From e09d483cf5fd3a7567aa795f9bdff223966364d9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 6 May 2017 18:36:09 +0100 Subject: [PATCH 0001/1050] Fixed typo in 808x cycle count. Patch from hOMER247. --- src/808x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/808x.c b/src/808x.c index 1ff61d0..7f811f2 100644 --- a/src/808x.c +++ b/src/808x.c @@ -2168,7 +2168,7 @@ void execx86(int cycs) addr=getword(); // printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr); AX=readmemw(ds,addr); - cycles-=!4; + cycles-=14; break; case 0xA2: /*MOV (w),AL*/ addr=getword(); From 7c63ce63686edda350a1d72a532238129c3c8eb1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 7 May 2017 10:38:28 +0100 Subject: [PATCH 0002/1050] Mark video memory mappings as external. Patch from Greatpsycho. --- src/vid_cga.c | 2 +- src/vid_ega.c | 2 +- src/vid_hercules.c | 2 +- src/vid_incolor.c | 2 +- src/vid_mda.c | 2 +- src/vid_svga.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vid_cga.c b/src/vid_cga.c index 65585b6..18cd630 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -454,7 +454,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); return cga; diff --git a/src/vid_ega.c b/src/vid_ega.c index bb98784..106af91 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -853,7 +853,7 @@ void *ega_standalone_init() ega_init(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(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; diff --git a/src/vid_hercules.c b/src/vid_hercules.c index d010baa..14750c2 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -312,7 +312,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/vid_incolor.c b/src/vid_incolor.c index 88df9c2..a393d3e 100644 --- a/src/vid_incolor.c +++ b/src/vid_incolor.c @@ -1007,7 +1007,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/vid_mda.c b/src/vid_mda.c index a3a7b39..fe46ec1 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -268,7 +268,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/vid_svga.c b/src/vid_svga.c index 34ecb1e..7433072 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -738,7 +738,7 @@ int svga_init(svga_t *svga, void *p, int memsize, 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); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); From a54e6575d3985e8bf43bac3850b1b1db04aacc61 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 11 May 2017 21:18:34 +0100 Subject: [PATCH 0003/1050] Partially implement Dell System 200 chipset. Fixes POST errors and HIMEM.SYS. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/dells200.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ src/dells200.h | 1 + src/model.c | 10 ++++++- 8 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 src/dells200.c create mode 100644 src/dells200.h diff --git a/src/Makefile.am b/src/Makefile.am index 3552a0d..58a36ab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429. 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 \ +dac.c dells200.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 \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 622d3f8..98f4466 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro allegro-gui-configure.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.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.c compaq.o config.o cpu.o \ -dac.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 2c5d4c7..aec090b 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -6,7 +6,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro allegro-gui-configure.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.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.c compaq.o config.o cpu.o \ -dac.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e790238..832f9a0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.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_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index f55c6e1..16a1f66 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.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_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/dells200.c b/src/dells200.c new file mode 100644 index 0000000..a8c9103 --- /dev/null +++ b/src/dells200.c @@ -0,0 +1,68 @@ +#include "ibm.h" +#include "io.h" +#include "mem.h" + +#include "dells200.h" + +static struct +{ + uint8_t regs[3]; +} dells200; + +static uint8_t dells200_in(uint16_t addr, void *p) +{ + uint8_t ret = 0xff; + + switch (addr) + { + case 0xa4: + ret = dells200.regs[0]; + break; + case 0xa5: + ret = dells200.regs[1]; + break; + case 0xab: + ret = dells200.regs[2]; + break; + } + +// pclog("dells200_in: addr=%04x ret=%02x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); + + return ret; +} + +static void dells200_out(uint16_t addr, uint8_t val, void *p) +{ +// pclog("dells200_out: addr=%04x val=%02x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); + + switch (addr) + { + case 0xa4: + dells200.regs[0] = val; + mem_a20_alt = val & 0x40; + mem_a20_recalc(); + break; + case 0xa5: + dells200.regs[1] = val; + if (val & 1) + mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); + else + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + if (val & 1) + mem_mapping_disable(&ram_high_mapping); + else + mem_mapping_enable(&ram_high_mapping); + break; + case 0xab: + dells200.regs[2] = val; + break; + } +} + +void dells200_chipset_init() +{ + memset(&dells200, 0, sizeof(dells200)); + + io_sethandler(0x00a4, 0x0002, dells200_in,NULL,NULL, dells200_out,NULL,NULL, NULL); + io_sethandler(0x00ab, 0x0001, dells200_in,NULL,NULL, dells200_out,NULL,NULL, NULL); +} diff --git a/src/dells200.h b/src/dells200.h new file mode 100644 index 0000000..96ae6c5 --- /dev/null +++ b/src/dells200.h @@ -0,0 +1 @@ +void dells200_chipset_init(); diff --git a/src/model.c b/src/model.c index e9a8460..43839da 100644 --- a/src/model.c +++ b/src/model.c @@ -8,6 +8,7 @@ #include "ali1429.h" #include "amstrad.h" #include "compaq.h" +#include "dells200.h" #include "device.h" #include "dma.h" #include "fdc.h" @@ -65,6 +66,7 @@ void olim24_init(); void at_init(); void ibm_at_init(); void at_ide_init(); +void dells200_init(); void deskpro386_init(); void ps1_m2011_init(); void ps1_m2121_init(); @@ -115,7 +117,7 @@ MODEL models[] = {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", 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}}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, dells200_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", 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}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, @@ -320,6 +322,12 @@ void deskpro386_init() compaq_init(); } +void dells200_init() +{ + at_init(); + dells200_chipset_init(); +} + void ps1_common_init() { AT = 1; From 411dbe574550082a07d0cc7f4aebed5268b68a56 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 11 May 2017 21:25:28 +0100 Subject: [PATCH 0004/1050] Fix disc indicator on Direct3D. --- src/win-d3d-fs.cc | 6 ++++++ src/win-d3d.cc | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 340cb9c..5ba60e4 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -391,7 +391,10 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) hr = d3ddev->SetTexture(0, NULL); if (hr == D3D_OK && readflash && vid_disc_indicator) + { hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); + readflash = 0; + } if (hr == D3D_OK) hr = d3ddev->EndScene(); @@ -508,7 +511,10 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) hr = d3ddev->SetTexture(0, NULL); if (hr == D3D_OK && readflash && vid_disc_indicator) + { hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); + readflash = 0; + } if (hr == D3D_OK) hr = d3ddev->EndScene(); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index dcaecb8..b795650 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -309,7 +309,10 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) hr = d3ddev->SetTexture(0, NULL); if (hr == D3D_OK && readflash && vid_disc_indicator) + { hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); + readflash = 0; + } if (hr == D3D_OK) hr = d3ddev->EndScene(); @@ -409,7 +412,10 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) hr = d3ddev->SetTexture(0, NULL); if (hr == D3D_OK && readflash && vid_disc_indicator) + { hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); + readflash = 0; + } if (hr == D3D_OK) hr = d3ddev->EndScene(); From 9791f4283de8c7a046fbbfd46186d6f1fdbd11cb Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 15 May 2017 18:06:20 +0100 Subject: [PATCH 0005/1050] Add default NVR files for PS/2 models. --- nvr/ibmps2_m50.nvr | Bin 0 -> 128 bytes nvr/ibmps2_m55sx.nvr | Bin 0 -> 128 bytes nvr/ibmps2_m80.nvr | Bin 0 -> 128 bytes nvr/ibmps2_m80_sec.nvr | Bin 0 -> 8192 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 nvr/ibmps2_m50.nvr create mode 100644 nvr/ibmps2_m55sx.nvr create mode 100644 nvr/ibmps2_m80.nvr create mode 100644 nvr/ibmps2_m80_sec.nvr diff --git a/nvr/ibmps2_m50.nvr b/nvr/ibmps2_m50.nvr new file mode 100644 index 0000000000000000000000000000000000000000..9d63cdc75566cb636e444939529ae1cd7491de40 GIT binary patch literal 128 zcmY%R&-P#8Kbr=NI2%*Je+C8z1_lPk2Brp9=D`1V{{w;IhmWU1#esq#2_T;Tm{XvE NRT9Vo1CSC*002GsQL6v| literal 0 HcmV?d00001 diff --git a/nvr/ibmps2_m55sx.nvr b/nvr/ibmps2_m55sx.nvr new file mode 100644 index 0000000000000000000000000000000000000000..e83ab4fdcb7a65d6fcc2c0c867a8fbe30e72241e GIT binary patch literal 128 zcmWGzU}cbCU=n2&S7QqJFTmiyz`(%Rz{J4v|L%V<2o(nkfCQmgUbXMcqM_#zyOCTqJ;r7BVYvp literal 0 HcmV?d00001 diff --git a/nvr/ibmps2_m80_sec.nvr b/nvr/ibmps2_m80_sec.nvr new file mode 100644 index 0000000000000000000000000000000000000000..e7e171ec012191ffb8663c4b2f158b40fbe96165 GIT binary patch literal 8192 zcmeIyF$%&!5CzcLU4tQ@q_fb%!Xs#(N-S*z+msf9H_#%5ttapnRu+2^?~pQ8#z`Ql zmZZ@H@ehP7^Ov3Q0-J0HinOAJ;+Nh{8ghx4squ(k+`^x!+aXAUwxh(y9v>0;Y<%0c z*_m&g-G6OHbe38QYxSg*=XC1LBU5+z7J>1?zbYF>#M1o)ncv7>}gVyNt*MeO3JruEP4=t00bZa0SG_<0uX=z b1Rwwb2tWV=5P$##AOHafKmY;|_=> Date: Tue, 16 May 2017 21:04:04 +0100 Subject: [PATCH 0006/1050] Add config manager file to makefiles. --- src/Makefile.linux32 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.mingw64 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 98f4466..ef20a09 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -4,7 +4,7 @@ CC = gcc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ -allegro-gui-configure.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ +allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index aec090b..52fe554 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -3,7 +3,7 @@ CPP = g++ CC = gcc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ -allegro-gui-configure.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ +allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 16a1f66..bd4194a 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -18,7 +18,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad 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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ + vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 vid_cga_comp.o From c518e3d1376c69745eadac357f9b829ee9cd6ec0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 16 May 2017 21:20:21 +0100 Subject: [PATCH 0007/1050] File extension for new configs or hard disc images is now appended if user doesn't specify one. --- src/win-config_sel.c | 2 +- src/win-hdconf.c | 2 +- src/win.c | 3 ++- src/win.h | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/win-config_sel.c b/src/win-config_sel.c index 9e3ef03..5ce9427 100644 --- a/src/win-config_sel.c +++ b/src/win-config_sel.c @@ -102,7 +102,7 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP strcat(s, "configs\\"); pclog("Dir %s\n", s); - if (!getsfile(hdlg, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "", s)) + if (!getsfile(hdlg, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "", s, "cfg")) { config_open(hdlg); diff --git a/src/win-hdconf.c b/src/win-hdconf.c index 184b370..d53e86c 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -205,7 +205,7 @@ static BOOL CALLBACK hdnew_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA return TRUE; case IDC_CFILE: - if (!getsfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "", NULL)) + if (!getsfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "", NULL, "img")) { h = GetDlgItem(hdlg, IDC_EDITC); SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); diff --git a/src/win.c b/src/win.c index e839c5c..55e4bb7 100644 --- a/src/win.c +++ b/src/win.c @@ -818,7 +818,7 @@ int getfile(HWND hwnd, char *f, char *fn) return 1; } -int getsfile(HWND hwnd, char *f, char *fn, char *dir) +int getsfile(HWND hwnd, char *f, char *fn, char *dir, char *ext) { OPENFILENAME ofn; // common dialog box structure BOOL r; @@ -842,6 +842,7 @@ int getsfile(HWND hwnd, char *f, char *fn, char *dir) ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = dir; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + ofn.lpstrDefExt = ext; // Display the Open dialog box. diff --git a/src/win.h b/src/win.h index ed12875..2675995 100644 --- a/src/win.h +++ b/src/win.h @@ -34,7 +34,7 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type); extern char openfilestring[260]; int getfile(HWND hwnd, char *f, char *fn); -int getsfile(HWND hwnd, char *f, char *fn, char *dir); +int getsfile(HWND hwnd, char *f, char *fn, char *dir, char *ext); extern int pause; From 85e78292440ab3b2d58fc19fbaf7f93347d03cc6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 May 2017 19:13:23 +0100 Subject: [PATCH 0008/1050] Fixed CD-ROM initialisation broken by config changes. --- src/cdrom-ioctl.c | 6 ++++++ src/pc.c | 1 + 2 files changed, 7 insertions(+) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 2d4f176..ef10004 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -737,14 +737,20 @@ void ioctl_reset() void ioctl_set_drive(char d) { + ioctl_close(); + sprintf(ioctl_path, "\\\\.\\%c:", d); pclog("Path is %s\n", ioctl_path); tocvalid = 0; atapi = &ioctl_atapi; + + ioctl_open(d); } int ioctl_open(char d) { + if (hIOCTL) + ioctl_close(); hIOCTL = CreateFile(ioctl_path,GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if (!hIOCTL) diff --git a/src/pc.c b/src/pc.c index 2c38c83..972e867 100644 --- a/src/pc.c +++ b/src/pc.c @@ -411,6 +411,7 @@ void resetpchard() } else { + ioctl_set_drive(cdrom_drive); ioctl_reset(); } } From 34679d4273c199590f46435a211bd3cc72df599e Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 18 May 2017 20:56:59 +0100 Subject: [PATCH 0009/1050] Tweaked S3 PIXTRANS register. Fixes text rendering in Line Wars II and problems with some S3 drivers. --- src/vid_s3.c | 86 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index f0ce975..580c16d 100644 --- a/src/vid_s3.c +++ b/src/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); + } } } @@ -422,38 +430,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); } } } @@ -581,10 +591,18 @@ static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); } else - 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); + } } } } @@ -605,38 +623,40 @@ static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, 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) { + 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); - s3_accel_start(16, 1, val, 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, 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, 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); - s3_accel_start(1, 1, 0xffffffff, val >> 24, s3); } } } From 3f4361b265c8430c5cb3402c4bc0ceffc9d114ee Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 May 2017 11:05:40 +0100 Subject: [PATCH 0010/1050] Fix loading of disc images at startup. --- src/pc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pc.c b/src/pc.c index 972e867..3438590 100644 --- a/src/pc.c +++ b/src/pc.c @@ -272,9 +272,6 @@ void initpc(int argc, char *argv[]) fdi_init(); img_init(); - disc_load(0, discfns[0]); - disc_load(1, discfns[1]); - //loadfont(); loadnvr(); resetide(); @@ -365,7 +362,9 @@ void resetpchard() mem_resize(); fdc_init(); disc_reset(); - + disc_load(0, discfns[0]); + disc_load(1, discfns[1]); + model_init(); mouse_emu_init(); video_init(); From 083ca3d4a2e832e426057166b49e7acb1d39987a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 May 2017 21:50:37 +0100 Subject: [PATCH 0011/1050] Slight optimisation when DS/SS are 'flat' (base=0, limit=4G). --- src/386_dynarec.c | 6 +- src/808x.c | 2 + src/codegen.h | 22 +-- src/codegen_ops_x86-64.h | 223 ++++++++++++++++++++++++------ src/codegen_ops_x86.h | 283 +++++++++++++++++++++++++++++++-------- src/codegen_x86-64.c | 5 +- src/codegen_x86.c | 3 +- src/ibm.h | 8 ++ src/x86_ops_misc.h | 28 ++++ src/x86seg.c | 123 +++++++++++++---- 10 files changed, 564 insertions(+), 139 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 09894dd..79c054e 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -17,6 +17,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; @@ -1433,7 +1435,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); @@ -1445,7 +1447,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/808x.c b/src/808x.c index 7f811f2..7933f58 100644 --- a/src/808x.c +++ b/src/808x.c @@ -623,6 +623,7 @@ void resetx86() resets++; ins = 0; use32=0; + cpu_cur_status = 0; stack32=0; // i86_Reset(); // cs=0xFFFF0; @@ -662,6 +663,7 @@ void softresetx86() // exit(-1); use32=0; stack32=0; + cpu_cur_status = 0; // i86_Reset(); // cs=0xFFFF0; cpu_state.pc=0; diff --git a/src/codegen.h b/src/codegen.h index e715915..cbac2b6 100644 --- a/src/codegen.h +++ b/src/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/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 76f142c..561b73a 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -869,6 +869,10 @@ static inline 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)) { @@ -903,6 +907,10 @@ static inline 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)) { @@ -929,6 +937,11 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline 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*/ @@ -965,7 +978,13 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static inline 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); @@ -1033,7 +1052,13 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline 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); @@ -1117,7 +1142,13 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline 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); @@ -1193,7 +1224,13 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline 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); @@ -1312,7 +1349,13 @@ static inline 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); @@ -1391,7 +1434,13 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static inline 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); @@ -1481,7 +1530,13 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static inline 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); @@ -1569,7 +1624,13 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static inline 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); @@ -5253,11 +5314,17 @@ static inline void LOAD_EA() static inline void MEM_CHECK_WRITE(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3; + uint8_t *jump1, *jump2, *jump3 = NULL; 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); @@ -5304,12 +5371,16 @@ static inline 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*/ @@ -5333,7 +5404,9 @@ static inline 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,12 +5446,18 @@ static inline void MEM_CHECK_WRITE(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 (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); @@ -5421,15 +5500,23 @@ static inline 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*/ @@ -5480,7 +5567,9 @@ static inline 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,12 +5599,18 @@ static inline void MEM_CHECK_WRITE_W(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); - 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); @@ -5558,15 +5653,23 @@ static inline 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*/ @@ -5617,7 +5720,9 @@ static inline 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); @@ -5647,7 +5752,13 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) static inline 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); @@ -5714,7 +5825,13 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline 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); @@ -5790,7 +5907,13 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline 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); @@ -5888,7 +6011,13 @@ static inline 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); @@ -5960,7 +6089,13 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static inline 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); @@ -6043,7 +6178,13 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static inline 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/codegen_ops_x86.h b/src/codegen_ops_x86.h index 3581f6e..34ace4d 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -618,6 +618,10 @@ static inline 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); @@ -639,6 +643,10 @@ static inline 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); @@ -652,6 +660,11 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline 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); @@ -677,9 +690,18 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static inline 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])); @@ -687,9 +709,18 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline 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])); @@ -699,9 +730,18 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline 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])); @@ -709,9 +749,18 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static inline 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); @@ -722,9 +771,18 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline 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])); @@ -734,9 +792,18 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline 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])); @@ -745,9 +812,18 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline 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])); @@ -758,9 +834,18 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static inline 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])); @@ -788,9 +873,18 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static inline 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*/ @@ -801,9 +895,18 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static inline 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*/ @@ -814,9 +917,18 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static inline 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*/ @@ -827,9 +939,18 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static inline 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*/ @@ -840,9 +961,18 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static inline 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*/ @@ -853,9 +983,18 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static inline 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*/ @@ -876,9 +1015,18 @@ static inline 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])); } @@ -3795,9 +3943,18 @@ static inline void LOAD_EA() static inline 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(); @@ -3805,9 +3962,18 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) static inline 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(); @@ -3815,9 +3981,18 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) static inline 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/codegen_x86-64.c b/src/codegen_x86-64.c index d421c7f..e6e8b78 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -274,13 +274,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 = 0; - + block->status = cpu_cur_status; + block->was_recompiled = 0; recomp_page = block->phys & ~0xfff; diff --git a/src/codegen_x86.c b/src/codegen_x86.c index b9893ba..07f6857 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -1394,12 +1394,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/ibm.h b/src/ibm.h index c06010f..5120aef 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -167,6 +167,14 @@ struct #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 COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index beee6bd..cad6d95 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -761,9 +761,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); @@ -803,8 +811,28 @@ 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/x86seg.c b/src/x86seg.c index 69a0ce0..7e88077 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -174,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; + } +} + static void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); @@ -195,6 +218,21 @@ static void do_seg_load(x86seg *s, uint16_t *segdat) 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); + + 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) @@ -275,6 +313,8 @@ void loadseg(uint16_t seg, x86seg *s) s->seg=0; s->access = 0; s->base=-1; + if (s == &_ds) + cpu_cur_status &= ~CPU_STATUS_FLATDS; // 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,pc); return; } @@ -343,7 +383,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); // pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]); } else if (s!=&_cs) @@ -400,10 +440,23 @@ void loadseg(uint16_t seg, x86seg *s) s->access = (3 << 5) | 2; s->base = seg << 4; s->seg = seg; - if (s == &_ss) - 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) @@ -484,8 +537,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; @@ -601,8 +653,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; @@ -615,7 +666,16 @@ 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; +/* if (segdat[3]&0x40) + { + use32=0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; + }*/ cycles -= timing_jmp_pm; } else /*System segment*/ @@ -710,8 +770,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; @@ -920,8 +980,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; @@ -940,7 +999,16 @@ 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 (segdat[3]&0x40) + { + use32=0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; + }*/ if (csout) pclog("Complete\n"); cycles -= timing_call_pm; } @@ -1102,7 +1170,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; @@ -1119,7 +1187,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"); @@ -1223,8 +1291,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; @@ -1397,7 +1465,7 @@ 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); // pclog("CPL=RPL return to %04X:%08X\n",CS,pc); cycles -= timing_retf_pm; @@ -1526,7 +1594,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); @@ -1548,7 +1616,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; @@ -1777,7 +1845,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); @@ -1881,7 +1949,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); // pclog("Int gate done!\n"); #ifdef CS_ACCESSED @@ -2056,6 +2124,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); @@ -2076,7 +2145,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; // pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X %i\n",CS,pc,SS,SP,DS,ES,FS,GS,abrt); @@ -2189,7 +2260,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; @@ -2283,7 +2354,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); @@ -2305,7 +2376,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); @@ -2522,7 +2593,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; From 3fb4eae1b011a604bd8ded0eb49dcb983e60c8b4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 May 2017 21:51:03 +0100 Subject: [PATCH 0012/1050] Fix a couple of uninitialised variables. --- src/disc_img.c | 2 +- src/sound_gus.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disc_img.c b/src/disc_img.c index 206eaae..c18d45a 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -130,7 +130,7 @@ void img_load(int drive, char *fn) uint8_t bpb_sectors; uint8_t bpb_sides; uint32_t bpt; - uint8_t max_spt; /* Used for XDF detection. */ + uint8_t max_spt = 0; /* Used for XDF detection. */ if (!xdf_maps_initialized) initialize_xdf_maps(); /* Initialize XDF maps, will need them to properly register sectors in tracks. */ diff --git a/src/sound_gus.c b/src/sound_gus.c index 4cd84ec..c6322ba 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -600,7 +600,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; // /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus->global); switch (addr) { From 8cd767091a5f226503d123587c67f5559ead32ca Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 May 2017 18:06:40 +0100 Subject: [PATCH 0013/1050] Fixed stack size bug introducted in rev 729. --- src/x86seg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x86seg.c b/src/x86seg.c index 7e88077..c729670 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -440,6 +440,8 @@ void loadseg(uint16_t seg, x86seg *s) s->access = (3 << 5) | 2; s->base = seg << 4; s->seg = seg; + if (s == &_ss) + stack32 = 0; s->checked = 1; } From 3d69f092c9f068bf9260f1323f3e4786231c1c32 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 May 2017 21:25:42 +0100 Subject: [PATCH 0014/1050] Fixed infinite loop in Windows GUI when selecting File->Exit. --- src/win.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win.c b/src/win.c index 55e4bb7..f88b5ee 100644 --- a/src/win.c +++ b/src/win.c @@ -935,7 +935,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM pause=0; break; case IDM_FILE_EXIT: - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + PostMessage(hwnd, WM_CLOSE, 0, 0); break; case IDM_DISC_A: if (!getfile(hwnd,"Disc image (*.IMG;*.IMA;*.FDI)\0*.IMG;*.IMA;*.FDI\0All files (*.*)\0*.*\0",discfns[0])) From 3c514a445fed082551f2184977487756acbccb20 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 28 May 2017 17:45:42 +0100 Subject: [PATCH 0015/1050] Removed palettised blitting code. --- src/vid_cga.c | 79 ++++++++++--------- src/vid_colorplus.c | 48 +++++------ src/vid_genius.c | 77 ++++++++++-------- src/vid_hercules.c | 48 +++++------ src/vid_mda.c | 46 +++++------ src/vid_olivetti_m24.c | 84 ++++++++++---------- src/vid_pc1512.c | 76 +++++++++--------- src/vid_pcjr.c | 130 +++++++++++++++--------------- src/vid_tandy.c | 138 ++++++++++++++++---------------- src/vid_tandysl.c | 156 ++++++++++++++++++------------------ src/vid_wy700.c | 175 ++++++++++++++++++++--------------------- src/video.c | 62 ++++++--------- src/video.h | 6 +- src/win-d3d-fs.cc | 151 ----------------------------------- src/win-d3d.cc | 142 ++------------------------------- src/win-ddraw-fs.cc | 106 ------------------------- src/win-ddraw.cc | 121 +--------------------------- src/win-video.c | 8 +- 18 files changed, 573 insertions(+), 1080 deletions(-) diff --git a/src/vid_cga.c b/src/vid_cga.c index 18cd630..b930a37 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -137,7 +137,7 @@ void cga_poll(void *p) int oldvc; uint8_t chr, attr; uint16_t dat; - int cols[4]; + uint32_t cols[4]; int col; int oldsc; @@ -158,20 +158,15 @@ void cga_poll(void *p) // printf("Firstline %i\n",firstline); } cga->lastline = cga->displine; + + cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); for (c = 0; c < 8; c++) { - if ((cga->cgamode & 0x12) == 0x12) - { - buffer->line[cga->displine][c] = 0; - if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = 0; - else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = 0; - } + ((uint32_t *)buffer32->line[cga->displine])[c] = cols[0]; + if (cga->cgamode & 1) + ((uint32_t *)buffer32->line[cga->displine])[c + (cga->crtc[1] << 3) + 8] = cols[0]; else - { - buffer->line[cga->displine][c] = (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) buffer->line[cga->displine][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; - else buffer->line[cga->displine][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; - } + ((uint32_t *)buffer32->line[cga->displine])[c + (cga->crtc[1] << 4) + 8] = cols[0]; } if (cga->cgamode & 1) { @@ -182,25 +177,25 @@ void cga_poll(void *p) drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); if (cga->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) cols[1] = cols[0]; } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; + cols[1] = attr & 15; + cols[0] = attr >> 4; } if (drawcursor) { for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } cga->ma++; } @@ -214,32 +209,35 @@ void cga_poll(void *p) drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); if (cga->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0]; + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; + cols[1] = attr & 15; + cols[0] = attr >> 4; } cga->ma++; if (drawcursor) { for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 4)+(c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[cga->displine])[(x << 4)+(c << 1) + 8] = + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) - buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } else if (!(cga->cgamode & 16)) { - cols[0] = (cga->cgacol & 15) | 16; - col = (cga->cgacol & 16) ? 24 : 16; + cols[0] = cga->cgacol & 15; + col = (cga->cgacol & 16) ? 8 : 0; if (cga->cgamode & 4) { cols[1] = col | 3; @@ -264,22 +262,23 @@ void cga_poll(void *p) cga->ma++; for (c = 0; c < 8; c++) { - buffer->line[cga->displine][(x << 4) + (c << 1) + 8] = - buffer->line[cga->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } } else { - cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16; + cols[0] = 0; + cols[1] = cga->cgacol & 15; for (x = 0; x < cga->crtc[1]; x++) { dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; cga->ma++; for (c = 0; c < 16; c++) { - buffer->line[cga->displine][(x << 4) + c + 8] = cols[dat >> 15]; + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -287,9 +286,9 @@ void cga_poll(void *p) } else { - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) hline(buffer, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); + cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); + if (cga->cgamode & 1) hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); } if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16; @@ -298,10 +297,15 @@ void cga_poll(void *p) if (cga->composite) { for (c = 0; c < x; c++) - buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf; + buffer32->line[cga->displine][c] = ((uint32_t *)buffer32->line[cga->displine])[c] & 0xf; Composite_Process(cga->cgamode, 0, x >> 2, buffer32->line[cga->displine]); } + else + { + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[cga->displine])[c] = cgapal[((uint32_t *)buffer32->line[cga->displine])[c] & 0xf]; + } cga->sc = oldsc; if (cga->vc == cga->crtc[7] && !cga->sc) @@ -380,10 +384,7 @@ void cga_poll(void *p) updatewindowsize(xsize, (ysize << 1) + 16); } - if (cga->composite) - video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8); - else - video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8); + video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8); frames++; video_res_x = xsize - 16; diff --git a/src/vid_colorplus.c b/src/vid_colorplus.c index 31110bd..acb10cb 100644 --- a/src/vid_colorplus.c +++ b/src/vid_colorplus.c @@ -101,10 +101,10 @@ void colorplus_poll(void *p) int cols[4]; int col; int oldsc; - static const int cols16[16] = { 0x10,0x12,0x14,0x16, - 0x18,0x1A,0x1C,0x1E, - 0x11,0x13,0x15,0x17, - 0x19,0x1B,0x1D,0x1F }; + static const int cols16[16] = { 0x0,0x2,0x4,0x6, + 0x8,0xA,0xC,0xE, + 0x1,0x3,0x5,0x7, + 0x9,0xB,0xD,0xF }; uint8_t *plane0 = colorplus->cga.vram; uint8_t *plane1 = colorplus->cga.vram + 0x4000; @@ -137,8 +137,8 @@ void colorplus_poll(void *p) /* Left / right border */ for (c = 0; c < 8; c++) { - buffer->line[colorplus->cga.displine][c] = - buffer->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16; + ((uint32_t *)buffer32->line[colorplus->cga.displine])[c] = + ((uint32_t *)buffer32->line[colorplus->cga.displine])[c + (colorplus->cga.crtc[1] << 4) + 8] = cgapal[colorplus->cga.cgacol & 15]; } if (colorplus->control & COLORPLUS_320x200_MODE) { @@ -151,9 +151,9 @@ void colorplus_poll(void *p) colorplus->cga.ma++; for (c = 0; c < 8; c++) { - buffer->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = - buffer->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = - cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]; + ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = + cgapal[cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]]; dat0 <<= 2; dat1 <<= 2; } @@ -161,25 +161,25 @@ void colorplus_poll(void *p) } else if (colorplus->control & COLORPLUS_640x200_MODE) { - cols[0] = (colorplus->cga.cgacol & 15) | 16; - col = (colorplus->cga.cgacol & 16) ? 24 : 16; + cols[0] = cgapal[colorplus->cga.cgacol & 15]; + col = (colorplus->cga.cgacol & 16) ? 8 : 0; if (colorplus->cga.cgamode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; } else if (colorplus->cga.cgacol & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; } for (x = 0; x < colorplus->cga.crtc[1]; x++) { @@ -190,7 +190,7 @@ void colorplus_poll(void *p) colorplus->cga.ma++; for (c = 0; c < 16; c++) { - buffer->line[colorplus->cga.displine][(x << 4) + c + 8] = + ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + c + 8] = cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; dat0 <<= 1; dat1 <<= 1; @@ -200,8 +200,8 @@ void colorplus_poll(void *p) } else /* Top / bottom border */ { - cols[0] = (colorplus->cga.cgacol & 15) + 16; - hline(buffer, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); + cols[0] = cgapal[colorplus->cga.cgacol & 15]; + hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); } x = (colorplus->cga.crtc[1] << 4) + 16; @@ -283,7 +283,7 @@ void colorplus_poll(void *p) updatewindowsize(xsize, (ysize << 1) + 16); } - video_blit_memtoscreen_8(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); + video_blit_memtoscreen(0, colorplus->cga.firstline - 4, 0, (colorplus->cga.lastline - colorplus->cga.firstline) + 8, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); frames++; video_res_x = xsize - 16; diff --git a/src/vid_genius.c b/src/vid_genius.c index c6d6202..c608071 100644 --- a/src/vid_genius.c +++ b/src/vid_genius.c @@ -109,6 +109,8 @@ typedef struct genius_t uint8_t *vram; } genius_t; +static uint32_t genius_pal[4]; + /* Mapping of attributes to colours, in MDA emulation mode */ static int mdacols[256][2][2]; @@ -265,7 +267,7 @@ void genius_textline(genius_t *genius, uint8_t background) 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; + uint32_t col; /* Character height is 12-15 */ charh = 15 - (genius->genius_charh & 3); @@ -317,13 +319,13 @@ void genius_textline(genius_t *genius, uint8_t background) if (genius->genius_control & 0x20) { - col ^= 15; + col ^= 0xffffff; } for (c = 0; c < cw; c++) { if (col != background) - buffer->line[genius->displine][(x * cw) + c] = col; + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; } } else /* Draw 8 pixels of character */ @@ -337,33 +339,35 @@ void genius_textline(genius_t *genius, uint8_t background) if (genius->genius_control & 0x20) { - col ^= 15; + col ^= 0xffffff; } if (col != background) { - buffer->line[genius->displine][(x * cw) + c] = col; + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; } } /* The ninth pixel column... */ if ((chr & ~0x1f) == 0xc0) { /* Echo column 8 for the graphics chars */ - col = buffer->line[genius->displine][(x * cw) + 7]; - if (col != background) buffer->line[genius->displine][(x * cw) + 8] = col; + col = ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 7]; + if (col != background) + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; } else /* Otherwise fill with background */ { col = mdacols[attr][blink][0]; if (genius->genius_control & 0x20) { - col ^= 15; + col ^= 0xffffff; } - if (col != background) buffer->line[genius->displine][(x * cw) + 8] = col; + if (col != background) + ((uint32_t *)buffer32->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]; + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] ^= mdacols[attr][0][1]; } ++ma; } @@ -378,10 +382,10 @@ void genius_cgaline(genius_t *genius) { int x, c; uint32_t dat; - uint8_t ink; + uint32_t ink; uint32_t addr; - ink = (genius->genius_control & 0x20) ? 16 : 16+15; + ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; /* We draw the CGA at row 600 */ if (genius->displine < 600) { @@ -402,7 +406,7 @@ void genius_cgaline(genius_t *genius) { if (dat & 0x80) { - buffer->line[genius->displine][x*8 + c] = ink; + ((uint32_t *)buffer32->line[genius->displine])[x*8 + c] = ink; } dat = dat << 1; } @@ -420,7 +424,7 @@ void genius_hiresline(genius_t *genius) uint8_t ink; uint32_t addr; - ink = (genius->genius_control & 0x20) ? 16 : 16+15; + ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; /* The first 512 lines live at A0000 */ if (genius->displine < 512) { @@ -440,7 +444,7 @@ void genius_hiresline(genius_t *genius) { if (dat & 0x80) { - buffer->line[genius->displine][x*8 + c] = ink; + ((uint32_t *)buffer32->line[genius->displine])[x*8 + c] = ink; } dat = dat << 1; } @@ -466,11 +470,11 @@ void genius_poll(void *p) { if (genius->genius_control & 0x20) { - background = 16 + 15; + background = genius_pal[3]; } else { - background = 16; + background = genius_pal[0]; } if (genius->displine == 0) { @@ -479,7 +483,7 @@ void genius_poll(void *p) /* Start off with a blank line */ for (x = 0; x < GENIUS_XSIZE; x++) { - buffer->line[genius->displine][x] = background; + ((uint32_t *)buffer32->line[genius->displine])[x] = background; } /* If graphics display enabled, draw graphics on top * of the blanked line */ @@ -536,7 +540,7 @@ void genius_poll(void *p) if (ysize < 32) ysize = 200; updatewindowsize(xsize, ysize); } - video_blit_memtoscreen_8(0, 0, xsize, ysize); + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); frames++; /* Fixed 728x1008 resolution */ @@ -566,27 +570,32 @@ void *genius_init() io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); + genius_pal[0] = makecol(0x00, 0x00, 0x00); + genius_pal[1] = makecol(0x55, 0x55, 0x55); + genius_pal[2] = makecol(0xaa, 0xaa, 0xaa); + genius_pal[3] = makecol(0xff, 0xff, 0xff); + /* MDA attributes */ /* I don't know if the Genius's MDA emulation actually does * emulate bright / non-bright. For the time being pretend it does. */ for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = genius_pal[0]; + if (c & 8) mdacols[c][0][1] = genius_pal[3]; + else mdacols[c][0][1] = genius_pal[2]; } - mdacols[0x70][0][1] = 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; + mdacols[0x70][0][1] = genius_pal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = genius_pal[3]; + mdacols[0xF0][0][1] = genius_pal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = genius_pal[3]; + mdacols[0x78][0][1] = genius_pal[2]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = genius_pal[3]; + mdacols[0xF8][0][1] = genius_pal[2]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = genius_pal[3]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = genius_pal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = genius_pal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = genius_pal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = genius_pal[0]; /* Start off in 80x25 text mode */ genius->cga_stat = 0xF4; diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 14750c2..cdfb31d 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -32,7 +32,7 @@ typedef struct hercules_t uint8_t *vram; } hercules_t; -static int mdacols[256][2][2]; +static uint32_t mdacols[256][2][2]; void hercules_recalctimings(hercules_t *hercules); void hercules_write(uint32_t addr, uint8_t val, void *p); @@ -153,7 +153,7 @@ void hercules_poll(void *p) dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; hercules->ma++; for (c = 0; c < 16; c++) - buffer->line[hercules->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0; + ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = (dat & (32768 >> c)) ? 0xffffff : 0; } } else @@ -167,20 +167,22 @@ void hercules_poll(void *p) if (hercules->sc == 12 && ((attr & 7) == 1)) { for (c = 0; c < 9; c++) - buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][1]; + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] = mdacols[attr][blink][1]; } else { for (c = 0; c < 8; c++) - buffer->line[hercules->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1]; - else buffer->line[hercules->displine][(x * 9) + 8] = mdacols[attr][blink][0]; + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1]; + else + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + 8] = mdacols[attr][blink][0]; } hercules->ma++; if (drawcursor) { for (c = 0; c < 9; c++) - buffer->line[hercules->displine][(x * 9) + c] ^= mdacols[attr][0][1]; + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] ^= mdacols[attr][0][1]; } } } @@ -268,7 +270,7 @@ void hercules_poll(void *p) updatewindowsize(xsize, ysize); } - video_blit_memtoscreen_8(0, hercules->firstline, xsize, ysize); + video_blit_memtoscreen(0, hercules->firstline, 0, ysize, xsize, ysize); frames++; if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) @@ -317,22 +319,22 @@ void *hercules_init() 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[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = makecol32(0, 0, 0); + if (c & 8) mdacols[c][0][1] = makecol32(0xff, 0xff, 0xff); + else mdacols[c][0][1] = makecol32(0xaa, 0xaa, 0xaa); } - 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; + mdacols[0x70][0][1] = makecol32(0, 0, 0); + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0xF0][0][1] = makecol32(0, 0, 0); + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0x78][0][1] = makecol32(0xaa, 0xaa, 0xaa); + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0xF8][0][1] = makecol32(0xaa, 0xaa, 0xaa); + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0x00][0][1] = mdacols[0x00][1][1] = makecol32(0, 0, 0); + mdacols[0x08][0][1] = mdacols[0x08][1][1] = makecol32(0, 0, 0); + mdacols[0x80][0][1] = mdacols[0x80][1][1] = makecol32(0, 0, 0); + mdacols[0x88][0][1] = mdacols[0x88][1][1] = makecol32(0, 0, 0); return hercules; } diff --git a/src/vid_mda.c b/src/vid_mda.c index fe46ec1..495b794 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -32,7 +32,7 @@ typedef struct mda_t uint8_t *vram; } mda_t; -static int mdacols[256][2][2]; +static uint32_t mdacols[256][2][2]; void mda_recalctimings(mda_t *mda); @@ -135,20 +135,22 @@ void mda_poll(void *p) if (mda->sc == 12 && ((attr & 7) == 1)) { for (c = 0; c < 9; c++) - buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] = mdacols[attr][blink][1]; } else { for (c = 0; c < 8; c++) - buffer->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; - else buffer->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; + else + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + 8] = mdacols[attr][blink][0]; } mda->ma++; if (drawcursor) { for (c = 0; c < 9; c++) - buffer->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1]; + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] ^= mdacols[attr][0][1]; } } } @@ -233,7 +235,7 @@ void mda_poll(void *p) updatewindowsize(xsize, ysize); } - video_blit_memtoscreen_8(0, mda->firstline, xsize, mda->lastline - mda->firstline); + video_blit_memtoscreen(0, mda->firstline, 0, ysize, xsize, ysize); frames++; video_res_x = mda->crtc[1]; @@ -273,22 +275,22 @@ void *mda_init() 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[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = makecol32(0, 0, 0); + if (c & 8) mdacols[c][0][1] = makecol32(0xff, 0xff, 0xff); + else mdacols[c][0][1] = makecol32(0xaa, 0xaa, 0xaa); } - 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; + mdacols[0x70][0][1] = makecol32(0, 0, 0); + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0xF0][0][1] = makecol32(0, 0, 0); + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0x78][0][1] = makecol32(0xaa, 0xaa, 0xaa); + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0xF8][0][1] = makecol32(0xaa, 0xaa, 0xaa); + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = makecol32(0xff, 0xff, 0xff); + mdacols[0x00][0][1] = mdacols[0x00][1][1] = makecol32(0, 0, 0); + mdacols[0x08][0][1] = mdacols[0x08][1][1] = makecol32(0, 0, 0); + mdacols[0x80][0][1] = mdacols[0x80][1][1] = makecol32(0, 0, 0); + mdacols[0x88][0][1] = mdacols[0x88][1][1] = makecol32(0, 0, 0); return mda; } diff --git a/src/vid_olivetti_m24.c b/src/vid_olivetti_m24.c index 2cae92c..9e04c0d 100644 --- a/src/vid_olivetti_m24.c +++ b/src/vid_olivetti_m24.c @@ -142,7 +142,7 @@ void m24_poll(void *p) int oldvc; uint8_t chr, attr; uint16_t dat, dat2; - int cols[4]; + uint32_t cols[4]; int col; int oldsc; if (!m24->linepos) @@ -167,15 +167,15 @@ void m24_poll(void *p) { if ((m24->cgamode & 0x12) == 0x12) { - buffer->line[m24->displine][c] = 0; - if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0; - else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0; + ((uint32_t *)buffer32->line[m24->displine])[c] = cgapal[0]; + if (m24->cgamode & 1) ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 3) + 8] = cgapal[0]; + else ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 4) + 8] = cgapal[0]; } else { - buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16; - if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16; - else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = (m24->cgacol & 15) + 16; + ((uint32_t *)buffer32->line[m24->displine])[c] = cgapal[m24->cgacol & 15]; + if (m24->cgamode & 1) ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 3) + 8] = cgapal[m24->cgacol & 15]; + else ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 4) + 8] = cgapal[m24->cgacol & 15]; } } if (m24->cgamode & 1) @@ -187,25 +187,25 @@ void m24_poll(void *p) drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron); if (m24->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; if ((m24->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; } if (drawcursor) { for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[m24->displine])[(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[m24->displine])[(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } m24->ma++; } @@ -219,52 +219,52 @@ void m24_poll(void *p) drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron); if (m24->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; if ((m24->blink & 16) && (attr & 0x80)) cols[1] = cols[0]; } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; } m24->ma++; if (drawcursor) { for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = - buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) - buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = - buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } } } else if (!(m24->cgamode & 16)) { - cols[0] = (m24->cgacol & 15) | 16; - col = (m24->cgacol & 16) ? 24 : 16; + cols[0] = cgapal[m24->cgacol & 15]; + col = (m24->cgacol & 16) ? 8 : 0; if (m24->cgamode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; } else if (m24->cgacol & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; } for (x = 0; x < m24->crtc[1]; x++) { @@ -273,8 +273,8 @@ void m24_poll(void *p) m24->ma++; for (c = 0; c < 8; c++) { - buffer->line[m24->displine][(x << 4) + (c << 1) + 8] = - buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } @@ -284,12 +284,14 @@ void m24_poll(void *p) if (m24->ctrl & 1) { dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000); - cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16; + cols[0] = cgapal[0]; + cols[1] = cgapal[15]; } else { dat2 = (m24->sc & 1) * 0x2000; - cols[0] = 0; cols[1] = (m24->cgacol & 15) + 16; + cols[0] = cgapal[0]; + cols[1] = cgapal[m24->cgacol & 15]; } for (x = 0; x < m24->crtc[1]; x++) { @@ -297,7 +299,7 @@ void m24_poll(void *p) m24->ma++; for (c = 0; c < 16; c++) { - buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15]; + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -305,9 +307,9 @@ void m24_poll(void *p) } else { - cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16; - if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]); + cols[0] = cgapal[((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15)]; + if (m24->cgamode & 1) hline(buffer32, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]); } if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16; @@ -396,7 +398,7 @@ void m24_poll(void *p) updatewindowsize(xsize, ysize + 16); } - video_blit_memtoscreen_8(0, m24->firstline - 8, xsize, (m24->lastline - m24->firstline) + 16); + video_blit_memtoscreen(0, m24->firstline - 8, 0, (m24->lastline - m24->firstline) + 16, xsize, (m24->lastline - m24->firstline) + 16); frames++; video_res_x = xsize - 16; diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 79ac43d..0b5f89a 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -187,15 +187,15 @@ static void pc1512_poll(void *p) { if ((pc1512->cgamode & 0x12) == 0x12) { - buffer->line[pc1512->displine][c] = (pc1512->border & 15) + 16; - if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = 0; - else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = 0; + ((uint32_t *)buffer32->line[pc1512->displine])[c] = cgapal[pc1512->border & 15]; + if (pc1512->cgamode & 1) ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 3) + 8] = 0; + else ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 4) + 8] = 0; } else { - buffer->line[pc1512->displine][c] = (pc1512->cgacol & 15) + 16; - if (pc1512->cgamode & 1) buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 3) + 8] = (pc1512->cgacol & 15) + 16; - else buffer->line[pc1512->displine][c + (pc1512->crtc[1] << 4) + 8] = (pc1512->cgacol & 15) + 16; + ((uint32_t *)buffer32->line[pc1512->displine])[c] = cgapal[pc1512->cgacol & 15]; + if (pc1512->cgamode & 1) ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 3) + 8] = cgapal[pc1512->cgacol & 15]; + else ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 4) + 8] = cgapal[pc1512->cgacol & 15]; } } if (pc1512->cgamode & 1) @@ -207,25 +207,25 @@ static void pc1512_poll(void *p) drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); if (pc1512->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; } if (drawcursor) { for (c = 0; c < 8; c++) - buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { for (c = 0; c < 8; c++) - buffer->line[pc1512->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } pc1512->ma++; } @@ -239,52 +239,52 @@ static void pc1512_poll(void *p) drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); if (pc1512->cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; if ((pc1512->blink & 16) && (attr & 0x80)) cols[1] = cols[0]; } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; } pc1512->ma++; if (drawcursor) { for (c = 0; c < 8; c++) - buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) - buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } else if (!(pc1512->cgamode&16)) { - cols[0] = (pc1512->cgacol & 15) | 16; - col = (pc1512->cgacol & 16) ? 24 : 16; + cols[0] = cgapal[pc1512->cgacol & 15]; + col = (pc1512->cgacol & 16) ? 8 : 0; if (pc1512->cgamode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; } else if (pc1512->cgacol & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; } for (x = 0; x < 40; x++) { @@ -292,8 +292,8 @@ static void pc1512_poll(void *p) pc1512->ma++; for (c = 0; c < 8; c++) { - buffer->line[pc1512->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pc1512->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } @@ -311,7 +311,7 @@ static void pc1512_poll(void *p) pc1512->ma++; for (c = 0; c < 16; c++) { - buffer->line[pc1512->displine][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (pc1512->cgacol & 15)) + 16; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + c + 8] = cgapal[((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (pc1512->cgacol & 15)]; dat <<= 1; dat2 <<= 1; dat3 <<= 1; @@ -322,9 +322,9 @@ static void pc1512_poll(void *p) } else { - cols[0] = ((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15) + 16; - if (pc1512->cgamode & 1) hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]); + cols[0] = cgapal[((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15)]; + if (pc1512->cgamode & 1) hline(buffer32, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]); } pc1512->sc = oldsc; @@ -402,7 +402,7 @@ static void pc1512_poll(void *p) updatewindowsize(xsize, (ysize << 1) + 16); } - video_blit_memtoscreen_8(0, pc1512->firstline - 4, xsize, (pc1512->lastline - pc1512->firstline) + 8); + video_blit_memtoscreen(0, pc1512->firstline - 4, 0, (pc1512->lastline - pc1512->firstline) + 8, 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); diff --git a/src/vid_pcjr.c b/src/vid_pcjr.c index 0e6b47d..fb3643c 100644 --- a/src/vid_pcjr.c +++ b/src/vid_pcjr.c @@ -206,12 +206,12 @@ void pcjr_poll(void *p) video_wait_for_buffer(); } pcjr->lastline = pcjr->displine; - cols[0] = (pcjr->array[2] & 0xf) + 16; + cols[0] = pcjr->array[2] & 0xf; for (c = 0; c < 8; c++) { - buffer->line[pcjr->displine][c] = cols[0]; - if (pcjr->array[0] & 1) buffer->line[pcjr->displine][c + (pcjr->crtc[1] << 3) + 8] = cols[0]; - else buffer->line[pcjr->displine][c + (pcjr->crtc[1] << 4) + 8] = cols[0]; + ((uint32_t *)buffer32->line[pcjr->displine])[c] = cols[0]; + if (pcjr->array[0] & 1) ((uint32_t *)buffer32->line[pcjr->displine])[c + (pcjr->crtc[1] << 3) + 8] = cols[0]; + else ((uint32_t *)buffer32->line[pcjr->displine])[c + (pcjr->crtc[1] << 4) + 8] = cols[0]; } switch (pcjr->addr_mode) @@ -235,14 +235,14 @@ void pcjr_poll(void *p) dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; pcjr->ma++; - buffer->line[pcjr->displine][(x << 3) + 8] = - buffer->line[pcjr->displine][(x << 3) + 9] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 3) + 10] = - buffer->line[pcjr->displine][(x << 3) + 11] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 3) + 12] = - buffer->line[pcjr->displine][(x << 3) + 13] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 3) + 14] = - buffer->line[pcjr->displine][(x << 3) + 15] = pcjr->array[(dat & pcjr->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 9] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 10] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 11] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 12] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 13] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 14] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 15] = pcjr->array[(dat & pcjr->array[1]) + 16]; } break; case 0x12: /*160x200x16*/ @@ -251,22 +251,22 @@ void pcjr_poll(void *p) dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; pcjr->ma++; - buffer->line[pcjr->displine][(x << 4) + 8] = - buffer->line[pcjr->displine][(x << 4) + 9] = - buffer->line[pcjr->displine][(x << 4) + 10] = - buffer->line[pcjr->displine][(x << 4) + 11] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 4) + 12] = - buffer->line[pcjr->displine][(x << 4) + 13] = - buffer->line[pcjr->displine][(x << 4) + 14] = - buffer->line[pcjr->displine][(x << 4) + 15] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 4) + 16] = - buffer->line[pcjr->displine][(x << 4) + 17] = - buffer->line[pcjr->displine][(x << 4) + 18] = - buffer->line[pcjr->displine][(x << 4) + 19] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16] + 16; - buffer->line[pcjr->displine][(x << 4) + 20] = - buffer->line[pcjr->displine][(x << 4) + 21] = - buffer->line[pcjr->displine][(x << 4) + 22] = - buffer->line[pcjr->displine][(x << 4) + 23] = pcjr->array[(dat & pcjr->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 9] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 10] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 11] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 12] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 13] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 14] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 15] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 16] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 17] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 18] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 19] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 20] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 21] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 22] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 23] = pcjr->array[(dat & pcjr->array[1]) + 16]; } break; case 0x03: /*640x200x4*/ @@ -279,7 +279,7 @@ void pcjr_poll(void *p) { chr = (dat >> 7) & 1; chr |= ((dat >> 14) & 2); - buffer->line[pcjr->displine][(x << 3) + 8 + c] = pcjr->array[(chr & pcjr->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 8 + c] = pcjr->array[(chr & pcjr->array[1]) + 16]; dat <<= 1; } } @@ -292,31 +292,31 @@ void pcjr_poll(void *p) drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron); if (pcjr->array[3] & 4) { - cols[1] = pcjr->array[ ((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16; + cols[1] = pcjr->array[ ((attr & 15) & pcjr->array[1]) + 16]; + cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16]; if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16]; + cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16]; } if (pcjr->sc & 8) { for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 3) + c + 8] = cols[0]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + c + 8] = cols[0]; } else { 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]; + ((uint32_t *)buffer32->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++) - buffer->line[pcjr->displine][(x << 3) + c + 8] ^= 15; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + c + 8] ^= 15; } pcjr->ma++; } @@ -329,41 +329,41 @@ void pcjr_poll(void *p) drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron); if (pcjr->array[3] & 4) { - cols[1] = pcjr->array[ ((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16; + cols[1] = pcjr->array[ ((attr & 15) & pcjr->array[1]) + 16]; + cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16]; if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16]; + cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16]; } pcjr->ma++; if (pcjr->sc & 8) { for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[0]; } else { for (c = 0; c < 8; c++) - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } if (drawcursor) { for (c = 0; c < 16; c++) - buffer->line[pcjr->displine][(x << 4) + c + 8] ^= 15; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + c + 8] ^= 15; } } break; case 0x02: /*320x200x4*/ - cols[0] = pcjr->array[0 + 16] + 16; - cols[1] = pcjr->array[1 + 16] + 16; - cols[2] = pcjr->array[2 + 16] + 16; - cols[3] = pcjr->array[3 + 16] + 16; + cols[0] = pcjr->array[0 + 16]; + cols[1] = pcjr->array[1 + 16]; + cols[2] = pcjr->array[2 + 16]; + cols[3] = pcjr->array[3 + 16]; for (x = 0; x < pcjr->crtc[1]; x++) { dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | @@ -371,15 +371,15 @@ void pcjr_poll(void *p) pcjr->ma++; for (c = 0; c < 8; c++) { - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 8] = - buffer->line[pcjr->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } break; case 0x102: /*640x200x2*/ - cols[0] = pcjr->array[0 + 16] + 16; - cols[1] = pcjr->array[1 + 16] + 16; + cols[0] = pcjr->array[0 + 16]; + cols[1] = pcjr->array[1 + 16]; for (x = 0; x < pcjr->crtc[1]; x++) { dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | @@ -387,7 +387,7 @@ void pcjr_poll(void *p) pcjr->ma++; for (c = 0; c < 16; c++) { - buffer->line[pcjr->displine][(x << 4) + c + 8] = cols[dat >> 15]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -398,15 +398,15 @@ void pcjr_poll(void *p) { if (pcjr->array[3] & 4) { - if (pcjr->array[0] & 1) hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, (pcjr->array[2] & 0xf) + 16); - else hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, (pcjr->array[2] & 0xf) + 16); + if (pcjr->array[0] & 1) hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, pcjr->array[2] & 0xf); + else hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, pcjr->array[2] & 0xf); } 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]); + cols[0] = pcjr->array[0 + 16]; + if (pcjr->array[0] & 1) hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, cols[0]); } } if (pcjr->array[0] & 1) x = (pcjr->crtc[1] << 3) + 16; @@ -414,10 +414,15 @@ void pcjr_poll(void *p) if (pcjr->composite) { for (c = 0; c < x; c++) - buffer32->line[pcjr->displine][c] = buffer->line[pcjr->displine][c] & 0xf; + buffer32->line[pcjr->displine][c] = ((uint32_t *)buffer32->line[pcjr->displine])[c] & 0xf; Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]); } + else + { + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[pcjr->displine])[c] = cgapal[((uint32_t *)buffer32->line[pcjr->displine])[c] & 0xf]; + } pcjr->sc = oldsc; if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { @@ -514,10 +519,7 @@ void pcjr_poll(void *p) // 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); - else - video_blit_memtoscreen_8(0, pcjr->firstline-4, xsize, (pcjr->lastline - pcjr->firstline) + 8); + video_blit_memtoscreen(0, pcjr->firstline-4, 0, (pcjr->lastline - pcjr->firstline) + 8, xsize, (pcjr->lastline - pcjr->firstline) + 8); frames++; video_res_x = xsize - 16; diff --git a/src/vid_tandy.c b/src/vid_tandy.c index 769a098..40a6034 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -223,26 +223,26 @@ void tandy_poll(void *p) // printf("Firstline %i\n",firstline); } tandy->lastline = tandy->displine; - cols[0] = (tandy->array[2] & 0xf) + 16; + cols[0] = tandy->array[2] & 0xf; for (c = 0; c < 8; c++) { if (tandy->array[3] & 4) { - buffer->line[tandy->displine][c] = cols[0]; - if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = cols[0]; - else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = cols[0]; + ((uint32_t *)buffer32->line[tandy->displine])[c] = cols[0]; + if (tandy->mode & 1) ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cols[0]; + else ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cols[0]; } else if ((tandy->mode & 0x12) == 0x12) { - buffer->line[tandy->displine][c] = 0; - if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = 0; - else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = 0; + ((uint32_t *)buffer32->line[tandy->displine])[c] = 0; + if (tandy->mode & 1) ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = 0; + else ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = 0; } else { - buffer->line[tandy->displine][c] = (tandy->col & 15) + 16; - if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = (tandy->col & 15) + 16; - else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = (tandy->col & 15) + 16; + ((uint32_t *)buffer32->line[tandy->displine])[c] = tandy->col & 15; + if (tandy->mode & 1) ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = tandy->col & 15; + else ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = tandy->col & 15; } } // printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8); @@ -254,14 +254,14 @@ void tandy_poll(void *p) dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; tandy->ma++; - buffer->line[tandy->displine][(x << 3) + 8] = - buffer->line[tandy->displine][(x << 3) + 9] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 3) + 10] = - buffer->line[tandy->displine][(x << 3) + 11] = tandy->array[((dat >> 8) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 3) + 12] = - buffer->line[tandy->displine][(x << 3) + 13] = tandy->array[((dat >> 4) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 3) + 14] = - buffer->line[tandy->displine][(x << 3) + 15] = tandy->array[(dat & tandy->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 9] = tandy->array[((dat >> 12) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 11] = tandy->array[((dat >> 8) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 13] = tandy->array[((dat >> 4) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 15] = tandy->array[(dat & tandy->array[1]) + 16]; } } else if (tandy->array[3] & 0x10) /*160x200x16*/ @@ -271,22 +271,22 @@ void tandy_poll(void *p) dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; tandy->ma++; - buffer->line[tandy->displine][(x << 4) + 8] = - buffer->line[tandy->displine][(x << 4) + 9] = - buffer->line[tandy->displine][(x << 4) + 10] = - buffer->line[tandy->displine][(x << 4) + 11] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 4) + 12] = - buffer->line[tandy->displine][(x << 4) + 13] = - buffer->line[tandy->displine][(x << 4) + 14] = - buffer->line[tandy->displine][(x << 4) + 15] = tandy->array[((dat >> 8) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 4) + 16] = - buffer->line[tandy->displine][(x << 4) + 17] = - buffer->line[tandy->displine][(x << 4) + 18] = - buffer->line[tandy->displine][(x << 4) + 19] = tandy->array[((dat >> 4) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 4) + 20] = - buffer->line[tandy->displine][(x << 4) + 21] = - buffer->line[tandy->displine][(x << 4) + 22] = - buffer->line[tandy->displine][(x << 4) + 23] = tandy->array[(dat & tandy->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 9] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 11] = tandy->array[((dat >> 12) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 13] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 15] = tandy->array[((dat >> 8) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 16] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 17] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 18] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 19] = tandy->array[((dat >> 4) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 20] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 21] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 22] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 23] = tandy->array[(dat & tandy->array[1]) + 16]; } } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ @@ -300,7 +300,7 @@ void tandy_poll(void *p) { chr = (dat >> 7) & 1; chr |= ((dat >> 14) & 2); - buffer->line[tandy->displine][(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16]; dat <<= 1; } } @@ -314,31 +314,31 @@ void tandy_poll(void *p) drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); if (tandy->mode & 0x20) { - cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16; + cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]; if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16; + cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16]; } if (tandy->sc & 8) { for (c = 0; c < 8; c++) - buffer->line[tandy->displine][(x << 3) + c + 8] = cols[0]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[0]; } else { 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]; + ((uint32_t *)buffer32->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++) - buffer->line[tandy->displine][(x << 3) + c + 8] ^= 15; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] ^= 0xffffff; } tandy->ma++; } @@ -352,40 +352,40 @@ void tandy_poll(void *p) drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); if (tandy->mode & 0x20) { - cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16; + cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]; if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16; + cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16]; } tandy->ma++; if (tandy->sc & 8) { for (c = 0; c < 8; c++) - buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = - buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[0]; } else { for (c = 0; c < 8; c++) - buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = - buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } if (drawcursor) { for (c = 0; c < 16; c++) - buffer->line[tandy->displine][(x << 4) + c + 8] ^= 15; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] ^= 0xffffff; } } } - else if (!(tandy->mode& 16)) + else if (!(tandy->mode & 16)) { - cols[0] = (tandy->col & 15) | 16; - col = (tandy->col & 16) ? 24 : 16; + cols[0] = tandy->col & 15; + col = (tandy->col & 16) ? 8 : 0; if (tandy->mode & 4) { cols[1] = col | 3; @@ -411,8 +411,8 @@ void tandy_poll(void *p) tandy->ma++; for (c = 0; c < 8; c++) { - buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = - buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } @@ -420,7 +420,7 @@ void tandy_poll(void *p) else { cols[0] = 0; - cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16] + 16; + cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16]; for (x = 0; x < tandy->crtc[1]; x++) { dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | @@ -428,7 +428,7 @@ void tandy_poll(void *p) tandy->ma++; for (c = 0; c < 16; c++) { - buffer->line[tandy->displine][(x << 4) + c + 8] = cols[dat >> 15]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -438,14 +438,14 @@ void tandy_poll(void *p) { if (tandy->array[3] & 4) { - if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, (tandy->array[2] & 0xf) + 16); - else hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, (tandy->array[2] & 0xf) + 16); + if (tandy->mode & 1) hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, tandy->array[2] & 0xf); + else hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, tandy->array[2] & 0xf); } else { - cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf) + 16; - if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); + cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf); + if (tandy->mode & 1) hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); } } if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; @@ -454,10 +454,15 @@ void tandy_poll(void *p) if (tandy->composite) { for (c = 0; c < x; c++) - buffer32->line[tandy->displine][c] = buffer->line[tandy->displine][c] & 0xf; + buffer32->line[tandy->displine][c] = ((uint32_t *)buffer32->line[tandy->displine])[c] & 0xf; Composite_Process(tandy->mode, 0, x >> 2, buffer32->line[tandy->displine]); } + else + { + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[((uint32_t *)buffer32->line[tandy->displine])[c] & 0xf]; + } tandy->sc = oldsc; if (tandy->vc == tandy->crtc[7] && !tandy->sc) @@ -553,10 +558,7 @@ void tandy_poll(void *p) // 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); - else - video_blit_memtoscreen_8(0, tandy->firstline-4, xsize, (tandy->lastline - tandy->firstline) + 8); + video_blit_memtoscreen(0, tandy->firstline-4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8); frames++; video_res_x = xsize - 16; diff --git a/src/vid_tandysl.c b/src/vid_tandysl.c index 22f3521..183fa5a 100644 --- a/src/vid_tandysl.c +++ b/src/vid_tandysl.c @@ -287,26 +287,26 @@ static void tandysl_poll(void *p) // printf("Firstline %i\n",firstline); } tandy->lastline = tandy->displine; - cols[0] = (tandy->array[2] & 0xf) + 16; + cols[0] = cgapal[tandy->array[2] & 0xf]; for (c = 0; c < 8; c++) { if (tandy->array[3] & 4) { - buffer->line[tandy->displine][c] = cols[0]; - if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = cols[0]; - else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = cols[0]; + ((uint32_t *)buffer32->line[tandy->displine])[c] = cols[0]; + if (tandy->mode & 1) ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cols[0]; + else ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cols[0]; } else if ((tandy->mode & 0x12) == 0x12) { - buffer->line[tandy->displine][c] = 0; - if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = 0; - else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = 0; + ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[0]; + if (tandy->mode & 1) ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cgapal[0]; + else ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cgapal[0]; } else { - buffer->line[tandy->displine][c] = (tandy->col & 15) + 16; - if (tandy->mode & 1) buffer->line[tandy->displine][c + (tandy->crtc[1] << 3) + 8] = (tandy->col & 15) + 16; - else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = (tandy->col & 15) + 16; + ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[tandy->col & 15]; + if (tandy->mode & 1) ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cgapal[tandy->col & 15]; + else ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cgapal[tandy->col & 15]; } } if (tandy->array[5] & 1) /*640x200x16*/ @@ -316,10 +316,10 @@ static void tandysl_poll(void *p) dat = (tandy->vram[(tandy->ma << 1) & 0xffff] << 8) | tandy->vram[((tandy->ma << 1) + 1) & 0xffff]; tandy->ma++; - buffer->line[tandy->displine][(x << 2) + 8] = tandy->array[((dat >> 12) & 0xf)/*tandy->array[1])*/ + 16] + 16; - buffer->line[tandy->displine][(x << 2) + 9] = tandy->array[((dat >> 8) & 0xf)/*tandy->array[1])*/ + 16] + 16; - buffer->line[tandy->displine][(x << 2) + 10] = tandy->array[((dat >> 4) & 0xf)/*tandy->array[1])*/ + 16] + 16; - buffer->line[tandy->displine][(x << 2) + 11] = tandy->array[(dat & 0xf)/*tandy->array[1])*/ + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 8] = cgapal[tandy->array[((dat >> 12) & 0xf)/*tandy->array[1])*/ + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 9] = cgapal[tandy->array[((dat >> 8) & 0xf)/*tandy->array[1])*/ + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 10] = cgapal[tandy->array[((dat >> 4) & 0xf)/*tandy->array[1])*/ + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 11] = cgapal[tandy->array[(dat & 0xf)/*tandy->array[1])*/ + 16]]; } } else if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ @@ -329,14 +329,14 @@ static void tandysl_poll(void *p) dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; tandy->ma++; - buffer->line[tandy->displine][(x << 3) + 8] = - buffer->line[tandy->displine][(x << 3) + 9] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 3) + 10] = - buffer->line[tandy->displine][(x << 3) + 11] = tandy->array[((dat >> 8) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 3) + 12] = - buffer->line[tandy->displine][(x << 3) + 13] = tandy->array[((dat >> 4) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 3) + 14] = - buffer->line[tandy->displine][(x << 3) + 15] = tandy->array[(dat & tandy->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 9] = cgapal[tandy->array[((dat >> 12) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 11] = cgapal[tandy->array[((dat >> 8) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 13] = cgapal[tandy->array[((dat >> 4) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 15] = cgapal[tandy->array[(dat & tandy->array[1]) + 16]]; } } else if (tandy->array[3] & 0x10) /*160x200x16*/ @@ -346,22 +346,22 @@ static void tandysl_poll(void *p) dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; tandy->ma++; - buffer->line[tandy->displine][(x << 4) + 8] = - buffer->line[tandy->displine][(x << 4) + 9] = - buffer->line[tandy->displine][(x << 4) + 10] = - buffer->line[tandy->displine][(x << 4) + 11] = tandy->array[((dat >> 12) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 4) + 12] = - buffer->line[tandy->displine][(x << 4) + 13] = - buffer->line[tandy->displine][(x << 4) + 14] = - buffer->line[tandy->displine][(x << 4) + 15] = tandy->array[((dat >> 8) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 4) + 16] = - buffer->line[tandy->displine][(x << 4) + 17] = - buffer->line[tandy->displine][(x << 4) + 18] = - buffer->line[tandy->displine][(x << 4) + 19] = tandy->array[((dat >> 4) & tandy->array[1]) + 16] + 16; - buffer->line[tandy->displine][(x << 4) + 20] = - buffer->line[tandy->displine][(x << 4) + 21] = - buffer->line[tandy->displine][(x << 4) + 22] = - buffer->line[tandy->displine][(x << 4) + 23] = tandy->array[(dat & tandy->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 9] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 11] = cgapal[tandy->array[((dat >> 12) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 13] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 15] = cgapal[tandy->array[((dat >> 8) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 16] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 17] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 18] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 19] = cgapal[tandy->array[((dat >> 4) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 20] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 21] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 22] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 23] = cgapal[tandy->array[(dat & tandy->array[1]) + 16]]; } } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ @@ -375,7 +375,7 @@ static void tandysl_poll(void *p) { chr = (dat >> 7) & 1; chr |= ((dat >> 14) & 2); - buffer->line[tandy->displine][(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16] + 16; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8 + c] = cgapal[tandy->array[(chr & tandy->array[1]) + 16]]; dat <<= 1; } } @@ -389,31 +389,31 @@ static void tandysl_poll(void *p) drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); if (tandy->mode & 0x20) { - cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16; + cols[1] = cgapal[tandy->array[ ((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]]; if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16; + cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[((attr >> 4) & tandy->array[1]) + 16]]; } if (tandy->sc & 8) { for (c = 0; c < 8; c++) - buffer->line[tandy->displine][(x << 3) + c + 8] = cols[0]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[0]; } else { 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]; + ((uint32_t *)buffer32->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++) - buffer->line[tandy->displine][(x << 3) + c + 8] ^= 15; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] ^= 0xffffff; } tandy->ma++; } @@ -427,57 +427,57 @@ static void tandysl_poll(void *p) drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); if (tandy->mode & 0x20) { - cols[1] = tandy->array[ ((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16] + 16; + cols[1] = cgapal[tandy->array[ ((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]]; if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) cols[1] = cols[0]; } else { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16] + 16; - cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16] + 16; + cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[((attr >> 4) & tandy->array[1]) + 16]]; } tandy->ma++; if (tandy->sc & 8) { for (c = 0; c < 8; c++) - buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = - buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[0]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[0]; } else { for (c = 0; c < 8; c++) - buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = - buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } if (drawcursor) { for (c = 0; c < 16; c++) - buffer->line[tandy->displine][(x << 4) + c + 8] ^= 15; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] ^= 0xffffff; } } } - else if (!(tandy->mode& 16)) + else if (!(tandy->mode & 16)) { - cols[0] = (tandy->col & 15) | 16; - col = (tandy->col & 16) ? 24 : 16; + cols[0] = cgapal[tandy->col & 15]; + col = (tandy->col & 16) ? 8 : 0; if (tandy->mode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; } else if (tandy->col & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; } for (x = 0; x < tandy->crtc[1]; x++) { @@ -486,16 +486,16 @@ static void tandysl_poll(void *p) tandy->ma++; for (c = 0; c < 8; c++) { - buffer->line[tandy->displine][(x << 4) + (c << 1) + 8] = - buffer->line[tandy->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; } } } else { - cols[0] = 0; - cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16] + 16; + cols[0] = cgapal[0]; + cols[1] = cgapal[tandy->array[(tandy->col & tandy->array[1]) + 16]]; for (x = 0; x < tandy->crtc[1]; x++) { dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | @@ -503,7 +503,7 @@ static void tandysl_poll(void *p) tandy->ma++; for (c = 0; c < 16; c++) { - buffer->line[tandy->displine][(x << 4) + c + 8] = cols[dat >> 15]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -513,14 +513,14 @@ static void tandysl_poll(void *p) { if (tandy->array[3] & 4) { - if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, (tandy->array[2] & 0xf) + 16); - else hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, (tandy->array[2] & 0xf) + 16); + if (tandy->mode & 1) hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cgapal[tandy->array[2] & 0xf]); + else hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cgapal[tandy->array[2] & 0xf]); } else { - cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf) + 16; - if (tandy->mode & 1) hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); - else hline(buffer, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); + cols[0] = cgapal[((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf)]; + if (tandy->mode & 1) hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); } } if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; @@ -631,7 +631,7 @@ static void tandysl_poll(void *p) // 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); + video_blit_memtoscreen(0, tandy->firstline-4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8); frames++; video_res_x = xsize - 16; diff --git a/src/vid_wy700.c b/src/vid_wy700.c index df4cfad..107b134 100644 --- a/src/vid_wy700.c +++ b/src/vid_wy700.c @@ -149,6 +149,7 @@ static uint8_t mode_40x24[] = 0x0f, /* Maximum raster address */ }; +static uint32_t wy700_pal[4]; /* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */ extern uint8_t fontdatw[512][32]; @@ -553,7 +554,7 @@ void wy700_textline(wy700_t *wy700) if (sc == 14 && mda && ((attr & 7) == 1)) { for (c = 0; c < cw; c++) - buffer->line[wy700->displine][(x * cw) + c] = + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] = mdacols[attr][blink][1]; } else /* Draw 16 pixels of character */ @@ -565,21 +566,23 @@ void wy700_textline(wy700_t *wy700) int col; if (c < 8) col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - else col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; + else + col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) col = mdacols[0][0][0]; if (w == 40) { - buffer->line[wy700->displine][(x * cw) + 2*c] = col; - buffer->line[wy700->displine][(x * cw) + 2*c + 1] = col; + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + 2*c] = col; + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + 2*c + 1] = col; } - else buffer->line[wy700->displine][(x * cw) + c] = col; + else + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] = col; } if (drawcursor) { for (c = 0; c < cw; c++) - buffer->line[wy700->displine][(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; } ++ma; } @@ -592,7 +595,7 @@ void wy700_cgaline(wy700_t *wy700) { int x, c; uint32_t dat; - uint8_t ink = 0; + uint32_t ink = 0; uint16_t addr; uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; @@ -614,11 +617,11 @@ void wy700_cgaline(wy700_t *wy700) { for (c = 0; c < 32; c++) { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; + ink = (dat & 0x80000000) ? wy700_pal[3]: wy700_pal[0]; if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = 16; - buffer->line[wy700->displine][x*64 + 2*c] = - buffer->line[wy700->displine][x*64 + 2*c+1] = + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 2*c] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 2*c+1] = ink; dat = dat << 1; } @@ -627,19 +630,13 @@ void wy700_cgaline(wy700_t *wy700) { for (c = 0; c < 16; c++) { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } + ink = wy700_pal[(dat >> 30) & 3]; if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = 16; - buffer->line[wy700->displine][x*64 + 4*c] = - buffer->line[wy700->displine][x*64 + 4*c+1] = - buffer->line[wy700->displine][x*64 + 4*c+2] = - buffer->line[wy700->displine][x*64 + 4*c+3] = + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c+1] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c+2] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c+3] = ink; dat = dat << 2; } @@ -652,7 +649,7 @@ void wy700_medresline(wy700_t *wy700) { int x, c; uint32_t dat; - uint8_t ink = 0; + uint32_t ink = 0; uint32_t addr; addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; @@ -669,19 +666,14 @@ void wy700_medresline(wy700_t *wy700) { for (c = 0; c < 16; c++) { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } + ink = wy700_pal[(dat >> 30) & 3]; /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*64 + 4*c] = - buffer->line[wy700->displine][x*64 + 4*c+1] = - buffer->line[wy700->displine][x*64 + 4*c+2] = - buffer->line[wy700->displine][x*64 + 4*c+3] = + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c+1] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c+2] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 4*c+3] = ink; dat = dat << 2; } @@ -690,11 +682,12 @@ void wy700_medresline(wy700_t *wy700) { for (c = 0; c < 32; c++) { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; + ink = (dat & 0x80000000) ? wy700_pal[3]: wy700_pal[0]; /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*64 + 2*c] = - buffer->line[wy700->displine][x*64 + 2*c+1] = + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 2*c] = + ((uint32_t *)buffer32->line[wy700->displine])[x*64 + 2*c+1] = ink; dat = dat << 1; } @@ -710,7 +703,7 @@ void wy700_hiresline(wy700_t *wy700) { int x, c; uint32_t dat; - uint8_t ink = 0; + uint32_t ink = 0; uint32_t addr; addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; @@ -731,17 +724,12 @@ void wy700_hiresline(wy700_t *wy700) { for (c = 0; c < 16; c++) { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } + ink = wy700_pal[(dat >> 30) & 3]; /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*32 + 2*c] = - buffer->line[wy700->displine][x*32 + 2*c+1] = + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x*32 + 2*c] = + ((uint32_t *)buffer32->line[wy700->displine])[x*32 + 2*c+1] = ink; dat = dat << 2; } @@ -750,10 +738,11 @@ void wy700_hiresline(wy700_t *wy700) { for (c = 0; c < 32; c++) { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; + ink = (dat & 0x80000000) ? wy700_pal[3]: wy700_pal[0]; /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer->line[wy700->displine][x*32 + c] = ink; + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x*32 + c] = ink; dat = dat << 1; } } @@ -845,7 +834,7 @@ void wy700_poll(void *p) if (ysize < 32) ysize = 200; updatewindowsize(xsize, ysize); } - video_blit_memtoscreen_8(0, 0, xsize, ysize); + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); frames++; /* Fixed 1280x800 resolution */ @@ -888,72 +877,78 @@ void *wy700_init() 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); + wy700_pal[0] = makecol(0x00, 0x00, 0x00); + wy700_pal[1] = makecol(0x55, 0x55, 0x55); + wy700_pal[2] = makecol(0xaa, 0xaa, 0xaa); + wy700_pal[3] = makecol(0xff, 0xff, 0xff); + /* Set up the emulated attributes. * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ for (c = 0; c < 0x10; c++) { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 7 + 16; + cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = wy700_pal[0]; + if (c & 8) cgacols[c][0][1] = wy700_pal[3]; + else cgacols[c][0][1] = wy700_pal[2]; } for (c = 0x10; c < 0x80; c++) { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16 + 7; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 0 + 16; + cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = wy700_pal[2]; + if (c & 8) cgacols[c][0][1] = wy700_pal[3]; + else cgacols[c][0][1] = wy700_pal[0]; - if ((c & 0x0F) == 8) cgacols[c][0][1] = 8 + 16; + if ((c & 0x0F) == 8) + cgacols[c][0][1] = wy700_pal[1]; } /* With special cases for 00, 11, 22, ... 77 */ - cgacols[0x00][0][1] = cgacols[0x00][1][1] = 16; + cgacols[0x00][0][1] = cgacols[0x00][1][1] = wy700_pal[0]; for (c = 0x11; c <= 0x77; c += 0x11) { - cgacols[c][0][1] = cgacols[c][1][1] = 16 + 7; + cgacols[c][0][1] = cgacols[c][1][1] = wy700_pal[2]; } for (c = 0x80; c < 0x90; c++) { - cgacols[c][0][0] = 16 + 8; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 7 + 16; + cgacols[c][0][0] = wy700_pal[1]; + if (c & 8) cgacols[c][0][1] = wy700_pal[3]; + else cgacols[c][0][1] = wy700_pal[2]; cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c-0x80][0][0]; } for (c = 0x90; c < 0x100; c++) { - cgacols[c][0][0] = 16 + 15; - if (c & 8) cgacols[c][0][1] = 8 + 16; - else cgacols[c][0][1] = 7 + 16; - if ((c & 0x0F) == 0) cgacols[c][0][1] = 16; + cgacols[c][0][0] = wy700_pal[3]; + if (c & 8) cgacols[c][0][1] = wy700_pal[1]; + else cgacols[c][0][1] = wy700_pal[2]; + if ((c & 0x0F) == 0) cgacols[c][0][1] = wy700_pal[0]; cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c-0x80][0][0]; } /* Also special cases for 99, AA, ..., FF */ for (c = 0x99; c <= 0xFF; c += 0x11) { - cgacols[c][0][1] = 16 + 15; + cgacols[c][0][1] = wy700_pal[3]; } /* Special cases for 08, 80 and 88 */ - cgacols[0x08][0][1] = 16 + 8; - cgacols[0x80][0][1] = 16; - cgacols[0x88][0][1] = 16 + 8; + cgacols[0x08][0][1] = wy700_pal[1]; + cgacols[0x80][0][1] = wy700_pal[0]; + cgacols[0x88][0][1] = wy700_pal[1]; /* MDA attributes */ for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = wy700_pal[0]; + if (c & 8) mdacols[c][0][1] = wy700_pal[3]; + else mdacols[c][0][1] = wy700_pal[2]; } - 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; + mdacols[0x70][0][1] = wy700_pal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = wy700_pal[3]; + mdacols[0xF0][0][1] = wy700_pal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = wy700_pal[3]; + mdacols[0x78][0][1] = wy700_pal[2]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = wy700_pal[3]; + mdacols[0xF8][0][1] = wy700_pal[2]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = wy700_pal[3]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = wy700_pal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = wy700_pal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = wy700_pal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = wy700_pal[0]; /* Start off in 80x25 text mode */ wy700->cga_stat = 0xF4; diff --git a/src/video.c b/src/video.c index b2d477b..80753cc 100644 --- a/src/video.c +++ b/src/video.c @@ -245,7 +245,6 @@ int video_timing_b, video_timing_w, video_timing_l; int video_res_x, video_res_y, video_bpp; void (*video_blit_memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); -void (*video_blit_memtoscreen_8_func)(int x, int y, int w, int h); void video_init() { @@ -314,7 +313,7 @@ void video_init() } -BITMAP *buffer, *buffer32; +BITMAP *buffer32; uint8_t fontdat[256][8]; uint8_t fontdatm[256][16]; @@ -323,8 +322,6 @@ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ int xsize=1,ysize=1; -PALETTE cgapal; - void loadfont(char *s, int format) { FILE *f=romfopen(s,"rb"); @@ -419,7 +416,7 @@ void loadfont(char *s, int format) static struct { - int x, y, y1, y2, w, h, blit8; + int x, y, y1, y2, w, h; int busy; int buffer_in_use; @@ -431,29 +428,14 @@ static struct static void blit_thread(void *param); +uint32_t cgapal[16]; + void initvideo() { int c, d, e; buffer32 = create_bitmap(2048, 2048); - buffer = create_bitmap(2048, 2048); - - for (c = 0; c < 64; c++) - { - cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - if ((c & 0x17) == 6) - cgapal[c + 64].g >>= 1; - } - for (c = 0; c < 64; c++) - { - cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21; - cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21; - } - for (c = 0; c < 256; c++) { e = c; @@ -484,6 +466,23 @@ void initvideo() for (c = 0; c < 65536; c++) video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x00, 0xaa); + cgapal[0x2] = makecol(0x00, 0xaa, 0x00); + cgapal[0x3] = makecol(0x00, 0xaa, 0xaa); + cgapal[0x4] = makecol(0xaa, 0x00, 0x00); + cgapal[0x5] = makecol(0xaa, 0x00, 0xaa); + cgapal[0x6] = makecol(0xaa, 0x55, 0x00); + cgapal[0x7] = makecol(0xaa, 0xaa, 0xaa); + cgapal[0x8] = makecol(0x55, 0x55, 0x55); + cgapal[0x9] = makecol(0x55, 0x55, 0xff); + cgapal[0xa] = makecol(0x55, 0xff, 0x55); + cgapal[0xb] = makecol(0x55, 0xff, 0xff); + cgapal[0xc] = makecol(0xff, 0x55, 0x55); + cgapal[0xd] = makecol(0xff, 0x55, 0xff); + cgapal[0xe] = makecol(0xff, 0xff, 0x55); + cgapal[0xf] = makecol(0xff, 0xff, 0xff); + blit_data.wake_blit_thread = thread_create_event(); blit_data.blit_complete = thread_create_event(); blit_data.buffer_not_in_use = thread_create_event(); @@ -499,7 +498,6 @@ void closevideo() free(video_15to32); free(video_16to32); - destroy_bitmap(buffer); destroy_bitmap(buffer32); } @@ -511,10 +509,7 @@ static void blit_thread(void *param) thread_wait_event(blit_data.wake_blit_thread, -1); thread_reset_event(blit_data.wake_blit_thread); - if (blit_data.blit8) - video_blit_memtoscreen_8_func(blit_data.x, blit_data.y, blit_data.w, blit_data.h); - else - video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); + video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); blit_data.busy = 0; thread_set_event(blit_data.blit_complete); @@ -551,18 +546,5 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) blit_data.y2 = y2; blit_data.w = w; blit_data.h = h; - blit_data.blit8 = 0; - thread_set_event(blit_data.wake_blit_thread); -} - -void video_blit_memtoscreen_8(int x, int y, int w, int h) -{ - video_wait_for_blit(); - blit_data.busy = 1; - blit_data.x = x; - blit_data.y = y; - blit_data.w = w; - blit_data.h = h; - blit_data.blit8 = 1; thread_set_event(blit_data.wake_blit_thread); } diff --git a/src/video.h b/src/video.h index f7fa3e7..dc04a81 100644 --- a/src/video.h +++ b/src/video.h @@ -29,7 +29,7 @@ typedef RGB PALETTE[256]; #endif -extern BITMAP *buffer, *buffer32; +extern BITMAP *buffer32; int video_card_available(int card); char *video_card_getname(int card); @@ -74,10 +74,8 @@ extern int readflash; extern void (*video_recalctimings)(); void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -void video_blit_memtoscreen_8(int x, int y, int w, int h); extern void (*video_blit_memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); -extern void (*video_blit_memtoscreen_8_func)(int x, int y, int w, int h); extern int video_timing_b, video_timing_w, video_timing_l; extern int video_speed; @@ -99,3 +97,5 @@ void video_updatetiming(); void hline(BITMAP *b, int x1, int y, int x2, int col); void destroy_bitmap(BITMAP *b); + +extern uint32_t cgapal[16]; diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 5ba60e4..e9c109e 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -15,7 +15,6 @@ extern "C" void device_force_redraw(); static void d3d_fs_init_objects(); static void d3d_fs_close_objects(); 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(); @@ -37,31 +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[] = { { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, @@ -83,13 +57,9 @@ static CUSTOMVERTEX d3d_verts[] = void d3d_fs_init(HWND h) { - int c; 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); - d3d_hwnd = h; d3d_device_window = CreateWindowEx ( @@ -130,7 +100,6 @@ void d3d_fs_init(HWND h) d3d_fs_init_objects(); video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen; - video_blit_memtoscreen_8_func = d3d_fs_blit_memtoscreen_8; } static void d3d_fs_close_objects() @@ -406,123 +375,3 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) 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)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK && readflash && vid_disc_indicator) - { - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); - readflash = 0; - } - - 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); -} diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 97eb536..763df0f 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -15,7 +15,6 @@ extern "C" void video_blit_complete(); void d3d_init_objects(); void d3d_close_objects(); 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; @@ -32,31 +31,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[] = { { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, @@ -78,11 +52,6 @@ static CUSTOMVERTEX d3d_verts[] = void d3d_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); - d3d_hwnd = h; d3d = Direct3DCreate9(D3D_SDK_VERSION); @@ -108,7 +77,6 @@ void d3d_init(HWND h) d3d_init_objects(); video_blit_memtoscreen_func = d3d_blit_memtoscreen; - video_blit_memtoscreen_8_func = d3d_blit_memtoscreen_8; } void d3d_close_objects() @@ -239,7 +207,7 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) RECT r; int yy; - if (y1 == y2) + if (y1 == y2 || h <= 0) { video_blit_complete(); return; /*Nothing to do*/ @@ -256,7 +224,10 @@ 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((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) + 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); @@ -326,106 +297,3 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) 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; - int yy, xx; - HRESULT hr = D3D_OK; - - if (h == 0) - { - 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++) - { - 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;//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; - 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 - 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_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 && readflash && vid_disc_indicator) - { - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); - readflash = 0; - } - - 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); -} diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index 9f16819..bc581e3 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -16,7 +16,6 @@ extern "C" void ddraw_fs_close(); extern "C" void video_blit_complete(); 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; @@ -29,41 +28,11 @@ 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) { - int c; - 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); - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) fatal("DirectDrawCreate failed\n"); @@ -108,7 +77,6 @@ void ddraw_fs_init(HWND h) 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; } void ddraw_fs_close() @@ -260,77 +228,3 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h 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; - - 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 *)((uintptr_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 && vid_disc_indicator) - { - 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-ddraw.cc b/src/win-ddraw.cc index a46dbf9..9cecff8 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -16,7 +16,6 @@ extern "C" void ddraw_close(); extern "C" void video_blit_complete(); 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; @@ -28,38 +27,8 @@ 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); - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) fatal("DirectDrawCreate failed\n"); @@ -112,7 +81,6 @@ void ddraw_init(HWND h) pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; video_blit_memtoscreen_func = ddraw_blit_memtoscreen; - video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8; } void ddraw_close() @@ -154,6 +122,9 @@ 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 (h <= 0) + return; + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -171,7 +142,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) + if ((y + yy) >= 0 && (y + yy) < buffer32->h) memcpy((void *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); } video_blit_complete(); @@ -223,87 +194,3 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) 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; - - 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 *)((uintptr_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 *)((uintptr_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 && vid_disc_indicator) - { - readflash = 0; - 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 *)((uintptr_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); - } -} diff --git a/src/win-video.c b/src/win-video.c index 2228481..7f0ca5c 100644 --- a/src/win-video.c +++ b/src/win-video.c @@ -7,13 +7,11 @@ BITMAP *screen; void hline(BITMAP *b, int x1, int y, int x2, int col) { - if (y < 0 || y >= buffer->h) + if (y < 0 || y >= buffer32->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); + for (; x1 < x2; x1++) + ((uint32_t *)b->line[y])[x1] = col; } void blit(BITMAP *src, BITMAP *dst, int x1, int y1, int x2, int y2, int xs, int ys) From fd36feae52e64f5c1f442c965f47a8302f9d8ec3 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Sun, 28 May 2017 18:21:17 +0100 Subject: [PATCH 0016/1050] Removed Allegro paletteised blitting code. --- src/allegro-video.c | 78 --------------------------------------------- 1 file changed, 78 deletions(-) diff --git a/src/allegro-video.c b/src/allegro-video.c index 5ca4da3..694f586 100644 --- a/src/allegro-video.c +++ b/src/allegro-video.c @@ -4,45 +4,13 @@ #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_func = allegro_blit_memtoscreen; - video_blit_memtoscreen_8_func = 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); } @@ -83,49 +51,3 @@ 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) -{ - 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]]; - } - } - } - video_blit_complete(); - 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); -} From 828224d14871cf2619a157a20698b3d4b8f3bbd2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 29 May 2017 12:13:45 +0100 Subject: [PATCH 0017/1050] Fixed more uninitialised variables. --- 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 e9c109e..b0f2c0a 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -271,7 +271,7 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) D3DLOCKED_RECT dr; RECT window_rect; int yy; - double l, t, r, b; + double l = 0, t = 0, r = 0, b = 0; if (y1 == y2) { From a2f44b8ea77bc98878db76db8ebd58685946e99e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 29 May 2017 13:56:19 +0100 Subject: [PATCH 0018/1050] Add support for BIN/CUE images. Patch from bit, BIN/CUE handling from DOSBox. --- src/Makefile.am | 4 +- src/Makefile.linux32 | 4 +- src/Makefile.linux64 | 4 +- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 4 +- src/allegro-gui.c | 16 +- src/cdrom-image.cc | 551 +++++++++++++++++++++++++++++++++++++ src/cdrom-image.h | 23 ++ src/cdrom-ioctl.c | 3 - src/cdrom-iso.c | 356 ------------------------ src/cdrom-iso.h | 13 - src/dosbox/cdrom.h | 172 ++++++++++++ src/dosbox/cdrom_image.cpp | 546 ++++++++++++++++++++++++++++++++++++ src/ibm.h | 2 +- src/ide.c | 2 +- src/ide.h | 2 +- src/pc.c | 38 ++- src/pc.rc | 2 +- src/resources.h | 2 +- src/sound.c | 4 + src/win.c | 34 +-- 21 files changed, 1363 insertions(+), 423 deletions(-) create mode 100644 src/cdrom-image.cc create mode 100644 src/cdrom-image.h delete mode 100644 src/cdrom-iso.c delete mode 100644 src/cdrom-iso.h create mode 100644 src/dosbox/cdrom.h create mode 100644 src/dosbox/cdrom_image.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 2e02c2f..babad39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \ allegro-gui-config-sel.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 \ +allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-image.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 dells200.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 \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ @@ -32,7 +32,7 @@ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti06 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 vid_wy700.c \ -x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ +x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ dosbox/vid_cga_comp.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_PS_.cc resid-fp/wave6581_PST.cc \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index ef20a09..69c1330 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -5,7 +5,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.o cdrom-null.o \ +allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -22,7 +22,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_ 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 wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 52fe554..70ea9d7 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -4,7 +4,7 @@ CC = gcc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.o cdrom-null.o \ +allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -21,7 +21,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_ 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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 95c34a8..68e24e5 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 \ @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index bd4194a..b210a22 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 \ @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 diff --git a/src/allegro-gui.c b/src/allegro-gui.c index 43914e6..427c226 100644 --- a/src/allegro-gui.c +++ b/src/allegro-gui.c @@ -5,7 +5,7 @@ #include "disc.h" #include "ide.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "cdrom-null.h" void warning(const char *format, ...) @@ -128,7 +128,7 @@ static void cdrom_update() case -1: cdrom_menu[1].flags = D_SELECTED; break; - case CDROM_ISO: + case CDROM_IMAGE: cdrom_menu[3].flags = D_SELECTED; break; default: @@ -200,14 +200,14 @@ static int cdrom_dev() return D_O_K; } -static int cdrom_iso() +static int cdrom_image() { char fn[260]; int ret; int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - strcpy(fn, iso_path); - ret = file_select_ex("Please choose an ISO image", fn, "ISO", 260, xsize, ysize); + strcpy(fn, image_path); + ret = file_select_ex("Please choose an image image", fn, "ISO;CUE", 260, xsize, ysize); if (ret) { if (!cdrom_enabled) @@ -220,8 +220,8 @@ static int cdrom_iso() atapi->exit(); } - cdrom_drive = CDROM_ISO; - iso_open(fn); + cdrom_drive = CDROM_IMAGE; + image_open(fn); if (!cdrom_enabled) { cdrom_enabled = 1; @@ -238,7 +238,7 @@ static MENU cdrom_menu[] = {"&Disabled", cdrom_disabled, NULL, 0, NULL}, {"&Empty", cdrom_empty, NULL, 0, NULL}, {"/dev/cdrom", cdrom_dev, NULL, 0, NULL}, - {"&ISO image...", cdrom_iso, NULL, 0, NULL}, + {"&Image...", cdrom_image, NULL, 0, NULL}, {NULL,NULL,NULL,0,NULL} }; diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc new file mode 100644 index 0000000..464adf3 --- /dev/null +++ b/src/cdrom-image.cc @@ -0,0 +1,551 @@ +#include +#include "cdrom-image.h" +#include "dosbox/cdrom.h" + +extern "C" +{ +#include "ibm.h" +#include "ide.h" + +int cdrom_drive; +int old_cdrom_drive; +} + +char image_path[1024]; +static int image_changed = 0; + +extern ATAPI image_atapi; + +CDROM_Interface_Image *cdrom = NULL; + +#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)) + +static uint32_t cdrom_capacity = 0; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +static int image_cd_state = CD_STOPPED; +static uint32_t image_cd_pos = 0, image_cd_end = 0; + +#define BUF_SIZE 32768 +static int16_t cd_buffer[BUF_SIZE]; +static int cd_buflen = 0; + +void image_audio_callback(int16_t *output, int len) +{ + if (image_cd_state != CD_PLAYING) + return; + while (cd_buflen < len) + { + if (image_cd_pos < image_cd_end) + { +// pclog("Read to %i\n", cd_buflen); + if (!cdrom->ReadSector((unsigned char *)&cd_buffer[cd_buflen], true, image_cd_pos - 150)) + { +// pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + image_cd_state = CD_STOPPED; + cd_buflen = len; + } + else + { +// pclog("DeviceIoControl returned true\n"); + image_cd_pos++; + cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + image_cd_state = CD_STOPPED; + cd_buflen = len; + } + } + memcpy(output, cd_buffer, len * 2); + memmove(cd_buffer, &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; +} + +void image_audio_stop() +{ + image_cd_state = CD_STOPPED; +} + +static int image_is_track_audio(uint32_t pos, int ismsf) +{ + if (!cdrom) return 0; + if (ismsf) + { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSF_TO_FRAMES(m, s, f); + } + + unsigned char attr; + TMSF tmsf; + int number; + cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +static void image_playaudio(uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdrom) return; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + pclog("Can't play data track\n"); + image_cd_pos = 0; + image_cd_state = CD_STOPPED; + return; + } + pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) + { + int m, s, f; + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + 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); + } + else + len += pos; + image_cd_pos = pos;// + 150; + image_cd_end = len;// + 150; + image_cd_state = CD_PLAYING; + if (image_cd_pos < 150) + image_cd_pos = 150; + cd_buflen = 0; + pclog("Audio start %08X %08X %i %i %i\n", image_cd_pos, image_cd_end, image_cd_state, cd_buflen, len); +} + +static void image_pause(void) +{ + if (!cdrom) return; + if (image_cd_state == CD_PLAYING) + image_cd_state = CD_PAUSED; +} + +static void image_resume(void) +{ + if (!cdrom) return; + if (image_cd_state == CD_PAUSED) + image_cd_state = CD_PLAYING; +} + +static void image_stop(void) +{ + if (!cdrom) return; + image_cd_state = CD_STOPPED; +} + +static void image_seek(uint32_t pos) +{ + if (!cdrom) return; + image_cd_pos = pos; + image_cd_state = CD_STOPPED; +} + +static int image_ready(void) +{ + if (!cdrom) + return 0; + + if (strlen(image_path) == 0) + return 0; + + if (image_changed) + image_changed = 0; + + return 1; +} + +static int image_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdrom) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(void) +{ + if (!cdrom) + return 0; + + if (strlen(image_path) == 0) + return 0; + + if (old_cdrom_drive != cdrom_drive) + { + old_cdrom_drive = cdrom_drive; + return 1; + } + + if (image_changed) + { + image_changed = 0; + return 1; + } + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t *b, int msf) +{ + if (!cdrom) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = image_cd_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdrom->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (image_cd_state == CD_PLAYING) + ret = 0x11; + else if (image_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(void) +{ +} + +static void image_load(void) +{ +} + +static int image_readsector(uint8_t *b, int sector) +{ + if (!cdrom) return -1; + return !cdrom->ReadSector(b, false, sector); +} + +static void image_readsector_raw(uint8_t *b, int sector) +{ + if (!cdrom) return; + cdrom->ReadSector(b, true, sector); +} + +static int image_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdrom) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdrom->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++) + { + cdrom->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++) { + cdrom->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(unsigned char *b, int msf, int maxlen) +{ + if (!cdrom) return 0; + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + cdrom->GetAudioTrackInfo(1, number, tmsf, attr); + +// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",0, 0, 0,1,1,attr,0,number); + + 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; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int image_readtoc_raw(unsigned char *b, int maxlen) +{ + if (!cdrom) return 0; + + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->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) + { + pclog("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdrom->GetAudioTrackInfo(track, number, tmsf, attr); + +// 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++] = 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 uint32_t image_size() +{ + return cdrom_capacity; +} + +static int image_status() +{ + if (!cdrom) return CD_STATUS_EMPTY; + if (cdrom->HasAudioTracks()) + { + switch(image_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() +{ +} + +void image_close(void) +{ + image_cd_state = CD_STOPPED; + if (cdrom) + { + delete cdrom; + cdrom = NULL; + } +// memset(image_path, 0, 1024); +} + +int image_open(char *fn) +{ + if (strcmp(fn, image_path) != 0) + image_changed = 1; + + /* Make sure image_changed stays when changing from an image to another image. */ + if (cdrom_drive != CDROM_IMAGE) + image_changed = 1; + /* strcpy fails on OSX if both parameters are pointing to the same address */ + if (image_path != fn) + strcpy(image_path, fn); + + cdrom = new CDROM_Interface_Image(); + if (!cdrom->SetDevice(fn, false)) + { + image_close(); + return 1; + } + image_cd_state = CD_STOPPED; + image_cd_pos = 0; + cd_buflen = 0; + cdrom_capacity = image_get_last_block(0, 0, 4096, 0) + 1; + atapi = &image_atapi; + return 0; +} + +static void image_exit(void) +{ +} + +ATAPI image_atapi= +{ + image_ready, + image_medium_changed, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + image_readsector, + image_readsector_raw, + image_playaudio, + image_seek, + 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 0000000..c0a7e44 --- /dev/null +++ b/src/cdrom-image.h @@ -0,0 +1,23 @@ +#ifndef CDROM_ISO_H +#define CDROM_ISO_H + +#include + +extern char image_path[1024]; + +#ifdef __cplusplus +extern "C" { +#endif + +int image_open(char *fn); +void image_reset(); +void image_close(); + +void image_audio_callback(int16_t *output, int len); +void image_audio_stop(); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_ISO_H */ diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index ef10004..f1b133c 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -58,10 +58,7 @@ void ioctl_audio_callback(int16_t *output, int len) // 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) - { - memset(output, 0, len * 2); return; - } while (cd_buflen < len) { if (ioctl_cd_pos < ioctl_cd_end) diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c deleted file mode 100644 index 220b073..0000000 --- a/src/cdrom-iso.c +++ /dev/null @@ -1,356 +0,0 @@ -/*ISO CD-ROM support*/ - -#include "ibm.h" -#include "ide.h" -#include "cdrom-iso.h" -#include - -static ATAPI iso_atapi; - -static 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 = NULL; -static int iso_changed = 0; - -void iso_audio_callback(int16_t *output, int len) -{ - memset(output, 0, len * 2); - return; -} - -void iso_audio_stop() -{ - pclog("iso_audio_stop stub\n"); -} - -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"); - return; -} - -static int iso_ready(void) -{ - if (strlen(iso_path) == 0) - return 0; - - if (old_cdrom_drive != cdrom_drive) - return 1; - - iso_changed = 0; - 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) -{ - iso_changed = 0; - return 0; -} - -static uint8_t iso_getcurrentsubchannel(uint8_t *b, int msf) -{ - pclog("iso_getcurrentsubchannel stub\n"); - return 0; -} - -static void iso_eject(void) -{ - pclog("iso_eject stub\n"); -} - -static void iso_load(void) -{ - pclog("iso_load stub\n"); -} - -static int iso_readsector(uint8_t *b, int sector) -{ - if (!cdrom_drive) - return -1; - fseek(iso_image,sector*2048,SEEK_SET); - fread(b,2048,1,iso_image); - 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 void iso_readsector_raw(uint8_t *b, int sector) -{ - if (!cdrom_drive) return; - fseek(iso_image, sector*2048, SEEK_SET); - fread(b+16, 2048, 1, 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); -} - -static int iso_readtoc(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 */ - last_block = image_size >> 11; - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, last_block); - q += 3; - } - else - { - *q++ = last_block >> 24; - *q++ = last_block >> 16; - *q++ = last_block >> 8; - *q++ = last_block; - } - len = q - buf; - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static int iso_readtoc_session(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; - - return 12; -} - -static int iso_readtoc_raw(unsigned char *buf, 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 */ - last_block = image_size >> 11; - /* this is raw, must be msf */ - *q++ = 0; /* reserved */ - lba_to_msf(q, last_block); - q += 3; - - *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 */ - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - - len = q - buf; - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static uint32_t iso_size() -{ - unsigned char b[4096]; - - atapi->readtoc(b, 0, 0, 4096, 0); - - return last_block; -} - -static int iso_status() -{ - if (!(iso_ready()) && (cdrom_drive != 200)) - return CD_STATUS_EMPTY; - - return CD_STATUS_DATA_ONLY; -} - -void iso_reset() -{ -} - -int iso_open(char *fn) -{ - struct stat st; - - if (iso_image) - fclose(iso_image); - - if (strcmp(fn, iso_path) != 0) - iso_changed = 1; - - /* Make sure iso_changed stays when changing from ISO to another ISO. */ - if (cdrom_drive != CDROM_ISO) - iso_changed = 1; - strcpy(iso_path, fn); - - iso_image = fopen(iso_path, "rb"); - atapi = &iso_atapi; - - stat(iso_path, &st); - image_size = st.st_size; - - return 0; -} - -void iso_close(void) -{ - if (iso_image) - { - fclose(iso_image); - iso_image = NULL; - } - memset(iso_path, 0, 1024); -} - -static void iso_exit(void) -{ - iso_inited = 0; -} - -static int iso_is_track_audio(uint32_t pos, int ismsf) -{ - return 0; -} - -static ATAPI iso_atapi = -{ - iso_ready, - iso_medium_changed, - iso_readtoc, - iso_readtoc_session, - iso_readtoc_raw, - iso_getcurrentsubchannel, - iso_readsector, - iso_readsector_raw, - iso_playaudio, - iso_seek, - iso_load, - iso_eject, - iso_pause, - iso_resume, - iso_size, - iso_status, - iso_is_track_audio, - iso_stop, - iso_exit -}; diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h deleted file mode 100644 index d4efd06..0000000 --- a/src/cdrom-iso.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CDROM_ISO_H -#define CDROM_ISO_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern char iso_path[1024]; - -extern int iso_open(char *fn); -extern void iso_reset(); -extern void iso_close(); - -#endif /* ! CDROM_ISO_H */ diff --git a/src/dosbox/cdrom.h b/src/dosbox/cdrom.h new file mode 100644 index 0000000..603deb7 --- /dev/null +++ b/src/dosbox/cdrom.h @@ -0,0 +1,172 @@ +/* + * 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 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/dosbox/cdrom_image.cpp b/src/dosbox/cdrom_image.cpp new file mode 100644 index 0000000..096777c --- /dev/null +++ b/src/dosbox/cdrom_image.cpp @@ -0,0 +1,546 @@ +/* + * 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.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::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {0, 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; + 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, 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/ibm.h b/src/ibm.h index 5120aef..82bb8bd 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -167,7 +167,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) diff --git a/src/ide.c b/src/ide.c index 766a683..a4e3fda 100644 --- a/src/ide.c +++ b/src/ide.c @@ -2415,7 +2415,7 @@ static void atapicommand(int ide_board) } - if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cd_status <= CD_STATUS_DATA_ONLY) || + if ((cdrom_drive < 1) || (cd_status <= CD_STATUS_DATA_ONLY) || !atapi->is_track_audio(pos, (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) { ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ diff --git a/src/ide.h b/src/ide.h index ae1ab63..4c4e0b6 100644 --- a/src/ide.h +++ b/src/ide.h @@ -56,6 +56,6 @@ extern int cdrom_channel; uint32_t atapi_get_cd_channel(int channel); uint32_t atapi_get_cd_volume(int channel); -#define CDROM_ISO 200 +#define CDROM_IMAGE 200 #endif //__IDE__ diff --git a/src/pc.c b/src/pc.c index 3438590..1420253 100644 --- a/src/pc.c +++ b/src/pc.c @@ -6,7 +6,7 @@ #include "ali1429.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "disc.h" #include "disc_img.h" #include "mem.h" @@ -281,13 +281,13 @@ void initpc(int argc, char *argv[]) else #endif { - if (cdrom_drive == CDROM_ISO) + if (cdrom_drive == CDROM_IMAGE) { - FILE *ff = fopen(iso_path, "rb"); + FILE *ff = fopen(image_path, "rb"); if (ff) { fclose(ff); - iso_open(iso_path); + image_open(image_path); } else { @@ -318,9 +318,9 @@ void initpc(int argc, char *argv[]) else #endif { - if (cdrom_drive == CDROM_ISO) + if (cdrom_drive == CDROM_IMAGE) { - iso_reset(); + image_reset(); } else { @@ -398,15 +398,31 @@ void resetpchard() // output=3; + image_close(); #if __unix if (cdrom_drive == -1) cdrom_null_reset(); else #endif { - if (cdrom_drive == CDROM_ISO) + if (cdrom_drive == CDROM_IMAGE) { - iso_reset(); + FILE *ff = fopen(image_path, "rb"); + if (ff) + { + fclose(ff); + image_open(image_path); + } + else + { +#if __unix + cdrom_drive = -1; + cdrom_null_open(cdrom_drive); +#else + cdrom_drive = 0; + ioctl_set_drive(cdrom_drive); +#endif + } } else { @@ -655,8 +671,8 @@ void loadconfig(char *fn) cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2); p = (char *)config_get_string(CFG_MACHINE, NULL, "cdrom_path", ""); - if (p) strcpy(iso_path, p); - else strcpy(iso_path, ""); + if (p) strcpy(image_path, p); + else strcpy(image_path, ""); hdc[0].spt = config_get_int(CFG_MACHINE, NULL, "hdc_sectors", 0); hdc[0].hpc = config_get_int(CFG_MACHINE, NULL, "hdc_heads", 0); @@ -764,7 +780,7 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "cdrom_drive", cdrom_drive); config_set_int(CFG_MACHINE, NULL, "cdrom_enabled", cdrom_enabled); config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel); - config_set_string(CFG_MACHINE, NULL, "cdrom_path", iso_path); + config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path); config_set_int(CFG_MACHINE, NULL, "hdc_sectors", hdc[0].spt); config_set_int(CFG_MACHINE, NULL, "hdc_heads", hdc[0].hpc); diff --git a/src/pc.rc b/src/pc.rc index 0c3ab71..2f1900d 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -31,7 +31,7 @@ BEGIN BEGIN MENUITEM "&Disabled", IDM_CDROM_DISABLED MENUITEM "&Empty",IDM_CDROM_EMPTY - MENUITEM "&ISO...",IDM_CDROM_ISO + MENUITEM "&Image...",IDM_CDROM_IMAGE END POPUP "&Video" BEGIN diff --git a/src/resources.h b/src/resources.h index 932eda4..af0bac4 100644 --- a/src/resources.h +++ b/src/resources.h @@ -24,7 +24,7 @@ #define IDM_CDROM_EMPTY 40100 #define IDM_CDROM_REAL 40100 #define IDM_CDROM_DISABLED 40200 -#define IDM_CDROM_ISO 40201 +#define IDM_CDROM_IMAGE 40201 #define IDC_COMBO1 1000 #define IDC_COMBOVID 1001 diff --git a/src/sound.c b/src/sound.c index a092bc2..26a93a2 100644 --- a/src/sound.c +++ b/src/sound.c @@ -4,6 +4,7 @@ #include "device.h" #include "cdrom-ioctl.h" +#include "cdrom-image.h" #include "ide.h" #include "filters.h" @@ -134,7 +135,9 @@ static void sound_cd_thread(void *param) int c; thread_wait_event(sound_cd_event, -1); + memset(cd_buffer, 0, CD_BUFLEN*2 * 2); ioctl_audio_callback(cd_buffer, CD_BUFLEN*2); + image_audio_callback(cd_buffer, CD_BUFLEN*2); if (soundon) { int32_t atapi_vol_l = atapi_get_cd_volume(0); @@ -259,4 +262,5 @@ void sound_reset() sound_set_cd_volume(65535, 65535); ioctl_audio_stop(); + image_audio_stop(); } diff --git a/src/win.c b/src/win.c index f88b5ee..c9d2093 100644 --- a/src/win.c +++ b/src/win.c @@ -15,7 +15,7 @@ #include #include "ibm.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "config.h" #include "cpu.h" #include "device.h" @@ -632,8 +632,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_CDROM_DISABLED, MF_CHECKED); else { - if (cdrom_drive == CDROM_ISO) - CheckMenuItem(menu, IDM_CDROM_ISO, MF_CHECKED); + if (cdrom_drive == CDROM_IMAGE) + CheckMenuItem(menu, IDM_CDROM_IMAGE, MF_CHECKED); else CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); } @@ -885,8 +885,8 @@ void atapi_close(void) { switch (cdrom_drive) { - case CDROM_ISO: - iso_close(); + case CDROM_IMAGE: + image_close(); break; default: ioctl_close(); @@ -898,7 +898,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { HMENU hmenu; RECT rect; - char temp_iso_path[1024]; + char temp_image_path[1024]; int new_cdrom_drive; // pclog("Message %i %08X\n",message,message); switch (message) @@ -1067,7 +1067,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM ioctl_set_drive(0); CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_CHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); old_cdrom_drive = cdrom_drive; cdrom_drive=0; CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_UNCHECKED); @@ -1103,7 +1103,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); old_cdrom_drive = cdrom_drive; cdrom_drive=0; CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED); @@ -1119,8 +1119,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } break; - case IDM_CDROM_ISO: - if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",iso_path)) + case IDM_CDROM_IMAGE: + if (!getfile(hwnd,"CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0",image_path)) { if (!cdrom_enabled) { @@ -1128,15 +1128,15 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; } old_cdrom_drive = cdrom_drive; - strcpy(temp_iso_path, openfilestring); - if ((strcmp(iso_path, temp_iso_path) == 0) && (cdrom_drive == CDROM_ISO) && cdrom_enabled) + strcpy(temp_image_path, openfilestring); + if ((strcmp(image_path, temp_image_path) == 0) && (cdrom_drive == CDROM_IMAGE) && cdrom_enabled) { /* Switching from ISO to the same ISO. Do nothing. */ break; } atapi->exit(); atapi_close(); - iso_open(temp_iso_path); + image_open(temp_image_path); if (cdrom_enabled) { /* Signal disc change to the emulated machine. */ @@ -1144,9 +1144,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } 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 = CDROM_ISO; - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); + cdrom_drive = CDROM_IMAGE; + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_CHECKED); saveconfig(NULL); if (!cdrom_enabled) { @@ -1185,7 +1185,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); cdrom_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); saveconfig(NULL); From 7fe91626d6592ed4e606e85c396ba76c512f34c4 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Mon, 29 May 2017 15:38:48 +0100 Subject: [PATCH 0019/1050] Added new GUI based on wxWidgets. Patch from bit. --- src/Makefile.am | 4 +- src/Makefile.in | 98 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 51 + src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 51 + src/Makefile.mingw-wx-sdl2 | 46 + src/Makefile.osx64-wx-sdl2 | 51 + src/cdrom-image.cc | 9 +- src/cdrom-ioctl-osx.c | 170 ++ src/fdc.c | 12 +- src/hdd_esdi.c | 4 +- src/ibm.h | 6 + src/icons/cd.png | Bin 0 -> 673 bytes src/icons/disk.png | Bin 0 -> 620 bytes src/icons/drive.png | Bin 0 -> 346 bytes src/icons/pause.svg | 43 + src/icons/pause24.png | Bin 0 -> 635 bytes src/icons/play-button.svg | 41 + src/icons/play24.png | Bin 0 -> 758 bytes src/icons/refresh.svg | 50 + src/icons/refresh24.png | Bin 0 -> 1144 bytes src/icons/stop.svg | 39 + src/icons/stop24.png | Bin 0 -> 622 bytes src/ide.c | 27 +- src/mfm_at.c | 8 +- src/mfm_xebec.c | 8 +- src/pc.c | 30 + src/pc.xrc | 1617 ++++++++++++++++++ src/vid_voodoo.c | 4 +- src/video.h | 2 +- src/wx-app.cc | 224 +++ src/wx-app.h | 134 ++ src/wx-common.c | 34 + src/wx-common.h | 26 + src/wx-config.c | 863 ++++++++++ src/wx-config_sel.c | 249 +++ src/wx-deviceconfig.cc | 268 +++ src/wx-deviceconfig.h | 10 + src/wx-dialogbox.cc | 45 + src/wx-dialogbox.h | 21 + src/wx-display.h | 36 + src/wx-main.cc | 15 + src/wx-resources.cpp | 3010 ++++++++++++++++++++++++++++++++++ src/wx-sdl2-display.c | 755 +++++++++ src/wx-sdl2-hdconf.c | 956 +++++++++++ src/wx-sdl2-joystick.c | 15 + src/wx-sdl2-keyboard.c | 23 + src/wx-sdl2-midi.c | 14 + src/wx-sdl2-mouse.c | 59 + src/wx-sdl2-status.c | 162 ++ src/wx-sdl2-video.c | 344 ++++ src/wx-sdl2-video.h | 38 + src/wx-sdl2.c | 889 ++++++++++ src/wx-sdl2.h | 16 + src/wx-status.cc | 351 ++++ src/wx-status.h | 70 + src/wx-thread.c | 169 ++ src/wx-utils.cc | 442 +++++ src/wx-utils.h | 112 ++ 60 files changed, 11647 insertions(+), 78 deletions(-) create mode 100644 src/Makefile.linux32-wx-sdl2 create mode 100644 src/Makefile.linux64-wx-sdl2 create mode 100644 src/Makefile.mingw-wx-sdl2 create mode 100644 src/Makefile.osx64-wx-sdl2 create mode 100644 src/cdrom-ioctl-osx.c create mode 100644 src/icons/cd.png create mode 100644 src/icons/disk.png create mode 100644 src/icons/drive.png create mode 100644 src/icons/pause.svg create mode 100644 src/icons/pause24.png create mode 100644 src/icons/play-button.svg create mode 100644 src/icons/play24.png create mode 100644 src/icons/refresh.svg create mode 100644 src/icons/refresh24.png create mode 100644 src/icons/stop.svg create mode 100644 src/icons/stop24.png create mode 100644 src/pc.xrc create mode 100644 src/wx-app.cc create mode 100644 src/wx-app.h create mode 100644 src/wx-common.c create mode 100644 src/wx-common.h create mode 100644 src/wx-config.c create mode 100644 src/wx-config_sel.c create mode 100644 src/wx-deviceconfig.cc create mode 100644 src/wx-deviceconfig.h create mode 100644 src/wx-dialogbox.cc create mode 100644 src/wx-dialogbox.h create mode 100644 src/wx-display.h create mode 100644 src/wx-main.cc create mode 100644 src/wx-resources.cpp create mode 100644 src/wx-sdl2-display.c create mode 100644 src/wx-sdl2-hdconf.c create mode 100644 src/wx-sdl2-joystick.c create mode 100644 src/wx-sdl2-keyboard.c create mode 100644 src/wx-sdl2-midi.c create mode 100644 src/wx-sdl2-mouse.c create mode 100644 src/wx-sdl2-status.c create mode 100644 src/wx-sdl2-video.c create mode 100644 src/wx-sdl2-video.h create mode 100644 src/wx-sdl2.c create mode 100644 src/wx-sdl2.h create mode 100644 src/wx-status.cc create mode 100644 src/wx-status.h create mode 100644 src/wx-thread.c create mode 100644 src/wx-utils.cc create mode 100644 src/wx-utils.h diff --git a/src/Makefile.am b/src/Makefile.am index babad39..7c2a47e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,13 +10,13 @@ CLEANFILES = $(noinst_SCRIPTS) amrefresh: -pcem_CFLAGS = $(allegro_CFLAGS) +pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \ allegro-gui-config-sel.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-image.c cdrom-null.c \ +allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 dells200.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 \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 8066b6a..cf50055 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -112,13 +112,13 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 \ + amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 hdd.c hdd_esdi.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ + dells200.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 hdd.c \ + hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 \ @@ -143,8 +143,8 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ - dosbox/vid_cga_comp.c resid-fp/convolve.cc \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/vid_cga_comp.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_PS_.cc \ @@ -167,24 +167,24 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(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-iso.$(OBJEXT) \ + pcem-cdrom-ioctl-linux.$(OBJEXT) cdrom-image.$(OBJEXT) \ pcem-cdrom-null.$(OBJEXT) pcem-codegen.$(OBJEXT) \ pcem-codegen_ops.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ pcem-codegen_timing_winchip.$(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-disc_sector.$(OBJEXT) pcem-dma.$(OBJEXT) \ - pcem-fdc.$(OBJEXT) pcem-fdc37c665.$(OBJEXT) pcem-fdd.$(OBJEXT) \ - pcem-fdi2raw.$(OBJEXT) pcem-gameport.$(OBJEXT) \ - pcem-hdd.$(OBJEXT) pcem-hdd_esdi.$(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-joystick_ch_flightstick_pro.$(OBJEXT) \ + pcem-dells200.$(OBJEXT) pcem-device.$(OBJEXT) \ + pcem-disc.$(OBJEXT) pcem-disc_fdi.$(OBJEXT) \ + pcem-disc_img.$(OBJEXT) pcem-disc_sector.$(OBJEXT) \ + pcem-dma.$(OBJEXT) pcem-fdc.$(OBJEXT) pcem-fdc37c665.$(OBJEXT) \ + pcem-fdd.$(OBJEXT) pcem-fdi2raw.$(OBJEXT) \ + pcem-gameport.$(OBJEXT) pcem-hdd.$(OBJEXT) \ + pcem-hdd_esdi.$(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-joystick_ch_flightstick_pro.$(OBJEXT) \ pcem-joystick_standard.$(OBJEXT) \ pcem-joystick_sw_pad.$(OBJEXT) pcem-joystick_tm_fcs.$(OBJEXT) \ pcem-keyboard.$(OBJEXT) pcem-keyboard_amstrad.$(OBJEXT) \ @@ -238,7 +238,7 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-video.$(OBJEXT) pcem-wd76c10.$(OBJEXT) \ pcem-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) sound_dbopl.$(OBJEXT) \ - sound_resid.$(OBJEXT) dbopl.$(OBJEXT) \ + sound_resid.$(OBJEXT) cdrom_image.$(OBJEXT) dbopl.$(OBJEXT) \ pcem-vid_cga_comp.$(OBJEXT) convolve.$(OBJEXT) \ convolve-sse.$(OBJEXT) envelope.$(OBJEXT) extfilt.$(OBJEXT) \ filter.$(OBJEXT) pot.$(OBJEXT) sid.$(OBJEXT) voice.$(OBJEXT) \ @@ -426,20 +426,20 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = ../pcem CLEANFILES = $(noinst_SCRIPTS) -pcem_CFLAGS = $(allegro_CFLAGS) $(am__append_2) +pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO $(am__append_2) pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acer386sx.c ali1429.c allegro-gui.c allegro-gui-config-sel.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 \ + amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 hdd.c hdd_esdi.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ + dells200.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 hdd.c \ + hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 \ @@ -464,8 +464,8 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ - dosbox/vid_cga_comp.c resid-fp/convolve.cc \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/vid_cga_comp.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_PS_.cc \ @@ -560,6 +560,8 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom-image.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_image.Po@am__quote@ @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@ @@ -585,7 +587,6 @@ distclean-compile: @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-iso.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@ @@ -599,6 +600,7 @@ distclean-compile: @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-dells200.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@ @@ -1028,20 +1030,6 @@ pcem-cdrom-ioctl-linux.obj: cdrom-ioctl-linux.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-iso.o: cdrom-iso.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-iso.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-iso.Tpo -c -o pcem-cdrom-iso.o `test -f 'cdrom-iso.c' || echo '$(srcdir)/'`cdrom-iso.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-iso.Tpo $(DEPDIR)/pcem-cdrom-iso.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-iso.c' object='pcem-cdrom-iso.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-iso.o `test -f 'cdrom-iso.c' || echo '$(srcdir)/'`cdrom-iso.c - -pcem-cdrom-iso.obj: cdrom-iso.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-iso.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-iso.Tpo -c -o pcem-cdrom-iso.obj `if test -f 'cdrom-iso.c'; then $(CYGPATH_W) 'cdrom-iso.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-iso.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-iso.Tpo $(DEPDIR)/pcem-cdrom-iso.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-iso.c' object='pcem-cdrom-iso.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-iso.obj `if test -f 'cdrom-iso.c'; then $(CYGPATH_W) 'cdrom-iso.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-iso.c'; fi` - pcem-cdrom-null.o: cdrom-null.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-null.Tpo $(DEPDIR)/pcem-cdrom-null.Po @@ -1196,6 +1184,20 @@ pcem-dac.obj: dac.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-dells200.o: dells200.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.o -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dells200.c' object='pcem-dells200.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c + +pcem-dells200.obj: dells200.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.obj -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.obj `if test -f 'dells200.c'; then $(CYGPATH_W) 'dells200.c'; else $(CYGPATH_W) '$(srcdir)/dells200.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dells200.c' object='pcem-dells200.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dells200.obj `if test -f 'dells200.c'; then $(CYGPATH_W) 'dells200.c'; else $(CYGPATH_W) '$(srcdir)/dells200.c'; fi` + pcem-device.o: device.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-device.Tpo $(DEPDIR)/pcem-device.Po @@ -3114,6 +3116,20 @@ pcem-codegen_x86-64.obj: codegen_x86-64.c @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +cdrom_image.o: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdrom_image.o -MD -MP -MF $(DEPDIR)/cdrom_image.Tpo -c -o cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdrom_image.Tpo $(DEPDIR)/cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='cdrom_image.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp + +cdrom_image.obj: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdrom_image.obj -MD -MP -MF $(DEPDIR)/cdrom_image.Tpo -c -o cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdrom_image.Tpo $(DEPDIR)/cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='cdrom_image.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` + dbopl.o: dosbox/dbopl.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/dbopl.Tpo $(DEPDIR)/dbopl.Po diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 69c1330..2b47115 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -1,7 +1,7 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc -CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 +CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m32 LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 new file mode 100644 index 0000000..d95f9f9 --- /dev/null +++ b/src/Makefile.linux32-wx-sdl2 @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.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_voodoo.o vid_wy700.o video.o wd76c10.o \ +x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 + + +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) + +PCem-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2" $(LIBS) + +all : PCem-wx-SDL2 + +clean : + rm *.o + rm PCem-wx-SDL2 + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 70ea9d7..1dc72e1 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -1,7 +1,7 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc -CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 +CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 new file mode 100644 index 0000000..014c895 --- /dev/null +++ b/src/Makefile.linux64-wx-sdl2 @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.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_voodoo.o vid_wy700.o video.o wd76c10.o \ +x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 + + +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) + +PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) + +all : PCem64-wx-SDL2 + +clean : + rm *.o + rm PCem64-wx-SDL2 + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 new file mode 100644 index 0000000..bebef57 --- /dev/null +++ b/src/Makefile.mingw-wx-sdl2 @@ -0,0 +1,46 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + scat.o serial.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o \ + wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ + wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 + + +LIBS = -mwindows -lopenal32 -lstdc++ -lwxbase31u -lwxmsw31u_core -lwxmsw31u_xrc -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static + +PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2.exe" $(LIBS) + +all : PCem-wx-SDL2.exe + +clean : + del *.o + del PCem-wx-SDL2.exe + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 new file mode 100644 index 0000000..813ec2a --- /dev/null +++ b/src/Makefile.osx64-wx-sdl2 @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WXRC = wxrc +CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.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.c compaq.o config.o cpu.o \ +dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.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_voodoo.o vid_wy700.o video.o wd76c10.o \ +x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.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 + + +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -L/usr/local/opt/openal-soft/lib + +PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) + +all : PCem64-wx-SDL2 + +clean : + rm *.o + rm PCem64-wx-SDL2 + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 464adf3..3ce4d46 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -4,13 +4,20 @@ extern "C" { -#include "ibm.h" +//#include "ibm.h" #include "ide.h" int cdrom_drive; int old_cdrom_drive; +void pclog(const char *format, ...); } +#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 + char image_path[1024]; static int image_changed = 0; diff --git a/src/cdrom-ioctl-osx.c b/src/cdrom-ioctl-osx.c new file mode 100644 index 0000000..5243ebd --- /dev/null +++ b/src/cdrom-ioctl-osx.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include "ibm.h" +#include "ide.h" +#include "cdrom-ioctl.h" + +static ATAPI ioctl_atapi; + +void ioctl_audio_callback(int16_t *output, int len) +{ + memset(output, 0, len * 2); +} + +void ioctl_audio_stop() +{ +} + +static int get_track_nr(uint32_t pos) +{ + return 0; +} + +static int is_track_audio(uint32_t pos) +{ + return 0; +} + +static int ioctl_is_track_audio(uint32_t pos, int ismsf) +{ + return 0; +} + +static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) +{ +} + +static void ioctl_pause(void) +{ +} + +static void ioctl_resume(void) +{ +} + +static void ioctl_stop(void) +{ +} + +static void ioctl_seek(uint32_t pos) +{ +} + +static int read_toc(int fd, struct cdrom_tocentry *btoc) +{ + return 0; +} + +static int ioctl_ready(void) +{ + return 0; +} + +static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + return 0; +} + +static int ioctl_medium_changed(void) +{ + return 0; +} + +static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) +{ + return 0x13; +} + +static void ioctl_eject(void) +{ +} + +static void ioctl_load(void) +{ +} + +static int ioctl_readsector(uint8_t *b, int sector) +{ + return 0; +} + +static int lba_to_msf(int lba) +{ + return 0; +} + +static void ioctl_readsector_raw(uint8_t *b, int sector) +{ +} + +static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + return 0; +} + +static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) +{ + return 0; +} + +static int ioctl_readtoc_raw(unsigned char *b, int maxlen) +{ + return 0; +} + +static uint32_t ioctl_size() +{ + return 0; +} + +static int ioctl_status() +{ + return CD_STATUS_EMPTY; +} +void ioctl_reset() +{ +} + +void ioctl_set_drive(char d) +{ + atapi = &ioctl_atapi; +} + +int ioctl_open(char d) +{ + atapi = &ioctl_atapi; + return 0; +} + +void ioctl_close(void) +{ +} + +static void ioctl_exit(void) +{ + +} + +static ATAPI ioctl_atapi= +{ + ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + ioctl_readsector, + 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/fdc.c b/src/fdc.c index 3714324..948df5b 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -575,7 +575,7 @@ bad_command: // pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]); disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; @@ -601,7 +601,7 @@ bad_command: disc_writesector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.pos = 0; if (fdc.pcjr) fdc.stat = 0xb0; @@ -621,7 +621,7 @@ bad_command: disc_readsector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; @@ -815,7 +815,7 @@ void fdc_callback() return; case 2: /*Read track*/ - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.eot[fdc.drive]--; // pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); if (!fdc.eot[fdc.drive] || fdc.tc) @@ -861,7 +861,7 @@ void fdc_callback() case 5: /*Write data*/ if (!fdc.in_seek_mt) { - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.sector++; if (fdc.sector > fdc.params[5]) { @@ -911,7 +911,7 @@ void fdc_callback() // rpclog("Read data %i\n", fdc.tc); if (!fdc.in_seek_mt) { - readflash = 1; + readflash_set(READFLASH_FDC, fdc.drive); fdc.sector++; if (fdc.sector > fdc.params[5]) { diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index db708ec..56c49c3 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -445,7 +445,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); - readflash = 1; + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); } // pclog("Read sector %i %i %08x\n", esdi->sector_pos, esdi->data_pos, esdi->rba*512); while (esdi->data_pos < 256) @@ -540,7 +540,7 @@ static void esdi_callback(void *p) fwrite(esdi->data, 512, 1, drive->hdfile); esdi->rba++; esdi->sector_pos++; - readflash = 1; + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); esdi->data_pos = 0; } diff --git a/src/ibm.h b/src/ibm.h index 82bb8bd..e2c5b64 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -3,6 +3,12 @@ #include #define printf pclog +#define READFLASH_FDC 0 +#define READFLASH_HDC 4 +#define readflash_set(offset, drive) readflash |= 1<<(offset+drive) +#define readflash_clear(offset, drive) readflash &= ~(1<<(offset+drive)) +#define readflash_get(offset, drive) ((readflash&(1<<(offset+drive))) != 0) + /*Memory*/ uint8_t *ram; diff --git a/src/icons/cd.png b/src/icons/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..ef4322357cbc34e0b5eeed34f9fdf553a1de2ee7 GIT binary patch literal 673 zcmV;S0$%-zP)fk+XBT$+GFLor|=G~7Z=&Bd_^zJLLP z{dbOmhNM(Q`mp7h`OloWYysF>=iU40Tf#?V356IC6~fPKul?5pw+W80zw#nVEgemD zincj})E^?AZGqXAKHDz@mch}3iwfqB3rPo#(gwa141DiTF(xO6U^eE%d{-hX0gf3o z8{W?(@4ZV6pRS)EXbxQZMi1!D!oC#YJOO&yAsn%9V=twmsxF*P_%ZxvD(XXc8T9DS zr0103x=g@fvEJ!1y5C7b$Hz+ryB7+I5>V>_sj5lWnV>%bWD?LRmBAb^h}fbg923Y3 zqK41OM-q_X|0W}n)p3}pGlwoCoNU0Ppf+VweFB8`9D=Abd!7lXx6+7Cma$90A4ue; zVKQTfc(bHa=}i!!qJ}b>M^UnvkNQWze=dVN?ZJ22Mf(14f#NRkt=PP(cyuKepkb#y3Gz>xmDvuMC zIuoRtGlX&@?9*%nGA0rvwq8W9jW)GLrXJl50KN-ci9ozQ$MNkH;k<IV|^+8goU4jB6C^%Mg5h>3Q7RCr>7r_DEKw7k44$|vUmJAm;${=2wBT`(Pek9N? z+*$Z3+nYyu(=ufrbdbTWW%|!LE6aD^rgi=em@XcV9q^{200000NkvXX Hu0mjf|3D;c literal 0 HcmV?d00001 diff --git a/src/icons/disk.png b/src/icons/disk.png new file mode 100644 index 0000000000000000000000000000000000000000..99d532e8b1750115952f97302a92d713c0486f97 GIT binary patch literal 620 zcmV-y0+aoTP)~H+MJzd|s z^YP1Hc07G_>)Lgir!F1{Qn4GcTg%?koHo<=1qRN{}nPDolOeI^o4N5I>! zU$N=L=sg~ zDx#dOA*B0N~cqPsWI(^rbbkh)DS0_H_UN0C4l_kvWIm2#Kyy6%BCh z(yIUf003&1xdx>t$*eR2ZvXxT0001Z_R$y3Iju92q*wg58};}zm(OaAH=p|y0002M zh5O5#fxp|~jc?yi@+7$`d4Q6Hl%z;WiWG??NXR{Hx%)pMd~SE0000OQI literal 0 HcmV?d00001 diff --git a/src/icons/drive.png b/src/icons/drive.png new file mode 100644 index 0000000000000000000000000000000000000000..37b7c9b27d39acaaecf06951b024ac08afbfd4d2 GIT binary patch literal 346 zcmV-g0j2(lP)`6pHR4C7- zkv&QTK@f$%UVGNSAB4p~7X&kJu`rW(3s2w)1kd9QoMeZ&fx$)tn+OJimk zjCT$JD?{UrQ?3~v=-g&C?-zWP;E3TkpyGrhTDFaQSzpwKU?tq9Uh&CO=Y?-R7%>t` z!bl_(!*h(_r3OLS;FuM!k+?!xBDEihL=?r53TBrP2>202N!*Y~*dL6MvS5Ku!P&n9 sT@vv>?encL=G!4ixo5^&>-PTUFAyGx1U4B=kpKVy07*qoM6N<$g0$g{=l}o! literal 0 HcmV?d00001 diff --git a/src/icons/pause.svg b/src/icons/pause.svg new file mode 100644 index 0000000..537fa7f --- /dev/null +++ b/src/icons/pause.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/pause24.png b/src/icons/pause24.png new file mode 100644 index 0000000000000000000000000000000000000000..7e2e38dd63b138abaa117818bab099b862405092 GIT binary patch literal 635 zcmV->0)+jEP)u)O4UuFX*)xxw2Q3#3~p<|L_;e<5u~_Pap9^6`Vm|!2zAqx zC{0q_`Vri9A%sFF(?;sTO7TzT&2`Zvn7_u*IWUWN-HvH@J= z|L`5S>#o*Ie+NycCCNuBQXGRE;1cjY*i1g`dxNI(Vt3Lp5CJz^HxU58=z3zq-EQUL zT)>>4ZvSUbd;pwDudO5c`31E#rYg0Wfv# zT|0L2`4!(jt@qgF80R_gzyyW46vDm!HJ0dHn{%gMM{HtHectzru4ho29ibG*fg_>K z7!_F}CWz>D1G*Sj0!0@LFhgt**AOov0}{lTATU5RHiMvQfSuUW9+nO!;jAj*?wKOdi5c-$iIJ2Gp9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/play24.png b/src/icons/play24.png new file mode 100644 index 0000000000000000000000000000000000000000..bf72ed1591202a6e9c8b41555a268dffc0f1528c GIT binary patch literal 758 zcmV#!;#7g22P~GCi%6pj*ZKNKNBptsQ9yl~MhhCjNjN@EOgfOtV)_&Vw@MXX?M=Z#B~#voUb6Z4e_ zKvrj6vaMz?#+^rQS6DK8kN77HfUV}b7yLr%9%}X-CNqBPs@jF6)d1paZ%9!q9Q1O_ z&AkUXv^^PDm6wyl+!^j;HXMp3i4zt#)nGa0QCJZp!pR*OJl|hRX<}Mre=nA0W0e_2 zi&sfN!oFdXTZeBK4RgW2vj95<5w{!u|5dPNP*{^Y~-cPhKzP&N22S~x&We?eeO{tcM$AP~PsKf7tM zoy_jMib(_TzUb7rsyPifYXEmq0^NBPlZysUZ_%08f?NgM|C$BLm7b!rEuJGYr=$M3 zpmi~{YZ`IS^%MkJJx3-$Z=t_gZ984jyFfUqmY}s_JDE%2p0A2|Wp&mi+gN4bmY|Zh o@Y$jeG|(0jx4FL{Fy_Vh3s&UrRLgmF$^ZZW07*qoM6N<$f)CJCK>z>% literal 0 HcmV?d00001 diff --git a/src/icons/refresh.svg b/src/icons/refresh.svg new file mode 100644 index 0000000..f3f25f1 --- /dev/null +++ b/src/icons/refresh.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/refresh24.png b/src/icons/refresh24.png new file mode 100644 index 0000000000000000000000000000000000000000..c5054b3ecfe3aab1296d4f35c3412dfa78afdb02 GIT binary patch literal 1144 zcmV-;1c&>HP)^L1O-V% zK~zY`m6m->)m0eBKj+-v6@-gQOkfv81Oi`5B+Qk$98flJOYM)gYq)Z*tu?c(t=gJy z+WM#Uvaqc`nyV?kOy?g8wlxB*HqjX(w!9K>r-0!L?_5Cc%kSwAytn(p1$zEF=Q+>! zd(QVf&v}kw1}m;Rm1Sz*7Nyt>WCNLxTs^=oL~1RDK6_=OqdOLcnr^bN{#1rV`S*kD z0xZmICQ6+#;lpbsj$5-56gM8PYFpqW3Sf0(b*3TO87j**doCa6uf3o#G zmdyD!zFSku8_jiePXyN_VUYvCo2t0(RF+tLuF!1xY5f+`;u5I2>*9d(G7{rf6Adfh z7nM<9OXlK0FYmNo2vgCg%xsH&=PR!R6``Kav0*yKhWXajiaA5t?9M49WnMh#@rf*% zpTw#KDLj{A=hwbF2xzUeOAAsS8F*>nE=RhY_(f*S%RbKpg$ox4#~V`YcuYU$qc{<% z(4g`n1Fc%4m6|p2k9D_kV{{-m?)N<8n~rOtHIS=8(jx;uTe+UMmOVKufhoelo0sv) zl#rjdH#6e%gf7W2B7-)h*eP4Q1iuLN_q%Cx56(!^?jGVumy-fpGQZsKiY~n3hU0Al z`GKrBy{;md<8AIicKq@4taqW6!cZEI>5p{X)B>)+Xiv_XAUHsQEg45jZ*8C(+K3z_ES~l}^ z*aOQG3sN{-^a3xYX5leS_B)#*2@YQ`sq9hzH5i{0ND6oZZ;U-Y5r8qD7uWbOUem-L zZzDZ^O1g)BKl_|bG&~4vY9q?Q+M{ls2it106D`nP%zDWrdgI(FHcs1j35-irJ zi~X(t4pp74+#VkZ?{LD_t7Y43q8m=bi9LdR9ocZKT2r)eF}aD0uqeg7$#GhS9?<8R zm@c8-Ybo1)C}ztnYB=$-LaIaMnxl=N%-61#RMv(iLgcEJQpY(lj9fvg0N)&dO^~C? z@Gp-9kNK+z*y_gWOasdnFgGJ=S?ITAs)#u6Rpz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/stop24.png b/src/icons/stop24.png new file mode 100644 index 0000000000000000000000000000000000000000..8792c936cb5aae1973e1f6d7f9ea3baed530fa70 GIT binary patch literal 622 zcmV-!0+IcRP)9)WocT>1=DKL3aY$+!owJ+!hI8&a^X8r>9D$uwF78;9L77p4 z1W4>)MO%Vts0KApY$aJ)Y7XL%e#PeX+_-1ti3sz6UcQg6>eRpu!c_}P90s^Dl==^)RmzG_NuS>w)iq!_8sdbjAJA_#8Dgt*7Kc=QMgKE&}#-rMkm0O0nSIqFXM)2 z5g4Eyp+MUJ^$0(5-JrS|8NEo&cw#Gn9|6C2!gy6DSy^f}()j`hv;X(+|K=TZIzx_% z_kDs!7GveLmIGh|ed=4e1&noH*x%X?&zIw1Pp!A`D-SNzieC`D{hzD~1er^eSHJ!d zIEjtoD}hHq@K59-4<{;x>cGhSoX)2MVYSz;VQmqkvlHvZ+Q7&Jh`Y;f=cJiZcn)~O zbPc+K^{2z+18)^w941``Wd>mqh;^4h>%gXCeK%HKYYpP~37k!{rb~+v)Bpeg07*qo IM6N<$f=pQ%$^ZZW literal 0 HcmV?d00001 diff --git a/src/ide.c b/src/ide.c index a4e3fda..7b9ad40 100644 --- a/src/ide.c +++ b/src/ide.c @@ -684,7 +684,7 @@ void ide_set_signature(IDE *ide) 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) ide->drive = 0; +// if (ide->type == IDE_HDD) ide->drive = 0; } void resetide(void) @@ -717,6 +717,7 @@ void resetide(void) #else for (d = 0; d < 4; d++) { + ide_drives[d].drive = d; ide_drives[d].packetstatus = 0xFF; if ((cdrom_channel == d) && cdrom_enabled) @@ -1378,7 +1379,7 @@ void callbackide(int ide_board) // if (addr) output=3; ide_irq_raise(ide); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1414,7 +1415,7 @@ void callbackide(int ide_board) } } #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1437,7 +1438,7 @@ void callbackide(int ide_board) if (ide->blockcount >= ide->blocksize) ide->blockcount = 0; #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1461,7 +1462,7 @@ void callbackide(int ide_board) else ide->atastat = READY_STAT | DSC_STAT; #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1497,7 +1498,7 @@ void callbackide(int ide_board) } } #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1525,7 +1526,7 @@ void callbackide(int ide_board) else ide->atastat = READY_STAT | DSC_STAT; #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1539,7 +1540,7 @@ void callbackide(int ide_board) // pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); ide_irq_raise(ide); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1558,7 +1559,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif return; @@ -1883,7 +1884,7 @@ static void atapicommand(int ide_board) #ifndef RPCEMU_IDE pclog("New ATAPI command %02X %i\n",idebufferb[0],ins); #endif -// readflash=1; +// readflash_set(READFLASH_HDD, ide->drive, 1); msf=idebufferb[1]&2; ide->cdlen=0; @@ -2092,7 +2093,7 @@ static void atapicommand(int ide_board) else atapi->readsector_raw(idebufferb,ide->cdpos); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif readcdmode = (rcdmode == 0xF8); ide->cdpos++; @@ -2157,7 +2158,7 @@ static void atapicommand(int ide_board) break; } #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif ide->cdpos++; ide->cdlen--; @@ -2690,7 +2691,7 @@ static void callreadcd(IDE *ide) else atapi->readsector((uint8_t *) ide->buffer, ide->cdpos); #ifndef RPCEMU_IDE - readflash=1; + readflash_set(READFLASH_HDC, ide->drive); #endif ide->cdpos++; ide->cdlen--; diff --git a/src/mfm_at.c b/src/mfm_at.c index f2099a1..81d0bd6 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -517,7 +517,7 @@ void mfm_callback(void *p) // 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; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_WRITE: @@ -541,7 +541,7 @@ void mfm_callback(void *p) } else mfm->status = STAT_READY | STAT_DSC; - readflash = 1; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_VERIFY: @@ -550,7 +550,7 @@ void mfm_callback(void *p) 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; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_FORMAT: @@ -570,7 +570,7 @@ void mfm_callback(void *p) } mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - readflash = 1; + readflash_set(READFLASH_HDC, mfm->drive_sel); break; case CMD_DIAGNOSE: diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index 7a65a31..bf583a9 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -391,7 +391,7 @@ static void xebec_callback(void *p) xebec_complete(xebec); - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); break; default: @@ -450,7 +450,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); } if (xebec->irq_dma_mask & DMA_ENA) xebec->callback = XEBEC_TIME; @@ -506,7 +506,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); xebec->state = STATE_SEND_DATA; @@ -592,7 +592,7 @@ static void xebec_callback(void *p) fwrite(xebec->sector_buf, 512, 1, drive->hdfile); } - readflash = 1; + readflash_set(READFLASH_HDC, xebec->drive_sel); xebec_next_sector(xebec); xebec->data_pos = 0; diff --git a/src/pc.c b/src/pc.c index 1420253..474489b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -586,6 +586,22 @@ void closepc() END_OF_MAIN();*/ +typedef struct config_callback_t +{ + void(*loadconfig)(); + void(*saveconfig)(); + void(*onloaded)(); +} config_callback_t; +config_callback_t config_callbacks[10]; +int num_config_callbacks = 0; + +void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()) +{ + config_callbacks[num_config_callbacks].loadconfig = loadconfig; + config_callbacks[num_config_callbacks].saveconfig = saveconfig; + config_callbacks[num_config_callbacks].onloaded = onloaded; + num_config_callbacks++; +} void loadconfig(char *fn) { @@ -734,6 +750,16 @@ void loadconfig(char *fn) } enable_sync = config_get_int(CFG_MACHINE, NULL, "enable_sync", 1); + + + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].loadconfig) + config_callbacks[d].loadconfig(); + + + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].onloaded) + config_callbacks[d].onloaded(); } void saveconfig(char *fn) @@ -837,6 +863,10 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "enable_sync", enable_sync); + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].saveconfig) + config_callbacks[d].saveconfig(); + pclog("config_save(%s)\n", config_file_default); if (fn) config_save(CFG_MACHINE, fn); diff --git a/src/pc.xrc b/src/pc.xrc new file mode 100644 index 0000000..b1a2d19 --- /dev/null +++ b/src/pc.xrc @@ -0,0 +1,1617 @@ + + + + icons/drive.png + icons/disk.png + icons/cd.png + + + + icons/play24.png + + + + icons/pause24.png + + + + icons/stop24.png + + + + icons/refresh24.png + + + + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + + + + + 1 + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + + 1 + + + + 1 + + + + + 1 + + + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + + + + + + + + + + + Configure PCem + 1 + + + + wxALL + 5 + + 3 + 0 + 0 + 0 + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + 50 + 10 + 200 + + + + wxALIGN_CENTER|wxALL + 0 + + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + Configure Hard Discs + 1 + + + + wxALL + 5 + + 1 + 0 + 0 + 0 + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + + + + 4 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + wxALL + 0 + + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + New Hard Disc + 1 + + + + wxALL + 5 + + 2 + 0 + 0 + 0 + + + wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + Hard disc parameters + 1 + + + + wxALL + 5 + + wxVERTICAL + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALIGN_CENTRE|wxALL + 0 + + 2 + 0 + 0 + 0 + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + + + wxALIGN_LEFT|wxALL + 0 + + + + + + wxALL + 0 + + + + + + + wxALIGN_LEFT|wxALL + 0 + + wxHORIZONTAL + + wxALIGN_CENTRE|wxALL + 0 + + 1 + + + + + wxALIGN_CENTRE|wxALL + 0 + + + + + + + + + + + + + + + + PCem Configuration Manager + 1 + + + + wxALL + 5 + + wxHORIZONTAL + + wxALL + 0 + + + 200,300 + + + + wxEXPAND + 0 + + wxVERTICAL + + + wxALL + 0 + + + 1 + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + + + + + + + + PCem + 1 + + + wxVERTICAL + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + + + + + wxALIGN_CENTER|wxALL + 5 + + + -1 + + + + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + + + + + + + + + 1 + + + wxVERTICAL + + + wxALL + 5 + + + -1 + + + + + wxEXPAND | wxALL + 5 + + + + + + + wxALL + 5 + + + 1 + + + + + + diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index b77a14a..0790068 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -1647,7 +1647,7 @@ 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; @@ -2768,7 +2768,7 @@ 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) diff --git a/src/video.h b/src/video.h index dc04a81..ffca4e8 100644 --- a/src/video.h +++ b/src/video.h @@ -1,4 +1,4 @@ -#ifdef __unix +#ifdef PCEM_ALLEGRO #undef MAX_JOYSTICKS #include "allegro-main.h" diff --git a/src/wx-app.cc b/src/wx-app.cc new file mode 100644 index 0000000..003ab39 --- /dev/null +++ b/src/wx-app.cc @@ -0,0 +1,224 @@ +#include "wx-app.h" + +#include +#include +#include "wx-utils.h" +#include "wx-common.h" + +extern "C" +{ + int wx_load_config(void*); + int wx_start(void*); + int wx_stop(void*); + void wx_show(void*); + void wx_handle_command(void*, int, int); + + int start_emulation(void*); + int resume_emulation(); + int pause_emulation(); + int stop_emulation(); +} + +extern void InitXmlResource(); + +wxDEFINE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); +wxDEFINE_EVENT(WX_EXIT_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); + +wxBEGIN_EVENT_TABLE(Frame, wxFrame) +wxEND_EVENT_TABLE() + +wxIMPLEMENT_APP_NO_MAIN(App); + +App::App() +{ + this->frame = NULL; +} + +bool App::OnInit() +{ + wxImage::AddHandler( new wxPNGHandler ); + wxXmlResource::Get()->InitAllHandlers(); +// if (!wxXmlResource::Get()->Load("src/pc.xrc")) +// { +// std::cout << "Could not load resource file" << std::endl; +// return false; +// } + InitXmlResource(); + + frame = new Frame(this, "null frame", wxPoint(500, 500), + wxSize(100, 100)); + frame->Start(); + return true; +} + +int App::OnRun() +{ + return wxApp::OnRun(); +} + +#include + +Frame::Frame(App* app, const wxString& title, const wxPoint& pos, + const wxSize& size) : + wxFrame(NULL, wxID_ANY, title, pos, size, 0)//wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER)) +{ + this->closing = false; + this->menu = wxXmlResource::Get()->LoadMenu(wxT("main_menu")); + + Bind(wxEVT_CLOSE_WINDOW, &Frame::OnClose, this); + Bind(wxEVT_MENU, &Frame::OnCommand, this); + Bind(wxEVT_TOOL, &Frame::OnCommand, this); + Bind(WX_SHOW_WINDOW_EVENT, &Frame::OnShowWindowEvent, this); + Bind(WX_POPUP_MENU_EVENT, &Frame::OnPopupMenuEvent, this); + Bind(WX_EXIT_EVENT, &Frame::OnExitEvent, this); + Bind(WX_EXIT_COMPLETE_EVENT, &Frame::OnExitCompleteEvent, this); + Bind(WX_STOP_EMULATION_EVENT, &Frame::OnStopEmulationEvent, this); + Bind(WX_CALLBACK_EVENT, &Frame::OnCallbackEvent, this); + + CenterOnScreen(); +} + +void Frame::Start() +{ + if (wx_start(this)) + ShowConfigSelection(); + else + Quit(0); +} + +void Frame::ShowConfigSelection() +{ + if (wx_load_config(this)) + start_emulation(this); + else + Quit(1); +} + +void Frame::OnCallbackEvent(CallbackEvent& event) +{ + WX_CALLBACK callback = event.GetCallback(); + callback(); +} + +void Frame::OnStopEmulationEvent(wxCommandEvent& event) +{ + if (emulation_state != EMULATION_STOPPED) + { + pause_emulation(); + int ret = wxID_OK; + + if (confirm_on_stop_emulation) + { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); + dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Stop emulation?"); + dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); + dlg.Fit(); + ret = dlg.ShowModal(); + if (ret == wxID_OK) + confirm_on_stop_emulation = !((wxCheckBox*)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); + } + + if (ret == wxID_OK) + { + stop_emulation(); + ShowConfigSelection(); + } + else + resume_emulation(); + } +} + +void Frame::OnShowWindowEvent(wxCommandEvent& event) +{ + wxWindow* window = (wxWindow*)event.GetEventObject(); + int shown = window->IsShown(); + int value = event.GetInt(); + if (value < 0) + window->Show(!shown); + else + window->Show(value > 0); + if (!shown) + window->Refresh(); +} + +void Frame::OnPopupMenuEvent(PopupMenuEvent& event) +{ + wxWindow* window = event.GetWindow(); + wxMenu* menu = event.GetMenu(); + int* x = event.GetX(); + int* y = event.GetY(); + + if (x && y) + window->PopupMenu(menu, *x, *y); + else + window->PopupMenu(menu); +} + +void Frame::OnCommand(wxCommandEvent& event) +{ + wx_handle_command(this, event.GetId(), event.IsChecked()); +} + +void Frame::OnClose(wxCloseEvent& event) +{ + wx_exit(this, 0); +} + +wxMenu* Frame::GetMenu() +{ + return menu; +} + +/* Exit */ + +void Frame::Quit(bool stop_emulator) +{ + if (closing) + return; + closing = true; + if (stop_emulator) + { + if (!wx_stop(this)) + { + // cancel quit + closing = false; + return; + } + } + Destroy(); +} + +void Frame::OnExitEvent(wxCommandEvent& event) +{ + if (closing) + return; + closing = true; + CExitThread* exitThread = new CExitThread(this); + exitThread->Run(); +} + +void Frame::OnExitCompleteEvent(wxCommandEvent& event) +{ + if (event.GetInt()) + Destroy(); + else + closing = false; +} + +CExitThread::CExitThread(Frame* frame) +{ + this->frame = frame; +} + +wxThread::ExitCode CExitThread::Entry() +{ + wxCommandEvent* event = new wxCommandEvent(WX_EXIT_COMPLETE_EVENT, wxID_ANY); + event->SetInt(wx_stop(frame)); + wxQueueEvent(frame, event); + return 0; +} diff --git a/src/wx-app.h b/src/wx-app.h new file mode 100644 index 0000000..0c3b244 --- /dev/null +++ b/src/wx-app.h @@ -0,0 +1,134 @@ +#ifndef SRC_WX_APP_H_ +#define SRC_WX_APP_H_ + +#include +#ifndef WX_PRECOMP +#include +#endif + +#include "wx-utils.h" + +class CallbackEvent; +class PopupMenuEvent; + +wxDECLARE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); +wxDECLARE_EVENT(WX_EXIT_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); + +class CallbackEvent: public wxCommandEvent +{ +public: + CallbackEvent(WX_CALLBACK callback) : wxCommandEvent(WX_CALLBACK_EVENT) + { + this->callback = callback; + } + CallbackEvent(const CallbackEvent& event) : wxCommandEvent(event) + { + this->callback = event.GetCallback(); + } + + wxEvent* Clone() const { return new CallbackEvent(*this); } + + WX_CALLBACK GetCallback() const { return callback; } + +private: + WX_CALLBACK callback; + + +}; + +class PopupMenuEvent: public wxCommandEvent +{ +public: + PopupMenuEvent(wxWindow* window, wxMenu* menu, int* x, int* y) : wxCommandEvent(WX_POPUP_MENU_EVENT) + { + this->window = window; + this->menu = menu; + this->x = x; + this->y = y; + } + PopupMenuEvent(const PopupMenuEvent& event) : wxCommandEvent(event) + { + this->window = event.GetWindow(); + this->menu = event.GetMenu(); + this->x = event.GetX(); + this->y = event.GetY(); + } + + wxEvent* Clone() const { return new PopupMenuEvent(*this); } + + wxWindow* GetWindow() const { return window; } + wxMenu* GetMenu() const { return menu; } + int* GetX() const { return x; } + int* GetY() const { return y; } + +private: + int* x; + int* y; + wxMenu* menu; + wxWindow* window; +}; + + +class Frame; + +class App: public wxApp +{ +public: + App(); + virtual bool OnInit(); + virtual int OnRun(); + Frame* GetFrame() + { + return frame; + } +private: + Frame* frame; +}; + +class CExitThread: public wxThread +{ +public: + CExitThread(Frame* frame); + virtual ~CExitThread() {} +private: + wxThread::ExitCode Entry(); + Frame* frame; +}; + +class Frame: public wxFrame +{ +public: + Frame(App* app, const wxString& title, const wxPoint& pos, + const wxSize& size); + + virtual ~Frame() {} + + void Start(); + + wxMenu* GetMenu(); + +private: + void OnCommand(wxCommandEvent& event); + void OnExitEvent(wxCommandEvent& event); + void OnExitCompleteEvent(wxCommandEvent& event); + void OnStopEmulationEvent(wxCommandEvent& event); + void OnShowWindowEvent(wxCommandEvent& event); + void OnPopupMenuEvent(PopupMenuEvent& event); + void OnCallbackEvent(CallbackEvent& event); + void OnClose(wxCloseEvent& event); + + void ShowConfigSelection(); + wxMenu* menu; + + bool closing; + + void Quit(bool stop_emulator = 1); + + wxDECLARE_EVENT_TABLE(); +}; + +#endif /* SRC_WX_APP_H_ */ diff --git a/src/wx-common.c b/src/wx-common.c new file mode 100644 index 0000000..55ef6e6 --- /dev/null +++ b/src/wx-common.c @@ -0,0 +1,34 @@ +#include "wx-common.h" +#include "config.h" + +void wx_loadconfig() +{ + show_machine_info = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); + show_disc_activity = config_get_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); + show_speed_history = config_get_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); + show_mount_paths = config_get_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); + show_status = config_get_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); + show_machine_on_start = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); + + confirm_on_reset_machine = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); + confirm_on_stop_emulation = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); + + wx_window_x = config_get_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); + wx_window_y = config_get_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); +} + +void wx_saveconfig() +{ + config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); + + config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); + config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); + + config_set_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); + config_set_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); +} diff --git a/src/wx-common.h b/src/wx-common.h new file mode 100644 index 0000000..294a0ee --- /dev/null +++ b/src/wx-common.h @@ -0,0 +1,26 @@ +extern int show_machine_info; +extern int show_status; +extern int show_machine_on_start; +extern int confirm_on_stop_emulation; +extern int confirm_on_reset_machine; +extern int show_speed_history; +extern int show_disc_activity; +extern int show_mount_paths; +extern int wx_window_x; +extern int wx_window_y; + +typedef enum { EMULATION_STOPPED, EMULATION_PAUSED, EMULATION_RUNNING } emulation_state_t; +extern emulation_state_t emulation_state; + +#define IS_PAUSED (emulation_state == EMULATION_PAUSED) + +typedef enum { DRIVE_TYPE_HDD, DRIVE_TYPE_FDD, DRIVE_TYPE_CDROM } drive_type_t; + +typedef struct drive_info_t { + drive_type_t type; + char fn[256]; + int enabled; + int drive; + char drive_letter; + int readflash; +} drive_info_t; diff --git a/src/wx-config.c b/src/wx-config.c new file mode 100644 index 0000000..2a5658d --- /dev/null +++ b/src/wx-config.c @@ -0,0 +1,863 @@ +#include "wx-utils.h" + +#include "ibm.h" +#include "cpu.h" +#include "device.h" +#include "fdd.h" +#include "gameport.h" +#include "hdd.h" +#include "model.h" +#include "mouse.h" +#include "mem.h" +#include "nvr.h" +#include "sound.h" +#include "video.h" +#include "vid_voodoo.h" + +extern int pause; + +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]; + +int has_been_inited = 0; + +extern void deviceconfig_open(void* hwnd, device_t *device); + +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_vid_list(void* hdlg, int model) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + int c = 0, d = 0; + int found_card = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_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[model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (video_new_to_old(c) == gfxcard) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + } + + d++; + } + + c++; + } + if (!found_card) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, models[model].fixed_gfxcard ? FALSE : TRUE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + wx_enablewindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVOODOO")); + wx_enablewindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); +} + +static void recalc_snd_list(void* hdlg, int model) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + int c = 0, d = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + + while (1) + { + char *s = sound_card_getname(c); + + if (!s[0]) + break; + + settings_sound_to_list[c] = d; + + if (sound_card_available(c)) + { + device_t *sound_dev = sound_card_getdevice(c); + + if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[model].flags & MODEL_MCA)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + settings_list_to_sound[d] = c; + d++; + } + } + + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); +} + +static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd) +{ + void* h; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + + if (models[model].flags & MODEL_HAS_IDE) + { + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Internal IDE"); + wx_enablewindow(h, FALSE); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + } + else + { + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + if (use_selected_hdd) + { + c = wx_sendmessage(h, WX_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); + + wx_sendmessage(h, WX_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)) || + (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model].flags & MODEL_MCA)) && c) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + wx_enablewindow(h, TRUE); + } +} + +int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char temp_str[256]; + void* 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_sound_card_current; + int temp_dynarec; + int cpu_flags; + int temp_fda_type, temp_fdb_type; + int temp_joystick_type; + int cpu_type; + int temp_mouse_type; + int hdd_changed; + + switch (message) + { + case WX_INITDIALOG: + { + pause = 1; + h = wx_getdlgitem(hdlg, WX_ID("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]) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) models[c].name); + modeltolist[c] = d; + listtomodel[d] = c; + romstolist[models[c].id] = d; + romstomodel[models[c].id] = c; + d++; + } + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); + + recalc_vid_list(hdlg, romstomodel[romset]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + c = 0; + while (models[romstomodel[romset]].cpu[c].cpus != NULL && c < 4) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[romstomodel[romset]].cpu[c].name); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu_manufacturer, 0); + if (c == 1) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + c = 0; + while (models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].cpu_type + != -1) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].name); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu, 0); + + recalc_snd_list(hdlg, romstomodel[romset]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + wx_sendmessage(h, WX_BM_SETCHECK, GAMEBLASTER, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + wx_sendmessage(h, WX_BM_SETCHECK, GUS, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + wx_sendmessage(h, WX_BM_SETCHECK, SSI2001, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + wx_sendmessage(h, WX_BM_SETCHECK, enable_sync, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + wx_sendmessage(h, WX_BM_SETCHECK, voodoo_enabled, 0); + + cpu_flags = + models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "8-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow 16-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast 16-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow VLB/PCI"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Mid VLB/PCI"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast VLB/PCI"); + wx_sendmessage(h, WX_CB_SETCURSEL, video_speed, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + printf("%d\n", models[model].ram_granularity); + wx_sendmessage(h, WX_UDM_SETRANGE, 0, + (models[romstomodel[romset]].min_ram << 16) + | models[romstomodel[romset]].max_ram); + wx_sendmessage(h, WX_UDM_SETINCR, 0, models[model].ram_granularity); + if (!(models[model].flags & MODEL_AT)) + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size); + else + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size / 1024); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); + if (model_getdevice(model)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(video_old_to_new(gfxcard))) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); + if (sound_card_has_config(sound_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"None"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 360k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M Dual RPM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 720k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M 3-Mode"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 2.88M"); + wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(0), 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"None"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 360k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M Dual RPM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 720k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M 3-Mode"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 2.88M"); + wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(1), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); + if (models[model].flags & MODEL_AT) + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); + else + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); + + // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); + // c = 0; + // while (joystick_get_name(c)) + // { + // wx_sendmessage(h, CB_ADDSTRING, 0, joystick_get_name(c)); + // c++; + // } + // wx_enablewindow(h, TRUE); + // wx_sendmessage(h, CB_SETCURSEL, joystick_type, 0); + // + // h = wx_getdlgitem(hdlg, ID("IDC_JOY1")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); + // h = wx_getdlgitem(hdlg, ID("IDC_JOY2")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); + // h = wx_getdlgitem(hdlg, ID("IDC_JOY3")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); + // h = wx_getdlgitem(hdlg, ID("IDC_JOY4")); + // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "System default"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "0 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "1 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "2 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "4 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "6 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "7 W/S"); + wx_sendmessage(h, WX_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)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("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)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + + settings_list_to_mouse[d] = c; + d++; + } + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); + + recalc_hdd_list(hdlg, romstomodel[romset], 0); + + return TRUE; + } + break; + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + int mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + 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 = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + gfx = video_new_to_old(video_card_getid(temp_str)); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type + >= CPU_i486DX) ? 1 : 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + temp_GUS = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + temp_SSI2001 = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + enable_sync = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + temp_voodoo = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, + WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + temp_fda_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); + + if (temp_model != model || gfx != gfxcard || mem != mem_size || + 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || + temp_mouse_type != mouse_type || hdd_changed) + { + if (!has_been_inited || confirm()) + { + 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; + cpu_use_dynarec = temp_dynarec; + mouse_type = temp_mouse_type; + + fdd_set_type(0, temp_fda_type); + fdd_set_type(1, temp_fdb_type); + + if (hdd_names[c]) + strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); + else + strcpy(hdd_controller_name, "none"); + + + if (has_been_inited) + { + mem_resize(); + loadbios(); + resetpchard(); + } + } + else + { + wx_enddialog(hdlg, 0); + pause = 0; + return TRUE; + } + } + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + cpu_set(); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + cpu_update_waitstates(); + + if (has_been_inited) + saveconfig(NULL); + + speedchanged(); + +// joystick_type = temp_joystick_type; +// gameport_update_joystick_type(); + + } + if (wParam == wxID_OK || wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + pause = 0; + return TRUE; + } + else if (wParam == WX_ID("IDC_COMBO1")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + /*Rebuild manufacturer list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model].cpu[c].cpus != NULL && c < 4) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[temp_model].cpu[c].name); + c++; + } + if (temp_cpu_m >= c) + temp_cpu_m = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu_m, 0); + if (c == 1) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + + /*Rebuild CPU list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[temp_model].cpu[temp_cpu_m].cpus[c].name); + c++; + } + if (temp_cpu >= c) + temp_cpu = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + cpu_flags = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); + if (models[temp_model].flags & MODEL_AT) + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); + else + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + wx_sendmessage(h, WX_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; + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + wx_sendmessage(h, WX_UDM_SETINCR, 0, models[temp_model].ram_granularity); + + h = wx_getdlgitem(hdlg, WX_ID("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) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); + if (model_getdevice(temp_model)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + wx_sendmessage(h, WX_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)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + + settings_list_to_mouse[d] = c; + d++; + } + + c++; + } + if (mouse_valid(temp_mouse_type, temp_model)) + wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + recalc_vid_list(hdlg, temp_model); + + recalc_hdd_list(hdlg, temp_model, 1); + + recalc_snd_list(hdlg, temp_model); + } + else if (wParam == WX_ID("IDC_COMBOCPUM")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + /*Rebuild CPU list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) models[temp_model].cpu[temp_cpu_m].cpus[c].name); + c++; + } + if (temp_cpu >= c) + temp_cpu = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + cpu_flags = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("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) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + + } + else if (wParam == WX_ID("IDC_COMBO3")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + cpu_flags = + models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) + || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + + h = wx_getdlgitem(hdlg, WX_ID("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) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } + else if (wParam == WX_ID("IDC_CONFIGUREMOD")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *) model_getdevice(temp_model)); + } + else if (wParam == WX_ID("IDC_CONFIGUREVID")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + + deviceconfig_open(hdlg, + (void *) video_card_getdevice(video_card_getid(temp_str))); + } + else if (wParam == WX_ID("IDC_COMBOVID")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + gfx = video_card_getid(temp_str); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(gfx)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } + else if (wParam == WX_ID("IDC_CONFIGURESND")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, + WX_CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, + (void *) sound_card_getdevice(temp_sound_card_current)); + } + else if (wParam == WX_ID("IDC_COMBOSND")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, + WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); + if (sound_card_has_config(temp_sound_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } + else if (wParam == WX_ID("IDC_CONFIGUREVOODOO")) + { + deviceconfig_open(hdlg, (void *) &voodoo_device); + } + // + // case IDC_COMBOJOY: + // if (HIWORD(wParam) == CBN_SELCHANGE) { + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // + // h = wx_getdlgitem(hdlg, IDC_JOY1); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY2); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY3); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY4); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? + // TRUE : FALSE); + // } + // break; + // + // case IDC_JOY1: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 0, temp_joystick_type); + // break; + // case IDC_JOY2: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 1, temp_joystick_type); + // break; + // case IDC_JOY3: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 2, temp_joystick_type); + // break; + // case IDC_JOY4: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 3, temp_joystick_type); + // break; + return 0; + } + } +} + +void config_open(void* hwnd) +{ + wx_dialogbox(hwnd, "ConfigureDlg", config_dlgproc); +} diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c new file mode 100644 index 0000000..0025bb0 --- /dev/null +++ b/src/wx-config_sel.c @@ -0,0 +1,249 @@ +#include "ibm.h" +#include "config.h" +#include "wx-utils.h" +#include "wx-sdl2.h" + +extern void config_open(void* hwnd); +extern void hdconf_open(void* hwnd); + +static void config_list_update(void* hdlg) +{ + char s[512]; + int num, c; + void* h; + + strcpy(s, pcempath); + put_backslash(s); + strcat(s, "configs/*.cfg"); + pclog("Dir %s\n", s); + + wx_dlgdirlist(hdlg, s, WX_ID("IDC_LIST"), 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + + for (c = 0; c < num; c++) + { + char *ext; + + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)s); + ext = get_extension(s); + if (ext && ext[0]) + { + ext--; + *ext = 0; + } + + wx_sendmessage(h, WX_LB_DELETESTRING, c, 0); + wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)s); + } +} + +static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + //void* h; + + switch (message) + { + case WX_INITDIALOG: + { + // pause = 1; + config_list_update(hdlg); + // h = wx_getdlgitem(hdlg, IDC_LIST); + // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"AAA"); + // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"BBB"); + return TRUE; + } + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, pcempath); + put_backslash(cfg); + strcat(cfg, "configs/"); + strcat(cfg, s); + strcat(cfg, "cfg"); +// sprintf(cfg, "%s\\configs\\%scfg", pcempath, s); + pclog("Config name %s\n", cfg); + + strcpy(config_file_default, cfg); + + wx_enddialog(hdlg, 1); +// pause = 0; + return TRUE; + } + return FALSE; + } + else if (wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + // pause = 0; + return TRUE; + } + else if (wParam == WX_ID("IDC_NEW")) + { + char name[64]; + +// if (!getsfile(hdlg, "Configuration (*.cfg)|*.cfg|All files (*.*)|*.*", "", s, "cfg")) + if (wx_textentrydialog(hdlg, "Enter name:", "New config", 0, 1, 64, (LONG_PARAM)name)) + { + strcpy(openfilestring, pcempath); + put_backslash(openfilestring); + strcat(openfilestring, "configs/"); + strcat(openfilestring, name); + strcat(openfilestring, ".cfg"); + + pclog("Config %s\n", openfilestring); + + config_open(hdlg); + + saveconfig(openfilestring); + + config_list_update(hdlg); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_CONFIG")) + { + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, pcempath); + put_backslash(cfg); + strcat(cfg, "configs/"); + strcat(cfg, s); + strcat(cfg, "cfg"); + pclog("Config name %s\n", cfg); + + loadconfig(cfg); + config_open(hdlg); + saveconfig(cfg); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_HDCONF")) + { + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, pcempath); + put_backslash(cfg); + strcat(cfg, "configs/"); + strcat(cfg, s); + strcat(cfg, "cfg"); + pclog("Config name %s\n", cfg); + + loadconfig(cfg); + hdconf_open(hdlg); + saveconfig(cfg); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_RENAME")) + { + char name[64]; + char old_name[64]; + void* h; + int c; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); + + if (wx_textentrydialog(hdlg, "Enter name:", "New name", old_name, 1, 64, (LONG_PARAM)name)) + { + char old_path[512]; + char new_path[512]; + + strcpy(old_path, pcempath); + put_backslash(old_path); + strcat(old_path, "configs/"); + strcat(old_path, old_name); + strcat(old_path, ".cfg"); + + strcpy(new_path, pcempath); + put_backslash(new_path); + strcat(new_path, "configs/"); + strcat(new_path, name); + strcat(new_path, ".cfg"); + + pclog("Rename %s to %s\n", old_path, new_path); + + rename(old_path, new_path); + + config_list_update(hdlg); + } + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_DELETE")) + { + char name[64]; + void* h; + int c; + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + char s[512]; + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)name); + sprintf(s, "Do you want to delete \"%s\"?", name); + if (wx_messagebox(NULL, s, "PCem", WX_MB_OKCANCEL) == WX_IDOK) + { + strcpy(s, pcempath); + put_backslash(s); + strcat(s, "configs/"); + strcat(s, name); + strcat(s, ".cfg"); + + remove(s); + + config_list_update(hdlg); + } + } + } + } + break; + } + return FALSE; +} + +int config_selection_open(void* hwnd, int inited) +{ + int ret; + + has_been_inited = inited; + + ret = wx_dialogbox(hwnd, "ConfigureSelectionDlg", config_selection_dlgproc); + + has_been_inited = 1; + + return ret; +} diff --git a/src/wx-deviceconfig.cc b/src/wx-deviceconfig.cc new file mode 100644 index 0000000..3a280ce --- /dev/null +++ b/src/wx-deviceconfig.cc @@ -0,0 +1,268 @@ +#include "wx-deviceconfig.h" + +#include "wx-utils.h" +#include "wx/wxprec.h" + +#include "wx-dialogbox.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/xrc/xmlres.h" + +extern "C" +{ + #include "config.h" + void saveconfig(char*); + void resetpchard(); + int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam); + device_t *config_device; + int confirm(); +} +#define IDC_CONFIG_BASE 1000 + + +int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { + switch (message) { + case WX_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; + void* h = 0; + int val_int; + char *val_string; + int num; + char s[80]; + + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + wx_sendmessage(h, WX_BM_SETCHECK, val_int, 0); + + id++; + break; + + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id+1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + c = 0; + while (selection->description[0]) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM) selection->description); + if (val_int == selection->value) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; + + case CONFIG_MIDI: + // midi ignored +// val_int = config_get_int(CFG_MACHINE, 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, (LONG_PARAM)s); +// if (val_int == c) +// SendMessage(h, CB_SETCURSEL, c, 0); +// } +// +// id += 2; + break; + } + config++; + } + } + return TRUE; + + case WX_COMMAND: + switch (wParam) { + case wxID_OK: { + 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; + void* h = 0; + int val_int; + char *val_string; + + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + if (val_int != wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)) + changed = 1; + + id++; + break; + + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id+1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); + + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; + + case CONFIG_MIDI: + // midi ignored +// val_int = config_get_int(CFG_MACHINE, NULL, config->name, +// config->default_int); +// +// c = SendMessage(h, CB_GETCURSEL, 0, 0); +// +// if (val_int != c) +// changed = 1; +// +// id += 2; + break; + } + config++; + } + + if (!changed) { + wx_enddialog(hdlg, 0); + return TRUE; + } + + if (has_been_inited && !confirm()) { + wx_enddialog(hdlg, 0); + return TRUE; + } + + id = IDC_CONFIG_BASE; + config = config_device->config; + + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void* h = 0; + int val_int; + char *val_string; + + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + config_set_int(CFG_MACHINE, config_device->name, config->name, + wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)); + + id++; + break; + + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id+1); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_int(CFG_MACHINE, config_device->name, config->name, + selection->value); + + id += 2; + break; + + case CONFIG_MIDI: + // midi ignored +// c = SendMessage(h, CB_GETCURSEL, 0, 0); +// config_set_int(CFG_MACHINE, NULL, config->name, c); +// +// id += 2; + break; + } + config++; + } + + if (has_been_inited) + { + saveconfig(NULL); + resetpchard(); + } + + wx_enddialog(hdlg, 0); + return TRUE; + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + + + +void deviceconfig_open(void* hwnd, device_t *device) { + config_device = device; + + PCemDialogBox dialog((wxWindow*) hwnd, deviceconfig_dlgproc); +// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + device_config_t *config = device->config; + + dialog.SetTitle("Device Configuration"); + + wxBoxSizer* root = new wxBoxSizer(wxVERTICAL); + dialog.SetSizer(root); + + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + root->Add(sizer, 0, wxALL, 5); + + int id = IDC_CONFIG_BASE; + + while (config->type != -1) { + switch (config->type) { + case CONFIG_BINARY: + sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL); + break; + + case CONFIG_SELECTION: { + sizer->Add(new wxStaticText(&dialog, id++, config->description), 0, wxALL); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + sizer->Add(cb, 0, wxALL); + } break; + case CONFIG_MIDI: + // midi ignored + break; + } + + config++; + } + + wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + + okCancelSizer->Add(new wxButton(&dialog, wxID_OK)); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL)); + + sizer->Add(okCancelSizer); + + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); +} diff --git a/src/wx-deviceconfig.h b/src/wx-deviceconfig.h new file mode 100644 index 0000000..5a591df --- /dev/null +++ b/src/wx-deviceconfig.h @@ -0,0 +1,10 @@ +#ifndef SRC_WX_DEVICECONFIG_H_ +#define SRC_WX_DEVICECONFIG_H_ + +extern "C" { +#include +#include "device.h" +void deviceconfig_open(void* hwnd, device_t *device); +} + +#endif /* SRC_WX_DEVICECONFIG_H_ */ diff --git a/src/wx-dialogbox.cc b/src/wx-dialogbox.cc new file mode 100644 index 0000000..7b1fa7f --- /dev/null +++ b/src/wx-dialogbox.cc @@ -0,0 +1,45 @@ +#include "wx-dialogbox.h" + +#include + +#ifndef WX_PRECOMP +#include +#endif + +#include + +BEGIN_EVENT_TABLE(PCemDialogBox, wxDialog) END_EVENT_TABLE() + +PCemDialogBox::PCemDialogBox(wxWindow* parent, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) : + wxDialog(parent, -1, "No title") +{ + this->callback = callback; +} + +PCemDialogBox::PCemDialogBox(wxWindow* parent, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) +{ + wxXmlResource::Get()->LoadDialog(this, parent, name); + this->callback = callback; +} + +void PCemDialogBox::OnInit() +{ + if (callback) + { + callback(this, WX_INITDIALOG, 0, 0); + Bind(wxEVT_BUTTON, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_TEXT, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_COMBOBOX, &PCemDialogBox::OnCommand, this); + } + + wxWindow* root = FindWindow(XRCID("ROOT_PANEL")); + if (root) + root->Fit(); + Fit(); +} + +void PCemDialogBox::OnCommand(wxCommandEvent& event) +{ + callback(this, WX_COMMAND, event.GetId(), 0); +} + diff --git a/src/wx-dialogbox.h b/src/wx-dialogbox.h new file mode 100644 index 0000000..ca3ee4d --- /dev/null +++ b/src/wx-dialogbox.h @@ -0,0 +1,21 @@ +#ifndef SRC_WX_PCEMDIALOGBOX_H_ +#define SRC_WX_PCEMDIALOGBOX_H_ + +#include "wx/dialog.h" + +#include "wx-utils.h" + +class PCemDialogBox: public wxDialog { +public: + PCemDialogBox(wxWindow* parent, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); + PCemDialogBox(wxWindow* parent, const char* name, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); + virtual ~PCemDialogBox() {} + void OnInit(); +private: + void OnCommand(wxCommandEvent &event); + int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2); + + DECLARE_EVENT_TABLE() +}; + +#endif /* SRC_WX_PCEMDIALOGBOX_H_ */ diff --git a/src/wx-display.h b/src/wx-display.h new file mode 100644 index 0000000..4753579 --- /dev/null +++ b/src/wx-display.h @@ -0,0 +1,36 @@ +#ifndef SRC_WX_DISPLAY_H_ +#define SRC_WX_DISPLAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int display_init(); +void display_close(); +void display_start(void* hwnd); +void display_stop(); +void display_resize(int width, int height); + +#ifdef __cplusplus +} +#endif + +extern int mousecapture; + +extern int video_scale_mode; +extern int video_vsync; +extern int video_focus_dim; +extern int video_fullscreen_mode; + +extern int win_doresize; + +extern int window_doreset; +extern int renderer_doreset; +extern int window_dofullscreen; +extern int window_dowindowed; +extern int window_doremember; +extern int window_doinputgrab; +extern int window_doinputrelease; +extern int window_dotogglefullscreen; + +#endif /* SRC_WX_DISPLAY_H_ */ diff --git a/src/wx-main.cc b/src/wx-main.cc new file mode 100644 index 0000000..e5790dc --- /dev/null +++ b/src/wx-main.cc @@ -0,0 +1,15 @@ +#include "wx-app.h" + +extern "C" +{ +int pc_main(int, char**); +} + +int main(int argc, char **argv) +{ + pc_main(argc, argv); + + wxApp::SetInstance(new App()); + wxEntry(argc, argv); +} + diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp new file mode 100644 index 0000000..645bb0a --- /dev/null +++ b/src/wx-resources.cpp @@ -0,0 +1,3010 @@ +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 346; +static unsigned char xml_res_file_0[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,4,0,0, +0,181,250,55,234,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, +116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, +97,103,101,82,101,97,100,121,113,201,101,60,0,0,0,236,73,68,65,84,40,207, +165,145,61,74,4,65,16,133,191,94,123,214,192,31,132,197,64,23,4,51,111, +177,48,147,120,11,79,224,9,4,207,227,13,156,100,135,185,129,193,70,3,155, +8,6,130,152,8,130,83,221,213,101,208,189,131,145,201,86,80,73,189,247,190, +162,202,25,255,215,140,125,5,30,96,88,107,173,68,2,129,128,32,8,35,210, +221,53,224,140,97,53,239,207,145,201,147,183,170,232,121,109,238,59,15, +241,241,140,119,14,1,43,67,227,141,83,174,25,30,232,220,102,53,239,23,124, +149,224,136,225,56,160,226,132,35,90,182,141,123,89,95,212,134,96,37,220, +166,94,241,201,83,231,133,111,62,24,49,18,74,194,72,36,20,195,115,140,224, +165,6,65,217,224,152,21,175,145,184,66,89,34,181,31,137,68,20,197,145,10, +102,151,17,8,248,17,69,73,220,144,72,216,31,140,145,178,96,129,78,193,217, +191,3,93,18,241,63,237,243,173,48,230,219,33,72,185,103,198,90,235,246, +254,230,47,16,30,136,4,54,25,76,145,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_1 = 620; +static unsigned char xml_res_file_1[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, +116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, +97,103,101,82,101,97,100,121,113,201,101,60,0,0,1,254,73,68,65,84,24,25, +5,193,61,139,93,85,24,6,208,181,207,236,59,67,130,146,168,96,132,68,68, +3,10,86,1,101,32,241,163,21,127,130,133,104,145,42,66,208,34,165,54,86, +86,34,162,8,99,161,216,10,118,130,98,97,149,34,22,22,193,78,197,66,180, +18,197,12,222,153,123,246,126,31,215,106,135,111,124,247,22,30,195,243, +120,2,247,145,142,38,192,222,210,44,75,147,148,42,255,236,111,252,188,61, +93,223,187,243,241,203,95,118,60,125,116,235,218,117,154,167,46,30,8,82, +177,27,177,91,203,222,210,156,57,88,180,198,241,182,28,159,204,115,191, +254,121,124,229,243,111,126,249,228,240,198,215,231,22,188,32,124,117,231, +95,21,146,184,249,225,15,170,66,107,54,189,89,150,102,55,98,187,150,81, +218,180,244,215,94,186,252,208,153,131,253,143,22,60,18,84,197,58,202,58, +2,214,138,190,199,166,55,85,177,221,149,117,132,196,247,119,239,217,223, +236,217,158,142,253,142,179,163,130,216,238,10,44,173,17,54,125,209,52, +39,107,217,158,70,37,42,84,226,143,191,78,72,90,39,125,38,18,78,71,192, +219,175,95,177,233,139,190,176,206,248,239,180,140,42,85,68,164,202,58, +166,164,116,180,154,72,188,251,217,143,90,107,150,198,166,47,26,70,197, +24,37,0,56,127,254,65,235,216,35,209,133,74,169,154,30,190,112,145,70,19, +2,81,161,170,36,81,137,170,162,53,235,58,72,233,48,39,9,208,18,160,81,69, +18,68,130,68,75,36,101,93,155,164,116,24,179,16,16,209,52,18,73,164,74, +68,18,85,83,42,162,156,174,33,165,19,179,66,120,231,149,75,0,0,0,0,224, +214,209,79,198,136,164,244,165,53,179,136,72,248,224,246,117,0,0,0,112, +243,234,145,57,135,221,8,137,174,81,21,13,112,237,210,171,0,0,0,0,106,150, +185,6,165,39,201,172,52,2,110,255,254,5,0,0,0,120,246,209,23,205,57,173, +51,146,164,87,252,182,27,245,248,51,151,207,106,141,55,159,251,20,0,0,0, +192,133,251,203,156,129,191,219,225,141,111,223,79,242,36,185,42,121,128, +146,132,148,164,72,73,138,20,137,36,72,200,61,109,185,251,63,33,124,110, +139,109,16,176,162,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_2 = 673; +static unsigned char xml_res_file_2[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, +116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, +97,103,101,82,101,97,100,121,113,201,101,60,0,0,2,51,73,68,65,84,56,203, +133,147,91,110,218,80,16,134,179,129,172,160,27,137,212,141,116,71,221, +0,50,74,251,210,42,137,4,129,230,129,72,17,133,92,154,128,66,67,49,96,32, +52,220,66,76,205,197,177,9,190,128,1,131,253,119,142,129,134,164,84,69, +250,176,229,153,249,207,156,185,108,1,216,90,231,221,251,232,91,194,71, +100,9,133,24,16,21,194,207,108,175,253,215,3,183,9,142,176,191,242,34,74, +45,29,77,117,138,182,57,131,212,31,34,158,109,129,217,150,62,219,47,4,150, +193,209,131,139,10,230,142,11,73,7,142,210,6,190,20,12,124,239,79,49,38, +39,135,96,54,230,195,124,87,34,43,1,142,25,52,27,222,207,36,239,189,75, +13,159,174,159,32,104,14,92,250,70,15,232,206,194,190,20,225,60,1,122,217, +33,28,177,111,99,47,165,162,170,46,156,78,248,49,252,103,42,234,67,120, +25,244,232,207,164,231,148,225,186,76,192,97,177,222,233,49,186,223,73, +65,199,199,75,5,187,23,10,138,18,80,235,1,169,170,73,215,153,160,63,1,100, +18,208,41,149,193,28,48,136,216,162,38,28,19,200,11,162,134,207,201,71, +18,144,225,255,38,35,146,213,113,152,168,51,135,46,35,156,108,192,164,160, +54,101,83,125,2,132,246,28,130,168,51,123,158,9,168,183,210,136,78,150, +177,75,193,31,72,228,166,97,50,99,135,120,179,164,83,233,77,16,161,162, +134,50,154,71,81,178,152,143,250,71,192,127,46,131,59,237,193,119,218,69, +250,254,111,129,226,47,11,33,94,199,254,205,128,232,163,176,38,144,207, +63,12,192,157,119,189,224,32,169,87,85,23,44,237,213,21,14,19,13,36,27, +44,131,33,142,75,22,162,229,17,114,205,231,43,120,69,188,190,31,67,144, +129,150,5,52,12,66,3,42,143,19,148,58,19,164,154,51,132,114,35,236,211, +108,4,50,38,18,36,182,94,68,175,141,54,181,70,166,30,221,13,0,190,11,92, +137,64,188,62,199,241,237,20,225,188,133,0,111,225,224,135,137,32,111,146, +176,253,220,198,245,65,82,168,93,130,2,36,40,56,86,115,17,41,207,16,22, +198,8,102,23,193,1,222,64,90,180,95,14,210,235,81,150,12,23,57,202,32,94, +155,35,82,92,156,126,36,208,46,220,89,248,41,219,155,71,121,211,50,101, +31,116,148,187,83,175,6,25,42,8,251,246,207,101,250,207,58,43,203,119,223, +166,117,254,13,152,46,30,143,29,240,166,162,0,0,0,0,73,69,78,68,174,66, +96,130}; + +static size_t xml_res_size_3 = 758; +static unsigned char xml_res_file_3[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,7,129,43,165,16,0,0,2,131,73,68,65,84,72,199, +173,150,75,72,85,81,20,134,191,181,207,193,30,100,20,133,72,138,40,74,88, +148,98,23,172,73,154,26,145,41,105,13,170,91,87,16,130,102,61,104,208,80, +176,73,163,232,49,8,10,132,64,203,50,172,124,21,36,233,176,129,248,200, +66,169,244,38,248,106,16,22,106,131,186,247,156,213,68,73,229,30,189,222, +252,135,251,44,190,181,215,218,255,62,107,11,203,200,215,222,144,226,154, +112,153,8,37,64,42,144,60,247,105,12,24,65,181,213,178,77,83,87,190,127, +212,139,33,145,22,179,223,54,36,89,226,84,129,158,7,44,150,151,139,72,163, +11,215,250,10,252,35,43,38,240,117,62,46,87,165,22,216,196,234,52,163,72, +160,183,208,223,188,112,209,44,134,63,186,172,74,99,12,112,128,120,65,95, +248,58,234,47,69,172,96,110,231,141,75,147,198,32,87,145,19,243,149,8,64, +86,103,93,178,173,102,48,198,157,71,110,87,88,50,123,143,248,39,12,128, +173,230,186,23,252,66,234,30,106,246,29,38,51,126,235,170,218,133,165,213, +0,226,107,111,72,81,43,28,244,114,203,205,189,7,57,180,61,25,87,149,151, +147,195,220,25,238,99,54,28,138,38,137,19,22,55,213,96,57,229,81,88,17, +35,194,201,29,25,60,223,95,74,105,98,90,100,127,47,150,101,99,149,25,69, +139,87,83,251,182,184,245,84,239,58,192,253,156,34,210,54,110,94,54,86, +85,143,25,144,140,88,78,209,183,37,129,39,185,197,92,76,207,38,206,88,94, +183,56,221,128,38,198,106,21,91,12,149,41,187,105,200,45,38,97,221,134, +72,33,73,102,45,60,25,103,44,44,137,136,114,109,129,9,133,157,177,128,29, +85,158,141,127,225,222,215,126,126,69,118,214,132,173,16,36,134,4,3,51, +83,220,248,212,197,192,204,148,247,33,67,208,70,181,13,145,163,209,130, +167,67,127,120,48,242,145,167,227,159,113,85,151,183,182,106,171,109,217, +166,201,113,244,246,74,119,65,129,87,223,70,184,53,212,195,143,208,239, +104,246,18,14,25,109,49,93,249,254,81,65,30,122,69,13,205,254,228,195,244, +119,42,187,223,80,53,248,46,90,56,64,77,127,65,96,76,254,13,152,240,32, +16,191,70,63,187,105,177,157,204,238,188,138,73,3,240,190,232,212,184,170, +57,13,56,107,0,119,81,2,221,121,21,147,139,6,78,111,209,153,215,130,92, +5,220,255,154,5,202,149,158,162,179,45,158,35,51,167,163,254,184,160,117, +49,180,107,26,113,207,245,20,4,90,61,71,38,64,111,161,191,89,109,59,93, +209,187,64,56,170,150,160,181,98,59,153,75,225,158,175,138,121,101,117, +214,37,219,88,101,224,150,160,146,182,240,217,162,16,52,208,22,18,183,185, +191,32,48,230,197,248,11,86,228,238,84,203,121,117,202,0,0,0,0,73,69,78, +68,174,66,96,130}; + +static size_t xml_res_size_4 = 635; +static unsigned char xml_res_file_4[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,39,59,41,220,197,88,0,0,2,8,73,68,65,84,72,199,181, +150,79,107,19,81,20,197,127,247,77,42,74,213,77,161,105,59,67,168,180,139, +172,252,12,110,107,193,68,67,43,65,17,164,184,85,113,225,170,8,250,17,92, +43,8,117,211,148,40,77,82,220,250,17,220,117,33,132,66,39,211,70,234,194, +74,241,79,230,205,117,209,36,152,191,198,208,57,48,139,119,223,155,115, +207,59,92,238,125,194,16,4,133,185,148,138,205,160,178,12,209,60,136,119, +186,163,62,152,61,160,130,53,219,110,62,216,31,196,33,253,130,251,133,41, +87,72,60,19,88,3,28,134,35,18,40,138,149,167,179,249,195,189,127,38,8,54, +167,179,42,178,1,92,228,255,240,29,184,235,174,214,75,127,7,77,167,37,201, +71,42,82,28,131,28,224,18,240,62,216,76,62,236,123,131,166,242,98,119,210, +49,16,1,55,91,55,17,0,191,232,122,98,195,221,110,229,226,92,192,156,159, +110,255,103,79,124,0,156,73,175,173,35,250,249,5,181,63,122,236,178,214, +166,83,249,163,32,1,32,97,248,2,233,181,229,242,213,117,38,23,215,218,235, +175,31,111,1,48,117,237,93,59,118,242,249,21,223,62,173,247,216,229,24, +231,57,240,192,4,133,185,20,194,189,254,53,150,232,92,155,115,167,95,71, +108,98,80,125,222,247,139,174,103,80,155,29,161,20,199,129,35,161,205,24, +21,89,34,38,136,232,117,3,186,24,87,2,69,23,12,48,67,108,16,215,16,47,34, +3,18,196,152,32,48,64,53,54,131,160,106,128,157,216,252,65,43,6,107,182, +1,27,3,127,136,51,81,54,205,97,241,166,191,132,70,103,217,69,191,32,250, +61,244,76,251,172,242,218,203,213,124,105,13,24,67,98,183,217,114,207,162, +217,29,55,28,155,158,207,29,29,180,219,245,193,214,204,82,164,90,62,131, +182,17,161,100,221,219,245,114,199,192,153,93,57,252,32,202,147,102,63, +31,159,92,120,220,34,239,59,50,107,133,228,13,224,109,183,93,35,224,88, +133,59,222,74,189,50,112,100,2,184,171,245,146,65,22,16,94,2,225,40,170, +21,217,104,56,54,221,77,62,240,85,209,130,95,116,61,9,109,70,37,90,22,228, +10,224,181,182,4,170,42,178,163,198,41,121,185,154,63,136,227,15,131,228, +187,196,255,21,120,89,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_5 = 622; +static unsigned char xml_res_file_5[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,10,255,154,217,173,0,0,1,251,73,68,65,84,72,199, +181,150,79,107,19,81,20,197,127,247,189,81,20,172,224,78,104,76,83,154, +69,65,92,249,29,4,173,249,163,11,5,91,18,161,184,85,113,225,82,169,31,193, +125,109,154,182,238,146,54,147,20,193,79,224,70,23,74,177,155,198,212,196, +184,20,234,194,66,102,230,186,104,163,113,72,106,26,157,179,155,251,134, +115,238,59,243,230,158,39,28,129,157,84,46,238,88,147,65,153,81,130,4,72, +236,96,69,91,130,105,168,6,53,79,108,37,89,89,106,14,226,144,126,197,230, +245,220,184,103,228,137,8,243,128,229,104,4,8,37,69,30,79,110,20,26,127, +21,248,148,189,155,21,213,21,224,12,199,195,119,163,204,197,221,101,183, +183,104,122,31,118,211,185,7,162,90,26,129,28,96,44,16,214,119,51,249,251, +125,119,112,216,121,41,44,58,2,2,163,220,232,238,68,0,90,55,103,99,158, +239,124,28,177,243,1,118,217,233,184,251,162,237,0,120,190,243,44,76,126, +234,226,52,167,47,95,26,138,237,199,219,15,236,111,109,135,236,242,23,128, +123,178,147,202,197,173,145,122,248,180,156,155,191,195,217,212,149,161, +4,246,170,175,249,182,248,50,92,246,29,235,37,140,99,36,59,196,81,28,5, +214,243,157,140,81,184,74,100,208,107,6,72,70,39,192,148,1,206,71,199,47, +227,134,104,17,24,160,29,161,64,219,0,245,8,63,114,221,160,186,25,25,189, +72,205,120,98,43,128,31,1,191,119,194,120,85,39,89,89,106,54,210,249,2, +7,179,255,247,239,255,230,29,116,58,67,142,138,247,125,130,70,22,99,229, +181,150,3,96,3,125,234,91,185,5,140,117,95,216,223,218,14,207,151,227,96, +79,173,183,240,43,15,46,212,138,95,16,189,253,159,172,10,4,153,75,148,87, +191,254,17,56,137,141,226,43,129,71,64,240,79,228,34,15,39,42,133,234,192, +200,252,156,206,167,3,97,181,215,174,97,109,17,163,179,19,235,197,218,192, +200,4,136,187,203,110,231,164,153,82,120,14,120,195,116,13,186,130,245, +167,195,228,3,111,21,93,28,38,93,6,101,6,97,18,136,117,151,64,235,192,166, +99,125,55,86,94,107,13,226,248,9,156,77,179,166,75,139,17,212,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_6 = 1144; +static unsigned char xml_res_file_6[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,3,134,70,97,9,0,0,4,5,73,68,65,84,72,199,149, +150,125,76,213,85,24,199,63,231,220,223,21,132,139,74,76,96,23,68,4,2,95, +74,36,204,149,185,28,80,54,112,75,237,143,182,107,184,114,174,173,53,179, +172,173,218,154,110,218,250,167,245,178,176,173,63,154,171,41,190,76,231, +31,10,182,53,2,172,54,209,25,34,182,188,18,112,167,128,225,11,239,92,64, +238,203,239,233,15,188,183,251,194,5,122,254,59,231,57,207,247,123,206, +247,60,207,121,142,98,6,43,174,59,149,101,106,223,22,165,216,12,100,3,153, +143,92,61,192,45,68,106,45,134,62,123,101,163,163,59,22,134,154,110,178, +176,254,84,134,69,249,247,131,236,2,44,204,108,38,74,157,49,225,195,107, +37,142,91,179,18,20,55,30,223,42,194,81,192,198,255,179,81,65,85,182,148, +58,206,197,36,40,110,60,246,174,136,250,10,208,161,243,217,9,11,88,155, +156,74,122,92,34,94,49,233,28,27,230,210,64,47,110,159,55,234,52,10,181, +183,185,212,81,21,69,240,104,231,103,66,193,87,36,61,198,222,188,34,138, +23,165,70,109,215,47,66,205,93,23,135,58,91,25,242,78,134,145,8,106,91, +224,36,10,96,117,99,117,166,33,218,25,42,203,54,123,46,31,231,175,197,80, +83,124,109,238,65,122,31,142,97,85,154,60,219,34,210,226,18,0,24,244,78, +242,246,181,6,254,118,15,133,203,229,83,203,91,54,57,254,49,0,12,209,7, +67,193,95,74,93,202,39,5,235,80,192,197,129,94,190,104,111,230,246,248, +104,48,90,43,197,51,201,233,124,148,191,150,204,249,54,190,91,83,202,27, +205,117,116,79,4,215,36,97,145,3,192,155,170,184,238,84,150,88,124,174, +208,108,249,105,253,22,210,226,18,168,185,235,226,128,243,50,18,227,86, +19,13,43,223,23,149,81,96,75,230,226,64,47,239,180,94,8,83,209,167,204, +108,139,125,231,43,175,3,21,161,158,206,177,97,58,198,134,249,214,213,138, +57,67,218,236,206,41,36,101,94,60,233,241,137,44,153,159,196,170,5,41,60, +151,98,231,215,190,59,8,104,173,180,75,11,82,30,25,120,105,224,46,71,186, +156,248,69,102,204,203,62,207,4,133,11,23,7,199,27,82,236,120,76,63,230, +163,56,17,169,208,160,242,34,3,173,90,163,149,154,53,241,143,117,183,113, +99,116,32,56,238,247,60,228,155,142,107,161,53,144,171,65,210,35,3,63,91, +185,158,183,150,61,57,43,129,41,194,193,155,151,241,201,148,144,159,183, +55,51,226,243,132,46,201,48,34,131,54,164,216,41,91,188,4,191,8,245,247, +187,105,115,15,206,72,210,238,30,226,72,151,147,2,91,50,191,220,239,138, +46,188,226,134,227,109,2,249,129,172,56,189,174,34,152,227,109,238,65,118, +252,241,243,172,119,161,149,194,80,26,143,233,143,116,221,212,2,174,192, +104,79,206,154,32,56,64,129,45,25,71,102,193,156,164,154,6,28,1,151,70, +228,124,160,164,19,12,131,11,125,61,193,5,127,141,244,135,17,78,103,86, +173,217,157,83,200,166,212,172,232,147,137,212,106,139,161,207,2,126,1, +246,221,104,226,131,63,127,15,106,153,100,157,199,15,93,55,102,148,230, +211,21,207,178,115,233,74,222,207,123,42,210,237,243,106,169,209,87,54, +58,186,21,234,199,80,207,151,29,87,185,55,57,78,214,252,36,78,62,93,78, +121,90,54,243,116,216,3,203,19,11,82,56,92,244,2,47,166,102,225,49,77,246, +59,155,34,9,14,95,47,169,236,81,255,53,24,159,19,72,10,120,3,111,140,61, +62,17,128,49,159,23,215,248,48,94,211,196,30,111,35,61,126,74,186,135,126, +63,251,156,77,52,60,8,107,106,35,202,240,47,111,126,126,71,111,176,154, +138,234,79,150,43,101,214,132,190,73,9,22,131,93,217,171,120,53,227,113, +18,44,214,168,139,253,173,255,14,85,157,173,220,30,31,9,239,112,194,214, +171,101,219,107,162,27,78,195,137,61,130,124,29,217,112,172,90,83,180,112, +49,185,137,139,176,40,197,189,201,113,90,134,30,208,231,153,152,46,161, +222,107,41,219,126,40,102,203,44,106,56,241,178,66,170,67,229,154,163,141, +160,204,215,174,150,84,214,134,37,66,228,170,150,82,199,57,49,140,92,65, +170,0,223,28,128,77,144,163,202,240,47,143,4,143,249,171,8,216,234,198, +234,76,3,203,22,48,55,35,106,89,232,183,101,170,136,56,239,85,230,185,235, +37,149,61,177,48,254,5,68,165,141,10,108,236,250,76,0,0,0,0,73,69,78,68, +174,66,96,130}; + +static size_t xml_res_size_7 = 59686; +static unsigned char xml_res_file_7[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, +32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, +116,115,46,111,114,103,47,116,114,117,110,107,47,111,118,101,114,118,105, +101,119,95,120,114,99,102,111,114,109,97,116,46,104,116,109,108,32,45,45, +62,10,60,114,101,115,111,117,114,99,101,32,120,109,108,110,115,61,34,104, +116,116,112,58,47,47,119,119,119,46,119,120,119,105,100,103,101,116,115, +46,111,114,103,47,119,120,120,114,99,34,32,118,101,114,115,105,111,110, +61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, +61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,100, +114,105,118,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,70,76,79,80, +80,89,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,100,105,115,107,46,112,110,103,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77, +65,80,95,67,68,82,79,77,34,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,99,100,46,112,110,103,60,47, +111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61, +34,116,111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86, +73,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101, +61,34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,112,108,97,121,50,52,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, +82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, +62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, +111,110,115,95,112,97,117,115,101,50,52,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,117,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116, +111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,83,84,79, +80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,115, +116,111,112,50,52,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,116,111,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,116,111,111,108,34,32, +110,97,109,101,61,34,84,79,79,76,66,65,82,95,82,69,83,69,84,34,62,10,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,114,101,102,114,101, +115,104,50,52,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,114,101,115,101,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97, +110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,34,32, +115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, +95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77, +95,86,73,68,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,49,50,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,34,32,115,116, +97,114,116,61,34,49,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97, +110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68, +69,82,95,68,82,73,86,69,82,34,32,115,116,97,114,116,61,34,49,52,48,48,34, +47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, +117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, +118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, +67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, +84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, +98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116, +111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,83,72,79,87,95,77,65,67,72,73,78,69,95,79,78,95,83, +84,65,82,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,111,110,32,115,116,97,114,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, +47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,111,110, +102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,79,78,70,73, +71,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104, +105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,72,68,67,79,78,70,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,72,97,114,100,32,100,105,115,99,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,77,105,115,99,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,82,69,83,69,84,95,67,79,78,70,73,82,77,65,84,73,79,78,95, +68,73,65,76,79,71,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,82,101,115,101,116,32,99,111,110,102,105,114,109,97,116,105,111, +110,32,100,105,97,108,111,103,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111, +114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,65,66,79,85,84,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,65,98,111,117,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +34,32,110,97,109,101,61,34,109,97,105,110,95,109,101,110,117,34,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,121, +115,116,101,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,72,82, +69,83,69,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +72,97,114,100,32,82,101,115,101,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,82,69, +83,69,84,95,67,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,67,116,114,108,43,65,108,116,43,68,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,68,105,115,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,68,73,83,67,95,65,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,104,97,110,103,101,32,100,114,105,118,101,32,95,65,58,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,68,73,83,67,95,66,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,104,97,110,103,101,32,100,114,105,118,101,32,95, +66,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,69,74,69,67,84,95,65,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,69,106,101,99,116,32,100,114,105,118, +101,32,65,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,69,74,69,67,84,95,66,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,69,106,101,99,116,32,100,114,105,118,101, +32,66,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,66,80,66, +95,68,73,83,65,66,76,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,105,115,97,98,108,101,32,66,80,66,32,99,104,101,99,107,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68, +77,95,67,68,82,79,77,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95, +73,77,65,71,69,95,76,79,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,76,111,97,100,32,105,109,97,103,101,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,68,73,83,65, +66,76,69,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +68,105,115,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95, +69,77,80,84,89,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,69,109,112,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,73,77, +65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73, +109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,105,100,101,111,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,82,69,83,73,90,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,101,115,105,122,97,98,108,101,32,119,105,110,100,111,119, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,77, +69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112,59,38, +97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49, +60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101,32, +102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, +116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, +76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, +117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,114,101,116,99,104,32,109,111,100,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112, +105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, +67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, +116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110,32, +109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, +95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,66,111,114,100,101,114,108,101,115,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,120,99, +108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,76,79,83,84,95,70,79, +67,85,83,95,68,73,77,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,68,105,109,32,100,105,115,112,108,97,121,32,111,110,32,108,111, +115,116,32,102,111,99,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99, +107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,82,101,110,100,101,114,32,100,114,105, +118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78, +68,69,82,95,68,82,73,86,69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,117,116,111,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105, +114,101,99,116,51,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, +73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,111,102,116,119,97,114,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98, +108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +77,97,99,104,105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76, +69,95,69,88,73,84,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +83,116,111,112,32,101,109,117,108,97,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111, +110,102,105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,116,105, +116,108,101,62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, +62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,33,45,45,32,109,97,99,104,105,110,101,32,45,45,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111, +32,115,112,101,101,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,105,100,101,111,32,115,112,101,101,100,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,112,117, +32,116,121,112,101,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85, +32,116,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, +79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,33,45,45,32,99,112,117,32,116,121,112,101,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,100,121, +110,97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,32,45,45,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67, +75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99,32,82,101,99, +111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,119,97,105, +116,115,116,97,116,101,115,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,115,111,117,110, +100,32,99,97,114,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111, +117,110,100,32,99,97,114,100,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, +45,45,32,72,68,68,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +33,45,45,32,70,68,68,49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,68,68,49,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +77,66,79,68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32, +124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,33,45,45,32,70,68,68,50,32,45,45,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,33,45,45,32,109,101,109,111,114,121,32,45,45, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73, +78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,83,80,95,72,79,82,73,90,79,78,84,65,76, +124,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,53,48,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,48, +60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,97,120,62,50,48,48,60,47,109,97,120,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, +77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,109,111,117,115,101,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,115,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85,83,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +33,45,45,32,84,79,68,79,58,32,106,111,121,115,116,105,99,107,32,45,45,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,109,115,32,47, +32,103,97,109,101,32,98,108,97,115,116,101,114,32,45,45,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,33,45,45,32,71,114,97,118,105,115,32,85,108,116,114, +97,115,111,117,110,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118, +105,115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, +45,45,32,73,110,110,111,118,97,116,105,111,110,32,83,83,73,45,50,48,48, +49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110, +32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,69,110,97, +98,108,101,32,116,105,109,101,32,115,121,110,99,32,45,45,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89, +78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,121,110,99,104,114,111,110,105,115,101,32,116,105,109, +101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,33,45,45,32,86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,32, +45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, +72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114, +97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79, +68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110, +99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,80, +65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105,100, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, +60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, +70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, +74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, +69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, +48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, +61,34,49,48,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61, +34,72,100,67,111,110,102,68,108,103,34,62,10,32,32,32,32,60,116,105,116, +108,101,62,67,111,110,102,105,103,117,114,101,32,72,97,114,100,32,68,105, +115,99,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, +101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68, +67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, +105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,78,69,87,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, +84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, +48,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,69,74,69,67,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, +67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,84,69,88,84,95,83,73,90,69,91,49,93,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, +105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,50,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,78,69,87,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, +84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, +50,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,51,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,69,74,69,67,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, +67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,84,69,88,84,95,83,73,90,69,91,51,93,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, +108,111,103,34,32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100, +32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101, +110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, +76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,50,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,51,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, +122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100, +83,105,122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62, +72,97,114,100,32,100,105,115,99,32,112,97,114,97,109,101,116,101,114,115, +60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101, +100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105, +116,105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97, +115,101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, +68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84, +49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,67,111,110,102,105,103,117,114,101,83,101,108,101,99,116,105, +111,110,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67, +101,109,32,67,111,110,102,105,103,117,114,97,116,105,111,110,32,77,97,110, +97,103,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110, +116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76, +34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82, +73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73, +83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,50,48,48,44,51,48,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, +111,97,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,78,101,119,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,110,97,109, +101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,101,108,101,116,101,46,46,46,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,67,79,78,70,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,46,46,46, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,105,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102, +105,114,109,82,101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115, +116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79, +78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61,34,119,120,65, +82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68, +67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,78,70,73,82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, +82,77,95,82,69,77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,65,98,111,117,116,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,99,101, +110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, +76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,67,101, +109,32,118,49,50,92,110,104,116,116,112,115,58,47,47,112,99,101,109,45, +101,109,117,108,97,116,111,114,46,99,111,46,117,107,47,92,110,92,110,84, +104,105,115,32,112,114,111,103,114,97,109,32,105,115,32,108,105,99,101, +110,115,101,100,32,117,110,100,101,114,32,116,104,101,32,71,78,85,32,71, +101,110,101,114,97,108,32,80,117,98,108,105,99,32,76,105,99,101,110,115, +101,32,118,101,114,115,105,111,110,32,50,46,92,110,83,101,101,32,67,79, +80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100,101,116,97,105, +108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105,99,111,110,115, +32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99,111,110,115,32, +40,104,116,116,112,115,58,47,47,114,111,117,110,100,105,99,111,110,115, +46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46,102,108,97,116, +105,99,111,110,46,99,111,109,92,110,83,116,97,116,117,115,45,105,99,111, +110,115,32,109,97,100,101,32,98,121,32,77,97,114,107,32,74,97,109,101,115, +32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,109,102,97,109,102, +97,109,46,99,111,109,47,108,97,98,47,105,99,111,110,115,47,115,105,108, +107,47,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_disk.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_play24.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_pause24.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_stop24.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_refresh24.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$pc.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$pc.xrc")); +} diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c new file mode 100644 index 0000000..b0fe236 --- /dev/null +++ b/src/wx-sdl2-display.c @@ -0,0 +1,755 @@ +#include +#include "wx-sdl2-video.h" +#include "wx-utils.h" +#include "ibm.h" +#include "video.h" +#include "wx-display.h" +#include "plat-keyboard.h" + +#ifdef __WINDOWS__ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +HHOOK hKeyboardHook; +int modkeystate[255]; + +#endif + +SDL_mutex* rendererMutex; +SDL_cond* rendererCond; +SDL_Thread* renderthread = NULL; + +SDL_Window* window = NULL; + +int rendering = 0; + +int mousecapture = 0; + +extern int pause; +extern int video_scale; + +void* ghwnd; +void* menu; + +SDL_Rect remembered_rect; +int remembered_mouse_x = 0; +int remembered_mouse_y = 0; + +int win_doresize = 0; +int winsizex = 640, winsizey = 480; + +void renderer_start(); +void renderer_stop(int timeout); + +int trigger_fullscreen = 0; +int trigger_togglewindow = 0; +int trigger_inputrelease = 0; + +extern void device_force_redraw(); +extern void mouse_wheel_update(int); +extern void toggle_fullscreen(); + +void display_resize(int width, int height) +{ + /* Video scaling-code is borrowed from 86Box */ + switch(video_scale) + { + case 0: + winsizex = width >> 1; + winsizey = height >> 1; + break; + case 2: + winsizex = (width * 3) >> 1; + winsizey = (height * 3) >> 1; + break; + case 3: + winsizex = width << 1; + winsizey = height << 1; + break; + case 1: + default: + winsizex = width; + winsizey = height; + break; + } + + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = winsizex; + rect.h = winsizey; + sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); + winsizex = rect.w; + winsizey = rect.h; + + win_doresize = 1; +} + +void releasemouse() +{ + if (mousecapture) + { + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + mousecapture = 0; + } +} + +int display_init() +{ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) + { + printf("SDL could not initialize! Error: %s\n", SDL_GetError()); + return 0; + } + + SDL_version ver; + SDL_GetVersion(&ver); + printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); + return 1; +} + +void display_close() +{ + SDL_Quit(); +} + +void display_start(void* hwnd) +{ + ghwnd = hwnd; + menu = wx_getmenu(hwnd); + atexit(releasemouse); + rendererMutex = SDL_CreateMutex(); + rendererCond = SDL_CreateCond(); + renderer_start(); +} + +void display_stop() +{ + renderer_stop(10 * 1000); + + SDL_DestroyMutex(rendererMutex); + SDL_DestroyCond(rendererCond); +#if SDL_VERSION_ATLEAST(2, 0, 2) + SDL_DetachThread(renderthread); +#endif + releasemouse(); +} + +int is_fullscreen() +{ + int flags = SDL_GetWindowFlags(window); + return (flags&SDL_WINDOW_FULLSCREEN) || (flags&SDL_WINDOW_FULLSCREEN_DESKTOP); +} + +void sdl_set_window_title(const char* title) { + if (window) + SDL_SetWindowTitle(window, title); +} + +int get_border_size(int* top, int* left, int* bottom, int* right) +{ +#if SDL_VERSION_ATLEAST(2, 0, 5) + return SDL_GetWindowBordersSize(window, top, left, bottom, right); +#else + if (top) *top = 0; + if (left) *left = 0; + if (bottom) *bottom = 0; + if (right) *right = 0; + return 0; +#endif +} + +static const struct { + SDL_Scancode sdl; + int system; +} SDLScancodeToSystemScancode[] = { + { SDL_SCANCODE_A, 0x1e }, + { SDL_SCANCODE_B, 0x30 }, + { SDL_SCANCODE_C, 0x2e }, + { SDL_SCANCODE_D, 0x20 }, + { SDL_SCANCODE_E, 0x12 }, + { SDL_SCANCODE_F, 0x21 }, + { SDL_SCANCODE_G, 0x22 }, + { SDL_SCANCODE_H, 0x23 }, + { SDL_SCANCODE_I, 0x17 }, + { SDL_SCANCODE_J, 0x24 }, + { SDL_SCANCODE_K, 0x25 }, + { SDL_SCANCODE_L, 0x26 }, + { SDL_SCANCODE_M, 0x32 }, + { SDL_SCANCODE_N, 0x31 }, + { SDL_SCANCODE_O, 0x18 }, + { SDL_SCANCODE_P, 0x19 }, + { SDL_SCANCODE_Q, 0x10 }, + { SDL_SCANCODE_R, 0x13 }, + { SDL_SCANCODE_S, 0x1f }, + { SDL_SCANCODE_T, 0x14 }, + { SDL_SCANCODE_U, 0x16 }, + { SDL_SCANCODE_V, 0x2f }, + { SDL_SCANCODE_W, 0x11 }, + { SDL_SCANCODE_X, 0x2d }, + { SDL_SCANCODE_Y, 0x15 }, + { SDL_SCANCODE_Z, 0x2c }, + { SDL_SCANCODE_0, 0x0B }, + { SDL_SCANCODE_1, 0x02 }, + { SDL_SCANCODE_2, 0x03 }, + { SDL_SCANCODE_3, 0x04 }, + { SDL_SCANCODE_4, 0x05 }, + { SDL_SCANCODE_5, 0x06 }, + { SDL_SCANCODE_6, 0x07 }, + { SDL_SCANCODE_7, 0x08 }, + { SDL_SCANCODE_8, 0x09 }, + { SDL_SCANCODE_9, 0x0A }, + { SDL_SCANCODE_GRAVE, 0x29 }, + { SDL_SCANCODE_MINUS, 0x0c }, + { SDL_SCANCODE_EQUALS, 0x0d }, + { SDL_SCANCODE_NONUSBACKSLASH, 0x56 }, + { SDL_SCANCODE_BACKSLASH, 0x2b }, + { SDL_SCANCODE_BACKSPACE, 0x0e }, + { SDL_SCANCODE_SPACE, 0x39 }, + { SDL_SCANCODE_TAB, 0x0f }, + { SDL_SCANCODE_CAPSLOCK, 0x3a }, + { SDL_SCANCODE_LSHIFT, 0x2a }, + { SDL_SCANCODE_LCTRL, 0x1d }, + { SDL_SCANCODE_LGUI, 0xdb }, + { SDL_SCANCODE_LALT, 0x38 }, + { SDL_SCANCODE_RSHIFT, 0x36 }, + { SDL_SCANCODE_RCTRL, 0x9d }, + { SDL_SCANCODE_RGUI, 0xdc }, + { SDL_SCANCODE_RALT, 0xb8 }, + { SDL_SCANCODE_SYSREQ, 0x54 }, + { SDL_SCANCODE_APPLICATION, 0xdd }, + { SDL_SCANCODE_RETURN, 0x1c }, + { SDL_SCANCODE_ESCAPE, 0x01 }, + { SDL_SCANCODE_F1, 0x3B }, + { SDL_SCANCODE_F2, 0x3C }, + { SDL_SCANCODE_F3, 0x3D }, + { SDL_SCANCODE_F4, 0x3e }, + { SDL_SCANCODE_F5, 0x3f }, + { SDL_SCANCODE_F6, 0x40 }, + { SDL_SCANCODE_F7, 0x41 }, + { SDL_SCANCODE_F8, 0x42 }, + { SDL_SCANCODE_F9, 0x43 }, + { SDL_SCANCODE_F10, 0x44 }, + { SDL_SCANCODE_F11, 0x57 }, + { SDL_SCANCODE_F12, 0x58 }, + { SDL_SCANCODE_SCROLLLOCK, 0x46 }, + { SDL_SCANCODE_LEFTBRACKET, 0x1a }, + { SDL_SCANCODE_RIGHTBRACKET, 0x1b }, + { SDL_SCANCODE_INSERT, 0xd2 }, + { SDL_SCANCODE_HOME, 0xc7 }, + { SDL_SCANCODE_PAGEUP, 0xc9 }, + { SDL_SCANCODE_DELETE, 0xd3 }, + { SDL_SCANCODE_END, 0xcf }, + { SDL_SCANCODE_PAGEDOWN, 0xd1 }, + { SDL_SCANCODE_UP, 0xc8 }, + { SDL_SCANCODE_LEFT, 0xcb }, + { SDL_SCANCODE_DOWN, 0xd0 }, + { SDL_SCANCODE_RIGHT, 0xcd }, + { SDL_SCANCODE_NUMLOCKCLEAR, 0x45 }, + { SDL_SCANCODE_KP_DIVIDE, 0xb5 }, + { SDL_SCANCODE_KP_MULTIPLY, 0x37 }, + { SDL_SCANCODE_KP_MINUS, 0x4a }, + { SDL_SCANCODE_KP_PLUS, 0x4e }, + { SDL_SCANCODE_KP_ENTER, 0x9c }, + { SDL_SCANCODE_KP_PERIOD, 0x53 }, + { SDL_SCANCODE_KP_0, 0x52 }, + { SDL_SCANCODE_KP_1, 0x4f }, + { SDL_SCANCODE_KP_2, 0x50 }, + { SDL_SCANCODE_KP_3, 0x51 }, + { SDL_SCANCODE_KP_4, 0x48 }, + { SDL_SCANCODE_KP_5, 0x4c }, + { SDL_SCANCODE_KP_6, 0x4d }, + { SDL_SCANCODE_KP_7, 0x47 }, + { SDL_SCANCODE_KP_8, 0x48 }, + { SDL_SCANCODE_KP_9, 0x49 }, + { SDL_SCANCODE_SEMICOLON, 0x27 }, + { SDL_SCANCODE_APOSTROPHE, 0x28 }, + { SDL_SCANCODE_COMMA, 0x33 }, + { SDL_SCANCODE_PERIOD, 0x34 }, + { SDL_SCANCODE_SLASH, 0x35 }, + { SDL_SCANCODE_PRINTSCREEN, 0xb7 } +}; + +int sdl_scancode(SDL_Scancode scancode) +{ + int i; + for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { + if (SDLScancodeToSystemScancode[i].sdl == scancode) { + return SDLScancodeToSystemScancode[i].system; + } + } + return -1; +} + +SDL_Event event; +SDL_Rect rect; +int border_x, border_y = 0; + +uint64_t render_time = 0; +int render_fps = 0; +uint32_t render_frame_time = 0; +uint32_t render_frames = 0; + +void window_setup() +{ + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); +#if SDL_VERSION_ATLEAST(2, 0, 5) + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); +#endif + + if (start_in_fullscreen) + { + start_in_fullscreen = 0; + window_dofullscreen = 1; + window_doinputgrab = 1; + } + + if (window_remember) + { + rect.x = window_x; + rect.y = window_y; + rect.w = window_w; + rect.h = window_h; + } + else + { + rect.x = SDL_WINDOWPOS_CENTERED; + rect.y = SDL_WINDOWPOS_CENTERED; + rect.w = 640; + rect.h = 480; + } +} + +#ifdef __WINDOWS__ +int sdl_winhook(int code) +{ + switch(code) + { + case VK_LMENU: + return SDL_SCANCODE_LALT; + case VK_LCONTROL: + return SDL_SCANCODE_LCTRL; + case VK_LWIN: + return SDL_SCANCODE_LGUI; + case VK_LSHIFT: + return SDL_SCANCODE_LSHIFT; + case VK_RMENU: + return SDL_SCANCODE_RALT; + case VK_RCONTROL: + return SDL_SCANCODE_RCTRL; + case VK_RWIN: + return SDL_SCANCODE_RGUI; + case VK_RSHIFT: + return SDL_SCANCODE_RSHIFT; + } + + return -1; +} + +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam; + + int c = p->vkCode; + + int steal = 0; + int s = sdl_winhook(c); + if (s != -1) + { + int key_state = !(p->flags & LLKHF_UP); + if (abs(modkeystate[c]) != key_state) + { + /* if mousecapture is 0, key_state should be negative */ + if (!mousecapture) + key_state = -key_state; + /* if key_state is 0 and modkeystate[c] is negative, + an sdl_event should not generated */ + if (key_state > 0 || modkeystate[c] > 0) + { + steal = 1; + SDL_Event event; + event.key.keysym.scancode = s; + + event.type = key_state ? SDL_KEYDOWN : SDL_KEYUP; + SDL_PushEvent(&event); + } + modkeystate[c] = key_state; + } + if (steal) + return 1; + } + + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); +} +#endif + +int window_create() +{ + window = SDL_CreateWindow("PCem Display", + rect.x, rect.y, rect.w, rect.h, + vid_resize ? SDL_WINDOW_RESIZABLE : 0); + if (!window) + { + char message[200]; + sprintf(message, + "SDL window could not be created! Error: %s\n", + SDL_GetError()); + wx_messagebox(ghwnd, message, "SDL Error", WX_MB_OK); + return 0; + } + +#ifdef __WINDOWS__ + memset(modkeystate, 0, sizeof(modkeystate)); + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); +#endif + + render_time = 0; + render_fps = 0; + render_frame_time = SDL_GetTicks(); + render_frames = 0; + return 1; +} + +void window_close() +{ +#ifdef __WINDOWS__ + UnhookWindowsHookEx( hKeyboardHook ); +#endif + + sdl_renderer_close(); + + if (window) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_GetWindowSize(window, &rect.w, &rect.h); + get_border_size(&border_y, &border_x, 0, 0); + rect.x -= border_x; + rect.y -= border_y; + + SDL_DestroyWindow(window); + } + window = NULL; +} + +int render() +{ + uint64_t start_time = timer_read(); + uint64_t end_time; + + if (window_doreset) + { + pclog("window_doreset\n"); + window_doreset = 0; + renderer_doreset = 0; + return 0; + } + if (renderer_doreset) + { + pclog("renderer_doreset\n"); + renderer_doreset = 0; + sdl_renderer_close(); + sdl_renderer_init(window); + + device_force_redraw(); + video_wait_for_blit(); + } + while(SDL_PollEvent(&event)) + { + switch (event.type) { + case SDL_MOUSEBUTTONUP: + if (!mousecapture) + { + if (event.button.button == SDL_BUTTON_LEFT && !pause) + { + window_doinputgrab = 1; + if (video_fullscreen) { + window_dofullscreen = 1; + } + } else if (event.button.button == SDL_BUTTON_RIGHT) + { + wx_popupmenu(ghwnd, menu, 0, 0); + } + } + break; + case SDL_MOUSEWHEEL: + if (mousecapture) mouse_wheel_update(event.wheel.y); + break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_CLOSE) { + wx_stop_emulation(ghwnd); + } + if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) + { + if (is_fullscreen()) + window_dowindowed = 1; + window_doinputrelease = 1; + } + + if (window_remember) { + int flags = SDL_GetWindowFlags(window); + if (!(flags&SDL_WINDOW_FULLSCREEN) && !(flags&SDL_WINDOW_FULLSCREEN_DESKTOP)) { + if (event.window.event == SDL_WINDOWEVENT_MOVED) { + get_border_size(&border_x, &border_y, 0, 0); + window_x = event.window.data1-border_x; + window_y = event.window.data2-border_y; + } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + window_w = event.window.data1; + window_h = event.window.data2; + } + //save_window_pos = 1; + } + } + + break; + case SDL_KEYDOWN: + { +#ifdef __WINDOWS__ + /* international keyboard workaround */ + if (event.key.keysym.scancode == SDL_SCANCODE_RALT && + (event.key.keysym.mod&KMOD_LCTRL) && + event.key.timestamp == rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)]) + rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] = 0; +#endif + int key_idx = sdl_scancode(event.key.keysym.scancode); + if (key_idx != -1) + rawinputkey[key_idx] = 1; + break; + } + case SDL_KEYUP: + { + int key_idx = sdl_scancode(event.key.keysym.scancode); + if (key_idx != -1) + rawinputkey[key_idx] = 0; + break; + } + } + } + if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_fullscreen = 1; + else if (trigger_fullscreen) + { + trigger_fullscreen = 0; + toggle_fullscreen(); + } +// if (event.key.keysym.scancode == SDL_SCANCODE_PAGEUP && +// (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && +// (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) +// trigger_togglewindow = 1; +// else if (trigger_togglewindow) +// { +// trigger_togglewindow = 0; +// wx_togglewindow(ghwnd); +// } + else if (event.key.keysym.scancode == SDL_SCANCODE_END && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) + trigger_inputrelease = 1; + else if (trigger_inputrelease) + { + trigger_inputrelease = 0; + if (!is_fullscreen()) + window_doinputrelease = 1; + } + if (window_doremember) { + window_doremember = 0; + SDL_GetWindowPosition(window, &window_x, &window_y); + SDL_GetWindowSize(window, &window_w, &window_h); + get_border_size(&border_y, &border_x, 0, 0); + window_x -= border_x; + window_y -= border_y; + saveconfig(NULL); + } + + if (window_dotogglefullscreen) + { + window_dotogglefullscreen = 0; + if (SDL_GetWindowGrab(window) || is_fullscreen()) + { + window_doinputrelease = 1; + if (is_fullscreen()) + window_dowindowed = 1; + } + else + { + window_doinputgrab = 1; + window_dofullscreen = 1; + } + } + + if (window_dofullscreen) + { + window_dofullscreen = 0; + video_wait_for_blit(); + SDL_RaiseWindow(window); +#if SDL_VERSION_ATLEAST(2, 0, 4) + SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); +#endif + SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); + get_border_size(&border_y, &border_x, 0, 0); + remembered_rect.x -= border_x; + remembered_rect.y -= border_y; + SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); + SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + } + if (window_doinputgrab) { + window_doinputgrab = 0; + mousecapture = 1; + SDL_GetRelativeMouseState(0, 0); + SDL_SetWindowGrab(window, SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); + } + + if (window_doinputrelease) { + window_doinputrelease = 0; + mousecapture = 0; + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + } + if (window_dowindowed) + { + window_dowindowed = 0; + SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); + SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); +#if SDL_VERSION_ATLEAST(2, 0, 4) + SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); +#endif + } + + if (win_doresize) + { + win_doresize = 0; + if (!vid_resize || (flags&SDL_WINDOW_FULLSCREEN)) { + SDL_GetWindowSize(window, &rect.w, &rect.h); + if (rect.w != winsizex || rect.h != winsizey) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_SetWindowSize(window, winsizex, winsizey); + SDL_SetWindowPosition(window, rect.x, rect.y); + device_force_redraw(); + } + } + } + + if (sdl_renderer_update(window)) sdl_renderer_present(window); + + end_time = timer_read(); + render_time += end_time - start_time; + + ++render_frames; + uint32_t ticks = SDL_GetTicks(); + if (ticks-render_frame_time >= 1000) { + render_fps = render_frames/((ticks-render_frame_time)/1000.0); + render_frames = 0; + render_frame_time = ticks; + } + + return 1; +} + +int renderer_thread(void* params) +{ + int internal_rendering; + + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); + + window_setup(); + + rendering = 1; + while (rendering) { + + if (!window_create()) + rendering = 0; + + renderer_doreset = 1; + internal_rendering = 1; + while (rendering && internal_rendering) + { + if (!render()) + internal_rendering = 0; + + SDL_Delay(1); + } + window_close(); + } + + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); + + return SDL_TRUE; +} + +void* timer = 0; + +void render_timer() +{ +#ifdef PCEM_RENDER_TIMER_LOOP + /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ + renderer_thread(0); +#else + if (rendering && !render()) + { + window_close(); + window_create(); + renderer_doreset = 1; + } +#endif +} + +void render_start_timer() +{ +#ifdef PCEM_RENDER_TIMER_LOOP + timer = wx_createtimer(render_timer); + wx_starttimer(timer, 500, 1); +#else + window_setup(); + if (window_create()) + { + rendering = 1; + renderer_doreset = 1; + wx_starttimer(timer, 1, 0); + } +#endif +} + +void renderer_start() +{ + if (!rendering) + { +#ifdef PCEM_RENDER_WITH_TIMER + render_start_timer(); +#else + SDL_LockMutex(rendererMutex); + renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); +#endif + } +} + +void renderer_stop(int timeout) +{ +#if defined(PCEM_RENDER_WITH_TIMER) && !defined(PCEM_RENDER_TIMER_LOOP) + rendering = 0; + window_close(); + wx_destroytimer(timer); +#else + if (rendering) + { + SDL_LockMutex(rendererMutex); + rendering = 0; + if (timeout) + SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); + else + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); + renderthread = NULL; + } + if (timer) + wx_destroytimer(timer); +#endif +} diff --git a/src/wx-sdl2-hdconf.c b/src/wx-sdl2-hdconf.c new file mode 100644 index 0000000..f462cb1 --- /dev/null +++ b/src/wx-sdl2-hdconf.c @@ -0,0 +1,956 @@ +#include "wx-utils.h" +#include "wx-sdl2.h" + +#include "ibm.h" +#include "ide.h" +#include "hdd.h" + +static struct +{ + int cylinders; + int heads; +} hd_types[] = +{ + {306, 4}, {615, 4}, {615, 6}, {940, 8}, + {940, 6}, {615, 4}, {462, 8}, {733, 5}, + {900, 15}, {820, 3}, {855, 5}, {855, 7}, + {306, 8}, {733, 7}, {0, 0}, {612, 4}, + {977, 5}, {977, 7}, {1024, 7}, {733, 5}, + {733, 7}, {733, 5}, {306, 4}, {925, 7}, + {925, 9}, {754, 7}, {754, 11}, {699, 7}, + {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, + {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, + {615, 8}, {987, 3}, {462, 7}, {820, 6}, + {977, 5}, {981, 5}, {830, 7}, {830, 10}, + {917, 15}, {1224, 15} +}; + +static int hd_changed = 0; + +static char hd_new_name[512]; +static int hd_new_spt, hd_new_hpc, hd_new_cyl; +static int hd_new_type; +static int new_cdrom_channel; + +extern int pause; + +static void check_hd_type(off64_t sz) +{ + int c; + + hd_new_type = 0; + + if (hdd_controller_current_is_mfm()) + { + for (c = 0; c < 46; c++) + { + if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) + { + hd_new_spt = 17; + hd_new_hpc = hd_types[c].heads; + hd_new_cyl = hd_types[c].cylinders; + hd_new_type = c+1; + return; + } + } + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + else + { + if ((sz % 17) == 0 && sz <= 133693440) + { + hd_new_spt = 17; + + if (sz <= 26738688) + hd_new_hpc = 4; + else if (sz <= 53477376) + hd_new_hpc = 6; + else if (sz <= 71303168) + hd_new_hpc = 8; + else + hd_new_hpc = 15; + + hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; + } + else + { + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + } +} + +#define ID_IS(s) wParam == wx_xrcid(s) +#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) + +static void update_hdd_cdrom(void* hdlg) +{ + void* h; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[0]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 0) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[0]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 0) ? 1 : 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[1]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 1) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[1]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 1) ? 1 : 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[2]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 2) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[2]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 2) ? 1 : 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[3]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 3) ? 0 : 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[3]")); + wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 3) ? 1 : 0, 0); +} + +static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + int c; + PcemHDC hd[4]; + FILE *f; + uint8_t buf[512]; + int hd_type; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", 63); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", 16); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", 511); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)""); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (((511*16*63)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + +// hd_type = 0; + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)hd_new_name); + if (!hd_new_name[0]) + { + wx_messagebox(NULL,"Please enter a valid filename","PCem error",WX_MB_OK); + return TRUE; + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); + + if (hd_new_spt > 63) + { + wx_messagebox(NULL, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) + { + wx_messagebox(NULL, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > 16383) + { + wx_messagebox(NULL, "Drive has too many cylinders (maximum is 16383)", "PCem error", WX_MB_OK); + return TRUE; + } + + f = fopen64(hd_new_name, "wb"); + if (!f) + { + wx_messagebox(NULL, "Can't open file for write", "PCem error", WX_MB_OK); + return TRUE; + } + memset(buf, 0, 512); + for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) + fwrite(buf, 512, 1, f); + fclose(f); + + wx_messagebox(NULL, "Remember to partition and format the new drive", "PCem", WX_MB_OK); + + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + return TRUE; + } else if (ID_IS("IDC_CFILE")) { + if (!getsfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "", NULL, "img")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) openfilestring); + } + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT1: %s\n", s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT2: %s\n", s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT3: %s\n", s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_type = 0; + for (c = 1; c <= 46; c++) + { + pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt,17, hd[0].hpc,hd_types[c-1].heads, hd[0].tracks,hd_types[c-1].cylinders); + if (hd[0].spt == 17 && hd[0].hpc == hd_types[c-1].heads && hd[0].tracks == hd_types[c-1].cylinders) + { + hd_type = c; + break; + } + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); + + return TRUE; + } else if (ID_IS("IDC_HDTYPE")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hd_type) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_types[hd_type-1].cylinders); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_types[hd_type-1].heads); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"17"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } + return TRUE; + } + break; + + } + return FALSE; +} + +static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + PcemHDC hd[2]; + int c; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, hd_new_type, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)((((uint64_t)hd_new_spt*(uint64_t)hd_new_hpc*(uint64_t)hd_new_cyl)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); + + if (hd_new_spt > 63) + { + wx_messagebox(NULL,"Drive has too many sectors (maximum is 63)","PCem error",WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) + { + wx_messagebox(NULL,"Drive has too many heads (maximum is 16)","PCem error",WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > 16383) + { + wx_messagebox(NULL,"Drive has too many cylinders (maximum is 16383)","PCem error",WX_MB_OK); + return TRUE; + } + + wx_enddialog(hdlg,1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg,0); + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + + } + return FALSE; +} + +static int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + PcemHDC hd[4]; + FILE *f; + off64_t sz; + switch (message) + { + case WX_INITDIALOG: + pause = 1; + hd[0] = hdc[0]; + hd[1] = hdc[1]; + hd[2] = hdc[2]; + hd[3] = hdc[3]; + hd_changed = 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hdc[0].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hdc[0].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hdc[0].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[0]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hdc[1].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hdc[1].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hdc[1].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[1]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hdc[2].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hdc[2].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hdc[2].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[2]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hdc[3].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hdc[3].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hdc[3].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[3]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[1].tracks*(uint64_t)hd[1].hpc)*(uint64_t)hd[1].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[2].tracks*(uint64_t)hd[2].hpc)*(uint64_t)hd[2].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[3].tracks*(uint64_t)hd[3].hpc)*(uint64_t)hd[3].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + new_cdrom_channel = cdrom_channel; + + update_hdd_cdrom(hdlg); + + if (hdd_controller_current_is_mfm()) { + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_PANEL[2]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_PANEL[3]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_HDD[0]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_HDD[1]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[0]")), 0); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[1]")), 0); + } + return TRUE; + + case WX_COMMAND: + if (wParam == wxID_OK) + { + if (hd_changed || cdrom_channel != new_cdrom_channel) + { + if (!has_been_inited || confirm()) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[0]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[1]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[2]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[3]); + + hdc[0] = hd[0]; + hdc[1] = hd[1]; + hdc[2] = hd[2]; + hdc[3] = hd[3]; + + cdrom_channel = new_cdrom_channel; + + if (has_been_inited) + { + saveconfig(NULL); + + resetpchard(); + } + } + } + } + if (wParam == wxID_OK || wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + pause = 0; + return TRUE; + } else if (ID_IS("IDC_EJECT[0]")) + { + hd[0].spt = 0; + hd[0].hpc = 0; + hd[0].tracks = 0; + ide_fn[0][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[0]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[1]")) + { + hd[1].spt = 0; + hd[1].hpc = 0; + hd[1].tracks = 0; + ide_fn[1][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[1]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[2]")) + { + hd[2].spt = 0; + hd[2].hpc = 0; + hd[2].tracks = 0; + ide_fn[2][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[2]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[3]")) + { + hd[3].spt = 0; + hd[3].hpc = 0; + hd[3].tracks = 0; + ide_fn[3][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[3]"), ""); + hd_changed = 1; + return TRUE; + } + else if (ID_IS("IDC_NEW[0]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[0]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + + } + else if (ID_IS("IDC_NEW[1]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[1]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_NEW[2]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[2]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_NEW[3]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[3]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "Size : %imb", ((((hd[0].tracks*hd[0].hpc)*hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "Size : %imb", ((((hd[1].tracks*hd[1].hpc)*hd[1].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "Size : %imb", ((((hd[2].tracks*hd[2].hpc)*hd[2].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "Size : %imb", ((((hd[3].tracks*hd[3].hpc)*hd[3].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_HDD[0]")) + { + if (new_cdrom_channel == 0) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[1]")) + { + if (new_cdrom_channel == 1) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[2]")) + { + if (new_cdrom_channel == 2) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[3]")) + { + if (new_cdrom_channel == 3) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + + } + else if (ID_IS("IDC_CDROM[0]")) + { + new_cdrom_channel = 0; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[1]")) + { + new_cdrom_channel = 1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[2]")) + { + new_cdrom_channel = 2; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[3]")) + { + new_cdrom_channel = 3; + update_hdd_cdrom(hdlg); + return TRUE; + } + + } + return FALSE; +} + +void hdconf_open(void* hwnd) +{ + wx_dialogbox(hwnd, "HdConfDlg", hdconf_dlgproc); +} diff --git a/src/wx-sdl2-joystick.c b/src/wx-sdl2-joystick.c new file mode 100644 index 0000000..9aed5d7 --- /dev/null +++ b/src/wx-sdl2-joystick.c @@ -0,0 +1,15 @@ +#include "plat-joystick.h" + +int joysticks_present; +joystick_t joystick_state[MAX_JOYSTICKS]; + +void joystick_init() +{ + joysticks_present = 0; +} +void joystick_close() +{ +} +void joystick_poll() +{ +} diff --git a/src/wx-sdl2-keyboard.c b/src/wx-sdl2-keyboard.c new file mode 100644 index 0000000..df2cffe --- /dev/null +++ b/src/wx-sdl2-keyboard.c @@ -0,0 +1,23 @@ +#include "plat-keyboard.h" +#include + +int pcem_key[272]; +int rawinputkey[272]; + +void keyboard_init() +{ + memset(pcem_key, 0, sizeof(pcem_key)); +} + +void keyboard_close() +{ +} + +void keyboard_poll_host() +{ + int c; + + for (c = 0; c < 272; ++c) + pcem_key[c] = rawinputkey[c]; +} + diff --git a/src/wx-sdl2-midi.c b/src/wx-sdl2-midi.c new file mode 100644 index 0000000..9ad75b0 --- /dev/null +++ b/src/wx-sdl2-midi.c @@ -0,0 +1,14 @@ +#include +#include "plat-midi.h" + +void midi_init() +{ +} + +void midi_close() +{ +} + +void midi_write(uint8_t val) +{ +} diff --git a/src/wx-sdl2-mouse.c b/src/wx-sdl2-mouse.c new file mode 100644 index 0000000..1f61758 --- /dev/null +++ b/src/wx-sdl2-mouse.c @@ -0,0 +1,59 @@ +#include +#include "plat-mouse.h" + +int mouse_buttons; +static int mouse_x = 0, mouse_y = 0, mouse_z = 0; + +int mouse[3]; + +void mouse_init() +{ + memset(mouse, 0, sizeof(mouse)); +} + +void mouse_close() +{ +} + +void mouse_wheel_update(int dir) +{ + mouse[2] += dir; +} + +void mouse_poll_host() +{ + if (mousecapture) + { + uint32_t mb = SDL_GetRelativeMouseState(&mouse[0], &mouse[1]); + mouse_buttons = 0; + if (mb & SDL_BUTTON(SDL_BUTTON_LEFT)) + { + mouse_buttons |= 1; + } + if (mb & SDL_BUTTON(SDL_BUTTON_RIGHT)) + { + mouse_buttons |= 2; + } + if (mb & SDL_BUTTON(SDL_BUTTON_MIDDLE)) + { + mouse_buttons |= 4; + } + mouse_x += mouse[0]; + mouse_y += mouse[1]; + mouse_z += mouse[2]; + mouse[2] = 0; + } + else + { + mouse_x = mouse_y = mouse_z = 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/wx-sdl2-status.c b/src/wx-sdl2-status.c new file mode 100644 index 0000000..78bacfb --- /dev/null +++ b/src/wx-sdl2-status.c @@ -0,0 +1,162 @@ +#include "wx-sdl2.h" +#include "wx-sdl2-video.h" +#include "ibm.h" +#include "device.h" +#include "video.h" +#include "x86_ops.h" +#include "mem.h" +#include "codegen.h" +#include "cpu.h" +#include "model.h" +#include "fdd.h" +#include "hdd.h" +#include "ide.h" +#include "cdrom-image.h" +#include "wx-common.h" + +drive_info_t drive_info[10]; + +int status_is_open = 0; + +extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; +extern int render_fps, fps; + +extern uint64_t main_time; +extern uint64_t render_time; +static uint64_t status_time; + +drive_info_t* get_machine_info(char* s, int* num_drive_info) { + int drive, i; + int pos = 0; + sprintf(s, + "Model: %s\n" + "CPU: %s", + model_getname(), + models[model].cpu[cpu_manufacturer].cpus[cpu].name); + if (emulation_state == EMULATION_RUNNING) + sprintf(s+strlen(s), "\nEmulation speed: %d%%", fps); + else if (emulation_state == EMULATION_PAUSED) + strcat(s, "\nEmulation is paused."); + else + strcat(s, "\nEmulation is not running."); + + for (i = 0; i < 2; ++i) + { + drive = 'A'+i; + if (fdd_get_type(i) > 0) + { + strcpy(drive_info[pos].fn, discfns[i]); + drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_FDD; + drive_info[pos].readflash = readflash_get(READFLASH_FDC, i); + readflash_clear(READFLASH_FDC, i); + pos++; + } + } + int num_hdds = hdd_controller_current_is_mfm() ? 2 : 4; + for (i = 0; i < num_hdds; ++i) + { + drive = 'C'+i; + if (cdrom_enabled && !hdd_controller_current_is_mfm() && i == cdrom_channel) + { + if (cdrom_drive < 0) + continue; + if (cdrom_drive == CDROM_IMAGE) + { + if (!strlen(image_path)) + continue; + strcpy(drive_info[pos].fn, image_path); + } + else + strcpy(drive_info[pos].fn, ""); + drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_CDROM; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } else if (strlen(ide_fn[i]) > 0) + { + strcpy(drive_info[pos].fn, ide_fn[i]); + drive_info[pos].enabled = 1; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_HDD; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } + } + *num_drive_info = pos; + return drive_info; +} + +int get_status(char* machine, char* device) +{ +// if (!status_is_open) { +// return 0; +// } +// char device_s[4096]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; + sprintf(machine, + "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" + "Timer 0 frequency : %fHz\n\n" + "CPU time : %f%% (%f%%)\n" + "Render time : %f%% (%f%%)\n" + "Renderer: %s\n" + "Render FPS: %d\n" + "\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" + // "\nFully recompiled ins %% : %f%%" + ,mips, + flops, + /*#ifndef DYNAREC + sreadlnum, + swritelnum, + #endif*/ + segareads, + segawrites, + clockrate - scycles_lost, + pit_timer0_freq(), + ((double)main_time * 100.0) / status_diff, + ((double)main_time * 100.0) / timer_freq, + ((double)render_time * 100.0) / status_diff, + ((double)render_time * 100.0) / timer_freq, + current_render_driver_name, + render_fps + + , 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) + // ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0 + // cpu_reps_latched, cpu_notreps_latched + ); + main_time = 0; + render_time = 0; + /*#ifndef DYNAREC + device_add_status_info(device_s, 4096); + #endif*/ + +// device_s[0] = 0; + device[0] = 0; + device_add_status_info(device, 4096); + + return 1; +} diff --git a/src/wx-sdl2-video.c b/src/wx-sdl2-video.c new file mode 100644 index 0000000..ec5eefa --- /dev/null +++ b/src/wx-sdl2-video.c @@ -0,0 +1,344 @@ +#include "wx-sdl2-video.h" + +#include +#include +#include +#include "wx-sdl2.h" +#include "video.h" + +void video_blit_complete(); + +static BITMAP *buffer32_vscale; +BITMAP *screen; +SDL_Texture* texture = NULL; +SDL_Renderer* renderer = NULL; +SDL_Rect old_screen_rect; +SDL_Rect screen_rect; +SDL_Rect updated_rect; +SDL_Rect window_rect; +SDL_Rect blit_rect; +SDL_Rect texture_rect; +int updated = 0; + +SDL_mutex* blitMutex = NULL; + +static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +static void sdl_blit_memtoscreen_8(int x, int y, int w, int h); + +int video_scale_mode = 1; +int video_vsync = 0; +int video_focus_dim = 0; +int video_fullscreen_mode = 0; + +static sdl_render_driver sdl_render_drivers[] = { + { RENDERER_AUTO, "auto", "Auto" }, + { RENDERER_DIRECT3D, "direct3d", "Direct3D" }, + { RENDERER_OPENGL, "opengl", "OpenGL" }, + { RENDERER_OPENGLES2, "opengles2", "OpenGL ES 2" }, + { RENDERER_OPENGLES, "opengles", "OpenGL ES" }, + { RENDERER_SOFTWARE, "software", "Software" } +}; + +sdl_render_driver requested_render_driver; + +char current_render_driver_name[50]; + +void hline(BITMAP *b, int x1, int y, int x2, int col) +{ + if (y < 0 || y >= buffer32->h) + return; + + for (; x1 < x2; x1++) + ((uint32_t *)b->line[y])[x1] = col; +} + +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; +} + +sdl_render_driver* sdl_get_render_drivers(int* num) +{ + if (num) + *num = SDL_arraysize(sdl_render_drivers); + return sdl_render_drivers; +} + +sdl_render_driver sdl_get_render_driver_by_name(const char* name, int def) +{ + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) + { + if (!strcmp(sdl_render_drivers[i].sdl_id, name)) + { + return sdl_render_drivers[i]; + } + } + return sdl_render_drivers[def]; +} + +sdl_render_driver* sdl_get_render_driver_by_name_ptr(const char* name) +{ + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) + { + if (!strcmp(sdl_render_drivers[i].sdl_id, name)) + { + return &sdl_render_drivers[i]; + } + } + return 0; +} + +sdl_render_driver sdl_get_render_driver_by_id(int id, int def) +{ + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) + { + if (sdl_render_drivers[i].id == id) + { + return sdl_render_drivers[i]; + } + } + return sdl_render_drivers[def]; +} + + +void sdl_scale(int scale, SDL_Rect src, SDL_Rect* dst, int w, int h) +{ + double t, b, l, r; + int ratio_w, ratio_h; + switch (scale) + { + case FULLSCR_SCALE_43: + t = 0; + b = src.h; + l = (src.w / 2) - ((src.h * 4) / (3 * 2)); + r = (src.w / 2) + ((src.h * 4) / (3 * 2)); + if (l < 0) + { + l = 0; + r = src.w; + t = (src.h / 2) + - ((src.w * 3) / (4 * 2)); + b = (src.h / 2) + + ((src.w * 3) / (4 * 2)); + } + break; + case FULLSCR_SCALE_SQ: + t = 0; + b = src.h; + l = (src.w / 2) - ((src.h * w) / (h * 2)); + r = (src.w / 2) + ((src.h * w) / (h * 2)); + if (l < 0) + { + l = 0; + r = src.w; + t = (src.h / 2) + - ((src.w * h) / (w * 2)); + b = (src.h / 2) + + ((src.w * h) / (w * 2)); + } + break; + case FULLSCR_SCALE_INT: + ratio_w = src.w / w; + ratio_h = src.h / h; + if (ratio_h < ratio_w) + ratio_w = ratio_h; + l = (src.w / 2) - ((w * ratio_w) / 2); + r = (src.w / 2) + ((w * ratio_w) / 2); + t = (src.h / 2) - ((h * ratio_w) / 2); + b = (src.h / 2) + ((h * ratio_w) / 2); + break; + case FULLSCR_SCALE_FULL: + default: + l = 0; + t = 0; + r = src.w; + b = src.h; + break; + } + + dst->x = l; + dst->y = t; + dst->w = r - l; + dst->h = b - t; +} + +static void set_updated_size(int x, int y, int w, int h) +{ + if (updated) + { + updated_rect.x = x < updated_rect.x ? x : updated_rect.x; + updated_rect.y = y < updated_rect.y ? y : updated_rect.y; + updated_rect.w = w > updated_rect.w ? w : updated_rect.w; + updated_rect.h = h > updated_rect.h ? h : updated_rect.h; + } + else + { + updated_rect.x = x; + updated_rect.y = y; + updated_rect.w = w; + updated_rect.h = h; + updated = 1; + } +} + +static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + if (y1 == y2) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + int xx, yy; + SDL_Rect rect; + SDL_LockMutex(blitMutex); + for (yy = y1; yy < y2; yy++) + { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) + memcpy(screen->dat + (yy * screen->w * 4), + &(((uint32_t *) buffer32->line[y + yy])[x]), w * 4); + } + set_updated_size(0, y1, w, y2 - y1); +// set_updated_size(0, 0, w, h); + blit_rect.w = w; + blit_rect.h = h; + SDL_UnlockMutex(blitMutex); + video_blit_complete(); +} + +int sdl_is_fullscreen(SDL_Window* window) { + int flags = SDL_GetWindowFlags(window); + return (flags&SDL_WINDOW_FULLSCREEN) || (flags&SDL_WINDOW_FULLSCREEN_DESKTOP); +} + +int sdl_video_init() +{ + blitMutex = SDL_CreateMutex(); + updated = 0; + + video_blit_memtoscreen_func = sdl_blit_memtoscreen; + requested_render_driver = sdl_get_render_driver_by_id(RENDERER_AUTO, RENDERER_AUTO); + + buffer32_vscale = create_bitmap(2048, 2048); + screen = create_bitmap(2048, 2048); + + return SDL_TRUE; +} + +void sdl_video_close() +{ + destroy_bitmap(buffer32_vscale); + destroy_bitmap(screen); + SDL_DestroyMutex(blitMutex); +} + +int sdl_renderer_init(SDL_Window* window) +{ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); + const char* driver = requested_render_driver.sdl_id; + if (!driver) driver = "0"; + SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); + + int flags = SDL_RENDERER_ACCELERATED; + if (video_vsync) { + flags |= SDL_RENDERER_PRESENTVSYNC; + } + renderer = SDL_CreateRenderer(window, -1, flags); + + SDL_RendererInfo rendererInfo; + SDL_GetRendererInfo(renderer, &rendererInfo); + sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); + if (!d) + strcpy(current_render_driver_name, "Unknown"); + else + strcpy(current_render_driver_name, d->name); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + screen->w, screen->h); + + return SDL_TRUE; +} + +void sdl_renderer_close() +{ + if (texture) + { + SDL_DestroyTexture(texture); + texture = NULL; + } + if (renderer) + { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } +} + +int sdl_renderer_update(SDL_Window* window) +{ + int render = 0; + SDL_LockMutex(blitMutex); + if (updated) + { + updated = 0; + SDL_UpdateTexture(texture, &updated_rect, + &((uint32_t*) screen->dat)[updated_rect.y + * screen->w + updated_rect.x], + screen->w * 4); + texture_rect.w = blit_rect.w; + texture_rect.h = blit_rect.h; + render = 1; + } + SDL_UnlockMutex(blitMutex); + return render; +} + +void sdl_renderer_present(SDL_Window* window) +{ + SDL_Rect wr; + int l, t, r, b; + SDL_GetWindowSize(window, &wr.w, &wr.h); + sdl_scale(video_fullscreen_scale, wr, &wr, texture_rect.w, texture_rect.h); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, &texture_rect, &wr); + if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + SDL_RenderPresent(renderer); +} diff --git a/src/wx-sdl2-video.h b/src/wx-sdl2-video.h new file mode 100644 index 0000000..635b0fc --- /dev/null +++ b/src/wx-sdl2-video.h @@ -0,0 +1,38 @@ +#include + +#define RENDERER_AUTO 0 +#define RENDERER_DIRECT3D 1 +#define RENDERER_OPENGL 2 +#define RENDERER_OPENGLES2 3 +#define RENDERER_OPENGLES 4 +#define RENDERER_SOFTWARE 5 + +typedef struct sdl_render_driver { + int id; + const char* sdl_id; + const char* name; +} sdl_render_driver; + +#ifdef __cplusplus +extern "C" { +#endif +int sdl_video_init(); +void sdl_video_close(); +int sdl_renderer_init(SDL_Window* window); +void sdl_renderer_close(); +int sdl_renderer_update(SDL_Window* window); +void sdl_renderer_present(SDL_Window* window); +void sdl_scale(int scale, SDL_Rect src, SDL_Rect* dst, int w, int h); +int sdl_is_fullscreen(SDL_Window* window); + +sdl_render_driver* sdl_get_render_drivers(int* num_renderers); +sdl_render_driver sdl_get_render_driver_by_id(int id, int def); +sdl_render_driver sdl_get_render_driver_by_name(const char* name, int def); +sdl_render_driver* sdl_get_render_driver_by_name_ptr(const char* name); + +#ifdef __cplusplus +} +#endif + +extern sdl_render_driver requested_render_driver; +extern char current_render_driver_name[50]; diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c new file mode 100644 index 0000000..22d4e63 --- /dev/null +++ b/src/wx-sdl2.c @@ -0,0 +1,889 @@ +#include "wx-sdl2.h" + +#include +#include + +#ifdef __WINDOWS__ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#endif + + +#include +#include +#include +#include +#include "ibm.h" +#include "cdrom-ioctl.h" +#include "cdrom-image.h" +#include "config.h" +#include "video.h" +#include "cpu.h" +#include "ide.h" +#include "model.h" +#include "mouse.h" +#include "nvr.h" +#include "sound.h" +#include "thread.h" +#include "disc.h" +#include "disc_img.h" +#include "mem.h" + +#include "wx-sdl2-video.h" +#include "wx-utils.h" +#include "wx-common.h" +#include "wx-display.h" + +#define ID_IS(s) wParam == wx_xrcid(s) +#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) + +#define IDM_CDROM_REAL 1500 + +uint64_t timer_freq; + + +int gfx_present[GFX_MAX]; + +SDL_mutex* ghMutex; +SDL_mutex* mainMutex; +SDL_cond* mainCond; + +SDL_Thread* mainthreadh = NULL; + +SDL_TimerID onesectimer; + +int running = 0; + +int drawits = 0; + +int romspresent[ROM_MAX]; +int quited = 0; + +SDL_Rect oldclip; + +void* ghwnd = 0; + +void* menu; + +emulation_state_t emulation_state = EMULATION_STOPPED; +int pause = 0; + +int window_doreset = 0; +int renderer_doreset = 0; +int window_dofullscreen = 0; +int window_dowindowed = 0; +int window_doremember = 0; +int window_doinputgrab = 0; +int window_doinputrelease = 0; +int window_dotogglefullscreen = 0; + +int video_scale = 1; + +int video_width = 640; +int video_height = 480; + +char menuitem[60]; + +extern void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()); + +extern int config_selection_open(void* hwnd, int inited); + +extern void sdl_set_window_title(const char* title); + +void warning(const char *format, ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + + wx_messagebox(ghwnd, buf, "PCem", WX_MB_OK); +} + +void updatewindowsize(int x, int y) +{ + video_width = x; + video_height = y; + + display_resize(x, y); +} + +void startblit() +{ + SDL_LockMutex(ghMutex); +} + +void endblit() +{ + SDL_UnlockMutex(ghMutex); +} + +void enter_fullscreen() +{ + window_dofullscreen = window_doinputgrab = 1; +} + +void leave_fullscreen() +{ + window_dowindowed = window_doinputrelease = 1; +} + +void toggle_fullscreen() +{ + window_dotogglefullscreen = 1; +} + +uint64_t main_time; + +int mainthread(void* param) +{ + int i; + + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + + int t = 0; + int frames = 0; + uint32_t old_time, new_time; + + drawits = 0; + old_time = SDL_GetTicks(); + running = 1; + while (running) + { + new_time = SDL_GetTicks(); + drawits += new_time - old_time; + old_time = new_time; + + if (drawits > 0 && !pause) + { + uint64_t start_time = timer_read(); + uint64_t end_time; + 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 + SDL_Delay(1); + } + + SDL_LockMutex(mainMutex); + SDL_CondSignal(mainCond); + SDL_UnlockMutex(mainMutex); + + return TRUE; +} + +void get_executable_name(char *s, int size) +{ + char* path = SDL_GetBasePath(); + strcpy(s, path); +} + +void set_window_title(const char *s) +{ + sdl_set_window_title(s); +} + +uint64_t timer_read() +{ + return SDL_GetPerformanceCounter(); +} + +Uint32 timer_onesec(Uint32 interval, void* param) +{ + onesec(); + return interval; +} + +void sdl_loadconfig() +{ + video_fullscreen = config_get_int(CFG_GLOBAL, "SDL2", "fullscreen", video_fullscreen); + video_fullscreen_mode = config_get_int(CFG_GLOBAL, "SDL2", "fullscreen_mode", video_fullscreen_mode); + video_scale = config_get_int(CFG_GLOBAL, "SDL2", "scale", video_scale); + video_scale_mode = config_get_int(CFG_GLOBAL, "SDL2", "scale_mode", video_scale_mode); + video_vsync = config_get_int(CFG_GLOBAL, "SDL2", "vsync", video_vsync); + video_focus_dim = config_get_int(CFG_GLOBAL, "SDL2", "focus_dim", video_focus_dim); + requested_render_driver = sdl_get_render_driver_by_name(config_get_string(CFG_GLOBAL, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); +} + +void sdl_saveconfig() +{ + config_set_int(CFG_GLOBAL, "SDL2", "fullscreen", video_fullscreen); + config_set_int(CFG_GLOBAL, "SDL2", "fullscreen_mode", video_fullscreen_mode); + config_set_int(CFG_GLOBAL, "SDL2", "scale", video_scale); + config_set_int(CFG_GLOBAL, "SDL2", "scale_mode", video_scale_mode); + config_set_int(CFG_GLOBAL, "SDL2", "vsync", video_vsync); + config_set_int(CFG_GLOBAL, "SDL2", "focus_dim", video_focus_dim); + config_set_string(CFG_GLOBAL, "SDL2", "render_driver", (char*)requested_render_driver.sdl_id); +} + +void update_cdrom_menu(void* hmenu) +{ + if (!cdrom_enabled) + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_DISABLED"), WX_MB_CHECKED); + else + { + if (cdrom_drive == CDROM_IMAGE) + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_IMAGE"), WX_MB_CHECKED); + else if (cdrom_drive > 0) + wx_checkmenuitem(menu, IDM_CDROM_REAL+cdrom_drive, WX_MB_CHECKED); + else + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_EMPTY"), WX_MB_CHECKED); + } +} + +void wx_initmenu() +{ + char s[32]; + menu = wx_getmenu(ghwnd); + + void* cdrom_submenu = wx_getsubmenu(menu, WX_ID("IDM_CDROM")); + +#ifdef __WINDOWS__ + int c; + /* 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); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+(c-'A'), s, wxITEM_RADIO); + } + } +#elif __linux__ + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); +#endif + +} + +void wx_setupmenu() +{ + int c; + update_cdrom_menu(menu); + if (vid_resize) + wx_checkmenuitem(menu, WX_ID("IDM_VID_RESIZE"), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_FS[%d]", video_fullscreen_scale); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_VID_FULLSCREEN"), video_fullscreen); + wx_checkmenuitem(menu, WX_ID("IDM_VID_REMEMBER"), + window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + + sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_SCALE[%d]", video_scale); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_FS_MODE[%d]", video_fullscreen_mode); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_VID_VSYNC"), video_vsync); + wx_checkmenuitem(menu, WX_ID("IDM_VID_LOST_FOCUS_DIM"), video_focus_dim); + + int num_renderers; + sdl_render_driver* drivers = sdl_get_render_drivers(&num_renderers); + for (c = 1; c < num_renderers; ++c) + { + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", drivers[c].id); + wx_enablemenuitem(menu, WX_ID(menuitem), 0); + } + SDL_RendererInfo renderInfo; + for (c = 0; c < SDL_GetNumRenderDrivers(); ++c) + { + SDL_GetRenderDriverInfo(c, &renderInfo); + sdl_render_driver* driver = sdl_get_render_driver_by_name_ptr(renderInfo.name); + + if (driver) + { + pclog("Renderer: %s (%d)\n", renderInfo.name, driver->id); + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", driver->id); + wx_enablemenuitem(menu, WX_ID(menuitem), 1); + } + } + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", requested_render_driver.id); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); +} + +void sdl_onconfigloaded() +{ + if (ghwnd) + wx_callback(ghwnd, wx_setupmenu); +} + +extern void wx_loadconfig(); +extern void wx_saveconfig(); + +int pc_main(int argc, char** argv) +{ +#ifndef __APPLE__ + display_init(); +#endif + sdl_video_init(); + + add_config_callback(sdl_loadconfig, sdl_saveconfig, sdl_onconfigloaded); + add_config_callback(wx_loadconfig, wx_saveconfig, 0); + + getpath(); + + sound_init(); + + initpc(argc, argv); + resetpchard(); + + return TRUE; +} + +int wx_load_config(void* hwnd) +{ + if (!config_override) + { + if (!config_selection_open(NULL, 0)) + return FALSE; + } + + return TRUE; +} + +int wx_start(void* hwnd) +{ + int c, d; + ghwnd = hwnd; + +#ifdef __APPLE__ + /* OSX requires SDL to be initialized after wxWidgets. */ + display_init(); +#endif + + readflash = 0; + + wx_initmenu(); + wx_setupmenu(); + + 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) + { + wx_messagebox(hwnd, + "No ROMs present!\nYou must have at least one romset to use PCem.", + "PCem fatal error", WX_MB_OK); + return 0; + } + + romset = d; + c = loadbios(); + + if (!c) + { + if (romset != -1) + wx_messagebox(hwnd, + "Configured romset not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = 0; c < ROM_MAX; c++) + { + if (romspresent[c]) + { + romset = c; + model = model_getmodel(romset); + saveconfig(NULL); + 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 (romset != -1) + wx_messagebox(hwnd, + "Configured video BIOS not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = GFX_MAX - 1; c >= 0; c--) + { + if (gfx_present[c]) + { + gfxcard = c; + saveconfig(NULL); + resetpchard(); + break; + } + } + } + + return TRUE; +} + +int resume_emulation() +{ + if (emulation_state == EMULATION_PAUSED) + { + emulation_state = EMULATION_RUNNING; + pause = 0; + return TRUE; + } + return FALSE; +} + +int start_emulation(void* params) +{ + if (resume_emulation()) + return TRUE; + pclog("Starting emulation...\n"); + loadconfig(NULL); + + emulation_state = EMULATION_RUNNING; + pause = 0; + + ghMutex = SDL_CreateMutex(); + mainMutex = SDL_CreateMutex(); + mainCond = SDL_CreateCond(); + + loadbios(); + resetpchard(); + + display_start(params); + mainthreadh = SDL_CreateThread(mainthread, "Main Thread", NULL); + + onesectimer = SDL_AddTimer(1000, timer_onesec, NULL); + + updatewindowsize(640, 480); + + timer_freq = timer_read(); + + if (show_machine_on_start) + wx_show_status(ghwnd); + + return TRUE; +} + +int pause_emulation() +{ + pclog("Emulation paused.\n"); + emulation_state = EMULATION_PAUSED; + pause = 1; + return TRUE; +} + +int stop_emulation() +{ + emulation_state = EMULATION_STOPPED; + pclog("Stopping emulation...\n"); + SDL_LockMutex(mainMutex); + running = 0; + SDL_CondWaitTimeout(mainCond, mainMutex, 10 * 1000); + SDL_UnlockMutex(mainMutex); + + SDL_DestroyCond(mainCond); + SDL_DestroyMutex(mainMutex); + + startblit(); + display_stop(); + +#if SDL_VERSION_ATLEAST(2, 0, 2) + SDL_DetachThread(mainthreadh); +#endif + mainthreadh = NULL; + SDL_RemoveTimer(onesectimer); + savenvr(); + saveconfig(NULL); + + endblit(); + SDL_DestroyMutex(ghMutex); + + pclog("Emulation stopped.\n"); + + wx_close_status(ghwnd); + + return TRUE; +} + +void reset_emulation() +{ + pause_emulation(); + SDL_Delay(100); + resetpchard(); + resume_emulation(); +} + +int wx_stop() +{ + pclog("Shutting down...\n"); + closepc(); + display_close(); + sdl_video_close(); + + printf("Shut down successfully!\n"); + return TRUE; +} + +char openfilestring[260]; +int getfile(void* hwnd, char *f, char *fn) +{ + int ret = wx_filedialog(hwnd, "Open", fn, f, 0, 1, openfilestring); +#ifdef __APPLE__ + /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ + window_doreset = 1; +#endif + return ret; +} + +int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext) +{ + int ret = wx_filedialog(hwnd, "Save", dir, f, ext, 0, openfilestring); +#ifdef __APPLE__ + window_doreset = 1; +#endif + return ret; +} + +void atapi_close(void) +{ + switch (cdrom_drive) + { + case CDROM_IMAGE: + image_close(); + break; + default: + ioctl_close(); + break; + } +} + +int wx_handle_command(void* hwnd, int wParam, int checked) +{ + SDL_Rect rect; + void* hmenu; + char temp_image_path[1024]; + int new_cdrom_drive; + hmenu = wx_getmenu(hwnd); + + if (ID_IS("IDM_STATUS")) + { + wx_show_status(hwnd); + } + else if (ID_IS("IDM_FILE_RESET")) + { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpc(); + pause = 0; + } + else if (ID_IS("IDM_FILE_HRESET")) + { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpchard(); + pause = 0; + } + else if (ID_IS("IDM_FILE_RESET_CAD")) + { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpc_cad(); + pause = 0; + } + else if (ID_IS("IDM_FILE_EXIT")) + { +// wx_exit(hwnd, 0); + wx_stop_emulation(hwnd); + } + else if (ID_IS("IDM_DISC_A")) + { + if (!getfile(hwnd, + "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", + discfns[0])) + { + disc_close(0); + disc_load(0, openfilestring); + saveconfig(NULL); + } + } + else if (ID_IS("IDM_DISC_B")) + { + if (!getfile(hwnd, + "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", + discfns[1])) + { + disc_close(1); + disc_load(1, openfilestring); + saveconfig(NULL); + } + } + else if (ID_IS("IDM_EJECT_A")) + { + disc_close(0); + saveconfig(NULL); + } + else if (ID_IS("IDM_EJECT_B")) + { + disc_close(1); + saveconfig(NULL); + } + else if (ID_IS("IDM_BPB_DISABLE")) + { + bpb_disable = checked; + wx_checkmenuitem(hmenu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + saveconfig(NULL); + } + else if (ID_IS("IDM_MACHINE_TOGGLE")) + { + if (emulation_state != EMULATION_STOPPED) + wx_togglewindow(hwnd); + } + else if (ID_IS("IDM_VID_RESIZE")) + { + vid_resize = checked; + window_doreset = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_REMEMBER")) + { + window_remember = checked; + wx_checkmenuitem(hmenu, WX_ID("IDM_VID_REMEMBER"), + window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); + window_doremember = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_FULLSCREEN")) + { + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + wx_messagebox(hwnd, + "Use CTRL + ALT + PAGE DOWN to return to windowed mode", + "PCem", WX_MB_OK); + } + video_fullscreen = checked; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_FULLSCREEN_TOGGLE")) + { + toggle_fullscreen(); + } + else if (ID_RANGE("IDM_VID_FS[start]", "IDM_VID_FS[end]")) + { + video_fullscreen_scale = wParam - wx_xrcid("IDM_VID_FS[start]"); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_SCALE_MODE[start]", "IDM_VID_SCALE_MODE[end]")) + { + video_scale_mode = wParam - wx_xrcid("IDM_VID_SCALE_MODE[start]"); + renderer_doreset = 1; + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_SCALE[start]", "IDM_VID_SCALE[end]")) + { + video_scale = wParam - wx_xrcid("IDM_VID_SCALE[start]"); + display_resize(video_width, video_height); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_FS_MODE[start]", "IDM_VID_FS_MODE[end]")) + { + video_fullscreen_mode = wParam - wx_xrcid("IDM_VID_FS_MODE[start]"); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_RENDER_DRIVER[start]", "IDM_VID_RENDER_DRIVER[end]")) + { + requested_render_driver = sdl_get_render_driver_by_id(wParam - wx_xrcid("IDM_VID_RENDER_DRIVER[start]"), RENDERER_AUTO); + window_doreset = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_VSYNC")) + { + video_vsync = checked; + renderer_doreset = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_LOST_FOCUS_DIM")) + { + video_focus_dim = checked; + saveconfig(NULL); + } + else if (ID_IS("IDM_CDROM_DISABLED")) + { + if (cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + if (!cdrom_enabled) + { + /* Switching from disabled to disabled. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + atapi->exit(); + atapi_close(); + ioctl_set_drive(0); + old_cdrom_drive = cdrom_drive; + cdrom_drive = 0; + if (cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 0; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } + else if (ID_IS("IDM_CDROM_EMPTY")) + { + if (!cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + if ((cdrom_drive == 0) && cdrom_enabled) + { + update_cdrom_menu(hmenu); + /* Switch from empty to empty. Do nothing. */ + return 0; + } + atapi->exit(); + atapi_close(); + ioctl_set_drive(0); + if (cdrom_enabled) + { + /* Signal disc change to the emulated machine. */ + atapi_insert_cdrom(); + } + old_cdrom_drive = cdrom_drive; + cdrom_drive = 0; + saveconfig(NULL); + if (!cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 1; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } + else if (ID_IS("IDM_CDROM_IMAGE") || ID_IS("IDM_CDROM_IMAGE_LOAD")) + { + if (!getfile(hwnd, + "CD-ROM image (*.iso;*.cue)|*.iso;*.cue|All files (*.*)|*.*", + image_path)) + { + if (!cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + old_cdrom_drive = cdrom_drive; + strcpy(temp_image_path, openfilestring); + if ((strcmp(image_path, temp_image_path) == 0) + && (cdrom_drive == CDROM_IMAGE) + && cdrom_enabled) + { + /* Switching from ISO to the same ISO. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + atapi->exit(); + atapi_close(); + image_open(temp_image_path); + if (cdrom_enabled) + { + /* Signal disc change to the emulated machine. */ + atapi_insert_cdrom(); + } + cdrom_drive = CDROM_IMAGE; + saveconfig(NULL); + if (!cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 1; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } else + update_cdrom_menu(hmenu); + } + else if (wParam >= IDM_CDROM_REAL && wParam < IDM_CDROM_REAL+100) + { + if (!cdrom_enabled) + { + if (!confirm()) + { + update_cdrom_menu(hmenu); + return 0; + } + } + new_cdrom_drive = wParam-IDM_CDROM_REAL+1; + if ((cdrom_drive == new_cdrom_drive) && cdrom_enabled) + { + /* Switching to the same drive. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + old_cdrom_drive = cdrom_drive; + atapi->exit(); + atapi_close(); + ioctl_set_drive(new_cdrom_drive); + if (cdrom_enabled) + { + /* Signal disc change to the emulated machine. */ + atapi_insert_cdrom(); + } + cdrom_drive = new_cdrom_drive; + saveconfig(NULL); + if (!cdrom_enabled) + { + pause = 1; + SDL_Delay(100); + cdrom_enabled = 1; + saveconfig(NULL); + resetpchard(); + pause = 0; + } + update_cdrom_menu(hmenu); + } + return 0; +} diff --git a/src/wx-sdl2.h b/src/wx-sdl2.h new file mode 100644 index 0000000..6857f5f --- /dev/null +++ b/src/wx-sdl2.h @@ -0,0 +1,16 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void leave_fullscreen(); +int getfile(void* hwnd, char *f, char *fn); +int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext); + +#ifdef __cplusplus +} +#endif + +extern char openfilestring[260]; + +extern int pause; + diff --git a/src/wx-status.cc b/src/wx-status.cc new file mode 100644 index 0000000..16b9968 --- /dev/null +++ b/src/wx-status.cc @@ -0,0 +1,351 @@ +#include "wx-status.h" +#include "wx-common.h" +#include "wx-utils.h" +#include +#include +#include + +extern "C" { + int get_status(char*, char*); + int fps; + int updatestatus; + drive_info_t* get_machine_info(char*, int*); +} + +int show_machine_on_start = 0; +int confirm_on_stop_emulation = 1; +int confirm_on_reset_machine = 1; +int show_status = 0; +int show_speed_history = 0; +int show_disc_activity = 1; +int show_machine_info = 1; +int show_mount_paths = 0; + +#define ACTIVITY_TEXT wxT("Activity") + +#define MAX(a, b) (a > b ? a : b) + +#define render_disc_activity(x, y) do { \ +if (show_disc_activity) \ +{ \ + int w = 8; \ + int h = 8; \ + if (info.readflash) { \ + dc.SetBrush(wxBrush(wxColour(0,255,0))); \ + } else { \ + dc.SetBrush(wxBrush(wxColour(0,100,0))); \ + } \ + dc.DrawRectangle(x+bitmap.GetWidth()-w, y, w, h); \ +}} while (0) + +StatusTimer::StatusTimer(StatusPane* pane) +{ + this->pane = pane; +} + +void StatusTimer::Notify() +{ + pane->Refresh(); +} + +void StatusTimer::Start() +{ + wxTimer::Start(10); +} + +BEGIN_EVENT_TABLE(StatusPane, wxPanel) EVT_PAINT(StatusPane::PaintEvent) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(StatusFrame, wxFrame) END_EVENT_TABLE() + +StatusPane::StatusPane(wxFrame* parent) : + wxPanel(parent) +{ +#ifndef __WXOSX_MAC__ + SetDoubleBuffered(true); +#endif + machineInfoText[0] = statusMachineText[0] = statusDeviceText[0] = 0; + lastSpeedUpdate = 0; + memset(speedHistory, -1, sizeof(speedHistory)); + + bitmapFDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_FLOPPY"); + bitmapFDD[1] = bitmapFDD[0].ConvertToDisabled(); + bitmapHDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_HARDDISK"); + bitmapHDD[1] = bitmapHDD[0].ConvertToDisabled(); + bitmapCDROM[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_CDROM"); + bitmapCDROM[1] = bitmapCDROM[0].ConvertToDisabled(); +} + +StatusPane::~StatusPane() { +} + +void StatusPane::PaintEvent(wxPaintEvent& evt) +{ + wxPaintDC dc(this); + Render(dc); +} + +void StatusPane::PaintNow() +{ + wxClientDC dc(this); + Render(dc); +} + +void StatusPane::Render(wxDC& dc) +{ + wxSize cSize = GetParent()->GetClientSize(); + + int width = 0; + int height = 0; + wxLongLong millis = wxGetUTCTimeMillis(); + + dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); + dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + dc.Clear(); + + // draw model/cpu etc + if (show_machine_info) { + int num_info; + drive_info_t* drive_info = get_machine_info(machineInfoText, &num_info); + wxSize size = dc.GetMultiLineTextExtent(machineInfoText); + dc.DrawText(machineInfoText, 5, height+5); + + width = MAX(width, width+5+size.x); + height = MAX(height, height+5+size.y); + + int x = cSize.x-5; + + for (int i = 0; i < num_info; ++i) + { + drive_info_t info = show_mount_paths ? drive_info[i] : drive_info[num_info-i-1]; + wxBitmap bitmap; + if (info.type == DRIVE_TYPE_FDD) + bitmap = info.enabled ? bitmapFDD[0] : bitmapFDD[1]; + else if (info.type == DRIVE_TYPE_CDROM) + bitmap = info.enabled ? bitmapCDROM[0] : bitmapCDROM[1]; + else + bitmap = info.enabled ? bitmapHDD[0] : bitmapHDD[1]; + if (show_mount_paths) + { + x = 5; + dc.DrawBitmap(bitmap, x, height+5); + render_disc_activity(x, height+5); + x += bitmap.GetWidth()+5; + + std::ostringstream ss; + ss << info.drive_letter << ":" << " " << info.fn; + std::string s = ss.str(); + size = dc.GetTextExtent(s); + dc.DrawText(s, x, height+5+(bitmap.GetHeight()-size.y)/2); + width = MAX(width, x+size.x); + height = MAX(height, height+5+MAX(bitmap.GetHeight(), size.y)); + } else { + x -= bitmap.GetWidth(); + dc.DrawBitmap(bitmap, x, 5); + render_disc_activity(x, 5); + x -= 5; + height = MAX(height, 5+bitmap.GetHeight()); + } + } + } + + if (emulation_state != EMULATION_STOPPED) + { + // draw status text + if (show_status) { + if (updatestatus) { + updatestatus = 0; + get_status(statusMachineText, statusDeviceText); + } + if (statusMachineText) { + int statusX = 5; + int statusY = height+5; + wxSize size = dc.GetMultiLineTextExtent(statusMachineText); + dc.DrawText(statusMachineText, statusX, statusY); + width = MAX(width, statusX+size.GetWidth()); + height = MAX(height, statusY+size.GetHeight()); + if (statusDeviceText) { + wxSize dSize = dc.GetMultiLineTextExtent(statusDeviceText); + dc.DrawText(statusDeviceText, statusX+ceil((size.GetWidth()+50)/100.0)*100, statusY); + width = MAX(width, statusX+ceil((size.GetWidth()+50)/100.0)*100+ceil((dSize.GetWidth()+50)/100.0)*100); + height = MAX(height, statusY+dSize.GetHeight()); + } + } + } + + if (emulation_state == EMULATION_RUNNING && (millis-lastSpeedUpdate > 500)) { + lastSpeedUpdate = millis; + memmove(speedHistory+1, speedHistory, SPEED_HISTORY_LENGTH-2); + speedHistory[0] = fps; + } + // draw speed history + if (show_speed_history) { + int speedGraphBorder = 5; + int speedGraphX = 5; + int speedGraphY = height+5; + int speedGraphWidth = MAX(2*SPEED_HISTORY_LENGTH, width-5); + double lineLength = (double)(speedGraphWidth-2)/(SPEED_HISTORY_LENGTH-1); + int speedGraphHeight = 125; + dc.SetBrush(wxBrush(wxColour(255, 255, 255))); + dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight+speedGraphBorder*2); + dc.SetPen(wxPen(wxColour(200, 200, 200))); + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-0, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-0); // 0 + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-50, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-50); // 50 + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-100, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-100); // 100 + dc.DrawLine(speedGraphX, speedGraphY+speedGraphBorder+speedGraphHeight-125, speedGraphX+speedGraphWidth, speedGraphY+speedGraphHeight+speedGraphBorder-125); // 125 + dc.SetPen(wxPen(wxColour(0, 0, 0))); + for (int i = 0; i < SPEED_HISTORY_LENGTH-1; ++i) { + int v0 = speedHistory[i]; + int v1 = speedHistory[i+1]; + if (v0 >= 0 && v1 >= 0) { + dc.DrawLine(speedGraphX+speedGraphWidth-i*lineLength-1, speedGraphY+speedGraphHeight+speedGraphBorder-v0, + speedGraphX+speedGraphWidth-(i+1)*lineLength-1, speedGraphY+speedGraphHeight+speedGraphBorder-v1); + } + } + dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxBrushStyle(wxBRUSHSTYLE_TRANSPARENT))); + dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight+speedGraphBorder*2); + + width = MAX(width, (speedGraphX+speedGraphWidth)); + height = MAX(height, speedGraphY+speedGraphHeight+speedGraphBorder*2); + } + } + + width += 5; + height += 5; + width = width < DEFAULT_WINDOW_WIDTH ? DEFAULT_WINDOW_WIDTH : width; + height = height < DEFAULT_WINDOW_HEIGHT ? DEFAULT_WINDOW_HEIGHT : height; + if (cSize.GetWidth() != width || cSize.GetHeight() != height) { + GetParent()->SetClientSize(width, height); + } +} + +extern "C" +{ + int window_remember; + void wx_handle_command(void*, int, int); + + void resume_emulation(); + void pause_emulation(); + int stop_emulation_confirm(); + void reset_emulation(); + + void hdconf_open(void* hwnd); + void config_open(void* hwnd); +} + +int wx_window_x = 0; +int wx_window_y = 0; + +StatusFrame::StatusFrame(wxWindow* parent) : + wxFrame(parent, STATUS_WINDOW_ID, "PCem Machine", wxPoint(0, 0), wxSize(DEFAULT_WINDOW_WIDTH, 200), wxCAPTION | wxCLOSE_BOX) +{ + SetMenuBar(wxXmlResource::Get()->LoadMenuBar(wxT("status_menu"))); + SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("tool_bar"))); + + this->statusPane = new StatusPane(this); + wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(statusPane, 1, wxEXPAND); + SetSizer(sizer); + + Bind(wxEVT_MENU, &StatusFrame::OnCommand, this); + Bind(wxEVT_MOVE, &StatusFrame::OnMoveWindow, this); + + statusTimer = new StatusTimer(statusPane); + statusTimer->Start(); + + if (window_remember) + SetPosition(wxPoint(wx_window_x, wx_window_y)); + else + CenterOnScreen(); + + UpdateToolbar(); + GetMenuBar()->FindItem(XRCID("IDM_SHOW_STATUS"))->Check(show_status); + GetMenuBar()->FindItem(XRCID("IDM_SPEED_HISTORY"))->Check(show_speed_history); + GetMenuBar()->FindItem(XRCID("IDM_DISC_ACTIVITY"))->Check(show_disc_activity); + GetMenuBar()->FindItem(XRCID("IDM_MACHINE_MOUNT_PATHS"))->Check(show_mount_paths); + GetMenuBar()->FindItem(XRCID("IDM_SHOW_MACHINE_ON_START"))->Check(show_machine_on_start); +} + +StatusFrame::~StatusFrame() +{ + statusTimer->Stop(); + delete statusTimer; +} + +void StatusFrame::UpdateToolbar() +{ + GetToolBar()->EnableTool(XRCID("TOOLBAR_RUN"), emulation_state != EMULATION_RUNNING); + GetToolBar()->EnableTool(XRCID("TOOLBAR_PAUSE"), emulation_state != EMULATION_PAUSED); +} + +void StatusFrame::OnCommand(wxCommandEvent& event) +{ + if (event.GetId() == XRCID("TOOLBAR_RUN")) + { + resume_emulation(); + UpdateToolbar(); + } + else if (event.GetId() == XRCID("TOOLBAR_PAUSE")) + { + pause_emulation(); + UpdateToolbar(); + } + else if (event.GetId() == XRCID("TOOLBAR_RESET")) + { + int ret = wxID_OK; + if (confirm_on_reset_machine) + { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); + dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Reset machine?"); + dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); + dlg.Fit(); + ret = dlg.ShowModal(); + if (ret == wxID_OK) + confirm_on_reset_machine = !((wxCheckBox*)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); + } + if (ret == wxID_OK) + { + reset_emulation(); + UpdateToolbar(); + } + } + else if (event.GetId() == XRCID("TOOLBAR_STOP")) + wx_stop_emulation(GetParent()); + else if (event.GetId() == XRCID("IDM_SHOW_STATUS")) + show_status = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_SPEED_HISTORY")) + show_speed_history = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_DISC_ACTIVITY")) + show_disc_activity = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_MACHINE_MOUNT_PATHS")) + show_mount_paths = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_SHOW_MACHINE_ON_START")) + show_machine_on_start = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_HDCONF")) + hdconf_open(this); + else if (event.GetId() == XRCID("IDM_CONFIG")) + config_open(this); + else if (event.GetId() == XRCID("IDM_RESET_CONFIRMATION_DIALOGS")) + { + confirm_on_reset_machine = 1; + confirm_on_stop_emulation = 1; + wxMessageBox("Confirmation dialogs has been reset.", "PCem"); + } + else if (event.GetId() == XRCID("IDM_ABOUT")) + { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "AboutDlg"); + dlg.Fit(); + dlg.ShowModal(); + } + +} + +void StatusFrame::OnMoveWindow(wxMoveEvent& event) +{ + if (window_remember) { + wx_window_x = event.GetPosition().x; + wx_window_y = event.GetPosition().y; + } +} diff --git a/src/wx-status.h b/src/wx-status.h new file mode 100644 index 0000000..fd89f92 --- /dev/null +++ b/src/wx-status.h @@ -0,0 +1,70 @@ +#ifndef SRC_WX_STATUS_H_ +#define SRC_WX_STATUS_H_ + +#include +#include + +#define DEFAULT_WINDOW_WIDTH 350 +#define DEFAULT_WINDOW_HEIGHT 25 + +#define SPEED_HISTORY_LENGTH 240 + +class StatusPane; + +class StatusTimer : public wxTimer +{ +public: + StatusTimer(StatusPane* pane); + virtual ~StatusTimer() {}; + + void Notify(); + void Start(); +private: + StatusPane* pane; +}; + +class StatusPane : public wxPanel +{ + +public: + StatusPane(wxFrame* parent); + virtual ~StatusPane(); + + void PaintEvent(wxPaintEvent& evt); + void PaintNow(); + void Render( wxDC& dc ); + +private: + char machineInfoText[4096]; + char statusMachineText[4096]; + char statusDeviceText[4096]; + wxLongLong lastSpeedUpdate; + char speedHistory[SPEED_HISTORY_LENGTH]; + + wxBitmap bitmapFDD[2]; + wxBitmap bitmapCDROM[2]; + wxBitmap bitmapHDD[2]; + + DECLARE_EVENT_TABLE() +}; + +#define STATUS_WINDOW_ID 1000 + +class StatusFrame : public wxFrame { +public: + StatusFrame(wxWindow* parent); + virtual ~StatusFrame(); + void OnQuit(); +private: + void OnCommand(wxCommandEvent &event); + void OnMoveWindow(wxMoveEvent& event); + StatusPane* statusPane; + StatusTimer* statusTimer; + + void UpdateToolbar(); + + DECLARE_EVENT_TABLE() + +}; + +#endif /* SRC_WX_STATUS_H_ */ diff --git a/src/wx-thread.c b/src/wx-thread.c new file mode 100644 index 0000000..1015356 --- /dev/null +++ b/src/wx-thread.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include "thread.h" +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#include +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); +} + +#else +#include +#include + +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, (void*)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; + +#ifdef __linux__ + clock_gettime(CLOCK_REALTIME, &abstime); +#else + struct timeval now; + gettimeofday(&now, 0); + abstime.tv_sec = now.tv_sec; + abstime.tv_nsec = now.tv_usec*1000UL; +#endif + 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); + if (timeout == -1) + pthread_cond_wait(&event->cond, &event->mutex); + else + 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); +} +#endif diff --git a/src/wx-utils.cc b/src/wx-utils.cc new file mode 100644 index 0000000..398a6d9 --- /dev/null +++ b/src/wx-utils.cc @@ -0,0 +1,442 @@ +#include "wx-utils.h" + +#include +#ifndef WX_PRECOMP +#include +#endif + +#include +#include +#include + +#include "wx-dialogbox.h" +#include "wx-app.h" +#include "wx-common.h" +#include "wx-status.h" + +int confirm() +{ + if (emulation_state != EMULATION_STOPPED) { + return wx_messagebox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", WX_MB_OKCANCEL) == WX_IDOK; + } + return 1; +} + +int wx_messagebox(void* window, const char* message, const char* title = NULL, int style = 5) +{ + return wxMessageBox(message, title, style | wxCENTRE, (wxWindow*) window); +} + +int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, int min_length, int max_length, LONG_PARAM result) +{ + while (1) + { + wxTextEntryDialog dlg((wxWindow*)window, message, title, value); + if (max_length > 0) + dlg.SetMaxLength(max_length); + if (dlg.ShowModal() == wxID_OK) + { + wxString value = dlg.GetValue(); + if (value.Length() >= min_length) + { + strcpy((char*)result, value); + return TRUE; + } + } + else + return FALSE; + } + return FALSE; +} + +void wx_setwindowtitle(void* window, char* s) +{ + ((wxFrame*) window)->SetTitle(s); +} + +int wx_xrcid(const char* s) +{ + return XRCID(s); +} + +int wx_filedialog(void* window, const char* title, const char* path, + const char* extensions, const char* extension, int open, char* file) +{ + wxFileDialog dlg((wxWindow*) window, title, "", path, extensions, + open ? wxFD_OPEN : wxFD_SAVE); + if (dlg.ShowModal() == wxID_OK) + { + wxString p = dlg.GetPath(); + wxFileName f(p); + if (!open && !f.HasExt() && extension) + { + wxString e = extension; + if (!p.EndsWith(".")) + p += "."; + p += extension; + strcpy(file, p); + } + else + strcpy(file, p); + return 0; + } + return 1; +} + +void wx_checkmenuitem(void* menu, int id, int checked) +{ + wxMenuItem* item = NULL; + if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar*) menu)->FindItem(id); + else + item = ((wxMenu*) menu)->FindItem(id); + + if (item) + item->Check(checked); + else + std::cout << "Menu item not found: " << id << std::endl; +} + +void wx_enablemenuitem(void* menu, int id, int enable) +{ + wxMenuItem* item = NULL; + if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar*) menu)->FindItem(id); + else + item = ((wxMenu*) menu)->FindItem(id); + + if (item) + item->Enable(enable); + else + std::cout << "Menu item not found: " << id << std::endl; +} + +void* wx_getsubmenu(void* menu, int id) +{ + wxMenuItem* m = ((wxMenu*) menu)->FindItem(id); + if (m) + return m->GetSubMenu(); + + return 0; +} + +void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type) +{ + ((wxMenu*) sub_menu)->Append(id, title, wxEmptyString, type); +} + + +void wx_enabletoolbaritem(void* toolbar, int id, int enable) +{ + ((wxToolBar*) toolbar)->EnableTool(id, enable); +} + +void* wx_getmenu(void* window) +{ + return ((Frame*) window)->GetMenu(); +} + +void* wx_getmenubar(void* window) +{ + return ((wxFrame*) window)->GetMenuBar(); +} + +void* wx_gettoolbar(void* window) +{ + return ((wxFrame*) window)->GetToolBar(); +} + +void* wx_getdlgitem(void* window, int id) +{ + return ((wxWindow*) window)->FindWindow(id); +} + +void wx_setdlgitemtext(void* window, int id, char* str) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl*) w)->SetValue(str); + else + ((wxStaticText*) w)->SetLabel(str); +} + +void wx_enablewindow(void* window, int enabled) +{ + ((wxWindow*) window)->Enable(enabled); +} + +void wx_showwindow(void* window, int show) +{ + wxCommandEvent* event = new wxCommandEvent(WX_SHOW_WINDOW_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + event->SetInt(show); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_togglewindow(void* window) +{ + wx_showwindow(window, -1); +} + +void wx_callback(void* window, WX_CALLBACK callback) +{ + CallbackEvent* event = new CallbackEvent(callback); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_enddialog(void* window, int ret_code) +{ + ((wxDialog*) window)->EndModal(ret_code); +} + +int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) + { + wxListBox* list = (wxListBox*)w; + list->Clear(); + wxArrayString items; + wxString f = wxFindFirstFile(path); + while (!f.empty()) + { + wxFileName file(f); + items.Add(file.GetName()); + f = wxFindNextFile(); + } + items.Sort(); + list->Set(items); + return TRUE; + } + return FALSE; +} + +int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) + { + wxListBox* list = (wxListBox*)w; + strcpy((char*)path, (list->GetStringSelection() + ".").GetData().AsChar()); + return TRUE; + } + return FALSE; +} + +int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) +{ + switch (type) + { + case WX_CB_ADDSTRING: + ((wxComboBox*) window)->Append((char*) param2); + break; + case WX_CB_SETCURSEL: + ((wxComboBox*) window)->Select(param1); + break; + case WX_CB_GETCURSEL: + return ((wxComboBox*) window)->GetCurrentSelection(); + break; + case WX_CB_GETLBTEXT: + strcpy((char*) param2, ((wxComboBox*) window)->GetString(param1)); + break; + case WX_CB_RESETCONTENT: + { +#ifndef __WXOSX_MAC__ + ((wxComboBox*) window)->Clear(); +#else + /* Clear() does not work on OSX */ + wxComboBox* cb = (wxComboBox*) window; + int count = cb->GetCount(); + while (count--) + cb->Delete(0); +#endif + break; + } + case WX_BM_SETCHECK: + ((wxCheckBox*) window)->SetValue(param1); + break; + case WX_BM_GETCHECK: + return ((wxCheckBox*) window)->GetValue(); + break; + case WX_WM_SETTEXT: + { + if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl*) window)->SetValue((char*) param2); + else + ((wxStaticText*) window)->SetLabel((char*) param2); + } + break; + case WX_WM_GETTEXT: + if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + strcpy((char*) param2, ((wxTextCtrl*) window)->GetValue()); + else + strcpy((char*) param2, ((wxStaticText*) window)->GetLabel()); + break; + case WX_UDM_SETPOS: + ((wxSpinCtrl*) window)->SetValue(param2); + break; + case WX_UDM_GETPOS: + return ((wxSpinCtrl*) window)->GetValue(); + case WX_UDM_SETRANGE: + { + int min = (param2 >> 16) & 0xffff; + int max = param2 & 0xffff; + ((wxSpinCtrl*) window)->SetRange(min, max); + break; + } + case WX_UDM_SETINCR: + { + /* SetIncrement-method may not exist on all platforms */ +#ifdef __WXGTK__ + ((wxSpinCtrl*) window)->SetIncrement(param2); +#endif + break; + } + case WX_LB_GETCOUNT: + { + return ((wxListBox*) window)->GetCount(); + } + case WX_LB_GETCURSEL: + { + return ((wxListBox*) window)->GetSelection(); + } + case WX_LB_GETTEXT: + { + strcpy((char*) param2, ((wxListBox*) window)->GetString(param1)); + break; + } + case WX_LB_INSERTSTRING: + { + ((wxListBox*) window)->Insert((char*) param2, param1); + break; + } + case WX_LB_DELETESTRING: + { + ((wxListBox*) window)->Delete(param1); + break; + } + } + + ((wxWindow*)window)->Fit(); + + return 0; +} + +int wx_dialogbox(void* window, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) +{ + PCemDialogBox dlg((wxWindow*) window, name, callback); + dlg.OnInit(); + dlg.Fit(); + int ret = dlg.ShowModal(); + dlg.Destroy(); + return ret; +} + +void wx_exit(void* window, int value) +{ + wxCommandEvent* event = new wxCommandEvent(WX_EXIT_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + event->SetInt(value); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_stop_emulation(void* window) +{ + wxCommandEvent* event = new wxCommandEvent(WX_STOP_EMULATION_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + wxQueueEvent((wxWindow*)window, event); +} + +int wx_yield() +{ + return wxYield(); +} + +/* Timer stuff */ + +class PCemTimer : public wxTimer +{ +public: + PCemTimer(void (*fn)()) + { + this->fn = fn; + } + virtual ~PCemTimer() {}; + + void Notify() + { + fn(); + } +private: + void (*fn)(); +}; + +void* wx_createtimer(void (*fn)()) +{ + return new PCemTimer(fn); +} + +void wx_starttimer(void* timer, int milliseconds, int once) +{ + wxTimer* t = (wxTimer*)timer; + t->Start(milliseconds, once); +} + +void wx_stoptimer(void* timer) +{ + wxTimer* t = (wxTimer*)timer; + t->Stop(); +} + +void wx_destroytimer(void* timer) +{ + wx_stoptimer(timer); + delete (wxTimer*)timer; +} + +void wx_popupmenu(void* window, void* menu, int* x, int* y) +{ + PopupMenuEvent* event = new PopupMenuEvent((wxWindow*)window, (wxMenu*)menu, x, y); + wxQueueEvent((wxWindow*)window, event); +} + +void* wx_create_status_frame(void* window) +{ + StatusFrame* frame = new StatusFrame((wxWindow*)window); + return frame; +} + +void wx_destroy_status_frame(void* window) +{ + StatusFrame* frame = (StatusFrame*)window; + delete frame; +} + +void wx_setwindowposition(void* window, int x, int y) +{ + ((wxFrame*) window)->SetPosition(wxPoint(x, y)); +} + +void wx_setwindowsize(void* window, int width, int height) +{ + ((wxFrame*) window)->SetSize(wxSize(width, height)); +} + +void wx_show_status(void* window) +{ + wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); + if (!status) + { + StatusFrame* statusFrame = new StatusFrame((wxWindow*) window); + statusFrame->Show(); + } +} + +void wx_close_status(void* window) +{ + wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); + if (status) + { + status->Close(); + } +} diff --git a/src/wx-utils.h b/src/wx-utils.h new file mode 100644 index 0000000..84296bf --- /dev/null +++ b/src/wx-utils.h @@ -0,0 +1,112 @@ +#include + +#ifndef LONG_PARAM +#define LONG_PARAM wxIntPtr +#endif + +#ifndef INT_PARAM +#define INT_PARAM wxInt32 +#endif + +typedef void (*WX_CALLBACK)(); + +#ifdef __cplusplus +extern "C" { +#endif + int wx_messagebox(void* nothing, const char* message, const char* title, int style); + int wx_xrcid(const char* s); + int wx_filedialog(void* window, const char* title, const char* path, const char* extensions, const char* extension, int open, char* file); + void wx_checkmenuitem(void* window, int id, int checked); + void wx_enablemenuitem(void* menu, int id, int enable); + void* wx_getmenu(void* window); + void* wx_getmenubar(void* window); + void wx_enabletoolbaritem(void* toolbar, int id, int enable); + void* wx_gettoolbar(void* window); + + void* wx_getsubmenu(void* window, int id); + void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type); + + int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, int min_length, int max_length, LONG_PARAM result); + + int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type); + int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id); + + void wx_setwindowtitle(void* window, char* s); + int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2); + void* wx_getdlgitem(void* window, int id); + void wx_setdlgitemtext(void* window, int id, char* str); + void wx_enablewindow(void* window, int enabled); + void wx_showwindow(void* window, int show); + void wx_callback(void* window, WX_CALLBACK callback); + void wx_togglewindow(void* window); + + void wx_enddialog(void* window, int ret_code); + + int wx_dialogbox(void* window, const char* name, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); + + void wx_exit(void* window, int value); + void wx_stop_emulation(void* window); + + void* wx_createtimer(void (*fn)()); + void wx_starttimer(void* timer, int milliseconds, int once); + void wx_stoptimer(void* timer); + void wx_destroytimer(void* timer); + + void wx_popupmenu(void* window, void* menu, int* x, int* y); + + void* wx_create_status_frame(void* window); + void wx_destroy_status_frame(void* window); + + int wx_yield(); + + void wx_setwindowposition(void* window, int x, int y); + void wx_setwindowsize(void* window, int width, int height); + + void wx_show_status(void* window); + void wx_close_status(void* window); + + int confirm(); +#ifdef __cplusplus +} +#endif + +extern int (*wx_keydown_func)(void* window, void* event, int keycode, int modifiers); +extern int (*wx_keyup_func)(void* window, void* event, int keycode, int modifiers); +extern void (*wx_idle_func)(void* window, void* event); + +#define WX_ID wx_xrcid + +#define WX_MB_CHECKED 1 +#define WX_MB_UNCHECKED 0 + +#define WX_INITDIALOG 1 +#define WX_COMMAND 2 + +#define WX_CB_ADDSTRING 1 +#define WX_CB_SETCURSEL 2 +#define WX_CB_GETCURSEL 3 +#define WX_CB_RESETCONTENT 4 +#define WX_CB_GETLBTEXT 5 + +#define WX_BM_SETCHECK 20 +#define WX_BM_GETCHECK 21 + +#define WX_WM_SETTEXT 40 +#define WX_WM_GETTEXT 41 + +#define WX_UDM_SETPOS 50 +#define WX_UDM_GETPOS 51 +#define WX_UDM_SETINCR 52 +#define WX_UDM_SETRANGE 53 + +#define WX_LB_GETCOUNT 60 +#define WX_LB_GETCURSEL 61 +#define WX_LB_GETTEXT 62 +#define WX_LB_DELETESTRING 63 +#define WX_LB_INSERTSTRING 64 + +#define WX_MB_OK wxOK +#define WX_MB_OKCANCEL wxOK|wxCANCEL +#define WX_IDOK wxOK + +extern int has_been_inited; From 23b2ae0d9d0f49cf4e43aefba9b38f88b44212d3 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Mon, 29 May 2017 16:24:08 +0100 Subject: [PATCH 0020/1050] wxWidgets GUI can now be built through autoconf (use '--enable-wx'). --- Makefile.in | 19 + aclocal.m4 | 1539 +++++++++++++++++++++++++++++++++++++++++++++++ configure | 882 ++++++++++++++++++++++++++- configure.ac | 52 +- src/Makefile.am | 27 +- src/Makefile.in | 1368 ++++++++++++++++++++++++++--------------- 6 files changed, 3373 insertions(+), 514 deletions(-) diff --git a/Makefile.in b/Makefile.in index 78e714f..3bdd759 100644 --- a/Makefile.in +++ b/Makefile.in @@ -243,10 +243,29 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +SDL2_CONFIG = @SDL2_CONFIG@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_RESCOMP = @WX_RESCOMP@ +WX_VERSION = @WX_VERSION@ +WX_VERSION_MAJOR = @WX_VERSION_MAJOR@ +WX_VERSION_MICRO = @WX_VERSION_MICRO@ +WX_VERSION_MINOR = @WX_VERSION_MINOR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff --git a/aclocal.m4 b/aclocal.m4 index ad14be9..b525be4 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -20,6 +20,1545 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR + +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +# serial 1 + +dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL2], +[dnl +dnl Get the cflags and libraries from the sdl2-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + min_sdl_version=ifelse([$1], ,2.0.0,$1) + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version], + [sdl_pc=yes], + [sdl_pc=no]) + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL2_CONFIG="pkg-config sdl2" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) + PATH="$as_save_PATH" + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + + if test "$SDL2_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl2-config to some extent +dnl + rm -f conf.sdltest + AC_TRY_RUN([ +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); + printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + if test "x$no_sdl" = x ; then + ifelse([$2], , :, [$2]) + else + if test "$SDL2_CONFIG" = "no" ; then + echo "*** The sdl2-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" + echo "*** full path to sdl2-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_TRY_LINK([ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) + +dnl --------------------------------------------------------------------------- +dnl Author: wxWidgets development team, +dnl Francesco Montorsi, +dnl Bob McCown (Mac-testing) +dnl Creation date: 24/11/2001 +dnl --------------------------------------------------------------------------- + +dnl =========================================================================== +dnl Table of Contents of this macro file: +dnl ------------------------------------- +dnl +dnl SECTION A: wxWidgets main macros +dnl - WX_CONFIG_OPTIONS +dnl - WX_CONFIG_CHECK +dnl - WXRC_CHECK +dnl - WX_STANDARD_OPTIONS +dnl - WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS +dnl - WX_DETECT_STANDARD_OPTION_VALUES +dnl +dnl SECTION B: wxWidgets-related utilities +dnl - WX_LIKE_LIBNAME +dnl - WX_ARG_ENABLE_YESNOAUTO +dnl - WX_ARG_WITH_YESNOAUTO +dnl +dnl SECTION C: messages to the user +dnl - WX_STANDARD_OPTIONS_SUMMARY_MSG +dnl - WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN +dnl - WX_STANDARD_OPTIONS_SUMMARY_MSG_END +dnl - WX_BOOLOPT_SUMMARY +dnl +dnl The special "WX_DEBUG_CONFIGURE" variable can be set to 1 to enable extra +dnl debug output on stdout from these macros. +dnl =========================================================================== + + +dnl --------------------------------------------------------------------------- +dnl Macros for wxWidgets detection. Typically used in configure.in as: +dnl +dnl AC_ARG_ENABLE(...) +dnl AC_ARG_WITH(...) +dnl ... +dnl WX_CONFIG_OPTIONS +dnl ... +dnl ... +dnl WX_CONFIG_CHECK([2.6.0], [wxWin=1]) +dnl if test "$wxWin" != 1; then +dnl AC_MSG_ERROR([ +dnl wxWidgets must be installed on your system +dnl but wx-config script couldn't be found. +dnl +dnl Please check that wx-config is in path, the directory +dnl where wxWidgets libraries are installed (returned by +dnl 'wx-config --libs' command) is in LD_LIBRARY_PATH or +dnl equivalent variable and wxWidgets version is 2.3.4 or above. +dnl ]) +dnl fi +dnl CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" +dnl CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY" +dnl CFLAGS="$CFLAGS $WX_CFLAGS_ONLY" +dnl +dnl LIBS="$LIBS $WX_LIBS" +dnl +dnl If you want to support standard --enable-debug/unicode/shared options, you +dnl may do the following: +dnl +dnl ... +dnl AC_CANONICAL_SYSTEM +dnl +dnl # define configure options +dnl WX_CONFIG_OPTIONS +dnl WX_STANDARD_OPTIONS([debug,unicode,shared,toolkit,wxshared]) +dnl +dnl # basic configure checks +dnl ... +dnl +dnl # we want to always have DEBUG==WX_DEBUG and UNICODE==WX_UNICODE +dnl WX_DEBUG=$DEBUG +dnl WX_UNICODE=$UNICODE +dnl +dnl WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS +dnl WX_CONFIG_CHECK([2.8.0], [wxWin=1],,[html,core,net,base],[$WXCONFIG_FLAGS]) +dnl WX_DETECT_STANDARD_OPTION_VALUES +dnl +dnl # write the output files +dnl AC_CONFIG_FILES([Makefile ...]) +dnl AC_OUTPUT +dnl +dnl # optional: just to show a message to the user +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG +dnl +dnl --------------------------------------------------------------------------- + + +dnl --------------------------------------------------------------------------- +dnl WX_CONFIG_OPTIONS +dnl +dnl adds support for --wx-prefix, --wx-exec-prefix, --with-wxdir and +dnl --wx-config command line options +dnl --------------------------------------------------------------------------- + +AC_DEFUN([WX_CONFIG_OPTIONS], +[ + AC_ARG_WITH(wxdir, + [ --with-wxdir=PATH Use uninstalled version of wxWidgets in PATH], + [ wx_config_name="$withval/wx-config" + wx_config_args="--inplace"]) + AC_ARG_WITH(wx-config, + [ --with-wx-config=CONFIG wx-config script to use (optional)], + wx_config_name="$withval" ) + AC_ARG_WITH(wx-prefix, + [ --with-wx-prefix=PREFIX Prefix where wxWidgets is installed (optional)], + wx_config_prefix="$withval", wx_config_prefix="") + AC_ARG_WITH(wx-exec-prefix, + [ --with-wx-exec-prefix=PREFIX + Exec prefix where wxWidgets is installed (optional)], + wx_config_exec_prefix="$withval", wx_config_exec_prefix="") +]) + +dnl Helper macro for checking if wx version is at least $1.$2.$3, set's +dnl wx_ver_ok=yes if it is: +AC_DEFUN([_WX_PRIVATE_CHECK_VERSION], +[ + wx_ver_ok="" + if test "x$WX_VERSION" != x ; then + if test $wx_config_major_version -gt $1; then + wx_ver_ok=yes + else + if test $wx_config_major_version -eq $1; then + if test $wx_config_minor_version -gt $2; then + wx_ver_ok=yes + else + if test $wx_config_minor_version -eq $2; then + if test $wx_config_micro_version -ge $3; then + wx_ver_ok=yes + fi + fi + fi + fi + fi + fi +]) + +dnl --------------------------------------------------------------------------- +dnl WX_CONFIG_CHECK(VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND +dnl [, WX-LIBS [, ADDITIONAL-WX-CONFIG-FLAGS]]]]) +dnl +dnl Test for wxWidgets, and define WX_C*FLAGS, WX_LIBS and WX_LIBS_STATIC +dnl (the latter is for static linking against wxWidgets). Set WX_CONFIG_NAME +dnl environment variable to override the default name of the wx-config script +dnl to use. Set WX_CONFIG_PATH to specify the full path to wx-config - in this +dnl case the macro won't even waste time on tests for its existence. +dnl +dnl Optional WX-LIBS argument contains comma- or space-separated list of +dnl wxWidgets libraries to link against. If it is not specified then WX_LIBS +dnl and WX_LIBS_STATIC will contain flags to link with all of the core +dnl wxWidgets libraries. +dnl +dnl Optional ADDITIONAL-WX-CONFIG-FLAGS argument is appended to wx-config +dnl invocation command in present. It can be used to fine-tune lookup of +dnl best wxWidgets build available. +dnl +dnl Example use: +dnl WX_CONFIG_CHECK([2.6.0], [wxWin=1], [wxWin=0], [html,core,net] +dnl [--unicode --debug]) +dnl --------------------------------------------------------------------------- + +dnl +dnl Get the cflags and libraries from the wx-config script +dnl +AC_DEFUN([WX_CONFIG_CHECK], +[ + dnl do we have wx-config name: it can be wx-config or wxd-config or ... + if test x${WX_CONFIG_NAME+set} != xset ; then + WX_CONFIG_NAME=wx-config + fi + + if test "x$wx_config_name" != x ; then + WX_CONFIG_NAME="$wx_config_name" + fi + + dnl deal with optional prefixes + if test x$wx_config_exec_prefix != x ; then + wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix" + WX_LOOKUP_PATH="$wx_config_exec_prefix/bin" + fi + if test x$wx_config_prefix != x ; then + wx_config_args="$wx_config_args --prefix=$wx_config_prefix" + WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin" + fi + if test "$cross_compiling" = "yes"; then + wx_config_args="$wx_config_args --host=$host_alias" + fi + + dnl don't search the PATH if WX_CONFIG_NAME is absolute filename + if test -x "$WX_CONFIG_NAME" ; then + AC_MSG_CHECKING(for wx-config) + WX_CONFIG_PATH="$WX_CONFIG_NAME" + AC_MSG_RESULT($WX_CONFIG_PATH) + else + AC_PATH_PROG(WX_CONFIG_PATH, $WX_CONFIG_NAME, no, "$WX_LOOKUP_PATH:$PATH") + fi + + if test "$WX_CONFIG_PATH" != "no" ; then + WX_VERSION="" + + min_wx_version=ifelse([$1], ,2.2.1,$1) + if test -z "$5" ; then + AC_MSG_CHECKING([for wxWidgets version >= $min_wx_version]) + else + AC_MSG_CHECKING([for wxWidgets version >= $min_wx_version ($5)]) + fi + + dnl don't add the libraries ($4) to this variable as this would result in + dnl an error when it's used with --version below + WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args $5" + + WX_VERSION=`$WX_CONFIG_WITH_ARGS --version 2>/dev/null` + wx_config_major_version=`echo $WX_VERSION | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + wx_config_minor_version=`echo $WX_VERSION | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + wx_config_micro_version=`echo $WX_VERSION | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + wx_requested_major_version=`echo $min_wx_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + wx_requested_minor_version=`echo $min_wx_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + wx_requested_micro_version=`echo $min_wx_version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + _WX_PRIVATE_CHECK_VERSION([$wx_requested_major_version], + [$wx_requested_minor_version], + [$wx_requested_micro_version]) + + if test -n "$wx_ver_ok"; then + AC_MSG_RESULT(yes (version $WX_VERSION)) + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs $4` + + dnl is this even still appropriate? --static is a real option now + dnl and WX_CONFIG_WITH_ARGS is likely to contain it if that is + dnl what the user actually wants, making this redundant at best. + dnl For now keep it in case anyone actually used it in the past. + AC_MSG_CHECKING([for wxWidgets static library]) + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs $4 2>/dev/null` + if test "x$WX_LIBS_STATIC" = "x"; then + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi + + dnl starting with version 2.2.6 wx-config has --cppflags argument + wx_has_cppflags="" + if test $wx_config_major_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_minor_version -eq 2; then + if test $wx_config_micro_version -ge 6; then + wx_has_cppflags=yes + fi + fi + fi + fi + fi + + dnl starting with version 2.7.0 wx-config has --rescomp option + wx_has_rescomp="" + if test $wx_config_major_version -gt 2; then + wx_has_rescomp=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -ge 7; then + wx_has_rescomp=yes + fi + fi + fi + if test "x$wx_has_rescomp" = x ; then + dnl cannot give any useful info for resource compiler + WX_RESCOMP= + else + WX_RESCOMP=`$WX_CONFIG_WITH_ARGS --rescomp` + fi + + if test "x$wx_has_cppflags" = x ; then + dnl no choice but to define all flags like CFLAGS + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags $4` + WX_CPPFLAGS=$WX_CFLAGS + WX_CXXFLAGS=$WX_CFLAGS + + WX_CFLAGS_ONLY=$WX_CFLAGS + WX_CXXFLAGS_ONLY=$WX_CFLAGS + else + dnl we have CPPFLAGS included in CFLAGS included in CXXFLAGS + WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags $4` + WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags $4` + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags $4` + + WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"` + WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"` + fi + + ifelse([$2], , :, [$2]) + + else + + if test "x$WX_VERSION" = x; then + dnl no wx-config at all + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(no (version $WX_VERSION is not new enough)) + fi + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + if test ! -z "$5"; then + + wx_error_message=" + The configuration you asked for $PACKAGE_NAME requires a wxWidgets + build with the following settings: + $5 + but such build is not available. + + To see the wxWidgets builds available on this system, please use + 'wx-config --list' command. To use the default build, returned by + 'wx-config --selected-config', use the options with their 'auto' + default values." + + fi + + wx_error_message=" + The requested wxWidgets build couldn't be found. + $wx_error_message + + If you still get this error, then check that 'wx-config' is + in path, the directory where wxWidgets libraries are installed + (returned by 'wx-config --libs' command) is in LD_LIBRARY_PATH + or equivalent variable and wxWidgets version is $1 or above." + + ifelse([$3], , AC_MSG_ERROR([$wx_error_message]), [$3]) + + fi + else + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + ifelse([$3], , :, [$3]) + + fi + + AC_SUBST(WX_CPPFLAGS) + AC_SUBST(WX_CFLAGS) + AC_SUBST(WX_CXXFLAGS) + AC_SUBST(WX_CFLAGS_ONLY) + AC_SUBST(WX_CXXFLAGS_ONLY) + AC_SUBST(WX_LIBS) + AC_SUBST(WX_LIBS_STATIC) + AC_SUBST(WX_VERSION) + AC_SUBST(WX_RESCOMP) + + dnl need to export also WX_VERSION_MINOR and WX_VERSION_MAJOR symbols + dnl to support wxpresets bakefiles (we export also WX_VERSION_MICRO for completeness): + WX_VERSION_MAJOR="$wx_config_major_version" + WX_VERSION_MINOR="$wx_config_minor_version" + WX_VERSION_MICRO="$wx_config_micro_version" + AC_SUBST(WX_VERSION_MAJOR) + AC_SUBST(WX_VERSION_MINOR) + AC_SUBST(WX_VERSION_MICRO) +]) + +dnl --------------------------------------------------------------------------- +dnl Get information on the wxrc program for making C++, Python and xrs +dnl resource files. +dnl +dnl AC_ARG_ENABLE(...) +dnl AC_ARG_WITH(...) +dnl ... +dnl WX_CONFIG_OPTIONS +dnl ... +dnl WX_CONFIG_CHECK(2.6.0, wxWin=1) +dnl if test "$wxWin" != 1; then +dnl AC_MSG_ERROR([ +dnl wxWidgets must be installed on your system +dnl but wx-config script couldn't be found. +dnl +dnl Please check that wx-config is in path, the directory +dnl where wxWidgets libraries are installed (returned by +dnl 'wx-config --libs' command) is in LD_LIBRARY_PATH or +dnl equivalent variable and wxWidgets version is 2.6.0 or above. +dnl ]) +dnl fi +dnl +dnl WXRC_CHECK([HAVE_WXRC=1], [HAVE_WXRC=0]) +dnl if test "x$HAVE_WXRC" != x1; then +dnl AC_MSG_ERROR([ +dnl The wxrc program was not installed or not found. +dnl +dnl Please check the wxWidgets installation. +dnl ]) +dnl fi +dnl +dnl CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS" +dnl CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY" +dnl CFLAGS="$CFLAGS $WX_CFLAGS_ONLY" +dnl +dnl LDFLAGS="$LDFLAGS $WX_LIBS" +dnl --------------------------------------------------------------------------- + +dnl --------------------------------------------------------------------------- +dnl WXRC_CHECK([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl +dnl Test for wxWidgets' wxrc program for creating either C++, Python or XRS +dnl resources. The variable WXRC will be set and substituted in the configure +dnl script and Makefiles. +dnl +dnl Example use: +dnl WXRC_CHECK([wxrc=1], [wxrc=0]) +dnl --------------------------------------------------------------------------- + +dnl +dnl wxrc program from the wx-config script +dnl +AC_DEFUN([WXRC_CHECK], +[ + AC_ARG_VAR([WXRC], [Path to wxWidget's wxrc resource compiler]) + + if test "x$WX_CONFIG_NAME" = x; then + AC_MSG_ERROR([The wxrc tests must run after wxWidgets test.]) + else + + AC_MSG_CHECKING([for wxrc]) + + if test "x$WXRC" = x ; then + dnl wx-config --utility is a new addition to wxWidgets: + _WX_PRIVATE_CHECK_VERSION(2,5,3) + if test -n "$wx_ver_ok"; then + WXRC=`$WX_CONFIG_WITH_ARGS --utility=wxrc` + fi + fi + + if test "x$WXRC" = x ; then + AC_MSG_RESULT([not found]) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT([$WXRC]) + ifelse([$1], , :, [$1]) + fi + + AC_SUBST(WXRC) + fi +]) + +dnl --------------------------------------------------------------------------- +dnl WX_LIKE_LIBNAME([output-var] [prefix], [name]) +dnl +dnl Sets the "output-var" variable to the name of a library named with same +dnl wxWidgets rule. +dnl E.g. for output-var=='lib', name=='test', prefix='mine', sets +dnl the $lib variable to: +dnl 'mine_gtk2ud_test-2.8' +dnl if WX_PORT=gtk2, WX_UNICODE=1, WX_DEBUG=1 and WX_RELEASE=28 +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_LIKE_LIBNAME], + [ + wx_temp="$2""_""$WX_PORT" + + dnl add the [u][d] string + if test "$WX_UNICODE" = "1"; then + wx_temp="$wx_temp""u" + fi + if test "$WX_DEBUG" = "1"; then + wx_temp="$wx_temp""d" + fi + + dnl complete the name of the lib + wx_temp="$wx_temp""_""$3""-$WX_VERSION_MAJOR.$WX_VERSION_MINOR" + + dnl save it in the user's variable + $1=$wx_temp + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_ARG_ENABLE_YESNOAUTO/WX_ARG_WITH_YESNOAUTO +dnl +dnl Two little custom macros which define the ENABLE/WITH configure arguments. +dnl Macro arguments: +dnl $1 = the name of the --enable / --with feature +dnl $2 = the name of the variable associated +dnl $3 = the description of that feature +dnl $4 = the default value for that feature +dnl $5 = additional action to do in case option is given with "yes" value +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_ARG_ENABLE_YESNOAUTO], + [AC_ARG_ENABLE($1, + AC_HELP_STRING([--enable-$1], [$3 (default is $4)]), + [], [enableval="$4"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --enable-$1 option]) + if test "$enableval" = "yes" ; then + AC_MSG_RESULT([yes]) + $2=1 + $5 + elif test "$enableval" = "no" ; then + AC_MSG_RESULT([no]) + $2=0 + elif test "$enableval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + $2="auto" + else + AC_MSG_ERROR([ + Unrecognized option value (allowed values: yes, no, auto) + ]) + fi + ]) + +AC_DEFUN([WX_ARG_WITH_YESNOAUTO], + [AC_ARG_WITH($1, + AC_HELP_STRING([--with-$1], [$3 (default is $4)]), + [], [withval="$4"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --with-$1 option]) + if test "$withval" = "yes" ; then + AC_MSG_RESULT([yes]) + $2=1 + $5 + dnl NB: by default we don't allow --with-$1=no option + dnl since it does not make much sense ! + elif test "$6" = "1" -a "$withval" = "no" ; then + AC_MSG_RESULT([no]) + $2=0 + elif test "$withval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + $2="auto" + else + AC_MSG_ERROR([ + Unrecognized option value (allowed values: yes, auto) + ]) + fi + ]) + + +dnl --------------------------------------------------------------------------- +dnl WX_STANDARD_OPTIONS([options-to-add]) +dnl +dnl Adds to the configure script one or more of the following options: +dnl --enable-[debug|unicode|shared|wxshared|wxdebug] +dnl --with-[gtk|msw|motif|x11|mac|dfb] +dnl --with-wxversion +dnl Then checks for their presence and eventually set the DEBUG, UNICODE, SHARED, +dnl PORT, WX_SHARED, WX_DEBUG, variables to one of the "yes", "no", "auto" values. +dnl +dnl Note that e.g. UNICODE != WX_UNICODE; the first is the value of the +dnl --enable-unicode option (in boolean format) while the second indicates +dnl if wxWidgets was built in Unicode mode (and still is in boolean format). +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_STANDARD_OPTIONS], + [ + + dnl the following lines will expand to WX_ARG_ENABLE_YESNOAUTO calls if and only if + dnl the $1 argument contains respectively the debug,unicode or shared options. + + dnl be careful here not to set debug flag if only "wxdebug" was specified + ifelse(regexp([$1], [\bdebug]), [-1],, + [WX_ARG_ENABLE_YESNOAUTO([debug], [DEBUG], [Build in debug mode], [auto])]) + + ifelse(index([$1], [unicode]), [-1],, + [WX_ARG_ENABLE_YESNOAUTO([unicode], [UNICODE], [Build in Unicode mode], [auto])]) + + ifelse(regexp([$1], [\bshared]), [-1],, + [WX_ARG_ENABLE_YESNOAUTO([shared], [SHARED], [Build as shared library], [auto])]) + + dnl WX_ARG_WITH_YESNOAUTO cannot be used for --with-toolkit since it's an option + dnl which must be able to accept the auto|gtk1|gtk2|msw|... values + ifelse(index([$1], [toolkit]), [-1],, + [ + AC_ARG_WITH([toolkit], + AC_HELP_STRING([--with-toolkit], + [Build against a specific wxWidgets toolkit (default is auto)]), + [], [withval="auto"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --with-toolkit option]) + if test "$withval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + TOOLKIT="auto" + else + TOOLKIT="$withval" + + dnl PORT must be one of the allowed values + if test "$TOOLKIT" != "gtk1" -a "$TOOLKIT" != "gtk2" -a \ + "$TOOLKIT" != "msw" -a "$TOOLKIT" != "motif" -a \ + "$TOOLKIT" != "osx_carbon" -a "$TOOLKIT" != "osx_cocoa" -a \ + "$TOOLKIT" != "dfb" -a "$TOOLKIT" != "x11"; then + AC_MSG_ERROR([ + Unrecognized option value (allowed values: auto, gtk1, gtk2, msw, motif, osx_carbon, osx_cocoa, dfb, x11) + ]) + fi + + AC_MSG_RESULT([$TOOLKIT]) + fi + ]) + + dnl ****** IMPORTANT ******* + dnl Unlike for the UNICODE setting, you can build your program in + dnl shared mode against a static build of wxWidgets. Thus we have the + dnl following option which allows these mixtures. E.g. + dnl + dnl ./configure --disable-shared --with-wxshared + dnl + dnl will build your library in static mode against the first available + dnl shared build of wxWidgets. + dnl + dnl Note that's not possible to do the viceversa: + dnl + dnl ./configure --enable-shared --without-wxshared + dnl + dnl Doing so you would try to build your library in shared mode against a static + dnl build of wxWidgets. This is not possible (you would mix PIC and non PIC code) ! + dnl A check for this combination of options is in WX_DETECT_STANDARD_OPTION_VALUES + dnl (where we know what 'auto' should be expanded to). + dnl + dnl If you try to build something in ANSI mode against a UNICODE build + dnl of wxWidgets or in RELEASE mode against a DEBUG build of wxWidgets, + dnl then at best you'll get ton of linking errors ! + dnl ************************ + + ifelse(index([$1], [wxshared]), [-1],, + [ + WX_ARG_WITH_YESNOAUTO( + [wxshared], [WX_SHARED], + [Force building against a shared build of wxWidgets, even if --disable-shared is given], + [auto], [], [1]) + ]) + + dnl Just like for SHARED and WX_SHARED it may happen that some adventurous + dnl peoples will want to mix a wxWidgets release build with a debug build of + dnl his app/lib. So, we have both DEBUG and WX_DEBUG variables. + ifelse(index([$1], [wxdebug]), [-1],, + [ + WX_ARG_WITH_YESNOAUTO( + [wxdebug], [WX_DEBUG], + [Force building against a debug build of wxWidgets, even if --disable-debug is given], + [auto], [], [1]) + ]) + + dnl WX_ARG_WITH_YESNOAUTO cannot be used for --with-wxversion since it's an option + dnl which accepts the "auto|2.6|2.7|2.8|2.9|3.0" etc etc values + ifelse(index([$1], [wxversion]), [-1],, + [ + AC_ARG_WITH([wxversion], + AC_HELP_STRING([--with-wxversion], + [Build against a specific version of wxWidgets (default is auto)]), + [], [withval="auto"]) + + dnl Show a message to the user about this option + AC_MSG_CHECKING([for the --with-wxversion option]) + if test "$withval" = "auto" ; then + AC_MSG_RESULT([will be automatically detected]) + WX_RELEASE="auto" + else + + wx_requested_major_version=`echo $withval | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).*/\1/'` + wx_requested_minor_version=`echo $withval | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).*/\2/'` + + dnl both vars above must be exactly 1 digit + if test "${#wx_requested_major_version}" != "1" -o \ + "${#wx_requested_minor_version}" != "1" ; then + AC_MSG_ERROR([ + Unrecognized option value (allowed values: auto, 2.6, 2.7, 2.8, 2.9, 3.0) + ]) + fi + + WX_RELEASE="$wx_requested_major_version"".""$wx_requested_minor_version" + AC_MSG_RESULT([$WX_RELEASE]) + fi + ]) + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] DEBUG: $DEBUG, WX_DEBUG: $WX_DEBUG" + echo "[[dbg]] UNICODE: $UNICODE, WX_UNICODE: $WX_UNICODE" + echo "[[dbg]] SHARED: $SHARED, WX_SHARED: $WX_SHARED" + echo "[[dbg]] TOOLKIT: $TOOLKIT, WX_TOOLKIT: $WX_TOOLKIT" + echo "[[dbg]] VERSION: $VERSION, WX_RELEASE: $WX_RELEASE" + fi + ]) + + +dnl --------------------------------------------------------------------------- +dnl WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS +dnl +dnl Sets the WXCONFIG_FLAGS string using the SHARED,DEBUG,UNICODE variable values +dnl which are different from "auto". +dnl Thus this macro needs to be called only once all options have been set. +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS], + [ + if test "$WX_SHARED" = "1" ; then + WXCONFIG_FLAGS="--static=no " + elif test "$WX_SHARED" = "0" ; then + WXCONFIG_FLAGS="--static=yes " + fi + + if test "$WX_DEBUG" = "1" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--debug=yes " + elif test "$WX_DEBUG" = "0" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--debug=no " + fi + + dnl The user should have set WX_UNICODE=UNICODE + if test "$WX_UNICODE" = "1" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--unicode=yes " + elif test "$WX_UNICODE" = "0" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--unicode=no " + fi + + if test "$TOOLKIT" != "auto" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--toolkit=$TOOLKIT " + fi + + if test "$WX_RELEASE" != "auto" ; then + WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--version=$WX_RELEASE " + fi + + dnl strip out the last space of the string + WXCONFIG_FLAGS=${WXCONFIG_FLAGS% } + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] WXCONFIG_FLAGS: $WXCONFIG_FLAGS" + fi + ]) + + +dnl --------------------------------------------------------------------------- +dnl _WX_SELECTEDCONFIG_CHECKFOR([RESULTVAR], [STRING], [MSG] +dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl +dnl Outputs the given MSG. Then searches the given STRING in the wxWidgets +dnl additional CPP flags and put the result of the search in WX_$RESULTVAR +dnl also adding the "yes" or "no" message result to MSG. +dnl --------------------------------------------------------------------------- +AC_DEFUN([_WX_SELECTEDCONFIG_CHECKFOR], + [ + if test "$$1" = "auto" ; then + + dnl The user does not have particular preferences for this option; + dnl so we will detect the wxWidgets relative build setting and use it + AC_MSG_CHECKING([$3]) + + dnl set WX_$1 variable to 1 if the $WX_SELECTEDCONFIG contains the $2 + dnl string or to 0 otherwise. + dnl NOTE: 'expr match STRING REGEXP' cannot be used since on Mac it + dnl doesn't work; we use 'expr STRING : REGEXP' instead + WX_$1=$(expr "$WX_SELECTEDCONFIG" : ".*$2.*") + + if test "$WX_$1" != "0"; then + WX_$1=1 + AC_MSG_RESULT([yes]) + ifelse([$4], , :, [$4]) + else + WX_$1=0 + AC_MSG_RESULT([no]) + ifelse([$5], , :, [$5]) + fi + else + + dnl Use the setting given by the user + WX_$1=$$1 + fi + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_DETECT_STANDARD_OPTION_VALUES +dnl +dnl Detects the values of the following variables: +dnl 1) WX_RELEASE +dnl 2) WX_UNICODE +dnl 3) WX_DEBUG +dnl 4) WX_SHARED (and also WX_STATIC) +dnl 5) WX_PORT +dnl from the previously selected wxWidgets build; this macro in fact must be +dnl called *after* calling the WX_CONFIG_CHECK macro. +dnl +dnl Note that the WX_VERSION_MAJOR, WX_VERSION_MINOR symbols are already set +dnl by WX_CONFIG_CHECK macro +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], + [ + dnl IMPORTANT: WX_VERSION contains all three major.minor.micro digits, + dnl while WX_RELEASE only the major.minor ones. + WX_RELEASE="$WX_VERSION_MAJOR""$WX_VERSION_MINOR" + if test $WX_RELEASE -lt 26 ; then + + AC_MSG_ERROR([ + Cannot detect the wxWidgets configuration for the selected wxWidgets build + since its version is $WX_VERSION < 2.6.0; please install a newer + version of wxWidgets. + ]) + fi + + dnl The wx-config we are using understands the "--selected_config" + dnl option which returns an easy-parseable string ! + WX_SELECTEDCONFIG=$($WX_CONFIG_WITH_ARGS --selected_config) + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] Using wx-config --selected-config" + echo "[[dbg]] WX_SELECTEDCONFIG: $WX_SELECTEDCONFIG" + fi + + + dnl we could test directly for WX_SHARED with a line like: + dnl _WX_SELECTEDCONFIG_CHECKFOR([SHARED], [shared], + dnl [if wxWidgets was built in SHARED mode]) + dnl but wx-config --selected-config DOES NOT outputs the 'shared' + dnl word when wx was built in shared mode; it rather outputs the + dnl 'static' word when built in static mode. + if test $WX_SHARED = "1"; then + STATIC=0 + elif test $WX_SHARED = "0"; then + STATIC=1 + elif test $WX_SHARED = "auto"; then + STATIC="auto" + fi + + dnl Now set the WX_UNICODE, WX_DEBUG, WX_STATIC variables + _WX_SELECTEDCONFIG_CHECKFOR([UNICODE], [unicode], + [if wxWidgets was built with UNICODE enabled]) + _WX_SELECTEDCONFIG_CHECKFOR([DEBUG], [debug], + [if wxWidgets was built in DEBUG mode]) + _WX_SELECTEDCONFIG_CHECKFOR([STATIC], [static], + [if wxWidgets was built in STATIC mode]) + + dnl init WX_SHARED from WX_STATIC + if test "$WX_STATIC" != "0"; then + WX_SHARED=0 + else + WX_SHARED=1 + fi + + AC_SUBST(WX_UNICODE) + AC_SUBST(WX_DEBUG) + AC_SUBST(WX_SHARED) + + dnl detect the WX_PORT to use + if test "$TOOLKIT" = "auto" ; then + + dnl The user does not have particular preferences for this option; + dnl so we will detect the wxWidgets relative build setting and use it + AC_MSG_CHECKING([which wxWidgets toolkit was selected]) + + WX_GTKPORT1=$(expr "$WX_SELECTEDCONFIG" : ".*gtk1.*") + WX_GTKPORT2=$(expr "$WX_SELECTEDCONFIG" : ".*gtk2.*") + WX_MSWPORT=$(expr "$WX_SELECTEDCONFIG" : ".*msw.*") + WX_MOTIFPORT=$(expr "$WX_SELECTEDCONFIG" : ".*motif.*") + WX_OSXCOCOAPORT=$(expr "$WX_SELECTEDCONFIG" : ".*osx_cocoa.*") + WX_OSXCARBONPORT=$(expr "$WX_SELECTEDCONFIG" : ".*osx_carbon.*") + WX_X11PORT=$(expr "$WX_SELECTEDCONFIG" : ".*x11.*") + WX_DFBPORT=$(expr "$WX_SELECTEDCONFIG" : ".*dfb.*") + + WX_PORT="unknown" + if test "$WX_GTKPORT1" != "0"; then WX_PORT="gtk1"; fi + if test "$WX_GTKPORT2" != "0"; then WX_PORT="gtk2"; fi + if test "$WX_MSWPORT" != "0"; then WX_PORT="msw"; fi + if test "$WX_MOTIFPORT" != "0"; then WX_PORT="motif"; fi + if test "$WX_OSXCOCOAPORT" != "0"; then WX_PORT="osx_cocoa"; fi + if test "$WX_OSXCARBONPORT" != "0"; then WX_PORT="osx_carbon"; fi + if test "$WX_X11PORT" != "0"; then WX_PORT="x11"; fi + if test "$WX_DFBPORT" != "0"; then WX_PORT="dfb"; fi + + dnl NOTE: backward-compatible check for wx2.8; in wx2.9 the mac + dnl ports are called 'osx_cocoa' and 'osx_carbon' (see above) + WX_MACPORT=$(expr "$WX_SELECTEDCONFIG" : ".*mac.*") + if test "$WX_MACPORT" != "0"; then WX_PORT="mac"; fi + + dnl check at least one of the WX_*PORT has been set ! + + if test "$WX_PORT" = "unknown" ; then + AC_MSG_ERROR([ + Cannot detect the currently installed wxWidgets port ! + Please check your 'wx-config --cxxflags'... + ]) + fi + + AC_MSG_RESULT([$WX_PORT]) + else + + dnl Use the setting given by the user + if test -z "$TOOLKIT" ; then + WX_PORT=$TOOLKIT + else + dnl try with PORT + WX_PORT=$PORT + fi + fi + + AC_SUBST(WX_PORT) + + if test "$WX_DEBUG_CONFIGURE" = "1"; then + echo "[[dbg]] Values of all WX_* options after final detection:" + echo "[[dbg]] WX_DEBUG: $WX_DEBUG" + echo "[[dbg]] WX_UNICODE: $WX_UNICODE" + echo "[[dbg]] WX_SHARED: $WX_SHARED" + echo "[[dbg]] WX_RELEASE: $WX_RELEASE" + echo "[[dbg]] WX_PORT: $WX_PORT" + fi + + dnl Avoid problem described in the WX_STANDARD_OPTIONS which happens when + dnl the user gives the options: + dnl ./configure --enable-shared --without-wxshared + dnl or just do + dnl ./configure --enable-shared + dnl but there is only a static build of wxWidgets available. + if test "$WX_SHARED" = "0" -a "$SHARED" = "1"; then + AC_MSG_ERROR([ + Cannot build shared library against a static build of wxWidgets ! + This error happens because the wxWidgets build which was selected + has been detected as static while you asked to build $PACKAGE_NAME + as shared library and this is not possible. + Use the '--disable-shared' option to build $PACKAGE_NAME + as static library or '--with-wxshared' to use wxWidgets as shared library. + ]) + fi + + dnl now we can finally update the DEBUG,UNICODE,SHARED options + dnl to their final values if they were set to 'auto' + if test "$DEBUG" = "auto"; then + DEBUG=$WX_DEBUG + fi + if test "$UNICODE" = "auto"; then + UNICODE=$WX_UNICODE + fi + if test "$SHARED" = "auto"; then + SHARED=$WX_SHARED + fi + if test "$TOOLKIT" = "auto"; then + TOOLKIT=$WX_PORT + fi + + dnl in case the user needs a BUILD=debug/release var... + if test "$DEBUG" = "1"; then + BUILD="debug" + elif test "$DEBUG" = "0" -o "$DEBUG" = ""; then + BUILD="release" + fi + + dnl respect the DEBUG variable adding the optimize/debug flags + dnl NOTE: the CXXFLAGS are merged together with the CPPFLAGS so we + dnl don't need to set them, too + if test "$DEBUG" = "1"; then + CXXFLAGS="$CXXFLAGS -g -O0" + CFLAGS="$CFLAGS -g -O0" + else + CXXFLAGS="$CXXFLAGS -O2" + CFLAGS="$CFLAGS -O2" + fi + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_BOOLOPT_SUMMARY([name of the boolean variable to show summary for], +dnl [what to print when var is 1], +dnl [what to print when var is 0]) +dnl +dnl Prints $2 when variable $1 == 1 and prints $3 when variable $1 == 0. +dnl This macro mainly exists just to make configure.ac scripts more readable. +dnl +dnl NOTE: you need to use the [" my message"] syntax for 2nd and 3rd arguments +dnl if you want that m4 avoid to throw away the spaces prefixed to the +dnl argument value. +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_BOOLOPT_SUMMARY], + [ + if test "x$$1" = "x1" ; then + echo $2 + elif test "x$$1" = "x0" ; then + echo $3 + else + echo "$1 is $$1" + fi + ]) + +dnl --------------------------------------------------------------------------- +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG +dnl +dnl Shows a summary message to the user about the WX_* variable contents. +dnl This macro is used typically at the end of the configure script. +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_STANDARD_OPTIONS_SUMMARY_MSG], + [ + echo + echo " The wxWidgets build which will be used by $PACKAGE_NAME $PACKAGE_VERSION" + echo " has the following settings:" + WX_BOOLOPT_SUMMARY([WX_DEBUG], [" - DEBUG build"], [" - RELEASE build"]) + WX_BOOLOPT_SUMMARY([WX_UNICODE], [" - UNICODE mode"], [" - ANSI mode"]) + WX_BOOLOPT_SUMMARY([WX_SHARED], [" - SHARED mode"], [" - STATIC mode"]) + echo " - VERSION: $WX_VERSION" + echo " - PORT: $WX_PORT" + ]) + + +dnl --------------------------------------------------------------------------- +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN, WX_STANDARD_OPTIONS_SUMMARY_MSG_END +dnl +dnl Like WX_STANDARD_OPTIONS_SUMMARY_MSG macro but these two macros also gives info +dnl about the configuration of the package which used the wxpresets. +dnl +dnl Typical usage: +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN +dnl echo " - Package setting 1: $SETTING1" +dnl echo " - Package setting 2: $SETTING1" +dnl ... +dnl WX_STANDARD_OPTIONS_SUMMARY_MSG_END +dnl +dnl --------------------------------------------------------------------------- +AC_DEFUN([WX_STANDARD_OPTIONS_SUMMARY_MSG_BEGIN], + [ + echo + echo " ----------------------------------------------------------------" + echo " Configuration for $PACKAGE_NAME $PACKAGE_VERSION successfully completed." + echo " Summary of main configuration settings for $PACKAGE_NAME:" + WX_BOOLOPT_SUMMARY([DEBUG], [" - DEBUG build"], [" - RELEASE build"]) + WX_BOOLOPT_SUMMARY([UNICODE], [" - UNICODE mode"], [" - ANSI mode"]) + WX_BOOLOPT_SUMMARY([SHARED], [" - SHARED mode"], [" - STATIC mode"]) + ]) + +AC_DEFUN([WX_STANDARD_OPTIONS_SUMMARY_MSG_END], + [ + WX_STANDARD_OPTIONS_SUMMARY_MSG + echo + echo " Now, just run make." + echo " ----------------------------------------------------------------" + echo + ]) + + +dnl --------------------------------------------------------------------------- +dnl Deprecated macro wrappers +dnl --------------------------------------------------------------------------- + +AC_DEFUN([AM_OPTIONS_WXCONFIG], [WX_CONFIG_OPTIONS]) +AC_DEFUN([AM_PATH_WXCONFIG], [ + WX_CONFIG_CHECK([$1],[$2],[$3],[$4],[$5]) +]) +AC_DEFUN([AM_PATH_WXRC], [WXRC_CHECK([$1],[$2])]) + # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation diff --git a/configure b/configure index 3fa2a2d..7f12c5e 100755 --- a/configure +++ b/configure @@ -2,7 +2,7 @@ # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for PCem v12. # -# Report bugs to >. +# Report bugs to >. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -266,10 +266,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and Sarah Walker -$0: about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." +$0: about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." fi exit 1 fi @@ -581,16 +581,37 @@ PACKAGE_NAME='PCem' PACKAGE_TARNAME='pcem' PACKAGE_VERSION='v12' PACKAGE_STRING='PCem v12' -PACKAGE_BUGREPORT='Sarah Walker ' +PACKAGE_BUGREPORT='Sarah Walker ' PACKAGE_URL='' ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +WX_VERSION_MICRO +WX_VERSION_MINOR +WX_VERSION_MAJOR +WX_RESCOMP +WX_VERSION +WX_LIBS_STATIC +WX_LIBS +WX_CXXFLAGS_ONLY +WX_CFLAGS_ONLY +WX_CXXFLAGS +WX_CFLAGS +WX_CPPFLAGS +WX_CONFIG_PATH +SDL2_CONFIG +SDL_LIBS +SDL_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG allegro_LIBS allegro_CFLAGS ALLEGRO_CONFIG +USE_WX_FALSE +USE_WX_TRUE OS_LINUX_FALSE OS_LINUX_TRUE OS_WIN_FALSE @@ -702,9 +723,17 @@ enable_option_checking enable_silent_rules enable_dependency_tracking enable_debug +enable_wx with_allegro_prefix with_allegro_exec_prefix enable_allegrotest +with_sdl_prefix +with_sdl_exec_prefix +enable_sdltest +with_wxdir +with_wx_config +with_wx_prefix +with_wx_exec_prefix ' ac_precious_vars='build_alias host_alias @@ -716,7 +745,12 @@ LIBS CPPFLAGS CXX CXXFLAGS -CCC' +CCC +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +SDL_CFLAGS +SDL_LIBS' # Initialize some variables set by options. @@ -1353,13 +1387,22 @@ Optional Features: --disable-dependency-tracking speeds up one-time build --enable-debug build debug executable + --enable-wx use wxWidgets GUI --disable-allegrotest Do not try to compile and run a test LIBallegro program + --disable-sdltest Do not try to compile and run a test SDL program Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-allegro-prefix=PFX Prefix where liballegro is installed (optional) --with-allegro-exec-prefix=PFX Exec prefix where liballegro is installed (optional) + --with-sdl-prefix=PFX Prefix where SDL is installed (optional) + --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) + --with-wxdir=PATH Use uninstalled version of wxWidgets in PATH + --with-wx-config=CONFIG wx-config script to use (optional) + --with-wx-prefix=PREFIX Prefix where wxWidgets is installed (optional) + --with-wx-exec-prefix=PREFIX + Exec prefix where wxWidgets is installed (optional) Some influential environment variables: CC C compiler command @@ -1371,11 +1414,18 @@ Some influential environment variables: you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + SDL_CFLAGS C compiler flags for SDL, overriding pkg-config + SDL_LIBS linker flags for SDL, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to >. +Report bugs to >. _ACEOF ac_status=$? fi @@ -4093,6 +4143,21 @@ else $as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use the wxWidgets-based GUI" >&5 +$as_echo_n "checking whether to use the wxWidgets-based GUI... " >&6; } +# Check whether --enable-wx was given. +if test "${enable_wx+set}" = set; then : + enableval=$enable_wx; +fi + +if test "$enable_wx" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu" >&5 $as_echo_n "checking for cpu... " >&6; } case "${host_cpu}" in @@ -4148,12 +4213,22 @@ else fi -# Do not run test for Allegro with Win32/MinGW version, as binary builds have -# `allegro-config' missing. -# NOTE: For the following Autoconf macro to be supported, you need to extract -# allegro.m4 from the DOS/Windows Allegro sources (the file is contained -# in `misc') and copy it to this directory or MSYS's `/share/aclocal'. -if test "$OS" != "win"; then + if test "$enable_wx" = "yes"; then + USE_WX_TRUE= + USE_WX_FALSE='#' +else + USE_WX_TRUE='#' + USE_WX_FALSE= +fi + + +if test "$enable_wx" != "yes"; then + # Do not run test for Allegro with Win32/MinGW version, as binary builds have + # `allegro-config' missing. + # NOTE: For the following Autoconf macro to be supported, you need to extract + # allegro.m4 from the DOS/Windows Allegro sources (the file is contained + # in `misc') and copy it to this directory or MSYS's `/share/aclocal'. + if test "$OS" != "win"; then @@ -4418,6 +4493,779 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conf.allegrotest + fi +else + SDL_VERSION=2.0.0 + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +# Check whether --with-sdl-prefix was given. +if test "${with_sdl_prefix+set}" = set; then : + withval=$with_sdl_prefix; sdl_prefix="$withval" +else + sdl_prefix="" +fi + + +# Check whether --with-sdl-exec-prefix was given. +if test "${with_sdl_exec_prefix+set}" = set; then : + withval=$with_sdl_exec_prefix; sdl_exec_prefix="$withval" +else + sdl_exec_prefix="" +fi + +# Check whether --enable-sdltest was given. +if test "${enable_sdltest+set}" = set; then : + enableval=$enable_sdltest; +else + enable_sdltest=yes +fi + + + min_sdl_version=$SDL_VERSION + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 +$as_echo_n "checking for SDL... " >&6; } + +if test -n "$SDL_CFLAGS"; then + pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sdl2 >= $min_sdl_version") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2 >= $min_sdl_version" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$SDL_LIBS"; then + pkg_cv_SDL_LIBS="$SDL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sdl2 >= $min_sdl_version") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2 >= $min_sdl_version" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sdl2 >= $min_sdl_version" 2>&1` + else + SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sdl2 >= $min_sdl_version" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$SDL_PKG_ERRORS" >&5 + + sdl_pc=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + sdl_pc=no +else + SDL_CFLAGS=$pkg_cv_SDL_CFLAGS + SDL_LIBS=$pkg_cv_SDL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + sdl_pc=yes +fi + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL2_CONFIG="pkg-config sdl2" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + # Extract the first word of "sdl2-config", so it can be a program name with args. +set dummy sdl2-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SDL2_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SDL2_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_SDL2_CONFIG="$SDL2_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SDL2_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SDL2_CONFIG" && ac_cv_path_SDL2_CONFIG="no" + ;; +esac +fi +SDL2_CONFIG=$ac_cv_path_SDL2_CONFIG +if test -n "$SDL2_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDL2_CONFIG" >&5 +$as_echo "$SDL2_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + PATH="$as_save_PATH" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 +$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } + no_sdl="" + + if test "$SDL2_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + rm -f conf.sdltest + if test "$cross_compiling" = yes; then : + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); + printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + no_sdl=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + if test "x$no_sdl" = x ; then + : + else + if test "$SDL2_CONFIG" = "no" ; then + echo "*** The sdl2-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" + echo "*** full path to sdl2-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main + +int +main () +{ + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" +else + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + as_fn_error $? "*** SDL version $SDL_VERSION not found!" "$LINENO" 5 + + fi + + + rm -f conf.sdltest + + + +# Check whether --with-wxdir was given. +if test "${with_wxdir+set}" = set; then : + withval=$with_wxdir; wx_config_name="$withval/wx-config" + wx_config_args="--inplace" +fi + + +# Check whether --with-wx-config was given. +if test "${with_wx_config+set}" = set; then : + withval=$with_wx_config; wx_config_name="$withval" +fi + + +# Check whether --with-wx-prefix was given. +if test "${with_wx_prefix+set}" = set; then : + withval=$with_wx_prefix; wx_config_prefix="$withval" +else + wx_config_prefix="" +fi + + +# Check whether --with-wx-exec-prefix was given. +if test "${with_wx_exec_prefix+set}" = set; then : + withval=$with_wx_exec_prefix; wx_config_exec_prefix="$withval" +else + wx_config_exec_prefix="" +fi + + + reqwx=3.0.0 + + + if test x${WX_CONFIG_NAME+set} != xset ; then + WX_CONFIG_NAME=wx-config + fi + + if test "x$wx_config_name" != x ; then + WX_CONFIG_NAME="$wx_config_name" + fi + + if test x$wx_config_exec_prefix != x ; then + wx_config_args="$wx_config_args --exec-prefix=$wx_config_exec_prefix" + WX_LOOKUP_PATH="$wx_config_exec_prefix/bin" + fi + if test x$wx_config_prefix != x ; then + wx_config_args="$wx_config_args --prefix=$wx_config_prefix" + WX_LOOKUP_PATH="$WX_LOOKUP_PATH:$wx_config_prefix/bin" + fi + if test "$cross_compiling" = "yes"; then + wx_config_args="$wx_config_args --host=$host_alias" + fi + + if test -x "$WX_CONFIG_NAME" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wx-config" >&5 +$as_echo_n "checking for wx-config... " >&6; } + WX_CONFIG_PATH="$WX_CONFIG_NAME" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +$as_echo "$WX_CONFIG_PATH" >&6; } + else + # Extract the first word of "$WX_CONFIG_NAME", so it can be a program name with args. +set dummy $WX_CONFIG_NAME; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_WX_CONFIG_PATH+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $WX_CONFIG_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_WX_CONFIG_PATH="$WX_CONFIG_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy=""$WX_LOOKUP_PATH:$PATH"" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_WX_CONFIG_PATH="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_WX_CONFIG_PATH" && ac_cv_path_WX_CONFIG_PATH="no" + ;; +esac +fi +WX_CONFIG_PATH=$ac_cv_path_WX_CONFIG_PATH +if test -n "$WX_CONFIG_PATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +$as_echo "$WX_CONFIG_PATH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + + if test "$WX_CONFIG_PATH" != "no" ; then + WX_VERSION="" + + min_wx_version=$reqwx + if test -z "" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version" >&5 +$as_echo_n "checking for wxWidgets version >= $min_wx_version... " >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version ()" >&5 +$as_echo_n "checking for wxWidgets version >= $min_wx_version ()... " >&6; } + fi + + WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args " + + WX_VERSION=`$WX_CONFIG_WITH_ARGS --version 2>/dev/null` + wx_config_major_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + wx_config_minor_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + wx_config_micro_version=`echo $WX_VERSION | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + + wx_requested_major_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + wx_requested_minor_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + wx_requested_micro_version=`echo $min_wx_version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + + + wx_ver_ok="" + if test "x$WX_VERSION" != x ; then + if test $wx_config_major_version -gt $wx_requested_major_version; then + wx_ver_ok=yes + else + if test $wx_config_major_version -eq $wx_requested_major_version; then + if test $wx_config_minor_version -gt $wx_requested_minor_version; then + wx_ver_ok=yes + else + if test $wx_config_minor_version -eq $wx_requested_minor_version; then + if test $wx_config_micro_version -ge $wx_requested_micro_version; then + wx_ver_ok=yes + fi + fi + fi + fi + fi + fi + + + if test -n "$wx_ver_ok"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $WX_VERSION)" >&5 +$as_echo "yes (version $WX_VERSION)" >&6; } + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs ` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets static library" >&5 +$as_echo_n "checking for wxWidgets static library... " >&6; } + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs 2>/dev/null` + if test "x$WX_LIBS_STATIC" = "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + + wx_has_cppflags="" + if test $wx_config_major_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -gt 2; then + wx_has_cppflags=yes + else + if test $wx_config_minor_version -eq 2; then + if test $wx_config_micro_version -ge 6; then + wx_has_cppflags=yes + fi + fi + fi + fi + fi + + wx_has_rescomp="" + if test $wx_config_major_version -gt 2; then + wx_has_rescomp=yes + else + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -ge 7; then + wx_has_rescomp=yes + fi + fi + fi + if test "x$wx_has_rescomp" = x ; then + WX_RESCOMP= + else + WX_RESCOMP=`$WX_CONFIG_WITH_ARGS --rescomp` + fi + + if test "x$wx_has_cppflags" = x ; then + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags ` + WX_CPPFLAGS=$WX_CFLAGS + WX_CXXFLAGS=$WX_CFLAGS + + WX_CFLAGS_ONLY=$WX_CFLAGS + WX_CXXFLAGS_ONLY=$WX_CFLAGS + else + WX_CPPFLAGS=`$WX_CONFIG_WITH_ARGS --cppflags ` + WX_CXXFLAGS=`$WX_CONFIG_WITH_ARGS --cxxflags ` + WX_CFLAGS=`$WX_CONFIG_WITH_ARGS --cflags ` + + WX_CFLAGS_ONLY=`echo $WX_CFLAGS | sed "s@^$WX_CPPFLAGS *@@"` + WX_CXXFLAGS_ONLY=`echo $WX_CXXFLAGS | sed "s@^$WX_CFLAGS *@@"` + fi + + wxWin=1 + + else + + if test "x$WX_VERSION" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (version $WX_VERSION is not new enough)" >&5 +$as_echo "no (version $WX_VERSION is not new enough)" >&6; } + fi + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + if test ! -z ""; then + + wx_error_message=" + The configuration you asked for $PACKAGE_NAME requires a wxWidgets + build with the following settings: + + but such build is not available. + + To see the wxWidgets builds available on this system, please use + 'wx-config --list' command. To use the default build, returned by + 'wx-config --selected-config', use the options with their 'auto' + default values." + + fi + + wx_error_message=" + The requested wxWidgets build couldn't be found. + $wx_error_message + + If you still get this error, then check that 'wx-config' is + in path, the directory where wxWidgets libraries are installed + (returned by 'wx-config --libs' command) is in LD_LIBRARY_PATH + or equivalent variable and wxWidgets version is $reqwx or above." + + as_fn_error $? "$wx_error_message" "$LINENO" 5 + + fi + else + + WX_CFLAGS="" + WX_CPPFLAGS="" + WX_CXXFLAGS="" + WX_LIBS="" + WX_LIBS_STATIC="" + WX_RESCOMP="" + + : + + fi + + + + + + + + + + + + WX_VERSION_MAJOR="$wx_config_major_version" + WX_VERSION_MINOR="$wx_config_minor_version" + WX_VERSION_MICRO="$wx_config_micro_version" + + + + + + if test "$wxWin" != 1; then + as_fn_error $? " + wxWidgets must be installed on your system. + + Please check that wx-config is in path, the directory + where wxWidgets libraries are installed (returned by + 'wx-config --libs' or 'wx-config --static --libs' command) + is in LD_LIBRARY_PATH or equivalent variable and + wxWidgets version is $reqwx or above. + " "$LINENO" 5 + fi + LIBS="$LIBS $WX_LIBS $SDL_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 @@ -4756,6 +5604,10 @@ if test -z "${OS_LINUX_TRUE}" && test -z "${OS_LINUX_FALSE}"; then as_fn_error $? "conditional \"OS_LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_WX_TRUE}" && test -z "${USE_WX_FALSE}"; then + as_fn_error $? "conditional \"USE_WX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -5204,7 +6056,7 @@ $config_files Configuration commands: $config_commands -Report bugs to >." +Report bugs to >." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 diff --git a/configure.ac b/configure.ac index 2e38eca..2d95478 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # AC_PREREQ([2.61]) -AC_INIT(PCem, v12, Sarah Walker , pcem) +AC_INIT(PCem, v12, Sarah Walker , pcem) AC_CANONICAL_HOST @@ -24,6 +24,15 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([whether to use the wxWidgets-based GUI]) +AC_ARG_ENABLE(wx, + AC_HELP_STRING([--enable-wx], [use wxWidgets GUI])) +if test "$enable_wx" = "yes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + AC_MSG_CHECKING([for cpu]) case "${host_cpu}" in i?86) @@ -48,14 +57,39 @@ AM_CONDITIONAL(CPU_X86_64, test "$CPU" = "x86_64") AM_CONDITIONAL(OS_WIN, test "$OS" = "win") AM_CONDITIONAL(OS_LINUX, test "$OS" = "linux") -# Do not run test for Allegro with Win32/MinGW version, as binary builds have -# `allegro-config' missing. -# NOTE: For the following Autoconf macro to be supported, you need to extract -# allegro.m4 from the DOS/Windows Allegro sources (the file is contained -# in `misc') and copy it to this directory or MSYS's `/share/aclocal'. -if test "$OS" != "win"; then - AC_CONFIG_MACRO_DIR([./]) - AM_PATH_ALLEGRO(, , AC_MSG_ERROR(building PCem requires Allegro to be installed)) +AM_CONDITIONAL(USE_WX, test "$enable_wx" = "yes") + +if test "$enable_wx" != "yes"; then + # Do not run test for Allegro with Win32/MinGW version, as binary builds have + # `allegro-config' missing. + # NOTE: For the following Autoconf macro to be supported, you need to extract + # allegro.m4 from the DOS/Windows Allegro sources (the file is contained + # in `misc') and copy it to this directory or MSYS's `/share/aclocal'. + if test "$OS" != "win"; then + AC_CONFIG_MACRO_DIR([./]) + AM_PATH_ALLEGRO(, , AC_MSG_ERROR(building PCem requires Allegro to be installed)) + fi +else + SDL_VERSION=2.0.0 + AM_PATH_SDL2($SDL_VERSION, + :, + AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) + ) + AM_OPTIONS_WXCONFIG + reqwx=3.0.0 + AM_PATH_WXCONFIG($reqwx, wxWin=1) + if test "$wxWin" != 1; then + AC_MSG_ERROR([ + wxWidgets must be installed on your system. + + Please check that wx-config is in path, the directory + where wxWidgets libraries are installed (returned by + 'wx-config --libs' or 'wx-config --static --libs' command) + is in LD_LIBRARY_PATH or equivalent variable and + wxWidgets version is $reqwx or above. + ]) + fi + LIBS="$LIBS $WX_LIBS $SDL_LIBS" fi AC_CHECK_LIB([openal], [alGetError], [], \ diff --git a/src/Makefile.am b/src/Makefile.am index 7c2a47e..363576e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,13 +10,7 @@ CLEANFILES = $(noinst_SCRIPTS) amrefresh: -pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO - -pcem_LDADD = $(allegro_LIBS) -lopenal - -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \ -allegro-gui-config-sel.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-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 dells200.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 \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ @@ -25,7 +19,7 @@ lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_s opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.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 \ +sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \ @@ -40,6 +34,23 @@ 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 USE_WX +pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +pcem_LDADD = @LIBS@ +pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ + wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-sdl2-hdconf.c wx-status.cc wx-sdl2-status.c \ + wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c +else +pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO +pcem_LDADD = $(allegro_LIBS) -lopenal +pcem_SOURCES += allegro-gui.c allegro-gui-config-sel.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 \ + thread-pthread.c +endif + if CPU_I386 pcem_SOURCES += codegen_x86.c pcem_CFLAGS += -msse2 diff --git a/src/Makefile.in b/src/Makefile.in index cf50055..8db7178 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -92,9 +92,19 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcem$(EXEEXT) -@CPU_I386_TRUE@am__append_1 = codegen_x86.c -@CPU_I386_TRUE@am__append_2 = -msse2 -@CPU_X86_64_TRUE@am__append_3 = codegen_x86-64.c +@USE_WX_TRUE@am__append_1 = wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ +@USE_WX_TRUE@ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ +@USE_WX_TRUE@ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-sdl2-hdconf.c wx-status.cc wx-sdl2-status.c \ +@USE_WX_TRUE@ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c + +@USE_WX_FALSE@am__append_2 = allegro-gui.c allegro-gui-config-sel.c allegro-gui-configure.c \ +@USE_WX_FALSE@ allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c \ +@USE_WX_FALSE@ allegro-keyboard.c allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ +@USE_WX_FALSE@ thread-pthread.c + +@CPU_I386_TRUE@am__append_3 = codegen_x86.c +@CPU_I386_TRUE@am__append_4 = -msse2 +@CPU_X86_64_TRUE@am__append_5 = codegen_x86-64.c subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/allegro.m4 \ @@ -108,20 +118,17 @@ 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-config-sel.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-image.cc 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 \ - dells200.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 hdd.c \ - hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 \ + acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c \ + cdrom-image.cc 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 dells200.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 hdd.c hdd_esdi.c headland.c i430lx.c \ + i430fx.c i430vx.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 mca.c mcr.c mem.c mfm_at.c \ mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c \ nmi.c nvr.c olivetti_m24.c opti495.c pc.c pci.c pic.c piix.c \ @@ -131,14 +138,14 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 vid_ati68860_ramdac.c vid_cga.c \ - vid_cl5429.c vid_colorplus.c vid_ega.c vid_et4000.c \ - vid_et4000w32.c vid_genius.c vid_hercules.c vid_icd2061.c \ - vid_ics2595.c vid_incolor.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_ps1_svga.c vid_s3.c vid_s3_virge.c \ + soundopenal.c tandy_eeprom.c tandy_rom.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ + vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ + vid_incolor.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_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 \ @@ -151,25 +158,55 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ 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) + resid-fp/wave8580__ST.cc resid-fp/wave.cc wx-main.cc \ + wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ + wx-sdl2-video.c wx-sdl2-midi.c wx-sdl2.c wx-config.c \ + wx-deviceconfig.cc wx-sdl2-hdconf.c wx-status.cc \ + wx-sdl2-status.c wx-resources.cpp wx-thread.c wx-common.c \ + wx-sdl2-display.c allegro-gui.c allegro-gui-config-sel.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 \ + thread-pthread.c codegen_x86.c codegen_x86-64.c +@USE_WX_TRUE@am__objects_1 = pcem-wx-main.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-config_sel.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-dialogbox.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-utils.$(OBJEXT) pcem-wx-app.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-joystick.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-mouse.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-keyboard.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-video.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-midi.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2.$(OBJEXT) pcem-wx-config.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-deviceconfig.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-hdconf.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-status.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-status.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-resources.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-thread.$(OBJEXT) pcem-wx-common.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) +@USE_WX_FALSE@am__objects_2 = pcem-allegro-gui.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-gui-config-sel.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-gui-configure.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-gui-deviceconfig.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-gui-hdconf.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-joystick.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-keyboard.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-main.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-midi.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-mouse.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-allegro-video.$(OBJEXT) \ +@USE_WX_FALSE@ pcem-thread-pthread.$(OBJEXT) +@CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) +@CPU_X86_64_TRUE@am__objects_4 = 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-config-sel.$(OBJEXT) \ - pcem-allegro-gui-configure.$(OBJEXT) \ - pcem-allegro-gui-deviceconfig.$(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) cdrom-image.$(OBJEXT) \ - pcem-cdrom-null.$(OBJEXT) pcem-codegen.$(OBJEXT) \ - pcem-codegen_ops.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ + pcem-amstrad.$(OBJEXT) pcem-cdrom-ioctl-linux.$(OBJEXT) \ + pcem-cdrom-image.$(OBJEXT) pcem-cdrom-null.$(OBJEXT) \ + pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ + pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ pcem-codegen_timing_winchip.$(OBJEXT) pcem-compaq.$(OBJEXT) \ @@ -213,43 +250,47 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-sound_speaker.$(OBJEXT) pcem-sound_ssi2001.$(OBJEXT) \ pcem-sound_wss.$(OBJEXT) pcem-sound_ym7128.$(OBJEXT) \ pcem-soundopenal.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ - pcem-tandy_rom.$(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_colorplus.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ - pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ - pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ - pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ - pcem-vid_incolor.$(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_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ - pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) sound_dbopl.$(OBJEXT) \ - sound_resid.$(OBJEXT) cdrom_image.$(OBJEXT) dbopl.$(OBJEXT) \ - pcem-vid_cga_comp.$(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-tandy_rom.$(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_colorplus.$(OBJEXT) \ + pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ + pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ + pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ + pcem-vid_ics2595.$(OBJEXT) pcem-vid_incolor.$(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_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) \ + pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ + pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ + pcem-cdrom_image.$(OBJEXT) pcem-dbopl.$(OBJEXT) \ + pcem-vid_cga_comp.$(OBJEXT) pcem-convolve.$(OBJEXT) \ + pcem-convolve-sse.$(OBJEXT) pcem-envelope.$(OBJEXT) \ + pcem-extfilt.$(OBJEXT) pcem-filter.$(OBJEXT) \ + pcem-pot.$(OBJEXT) pcem-sid.$(OBJEXT) pcem-voice.$(OBJEXT) \ + pcem-wave6581_PS_.$(OBJEXT) pcem-wave6581_PST.$(OBJEXT) \ + pcem-wave6581_P_T.$(OBJEXT) pcem-wave6581__ST.$(OBJEXT) \ + pcem-wave8580_PS_.$(OBJEXT) pcem-wave8580_PST.$(OBJEXT) \ + pcem-wave8580_P_T.$(OBJEXT) pcem-wave8580__ST.$(OBJEXT) \ + pcem-wave.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = -pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) +@USE_WX_FALSE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) +pcem_LINK = $(CXXLD) $(pcem_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ SCRIPTS = $(noinst_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -366,10 +407,29 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +SDL2_CONFIG = @SDL2_CONFIG@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_LIBS = @SDL_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +WX_CFLAGS = @WX_CFLAGS@ +WX_CFLAGS_ONLY = @WX_CFLAGS_ONLY@ +WX_CONFIG_PATH = @WX_CONFIG_PATH@ +WX_CPPFLAGS = @WX_CPPFLAGS@ +WX_CXXFLAGS = @WX_CXXFLAGS@ +WX_CXXFLAGS_ONLY = @WX_CXXFLAGS_ONLY@ +WX_LIBS = @WX_LIBS@ +WX_LIBS_STATIC = @WX_LIBS_STATIC@ +WX_RESCOMP = @WX_RESCOMP@ +WX_VERSION = @WX_VERSION@ +WX_VERSION_MAJOR = @WX_VERSION_MAJOR@ +WX_VERSION_MICRO = @WX_VERSION_MICRO@ +WX_VERSION_MINOR = @WX_VERSION_MINOR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -426,23 +486,18 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = ../pcem CLEANFILES = $(noinst_SCRIPTS) -pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO $(am__append_2) -pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ - acer386sx.c ali1429.c allegro-gui.c allegro-gui-config-sel.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-image.cc 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 \ - dells200.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 hdd.c \ - hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 \ + acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c \ + cdrom-image.cc 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 dells200.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 hdd.c hdd_esdi.c headland.c i430lx.c \ + i430fx.c i430vx.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 mca.c mcr.c mem.c mfm_at.c \ mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c \ nmi.c nvr.c olivetti_m24.c opti495.c pc.c pci.c pic.c piix.c \ @@ -452,14 +507,14 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 vid_ati68860_ramdac.c vid_cga.c \ - vid_cl5429.c vid_colorplus.c vid_ega.c vid_et4000.c \ - vid_et4000w32.c vid_genius.c vid_hercules.c vid_icd2061.c \ - vid_ics2595.c vid_incolor.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_ps1_svga.c vid_s3.c vid_s3_virge.c \ + soundopenal.c tandy_eeprom.c tandy_rom.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ + vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ + vid_incolor.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_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 \ @@ -473,7 +528,14 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ 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_3) + $(am__append_2) $(am__append_3) $(am__append_5) +@USE_WX_FALSE@pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO \ +@USE_WX_FALSE@ $(am__append_4) +@USE_WX_TRUE@pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell \ +@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_4) +@USE_WX_TRUE@pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +@USE_WX_FALSE@pcem_LDADD = $(allegro_LIBS) -lopenal +@USE_WX_TRUE@pcem_LDADD = @LIBS@ all: all-am .SUFFIXES: @@ -552,7 +614,7 @@ clean-binPROGRAMS: pcem$(EXEEXT): $(pcem_OBJECTS) $(pcem_DEPENDENCIES) $(EXTRA_pcem_DEPENDENCIES) @rm -f pcem$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(pcem_OBJECTS) $(pcem_LDADD) $(LIBS) + $(AM_V_CXXLD)$(pcem_LINK) $(pcem_OBJECTS) $(pcem_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -560,14 +622,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom-image.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_image.Po@am__quote@ -@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@ @@ -586,8 +640,10 @@ distclean-compile: @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-image.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-cdrom_image.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@ @@ -598,8 +654,11 @@ distclean-compile: @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-convolve-sse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-convolve.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-dbopl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.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@ @@ -607,10 +666,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_img.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_sector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-envelope.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-extfilt.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-fdd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdi2raw.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ @@ -653,6 +715,7 @@ distclean-compile: @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-pot.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-ps2.Po@am__quote@ @@ -662,12 +725,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sid.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_dbopl.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@ @@ -675,6 +740,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pas16.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ps1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.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@ @@ -731,24 +797,40 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_wy700.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-voice.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-hdconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.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@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -848,160 +930,6 @@ pcem-ali1429.obj: ali1429.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-config-sel.o: allegro-gui-config-sel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-config-sel.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo -c -o pcem-allegro-gui-config-sel.o `test -f 'allegro-gui-config-sel.c' || echo '$(srcdir)/'`allegro-gui-config-sel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo $(DEPDIR)/pcem-allegro-gui-config-sel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-config-sel.c' object='pcem-allegro-gui-config-sel.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-config-sel.o `test -f 'allegro-gui-config-sel.c' || echo '$(srcdir)/'`allegro-gui-config-sel.c - -pcem-allegro-gui-config-sel.obj: allegro-gui-config-sel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-config-sel.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo -c -o pcem-allegro-gui-config-sel.obj `if test -f 'allegro-gui-config-sel.c'; then $(CYGPATH_W) 'allegro-gui-config-sel.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-config-sel.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo $(DEPDIR)/pcem-allegro-gui-config-sel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-config-sel.c' object='pcem-allegro-gui-config-sel.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-config-sel.obj `if test -f 'allegro-gui-config-sel.c'; then $(CYGPATH_W) 'allegro-gui-config-sel.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-config-sel.c'; fi` - -pcem-allegro-gui-configure.o: allegro-gui-configure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-deviceconfig.o: allegro-gui-deviceconfig.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-deviceconfig.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo -c -o pcem-allegro-gui-deviceconfig.o `test -f 'allegro-gui-deviceconfig.c' || echo '$(srcdir)/'`allegro-gui-deviceconfig.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo $(DEPDIR)/pcem-allegro-gui-deviceconfig.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-deviceconfig.c' object='pcem-allegro-gui-deviceconfig.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-deviceconfig.o `test -f 'allegro-gui-deviceconfig.c' || echo '$(srcdir)/'`allegro-gui-deviceconfig.c - -pcem-allegro-gui-deviceconfig.obj: allegro-gui-deviceconfig.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-deviceconfig.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo -c -o pcem-allegro-gui-deviceconfig.obj `if test -f 'allegro-gui-deviceconfig.c'; then $(CYGPATH_W) 'allegro-gui-deviceconfig.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-deviceconfig.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo $(DEPDIR)/pcem-allegro-gui-deviceconfig.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-deviceconfig.c' object='pcem-allegro-gui-deviceconfig.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-deviceconfig.obj `if test -f 'allegro-gui-deviceconfig.c'; then $(CYGPATH_W) 'allegro-gui-deviceconfig.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-deviceconfig.c'; fi` - -pcem-allegro-gui-hdconf.o: allegro-gui-hdconf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-amstrad.Tpo $(DEPDIR)/pcem-amstrad.Po @@ -2374,20 +2302,6 @@ pcem-tandy_rom.obj: tandy_rom.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-tandy_rom.obj `if test -f 'tandy_rom.c'; then $(CYGPATH_W) 'tandy_rom.c'; else $(CYGPATH_W) '$(srcdir)/tandy_rom.c'; fi` -pcem-thread-pthread.o: thread-pthread.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-timer.Tpo $(DEPDIR)/pcem-timer.Po @@ -3074,6 +2988,356 @@ pcem-vid_cga_comp.obj: dosbox/vid_cga_comp.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cga_comp.obj `if test -f 'dosbox/vid_cga_comp.c'; then $(CYGPATH_W) 'dosbox/vid_cga_comp.c'; else $(CYGPATH_W) '$(srcdir)/dosbox/vid_cga_comp.c'; fi` +pcem-wx-config_sel.o: wx-config_sel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-config_sel.o -MD -MP -MF $(DEPDIR)/pcem-wx-config_sel.Tpo -c -o pcem-wx-config_sel.o `test -f 'wx-config_sel.c' || echo '$(srcdir)/'`wx-config_sel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-config_sel.Tpo $(DEPDIR)/pcem-wx-config_sel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-config_sel.c' object='pcem-wx-config_sel.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-config_sel.o `test -f 'wx-config_sel.c' || echo '$(srcdir)/'`wx-config_sel.c + +pcem-wx-config_sel.obj: wx-config_sel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-config_sel.obj -MD -MP -MF $(DEPDIR)/pcem-wx-config_sel.Tpo -c -o pcem-wx-config_sel.obj `if test -f 'wx-config_sel.c'; then $(CYGPATH_W) 'wx-config_sel.c'; else $(CYGPATH_W) '$(srcdir)/wx-config_sel.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-config_sel.Tpo $(DEPDIR)/pcem-wx-config_sel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-config_sel.c' object='pcem-wx-config_sel.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-config_sel.obj `if test -f 'wx-config_sel.c'; then $(CYGPATH_W) 'wx-config_sel.c'; else $(CYGPATH_W) '$(srcdir)/wx-config_sel.c'; fi` + +pcem-wx-sdl2-joystick.o: wx-sdl2-joystick.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-joystick.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-joystick.Tpo -c -o pcem-wx-sdl2-joystick.o `test -f 'wx-sdl2-joystick.c' || echo '$(srcdir)/'`wx-sdl2-joystick.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-joystick.Tpo $(DEPDIR)/pcem-wx-sdl2-joystick.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-joystick.c' object='pcem-wx-sdl2-joystick.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-joystick.o `test -f 'wx-sdl2-joystick.c' || echo '$(srcdir)/'`wx-sdl2-joystick.c + +pcem-wx-sdl2-joystick.obj: wx-sdl2-joystick.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-joystick.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-joystick.Tpo -c -o pcem-wx-sdl2-joystick.obj `if test -f 'wx-sdl2-joystick.c'; then $(CYGPATH_W) 'wx-sdl2-joystick.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-joystick.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-joystick.Tpo $(DEPDIR)/pcem-wx-sdl2-joystick.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-joystick.c' object='pcem-wx-sdl2-joystick.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-joystick.obj `if test -f 'wx-sdl2-joystick.c'; then $(CYGPATH_W) 'wx-sdl2-joystick.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-joystick.c'; fi` + +pcem-wx-sdl2-mouse.o: wx-sdl2-mouse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-mouse.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-mouse.Tpo -c -o pcem-wx-sdl2-mouse.o `test -f 'wx-sdl2-mouse.c' || echo '$(srcdir)/'`wx-sdl2-mouse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-mouse.Tpo $(DEPDIR)/pcem-wx-sdl2-mouse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-mouse.c' object='pcem-wx-sdl2-mouse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-mouse.o `test -f 'wx-sdl2-mouse.c' || echo '$(srcdir)/'`wx-sdl2-mouse.c + +pcem-wx-sdl2-mouse.obj: wx-sdl2-mouse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-mouse.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-mouse.Tpo -c -o pcem-wx-sdl2-mouse.obj `if test -f 'wx-sdl2-mouse.c'; then $(CYGPATH_W) 'wx-sdl2-mouse.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-mouse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-mouse.Tpo $(DEPDIR)/pcem-wx-sdl2-mouse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-mouse.c' object='pcem-wx-sdl2-mouse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-mouse.obj `if test -f 'wx-sdl2-mouse.c'; then $(CYGPATH_W) 'wx-sdl2-mouse.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-mouse.c'; fi` + +pcem-wx-sdl2-keyboard.o: wx-sdl2-keyboard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-keyboard.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-keyboard.Tpo -c -o pcem-wx-sdl2-keyboard.o `test -f 'wx-sdl2-keyboard.c' || echo '$(srcdir)/'`wx-sdl2-keyboard.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-keyboard.Tpo $(DEPDIR)/pcem-wx-sdl2-keyboard.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-keyboard.c' object='pcem-wx-sdl2-keyboard.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-keyboard.o `test -f 'wx-sdl2-keyboard.c' || echo '$(srcdir)/'`wx-sdl2-keyboard.c + +pcem-wx-sdl2-keyboard.obj: wx-sdl2-keyboard.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-keyboard.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-keyboard.Tpo -c -o pcem-wx-sdl2-keyboard.obj `if test -f 'wx-sdl2-keyboard.c'; then $(CYGPATH_W) 'wx-sdl2-keyboard.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-keyboard.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-keyboard.Tpo $(DEPDIR)/pcem-wx-sdl2-keyboard.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-keyboard.c' object='pcem-wx-sdl2-keyboard.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-keyboard.obj `if test -f 'wx-sdl2-keyboard.c'; then $(CYGPATH_W) 'wx-sdl2-keyboard.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-keyboard.c'; fi` + +pcem-wx-sdl2-video.o: wx-sdl2-video.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video.Tpo -c -o pcem-wx-sdl2-video.o `test -f 'wx-sdl2-video.c' || echo '$(srcdir)/'`wx-sdl2-video.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video.Tpo $(DEPDIR)/pcem-wx-sdl2-video.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-video.c' object='pcem-wx-sdl2-video.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video.o `test -f 'wx-sdl2-video.c' || echo '$(srcdir)/'`wx-sdl2-video.c + +pcem-wx-sdl2-video.obj: wx-sdl2-video.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video.Tpo -c -o pcem-wx-sdl2-video.obj `if test -f 'wx-sdl2-video.c'; then $(CYGPATH_W) 'wx-sdl2-video.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video.Tpo $(DEPDIR)/pcem-wx-sdl2-video.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-video.c' object='pcem-wx-sdl2-video.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video.obj `if test -f 'wx-sdl2-video.c'; then $(CYGPATH_W) 'wx-sdl2-video.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video.c'; fi` + +pcem-wx-sdl2-midi.o: wx-sdl2-midi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-midi.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-midi.Tpo -c -o pcem-wx-sdl2-midi.o `test -f 'wx-sdl2-midi.c' || echo '$(srcdir)/'`wx-sdl2-midi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-midi.Tpo $(DEPDIR)/pcem-wx-sdl2-midi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-midi.c' object='pcem-wx-sdl2-midi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.o `test -f 'wx-sdl2-midi.c' || echo '$(srcdir)/'`wx-sdl2-midi.c + +pcem-wx-sdl2-midi.obj: wx-sdl2-midi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-midi.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-midi.Tpo -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-midi.Tpo $(DEPDIR)/pcem-wx-sdl2-midi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-midi.c' object='pcem-wx-sdl2-midi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` + +pcem-wx-sdl2.o: wx-sdl2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2.Tpo -c -o pcem-wx-sdl2.o `test -f 'wx-sdl2.c' || echo '$(srcdir)/'`wx-sdl2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2.Tpo $(DEPDIR)/pcem-wx-sdl2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2.c' object='pcem-wx-sdl2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2.o `test -f 'wx-sdl2.c' || echo '$(srcdir)/'`wx-sdl2.c + +pcem-wx-sdl2.obj: wx-sdl2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2.Tpo -c -o pcem-wx-sdl2.obj `if test -f 'wx-sdl2.c'; then $(CYGPATH_W) 'wx-sdl2.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2.Tpo $(DEPDIR)/pcem-wx-sdl2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2.c' object='pcem-wx-sdl2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2.obj `if test -f 'wx-sdl2.c'; then $(CYGPATH_W) 'wx-sdl2.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2.c'; fi` + +pcem-wx-config.o: wx-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-config.o -MD -MP -MF $(DEPDIR)/pcem-wx-config.Tpo -c -o pcem-wx-config.o `test -f 'wx-config.c' || echo '$(srcdir)/'`wx-config.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-config.Tpo $(DEPDIR)/pcem-wx-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-config.c' object='pcem-wx-config.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-config.o `test -f 'wx-config.c' || echo '$(srcdir)/'`wx-config.c + +pcem-wx-config.obj: wx-config.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-config.obj -MD -MP -MF $(DEPDIR)/pcem-wx-config.Tpo -c -o pcem-wx-config.obj `if test -f 'wx-config.c'; then $(CYGPATH_W) 'wx-config.c'; else $(CYGPATH_W) '$(srcdir)/wx-config.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-config.Tpo $(DEPDIR)/pcem-wx-config.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-config.c' object='pcem-wx-config.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-config.obj `if test -f 'wx-config.c'; then $(CYGPATH_W) 'wx-config.c'; else $(CYGPATH_W) '$(srcdir)/wx-config.c'; fi` + +pcem-wx-sdl2-hdconf.o: wx-sdl2-hdconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-hdconf.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo -c -o pcem-wx-sdl2-hdconf.o `test -f 'wx-sdl2-hdconf.c' || echo '$(srcdir)/'`wx-sdl2-hdconf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo $(DEPDIR)/pcem-wx-sdl2-hdconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-hdconf.c' object='pcem-wx-sdl2-hdconf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-hdconf.o `test -f 'wx-sdl2-hdconf.c' || echo '$(srcdir)/'`wx-sdl2-hdconf.c + +pcem-wx-sdl2-hdconf.obj: wx-sdl2-hdconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-hdconf.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo -c -o pcem-wx-sdl2-hdconf.obj `if test -f 'wx-sdl2-hdconf.c'; then $(CYGPATH_W) 'wx-sdl2-hdconf.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-hdconf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo $(DEPDIR)/pcem-wx-sdl2-hdconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-hdconf.c' object='pcem-wx-sdl2-hdconf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-hdconf.obj `if test -f 'wx-sdl2-hdconf.c'; then $(CYGPATH_W) 'wx-sdl2-hdconf.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-hdconf.c'; fi` + +pcem-wx-sdl2-status.o: wx-sdl2-status.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-status.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-status.Tpo -c -o pcem-wx-sdl2-status.o `test -f 'wx-sdl2-status.c' || echo '$(srcdir)/'`wx-sdl2-status.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-status.Tpo $(DEPDIR)/pcem-wx-sdl2-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-status.c' object='pcem-wx-sdl2-status.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-status.o `test -f 'wx-sdl2-status.c' || echo '$(srcdir)/'`wx-sdl2-status.c + +pcem-wx-sdl2-status.obj: wx-sdl2-status.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-status.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-status.Tpo -c -o pcem-wx-sdl2-status.obj `if test -f 'wx-sdl2-status.c'; then $(CYGPATH_W) 'wx-sdl2-status.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-status.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-status.Tpo $(DEPDIR)/pcem-wx-sdl2-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-status.c' object='pcem-wx-sdl2-status.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-status.obj `if test -f 'wx-sdl2-status.c'; then $(CYGPATH_W) 'wx-sdl2-status.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-status.c'; fi` + +pcem-wx-thread.o: wx-thread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-thread.o -MD -MP -MF $(DEPDIR)/pcem-wx-thread.Tpo -c -o pcem-wx-thread.o `test -f 'wx-thread.c' || echo '$(srcdir)/'`wx-thread.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-thread.Tpo $(DEPDIR)/pcem-wx-thread.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-thread.c' object='pcem-wx-thread.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-thread.o `test -f 'wx-thread.c' || echo '$(srcdir)/'`wx-thread.c + +pcem-wx-thread.obj: wx-thread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-thread.obj -MD -MP -MF $(DEPDIR)/pcem-wx-thread.Tpo -c -o pcem-wx-thread.obj `if test -f 'wx-thread.c'; then $(CYGPATH_W) 'wx-thread.c'; else $(CYGPATH_W) '$(srcdir)/wx-thread.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-thread.Tpo $(DEPDIR)/pcem-wx-thread.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-thread.c' object='pcem-wx-thread.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-thread.obj `if test -f 'wx-thread.c'; then $(CYGPATH_W) 'wx-thread.c'; else $(CYGPATH_W) '$(srcdir)/wx-thread.c'; fi` + +pcem-wx-common.o: wx-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-common.o -MD -MP -MF $(DEPDIR)/pcem-wx-common.Tpo -c -o pcem-wx-common.o `test -f 'wx-common.c' || echo '$(srcdir)/'`wx-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-common.Tpo $(DEPDIR)/pcem-wx-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-common.c' object='pcem-wx-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-common.o `test -f 'wx-common.c' || echo '$(srcdir)/'`wx-common.c + +pcem-wx-common.obj: wx-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-common.obj -MD -MP -MF $(DEPDIR)/pcem-wx-common.Tpo -c -o pcem-wx-common.obj `if test -f 'wx-common.c'; then $(CYGPATH_W) 'wx-common.c'; else $(CYGPATH_W) '$(srcdir)/wx-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-common.Tpo $(DEPDIR)/pcem-wx-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-common.c' object='pcem-wx-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-common.obj `if test -f 'wx-common.c'; then $(CYGPATH_W) 'wx-common.c'; else $(CYGPATH_W) '$(srcdir)/wx-common.c'; fi` + +pcem-wx-sdl2-display.o: wx-sdl2-display.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display.Tpo -c -o pcem-wx-sdl2-display.o `test -f 'wx-sdl2-display.c' || echo '$(srcdir)/'`wx-sdl2-display.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display.Tpo $(DEPDIR)/pcem-wx-sdl2-display.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display.c' object='pcem-wx-sdl2-display.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.o `test -f 'wx-sdl2-display.c' || echo '$(srcdir)/'`wx-sdl2-display.c + +pcem-wx-sdl2-display.obj: wx-sdl2-display.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display.Tpo -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display.Tpo $(DEPDIR)/pcem-wx-sdl2-display.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display.c' object='pcem-wx-sdl2-display.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` + +pcem-allegro-gui.o: allegro-gui.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-config-sel.o: allegro-gui-config-sel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-config-sel.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo -c -o pcem-allegro-gui-config-sel.o `test -f 'allegro-gui-config-sel.c' || echo '$(srcdir)/'`allegro-gui-config-sel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo $(DEPDIR)/pcem-allegro-gui-config-sel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-config-sel.c' object='pcem-allegro-gui-config-sel.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-config-sel.o `test -f 'allegro-gui-config-sel.c' || echo '$(srcdir)/'`allegro-gui-config-sel.c + +pcem-allegro-gui-config-sel.obj: allegro-gui-config-sel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-config-sel.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo -c -o pcem-allegro-gui-config-sel.obj `if test -f 'allegro-gui-config-sel.c'; then $(CYGPATH_W) 'allegro-gui-config-sel.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-config-sel.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo $(DEPDIR)/pcem-allegro-gui-config-sel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-config-sel.c' object='pcem-allegro-gui-config-sel.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-config-sel.obj `if test -f 'allegro-gui-config-sel.c'; then $(CYGPATH_W) 'allegro-gui-config-sel.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-config-sel.c'; fi` + +pcem-allegro-gui-configure.o: allegro-gui-configure.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-deviceconfig.o: allegro-gui-deviceconfig.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-deviceconfig.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo -c -o pcem-allegro-gui-deviceconfig.o `test -f 'allegro-gui-deviceconfig.c' || echo '$(srcdir)/'`allegro-gui-deviceconfig.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo $(DEPDIR)/pcem-allegro-gui-deviceconfig.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-deviceconfig.c' object='pcem-allegro-gui-deviceconfig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-deviceconfig.o `test -f 'allegro-gui-deviceconfig.c' || echo '$(srcdir)/'`allegro-gui-deviceconfig.c + +pcem-allegro-gui-deviceconfig.obj: allegro-gui-deviceconfig.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-deviceconfig.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo -c -o pcem-allegro-gui-deviceconfig.obj `if test -f 'allegro-gui-deviceconfig.c'; then $(CYGPATH_W) 'allegro-gui-deviceconfig.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-deviceconfig.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo $(DEPDIR)/pcem-allegro-gui-deviceconfig.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-deviceconfig.c' object='pcem-allegro-gui-deviceconfig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-deviceconfig.obj `if test -f 'allegro-gui-deviceconfig.c'; then $(CYGPATH_W) 'allegro-gui-deviceconfig.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-deviceconfig.c'; fi` + +pcem-allegro-gui-hdconf.o: allegro-gui-hdconf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-thread-pthread.o: thread-pthread.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-codegen_x86.o: codegen_x86.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_x86.Tpo $(DEPDIR)/pcem-codegen_x86.Po @@ -3116,271 +3380,411 @@ pcem-codegen_x86-64.obj: codegen_x86-64.c @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -cdrom_image.o: dosbox/cdrom_image.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdrom_image.o -MD -MP -MF $(DEPDIR)/cdrom_image.Tpo -c -o cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdrom_image.Tpo $(DEPDIR)/cdrom_image.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='cdrom_image.o' libtool=no @AMDEPBACKSLASH@ +pcem-cdrom-image.o: cdrom-image.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-cdrom-image.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-image.Tpo -c -o pcem-cdrom-image.o `test -f 'cdrom-image.cc' || echo '$(srcdir)/'`cdrom-image.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-image.Tpo $(DEPDIR)/pcem-cdrom-image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdrom-image.cc' object='pcem-cdrom-image.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-cdrom-image.o `test -f 'cdrom-image.cc' || echo '$(srcdir)/'`cdrom-image.cc -cdrom_image.obj: dosbox/cdrom_image.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdrom_image.obj -MD -MP -MF $(DEPDIR)/cdrom_image.Tpo -c -o cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cdrom_image.Tpo $(DEPDIR)/cdrom_image.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='cdrom_image.obj' libtool=no @AMDEPBACKSLASH@ +pcem-cdrom-image.obj: cdrom-image.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-cdrom-image.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-image.Tpo -c -o pcem-cdrom-image.obj `if test -f 'cdrom-image.cc'; then $(CYGPATH_W) 'cdrom-image.cc'; else $(CYGPATH_W) '$(srcdir)/cdrom-image.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-image.Tpo $(DEPDIR)/pcem-cdrom-image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cdrom-image.cc' object='pcem-cdrom-image.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-cdrom-image.obj `if test -f 'cdrom-image.cc'; then $(CYGPATH_W) 'cdrom-image.cc'; else $(CYGPATH_W) '$(srcdir)/cdrom-image.cc'; fi` -dbopl.o: dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/dbopl.Tpo $(DEPDIR)/dbopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='dbopl.o' libtool=no @AMDEPBACKSLASH@ +pcem-sound_dbopl.o: sound_dbopl.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sound_dbopl.o -MD -MP -MF $(DEPDIR)/pcem-sound_dbopl.Tpo -c -o pcem-sound_dbopl.o `test -f 'sound_dbopl.cc' || echo '$(srcdir)/'`sound_dbopl.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_dbopl.Tpo $(DEPDIR)/pcem-sound_dbopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sound_dbopl.cc' object='pcem-sound_dbopl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sound_dbopl.o `test -f 'sound_dbopl.cc' || echo '$(srcdir)/'`sound_dbopl.cc -dbopl.obj: dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/dbopl.Tpo $(DEPDIR)/dbopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='dbopl.obj' libtool=no @AMDEPBACKSLASH@ +pcem-sound_dbopl.obj: sound_dbopl.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sound_dbopl.obj -MD -MP -MF $(DEPDIR)/pcem-sound_dbopl.Tpo -c -o pcem-sound_dbopl.obj `if test -f 'sound_dbopl.cc'; then $(CYGPATH_W) 'sound_dbopl.cc'; else $(CYGPATH_W) '$(srcdir)/sound_dbopl.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_dbopl.Tpo $(DEPDIR)/pcem-sound_dbopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sound_dbopl.cc' object='pcem-sound_dbopl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sound_dbopl.obj `if test -f 'sound_dbopl.cc'; then $(CYGPATH_W) 'sound_dbopl.cc'; else $(CYGPATH_W) '$(srcdir)/sound_dbopl.cc'; fi` -convolve.o: resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/convolve.Tpo $(DEPDIR)/convolve.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='convolve.o' libtool=no @AMDEPBACKSLASH@ +pcem-sound_resid.o: sound_resid.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sound_resid.o -MD -MP -MF $(DEPDIR)/pcem-sound_resid.Tpo -c -o pcem-sound_resid.o `test -f 'sound_resid.cc' || echo '$(srcdir)/'`sound_resid.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_resid.Tpo $(DEPDIR)/pcem-sound_resid.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sound_resid.cc' object='pcem-sound_resid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sound_resid.o `test -f 'sound_resid.cc' || echo '$(srcdir)/'`sound_resid.cc -convolve.obj: resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/convolve.Tpo $(DEPDIR)/convolve.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='convolve.obj' libtool=no @AMDEPBACKSLASH@ +pcem-sound_resid.obj: sound_resid.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sound_resid.obj -MD -MP -MF $(DEPDIR)/pcem-sound_resid.Tpo -c -o pcem-sound_resid.obj `if test -f 'sound_resid.cc'; then $(CYGPATH_W) 'sound_resid.cc'; else $(CYGPATH_W) '$(srcdir)/sound_resid.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_resid.Tpo $(DEPDIR)/pcem-sound_resid.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='sound_resid.cc' object='pcem-sound_resid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sound_resid.obj `if test -f 'sound_resid.cc'; then $(CYGPATH_W) 'sound_resid.cc'; else $(CYGPATH_W) '$(srcdir)/sound_resid.cc'; fi` -convolve-sse.o: resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/convolve-sse.Tpo $(DEPDIR)/convolve-sse.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='convolve-sse.o' libtool=no @AMDEPBACKSLASH@ +pcem-cdrom_image.o: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-cdrom_image.o -MD -MP -MF $(DEPDIR)/pcem-cdrom_image.Tpo -c -o pcem-cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom_image.Tpo $(DEPDIR)/pcem-cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='pcem-cdrom_image.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp -convolve-sse.obj: resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/convolve-sse.Tpo $(DEPDIR)/convolve-sse.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='convolve-sse.obj' libtool=no @AMDEPBACKSLASH@ +pcem-cdrom_image.obj: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-cdrom_image.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom_image.Tpo -c -o pcem-cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom_image.Tpo $(DEPDIR)/pcem-cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='pcem-cdrom_image.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` -envelope.o: resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/envelope.Tpo $(DEPDIR)/envelope.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='envelope.o' libtool=no @AMDEPBACKSLASH@ +pcem-dbopl.o: dosbox/dbopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-dbopl.o -MD -MP -MF $(DEPDIR)/pcem-dbopl.Tpo -c -o pcem-dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dbopl.Tpo $(DEPDIR)/pcem-dbopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='pcem-dbopl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp -envelope.obj: resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/envelope.Tpo $(DEPDIR)/envelope.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='envelope.obj' libtool=no @AMDEPBACKSLASH@ +pcem-dbopl.obj: dosbox/dbopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-dbopl.obj -MD -MP -MF $(DEPDIR)/pcem-dbopl.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-dbopl.Tpo $(DEPDIR)/pcem-dbopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='pcem-dbopl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-dbopl.obj `if test -f 'dosbox/dbopl.cpp'; then $(CYGPATH_W) 'dosbox/dbopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/dbopl.cpp'; fi` -extfilt.o: resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/extfilt.Tpo $(DEPDIR)/extfilt.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='extfilt.o' libtool=no @AMDEPBACKSLASH@ +pcem-convolve.o: resid-fp/convolve.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve.o -MD -MP -MF $(DEPDIR)/pcem-convolve.Tpo -c -o pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-convolve.Tpo $(DEPDIR)/pcem-convolve.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='pcem-convolve.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc -extfilt.obj: resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/extfilt.Tpo $(DEPDIR)/extfilt.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='extfilt.obj' libtool=no @AMDEPBACKSLASH@ +pcem-convolve.obj: resid-fp/convolve.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve.obj -MD -MP -MF $(DEPDIR)/pcem-convolve.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-convolve.Tpo $(DEPDIR)/pcem-convolve.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='pcem-convolve.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -filter.o: resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/filter.Tpo $(DEPDIR)/filter.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='filter.o' libtool=no @AMDEPBACKSLASH@ +pcem-convolve-sse.o: resid-fp/convolve-sse.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve-sse.o -MD -MP -MF $(DEPDIR)/pcem-convolve-sse.Tpo -c -o pcem-convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-convolve-sse.Tpo $(DEPDIR)/pcem-convolve-sse.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='pcem-convolve-sse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc -filter.obj: resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/filter.Tpo $(DEPDIR)/filter.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='filter.obj' libtool=no @AMDEPBACKSLASH@ +pcem-convolve-sse.obj: resid-fp/convolve-sse.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve-sse.obj -MD -MP -MF $(DEPDIR)/pcem-convolve-sse.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-convolve-sse.Tpo $(DEPDIR)/pcem-convolve-sse.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='pcem-convolve-sse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -pot.o: resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/pot.Tpo $(DEPDIR)/pot.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='pot.o' libtool=no @AMDEPBACKSLASH@ +pcem-envelope.o: resid-fp/envelope.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-envelope.o -MD -MP -MF $(DEPDIR)/pcem-envelope.Tpo -c -o pcem-envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-envelope.Tpo $(DEPDIR)/pcem-envelope.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='pcem-envelope.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc -pot.obj: resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/pot.Tpo $(DEPDIR)/pot.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='pot.obj' libtool=no @AMDEPBACKSLASH@ +pcem-envelope.obj: resid-fp/envelope.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-envelope.obj -MD -MP -MF $(DEPDIR)/pcem-envelope.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-envelope.Tpo $(DEPDIR)/pcem-envelope.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='pcem-envelope.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -sid.o: resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/sid.Tpo $(DEPDIR)/sid.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='sid.o' libtool=no @AMDEPBACKSLASH@ +pcem-extfilt.o: resid-fp/extfilt.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-extfilt.o -MD -MP -MF $(DEPDIR)/pcem-extfilt.Tpo -c -o pcem-extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-extfilt.Tpo $(DEPDIR)/pcem-extfilt.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='pcem-extfilt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc -sid.obj: resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/sid.Tpo $(DEPDIR)/sid.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='sid.obj' libtool=no @AMDEPBACKSLASH@ +pcem-extfilt.obj: resid-fp/extfilt.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-extfilt.obj -MD -MP -MF $(DEPDIR)/pcem-extfilt.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-extfilt.Tpo $(DEPDIR)/pcem-extfilt.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='pcem-extfilt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -voice.o: resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/voice.Tpo $(DEPDIR)/voice.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='voice.o' libtool=no @AMDEPBACKSLASH@ +pcem-filter.o: resid-fp/filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-filter.o -MD -MP -MF $(DEPDIR)/pcem-filter.Tpo -c -o pcem-filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-filter.Tpo $(DEPDIR)/pcem-filter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='pcem-filter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc -voice.obj: resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/voice.Tpo $(DEPDIR)/voice.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='voice.obj' libtool=no @AMDEPBACKSLASH@ +pcem-filter.obj: resid-fp/filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-filter.obj -MD -MP -MF $(DEPDIR)/pcem-filter.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-filter.Tpo $(DEPDIR)/pcem-filter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='pcem-filter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave6581_PS_.o: resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581_PS_.Tpo $(DEPDIR)/wave6581_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='wave6581_PS_.o' libtool=no @AMDEPBACKSLASH@ +pcem-pot.o: resid-fp/pot.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-pot.o -MD -MP -MF $(DEPDIR)/pcem-pot.Tpo -c -o pcem-pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pot.Tpo $(DEPDIR)/pcem-pot.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='pcem-pot.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc -wave6581_PS_.obj: resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581_PS_.Tpo $(DEPDIR)/wave6581_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='wave6581_PS_.obj' libtool=no @AMDEPBACKSLASH@ +pcem-pot.obj: resid-fp/pot.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-pot.obj -MD -MP -MF $(DEPDIR)/pcem-pot.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-pot.Tpo $(DEPDIR)/pcem-pot.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='pcem-pot.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave6581_PST.o: resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581_PST.Tpo $(DEPDIR)/wave6581_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='wave6581_PST.o' libtool=no @AMDEPBACKSLASH@ +pcem-sid.o: resid-fp/sid.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sid.o -MD -MP -MF $(DEPDIR)/pcem-sid.Tpo -c -o pcem-sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sid.Tpo $(DEPDIR)/pcem-sid.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='pcem-sid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc -wave6581_PST.obj: resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581_PST.Tpo $(DEPDIR)/wave6581_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='wave6581_PST.obj' libtool=no @AMDEPBACKSLASH@ +pcem-sid.obj: resid-fp/sid.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sid.obj -MD -MP -MF $(DEPDIR)/pcem-sid.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-sid.Tpo $(DEPDIR)/pcem-sid.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='pcem-sid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave6581_P_T.o: resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581_P_T.Tpo $(DEPDIR)/wave6581_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='wave6581_P_T.o' libtool=no @AMDEPBACKSLASH@ +pcem-voice.o: resid-fp/voice.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-voice.o -MD -MP -MF $(DEPDIR)/pcem-voice.Tpo -c -o pcem-voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-voice.Tpo $(DEPDIR)/pcem-voice.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='pcem-voice.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc -wave6581_P_T.obj: resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581_P_T.Tpo $(DEPDIR)/wave6581_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='wave6581_P_T.obj' libtool=no @AMDEPBACKSLASH@ +pcem-voice.obj: resid-fp/voice.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-voice.obj -MD -MP -MF $(DEPDIR)/pcem-voice.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-voice.Tpo $(DEPDIR)/pcem-voice.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='pcem-voice.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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__ST.o: resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581__ST.Tpo $(DEPDIR)/wave6581__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='wave6581__ST.o' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581_PS_.o: resid-fp/wave6581_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PS_.o -MD -MP -MF $(DEPDIR)/pcem-wave6581_PS_.Tpo -c -o pcem-wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PS_.Tpo $(DEPDIR)/pcem-wave6581_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='pcem-wave6581_PS_.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc -wave6581__ST.obj: resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave6581__ST.Tpo $(DEPDIR)/wave6581__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='wave6581__ST.obj' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581_PS_.obj: resid-fp/wave6581_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PS_.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581_PS_.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PS_.Tpo $(DEPDIR)/pcem-wave6581_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='pcem-wave6581_PS_.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave8580_PS_.o: resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580_PS_.Tpo $(DEPDIR)/wave8580_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='wave8580_PS_.o' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581_PST.o: resid-fp/wave6581_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PST.o -MD -MP -MF $(DEPDIR)/pcem-wave6581_PST.Tpo -c -o pcem-wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PST.Tpo $(DEPDIR)/pcem-wave6581_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='pcem-wave6581_PST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc -wave8580_PS_.obj: resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580_PS_.Tpo $(DEPDIR)/wave8580_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='wave8580_PS_.obj' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581_PST.obj: resid-fp/wave6581_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PST.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581_PST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PST.Tpo $(DEPDIR)/pcem-wave6581_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='pcem-wave6581_PST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave8580_PST.o: resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580_PST.Tpo $(DEPDIR)/wave8580_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='wave8580_PST.o' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581_P_T.o: resid-fp/wave6581_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_P_T.o -MD -MP -MF $(DEPDIR)/pcem-wave6581_P_T.Tpo -c -o pcem-wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_P_T.Tpo $(DEPDIR)/pcem-wave6581_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='pcem-wave6581_P_T.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc -wave8580_PST.obj: resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580_PST.Tpo $(DEPDIR)/wave8580_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='wave8580_PST.obj' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581_P_T.obj: resid-fp/wave6581_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_P_T.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581_P_T.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_P_T.Tpo $(DEPDIR)/pcem-wave6581_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='pcem-wave6581_P_T.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave8580_P_T.o: resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580_P_T.Tpo $(DEPDIR)/wave8580_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='wave8580_P_T.o' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581__ST.o: resid-fp/wave6581__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581__ST.o -MD -MP -MF $(DEPDIR)/pcem-wave6581__ST.Tpo -c -o pcem-wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581__ST.Tpo $(DEPDIR)/pcem-wave6581__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='pcem-wave6581__ST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc -wave8580_P_T.obj: resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580_P_T.Tpo $(DEPDIR)/wave8580_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='wave8580_P_T.obj' libtool=no @AMDEPBACKSLASH@ +pcem-wave6581__ST.obj: resid-fp/wave6581__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581__ST.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581__ST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581__ST.Tpo $(DEPDIR)/pcem-wave6581__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='pcem-wave6581__ST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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__ST.o: resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580__ST.Tpo $(DEPDIR)/wave8580__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='wave8580__ST.o' libtool=no @AMDEPBACKSLASH@ +pcem-wave8580_PS_.o: resid-fp/wave8580_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PS_.o -MD -MP -MF $(DEPDIR)/pcem-wave8580_PS_.Tpo -c -o pcem-wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PS_.Tpo $(DEPDIR)/pcem-wave8580_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='pcem-wave8580_PS_.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc -wave8580__ST.obj: resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave8580__ST.Tpo $(DEPDIR)/wave8580__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='wave8580__ST.obj' libtool=no @AMDEPBACKSLASH@ +pcem-wave8580_PS_.obj: resid-fp/wave8580_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PS_.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580_PS_.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PS_.Tpo $(DEPDIR)/pcem-wave8580_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='pcem-wave8580_PS_.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` -wave.o: resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave.Tpo $(DEPDIR)/wave.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='wave.o' libtool=no @AMDEPBACKSLASH@ +pcem-wave8580_PST.o: resid-fp/wave8580_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PST.o -MD -MP -MF $(DEPDIR)/pcem-wave8580_PST.Tpo -c -o pcem-wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PST.Tpo $(DEPDIR)/pcem-wave8580_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='pcem-wave8580_PST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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 +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc -wave.obj: resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(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_V_at)$(am__mv) $(DEPDIR)/wave.Tpo $(DEPDIR)/wave.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='wave.obj' libtool=no @AMDEPBACKSLASH@ +pcem-wave8580_PST.obj: resid-fp/wave8580_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PST.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580_PST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PST.Tpo $(DEPDIR)/pcem-wave8580_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='pcem-wave8580_PST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(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` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` + +pcem-wave8580_P_T.o: resid-fp/wave8580_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_P_T.o -MD -MP -MF $(DEPDIR)/pcem-wave8580_P_T.Tpo -c -o pcem-wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_P_T.Tpo $(DEPDIR)/pcem-wave8580_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='pcem-wave8580_P_T.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc + +pcem-wave8580_P_T.obj: resid-fp/wave8580_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_P_T.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580_P_T.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_P_T.Tpo $(DEPDIR)/pcem-wave8580_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='pcem-wave8580_P_T.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` + +pcem-wave8580__ST.o: resid-fp/wave8580__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580__ST.o -MD -MP -MF $(DEPDIR)/pcem-wave8580__ST.Tpo -c -o pcem-wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580__ST.Tpo $(DEPDIR)/pcem-wave8580__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='pcem-wave8580__ST.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc + +pcem-wave8580__ST.obj: resid-fp/wave8580__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580__ST.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580__ST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580__ST.Tpo $(DEPDIR)/pcem-wave8580__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='pcem-wave8580__ST.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` + +pcem-wave.o: resid-fp/wave.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave.o -MD -MP -MF $(DEPDIR)/pcem-wave.Tpo -c -o pcem-wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave.Tpo $(DEPDIR)/pcem-wave.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='pcem-wave.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc + +pcem-wave.obj: resid-fp/wave.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave.obj -MD -MP -MF $(DEPDIR)/pcem-wave.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave.Tpo $(DEPDIR)/pcem-wave.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='pcem-wave.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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` + +pcem-wx-main.o: wx-main.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-main.o -MD -MP -MF $(DEPDIR)/pcem-wx-main.Tpo -c -o pcem-wx-main.o `test -f 'wx-main.cc' || echo '$(srcdir)/'`wx-main.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-main.Tpo $(DEPDIR)/pcem-wx-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-main.cc' object='pcem-wx-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-main.o `test -f 'wx-main.cc' || echo '$(srcdir)/'`wx-main.cc + +pcem-wx-main.obj: wx-main.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-main.obj -MD -MP -MF $(DEPDIR)/pcem-wx-main.Tpo -c -o pcem-wx-main.obj `if test -f 'wx-main.cc'; then $(CYGPATH_W) 'wx-main.cc'; else $(CYGPATH_W) '$(srcdir)/wx-main.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-main.Tpo $(DEPDIR)/pcem-wx-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-main.cc' object='pcem-wx-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-main.obj `if test -f 'wx-main.cc'; then $(CYGPATH_W) 'wx-main.cc'; else $(CYGPATH_W) '$(srcdir)/wx-main.cc'; fi` + +pcem-wx-dialogbox.o: wx-dialogbox.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-dialogbox.o -MD -MP -MF $(DEPDIR)/pcem-wx-dialogbox.Tpo -c -o pcem-wx-dialogbox.o `test -f 'wx-dialogbox.cc' || echo '$(srcdir)/'`wx-dialogbox.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-dialogbox.Tpo $(DEPDIR)/pcem-wx-dialogbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-dialogbox.cc' object='pcem-wx-dialogbox.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-dialogbox.o `test -f 'wx-dialogbox.cc' || echo '$(srcdir)/'`wx-dialogbox.cc + +pcem-wx-dialogbox.obj: wx-dialogbox.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-dialogbox.obj -MD -MP -MF $(DEPDIR)/pcem-wx-dialogbox.Tpo -c -o pcem-wx-dialogbox.obj `if test -f 'wx-dialogbox.cc'; then $(CYGPATH_W) 'wx-dialogbox.cc'; else $(CYGPATH_W) '$(srcdir)/wx-dialogbox.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-dialogbox.Tpo $(DEPDIR)/pcem-wx-dialogbox.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-dialogbox.cc' object='pcem-wx-dialogbox.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-dialogbox.obj `if test -f 'wx-dialogbox.cc'; then $(CYGPATH_W) 'wx-dialogbox.cc'; else $(CYGPATH_W) '$(srcdir)/wx-dialogbox.cc'; fi` + +pcem-wx-utils.o: wx-utils.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-utils.o -MD -MP -MF $(DEPDIR)/pcem-wx-utils.Tpo -c -o pcem-wx-utils.o `test -f 'wx-utils.cc' || echo '$(srcdir)/'`wx-utils.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-utils.Tpo $(DEPDIR)/pcem-wx-utils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-utils.cc' object='pcem-wx-utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-utils.o `test -f 'wx-utils.cc' || echo '$(srcdir)/'`wx-utils.cc + +pcem-wx-utils.obj: wx-utils.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-utils.obj -MD -MP -MF $(DEPDIR)/pcem-wx-utils.Tpo -c -o pcem-wx-utils.obj `if test -f 'wx-utils.cc'; then $(CYGPATH_W) 'wx-utils.cc'; else $(CYGPATH_W) '$(srcdir)/wx-utils.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-utils.Tpo $(DEPDIR)/pcem-wx-utils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-utils.cc' object='pcem-wx-utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-utils.obj `if test -f 'wx-utils.cc'; then $(CYGPATH_W) 'wx-utils.cc'; else $(CYGPATH_W) '$(srcdir)/wx-utils.cc'; fi` + +pcem-wx-app.o: wx-app.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-app.o -MD -MP -MF $(DEPDIR)/pcem-wx-app.Tpo -c -o pcem-wx-app.o `test -f 'wx-app.cc' || echo '$(srcdir)/'`wx-app.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-app.Tpo $(DEPDIR)/pcem-wx-app.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-app.cc' object='pcem-wx-app.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-app.o `test -f 'wx-app.cc' || echo '$(srcdir)/'`wx-app.cc + +pcem-wx-app.obj: wx-app.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-app.obj -MD -MP -MF $(DEPDIR)/pcem-wx-app.Tpo -c -o pcem-wx-app.obj `if test -f 'wx-app.cc'; then $(CYGPATH_W) 'wx-app.cc'; else $(CYGPATH_W) '$(srcdir)/wx-app.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-app.Tpo $(DEPDIR)/pcem-wx-app.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-app.cc' object='pcem-wx-app.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-app.obj `if test -f 'wx-app.cc'; then $(CYGPATH_W) 'wx-app.cc'; else $(CYGPATH_W) '$(srcdir)/wx-app.cc'; fi` + +pcem-wx-deviceconfig.o: wx-deviceconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-deviceconfig.o -MD -MP -MF $(DEPDIR)/pcem-wx-deviceconfig.Tpo -c -o pcem-wx-deviceconfig.o `test -f 'wx-deviceconfig.cc' || echo '$(srcdir)/'`wx-deviceconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-deviceconfig.Tpo $(DEPDIR)/pcem-wx-deviceconfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-deviceconfig.cc' object='pcem-wx-deviceconfig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-deviceconfig.o `test -f 'wx-deviceconfig.cc' || echo '$(srcdir)/'`wx-deviceconfig.cc + +pcem-wx-deviceconfig.obj: wx-deviceconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-deviceconfig.obj -MD -MP -MF $(DEPDIR)/pcem-wx-deviceconfig.Tpo -c -o pcem-wx-deviceconfig.obj `if test -f 'wx-deviceconfig.cc'; then $(CYGPATH_W) 'wx-deviceconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-deviceconfig.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-deviceconfig.Tpo $(DEPDIR)/pcem-wx-deviceconfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-deviceconfig.cc' object='pcem-wx-deviceconfig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-deviceconfig.obj `if test -f 'wx-deviceconfig.cc'; then $(CYGPATH_W) 'wx-deviceconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-deviceconfig.cc'; fi` + +pcem-wx-status.o: wx-status.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-status.o -MD -MP -MF $(DEPDIR)/pcem-wx-status.Tpo -c -o pcem-wx-status.o `test -f 'wx-status.cc' || echo '$(srcdir)/'`wx-status.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-status.Tpo $(DEPDIR)/pcem-wx-status.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-status.cc' object='pcem-wx-status.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-status.o `test -f 'wx-status.cc' || echo '$(srcdir)/'`wx-status.cc + +pcem-wx-status.obj: wx-status.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-status.obj -MD -MP -MF $(DEPDIR)/pcem-wx-status.Tpo -c -o pcem-wx-status.obj `if test -f 'wx-status.cc'; then $(CYGPATH_W) 'wx-status.cc'; else $(CYGPATH_W) '$(srcdir)/wx-status.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-status.Tpo $(DEPDIR)/pcem-wx-status.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-status.cc' object='pcem-wx-status.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-status.obj `if test -f 'wx-status.cc'; then $(CYGPATH_W) 'wx-status.cc'; else $(CYGPATH_W) '$(srcdir)/wx-status.cc'; fi` + +pcem-wx-resources.o: wx-resources.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-resources.o -MD -MP -MF $(DEPDIR)/pcem-wx-resources.Tpo -c -o pcem-wx-resources.o `test -f 'wx-resources.cpp' || echo '$(srcdir)/'`wx-resources.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-resources.Tpo $(DEPDIR)/pcem-wx-resources.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-resources.cpp' object='pcem-wx-resources.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.o `test -f 'wx-resources.cpp' || echo '$(srcdir)/'`wx-resources.cpp + +pcem-wx-resources.obj: wx-resources.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-resources.obj -MD -MP -MF $(DEPDIR)/pcem-wx-resources.Tpo -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-resources.Tpo $(DEPDIR)/pcem-wx-resources.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-resources.cpp' object='pcem-wx-resources.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< From 3724b442fcd86483cdaa3fa5166a4dfd59341419 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 1 Jun 2017 18:28:17 +0100 Subject: [PATCH 0021/1050] Fixed blit thread hang with DirectDraw when blitting a zero line frame. --- src/win-ddraw.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 9cecff8..2cd0864 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -123,7 +123,10 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) // pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); if (h <= 0) + { + video_blit_complete(); return; + } memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); From 6bd87d571896a068ab785aab36aacf46854506c0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 1 Jun 2017 20:37:09 +0100 Subject: [PATCH 0022/1050] PCI changes : - Each machine now specifies what PCI device IDs are used as generic card slots - Implemented IRQ handling - Added SIO chip to allow IRQ routing for Premiere/PCI --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/model.c | 39 +++++++----- src/pci.c | 71 ++++++++++++++++++--- src/pci.h | 16 ++++- src/piix.c | 36 ++++++++++- src/piix.h | 2 +- src/sio.c | 119 +++++++++++++++++++++++++++++++++++ src/sio.h | 1 + src/sis496.c | 33 ++++++++++ 17 files changed, 296 insertions(+), 39 deletions(-) create mode 100644 src/sio.c create mode 100644 src/sio.h diff --git a/src/Makefile.am b/src/Makefile.am index 363576e..dbf3360 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sis496.c sound.c \ +opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 2b47115..8d9ad8a 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -11,7 +11,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index d95f9f9..9d58188 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -9,7 +9,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 1dc72e1..9550405 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -10,7 +10,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 014c895..c0caaaa 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -9,7 +9,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 68e24e5..a344795 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 ali1429.o amstrad i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index bebef57..124fc8c 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -9,7 +9,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o serial.o sio.o sis496.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 um8881f.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 b210a22..49a1949 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 ali1429.o amstrad i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 813ec2a..4ea2833 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -9,7 +9,7 @@ dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sis496.o sound.o \ +opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/model.c b/src/model.c index 43839da..41715d3 100644 --- a/src/model.c +++ b/src/model.c @@ -44,6 +44,7 @@ #include "ps2_mca.h" #include "scat.h" #include "serial.h" +#include "sio.h" #include "sis496.h" #include "sound_ps1.h" #include "sound_pssj.h" @@ -51,7 +52,6 @@ #include "tandy_eeprom.h" #include "tandy_rom.h" #include "um8669f.h" -#include "um8881f.h" #include "vid_pcjr.h" #include "vid_tandy.h" #include "wd76c10.h" @@ -81,7 +81,6 @@ 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(); @@ -134,7 +133,6 @@ MODEL models[] = {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 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}}, 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, -/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, 1, 1, 256, 1, at_um8881f_init},*/ {"Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, @@ -458,19 +456,14 @@ void at_ali1429_init() ali1429_init(); } -void at_um8881f_init() -{ - at_init(); - ide_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - um8881f_init(); -} - void at_sis496_init() { at_init(); ide_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xd); + pci_slot(0xf); device_add(&sis496_device); } @@ -478,8 +471,12 @@ void at_batman_init() { at_init(); ide_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); i430lx_init(); + sio_init(2, 0xc, 0xe, 0x6, 0); fdc37c665_init(); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); @@ -488,9 +485,13 @@ void at_endeavor_init() { at_init(); 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); um8669f_init(); intel_endeavor_init(); device_add(&intel_flash_bxt_ami_device); @@ -500,9 +501,13 @@ void at_i430vx_init() { at_init(); ide_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(); - piix_init(7); + piix_init(7, 18, 17, 20, 19); um8669f_init(); device_add(&intel_flash_bxt_device); } diff --git a/src/pci.c b/src/pci.c index 73b455a..8e9694d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,14 +1,19 @@ #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 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; -static int pci_min_card, pci_max_card; int pci_burst_time, pci_nonburst_time; void pci_cf8_write(uint16_t port, uint32_t val, void *p) @@ -116,8 +121,46 @@ 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; +// pclog("pci_set_irq_routing: pci_int=%i irq=%i\n", pci_int, irq); +} + +void pci_set_card_routing(int card, int pci_int) +{ + pci_irq_routing[card] = pci_int; +// pclog("pci_irq_routing: card=%i pci_int=%i\n", card, pci_int); +} + +void pci_set_irq(int card, int pci_int) +{ +// pclog("pci_set_irq: card=%i irq_routing=%i\n", card, pci_irq_routing[card]); + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; +// pclog(" irq=%i pci_irqs=%i active=%i\n", irq, pci_irqs[irq], pci_irq_active[card]); + 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) +{ +// pclog("pci_clear_irq: card=%i irq_routing=%i\n", card, pci_irq_routing[card]); + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; +// pclog(" irq=%i pci_irqs=%i active=%i\n", irq, pci_irqs[irq], pci_irq_active[card]); + 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; @@ -139,10 +182,18 @@ void pci_init(int type, int min_card, int max_card) 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) @@ -152,18 +203,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 f248c36..142b793 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,6 +1,11 @@ -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 @@ -10,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 e51be18..a62ba82 100644 --- a/src/piix.c +++ b/src/piix.c @@ -87,6 +87,35 @@ void piix_write(int func, int addr, uint8_t val, void *priv) case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0e: return; + + case 0x60: +// pclog("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } card_piix[addr] = val; } @@ -306,7 +335,7 @@ void piix_bus_master_set_irq(int channel) piix_busmaster[channel].status |= 4; } -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); @@ -346,4 +375,9 @@ void piix_init(int card) card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq); + + 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 0e85a27..88a2666 100644 --- a/src/piix.h +++ b/src/piix.h @@ -1 +1 @@ -void piix_init(int card); +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); diff --git a/src/sio.c b/src/sio.c new file mode 100644 index 0000000..4160cc4 --- /dev/null +++ b/src/sio.c @@ -0,0 +1,119 @@ +#include + +#include "ibm.h" +#include "ide.h" +#include "io.h" +#include "mem.h" +#include "pci.h" + +#include "sio.h" + +static uint8_t card_sio[256]; +//static int pci_cards_ids[4]; + +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, cpu_state.pc); + if (func > 0) + return; + + 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 0x04: /*Command register*/ + val &= 0x08; + val |= 0x07; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + + case 0x60: +// pclog("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x62: +// pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x63: +// pclog("IRQ routing %02x %02x\n", addr, val); + 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 card_sio[addr]; +} + +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); + + memset(card_sio, 0, 256); + card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/ + 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] = 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; + + 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 new file mode 100644 index 0000000..6957aff --- /dev/null +++ b/src/sio.h @@ -0,0 +1 @@ +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 de9a246..a5ec77f 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -65,6 +65,35 @@ void sis496_write(int func, int addr, uint8_t val, void *p) sis496_recalcmapping(sis496); } break; + + case 0xc0: + // pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, val & 0xf); + else + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + break; + case 0xc1: +// pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, val & 0xf); + else + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + break; + case 0xc2: +// pclog("IRQ routing %02x %02x\n", addr, val); + 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) @@ -104,6 +133,10 @@ void *sis496_init() sis496->pci_conf[0x0e] = 0x00; /*Single function device*/ + pci_set_card_routing(15, PCI_INTA); + pci_set_card_routing(13, PCI_INTD); + pci_set_card_routing(11, PCI_INTC); + return sis496; } From d38c51c0d6a99085bb16aa199d9ea41a0bf94ba5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 1 Jun 2017 20:43:34 +0100 Subject: [PATCH 0023/1050] Improved PCI configuration registers on i430LX, i430FX, i430VX and PIIX. --- src/i430fx.c | 22 ++++++++++++++++++++-- src/i430lx.c | 20 +++++++++++++++++++- src/i430vx.c | 21 ++++++++++++++++++++- src/piix.c | 5 ++++- 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/i430fx.c b/src/i430fx.c index 5b7cf7f..4db750e 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -34,15 +34,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/i430lx.c b/src/i430lx.c index 1f6a874..ebde9bc 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -36,13 +36,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/i430vx.c b/src/i430vx.c index 5f2cb05..6b1c4bb 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -34,13 +34,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/piix.c b/src/piix.c index a62ba82..1c3bc28 100644 --- a/src/piix.c +++ b/src/piix.c @@ -81,6 +81,9 @@ 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: @@ -343,7 +346,7 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) 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*/ From 617cfd7ef24dbfdd8e01acb69cd1ff79a7f6bf11 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 1 Jun 2017 21:51:02 +0100 Subject: [PATCH 0024/1050] Added preliminary IRQ support for ATI Mach64, S3 Vision864/Trio32/Trio64, and S3 ViRGE. --- src/vid_ati_mach64.c | 53 +++++++++++++++++++++++++++++++++++++------- src/vid_s3.c | 53 +++++++++++++++++++++++++++++++++++++++----- src/vid_s3_virge.c | 41 +++++++++++++++++++++++++++++++++- 3 files changed, 133 insertions(+), 14 deletions(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index e7ff3f0..a608060 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -71,6 +71,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]; @@ -197,6 +199,7 @@ 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]; @@ -552,6 +555,14 @@ void mach64_updatemapping(mach64_t *mach64) } } +static void mach64_update_irqs(mach64_t *mach64) +{ + 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*/ @@ -1671,6 +1682,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; @@ -2230,6 +2242,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: @@ -3146,17 +3159,20 @@ static void mach64_io_set(mach64_t *mach64) io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - for (c = 0; c < 8; c++) + if (!mach64->use_block_decoded_io) { - 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); + 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); } @@ -3203,6 +3219,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; } @@ -3280,6 +3301,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; } } @@ -3308,7 +3344,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; @@ -3356,7 +3392,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; + ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); rom_init(&mach64->bios_rom, "roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); diff --git a/src/vid_s3.c b/src/vid_s3.c index 580c16d..53b3324 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -76,11 +76,14 @@ typedef struct s3_t 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; @@ -131,8 +134,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); @@ -154,6 +165,14 @@ static void s3_wait_fifo_idle(s3_t *s3) } } +static void s3_update_irqs(s3_t *s3) +{ + 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) \ @@ -711,9 +730,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]; @@ -1105,9 +1134,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; @@ -1140,9 +1172,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); @@ -2087,6 +2119,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; } @@ -2099,7 +2134,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 @@ -2130,6 +2165,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; } } @@ -2181,10 +2220,12 @@ static void *s3_init(char *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; s3_io_set(s3); - pci_add(s3_pci_read, s3_pci_write, s3); + s3->card = pci_add(s3_pci_read, s3_pci_write, s3); s3->pci_regs[0x04] = 7; @@ -2197,6 +2238,8 @@ static void *s3_init(char *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/vid_s3_virge.c b/src/vid_s3_virge.c index cb30cee..8df14e0 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -127,6 +127,7 @@ typedef struct virge_t uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; int is_375; @@ -234,6 +235,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) @@ -298,6 +301,21 @@ 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 ((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; @@ -353,6 +371,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: @@ -717,6 +736,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) @@ -851,6 +878,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); // pclog("Read status %04x %i\n", ret, virge->s3d_busy); @@ -1270,6 +1298,8 @@ static void fifo_thread(void *param) virge_time += end_time - start_time; } virge->virge_busy = 0; + virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; + s3_virge_update_irqs(virge); } } @@ -1480,6 +1510,12 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) svga->fullchange = changeframecount; break; + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); + break; + case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: case 0xa020: case 0xa024: case 0xa028: case 0xa02c: @@ -3304,6 +3340,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); } } @@ -3857,6 +3895,7 @@ static void *s3_virge_375_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, "roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -3925,7 +3964,7 @@ static void *s3_virge_375_init() virge->is_375 = 1; - 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(); From 71055ef19c9512e70b5e4266bcd6634d25af10a7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Jun 2017 19:46:00 +0100 Subject: [PATCH 0025/1050] Sound Blaster volume balancing and filter changes. Patch from James-F. --- src/filters.h | 10 +++++----- src/sound_opl.c | 8 ++++---- src/sound_sb.c | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/filters.h b/src/filters.h index 454a12a..ca3b43a 100644 --- a/src/filters.h +++ b/src/filters.h @@ -132,11 +132,11 @@ static inline float high_cut_iir(int i, float NewSample) { #undef NCoef -#define NCoef 1 +#define NCoef 2 //fc=3.2kHz static inline float sb_iir(int i, float NewSample) { -/* float ACoef[NCoef+1] = { + float ACoef[NCoef+1] = { 0.03356837051492005100, 0.06713674102984010200, 0.03356837051492005100 @@ -146,9 +146,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 }; @@ -156,7 +156,7 @@ 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_opl.c b/src/sound_opl.c index 0ec7643..9fece84 100644 --- a/src/sound_opl.c +++ b/src/sound_opl.c @@ -83,8 +83,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); } } } @@ -96,8 +96,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_sb.c b/src/sound_sb.c index d4212ca..6c699bc 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -43,9 +43,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 + 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 }; static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) @@ -61,8 +61,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) * 55000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 55000) >> 16); if (sb->mixer.filter) { @@ -112,8 +112,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) * 55000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 55000) >> 16); if (sb->mixer.filter) { From 3630bc2f17edd1f75ac6109b855716c09bbdd835 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Jun 2017 20:41:43 +0100 Subject: [PATCH 0026/1050] Add undocumented 0xF8 Sound Blaster DSP command. Fixes TEST-SBP.EXE. --- src/sound_sb_dsp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 29dc3f0..1849711 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -501,6 +501,10 @@ void sb_exec_command(sb_dsp_t *dsp) // 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 0xF8: + if (dsp->sb_type < SB16) break; + sb_add_data(dsp, 0); break; case 0xF9: if (dsp->sb_type < SB16) break; From 12e8cb670060f57817d3f962c4efebc74c75b846 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Jun 2017 21:14:27 +0100 Subject: [PATCH 0027/1050] Fixed readback of invalid SB Pro mixer registers. Fixes SBCHECK.EXE. --- src/sound_sb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index 6c699bc..605c605 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -247,7 +247,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) From fa9d9381b7d82a7ea2b2a4989e589087ae8b0641 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Jun 2017 22:01:09 +0100 Subject: [PATCH 0028/1050] Clear flat DS/SS status on segment load during block. Fixes LBA 2. --- src/codegen_ops_x86-64.h | 87 +++++++++++++--------------------------- src/codegen_ops_x86.h | 66 ++++++++++-------------------- src/codegen_x86-64.c | 5 ++- src/codegen_x86.c | 4 ++ src/x86.h | 3 ++ src/x86seg.c | 8 ++++ 6 files changed, 68 insertions(+), 105 deletions(-) diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 561b73a..3742053 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -869,9 +869,7 @@ static inline 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)) + if ((seg == &_ds) && codegen_flat_ds) return; if (IS_32_ADDR(&seg->base)) @@ -907,9 +905,7 @@ static inline 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)) + if ((seg == &_ds) && codegen_flat_ds) return; if (IS_32_ADDR(&seg->base)) @@ -937,9 +933,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline 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)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) return; if (IS_32_ADDR(&seg->base)) @@ -978,8 +972,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) 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 ECX, ECX*/ addbyte(0xc9); @@ -1052,8 +1045,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1142,8 +1134,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1224,8 +1215,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1349,8 +1339,7 @@ static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1434,8 +1423,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1530,8 +1518,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1624,8 +1611,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5318,8 +5304,7 @@ static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5371,8 +5356,7 @@ static inline 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))) + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5404,8 +5388,7 @@ static inline 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))) + 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]*/ @@ -5451,8 +5434,7 @@ static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5500,8 +5482,7 @@ static inline 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))) + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5510,8 +5491,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) 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))) + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) { addbyte(0x74); /*JE slowpath*/ jump4 = &codeblock[block_current].data[block_pos]; @@ -5567,8 +5547,7 @@ static inline 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))) + 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); @@ -5604,8 +5583,7 @@ static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5653,8 +5631,7 @@ static inline 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))) + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5663,8 +5640,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) 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))) + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) { addbyte(0x74); /*JE slowpath*/ jump4 = &codeblock[block_current].data[block_pos]; @@ -5720,8 +5696,7 @@ static inline 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))) + 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); @@ -5752,8 +5727,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5825,8 +5799,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5907,8 +5880,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -6011,8 +5983,7 @@ static inline 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); @@ -6089,8 +6060,7 @@ static inline void MEM_STORE_ADDR_EA_B_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); @@ -6178,8 +6148,7 @@ static inline void MEM_STORE_ADDR_EA_W_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); diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 34ace4d..77d284f 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -618,9 +618,7 @@ static inline 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)) + if (seg == &_ds && codegen_flat_ds) return; addbyte(0x83); /*CMP seg->base, -1*/ @@ -643,9 +641,7 @@ static inline 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)) + if (seg == &_ds && codegen_flat_ds) return; addbyte(0x83); /*CMP seg->base, -1*/ @@ -660,9 +656,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline 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)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) return; addbyte(0x3b); /*CMP EAX, seg->limit_low*/ @@ -690,8 +684,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) 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); @@ -709,8 +702,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -730,8 +722,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -749,8 +740,7 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -771,8 +761,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -792,8 +781,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -812,8 +800,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -834,8 +821,7 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -873,8 +859,7 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -895,8 +880,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -917,8 +901,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -939,8 +922,7 @@ static inline void MEM_STORE_ADDR_EA_W(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 ESI, ESI*/ addbyte(0xf6); @@ -961,8 +943,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -983,8 +964,7 @@ static inline void MEM_STORE_ADDR_EA_L(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 ESI, ESI*/ addbyte(0xf6); @@ -1015,8 +995,7 @@ static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3943,8 +3922,7 @@ static inline void LOAD_EA() static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3962,8 +3940,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3981,8 +3958,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) static inline 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))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index e6e8b78..5a35102 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -23,7 +23,7 @@ #include #endif - +int codegen_flat_ds, codegen_flat_ss; int codegen_flags_changed = 0; int codegen_fpu_entered = 0; int codegen_fpu_loaded_iq[8]; @@ -384,6 +384,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/codegen_x86.c b/src/codegen_x86.c index 07f6857..841ef7e 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -23,6 +23,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; @@ -1478,6 +1479,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/x86.h b/src/x86.h index dc60e05..1c15e1f 100644 --- a/src/x86.h +++ b/src/x86.h @@ -111,3 +111,6 @@ void dumpregs(); void execx86(int cycs); void exec386(int cycs); void exec386_dynarec(int cycs); + +extern int codegen_flat_ds; +extern int codegen_flat_ss; diff --git a/src/x86seg.c b/src/x86seg.c index c729670..364c616 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -434,6 +434,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 { @@ -443,6 +447,10 @@ 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) From ff26a772b25b384ee6ccffdea27930bf1e8c4377 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 3 Jun 2017 07:50:31 +0100 Subject: [PATCH 0029/1050] Corrected test on SB DSP command 0xf8. --- src/sound_sb_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 1849711..5b2a326 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -507,7 +507,7 @@ void sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, 0); break; case 0xF9: - if (dsp->sb_type < SB16) break; + if (dsp->sb_type >= SB16) break; if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff); else if (dsp->sb_data[0] == 0x0f) sb_add_data(dsp, 0x07); else if (dsp->sb_data[0] == 0x37) sb_add_data(dsp, 0x38); From 4faab6f75c53ae67f41186e3bed5bf53d5c2ab5d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 3 Jun 2017 10:03:07 +0100 Subject: [PATCH 0030/1050] Correct fix for SB DSP command 0xf8. --- src/sound_sb_dsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 5b2a326..b0dbe1d 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -503,11 +503,11 @@ void sb_exec_command(sb_dsp_t *dsp) // pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[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: - if (dsp->sb_type >= SB16) break; + if (dsp->sb_type < SB16) break; if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff); else if (dsp->sb_data[0] == 0x0f) sb_add_data(dsp, 0x07); else if (dsp->sb_data[0] == 0x37) sb_add_data(dsp, 0x38); From 3b4392bcf8d697aeced05af9c5317b6c06258954 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Jun 2017 16:41:33 +0100 Subject: [PATCH 0031/1050] Implemented data misalignment penalties on 486 and later CPUs. --- src/386_common.h | 18 ++- src/codegen_ops_x86-64.h | 231 +++++++++++++++++---------------------- src/codegen_x86.c | 216 ++++++++++++++++++------------------ src/cpu.c | 22 ++++ src/cpu.h | 3 + src/ibm.h | 4 +- src/mem.c | 194 ++++++++++++++++++++------------ 7 files changed, 361 insertions(+), 327 deletions(-) diff --git a/src/386_common.h b/src/386_common.h index bbcfaa0..88a92fc 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -5,13 +5,13 @@ 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 int checkio(int port); @@ -88,8 +88,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]); @@ -119,10 +119,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/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 3742053..e0cb874 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -1069,16 +1069,14 @@ static inline 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]*/ @@ -1098,18 +1096,17 @@ static inline 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:*/ @@ -1158,16 +1155,14 @@ static inline 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]*/ @@ -1187,17 +1182,16 @@ static inline 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:*/ @@ -1239,16 +1233,14 @@ static inline 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]*/ @@ -1268,18 +1260,17 @@ static inline 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:*/ @@ -1447,16 +1438,14 @@ static inline 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]*/ @@ -1476,29 +1465,27 @@ static inline 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); @@ -1542,16 +1529,14 @@ static inline 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]*/ @@ -1571,27 +1556,25 @@ static inline 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); @@ -1635,16 +1618,14 @@ static inline 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]*/ @@ -1664,28 +1645,26 @@ static inline 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); @@ -5823,16 +5802,14 @@ static inline 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]*/ @@ -5852,18 +5829,17 @@ static inline 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); /*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); /*slowpath:*/ @@ -5904,16 +5880,14 @@ static inline 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, 1*/ addbyte(0xc7); - addlong(0xffc); + addlong(1); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -5933,17 +5907,16 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(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); /*slowpath:*/ @@ -6084,16 +6057,14 @@ static inline 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]*/ @@ -6113,29 +6084,27 @@ static inline 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); @@ -6172,16 +6141,14 @@ static inline 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]*/ @@ -6201,27 +6168,25 @@ static inline 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/codegen_x86.c b/src/codegen_x86.c index 841ef7e..9739da8 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -137,31 +137,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*/ @@ -194,30 +192,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*/ @@ -247,34 +243,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*/ @@ -353,31 +347,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*/ @@ -409,30 +401,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*/ @@ -464,34 +454,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*/ @@ -515,7 +503,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]; @@ -577,7 +567,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]; @@ -586,31 +578,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*/ @@ -646,7 +636,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]; @@ -655,30 +647,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); /*JE 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*/ @@ -714,7 +704,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]; @@ -772,7 +764,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]; @@ -782,31 +776,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*/ @@ -838,7 +830,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]; @@ -848,30 +842,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.c b/src/cpu.c index 540ba2d..2a6eda6 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -68,6 +68,7 @@ int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; +int cpu_cyrix_alignment; uint64_t cpu_CR4_mask; @@ -90,6 +91,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 { @@ -581,6 +583,9 @@ void cpu_set() } memset(&msr, 0, sizeof(msr)); + + timing_misaligned = 0; + cpu_cyrix_alignment = 0; switch (cpu_s->cpu_type) { @@ -712,6 +717,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_486DLC: @@ -744,6 +750,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_i486SX: @@ -776,6 +783,7 @@ void cpu_set() timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_Am486SX: @@ -809,6 +817,7 @@ void cpu_set() timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_Cx486S: @@ -841,6 +850,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_Cx5x86: @@ -872,6 +882,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: @@ -909,6 +921,8 @@ void cpu_set() timing_jmp_rm = 5; timing_jmp_pm = 7; timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; codegen_timing_set(&codegen_timing_winchip); break; @@ -942,6 +956,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; @@ -981,6 +996,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; @@ -1019,6 +1035,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; @@ -1057,6 +1075,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; @@ -1129,6 +1149,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; diff --git a/src/cpu.h b/src/cpu.h index 4a5a679..18671f3 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -51,6 +51,7 @@ 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 { @@ -97,6 +98,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 e2c5b64..20cabea 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -24,8 +24,8 @@ 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)))) //#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 diff --git a/src/mem.c b/src/mem.c index ecfc949..b387016 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1099,22 +1099,30 @@ 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 (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); printf("NULL segment! rw %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); 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 (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1137,25 +1145,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 (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) { @@ -1163,6 +1152,37 @@ 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 & 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]); @@ -1197,15 +1217,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 (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) { @@ -1213,7 +1224,24 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return -1; } - + + 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); @@ -1236,23 +1264,33 @@ 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); printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); 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]); @@ -1294,15 +1332,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) { @@ -1310,6 +1339,22 @@ uint64_t readmemql(uint32_t seg, uint32_t addr) printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,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) { @@ -1330,23 +1375,32 @@ 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); printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); 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]); From fbd0f0196748129637ee3ba4035c58feb833cb0b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Jun 2017 16:48:19 +0100 Subject: [PATCH 0032/1050] Corrected intensity in Hercules graphics mode. --- src/vid_hercules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_hercules.c b/src/vid_hercules.c index cdfb31d..1a70db6 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -153,7 +153,7 @@ void hercules_poll(void *p) dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; hercules->ma++; for (c = 0; c < 16; c++) - ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = (dat & (32768 >> c)) ? 0xffffff : 0; + ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = (dat & (32768 >> c)) ? 0xaaaaaa : 0; } } else From 7af491d719aad45dc81eb48f9240b737dde0a4f1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Jun 2017 17:39:39 +0100 Subject: [PATCH 0033/1050] Added monochrome green/amber/white monitor selection for CGA, MDA and Hercules. Patch from basic2004. --- src/vid_cga.c | 40 +++++++--- src/vid_hercules.c | 70 ++++++++++++----- src/vid_mda.c | 68 +++++++++++++---- src/video.c | 170 +++++++++++++++++++++++++++++++++++++---- src/video.h | 9 +++ src/win-deviceconfig.c | 2 +- 6 files changed, 300 insertions(+), 59 deletions(-) diff --git a/src/vid_cga.c b/src/vid_cga.c index b930a37..59aa6ef 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -10,9 +10,6 @@ #include "vid_cga.h" #include "dosbox/vid_cga_comp.h" -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 - #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 @@ -442,14 +439,15 @@ void cga_init(cga_t *cga) void *cga_standalone_init() { - int display_type; + int display_type, contrast; cga_t *cga = malloc(sizeof(cga_t)); memset(cga, 0, sizeof(cga_t)); display_type = device_get_config_int("display_type"); - cga->composite = (display_type != CGA_RGB); + cga->composite = (display_type == DISPLAY_COMPOSITE); cga->revision = device_get_config_int("composite_type"); cga->snow_enabled = device_get_config_int("snow_enabled"); + contrast = device_get_config_int("contrast"); cga->vram = malloc(0x4000); @@ -457,7 +455,9 @@ void *cga_standalone_init() timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); - + + cgapal_rebuild(display_type, contrast); + return cga; } @@ -486,17 +486,33 @@ static device_config_t cga_config[] = { { .description = "RGB", - .value = CGA_RGB + .value = DISPLAY_RGB + }, + { + .description = "RGB (no brown)", + .value = DISPLAY_RGB_NO_BROWN + }, + { + .description = "Green Monochrome", + .value = DISPLAY_GREEN + }, + { + .description = "Amber Monochrome", + .value = DISPLAY_AMBER + }, + { + .description = "White Monochrome", + .value = DISPLAY_WHITE }, { .description = "Composite", - .value = CGA_COMPOSITE + .value = DISPLAY_COMPOSITE }, { .description = "" } }, - .default_int = CGA_RGB + .default_int = DISPLAY_RGB }, { .name = "composite_type", @@ -524,6 +540,12 @@ static device_config_t cga_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "contrast", + .description = "Alternate monochrome contrast", + .type = CONFIG_BINARY, + .default_int = 0 + }, { .type = -1 } diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 1a70db6..899de86 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -153,7 +153,7 @@ void hercules_poll(void *p) dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; hercules->ma++; for (c = 0; c < 16; c++) - ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = (dat & (32768 >> c)) ? 0xaaaaaa : 0; + ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = (dat & (32768 >> c)) ? cgapal[0x7] : 0; } } else @@ -307,6 +307,7 @@ void hercules_poll(void *p) void *hercules_init() { + int display_type; int c; hercules_t *hercules = malloc(sizeof(hercules_t)); memset(hercules, 0, sizeof(hercules_t)); @@ -317,24 +318,27 @@ void *hercules_init() 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); + display_type = device_get_config_int("display_type"); + cgapal_rebuild(display_type, 0); + for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = makecol32(0, 0, 0); - if (c & 8) mdacols[c][0][1] = makecol32(0xff, 0xff, 0xff); - else mdacols[c][0][1] = makecol32(0xaa, 0xaa, 0xaa); + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = cgapal[0]; + if (c & 8) mdacols[c][0][1] = cgapal[0xf]; + else mdacols[c][0][1] = cgapal[0x7]; } - mdacols[0x70][0][1] = makecol32(0, 0, 0); - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0xF0][0][1] = makecol32(0, 0, 0); - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0x78][0][1] = makecol32(0xaa, 0xaa, 0xaa); - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0xF8][0][1] = makecol32(0xaa, 0xaa, 0xaa); - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0x00][0][1] = mdacols[0x00][1][1] = makecol32(0, 0, 0); - mdacols[0x08][0][1] = mdacols[0x08][1][1] = makecol32(0, 0, 0); - mdacols[0x80][0][1] = mdacols[0x80][1][1] = makecol32(0, 0, 0); - mdacols[0x88][0][1] = mdacols[0x88][1][1] = makecol32(0, 0, 0); + mdacols[0x70][0][1] = cgapal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = cgapal[0xf]; + mdacols[0xF0][0][1] = cgapal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = cgapal[0xf]; + mdacols[0x78][0][1] = cgapal[0x7]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = cgapal[0xf]; + mdacols[0xF8][0][1] = cgapal[0x7]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = cgapal[0xf]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = cgapal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; return hercules; } @@ -354,6 +358,37 @@ void hercules_speed_changed(void *p) hercules_recalctimings(hercules); } +static device_config_t hercules_config[] = +{ + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Green", + .value = DISPLAY_GREEN + }, + { + .description = "Amber", + .value = DISPLAY_AMBER + }, + { + .description = "White", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + }, + .default_int = DISPLAY_WHITE + }, + { + .type = -1 + } +}; + device_t hercules_device = { "Hercules", @@ -363,5 +398,6 @@ device_t hercules_device = NULL, hercules_speed_changed, NULL, - NULL + NULL, + hercules_config }; diff --git a/src/vid_mda.c b/src/vid_mda.c index 495b794..fdb549e 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -263,6 +263,7 @@ void mda_poll(void *p) void *mda_init() { + int display_type; int c; mda_t *mda = malloc(sizeof(mda_t)); memset(mda, 0, sizeof(mda_t)); @@ -273,24 +274,27 @@ void *mda_init() 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); + display_type = device_get_config_int("display_type"); + cgapal_rebuild(display_type, 0); + for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = makecol32(0, 0, 0); - if (c & 8) mdacols[c][0][1] = makecol32(0xff, 0xff, 0xff); - else mdacols[c][0][1] = makecol32(0xaa, 0xaa, 0xaa); + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = cgapal[0]; + if (c & 8) mdacols[c][0][1] = cgapal[0xf]; + else mdacols[c][0][1] = cgapal[0x7]; } - mdacols[0x70][0][1] = makecol32(0, 0, 0); - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0xF0][0][1] = makecol32(0, 0, 0); - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0x78][0][1] = makecol32(0xaa, 0xaa, 0xaa); - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0xF8][0][1] = makecol32(0xaa, 0xaa, 0xaa); - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = makecol32(0xff, 0xff, 0xff); - mdacols[0x00][0][1] = mdacols[0x00][1][1] = makecol32(0, 0, 0); - mdacols[0x08][0][1] = mdacols[0x08][1][1] = makecol32(0, 0, 0); - mdacols[0x80][0][1] = mdacols[0x80][1][1] = makecol32(0, 0, 0); - mdacols[0x88][0][1] = mdacols[0x88][1][1] = makecol32(0, 0, 0); + mdacols[0x70][0][1] = cgapal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = cgapal[0xf]; + mdacols[0xF0][0][1] = cgapal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = cgapal[0xf]; + mdacols[0x78][0][1] = cgapal[0x7]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = cgapal[0xf]; + mdacols[0xF8][0][1] = cgapal[0x7]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = cgapal[0xf]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = cgapal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; return mda; } @@ -310,6 +314,37 @@ void mda_speed_changed(void *p) mda_recalctimings(mda); } +static device_config_t mda_config[] = +{ + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Green", + .value = DISPLAY_GREEN + }, + { + .description = "Amber", + .value = DISPLAY_AMBER + }, + { + .description = "White", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + }, + .default_int = DISPLAY_WHITE + }, + { + .type = -1 + } +}; + device_t mda_device = { "MDA", @@ -319,5 +354,6 @@ device_t mda_device = NULL, mda_speed_changed, NULL, - NULL + NULL, + mda_config }; diff --git a/src/video.c b/src/video.c index 80753cc..490a349 100644 --- a/src/video.c +++ b/src/video.c @@ -466,22 +466,7 @@ void initvideo() for (c = 0; c < 65536; c++) video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x00, 0x00, 0xaa); - cgapal[0x2] = makecol(0x00, 0xaa, 0x00); - cgapal[0x3] = makecol(0x00, 0xaa, 0xaa); - cgapal[0x4] = makecol(0xaa, 0x00, 0x00); - cgapal[0x5] = makecol(0xaa, 0x00, 0xaa); - cgapal[0x6] = makecol(0xaa, 0x55, 0x00); - cgapal[0x7] = makecol(0xaa, 0xaa, 0xaa); - cgapal[0x8] = makecol(0x55, 0x55, 0x55); - cgapal[0x9] = makecol(0x55, 0x55, 0xff); - cgapal[0xa] = makecol(0x55, 0xff, 0x55); - cgapal[0xb] = makecol(0x55, 0xff, 0xff); - cgapal[0xc] = makecol(0xff, 0x55, 0x55); - cgapal[0xd] = makecol(0xff, 0x55, 0xff); - cgapal[0xe] = makecol(0xff, 0xff, 0x55); - cgapal[0xf] = makecol(0xff, 0xff, 0xff); + cgapal_rebuild(DISPLAY_RGB, 0); blit_data.wake_blit_thread = thread_create_event(); blit_data.blit_complete = thread_create_event(); @@ -548,3 +533,156 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) blit_data.h = h; thread_set_event(blit_data.wake_blit_thread); } + +void cgapal_rebuild(int display_type, int contrast) +{ + switch (display_type) + { + case DISPLAY_GREEN: + if (contrast) + { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x34, 0x0c); + cgapal[0x2] = makecol(0x04, 0x5d, 0x14); + cgapal[0x3] = makecol(0x04, 0x69, 0x18); + cgapal[0x4] = makecol(0x08, 0xa2, 0x24); + cgapal[0x5] = makecol(0x08, 0xb2, 0x28); + cgapal[0x6] = makecol(0x0c, 0xe7, 0x34); + cgapal[0x7] = makecol(0x0c, 0xf3, 0x38); + cgapal[0x8] = makecol(0x00, 0x1c, 0x04); + cgapal[0x9] = makecol(0x04, 0x4d, 0x10); + cgapal[0xa] = makecol(0x04, 0x7d, 0x1c); + cgapal[0xb] = makecol(0x04, 0x8e, 0x20); + cgapal[0xc] = makecol(0x08, 0xc7, 0x2c); + cgapal[0xd] = makecol(0x08, 0xd7, 0x30); + cgapal[0xe] = makecol(0x14, 0xff, 0x45); + cgapal[0xf] = makecol(0x34, 0xff, 0x5d); + } + else + { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x34, 0x0c); + cgapal[0x2] = makecol(0x04, 0x55, 0x14); + cgapal[0x3] = makecol(0x04, 0x5d, 0x14); + cgapal[0x4] = makecol(0x04, 0x86, 0x20); + cgapal[0x5] = makecol(0x04, 0x92, 0x20); + cgapal[0x6] = makecol(0x08, 0xba, 0x2c); + cgapal[0x7] = makecol(0x08, 0xc7, 0x2c); + cgapal[0x8] = makecol(0x04, 0x8a, 0x20); + cgapal[0x9] = makecol(0x08, 0xa2, 0x24); + cgapal[0xa] = makecol(0x08, 0xc3, 0x2c); + cgapal[0xb] = makecol(0x08, 0xcb, 0x30); + cgapal[0xc] = makecol(0x0c, 0xe7, 0x34); + cgapal[0xd] = makecol(0x0c, 0xef, 0x38); + cgapal[0xe] = makecol(0x24, 0xff, 0x51); + cgapal[0xf] = makecol(0x34, 0xff, 0x5d); + } + break; + case DISPLAY_AMBER: + if (contrast) + { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x55, 0x14, 0x00); + cgapal[0x2] = makecol(0x82, 0x2c, 0x00); + cgapal[0x3] = makecol(0x92, 0x34, 0x00); + cgapal[0x4] = makecol(0xcf, 0x61, 0x00); + cgapal[0x5] = makecol(0xdf, 0x6d, 0x00); + cgapal[0x6] = makecol(0xff, 0x9a, 0x04); + cgapal[0x7] = makecol(0xff, 0xae, 0x18); + cgapal[0x8] = makecol(0x2c, 0x08, 0x00); + cgapal[0x9] = makecol(0x6d, 0x20, 0x00); + cgapal[0xa] = makecol(0xa6, 0x45, 0x00); + cgapal[0xb] = makecol(0xba, 0x51, 0x00); + cgapal[0xc] = makecol(0xef, 0x79, 0x00); + cgapal[0xd] = makecol(0xfb, 0x86, 0x00); + cgapal[0xe] = makecol(0xff, 0xcb, 0x28); + cgapal[0xf] = makecol(0xff, 0xe3, 0x34); + } + else + { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x55, 0x14, 0x00); + cgapal[0x2] = makecol(0x79, 0x24, 0x00); + cgapal[0x3] = makecol(0x86, 0x2c, 0x00); + cgapal[0x4] = makecol(0xae, 0x49, 0x00); + cgapal[0x5] = makecol(0xbe, 0x55, 0x00); + cgapal[0x6] = makecol(0xe3, 0x71, 0x00); + cgapal[0x7] = makecol(0xef, 0x79, 0x00); + cgapal[0x8] = makecol(0xb2, 0x4d, 0x00); + cgapal[0x9] = makecol(0xcb, 0x5d, 0x00); + cgapal[0xa] = makecol(0xeb, 0x79, 0x00); + cgapal[0xb] = makecol(0xf3, 0x7d, 0x00); + cgapal[0xc] = makecol(0xff, 0x9e, 0x04); + cgapal[0xd] = makecol(0xff, 0xaa, 0x10); + cgapal[0xe] = makecol(0xff, 0xdb, 0x30); + cgapal[0xf] = makecol(0xff, 0xe3, 0x34); + } + break; + case DISPLAY_WHITE: + if (contrast) + { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x37, 0x3d, 0x40); + cgapal[0x2] = makecol(0x55, 0x5c, 0x5f); + cgapal[0x3] = makecol(0x61, 0x67, 0x6b); + cgapal[0x4] = makecol(0x8f, 0x95, 0x95); + cgapal[0x5] = makecol(0x9b, 0xa0, 0x9f); + cgapal[0x6] = makecol(0xcc, 0xcf, 0xc8); + cgapal[0x7] = makecol(0xdf, 0xde, 0xd4); + cgapal[0x8] = makecol(0x24, 0x27, 0x29); + cgapal[0x9] = makecol(0x42, 0x48, 0x4c); + cgapal[0xa] = makecol(0x70, 0x76, 0x78); + cgapal[0xb] = makecol(0x81, 0x87, 0x87); + cgapal[0xc] = makecol(0xaf, 0xb3, 0xb0); + cgapal[0xd] = makecol(0xbb, 0xbf, 0xba); + cgapal[0xe] = makecol(0xef, 0xed, 0xdf); + cgapal[0xf] = makecol(0xff, 0xfd, 0xed); + } + else + { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x37, 0x3d, 0x40); + cgapal[0x2] = makecol(0x4a, 0x50, 0x54); + cgapal[0x3] = makecol(0x55, 0x5c, 0x5f); + cgapal[0x4] = makecol(0x78, 0x7e, 0x80); + cgapal[0x5] = makecol(0x81, 0x87, 0x87); + cgapal[0x6] = makecol(0xa3, 0xa7, 0xa6); + cgapal[0x7] = makecol(0xaf, 0xb3, 0xb0); + cgapal[0x8] = makecol(0x7a, 0x81, 0x83); + cgapal[0x9] = makecol(0x8c, 0x92, 0x92); + cgapal[0xa] = makecol(0xac, 0xb0, 0xad); + cgapal[0xb] = makecol(0xb3, 0xb7, 0xb4); + cgapal[0xc] = makecol(0xd1, 0xd3, 0xcb); + cgapal[0xd] = makecol(0xd9, 0xdb, 0xd2); + cgapal[0xe] = makecol(0xf7, 0xf5, 0xe7); + cgapal[0xf] = makecol(0xff, 0xfd, 0xed); + } + break; + + default: + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x00, 0xaa); + cgapal[0x2] = makecol(0x00, 0xaa, 0x00); + cgapal[0x3] = makecol(0x00, 0xaa, 0xaa); + cgapal[0x4] = makecol(0xaa, 0x00, 0x00); + cgapal[0x5] = makecol(0xaa, 0x00, 0xaa); + if (display_type == DISPLAY_RGB_NO_BROWN) + { + cgapal[0x6] = makecol(0xaa, 0xaa, 0x00); + } + else + { + cgapal[0x6] = makecol(0xaa, 0x55, 0x00); + } + cgapal[0x7] = makecol(0xaa, 0xaa, 0xaa); + cgapal[0x8] = makecol(0x55, 0x55, 0x55); + cgapal[0x9] = makecol(0x55, 0x55, 0xff); + cgapal[0xa] = makecol(0x55, 0xff, 0x55); + cgapal[0xb] = makecol(0x55, 0xff, 0xff); + cgapal[0xc] = makecol(0xff, 0x55, 0x55); + cgapal[0xd] = makecol(0xff, 0x55, 0xff); + cgapal[0xe] = makecol(0xff, 0xff, 0x55); + cgapal[0xf] = makecol(0xff, 0xff, 0xff); + break; + } +} diff --git a/src/video.h b/src/video.h index ffca4e8..c342b4c 100644 --- a/src/video.h +++ b/src/video.h @@ -99,3 +99,12 @@ void hline(BITMAP *b, int x1, int y, int x2, int col); void destroy_bitmap(BITMAP *b); extern uint32_t cgapal[16]; + +#define DISPLAY_RGB 0 +#define DISPLAY_COMPOSITE 1 +#define DISPLAY_RGB_NO_BROWN 2 +#define DISPLAY_GREEN 3 +#define DISPLAY_AMBER 4 +#define DISPLAY_WHITE 5 + +void cgapal_rebuild(int display_type, int contrast); diff --git a/src/win-deviceconfig.c b/src/win-deviceconfig.c index 4160523..45780a1 100644 --- a/src/win-deviceconfig.c +++ b/src/win-deviceconfig.c @@ -235,7 +235,7 @@ void deviceconfig_open(HWND hwnd, device_t *device) item->y = y; item->id = id++; - item->cx = 80; + item->cx = 200; item->cy = 15; item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; From 45bd0db00c25a51349b9b4351affcb121c0ddee4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Jun 2017 17:47:13 +0100 Subject: [PATCH 0034/1050] Corrected EuroPC CPU options. Patch from ecksemmess. --- src/cpu.c | 9 +++++++++ src/cpu.h | 1 + src/model.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cpu.c b/src/cpu.c index 2a6eda6..c58c7df 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -141,6 +141,15 @@ CPU cpus_pcjr[] = {"", -1, 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*/ diff --git a/src/cpu.h b/src/cpu.h index 18671f3..60ff266 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -88,6 +88,7 @@ extern CPU cpus_Pentium[]; extern CPU cpus_6x86[]; extern CPU cpus_pcjr[]; +extern CPU cpus_europc[]; extern CPU cpus_pc1512[]; extern CPU cpus_ibmat[]; extern CPU cpus_ps1_m2011[]; diff --git a/src/model.c b/src/model.c index 41715d3..b9fa9f9 100644 --- a/src/model.c +++ b/src/model.c @@ -107,7 +107,7 @@ MODEL models[] = {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, {"Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Euro PC", ROM_EUROPC, "europc", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, From d7b10fd12fde722c5be34b3a68589836fff0bc71 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Jun 2017 17:58:56 +0100 Subject: [PATCH 0035/1050] Load IBM BIOS on Laser XT systems if available. Patch from Greatpsycho. --- src/mem.c | 61 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/src/mem.c b/src/mem.c index b387016..b2f79e9 100644 --- a/src/mem.c +++ b/src/mem.c @@ -69,6 +69,45 @@ static void mem_load_atide115_bios() fclose(f); } } + +static int mem_load_basic(char *path) +{ + char s[256]; + FILE *f; + + sprintf(s, "%s/ibm-basic-1.10.rom", path); + f = romfopen(s, "rb"); + if (!f) + { + sprintf(s, "%s/basicc11.f6", path); + f = romfopen(s, "rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom + 0x6000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.f8", path); + f = romfopen(s, "rb"); + if (!f) return 0; /*But if some of it is there, then all of it must be*/ + fread(rom + 0x8000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.fa", path); + f = romfopen(s, "rb"); + if (!f) return 0; + fread(rom + 0xA000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.fc", path); + f = romfopen(s, "rb"); + if (!f) return 0; + fread(rom + 0xC000, 8192, 1, f); + fclose(f); + } + else + { + fread(rom + 0x6000, 32768, 1, f); + fclose(f); + } + + return 1; +} int loadbios() { @@ -361,22 +400,8 @@ int loadbios() // f=fopen("pc081682.bin","rb"); fread(rom+0xE000,8192,1,f); fclose(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); + if (!mem_load_basic("roms/ibmpc")) + break; return 1; case ROM_MEGAPC: @@ -531,6 +556,8 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); + if (!mem_load_basic("roms/ltxt")) + break; return 1; case ROM_LXT3: @@ -538,6 +565,8 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); + if (!mem_load_basic("roms/lxt3")) + break; return 1; case ROM_PX386: /*Phoenix 80386 BIOS*/ From 8c56b71184983220f7a5c53b996d603c6048b15c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Jun 2017 21:30:07 +0100 Subject: [PATCH 0036/1050] Enable scrollbar in configuration manager dialogue. --- src/pc.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc.rc b/src/pc.rc index 2f1900d..429788d 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -326,5 +326,5 @@ BEGIN DEFPUSHBUTTON "Configuration...", IDC_CONFIG, 200-54,58, 50, 14, WS_TABSTOP DEFPUSHBUTTON "HDD...", IDC_HDCONF, 200-54,76, 50, 14, WS_TABSTOP - LISTBOX IDC_LIST, 4, 4,140,142, WS_TABSTOP + LISTBOX IDC_LIST, 4, 4,140,142, WS_TABSTOP|WS_VSCROLL END From 472a76892a8892033b6b4a967547ce88dea0c36d Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 5 Jun 2017 20:43:47 +0100 Subject: [PATCH 0037/1050] Added EMS support to Laser XT machines. Patch from Greatpsycho. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/allegro-gui-configure.c | 2 +- src/laserxt.c | 112 +++++++++++++++++++++++++++++++++++ src/laserxt.h | 1 + src/mem.c | 6 +- src/model.c | 13 +++- 14 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 src/laserxt.c create mode 100644 src/laserxt.h diff --git a/src/Makefile.am b/src/Makefile.am index dbf3360..35ed872 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing dac.c dells200.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 \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.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 mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ +laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 8d9ad8a..26e3e10 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -10,7 +10,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 9d58188..a6ecc81 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -8,7 +8,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 9550405..c44faa4 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -9,7 +9,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index c0caaaa..1802e04 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -8,7 +8,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index a344795..c9fb127 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad 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 \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 124fc8c..169eaaf 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad 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 dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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 49a1949..cfaaab8 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad 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 \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 4ea2833..a54f1e6 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -8,7 +8,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.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 mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/allegro-gui-configure.c b/src/allegro-gui-configure.c index cdd16a3..0c2e321 100644 --- a/src/allegro-gui-configure.c +++ b/src/allegro-gui-configure.c @@ -290,7 +290,7 @@ static DIALOG configure_dialog[] = {d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0}, //7 {list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //8 - {d_edit_proc, 70*2, 276, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0}, + {d_edit_proc, 70*2, 276, 40, 14, 0, 0xffffff, 0, 0, 4, 0, mem_size_str, 0, 0}, {d_text_proc, 98*2, 276, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, diff --git a/src/laserxt.c b/src/laserxt.c new file mode 100644 index 0000000..d66c92b --- /dev/null +++ b/src/laserxt.c @@ -0,0 +1,112 @@ +/*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; + +static 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; +} + +static 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); + mem_mapping_set_exec(&laserxt_ems_mapping[port >> 14], ram + vaddr); + } + else + { + mem_mapping_disable(&laserxt_ems_mapping[port >> 14]); + } + + 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); + + 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); + + flushmmucache(); + break; + } +} + +static uint8_t laserxt_read(uint16_t port, void *priv) +{ + switch (port) + { + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + return laserxt_emspage[port >> 14]; + + case 0x0209: case 0x4209: case 0x8209: case 0xC209: + return laserxt_emscontrol[port >> 14]; + } + return 0xff; +} + +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; +} + +static 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 0000000..abf7df1 --- /dev/null +++ b/src/laserxt.h @@ -0,0 +1 @@ +void laserxt_init(); diff --git a/src/mem.c b/src/mem.c index b2f79e9..8ce0d7c 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1911,7 +1911,8 @@ void mem_init() 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); // pclog("Mem resize %i %i\n",mem_size,c); } @@ -2009,7 +2010,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); // pclog("Mem resize %i %i\n",mem_size,c); mem_a20_key = 2; diff --git a/src/model.c b/src/model.c index b9fa9f9..f1ecff9 100644 --- a/src/model.c +++ b/src/model.c @@ -27,6 +27,7 @@ #include "keyboard_olim24.h" #include "keyboard_pcjr.h" #include "keyboard_xt.h" +#include "laserxt.h" #include "lpt.h" #include "mem.h" #include "mouse_ps2.h" @@ -85,7 +86,7 @@ void at_sis496_init(); void at_i430vx_init(); void at_batman_init(); void at_endeavor_init(); - +void xt_laserxt_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -98,8 +99,8 @@ MODEL models[] = {"Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, {"Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, @@ -289,6 +290,12 @@ void olim24_init() device_add(&gameport_device); } +void xt_laserxt_init() +{ + xt_init(); + laserxt_init(); +} + void at_init() { AT = 1; From 099b7a21d112edc6449745e05ef4cd41bcfd426d Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 6 Jun 2017 21:53:30 +0100 Subject: [PATCH 0038/1050] Added NukedOPL emulator for OPL3. Based on patch from Battler. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/sound_adlibgold.c | 21 +++- src/sound_dbopl.cc | 56 ++++++++--- src/sound_dbopl.h | 2 +- src/sound_opl.c | 8 +- src/sound_opl.h | 5 +- src/sound_pas16.c | 2 +- src/sound_sb.c | 186 ++++++++++++++++++++++++++++++++--- src/sound_wss.c | 32 +++++- 17 files changed, 281 insertions(+), 49 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 35ed872..8965c21 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,7 @@ vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_ 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 vid_wy700.c \ x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ -dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \ +dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_PS_.cc resid-fp/wave6581_PST.cc \ resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc resid-fp/wave8580_PS_.cc \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 26e3e10..b8dc43f 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -22,7 +22,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_ 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 wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index a6ecc81..d828df9 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -22,7 +22,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o -DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index c44faa4..3e1f78d 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -21,7 +21,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_ 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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 1802e04..e331164 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -22,7 +22,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o -DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw b/src/Makefile.mingw index c9fb127..cbc49d7 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 169eaaf..8c2e2bf 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o -DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index cfaaab8..67df2c0 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index a54f1e6..bf8a60f 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -22,7 +22,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o -DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index 063d261..bc5b445 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -768,12 +768,14 @@ void *adgold_init() FILE *f; int c; double out; + int opl_emu; adgold_t *adgold = malloc(sizeof(adgold_t)); memset(adgold, 0, sizeof(adgold_t)); adgold->surround_enabled = device_get_config_int("surround"); + opl_emu = device_get_config_int("opl_emu"); - opl3_init(&adgold->opl); + opl3_init(&adgold->opl, opl_emu); if (adgold->surround_enabled) ym7128_init(&adgold->ym7128); @@ -844,6 +846,23 @@ static device_config_t adgold_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, { .type = -1 } diff --git a/src/sound_dbopl.cc b/src/sound_dbopl.cc index 7040747..7342ea4 100644 --- a/src/sound_dbopl.cc +++ b/src/sound_dbopl.cc @@ -1,15 +1,18 @@ #include "dosbox/dbopl.h" +#include "dosbox/nukedopl.h" #include "sound_dbopl.h" static struct { DBOPL::Chip chip; + struct opl3_chip opl3chip; int addr; int timer[2]; uint8_t timer_ctrl; uint8_t status_mask; uint8_t status; int is_opl3; + int opl_emu; void (*timer_callback)(void *param, int timer, int64_t period); void *timer_param; @@ -31,13 +34,25 @@ enum CTRL_TIMER1_CTRL = 0x01 }; -void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3) +void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3, int opl_emu) { - 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; + if (!is_opl3 || !opl_emu) + { + 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; + opl[nr].opl_emu = opl_emu; + } + else + { + OPL3_Reset(&opl[nr].opl3chip, 48000); + opl[nr].timer_callback = timer_callback; + opl[nr].timer_param = timer_param; + opl[nr].is_opl3 = is_opl3; + opl[nr].opl_emu = opl_emu; + } } void opl_status_update(int nr) @@ -67,10 +82,18 @@ void opl_timer_over(int nr, int timer) void opl_write(int nr, uint16_t addr, uint8_t val) { if (!(addr & 1)) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & (opl[nr].is_opl3 ? 0x1ff : 0xff); + { + if (!opl[nr].is_opl3 || !opl[nr].opl_emu) + 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; + } else { - opl[nr].chip.WriteReg(opl[nr].addr, val); + if (!opl[nr].is_opl3 || !opl[nr].opl_emu) + opl[nr].chip.WriteReg(opl[nr].addr, val); + else + OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); switch (opl[nr].addr) { @@ -133,9 +156,16 @@ void opl3_update(int nr, int16_t *buffer, int samples) { int c; Bit32s buffer_32[samples*2]; - - opl[nr].chip.GenerateBlock3(samples, buffer_32); - - for (c = 0; c < samples*2; c++) - buffer[c] = (int16_t)buffer_32[c]; + + if (opl[nr].opl_emu) + { + 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 0890552..4aa03bf 100644 --- a/src/sound_dbopl.h +++ b/src/sound_dbopl.h @@ -1,7 +1,7 @@ #ifdef __cplusplus extern "C" { #endif - void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3); + void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3, int opl_emu); void opl_write(int nr, uint16_t addr, uint8_t val); uint8_t opl_read(int nr, uint16_t addr); void opl_timer_over(int nr, int timer); diff --git a/src/sound_opl.c b/src/sound_opl.c index 9fece84..2a59460 100644 --- a/src/sound_opl.c +++ b/src/sound_opl.c @@ -159,17 +159,17 @@ static void opl_timer_callback11(void *p) void opl2_init(opl_t *opl) { - opl_init(ym3812_timer_set_0, opl, 0, 0); - opl_init(ym3812_timer_set_1, opl, 1, 0); + opl_init(ym3812_timer_set_0, opl, 0, 0, 0); + opl_init(ym3812_timer_set_1, opl, 1, 0, 0); timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); timer_add(opl_timer_callback10, &opl->timers[1][0], &opl->timers_enable[1][0], (void *)opl); timer_add(opl_timer_callback11, &opl->timers[1][1], &opl->timers_enable[1][1], (void *)opl); } -void opl3_init(opl_t *opl) +void opl3_init(opl_t *opl, int opl_emu) { - opl_init(ymf262_timer_set, opl, 0, 1); + opl_init(ymf262_timer_set, opl, 0, 1, opl_emu); timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); } diff --git a/src/sound_opl.h b/src/sound_opl.h index 047808e..8d67bb9 100644 --- a/src/sound_opl.h +++ b/src/sound_opl.h @@ -24,7 +24,10 @@ void opl2_poll(opl_t *opl, int16_t *bufl, int16_t *bufr); void opl3_poll(opl_t *opl, int16_t *bufl, int16_t *bufr); void opl2_init(opl_t *opl); -void opl3_init(opl_t *opl); +void opl3_init(opl_t *opl, int opl_emu); void opl2_update2(opl_t *opl); void opl3_update2(opl_t *opl); + +#define OPL_DBOPL 0 +#define OPL_NUKED 1 diff --git a/src/sound_pas16.c b/src/sound_pas16.c index 2e6f4be..bbb2fbc 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -731,7 +731,7 @@ void *pas16_init() pas16_t *pas16 = malloc(sizeof(pas16_t)); memset(pas16, 0, sizeof(pas16_t)); - opl3_init(&pas16->opl); + opl3_init(&pas16->opl, 0); sb_dsp_init(&pas16->dsp, SB2); io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); diff --git a/src/sound_sb.c b/src/sound_sb.c index 605c605..264c2b1 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -39,6 +39,8 @@ typedef struct sb_t int pos; uint8_t pos_regs[8]; + + int opl_emu; } sb_t; static int sb_att[]= @@ -61,8 +63,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) { @@ -112,8 +114,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) * 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) * (sb->opl_emu ? 47000 : 55000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 55000)) >> 16); if (sb->mixer.filter) { @@ -322,6 +324,7 @@ uint8_t sb_16_mixer_read(uint16_t addr, void *p) switch (mixer->index) { + case 0x40: return 0xff; case 0x80: switch (sb->dsp.sb_irqnum) { @@ -535,7 +538,8 @@ void *sb_pro_v2_init() uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); - opl3_init(&sb->opl); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); sb_dsp_init(&sb->dsp, SBPRO2); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); @@ -558,14 +562,11 @@ void *sb_pro_v2_init() void *sb_pro_mcv_init() { sb_t *sb = malloc(sizeof(sb_t)); - //uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); - opl3_init(&sb->opl); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); 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); @@ -587,7 +588,8 @@ void *sb_16_init() sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); - opl3_init(&sb->opl); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); sb_dsp_init(&sb->dsp, SB16); sb_dsp_setaddr(&sb->dsp, 0x0220); sb_mixer_init(&sb->mixer); @@ -626,7 +628,8 @@ void *sb_awe32_init() int onboard_ram = device_get_config_int("onboard_ram"); memset(sb, 0, sizeof(sb_t)); - opl3_init(&sb->opl); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); sb_dsp_init(&sb->dsp, SB16 + 1); sb_dsp_setaddr(&sb->dsp, 0x0220); sb_mixer_init(&sb->mixer); @@ -812,7 +815,7 @@ static device_config_t sb_mcv_config[] = } }; -static device_config_t sb_pro_config[] = +static device_config_t sb_pro_v1_config[] = { { .name = "addr", @@ -888,6 +891,123 @@ static device_config_t sb_pro_config[] = } }; +static device_config_t sb_pro_v2_config[] = +{ + { + .name = "addr", + .description = "Address", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "" + } + }, + .default_int = 0x220 + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { + .description = "" + } + }, + .default_int = 1 + }, + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, + { + .type = -1 + } +}; + +static device_config_t sb_pro_mcv_config[] = +{ + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, + { + .type = -1 + } +}; + static device_config_t sb_16_config[] = { { @@ -896,6 +1016,23 @@ static device_config_t sb_16_config[] = .type = CONFIG_MIDI, .default_int = 0 }, + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, { .type = -1 } @@ -941,6 +1078,23 @@ static device_config_t sb_awe32_config[] = }, .default_int = 512 }, + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, { .type = -1 } @@ -1004,7 +1158,7 @@ device_t sb_pro_v1_device = sb_speed_changed, NULL, sb_add_status_info, - sb_pro_config + sb_pro_v1_config }; device_t sb_pro_v2_device = { @@ -1016,7 +1170,7 @@ device_t sb_pro_v2_device = sb_speed_changed, NULL, sb_add_status_info, - sb_pro_config + sb_pro_v2_config }; device_t sb_pro_mcv_device = { @@ -1028,7 +1182,7 @@ device_t sb_pro_mcv_device = sb_speed_changed, NULL, sb_add_status_info, - NULL + sb_pro_mcv_config }; device_t sb_16_device = { diff --git a/src/sound_wss.c b/src/sound_wss.c index bd94c38..4129744 100644 --- a/src/sound_wss.c +++ b/src/sound_wss.c @@ -78,11 +78,12 @@ static void wss_get_buffer(int32_t *buffer, int len, void *p) void *wss_init() { + int opl_emu; wss_t *wss = malloc(sizeof(wss_t)); - memset(wss, 0, sizeof(wss_t)); - opl3_init(&wss->opl); + opl_emu = device_get_config_int("opl_emu"); + opl3_init(&wss->opl, opl_emu); ad1848_init(&wss->ad1848); ad1848_setirq(&wss->ad1848, 7); @@ -111,6 +112,30 @@ void wss_speed_changed(void *p) ad1848_speed_changed(&wss->ad1848); } +static device_config_t wss_config[] = +{ + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, + { + .type = -1 + } +}; + device_t wss_device = { "Windows Sound System", @@ -120,5 +145,6 @@ device_t wss_device = NULL, wss_speed_changed, NULL, - NULL + NULL, + wss_config }; From f928b153e285db9b580a920b0ece97856017faa8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 7 Jun 2017 17:46:45 +0100 Subject: [PATCH 0039/1050] Added NukedOPL files --- src/dosbox/nukedopl.cpp | 1371 +++++++++++++++++++++++++++++++++++++++ src/dosbox/nukedopl.h | 103 +++ 2 files changed, 1474 insertions(+) create mode 100644 src/dosbox/nukedopl.cpp create mode 100644 src/dosbox/nukedopl.h diff --git a/src/dosbox/nukedopl.cpp b/src/dosbox/nukedopl.cpp new file mode 100644 index 0000000..374b9bf --- /dev/null +++ b/src/dosbox/nukedopl.cpp @@ -0,0 +1,1371 @@ +// +// Nuked OPL3 emulator. +// Thanks: +// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): +// Feedback and Rhythm part calculation information. +// forums.submarine.org.uk(carbon14, opl3): +// Tremolo and phase generator calculation information. +// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): +// OPL2 ROMs. +// +// version: 1.7.4 +// + +#include +#include +#include +#include "nukedopl.h" + +#define RSM_FRAC 10 + +// Channel types + +enum { + ch_2op = 0, + ch_4op = 1, + ch_4op2 = 2, + ch_drum = 3 +}; + +// Envelope key types + +enum { + egk_norm = 0x01, + egk_drum = 0x02 +}; + + +// +// logsin table +// + +static const Bit16u logsinrom[256] = { + 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, + 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, + 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, + 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, + 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, + 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, + 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, + 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, + 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, + 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, + 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, + 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, + 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, + 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, + 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, + 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, + 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, + 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, + 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, + 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, + 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, + 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, + 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, + 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, + 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, + 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, + 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, + 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, + 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, + 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, + 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 +}; + +// +// exp table +// + +static const Bit16u exprom[256] = { + 0x000, 0x003, 0x006, 0x008, 0x00b, 0x00e, 0x011, 0x014, + 0x016, 0x019, 0x01c, 0x01f, 0x022, 0x025, 0x028, 0x02a, + 0x02d, 0x030, 0x033, 0x036, 0x039, 0x03c, 0x03f, 0x042, + 0x045, 0x048, 0x04b, 0x04e, 0x051, 0x054, 0x057, 0x05a, + 0x05d, 0x060, 0x063, 0x066, 0x069, 0x06c, 0x06f, 0x072, + 0x075, 0x078, 0x07b, 0x07e, 0x082, 0x085, 0x088, 0x08b, + 0x08e, 0x091, 0x094, 0x098, 0x09b, 0x09e, 0x0a1, 0x0a4, + 0x0a8, 0x0ab, 0x0ae, 0x0b1, 0x0b5, 0x0b8, 0x0bb, 0x0be, + 0x0c2, 0x0c5, 0x0c8, 0x0cc, 0x0cf, 0x0d2, 0x0d6, 0x0d9, + 0x0dc, 0x0e0, 0x0e3, 0x0e7, 0x0ea, 0x0ed, 0x0f1, 0x0f4, + 0x0f8, 0x0fb, 0x0ff, 0x102, 0x106, 0x109, 0x10c, 0x110, + 0x114, 0x117, 0x11b, 0x11e, 0x122, 0x125, 0x129, 0x12c, + 0x130, 0x134, 0x137, 0x13b, 0x13e, 0x142, 0x146, 0x149, + 0x14d, 0x151, 0x154, 0x158, 0x15c, 0x160, 0x163, 0x167, + 0x16b, 0x16f, 0x172, 0x176, 0x17a, 0x17e, 0x181, 0x185, + 0x189, 0x18d, 0x191, 0x195, 0x199, 0x19c, 0x1a0, 0x1a4, + 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc, 0x1c0, 0x1c4, + 0x1c8, 0x1cc, 0x1d0, 0x1d4, 0x1d8, 0x1dc, 0x1e0, 0x1e4, + 0x1e8, 0x1ec, 0x1f0, 0x1f5, 0x1f9, 0x1fd, 0x201, 0x205, + 0x209, 0x20e, 0x212, 0x216, 0x21a, 0x21e, 0x223, 0x227, + 0x22b, 0x230, 0x234, 0x238, 0x23c, 0x241, 0x245, 0x249, + 0x24e, 0x252, 0x257, 0x25b, 0x25f, 0x264, 0x268, 0x26d, + 0x271, 0x276, 0x27a, 0x27f, 0x283, 0x288, 0x28c, 0x291, + 0x295, 0x29a, 0x29e, 0x2a3, 0x2a8, 0x2ac, 0x2b1, 0x2b5, + 0x2ba, 0x2bf, 0x2c4, 0x2c8, 0x2cd, 0x2d2, 0x2d6, 0x2db, + 0x2e0, 0x2e5, 0x2e9, 0x2ee, 0x2f3, 0x2f8, 0x2fd, 0x302, + 0x306, 0x30b, 0x310, 0x315, 0x31a, 0x31f, 0x324, 0x329, + 0x32e, 0x333, 0x338, 0x33d, 0x342, 0x347, 0x34c, 0x351, + 0x356, 0x35b, 0x360, 0x365, 0x36a, 0x370, 0x375, 0x37a, + 0x37f, 0x384, 0x38a, 0x38f, 0x394, 0x399, 0x39f, 0x3a4, + 0x3a9, 0x3ae, 0x3b4, 0x3b9, 0x3bf, 0x3c4, 0x3c9, 0x3cf, + 0x3d4, 0x3da, 0x3df, 0x3e4, 0x3ea, 0x3ef, 0x3f5, 0x3fa +}; + +// +// freq mult table multiplied by 2 +// +// 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 +// + +static const Bit8u mt[16] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 +}; + +// +// ksl table +// + +static const Bit8u kslrom[16] = { + 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 +}; + +static const Bit8u kslshift[4] = { + 8, 1, 2, 0 +}; + +// +// envelope generator constants +// + +static const Bit8u eg_incstep[3][4][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, 1, 0, 1, 0, 1, 0, 1 }, + { 0, 1, 0, 1, 1, 1, 0, 1 }, + { 0, 1, 1, 1, 0, 1, 1, 1 }, + { 0, 1, 1, 1, 1, 1, 1, 1 } + }, + { + { 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 1, 1, 2, 2, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 1, 1 } + } +}; + +static const Bit8u eg_incdesc[16] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2 +}; + +static const Bit8s eg_incsh[16] = { + 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2 +}; + +// +// address decoding +// + +static const Bit8s ad_slot[0x20] = { + 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, + 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const Bit8u ch_slot[18] = { + 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 +}; + +// +// Envelope generator +// + +typedef Bit16s(*envelope_sinfunc)(Bit16u phase, Bit16u envelope); +typedef void(*envelope_genfunc)(opl3_slot *slott); + +static Bit16s OPL3_EnvelopeCalcExp(Bit32u level) +{ + if (level > 0x1fff) + { + level = 0x1fff; + } + return ((exprom[(level & 0xff) ^ 0xff] | 0x400) << 1) >> (level >> 8); +} + +static Bit16s OPL3_EnvelopeCalcSin0(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + Bit16u neg = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + neg = ~0; + } + if (phase & 0x100) + { + out = logsinrom[(phase & 0xff) ^ 0xff]; + } + else + { + out = logsinrom[phase & 0xff]; + } + return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; +} + +static Bit16s OPL3_EnvelopeCalcSin1(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + out = 0x1000; + } + else if (phase & 0x100) + { + out = logsinrom[(phase & 0xff) ^ 0xff]; + } + else + { + out = logsinrom[phase & 0xff]; + } + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); +} + +static Bit16s OPL3_EnvelopeCalcSin2(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + phase &= 0x3ff; + if (phase & 0x100) + { + out = logsinrom[(phase & 0xff) ^ 0xff]; + } + else + { + out = logsinrom[phase & 0xff]; + } + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); +} + +static Bit16s OPL3_EnvelopeCalcSin3(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + phase &= 0x3ff; + if (phase & 0x100) + { + out = 0x1000; + } + else + { + out = logsinrom[phase & 0xff]; + } + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); +} + +static Bit16s OPL3_EnvelopeCalcSin4(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + Bit16u neg = 0; + phase &= 0x3ff; + if ((phase & 0x300) == 0x100) + { + neg = ~0; + } + if (phase & 0x200) + { + out = 0x1000; + } + else if (phase & 0x80) + { + out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; + } + else + { + out = logsinrom[(phase << 1) & 0xff]; + } + return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; +} + +static Bit16s OPL3_EnvelopeCalcSin5(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + out = 0x1000; + } + else if (phase & 0x80) + { + out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; + } + else + { + out = logsinrom[(phase << 1) & 0xff]; + } + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); +} + +static Bit16s OPL3_EnvelopeCalcSin6(Bit16u phase, Bit16u envelope) +{ + Bit16u neg = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + neg = ~0; + } + return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg; +} + +static Bit16s OPL3_EnvelopeCalcSin7(Bit16u phase, Bit16u envelope) +{ + Bit16u out = 0; + Bit16u neg = 0; + phase &= 0x3ff; + if (phase & 0x200) + { + neg = ~0; + phase = (phase & 0x1ff) ^ 0x1ff; + } + out = phase << 3; + return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; +} + +static const envelope_sinfunc envelope_sin[8] = { + OPL3_EnvelopeCalcSin0, + OPL3_EnvelopeCalcSin1, + OPL3_EnvelopeCalcSin2, + OPL3_EnvelopeCalcSin3, + OPL3_EnvelopeCalcSin4, + OPL3_EnvelopeCalcSin5, + OPL3_EnvelopeCalcSin6, + OPL3_EnvelopeCalcSin7 +}; + +static void OPL3_EnvelopeGenOff(opl3_slot *slot); +static void OPL3_EnvelopeGenAttack(opl3_slot *slot); +static void OPL3_EnvelopeGenDecay(opl3_slot *slot); +static void OPL3_EnvelopeGenSustain(opl3_slot *slot); +static void OPL3_EnvelopeGenRelease(opl3_slot *slot); + +envelope_genfunc envelope_gen[5] = { + OPL3_EnvelopeGenOff, + OPL3_EnvelopeGenAttack, + OPL3_EnvelopeGenDecay, + OPL3_EnvelopeGenSustain, + OPL3_EnvelopeGenRelease +}; + +enum envelope_gen_num +{ + envelope_gen_num_off = 0, + envelope_gen_num_attack = 1, + envelope_gen_num_decay = 2, + envelope_gen_num_sustain = 3, + envelope_gen_num_release = 4 +}; + +static Bit8u OPL3_EnvelopeCalcRate(opl3_slot *slot, Bit8u reg_rate) +{ + Bit8u rate; + if (reg_rate == 0x00) + { + return 0x00; + } + rate = (reg_rate << 2) + + (slot->reg_ksr ? slot->channel->ksv : (slot->channel->ksv >> 2)); + if (rate > 0x3c) + { + rate = 0x3c; + } + return rate; +} + +static void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) +{ + Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) + - ((0x08 - slot->channel->block) << 5); + if (ksl < 0) + { + ksl = 0; + } + slot->eg_ksl = (Bit8u)ksl; +} + +static void OPL3_EnvelopeUpdateRate(opl3_slot *slot) +{ + switch (slot->eg_gen) + { + case envelope_gen_num_off: + case envelope_gen_num_attack: + slot->eg_rate = OPL3_EnvelopeCalcRate(slot, slot->reg_ar); + break; + case envelope_gen_num_decay: + slot->eg_rate = OPL3_EnvelopeCalcRate(slot, slot->reg_dr); + break; + case envelope_gen_num_sustain: + case envelope_gen_num_release: + slot->eg_rate = OPL3_EnvelopeCalcRate(slot, slot->reg_rr); + break; + } +} + +static void OPL3_EnvelopeGenOff(opl3_slot *slot) +{ + slot->eg_rout = 0x1ff; +} + +static void OPL3_EnvelopeGenAttack(opl3_slot *slot) +{ + if (slot->eg_rout == 0x00) + { + slot->eg_gen = envelope_gen_num_decay; + OPL3_EnvelopeUpdateRate(slot); + return; + } + slot->eg_rout += ((~slot->eg_rout) * slot->eg_inc) >> 3; + if (slot->eg_rout < 0x00) + { + slot->eg_rout = 0x00; + } +} + +static void OPL3_EnvelopeGenDecay(opl3_slot *slot) +{ + if (slot->eg_rout >= slot->reg_sl << 4) + { + slot->eg_gen = envelope_gen_num_sustain; + OPL3_EnvelopeUpdateRate(slot); + return; + } + slot->eg_rout += slot->eg_inc; +} + +static void OPL3_EnvelopeGenSustain(opl3_slot *slot) +{ + if (!slot->reg_type) + { + OPL3_EnvelopeGenRelease(slot); + } +} + +static void OPL3_EnvelopeGenRelease(opl3_slot *slot) +{ + if (slot->eg_rout >= 0x1ff) + { + slot->eg_gen = envelope_gen_num_off; + slot->eg_rout = 0x1ff; + OPL3_EnvelopeUpdateRate(slot); + return; + } + slot->eg_rout += slot->eg_inc; +} + +static void OPL3_EnvelopeCalc(opl3_slot *slot) +{ + Bit8u rate_h, rate_l; + Bit8u inc = 0; + rate_h = slot->eg_rate >> 2; + rate_l = slot->eg_rate & 3; + if (eg_incsh[rate_h] > 0) + { + if ((slot->chip->timer & ((1 << eg_incsh[rate_h]) - 1)) == 0) + { + inc = eg_incstep[eg_incdesc[rate_h]][rate_l] + [((slot->chip->timer)>> eg_incsh[rate_h]) & 0x07]; + } + } + else + { + inc = eg_incstep[eg_incdesc[rate_h]][rate_l] + [slot->chip->timer & 0x07] << (-eg_incsh[rate_h]); + } + slot->eg_inc = inc; + slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; + envelope_gen[slot->eg_gen](slot); +} + +static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) +{ + if (!slot->key) + { + slot->eg_gen = envelope_gen_num_attack; + OPL3_EnvelopeUpdateRate(slot); + if ((slot->eg_rate >> 2) == 0x0f) + { + slot->eg_gen = envelope_gen_num_decay; + OPL3_EnvelopeUpdateRate(slot); + slot->eg_rout = 0x00; + } + slot->pg_phase = 0x00; + } + slot->key |= type; +} + +static void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) +{ + if (slot->key) + { + slot->key &= (~type); + if (!slot->key) + { + slot->eg_gen = envelope_gen_num_release; + OPL3_EnvelopeUpdateRate(slot); + } + } +} + +// +// Phase Generator +// + +static void OPL3_PhaseGenerate(opl3_slot *slot) +{ + Bit16u f_num; + Bit32u basefreq; + + f_num = slot->channel->f_num; + if (slot->reg_vib) + { + Bit8s range; + Bit8u vibpos; + + range = (f_num >> 7) & 7; + vibpos = slot->chip->vibpos; + + if (!(vibpos & 3)) + { + range = 0; + } + else if (vibpos & 1) + { + range >>= 1; + } + range >>= slot->chip->vibshift; + + if (vibpos & 4) + { + range = -range; + } + f_num += range; + } + basefreq = (f_num << slot->channel->block) >> 1; + slot->pg_phase += (basefreq * mt[slot->reg_mult]) >> 1; +} + +// +// Noise Generator +// + +static void OPL3_NoiseGenerate(opl3_chip *chip) +{ + if (chip->noise & 0x01) + { + chip->noise ^= 0x800302; + } + chip->noise >>= 1; +} + +// +// Slot +// + +static void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) +{ + if ((data >> 7) & 0x01) + { + slot->trem = &slot->chip->tremolo; + } + else + { + slot->trem = (Bit8u*)&slot->chip->zeromod; + } + slot->reg_vib = (data >> 6) & 0x01; + slot->reg_type = (data >> 5) & 0x01; + slot->reg_ksr = (data >> 4) & 0x01; + slot->reg_mult = data & 0x0f; + OPL3_EnvelopeUpdateRate(slot); +} + +static void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data) +{ + slot->reg_ksl = (data >> 6) & 0x03; + slot->reg_tl = data & 0x3f; + OPL3_EnvelopeUpdateKSL(slot); +} + +static void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data) +{ + slot->reg_ar = (data >> 4) & 0x0f; + slot->reg_dr = data & 0x0f; + OPL3_EnvelopeUpdateRate(slot); +} + +static void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) +{ + slot->reg_sl = (data >> 4) & 0x0f; + if (slot->reg_sl == 0x0f) + { + slot->reg_sl = 0x1f; + } + slot->reg_rr = data & 0x0f; + OPL3_EnvelopeUpdateRate(slot); +} + +static void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data) +{ + slot->reg_wf = data & 0x07; + if (slot->chip->newm == 0x00) + { + slot->reg_wf &= 0x03; + } +} + +static void OPL3_SlotGeneratePhase(opl3_slot *slot, Bit16u phase) +{ + slot->out = envelope_sin[slot->reg_wf](phase, slot->eg_out); +} + +static void OPL3_SlotGenerate(opl3_slot *slot) +{ + OPL3_SlotGeneratePhase(slot, (Bit16u)(slot->pg_phase >> 9) + *slot->mod); +} + +static void OPL3_SlotGenerateZM(opl3_slot *slot) +{ + OPL3_SlotGeneratePhase(slot, (Bit16u)(slot->pg_phase >> 9)); +} + +static void OPL3_SlotCalcFB(opl3_slot *slot) +{ + if (slot->channel->fb != 0x00) + { + slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb); + } + else + { + slot->fbmod = 0; + } + slot->prout = slot->out; +} + +// +// Channel +// + +static void OPL3_ChannelSetupAlg(opl3_channel *channel); + +static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) +{ + opl3_channel *channel6; + opl3_channel *channel7; + opl3_channel *channel8; + Bit8u chnum; + + chip->rhy = data & 0x3f; + if (chip->rhy & 0x20) + { + channel6 = &chip->channel[6]; + channel7 = &chip->channel[7]; + channel8 = &chip->channel[8]; + channel6->out[0] = &channel6->slots[1]->out; + channel6->out[1] = &channel6->slots[1]->out; + channel6->out[2] = &chip->zeromod; + channel6->out[3] = &chip->zeromod; + channel7->out[0] = &channel7->slots[0]->out; + channel7->out[1] = &channel7->slots[0]->out; + channel7->out[2] = &channel7->slots[1]->out; + channel7->out[3] = &channel7->slots[1]->out; + channel8->out[0] = &channel8->slots[0]->out; + channel8->out[1] = &channel8->slots[0]->out; + channel8->out[2] = &channel8->slots[1]->out; + channel8->out[3] = &channel8->slots[1]->out; + for (chnum = 6; chnum < 9; chnum++) + { + chip->channel[chnum].chtype = ch_drum; + } + OPL3_ChannelSetupAlg(channel6); + //hh + if (chip->rhy & 0x01) + { + OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); + } + else + { + OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); + } + //tc + if (chip->rhy & 0x02) + { + OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); + } + else + { + OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); + } + //tom + if (chip->rhy & 0x04) + { + OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); + } + else + { + OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); + } + //sd + if (chip->rhy & 0x08) + { + OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); + } + else + { + OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); + } + //bd + if (chip->rhy & 0x10) + { + OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); + } + else + { + OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); + } + } + else + { + for (chnum = 6; chnum < 9; chnum++) + { + chip->channel[chnum].chtype = ch_2op; + OPL3_ChannelSetupAlg(&chip->channel[chnum]); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum); + OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum); + } + } +} + +static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) +{ + if (channel->chip->newm && channel->chtype == ch_4op2) + { + return; + } + channel->f_num = (channel->f_num & 0x300) | data; + channel->ksv = (channel->block << 1) + | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); + OPL3_EnvelopeUpdateKSL(channel->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateRate(channel->slots[0]); + OPL3_EnvelopeUpdateRate(channel->slots[1]); + if (channel->chip->newm && channel->chtype == ch_4op) + { + channel->pair->f_num = channel->f_num; + channel->pair->ksv = channel->ksv; + OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); + } +} + +static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) +{ + if (channel->chip->newm && channel->chtype == ch_4op2) + { + return; + } + channel->f_num = (channel->f_num & 0xff) | ((data & 0x03) << 8); + channel->block = (data >> 2) & 0x07; + channel->ksv = (channel->block << 1) + | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); + OPL3_EnvelopeUpdateKSL(channel->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateRate(channel->slots[0]); + OPL3_EnvelopeUpdateRate(channel->slots[1]); + if (channel->chip->newm && channel->chtype == ch_4op) + { + channel->pair->f_num = channel->f_num; + channel->pair->block = channel->block; + channel->pair->ksv = channel->ksv; + OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); + } +} + +static void OPL3_ChannelSetupAlg(opl3_channel *channel) +{ + if (channel->chtype == ch_drum) + { + switch (channel->alg & 0x01) + { + case 0x00: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->slots[0]->out; + break; + case 0x01: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->chip->zeromod; + break; + } + return; + } + if (channel->alg & 0x08) + { + return; + } + if (channel->alg & 0x04) + { + channel->pair->out[0] = &channel->chip->zeromod; + channel->pair->out[1] = &channel->chip->zeromod; + channel->pair->out[2] = &channel->chip->zeromod; + channel->pair->out[3] = &channel->chip->zeromod; + switch (channel->alg & 0x03) + { + case 0x00: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; + channel->slots[0]->mod = &channel->pair->slots[1]->out; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->slots[1]->out; + channel->out[1] = &channel->chip->zeromod; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x01: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; + channel->slots[0]->mod = &channel->chip->zeromod; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->pair->slots[1]->out; + channel->out[1] = &channel->slots[1]->out; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x02: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->chip->zeromod; + channel->slots[0]->mod = &channel->pair->slots[1]->out; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->pair->slots[0]->out; + channel->out[1] = &channel->slots[1]->out; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x03: + channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; + channel->pair->slots[1]->mod = &channel->chip->zeromod; + channel->slots[0]->mod = &channel->pair->slots[1]->out; + channel->slots[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->pair->slots[0]->out; + channel->out[1] = &channel->slots[0]->out; + channel->out[2] = &channel->slots[1]->out; + channel->out[3] = &channel->chip->zeromod; + break; + } + } + else + { + switch (channel->alg & 0x01) + { + case 0x00: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->slots[0]->out; + channel->out[0] = &channel->slots[1]->out; + channel->out[1] = &channel->chip->zeromod; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + case 0x01: + channel->slots[0]->mod = &channel->slots[0]->fbmod; + channel->slots[1]->mod = &channel->chip->zeromod; + channel->out[0] = &channel->slots[0]->out; + channel->out[1] = &channel->slots[1]->out; + channel->out[2] = &channel->chip->zeromod; + channel->out[3] = &channel->chip->zeromod; + break; + } + } +} + +static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) +{ + channel->fb = (data & 0x0e) >> 1; + channel->con = data & 0x01; + channel->alg = channel->con; + if (channel->chip->newm) + { + if (channel->chtype == ch_4op) + { + channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con); + channel->alg = 0x08; + OPL3_ChannelSetupAlg(channel->pair); + } + else if (channel->chtype == ch_4op2) + { + channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con); + channel->pair->alg = 0x08; + OPL3_ChannelSetupAlg(channel); + } + else + { + OPL3_ChannelSetupAlg(channel); + } + } + else + { + OPL3_ChannelSetupAlg(channel); + } + if (channel->chip->newm) + { + channel->cha = ((data >> 4) & 0x01) ? ~0 : 0; + channel->chb = ((data >> 5) & 0x01) ? ~0 : 0; + } + else + { + channel->cha = channel->chb = ~0; + } +} + +static void OPL3_ChannelKeyOn(opl3_channel *channel) +{ + if (channel->chip->newm) + { + if (channel->chtype == ch_4op) + { + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); + } + else if (channel->chtype == ch_2op || channel->chtype == ch_drum) + { + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + } + } + else + { + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + } +} + +static void OPL3_ChannelKeyOff(opl3_channel *channel) +{ + if (channel->chip->newm) + { + if (channel->chtype == ch_4op) + { + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); + } + else if (channel->chtype == ch_2op || channel->chtype == ch_drum) + { + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + } + } + else + { + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + } +} + +static void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) +{ + Bit8u bit; + Bit8u chnum; + for (bit = 0; bit < 6; bit++) + { + chnum = bit; + if (bit >= 3) + { + chnum += 9 - 3; + } + if ((data >> bit) & 0x01) + { + chip->channel[chnum].chtype = ch_4op; + chip->channel[chnum + 3].chtype = ch_4op2; + } + else + { + chip->channel[chnum].chtype = ch_2op; + chip->channel[chnum + 3].chtype = ch_2op; + } + } +} + +static Bit16s OPL3_ClipSample(Bit32s sample) +{ + if (sample > 32767) + { + sample = 32767; + } + else if (sample < -32768) + { + sample = -32768; + } + return (Bit16s)sample; +} + +static void OPL3_GenerateRhythm1(opl3_chip *chip) +{ + opl3_channel *channel6; + opl3_channel *channel7; + opl3_channel *channel8; + Bit16u phase14; + Bit16u phase17; + Bit16u phase; + Bit16u phasebit; + + channel6 = &chip->channel[6]; + channel7 = &chip->channel[7]; + channel8 = &chip->channel[8]; + OPL3_SlotGenerate(channel6->slots[0]); + phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + phase = 0x00; + //hh tc phase bit + phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) + | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //hh + phase = (phasebit << 9) + | (0x34 << ((phasebit ^ (chip->noise & 0x01)) << 1)); + OPL3_SlotGeneratePhase(channel7->slots[0], phase); + //tt + OPL3_SlotGenerateZM(channel8->slots[0]); +} + +static void OPL3_GenerateRhythm2(opl3_chip *chip) +{ + opl3_channel *channel6; + opl3_channel *channel7; + opl3_channel *channel8; + Bit16u phase14; + Bit16u phase17; + Bit16u phase; + Bit16u phasebit; + + channel6 = &chip->channel[6]; + channel7 = &chip->channel[7]; + channel8 = &chip->channel[8]; + OPL3_SlotGenerate(channel6->slots[1]); + phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + phase = 0x00; + //hh tc phase bit + phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) + | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //sd + phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); + OPL3_SlotGeneratePhase(channel7->slots[1], phase); + //tc + phase = 0x100 | (phasebit << 9); + OPL3_SlotGeneratePhase(channel8->slots[1], phase); +} + +void OPL3_Generate(opl3_chip *chip, Bit16s *buf) +{ + Bit8u ii; + Bit8u jj; + Bit16s accm; + + buf[1] = OPL3_ClipSample(chip->mixbuff[1]); + + for (ii = 0; ii < 12; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotGenerate(&chip->slot[ii]); + } + + for (ii = 12; ii < 15; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + } + + if (chip->rhy & 0x20) + { + OPL3_GenerateRhythm1(chip); + } + else + { + OPL3_SlotGenerate(&chip->slot[12]); + OPL3_SlotGenerate(&chip->slot[13]); + OPL3_SlotGenerate(&chip->slot[14]); + } + + chip->mixbuff[0] = 0; + for (ii = 0; ii < 18; ii++) + { + accm = 0; + for (jj = 0; jj < 4; jj++) + { + accm += *chip->channel[ii].out[jj]; + } + chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha); + } + + for (ii = 15; ii < 18; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + } + + if (chip->rhy & 0x20) + { + OPL3_GenerateRhythm2(chip); + } + else + { + OPL3_SlotGenerate(&chip->slot[15]); + OPL3_SlotGenerate(&chip->slot[16]); + OPL3_SlotGenerate(&chip->slot[17]); + } + + buf[0] = OPL3_ClipSample(chip->mixbuff[0]); + + for (ii = 18; ii < 33; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotGenerate(&chip->slot[ii]); + } + + chip->mixbuff[1] = 0; + for (ii = 0; ii < 18; ii++) + { + accm = 0; + for (jj = 0; jj < 4; jj++) + { + accm += *chip->channel[ii].out[jj]; + } + chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb); + } + + for (ii = 33; ii < 36; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotGenerate(&chip->slot[ii]); + } + + OPL3_NoiseGenerate(chip); + + if ((chip->timer & 0x3f) == 0x3f) + { + chip->tremolopos = (chip->tremolopos + 1) % 210; + } + if (chip->tremolopos < 105) + { + chip->tremolo = chip->tremolopos >> chip->tremoloshift; + } + else + { + chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift; + } + + if ((chip->timer & 0x3ff) == 0x3ff) + { + chip->vibpos = (chip->vibpos + 1) & 7; + } + + chip->timer++; +} + +void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf) +{ + while (chip->samplecnt >= chip->rateratio) + { + chip->oldsamples[0] = chip->samples[0]; + chip->oldsamples[1] = chip->samples[1]; + OPL3_Generate(chip, chip->samples); + chip->samplecnt -= chip->rateratio; + } + buf[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) + + chip->samples[0] * chip->samplecnt) / chip->rateratio); + buf[1] = (Bit16s)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) + + chip->samples[1] * chip->samplecnt) / chip->rateratio); + chip->samplecnt += 1 << RSM_FRAC; +} + +void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) +{ + Bit8u slotnum; + Bit8u channum; + + memset(chip, 0, sizeof(opl3_chip)); + for (slotnum = 0; slotnum < 36; slotnum++) + { + chip->slot[slotnum].chip = chip; + chip->slot[slotnum].mod = &chip->zeromod; + chip->slot[slotnum].eg_rout = 0x1ff; + chip->slot[slotnum].eg_out = 0x1ff; + chip->slot[slotnum].eg_gen = envelope_gen_num_off; + chip->slot[slotnum].trem = (Bit8u*)&chip->zeromod; + } + for (channum = 0; channum < 18; channum++) + { + chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]]; + chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3]; + chip->slot[ch_slot[channum]].channel = &chip->channel[channum]; + chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum]; + if ((channum % 9) < 3) + { + chip->channel[channum].pair = &chip->channel[channum + 3]; + } + else if ((channum % 9) < 6) + { + chip->channel[channum].pair = &chip->channel[channum - 3]; + } + chip->channel[channum].chip = chip; + chip->channel[channum].out[0] = &chip->zeromod; + chip->channel[channum].out[1] = &chip->zeromod; + chip->channel[channum].out[2] = &chip->zeromod; + chip->channel[channum].out[3] = &chip->zeromod; + chip->channel[channum].chtype = ch_2op; + chip->channel[channum].cha = ~0; + chip->channel[channum].chb = ~0; + OPL3_ChannelSetupAlg(&chip->channel[channum]); + } + chip->noise = 0x306600; + chip->rateratio = (samplerate << RSM_FRAC) / 49716; + chip->tremoloshift = 4; + chip->vibshift = 1; +} + +Bit32u OPL3_WriteAddr(opl3_chip *chip, Bit32u port, Bit8u val) +{ + Bit16u addr; + addr = val; + if ((port & 2) && (addr == 0x05 || chip->newm)) { + addr |= 0x100; + } + return addr; +} + +void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) +{ + Bit8u high = (reg >> 8) & 0x01; + Bit8u regm = reg & 0xff; + switch (regm & 0xf0) + { + case 0x00: + if (high) + { + switch (regm & 0x0f) + { + case 0x04: + OPL3_ChannelSet4Op(chip, v); + break; + case 0x05: + chip->newm = v & 0x01; + break; + } + } + else + { + switch (regm & 0x0f) + { + case 0x08: + chip->nts = (v >> 6) & 0x01; + break; + } + } + break; + case 0x20: + case 0x30: + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + } + break; + case 0x40: + case 0x50: + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + } + break; + case 0x60: + case 0x70: + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + } + break; + case 0x80: + case 0x90: + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + } + break; + case 0xe0: + case 0xf0: + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWriteE0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + } + break; + case 0xa0: + if ((regm & 0x0f) < 9) + { + OPL3_ChannelWriteA0(&chip->channel[9 * high + (regm & 0x0f)], v); + } + break; + case 0xb0: + if (regm == 0xbd && !high) + { + chip->tremoloshift = (((v >> 7) ^ 1) << 1) + 2; + chip->vibshift = ((v >> 6) & 0x01) ^ 1; + OPL3_ChannelUpdateRhythm(chip, v); + } + else if ((regm & 0x0f) < 9) + { + OPL3_ChannelWriteB0(&chip->channel[9 * high + (regm & 0x0f)], v); + if (v & 0x20) + { + OPL3_ChannelKeyOn(&chip->channel[9 * high + (regm & 0x0f)]); + } + else + { + OPL3_ChannelKeyOff(&chip->channel[9 * high + (regm & 0x0f)]); + } + } + break; + case 0xc0: + if ((regm & 0x0f) < 9) + { + OPL3_ChannelWriteC0(&chip->channel[9 * high + (regm & 0x0f)], v); + } + break; + } +} + +void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples) +{ + Bit32u i; + + for(i = 0; i < numsamples; i++) + { + OPL3_GenerateResampled(chip, sndptr); + sndptr += 2; + } +} diff --git a/src/dosbox/nukedopl.h b/src/dosbox/nukedopl.h new file mode 100644 index 0000000..ccebfc2 --- /dev/null +++ b/src/dosbox/nukedopl.h @@ -0,0 +1,103 @@ +// +// Nuked OPL3 emulator. +// Thanks: +// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): +// Feedback and Rhythm part calculation information. +// forums.submarine.org.uk(carbon14, opl3): +// Tremolo and phase generator calculation information. +// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): +// OPL2 ROMs. +// + +#ifndef NUKEDOPL_H +#define NUKEDOPL_H + +//#include "dosbox.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; + +struct opl3_chip; +struct opl3_slot; +struct opl3_channel; + +struct opl3_slot { + opl3_channel *channel; + opl3_chip *chip; + Bit16s out; + Bit16s fbmod; + Bit16s *mod; + Bit16s prout; + Bit16s eg_rout; + Bit16s eg_out; + Bit8u eg_inc; + Bit8u eg_gen; + Bit8u eg_rate; + Bit8u eg_ksl; + Bit8u *trem; + Bit8u reg_vib; + Bit8u reg_type; + Bit8u reg_ksr; + Bit8u reg_mult; + Bit8u reg_ksl; + Bit8u reg_tl; + Bit8u reg_ar; + Bit8u reg_dr; + Bit8u reg_sl; + Bit8u reg_rr; + Bit8u reg_wf; + Bit8u key; + Bit32u pg_phase; + Bit32u timer; +}; + +struct opl3_channel { + opl3_slot *slots[2]; + opl3_channel *pair; + opl3_chip *chip; + Bit16s *out[4]; + Bit8u chtype; + Bit16u f_num; + Bit8u block; + Bit8u fb; + Bit8u con; + Bit8u alg; + Bit8u ksv; + Bit16u cha, chb; +}; + +struct opl3_chip { + opl3_channel channel[18]; + opl3_slot slot[36]; + Bit16u timer; + Bit8u newm; + Bit8u nts; + Bit8u rhy; + Bit8u vibpos; + Bit8u vibshift; + Bit8u tremolo; + Bit8u tremolopos; + Bit8u tremoloshift; + Bit32u noise; + Bit16s zeromod; + Bit32s mixbuff[2]; + + Bit32s rateratio; + Bit32s samplecnt; + Bit16s oldsamples[2]; + Bit16s samples[2]; +}; + +//void OPL3_Generate(opl3_chip *chip, Bit16s *buf); +//void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf); +void OPL3_Reset(opl3_chip *chip, Bit32u samplerate); +Bit32u OPL3_WriteAddr(opl3_chip *chip, Bit32u port, Bit8u val); +void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v); +void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); +#endif From 8aa5c86386f695111fd5bb3bef7673693b59321c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 7 Jun 2017 17:56:32 +0100 Subject: [PATCH 0040/1050] DirectDraw code now falls back to backbuffer in system memory if it can't allocate backbuffer in video memory. --- src/win-ddraw-fs.cc | 9 ++++++++- src/win-ddraw.cc | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index bc581e3..aa929a0 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -72,7 +72,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"); + { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) + fatal("CreateSurface back failed\n"); + } pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 2cd0864..88b4756 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -59,7 +59,14 @@ 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"); + { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) + fatal("CreateSurface back failed\n"); + } memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -69,7 +76,14 @@ 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"); + { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) + fatal("CreateSurface back failed\n"); + } if (FAILED(lpdd4->CreateClipper(0, &lpdd_clipper, NULL))) fatal("CreateClipper failed\n"); From 9687b218d1378c7435541f8c782ab3c0f4ff36b7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 7 Jun 2017 17:59:21 +0100 Subject: [PATCH 0041/1050] Direct3D code now fatals out instead of crashing if D3D device can not be created. --- src/win-d3d-fs.cc | 3 ++- src/win-d3d.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index b0f2c0a..c611647 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -95,7 +95,8 @@ void d3d_fs_init(HWND h) d3dpp.BackBufferWidth = d3d_fs_w; d3dpp.BackBufferHeight = d3d_fs_h; - d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) + fatal("CreateDevice failed\n"); d3d_fs_init_objects(); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 763df0f..0abcc80 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -72,7 +72,8 @@ void d3d_init(HWND h) d3dpp.BackBufferWidth = 0; d3dpp.BackBufferHeight = 0; - d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) + fatal("CreateDevice failed\n"); d3d_init_objects(); From a31ab58d644d18420594645dc145ea900d6bad00 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 7 Jun 2017 18:03:21 +0100 Subject: [PATCH 0042/1050] More D3D error checking. Patch from ruben_balea --- src/win-d3d-fs.cc | 8 +++++--- src/win-d3d.cc | 10 ++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index c611647..dcd1d74 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -123,14 +123,16 @@ static void d3d_fs_init_objects() int y; RECT r; - d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), + if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_MANAGED, &v_buffer, - NULL); + NULL))) + fatal("CreateVertexBuffer failed\n"); - d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) + fatal("CreateTexture failed\n"); r.top = r.left = 0; r.bottom = r.right = 2047; diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 0abcc80..12402af 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -100,15 +100,17 @@ void d3d_init_objects() int y; RECT r; - d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), + if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_MANAGED, &v_buffer, - NULL); + NULL))) + fatal("CreateVertexBuffer failed\n"); - d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - + if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) + fatal("CreateTexture failed\n"); + r.top = r.left = 0; r.bottom = r.right = 2047; From 5788188ce9e01f422b93b70873011e333f665331 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 7 Jun 2017 19:10:16 +0100 Subject: [PATCH 0043/1050] Correct DBOPL OPL3 volume balancing. Correct OPL mixing on AWE32. --- 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 264c2b1..8b27138 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -114,8 +114,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) * (sb->opl_emu ? 47000 : 55000)) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 55000)) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 16); if (sb->mixer.filter) { @@ -168,8 +168,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) * (sb->opl_emu ? 47000 : 51000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 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); From 6e51e8975eda81432f64dfac0a5cf93c8bbe32a4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 10 Jun 2017 21:00:23 +0100 Subject: [PATCH 0044/1050] Sound buffer size now configurable. --- src/dac.c | 3 ++- src/ibm.h | 2 -- src/pc.c | 7 +++++++ src/pc.rc | 9 +++++++++ src/resources.h | 3 +++ src/sound.c | 31 ++++++++++++++++++++++--------- src/sound.h | 6 ++++++ src/sound_ad1848.h | 2 +- src/sound_adlibgold.c | 4 ++-- src/sound_cms.c | 2 +- src/sound_emu8k.h | 2 +- src/sound_gus.c | 2 +- src/sound_opl.h | 4 +++- src/sound_pas16.c | 2 +- src/sound_ps1.c | 2 +- src/sound_pssj.c | 2 +- src/sound_sb_dsp.h | 2 +- src/sound_sn76489.h | 4 +++- src/sound_speaker.c | 2 +- src/sound_ssi2001.c | 2 +- src/soundopenal.c | 3 +++ src/win.c | 22 ++++++++++++++++++++++ 22 files changed, 92 insertions(+), 26 deletions(-) diff --git a/src/dac.c b/src/dac.c index b24561b..b8f7052 100644 --- a/src/dac.c +++ b/src/dac.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "dac.h" +#include "sound.h" uint8_t dac,dac2; uint8_t dacctrl; @@ -43,7 +44,7 @@ void pollss() } } -int16_t dacbuffer[SOUNDBUFLEN+20]; +int16_t dacbuffer[MAXSOUNDBUFLEN+20]; int dacbufferpos=0; void getdacsamp() { diff --git a/src/ibm.h b/src/ibm.h index 20cabea..183d462 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -485,8 +485,6 @@ float VGACONST1,VGACONST2; float RTCCONST; int gated,speakval,speakon; -#define SOUNDBUFLEN (48000/20) - /*Sound Blaster*/ #define SADLIB 1 /*No DSP*/ diff --git a/src/pc.c b/src/pc.c index 474489b..df2c991 100644 --- a/src/pc.c +++ b/src/pc.c @@ -36,6 +36,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_speaker.h" @@ -430,6 +431,8 @@ void resetpchard() ioctl_reset(); } } + + sound_update_buf_length(); } 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"}; @@ -631,6 +634,8 @@ void loadconfig(char *fn) window_x = config_get_int(CFG_GLOBAL, NULL, "window_x", 0); window_y = config_get_int(CFG_GLOBAL, NULL, "window_y", 0); window_remember = config_get_int(CFG_GLOBAL, NULL, "window_remember", 0); + + sound_buf_len = config_get_int(CFG_GLOBAL, NULL, "sound_buf_len", 200); GAMEBLASTER = config_get_int(CFG_MACHINE, NULL, "gameblaster", 0); GUS = config_get_int(CFG_MACHINE, NULL, "gus", 0); @@ -781,6 +786,8 @@ void saveconfig(char *fn) config_set_int(CFG_GLOBAL, NULL, "window_x", window_x); config_set_int(CFG_GLOBAL, NULL, "window_y", window_y); config_set_int(CFG_GLOBAL, NULL, "window_remember", window_remember); + + config_set_int(CFG_GLOBAL, NULL, "sound_buf_len", sound_buf_len); config_set_int(CFG_MACHINE, NULL, "gameblaster", GAMEBLASTER); config_set_int(CFG_MACHINE, NULL, "gus", GUS); diff --git a/src/pc.rc b/src/pc.rc index 429788d..9a3f432 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -53,6 +53,15 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Disc activity indicator", IDM_VID_DISC END + POPUP "&Sound" + BEGIN + POPUP "&Buffer length" + BEGIN + MENUITEM "&100ms", IDM_BUF_100MS + MENUITEM "&200ms", IDM_BUF_200MS + MENUITEM "&400ms", IDM_BUF_400MS + END + END END POPUP "&Misc" BEGIN diff --git a/src/resources.h b/src/resources.h index af0bac4..9e1b226 100644 --- a/src/resources.h +++ b/src/resources.h @@ -21,6 +21,9 @@ #define IDM_VID_FS_43 40072 #define IDM_VID_FS_SQ 40073 #define IDM_VID_FS_INT 40074 +#define IDM_BUF_100MS 40080 +#define IDM_BUF_200MS 40081 +#define IDM_BUF_400MS 40082 #define IDM_CDROM_EMPTY 40100 #define IDM_CDROM_REAL 40100 #define IDM_CDROM_DISABLED 40200 diff --git a/src/sound.c b/src/sound.c index 26a93a2..d8a351b 100644 --- a/src/sound.c +++ b/src/sound.c @@ -120,7 +120,18 @@ static int16_t cd_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; + +int sound_buf_len = 48000 / 10; + +void sound_update_buf_length() +{ + int new_buf_len = (48000 / (1000 / sound_buf_len)) / 4; + + if (new_buf_len > MAXSOUNDBUFLEN) + new_buf_len = MAXSOUNDBUFLEN; + + SOUNDBUFLEN = new_buf_len; +} void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) { @@ -194,7 +205,7 @@ void sound_init() initalmain(0,NULL); inital(); - outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int32_t)); + outbuffer = malloc(MAXSOUNDBUFLEN * 2 * sizeof(int32_t)); sound_cd_event = thread_create_event(); sound_cd_thread_h = thread_create(sound_cd_thread, NULL); @@ -207,9 +218,17 @@ void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), vo sound_handlers_num++; } +static int cd_pos = 0; void sound_poll(void *priv) { sound_poll_time += sound_poll_latch; + + cd_pos++; + if (cd_pos == (CD_BUFLEN * 48000) / CD_FREQ) + { + cd_pos = 0; + thread_set_event(sound_cd_event); + } sound_pos_global++; if (sound_pos_global == SOUNDBUFLEN) @@ -238,14 +257,8 @@ void sound_poll(void *priv) if (soundon) givealbuffer(outbuffer); - 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; + sound_update_buf_length(); } } diff --git a/src/sound.h b/src/sound.h index f5c59a3..4bf0395 100644 --- a/src/sound.h +++ b/src/sound.h @@ -27,3 +27,9 @@ void inital(); void givealbuffer(int32_t *buf); void givealbuffer_cd(int16_t *buf); + +extern int sound_buf_len; +void sound_update_buf_length(); + +extern int SOUNDBUFLEN; +#define MAXSOUNDBUFLEN (48000 / 10) diff --git a/src/sound_ad1848.h b/src/sound_ad1848.h index 5cba0f1..34b707a 100644 --- a/src/sound_ad1848.h +++ b/src/sound_ad1848.h @@ -21,7 +21,7 @@ typedef struct ad1848_t int timer_count, timer_latch; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; } ad1848_t; diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index bc5b445..1f62dc4 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -55,8 +55,8 @@ typedef struct adgold_t int vol_l, vol_r; int treble, bass; - int16_t opl_buffer[SOUNDBUFLEN * 2]; - int16_t mma_buffer[2][SOUNDBUFLEN]; + int16_t opl_buffer[MAXSOUNDBUFLEN * 2]; + int16_t mma_buffer[2][MAXSOUNDBUFLEN]; int pos; diff --git a/src/sound_cms.c b/src/sound_cms.c index 7c4a33f..6361dd9 100644 --- a/src/sound_cms.c +++ b/src/sound_cms.c @@ -23,7 +23,7 @@ typedef struct cms_t int noisecount[2][2]; int noisetype[2][2]; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; } cms_t; diff --git a/src/sound_emu8k.h b/src/sound_emu8k.h index ac091de..f54576a 100644 --- a/src/sound_emu8k.h +++ b/src/sound_emu8k.h @@ -81,7 +81,7 @@ typedef struct emu8k_t int16_t out_l, out_r; int pos; - int32_t buffer[SOUNDBUFLEN * 2]; + int32_t buffer[MAXSOUNDBUFLEN * 2]; } emu8k_t; void emu8k_init(emu8k_t *emu8k, int onboard_ram); diff --git a/src/sound_gus.c b/src/sound_gus.c index c6322ba..bc45155 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -39,7 +39,7 @@ typedef struct gus_t int32_t out_l, out_r; - int16_t buffer[2][SOUNDBUFLEN]; + int16_t buffer[2][MAXSOUNDBUFLEN]; int pos; int samp_timer, samp_latch; diff --git a/src/sound_opl.h b/src/sound_opl.h index 8d67bb9..0728d67 100644 --- a/src/sound_opl.h +++ b/src/sound_opl.h @@ -1,3 +1,5 @@ +#include "sound.h" + typedef struct opl_t { int chip_nr[2]; @@ -7,7 +9,7 @@ typedef struct opl_t int16_t filtbuf[2]; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; } opl_t; diff --git a/src/sound_pas16.c b/src/sound_pas16.c index bbb2fbc..c736611 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -132,7 +132,7 @@ typedef struct pas16_t opl_t opl; sb_dsp_t dsp; - int16_t pcm_buffer[2][SOUNDBUFLEN]; + int16_t pcm_buffer[2][MAXSOUNDBUFLEN]; int pos; } pas16_t; diff --git a/src/sound_ps1.c b/src/sound_ps1.c index a7de420..fb8a9a5 100644 --- a/src/sound_ps1.c +++ b/src/sound_ps1.c @@ -21,7 +21,7 @@ typedef struct ps1_audio_t uint8_t dac_val; - int16_t buffer[SOUNDBUFLEN]; + int16_t buffer[MAXSOUNDBUFLEN]; int pos; } ps1_audio_t; diff --git a/src/sound_pssj.c b/src/sound_pssj.c index 3ffaaae..d692f33 100644 --- a/src/sound_pssj.c +++ b/src/sound_pssj.c @@ -27,7 +27,7 @@ typedef struct pssj_t int wave_pos; int pulse_width; - int16_t buffer[SOUNDBUFLEN]; + int16_t buffer[MAXSOUNDBUFLEN]; int pos; } pssj_t; diff --git a/src/sound_sb_dsp.h b/src/sound_sb_dsp.h index 81b4641..e945b40 100644 --- a/src/sound_sb_dsp.h +++ b/src/sound_sb_dsp.h @@ -57,7 +57,7 @@ typedef struct sb_dsp_t int wb_time, wb_full; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; } sb_dsp_t; diff --git a/src/sound_sn76489.h b/src/sound_sn76489.h index 2f7a687..d5acb62 100644 --- a/src/sound_sn76489.h +++ b/src/sound_sn76489.h @@ -1,3 +1,5 @@ +#include "sound.h" + enum { SN76496, @@ -23,7 +25,7 @@ typedef struct sn76489_t int type; int extra_divide; - int16_t buffer[SOUNDBUFLEN]; + int16_t buffer[MAXSOUNDBUFLEN]; int pos; double psgconst; diff --git a/src/sound_speaker.c b/src/sound_speaker.c index a6c386d..d70651c 100644 --- a/src/sound_speaker.c +++ b/src/sound_speaker.c @@ -4,7 +4,7 @@ int speaker_mute = 0; -static int16_t speaker_buffer[SOUNDBUFLEN]; +static int16_t speaker_buffer[MAXSOUNDBUFLEN]; static int speaker_pos = 0; diff --git a/src/sound_ssi2001.c b/src/sound_ssi2001.c index ff83041..2efc15c 100644 --- a/src/sound_ssi2001.c +++ b/src/sound_ssi2001.c @@ -10,7 +10,7 @@ typedef struct ssi2001_t { void *psid; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; } ssi2001_t; diff --git a/src/soundopenal.c b/src/soundopenal.c index 639bbcc..5dd088f 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -16,6 +16,9 @@ ALuint buffers_cd[4]; // front and back buffers static ALuint source[2]; // audio source #endif #define FREQ 48000 + +int SOUNDBUFLEN = 48000/20; + #define BUFLEN SOUNDBUFLEN void closeal(); diff --git a/src/win.c b/src/win.c index c9d2093..9769261 100644 --- a/src/win.c +++ b/src/win.c @@ -646,6 +646,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_BPB_DISABLE, bpb_disable ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_DISC, vid_disc_indicator ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_BUF_100MS, (sound_buf_len == 100) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_BUF_200MS, (sound_buf_len == 200) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_BUF_400MS, (sound_buf_len == 400) ? MF_CHECKED : MF_UNCHECKED); if (!loadbios()) { @@ -1051,6 +1054,25 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM saveconfig(NULL); break; + case IDM_BUF_100MS: case IDM_BUF_200MS: case IDM_BUF_400MS: + switch (LOWORD(wParam)) + { + case IDM_BUF_100MS: + sound_buf_len = 100; + break; + case IDM_BUF_200MS: + sound_buf_len = 200; + break; + case IDM_BUF_400MS: + sound_buf_len = 400; + break; + } + CheckMenuItem(hmenu, IDM_BUF_100MS, (sound_buf_len == 100) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_BUF_200MS, (sound_buf_len == 200) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_BUF_400MS, (sound_buf_len == 400) ? MF_CHECKED : MF_UNCHECKED); + saveconfig(NULL); + break; + case IDM_CDROM_DISABLED: if (cdrom_enabled) { From 6692f708adab576b646d890942fb42dfe4ea3e8b Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Jun 2017 18:16:02 +0100 Subject: [PATCH 0045/1050] Increased PS/2 ESDI sector buffer size. --- src/hdd_esdi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 56c49c3..2aaa644 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -56,7 +56,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; @@ -650,7 +650,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; @@ -714,7 +714,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; From 03a63ecb88fa04929cd45b58c1e4faaf11a838e1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Jun 2017 20:34:45 +0100 Subject: [PATCH 0046/1050] Fixed typo in x86-64 MEM_CHECK_WRITE_W()/L() functions - Windows XP boots on x86-64 recompiler again. --- src/codegen_ops_x86-64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index e0cb874..c0fa7c5 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -5509,7 +5509,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) { addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ addbyte(0x3c); - addbyte(0xfd); + addbyte(0xf5); addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } @@ -5658,7 +5658,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) { addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ addbyte(0x3c); - addbyte(0xfd); + addbyte(0xf5); addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } From 3a7c4687d6aeb1ae49fa4bfbf745ca3af511e00f Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Jun 2017 21:05:10 +0100 Subject: [PATCH 0047/1050] Reduce self modifying code granularity from 64 bytes to 16. --- src/386_dynarec.c | 22 ++++++++-------- src/codegen.h | 5 +++- src/codegen_x86-64.c | 63 ++++++++++++++++++++++++-------------------- src/codegen_x86.c | 61 +++++++++++++++++++++++------------------- src/mem.c | 18 ++++++------- src/mem.h | 4 +-- 6 files changed, 95 insertions(+), 78 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 79c054e..6ce33ba 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1440,7 +1440,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); @@ -1453,10 +1453,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; } @@ -1469,15 +1470,14 @@ 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; } @@ -1562,7 +1562,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) @@ -1638,7 +1638,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/codegen.h b/src/codegen.h index cbac2b6..a88f39d 100644 --- a/src/codegen.h +++ b/src/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/codegen_x86-64.c b/src/codegen_x86-64.c index 5a35102..91de59f 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -99,7 +99,7 @@ void codegen_reset() void dump_block() { - codeblock_t *block = pages[0x119000 >> 12].block; +/* codeblock_t *block = pages[0x119000 >> 12].block; pclog("dump_block:\n"); while (block) @@ -112,12 +112,12 @@ void dump_block() block = block->next; } - pclog("dump_block done\n"); + 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 +126,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 +142,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 +171,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 @@ -193,7 +193,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 +218,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 +232,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) { @@ -252,7 +252,7 @@ void codegen_block_init(uint32_t phys_addr) codeblock_t *block; 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; @@ -274,6 +274,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; @@ -291,7 +293,7 @@ void codegen_block_start_recompile(codeblock_t *block) { 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); @@ -402,17 +404,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; @@ -423,26 +427,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); - - 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) @@ -451,6 +456,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/codegen_x86.c b/src/codegen_x86.c index 9739da8..0474703 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -1212,7 +1212,7 @@ void codegen_reset() void dump_block() { - codeblock_t *block = pages[0x119000 >> 12].block; +/* codeblock_t *block = pages[0x119000 >> 12].block; pclog("dump_block:\n"); while (block) @@ -1225,12 +1225,12 @@ void dump_block() block = block->next; } - pclog("dump_block done\n"); + 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"); @@ -1239,12 +1239,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) @@ -1255,18 +1255,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; } } } @@ -1284,7 +1284,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 @@ -1306,7 +1306,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 @@ -1331,7 +1331,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) { @@ -1345,7 +1345,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) { @@ -1365,7 +1365,7 @@ void codegen_block_init(uint32_t phys_addr) codeblock_t *block; 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; @@ -1387,6 +1387,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; @@ -1404,7 +1406,7 @@ void codegen_block_start_recompile(codeblock_t *block) { 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); @@ -1489,17 +1491,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; @@ -1510,26 +1514,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) @@ -1538,6 +1543,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/mem.c b/src/mem.c index 8ce0d7c..2e4d4e0 100644 --- a/src/mem.c +++ b/src/mem.c @@ -988,7 +988,7 @@ void addwritelookup(uint32_t virt, uint32_t phys) // if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff)) // fatal("Bad write mapping\n"); - 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];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; @@ -1516,7 +1516,7 @@ void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { 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->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; p->mem[addr & 0xfff] = val; } } @@ -1525,10 +1525,10 @@ 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); // pclog("mem_write_ramw_page: %08x %04x %08x\n", addr, val, cs+pc); - p->dirty_mask |= mask; + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; *(uint16_t *)&p->mem[addr & 0xfff] = val; } } @@ -1537,10 +1537,10 @@ 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); // pclog("mem_write_raml_page: %08x %08x %08x\n", addr, val, cs+pc); - p->dirty_mask |= mask; + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; *(uint32_t *)&p->mem[addr & 0xfff] = val; } } @@ -1615,7 +1615,7 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) { 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; } } @@ -2027,8 +2027,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 370be13..b8c923c 100644 --- a/src/mem.h +++ b/src/mem.h @@ -112,12 +112,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 182d22cb9541c3d4aa4257b0ff46f78f1fe83524 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Jun 2017 21:33:18 +0100 Subject: [PATCH 0048/1050] Fix unused variable in vid_voodoo.c. --- src/vid_voodoo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 0790068..3bb8ccb 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -7142,7 +7142,9 @@ void *voodoo_init() void voodoo_close(void *p) { +#ifndef RELEASE_BUILD FILE *f; +#endif voodoo_t *voodoo = (voodoo_t *)p; int c; From dac7f3406c6d53f13e6d42f746b52b0ab43aa880 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Jun 2017 18:26:54 +0100 Subject: [PATCH 0049/1050] Pentium timing improvements - decoder & pairing limitations on instructions with immediate & displacement, 7 byte limitation on Pentium MMX decoding. --- src/codegen_timing_pentium.c | 186 +++++++++++++++++++++++++++++------ 1 file changed, 155 insertions(+), 31 deletions(-) diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index 0fbf5e6..05b0f91 100644 --- a/src/codegen_timing_pentium.c +++ b/src/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; @@ -857,10 +948,12 @@ void codegen_timing_pentium_start() { // decode_delay = 0; 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'*/ @@ -943,12 +1036,18 @@ 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; // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); break; + case 0x81: + timings = mod3 ? opcode_timings_mod3 : opcode_timings_81; + 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; @@ -996,24 +1095,39 @@ 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); // 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; + 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*/ @@ -1026,13 +1140,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*/ From d5335ccb27e71085109ee5133bdc84414ff641cf Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Jun 2017 20:45:13 +0100 Subject: [PATCH 0050/1050] Fixed typos breaking 16-bit DMA. --- src/dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dma.c b/src/dma.c index eb32dbc..7c82747 100644 --- a/src/dma.c +++ b/src/dma.c @@ -666,11 +666,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 69f0f7b01ce3679c6c9a97e33c6edb774a97c705 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Jun 2017 20:46:11 +0100 Subject: [PATCH 0051/1050] Implemented 16-bit DMA support for GUS. --- src/sound_gus.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/sound_gus.c b/src/sound_gus.c index bc45155..08b3e5d 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -380,13 +380,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; @@ -403,10 +417,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; From 59b5cf50dd070d6743c0c3694f715623cb88d1fb Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Jun 2017 08:03:35 +0100 Subject: [PATCH 0052/1050] Buffer IDE multiple-sector read commands. --- src/ide.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/ide.c b/src/ide.c index 7b9ad40..9c7b150 100644 --- a/src/ide.c +++ b/src/ide.c @@ -261,6 +261,9 @@ typedef struct IDE uint32_t lba_addr; int skip512; int blocksize, blockcount; + uint8_t sector_buffer[256*512]; + int do_initial_read; + int sector_pos; } IDE; IDE ide_drives[4]; @@ -978,6 +981,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) timer_process(); idecallback[ide_board]=200*IDE_TIME; timer_update_outstanding(); + ide->do_initial_read = 1; return; case WIN_WRITE_MULTIPLE: @@ -1365,14 +1369,24 @@ void callbackide(int ide_board) ide_set_signature(ide); goto abort_cmd; } - addr = ide_get_sector(ide) * 512; + if (ide->do_initial_read) + { + ide->do_initial_read = 0; + ide->sector_pos = 0; + addr = ide_get_sector(ide) * 512; + fseeko64(ide->hdfile, addr, SEEK_SET); + if (ide->secount) + fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); + else + fread(ide->sector_buffer, 256*512, 1, ide->hdfile); + } + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); + ide->sector_pos++; // pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); /* if (ide.cylinder || ide.head) { fatal("Read from other cylinder/head"); }*/ - fseeko64(ide->hdfile, addr, SEEK_SET); - fread(ide->buffer, 512, 1, ide->hdfile); ide->pos=0; ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; // 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]); @@ -1387,18 +1401,27 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, addr, SEEK_SET); - fread(ide->buffer, 512, 1, ide->hdfile); + if (ide->do_initial_read) + { + ide->do_initial_read = 0; + ide->sector_pos = 0; + addr = ide_get_sector(ide) * 512; + fseeko64(ide->hdfile, addr, SEEK_SET); + if (ide->secount) + fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); + else + fread(ide->sector_buffer, 256*512, 1, ide->hdfile); + } ide->pos=0; if (ide_bus_master_read_sector) { - if (ide_bus_master_read_sector(ide_board, (uint8_t *)ide->buffer)) - idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ + if (ide_bus_master_read_sector(ide_board, &ide->sector_buffer[ide->sector_pos*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; @@ -1423,10 +1446,19 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } - addr = ide_get_sector(ide) * 512; -// pclog("Read multiple from %08X %i (%i) %i\n", addr, ide->blockcount, ide->blocksize, ide->secount); - fseeko64(ide->hdfile, addr, SEEK_SET); - fread(ide->buffer, 512, 1, ide->hdfile); + if (ide->do_initial_read) + { + ide->do_initial_read = 0; + ide->sector_pos = 0; + addr = ide_get_sector(ide) * 512; + fseeko64(ide->hdfile, addr, SEEK_SET); + if (ide->secount) + fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); + else + fread(ide->sector_buffer, 256*512, 1, ide->hdfile); + } + 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)// || ide->secount == 1) From fb4e1f071582da4f2d31a6c1858e58b93e6b5837 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 18 Jun 2017 15:48:20 +0100 Subject: [PATCH 0053/1050] Implemented Pentium FPU latencies. --- src/codegen_timing_pentium.c | 543 +++++++++++++++++++++++------------ 1 file changed, 367 insertions(+), 176 deletions(-) diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index 05b0f91..fbac3b8 100644 --- a/src/codegen_timing_pentium.c +++ b/src/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,76 +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) /*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_HASIMM (3ull << 2) +#define CYCLES_IMM8 (1ull << 2) +#define CYCLES_IMM1632 (2ull << 2) -#define CYCLES_MASK ((1 << 7) - 1) +#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_FPU (4 << 29) +#define PAIR_FPU (4ull << 29) -#define PAIR_MASK (7 << 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) @@ -162,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, @@ -298,7 +350,7 @@ 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, @@ -435,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, @@ -517,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, @@ -600,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), @@ -654,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, @@ -743,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, @@ -758,82 +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_81[8] = +static uint64_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] = +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) @@ -860,11 +915,43 @@ 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) @@ -891,7 +978,7 @@ static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32) /*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) +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) @@ -941,7 +1028,7 @@ static inline int codegen_timing_instr_length(uint32_t timing, uint32_t fetchdat 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() @@ -954,6 +1041,11 @@ void codegen_timing_pentium_start() 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'*/ @@ -963,7 +1055,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; } @@ -975,13 +1067,100 @@ 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 + { +/* if (timings[opcode] & FPU_WRITE_ST0) + fatal("FPU_WRITE_ST0\n"); + if (timings[opcode] & FPU_WRITE_ST1) + fatal("FPU_WRITE_ST1\n"); + if (timings[opcode] & FPU_WRITE_STREG) + fatal("FPU_WRITE_STREG\n");*/ + 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)) + { + /* if (fpu_latency) + fatal("Bad latency FPU\n");*/ + 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) + { +/* if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (timings[opcode] & FPU_WRITE_ST1) + { +/* if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ + 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))) + { +/* if (fpu_st_latency[reg]) + fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ + 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); @@ -1078,9 +1257,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); @@ -1092,8 +1268,24 @@ 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 ((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) + if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) <= 0) { int has_displacement; @@ -1107,6 +1299,7 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) 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; @@ -1119,26 +1312,23 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) 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); - -// 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; - + /*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; -// 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) + if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) { int has_displacement; @@ -1155,14 +1345,15 @@ nopair: 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; -// 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); + codegen_instruction(timings, opcode, fetchdat, decode_delay_offset, op_32); + decode_delay_offset = 0; } void codegen_timing_pentium_block_end() @@ -1170,7 +1361,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; } } From 7234e2c3beb27f24fdda0e9b46e12f8c22e73a2e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 18 Jun 2017 20:15:46 +0100 Subject: [PATCH 0054/1050] Several 286/386SX models can now have less than 1MB of RAM. Memory remapping code restructured. Patch from Greatpsycho. --- src/allegro-gui-configure.c | 10 ++-- src/mem.c | 114 +++++++++++++++++++++++------------- src/model.c | 20 ++++--- src/pc.c | 4 +- src/win-config.c | 8 +-- src/wx-config.c | 8 +-- 6 files changed, 100 insertions(+), 64 deletions(-) diff --git a/src/allegro-gui-configure.c b/src/allegro-gui-configure.c index 0c2e321..349ed91 100644 --- a/src/allegro-gui-configure.c +++ b/src/allegro-gui-configure.c @@ -290,7 +290,7 @@ static DIALOG configure_dialog[] = {d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0}, //7 {list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //8 - {d_edit_proc, 70*2, 276, 40, 14, 0, 0xffffff, 0, 0, 4, 0, mem_size_str, 0, 0}, + {d_edit_proc, 70*2, 276, 48, 14, 0, 0xffffff, 0, 0, 5, 0, mem_size_str, 0, 0}, {d_text_proc, 98*2, 276, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, @@ -472,7 +472,7 @@ static int list_proc(int msg, DIALOG *d, int c) new_mem_size = models[new_model].max_ram; sprintf(mem_size_str, "%i", new_mem_size); - if (models[new_model].flags & MODEL_AT) + if ((models[new_model].flags & MODEL_AT) && models[new_model].ram_granularity < 128) sprintf(mem_size_units, "MB"); else sprintf(mem_size_units, "kB"); @@ -714,12 +714,12 @@ pclog("video_card_available : %i\n", c); else configure_dialog[14].flags &= ~D_SELECTED; - if (models[model].flags & MODEL_AT) + if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) sprintf(mem_size_str, "%i", mem_size / 1024); else sprintf(mem_size_str, "%i", mem_size); - if (models[model].flags & MODEL_AT) + if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) sprintf(mem_size_units, "MB"); else sprintf(mem_size_units, "kB"); @@ -770,7 +770,7 @@ pclog("video_card_available : %i\n", c); 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].flags & MODEL_AT) + if ((models[new_model].flags & MODEL_AT) && models[new_model].ram_granularity < 128) new_mem_size *= 1024; if (new_model != model || new_gfxcard != gfxcard || new_mem_size != mem_size || diff --git a/src/mem.c b/src/mem.c index 2e4d4e0..e1ae279 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1561,6 +1561,50 @@ 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?*/ @@ -1858,7 +1902,7 @@ void mem_init() { int c; - ram = malloc((mem_size + 384) * 1024); + ram = malloc(mem_size * 1024); // rom = malloc(0x20000); readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); @@ -1866,12 +1910,12 @@ void mem_init() 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 *)); - for (c = 0; c < ((mem_size * 1024) >> 12); c++) + for (c = 0; c < (((mem_size + 384) * 1024) >> 12); c++) { pages[c].mem = &ram[c << 12]; pages[c].write_b = mem_write_ramb_page; @@ -1880,7 +1924,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) @@ -1916,49 +1960,39 @@ void mem_init() // pclog("Mem resize %i %i\n",mem_size,c); } -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++) + if (mem_size > 640) { - 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; - } + 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; + } - 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(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); } +} - 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_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() @@ -1966,8 +2000,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)); @@ -1981,7 +2015,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) diff --git a/src/model.c b/src/model.c index f1ecff9..ae7259c 100644 --- a/src/model.c +++ b/src/model.c @@ -93,7 +93,7 @@ int AMSTRAD, AT, PCI, TANDY; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, xt_init, NULL}, {"IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 64, pcjr_init, &pcjr_device}, {"Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, @@ -113,22 +113,22 @@ MODEL models[] = {"Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, ibm_at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", 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}}, 0, MODEL_AT, 1, 16, 1, dells200_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, + {"DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|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}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, {"Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, 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_init, NULL},*/ {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, @@ -319,6 +319,7 @@ void at_ide_init() { at_init(); ide_init(); + mem_remap_top_384k(); } void deskpro386_init() @@ -354,6 +355,7 @@ void ps1_m2011_init() { ps1_common_init(); ps1mb_init(); + mem_remap_top_384k(); } void ps1_m2121_init() diff --git a/src/pc.c b/src/pc.c index df2c991..0e900ed 100644 --- a/src/pc.c +++ b/src/pc.c @@ -684,8 +684,8 @@ void loadconfig(char *fn) strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); mem_size = config_get_int(CFG_MACHINE, 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 < (((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); cdrom_drive = config_get_int(CFG_MACHINE, NULL, "cdrom_drive", 0); cdrom_enabled = config_get_int(CFG_MACHINE, NULL, "cdrom_enabled", 0); diff --git a/src/win-config.c b/src/win-config.c index 0a4032f..c22850e 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -285,7 +285,7 @@ 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) + if (!((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128)) SendMessage(h, UDM_SETPOS, 0, mem_size); else SendMessage(h, UDM_SETPOS, 0, mem_size / 1024); @@ -333,7 +333,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, CB_SETCURSEL, fdd_get_type(1), 0); h = GetDlgItem(hdlg, IDC_TEXT_MB); - if (models[model].flags & MODEL_AT) + if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"MB"); else SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"KB"); @@ -417,7 +417,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR 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) + if ((models[temp_model].flags & MODEL_AT) && models[temp_model].ram_granularity < 128) mem *= 1024; h = GetDlgItem(hdlg, IDC_COMBOVID); @@ -582,7 +582,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR 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) + if ((models[temp_model].flags & MODEL_AT) && models[temp_model].ram_granularity < 128) SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"MB"); else SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"KB"); diff --git a/src/wx-config.c b/src/wx-config.c index 2a5658d..46095c8 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -298,7 +298,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) (models[romstomodel[romset]].min_ram << 16) | models[romstomodel[romset]].max_ram); wx_sendmessage(h, WX_UDM_SETINCR, 0, models[model].ram_granularity); - if (!(models[model].flags & MODEL_AT)) + if (!((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128)) wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size); else wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size / 1024); @@ -343,7 +343,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(1), 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); - if (models[model].flags & MODEL_AT) + if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128)) wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); else wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); @@ -429,7 +429,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) 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) + if ((models[temp_model].flags & MODEL_AT) && models[temp_model].ram_granularity < 128) mem *= 1024; h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); @@ -609,7 +609,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); - if (models[temp_model].flags & MODEL_AT) + if ((models[temp_model].flags & MODEL_AT) && models[temp_model].ram_granularity < 128) wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); else wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); From bfef4889a7ea683b12b36bb7cdb6d0a69ab9ed38 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Sun, 18 Jun 2017 20:49:52 +0100 Subject: [PATCH 0055/1050] Fix build error with wxWidgets GUI introducted in rev 772. --- src/wx-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wx-config.c b/src/wx-config.c index 46095c8..44368dc 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -343,7 +343,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(1), 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); - if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128)) + if ((models[model].flags & MODEL_AT) && (models[model].ram_granularity < 128)) wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); else wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); From 03f7302cf8a1fb37026b4f3ffd0443cc91278b0d Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Sun, 18 Jun 2017 20:50:20 +0100 Subject: [PATCH 0056/1050] Clean up duplicate definitions in cdrom-image.cc. Patch from bit. --- src/cdrom-image.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 3ce4d46..23e3fcb 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -4,20 +4,10 @@ extern "C" { -//#include "ibm.h" +#include "ibm.h" #include "ide.h" - -int cdrom_drive; -int old_cdrom_drive; -void pclog(const char *format, ...); } -#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 - char image_path[1024]; static int image_changed = 0; From e61d25eeddc37557f9c07b392e494ce414bb633e Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Sun, 18 Jun 2017 20:51:07 +0100 Subject: [PATCH 0057/1050] Fixed --config parameter with wxWidgets GUI. Patch from bit. --- src/wx-app.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wx-app.cc b/src/wx-app.cc index 003ab39..b8c1179 100644 --- a/src/wx-app.cc +++ b/src/wx-app.cc @@ -19,6 +19,8 @@ extern "C" int stop_emulation(); } +extern int config_override; + extern void InitXmlResource(); wxDEFINE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); @@ -126,7 +128,10 @@ void Frame::OnStopEmulationEvent(wxCommandEvent& event) if (ret == wxID_OK) { stop_emulation(); - ShowConfigSelection(); + if (!config_override) + ShowConfigSelection(); + else + Quit(1); } else resume_emulation(); From 0928b4fbdfbce657e8a04eb428aa70867b4d75ab Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Sun, 18 Jun 2017 21:03:22 +0100 Subject: [PATCH 0058/1050] Sound buffer length now configurable in wxWidgets GUI. Patch from bit. --- src/pc.xrc | 23 + src/wx-resources.cpp | 3657 +++++++++++++++++++++--------------------- src/wx-sdl2.c | 11 + 3 files changed, 1879 insertions(+), 1812 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index b1a2d19..ebdb59f 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -28,6 +28,7 @@ + @@ -229,6 +230,28 @@ 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 645bb0a..c48e954 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -274,7 +274,7 @@ static unsigned char xml_res_file_6[] = { 37,149,61,177,48,254,5,68,165,141,10,108,236,250,76,0,0,0,0,73,69,78,68, 174,66,96,130}; -static size_t xml_res_size_7 = 59686; +static size_t xml_res_size_7 = 60429; static unsigned char xml_res_file_7[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -341,32 +341,34 @@ static unsigned char xml_res_file_7[] = { 97,114,116,61,34,49,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97, 110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68, 69,82,95,68,82,73,86,69,82,34,32,115,116,97,114,116,61,34,49,52,48,48,34, -47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, -117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, -118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, -101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, -67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, -84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, -98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,77,95,83,78,68,95,66,85,70,34,32,115,116,97,114,116,61,34,50,48, +48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116, +97,116,117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97, +99,116,105,118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +77,65,67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97, +116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95, +83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, 83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, 60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, @@ -659,222 +661,81 @@ static unsigned char xml_res_file_7[] = { 60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98, 108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -77,97,99,104,105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76, -69,95,69,88,73,84,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -83,116,111,112,32,101,109,117,108,97,116,105,111,110,60,47,108,97,98,101, -108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111, -110,102,105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,116,105, -116,108,101,62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47, -116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, -62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47, -114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, -112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,33,45,45,32,109,97,99,104,105,110,101,32,45,45,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, -79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32, -45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,111,117,110,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,66,117,102,102,101,114,32,108,101,110,103,116,104,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,53,48,32,109,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,49,48,48, +32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85, +70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,50,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111, -32,115,112,101,101,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,86,105,100,101,111,32,115,112,101,101,100,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, -101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,112,117, -32,116,121,112,101,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85, -32,116,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, -79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, -78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,33,45,45,32,99,112,117,32,116,121,112,101,32, -45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,100,121, -110,97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,32,45,45,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, -101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67, -75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99,32,82,101,99, -111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, +78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,84,65,84,85, +83,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105, +110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,69,88, +73,84,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,116,111, +112,32,101,109,117,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102, +105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108, +101,62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, +47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,33,45,45,32,109,97,99,104,105,110,101,32,45,45,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,119,97,105, -116,115,116,97,116,101,115,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108,62,10, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, @@ -884,87 +745,72 @@ static unsigned char xml_res_file_7[] = { 98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, -79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,115,111,117,110, -100,32,99,97,114,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76, +61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, 60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111, -117,110,100,32,99,97,114,100,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, -78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102, +105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32,45,45,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,105,100,101,111,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, -45,45,32,72,68,68,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -33,45,45,32,70,68,68,49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,70,68,68,49,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79, +78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32,115,112,101, +101,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,32,115, +112,101,101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, @@ -974,40 +820,14 @@ static unsigned char xml_res_file_7[] = { 48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, 111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32, 124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,33,45,45,32,70,68,68,50,32,45,45,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, -70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, -78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,33,45,45,32,109,101,109,111,114,121,32,45,45, +32,32,32,32,32,32,60,33,45,45,32,99,112,117,32,116,121,112,101,32,45,45, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, @@ -1016,55 +836,69 @@ static unsigned char xml_res_file_7[] = { 48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, 116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,32,116,121,112,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, 101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, 103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, -101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +33,45,45,32,99,112,117,32,116,121,112,101,32,45,45,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110, -67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73, -78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,83,80,95,72,79,82,73,90,79,78,84,65,76, -124,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,97,108,117,101,62,53,48,60,47,118,97,108,117,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,48, -60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,97,120,62,50,48,48,60,47,109,97,120,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, -77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,109,111,117,115,101,32, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, +79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124, +32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,33,45,45,32,100,121,110,97,109,105,99,32,114,101,99,111, +109,112,105,108,101,114,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,121,110,97,109,105,99,32,82,101,99,111,109,112,105,108,101,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,33,45,45,32,119,97,105,116,115,116,97,116,101,115,32, 45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, @@ -1073,1259 +907,63 @@ static unsigned char xml_res_file_7[] = { 62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,115,101,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85,83,69,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -33,45,45,32,84,79,68,79,58,32,106,111,121,115,116,105,99,107,32,45,45,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,109,115,32,47, -32,103,97,109,101,32,98,108,97,115,116,101,114,32,45,45,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, -69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,33,45,45,32,71,114,97,118,105,115,32,85,108,116,114, -97,115,111,117,110,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116, +101,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118, -105,115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, -45,45,32,73,110,110,111,118,97,116,105,111,110,32,83,83,73,45,50,48,48, -49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110, -32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,69,110,97, -98,108,101,32,116,105,109,101,32,115,121,110,99,32,45,45,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, -69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89, -78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,83,121,110,99,104,114,111,110,105,115,101,32,116,105,109, -101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,33,45,45,32,86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,32, -45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, -72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114, -97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79, -68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,67,111,110,102,105,103,117,114,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, -70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110, -99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, +87,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,80, -65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105,100, -115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,67,68,82, -79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, -60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, -70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, -74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, -69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, -32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, -95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, -48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, -101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, -61,34,49,48,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61, -34,72,100,67,111,110,102,68,108,103,34,62,10,32,32,32,32,60,116,105,116, -108,101,62,67,111,110,102,105,103,117,114,101,32,72,97,114,100,32,68,105, -115,99,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, -101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, -110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, -119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +32,32,32,60,33,45,45,32,115,111,117,110,100,32,99,97,114,100,32,45,45,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68, -67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, -91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, -105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,111,117,110,100,32,99,97,114, +100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,78,69,87,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, -84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, -47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, -48,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,49,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,78, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, -66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, -79,77,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, -101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,69,74,69,67,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, -67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,84,69,88,84,95,83,73,90,69,91,49,93,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, -68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,69,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, -91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, -105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,50,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,50,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,78,69,87,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, -84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, -47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, -50,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,51,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, -66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, -79,77,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, -101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,69,74,69,67,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, -67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,84,69,88,84,95,83,73,90,69,91,51,93,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, -73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, -108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, -108,111,103,34,32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34, -62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100, -32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101, -110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, -76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, -119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, -61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68, -79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85, +82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,72, +68,68,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, 119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, @@ -2333,7 +971,33 @@ static unsigned char xml_res_file_7[] = { 101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, +79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45, +32,70,68,68,49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49, 58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, @@ -2342,71 +1006,51 @@ static unsigned char xml_res_file_7[] = { 97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +33,45,45,32,70,68,68,50,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,50,34,47,62,10,32,32,32,32,32,32, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,51,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, -122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32, +124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,33,45,45,32,109,101,109,111,114,121,32,45,45,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47, 108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, @@ -2415,19 +1059,1226 @@ static unsigned char xml_res_file_7[] = { 119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, 114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, -79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,83,80,95,72,79,82,73,90,79,78,84,65,76,124, +119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,53,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,48,60,47, +109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,97,120,62,50,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,33,45,45,32,109,111,117,115,101,32,45,45,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,111,117,115,101,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85,83,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, +45,45,32,84,79,68,79,58,32,106,111,121,115,116,105,99,107,32,45,45,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,109,115,32,47,32, +103,97,109,101,32,98,108,97,115,116,101,114,32,45,45,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,33,45,45,32,71,114,97,118,105,115,32,85,108,116,114,97,115, +111,117,110,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105,115,32,85,108, +116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,73,110,110, +111,118,97,116,105,111,110,32,83,83,73,45,50,48,48,49,32,45,45,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83,83,73,45,50, +48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,69,110,97,98,108,101,32,116, +105,109,101,32,115,121,110,99,32,45,45,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, 101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78,67,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,121,110, +99,104,114,111,110,105,115,101,32,116,105,109,101,32,116,111,32,104,111, +115,116,32,99,108,111,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,86,111,111, +100,111,111,32,71,114,97,112,104,105,99,115,32,45,45,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79, +79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102, +105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116, +97,114,116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,67,95,72,68,68,34,32,115,116,97,114,116, +61,34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, +110,97,109,101,61,34,73,68,67,95,67,68,82,79,77,34,32,115,116,97,114,116, +61,34,50,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, +110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34,32,115,116,97, +114,116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32,115,116,97,114, +116,61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32,115,116,97,114, +116,61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116,97,114,116,61, +34,54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114, +116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116, +97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34, +32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, +73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108, +111,103,34,32,110,97,109,101,61,34,72,100,67,111,110,102,68,108,103,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117, +114,101,32,72,97,114,100,32,68,105,115,99,115,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101, +110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, +67,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,84,69,88,84,95,83,73,90,69,91,48,93,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, +91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, +105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, +84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,49,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,95,67,89,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, +49,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,50,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, +67,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,84,69,88,84,95,83,73,90,69,91,50,93,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, +91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, +105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, +84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,51,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,95,67,89,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, +51,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, 62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, @@ -2466,134 +2317,316 @@ static unsigned char xml_res_file_7[] = { 116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100, -83,105,122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62, -72,97,114,100,32,100,105,115,99,32,112,97,114,97,109,101,116,101,114,115, -60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101, -100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, -34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +78,101,119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78, +101,119,32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, -47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105, -116,105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97, -115,101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, -60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, -97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, -99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, 103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, +117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110, +99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,72,100,83,105,122,101,68,108,103,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,72,97,114,100,32,100,105,115,99,32,112,97,114,97,109, +101,116,101,114,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101, +110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, -68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, +76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,110,105,116,105,97,108,32,115,101,116,116,105,110,103, +115,32,97,114,101,32,98,97,115,101,100,32,111,110,32,102,105,108,101,32, +115,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, 101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, -84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100, -115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, -67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, -115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, -67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84, -49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, +101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,50,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110, +100,101,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,51,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, +84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 22d4e63..fcafbc0 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "ibm.h" #include "cdrom-ioctl.h" #include "cdrom-image.h" @@ -41,6 +42,8 @@ #define IDM_CDROM_REAL 1500 +#define MIN_SND_BUF 50 + uint64_t timer_freq; @@ -285,6 +288,9 @@ void wx_setupmenu() window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); wx_checkmenuitem(menu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len/MIN_SND_BUF)/log(2))); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); sprintf(menuitem, "IDM_VID_SCALE[%d]", video_scale); @@ -729,6 +735,11 @@ int wx_handle_command(void* hwnd, int wParam, int checked) video_focus_dim = checked; saveconfig(NULL); } + else if (ID_RANGE("IDM_SND_BUF[start]", "IDM_SND_BUF[end]")) + { + sound_buf_len = MIN_SND_BUF*1<<(wParam - wx_xrcid("IDM_SND_BUF[start]")); + saveconfig(NULL); + } else if (ID_IS("IDM_CDROM_DISABLED")) { if (cdrom_enabled) From 4446a6cdaf19627cdcacfac368f2ec3e1b562ee5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Jun 2017 19:55:59 +0100 Subject: [PATCH 0059/1050] Implemented 16-bit task switching. Patch from Greatpsycho. --- src/x86seg.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 7 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 364c616..1785a64 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -799,6 +799,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) break; + case 0x100: /*286 Task gate*/ case 0x900: /*386 Task gate*/ // pclog("Task gate\n"); cpu_state.pc=oxpc; @@ -2102,7 +2103,7 @@ void pmodeiret(int is32) segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); - taskswitch286(seg,segdat,0); + taskswitch286(seg,segdat,segdat[2] & 0x800); cpl_override=0; return; } @@ -2418,16 +2419,19 @@ 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); + base=segdat[1]|((segdat[2]&0xFF)<<16); + limit=segdat[0]; // pclog("286 Task switch! %04X:%04X\n",CS,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 (is32) { // if (output) pclog("32-bit TSS\n"); - + + 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); @@ -2629,8 +2633,176 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } else { - pclog("16-bit TSS\n"); - resetx86(); +// pclog("16-bit TSS\n"); +// 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); +// if (output) pclog("Read CS from %08X\n",base+0x4C); + 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; + +// if (output) pclog("Write PC %08X %08X\n",tr.base,pc); + 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); +// if (output) pclog("Write CS %04X to %08X\n",CS,tr.base+0x4C); + 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; +// if (output) pclog("New pc %08X\n",new_pc); + flags=new_flags; + 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); + ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); +// if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); + + + 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; + } + +// if (output) pclog("new_cs %04X\n",new_cs); + 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); //exit(-1); } From 16b4894b4422fbd7425b623efb591a9dfd3213a7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Jun 2017 19:31:48 +0100 Subject: [PATCH 0060/1050] Opcode C6/1-7 and C7/1-7 treated as illegal on 286+ CPUs. Patch from Greatpsycho. --- src/x86_ops_mov.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index 32b88c9..bdd968c 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); From 4c94ab07c967bb024823c4c01e1418cc64fb147a Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Jun 2017 19:32:12 +0100 Subject: [PATCH 0061/1050] 286 LOADALL can not change PE bit in MSW register when in protected mode. Patch from Greatpsycho. --- src/x86_ops_misc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index cad6d95..ebd9a0d 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -734,7 +734,7 @@ static int opLOADALL(uint32_t fetchdat) x86gpf(NULL,0); return 1; } - msw = readmemw(0, 0x806); + msw = (msw & 1) | readmemw(0, 0x806); flags = (readmemw(0, 0x818) & 0xffd5) | 2; flags_extract(); tr.seg = readmemw(0, 0x816); From 8fbebead19543ced8d56cd10ddc48e5ee7755b19 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Jun 2017 19:32:58 +0100 Subject: [PATCH 0062/1050] CHECK_READ()/CHECK_WRITE() now handle code segments. Patch from Greatpsycho. --- src/386_common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/386_common.h b/src/386_common.h index 88a92fc..36519fa 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -38,14 +38,14 @@ int checkio(int port); } #define CHECK_READ(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((seg)->access & 10) == 8))) \ { \ x86gpf("Limit check", 0); \ return 1; \ } #define CHECK_WRITE(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2)) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((seg)->access & 8))) \ { \ x86gpf("Limit check", 0); \ return 1; \ From 1f33b52451b38320cda6a1acd3847888f6db7653 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 30 Jun 2017 20:42:19 +0100 Subject: [PATCH 0063/1050] Added VME emulation to Intel DX4, Pentium and Pentium MMX. Temporarily disabled recompilation of CLI and STI. --- nvr/ami386dx_opti495.nvr | Bin 128 -> 128 bytes src/386.h | 1 + src/386_dynarec.c | 32 +++++++++++ src/808x.c | 2 +- src/codegen_ops_misc.h | 2 + src/cpu.c | 40 ++++++++++--- src/cpu.h | 18 +++--- src/ibm.h | 5 ++ src/x86_ops_flag.h | 117 +++++++++++++++++++++++++++++++-------- src/x86_ops_int.h | 32 +++++++++-- src/x86_ops_ret.h | 80 ++++++++++++++++++-------- 11 files changed, 263 insertions(+), 66 deletions(-) diff --git a/nvr/ami386dx_opti495.nvr b/nvr/ami386dx_opti495.nvr index dca4bd2693dd57ef29ce97be3e2598e9cbbd3c62..b6de20e01d144b622e8c6a2fb42496a8176f8ac0 100644 GIT binary patch literal 128 zcma!GU|~>VVA5a{S7QqJ&%ofY`-1^*0~3RcKEnzo0R{#R1_pZu7|3QxWRQ_O$-vLh b01;y4hDqU~nH-)lT>U7}&;Zo(9}55gwY?z- literal 128 zcmZQ#@MKVAU{x0sQ)3GF&&c4go56s$fr&wefuVvyfPsO7fx(^u2C|t27-S?@Fz_=p aK!jMiVN$qgCWj{sS3e3gGyt{y#{vKVt{*=D diff --git a/src/386.h b/src/386.h index d78be84..9ed872e 100644 --- a/src/386.h +++ b/src/386.h @@ -7,6 +7,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc); void pmoderetf(int is32, uint16_t off); void pmodeiret(int is32); void x86_int_sw(int num); +int x86_int_sw_rm(int num); int divl(uint32_t val); int idivl(int32_t val); diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 6ce33ba..6ab9418 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -263,6 +263,38 @@ void x86_int_sw(int num) CPU_BLOCK_END(); } +int x86_int_sw_rm(int num) +{ + uint32_t addr; + uint16_t new_pc, new_cs; + + flags_rebuild(); + cycles -= timing_int; + + addr = num << 2; + new_pc = readmemw(0, addr); + new_cs = readmemw(0, addr + 2); + + if (cpu_state.abrt) return 1; + + writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; } + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; } + SP-=6; + + eflags &= ~VIF_FLAG; + flags &= ~T_FLAG; + cpu_state.pc = new_pc; + loadcs(new_cs); + oxpc=cpu_state.pc; + + cycles -= timing_int_rm; + trap = 0; + CPU_BLOCK_END(); + + return 0; +} + void x86illegal() { // pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); diff --git a/src/808x.c b/src/808x.c index 7933f58..a78b52c 100644 --- a/src/808x.c +++ b/src/808x.c @@ -602,7 +602,7 @@ chdir(pcempath); if (is386) { printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit"); - printf("CR0=%08X CR2=%08X CR3=%08X\n",cr0,cr2,cr3); + printf("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4); } printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum); for (c=0;c<1024*1024;c++) diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index 1ccbcff..b4576d4 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -16,11 +16,13 @@ static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32 static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + return 0; CLEAR_BITS((uintptr_t)&flags, I_FLAG); return op_pc; } static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { + return 0; SET_BITS((uintptr_t)&flags, I_FLAG); return op_pc; } diff --git a/src/cpu.c b/src/cpu.c index c58c7df..9552c1d 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -51,6 +51,7 @@ OpFn *x86_opcodes_df_a32; enum { CPUID_FPU = (1 << 0), + CPUID_VME = (1 << 1), CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_CMPXCHG8B = (1 << 8), @@ -67,6 +68,7 @@ int cpu_busspeed; int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; +int cpu_hasVME; int cpu_use_dynarec; int cpu_cyrix_alignment; @@ -294,8 +296,8 @@ CPU cpus_i486[] = {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, - {"iDX4/75", CPU_i486DX, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_i486DX,10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7}, {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8}, {"", -1, 0, 0, 0} @@ -761,7 +763,11 @@ void cpu_set() timing_jmp_pm_gate = 37; timing_misaligned = 3; break; - + + case CPU_iDX4: + cpu_hasCR4 = 1; + cpu_hasVME = 1; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; case CPU_i486SX: case CPU_i486DX: timing_rr = 1; /*register dest - register src*/ @@ -971,7 +977,8 @@ void cpu_set() cpu_hasMMX = 0; cpu_hasMSR = 1; cpu_hasCR4 = 1; - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_hasVME = 1; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1011,7 +1018,8 @@ void cpu_set() cpu_hasMMX = 1; cpu_hasMSR = 1; cpu_hasCR4 = 1; - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_hasVME = 1; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1197,6 +1205,24 @@ void cpu_CPUID() EAX = 0; break; + case CPU_iDX4: + if (!EAX) + { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } + else if (EAX == 1) + { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME; + } + else + EAX = 0; + break; + case CPU_Am486SX: if (!EAX) { @@ -1273,7 +1299,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; } else EAX = 0; @@ -1291,7 +1317,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; } else EAX = 0; diff --git a/src/cpu.h b/src/cpu.h index 60ff266..2a94816 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -23,16 +23,17 @@ extern int cpu, cpu_manufacturer; #define CPU_i486DX 10 #define CPU_Am486DX 11 #define CPU_Cx486DX 12 -#define CPU_Cx5x86 13 +#define CPU_iDX4 13 +#define CPU_Cx5x86 14 /*586 class CPUs*/ -#define CPU_WINCHIP 14 -#define CPU_PENTIUM 15 -#define CPU_PENTIUMMMX 16 -#define CPU_Cx6x86 17 -#define CPU_Cx6x86MX 18 -#define CPU_Cx6x86L 19 -#define CPU_CxGX1 20 +#define CPU_WINCHIP 15 +#define CPU_PENTIUM 16 +#define CPU_PENTIUMMMX 17 +#define CPU_Cx6x86 18 +#define CPU_Cx6x86MX 19 +#define CPU_Cx6x86L 20 +#define CPU_CxGX1 21 #define MANU_INTEL 0 #define MANU_AMD 1 @@ -106,6 +107,7 @@ extern int cpu_hasrdtsc; extern int cpu_hasMSR; extern int cpu_hasMMX; extern int cpu_hasCR4; +extern int cpu_hasVME; #define CR4_TSD (1 << 2) #define CR4_DE (1 << 3) diff --git a/src/ibm.h b/src/ibm.h index 183d462..47ba64b 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -244,9 +244,14 @@ uint32_t dr[8]; #define V_FLAG 0x0800 #define NT_FLAG 0x4000 #define VM_FLAG 0x0002 /*In EFLAGS*/ +#define VIF_FLAG 0x0008 /*In EFLAGS*/ +#define VIP_FLAG 0x0010 /*In EFLAGS*/ #define WP_FLAG 0x10000 /*In CR0*/ +#define CR4_VME (1 << 0) +#define CR4_PVI (1 << 1) + #define IOPL ((flags>>12)&3) #define IOPLp ((!(msw&1)) || (CPL<=IOPL)) diff --git a/src/x86_ops_flag.h b/src/x86_ops_flag.h index 3fbaba6..9d3c0d7 100644 --- a/src/x86_ops_flag.h +++ b/src/x86_ops_flag.h @@ -27,8 +27,16 @@ static int opCLI(uint32_t fetchdat) { if (!IOPLp) { - x86gpf(NULL,0); - return 1; + if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((eflags & VM_FLAG) && (cr4 & CR4_VME))) + { + eflags &= ~VIF_FLAG; + } + else + { + x86gpf(NULL,0); + return 1; + } } else flags &= ~I_FLAG; @@ -57,8 +65,22 @@ static int opSTI(uint32_t fetchdat) { if (!IOPLp) { - x86gpf(NULL,0); - return 1; + if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((eflags & VM_FLAG) && (cr4 & CR4_VME))) + { + if (eflags & VIP_FLAG) + { + x86gpf(NULL,0); + return 1; + } + else + eflags |= VIF_FLAG; + } + else + { + x86gpf(NULL,0); + return 1; + } } else flags |= I_FLAG; @@ -94,11 +116,27 @@ static int opPUSHF(uint32_t fetchdat) { if ((eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL,0); - return 1; + if (cr4 & CR4_VME) + { + uint16_t temp; + + flags_rebuild(); + temp = (flags & ~I_FLAG) | 0x3000; + if (eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } + else + { + x86gpf(NULL,0); + return 1; + } + } + else + { + flags_rebuild(); + PUSH_W(flags); } - flags_rebuild(); - PUSH_W(flags); CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return cpu_state.abrt; @@ -111,8 +149,9 @@ static int opPUSHFD(uint32_t fetchdat) x86gpf(NULL, 0); return 1; } - if (CPUID) tempw = eflags & 0x24; - else tempw = eflags & 4; + if (cpu_CR4_mask & CR4_VME) tempw = eflags & 0x3c; + else if (CPUID) tempw = eflags & 0x24; + else tempw = eflags & 4; flags_rebuild(); PUSH_L(flags | (tempw << 16)); CLOCK_CYCLES(4); @@ -151,15 +190,48 @@ static int opPOPF(uint32_t fetchdat) if ((eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL, 0); - return 1; - } - - tempw = POP_W(); if (cpu_state.abrt) return 1; + if (cr4 & CR4_VME) + { + uint32_t old_esp = ESP; - if (!(CPL) || !(msw & 1)) flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; - else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; + tempw = POP_W(); + if (cpu_state.abrt) + { + ESP = old_esp; + return 1; + } + + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (eflags & VIP_FLAG))) + { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + eflags |= VIF_FLAG; + else + eflags &= ~VIF_FLAG; + flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + else + { + x86gpf(NULL, 0); + return 1; + } + } + else + { + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; + } flags_extract(); CLOCK_CYCLES(5); @@ -185,11 +257,12 @@ static int opPOPFD(uint32_t fetchdat) else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2; else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2; - templ &= is486 ? 0x240000 : 0; + templ &= is486 ? 0x3c0000 : 0; templ |= ((eflags&3) << 16); - if (CPUID) eflags = (templ >> 16) & 0x27; - else if (is486) eflags = (templ >> 16) & 7; - else eflags = (templ >> 16) & 3; + if (cpu_CR4_mask & CR4_VME) eflags = (templ >> 16) & 0x3f; + else if (CPUID) eflags = (templ >> 16) & 0x27; + else if (is486) eflags = (templ >> 16) & 7; + else eflags = (templ >> 16) & 3; flags_extract(); diff --git a/src/x86_ops_int.h b/src/x86_ops_int.h index f72ef60..ce85225 100644 --- a/src/x86_ops_int.h +++ b/src/x86_ops_int.h @@ -29,15 +29,39 @@ static int opINT1(uint32_t fetchdat) static int opINT(uint32_t fetchdat) { 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);*/ + uint8_t temp = getbytef(); + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) + { + uint16_t t; + uint8_t d; + + cpl_override = 1; + t = readmemw(tr.base, 0x66) - 32; + cpl_override = 0; + if (cpu_state.abrt) return 1; + + t += (temp >> 3); + if (t <= tr.limit) + { + cpl_override = 1; + d = readmemb(tr.base, t);// + (temp >> 3)); + cpl_override = 0; + if (cpu_state.abrt) return 1; + + if (!(d & (1 << (temp & 7)))) + { + x86_int_sw_rm(temp); + PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); + return 1; + } + } + } x86gpf(NULL,0); 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; diff --git a/src/x86_ops_ret.h b/src/x86_ops_ret.h index 3a600ce..d9db8ba 100644 --- a/src/x86_ops_ret.h +++ b/src/x86_ops_ret.h @@ -141,35 +141,67 @@ static int opIRET(uint32_t fetchdat) if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { - x86gpf(NULL,0); - return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - oxpc = cpu_state.pc; - if (stack32) + if (cr4 & CR4_VME) { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; + uint16_t new_pc, new_cs, new_flags; + + new_pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + new_flags = readmemw(ss, ((SP + 4) & 0xffff)); + if (cpu_state.abrt) + return 1; + + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (eflags & VIP_FLAG))) + { + x86gpf(NULL, 0); + return 1; + } + SP += 6; + if (new_flags & I_FLAG) + eflags |= VIF_FLAG; + else + eflags &= ~VIF_FLAG; + flags = (flags & 0x3300) | (new_flags & 0x4cd5) | 2; + loadcs(new_cs); + cpu_state.pc = new_pc; + + cycles -= timing_iret_rm; } else { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; - SP += 6; + x86gpf(NULL,0); + return 1; + } + } + else + { + if (msw&1) + { + optype = IRET; + pmodeiret(0); + optype = 0; + } + else + { + uint16_t new_cs; + oxpc = cpu_state.pc; + if (stack32) + { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } + else + { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; } - loadcs(new_cs); - cycles -= timing_iret_rm; } flags_extract(); nmi_enable = 1; From c760a93e1ad66372e500b140871d910b6c257220 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 30 Jun 2017 21:02:28 +0100 Subject: [PATCH 0064/1050] Re-enabled recompiled CLI/STI with VME. --- src/codegen_ops_misc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index b4576d4..9eb9567 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -16,13 +16,15 @@ static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32 static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; CLEAR_BITS((uintptr_t)&flags, I_FLAG); return op_pc; } static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; SET_BITS((uintptr_t)&flags, I_FLAG); return op_pc; } From 6484baaf9f49b54e56da429c01d8c45d242c5dd2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 2 Jul 2017 18:10:36 +0100 Subject: [PATCH 0065/1050] Abstracted hard disc image handling to separate file. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/hdd_esdi.c | 101 +++++++---------------------- src/hdd_file.c | 85 ++++++++++++++++++++++++ src/hdd_file.h | 14 ++++ src/ide.c | 103 +++++++++++++++++++---------- src/mfm_at.c | 89 +++++--------------------- src/mfm_xebec.c | 121 ++++++++++------------------------- 15 files changed, 251 insertions(+), 280 deletions(-) create mode 100644 src/hdd_file.c create mode 100644 src/hdd_file.h diff --git a/src/Makefile.am b/src/Makefile.am index 8965c21..b8ae928 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ amrefresh: pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 dells200.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 \ -hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ +hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.c sis496.c sound.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index b8dc43f..ea65156 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -8,7 +8,7 @@ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o alle allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index d828df9..2735900 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(sh OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 3e1f78d..7715e58 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -7,7 +7,7 @@ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o alle allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index e331164..15c2f3e 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-con OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index cbc49d7..7e1f51a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 8c2e2bf..741ad5f 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 67df2c0..812b4ce 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index bf8a60f..953f665 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64= OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.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.c compaq.o config.o cpu.o \ dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 2aaa644..6226425 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -12,6 +12,7 @@ #include "device.h" #include "dma.h" +#include "hdd_file.h" #include "io.h" #include "mca.h" #include "mem.h" @@ -27,14 +28,6 @@ extern char ide_fn[4][512]; -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; @@ -74,7 +67,7 @@ typedef struct esdi_t int req_in_progress; } cmds[3]; - esdi_drive_t drives[2]; + hdd_file_t hdd_file[2]; uint8_t pos_regs[8]; } esdi_t; @@ -379,15 +372,15 @@ static void device_not_present(esdi_t *esdi) return; \ } \ if (esdi->cmd_dev == ATTN_DEVICE_0) \ - drive = &esdi->drives[0]; \ + hdd_file = &esdi->hdd_file[0]; \ else \ - drive = &esdi->drives[1]; \ + hdd_file = &esdi->hdd_file[1]; \ } while (0) static void esdi_callback(void *p) { esdi_t *esdi = (esdi_t *)p; - esdi_drive_t *drive; + hdd_file_t *hdd_file; esdi->callback = 0; @@ -406,7 +399,7 @@ static void esdi_callback(void *p) case CMD_READ: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -441,11 +434,9 @@ static void esdi_callback(void *p) { if (!esdi->data_pos) { - if (esdi->rba >= drive->sectors) + if (esdi->rba >= hdd_file->sectors) fatal("Read past end of drive\n"); - fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); - fread(esdi->data, 512, 1, drive->hdfile); - readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); + hdd_read_sectors(hdd_file, esdi->rba, 1, esdi->data); } // pclog("Read sector %i %i %08x\n", esdi->sector_pos, esdi->data_pos, esdi->rba*512); while (esdi->data_pos < 256) @@ -486,7 +477,7 @@ static void esdi_callback(void *p) case CMD_WRITE_VERIFY: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -534,10 +525,9 @@ static void esdi_callback(void *p) esdi->data[esdi->data_pos++] = val & 0xffff; } - if (esdi->rba >= drive->sectors) + if (esdi->rba >= hdd_file->sectors) fatal("Write past end of drive\n"); - fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); - fwrite(esdi->data, 512, 1, drive->hdfile); + hdd_write_sectors(hdd_file, esdi->rba, 1, esdi->data); esdi->rba++; esdi->sector_pos++; readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); @@ -563,7 +553,7 @@ static void esdi_callback(void *p) case CMD_READ_VERIFY: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -578,7 +568,7 @@ static void esdi_callback(void *p) case CMD_SEEK: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -593,7 +583,7 @@ static void esdi_callback(void *p) case CMD_GET_DEV_CONFIG: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!hdd_file->f) { device_not_present(esdi); return; @@ -607,10 +597,10 @@ static void esdi_callback(void *p) 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); + esdi->status_data[2] = hdd_file->sectors & 0xffff; + esdi->status_data[3] = hdd_file->sectors >> 16; + esdi->status_data[4] = hdd_file->tracks; + esdi->status_data[5] = hdd_file->hpc | (hdd_file->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], @@ -827,45 +817,6 @@ static void esdi_mca_write(int port, uint8_t val, void *p) } } -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() { esdi_t *esdi = malloc(sizeof(esdi_t)); @@ -874,8 +825,8 @@ static void *esdi_init() 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); - loadhd(esdi, 0, ide_fn[0]); - loadhd(esdi, 1, ide_fn[1]); + hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]); + hdd_load(&esdi->hdd_file[1], 1, ide_fn[1]); timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); @@ -894,16 +845,10 @@ static void *esdi_init() 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); - } + hdd_close(&esdi->hdd_file[0]); + hdd_close(&esdi->hdd_file[1]); + free(esdi); } diff --git a/src/hdd_file.c b/src/hdd_file.c new file mode 100644 index 0000000..01e5007 --- /dev/null +++ b/src/hdd_file.c @@ -0,0 +1,85 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include + +#include "ibm.h" +#include "hdd_file.h" + +void hdd_load(hdd_file_t *hdd, int d, const char *fn) +{ + if (hdd->f == NULL) + { + /* Try to open existing hard disk image */ + hdd->f = fopen64(fn, "rb+"); + if (hdd->f == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + hdd->f = fopen64(fn, "wb+"); + if (hdd->f == 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; + } + } + } + + hdd->spt = hdc[d].spt; + hdd->hpc = hdc[d].hpc; + hdd->tracks = hdc[d].tracks; + hdd->sectors = hdc[d].spt * hdc[d].hpc * hdc[d].tracks; +} + +void hdd_close(hdd_file_t *hdd) +{ + if (hdd->f) + { + fclose(hdd->f); + hdd->f = NULL; + } +} + +void hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) +{ + off64_t addr; + + addr = offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); + fread(buffer, nr_sectors*512, 1, hdd->f); +} + +void hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) +{ + off64_t addr; + + addr = offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); + fwrite(buffer, nr_sectors*512, 1, hdd->f); +} + +void hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) +{ + off64_t addr; + int c; + uint8_t zero_buffer[512]; + + memset(zero_buffer, 0, 512); + + addr = offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); + for (c = 0; c < nr_sectors; c++) + fwrite(zero_buffer, 512, 1, hdd->f); +} diff --git a/src/hdd_file.h b/src/hdd_file.h new file mode 100644 index 0000000..83ef438 --- /dev/null +++ b/src/hdd_file.h @@ -0,0 +1,14 @@ +typedef struct hdd_file_t +{ + FILE *f; + int spt; + int hpc; + int tracks; + int sectors; +} hdd_file_t; + +void hdd_load(hdd_file_t *hdd, int d, const char *fn); +void hdd_close(hdd_file_t *hdd); +void hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); +void hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); +void hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors); diff --git a/src/ide.c b/src/ide.c index 9c7b150..6d5d4e3 100644 --- a/src/ide.c +++ b/src/ide.c @@ -23,6 +23,7 @@ #include "io.h" #include "pic.h" #include "timer.h" + #include "hdd_file.h" #endif #include "ide.h" @@ -247,13 +248,10 @@ typedef struct IDE uint8_t fdisk; int pos; int packlen; - int spt,hpc; - int tracks; int packetstatus; int cdpos,cdlen; uint8_t asc; int reset; - FILE *hdfile; uint16_t buffer[65536]; int irqstat; int service; @@ -264,6 +262,13 @@ typedef struct IDE uint8_t sector_buffer[256*512]; int do_initial_read; int sector_pos; +#ifdef RPCEMU_IDE + FILE *hdfile; + int spt,hpc; + int tracks; +#else + hdd_file_t hdd_file; +#endif } IDE; IDE ide_drives[4]; @@ -561,9 +566,13 @@ static off64_t ide_get_sector(IDE *ide) } else { +#ifdef RPCEMU_IDE int heads = ide->hpc; int sectors = ide->spt; - +#else + int heads = ide->hdd_file.hpc; + int sectors = ide->hdd_file.spt; +#endif return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (ide->sector - 1) + ide->skip512; } @@ -581,10 +590,18 @@ static void ide_next_sector(IDE *ide) else { ide->sector++; +#ifdef RPCEMU_IDE if (ide->sector == (ide->spt + 1)) { +#else + if (ide->sector == (ide->hdd_file.spt + 1)) { +#endif ide->sector = 1; ide->head++; +#ifdef RPCEMU_IDE if (ide->head == ide->hpc) { +#else + if (ide->head == ide->hdd_file.hpc) { +#endif ide->head = 0; ide->cylinder++; } @@ -649,35 +666,12 @@ static void loadhd(IDE *ide, int d, const char *fn) #else static void loadhd(IDE *ide, int d, const char *fn) { - if (ide->hdfile == NULL) { - /* Try to open existing hard disk image */ - ide->hdfile = fopen64(fn, "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 = fopen64(fn, "wb+"); - if (ide->hdfile == NULL) { - ide->type = IDE_NONE; -/* fatal("Cannot create file '%s': %s", - fn, strerror(errno));*/ - return; - } - } else { - /* Failed for another reason */ - ide->type = IDE_NONE; -/* fatal("Cannot open file '%s': %s", - fn, strerror(errno));*/ - return; - } - } - } - - ide->spt = hdc[d].spt; - ide->hpc = hdc[d].hpc; - ide->tracks = hdc[d].tracks; - ide->type = IDE_HDD; + hdd_load(&ide->hdd_file, d, fn); + + if (ide->hdd_file.f) + ide->type = IDE_HDD; + else + ide->type = IDE_NONE; } #endif @@ -697,10 +691,14 @@ void resetide(void) /* Close hard disk image files (if previously open) */ for (d = 0; d < 4; d++) { ide_drives[d].type = IDE_NONE; +#ifdef RPCEMU_IDE if (ide_drives[d].hdfile != NULL) { fclose(ide_drives[d].hdfile); ide_drives[d].hdfile = NULL; } +#else + hdd_close(&ide_drives[d].hdd_file); +#endif ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; ide_drives[d].board = (d & 2) ? 1 : 0; @@ -1295,8 +1293,10 @@ void callbackide(int ide_board) { IDE *ide = &ide_drives[cur_ide[ide_board]]; IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; +#if RPCEMU_IDE off64_t addr; int c; +#endif ext_ide = ide; // return; if (ide->command==0x30) times30++; @@ -1373,12 +1373,16 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); if (ide->secount) fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); else fread(ide->sector_buffer, 256*512, 1, ide->hdfile); +#else + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); +#endif } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); ide->sector_pos++; @@ -1405,12 +1409,16 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); if (ide->secount) fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); else fread(ide->sector_buffer, 256*512, 1, ide->hdfile); +#else + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); +#endif } ide->pos=0; @@ -1450,12 +1458,16 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); if (ide->secount) fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); else fread(ide->sector_buffer, 256*512, 1, ide->hdfile); +#else + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); +#endif } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); ide->sector_pos++; @@ -1479,10 +1491,14 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; // pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); fseeko64(ide->hdfile, addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); +#else + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); +#endif ide_irq_raise(ide); ide->secount = (ide->secount - 1) & 0xff; if (ide->secount) @@ -1510,9 +1526,13 @@ void callbackide(int ide_board) else { /*DMA successful*/ +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); +#else + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); +#endif ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1538,10 +1558,14 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } +#ifdef RPCEMU_IDE addr = ide_get_sector(ide) * 512; // pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); fseeko64(ide->hdfile, addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); +#else + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); +#endif ide->blockcount++; if (ide->blockcount >= ide->blocksize || ide->secount == 1) { @@ -1580,6 +1604,7 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } +#ifdef RPCEMU_IDE 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); fseeko64(ide->hdfile, addr, SEEK_SET); @@ -1588,6 +1613,9 @@ void callbackide(int ide_board) { fwrite(ide->buffer, 512, 1, ide->hdfile); } +#else + hdd_format_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount); +#endif ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); #ifndef RPCEMU_IDE @@ -1616,8 +1644,13 @@ void callbackide(int ide_board) #endif goto abort_cmd; } - ide->spt=ide->secount; - ide->hpc=ide->head+1; +#if RPCEMU_IDE + ide->spt = ide->secount; + ide->hpc = ide->head+1; +#else + ide->hdd_file.spt = ide->secount; + ide->hdd_file.hpc = ide->head+1; +#endif ide->atastat = READY_STAT | DSC_STAT; #ifndef RPCEMU_IDE // pclog("SPECIFY - %i sectors per track, %i heads per cylinder %i %i\n",ide->spt,ide->hpc,cur_ide[ide_board],ide_board); diff --git a/src/mfm_at.c b/src/mfm_at.c index 81d0bd6..c3c7346 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -11,6 +11,7 @@ #include "ibm.h" #include "device.h" +#include "hdd_file.h" #include "io.h" #include "pic.h" #include "timer.h" @@ -49,12 +50,10 @@ 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; + hdd_file_t hdd_file; } mfm_drive_t; typedef struct mfm_t @@ -123,12 +122,12 @@ static int mfm_get_sector(mfm_t *mfm, off64_t *addr) pclog("mfm_get_sector: past end of configured sectors\n"); return 1; } - if (mfm->head > drive->hpc) + if (mfm->head > drive->hdd_file.hpc) { pclog("mfm_get_sector: past end of heads\n"); return 1; } - if (mfm->sector >= drive->spt+1) + if (mfm->sector >= drive->hdd_file.spt+1) { pclog("mfm_get_sector: past end of sectors\n"); return 1; @@ -156,52 +155,12 @@ static void mfm_next_sector(mfm_t *mfm) { mfm->head = 0; mfm->cylinder++; - if (drive->current_cylinder < drive->tracks) + if (drive->current_cylinder < drive->hdd_file.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; @@ -236,14 +195,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) + if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) mfm->status = 0; else mfm->status = STAT_READY | STAT_DSC; return; case 0x1F7: /* Command register */ - if (mfm->drives[mfm->drive_sel].hdfile == NULL) + if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) fatal("Command on non-present drive\n"); mfm_irq_lower(mfm); @@ -458,10 +417,10 @@ static void do_seek(mfm_t *mfm) { mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; - if (mfm->cylinder < drive->tracks) + if (mfm->cylinder < drive->hdd_file.tracks) drive->current_cylinder = mfm->cylinder; else - drive->current_cylinder = drive->tracks-1; + drive->current_cylinder = drive->hdd_file.tracks-1; } void mfm_callback(void *p) @@ -469,7 +428,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; // pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); mfm->callback = 0; @@ -510,8 +468,7 @@ void mfm_callback(void *p) } // 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); + hdd_read_sectors(&drive->hdd_file, addr, 1, mfm->buffer); 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]); @@ -529,8 +486,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_write_sectors(&drive->hdd_file, addr, 1, mfm->buffer); mfm_irq_raise(mfm); mfm->secount = (mfm->secount - 1) & 0xff; if (mfm->secount) @@ -562,12 +518,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_format_sectors(&drive->hdd_file, addr, mfm->secount); mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); readflash_set(READFLASH_HDC, mfm->drive_sel); @@ -601,8 +552,8 @@ 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]); + hdd_load(&mfm->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&mfm->drives[1].hdd_file, 1, ide_fn[1]); mfm->status = STAT_READY | STAT_DSC; mfm->error = 1; /*No errors*/ @@ -619,15 +570,9 @@ void *mfm_init() 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); - } + + hdd_close(&mfm->drives[0].hdd_file); + hdd_close(&mfm->drives[1].hdd_file); free(mfm); } diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index bf583a9..9cfdf23 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -12,6 +12,7 @@ #include "device.h" #include "dma.h" +#include "hdd_file.h" #include "io.h" #include "mem.h" #include "pic.h" @@ -39,13 +40,11 @@ enum typedef struct mfm_drive_t { - int spt, hpc; - int tracks; int cfg_spt; int cfg_hpc; int cfg_cyl; int current_cylinder; - FILE *hdfile; + hdd_file_t hdd_file; } mfm_drive_t; typedef struct xebec_t @@ -271,7 +270,7 @@ static int xebec_get_sector(xebec_t *xebec, off64_t *addr) xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; return 1; } - if (xebec->head > drive->hpc) + if (xebec->head > drive->hdd_file.hpc) { pclog("mfm_get_sector: past end of heads\n"); xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; @@ -325,13 +324,13 @@ static void xebec_callback(void *p) switch (xebec->command[0]) { case CMD_TEST_DRIVE_READY: - if (!drive->hdfile) + if (!drive->hdd_file.f) xebec_error(xebec, ERR_NOT_READY); xebec_complete(xebec); break; case CMD_RECALIBRATE: - if (!drive->hdfile) + if (!drive->hdd_file.f) xebec_error(xebec, ERR_NOT_READY); else { @@ -402,7 +401,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; @@ -417,10 +415,8 @@ static void xebec_callback(void *p) return; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - for (c = 0; c < 17; c++) - fwrite(xebec->sector_buf, 512, 1, drive->hdfile); - + hdd_format_sectors(&drive->hdd_file, addr, 17); + xebec_complete(xebec); } break; @@ -448,8 +444,7 @@ static void xebec_callback(void *p) } // pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, xebec->sector); - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(xebec->sector_buf, 512, 1, drive->hdfile); + hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); readflash_set(READFLASH_HDC, xebec->drive_sel); } if (xebec->irq_dma_mask & DMA_ENA) @@ -503,9 +498,8 @@ static void xebec_callback(void *p) } // pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, xebec->sector); - - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(xebec->sector_buf, 512, 1, drive->hdfile); + + hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); readflash_set(READFLASH_HDC, xebec->drive_sel); xebec->state = STATE_SEND_DATA; @@ -587,9 +581,8 @@ static void xebec_callback(void *p) } // pclog("xebec Write %i,%i,%i %i\n", xebec->cylinder, xebec->head, xebec->sector, xebec->drive_sel); - - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fwrite(xebec->sector_buf, 512, 1, drive->hdfile); + + hdd_write_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); } readflash_set(READFLASH_HDC, xebec->drive_sel); @@ -616,7 +609,7 @@ static void xebec_callback(void *p) break; case CMD_SEEK: - if (!drive->hdfile) + if (!drive->hdd_file.f) xebec_error(xebec, ERR_NOT_READY); else { @@ -723,10 +716,10 @@ static void xebec_callback(void *p) 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); + xebec->data[0] = drive->hdd_file.tracks & 0xff; + xebec->data[1] = 17 | ((drive->hdd_file.tracks >> 2) & 0xc0); + xebec->data[2] = drive->hdd_file.hpc-1; + pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], drive->hdd_file.tracks); break; case STATE_SENT_DATA: @@ -747,9 +740,9 @@ static void xebec_callback(void *p) 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; + xebec->data[0x4] = drive->hdd_file.tracks & 0xff; + xebec->data[0x5] = (drive->hdd_file.tracks >> 8) & 0xff; + xebec->data[0xa] = drive->hdd_file.hpc; break; case STATE_SENT_DATA: @@ -783,44 +776,6 @@ static void xebec_callback(void *p) } } -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; @@ -842,14 +797,14 @@ static void xebec_set_switches(xebec_t *xebec) { mfm_drive_t *drive = &xebec->drives[d]; - if (!drive->hdfile) + if (!drive->hdd_file.f) 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) + if (drive->hdd_file.spt == 17 && + drive->hdd_file.hpc == xebec_hd_types[c].hpc && + drive->hdd_file.tracks == xebec_hd_types[c].tracks) { xebec->switches |= (c << (d ? 0 : 2)); break; @@ -866,8 +821,8 @@ static void *xebec_init() xebec_t *xebec = malloc(sizeof(xebec_t)); memset(xebec, 0, sizeof(xebec_t)); - loadhd(xebec, 0, ide_fn[0]); - loadhd(xebec, 1, ide_fn[1]); + hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); xebec_set_switches(xebec); rom_init(&xebec->bios_rom, "roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); @@ -882,16 +837,10 @@ static void *xebec_init() 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); - } + hdd_close(&xebec->drives[0].hdd_file); + hdd_close(&xebec->drives[1].hdd_file); + free(xebec); } @@ -918,14 +867,14 @@ static void *dtc_5150x_init() xebec_t *xebec = malloc(sizeof(xebec_t)); memset(xebec, 0, sizeof(xebec_t)); - loadhd(xebec, 0, ide_fn[0]); - loadhd(xebec, 1, ide_fn[1]); + hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); 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; + xebec->drives[0].cfg_cyl = xebec->drives[0].hdd_file.tracks; + xebec->drives[0].cfg_hpc = xebec->drives[0].hdd_file.hpc; + xebec->drives[1].cfg_cyl = xebec->drives[1].hdd_file.tracks; + xebec->drives[1].cfg_hpc = xebec->drives[1].hdd_file.hpc; rom_init(&xebec->bios_rom, "roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); From 5d6c3fb9ea587fa05f84f8c00be355496957d9f8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 5 Jul 2017 21:00:50 +0100 Subject: [PATCH 0066/1050] Added WD1007V-SE1 ESDI emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/esdi_at.c | 834 +++++++++++++++++++++++++++++++++++ src/esdi_at.h | 1 + src/hdd.c | 16 +- src/hdd_file.c | 39 +- src/hdd_file.h | 6 +- src/rom.c | 2 +- src/rom.h | 4 + 16 files changed, 891 insertions(+), 29 deletions(-) create mode 100644 src/esdi_at.c create mode 100644 src/esdi_at.h diff --git a/src/Makefile.am b/src/Makefile.am index b8ae928..2ab6bbc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,7 @@ amrefresh: pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 dells200.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 \ +dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index ea65156..40a175b 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 2735900..c0cb649 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 7715e58..1234299 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -6,7 +6,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 15c2f3e..d4f5305 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 7e1f51a..9e34408 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 741ad5f..bd47f6a 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 812b4ce..1e108c4 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -5,7 +5,7 @@ WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 953f665..a93c541 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.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.c compaq.o config.o cpu.o \ -dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ diff --git a/src/esdi_at.c b/src/esdi_at.c new file mode 100644 index 0000000..88646ee --- /dev/null +++ b/src/esdi_at.c @@ -0,0 +1,834 @@ +#include +#include +#include +#include + +#include + +#include "ibm.h" +#include "device.h" +#include "hdd_file.h" +#include "io.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "timer.h" + +#include "esdi_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_NOP 0x00 +#define CMD_RESTORE 0x10 +#define CMD_READ 0x20 +#define CMD_WRITE 0x30 +#define CMD_VERIFY 0x40 +#define CMD_FORMAT 0x50 +#define CMD_SEEK 0x70 +#define CMD_DIAGNOSE 0x90 +#define CMD_SET_PARAMETERS 0x91 +#define CMD_READ_PARAMETERS 0xec + +extern char ide_fn[4][512]; + +typedef struct esdi_drive_t +{ + int cfg_spt; + int cfg_hpc; + int current_cylinder; + hdd_file_t hdd_file; +} esdi_drive_t; + +typedef struct esdi_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; + + esdi_drive_t drives[2]; + + rom_t bios_rom; +} esdi_t; + +uint16_t esdi_readw(uint16_t port, void *p); +void esdi_writew(uint16_t port, uint16_t val, void *p); + +static inline void esdi_irq_raise(esdi_t *esdi) +{ +// pclog("IDE_IRQ_RAISE\n"); + if (!(esdi->fdisk&2)) + picint(1 << 14); + + esdi->irqstat=1; +} + +static inline void esdi_irq_lower(esdi_t *esdi) +{ + picintc(1 << 14); +} + +void esdi_irq_update(esdi_t *esdi) +{ + if (esdi->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(esdi->fdisk & 2)) + picint(1 << 14); +} + +/* + * Return the sector offset for the current register values + */ +int esdi_get_sector(esdi_t *esdi, off64_t *addr) +{ + esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + + if (esdi->head > heads) + { + pclog("esdi_get_sector: past end of configured heads\n"); + return 1; + } + if (esdi->sector >= sectors+1) + { + pclog("esdi_get_sector: past end of configured sectors\n"); + return 1; + } + + if (drive->cfg_spt == drive->hdd_file.spt && drive->cfg_hpc == drive->hdd_file.hpc) + { + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * + sectors) + (esdi->sector - 1); + } + else + { + /*When performing translation, the firmware seems to leave 1 + sector per track inaccessible (spare sector)*/ + int c, h, s; + *addr = ((((off64_t) esdi->cylinder * heads) + esdi->head) * + sectors) + (esdi->sector - 1); + + s = *addr % (drive->hdd_file.spt - 1); + h = (*addr / (drive->hdd_file.spt - 1)) % drive->hdd_file.hpc; + c = (*addr / (drive->hdd_file.spt - 1)) / drive->hdd_file.hpc; + + *addr = ((((off64_t) c * drive->hdd_file.hpc) + h) * + drive->hdd_file.spt) + s; + } + + return 0; +} + +/** + * Move to the next sector using CHS addressing + */ +void esdi_next_sector(esdi_t *esdi) +{ + esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; + + esdi->sector++; + if (esdi->sector == (drive->cfg_spt + 1)) + { + esdi->sector = 1; + esdi->head++; + if (esdi->head == drive->cfg_hpc) + { + esdi->head = 0; + esdi->cylinder++; + if (drive->current_cylinder < drive->hdd_file.tracks) + drive->current_cylinder++; + } + } +} + +void esdi_write(uint16_t port, uint8_t val, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + +// pclog("esdi_write: addr=%04x val=%02x\n", port, val); + switch (port) + { + case 0x1F0: /* Data */ + esdi_writew(port, val | (val << 8), p); + return; + + case 0x1F1: /* Write precompenstation */ + esdi->cylprecomp = val; + return; + + case 0x1F2: /* Sector count */ + esdi->secount = val; + return; + + case 0x1F3: /* Sector */ + esdi->sector = val; + return; + + case 0x1F4: /* Cylinder low */ + esdi->cylinder = (esdi->cylinder & 0xFF00) | val; + return; + + case 0x1F5: /* Cylinder high */ + esdi->cylinder = (esdi->cylinder & 0xFF) | (val << 8); + return; + + case 0x1F6: /* Drive/Head */ + esdi->head = val & 0xF; + esdi->drive_sel = (val & 0x10) ? 1 : 0; + if (esdi->drives[esdi->drive_sel].hdd_file.f == NULL) + esdi->status = 0; + else + esdi->status = STAT_READY | STAT_DSC; + return; + + case 0x1F7: /* Command register */ +// if (esdi->drives[esdi->drive_sel].hdd_file.f == NULL && val != CMD_SET_PARAMETERS && val != CMD_NOP && val != 0xe0 && (val & ~3) != 0x20 && (val & ~3) != 0x30 && (val & ~3) != 0x40 && val != 0x90 && val != CMD_READ_PARAMETERS) +// fatal("Command %02x on non-present drive\n", val); + + esdi_irq_lower(esdi); + esdi->command = val; + esdi->error = 0; + + switch (val & 0xf0) + { + case CMD_RESTORE: +// pclog("Restore\n"); + esdi->command &= ~0x0f; /*Mask off step rate*/ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_SEEK: +// pclog("Seek to cylinder %i\n", esdi->cylinder); + esdi->command &= ~0x0f; /*Mask off step rate*/ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + default: + switch (val) + { + case CMD_NOP: + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + 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",esdi->secount,esdi->sector,esdi->cylinder,esdi->head,ins); + esdi->command &= ~3; + if (val & 2) + fatal("Read with ECC\n"); + case 0xa0: + esdi->status = STAT_BUSY; + timer_process(); + esdi->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",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); + esdi->command &= ~3; + if (val & 2) + fatal("Write with ECC\n"); + esdi->status = STAT_DRQ | STAT_DSC;// | STAT_BUSY; + esdi->pos=0; + break; + + case CMD_VERIFY: case CMD_VERIFY+1: +// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); + esdi->command &= ~1; + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200 * IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_FORMAT: +// pclog("Format track %i head %i\n", esdi->cylinder, esdi->head); + esdi->status = STAT_DRQ;// | STAT_BUSY; + esdi->pos=0; + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 30*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + case 0xe0: /*???*/ + case CMD_READ_PARAMETERS: + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + default: + pclog("Bad esdi command %02X\n", val); + case 0xe8: /*???*/ + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + } + } + break; + + case 0x3F6: /* Device control */ + if ((esdi->fdisk & 4) && !(val & 4)) + { + timer_process(); + esdi->callback = 500*IDE_TIME; + timer_update_outstanding(); + esdi->reset = 1; + esdi->status = STAT_BUSY; +// pclog("esdi Reset\n"); + } + if (val & 4) + { + /*Drive held in reset*/ + timer_process(); + esdi->callback = 0; + timer_update_outstanding(); + esdi->status = STAT_BUSY; + } + esdi->fdisk = val; + esdi_irq_update(esdi); + return; + } +// fatal("Bad ESDI write %04X %02X\n", port, val); +} + +void esdi_writew(uint16_t port, uint16_t val, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + +// pclog("Write ESDIw %04X\n",val); + esdi->buffer[esdi->pos >> 1] = val; + esdi->pos += 2; + + if (esdi->pos >= 512) + { + esdi->pos = 0; + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 6*IDE_TIME; + timer_update_outstanding(); + } +} + +uint8_t esdi_read(uint16_t port, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + uint8_t temp = 0xff; + + switch (port) + { + case 0x1F0: /* Data */ + temp = esdi_readw(port, esdi) & 0xff; + break; + + case 0x1F1: /* Error */ + temp = esdi->error; + break; + + case 0x1F2: /* Sector count */ + temp = (uint8_t)esdi->secount; + break; + + case 0x1F3: /* Sector */ + temp = (uint8_t)esdi->sector; + break; + + case 0x1F4: /* Cylinder low */ + temp = (uint8_t)(esdi->cylinder&0xFF); + break; + + case 0x1F5: /* Cylinder high */ + temp = (uint8_t)(esdi->cylinder>>8); + break; + + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); + break; + + case 0x1F7: /* Status */ + esdi_irq_lower(esdi); + temp = esdi->status; + break; + } + +// if (port != 0x1f7) pclog("esdi_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); + return temp; +} + +uint16_t esdi_readw(uint16_t port, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + uint16_t temp; + + temp = esdi->buffer[esdi->pos >> 1]; + esdi->pos += 2; + + if (esdi->pos >= 512) + { +// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + esdi->pos=0; + esdi->status = STAT_READY | STAT_DSC; + if (esdi->command == CMD_READ || esdi->command == 0xa0) + { + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) + { + esdi_next_sector(esdi); + esdi->status = STAT_BUSY; + timer_process(); + esdi->callback = 6*IDE_TIME; + timer_update_outstanding(); + } + } + } + +// pclog("esdi_readw: temp=%04x %i\n", temp, esdi->pos); + return temp; +} + +void esdi_callback(void *p) +{ + esdi_t *esdi = (esdi_t *)p; + esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; + off64_t addr; + +// pclog("esdi_callback: command=%02x reset=%i\n", esdi->command, esdi->reset); + esdi->callback = 0; + if (esdi->reset) + { + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; + esdi->secount = 1; + esdi->sector = 1; + esdi->head = 0; + esdi->cylinder = 0; + esdi->reset = 0; +// pclog("Reset callback\n"); + return; + } + switch (esdi->command) + { + case CMD_RESTORE: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + drive->current_cylinder = 0; + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; + + case CMD_SEEK: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; + + case CMD_READ: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + if (esdi_get_sector(esdi, &addr)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_read_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + esdi->pos = 0; + esdi->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; + esdi_irq_raise(esdi); + readflash_set(READFLASH_HDC, esdi->drive_sel); + } + break; + + case CMD_WRITE: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + if (esdi_get_sector(esdi, &addr)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_write_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + esdi_irq_raise(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) + { + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + esdi->pos = 0; + esdi_next_sector(esdi); + } + else + esdi->status = STAT_READY | STAT_DSC; + readflash_set(READFLASH_HDC, esdi->drive_sel); + } + break; + + case CMD_VERIFY: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + if (esdi_get_sector(esdi, &addr)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_read_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + readflash_set(READFLASH_HDC, esdi->drive_sel); + esdi_next_sector(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) + esdi->callback = 6*IDE_TIME; + else + { + esdi->pos = 0; + esdi->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); + esdi_irq_raise(esdi); + } + } + break; + + case CMD_FORMAT: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + if (esdi_get_sector(esdi, &addr)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_format_sectors(&drive->hdd_file, addr, esdi->secount)) + { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + readflash_set(READFLASH_HDC, esdi->drive_sel); + } + break; + + case CMD_DIAGNOSE: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + esdi->error = 1; /*No error detected*/ + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + drive->cfg_spt = esdi->secount; + drive->cfg_hpc = esdi->head+1; + pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); + if (!esdi->secount) + fatal("secount=0\n"); + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; + + case CMD_NOP: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + break; + + case 0xe0: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + switch (esdi->cylinder >> 8) + { + case 0x31: + esdi->cylinder = drive->hdd_file.tracks; + break; + case 0x33: + esdi->cylinder = drive->hdd_file.hpc; + break; + case 0x35: + esdi->cylinder = 0x200; + break; + case 0x36: + esdi->cylinder = drive->hdd_file.spt; + break; + default: + pclog("EDSI Bad read config %02x\n", esdi->cylinder >> 8); + } + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; + + case 0xa0: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + memset(esdi->buffer, 0, 512); + memset(&esdi->buffer[3], 0xff, 512-6); + esdi->pos = 0; + esdi->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; + esdi_irq_raise(esdi); + } + break; + + case CMD_READ_PARAMETERS: + if (!drive->hdd_file.f) + { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } + else + { + memset(esdi->buffer, 0, 512); + + esdi->buffer[0] = 0x44; /* general configuration */ + esdi->buffer[1] = drive->hdd_file.tracks; /* number of non-removable cylinders */ + esdi->buffer[2] = 0; /* number of removable cylinders */ + esdi->buffer[3] = drive->hdd_file.hpc; /* number of heads */ + esdi->buffer[5] = esdi->buffer[4] * drive->hdd_file.spt; /* number of unformatted bytes/sector */ + esdi->buffer[4] = 600; /* number of unformatted bytes/track */ + esdi->buffer[6] = drive->hdd_file.spt; /* number of sectors */ + esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ + esdi->buffer[8] = 0; /* minimum bytes in postamble */ + esdi->buffer[9] = 0; /* number of words of vendor status */ + /* controller info */ +// char wdp_cnsn[20]; /* controller serial number */ + esdi->buffer[20] = 2; /* controller type */ + esdi->buffer[21] = 1; /* sector buffer size, in sectors */ + esdi->buffer[22] = 0; /* ecc bytes appended */ +// char wdp_rev[8]; /* firmware revision */ + //27 + esdi->buffer[27] = 'W' | ('D' << 8); + esdi->buffer[28] = '1' | ('0' << 8); + esdi->buffer[29] = '0' | ('7' << 8); + esdi->buffer[30] = 'V' | ('-' << 8); + esdi->buffer[31] = 'S' | ('E' << 8); + esdi->buffer[32] = '1'; + esdi->buffer[47] = 0; /* sectors per interrupt */ + esdi->buffer[48] = 0;/* can use double word read/write? */ + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; + + default: + pclog("ESDI Callback on unknown command %02x\n", esdi->command); + case 0xe8: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + break; + } +} + +static void esdi_rom_write(uint32_t addr, uint8_t val, void *p) +{ + rom_t *rom = (rom_t *)p; + + addr &= rom->mask; + + if (addr >= 0x1f00 && addr < 0x2000) + rom->rom[addr] = val; +} + +void *wd1007vse1_init() +{ + esdi_t *esdi = malloc(sizeof(esdi_t)); + memset(esdi, 0, sizeof(esdi_t)); + + hdd_load(&esdi->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&esdi->drives[1].hdd_file, 1, ide_fn[1]); + + esdi->drives[0].cfg_spt = esdi->drives[0].hdd_file.spt; + esdi->drives[0].cfg_hpc = esdi->drives[0].hdd_file.hpc; + esdi->drives[1].cfg_spt = esdi->drives[1].hdd_file.spt; + esdi->drives[1].cfg_hpc = esdi->drives[1].hdd_file.hpc; + + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; /*No errors*/ + + rom_init(&esdi->bios_rom, "roms/62-000279-061.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_set_handler(&esdi->bios_rom.mapping, + rom_read, rom_readw, rom_readl, + esdi_rom_write, NULL, NULL); + + io_sethandler(0x01f0, 0x0001, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); + io_sethandler(0x01f1, 0x0007, esdi_read, NULL, NULL, esdi_write, NULL, NULL, esdi); + io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi); + + timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); + + return esdi; +} + +void wd1007vse1_close(void *p) +{ + esdi_t *esdi = (esdi_t *)p; + + hdd_close(&esdi->drives[0].hdd_file); + hdd_close(&esdi->drives[1].hdd_file); + + free(esdi); +} + +static int wd1007vse1_available() +{ + return rom_present("roms/62-000279-061.bin"); +} + +device_t wd1007vse1_device = +{ + "Western Digital WD1007V-SE1 (ESDI)", + DEVICE_AT, + wd1007vse1_init, + wd1007vse1_close, + wd1007vse1_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/esdi_at.h b/src/esdi_at.h new file mode 100644 index 0000000..75efd32 --- /dev/null +++ b/src/esdi_at.h @@ -0,0 +1 @@ +extern device_t wd1007vse1_device; diff --git a/src/hdd.c b/src/hdd.c index 41e5a1d..aaaaa20 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -2,6 +2,7 @@ #include "device.h" #include "hdd.h" +#include "esdi_at.h" #include "hdd_esdi.h" #include "mfm_at.h" #include "mfm_xebec.h" @@ -21,13 +22,14 @@ static struct int is_mfm; } hdd_controllers[] = { - {"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}, + {"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}, + {"Western Digital WD1007V-SE1 (ESDI)","wd1007vse1", &wd1007vse1_device, 0}, + {"XTIDE", "xtide", &xtide_device, 0}, + {"XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, {"", "", NULL, 0} }; diff --git a/src/hdd_file.c b/src/hdd_file.c index 01e5007..fdfd77e 100644 --- a/src/hdd_file.c +++ b/src/hdd_file.c @@ -52,34 +52,55 @@ void hdd_close(hdd_file_t *hdd) } } -void hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) +int hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { off64_t addr; - + int transfer_sectors = nr_sectors; + + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; addr = offset * 512; fseeko64(hdd->f, addr, SEEK_SET); - fread(buffer, nr_sectors*512, 1, hdd->f); + fread(buffer, transfer_sectors*512, 1, hdd->f); + + if (nr_sectors != transfer_sectors) + return 1; + return 0; } -void hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) +int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { off64_t addr; - + int transfer_sectors = nr_sectors; + + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; addr = offset * 512; fseeko64(hdd->f, addr, SEEK_SET); - fwrite(buffer, nr_sectors*512, 1, hdd->f); + fwrite(buffer, transfer_sectors*512, 1, hdd->f); + + if (nr_sectors != transfer_sectors) + return 1; + return 0; } -void hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) +int hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) { off64_t addr; int c; uint8_t zero_buffer[512]; - + int transfer_sectors = nr_sectors; + memset(zero_buffer, 0, 512); + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; addr = offset * 512; fseeko64(hdd->f, addr, SEEK_SET); - for (c = 0; c < nr_sectors; c++) + for (c = 0; c < transfer_sectors; c++) fwrite(zero_buffer, 512, 1, hdd->f); + + if (nr_sectors != transfer_sectors) + return 1; + return 0; } diff --git a/src/hdd_file.h b/src/hdd_file.h index 83ef438..cd2997c 100644 --- a/src/hdd_file.h +++ b/src/hdd_file.h @@ -9,6 +9,6 @@ typedef struct hdd_file_t void hdd_load(hdd_file_t *hdd, int d, const char *fn); void hdd_close(hdd_file_t *hdd); -void hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); -void hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); -void hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors); +int hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); +int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); +int hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors); diff --git a/src/rom.c b/src/rom.c index abbca06..b83b098 100644 --- a/src/rom.c +++ b/src/rom.c @@ -31,7 +31,7 @@ int rom_present(char *fn) return 0; } -static uint8_t rom_read(uint32_t addr, void *p) +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]); diff --git a/src/rom.h b/src/rom.h index 06ace63..0e32d57 100644 --- a/src/rom.h +++ b/src/rom.h @@ -10,3 +10,7 @@ typedef struct 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); + +uint8_t rom_read(uint32_t addr, void *p); +uint16_t rom_readw(uint32_t addr, void *p); +uint32_t rom_readl(uint32_t addr, void *p); From 2ac22b03d541747bda88be80d93d67ff6e2d0ece Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 5 Jul 2017 21:40:02 +0100 Subject: [PATCH 0067/1050] Fixes to task switching. Patch from Greatpsycho. --- src/x86seg.c | 253 +++++++++++++++++++++++++++++---------------------- 1 file changed, 144 insertions(+), 109 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 1785a64..654143a 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -1320,12 +1320,14 @@ void loadcscall(uint16_t seg) } break; -// case 0x900: /*386 Task gate*/ -// case 0xB00: /*386 Busy task gate*/ -// if (optype==JMP) pclog("Task switch!\n"); -// taskswitch386(seg,segdat); -// return; - + case 0x100: /*286 Task gate*/ + case 0x900: /*386 Task gate*/ +// pclog("Task gate\n"); + cpu_state.pc=oxpc; + cpl_override=1; + taskswitch286(seg,segdat,segdat[2]&0x800); + cpl_override=0; + break; default: pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00); @@ -1800,7 +1802,7 @@ void pmodeint(int num, int soft) } else { - addr = 2 + tr.base + (DPL2 * 8); + addr = 2 + tr.base + (DPL2 * 4); newss=readmemw(0,addr+2); newsp=readmemw(0,addr); } @@ -2421,6 +2423,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) //output=3; base=segdat[1]|((segdat[2]&0xFF)<<16); limit=segdat[0]; + if(is386) + { + base |= (segdat[3]>>8)<<24; + limit |= (segdat[3]&0xF)<<16; + } // pclog("286 Task switch! %04X:%04X\n",CS,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]); @@ -2428,43 +2435,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (is32) { // if (output) pclog("32-bit TSS\n"); - - 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); - - new_eax=readmeml(base,0x28); - new_ecx=readmeml(base,0x2C); - new_edx=readmeml(base,0x30); - new_ebx=readmeml(base,0x34); - new_esp=readmeml(base,0x38); - new_ebp=readmeml(base,0x3C); - new_esi=readmeml(base,0x40); - 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); - new_fs=readmemw(base,0x58); - new_gs=readmemw(base,0x5C); - new_ldt=readmemw(base,0x60); - - if (cpu_state.abrt) return; - if (optype==JMP || optype==OPTYPE_INT) + if (limit < 103) { - 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); + pclog("32-bit TSS %04X limit less than 103.\n", seg); + x86ts(NULL, seg); + return; } - + if (optype==IRET) flags&=~NT_FLAG; // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); @@ -2489,15 +2466,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) writememl(tr.base,0x54,DS); writememl(tr.base,0x58,FS); writememl(tr.base,0x5C,GS); - writememl(tr.base,0x60,ldt.seg); - - if (optype==OPTYPE_INT) - { - writememl(base,0,tr.seg); - new_flags|=NT_FLAG; - } - if (cpu_state.abrt) return; - if (optype==JMP || optype==OPTYPE_INT) + + if (optype==JMP || optype==CALL || optype==OPTYPE_INT) { if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); else tempw=readmemw(gdt.base,(seg&~7)+4); @@ -2506,7 +2476,49 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); else writememw(gdt.base,(seg&~7)+4,tempw); } + if (cpu_state.abrt) return; + + new_cr3=readmeml(base,0x1C); + new_pc=readmeml(base,0x20); + new_flags=readmeml(base,0x24); + new_eax=readmeml(base,0x28); + new_ecx=readmeml(base,0x2C); + new_edx=readmeml(base,0x30); + new_ebx=readmeml(base,0x34); + new_esp=readmeml(base,0x38); + new_ebp=readmeml(base,0x3C); + new_esi=readmeml(base,0x40); + 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); + new_fs=readmemw(base,0x58); + new_gs=readmemw(base,0x5C); + new_ldt=readmemw(base,0x60); + + if (optype==JMP || optype==CALL || 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 (cpu_state.abrt) return; + + if (optype==OPTYPE_INT || optype==CALL) + { + writememl(base,0,tr.seg); + new_flags|=NT_FLAG; + } + if (cpu_state.abrt) return; + + cr0 |= 8; cr3=new_cr3; @@ -2545,7 +2557,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (!(new_cs&~3)) { pclog("TS loading null CS\n"); - x86gpf(NULL,0); + x86ts(NULL,0); return; } addr=new_cs&~7; @@ -2554,7 +2566,7 @@ 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); + x86ts(NULL,new_cs&~3); return; } addr+=ldt.base; @@ -2564,7 +2576,7 @@ 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); + x86ts(NULL,new_cs&~3); return; } addr+=gdt.base; @@ -2585,7 +2597,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if ((new_cs&3) != DPL2) { pclog("TS load CS non-conforming RPL != DPL"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; @@ -2593,13 +2605,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if ((new_cs&3) < DPL2) { pclog("TS load CS non-conforming RPL < DPL"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; default: pclog("TS load CS not code segment\n"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } @@ -2635,37 +2647,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { // pclog("16-bit TSS\n"); // 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); -// if (output) pclog("Read CS from %08X\n",base+0x4C); - 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 (limit < 43) { - 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); + pclog("16-bit TSS %04X limit less than 43.\n", seg); + x86ts(NULL, seg); + return; } - + if (optype==IRET) flags&=~NT_FLAG; // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); @@ -2687,15 +2675,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) 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 (optype==JMP || optype==CALL || optype==OPTYPE_INT) { if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); else tempw=readmemw(gdt.base,(seg&~7)+4); @@ -2704,7 +2685,47 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); else writememw(gdt.base,(seg&~7)+4,tempw); } + if (cpu_state.abrt) return; + 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); +// if (output) pclog("Read CS from %08X\n",base+0x4C); + new_cs=readmemw(base,0x24); + new_ss=readmemw(base,0x26); + new_ds=readmemw(base,0x28); + new_ldt=readmemw(base,0x2A); + + if (optype==JMP || optype==CALL || 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 (cpu_state.abrt) return; + + if (optype==OPTYPE_INT || optype==CALL) + { + writememw(base,0,tr.seg); + new_flags|=NT_FLAG; + } + if (cpu_state.abrt) return; + + msw |= 8; + cpu_state.pc=new_pc; // if (output) pclog("New pc %08X\n",new_pc); flags=new_flags; @@ -2716,13 +2737,22 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) // if (output) pclog("Load from %08X %08X\n",templ,gdt.base); ldt.limit=readmemw(0,templ); ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); + if (is386) + { + if (readmemb(0,templ+6)&0x80) + { + ldt.limit<<=12; + ldt.limit|=0xFFF; + } + ldt.base|=(readmemb(0,templ+7)<<24); + } // if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); if (!(new_cs&~3)) { pclog("TS loading null CS\n"); - x86gpf(NULL,0); + x86ts(NULL,0); return; } addr=new_cs&~7; @@ -2731,7 +2761,7 @@ 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); + x86ts(NULL,new_cs&~3); return; } addr+=ldt.base; @@ -2741,7 +2771,7 @@ 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); + x86ts(NULL,new_cs&~3); return; } addr+=gdt.base; @@ -2762,7 +2792,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if ((new_cs&3) != DPL2) { pclog("TS load CS non-conforming RPL != DPL"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; @@ -2770,13 +2800,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if ((new_cs&3) < DPL2) { pclog("TS load CS non-conforming RPL < DPL"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } break; default: pclog("TS load CS not code segment\n"); - x86gpf(NULL,new_cs&~3); + x86ts(NULL,new_cs&~3); return; } @@ -2786,14 +2816,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) 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; + EAX=new_eax | 0xFFFF0000; + ECX=new_ecx | 0xFFFF0000; + EDX=new_edx | 0xFFFF0000; + EBX=new_ebx | 0xFFFF0000; + ESP=new_esp | 0xFFFF0000; + EBP=new_ebp | 0xFFFF0000; + ESI=new_esi | 0xFFFF0000; + EDI=new_edi | 0xFFFF0000; if (output) pclog("Load ES %04X\n",new_es); loadseg(new_es,&_es); @@ -2801,6 +2831,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) loadseg(new_ss,&_ss); if (output) pclog("Load DS %04X\n",new_ds); loadseg(new_ds,&_ds); + if (is386) + { + loadseg(0,&_fs); + loadseg(0,&_gs); + } if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc); //exit(-1); From 1e90a84e9025d470fdcf6ecb885ea5e724c74c0c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 5 Jul 2017 21:54:48 +0100 Subject: [PATCH 0068/1050] Tweaks to hard drive image parameter finding. Patch from Greatpsycho. --- src/allegro-gui-hdconf.c | 19 ++++++++++--------- src/win-hdconf.c | 16 ++++++++++------ src/wx-sdl2-hdconf.c | 13 +++++++++---- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/allegro-gui-hdconf.c b/src/allegro-gui-hdconf.c index 493c3ff..050be68 100644 --- a/src/allegro-gui-hdconf.c +++ b/src/allegro-gui-hdconf.c @@ -68,7 +68,7 @@ static int hdconf_open(int msg, DIALOG *d, int c) fseeko64(f, -1, SEEK_END); sz = ftello64(f) + 1; fclose(f); - if ((sz % 17) == 0 && sz <= 133693440) + if ((sz % 17) == 0 && sz <= 142606336) { sprintf(hd_sectors_new, "17"); if (sz <= 26738688) @@ -76,20 +76,21 @@ static int hdconf_open(int msg, DIALOG *d, int c) sprintf(hd_heads_new, "4"); sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 4) / 17); } - else if (sz <= 53477376) + else if ((sz % 3072) == 0 && sz <= 53477376) { sprintf(hd_heads_new, "6"); sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 6) / 17); } - else if (sz <= 71303168) - { - sprintf(hd_heads_new, "8"); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 8) / 17); - } else { - sprintf(hd_heads_new, "15"); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 15) / 17); + int i; + for(i=5;i<16;i++) + { + if((sz % (i * 512)) == 0 && sz <= 1024*i*17*512) break; + if (i == 5) i++; + } + sprintf(hd_heads_new, "%i",i); + sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / i) / 17); } } else diff --git a/src/win-hdconf.c b/src/win-hdconf.c index d53e86c..c1107e9 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -61,19 +61,23 @@ static void check_hd_type(off64_t sz) } else { - if ((sz % 17) == 0 && sz <= 133693440) + if ((sz % 17) == 0 && sz <= 142606336) { hd_new_spt = 17; if (sz <= 26738688) hd_new_hpc = 4; - else if (sz <= 53477376) + else if ((sz % 3072) == 0 && sz <= 53477376) hd_new_hpc = 6; - else if (sz <= 71303168) - hd_new_hpc = 8; else - hd_new_hpc = 15; - + { + for (c=5;c<16;c++) + { + if((sz % (c * 512)) == 0 && sz <= 1024*c*17*512) break; + if (c == 5) c++; + } + hd_new_hpc = c; + } hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; } else diff --git a/src/wx-sdl2-hdconf.c b/src/wx-sdl2-hdconf.c index f462cb1..b4e1e51 100644 --- a/src/wx-sdl2-hdconf.c +++ b/src/wx-sdl2-hdconf.c @@ -65,12 +65,17 @@ static void check_hd_type(off64_t sz) if (sz <= 26738688) hd_new_hpc = 4; - else if (sz <= 53477376) + else if ((sz % 3072) == 0 && sz <= 53477376) hd_new_hpc = 6; - else if (sz <= 71303168) - hd_new_hpc = 8; else - hd_new_hpc = 15; + { + for (c=5;c<16;c++) + { + if((sz % (c * 512)) == 0 && sz <= 1024*c*17*512) break; + if (c == 5) c++; + } + hd_new_hpc = c; + } hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; } From c05689a9ec1316eff680511d35ff6b18951889c2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 6 Jul 2017 18:41:51 +0100 Subject: [PATCH 0069/1050] More task switching fixes. Patch from Greatpsycho. --- src/x86seg.c | 100 +++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 654143a..2da6a43 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2442,6 +2442,17 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) return; } + if (optype==JMP || optype==CALL || 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); + } + if (cpu_state.abrt) return; + if (optype==IRET) flags&=~NT_FLAG; // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); @@ -2466,15 +2477,22 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) writememl(tr.base,0x54,DS); writememl(tr.base,0x58,FS); writememl(tr.base,0x5C,GS); - - if (optype==JMP || optype==CALL || optype==OPTYPE_INT) + + if (optype==JMP || optype==IRET) { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); + 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,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); + tempw&=~0x200; + if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); + else writememw(gdt.base,(tr.seg&~7)+4,tempw); + } + if (cpu_state.abrt) return; + + if (optype==OPTYPE_INT || optype==CALL) + { + writememl(base,0,tr.seg); + new_flags|=NT_FLAG; } if (cpu_state.abrt) return; @@ -2499,24 +2517,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) new_fs=readmemw(base,0x58); new_gs=readmemw(base,0x5C); new_ldt=readmemw(base,0x60); - - if (optype==JMP || optype==CALL || 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 (cpu_state.abrt) return; - - if (optype==OPTYPE_INT || optype==CALL) - { - writememl(base,0,tr.seg); - new_flags|=NT_FLAG; - } - if (cpu_state.abrt) return; cr0 |= 8; @@ -2654,6 +2654,17 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) return; } + if (optype==JMP || optype==CALL || 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); + } + if (cpu_state.abrt) return; + if (optype==IRET) flags&=~NT_FLAG; // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); @@ -2675,15 +2686,22 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) writememw(tr.base,0x24,CS); writememw(tr.base,0x26,SS); writememw(tr.base,0x28,DS); - - if (optype==JMP || optype==CALL || optype==OPTYPE_INT) + + if (optype==JMP || optype==IRET) { - if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); - else tempw=readmemw(gdt.base,(seg&~7)+4); + 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,(seg&~7)+4,tempw); - else writememw(gdt.base,(seg&~7)+4,tempw); + tempw&=~0x200; + if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); + else writememw(gdt.base,(tr.seg&~7)+4,tempw); + } + if (cpu_state.abrt) return; + + if (optype==OPTYPE_INT || optype==CALL) + { + writememw(base,0,tr.seg); + new_flags|=NT_FLAG; } if (cpu_state.abrt) return; @@ -2705,24 +2723,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) new_ss=readmemw(base,0x26); new_ds=readmemw(base,0x28); new_ldt=readmemw(base,0x2A); - - if (optype==JMP || optype==CALL || 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 (cpu_state.abrt) return; - - if (optype==OPTYPE_INT || optype==CALL) - { - writememw(base,0,tr.seg); - new_flags|=NT_FLAG; - } - if (cpu_state.abrt) return; msw |= 8; From 1d4c9ab4e8f57ce9596910d2ad100f2b61456eb3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 6 Jul 2017 20:26:48 +0100 Subject: [PATCH 0070/1050] More SCAT improvements. Patch from Greatpsycho. --- src/scat.c | 146 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 100 insertions(+), 46 deletions(-) diff --git a/src/scat.c b/src/scat.c index 10cdc6e..cedfa65 100644 --- a/src/scat.c +++ b/src/scat.c @@ -20,6 +20,9 @@ static mem_mapping_t scat_512k_clip_mapping; static mem_mapping_t scat_4000_9FFF_mapping[24]; static mem_mapping_t scat_A000_BFFF_mapping; +uint8_t scat_read(uint16_t port, void *priv); +void scat_write(uint16_t port, uint8_t val, void *priv); + void scat_shadow_state_update() { int i, val; @@ -136,6 +139,32 @@ uint32_t get_scat_addr(uint32_t addr, scat_t *p) return addr; } +void scat_set_global_EMS_state(int state) +{ + int i; + uint32_t base_addr, virt_addr; + + for(i=0; i<32; i++) + { + base_addr = (i + 16) << 14; + if(i >= 24) + base_addr += 0x30000; + if(state && (scat_stat[i].regs_2x9 & 0x80)) + { + virt_addr = get_scat_addr(base_addr, &scat_stat[i]); + if(i < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[i]); + mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); + mem_mapping_enable(&scat_mapping[i]); + } + else + { + mem_mapping_set_exec(&scat_mapping[i], ram + base_addr); + mem_mapping_disable(&scat_mapping[i]); + if(i < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + } + } +} + void scat_write(uint16_t port, uint8_t val, void *priv) { uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index; @@ -152,7 +181,28 @@ void scat_write(uint16_t port, uint8_t val, void *priv) { case SCAT_CLOCK_CONTROL: case SCAT_PERIPHERAL_CONTROL: + scat_reg_valid = 1; + break; case SCAT_EMS_CONTROL: + if(val & 0x40) + { + if(val & 1) + { + io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + } + else + { + io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + } + } + else + { + io_removehandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_removehandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + } + scat_set_global_EMS_state(val & 0x80); scat_reg_valid = 1; break; case SCAT_POWER_MANAGEMENT: @@ -204,7 +254,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_regs[scat_index] = val; if (scat_shadow_update) scat_shadow_state_update(); - pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); +// pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); break; case 0x92: @@ -224,11 +274,11 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x208: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// 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; - if(scat_stat[index].regs_2x9 & 0x80) + if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { flushmmucache(); } @@ -237,29 +287,32 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x209: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// 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_2x9 = val; base_addr = (index + 16) << 14; if(index >= 24) base_addr += 0x30000; - if (val & 0x80) + if (scat_regs[SCAT_EMS_CONTROL] & 0x80) { - virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - mem_mapping_enable(&scat_mapping[index]); - pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + if (val & 0x80) + { + virt_addr = get_scat_addr(base_addr, &scat_stat[index]); + if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); + mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + mem_mapping_enable(&scat_mapping[index]); +// pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + } + else + { + mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); + mem_mapping_disable(&scat_mapping[index]); + if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); +// pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); + } + flushmmucache(); } - else - { - mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_mapping[index]); - if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); - pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); - } - flushmmucache(); if (scat_ems_reg_2xA & 0x80) { @@ -270,7 +323,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x20A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); scat_ems_reg_2xA = val; } break; @@ -278,11 +331,11 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// 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; - if(scat_stat[index].regs_2x9 & 0x80) + if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { flushmmucache(); } @@ -291,29 +344,32 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// 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_2x9 = val; base_addr = (index + 16) << 14; if (index >= 24) base_addr += 0x30000; - if (val & 0x80) + if (scat_regs[SCAT_EMS_CONTROL] & 0x80) { - virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - mem_mapping_enable(&scat_mapping[index]); - pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + if (val & 0x80) + { + virt_addr = get_scat_addr(base_addr, &scat_stat[index]); + if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); + mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + mem_mapping_enable(&scat_mapping[index]); + pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + } + else + { + mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); + mem_mapping_disable(&scat_mapping[index]); + if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); + pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); + } + flushmmucache(); } - else - { - mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_mapping[index]); - if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); - pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); - } - flushmmucache(); if (scat_ems_reg_2xA & 0x80) { @@ -324,7 +380,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x21A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); +// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); scat_ems_reg_2xA = val; } break; @@ -349,7 +405,7 @@ uint8_t scat_read(uint16_t port, void *priv) val = scat_regs[scat_index]; break; } - pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); +// pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); break; case 0x92: @@ -359,7 +415,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x208: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x8; } @@ -367,7 +423,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x209: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x9; } @@ -375,7 +431,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x20A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); val = scat_ems_reg_2xA; } break; @@ -383,7 +439,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x218: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x8; } @@ -391,7 +447,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x219: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; val = scat_stat[index].regs_2x9; } @@ -399,7 +455,7 @@ uint8_t scat_read(uint16_t port, void *priv) case 0x21A: if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) { - pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); +// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); val = scat_ems_reg_2xA; } break; @@ -434,8 +490,6 @@ void scat_init() io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0208, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0218, 0x0003, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); for (i = 0; i < 256; i++) { From 807b710a5d6c14da16226b3700570211522228b9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 6 Jul 2017 21:25:10 +0100 Subject: [PATCH 0071/1050] Improvements to path handling. Patch from bit. --- src/808x.c | 3 +- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/allegro-gui-config-sel.c | 13 +-- src/allegro-main.c | 80 +++++++++++++++- src/config.c | 14 ++- src/config.h | 3 + src/hdd_esdi.c | 4 +- src/ibm.h | 5 - src/intel_flash.c | 6 +- src/mem.c | 178 +++++++++++++++++------------------ src/mfm_xebec.c | 8 +- src/nvr.c | 140 ++++++++++++++------------- src/nvr.h | 2 + src/pc.c | 85 +++++++++-------- src/ps1.c | 8 +- src/ps2_nvr.c | 5 +- src/rom.c | 25 +++-- src/sound_adlibgold.c | 5 +- src/sound_emu8k.c | 4 +- src/sound_sb.c | 2 +- src/tandy_eeprom.c | 9 +- src/tandy_rom.c | 4 +- src/vid_ati18800.c | 4 +- src/vid_ati28800.c | 4 +- src/vid_ati_mach64.c | 8 +- src/vid_cl5429.c | 4 +- src/vid_ega.c | 4 +- src/vid_et4000.c | 4 +- src/vid_et4000w32.c | 4 +- src/vid_genius.c | 2 +- src/vid_oti067.c | 6 +- src/vid_paradise.c | 8 +- src/vid_pc1640.c | 2 +- src/vid_s3.c | 16 ++-- src/vid_s3_virge.c | 8 +- src/vid_tgui9440.c | 4 +- src/vid_tvga.c | 4 +- src/vid_vga.c | 4 +- src/win-config_sel.c | 19 ++-- src/win.c | 38 +++++--- src/wx-config_sel.c | 28 +++--- src/wx-main.cc | 8 +- src/wx-sdl2.c | 51 ++++++++-- src/wx-utils.cc | 57 +++++++++++ src/wx-utils.h | 7 ++ src/x86seg.c | 33 ++++--- src/xtide.c | 8 +- 55 files changed, 588 insertions(+), 368 deletions(-) diff --git a/src/808x.c b/src/808x.c index a78b52c..2f71e08 100644 --- a/src/808x.c +++ b/src/808x.c @@ -23,6 +23,7 @@ #include "timer.h" #include "x86.h" #include "x87.h" +#include "paths.h" int xt_cpu_multi; int nmi = 0; @@ -507,7 +508,7 @@ void dumpregs() // return; // savenvr(); // return; -chdir(pcempath); + chdir(logs_path); nopageerrors=1; /* f=fopen("rram3.dmp","wb"); for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); diff --git a/src/Makefile.am b/src/Makefile.am index 2ab6bbc..b5c1e19 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.c sis496.c sound.c \ +opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 40a175b..5a82431 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -11,7 +11,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index c0cb649..fe9abe5 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -9,7 +9,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 1234299..1d55536 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -10,7 +10,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index d4f5305..15c98c1 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -9,7 +9,7 @@ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 9e34408..7c8259e 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index bd47f6a..60feb55 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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 \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 1e108c4..2454ecb 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index a93c541..5e05dc1 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -9,7 +9,7 @@ dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/allegro-gui-config-sel.c b/src/allegro-gui-config-sel.c index 5f2b7ff..708889b 100644 --- a/src/allegro-gui-config-sel.c +++ b/src/allegro-gui-config-sel.c @@ -3,6 +3,7 @@ #include "allegro-main.h" #include "allegro-gui.h" #include "config.h" +#include "paths.h" #undef printf typedef struct config_t { @@ -83,7 +84,7 @@ static int new_proc(int msg, DIALOG *d, int c) if (c == 1) { - sprintf(config_file_default, "%sconfigs/%s.cfg", pcempath, config_name); + sprintf(config_file_default, "%s%s.cfg", configs_path, config_name); c = settings_configure(); free_configs(); populate_configs(); @@ -106,7 +107,7 @@ static int config_proc(int msg, DIALOG *d, int c) if (name) { - sprintf(config_file_default, "%sconfigs/%s.cfg", pcempath, name); + sprintf(config_file_default, "%s%s.cfg", configs_path, name); loadconfig(NULL); return settings_configure(); } @@ -127,7 +128,7 @@ static int hdd_proc(int msg, DIALOG *d, int c) if (name) { - sprintf(config_file_default, "%sconfigs/%s.cfg", pcempath, name); + sprintf(config_file_default, "%s%s.cfg", configs_path, name); loadconfig(NULL); return disc_hdconf(); } @@ -165,8 +166,8 @@ static void populate_configs() char cfg[512]; config_t *config = NULL; - strcpy(cfg, pcempath); - strcat(cfg, "/configs/*.cfg"); + strcpy(cfg, configs_path); + strcat(cfg, "*.cfg"); printf("cfg %s\n", cfg); if (al_findfirst(cfg, &info, FA_ALL)) return; @@ -247,7 +248,7 @@ int config_sel() if (name) { - sprintf(config_file_default, "%sconfigs/%s.cfg", pcempath, name); + sprintf(config_file_default, "%s%s.cfg", configs_path, name); pclog("config_file_default=%s\n", config_file_default); free_configs(); return 0; diff --git a/src/allegro-main.c b/src/allegro-main.c index 47098f6..2d60650 100644 --- a/src/allegro-main.c +++ b/src/allegro-main.c @@ -14,7 +14,13 @@ #include "plat-mouse.h" #include "sound.h" #include "video.h" - +#include +#include +#include +#include +#include +#include "paths.h" + #undef printf int has_been_inited = 0; @@ -60,10 +66,41 @@ uint64_t timer_read() return 0; } +int dir_exists(char *path) +{ + DIR *dir = opendir(path); + if (dir) + { + closedir(dir); + return 1; + } + return 0; +} + +int create_dir(char *path) +{ + if (!mkdir(path, 0755)) + return 1; + return 0; +} + +void get_pcem_path(char *s, int size) +{ + struct passwd *pw = getpwuid(getuid()); + + strncpy(s, pw->pw_dir, size-10); + append_slash(s, size); + strcat(s, ".pcem/"); + //get_executable_name(s, size); +} + int main(int argc, char *argv[]) { + char s[512]; int frames = 0; int c; + FILE *f; + allegro_init(); allegro_video_init(); install_timer(); @@ -71,12 +108,51 @@ int main(int argc, char *argv[]) install_int_ex(onesec, BPS_TO_TIMER(1)); midi_init(); - getpath(); + paths_init(); + /* create directories if they don't exist */ + if (!dir_exists(pcem_path)) { + if (!create_dir(pcem_path)) + return 0; + append_filename(s, pcem_path, "configs", 511); + if (!dir_exists(s) && !create_dir(s)) + return 0; + + append_filename(s, pcem_path, "roms", 511); + if (!dir_exists(s) && !create_dir(s)) + return 0; + + append_filename(s, pcem_path, "nvr", 511); + if (!dir_exists(s) && !create_dir(s)) + return 0; + + append_filename(s, pcem_path, "logs", 511); + if (!dir_exists(s) && !create_dir(s)) + return 0; + } + + /* set up default paths */ + sprintf(s, "%s%s%c%s", pcem_path, "roms/", get_path_separator(), "/usr/share/pcem/roms/"); + set_default_roms_paths(s); + append_filename(s, pcem_path, "nvr/", 511); + set_default_nvr_path(s); + append_filename(s, pcem_path, "configs/", 511); + set_default_configs_path(s); + append_filename(s, pcem_path, "logs/", 511); + set_default_logs_path(s); + sound_init(); initpc(argc, argv); + /* check if cfg exists, and if not create it */ + append_filename(s, pcem_path, "pcem.cfg", 511); + f = fopen(s, "r"); + if (f) + fclose(f); + else + saveconfig(NULL); + keyboard_init(); mouse_init(); joystick_init(); diff --git a/src/config.c b/src/config.c index ca2a184..48c917a 100644 --- a/src/config.c +++ b/src/config.c @@ -190,8 +190,6 @@ void config_load(int is_global, char *fn) } fclose(f); - - config_dump(is_global); } @@ -353,6 +351,18 @@ void append_filename(char *dest, char *s1, char *s2, int size) sprintf(dest, "%s%s", s1, s2); } +void append_slash(char *s, int size) +{ + int c = strlen(s)-1; + if (s[c] != '/' && s[c] != '\\') + { + if (c < size-2) + strcat(s, "/"); + else + s[c] = '/'; + } +} + void put_backslash(char *s) { int c = strlen(s) - 1; diff --git a/src/config.h b/src/config.h index 23b0a48..174c437 100644 --- a/src/config.h +++ b/src/config.h @@ -3,8 +3,11 @@ char *config_get_string(int is_global, char *head, char *name, char *def); void config_set_int(int is_global, char *head, char *name, int val); void config_set_string(int is_global, char *head, char *name, char *val); +void add_config_callback(void (*loadconfig)(), void (*saveconfig)(), void (*onloaded)()); + char *get_filename(char *s); void append_filename(char *dest, char *s1, char *s2, int size); +void append_slash(char *s, int size); void put_backslash(char *s); char *get_extension(char *s); diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 6226425..1b32b1b 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -822,7 +822,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, "90x8970.bin", "90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&esdi->bios_rom.mapping); hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]); @@ -854,7 +854,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("90x8969.bin") && rom_present("90x8970.bin"); } device_t hdd_esdi_device = diff --git a/src/ibm.h b/src/ibm.h index 47ba64b..81e5ae4 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -503,8 +503,6 @@ int gated,speakval,speakon; #define SND_WSS 9 /*Windows Sound System*/ #define SND_PAS16 10 /*Pro Audio Spectrum 16*/ -char pcempath[512]; - /*Hard disc*/ @@ -561,8 +559,6 @@ void resetpc_cad(); extern int start_in_fullscreen; extern int window_w, window_h, window_x, window_y, window_remember; -void get_executable_name(char *s, int size); - void startblit(); void endblit(); @@ -578,6 +574,5 @@ void resetpchard(); void speedchanged(); void saveconfig(char *fn); -void getpath(); #define UNUSED(x) (void)x diff --git a/src/intel_flash.c b/src/intel_flash.c index 304e873..9846b93 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -162,13 +162,13 @@ void *intel_flash_init(uint8_t type) switch(romset) { case ROM_REVENGE: - strcpy(flash_path, "roms/revenge/"); + strcpy(flash_path, "revenge/"); break; case ROM_ENDEAVOR: - strcpy(flash_path, "roms/endeavor/"); + strcpy(flash_path, "endeavor/"); break; case ROM_430VX: - strcpy(flash_path, "roms/430vx/"); + strcpy(flash_path, "430vx/"); break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); diff --git a/src/mem.c b/src/mem.c index e1ae279..a9eb585 100644 --- a/src/mem.c +++ b/src/mem.c @@ -60,7 +60,7 @@ uint8_t romext[32768]; static void mem_load_atide115_bios() { FILE *f; - f=romfopen("roms/ide_at_1_1_5.bin","rb"); + f=romfopen("ide_at_1_1_5.bin","rb"); // is486=0; if (f) @@ -114,9 +114,9 @@ int loadbios() FILE *f=NULL,*ff=NULL; int c; - loadfont("roms/mda.rom", 0); - loadfont("roms/wy700.rom", 3); - loadfont("roms/8x12.bin", 4); + loadfont("mda.rom", 0); + loadfont("wy700.rom", 3); + loadfont("8x12.bin", 4); biosmask = 0xffff; @@ -130,8 +130,8 @@ int loadbios() switch (romset) { case ROM_PC1512: - f=romfopen("roms/pc1512/40043.v1","rb"); - ff=romfopen("roms/pc1512/40044.v1","rb"); + f=romfopen("pc1512/40043.v1","rb"); + ff=romfopen("pc1512/40044.v1","rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -140,11 +140,11 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("roms/pc1512/40078.ic127", 2); + loadfont("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("pc1640/40044.v3","rb"); + ff=romfopen("pc1640/40043.v3","rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -153,13 +153,13 @@ int loadbios() } fclose(ff); fclose(f); - f=romfopen("roms/pc1640/40100","rb"); + f=romfopen("pc1640/40100","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("pc200/pc20v2.1","rb"); + ff=romfopen("pc200/pc20v2.0","rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -168,24 +168,24 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("roms/pc200/40109.bin", 1); + loadfont("pc200/40109.bin", 1); return 1; case ROM_TANDY: - f=romfopen("roms/tandy/tandy1t1.020","rb"); + f=romfopen("tandy/tandy1t1.020","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("tandy1000hx/v020000.u12", "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("tandy1000sl2/8079047.hu1" ,"rb"); + ff = romfopen("tandy1000sl2/8079048.hu2","rb"); if (!f || !ff) break; fseek(f, 0x30000/2, SEEK_SET); fseek(ff, 0x30000/2, SEEK_SET); @@ -206,11 +206,11 @@ int loadbios() fclose(f); break;*/ case ROM_IBMXT: - f=romfopen("roms/ibmxt/xt.rom","rb"); + f=romfopen("ibmxt/xt.rom","rb"); if (!f) { - f = romfopen("roms/ibmxt/5000027.u19", "rb"); - ff = romfopen("roms/ibmxt/1501512.u18","rb"); + f = romfopen("ibmxt/5000027.u19", "rb"); + ff = romfopen("ibmxt/1501512.u18","rb"); if (!f || !ff) break; fread(rom, 0x8000, 1, f); fread(rom + 0x8000, 0x8000, 1, ff); @@ -227,27 +227,27 @@ int loadbios() break; case ROM_IBMPCJR: - f = romfopen("roms/ibmpcjr/bios.rom","rb"); + f = romfopen("ibmpcjr/bios.rom","rb"); if (!f) break; fread(rom, 0x10000, 1, f); fclose(f); return 1; case ROM_GENXT: - f=romfopen("roms/genxt/pcxt.rom","rb"); + f=romfopen("genxt/pcxt.rom","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("dtk/dtk_erso_2.42_2764.bin","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("olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); + ff = romfopen("olivetti_m24/olivetti_m24_version_1.43_high.bin","rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x4000; c += 2) { @@ -259,8 +259,8 @@ int loadbios() return 1; case ROM_PC2086: - f = romfopen("roms/pc2086/40179.ic129" ,"rb"); - ff = romfopen("roms/pc2086/40180.ic132","rb"); + f = romfopen("pc2086/40179.ic129" ,"rb"); + ff = romfopen("pc2086/40180.ic132","rb"); if (!f || !ff) break; pclog("Loading BIOS\n"); for (c = 0x0000; c < 0x4000; c += 2) @@ -271,32 +271,32 @@ 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("pc2086/40186.ic171", "rb"); if (!f) break; fclose(f); biosmask = 0x3fff; return 1; case ROM_PC3086: - f = romfopen("roms/pc3086/fc00.bin" ,"rb"); + f = romfopen("pc3086/fc00.bin" ,"rb"); if (!f) break; fread(rom, 0x4000, 1, f); fclose(f); - f = romfopen("roms/pc3086/c000.bin", "rb"); + f = romfopen("pc3086/c000.bin", "rb"); if (!f) break; fclose(f); biosmask = 0x3fff; return 1; case ROM_IBMAT: -/* f=romfopen("roms/amic206.bin","rb"); +/* f=romfopen("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("ibmat/62x0820.u27", "rb"); + ff =romfopen("ibmat/62x0821.u47", "rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -307,8 +307,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("cmdpc30/commodore pc 30 iii even.bin", "rb"); + ff = romfopen("cmdpc30/commodore pc 30 iii odd.bin", "rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x8000; c += 2) { @@ -320,8 +320,8 @@ int loadbios() biosmask = 0x7fff; return 1; case ROM_DELL200: - f=romfopen("roms/dells200/dell0.bin","rb"); - ff=romfopen("roms/dells200/dell1.bin","rb"); + f=romfopen("dells200/dell0.bin","rb"); + ff=romfopen("dells200/dell1.bin","rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -332,46 +332,46 @@ int loadbios() fclose(f); return 1; /* case ROM_IBMAT386: - f=romfopen("roms/at386/at386.bin","rb"); + f=romfopen("at386/at386.bin","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1;*/ case ROM_AMI386SX: -// f=romfopen("roms/at386/at386.bin","rb"); - f=romfopen("roms/ami386/ami386.bin","rb"); +// f=romfopen("at386/at386.bin","rb"); + f=romfopen("ami386/ami386.bin","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("ami386dx/opt495sx.ami","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("mr386dx/opt495sx.mr","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_ACER386: - f=romfopen("roms/acer386/acer386.bin","rb"); + f=romfopen("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"); + f=romfopen("acer386/oti067.bin","rb"); if (!f) break; fclose(f); return 1; case ROM_AMI286: - f=romfopen("roms/ami286/amic206.bin","rb"); + f=romfopen("ami286/amic206.bin","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); @@ -379,7 +379,7 @@ int loadbios() return 1; case ROM_AWARD286: - f=romfopen("roms/award286/award.bin","rb"); + f=romfopen("award286/award.bin","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); @@ -387,7 +387,7 @@ int loadbios() case ROM_EUROPC: // return 0; - f=romfopen("roms/europc/50145","rb"); + f=romfopen("europc/50145","rb"); if (!f) break; fread(rom+0x8000,32768,1,f); fclose(f); @@ -395,18 +395,18 @@ int loadbios() return 1; case ROM_IBMPC: - f=romfopen("roms/ibmpc/pc102782.bin","rb"); + f=romfopen("ibmpc/pc102782.bin","rb"); if (!f) break; // f=fopen("pc081682.bin","rb"); fread(rom+0xE000,8192,1,f); fclose(f); - if (!mem_load_basic("roms/ibmpc")) + if (!mem_load_basic("ibmpc")) break; return 1; case ROM_MEGAPC: - f = romfopen("roms/megapc/41651-bios lo.u18", "rb"); - ff = romfopen("roms/megapc/211253-bios hi.u19", "rb"); + f = romfopen("megapc/41651-bios lo.u18", "rb"); + ff = romfopen("megapc/211253-bios hi.u19", "rb"); if (!f || !ff) break; fseek(f, 0x8000, SEEK_SET); fseek(ff, 0x8000, SEEK_SET); @@ -420,7 +420,7 @@ int loadbios() return 1; case ROM_AMI486: - f=romfopen("roms/ami486/ami486.bin","rb"); + f=romfopen("ami486/ami486.bin","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); @@ -428,8 +428,8 @@ int loadbios() return 1; case ROM_WIN486: -// f=romfopen("roms/win486/win486.bin","rb"); - f=romfopen("roms/win486/ali1429g.amw","rb"); +// f=romfopen("win486/win486.bin","rb"); + f=romfopen("win486/ali1429g.amw","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); @@ -437,7 +437,7 @@ int loadbios() return 1; case ROM_PCI486: - f=romfopen("roms/hot-433/hot-433.ami","rb"); + f=romfopen("hot-433/hot-433.ami","rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -446,7 +446,7 @@ int loadbios() return 1; case ROM_SIS496: - f = romfopen("roms/sis496/sis496-1.awa", "rb"); + f = romfopen("sis496/sis496-1.awa", "rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -455,10 +455,10 @@ 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"); +// f = romfopen("430vx/ga586atv.bin", "rb"); +// f = fopen("430vx/vx29.bin", "rb"); + f = romfopen("430vx/55xwuq0e.bin", "rb"); +// f=romfopen("430vx/430vx","rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -467,12 +467,12 @@ int loadbios() return 1; case ROM_REVENGE: - f = romfopen("roms/revenge/1009af2_.bio", "rb"); + f = romfopen("revenge/1009af2_.bio", "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("revenge/1009af2_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xc000, 1, f); @@ -481,12 +481,12 @@ int loadbios() //is486=1; return 1; case ROM_ENDEAVOR: - f = romfopen("roms/endeavor/1006cb0_.bio", "rb"); + f = romfopen("endeavor/1006cb0_.bio", "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("endeavor/1006cb0_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xd000, 1, f); @@ -497,8 +497,8 @@ int loadbios() 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"); + f=romfopen("ibmps1es/ibm_1057757_24-05-90.bin","rb"); + ff=romfopen("ibmps1es/ibm_1057757_29-15-90.bin","rb"); fseek(f, 0x10000, SEEK_SET); fseek(ff, 0x10000, SEEK_SET); if (!f || !ff) break; @@ -511,7 +511,7 @@ int loadbios() fclose(f); #endif //#if 0 - f = romfopen("roms/ibmps1es/f80000.bin", "rb"); + f = romfopen("ibmps1es/f80000.bin", "rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); fread(rom, 0x20000, 1, f); @@ -522,7 +522,7 @@ int loadbios() return 1; case ROM_IBMPS1_2121: - f = romfopen("roms/ibmps1_2121/fc0000.bin", "rb"); + f = romfopen("ibmps1_2121/fc0000.bin", "rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); fread(rom, 0x20000, 1, f); @@ -531,8 +531,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("deskpro386/109592-005.u11.bin","rb"); + ff=romfopen("deskpro386/109591-005.u13.bin","rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x8000; c += 2) { @@ -545,33 +545,33 @@ int loadbios() return 1; case ROM_AMIXT: - f = romfopen("roms/amixt/ami_8088_bios_31jan89.bin", "rb"); + f = romfopen("amixt/ami_8088_bios_31jan89.bin", "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("ltxt/27c64.bin", "rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (!mem_load_basic("roms/ltxt")) + if (!mem_load_basic("ltxt")) break; return 1; case ROM_LXT3: - f = romfopen("roms/lxt3/27c64d.bin", "rb"); + f = romfopen("lxt3/27c64d.bin", "rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (!mem_load_basic("roms/lxt3")) + if (!mem_load_basic("lxt3")) break; return 1; case ROM_PX386: /*Phoenix 80386 BIOS*/ - f=romfopen("roms/px386/3iip001l.bin","rb"); - ff=romfopen("roms/px386/3iip001h.bin","rb"); + f=romfopen("px386/3iip001l.bin","rb"); + ff=romfopen("px386/3iip001h.bin","rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x10000; c += 2) { @@ -583,28 +583,28 @@ int loadbios() return 1; case ROM_DTK386: /*Uses NEAT chipset*/ - f = romfopen("roms/dtk386/3cto001.bin", "rb"); + f = romfopen("dtk386/3cto001.bin", "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("pxxt/000p001.bin", "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("jukopc/000o001.bin", "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("ibmps2_m30_286/33f5381a.bin", "rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -612,8 +612,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("i8550021/90x7423.zm14","rb"); + ff=romfopen("i8550021/90x7426.zm16","rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x10000; c += 2) { @@ -622,8 +622,8 @@ int loadbios() } fclose(ff); fclose(f); - f=romfopen("roms/i8550021/90x7420.zm13","rb"); - ff=romfopen("roms/i8550021/90x7429.zm18","rb"); + f=romfopen("i8550021/90x7420.zm13","rb"); + ff=romfopen("i8550021/90x7429.zm18","rb"); if (!f || !ff) break; for (c = 0x10000; c < 0x20000; c += 2) { @@ -636,8 +636,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("i8555081/33f8146.zm41","rb"); + ff=romfopen("i8555081/33f8145.zm40","rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x20000; c += 2) { @@ -650,8 +650,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("i8580111/15f6637.bin","rb"); + ff=romfopen("i8580111/15f6639.bin","rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x20000; c += 2) { diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index 9cfdf23..7c185f2 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -825,7 +825,7 @@ static void *xebec_init() hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); 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, "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); @@ -846,7 +846,7 @@ static void xebec_close(void *p) static int xebec_available() { - return rom_present("roms/ibm_xebec_62x0822_1985.bin"); + return rom_present("ibm_xebec_62x0822_1985.bin"); } device_t mfm_xebec_device = @@ -876,7 +876,7 @@ static void *dtc_5150x_init() xebec->drives[1].cfg_cyl = xebec->drives[1].hdd_file.tracks; xebec->drives[1].cfg_hpc = xebec->drives[1].hdd_file.hpc; - rom_init(&xebec->bios_rom, "roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, "dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); @@ -886,7 +886,7 @@ static void *dtc_5150x_init() } static int dtc_5150x_available() { - return rom_present("roms/dtc_cxd21a.bin"); + return rom_present("dtc_cxd21a.bin"); } device_t dtc_5150x_device = diff --git a/src/nvr.c b/src/nvr.c index 419e7b9..33df4b6 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -5,6 +5,8 @@ #include "pic.h" #include "timer.h" #include "rtc.h" +#include "paths.h" +#include "config.h" int oldromset; int nvrmask=63; @@ -17,6 +19,16 @@ static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; static int rtctime; +FILE *nvrfopen(char *fn, char *mode) +{ + char s[512]; + + strcpy(s, nvr_path); + put_backslash(s); + strcat(s, fn); + return fopen(s, mode); +} + void getnvrtime() { time_get(nvrram); @@ -200,38 +212,38 @@ void loadnvr() oldromset=romset; switch (romset) { - case ROM_PC1512: f = romfopen("nvr/pc1512.nvr", "rb"); break; - case ROM_PC1640: f = romfopen("nvr/pc1640.nvr", "rb"); break; - case ROM_PC200: f = romfopen("nvr/pc200.nvr", "rb"); break; - case ROM_PC2086: f = romfopen("nvr/pc2086.nvr", "rb"); break; - case ROM_PC3086: f = romfopen("nvr/pc3086.nvr", "rb"); break; - case ROM_IBMAT: f = romfopen("nvr/at.nvr", "rb"); break; - case ROM_IBMPS1_2011: f = romfopen("nvr/ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break; - case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M30_286: f = romfopen("nvr/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/cmdpc30.nvr", "rb"); nvrmask = 127; break; - case ROM_AMI286: f = romfopen("nvr/ami286.nvr", "rb"); nvrmask = 127; break; - case ROM_AWARD286: f = romfopen("nvr/award286.nvr", "rb"); nvrmask = 127; break; - case ROM_DELL200: f = romfopen("nvr/dell200.nvr", "rb"); nvrmask = 127; break; - case ROM_IBMAT386: f = romfopen("nvr/at386.nvr", "rb"); nvrmask = 127; break; - case ROM_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "rb"); break; - case ROM_ACER386: f = romfopen("nvr/acer386.nvr", "rb"); nvrmask = 127; break; - case ROM_MEGAPC: f = romfopen("nvr/megapc.nvr", "rb"); nvrmask = 127; break; - case ROM_AMI386SX: f = romfopen("nvr/ami386.nvr", "rb"); nvrmask = 127; break; - case ROM_AMI486: f = romfopen("nvr/ami486.nvr", "rb"); nvrmask = 127; break; - case ROM_WIN486: f = romfopen("nvr/win486.nvr", "rb"); nvrmask = 127; break; - case ROM_PCI486: f = romfopen("nvr/hot-433.nvr", "rb"); nvrmask = 127; break; - case ROM_SIS496: f = romfopen("nvr/sis496.nvr", "rb"); nvrmask = 127; break; - case ROM_430VX: f = romfopen("nvr/430vx.nvr", "rb"); nvrmask = 127; break; - case ROM_REVENGE: f = romfopen("nvr/revenge.nvr", "rb"); nvrmask = 127; break; - case ROM_ENDEAVOR: f = romfopen("nvr/endeavor.nvr", "rb"); nvrmask = 127; break; - case ROM_PX386: f = romfopen("nvr/px386.nvr", "rb"); nvrmask = 127; break; - case ROM_DTK386: f = romfopen("nvr/dtk386.nvr", "rb"); nvrmask = 127; break; - case ROM_MR386DX_OPTI495: f = romfopen("nvr/mr386dx_opti495.nvr", "rb"); nvrmask = 127; break; - case ROM_AMI386DX_OPTI495: f = romfopen("nvr/ami386dx_opti495.nvr", "rb"); nvrmask = 127; break; + case ROM_PC1512: f = nvrfopen("pc1512.nvr", "rb"); break; + case ROM_PC1640: f = nvrfopen("pc1640.nvr", "rb"); break; + case ROM_PC200: f = nvrfopen("pc200.nvr", "rb"); break; + case ROM_PC2086: f = nvrfopen("pc2086.nvr", "rb"); break; + case ROM_PC3086: f = nvrfopen("pc3086.nvr", "rb"); break; + case ROM_IBMAT: f = nvrfopen("at.nvr", "rb"); break; + case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break; + case ROM_IBMPS1_2121: f = nvrfopen("ibmps1_2121.nvr", "rb"); nvrmask = 127; break; + case ROM_IBMPS2_M30_286: f = nvrfopen("ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */break; + case ROM_IBMPS2_M50: f = nvrfopen("ibmps2_m50.nvr", "rb"); break; + case ROM_IBMPS2_M55SX: f = nvrfopen("ibmps2_m55sx.nvr", "rb"); break; + case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "rb"); break; + case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break; + case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); nvrmask = 127; break; + case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break; + case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); nvrmask = 127; break; + case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); nvrmask = 127; break; + case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); break; + case ROM_ACER386: f = nvrfopen("acer386.nvr", "rb"); nvrmask = 127; break; + case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "rb"); nvrmask = 127; break; + case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "rb"); nvrmask = 127; break; + case ROM_AMI486: f = nvrfopen("ami486.nvr", "rb"); nvrmask = 127; break; + case ROM_WIN486: f = nvrfopen("win486.nvr", "rb"); nvrmask = 127; break; + case ROM_PCI486: f = nvrfopen("hot-433.nvr", "rb"); nvrmask = 127; break; + case ROM_SIS496: f = nvrfopen("sis496.nvr", "rb"); nvrmask = 127; break; + case ROM_430VX: f = nvrfopen("430vx.nvr", "rb"); nvrmask = 127; break; + case ROM_REVENGE: f = nvrfopen("revenge.nvr", "rb"); nvrmask = 127; break; + case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "rb"); nvrmask = 127; break; + case ROM_PX386: f = nvrfopen("px386.nvr", "rb"); nvrmask = 127; break; + case ROM_DTK386: f = nvrfopen("dtk386.nvr", "rb"); nvrmask = 127; break; + case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "rb"); nvrmask = 127; break; + case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "rb"); nvrmask = 127; break; default: return; } if (!f) @@ -263,38 +275,38 @@ void savenvr() FILE *f; switch (oldromset) { - case ROM_PC1512: f = romfopen("nvr/pc1512.nvr", "wb"); break; - case ROM_PC1640: f = romfopen("nvr/pc1640.nvr", "wb"); break; - case ROM_PC200: f = romfopen("nvr/pc200.nvr", "wb"); break; - case ROM_PC2086: f = romfopen("nvr/pc2086.nvr", "wb"); break; - case ROM_PC3086: f = romfopen("nvr/pc3086.nvr", "wb"); break; - case ROM_IBMAT: f = romfopen("nvr/at.nvr", "wb"); break; - case ROM_IBMPS1_2011: f = romfopen("nvr/ibmps1_2011.nvr", "wb"); break; - case ROM_IBMPS1_2121: f = romfopen("nvr/ibmps1_2121.nvr", "wb"); break; - case ROM_IBMPS2_M30_286: f = romfopen("nvr/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/cmdpc30.nvr", "wb"); break; - case ROM_AMI286: f = romfopen("nvr/ami286.nvr", "wb"); break; - case ROM_AWARD286: f = romfopen("nvr/award286.nvr", "wb"); break; - case ROM_DELL200: f = romfopen("nvr/dell200.nvr", "wb"); break; - case ROM_IBMAT386: f = romfopen("nvr/at386.nvr", "wb"); break; - case ROM_DESKPRO_386: f = romfopen("nvr/deskpro386.nvr", "wb"); break; - case ROM_ACER386: f = romfopen("nvr/acer386.nvr", "wb"); break; - case ROM_MEGAPC: f = romfopen("nvr/megapc.nvr", "wb"); break; - case ROM_AMI386SX: f = romfopen("nvr/ami386.nvr", "wb"); break; - case ROM_AMI486: f = romfopen("nvr/ami486.nvr", "wb"); break; - case ROM_WIN486: f = romfopen("nvr/win486.nvr", "wb"); break; - case ROM_PCI486: f = romfopen("nvr/hot-433.nvr", "wb"); break; - case ROM_SIS496: f = romfopen("nvr/sis496.nvr", "wb"); break; - case ROM_430VX: f = romfopen("nvr/430vx.nvr", "wb"); break; - case ROM_REVENGE: f = romfopen("nvr/revenge.nvr", "wb"); break; - case ROM_ENDEAVOR: f = romfopen("nvr/endeavor.nvr", "wb"); break; - case ROM_PX386: f = romfopen("nvr/px386.nvr", "wb"); break; - case ROM_DTK386: f = romfopen("nvr/dtk386.nvr", "wb"); break; - case ROM_MR386DX_OPTI495: f = romfopen("nvr/mr386dx_opti495.nvr", "wb"); break; - case ROM_AMI386DX_OPTI495: f = romfopen("nvr/ami386dx_opti495.nvr", "wb"); break; + case ROM_PC1512: f = nvrfopen("pc1512.nvr", "wb"); break; + case ROM_PC1640: f = nvrfopen("pc1640.nvr", "wb"); break; + case ROM_PC200: f = nvrfopen("pc200.nvr", "wb"); break; + case ROM_PC2086: f = nvrfopen("pc2086.nvr", "wb"); break; + case ROM_PC3086: f = nvrfopen("pc3086.nvr", "wb"); break; + case ROM_IBMAT: f = nvrfopen("at.nvr", "wb"); break; + case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "wb"); break; + case ROM_IBMPS1_2121: f = nvrfopen("ibmps1_2121.nvr", "wb"); break; + case ROM_IBMPS2_M30_286: f = nvrfopen("ibmps2_m30_286.nvr", "wb"); break; + case ROM_IBMPS2_M50: f = nvrfopen("ibmps2_m50.nvr", "wb"); break; + case ROM_IBMPS2_M55SX: f = nvrfopen("ibmps2_m55sx.nvr", "wb"); break; + case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "wb"); break; + case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "wb"); break; + case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); break; + case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break; + case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); break; + case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); break; + case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); break; + case ROM_ACER386: f = nvrfopen("acer386.nvr", "wb"); break; + case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "wb"); break; + case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "wb"); break; + case ROM_AMI486: f = nvrfopen("ami486.nvr", "wb"); break; + case ROM_WIN486: f = nvrfopen("win486.nvr", "wb"); break; + case ROM_PCI486: f = nvrfopen("hot-433.nvr", "wb"); break; + case ROM_SIS496: f = nvrfopen("sis496.nvr", "wb"); break; + case ROM_430VX: f = nvrfopen("430vx.nvr", "wb"); break; + case ROM_REVENGE: f = nvrfopen("revenge.nvr", "wb"); break; + case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "wb"); break; + case ROM_PX386: f = nvrfopen("px386.nvr", "wb"); break; + case ROM_DTK386: f = nvrfopen("dtk386.nvr", "wb"); break; + case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "wb"); break; + case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/nvr.h b/src/nvr.h index c04289f..1a60fdf 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -8,3 +8,5 @@ void loadnvr(); void savenvr(); void nvr_recalc(); + +FILE *nvrfopen(char *fn, char *mode); diff --git a/src/pc.c b/src/pc.c index 0e900ed..ac44c99 100644 --- a/src/pc.c +++ b/src/pc.c @@ -47,6 +47,7 @@ #include "amstrad.h" #include "hdd.h" #include "x86.h" +#include "paths.h" int window_w, window_h, window_x, window_y, window_remember; @@ -79,37 +80,47 @@ FILE *pclogf; void pclog(const char *format, ...) { #ifndef RELEASE_BUILD - char buf[1024]; - //return; - if (!pclogf) - pclogf=fopen("pclog.txt","wt"); -//return; - va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - fputs(buf,pclogf); -//fflush(pclogf); + char buf[1024]; + //return; + if (!pclogf) + { + strcpy(buf, logs_path); + put_backslash(buf); + strcat(buf, "pcem.log"); + pclogf=fopen(buf, "wt"); + } + //return; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fputs(buf,pclogf); + //fflush(pclogf); #endif } void fatal(const char *format, ...) { - char buf[256]; -// return; - if (!pclogf) - pclogf=fopen("pclog.txt","wt"); -//return; - va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - fputs(buf,pclogf); - fflush(pclogf); - savenvr(); - dumppic(); - dumpregs(); - exit(-1); + char buf[256]; + // return; + if (!pclogf) + { + strcpy(buf, logs_path); + put_backslash(buf); + strcat(buf, "pcem.log"); + pclogf=fopen(buf, "wt"); + } + //return; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fputs(buf,pclogf); + fflush(pclogf); + savenvr(); + dumppic(); + dumpregs(); + exit(-1); } uint8_t cgastat; @@ -205,16 +216,7 @@ void pc_reset() // video_init(); } #undef printf -void getpath() -{ - char *p; - - get_executable_name(pcempath,511); - pclog("executable_name = %s\n", pcempath); - p=get_filename(pcempath); - *p=0; - pclog("path = %s\n", pcempath); -} + void initpc(int argc, char *argv[]) { @@ -246,7 +248,7 @@ void initpc(int argc, char *argv[]) } } -// append_filename(config_file_default, pcempath, "pcem.cfg", 511); +// append_filename(config_file_default, pcempath, "pcem.cfg", 511); loadconfig(NULL); pclog("Config loaded\n"); @@ -613,7 +615,7 @@ void loadconfig(char *fn) char global_config_file[512]; char *p; - append_filename(global_config_file, pcempath, "pcem.cfg", 511); + append_filename(global_config_file, pcem_path, "pcem.cfg", 511); config_load(CFG_GLOBAL, global_config_file); @@ -765,6 +767,9 @@ void loadconfig(char *fn) for (d = 0; d < num_config_callbacks; ++d) if (config_callbacks[d].onloaded) config_callbacks[d].onloaded(); + + config_dump(CFG_GLOBAL); + config_dump(CFG_MACHINE); } void saveconfig(char *fn) @@ -772,7 +777,7 @@ void saveconfig(char *fn) int c, d; char global_config_file[512]; - append_filename(global_config_file, pcempath, "pcem.cfg", 511); + append_filename(global_config_file, pcem_path, "pcem.cfg", 511); config_set_int(CFG_GLOBAL, NULL, "vid_resize", vid_resize); config_set_int(CFG_GLOBAL, NULL, "vid_force_aspect_ratio", video_force_aspect_ration); @@ -877,7 +882,7 @@ void saveconfig(char *fn) pclog("config_save(%s)\n", config_file_default); if (fn) config_save(CFG_MACHINE, fn); - else + else if (strlen(config_file_default)) config_save(CFG_MACHINE, config_file_default); config_save(CFG_GLOBAL, global_config_file); diff --git a/src/ps1.c b/src/ps1.c index 72fa773..6450767 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -131,15 +131,15 @@ void ps1mb_init() io_sethandler(0x0324, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); rom_init(&ps1_high_rom, - "roms/ibmps1es/f80000.bin", + "ibmps1es/f80000.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", + "ibmps1es/ibm_1057757_24-05-90.bin", + "ibmps1es/ibm_1057757_29-15-90.bin", 0xfc0000, 0x40000, 0x3ffff, @@ -283,7 +283,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.bin", + "ibmps1_2121/fc0000.bin", 0xfc0000, 0x40000, 0x3ffff, diff --git a/src/ps2_nvr.c b/src/ps2_nvr.c index 1225f69..ed1896b 100644 --- a/src/ps2_nvr.c +++ b/src/ps2_nvr.c @@ -3,6 +3,7 @@ #include "device.h" #include "io.h" #include "ps2_nvr.h" +#include "nvr.h" typedef struct ps2_nvr_t { @@ -57,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("ibmps2_m80_sec.nvr", "rb"); break; } if (f) { @@ -77,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("ibmps2_m80_sec.nvr", "wb"); break; } if (f) { diff --git a/src/rom.c b/src/rom.c index b83b098..49f0fc1 100644 --- a/src/rom.c +++ b/src/rom.c @@ -4,25 +4,30 @@ #include "config.h" #include "mem.h" #include "rom.h" +#include "paths.h" FILE *romfopen(char *fn, char *mode) { + FILE *f; char s[512]; - strcpy(s, pcempath); - put_backslash(s); - strcat(s, fn); - return fopen(s, mode); + int i; + + for (i = 0; i < num_roms_paths; ++i) + { + get_roms_path(i, s, 511); + put_backslash(s); + strcat(s, fn); + f = fopen(s, mode); + if (f) + return f; + } + return 0; } int rom_present(char *fn) { FILE *f; - char s[512]; - - strcpy(s, pcempath); - put_backslash(s); - strcat(s, fn); - f = fopen(s, "rb"); + f = romfopen(fn, "rb"); if (f) { fclose(f); diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index 1f62dc4..507751c 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -11,6 +11,7 @@ #include "pit.h" #include "sound.h" #include "timer.h" +#include "nvr.h" #include "filters.h" @@ -788,7 +789,7 @@ void *adgold_init() for (; c >= 0; c--) attenuation[c] = 0; - f = romfopen("nvr/adgold.bin", "rb"); + f = nvrfopen("adgold.bin", "rb"); if (f) { fread(adgold->adgold_eeprom, 0x18, 1, f); @@ -828,7 +829,7 @@ void adgold_close(void *p) FILE *f; adgold_t *adgold = (adgold_t *)p; - f = romfopen("nvr/adgold.bin", "wb"); + f = nvrfopen("adgold.bin", "wb"); if (f) { fwrite(adgold->adgold_eeprom, 0x18, 1, f); diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index 49d8216..640eb06 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -676,9 +676,9 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram) int c; double out; - f = romfopen("roms/awe32.raw", "rb"); + f = romfopen("awe32.raw", "rb"); if (!f) - fatal("ROMS/AWE32.RAW not found\n"); + fatal("AWE32.RAW not found\n"); if (onboard_ram) { diff --git a/src/sound_sb.c b/src/sound_sb.c index 8b27138..f52fea6 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -619,7 +619,7 @@ void *sb_16_init() int sb_awe32_available() { - return rom_present("roms/awe32.raw"); + return rom_present("awe32.raw"); } void *sb_awe32_init() diff --git a/src/tandy_eeprom.c b/src/tandy_eeprom.c index a29e272..0682a52 100644 --- a/src/tandy_eeprom.c +++ b/src/tandy_eeprom.c @@ -3,6 +3,7 @@ #include "io.h" #include "device.h" #include "tandy_eeprom.h" +#include "nvr.h" typedef struct { @@ -126,10 +127,10 @@ void *tandy_eeprom_init() switch (romset) { case ROM_TANDY1000HX: - f = romfopen("nvr/tandy1000hx.bin" ,"rb"); + f = nvrfopen("tandy1000hx.bin" ,"rb"); break; case ROM_TANDY1000SL2: - f = romfopen("nvr/tandy1000sl2.bin" ,"rb"); + f = nvrfopen("tandy1000sl2.bin" ,"rb"); break; } if (f) @@ -153,10 +154,10 @@ void tandy_eeprom_close(void *p) switch (eeprom->romset) { case ROM_TANDY1000HX: - f = romfopen("nvr/tandy1000hx.bin" ,"wb"); + f = nvrfopen("tandy1000hx.bin" ,"wb"); break; case ROM_TANDY1000SL2: - f = romfopen("nvr/tandy1000sl2.bin" ,"wb"); + f = nvrfopen("tandy1000sl2.bin" ,"wb"); break; } fwrite(eeprom->store, 128, 1, f); diff --git a/src/tandy_rom.c b/src/tandy_rom.c index becf8d7..df49d87 100644 --- a/src/tandy_rom.c +++ b/src/tandy_rom.c @@ -56,8 +56,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("tandy1000sl2/8079047.hu1" ,"rb"); + ff = romfopen("tandy1000sl2/8079048.hu2","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 f3a9cac..7e672a0 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -128,7 +128,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, "vgaedge16.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ NULL, @@ -148,7 +148,7 @@ void *ati18800_init() static int ati18800_available() { - return rom_present("roms/vgaedge16.vbi"); + return rom_present("vgaedge16.vbi"); } void ati18800_close(void *p) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 2ab7e07..393f41e 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -149,7 +149,7 @@ void *ati28800_init() ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); - rom_init(&ati28800->bios_rom, "roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati28800->bios_rom, "bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ ati28800_recalctimings, @@ -169,7 +169,7 @@ void *ati28800_init() static int ati28800_available() { - return rom_present("roms/bios.bin"); + return rom_present("bios.bin"); } void ati28800_close(void *p) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index a608060..371638e 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -3378,7 +3378,7 @@ static void *mach64gx_init() ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); - rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, "mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return mach64; } @@ -3396,7 +3396,7 @@ static void *mach64vt2_init() ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); - rom_init(&mach64->bios_rom, "roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, "atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga->vblank_start = mach64_vblank_start; @@ -3405,11 +3405,11 @@ static void *mach64vt2_init() int mach64gx_available() { - return rom_present("roms/mach64gx/bios.bin"); + return rom_present("mach64gx/bios.bin"); } int mach64vt2_available() { - return rom_present("roms/atimach64vt2pci.bin"); + return rom_present("atimach64vt2pci.bin"); } void mach64_close(void *p) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 13ff6df..6616b59 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -822,7 +822,7 @@ void *gd5429_init() svga_t *svga = &gd5429->svga; memset(gd5429, 0, sizeof(gd5429_t)); - rom_init(&gd5429->bios_rom, "roms/5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&gd5429->bios_rom, "5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/ gd5429_recalctimings, @@ -847,7 +847,7 @@ void *gd5429_init() static int gd5429_available() { - return rom_present("roms/5429.vbi"); + return rom_present("5429.vbi"); } void gd5429_close(void *p) diff --git a/src/vid_ega.c b/src/vid_ega.c index 106af91..d212b59 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -836,7 +836,7 @@ void *ega_standalone_init() ega_t *ega = malloc(sizeof(ega_t)); memset(ega, 0, sizeof(ega_t)); - 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, "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) { @@ -861,7 +861,7 @@ void *ega_standalone_init() static int ega_standalone_available() { - return rom_present("roms/ibm_6277356_ega_card_u44_27128.bin"); + return rom_present("ibm_6277356_ega_card_u44_27128.bin"); } void ega_close(void *p) diff --git a/src/vid_et4000.c b/src/vid_et4000.c index 483ce94..f24acbc 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -148,7 +148,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, "et4000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); @@ -163,7 +163,7 @@ void *et4000_init() static int et4000_available() { - return rom_present("roms/et4000.bin"); + return rom_present("et4000.bin"); } void et4000_close(void *p) diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index f0b936a..97fca5f 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -1176,7 +1176,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, "et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); /*Some BIOSes (eg Diamond Stealth 32 VLB) have a PCI data structure, but with the wrong PCI device ID. The BIOSes on the Intel boards detect this @@ -1212,7 +1212,7 @@ void *et4000w32p_init() int et4000w32p_available() { - return rom_present("roms/et4000w32.bin"); + return rom_present("et4000w32.bin"); } void et4000w32p_close(void *p) diff --git a/src/vid_genius.c b/src/vid_genius.c index c608071..088cdf2 100644 --- a/src/vid_genius.c +++ b/src/vid_genius.c @@ -615,7 +615,7 @@ void genius_close(void *p) static int genius_available() { - return rom_present("roms/8x12.bin"); + return rom_present("8x12.bin"); } void genius_speed_changed(void *p) diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 6d8b8a6..7088bbf 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -174,12 +174,12 @@ void *oti067_common_init(char *bios_fn, int vram_size) void *oti067_init() { int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/oti067/bios.bin", vram_size); + return oti067_common_init("oti067/bios.bin", vram_size); } void *oti067_acer386_init() { - oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512); + oti067_t *oti067 = oti067_common_init("acer386/oti067.bin", 512); if (oti067) oti067->bios_rom.rom[0x5d] = 0x74; @@ -189,7 +189,7 @@ void *oti067_acer386_init() static int oti067_available() { - return rom_present("roms/oti067/bios.bin"); + return rom_present("oti067/bios.bin"); } void oti067_close(void *p) diff --git a/src/vid_paradise.c b/src/vid_paradise.c index dc90657..6e12061 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, "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, "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", + "megapc/41651-bios lo.u18", + "megapc/211253-bios hi.u19", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; diff --git a/src/vid_pc1640.c b/src/vid_pc1640.c index e7327e1..9c65ca4 100644 --- a/src/vid_pc1640.c +++ b/src/vid_pc1640.c @@ -117,7 +117,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, "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 53b3324..13f71cf 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2246,7 +2246,7 @@ static void *s3_init(char *bios_fn, int chip) void *s3_bahamas64_init() { - s3_t *s3 = s3_init("roms/bahamas64.bin", S3_VISION864); + s3_t *s3 = s3_init("bahamas64.bin", S3_VISION864); s3->id = 0xc0; /*Vision864P*/ s3->id_ext = s3->id_ext_pci = 0xc0; @@ -2260,12 +2260,12 @@ void *s3_bahamas64_init() int s3_bahamas64_available() { - return rom_present("roms/bahamas64.bin"); + return rom_present("bahamas64.bin"); } void *s3_9fx_init() { - s3_t *s3 = s3_init("roms/s3_764.bin", S3_TRIO64); + s3_t *s3 = s3_init("s3_764.bin", S3_TRIO64); s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; @@ -2279,12 +2279,12 @@ void *s3_9fx_init() int s3_9fx_available() { - return rom_present("roms/s3_764.bin"); + return rom_present("s3_764.bin"); } void *s3_phoenix_trio32_init() { - s3_t *s3 = s3_init("roms/86c732p.bin", S3_TRIO32); + s3_t *s3 = s3_init("86c732p.bin", S3_TRIO32); s3->id = 0xe1; /*Trio32*/ s3->id_ext = 0x10; @@ -2299,12 +2299,12 @@ void *s3_phoenix_trio32_init() int s3_phoenix_trio32_available() { - return rom_present("roms/86c732p.bin"); + return rom_present("86c732p.bin"); } void *s3_phoenix_trio64_init() { - s3_t *s3 = s3_init("roms/86c764x1.bin", S3_TRIO64); + s3_t *s3 = s3_init("86c764x1.bin", S3_TRIO64); s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; @@ -2318,7 +2318,7 @@ void *s3_phoenix_trio64_init() int s3_phoenix_trio64_available() { - return rom_present("roms/86c764x1.bin"); + return rom_present("86c764x1.bin"); } void s3_close(void *p) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 8df14e0..625901b 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3802,7 +3802,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, "s3virge.bin", 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_overlay_draw); virge->svga.vblank_start = s3_virge_vblank_start; - rom_init(&virge->bios_rom, "roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, "86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -4003,12 +4003,12 @@ static void s3_virge_close(void *p) static int s3_virge_available() { - return rom_present("roms/s3virge.bin"); + return rom_present("s3virge.bin"); } static int s3_virge_375_available() { - return rom_present("roms/86c375_1.bin"); + return rom_present("86c375_1.bin"); } static void s3_virge_speed_changed(void *p) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 6a93aec..06c6d4e 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -517,7 +517,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, "9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tgui->svga, tgui, tgui->vram_size, tgui_recalctimings, @@ -543,7 +543,7 @@ void *tgui9440_init() static int tgui9440_available() { - return rom_present("roms/9440.vbi"); + return rom_present("9440.vbi"); } void tgui_close(void *p) diff --git a/src/vid_tvga.c b/src/vid_tvga.c index e3a3df0..a5c6ae6 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -288,7 +288,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, "trident.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tvga->svga, tvga, tvga->vram_size, tvga_recalctimings, @@ -303,7 +303,7 @@ void *tvga8900d_init() static int tvga8900d_available() { - return rom_present("roms/trident.bin"); + return rom_present("trident.bin"); } void tvga_close(void *p) diff --git a/src/vid_vga.c b/src/vid_vga.c index 6f4d639..40472f7 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, "ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ NULL, @@ -122,7 +122,7 @@ void *ps1vga_init() static int vga_available() { - return rom_present("roms/ibm_vga.bin"); + return rom_present("ibm_vga.bin"); } void vga_close(void *p) diff --git a/src/win-config_sel.c b/src/win-config_sel.c index 5ce9427..83d08c4 100644 --- a/src/win-config_sel.c +++ b/src/win-config_sel.c @@ -9,6 +9,7 @@ #include "config.h" #include "resources.h" #include "win.h" +#include "paths.h" static void config_list_update(HWND hdlg) { @@ -16,9 +17,9 @@ static void config_list_update(HWND hdlg) int num, c; HWND h; - strcpy(s, pcempath); + strcpy(s, configs_path); put_backslash(s); - strcat(s, "configs\\*.cfg"); + strcat(s, "*.cfg"); pclog("Dir %s\n", s); DlgDirList(hdlg, s, IDC_LIST, 0, 0); @@ -71,12 +72,11 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP { char cfg[512]; - strcpy(cfg, pcempath); + strcpy(cfg, configs_path); put_backslash(cfg); - strcat(cfg, "configs\\"); strcat(cfg, s); strcat(cfg, "cfg"); -// sprintf(cfg, "%s\\configs\\%scfg", pcempath, s); +// sprintf(cfg, "%s\\configs\\%scfg", configs_path, s); pclog("Config name %s\n", cfg); strcpy(config_file_default, cfg); @@ -97,9 +97,8 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP { char s[512]; - strcpy(s, pcempath); + strcpy(s, configs_path); put_backslash(s); - strcat(s, "configs\\"); pclog("Dir %s\n", s); if (!getsfile(hdlg, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "", s, "cfg")) @@ -125,9 +124,8 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP { char cfg[512]; - strcpy(cfg, pcempath); + strcpy(cfg, configs_path); put_backslash(cfg); - strcat(cfg, "configs\\"); strcat(cfg, s); strcat(cfg, "cfg"); pclog("Config name %s\n", cfg); @@ -151,9 +149,8 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP { char cfg[512]; - strcpy(cfg, pcempath); + strcpy(cfg, configs_path); put_backslash(cfg); - strcat(cfg, "configs\\"); strcat(cfg, s); strcat(cfg, "cfg"); pclog("Config name %s\n", cfg); diff --git a/src/win.c b/src/win.c index 9769261..7ba7943 100644 --- a/src/win.c +++ b/src/win.c @@ -41,6 +41,7 @@ #include "win-ddraw-fs.h" #include "win-d3d.h" #include "win-d3d-fs.h" +#include "paths.h" //#include "win-opengl.h" #ifndef MAPVK_VK_TO_VSC @@ -314,7 +315,15 @@ static void initmenu(void) } } -void get_executable_name(char *s, int size) +int dir_exists(char *path) +{ + DWORD dwAttrib = GetFileAttributes(path); + + return (dwAttrib != INVALID_FILE_ATTRIBUTES && + (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +} + +void get_pcem_path(char *s, int size) { GetModuleFileName(hinstance, s, size); } @@ -486,7 +495,7 @@ static void process_command_line() argbuf[i] = 0; i++; } - pclog("Arg %i - %s\n",argc-1,argv[argc-1]); + //pclog("Arg %i - %s\n",argc-1,argv[argc-1]); } } @@ -535,7 +544,19 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (!RegisterClassEx(&wincl)) return 0; - getpath(); + paths_init(); + + timeBeginPeriod(1); + + atexit(releasemouse); + + QueryPerformanceFrequency(&qpc_freq); + timer_freq = qpc_freq.QuadPart; + + sound_init(); + + initpc(argc, argv); + d = romset; for (c = 0; c < ROM_MAX; c++) @@ -561,17 +582,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, for (c = 0; c < GFX_MAX; c++) gfx_present[c] = video_card_available(video_old_to_new(c)); - timeBeginPeriod(1); - - atexit(releasemouse); - - QueryPerformanceFrequency(&qpc_freq); - timer_freq = qpc_freq.QuadPart; - - sound_init(); - - initpc(argc, argv); - while (1) { quited = 0; diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index 0025bb0..dda0fe7 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -2,6 +2,7 @@ #include "config.h" #include "wx-utils.h" #include "wx-sdl2.h" +#include "paths.h" extern void config_open(void* hwnd); extern void hdconf_open(void* hwnd); @@ -12,9 +13,9 @@ static void config_list_update(void* hdlg) int num, c; void* h; - strcpy(s, pcempath); + strcpy(s, configs_path); put_backslash(s); - strcat(s, "configs/*.cfg"); + strcat(s, "*.cfg"); pclog("Dir %s\n", s); wx_dlgdirlist(hdlg, s, WX_ID("IDC_LIST"), 0, 0); @@ -67,12 +68,11 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L { char cfg[512]; - strcpy(cfg, pcempath); + strcpy(cfg, configs_path); put_backslash(cfg); - strcat(cfg, "configs/"); strcat(cfg, s); strcat(cfg, "cfg"); -// sprintf(cfg, "%s\\configs\\%scfg", pcempath, s); +// sprintf(cfg, "%s\\configs\\%scfg", config_path, s); pclog("Config name %s\n", cfg); strcpy(config_file_default, cfg); @@ -96,9 +96,8 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L // if (!getsfile(hdlg, "Configuration (*.cfg)|*.cfg|All files (*.*)|*.*", "", s, "cfg")) if (wx_textentrydialog(hdlg, "Enter name:", "New config", 0, 1, 64, (LONG_PARAM)name)) { - strcpy(openfilestring, pcempath); + strcpy(openfilestring, configs_path); put_backslash(openfilestring); - strcat(openfilestring, "configs/"); strcat(openfilestring, name); strcat(openfilestring, ".cfg"); @@ -124,9 +123,8 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L { char cfg[512]; - strcpy(cfg, pcempath); + strcpy(cfg, configs_path); put_backslash(cfg); - strcat(cfg, "configs/"); strcat(cfg, s); strcat(cfg, "cfg"); pclog("Config name %s\n", cfg); @@ -149,9 +147,8 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L { char cfg[512]; - strcpy(cfg, pcempath); + strcpy(cfg, configs_path); put_backslash(cfg); - strcat(cfg, "configs/"); strcat(cfg, s); strcat(cfg, "cfg"); pclog("Config name %s\n", cfg); @@ -181,15 +178,13 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L char old_path[512]; char new_path[512]; - strcpy(old_path, pcempath); + strcpy(old_path, configs_path); put_backslash(old_path); - strcat(old_path, "configs/"); strcat(old_path, old_name); strcat(old_path, ".cfg"); - strcpy(new_path, pcempath); + strcpy(new_path, configs_path); put_backslash(new_path); - strcat(new_path, "configs/"); strcat(new_path, name); strcat(new_path, ".cfg"); @@ -217,9 +212,8 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L sprintf(s, "Do you want to delete \"%s\"?", name); if (wx_messagebox(NULL, s, "PCem", WX_MB_OKCANCEL) == WX_IDOK) { - strcpy(s, pcempath); + strcpy(s, configs_path); put_backslash(s); - strcat(s, "configs/"); strcat(s, name); strcat(s, ".cfg"); diff --git a/src/wx-main.cc b/src/wx-main.cc index e5790dc..393eb0e 100644 --- a/src/wx-main.cc +++ b/src/wx-main.cc @@ -7,9 +7,11 @@ int pc_main(int, char**); int main(int argc, char **argv) { - pc_main(argc, argv); + if (!pc_main(argc, argv)) + return -1; - wxApp::SetInstance(new App()); - wxEntry(argc, argv); + wxApp::SetInstance(new App()); + wxEntry(argc, argv); + return 0; } diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index fcafbc0..ce343e8 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -31,6 +31,7 @@ #include "disc.h" #include "disc_img.h" #include "mem.h" +#include "paths.h" #include "wx-sdl2-video.h" #include "wx-utils.h" @@ -89,8 +90,6 @@ int video_height = 480; char menuitem[60]; -extern void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()); - extern int config_selection_open(void* hwnd, int inited); extern void sdl_set_window_title(const char* title); @@ -190,10 +189,20 @@ int mainthread(void* param) return TRUE; } -void get_executable_name(char *s, int size) +int dir_exists(char* path) { + return wx_dir_exists(path); +} + +void get_pcem_path(char *s, int size) +{ +#ifdef __linux + wx_get_home_directory(s); + strcat(s, ".pcem/"); +#else char* path = SDL_GetBasePath(); strcpy(s, path); +#endif } void set_window_title(const char *s) @@ -335,20 +344,44 @@ extern void wx_saveconfig(); int pc_main(int argc, char** argv) { -#ifndef __APPLE__ - display_init(); + char s[512]; + paths_init(); + +#ifdef __linux__ + /* create directories if they don't exist */ + if (!wx_setup(pcem_path)) + return FALSE; + + /* set up default paths */ + sprintf(s, "%s%s%c%s", pcem_path, "roms/", get_path_separator(), "/usr/share/pcem/roms/"); + set_default_roms_paths(s); + append_filename(s, pcem_path, "nvr/", 511); + set_default_nvr_path(s); + append_filename(s, pcem_path, "configs/", 511); + set_default_configs_path(s); + append_filename(s, pcem_path, "logs/", 511); + set_default_logs_path(s); #endif - sdl_video_init(); add_config_callback(sdl_loadconfig, sdl_saveconfig, sdl_onconfigloaded); add_config_callback(wx_loadconfig, wx_saveconfig, 0); - getpath(); + initpc(argc, argv); + resetpchard(); sound_init(); - initpc(argc, argv); - resetpchard(); +#ifdef __linux__ + /* check if cfg exists, and if not create it */ + append_filename(s, pcem_path, "pcem.cfg", 511); + if (!wx_file_exists(s)) + saveconfig(NULL); +#endif + +#ifndef __APPLE__ + display_init(); +#endif + sdl_video_init(); return TRUE; } diff --git a/src/wx-utils.cc b/src/wx-utils.cc index 398a6d9..598efc8 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -440,3 +440,60 @@ void wx_close_status(void* window) status->Close(); } } + +void wx_get_home_directory(char* path) +{ + wxString home = wxFileName::GetHomeDir(); + if (!home.EndsWith(wxFileName::GetPathSeparator())) { + home.Append(wxFileName::GetPathSeparator()); + } + strcpy(path, home); +} + +int wx_create_directory(char* path) +{ + return wxFileName::Mkdir(path); +} + +int wx_setup(char* path) +{ + wxFileName p(path); + if (!p.DirExists()) + { + if (!p.Mkdir()) + return FALSE; + wxFileName configs(p); + configs.AppendDir("configs"); + if (!configs.DirExists() && !configs.Mkdir()) + return FALSE; + + wxFileName roms(p); + roms.AppendDir("roms"); + if (!roms.DirExists() && !roms.Mkdir()) + return FALSE; + + wxFileName nvr(p); + nvr.AppendDir("nvr"); + if (!nvr.DirExists() && !nvr.Mkdir()) + return FALSE; + + wxFileName logs(p); + logs.AppendDir("logs"); + if (!logs.DirExists() && !logs.Mkdir()) + return FALSE; + } + + return TRUE; +} + +int wx_file_exists(char* path) +{ + wxFileName p(path); + return p.Exists(); +} + +int wx_dir_exists(char* path) +{ + wxFileName p(path); + return p.DirExists(); +} diff --git a/src/wx-utils.h b/src/wx-utils.h index 84296bf..719e224 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -65,6 +65,13 @@ extern "C" { void wx_show_status(void* window); void wx_close_status(void* window); + void wx_get_home_directory(char* path); + int wx_create_directory(char* path); + + int wx_setup(char* path); + int wx_file_exists(char* path); + int wx_dir_exists(char* path); + int confirm(); #ifdef __cplusplus } diff --git a/src/x86seg.c b/src/x86seg.c index 2da6a43..a465f0a 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -8,6 +8,8 @@ #include "386.h" #include "386_common.h" #include "cpu.h" +#include "config.h" +#include "paths.h" /*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ #define CS_ACCESSED @@ -38,19 +40,24 @@ int output; FILE *pclogf; void x86abort(const char *format, ...) { - char buf[256]; -// return; - if (!pclogf) - pclogf=fopen("pclog.txt","wt"); -//return; - va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - fputs(buf,pclogf); - fflush(pclogf); - dumpregs(); - exit(-1); + char buf[256]; + // return; + if (!pclogf) + { + strcpy(buf, logs_path); + put_backslash(buf); + strcat(buf, "pcem.log"); + pclogf=fopen(buf, "wt"); + } + //return; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fputs(buf,pclogf); + fflush(pclogf); + dumpregs(); + exit(-1); } uint8_t opcode2; diff --git a/src/xtide.c b/src/xtide.c index 15954ab..5178a5c 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -70,7 +70,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, "ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); ide_pri_disable(); ide_sec_disable(); @@ -84,7 +84,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, "ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; @@ -99,12 +99,12 @@ static void xtide_close(void *p) static int xtide_available() { - return rom_present("roms/ide_xt.bin"); + return rom_present("ide_xt.bin"); } static int xtide_at_available() { - return rom_present("roms/ide_at.bin"); + return rom_present("ide_at.bin"); } device_t xtide_device = From c9f29583ff601bde736c4e69027fccf2649c4ea9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 6 Jul 2017 21:41:59 +0100 Subject: [PATCH 0072/1050] Re-ordered model menu to be more logical. --- src/model.c | 98 +++++++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/src/model.c b/src/model.c index ae7259c..1a0d512 100644 --- a/src/model.c +++ b/src/model.c @@ -93,51 +93,59 @@ int AMSTRAD, AT, PCI, TANDY; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 64, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_ide_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|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}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, - {"Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, 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_init, NULL},*/ - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, - {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 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}}, 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}}, 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}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, - {"Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, - {"Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"[8088] AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, xt_init, NULL}, + {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 64, pcjr_init, &pcjr_device}, + {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, + {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, + {"[8088] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, + + {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, + {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + + {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, + {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, + {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_ide_init, NULL}, + {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, + {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, + {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, + {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, + {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + + {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, + {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, + {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, + {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, + + {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, + {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + + {"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, + + {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, + + {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + + {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; From b18891f62e90372aabd2fdba7093c696870539b9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Jul 2017 18:17:46 +0100 Subject: [PATCH 0073/1050] Added paths.c/h files missing from rev 789. --- src/paths.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/paths.h | 24 +++++++ 2 files changed, 225 insertions(+) create mode 100644 src/paths.c create mode 100644 src/paths.h diff --git a/src/paths.c b/src/paths.c new file mode 100644 index 0000000..d401d64 --- /dev/null +++ b/src/paths.c @@ -0,0 +1,201 @@ +#include "paths.h" +#include "config.h" +#include +#include "ibm.h" + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +char default_roms_paths[4096]; +char default_nvr_path[512]; +char default_configs_path[512]; +char default_logs_path[512]; + +/* the number of roms paths */ +int num_roms_paths; +char roms_paths[4096]; +/* this is where pcem.cfg is */ +char pcem_path[512]; +/* this is where nvr-files as stored */ +char nvr_path[512]; +/* this is where configs as stored */ +char configs_path[512]; +/* this is where log-files as stored */ +char logs_path[512]; + +char get_path_separator() +{ +#ifdef _WIN32 + return ';'; +#else + return ':'; +#endif +} + +int get_roms_path(int pos, char *s, int size) +{ + int j, i, z, len; + char path_separator; + + path_separator = get_path_separator(); + len = strlen(roms_paths); + j = 0; + for (i = 0; i < len; i++) + { + if (roms_paths[i] == path_separator || i == len-1) + { + if ((pos--) == 0) + { + z = (i-j) + ((i == len-1) ? 1 : 0); + safe_strncpy(s, roms_paths+j, size); + s[(size-1 < z) ? size-1 : z] = 0; + return 1; + } + j = i+1; + } + } + return 0; +} + +void set_roms_paths(char *path) +{ + char s[512]; + int j, i, z, len; + char path_separator[2]; + + roms_paths[0] = 0; + path_separator[0] = get_path_separator(); + path_separator[1] = 0; + len = strlen(path); + j = 0; + num_roms_paths = 0; + for (i = 0; i < len; i++) + { + if (path[i] == path_separator[0] || i == len-1) + { + z = (i-j) + ((i == len-1) ? 1 : 0) + 1; + safe_strncpy(s, path+j, z); + s[(511 < z) ? 511 : z] = 0; + append_slash(s, 512); + if (dir_exists(s)) + { + if (num_roms_paths > 0) + strcat(roms_paths, path_separator); + strcat(roms_paths, s); + num_roms_paths++; + } + j = i+1; + } + } +} + +void set_nvr_path(char *s) +{ + safe_strncpy(nvr_path, s, 512); + append_slash(nvr_path, 512); +} + +void set_logs_path(char *s) +{ + safe_strncpy(logs_path, s, 512); + append_slash(logs_path, 512); +} + +void set_configs_path(char *s) +{ + safe_strncpy(configs_path, s, 512); + append_slash(configs_path, 512); +} + +/* set the default roms paths, this makes them permanent */ +void set_default_roms_paths(char *s) +{ + safe_strncpy(default_roms_paths, s, 4096); + set_roms_paths(s); +} + +/* set the default nvr path, this makes it permanent */ +void set_default_nvr_path(char *s) +{ + safe_strncpy(default_nvr_path, s, 512); + set_nvr_path(s); +} + +/* set the default logs path, this makes it permanent */ +void set_default_logs_path(char *s) +{ + safe_strncpy(default_logs_path, s, 512); + set_logs_path(s); +} + +/* set the default configs path, this makes it permanent */ +void set_default_configs_path(char *s) +{ + safe_strncpy(default_configs_path, s, 512); + set_configs_path(s); +} + +void paths_loadconfig() +{ + char *cfg_roms_paths = config_get_string(CFG_GLOBAL, "Paths", "roms_paths", 0); + char *cfg_nvr_path = config_get_string(CFG_GLOBAL, "Paths", "nvr_path", 0); + char *cfg_configs_path = config_get_string(CFG_GLOBAL, "Paths", "configs_path", 0); + char *cfg_logs_path = config_get_string(CFG_GLOBAL, "Paths", "logs_path", 0); + + if (cfg_roms_paths) + safe_strncpy(default_roms_paths, cfg_roms_paths, 4096); + if (cfg_nvr_path) + safe_strncpy(default_nvr_path, cfg_nvr_path, 512); + if (cfg_configs_path) + safe_strncpy(default_configs_path, cfg_configs_path, 512); + if (cfg_logs_path) + safe_strncpy(default_logs_path, cfg_logs_path, 512); +} + +void paths_saveconfig() +{ + config_set_string(CFG_GLOBAL, "Paths", "roms_paths", default_roms_paths); + config_set_string(CFG_GLOBAL, "Paths", "nvr_path", default_nvr_path); + config_set_string(CFG_GLOBAL, "Paths", "configs_path", default_configs_path); + config_set_string(CFG_GLOBAL, "Paths", "logs_path", default_logs_path); +} + +void paths_onconfigloaded() +{ + if (strlen(default_roms_paths) > 0) + set_roms_paths(default_roms_paths); + + if (strlen(default_nvr_path) > 0) + set_nvr_path(default_nvr_path); + + if (strlen(default_configs_path) > 0) + set_configs_path(default_configs_path); + + if (strlen(default_logs_path) > 0) + set_logs_path(default_logs_path); + + pclog("path = %s\n", pcem_path); +} + +/* initialize default paths */ +void paths_init() +{ + char s[512]; + char *p; + + get_pcem_path(pcem_path, 512); + /* pcem_path may be path to executable */ + p=get_filename(pcem_path); + *p=0; + + /* set up default paths for this session */ + append_filename(s, pcem_path, "roms/", 512); + set_roms_paths(s); + append_filename(s, pcem_path, "nvr/", 512); + set_nvr_path(s); + append_filename(s, pcem_path, "configs/", 512); + set_configs_path(s); + set_logs_path(pcem_path); + + add_config_callback(paths_loadconfig, paths_saveconfig, paths_onconfigloaded); + +} diff --git a/src/paths.h b/src/paths.h new file mode 100644 index 0000000..991d0d3 --- /dev/null +++ b/src/paths.h @@ -0,0 +1,24 @@ +extern int num_roms_paths; +extern char pcem_path[512]; +extern char configs_path[512]; +extern char nvr_path[512]; +extern char logs_path[512]; + +void get_pcem_path(char *s, int size); +char get_path_separator(); +void paths_init(); +int dir_exists(char* path); + +int get_roms_path(int p, char* s, int size); + +/* set the default paths to make them permanent */ +void set_default_roms_paths(char *s); +void set_default_nvr_path(char *s); +void set_default_logs_path(char *s); +void set_default_configs_path(char *s); + +/* set the paths temporarily for this session */ +void set_roms_paths(char* path); +void set_nvr_path(char *s); +void set_logs_path(char *s); +void set_configs_path(char *s); From d8a94b22e607e0578d02b2aa61496b657203b095 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Jul 2017 18:51:39 +0100 Subject: [PATCH 0074/1050] Handle D3D buffer locking failures more gracefully. Patch from JosepMa. --- src/win-d3d-fs.cc | 20 +++++++++++++------- src/win-d3d.cc | 7 ++++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index dcd1d74..5e0e8b6 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -291,14 +291,20 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) 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((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); + if (hr == D3D_OK) + { + for (yy = y1; yy < y2; yy++) + 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); + video_blit_complete(); + d3dTexture->UnlockRect(0); + } + else + { + video_blit_complete(); + return; + } } else video_blit_complete(); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 12402af..c138fad 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -221,11 +221,9 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) r.bottom = y2; r.right = 2047; + hr = d3dTexture->LockRect(0, &dr, &r, 0); if (hr == D3D_OK) { - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - for (yy = y1; yy < y2; yy++) { if ((y + yy) >= 0 && (y + yy) < buffer32->h) @@ -236,7 +234,10 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) d3dTexture->UnlockRect(0); } else + { video_blit_complete(); + return; + } 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; From 935b62156000182eb76e996d38cc56ae37238957 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 10 Jul 2017 20:53:28 +0100 Subject: [PATCH 0075/1050] Add LARGEFILE defines to esdi_at.c. --- src/esdi_at.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/esdi_at.c b/src/esdi_at.c index 88646ee..c174d1c 100644 --- a/src/esdi_at.c +++ b/src/esdi_at.c @@ -1,3 +1,7 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE + #include #include #include From 5c97ee34228648f3240ee089b82f7d44865c06c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 10 Jul 2017 21:10:04 +0100 Subject: [PATCH 0076/1050] Fixed corruption on large (>4GB) drives. --- src/hdd_file.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hdd_file.c b/src/hdd_file.c index fdfd77e..7d250e7 100644 --- a/src/hdd_file.c +++ b/src/hdd_file.c @@ -59,7 +59,8 @@ int hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) if ((hdd->sectors - offset) < transfer_sectors) transfer_sectors = hdd->sectors - offset; - addr = offset * 512; + addr = (uint64_t)offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); fread(buffer, transfer_sectors*512, 1, hdd->f); @@ -75,7 +76,8 @@ int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) if ((hdd->sectors - offset) < transfer_sectors) transfer_sectors = hdd->sectors - offset; - addr = offset * 512; + addr = (uint64_t)offset * 512; + fseeko64(hdd->f, addr, SEEK_SET); fwrite(buffer, transfer_sectors*512, 1, hdd->f); @@ -95,7 +97,7 @@ int hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) if ((hdd->sectors - offset) < transfer_sectors) transfer_sectors = hdd->sectors - offset; - addr = offset * 512; + addr = (uint64_t)offset * 512; fseeko64(hdd->f, addr, SEEK_SET); for (c = 0; c < transfer_sectors; c++) fwrite(zero_buffer, 512, 1, hdd->f); From 29bef61a3e3a3f966fb9d03ff67a6f17efdda9e3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Jul 2017 15:31:32 +0100 Subject: [PATCH 0077/1050] Eject floppy drives on reset - fixes loaded discs persisting through config changes. --- src/disc.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/disc.c b/src/disc.c index f4ccb2b..10274cc 100644 --- a/src/disc.c +++ b/src/disc.c @@ -205,9 +205,25 @@ void disc_set_rate(int drive, int drvden, int rate) void disc_reset() { + int drive; + curdrive = 0; disc_period = 32; timer_add(disc_poll, &disc_poll_time, &motoron, NULL); + + for (drive = 0; drive < 2; drive++) + { + if (loaders[driveloaders[drive]].close) + loaders[driveloaders[drive]].close(drive); + drive_empty[drive] = 1; + drives[drive].hole = NULL; + drives[drive].poll = NULL; + drives[drive].seek = NULL; + drives[drive].readsector = NULL; + drives[drive].writesector = NULL; + drives[drive].readaddress = NULL; + drives[drive].format = NULL; + } } void disc_init() From 51ed6ea341bed0798d57035abb25ac1cb6319c3c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Jul 2017 15:51:19 +0100 Subject: [PATCH 0078/1050] Protected mode improvements : - LTR now sets TSS state to busy - LMSW preserves ET bit in CR0 - Fixed PC size in 16-bit system segment on CALL/JMP Patch from Greatpsycho --- src/x86_ops_pmode.h | 10 +++++++++- src/x86seg.c | 11 ++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index 426776e..562b6ba 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -212,6 +212,9 @@ static int op0F00_common(uint32_t fetchdat, int ea32) access = readmemb(0, addr + 5); granularity = readmemb(0, addr + 6) & 0x80; if (cpu_state.abrt) return 1; + access |= 2; + writememb(0, addr + 5, access); + if (cpu_state.abrt) return 1; tr.seg = sel; tr.limit = limit; tr.access = access; @@ -365,7 +368,12 @@ 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; + if (is386) + { + tempw &= ~0x10; + tempw |= (msw & 0x10); + } + else tempw &= 0xF; msw = tempw; PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; diff --git a/src/x86seg.c b/src/x86seg.c index a465f0a..b514f0b 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -704,8 +704,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) return; } type=segdat[2]&0xF00; - if (type==0x400) newpc=segdat[0]; - else newpc=segdat[0]|(segdat[3]<<16); + newpc=segdat[0]; + if (type&0x800) newpc|=segdat[3]<<16; switch (type) { case 0x400: /*Call gate*/ @@ -810,6 +810,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) case 0x900: /*386 Task gate*/ // pclog("Task gate\n"); cpu_state.pc=oxpc; + optype=JMP; cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); flags &= ~NT_FLAG; @@ -965,8 +966,8 @@ void loadcscall(uint16_t seg) segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; type=segdat[2]&0xF00; - if (type==0x400) newpc=segdat[0]; - else newpc=segdat[0]|(segdat[3]<<16); + newpc=segdat[0]; + if (type&0x800) newpc|=segdat[3]<<16; if (csout) pclog("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]); if (segdat[2]&0x1000) @@ -1183,7 +1184,7 @@ void loadcscall(uint16_t seg) if (!(segdat2[2]&0x8000)) { pclog("Call gate loading SS not present\n"); - x86np("Call gate loading SS not present\n", newss & 0xfffc); + x86ss("Call gate loading SS not present\n", newss & 0xfffc); return; } if (!stack32) oldsp &= 0xFFFF; From 9521237b0b8718a31f47f52448108d21776114d4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Jul 2017 16:17:59 +0100 Subject: [PATCH 0079/1050] Added Samsung SPC-4200P emulation. IDE Drive Diagnostics command now doesn't complete immediately (required by SPC-4200P BIOS). Patch from Greatpsycho. --- src/ibm.h | 1 + src/ide.c | 6 ++++++ src/mem.c | 7 +++++++ src/model.c | 1 + src/nvr.c | 2 ++ 5 files changed, 17 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index 81e5ae4..df8dcfa 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -404,6 +404,7 @@ enum ROM_CMDPC30, ROM_AMI286, ROM_AWARD286, + ROM_SPC4200P, ROM_DELL200, ROM_MISC286, ROM_IBMAT386, diff --git a/src/ide.c b/src/ide.c index 6d5d4e3..085097b 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1045,6 +1045,12 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ + ide->atastat = BUSY_STAT; + timer_process(); + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); + return; + case WIN_PIDENTIFY: /* Identify Packet Device */ case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ // output=1; diff --git a/src/mem.c b/src/mem.c index a9eb585..031d1f8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -385,6 +385,13 @@ int loadbios() fclose(f); return 1; + case ROM_SPC4200P: + f=romfopen("spc4200p/u8.01","rb"); + if (!f) break; + fread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_EUROPC: // return 0; f=romfopen("europc/50145","rb"); diff --git a/src/model.c b/src/model.c index 1a0d512..ca64a94 100644 --- a/src/model.c +++ b/src/model.c @@ -123,6 +123,7 @@ MODEL models[] = {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512,2048, 128, at_scat_init, NULL}, {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 33df4b6..9258eea 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -227,6 +227,7 @@ void loadnvr() case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break; case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); nvrmask = 127; break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break; + case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); break; @@ -290,6 +291,7 @@ void savenvr() case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "wb"); break; case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break; + case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); break; From e7afbb1a26ce01d94b6f7c905ab3344e97205f4b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Jul 2017 16:55:11 +0100 Subject: [PATCH 0080/1050] Re-ordered HDD controller menu to be more logical. --- src/hdd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hdd.c b/src/hdd.c index aaaaa20..05b1ffd 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -22,14 +22,14 @@ static struct int is_mfm; } hdd_controllers[] = { - {"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}, - {"Western Digital WD1007V-SE1 (ESDI)","wd1007vse1", &wd1007vse1_device, 0}, - {"XTIDE", "xtide", &xtide_device, 0}, - {"XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, + {"None", "none", &null_hdd_device, 0}, + {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1}, + {"[MFM] DTC 5150X", "dtc5150x", &dtc_5150x_device, 1}, + {"[MFM] Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1}, + {"[ESDI] IBM ESDI Fixed Disk Controller", "esdi_mca", &hdd_esdi_device, 1}, + {"[ESDI] Western Digital WD1007V-SE1", "wd1007vse1", &wd1007vse1_device, 0}, + {"[IDE] XTIDE", "xtide", &xtide_device, 0}, + {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, {"", "", NULL, 0} }; From dc511447dfe904ee17928e3e249b71cf90625c7c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Jul 2017 21:24:09 +0100 Subject: [PATCH 0081/1050] Added Page Size Extension (4MB pages) to Pentium CPUs. --- src/cpu.c | 9 +++++---- src/ibm.h | 1 + src/mem.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 9552c1d..2610ca3 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -52,6 +52,7 @@ enum { CPUID_FPU = (1 << 0), CPUID_VME = (1 << 1), + CPUID_PSE = (1 << 3), CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_CMPXCHG8B = (1 << 8), @@ -978,7 +979,7 @@ void cpu_set() cpu_hasMSR = 1; cpu_hasCR4 = 1; cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1019,7 +1020,7 @@ void cpu_set() cpu_hasMSR = 1; cpu_hasCR4 = 1; cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1299,7 +1300,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; } else EAX = 0; @@ -1317,7 +1318,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; } else EAX = 0; diff --git a/src/ibm.h b/src/ibm.h index df8dcfa..468dd1e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -251,6 +251,7 @@ uint32_t dr[8]; #define CR4_VME (1 << 0) #define CR4_PVI (1 << 1) +#define CR4_PSE (1 << 4) #define IOPL ((flags>>12)&3) diff --git a/src/mem.c b/src/mem.c index 031d1f8..25fb4f7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -873,6 +873,32 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) }*/ return -1; } + + if ((temp & 0x80) && (cr4 & CR4_PSE)) + { + /*4MB page*/ + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 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,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; + + return -1; + } + + mmu_perm = temp & 4; + ((uint32_t *)ram)[addr2>>2] |= 0x20; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; temp3=temp&temp2; // if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3); @@ -921,6 +947,15 @@ uint32_t mmutranslate_noabrt(uint32_t addr, int rw) if (!(temp&1)) return -1; + if ((temp & 0x80) && (cr4 & CR4_PSE)) + { + /*4MB page*/ + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) + return -1; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; temp3=temp&temp2; From 7531b95e83d6eb60636d34598be4e26a69314cfc Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Jul 2017 19:38:02 +0100 Subject: [PATCH 0082/1050] Fixed A20 reset issues. Patch from Greatpsycho. --- src/intel.c | 27 +++++++++++++++++++++++++++ src/model.c | 1 + src/ps1.c | 1 + src/ps2.c | 3 ++- src/scat.c | 2 +- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/intel.c b/src/intel.c index 67d06f4..a7194f3 100644 --- a/src/intel.c +++ b/src/intel.c @@ -4,9 +4,12 @@ #include "mem.h" #include "pit.h" #include "timer.h" +#include "x86.h" #include "intel.h" +static uint8_t batman_port_92; + uint8_t batman_brdconfig(uint16_t port, void *p) { // pclog("batman_brdconfig read port=%04x\n", port); @@ -16,12 +19,34 @@ uint8_t batman_brdconfig(uint16_t port, void *p) return 0xff; case 0x75: return 0xdf; + case 0x92: + return batman_port_92; } return 0; } +void batman_brdconfig_write(uint16_t port, uint8_t val, void *p) +{ + switch (port) + { + case 0x92: + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~batman_port_92 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + batman_port_92 = val; + } +} + static uint16_t batman_timer_latch; static int batman_timer = 0; + static void batman_timer_over(void *p) { batman_timer = 0; @@ -60,6 +85,8 @@ void intel_batman_init() io_sethandler(0x0075, 0x0001, batman_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, batman_brdconfig, NULL, NULL, batman_brdconfig_write, NULL, NULL, NULL); + batman_port_92 = 0; timer_add(batman_timer_over, &batman_timer, &batman_timer, NULL); } diff --git a/src/model.c b/src/model.c index ca64a94..5f6bd68 100644 --- a/src/model.c +++ b/src/model.c @@ -308,6 +308,7 @@ void xt_laserxt_init() void at_init() { AT = 1; + mem_a20_key = mem_a20_alt = 0; common_init(); mem_add_bios(); pit_set_out_func(&pit, 1, pit_refresh_timer_at); diff --git a/src/ps1.c b/src/ps1.c index 6450767..b2ea50f 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -289,6 +289,7 @@ void ps1mb_m2121_init() 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + ps1_92 = 0; ps1_190 = 0; lpt1_remove(); diff --git a/src/ps2.c b/src/ps2.c index 18b0ed7..6334666 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -124,7 +124,8 @@ void ps2board_init() 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_92 = 0; ps2_190 = 0; lpt1_remove(); diff --git a/src/scat.c b/src/scat.c index cedfa65..2a27a04 100644 --- a/src/scat.c +++ b/src/scat.c @@ -5,7 +5,6 @@ #include "mem.h" #include "scat.h" #include "x86.h" -#include "cpu.h" static uint8_t scat_regs[256]; static int scat_index; @@ -510,6 +509,7 @@ void scat_init() scat_regs[SCAT_DRAM_CONFIGURATION] = cpu_waitstates == 1 ? 2 : 0x12; scat_regs[SCAT_EXTENDED_BOUNDARY] = 0; scat_regs[SCAT_EMS_CONTROL] = 0; + scat_port_92 = 0; mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); From b90b5b7d7d61dce953b32fbaee5b80a829093574 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Jul 2017 20:59:42 +0100 Subject: [PATCH 0083/1050] Ignore 0 line blits. --- src/video.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video.c b/src/video.c index 490a349..a515919 100644 --- a/src/video.c +++ b/src/video.c @@ -522,6 +522,8 @@ void video_wait_for_buffer() void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { + if (h <= 0) + return; video_wait_for_blit(); blit_data.busy = 1; blit_data.buffer_in_use = 1; From 7a0398dd076008d98c38feba1b2723d7b57b1551 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Jul 2017 21:02:53 +0100 Subject: [PATCH 0084/1050] Add EGA status information. --- src/vid_ega.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index d212b59..ff830a1 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -540,7 +540,6 @@ void ega_poll(void *p) } if (ega->vc == ega->vsyncstart) { - int wx = 0, wy = 0; ega->dispon = 0; // printf("Vsync on at line %i %i\n",displine,vc); ega->stat |= 8; @@ -563,10 +562,9 @@ void ega_poll(void *p) video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline, xsize, ega->lastline - ega->firstline); - frames++; - - ega->video_res_x = wx; - ega->video_res_y = wy + 1; + ega->frames++; + ega->video_res_x = xsize; + ega->video_res_y = ysize+1; if (!(ega->gdcreg[6] & 1)) /*Text mode*/ { ega->video_res_x /= (ega->seqregs[1] & 1) ? 8 : 9; @@ -879,6 +877,23 @@ void ega_speed_changed(void *p) ega_recalctimings(ega); } +void ega_add_status_info(char *s, int max_len, void *p) +{ + ega_t *ega = (ega_t *)p; + char temps[128]; + + if (!ega->video_bpp) strcpy(temps, "EGA in text mode\n"); + else sprintf(temps, "EGA colour depth : %i bpp\n", ega->video_bpp); + strncat(s, temps, max_len); + + sprintf(temps, "EGA resolution : %i x %i\n", ega->video_res_x, ega->video_res_y); + strncat(s, temps, max_len); + + sprintf(temps, "EGA refresh rate : %i Hz\n\n", ega->frames); + ega->frames = 0; + strncat(s, temps, max_len); +} + device_t ega_device = { "EGA", @@ -888,5 +903,5 @@ device_t ega_device = ega_standalone_available, ega_speed_changed, NULL, - NULL + ega_add_status_info }; From a489f543fb2e3ad8e26c0a683d310cd1d89a0ec2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Jul 2017 21:04:07 +0100 Subject: [PATCH 0085/1050] Add EGA display type configuration. --- src/vid_ega.c | 108 ++++++++++++++++++++++++++++++++++++++++++----- src/vid_ega.h | 3 +- src/vid_pc1640.c | 2 +- 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index ff830a1..2cfc331 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -554,7 +554,7 @@ void ega_poll(void *p) ysize = ega->lastline - ega->firstline; if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; - if (ega->vres) + if (ega->vres || ysize <= 200) updatewindowsize(xsize, ysize << 1); else updatewindowsize(xsize, ysize); @@ -788,7 +788,7 @@ uint8_t ega_read(uint32_t addr, void *p) return ega->vram[addr | readplane]; } -void ega_init(ega_t *ega) +void ega_init(ega_t *ega, int monitor_type, int is_mono) { int c, d, e; @@ -817,22 +817,63 @@ void ega_init(ega_t *ega) } } - for (c = 0; c < 256; c++) + if (is_mono) { - pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); - if ((c & 0x17) == 6) - pallook16[c] = makecol32(0xaa, 0x55, 0); + for (c = 0; c < 256; c++) + { + int video = ((c & 8) ? 2 : 0) | ((c & 16) ? 1 : 0); + switch (monitor_type >> 4) + { + case DISPLAY_GREEN: + pallook64[c] = makecol32(0, video*0x55, 0); + pallook16[c] = makecol32(0, video*0x55, 0); + break; + case DISPLAY_AMBER: + switch ((c >> 3) & 3) + { + case 0: + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x2c, 0x08, 0x00); + break; + case 1: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xae, 0x18); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); + break; + } + break; + case DISPLAY_WHITE: default: + pallook64[c] = makecol32(video*0x55, video*0x55, video*0x55); + pallook16[c] = makecol32(video*0x55, video*0x55, video*0x55); + break; + } + } + } + else + { + for (c = 0; c < 256; c++) + { + pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); + if ((c & 0x17) == 6) + pallook16[c] = makecol32(0xaa, 0x55, 0); + } } ega->pallook = pallook16; + + egaswitches = monitor_type & 0xf; } void *ega_standalone_init() { ega_t *ega = malloc(sizeof(ega_t)); memset(ega, 0, sizeof(ega_t)); + int monitor_type; rom_init(&ega->bios_rom, "ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -849,7 +890,8 @@ void *ega_standalone_init() } } - ega_init(ega); + monitor_type = device_get_config_int("monitor_type"); + ega_init(ega, monitor_type, (monitor_type & 0xf) == 10); 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); @@ -894,6 +936,49 @@ void ega_add_status_info(char *s, int max_len, void *p) strncat(s, temps, max_len); } +static device_config_t ega_config[] = +{ + { + .name = "monitor_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "EGA Colour, 40x25", + .value = 6 + }, + { + .description = "EGA Colour, 80x25", + .value = 7 + }, + { + .description = "EGA Colour, ECD", + .value = 9 + }, + { + .description = "EGA Monochrome (white)", + .value = 10 | (DISPLAY_WHITE << 4) + }, + { + .description = "EGA Monochrome (green)", + .value = 10 | (DISPLAY_GREEN << 4) + }, + { + .description = "EGA Monochrome (amber)", + .value = 10 | (DISPLAY_AMBER << 4) + }, + { + .description = "" + } + }, + .default_int = 9 + }, + { + .type = -1 + } +}; + device_t ega_device = { "EGA", @@ -903,5 +988,6 @@ device_t ega_device = ega_standalone_available, ega_speed_changed, NULL, - ega_add_status_info + ega_add_status_info, + ega_config }; diff --git a/src/vid_ega.h b/src/vid_ega.h index 1c43184..ea3bbbc 100644 --- a/src/vid_ega.h +++ b/src/vid_ega.h @@ -62,6 +62,7 @@ typedef struct ega_t int vrammask; int video_res_x, video_res_y, video_bpp; + int frames; } ega_t; void *ega_standalone_init(); @@ -71,6 +72,6 @@ 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); +void ega_init(ega_t *ega, int monitor_type, int is_mono); extern device_t ega_device; diff --git a/src/vid_pc1640.c b/src/vid_pc1640.c index 9c65ca4..c01dab3 100644 --- a/src/vid_pc1640.c +++ b/src/vid_pc1640.c @@ -119,7 +119,7 @@ void *pc1640_init() rom_init(&pc1640->bios_rom, "pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); - ega_init(&pc1640->ega); + ega_init(&pc1640->ega, 9, 0); pc1640->cga.vram = pc1640->ega.vram; pc1640->cga_enabled = 1; cga_init(&pc1640->cga); From c9d4459e6b74820a61d5d4457b83cdbcdac74bdf Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Jul 2017 21:04:41 +0100 Subject: [PATCH 0086/1050] Fix EGA cursor when cursor end = line 0. --- src/vid_ega.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_ega.c b/src/vid_ega.c index 2cfc331..fc43dd5 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -503,6 +503,8 @@ void ega_poll(void *p) if (ega->sc == (ega->crtc[9] & 31)) { ega->sc = 0; + if (ega->sc == (ega->crtc[11] & 31)) + ega->con = 0; ega->maback += (ega->rowoffset << 3); ega->maback &= ega->vrammask; From 80a411b85f2f35263a35402ad70f28e6be64881e Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 18 Jul 2017 21:47:25 +0100 Subject: [PATCH 0087/1050] EGA now supports < 256kb video memory. --- src/vid_ega.c | 36 +++++++++++++++++++++++++++++++++++- src/vid_ega.h | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index fc43dd5..e9b8df3 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -636,6 +636,9 @@ void ega_write(uint32_t addr, uint8_t val, void *p) addr <<= 2; + if (addr >= ega->vram_limit) + return; + if (!(ega->gdcreg[6] & 1)) fullchange = 2; @@ -766,7 +769,9 @@ uint8_t ega_read(uint32_t addr, void *p) } addr <<= 2; - + if (addr >= ega->vram_limit) + return 0xff; + ega->la = ega->vram[addr]; ega->lb = ega->vram[addr | 0x1]; ega->lc = ega->vram[addr | 0x2]; @@ -869,6 +874,8 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono) ega->pallook = pallook16; egaswitches = monitor_type & 0xf; + ega->vram_limit = 256 * 1024; + ega->vrammask = ega->vram_limit-1; } void *ega_standalone_init() @@ -895,6 +902,9 @@ void *ega_standalone_init() monitor_type = device_get_config_int("monitor_type"); ega_init(ega, monitor_type, (monitor_type & 0xf) == 10); + ega->vram_limit = device_get_config_int("memory") * 1024; + ega->vrammask = ega->vram_limit-1; + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -940,6 +950,30 @@ void ega_add_status_info(char *s, int max_len, void *p) static device_config_t ega_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "64 kB", + .value = 64 + }, + { + .description = "128 kB", + .value = 128 + }, + { + .description = "256 kB", + .value = 256 + }, + { + .description = "" + } + }, + .default_int = 256 + }, { .name = "monitor_type", .description = "Monitor type", diff --git a/src/vid_ega.h b/src/vid_ega.h index ea3bbbc..4d50622 100644 --- a/src/vid_ega.h +++ b/src/vid_ega.h @@ -60,6 +60,7 @@ typedef struct ega_t uint8_t *vram; int vrammask; + uint32_t vram_limit; int video_res_x, video_res_y, video_bpp; int frames; From 47b4e1da1c8d8303462203a5e335a50c42f669c2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 18 Jul 2017 21:48:14 +0100 Subject: [PATCH 0088/1050] Reworked EGA plotting code a bit. Tweaked EGA odd/even handling - 640x350x4 with 64kb video memory now works. --- src/vid_ega.c | 424 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 253 insertions(+), 171 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index e9b8df3..6c96d35 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -250,16 +250,253 @@ void ega_recalctimings(ega_t *ega) // 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]); } +static void ega_draw_text(ega_t *ega) +{ + int x, xx; + + for (x = 0; x < ega->hdisp; x++) + { + int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + uint8_t chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + uint8_t attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + uint8_t dat; + uint32_t fg, bg; + uint32_t charaddr; + + if (attr & 8) + charaddr = ega->charsetb + (chr * 128); + else + charaddr = ega->charseta + (chr * 128); + + if (drawcursor) + { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } + else + { + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; + } + } + + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 32 + (xx << 1)) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + (xx << 1)) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = bg; + else + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = (dat & 1) ? fg : bg; + } + } + else + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x << 3) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = bg; + else + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = (dat & 1) ? fg : bg; + } + } + ega->ma += 4; + ega->ma &= ega->vrammask; + } +} + +static void ega_draw_2bpp(ega_t *ega) +{ + int x; + int offset = ((8 - ega->scrollcache) << 1) + 16; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[2]; + uint32_t addr = ega->ma; + + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + if (ega->seqregs[1] & 4) + ega->ma += 2; + else + ega->ma += 4; + + ega->ma &= ega->vrammask; + + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset]= ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } +} + +static void ega_draw_4bpp_lowres(ega_t *ega) +{ + int x; + int offset = ((8 - ega->scrollcache) << 1) + 16; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = ega->ma; + int oddeven = 0; + + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + if (ega->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + + if (ega->seqregs[1] & 4) + { + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } + else + { + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + edat[2] = ega->vram[addr | 0x2]; + edat[3] = ega->vram[addr | 0x3]; + ega->ma += 4; + } + ega->ma &= ega->vrammask; + + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = 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])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = 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])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = 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])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } +} + +static void ega_draw_4bpp_highres(ega_t *ega) +{ + int x; + int offset = (8 - ega->scrollcache) + 24; + + for (x = 0; x <= ega->hdisp; x++) + { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = ega->ma; + int oddeven = 0; + + if (!(ega->crtc[0x17] & 0x40)) + { + addr = (addr << 1) & ega->vrammask; + if (ega->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + + if (ega->seqregs[1] & 4) + { + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } + else + { + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + edat[2] = ega->vram[addr | 0x2]; + edat[3] = ega->vram[addr | 0x3]; + ega->ma += 4; + } + ega->ma &= ega->vrammask; + + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 6 + offset] = 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])[(x << 3) + 5 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 4 + offset] = 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])[(x << 3) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 2 + offset] = 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])[(x << 3) + 1 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } +} + 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 drawcursor = 0; if (!ega->linepos) { @@ -300,76 +537,7 @@ void ega_poll(void *p) 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[ega->displine])[((x << 4) + 32 + (xx << 1)) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + (xx << 1)) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = bg; - else - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = (dat & 1) ? fg : bg; - } - } - else - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x << 3) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = bg; - else - ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } - } + ega_draw_text(ega); } else { @@ -377,104 +545,12 @@ void ega_poll(void *p) { 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])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = 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])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = 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])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = 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])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } + ega_draw_4bpp_lowres(ega); 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])[(x << 3) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 6 + offset] = 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])[(x << 3) + 5 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 4 + offset] = 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])[(x << 3) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 2 + offset] = 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])[(x << 3) + 1 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } + ega_draw_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[ega->displine])[(x << 4) + 14 + offset]= ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; - } + ega_draw_2bpp(ega); break; } } @@ -632,6 +708,9 @@ void ega_write(uint32_t addr, uint8_t val, void *p) if (addr & 1) writemask2 <<= 1; addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; } addr <<= 2; @@ -766,6 +845,9 @@ uint8_t ega_read(uint32_t addr, void *p) { readplane = (readplane & 2) | (addr & 1); addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; } addr <<= 2; From c6a98090bf92f5e57516cfbf0d0ade29a0bc3fee Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 18 Jul 2017 21:53:31 +0100 Subject: [PATCH 0089/1050] Tweaks to EGA monochrome palettes. Patch from basic2004. --- src/vid_ega.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index 6c96d35..20e2708 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -910,12 +910,24 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono) { for (c = 0; c < 256; c++) { - int video = ((c & 8) ? 2 : 0) | ((c & 16) ? 1 : 0); switch (monitor_type >> 4) { case DISPLAY_GREEN: - pallook64[c] = makecol32(0, video*0x55, 0); - pallook16[c] = makecol32(0, video*0x55, 0); + switch ((c >> 3) & 3) + { + case 0: + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x04, 0x8a, 0x20); + break; + case 1: + pallook64[c] = pallook16[c] = makecol32(0x08, 0xc7, 0x2c); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); + break; + } break; case DISPLAY_AMBER: switch ((c >> 3) & 3) @@ -924,10 +936,10 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono) pallook64[c] = pallook16[c] = makecol32(0, 0, 0); break; case 2: - pallook64[c] = pallook16[c] = makecol32(0x2c, 0x08, 0x00); + pallook64[c] = pallook16[c] = makecol32(0xb2, 0x4d, 0x00); break; case 1: - pallook64[c] = pallook16[c] = makecol32(0xff, 0xae, 0x18); + pallook64[c] = pallook16[c] = makecol32(0xef, 0x79, 0x00); break; case 3: pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); @@ -935,8 +947,21 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono) } break; case DISPLAY_WHITE: default: - pallook64[c] = makecol32(video*0x55, video*0x55, video*0x55); - pallook16[c] = makecol32(video*0x55, video*0x55, video*0x55); + switch ((c >> 3) & 3) + { + case 0: + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x7a, 0x81, 0x83); + break; + case 1: + pallook64[c] = pallook16[c] = makecol32(0xaf, 0xb3, 0xb0); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); + break; + } break; } } From 8b433633c0e36ca0418c4471b8674bc453252dd9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Jul 2017 19:35:01 +0100 Subject: [PATCH 0090/1050] Implement port 0x70 NMI mask. Patch from Greatpsycho. --- src/386.c | 3 ++- src/model.c | 1 + src/nvr.c | 7 ++++++- src/scat.c | 3 ++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/386.c b/src/386.c index 8a03cc4..6b81d79 100644 --- a/src/386.c +++ b/src/386.c @@ -10,6 +10,7 @@ #include "fdc.h" #include "pic.h" #include "timer.h" +#include "nmi.h" #include "386_common.h" @@ -319,7 +320,7 @@ dontprint=0; loadcs(readmemw(0,addr+2)); } } - else if (nmi && nmi_enable) + else if (nmi && nmi_enable && nmi_mask) { cpu_state.oldpc = cpu_state.pc; oldcs = CS; diff --git a/src/model.c b/src/model.c index 5f6bd68..d26d293 100644 --- a/src/model.c +++ b/src/model.c @@ -317,6 +317,7 @@ void at_init() nvr_init(); pic2_init(); device_add(&gameport_device); + nmi_mask = 0; } void ibm_at_init() diff --git a/src/nvr.c b/src/nvr.c index 9258eea..e4934e0 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -7,6 +7,7 @@ #include "rtc.h" #include "paths.h" #include "config.h" +#include "nmi.h" int oldromset; int nvrmask=63; @@ -176,7 +177,11 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) } } } - else nvraddr=val&nvrmask; + else + { + nvraddr=val&nvrmask; + nmi_mask = ~val & 0x80; + } } uint8_t readnvr(uint16_t addr, void *priv) diff --git a/src/scat.c b/src/scat.c index 2a27a04..14a4406 100644 --- a/src/scat.c +++ b/src/scat.c @@ -5,6 +5,7 @@ #include "mem.h" #include "scat.h" #include "x86.h" +#include "nmi.h" static uint8_t scat_regs[256]; static int scat_index; @@ -395,7 +396,7 @@ uint8_t scat_read(uint16_t port, void *priv) switch (scat_index) { case SCAT_MISCELLANEOUS_STATUS: - val = (scat_regs[scat_index] & 0xbf) | ((mem_a20_key & 2) << 5); + val = (scat_regs[scat_index] & 0x3f) | (~nmi_mask & 0x80) | ((mem_a20_key & 2) << 5); break; case SCAT_DRAM_CONFIGURATION: val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); From 904ac544462043688be26401be9fd9cee1a3a62c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Jul 2017 19:35:44 +0100 Subject: [PATCH 0091/1050] Move A20 gate initialisation to mem.c. Patch from Greatpsycho. --- src/mem.c | 5 ++++- src/model.c | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mem.c b/src/mem.c index 25fb4f7..be215ad 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1938,7 +1938,7 @@ void mem_add_bios() } int mem_a20_key = 0, mem_a20_alt = 0; -static int mem_a20_state = 1; +static int mem_a20_state = 2; void mem_init() { @@ -2000,6 +2000,8 @@ void mem_init() 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); // pclog("Mem resize %i %i\n",mem_size,c); + mem_a20_key = 2; + mem_a20_alt = 0; } static void mem_remap_top(int max_size) @@ -2091,6 +2093,7 @@ void mem_resize() // pclog("Mem resize %i %i\n",mem_size,c); mem_a20_key = 2; + mem_a20_alt = 0; mem_a20_recalc(); } diff --git a/src/model.c b/src/model.c index d26d293..8fecc2a 100644 --- a/src/model.c +++ b/src/model.c @@ -308,7 +308,6 @@ void xt_laserxt_init() void at_init() { AT = 1; - mem_a20_key = mem_a20_alt = 0; common_init(); mem_add_bios(); pit_set_out_func(&pit, 1, pit_refresh_timer_at); From b6b9aab6dc39111c1463140a2e57684dc3901b9d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Jul 2017 19:47:00 +0100 Subject: [PATCH 0092/1050] Fix access to undefined variable in x86 task switch code. --- src/x86seg.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index b514f0b..1e744f8 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2500,14 +2500,17 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (optype==OPTYPE_INT || optype==CALL) { writememl(base,0,tr.seg); - new_flags|=NT_FLAG; + if (cpu_state.abrt) + return; } - if (cpu_state.abrt) return; + new_cr3=readmeml(base,0x1C); new_pc=readmeml(base,0x20); new_flags=readmeml(base,0x24); - + if (optype == OPTYPE_INT || optype == CALL) + new_flags |= NT_FLAG; + new_eax=readmeml(base,0x28); new_ecx=readmeml(base,0x2C); new_edx=readmeml(base,0x30); @@ -2709,13 +2712,15 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (optype==OPTYPE_INT || optype==CALL) { writememw(base,0,tr.seg); - new_flags|=NT_FLAG; + if (cpu_state.abrt) + return; } - if (cpu_state.abrt) return; new_pc=readmemw(base,0x0E); new_flags=readmemw(base,0x10); - + if (optype == OPTYPE_INT || optype == CALL) + new_flags |= NT_FLAG; + new_eax=readmemw(base,0x12); new_ecx=readmemw(base,0x14); new_edx=readmemw(base,0x16); From bb4eb4c3b044e8ee4d86950f45026c131cfa68f3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Jul 2017 20:09:36 +0100 Subject: [PATCH 0093/1050] Fixed path in Windows new config file dialog. --- src/win-config_sel.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/win-config_sel.c b/src/win-config_sel.c index 83d08c4..0d89b51 100644 --- a/src/win-config_sel.c +++ b/src/win-config_sel.c @@ -96,12 +96,18 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP case IDC_NEW: { char s[512]; + int c; strcpy(s, configs_path); put_backslash(s); - pclog("Dir %s\n", s); + strcat(s, "*.cfg"); + for (c = 0; c < strlen(s); c++) + { + if (s[c] == '/') + s[c] = '\\'; + } - if (!getsfile(hdlg, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "", s, "cfg")) + if (!getsfile(hdlg, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", s, s, "cfg")) { config_open(hdlg); From a96e87527e7606aef766658a90b7ad1eb3acccce Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 20 Jul 2017 21:06:21 +0100 Subject: [PATCH 0094/1050] Reorganised REP instructions. --- src/386.h | 3 - src/386_common.h | 2 +- src/386_dynarec.c | 881 ------------------------------------------- src/386_ops.h | 182 +++++++++ src/codegen_ops.c | 94 +++++ src/codegen_ops.h | 2 + src/codegen_x86-64.c | 16 + src/codegen_x86.c | 15 + src/cpu.c | 8 + src/x86_ops.h | 10 + src/x86_ops_prefix.h | 97 ++++- src/x86_ops_rep.h | 626 +++++++++++++++++++++++++++++- 12 files changed, 1037 insertions(+), 899 deletions(-) diff --git a/src/386.h b/src/386.h index 9ed872e..595773e 100644 --- a/src/386.h +++ b/src/386.h @@ -11,6 +11,3 @@ int x86_int_sw_rm(int num); int divl(uint32_t val); int idivl(int32_t val); - -int rep386(int fv); - diff --git a/src/386_common.h b/src/386_common.h index 36519fa..3401257 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -28,7 +28,7 @@ int checkio(int port); #define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ { \ - tempi = checkio(port); \ + int tempi = checkio(port); \ if (cpu_state.abrt) break; \ if (tempi) \ { \ diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 6ab9418..c250d9c 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -391,887 +391,6 @@ static void prefetch_flush() #define PREFETCH_FLUSH() prefetch_flush() -int rep386(int fv) -{ - uint8_t temp; - uint32_t c;//=CX; - uint8_t temp2; - uint16_t tempw,tempw2,of; - uint32_t ipc = cpu_state.oldpc;//pc-1; - uint32_t rep32 = cpu_state.op32; - uint32_t templ,templ2; - int tempz; - int tempi; - /*Limit the amount of time the instruction is uninterruptable for, so - that high frequency timers still work okay. This amount is different - for interpreter and recompiler*/ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); - int reads = 0, reads_l = 0, writes = 0, writes_l = 0, total_cycles = 0; - - if (trap) - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ - - cpu_reps++; - - 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: - cpu_state.pc--; - break; - case 0x08: - cpu_state.pc=ipc+1; - break; - case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/ - cpu_state.ea_seg = &_es; - PREFETCH_PREFIX(); - goto startrep; - break; - case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/ - cpu_state.ea_seg = &_cs; - PREFETCH_PREFIX(); - goto startrep; - case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/ - cpu_state.ea_seg = &_ss; - PREFETCH_PREFIX(); - goto startrep; - case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/ - cpu_state.ea_seg = &_ds; - PREFETCH_PREFIX(); - goto startrep; - case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/ - cpu_state.ea_seg = &_fs; - PREFETCH_PREFIX(); - goto startrep; - case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/ - cpu_state.ea_seg = &_gs; - PREFETCH_PREFIX(); - goto startrep; - case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/ - rep32 = (rep32 & 0x200) | ((use32 ^ 0x100) & 0x100); - PREFETCH_PREFIX(); - goto startrep; - case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/ - rep32 = (rep32 & 0x100) | ((use32 ^ 0x200) & 0x200); - PREFETCH_PREFIX(); - goto startrep; - case 0x6C: case 0x16C: /*REP INSB*/ -// cpu_notreps++; - if (c>0) - { - checkio_perm(DX); - temp2=inb(DX); - writememb(es,DI,temp2); - if (cpu_state.abrt) break; - if (flags&D_FLAG) DI--; - else DI++; - c--; - cycles-=15; - reads++; writes++; total_cycles += 15; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x26C: case 0x36C: /*REP INSB*/ -// cpu_notreps++; - if (c>0) - { - checkio_perm(DX); - temp2=inb(DX); - writememb(es,EDI,temp2); - if (cpu_state.abrt) break; - if (flags&D_FLAG) EDI--; - else EDI++; - c--; - cycles-=15; - reads++; writes++; total_cycles += 15; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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; - if (flags&D_FLAG) DI-=2; - else DI+=2; - c--; - cycles-=15; - reads++; writes++; total_cycles += 15; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x16D: /*REP INSL*/ -// cpu_notreps++; - if (c>0) - { - templ=inl(DX); - writememl(es,DI,templ); - if (cpu_state.abrt) break; - if (flags&D_FLAG) DI-=4; - else DI+=4; - c--; - cycles-=15; - reads_l++; writes_l++; total_cycles += 15; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x26D: /*REP INSW*/ -// cpu_notreps++; - if (c>0) - { - tempw=inw(DX); - writememw(es,EDI,tempw); - if (cpu_state.abrt) break; - if (flags&D_FLAG) EDI-=2; - else EDI+=2; - c--; - cycles-=15; - reads++; writes++; total_cycles += 15; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x36D: /*REP INSL*/ -// cpu_notreps++; - if (c>0) - { - templ=inl(DX); - writememl(es,EDI,templ); - if (cpu_state.abrt) break; - if (flags&D_FLAG) EDI-=4; - else EDI+=4; - c--; - cycles-=15; - reads_l++; writes_l++; total_cycles += 15; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x6E: case 0x16E: /*REP OUTSB*/ -// cpu_notreps++; - if (c>0) - { - temp2 = readmemb(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) break; - checkio_perm(DX); - outb(DX,temp2); - if (flags&D_FLAG) SI--; - else SI++; - c--; - cycles-=14; - reads++; writes++; total_cycles += 14; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x26E: case 0x36E: /*REP OUTSB*/ -// cpu_notreps++; - if (c>0) - { - temp2 = readmemb(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) break; - checkio_perm(DX); - outb(DX,temp2); - if (flags&D_FLAG) ESI--; - else ESI++; - c--; - cycles-=14; - reads++; writes++; total_cycles += 14; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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; - c--; - cycles-=14; - reads++; writes++; total_cycles += 14; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x16F: /*REP OUTSL*/ -// cpu_notreps++; - if (c > 0) - { - templ = readmeml(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) break; - outl(DX, templ); - if (flags & D_FLAG) SI -= 4; - else SI += 4; - c--; - cycles -= 14; - reads_l++; writes_l++; total_cycles += 14; - } - if (c > 0) { firstrepcycle = 0; cpu_state.pc = ipc; } - else firstrepcycle = 1; - break; - case 0x26F: /*REP OUTSW*/ -// cpu_notreps++; - if (c>0) - { - tempw = readmemw(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) break; - outw(DX,tempw); - if (flags&D_FLAG) ESI-=2; - else ESI+=2; - c--; - cycles-=14; - reads++; writes++; total_cycles += 14; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x36F: /*REP OUTSL*/ -// cpu_notreps++; - if (c > 0) - { - templ = readmeml(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) break; - outl(DX, templ); - if (flags & D_FLAG) ESI -= 4; - else ESI += 4; - c--; - cycles -= 14; - reads_l++; writes_l++; total_cycles += 14; - } - if (c > 0) { firstrepcycle = 0; cpu_state.pc = ipc; } - else firstrepcycle = 1; - break; - case 0x90: case 0x190: /*REP NOP*/ - case 0x290: case 0x390: -// cpu_notreps++; - break; - case 0xA4: case 0x1A4: /*REP MOVSB*/ - while (c > 0) - { - 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--; - cycles-=(is486)?3:4; - ins++; - reads++; writes++; total_cycles += is486 ? 3 : 4; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x2A4: case 0x3A4: /*REP MOVSB*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, EDI, EDI); - temp2 = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break; - writememb(es,EDI,temp2); if (cpu_state.abrt) break; - if (flags&D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - c--; - cycles-=(is486)?3:4; - ins++; - reads++; writes++; total_cycles += is486 ? 3 : 4; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0xA5: /*REP MOVSW*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, DI, DI+1); - tempw = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break; - writememw(es,DI,tempw); if (cpu_state.abrt) break; - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } - c--; - cycles-=(is486)?3:4; - ins++; - reads++; writes++; total_cycles += is486 ? 3 : 4; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x1A5: /*REP MOVSL*/ - while (c > 0) - { - 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; } - c--; - cycles-=(is486)?3:4; - ins++; - reads_l++; writes_l++; total_cycles += is486 ? 3 : 4; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x2A5: /*REP MOVSW*/ - while (c > 0) - { - 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--; - cycles-=(is486)?3:4; - ins++; - reads++; writes++; total_cycles += is486 ? 3 : 4; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x3A5: /*REP MOVSL*/ - while (c > 0) - { - 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--; - cycles-=(is486)?3:4; - ins++; - reads_l++; writes_l++; total_cycles += is486 ? 3 : 4; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0xA6: case 0x1A6: /*REP CMPSB*/ -// cpu_notreps++; - tempz = (fv) ? 1 : 0; - if ((c>0) && (fv==tempz)) - { - temp = readmemb(cpu_state.ea_seg->base, SI); - temp2=readmemb(es,DI); - if (cpu_state.abrt) { flags=of; break; } - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - c--; - cycles-=(is486)?7:9; - reads += 2; total_cycles += is486 ? 7 : 9; - setsub8(temp,temp2); - tempz = (ZF_SET()) ? 1 : 0; - } - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - break; - case 0x2A6: case 0x3A6: /*REP CMPSB*/ -// cpu_notreps++; - tempz = (fv) ? 1 : 0; - if ((c>0) && (fv==tempz)) - { - temp = readmemb(cpu_state.ea_seg->base, ESI); - temp2=readmemb(es,EDI); - if (cpu_state.abrt) { flags=of; break; } - if (flags&D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - c--; - cycles-=(is486)?7:9; - reads += 2; total_cycles += is486 ? 7 : 9; - setsub8(temp,temp2); - tempz = (ZF_SET()) ? 1 : 0; - } - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - 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; } - else { DI+=2; SI+=2; } - c--; - cycles-=(is486)?7:9; - reads += 2; total_cycles += is486 ? 7 : 9; - setsub16(tempw,tempw2); - tempz = (ZF_SET()) ? 1 : 0; - } - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - break; - case 0x1A7: /*REP CMPSL*/ -// cpu_notreps++; - tempz = (fv) ? 1 : 0; - if ((c>0) && (fv==tempz)) - { - templ = readmeml(cpu_state.ea_seg->base, SI); - templ2=readmeml(es,DI); - if (cpu_state.abrt) { flags=of; break; } - if (flags&D_FLAG) { DI-=4; SI-=4; } - else { DI+=4; SI+=4; } - c--; - cycles-=(is486)?7:9; - reads_l += 2; total_cycles += is486 ? 7 : 9; - setsub32(templ,templ2); - tempz = (ZF_SET()) ? 1 : 0; - } - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - break; - case 0x2A7: /*REP CMPSW*/ -// cpu_notreps++; - tempz = (fv) ? 1 : 0; - if ((c>0) && (fv==tempz)) - { - tempw = readmemw(cpu_state.ea_seg->base, ESI); - tempw2=readmemw(es,EDI); - if (cpu_state.abrt) { flags=of; break; } - if (flags&D_FLAG) { EDI-=2; ESI-=2; } - else { EDI+=2; ESI+=2; } - c--; - cycles-=(is486)?7:9; - reads += 2; total_cycles += is486 ? 7 : 9; - setsub16(tempw,tempw2); - tempz = (ZF_SET()) ? 1 : 0; - } - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - break; - case 0x3A7: /*REP CMPSL*/ -// cpu_notreps++; - tempz = (fv) ? 1 : 0; - if ((c>0) && (fv==tempz)) - { - templ = readmeml(cpu_state.ea_seg->base, ESI); - templ2=readmeml(es,EDI); - if (cpu_state.abrt) { flags=of; break; } - if (flags&D_FLAG) { EDI-=4; ESI-=4; } - else { EDI+=4; ESI+=4; } - c--; - cycles-=(is486)?7:9; - reads_l += 2; total_cycles += is486 ? 7 : 9; - setsub32(templ,templ2); - tempz = (ZF_SET()) ? 1 : 0; - } - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - break; - - case 0xAA: case 0x1AA: /*REP STOSB*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, DI, DI); - writememb(es,DI,AL); - if (cpu_state.abrt) break; - if (flags&D_FLAG) DI--; - else DI++; - c--; - cycles-=(is486)?4:5; - writes++; total_cycles += is486 ? 4 : 5; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x2AA: case 0x3AA: /*REP STOSB*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, EDI, EDI); - writememb(es,EDI,AL); - if (cpu_state.abrt) break; - if (flags&D_FLAG) EDI--; - else EDI++; - c--; - cycles-=(is486)?4:5; - writes++; total_cycles += is486 ? 4 : 5; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0xAB: /*REP STOSW*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, DI, DI+1); - writememw(es,DI,AX); - if (cpu_state.abrt) break; - if (flags&D_FLAG) DI-=2; - else DI+=2; - c--; - cycles-=(is486)?4:5; - writes++; total_cycles += is486 ? 4 : 5; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x2AB: /*REP STOSW*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, EDI, EDI+1); - writememw(es,EDI,AX); - if (cpu_state.abrt) break; - if (flags&D_FLAG) EDI-=2; - else EDI+=2; - c--; - cycles-=(is486)?4:5; - writes++; total_cycles += is486 ? 4 : 5; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x1AB: /*REP STOSL*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, DI, DI+3); - writememl(es,DI,EAX); - if (cpu_state.abrt) break; - if (flags&D_FLAG) DI-=4; - else DI+=4; - c--; - cycles-=(is486)?4:5; - writes_l++; total_cycles += is486 ? 4 : 5; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - break; - case 0x3AB: /*REP STOSL*/ - while (c > 0) - { - CHECK_WRITE_REP(&_es, EDI, EDI+3); - writememl(es,EDI,EAX); - if (cpu_state.abrt) break; - if (flags&D_FLAG) EDI-=4; - else EDI+=4; - c--; - cycles-=(is486)?4:5; - writes_l++; total_cycles += is486 ? 4 : 5; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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); - if (cpu_state.abrt) break; - if (flags&D_FLAG) SI--; - else SI++; - c--; - cycles-=5; - reads++; total_cycles += 5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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); - if (cpu_state.abrt) break; - if (flags&D_FLAG) ESI--; - else ESI++; - c--; - cycles-=5; - reads++; total_cycles += 5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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); - if (cpu_state.abrt) break; - if (flags&D_FLAG) SI-=2; - else SI+=2; - c--; - cycles-=5; - reads++; total_cycles += 5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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); - if (cpu_state.abrt) break; - if (flags&D_FLAG) SI-=4; - else SI+=4; - c--; - cycles-=5; - reads_l++; total_cycles += 5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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); - if (cpu_state.abrt) break; - if (flags&D_FLAG) ESI-=2; - else ESI+=2; - c--; - cycles-=5; - reads++; total_cycles += 5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - 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); - if (cpu_state.abrt) break; - if (flags&D_FLAG) ESI-=4; - else ESI+=4; - c--; - cycles-=5; - reads_l++; total_cycles += 5; - } - if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; } - else firstrepcycle=1; - 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)) - { - temp2=readmemb(es,DI); - if (cpu_state.abrt) { flags=of; break; } - setsub8(AL,temp2); - tempz = (ZF_SET()) ? 1 : 0; - if (flags&D_FLAG) DI--; - else DI++; - c--; - cycles-=(is486)?5:8; - reads++; total_cycles += is486 ? 5 : 8; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - 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--; - else EDI++; - c--; - cycles-=(is486)?5:8; - reads++; total_cycles += is486 ? 5 : 8; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - 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)) - { - tempw=readmemw(es,DI); - if (cpu_state.abrt) { flags=of; break; } - setsub16(AX,tempw); - tempz = (ZF_SET()) ? 1 : 0; - if (flags&D_FLAG) DI-=2; - else DI+=2; - c--; - cycles-=(is486)?5:8; - reads++; total_cycles += is486 ? 5 : 8; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - 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)) - { - templ=readmeml(es,DI); - if (cpu_state.abrt) { flags=of; break; } - setsub32(EAX,templ); - tempz = (ZF_SET()) ? 1 : 0; - if (flags&D_FLAG) DI-=4; - else DI+=4; - c--; - cycles-=(is486)?5:8; - reads_l++; total_cycles += is486 ? 5 : 8; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - 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)) - { - tempw=readmemw(es,EDI); - if (cpu_state.abrt) { flags=of; break; } - setsub16(AX,tempw); - tempz = (ZF_SET()) ? 1 : 0; - if (flags&D_FLAG) EDI-=2; - else EDI+=2; - c--; - cycles-=(is486)?5:8; - reads++; total_cycles += is486 ? 5 : 8; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - 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)) - { - templ=readmeml(es,EDI); - if (cpu_state.abrt) { flags=of; break; } - setsub32(EAX,templ); - tempz = (ZF_SET()) ? 1 : 0; - if (flags&D_FLAG) EDI-=4; - else EDI+=4; - c--; - cycles-=(is486)?5:8; - reads_l++; total_cycles += is486 ? 5 : 8; - ins++; - if (cycles < cycles_end) - break; - } - ins--; - if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; } - else firstrepcycle=1; - break; - - - default: - cpu_state.pc = ipc+1; - //pclog("Bad REP %02X %i\n", temp, rep32 >> 8); - break; - } - if (rep32&0x200) ECX=c; - else CX=c; - 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; diff --git a/src/386_ops.h b/src/386_ops.h index 43a7cfd..0d74ad7 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -910,4 +910,186 @@ OpFn OP_TABLE(386)[1024] = /*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, }; +OpFn OP_TABLE(REPE)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_w_a16,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_w_a16,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_l_a16,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_l_a16,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_w_a32,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_w_a32,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_l_a32,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_l_a32,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +OpFn OP_TABLE(REPNE)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_w_a16,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_w_a16,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_l_a16,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_l_a16,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_w_a32,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_w_a32,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_l_a32,ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_l_a32,ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE, +/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + #include "x87_ops.h" diff --git a/src/codegen_ops.c b/src/codegen_ops.c index e4fb0c4..68da1ed 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -495,3 +495,97 @@ RecompOpFn recomp_opcodes_df[512] = /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; + +RecompOpFn recomp_opcodes_REPE[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +RecompOpFn recomp_opcodes_REPNE[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 3f0d1be..2e38ec1 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -10,6 +10,8 @@ extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; extern RecompOpFn recomp_opcodes_df[512]; +RecompOpFn recomp_opcodes_REPE[512]; +RecompOpFn recomp_opcodes_REPNE[512]; #define REG_EAX 0 #define REG_ECX 1 diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index 91de59f..3e3f679 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -1059,6 +1059,15 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xf0: /*LOCK*/ break; + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = recomp_opcodes_REPE; + break; + default: goto generate_call; } @@ -1110,6 +1119,13 @@ generate_call: } #endif } + + if ((op_table == x86_opcodes_REPNE || op_table == x86_opcodes_REPE) && !op_table[opcode | op_32]) + { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); diff --git a/src/codegen_x86.c b/src/codegen_x86.c index 0474703..4d71317 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -1991,6 +1991,15 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xf0: /*LOCK*/ break; + + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = recomp_opcodes_REPE; + break; default: goto generate_call; @@ -2044,6 +2053,12 @@ generate_call: #endif } + if ((op_table == x86_opcodes_REPNE || op_table == x86_opcodes_REPE) && !op_table[opcode | op_32]) + { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); diff --git a/src/cpu.c b/src/cpu.c index 2610ca3..4f1b6ec 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -28,6 +28,8 @@ OpFn *x86_dynarec_opcodes_de_a16; OpFn *x86_dynarec_opcodes_de_a32; OpFn *x86_dynarec_opcodes_df_a16; OpFn *x86_dynarec_opcodes_df_a32; +OpFn *x86_dynarec_opcodes_REPE; +OpFn *x86_dynarec_opcodes_REPNE; OpFn *x86_opcodes; OpFn *x86_opcodes_0f; @@ -47,6 +49,8 @@ OpFn *x86_opcodes_de_a16; OpFn *x86_opcodes_de_a32; OpFn *x86_opcodes_df_a16; OpFn *x86_opcodes_df_a32; +OpFn *x86_opcodes_REPE; +OpFn *x86_opcodes_REPNE; enum { @@ -514,6 +518,10 @@ void cpu_set() pclog("is486 - %i %i\n",is486,cpu_s->cpu_type); x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); + x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPNE = ops_REPNE; + x86_dynarec_opcodes_REPE = dynarec_ops_REPE; + x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; if (hasfpu) { diff --git a/src/x86_ops.h b/src/x86_ops.h index 1aa5ae6..7919ec4 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -23,6 +23,8 @@ extern OpFn *x86_dynarec_opcodes_de_a16; extern OpFn *x86_dynarec_opcodes_de_a32; extern OpFn *x86_dynarec_opcodes_df_a16; extern OpFn *x86_dynarec_opcodes_df_a32; +extern OpFn *x86_dynarec_opcodes_REPE; +extern OpFn *x86_dynarec_opcodes_REPNE; extern OpFn dynarec_ops_286[1024]; extern OpFn dynarec_ops_286_0f[1024]; @@ -62,6 +64,9 @@ extern OpFn dynarec_ops_fpu_686_db_a32[256]; extern OpFn dynarec_ops_fpu_686_df_a16[256]; extern OpFn dynarec_ops_fpu_686_df_a32[256]; +extern OpFn dynarec_ops_REPE[1024]; +extern OpFn dynarec_ops_REPNE[1024]; + extern OpFn *x86_opcodes; extern OpFn *x86_opcodes_0f; extern OpFn *x86_opcodes_d8_a16; @@ -80,6 +85,8 @@ extern OpFn *x86_opcodes_de_a16; extern OpFn *x86_opcodes_de_a32; extern OpFn *x86_opcodes_df_a16; extern OpFn *x86_opcodes_df_a32; +extern OpFn *x86_opcodes_REPE; +extern OpFn *x86_opcodes_REPNE; extern OpFn ops_286[1024]; extern OpFn ops_286_0f[1024]; @@ -120,4 +127,7 @@ extern OpFn ops_fpu_686_db_a32[256]; extern OpFn ops_fpu_686_df_a16[256]; extern OpFn ops_fpu_686_df_a32[256]; +extern OpFn ops_REPE[1024]; +extern OpFn ops_REPNE[1024]; + #endif /*_X86_OPS_H*/ diff --git a/src/x86_ops_prefix.h b/src/x86_ops_prefix.h index 18d84d7..48147c7 100644 --- a/src/x86_ops_prefix.h +++ b/src/x86_ops_prefix.h @@ -1,4 +1,4 @@ -#define op_seg(name, seg) \ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ static int op ## name ## _w_a16(uint32_t fetchdat) \ { \ fetchdat = fastreadl(cs + cpu_state.pc); \ @@ -10,7 +10,9 @@ static int op ## name ## _w_a16(uint32_t fetchdat) \ CLOCK_CYCLES(4); \ PREFETCH_PREFIX(); \ \ - return x86_opcodes[fetchdat & 0xff](fetchdat >> 8); \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ } \ \ static int op ## name ## _l_a16(uint32_t fetchdat) \ @@ -24,7 +26,9 @@ static int op ## name ## _l_a16(uint32_t fetchdat) \ CLOCK_CYCLES(4); \ PREFETCH_PREFIX(); \ \ - return x86_opcodes[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ } \ \ static int op ## name ## _w_a32(uint32_t fetchdat) \ @@ -38,7 +42,9 @@ static int op ## name ## _w_a32(uint32_t fetchdat) \ CLOCK_CYCLES(4); \ PREFETCH_PREFIX(); \ \ - return x86_opcodes[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ } \ \ static int op ## name ## _l_a32(uint32_t fetchdat) \ @@ -52,15 +58,31 @@ static int op ## name ## _l_a32(uint32_t fetchdat) \ CLOCK_CYCLES(4); \ PREFETCH_PREFIX(); \ \ - return x86_opcodes[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ } -op_seg(CS, _cs) -op_seg(DS, _ds) -op_seg(ES, _es) -op_seg(FS, _fs) -op_seg(GS, _gs) -op_seg(SS, _ss) +op_seg(CS, _cs, x86_opcodes, x86_opcodes) +op_seg(DS, _ds, x86_opcodes, x86_opcodes) +op_seg(ES, _es, x86_opcodes, x86_opcodes) +op_seg(FS, _fs, x86_opcodes, x86_opcodes) +op_seg(GS, _gs, x86_opcodes, x86_opcodes) +op_seg(SS, _ss, x86_opcodes, x86_opcodes) + +op_seg(CS_REPE, _cs, x86_opcodes_REPE, x86_opcodes) +op_seg(DS_REPE, _ds, x86_opcodes_REPE, x86_opcodes) +op_seg(ES_REPE, _es, x86_opcodes_REPE, x86_opcodes) +op_seg(FS_REPE, _fs, x86_opcodes_REPE, x86_opcodes) +op_seg(GS_REPE, _gs, x86_opcodes_REPE, x86_opcodes) +op_seg(SS_REPE, _ss, x86_opcodes_REPE, x86_opcodes) + +op_seg(CS_REPNE, _cs, x86_opcodes_REPNE, x86_opcodes) +op_seg(DS_REPNE, _ds, x86_opcodes_REPNE, x86_opcodes) +op_seg(ES_REPNE, _es, x86_opcodes_REPNE, x86_opcodes) +op_seg(FS_REPNE, _fs, x86_opcodes_REPNE, x86_opcodes) +op_seg(GS_REPNE, _gs, x86_opcodes_REPNE, x86_opcodes) +op_seg(SS_REPNE, _ss, x86_opcodes_REPNE, x86_opcodes) static int op_66(uint32_t fetchdat) /*Data size select*/ { @@ -84,3 +106,56 @@ static int op_67(uint32_t fetchdat) /*Address size select*/ PREFETCH_PREFIX(); return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } + +static int op_66_REPE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int op_67_REPE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} +static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +{ + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index 7d3713a..f116661 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -1,9 +1,629 @@ +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ +static int opREP_INSB_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) \ + { \ + uint8_t temp; \ + \ + check_io_perm(DX); \ + temp = inb(DX); \ + writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) DEST_REG--; \ + else DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; writes++; total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_INSW_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) \ + { \ + uint16_t temp; \ + \ + check_io_perm(DX); \ + check_io_perm(DX+1); \ + temp = inw(DX); \ + writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) DEST_REG -= 2; \ + else DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; writes++; total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_INSL_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) \ + { \ + uint32_t temp; \ + \ + check_io_perm(DX); \ + check_io_perm(DX+1); \ + check_io_perm(DX+2); \ + check_io_perm(DX+3); \ + temp = inl(DX); \ + writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) DEST_REG -= 4; \ + else DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; writes++; total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ + \ +static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) \ + { \ + uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (flags & D_FLAG) SRC_REG--; \ + else SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; writes++; total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) \ + { \ + uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + check_io_perm(DX); \ + check_io_perm(DX+1); \ + outw(DX, temp); \ + if (flags & D_FLAG) SRC_REG -= 2; \ + else SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; writes++; total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) \ + { \ + uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + check_io_perm(DX); \ + check_io_perm(DX+1); \ + check_io_perm(DX+2); \ + check_io_perm(DX+3); \ + outl(DX, temp); \ + if (flags & D_FLAG) SRC_REG -= 4; \ + else SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; writes++; total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ + \ +static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + uint8_t temp; \ + \ + CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ + else { DEST_REG++; SRC_REG++; } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + ins++; \ + reads++; writes++; total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + ins--; \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + uint16_t temp; \ + \ + CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ + else { DEST_REG += 2; SRC_REG += 2; } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + ins++; \ + reads++; writes++; total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + ins--; \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + uint32_t temp; \ + \ + CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ + else { DEST_REG += 4; SRC_REG += 4; } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + ins++; \ + reads++; writes++; total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + ins--; \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ + \ + \ +static int opREP_STOSB_ ## size(uint32_t fetchdat) \ +{ \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ + if (flags & D_FLAG) DEST_REG--; \ + else DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; total_cycles += is486 ? 4 : 5; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_STOSW_ ## size(uint32_t fetchdat) \ +{ \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \ + writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ + if (flags & D_FLAG) DEST_REG -= 2; \ + else DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; total_cycles += is486 ? 4 : 5; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_STOSL_ ## size(uint32_t fetchdat) \ +{ \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \ + writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ + if (flags & D_FLAG) DEST_REG -= 4; \ + else DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; total_cycles += is486 ? 4 : 5; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ + \ +static int opREP_LODSB_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + if (flags & D_FLAG) SRC_REG--; \ + else SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; total_cycles += is486 ? 4 : 5; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_LODSW_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + if (flags & D_FLAG) SRC_REG -= 2; \ + else SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; total_cycles += is486 ? 4 : 5; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_LODSL_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + while (CNT_REG > 0) \ + { \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + if (flags & D_FLAG) SRC_REG -= 4; \ + else SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; total_cycles += is486 ? 4 : 5; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if (CNT_REG > 0) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ + + +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ +static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0, tempz; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ + else { DEST_REG++; SRC_REG++; } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; total_cycles += is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0, tempz; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ + else { DEST_REG += 2; SRC_REG += 2; } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; total_cycles += is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0, tempz; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ + \ + if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ + else { DEST_REG += 4; SRC_REG += 4; } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; total_cycles += is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ + \ +static int opREP_SCASB_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + tempz = FV; \ + while ((CNT_REG > 0) && (FV == tempz)) \ + { \ + uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (flags & D_FLAG) DEST_REG--; \ + else DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; total_cycles += is486 ? 5 : 8; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + ins--; \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_SCASW_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + tempz = FV; \ + while ((CNT_REG > 0) && (FV == tempz)) \ + { \ + uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (flags & D_FLAG) DEST_REG -= 2; \ + else DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; total_cycles += is486 ? 5 : 8; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + ins--; \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} \ +static int opREP_SCASL_ ## size(uint32_t fetchdat) \ +{ \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + \ + tempz = FV; \ + while ((CNT_REG > 0) && (FV == tempz)) \ + { \ + uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (flags & D_FLAG) DEST_REG -= 4; \ + else DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; total_cycles += is486 ? 5 : 8; \ + ins++; \ + if (cycles < cycles_end) \ + break; \ + } \ + ins--; \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) \ + { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ +} + +REP_OPS(a16, CX, SI, DI) +REP_OPS(a32, ECX, ESI, EDI) +REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) + static int opREPNE(uint32_t fetchdat) { - return rep386(0); + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } static int opREPE(uint32_t fetchdat) { - return rep386(1); -} + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} From a8833997811f4a04beffecb789add62ea112c869 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 23 Jul 2017 17:41:24 +0100 Subject: [PATCH 0095/1050] Added AGI stalls to 486 and later CPUs. Reworked codegen timing a bit - split timing tables into CPU-specific and generic files. A few other timing tweaks. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/codegen.h | 6 + src/codegen_ops.h | 7 + src/codegen_timing_486.c | 67 ++- src/codegen_timing_686.c | 627 ++++++++++++++------------- src/codegen_timing_common.c | 678 ++++++++++++++++++++++++++++++ src/codegen_timing_common.h | 226 ++++++++++ src/codegen_timing_pentium.c | 794 +++++++++++++++++------------------ src/codegen_timing_winchip.c | 65 ++- 17 files changed, 1740 insertions(+), 748 deletions(-) create mode 100644 src/codegen_timing_common.c create mode 100644 src/codegen_timing_common.h diff --git a/src/Makefile.am b/src/Makefile.am index b5c1e19..9cf520b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,7 @@ amrefresh: pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc 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 \ +codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 5a82431..430397b 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -6,7 +6,7 @@ LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index fe9abe5..2c109cd 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 1d55536..fb25ff6 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -5,7 +5,7 @@ CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 15c98c1..6d6b385 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.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.c compaq.o config.o cpu.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 7c8259e..9d1aa5b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -4,7 +4,7 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 60feb55..0ecfaa4 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 2454ecb..10c5193 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -4,7 +4,7 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.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 \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 5e05dc1..9fc9bd3 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.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.c compaq.o config.o cpu.o \ +codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ diff --git a/src/codegen.h b/src/codegen.h index a88f39d..8eaab36 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -1,4 +1,8 @@ +#ifndef _CODEGEN_H_ +#define _CODEGEN_H_ + #include "mem.h" +#include "x86_ops.h" #ifdef __amd64__ #include "codegen_x86-64.h" @@ -358,3 +362,5 @@ extern int codegen_fpu_loaded_iq[8]; extern int codegen_reg_loaded[8]; extern int codegen_in_recompile; + +#endif diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 2e38ec1..7060238 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -1,3 +1,8 @@ +#ifndef _CODEGEN_OPS_H_ +#define _CODEGEN_OPS_H_ + +#include "codegen.h" + typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block); extern RecompOpFn recomp_opcodes[512]; @@ -37,3 +42,5 @@ RecompOpFn recomp_opcodes_REPNE[512]; #define REG_DH 6 #define REG_BL 3 #define REG_BH 7 + +#endif diff --git a/src/codegen_timing_486.c b/src/codegen_timing_486.c index c88f9ca..4e05e24 100644 --- a/src/codegen_timing_486.c +++ b/src/codegen_timing_486.c @@ -5,6 +5,8 @@ #include "x87.h" #include "mem.h" #include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" #define CYCLES(c) (int *)c #define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) @@ -247,9 +249,22 @@ static int *opcode_timings_8x[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; +static int *opcode_timings_8x_mod3[8] = +{ + &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm +}; +static int *opcode_timings_81[8] = +{ + &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm +}; +static int *opcode_timings_81_mod3[8] = +{ + &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm +}; static int timing_count; static uint8_t last_prefix; +static uint32_t regmask_modified; static inline int COUNT(int *c, int op_32) { @@ -266,6 +281,7 @@ static inline int COUNT(int *c, int op_32) void codegen_timing_486_block_start() { + regmask_modified = 0; } void codegen_timing_486_start() @@ -283,82 +299,123 @@ void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { int **timings; + uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); - + int bit8 = !(opcode & 1); + switch (last_prefix) { case 0x0f: timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; +// pclog("timings 0f\n"); break; case 0xd8: timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; +// pclog("timings d8\n"); break; case 0xd9: timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings d9\n"); break; case 0xda: timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; +// pclog("timings da\n"); break; case 0xdb: timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings db\n"); break; case 0xdc: timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; +// pclog("timings dc\n"); break; case 0xdd: timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; +// pclog("timings dd\n"); break; case 0xde: timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; +// pclog("timings de\n"); break; case 0xdf: timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; +// pclog("timings df\n"); break; default: switch (opcode) { - case 0x80: case 0x81: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; - if (!mod3) - opcode = (fetchdat >> 3) & 7; + case 0x80: case 0x82: case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; + opcode = (fetchdat >> 3) & 7; +// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + 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; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; +// pclog("timings c0\n"); break; case 0xf6: timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; +// pclog("timings f6\n"); break; case 0xf7: timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; +// pclog("timings f7\n"); break; case 0xff: timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; +// pclog("timings ff\n"); break; default: timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; +// pclog("timings normal\n"); break; } } timing_count += COUNT(timings[opcode], op_32); + if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) + timing_count++; /*AGI stall*/ codegen_block_cycles += timing_count; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } void codegen_timing_486_block_end() diff --git a/src/codegen_timing_686.c b/src/codegen_timing_686.c index efe7917..5bcd55e 100644 --- a/src/codegen_timing_686.c +++ b/src/codegen_timing_686.c @@ -2,6 +2,7 @@ - X/Y pairing - FPU/FXCH pairing - Prefix decode delay + - AGI stalls Elements not taken into account : - Branch prediction (beyond most simplistic approximation) - FPU queue @@ -15,6 +16,7 @@ #include "x87.h" #include "mem.h" #include "codegen.h" +#include "codegen_timing_common.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ #define CYCLES_HAS_MULTI (1 << 31) @@ -33,11 +35,6 @@ #define CYCLES_MASK ((1 << 7) - 1) -/*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1 << 7) -/*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1 << 8) - /*Instruction does not pair*/ #define PAIR_NP (0 << 29) /*Instruction pairs in X pipe only*/ @@ -49,35 +46,6 @@ #define PAIR_MASK (3 << 29) -/*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1 << 9) -/*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1 << 10) -/*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1 << 11) -/*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1 << 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) - -/*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 INVALID 0 static int prev_full; @@ -85,119 +53,74 @@ static uint32_t prev_opcode; static uint32_t *prev_timings; static uint32_t prev_op_32; static uint32_t prev_regmask; +static uint64_t *prev_deps; +static uint32_t prev_fetchdat; -#define REGMASK_MMX (1 << 8) +static uint32_t regmask_modified; -static uint32_t get_srcdep_mask(uint32_t data, uint32_t fetchdat, int bit8) -{ - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> 16) & 0xff); - if (data & (MMX_SHIFTPACK | MMX_MULTIPLY)) - mask |= REGMASK_MMX; - - return mask; -} - -static uint32_t get_dstdep_mask(uint32_t data, uint32_t fetchdat, int bit8) -{ - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> 24) & 0xff); - if (data & (MMX_SHIFTPACK | MMX_MULTIPLY)) - mask |= REGMASK_MMX; - - return mask; -} static uint32_t opcode_timings[256] = { -/* ADD ADD ADD ADD*/ -/*00*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* ADD ADD PUSH ES POP ES*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* OR OR PUSH CS */ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, INVALID, +/* ADD ADD ADD ADD*/ +/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* ADD ADD PUSH ES POP ES*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* OR OR OR OR*/ + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* OR OR PUSH CS */ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* ADC ADC PUSH SS POP SS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3), +/* ADC ADC ADC ADC*/ +/*10*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* ADC ADC PUSH SS POP SS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* SBB SBB SBB SBB*/ + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* SBB SBB PUSH DS POP DS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* AND AND AND AND*/ -/*20*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* AND AND DAA*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7), -/* SUB SUB SUB SUB*/ - PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* SUB SUB DAS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7), +/* AND AND AND AND*/ +/*20*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* AND AND DAA*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), +/* SUB SUB SUB SUB*/ + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* SUB SUB DAS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* XOR XOR AAA*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7), -/* CMP CMP CMP CMP*/ - PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, -/* CMP CMP AAS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(7), +/* XOR XOR XOR XOR*/ +/*30*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* XOR XOR AAA*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), +/* CMP CMP CMP CMP*/ + PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, +/* CMP CMP AAS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* INC ESP INC EBP INC ESI INC EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP, +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* POP EAX POP ECX POP EDX POP EBX*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* POP ESP POP EBP POP ESI POP EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(10), PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), +/* PUSHA POPA BOUND ARPL*/ +/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), +/* INSB INSW OUTSB OUTSW*/ + PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), /* Jxx*/ /*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, @@ -205,37 +128,37 @@ static uint32_t opcode_timings[256] = PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG, PAIR_XY | CYCLES_REG | DSTDEP_REG, PAIR_XY | CYCLES_REG | DSTDEP_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG | DSTDEP_REG, CYCLES(3), PAIR_XY | CYCLES(1), +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), +/* MOV MOV MOV MOV*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* MOV from seg LEA MOV to seg POP*/ + PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, CYCLES(3), PAIR_XY | CYCLES(1), -/* NOP XCHG XCHG XCHG*/ -/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* XCHG XCHG XCHG XCHG*/ - PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* CBW CWD CALL far WAIT*/ - PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), -/* PUSHF POPF SAHF LAHF*/ - PAIR_XY | CYCLES(2) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(9) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), +/* NOP XCHG XCHG XCHG*/ +/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), +/* XCHG XCHG XCHG XCHG*/ + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), +/* CBW CWD CALL far WAIT*/ + PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), +/* PUSHF POPF SAHF LAHF*/ + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ -/*a0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, -/* MOVSB MOVSW CMPSB CMPSW*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), -/* TEST TEST STOSB STOSW*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* LODSB LODSW SCASB SCASW*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), +/* MOV MOV MOV MOV*/ +/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* MOVSB MOVSW CMPSB CMPSW*/ + PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), +/* TEST TEST STOSB STOSW*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), +/* LODSB LODSW SCASB SCASW*/ + PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), /* MOV*/ -/*b0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX, - PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX, - PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX, - PAIR_XY | CYCLES_REG | DSTDEP_ESP, PAIR_XY | CYCLES_REG | DSTDEP_EBP, PAIR_XY | CYCLES_REG | DSTDEP_ESI, PAIR_XY | CYCLES_REG | DSTDEP_EDI, +/*b0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, /* RET imm RET*/ /*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2), @@ -253,7 +176,7 @@ static uint32_t opcode_timings[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, +/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, /* IN AL IN AX OUT_AL OUT_AX*/ PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), /* CALL JMP JMP JMP*/ @@ -273,68 +196,67 @@ static uint32_t opcode_timings[256] = static uint32_t opcode_timings_mod3[256] = { -/* ADD ADD ADD ADD*/ -/*00*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* ADD ADD PUSH ES POP ES*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3), -/* OR OR OR OR*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* OR OR PUSH CS */ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, INVALID, +/* ADD ADD ADD ADD*/ +/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* ADD ADD PUSH ES POP ES*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* OR OR OR OR*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* OR OR PUSH CS */ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* ADC ADC PUSH SS POP SS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3), -/* SBB SBB SBB SBB*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3), +/* ADC ADC ADC ADC*/ +/*10*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* ADC ADC PUSH SS POP SS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* SBB SBB SBB SBB*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* SBB SBB PUSH DS POP DS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* AND AND AND AND*/ -/*20*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* AND AND DAA*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(9), -/* SUB SUB SUB SUB*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* SUB SUB DAS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(9), +/* AND AND AND AND*/ +/*20*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* AND AND DAA*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), +/* SUB SUB SUB SUB*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* SUB SUB DAS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* XOR XOR XOR XOR*/ -/*30*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, -/* XOR XOR AAA*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7), -/* CMP CMP CMP CMP*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | SRCDEP_REG, -/* CMP CMP AAS*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(7), +/* XOR XOR XOR XOR*/ +/*30*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* XOR XOR AAA*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), +/* CMP CMP CMP CMP*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* CMP CMP AAS*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7), -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* INC ESP INC EBP INC ESI INC EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP, -/* POP EAX POP ECX POP EDX POP EBX*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP, +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* POP EAX POP ECX POP EDX POP EBX*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* POP ESP POP EBP POP ESI POP EDI*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, -/* PUSHA POPA BOUND ARPL*/ -/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(10), PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(10), -/* INSB INSW OUTSB OUTSW*/ - PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), +/* PUSHA POPA BOUND ARPL*/ +/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9), + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), +/* INSB INSW OUTSB OUTSW*/ + PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), /* Jxx*/ /*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, @@ -342,13 +264,13 @@ static uint32_t opcode_timings_mod3[256] = PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, -/*80*/ PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, -/* TEST TEST XCHG XCHG*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), -/* MOV MOV MOV MOV*/ - PAIR_XY | CYCLES_REG | SRCDEP_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG | DSTDEP_REG, PAIR_NP | CYCLES(3), PAIR_XY | CYCLES(1), +/*80*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* TEST TEST XCHG XCHG*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), +/* MOV MOV MOV MOV*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, +/* MOV from seg LEA MOV to seg POP*/ + PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_XY | CYCLES(1), /* NOP XCHG XCHG XCHG*/ /*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), @@ -357,22 +279,22 @@ static uint32_t opcode_timings_mod3[256] = /* CBW CWD CALL far WAIT*/ PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), /* PUSHF POPF SAHF LAHF*/ - PAIR_XY | CYCLES(2) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(9) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2), /* MOV MOV MOV MOV*/ -/*a0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, +/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, /* MOVSB MOVSW CMPSB CMPSW*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), /* TEST TEST STOSB STOSW*/ - PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), /* LODSB LODSW SCASB SCASW*/ PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), /* MOV*/ -/*b0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX, - PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX, - PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX, - PAIR_XY | CYCLES_REG | DSTDEP_ESP, PAIR_XY | CYCLES_REG | DSTDEP_EBP, PAIR_XY | CYCLES_REG | DSTDEP_ESI, PAIR_XY | CYCLES_REG | DSTDEP_EDI, +/*b0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, /* RET imm RET*/ /*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2), @@ -391,7 +313,7 @@ static uint32_t opcode_timings_mod3[256] = INVALID, INVALID, INVALID, INVALID, /* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, +/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, /* IN AL IN AX OUT_AL OUT_AX*/ PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), /* CALL JMP JMP JMP*/ @@ -441,15 +363,15 @@ static uint32_t opcode_timings_0f[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*60*/ PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, - PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, - INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, +/*60*/ PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, + INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, -/*70*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES(1), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, +/*70*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES(1), + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, /*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, @@ -476,20 +398,20 @@ static uint32_t opcode_timings_0f[256] = PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), -/*d0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, +/*d0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, + INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, -/*e0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, INVALID, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, +/*e0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, + INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM, -/*f0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, - INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, - PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, +/*f0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, + INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, + PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, }; static uint32_t opcode_timings_0f_mod3[256] = { @@ -523,15 +445,15 @@ static uint32_t opcode_timings_0f_mod3[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*60*/ PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, - PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, - INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, +/*60*/ PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, + INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, -/*70*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES(1), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, +/*70*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES(1), + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, /*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, @@ -557,20 +479,20 @@ static uint32_t opcode_timings_0f_mod3[256] = 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), -/*d0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, - INVALID, PAIR_X | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, +/*d0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, + INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, -/*e0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, INVALID, - INVALID, PAIR_X | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, +/*e0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, + INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG, -/*f0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, - INVALID, PAIR_X | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, - PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, +/*f0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, + INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, + PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, }; static uint32_t opcode_timings_shift[8] = @@ -580,8 +502,8 @@ static uint32_t opcode_timings_shift[8] = }; static uint32_t opcode_timings_shift_mod3[8] = { - PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES(3) | DSTDEP_RM, PAIR_XY | CYCLES(4) | DSTDEP_RM, - PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, }; static uint32_t opcode_timings_shift_imm[8] = { @@ -590,18 +512,18 @@ static uint32_t opcode_timings_shift_imm[8] = }; static uint32_t opcode_timings_shift_imm_mod3[8] = { - PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES(3) | DSTDEP_RM, PAIR_XY | CYCLES(4) | DSTDEP_RM, - PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, }; static uint32_t opcode_timings_shift_cl[8] = { - PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(8) | SRCDEP_ECX, PAIR_XY | CYCLES(9) | SRCDEP_ECX, - PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), }; static uint32_t opcode_timings_shift_cl_mod3[8] = { - PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(8) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(9) | DSTDEP_RM | SRCDEP_ECX, - PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), + PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), }; static uint32_t opcode_timings_f6[8] = @@ -613,22 +535,22 @@ static uint32_t opcode_timings_f6[8] = }; static uint32_t opcode_timings_f6_mod3[8] = { -/* TST NOT NEG*/ - PAIR_XY | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), +/* TST NOT NEG*/ + PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) }; static uint32_t opcode_timings_f7[8] = { /* TST NOT NEG*/ - PAIR_XY | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), + PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) }; static uint32_t opcode_timings_f7_mod3[8] = { /* TST NOT NEG*/ - PAIR_XY | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), + PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) }; @@ -637,14 +559,14 @@ static uint32_t opcode_timings_ff[8] = /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), /* JMP JMP far PUSH*/ - PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, INVALID + PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID }; static uint32_t opcode_timings_ff_mod3[8] = { -/* INC DEC CALL CALL far*/ - PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), -/* JMP JMP far PUSH*/ - PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2) | SRCDEP_ESP | DSTDEP_ESP, INVALID +/* INC DEC CALL CALL far*/ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), +/* JMP JMP far PUSH*/ + PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID }; static uint32_t opcode_timings_d8[8] = @@ -812,8 +734,23 @@ static uint32_t opcode_timings_df_mod3[8] = static uint32_t opcode_timings_8x[8] = { - PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, - PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM +}; +static uint32_t opcode_timings_8x_mod3[8] = +{ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG +}; +static uint32_t opcode_timings_81[8] = +{ + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, + PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM +}; +static uint32_t opcode_timings_81_mod3[8] = +{ + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, + PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG }; static int decode_delay; @@ -836,6 +773,7 @@ static inline int COUNT(uint32_t c, int op_32) void codegen_timing_686_block_start() { prev_full = decode_delay = 0; + regmask_modified = 0; } void codegen_timing_686_start() @@ -853,9 +791,20 @@ void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; } +static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +{ + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + + if (addr_regmask & IMPL_ESP) + addr_regmask |= (1 << REG_ESP); + + return regmask_modified & addr_regmask; +} + void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { uint32_t *timings; + uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); int bit8 = !(opcode & 1); @@ -863,46 +812,55 @@ 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; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; // pclog("timings 0f\n"); break; case 0xd8: timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; // pclog("timings d8\n"); break; case 0xd9: timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; // pclog("timings d9\n"); break; case 0xda: timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; // pclog("timings da\n"); break; case 0xdb: timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; // pclog("timings db\n"); break; case 0xdc: timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; // pclog("timings dc\n"); break; case 0xdd: timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; // pclog("timings dd\n"); break; case 0xde: timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; // pclog("timings de\n"); break; case 0xdf: timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; // pclog("timings df\n"); break; @@ -910,46 +868,62 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) default: switch (opcode) { - case 0x80: case 0x81: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; - if (!mod3) - opcode = (fetchdat >> 3) & 7; + case 0x80: case 0x82: case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; + opcode = (fetchdat >> 3) & 7; +// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + 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: timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; +// pclog("timings c0\n"); break; - + case 0xd0: case 0xd1: timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; +// pclog("timings d0\n"); break; - + case 0xd2: case 0xd3: timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; + deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; opcode = (fetchdat >> 3) & 7; +// pclog("timings d2\n"); break; case 0xf6: timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; // pclog("timings f6\n"); break; case 0xf7: timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; // pclog("timings f7\n"); break; case 0xff: timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; // pclog("timings ff\n"); break; default: timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; // pclog("timings normal\n"); break; } @@ -960,16 +934,24 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if (prev_full) { - uint8_t regmask = get_srcdep_mask(timings[opcode], fetchdat, bit8); - + uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32); + int agi_stall = 0; + + if (regmask & IMPL_ESP) + regmask |= SRCDEP_ESP | DSTDEP_ESP; + + if (check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32)) + agi_stall = 2; + /*Second instruction in the pair*/ if ((timings[opcode] & PAIR_MASK) == PAIR_NP) { /*Instruction can not pair with previous*/ /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1; + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; prev_full = 0; + regmask_modified = prev_regmask; // 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) @@ -977,18 +959,20 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { /*Instruction can not pair with previous*/ /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1; + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; prev_full = 0; + regmask_modified = prev_regmask; // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } else if (prev_regmask & regmask) { /*Instruction can not pair with previous*/ /*Run previous now*/ - codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; - decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1; + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; prev_full = 0; + regmask_modified = prev_regmask; // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } else @@ -999,9 +983,14 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if (!t_pair) fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); - codegen_block_cycles += t_pair; - decode_delay = (-t_pair) + 1; + + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 2; + + codegen_block_cycles += t_pair + agi_stall; + decode_delay = (-t_pair) + 1 + agi_stall; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; prev_full = 0; // pclog("Pairable %i %i %i %02x %02x\n", t_pair, t1, t2, opcode, prev_opcode); return; @@ -1014,8 +1003,14 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) { /*Instruction not pairable*/ - codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay; - decode_delay = (-COUNT(timings[opcode], op_32)) + 1; + int agi_stall = 0; + + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 2; + + codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; + decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); // pclog("Not pairable %i\n", COUNT(timings[opcode], op_32) + decode_delay); } else @@ -1026,7 +1021,11 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) prev_opcode = opcode; prev_timings = timings; prev_op_32 = op_32; - prev_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8); + prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + if (prev_regmask & IMPL_ESP) + prev_regmask |= SRCDEP_ESP | DSTDEP_ESP; + prev_deps = deps; + prev_fetchdat = fetchdat; return; } } diff --git a/src/codegen_timing_common.c b/src/codegen_timing_common.c new file mode 100644 index 0000000..b56335a --- /dev/null +++ b/src/codegen_timing_common.c @@ -0,0 +1,678 @@ +#include "ibm.h" +#include "codegen_timing_common.h" + +uint64_t opcode_deps[256] = +{ +/* ADD ADD ADD ADD*/ +/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* ADD ADD PUSH ES POP ES*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, +/* OR OR OR OR*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* OR OR PUSH CS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, + +/* ADC ADC ADC ADC*/ +/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* ADC ADC PUSH SS POP SS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, +/* SBB SBB SBB SBB*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* SBB SBB PUSH DS POP DS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, + +/* AND AND AND AND*/ +/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* AND AND DAA*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, +/* SUB SUB SUB SUB*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* SUB SUB DAS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, + +/* XOR XOR XOR XOR*/ +/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* XOR XOR AAA*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, +/* CMP CMP CMP CMP*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, +/* CMP CMP AAS*/ + SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, +/* INC ESP INC EBP INC ESI INC EDI*/ + SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP, +/* POP EAX POP ECX POP EDX POP EBX*/ + DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP, +/* POP ESP POP EBP POP ESI POP EDI*/ + DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ IMPL_ESP, IMPL_ESP, 0, 0, + 0, 0, 0, 0, +/* PUSH imm IMUL PUSH imm IMUL*/ + IMPL_ESP, DSTDEP_REG | MODRM, IMPL_ESP, DSTDEP_REG | MODRM, +/* INSB INSW OUTSB OUTSW*/ + 0, 0, 0, 0, + +/* Jxx*/ +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +/*80*/ 0, 0, 0, 0, +/* TEST TEST XCHG XCHG*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* MOV MOV MOV MOV*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, +/* MOV from seg LEA MOV to seg POP*/ + MODRM, DSTDEP_REG | MODRM, MODRM, IMPL_ESP | MODRM, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX, +/* XCHG XCHG XCHG XCHG*/ + SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI, +/* CBW CWD CALL far WAIT*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0, +/* PUSHF POPF SAHF LAHF*/ + IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX, + +/* MOV MOV MOV MOV*/ +/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, +/* MOVSB MOVSW CMPSB CMPSW*/ + 0, 0, 0, 0, +/* TEST TEST STOSB STOSW*/ + SRCDEP_EAX, SRCDEP_EAX, 0, 0, +/* LODSB LODSW SCASB SCASW*/ + 0, 0, 0, 0, + +/* MOV*/ +/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, + DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, + DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, + DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, + +/* RET imm RET*/ +/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, +/* LES LDS MOV MOV*/ + DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM, MODRM, +/* ENTER LEAVE RETF RETF*/ + IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, +/* INT3 INT INTO IRET*/ + 0, 0, 0, 0, + + +/*d0*/ 0, 0, 0, 0, +/* AAM AAD SETALC XLAT*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX, +/* IN AL IN AX OUT_AL OUT_AX*/ + DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, +/* CALL JMP JMP JMP*/ + IMPL_ESP, 0, 0, 0, +/* IN AL IN AX OUT_AL OUT_AX*/ + SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, + +/* REPNE REPE*/ +/*f0*/ 0, 0, 0, 0, +/* HLT CMC*/ + 0, 0, 0, 0, +/* CLC STC CLI STI*/ + 0, 0, 0, 0, +/* CLD STD INCDEC*/ + 0, 0, MODRM, 0 +}; + +uint64_t opcode_deps_mod3[256] = +{ +/* ADD ADD ADD ADD*/ +/*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* ADD ADD PUSH ES POP ES*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, +/* OR OR OR OR*/ + SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* OR OR PUSH CS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, + +/* ADC ADC ADC ADC*/ +/*10*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* ADC ADC PUSH SS POP SS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, +/* SBB SBB SBB SBB*/ + SRCDEP_REG |SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* SBB SBB PUSH DS POP DS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, + +/* AND AND AND AND*/ +/*20*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* AND AND DAA*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, +/* SUB SUB SUB SUB*/ + SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* SUB SUB DAS*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, + +/* XOR XOR XOR XOR*/ +/*30*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, +/* XOR XOR AAA*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, +/* CMP CMP CMP CMP*/ + SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, +/* CMP CMP AAS*/ + SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, +/* INC ESP INC EBP INC ESI INC EDI*/ + SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP, +/* POP EAX POP ECX POP EDX POP EBX*/ + DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP, +/* POP ESP POP EBP POP ESI POP EDI*/ + DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ IMPL_ESP, IMPL_ESP, 0, 0, + 0, 0, 0, 0, +/* PUSH imm IMUL PUSH imm IMUL*/ + IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, +/* INSB INSW OUTSB OUTSW*/ + 0, 0, 0, 0, + +/* Jxx*/ +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + +/*80*/ 0, 0, 0, 0, +/* TEST TEST XCHG XCHG*/ + SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, +/* MOV MOV MOV MOV*/ + SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, +/* MOV from seg LEA MOV to seg POP*/ + DSTDEP_RM | MODRM, DSTDEP_REG | MODRM, SRCDEP_RM | MODRM, IMPL_ESP | DSTDEP_RM | MODRM, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX, +/* XCHG XCHG XCHG XCHG*/ + SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI, +/* CBW CWD CALL far WAIT*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0, +/* PUSHF POPF SAHF LAHF*/ + IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX, + +/* MOV MOV MOV MOV*/ +/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, +/* MOVSB MOVSW CMPSB CMPSW*/ + 0, 0, 0, 0, +/* TEST TEST STOSB STOSW*/ + SRCDEP_EAX, SRCDEP_EAX, 0, 0, +/* LODSB LODSW SCASB SCASW*/ + 0, 0, 0, 0, + +/* MOV*/ +/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, + DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, + DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, + DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, + +/* RET imm RET*/ +/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, +/* LES LDS MOV MOV*/ + DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM, DSTDEP_RM | MODRM, +/* ENTER LEAVE RETF RETF*/ + IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, +/* INT3 INT INTO IRET*/ + 0, 0, 0, 0, + + +/*d0*/ 0, 0, 0, 0, +/* AAM AAD SETALC XLAT*/ + SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX, +/* IN AL IN AX OUT_AL OUT_AX*/ + DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX, +/* CALL JMP JMP JMP*/ + IMPL_ESP, 0, 0, 0, +/* IN AL IN AX OUT_AL OUT_AX*/ + SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, + +/* REPNE REPE*/ +/*f0*/ 0, 0, 0, 0, +/* HLT CMC*/ + 0, 0, 0, 0, +/* CLC STC CLI STI*/ + 0, 0, 0, 0, +/* CLD STD INCDEC*/ + 0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0 +}; + +uint64_t opcode_deps_0f[256] = +{ +/*00*/ MODRM, MODRM, MODRM, MODRM, + 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*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, 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*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + MODRM, MODRM, MODRM, MODRM, + MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + 0, 0, MODRM, MODRM, + +/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + MODRM, MODRM, MODRM, 0, + 0, 0, 0, 0, + 0, 0, MODRM, MODRM, + +/*80*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*90*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + +/*a0*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, 0, 0, + MODRM, MODRM, 0, MODRM, + MODRM, MODRM, 0, MODRM, + +/*b0*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + 0, 0, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + +/*c0*/ MODRM, MODRM, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + 0, MODRM | MMX_MULTIPLY, 0, 0, + MODRM, MODRM, 0, MODRM, + MODRM, MODRM, 0, MODRM, + +/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0, + 0, MODRM | MMX_MULTIPLY, 0, 0, + MODRM, MODRM, 0, MODRM, + MODRM, MODRM, 0, MODRM, + +/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + 0, MODRM | MMX_MULTIPLY, 0, 0, + MODRM, MODRM, MODRM, 0, + MODRM, MODRM, MODRM, 0, +}; +uint64_t opcode_deps_0f_mod3[256] = +{ +/*00*/ MODRM, MODRM, MODRM, MODRM, + 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*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, 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*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + MODRM, MODRM, MODRM, MODRM, + MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + 0, 0, MODRM, MODRM, + +/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + MODRM, MODRM, MODRM, 0, + 0, 0, 0, 0, + 0, 0, MODRM, MODRM, + +/*80*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*90*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + +/*a0*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, 0, 0, + MODRM, MODRM, 0, MODRM, + MODRM, MODRM, 0, MODRM, + +/*b0*/ MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + 0, 0, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, + +/*c0*/ MODRM, MODRM, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + 0, MODRM | MMX_MULTIPLY, 0, 0, + MODRM, MODRM, 0, MODRM, + MODRM, MODRM, 0, MODRM, + +/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0, + 0, MODRM | MMX_MULTIPLY, 0, 0, + MODRM, MODRM, 0, MODRM, + MODRM, MODRM, 0, MODRM, + +/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, + 0, MODRM | MMX_MULTIPLY, 0, 0, + MODRM, MODRM, MODRM, 0, + MODRM, MODRM, MODRM, 0, +}; + +uint64_t opcode_deps_shift[8] = +{ + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM, +}; +uint64_t opcode_deps_shift_mod3[8] = +{ + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, +}; + +uint64_t opcode_deps_shift_cl[8] = +{ + MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, + MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, +}; +uint64_t opcode_deps_shift_cl_mod3[8] = +{ + SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, + SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, +}; + +uint64_t opcode_deps_f6[8] = +{ +/* TST NOT NEG*/ + MODRM, 0, MODRM, MODRM, +/* MUL IMUL DIV IDIV*/ + SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM +}; +uint64_t opcode_deps_f6_mod3[8] = +{ +/* TST NOT NEG*/ + SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, +/* MUL IMUL DIV IDIV*/ + SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM +}; +uint64_t opcode_deps_f7[8] = +{ +/* TST NOT NEG*/ + MODRM, 0, MODRM, MODRM, +/* MUL IMUL DIV IDIV*/ + SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM +}; +uint64_t opcode_deps_f7_mod3[8] = +{ +/* TST NOT NEG*/ + SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, +/* MUL IMUL DIV IDIV*/ + SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM +}; +uint64_t opcode_deps_ff[8] = +{ +/* INC DEC CALL CALL far*/ + MODRM, MODRM, MODRM | IMPL_ESP, MODRM, +/* JMP JMP far PUSH*/ + MODRM, MODRM, MODRM | IMPL_ESP, 0 +}; +uint64_t opcode_deps_ff_mod3[8] = +{ +/* INC DEC CALL CALL far*/ + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM, +/* JMP JMP far PUSH*/ + SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0 +}; + +uint64_t opcode_deps_d8[8] = +{ +/* FADDs FMULs FCOMs FCOMPs*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM, +/* FSUBs FSUBRs FDIVs FDIVRs*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM +}; +uint64_t opcode_deps_d8_mod3[8] = +{ +/* FADD FMUL FCOM FCOMP*/ + FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG, +/* FSUB FSUBR FDIV FDIVR*/ + FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG +}; + +uint64_t opcode_deps_d9[8] = +{ +/* FLDs FSTs FSTPs*/ + FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM, +/* FLDENV FLDCW FSTENV FSTCW*/ + MODRM, MODRM, MODRM, MODRM +}; +uint64_t opcode_deps_d9_mod3[64] = +{ + /*FLD*/ + FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, + FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, + /*FXCH*/ + FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH, + FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH, + /*FNOP*/ + 0, 0, 0, 0, 0, 0, 0, 0, + /*FSTP*/ + FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, + FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, +/* opFCHS opFABS*/ + 0, 0, 0, 0, +/* opFTST opFXAM*/ + 0, 0, 0, 0, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + FPU_PUSH, FPU_PUSH, FPU_PUSH, FPU_PUSH, +/* opFLDEG2 opFLDLN2 opFLDZ*/ + FPU_PUSH, FPU_PUSH, FPU_PUSH, 0, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + 0, 0, 0, 0, +/* opFDECSTP opFINCSTP,*/ + 0, 0, 0, 0, +/* opFPREM opFSQRT opFSINCOS*/ + 0, 0, 0, 0, +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + 0, 0, 0, 0 +}; + +uint64_t opcode_deps_da[8] = +{ +/* FIADDl FIMULl FICOMl FICOMPl*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM +}; +uint64_t opcode_deps_da_mod3[8] = +{ + 0, 0, 0, 0, +/* FCOMPP*/ + 0, FPU_POP2, 0, 0 +}; + + +uint64_t opcode_deps_db[8] = +{ +/* FLDil FSTil FSTPil*/ + FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, +/* FLDe FSTPe*/ + 0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM +}; +uint64_t opcode_deps_db_mod3[64] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + + + 0, 0, 0, 0, 0, 0, 0, 0, + +/* opFNOP opFCLEX opFINIT*/ + 0, 0, 0, 0, +/* opFNOP opFNOP*/ + 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +uint64_t opcode_deps_dc[8] = +{ +/* FADDd FMULd FCOMd FCOMPd*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, +/* FSUBd FSUBRd FDIVd FDIVRd*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM +}; +uint64_t opcode_deps_dc_mod3[8] = +{ +/* opFADDr opFMULr*/ + FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG +}; + +uint64_t opcode_deps_dd[8] = +{ +/* FLDd FSTd FSTPd*/ + FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, +/* FRSTOR FSAVE FSTSW*/ + MODRM, 0, MODRM, MODRM +}; +uint64_t opcode_deps_dd_mod3[8] = +{ +/* FFFREE FST FSTP*/ + 0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, +/* FUCOM FUCOMP*/ + FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0 +}; + +uint64_t opcode_deps_de[8] = +{ +/* FIADDw FIMULw FICOMw FICOMPw*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM +}; +uint64_t opcode_deps_de_mod3[8] = +{ +/* FADDP FMULP FCOMPP*/ + FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2, +/* FSUBP FSUBRP FDIVP FDIVRP*/ + FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP +}; + +uint64_t opcode_deps_df[8] = +{ +/* FILDiw FISTiw FISTPiw*/ + FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, +/* FILDiq FBSTP FISTPiq*/ + 0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM +}; +uint64_t opcode_deps_df_mod3[8] = +{ + 0, 0, 0, 0, +/* FSTSW AX*/ + 0, 0, 0, 0 +}; + +uint64_t opcode_deps_81[8] = +{ + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM +}; +uint64_t opcode_deps_81_mod3[8] = +{ + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM +}; +uint64_t opcode_deps_8x[8] = +{ + MODRM, MODRM, MODRM, MODRM, + MODRM, MODRM, MODRM, MODRM +}; +uint64_t opcode_deps_8x_mod3[8] = +{ + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, + SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM +}; diff --git a/src/codegen_timing_common.h b/src/codegen_timing_common.h new file mode 100644 index 0000000..ac7bd2a --- /dev/null +++ b/src/codegen_timing_common.h @@ -0,0 +1,226 @@ +#include "codegen_ops.h" + +/*Instruction has input dependency on register in REG field*/ +#define SRCDEP_REG (1ull << 0) +/*Instruction has input dependency on register in R/M field*/ +#define SRCDEP_RM (1ull << 1) +/*Instruction modifies register in REG field*/ +#define DSTDEP_REG (1ull << 2) +/*Instruction modifies register in R/M field*/ +#define DSTDEP_RM (1ull << 3) + +#define SRCDEP_SHIFT 4 +#define DSTDEP_SHIFT 12 + +/*Instruction has input dependency on given register*/ +#define SRCDEP_EAX (1ull << 4) +#define SRCDEP_ECX (1ull << 5) +#define SRCDEP_EDX (1ull << 6) +#define SRCDEP_EBX (1ull << 7) +#define SRCDEP_ESP (1ull << 8) +#define SRCDEP_EBP (1ull << 9) +#define SRCDEP_ESI (1ull << 10) +#define SRCDEP_EDI (1ull << 11) + +/*Instruction modifies given register*/ +#define DSTDEP_EAX (1ull << 12) +#define DSTDEP_ECX (1ull << 13) +#define DSTDEP_EDX (1ull << 14) +#define DSTDEP_EBX (1ull << 15) +#define DSTDEP_ESP (1ull << 16) +#define DSTDEP_EBP (1ull << 17) +#define DSTDEP_ESI (1ull << 18) +#define DSTDEP_EDI (1ull << 19) + +/*Instruction has ModR/M byte*/ +#define MODRM (1ull << 20) +/*Instruction implicitly uses ESP*/ +#define IMPL_ESP (1ull << 21) + +/*Instruction is MMX shift or pack/unpack instruction*/ +#define MMX_SHIFTPACK (1ull << 22) +/*Instruction is MMX multiply instruction*/ +#define MMX_MULTIPLY (1ull << 23) + +/*Instruction pops the FPU stack*/ +#define FPU_POP (1ull << 24) +/*Instruction pops the FPU stack twice*/ +#define FPU_POP2 (1ull << 25) +/*Instruction pushes onto the FPU stack*/ +#define FPU_PUSH (1ull << 26) + +/*Instruction writes to ST(0)*/ +#define FPU_WRITE_ST0 (1ull << 27) +/*Instruction reads from ST(0)*/ +#define FPU_READ_ST0 (1ull << 28) +/*Instruction reads from and writes to ST(0)*/ +#define FPU_RW_ST0 (3ull << 27) + +/*Instruction reads from ST(1)*/ +#define FPU_READ_ST1 (1ull << 29) +/*Instruction writes to ST(1)*/ +#define FPU_WRITE_ST1 (1ull << 30) +/*Instruction reads from and writes to ST(1)*/ +#define FPU_RW_ST1 (3ull << 29) + +/*Instruction reads from ST(reg)*/ +#define FPU_READ_STREG (1ull << 31) +/*Instruction writes to ST(reg)*/ +#define FPU_WRITE_STREG (1ull << 32) +/*Instruction reads from and writes to ST(reg)*/ +#define FPU_RW_STREG (3ull << 30) + +#define FPU_FXCH (1ull << 33) + + +#define REGMASK_IMPL_ESP (1 << 8) +#define REGMASK_SHIFTPACK (1 << 9) +#define REGMASK_MULTIPLY (1 << 9) + + +extern uint64_t opcode_deps[256]; +extern uint64_t opcode_deps_mod3[256]; +extern uint64_t opcode_deps_0f[256]; +extern uint64_t opcode_deps_0f_mod3[256]; +extern uint64_t opcode_deps_shift[8]; +extern uint64_t opcode_deps_shift_mod3[8]; +extern uint64_t opcode_deps_shift_cl[8]; +extern uint64_t opcode_deps_shift_cl_mod3[8]; +extern uint64_t opcode_deps_f6[8]; +extern uint64_t opcode_deps_f6_mod3[8]; +extern uint64_t opcode_deps_f7[8]; +extern uint64_t opcode_deps_f7_mod3[8]; +extern uint64_t opcode_deps_ff[8]; +extern uint64_t opcode_deps_ff_mod3[8]; +extern uint64_t opcode_deps_d8[8]; +extern uint64_t opcode_deps_d8_mod3[8]; +extern uint64_t opcode_deps_d9[8]; +extern uint64_t opcode_deps_d9_mod3[64]; +extern uint64_t opcode_deps_da[8]; +extern uint64_t opcode_deps_da_mod3[8]; +extern uint64_t opcode_deps_db[8]; +extern uint64_t opcode_deps_db_mod3[64]; +extern uint64_t opcode_deps_dc[8]; +extern uint64_t opcode_deps_dc_mod3[8]; +extern uint64_t opcode_deps_dd[8]; +extern uint64_t opcode_deps_dd_mod3[8]; +extern uint64_t opcode_deps_de[8]; +extern uint64_t opcode_deps_de_mod3[8]; +extern uint64_t opcode_deps_df[8]; +extern uint64_t opcode_deps_df_mod3[8]; +extern uint64_t opcode_deps_81[8]; +extern uint64_t opcode_deps_81_mod3[8]; +extern uint64_t opcode_deps_8x[8]; +extern uint64_t opcode_deps_8x_mod3[8]; + + + +static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) +{ + uint32_t addr_regmask = 0; + + if (data & MODRM) + { + uint8_t modrm = fetchdat & 0xff; + + if ((modrm & 0xc0) != 0xc0) + { + if (op_32 & 0x200) + { + if ((modrm & 0x7) == 4) + { + uint8_t sib = (fetchdat >> 8) & 0xff; + + if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) + { + addr_regmask = 1 << (sib & 7); + if ((sib & 0x38) != 0x20) + addr_regmask |= 1 << ((sib >> 3) & 7); + } + } + else if ((modrm & 0xc7) != 5) + { + addr_regmask = 1 << (modrm & 7); + } + } + else + { + if ((modrm & 0xc7) != 0x06) + { + switch (modrm & 7) + { + case 0: addr_regmask = REG_BX | REG_SI; break; + case 1: addr_regmask = REG_BX | REG_DI; break; + case 2: addr_regmask = REG_BP | REG_SI; break; + case 3: addr_regmask = REG_BP | REG_DI; break; + case 4: addr_regmask = REG_SI; break; + case 5: addr_regmask = REG_DI; break; + case 6: addr_regmask = REG_BP; break; + case 7: addr_regmask = REG_BX; break; + } + } + } + } + } + + if (data & IMPL_ESP) + addr_regmask |= REGMASK_IMPL_ESP; + + return addr_regmask; +} + +static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) +{ + uint32_t mask = 0; + if (data & SRCDEP_REG) + { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & SRCDEP_RM) + { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> SRCDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; + + mask |= get_addr_regmask(data, fetchdat, op_32); + + return mask; +} + +static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) +{ + uint32_t mask = 0; + if (data & DSTDEP_REG) + { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & DSTDEP_RM) + { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> DSTDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; + if (data & IMPL_ESP) + mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); + + return mask; +} diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index fbac3b8..a142024 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -3,6 +3,7 @@ - FPU/FXCH pairing - Prefix decode delay (including shadowing) - FPU latencies + - AGI stalls Elements not taken into account : - Branch prediction (beyond most simplistic approximation) - PMMX decode queue @@ -16,6 +17,8 @@ #include "x87.h" #include "mem.h" #include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" @@ -51,10 +54,6 @@ static int pair_timings[4][4] = #define CYCLES_MASK ((1ull << 7) - 1) -/*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1ull << 7) -/*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 8) /*Instruction does not pair*/ #define PAIR_NP (0ull << 29) @@ -73,62 +72,6 @@ static int pair_timings[4][4] = #define PAIR_MASK (7ull << 29) -/*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1ull << 9) -/*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 10) -/*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1ull << 11) -/*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 12) - -/*Instruction has input dependency on given register*/ -#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 (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 @@ -145,7 +88,6 @@ static int pair_timings[4][4] = #define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) -#define FPU_FXCH (1ull << 56) #define INVALID 0 @@ -156,119 +98,70 @@ 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 uint64_t *u_pipe_deps; + +static uint32_t regmask_modified; + +static uint32_t addr_regmask; static int fpu_latency; static int fpu_st_latency[8]; -#define REGMASK_SHIFTPACK (1 << 8) -#define REGMASK_MULTIPLY (1 << 8) - -static uint32_t get_srcdep_mask(uint32_t data, uint32_t fetchdat, int bit8) -{ - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> 16) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - - return mask; -} - -static uint32_t get_dstdep_mask(uint32_t data, uint32_t fetchdat, int bit8) -{ - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> 24) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - - return mask; -} 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, -/* ADD ADD PUSH ES POP ES*/ - 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_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, -/* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID, +/* ADD ADD ADD ADD*/ +/*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, +/* ADD ADD PUSH ES POP ES*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* OR OR OR OR*/ + PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, +/* OR OR PUSH CS */ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID, -/* ADC ADC ADC ADC*/ -/*10*/ PAIR_U | CYCLES_RMW | SRCDEP_REG, PAIR_U | CYCLES_RMW | SRCDEP_REG, PAIR_U | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_U | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* ADC ADC PUSH SS POP SS*/ - 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_RMW | SRCDEP_REG, PAIR_U | CYCLES_RMW | SRCDEP_REG, PAIR_U | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_U | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, -/* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* ADC ADC ADC ADC*/ +/*10*/ PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, +/* ADC ADC PUSH SS POP SS*/ + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* SBB SBB SBB SBB*/ + PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, +/* SBB SBB PUSH DS POP DS*/ + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), -/* AND AND AND AND*/ -/*20*/ 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, -/* AND AND DAA*/ - 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_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, -/* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), +/* AND AND AND AND*/ +/*20*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, +/* AND AND DAA*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), +/* SUB SUB SUB SUB*/ + PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, +/* SUB SUB DAS*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), -/* XOR XOR XOR XOR*/ -/*30*/ 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, -/* XOR XOR AAA*/ - 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_RM | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG, -/* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3), +/* XOR XOR XOR XOR*/ +/*30*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, +/* XOR XOR AAA*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), +/* CMP CMP CMP CMP*/ + PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, +/* CMP CMP AAS*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, 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, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - 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, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* INC ESP INC EBP INC ESI INC EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ 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, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, -/* POP EAX POP ECX POP EDX POP EBX*/ - 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, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* POP EAX POP ECX POP EDX POP EBX*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* POP ESP POP EBP POP ESI POP EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* PUSHA POPA BOUND ARPL*/ /*60*/ PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(8), PAIR_NP | CYCLES(7), @@ -284,13 +177,13 @@ static uint64_t opcode_timings[256] = PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - PAIR_UV | CYCLES_RM | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MOV MOV MOV MOV*/ - PAIR_UV | CYCLES_REG | SRCDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG, PAIR_UV | CYCLES_REG | DSTDEP_REG, PAIR_UV | CYCLES_REG | DSTDEP_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG | DSTDEP_REG, CYCLES(3), PAIR_NP | CYCLES(3), +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), +/* MOV MOV MOV MOV*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV, +/* MOV from seg LEA MOV to seg POP*/ + PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG, CYCLES(3), PAIR_NP | CYCLES(3), /* NOP XCHG XCHG XCHG*/ /*90*/ PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), @@ -302,19 +195,19 @@ static uint64_t opcode_timings[256] = PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), /* MOV MOV MOV MOV*/ -/*a0*/ PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, +/*a0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* MOVSB MOVSW CMPSB CMPSW*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), /* TEST TEST STOSB STOSW*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* LODSB LODSW SCASB SCASW*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), /* MOV*/ -/*b0*/ PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_ECX, PAIR_UV | CYCLES_REG | DSTDEP_EDX, PAIR_UV | CYCLES_REG | DSTDEP_EBX, - PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_ECX, PAIR_UV | CYCLES_REG | DSTDEP_EDX, PAIR_UV | CYCLES_REG | DSTDEP_EBX, - PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_ECX, PAIR_UV | CYCLES_REG | DSTDEP_EDX, PAIR_UV | CYCLES_REG | DSTDEP_EBX, - PAIR_UV | CYCLES_REG | DSTDEP_ESP, PAIR_UV | CYCLES_REG | DSTDEP_EBP, PAIR_UV | CYCLES_REG | DSTDEP_ESI, PAIR_UV | CYCLES_REG | DSTDEP_EDI, +/*b0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* RET imm RET*/ /*c0*/ INVALID, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), @@ -352,59 +245,59 @@ static uint64_t opcode_timings[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 | 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 | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID, +/* ADD ADD ADD ADD*/ +/*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* ADD ADD PUSH ES POP ES*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* OR OR OR OR*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* OR OR PUSH CS */ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, 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 | 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 | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* ADC ADC ADC ADC*/ +/*10*/ PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, +/* ADC ADC PUSH SS POP SS*/ + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), +/* SBB SBB SBB SBB*/ + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, +/* SBB SBB PUSH DS POP DS*/ + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, 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 | 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 | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), +/* AND AND AND AND*/ +/*20*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* AND AND DAA*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), +/* SUB SUB SUB SUB*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* SUB SUB DAS*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, 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 | 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, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3), +/* XOR XOR XOR XOR*/ +/*30*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* XOR XOR AAA*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), +/* CMP CMP CMP CMP*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* CMP CMP AAS*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, 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, -/* INC ESP INC EBP INC ESI INC EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - 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, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* INC ESP INC EBP INC ESI INC EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ 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, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, -/* POP EAX POP ECX POP EDX POP EBX*/ - 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, -/* POP ESP POP EBP POP ESI POP EDI*/ - PAIR_UV | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_UV | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_UV | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_UV | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI, +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* POP EAX POP ECX POP EDX POP EBX*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* POP ESP POP EBP POP ESI POP EDI*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* PUSHA POPA BOUND ARPL*/ /*60*/ PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(8), PAIR_NP | CYCLES(7), @@ -420,13 +313,13 @@ static uint64_t opcode_timings_mod3[256] = PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, PAIR_V | CYCLES_BRANCH, -/*80*/ PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, -/* TEST TEST XCHG XCHG*/ - PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* MOV MOV MOV MOV*/ - PAIR_UV | CYCLES_REG | SRCDEP_REG | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_REG, -/* MOV from seg LEA MOV to seg POP*/ - PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG | DSTDEP_REG, CYCLES(3), PAIR_NP | CYCLES(3), +/*80*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* TEST TEST XCHG XCHG*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), +/* MOV MOV MOV MOV*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/* MOV from seg LEA MOV to seg POP*/ + PAIR_NP | CYCLES(1), PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* NOP XCHG XCHG XCHG*/ /*90*/ PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), @@ -438,19 +331,19 @@ static uint64_t opcode_timings_mod3[256] = PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), /* MOV MOV MOV MOV*/ -/*a0*/ PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, +/*a0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* MOVSB MOVSW CMPSB CMPSW*/ PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5), /* TEST TEST STOSB STOSW*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* LODSB LODSW SCASB SCASW*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), /* MOV*/ -/*b0*/ PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_ECX, PAIR_UV | CYCLES_REG | DSTDEP_EDX, PAIR_UV | CYCLES_REG | DSTDEP_EBX, - PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_ECX, PAIR_UV | CYCLES_REG | DSTDEP_EDX, PAIR_UV | CYCLES_REG | DSTDEP_EBX, - PAIR_UV | CYCLES_REG | DSTDEP_EAX, PAIR_UV | CYCLES_REG | DSTDEP_ECX, PAIR_UV | CYCLES_REG | DSTDEP_EDX, PAIR_UV | CYCLES_REG | DSTDEP_EBX, - PAIR_UV | CYCLES_REG | DSTDEP_ESP, PAIR_UV | CYCLES_REG | DSTDEP_EBP, PAIR_UV | CYCLES_REG | DSTDEP_ESI, PAIR_UV | CYCLES_REG | DSTDEP_EDI, +/*b0*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /* RET imm RET*/ /*c0*/ INVALID, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), @@ -489,20 +382,20 @@ static uint64_t opcode_timings_mod3[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, - PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, +/*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, + PAIR_NP | CYCLES(1000), PAIR_NP | CYCLES(10000), INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), - PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, +/*20*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), + PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, /*30*/ PAIR_NP | CYCLES(9), CYCLES(1), PAIR_NP | CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, @@ -519,15 +412,15 @@ static uint64_t opcode_timings_0f[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*60*/ PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, - PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, - INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, +/*60*/ PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, + INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, -/*70*/ INVALID, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_NP | CYCLES(100), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, +/*70*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_NP | CYCLES(100), + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, /*80*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), @@ -554,20 +447,20 @@ static uint64_t opcode_timings_0f[256] = 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), -/*d0*/ INVALID, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, +/*d0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, + INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, -/*e0*/ INVALID, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, INVALID, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, - PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, +/*e0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, + INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, + PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, -/*f0*/ INVALID, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, PAIR_U | MMX_SHIFTPACK | CYCLES_RM, - INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, - 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, +/*f0*/ INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, + INVALID, PAIR_U | CYCLES_RM, INVALID, INVALID, + 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 uint64_t opcode_timings_0f_mod3[256] = { @@ -601,15 +494,15 @@ static uint64_t opcode_timings_0f_mod3[256] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*60*/ PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, - PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, - INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/*60*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, -/*70*/ INVALID, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(100), - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, +/*70*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(100), + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, /*80*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), @@ -636,20 +529,20 @@ static uint64_t opcode_timings_0f_mod3[256] = 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), -/*d0*/ INVALID, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, - INVALID, PAIR_UV | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, +/*d0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, -/*e0*/ INVALID, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, INVALID, - INVALID, PAIR_UV | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, +/*e0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, + INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, PAIR_UV | CYCLES_REG, -/*f0*/ INVALID, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, PAIR_UV | MMX_SHIFTPACK | CYCLES_REG, - INVALID, PAIR_UV | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, - PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, +/*f0*/ INVALID, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + INVALID, PAIR_UV | CYCLES_REG, INVALID, INVALID, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, }; static uint64_t opcode_timings_shift[8] = @@ -659,8 +552,8 @@ static uint64_t opcode_timings_shift[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, + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, + PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, }; static uint64_t opcode_timings_f6[8] = @@ -673,83 +566,83 @@ static uint64_t opcode_timings_f6[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), + PAIR_UV | CYCLES_REG, 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 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) +/* 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 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) +/* TST NOT NEG*/ + PAIR_UV | CYCLES_REG, 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 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), +/* 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 + PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID }; 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), +/* INC DEC CALL CALL far*/ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, 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 uint64_t opcode_timings_d8[8] = { -/* 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) +/* FADDs FMULs FCOMs FCOMPs*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), +/* FSUBs FSUBRs FDIVs FDIVRs*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) }; static uint64_t opcode_timings_d8_mod3[8] = { -/* 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) +/* FADD FMUL FCOM FCOMP*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), +/* FSUB FSUBR FDIV FDIVR*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) }; static uint64_t opcode_timings_d9[8] = { -/* 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) +/* FLDs FSTs FSTPs*/ + PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | 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 uint64_t opcode_timings_d9_mod3[64] = { /*FLD*/ - 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), + PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), + PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), /*FXCH*/ - 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), + PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), + PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), PAIR_FXCH | CYCLES(0), /*FNOP*/ PAIR_NP | FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, /*FSTP*/ - 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), + PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), + PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | 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), + PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | 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, + PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | FPU_CYCLES(5,2,2), PAIR_NP | 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,*/ @@ -762,25 +655,25 @@ static uint64_t opcode_timings_d9_mod3[64] = static uint64_t opcode_timings_da[8] = { -/* 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) +/* FIADDl FIMULl FICOMl FICOMPl*/ + PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) }; static uint64_t opcode_timings_da_mod3[8] = { - INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ - INVALID, PAIR_NP | FPU_POP2 | FPU_CYCLES(1,0,0), INVALID, INVALID + INVALID, PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID }; static uint64_t opcode_timings_db[8] = { -/* 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) +/* FLDil FSTil FSTPil*/ + PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), +/* FLDe FSTPe*/ + INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0) }; static uint64_t opcode_timings_db_mod3[64] = { @@ -813,55 +706,55 @@ static uint64_t opcode_timings_db_mod3[64] = static uint64_t opcode_timings_dc[8] = { -/* 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) +/* FADDd FMULd FCOMd FCOMPd*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), +/* FSUBd FSUBRd FDIVd FDIVRd*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) }; static uint64_t opcode_timings_dc_mod3[8] = { -/* 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) +/* opFADDr opFMULr*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) }; static uint64_t opcode_timings_dd[8] = { -/* 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) +/* FLDd FSTd FSTPd*/ + PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | 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 uint64_t opcode_timings_dd_mod3[8] = { -/* 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 +/* FFFREE FST FSTP*/ + PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), +/* FUCOM FUCOMP*/ + PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID }; static uint64_t opcode_timings_de[8] = { -/* 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) +/* FIADDw FIMULw FICOMw FICOMPw*/ + PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) }; static uint64_t opcode_timings_de_mod3[8] = { -/* 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) +/* FADDP FMULP FCOMPP*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0), +/* FSUBP FSUBRP FDIVP FDIVRP*/ + PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) }; static uint64_t opcode_timings_df[8] = { -/* 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) +/* FILDiw FISTiw FISTPiw*/ + PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), +/* FILDiq FBSTP FISTPiq*/ + INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0) }; static uint64_t opcode_timings_df_mod3[8] = { @@ -872,38 +765,48 @@ static uint64_t opcode_timings_df_mod3[8] = static uint64_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 + PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, + PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632 +}; +static uint64_t opcode_timings_81_mod3[8] = +{ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG }; 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 + PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, + PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8 +}; +static uint64_t opcode_timings_8x_mod3[8] = +{ + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, + PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG }; static int decode_delay, decode_delay_offset; static uint8_t last_prefix; static int prefixes; -static inline int COUNT(uint64_t c, int op_32) +static inline int COUNT(uint64_t timings, uint64_t deps, int op_32) { - if ((c & PAIR_FPU) && !(c & FPU_FXCH)) - return FPU_I_LATENCY(c); - if (c & CYCLES_HAS_MULTI) + if ((timings & PAIR_FPU) && !(deps & FPU_FXCH)) + return FPU_I_LATENCY(timings); + if (timings & CYCLES_HAS_MULTI) { if (op_32 & 0x100) - return ((uintptr_t)c >> 8) & 0xff; - return (uintptr_t)c & 0xff; + return ((uintptr_t)timings >> 8) & 0xff; + return (uintptr_t)timings & 0xff; } - if (!(c & PAIR_MASK)) - 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) + if (!(timings & PAIR_MASK)) + return timings & 0xffff; + if ((timings & PAIR_MASK) == PAIR_FX) + return timings & 0xffff; + if ((timings & PAIR_MASK) == PAIR_FXCH) + return timings & 0xffff; + if ((timings & PAIR_UV) && !(timings & PAIR_FPU)) + timings &= 3; + switch (timings & CYCLES_MASK) { case CYCLES_REG: return 1; @@ -915,20 +818,20 @@ static inline int COUNT(uint64_t c, int op_32) return cpu_hasMMX ? 1 : 2; } - fatal("Illegal COUNT %016llx\n", c); + fatal("Illegal COUNT %016llx\n", timings); - return c; + return timings; } -static int codegen_fpu_latencies(uint64_t timings, int reg) +static int codegen_fpu_latencies(uint64_t deps, int reg) { int latency = fpu_latency; - if ((timings & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + if ((deps & 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) + if ((deps & 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) + if ((deps & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) latency = fpu_st_latency[reg]; return latency; @@ -1071,12 +974,24 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; } -static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32) +static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +{ + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); + + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; +} + +static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) { int instr_cycles, latency = 0; - if ((timings[opcode] & PAIR_FPU) && !(timings[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(timings[opcode], fetchdat & 7); + if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); else { /* if (timings[opcode] & FPU_WRITE_ST0) @@ -1092,14 +1007,16 @@ static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetc 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); + instr_cycles += COUNT(timings[opcode], deps[opcode], op_32); + instr_cycles += exec_delay; 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) + if (deps[opcode] & FPU_POP) { int c; @@ -1107,7 +1024,7 @@ static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetc fpu_st_latency[c] = fpu_st_latency[c+1]; fpu_st_latency[7] = 0; } - if (timings[opcode] & FPU_POP2) + if (deps[opcode] & FPU_POP2) { int c; @@ -1115,14 +1032,14 @@ static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetc 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)) + if ((timings[opcode] & PAIR_FPU) && !(deps[opcode] & FPU_FXCH)) { /* if (fpu_latency) fatal("Bad latency FPU\n");*/ fpu_latency = FPU_F_LATENCY(timings[opcode]); } - if (timings[opcode] & FPU_PUSH) + if (deps[opcode] & FPU_PUSH) { int c; @@ -1130,26 +1047,26 @@ static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetc fpu_st_latency[c+1] = fpu_st_latency[c]; fpu_st_latency[0] = 0; } - if (timings[opcode] & FPU_WRITE_ST0) + if (deps[opcode] & FPU_WRITE_ST0) { /* if (fpu_st_latency[0]) fatal("Bad latency ST0\n");*/ fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); } - if (timings[opcode] & FPU_WRITE_ST1) + if (deps[opcode] & FPU_WRITE_ST1) { /* if (fpu_st_latency[1]) fatal("Bad latency ST1\n");*/ fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); } - if (timings[opcode] & FPU_WRITE_STREG) + if (deps[opcode] & FPU_WRITE_STREG) { int reg = fetchdat & 7; - if (timings[opcode] & FPU_POP) + if (deps[opcode] & FPU_POP) reg--; if (reg >= 0 && - !(reg == 0 && (timings[opcode] & FPU_WRITE_ST0)) && - !(reg == 1 && (timings[opcode] & FPU_WRITE_ST1))) + !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && + !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) { /* if (fpu_st_latency[reg]) fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ @@ -1161,53 +1078,64 @@ static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetc void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { uint64_t *timings; + uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); int bit8 = !(opcode & 1); + int agi_stall = 0; switch (last_prefix) { case 0x0f: timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; // pclog("timings 0f\n"); break; case 0xd8: timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_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; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; // pclog("timings d9\n"); + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; // pclog("timings da\n"); break; case 0xdb: timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; // pclog("timings db\n"); break; case 0xdc: timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; // pclog("timings dc\n"); break; case 0xdd: timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; // pclog("timings dd\n"); break; case 0xde: timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; // pclog("timings de\n"); break; case 0xdf: timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; // pclog("timings df\n"); break; @@ -1216,42 +1144,54 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) switch (opcode) { case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; - if (!mod3) - opcode = (fetchdat >> 3) & 7; + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; + opcode = (fetchdat >> 3) & 7; // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); break; case 0x81: - timings = mod3 ? opcode_timings_mod3 : opcode_timings_81; - if (!mod3) - opcode = (fetchdat >> 3) & 7; + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + 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: + case 0xc0: case 0xc1: case 0xd0: case 0xd1: timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; // pclog("timings c0\n"); break; + case 0xd2: case 0xd3: + timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; + opcode = (fetchdat >> 3) & 7; +// pclog("timings d2\n"); + break; + case 0xf6: timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; // pclog("timings f6\n"); break; case 0xf7: timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; // pclog("timings f7\n"); break; case 0xff: timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; // pclog("timings ff\n"); break; default: timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; // pclog("timings normal\n"); break; } @@ -1259,8 +1199,8 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if (u_pipe_full) { - uint8_t regmask = get_srcdep_mask(timings[opcode], fetchdat, bit8); - + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && (timings[opcode] & PAIR_MASK) != PAIR_FXCH) goto nopair; @@ -1274,7 +1214,10 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { int temp; - codegen_instruction(u_pipe_timings, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32); + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); temp = fpu_st_latency[fetchdat & 7]; fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; @@ -1282,6 +1225,8 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) u_pipe_full = 0; decode_delay_offset = 0; + regmask_modified = u_pipe_regmask; + addr_regmask = 0; return; } @@ -1300,32 +1245,42 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) int t2 = timings[opcode] & CYCLES_MASK; int t_pair; uint64_t temp_timing; + uint64_t temp_deps = 0; 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); + if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(&temp_timing, &temp_deps, 0, 0, 0, 0, agi_stall); u_pipe_full = 0; decode_delay_offset = 0; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; + addr_regmask = 0; return; } } nopair: /*Instruction can not pair with previous*/ /*Run previous now*/ - codegen_instruction(u_pipe_timings, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32); + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); u_pipe_full = 0; + regmask_modified = u_pipe_regmask; + addr_regmask = 0; } if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) @@ -1344,16 +1299,21 @@ nopair: 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_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); u_pipe_fetchdat = fetchdat; u_pipe_decode_delay_offset = decode_delay_offset; + u_pipe_deps = deps; decode_delay_offset = 0; return; } } /*Instruction can not pair and must run now*/ - codegen_instruction(timings, opcode, fetchdat, decode_delay_offset, op_32); + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); + addr_regmask = 0; } void codegen_timing_pentium_block_end() @@ -1361,7 +1321,9 @@ 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 + decode_delay_offset; + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + codegen_block_cycles++; + codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_deps[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; u_pipe_full = 0; } } diff --git a/src/codegen_timing_winchip.c b/src/codegen_timing_winchip.c index 160650e..9846e55 100644 --- a/src/codegen_timing_winchip.c +++ b/src/codegen_timing_winchip.c @@ -5,6 +5,8 @@ #include "x87.h" #include "mem.h" #include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" #define CYCLES(c) (int *)c #define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8)) @@ -247,9 +249,22 @@ static int *opcode_timings_8x[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; +static int *opcode_timings_8x_mod3[8] = +{ + &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm +}; +static int *opcode_timings_81[8] = +{ + &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm +}; +static int *opcode_timings_81_mod3[8] = +{ + &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm +}; static int timing_count; static uint8_t last_prefix; +static uint32_t regmask_modified; static inline int COUNT(int *c, int op_32) { @@ -266,6 +281,7 @@ static inline int COUNT(int *c, int op_32) void codegen_timing_winchip_block_start() { + regmask_modified = 0; } void codegen_timing_winchip_start() @@ -283,82 +299,123 @@ void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { int **timings; + uint64_t *deps; int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); switch (last_prefix) { case 0x0f: timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; +// pclog("timings 0f\n"); break; case 0xd8: timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; +// pclog("timings d8\n"); break; case 0xd9: timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings d9\n"); break; case 0xda: timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; +// pclog("timings da\n"); break; case 0xdb: timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings db\n"); break; case 0xdc: timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; +// pclog("timings dc\n"); break; case 0xdd: timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; +// pclog("timings dd\n"); break; case 0xde: timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; +// pclog("timings de\n"); break; case 0xdf: timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; +// pclog("timings df\n"); break; default: switch (opcode) { - case 0x80: case 0x81: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; - if (!mod3) - opcode = (fetchdat >> 3) & 7; + case 0x80: case 0x82: case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; + opcode = (fetchdat >> 3) & 7; +// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + 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; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; +// pclog("timings c0\n"); break; case 0xf6: timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; +// pclog("timings f6\n"); break; case 0xf7: timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; +// pclog("timings f7\n"); break; case 0xff: timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; +// pclog("timings ff\n"); break; default: timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; +// pclog("timings normal\n"); break; } } timing_count += COUNT(timings[opcode], op_32); + if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32)) + timing_count++; /*AGI stall*/ codegen_block_cycles += timing_count; + + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } void codegen_timing_winchip_block_end() From f078dab4995c19caaf1f8d4e8c3ec6627d3dc011 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 24 Jul 2017 17:54:26 +0100 Subject: [PATCH 0096/1050] Fixed invalid opcode value in REP instruction tables. --- src/386_ops.h | 256 +++++++++++++++++++++++++------------------------- 1 file changed, 128 insertions(+), 128 deletions(-) diff --git a/src/386_ops.h b/src/386_ops.h index 0d74ad7..36e421e 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -914,182 +914,182 @@ OpFn OP_TABLE(REPE)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_w_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_w_a16,ILLEGAL, +/*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, opES_REPE_w_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPE_w_a16,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_w_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPE_w_a16,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,0, 0, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_l_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_l_a16,ILLEGAL, +/*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, opES_REPE_l_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPE_l_a16,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_l_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPE_l_a16,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,0, 0, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_w_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_w_a32,ILLEGAL, +/*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, opES_REPE_w_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPE_w_a32,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_w_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPE_w_a32,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,0, 0, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPE_l_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPE_l_a32,ILLEGAL, +/*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, opES_REPE_l_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPE_l_a32,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_l_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPE_l_a32,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,0, 0, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; OpFn OP_TABLE(REPNE)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_w_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_w_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_w_a16,ILLEGAL, +/*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, opES_REPNE_w_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_w_a16,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_w_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_w_a16,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,0, 0, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_l_a16,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_l_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_l_a16,ILLEGAL, +/*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, opES_REPNE_l_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_l_a16,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_l_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_l_a16,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,0, 0, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_w_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_w_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_w_a32,ILLEGAL, +/*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, opES_REPNE_w_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_w_a32,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_w_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_w_a32,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,0, 0, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opES_REPNE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCS_REPNE_l_a32,ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSS_REPNE_l_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opDS_REPNE_l_a32,ILLEGAL, +/*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, opES_REPNE_l_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_l_a32,0, +/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_l_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_l_a32,0, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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*/ 0, 0, 0, 0, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32, +/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*a0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,ILLEGAL, ILLEGAL, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE, -/*b0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*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, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,0, 0, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE, +/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/*d0*/ 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #include "x87_ops.h" From 7e8ea2b6d5de07658daeec7ca9d7cacd1b7201ab Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 24 Jul 2017 18:45:50 +0100 Subject: [PATCH 0097/1050] Fixed REP instructions with trap flag enabled. --- src/x86_ops_rep.h | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index f116661..66587ef 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -1,3 +1,5 @@ +extern int trap; + #define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ static int opREP_INSB_ ## size(uint32_t fetchdat) \ { \ @@ -166,7 +168,8 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ uint8_t temp; \ @@ -198,7 +201,8 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ uint16_t temp; \ @@ -230,7 +234,8 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat) { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ uint32_t temp; \ @@ -264,7 +269,8 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat) { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ @@ -291,7 +297,8 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat) { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \ @@ -318,7 +325,8 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat) { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \ @@ -346,7 +354,8 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat) { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ @@ -372,7 +381,8 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat) { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ @@ -398,7 +408,8 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ while (CNT_REG > 0) \ { \ EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ @@ -509,7 +520,8 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat) { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ @@ -539,7 +551,8 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat) { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ @@ -569,7 +582,8 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat) { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - \ + if (trap) \ + cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ From 9946bf2b73deb0529545741888ffeec0bcba6ba7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 24 Jul 2017 19:36:46 +0100 Subject: [PATCH 0098/1050] Fixed task switch to V86 mode. --- src/x86seg.c | 127 ++++++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 1e744f8..7c2bf59 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2558,79 +2558,80 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) // if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); - if (eflags&VM_FLAG) + if (eflags & VM_FLAG) { - pclog("Task switch V86!\n"); - x86gpf(NULL,0); - return; - } - - if (!(new_cs&~3)) - { - pclog("TS loading null CS\n"); - x86ts(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); - x86ts(NULL,new_cs&~3); - return; - } - addr+=ldt.base; + loadcs(new_cs); + set_use32(0); } else { - if (addr>=gdt.limit) + if (!(new_cs&~3)) { - pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); + pclog("TS loading null CS\n"); + x86ts(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); + x86ts(NULL,new_cs&~3); + return; + } + addr+=ldt.base; + } + else + { + if (addr>=gdt.limit) + { + pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); + x86ts(NULL,new_cs&~3); + 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"); + x86ts(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"); + x86ts(NULL,new_cs&~3); + return; + } + break; + default: + pclog("TS load CS not code segment\n"); x86ts(NULL,new_cs&~3); 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"); - x86ts(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"); - x86ts(NULL,new_cs&~3); - return; - } - break; - default: - pclog("TS load CS not code segment\n"); - x86ts(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(); - set_use32(segdat2[3] & 0x40); + CS=new_cs; + do_seg_load(&_cs, segdat2); + if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + set_use32(segdat2[3] & 0x40); + } EAX=new_eax; ECX=new_ecx; From e93fb011b4e90a4504087ca79a06324940b2d490 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 25 Jul 2017 18:09:12 +0100 Subject: [PATCH 0099/1050] Removed unnecessary calls to midi_close()/midi_init() in resetpchard(). --- src/pc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pc.c b/src/pc.c index ac44c99..5eff36e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -357,9 +357,6 @@ void resetpchard() mouse_emu_close(); device_init(); - midi_close(); - midi_init(); - timer_reset(); sound_reset(); mem_resize(); From 197b5127e2a33b1be051944d5c3d419359da005b Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 26 Jul 2017 20:40:08 +0100 Subject: [PATCH 0100/1050] Fixed typo in menu. --- src/pc.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc.rc b/src/pc.rc index 9a3f432..c2a4b64 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -36,7 +36,7 @@ BEGIN POPUP "&Video" BEGIN MENUITEM "&Resizeable window",IDM_VID_RESIZE - MENUITEM "Force 4:3 &aspect ration",IDM_VID_ASPECT + MENUITEM "Force 4:3 &aspect ratio",IDM_VID_ASPECT MENUITEM "Remember size && position",IDM_VID_REMEMBER MENUITEM SEPARATOR MENUITEM "&DirectDraw", IDM_VID_DDRAW From 40d7e020061469bdeadd650cd117043385544261 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 28 Jul 2017 20:30:10 +0100 Subject: [PATCH 0101/1050] Fixed recompiler bug introduced by REP rework - Windows XP installer works again. --- src/codegen_x86-64.c | 2 +- src/codegen_x86.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index 3e3f679..7220966 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -1120,7 +1120,7 @@ generate_call: #endif } - if ((op_table == x86_opcodes_REPNE || op_table == x86_opcodes_REPE) && !op_table[opcode | op_32]) + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { op_table = x86_dynarec_opcodes; recomp_op_table = recomp_opcodes; diff --git a/src/codegen_x86.c b/src/codegen_x86.c index 4d71317..14f076e 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -2053,7 +2053,7 @@ generate_call: #endif } - if ((op_table == x86_opcodes_REPNE || op_table == x86_opcodes_REPE) && !op_table[opcode | op_32]) + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { op_table = x86_dynarec_opcodes; recomp_op_table = recomp_opcodes; From 354d52754c605463c2ad717376792d8b594c8124 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 30 Jul 2017 08:31:03 +0100 Subject: [PATCH 0102/1050] Indentation fixes. Patch from basic2004. --- src/808x.c | 2 +- src/pc.c | 112 ++++++++++++++++---------------- src/sio.c | 4 +- src/vid_ega.c | 4 +- src/vid_voodoo_codegen_x86-64.h | 8 +-- src/vid_voodoo_codegen_x86.h | 8 +-- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/src/808x.c b/src/808x.c index 2f71e08..793229e 100644 --- a/src/808x.c +++ b/src/808x.c @@ -462,7 +462,7 @@ void makeznptable() 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; } diff --git a/src/pc.c b/src/pc.c index 5eff36e..6bb02da 100644 --- a/src/pc.c +++ b/src/pc.c @@ -471,66 +471,66 @@ void runpc() else execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); - keyboard_poll_host(); - keyboard_process(); -// checkkeys(); - pollmouse(); - joystick_poll(); + keyboard_poll_host(); + keyboard_process(); +// checkkeys(); + pollmouse(); + joystick_poll(); endblit(); - framecountx++; - framecount++; - if (framecountx>=100) - { - pclog("onesec\n"); - framecountx=0; - mips=(float)insc/1000000.0f; - insc=0; - flops=(float)fpucount/1000000.0f; - fpucount=0; - sreadlnum=readlnum; - swritelnum=writelnum; - segareads=egareads; - segawrites=egawrites; - scycles_lost = cycles_lost; + framecountx++; + framecount++; + if (framecountx>=100) + { + pclog("onesec\n"); + framecountx=0; + mips=(float)insc/1000000.0f; + insc=0; + flops=(float)fpucount/1000000.0f; + fpucount=0; + sreadlnum=readlnum; + swritelnum=writelnum; + segareads=egareads; + segawrites=egawrites; + scycles_lost = cycles_lost; - cpu_recomp_blocks_latched = cpu_recomp_blocks; - cpu_recomp_ins_latched = cpu_state.cpu_recomp_ins; - cpu_recomp_full_ins_latched = cpu_recomp_full_ins; - cpu_new_blocks_latched = cpu_new_blocks; - cpu_recomp_flushes_latched = cpu_recomp_flushes; - cpu_recomp_evicted_latched = cpu_recomp_evicted; - cpu_recomp_reuse_latched = cpu_recomp_reuse; - cpu_recomp_removed_latched = cpu_recomp_removed; - cpu_reps_latched = cpu_reps; - cpu_notreps_latched = cpu_notreps; - - cpu_recomp_blocks = 0; - cpu_state.cpu_recomp_ins = 0; - cpu_recomp_full_ins = 0; - cpu_new_blocks = 0; - cpu_recomp_flushes = 0; - cpu_recomp_evicted = 0; - cpu_recomp_reuse = 0; - cpu_recomp_removed = 0; - cpu_reps = 0; - cpu_notreps = 0; + cpu_recomp_blocks_latched = cpu_recomp_blocks; + cpu_recomp_ins_latched = cpu_state.cpu_recomp_ins; + cpu_recomp_full_ins_latched = cpu_recomp_full_ins; + cpu_new_blocks_latched = cpu_new_blocks; + cpu_recomp_flushes_latched = cpu_recomp_flushes; + cpu_recomp_evicted_latched = cpu_recomp_evicted; + cpu_recomp_reuse_latched = cpu_recomp_reuse; + cpu_recomp_removed_latched = cpu_recomp_removed; + cpu_reps_latched = cpu_reps; + cpu_notreps_latched = cpu_notreps; - updatestatus=1; - readlnum=writelnum=0; - egareads=egawrites=0; - cycles_lost = 0; - mmuflush=0; - emu_fps = frames; - frames = 0; - } - if (win_title_update) - { - win_title_update=0; - sprintf(s, "PCem v12 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); - set_window_title(s); - } - done++; + cpu_recomp_blocks = 0; + cpu_state.cpu_recomp_ins = 0; + cpu_recomp_full_ins = 0; + cpu_new_blocks = 0; + cpu_recomp_flushes = 0; + cpu_recomp_evicted = 0; + cpu_recomp_reuse = 0; + cpu_recomp_removed = 0; + cpu_reps = 0; + cpu_notreps = 0; + + updatestatus=1; + readlnum=writelnum=0; + egareads=egawrites=0; + cycles_lost = 0; + mmuflush=0; + emu_fps = frames; + frames = 0; + } + if (win_title_update) + { + win_title_update=0; + sprintf(s, "PCem v12 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + set_window_title(s); + } + done++; } void fullspeed() diff --git a/src/sio.c b/src/sio.c index 4160cc4..bc2dc33 100644 --- a/src/sio.c +++ b/src/sio.c @@ -17,8 +17,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/vid_ega.c b/src/vid_ega.c index 20e2708..ca5af05 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -150,8 +150,8 @@ 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; diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 1e940a7..8e0aef5 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -800,10 +800,10 @@ 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_pos) + *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) { diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 21ee944..42df050 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -759,10 +759,10 @@ 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_pos) + *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) { From 2881d35680acb4b6292cc3adfab505d4f0dbbd86 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Sun, 30 Jul 2017 10:39:27 +0100 Subject: [PATCH 0103/1050] Changes to wxWidgets/SDL2 port : - Updated UI - OpenGL 3.0 with GLSL/GLSLP-support - Improvements to Windows version - Minor changes/bugfixes Patch from bit. --- configure | 100 +- configure.ac | 8 +- src/Makefile.am | 5 +- src/Makefile.in | 454 +- src/Makefile.linux32-wx-sdl2 | 11 +- src/Makefile.linux64-wx-sdl2 | 13 +- src/Makefile.mingw-wx-sdl2 | 35 +- src/Makefile.osx64-wx-sdl2 | 6 +- src/cdrom-ioctl-linux.c | 1 + src/cdrom-ioctl-osx.c | 2 + src/config.c | 76 + src/config.h | 6 +- src/hdd.c | 11 +- src/hdd.h | 1 + src/icons/16x16/cd.png | Bin 0 -> 835 bytes src/icons/16x16/computer_add.png | Bin 0 -> 783 bytes src/icons/16x16/computer_delete.png | Bin 0 -> 774 bytes src/icons/16x16/computer_edit.png | Bin 0 -> 798 bytes src/icons/16x16/control_eject.png | Bin 0 -> 685 bytes src/icons/16x16/control_play_blue.png | Bin 0 -> 742 bytes src/icons/16x16/diskette.png | Bin 0 -> 730 bytes src/icons/16x16/door_out.png | Bin 0 -> 763 bytes src/icons/16x16/drive.png | Bin 0 -> 430 bytes src/icons/16x16/drive_add.png | Bin 0 -> 634 bytes src/icons/16x16/folder.png | Bin 0 -> 632 bytes src/icons/16x16/setting_tools.png | Bin 0 -> 1017 bytes src/icons/24x24/pause.png | Bin 0 -> 635 bytes src/icons/24x24/play.png | Bin 0 -> 758 bytes src/icons/24x24/refresh.png | Bin 0 -> 1144 bytes src/icons/24x24/stop.png | Bin 0 -> 622 bytes src/icons/32x32/add.png | Bin 0 -> 1815 bytes src/icons/32x32/computer_add.png | Bin 0 -> 2051 bytes src/icons/32x32/computer_delete.png | Bin 0 -> 2051 bytes src/icons/32x32/computer_edit.png | Bin 0 -> 2007 bytes src/icons/32x32/control_play_blue.png | Bin 0 -> 1971 bytes src/icons/32x32/delete.png | Bin 0 -> 1886 bytes src/icons/32x32/door_in.png | Bin 0 -> 1382 bytes src/icons/32x32/door_out.png | Bin 0 -> 1394 bytes src/icons/32x32/drive.png | Bin 0 -> 869 bytes src/icons/32x32/motherboard.png | Bin 0 -> 1852 bytes src/icons/32x32/mouse_pc.png | Bin 0 -> 1507 bytes src/icons/32x32/setting_tools.png | Bin 0 -> 2315 bytes src/icons/32x32/sound.png | Bin 0 -> 1855 bytes src/icons/32x32/textfield_rename.png | Bin 0 -> 856 bytes src/icons/32x32/video_mode.png | Bin 0 -> 1751 bytes src/icons/svg/pause.svg | 43 + src/icons/svg/play-button.svg | 41 + src/icons/svg/refresh.svg | 50 + src/icons/svg/stop.svg | 39 + src/paths.c | 25 + src/paths.h | 3 + src/pc.c | 2 + src/pc.xrc | 3341 ++++++---- src/video.c | 3 + src/video.h | 2 +- src/wx-app.cc | 22 +- src/wx-app.h | 46 +- src/wx-config.c | 1456 ++++- src/wx-config_sel.c | 202 +- src/wx-deviceconfig.cc | 239 +- src/wx-dialogbox.cc | 47 +- src/wx-dialogbox.h | 5 +- src/wx-display.h | 1 + src/wx-glsl.h | 155 + src/wx-glslp-parser.c | 328 + src/wx-glslp-parser.h | 54 + src/wx-resources.cpp | 8734 +++++++++++++++++-------- src/wx-sdl2-display-win.c | 984 +++ src/wx-sdl2-display.c | 102 +- src/wx-sdl2-glw.h | 92 + src/wx-sdl2-hdconf.c | 961 --- src/wx-sdl2-keyboard.c | 2 +- src/wx-sdl2-midi.c | 9 + src/wx-sdl2-mouse.c | 3 +- src/wx-sdl2-status.c | 3 +- src/wx-sdl2-video-gl3.c | 1656 +++++ src/wx-sdl2-video-gl3.h | 3 + src/wx-sdl2-video-renderer.c | 180 + src/wx-sdl2-video-renderer.h | 3 + src/wx-sdl2-video.c | 110 +- src/wx-sdl2-video.h | 32 +- src/wx-sdl2.c | 360 +- src/wx-sdl2.h | 2 + src/wx-shader_man.c | 230 + src/wx-shaderconfig.cc | 146 + src/wx-shaderconfig.h | 13 + src/wx-status.cc | 8 +- src/wx-utils.cc | 301 +- src/wx-utils.h | 43 +- src/wx.rc | 1 + 90 files changed, 15251 insertions(+), 5560 deletions(-) create mode 100644 src/icons/16x16/cd.png create mode 100644 src/icons/16x16/computer_add.png create mode 100644 src/icons/16x16/computer_delete.png create mode 100644 src/icons/16x16/computer_edit.png create mode 100644 src/icons/16x16/control_eject.png create mode 100644 src/icons/16x16/control_play_blue.png create mode 100644 src/icons/16x16/diskette.png create mode 100644 src/icons/16x16/door_out.png create mode 100644 src/icons/16x16/drive.png create mode 100644 src/icons/16x16/drive_add.png create mode 100644 src/icons/16x16/folder.png create mode 100644 src/icons/16x16/setting_tools.png create mode 100644 src/icons/24x24/pause.png create mode 100644 src/icons/24x24/play.png create mode 100644 src/icons/24x24/refresh.png create mode 100644 src/icons/24x24/stop.png create mode 100644 src/icons/32x32/add.png create mode 100644 src/icons/32x32/computer_add.png create mode 100644 src/icons/32x32/computer_delete.png create mode 100644 src/icons/32x32/computer_edit.png create mode 100644 src/icons/32x32/control_play_blue.png create mode 100644 src/icons/32x32/delete.png create mode 100644 src/icons/32x32/door_in.png create mode 100644 src/icons/32x32/door_out.png create mode 100644 src/icons/32x32/drive.png create mode 100644 src/icons/32x32/motherboard.png create mode 100644 src/icons/32x32/mouse_pc.png create mode 100644 src/icons/32x32/setting_tools.png create mode 100644 src/icons/32x32/sound.png create mode 100644 src/icons/32x32/textfield_rename.png create mode 100644 src/icons/32x32/video_mode.png create mode 100644 src/icons/svg/pause.svg create mode 100644 src/icons/svg/play-button.svg create mode 100644 src/icons/svg/refresh.svg create mode 100644 src/icons/svg/stop.svg create mode 100644 src/wx-glsl.h create mode 100644 src/wx-glslp-parser.c create mode 100644 src/wx-glslp-parser.h create mode 100644 src/wx-sdl2-display-win.c create mode 100644 src/wx-sdl2-glw.h delete mode 100644 src/wx-sdl2-hdconf.c create mode 100644 src/wx-sdl2-video-gl3.c create mode 100644 src/wx-sdl2-video-gl3.h create mode 100644 src/wx-sdl2-video-renderer.c create mode 100644 src/wx-sdl2-video-renderer.h create mode 100644 src/wx-shader_man.c create mode 100644 src/wx-shaderconfig.cc create mode 100644 src/wx-shaderconfig.h create mode 100644 src/wx.rc diff --git a/configure b/configure index 7f12c5e..632f62a 100755 --- a/configure +++ b/configure @@ -4495,7 +4495,7 @@ rm -f core conftest.err conftest.$ac_objext \ fi else - SDL_VERSION=2.0.0 + SDL_VERSION=2.0.1 @@ -5265,6 +5265,55 @@ $as_echo "no (version $WX_VERSION is not new enough)" >&6; } wxWidgets version is $reqwx or above. " "$LINENO" 5 fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +$as_echo_n "checking for glGetError in -lGL... " >&6; } +if ${ac_cv_lib_GL_glGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glGetError (); +int +main () +{ +return glGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_glGetError=yes +else + ac_cv_lib_GL_glGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +$as_echo "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGL 1 +_ACEOF + + LIBS="-lGL $LIBS" + +else + \ + echo "You need to install the OpenGL library." + exit -1 +fi + LIBS="$LIBS $WX_LIBS $SDL_LIBS" fi @@ -5317,55 +5366,6 @@ else exit -1 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alutInit in -lalut" >&5 -$as_echo_n "checking for alutInit in -lalut... " >&6; } -if ${ac_cv_lib_alut_alutInit+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lalut $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char alutInit (); -int -main () -{ -return alutInit (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_alut_alutInit=yes -else - ac_cv_lib_alut_alutInit=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_alut_alutInit" >&5 -$as_echo "$ac_cv_lib_alut_alutInit" >&6; } -if test "x$ac_cv_lib_alut_alutInit" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBALUT 1 -_ACEOF - - LIBS="-lalut $LIBS" - -else - \ - echo "You need to install the ALUT library." - exit -1 -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } diff --git a/configure.ac b/configure.ac index 2d95478..449d532 100644 --- a/configure.ac +++ b/configure.ac @@ -70,7 +70,7 @@ if test "$enable_wx" != "yes"; then AM_PATH_ALLEGRO(, , AC_MSG_ERROR(building PCem requires Allegro to be installed)) fi else - SDL_VERSION=2.0.0 + SDL_VERSION=2.0.1 AM_PATH_SDL2($SDL_VERSION, :, AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) @@ -89,15 +89,15 @@ else wxWidgets version is $reqwx or above. ]) fi + AC_CHECK_LIB([GL], [glGetError], [], \ + [echo "You need to install the OpenGL library." + exit -1]) LIBS="$LIBS $WX_LIBS $SDL_LIBS" fi AC_CHECK_LIB([openal], [alGetError], [], \ [echo "You need to install the OpenAL library." exit -1]) -AC_CHECK_LIB([alut], [alutInit], [], \ - [echo "You need to install the ALUT library." - exit -1]) AC_CHECK_LIB([pthread], [pthread_create]) diff --git a/src/Makefile.am b/src/Makefile.am index 9cf520b..3bd5a14 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,8 +40,9 @@ pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) pcem_LDADD = @LIBS@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ - wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-sdl2-hdconf.c wx-status.cc wx-sdl2-status.c \ - wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c + wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ + wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc else pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO pcem_LDADD = $(allegro_LIBS) -lopenal diff --git a/src/Makefile.in b/src/Makefile.in index 8db7178..fb3161e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -94,8 +94,9 @@ host_triplet = @host@ bin_PROGRAMS = pcem$(EXEEXT) @USE_WX_TRUE@am__append_1 = wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ @USE_WX_TRUE@ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ -@USE_WX_TRUE@ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-sdl2-hdconf.c wx-status.cc wx-sdl2-status.c \ -@USE_WX_TRUE@ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c +@USE_WX_TRUE@ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ +@USE_WX_TRUE@ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ +@USE_WX_TRUE@ wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc @USE_WX_FALSE@am__append_2 = allegro-gui.c allegro-gui-config-sel.c allegro-gui-configure.c \ @USE_WX_FALSE@ allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c \ @@ -121,37 +122,39 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c \ cdrom-image.cc 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 dells200.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 hdd.c hdd_esdi.c headland.c i430lx.c \ - i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c \ + codegen_timing_common.c codegen_timing_pentium.c \ + codegen_timing_winchip.c compaq.c config.c cpu.c dac.c \ + dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c \ + dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ + hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c \ + i430vx.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 mca.c mcr.c mem.c mfm_at.c \ - mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c \ - nmi.c nvr.c olivetti_m24.c opti495.c pc.c pci.c pic.c piix.c \ - pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.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 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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ - vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ - vid_incolor.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_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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc \ + keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c mca.c mcr.c \ + mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c \ + mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c \ + paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ + ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 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_colorplus.c \ + vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ + vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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 \ + vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_PS_.cc \ @@ -162,12 +165,14 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ wx-sdl2-video.c wx-sdl2-midi.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-sdl2-hdconf.c wx-status.cc \ - wx-sdl2-status.c wx-resources.cpp wx-thread.c wx-common.c \ - wx-sdl2-display.c allegro-gui.c allegro-gui-config-sel.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 \ + wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ + wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c \ + wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ + wx-shader_man.c wx-shaderconfig.cc allegro-gui.c \ + allegro-gui-config-sel.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 \ thread-pthread.c codegen_x86.c codegen_x86-64.c @USE_WX_TRUE@am__objects_1 = pcem-wx-main.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-config_sel.$(OBJEXT) \ @@ -180,12 +185,16 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ @USE_WX_TRUE@ pcem-wx-sdl2-midi.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-sdl2.$(OBJEXT) pcem-wx-config.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-deviceconfig.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-hdconf.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-status.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-sdl2-status.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-resources.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-thread.$(OBJEXT) pcem-wx-common.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) +@USE_WX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-video-renderer.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-sdl2-video-gl3.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-glslp-parser.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-shader_man.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-shaderconfig.$(OBJEXT) @USE_WX_FALSE@am__objects_2 = pcem-allegro-gui.$(OBJEXT) \ @USE_WX_FALSE@ pcem-allegro-gui-config-sel.$(OBJEXT) \ @USE_WX_FALSE@ pcem-allegro-gui-configure.$(OBJEXT) \ @@ -208,16 +217,18 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ + pcem-codegen_timing_common.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ pcem-codegen_timing_winchip.$(OBJEXT) pcem-compaq.$(OBJEXT) \ pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) pcem-dac.$(OBJEXT) \ pcem-dells200.$(OBJEXT) pcem-device.$(OBJEXT) \ pcem-disc.$(OBJEXT) pcem-disc_fdi.$(OBJEXT) \ pcem-disc_img.$(OBJEXT) pcem-disc_sector.$(OBJEXT) \ - pcem-dma.$(OBJEXT) pcem-fdc.$(OBJEXT) pcem-fdc37c665.$(OBJEXT) \ - pcem-fdd.$(OBJEXT) pcem-fdi2raw.$(OBJEXT) \ - pcem-gameport.$(OBJEXT) pcem-hdd.$(OBJEXT) \ - pcem-hdd_esdi.$(OBJEXT) pcem-headland.$(OBJEXT) \ + pcem-dma.$(OBJEXT) pcem-esdi_at.$(OBJEXT) pcem-fdc.$(OBJEXT) \ + pcem-fdc37c665.$(OBJEXT) pcem-fdd.$(OBJEXT) \ + pcem-fdi2raw.$(OBJEXT) pcem-gameport.$(OBJEXT) \ + pcem-hdd.$(OBJEXT) pcem-hdd_esdi.$(OBJEXT) \ + pcem-hdd_file.$(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) \ @@ -227,65 +238,67 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(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-lpt.$(OBJEXT) pcem-mca.$(OBJEXT) pcem-mcr.$(OBJEXT) \ - pcem-mem.$(OBJEXT) pcem-mfm_at.$(OBJEXT) \ + pcem-laserxt.$(OBJEXT) pcem-lpt.$(OBJEXT) pcem-mca.$(OBJEXT) \ + pcem-mcr.$(OBJEXT) pcem-mem.$(OBJEXT) pcem-mfm_at.$(OBJEXT) \ pcem-mfm_xebec.$(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-opti495.$(OBJEXT) \ - pcem-pc.$(OBJEXT) pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) \ - pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) \ - pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) pcem-ps2_mca.$(OBJEXT) \ - pcem-ps2_nvr.$(OBJEXT) pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) \ - pcem-scat.$(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_ps1.$(OBJEXT) \ - pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) \ - pcem-soundopenal.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ - pcem-tandy_rom.$(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_colorplus.$(OBJEXT) \ - pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ - pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ - pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ - pcem-vid_ics2595.$(OBJEXT) pcem-vid_incolor.$(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_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) \ - pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ + pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pci.$(OBJEXT) \ + pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) \ + pcem-ppi.$(OBJEXT) pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) \ + pcem-ps2_mca.$(OBJEXT) pcem-ps2_nvr.$(OBJEXT) \ + pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) pcem-scat.$(OBJEXT) \ + pcem-serial.$(OBJEXT) pcem-sio.$(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_ps1.$(OBJEXT) pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ + pcem-tandy_eeprom.$(OBJEXT) pcem-tandy_rom.$(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_colorplus.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ + pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ + pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ + pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ + pcem-vid_incolor.$(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_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ + pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ pcem-cdrom_image.$(OBJEXT) pcem-dbopl.$(OBJEXT) \ - pcem-vid_cga_comp.$(OBJEXT) pcem-convolve.$(OBJEXT) \ - pcem-convolve-sse.$(OBJEXT) pcem-envelope.$(OBJEXT) \ - pcem-extfilt.$(OBJEXT) pcem-filter.$(OBJEXT) \ - pcem-pot.$(OBJEXT) pcem-sid.$(OBJEXT) pcem-voice.$(OBJEXT) \ - pcem-wave6581_PS_.$(OBJEXT) pcem-wave6581_PST.$(OBJEXT) \ - pcem-wave6581_P_T.$(OBJEXT) pcem-wave6581__ST.$(OBJEXT) \ - pcem-wave8580_PS_.$(OBJEXT) pcem-wave8580_PST.$(OBJEXT) \ - pcem-wave8580_P_T.$(OBJEXT) pcem-wave8580__ST.$(OBJEXT) \ - pcem-wave.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) $(am__objects_4) + pcem-nukedopl.$(OBJEXT) pcem-vid_cga_comp.$(OBJEXT) \ + pcem-convolve.$(OBJEXT) pcem-convolve-sse.$(OBJEXT) \ + pcem-envelope.$(OBJEXT) pcem-extfilt.$(OBJEXT) \ + pcem-filter.$(OBJEXT) pcem-pot.$(OBJEXT) pcem-sid.$(OBJEXT) \ + pcem-voice.$(OBJEXT) pcem-wave6581_PS_.$(OBJEXT) \ + pcem-wave6581_PST.$(OBJEXT) pcem-wave6581_P_T.$(OBJEXT) \ + pcem-wave6581__ST.$(OBJEXT) pcem-wave8580_PS_.$(OBJEXT) \ + pcem-wave8580_PST.$(OBJEXT) pcem-wave8580_P_T.$(OBJEXT) \ + pcem-wave8580__ST.$(OBJEXT) pcem-wave.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = @USE_WX_FALSE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) @@ -490,37 +503,39 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c \ cdrom-image.cc 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 dells200.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 hdd.c hdd_esdi.c headland.c i430lx.c \ - i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c \ + codegen_timing_common.c codegen_timing_pentium.c \ + codegen_timing_winchip.c compaq.c config.c cpu.c dac.c \ + dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c \ + dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ + hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c \ + i430vx.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 mca.c mcr.c mem.c mfm_at.c \ - mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c \ - nmi.c nvr.c olivetti_m24.c opti495.c pc.c pci.c pic.c piix.c \ - pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.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 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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ - vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ - vid_incolor.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_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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc \ + keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c mca.c mcr.c \ + mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c \ + mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c \ + paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ + ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 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_colorplus.c \ + vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ + vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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 \ + vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_PS_.cc \ @@ -648,6 +663,7 @@ distclean-compile: @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_686.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.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_timing_winchip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_x86-64.Po@am__quote@ @@ -667,6 +683,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_sector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-envelope.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-extfilt.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@ @@ -676,6 +693,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.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@ @@ -695,6 +713,7 @@ distclean-compile: @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-laserxt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mcr.Po@am__quote@ @@ -707,9 +726,11 @@ distclean-compile: @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-nukedopl.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-opti495.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.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@ @@ -726,6 +747,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.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@ @@ -814,17 +836,21 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-hdconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.Po@am__quote@ @@ -1028,6 +1054,20 @@ pcem-codegen_timing_686.obj: codegen_timing_686.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_686.obj `if test -f 'codegen_timing_686.c'; then $(CYGPATH_W) 'codegen_timing_686.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_686.c'; fi` +pcem-codegen_timing_common.o: codegen_timing_common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_common.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_common.Tpo -c -o pcem-codegen_timing_common.o `test -f 'codegen_timing_common.c' || echo '$(srcdir)/'`codegen_timing_common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_common.Tpo $(DEPDIR)/pcem-codegen_timing_common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_common.c' object='pcem-codegen_timing_common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_common.o `test -f 'codegen_timing_common.c' || echo '$(srcdir)/'`codegen_timing_common.c + +pcem-codegen_timing_common.obj: codegen_timing_common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_common.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_common.Tpo -c -o pcem-codegen_timing_common.obj `if test -f 'codegen_timing_common.c'; then $(CYGPATH_W) 'codegen_timing_common.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_common.Tpo $(DEPDIR)/pcem-codegen_timing_common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_common.c' object='pcem-codegen_timing_common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_common.obj `if test -f 'codegen_timing_common.c'; then $(CYGPATH_W) 'codegen_timing_common.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_common.c'; fi` + pcem-codegen_timing_pentium.o: codegen_timing_pentium.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_pentium.Tpo $(DEPDIR)/pcem-codegen_timing_pentium.Po @@ -1210,6 +1250,20 @@ pcem-dma.obj: dma.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-esdi_at.o: esdi_at.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-esdi_at.o -MD -MP -MF $(DEPDIR)/pcem-esdi_at.Tpo -c -o pcem-esdi_at.o `test -f 'esdi_at.c' || echo '$(srcdir)/'`esdi_at.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-esdi_at.Tpo $(DEPDIR)/pcem-esdi_at.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='esdi_at.c' object='pcem-esdi_at.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-esdi_at.o `test -f 'esdi_at.c' || echo '$(srcdir)/'`esdi_at.c + +pcem-esdi_at.obj: esdi_at.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-esdi_at.obj -MD -MP -MF $(DEPDIR)/pcem-esdi_at.Tpo -c -o pcem-esdi_at.obj `if test -f 'esdi_at.c'; then $(CYGPATH_W) 'esdi_at.c'; else $(CYGPATH_W) '$(srcdir)/esdi_at.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-esdi_at.Tpo $(DEPDIR)/pcem-esdi_at.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='esdi_at.c' object='pcem-esdi_at.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-esdi_at.obj `if test -f 'esdi_at.c'; then $(CYGPATH_W) 'esdi_at.c'; else $(CYGPATH_W) '$(srcdir)/esdi_at.c'; fi` + pcem-fdc.o: fdc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-fdc.Tpo $(DEPDIR)/pcem-fdc.Po @@ -1308,6 +1362,20 @@ pcem-hdd_esdi.obj: hdd_esdi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-hdd_esdi.obj `if test -f 'hdd_esdi.c'; then $(CYGPATH_W) 'hdd_esdi.c'; else $(CYGPATH_W) '$(srcdir)/hdd_esdi.c'; fi` +pcem-hdd_file.o: hdd_file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-hdd_file.o -MD -MP -MF $(DEPDIR)/pcem-hdd_file.Tpo -c -o pcem-hdd_file.o `test -f 'hdd_file.c' || echo '$(srcdir)/'`hdd_file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-hdd_file.Tpo $(DEPDIR)/pcem-hdd_file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hdd_file.c' object='pcem-hdd_file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-hdd_file.o `test -f 'hdd_file.c' || echo '$(srcdir)/'`hdd_file.c + +pcem-hdd_file.obj: hdd_file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-hdd_file.obj -MD -MP -MF $(DEPDIR)/pcem-hdd_file.Tpo -c -o pcem-hdd_file.obj `if test -f 'hdd_file.c'; then $(CYGPATH_W) 'hdd_file.c'; else $(CYGPATH_W) '$(srcdir)/hdd_file.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-hdd_file.Tpo $(DEPDIR)/pcem-hdd_file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hdd_file.c' object='pcem-hdd_file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-hdd_file.obj `if test -f 'hdd_file.c'; then $(CYGPATH_W) 'hdd_file.c'; else $(CYGPATH_W) '$(srcdir)/hdd_file.c'; fi` + pcem-headland.o: headland.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-headland.Tpo $(DEPDIR)/pcem-headland.Po @@ -1574,6 +1642,20 @@ pcem-keyboard_xt.obj: keyboard_xt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-laserxt.o: laserxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-laserxt.o -MD -MP -MF $(DEPDIR)/pcem-laserxt.Tpo -c -o pcem-laserxt.o `test -f 'laserxt.c' || echo '$(srcdir)/'`laserxt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-laserxt.Tpo $(DEPDIR)/pcem-laserxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='laserxt.c' object='pcem-laserxt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-laserxt.o `test -f 'laserxt.c' || echo '$(srcdir)/'`laserxt.c + +pcem-laserxt.obj: laserxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-laserxt.obj -MD -MP -MF $(DEPDIR)/pcem-laserxt.Tpo -c -o pcem-laserxt.obj `if test -f 'laserxt.c'; then $(CYGPATH_W) 'laserxt.c'; else $(CYGPATH_W) '$(srcdir)/laserxt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-laserxt.Tpo $(DEPDIR)/pcem-laserxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='laserxt.c' object='pcem-laserxt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-laserxt.obj `if test -f 'laserxt.c'; then $(CYGPATH_W) 'laserxt.c'; else $(CYGPATH_W) '$(srcdir)/laserxt.c'; fi` + pcem-lpt.o: lpt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-lpt.Tpo $(DEPDIR)/pcem-lpt.Po @@ -1784,6 +1866,20 @@ pcem-opti495.obj: opti495.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-opti495.obj `if test -f 'opti495.c'; then $(CYGPATH_W) 'opti495.c'; else $(CYGPATH_W) '$(srcdir)/opti495.c'; fi` +pcem-paths.o: paths.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-paths.o -MD -MP -MF $(DEPDIR)/pcem-paths.Tpo -c -o pcem-paths.o `test -f 'paths.c' || echo '$(srcdir)/'`paths.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-paths.Tpo $(DEPDIR)/pcem-paths.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='paths.c' object='pcem-paths.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-paths.o `test -f 'paths.c' || echo '$(srcdir)/'`paths.c + +pcem-paths.obj: paths.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-paths.obj -MD -MP -MF $(DEPDIR)/pcem-paths.Tpo -c -o pcem-paths.obj `if test -f 'paths.c'; then $(CYGPATH_W) 'paths.c'; else $(CYGPATH_W) '$(srcdir)/paths.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-paths.Tpo $(DEPDIR)/pcem-paths.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='paths.c' object='pcem-paths.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-paths.obj `if test -f 'paths.c'; then $(CYGPATH_W) 'paths.c'; else $(CYGPATH_W) '$(srcdir)/paths.c'; fi` + pcem-pc.o: pc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-pc.Tpo $(DEPDIR)/pcem-pc.Po @@ -1980,6 +2076,20 @@ pcem-serial.obj: serial.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-sio.o: sio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sio.o -MD -MP -MF $(DEPDIR)/pcem-sio.Tpo -c -o pcem-sio.o `test -f 'sio.c' || echo '$(srcdir)/'`sio.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sio.Tpo $(DEPDIR)/pcem-sio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sio.c' object='pcem-sio.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sio.o `test -f 'sio.c' || echo '$(srcdir)/'`sio.c + +pcem-sio.obj: sio.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sio.obj -MD -MP -MF $(DEPDIR)/pcem-sio.Tpo -c -o pcem-sio.obj `if test -f 'sio.c'; then $(CYGPATH_W) 'sio.c'; else $(CYGPATH_W) '$(srcdir)/sio.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sio.Tpo $(DEPDIR)/pcem-sio.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sio.c' object='pcem-sio.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sio.obj `if test -f 'sio.c'; then $(CYGPATH_W) 'sio.c'; else $(CYGPATH_W) '$(srcdir)/sio.c'; fi` + pcem-sis496.o: sis496.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-sis496.Tpo $(DEPDIR)/pcem-sis496.Po @@ -3100,20 +3210,6 @@ pcem-wx-config.obj: wx-config.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-config.obj `if test -f 'wx-config.c'; then $(CYGPATH_W) 'wx-config.c'; else $(CYGPATH_W) '$(srcdir)/wx-config.c'; fi` -pcem-wx-sdl2-hdconf.o: wx-sdl2-hdconf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-hdconf.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo -c -o pcem-wx-sdl2-hdconf.o `test -f 'wx-sdl2-hdconf.c' || echo '$(srcdir)/'`wx-sdl2-hdconf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo $(DEPDIR)/pcem-wx-sdl2-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-hdconf.c' object='pcem-wx-sdl2-hdconf.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-hdconf.o `test -f 'wx-sdl2-hdconf.c' || echo '$(srcdir)/'`wx-sdl2-hdconf.c - -pcem-wx-sdl2-hdconf.obj: wx-sdl2-hdconf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-hdconf.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo -c -o pcem-wx-sdl2-hdconf.obj `if test -f 'wx-sdl2-hdconf.c'; then $(CYGPATH_W) 'wx-sdl2-hdconf.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-hdconf.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-hdconf.Tpo $(DEPDIR)/pcem-wx-sdl2-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-hdconf.c' object='pcem-wx-sdl2-hdconf.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-hdconf.obj `if test -f 'wx-sdl2-hdconf.c'; then $(CYGPATH_W) 'wx-sdl2-hdconf.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-hdconf.c'; fi` - pcem-wx-sdl2-status.o: wx-sdl2-status.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-status.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-status.Tpo -c -o pcem-wx-sdl2-status.o `test -f 'wx-sdl2-status.c' || echo '$(srcdir)/'`wx-sdl2-status.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-status.Tpo $(DEPDIR)/pcem-wx-sdl2-status.Po @@ -3170,6 +3266,62 @@ pcem-wx-sdl2-display.obj: wx-sdl2-display.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` +pcem-wx-sdl2-video-renderer.o: wx-sdl2-video-renderer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video-renderer.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video-renderer.Tpo -c -o pcem-wx-sdl2-video-renderer.o `test -f 'wx-sdl2-video-renderer.c' || echo '$(srcdir)/'`wx-sdl2-video-renderer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video-renderer.Tpo $(DEPDIR)/pcem-wx-sdl2-video-renderer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-video-renderer.c' object='pcem-wx-sdl2-video-renderer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video-renderer.o `test -f 'wx-sdl2-video-renderer.c' || echo '$(srcdir)/'`wx-sdl2-video-renderer.c + +pcem-wx-sdl2-video-renderer.obj: wx-sdl2-video-renderer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video-renderer.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video-renderer.Tpo -c -o pcem-wx-sdl2-video-renderer.obj `if test -f 'wx-sdl2-video-renderer.c'; then $(CYGPATH_W) 'wx-sdl2-video-renderer.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video-renderer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video-renderer.Tpo $(DEPDIR)/pcem-wx-sdl2-video-renderer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-video-renderer.c' object='pcem-wx-sdl2-video-renderer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video-renderer.obj `if test -f 'wx-sdl2-video-renderer.c'; then $(CYGPATH_W) 'wx-sdl2-video-renderer.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video-renderer.c'; fi` + +pcem-wx-sdl2-video-gl3.o: wx-sdl2-video-gl3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video-gl3.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video-gl3.Tpo -c -o pcem-wx-sdl2-video-gl3.o `test -f 'wx-sdl2-video-gl3.c' || echo '$(srcdir)/'`wx-sdl2-video-gl3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video-gl3.Tpo $(DEPDIR)/pcem-wx-sdl2-video-gl3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-video-gl3.c' object='pcem-wx-sdl2-video-gl3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video-gl3.o `test -f 'wx-sdl2-video-gl3.c' || echo '$(srcdir)/'`wx-sdl2-video-gl3.c + +pcem-wx-sdl2-video-gl3.obj: wx-sdl2-video-gl3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video-gl3.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video-gl3.Tpo -c -o pcem-wx-sdl2-video-gl3.obj `if test -f 'wx-sdl2-video-gl3.c'; then $(CYGPATH_W) 'wx-sdl2-video-gl3.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video-gl3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video-gl3.Tpo $(DEPDIR)/pcem-wx-sdl2-video-gl3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-video-gl3.c' object='pcem-wx-sdl2-video-gl3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video-gl3.obj `if test -f 'wx-sdl2-video-gl3.c'; then $(CYGPATH_W) 'wx-sdl2-video-gl3.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video-gl3.c'; fi` + +pcem-wx-glslp-parser.o: wx-glslp-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-glslp-parser.o -MD -MP -MF $(DEPDIR)/pcem-wx-glslp-parser.Tpo -c -o pcem-wx-glslp-parser.o `test -f 'wx-glslp-parser.c' || echo '$(srcdir)/'`wx-glslp-parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-glslp-parser.Tpo $(DEPDIR)/pcem-wx-glslp-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-glslp-parser.c' object='pcem-wx-glslp-parser.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-glslp-parser.o `test -f 'wx-glslp-parser.c' || echo '$(srcdir)/'`wx-glslp-parser.c + +pcem-wx-glslp-parser.obj: wx-glslp-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-glslp-parser.obj -MD -MP -MF $(DEPDIR)/pcem-wx-glslp-parser.Tpo -c -o pcem-wx-glslp-parser.obj `if test -f 'wx-glslp-parser.c'; then $(CYGPATH_W) 'wx-glslp-parser.c'; else $(CYGPATH_W) '$(srcdir)/wx-glslp-parser.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-glslp-parser.Tpo $(DEPDIR)/pcem-wx-glslp-parser.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-glslp-parser.c' object='pcem-wx-glslp-parser.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-glslp-parser.obj `if test -f 'wx-glslp-parser.c'; then $(CYGPATH_W) 'wx-glslp-parser.c'; else $(CYGPATH_W) '$(srcdir)/wx-glslp-parser.c'; fi` + +pcem-wx-shader_man.o: wx-shader_man.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-shader_man.o -MD -MP -MF $(DEPDIR)/pcem-wx-shader_man.Tpo -c -o pcem-wx-shader_man.o `test -f 'wx-shader_man.c' || echo '$(srcdir)/'`wx-shader_man.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-shader_man.Tpo $(DEPDIR)/pcem-wx-shader_man.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-shader_man.c' object='pcem-wx-shader_man.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-shader_man.o `test -f 'wx-shader_man.c' || echo '$(srcdir)/'`wx-shader_man.c + +pcem-wx-shader_man.obj: wx-shader_man.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-shader_man.obj -MD -MP -MF $(DEPDIR)/pcem-wx-shader_man.Tpo -c -o pcem-wx-shader_man.obj `if test -f 'wx-shader_man.c'; then $(CYGPATH_W) 'wx-shader_man.c'; else $(CYGPATH_W) '$(srcdir)/wx-shader_man.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-shader_man.Tpo $(DEPDIR)/pcem-wx-shader_man.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-shader_man.c' object='pcem-wx-shader_man.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-shader_man.obj `if test -f 'wx-shader_man.c'; then $(CYGPATH_W) 'wx-shader_man.c'; else $(CYGPATH_W) '$(srcdir)/wx-shader_man.c'; fi` + pcem-allegro-gui.o: allegro-gui.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po @@ -3450,6 +3602,20 @@ pcem-dbopl.obj: dosbox/dbopl.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-dbopl.obj `if test -f 'dosbox/dbopl.cpp'; then $(CYGPATH_W) 'dosbox/dbopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/dbopl.cpp'; fi` +pcem-nukedopl.o: dosbox/nukedopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-nukedopl.o -MD -MP -MF $(DEPDIR)/pcem-nukedopl.Tpo -c -o pcem-nukedopl.o `test -f 'dosbox/nukedopl.cpp' || echo '$(srcdir)/'`dosbox/nukedopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nukedopl.Tpo $(DEPDIR)/pcem-nukedopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/nukedopl.cpp' object='pcem-nukedopl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-nukedopl.o `test -f 'dosbox/nukedopl.cpp' || echo '$(srcdir)/'`dosbox/nukedopl.cpp + +pcem-nukedopl.obj: dosbox/nukedopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-nukedopl.obj -MD -MP -MF $(DEPDIR)/pcem-nukedopl.Tpo -c -o pcem-nukedopl.obj `if test -f 'dosbox/nukedopl.cpp'; then $(CYGPATH_W) 'dosbox/nukedopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/nukedopl.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nukedopl.Tpo $(DEPDIR)/pcem-nukedopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/nukedopl.cpp' object='pcem-nukedopl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-nukedopl.obj `if test -f 'dosbox/nukedopl.cpp'; then $(CYGPATH_W) 'dosbox/nukedopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/nukedopl.cpp'; fi` + pcem-convolve.o: resid-fp/convolve.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve.o -MD -MP -MF $(DEPDIR)/pcem-convolve.Tpo -c -o pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-convolve.Tpo $(DEPDIR)/pcem-convolve.Po @@ -3786,6 +3952,20 @@ pcem-wx-resources.obj: wx-resources.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` +pcem-wx-shaderconfig.o: wx-shaderconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-shaderconfig.o -MD -MP -MF $(DEPDIR)/pcem-wx-shaderconfig.Tpo -c -o pcem-wx-shaderconfig.o `test -f 'wx-shaderconfig.cc' || echo '$(srcdir)/'`wx-shaderconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-shaderconfig.Tpo $(DEPDIR)/pcem-wx-shaderconfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-shaderconfig.cc' object='pcem-wx-shaderconfig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-shaderconfig.o `test -f 'wx-shaderconfig.cc' || echo '$(srcdir)/'`wx-shaderconfig.cc + +pcem-wx-shaderconfig.obj: wx-shaderconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-shaderconfig.obj -MD -MP -MF $(DEPDIR)/pcem-wx-shaderconfig.Tpo -c -o pcem-wx-shaderconfig.obj `if test -f 'wx-shaderconfig.cc'; then $(CYGPATH_W) 'wx-shaderconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-shaderconfig.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-shaderconfig.Tpo $(DEPDIR)/pcem-wx-shaderconfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-shaderconfig.cc' object='pcem-wx-shaderconfig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-shaderconfig.obj `if test -f 'wx-shaderconfig.cc'; then $(CYGPATH_W) 'wx-shaderconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-shaderconfig.cc'; fi` + .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 2c109cd..1c97379 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -3,6 +3,7 @@ CPP = g++ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ @@ -21,12 +22,12 @@ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ -wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -lGL PCem-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2" $(LIBS) @@ -45,7 +46,7 @@ wx-resources.o : pc.xrc $(CC) $(CFLAGS) -c $< %.o : %.cc - $(CPP) $(CFLAGS) -c $< + $(CPP) $(CXXFLAGS) -c $< %.o : %.cpp - $(CPP) $(CFLAGS) -c $< + $(CPP) $(CXXFLAGS) -c $< diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 6d6b385..a4e5963 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -2,7 +2,8 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc WXRC = wxrc -CFLAGS = -Doff64_t=__off64_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ @@ -21,12 +22,12 @@ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ -wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -lGL PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) @@ -45,7 +46,7 @@ wx-resources.o : pc.xrc $(CC) $(CFLAGS) -c $< %.o : %.cc - $(CPP) $(CFLAGS) -c $< + $(CPP) $(CXXFLAGS) -c $< %.o : %.cpp - $(CPP) $(CFLAGS) -c $< + $(CPP) $(CXXFLAGS) -c $< diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 0ecfaa4..50d78cd 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -1,8 +1,12 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc -WXRC = wxrc -CFLAGS = -DRELEASE_BUILD -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +WINDRES = windres.exe +WXRC = ../utils/wx/wxrc.exe +WXVERSION = 31 +WXINCLUDE = C:/MinGW/include/wx/ +CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -IC:\MinGW\lib\mswu +CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ @@ -18,29 +22,38 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad 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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o \ - wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ - wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o + vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ + wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ + wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -mwindows -lopenal32 -lstdc++ -lwxbase31u -lwxmsw31u_core -lwxmsw31u_xrc -lmingw32 -lSDL2main -lSDL2 -mwindows -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static +LIBS = -Wl,--subsystem,windows -mthreads -mwindows -lwxmsw$(WXVERSION)u_xrc -lwxmsw$(WXVERSION)u_html -lwxmsw$(WXVERSION)u_adv -lwxbase$(WXVERSION)u_xml -lwxmsw$(WXVERSION)u_core -lwxbase$(WXVERSION)u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -lcomdlg32 -lwinspool -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lmingw32 -lopengl32 -lopenal32 -lstdc++ -lSDL2main -lSDL2 -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2.exe" $(LIBS) + strip -s PCem-wx-SDL2.exe all : PCem-wx-SDL2.exe clean : - del *.o - del PCem-wx-SDL2.exe + rm *.o + rm PCem-wx-SDL2.exe + rm *.res + +wx-resources.o : pc.xrc + $(WXRC) -c pc.xrc -o wx-resources.cpp + $(CPP) $(CXXFLAGS) -c wx-resources.cpp %.o : %.c $(CC) $(CFLAGS) -c $< %.o : %.cc - $(CPP) $(CFLAGS) -c $< + $(CPP) $(CXXFLAGS) -c $< %.o : %.cpp - $(CPP) $(CFLAGS) -c $< + $(CPP) $(CXXFLAGS) -c $< + +wx.res: wx.rc + $(WINDRES) -I$(WXINCLUDE)/../ -i wx.rc --input-format=rc -o wx.res -O coff diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 9fc9bd3..9b2983a 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -21,12 +21,12 @@ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ -wx-sdl2.o wx-config.o wx-deviceconfig.o wx-sdl2-hdconf.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o +wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -L/usr/local/opt/openal-soft/lib +LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -L/usr/local/opt/openal-soft/lib -framework OpenGL PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c index cd89b36..820e7e6 100644 --- a/src/cdrom-ioctl-linux.c +++ b/src/cdrom-ioctl-linux.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "ibm.h" #include "ide.h" #include "cdrom-ioctl.h" diff --git a/src/cdrom-ioctl-osx.c b/src/cdrom-ioctl-osx.c index 5243ebd..7f1e750 100644 --- a/src/cdrom-ioctl-osx.c +++ b/src/cdrom-ioctl-osx.c @@ -7,6 +7,8 @@ static ATAPI ioctl_atapi; +int old_cdrom_drive; + void ioctl_audio_callback(int16_t *output, int len) { memset(output, 0, len * 2); diff --git a/src/config.c b/src/config.c index 48c917a..e888507 100644 --- a/src/config.c +++ b/src/config.c @@ -98,6 +98,43 @@ void config_free(int is_global) } } +int config_free_section(int is_global, char *name) +{ + section_t *current_section, *prev_section; + list_t *head = is_global ? &global_config_head : &machine_config_head; + current_section = (section_t *)head->next; + prev_section = 0; + + while (current_section) + { + section_t *next_section = (section_t *)current_section->list.next; + if (!strcmp(current_section->name, name)) + { + entry_t *current_entry; + + current_entry = (entry_t *)current_section->entry_head.next; + + while (current_entry) + { + entry_t *next_entry = (entry_t *)current_entry->list.next; + + free(current_entry); + current_entry = next_entry; + } + + free(current_section); + if (!prev_section) + head->next = (list_t*)next_section; + else + prev_section->list.next = (list_t*)next_section; + return 1; + } + prev_section = current_section; + current_section = next_section; + } + return 0; +} + void config_load(int is_global, char *fn) { FILE *f = fopen(fn, "rt"); @@ -279,6 +316,27 @@ int config_get_int(int is_global, char *head, char *name, int def) return value; } +float config_get_float(int is_global, char *head, char *name, float def) +{ + section_t *section; + entry_t *entry; + float value; + + section = find_section(head, is_global); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + sscanf(entry->data, "%f", &value); + + return value; +} + char *config_get_string(int is_global, char *head, char *name, char *def) { section_t *section; @@ -315,6 +373,24 @@ void config_set_int(int is_global, char *head, char *name, int val) sprintf(entry->data, "%i", val); } +void config_set_float(int is_global, char *head, char *name, float val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head, is_global); + + if (!section) + section = create_section(head, is_global); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + sprintf(entry->data, "%f", val); +} + void config_set_string(int is_global, char *head, char *name, char *val) { section_t *section; diff --git a/src/config.h b/src/config.h index 174c437..16d513e 100644 --- a/src/config.h +++ b/src/config.h @@ -1,9 +1,13 @@ +float config_get_float(int is_global, char *head, char *name, float def); int config_get_int(int is_global, char *head, char *name, int def); char *config_get_string(int is_global, char *head, char *name, char *def); +void config_set_float(int is_global, char *head, char *name, float val); void config_set_int(int is_global, char *head, char *name, int val); void config_set_string(int is_global, char *head, char *name, char *val); -void add_config_callback(void (*loadconfig)(), void (*saveconfig)(), void (*onloaded)()); +int config_free_section(int is_global, char *head); + +void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()); char *get_filename(char *s); void append_filename(char *dest, char *s1, char *s2, int size); diff --git a/src/hdd.c b/src/hdd.c index 05b1ffd..9cf3a40 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -53,16 +53,16 @@ int hdd_controller_available(int hdd) return device_available(hdd_controllers[hdd].device); } -int hdd_controller_current_is_mfm() +int hdd_controller_is_mfm(char* internal_name) { int c = 0; while (hdd_controllers[c].device) { - if (!strcmp(hdd_controller_name, hdd_controllers[c].internal_name)) + if (!strcmp(internal_name, hdd_controllers[c].internal_name)) { hdd_controller_current = c; - if (strcmp(hdd_controller_name, "none")) + if (strcmp(internal_name, "none")) return hdd_controllers[c].is_mfm; } c++; @@ -71,6 +71,11 @@ int hdd_controller_current_is_mfm() return 0; } +int hdd_controller_current_is_mfm() +{ + return hdd_controller_is_mfm(hdd_controller_name); +} + void hdd_controller_init(char *internal_name) { int c = 0; diff --git a/src/hdd.h b/src/hdd.h index c0443e0..26faa2b 100644 --- a/src/hdd.h +++ b/src/hdd.h @@ -2,6 +2,7 @@ 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_is_mfm(char* internal_name); int hdd_controller_current_is_mfm(); void hdd_controller_init(char *internal_name); diff --git a/src/icons/16x16/cd.png b/src/icons/16x16/cd.png new file mode 100644 index 0000000000000000000000000000000000000000..6afc04b7a91eff61c711563d1f424af719667adf GIT binary patch literal 835 zcmV-J1HAl+P)Pn}N!-cGfVj~ZcP`v$Oe6&2N;lwwjY5Jk5J@y*M3g8()PSfI z`3j}<$1uO=otg4cUvegs_wG6O-23k1@Xu;}`ng@x*+s_SVyQh2knA?@;g!1b#+|W@ zg19YW@AwHtV||B%IVdmmBjDx`)qo5;5Z_=J53OME%L1G>uD1D9MgLy{t-WIxY#i5l zy1Epqz+*lE=sMux0XL!4Yr4Q{QpKYe69%!ixvrw$5U?2nilTMaRvo~+#$z@PxM(+9 zB)EVamqnJ68q}DMx+D7`t7_k-b4N?hhxYQ~TqNucI4Enn6Ug%bUdMK=@`jG-P!h{w z8UBEXqrqI`n6%_0wsE#m!;h#Xy>d-5xqcUIougxadzSfQ?_`yAlR&go9$ zYtuD`Z2AodB#^TGovbES7arWbbn==U3qM}c={ksIkf}=0rNApXtsXF@!=9=&x~9OF z=DM8Xo_pvy@~6{G~i>|7E)FOTXnFMLai zFcDEN7wzJ4tVlG;;SI`87GiN72G10TtuA%H9-Tdx#b-iNRq&!6Ho=a{Vjh*7&M0(# zowDne{h!kdh=zZ6r=}DIce)0rkC&DqKhKLaav-{B3KbxsSe9u7%*+yz*WwB$hu`9A zeN7<^Qpgyj(5E-gn+B)8LJ%1>hcg?sLUtpHg*DZ}GFh1#d56)VfhL1zmSB83TW)rM z)MZ&|t2tDHz4?0(XPjx-Ks3n^nV-dK=o>x`y=>|*;v-@2|GR|ey>wlX^gKyVa@`vS&KY!F zd!=txD5X?z95>m1=`@5RHsxrBhR*v#$t?*OV{l!UAdt!C@M&U-G*`)2Z$}PPsvLby zag&0k!IKVr`^AOZ^8_rP>&IN-!tYG?s81ohWS&H>lK~8k8jX_m5EToY zZKxw654zvy8%+DatZ_H2-vX?aEDB;F#0!InL<2B`I!uEjOvPcc z&RmX+O{W*fXjPr+zd_{4q7L1+yJTe%G=qcy!e$5_4bUao9BD|ho(L6Sc%lj4V}oE{ zp&Y%oE)rpq2*|;bm4P0J!lo&tZ3aOtfC^<+z_mCkon{;?8N|t>KyBGId`xv=e6k<8 zNDACRZ|CBCGtV|1(&tmRhEyI^?RaoPp=?MV7= zp7c~AXEY=p!`#j$9NGie4sf$x;`T73Ap_$-)NY}Q5cdmi^gj6otT~n(!b&(>}uD5N_HFv>G|1#c%tOo+G^83hlStizQ?`o zeU05{GmCJ>f8}qboyN1FR!Uq5V N002ovPDHLkV1jYEU=RQR literal 0 HcmV?d00001 diff --git a/src/icons/16x16/computer_delete.png b/src/icons/16x16/computer_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..06eb7c65b716d29c040b620923ebf23e58a1539a GIT binary patch literal 774 zcmV+h1Nr=kP)DW6dcpQ7}zN zIbOXZo;F6oB;rpoAx*bSQ(A)%=VWMhPHEIX@Xoxh3$t=gv$&$bt zR4!loHmK2e;uvkCb=j2y8V-`j!t?qu_|RuqGt*POp9TkZw)FQy$5C`|Qpve(f*&rz zY1@YEY=d}sgESNja>wY58Ah;RYp4>szvcRaekYN{>dIt*ANiR^dMbmOffv{|{sGm+ zW&ohI!q;hqFFf>yow?ExH2c1f^sljwM6&$I{A$zsjZgk=e{}VH`>VRz=CWAP0S(q9 zW3KyTPtW^iw&*WVNwsp(*(lWysw%4T1?LmmR07*qoM6N<$ Ef?t?k761SM literal 0 HcmV?d00001 diff --git a/src/icons/16x16/computer_edit.png b/src/icons/16x16/computer_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..88f128fa3668a6f4e15c9ae99711af03e850b8fc GIT binary patch literal 798 zcmV+(1L6FMP){tUEMHJ zq|yov49R+lh@yw+Wht;If(j!IABwUfkX`~of+(XvEM220D9R!$p@$?QOVeJg2cakx z)1-BGoxRMpe|8Nbb>N?wbI$jF|Lr@hsqHZqdo0`TGEFOF+YYUqe@+-UjzJLkC&EIG zj^kv^FwD@o+G<#aH4np!Jepe{gcc-VjKMTbG7G7+jt^gcP|P{xiaMNEJ2xbXb7VB1I+7@iu5^So|vg}Zn#Q7%-Ao3h8-+GjBqNL!>&4nN-FbHrc zw3!GT2yUJAHM_t$7PvXjY!9+LZZtQNX))XgKga%kJ0RbDhvd~h=zb!wEEDNe8XKC% zkRR~C>lNWqM5q!6l?PPLfk*@m+eDfQ!^5^_)Knb7#P}4Bj>o`J3D6R0I9???&O zhE@WjKY^Jj-uKy@1-I8{&V31GMdorA>~-Esx% z9gPHK!JVE%;&264Lgshp-`H|@K=B7rRJ0uY+lvU6mSbmy58-QJyeU2p+1AKcCym${ zx$7ydmo;4K$cV=<3`C|UJAC;Chb<-{IQA5>nMCzE8EZ~-RV{L1XV`xmg=EVX0DfHT c%Ks5y0O6fOEc%yjw*UYD07*qoM6N<$f+%%if&c&j literal 0 HcmV?d00001 diff --git a/src/icons/16x16/control_eject.png b/src/icons/16x16/control_eject.png new file mode 100644 index 0000000000000000000000000000000000000000..00deee0d20af0726ca13158a544ac10785270fc3 GIT binary patch literal 685 zcmV;e0#f~nP)+n?#>9k(?{;>e>v}Si$-Mn90G%aEHMPDD$%JpsCc0f4n#TiY zJVq!K#MxL3QW>_&Wjd-L4B%k^W=^G2uZVRRaq`Hgp9&xnAUGNi5ex?LsPGuqlSy=?+{MK+>ZVRRaq`HgAAfxATi86x zsgo!0rdpkyuClwF=`#u7_xlx?PNxwF1mN*-KokdKX`TNcLnZQ{q_&$$4n$MQ_c&S}&> zegOSkESAsbomQ*ubUIzfvi>--M2^gSBGfI*QaE|!)6ZR`X1!j|R4UuBEE9g+uQqNl z7)*q^Uq(orJo4!`X=15VdcnKb>lIg5uV88Eyu3N`Z`U=A<)T*mgx%fu%Gu@PsLk$) zik!>kau1@>=neU=Phow-FkTDxQ2y_W7;|6a)QO24KUy;PNDJ}HEqnTN{wu%$cuGOZ T6S&mg00000NkvXXu0mjfVEjtx literal 0 HcmV?d00001 diff --git a/src/icons/16x16/control_play_blue.png b/src/icons/16x16/control_play_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..184be23125a64eb0a80617582aa9e45c6f0e8c58 GIT binary patch literal 742 zcmVA-TnxX&OtGGJ9Wl9&at> z64AfGk*-8jW5*!%ji%`L0eUi4SZHM6v>KBKEQj>>WiQCI2u7w!vB_@dJWeh^$fvA-VU>18;| zfD;BK*&2BtFFTCx*GhLOySwhGvGONLMk=jWfx{L#JjFwu~?wkz~_uRx5khd9>ep_ zQ}9EA1QVX{MYpmC*>wNV`){a;^4cvEmdOU(IJj>co;;1C|MqG4zMMDdgu)ZP=!z-o z8gC5H$Dd0yohO>e5GDEMrE)}{e)%++CHk6Kf%JtZe9;vz()Y~7o2zXPM=?8>M|HWZ zlcVt+-N14ARN>it8@Voh;R#=KrSGC*&)N1?aqf9FMalVq=Hv}9RCwBqQ%y)!K^Q%A@7(vE_o>eo zlKmUjqT1WW7A-1i7qkhB2%>1?wjw3+iP)l*e~T7|B(_j=6BfRL5W&ZoFDpqK1Oy*Tyl3hv#|jpA*=#wa#ImpKF3} zB_k{w1p2TvbNac(lHV`ebnNI8oA&vFdixEE#m z(B9EaRfRY{aB08u>TN=G5U%fm>Iu~fDZNdbmHOU z9h4?Uk@4Z?tu@3Rb{yeqNn?ff=Q+xEe7!WAFH^3DIaxi8Xw-#WK@;gJNRCwB)Q%y)zQ562}&%19%GtkI> zh>CuYD1vCnb&C-S!zi#KYEy1BB3wjJJ1GdFg@hCmp`~raf`p1(2`Q59)I}|VLU3ha zIWuqO-uL?MD@>Pl;4sYNobPN>qea64E;mJD^OF4_f=- zvJTQ^p^_}L2+1aZ4pchL*%;O(s91rhRHRgX_h?ZC$^CP^82@w;r2-H%4}e1vENntB zbChx{L1I)m$+9`uFo7?nJU#FL4$18^ckp4p4T%EowqD{YEdrC^#&AEfvj#E02k9!4 zl)mJete4bbFT0hbHzT0bpqZyrGr1IQwDM3@a)}Q*zym0Kn8EFBWK;c zscR?Ou&8?RWC$t!LEVR{#cj}`K+LTK!g~;Lr2=&|A);d8_Z^(*#`LSJ$O+jy)p7b1 zOlBBcCOZKg5s9lY)JUR^hheGLZz1Hhm7`^ZoHA08&%BX z@&XkBSjanYG{9NE#stN}GOCS)j!glzW0!HhRZcg3oWc9}5LAYpr0ttmj@n6j;yoZ6 zniCb5IfyHUv^;elf)aT9Z4WD#_&R8{So;<%bM$jH4%Qcukpw8v#QKftOFE2yjGGsZ tG&OAB(ABtahZ6X|sAKN*5BQe=0{|&L5m;-6DpCLd002ovPDHLkV1n8DQX&8V literal 0 HcmV?d00001 diff --git a/src/icons/16x16/drive.png b/src/icons/16x16/drive.png new file mode 100644 index 0000000000000000000000000000000000000000..e3979a83d4f080ff2e75f836e97065cde5a87a74 GIT binary patch literal 430 zcmV;f0a5;mP)YOW36Z*}C?aTQL3in(b?nlh9n!nx%y&kIs@Au{1 zy?a7yjZwnFh~ez+?ITSySeD>gmrA99K$0Z6c7Ljhxht%#u7E5vK+;R#`5u;+7IR(~8qo*pH}CxKmsi(@A!`g|Pr~*=LVeEj)Ncw%osMvm@;;|-A28BwD8-WV5a%2Y%pIIf9#K~&=LRMjjsX> Y00BI)n_shN)Bpeg07*qoM6N<$f-RN5#Q*>R literal 0 HcmV?d00001 diff --git a/src/icons/16x16/drive_add.png b/src/icons/16x16/drive_add.png new file mode 100644 index 0000000000000000000000000000000000000000..0a6b97c49e8c0164204c3622940ccfb480a56389 GIT binary patch literal 634 zcmV-=0)_pFP)I^8Bir7(`&SOUv zFRMP{A52ugg7m~|T>^n$DFL_S615|E>ToLa@lU;#Y&BwHiZDWkINa98rr36HL&!j& zO7PJlk%&!hZIyU@YgM2USM{2Za7bsbl397e{c&|_Ku7pIcwLnYbT?zMD6_MlH^4f& zo^zC`AJ@n^X-*x1_8ke{Wrvxbdql|ohNWTCvTz)yy#8*sijKpBOq%1(uwH=uTZVWw zH_Se@f18`Y%IEWMQmMxsQpy_rR<#EXW(yo@>gQn7o$~qRcFBkA0F$2v%bn80-&}8S zeIvX-&<{907*qoM6N<$f>#J9uK)l5 literal 0 HcmV?d00001 diff --git a/src/icons/16x16/folder.png b/src/icons/16x16/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..f1ed9abe0338be5a0401f4aee1b3bb168b4d815f GIT binary patch literal 632 zcmV-;0*C#HP)4gUbq(tw1lgoXx`HVs0gK|-QT;Nk*gBnKlTn_z-{ zmhYU)-7d3t&KJ-ik94}dotgJ$-pr9P27{QufTqgxGmAP3uNoaE7bGM|sxpx{$6x!S zseeO+ZJ)Bq=VzY*TTvP$C03r?ILjc0=nnu+A|W7D<`Wa0NdS!2oVvxShDKmPGuu1Z{X#D3g|-0BZ&qN9*G%zO46N zD4sVu^%@Qrc`Ds1baRPAMG7LbeA>HftOGIA&>{S+y14WB!(!4xyYUUh=}X*79hA*; zs@NUjK4So91b$-;-y6->tMfCSvO&Q{3%OG#fnJLTF^s=9aIa;Dv9bIfwI98O6QfM# z&RzC+V0j(IuuEljHs;@Ei!vnIlXu^Ym7iYmY~+PRvHvr>_inmd1OCpx1sDLU%fF)P S!b7P50000 literal 0 HcmV?d00001 diff --git a/src/icons/16x16/setting_tools.png b/src/icons/16x16/setting_tools.png new file mode 100644 index 0000000000000000000000000000000000000000..81857cd8d05218020365367fa5ef5b2d5732e45f GIT binary patch literal 1017 zcmVW}`hKTLnv#$eiNXap^y z5?ab`nwF)tbz#>6U3O;K2kd)hcDzGK{NqVZ=FXjazVF=gWvIUXL5QLV1%euZoiah9T}1B@b+WqE^wAYQ6`x!m&h zTW_MPyW4$jWaQ%#qft&vO|_SmmLThiCm~28BH;)ej``w8%S(=p0?A|&k|cd!yn9z| zb(IM}T)vEx9qs$cr@!Ana@4!CumChgW8%+Agu`Kk!Xbd7NYf-3MVy_T4UXe#&89tY z%rBrYzW}Xm9W5G-_GmO3)#`LQ+`s=9v}zSx|G3cH)M&&e7-Id3Ac{4X!v`_<;32l? z^?2-dE3S?ZS8MTDY@<^~Mh0k_Mk0|wPv04vBnqI&J54T7v$whmv-W#R7`Sz72BTx6 zX!)cGMMXtTF;XBFOMoSzDz?oglM=ctDWMTXN=4->RqLThZf2$)0lyDt2M69sPh+)d zY|756S1VwgRoS2>bfSN zJN@&8L&Nj(jesnFaos8ZI`Wfzs|8>l3W-{u}(N@dtOS_J_t=`2ga@C(mw zt2?nT55xET@Wql?;(hQq?_8VfZ7^GGsgslIdi0NTXxneVYxy}AQ4)vgES&}lx29_j z4jp=tbmm}RiDS_lz@l?*jO(p$+}?ftE(ux7`8fEa626-7;MBWC8ycF}Q!EltI5+J_ zFd^d+&tb`BAM^DdKGyeXvolGh!2S7wkG!tgv1KoZKupHqA3n%Llfs(n5G8+M#Lt@_ z2P4mUR(S+Gu5rG{@?lroaU!O1Q&os9``+^}pRSo=c2^e%6Y<A+Z@c&Rop1HXW{42l!jXJr?mY+(D00000NkvXXu0mjfaunFH literal 0 HcmV?d00001 diff --git a/src/icons/24x24/pause.png b/src/icons/24x24/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..7e2e38dd63b138abaa117818bab099b862405092 GIT binary patch literal 635 zcmV->0)+jEP)u)O4UuFX*)xxw2Q3#3~p<|L_;e<5u~_Pap9^6`Vm|!2zAqx zC{0q_`Vri9A%sFF(?;sTO7TzT&2`Zvn7_u*IWUWN-HvH@J= z|L`5S>#o*Ie+NycCCNuBQXGRE;1cjY*i1g`dxNI(Vt3Lp5CJz^HxU58=z3zq-EQUL zT)>>4ZvSUbd;pwDudO5c`31E#rYg0Wfv# zT|0L2`4!(jt@qgF80R_gzyyW46vDm!HJ0dHn{%gMM{HtHectzru4ho29ibG*fg_>K z7!_F}CWz>D1G*Sj0!0@LFhgt**AOov0}{lTATU5RHiMvQfSuUW9+nO!;jAj*?wKOdi5c-$iIJ2Gp9#!;#7g22P~GCi%6pj*ZKNKNBptsQ9yl~MhhCjNjN@EOgfOtV)_&Vw@MXX?M=Z#B~#voUb6Z4e_ zKvrj6vaMz?#+^rQS6DK8kN77HfUV}b7yLr%9%}X-CNqBPs@jF6)d1paZ%9!q9Q1O_ z&AkUXv^^PDm6wyl+!^j;HXMp3i4zt#)nGa0QCJZp!pR*OJl|hRX<}Mre=nA0W0e_2 zi&sfN!oFdXTZeBK4RgW2vj95<5w{!u|5dPNP*{^Y~-cPhKzP&N22S~x&We?eeO{tcM$AP~PsKf7tM zoy_jMib(_TzUb7rsyPifYXEmq0^NBPlZysUZ_%08f?NgM|C$BLm7b!rEuJGYr=$M3 zpmi~{YZ`IS^%MkJJx3-$Z=t_gZ984jyFfUqmY}s_JDE%2p0A2|Wp&mi+gN4bmY|Zh o@Y$jeG|(0jx4FL{Fy_Vh3s&UrRLgmF$^ZZW07*qoM6N<$f)CJCK>z>% literal 0 HcmV?d00001 diff --git a/src/icons/24x24/refresh.png b/src/icons/24x24/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..c5054b3ecfe3aab1296d4f35c3412dfa78afdb02 GIT binary patch literal 1144 zcmV-;1c&>HP)^L1O-V% zK~zY`m6m->)m0eBKj+-v6@-gQOkfv81Oi`5B+Qk$98flJOYM)gYq)Z*tu?c(t=gJy z+WM#Uvaqc`nyV?kOy?g8wlxB*HqjX(w!9K>r-0!L?_5Cc%kSwAytn(p1$zEF=Q+>! zd(QVf&v}kw1}m;Rm1Sz*7Nyt>WCNLxTs^=oL~1RDK6_=OqdOLcnr^bN{#1rV`S*kD z0xZmICQ6+#;lpbsj$5-56gM8PYFpqW3Sf0(b*3TO87j**doCa6uf3o#G zmdyD!zFSku8_jiePXyN_VUYvCo2t0(RF+tLuF!1xY5f+`;u5I2>*9d(G7{rf6Adfh z7nM<9OXlK0FYmNo2vgCg%xsH&=PR!R6``Kav0*yKhWXajiaA5t?9M49WnMh#@rf*% zpTw#KDLj{A=hwbF2xzUeOAAsS8F*>nE=RhY_(f*S%RbKpg$ox4#~V`YcuYU$qc{<% z(4g`n1Fc%4m6|p2k9D_kV{{-m?)N<8n~rOtHIS=8(jx;uTe+UMmOVKufhoelo0sv) zl#rjdH#6e%gf7W2B7-)h*eP4Q1iuLN_q%Cx56(!^?jGVumy-fpGQZsKiY~n3hU0Al z`GKrBy{;md<8AIicKq@4taqW6!cZEI>5p{X)B>)+Xiv_XAUHsQEg45jZ*8C(+K3z_ES~l}^ z*aOQG3sN{-^a3xYX5leS_B)#*2@YQ`sq9hzH5i{0ND6oZZ;U-Y5r8qD7uWbOUem-L zZzDZ^O1g)BKl_|bG&~4vY9q?Q+M{ls2it106D`nP%zDWrdgI(FHcs1j35-irJ zi~X(t4pp74+#VkZ?{LD_t7Y43q8m=bi9LdR9ocZKT2r)eF}aD0uqeg7$#GhS9?<8R zm@c8-Ybo1)C}ztnYB=$-LaIaMnxl=N%-61#RMv(iLgcEJQpY(lj9fvg0N)&dO^~C? z@Gp-9kNK+z*y_gWOasdnFgGJ=S?ITAs)#u6Rpz9)WocT>1=DKL3aY$+!owJ+!hI8&a^X8r>9D$uwF78;9L77p4 z1W4>)MO%Vts0KApY$aJ)Y7XL%e#PeX+_-1ti3sz6UcQg6>eRpu!c_}P90s^Dl==^)RmzG_NuS>w)iq!_8sdbjAJA_#8Dgt*7Kc=QMgKE&}#-rMkm0O0nSIqFXM)2 z5g4Eyp+MUJ^$0(5-JrS|8NEo&cw#Gn9|6C2!gy6DSy^f}()j`hv;X(+|K=TZIzx_% z_kDs!7GveLmIGh|ed=4e1&noH*x%X?&zIw1Pp!A`D-SNzieC`D{hzD~1er^eSHJ!d zIEjtoD}hHq@K59-4<{;x>cGhSoX)2MVYSz;VQmqkvlHvZ+Q7&Jh`Y;f=cJiZcn)~O zbPc+K^{2z+18)^w941``Wd>mqh;^4h>%gXCeK%HKYYpP~37k!{rb~+v)Bpeg07*qo IM6N<$f=pQ%$^ZZW literal 0 HcmV?d00001 diff --git a/src/icons/32x32/add.png b/src/icons/32x32/add.png new file mode 100644 index 0000000000000000000000000000000000000000..60a7a2910eeaefb1c1d3ec231d08ec1312667c73 GIT binary patch literal 1815 zcmV+y2k7{TP)dFD!z@3;hSH-KzJ#7g5~qxjO{z?*M9{VtjxXhv8W zf`TBON z);?PO$@8Bhf?h;5KZYm%#@KW>rb2y)$5q4amKKLB!{b_s(&9C6+G=oP&1{ zl85ZL(svFclL-t@V&v>WtjaecUyZ!|82qoazOek6$95tv^`oo*M+}T~L6QJbm6v-dQ79Fhr)o;irRY$K$cm>qcHShHl`M@Xhu!%1)R1VCR(0o z+>iSmF6`UW{33*+X>|6VBog&xZk~NR2H&;59S2%;L-;p8)AP8_=fW{Rg0ahZxPCio zE6K%9>|-p;`<4N+XEjbd^~e?!mjKg|9{9#O)8L}H)fB1$#;v{OyE8!i+wg>tyO)K} z2V=dEYzf?7y8$&7Kt%&iFlNSpRZpP8ZpXTHE4?Tx5^=5nctLPvg&==vD7@DQ3F#T1 zy@0hzCM~Y8VD8*xFY`gs6(rOEDoed6 zCoiwwioHlv3wGIsSMMot!|8NjlnlsbHHTHx=fz@pp%m2hyuEq$%_;+^@YKQWB>%hd zDr3`~;S|Xw9=8aW(~S_3MlfBknS@iddABo2qCgCcXX<>Kistof;yj7tN&qz_O@;xC z$=GZF3sPz~Ni2xH39~`KLOkvQ4yH^QW7l)R0PZ9=WF(zZP0m&I3#*`TPCW1PAQ(ahQZ@sAj zVu27W);BBzDoCfFbTbBHF(zY+=Bzf?eF_J7hWl^08*0*lGFt<*MH&l}%NL%{4*qS- z3k8f|9Uj(2I(tbsV=xwDGPcds5gq&kozx&s4m+{?s^c7*))M=XL`3!Ha85AGS4V%F zQDlrsMo2#s3Z#FDREIKgGk))B#}LnlV>roJjF~+V8I|0330GINV2>cGu4vMShI_Y> zZxe`NI>TzKyNTj_tUAmmAgGlo$zmf5yJQmP32i~&A4hRL4~VHfQf zBnew1gp}v8B=?LP=ke3BCOkKnP>Vv*9yr7ztZ=tdp5JSH{%ArJDjB1jz$~&L!zHdj zxwHx8Xrytxj|Q7d=ntrT^JxNqmUIu0usc&X9m`30TJg5NhmT9Ev9pG7E6W5_lz3^P zsY7{jHKmn3r(URPl8Q_K6CuBmYRq;fTsVN!7eB)h<|@hLt;X_fBg#pZ*KESZ2VcZd zy9=v$lHp#?BITtbmsc(@ES%@bC|IvikbnP)pSOl5Il4l~IXwk2~Wx|uCA#AQs8 z1%?Gew-pc)*(h|QA4p4!w70z<=bjIL&wI`-x3CK9NuQqczV|)v^Lu~K?|I($D9rA% zI-Y#-Wy7@Ahhcc#FDa!E_}*WC`Te`^V$;)ovvK~=_7`@B%3QZ(NehB70ImlEJsHZt z@#8&Eq5tZyet6H9OCUb%Rkitv7ek**&$)g$S@5pgWW2m5@5?-THM0Pa416DM(Z{}H zz4#CjU^=BF$gqV|;kRZbL3!UW zkgzOld-;GCS82wu1f+}_c?#%wdFu^yj%mMH(^PFy)xotnl@&bl)Jyu=pmP=TD|b7U zLZa#;bQqwNAz_Ib6-NE#iWb}ayXSWn{a{_&;sw{G>Ja60tEp5{hQiS!CsC75qIKbo z@cqjm}yHa2yl1V^e4fiG&54s1h`rZJRWSaTshGG1I4k^w~WG;X@IP zWmpK6#5-D?inZnWR|9|yE4UugDRIb{Bn>z;o3lIgWLlA94Zw&2(6MEPusN4yL@P`s zZ4?R~9hg{t()Od`^X_`Lb$)(#Q9eqiF9-S{R9K>`S16tcYgAHaZ!&@Ji}7zQ01vSL$*!AeATk4{HjAjdQs%XwNDO^>EG@?Ak<1mH>xz%x}S!5vVD-5`b01RDd zB;dBAM9wVSdjtr1X z5t>B?7+DM#$c(a}BrF6Y?1-2`<(CRPL2;}}*32Z{K6fA9y|fE!KL1rLZvHVvS)s?} z+$>IsopP`o!E5Oc5Hv`XUv@8DF8-^fh^-_ zlYtCZJ&^H`DJo1**%{A3#*eKSw_}@NJSRP}=I%qI^E%qs{2HBSA4OOHpKviZi5=@h zZSvgJ|2z)#J&Fg`JPbGe25$Zi77Kc-v|AM@D7(f%=eN=@N|iknst&cWbc1%yMy7L=*RH_0F`K+u; z~7sdM0kOcqYcfkzFT?CI5gm-6Sii?SH)Q@RA_DbUC7h*tii-7M2qw1di+vHT$7 zQ=DG0oXs<_m9AQsCH2!En}_kq9D2?S;8d9yrnP literal 0 HcmV?d00001 diff --git a/src/icons/32x32/computer_delete.png b/src/icons/32x32/computer_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5a4416ec357ab312828d85a482b56f9e505ec71c GIT binary patch literal 2051 zcmV+e2>kbnP)fVv)Y1N+8LSNQqthAVRHaU9omy|j);bJ~ zMF$*;LKz(-q|~+$uEk(#ZX`L$x$M>F-Q9CINt!})CU17Xy?pQUKJW9s-?s|$`x)CG zf9?fMH#P=AaNRE{rQmz+o^9W__Z|-2@Y;NwfBz@X?hcf`p}l=M{J;mU2LnB6O2f&M zXP^S_Pd|8I)8~pH-tDjI;hoO~9z)OBUNBW~uiNB#c~9P#dBSMs0U+sn9&E?MOTFju zE;7Ir0Bdep3VC1Vp=IU+KuO-ku}pYp$I|F(Q2ICL?_lo*cz(dN1*P;G^OB&vuW2w1 z1Klqi3B^^MF(?8lqejkrI=;Pa5uIb&J!6`x4XWC|Hm4H7BTqaZo@;cjVt(bANTpy_ zEu=#q#R>_E%%~u`Uan}dhkyLL-HzvP=vcY*x>OyYoNiSrC8a5x=y?M*=_J}(-v`gT z3POG|c7y5H1V9R!zG3S(?}bQ1n`dJPV*BJB9oX@s-{9+CSPRGX%ji}((9;Ls4Q2sI z3Nk*5Z*BiMlBNbdPG%{cC>xihur%i6k~zl<(B1XbPz;Yge>kMO_@1Qg*5%D1!!rS> zfDaZNptdT7KMr>wWhz*fj)aw<&=gG5K!T`DT7u&QX%gdONYIFxJ~gD@JU|d06ww%( zfj~*Vqu^AmE!Ue30Pa?yXn-!?#@m&A-oL(yijm#BuP0-F?6UU z44NL9jK#qDfHWl0JN~t zNWv4A5;=$E7AS-zX!FFZs)qgV6ZqJ{XRz>>-wo9tt{MDie`pPI>%ItQ@mlx{a)t)L z+>rrtDMB;I05glh0+~?;l%$1VgdGu6puA#(CnybW!i1xlXxZ}%)Es*WD?jyVEaB<>Q15NK+~J8m4kAPUc=Q+CZY$b$Ape$Vj+e zu*OLjqhVTxt8a>_jf*k_JP;Xee>d#(w~gtYE_`15;YbM-t9VX~p@0kx%RVPI-poa7CT2} zRT_6SHHFslE$nlQnN_6nb?HCO6#~Hm6y+lO2GZ-El$As(kAe81DA0I9|T}wj^mb5frWPFNM;*_euV$SPo(vaou#H**Vf8h#L zztMyGrY1&d#+#1WTXHR;9d8Z{VgKORV?4F>IRIGIwGBgKx!~?fmek5+EofcRj3qbL z(&|xV88}N;4jw&@V~6&2J^Rd0f4Hh9RpaLJZ7nx8v1>|8=Yl5d3XgiY!cwRNaQyXC zI5Rf6x9hcwPtwnoxjxNOwC1|T=H=@)b$+jMLEWlow;WL*R8Ec$zr1hPlRHNK_uq>m zWJ%kvKDc~GYi;%VW$#^#`g&^GhzX`9hKGl7_TnX+9?iUXe@|bR5Fu%w3xIHC$)vPK zTJ?-?2+_?%EZos}ET38}_bqO`<1KxI`4HL{H%Va_}F&P8rNMUSK zke_a_PFp&Gl`^WNVp!MC_V)grzt878_uO*tmP)Cf^zC=gz2}_geV^xjzxO=?lRL}@ zfA!1`X_%i=N=^7CAq0HSef~%Hw0x1LZt&e?z<>D5-#w>Q_ruy8sYV6;*$G)yUc)p@+YD|7}QYonKml6@v z#D*P*gXGFTQRN*ephkc43EVuVj^HTz%`D1llUeOwoKqda&mP|%e3k?kA-{UH;&DXE zDhTK!Um+^bj8M7n3o}~Vx{ceOb3A`()BO4gWwk;f-D0eigcRuf>q(TC#xQ60mGHa^ zPUyoWxC>R3H`;+Xq_OmYdt0DWLr!vIP@#S1h9*4pi>J~0V%k$)if=yn1Y!{hBNTH?P86IMNH}&*4zzNPr?BDvZv@Hk@b*Ii-TGIbpbjHz zIcZ~X*J;?5qR0WEcwyE7rkBOB^PMKdBLdN=0V`@T(F7t96BfOS&@7%?e3&*~28%|Y zi78R~kC*9$2SIO4X)^Mh-kw456Iqm8Jr|?NBv!m}3>!lS0><@aS=&WvTmw>*m_$5I ziwczRb2M-$G%GaiNQ4gXdKLqOp?IH#Y?dl31I<@`7}wI8uBtp5CT|aBFF(lYtMXO*sklcawtb6CuTevMUq=| zl8iil?jvYu{Q??lYVp{%gD{*?oIHMlQUP1$25n$~mNat;FbQoZh(IzDDK*`>=*&oN zbqP9X18G-bIPC_BrX1=`Cw$VL$qL-xP=XQLz>0zU(AathQ2jOFl^^3?cRSYneH~aN z_|Dq(*tB(rh8?BZX0EI>11=+>1JpXuoo14Olqb+{3pyZ!jYbP@F&W`{LAmJ~_xUgD z^ZNKS%y@Dh7OcLV;429J5OAtZXDF^dzZsRS`;bnj^UbKB3g}rzGe9nNqM2lXDTcSR zJ_ZQx>jb3chL(tVpyd&U5jdo^cZ?`fvJ}mKT#^I-z}JCSHTbTe6_`WXOyl_7BhUYO@C5n4N(5kSx7Sh(|MYUqUVZ0#z)AbjYJ7#@d;ZjkC7)=*o+!^XMxJRlZk`HKN?~QW9f*r!qm$_X#eU?W_L17ESkP@Vkq^H@{ws z)6I|I#Y5DbuI@e15$vLSxay(Q3+9Ak2{ONV_ zIILWFFYv?PE;yiP^F(O*W4i4)_~-|#Fp^B8_e?)dDbgpSXdLLkhi-iYZr@&rYz77+ z-`aTvrmft~?RJFwf)~t-~`_v5+--qPO& zIrJt@^u3E?C+cvx?)$J_phLcci_PhJ^U5R>?fFa}&jI&ue`)_N=cGp$%x^%`yjiH2 zQHjmZ{s70#IMysah@HERpeM2rhtF26ZQr!40~32cLdf_#I`{tDt67{@bJ@(AS&Nsg zdZ4Ug<_+auKe{`6aOKo@QB^+=J?YEa_ddO0{owh3_VL;gJ@{P0_?QWE&mGSJEmBnH z0&OPkvinxw@zlWCW7~eayZa^G#X?Y>xI^Is)nta*i@lthAsZF6@?d|>0c!`c`6%!| p920#zwn9d{5ZK56>G+QT0|1pdf;dd=HYNZ7002ovPDHLkV1kQb-lYHl literal 0 HcmV?d00001 diff --git a/src/icons/32x32/control_play_blue.png b/src/icons/32x32/control_play_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..a1f7345f3713a730b613faf82026caaa0adb375c GIT binary patch literal 1971 zcmV;k2Tb^hP)FuzPnw&Ga@2NOxDg`J$q# zyMDH*0$W!WL8Ha4>l%7TG>k;`q?i4whyuTa`Ew*l^#AdeAZp(J6tQUZrBl^gpQ0u0 zb_ghy`O6CHT< zz4qRZsyEM{OhTS&d1Lpkdza)rM9Q0cqUauqfy1pxw@w(xB!@^#Zy5cf3U=PJki20O zh(crc>HVAUNF*U8#=LTG-J!b{6>iwGr2^-IQCt~`LniGKnJx;P=@vv$Bv_d*B&<*D zo9|c{j_9}%HL!6-E-qgF%BNOrEa*A;_a-MX9Rk9Noz;sn3QGQ1^VoVyGM(ZbgG_Fe z9Jkw$XhEe7nS5-8!?1EfmFwbhEGZlLO(QlW*SG=N* zbxsf{TDvvd<8ha7q&olNdd#$lW6p_`2-0m@-_jPufydY3=PxwC>yl_qF!v_E@4(5Q z0C{!u>iJLC+=i@{uPDhjlSO1JZUKt`bw7`an)kb~_o21;>GN;G z*fNhxF{D`W&?PVA$+$aS8o<8fn=%_(S@mbetvJeZA9DAnVJCFzu&ZcJ^} zk|89`Mmcd)CKqUek(xk)2cm`u7r9%oW!IKu;<-0I#9#JqqY8q?5WZ>15q} zTs$1=ZaCZ43!fs)q6#bmnkZvlrWbYfC-B#O+vx^mK-aD7SxQ-Akwy*pTzenJLzf#^ zHxmd4{_*nR=C-TkQczc$*$eD5jeHyvDf5s06G!%w^0+>uh0XkB)e{tz}Z1oZdi5)jvZ;j(Q3Aw{K%IT2-C~hkm<|} zYCA_xc0iAgbqh%o2)oGEN$=&a-Ao0XD5$NRm`Fx^*|4 zZX74VM}|cxK@S`~kIuIaK60Zk5FoK}=RTm*!kE9TvgE6ny7-=D^URvojp<47I^PE- zuH`c+Hxp09oHPN?{<#^~dIHDWj{oj861&c+G(mv>={?(cA-?dw2lMA8e zsVTP}yHKs~ff+!abkm&9@Ctab@e*1-4-R~M;Nc&UXdlOa@|BFQ&3f=;?b|(B>+dhj z$@DHR@|$YRHa!bBC*7P#xrb(5x)(Uu(294@c7&RLy=@B}(?b}xjZPxK{*3aRxpJ!Z zonY4bZT-V>&o>v%BP$Z`gSdI`n{MP%Xk65;)2N!p!Ww>g_#Do(b`O&Bt^8R*807Ms z?o#T6BEm$1r)rzVvX|$d>KG}@O!uJTYd&ktCe^hC$(|8R)Z;Se4URQ;;$mZyjnF8@R%C-cR7$@7V2rnkDWlHjy+!Iw6DLNw`rbhHsoO zWGC6EtvL4oewPcJdE4r6-{OF literal 0 HcmV?d00001 diff --git a/src/icons/32x32/delete.png b/src/icons/32x32/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..30a45b821c6739e81891184332a263cf725e9af1 GIT binary patch literal 1886 zcmV-k2ch_hP)<# z`z>N=cJDg$-ERPfPEV?^2R}x6Xb{zjaX8Bb&U^4Q;cMv>qMcocALxOxcR&1M z0hNV3MlSvbh1tdYlb41%>B;(L9MIo6a$xe{nG@NzC%z;jbS9=S|CiU{l}eNsjeJq% znXkW?6TaukEUAe&TAw}%HIqRtH--F-QA`Yu%slzt^*#4Hp?m`TX!q@dr;fL^J${Vt z3aktaVCDVyAPhqS%czwHBrZG>cEqpO(b(6IrpF$qjNQV_@EE3sCuS)VyVpCRu0Qj? zAMJTHd+@*$dru#i;KlRjVP3ro(GZ2u^dNE}2>$`X_XIyfS<*Dvvw3)T?;>%y9}%wt zbGelGdUIp;TyEjbRbs9>p#0+Cp6-2#=pVlL{153{6{QOoV14)@)JQ}c3xJi)iBRP8 zg6!CZC7@bG;y^E=u7zTLslTTw_UE_fi%Sfwt){*|5joFn=kjtVZ^OKDg(7bV(!Sk` zblC~>)-d8k&{$hLI`$M`yZ(8)+ecz^J>g8YxuwA{dS$5*+m{Fa29>~7id=9c47Wi*$1m5l!?y)85j8u%Oj%?`nRIn+!J<=jKiLm1=nAT6m@pCu|EuN;f|P zBauQnoxr!+Tb^TVcED&7IGdsl$5(A^3_@QeoFdCaA-*X77KL?Kmu(OX^QcA+L{d8t zi>OHI+F8bC4m3m*rFRFnS5m3xW&)2XecauA+oqDT>2L4TI_f9e3zJr-(j^juGeJ(+ zg#u!aJc@Wk17k8aJD|zILLS2NWg8W&#Bf~8Kl?TGFFdv_4%V++Liwc^pfC(Mq2Q@7CYicIc)wT;RON({M2A3rF6+)({$Sz|AsEW3hGS`t^Oy%=p zYWN5gAM#R#SaZPVlBO(62SN|TT0`b(=J^40Wmlt2M51u6ez0wD)@2((R)dNNrsuuE zC^Nv_%P}j^qKy!ZO{7V!T6VJ-sxQAthZ&M^3mlXrCK8HROg1Fe6$WvONbNcs9q=t5 zBg>Py{h34(dRrTu>0Drd(?`7k(b(p}H;g$&1|mNx06m#PeQ6G+?ZWc>5ys{ta3-tv zz%rGeU$vmO?~)3NvN}|#Cul}cQd<$$Vcm7<*HbA}@;R84;7O}Cz}W0S^_7X)bG$}* z6%$HpE7WK-94g}fBVV#xeK&1SRbDbH z>zvr4(2v@fgh;0`fAMY1P$L|*oWK6^)}7Y~bD0;_H3#^gH}ZvRr<1X78mfpzH4g^O zaD~gyG{cBQFkChhJ(pNh6O>dE3k1Gcs$kyHmd?CC^eo-V^ZDPul5uf*f66Uhc-j!B z426c4UxU$>l@Xw9(UkM<9mfL+C*&{_nO5pKE=B&11kcsA#jpPRSZ z1)FCGIq{F<4f^S7u^f$hmK@Jo$8H)bu>jojWnC+{7qQ^7i&6C?De6Qc%&Ae#U%7}p z#X09_1p@yX*`6dRaQS`eT28{-O6MQ@_y6?s@rD!aojb9kg_=~HwwYv_*6viWO02$= zu#9sow!l5-ulhx^gyms<2qj;;qBMj>Z{rM z`+Dd|oP;J7k|fc!NqX;MQdLOqh9omX;QDr7PXAX%3|^zcA$Gs6ACjvYlG)vi(fb%707*qoM6N<$f(2Nb;{X5v literal 0 HcmV?d00001 diff --git a/src/icons/32x32/door_in.png b/src/icons/32x32/door_in.png new file mode 100644 index 0000000000000000000000000000000000000000..a65ed5884e371fad9d3c82212ec646eb7bda8cf5 GIT binary patch literal 1382 zcmV-s1)2JZP)GW zK}?BFU#gJwMGZm?Q7EP?eGp$1g7%@{yU+(geDF!AivK{d#3;pw`Vnih6as3sUsTaV z4AnHGX;VyMQ)-jAGjs3toI7_nyRyyBB4(45$nN}e=2>lySr<8ZRxk(xwFS$q6k6= zzLsvrKD7C{i8yJsJ|9(xMm>Mh)u_zuzPGCD*&ub z+G5dlOuhr+stuK=)~fl3G( zrD5jad$7+P#YqMzHHSbEWwK?{1i)zPG*M?wM3~nkl>S|K{;xN&BFf64Rm4D25pt|0 z(PeD|2IxnJq0`m97)S>ic%kogJll(*vBEhho23OQ+Elh+%H_M$fj7-Z&H^e#s)m7d z@f|FN8r$4OLc3O`BXSt*eGw&f0>3YR13NhYnF$H9P9g!P8SVEoE&&8NCss&Pkqg0k z7UbFa@mG)GR{3+ToV1W`u=itP{sa#6z6_Zj#(DWQ)GyD_#sTea5`@6UA~bOb*m?Iu zGw9elkGW{D(hD4b3_tmu@&dlS^2K_&6{F-BnEYcHgFS~RZI0uj97o&K0PP;dUN!*0 zS)h$^Pp_?T)IWIN5{65UVxXw23{*9+qUR|Xa3(Tjd?a|5HoEfX$9Q7T9z>lt-ASi% z+00ap2z@OepZQ!GCJdZTs#(BTR_zU_EUFAxQ&Uh<0WM8XAv53UY66%(VK**B!WSZ2 z(SdO+Y{{k(QX%pYh#BBbLv<6`JjG)Rk&vScnb=Zo!0aM$q0~k6?93D!|mWoj83ykG`kNb(+DK-7i6p`zW}^QpKQ`Ch<(SIB0_CdnrFe^&6!98fxmuLhPLhs_$!&IH0+Hx`*O zHL2(=Ppv&75!UtssxG)qw%~1<1dKDIID7GZysN43@OP<1Yn70m!kGF>$d*Y_kDwS! zdGB@{j=qMy{{JYFv0`~a;%3N&$TsK&eq3V)avL-w4#_OvOIFZyaI^}G7J3nBK)Twm z8vqD(u;Dxqcylu$FIE%-W=y~)9S113DsIKv)~#~=h8Pg3gcA|xu!}!LYYcD$;u+BX z3pO(lQXR;*Fp{~_>-w2ZJQ8sT;x35wk<5>VCMr`{bIAatMMQ58inFkV_X1uQ>n4_x zsDj{wW1vQanW3Sfa>I>i;n*^(ddYuF9s+G8&de0BBNw5w5F(#4h=*g&f^u~tas$c8 z$jEM<3mOsN&u9MY``H8Aa=F9Bo`Vl}wD)ZYJNw^WPW}GvWLwFo<>3xj oU4hN}DF3io4~D0jm45^n0OJvI9sH?~iU0rr07*qoM6N<$f?2tFk^lez literal 0 HcmV?d00001 diff --git a/src/icons/32x32/door_out.png b/src/icons/32x32/door_out.png new file mode 100644 index 0000000000000000000000000000000000000000..e4efe062692571e4bb70cf7cae814a69b72ac539 GIT binary patch literal 1394 zcmV-&1&#WNP){ zn`&r%FlxmXimjp2RDtf^J2Rd$_wKTb+uciyESzk1cg~z|zVn@P<^pT`66e49sBdxl zyI|z`ZcCq&-dY7dJ^t>ddp2%3CSf{+mw*zIzt6}u2(D%)$Hz9eG@oCZ`?+KKi#K6{ z073}Cg^OoT;P1H$5RyWXS>wZMVnD_NP$NPVsG*gs z0bp$cGhdBjDQn1&!%#pvIsL;B02OUk4Sbk7!{-6mh=FP; z@Oodtm`S1^S2*{I%*56JFXOeE02sZ30r%aq2+Q>W^~ey$c5FhwHmoS&nug4q6tT@( z`){K^?fXtw}Ne^94}9fXyjNLn<_zBu9@nmoZGadUraAOgjeP8j&hf zhAw#57WDUYJV7{Xkh=lA+H?%wUIIcZlb0JI&+dXygiP3qDPYYogHCj=00admR*Xd8 zQc$V^uV)Cyw{J!FW9@^OoOv5N?|mI_9N6bhBZS87HTy9*@-%8E71t(3F*g^14FNb2 znoxusyydPbG_IS)bkLih1r9)B&k_9oKpPq!ZGQ^qX5WHL0299+bQ?wcVb_-Jq+U23 zIP{eiX~Qbe#<Ljv%}wFd0j_C2LCDAB+Y+3cy8afsfBclV&Xxj9Vn$a@hO#W_8V^wqnG zAx^MFK_EBPfCwj_6)pv&0{nP!BR=^$gU%h97z6&l2 zwO{!nC0rSbi2h|EyE_<-_JBlKZWa_kOb`=vcX%z)gf4EKoOc#&cqfW65EuZR(6};` z%d^1ULM1eHLQj?-Mgo3YMT5;TP$a_Sz`#JZ>_+7H={&1?F8UNd1)9q5^Qn3?qyucI_mS}o z!pkvNLAG!sa^rY(baXTKh;jr(-zWd;^VuD@q|*ob+V`z*tn0k39{1;`p@=rmM8W>I zhtp{PI8A~0O)3;zf(06B0@##gfmG5`Po07*qoM6N<$g5UIn Avj6}9 literal 0 HcmV?d00001 diff --git a/src/icons/32x32/drive.png b/src/icons/32x32/drive.png new file mode 100644 index 0000000000000000000000000000000000000000..1b21050f31af873870dece6c794b29133bfe6c7b GIT binary patch literal 869 zcmV-r1DgDaP)1Q%!oX zm*@wAN%g#;i4htFQuG#4Bw~ml75yDi5r`yWCDD^o2t`UHrsQ)43DOol2dO)*J3Bk~ zcFrAl-CcEdSC;l=?{ar`?~ijn^S$Ss*=0fqsAf~3%B==a1E@Lx^O(~oUcR#ABF6S* zJd@%#u3t0ok}5|5ef;@^)!Nz$w(USV&4F`KR;N9*mu!$NvRSGE`smoW6^%yW%hzuZ z4u#R61NlnqrHIJ8b4BrixnaWTQzv0*X$kuKdUq&MXh|O#9kV(+I^g^AvK(k{I|J+M z>#(*Khh#DdiOo$<*@J-q`2BvUua7`oT^%eeewO1WT3TRkejWz;`|==i0rcUKr&f1& z7p$!O*qRb(%zy(84G@V$K-V=e48s$^vMflYY>3C>@OO0;p{=Z~=H}xtGcyZ=1Glpf z836t9lVR)1p~A2mx3{B%s1XHZ@Hv zQ~m)s|3M900000NkvXXu0mjf=;Mjm literal 0 HcmV?d00001 diff --git a/src/icons/32x32/motherboard.png b/src/icons/32x32/motherboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ce695b10c6f3b7e61d873262071f6539478fca9f GIT binary patch literal 1852 zcmV-C2gCS@P)RTTdAKIh&$_s+F( zY}83JGlGmDsvkYbh~9)Ksbxh%We<8lN)M?BDyXomEU2XDVOB_wG0mR%Cqn-eRAi+= zk)$=6QO?Y5=A3)ZJ*RK2ebjr;%#cQP@HlIq{rdK|zP0wc27tfj&Xd+!#50kmY|8sz zK8F7c68P`UUHbV&KEIT08qGZMvZY9q2K$T~q;EEUgk@6v6RfFDF~;JH*YBDsdkcUz zL^ag=f5DawD*)@m*dj-Hy0d42f_2jq&bAqvC~<9BF>O8HzV_E#&{f+V9x*!&Yqjek+Cs`{1+F=R&^q$bdnmy~?*8 zmh&o=cC~%Zzx|zdeG4APvvbdJ_u|$!4S7w_m$%=tDEVB|7W*$-g*s+pL6_I23t)%zHt?+=;Oh4$(g^(#^y6+Ai@f#cn zJt5tVAaB!<2-7IbGjPJ9P1w1!7u9nwMEBuGBHD00md~zHs44mejN6D4-?)1&{8F29 z4FS!6;7#q5jXbg!)&t$hBklE^ZFG!tfk6&HIMj!4zTT{xj61Z86H{Ef+SjOEKFf*_ zRJonwx=?JZ=)`(3=t8NHGGe(f-!OD1we)v5l(Pv?#z|x`99jWH^$6{il4?N0q(UGo z7bK8j{r#Lk0ZP!1sg~*MvdaS$m;$re$+%fK6ljw1Orm~ou`>Y*kW?8k`vEkV9LnXg zMnT+&H3S!~iZszYb&2NyFxV>;r{}wg1(_PxsR>X0Z$$(3x{A%%5o}?AuXP!zm4OB+ zDbcqn0W=tP5{8v>Ns~;$3o-y9j=%UWmmxK)@)R-qOi7cE$G1)w7y|OVgnkc)*&;|8 zn`ObKFiZ{F$`x*C^wa{xE3~;Z>cx7>ed;&aWKlEIHqpZOedmHO)RW3aE+U$2VZ&qz zFdqfBSV3F0pa3KVr#$6~`LX(GFf5|yk=q!$i3*YAkQL~{(k}^k()bR=SkGveh{)Sc z4Xbm`(6g5Z{-4L zT6GsJvnNAQ!ccszIe{BTIok;^)rfJ|XcGgnh~(@!&kd+Adv5N)#n1F{(-bc+EaQ}` z@0VC@EdWfW1G?<9m+xb{*CHHs}ttP)%cqG7hMXKXTDgtBhL@OyrNuRsR=4Djrwu70Vr^5|KytR-}s zX^`-mHn|Hi@A@S(_Gp|3aTRyW_(Mko@fa*QV~?`lNZK9fbeIdEl}gBDbHe5KxYO>X zn}1Fkt@e_|{35A*jc^mPIQfM)H#8T_6ydC`tFv z8Qn>)&>9UuLB%E-+UQ+@?c2WBuBp?G#yNI1W= z?PJ_9!RgoBw|}mzPkn6dc?8qvErBBBh4$UL$5BW|)Bv;$$3U-JzQraw1V$`9b{#ATE@n;ui(IcBf9%_YWG-ewa(4@CU#)sy6n5O z59`#uj5W=f(9}NN^hs5UP-71M=jLxe?f1w?ea+vsZH?}^H^T`0X?#0J&p7}3BNR!l q{?TZ82QW#ai2wJI>-EpS1Q-D1Wh>VO{XJ*^00001ryqqwlyw4OLSS$ETQ&E! zZ9i90S+Qlu)>c~A)JPTO0kL+tx1aXCxKn(ePoyY35ut&rLo`1(e=Qc9dGhU7_Kf5b zS>h8va>dD|<6zIm55G8WTp7G>xIG=+y{_+}54-pFcW(ktE&*G-wER;NT(frgp&i?( zt#u>my2fG}%CbxzkB8E!lu*<(tmz_pGN)$S<`$AUJ!c1u8@%ji$+$U?mvQdt`lzq7 zWy789{2o#jg%m|yaAdIHNvBO*{Kk8%Ll63}gZ-hS$BqK8SOR{(zpQ;r%iRp7k*eup z_Yh=Ml1$S~CS%o&EFx{|Kp#Z5a^!rz(ieC!Pz(Y2-Oj^L1pK8`Sy4u+>ex9~JTiLm z_dluo(|)?QbrT)=@&x^Q<(fz|*6m2Bszz0nWpqbl9lhCc;PKpAz>}{AJXuAlYY0{m zx18zRDo*6s!?cHQj?wO?9wWR)&OiA4INjg2d7(z^Vndw(r#e{wEWbLDTMPLJc&lrJ zk5pBZGi8Z1E zrgO)95D~~^DaC_FGi(Bi+1pkMB$F-LgGAk$_Hw~BAOYCt75(m5r9K6R=L=`CB9V?P`NlY zM`{Wuz@;m(4Wb}>J*y_b1C2!`(%tRzjbbB}N?pG_Ju9jm&KG;UaDg4{XXA5}WIVSE zNFcX}`yi;j+j zCUCG@qt;k(G|TsaC<{JqV&X)EChL!c{vp@{2YAI2K*i4e`2Dx94vmJb%crrB=X|1D zq1QMSL!;vad*HZrz)A$L;lytP7p{gwH@~{{#|<;Ij(eY5^O{PeE9@6^=PJt&H8;ry3)|wa-EzMg0(KGMAU1_0VRsLpvLJ{|x7002ov JPDHLkV1ixr*k}L% literal 0 HcmV?d00001 diff --git a/src/icons/32x32/setting_tools.png b/src/icons/32x32/setting_tools.png new file mode 100644 index 0000000000000000000000000000000000000000..2a1e72744479f7980973cc388a14300bb0a4bef4 GIT binary patch literal 2315 zcmV+m3H0`fP)Ran$O@M`*`EZE8B1X%mg1D)>ymAr_M{CaIk`W%965Q81mxv`xZe zQKX=gqVirrfqgH#?C#z7tLMMDo2-b)w7oNDcK6=@{@-_A-}#pZQ@plq-w~OZka$8Q z5)~&TB#4q{B*C<4(}1RFkl(upJw3g$lYe+~B`)0EEC!8613Vr+ z@Oo?Q4#xpp*N^M`WMAGCu;~M3hyExK2zE&~Zh-l@Il!YRP$-qq+WIg2R6$=~U*mhH zPwl|9hVtWY_9Z1GCM;XN6vT0H;P?9xoCi*)6Z-q_!PoT-pim5Fo_YVhK0<>3B=CI) z%4+iS@(_DH3v6YqP~X@DvgT&!>g=p!7|U?8tf>Xpy5Fd%?3*`tZbD(<66m;n7p`A# z1&jo1@zdiWH#-ZGlat_svw!Zv^&&LqWCZB_r3Y*B3-Y9!q#I#$)Bpyf5gHJ@x3^dS zR@I3uxJHL&Mq~Dt?0(Ei527iwbg!!*?`v zVoe6N1c>)Sp&-~}?L?s-AAwLFkK(`w5!{5;>j0<2 z33~k~7T$H(^qiDzzK*O7evuI1(|oqAz6IyAHSnZHqsA3ob$;FgP^#20Hf9F9!vzk9 z1MGwZwvk4wgRklvSun1Ozq`C1muhfu0OGOl1p+>jK;zTk_xUCzKo9~4v`FApIF%;&G0||ZrHPSCA6s+XdhBRidzM*X82%8qlf0}EsDs<$QZ1Y&}m^|=!}I0!=i5a;7@1v z;nxRT8@qU1D@LKEAc?nU&(0`JPELl7jt)3fw*P6oujfRBlyuD2&6|()F50!`x6dwv zyE;3l83(xi6x_Tw2h{R2Dn9eSYwuMTAFzY}f#e zZj~ZC1j$}lF%YJ@gRyv;>U}5>D}4s*?IjH>wgSa z2D#niBz=C@aT#4Xb{Q!KmEgK|~d6~1~#hHJvZ>XINc%leQC{(fg&KEDr zoLl|!@`dolIB+k5t8q?v3=iN`o&ac`4}O%t0CxVh58CxUFqzF)bjQ|h;qnhtk>ZD* z#gv@ezI=X8b=k8E;cCBu&3Q1m&TNEXtr8@+s{d)wsX>4Ov+=`r7^5QKFWZ;GvUzD6 z;||tc92e=wrr;s)=-18_uUI(0diRQKxNz6NR=d~#J-FU%0Ht~aj31U2-ERK!YM4+k z>u-YWG(mhC{C-sq{6lVmUo1!lwbd)pNmk|BWEU3z>hAgyZB;Zfpl$dGFC2@7 z>3(bk=;+egnmwx*OMjY~2p79XLGw89Pb;?A?l!mKJL*8E@N!lZT{Ay7uXfP7m2_iv1 z?viW|Uzi#qie%$!cTG+rK!6sP)t=q;lSM@<(ep>au`d}5C{z!?*?H}_{?qc0IDv8m zc|%CJnH!(AhU6@fxM^XkF!aeJ0tBYTu6f~N>FNboaKYey)^i3ABqPcJaNLnq=+7Vj zm;<+uE2{4lbutn!APKF_C(&oG&a*b1uL-oFXpT4vAK=cI^KV=2d+_@s{oppJWe9$b zlUOSUIR5em6jXI`=N?AUBhzY!!HU9bMI{(EIpA`)5lU8N;U5A4d#VZ$pwt!{P&k$d zII&=G&!|eKs@nbvm-EMgPfEguBy31R$++N^+FQV5j7?;~1yT^kEBN`AteJ698ap4H zxP=*y;X{ghsB)@i)yW-uaLq6`l)O{;H|2jM9sH0~QCKvx8iEmdr%Y2-{4zct4d?(S z3NjMPF4yuzVJUc`W{*x@?eG_>Q@ajwL&-QraF}4gr6j)g(P^PL`5BjPq(xO#{5x*X zu>b)w>toSoaFdYYMy8P~xUtFfe2OFjQ`XGY5$jN}5(>C;nvhdSAJ=B~|HAV})RjBN l3pmH@|ARyS-|IgD3;=X$f&6|~5VHUP002ovPDHLkV1lF~V^078 literal 0 HcmV?d00001 diff --git a/src/icons/32x32/sound.png b/src/icons/32x32/sound.png new file mode 100644 index 0000000000000000000000000000000000000000..8c2baf0439b195248a27b9a0f33163e32f1e286f GIT binary patch literal 1855 zcmV-F2f+A=P)_Fmedq37+!R!-#+~_Q@45G!^Zm~E`(B4qRTUoRkNTJEx$&>%T*d!x z48z!WY|ecOpMCAwfO%BlFJ(@TOCFML8x&73fyJ31TGT)3bqH<`^~L;;K>wQY~)g!SozfTH6Oh=YvV1ArbqC3{x) zm>wG6Hk%DB77G|nCQW#Q0Ssu3)TK;|j zn6a#Smb^}cy*-;8f@%61fy05Eaj&+M9A zh?mX(ouAo))fpXJk*259*$zm`kM4mfCCg*}*K0su4zlfZec2Eq+0SeyDoIPU|R zQXi;XLC5bI+e2fLVbF8`S!tz^6zL0jmhVc%I9HW`<;}ntRd9;}P|CvrkYyzhAvzEA z!aeVS;&0NTA$>)3a4w(zc1&ye`VIxM0DQ;J=oTt)$Ulz>lK^Nd{DL7UGfL=@dF9K@ zk3|5IcvQCcs12&*JW4*%kx9dFftx%VCaoRViUmaA!Xp3-G6Gr-Dzc)<6dAhQUDS!zcjc zK4suQbV5G}?q;}nxdDMIZGb=v;M!m+rf8a&LsVIw#<&-~KW~^sqQNlv)Bbp(7;)3g zRa(r2b(y2sYQG|ZqXF;(?QGgo)PX_Y_{$y!g-0!z34Ji&`TmfYmBiXeA|~-qsNUSU;vzFp*MG&Sv7I1b{bcUd4!a zr^F8P_!PB+L8Z!fl$|46I_(qZVm6%dTyip4Z`weVJol7b5(Qd1CV7yeDIJ%S>}y)I zXEi3A9949bONI0Eh(bE5f3b4?+=u!c4*@_Nqkc_sLz7;i6wN3|Z^faVYnpH0JZ-nz zR}UXC0t86}m)m`hBkB*KhVe4}#&s>C_CIn&V67eKBuq+1^s-Yl4esa}rpHQ{Ck3PI@Ui?!D zI%RL{3trImNugmFOb(&FoUEhtTN*BUvE?2qxLx_FFQ&ysVu^OTTv{oHwi_~xMrb5d zViR%z8Hz;ZDLA%~gXxESsJ7g%Z|1pp{$zN96Ra5aB- z?Q-o!eRFaE53!_dIeo-?=#zY1`OVP2@L}%-vTicza_!mUnEY-xH@j1NB_sliy#gsr z)m2ppz!3_dB|oXo8=`Ja$K6e7d%9w>@D}<1v*O@4jaM$66a-<*$WfypJS+@T2~Daa z)5bdAe|a?vG%6H@>H002ovPDHLkV1gQxf7k#3 literal 0 HcmV?d00001 diff --git a/src/icons/32x32/textfield_rename.png b/src/icons/32x32/textfield_rename.png new file mode 100644 index 0000000000000000000000000000000000000000..d35927feacb4e1d455a6e59bdceeb327fb7a0ce6 GIT binary patch literal 856 zcmV-e1E>6nP)K# zYCr^}XMBzVqX2R7$}r4+~a&tegOn+1+mUcN9gNWM|{GWwG^Jt=4%- z*A9cX+wC*;ywmAyGBy*aB%Xgg{04|vDljMgrHf4%V^(BV8WVwJEbp15nif@6c3kGf z#<+kG0;H4^vb-RB69fT-VYpC%Y@W>#5Ed4y!1tw)u=8+dZfy7EE(B;+K#y6)1gf?L z>o$2Pus?y9%bkj+QVsd`x%?ag$ zRwPScKx)5#(1@?=8+DMj1XCBqu~W=(79*z$a3&uR>J?=*(jJ-K$nwV$flkk9LGpt78B7>hUBhBpySvNA&8JBrx|mO48kk` zJtxFciO6ah6qtg2cznI2_b=w{2h{Yk#2pe>)ilg%s=x%3#?Ngvsa`)(*9vo+8uMql zMP&_|bbfQc2jPgyu;BS*4uk(XKA9v$f|&|I6eu`)c1zDFQo`a`>v+2!z`^!~q&{eY z1ur97k~{2dx}*pMgp8pAG{jF50oQeBx}iSzJdct#GKNsaW`QVfM5xQmumYDGgXO(u zHMV&}V;NgrvD_~uc96jtld;*|4YDn=#$0DC?+D0_$iCwkbe(K%sUZHN-8tDQ*-ZBU(^_S#%*YN~IzOG!*9{@F7qLg&x)DN)O>~;IU_5a`h|7#0Mn)B+u4-ZJ?tk+u8 z|Jj5P6i4Bqm$wgW!fPm4`HOG7e^5xLf5nRB6f=PT3j?%C061~tEa^D>;&I8Gq&@pS>Sx^ypcqH7*fi3nOgjIrQ!;TPcVb1dl%ipB*C?|Blkb^r$#uwl6?j+JOH*kRwY}gOZVj z7bu!T6aklX?}K%1AE`sRrAnmTNi$r5!D2?|VV&EK)p6C$MG*Lo{>000xG z(IyjSXw&JsP8uuIn1mgKGSR&n77}E=pwSY?P(D02J zgiWAW^XX;Yn#KabbPkXHw26Wv z&A1>7z;FPaUY!G}6-07mk*dr95X!()h5;(s$xT8;xGrl#I3ltz&&3uV1Bf^Z03d4O zg21>yQoa=A&&-EZA~~!w+;JJvW8G)ZInB2C0T;`=JmX&kTwVJpxzOk$>2C=!(g zpa|>u#s$;>z;R!T*afOdCb#SY5Nt)4w6P@KhXJsRQ#y^=jwPZwRkF@-NSkzPfO}q& zh~m5jC?TQerXLzqdNa1g$V z%iv&SRHX;wY$?nP#E;Z!sP3JCnEeJghtnFHm~-cDqRg$$&1Y5rkDl3S+yXo#bK+$&O@%zAGc<8Kd+?2R=@o zAd4UPbosAg@FoU%1>9Vuq2cj72|3O3>rcN8L;lW`1N7VK#BS0;*L^8;5(g;-gtJ``Im8tUBv7f*Dc9o9f=2t>(Ih#H+{nN|0u9C1Hm-R`{26u z-vB^6hH5wZRB&4Sq-YBeQp*<3r}AWl&YrtWXQq8YF^G9RT{Ne&gMR(xl(KjF{|tZ| zqF(pSpDU3|X>@#&D!!lNUFS>s&RIX-=xeQ|#ua@&N6V&dJ9l*T z^saMUw>xVBoP7BDwV|&LyuD{Hvm0`y6&JJ$K-di21-S__+k(nod0E*QgfrQ7h)*qi t=C%qT>$0L%?lg(*nl*dW>W2RaFaV=i$c7>F2WkKS002ovPDHLkV1gD1JgWcz literal 0 HcmV?d00001 diff --git a/src/icons/svg/pause.svg b/src/icons/svg/pause.svg new file mode 100644 index 0000000..537fa7f --- /dev/null +++ b/src/icons/svg/pause.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/svg/play-button.svg b/src/icons/svg/play-button.svg new file mode 100644 index 0000000..9f46031 --- /dev/null +++ b/src/icons/svg/play-button.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/svg/refresh.svg b/src/icons/svg/refresh.svg new file mode 100644 index 0000000..f3f25f1 --- /dev/null +++ b/src/icons/svg/refresh.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/svg/stop.svg b/src/icons/svg/stop.svg new file mode 100644 index 0000000..65d7bf1 --- /dev/null +++ b/src/icons/svg/stop.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/paths.c b/src/paths.c index d401d64..e3265b8 100644 --- a/src/paths.c +++ b/src/paths.c @@ -9,6 +9,7 @@ char default_roms_paths[4096]; char default_nvr_path[512]; char default_configs_path[512]; char default_logs_path[512]; +char default_screenshots_path[512]; /* the number of roms paths */ int num_roms_paths; @@ -21,6 +22,8 @@ char nvr_path[512]; char configs_path[512]; /* this is where log-files as stored */ char logs_path[512]; +/* this is where screenshots as stored */ +char screenshots_path[512]; char get_path_separator() { @@ -106,6 +109,12 @@ void set_configs_path(char *s) append_slash(configs_path, 512); } +void set_screenshots_path(char *s) +{ + safe_strncpy(screenshots_path, s, 512); + append_slash(screenshots_path, 512); +} + /* set the default roms paths, this makes them permanent */ void set_default_roms_paths(char *s) { @@ -134,12 +143,20 @@ void set_default_configs_path(char *s) set_configs_path(s); } +/* set the default screenshots path, this makes it permanent */ +void set_default_screenshots_path(char *s) +{ + safe_strncpy(default_screenshots_path, s, 512); + set_screenshots_path(s); +} + void paths_loadconfig() { char *cfg_roms_paths = config_get_string(CFG_GLOBAL, "Paths", "roms_paths", 0); char *cfg_nvr_path = config_get_string(CFG_GLOBAL, "Paths", "nvr_path", 0); char *cfg_configs_path = config_get_string(CFG_GLOBAL, "Paths", "configs_path", 0); char *cfg_logs_path = config_get_string(CFG_GLOBAL, "Paths", "logs_path", 0); + char *cfg_screenshots_path = config_get_string(CFG_GLOBAL, "Paths", "screenshots_path", 0); if (cfg_roms_paths) safe_strncpy(default_roms_paths, cfg_roms_paths, 4096); @@ -149,6 +166,8 @@ void paths_loadconfig() safe_strncpy(default_configs_path, cfg_configs_path, 512); if (cfg_logs_path) safe_strncpy(default_logs_path, cfg_logs_path, 512); + if (cfg_screenshots_path) + safe_strncpy(default_screenshots_path, cfg_screenshots_path, 512); } void paths_saveconfig() @@ -157,6 +176,7 @@ void paths_saveconfig() config_set_string(CFG_GLOBAL, "Paths", "nvr_path", default_nvr_path); config_set_string(CFG_GLOBAL, "Paths", "configs_path", default_configs_path); config_set_string(CFG_GLOBAL, "Paths", "logs_path", default_logs_path); + config_set_string(CFG_GLOBAL, "Paths", "screenshots_path", default_screenshots_path); } void paths_onconfigloaded() @@ -173,6 +193,9 @@ void paths_onconfigloaded() if (strlen(default_logs_path) > 0) set_logs_path(default_logs_path); + if (strlen(default_screenshots_path) > 0) + set_screenshots_path(default_screenshots_path); + pclog("path = %s\n", pcem_path); } @@ -194,6 +217,8 @@ void paths_init() set_nvr_path(s); append_filename(s, pcem_path, "configs/", 512); set_configs_path(s); + append_filename(s, pcem_path, "screenshots/", 512); + set_screenshots_path(s); set_logs_path(pcem_path); add_config_callback(paths_loadconfig, paths_saveconfig, paths_onconfigloaded); diff --git a/src/paths.h b/src/paths.h index 991d0d3..ba54344 100644 --- a/src/paths.h +++ b/src/paths.h @@ -3,6 +3,7 @@ extern char pcem_path[512]; extern char configs_path[512]; extern char nvr_path[512]; extern char logs_path[512]; +extern char screenshots_path[512]; void get_pcem_path(char *s, int size); char get_path_separator(); @@ -16,9 +17,11 @@ void set_default_roms_paths(char *s); void set_default_nvr_path(char *s); void set_default_logs_path(char *s); void set_default_configs_path(char *s); +void set_default_screenshots_path(char *s); /* set the paths temporarily for this session */ void set_roms_paths(char* path); void set_nvr_path(char *s); void set_logs_path(char *s); void set_configs_path(char *s); +void set_screenshots_path(char *s); diff --git a/src/pc.c b/src/pc.c index 6bb02da..3a652dd 100644 --- a/src/pc.c +++ b/src/pc.c @@ -192,6 +192,8 @@ void onesec() { fps=framecount; framecount=0; + video_refresh_rate = video_frames; + video_frames = 0; win_title_update=1; } diff --git a/src/pc.xrc b/src/pc.xrc index ebdb59f..d0137d5 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -1,34 +1,38 @@ - + - icons/drive.png - icons/disk.png - icons/cd.png + icons/16x16/drive.png + icons/16x16/diskette.png + icons/16x16/cd.png - icons/play24.png + icons/24x24/play.png - icons/pause24.png + icons/24x24/pause.png - icons/stop24.png + icons/24x24/stop.png - icons/refresh24.png + icons/24x24/refresh.png + + + + @@ -59,9 +63,6 @@ - - - @@ -83,6 +84,10 @@ + + + + @@ -141,8 +146,63 @@ 1 + - + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 @@ -161,7 +221,7 @@ - + 1 @@ -178,57 +238,120 @@ 1 + + + 1 + + + + 1 + + + + 1 + + + + 1 + - - - - - 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + - - - 1 + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + - - - - 1 - - - - - - 1 + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + - - - 1 + + + - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - 1 - @@ -252,374 +375,43 @@ - - - - - - - - - - - - Configure PCem - 1 - - - - wxALL - 5 - - 3 - 0 - 0 - 0 - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - 50 - 10 - 200 - - - - wxALIGN_CENTER|wxALL - 0 - - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - 1 - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - + + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + 1 + + + + - + @@ -631,553 +423,1435 @@ - - Configure Hard Discs + + + + + Configure PCem 1 - - - wxALL - 5 - - 1 - 0 - 0 - 0 - - - - - 4 - 0 - 0 - 0 - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - - - - - - - 4 - 0 - 0 - 0 - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - - - - - - - 4 - 0 - 0 - 0 - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - - - - - - - 4 - 0 - 0 - 0 - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - - - wxALL - 0 - - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - wxHORIZONTAL + + 0 + 1 + 0 + 0 + + + + + wxALL|wxEXPAND + 5 + + + + 1 + icons/32x32/motherboard.png + + + + 0 + 3 + 0 + 0 + 1 + - wxALIGN_CENTRE|wxALL - 0 - - 1 - + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 - wxALIGN_CENTRE|wxALL + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 120,-1 + + + + + + + wxALL + 5 + + + 220,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 0 + 0 + 10 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + + + 0 + icons/32x32/video_mode.png + + + + 0 + 3 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxALL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 0 + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + + + 0 + icons/32x32/sound.png + + + + 0 + 3 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + + + 0 + icons/32x32/drive.png + + + + 0 + 1 + 0 + 0 + 0 + + + + wxEXPAND 0 - - + + 0 + 2 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + + + wxEXPAND | wxALL + 5 + + + + + + + wxEXPAND | wxALL + 5 + + + + + 1 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + + + + + 0 + icons/32x32/mouse_pc.png + + + + 0 + 2 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + @@ -1185,6 +1859,39 @@ + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 0 + + + + + @@ -1192,117 +1899,204 @@ New Hard Disc 1 - + + 0 + 1 + 0 + 0 + + - wxALL + + wxEXPAND 5 - 2 0 + 3 0 0 - + 1 + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + 80,-1 + + -1 + + + + wxALL - 0 + 5 + 350,-1 + - wxALIGN_CENTRE|wxALL - 0 - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - + wxALL - 0 - + 5 + + + icons/16x16/folder.png + 0 - - - wxALIGN_LEFT|wxALL - 0 - - - + + + wxEXPAND + 5 + 0,0 - wxALL - 0 - + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + - - - wxALIGN_LEFT|wxALL - 0 - - - + + + wxEXPAND + 5 + 0,0 - wxALL - 0 - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - wxALIGN_LEFT|wxALL - 0 + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + -1 + wxALL - 0 + 5 - + + 350,-1 + + - + + + wxEXPAND + 5 + 0,0 + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + - wxALIGN_LEFT|wxALL - 0 - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - 1 - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 0 @@ -1312,119 +2106,186 @@ - Hard disc parameters + Hard Disc Parameters 1 - + + 0 + 1 + 0 + 0 + + - wxALL + + wxALL | wxALIGN_CENTER_VERTICAL 5 - - wxVERTICAL + + + -1 + + + + + wxEXPAND + 5 + + 0 + 3 + 0 + 0 + 1 + + + + wxEXPAND + 5 + 0,0 + - wxALIGN_LEFT|wxALL - 0 + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 - + + -1 - wxALIGN_CENTRE|wxALL - 0 - - 2 - 0 - 0 - 0 - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - - - wxALIGN_LEFT|wxALL - 0 - - - - - - wxALL - 0 - - - - - - - wxALIGN_LEFT|wxALL - 0 - - wxHORIZONTAL - - wxALIGN_CENTRE|wxALL - 0 - - 1 - - - - - wxALIGN_CENTRE|wxALL - 0 - - - - - - + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 0 @@ -1436,6 +2297,133 @@ PCem Configuration Manager 1 + + 1 + 1 + 0 + 0 + 0 + 0 + + + wxALL|wxEXPAND + 5 + + 2 + 2 + 0 + 0 + 0 + 0 + + + wxEXPAND + 5 + + wxVERTICAL + + + wxALL|wxEXPAND + 5 + + + 250,300 + + + + + + + + wxEXPAND + 5 + + wxVERTICAL + + + wxALL + 5 + + + Load + icons/32x32/control_play_blue.png + 1 + + + + + wxALL + 5 + + + Configure + icons/32x32/setting_tools.png + 0 + + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + New + icons/32x32/computer_add.png + 0 + + + + + wxALL + 5 + + + Rename + icons/32x32/computer_edit.png + 0 + + + + + wxALL + 5 + + + Delete + icons/32x32/computer_delete.png + 0 + + + + + + + wxALL + 5 + + + Quit + icons/32x32/door_in.png + 0 + + + + + + + + + + PCem Shader Manager + 1 @@ -1448,7 +2436,7 @@ 0 - 200,300 + 300,350 @@ -1460,41 +2448,19 @@ wxALL 0 - - - 1 - - - - - - wxEXPAND - - - - wxALL - 0 - - + + wxALL 0 - - + + - - - wxALL - 0 - - - - - + wxEXPAND @@ -1511,8 +2477,16 @@ wxALL 0 - - + + + + + + + wxALL + 0 + + @@ -1521,11 +2495,26 @@ wxEXPAND + + wxALL + 0 + + + + + + wxALL + 0 + + + 1 + + wxALL 0 - + @@ -1537,6 +2526,7 @@ + PCem 1 @@ -1586,6 +2576,7 @@ 5 + 1 @@ -1613,7 +2604,7 @@ wxALL 5 - + -1 diff --git a/src/video.c b/src/video.c index a515919..2a1c8e1 100644 --- a/src/video.c +++ b/src/video.c @@ -167,6 +167,8 @@ int changeframecount=2; uint8_t rotatevga[8][256]; int frames = 0; +int video_frames = 0; +int video_refresh_rate = 0; int fullchange; @@ -522,6 +524,7 @@ void video_wait_for_buffer() void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { + video_frames++; if (h <= 0) return; video_wait_for_blit(); diff --git a/src/video.h b/src/video.h index c342b4c..e3565b6 100644 --- a/src/video.h +++ b/src/video.h @@ -67,7 +67,7 @@ extern int xsize,ysize; extern float cpuclock; -extern int emu_fps, frames; +extern int emu_fps, frames, video_frames, video_refresh_rate; extern int readflash; diff --git a/src/wx-app.cc b/src/wx-app.cc index b8c1179..ca70c16 100644 --- a/src/wx-app.cc +++ b/src/wx-app.cc @@ -5,6 +5,13 @@ #include "wx-utils.h" #include "wx-common.h" +#ifdef _WIN32 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#endif + extern "C" { int wx_load_config(void*); @@ -29,6 +36,9 @@ wxDEFINE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); +#ifdef _WIN32 +wxDEFINE_EVENT(WX_WIN_SEND_MESSAGE_EVENT, WinSendMessageEvent); +#endif wxBEGIN_EVENT_TABLE(Frame, wxFrame) wxEND_EVENT_TABLE() @@ -80,6 +90,9 @@ Frame::Frame(App* app, const wxString& title, const wxPoint& pos, Bind(WX_EXIT_COMPLETE_EVENT, &Frame::OnExitCompleteEvent, this); Bind(WX_STOP_EMULATION_EVENT, &Frame::OnStopEmulationEvent, this); Bind(WX_CALLBACK_EVENT, &Frame::OnCallbackEvent, this); +#ifdef _WIN32 + Bind(WX_WIN_SEND_MESSAGE_EVENT, &Frame::OnWinSendMessageEvent, this); +#endif CenterOnScreen(); } @@ -103,7 +116,7 @@ void Frame::ShowConfigSelection() void Frame::OnCallbackEvent(CallbackEvent& event) { WX_CALLBACK callback = event.GetCallback(); - callback(); + callback(event.GetData()); } void Frame::OnStopEmulationEvent(wxCommandEvent& event) @@ -227,3 +240,10 @@ wxThread::ExitCode CExitThread::Entry() wxQueueEvent(frame, event); return 0; } + +#ifdef _WIN32 +void Frame::OnWinSendMessageEvent(WinSendMessageEvent& event) +{ + SendMessage((HWND)event.GetHWND(), event.GetMessage(), event.GetWParam(), event.GetLParam()); +} +#endif diff --git a/src/wx-app.h b/src/wx-app.h index 0c3b244..803f5d1 100644 --- a/src/wx-app.h +++ b/src/wx-app.h @@ -18,24 +18,64 @@ wxDECLARE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); wxDECLARE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); wxDECLARE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); +#ifdef _WIN32 +class WinSendMessageEvent; +wxDECLARE_EVENT(WX_WIN_SEND_MESSAGE_EVENT, WinSendMessageEvent); +class WinSendMessageEvent: public wxCommandEvent +{ +public: + WinSendMessageEvent(void* hwnd, int message, INT_PARAM wParam, LONG_PARAM lParam) : wxCommandEvent(WX_WIN_SEND_MESSAGE_EVENT) + { + this->hwnd = hwnd; + this->message = message; + this->wParam = wParam; + this->lParam = lParam; + } + WinSendMessageEvent(const WinSendMessageEvent& event) : wxCommandEvent(event) + { + this->hwnd = event.GetHWND(); + this->message = event.GetMessage(); + this->wParam = event.GetWParam(); + this->lParam = event.GetLParam(); + } + + wxEvent* Clone() const { return new WinSendMessageEvent(*this); } + + void* GetHWND() const { return hwnd; } + int GetMessage() const { return message; } + INT_PARAM GetWParam() const { return wParam; } + LONG_PARAM GetLParam() const { return lParam; } + +private: + void* hwnd; + int message; + INT_PARAM wParam; + LONG_PARAM lParam; +}; +#endif + class CallbackEvent: public wxCommandEvent { public: - CallbackEvent(WX_CALLBACK callback) : wxCommandEvent(WX_CALLBACK_EVENT) + CallbackEvent(WX_CALLBACK callback, void* data) : wxCommandEvent(WX_CALLBACK_EVENT) { this->callback = callback; + this->data = data; } CallbackEvent(const CallbackEvent& event) : wxCommandEvent(event) { this->callback = event.GetCallback(); + this->data = event.GetData(); } wxEvent* Clone() const { return new CallbackEvent(*this); } WX_CALLBACK GetCallback() const { return callback; } + void* GetData() const { return data; } private: WX_CALLBACK callback; + void* data; }; @@ -72,7 +112,6 @@ private: wxWindow* window; }; - class Frame; class App: public wxApp @@ -120,6 +159,9 @@ private: void OnPopupMenuEvent(PopupMenuEvent& event); void OnCallbackEvent(CallbackEvent& event); void OnClose(wxCloseEvent& event); +#ifdef _WIN32 + void OnWinSendMessageEvent(WinSendMessageEvent& event); +#endif void ShowConfigSelection(); wxMenu* menu; diff --git a/src/wx-config.c b/src/wx-config.c index 44368dc..6ce096c 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -1,6 +1,8 @@ #include "wx-utils.h" +#include "wx-sdl2.h" #include "ibm.h" +#include "ide.h" #include "cpu.h" #include "device.h" #include "fdd.h" @@ -26,7 +28,18 @@ static char *hdd_names[16]; int has_been_inited = 0; +static int hd_changed = 0; + +static char hd_new_name[512]; +static int hd_new_spt, hd_new_hpc, hd_new_cyl; +static int hd_new_type; +static int new_cdrom_channel; + +extern int pause; + extern void deviceconfig_open(void* hwnd, device_t *device); +extern int hdconf_init(void* hdlg); +extern int hdconf_update(void* hdlg); static int mouse_valid(int type, int model) { @@ -42,6 +55,15 @@ static int mouse_valid(int type, int model) return 1; } +static int mpu401_available(int sound_card) +{ + char* name = sound_card_get_internal_name(sound_card); + if (name && (!strcmp(name, "sb16") || !strcmp(name, "sbawe32"))) + return TRUE; + + return FALSE; +} + static void recalc_vid_list(void* hdlg, int model) { void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); @@ -184,6 +206,207 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd) } } +int config_dlgsave(void* hdlg) +{ + char temp_str[256]; + void* h; + int c, d; + int rom, gfx, fpu; + int temp_cpu, temp_cpu_m, temp_model; + int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; + int temp_dynarec; + int cpu_flags; + int temp_fda_type, temp_fdb_type; + int temp_joystick_type; + int cpu_type; + int temp_mouse_type; + int hdd_changed; + char s[260]; + PcemHDC hd[4]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + int mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + 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) && models[temp_model].ram_granularity < 128) + mem *= 1024; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), + (LONG_PARAM) temp_str); + gfx = video_new_to_old(video_card_getid(temp_str)); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type + >= CPU_i486DX) ? 1 : 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + temp_GUS = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + temp_SSI2001 = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + enable_sync = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + temp_voodoo = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + temp_fda_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); + + + if (temp_model != model || gfx != gfxcard || mem != mem_size || + 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || + temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel) + { + if (!has_been_inited || confirm()) + { + 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; + cpu_use_dynarec = temp_dynarec; + mouse_type = temp_mouse_type; + + fdd_set_type(0, temp_fda_type); + fdd_set_type(1, temp_fdb_type); + + if (hdd_names[c]) + strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); + else + strcpy(hdd_controller_name, "none"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[0]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[1]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[2]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].tracks); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[3]); + + hdc[0] = hd[0]; + hdc[1] = hd[1]; + hdc[2] = hd[2]; + hdc[3] = hd[3]; + + cdrom_channel = new_cdrom_channel; + + if (has_been_inited) + { + mem_resize(); + loadbios(); + resetpchard(); + } + } + else + return TRUE; + } + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + cpu_set(); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + cpu_update_waitstates(); + + if (has_been_inited) + saveconfig(NULL); + + speedchanged(); + +// joystick_type = temp_joystick_type; +// gameport_update_joystick_type(); + + + return TRUE; +} + int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { char temp_str[256]; @@ -245,8 +468,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); c = 0; - while (models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].cpu_type - != -1) + while (models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].cpu_type != -1) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].name); @@ -412,150 +634,17 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) recalc_hdd_list(hdlg, romstomodel[romset], 0); + hd_changed = 0; + new_cdrom_channel = cdrom_channel; + + hdconf_init(hdlg); + return TRUE; } break; case WX_COMMAND: { - if (wParam == wxID_OK) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); - int mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); - 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) && models[temp_model].ram_granularity < 128) - mem *= 1024; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); - wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), - (LONG_PARAM) temp_str); - gfx = video_new_to_old(video_card_getid(temp_str)); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); - temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); - temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type - >= CPU_i486DX) ? 1 : 0; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); - temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); - temp_GUS = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); - temp_SSI2001 = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); - enable_sync = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); - temp_voodoo = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, - WX_CB_GETCURSEL, 0, 0)]; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); - temp_fda_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); - temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - - // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); - temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); - - if (temp_model != model || gfx != gfxcard || mem != mem_size || - 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type || hdd_changed) - { - if (!has_been_inited || confirm()) - { - 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; - cpu_use_dynarec = temp_dynarec; - mouse_type = temp_mouse_type; - - fdd_set_type(0, temp_fda_type); - fdd_set_type(1, temp_fdb_type); - - if (hdd_names[c]) - strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); - else - strcpy(hdd_controller_name, "none"); - - - if (has_been_inited) - { - mem_resize(); - loadbios(); - resetpchard(); - } - } - else - { - wx_enddialog(hdlg, 0); - pause = 0; - return TRUE; - } - } - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); - video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - cpu_set(); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); - cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - cpu_update_waitstates(); - - if (has_been_inited) - saveconfig(NULL); - - speedchanged(); - -// joystick_type = temp_joystick_type; -// gameport_update_joystick_type(); - - } - if (wParam == wxID_OK || wParam == wxID_CANCEL) - { - wx_enddialog(hdlg, 0); - pause = 0; - return TRUE; - } - else if (wParam == WX_ID("IDC_COMBO1")) + if (wParam == WX_ID("IDC_COMBO1")) { h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; @@ -785,17 +874,14 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_CONFIGURESND")) { h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, - WX_CB_GETCURSEL, 0, 0)]; + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - deviceconfig_open(hdlg, - (void *) sound_card_getdevice(temp_sound_card_current)); + deviceconfig_open(hdlg, (void *) sound_card_getdevice(temp_sound_card_current)); } else if (wParam == WX_ID("IDC_COMBOSND")) { h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, - WX_CB_GETCURSEL, 0, 0)]; + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); if (sound_card_has_config(temp_sound_card_current)) @@ -807,57 +893,1045 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { deviceconfig_open(hdlg, (void *) &voodoo_device); } + else if (wParam == WX_ID("IDC_COMBOHDD")) + { + hdconf_update(hdlg); + } // - // case IDC_COMBOJOY: - // if (HIWORD(wParam) == CBN_SELCHANGE) { - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // case IDC_COMBOJOY: + // if (HIWORD(wParam) == CBN_SELCHANGE) { + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); // - // h = wx_getdlgitem(hdlg, IDC_JOY1); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? - // TRUE : FALSE); - // h = wx_getdlgitem(hdlg, IDC_JOY2); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? - // TRUE : FALSE); - // h = wx_getdlgitem(hdlg, IDC_JOY3); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? - // TRUE : FALSE); - // h = wx_getdlgitem(hdlg, IDC_JOY4); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? - // TRUE : FALSE); - // } - // break; + // h = wx_getdlgitem(hdlg, IDC_JOY1); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY2); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY3); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? + // TRUE : FALSE); + // h = wx_getdlgitem(hdlg, IDC_JOY4); + // wx_enablewindow(h, + // (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? + // TRUE : FALSE); + // } + // break; // - // case IDC_JOY1: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 0, temp_joystick_type); - // break; - // case IDC_JOY2: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 1, temp_joystick_type); - // break; - // case IDC_JOY3: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 2, temp_joystick_type); - // break; - // case IDC_JOY4: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 3, temp_joystick_type); - // break; + // case IDC_JOY1: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 0, temp_joystick_type); + // break; + // case IDC_JOY2: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 1, temp_joystick_type); + // break; + // case IDC_JOY3: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 2, temp_joystick_type); + // break; + // case IDC_JOY4: + // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); + // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + // joystickconfig_open(hdlg, 3, temp_joystick_type); + // break; return 0; } } } -void config_open(void* hwnd) +static struct { - wx_dialogbox(hwnd, "ConfigureDlg", config_dlgproc); + int cylinders; + int heads; +} hd_types[] = +{ + {306, 4}, {615, 4}, {615, 6}, {940, 8}, + {940, 6}, {615, 4}, {462, 8}, {733, 5}, + {900, 15}, {820, 3}, {855, 5}, {855, 7}, + {306, 8}, {733, 7}, {0, 0}, {612, 4}, + {977, 5}, {977, 7}, {1024, 7}, {733, 5}, + {733, 7}, {733, 5}, {306, 4}, {925, 7}, + {925, 9}, {754, 7}, {754, 11}, {699, 7}, + {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, + {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, + {615, 8}, {987, 3}, {462, 7}, {820, 6}, + {977, 5}, {981, 5}, {830, 7}, {830, 10}, + {917, 15}, {1224, 15} +}; + +static int hdd_controller_selected_is_mfm(void* hdlg) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_is_mfm(hdd_names[c]); + return 0; +} + +static void check_hd_type(void* hdlg, off64_t sz) +{ + int c; + + hd_new_type = 0; + + if (hdd_controller_selected_is_mfm(hdlg)) + { + for (c = 0; c < 46; c++) + { + if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) + { + hd_new_spt = 17; + hd_new_hpc = hd_types[c].heads; + hd_new_cyl = hd_types[c].cylinders; + hd_new_type = c+1; + return; + } + } + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + else + { + if ((sz % 17) == 0 && sz <= 142606336) + { + hd_new_spt = 17; + + if (sz <= 26738688) + hd_new_hpc = 4; + else if ((sz % 3072) == 0 && sz <= 53477376) + hd_new_hpc = 6; + else + { + for (c=5;c<16;c++) + { + if((sz % (c * 512)) == 0 && sz <= 1024*c*17*512) break; + if (c == 5) c++; + } + hd_new_hpc = c; + } + hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; + } + else + { + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + } +} + +#define ID_IS(s) wParam == wx_xrcid(s) +#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) + +static void update_hdd_cdrom(void* hdlg) +{ + void* h; + int i, j, b; + char s[25]; + + int is_mfm = hdd_controller_selected_is_mfm(hdlg); + + for (i = 0; i < 4; ++i) + { + b = !is_mfm && (new_cdrom_channel == i); + sprintf(s, "IDC_HDD[%d]", i); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_BM_SETCHECK, b ? 0 : 1, 0); + sprintf(s, "IDC_CDROM[%d]", i); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_BM_SETCHECK, b ? 1 : 0, 0); + sprintf(s, "IDC_EDIT_FN[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_FILE[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EJECT[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_NEW[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EDIT_SPT[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EDIT_HPC[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EDIT_CYL[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_TEXT_SIZE[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + for (j = 1; j < 6; ++j) + { + sprintf(s, "IDC_HDD_LABEL[%d]", i*10+j); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + } + } +} + +static int create_drive(void* data) +{ + int c; + uint8_t buf[512]; + FILE* f = (FILE*)data; + memset(buf, 0, 512); + for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) + fwrite(buf, 512, 1, f); + + fclose(f); + + return 1; +} + +static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + int c; + PcemHDC hd[4]; + FILE *f; + uint8_t buf[512]; + int hd_type; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", 63); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", 16); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", 511); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)""); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", (((511*16*63)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + +// hd_type = 0; + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)hd_new_name); + if (!hd_new_name[0]) + { + wx_messagebox(hdlg,"Please enter a valid filename","PCem error",WX_MB_OK); + return TRUE; + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); + + if (hd_new_spt > 63) + { + wx_messagebox(hdlg, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) + { + wx_messagebox(hdlg, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > 16383) + { + wx_messagebox(hdlg, "Drive has too many cylinders (maximum is 16383)", "PCem error", WX_MB_OK); + return TRUE; + } + + f = fopen64(hd_new_name, "wb"); + if (!f) + { + wx_messagebox(hdlg, "Can't open file for write", "PCem error", WX_MB_OK); + return TRUE; + } + wx_progressdialogpulse(hdlg, "PCem", "Creating drive, please wait...", create_drive, f); + + wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", WX_MB_OK); + + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + return TRUE; + } else if (ID_IS("IDC_CFILE")) { + if (!getsfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "", NULL, "img")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) openfilestring); + } + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT1: %s\n", s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT2: %s\n", s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT3: %s\n", s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_type = 0; + for (c = 1; c <= 46; c++) + { + pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt,17, hd[0].hpc,hd_types[c-1].heads, hd[0].tracks,hd_types[c-1].cylinders); + if (hd[0].spt == 17 && hd[0].hpc == hd_types[c-1].heads && hd[0].tracks == hd_types[c-1].cylinders) + { + hd_type = c; + break; + } + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); + + return TRUE; + } else if (ID_IS("IDC_HDTYPE")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hd_type) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_types[hd_type-1].cylinders); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_types[hd_type-1].heads); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"17"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } + return TRUE; + } + break; + + } + return FALSE; +} + +static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + PcemHDC hd[2]; + int c; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); + for (c = 1; c <= 46; c++) + { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, hd_new_type, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", (int)((((uint64_t)hd_new_spt*(uint64_t)hd_new_hpc*(uint64_t)hd_new_cyl)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); + + if (hd_new_spt > 63) + { + wx_messagebox(hdlg,"Drive has too many sectors (maximum is 63)","PCem error",WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) + { + wx_messagebox(hdlg,"Drive has too many heads (maximum is 16)","PCem error",WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > 16383) + { + wx_messagebox(hdlg,"Drive has too many cylinders (maximum is 16383)","PCem error",WX_MB_OK); + return TRUE; + } + + wx_enddialog(hdlg,1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg,0); + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + + } + return FALSE; +} + +int hdconf_init(void* hdlg) +{ + char s[260]; + void* h; + PcemHDC hd[4]; + + hd[0] = hdc[0]; + hd[1] = hdc[1]; + hd[2] = hdc[2]; + hd[3] = hdc[3]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hdc[0].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hdc[0].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hdc[0].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[0]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hdc[1].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hdc[1].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hdc[1].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[1]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hdc[2].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hdc[2].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hdc[2].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[2]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hdc[3].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hdc[3].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hdc[3].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[3]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd[1].tracks*(uint64_t)hd[1].hpc)*(uint64_t)hd[1].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd[2].tracks*(uint64_t)hd[2].hpc)*(uint64_t)hd[2].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd[3].tracks*(uint64_t)hd[3].hpc)*(uint64_t)hd[3].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + return hdconf_update(hdlg); +} + +int hdconf_update(void* hdlg) +{ + char s[260]; + void* h; + + int is_mfm = hdd_controller_selected_is_mfm(hdlg); + + update_hdd_cdrom(hdlg); + + int i, j; + for (i = 0; i < 4; ++i) + { + sprintf(s, "IDC_HDD_LABEL[%d]", i*10); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_HDD[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_CDROM[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + if (i >= 2) + { + sprintf(s, "IDC_EDIT_FN[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_FILE[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_EJECT[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_NEW[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_EDIT_SPT[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_EDIT_HPC[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_EDIT_CYL[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_TEXT_SIZE[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + for (j = 1; j < 6; ++j) + { + sprintf(s, "IDC_HDD_LABEL[%d]", i*10+j); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + } + } + } + + return TRUE; +} + +int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[260]; + void* h; + PcemHDC hd[4]; + FILE *f; + off64_t sz; + switch (message) + { + case WX_INITDIALOG: + pause = 1; + return hdconf_init(hdlg); + + case WX_COMMAND: + if (ID_IS("IDC_EJECT[0]")) + { + hd[0].spt = 0; + hd[0].hpc = 0; + hd[0].tracks = 0; + ide_fn[0][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[0]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[0]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[1]")) + { + hd[1].spt = 0; + hd[1].hpc = 0; + hd[1].tracks = 0; + ide_fn[1][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[1]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[1]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[2]")) + { + hd[2].spt = 0; + hd[2].hpc = 0; + hd[2].tracks = 0; + ide_fn[2][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[2]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[2]"), ""); + hd_changed = 1; + return TRUE; + } else if (ID_IS("IDC_EJECT[3]")) + { + hd[3].spt = 0; + hd[3].hpc = 0; + hd[3].tracks = 0; + ide_fn[3][0] = 0; + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[3]"), "0"); + wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[3]"), ""); + hd_changed = 1; + return TRUE; + } + else if (ID_IS("IDC_NEW[0]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[0]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + + } + else if (ID_IS("IDC_NEW[1]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[1]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_NEW[2]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[2]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_NEW[3]")) + { + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; + } + else if (ID_IS("IDC_FILE[3]")) + { + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); + sprintf(s, "%imb", ((((hd[0].tracks*hd[0].hpc)*hd[0].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[1].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); + sprintf(s, "%imb", ((((hd[1].tracks*hd[1].hpc)*hd[1].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[2].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); + sprintf(s, "%imb", ((((hd[2].tracks*hd[2].hpc)*hd[2].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[3].tracks); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); + sprintf(s, "%imb", ((((hd[3].tracks*hd[3].hpc)*hd[3].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + else if (ID_IS("IDC_HDD[0]")) + { + if (new_cdrom_channel == 0) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[1]")) + { + if (new_cdrom_channel == 1) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[2]")) + { + if (new_cdrom_channel == 2) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_HDD[3]")) + { + if (new_cdrom_channel == 3) + new_cdrom_channel = -1; + update_hdd_cdrom(hdlg); + return TRUE; + + } + else if (ID_IS("IDC_CDROM[0]")) + { + new_cdrom_channel = 0; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[1]")) + { + new_cdrom_channel = 1; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[2]")) + { + new_cdrom_channel = 2; + update_hdd_cdrom(hdlg); + return TRUE; + } + else if (ID_IS("IDC_CDROM[3]")) + { + new_cdrom_channel = 3; + update_hdd_cdrom(hdlg); + return TRUE; + } + + } + return FALSE; +} + +int config_dialog_proc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + void* h; + switch (message) + { + case WX_INITDIALOG: + pause = 1; + return config_dlgproc(hdlg, message, wParam, lParam); + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + config_dlgsave(hdlg); + pause = 0; + wx_enddialog(hdlg, 1); + return TRUE; + } + else if (wParam == wxID_CANCEL) + { + pause = 0; + wx_enddialog(hdlg, 0); + return TRUE; + } + else if (wParam == WX_ID("IDC_NOTEBOOK")) + { + if (lParam == 3) + hdconf_update(hdlg); + } + break; + } + } + config_dlgproc(hdlg, message, wParam, lParam); + hdconf_dlgproc(hdlg, message, wParam, lParam); + return TRUE; +} + + +int config_open(void* hwnd) +{ + return wx_dialogbox(hwnd, "ConfigureDlg", config_dialog_proc); } diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index dda0fe7..6542dba 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -1,16 +1,35 @@ #include "ibm.h" #include "config.h" #include "wx-utils.h" -#include "wx-sdl2.h" #include "paths.h" -extern void config_open(void* hwnd); -extern void hdconf_open(void* hwnd); +extern int config_open(void* hwnd); + +static void select_config(void* hdlg, char* name) +{ + char s[512]; + int num, c, p; + void* h; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + + for (c = 0; c < num; c++) + { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)s); + if (!strcmp(s, name)) + { + wx_sendmessage(h, WX_LB_SETCURSEL, c, 0); + return; + } + } + +} static void config_list_update(void* hdlg) { char s[512]; - int num, c; + int num, c, p; void* h; strcpy(s, configs_path); @@ -18,9 +37,11 @@ static void config_list_update(void* hdlg) strcat(s, "*.cfg"); pclog("Dir %s\n", s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + p = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + wx_dlgdirlist(hdlg, s, WX_ID("IDC_LIST"), 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); for (c = 0; c < num; c++) @@ -38,11 +59,52 @@ static void config_list_update(void* hdlg) wx_sendmessage(h, WX_LB_DELETESTRING, c, 0); wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)s); } + + if (num > 0) + { + if (p >= num) + p = num-1; + else if (p < 0) + p = 0; + wx_sendmessage(h, WX_LB_SETCURSEL, p, 0); + } + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_RENAME")), num); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_DELETE")), num); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CONFIG")), num); + wx_enablewindow(wx_getdlgitem(hdlg, wxID_OK), num); +} + +static int run(void* hdlg) +{ + char s[512]; + + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) + { + char cfg[512]; + + strcpy(cfg, configs_path); + put_backslash(cfg); + strcat(cfg, s); + strcat(cfg, "cfg"); +// sprintf(cfg, "%s\\configs\\%scfg", config_path, s); + pclog("Config name %s\n", cfg); + + strcpy(config_file_default, cfg); + + wx_enddialog(hdlg, 1); +// pause = 0; + return TRUE; + } + return FALSE; } static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { //void* h; + int done = 0; switch (message) { @@ -58,31 +120,7 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L case WX_COMMAND: { if (wParam == wxID_OK) - { - char s[512]; - - int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); - - pclog("wx_dlgdirselectex returned %i %s\n", ret, s); - if (s[0]) - { - char cfg[512]; - - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); -// sprintf(cfg, "%s\\configs\\%scfg", config_path, s); - pclog("Config name %s\n", cfg); - - strcpy(config_file_default, cfg); - - wx_enddialog(hdlg, 1); -// pause = 0; - return TRUE; - } - return FALSE; - } + return run(hdlg); else if (wParam == wxID_CANCEL) { wx_enddialog(hdlg, 0); @@ -92,22 +130,37 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L else if (wParam == WX_ID("IDC_NEW")) { char name[64]; + name[0] = 0; -// if (!getsfile(hdlg, "Configuration (*.cfg)|*.cfg|All files (*.*)|*.*", "", s, "cfg")) - if (wx_textentrydialog(hdlg, "Enter name:", "New config", 0, 1, 64, (LONG_PARAM)name)) + while (!done) { - strcpy(openfilestring, configs_path); - put_backslash(openfilestring); - strcat(openfilestring, name); - strcat(openfilestring, ".cfg"); + if (wx_textentrydialog(hdlg, "Enter name:", "New config", name, 1, 64, (LONG_PARAM)name)) + { + char cfg[512]; - pclog("Config %s\n", openfilestring); + strcpy(cfg, configs_path); + put_backslash(cfg); + strcat(cfg, name); + strcat(cfg, ".cfg"); - config_open(hdlg); + pclog("Config %s\n", cfg); - saveconfig(openfilestring); + if (!wx_file_exists(cfg)) + { + if (config_open(hdlg)) + { + saveconfig(cfg); - config_list_update(hdlg); + config_list_update(hdlg); + select_config(hdlg, name); + } + done = 1; + } + else + wx_simple_messagebox("Already exists", "A configuration with that name already exists."); + } + else + done = 1; } return TRUE; @@ -136,30 +189,6 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L return TRUE; } - else if (wParam == WX_ID("IDC_HDCONF")) - { - char s[512]; - - int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); - - pclog("wx_dlgdirselectex returned %i %s\n", ret, s); - if (s[0]) - { - char cfg[512]; - - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); - pclog("Config name %s\n", cfg); - - loadconfig(cfg); - hdconf_open(hdlg); - saveconfig(cfg); - } - - return TRUE; - } else if (wParam == WX_ID("IDC_RENAME")) { char name[64]; @@ -172,27 +201,39 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L if (c >= 0) { wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); + strcpy(name, old_name); - if (wx_textentrydialog(hdlg, "Enter name:", "New name", old_name, 1, 64, (LONG_PARAM)name)) + while (!done) { - char old_path[512]; - char new_path[512]; + if (wx_textentrydialog(hdlg, "Enter name:", "New name", name, 1, 64, (LONG_PARAM)name)) + { + char old_path[512]; + char new_path[512]; - strcpy(old_path, configs_path); - put_backslash(old_path); - strcat(old_path, old_name); - strcat(old_path, ".cfg"); + strcpy(old_path, configs_path); + put_backslash(old_path); + strcat(old_path, old_name); + strcat(old_path, ".cfg"); - strcpy(new_path, configs_path); - put_backslash(new_path); - strcat(new_path, name); - strcat(new_path, ".cfg"); + strcpy(new_path, configs_path); + put_backslash(new_path); + strcat(new_path, name); + strcat(new_path, ".cfg"); - pclog("Rename %s to %s\n", old_path, new_path); + pclog("Rename %s to %s\n", old_path, new_path); - rename(old_path, new_path); + if (!wx_file_exists(new_path)) + { + rename(old_path, new_path); - config_list_update(hdlg); + config_list_update(hdlg); + done = 1; + } + else + wx_simple_messagebox("Already exists", "A configuration with that name already exists."); + } + else + done = 1; } } @@ -223,6 +264,11 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L } } } + else if (wParam == WX_ID("IDC_LIST")) + { + if (lParam == WX_LBN_DBLCLK) + run(hdlg); + } } break; } diff --git a/src/wx-deviceconfig.cc b/src/wx-deviceconfig.cc index 3a280ce..6bd913f 100644 --- a/src/wx-deviceconfig.cc +++ b/src/wx-deviceconfig.cc @@ -13,36 +13,41 @@ extern "C" { - #include "config.h" - void saveconfig(char*); - void resetpchard(); - int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam); - device_t *config_device; - int confirm(); +#include "config.h" +#include "plat-midi.h" +void saveconfig(char*); +void resetpchard(); +int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, + LONG_PARAM lParam); +device_t *config_device; +int confirm(); } #define IDC_CONFIG_BASE 1000 - -int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - switch (message) { - case WX_INITDIALOG: { +int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, + LONG_PARAM lParam) +{ + switch (message) + { + case WX_INITDIALOG: + { int id = IDC_CONFIG_BASE; device_config_t *config = config_device->config; int c; - while (config->type != -1) { + while (config->type != -1) + { device_config_selection_t *selection = config->selection; void* h = 0; int val_int; - char *val_string; int num; - char s[80]; + char s[100]; - switch (config->type) { + switch (config->type) + { case CONFIG_BINARY: h = wx_getdlgitem(hdlg, id); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, - config->default_int); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); wx_sendmessage(h, WX_BM_SETCHECK, val_int, 0); @@ -50,14 +55,13 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l break; case CONFIG_SELECTION: - h = wx_getdlgitem(hdlg, id+1); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, - config->default_int); + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); c = 0; - while (selection->description[0]) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, - (LONG_PARAM) selection->description); + while (selection->description[0]) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) selection->description); if (val_int == selection->value) wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); selection++; @@ -68,19 +72,21 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l break; case CONFIG_MIDI: - // midi ignored -// val_int = config_get_int(CFG_MACHINE, 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, (LONG_PARAM)s); -// if (val_int == c) -// SendMessage(h, CB_SETCURSEL, c, 0); -// } -// -// id += 2; + num = midi_get_num_devs(); + if (num > 0) + { + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); + + for (c = 0; c < num; c++) + { + midi_get_dev_name(c, s); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) s); + if (val_int == c) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + } + id += 2; + } break; } config++; @@ -89,24 +95,26 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l return TRUE; case WX_COMMAND: - switch (wParam) { - case wxID_OK: { + switch (wParam) + { + case wxID_OK: + { int id = IDC_CONFIG_BASE; device_config_t *config = config_device->config; int c; int changed = 0; - while (config->type != -1) { + while (config->type != -1) + { device_config_selection_t *selection = config->selection; void* h = 0; int val_int; - char *val_string; - switch (config->type) { + switch (config->type) + { case CONFIG_BINARY: h = wx_getdlgitem(hdlg, id); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, - config->default_int); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); if (val_int != wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)) changed = 1; @@ -115,9 +123,8 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l break; case CONFIG_SELECTION: - h = wx_getdlgitem(hdlg, id+1); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, - config->default_int); + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); @@ -131,27 +138,30 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l break; case CONFIG_MIDI: - // midi ignored -// val_int = config_get_int(CFG_MACHINE, NULL, config->name, -// config->default_int); -// -// c = SendMessage(h, CB_GETCURSEL, 0, 0); -// -// if (val_int != c) -// changed = 1; -// -// id += 2; + if (midi_get_num_devs() > 0) + { + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); + + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + if (val_int != c) + changed = 1; + id += 2; + } break; } config++; } - if (!changed) { + if (!changed) + { wx_enddialog(hdlg, 0); return TRUE; } - if (has_been_inited && !confirm()) { + if (has_been_inited && !confirm()) + { wx_enddialog(hdlg, 0); return TRUE; } @@ -159,38 +169,40 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l id = IDC_CONFIG_BASE; config = config_device->config; - while (config->type != -1) { + while (config->type != -1) + { device_config_selection_t *selection = config->selection; void* h = 0; int val_int; - char *val_string; - switch (config->type) { + switch (config->type) + { case CONFIG_BINARY: h = wx_getdlgitem(hdlg, id); - config_set_int(CFG_MACHINE, config_device->name, config->name, - wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)); + config_set_int(CFG_MACHINE, config_device->name, config->name, wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)); id++; break; case CONFIG_SELECTION: - h = wx_getdlgitem(hdlg, id+1); + h = wx_getdlgitem(hdlg, id + 1); c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_int(CFG_MACHINE, config_device->name, config->name, - selection->value); + config_set_int(CFG_MACHINE, config_device->name, config->name, selection->value); id += 2; break; case CONFIG_MIDI: - // midi ignored -// c = SendMessage(h, CB_GETCURSEL, 0, 0); -// config_set_int(CFG_MACHINE, NULL, config->name, c); -// -// id += 2; + if (midi_get_num_devs() > 0) + { + h = wx_getdlgitem(hdlg, id + 1); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + config_set_int(CFG_MACHINE, NULL, config->name, c); + + id += 2; + } break; } config++; @@ -214,55 +226,68 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l return FALSE; } +void deviceconfig_open(void* hwnd, device_t *device) +{ + char s[257]; + config_device = device; - -void deviceconfig_open(void* hwnd, device_t *device) { - config_device = device; - - PCemDialogBox dialog((wxWindow*) hwnd, deviceconfig_dlgproc); + PCemDialogBox dialog((wxWindow*) hwnd, deviceconfig_dlgproc); // dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - device_config_t *config = device->config; + device_config_t *config = device->config; - dialog.SetTitle("Device Configuration"); + dialog.SetTitle("Device Configuration"); - wxBoxSizer* root = new wxBoxSizer(wxVERTICAL); + wxFlexGridSizer* root = new wxFlexGridSizer(0, 1, 0, 0); + root->SetFlexibleDirection(wxBOTH); + root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); dialog.SetSizer(root); - wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); - root->Add(sizer, 0, wxALL, 5); + wxFlexGridSizer* sizer = new wxFlexGridSizer(0, 2, 0, 0); + sizer->SetFlexibleDirection(wxBOTH); + sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + sizer->AddGrowableCol(1); + root->Add(sizer, 1, wxEXPAND, 5); - int id = IDC_CONFIG_BASE; + int id = IDC_CONFIG_BASE; - while (config->type != -1) { - switch (config->type) { - case CONFIG_BINARY: - sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL); - break; + while (config->type != -1) + { + switch (config->type) + { + case CONFIG_BINARY: + sizer->Add(0, 0, 1, wxEXPAND, 5); + sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL, 5); + break; - case CONFIG_SELECTION: { - sizer->Add(new wxStaticText(&dialog, id++, config->description), 0, wxALL); - wxComboBox* cb = new wxComboBox(&dialog, id++); - cb->SetEditable(false); - sizer->Add(cb, 0, wxALL); - } break; - case CONFIG_MIDI: - // midi ignored - break; - } + case CONFIG_SELECTION: + case CONFIG_MIDI: + { + if (config->type == CONFIG_MIDI && midi_get_num_devs() == 0) + break; + sprintf(s, "%s:", config->description); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer* comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + break; + } + } - config++; - } + config++; + } - wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + root->Add(okCancelSizer, 1, wxEXPAND, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_OK)); - okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL)); + okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); - sizer->Add(okCancelSizer); - - dialog.Fit(); - dialog.OnInit(); - dialog.ShowModal(); - dialog.Destroy(); + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); } diff --git a/src/wx-dialogbox.cc b/src/wx-dialogbox.cc index 7b1fa7f..50d3c6b 100644 --- a/src/wx-dialogbox.cc +++ b/src/wx-dialogbox.cc @@ -1,5 +1,3 @@ -#include "wx-dialogbox.h" - #include #ifndef WX_PRECOMP @@ -7,19 +5,34 @@ #endif #include +#include + +#include "wx-dialogbox.h" +#include "wx-utils.h" BEGIN_EVENT_TABLE(PCemDialogBox, wxDialog) END_EVENT_TABLE() +class CommandValue: public wxObject +{ +public: + CommandValue(int value) { this->value = value; } + int GetValue() { return this->value; } +private: + int value; +}; + PCemDialogBox::PCemDialogBox(wxWindow* parent, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) : wxDialog(parent, -1, "No title") { this->callback = callback; + this->commandActive = false; } PCemDialogBox::PCemDialogBox(wxWindow* parent, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) { wxXmlResource::Get()->LoadDialog(this, parent, name); this->callback = callback; + this->commandActive = false; } void PCemDialogBox::OnInit() @@ -28,8 +41,11 @@ void PCemDialogBox::OnInit() { callback(this, WX_INITDIALOG, 0, 0); Bind(wxEVT_BUTTON, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_RADIOBUTTON, &PCemDialogBox::OnCommand, this); Bind(wxEVT_TEXT, &PCemDialogBox::OnCommand, this); Bind(wxEVT_COMBOBOX, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &PCemDialogBox::OnNotebookChanged, this); + Bind(wxEVT_LISTBOX_DCLICK, &PCemDialogBox::OnCommand, this, wxID_ANY, wxID_ANY, new CommandValue(WX_LBN_DBLCLK)); } wxWindow* root = FindWindow(XRCID("ROOT_PANEL")); @@ -38,8 +54,31 @@ void PCemDialogBox::OnInit() Fit(); } -void PCemDialogBox::OnCommand(wxCommandEvent& event) +int PCemDialogBox::processEvent(int message, INT_PARAM param1, LONG_PARAM param2) { - callback(this, WX_COMMAND, event.GetId(), 0); + int result = 0; + /* lock the current command to prevent strange behavior */ + if (!commandActive) + { + commandActive = true; + result = callback(this, message, param1, param2); + commandActive = false; + } + return result; +} + +void PCemDialogBox::OnNotebookChanged(wxCommandEvent& event) +{ + wxBookCtrlEvent* ev = (wxBookCtrlEvent*)&event; + processEvent(WX_COMMAND, ev->GetId(), ev->GetSelection()); +} + +void PCemDialogBox::OnCommand(wxCommandEvent& event) +{ + LONG_PARAM val = 0; + CommandValue* c = (CommandValue*)event.GetEventUserData(); + if (c) + val = c->GetValue(); + processEvent(WX_COMMAND, event.GetId(), val); } diff --git a/src/wx-dialogbox.h b/src/wx-dialogbox.h index ca3ee4d..af8ed2d 100644 --- a/src/wx-dialogbox.h +++ b/src/wx-dialogbox.h @@ -12,8 +12,11 @@ public: virtual ~PCemDialogBox() {} void OnInit(); private: - void OnCommand(wxCommandEvent &event); + void OnNotebookChanged(wxCommandEvent& event); + void OnCommand(wxCommandEvent& event); + int processEvent(int message, INT_PARAM param1, LONG_PARAM param2); int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2); + bool commandActive; DECLARE_EVENT_TABLE() }; diff --git a/src/wx-display.h b/src/wx-display.h index 4753579..2c98c75 100644 --- a/src/wx-display.h +++ b/src/wx-display.h @@ -25,6 +25,7 @@ extern int video_fullscreen_mode; extern int win_doresize; extern int window_doreset; +extern int window_dosetresize; extern int renderer_doreset; extern int window_dofullscreen; extern int window_dowindowed; diff --git a/src/wx-glsl.h b/src/wx-glsl.h new file mode 100644 index 0000000..ac371f3 --- /dev/null +++ b/src/wx-glsl.h @@ -0,0 +1,155 @@ +#ifndef SRC_WX_GLSL_H_ +#define SRC_WX_GLSL_H_ + +#define MAX_PREV 7 + +#define MAX_SHADERS 20 +#define MAX_TEXTURES 20 +#define MAX_PARAMETERS 100 + +#define MAX_USER_SHADERS 20 +//#define SDL2_SHADER_DEBUG + +struct shader_scale { + int mode[2]; + float value[2]; +}; + +struct shader_state { + float input_size[2]; + float input_texture_size[2]; + float output_texture_size[2]; + float output_size[2]; + float tex_coords[8]; +}; + +struct shader_vbo { + int vertex_coord; + int tex_coord; + int color; +}; + +struct shader_texture { + int id; + int width; + int height; + int type; + int internal_format; + int format; + int min_filter; + int mag_filter; + int wrap_mode; + void* data; + int mipmap; +}; + +struct shader_lut_texture { + char name[50]; + struct shader_texture texture; +}; + +struct shader_fbo { + int id; + struct shader_texture texture; + int srgb; +}; + +struct shader_prev { + struct shader_fbo fbo; + struct shader_vbo vbo; +}; + +struct shader_input { + int texture; + int input_size; + int texture_size; + int tex_coord; +}; + +struct shader_uniforms { + int mvp_matrix; + int vertex_coord; + int tex_coord; + int color; + + int texture; + int input_size; + int texture_size; + int output_size; + + int frame_count; + int frame_direction; + + struct shader_input orig; + struct shader_input pass[MAX_SHADERS]; + struct shader_input prev_pass[MAX_SHADERS]; + struct shader_input prev[MAX_PREV]; + + int parameters[MAX_PARAMETERS]; + int lut_textures[MAX_TEXTURES]; +}; + +struct shader_program { + int vertex_shader; + int fragment_shader; + int id; +}; + +struct shader_parameter { + char id[64]; + char description[64]; + float default_value; + float value; + float min; + float max; + float step; +}; + +struct shader_pass { + int active; + char alias[64]; + int vertex_array; + int frame_count_mod; + struct shader_program program; + struct shader_uniforms uniforms; + struct shader_fbo fbo; + struct shader_vbo vbo; + struct shader_state state; + struct shader_scale scale; +}; + +struct glsl_shader { + int active; + char name[64]; + + int num_passes; + struct shader_pass passes[MAX_SHADERS]; + + int num_lut_textures; + struct shader_lut_texture lut_textures[MAX_TEXTURES]; + + int num_parameters; + struct shader_parameter parameters[MAX_PARAMETERS]; + + struct shader_pass prev_scene; + struct shader_prev prev[MAX_PREV+1]; + + int last_prev_update; + int has_prev; + + float shader_refresh_rate; +}; + +typedef struct glsl_t { + int num_shaders; + struct glsl_shader shaders[MAX_USER_SHADERS]; + struct shader_pass scene; + struct shader_pass final_pass; + struct shader_pass fs_color; +#ifdef SDL2_SHADER_DEBUG + struct shader_pass debug; +#endif + int srgb; +} glsl_t; + +#endif diff --git a/src/wx-glslp-parser.c b/src/wx-glslp-parser.c new file mode 100644 index 0000000..02aa822 --- /dev/null +++ b/src/wx-glslp-parser.c @@ -0,0 +1,328 @@ +#include "wx-glslp-parser.h" + +#include +#include +#include +#include +#include "wx-utils.h" + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +extern char* get_filename(char*); +extern void pclog(const char *format, ...); + +static int endswith(const char* str, const char* ext) +{ + int i; + const char* p; + int elen = strlen(ext); + int slen = strlen(str); + if (slen >= elen) + { + p = &str[slen-elen]; + for (i = 0; i < elen; ++i) + { + if (tolower(p[i]) != tolower(ext[i])) + return 0; + } + return 1; + } + return 0; +} + +static char* load_file(const char* fn) +{ + FILE* f = fopen(fn, "rb"); + if (!f) + return 0; + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char* data = malloc(fsize+1); + + long read = fread(data, fsize, 1, f); + fclose(f); + + data[fsize] = 0; + + return data; +} + +static void strip_lines(const char* program, const char* starts_with) +{ + /* strip parameters */ + char* ptr = strstr(program, starts_with); + while (ptr) + { + while (*ptr != '\n' && *ptr != '\0') + *ptr++ = ' '; + ptr = strstr(program, starts_with); + } +} + +static void strip_parameters(const char* program) +{ + /* strip parameters */ + strip_lines(program, "#pragma parameter"); +} + +static void strip_defines(const char* program) +{ + /* strip texture define */ + strip_lines(program, "#define texture"); +} + +static int has_parameter(glslp_t* glsl, char* id) +{ + int i; + for (i = 0; i < glsl->num_parameters; ++i) + if (!strcmp(glsl->parameters[i].id, id)) + return 1; + return 0; +} + +static int get_parameters(glslp_t* glsl) +{ + int i; + struct parameter p; + for (i = 0; i < glsl->num_shaders; ++i) + { + struct shader* shader = &glsl->shaders[i]; + FILE* f = fopen(shader->shader_fn, "rb"); + if (!f) + return 0; + + char line[1024]; + while (fgets(line, sizeof(line)-1, f) && glsl->num_parameters < MAX_PARAMETERS) + { + int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, &p.default_value, &p.min, &p.max, &p.step); + if (num < 5) + continue; + p.id[63] = 0; + p.description[63] = 0; + + if (num == 5) + p.step = 0.1f * (p.max-p.min); + + p.value = p.default_value; + + if (!has_parameter(glsl, p.id)) + { + memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); + pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, p.max, p.step); + } + } + + fclose(f); + } + + return 1; +} + +static struct parameter* get_parameter(glslp_t* glslp, const char* id) +{ + int i; + for (i = 0; i < glslp->num_parameters; ++i) + { + if (!strcmp(glslp->parameters[i].id, id)) { + return &glslp->parameters[i]; + } + } + return 0; +} + +static glslp_t* glsl_parse(const char* f) +{ + glslp_t* glslp = malloc(sizeof(glslp_t)); + memset(glslp, 0, sizeof(glslp_t)); + glslp->num_shaders = 1; + struct shader* shader = &glslp->shaders[0]; + strcpy(shader->shader_fn, f); + shader->shader_program = load_file(f); + if (!shader->shader_program) + { + wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); + shader->scale_x = shader->scale_y = 1.0f; + strcpy(shader->scale_type_x, "source"); + strcpy(shader->scale_type_y, "source"); + get_parameters(glslp); + return glslp; +} + +void get_glslp_name(const char* f, char* s, int size) +{ + safe_strncpy(s, get_filename((char*)f), size); +} + +glslp_t* glslp_parse(const char* f) +{ + int i, j, len, sublen; + char s[512], t[512], z[512]; + + s[511] = 0; + if (endswith(f, ".glsl")) + return glsl_parse(f); + + void* cfg = wx_config_load(f); + + if (!cfg) + { + wx_simple_messagebox("GLSLP error", "Could not load GLSLP-file %s\n", f); + return 0; + } + + glslp_t* glslp = malloc(sizeof(glslp_t)); + memset(glslp, 0, sizeof(glslp_t)); + + get_glslp_name(f, glslp->name, sizeof(glslp->name)); + + wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); + + for (i = 0; i < glslp->num_shaders; ++i) + { + struct shader* shader = &glslp->shaders[i]; + + + snprintf(s, sizeof(s)-1, "shader%d", i); + if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) + { + /* shader doesn't exist, lets break here */ + glslp->num_shaders = i; + break; + } + strcpy(s, f); + *get_filename(s) = 0; + snprintf(shader->shader_fn, sizeof(shader->shader_fn)-1, "%s%s", s, t); + shader->shader_program = load_file(shader->shader_fn); + if (!shader->shader_program) + { + wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); + + snprintf(s, sizeof(s)-1, "alias%d", i); + wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); + + snprintf(s, sizeof(s)-1, "filter_linear%d", i); + wx_config_get_bool(cfg, s, &shader->filter_linear, 0); + + snprintf(s, sizeof(s)-1, "wrap_mode%d", i); + wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); + + snprintf(s, sizeof(s)-1, "float_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); + snprintf(s, sizeof(s)-1, "srgb_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); + + snprintf(s, sizeof(s)-1, "mipmap_input%d", i); + wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); + + strcpy(shader->scale_type_x, "source"); + snprintf(s, sizeof(s)-1, "scale_type_x%d", i); + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + strcpy(shader->scale_type_y, "source"); + snprintf(s, sizeof(s)-1, "scale_type_y%d", i); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + snprintf(s, sizeof(s)-1, "scale_type%d", i); + if (wx_config_has_entry(cfg, s)) + { + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + } + + snprintf(s, sizeof(s)-1, "scale_x%d", i); + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + snprintf(s, sizeof(s)-1, "scale_y%d", i); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + snprintf(s, sizeof(s)-1, "scale%d", i); + if (wx_config_has_entry(cfg, s)) + { + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + } + + snprintf(s, sizeof(s)-1, "frame_count_mod%d", i); + wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); + } + + /* textures */ + glslp->num_textures = 0; + wx_config_get_string(cfg, "textures", t, sizeof(t), 0); + + len = strlen(t); + j = 0; + sublen = 0; + for (i = 0; i < len; ++i) + { + if (t[i] == ';' || i == len-1) + { + sublen = (i-j) + ((i == len-1) ? 1 : 0) + 1; + safe_strncpy(s, t+j, sublen); + s[511 < sublen ? 511 : sublen] = 0; + + struct texture* tex = &glslp->textures[glslp->num_textures++]; + + strcpy(tex->name, s); + wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); + + snprintf(z, sizeof(z)-1, "%s_linear", s); + wx_config_get_bool(cfg, z, &tex->linear, 0); + + snprintf(z, sizeof(z)-1, "%s_mipmap", s); + wx_config_get_bool(cfg, z, &tex->mipmap, 0); + + snprintf(z, sizeof(z)-1, "%s_wrap_mode", s); + wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); + + j = i+1; + } + } + + /* parameters */ + get_parameters(glslp); + + wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); + + len = strlen(t); + j = 0; + sublen = 0; + for (i = 0; i < len; ++i) + { + if (t[i] == ';' || i == len-1) + { + sublen = (i-j) + ((i == len-1) ? 1 : 0) + 1; + safe_strncpy(s, t+j, sublen); + s[511 < sublen ? 511 : sublen] = 0; + + struct parameter* p = get_parameter(glslp, s); + + if (p) + wx_config_get_float(cfg, s, &p->default_value, 0); + + j = i+1; + } + } + + wx_config_free(cfg); + + + return glslp; +} + +void glslp_free(glslp_t* p) +{ + int i; + for (i = 0; i < p->num_shaders; ++i) + if (p->shaders[i].shader_program) + free(p->shaders[i].shader_program); + free(p); +} diff --git a/src/wx-glslp-parser.h b/src/wx-glslp-parser.h new file mode 100644 index 0000000..94862d7 --- /dev/null +++ b/src/wx-glslp-parser.h @@ -0,0 +1,54 @@ +#ifndef SRC_WX_GLSLP_PARSER_H_ +#define SRC_WX_GLSLP_PARSER_H_ + +#include "wx-glsl.h" + +struct parameter { + char id[64]; + char description[64]; + float default_value; + float value; + float min; + float max; + float step; +}; + +struct texture { + char path[256]; + char name[50]; + int linear; + int mipmap; + char wrap_mode[50]; +}; + +struct shader { + char shader_fn[512]; + char* shader_program; + char alias[64]; + int filter_linear; + int float_framebuffer; + int srgb_framebuffer; + int mipmap_input; + int frame_count_mod; + char wrap_mode[50]; + char scale_type_x[9], scale_type_y[9]; + float scale_x, scale_y; +}; + +typedef struct glslp_t { + char name[64]; + int num_shaders; + struct shader shaders[MAX_SHADERS]; + + int num_textures; + struct texture textures[MAX_TEXTURES]; + + int num_parameters; + struct parameter parameters[MAX_PARAMETERS]; +} glslp_t; + +void get_glslp_name(const char* f, char* s, int size); +glslp_t* glslp_parse(const char* f); +void glslp_free(glslp_t* p); + +#endif /* SRC_WX_GLSLP_PARSER_H_ */ diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index c48e954..ec14ae4 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -21,93 +21,112 @@ wxMemoryFSHandler::AddFile(name, data, size) #endif -static size_t xml_res_size_0 = 346; +static size_t xml_res_size_0 = 430; static unsigned char xml_res_file_0[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,4,0,0, -0,181,250,55,234,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, -116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, -97,103,101,82,101,97,100,121,113,201,101,60,0,0,0,236,73,68,65,84,40,207, -165,145,61,74,4,65,16,133,191,94,123,214,192,31,132,197,64,23,4,51,111, -177,48,147,120,11,79,224,9,4,207,227,13,156,100,135,185,129,193,70,3,155, -8,6,130,152,8,130,83,221,213,101,208,189,131,145,201,86,80,73,189,247,190, -162,202,25,255,215,140,125,5,30,96,88,107,173,68,2,129,128,32,8,35,210, -221,53,224,140,97,53,239,207,145,201,147,183,170,232,121,109,238,59,15, -241,241,140,119,14,1,43,67,227,141,83,174,25,30,232,220,102,53,239,23,124, -149,224,136,225,56,160,226,132,35,90,182,141,123,89,95,212,134,96,37,220, -166,94,241,201,83,231,133,111,62,24,49,18,74,194,72,36,20,195,115,140,224, -165,6,65,217,224,152,21,175,145,184,66,89,34,181,31,137,68,20,197,145,10, -102,151,17,8,248,17,69,73,220,144,72,216,31,140,145,178,96,129,78,193,217, -191,3,93,18,241,63,237,243,173,48,230,219,33,72,185,103,198,90,235,246, -254,230,47,16,30,136,4,54,25,76,145,0,0,0,0,73,69,78,68,174,66,96,130}; +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,1,80,73,68,65,84,120,218,196,147,177,75,195,64,20,198,191,75,2,77,82, +2,66,58,171,32,130,171,130,179,10,34,138,173,155,131,56,248,143,137,184, +9,145,186,168,40,34,104,103,65,119,233,160,117,236,210,160,29,210,187,228, +204,119,70,135,170,181,218,193,7,71,238,184,239,247,229,221,189,123,66, +107,141,81,194,194,136,225,236,238,237,35,77,51,88,150,224,90,151,74,165, +129,64,146,36,252,136,44,211,176,109,11,14,87,89,150,209,68,215,170,235, +120,120,108,13,52,152,156,24,199,241,201,169,22,194,18,52,176,8,247,164, +212,27,181,106,14,63,209,28,66,124,61,184,71,13,181,100,200,58,105,154, +70,59,219,91,144,74,97,102,122,106,184,131,231,102,100,14,162,195,200,81, +74,109,198,207,47,56,59,191,40,118,127,170,138,185,43,172,173,174,128,44, +51,64,210,75,224,249,30,150,151,22,115,94,23,26,209,7,234,55,239,252,239, +151,87,215,134,33,107,12,100,79,194,247,92,40,41,113,115,123,247,113,222, +126,3,190,153,249,185,89,163,37,99,12,148,74,205,196,117,61,116,226,24, +149,74,88,24,124,14,26,80,67,45,25,178,38,3,222,102,185,236,227,190,217, +252,22,126,143,118,187,141,48,12,139,210,231,6,156,216,142,131,32,8,204, +24,54,200,152,50,118,187,221,70,189,126,180,240,219,158,96,166,249,171, +108,48,95,22,127,236,143,173,208,17,255,222,141,175,2,12,0,1,60,177,155, +95,179,104,212,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_1 = 620; +static size_t xml_res_size_1 = 730; static unsigned char xml_res_file_1[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, -116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, -97,103,101,82,101,97,100,121,113,201,101,60,0,0,1,254,73,68,65,84,24,25, -5,193,61,139,93,85,24,6,208,181,207,236,59,67,130,146,168,96,132,68,68, -3,10,86,1,101,32,241,163,21,127,130,133,104,145,42,66,208,34,165,54,86, -86,34,162,8,99,161,216,10,118,130,98,97,149,34,22,22,193,78,197,66,180, -18,197,12,222,153,123,246,126,31,215,106,135,111,124,247,22,30,195,243, -120,2,247,145,142,38,192,222,210,44,75,147,148,42,255,236,111,252,188,61, -93,223,187,243,241,203,95,118,60,125,116,235,218,117,154,167,46,30,8,82, -177,27,177,91,203,222,210,156,57,88,180,198,241,182,28,159,204,115,191, -254,121,124,229,243,111,126,249,228,240,198,215,231,22,188,32,124,117,231, -95,21,146,184,249,225,15,170,66,107,54,189,89,150,102,55,98,187,150,81, -218,180,244,215,94,186,252,208,153,131,253,143,22,60,18,84,197,58,202,58, -2,214,138,190,199,166,55,85,177,221,149,117,132,196,247,119,239,217,223, -236,217,158,142,253,142,179,163,130,216,238,10,44,173,17,54,125,209,52, -39,107,217,158,70,37,42,84,226,143,191,78,72,90,39,125,38,18,78,71,192, -219,175,95,177,233,139,190,176,206,248,239,180,140,42,85,68,164,202,58, -166,164,116,180,154,72,188,251,217,143,90,107,150,198,166,47,26,70,197, -24,37,0,56,127,254,65,235,216,35,209,133,74,169,154,30,190,112,145,70,19, -2,81,161,170,36,81,137,170,162,53,235,58,72,233,48,39,9,208,18,160,81,69, -18,68,130,68,75,36,101,93,155,164,116,24,179,16,16,209,52,18,73,164,74, -68,18,85,83,42,162,156,174,33,165,19,179,66,120,231,149,75,0,0,0,0,224, -214,209,79,198,136,164,244,165,53,179,136,72,248,224,246,117,0,0,0,112, -243,234,145,57,135,221,8,137,174,81,21,13,112,237,210,171,0,0,0,0,106,150, -185,6,165,39,201,172,52,2,110,255,254,5,0,0,0,120,246,209,23,205,57,173, -51,146,164,87,252,182,27,245,248,51,151,207,106,141,55,159,251,20,0,0,0, -192,133,251,203,156,129,191,219,225,141,111,223,79,242,36,185,42,121,128, -146,132,148,164,72,73,138,20,137,36,72,200,61,109,185,251,63,33,124,110, -139,109,16,176,162,0,0,0,0,73,69,78,68,174,66,96,130}; +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,124,73,68,65,84,120,218,140,83,77,72,85,65,24,61,115,239,220,247, +158,247,169,207,22,146,253,27,214,162,218,219,198,22,45,42,105,23,180,9, +139,8,162,104,227,182,34,37,242,137,216,162,149,127,139,22,134,36,182,80, +116,19,22,190,130,16,194,140,22,45,130,90,244,71,100,17,6,37,153,250,222, +157,59,157,111,238,141,90,132,116,185,115,103,238,204,57,223,249,190,51, +51,170,161,107,186,35,178,40,86,76,140,40,6,248,174,251,120,108,154,159, +192,247,160,21,58,81,127,109,218,62,91,180,118,246,83,100,255,247,17,172, +112,132,171,141,181,208,212,61,48,252,6,246,242,110,188,90,88,162,134,130, +229,215,198,49,136,135,231,121,238,159,19,216,179,181,206,97,159,159,107, +130,112,37,35,44,27,5,204,12,185,20,71,250,123,49,50,208,139,249,210,20, +158,148,38,81,21,102,113,171,175,7,79,31,76,113,110,50,169,99,102,48,225, +72,57,138,253,207,114,12,221,184,23,101,250,208,222,209,77,85,133,56,54, +46,19,202,162,253,74,55,98,167,102,177,90,49,14,43,28,225,122,138,185,253, +88,139,208,176,255,16,137,49,250,138,29,152,25,191,141,128,14,245,247,116, +226,225,228,29,148,38,70,145,241,225,230,173,53,196,30,118,28,225,106,73, +99,133,246,231,57,202,178,93,42,22,221,110,72,237,23,187,138,46,77,81,151, +224,199,78,158,66,46,0,242,126,194,113,37,72,150,107,252,41,4,10,247,222, +174,160,117,103,72,75,173,51,45,177,242,207,6,138,97,130,41,100,148,227, +8,87,75,149,101,30,132,2,229,175,207,125,199,213,217,111,88,51,169,106, +74,21,140,199,130,179,84,14,41,36,88,225,40,164,37,208,15,84,51,106,217, +120,56,219,164,208,214,188,233,47,101,155,54,133,209,249,207,24,251,96, +145,241,148,227,36,187,144,6,168,146,227,69,96,91,115,61,94,190,255,10, +95,7,78,186,82,137,16,27,227,220,150,181,137,143,139,196,38,1,84,122,50, +81,161,65,57,166,150,97,62,17,243,223,178,113,3,134,111,14,226,252,233, +19,216,198,113,192,5,173,53,162,85,67,140,114,88,225,224,119,9,177,245, +144,15,52,245,121,31,140,69,77,232,97,238,241,44,142,180,30,69,77,78,8, +190,108,139,91,11,57,206,7,158,227,184,0,98,142,246,125,212,133,1,116,133, +7,202,75,22,178,188,44,97,214,197,103,159,113,59,226,115,77,112,213,12, +32,28,199,141,190,188,27,186,113,23,23,162,216,98,169,108,112,166,118,23, +86,120,18,183,239,104,60,222,62,246,8,45,45,7,199,151,233,131,4,168,37, +113,224,254,107,212,242,84,81,25,194,21,31,196,242,205,255,184,185,47,210, +126,223,58,183,123,225,151,0,3,0,201,66,64,174,55,176,170,129,0,0,0,0,73, +69,78,68,174,66,96,130}; -static size_t xml_res_size_2 = 673; +static size_t xml_res_size_2 = 835; static unsigned char xml_res_file_2[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,4,103,65,77,65,0,0,175,200,55,5,138,233,0,0,0,25, -116,69,88,116,83,111,102,116,119,97,114,101,0,65,100,111,98,101,32,73,109, -97,103,101,82,101,97,100,121,113,201,101,60,0,0,2,51,73,68,65,84,56,203, -133,147,91,110,218,80,16,134,179,129,172,160,27,137,212,141,116,71,221, -0,50,74,251,210,42,137,4,129,230,129,72,17,133,92,154,128,66,67,49,96,32, -52,220,66,76,205,197,177,9,190,128,1,131,253,119,142,129,134,164,84,69, -250,176,229,153,249,207,156,185,108,1,216,90,231,221,251,232,91,194,71, -100,9,133,24,16,21,194,207,108,175,253,215,3,183,9,142,176,191,242,34,74, -45,29,77,117,138,182,57,131,212,31,34,158,109,129,217,150,62,219,47,4,150, -193,209,131,139,10,230,142,11,73,7,142,210,6,190,20,12,124,239,79,49,38, -39,135,96,54,230,195,124,87,34,43,1,142,25,52,27,222,207,36,239,189,75, -13,159,174,159,32,104,14,92,250,70,15,232,206,194,190,20,225,60,1,122,217, -33,28,177,111,99,47,165,162,170,46,156,78,248,49,252,103,42,234,67,120, -25,244,232,207,164,231,148,225,186,76,192,97,177,222,233,49,186,223,73, -65,199,199,75,5,187,23,10,138,18,80,235,1,169,170,73,215,153,160,63,1,100, -18,208,41,149,193,28,48,136,216,162,38,28,19,200,11,162,134,207,201,71, -18,144,225,255,38,35,146,213,113,152,168,51,135,46,35,156,108,192,164,160, -54,101,83,125,2,132,246,28,130,168,51,123,158,9,168,183,210,136,78,150, -177,75,193,31,72,228,166,97,50,99,135,120,179,164,83,233,77,16,161,162, -134,50,154,71,81,178,152,143,250,71,192,127,46,131,59,237,193,119,218,69, -250,254,111,129,226,47,11,33,94,199,254,205,128,232,163,176,38,144,207, -63,12,192,157,119,189,224,32,169,87,85,23,44,237,213,21,14,19,13,36,27, -44,131,33,142,75,22,162,229,17,114,205,231,43,120,69,188,190,31,67,144, -129,150,5,52,12,66,3,42,143,19,148,58,19,164,154,51,132,114,35,236,211, -108,4,50,38,18,36,182,94,68,175,141,54,181,70,166,30,221,13,0,190,11,92, -137,64,188,62,199,241,237,20,225,188,133,0,111,225,224,135,137,32,111,146, -176,253,220,198,245,65,82,168,93,130,2,36,40,56,86,115,17,41,207,16,22, -198,8,102,23,193,1,222,64,90,180,95,14,210,235,81,150,12,23,57,202,32,94, -155,35,82,92,156,126,36,208,46,220,89,248,41,219,155,71,121,211,50,101, -31,116,148,187,83,175,6,25,42,8,251,246,207,101,250,207,58,43,203,119,223, -166,117,254,13,152,46,30,143,29,240,166,162,0,0,0,0,73,69,78,68,174,66, -96,130}; +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,229,73,68,65,84,120,218,100,83,75,76,19,81,20,61,211,118,166,157, +150,22,176,5,1,229,35,82,36,4,99,162,6,18,34,113,39,46,80,227,70,73,220, +201,202,128,184,209,24,119,46,220,104,76,36,4,226,74,55,224,130,141,66, +130,49,16,73,52,98,68,148,40,66,212,128,168,20,249,10,165,244,199,48,191, +231,157,153,242,81,95,114,38,147,247,238,57,247,220,251,238,227,240,207, +106,125,250,185,93,211,217,69,198,224,98,169,61,14,144,236,54,238,225,149, +186,242,198,157,177,140,130,184,45,98,239,248,9,69,99,125,135,131,57,40, +47,244,35,224,230,16,213,128,12,59,16,223,96,24,15,173,96,240,203,2,156, +54,174,182,249,84,69,255,95,2,173,189,99,23,108,28,215,121,186,186,20,170, +192,99,62,1,232,58,224,225,1,55,161,212,107,186,192,106,82,197,163,23,19, +6,177,182,185,174,162,223,16,176,25,2,138,162,117,214,86,29,192,188,198, +99,54,14,184,104,55,91,36,184,128,28,151,69,150,146,26,212,152,142,186, +35,251,33,171,106,223,166,115,71,75,207,135,246,242,226,92,36,236,14,56, +40,107,186,19,200,243,0,94,199,118,173,242,134,142,233,80,18,203,97,25, +254,128,136,163,193,92,220,35,30,29,53,58,84,85,107,40,200,11,128,217,45, +187,89,148,89,36,7,207,70,102,176,16,78,162,40,224,67,85,73,54,92,110,59, +50,152,0,191,223,129,116,33,11,195,95,102,26,76,1,6,221,233,243,216,192, +147,79,183,205,34,15,140,45,226,253,143,136,28,93,158,123,242,43,154,119, +86,222,224,132,218,170,221,88,161,174,166,251,28,224,204,206,233,78,227, +107,211,53,134,108,250,13,8,36,144,178,253,157,172,38,86,23,30,220,189, +116,242,154,28,11,63,94,210,233,58,136,101,144,169,74,208,165,192,43,58, +173,30,48,166,195,158,170,53,186,166,192,151,230,192,62,143,7,82,240,96, +195,253,87,139,170,162,234,245,133,89,110,243,156,46,1,235,4,141,8,177, +68,194,18,224,160,203,73,73,21,164,4,195,236,92,18,62,47,143,234,50,47, +124,75,138,48,17,81,47,23,237,226,113,172,72,52,201,225,13,202,78,22,98, +113,29,6,207,20,136,173,46,117,191,30,157,61,151,197,103,66,82,85,240,162, +29,54,193,142,202,98,30,149,155,206,40,116,126,157,178,235,150,253,159, +211,11,136,134,127,119,167,166,20,5,119,186,6,167,143,151,150,33,63,207, +139,52,114,32,186,104,10,21,32,161,88,150,105,4,204,204,18,145,215,226, +10,38,135,223,226,106,125,77,33,13,82,200,24,164,208,167,55,207,155,6,167, +190,66,16,25,53,135,51,27,181,66,118,35,138,133,53,213,194,50,89,153,26, +121,135,209,161,129,38,131,103,150,96,124,58,91,110,118,128,212,101,89, +105,171,57,84,130,189,249,123,16,103,156,105,217,64,52,201,16,153,159,197, +106,232,27,62,14,189,108,234,48,226,183,31,218,214,242,17,130,55,218,186, +174,251,50,3,103,232,64,112,137,46,200,146,100,4,201,107,225,229,158,91, +77,231,111,83,204,164,209,150,255,94,227,142,85,64,240,27,51,178,99,207, +172,106,211,246,206,231,252,71,128,1,0,112,7,72,225,52,89,175,48,0,0,0, +0,73,69,78,68,174,66,96,130}; static size_t xml_res_size_3 = 758; static unsigned char xml_res_file_3[] = { @@ -274,8 +293,1162 @@ static unsigned char xml_res_file_6[] = { 37,149,61,177,48,254,5,68,165,141,10,108,236,250,76,0,0,0,0,73,69,78,68, 174,66,96,130}; -static size_t xml_res_size_7 = 60429; +static size_t xml_res_size_7 = 1852; static unsigned char xml_res_file_7[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,6,222,73,68,65,84,120,218,188,87,107,136,85,85,20,254,246,62,231, +222,59,247,206,181,113,108,212,73,51,51,130,140,32,170,31,61,200,136,222, +132,40,169,101,69,66,101,15,122,64,74,15,169,8,42,168,176,172,44,168,164, +232,97,86,72,143,49,205,158,248,39,66,255,20,84,100,165,65,145,164,53,154, +81,206,204,109,230,156,123,206,61,167,111,173,125,212,123,207,204,144,70, +117,240,56,107,159,253,250,246,183,190,181,246,186,6,128,191,230,206,147, +214,90,196,51,145,166,108,202,251,95,62,134,255,12,18,248,239,205,93,250, +249,69,62,191,148,109,26,205,60,241,178,165,72,147,6,251,140,27,164,111, +54,126,132,101,82,252,19,172,169,78,49,198,226,139,215,239,154,41,123,11, +128,54,68,53,212,251,127,193,150,13,43,0,235,195,216,34,71,121,186,179, +103,129,130,117,211,19,206,182,25,154,40,113,109,89,49,109,61,223,190,246, +48,155,12,39,60,228,177,231,222,200,70,34,159,219,4,128,233,190,226,93, +108,217,253,43,112,198,114,76,232,158,130,223,215,95,201,157,139,4,98,80, +34,142,37,235,138,194,26,158,152,23,98,113,79,73,61,245,232,156,58,23,115, +27,196,13,89,60,129,37,177,150,136,19,93,155,182,109,181,27,137,65,20,69, +14,150,50,205,45,228,255,193,218,239,216,246,195,86,108,251,126,43,134, +6,251,224,179,211,231,66,190,245,200,128,65,165,189,202,183,29,150,243, +42,149,118,181,125,206,191,253,157,118,125,11,30,199,179,115,207,113,247, +226,214,55,13,121,77,208,151,183,223,178,40,249,92,211,227,137,210,198, +62,198,132,1,196,245,24,29,29,157,180,44,162,48,230,32,46,88,112,92,199, +113,130,123,207,236,229,73,98,244,15,0,247,204,24,212,239,181,26,176,244, +252,65,158,216,67,163,81,128,103,82,68,65,13,69,63,165,203,82,196,121,219, +75,245,48,150,135,75,243,0,18,175,132,142,113,19,148,144,196,248,40,149, +124,44,90,227,57,170,103,199,56,235,206,183,57,42,24,69,88,109,248,232, +161,121,40,148,44,194,48,32,213,6,30,65,141,102,147,84,100,126,217,15,96, +251,170,153,152,126,246,117,216,241,213,251,24,162,239,15,153,212,133,246, +234,24,245,43,82,30,21,60,58,23,129,231,187,87,158,70,236,222,98,164,227, +12,69,27,6,117,61,33,221,141,32,111,211,144,8,211,40,203,51,112,194,162, +77,216,185,179,23,213,115,47,68,247,225,71,34,218,112,61,150,207,174,81, +168,41,250,6,140,219,136,19,223,184,123,46,252,82,155,115,13,1,205,127, +224,77,237,147,141,60,178,23,214,3,221,200,35,237,245,156,109,116,140,115, +129,65,14,64,56,212,135,111,190,222,172,155,140,59,180,139,19,83,92,187, +218,215,168,93,62,203,138,16,84,185,157,227,186,80,108,171,232,196,122, +48,232,66,169,145,50,98,185,48,223,48,116,39,181,244,119,56,148,179,9,80, +198,73,100,49,28,90,1,68,245,8,237,149,146,106,64,194,164,66,32,43,23,36, +144,97,253,253,156,64,1,74,208,143,169,150,233,235,178,203,3,20,152,2,179, +217,201,184,89,56,20,104,146,241,76,162,126,111,177,51,1,10,144,84,25,48, +251,1,52,152,28,202,229,178,70,65,220,136,53,4,23,174,138,52,209,60,117, +137,231,0,48,216,43,20,167,231,187,137,5,153,26,215,169,9,79,253,111,69, +3,245,186,138,205,216,17,108,97,128,175,117,25,169,149,129,6,41,41,209, +183,41,1,52,24,118,18,134,149,114,73,147,76,193,11,50,0,33,142,191,248, +46,151,33,53,171,242,20,49,251,76,73,147,143,199,183,78,23,24,2,242,188, +132,126,15,135,217,34,72,25,155,101,193,166,48,76,13,218,202,21,110,104, +244,212,2,196,43,180,185,52,234,197,122,202,125,234,55,217,100,81,51,211, +54,209,194,247,125,231,130,48,212,147,202,70,46,34,154,108,97,195,100,9, +48,31,5,182,88,65,91,181,160,0,36,5,167,60,229,138,249,177,250,105,48,44, +162,231,145,219,24,186,137,10,145,228,144,21,232,194,210,47,9,120,210,248, +14,197,88,207,104,151,136,200,219,78,15,34,25,134,108,30,192,79,175,205, +199,49,167,205,70,255,207,155,17,51,17,217,73,157,184,236,133,72,7,172, +188,170,132,35,216,150,139,196,232,230,6,87,190,20,42,8,1,16,113,173,85, +11,61,141,28,137,2,35,241,78,218,131,156,237,244,0,141,4,168,188,155,68, +56,177,107,44,166,76,158,136,33,179,75,145,210,35,120,235,6,95,55,29,12, +24,13,84,251,94,6,164,111,229,2,104,90,117,23,44,179,39,67,81,194,80,124, +173,57,129,27,71,57,219,9,48,213,136,113,215,104,19,3,178,136,228,236,57, +207,13,168,47,123,110,238,192,197,207,244,113,211,20,47,47,44,227,148,171, +239,151,88,109,45,0,76,166,3,186,236,179,151,239,99,179,160,39,133,170, +61,29,102,187,44,232,106,129,97,137,72,65,48,20,229,150,219,91,144,136, +40,147,140,118,244,237,160,226,163,150,240,217,39,68,175,64,208,34,10,15, +53,138,45,74,172,18,92,11,162,97,182,176,103,108,50,92,132,178,110,196, +240,123,126,129,175,64,6,254,12,240,236,165,174,126,169,179,242,232,89, +177,172,37,116,154,105,144,240,154,54,185,11,49,239,250,37,51,246,104,156, +7,113,21,119,204,248,67,71,4,241,24,44,57,99,143,178,222,72,218,29,232, +116,152,11,160,149,74,200,100,115,194,229,247,184,211,238,165,155,127,78, +26,173,246,146,197,252,34,190,92,253,160,14,60,124,124,69,197,40,39,156, +220,85,209,80,145,156,114,68,247,33,168,199,188,150,69,43,34,70,242,146, +230,93,32,16,153,40,73,247,207,25,221,73,174,208,26,13,64,65,197,38,26, +218,232,93,129,237,219,190,215,174,169,211,142,198,57,118,53,102,63,177, +91,195,123,205,45,227,179,91,152,26,200,39,162,236,126,213,251,122,253, +139,79,114,239,88,35,224,111,235,91,17,22,147,209,81,147,15,149,124,132, +95,123,119,224,227,13,31,104,223,133,179,230,192,159,98,80,29,83,85,0,122, +11,90,151,199,82,140,0,64,228,34,7,154,181,248,97,98,25,65,112,163,49,64, +17,126,219,179,76,75,173,93,187,118,177,100,115,151,149,216,102,170,135, +158,155,164,174,48,8,162,84,43,36,185,8,61,164,35,48,160,138,207,92,112, +144,0,132,137,148,115,183,237,216,137,134,117,119,200,143,219,123,145,158, +108,113,206,195,187,181,253,225,109,227,113,222,178,221,252,59,97,248,93, +160,106,38,55,30,67,233,163,87,159,86,65,30,40,0,9,193,35,89,65,53,56,229, +246,83,123,181,0,145,185,113,50,196,248,239,192,187,139,198,105,197,20, +6,33,62,88,220,169,185,197,51,185,235,88,215,18,84,156,124,193,77,15,186, +10,232,32,24,248,110,237,99,220,48,193,233,215,220,183,127,174,172,79,125, +108,237,121,4,211,231,45,129,34,228,133,246,221,186,199,81,72,70,212,0, +180,12,199,64,175,91,228,128,126,246,24,93,84,42,99,125,250,126,105,154, +235,110,75,77,82,125,92,83,88,149,235,153,109,219,180,130,239,126,29,100, +101,120,90,198,198,181,175,224,192,127,35,186,251,117,106,247,88,109,181, +206,205,250,38,118,96,227,186,236,187,180,15,235,212,189,140,53,205,153, +208,212,62,221,244,73,85,138,80,99,14,254,231,230,111,63,237,247,200,72, +125,205,223,181,109,141,238,185,55,195,8,252,105,124,59,71,207,56,255,250, +35,20,73,174,254,209,104,121,7,48,73,163,136,255,247,145,235,245,207,191, +4,24,0,228,101,43,215,5,253,61,104,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_8 = 1017; +static unsigned char xml_res_file_8[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,3,155,73,68,65,84,120,218,108,83,107,76,28,85,24,61,51,204,192,62,200, +178,180,74,106,85,144,46,143,74,74,85,88,16,180,11,110,155,216,248,10,54, +45,93,72,140,105,13,49,77,68,34,36,45,2,41,181,42,225,33,5,234,143,254, +177,63,76,127,216,198,96,218,106,104,4,45,162,18,90,202,110,154,150,165, +181,117,97,215,2,93,118,102,217,7,236,123,102,118,188,67,72,252,227,73, +78,230,206,157,123,190,239,220,243,101,168,190,254,65,136,162,8,5,130,32, +32,22,143,127,89,110,44,237,96,24,6,118,187,29,222,213,213,31,95,42,41, +105,39,103,70,213,106,245,211,233,26,45,2,235,107,144,68,113,150,162,168, +3,140,34,148,101,121,131,130,32,94,170,124,185,220,242,246,91,111,162,171, +187,219,125,109,100,228,227,18,163,81,78,75,77,181,151,149,150,32,235,137, +39,33,72,34,34,225,8,28,142,249,226,71,203,75,142,141,2,201,100,18,146, +36,125,95,188,123,87,109,117,149,9,63,92,190,140,147,29,237,251,201,167, +191,223,63,114,212,187,179,176,0,52,69,99,226,207,73,132,195,97,132,194, +33,128,162,72,211,36,24,69,156,157,157,13,142,227,106,205,166,61,112,204, +47,160,48,191,0,173,109,29,45,26,141,246,104,52,26,213,234,116,58,220,191, +255,23,180,106,21,92,255,184,208,220,212,104,196,38,24,98,253,138,32,138, +53,150,195,7,49,247,224,33,182,232,245,120,236,118,43,174,142,16,87,107, +241,88,108,163,83,70,70,6,104,154,70,34,145,64,79,223,25,155,36,10,160, +200,59,77,46,80,179,183,186,10,179,246,123,74,24,184,117,107,6,163,99,163, +104,249,164,9,69,69,69,77,49,82,32,22,75,128,37,161,42,182,205,38,147,18, +186,44,41,161,17,69,74,69,229,43,85,235,161,72,110,102,166,30,1,191,15, +103,7,7,222,73,79,99,181,105,108,202,206,170,87,43,96,187,125,7,121,121, +6,50,157,4,52,42,21,114,178,159,65,69,121,25,12,134,92,204,88,109,65,138, +84,217,209,222,209,249,141,70,173,218,27,13,5,199,187,122,122,223,32,123, +79,25,142,159,183,165,179,236,214,241,70,51,22,22,221,120,224,88,128,213, +58,131,156,237,219,176,22,12,34,24,10,91,7,134,134,26,208,223,63,160,100, +177,131,176,84,121,234,186,38,160,59,253,243,133,67,195,243,242,141,128, +44,127,113,221,41,255,58,242,147,124,170,179,83,62,209,210,124,113,243, +156,194,130,158,207,78,130,58,119,166,15,52,153,109,171,184,135,36,42,66, +18,226,223,213,151,61,95,255,65,101,14,206,78,241,88,137,83,240,90,175, +98,244,152,25,211,55,167,197,11,172,241,219,95,238,58,245,44,203,214,42, +33,50,157,241,114,146,100,18,106,57,1,65,20,46,190,190,43,175,78,17,127, +61,229,129,63,46,195,195,251,201,68,224,187,125,99,82,180,101,84,100,181, +154,242,27,168,36,141,223,230,30,94,74,101,216,58,90,5,1,44,233,44,75,194, +240,11,207,110,171,59,177,47,15,195,247,252,240,197,146,88,226,125,240, +56,239,92,155,235,109,48,91,108,169,147,147,235,122,244,143,115,104,219, +111,192,107,249,57,22,81,18,135,233,44,157,6,10,183,166,107,14,14,29,122, +145,116,230,96,95,137,99,209,27,192,162,115,110,140,235,173,111,220,222, +125,253,46,9,89,203,249,56,248,163,18,190,154,240,224,212,187,69,27,26, +154,216,83,44,18,80,56,55,237,71,48,33,227,17,207,97,201,101,31,243,245, +30,62,214,247,105,179,51,73,165,192,253,249,129,143,188,174,217,177,101, +47,135,64,76,198,224,31,62,200,68,147,194,154,234,16,37,127,97,196,207, +155,31,7,35,207,121,86,121,4,60,174,113,190,199,242,97,87,219,113,34,166, +113,83,85,136,45,251,222,243,47,159,174,153,98,118,87,23,7,19,241,220,69, +158,199,154,119,229,119,10,255,193,64,168,223,92,251,9,23,240,255,80,70, +158,185,185,14,252,43,192,0,141,58,185,202,150,159,74,140,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_9 = 1751; +static unsigned char xml_res_file_9[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,6,121,73,68,65,84,120,218,180,87,91,136,85,85,24,254,215,90,123, +239,115,206,92,116,116,38,157,48,47,35,90,80,129,89,116,33,51,74,165,34, +6,52,20,231,33,240,33,80,8,133,30,213,232,74,15,225,99,161,4,69,15,9,65, +23,203,140,30,122,200,64,208,138,233,98,150,24,42,90,94,162,209,156,25, +103,206,204,156,115,246,109,245,253,107,175,125,206,222,211,25,60,15,181, +14,63,251,236,117,251,191,245,255,223,255,255,107,11,74,154,243,234,190, +15,15,72,229,172,215,90,211,255,217,132,16,20,71,225,161,151,183,15,108, +194,107,40,88,249,139,111,188,127,80,72,167,127,197,138,229,20,51,128,255, +11,3,180,73,0,56,113,226,44,233,56,252,226,181,231,158,126,202,65,119,137, +148,211,191,107,251,102,138,211,137,186,233,218,186,76,111,26,157,241,204, +58,115,107,120,235,199,87,175,164,61,251,62,234,103,221,12,160,24,71,177, +217,96,235,243,111,153,73,137,21,120,168,13,82,32,137,101,5,242,129,116, +138,28,10,217,104,232,41,226,233,65,185,160,192,13,104,170,84,161,192,9, +208,111,182,36,129,245,18,187,122,88,231,106,159,164,134,14,40,241,107, +130,222,124,233,89,252,55,144,139,60,91,104,44,11,35,108,231,57,244,238, +43,91,41,136,24,4,143,63,4,159,29,35,23,255,142,210,195,244,168,56,98,182, +47,64,92,218,128,255,63,144,35,75,84,131,146,145,133,23,40,154,67,20,1, +151,116,239,38,225,118,193,176,130,222,115,183,65,158,161,118,108,18,3, +123,223,234,119,8,231,37,203,53,225,24,179,224,37,8,53,22,40,242,49,169, +234,91,0,162,0,243,181,225,28,34,81,139,71,135,57,55,108,32,60,128,232, +32,165,74,164,221,73,51,92,129,193,98,70,231,97,157,219,142,227,225,212, +174,36,23,90,92,69,198,118,133,130,194,1,67,86,154,176,191,1,32,162,2,102, +177,98,118,65,204,142,133,8,99,72,153,98,229,127,164,120,161,86,88,236, +130,84,108,106,215,116,198,152,18,179,185,148,34,161,48,19,34,164,224,215, +122,43,120,0,0,19,167,209,38,19,102,104,211,233,186,78,26,43,211,152,132, +29,132,52,118,144,117,97,104,248,161,95,113,143,204,14,202,186,48,128,236, +118,172,35,8,67,210,148,1,192,104,124,116,186,142,99,24,157,227,172,81, +172,140,58,202,1,144,38,164,164,129,34,76,167,200,1,80,117,0,217,208,98, +29,126,24,215,45,224,52,0,196,13,11,104,202,88,34,221,89,24,211,11,145, +181,128,74,237,208,240,141,25,132,77,160,88,243,233,101,222,154,198,2,193, +116,14,144,54,157,6,128,206,4,48,9,123,114,97,50,152,152,110,1,134,33,44, +0,101,215,240,160,163,12,8,33,99,195,5,193,134,180,137,130,35,205,184,32, +11,192,112,0,157,94,157,3,169,21,68,114,100,145,170,204,0,16,202,192,83, +134,1,42,217,201,77,66,68,184,46,107,66,56,34,178,48,207,197,22,30,3,136, +56,10,0,32,106,226,130,192,184,64,82,190,20,228,207,204,135,84,34,57,172, +50,220,119,17,142,78,194,129,9,68,64,0,193,160,30,27,36,25,118,80,36,125, +58,89,189,151,62,27,177,233,18,227,253,91,101,46,10,26,0,208,233,57,174, +209,217,160,128,74,34,192,18,141,149,59,214,56,19,52,73,99,250,34,77,196, +62,226,251,42,209,105,28,176,4,97,43,208,53,76,98,166,87,40,18,149,36,115, +177,5,0,160,8,235,248,198,5,212,0,192,113,95,139,216,5,170,73,38,183,236, +2,16,108,69,151,180,177,36,222,135,1,176,140,83,58,141,217,142,37,162,57, +85,178,206,112,72,155,116,107,128,123,94,146,136,226,188,5,40,33,161,231, +228,84,55,78,95,33,95,143,154,76,38,172,27,132,45,51,156,37,117,179,18, +37,40,71,104,157,141,2,63,110,146,9,131,216,48,148,67,152,73,156,112,16, +190,138,203,224,96,100,84,165,7,227,108,41,204,12,196,143,212,117,77,138, +247,141,44,119,209,39,177,111,253,126,17,89,147,115,30,168,54,18,81,61, +10,66,84,138,246,146,162,118,213,48,99,140,234,23,83,213,76,18,230,252, +105,127,186,99,144,171,221,179,38,237,56,120,160,149,15,64,62,69,126,148, +73,68,194,228,235,127,39,34,252,34,132,70,215,108,55,151,54,239,184,111, +45,117,247,44,166,8,12,94,57,188,140,244,96,99,236,133,7,214,210,169,238, +37,80,162,192,183,113,227,227,180,173,25,216,76,65,97,22,69,97,141,182, +109,185,147,244,19,141,177,67,131,14,85,107,97,179,76,24,26,23,100,155, +82,21,212,147,49,227,231,80,130,7,246,204,92,13,71,49,54,162,174,35,16, +81,148,162,169,252,186,145,9,84,197,8,0,2,170,141,84,97,67,84,194,72,112, +109,50,42,253,160,41,0,248,12,87,142,225,234,53,36,49,166,172,130,85,118, +163,118,187,73,4,201,128,46,169,17,132,85,68,10,99,187,162,157,228,98,12, +201,142,100,132,190,43,35,230,25,163,244,69,7,62,78,158,32,139,31,248,116, +249,175,97,240,38,6,121,5,220,92,164,161,225,241,60,9,57,205,242,235,79, +191,13,67,254,206,148,3,244,219,234,196,110,210,66,215,125,41,116,18,7, +41,5,132,185,69,105,147,57,181,176,25,84,219,117,118,140,245,40,176,188, +88,240,234,21,215,228,149,169,242,216,177,159,191,251,118,149,142,227,230, +87,66,109,57,155,62,51,253,211,203,183,176,239,162,73,89,79,223,4,64,84, +38,198,143,217,252,72,157,144,69,144,158,122,84,204,220,228,150,29,187, +215,47,233,91,190,177,216,57,167,55,59,80,45,143,14,253,241,251,217,79, +246,239,125,253,16,205,124,71,77,91,152,164,75,186,40,172,210,146,185,73, +54,191,244,26,208,107,250,7,22,61,242,228,198,193,9,228,139,123,238,186, +149,206,195,175,217,76,179,244,230,110,58,126,226,12,181,57,146,142,124, +249,233,253,135,63,255,224,2,205,124,193,231,126,230,102,197,177,104,202, +86,102,106,133,85,143,109,24,210,133,34,114,121,76,157,179,58,104,221,130, +121,117,38,179,111,175,150,167,200,3,193,52,204,251,224,186,245,223,0,64, +59,134,106,55,250,84,112,90,252,164,104,11,16,82,203,22,206,167,242,100, +133,206,158,187,76,103,166,125,65,49,136,121,61,93,52,167,179,131,126,253, +229,148,178,119,250,255,12,128,27,162,94,247,205,159,43,145,75,105,116, +124,146,42,190,159,227,96,9,245,191,103,118,7,133,65,64,199,185,182,39, +183,131,27,54,213,34,0,175,60,62,250,253,148,156,53,224,224,138,117,91, +223,2,186,125,233,45,180,184,119,46,164,155,22,245,246,96,163,152,78,158, +62,79,95,31,253,145,14,31,220,191,233,234,159,23,206,89,63,223,232,107, +173,165,198,21,125,62,71,203,166,109,59,119,116,245,244,174,115,92,183, +59,107,2,156,124,248,250,181,161,175,14,188,189,103,47,179,27,114,165,21, +23,180,10,64,216,12,220,5,185,9,50,219,130,202,94,121,89,217,24,132,51, +217,117,136,79,45,124,230,182,10,32,235,178,162,85,238,52,137,237,154,53, +123,212,234,134,255,8,48,0,163,88,200,134,33,243,7,106,0,0,0,0,73,69,78, +68,174,66,96,130}; + +static size_t xml_res_size_10 = 1855; +static unsigned char xml_res_file_10[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,6,225,73,68,65,84,120,218,196,87,123,80,84,85,24,255,238,115,31, +160,41,169,37,175,196,16,28,21,75,108,20,21,195,200,124,128,111,39,49,205, +7,154,38,249,154,177,153,242,143,254,232,53,163,142,53,227,24,67,89,227, +148,96,36,166,228,35,95,164,136,104,68,89,249,2,53,65,65,212,69,151,213, +117,217,221,123,239,62,238,189,125,231,238,93,220,20,84,172,198,157,249, +102,239,185,247,156,243,253,206,247,251,94,135,82,85,21,30,231,143,250, +151,235,185,241,175,229,92,197,255,110,12,195,216,119,108,206,125,10,159, +125,237,217,128,121,84,224,47,101,78,143,75,30,146,110,27,147,145,17,54, +120,200,16,56,117,226,132,41,50,246,217,163,245,53,213,117,237,217,136, +126,4,229,244,152,169,243,102,71,197,198,93,202,156,56,17,142,149,151,131, +44,203,160,42,10,72,130,139,107,239,158,108,59,149,51,25,211,22,108,141, +239,149,48,165,95,82,18,148,150,148,128,71,146,208,30,1,38,21,69,161,117, +0,242,255,1,128,203,156,182,240,242,144,212,212,238,70,163,17,126,173,172, +4,142,227,128,161,67,15,220,170,67,115,230,101,165,215,17,221,53,33,119, +228,192,187,125,132,126,40,190,51,178,226,38,207,90,234,205,156,48,161, +59,58,27,212,92,184,160,41,55,153,205,96,68,1,140,36,181,109,143,230,132, +245,233,131,128,162,227,17,136,131,140,219,3,128,30,61,37,123,86,247,152, +30,26,223,54,155,13,44,22,11,24,77,38,77,120,131,1,12,104,141,214,66,153, +75,91,222,17,21,90,77,11,126,200,198,161,71,248,44,125,56,248,164,75,230, +197,7,246,135,90,254,126,0,152,177,175,190,81,212,43,177,247,166,87,70, +143,134,134,250,122,112,58,157,96,34,202,81,169,1,149,27,117,105,13,128, +98,57,101,80,221,183,126,164,76,157,114,205,57,123,215,224,171,27,194,231, +25,51,129,225,134,153,230,22,78,15,234,38,72,216,171,27,83,118,240,148, +63,147,5,63,92,176,135,195,59,71,147,192,196,248,33,101,232,80,136,138, +142,134,250,186,58,77,9,81,126,143,34,244,126,85,231,159,82,149,22,36,114, +77,153,40,214,148,173,226,82,23,149,114,201,89,5,166,236,162,74,241,235, +172,98,127,245,190,121,108,223,140,111,113,202,118,20,145,0,48,113,224, +207,236,154,93,136,123,200,48,152,146,97,122,172,3,76,172,31,68,193,5,215, +209,228,132,111,138,106,157,97,2,140,8,165,146,35,41,154,207,240,243,183, +15,98,195,58,239,146,47,28,30,231,217,255,81,37,221,241,233,101,76,124, +218,122,252,182,217,123,104,109,37,219,103,172,100,156,181,105,154,84,48, +167,128,152,1,73,196,133,126,23,216,74,94,7,225,240,108,104,178,218,192, +106,181,130,219,237,214,156,140,240,77,184,110,77,200,55,208,40,64,16,1, +91,80,190,109,75,235,193,239,109,98,18,210,143,227,248,150,103,239,251, +251,65,246,93,53,205,223,182,2,199,130,234,188,94,68,133,117,33,190,193, +209,45,206,171,72,96,140,136,2,99,231,72,220,212,172,153,59,200,247,125, +5,231,168,119,232,144,53,163,56,44,94,33,111,204,12,213,43,156,49,231,236, +219,138,239,156,202,141,243,95,80,230,8,2,64,149,175,157,222,75,241,230, +52,114,248,128,19,170,148,6,192,208,169,27,208,157,187,1,75,51,192,178, +40,204,253,133,132,36,153,27,36,199,239,247,41,244,146,35,249,166,37,7, +139,113,104,247,253,178,113,37,112,198,151,53,165,13,191,87,32,143,102, +114,96,185,182,188,90,95,194,135,36,34,9,29,212,136,70,81,192,106,191,9, +102,222,139,156,62,184,82,146,12,16,23,254,76,208,2,172,146,155,182,18, +150,149,145,122,32,249,79,21,159,229,211,150,6,104,249,45,191,150,75,201, +14,56,104,93,133,61,152,99,2,0,52,7,147,192,121,173,6,194,13,42,88,155, +250,67,56,239,3,154,82,31,168,92,65,199,239,25,219,67,99,146,97,208,115, +255,89,105,165,144,20,233,11,121,150,239,74,197,56,87,149,128,229,205,192, +24,85,112,139,2,80,202,195,1,144,101,37,16,33,58,15,244,194,61,239,129, +226,111,210,162,33,125,69,116,112,46,159,254,118,76,107,249,250,14,5,178, +0,124,199,206,232,22,42,112,200,63,143,9,147,0,104,43,252,130,33,40,51, +74,232,145,121,229,203,204,143,69,0,146,120,84,182,247,168,13,170,228,60, +74,62,209,145,73,195,112,129,155,60,27,38,173,29,216,138,5,68,224,194,35, +0,12,50,2,96,129,193,47,12,57,24,2,104,51,7,144,116,41,203,45,3,154,97, +201,196,219,252,196,181,73,108,204,128,82,124,17,45,230,141,233,75,190, +210,79,68,173,80,155,27,183,107,96,58,69,167,130,79,172,214,64,6,236,134, +193,64,232,195,40,0,228,62,101,224,64,116,66,63,8,238,102,184,120,185,1, +129,43,109,128,64,11,224,218,96,42,166,104,154,152,67,84,89,158,198,184, +23,189,63,111,152,68,162,193,48,249,211,254,120,162,24,113,211,204,85,90, +204,133,117,153,163,216,106,191,34,129,163,1,240,3,237,108,218,82,212,129, +65,223,248,203,30,6,133,71,45,152,9,125,48,224,249,254,144,152,152,8,87, +26,27,193,227,241,220,3,130,168,165,21,165,197,136,138,94,90,124,219,151, +87,163,199,141,35,96,12,25,31,68,48,49,201,37,138,237,210,58,28,55,27,167, +174,75,70,48,145,82,81,206,102,226,164,4,128,55,106,94,197,136,119,167, +196,14,243,248,20,181,131,65,165,202,119,148,157,35,91,58,237,19,231,98, +54,156,241,92,114,50,88,111,218,64,148,60,247,148,92,18,5,90,58,38,121, +144,162,41,29,151,147,236,107,90,180,103,53,38,156,28,85,116,148,75,133, +243,243,136,66,58,170,127,177,114,253,220,135,250,28,15,1,64,28,163,126, +77,113,67,147,94,161,20,205,40,72,111,197,161,157,107,154,111,223,60,109, +183,219,87,15,31,49,2,4,73,4,151,219,125,143,35,234,15,161,134,241,50,253, +198,119,64,229,111,42,214,154,92,105,203,194,13,248,206,129,89,241,123, +240,121,234,164,173,111,21,232,0,20,86,143,79,146,24,28,33,0,20,253,185, +185,234,143,99,197,183,154,26,235,93,46,215,38,4,97,232,18,241,36,56,176, +44,7,21,170,161,32,66,126,114,213,110,159,80,181,187,143,62,188,109,94, +252,83,9,58,101,111,236,11,94,208,245,73,161,97,24,76,14,161,189,156,172, +163,244,91,26,46,122,177,229,30,41,184,93,249,169,47,166,197,69,98,137, +118,186,92,90,41,134,182,27,50,140,70,104,36,84,98,19,114,0,25,138,68,229, +41,56,182,145,131,233,135,124,168,182,220,175,111,230,185,120,254,100,137, +76,241,145,72,123,66,207,248,120,80,176,124,211,20,173,85,197,234,51,103, +64,112,53,127,119,237,114,237,69,125,115,114,0,15,177,164,108,57,125,196, +123,232,147,124,93,249,205,208,190,240,97,239,5,178,110,50,233,114,237, +217,227,152,252,110,55,55,187,83,123,37,36,2,139,189,2,41,76,213,85,85, +8,192,17,10,160,37,63,169,206,27,162,110,77,199,221,77,105,123,186,98,178, +240,22,249,255,179,226,224,55,141,87,46,157,20,4,97,203,200,81,163,32,60, +44,12,83,9,77,170,35,211,198,58,223,127,121,53,11,52,49,120,29,67,137,205, +204,90,184,147,166,153,78,152,35,156,187,10,243,72,214,179,180,231,94,240, +168,119,67,178,142,71,233,138,18,137,18,166,155,183,94,247,112,245,255, +6,208,210,125,235,202,57,221,204,238,246,94,78,31,251,239,111,1,6,0,48, +107,244,198,77,151,19,83,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_11 = 869; +static unsigned char xml_res_file_11[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,3,7,73,68,65,84,120,218,236,151,223,75,20,81,20,199,207,157,157, +31,251,83,77,122,176,151,232,7,130,73,245,188,161,137,17,26,5,82,244,22, +81,36,98,136,32,21,253,29,81,17,136,36,98,37,209,147,82,8,69,74,36,166, +228,115,5,9,210,22,61,7,169,59,174,59,59,59,247,118,206,29,119,221,93,117, +118,87,150,246,101,239,114,119,118,239,143,115,62,243,189,231,156,217,101, +66,8,168,102,83,160,202,173,6,80,3,168,58,0,243,152,211,39,94,190,178,228, +34,198,246,101,60,147,226,55,174,95,51,240,146,42,71,1,125,252,249,132, +213,218,218,10,182,237,64,58,205,129,115,81,86,167,61,180,151,108,144,45, +178,89,170,2,250,232,216,184,21,141,70,225,203,215,111,16,14,133,209,160, +3,249,74,236,165,136,200,187,115,69,241,129,185,97,194,233,83,39,97,105, +105,9,250,251,122,119,40,81,104,73,31,25,29,179,58,59,58,224,251,242,178, +28,104,111,59,3,235,235,235,176,182,22,135,100,50,9,137,205,77,79,217,131, +129,0,248,253,126,168,175,143,64,93,93,29,44,44,126,150,227,39,90,90,96, +110,126,30,6,250,251,242,32,114,1,244,225,145,167,86,119,119,23,172,172, +252,216,154,18,104,204,128,3,13,13,16,137,68,64,215,53,48,12,195,19,192, +178,44,72,165,108,136,199,227,240,119,117,21,161,173,172,173,230,230,227, +48,51,51,11,131,3,183,179,16,25,0,253,241,147,97,235,202,229,30,136,253, +252,85,16,72,180,85,184,178,150,250,220,192,163,162,227,146,175,2,141,143, +29,61,2,175,223,76,195,157,161,65,9,65,211,234,131,135,143,166,122,111, +221,236,177,237,116,246,28,119,59,94,81,78,106,177,189,103,53,77,133,241, +103,47,166,239,223,187,123,85,197,145,128,207,167,246,152,102,2,222,190, +123,47,23,8,193,161,210,79,73,169,8,83,228,157,92,186,120,1,200,39,249, +38,0,131,115,142,105,147,150,193,67,110,187,206,159,147,0,172,88,165,40, +169,24,184,202,17,192,236,135,143,210,28,249,34,159,228,155,0,20,250,98, +227,32,5,24,71,199,220,225,48,247,105,1,211,72,169,132,127,233,172,243, +108,59,6,177,14,10,130,216,219,0,10,1,64,70,1,85,85,229,6,51,177,1,145, +112,8,1,88,69,36,160,194,68,54,53,77,43,84,0,178,0,60,237,200,5,36,125, +10,83,39,16,8,238,187,4,239,86,146,201,166,134,55,72,54,201,87,1,0,82,98, +224,81,158,19,177,237,56,16,10,21,1,16,185,149,156,123,10,69,0,100,211, +48,52,169,40,249,34,159,249,10,224,32,41,64,45,22,139,121,58,151,249,45, +84,80,28,183,40,113,159,5,130,165,101,189,240,130,104,108,108,116,215,75, +128,130,35,16,130,242,211,53,216,212,116,168,72,158,51,116,238,207,27,227, +190,164,39,64,166,168,185,87,150,15,64,116,20,128,225,112,208,77,191,98, +71,47,92,5,124,220,5,118,20,82,0,55,177,226,0,164,172,12,118,177,125,4, +194,52,227,139,147,147,83,109,52,88,74,253,97,59,62,137,156,247,162,85, +90,66,36,18,27,139,238,173,0,68,176,31,198,126,48,163,200,127,104,84,243, +255,96,255,205,182,156,6,176,251,43,144,244,229,212,167,36,246,205,106, +255,36,196,176,169,253,53,171,1,84,185,253,19,96,0,249,4,138,17,171,4,193, +66,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_12 = 634; +static unsigned char xml_res_file_12[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,28,73,68,65,84,120,218,140,146,205,107,19,65,24,135,159,217,221,144, +108,194,162,104,244,80,177,181,136,32,130,7,169,90,240,82,197,34,86,91, +47,90,68,122,240,31,240,32,166,135,10,122,18,145,106,251,23,136,246,224, +65,76,27,15,106,81,36,82,5,123,144,106,148,94,10,173,45,181,133,32,10,37, +181,77,52,217,143,113,38,9,82,37,196,188,48,187,204,204,251,252,222,175, +17,119,239,141,224,251,1,134,33,80,38,195,225,48,245,172,88,44,234,159, +8,2,137,105,26,88,122,23,4,129,22,145,61,221,167,89,252,178,84,87,96,87, +75,51,79,159,141,75,33,12,161,5,12,13,151,92,87,158,233,233,86,240,178, +22,71,136,218,75,223,105,31,237,171,25,205,90,190,239,39,47,246,93,192, +245,60,246,238,217,77,67,166,196,52,243,48,57,154,180,60,207,235,93,93, +91,231,249,139,151,213,91,249,63,186,252,237,58,121,2,205,234,12,40,150, +138,216,81,155,206,99,71,21,47,171,62,226,31,76,84,191,130,244,196,107, +93,2,129,95,41,1,183,228,18,181,35,120,234,112,42,243,241,79,189,149,108, +53,98,98,138,48,66,134,56,220,214,198,166,216,118,112,67,200,64,160,74, +240,209,34,145,136,77,110,109,149,120,124,107,85,160,18,87,245,154,144, +112,72,103,175,146,89,121,194,253,113,117,106,64,71,248,60,120,93,149,12, +116,55,99,177,40,179,179,159,55,192,58,186,158,115,148,169,31,215,200,57, +105,78,29,129,246,29,9,222,101,135,153,158,123,68,200,254,134,165,97,211, +178,112,28,167,188,254,110,182,138,142,195,131,76,154,227,205,176,94,128, +253,91,134,120,53,55,204,62,181,127,155,155,192,202,231,243,111,82,169, +199,29,82,202,26,253,86,181,7,14,102,11,28,106,234,231,96,211,157,242,249, +229,118,201,135,236,0,147,159,6,203,157,210,195,223,92,111,112,125,35,188, +63,208,10,5,23,174,119,74,110,164,5,209,16,76,47,128,117,243,214,237,249, +90,209,193,80,209,109,102,90,47,81,248,202,216,124,152,115,59,227,48,185, +56,128,165,220,23,178,240,115,133,148,85,247,205,72,83,141,14,198,18,36, +122,135,16,249,95,156,157,89,30,212,15,177,12,143,246,115,69,208,184,169, +182,177,109,195,254,187,90,75,162,118,250,141,219,111,1,6,0,80,239,219, +105,146,138,192,9,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_13 = 632; +static unsigned char xml_res_file_13[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,26,73,68,65,84,120,218,164,83,61,111,19,65,16,125,179,187,103,7,131, +81,8,4,10,155,68,20,72,161,224,67,73,68,75,19,104,41,40,144,16,162,129, +34,5,13,255,0,209,210,128,132,172,132,134,6,148,54,13,66,164,65,66,162, +76,224,226,2,100,36,7,35,36,155,96,130,125,150,239,156,203,221,46,179,119, +206,23,208,32,143,116,186,189,157,153,247,102,222,204,145,49,6,131,152, +192,128,166,202,243,51,139,58,10,175,26,29,39,23,36,36,72,170,50,145,56, +199,95,251,163,169,127,67,132,109,159,178,201,231,103,159,1,91,81,26,36, +37,86,158,220,56,203,32,134,232,15,0,78,34,33,32,84,230,19,19,157,73,0, +140,214,156,188,137,176,242,16,198,16,156,194,53,76,206,62,231,230,250, +201,22,100,27,200,190,148,130,91,186,53,33,73,76,241,253,178,74,28,166, +203,142,3,236,151,136,214,95,241,197,203,36,150,24,196,196,26,65,199,239, +151,110,144,41,92,231,120,131,142,31,94,204,31,204,90,0,118,197,62,132, +51,196,71,105,139,220,97,214,172,75,229,157,139,160,213,177,44,236,225, +137,209,125,8,169,144,115,156,18,235,246,32,5,160,77,75,135,160,29,32,233, +59,165,67,109,165,130,209,177,17,28,191,89,2,18,145,77,250,88,191,147,129, +59,119,251,152,178,101,34,242,240,249,173,139,238,47,111,87,47,214,99,124, +234,52,142,20,142,98,171,250,136,171,214,73,233,22,64,230,138,8,197,4,154, +237,112,73,89,102,191,190,198,202,2,211,247,22,184,157,184,175,150,68,252, +181,4,109,120,85,40,147,150,159,0,107,6,24,71,235,227,42,190,172,247,94, +40,158,55,58,245,26,14,23,121,42,221,42,116,115,137,67,69,10,34,179,124, +218,187,107,172,3,49,211,208,33,252,172,186,184,243,248,195,98,210,66,187, +241,13,197,233,75,220,74,29,148,205,115,170,216,29,225,62,99,0,103,4,126, +99,13,223,27,205,215,171,243,51,158,178,65,193,70,11,185,83,39,129,94,139, +7,49,140,191,54,112,175,101,135,177,177,252,30,181,31,189,133,19,163,76, +230,206,93,246,120,96,121,29,197,176,75,101,118,54,230,223,102,139,50,36, +218,147,119,223,140,149,159,94,241,108,228,133,68,177,255,51,187,247,110, +186,91,3,254,206,191,5,24,0,171,203,191,162,234,194,67,169,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_14 = 685; +static unsigned char xml_res_file_14[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,79,73,68,65,84,120,218,100,83,61,108,82,81,20,254,30,63,15,144,194, +98,52,154,70,156,28,108,73,140,198,166,49,52,142,226,166,198,196,132,142, +154,176,72,88,93,89,93,136,65,106,28,180,12,38,52,150,69,55,113,174,49, +93,52,8,117,176,46,98,26,45,196,193,247,158,240,248,125,158,239,218,71, +16,110,114,184,156,243,125,231,231,158,115,158,134,153,83,40,20,54,70,163, +209,93,199,113,130,174,77,211,52,219,235,245,110,102,179,217,251,211,92, +225,64,115,149,98,177,120,173,223,239,87,19,107,107,136,199,227,56,22,10, +77,136,157,110,23,141,70,3,239,118,118,160,235,122,50,147,201,188,253,47, +0,157,37,75,53,181,190,14,201,132,111,205,38,186,93,27,154,199,3,103,60, +70,40,20,196,217,88,12,82,25,182,202,101,58,170,32,12,224,97,0,102,78,165, +82,176,237,30,190,236,127,21,226,24,225,112,24,229,242,150,186,169,211, +78,156,60,242,221,234,60,124,115,34,145,128,215,167,227,176,221,150,108, +33,44,44,132,241,236,249,38,86,46,175,168,155,58,237,196,201,35,159,126, +42,192,112,56,188,183,180,188,140,118,171,141,160,174,99,65,50,110,60,121, +138,171,210,139,131,131,239,234,166,78,59,113,242,200,167,159,10,32,18, +32,56,26,15,17,12,6,241,168,240,24,215,147,73,116,165,220,197,197,51,234, +166,78,59,113,242,200,167,31,127,124,238,91,216,60,202,169,147,39,240,166, +90,157,157,174,178,187,156,233,51,9,224,247,251,21,152,78,167,17,8,4,224, +241,112,64,20,7,99,105,162,221,235,73,19,109,197,155,13,208,55,76,83,103, +121,124,207,203,237,10,76,211,152,171,32,18,137,226,246,173,155,240,249, +124,16,190,26,158,10,96,154,230,171,207,123,123,119,46,92,188,4,91,22,198, +248,109,226,199,225,207,185,0,167,199,242,76,201,206,105,212,62,126,0,253, +92,44,150,207,231,157,86,171,237,116,58,93,199,178,254,56,178,68,142,204, +124,34,212,45,203,82,56,121,228,211,207,93,164,102,189,94,207,84,42,219, +176,44,19,126,221,175,54,110,48,24,76,132,186,95,70,72,156,60,242,233,55, +105,98,169,84,122,193,187,215,235,21,87,87,175,96,105,233,188,188,57,242, +111,215,53,141,229,162,86,251,132,221,221,247,202,217,229,227,168,205,238, +137,138,156,203,229,114,15,162,209,232,13,249,175,79,97,125,195,48,94,11, +246,80,254,239,139,24,115,95,227,212,137,137,28,63,90,50,247,72,11,241, +203,45,123,250,115,254,43,192,0,120,74,65,201,19,184,212,222,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_15 = 1507; +static unsigned char xml_res_file_15[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,5,133,73,68,65,84,120,218,164,87,91,104,28,101,20,62,51,187,155, +236,230,158,77,210,52,218,180,138,109,76,177,105,161,96,125,17,159,4,81, +4,193,7,171,40,98,193,82,237,139,216,168,120,125,200,67,40,105,107,131, +68,107,193,104,180,10,26,168,20,193,90,16,108,169,109,173,13,84,107,45, +33,109,18,91,55,27,211,53,183,221,77,246,58,55,207,247,207,76,50,89,102, +147,221,56,112,216,221,249,207,249,206,247,159,219,255,175,100,24,6,229, +62,146,36,145,203,35,189,127,244,216,3,165,126,255,235,146,236,121,148, +117,2,146,44,145,71,146,73,51,116,50,116,131,24,43,101,232,218,169,76,58, +125,176,253,165,231,47,177,141,225,6,228,244,41,21,66,96,111,251,91,53, +247,181,109,63,87,81,89,177,101,199,214,86,90,215,212,72,21,229,1,177,118, +184,183,159,246,189,184,83,124,159,79,164,40,60,17,161,129,171,67,52,63, +55,127,45,22,155,121,242,237,87,246,140,228,18,89,226,19,63,114,197,201, +165,227,96,207,198,15,191,56,110,92,25,188,110,184,61,29,221,189,174,239, +161,15,187,247,246,119,111,2,78,46,1,91,188,180,252,83,18,92,179,118,248, +161,29,219,168,173,117,35,233,186,198,98,26,202,178,76,30,143,135,210,169, +148,80,212,52,172,233,34,122,50,167,102,219,230,22,146,57,61,103,7,140, +27,188,236,103,201,184,57,144,151,113,238,233,250,168,175,179,101,195,157, +236,252,30,82,21,133,20,69,93,112,100,176,224,73,167,77,92,252,198,123, +172,67,15,250,176,131,253,161,163,199,142,2,175,88,2,126,191,191,172,125, +75,203,221,12,166,145,170,233,98,247,16,100,84,146,76,211,76,38,99,213, +141,44,34,109,235,64,31,68,182,114,228,124,190,210,23,120,49,80,12,1,249, +221,206,195,79,4,252,165,84,89,81,70,170,234,216,57,87,60,50,122,241,247, +63,169,251,211,126,186,183,117,19,29,249,242,4,253,122,229,154,72,52,214, +237,72,168,170,70,85,149,101,116,71,99,29,189,217,113,224,241,220,90,192, +147,175,6,60,89,69,169,107,8,86,17,183,156,233,220,42,78,228,216,195,180, +135,111,142,209,238,167,30,35,188,70,206,63,248,252,56,221,223,182,121, +161,70,236,98,67,157,0,167,58,88,255,44,191,58,145,91,11,249,8,120,171, +107,131,143,84,85,148,51,101,137,52,46,62,195,65,0,223,51,156,251,88,60, +206,107,58,121,217,137,146,85,68,183,153,17,176,116,17,74,214,175,175,173, +166,146,82,255,195,252,179,180,80,2,62,159,215,183,189,154,195,39,138,139, +35,96,56,102,4,156,128,64,34,153,100,2,220,74,28,146,108,54,43,66,111,138, +163,149,217,182,134,211,104,152,157,80,82,104,10,124,178,215,215,212,24, +172,225,208,235,166,115,199,124,16,17,200,100,41,197,131,71,51,108,2,138, +217,219,86,10,36,147,45,218,131,68,221,154,246,114,193,53,32,1,216,231, +21,253,238,156,94,72,9,162,128,29,39,82,73,107,38,72,156,130,172,136,185, +196,250,50,153,4,160,43,51,57,172,75,134,235,84,206,59,138,215,236,239, +249,44,18,137,76,81,137,223,79,229,1,63,5,202,203,24,204,35,114,106,14, +33,123,51,38,33,56,84,181,197,90,65,42,146,201,148,72,149,194,51,161,161, +190,150,218,247,60,215,200,75,255,58,125,230,157,132,94,175,143,246,237, +222,73,149,85,85,86,251,229,18,181,59,106,177,224,12,59,83,18,45,137,64, +60,22,167,254,31,206,186,251,201,71,0,173,151,97,230,82,34,41,118,108,228, +9,225,114,15,34,3,242,89,85,17,159,69,17,128,67,49,86,185,216,188,37,190, +85,19,80,185,56,53,71,106,10,39,192,165,43,177,13,162,32,123,61,171,38, +192,3,141,69,37,210,221,237,243,141,98,35,149,74,93,191,61,61,43,170,29, +206,23,123,188,112,129,29,236,103,227,115,148,100,60,183,11,74,62,2,90, +54,155,30,139,70,19,230,208,201,20,79,194,158,21,152,35,192,1,30,112,11, +37,160,78,69,38,206,128,57,170,153,163,177,170,8,192,14,246,192,1,30,112, +11,37,144,253,233,212,119,39,39,103,162,100,48,130,162,42,34,151,246,73, +183,242,238,117,161,15,59,216,3,7,120,192,45,152,192,173,191,134,167,230, +19,233,76,44,54,47,58,154,239,120,124,38,232,43,166,66,172,179,94,98,62, +33,128,96,15,28,224,21,67,0,77,155,137,206,76,158,28,143,76,139,218,193, +113,28,103,18,56,227,209,33,112,146,43,120,143,117,232,225,148,68,201,193, +30,56,214,41,168,23,115,35,202,12,92,56,243,73,104,124,82,40,73,214,92, +136,207,205,81,42,157,182,28,88,103,63,214,144,115,126,143,117,232,65,159, +143,0,130,61,112,86,115,39,76,95,60,119,122,48,26,139,142,142,132,38,112, +176,91,163,214,88,112,52,203,247,129,40,11,62,109,98,226,68,132,38,235, +143,132,254,33,216,3,7,120,197,18,64,197,206,253,248,253,183,175,14,141, +134,173,203,167,177,144,231,124,162,91,161,215,56,21,67,163,227,4,123,224, +184,117,192,74,4,176,225,196,111,3,23,174,134,67,55,191,186,244,199,13, +51,180,142,123,159,91,245,99,29,55,168,243,151,7,9,118,176,7,78,190,127, +73,242,10,211,20,247,172,153,222,158,174,174,112,56,252,243,47,151,135, +204,123,30,31,78,246,17,108,159,132,230,93,209,60,180,160,7,125,216,193, +222,194,41,234,62,176,228,114,194,82,205,178,126,215,203,175,189,209,188, +254,174,103,54,52,55,210,186,181,245,84,230,47,17,249,6,149,100,58,75,225, +219,83,244,247,88,132,198,66,183,190,238,251,248,208,1,182,9,161,19,115, +39,96,209,255,13,173,67,171,138,165,169,54,88,223,252,244,174,189,239,212, +212,212,61,40,138,109,225,252,151,120,228,78,159,255,166,239,72,231,236, +204,20,198,46,87,46,197,221,114,191,26,2,118,36,240,231,162,134,165,193, +34,228,205,41,90,56,156,100,137,98,130,187,205,254,255,67,192,25,141,128, +117,197,150,115,135,151,229,88,93,14,192,233,243,63,1,6,0,218,58,168,206, +121,36,62,30,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_16 = 1971; +static unsigned char xml_res_file_16[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,85,73,68,65,84,120,218,156,87,123,76,149,231,25,255,125,215,115, +225,28,64,4,228,182,34,76,81,196,203,172,174,42,118,118,217,186,46,198, +75,170,105,154,213,206,118,107,27,99,155,45,157,201,178,196,54,248,135, +108,251,103,174,29,75,237,76,219,117,235,26,187,49,131,98,129,182,75,183, +214,86,165,245,194,102,13,181,5,122,40,194,17,116,28,176,128,192,185,125, +223,183,231,249,46,120,14,112,16,247,145,31,129,247,253,158,247,249,61, +247,247,19,48,203,103,245,238,154,116,247,220,226,39,116,81,122,84,135, +184,220,48,0,131,126,248,17,248,71,0,68,232,23,69,93,123,45,60,112,249, +149,243,135,158,30,158,205,185,194,173,246,215,237,249,83,169,232,203,174, +119,169,234,210,205,171,138,176,186,52,7,107,22,100,67,149,146,69,163,154, +129,51,95,132,112,46,208,143,166,127,7,17,137,70,91,245,27,161,251,63,122, +254,199,157,128,205,244,54,9,72,119,87,189,249,162,162,170,187,126,182, +169,2,91,87,22,65,163,197,174,235,26,122,71,52,140,68,245,164,151,253,170, +136,2,191,132,249,115,36,72,244,255,241,150,32,106,222,254,20,177,104,244, +165,83,213,91,159,162,37,237,118,8,40,149,251,154,46,175,89,144,155,95, +253,131,85,68,95,192,133,171,97,116,14,198,77,87,11,211,8,26,14,232,87, +105,150,130,111,228,187,160,107,58,246,213,182,224,124,160,191,239,244, +254,77,197,180,29,155,13,1,101,109,85,67,215,147,247,85,20,236,188,187, +4,29,131,26,254,211,23,6,157,5,145,149,11,169,89,59,4,116,130,36,2,43,243, +221,88,144,37,225,213,19,29,120,245,189,246,222,143,170,55,207,159,76,66, +158,106,121,99,247,174,123,151,228,61,68,202,155,123,162,232,30,138,129, +195,173,72,183,78,24,199,36,135,72,75,111,24,253,163,10,118,222,179,144, +188,97,20,136,66,99,247,233,253,155,239,72,36,33,37,198,188,114,111,221, +161,187,22,21,110,216,179,165,2,231,130,81,92,25,137,67,38,237,18,153,46, +10,156,233,22,68,81,36,88,153,47,36,172,79,236,155,239,88,24,142,232,184, +17,53,176,113,69,46,46,94,254,202,167,86,108,44,232,57,249,247,38,39,49, +29,2,194,138,157,213,139,50,10,74,254,88,243,216,122,74,50,157,226,29,131, +76,110,148,28,183,219,144,104,65,165,13,153,124,108,133,195,176,114,66, +152,10,209,6,147,112,209,251,247,86,228,161,190,229,202,157,25,69,139,254, +118,237,226,251,3,172,88,116,92,159,86,188,188,110,215,119,151,144,164, +136,246,129,40,41,191,105,185,3,137,44,87,101,9,245,31,180,226,153,63,52, +193,163,42,20,26,217,92,79,124,47,89,70,48,207,106,163,51,21,122,255,209, +111,151,193,87,188,162,142,117,78,16,40,90,187,53,219,227,113,151,111,164, +58,255,226,122,204,180,136,99,206,137,148,8,210,109,90,223,210,22,196,129, +199,215,225,231,47,52,192,235,146,104,77,48,247,38,191,239,192,201,159, +0,121,117,243,234,249,80,20,165,156,117,58,4,164,194,202,7,30,251,206,178, +66,68,168,82,7,198,226,166,219,197,20,144,236,82,24,167,184,86,255,112, +13,246,252,158,73,200,212,152,68,83,89,74,57,66,136,206,22,232,143,202, +242,60,20,145,78,88,252,72,214,237,223,113,103,105,46,41,215,233,197,169, +174,79,114,41,39,26,9,69,168,243,237,107,108,67,213,142,187,240,116,77, +3,60,46,133,14,74,29,14,62,147,101,89,199,202,146,28,72,30,255,14,214,205, +4,220,134,172,150,175,40,201,54,147,69,100,43,110,1,139,0,117,63,143,138, +154,247,187,176,247,161,181,248,233,243,111,194,227,182,194,33,73,41,100, +37,43,33,151,21,103,193,144,92,229,172,155,9,200,6,21,173,199,37,32,70, +29,68,18,82,91,239,128,159,24,21,81,26,17,240,121,93,120,165,57,136,170, +71,214,227,201,3,199,77,79,40,196,32,149,247,98,212,208,56,121,89,39,235, +22,97,85,146,217,189,132,25,98,159,8,126,194,26,149,163,170,130,134,20, +89,174,226,216,197,126,252,226,225,111,97,215,111,234,205,68,181,194,56, +73,214,44,120,3,126,159,236,76,39,65,78,236,163,188,200,117,158,170,227, +113,99,145,205,41,104,152,150,184,20,213,60,152,141,81,40,213,227,134,37, +233,148,158,110,76,109,213,146,33,36,205,70,57,113,83,38,23,104,130,145, +154,64,130,7,162,134,8,23,185,91,176,101,215,150,100,226,185,55,62,196, +95,246,110,163,10,137,155,171,162,48,149,128,64,139,253,67,209,9,29,38, +1,110,159,163,17,182,72,52,243,32,53,1,203,173,124,146,70,14,85,21,197, +148,93,146,151,134,131,181,39,240,250,51,219,17,166,49,205,30,113,114,101, +50,1,55,233,24,141,68,38,246,69,203,159,227,29,29,125,67,180,41,220,178, +2,36,187,119,198,13,217,140,127,113,118,26,94,175,59,129,55,170,182,211, +165,68,131,78,212,4,242,98,42,89,15,233,248,164,147,186,48,233,100,221, +124,92,60,28,234,110,56,219,214,11,159,34,204,162,10,44,2,154,40,99,94, +166,23,117,245,39,240,215,125,219,233,6,100,64,215,173,235,89,74,89,98, +145,70,13,248,92,123,31,198,67,151,27,88,55,19,8,7,254,241,242,225,230, +182,171,228,82,80,87,155,217,11,236,51,141,124,28,19,41,243,143,253,19, +71,246,147,242,184,62,163,229,14,124,42,119,80,141,166,226,0,2,239,188, +124,152,117,243,145,209,225,158,207,174,133,66,3,157,255,186,208,135,12, +234,237,220,205,36,187,110,147,192,217,65,86,110,88,118,7,142,29,105,194, +209,106,182,156,252,200,151,21,8,211,203,216,144,233,204,12,106,59,71,78, +118,64,143,142,117,14,145,78,214,45,57,213,161,141,13,93,26,76,95,188,227, +251,171,74,204,18,138,115,50,78,26,175,206,179,102,73,1,54,173,91,72,146, +84,53,186,117,55,156,110,28,39,194,71,134,69,40,65,15,28,61,143,206,183, +14,62,114,163,47,16,32,177,113,231,62,160,211,194,152,191,172,178,228,171, +152,186,248,158,101,243,204,154,214,141,233,73,240,58,223,7,38,174,229, +51,41,55,19,79,196,156,52,1,207,254,185,25,215,122,2,199,219,142,255,238, +53,18,187,206,169,52,65,128,255,233,61,219,120,33,190,240,190,7,243,231, +102,122,203,10,253,20,107,209,44,169,41,183,30,187,80,173,239,129,25,64, +158,116,211,156,206,240,10,120,177,241,18,90,62,15,14,124,124,224,225,31, +145,104,31,199,127,242,149,140,175,205,122,240,100,237,219,61,89,235,239, +47,204,201,244,46,46,242,155,106,204,54,61,11,55,39,221,156,72,185,135, +102,93,186,23,56,216,208,138,119,207,118,132,154,127,189,109,11,29,211, +67,24,182,141,78,34,192,254,140,242,156,185,114,170,246,157,96,214,250, +109,253,195,113,207,55,23,205,35,43,18,239,131,184,121,239,155,110,228, +82,104,92,212,174,211,168,154,198,194,26,126,121,248,28,206,180,118,15, +146,242,173,252,89,65,24,228,242,155,238,82,234,132,34,194,68,130,167,106, +155,198,178,151,231,159,234,24,41,203,76,247,160,226,107,62,107,204,38, +213,181,5,201,158,17,76,212,227,50,231,13,142,53,119,226,183,71,91,208, +213,254,121,211,153,231,118,238,182,149,135,38,95,203,83,126,152,16,230, +16,242,114,151,110,88,90,186,233,39,191,202,205,205,153,191,174,60,31,149, +84,1,165,121,126,202,234,155,51,133,15,225,86,254,201,151,131,248,248,82, +47,78,127,214,139,241,145,161,174,64,211,11,207,254,183,245,195,86,218, +190,106,39,93,236,182,62,205,8,20,65,204,37,228,120,231,22,206,251,250, +198,221,91,188,249,101,223,19,221,190,18,221,48,166,204,9,35,114,227,203, +209,190,246,119,3,111,29,106,24,27,184,194,117,222,79,224,219,239,216,237, +126,154,37,238,43,54,145,52,66,58,33,131,224,73,184,81,39,134,111,156,48, +100,39,217,168,173,56,246,255,126,156,78,231,17,149,7,154,61,69,167,251, +60,140,219,229,21,77,101,241,228,231,127,2,12,0,35,187,154,106,194,98,206, +112,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_17 = 2315; +static unsigned char xml_res_file_17[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,8,173,73,68,65,84,120,218,172,87,11,80,84,231,21,62,123,239,238, +178,32,225,189,8,136,32,136,202,242,168,10,212,166,81,177,106,173,113,212, +234,198,71,104,199,65,109,106,58,153,105,19,141,161,42,248,76,192,33,22, +147,49,38,169,157,56,101,242,176,81,81,48,157,198,180,77,194,99,81,164, +160,147,162,242,94,65,129,125,47,187,236,238,221,247,171,231,191,185,155, +172,136,200,180,189,51,103,118,247,222,255,254,223,119,94,223,249,151,7, +83,188,182,109,223,17,153,152,144,120,66,36,18,21,39,36,36,136,146,103, +36,193,180,105,211,128,166,105,144,223,187,7,61,61,189,178,147,127,120, +115,37,46,245,29,125,189,98,47,69,81,187,189,94,111,146,88,44,6,141,70, +3,60,30,62,240,122,107,237,14,199,1,92,215,143,235,252,100,95,222,20,176, +233,3,101,135,254,40,16,8,118,73,55,110,128,249,185,57,192,163,40,80,40, +149,208,218,250,47,252,84,65,95,95,95,227,123,167,79,237,192,181,134,242, +227,111,246,37,37,36,38,44,91,190,20,196,113,113,224,247,251,17,156,7,78, +167,19,250,251,239,193,215,245,13,160,80,12,103,158,121,255,189,62,66,130, +255,36,240,125,7,202,106,242,243,242,16,123,61,11,108,101,172,80,223,216, +4,178,230,102,232,234,236,172,100,24,203,112,179,172,169,5,215,186,223, +168,168,236,155,55,119,110,66,97,225,18,232,184,125,23,174,95,111,5,140, +4,107,241,211,227,33,55,59,11,146,147,147,224,131,179,127,238,193,245,34, +52,231,100,4,232,253,165,7,107,242,11,242,164,155,164,27,97,116,212,0,6, +163,17,26,16,188,183,183,87,255,86,213,137,45,184,70,135,102,70,99,246, +150,236,127,126,70,98,18,130,47,70,130,50,240,122,60,128,81,3,179,217,76, +60,134,174,238,46,104,168,175,103,131,78,211,20,217,63,108,50,2,36,236, +232,121,62,130,111,128,7,67,35,96,181,89,161,169,73,6,114,185,92,129,224, +91,113,205,16,9,57,154,11,77,24,17,17,113,148,132,189,227,118,39,11,78, +81,52,91,31,38,147,9,94,63,122,100,13,137,80,208,254,198,192,23,106,98, +240,195,53,63,44,40,144,110,122,110,3,220,127,48,132,155,140,1,133,121, +140,141,141,1,198,98,249,134,3,215,160,217,208,60,104,33,152,235,233,241, +113,98,80,171,213,108,206,41,138,7,124,62,159,45,62,188,6,209,238,4,25, +249,109,37,15,198,71,128,127,240,240,177,218,252,188,133,235,73,206,7,6, +239,99,8,25,112,185,156,224,241,122,97,235,230,77,64,83,212,186,136,200, +72,168,58,81,41,13,122,79,64,138,205,108,177,0,65,36,4,136,247,66,161,32, +216,99,237,68,161,30,31,129,80,30,143,226,192,7,17,220,132,213,235,0,167, +195,9,122,253,40,22,222,117,216,244,156,148,108,190,142,172,13,126,145, +16,224,211,124,182,173,190,5,231,179,53,240,164,70,163,198,21,93,117,126, +222,2,80,170,212,48,54,102,6,187,195,5,14,135,3,236,132,4,182,145,70,171, +131,175,234,27,89,48,174,138,191,187,188,30,151,106,112,112,0,226,177,239, +5,2,62,146,64,227,211,224,247,249,38,37,64,232,241,203,143,87,94,17,139, +227,215,166,166,204,132,140,217,233,108,222,195,195,195,17,216,9,46,52, +7,18,33,105,64,97,129,129,129,65,192,100,131,82,161,168,59,116,168,140, +116,130,23,45,118,247,158,189,117,69,69,69,75,163,163,163,161,95,46,103, +243,47,10,9,1,53,138,80,123,123,59,219,138,44,32,91,31,20,84,30,47,15,33, +5,204,231,194,190,246,197,95,239,100,23,212,55,52,193,32,134,159,20,79, +234,172,52,4,118,129,199,237,98,159,13,13,13,131,72,36,100,211,48,102,208, +73,159,162,125,231,119,151,30,218,246,70,233,129,51,171,214,174,95,58,111, +110,6,252,27,251,159,68,8,21,147,37,145,158,158,14,89,18,9,251,91,32,160, +65,165,84,195,229,186,186,1,174,13,89,2,66,139,197,212,84,115,169,118,153, +4,23,134,134,138,216,192,88,44,12,246,123,31,232,116,26,246,55,217,52,50, +34,2,22,204,159,15,183,218,219,32,43,39,27,62,14,95,182,57,230,200,231, +82,207,28,160,243,127,144,5,109,29,157,96,183,219,208,236,172,247,49,81, +81,236,123,108,129,162,30,116,247,244,64,119,119,55,234,193,215,123,131, +83,240,20,90,218,222,146,125,167,51,231,73,10,103,207,73,7,55,122,45,151, +15,64,111,79,119,125,91,91,235,37,1,95,192,195,40,248,211,82,102,110,217, +184,97,195,242,168,184,233,240,234,55,110,216,179,118,37,180,169,24,104, +31,82,65,138,91,5,175,102,248,96,72,163,135,230,235,45,138,200,200,200, +24,172,148,208,105,97,97,232,140,133,5,195,162,110,249,224,79,103,246,225, +215,7,92,27,187,120,92,43,70,161,165,32,137,183,103,207,206,40,76,78,78, +134,142,142,14,56,84,182,255,105,188,175,231,68,132,148,116,204,214,205, +155,143,245,46,218,181,230,183,207,46,131,187,58,59,168,25,7,184,253,20, +220,188,55,8,235,104,57,248,238,54,106,207,156,61,251,75,174,54,40,28,92, +225,168,13,86,78,47,76,28,112,64,192,252,52,153,94,68,18,201,141,27,45, +215,91,37,89,57,185,24,174,153,140,197,212,114,237,90,115,53,222,87,5,228, +54,116,69,113,140,117,197,75,85,37,107,22,195,109,173,29,84,22,59,184,125, +126,240,160,69,132,71,129,108,216,0,141,111,151,252,12,215,222,71,83,18, +242,12,195,40,57,13,208,112,210,109,10,86,197,224,38,37,100,162,209,146, +208,34,56,241,32,138,71,226,199,139,121,233,221,217,233,217,121,253,21, +235,127,12,87,229,70,80,90,28,44,176,27,253,116,251,121,160,192,57,17,230, +53,193,38,253,151,159,237,59,124,164,8,223,113,4,97,248,31,59,112,130,181, +132,11,11,195,129,147,48,217,201,253,152,223,188,147,134,224,242,242,245, +207,176,224,42,198,142,224,192,130,123,16,92,137,224,94,253,0,124,181,45, +27,36,146,121,153,179,226,197,153,127,175,111,168,157,12,120,162,8,76,40, +84,177,251,206,23,47,202,156,91,253,242,242,133,240,197,56,112,47,130,171, +113,78,120,12,15,224,84,158,0,104,158,15,126,148,191,0,118,254,181,15,218, +245,62,48,153,205,87,116,199,214,109,225,242,15,83,145,226,135,158,197, +148,156,219,190,124,126,78,117,217,179,11,225,106,191,129,205,121,48,184, +206,108,132,97,173,18,36,183,170,255,105,208,169,65,128,2,179,241,195,118, +24,163,34,224,47,219,151,194,178,121,105,27,227,14,214,93,28,23,233,199, +166,224,33,240,232,215,206,21,175,88,56,191,122,247,138,108,184,112,215, +192,86,187,215,255,61,184,222,108,0,165,122,4,140,31,150,21,221,110,254, +242,106,152,80,48,235,111,130,236,52,65,124,26,252,126,85,14,252,67,110, +129,95,44,72,6,181,213,43,209,73,86,229,218,100,23,46,77,148,146,137,82, +192,143,46,171,187,248,98,97,129,116,109,110,50,92,236,28,69,112,231,4, +224,195,96,188,80,249,188,237,78,211,77,174,224,18,231,190,115,227,230, +39,59,158,134,183,26,181,96,69,45,153,21,21,6,91,179,99,224,84,67,39,52, +118,245,215,233,203,165,1,233,126,108,4,232,232,210,218,154,61,171,23,75, +127,154,153,8,23,187,70,65,243,56,240,79,43,182,216,238,54,183,225,59,234, +64,167,240,114,86,20,92,233,181,166,122,169,112,32,135,30,135,219,3,35, +22,15,252,106,81,42,104,48,18,218,9,34,65,63,228,121,105,237,37,2,94,152, +17,15,53,232,185,198,58,49,184,179,171,165,194,84,255,201,231,28,184,147, +211,18,191,173,165,246,70,104,238,146,108,15,95,152,26,34,138,100,227,107, +119,77,78,34,64,128,22,151,213,158,221,245,147,69,69,43,209,243,71,193, +177,47,25,11,40,84,15,192,217,121,237,184,254,211,242,143,56,129,114,4, +121,67,72,184,153,27,159,181,134,228,44,145,184,105,97,170,48,244,201,36, +2,4,166,197,174,121,225,98,233,234,5,88,112,193,224,126,214,115,6,15,36, +35,202,1,112,220,145,85,232,207,31,255,152,3,183,143,43,170,239,20,117, +50,18,47,32,9,173,205,39,209,103,175,206,179,54,157,175,9,180,161,104,142, +56,10,31,224,206,152,243,111,91,237,123,240,251,35,253,224,54,168,101,8, +126,142,147,88,43,7,56,254,242,6,20,84,117,114,231,30,70,209,35,211,106, +135,193,138,194,107,69,37,24,54,57,224,114,183,17,74,86,101,225,31,2,1, +123,170,10,16,160,212,22,27,80,56,150,8,56,177,96,112,207,168,74,166,170, +218,254,10,151,243,199,129,79,74,194,134,36,108,72,66,201,184,224,149,218, +91,192,99,140,77,100,192,5,82,16,198,43,248,249,150,172,153,113,81,26,59, +31,156,184,133,25,143,225,67,138,123,168,114,170,102,213,201,29,123,112, +205,48,55,148,188,83,248,55,229,127,36,29,252,144,84,81,88,52,178,26,130, +17,121,167,76,83,85,252,50,62,31,13,232,0,38,10,50,18,202,46,215,242,68, +97,41,120,162,102,143,78,94,237,240,23,170,83,187,14,114,67,201,56,69,112, +152,96,192,165,36,190,246,209,105,161,56,249,25,151,110,164,69,85,85,252, +59,110,207,177,0,1,50,235,99,209,102,112,147,144,226,70,166,145,43,184, +177,201,244,124,138,36,2,83,214,204,213,17,235,80,176,18,10,184,115,154, +144,83,72,31,215,102,246,255,194,243,71,212,149,59,198,11,56,199,236,255, +131,67,255,223,235,63,2,12,0,116,106,129,252,126,87,16,179,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_18 = 2051; +static unsigned char xml_res_file_18[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,165,73,68,65,84,120,218,156,87,125,108,85,103,25,255,189,231,227, +158,123,123,251,129,165,45,216,58,235,112,165,104,132,208,144,97,34,211, +12,199,88,2,24,166,76,103,166,243,47,157,157,78,99,252,136,35,200,76,101, +113,97,14,51,201,22,182,37,115,38,186,153,45,51,196,101,76,145,5,134,5, +66,183,21,16,18,217,40,116,163,31,72,75,139,180,183,189,31,231,158,15,127, +207,123,206,45,183,176,10,235,73,159,158,243,190,247,61,239,243,123,127, +207,239,121,222,247,40,204,238,178,58,158,124,241,101,195,180,214,135,97, +120,221,47,41,165,16,248,222,95,127,249,253,187,239,98,211,211,125,179, +113,254,208,246,23,118,134,202,92,183,100,73,11,130,48,0,174,7,3,61,25, +202,192,241,227,61,80,161,255,234,175,126,120,207,151,75,32,62,236,85,181, +249,137,23,67,159,75,207,185,126,56,89,240,174,219,100,188,188,39,239,203, +60,122,53,179,0,144,12,124,31,110,209,199,190,99,189,248,16,17,96,8,128, +149,75,23,64,222,151,121,104,153,217,0,80,18,119,113,44,19,126,177,109, +65,212,27,78,253,155,241,218,123,236,61,248,65,200,176,133,83,225,183,102, +37,65,121,223,48,144,176,44,108,123,249,128,22,87,105,198,176,4,164,140, +26,121,10,232,120,121,235,13,116,142,105,191,89,211,84,109,81,213,193,181, +57,149,21,60,242,212,75,250,217,160,115,21,243,43,119,59,149,66,162,234, +35,116,24,160,148,33,97,137,25,21,70,253,229,138,22,219,252,187,231,119, +22,253,96,93,219,226,5,215,165,234,16,229,116,171,169,84,82,134,194,209, +35,39,81,147,78,162,117,225,141,240,253,203,32,228,146,182,23,78,239,19, +0,41,24,230,186,77,15,220,13,145,134,49,203,194,16,198,118,199,45,109,216, +242,219,63,226,123,95,91,133,162,23,148,209,173,176,231,200,41,4,94,120, +21,128,164,32,227,80,252,160,227,25,36,19,6,204,56,152,83,225,68,89,187, +44,132,83,109,78,46,145,43,250,33,182,109,188,79,139,97,235,75,157,154, +238,210,123,18,182,101,45,141,154,225,43,1,168,144,3,11,69,160,182,42,133, +191,140,180,33,149,80,112,28,19,182,99,83,104,10,137,132,5,155,168,18,52, +155,109,155,52,137,113,24,108,26,49,211,167,129,244,217,61,4,225,67,17, +141,101,88,8,149,196,59,90,156,138,181,229,249,87,3,128,12,43,184,30,210, +41,113,200,152,36,13,56,52,155,179,59,244,100,90,145,99,13,192,136,1,208, +177,101,134,176,57,151,101,68,43,76,37,109,20,10,30,29,152,88,126,211,39, +53,3,174,114,225,154,17,237,158,235,106,13,148,107,44,202,2,14,204,187, +62,233,183,161,108,19,166,99,192,146,123,194,100,91,0,208,76,3,6,65,24, +4,192,63,138,62,212,119,131,119,165,57,134,126,95,22,98,4,9,60,81,152,7, +145,192,183,43,70,176,246,201,109,116,234,99,103,123,59,139,16,62,128,1, +118,20,138,46,146,164,156,169,168,29,26,182,69,51,35,147,182,24,25,32,14, +173,17,185,147,100,88,2,68,138,139,167,144,36,3,121,2,8,248,251,200,33, +106,66,184,191,221,196,249,87,30,137,116,115,255,253,4,21,76,223,88,74, +50,202,83,4,78,34,193,85,27,218,169,178,204,8,12,159,45,75,194,97,68,33, +48,37,246,12,7,29,123,158,199,204,97,152,18,146,62,33,42,28,135,11,41,178, +218,229,177,249,214,33,29,111,183,152,65,215,238,65,2,8,96,20,178,188,251, +31,192,128,136,208,45,234,21,24,6,29,27,178,98,83,135,193,74,68,119,143, +78,71,93,32,199,52,26,203,121,90,84,97,145,241,38,136,128,171,206,231,129, +205,139,146,96,152,17,6,228,38,84,58,169,109,134,195,116,165,252,250,4, +102,144,41,92,85,136,52,162,60,197,227,48,134,6,185,213,113,167,89,100, +32,235,43,12,184,138,0,12,93,104,36,224,182,163,68,206,58,221,196,79,192, +127,62,199,85,166,230,224,244,249,127,226,52,30,196,67,127,235,67,57,219, +139,26,150,98,121,243,79,208,210,180,129,176,172,43,53,0,198,142,12,144, +75,17,154,69,6,24,89,12,23,200,140,178,160,36,44,4,35,236,136,152,66,229, +151,10,60,65,113,172,73,214,204,36,222,62,119,31,222,189,180,11,107,62, +255,85,44,110,254,49,69,89,161,199,229,220,44,78,156,61,128,87,187,239, +197,80,110,55,157,110,184,50,11,124,166,79,81,51,32,69,165,64,170,38,115, +76,78,198,94,113,181,161,172,158,78,124,10,19,92,169,222,47,152,227,236, +212,21,142,249,131,134,226,122,156,207,239,197,198,13,219,209,63,246,38, +254,209,179,9,67,19,147,122,250,121,149,105,124,102,254,157,216,116,215, +118,108,127,237,103,204,156,225,41,0,70,137,129,44,227,104,147,129,12,87, +61,144,241,144,41,42,76,80,217,25,207,64,198,143,173,24,183,99,155,96,60, +39,61,178,230,238,67,163,243,58,218,215,252,26,157,103,31,69,87,255,159, +112,49,55,137,29,235,67,109,242,220,213,255,60,14,244,61,138,7,214,60,12, +55,253,6,110,254,14,22,11,122,171,180,91,21,40,40,187,198,65,231,183,210, +48,74,149,61,20,170,179,151,171,125,88,218,197,227,237,151,33,177,140,20, +182,254,253,97,180,54,127,29,71,207,253,1,163,217,1,93,152,92,53,253,32, +34,125,242,219,177,115,207,97,237,178,123,241,194,165,103,59,248,83,167, +21,159,48,168,169,16,199,123,47,226,95,167,71,167,85,249,255,119,226,49, +24,2,75,85,227,112,239,97,220,122,115,27,246,191,255,14,43,29,163,196,232, +184,101,2,148,103,51,136,106,71,127,230,223,88,121,227,42,10,29,43,100, +35,20,0,225,196,196,248,193,163,93,135,86,132,165,189,122,106,35,138,78, +47,21,73,7,147,217,124,124,226,0,210,21,73,100,243,5,50,69,241,161,26,102, +10,24,206,119,235,154,255,155,213,87,35,222,241,165,203,125,15,190,174, +40,196,183,74,91,184,84,126,228,127,191,245,231,223,229,189,174,236,128, +162,62,119,219,186,214,213,95,249,230,182,156,175,156,101,75,23,162,247, +63,163,83,147,44,248,232,92,116,31,59,133,234,36,247,253,79,124,10,39,187, +129,9,183,79,211,124,173,75,88,144,177,49,0,173,129,28,173,143,54,92,118, +76,79,174,186,243,27,123,84,170,2,14,249,172,172,74,227,182,198,250,169, +115,224,133,76,22,78,202,129,71,13,156,236,233,213,125,151,242,231,185, +139,178,24,237,83,186,4,231,41,208,199,239,136,86,254,163,221,44,211,86, +180,131,202,152,177,252,32,226,83,156,94,177,156,205,51,177,149,174,90, +151,37,245,211,31,155,135,241,201,28,122,206,12,224,84,153,24,228,12,216, +80,55,7,213,233,52,222,57,209,143,133,13,43,48,122,241,32,230,215,71,43, +20,13,24,101,108,84,208,105,133,29,239,31,204,220,225,11,220,39,178,56, +34,1,157,233,80,106,121,172,116,77,245,53,104,110,170,199,232,216,164,174, +241,165,44,112,108,27,115,107,210,80,92,234,9,175,7,222,224,74,156,153, +56,136,198,6,6,213,142,138,164,83,54,25,247,56,72,9,17,231,178,115,158, +121,15,24,236,198,227,162,79,115,6,0,78,117,109,253,133,75,185,112,117, +37,227,188,248,166,38,44,108,110,68,243,252,90,90,29,170,28,11,167,201, +202,222,67,221,120,243,141,93,27,119,62,179,227,177,186,69,168,25,47,48, +27,155,232,200,138,118,204,253,125,29,232,28,232,0,183,24,13,76,72,57,252, +54,211,177,15,175,188,245,28,158,102,243,191,51,125,154,81,215,104,156, +219,208,216,178,230,158,246,95,84,206,153,187,34,58,45,71,20,72,8,38,198, +70,14,190,246,231,167,183,140,14,157,123,95,132,44,97,251,194,79,177,165, +238,6,172,109,109,97,245,155,23,1,209,167,32,6,121,104,8,120,183,135,206, +251,177,107,255,99,216,200,238,179,18,246,153,0,8,88,97,177,150,70,98,153, +107,211,191,33,68,55,227,177,112,47,198,109,249,212,106,106,185,29,183, +124,252,179,104,79,84,99,73,217,193,25,238,56,142,247,117,225,169,158,61, +56,192,158,65,218,24,116,97,191,198,135,104,204,134,115,197,129,89,82,190, +16,103,80,233,3,83,194,153,142,65,75,74,87,198,125,250,68,78,155,160,141, +196,128,39,227,190,89,125,29,95,227,27,24,118,12,58,81,54,191,112,225,198, +128,139,229,223,112,255,19,96,0,111,126,151,122,57,77,224,198,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_19 = 2007; +static unsigned char xml_res_file_19[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,121,73,68,65,84,120,218,172,87,13,108,85,103,25,126,190,239,156, +115,127,90,74,41,163,180,182,118,115,117,64,21,232,214,176,117,70,22,163, +27,209,17,152,110,254,85,97,63,49,76,129,110,26,166,38,58,38,234,28,209, +204,13,19,204,36,203,100,66,54,49,25,3,231,72,97,108,83,144,159,110,176, +78,91,58,129,149,50,170,164,98,88,215,206,246,246,254,157,191,207,231,59, +247,220,114,239,150,74,169,158,244,237,119,207,189,231,156,231,125,159, +231,125,191,247,61,2,147,59,204,7,127,245,204,14,105,152,159,83,74,77,248, +38,33,4,124,207,125,254,71,247,180,124,145,167,110,240,221,100,192,127, +248,203,223,61,167,132,177,180,177,113,22,124,229,3,19,241,129,72,82,72, +116,119,247,66,40,175,237,39,223,90,118,91,222,137,75,61,202,214,61,246, +140,242,24,122,218,246,84,50,235,78,216,244,245,250,62,125,191,126,78,16, +205,36,28,136,249,158,7,219,241,176,191,235,12,46,65,1,74,0,124,234,154, +122,232,251,245,115,104,137,201,56,32,180,238,26,88,63,240,198,166,250, +220,183,106,236,223,184,199,190,174,62,120,190,162,108,106,76,126,115,82, +41,168,239,151,18,17,211,196,134,29,135,131,228,202,63,81,229,29,41,160, +70,127,242,9,220,60,167,142,224,40,250,205,44,202,106,147,89,237,95,156, +83,29,193,207,30,223,30,124,150,4,23,33,191,122,181,226,113,68,202,42,8, +232,35,95,33,42,207,140,80,185,239,11,51,90,219,186,141,219,158,115,60, +127,105,211,252,250,9,101,181,66,33,221,98,172,148,132,20,232,252,235,73, +148,151,198,48,103,246,149,240,188,11,78,232,195,37,184,11,85,148,55,218, +129,56,164,177,244,129,123,91,160,83,67,78,114,99,80,161,125,230,134,38, +60,244,139,167,209,250,229,69,112,92,63,160,91,137,128,42,188,212,245,22, +60,189,23,200,98,9,98,218,83,94,138,111,62,248,4,98,17,9,35,20,115,76,78, +20,156,23,72,56,118,78,14,180,114,142,167,176,225,254,111,4,201,240,240, +246,67,1,221,250,87,159,160,14,35,107,57,105,99,112,215,105,216,149,162, +200,1,161,120,97,214,1,166,151,197,177,243,157,38,196,35,2,209,168,1,43, +106,49,209,4,34,17,19,22,189,138,208,44,158,91,124,152,54,94,6,139,70,159, +137,41,81,250,143,151,233,132,7,65,111,76,105,50,242,156,222,158,65,240, +19,89,148,92,61,23,163,201,36,86,188,113,12,27,67,7,2,198,245,101,89,219, +69,105,92,3,82,147,152,68,60,78,139,10,148,240,115,52,112,40,52,43,52,237, +72,132,14,240,122,22,3,132,161,120,159,133,108,150,42,43,3,205,87,125,24, +215,210,154,174,170,67,109,170,15,123,171,123,145,30,73,33,53,154,194,112, +85,29,58,214,108,57,79,232,72,174,10,200,64,198,246,72,191,5,97,25,48,162, +18,166,94,35,6,207,41,137,73,51,36,36,65,37,181,228,31,147,94,5,171,228, +42,130,58,67,112,191,14,68,168,8,54,218,85,176,249,221,151,122,118,226, +218,230,102,148,79,159,138,205,79,109,193,205,114,17,50,233,12,34,118,86, +35,151,202,124,89,101,29,27,49,82,206,82,36,160,9,105,105,51,194,149,22, +201,173,134,118,44,112,206,12,156,212,38,233,160,144,6,98,100,64,7,226, +9,19,231,142,0,63,255,253,92,68,167,76,195,148,242,105,232,61,117,26,85, +21,51,240,236,200,31,80,221,223,131,235,55,173,250,88,193,62,160,144,97, +18,68,35,17,62,88,6,192,194,52,114,206,104,16,2,88,100,34,200,1,67,107, +207,124,96,216,174,235,178,114,40,71,36,39,102,60,26,69,146,91,116,146, +140,60,126,238,35,104,104,253,2,26,106,106,241,216,182,131,48,156,81,156, +60,126,130,82,1,91,230,6,109,96,128,150,52,115,10,48,9,109,39,136,64,50, +18,41,53,221,185,232,204,72,110,117,9,58,104,3,105,87,97,56,237,6,137,166, +28,234,77,39,124,210,158,201,10,220,223,80,130,17,219,192,138,129,251,208, +216,122,7,80,253,53,224,149,31,227,94,119,59,214,252,125,29,88,36,248,206, +218,245,216,180,117,135,134,29,165,217,102,174,172,52,3,46,35,161,3,212, +58,208,157,102,146,129,148,39,208,111,11,58,32,131,141,70,11,110,49,25, +225,122,65,185,233,26,247,249,47,235,243,250,248,52,204,120,114,30,22,172, +190,157,224,43,8,254,16,112,170,77,103,40,174,62,191,25,149,173,251,144, +78,167,243,205,168,160,10,232,89,70,51,64,46,117,162,153,100,128,41,134, +183,179,62,6,8,238,235,4,164,230,134,150,136,121,160,229,17,134,17,56,164, +181,119,140,40,82,178,20,205,127,92,146,3,255,192,215,129,87,53,248,174, +160,229,111,58,82,131,219,158,124,11,118,54,9,155,201,151,219,31,10,123, +129,239,177,124,156,128,1,189,169,232,104,146,105,22,167,78,46,70,171,116, +244,4,244,116,205,145,145,160,95,72,62,132,181,238,144,129,97,21,195,129, +115,245,152,189,242,46,70,174,193,215,135,224,14,193,171,209,178,245,77, +188,120,224,13,152,194,99,222,120,69,219,243,24,3,41,234,104,145,129,4, +163,238,79,184,72,240,201,163,174,64,194,149,72,120,161,57,225,121,96,6, +134,61,11,67,254,20,236,239,187,8,248,190,46,220,188,112,62,244,134,231, +49,88,37,138,123,65,208,173,178,76,40,171,60,138,67,119,150,66,230,119, +118,69,173,84,234,194,110,175,242,93,92,192,147,22,183,215,82,12,255,244, +114,204,94,125,231,123,192,73,251,209,106,124,133,224,123,254,212,137,37, +159,104,194,158,63,191,198,156,50,130,6,245,190,118,204,9,131,57,165,208, +125,102,8,199,78,15,22,237,242,239,159,120,152,144,48,144,33,237,139,95, +93,130,235,90,239,10,53,15,193,165,135,39,94,171,193,242,45,199,177,123, +127,23,110,249,100,19,215,163,184,229,198,235,241,194,193,215,137,83,220, +33,181,3,106,116,116,164,189,243,232,43,11,85,190,87,143,53,162,220,244, +82,18,99,125,167,50,65,207,247,9,46,153,237,171,254,189,22,77,247,104,240, +187,139,192,55,191,94,139,211,205,143,224,197,67,212,156,174,238,61,208, +17,236,162,123,184,234,161,212,11,230,132,98,9,50,191,121,248,123,43,185, +206,40,24,80,196,199,111,90,58,231,211,159,191,125,67,218,19,209,5,215, +204,198,153,127,13,6,229,228,200,24,62,219,209,130,198,85,203,73,123,49, +248,175,59,106,80,118,119,27,154,157,4,213,179,115,114,9,81,48,122,171, +160,89,189,151,129,52,237,44,237,237,130,49,61,182,232,214,229,47,139,120, +9,162,164,108,74,89,41,110,170,153,201,182,106,97,176,251,121,76,93,244, +85,160,238,219,192,1,90,239,110,130,171,32,242,169,43,218,96,216,9,102, +181,29,200,90,56,172,92,120,47,240,195,223,46,56,160,103,243,68,104,249, +99,186,237,56,248,232,7,171,48,146,76,163,247,76,63,78,41,210,39,163,104, +28,232,192,135,110,125,4,110,223,94,136,108,6,6,35,223,218,121,5,166,173, +220,205,237,118,132,251,130,23,204,139,227,142,115,122,126,44,248,125,188, +161,212,212,245,90,91,89,142,43,106,43,49,52,156,98,103,19,48,250,247,227, +186,6,222,210,223,6,57,244,38,78,244,189,139,99,39,234,112,184,238,251, +176,94,160,67,190,131,139,205,233,122,243,202,36,19,237,249,76,31,207,1, +247,111,127,105,255,46,231,164,71,23,204,111,64,211,188,89,168,152,81,137, +205,207,254,0,199,205,56,214,44,62,136,157,187,142,160,39,178,16,135,207, +86,173,109,223,180,172,3,19,123,63,66,200,248,59,58,247,254,219,171,89, +156,86,115,217,204,154,89,139,151,173,122,160,172,98,230,13,229,94,63,186, +59,123,112,229,212,119,81,85,63,15,61,233,203,219,247,62,189,97,253,224, +249,127,246,241,218,17,61,248,92,194,248,152,9,115,207,29,207,1,45,82,84, +231,2,109,38,237,178,251,86,223,241,212,192,217,99,219,126,187,187,251, +37,221,197,66,80,157,184,67,225,3,213,100,134,217,139,189,156,154,33,27, +21,180,242,96,127,205,1,107,7,178,249,40,240,63,28,19,125,59,182,66,70, +188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, +73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_20 = 2051; +static unsigned char xml_res_file_20[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,165,73,68,65,84,120,218,156,87,107,112,21,103,25,126,190,221,61, +187,231,228,228,2,185,181,73,4,148,66,130,117,200,52,182,214,81,42,14,45, +86,7,80,212,233,216,17,157,78,127,56,26,188,212,209,254,160,25,172,12,242, +163,211,25,227,84,165,78,107,157,90,111,197,214,58,12,140,69,7,28,138,66, +25,29,36,164,212,182,16,174,197,96,106,110,36,57,201,185,236,213,231,221, +221,115,56,73,154,66,115,38,111,118,191,189,124,239,243,62,239,243,190, +223,183,10,243,251,25,219,31,127,238,5,77,55,54,6,65,112,221,47,41,165, +224,123,238,158,109,223,184,247,30,14,221,240,218,124,156,127,255,39,207, +238,14,148,190,161,189,125,57,252,192,7,174,7,3,61,105,74,195,201,147,103, +160,2,239,79,63,120,96,211,231,138,32,222,237,175,234,225,157,207,5,30, +67,207,217,94,48,85,112,175,219,228,121,121,79,222,151,121,194,104,230, +1,32,233,123,30,108,199,195,75,189,231,241,46,50,192,20,0,107,110,89,10, +121,95,230,161,101,230,3,64,73,222,197,177,76,120,103,199,210,232,106,80, +250,55,231,239,96,239,5,120,126,192,180,5,165,244,27,243,146,160,188,175, +105,48,13,3,221,47,28,9,197,85,156,49,40,2,41,163,70,206,124,58,190,189, +109,17,157,99,218,61,99,154,170,13,170,218,191,54,167,18,193,35,79,60,31, +158,107,116,174,98,126,229,152,72,165,96,86,45,164,67,31,197,10,9,138,204, +168,32,186,94,174,104,177,135,127,252,187,221,142,231,111,232,88,185,244, +186,84,29,160,156,110,85,42,37,165,41,156,232,121,3,53,233,36,218,90,223, +7,207,187,10,66,126,50,118,131,233,215,4,64,10,154,190,97,235,55,239,133, +72,67,155,103,99,8,98,251,228,29,29,216,241,163,223,224,235,95,88,11,199, +245,203,232,86,56,208,211,7,223,13,102,1,72,10,50,62,138,111,109,255,57, +146,166,6,61,78,102,41,157,40,27,151,165,176,52,230,228,146,57,199,11,208, +221,245,213,80,12,143,62,127,56,164,187,248,158,164,237,214,229,205,33, +195,51,1,168,128,15,22,28,160,182,42,133,63,14,119,32,101,42,88,150,142, +132,149,160,208,20,76,211,64,130,168,76,90,130,227,4,105,18,227,99,72,208, +136,153,62,53,164,223,60,64,16,30,20,209,24,154,129,64,73,190,163,224,84, +172,45,215,155,13,0,242,88,193,118,145,78,137,67,230,36,169,193,162,37, +56,187,69,79,186,17,57,14,1,104,49,0,58,54,244,0,9,206,101,104,81,132,169, +100,2,133,130,75,7,58,110,95,118,83,200,128,173,108,216,122,68,187,107, +219,161,6,202,53,22,85,1,31,204,219,30,233,79,64,37,116,232,150,6,67,142, +166,206,177,0,160,233,26,52,130,208,8,128,127,20,125,16,30,53,30,85,200, +49,194,247,37,16,205,55,177,179,112,3,68,2,95,169,24,198,250,199,187,233, +212,195,238,206,78,54,33,188,13,3,188,80,112,108,36,73,57,75,49,116,168, +37,12,154,30,153,140,197,200,0,113,132,26,145,35,73,134,33,64,164,185,184, +10,73,50,144,39,0,159,247,135,143,82,19,194,253,39,116,188,181,247,145, +72,55,155,55,19,148,63,125,97,41,202,40,79,17,88,166,201,168,181,208,169, +50,244,8,12,207,13,67,210,161,69,41,208,37,247,76,7,29,187,174,203,202, +97,154,76,41,159,0,21,150,133,60,3,113,130,60,182,174,121,43,204,183,237, +78,224,31,251,251,9,192,135,42,228,24,172,247,54,12,136,8,109,39,140,64, +211,232,88,147,136,245,48,13,134,25,29,93,58,29,177,129,28,203,104,60,231, +134,162,10,28,230,155,32,124,70,157,47,0,91,87,88,200,178,18,10,204,77, +214,244,88,247,34,65,45,202,15,185,23,183,158,95,214,152,138,0,4,81,158, +226,177,152,67,141,220,134,121,167,25,100,32,235,41,244,219,138,0,180,176, +209,72,194,19,150,18,57,135,229,22,40,132,37,104,243,196,172,170,134,253, +239,19,248,216,193,103,176,240,151,223,13,213,31,174,25,252,103,127,104, +13,114,235,190,8,103,241,90,248,12,114,134,6,192,220,145,1,114,41,66,51, +200,0,51,139,193,2,153,81,6,148,164,133,96,132,29,17,83,160,188,98,131, +39,40,13,110,194,132,163,153,104,217,243,11,212,28,123,9,43,63,245,105, +44,232,188,31,122,170,34,138,58,155,197,149,87,123,209,191,179,11,133,83, +199,224,212,119,204,172,2,143,229,227,132,12,72,83,41,248,26,166,114,44, +78,230,94,49,218,64,162,215,117,120,20,38,200,72,184,94,176,198,73,23,163, +97,90,148,137,239,252,245,65,52,142,29,199,242,45,219,80,56,251,58,50,187, +158,130,59,52,16,57,105,104,66,213,135,87,163,253,161,109,56,245,179,199, +208,209,56,80,2,160,21,25,200,50,143,9,50,144,97,212,253,25,23,25,71,97, +146,202,206,184,26,50,94,108,78,60,46,26,155,215,132,151,192,77,255,249, +23,214,14,252,29,173,155,191,141,236,158,93,200,239,223,3,76,102,96,164, +171,67,147,115,185,150,231,189,247,119,62,128,246,129,215,208,125,243,226, +149,210,159,140,226,106,85,160,160,18,53,22,14,223,151,134,86,236,236,129, +80,157,189,218,237,131,226,42,30,47,63,164,223,75,86,96,104,203,211,104, +92,127,15,242,135,254,2,111,240,50,180,100,50,218,44,148,150,41,121,215, +8,239,21,254,182,15,139,214,109,196,7,126,255,219,237,188,113,216,136,119, +24,212,84,128,147,231,71,241,202,217,145,105,93,254,29,119,60,4,224,36, +211,88,125,232,0,106,30,124,8,83,71,254,12,197,86,28,176,227,205,94,82, +85,148,198,115,167,177,176,227,35,72,234,218,42,89,8,5,64,48,57,57,241, +242,137,127,30,93,21,20,215,234,210,66,20,237,94,42,146,22,166,178,249, +120,199,1,164,43,146,200,74,221,17,64,222,172,192,234,4,59,104,255,5,54, +40,133,154,23,123,223,113,213,28,223,120,27,212,165,115,69,120,210,249, +145,127,250,209,45,95,227,177,190,108,131,162,62,122,215,134,182,187,63, +255,229,238,156,167,172,91,111,105,197,249,129,145,210,36,75,155,234,112, +188,183,15,149,41,11,139,86,44,3,254,64,41,141,93,97,3,75,94,115,217,14, +159,225,179,44,31,20,53,144,163,93,162,13,150,37,45,185,246,179,95,58,160, +88,70,22,59,71,101,85,26,119,53,55,148,246,129,67,153,44,44,58,247,72,233, +169,190,11,104,147,53,111,108,20,122,117,13,38,55,221,25,54,167,89,185, +147,29,147,116,86,62,227,143,141,197,26,137,34,150,189,121,38,182,226,175, +214,118,28,220,252,158,27,48,49,149,195,153,115,253,232,43,155,80,246,128, +141,245,11,80,153,174,192,43,167,47,34,127,219,199,49,49,126,25,181,13, +245,240,172,100,212,106,103,75,32,124,143,31,51,24,30,27,199,132,235,245, +32,148,230,28,31,31,46,59,93,75,67,13,150,180,52,96,100,124,138,85,226, +148,170,192,98,206,235,106,210,144,229,238,196,171,167,177,127,225,10,84, +191,209,131,250,166,38,70,105,198,155,142,217,91,114,45,162,29,111,14,12, +97,255,224,216,99,60,181,245,57,0,88,213,181,13,67,99,185,224,238,74,150, +212,202,101,45,104,93,210,140,37,55,214,210,234,81,101,25,56,75,86,14,30, +61,142,99,135,246,117,61,251,204,79,127,184,170,38,85,227,230,242,109,45, +55,54,177,107,74,75,231,130,38,235,10,143,122,184,194,82,168,4,112,252, +245,83,56,51,54,185,183,235,181,139,79,210,207,149,185,62,205,82,180,230, +186,198,230,229,235,54,117,126,175,114,65,221,170,104,183,28,81,32,84,78, +142,15,191,188,111,215,147,59,70,254,247,223,139,34,100,73,219,175,62,184, +124,71,107,109,245,250,101,239,93,140,250,122,106,218,136,9,166,38,134, +135,135,113,246,226,37,156,30,205,188,120,127,79,95,151,16,33,105,159,11, +128,112,101,201,164,180,70,90,245,140,111,8,209,205,68,44,220,209,120,44, +159,90,45,247,45,110,188,227,51,77,181,157,117,134,222,126,117,59,10,140, +184,222,201,189,3,163,79,252,250,210,224,17,14,47,75,69,34,108,236,215, +248,16,141,217,176,102,108,152,101,161,43,196,21,84,252,192,148,116,166, +99,208,82,210,149,241,181,112,71,78,155,164,13,199,128,167,226,107,243, +250,58,190,198,55,48,18,49,104,115,122,47,134,29,3,118,202,219,228,255, +5,24,0,238,123,163,24,29,62,142,101,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_21 = 1382; +static unsigned char xml_res_file_21[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,5,8,73,68,65,84,120,218,188,87,221,107,28,85,20,255,221,123,247, +35,219,205,182,214,26,65,76,137,77,95,170,144,244,69,13,66,13,81,40,166, +44,125,16,95,20,130,246,161,224,187,208,7,65,124,240,73,168,138,255,64, +177,196,40,197,135,250,17,107,179,20,2,106,181,95,84,209,68,12,213,52,164, +105,83,76,98,83,106,147,184,51,115,239,245,156,59,119,55,187,178,205,206, +34,102,147,147,201,206,204,189,231,55,191,243,59,31,3,108,238,71,76,95, +248,178,184,58,247,67,244,193,145,126,75,223,51,169,205,114,124,169,244, +225,174,71,118,118,126,42,97,122,69,42,13,37,36,159,207,203,77,112,174, +230,127,42,125,178,187,187,107,122,109,233,183,222,185,179,199,96,162,8, +66,8,190,150,110,198,64,234,163,55,6,63,203,101,100,81,210,2,145,208,163, +177,22,65,16,160,187,103,31,186,30,123,10,225,234,45,220,152,248,14,209, +234,50,64,215,140,53,80,42,126,246,102,0,114,217,148,40,190,117,106,141, +130,69,0,18,34,48,198,98,229,239,0,151,15,237,195,181,159,199,113,119,105, +22,66,146,43,50,107,66,88,77,12,200,100,0,218,68,140,2,109,116,103,43,0, +172,77,227,250,247,35,88,43,27,90,199,110,200,33,61,57,253,194,16,0,229, +55,107,6,64,8,43,192,244,51,96,153,16,0,7,75,41,5,75,139,140,224,144,192, +81,15,27,135,71,235,176,162,1,36,200,2,11,73,241,106,5,0,127,248,126,118, +70,207,28,3,0,124,252,233,124,20,186,61,19,1,16,70,130,239,149,210,38,7, +64,247,17,1,68,55,135,194,186,135,175,0,176,158,129,74,8,26,165,97,230, +224,123,176,207,29,197,73,6,40,53,135,64,17,101,178,101,211,4,192,104,235, +52,81,103,77,68,152,215,36,148,254,93,120,254,175,55,177,34,202,202,161, +85,196,64,82,17,114,172,37,209,101,109,3,6,232,71,135,161,211,213,189,24, +72,7,26,120,161,239,117,60,219,139,161,177,194,57,40,155,165,5,41,218,84, +182,96,202,229,187,211,129,55,205,71,206,2,42,68,170,134,129,116,241,29, +44,134,26,219,220,69,66,187,86,166,35,114,24,236,125,17,37,117,2,191,47, +127,3,59,57,0,153,9,9,178,78,34,1,167,25,237,247,51,46,1,4,57,39,86,72, +83,145,11,193,122,22,228,217,249,241,87,143,225,86,249,115,174,156,180, +144,110,176,247,99,98,254,4,14,244,190,12,153,30,198,121,249,53,212,47, +207,208,198,1,237,110,18,132,192,198,34,52,113,8,216,121,247,67,51,232, +216,58,143,185,104,176,210,11,28,128,12,63,249,157,242,2,190,189,242,197, +122,185,21,163,228,24,152,252,99,24,131,61,135,40,109,142,227,162,28,71, +219,212,0,237,30,197,94,54,0,192,89,160,141,113,79,175,173,112,212,63,120, +223,18,134,75,143,98,160,168,171,12,84,53,176,162,231,41,24,112,38,50,100, +124,36,120,150,54,186,242,231,199,120,98,207,30,68,157,55,221,73,167,114, +217,204,84,141,8,125,45,32,159,249,92,26,38,12,156,78,170,89,192,88,86, +237,13,168,44,170,12,88,83,83,80,82,1,46,77,79,33,51,223,233,106,2,152, +62,97,55,46,68,194,23,34,91,209,129,113,44,108,201,166,17,82,33,242,17, +136,25,224,77,67,117,19,217,60,197,99,11,145,144,163,11,153,216,82,109, +192,236,34,112,161,212,69,244,239,39,2,168,182,43,56,10,155,153,246,121, +111,201,179,37,0,11,183,119,224,192,147,63,82,33,138,234,52,192,0,238,30, +29,62,215,206,8,89,48,148,37,120,229,165,56,202,87,175,3,151,199,186,80, +184,186,31,50,27,120,200,178,169,8,149,18,113,231,179,194,237,73,42,192, +212,181,157,56,125,62,143,190,167,203,117,205,40,56,117,4,253,116,220,238, +163,145,30,124,27,167,153,133,95,167,129,197,241,14,20,166,73,181,25,202, +77,105,155,59,175,134,64,212,133,192,161,162,221,219,243,169,184,25,249, +94,192,127,87,200,102,200,38,201,38,248,127,86,240,204,28,80,58,137,175, +6,150,30,135,205,26,206,206,4,194,91,55,22,153,49,53,169,232,45,79,173, +61,34,17,214,246,2,170,46,184,77,182,224,109,153,4,140,51,163,56,123,241, +125,188,171,169,240,240,119,169,68,107,149,144,158,194,152,250,74,200,150, +73,81,143,160,24,75,121,239,118,28,142,190,134,189,254,255,40,146,177,98, +121,65,226,102,200,133,200,54,232,5,126,92,99,6,114,27,52,35,14,201,44, +223,75,86,208,116,112,180,10,139,22,122,17,105,64,186,218,175,27,0,8,117, +176,225,60,16,120,115,51,33,47,86,20,3,102,76,192,38,29,7,40,182,42,110, +197,218,214,173,114,253,134,24,16,169,132,19,17,231,176,139,63,68,107,12, +112,3,226,25,208,254,11,54,51,16,82,29,200,183,48,146,185,210,235,250,153, +77,60,18,113,8,226,46,136,245,145,204,143,134,38,42,83,88,115,201,0,164, +69,68,111,15,138,179,176,133,247,2,94,23,235,38,150,146,168,130,224,131, +99,160,70,132,153,161,161,161,114,195,141,104,225,216,50,171,122,201,127, +75,30,2,109,37,206,204,20,176,35,23,161,179,16,34,159,50,136,135,99,206, +130,114,117,34,114,3,201,200,200,200,110,158,11,26,17,224,207,103,254,235, +251,217,3,219,114,185,195,197,158,131,15,119,180,247,109,47,96,111,165, +27,10,191,121,222,59,251,223,94,78,253,254,237,100,91,201,168,229,225,14, +87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, +29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_22 = 113420; +static unsigned char xml_res_file_22[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, 32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, @@ -287,114 +1460,122 @@ static unsigned char xml_res_file_7[] = { 61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, 61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,100, -114,105,118,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,70,76,79,80, -80,89,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,100,105,115,107,46,112,110,103,60,47,111,98,106, -101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77, -65,80,95,67,68,82,79,77,34,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,99,100,46,112,110,103,60,47, -111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61, -34,116,111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108, -101,62,119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86, -73,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101, -61,34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98, -105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, -99,112,112,36,105,99,111,110,115,95,112,108,97,121,50,52,46,112,110,103, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47,111,98,106,101, +99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65, +80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,100,105,115, +107,101,116,116,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,67,68,82,79, +77,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,99,100,46,112,110,103,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61,34,116, +111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86,73,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61, +34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,50,52,120,50,52,95,112,108,97,121,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66, +65,82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103, 60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, -62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, +62,80,97,117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76, +66,65,82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, -82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, +82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, 62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, -111,110,115,95,112,97,117,115,101,50,52,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,117,115, -101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116, -111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,83,84,79, -80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,115, -116,111,112,50,52,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, -32,32,32,32,60,108,97,98,101,108,62,83,116,111,112,60,47,108,97,98,101, -108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,116,111,111,108,34,32, -110,97,109,101,61,34,84,79,79,76,66,65,82,95,82,69,83,69,84,34,62,10,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,114,101,102,114,101, -115,104,50,52,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, -32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,114,101,115,101,116,60, -47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97, -110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,34,32, -115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45, -114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, -95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32, -32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77, -95,86,73,68,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,49,50,48,48, -34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,34,32,115,116, -97,114,116,61,34,49,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97, -110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68, -69,82,95,68,82,73,86,69,82,34,32,115,116,97,114,116,61,34,49,52,48,48,34, +111,110,115,95,50,52,120,50,52,95,114,101,102,114,101,115,104,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,97,114,100,32,114,101,115,101,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84, +34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32,32,60,105,100,115, +45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +83,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,70,83,95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,49,48,48,34, 47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,77,95,83,78,68,95,66,85,70,34,32,115,116,97,114,116,61,34,50,48, -48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116, -97,116,117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101, +34,73,68,77,95,86,73,68,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34, +49,50,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69, +34,32,115,116,97,114,116,61,34,49,51,48,48,34,47,62,10,32,32,60,105,100, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,32,115,116,97,114,116,61,34, +49,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,34,32,115,116,97,114, +116,61,34,50,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80, +85,84,95,83,84,82,69,84,67,72,34,32,115,116,97,114,116,61,34,51,48,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76, +69,34,32,115,116,97,114,116,61,34,51,49,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84, +69,34,32,115,116,97,114,116,61,34,51,50,48,48,34,47,62,10,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,66, +97,114,34,32,110,97,109,101,61,34,115,116,97,116,117,115,95,109,101,110, +117,34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,68, +73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,105,115,99,32,97,99,116,105,118,105,116,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65,67,72,73,78,69,95, +77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,111,117,110,116,32,112,97,116,104,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, +101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83,84,65,84,85,83,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,116,117, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,80,69,69,68,95, +72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,112,101,101,100,32,104,105,115,116,111,114,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101, +62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,72,79,87,95,77,65,67,72,73,78,69,95,79,78,95,83,84,65,82,84,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,111,110, +32,115,116,97,114,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, +98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97, -99,116,105,118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -77,65,67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97, -116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, -104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95, -83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, -107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116, -111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,83,72,79,87,95,77,65,67,72,73,78,69,95,79,78,95,83, -84,65,82,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -104,111,119,32,111,110,32,115,116,97,114,116,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, -47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,111,110, -102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,79,78,70,73, -71,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104, -105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,72,68,67,79,78,70,34,62,10,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,72,97,114,100,32,100,105,115,99,115,60,47,108, +32,32,32,32,60,108,97,98,101,108,62,95,67,111,110,102,105,103,117,114,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,67,79,78,70,73,71,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,60,47,108, 97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, @@ -428,2278 +1609,4618 @@ static unsigned char xml_res_file_7[] = { 83,69,84,95,67,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,95,67,116,114,108,43,65,108,116,43,68,101,108,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,68,105,115,99,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,68,73,83,67,95,65,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,67,104,97,110,103,101,32,100,114,105,118,101,32,95,65,58,46, -46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,68,73,83,67,95,66,34,62,10,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,104,97,110,103,101,32,100,114,105,118,101,32,95, -66,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,69,74,69,67,84,95,65,34,62,10,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,69,106,101,99,116,32,100,114,105,118, -101,32,65,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,69,74,69,67,84,95,66,34,62,10,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,69,106,101,99,116,32,100,114,105,118,101, -32,66,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,66,80,66, -95,68,73,83,65,66,76,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,105,115,97,98,108,101,32,66,80,66,32,99,104,101,99,107,105,110, -103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68, -77,95,67,68,82,79,77,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95, -73,77,65,71,69,95,76,79,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,76,111,97,100,32,105,109,97,103,101,46,46,46,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112, +97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,69,88,73,84,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,104,117,116,100,111, +119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,115,99, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,68,73,83,67,95,65,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,32,100,114,105, +118,101,32,95,65,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,68,73,83,65, -66,76,69,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -68,105,115,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95, -69,77,80,84,89,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,69,109,112,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,73,77, -65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73, -109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108, -97,98,101,108,62,86,105,100,101,111,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,82,69,83,73,90,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,82,101,115,105,122,97,98,108,101,32,119,105,110,100,111,119, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, -107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,77, -69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112,59,38, -97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49, -60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101,32, -102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, -116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, +109,34,32,110,97,109,101,61,34,73,68,77,95,68,73,83,67,95,66,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,32,100, +114,105,118,101,32,95,66,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, -76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, -117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,69,74,69,67,84,95,65, +34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,106,101, +99,116,32,100,114,105,118,101,32,65,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,69,74,69,67,84,95,66, +34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99, +116,32,100,114,105,118,101,32,66,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116, +111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,66,80,66,95,68,73,83,65,66,76,69,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108,101,32,66,80, +66,32,99,104,101,99,107,105,110,103,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104, +101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,67,68,45,82,79,77,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,95,76,79,65,68,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97,100,32,105,109, +97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,116,114,101,116,99,104,32,109,111,100,101,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +67,68,82,79,77,95,68,73,83,65,66,76,69,68,34,62,10,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,68,105,115,97,98,108,101,100,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112, -105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +34,73,68,77,95,86,73,68,95,82,69,83,73,90,69,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,115,105,122,97,98,108,101,32,119,105, +110,100,111,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97, +109,112,59,38,97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98, +108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34, +47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76, +69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103, +103,108,101,32,102,117,108,108,115,99,114,101,101,110,92,116,67,116,114, +108,43,65,108,116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +85,76,76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110, +112,117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99, +107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115, +99,114,101,101,110,32,109,111,100,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,70,83,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,66,111,114,100,101,114,108,101, +115,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95, +77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,95,69,120,99,108,117,115,105,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82, +95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,82,101,110,100,101,114,32,100,114,105,118,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86, +69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,65,117,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, 110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, -49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, -67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, +95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116,51,68,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95, +68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,101,110,71,76,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,71,76,32,51,46,48,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,111,102,116,119,97,114,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,86,83,89,78,67,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,86,83,121,110,99,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, +47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73, +77,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,109, +32,100,105,115,112,108,97,121,32,111,110,32,108,111,115,116,32,102,111, +99,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114, +97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,99,97,108,101,32,102,105,108,116,101, +114,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67, +65,76,69,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105, +110,101,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,116,114, +101,116,99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, 111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101,108, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73, +110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, 105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, -116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110,32, -109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, -95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,66,111,114,100,101,114,108,101,115,115,60,47,108,97,98, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,120,99, -108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,76,79,83,84,95,70,79, -67,85,83,95,68,73,77,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,68,105,109,32,100,105,115,112,108,97,121,32,111,110,32,108,111, -115,116,32,102,111,99,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99, -107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69, -91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114,60,47, +109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47, 108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, 111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,82,101,110,100,101,114,32,100,114,105, -118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78, -68,69,82,95,68,82,73,86,69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,65,117,116,111,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105, -114,101,99,116,51,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46, +53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, +69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,52,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,71,76,32,51,46,48,32,114,101,110,100,101,114,101,114,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,116,114,101,116, +99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83, +113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84, +95,83,84,82,69,84,67,72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99,97, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112, +117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53, +120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, 110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78, +80,85,84,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, +83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65, +76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51, +46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,114, +101,102,114,101,115,104,32,114,97,116,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82, +69,83,72,95,82,65,84,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,97,109,101,32,97,115,32,101,109,117,108, +97,116,101,100,32,100,105,115,112,108,97,121,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, -73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,83,111,102,116,119,97,114,101,60,47,108,97,98,101,108,62,10, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, +82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,48,32,104,122,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +50,53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, +95,82,65,84,69,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,51,48,32,104,122,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, +95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,53,48,32,104,122,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54, +48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82, +65,84,69,91,55,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69, +70,82,69,83,72,95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100, +101,114,32,109,97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102, +101,114,32,108,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,78,68,95,66,85,70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, 100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98, -108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, -32,32,32,60,108,97,98,101,108,62,83,111,117,110,100,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,66,117,102,102,101,114,32,108,101,110,103,116,104,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,48,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,53,48,32,109,115, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,83,78,68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,50,48,48,32,109,115, 60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, 105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,49,48,48, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,48,48, 32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, 60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85, -70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,50,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, -78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,84,65,84,85, -83,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105, -110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,60,111, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115, +99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114,101,101,110,115,104, +111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72, +79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +84,97,107,101,32,115,99,114,101,101,110,115,104,111,116,92,116,67,116,114, +108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,69,88, -73,84,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,116,111, -112,32,101,109,117,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, +72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, +79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, +51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, +72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102, -105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108, -101,62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47,116,105, -116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, -47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, -101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, -112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,33,45,45,32,109,97,99,104,105,110,101,32,45,45,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, -84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, +99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62, +10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, +68,67,95,67,68,82,79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62, +10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, +68,67,95,69,68,73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,67,95,70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,78,69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10, +32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68, +67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56, +48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114, +116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115, +116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114, +97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66, +69,76,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111, +103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117, +114,101,32,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, +99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, +69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84, +69,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, +114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,51,50,120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, 61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, -80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102, -105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, +65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32,45,45,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,86,105,100,101,111,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, -66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79, -78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, -101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, -110,102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,33,45,45,32,118,105,100,101,111,32,115,112,101, -101,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,32,115, -112,101,101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, -111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32, -124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,33,45,45,32,99,112,117,32,116,121,112,101,32,45,45, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,32,116,121,112,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -33,45,45,32,99,112,117,32,116,121,112,101,32,45,45,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70, -84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67, -79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124, -32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,33,45,45,32,100,121,110,97,109,105,99,32,114,101,99,111, -109,112,105,108,101,114,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -68,121,110,97,109,105,99,32,82,101,99,111,109,112,105,108,101,114,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,33,45,45,32,119,97,105,116,115,116,97,116,101,115,32, -45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116, -101,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, -98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, -87,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, -67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,33,45,45,32,115,111,117,110,100,32,99,97,114,100,32,45,45,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,111,117,110,100,32,99,97,114, -100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,78, -68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, -67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85, -82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,72, -68,68,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68, -79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45, -32,70,68,68,49,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -33,45,45,32,70,68,68,50,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, -111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32, -124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,33,45,45,32,109,101,109,111,114,121,32,45,45,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,83,80,95,72,79,82,73,90,79,78,84,65,76,124, -119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,62,53,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,48,60,47, -109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,109,97,120,62,50,48,48,60,47,109,97,120,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, 76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,33,45,45,32,109,111,117,115,101,32,45,45,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,77,111,117,115,101,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85,83,69,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33, -45,45,32,84,79,68,79,58,32,106,111,121,115,116,105,99,107,32,45,45,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,99,109,115,32,47,32, -103,97,109,101,32,98,108,97,115,116,101,114,32,45,45,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, -70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, -77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,33,45,45,32,71,114,97,118,105,115,32,85,108,116,114,97,115, -111,117,110,100,32,45,45,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105,115,32,85,108, -116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,73,110,110, -111,118,97,116,105,111,110,32,83,83,73,45,50,48,48,49,32,45,45,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, 99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83,83,73,45,50, -48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99, +32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,69,110,97,98,108,101,32,116, -105,109,101,32,115,121,110,99,32,45,45,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78,67,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,121,110, -99,104,114,111,110,105,115,101,32,116,105,109,101,32,116,111,32,104,111, -115,116,32,99,108,111,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,33,45,45,32,86,111,111, -100,111,111,32,71,114,97,112,104,105,99,115,32,45,45,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, -70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79, -79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102, -105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, -79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, -101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, -67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, +122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, +99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, +105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, +103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, +65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, +115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, +97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116, -97,114,116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,67,95,72,68,68,34,32,115,116,97,114,116, -61,34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, -110,97,109,101,61,34,73,68,67,95,67,68,82,79,77,34,32,115,116,97,114,116, -61,34,50,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, -110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34,32,115,116,97, -114,116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32,115,116,97,114, -116,61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32,115,116,97,114, -116,61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116,97,114,116,61, -34,54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114, -116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116, -97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34, -32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45, -114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, -73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108, -111,103,34,32,110,97,109,101,61,34,72,100,67,111,110,102,68,108,103,34, -62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117, -114,101,32,72,97,114,100,32,68,105,115,99,115,60,47,116,105,116,108,101, -62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101, -110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, -34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, +73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68, +50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,111,105,99,101,98,111,111,107,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,72,66,95,68,69,70,65,85,76,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111, +105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,114,105,118,101,32,49,32,40,67,58,41,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, +65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73, +68,67,95,72,68,68,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47, +118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99,111,110,116, +114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105,116,109,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,106, +101,99,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, +95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, +66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90, +69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, +111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, +76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,51,32,40,69,58,41, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, +47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,48,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114, +100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, +82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, +117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50, +53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, +73,90,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, +111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,114,105,118,101,32,52,32,40,70,58,41,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, +76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,109,111,117,115,101,95,112,99,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,117,115,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,77,79,85,83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,78,101, +119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119, +32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32, +32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, +114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79, +84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, 97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, 53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, 71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, 103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, 62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, -66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, -79,77,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, -101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,48,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, -67,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, 124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,84,69,88,84,95,83,73,90,69,91,48,93,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, -68,67,95,80,65,78,69,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,68,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, -91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, -105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, -84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,49,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, -47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,95,67,89,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, -49,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,50,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, -66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68,82, -79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, -101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,78,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, -71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80, -67,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,67,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,84,69,88,84,95,83,73,90,69,91,50,93,34,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, -68,67,95,80,65,78,69,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,70,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68, -91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32,100,114, -105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,69,106,101,99,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80, -84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,72,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,51,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60, -47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,95,67,89,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91, -51,93,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, -120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100, -78,101,119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78, -101,119,32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62, -10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, -116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, -79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, -60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, 62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, 34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, 84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, -67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76, -69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69, -70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, +85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, -97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, -101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, -117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79, -75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110, -99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, -101,61,34,72,100,83,105,122,101,68,108,103,34,62,10,32,32,32,32,60,116, -105,116,108,101,62,72,97,114,100,32,100,105,115,99,32,112,97,114,97,109, -101,116,101,114,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101, -110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, -76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, -82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,73,110,105,116,105,97,108,32,115,101,116,116,105,110,103, -115,32,97,114,101,32,98,97,115,101,100,32,111,110,32,102,105,108,101,32, -115,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, -62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,49,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,76,69,70,84,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, 101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, -101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,50,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110, -100,101,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, -101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,51,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95, -84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,76,60, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, 47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,48,109,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,83,105, +122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,72,97, +114,100,32,68,105,115,99,32,80,97,114,97,109,101,116,101,114,115,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, +62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47, +62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116, +105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97,115, +101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, +108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, -97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108, +111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,83, +101,108,101,99,116,105,111,110,68,108,103,34,62,10,32,32,32,32,60,116,105, +116,108,101,62,80,67,101,109,32,67,111,110,102,105,103,117,114,97,116,105, +111,110,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62,10,32, +32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, +114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,114,111,119,115,62,49,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +50,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, 122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, -101,61,34,67,111,110,102,105,103,117,114,101,83,101,108,101,99,116,105, -111,110,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67, -101,109,32,67,111,110,102,105,103,117,114,97,116,105,111,110,32,77,97,110, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73,78, +71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,53,48,44,51,48,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97, +112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,116,111,111,108,116,105,112,62,76,111,97,100,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,110,116, +114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100, +100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, +82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97, +109,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, +50,120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76, +69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +99,111,109,112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89, +95,79,78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116, +105,116,108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110, 97,103,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110, 116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, @@ -2724,7 +6245,7 @@ static unsigned char xml_res_file_7[] = { 83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, 121,108,101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108, 101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,50,48,48,44,51,48,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +101,62,51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, @@ -2743,69 +6264,36 @@ static unsigned char xml_res_file_7[] = { 32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, -111,97,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, -100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,110,97,109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100, +100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,78,101,119,46,46,46,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,110,97,109, -101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34,62, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,68,101,108,101,116,101,46,46,46,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, 32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, @@ -2820,122 +6308,152 @@ static unsigned char xml_res_file_7[] = { 100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,72,68,67,79,78,70,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,46,46,46, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, -68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,105,116,60,47,108,97, +34,73,68,67,95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101, +32,117,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87, +78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102, -105,114,109,82,101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32, -32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105,116,108,101,62, -10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, -116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, -79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115, -116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79, -78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61,34,119,120,65, -82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,80,80,76, +89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,112,112,108,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101, +61,34,67,111,110,102,105,114,109,82,101,109,101,109,98,101,114,68,108,103, +34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76, +84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79, +78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, +108,101,62,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, +99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, +69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115,116,111,99,107,95, +105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79,78,34,32,115,116, +111,99,107,95,99,108,105,101,110,116,61,34,119,120,65,82,84,95,67,77,78, +95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,67, +79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, +82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68, -67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,78,70,73,82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, -82,77,95,82,69,77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, -104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, -101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73, +82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73,82,77,95,82,69, +77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, 78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, @@ -2943,80 +6461,93 @@ static unsigned char xml_res_file_7[] = { 32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,97,110,99,101,108, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -68,105,97,108,111,103,34,32,110,97,109,101,61,34,65,98,111,117,116,68,108, -103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, -85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,99,101, -110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98, +117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72, +79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, -76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, -60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,67,101, -109,32,118,49,50,92,110,104,116,116,112,115,58,47,47,112,99,101,109,45, -101,109,117,108,97,116,111,114,46,99,111,46,117,107,47,92,110,92,110,84, -104,105,115,32,112,114,111,103,114,97,109,32,105,115,32,108,105,99,101, -110,115,101,100,32,117,110,100,101,114,32,116,104,101,32,71,78,85,32,71, -101,110,101,114,97,108,32,80,117,98,108,105,99,32,76,105,99,101,110,115, -101,32,118,101,114,115,105,111,110,32,50,46,92,110,83,101,101,32,67,79, -80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100,101,116,97,105, -108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105,99,111,110,115, -32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99,111,110,115,32, -40,104,116,116,112,115,58,47,47,114,111,117,110,100,105,99,111,110,115, -46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46,102,108,97,116, -105,99,111,110,46,99,111,109,92,110,83,116,97,116,117,115,45,105,99,111, -110,115,32,109,97,100,101,32,98,121,32,77,97,114,107,32,74,97,109,101,115, -32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,109,102,97,109,102, -97,109,46,99,111,109,47,108,97,98,47,105,99,111,110,115,47,115,105,108, -107,47,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, -79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, -111,117,114,99,101,62,10}; +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,65,98,111,117,116,68,108,103,34,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, +47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,67,101,109,32,118,49,50,92,110,104, +116,116,112,115,58,47,47,112,99,101,109,45,101,109,117,108,97,116,111,114, +46,99,111,46,117,107,47,92,110,92,110,84,104,105,115,32,112,114,111,103, +114,97,109,32,105,115,32,108,105,99,101,110,115,101,100,32,117,110,100, +101,114,32,116,104,101,32,71,78,85,32,71,101,110,101,114,97,108,32,80,117, +98,108,105,99,32,76,105,99,101,110,115,101,32,118,101,114,115,105,111,110, +32,50,46,92,110,83,101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109, +111,114,101,32,100,101,116,97,105,108,115,46,92,110,92,110,84,111,111,108, +98,97,114,45,105,99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117, +110,100,105,99,111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117, +110,100,105,99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119, +119,119,46,102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104, +101,114,32,105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116, +67,111,119,32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,116,99, +111,119,46,99,111,109,47,102,114,101,101,45,105,99,111,110,115,47,41,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; void InitXmlResource() { @@ -3031,13 +6562,28 @@ void InitXmlResource() else wxFileSystem::AddHandler(new wxMemoryFSHandler); } - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_disk.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_play24.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_pause24.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_stop24.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_refresh24.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$pc.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$pc.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$pc.xrc")); } diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c new file mode 100644 index 0000000..9eaac1a --- /dev/null +++ b/src/wx-sdl2-display-win.c @@ -0,0 +1,984 @@ +#define _WIN32_WINNT 0x0501 +#include +#include "video.h" +#include "wx-sdl2-video.h" +#include "wx-utils.h" +#include "ibm.h" +#include "wx-display.h" +#include "plat-keyboard.h" + +#ifdef _WIN32 +#define BITMAP WINDOWS_BITMAP +#undef UNICODE +#include +#include +#undef BITMAP +#endif + +HHOOK hKeyboardHook; + +static HINSTANCE hinstance = 0; +static HWND hwnd = 0; +static HMENU menu = 0; + +#define szClassName "PCemMainWnd" +#define szSubClassName "PCemSubWnd" + +static RAWINPUTDEVICE device; +static uint16_t scancode_map[65536]; + +SDL_mutex* rendererMutex; +SDL_cond* rendererCond; +SDL_Thread* renderthread = NULL; + +SDL_Window* window = NULL; +SDL_Window* dummy_window = NULL; + +int rendering = 0; + +int mousecapture = 0; + +extern int pause; +extern int video_scale; +extern int take_screenshot; + +void* window_ptr; +void* menu_ptr; + +SDL_Rect remembered_rect; +int remembered_mouse_x = 0; +int remembered_mouse_y = 0; + +int win_doresize = 0; +int winsizex = 640, winsizey = 480; + +void renderer_start(); +void renderer_stop(int timeout); + +int trigger_fullscreen = 0; +int trigger_screenshot = 0; +int trigger_togglewindow = 0; +int trigger_inputrelease = 0; + +extern void device_force_redraw(); +extern void mouse_wheel_update(int); +extern void toggle_fullscreen(); + +void display_resize(int width, int height) +{ + winsizex = width*(video_scale+1) >> 1; + winsizey = height*(video_scale+1) >> 1; + + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = winsizex; + rect.h = winsizey; + sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); + winsizex = rect.w; + winsizey = rect.h; + + win_doresize = 1; +} + +void releasemouse() +{ + if (mousecapture) + { + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + mousecapture = 0; + } +} + +int is_fullscreen() +{ + if (window) + { + int flags = SDL_GetWindowFlags(window); + return (flags&SDL_WINDOW_FULLSCREEN) || (flags&SDL_WINDOW_FULLSCREEN_DESKTOP); + } + return 0; +} + +/* 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 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() +{ + char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + char *valueName = "Scancode Map"; + 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; + pclog("Preparing scan code map list...\n"); + /* 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, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS) + { + UINT32 *bufEx2 = (UINT32 *) buf; + int scMapCount = bufEx2[2]; + pclog("%lu scan code mappings found!\n", scMapCount); + if ((bufSize != 0) && (scMapCount != 0)) + { + UINT16 *bufEx = (UINT16 *) (buf + 12); + pclog("More than zero scan code mappings found, processing...\n"); + 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); + + scancode_map[scancode_unmapped] = scancode_mapped; + pclog("Scan code mapping %u detected: %X -> %X\n", scancode_unmapped, scancode_mapped, scancode_map[scancode_unmapped]); + } + pclog("Done processing!\n"); + } + } + RegCloseKey(hKey); + } + pclog("Done preparing!\n"); +} + +LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + + KBDLLHOOKSTRUCT* 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 + BOOL 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 ); +} + +LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_COMMAND: + /* pass through commands to wx window */ + wx_winsendmessage(window_ptr, message, wParam, lParam); + return 0; + break; + case WM_INPUT: + { + UINT size; + RAWINPUT *raw; + + if (!infocus) + break; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + + raw = malloc(size); + + /* Here we read the raw input data for the keyboard */ + GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); + + /* If the input is keyboard, we process it */ + if (raw->header.dwType == RIM_TYPEKEYBOARD) + { + 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)) + { + 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); + } + } + free(raw); + + } + break; + case WM_SETFOCUS: + infocus=1; + break; + case WM_KILLFOCUS: + infocus=0; + if (is_fullscreen()) + window_dowindowed = 1; + window_doinputrelease = 1; + memset(rawinputkey, 0, sizeof(rawinputkey)); + break; + case WM_CLOSE: + case WM_DESTROY: + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + return 0; + + case WM_SYSCOMMAND: + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) + return 0; /*disable ALT key for menu*/ + break; + default: + break; + } + return DefWindowProc (hwnd, message, wParam, lParam); +} + +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +int display_init() +{ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) + { + printf("SDL could not initialize! Error: %s\n", SDL_GetError()); + return 0; + } + + SDL_version ver; + SDL_GetVersion(&ver); + printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); + + return 1; +} + +void display_close() +{ + SDL_Quit(); +} + +void display_start(void* wnd_ptr) +{ + window_ptr = wnd_ptr; + menu_ptr = wx_getmenu(wnd_ptr); + + get_registry_key_map(); + + infocus = 1; + + atexit(releasemouse); + rendererMutex = SDL_CreateMutex(); + rendererCond = SDL_CreateCond(); + renderer_start(); +} + +void display_stop() +{ + renderer_stop(10 * 1000); + + SDL_DestroyMutex(rendererMutex); + SDL_DestroyCond(rendererCond); + SDL_DetachThread(renderthread); + releasemouse(); + +} + +void sdl_set_window_title(const char* title) { + if (hwnd && !is_fullscreen()) + SetWindowText(hwnd, title); +} + +int get_border_size(int* top, int* left, int* bottom, int* right) +{ + int res = SDL_GetWindowBordersSize(window, top, left, bottom, right); + if (top) *top -= GetSystemMetrics(SM_CYMENUSIZE); + + return res; +} + +static const struct { + SDL_Scancode sdl; + int system; +} SDLScancodeToSystemScancode[] = { + { SDL_SCANCODE_A, 0x1e }, + { SDL_SCANCODE_B, 0x30 }, + { SDL_SCANCODE_C, 0x2e }, + { SDL_SCANCODE_D, 0x20 }, + { SDL_SCANCODE_E, 0x12 }, + { SDL_SCANCODE_F, 0x21 }, + { SDL_SCANCODE_G, 0x22 }, + { SDL_SCANCODE_H, 0x23 }, + { SDL_SCANCODE_I, 0x17 }, + { SDL_SCANCODE_J, 0x24 }, + { SDL_SCANCODE_K, 0x25 }, + { SDL_SCANCODE_L, 0x26 }, + { SDL_SCANCODE_M, 0x32 }, + { SDL_SCANCODE_N, 0x31 }, + { SDL_SCANCODE_O, 0x18 }, + { SDL_SCANCODE_P, 0x19 }, + { SDL_SCANCODE_Q, 0x10 }, + { SDL_SCANCODE_R, 0x13 }, + { SDL_SCANCODE_S, 0x1f }, + { SDL_SCANCODE_T, 0x14 }, + { SDL_SCANCODE_U, 0x16 }, + { SDL_SCANCODE_V, 0x2f }, + { SDL_SCANCODE_W, 0x11 }, + { SDL_SCANCODE_X, 0x2d }, + { SDL_SCANCODE_Y, 0x15 }, + { SDL_SCANCODE_Z, 0x2c }, + { SDL_SCANCODE_0, 0x0B }, + { SDL_SCANCODE_1, 0x02 }, + { SDL_SCANCODE_2, 0x03 }, + { SDL_SCANCODE_3, 0x04 }, + { SDL_SCANCODE_4, 0x05 }, + { SDL_SCANCODE_5, 0x06 }, + { SDL_SCANCODE_6, 0x07 }, + { SDL_SCANCODE_7, 0x08 }, + { SDL_SCANCODE_8, 0x09 }, + { SDL_SCANCODE_9, 0x0A }, + { SDL_SCANCODE_GRAVE, 0x29 }, + { SDL_SCANCODE_MINUS, 0x0c }, + { SDL_SCANCODE_EQUALS, 0x0d }, + { SDL_SCANCODE_NONUSBACKSLASH, 0x56 }, + { SDL_SCANCODE_BACKSLASH, 0x2b }, + { SDL_SCANCODE_BACKSPACE, 0x0e }, + { SDL_SCANCODE_SPACE, 0x39 }, + { SDL_SCANCODE_TAB, 0x0f }, + { SDL_SCANCODE_CAPSLOCK, 0x3a }, + { SDL_SCANCODE_LSHIFT, 0x2a }, + { SDL_SCANCODE_LCTRL, 0x1d }, + { SDL_SCANCODE_LGUI, 0xdb }, + { SDL_SCANCODE_LALT, 0x38 }, + { SDL_SCANCODE_RSHIFT, 0x36 }, + { SDL_SCANCODE_RCTRL, 0x9d }, + { SDL_SCANCODE_RGUI, 0xdc }, + { SDL_SCANCODE_RALT, 0xb8 }, + { SDL_SCANCODE_SYSREQ, 0x54 }, + { SDL_SCANCODE_APPLICATION, 0xdd }, + { SDL_SCANCODE_RETURN, 0x1c }, + { SDL_SCANCODE_ESCAPE, 0x01 }, + { SDL_SCANCODE_F1, 0x3B }, + { SDL_SCANCODE_F2, 0x3C }, + { SDL_SCANCODE_F3, 0x3D }, + { SDL_SCANCODE_F4, 0x3e }, + { SDL_SCANCODE_F5, 0x3f }, + { SDL_SCANCODE_F6, 0x40 }, + { SDL_SCANCODE_F7, 0x41 }, + { SDL_SCANCODE_F8, 0x42 }, + { SDL_SCANCODE_F9, 0x43 }, + { SDL_SCANCODE_F10, 0x44 }, + { SDL_SCANCODE_F11, 0x57 }, + { SDL_SCANCODE_F12, 0x58 }, + { SDL_SCANCODE_SCROLLLOCK, 0x46 }, + { SDL_SCANCODE_LEFTBRACKET, 0x1a }, + { SDL_SCANCODE_RIGHTBRACKET, 0x1b }, + { SDL_SCANCODE_INSERT, 0xd2 }, + { SDL_SCANCODE_HOME, 0xc7 }, + { SDL_SCANCODE_PAGEUP, 0xc9 }, + { SDL_SCANCODE_DELETE, 0xd3 }, + { SDL_SCANCODE_END, 0xcf }, + { SDL_SCANCODE_PAGEDOWN, 0xd1 }, + { SDL_SCANCODE_UP, 0xc8 }, + { SDL_SCANCODE_LEFT, 0xcb }, + { SDL_SCANCODE_DOWN, 0xd0 }, + { SDL_SCANCODE_RIGHT, 0xcd }, + { SDL_SCANCODE_NUMLOCKCLEAR, 0x45 }, + { SDL_SCANCODE_KP_DIVIDE, 0xb5 }, + { SDL_SCANCODE_KP_MULTIPLY, 0x37 }, + { SDL_SCANCODE_KP_MINUS, 0x4a }, + { SDL_SCANCODE_KP_PLUS, 0x4e }, + { SDL_SCANCODE_KP_ENTER, 0x9c }, + { SDL_SCANCODE_KP_PERIOD, 0x53 }, + { SDL_SCANCODE_KP_0, 0x52 }, + { SDL_SCANCODE_KP_1, 0x4f }, + { SDL_SCANCODE_KP_2, 0x50 }, + { SDL_SCANCODE_KP_3, 0x51 }, + { SDL_SCANCODE_KP_4, 0x48 }, + { SDL_SCANCODE_KP_5, 0x4c }, + { SDL_SCANCODE_KP_6, 0x4d }, + { SDL_SCANCODE_KP_7, 0x47 }, + { SDL_SCANCODE_KP_8, 0x48 }, + { SDL_SCANCODE_KP_9, 0x49 }, + { SDL_SCANCODE_SEMICOLON, 0x27 }, + { SDL_SCANCODE_APOSTROPHE, 0x28 }, + { SDL_SCANCODE_COMMA, 0x33 }, + { SDL_SCANCODE_PERIOD, 0x34 }, + { SDL_SCANCODE_SLASH, 0x35 }, + { SDL_SCANCODE_PRINTSCREEN, 0xb7 } +}; + +int sdl_scancode(SDL_Scancode scancode) +{ + int i; + for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { + if (SDLScancodeToSystemScancode[i].sdl == scancode) { + return SDLScancodeToSystemScancode[i].system; + } + } + return -1; +} + +SDL_Event event; +SDL_Rect rect; +int border_x, border_y = 0; + +uint64_t render_time = 0; +int render_fps = 0; +uint32_t render_frame_time = 0; +uint32_t render_frames = 0; + +void window_setup() +{ + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0"); + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); + SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); + + if (start_in_fullscreen) + { + start_in_fullscreen = 0; + window_dofullscreen = 1; + window_doinputgrab = 1; + } + + if (window_remember) + { + rect.x = window_x; + rect.y = window_y; + rect.w = window_w; + rect.h = window_h; + } + else + { + rect.x = SDL_WINDOWPOS_CENTERED; + rect.y = SDL_WINDOWPOS_CENTERED; + rect.w = 640; + rect.h = 480; + } +} + +int window_create() +{ + int i; + WNDCLASSEX wincl; /* Data structure for the windowclass */ + + hinstance = (HINSTANCE)GetModuleHandle(NULL); + /* The Window structure */ + wincl.hInstance = hinstance; + 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 (NULL, IDI_APPLICATION); + wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); + wincl.hCursor = NULL;//LoadCursor (NULL, IDC_ARROW); + 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 = CreateMenu(); + HMENU native_menu = (HMENU)wx_getnativemenu(menu_ptr); + int count = GetMenuItemCount(native_menu); + MENUITEMINFO info; + for (i = 0; i < count; ++i) + { + char label[256]; + memset(&info, 0, sizeof(MENUITEMINFO)); + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_TYPE | MIIM_ID; + info.fType = MFT_STRING; + info.cch = 256; + info.dwTypeData = label; + if (GetMenuItemInfo(native_menu, i, 1, &info)) + AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)GetSubMenu(native_menu, i), info.dwTypeData); + } + + /* The class is registered, let's create the program*/ + hwnd = CreateWindowEx ( + 0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + "PCem v12", /* Title Text */ + WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* 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 */ + hinstance, /* Program Instance handler */ + NULL /* No Window Creation data */ + ); + + /* Make the window visible on the screen */ + ShowWindow(hwnd, 1); + + 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"); + + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + + if (requested_render_driver.sdl_window_params & SDL_WINDOW_OPENGL) + { + /* create dummy window for opengl */ + dummy_window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + if (dummy_window) + { + char ptr[32]; + snprintf(ptr, 31, "%p", dummy_window); + ptr[31] = 0; + SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, ptr); + } + } + window = SDL_CreateWindowFrom(hwnd); + if (!window) + { + char message[200]; + sprintf(message, + "SDL window could not be created! Error: %s\n", + SDL_GetError()); + wx_messagebox(window_ptr, message, "SDL Error", WX_MB_OK); + return 0; + } + + SDL_SetWindowPosition(window, rect.x, rect.y); + SDL_SetWindowSize(window, rect.w, rect.h); + + if (vid_resize) + window_dosetresize = 1; + + render_time = 0; + render_fps = 0; + render_frame_time = SDL_GetTicks(); + render_frames = 0; + return 1; +} + +void window_close() +{ + int i; + sdl_renderer_close(); + + int count = GetMenuItemCount(menu); + for (i = 0; i < count; ++i) + RemoveMenu(menu, 0, MF_BYPOSITION); + DestroyMenu(menu); + menu = 0; + SetMenu(hwnd, 0); + + if (window) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_GetWindowSize(window, &rect.w, &rect.h); + get_border_size(&border_y, &border_x, 0, 0); + rect.x -= border_x; + rect.y -= border_y; + + SDL_DestroyWindow(window); + } + window = NULL; + + if (dummy_window) + { + SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, ""); + SDL_DestroyWindow(dummy_window); + } + dummy_window = NULL; + + UnhookWindowsHookEx( hKeyboardHook ); + DestroyWindow(hwnd); + hwnd = NULL; + + UnregisterClass(szSubClassName, hinstance); + UnregisterClass(szClassName, hinstance); + +} + +int render() +{ + uint64_t start_time = timer_read(); + uint64_t end_time; + + if (window_doreset) + { + pclog("window_doreset\n"); + window_doreset = 0; + renderer_doreset = 0; + return 0; + } + if (window_dosetresize) + { + window_dosetresize = 0; + SDL_GetWindowSize(window, &rect.w, &rect.h); + SDL_SetWindowResizable(window, vid_resize); + SDL_SetWindowSize(window, rect.w, rect.h); + } + if (renderer_doreset) + { + pclog("renderer_doreset\n"); + renderer_doreset = 0; + sdl_renderer_close(); + sdl_renderer_init(window); + + device_force_redraw(); + video_wait_for_blit(); + } + while(SDL_PollEvent(&event)) + { + switch (event.type) { + case SDL_MOUSEBUTTONUP: + if (!mousecapture) + { + if (event.button.button == SDL_BUTTON_LEFT && !pause) + { + window_doinputgrab = 1; + if (video_fullscreen) + window_dofullscreen = 1; + } + } + else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen()) + window_doinputrelease = 1; + break; + case SDL_MOUSEWHEEL: + if (mousecapture) mouse_wheel_update(event.wheel.y); + break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_CLOSE) + wx_stop_emulation(window_ptr); + + if (window_remember) + { + int flags = SDL_GetWindowFlags(window); + if (!(flags&SDL_WINDOW_FULLSCREEN) && !(flags&SDL_WINDOW_FULLSCREEN_DESKTOP)) + { + if (event.window.event == SDL_WINDOWEVENT_MOVED) + { + get_border_size(&border_y, &border_x, 0, 0); + window_x = event.window.data1-border_x; + window_y = event.window.data2-border_y; + } + else if (event.window.event == SDL_WINDOWEVENT_RESIZED) + { + window_w = event.window.data1; + window_h = event.window.data2; + } + //save_window_pos = 1; + } + } + + break; + } + } + if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_fullscreen = 1; + else if (trigger_fullscreen) + { + trigger_fullscreen = 0; + toggle_fullscreen(); + } + else if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_screenshot = 1; + else if (trigger_screenshot) + { + trigger_screenshot = 0; + take_screenshot = 1; + } + else if (event.key.keysym.scancode == SDL_SCANCODE_END && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) + trigger_inputrelease = 1; + else if (trigger_inputrelease) + { + trigger_inputrelease = 0; + if (!is_fullscreen()) + window_doinputrelease = 1; + } + if (window_doremember) + { + window_doremember = 0; + SDL_GetWindowPosition(window, &window_x, &window_y); + SDL_GetWindowSize(window, &window_w, &window_h); + get_border_size(&border_y, &border_x, 0, 0); + window_x -= border_x; + window_y -= border_y; + saveconfig(NULL); + } + + if (window_dotogglefullscreen) + { + window_dotogglefullscreen = 0; + if (SDL_GetWindowGrab(window) || is_fullscreen()) + { + window_doinputrelease = 1; + if (is_fullscreen()) + window_dowindowed = 1; + } + else + { + window_doinputgrab = 1; + window_dofullscreen = 1; + } + } + + if (window_dofullscreen) + { + window_dofullscreen = 0; + SetMenu(hwnd, 0); + video_wait_for_blit(); + SDL_RaiseWindow(window); + SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); + SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); + get_border_size(&border_y, &border_x, 0, 0); + remembered_rect.x -= border_x; + remembered_rect.y -= border_y; + SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); + SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + } + if (window_doinputgrab) { + window_doinputgrab = 0; + mousecapture = 1; + SDL_GetRelativeMouseState(0, 0); + SDL_SetWindowGrab(window, SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); + } + if (mousecapture) + { + SDL_Rect rect; + SDL_GetWindowSize(window, &rect.w, &rect.h); + SDL_WarpMouseInWindow(window, rect.w/2, rect.h/2); + } + + if (window_doinputrelease) { + window_doinputrelease = 0; + releasemouse(); + } + if (window_dowindowed) + { + window_dowindowed = 0; + SetMenu(hwnd, menu); + SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); + SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); + SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); + } + + if (win_doresize) + { + win_doresize = 0; + if (!vid_resize || (flags&SDL_WINDOW_FULLSCREEN)) { + SDL_GetWindowSize(window, &rect.w, &rect.h); + if (rect.w != winsizex || rect.h != winsizey) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_SetWindowSize(window, winsizex, winsizey); + SDL_SetWindowPosition(window, rect.x, rect.y); + device_force_redraw(); + } + } + } + + if (sdl_renderer_update(window)) sdl_renderer_present(window); + + end_time = timer_read(); + render_time += end_time - start_time; + + ++render_frames; + uint32_t ticks = SDL_GetTicks(); + if (ticks-render_frame_time >= 1000) { + render_fps = render_frames/((ticks-render_frame_time)/1000.0); + render_frames = 0; + render_frame_time = ticks; + } + + return 1; +} + +int renderer_thread(void* params) +{ + int internal_rendering; + + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); + + window_setup(); + + rendering = 1; + while (rendering) { + + if (!window_create()) + rendering = 0; + + renderer_doreset = 1; + internal_rendering = 1; + while (rendering && internal_rendering) + { + if (!render()) + internal_rendering = 0; + + SDL_Delay(1); + } + window_close(); + } + + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); + + return SDL_TRUE; +} + +void* timer = 0; + +void render_timer() +{ +#ifdef PCEM_RENDER_TIMER_LOOP + /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ + renderer_thread(0); +#else + if (rendering && !render()) + { + window_close(); + window_create(); + renderer_doreset = 1; + } +#endif +} + +void render_start_timer() +{ +#ifdef PCEM_RENDER_TIMER_LOOP + timer = wx_createtimer(render_timer); + wx_starttimer(timer, 500, 1); +#else + window_setup(); + if (window_create()) + { + rendering = 1; + renderer_doreset = 1; + wx_starttimer(timer, 1, 0); + } +#endif +} + +void renderer_start() +{ + if (!rendering) + { +#ifdef PCEM_RENDER_WITH_TIMER + render_start_timer(); +#else + SDL_LockMutex(rendererMutex); + renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); +#endif + } +} + +void renderer_stop(int timeout) +{ +#if defined(PCEM_RENDER_WITH_TIMER) && !defined(PCEM_RENDER_TIMER_LOOP) + rendering = 0; + window_close(); + wx_destroytimer(timer); +#else + if (rendering) + { + SDL_LockMutex(rendererMutex); + rendering = 0; + if (timeout) + SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); + else + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); + renderthread = NULL; + } + if (timer) + wx_destroytimer(timer); +#endif +} diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index b0fe236..3f1bd91 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -1,13 +1,14 @@ #include +#include "video.h" #include "wx-sdl2-video.h" #include "wx-utils.h" #include "ibm.h" -#include "video.h" #include "wx-display.h" #include "plat-keyboard.h" #ifdef __WINDOWS__ #define BITMAP WINDOWS_BITMAP +#undef UNICODE #include #include #undef BITMAP @@ -29,6 +30,7 @@ int mousecapture = 0; extern int pause; extern int video_scale; +extern int take_screenshot; void* ghwnd; void* menu; @@ -44,6 +46,7 @@ void renderer_start(); void renderer_stop(int timeout); int trigger_fullscreen = 0; +int trigger_screenshot = 0; int trigger_togglewindow = 0; int trigger_inputrelease = 0; @@ -53,27 +56,8 @@ extern void toggle_fullscreen(); void display_resize(int width, int height) { - /* Video scaling-code is borrowed from 86Box */ - switch(video_scale) - { - case 0: - winsizex = width >> 1; - winsizey = height >> 1; - break; - case 2: - winsizex = (width * 3) >> 1; - winsizey = (height * 3) >> 1; - break; - case 3: - winsizex = width << 1; - winsizey = height << 1; - break; - case 1: - default: - winsizex = width; - winsizey = height; - break; - } + winsizex = width*(video_scale+1) >> 1; + winsizey = height*(video_scale+1) >> 1; SDL_Rect rect; rect.x = rect.y = 0; @@ -144,7 +128,7 @@ int is_fullscreen() } void sdl_set_window_title(const char* title) { - if (window) + if (window && !is_fullscreen()) SDL_SetWindowTitle(window, title); } @@ -258,7 +242,7 @@ static const struct { { SDL_SCANCODE_KP_1, 0x4f }, { SDL_SCANCODE_KP_2, 0x50 }, { SDL_SCANCODE_KP_3, 0x51 }, - { SDL_SCANCODE_KP_4, 0x48 }, + { SDL_SCANCODE_KP_4, 0x4b }, { SDL_SCANCODE_KP_5, 0x4c }, { SDL_SCANCODE_KP_6, 0x4d }, { SDL_SCANCODE_KP_7, 0x47 }, @@ -365,12 +349,13 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) if (!mousecapture) key_state = -key_state; /* if key_state is 0 and modkeystate[c] is negative, - an sdl_event should not generated */ + an sdl_event should not be generated */ if (key_state > 0 || modkeystate[c] > 0) { - steal = 1; + steal = key_state != 0; SDL_Event event; event.key.keysym.scancode = s; + event.key.timestamp = p->time; event.type = key_state ? SDL_KEYDOWN : SDL_KEYUP; SDL_PushEvent(&event); @@ -389,7 +374,7 @@ int window_create() { window = SDL_CreateWindow("PCem Display", rect.x, rect.y, rect.w, rect.h, - vid_resize ? SDL_WINDOW_RESIZABLE : 0); + requested_render_driver.sdl_window_params | (vid_resize ? SDL_WINDOW_RESIZABLE : 0)); if (!window) { char message[200]; @@ -437,6 +422,17 @@ int render() uint64_t start_time = timer_read(); uint64_t end_time; + if (window_dosetresize) + { + window_dosetresize = 0; +#if SDL_VERSION_ATLEAST(2, 0, 5) + SDL_GetWindowSize(window, &rect.w, &rect.h); + SDL_SetWindowResizable(window, vid_resize); + SDL_SetWindowSize(window, rect.w, rect.h); +#else + window_doreset = 1; +#endif + } if (window_doreset) { pclog("window_doreset\n"); @@ -463,22 +459,22 @@ int render() if (event.button.button == SDL_BUTTON_LEFT && !pause) { window_doinputgrab = 1; - if (video_fullscreen) { + if (video_fullscreen) window_dofullscreen = 1; - } - } else if (event.button.button == SDL_BUTTON_RIGHT) - { - wx_popupmenu(ghwnd, menu, 0, 0); } + else if (event.button.button == SDL_BUTTON_RIGHT) + wx_popupmenu(ghwnd, menu, 0, 0); + } + else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen()) + window_doinputrelease = 1; break; case SDL_MOUSEWHEEL: if (mousecapture) mouse_wheel_update(event.wheel.y); break; case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_CLOSE) { + if (event.window.event == SDL_WINDOWEVENT_CLOSE) wx_stop_emulation(ghwnd); - } if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { if (is_fullscreen()) @@ -486,14 +482,19 @@ int render() window_doinputrelease = 1; } - if (window_remember) { + if (window_remember) + { int flags = SDL_GetWindowFlags(window); - if (!(flags&SDL_WINDOW_FULLSCREEN) && !(flags&SDL_WINDOW_FULLSCREEN_DESKTOP)) { - if (event.window.event == SDL_WINDOWEVENT_MOVED) { - get_border_size(&border_x, &border_y, 0, 0); + if (!(flags&SDL_WINDOW_FULLSCREEN) && !(flags&SDL_WINDOW_FULLSCREEN_DESKTOP)) + { + if (event.window.event == SDL_WINDOWEVENT_MOVED) + { + get_border_size(&border_y, &border_x, 0, 0); window_x = event.window.data1-border_x; window_y = event.window.data2-border_y; - } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + } + else if (event.window.event == SDL_WINDOWEVENT_RESIZED) + { window_w = event.window.data1; window_h = event.window.data2; } @@ -513,7 +514,7 @@ int render() #endif int key_idx = sdl_scancode(event.key.keysym.scancode); if (key_idx != -1) - rawinputkey[key_idx] = 1; + rawinputkey[key_idx] = event.key.timestamp; break; } case SDL_KEYUP: @@ -534,15 +535,15 @@ int render() trigger_fullscreen = 0; toggle_fullscreen(); } -// if (event.key.keysym.scancode == SDL_SCANCODE_PAGEUP && -// (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && -// (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) -// trigger_togglewindow = 1; -// else if (trigger_togglewindow) -// { -// trigger_togglewindow = 0; -// wx_togglewindow(ghwnd); -// } + else if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_screenshot = 1; + else if (trigger_screenshot) + { + trigger_screenshot = 0; + take_screenshot = 1; + } else if (event.key.keysym.scancode == SDL_SCANCODE_END && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) trigger_inputrelease = 1; @@ -552,7 +553,8 @@ int render() if (!is_fullscreen()) window_doinputrelease = 1; } - if (window_doremember) { + if (window_doremember) + { window_doremember = 0; SDL_GetWindowPosition(window, &window_x, &window_y); SDL_GetWindowSize(window, &window_w, &window_h); diff --git a/src/wx-sdl2-glw.h b/src/wx-sdl2-glw.h new file mode 100644 index 0000000..babf48b --- /dev/null +++ b/src/wx-sdl2-glw.h @@ -0,0 +1,92 @@ +#ifndef SRC_WX_SDL2_GLW_H_ +#define SRC_WX_SDL2_GLW_H_ + +typedef struct glw_t { + PFNGLACTIVETEXTUREPROC glActiveTexture; + PFNGLCREATESHADERPROC glCreateShader; + PFNGLSHADERSOURCEPROC glShaderSource; + PFNGLCOMPILESHADERPROC glCompileShader; + PFNGLGETSHADERIVPROC glGetShaderiv; + PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; + PFNGLCREATEPROGRAMPROC glCreateProgram; + PFNGLATTACHSHADERPROC glAttachShader; + PFNGLLINKPROGRAMPROC glLinkProgram; + PFNGLGETPROGRAMIVPROC glGetProgramiv; + PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; + PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; + PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; + PFNGLUSEPROGRAMPROC glUseProgram; + PFNGLGENERATEMIPMAPPROC glGenerateMipmap; + PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; + PFNGLDELETESHADERPROC glDeleteShader; + PFNGLDELETEPROGRAMPROC glDeleteProgram; + PFNGLDELETEBUFFERSPROC glDeleteBuffers; + PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; + PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; + PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; + PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; + PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; + PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; + PFNGLBINDVERTEXARRAYPROC glBindVertexArray; + PFNGLGENBUFFERSPROC glGenBuffers; + PFNGLBINDBUFFERPROC glBindBuffer; + PFNGLBUFFERDATAPROC glBufferData; + PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; + PFNGLUNIFORM1IPROC glUniform1i; + PFNGLUNIFORM1FPROC glUniform1f; + PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; + PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; + PFNGLUNIFORM2FVPROC glUniform2fv; + PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; + PFNGLBUFFERSUBDATAPROC glBufferSubData; +} glw_t; + +glw_t* glw_init() +{ + glw_t* glw = malloc(sizeof(glw_t)); + glw->glActiveTexture = SDL_GL_GetProcAddress("glActiveTexture"); + glw->glCreateShader = SDL_GL_GetProcAddress("glCreateShader"); + glw->glShaderSource = SDL_GL_GetProcAddress("glShaderSource"); + glw->glCompileShader = SDL_GL_GetProcAddress("glCompileShader"); + glw->glGetShaderiv = SDL_GL_GetProcAddress("glGetShaderiv"); + glw->glGetShaderInfoLog = SDL_GL_GetProcAddress("glGetShaderInfoLog"); + glw->glCreateProgram = SDL_GL_GetProcAddress("glCreateProgram"); + glw->glAttachShader = SDL_GL_GetProcAddress("glAttachShader"); + glw->glLinkProgram = SDL_GL_GetProcAddress("glLinkProgram"); + glw->glGetProgramiv = SDL_GL_GetProcAddress("glGetProgramiv"); + glw->glGetProgramInfoLog = SDL_GL_GetProcAddress("glGetProgramInfoLog"); + glw->glGetUniformLocation = SDL_GL_GetProcAddress("glGetUniformLocation"); + glw->glGetAttribLocation = SDL_GL_GetProcAddress("glGetAttribLocation"); + glw->glUseProgram = SDL_GL_GetProcAddress("glUseProgram"); + glw->glGenerateMipmap = SDL_GL_GetProcAddress("glGenerateMipmap"); + glw->glDeleteFramebuffers = SDL_GL_GetProcAddress("glDeleteFramebuffers"); + glw->glDeleteShader = SDL_GL_GetProcAddress("glDeleteShader"); + glw->glDeleteProgram = SDL_GL_GetProcAddress("glDeleteProgram"); + glw->glDeleteBuffers = SDL_GL_GetProcAddress("glDeleteBuffers"); + glw->glDeleteVertexArrays = SDL_GL_GetProcAddress("glDeleteVertexArrays"); + glw->glGenFramebuffers = SDL_GL_GetProcAddress("glGenFramebuffers"); + glw->glBindFramebuffer = SDL_GL_GetProcAddress("glBindFramebuffer"); + glw->glFramebufferTexture2D = SDL_GL_GetProcAddress("glFramebufferTexture2D"); + glw->glCheckFramebufferStatus = SDL_GL_GetProcAddress("glCheckFramebufferStatus"); + glw->glGenVertexArrays = SDL_GL_GetProcAddress("glGenVertexArrays"); + glw->glBindVertexArray = SDL_GL_GetProcAddress("glBindVertexArray"); + glw->glGenBuffers = SDL_GL_GetProcAddress("glGenBuffers"); + glw->glBindBuffer = SDL_GL_GetProcAddress("glBindBuffer"); + glw->glBufferData = SDL_GL_GetProcAddress("glBufferData"); + glw->glVertexAttribPointer = SDL_GL_GetProcAddress("glVertexAttribPointer"); + glw->glUniform1i = SDL_GL_GetProcAddress("glUniform1i"); + glw->glUniform1f = SDL_GL_GetProcAddress("glUniform1f"); + glw->glEnableVertexAttribArray = SDL_GL_GetProcAddress("glEnableVertexAttribArray"); + glw->glUniformMatrix4fv = SDL_GL_GetProcAddress("glUniformMatrix4fv"); + glw->glUniform2fv = SDL_GL_GetProcAddress("glUniform2fv"); + glw->glDisableVertexAttribArray = SDL_GL_GetProcAddress("glDisableVertexAttribArray"); + glw->glBufferSubData = SDL_GL_GetProcAddress("glBufferSubData"); + return glw; +} + +void glw_free(glw_t* glw) +{ + free(glw); +} + +#endif /* SRC_WX_SDL2_GLW_H_ */ diff --git a/src/wx-sdl2-hdconf.c b/src/wx-sdl2-hdconf.c deleted file mode 100644 index b4e1e51..0000000 --- a/src/wx-sdl2-hdconf.c +++ /dev/null @@ -1,961 +0,0 @@ -#include "wx-utils.h" -#include "wx-sdl2.h" - -#include "ibm.h" -#include "ide.h" -#include "hdd.h" - -static struct -{ - int cylinders; - int heads; -} hd_types[] = -{ - {306, 4}, {615, 4}, {615, 6}, {940, 8}, - {940, 6}, {615, 4}, {462, 8}, {733, 5}, - {900, 15}, {820, 3}, {855, 5}, {855, 7}, - {306, 8}, {733, 7}, {0, 0}, {612, 4}, - {977, 5}, {977, 7}, {1024, 7}, {733, 5}, - {733, 7}, {733, 5}, {306, 4}, {925, 7}, - {925, 9}, {754, 7}, {754, 11}, {699, 7}, - {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, - {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, - {615, 8}, {987, 3}, {462, 7}, {820, 6}, - {977, 5}, {981, 5}, {830, 7}, {830, 10}, - {917, 15}, {1224, 15} -}; - -static int hd_changed = 0; - -static char hd_new_name[512]; -static int hd_new_spt, hd_new_hpc, hd_new_cyl; -static int hd_new_type; -static int new_cdrom_channel; - -extern int pause; - -static void check_hd_type(off64_t sz) -{ - int c; - - hd_new_type = 0; - - if (hdd_controller_current_is_mfm()) - { - for (c = 0; c < 46; c++) - { - if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) - { - hd_new_spt = 17; - hd_new_hpc = hd_types[c].heads; - hd_new_cyl = hd_types[c].cylinders; - hd_new_type = c+1; - return; - } - } - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - } - else - { - if ((sz % 17) == 0 && sz <= 133693440) - { - hd_new_spt = 17; - - if (sz <= 26738688) - hd_new_hpc = 4; - else if ((sz % 3072) == 0 && sz <= 53477376) - hd_new_hpc = 6; - else - { - for (c=5;c<16;c++) - { - if((sz % (c * 512)) == 0 && sz <= 1024*c*17*512) break; - if (c == 5) c++; - } - hd_new_hpc = c; - } - - hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; - } - else - { - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - } - } -} - -#define ID_IS(s) wParam == wx_xrcid(s) -#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) - -static void update_hdd_cdrom(void* hdlg) -{ - void* h; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[0]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 0) ? 0 : 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[0]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 0) ? 1 : 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[1]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 1) ? 0 : 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[1]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 1) ? 1 : 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[2]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 2) ? 0 : 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[2]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 2) ? 1 : 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDD[3]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 3) ? 0 : 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[3]")); - wx_sendmessage(h, WX_BM_SETCHECK, (new_cdrom_channel == 3) ? 1 : 0, 0); -} - -static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) -{ - char s[260]; - void* h; - int c; - PcemHDC hd[4]; - FILE *f; - uint8_t buf[512]; - int hd_type; - - switch (message) - { - case WX_INITDIALOG: - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - sprintf(s, "%i", 63); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", 16); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", 511); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)""); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "Size : %imb", (((511*16*63)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - -// hd_type = 0; - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); - for (c = 1; c <= 46; c++) - { - sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - - return TRUE; - case WX_COMMAND: - if (wParam == wxID_OK) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)hd_new_name); - if (!hd_new_name[0]) - { - wx_messagebox(NULL,"Please enter a valid filename","PCem error",WX_MB_OK); - return TRUE; - } - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_cyl); - - if (hd_new_spt > 63) - { - wx_messagebox(NULL, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); - return TRUE; - } - if (hd_new_hpc > 16) - { - wx_messagebox(NULL, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); - return TRUE; - } - if (hd_new_cyl > 16383) - { - wx_messagebox(NULL, "Drive has too many cylinders (maximum is 16383)", "PCem error", WX_MB_OK); - return TRUE; - } - - f = fopen64(hd_new_name, "wb"); - if (!f) - { - wx_messagebox(NULL, "Can't open file for write", "PCem error", WX_MB_OK); - return TRUE; - } - memset(buf, 0, 512); - for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) - fwrite(buf, 512, 1, f); - fclose(f); - - wx_messagebox(NULL, "Remember to partition and format the new drive", "PCem", WX_MB_OK); - - wx_enddialog(hdlg, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg, 0); - return TRUE; - } else if (ID_IS("IDC_CFILE")) { - if (!getsfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "", NULL, "img")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) openfilestring); - } - return TRUE; - } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT1: %s\n", s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT2: %s\n", s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT3: %s\n", s); - sscanf(s, "%i", &hd[0].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_type = 0; - for (c = 1; c <= 46; c++) - { - pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt,17, hd[0].hpc,hd_types[c-1].heads, hd[0].tracks,hd_types[c-1].cylinders); - if (hd[0].spt == 17 && hd[0].hpc == hd_types[c-1].heads && hd[0].tracks == hd_types[c-1].cylinders) - { - hd_type = c; - break; - } - } - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); - - return TRUE; - } else if (ID_IS("IDC_HDTYPE")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hd_type) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", hd_types[hd_type-1].cylinders); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", hd_types[hd_type-1].heads); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"17"); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "Size : %imb", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - } - return TRUE; - } - break; - - } - return FALSE; -} - -static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) -{ - char s[260]; - void* h; - PcemHDC hd[2]; - int c; - - switch (message) - { - case WX_INITDIALOG: - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); - for (c = 1; c <= 46; c++) - { - sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - wx_sendmessage(h, WX_CB_SETCURSEL, hd_new_type, 0); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "Size : %imb", (int)((((uint64_t)hd_new_spt*(uint64_t)hd_new_hpc*(uint64_t)hd_new_cyl)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - return TRUE; - case WX_COMMAND: - if (wParam == wxID_OK) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_cyl); - - if (hd_new_spt > 63) - { - wx_messagebox(NULL,"Drive has too many sectors (maximum is 63)","PCem error",WX_MB_OK); - return TRUE; - } - if (hd_new_hpc > 16) - { - wx_messagebox(NULL,"Drive has too many heads (maximum is 16)","PCem error",WX_MB_OK); - return TRUE; - } - if (hd_new_cyl > 16383) - { - wx_messagebox(NULL,"Drive has too many cylinders (maximum is 16383)","PCem error",WX_MB_OK); - return TRUE; - } - - wx_enddialog(hdlg,1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg,0); - return TRUE; - } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } - - } - return FALSE; -} - -static int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) -{ - char s[260]; - void* h; - PcemHDC hd[4]; - FILE *f; - off64_t sz; - switch (message) - { - case WX_INITDIALOG: - pause = 1; - hd[0] = hdc[0]; - hd[1] = hdc[1]; - hd[2] = hdc[2]; - hd[3] = hdc[3]; - hd_changed = 0; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - sprintf(s, "%i", hdc[0].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - sprintf(s, "%i", hdc[0].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - sprintf(s, "%i", hdc[0].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[0]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - sprintf(s, "%i", hdc[1].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - sprintf(s, "%i", hdc[1].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - sprintf(s, "%i", hdc[1].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[1]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - sprintf(s, "%i", hdc[2].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - sprintf(s, "%i", hdc[2].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - sprintf(s, "%i", hdc[2].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[2]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - sprintf(s, "%i", hdc[3].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - sprintf(s, "%i", hdc[3].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - sprintf(s, "%i", hdc[3].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[3]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[1].tracks*(uint64_t)hd[1].hpc)*(uint64_t)hd[1].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[2].tracks*(uint64_t)hd[2].hpc)*(uint64_t)hd[2].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[3].tracks*(uint64_t)hd[3].hpc)*(uint64_t)hd[3].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - new_cdrom_channel = cdrom_channel; - - update_hdd_cdrom(hdlg); - - if (hdd_controller_current_is_mfm()) { - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_PANEL[2]")), 0); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_PANEL[3]")), 0); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_HDD[0]")), 0); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_HDD[1]")), 0); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[0]")), 0); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CDROM[1]")), 0); - } - return TRUE; - - case WX_COMMAND: - if (wParam == wxID_OK) - { - if (hd_changed || cdrom_channel != new_cdrom_channel) - { - if (!has_been_inited || confirm()) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[0]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[1]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[2]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[3]); - - hdc[0] = hd[0]; - hdc[1] = hd[1]; - hdc[2] = hd[2]; - hdc[3] = hd[3]; - - cdrom_channel = new_cdrom_channel; - - if (has_been_inited) - { - saveconfig(NULL); - - resetpchard(); - } - } - } - } - if (wParam == wxID_OK || wParam == wxID_CANCEL) - { - wx_enddialog(hdlg, 0); - pause = 0; - return TRUE; - } else if (ID_IS("IDC_EJECT[0]")) - { - hd[0].spt = 0; - hd[0].hpc = 0; - hd[0].tracks = 0; - ide_fn[0][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[0]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[0]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[0]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[0]"), ""); - hd_changed = 1; - return TRUE; - } else if (ID_IS("IDC_EJECT[1]")) - { - hd[1].spt = 0; - hd[1].hpc = 0; - hd[1].tracks = 0; - ide_fn[1][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[1]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[1]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[1]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[1]"), ""); - hd_changed = 1; - return TRUE; - } else if (ID_IS("IDC_EJECT[2]")) - { - hd[2].spt = 0; - hd[2].hpc = 0; - hd[2].tracks = 0; - ide_fn[2][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[2]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[2]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[2]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[2]"), ""); - hd_changed = 1; - return TRUE; - } else if (ID_IS("IDC_EJECT[3]")) - { - hd[3].spt = 0; - hd[3].hpc = 0; - hd[3].tracks = 0; - ide_fn[3][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[3]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[3]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[3]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[3]"), ""); - hd_changed = 1; - return TRUE; - } - else if (ID_IS("IDC_NEW[0]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[0]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - - } - else if (ID_IS("IDC_NEW[1]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[1]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - } - else if (ID_IS("IDC_NEW[2]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[2]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - } - else if (ID_IS("IDC_NEW[3]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[3]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(NULL,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - } - else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "Size : %imb", ((((hd[0].tracks*hd[0].hpc)*hd[0].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } - else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "Size : %imb", ((((hd[1].tracks*hd[1].hpc)*hd[1].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } - else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "Size : %imb", ((((hd[2].tracks*hd[2].hpc)*hd[2].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } - else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "Size : %imb", ((((hd[3].tracks*hd[3].hpc)*hd[3].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } - else if (ID_IS("IDC_HDD[0]")) - { - if (new_cdrom_channel == 0) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_HDD[1]")) - { - if (new_cdrom_channel == 1) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_HDD[2]")) - { - if (new_cdrom_channel == 2) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_HDD[3]")) - { - if (new_cdrom_channel == 3) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - - } - else if (ID_IS("IDC_CDROM[0]")) - { - new_cdrom_channel = 0; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_CDROM[1]")) - { - new_cdrom_channel = 1; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_CDROM[2]")) - { - new_cdrom_channel = 2; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_CDROM[3]")) - { - new_cdrom_channel = 3; - update_hdd_cdrom(hdlg); - return TRUE; - } - - } - return FALSE; -} - -void hdconf_open(void* hwnd) -{ - wx_dialogbox(hwnd, "HdConfDlg", hdconf_dlgproc); -} diff --git a/src/wx-sdl2-keyboard.c b/src/wx-sdl2-keyboard.c index df2cffe..12eb626 100644 --- a/src/wx-sdl2-keyboard.c +++ b/src/wx-sdl2-keyboard.c @@ -18,6 +18,6 @@ void keyboard_poll_host() int c; for (c = 0; c < 272; ++c) - pcem_key[c] = rawinputkey[c]; + pcem_key[c] = rawinputkey[c] > 0; } diff --git a/src/wx-sdl2-midi.c b/src/wx-sdl2-midi.c index 9ad75b0..9f89456 100644 --- a/src/wx-sdl2-midi.c +++ b/src/wx-sdl2-midi.c @@ -12,3 +12,12 @@ void midi_close() void midi_write(uint8_t val) { } + +int midi_get_num_devs() +{ + return 0; +} + +void midi_get_dev_name(int num, char *s) +{ +} diff --git a/src/wx-sdl2-mouse.c b/src/wx-sdl2-mouse.c index 1f61758..a9326cf 100644 --- a/src/wx-sdl2-mouse.c +++ b/src/wx-sdl2-mouse.c @@ -1,4 +1,5 @@ -#include +#include +#include #include "plat-mouse.h" int mouse_buttons; diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 78bacfb..9286c9c 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -1,8 +1,9 @@ +#include +#include "video.h" #include "wx-sdl2.h" #include "wx-sdl2-video.h" #include "ibm.h" #include "device.h" -#include "video.h" #include "x86_ops.h" #include "mem.h" #include "codegen.h" diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c new file mode 100644 index 0000000..2030190 --- /dev/null +++ b/src/wx-sdl2-video-gl3.c @@ -0,0 +1,1656 @@ +#include +#define BITMAP WINDOWS_BITMAP +#include +#if SDL_VERSION_ATLEAST(2, 0, 4) +#include +#endif +#undef BITMAP +#include "wx-sdl2-glw.h" +#include +#include +#include +#include "video.h" +#include "wx-sdl2-video.h" +#include "wx-sdl2-video-renderer.h" +#include "ibm.h" +#include "wx-glslp-parser.h" +#include "wx-utils.h" +#include "config.h" +#include "wx-glsl.h" + +extern char* get_filename(char*); + +extern int take_screenshot; +extern void screenshot_taken(unsigned char* rgb, int width, int height); + +#define SCALE_SOURCE 0 +#define SCALE_VIEWPORT 1 +#define SCALE_ABSOLUTE 2 + +float gl3_shader_refresh_rate = 0; +float gl3_input_scale = 1.0f; +int gl3_input_stretch = FULLSCR_SCALE_FULL; +char gl3_shader_file[MAX_USER_SHADERS][512]; + +static int max_texture_size; + +static SDL_GLContext context = NULL; +static struct shader_texture scene_texture; + +static glsl_t* active_shader; + +static glw_t* glw; + +static GLfloat matrix[] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +}; + + +extern int video_scale_mode; +extern int video_vsync; +extern int video_focus_dim; +extern int video_refresh_rate; + +const char* vertex_shader_default_tex_src = + "#version 130\n" + "\n" + "in vec4 VertexCoord;\n" + "in vec2 TexCoord;\n" + "\n" + "out vec2 texCoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " texCoord = TexCoord;\n" + "}\n"; + +const char* fragment_shader_default_tex_src = + "#version 130\n" + "\n" + "in vec2 texCoord;\n" + "uniform sampler2D Texture;\n" + "\n" + "out vec4 color;" + "\n" + "void main()\n" + "{\n" + " color = texture(Texture, texCoord);\n" + "}\n"; + +const char* vertex_shader_default_color_src = + "#version 130\n" + "\n" + "in vec4 VertexCoord;\n" + "in vec4 Color;\n" + "\n" + "out vec4 color;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " color = Color;\n" + "}\n"; + +const char* fragment_shader_default_color_src = + "#version 130\n" + "\n" + "in vec4 color;\n" + "\n" + "out vec4 outColor;" + "\n" + "void main()\n" + "{\n" + " outColor = color;\n" + "}\n"; + +static int next_pow2(unsigned int n) +{ + n--; + n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32, + n |= n >> 2; // and then or the results. + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; + + return n; +} + +static int compile_shader(GLenum shader_type, const char* prepend, const char* program, int* dst) +{ + const char* source[3]; + source[0] = ""; + source[1] = prepend ? prepend : ""; + source[2] = 0; + char version[50]; + if (strstr(program, "#version")) + { + char* line = strchr(program, '\n'); + int len = (line-program)+1; + if (len >= sizeof(version)-1) len = sizeof(version)-1; + strncpy(version, program, len); + version[len] = 0; + source[0] = version; + source[2] = line; + } + else + { +// source[0] = "#version 130\n"; + source[2] = program; + } + + GLuint shader = glw->glCreateShader(shader_type); + glw->glShaderSource(shader, 3, source, NULL); + glw->glCompileShader(shader); + + GLint status = 0; + glw->glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status) + { + GLint length; + glw->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); + char* log = malloc(length); + glw->glGetShaderInfoLog(shader, length, &length, log); + wx_simple_messagebox("GLSL Error", "Could not compile shader:\n%s", log); + pclog("Could not compile shader: %s\n", log); +// pclog("Shader: %s\n", program); + + free(log); + return 0; + } + + *dst = shader; + + return 1; +} + +static int create_program(struct shader_program* program) +{ + GLint status; + program->id = glw->glCreateProgram(); + glw->glAttachShader(program->id, program->vertex_shader); + glw->glAttachShader(program->id, program->fragment_shader); + + glw->glLinkProgram(program->id); + + glw->glDeleteShader(program->vertex_shader); + glw->glDeleteShader(program->fragment_shader); + + program->vertex_shader = program->fragment_shader = 0; + + glw->glGetProgramiv(program->id, GL_LINK_STATUS, &status); + + if (!status) + { + int maxLength; + int length; + glw->glGetProgramiv(program->id, GL_INFO_LOG_LENGTH, &maxLength); + char* log = malloc(maxLength); + glw->glGetProgramInfoLog(program->id, maxLength, &length, log); + wx_simple_messagebox("GLSL Error", "Program not linked:\n%s", log); + free(log); + return 0; + } + + return 1; +} + +static GLuint get_uniform(GLuint program, const char* name) +{ + return glw->glGetUniformLocation(program, name); +} + +static GLuint get_attrib(GLuint program, const char* name) +{ + return glw->glGetAttribLocation(program, name); +} + +static void find_uniforms(struct glsl_shader* glsl, int num_pass) +{ + int i; + char s[50]; + struct shader_pass* pass = &glsl->passes[num_pass]; + int p = pass->program.id; + glw->glUseProgram(p); + + struct shader_uniforms* u = &pass->uniforms; + + u->mvp_matrix = get_uniform(p, "MVPMatrix"); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->tex_coord = get_attrib(p, "TexCoord"); + u->color = get_attrib(p, "Color"); + + u->frame_count = get_uniform(p, "FrameCount"); + u->frame_direction = get_uniform(p, "FrameDirection"); + + u->texture = get_uniform(p, "Texture"); + u->input_size = get_uniform(p, "InputSize"); + u->texture_size = get_uniform(p, "TextureSize"); + u->output_size = get_uniform(p, "OutputSize"); + + u->orig.texture = get_uniform(p, "OrigTexture"); + u->orig.input_size = get_uniform(p, "OrigInputSize"); + u->orig.texture_size = get_uniform(p, "OrigTextureSize"); + + for (i = 0; i < glsl->num_passes; ++i) + { + sprintf(s, "Pass%dTexture", (i+1)); + u->pass[i].texture = get_uniform(p, s); + sprintf(s, "Pass%dInputSize", (i+1)); + u->pass[i].input_size = get_uniform(p, s); + sprintf(s, "Pass%dTextureSize", (i+1)); + u->pass[i].texture_size = get_uniform(p, s); + + sprintf(s, "PassPrev%dTexture", num_pass-i); + u->prev_pass[i].texture = get_uniform(p, s); + sprintf(s, "PassPrev%dInputSize", num_pass-i); + u->prev_pass[i].input_size = get_uniform(p, s); + sprintf(s, "PassPrev%dTextureSize", num_pass-i); + u->prev_pass[i].texture_size = get_uniform(p, s); + } + + u->prev[0].texture = get_uniform(p, "PrevTexture"); + u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); + for (i = 1; i < MAX_PREV; ++i) + { + sprintf(s, "Prev%dTexture", i); + u->prev[i].texture = get_uniform(p, s); + sprintf(s, "Prev%dTexCoord", i); + u->prev[i].tex_coord = get_attrib(p, s); + } + for (i = 0; i < MAX_PREV; ++i) + if (u->prev[i].texture >= 0) glsl->has_prev = 1; + + for (i = 0; i < glsl->num_lut_textures; ++i) + u->lut_textures[i] = get_uniform(p, glsl->lut_textures[i].name); + + for (i = 0; i < glsl->num_parameters; ++i) + u->parameters[i] = get_uniform(p, glsl->parameters[i].id); + + glw->glUseProgram(0); +} + +static void set_scale_mode(char* scale, int* dst) +{ + if (!strcmp(scale, "viewport")) + *dst = SCALE_VIEWPORT; + else if (!strcmp(scale, "absolute")) + *dst = SCALE_ABSOLUTE; + else + *dst = SCALE_SOURCE; +} + +static void setup_scale(struct shader* shader, struct shader_pass* pass) +{ + set_scale_mode(shader->scale_type_x, &pass->scale.mode[0]); + set_scale_mode(shader->scale_type_y, &pass->scale.mode[1]); + pass->scale.value[0] = shader->scale_x; + pass->scale.value[1] = shader->scale_y; +} + +static void create_texture(struct shader_texture* tex) +{ + if (tex->width > max_texture_size) + tex->width = max_texture_size; + if (tex->height > max_texture_size) + tex->height = max_texture_size; + pclog("Create texture with size %dx%d\n", tex->width, tex->height); + glGenTextures(1, &tex->id); + glBindTexture(GL_TEXTURE_2D, tex->id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter); + glTexImage2D(GL_TEXTURE_2D, 0, tex->internal_format, tex->width, tex->height, 0, tex->format, tex->type, tex->data); + if (tex->mipmap) + glw->glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} + +static void delete_texture(struct shader_texture* tex) +{ + if (tex->id > 0) + glDeleteTextures(1, &tex->id); + tex->id = 0; +} + +static void delete_fbo(struct shader_fbo* fbo) +{ + if (fbo->id >= 0) + { + glw->glDeleteFramebuffers(1, &fbo->id); + delete_texture(&fbo->texture); + } +} + +static void delete_program(struct shader_program* program) +{ + if (program->vertex_shader) glw->glDeleteShader(program->vertex_shader); + if (program->fragment_shader) glw->glDeleteShader(program->fragment_shader); + glw->glDeleteProgram(program->id); +} + +static void delete_vbo(struct shader_vbo* vbo) +{ + if (vbo->color >= 0) glw->glDeleteBuffers(1, &vbo->color); + glw->glDeleteBuffers(1, &vbo->vertex_coord); + glw->glDeleteBuffers(1, &vbo->tex_coord); +} + +static void delete_pass(struct shader_pass* pass) +{ + delete_fbo(&pass->fbo); + delete_vbo(&pass->vbo); + delete_program(&pass->program); + glw->glDeleteVertexArrays(1, &pass->vertex_array); +} + +static void delete_prev(struct shader_prev* prev) +{ + delete_fbo(&prev->fbo); + delete_vbo(&prev->vbo); +} + +static void delete_shader(struct glsl_shader* glsl) +{ + int i; + for (i = 0; i < glsl->num_passes; ++i) + delete_pass(&glsl->passes[i]); + if (glsl->has_prev) + { + delete_pass(&glsl->prev_scene); + for (i = 0; i < MAX_PREV; ++i) + delete_prev(&glsl->prev[i]); + } + for (i = 0; i < glsl->num_lut_textures; ++i) + delete_texture(&glsl->lut_textures[i].texture); +} + +static void delete_glsl(glsl_t* glsl) +{ + int i; + for (i = 0; i < glsl->num_shaders; ++i) + delete_shader(&glsl->shaders[i]); + delete_pass(&glsl->scene); + delete_pass(&glsl->fs_color); + delete_pass(&glsl->final_pass); +#ifdef SDL2_SHADER_DEBUG + delete_pass(&glsl->debug); +#endif +} + +static void create_fbo(struct shader_fbo* fbo) +{ + create_texture(&fbo->texture); + + glw->glGenFramebuffers(1, &fbo->id); + glw->glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); + glw->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); + + if (glw->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + pclog("Could not create framebuffer!\n"); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +static void setup_fbo(struct shader* shader, struct shader_fbo* fbo) +{ + fbo->texture.internal_format = GL_RGBA8; + fbo->texture.format = GL_RGBA; + fbo->texture.min_filter = fbo->texture.mag_filter = shader->filter_linear ? GL_LINEAR : GL_NEAREST; + fbo->texture.width = 1024; + fbo->texture.height = 1024; + fbo->texture.type = GL_UNSIGNED_BYTE; + if (!strcmp(shader->wrap_mode, "repeat")) + fbo->texture.wrap_mode = GL_REPEAT; + else if (!strcmp(shader->wrap_mode, "mirrored_repeat")) + fbo->texture.wrap_mode = GL_MIRRORED_REPEAT; + else if (!strcmp(shader->wrap_mode, "clamp_to_edge")) + fbo->texture.wrap_mode = GL_CLAMP_TO_EDGE; + else + fbo->texture.wrap_mode = GL_CLAMP_TO_BORDER; + fbo->srgb = 0; + if (shader->srgb_framebuffer) + { + fbo->texture.internal_format = GL_SRGB8_ALPHA8; + fbo->srgb = 1; + } + else if (shader->float_framebuffer) + { + fbo->texture.internal_format = GL_RGBA32F; + fbo->texture.type = GL_FLOAT; + } + + if (fbo->texture.mipmap) + fbo->texture.min_filter = shader->filter_linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; + + create_fbo(fbo); +} + +static void recreate_fbo(struct shader_fbo* fbo, int width, int height) +{ + if (width != fbo->texture.width || height != fbo->texture.height) + { + glw->glDeleteFramebuffers(1, &fbo->id); + glDeleteTextures(1, &fbo->texture.id); + fbo->texture.width = width; + fbo->texture.height = height; + create_fbo(fbo); + } +} + +static int create_default_shader_tex(struct shader_pass* pass) +{ + if ( + !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_tex_src, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_tex_src, &pass->program.fragment_shader) || + !create_program(&pass->program)) + return 0; + glw->glGenVertexArrays(1, &pass->vertex_array); + + struct shader_uniforms* u = &pass->uniforms; + int p = pass->program.id; + memset(u, -1, sizeof(struct shader_uniforms)); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->tex_coord = get_attrib(p, "TexCoord"); + u->texture = get_uniform(p, "Texture"); + pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; + pass->scale.value[0] = pass->scale.value[1] = 1.0f; + pass->fbo.id = -1; + pass->active = 1; + return 1; +} + +static int create_default_shader_color(struct shader_pass* pass) +{ + if ( + !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_color_src, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_color_src, &pass->program.fragment_shader) || + !create_program(&pass->program)) + return 0; + glw->glGenVertexArrays(1, &pass->vertex_array); + + struct shader_uniforms* u = &pass->uniforms; + int p = pass->program.id; + memset(u, -1, sizeof(struct shader_uniforms)); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->color = get_attrib(p, "Color"); + pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; + pass->scale.value[0] = pass->scale.value[1] = 1.0f; + pass->fbo.id = -1; + pass->active = 1; + return 1; +} + +/* create the default scene shader */ +static void create_scene_shader() +{ + struct shader scene_shader_conf; + memset(&scene_shader_conf, 0, sizeof(struct shader)); + create_default_shader_tex(&active_shader->scene); + setup_fbo(&scene_shader_conf, &active_shader->scene.fbo); + + memset(&scene_shader_conf, 0, sizeof(struct shader)); + create_default_shader_color(&active_shader->fs_color); + setup_fbo(&scene_shader_conf, &active_shader->fs_color.fbo); +} + +static int load_texture(const char* f, struct shader_texture* tex) +{ + void* img = wx_image_load(f); + if (!img) + return 0; + int width, height; + wx_image_get_size(img, &width, &height); + + if (width != next_pow2(width) || height != next_pow2(height)) + wx_image_rescale(img, next_pow2(width), next_pow2(height)); + + wx_image_get_size(img, &width, &height); + + GLubyte* rgb = wx_image_get_data(img); + GLubyte* alpha = wx_image_get_alpha(img); + + int bpp = alpha ? 4 : 3; + + GLubyte* data = malloc(width*height*bpp); + + int x, y, Y; + for (y = 0; y < height; ++y) + { + Y = height-y-1; + for (x = 0; x < width; x++) + { + data[(y*width+x)*bpp+0] = rgb[(Y*width+x)*3+0]; + data[(y*width+x)*bpp+1] = rgb[(Y*width+x)*3+1]; + data[(y*width+x)*bpp+2] = rgb[(Y*width+x)*3+2]; + + if (alpha) + data[(y*width+x)*bpp+3] = alpha[Y*width+x]; + } + } + wx_image_free(img); + + tex->width = width; + tex->height = height; + tex->internal_format = alpha ? GL_RGBA8 : GL_RGB8; + tex->format = alpha ? GL_RGBA : GL_RGB; + tex->type = GL_UNSIGNED_BYTE; + tex->data = data; + return 1; +} + +static glsl_t* load_glslp(glsl_t* glsl, int num_shader, const char* f) +{ + int i, j; + glslp_t* p = glslp_parse(f); + + if (p) + { + char path[512]; + char file[512]; + int failed = 0; + strcpy(path, f); + char* filename = get_filename(path); + + struct glsl_shader* gshader = &glsl->shaders[num_shader]; + + strcpy(gshader->name, p->name); + *filename = 0; + + gshader->num_lut_textures = p->num_textures; + + for (i = 0; i < p->num_textures; ++i) + { + struct texture* texture = &p->textures[i]; + + sprintf(file, "%s%s", path, texture->path); + + struct shader_lut_texture* tex = &gshader->lut_textures[i]; + strcpy(tex->name, texture->name); + + pclog("Load texture %s...\n", file); + + if (!load_texture(file, &tex->texture)) + { + wx_simple_messagebox("GLSL Error", "Could not load texture: %s", file); + pclog("Could not load texture %s!\n", file); + failed = 1; + break; + } + + if (!strcmp(texture->wrap_mode, "repeat")) + tex->texture.wrap_mode = GL_REPEAT; + else if (!strcmp(texture->wrap_mode, "mirrored_repeat")) + tex->texture.wrap_mode = GL_MIRRORED_REPEAT; + else if (!strcmp(texture->wrap_mode, "clamp_to_edge")) + tex->texture.wrap_mode = GL_CLAMP_TO_EDGE; + else + tex->texture.wrap_mode = GL_CLAMP_TO_BORDER; + + tex->texture.mipmap = texture->mipmap; + + tex->texture.min_filter = tex->texture.mag_filter = texture->linear ? GL_LINEAR : GL_NEAREST; + if (tex->texture.mipmap) + tex->texture.min_filter = texture->linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; + + create_texture(&tex->texture); + free(tex->texture.data); + tex->texture.data = 0; + } + + if (!failed) + { + gshader->num_parameters = p->num_parameters; + for (j = 0; j < gshader->num_parameters; ++j) + memcpy(&gshader->parameters[j], &p->parameters[j], sizeof(struct shader_parameter)); + + gshader->num_passes = p->num_shaders; + + for (i = 0; i < p->num_shaders; ++i) + { + struct shader* shader = &p->shaders[i]; + struct shader_pass* pass = &gshader->passes[i]; + + strcpy(pass->alias, shader->alias); + if (!strlen(pass->alias)) + sprintf(pass->alias, "Pass %u", (i+1)); + + pclog("Creating pass %u (%s)\n", (i+1), pass->alias); + pclog("Loading shader %s...\n", shader->shader_fn); + if (!shader->shader_program) + { + wx_simple_messagebox("GLSL Error", "Could not load shader: %s", shader->shader_fn); + pclog("Could not load shader %s\n", shader->shader_fn); + failed = 1; + break; + } + else + pclog("Shader %s loaded\n", shader->shader_fn); + failed = + !compile_shader(GL_VERTEX_SHADER, "#define VERTEX\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.fragment_shader); + if (failed) + break; + + if (!create_program(&pass->program)) + { + failed = 1; + break; + } + pass->frame_count_mod = shader->frame_count_mod; + + glw->glGenVertexArrays(1, &pass->vertex_array); + find_uniforms(gshader, i); + setup_scale(shader, pass); + if (i == p->num_shaders-1) /* last pass may or may not be an fbo depending on scale */ + { + if (num_shader == glsl->num_shaders-1) + { + pass->fbo.id = -1; + + for (j = 0; j < 2; ++j) + { + if (pass->scale.mode[j] != SCALE_SOURCE || pass->scale.value[j] != 1) + { + setup_fbo(shader, &pass->fbo); + break; + } + } + } + else + setup_fbo(shader, &pass->fbo); + } + else + { + /* check if next pass wants the input mipmapped, if so we need to generate mipmaps of this pass */ + pass->fbo.texture.mipmap = (i+1) < p->num_shaders && p->shaders[i+1].mipmap_input; + setup_fbo(shader, &pass->fbo); + } + if (pass->fbo.srgb) glsl->srgb = 1; + pass->active = 1; + } + if (!failed) + { + if (gshader->has_prev) + { + struct shader scene_shader_conf; + memset(&scene_shader_conf, 0, sizeof(struct shader)); + for (i = 0; i < MAX_PREV; ++i) + { + setup_fbo(&scene_shader_conf, &gshader->prev[i].fbo); + } + + } + } + } + + glslp_free(p); + + return glsl; + } + return 0; +} + +static glsl_t* load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) +{ + int i; + glsl_t* glsl; + + glsl = malloc(sizeof(glsl_t)); + memset(glsl, 0, sizeof(glsl_t)); + + glsl->num_shaders = num; + int failed = 0; + for (i = 0; i < num; ++i) + { + const char* f = shaders[i]; + if (f && strlen(f)) + { + struct glsl_shader* shader = &glsl->shaders[num-i-1]; + + if (!load_glslp(glsl, i, f)) + { + failed = 1; + break; + } + } + + } + if (failed) + { + delete_glsl(glsl); + memset(glsl, 0, sizeof(glsl_t)); + } + return glsl; +} + +static void read_shader_config() +{ + char s[512]; + int i, j; + for (i = 0; i < active_shader->num_shaders; ++i) + { + struct glsl_shader* shader = &active_shader->shaders[i]; + char* name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); +// shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); + for (j = 0; j < shader->num_parameters; ++j) + { + struct shader_parameter* param = &shader->parameters[j]; + param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); + } + } +} + +int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITMAP* screen) +{ + int i, j; + + strcpy(current_render_driver_name, requested_render_driver.name); + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + + context = SDL_GL_CreateContext(window); + + if (!context) + { + pclog("Could not create GL context.\n"); + return FALSE; + } + + SDL_GL_SetSwapInterval(video_vsync ? 1 : 0); + + pclog("OpenGL information: [%s] %s (%s)\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); + int version = -1; + glGetIntegerv(GL_MAJOR_VERSION, &version); + if (version < 3) + { + pclog("OpenGL 3.0 is not available."); + return SDL_FALSE; + } + pclog("Using OpenGL %s\n", glGetString(GL_VERSION)); + pclog("Using Shading Language %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + pclog("Max texture size: %dx%d\n", max_texture_size, max_texture_size); + + //SDL_GL_MakeCurrent(window, context); + + glw = glw_init(); + + glEnable(GL_TEXTURE_2D); + + scene_texture.data = screen->dat; + scene_texture.width = screen->w; + scene_texture.height = screen->h; + scene_texture.internal_format = GL_RGBA8; + scene_texture.format = GL_RGBA; + scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; + scene_texture.wrap_mode = GL_CLAMP_TO_BORDER; + scene_texture.min_filter = scene_texture.mag_filter = video_scale_mode ? GL_LINEAR : GL_NEAREST; + scene_texture.mipmap = 0; + + create_texture(&scene_texture); + + GLint status; + char buffer[512]; + + /* load shader */ +// const char* shaders[1]; +// shaders[0] = gl3_shader_file; +// +// active_shader = load_shaders(1, shaders); + +// const char* shaders[3]; +// shaders[0] = "/home/phantasy/git/glsl-shaders/ntsc/ntsc-320px.glslp"; +// shaders[1] = "/home/phantasy/git/glsl-shaders/motionblur/motionblur-simple.glslp"; +// shaders[2] = "/home/phantasy/git/glsl-shaders/crt/crt-lottes-multipass.glslp"; +// +// active_shader = load_shaders(3, shaders); + int num_shaders = 0; + for (i = 0; i < MAX_USER_SHADERS; ++i) + { + if (strlen(gl3_shader_file[i])) + ++num_shaders; + else + break; + } + active_shader = load_shaders(num_shaders, gl3_shader_file); + + create_scene_shader(); + + /* read config */ + read_shader_config(); + + /* buffers */ + + GLfloat vertex[] = { + -1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f + }; + + GLfloat inv_vertex[] = { + -1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, 1.0f, + 1.0f, -1.0f + }; + + GLfloat tex_coords[] = { + 0.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f + }; + + + GLfloat colors[] = { + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + + + /* set the scene shader buffers */ + { + glw->glBindVertexArray(active_shader->scene.vertex_array); + + struct shader_vbo* vbo = &active_shader->scene.vbo; + + glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(inv_vertex), inv_vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(active_shader->scene.uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, &vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(active_shader->scene.uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + } + + /* set buffers for all passes */ + for (j = 0; j < active_shader->num_shaders; ++j) + { + struct glsl_shader* shader = &active_shader->shaders[j]; + for (i = 0; i < shader->num_passes; ++i) + { + struct shader_uniforms* u = &shader->passes[i].uniforms; + + glw->glBindVertexArray(shader->passes[i].vertex_array); + + struct shader_vbo* vbo = &shader->passes[i].vbo; + + glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + + glw->glVertexAttribPointer(u->vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, &vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(u->tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + + if (u->color) + { + glw->glGenBuffers(1, &vbo->color); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); + glw->glVertexAttribPointer(u->color, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)0); + } + } + } + + for (i = 0; i < active_shader->num_shaders; ++i) + { + struct glsl_shader* shader = &active_shader->shaders[i]; + if (shader->has_prev) + { + struct shader_pass* prev_pass = &shader->prev_scene; + create_default_shader_tex(prev_pass); + + struct shader_vbo* vbo = &prev_pass->vbo; + + glw->glBindVertexArray(prev_pass->vertex_array); + + glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(prev_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, &vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(prev_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + + for (j = 0; j < MAX_PREV; ++j) + { + struct shader_prev* prev = &shader->prev[j]; + struct shader_vbo* prev_vbo = &prev->vbo; + + glw->glGenBuffers(1, &prev_vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + + glw->glGenBuffers(1, &prev_vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + } + } + } + + /* create final pass */ + if (active_shader->num_shaders == 0 || active_shader->shaders[active_shader->num_shaders-1].passes[active_shader->shaders[active_shader->num_shaders-1].num_passes-1].fbo.id >= 0) + { + struct shader_pass* final_pass = &active_shader->final_pass; + create_default_shader_tex(final_pass); + + glw->glBindVertexArray(final_pass->vertex_array); + + struct shader_vbo* vbo = &final_pass->vbo; + + glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(final_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, &vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(final_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + } + + { + struct shader_pass* color_pass = &active_shader->fs_color; + create_default_shader_color(color_pass); + + glw->glBindVertexArray(color_pass->vertex_array); + + struct shader_vbo* vbo = &color_pass->vbo; + + glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(color_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, &vbo->color); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(color_pass->uniforms.color, 4, GL_FLOAT, GL_TRUE, 4*sizeof(GLfloat), (GLvoid*)0); + + } +#ifdef SDL2_SHADER_DEBUG + struct shader_pass* debug_pass = &active_shader->debug; + create_default_shader(debug_pass); + + glBindVertexArray(debug_pass->vertex_array); + + struct shader_vbo* vbo = &debug_pass->vbo; + + glGenBuffers(1, &vbo->vertex_coord); + glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glVertexAttribPointer(debug_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glGenBuffers(1, &vbo->tex_coord); + glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glVertexAttribPointer(debug_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); +#endif + + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + glw->glBindVertexArray(0); + + return SDL_TRUE; +} + +void gl3_close() +{ + if (context) + { + delete_texture(&scene_texture); + + if (active_shader) + { + delete_glsl(active_shader); + free(active_shader); + } + active_shader = NULL; + + SDL_GL_DeleteContext(context); + context = NULL; + } + glw_free(glw); +} + +void gl3_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen) +{ + if (!context) + return; + glBindTexture(GL_TEXTURE_2D, scene_texture.id); + glPixelStorei(GL_UNPACK_ROW_LENGTH, screen->w); + glTexSubImage2D(GL_TEXTURE_2D, 0, updated_rect.x, updated_rect.y, updated_rect.w, updated_rect.h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glBindTexture(GL_TEXTURE_2D, 0); +} + +struct render_data { + int pass; + struct glsl_shader* shader; + struct shader_pass* shader_pass; + GLfloat* output_size; + struct shader_pass* orig_pass; + GLint texture; + int frame_count; +}; + +static void render_pass(struct render_data* data) +{ + int i; + char s[64]; + GLint loc; + GLuint texture_unit = 0; + +// pclog("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], pass->state.input_size[1], pass->state.input_texture_size[0], pass->state.input_texture_size[1], pass->state.output_size[0], pass->state.output_size[1], pass->state.output_texture_size[0], pass->state.output_texture_size[1], output_size[0], output_size[1]); + + glw->glBindVertexArray(data->shader_pass->vertex_array); + + GLint p = data->shader_pass->program.id; + struct shader_uniforms* u = &data->shader_pass->uniforms; + + glw->glUseProgram(p); + + if (data->texture) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->texture); + glw->glUniform1i(u->texture, texture_unit); + texture_unit++; + } + + if (u->color >= 0) glw->glEnableVertexAttribArray(u->color); + + if (u->mvp_matrix >= 0) glw->glUniformMatrix4fv(u->mvp_matrix, 1, 0, matrix); + if (u->frame_direction >= 0) glw->glUniform1i(u->frame_direction, 1); + + int framecnt = data->frame_count; + if (data->shader_pass->frame_count_mod > 0) + framecnt = framecnt%data->shader_pass->frame_count_mod; + if (u->frame_count >= 0) glw->glUniform1i(u->frame_count, framecnt); + + if (u->input_size >= 0) glw->glUniform2fv(u->input_size, 1, data->shader_pass->state.input_size); + if (u->texture_size >= 0) glw->glUniform2fv(u->texture_size, 1, data->shader_pass->state.input_texture_size); + if (u->output_size >= 0) glw->glUniform2fv(u->output_size, 1, data->output_size); + + if (data->shader) + { + /* parameters */ + for (i = 0; i < data->shader->num_parameters; ++i) + if (u->parameters[i] >= 0) glw->glUniform1f(u->parameters[i], data->shader->parameters[i].value); + + if (data->pass > 0) + { + struct shader_pass* passes = data->shader->passes; + struct shader_pass* orig = data->orig_pass; + if (u->orig.texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, orig->fbo.texture.id); + glw->glUniform1i(u->orig.texture, texture_unit); + texture_unit++; + } + if (u->orig.input_size >= 0) glw->glUniform2fv(u->orig.input_size, 1, orig->state.input_size); + if (u->orig.texture_size >= 0) glw->glUniform2fv(u->orig.texture_size, 1, orig->state.input_texture_size); + + for (i = 0; i < data->pass; ++i) + { + if (u->pass[i].texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); + glw->glUniform1i(u->pass[i].texture, texture_unit); + texture_unit++; + } + if (u->pass[i].texture_size >= 0) glw->glUniform2fv(u->pass[i].texture_size, 1, passes[i].state.input_texture_size); + if (u->pass[i].input_size >= 0) glw->glUniform2fv(u->pass[i].input_size, 1, passes[i].state.input_size); + + if (u->prev_pass[i].texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); + glw->glUniform1i(u->prev_pass[i].texture, texture_unit); + texture_unit++; + } + if (u->prev_pass[i].texture_size >= 0) glw->glUniform2fv(u->prev_pass[i].texture_size, 1, passes[i].state.input_texture_size); + if (u->prev_pass[i].input_size >= 0) glw->glUniform2fv(u->prev_pass[i].input_size, 1, passes[i].state.input_size); + + } + } + + if (data->shader->has_prev) + { + /* loop through each previous frame */ + for (i = 0; i < MAX_PREV; ++i) + { + if (u->prev[i].texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->shader->prev[i].fbo.texture.id); + glw->glUniform1i(u->prev[i].texture, texture_unit); + texture_unit++; + } + if (u->prev[i].tex_coord >= 0) + { + glw->glBindBuffer(GL_ARRAY_BUFFER, data->shader->prev[i].vbo.tex_coord); + glw->glVertexAttribPointer(u->prev[i].tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + glw->glEnableVertexAttribArray(u->prev[i].tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + } + } + } + + for (i = 0; i < data->shader->num_lut_textures; ++i) + { + if (u->lut_textures[i] >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->shader->lut_textures[i].texture.id); + glw->glUniform1i(u->lut_textures[i], texture_unit); + texture_unit++; + } + + } + } + + glw->glEnableVertexAttribArray(u->vertex_coord); + glw->glEnableVertexAttribArray(u->tex_coord); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glw->glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.vertex_coord); + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.tex_coord); + if (data->shader_pass->uniforms.color >= 0) glw->glDisableVertexAttribArray(data->shader_pass->uniforms.color); + + if (data->shader && data->shader->has_prev) + { + for (i = 0; i < MAX_PREV; ++i) + { + if (u->prev[i].tex_coord >= 0) + glw->glDisableVertexAttribArray(u->prev[i].tex_coord); + + } + } + + glw->glBindVertexArray(0); + + + glw->glUseProgram(0); +} + +void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, BITMAP* screen) +{ + if (!context) + return; + + int s, i, j; + GLuint p; + + Uint32 ticks = SDL_GetTicks(); + + GLfloat orig_output_size[] = { + window_rect.w, window_rect.h + }; + + if (active_shader->srgb) glEnable(GL_FRAMEBUFFER_SRGB); + + struct render_data data; + + /* render scene to texture */ + { + struct shader_pass* pass = &active_shader->scene; + + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = video_rect.w*gl3_input_scale; + rect.h = video_rect.h*gl3_input_scale; + sdl_scale(gl3_input_stretch, rect, &rect, video_rect.w, video_rect.h); + + pass->state.input_size[0] = pass->state.output_size[0] = rect.w; + pass->state.input_size[1] = pass->state.output_size[1] = rect.h; + + pass->state.input_texture_size[0] = pass->state.output_texture_size[0] = next_pow2(pass->state.output_size[0]); + pass->state.input_texture_size[1] = pass->state.output_texture_size[1] = next_pow2(pass->state.output_size[1]); + + recreate_fbo(&active_shader->scene.fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, active_shader->scene.fbo.id); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + // create input tex coords + minx = video_rect.x/(float)screen->w; + miny = video_rect.y/(float)screen->h; + maxx = (video_rect.x+video_rect.w)/(float)screen->w; + maxy = (video_rect.y+video_rect.h)/(float)screen->h; + + GLfloat tex_coords[] = { + minx, miny, + minx, maxy, + maxx, miny, + maxx, maxy + }; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -1; + data.shader_pass = &active_shader->scene; + data.texture = scene_texture.id; + data.output_size = orig_output_size; + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + struct shader_pass* orig = &active_shader->scene; + struct shader_pass* input = &active_shader->scene; + + for (s = 0; s < active_shader->num_shaders; ++s) + { + struct glsl_shader* shader = &active_shader->shaders[s]; + int last_shader = s == active_shader->num_shaders-1; + +// float refresh_rate = shader->shader_refresh_rate; +// if (refresh_rate < 0) +// refresh_rate = gl3_shader_refresh_rate; + float refresh_rate = gl3_shader_refresh_rate; + if (refresh_rate == 0) + refresh_rate = video_refresh_rate; + int frame_count = ticks/(1000.0f/refresh_rate); + + /* loop through each pass */ + for (i = 0; i < shader->num_passes; ++i) + { + struct shader_pass* pass = &shader->passes[i]; + + memcpy(pass->state.input_size, input->state.output_size, 2*sizeof(GLfloat)); + memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2*sizeof(GLfloat)); + + for (j = 0; j < 2; ++j) + { + if (pass->scale.mode[j] == SCALE_VIEWPORT) + pass->state.output_size[j] = orig_output_size[j]*pass->scale.value[j]; + else if (pass->scale.mode[j] == SCALE_ABSOLUTE) + pass->state.output_size[j] = pass->scale.value[j]; + else + pass->state.output_size[j] = pass->state.input_size[j]*pass->scale.value[j]; + + pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); + } + + if (pass->fbo.id >= 0) + { + recreate_fbo(&pass->fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, pass->fbo.id); + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + } + else + glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), input->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.shader = shader; + data.pass = i; + data.shader_pass = pass; + data.texture = input->fbo.texture.id; + data.output_size = orig_output_size; + data.orig_pass = orig; + data.frame_count = frame_count; + + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + + if (pass->fbo.texture.mipmap) + { + glw->glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, pass->fbo.texture.id); + glw->glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + + + } + + input = pass; + } + + if (shader->has_prev && (ticks-shader->last_prev_update) >= (1000.f/refresh_rate)) + { + shader->last_prev_update = ticks; + + /* shift array */ + memmove(&shader->prev[1], &shader->prev[0], MAX_PREV*sizeof(struct shader_prev)); + memcpy(&shader->prev[0], &shader->prev[MAX_PREV], sizeof(struct shader_prev)); + + struct shader_pass* pass = orig; + struct shader_pass* prev_pass = &shader->prev_scene; + struct shader_prev* prev = &shader->prev[0]; + + memcpy(&prev_pass->state, &pass->state, sizeof(struct shader_state)); + + recreate_fbo(&prev->fbo, prev_pass->state.output_texture_size[0], prev_pass->state.output_texture_size[1]); + + memcpy(&prev_pass->fbo, &prev->fbo, sizeof(struct shader_fbo)); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, prev->fbo.id); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + + glw->glBindVertexArray(prev_pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, prev->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), pass->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), pass->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.shader = shader; + data.pass = -10; + data.shader_pass = prev_pass; + data.texture = pass->fbo.texture.id; + data.output_size = orig_output_size; + + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + orig = input; + } + + if (active_shader->final_pass.active) + { + struct shader_pass* pass = &active_shader->final_pass; + + memcpy(pass->state.input_size, input->state.output_size, 2*sizeof(GLfloat)); + memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2*sizeof(GLfloat)); + + for (j = 0; j < 2; ++j) + { + if (pass->scale.mode[j] == SCALE_VIEWPORT) + pass->state.output_size[j] = orig_output_size[j]*pass->scale.value[j]; + else if (pass->scale.mode[j] == SCALE_ABSOLUTE) + pass->state.output_size[j] = pass->scale.value[j]; + else + pass->state.output_size[j] = pass->state.input_size[j]*pass->scale.value[j]; + + pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); + } + + glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), input->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -2; + data.shader_pass = pass; + data.texture = input->fbo.texture.id; + data.output_size = orig_output_size; + data.orig_pass = orig; + + render_pass(&data); + } + + if (!take_screenshot) + { + if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) + { + struct shader_pass* pass = &active_shader->fs_color; + GLfloat r = 0; + GLfloat g = 0; + GLfloat b = 0; + GLfloat a = 0x80/(float)0xff; + + GLfloat colors[] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a + }; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16*sizeof(GLfloat), colors); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -3; + data.shader_pass = pass; + data.texture = 0; + data.output_size = orig_output_size; + data.orig_pass = orig; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + render_pass(&data); + glDisable(GL_BLEND); + } + if (flash.enabled) + { + struct shader_pass* pass = &active_shader->fs_color; + GLfloat r = (flash.color[0]&0xff)/(float)0xff; + GLfloat g = (flash.color[1]&0xff)/(float)0xff; + GLfloat b = (flash.color[2]&0xff)/(float)0xff; + GLfloat a = (flash.color[3]&0xff)/(float)0xff; + + GLfloat colors[] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a + }; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16*sizeof(GLfloat), colors); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -3; + data.shader_pass = pass; + data.texture = 0; + data.output_size = orig_output_size; + data.orig_pass = orig; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + render_pass(&data); + glDisable(GL_BLEND); + } + } + else + { + take_screenshot = 0; + + int width = window_rect.w; + int height = window_rect.h; + + SDL_GetWindowSize(window, &width, &height); + + unsigned char* rgba = (unsigned char*)malloc(width*height*4); + + glFinish(); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + + int x, y; + unsigned char* rgb = (unsigned char*)malloc(width*height*3); + + for (x = 0; x < width; ++x) + { + for (y = 0; y < height; ++y) + { + rgb[(y*width+x)*3+0] = rgba[((height-y-1)*width+x)*4+0]; + rgb[(y*width+x)*3+1] = rgba[((height-y-1)*width+x)*4+1]; + rgb[(y*width+x)*3+2] = rgba[((height-y-1)*width+x)*4+2]; + } + } + + screenshot_taken(rgb, width, height); + + free(rgb); + free(rgba); + } + + // DEBUG: render FBO +#ifdef SDL2_SHADER_DEBUG +// GLint texture = scene_texture.id; + GLint texture = active_shader->lut_textures[0].texture.id; +// GLint texture = active_shader->scene.fbo.texture; + + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, orig_output_size[0], orig_output_size[1]); + + struct shader_pass* pass = &active_shader->debug; + + render_pass(-999, pass, orig_output_size, texture); +#endif + + glDisable(GL_FRAMEBUFFER_SRGB); + + SDL_GL_SwapWindow(window); + +} + +sdl_renderer_t* gl3_renderer_create() +{ + sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t)); + renderer->init = gl3_init; + renderer->close = gl3_close; + renderer->update = gl3_update; + renderer->present = gl3_present; + renderer->always_update = 1; + return renderer; +} + +void gl3_renderer_close(sdl_renderer_t* renderer) +{ + free(renderer); +} + +static int available = -1; + +int gl3_renderer_available(struct sdl_render_driver* driver) +{ + if (available < 0) + { + available = 0; + SDL_Window* window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + if (window) + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); + + SDL_GLContext context = SDL_GL_CreateContext(window); + if (context) + { + int version = -1; + glGetIntegerv(GL_MAJOR_VERSION, &version); + + SDL_GL_DeleteContext(context); + + available = version >= 3; + } + SDL_DestroyWindow(window); + } + + } + return available; +} diff --git a/src/wx-sdl2-video-gl3.h b/src/wx-sdl2-video-gl3.h new file mode 100644 index 0000000..c4b1411 --- /dev/null +++ b/src/wx-sdl2-video-gl3.h @@ -0,0 +1,3 @@ +sdl_renderer_t* gl3_renderer_create(); +void gl3_renderer_close(sdl_renderer_t* renderer); +int gl3_renderer_available(struct sdl_render_driver* driver); diff --git a/src/wx-sdl2-video-renderer.c b/src/wx-sdl2-video-renderer.c new file mode 100644 index 0000000..81445ac --- /dev/null +++ b/src/wx-sdl2-video-renderer.c @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include "video.h" +#include "wx-utils.h" +#include "wx-sdl2-video.h" +#include "wx-sdl2-video-renderer.h" + +static SDL_Texture* texture = NULL; +static SDL_Renderer* renderer = NULL; + +extern int video_scale_mode; +extern int video_vsync; +extern int video_focus_dim; +extern int take_screenshot; +extern void screenshot_taken(unsigned char* rgb, int width, int height); + +int sdl_video_renderer_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITMAP* screen) +{ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); + const char* driver = requested_render_driver.sdl_id; + if (!driver) driver = "0"; + SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); + + int flags = SDL_RENDERER_ACCELERATED; + if (video_vsync) { + flags |= SDL_RENDERER_PRESENTVSYNC; + } + renderer = SDL_CreateRenderer(window, -1, flags); + + if (!renderer) + { + char message[200]; + sprintf(message, + "SDL window could not be created! Error: %s\n", + SDL_GetError()); + wx_messagebox(0, message, "SDL Error", WX_MB_OK); + return SDL_FALSE; + } + + SDL_RendererInfo rendererInfo; + SDL_GetRendererInfo(renderer, &rendererInfo); + sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); + if (!d) + strcpy(current_render_driver_name, "Unknown"); + else + strcpy(current_render_driver_name, d->name); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + screen->w, screen->h); + + return SDL_TRUE; + +} + +void sdl_video_renderer_close() +{ + if (texture) + { + SDL_DestroyTexture(texture); + texture = NULL; + } + if (renderer) + { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } +} + +void sdl_video_renderer_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen) +{ + SDL_UpdateTexture(texture, &updated_rect, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x], screen->w * 4); +} + +void sdl_video_renderer_present(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, BITMAP* screen) +{ + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); + int sshot = take_screenshot; + if (!sshot) + { + if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + if (flash.enabled) + { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, flash.color[0], flash.color[1], flash.color[2], flash.color[3]); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + } + SDL_RenderPresent(renderer); + + if (sshot) + { + take_screenshot = 0; + + int width = window_rect.w; + int height = window_rect.h; + + SDL_GetWindowSize(window, &width, &height); + + /* seems to work without rendering to texture first */ +// SDL_Texture* tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_TARGET, width, height); +// +// SDL_SetRenderTarget(renderer, tex); +// SDL_RenderClear(renderer); +// SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); +// SDL_RenderPresent(renderer); + + unsigned char* rgba = (unsigned char*)malloc(width*height*4); + int res = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width*4); + +// SDL_SetRenderTarget(renderer, NULL); +// SDL_DestroyTexture(tex); + + if (!res) + { + int x, y; + unsigned char* rgb = (unsigned char*)malloc(width*height*3); + + for (x = 0; x < width; ++x) + { + for (y = 0; y < height; ++y) + { + rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; + rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; + rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; + } + } + + screenshot_taken(rgb, width, height); + + free(rgb); + } + else + screenshot_taken(0, 0, 0); + + free(rgba); + } + +} + +sdl_renderer_t* sdl2_renderer_create() +{ + sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t)); + renderer->init = sdl_video_renderer_init; + renderer->close = sdl_video_renderer_close; + renderer->update = sdl_video_renderer_update; + renderer->present = sdl_video_renderer_present; + renderer->always_update = 0; + return renderer; +} + +void sdl2_renderer_close(sdl_renderer_t* renderer) +{ + free(renderer); +} + +int sdl2_renderer_available(struct sdl_render_driver* driver) +{ + int i; + SDL_RendererInfo renderInfo; + for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) + { + SDL_GetRenderDriverInfo(i, &renderInfo); + if (!strcmp(driver->sdl_id, renderInfo.name)) + return 1; + } + return 0; + +} diff --git a/src/wx-sdl2-video-renderer.h b/src/wx-sdl2-video-renderer.h new file mode 100644 index 0000000..08f7488 --- /dev/null +++ b/src/wx-sdl2-video-renderer.h @@ -0,0 +1,3 @@ +sdl_renderer_t* sdl2_renderer_create(); +void sdl2_renderer_close(sdl_renderer_t* renderer); +int sdl2_renderer_available(struct sdl_render_driver* driver); diff --git a/src/wx-sdl2-video.c b/src/wx-sdl2-video.c index ec5eefa..851bfb0 100644 --- a/src/wx-sdl2-video.c +++ b/src/wx-sdl2-video.c @@ -1,17 +1,19 @@ -#include "wx-sdl2-video.h" - +#include #include #include #include +#include #include "wx-sdl2.h" #include "video.h" +#include "wx-sdl2-video.h" + +#include "wx-sdl2-video-gl3.h" +#include "wx-sdl2-video-renderer.h" void video_blit_complete(); static BITMAP *buffer32_vscale; BITMAP *screen; -SDL_Texture* texture = NULL; -SDL_Renderer* renderer = NULL; SDL_Rect old_screen_rect; SDL_Rect screen_rect; SDL_Rect updated_rect; @@ -23,7 +25,6 @@ int updated = 0; SDL_mutex* blitMutex = NULL; static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void sdl_blit_memtoscreen_8(int x, int y, int w, int h); int video_scale_mode = 1; int video_vsync = 0; @@ -31,17 +32,19 @@ int video_focus_dim = 0; int video_fullscreen_mode = 0; static sdl_render_driver sdl_render_drivers[] = { - { RENDERER_AUTO, "auto", "Auto" }, - { RENDERER_DIRECT3D, "direct3d", "Direct3D" }, - { RENDERER_OPENGL, "opengl", "OpenGL" }, - { RENDERER_OPENGLES2, "opengles2", "OpenGL ES 2" }, - { RENDERER_OPENGLES, "opengles", "OpenGL ES" }, - { RENDERER_SOFTWARE, "software", "Software" } + { RENDERER_AUTO, "auto", "Auto", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, + { RENDERER_DIRECT3D, "direct3d", "Direct3D", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, + { RENDERER_OPENGL, "opengl", "OpenGL", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, + { RENDERER_OPENGLES2, "opengles2", "OpenGL ES 2", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, + { RENDERER_OPENGLES, "opengles", "OpenGL ES", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, + { RENDERER_SOFTWARE, "software", "Software", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, + { RENDERER_GL3, "gl3", "OpenGL 3.0", SDL_WINDOW_OPENGL, gl3_renderer_create, gl3_renderer_close, gl3_renderer_available } }; sdl_render_driver requested_render_driver; char current_render_driver_name[50]; +static sdl_renderer_t* renderer = NULL; void hline(BITMAP *b, int x1, int y, int x2, int col) { @@ -70,6 +73,7 @@ void set_palette(PALETTE p) void destroy_bitmap(BITMAP *b) { + free(b); } BITMAP *create_bitmap(int x, int y) @@ -221,8 +225,7 @@ static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) return; /*Nothing to do*/ } - int xx, yy; - SDL_Rect rect; + int yy; SDL_LockMutex(blitMutex); for (yy = y1; yy < y2; yy++) { @@ -259,6 +262,8 @@ int sdl_video_init() void sdl_video_close() { + requested_render_driver.renderer_close(renderer); + renderer = NULL; destroy_bitmap(buffer32_vscale); destroy_bitmap(screen); SDL_DestroyMutex(blitMutex); @@ -266,44 +271,15 @@ void sdl_video_close() int sdl_renderer_init(SDL_Window* window) { - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); - const char* driver = requested_render_driver.sdl_id; - if (!driver) driver = "0"; - SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); - - int flags = SDL_RENDERER_ACCELERATED; - if (video_vsync) { - flags |= SDL_RENDERER_PRESENTVSYNC; - } - renderer = SDL_CreateRenderer(window, -1, flags); - - SDL_RendererInfo rendererInfo; - SDL_GetRendererInfo(renderer, &rendererInfo); - sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); - if (!d) - strcpy(current_render_driver_name, "Unknown"); - else - strcpy(current_render_driver_name, d->name); - - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, - screen->w, screen->h); - - return SDL_TRUE; + renderer = requested_render_driver.renderer_create(); + return renderer->init(window, requested_render_driver, screen); } void sdl_renderer_close() { - if (texture) - { - SDL_DestroyTexture(texture); - texture = NULL; - } if (renderer) - { - SDL_DestroyRenderer(renderer); - renderer = NULL; - } + renderer->close(); + renderer = NULL; } int sdl_renderer_update(SDL_Window* window) @@ -313,32 +289,42 @@ int sdl_renderer_update(SDL_Window* window) if (updated) { updated = 0; - SDL_UpdateTexture(texture, &updated_rect, - &((uint32_t*) screen->dat)[updated_rect.y - * screen->w + updated_rect.x], - screen->w * 4); + renderer->update(window, updated_rect, screen); texture_rect.w = blit_rect.w; texture_rect.h = blit_rect.h; render = 1; } SDL_UnlockMutex(blitMutex); - return render; + return render || renderer->always_update; } void sdl_renderer_present(SDL_Window* window) { + if (flash.enabled) + { + int elapsed = SDL_GetTicks() - flash.start; + float a = flash.func(elapsed / (float)flash.time) * (flash.alpha&0xff); + flash.color[3] = (char)a; + if (elapsed >= flash.time) + flash.enabled = 0; + } + SDL_Rect wr; - int l, t, r, b; SDL_GetWindowSize(window, &wr.w, &wr.h); sdl_scale(video_fullscreen_scale, wr, &wr, texture_rect.w, texture_rect.h); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, &texture_rect, &wr); - if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); - SDL_RenderFillRect(renderer, NULL); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - } - SDL_RenderPresent(renderer); + renderer->present(window, texture_rect, wr, screen); + +} + +void color_flash(FLASH_FUNC func, int time_ms, char r, char g, char b, char a) +{ + flash.func = func; + flash.color[0] = r; + flash.color[1] = g; + flash.color[2] = b; + flash.color[3] = 0; + flash.alpha = a; + flash.start = SDL_GetTicks(); + flash.time = time_ms; + flash.enabled = 1; } diff --git a/src/wx-sdl2-video.h b/src/wx-sdl2-video.h index 635b0fc..18dfd13 100644 --- a/src/wx-sdl2-video.h +++ b/src/wx-sdl2-video.h @@ -1,18 +1,44 @@ -#include - #define RENDERER_AUTO 0 #define RENDERER_DIRECT3D 1 #define RENDERER_OPENGL 2 #define RENDERER_OPENGLES2 3 #define RENDERER_OPENGLES 4 #define RENDERER_SOFTWARE 5 +#define RENDERER_GL3 6 + +struct sdl_render_driver; + +typedef struct sdl_renderer_t { + int (*init)(SDL_Window* window, struct sdl_render_driver driver, BITMAP* screen); + void (*close)(); + void (*update)(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen); + void (*present)(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, BITMAP* screen); + int always_update; +} sdl_renderer_t; typedef struct sdl_render_driver { int id; const char* sdl_id; const char* name; + int sdl_window_params; + sdl_renderer_t* (*renderer_create)(); + void (*renderer_close)(sdl_renderer_t* renderer); + int (*renderer_available)(struct sdl_render_driver* driver); } sdl_render_driver; +typedef float (*FLASH_FUNC)(float v); + +typedef struct flash_t { + int enabled; + int time; + char color[4]; + int start; + char alpha; + FLASH_FUNC func; +} flash_t; + +flash_t flash; + #ifdef __cplusplus extern "C" { #endif @@ -30,6 +56,8 @@ sdl_render_driver sdl_get_render_driver_by_id(int id, int def); sdl_render_driver sdl_get_render_driver_by_name(const char* name, int def); sdl_render_driver* sdl_get_render_driver_by_name_ptr(const char* name); +void color_flash(FLASH_FUNC func, int time_ms, char r, char g, char b, char a); + #ifdef __cplusplus } #endif diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index ce343e8..1d9d419 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -5,6 +5,7 @@ #ifdef __WINDOWS__ #define BITMAP WINDOWS_BITMAP +#undef UNICODE #include #include #undef BITMAP @@ -75,6 +76,7 @@ emulation_state_t emulation_state = EMULATION_STOPPED; int pause = 0; int window_doreset = 0; +int window_dosetresize = 0; int renderer_doreset = 0; int window_dofullscreen = 0; int window_dowindowed = 0; @@ -91,9 +93,19 @@ int video_height = 480; char menuitem[60]; extern int config_selection_open(void* hwnd, int inited); +extern int shader_manager_open(void* hwnd); extern void sdl_set_window_title(const char* title); +extern float gl3_shader_refresh_rate; +extern float gl3_input_scale; +extern int gl3_input_stretch; +extern char gl3_shader_file[20][512]; + +char screenshot_format[10]; +int screenshot_flash = 1; +int take_screenshot = 0; + void warning(const char *format, ...) { char buf[1024]; @@ -114,6 +126,16 @@ void updatewindowsize(int x, int y) display_resize(x, y); } +unsigned int get_ticks() +{ + return SDL_GetTicks(); +} + +void delay_ms(unsigned int ms) +{ + SDL_Delay(ms); +} + void startblit() { SDL_LockMutex(ghMutex); @@ -143,11 +165,8 @@ uint64_t main_time; int mainthread(void* param) { - int i; - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); - int t = 0; int frames = 0; uint32_t old_time, new_time; @@ -210,6 +229,37 @@ void set_window_title(const char *s) sdl_set_window_title(s); } +float flash_func(float x) +{ + return 1 - pow(x, 4); +} + +float flash_failed_func(float x) +{ + return fabs(sin(x*3.1415926*2)); +} + +void screenshot_taken(unsigned char* rgb, int width, int height) +{ + char name[512]; + char date[128]; + strcpy(name, "Screenshot from "); + wx_date_format(date, "%Y-%m-%d %H-%M-%S"); + strcat(name, date); + if (wx_image_save(screenshots_path, name, screenshot_format, rgb, width, height, 0)) + { + pclog("Screenshot saved\n"); + if (screenshot_flash) + color_flash(flash_func, 500, 0xff, 0xff, 0xff, 0xff); + } + else + { + pclog("Screenshot was not saved\n"); + if (screenshot_flash) + color_flash(flash_failed_func, 500, 0xff, 0, 0, 0xff); + } +} + uint64_t timer_read() { return SDL_GetPerformanceCounter(); @@ -223,24 +273,69 @@ Uint32 timer_onesec(Uint32 interval, void* param) void sdl_loadconfig() { - video_fullscreen = config_get_int(CFG_GLOBAL, "SDL2", "fullscreen", video_fullscreen); - video_fullscreen_mode = config_get_int(CFG_GLOBAL, "SDL2", "fullscreen_mode", video_fullscreen_mode); - video_scale = config_get_int(CFG_GLOBAL, "SDL2", "scale", video_scale); - video_scale_mode = config_get_int(CFG_GLOBAL, "SDL2", "scale_mode", video_scale_mode); - video_vsync = config_get_int(CFG_GLOBAL, "SDL2", "vsync", video_vsync); - video_focus_dim = config_get_int(CFG_GLOBAL, "SDL2", "focus_dim", video_focus_dim); - requested_render_driver = sdl_get_render_driver_by_name(config_get_string(CFG_GLOBAL, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); + vid_resize = config_get_int(CFG_MACHINE, NULL, "vid_resize", 0); + video_fullscreen_scale = config_get_int(CFG_MACHINE, NULL, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(CFG_MACHINE, NULL, "video_fullscreen_first", 1); + + strcpy(screenshot_format, config_get_string(CFG_MACHINE, "SDL2", "screenshot_format", IMAGE_PNG)); + screenshot_flash = config_get_int(CFG_MACHINE, "SDL2", "screenshot_flash", 1); + + video_fullscreen = config_get_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); + video_fullscreen_mode = config_get_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); + video_scale = config_get_int(CFG_MACHINE, "SDL2", "scale", video_scale); + video_scale_mode = config_get_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); + video_vsync = config_get_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); + video_focus_dim = config_get_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); + requested_render_driver = sdl_get_render_driver_by_name(config_get_string(CFG_MACHINE, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); + + gl3_input_scale = config_get_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); + gl3_input_stretch = config_get_int(CFG_MACHINE, "GL3", "input_stretch", gl3_input_stretch); + gl3_shader_refresh_rate = config_get_float(CFG_MACHINE, "GL3", "shader_refresh_rate", gl3_shader_refresh_rate); + + memset(&gl3_shader_file, 0, sizeof(gl3_shader_file)); + int num_shaders = config_get_int(CFG_MACHINE, "GL3 Shaders", "shaders", 0); + char s[20]; + int i; + for (i = 0; i < num_shaders; ++i) + { + sprintf(s, "shader%d", i); + strncpy(gl3_shader_file[i], config_get_string(CFG_MACHINE, "GL3 Shaders", s, ""), 511); + gl3_shader_file[i][511] = 0; + } } void sdl_saveconfig() { - config_set_int(CFG_GLOBAL, "SDL2", "fullscreen", video_fullscreen); - config_set_int(CFG_GLOBAL, "SDL2", "fullscreen_mode", video_fullscreen_mode); - config_set_int(CFG_GLOBAL, "SDL2", "scale", video_scale); - config_set_int(CFG_GLOBAL, "SDL2", "scale_mode", video_scale_mode); - config_set_int(CFG_GLOBAL, "SDL2", "vsync", video_vsync); - config_set_int(CFG_GLOBAL, "SDL2", "focus_dim", video_focus_dim); - config_set_string(CFG_GLOBAL, "SDL2", "render_driver", (char*)requested_render_driver.sdl_id); + config_set_int(CFG_MACHINE, NULL, "vid_resize", vid_resize); + config_set_int(CFG_MACHINE, NULL, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(CFG_MACHINE, NULL, "video_fullscreen_first", video_fullscreen_first); + + config_set_string(CFG_MACHINE, "SDL2", "screenshot_format", screenshot_format); + config_set_int(CFG_MACHINE, "SDL2", "screenshot_flash", screenshot_flash); + + config_set_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); + config_set_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); + config_set_int(CFG_MACHINE, "SDL2", "scale", video_scale); + config_set_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); + config_set_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); + config_set_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); + config_set_string(CFG_MACHINE, "SDL2", "render_driver", (char*)requested_render_driver.sdl_id); + + config_set_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); + config_set_int(CFG_MACHINE, "GL3", "input_stretch", gl3_input_stretch); + config_set_float(CFG_MACHINE, "GL3", "shader_refresh_rate", gl3_shader_refresh_rate); + + char s[20]; + int i; + for (i = 0; i < 20; ++i) + { + sprintf(s, "shader%d", i); + if (strlen(gl3_shader_file[i])) + config_set_string(CFG_MACHINE, "GL3 Shaders", s, gl3_shader_file[i]); + else + break; + } + config_set_int(CFG_MACHINE, "GL3 Shaders", "shaders", i); } void update_cdrom_menu(void* hmenu) @@ -260,19 +355,19 @@ void update_cdrom_menu(void* hmenu) void wx_initmenu() { - char s[32]; menu = wx_getmenu(ghwnd); void* cdrom_submenu = wx_getsubmenu(menu, WX_ID("IDM_CDROM")); #ifdef __WINDOWS__ + char s[32]; int c; /* 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) + if (GetDriveTypeA(s)==DRIVE_CDROM) { sprintf(s, "Host CD/DVD Drive (%c:)", c); wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+(c-'A'), s, wxITEM_RADIO); @@ -284,7 +379,7 @@ void wx_initmenu() } -void wx_setupmenu() +int wx_setupmenu(void* data) { int c; update_cdrom_menu(menu); @@ -300,6 +395,9 @@ void wx_setupmenu() sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len/MIN_SND_BUF)/log(2))); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len/MIN_SND_BUF)/log(2))); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); sprintf(menuitem, "IDM_VID_SCALE[%d]", video_scale); @@ -309,34 +407,54 @@ void wx_setupmenu() wx_checkmenuitem(menu, WX_ID("IDM_VID_VSYNC"), video_vsync); wx_checkmenuitem(menu, WX_ID("IDM_VID_LOST_FOCUS_DIM"), video_focus_dim); + int format = 0; + if (!strcmp(screenshot_format, IMAGE_TIFF)) + format = 1; + else if (!strcmp(screenshot_format, IMAGE_BMP)) + format = 2; + else if (!strcmp(screenshot_format, IMAGE_JPG)) + format = 3; + sprintf(menuitem, "IDM_SCREENSHOT_FORMAT[%d]", format); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_SCREENSHOT_FLASH"), screenshot_flash); + int num_renderers; sdl_render_driver* drivers = sdl_get_render_drivers(&num_renderers); for (c = 1; c < num_renderers; ++c) { sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", drivers[c].id); - wx_enablemenuitem(menu, WX_ID(menuitem), 0); - } - SDL_RendererInfo renderInfo; - for (c = 0; c < SDL_GetNumRenderDrivers(); ++c) - { - SDL_GetRenderDriverInfo(c, &renderInfo); - sdl_render_driver* driver = sdl_get_render_driver_by_name_ptr(renderInfo.name); - - if (driver) - { - pclog("Renderer: %s (%d)\n", renderInfo.name, driver->id); - sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", driver->id); - wx_enablemenuitem(menu, WX_ID(menuitem), 1); - } + wx_enablemenuitem(menu, WX_ID(menuitem), drivers[c].renderer_available(&drivers[c])); } sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", requested_render_driver.id); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + +// wx_enablemenuitem(menu, WX_ID("IDM_VID_SDL2"), requested_render_driver.id != RENDERER_GL3); + wx_enablemenuitem(menu, WX_ID("IDM_VID_GL3"), requested_render_driver.id == RENDERER_GL3); + + sprintf(menuitem, "IDM_VID_GL3_INPUT_STRETCH[%d]", gl3_input_stretch); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_GL3_INPUT_SCALE[%d]", (int)((gl3_input_scale-0.5)*2)); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_GL3_SHADER_REFRESH_RATE[%g]", gl3_shader_refresh_rate); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + + return 1; } void sdl_onconfigloaded() { if (ghwnd) - wx_callback(ghwnd, wx_setupmenu); + wx_callback(ghwnd, wx_setupmenu, 0); + + /* create directories */ + if (!wx_dir_exists(configs_path)) + wx_create_directory(configs_path); + if (!wx_dir_exists(nvr_path)) + wx_create_directory(nvr_path); + if (!wx_dir_exists(logs_path)) + wx_create_directory(logs_path); + if (!wx_dir_exists(screenshots_path)) + wx_create_directory(screenshots_path); } extern void wx_loadconfig(); @@ -344,10 +462,10 @@ extern void wx_saveconfig(); int pc_main(int argc, char** argv) { - char s[512]; paths_init(); #ifdef __linux__ + char s[512]; /* create directories if they don't exist */ if (!wx_setup(pcem_path)) return FALSE; @@ -359,6 +477,8 @@ int pc_main(int argc, char** argv) set_default_nvr_path(s); append_filename(s, pcem_path, "configs/", 511); set_default_configs_path(s); + append_filename(s, pcem_path, "screenshots/", 511); + set_default_screenshots_path(s); append_filename(s, pcem_path, "logs/", 511); set_default_logs_path(s); #endif @@ -410,7 +530,7 @@ int wx_start(void* hwnd) readflash = 0; wx_initmenu(); - wx_setupmenu(); + wx_setupmenu(0); d = romset; for (c = 0; c < ROM_MAX; c++) @@ -434,48 +554,9 @@ int wx_start(void* hwnd) } romset = d; - c = loadbios(); - - if (!c) - { - if (romset != -1) - wx_messagebox(hwnd, - "Configured romset not available.\nDefaulting to available romset.", - "PCem error", WX_MB_OK); - for (c = 0; c < ROM_MAX; c++) - { - if (romspresent[c]) - { - romset = c; - model = model_getmodel(romset); - saveconfig(NULL); - 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 (romset != -1) - wx_messagebox(hwnd, - "Configured video BIOS not available.\nDefaulting to available romset.", - "PCem error", WX_MB_OK); - for (c = GFX_MAX - 1; c >= 0; c--) - { - if (gfx_present[c]) - { - gfxcard = c; - saveconfig(NULL); - resetpchard(); - break; - } - } - } - return TRUE; } @@ -494,6 +575,7 @@ int start_emulation(void* params) { if (resume_emulation()) return TRUE; + int c; pclog("Starting emulation...\n"); loadconfig(NULL); @@ -504,6 +586,40 @@ int start_emulation(void* params) mainMutex = SDL_CreateMutex(); mainCond = SDL_CreateCond(); + if (!loadbios()) + { + if (romset != -1) + wx_messagebox(ghwnd, + "Configured romset not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = 0; c < ROM_MAX; c++) + { + if (romspresent[c]) + { + romset = c; + model = model_getmodel(romset); + break; + } + } + } + + if (!video_card_available(video_old_to_new(gfxcard))) + { + if (romset != -1) + wx_messagebox(ghwnd, + "Configured video BIOS not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = GFX_MAX - 1; c >= 0; c--) + { + if (gfx_present[c]) + { + gfxcard = c; + break; + } + } + } + + loadbios(); resetpchard(); @@ -617,7 +733,6 @@ void atapi_close(void) int wx_handle_command(void* hwnd, int wParam, int checked) { - SDL_Rect rect; void* hmenu; char temp_image_path[1024]; int new_cdrom_drive; @@ -690,8 +805,8 @@ int wx_handle_command(void* hwnd, int wParam, int checked) } else if (ID_IS("IDM_BPB_DISABLE")) { - bpb_disable = checked; - wx_checkmenuitem(hmenu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + bpb_disable = !bpb_disable; + wx_checkmenuitem(hmenu, wParam, bpb_disable); saveconfig(NULL); } else if (ID_IS("IDM_MACHINE_TOGGLE")) @@ -701,13 +816,38 @@ int wx_handle_command(void* hwnd, int wParam, int checked) } else if (ID_IS("IDM_VID_RESIZE")) { - vid_resize = checked; - window_doreset = 1; + vid_resize = !vid_resize; + wx_checkmenuitem(hmenu, wParam, vid_resize); + window_dosetresize = 1; + saveconfig(NULL); + } + else if (ID_IS("IDM_SCREENSHOT")) + { + take_screenshot = 1; + } + else if (ID_RANGE("IDM_SCREENSHOT_FORMAT[start]", "IDM_SCREENSHOT_FORMAT[end]")) + { + int format = wParam - wx_xrcid("IDM_SCREENSHOT_FORMAT[start]"); + if (format == 0) + strcpy(screenshot_format, IMAGE_PNG); + else if (format == 1) + strcpy(screenshot_format, IMAGE_TIFF); + else if (format == 2) + strcpy(screenshot_format, IMAGE_BMP); + else if (format == 3) + strcpy(screenshot_format, IMAGE_JPG); + saveconfig(NULL); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + } + else if (ID_IS("IDM_SCREENSHOT_FLASH")) + { + screenshot_flash = !screenshot_flash; + wx_checkmenuitem(hmenu, wParam, screenshot_flash); saveconfig(NULL); } else if (ID_IS("IDM_VID_REMEMBER")) { - window_remember = checked; + window_remember = !window_remember; wx_checkmenuitem(hmenu, WX_ID("IDM_VID_REMEMBER"), window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); window_doremember = 1; @@ -722,7 +862,8 @@ int wx_handle_command(void* hwnd, int wParam, int checked) "Use CTRL + ALT + PAGE DOWN to return to windowed mode", "PCem", WX_MB_OK); } - video_fullscreen = checked; + video_fullscreen = !video_fullscreen; + wx_checkmenuitem(hmenu, wParam, video_fullscreen); saveconfig(NULL); } else if (ID_IS("IDM_VID_FULLSCREEN_TOGGLE")) @@ -732,45 +873,94 @@ int wx_handle_command(void* hwnd, int wParam, int checked) else if (ID_RANGE("IDM_VID_FS[start]", "IDM_VID_FS[end]")) { video_fullscreen_scale = wParam - wx_xrcid("IDM_VID_FS[start]"); + display_resize(video_width, video_height); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); saveconfig(NULL); } else if (ID_RANGE("IDM_VID_SCALE_MODE[start]", "IDM_VID_SCALE_MODE[end]")) { video_scale_mode = wParam - wx_xrcid("IDM_VID_SCALE_MODE[start]"); renderer_doreset = 1; + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); saveconfig(NULL); } else if (ID_RANGE("IDM_VID_SCALE[start]", "IDM_VID_SCALE[end]")) { video_scale = wParam - wx_xrcid("IDM_VID_SCALE[start]"); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); display_resize(video_width, video_height); saveconfig(NULL); } else if (ID_RANGE("IDM_VID_FS_MODE[start]", "IDM_VID_FS_MODE[end]")) { video_fullscreen_mode = wParam - wx_xrcid("IDM_VID_FS_MODE[start]"); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); saveconfig(NULL); } else if (ID_RANGE("IDM_VID_RENDER_DRIVER[start]", "IDM_VID_RENDER_DRIVER[end]")) { requested_render_driver = sdl_get_render_driver_by_id(wParam - wx_xrcid("IDM_VID_RENDER_DRIVER[start]"), RENDERER_AUTO); window_doreset = 1; + + /* update enabled menu-items */ +// wx_enablemenuitem(menu, WX_ID("IDM_VID_SDL2"), requested_render_driver.id != RENDERER_GL3); + wx_enablemenuitem(menu, WX_ID("IDM_VID_GL3"), requested_render_driver.id == RENDERER_GL3); + + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); saveconfig(NULL); } else if (ID_IS("IDM_VID_VSYNC")) { - video_vsync = checked; + video_vsync = !video_vsync; + wx_checkmenuitem(menu, wParam, video_vsync); renderer_doreset = 1; saveconfig(NULL); } else if (ID_IS("IDM_VID_LOST_FOCUS_DIM")) { - video_focus_dim = checked; + video_focus_dim = !video_focus_dim; + wx_checkmenuitem(menu, wParam, video_focus_dim); saveconfig(NULL); } + else if (ID_RANGE("IDM_VID_GL3_INPUT_STRETCH[start]", "IDM_VID_GL3_INPUT_STRETCH[end]")) + { + gl3_input_stretch = wParam - wx_xrcid("IDM_VID_GL3_INPUT_STRETCH[start]"); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_GL3_INPUT_SCALE[start]", "IDM_VID_GL3_INPUT_SCALE[end]")) + { + int input_scale = wParam - wx_xrcid("IDM_VID_GL3_INPUT_SCALE[start]"); + gl3_input_scale = input_scale/2.0f+0.5f; + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } + else if (ID_RANGE("IDM_VID_GL3_SHADER_REFRESH_RATE[start]", "IDM_VID_GL3_SHADER_REFRESH_RATE[end]")) + { + gl3_shader_refresh_rate = wParam - wx_xrcid("IDM_VID_GL3_SHADER_REFRESH_RATE[start]"); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } + else if (ID_IS("IDM_VID_GL3_SHADER_MANAGER")) + { + if (shader_manager_open(hwnd)) + { + renderer_doreset = 1; + saveconfig(NULL); + } +// if (!getfile(hwnd, "GLSL Shaders (*.glslp;*.glsl)|*.glslp;*.glsl|All files (*.*)|*.*", gl3_shader_file)) +// { +// strncpy(gl3_shader_file, openfilestring, 511); +// gl3_shader_file[511] = 0; +// renderer_doreset = 1; +// saveconfig(NULL); +// } + + } else if (ID_RANGE("IDM_SND_BUF[start]", "IDM_SND_BUF[end]")) { sound_buf_len = MIN_SND_BUF*1<<(wParam - wx_xrcid("IDM_SND_BUF[start]")); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); saveconfig(NULL); } else if (ID_IS("IDM_CDROM_DISABLED")) diff --git a/src/wx-sdl2.h b/src/wx-sdl2.h index 6857f5f..fdc45ef 100644 --- a/src/wx-sdl2.h +++ b/src/wx-sdl2.h @@ -5,6 +5,7 @@ extern "C" { void leave_fullscreen(); int getfile(void* hwnd, char *f, char *fn); int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext); +void screenshot_taken(unsigned char* rgb, int width, int height); #ifdef __cplusplus } @@ -14,3 +15,4 @@ extern char openfilestring[260]; extern int pause; +extern int take_screenshot; diff --git a/src/wx-shader_man.c b/src/wx-shader_man.c new file mode 100644 index 0000000..869a3aa --- /dev/null +++ b/src/wx-shader_man.c @@ -0,0 +1,230 @@ +#include +#include +#include "wx-utils.h" +#include "wx-display.h" +#include "wx-glslp-parser.h" +#include "wx-shaderconfig.h" +#include "config.h" + +#define MAX_USER_SHADERS 20 + +extern char *get_filename(char *s); + +extern char gl3_shader_file[MAX_USER_SHADERS][512]; +static char shaders[MAX_USER_SHADERS][512]; + +void read_shader_config(glslp_t* shader) +{ + char s[512]; + int i; + char* name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); + for (i = 0; i < shader->num_parameters; ++i) + { + struct parameter* param = &shader->parameters[i]; + param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); + } +} + +void write_shader_config(glslp_t* shader) +{ + char s[512]; + int i; + char* name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); + for (i = 0; i < shader->num_parameters; ++i) + { + struct parameter* param = &shader->parameters[i]; + config_set_float(CFG_MACHINE, s, param->id, param->value); + } +} + +static void add_shader(int p, const char* s) +{ + memmove(&shaders[p+1], &shaders[p], (MAX_USER_SHADERS-p-2)*512); + strcpy(shaders[p], s); +} + +static int shader_list_update(void* hdlg) +{ + char s[512]; + int c; + void* h; + int num = 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + wx_sendmessage(h, WX_LB_RESETCONTENT, 0, 0); + + for (c = 0; c < MAX_USER_SHADERS; c++) + { + if (strlen(shaders[c])) + { + char* p = get_filename(shaders[c]); + wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)p); + ++num; + } + } + return num; +} + +static void set_shaders() +{ + int i, j, available; + char s[128]; + char name[64]; + for (i = 0; i < MAX_USER_SHADERS; ++i) + { + if (strlen(gl3_shader_file[i])) + { + available = 0; + for (j = 0; j < MAX_USER_SHADERS; ++j) + { + if (!strcmp(gl3_shader_file[i], shaders[j])) + { + available = 1; + continue; + } + } + if (!available) + { + get_glslp_name(gl3_shader_file[i], name, sizeof(name)); + sprintf(s, "GL3 Shaders - %s", name); + config_free_section(CFG_MACHINE, s); + } + } + } + memcpy(&gl3_shader_file, &shaders, sizeof(gl3_shader_file)); + +} + +static int shader_manager_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + char s[512]; + switch (message) + { + case WX_INITDIALOG: + { + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + memcpy(&shaders, &gl3_shader_file, sizeof(gl3_shader_file)); + int len = shader_list_update(hdlg); + if (len) + wx_sendmessage(h, WX_LB_SETCURSEL, len-1, 0); + return TRUE; + } + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + set_shaders(); + wx_enddialog(hdlg, 1); + return TRUE; + } + else if (wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + return TRUE; + } + else if (wParam == WX_ID("IDC_APPLY")) + { + set_shaders(); + renderer_doreset = 1; + return TRUE; + } + else if (wParam == WX_ID("IDC_ADD")) + { + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + int count = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + if (count >= MAX_USER_SHADERS) + { + wx_simple_messagebox("Error", "Can't add more shaders."); + return FALSE; + } + + int ret = !wx_filedialog(hdlg, "Open", shaders[c], "GLSL Shaders (*.glslp;*.glsl)|*.glslp;*.glsl|All files (*.*)|*.*", 0, 1, s); + + if (ret) + { + add_shader(c+1, s); + shader_list_update(hdlg); + wx_sendmessage(h, WX_LB_SETCURSEL, c+1, 0); + } + + return TRUE; + } + else if (wParam == WX_ID("IDC_CONFIG")) + { + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + glslp_t* glsl = glslp_parse(shaders[c]); + if (glsl) + { + read_shader_config(glsl); + shaderconfig_open(hdlg, glsl); + write_shader_config(glsl); + glslp_free(glsl); + return TRUE; + } + } + return FALSE; + } + else if (wParam == WX_ID("IDC_REMOVE")) + { + char name[64]; + void* h; + int c; + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + memmove(&shaders[c], &shaders[c+1], (MAX_USER_SHADERS-c-1)*512); + int len = shader_list_update(hdlg); + if (len > 0) + { + if (c > 0) + c--; + wx_sendmessage(h, WX_LB_SETCURSEL, c, 0); + } + } + } + else if (wParam == WX_ID("IDC_MOVE_UP")) + { + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c > 0) + { + strcpy(s, shaders[c-1]); + strcpy(shaders[c-1], shaders[c]); + strcpy(shaders[c], s); + shader_list_update(hdlg); + wx_sendmessage(h, WX_LB_SETCURSEL, c-1, 0); + } + } + else if (wParam == WX_ID("IDC_MOVE_DOWN")) + { + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c < MAX_USER_SHADERS-1) + { + if (strlen(shaders[c+1])) + { + strcpy(s, shaders[c+1]); + strcpy(shaders[c+1], shaders[c]); + strcpy(shaders[c], s); + shader_list_update(hdlg); + wx_sendmessage(h, WX_LB_SETCURSEL, c+1, 0); + } + } + } + } + break; + } + return FALSE; +} + +int shader_manager_open(void* hwnd) +{ + return wx_dialogbox(hwnd, "ShaderManagerDlg", shader_manager_dlgproc); +} diff --git a/src/wx-shaderconfig.cc b/src/wx-shaderconfig.cc new file mode 100644 index 0000000..d56096d --- /dev/null +++ b/src/wx-shaderconfig.cc @@ -0,0 +1,146 @@ +#include "wx-utils.h" +#include + +#include "wx-dialogbox.h" + +#ifndef WX_PRECOMP +#include +#endif + +#include +#include + +#include "wx-glslp-parser.h" +#include "wx-shaderconfig.h" + +extern "C" +{ + #include "config.h" + void saveconfig(char*); + void resetpchard(); + int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam); + void write_shader_config(glslp_t* shader); + struct glslp_t* current_glsl; + int confirm(); +} +#define IDC_CONFIG_BASE 1000 +#define ID_APPLY 500 +#define ID_RESET 501 +extern int renderer_doreset; + +static int shaderconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { + int i; + switch (message) { + case WX_INITDIALOG: { + return TRUE; + } + case WX_COMMAND: + switch (wParam) { + case ID_APPLY: { + for (i = 0; i < current_glsl->num_parameters; ++i) + { + struct parameter* p = ¤t_glsl->parameters[i]; + wxSpinCtrlDouble* h = (wxSpinCtrlDouble*)wx_getdlgitem(hdlg, IDC_CONFIG_BASE+i); + p->value = (float)h->GetValue(); + } + write_shader_config(current_glsl); + renderer_doreset = 1; + return TRUE; + } + case wxID_OK: { + for (i = 0; i < current_glsl->num_parameters; ++i) + { + struct parameter* p = ¤t_glsl->parameters[i]; + wxSpinCtrlDouble* h = (wxSpinCtrlDouble*)wx_getdlgitem(hdlg, IDC_CONFIG_BASE+i); + p->value = (float)h->GetValue(); + } + write_shader_config(current_glsl); + renderer_doreset = 1; + wx_enddialog(hdlg, 0); + return TRUE; + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + case ID_RESET: { + for (i = 0; i < current_glsl->num_parameters; ++i) + { + struct parameter* p = ¤t_glsl->parameters[i]; + wxSpinCtrlDouble* h = (wxSpinCtrlDouble*)wx_getdlgitem(hdlg, IDC_CONFIG_BASE+i); + h->SetValue(p->default_value); + } + return TRUE; + } + } + } + return TRUE; +} + + + +void shaderconfig_open(void* hwnd, struct glslp_t* glsl) { + int i; + current_glsl = glsl; + + PCemDialogBox dialog((wxWindow*) hwnd, shaderconfig_dlgproc); +// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + dialog.SetTitle("Shader Configuration"); + + wxBoxSizer* root = new wxBoxSizer(wxVERTICAL); + dialog.SetSizer(root); + + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + root->Add(sizer, 0, wxALL, 5); + + wxPanel* panel = new wxPanel(&dialog, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_SUNKEN); + sizer->Add(panel); + + wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL); + panel->SetSizer(panelSizer); + + wxScrolledWindow* win = new wxScrolledWindow(panel, wxID_ANY, wxDefaultPosition, wxSize(300, 350), wxHSCROLL|wxVSCROLL); + win->SetScrollRate( 5, 5 ); + panelSizer->Add(win, 1, wxEXPAND | wxALL, 5); + + wxBoxSizer* winSizer = new wxBoxSizer(wxVERTICAL); + win->SetSizer(winSizer); + + if (glsl->num_parameters > 0) + { + wxPanel* scrollPanel = new wxPanel(win); + winSizer->Add(scrollPanel); + + wxBoxSizer* scollPanelSizer = new wxBoxSizer(wxVERTICAL); + scrollPanel->SetSizer(scollPanelSizer); + + for (i = 0; i < glsl->num_parameters; ++i) + { + struct parameter* p = &glsl->parameters[i]; + scollPanelSizer->Add(new wxStaticText(scrollPanel, wxID_ANY, p->description), 0, wxALL); + wxSpinCtrlDouble* spin = new wxSpinCtrlDouble(scrollPanel, IDC_CONFIG_BASE+i); + spin->SetRange(p->min, p->max); + spin->SetIncrement(p->step); + spin->SetValue(p->value); + spin->SetDigits(2); + + scollPanelSizer->Add(spin, 0, wxALL); + } + } + else + winSizer->Add(new wxStaticText(win, wxID_ANY, "No configuration available."), 0, wxALL); + + wxBoxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL); + + buttonSizer->Add(new wxButton(&dialog, ID_APPLY, "Apply")); + buttonSizer->Add(new wxButton(&dialog, wxID_OK)); + buttonSizer->Add(new wxButton(&dialog, wxID_CANCEL)); + buttonSizer->Add(new wxButton(&dialog, ID_RESET, "Reset")); + + sizer->Add(buttonSizer); + + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); +} diff --git a/src/wx-shaderconfig.h b/src/wx-shaderconfig.h new file mode 100644 index 0000000..279409c --- /dev/null +++ b/src/wx-shaderconfig.h @@ -0,0 +1,13 @@ +#ifndef SRC_WX_SHADERCONFIG_H_ +#define SRC_WX_SHADERCONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif +void shaderconfig_open(void* hwnd, struct glslp_t* glsl); +#ifdef __cplusplus +} +#endif + + +#endif /* SRC_WX_SHADERCONFIG_H_ */ diff --git a/src/wx-status.cc b/src/wx-status.cc index 16b9968..b257d5f 100644 --- a/src/wx-status.cc +++ b/src/wx-status.cc @@ -322,8 +322,8 @@ void StatusFrame::OnCommand(wxCommandEvent& event) show_mount_paths = event.IsChecked(); else if (event.GetId() == XRCID("IDM_SHOW_MACHINE_ON_START")) show_machine_on_start = event.IsChecked(); - else if (event.GetId() == XRCID("IDM_HDCONF")) - hdconf_open(this); +// else if (event.GetId() == XRCID("IDM_HDCONF")) +// hdconf_open(this); else if (event.GetId() == XRCID("IDM_CONFIG")) config_open(this); else if (event.GetId() == XRCID("IDM_RESET_CONFIRMATION_DIALOGS")) @@ -345,7 +345,7 @@ void StatusFrame::OnCommand(wxCommandEvent& event) void StatusFrame::OnMoveWindow(wxMoveEvent& event) { if (window_remember) { - wx_window_x = event.GetPosition().x; - wx_window_y = event.GetPosition().y; + wx_window_x = GetScreenPosition().x; + wx_window_y = GetScreenPosition().y; } } diff --git a/src/wx-utils.cc b/src/wx-utils.cc index 598efc8..a88919c 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -8,12 +8,20 @@ #include #include #include +#include +#include +#include #include "wx-dialogbox.h" #include "wx-app.h" #include "wx-common.h" #include "wx-status.h" +extern "C" +{ +#include "thread.h" +} + int confirm() { if (emulation_state != EMULATION_STOPPED) { @@ -24,10 +32,22 @@ int confirm() int wx_messagebox(void* window, const char* message, const char* title = NULL, int style = 5) { - return wxMessageBox(message, title, style | wxCENTRE, (wxWindow*) window); + return wxMessageBox(message, title, style | wxCENTRE | wxSTAY_ON_TOP, (wxWindow*) window); } -int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, int min_length, int max_length, LONG_PARAM result) +void wx_simple_messagebox(const char* title, const char *format, ...) +{ + char message[2048]; + va_list ap; + va_start(ap, format); + vsnprintf(message, 2047, format, ap); + message[2047] = 0; + va_end(ap); + wx_messagebox(0, message, title, WX_MB_OK); +} + + +int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, unsigned int min_length, unsigned int max_length, LONG_PARAM result) { while (1) { @@ -39,7 +59,7 @@ int wx_textentrydialog(void* window, const char* message, const char* title, con wxString value = dlg.GetValue(); if (value.Length() >= min_length) { - strcpy((char*)result, value); + strcpy((char*)result, value.mb_str()); return TRUE; } } @@ -63,7 +83,7 @@ int wx_filedialog(void* window, const char* title, const char* path, const char* extensions, const char* extension, int open, char* file) { wxFileDialog dlg((wxWindow*) window, title, "", path, extensions, - open ? wxFD_OPEN : wxFD_SAVE); + open ? (wxFD_OPEN | wxFD_FILE_MUST_EXIST) : (wxFD_SAVE | wxFD_OVERWRITE_PROMPT)); if (dlg.ShowModal() == wxID_OK) { wxString p = dlg.GetPath(); @@ -74,10 +94,10 @@ int wx_filedialog(void* window, const char* title, const char* path, if (!p.EndsWith(".")) p += "."; p += extension; - strcpy(file, p); + strcpy(file, p.mb_str()); } else - strcpy(file, p); + strcpy(file, p.mb_str()); return 0; } return 1; @@ -120,6 +140,30 @@ void* wx_getsubmenu(void* menu, int id) return 0; } +void* wx_getnativemenu(void* menu) +{ +#ifdef _WIN32 + return ((wxMenu*)menu)->GetHMenu(); +#endif + return 0; +} + +void* wx_getnativewindow(void* window) +{ +#ifdef _WIN32 + return ((wxWindow*)window)->GetHWND(); +#endif + return 0; +} + +#ifdef _WIN32 +void wx_winsendmessage(void* window, int msg, INT_PARAM wParam, LONG_PARAM lParam) +{ + WinSendMessageEvent* event = new WinSendMessageEvent(wx_getnativewindow(window), msg, wParam, lParam); + wxQueueEvent((wxWindow*)window, event); +} +#endif + void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type) { ((wxMenu*) sub_menu)->Append(id, title, wxEmptyString, type); @@ -173,14 +217,19 @@ void wx_showwindow(void* window, int show) wxQueueEvent((wxWindow*)window, event); } +int wx_iswindowvisible(void* window) +{ + return ((wxWindow*) window)->IsShown(); +} + void wx_togglewindow(void* window) { wx_showwindow(window, -1); } -void wx_callback(void* window, WX_CALLBACK callback) +void wx_callback(void* window, WX_CALLBACK callback, void* data) { - CallbackEvent* event = new CallbackEvent(callback); + CallbackEvent* event = new CallbackEvent(callback, data); wxQueueEvent((wxWindow*)window, event); } @@ -231,17 +280,19 @@ int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) ((wxComboBox*) window)->Append((char*) param2); break; case WX_CB_SETCURSEL: - ((wxComboBox*) window)->Select(param1); + if (param1 >= 0 && param1 < ((wxComboBox*) window)->GetCount()) + ((wxComboBox*) window)->Select(param1); break; case WX_CB_GETCURSEL: return ((wxComboBox*) window)->GetCurrentSelection(); break; case WX_CB_GETLBTEXT: - strcpy((char*) param2, ((wxComboBox*) window)->GetString(param1)); + strcpy((char*) param2, ((wxComboBox*) window)->GetString(param1).mb_str()); break; case WX_CB_RESETCONTENT: { #ifndef __WXOSX_MAC__ + ((wxComboBox*) window)->SetValue(""); ((wxComboBox*) window)->Clear(); #else /* Clear() does not work on OSX */ @@ -268,9 +319,9 @@ int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) break; case WX_WM_GETTEXT: if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - strcpy((char*) param2, ((wxTextCtrl*) window)->GetValue()); + strcpy((char*) param2, ((wxTextCtrl*) window)->GetValue().mb_str()); else - strcpy((char*) param2, ((wxStaticText*) window)->GetLabel()); + strcpy((char*) param2, ((wxStaticText*) window)->GetLabel().mb_str()); break; case WX_UDM_SETPOS: ((wxSpinCtrl*) window)->SetValue(param2); @@ -300,9 +351,14 @@ int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) { return ((wxListBox*) window)->GetSelection(); } + case WX_LB_SETCURSEL: + { + ((wxListBox*) window)->SetSelection(param1); + break; + } case WX_LB_GETTEXT: { - strcpy((char*) param2, ((wxListBox*) window)->GetString(param1)); + strcpy((char*) param2, ((wxListBox*) window)->GetString(param1).mb_str()); break; } case WX_LB_INSERTSTRING: @@ -315,6 +371,11 @@ int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) ((wxListBox*) window)->Delete(param1); break; } + case WX_LB_RESETCONTENT: + { + ((wxListBox*) window)->Clear(); + break; + } } ((wxWindow*)window)->Fit(); @@ -447,7 +508,7 @@ void wx_get_home_directory(char* path) if (!home.EndsWith(wxFileName::GetPathSeparator())) { home.Append(wxFileName::GetPathSeparator()); } - strcpy(path, home); + strcpy(path, home.mb_str()); } int wx_create_directory(char* path) @@ -477,6 +538,11 @@ int wx_setup(char* path) if (!nvr.DirExists() && !nvr.Mkdir()) return FALSE; + wxFileName screenshots(p); + screenshots.AppendDir("screenshots"); + if (!screenshots.DirExists() && !screenshots.Mkdir()) + return FALSE; + wxFileName logs(p); logs.AppendDir("logs"); if (!logs.DirExists() && !logs.Mkdir()) @@ -497,3 +563,210 @@ int wx_dir_exists(char* path) wxFileName p(path); return p.DirExists(); } + +int wx_image_save(const char* path, const char* name, const char* format, unsigned char* rgba, int width, int height, int alpha) +{ + int x, y; + wxLogNull logNull; + wxImage image(width, height); + if (alpha) + { + unsigned char* rgb = (unsigned char*)malloc(width*height*3); + unsigned char* a = (unsigned char*)malloc(width*height); + for (x = 0; x < width; ++x) + { + for (y = 0; y < height; ++y) + { + rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; + rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; + rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; + a[y*width+x] = rgba[(y*width+x)*4+3]; + } + } + image.SetData(rgb); + image.SetAlpha(a); + } + else + image.SetData(rgba, true); + + wxImageHandler* h; + wxString ext; + + if (!strcmp(format, IMAGE_TIFF)) + { + h = new wxTIFFHandler(); + ext = "tif"; + } + else if (!strcmp(format, IMAGE_BMP)) + { + h = new wxBMPHandler(); + ext = "bmp"; + } + else if (!strcmp(format, IMAGE_JPG)) + { + h = new wxJPEGHandler(); + ext = "jpg"; + } + else + { + h = new wxPNGHandler(); + ext = "png"; + } + + int res = 0; + if (h) + { + wxString p(path); + if (!p.EndsWith("/")) + p = p.Append("/"); + p = p.Append(name).Append(".").Append(ext); + + wxFileOutputStream stream(p); + res = h->SaveFile(&image, stream, false); + delete h; + } + + return res; +} + +void* wx_image_load(const char* path) +{ + wxLogNull logNull; /* removes sRGB-warnings on Windows */ + wxImage* image = new wxImage(path); + if (image->IsOk()) + return image; + delete image; + return 0; +} + +void wx_image_free(void* image) +{ + delete (wxImage*)image; +} + +void wx_image_rescale(void* image, int width, int height) +{ + ((wxImage*)image)->Rescale(width, height); +} + +void wx_image_get_size(void* image, int* width, int* height) +{ + *width = ((wxImage*)image)->GetWidth(); + *height = ((wxImage*)image)->GetHeight(); +} + +unsigned char* wx_image_get_data(void* image) +{ + return ((wxImage*)image)->GetData(); +} + +unsigned char* wx_image_get_alpha(void* image) +{ + return ((wxImage*)image)->GetAlpha(); +} + +/* wxFileConfig */ + +void* wx_config_load(const char* path) +{ + if (!wxFileExists(path)) + return 0; + wxFileInputStream stream(path); + if (stream.IsOk()) + return new wxFileConfig(stream); + return 0; +} +int wx_config_get_string(void* config, const char* name, char* dst, int size, const char* defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + wxString val; + bool res = c->Read(name, &val, wxString(defVal)); + strncpy(dst, val.GetData().AsChar(), size-1); + dst[size-1] = 0; + return res; +} +int wx_config_get_int(void* config, const char* name, int* dst, int defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + return c->Read(name, dst, defVal); +} + +int wx_config_get_float(void* config, const char* name, float* dst, float defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + return c->Read(name, dst, defVal); + +} + +int wx_config_get_bool(void* config, const char* name, int* dst, int defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + wxString val; + bool res = 1; + if (c->Read(name, &val)) + { + val.LowerCase(); + if (val.StartsWith("true")) + *dst = 1; + else if (val.StartsWith("false")) + *dst = 0; + else + res = 0; + } + if (!res) + res = c->Read(name, (bool*)dst, (bool)defVal); + + return res; +} + +int wx_config_has_entry(void* config, const char* name) +{ + wxFileConfig* c = ((wxFileConfig*)config); + return c->HasEntry(name); +} + +void wx_config_free(void* config) +{ + delete (wxFileConfig*)config; +} + +typedef struct progress_data_t { + WX_CALLBACK callback; + void* data; + int active; + int result; +} progress_data_t; + +static void progress_callback(void* data) +{ + progress_data_t* d = (progress_data_t*) data; + d->result = d->callback(d->data); + d->active = 0; +} + +int wx_progressdialogpulse(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data) +{ + struct progress_data_t pdata; + pdata.callback = callback; + pdata.data = data; + pdata.active = 1; + pdata.result = 0; + + thread_t* t = thread_create(progress_callback, &pdata); + + wxProgressDialog dlg(title, message, 100, (wxWindow*)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); + while (pdata.active) + { + dlg.Pulse(); + wxMilliSleep(50); + } + thread_kill(t); + + return pdata.result; +} + +void wx_date_format(char* s, const char* format) +{ + wxString res = wxDateTime::Now().Format(format); + strcpy(s, res.mb_str()); +} diff --git a/src/wx-utils.h b/src/wx-utils.h index 719e224..6ab844b 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -8,12 +8,14 @@ #define INT_PARAM wxInt32 #endif -typedef void (*WX_CALLBACK)(); +typedef int (*WX_CALLBACK)(void* data); #ifdef __cplusplus extern "C" { #endif int wx_messagebox(void* nothing, const char* message, const char* title, int style); + void wx_simple_messagebox(const char* title, const char *format, ...); + int wx_xrcid(const char* s); int wx_filedialog(void* window, const char* title, const char* path, const char* extensions, const char* extension, int open, char* file); void wx_checkmenuitem(void* window, int id, int checked); @@ -25,8 +27,9 @@ extern "C" { void* wx_getsubmenu(void* window, int id); void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type); + void* wx_getnativemenu(void* menu); - int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, int min_length, int max_length, LONG_PARAM result); + int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, unsigned int min_length, unsigned int max_length, LONG_PARAM result); int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type); int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id); @@ -37,8 +40,11 @@ extern "C" { void wx_setdlgitemtext(void* window, int id, char* str); void wx_enablewindow(void* window, int enabled); void wx_showwindow(void* window, int show); - void wx_callback(void* window, WX_CALLBACK callback); + int wx_iswindowvisible(void* window); + void* wx_getnativewindow(void* window); + void wx_callback(void* window, WX_CALLBACK callback, void* data); void wx_togglewindow(void* window); + int wx_progressdialogpulse(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data); void wx_enddialog(void* window, int ret_code); @@ -72,7 +78,30 @@ extern "C" { int wx_file_exists(char* path); int wx_dir_exists(char* path); + void wx_date_format(char* s, const char* format); + + int wx_image_save(const char* path, const char* name, const char* format, unsigned char* rgba, int width, int height, int alpha); + + void* wx_image_load(const char* path); + void wx_image_rescale(void* image, int width, int height); + void wx_image_get_size(void* image, int* width, int* height); + unsigned char* wx_image_get_data(void* image); + unsigned char* wx_image_get_alpha(void* image); + void wx_image_free(void* image); + + void* wx_config_load(const char* path); + int wx_config_get_string(void* config, const char* name, char* dst, int size, const char* defVal); + int wx_config_get_int(void* config, const char* name, int* dst, int defVal); + int wx_config_get_float(void* config, const char* name, float* dst, float defVal); + int wx_config_get_bool(void* config, const char* name, int* dst, int defVal); + int wx_config_has_entry(void* config, const char* name); + void wx_config_free(void* config); + int confirm(); + +#ifdef _WIN32 + void wx_winsendmessage(void* window, int msg, INT_PARAM wParam, LONG_PARAM lParam); +#endif #ifdef __cplusplus } #endif @@ -111,9 +140,17 @@ extern void (*wx_idle_func)(void* window, void* event); #define WX_LB_GETTEXT 62 #define WX_LB_DELETESTRING 63 #define WX_LB_INSERTSTRING 64 +#define WX_LB_RESETCONTENT 65 +#define WX_LB_SETCURSEL 66 +#define WX_LBN_DBLCLK 67 #define WX_MB_OK wxOK #define WX_MB_OKCANCEL wxOK|wxCANCEL #define WX_IDOK wxOK +#define IMAGE_JPG "jpg" +#define IMAGE_PNG "png" +#define IMAGE_BMP "bmp" +#define IMAGE_TIFF "tiff" + extern int has_been_inited; diff --git a/src/wx.rc b/src/wx.rc new file mode 100644 index 0000000..20db40e --- /dev/null +++ b/src/wx.rc @@ -0,0 +1 @@ +#include "wx/msw/wx.rc" \ No newline at end of file From 6697e319294b2f01cd3e042552e52d5a964e671e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 31 Jul 2017 10:10:36 +0100 Subject: [PATCH 0104/1050] Added NE2000 network support. NE2000 emulation originally from Bochs, ported by SA1988. SLiRP originally from QEMU, ported by neozeed. --- src/Makefile.mingw-network | 51 ++ src/bswap.h | 202 +++++ src/ne2000.c | 1748 ++++++++++++++++++++++++++++++++++++ src/ne2000.h | 1 + src/nethandler.c | 117 +++ src/nethandler.h | 20 + src/pc.c | 34 + src/pc.rc | 45 +- src/resources.h | 2 + src/slirp/COPYRIGHT.txt | 61 ++ src/slirp/Makefile | 26 + src/slirp/VERSION.txt | 1 + src/slirp/bootp.c | 242 +++++ src/slirp/bootp.h | 121 +++ src/slirp/cksum.c | 137 +++ src/slirp/config-host.h | 9 + src/slirp/config.h | 9 + src/slirp/ctl.h | 7 + src/slirp/debug.c | 440 +++++++++ src/slirp/debug.h | 50 ++ src/slirp/icmp_var.h | 65 ++ src/slirp/if.c | 322 +++++++ src/slirp/if.h | 50 ++ src/slirp/ip.h | 341 +++++++ src/slirp/ip_icmp.c | 371 ++++++++ src/slirp/ip_icmp.h | 168 ++++ src/slirp/ip_input.c | 693 ++++++++++++++ src/slirp/ip_output.c | 202 +++++ src/slirp/libslirp.h | 41 + src/slirp/main.h | 54 ++ src/slirp/mbuf.c | 248 +++++ src/slirp/mbuf.h | 143 +++ src/slirp/misc.c | 970 ++++++++++++++++++++ src/slirp/misc.h | 87 ++ src/slirp/queue.c | 116 +++ src/slirp/queue.h | 101 +++ src/slirp/sbuf.c | 202 +++++ src/slirp/sbuf.h | 31 + src/slirp/slirp.c | 682 ++++++++++++++ src/slirp/slirp.h | 415 +++++++++ src/slirp/slirp_config.h | 135 +++ src/slirp/socket.c | 731 +++++++++++++++ src/slirp/socket.h | 104 +++ src/slirp/tcp.h | 181 ++++ src/slirp/tcp_input.c | 1722 +++++++++++++++++++++++++++++++++++ src/slirp/tcp_output.c | 601 +++++++++++++ src/slirp/tcp_subr.c | 1324 +++++++++++++++++++++++++++ src/slirp/tcp_timer.c | 322 +++++++ src/slirp/tcp_timer.h | 138 +++ src/slirp/tcp_var.h | 248 +++++ src/slirp/tcpip.h | 70 ++ src/slirp/tftp.c | 331 +++++++ src/slirp/tftp.h | 40 + src/slirp/udp.c | 676 ++++++++++++++ src/slirp/udp.h | 114 +++ src/win-config.c | 99 +- src/win.c | 8 + 57 files changed, 15460 insertions(+), 9 deletions(-) create mode 100644 src/Makefile.mingw-network create mode 100644 src/bswap.h create mode 100644 src/ne2000.c create mode 100644 src/ne2000.h create mode 100644 src/nethandler.c create mode 100644 src/nethandler.h create mode 100644 src/slirp/COPYRIGHT.txt create mode 100644 src/slirp/Makefile create mode 100644 src/slirp/VERSION.txt create mode 100644 src/slirp/bootp.c create mode 100644 src/slirp/bootp.h create mode 100644 src/slirp/cksum.c create mode 100644 src/slirp/config-host.h create mode 100644 src/slirp/config.h create mode 100644 src/slirp/ctl.h create mode 100644 src/slirp/debug.c create mode 100644 src/slirp/debug.h create mode 100644 src/slirp/icmp_var.h create mode 100644 src/slirp/if.c create mode 100644 src/slirp/if.h create mode 100644 src/slirp/ip.h create mode 100644 src/slirp/ip_icmp.c create mode 100644 src/slirp/ip_icmp.h create mode 100644 src/slirp/ip_input.c create mode 100644 src/slirp/ip_output.c create mode 100644 src/slirp/libslirp.h create mode 100644 src/slirp/main.h create mode 100644 src/slirp/mbuf.c create mode 100644 src/slirp/mbuf.h create mode 100644 src/slirp/misc.c create mode 100644 src/slirp/misc.h create mode 100644 src/slirp/queue.c create mode 100644 src/slirp/queue.h create mode 100644 src/slirp/sbuf.c create mode 100644 src/slirp/sbuf.h create mode 100644 src/slirp/slirp.c create mode 100644 src/slirp/slirp.h create mode 100644 src/slirp/slirp_config.h create mode 100644 src/slirp/socket.c create mode 100644 src/slirp/socket.h create mode 100644 src/slirp/tcp.h create mode 100644 src/slirp/tcp_input.c create mode 100644 src/slirp/tcp_output.c create mode 100644 src/slirp/tcp_subr.c create mode 100644 src/slirp/tcp_timer.c create mode 100644 src/slirp/tcp_timer.h create mode 100644 src/slirp/tcp_var.h create mode 100644 src/slirp/tcpip.h create mode 100644 src/slirp/tftp.c create mode 100644 src/slirp/tftp.h create mode 100644 src/slirp/udp.c create mode 100644 src/slirp/udp.h diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network new file mode 100644 index 0000000..6adadca --- /dev/null +++ b/src/Makefile.mingw-network @@ -0,0 +1,51 @@ +VPATH = . dosbox resid-fp +CPP = g++.exe +CC = gcc.exe +MAKE = make.exe +WINDRES = windres.exe +CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -DUSE_NETWORKING +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + scat.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ + win-ddraw-fs.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 = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 +NETOBJ = ne2000.o nethandler.o + +LIBS = -mwindows -lwinmm -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lwsock32 -liphlpapi -lstdc++ + +PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) libslirp.a + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) slirp/libslirp.a -o "PCem.exe" $(LIBS) + +libslirp.a: + $(MAKE) -C slirp + +all : libslirp.a PCem.exe + +clean : + rm *.o + rm *.exe + rm *.res + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CFLAGS) -c $< + +pc.res: pc.rc + $(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff -D USE_NETWORKING diff --git a/src/bswap.h b/src/bswap.h new file mode 100644 index 0000000..c473c50 --- /dev/null +++ b/src/bswap.h @@ -0,0 +1,202 @@ +#ifndef BSWAP_H +#define BSWAP_H + +//#include "config-host.h" + +#include + +#ifdef HAVE_BYTESWAP_H +#include +#else + +#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 __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 __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) +{ + return bswap_16(x); +} + +static inline uint32_t bswap32(uint32_t x) +{ + return bswap_32(x); +} + +static inline uint64_t bswap64(uint64_t x) +{ + return bswap_64(x); +} + +static inline void bswap16s(uint16_t *s) +{ + *s = bswap16(*s); +} + +static inline void bswap32s(uint32_t *s) +{ + *s = bswap32(*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); +#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); +#endif + +#define CPU_CONVERT(endian, size, type)\ +static inline type endian ## size ## _to_cpu(type v)\ +{\ + return endian ## _bswap(v, size);\ +}\ +\ +static inline type cpu_to_ ## endian ## size(type v)\ +{\ + return endian ## _bswap(v, size);\ +}\ +\ +static inline void endian ## size ## _to_cpus(type *p)\ +{\ + endian ## _bswaps(p, size)\ +}\ +\ +static inline void cpu_to_ ## endian ## size ## s(type *p)\ +{\ + endian ## _bswaps(p, size)\ +}\ +\ +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)\ +{\ + *p = cpu_to_ ## endian ## size(v);\ +} + +CPU_CONVERT(be, 16, uint16_t) +CPU_CONVERT(be, 32, uint32_t) +CPU_CONVERT(be, 64, uint64_t) + +CPU_CONVERT(le, 16, uint16_t) +CPU_CONVERT(le, 32, uint32_t) +CPU_CONVERT(le, 64, uint64_t) + +/* unaligned versions (optimized for frequent unaligned accesses)*/ + +#if defined(__i386__) || defined(__powerpc__) + +#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) +#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) +#define le16_to_cpupu(p) le16_to_cpup(p) +#define le32_to_cpupu(p) le32_to_cpup(p) + +#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) +#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) + +#else + +static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) +{ + uint8_t *p1 = (uint8_t *)p; + + p1[0] = v; + p1[1] = v >> 8; +} + +static inline void cpu_to_le32wu(uint32_t *p, uint32_t v) +{ + uint8_t *p1 = (uint8_t *)p; + + p1[0] = v; + p1[1] = v >> 8; + p1[2] = v >> 16; + p1[3] = v >> 24; +} + +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) +{ + 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) +{ + uint8_t *p1 = (uint8_t *)p; + + p1[0] = v >> 8; + p1[1] = v; +} + +static inline void cpu_to_be32wu(uint32_t *p, uint32_t v) +{ + uint8_t *p1 = (uint8_t *)p; + + p1[0] = v >> 24; + p1[1] = v >> 16; + p1[2] = v >> 8; + p1[3] = v; +} + +#endif + +#ifdef WORDS_BIGENDIAN +#define cpu_to_32wu cpu_to_be32wu +#else +#define cpu_to_32wu cpu_to_le32wu +#endif + +#undef le_bswap +#undef be_bswap +#undef le_bswaps +#undef be_bswaps + +#endif /* BSWAP_H */ diff --git a/src/ne2000.c b/src/ne2000.c new file mode 100644 index 0000000..afbabb2 --- /dev/null +++ b/src/ne2000.c @@ -0,0 +1,1748 @@ +///////////////////////////////////////////////////////////////////////// +// $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/ +// +// This library 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 of the License, or (at your option) any later version. +// +// This library 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 library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +// Peter Grehan (grehan@iprg.nokia.com) coded all of this +// NE2000/ether stuff. +//#include "vl.h" +#include +#include +#include +#include + +#include "slirp/slirp.h" +#include "slirp/queue.h" +#include + +#include "ibm.h" +#include "device.h" + +#include "nethandler.h" + +#include "config.h" +#include "io.h" +#include "ne2000.h" +#include "pic.h" +#include "timer.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}; + +#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(); + +#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 BX_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) + +typedef struct ne2000_t +{ + // + // 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; + + 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 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. + // + + // 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; +} ne2000_t; + +static void ne2000_tx_event(int val, void *p); + +void ne2000_rx_frame(void *p, const void *buf, int io_len); + +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(int type, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + int i; + + pclog("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]; + + // 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; + + //memset( & ne2000->physaddr, 0, sizeof(ne2000->physaddr)); + //memset( & ne2000->mchash, 0, sizeof(ne2000->mchash)); + ne2000->curr_page = 0; + + ne2000->rempkt_ptr = 0; + ne2000->localpkt_ptr = 0; + ne2000->address_cnt = 0; + + 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); +} + +#include "bswap.h" + +// +// 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 inline uint8_t ne2000_chipmem_read_b(uint32_t address, ne2000_t *ne2000) +{ + // ROM'd MAC address + if ((address >= 0) && (address <= 31)) + return ne2000->macaddr[address]; + + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + return ne2000->mem[address - BX_NE2K_MEMSTART]; + else + return 0xff; +} + + +static inline uint16_t ne2000_chipmem_read_w(uint32_t address, ne2000_t *ne2000) +{ + // ROM'd MAC address + if ((address >=0) && (address <= 31)) + return le16_to_cpu(*(uint16_t *)(ne2000->macaddr + address)); + + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + return le16_to_cpu(*(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART))); + else + return 0xffff; +} + +static inline void ne2000_chipmem_write_b(uint32_t address, uint8_t value, ne2000_t *ne2000) +{ + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; +} + + +static inline void ne2000_chipmem_write_w(uint32_t address, uint16_t value, ne2000_t *ne2000) +{ + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + *(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART)) = cpu_to_le16(value); +} + +// +// 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. +// +uint16_t ne2000_dma_read(int io_len, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + // + // 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). + // + ne2000->remote_dma += io_len; + 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 > 1) + ne2000->remote_bytes -= io_len; + else + 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); + picintc(1 << ne2000->base_irq); + } + } + + return 0; +} + +uint16_t ne2000_asic_read_w(uint16_t offset, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + int retval; + + if (ne2000->DCR.wdsize & 0x01) + { + /* 16 bit access */ + retval = ne2000_chipmem_read_w(ne2000->remote_dma, ne2000); + ne2000_dma_read(2, ne2000); + } + else + { + /* 8 bit access */ + retval = ne2000_chipmem_read_b(ne2000->remote_dma, ne2000); + ne2000_dma_read(1, ne2000); + } + + pclog("asic read val=0x%04x\n", retval); + + return retval; +} + +void ne2000_dma_write(int io_len, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + // is this right ??? asic_read uses DCR.wordsize + ne2000->remote_dma += io_len; + if (ne2000->remote_dma == ne2000->page_stop << 8) + ne2000->remote_dma = ne2000->page_start << 8; + + ne2000->remote_bytes -= io_len; + 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); + picintc(1 << ne2000->base_irq); + } + } +} + +void ne2000_asic_write_w(uint16_t offset, uint16_t value, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + pclog("asic write val=0x%04x\n", value); + + if (ne2000->remote_bytes == 0) + return; + if (ne2000->DCR.wdsize & 0x01) { + /* 16 bit access */ + ne2000_chipmem_write_w(ne2000->remote_dma, value, ne2000); + ne2000_dma_write(2, ne2000); + } else { + /* 8 bit access */ + ne2000_chipmem_write_b(ne2000->remote_dma, value, ne2000); + ne2000_dma_write(1, ne2000); + } +} + +uint8_t ne2000_asic_read_b(uint16_t offset, void *p) +{ + if (offset & 1) + return ne2000_asic_read_w(offset & ~1, p) >> 1; + return ne2000_asic_read_w(offset, p) & 0xff; +} + +void ne2000_asic_write_b(uint16_t offset, uint8_t value, void *p) +{ + if (offset & 1) + ne2000_asic_write_w(offset & ~1, value << 8, p); + else + ne2000_asic_write_w(offset, value, p); +} + +uint8_t ne2000_reset_read(uint16_t offset, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_reset(BX_RESET_SOFTWARE, ne2000); + return 0; +} + +void ne2000_reset_write(uint16_t offset, uint8_t value, void *p) +{ +} + +// +// 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 +// +uint8_t ne2000_read(uint16_t address, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + pclog("read addr %x\n", address); + int ret = 0; + + address &= 0xf; + + if (address == 0x00) + { + ret = (((ne2000->CR.pgsel & 0x03) << 6) | + ((ne2000->CR.rdma_cmd & 0x07) << 3) | + (ne2000->CR.tx_packet << 2) | + (ne2000->CR.start << 1) | + (ne2000->CR.stop)); + pclog("read CR returns 0x%08x\n", ret); + } + else + { + switch (ne2000->CR.pgsel) + { + case 0x00: + pclog("page 0 read from port %04x\n", address); + + switch (address) + { + case 0x1: // CLDA0 + return ne2000->local_dma & 0xff; + + case 0x2: // CLDA1 + return ne2000->local_dma >> 8; + + case 0x3: // BNRY + return ne2000->bound_ptr; + + case 0x4: // TSR + return ((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)); + + case 0x5: // NCR + return ne2000->num_coll; + + case 0x6: // FIFO + // reading FIFO is only valid in loopback mode + pclog("reading FIFO not supported yet\n"); + return ne2000->fifo; + + case 0x7: // ISR + return ((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)); + + case 0x8: // CRDA0 + return ne2000->remote_dma & 0xff; + + case 0x9: // CRDA1 + return ne2000->remote_dma >> 8; + + case 0xa: // reserved + pclog("reserved read - page 0, 0xa\n"); + return 0xff; + + case 0xb: // reserved + pclog("reserved read - page 0, 0xb\n"); + return 0xff; + + case 0xc: // RSR + return ((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)); + + case 0xd: // CNTR0 + return ne2000->tallycnt_0; + + case 0xe: // CNTR1 + return ne2000->tallycnt_1; + + case 0xf: // CNTR2 + return ne2000->tallycnt_2; + } + + return 0; + + case 0x01: + pclog("page 1 read from port %04x\n", address); + + switch (address) + { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + return ne2000->physaddr[address - 1]; + + case 0x7: // CURR + pclog("returning current page: %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[address - 8]; + } + + return 0; + + case 0x02: + pclog("page 2 read from port %04x\n", address); + + switch (address) + { + case 0x1: // PSTART + return (ne2000->page_start); + + case 0x2: // PSTOP + return ne2000->page_stop; + + case 0x3: // Remote Next-packet pointer + return ne2000->rempkt_ptr; + + case 0x4: // TPSR + return ne2000->tx_page_start; + + case 0x5: // Local Next-packet pointer + return ne2000->localpkt_ptr; + + case 0x6: // Address counter (upper) + return ne2000->address_cnt >> 8; + + case 0x7: // Address counter (lower) + return ne2000->address_cnt & 0xff; + + case 0x8: // Reserved + case 0x9: + case 0xa: + case 0xb: + pclog("reserved read - page 2, 0x%02x\n", address); + break; + + 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 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)); + } + break; + + default: + fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); + } + } + + return ret; +} + +// +// write_handler/write - i/o 'catcher' function called from BOCHS +// mainline when the CPU attempts a write in the i/o space registered +// by this ne2000 instance +// +void ne2000_write(uint16_t address, uint8_t value, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + pclog("write address %x, val=%x\n", address, value); + + address &= 0xf; + + // + // 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 (address == 0x00) + { + pclog("wrote 0x%02x to CR\n", value); + + // Validate remote-DMA + if ((value & 0x38) == 0x00) + { + pclog("CR write - invalid rDMA value 0\n"); + value |= 0x20; /* dma_cmd == 4 is a safe default */ + //value = 0x22; /* 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->mem[ne2000->bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]); + pclog("Sending buffer #x%x length %d\n", + ne2000->remote_start, + ne2000->remote_bytes); + } + + // Check for start-tx + if ((value & 0x04) && ne2000->TCR.loop_cntl) + { + // loopback mode + if (ne2000->TCR.loop_cntl != 1) + { + pclog("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); + + // do a TX interrupt + // Generate an interrupt if not masked and not one in progress + if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) + { + //LOG_MSG("tx complete interrupt"); + picint(1 << ne2000->base_irq); + } + ne2000->ISR.pkt_tx = 1; + } + } + else if (value & 0x04) + { + // start-tx and no loopback + if (ne2000->CR.stop || !ne2000->CR.start) + pclog("CR write - tx start, dev in reset\n"); + + if (ne2000->tx_bytes == 0) + pclog("CR write - tx start, tx bytes == 0\n"); + + // Send the packet to the system driver + /* TODO: Transmit packet */ + //BX_NE2K_THIS ethdev->sendpkt(& ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + //pcap_sendpacket(adhandle,&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + if (net_is_slirp) + { + slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + pclog("ne2000 slirp sending packet\n"); + } + if(net_is_pcap && net_pcap!=NULL) + { + _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + pclog("ne2000 pcap sending packet\n"); + } + + ne2000_tx_event(value, ne2000); + // Schedule a timer to trigger a tx-complete interrupt + // The number of microseconds is the bit-time / 10. + // The bit-time is the preamble+sfd (64 bits), the + // inter-frame gap (96 bits), the CRC (4 bytes), and the + // the number of bits in the frame (s.tx_bytes * 8). + // + + /* TODO: Code transmit timer */ + /* + bx_pc_system.activate_timer(ne2000->tx_timer_index, + (64 + 96 + 4*8 + ne2000->tx_bytes*8)/10, + 0); // not continuous + */ + } // end transmit-start branch + + // 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); + picintc(1 << ne2000->base_irq); + //DEV_pic_raise_irq(ne2000->base_irq); + } + } + } + else + { + switch (ne2000->CR.pgsel) + { + case 0x00: + pclog("page 0 write to port %04x\n", address); + + // It appears to be a common practice to use outw on page0 regs... + + switch (address) + { + case 0x1: // PSTART + ne2000->page_start = value; + break; + + case 0x2: // PSTOP + // BX_INFO(("Writing to PSTOP: %02x", value)); + ne2000->page_stop = value; + break; + + case 0x3: // BNRY + ne2000->bound_ptr = 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 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); + //DEV_pic_lower_irq(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) + pclog("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) + pclog("RCR write, monitor bit set!\n"); + break; + + case 0xd: // TCR + // Check reserved bits + if (value & 0xe0) + pclog("TCR write, reserved bits set\n"); + + // Test loop mode (not supported) + if (value & 0x06) + { + ne2000->TCR.loop_cntl = (value & 0x6) >> 1; + pclog("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) + { + //fatal("ne2000 TCR write, inhibit-CRC not supported\n"); + pclog("ne2000 TCR write, inhibit-CRC not supported\n"); + return; + } + + // Auto-transmit disable very suspicious + if (value & 0x08) + { + //fatal("ne2000 TCR write, auto transmit disable not supported\n"); + pclog("ne2000 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)) + pclog("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) + pclog("DCR write - LAS set ???\n"); + if (value & 0x10) + pclog("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) + pclog("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); + if (ne2000->ISR.pkt_tx && ne2000->IMR.tx_inte) + { + pclog("tx irq retrigger\n"); + picint(1 << ne2000->base_irq); + picintc(1 << ne2000->base_irq); + } + break; + } + break; + + case 0x01: + pclog("page 1 w offset %04x\n", address); + switch (address) + { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + ne2000->physaddr[address - 1] = 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[address - 8] = value; + break; + } + break; + + case 0x02: + if (address != 0) + pclog("page 2 write ?\n"); + + switch (address) + { + 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 0x3: // Remote Next-pkt pointer + ne2000->rempkt_ptr = value; + break; + + case 0x4: + //fatal("page 2 write to reserved offset 4\n"); + //OS/2 Warp can cause this to freak out. + pclog("ne2000 page 2 write to reserved offset 4\n"); + 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 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: + //fatal("page 2 write to reserved offset %0x\n", address); + pclog("ne2000 page 2 write to reserved offset %0x\n", address); + default: + break; + } + break; + + default: + //fatal("ne2K: unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + break; + } + } +} + +/* + * 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) +{ +#define POLYNOMIAL 0x04c11db6 + 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; +#undef POLYNOMIAL +} + +/* + * 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 + */ +void ne2000_rx_frame(void *p, const void *buf, int io_len) +{ + ne2000_t *ne2000 = (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}; + + if(io_len != 60) + pclog("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; + + // 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); + + // 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("no space\n"); + return; + } + + if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) + { + pclog("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) + { + if (!memcmp(buf, bcast_addr, 6)) + { + 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 + pclog("rx_frame promiscuous receive\n"); + + pclog("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; + + // 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); + memcpy(startptr + 4, buf, io_len); + ne2000->curr_page = nextpage; + } + else + { + int endbytes = (ne2000->page_stop - ne2000->curr_page) + * 256; + memcpy(startptr, pkthdr, 4); + 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->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"); +} + +void ne2000_tx_timer(void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + pclog("tx_timer\n"); + ne2000->TSR.tx_ok = 1; + // Generate an interrupt if not masked and not one in progress + if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) + { + //LOG_MSG("tx complete interrupt"); + picint(1 << ne2000->base_irq); + //DEV_pic_raise_irq(ne2000->base_irq); + } + //else LOG_MSG("no tx complete interrupt"); + ne2000->ISR.pkt_tx = 1; + ne2000->tx_timer_active = 0; +} + +static void ne2000_tx_event(int val, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_tx_timer(ne2000); +} + +static void ne2000_poller(void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + struct queuepacket *qp; + const unsigned char *data; + struct pcap_pkthdr h; + + 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); + pclog("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) + { + data = _pcap_next(net_pcap,&h); + if (data == 0x0) + return; + if ((memcmp(data+6,maclocal,6)) == 0) + pclog("ne2000 we just saw ourselves\n"); + else + { + if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) + return; + + pclog("ne2000 pcap received a frame %d bytes\n",h.caplen); + ne2000_rx_frame(ne2000,data,h.caplen); + } + } +} + + +void *ne2000_init() +{ + struct in_addr myaddr; + int rc; + + ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); + memset(ne2000, 0, sizeof(ne2000_t)); + + uint16_t addr = device_get_config_int("addr"); + ne2000_setirq(ne2000, device_get_config_int("irq")); + + //net_type + //0 pcap + //1 slirp + // + net_is_slirp = config_get_int(CFG_MACHINE, NULL, "net_type", 1); + pclog("ne2000 pcap device %s\n",config_get_string(CFG_MACHINE, NULL,"pcap_device","nothing")); + + //Check that we have a string setup, otherwise turn pcap off + if (!strcmp("nothing",config_get_string(CFG_MACHINE, NULL,"pcap_device","nothing"))) + net_is_pcap = 0; + else if (net_is_slirp == 0) + net_is_pcap = 1; + + io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); + memcpy(ne2000->physaddr, maclocal, 6); + + ne2000_reset(BX_RESET_HARDWARE, ne2000); + vlan_handler(ne2000_poller, ne2000); + + pclog("ne2000 init 0x%X %d\tslirp is %d net_is_pcap is %d\n",addr,device_get_config_int("irq"),net_is_slirp,net_is_pcap); + + //need a switch statment for more network types. + + if (net_is_slirp) + { + pclog("ne2000 initalizing SLiRP\n"); + net_is_pcap = 0; + rc = slirp_init(); + pclog("ne2000 slirp_init returned: %d\n",rc); + if (rc == 0) + { + pclog("ne2000 slirp initalized!\n"); + inet_aton("10.0.2.15",&myaddr); + //YES THIS NEEDS TO PULL FROM A CONFIG FILE... but for now. + rc=slirp_redir(0,42323,myaddr,23); + pclog("ne2000 slirp redir returned %d on port 42323 -> 23\n",rc); + rc=slirp_redir(0,42380,myaddr,80); + pclog("ne2000 slirp redir returned %d on port 42380 -> 80\n",rc); + rc=slirp_redir(0,42443,myaddr,443); + pclog("ne2000 slirp redir returned %d on port 42443 -> 443\n",rc); + rc=slirp_redir(0,42322,myaddr,22); + pclog("ne2000 slirp redir returned %d on port 42322 -> 22\n",rc); + + //Kali + rc=slirp_redir(1,2213,myaddr,2213); + pclog("ne2000 slirp redir returned %d on port 2213 -> 2213\n",rc); + rc=slirp_redir(1,2231,myaddr,2231); + pclog("ne2000 slirp redir returned %d on port 2231 -> 2231\n",rc); + rc=slirp_redir(1,2271,myaddr,2271); + pclog("ne2000 slirp redir returned %d on port 2271 -> 2271\n",rc); + + net_slirp_inited=1; + slirpq = QueueCreate(); + net_is_slirp=1; + fizz=0; + pclog("ne2000 slirpq is %x\n",&slirpq); + } + else + { + net_slirp_inited=0; + net_is_slirp=0; + } + } + if (net_is_pcap) + { //pcap + char errbuf[32768]; + + pclog("ne2000 initalizing libpcap\n"); + net_is_slirp=0; + net_hLib = LoadLibraryA(net_lib_name); + if(net_hLib==0) + { + pclog("ne2000 Failed to load %s\n",net_lib_name); + net_is_pcap=0; + } + _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) + { + pclog("ne2000 Pcap version [%s]\n",_pcap_lib_version()); + + if ((net_pcap=_pcap_open_live(config_get_string(CFG_MACHINE, NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) + { + pclog("ne2000 pcap_open_live error on %s!\n",config_get_string(CFG_MACHINE, NULL,"pcap_device","whatever the ethernet is")); + net_is_pcap=0; return(ne2000); //YUCK!!! + } + } + else + { + pclog("%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); + pclog("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); + switch(rc) + { + case 0: + pclog("ne2000 Setting interface to non-blocking mode.."); + rc=_pcap_setnonblock(net_pcap,1,errbuf); + if (rc==0) + { + pclog(".."); + rc=_pcap_getnonblock(net_pcap,errbuf); + if (rc==1) + { + pclog("..!",rc); + net_is_pcap=1; + } + else + { + pclog("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + net_is_pcap=0; + } + } + else + { + pclog("There was an unexpected error of [%s]\n\nexiting.\n",errbuf); + net_is_pcap=0; + } + pclog("\n"); + break; + case 1: + pclog("non blocking\n"); + break; + default: + pclog("this isn't right!!!\n"); + net_is_pcap=0; + break; + } + if( net_is_pcap ) + { + if(_pcap_compile && _pcap_setfilter) + { + struct bpf_program fp; + char filter_exp[255]; + + pclog("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) + { + pclog("\nne2000 Couldn't compile filter\n"); + } + else + { + pclog("..."); + if (_pcap_setfilter(net_pcap, &fp) == -1) + { + pclog("\nError installing pcap filter.\n"); + } + else + { + pclog("...!\n"); + } + } + pclog("ne2000 Using filter\t[%s]\n",filter_exp); + } + else + { + pclog("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); + net_is_pcap=0; + } + pclog("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); + } + } //end pcap setup + + pclog("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); + + return ne2000; +} + +void ne2000_close(void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + free(ne2000); + if(net_is_slirp) + { + QueueDestroy(slirpq); + slirp_exit(0); + net_slirp_inited=0; + pclog("ne2000 exiting slirp\n"); + } + if(net_is_pcap && net_pcap!=NULL) + { + _pcap_close(net_pcap); + FreeLibrary(net_hLib); + pclog("ne2000 closing pcap\n"); + } + pclog("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 + }, + { + .type = -1 + } +}; + +device_t ne2000_device = +{ + "Novell NE2000", + 0, + ne2000_init, + ne2000_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("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() +{ + 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(timeout<0) + timeout=500; + 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); + } + //pclog("ne2000 slirp_tic()\n"); + }//end if slirp inited +} diff --git a/src/ne2000.h b/src/ne2000.h new file mode 100644 index 0000000..a3f1fea --- /dev/null +++ b/src/ne2000.h @@ -0,0 +1 @@ +extern device_t ne2000_device; diff --git a/src/nethandler.c b/src/nethandler.c new file mode 100644 index 0000000..221a69a --- /dev/null +++ b/src/nethandler.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include +#include "nethandler.h" + +#include "ibm.h" +#include "device.h" + +#include "ne2000.h" +#include "timer.h" + +int network_card_current = 0; +static int network_card_last = 0; + +typedef struct +{ + char name[32]; + char internal_name[24]; + device_t *device; +} NETWORK_CARD; + +static NETWORK_CARD network_cards[] = +{ + {"None", "", NULL}, + {"Novell NE2000", "ne2000", &ne2000_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].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; +} + +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) +//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++; +} + +void vlan_poller(void *priv) +{ + int c; + + vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0)); + + for (c = 0; c < vlan_handlers_num; c++) + vlan_handlers[c].poller(vlan_handlers[c].priv); +} + +void vlan_reset() +{ + 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 new file mode 100644 index 0000000..024fad8 --- /dev/null +++ b/src/nethandler.h @@ -0,0 +1,20 @@ +#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; + +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); +void network_card_init(); + +char *network_card_get_internal_name(int card); +int network_card_get_from_internal_name(char *s); + +void initpcap(); +void closepcap(); + +void vlan_reset(); diff --git a/src/pc.c b/src/pc.c index 3a652dd..b836136 100644 --- a/src/pc.c +++ b/src/pc.c @@ -49,6 +49,13 @@ #include "x86.h" #include "paths.h" +#ifdef USE_NETWORKING +#include "nethandler.h" +#define NE2000 1 +uint8_t ethif; +int inum; +#endif + int window_w, window_h, window_x, window_y, window_remember; int start_in_fullscreen = 0; @@ -276,6 +283,10 @@ void initpc(int argc, char *argv[]) disc_init(); fdi_init(); img_init(); +#ifdef USE_NETWORKING + vlan_reset(); //NETWORK + network_card_init(network_card_current); +#endif //loadfont(); loadnvr(); @@ -371,6 +382,12 @@ void resetpchard() mouse_emu_init(); video_init(); speaker_init(); + +#ifdef USE_NETWORKING + vlan_reset(); //NETWORK + network_card_init(network_card_current); +#endif + sound_card_init(sound_card_current); if (GUS) device_add(&gus_device); @@ -757,6 +774,18 @@ void loadconfig(char *fn) enable_sync = config_get_int(CFG_MACHINE, NULL, "enable_sync", 1); +#ifdef USE_NETWORKING + //network + ethif = config_get_int(CFG_GLOBAL, NULL, "netinterface", 1); + if (ethif >= inum) + inum = ethif + 1; + + p = (char *)config_get_string(CFG_MACHINE, NULL, "netcard", ""); + if (p) + network_card_current = network_card_get_from_internal_name(p); + else + network_card_current = 0; +#endif for (d = 0; d < num_config_callbacks; ++d) if (config_callbacks[d].loadconfig) @@ -874,6 +903,11 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "enable_sync", enable_sync); +#ifdef USE_NETWORKING + config_set_int(CFG_GLOBAL, NULL, "netinterface", ethif); + config_set_string(CFG_MACHINE, NULL, "netcard", network_card_get_internal_name(network_card_current)); +#endif + for (d = 0; d < num_config_callbacks; ++d) if (config_callbacks[d].saveconfig) config_callbacks[d].saveconfig(); diff --git a/src/pc.rc b/src/pc.rc index c2a4b64..2307a57 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -69,13 +69,22 @@ BEGIN END END +#ifdef USE_NETWORKING +ConfigureDlg DIALOGEX 0, 0, 292, 432 +#else ConfigureDlg DIALOGEX 0, 0, 292, 412 +#endif STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure PCem" FONT 8, "MS Sans Serif" BEGIN +#ifdef USE_NETWORKING + DEFPUSHBUTTON "OK",IDOK,64,408,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,408,50,14, WS_TABSTOP +#else DEFPUSHBUTTON "OK",IDOK,64,388,50,14, WS_TABSTOP PUSHBUTTON "Cancel",IDCANCEL,128,388,50,14, WS_TABSTOP +#endif COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGUREMOD, 224, 16, 40, 14, WS_TABSTOP COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP @@ -90,12 +99,6 @@ BEGIN EDITTEXT IDC_MEMTEXT, 62, 172, 36, 14, ES_AUTOHSCROLL | ES_NUMBER CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 172, 12, 14 LTEXT "MB", IDC_TEXT_MB, 98, 172, 40, 10 - CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,312,118,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,328,118,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,344,118,10 - CONTROL "Synchronise time to host clock",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,360,118,10 - CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,376,118,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 376, 40, 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 @@ -110,6 +113,28 @@ BEGIN LTEXT "Drive B: :",IDC_STATIC,15,236,40,10 COMBOBOX IDC_COMBODRA,62,216,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBODRB,62,236,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + +#ifdef USE_NETWORKING + LTEXT "Network card:",IDC_STATIC,15,256,45,10 + COMBOBOX IDC_COMBONETCARD,62,256,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure", IDC_CONFIGURENETCARD, 224, 256, 40, 14, WS_TABSTOP + + LTEXT "Mouse :",IDC_STATIC,15,276,40,10 + COMBOBOX IDC_COMBOMOUSE,62,276,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Joystick :",IDC_STATIC,15,296,40,10 + COMBOBOX IDC_COMBOJOY,62,296,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,312,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 2...",IDC_JOY2,80,312,50,14, WS_TABSTOP + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,312,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 4...",IDC_JOY4,208,312,50,14, WS_TABSTOP + + CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,332,118,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,348,118,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,364,118,10 + CONTROL "Synchronise time to host clock",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,380,118,10 + CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,396,118,10 + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 356, 40, 14, WS_TABSTOP +#else LTEXT "Mouse :",IDC_STATIC,15,256,40,10 COMBOBOX IDC_COMBOMOUSE,62,256,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP LTEXT "Joystick :",IDC_STATIC,15,276,40,10 @@ -118,6 +143,14 @@ BEGIN PUSHBUTTON "Joystick 2...",IDC_JOY2,80,292,50,14, WS_TABSTOP DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,292,50,14, WS_TABSTOP PUSHBUTTON "Joystick 4...",IDC_JOY4,208,292,50,14, WS_TABSTOP + + CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,312,118,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,328,118,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,344,118,10 + CONTROL "Synchronise time to host clock",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,360,118,10 + CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,376,118,10 + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 376, 40, 14, WS_TABSTOP +#endif END HdConfDlg DIALOGEX 0, 0, 210, 312+4*16 diff --git a/src/resources.h b/src/resources.h index 9e1b226..4d9193d 100644 --- a/src/resources.h +++ b/src/resources.h @@ -44,6 +44,7 @@ #define IDC_COMBOWS 1065 #define IDC_COMBOMOUSE 1066 #define IDC_COMBOHDD 1067 +#define IDC_COMBONETCARD 1068 #define IDC_CHECK1 1010 #define IDC_CHECK2 1011 #define IDC_CHECK3 1012 @@ -126,6 +127,7 @@ #define IDC_CONFIGURESND 1201 #define IDC_CONFIGUREVOODOO 1202 #define IDC_CONFIGUREMOD 1203 +#define IDC_CONFIGURENETCARD 1204 #define IDC_JOY1 1210 #define IDC_JOY2 1211 #define IDC_JOY3 1212 diff --git a/src/slirp/COPYRIGHT.txt b/src/slirp/COPYRIGHT.txt new file mode 100644 index 0000000..01d4400 --- /dev/null +++ b/src/slirp/COPYRIGHT.txt @@ -0,0 +1,61 @@ +Slirp was written by Danny Gasparovski. +Copyright (c), 1995,1996 All Rights Reserved. + +Slirp is maintained by Kelly Price + +Slirp is free software; "free" as in you don't have to pay for it, and you +are free to do whatever you want with it. I do not accept any donations, +monetary or otherwise, for Slirp. Instead, I would ask you to pass this +potential donation to your favorite charity. In fact, I encourage +*everyone* who finds Slirp useful to make a small donation to their +favorite charity (for example, GreenPeace). This is not a requirement, but +a suggestion from someone who highly values the service they provide. + +The copyright terms and conditions: + +---BEGIN--- + + Copyright (c) 1995,1996 Danny Gasparovski. 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. + + THIS SOFTWARE IS PROVIDED ``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 + DANNY GASPAROVSKI 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. + +---END--- + +This basically means you can do anything you want with the software, except +1) call it your own, and 2) claim warranty on it. There is no warranty for +this software. None. Nada. If you lose a million dollars while using +Slirp, that's your loss not mine. So, ***USE AT YOUR OWN RISK!***. + +If these conditions cannot be met due to legal restrictions (E.g. where it +is against the law to give out Software without warranty), you must cease +using the software and delete all copies you have. + +Slirp uses code that is copyrighted by the following people/organizations: + +Juha Pirkola. +Gregory M. Christy. +The Regents of the University of California. +Carnegie Mellon University. +The Australian National University. +RSA Data Security, Inc. + +Please read the top of each source file for the details on the various +copyrights. \ No newline at end of file diff --git a/src/slirp/Makefile b/src/slirp/Makefile new file mode 100644 index 0000000..e513410 --- /dev/null +++ b/src/slirp/Makefile @@ -0,0 +1,26 @@ +CC=gcc +CFLAGS=-I. -Ofast -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/VERSION.txt b/src/slirp/VERSION.txt new file mode 100644 index 0000000..0dd1c2b --- /dev/null +++ b/src/slirp/VERSION.txt @@ -0,0 +1 @@ +qemu 0.9.0 (2007/02/05) \ No newline at end of file diff --git a/src/slirp/bootp.c b/src/slirp/bootp.c new file mode 100644 index 0000000..34913b6 --- /dev/null +++ b/src/slirp/bootp.c @@ -0,0 +1,242 @@ +/* + * QEMU BOOTP/DHCP server + * + * Copyright (c) 2004 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "slirp.h" + +/* XXX: only DHCP is supported */ + +#define NB_ADDR 16 + +#define START_ADDR 15 + +#define LEASE_TIME (24 * 3600) + +typedef struct { + uint8_t allocated; + uint8_t macaddr[6]; +} BOOTPClient; + +BOOTPClient bootp_clients[NB_ADDR]; + +static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; + +static BOOTPClient *get_new_addr(struct in_addr *paddr) +{ + BOOTPClient *bc; + int i; + + for(i = 0; i < NB_ADDR; i++) { + if (!bootp_clients[i].allocated) + goto found; + } + return NULL; + found: + bc = &bootp_clients[i]; + bc->allocated = 1; + paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); + return bc; +} + +static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr) +{ + BOOTPClient *bc; + int i; + + for(i = 0; i < NB_ADDR; i++) { + if (!memcmp(macaddr, bootp_clients[i].macaddr, 6)) + goto found; + } + return NULL; + found: + bc = &bootp_clients[i]; + bc->allocated = 1; + paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); + return bc; +} + +static void dhcp_decode(const uint8_t *buf, int size, + int *pmsg_type) +{ + const uint8_t *p, *p_end; + int len, tag; + + *pmsg_type = 0; + + p = buf; + p_end = buf + size; + if (size < 5) + return; + if (memcmp(p, rfc1533_cookie, 4) != 0) + return; + p += 4; + while (p < p_end) { + tag = p[0]; + if (tag == RFC1533_PAD) { + p++; + } else if (tag == RFC1533_END) { + break; + } else { + p++; + if (p >= p_end) + break; + len = *p++; + + switch(tag) { + case RFC2132_MSG_TYPE: + if (len >= 1) + *pmsg_type = p[0]; + break; + default: + break; + } + p += len; + } + } +} + +static void bootp_reply(struct bootp_t *bp) +{ + BOOTPClient *bc; + struct SLIRPmbuf *m; + struct bootp_t *rbp; + struct sockaddr_in saddr, daddr; + struct in_addr dns_addr; + int dhcp_msg_type, val; + uint8_t *q; + + /* extract exact DHCP msg type */ + dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type); + + if (dhcp_msg_type == 0) + dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */ + + if (dhcp_msg_type != DHCPDISCOVER && + dhcp_msg_type != DHCPREQUEST) + return; + /* XXX: this is a hack to get the client mac address */ + memcpy(client_ethaddr, bp->bp_hwaddr, 6); + + if ((m = m_get()) == NULL) + return; + m->m_data += if_maxlinkhdr; + rbp = (struct bootp_t *)m->m_data; + m->m_data += sizeof(struct udpiphdr); + memset(rbp, 0, sizeof(struct bootp_t)); + + if (dhcp_msg_type == DHCPDISCOVER) { + new_addr: + bc = get_new_addr(&daddr.sin_addr); + if (!bc) + return; + memcpy(bc->macaddr, client_ethaddr, 6); + } else { + bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr); + if (!bc) { + /* if never assigned, behaves as if it was already + assigned (windows fix because it remembers its address) */ + goto new_addr; + } + } + + saddr.sin_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_ALIAS); + saddr.sin_port = htons(BOOTP_SERVER); + + daddr.sin_port = htons(BOOTP_CLIENT); + + rbp->bp_op = BOOTP_REPLY; + rbp->bp_xid = bp->bp_xid; + rbp->bp_htype = 1; + rbp->bp_hlen = 6; + memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); + + rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ + rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ + + q = rbp->bp_vend; + memcpy(q, rfc1533_cookie, 4); + q += 4; + + if (dhcp_msg_type == DHCPDISCOVER) { + *q++ = RFC2132_MSG_TYPE; + *q++ = 1; + *q++ = DHCPOFFER; + } else if (dhcp_msg_type == DHCPREQUEST) { + *q++ = RFC2132_MSG_TYPE; + *q++ = 1; + *q++ = DHCPACK; + } + + if (dhcp_msg_type == DHCPDISCOVER || + dhcp_msg_type == DHCPREQUEST) { + *q++ = RFC2132_SRV_ID; + *q++ = 4; + memcpy(q, &saddr.sin_addr, 4); + q += 4; + + *q++ = RFC1533_NETMASK; + *q++ = 4; + *q++ = 0xff; + *q++ = 0xff; + *q++ = 0xff; + *q++ = 0x00; + + *q++ = RFC1533_GATEWAY; + *q++ = 4; + memcpy(q, &saddr.sin_addr, 4); + q += 4; + + *q++ = RFC1533_DNS; + *q++ = 4; + dns_addr.s_addr = htonl(ntohl(special_addr.s_addr) | CTL_DNS); + memcpy(q, &dns_addr, 4); + q += 4; + + *q++ = RFC2132_LEASE_TIME; + *q++ = 4; + val = htonl(LEASE_TIME); + memcpy(q, &val, 4); + q += 4; + + if (*slirp_hostname) { + val = strlen(slirp_hostname); + *q++ = RFC1533_HOSTNAME; + *q++ = val; + memcpy(q, slirp_hostname, val); + q += val; + } + } + *q++ = RFC1533_END; + + m->m_len = sizeof(struct bootp_t) - + sizeof(struct ip) - sizeof(struct udphdr); + udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); +} + +void bootp_input(struct SLIRPmbuf *m) +{ + struct bootp_t *bp = mtod(m, struct bootp_t *); + + if (bp->bp_op == BOOTP_REQUEST) { + bootp_reply(bp); + } +} diff --git a/src/slirp/bootp.h b/src/slirp/bootp.h new file mode 100644 index 0000000..0625161 --- /dev/null +++ b/src/slirp/bootp.h @@ -0,0 +1,121 @@ +/* bootp/dhcp defines */ + +#define BOOTP_SERVER 67 +#define BOOTP_CLIENT 68 + +#define BOOTP_REQUEST 1 +#define BOOTP_REPLY 2 + +#define RFC1533_COOKIE 99, 130, 83, 99 +#define RFC1533_PAD 0 +#define RFC1533_NETMASK 1 +#define RFC1533_TIMEOFFSET 2 +#define RFC1533_GATEWAY 3 +#define RFC1533_TIMESERVER 4 +#define RFC1533_IEN116NS 5 +#define RFC1533_DNS 6 +#define RFC1533_LOGSERVER 7 +#define RFC1533_COOKIESERVER 8 +#define RFC1533_LPRSERVER 9 +#define RFC1533_IMPRESSSERVER 10 +#define RFC1533_RESOURCESERVER 11 +#define RFC1533_HOSTNAME 12 +#define RFC1533_BOOTFILESIZE 13 +#define RFC1533_MERITDUMPFILE 14 +#define RFC1533_DOMAINNAME 15 +#define RFC1533_SWAPSERVER 16 +#define RFC1533_ROOTPATH 17 +#define RFC1533_EXTENSIONPATH 18 +#define RFC1533_IPFORWARDING 19 +#define RFC1533_IPSOURCEROUTING 20 +#define RFC1533_IPPOLICYFILTER 21 +#define RFC1533_IPMAXREASSEMBLY 22 +#define RFC1533_IPTTL 23 +#define RFC1533_IPMTU 24 +#define RFC1533_IPMTUPLATEAU 25 +#define RFC1533_INTMTU 26 +#define RFC1533_INTLOCALSUBNETS 27 +#define RFC1533_INTBROADCAST 28 +#define RFC1533_INTICMPDISCOVER 29 +#define RFC1533_INTICMPRESPOND 30 +#define RFC1533_INTROUTEDISCOVER 31 +#define RFC1533_INTROUTESOLICIT 32 +#define RFC1533_INTSTATICROUTES 33 +#define RFC1533_LLTRAILERENCAP 34 +#define RFC1533_LLARPCACHETMO 35 +#define RFC1533_LLETHERNETENCAP 36 +#define RFC1533_TCPTTL 37 +#define RFC1533_TCPKEEPALIVETMO 38 +#define RFC1533_TCPKEEPALIVEGB 39 +#define RFC1533_NISDOMAIN 40 +#define RFC1533_NISSERVER 41 +#define RFC1533_NTPSERVER 42 +#define RFC1533_VENDOR 43 +#define RFC1533_NBNS 44 +#define RFC1533_NBDD 45 +#define RFC1533_NBNT 46 +#define RFC1533_NBSCOPE 47 +#define RFC1533_XFS 48 +#define RFC1533_XDM 49 + +#define RFC2132_REQ_ADDR 50 +#define RFC2132_LEASE_TIME 51 +#define RFC2132_MSG_TYPE 53 +#define RFC2132_SRV_ID 54 +#define RFC2132_PARAM_LIST 55 +#define RFC2132_MAX_SIZE 57 +#define RFC2132_RENEWAL_TIME 58 +#define RFC2132_REBIND_TIME 59 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPACK 5 + +#define RFC1533_VENDOR_MAJOR 0 +#define RFC1533_VENDOR_MINOR 0 + +#define RFC1533_VENDOR_MAGIC 128 +#define RFC1533_VENDOR_ADDPARM 129 +#define RFC1533_VENDOR_ETHDEV 130 +#define RFC1533_VENDOR_HOWTO 132 +#define RFC1533_VENDOR_MNUOPTS 160 +#define RFC1533_VENDOR_SELECTION 176 +#define RFC1533_VENDOR_MOTD 184 +#define RFC1533_VENDOR_NUMOFMOTD 8 +#define RFC1533_VENDOR_IMG 192 +#define RFC1533_VENDOR_NUMOFIMG 16 + +#define RFC1533_END 255 +#define BOOTP_VENDOR_LEN 64 +#define DHCP_OPT_LEN 312 + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct bootp_t { + struct ip ip; + struct udphdr udp; + uint8_t bp_op; + uint8_t bp_htype; + uint8_t bp_hlen; + uint8_t bp_hops; + uint32_t bp_xid; + uint16_t bp_secs; + uint16_t unused; + struct in_addr bp_ciaddr; + struct in_addr bp_yiaddr; + struct in_addr bp_siaddr; + struct in_addr bp_giaddr; + uint8_t bp_hwaddr[16]; + uint8_t bp_sname[64]; + uint8_t bp_file[128]; + uint8_t bp_vend[DHCP_OPT_LEN]; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) +#endif + +void bootp_input(struct SLIRPmbuf *m); diff --git a/src/slirp/cksum.c b/src/slirp/cksum.c new file mode 100644 index 0000000..eeccb88 --- /dev/null +++ b/src/slirp/cksum.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1988, 1992, 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. + * + * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 + * in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp + */ + +#include "slirp.h" + +/* + * Checksum routine for Internet Protocol family headers (Portable Version). + * + * This routine is very heavily used in the network + * code and should be modified for each CPU to be as fast as possible. + * + * XXX Since we will never span more than 1 SLIRPmbuf, we can optimise this + */ + +#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) +#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} + +int cksum(struct SLIRPmbuf *m, int len) +{ + register u_int16_t *w; + register int sum = 0; + register int mlen = 0; + int byte_swapped = 0; + + union { + u_int8_t c[2]; + u_int16_t s; + } s_util; + union { + u_int16_t s[2]; + u_int32_t l; + } l_util; + + if (m->m_len == 0) + goto cont; + w = mtod(m, u_int16_t *); + + mlen = m->m_len; + + if (len < mlen) + mlen = len; + len -= mlen; + /* + * Force to even boundary. + */ + if ((1 & (long) w) && (mlen > 0)) { + REDUCE; + sum <<= 8; + s_util.c[0] = *(u_int8_t *)w; + w = (u_int16_t *)((int8_t *)w + 1); + mlen--; + byte_swapped = 1; + } + /* + * Unroll the loop to make overhead from + * branches &c small. + */ + while ((mlen -= 32) >= 0) { + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7]; + sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11]; + sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15]; + w += 16; + } + mlen += 32; + while ((mlen -= 8) >= 0) { + sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; + w += 4; + } + mlen += 8; + if (mlen == 0 && byte_swapped == 0) + goto cont; + REDUCE; + while ((mlen -= 2) >= 0) { + sum += *w++; + } + + if (byte_swapped) { + REDUCE; + sum <<= 8; + byte_swapped = 0; + if (mlen == -1) { + s_util.c[1] = *(u_int8_t *)w; + sum += s_util.s; + mlen = 0; + } else + + mlen = -1; + } else if (mlen == -1) + s_util.c[0] = *(u_int8_t *)w; + +cont: +#ifdef SLIRP_DEBUG + if (len) { + DEBUG_ERROR((dfd, "cksum: out of data\n")); + DEBUG_ERROR((dfd, " len = %d\n", len)); + } +#endif + if (mlen == -1) { + /* The last SLIRPmbuf has odd # of bytes. Follow the + standard (the odd byte may be shifted left by 8 bits + or not as determined by endian-ness of the machine) */ + s_util.c[1] = 0; + sum += s_util.s; + } + REDUCE; + return (~sum & 0xffff); +} diff --git a/src/slirp/config-host.h b/src/slirp/config-host.h new file mode 100644 index 0000000..90e7dd3 --- /dev/null +++ b/src/slirp/config-host.h @@ -0,0 +1,9 @@ +/* Automatically generated by configure - do not modify */ +#define CONFIG_QEMU_SHAREDIR "/c/Program Files/Qemu" +#define HOST_I386 1 +#define HOST_LONG_BITS 32 +#define CONFIG_WIN32 1 +#define CONFIG_GDBSTUB 1 +#define CONFIG_SLIRP 1 +#define QEMU_VERSION "0.9.0" +#define CONFIG_UNAME_RELEASE "" diff --git a/src/slirp/config.h b/src/slirp/config.h new file mode 100644 index 0000000..09047ab --- /dev/null +++ b/src/slirp/config.h @@ -0,0 +1,9 @@ +/* Automatically generated by configure - do not modify */ +#include "config-host.h" +#define CONFIG_QEMU_PREFIX "/usr/gnemul/qemu-i386" +#define TARGET_ARCH "i386" +#define TARGET_I386 1 +#define USE_KQEMU 1 +#define CONFIG_SOFTMMU 1 +#define CONFIG_SDL 1 +#define HAVE_STRDUP 1 diff --git a/src/slirp/ctl.h b/src/slirp/ctl.h new file mode 100644 index 0000000..efac7cb --- /dev/null +++ b/src/slirp/ctl.h @@ -0,0 +1,7 @@ +#define CTL_CMD 0 +#define CTL_EXEC 1 +#define CTL_ALIAS 2 +#define CTL_DNS 3 + +#define CTL_SPECIAL "10.0.2.0" +#define CTL_LOCAL "10.0.2.15" diff --git a/src/slirp/debug.c b/src/slirp/debug.c new file mode 100644 index 0000000..f6f244b --- /dev/null +++ b/src/slirp/debug.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * Portions copyright (c) 2000 Kelly Price. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include "slirp.h" + +FILE *dfd = NULL; +#ifdef SLIRP_DEBUG +int dostats = 1; +#else +int dostats = 0; +#endif +int slirp_debug = 0; + +extern char *strerror _P((int)); + +/* Carry over one item from main.c so that the tty's restored. + * Only done when the tty being used is /dev/tty --RedWolf */ +extern struct termios slirp_tty_settings; +extern int slirp_tty_restore; + + +void +debug_init(file, dbg) + char *file; + int dbg; +{ + /* Close the old debugging file */ + if (dfd) + fclose(dfd); + + dfd = fopen(file,"w"); + if (dfd != NULL) { +#if 1 + fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION); +#endif + fprintf(dfd,"Debugging Started level %i.\r\n",dbg); + fflush(dfd); + slirp_debug = dbg; + } else { + lprint("Error: Debugging file \"%s\" could not be opened: %s\r\n", + file, strerror(errno)); + } +} + +/* + * Dump a packet in the same format as tcpdump -x + */ +#ifdef SLIRP_DEBUG +void +dump_packet(dat, n) + void *dat; + int n; +{ + u_char *pptr = (u_char *)dat; + int j,k; + + n /= 16; + n++; + DEBUG_MISC((dfd, "PACKET DUMPED: \n")); + for(j = 0; j < n; j++) { + for(k = 0; k < 6; k++) + DEBUG_MISC((dfd, "%02x ", *pptr++)); + DEBUG_MISC((dfd, "\n")); + fflush(dfd); + } +} +#endif + +#if 0 +/* + * Statistic routines + * + * These will print statistics to the screen, the debug file (dfd), or + * a buffer, depending on "type", so that the stats can be sent over + * the link as well. + */ + +void +ttystats(ttyp) + struct ttys *ttyp; +{ + struct slirp_ifstats *is = &ttyp->ifstats; + char buff[512]; + + lprint(" \r\n"); + + if (if_comp & IF_COMPRESS) + strcpy(buff, "on"); + else if (if_comp & IF_NOCOMPRESS) + strcpy(buff, "off"); + else + strcpy(buff, "off (for now)"); + lprint("Unit %d:\r\n", ttyp->unit); + lprint(" using %s encapsulation (VJ compression is %s)\r\n", ( +#ifdef USE_PPP + ttyp->proto==PROTO_PPP?"PPP": +#endif + "SLIP"), buff); + lprint(" %d baudrate\r\n", ttyp->baud); + lprint(" interface is %s\r\n", ttyp->up?"up":"down"); + lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid); +#ifndef FULL_BOLT + lprint(" towrite is %d bytes\r\n", ttyp->towrite); +#endif + if (ttyp->zeros) + lprint(" %d zeros have been typed\r\n", ttyp->zeros); + else if (ttyp->ones) + lprint(" %d ones have been typed\r\n", ttyp->ones); + lprint("Interface stats:\r\n"); + lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes); + lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes); + lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes); + lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes); + lprint(" %6d bad input packets\r\n", is->in_mbad); +} + +void +allttystats() +{ + struct ttys *ttyp; + + for (ttyp = ttys; ttyp; ttyp = ttyp->next) + ttystats(ttyp); +} +#endif + +void +ipstats() +{ + lprint(" \r\n"); + + lprint("IP stats:\r\n"); + lprint(" %6d total packets received (%d were unaligned)\r\n", + ipstat.ips_total, ipstat.ips_unaligned); + lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers); + lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum); + lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort); + lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall); + lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen); + lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen); + lprint(" %6d fragments received\r\n", ipstat.ips_fragments); + lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped); + lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout); + lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled); + lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented); + lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments); + lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto); + lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered); +} + +#if 0 +void +vjstats() +{ + lprint(" \r\n"); + + lprint("VJ compression stats:\r\n"); + + lprint(" %6d outbound packets (%d compressed)\r\n", + comp_s.sls_packets, comp_s.sls_compressed); + lprint(" %6d searches for connection stats (%d misses)\r\n", + comp_s.sls_searches, comp_s.sls_misses); + lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin); + lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin); + lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin); + lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed); +} +#endif + +void +tcpstats() +{ + lprint(" \r\n"); + + lprint("TCP stats:\r\n"); + + lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal); + lprint(" %6d data packets (%d bytes)\r\n", + tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte); + lprint(" %6d data packets retransmitted (%d bytes)\r\n", + tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte); + lprint(" %6d ack-only packets (%d delayed)\r\n", + tcpstat.tcps_sndacks, tcpstat.tcps_delack); + lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg); + lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe); + lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup); + lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl); + lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin); + + lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal); + lprint(" %6d acks (for %d bytes)\r\n", + tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte); + lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack); + lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch); + lprint(" %6d packets received in sequence (%d bytes)\r\n", + tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte); + lprint(" %6d completely duplicate packets (%d bytes)\r\n", + tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte); + + lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n", + tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte); + lprint(" %6d out-of-order packets (%d bytes)\r\n", + tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte); + lprint(" %6d packets of data after window (%d bytes)\r\n", + tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin); + lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe); + lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd); + lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose); + lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum); + lprint(" %6d discarded for bad header offset fields\r\n", + tcpstat.tcps_rcvbadoff); + + lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt); + lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts); + lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects); + lprint(" %6d connections closed (including %d drop)\r\n", + tcpstat.tcps_closed, tcpstat.tcps_drops); + lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops); + lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n", + tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated); + lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo); + lprint(" %6d connections dropped by rxmt timeout\r\n", + tcpstat.tcps_timeoutdrop); + lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo); + lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo); + lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe); + lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops); + lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack); + lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat); + lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss); + + +/* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */ +/* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */ + +} + +void +udpstats() +{ + lprint(" \r\n"); + + lprint("UDP stats:\r\n"); + lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets); + lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops); + lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum); + lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen); + lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss); + lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets); +} + +void +icmpstats() +{ + lprint(" \r\n"); + lprint("ICMP stats:\r\n"); + lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received); + lprint(" %6d were too short\r\n", icmpstat.icps_tooshort); + lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum); + lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp); + lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype); + lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect); +} + +void +mbufstats() +{ + struct SLIRPmbuf *m; + int i; + + lprint(" \r\n"); + + lprint("Mbuf stats:\r\n"); + + lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max); + + i = 0; + for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next) + i++; + lprint(" %6d mbufs on free list\r\n", i); + + i = 0; + for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) + i++; + lprint(" %6d mbufs on used list\r\n", i); + lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); +} + + +void sockstats(void) +{ + char buff[256]; + int n; + struct SLIRPsocket *so; + + lprint(" \r\n"); + + lprint( + "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); + + for (so = tcb.so_next; so != &tcb; so = so->so_next) { + + n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); + while (n < 17) + buff[n++] = ' '; + buff[17] = 0; + lprint("%s %3d %15s %5d ", + buff, so->s, + inet_ntoa(so->so_laddr), ntohs(so->so_lport)); + lprint("%15s %5d %5d %5d\r\n", + inet_ntoa(so->so_faddr), ntohs(so->so_fport), + so->so_rcv.sb_cc, so->so_snd.sb_cc); + + } + + for (so = udb.so_next; so != &udb; so = so->so_next) { + + n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); + while (n < 17) + buff[n++] = ' '; + buff[17] = 0; + lprint("%s %3d %15s %5d ", + buff, so->s, + inet_ntoa(so->so_laddr), ntohs(so->so_lport)); + lprint("%15s %5d %5d %5d\r\n", + inet_ntoa(so->so_faddr), ntohs(so->so_fport), + so->so_rcv.sb_cc, so->so_snd.sb_cc); + } +} + + + +void printf_sockstats(void) +{ + char buff[256]; + int n; + struct SLIRPsocket *so; + + printf(" \r\n"); + + printf( + "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n"); + + for (so = tcb.so_next; so != &tcb; so = so->so_next) { + + n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE"); + while (n < 17) + buff[n++] = ' '; + buff[17] = 0; + printf("%s %3d %15s %5d ", + buff, so->s, + inet_ntoa(so->so_laddr), ntohs(so->so_lport)); + printf("%15s %5d %5d %5d\r\n", + inet_ntoa(so->so_faddr), ntohs(so->so_fport), + so->so_rcv.sb_cc, so->so_snd.sb_cc); + + } + + for (so = udb.so_next; so != &udb; so = so->so_next) { + + n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000); + while (n < 17) + buff[n++] = ' '; + buff[17] = 0; + printf("%s %3d %15s %5d ", + buff, so->s, + inet_ntoa(so->so_laddr), ntohs(so->so_lport)); + printf("%15s %5d %5d %5d\r\n", + inet_ntoa(so->so_faddr), ntohs(so->so_fport), + so->so_rcv.sb_cc, so->so_snd.sb_cc); + } +printf("\n\n"); +} + +//Simple code to purge and close open sockets. +//This way we can open/close/open/close.. +void purgesocks(void) +{ + struct SLIRPsocket *so; + + for (so = tcb.so_next; so != &tcb; so = so->so_next) { + + closesocket(so->s); //close the socket + } +} + +#if 1 +void +slirp_exit(exit_status) + int exit_status; +{ +// struct ttys *ttyp; + + DEBUG_CALL("slirp_exit"); + DEBUG_ARG("exit_status = %d", exit_status); + + if (dostats) { + lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf; + if (!dfd) + debug_init("slirp_stats", 0xf); + lprint_arg = (char **)&dfd; + + ipstats(); + tcpstats(); + udpstats(); + icmpstats(); + mbufstats(); + sockstats(); + fclose(dfd); +// allttystats(); +// vjstats(); + } + +// for (ttyp = ttys; ttyp; ttyp = ttyp->next) +// tty_detached(ttyp, 1); + +// if (slirp_forked) { +// /* Menendez time */ +// if (kill(getppid(), SIGQUIT) < 0) +// lprint("Couldn't kill parent process %ld!\n", +// (long) getppid()); +// } + + /* Restore the terminal if we gotta */ +// if(slirp_tty_restore) +// tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */ +// exit(exit_status); + + //This will iterate though the sockets, and close them all (think redirects) + //PCem will have SLiRP open, close several times, which trips up SLiRP + //So for now I go through the sockets and close them + purgesocks(); + +} +#endif diff --git a/src/slirp/debug.h b/src/slirp/debug.h new file mode 100644 index 0000000..7b96c1a --- /dev/null +++ b/src/slirp/debug.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#define PRN_STDERR 1 +#define PRN_SPRINTF 2 + +extern FILE *dfd; +extern FILE *lfd; +extern int dostats; +extern int slirp_debug; + +#define DBG_CALL 0x1 +#define DBG_MISC 0x2 +#define DBG_ERROR 0x4 +#define DEBUG_DEFAULT DBG_CALL|DBG_MISC|DBG_ERROR + +#ifdef SLIRP_DEBUG +#define DEBUG_CALL(x) if (slirp_debug & DBG_CALL) { fprintf(dfd, "%s...\n", x); fflush(dfd); } +#define DEBUG_ARG(x, y) if (slirp_debug & DBG_CALL) { fputc(' ', dfd); fprintf(dfd, x, y); fputc('\n', dfd); fflush(dfd); } +#define DEBUG_ARGS(x) if (slirp_debug & DBG_CALL) { fprintf x ; fflush(dfd); } +#define DEBUG_MISC(x) if (slirp_debug & DBG_MISC) { fprintf x ; fflush(dfd); } +#define DEBUG_ERROR(x) if (slirp_debug & DBG_ERROR) {fprintf x ; fflush(dfd); } + + +#else + +#define DEBUG_CALL(x) +#define DEBUG_ARG(x, y) +#define DEBUG_ARGS(x) +#define DEBUG_MISC(x) +#define DEBUG_ERROR(x) + +#endif + +void debug_init _P((char *, int)); +//void ttystats _P((struct ttys *)); +void allttystats _P((void)); +void ipstats _P((void)); +void vjstats _P((void)); +void tcpstats _P((void)); +void udpstats _P((void)); +void icmpstats _P((void)); +void mbufstats _P((void)); +void sockstats _P((void)); +void slirp_exit _P((int)); + diff --git a/src/slirp/icmp_var.h b/src/slirp/icmp_var.h new file mode 100644 index 0000000..8bacc63 --- /dev/null +++ b/src/slirp/icmp_var.h @@ -0,0 +1,65 @@ +/* + * 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. + * + * @(#)icmp_var.h 8.1 (Berkeley) 6/10/93 + * icmp_var.h,v 1.4 1995/02/16 00:27:40 wollman Exp + */ + +#ifndef _NETINET_ICMP_VAR_H_ +#define _NETINET_ICMP_VAR_H_ + +/* + * Variables related to this implementation + * of the internet control message protocol. + */ +struct icmpstat { +/* statistics related to input messages processed */ + u_long icps_received; /* #ICMP packets received */ + u_long icps_tooshort; /* packet < ICMP_MINLEN */ + u_long icps_checksum; /* bad checksum */ + u_long icps_notsupp; /* #ICMP packets not supported */ + u_long icps_badtype; /* #with bad type feild */ + u_long icps_reflect; /* number of responses */ +}; + +/* + * Names for ICMP sysctl objects + */ +#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ +#define ICMPCTL_STATS 2 /* statistics (read-only) */ +#define ICMPCTL_MAXID 3 + +#define ICMPCTL_NAMES { \ + { 0, 0 }, \ + { "maskrepl", CTLTYPE_INT }, \ + { "stats", CTLTYPE_STRUCT }, \ +} + +extern struct icmpstat icmpstat; + +#endif diff --git a/src/slirp/if.c b/src/slirp/if.c new file mode 100644 index 0000000..aa0cea9 --- /dev/null +++ b/src/slirp/if.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include "slirp.h" + +int if_mtu, if_mru; +int if_comp; +int if_maxlinkhdr; +int if_queued = 0; /* Number of packets queued so far */ +int if_thresh = 10; /* Number of packets queued before we start sending + * (to prevent allocing too many SLIRPmbufs) */ + +struct SLIRPmbuf if_fastq; /* fast queue (for interactive data) */ +struct SLIRPmbuf if_batchq; /* queue for non-interactive data */ +struct SLIRPmbuf *next_m; /* Pointer to next SLIRPmbuf to output */ + +#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) + +void +ifs_insque(ifm, ifmhead) + struct SLIRPmbuf *ifm, *ifmhead; +{ + ifm->ifs_next = ifmhead->ifs_next; + ifmhead->ifs_next = ifm; + ifm->ifs_prev = ifmhead; + ifm->ifs_next->ifs_prev = ifm; +} + +void +ifs_remque(ifm) + struct SLIRPmbuf *ifm; +{ + ifm->ifs_prev->ifs_next = ifm->ifs_next; + ifm->ifs_next->ifs_prev = ifm->ifs_prev; +} + +void +if_init() +{ +#if 0 + /* + * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, + * and 8 bytes for PPP, but need to have it on an 8byte boundary + */ +#ifdef USE_PPP + if_maxlinkhdr = 48; +#else + if_maxlinkhdr = 40; +#endif +#else + /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ + if_maxlinkhdr = 2 + 14 + 40; +#endif + if_mtu = 1500; + if_mru = 1500; + if_comp = IF_AUTOCOMP; + if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; + if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; + // sl_compress_init(&comp_s); + next_m = &if_batchq; +} + +#if 0 +/* + * This shouldn't be needed since the modem is blocking and + * we don't expect any signals, but what the hell.. + */ +inline int +writen(fd, bptr, n) + int fd; + char *bptr; + int n; +{ + int ret; + int total; + + /* This should succeed most of the time */ + ret = send(fd, bptr, n,0); + if (ret == n || ret <= 0) + return ret; + + /* Didn't write everything, go into the loop */ + total = ret; + while (n > total) { + ret = send(fd, bptr+total, n-total,0); + if (ret <= 0) + return ret; + total += ret; + } + return total; +} + +/* + * if_input - read() the tty, do "top level" processing (ie: check for any escapes), + * and pass onto (*ttyp->if_input) + * + * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. + */ +#define INBUFF_SIZE 2048 /* XXX */ +void +if_input(ttyp) + struct ttys *ttyp; +{ + u_char if_inbuff[INBUFF_SIZE]; + int if_n; + + DEBUG_CALL("if_input"); + DEBUG_ARG("ttyp = %lx", (long)ttyp); + + if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); + + DEBUG_MISC((dfd, " read %d bytes\n", if_n)); + + if (if_n <= 0) { + if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { + if (ttyp->up) + link_up--; + tty_detached(ttyp, 0); + } + return; + } + if (if_n == 1) { + if (*if_inbuff == '0') { + ttyp->ones = 0; + if (++ttyp->zeros >= 5) + slirp_exit(0); + return; + } + if (*if_inbuff == '1') { + ttyp->zeros = 0; + if (++ttyp->ones >= 5) + tty_detached(ttyp, 0); + return; + } + } + ttyp->ones = ttyp->zeros = 0; + + (*ttyp->if_input)(ttyp, if_inbuff, if_n); +} +#endif + +/* + * if_output: Queue packet into an output queue. + * There are 2 output queue's, if_fastq and if_batchq. + * Each output queue is a doubly linked list of double linked lists + * of SLIRPmbufs, each list belonging to one "session" (socket). This + * way, we can output packets fairly by sending one packet from each + * session, instead of all the packets from one session, then all packets + * from the next session, etc. Packets on the if_fastq get absolute + * priority, but if one session hogs the link, it gets "downgraded" + * to the batchq until it runs out of packets, then it'll return + * to the fastq (eg. if the user does an ls -alR in a telnet session, + * it'll temporarily get downgraded to the batchq) + */ +void +if_output(so, ifm) + struct SLIRPsocket *so; + struct SLIRPmbuf *ifm; +{ + struct SLIRPmbuf *ifq; + int on_fastq = 1; + + DEBUG_CALL("if_output"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("ifm = %lx", (long)ifm); + + /* + * First remove the SLIRPmbuf from m_usedlist, + * since we're gonna use m_next and m_prev ourselves + * XXX Shouldn't need this, gotta change dtom() etc. + */ + if (ifm->m_flags & M_USEDLIST) { + remque(ifm); + ifm->m_flags &= ~M_USEDLIST; + } + + /* + * See if there's already a batchq list for this session. + * This can include an interactive session, which should go on fastq, + * but gets too greedy... hence it'll be downgraded from fastq to batchq. + * We mustn't put this packet back on the fastq (or we'll send it out of order) + * XXX add cache here? + */ + for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { + if (so == ifq->ifq_so) { + /* A match! */ + ifm->ifq_so = so; + ifs_insque(ifm, ifq->ifs_prev); + goto diddit; + } + } + + /* No match, check which queue to put it on */ + if (so && (so->so_iptos & IPTOS_LOWDELAY)) { + ifq = if_fastq.ifq_prev; + on_fastq = 1; + /* + * Check if this packet is a part of the last + * packet's session + */ + if (ifq->ifq_so == so) { + ifm->ifq_so = so; + ifs_insque(ifm, ifq->ifs_prev); + goto diddit; + } + } else + ifq = if_batchq.ifq_prev; + + /* Create a new doubly linked list for this session */ + ifm->ifq_so = so; + ifs_init(ifm); + insque(ifm, ifq); + +diddit: + ++if_queued; + + if (so) { + /* Update *_queued */ + so->so_queued++; + so->so_nqueued++; + /* + * Check if the interactive session should be downgraded to + * the batchq. A session is downgraded if it has queued 6 + * packets without pausing, and at least 3 of those packets + * have been sent over the link + * (XXX These are arbitrary numbers, probably not optimal..) + */ + if (on_fastq && ((so->so_nqueued >= 6) && + (so->so_nqueued - so->so_queued) >= 3)) { + + /* Remove from current queue... */ + remque(ifm->ifs_next); + + /* ...And insert in the new. That'll teach ya! */ + insque(ifm->ifs_next, &if_batchq); + } + } + +#ifndef FULL_BOLT + /* + * This prevents us from malloc()ing too many SLIRPmbufs + */ + if (link_up) { + /* if_start will check towrite */ + if_start(); + } +#endif +} + +/* + * Send a packet + * We choose a packet based on it's position in the output queues; + * If there are packets on the fastq, they are sent FIFO, before + * everything else. Otherwise we choose the first packet from the + * batchq and send it. the next packet chosen will be from the session + * after this one, then the session after that one, and so on.. So, + * for example, if there are 3 ftp session's fighting for bandwidth, + * one packet will be sent from the first session, then one packet + * from the second session, then one packet from the third, then back + * to the first, etc. etc. + */ +void +if_start(void) +{ + struct SLIRPmbuf *ifm, *ifqt; + + DEBUG_CALL("if_start"); + + if (if_queued == 0) + return; /* Nothing to do */ + + again: + /* check if we can really output */ + if (!slirp_can_output()) + return; + + /* + * See which queue to get next packet from + * If there's something in the fastq, select it immediately + */ + if (if_fastq.ifq_next != &if_fastq) { + ifm = if_fastq.ifq_next; + } else { + /* Nothing on fastq, see if next_m is valid */ + if (next_m != &if_batchq) + ifm = next_m; + else + ifm = if_batchq.ifq_next; + + /* Set which packet to send on next iteration */ + next_m = ifm->ifq_next; + } + /* Remove it from the queue */ + ifqt = ifm->ifq_prev; + remque(ifm); + --if_queued; + + /* If there are more packets for this session, re-queue them */ + if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { + insque(ifm->ifs_next, ifqt); + ifs_remque(ifm); + } + + /* Update so_queued */ + if (ifm->ifq_so) { + if (--ifm->ifq_so->so_queued == 0) + /* If there's no more queued, reset nqueued */ + ifm->ifq_so->so_nqueued = 0; + } + + /* Encapsulate the packet for sending */ + if_encap((uint8_t*)ifm->m_data, ifm->m_len); + + m_free(ifm); + + if (if_queued) + goto again; +} diff --git a/src/slirp/if.h b/src/slirp/if.h new file mode 100644 index 0000000..4f39951 --- /dev/null +++ b/src/slirp/if.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#ifndef _IF_H_ +#define _IF_H_ + +#define IF_COMPRESS 0x01 /* We want compression */ +#define IF_NOCOMPRESS 0x02 /* Do not do compression */ +#define IF_AUTOCOMP 0x04 /* Autodetect (default) */ +#define IF_NOCIDCOMP 0x08 /* CID compression */ + +/* Needed for FreeBSD */ +#undef if_mtu +extern int if_mtu; +extern int if_mru; /* MTU and MRU */ +extern int if_comp; /* Flags for compression */ +extern int if_maxlinkhdr; +extern int if_queued; /* Number of packets queued so far */ +extern int if_thresh; /* Number of packets queued before we start sending + * (to prevent allocing too many SLIRPmbufs) */ + +extern struct SLIRPmbuf if_fastq; /* fast queue (for interactive data) */ +extern struct SLIRPmbuf if_batchq; /* queue for non-interactive data */ +extern struct SLIRPmbuf *next_m; + +#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) + +/* Interface statistics */ +struct slirp_ifstats { + u_int out_pkts; /* Output packets */ + u_int out_bytes; /* Output bytes */ + u_int out_errpkts; /* Output Error Packets */ + u_int out_errbytes; /* Output Error Bytes */ + u_int in_pkts; /* Input packets */ + u_int in_bytes; /* Input bytes */ + u_int in_errpkts; /* Input Error Packets */ + u_int in_errbytes; /* Input Error Bytes */ + + u_int bytes_saved; /* Number of bytes that compression "saved" */ + /* ie: number of bytes that didn't need to be sent over the link + * because of compression */ + + u_int in_mbad; /* Bad incoming packets */ +}; + +#endif diff --git a/src/slirp/ip.h b/src/slirp/ip.h new file mode 100644 index 0000000..f7fc59f --- /dev/null +++ b/src/slirp/ip.h @@ -0,0 +1,341 @@ +/* + * 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. + * + * @(#)ip.h 8.1 (Berkeley) 6/10/93 + * ip.h,v 1.3 1994/08/21 05:27:30 paul Exp + */ + +#ifndef _IP_H_ +#define _IP_H_ + +#ifdef WORDS_BIGENDIAN +# ifndef NTOHL +# define NTOHL(d) +# endif +# ifndef NTOHS +# define NTOHS(d) +# endif +# ifndef HTONL +# define HTONL(d) +# endif +# ifndef HTONS +# define HTONS(d) +# endif +#else +# ifndef NTOHL +# define NTOHL(d) ((d) = ntohl((d))) +# endif +# ifndef NTOHS +# define NTOHS(d) ((d) = ntohs((u_int16_t)(d))) +# endif +# ifndef HTONL +# define HTONL(d) ((d) = htonl((d))) +# endif +# ifndef HTONS +# define HTONS(d) ((d) = htons((u_int16_t)(d))) +# endif +#endif + +typedef u_int32_t n_long; /* long as received from the net */ + +/* + * Definitions for internet protocol version 4. + * Per RFC 791, September 1981. + */ +#define IPVERSION 4 + +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif + +/* + * Structure of an internet header, naked of options. + */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct ip { +#ifdef WORDS_BIGENDIAN + u_char ip_v:4, /* version */ + ip_hl:4; /* header length */ +#else + u_char ip_hl:4, /* header length */ + ip_v:4; /* version */ +#endif + u_int8_t ip_tos; /* type of service */ + u_int16_t ip_len; /* total length */ + u_int16_t ip_id; /* identification */ + u_int16_t ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* don't fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_int8_t ip_ttl; /* time to live */ + u_int8_t ip_p; /* protocol */ + u_int16_t ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) //WAS 0 +#endif + +#define IP_MAXPACKET 65535 /* maximum packet size */ + +/* + * Definitions for IP type of service (ip_tos) + */ +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 + +/* + * Definitions for options. + */ +#define IPOPT_COPIED(o) ((o)&0x80) +#define IPOPT_CLASS(o) ((o)&0x60) +#define IPOPT_NUMBER(o) ((o)&0x1f) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_DEBMEAS 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_EOL 0 /* end of option list */ +#define IPOPT_NOP 1 /* no operation */ + +#define IPOPT_RR 7 /* record packet route */ +#define IPOPT_TS 68 /* timestamp */ +#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ +#define IPOPT_LSRR 131 /* loose source route */ +#define IPOPT_SATID 136 /* satnet id */ +#define IPOPT_SSRR 137 /* strict source route */ + +/* + * Offsets to fields in options other than EOL and NOP. + */ +#define IPOPT_OPTVAL 0 /* option ID */ +#define IPOPT_OLEN 1 /* option length */ +#define IPOPT_OFFSET 2 /* offset within option */ +#define IPOPT_MINOFF 4 /* min value of above */ + +/* + * Time stamp option structure. + */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct ip_timestamp { + u_int8_t ipt_code; /* IPOPT_TS */ + u_int8_t ipt_len; /* size of structure (variable) */ + u_int8_t ipt_ptr; /* index of current entry */ +#ifdef WORDS_BIGENDIAN + u_char ipt_oflw:4, /* overflow counter */ + ipt_flg:4; /* flags, see below */ +#else + u_char ipt_flg:4, /* flags, see below */ + ipt_oflw:4; /* overflow counter */ +#endif + union ipt_timestamp { + n_long ipt_time[1]; + struct ipt_ta { + struct in_addr ipt_addr; + n_long ipt_time; + } ipt_ta[1]; + } ipt_timestamp; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) +#endif + +/* flag bits for ipt_flg */ +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +/* bits for security (not byte swapped) */ +#define IPOPT_SECUR_UNCLASS 0x0000 +#define IPOPT_SECUR_CONFID 0xf135 +#define IPOPT_SECUR_EFTO 0x789a +#define IPOPT_SECUR_MMMM 0xbc4d +#define IPOPT_SECUR_RESTR 0xaf13 +#define IPOPT_SECUR_SECRET 0xd788 +#define IPOPT_SECUR_TOPSECRET 0x6bc5 + +/* + * Internet implementation parameters. + */ +#define MAXTTL 255 /* maximum time to live (seconds) */ +#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ +#define IPFRAGTTL 60 /* time to live for frags, slowhz */ +#define IPTTLDEC 1 /* subtracted when forwarding */ + +#define IP_MSS 576 /* default maximum segment size */ + +#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ +#include +#else +#if SIZEOF_CHAR_P == 4 +typedef SLIRPcaddr_t caddr32_t; +#else +typedef u_int32_t caddr32_t; +#endif +#endif + +#if SIZEOF_CHAR_P == 4 +typedef struct ipq *ipqp_32; +typedef struct ipasfrag *ipasfragp_32; +#else +typedef caddr32_t ipqp_32; +typedef caddr32_t ipasfragp_32; +#endif + +/* + * Overlay for ip header used by other protocols (tcp, udp). + */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct ipovly { + caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ + u_int8_t ih_x1; /* (unused) */ + u_int8_t ih_pr; /* protocol */ + u_int16_t ih_len; /* protocol length */ + struct in_addr ih_src; /* source internet address */ + struct in_addr ih_dst; /* destination internet address */ +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) +#endif + +#if defined(_MSC_VER) +#pragma pack(pop) +#endif + +/* + * Ip reassembly queue structure. Each fragment + * being reassembled is attached to one of these structures. + * They are timed out after ipq_ttl drops to 0, and may also + * be reclaimed if memory becomes tight. + * size 28 bytes + */ +struct ipq { + ipqp_32 next,prev; /* to other reass headers */ + u_int8_t ipq_ttl; /* time for reass q to live */ + u_int8_t ipq_p; /* protocol of this fragment */ + u_int16_t ipq_id; /* sequence id for reassembly */ + ipasfragp_32 ipq_next,ipq_prev; + /* to ip headers of fragments */ + struct in_addr ipq_src,ipq_dst; +}; + +/* + * Ip header, when holding a fragment. + * + * Note: ipf_next must be at same offset as ipq_next above + */ +struct ipasfrag { +#ifdef WORDS_BIGENDIAN + u_char ip_v:4, + ip_hl:4; +#else + u_char ip_hl:4, + ip_v:4; +#endif + /* BUG : u_int changed to u_int8_t. + * sizeof(u_int)==4 on linux 2.0 + */ + u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit + * to avoid destroying tos (PPPDTRuu); + * copied from (ip_off&IP_MF) */ + u_int16_t ip_len; + u_int16_t ip_id; + u_int16_t ip_off; + u_int8_t ip_ttl; + u_int8_t ip_p; + u_int16_t ip_sum; + ipasfragp_32 ipf_next; /* next fragment */ + ipasfragp_32 ipf_prev; /* previous fragment */ +}; + +/* + * Structure stored in mbuf in inpcb.ip_options + * and passed to ip_output when ip options are in use. + * The actual length of the options (including ipopt_dst) + * is in m_len. + */ +#define MAX_IPOPTLEN 40 + +struct ipoption { + struct in_addr ipopt_dst; /* first-hop dst if source routed */ + int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ +}; + +/* + * Structure attached to inpcb.ip_moptions and + * passed to ip_output when IP multicast options are in use. + */ + +struct ipstat { + u_long ips_total; /* total packets received */ + u_long ips_badsum; /* checksum bad */ + u_long ips_tooshort; /* packet too short */ + u_long ips_toosmall; /* not enough data */ + u_long ips_badhlen; /* ip header length < data size */ + u_long ips_badlen; /* ip length < ip header length */ + u_long ips_fragments; /* fragments received */ + u_long ips_fragdropped; /* frags dropped (dups, out of space) */ + u_long ips_fragtimeout; /* fragments timed out */ + u_long ips_forward; /* packets forwarded */ + u_long ips_cantforward; /* packets rcvd for unreachable dest */ + u_long ips_redirectsent; /* packets forwarded on same net */ + u_long ips_noproto; /* unknown or unsupported protocol */ + u_long ips_delivered; /* datagrams delivered to upper level*/ + u_long ips_localout; /* total ip packets generated here */ + u_long ips_odropped; /* lost packets due to nobufs, etc. */ + u_long ips_reassembled; /* total packets reassembled ok */ + u_long ips_fragmented; /* datagrams successfully fragmented */ + u_long ips_ofragments; /* output fragments created */ + u_long ips_cantfrag; /* don't fragment flag was set, etc. */ + u_long ips_badoptions; /* error in option processing */ + u_long ips_noroute; /* packets discarded due to no route */ + u_long ips_badvers; /* ip version != 4 */ + u_long ips_rawout; /* total raw ip packets generated */ + u_long ips_unaligned; /* times the ip packet was not aligned */ +}; + +extern struct ipstat ipstat; +extern struct ipq ipq; /* ip reass. queue */ +extern u_int16_t ip_id; /* ip packet ctr, for ids */ +extern int ip_defttl; /* default IP ttl */ + +#endif diff --git a/src/slirp/ip_icmp.c b/src/slirp/ip_icmp.c new file mode 100644 index 0000000..396293d --- /dev/null +++ b/src/slirp/ip_icmp.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 1982, 1986, 1988, 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. + * + * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 + * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp + */ + +#include "slirp.h" +#include "ip_icmp.h" + +struct icmpstat icmpstat; + +/* The message sent when emulating PING */ +/* Be nice and tell them it's just a psuedo-ping packet */ +char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST packets.\n"; + +/* list of actions for icmp_error() on RX of an icmp message */ +static int icmp_flush[19] = { +/* ECHO REPLY (0) */ 0, + 1, + 1, +/* DEST UNREACH (3) */ 1, +/* SOURCE QUENCH (4)*/ 1, +/* REDIRECT (5) */ 1, + 1, + 1, +/* ECHO (8) */ 0, +/* ROUTERADVERT (9) */ 1, +/* ROUTERSOLICIT (10) */ 1, +/* TIME EXCEEDED (11) */ 1, +/* PARAMETER PROBLEM (12) */ 1, +/* TIMESTAMP (13) */ 0, +/* TIMESTAMP REPLY (14) */ 0, +/* INFO (15) */ 0, +/* INFO REPLY (16) */ 0, +/* ADDR MASK (17) */ 0, +/* ADDR MASK REPLY (18) */ 0 +}; + +/* + * Process a received ICMP message. + */ +void +icmp_input(m, hlen) + struct SLIRPmbuf *m; + int hlen; +{ + register struct icmp *icp; + register struct ip *ip=mtod(m, struct ip *); + int icmplen=ip->ip_len; + /* int code; */ + + DEBUG_CALL("icmp_input"); + DEBUG_ARG("m = %lx", (long )m); + DEBUG_ARG("m_len = %d", m->m_len); + + icmpstat.icps_received++; + + /* + * Locate icmp structure in SLIRPmbuf, and check + * that its not corrupted and of at least minimum length. + */ + if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ + icmpstat.icps_tooshort++; + freeit: + m_freem(m); + goto end_error; + } + + m->m_len -= hlen; + m->m_data += hlen; + icp = mtod(m, struct icmp *); + if (cksum(m, icmplen)) { + icmpstat.icps_checksum++; + goto freeit; + } + m->m_len += hlen; + m->m_data -= hlen; + + /* icmpstat.icps_inhist[icp->icmp_type]++; */ + /* code = icp->icmp_code; */ + + DEBUG_ARG("icmp_type = %d", icp->icmp_type); + switch (icp->icmp_type) { + case ICMP_ECHO: + icp->icmp_type = ICMP_ECHOREPLY; + ip->ip_len += hlen; /* since ip_input subtracts this */ + if (ip->ip_dst.s_addr == alias_addr.s_addr) { + icmp_reflect(m); + } else { + struct SLIRPsocket *so; + struct sockaddr_in addr; + if ((so = socreate()) == NULL) goto freeit; + if(udp_attach(so) == -1) { + DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n", + errno,strerror(errno))); + sofree(so); + m_free(m); + goto end_error; + } + so->so_m = m; + so->so_faddr = ip->ip_dst; + so->so_fport = htons(7); + so->so_laddr = ip->ip_src; + so->so_lport = htons(9); + so->so_iptos = ip->ip_tos; + so->so_type = IPPROTO_ICMP; + so->so_state = SS_ISFCONNECTED; + + /* Send the packet */ + addr.sin_family = AF_INET; + if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + /* It's an alias */ + switch(ntohl(so->so_faddr.s_addr) & 0xff) { + case CTL_DNS: + addr.sin_addr = dns_addr; + break; + case CTL_ALIAS: + default: + addr.sin_addr = loopback_addr; + break; + } + } else { + addr.sin_addr = so->so_faddr; + } + addr.sin_port = so->so_fport; + if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0, + (struct sockaddr *)&addr, sizeof(addr)) == -1) { + DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n", + errno,strerror(errno))); + icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); + udp_detach(so); + } + } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ + break; + case ICMP_UNREACH: + /* XXX? report error? close socket? */ + case ICMP_TIMXCEED: + case ICMP_PARAMPROB: + case ICMP_SOURCEQUENCH: + case ICMP_TSTAMP: + case ICMP_MASKREQ: + case ICMP_REDIRECT: + icmpstat.icps_notsupp++; + m_freem(m); + break; + + default: + icmpstat.icps_badtype++; + m_freem(m); + } /* swith */ + +end_error: + /* m is m_free()'d xor put in a socket xor or given to ip_send */ + return; +} + + +/* + * Send an ICMP message in response to a situation + * + * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. MAY send more (we do). + * MUST NOT change this header information. + * MUST NOT reply to a multicast/broadcast IP address. + * MUST NOT reply to a multicast/broadcast MAC address. + * MUST reply to only the first fragment. + */ +/* + * Send ICMP_UNREACH back to the source regarding msrc. + * SLIRPmbuf *msrc is used as a template, but is NOT m_free()'d. + * It is reported as the bad ip packet. The header should + * be fully correct and in host byte order. + * ICMP fragmentation is illegal. All machines must accept 576 bytes in one + * packet. The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548 + */ + +#define ICMP_MAXDATALEN (IP_MSS-28) +void +icmp_error(msrc, type, code, minsize, message) + struct SLIRPmbuf *msrc; + u_char type; + u_char code; + int minsize; + char *message; +{ + unsigned hlen, shlen, s_ip_len; + register struct ip *ip; + register struct icmp *icp; + register struct SLIRPmbuf *m; + + DEBUG_CALL("icmp_error"); + DEBUG_ARG("msrc = %lx", (long )msrc); + DEBUG_ARG("msrc_len = %d", msrc->m_len); + + if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error; + + /* check msrc */ + if(!msrc) goto end_error; + ip = mtod(msrc, struct ip *); +#if SLIRP_DEBUG + { char bufa[20], bufb[20]; + strcpy(bufa, inet_ntoa(ip->ip_src)); + strcpy(bufb, inet_ntoa(ip->ip_dst)); + DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb)); + } +#endif + if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */ + + shlen=ip->ip_hl << 2; + s_ip_len=ip->ip_len; + if(ip->ip_p == IPPROTO_ICMP) { + icp = (struct icmp *)((char *)ip + shlen); + /* + * Assume any unknown ICMP type is an error. This isn't + * specified by the RFC, but think about it.. + */ + if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error; + } + + /* make a copy */ + if(!(m=m_get())) goto end_error; /* get SLIRPmbuf */ + { u_int new_m_size; + new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN; + if(new_m_size>m->m_size) m_inc(m, new_m_size); + } + memcpy(m->m_data, msrc->m_data, msrc->m_len); + m->m_len = msrc->m_len; /* copy msrc to m */ + + /* make the header of the reply packet */ + ip = mtod(m, struct ip *); + hlen= sizeof(struct ip ); /* no options in reply */ + + /* fill in icmp */ + m->m_data += hlen; + m->m_len -= hlen; + + icp = mtod(m, struct icmp *); + + if(minsize) s_ip_len=shlen+ICMP_MINLEN; /* return header+8b only */ + else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */ + s_ip_len=ICMP_MAXDATALEN; + + m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */ + + /* min. size = 8+sizeof(struct ip)+8 */ + + icp->icmp_type = type; + icp->icmp_code = code; + icp->icmp_id = 0; + icp->icmp_seq = 0; + + memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */ + HTONS(icp->icmp_ip.ip_len); + HTONS(icp->icmp_ip.ip_id); + HTONS(icp->icmp_ip.ip_off); + +#if SLIRP_DEBUG + if(message) { /* DEBUG : append message to ICMP packet */ + int message_len; + char *cpnt; + message_len=strlen(message); + if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN; + cpnt=(char *)m->m_data+m->m_len; + memcpy(cpnt, message, message_len); + m->m_len+=message_len; + } +#endif + + icp->icmp_cksum = 0; + icp->icmp_cksum = cksum(m, m->m_len); + + m->m_data -= hlen; + m->m_len += hlen; + + /* fill in ip */ + ip->ip_hl = hlen >> 2; + ip->ip_len = (u_int16_t)m->m_len; + + ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ + + ip->ip_ttl = MAXTTL; + ip->ip_p = IPPROTO_ICMP; + ip->ip_dst = ip->ip_src; /* ip adresses */ + ip->ip_src = alias_addr; + + (void ) ip_output((struct SLIRPsocket *)NULL, m); + + icmpstat.icps_reflect++; + +end_error: + return; +} +#undef ICMP_MAXDATALEN + +/* + * Reflect the ip packet back to the source + */ +void +icmp_reflect(m) + struct SLIRPmbuf *m; +{ + register struct ip *ip = mtod(m, struct ip *); + int hlen = ip->ip_hl << 2; + int optlen = hlen - sizeof(struct ip ); + register struct icmp *icp; + + /* + * Send an icmp packet back to the ip level, + * after supplying a checksum. + */ + m->m_data += hlen; + m->m_len -= hlen; + icp = mtod(m, struct icmp *); + + icp->icmp_cksum = 0; + icp->icmp_cksum = cksum(m, ip->ip_len - hlen); + + m->m_data -= hlen; + m->m_len += hlen; + + /* fill in ip */ + if (optlen > 0) { + /* + * Strip out original options by copying rest of first + * SLIRPmbuf's data back, and adjust the IP length. + */ + memmove((SLIRPcaddr_t)(ip + 1), (SLIRPcaddr_t)ip + hlen, + (unsigned )(m->m_len - hlen)); + hlen -= optlen; + ip->ip_hl = hlen >> 2; + ip->ip_len -= optlen; + m->m_len -= optlen; + } + + ip->ip_ttl = MAXTTL; + { /* swap */ + struct in_addr icmp_dst; + icmp_dst = ip->ip_dst; + ip->ip_dst = ip->ip_src; + ip->ip_src = icmp_dst; + } + + (void ) ip_output((struct SLIRPsocket *)NULL, m); + + icmpstat.icps_reflect++; +} diff --git a/src/slirp/ip_icmp.h b/src/slirp/ip_icmp.h new file mode 100644 index 0000000..2de52a1 --- /dev/null +++ b/src/slirp/ip_icmp.h @@ -0,0 +1,168 @@ +/* + * 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. + * + * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93 + * ip_icmp.h,v 1.4 1995/05/30 08:09:43 rgrimes Exp + */ + +#ifndef _NETINET_IP_ICMP_H_ +#define _NETINET_IP_ICMP_H_ + +/* + * Interface Control Message Protocol Definitions. + * Per RFC 792, September 1981. + */ + +typedef u_int32_t n_time; + +/* + * Structure of an icmp header. + */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct icmp { + u_char icmp_type; /* type of message, see below */ + u_char icmp_code; /* type sub code */ + u_short icmp_cksum; /* ones complement cksum of struct */ + union { + u_char ih_pptr; /* ICMP_PARAMPROB */ + struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ + struct ih_idseq { + u_short icd_id; + u_short icd_seq; + } ih_idseq; + int ih_void; + + /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ + struct ih_pmtu { + u_short ipm_void; + u_short ipm_nextmtu; + } ih_pmtu; + } icmp_hun; +#define icmp_pptr icmp_hun.ih_pptr +#define icmp_gwaddr icmp_hun.ih_gwaddr +#define icmp_id icmp_hun.ih_idseq.icd_id +#define icmp_seq icmp_hun.ih_idseq.icd_seq +#define icmp_void icmp_hun.ih_void +#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void +#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu + union { + struct id_ts { + n_time its_otime; + n_time its_rtime; + n_time its_ttime; + } id_ts; + struct id_ip { + struct ip idi_ip; + /* options and then 64 bits of data */ + } id_ip; + uint32_t id_mask; + char id_data[1]; + } icmp_dun; +#define icmp_otime icmp_dun.id_ts.its_otime +#define icmp_rtime icmp_dun.id_ts.its_rtime +#define icmp_ttime icmp_dun.id_ts.its_ttime +#define icmp_ip icmp_dun.id_ip.idi_ip +#define icmp_mask icmp_dun.id_mask +#define icmp_data icmp_dun.id_data +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(0) +#endif + +/* + * Lower bounds on packet lengths for various types. + * For the error advice packets must first insure that the + * packet is large enought to contain the returned ip header. + * Only then can we do the check to see if 64 bits of packet + * data have been returned, since we need to check the returned + * ip header length. + */ +#define ICMP_MINLEN 8 /* abs minimum */ +#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ +#define ICMP_MASKLEN 12 /* address mask */ +#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ +#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) + /* N.B.: must separately check that ip_hl >= 5 */ + +/* + * Definition of type and code field values. + */ +#define ICMP_ECHOREPLY 0 /* echo reply */ +#define ICMP_UNREACH 3 /* dest unreachable, codes: */ +#define ICMP_UNREACH_NET 0 /* bad net */ +#define ICMP_UNREACH_HOST 1 /* bad host */ +#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ +#define ICMP_UNREACH_PORT 3 /* bad port */ +#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ +#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ +#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ +#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ +#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ +#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ +#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ +#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ +#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ +#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ +#define ICMP_REDIRECT 5 /* shorter route, codes: */ +#define ICMP_REDIRECT_NET 0 /* for network */ +#define ICMP_REDIRECT_HOST 1 /* for host */ +#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ +#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ +#define ICMP_ECHO 8 /* echo service */ +#define ICMP_ROUTERADVERT 9 /* router advertisement */ +#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ +#define ICMP_TIMXCEED 11 /* time exceeded, code: */ +#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ +#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ +#define ICMP_PARAMPROB 12 /* ip header bad */ +#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ +#define ICMP_TSTAMP 13 /* timestamp request */ +#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ +#define ICMP_IREQ 15 /* information request */ +#define ICMP_IREQREPLY 16 /* information reply */ +#define ICMP_MASKREQ 17 /* address mask request */ +#define ICMP_MASKREPLY 18 /* address mask reply */ + +#define ICMP_MAXTYPE 18 + +#define ICMP_INFOTYPE(type) \ + ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ + (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ + (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ + (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ + (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) + +void icmp_input _P((struct SLIRPmbuf *, int)); +void icmp_error _P((struct SLIRPmbuf *, u_char, u_char, int, char *)); +void icmp_reflect _P((struct SLIRPmbuf *)); + +#endif diff --git a/src/slirp/ip_input.c b/src/slirp/ip_input.c new file mode 100644 index 0000000..70d3fc8 --- /dev/null +++ b/src/slirp/ip_input.c @@ -0,0 +1,693 @@ +/* + * Copyright (c) 1982, 1986, 1988, 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. + * + * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 + * ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp + */ + +/* + * Changes and additions relating to SLiRP are + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include "slirp.h" +#include "ip_icmp.h" + +int ip_defttl; +struct ipstat ipstat; +struct ipq ipq; + +/* + * IP initialization: fill in IP protocol switch table. + * All protocols not implemented in kernel go to raw IP protocol handler. + */ +void +ip_init() +{ + ipq.next = ipq.prev = (ipqp_32)&ipq; + ip_id = tt.tv_sec & 0xffff; + udp_init(); + tcp_init(); + ip_defttl = IPDEFTTL; +} + +/* + * Ip input routine. Checksum and byte swap header. If fragmented + * try to reassemble. Process options. Pass to next level. + */ +void +ip_input(m) + struct SLIRPmbuf *m; +{ + register struct ip *ip; + u_int hlen; + + DEBUG_CALL("ip_input"); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("m_len = %d", m->m_len); + + ipstat.ips_total++; + + if (m->m_len < sizeof (struct ip)) { + ipstat.ips_toosmall++; + return; + } + + ip = mtod(m, struct ip *); + + if (ip->ip_v != IPVERSION) { + ipstat.ips_badvers++; + goto bad; + } + + hlen = ip->ip_hl << 2; + if (hlenm->m_len) {/* min header length */ + ipstat.ips_badhlen++; /* or packet too short */ + goto bad; + } + + /* keep ip header intact for ICMP reply + * ip->ip_sum = cksum(m, hlen); + * if (ip->ip_sum) { + */ + if(cksum(m,hlen)) { + ipstat.ips_badsum++; + goto bad; + } + + /* + * Convert fields to host representation. + */ + NTOHS(ip->ip_len); + if (ip->ip_len < hlen) { + ipstat.ips_badlen++; + goto bad; + } + NTOHS(ip->ip_id); + NTOHS(ip->ip_off); + + /* + * Check that the amount of data in the buffers + * is as at least much as the IP header would have us expect. + * Trim SLIRPmbufs if longer than we expect. + * Drop packet if shorter than we expect. + */ + if (m->m_len < ip->ip_len) { + ipstat.ips_tooshort++; + goto bad; + } + /* Should drop packet if SLIRPmbuf too long? hmmm... */ + if (m->m_len > ip->ip_len) + m_adj(m, ip->ip_len - m->m_len); + + /* check ip_ttl for a correct ICMP reply */ + if(ip->ip_ttl==0 || ip->ip_ttl==1) { + icmp_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl"); + goto bad; + } + + /* + * Process options and, if not destined for us, + * ship it on. ip_dooptions returns 1 when an + * error was detected (causing an icmp message + * to be sent and the original packet to be freed). + */ +/* We do no IP options */ +/* if (hlen > sizeof (struct ip) && ip_dooptions(m)) + * goto next; + */ + /* + * If offset or IP_MF are set, must reassemble. + * Otherwise, nothing need be done. + * (We could look in the reassembly queue to see + * if the packet was previously fragmented, + * but it's not worth the time; just let them time out.) + * + * XXX This should fail, don't fragment yet + */ + if (ip->ip_off &~ IP_DF) { + register struct ipq *fp; + /* + * Look for queue of fragments + * of this datagram. + */ + for (fp = (struct ipq *) ipq.next; fp != &ipq; + fp = (struct ipq *) fp->next) + if (ip->ip_id == fp->ipq_id && + ip->ip_src.s_addr == fp->ipq_src.s_addr && + ip->ip_dst.s_addr == fp->ipq_dst.s_addr && + ip->ip_p == fp->ipq_p) + goto found; + fp = 0; + found: + + /* + * Adjust ip_len to not reflect header, + * set ip_mff if more fragments are expected, + * convert offset of this to bytes. + */ + ip->ip_len -= hlen; + if (ip->ip_off & IP_MF) + ((struct ipasfrag *)ip)->ipf_mff |= 1; + else + ((struct ipasfrag *)ip)->ipf_mff &= ~1; + + ip->ip_off <<= 3; + + /* + * If datagram marked as having more fragments + * or if this is not the first fragment, + * attempt reassembly; if it succeeds, proceed. + */ + if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { + ipstat.ips_fragments++; + ip = ip_reass((struct ipasfrag *)ip, fp); + if (ip == 0) + return; + ipstat.ips_reassembled++; + m = dtom(ip); + } else + if (fp) + ip_freef(fp); + + } else + ip->ip_len -= hlen; + + /* + * Switch out to protocol's input routine. + */ + ipstat.ips_delivered++; + switch (ip->ip_p) { + case IPPROTO_TCP: + tcp_input(m, hlen, (struct SLIRPsocket *)NULL); + break; + case IPPROTO_UDP: + udp_input(m, hlen); + break; + case IPPROTO_ICMP: + icmp_input(m, hlen); + break; + default: + ipstat.ips_noproto++; + m_free(m); + } + return; +bad: + m_freem(m); + return; +} + +/* + * Take incoming datagram fragment and try to + * reassemble it into whole datagram. If a chain for + * reassembly of this datagram already exists, then it + * is given as fp; otherwise have to make a chain. + */ +struct ip * +ip_reass(ip, fp) + register struct ipasfrag *ip; + register struct ipq *fp; +{ + register struct SLIRPmbuf *m = dtom(ip); + register struct ipasfrag *q; + int hlen = ip->ip_hl << 2; + int i, next; + + DEBUG_CALL("ip_reass"); + DEBUG_ARG("ip = %lx", (long)ip); + DEBUG_ARG("fp = %lx", (long)fp); + DEBUG_ARG("m = %lx", (long)m); + + /* + * Presence of header sizes in SLIRPmbufs + * would confuse code below. + * Fragment m_data is concatenated. + */ + m->m_data += hlen; + m->m_len -= hlen; + + /* + * If first fragment to arrive, create a reassembly queue. + */ + if (fp == 0) { + struct SLIRPmbuf *t; + if ((t = m_get()) == NULL) goto dropfrag; + fp = mtod(t, struct ipq *); + insque_32(fp, &ipq); + fp->ipq_ttl = IPFRAGTTL; + fp->ipq_p = ip->ip_p; + fp->ipq_id = ip->ip_id; + fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp; + fp->ipq_src = ((struct ip *)ip)->ip_src; + fp->ipq_dst = ((struct ip *)ip)->ip_dst; + q = (struct ipasfrag *)fp; + goto insert; + } + + /* + * Find a segment which begins after this one does. + */ + for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp; + q = (struct ipasfrag *)q->ipf_next) + if (q->ip_off > ip->ip_off) + break; + + /* + * If there is a preceding segment, it may provide some of + * our data already. If so, drop the data from the incoming + * segment. If it provides all of our data, drop us. + */ + if (q->ipf_prev != (ipasfragp_32)fp) { + i = ((struct ipasfrag *)(q->ipf_prev))->ip_off + + ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; + if (i > 0) { + if (i >= ip->ip_len) + goto dropfrag; + m_adj(dtom(ip), i); + ip->ip_off += i; + ip->ip_len -= i; + } + } + + /* + * While we overlap succeeding segments trim them or, + * if they are completely covered, dequeue them. + */ + while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { + i = (ip->ip_off + ip->ip_len) - q->ip_off; + if (i < q->ip_len) { + q->ip_len -= i; + q->ip_off += i; + m_adj(dtom(q), i); + break; + } + q = (struct ipasfrag *) q->ipf_next; + m_freem(dtom((struct ipasfrag *) q->ipf_prev)); + ip_deq((struct ipasfrag *) q->ipf_prev); + } + +insert: + /* + * Stick new segment in its place; + * check for complete reassembly. + */ + ip_enq(ip, (struct ipasfrag *) q->ipf_prev); + next = 0; + for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; + q = (struct ipasfrag *) q->ipf_next) { + if (q->ip_off != next) + return (0); + next += q->ip_len; + } + if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) + return (0); + + /* + * Reassembly is complete; concatenate fragments. + */ + q = (struct ipasfrag *) fp->ipq_next; + m = dtom(q); + + q = (struct ipasfrag *) q->ipf_next; + while (q != (struct ipasfrag *)fp) { + struct SLIRPmbuf *t; + t = dtom(q); + q = (struct ipasfrag *) q->ipf_next; + m_cat(m, t); + } + + /* + * Create header for new ip packet by + * modifying header of first packet; + * dequeue and discard fragment reassembly header. + * Make header visible. + */ + ip = (struct ipasfrag *) fp->ipq_next; + + /* + * If the fragments concatenated to an SLIRPmbuf that's + * bigger than the total size of the fragment, then and + * m_ext buffer was alloced. But fp->ipq_next points to + * the old buffer (in the SLIRPmbuf), so we must point ip + * into the new buffer. + */ + if (m->m_flags & M_EXT) { + int delta; + delta = (char *)ip - m->m_dat; + ip = (struct ipasfrag *)(m->m_ext + delta); + } + + /* DEBUG_ARG("ip = %lx", (long)ip); + * ip=(struct ipasfrag *)m->m_data; */ + + ip->ip_len = next; + ip->ipf_mff &= ~1; + ((struct ip *)ip)->ip_src = fp->ipq_src; + ((struct ip *)ip)->ip_dst = fp->ipq_dst; + remque_32(fp); + (void) m_free(dtom(fp)); + m = dtom(ip); + m->m_len += (ip->ip_hl << 2); + m->m_data -= (ip->ip_hl << 2); + + return ((struct ip *)ip); + +dropfrag: + ipstat.ips_fragdropped++; + m_freem(m); + return (0); +} + +/* + * Free a fragment reassembly header and all + * associated datagrams. + */ +void +ip_freef(fp) + struct ipq *fp; +{ + register struct ipasfrag *q, *p; + + for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; + q = p) { + p = (struct ipasfrag *) q->ipf_next; + ip_deq(q); + m_freem(dtom(q)); + } + remque_32(fp); + (void) m_free(dtom(fp)); +} + +/* + * Put an ip fragment on a reassembly chain. + * Like insque, but pointers in middle of structure. + */ +void +ip_enq(p, prev) + register struct ipasfrag *p, *prev; +{ + DEBUG_CALL("ip_enq"); + DEBUG_ARG("prev = %lx", (long)prev); + p->ipf_prev = (ipasfragp_32) prev; + p->ipf_next = prev->ipf_next; + ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p; + prev->ipf_next = (ipasfragp_32) p; +} + +/* + * To ip_enq as remque is to insque. + */ +void +ip_deq(p) + register struct ipasfrag *p; +{ + ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next; + ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev; +} + +/* + * IP timer processing; + * if a timer expires on a reassembly + * queue, discard it. + */ +void +ip_slowtimo() +{ + register struct ipq *fp; + + DEBUG_CALL("ip_slowtimo"); + + fp = (struct ipq *) ipq.next; + if (fp == 0) + return; + + while (fp != &ipq) { + --fp->ipq_ttl; + fp = (struct ipq *) fp->next; + if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { + ipstat.ips_fragtimeout++; + ip_freef((struct ipq *) fp->prev); + } + } +} + +/* + * Do option processing on a datagram, + * possibly discarding it if bad options are encountered, + * or forwarding it if source-routed. + * Returns 1 if packet has been forwarded/freed, + * 0 if the packet should be processed further. + */ + +#ifdef notdef + +int +ip_dooptions(m) + struct SLIRPmbuf *m; +{ + register struct ip *ip = mtod(m, struct ip *); + register u_char *cp; + register struct ip_timestamp *ipt; + register struct in_ifaddr *ia; +/* int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; */ + int opt, optlen, cnt, off, code, type, forward = 0; + struct in_addr *sin, dst; +typedef u_int32_t n_time; + n_time ntime; + + dst = ip->ip_dst; + cp = (u_char *)(ip + 1); + cnt = (ip->ip_hl << 2) - sizeof (struct ip); + for (; cnt > 0; cnt -= optlen, cp += optlen) { + opt = cp[IPOPT_OPTVAL]; + if (opt == IPOPT_EOL) + break; + if (opt == IPOPT_NOP) + optlen = 1; + else { + optlen = cp[IPOPT_OLEN]; + if (optlen <= 0 || optlen > cnt) { + code = &cp[IPOPT_OLEN] - (u_char *)ip; + goto bad; + } + } + switch (opt) { + + default: + break; + + /* + * Source routing with record. + * Find interface with current destination address. + * If none on this machine then drop if strictly routed, + * or do nothing if loosely routed. + * Record interface address and bring up next address + * component. If strictly routed make sure next + * address is on directly accessible net. + */ + case IPOPT_LSRR: + case IPOPT_SSRR: + if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { + code = &cp[IPOPT_OFFSET] - (u_char *)ip; + goto bad; + } + ipaddr.sin_addr = ip->ip_dst; + ia = (struct in_ifaddr *) + ifa_ifwithaddr((struct sockaddr *)&ipaddr); + if (ia == 0) { + if (opt == IPOPT_SSRR) { + type = ICMP_UNREACH; + code = ICMP_UNREACH_SRCFAIL; + goto bad; + } + /* + * Loose routing, and not at next destination + * yet; nothing to do except forward. + */ + break; + } + off--; / * 0 origin * / + if (off > optlen - sizeof(struct in_addr)) { + /* + * End of source route. Should be for us. + */ + save_rte(cp, ip->ip_src); + break; + } + /* + * locate outgoing interface + */ + bcopy((SLIRPcaddr_t)(cp + off), (SLIRPcaddr_t)&ipaddr.sin_addr, + sizeof(ipaddr.sin_addr)); + if (opt == IPOPT_SSRR) { +#define INA struct in_ifaddr * +#define SA struct sockaddr * + if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0) + ia = (INA)ifa_ifwithnet((SA)&ipaddr); + } else + ia = ip_rtaddr(ipaddr.sin_addr); + if (ia == 0) { + type = ICMP_UNREACH; + code = ICMP_UNREACH_SRCFAIL; + goto bad; + } + ip->ip_dst = ipaddr.sin_addr; + bcopy((SLIRPcaddr_t)&(IA_SIN(ia)->sin_addr), + (SLIRPcaddr_t)(cp + off), sizeof(struct in_addr)); + cp[IPOPT_OFFSET] += sizeof(struct in_addr); + /* + * Let ip_intr's mcast routing check handle mcast pkts + */ + forward = !IN_MULTICAST(ntohl(ip->ip_dst.s_addr)); + break; + + case IPOPT_RR: + if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { + code = &cp[IPOPT_OFFSET] - (u_char *)ip; + goto bad; + } + /* + * If no space remains, ignore. + */ + off--; * 0 origin * + if (off > optlen - sizeof(struct in_addr)) + break; + bcopy((SLIRPcaddr_t)(&ip->ip_dst), (SLIRPcaddr_t)&ipaddr.sin_addr, + sizeof(ipaddr.sin_addr)); + /* + * locate outgoing interface; if we're the destination, + * use the incoming interface (should be same). + */ + if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 && + (ia = ip_rtaddr(ipaddr.sin_addr)) == 0) { + type = ICMP_UNREACH; + code = ICMP_UNREACH_HOST; + goto bad; + } + bcopy((SLIRPcaddr_t)&(IA_SIN(ia)->sin_addr), + (SLIRPcaddr_t)(cp + off), sizeof(struct in_addr)); + cp[IPOPT_OFFSET] += sizeof(struct in_addr); + break; + + case IPOPT_TS: + code = cp - (u_char *)ip; + ipt = (struct ip_timestamp *)cp; + if (ipt->ipt_len < 5) + goto bad; + if (ipt->ipt_ptr > ipt->ipt_len - sizeof (int32_t)) { + if (++ipt->ipt_oflw == 0) + goto bad; + break; + } + sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); + switch (ipt->ipt_flg) { + + case IPOPT_TS_TSONLY: + break; + + case IPOPT_TS_TSANDADDR: + if (ipt->ipt_ptr + sizeof(n_time) + + sizeof(struct in_addr) > ipt->ipt_len) + goto bad; + ipaddr.sin_addr = dst; + ia = (INA)ifaof_ i f p foraddr((SA)&ipaddr, + m->m_pkthdr.rcvif); + if (ia == 0) + continue; + bcopy((SLIRPcaddr_t)&IA_SIN(ia)->sin_addr, + (SLIRPcaddr_t)sin, sizeof(struct in_addr)); + ipt->ipt_ptr += sizeof(struct in_addr); + break; + + case IPOPT_TS_PRESPEC: + if (ipt->ipt_ptr + sizeof(n_time) + + sizeof(struct in_addr) > ipt->ipt_len) + goto bad; + bcopy((SLIRPcaddr_t)sin, (SLIRPcaddr_t)&ipaddr.sin_addr, + sizeof(struct in_addr)); + if (ifa_ifwithaddr((SA)&ipaddr) == 0) + continue; + ipt->ipt_ptr += sizeof(struct in_addr); + break; + + default: + goto bad; + } + ntime = iptime(); + bcopy((SLIRPcaddr_t)&ntime, (SLIRPcaddr_t)cp + ipt->ipt_ptr - 1, + sizeof(n_time)); + ipt->ipt_ptr += sizeof(n_time); + } + } + if (forward) { + ip_forward(m, 1); + return (1); + } + } + } + return (0); +bad: + /* ip->ip_len -= ip->ip_hl << 2; XXX icmp_error adds in hdr length */ + +/* Not yet */ + icmp_error(m, type, code, 0, 0); + + ipstat.ips_badoptions++; + return (1); +} + +#endif /* notdef */ + +/* + * Strip out IP options, at higher + * level protocol in the kernel. + * Second argument is buffer to which options + * will be moved, and return value is their length. + * (XXX) should be deleted; last arg currently ignored. + */ +void +ip_stripoptions(m, mopt) + struct SLIRPmbuf *m; + struct SLIRPmbuf *mopt; +{ + register int i; + struct ip *ip = mtod(m, struct ip *); + register SLIRPcaddr_t opts; + int olen; + + olen = (ip->ip_hl<<2) - sizeof (struct ip); + opts = (SLIRPcaddr_t)(ip + 1); + i = m->m_len - (sizeof (struct ip) + olen); + memcpy(opts, opts + olen, (unsigned)i); + m->m_len -= olen; + + ip->ip_hl = sizeof(struct ip) >> 2; +} diff --git a/src/slirp/ip_output.c b/src/slirp/ip_output.c new file mode 100644 index 0000000..214c031 --- /dev/null +++ b/src/slirp/ip_output.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1990, 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. + * + * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 + * ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp + */ + +/* + * Changes and additions relating to SLiRP are + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include "slirp.h" + +u_int16_t ip_id; + +/* + * IP output. The packet in SLIRPmbuf chain m contains a skeletal IP + * header (with len, off, ttl, proto, tos, src, dst). + * The SLIRPmbuf chain containing the packet will be freed. + * The SLIRPmbuf opt, if present, will not be freed. + */ +int +ip_output(so, m0) + struct SLIRPsocket *so; + struct SLIRPmbuf *m0; +{ + struct ip *ip; + struct SLIRPmbuf *m = m0; + u_int hlen = sizeof(struct ip ); + u_int len, off; + int error = 0; + + DEBUG_CALL("ip_output"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("m0 = %lx", (long)m0); + + /* We do no options */ +/* if (opt) { + * m = ip_insertoptions(m, opt, &len); + * hlen = len; + * } + */ + ip = mtod(m, struct ip *); + /* + * Fill in IP header. + */ + ip->ip_v = IPVERSION; + ip->ip_off &= IP_DF; + ip->ip_id = htons(ip_id++); + ip->ip_hl = hlen >> 2; + ipstat.ips_localout++; + + /* + * Verify that we have any chance at all of being able to queue + * the packet or packet fragments + */ + /* XXX Hmmm... */ +/* if (if_queued > if_thresh && towrite <= 0) { + * error = ENOBUFS; + * goto bad; + * } + */ + + /* + * If small enough for interface, can just send directly. + */ + if ((u_int16_t)ip->ip_len <= if_mtu) { + ip->ip_len = htons((u_int16_t)ip->ip_len); + ip->ip_off = htons((u_int16_t)ip->ip_off); + ip->ip_sum = 0; + ip->ip_sum = cksum(m, hlen); + + if_output(so, m); + goto done; + } + + /* + * Too large for interface; fragment if possible. + * Must be able to put at least 8 bytes per fragment. + */ + if (ip->ip_off & IP_DF) { + error = -1; + ipstat.ips_cantfrag++; + goto bad; + } + + len = (if_mtu - hlen) &~ 7; /* ip databytes per packet */ + if (len < 8) { + error = -1; + goto bad; + } + + { + int mhlen, firstlen = len; + struct SLIRPmbuf **mnext = &m->m_nextpkt; + + /* + * Loop through length of segment after first fragment, + * make new header and copy data of each part and link onto chain. + */ + m0 = m; + mhlen = sizeof (struct ip); + for (off = hlen + len; off < ip->ip_len; off += len) { + struct ip *mhip; + m = m_get(); + if (m == 0) { + error = -1; + ipstat.ips_odropped++; + goto sendorfree; + } + m->m_data += if_maxlinkhdr; + mhip = mtod(m, struct ip *); + *mhip = *ip; + + /* No options */ +/* if (hlen > sizeof (struct ip)) { + * mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); + * mhip->ip_hl = mhlen >> 2; + * } + */ + m->m_len = mhlen; + mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); + if (ip->ip_off & IP_MF) + mhip->ip_off |= IP_MF; + if (off + len >= (u_int16_t)ip->ip_len) + len = (u_int16_t)ip->ip_len - off; + else + mhip->ip_off |= IP_MF; + mhip->ip_len = htons((u_int16_t)(len + mhlen)); + + if (m_copy(m, m0, off, len) < 0) { + error = -1; + goto sendorfree; + } + + mhip->ip_off = htons((u_int16_t)mhip->ip_off); + mhip->ip_sum = 0; + mhip->ip_sum = cksum(m, mhlen); + *mnext = m; + mnext = &m->m_nextpkt; + ipstat.ips_ofragments++; + } + /* + * Update first fragment by trimming what's been copied out + * and updating header, then send each fragment (in order). + */ + m = m0; + m_adj(m, hlen + firstlen - ip->ip_len); + ip->ip_len = htons((u_int16_t)m->m_len); + ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF)); + ip->ip_sum = 0; + ip->ip_sum = cksum(m, hlen); +sendorfree: + for (m = m0; m; m = m0) { + m0 = m->m_nextpkt; + m->m_nextpkt = 0; + if (error == 0) + if_output(so, m); + else + m_freem(m); + } + + if (error == 0) + ipstat.ips_fragmented++; + } + +done: + return (error); + +bad: + m_freem(m0); + goto done; +} diff --git a/src/slirp/libslirp.h b/src/slirp/libslirp.h new file mode 100644 index 0000000..57a68cf --- /dev/null +++ b/src/slirp/libslirp.h @@ -0,0 +1,41 @@ +#ifndef _LIBSLIRP_H +#define _LIBSLIRP_H + +#ifdef _WIN32 +#include +int inet_aton(const char *cp, struct in_addr *ia); +#else +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int slirp_init(void); + +int slirp_select_fill(int *pnfds, + fd_set *readfds, fd_set *writefds, fd_set *xfds); + +void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds); + +void slirp_input(const uint8 *pkt, int pkt_len); + +/* you must provide the following functions: */ +int slirp_can_output(void); +void slirp_output(const uint8 *pkt, int pkt_len); + +int slirp_redir(int is_udp, int host_port, + struct in_addr guest_addr, int guest_port); +int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, + int guest_port); + +extern const char *tftp_prefix; +extern char slirp_hostname[33]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/slirp/main.h b/src/slirp/main.h new file mode 100644 index 0000000..45e51cd --- /dev/null +++ b/src/slirp/main.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#define TOWRITEMAX 512 + +extern struct timeval tt; +extern int link_up; +extern int slirp_socket; +extern int slirp_socket_unit; +extern int slirp_socket_port; +extern u_int32_t slirp_socket_addr; +extern char *slirp_socket_passwd; +extern int ctty_closed; + +/* + * Get the difference in 2 times from updtim() + * Allow for wraparound times, "just in case" + * x is the greater of the 2 (current time) and y is + * what it's being compared against. + */ +#define TIME_DIFF(x,y) (x)-(y) < 0 ? ~0-(y)+(x) : (x)-(y) + +extern char *slirp_tty; +extern char *exec_shell; +extern u_int curtime; +extern fd_set *global_readfds, *global_writefds, *global_xfds; +extern struct in_addr ctl_addr; +extern struct in_addr special_addr; +extern struct in_addr alias_addr; +extern struct in_addr our_addr; +extern struct in_addr loopback_addr; +extern struct in_addr dns_addr; +extern char *username; +extern char *socket_path; +extern int towrite_max; +extern int ppp_exit; +extern int so_options; +extern int tcp_keepintvl; +extern uint8_t client_ethaddr[6]; + +#define PROTO_SLIP 0x1 +#ifdef USE_PPP +#define PROTO_PPP 0x2 +#endif + +void if_encap(const uint8_t *ip_data, int ip_data_len); diff --git a/src/slirp/mbuf.c b/src/slirp/mbuf.c new file mode 100644 index 0000000..bf636e1 --- /dev/null +++ b/src/slirp/mbuf.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1995 Danny Gasparovski + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +/* + * mbuf's in SLiRP are much simpler than the real mbufs in + * FreeBSD. They are fixed size, determined by the MTU, + * so that one whole packet can fit. Mbuf's cannot be + * chained together. If there's more data than the mbuf + * could hold, an external malloced buffer is pointed to + * by m_ext (and the data pointers) and M_EXT is set in + * the flags + */ + +#include +#include "slirp.h" + +struct mbuf *mbutl; +char *mclrefcnt; +int mbuf_alloced = 0; +struct SLIRPmbuf m_freelist, m_usedlist; +int mbuf_thresh = 30; +int mbuf_max = 0; +size_t msize; + +void +m_init() +{ + m_freelist.m_next = m_freelist.m_prev = &m_freelist; + m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist; + msize_init(); +} + +void msize_init() +{ + /* + * Find a nice value for msize + * XXX if_maxlinkhdr already in mtu + */ + msize = (if_mtu>if_mru?if_mtu:if_mru) + + if_maxlinkhdr + sizeof(struct m_hdr ) + 6; +} + +/* + * Get an mbuf from the free list, if there are none + * malloc one + * + * Because fragmentation can occur if we alloc new mbufs and + * free old mbufs, we mark all mbufs above mbuf_thresh as M_DOFREE, + * which tells m_free to actually free() it + */ +struct SLIRPmbuf * m_get() +{ + struct SLIRPmbuf *m; + int flags = 0; + + DEBUG_CALL("m_get"); + + if (m_freelist.m_next == &m_freelist) { + m = (struct SLIRPmbuf *)malloc(msize); + if (m == NULL) goto end_error; + mbuf_alloced++; + if (mbuf_alloced > mbuf_thresh) + flags = M_DOFREE; + if (mbuf_alloced > mbuf_max) + mbuf_max = mbuf_alloced; + } else { + m = m_freelist.m_next; + remque(m); + } + + /* Insert it in the used list */ + insque(m,&m_usedlist); + m->m_flags = (flags | M_USEDLIST); + + /* Initialise it */ + m->m_size = msize - sizeof(struct m_hdr); + m->m_data = m->m_dat; + m->m_len = 0; + m->m_nextpkt = 0; + m->m_prevpkt = 0; +end_error: + DEBUG_ARG("m = %lx", (long )m); + return m; +} + +//For some reason this fails in GDB saying tehre is no m_flags member +void +m_free(m) + struct SLIRPmbuf *m; +{ + + DEBUG_CALL("m_free"); + DEBUG_ARG("m = %lx", (long )m); + + if(m) { + /* Remove from m_usedlist */ + if (m->m_flags & M_USEDLIST) + remque(m); + + + + /* If it's M_EXT, free() it */ + if (m->m_flags & M_EXT) + free(m->m_ext); + + /* + * Either free() it or put it on the free list + */ + if (m->m_flags & M_DOFREE) { + free(m); + mbuf_alloced--; + } else if ((m->m_flags & M_FREELIST) == 0) { + insque(m,&m_freelist); + m->m_flags = M_FREELIST; /* Clobber other flags */ + } + } /* if(m) */ +} + +/* + * Copy data from one mbuf to the end of + * the other.. if result is too big for one mbuf, malloc() + * an M_EXT data segment + */ +void +m_cat(m, n) + struct SLIRPmbuf *m, *n; +{ + /* + * If there's no room, realloc + */ + if (M_FREEROOM(m) < n->m_len) + m_inc(m,m->m_size+MINCSIZE); + + memcpy(m->m_data+m->m_len, n->m_data, n->m_len); + m->m_len += n->m_len; + + m_free(n); +} + + +/* make m size bytes large */ +void +m_inc(m, size) + struct SLIRPmbuf *m; + int size; +{ + int datasize; + + /* some compiles throw up on gotos. This one we can fake. */ + if(m->m_size>size) return; + + if (m->m_flags & M_EXT) { + datasize = m->m_data - m->m_ext; + m->m_ext = (char *)realloc(m->m_ext,size); +/* if (m->m_ext == NULL) + * return (struct SLIRPmbuf *)NULL; + */ + m->m_data = m->m_ext + datasize; + } else { + char *dat; + datasize = m->m_data - m->m_dat; + dat = (char *)malloc(size); +/* if (dat == NULL) + * return (struct SLIRPmbuf *)NULL; + */ + memcpy(dat, m->m_dat, m->m_size); + + m->m_ext = dat; + m->m_data = m->m_ext + datasize; + m->m_flags |= M_EXT; + } + + m->m_size = size; + +} + + + +void +m_adj(m, len) + struct SLIRPmbuf *m; + int len; +{ + if (m == NULL) + return; + if (len >= 0) { + /* Trim from head */ + m->m_data += len; + m->m_len -= len; + } else { + /* Trim from tail */ + len = -len; + m->m_len -= len; + } +} + + +/* + * Copy len bytes from m, starting off bytes into n + */ +int +m_copy(n, m, off, len) + struct SLIRPmbuf *n, *m; + int off, len; +{ + if (len > M_FREEROOM(n)) + return -1; + + memcpy((n->m_data + n->m_len), (m->m_data + off), len); + n->m_len += len; + return 0; +} + + +/* + * Given a pointer into an mbuf, return the mbuf + * XXX This is a kludge, I should eliminate the need for it + * Fortunately, it's not used often + */ +struct SLIRPmbuf * +dtom(dat) + void *dat; +{ + struct SLIRPmbuf *m; + + DEBUG_CALL("dtom"); + DEBUG_ARG("dat = %lx", (long )dat); + + /* bug corrected for M_EXT buffers */ + for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) { + if (m->m_flags & M_EXT) { + if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) + return m; + } else { + if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) + return m; + } + } + + DEBUG_ERROR((dfd, "dtom failed")); + + return (struct SLIRPmbuf *)0; +} + diff --git a/src/slirp/mbuf.h b/src/slirp/mbuf.h new file mode 100644 index 0000000..840fa3b --- /dev/null +++ b/src/slirp/mbuf.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1982, 1986, 1988, 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. + * + * @(#)mbuf.h 8.3 (Berkeley) 1/21/94 + * mbuf.h,v 1.9 1994/11/14 13:54:20 bde Exp + */ + +#ifndef _MBUF_H_ +#define _MBUF_H_ + +#define m_freem m_free + + +#define MINCSIZE 4096 /* Amount to increase mbuf if too small */ + +/* + * Macros for type conversion + * mtod(m,t) - convert mbuf pointer to data pointer of correct type + * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX) + */ +#define mtod(m,t) ((t)(m)->m_data) +/* #define dtom(x) ((struct SLIRPmbuf *)((int)(x) & ~(M_SIZE-1))) */ + +/* XXX About mbufs for slirp: + * Only one mbuf is ever used in a chain, for each "cell" of data. + * m_nextpkt points to the next packet, if fragmented. + * If the data is too large, the M_EXT is used, and a larger block + * is alloced. Therefore, m_free[m] must check for M_EXT and if set + * free the m_ext. This is inefficient memory-wise, but who cares. + */ + +/* XXX should union some of these! */ +/* header at beginning of each mbuf: */ +struct m_hdr { + struct SLIRPmbuf *mh_next; /* Linked list of mbufs */ + struct SLIRPmbuf *mh_prev; + struct SLIRPmbuf *mh_nextpkt; /* Next packet in queue/record */ + struct SLIRPmbuf *mh_prevpkt; /* Flags aren't used in the output queue */ + int mh_flags; /* Misc flags */ + + size_t mh_size; /* Size of data */ + struct SLIRPsocket *mh_so; + + SLIRPcaddr_t mh_data; /* Location of data */ + size_t mh_len; /* Amount of data in this mbuf */ +}; + +/* + * How much room is in the mbuf, from m_data to the end of the mbuf + */ +#define M_ROOM(m) ((m->m_flags & M_EXT)? \ + (((m)->m_ext + (m)->m_size) - (m)->m_data) \ + : \ + (((m)->m_dat + (m)->m_size) - (m)->m_data)) + +/* + * How much free room there is + */ +#define M_FREEROOM(m) (M_ROOM(m) - (m)->m_len) +#define M_TRAILINGSPACE M_FREEROOM + +struct SLIRPmbuf { + struct m_hdr m_hdr; + union M_dat { + char m_dat_[1]; /* ANSI don't like 0 sized arrays */ + char *m_ext_; + } M_dat; +}; + +#define m_next m_hdr.mh_next +#define m_prev m_hdr.mh_prev +#define m_nextpkt m_hdr.mh_nextpkt +#define m_prevpkt m_hdr.mh_prevpkt +#define m_flags m_hdr.mh_flags +#define m_len m_hdr.mh_len +#define m_data m_hdr.mh_data +#define m_size m_hdr.mh_size +#define m_dat M_dat.m_dat_ +#define m_ext M_dat.m_ext_ +#define m_so m_hdr.mh_so + +#define ifq_prev m_prev +#define ifq_next m_next +#define ifs_prev m_prevpkt +#define ifs_next m_nextpkt +#define ifq_so m_so + +#define M_EXT 0x01 /* m_ext points to more (malloced) data */ +#define M_FREELIST 0x02 /* mbuf is on free list */ +#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */ +#define M_DOFREE 0x08 /* when m_free is called on the mbuf, free() + * it rather than putting it on the free list */ + +/* + * Mbuf statistics. XXX + */ + +struct mbstat { + int mbs_alloced; /* Number of mbufs allocated */ + +}; + +extern struct mbstat mbstat; +extern int mbuf_alloced; +extern struct SLIRPmbuf m_freelist, m_usedlist; +extern int mbuf_max; + +void m_init _P((void)); +void msize_init _P((void)); +struct SLIRPmbuf * m_get _P((void)); +void m_free _P((struct SLIRPmbuf *)); +void m_cat _P((register struct SLIRPmbuf *, register struct SLIRPmbuf *)); +void m_inc _P((struct SLIRPmbuf *, int)); +void m_adj _P((struct SLIRPmbuf *, int)); +int m_copy _P((struct SLIRPmbuf *, struct SLIRPmbuf *, int, int)); +struct SLIRPmbuf * dtom _P((void *)); + +#endif diff --git a/src/slirp/misc.c b/src/slirp/misc.c new file mode 100644 index 0000000..b1e2df2 --- /dev/null +++ b/src/slirp/misc.c @@ -0,0 +1,970 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#define WANT_SYS_IOCTL_H +#include +#include "slirp.h" + +u_int curtime, time_fasttimo, last_slowtimo, detach_time; +u_int detach_wait = 600000; /* 10 minutes */ + +#if 0 +int x_port = -1; +int x_display = 0; +int x_screen = 0; + +int +show_x(buff, inso) + char *buff; + struct SLIRPsocket *inso; +{ + if (x_port < 0) { + lprint("X Redir: X not being redirected.\r\n"); + } else { + lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n", + inet_ntoa(our_addr), x_port, x_screen); + lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n", + inet_ntoa(our_addr), x_port, x_screen); + if (x_display) + lprint("X Redir: Redirecting to display %d\r\n", x_display); + } + + return CFG_OK; +} + + +/* + * XXX Allow more than one X redirection? + */ +void +redir_x(inaddr, start_port, display, screen) + u_int32_t inaddr; + int start_port; + int display; + int screen; +{ + int i; + + if (x_port >= 0) { + lprint("X Redir: X already being redirected.\r\n"); + show_x(0, 0); + } else { + for (i = 6001 + (start_port-1); i <= 6100; i++) { + if (solisten(htons(i), inaddr, htons(6000 + display), 0)) { + /* Success */ + x_port = i - 6000; + x_display = display; + x_screen = screen; + show_x(0, 0); + return; + } + } + lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n"); + } +} +#endif + +#ifndef HAVE_INET_ATON +int +inet_aton(cp, ia) + const char *cp; + struct in_addr *ia; +{ + u_int32_t addr = inet_addr(cp); + if (addr == 0xffffffff) + return 0; + ia->s_addr = addr; + return 1; +} +#endif + +/* + * Get our IP address and put it in our_addr + */ +void +getouraddr() +{ + char buff[512]; + struct hostent *he = NULL; +#define 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 + if (gethostname(buff,256) == 0) + { + struct addrinfo hints = { 0 }; + hints.ai_flags = AI_NUMERICHOST; + hints.ai_family = AF_INET; + struct addrinfo* ai; + if (getaddrinfo(buff, NULL, &hints, &ai) == 0) + { + our_addr = *(struct in_addr *)ai->ai_addr->sa_data; + freeaddrinfo(ai); + } + } + if (our_addr.s_addr == 0) + our_addr.s_addr = loopback_addr.s_addr; + #endif + #undef ANCIENT +} + +//#if SIZEOF_CHAR_P == 8 +//what?! + +struct quehead_32 { + u_int32_t qh_link; + u_int32_t qh_rlink; +}; + +inline void +insque_32(a, b) + void *a; + void *b; +{ + register struct quehead_32 *element = (struct quehead_32 *) a; + register struct quehead_32 *head = (struct quehead_32 *) b; + element->qh_link = head->qh_link; + head->qh_link = (u_int32_t)element; + element->qh_rlink = (u_int32_t)head; + ((struct quehead_32 *)(element->qh_link))->qh_rlink + = (u_int32_t)element; +} + +inline void +remque_32(a) + void *a; +{ + register struct quehead_32 *element = (struct quehead_32 *) a; + ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; + ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; + element->qh_rlink = 0; +} + +//#endif /* SIZEOF_CHAR_P == 8 */ +//Should be for 64bit + +struct quehead { + struct quehead *qh_link; + struct quehead *qh_rlink; +}; + +void +insque(a, b) + void *a, *b; +{ + register struct quehead *element = (struct quehead *) a; + register struct quehead *head = (struct quehead *) b; + element->qh_link = head->qh_link; + head->qh_link = (struct quehead *)element; + element->qh_rlink = (struct quehead *)head; + ((struct quehead *)(element->qh_link))->qh_rlink + = (struct quehead *)element; +} + +void +remque(a) + void *a; +{ + register struct quehead *element = (struct quehead *) a; + ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; + ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; + element->qh_rlink = NULL; + /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */ +} + +/* #endif */ + + +int +add_exec(ex_ptr, do_pty, exec, addr, port) + struct ex_list **ex_ptr; + int do_pty; + char *exec; + int addr; + int port; +{ + struct ex_list *tmp_ptr; + + /* First, check if the port is "bound" */ + for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { + if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) + return -1; + } + + tmp_ptr = *ex_ptr; + *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); + (*ex_ptr)->ex_fport = port; + (*ex_ptr)->ex_addr = addr; + (*ex_ptr)->ex_pty = do_pty; + (*ex_ptr)->ex_exec = strdup(exec); + (*ex_ptr)->ex_next = tmp_ptr; + return 0; +} + +#ifndef HAVE_STRERROR + +/* + * For systems with no strerror + */ + +#ifdef WIN32 +//extern int sys_nerr; +//extern char *sys_errlist[]; +#endif + +char * +SLIRPstrerror(error) + int error; +{ + if (error < sys_nerr) + return sys_errlist[error]; + else + return "Unknown error."; +} + +#endif + + +#ifdef _WIN32 + +int +fork_exec(so, ex, do_pty) + struct SLIRPsocket *so; + char *ex; + int do_pty; +{ + /* not implemented */ + return 0; +} + +#else + +int +slirp_openpty(amaster, aslave) + int *amaster, *aslave; +{ + register int master, slave; + +#ifdef HAVE_GRANTPT + char *ptr; + + if ((master = open("/dev/ptmx", O_RDWR)) < 0 || + grantpt(master) < 0 || + unlockpt(master) < 0 || + (ptr = ptsname(master)) == NULL) { + close(master); + return -1; + } + + if ((slave = open(ptr, O_RDWR)) < 0 || + ioctl(slave, I_PUSH, "ptem") < 0 || + ioctl(slave, I_PUSH, "ldterm") < 0 || + ioctl(slave, I_PUSH, "ttcompat") < 0) { + close(master); + close(slave); + return -1; + } + + *amaster = master; + *aslave = slave; + return 0; + +#else + + static char line[] = "/dev/ptyXX"; + register const char *cp1, *cp2; + + for (cp1 = "pqrsPQRS"; *cp1; cp1++) { + line[8] = *cp1; + for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { + line[9] = *cp2; + if ((master = open(line, O_RDWR, 0)) == -1) { + if (errno == ENOENT) + return (-1); /* out of ptys */ + } else { + line[5] = 't'; + /* These will fail */ + (void) chown(line, getuid(), 0); + (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); +#ifdef HAVE_REVOKE + (void) revoke(line); +#endif + if ((slave = open(line, O_RDWR, 0)) != -1) { + *amaster = master; + *aslave = slave; + return 0; + } + (void) close(master); + line[5] = 'p'; + } + } + } + errno = ENOENT; /* out of ptys */ + return (-1); +#endif +} + +/* + * XXX This is ugly + * We create and bind a socket, then fork off to another + * process, which connects to this socket, after which we + * exec the wanted program. If something (strange) happens, + * the accept() call could block us forever. + * + * do_pty = 0 Fork/exec inetd style + * do_pty = 1 Fork/exec using slirp.telnetd + * do_ptr = 2 Fork/exec using pty + */ +int +fork_exec(so, ex, do_pty) + struct SLIRPsocket *so; + char *ex; + int do_pty; +{ + int s; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + int opt; + int master; + char *argv[256]; +#if 0 + char buff[256]; +#endif + /* don't want to clobber the original */ + char *bptr; + char *curarg; + int c, i, ret; + + DEBUG_CALL("fork_exec"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("ex = %lx", (long)ex); + DEBUG_ARG("do_pty = %lx", (long)do_pty); + + if (do_pty == 2) { + if (slirp_openpty(&master, &s) == -1) { + lprint("Error: openpty failed: %s\n", strerror(errno)); + return 0; + } + } else { + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = 0; + addr.sin_addr.s_addr = INADDR_ANY; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 || + bind(s, (struct sockaddr *)&addr, addrlen) < 0 || + listen(s, 1) < 0) { + lprint("Error: inet socket: %s\n", strerror(errno)); + closesocket(s); + + return 0; + } + } + + switch(fork()) { + case -1: + lprint("Error: fork failed: %s\n", strerror(errno)); + close(s); + if (do_pty == 2) + close(master); + return 0; + + case 0: + /* Set the DISPLAY */ + if (do_pty == 2) { + (void) close(master); +#ifdef TIOCSCTTY /* XXXXX */ + (void) setsid(); + ioctl(s, TIOCSCTTY, (char *)NULL); +#endif + } else { + getsockname(s, (struct sockaddr *)&addr, &addrlen); + close(s); + /* + * Connect to the socket + * XXX If any of these fail, we're in trouble! + */ + s = socket(AF_INET, SOCK_STREAM, 0); + addr.sin_addr = loopback_addr; + do { + ret = connect(s, (struct sockaddr *)&addr, addrlen); + } while (ret < 0 && errno == EINTR); + } + +#if 0 + if (x_port >= 0) { +#ifdef HAVE_SETENV + sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); + setenv("DISPLAY", buff, 1); +#else + sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); + putenv(buff); +#endif + } +#endif + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + for (s = 3; s <= 255; s++) + close(s); + + i = 0; + bptr = strdup(ex); /* No need to free() this */ + if (do_pty == 1) { + /* Setup "slirp.telnetd -x" */ + argv[i++] = "slirp.telnetd"; + argv[i++] = "-x"; + argv[i++] = bptr; + } else + do { + /* Change the string into argv[] */ + curarg = bptr; + while (*bptr != ' ' && *bptr != (char)0) + bptr++; + c = *bptr; + *bptr++ = (char)0; + argv[i++] = strdup(curarg); + } while (c); + + argv[i] = 0; + execvp(argv[0], argv); + + /* Ooops, failed, let's tell the user why */ + { + char buff[256]; + + sprintf(buff, "Error: execvp of %s failed: %s\n", + argv[0], strerror(errno)); + write(2, buff, strlen(buff)+1); + } + close(0); close(1); close(2); /* XXX */ + exit(1); + + default: + if (do_pty == 2) { + close(s); + so->s = master; + } else { + /* + * XXX this could block us... + * XXX Should set a timer here, and if accept() doesn't + * return after X seconds, declare it a failure + * The only reason this will block forever is if socket() + * of connect() fail in the child process + */ + do { + so->s = accept(s, (struct sockaddr *)&addr, &addrlen); + } while (so->s < 0 && errno == EINTR); + closesocket(s); + opt = 1; + setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); + opt = 1; + setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); + } + fd_nonblock(so->s); + + /* Append the telnet options now */ + if (so->so_m != 0 && do_pty == 1) { + sbappend(so, so->so_m); + so->so_m = 0; + } + + return 1; + } +} +#endif + +#ifndef HAVE_STRDUP +char * strdup(char *str) +{ + char *bptr; + + bptr = (char *)malloc(strlen(str)+1); + strcpy(bptr, str); + + return bptr; +} +#endif + +#if 0 +void +snooze_hup(num) + int num; +{ + int s, ret; +#ifndef NO_UNIX_SOCKETS + struct sockaddr_un sock_un; +#endif + struct sockaddr_in sock_in; + char buff[256]; + + ret = -1; + if (slirp_socket_passwd) { + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + slirp_exit(1); + sock_in.sin_family = AF_INET; + sock_in.sin_addr.s_addr = slirp_socket_addr; + sock_in.sin_port = htons(slirp_socket_port); + if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0) + slirp_exit(1); /* just exit...*/ + sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit); + write(s, buff, strlen(buff)+1); + } +#ifndef NO_UNIX_SOCKETS + else { + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) + slirp_exit(1); + sock_un.sun_family = AF_UNIX; + strcpy(sock_un.sun_path, socket_path); + if (connect(s, (struct sockaddr *)&sock_un, + sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0) + slirp_exit(1); + sprintf(buff, "kill none:%d", slirp_socket_unit); + write(s, buff, strlen(buff)+1); + } +#endif + slirp_exit(0); +} + + +void +snooze() +{ + sigset_t s; + int i; + + /* Don't need our data anymore */ + /* XXX This makes SunOS barf */ +/* brk(0); */ + + /* Close all fd's */ + for (i = 255; i >= 0; i--) + close(i); + + signal(SIGQUIT, slirp_exit); + signal(SIGHUP, snooze_hup); + sigemptyset(&s); + + /* Wait for any signal */ + sigsuspend(&s); + + /* Just in case ... */ + exit(255); +} + +void +relay(s) + int s; +{ + char buf[8192]; + int n; + fd_set readfds; + struct ttys *ttyp; + + /* Don't need our data anymore */ + /* XXX This makes SunOS barf */ +/* brk(0); */ + + signal(SIGQUIT, slirp_exit); + signal(SIGHUP, slirp_exit); + signal(SIGINT, slirp_exit); + signal(SIGTERM, slirp_exit); + + /* Fudge to get term_raw and term_restore to work */ + if (NULL == (ttyp = tty_attach (0, slirp_tty))) { + lprint ("Error: tty_attach failed in misc.c:relay()\r\n"); + slirp_exit (1); + } + ttyp->fd = 0; + ttyp->flags |= TTY_CTTY; + term_raw(ttyp); + + while (1) { + FD_ZERO(&readfds); + + FD_SET(0, &readfds); + FD_SET(s, &readfds); + + n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); + + if (n <= 0) + slirp_exit(0); + + if (FD_ISSET(0, &readfds)) { + n = read(0, buf, 8192); + if (n <= 0) + slirp_exit(0); + n = writen(s, buf, n); + if (n <= 0) + slirp_exit(0); + } + + if (FD_ISSET(s, &readfds)) { + n = read(s, buf, 8192); + if (n <= 0) + slirp_exit(0); + n = writen(0, buf, n); + if (n <= 0) + slirp_exit(0); + } + } + + /* Just in case.... */ + exit(1); +} +#endif + +int (*lprint_print) _P((void *, const char *, va_list)); +char *lprint_ptr, *lprint_ptr2, **lprint_arg; + +#ifdef _MSC_VER //aren't we +#define __STDC__ +#endif + +void +#ifdef __STDC__ +lprint(const char *format, ...) +#else +lprint(va_alist) va_dcl +#endif +{ + va_list args; + +#ifdef __STDC__ + va_start(args, format); +#else + char *format; + va_start(args); + format = va_arg(args, char *); +#endif +#if 0 + /* If we're printing to an sbuf, make sure there's enough room */ + /* XXX +100? */ + if (lprint_sb) { + if ((lprint_ptr - lprint_sb->sb_wptr) >= + (lprint_sb->sb_datalen - (strlen(format) + 100))) { + int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data; + int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data; + int deltap = lprint_ptr - lprint_sb->sb_data; + + lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data, + lprint_sb->sb_datalen + TCP_SNDSPACE); + + /* Adjust all values */ + lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw; + lprint_sb->sb_rptr = lprint_sb->sb_data + deltar; + lprint_ptr = lprint_sb->sb_data + deltap; + + lprint_sb->sb_datalen += TCP_SNDSPACE; + } + } +#endif + if (lprint_print) + lprint_ptr += (*lprint_print)(*lprint_arg, format, args); + + /* Check if they want output to be logged to file as well */ + if (lfd) { + /* + * Remove \r's + * otherwise you'll get ^M all over the file + */ + int len = strlen(format); + char *bptr1, *bptr2; + + bptr1 = bptr2 = strdup(format); + + while (len--) { + if (*bptr1 == '\r') + memcpy(bptr1, bptr1+1, len+1); + else + bptr1++; + } + vfprintf(lfd, bptr2, args); + free(bptr2); + } + va_end(args); +} + +void +add_emu(buff) + char *buff; +{ + u_int lport, fport; + u_int8_t tos = 0, emu = 0; + char buff1[256], buff2[256], buff4[128]; + char *buff3 = buff4; + struct emu_t *emup; + struct SLIRPsocket *so; + + if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) { + lprint("Error: Bad arguments\r\n"); + return; + } + + if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) { + lport = 0; + if (sscanf(buff1, "%d", &fport) != 1) { + lprint("Error: Bad first argument\r\n"); + return; + } + } + + if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) { + buff3 = 0; + if (sscanf(buff2, "%256s", buff1) != 1) { + lprint("Error: Bad second argument\r\n"); + return; + } + } + + if (buff3) { + if (strcmp(buff3, "lowdelay") == 0) + tos = IPTOS_LOWDELAY; + else if (strcmp(buff3, "throughput") == 0) + tos = IPTOS_THROUGHPUT; + else { + lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n"); + return; + } + } + + if (strcmp(buff1, "ftp") == 0) + emu = EMU_FTP; + else if (strcmp(buff1, "irc") == 0) + emu = EMU_IRC; + else if (strcmp(buff1, "none") == 0) + emu = EMU_NONE; /* ie: no emulation */ + else { + lprint("Error: Unknown service\r\n"); + return; + } + + /* First, check that it isn't already emulated */ + for (emup = tcpemu; emup; emup = emup->next) { + if (emup->lport == lport && emup->fport == fport) { + lprint("Error: port already emulated\r\n"); + return; + } + } + + /* link it */ + emup = (struct emu_t *)malloc(sizeof (struct emu_t)); + emup->lport = (u_int16_t)lport; + emup->fport = (u_int16_t)fport; + emup->tos = tos; + emup->emu = emu; + emup->next = tcpemu; + tcpemu = emup; + + /* And finally, mark all current sessions, if any, as being emulated */ + for (so = tcb.so_next; so != &tcb; so = so->so_next) { + if ((lport && lport == ntohs(so->so_lport)) || + (fport && fport == ntohs(so->so_fport))) { + if (emu) + so->so_emu = emu; + if (tos) + so->so_iptos = tos; + } + } + + lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); +} + +#ifdef BAD_SPRINTF + +#undef vsprintf +#undef sprintf + +/* + * Some BSD-derived systems have a sprintf which returns char * + */ + +int +vsprintf_len(string, format, args) + char *string; + const char *format; + va_list args; +{ + vsprintf(string, format, args); + return strlen(string); +} + +int +#ifdef __STDC__ +sprintf_len(char *string, const char *format, ...) +#else +sprintf_len(va_alist) va_dcl +#endif +{ + va_list args; +#ifdef __STDC__ + va_start(args, format); +#else + char *string; + char *format; + va_start(args); + string = va_arg(args, char *); + format = va_arg(args, char *); +#endif + vsprintf(string, format, args); + return strlen(string); +} + +#endif + +void +u_sleep(usec) + int usec; +{ + struct timeval t; + fd_set fdset; + + FD_ZERO(&fdset); + + t.tv_sec = 0; + t.tv_usec = usec * 1000; + + select(0, &fdset, &fdset, &fdset, &t); +} + +/* + * Set fd blocking and non-blocking + */ + +void +fd_nonblock(fd) + int fd; +{ +#if defined USE_FIONBIO && defined FIONBIO + ioctlsockopt_t opt = 1; + + ioctlsocket(fd, FIONBIO, &opt); +#else + int opt; + + opt = fcntl(fd, F_GETFL, 0); + opt |= O_NONBLOCK; + fcntl(fd, F_SETFL, opt); +#endif +} + +void +fd_block(fd) + int fd; +{ +#if defined USE_FIONBIO && defined FIONBIO + ioctlsockopt_t opt = 0; + + ioctlsocket(fd, FIONBIO, &opt); +#else + int opt; + + opt = fcntl(fd, F_GETFL, 0); + opt &= ~O_NONBLOCK; + fcntl(fd, F_SETFL, opt); +#endif +} + + +#if 0 +/* + * invoke RSH + */ +int +rsh_exec(so,ns, user, host, args) + struct SLIRPsocket *so; + struct SLIRPsocket *ns; + char *user; + char *host; + char *args; +{ + int fd[2]; + int fd0[2]; + int s; + char buff[256]; + + DEBUG_CALL("rsh_exec"); + DEBUG_ARG("so = %lx", (long)so); + + if (pipe(fd)<0) { + lprint("Error: pipe failed: %s\n", strerror(errno)); + return 0; + } +/* #ifdef HAVE_SOCKETPAIR */ +#if 1 + if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) { + close(fd[0]); + close(fd[1]); + lprint("Error: openpty failed: %s\n", strerror(errno)); + return 0; + } +#else + if (slirp_openpty(&fd0[0], &fd0[1]) == -1) { + close(fd[0]); + close(fd[1]); + lprint("Error: openpty failed: %s\n", strerror(errno)); + return 0; + } +#endif + + switch(fork()) { + case -1: + lprint("Error: fork failed: %s\n", strerror(errno)); + close(fd[0]); + close(fd[1]); + close(fd0[0]); + close(fd0[1]); + return 0; + + case 0: + close(fd[0]); + close(fd0[0]); + + /* Set the DISPLAY */ + if (x_port >= 0) { +#ifdef HAVE_SETENV + sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); + setenv("DISPLAY", buff, 1); +#else + sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); + putenv(buff); +#endif + } + + dup2(fd0[1], 0); + dup2(fd0[1], 1); + dup2(fd[1], 2); + for (s = 3; s <= 255; s++) + close(s); + + execlp("rsh","rsh","-l", user, host, args, NULL); + + /* Ooops, failed, let's tell the user why */ + + sprintf(buff, "Error: execlp of %s failed: %s\n", + "rsh", strerror(errno)); + write(2, buff, strlen(buff)+1); + close(0); close(1); close(2); /* XXX */ + exit(1); + + default: + close(fd[1]); + close(fd0[1]); + ns->s=fd[0]; + so->s=fd0[0]; + + return 1; + } +} +#endif diff --git a/src/slirp/misc.h b/src/slirp/misc.h new file mode 100644 index 0000000..4ab838d --- /dev/null +++ b/src/slirp/misc.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#ifndef _MISC_H_ +#define _MISC_H_ + +struct ex_list { + int ex_pty; /* Do we want a pty? */ + int ex_addr; /* The last byte of the address */ + int ex_fport; /* Port to telnet to */ + char *ex_exec; /* Command line of what to exec */ + struct ex_list *ex_next; +}; + +extern struct ex_list *exec_list; +extern u_int curtime, time_fasttimo, last_slowtimo, detach_time, detach_wait; + +extern int (*lprint_print) _P((void *, const char *, va_list)); +extern char *lprint_ptr, *lprint_ptr2, **lprint_arg; +extern struct sbuf *lprint_sb; + +#ifndef HAVE_STRDUP +char *strdup _P((const char *)); +#endif + +void do_wait _P((int)); + +#define EMU_NONE 0x0 + +/* TCP emulations */ +#define EMU_CTL 0x1 +#define EMU_FTP 0x2 +#define EMU_KSH 0x3 +#define EMU_IRC 0x4 +#define EMU_REALAUDIO 0x5 +#define EMU_RLOGIN 0x6 +#define EMU_IDENT 0x7 +#define EMU_RSH 0x8 + +#define EMU_NOCONNECT 0x10 /* Don't connect */ + +/* UDP emulations */ +#define EMU_TALK 0x1 +#define EMU_NTALK 0x2 +#define EMU_CUSEEME 0x3 + +struct tos_t { + u_int16_t lport; + u_int16_t fport; + u_int8_t tos; + u_int8_t emu; +}; + +struct emu_t { + u_int16_t lport; + u_int16_t fport; + u_int8_t tos; + u_int8_t emu; + struct emu_t *next; +}; + +extern struct emu_t *tcpemu; + +extern int x_port, x_server, x_display; + +int show_x _P((char *, struct SLIRPsocket *)); +void redir_x _P((u_int32_t, int, int, int)); +void getouraddr _P((void)); +void slirp_insque _P((void *, void *)); +void slirp_remque _P((void *)); +int add_exec _P((struct ex_list **, int, char *, int, int)); +int slirp_openpty _P((int *, int *)); +int fork_exec _P((struct SLIRPsocket *, char *, int)); +void snooze_hup _P((int)); +void snooze _P((void)); +void relay _P((int)); +void add_emu _P((char *)); +void u_sleep _P((int)); +void fd_nonblock _P((int)); +void fd_block _P((int)); +int rsh_exec _P((struct SLIRPsocket *, struct SLIRPsocket *, char *, char *, char *)); + +#endif diff --git a/src/slirp/queue.c b/src/slirp/queue.c new file mode 100644 index 0000000..39405dc --- /dev/null +++ b/src/slirp/queue.c @@ -0,0 +1,116 @@ +/* + * File: queue.c + * Author: Robert I. Pitts + * Last Modified: March 9, 2000 + * Topic: Queue - Array Implementation + * ---------------------------------------------------------------- + */ + +#include +#include +#include "queue.h" + +/* + * Constants + * --------- + * MAX_QUEUE_SIZE = Largest number of items queue can hold. + */ + +#define MAX_QUEUE_SIZE 100 + +/* + * struct queueCDT gives the implementation of a queue. + * It holds the information that we need for each queue. + */ +typedef struct queueCDT { + queueElementT contents[MAX_QUEUE_SIZE]; + int front; + int count; +} queueCDT; + +queueADT QueueCreate(void) +{ + queueADT queue; + + queue = (queueADT)malloc(sizeof(queueCDT)); + + if (queue == NULL) { + fprintf(stderr, "Insufficient Memory for new Queue.\n"); + exit(ERROR_MEMORY); /* Exit program, returning error code. */ + } + + queue->front = 0; + queue->count = 0; + + return queue; +} + +void QueueDestroy(queueADT queue) +{ + free(queue); +} + +void QueueEnter(queueADT queue, queueElementT element) +{ + int newElementIndex; + + if (queue->count >= MAX_QUEUE_SIZE) { +// fprintf(stderr, "QueueEnter on Full Queue.\n"); +// exit(ERROR_QUEUE); /* Exit program, returning error code. */ + return; + } + + /* + * Calculate index at which to put + * next element. + */ + newElementIndex = (queue->front + queue->count) + % MAX_QUEUE_SIZE; + queue->contents[newElementIndex] = element; +//printf("element %d, pointer to %d, [%s]\n",newElementIndex,element,element); + + queue->count++; +} + +int QueuePeek(queueADT queue) +{ +return queue->count; +} + +queueElementT QueueDelete(queueADT queue) +{ + queueElementT oldElement; + + if (queue->count <= 0) { + //fprintf(stderr, "QueueDelete on Empty Queue.\n"); + //exit(ERROR_QUEUE); /* Exit program, returning error code. */ + return NULL; + } + + /* Save the element so we can return it. */ + oldElement = queue->contents[queue->front]; + + /* + * Advance the index of the front, + * making sure it wraps around the + * array properly. + */ + queue->front++; + queue->front %= MAX_QUEUE_SIZE; + +//printf("dequing @%d [%s]\n",oldElement,oldElement); + + queue->count--; + + return oldElement; +} + +int QueueIsEmpty(queueADT queue) +{ + return queue->count <= 0; +} + +int QueueIsFull(queueADT queue) +{ + return queue->count >= MAX_QUEUE_SIZE; +} diff --git a/src/slirp/queue.h b/src/slirp/queue.h new file mode 100644 index 0000000..c75ec70 --- /dev/null +++ b/src/slirp/queue.h @@ -0,0 +1,101 @@ +/* + * File: queue.h + * Author: Robert I. Pitts + * Last Modified: March 9, 2000 + * Topic: Queue - Array Implementation + * ---------------------------------------------------------------- + */ + +#ifndef _QUEUE_H +#define _QUEUE_H + +/* + * Constants + * --------- + * ERROR_* These signal error conditions in queue functions + * and are used as exit codes for the program. + */ +#define ERROR_QUEUE 2 +#define ERROR_MEMORY 3 + +/* + * Type: queueElementT + * ------------------- + * This is the type of objects held in the queue. + */ + +/*typedef char queueElementT; +typedef unsigned char *queueElementT; +*/ + +struct queuepacket{ + int len; + unsigned char data[2000]; +}; +typedef struct queuepacket *queueElementT; + +/* + * Type: queueADT + * -------------- + * The actual implementation of a queue is completely + * hidden. Client will work with queueADT which is a + * pointer to underlying queueCDT. + */ + +/* + * NOTE: need word struct below so that the compiler + * knows at least that a queueCDT will be some sort + * of struct. + */ + +typedef struct queueCDT *queueADT; + +/* + * Function: QueueCreate + * Usage: queue = QueueCreate(); + * ------------------------- + * A new empty queue is created and returned. + */ + +queueADT QueueCreate(void); + +/* Function: QueueDestroy + * Usage: QueueDestroy(queue); + * ----------------------- + * This function frees all memory associated with + * the queue. "queue" may not be used again unless + * queue = QueueCreate() is called first. + */ + +void QueueDestroy(queueADT queue); + +/* + * Functions: QueueEnter, QueueDelete + * Usage: QueueEnter(queue, element); + * element = QueueDelete(queue); + * -------------------------------------------- + * These are the fundamental queue operations that enter + * elements in and delete elements from the queue. A call + * to QueueDelete() on an empty queue or to QueueEnter() + * on a full queue is an error. Make use of QueueIsFull() + * and QueueIsEmpty() (see below) to avoid these errors. + */ + +void QueueEnter(queueADT queue, queueElementT element); +queueElementT QueueDelete(queueADT queue); + + +/* + * Functions: QueueIsEmpty, QueueIsFull + * Usage: if (QueueIsEmpty(queue)) ... + * ----------------------------------- + * These return a true/false value based on whether + * the queue is empty or full, respectively. + */ + +int QueueIsEmpty(queueADT queue); +int QueueIsFull(queueADT queue); + +int QueuePeek(queueADT queue); + +#endif /* not defined _QUEUE_H */ diff --git a/src/slirp/sbuf.c b/src/slirp/sbuf.c new file mode 100644 index 0000000..259f627 --- /dev/null +++ b/src/slirp/sbuf.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include +#include "slirp.h" + +/* Done as a macro in socket.h */ +/* int + * sbspace(struct sockbuff *sb) + * { + * return SB_DATALEN - sb->sb_cc; + * } + */ + +void +sbfree(sb) + struct sbuf *sb; +{ + free(sb->sb_data); +} + +void +sbdrop(sb, num) + struct sbuf *sb; + int num; +{ + /* + * We can only drop how much we have + * This should never succeed + */ + if(num > sb->sb_cc) + num = sb->sb_cc; + sb->sb_cc -= num; + sb->sb_rptr += num; + if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen) + sb->sb_rptr -= sb->sb_datalen; + +} + +void +sbreserve(sb, size) + struct sbuf *sb; + int size; +{ + if (sb->sb_data) { + /* Already alloced, realloc if necessary */ + if (sb->sb_datalen != size) { + sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size); + sb->sb_cc = 0; + if (sb->sb_wptr) + sb->sb_datalen = size; + else + sb->sb_datalen = 0; + } + } else { + sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size); + sb->sb_cc = 0; + if (sb->sb_wptr) + sb->sb_datalen = size; + else + sb->sb_datalen = 0; + } +} + +/* + * Try and write() to the socket, whatever doesn't get written + * append to the buffer... for a host with a fast net connection, + * this prevents an unnecessary copy of the data + * (the socket is non-blocking, so we won't hang) + */ +void +sbappend(so, m) + struct SLIRPsocket *so; + struct SLIRPmbuf *m; +{ + int ret = 0; + + DEBUG_CALL("sbappend"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("m->m_len = %d", m->m_len); + + /* Shouldn't happen, but... e.g. foreign host closes connection */ + if (m->m_len <= 0) { + m_free(m); + return; + } + + /* + * If there is urgent data, call sosendoob + * if not all was sent, sowrite will take care of the rest + * (The rest of this function is just an optimisation) + */ + if (so->so_urgc) { + sbappendsb(&so->so_rcv, m); + m_free(m); + sosendoob(so); + return; + } + + /* + * We only write if there's nothing in the buffer, + * ottherwise it'll arrive out of order, and hence corrupt + */ + if (!so->so_rcv.sb_cc) + ret = send(so->s, m->m_data, m->m_len, 0); + + if (ret <= 0) { + /* + * Nothing was written + * It's possible that the socket has closed, but + * we don't need to check because if it has closed, + * it will be detected in the normal way by soread() + */ + sbappendsb(&so->so_rcv, m); + } else if (ret != m->m_len) { + /* + * Something was written, but not everything.. + * sbappendsb the rest + */ + m->m_len -= ret; + m->m_data += ret; + sbappendsb(&so->so_rcv, m); + } /* else */ + /* Whatever happened, we free the SLIRPmbuf */ + m_free(m); +} + +/* + * Copy the data from m into sb + * The caller is responsible to make sure there's enough room + */ +void +sbappendsb(sb, m) + struct sbuf *sb; + struct SLIRPmbuf *m; +{ + int len, n, nn; + + len = m->m_len; + + if (sb->sb_wptr < sb->sb_rptr) { + n = sb->sb_rptr - sb->sb_wptr; + if (n > len) n = len; + memcpy(sb->sb_wptr, m->m_data, n); + } else { + /* Do the right edge first */ + n = sb->sb_data + sb->sb_datalen - sb->sb_wptr; + if (n > len) n = len; + memcpy(sb->sb_wptr, m->m_data, n); + len -= n; + if (len) { + /* Now the left edge */ + nn = sb->sb_rptr - sb->sb_data; + if (nn > len) nn = len; + memcpy(sb->sb_data,m->m_data+n,nn); + n += nn; + } + } + + sb->sb_cc += n; + sb->sb_wptr += n; + if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen) + sb->sb_wptr -= sb->sb_datalen; +} + +/* + * Copy data from sbuf to a normal, straight buffer + * Don't update the sbuf rptr, this will be + * done in sbdrop when the data is acked + */ +void +sbcopy(sb, off, len, to) + struct sbuf *sb; + int off; + int len; + char *to; +{ + char *from; + + from = sb->sb_rptr + off; + if (from >= sb->sb_data + sb->sb_datalen) + from -= sb->sb_datalen; + + if (from < sb->sb_wptr) { + if (len > sb->sb_cc) len = sb->sb_cc; + memcpy(to,from,len); + } else { + /* re-use off */ + off = (sb->sb_data + sb->sb_datalen) - from; + if (off > len) off = len; + memcpy(to,from,off); + len -= off; + if (len) + memcpy(to+off,sb->sb_data,len); + } +} + diff --git a/src/slirp/sbuf.h b/src/slirp/sbuf.h new file mode 100644 index 0000000..eff9481 --- /dev/null +++ b/src/slirp/sbuf.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#ifndef _SBUF_H_ +#define _SBUF_H_ + +#define sbflush(sb) sbdrop((sb),(sb)->sb_cc) +#define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) + +struct sbuf { + u_int sb_cc; /* actual chars in buffer */ + u_int sb_datalen; /* Length of data */ + char *sb_wptr; /* write pointer. points to where the next + * bytes should be written in the sbuf */ + char *sb_rptr; /* read pointer. points to where the next + * byte should be read from the sbuf */ + char *sb_data; /* Actual data */ +}; + +void sbfree _P((struct sbuf *)); +void sbdrop _P((struct sbuf *, int)); +void sbreserve _P((struct sbuf *, int)); +void sbappend _P((struct SLIRPsocket *, struct SLIRPmbuf *)); +void sbappendsb _P((struct sbuf *, struct SLIRPmbuf *)); +void sbcopy _P((struct sbuf *, int, int, char *)); + +#endif diff --git a/src/slirp/slirp.c b/src/slirp/slirp.c new file mode 100644 index 0000000..1ac66ae --- /dev/null +++ b/src/slirp/slirp.c @@ -0,0 +1,682 @@ +#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; + +const uint8_t special_ethaddr[6] = { + 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 +}; + +uint8_t client_ethaddr[6]; + +int do_slowtimo; +int link_up; +struct timeval tt; +FILE *lfd; +struct ex_list *exec_list; + +/* XXX: suppress those select globals */ +fd_set *global_readfds, *global_writefds, *global_xfds; + +char slirp_hostname[33]; + +#ifdef _WIN32 + +static int get_dns_addr(struct in_addr *pdns_addr) +{ + FIXED_INFO *FixedInfo=NULL; + ULONG BufLen; + DWORD ret; + IP_ADDR_STRING *pIPAddr; + struct in_addr tmp_addr; + + FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); + BufLen = sizeof(FIXED_INFO); + + if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &BufLen)) { + if (FixedInfo) { + GlobalFree(FixedInfo); + FixedInfo = NULL; + } + FixedInfo = GlobalAlloc(GPTR, BufLen); + } + + if ((ret = GetNetworkParams(FixedInfo, &BufLen)) != ERROR_SUCCESS) { + printf("GetNetworkParams failed. ret = %08x\n", (u_int)ret ); + if (FixedInfo) { + GlobalFree(FixedInfo); + FixedInfo = NULL; + } + return -1; + } + + pIPAddr = &(FixedInfo->DnsServerList); + inet_aton(pIPAddr->IpAddress.String, &tmp_addr); + *pdns_addr = tmp_addr; +#if 0 + printf( "DNS Servers:\n" ); + printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); + + pIPAddr = FixedInfo -> DnsServerList.Next; + while ( pIPAddr ) { + printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String ); + pIPAddr = pIPAddr ->Next; + } +#endif + if (FixedInfo) { + GlobalFree(FixedInfo); + FixedInfo = NULL; + } + return 0; +} + +#else + +static int get_dns_addr(struct in_addr *pdns_addr) +{ + char buff[512]; + char buff2[256]; + FILE *f; + int found = 0; + struct in_addr tmp_addr; + + f = fopen("/etc/resolv.conf", "r"); + if (!f) + return -1; + + lprint("IP address of your DNS(s): "); + while (fgets(buff, 512, f) != NULL) { + if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { + if (!inet_aton(buff2, &tmp_addr)) + continue; + if (tmp_addr.s_addr == loopback_addr.s_addr) + tmp_addr = our_addr; + /* If it's the first one, set it to dns_addr */ + if (!found) + *pdns_addr = tmp_addr; + else + lprint(", "); + if (++found > 3) { + lprint("(more)"); + break; + } else + lprint("%s", inet_ntoa(tmp_addr)); + } + } + fclose(f); + if (!found) + return -1; + return 0; +} + +#endif + +#ifdef _WIN32 +void slirp_cleanup(void) +{ + WSACleanup(); +} +#endif + +int slirp_init(void) +{ +#ifdef SLIRP_DEBUG + // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); + // debug_init("slirplog.txt",DEBUG_DEFAULT); + //debug_init("slirplog.txt",DBG_CALL); +debug_init("slirplog.txt",DEBUG_DEFAULT); +#endif + +#ifdef _WIN32 + { + WSADATA Data; + WSAStartup(MAKEWORD(2,0), &Data); + atexit(slirp_cleanup); + } +#endif + + link_up = 1; + + if_init(); + ip_init(); + + /* Initialise mbufs *after* setting the MTU */ + m_init(); + + /* set default addresses */ + inet_aton("127.0.0.1", &loopback_addr); + + if (get_dns_addr(&dns_addr) < 0) + return -1; + + inet_aton(CTL_SPECIAL, &special_addr); + alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + getouraddr(); + return 0; +} + +#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) +#define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) +#define UPD_NFDS(x) if (nfds < (x)) nfds = (x) + +/* + * curtime kept to an accuracy of 1ms + */ +#ifdef _WIN32 +static void updtime(void) +{ + struct _timeb tb; + + _ftime(&tb); + curtime = (u_int)tb.time * (u_int)1000; + curtime += (u_int)tb.millitm; +} +#else +static void updtime(void) +{ + gettimeofday(&tt, 0); + + curtime = (u_int)tt.tv_sec * (u_int)1000; + curtime += (u_int)tt.tv_usec / (u_int)1000; + + if ((tt.tv_usec % 1000) >= 500) + curtime++; +} +#endif + +int slirp_select_fill(int *pnfds, + fd_set *readfds, fd_set *writefds, fd_set *xfds) +{ + struct SLIRPsocket *so, *so_next; + int nfds; + int timeout, tmp_time; + + /* fail safe */ + global_readfds = NULL; + global_writefds = NULL; + global_xfds = NULL; + + nfds = *pnfds; + /* + * First, TCP sockets + */ + do_slowtimo = 0; + if (link_up) { + /* + * *_slowtimo needs calling if there are IP fragments + * in the fragment queue, or there are TCP connections active + */ + do_slowtimo = ((tcb.so_next != &tcb) || + ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); + + for (so = tcb.so_next; (so != &tcb); so = so_next) { + so_next = so->so_next; + + + /* + * See if we need a tcp_fasttimo + */ + if(&so->so_tcpcb->t_flags!=0x0){ //This is to prevent a common lockup. + if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK) + time_fasttimo = curtime; }/* Flag when we want a fasttimo */ + + + /* + * NOFDREF can include still connecting to local-host, + * newly socreated() sockets etc. Don't want to select these. + */ + if (so->so_state & SS_NOFDREF || so->s == -1) + continue; + + /* + * Set for reading sockets which are accepting + */ + if (so->so_state & SS_FACCEPTCONN) { + FD_SET(so->s, readfds); + UPD_NFDS(so->s); + continue; + } + + /* + * Set for writing sockets which are connecting + */ + if (so->so_state & SS_ISFCONNECTING) { + FD_SET(so->s, writefds); + UPD_NFDS(so->s); + continue; + } + + /* + * Set for writing if we are connected, can send more, and + * we have something to send + */ + if (CONN_CANFSEND(so) && so->so_rcv.sb_cc) { + FD_SET(so->s, writefds); + UPD_NFDS(so->s); + } + + /* + * Set for reading (and urgent data) if we are connected, can + * receive more, and we have room for it XXX /2 ? + */ + if (CONN_CANFRCV(so) && (so->so_snd.sb_cc < (so->so_snd.sb_datalen/2))) { + FD_SET(so->s, readfds); + FD_SET(so->s, xfds); + UPD_NFDS(so->s); + } + } + + /* + * UDP sockets + */ + for (so = udb.so_next; so != &udb; so = so_next) { + so_next = so->so_next; + + /* + * See if it's timed out + */ + if (so->so_expire) { + if (so->so_expire <= curtime) { + udp_detach(so); + continue; + } else + do_slowtimo = 1; /* Let socket expire */ + } + + /* + * When UDP packets are received from over the + * link, they're sendto()'d straight away, so + * no need for setting for writing + * Limit the number of packets queued by this session + * to 4. Note that even though we try and limit this + * to 4 packets, the session could have more queued + * if the packets needed to be fragmented + * (XXX <= 4 ?) + */ + if ((so->so_state & SS_ISFCONNECTED) && so->so_queued <= 4) { + FD_SET(so->s, readfds); + UPD_NFDS(so->s); + } + } + } + + /* + * Setup timeout to use minimum CPU usage, especially when idle + */ + + timeout = -1; + + /* + * If a slowtimo is needed, set timeout to 5ms from the last + * slow timeout. If a fast timeout is needed, set timeout within + * 2ms of when it was requested. + */ +# define SLOW_TIMO 5 +# define FAST_TIMO 2 + if (do_slowtimo) { + timeout = (SLOW_TIMO - (curtime - last_slowtimo)) * 1000; + if (timeout < 0) + timeout = 0; + else if (timeout > (SLOW_TIMO * 1000)) + timeout = SLOW_TIMO * 1000; + + /* Can only fasttimo if we also slowtimo */ + if (time_fasttimo) { + tmp_time = (FAST_TIMO - (curtime - time_fasttimo)) * 1000; + if (tmp_time < 0) + tmp_time = 0; + + /* Choose the smallest of the 2 */ + if (tmp_time < timeout) + timeout = tmp_time; + } + } + *pnfds = nfds; + + /* + * Adjust the timeout to make the minimum timeout + * 2ms (XXX?) to lessen the CPU load + */ + if (timeout < (FAST_TIMO * 1000)) + timeout = FAST_TIMO * 1000; + + return timeout; +} + +void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) +{ + struct SLIRPsocket *so, *so_next; + int ret; + + global_readfds = readfds; + global_writefds = writefds; + global_xfds = xfds; + + /* Update time */ + updtime(); + + /* + * See if anything has timed out + */ + if (link_up) { + if (time_fasttimo && ((curtime - time_fasttimo) >= FAST_TIMO)) { + tcp_fasttimo(); + time_fasttimo = 0; + } + if (do_slowtimo && ((curtime - last_slowtimo) >= SLOW_TIMO)) { + ip_slowtimo(); + tcp_slowtimo(); + last_slowtimo = curtime; + } + } + + /* + * Check sockets + */ + if (link_up) { + /* + * Check TCP sockets + */ + for (so = tcb.so_next; so != &tcb; so = so_next) { + so_next = so->so_next; + + /* + * FD_ISSET is meaningless on these sockets + * (and they can crash the program) + */ + if (so->so_state & SS_NOFDREF || so->s == -1) + continue; + + /* + * Check for URG data + * This will soread as well, so no need to + * test for readfds below if this succeeds + */ + if (FD_ISSET(so->s, xfds)) + sorecvoob(so); + /* + * Check sockets for reading + */ + else if (FD_ISSET(so->s, readfds)) { + /* + * Check for incoming connections + */ + if (so->so_state & SS_FACCEPTCONN) { + tcp_connect(so); + continue; + } /* else */ + ret = soread(so); + + /* Output it if we read something */ + if (ret > 0) + tcp_output(sototcpcb(so)); + } + + /* + * Check sockets for writing + */ + if (FD_ISSET(so->s, writefds)) { + /* + * Check for non-blocking, still-connecting sockets + */ + if (so->so_state & SS_ISFCONNECTING) { + /* Connected */ + so->so_state &= ~SS_ISFCONNECTING; + + //ret = send(so->s, &ret, 0, 0); + //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. + if (ret < 0) { + /* XXXXX Must fix, zero bytes is a NOP */ + if (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINPROGRESS || errno == ENOTCONN) + continue; + + /* else failed */ + so->so_state = SS_NOFDREF; + } + /* else so->so_state &= ~SS_ISFCONNECTING; */ + + /* + * Continue tcp_input + */ + tcp_input((struct SLIRPmbuf *)NULL, sizeof(struct ip), so); + /* continue; */ + } else + ret = sowrite(so); + /* + * XXXXX If we wrote something (a lot), there + * could be a need for a window update. + * In the worst case, the remote will send + * a window probe to get things going again + */ + } + + /* + * Probe a still-connecting, non-blocking socket + * to check if it's still alive + */ +#ifdef PROBE_CONN + if (so->so_state & SS_ISFCONNECTING) { + ret = recv(so->s, (char *)&ret, 0,0); + + if (ret < 0) { + /* XXX */ + if (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINPROGRESS || errno == ENOTCONN) + continue; /* Still connecting, continue */ + + /* else failed */ + so->so_state = SS_NOFDREF; + + /* tcp_input will take care of it */ + } else { + ret = send(so->s, &ret, 0,0); + if (ret < 0) { + /* XXX */ + if (errno == EAGAIN || errno == EWOULDBLOCK || + errno == EINPROGRESS || errno == ENOTCONN) + continue; + /* else failed */ + so->so_state = SS_NOFDREF; + } else + so->so_state &= ~SS_ISFCONNECTING; + + } + tcp_input((struct SLIRPmbuf *)NULL, sizeof(struct ip),so); + } /* SS_ISFCONNECTING */ +#endif + } + + /* + * Now UDP sockets. + * Incoming packets are sent straight away, they're not buffered. + * Incoming UDP data isn't buffered either. + */ + for (so = udb.so_next; so != &udb; so = so_next) { + so_next = so->so_next; + + if (so->s != -1 && FD_ISSET(so->s, readfds)) { + sorecvfrom(so); + } + } + } + + /* + * See if we can start outputting + */ + if (if_queued && link_up) + if_start(); + + /* clear global file descriptor sets. + * these reside on the stack in vl.c + * so they're unusable if we're not in + * slirp_select_fill or slirp_select_poll. + */ + global_readfds = NULL; + global_writefds = NULL; + global_xfds = NULL; +} + +#define ETH_ALEN 6 +#define ETH_HLEN 14 + +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ + +#define ARPOP_REQUEST 1 /* ARP request */ +#define ARPOP_REPLY 2 /* ARP reply */ + +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +}; + +struct arphdr +{ + unsigned short ar_hrd; /* format of hardware address */ + unsigned short ar_pro; /* format of protocol address */ + unsigned char ar_hln; /* length of hardware address */ + unsigned char ar_pln; /* length of protocol address */ + unsigned short ar_op; /* ARP opcode (command) */ + + /* + * Ethernet looks like this : This bit is variable sized however... + */ + unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ + unsigned char ar_sip[4]; /* sender IP address */ + unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ + unsigned char ar_tip[4]; /* target IP address */ +}; + +void arp_input(const uint8_t *pkt, int pkt_len) +{ + struct ethhdr *eh = (struct ethhdr *)pkt; + struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN); + uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)]; + struct ethhdr *reh = (struct ethhdr *)arp_reply; + struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN); + int ar_op; + struct ex_list *ex_ptr; + + ar_op = ntohs(ah->ar_op); + switch(ar_op) { + case ARPOP_REQUEST: + if (!memcmp(ah->ar_tip, &special_addr, 3)) { + if (ah->ar_tip[3] == CTL_DNS || ah->ar_tip[3] == CTL_ALIAS) + goto arp_ok; + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { + if (ex_ptr->ex_addr == ah->ar_tip[3]) + goto arp_ok; + } + return; + arp_ok: + /* XXX: make an ARP request to have the client address */ + memcpy(client_ethaddr, eh->h_source, ETH_ALEN); + + /* ARP request for alias/dns mac address */ + memcpy(reh->h_dest, pkt + ETH_ALEN, ETH_ALEN); + memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1); + reh->h_source[5] = ah->ar_tip[3]; + reh->h_proto = htons(ETH_P_ARP); + + rah->ar_hrd = htons(1); + rah->ar_pro = htons(ETH_P_IP); + rah->ar_hln = ETH_ALEN; + rah->ar_pln = 4; + rah->ar_op = htons(ARPOP_REPLY); + memcpy(rah->ar_sha, reh->h_source, ETH_ALEN); + memcpy(rah->ar_sip, ah->ar_tip, 4); + memcpy(rah->ar_tha, ah->ar_sha, ETH_ALEN); + memcpy(rah->ar_tip, ah->ar_sip, 4); + slirp_output(arp_reply, sizeof(arp_reply)); + } + break; + default: + break; + } +} + +void slirp_input(const uint8_t *pkt, int pkt_len) +{ + struct SLIRPmbuf *m; + int proto; + + if (pkt_len < ETH_HLEN) + return; + + proto = (pkt[12] << 8) | pkt[13]; + switch(proto) { + case ETH_P_ARP: + arp_input(pkt, pkt_len); + break; + case ETH_P_IP: + m = m_get(); + if (!m) + return; + /* Note: we add to align the IP header */ + m->m_len = pkt_len + 2; + memcpy(m->m_data + 2, pkt, pkt_len); + + m->m_data += 2 + ETH_HLEN; + m->m_len -= 2 + ETH_HLEN; + + ip_input(m); + break; + default: + break; + } +} + +/* output the IP packet to the ethernet device */ +void if_encap(const uint8_t *ip_data, int ip_data_len) +{ + uint8_t buf[1600]; + struct ethhdr *eh = (struct ethhdr *)buf; + + if (ip_data_len + ETH_HLEN > sizeof(buf)) + return; + + memcpy(eh->h_dest, client_ethaddr, ETH_ALEN); + memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1); + /* XXX: not correct */ + eh->h_source[5] = CTL_ALIAS; + eh->h_proto = htons(ETH_P_IP); + memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); + slirp_output(buf, ip_data_len + ETH_HLEN); +} + +int slirp_redir(int is_udp, int host_port, + struct in_addr guest_addr, int guest_port) +{ + if (is_udp) { + if (!udp_listen(htons(host_port), guest_addr.s_addr, + htons(guest_port), 0)) + return -1; + } else { + if (!solisten(htons(host_port), guest_addr.s_addr, + htons(guest_port), 0)) + return -1; + } + return 0; +} + +int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, + int guest_port) +{ + return add_exec(&exec_list, do_pty, (char *)args, + addr_low_byte, htons(guest_port)); +} diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h new file mode 100644 index 0000000..83a1b6d --- /dev/null +++ b/src/slirp/slirp.h @@ -0,0 +1,415 @@ +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#define SLIRP_VERSION "Cockatrice special" + +#define CONFIG_QEMU + +#ifndef CONFIG_QEMU +#include "version.h" +#endif +#include "config.h" +#include "slirp_config.h" + +#ifdef _WIN32 +#ifdef __GNUC__ //MINGW? +# include +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; +typedef char *SLIRPcaddr_t; +typedef int socklen_t; +typedef unsigned long ioctlsockopt_t; +#else +typedef unsigned char u_int8_t; +typedef char int8_t; +typedef unsigned char uint8_t; +typedef unsigned short u_int16_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned int u_int32_t; +typedef unsigned int uint32_t; +typedef int int32_t; + +typedef unsigned __int64 u_int64_t; +typedef char *SLIRPcaddr_t; +typedef int socklen_t; +typedef unsigned long ioctlsockopt_t; + +#endif + +# include //needs to be on top otherwise, it'll pull in winsock1 +# include + +# include +# include + +# define USE_FIONBIO 1 +# define EWOULDBLOCK WSAEWOULDBLOCK +# define EINPROGRESS WSAEINPROGRESS +# define ENOTCONN WSAENOTCONN +# define EHOSTUNREACH WSAEHOSTUNREACH +# define ENETUNREACH WSAENETUNREACH +# define ECONNREFUSED WSAECONNREFUSED + +/* Basilisk II Router defines those */ +# define udp_read_completion slirp_udp_read_completion +# define write_udp slirp_write_udp +# define init_udp slirp_init_udp +# define final_udp slirp_final_udp +#else +typedef int ioctlsockopt_t; +# define ioctlsocket ioctl +# define closesocket(s) close(s) +# define O_BINARY 0 +#endif + +#include +#ifdef HAVE_SYS_BITYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif + +#ifndef _MSC_VER +#include +#else +#include +#endif + +#ifdef NEED_TYPEDEFS +typedef char int8_t; +typedef unsigned char u_int8_t; + +# if SIZEOF_SHORT == 2 + typedef short int16_t; + typedef unsigned short u_int16_t; +# else +# if SIZEOF_INT == 2 + typedef int int16_t; + typedef unsigned int u_int16_t; +# else + #error Cannot find a type with sizeof() == 2 +# endif +# endif + +# if SIZEOF_SHORT == 4 + typedef short int32_t; + typedef unsigned short u_int32_t; +# else +# if SIZEOF_INT == 4 + typedef int int32_t; + typedef unsigned int u_int32_t; +# else + #error Cannot find a type with sizeof() == 4 +# endif +# endif +#endif /* NEED_TYPEDEFS */ + +/* Basilisk II types glue */ +typedef u_int8_t uint8; +typedef u_int16_t uint16; +typedef u_int32_t uint32; + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE_STDLIB_H +# include +#endif + +#include +#include + +#ifndef HAVE_MEMMOVE +#define memmove(x, y, z) bcopy(y, x, z) +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifdef HAVE_STRING_H +# include +#else +#ifndef _MSC_VER +# include +#else +#include +#endif +#endif + +#ifndef _WIN32 +#include +#endif + +#ifndef _P +#ifndef NO_PROTOTYPES +# define _P(x) x +#else +# define _P(x) () +#endif +#endif + +#ifndef _WIN32 +#include +#include +#endif + +#ifdef GETTIMEOFDAY_ONE_ARG +#define gettimeofday(x, y) gettimeofday(x) +#endif + +/* Systems lacking strdup() definition in . */ +#if defined(ultrix) +char *strdup _P((const char *)); +#endif + +/* Systems lacking malloc() definition in . */ +#if defined(ultrix) || defined(hcx) +void *malloc _P((size_t arg)); +void free _P((void *ptr)); +#endif + +#ifndef HAVE_INET_ATON +int inet_aton _P((const char *cp, struct in_addr *ia)); +#endif + +#include +#ifndef NO_UNIX_SOCKETS +#include +#endif +#include +#ifdef HAVE_SYS_SIGNAL_H +# include +#endif +#ifndef _WIN32 +#include +#endif + +#if defined(HAVE_SYS_IOCTL_H) +# include +#endif + +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#ifdef HAVE_SYS_WAIT_H +# include +#endif + +#ifdef HAVE_SYS_FILIO_H +# include +#endif + +#ifdef USE_PPP +#include +#endif + +#ifdef __STDC__ +#include +#else +#include +#endif + +#include + +/* Avoid conflicting with the libc insque() and remque(), which + have different prototypes. */ +#define insque slirp_insque +#define remque slirp_remque + +#ifdef HAVE_SYS_STROPTS_H +#include +#endif + +#include "debug.h" + +#if defined __GNUC__ +#define PACKED__ __attribute__ ((packed)) +#elif defined __sgi +#define PRAGMA_PACK_SUPPORTED 1 +#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" +#endif + +#if defined(_MSC_VER) +#pragma pack(push, 1) +#endif + +#include "ip.h" +#include "tcp.h" +#include "tcp_timer.h" +#include "tcp_var.h" +#include "tcpip.h" +#include "udp.h" +#include "icmp_var.h" +#include "mbuf.h" +#include "sbuf.h" +#include "socket.h" +#include "if.h" +#include "main.h" +#include "misc.h" +#include "ctl.h" +#ifdef USE_PPP +#include "ppp/pppd.h" +#include "ppp/ppp.h" +#endif + +#include "bootp.h" +#include "tftp.h" +#include "libslirp.h" + +extern struct ttys *ttys_unit[MAX_INTERFACES]; + +#ifndef NULL +#define NULL (void *)0 +#endif + +#ifndef FULL_BOLT +void if_start _P((void)); +#else +void if_start _P((struct ttys *)); +#endif + +#ifdef BAD_SPRINTF +# define vsprintf vsprintf_len +# define sprintf sprintf_len + extern int vsprintf_len _P((char *, const char *, va_list)); + extern int sprintf_len _P((char *, const char *, ...)); +#endif + +#ifdef DECLARE_SPRINTF +# ifndef BAD_SPRINTF + extern int vsprintf _P((char *, const char *, va_list)); +# endif + extern int vfprintf _P((FILE *, const char *, va_list)); +#endif + +#ifndef HAVE_STRERROR +#ifndef _MSC_VER + extern char *strerror _P((int error)); + #define HAVE_STRERROR +#endif +#endif + +#ifndef HAVE_INDEX + char *index _P((const char *, int)); +#endif + +#ifndef HAVE_GETHOSTID + long gethostid _P((void)); +#endif + +void lprint _P((const char *, ...)); + +extern int do_echo; + +#ifdef _MSC_VER +#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 *)); +#endif + +#ifndef _WIN32 +#include +#endif + +#define DEFAULT_BAUD 115200 + +/* cksum.c */ +int cksum(struct SLIRPmbuf *m, int len); + +/* if.c */ +void if_init _P((void)); +void if_output _P((struct SLIRPsocket *, struct SLIRPmbuf *)); + +/* ip_input.c */ +void ip_init _P((void)); +void ip_input _P((struct SLIRPmbuf *)); +struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *)); +void ip_freef _P((struct ipq *)); +void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *)); +void ip_deq _P((register struct ipasfrag *)); +void ip_slowtimo _P((void)); +void ip_stripoptions _P((register struct SLIRPmbuf *, struct SLIRPmbuf *)); + +/* ip_output.c */ +int ip_output _P((struct SLIRPsocket *, struct SLIRPmbuf *)); + +/* tcp_input.c */ +int tcp_reass _P((register struct tcpcb *, register struct tcpiphdr *, struct SLIRPmbuf *)); +void tcp_input _P((register struct SLIRPmbuf *, int, struct SLIRPsocket *)); +void tcp_dooptions _P((struct tcpcb *, u_char *, int, struct tcpiphdr *)); +void tcp_xmit_timer _P((register struct tcpcb *, int)); +int tcp_mss _P((register struct tcpcb *, u_int)); + +/* tcp_output.c */ +int tcp_output _P((register struct tcpcb *)); +void tcp_setpersist _P((register struct tcpcb *)); + +/* tcp_subr.c */ +void tcp_init _P((void)); +void tcp_template _P((struct tcpcb *)); +void tcp_respond _P((struct tcpcb *, register struct tcpiphdr *, register struct SLIRPmbuf *, tcp_seq, tcp_seq, int)); +struct tcpcb * tcp_newtcpcb _P((struct SLIRPsocket *)); +struct tcpcb * tcp_close _P((register struct tcpcb *)); +void tcp_drain _P((void)); +void tcp_sockclosed _P((struct tcpcb *)); +int tcp_fconnect _P((struct SLIRPsocket *)); +void tcp_connect _P((struct SLIRPsocket *)); +int tcp_attach _P((struct SLIRPsocket *)); +u_int8_t tcp_tos _P((struct SLIRPsocket *)); +int tcp_emu _P((struct SLIRPsocket *, struct SLIRPmbuf *)); +int tcp_ctl _P((struct SLIRPsocket *)); +struct tcpcb *tcp_drop(struct tcpcb *tp, int err); + + +#if defined(_MSC_VER) +#pragma pack(pop) +#endif + +#ifdef USE_PPP +#define MIN_MRU MINMRU +#define MAX_MRU MAXMRU +#else +#define MIN_MRU 128 +#define MAX_MRU 16384 +#endif + +#ifndef _WIN32 +#define min(x,y) ((x) < (y) ? (x) : (y)) +#define max(x,y) ((x) > (y) ? (x) : (y)) +#endif + +#ifdef _WIN32 +#undef errno +#define errno (WSAGetLastError()) +#endif + +#define PROBE_CONN + +#endif diff --git a/src/slirp/slirp_config.h b/src/slirp/slirp_config.h new file mode 100644 index 0000000..850ddee --- /dev/null +++ b/src/slirp/slirp_config.h @@ -0,0 +1,135 @@ +/* + * User definable configuration options + */ + +/* Undefine if you don't want talk emulation */ +#undef EMULATE_TALK + +/* Define if you want the connection to be probed */ +/* XXX Not working yet, so ignore this for now */ +#undef PROBE_CONN + +/* Define to 1 if you want KEEPALIVE timers */ +#define DO_KEEPALIVE 0 + +/* Define to MAX interfaces you expect to use at once */ +/* MAX_INTERFACES determines the max. TOTAL number of interfaces (SLIP and PPP) */ +/* MAX_PPP_INTERFACES determines max. number of PPP interfaces */ +#define MAX_INTERFACES 1 +#define MAX_PPP_INTERFACES 1 + +/* Define if you want slirp's socket in /tmp */ +/* XXXXXX Do this in ./configure */ +#undef USE_TMPSOCKET + +/* Define if you want slirp to use cfsetXspeed() on the terminal */ +#undef DO_CFSETSPEED + +/* Define this if you want slirp to write to the tty as fast as it can */ +/* This should only be set if you are using load-balancing, slirp does a */ +/* pretty good job on single modems already, and seting this will make */ +/* interactive sessions less responsive */ +/* XXXXX Talk about having fast modem as unit 0 */ +#undef FULL_BOLT + +/* + * Define if you want slirp to use less CPU + * You will notice a small lag in interactive sessions, but it's not that bad + * Things like Netscape/ftp/etc. are completely unaffected + * This is mainly for sysadmins who have many slirp users + */ +#undef USE_LOWCPU + +/* Define this if your compiler doesn't like prototypes */ +#ifndef __STDC__ +#define NO_PROTOTYPES +#endif + +/*********************************************************/ +/* + * Autoconf defined configuration options + * You shouldn't need to touch any of these + */ + +/* Ignore this */ +#undef DUMMY_PPP + +/* XXX: Define according to how time.h should be included */ +#undef TIME_WITH_SYS_TIME +#define TIME_WITH_SYS_TIME 0 +#undef HAVE_SYS_TIME_H + +/* Define if your sprintf returns char * instead of int */ +#undef BAD_SPRINTF + +/* Define if you have readv */ +#undef HAVE_READV + +/* Define if iovec needs to be declared */ +#undef DECLARE_IOVEC +#ifdef _WIN32 +#define DECLARE_IOVEC +#endif + +/* Define if a declaration of sprintf/fprintf is needed */ +#undef DECLARE_SPRINTF + +/* Define if you have sys/stropts.h */ +#undef HAVE_SYS_STROPTS_H + +/* Define if your compiler doesn't like prototypes */ +#undef NO_PROTOTYPES + +/* Define if you don't have u_int32_t etc. typedef'd */ +#undef NEED_TYPEDEFS +#ifdef __sun__ +#define NEED_TYPEDEFS +#endif + +/* Define to sizeof(char *) */ +#define SIZEOF_CHAR_P SIZEOF_VOID_P + +/* Define if you have random() */ +#undef HAVE_RANDOM + +/* Define if you have srandom() */ +#undef HAVE_SRANDOM + +/* Define if you have setenv */ +#undef HAVE_SETENV + +/* Define if you have index() */ +#undef HAVE_INDEX + +/* Define if you have bcmp() */ +#undef HAVE_BCMP + +/* Define if you have drand48 */ +#undef HAVE_DRAND48 + +/* Define if you have memmove */ +#define HAVE_MEMMOVE + +/* Define if you have gethostid */ +#undef HAVE_GETHOSTID + +/* Define if you DON'T have unix-domain sockets */ +#undef NO_UNIX_SOCKETS +#ifdef _WIN32 +#define NO_UNIX_SOCKETS +#endif + +/* Define if gettimeofday only takes one argument */ +#undef GETTIMEOFDAY_ONE_ARG + +/* Define if you have revoke() */ +#undef HAVE_REVOKE + +/* Define if you have the sysv method of opening pty's (/dev/ptmx, etc.) */ +#undef HAVE_GRANTPT + +/* Define if you have fchmod */ +#undef HAVE_FCHMOD + +/* Define if you have */ +#undef HAVE_SYS_TYPES32_H diff --git a/src/slirp/socket.c b/src/slirp/socket.c new file mode 100644 index 0000000..604c2bf --- /dev/null +++ b/src/slirp/socket.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#define WANT_SYS_IOCTL_H +#include +#include "slirp.h" +#include "ip_icmp.h" +#include "main.h" +#ifdef __sun__ +#include +#endif + +#ifndef FIONREAD +#include +#endif + +void +so_init() +{ + /* Nothing yet */ +} + + +struct SLIRPsocket * +solookup(head, laddr, lport, faddr, fport) + struct SLIRPsocket *head; + struct in_addr laddr; + u_int lport; + struct in_addr faddr; + u_int fport; +{ + struct SLIRPsocket *so; + + for (so = head->so_next; so != head; so = so->so_next) { + if (so->so_lport == lport && + so->so_laddr.s_addr == laddr.s_addr && + so->so_faddr.s_addr == faddr.s_addr && + so->so_fport == fport) + break; + } + + if (so == head) + return (struct SLIRPsocket *)NULL; + return so; + +} + +/* + * Create a new socket, initialise the fields + * It is the responsibility of the caller to + * insque() it into the correct linked-list + */ +struct SLIRPsocket * +socreate() +{ + struct SLIRPsocket *so; + + so = (struct SLIRPsocket *)malloc(sizeof(struct SLIRPsocket)); + if(so) { + memset(so, 0, sizeof(struct SLIRPsocket)); + so->so_state = SS_NOFDREF; + so->s = -1; + } + return(so); +} + +/* + * remque and free a socket, clobber cache + */ +void +sofree(so) + struct SLIRPsocket *so; +{ + if (so->so_emu==EMU_RSH && so->extra) { + sofree(so->extra); + so->extra=NULL; + } + if (so == tcp_last_so) + tcp_last_so = &tcb; + else if (so == udp_last_so) + udp_last_so = &udb; + + if(so->so_m!=NULL) + m_free(so->so_m); + + if(so->so_next && so->so_prev) + remque(so); /* crashes if so is not in a queue */ + + free(so); +} + +/* + * Read from so's socket into sb_snd, updating all relevant sbuf fields + * NOTE: This will only be called if it is select()ed for reading, so + * a read() of 0 (or less) means it's disconnected + */ +int +soread(so) + struct SLIRPsocket *so; +{ + int n, nn, lss, total; + struct sbuf *sb = &so->so_snd; + int len = sb->sb_datalen - sb->sb_cc; + struct iovec iov[2]; + int mss; + if(!so->so_tcpcb) + return 0; + + mss = so->so_tcpcb->t_maxseg; + + DEBUG_CALL("soread"); + DEBUG_ARG("so = %lx", (long )so); + + /* + * No need to check if there's enough room to read. + * soread wouldn't have been called if there weren't + */ + + len = sb->sb_datalen - sb->sb_cc; + + iov[0].iov_base = sb->sb_wptr; + if (sb->sb_wptr < sb->sb_rptr) { + iov[0].iov_len = sb->sb_rptr - sb->sb_wptr; + /* Should never succeed, but... */ + if (iov[0].iov_len > len) + iov[0].iov_len = len; + if (iov[0].iov_len > mss) + iov[0].iov_len -= iov[0].iov_len%mss; + n = 1; + } else { + iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr; + /* Should never succeed, but... */ + if (iov[0].iov_len > len) iov[0].iov_len = len; + len -= iov[0].iov_len; + if (len) { + iov[1].iov_base = sb->sb_data; + iov[1].iov_len = sb->sb_rptr - sb->sb_data; + if(iov[1].iov_len > len) + iov[1].iov_len = len; + total = iov[0].iov_len + iov[1].iov_len; + if (total > mss) { + lss = total%mss; + if (iov[1].iov_len > lss) { + iov[1].iov_len -= lss; + n = 2; + } else { + lss -= iov[1].iov_len; + iov[0].iov_len -= lss; + n = 1; + } + } else + n = 2; + } else { + if (iov[0].iov_len > mss) + iov[0].iov_len -= iov[0].iov_len%mss; + n = 1; + } + } + +#ifdef HAVE_READV + nn = readv(so->s, (struct iovec *)iov, n); + DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); +#else + nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0); +#endif + if (nn <= 0) { + if (nn < 0 && (errno == EINTR || errno == EAGAIN)) + return 0; + else { + DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); + sofcantrcvmore(so); + tcp_sockclosed(sototcpcb(so)); + return -1; + } + } + +#ifndef HAVE_READV + /* + * If there was no error, try and read the second time round + * We read again if n = 2 (ie, there's another part of the buffer) + * and we read as much as we could in the first read + * We don't test for <= 0 this time, because there legitimately + * might not be any more data (since the socket is non-blocking), + * a close will be detected on next iteration. + * A return of -1 wont (shouldn't) happen, since it didn't happen above + */ + if (n == 2 && nn == iov[0].iov_len) { + int ret; + ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0); + if (ret > 0) + nn += ret; + } + + DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); +#endif + + /* Update fields */ + sb->sb_cc += nn; + sb->sb_wptr += nn; + if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen)) + sb->sb_wptr -= sb->sb_datalen; + return nn; +} + +/* + * Get urgent data + * + * When the socket is created, we set it SO_OOBINLINE, + * so when OOB data arrives, we soread() it and everything + * in the send buffer is sent as urgent data + */ +void +sorecvoob(so) + struct SLIRPsocket *so; +{ + struct tcpcb *tp = sototcpcb(so); + + DEBUG_CALL("sorecvoob"); + DEBUG_ARG("so = %lx", (long)so); + + /* + * We take a guess at how much urgent data has arrived. + * In most situations, when urgent data arrives, the next + * read() should get all the urgent data. This guess will + * be wrong however if more data arrives just after the + * urgent data, or the read() doesn't return all the + * urgent data. + */ + soread(so); + tp->snd_up = tp->snd_una + so->so_snd.sb_cc; + tp->t_force = 1; + tcp_output(tp); + tp->t_force = 0; +} + +/* + * Send urgent data + * There's a lot duplicated code here, but... + */ +int +sosendoob(so) + struct SLIRPsocket *so; +{ + struct sbuf *sb = &so->so_rcv; + char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ + + int n, len; + + DEBUG_CALL("sosendoob"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); + + if (so->so_urgc > 2048) + so->so_urgc = 2048; /* XXXX */ + + if (sb->sb_rptr < sb->sb_wptr) { + /* We can send it directly */ + n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */ + so->so_urgc -= n; + + DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); + } else { + /* + * Since there's no sendv or sendtov like writev, + * we must copy all data to a linear buffer then + * send it all + */ + len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; + if (len > so->so_urgc) len = so->so_urgc; + memcpy(buff, sb->sb_rptr, len); + so->so_urgc -= len; + if (so->so_urgc) { + n = sb->sb_wptr - sb->sb_data; + if (n > so->so_urgc) n = so->so_urgc; + memcpy((buff + len), sb->sb_data, n); + so->so_urgc -= n; + len += n; + } + n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */ +#ifdef SLIRP_DEBUG + if (n != len) + DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n")); +#endif + DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc)); + } + + sb->sb_cc -= n; + sb->sb_rptr += n; + if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) + sb->sb_rptr -= sb->sb_datalen; + + return n; +} + +/* + * Write data from so_rcv to so's socket, + * updating all sbuf field as necessary + */ +int +sowrite(so) + struct SLIRPsocket *so; +{ + int n,nn; + struct sbuf *sb = &so->so_rcv; + int len = sb->sb_cc; + struct iovec iov[2]; + + DEBUG_CALL("sowrite"); + DEBUG_ARG("so = %lx", (long)so); + + if (so->so_urgc) { + sosendoob(so); + if (sb->sb_cc == 0) + return 0; + } + + /* + * No need to check if there's something to write, + * sowrite wouldn't have been called otherwise + */ + + len = sb->sb_cc; + + iov[0].iov_base = sb->sb_rptr; + if (sb->sb_rptr < sb->sb_wptr) { + iov[0].iov_len = sb->sb_wptr - sb->sb_rptr; + /* Should never succeed, but... */ + if (iov[0].iov_len > len) iov[0].iov_len = len; + n = 1; + } else { + iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr; + if (iov[0].iov_len > len) iov[0].iov_len = len; + len -= iov[0].iov_len; + if (len) { + iov[1].iov_base = sb->sb_data; + iov[1].iov_len = sb->sb_wptr - sb->sb_data; + if (iov[1].iov_len > len) iov[1].iov_len = len; + n = 2; + } else + n = 1; + } + /* Check if there's urgent data to send, and if so, send it */ + +#ifdef HAVE_READV + nn = writev(so->s, (const struct iovec *)iov, n); + + DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); +#else + nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0); +#endif + /* This should never happen, but people tell me it does *shrug* */ + if (nn < 0 && (errno == EAGAIN || errno == EINTR)) + return 0; + + if (nn <= 0) { + DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n", + so->so_state, errno)); + sofcantsendmore(so); + tcp_sockclosed(sototcpcb(so)); + return -1; + } + +#ifndef HAVE_READV + if (n == 2 && nn == iov[0].iov_len) { + int ret; + ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0); + if (ret > 0) + nn += ret; + } + DEBUG_MISC((dfd, " ... wrote nn = %d bytes\n", nn)); +#endif + + /* Update sbuf */ + sb->sb_cc -= nn; + sb->sb_rptr += nn; + if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen)) + sb->sb_rptr -= sb->sb_datalen; + + /* + * If in DRAIN mode, and there's no more data, set + * it CANTSENDMORE + */ + if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0) + sofcantsendmore(so); + + return nn; +} + +/* + * recvfrom() a UDP socket + */ +void +sorecvfrom(so) + struct SLIRPsocket *so; +{ + struct sockaddr_in addr; + socklen_t addrlen = sizeof(struct sockaddr_in); + + DEBUG_CALL("sorecvfrom"); + DEBUG_ARG("so = %lx", (long)so); + + if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ + char buff[256]; + int len; + + len = recvfrom(so->s, buff, 256, 0, + (struct sockaddr *)&addr, &addrlen); + /* XXX Check if reply is "correct"? */ + + if(len == -1 || len == 0) { + u_char code=ICMP_UNREACH_PORT; + + if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; + + DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", + errno,strerror(errno))); + icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); + } else { + icmp_reflect(so->so_m); + so->so_m = 0; /* Don't m_free() it again! */ + } + /* No need for this socket anymore, udp_detach it */ + udp_detach(so); + } else { /* A "normal" UDP packet */ + struct SLIRPmbuf *m; + int len; + ioctlsockopt_t n; + + if (!(m = m_get())) return; + m->m_data += if_maxlinkhdr; + + /* + * XXX Shouldn't FIONREAD packets destined for port 53, + * but I don't know the max packet size for DNS lookups + */ + len = M_FREEROOM(m); + /* if (so->so_fport != htons(53)) { */ + ioctlsocket(so->s, FIONREAD, &n); + + if (n > len) { + n = (m->m_data - m->m_dat) + m->m_len + n + 1; + m_inc(m, n); + len = M_FREEROOM(m); + } + /* } */ + + m->m_len = recvfrom(so->s, m->m_data, len, 0, + (struct sockaddr *)&addr, &addrlen); + DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n", + m->m_len, errno,strerror(errno))); + if(m->m_len<0) { + u_char code=ICMP_UNREACH_PORT; + + if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; + else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET; + + DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code)); + icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); + m_free(m); + } else { + /* + * Hack: domain name lookup will be used the most for UDP, + * and since they'll only be used once there's no need + * for the 4 minute (or whatever) timeout... So we time them + * out much quicker (10 seconds for now...) + */ + if (so->so_expire) { + if (so->so_fport == htons(53)) + so->so_expire = curtime + SO_EXPIREFAST; + else + so->so_expire = curtime + SO_EXPIRE; + } + + /* if (m->m_len == len) { + * m_inc(m, MINCSIZE); + * m->m_len = 0; + * } + */ + + /* + * If this packet was destined for CTL_ADDR, + * make it look like that's where it came from, done by udp_output + */ + udp_output(so, m, &addr); + } /* rx error */ + } /* if ping packet */ +} + +/* + * sendto() a socket + */ +int +sosendto(so, m) + struct SLIRPsocket *so; + struct SLIRPmbuf *m; +{ + int ret; + struct sockaddr_in addr; + + DEBUG_CALL("sosendto"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("m = %lx", (long)m); + + addr.sin_family = AF_INET; + if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + /* It's an alias */ + switch(ntohl(so->so_faddr.s_addr) & 0xff) { + case CTL_DNS: + addr.sin_addr = dns_addr; + break; + case CTL_ALIAS: + default: + addr.sin_addr = loopback_addr; + break; + } + } else + addr.sin_addr = so->so_faddr; + addr.sin_port = so->so_fport; + + DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); + + /* Don't care what port we get */ + ret = sendto(so->s, m->m_data, m->m_len, 0, + (struct sockaddr *)&addr, sizeof (struct sockaddr)); + if (ret < 0) + return -1; + + /* + * Kill the socket if there's no reply in 4 minutes, + * but only if it's an expirable socket + */ + if (so->so_expire) + so->so_expire = curtime + SO_EXPIRE; + so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */ + return 0; +} + +/* + * XXX This should really be tcp_listen + */ +struct SLIRPsocket * +solisten(port, laddr, lport, flags) + u_int port; + u_int32_t laddr; + u_int lport; + int flags; +{ + struct sockaddr_in addr; + struct SLIRPsocket *so; + int s; + socklen_t addrlen = sizeof(addr); + int opt = 1; + + DEBUG_CALL("solisten"); + DEBUG_ARG("port = %d", port); + DEBUG_ARG("laddr = %x", laddr); + DEBUG_ARG("lport = %d", lport); + DEBUG_ARG("flags = %x", flags); + + if ((so = socreate()) == NULL) { + /* free(so); Not sofree() ??? free(NULL) == NOP */ + return NULL; + } + + /* Don't tcp_attach... we don't need so_snd nor so_rcv */ + if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { + free(so); + return NULL; + } + insque(so,&tcb); + + /* + * SS_FACCEPTONCE sockets must time out. + */ + if (flags & SS_FACCEPTONCE) + so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; + + so->so_state = (SS_FACCEPTCONN|flags); + so->so_lport = lport; /* Kept in network format */ + so->so_laddr.s_addr = laddr; /* Ditto */ + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = port; + + if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || + (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || + (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || + (listen(s,1) < 0)) { + int tmperrno = errno; /* Don't clobber the real reason we failed */ + + close(s); + sofree(so); + /* Restore the real errno */ +#ifdef _WIN32 + WSASetLastError(tmperrno); +#else + errno = tmperrno; +#endif + return NULL; + } + setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); + + getsockname(s,(struct sockaddr *)&addr,&addrlen); + so->so_fport = addr.sin_port; + if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) + so->so_faddr = alias_addr; + else + so->so_faddr = addr.sin_addr; + + so->s = s; + return so; +} + +/* + * Data is available in so_rcv + * Just write() the data to the socket + * XXX not yet... + */ +void +sorwakeup(so) + struct SLIRPsocket *so; +{ +/* sowrite(so); */ +/* FD_CLR(so->s,&writefds); */ +} + +/* + * Data has been freed in so_snd + * We have room for a read() if we want to + * For now, don't read, it'll be done in the main loop + */ +void +sowwakeup(so) + struct SLIRPsocket *so; +{ + /* Nothing, yet */ +} + +/* + * Various session state calls + * XXX Should be #define's + * The socket state stuff needs work, these often get call 2 or 3 + * times each when only 1 was needed + */ +void +soisfconnecting(so) + register struct SLIRPsocket *so; +{ + so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE| + SS_FCANTSENDMORE|SS_FWDRAIN); + so->so_state |= SS_ISFCONNECTING; /* Clobber other states */ +} + +void +soisfconnected(so) + register struct SLIRPsocket *so; +{ + so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF); + so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ +} + +void +sofcantrcvmore(so) + struct SLIRPsocket *so; +{ + if ((so->so_state & SS_NOFDREF) == 0) { + shutdown(so->s,0); + if(global_writefds) { + FD_CLR(so->s,global_writefds); + } + } + so->so_state &= ~(SS_ISFCONNECTING); + if (so->so_state & SS_FCANTSENDMORE) + so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */ + else + so->so_state |= SS_FCANTRCVMORE; +} + +void +sofcantsendmore(so) + struct SLIRPsocket *so; +{ + if ((so->so_state & SS_NOFDREF) == 0) { + shutdown(so->s,1); /* send FIN to fhost */ + if (global_readfds) { + FD_CLR(so->s,global_readfds); + } + if (global_xfds) { + FD_CLR(so->s,global_xfds); + } + } + so->so_state &= ~(SS_ISFCONNECTING); + if (so->so_state & SS_FCANTRCVMORE) + so->so_state = SS_NOFDREF; /* as above */ + else + so->so_state |= SS_FCANTSENDMORE; +} + +void +soisfdisconnected(so) + struct SLIRPsocket *so; +{ +/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */ +/* close(so->s); */ +/* so->so_state = SS_ISFDISCONNECTED; */ + /* + * XXX Do nothing ... ? + */ +} + +/* + * Set write drain mode + * Set CANTSENDMORE once all data has been write()n + */ +void +sofwdrain(so) + struct SLIRPsocket *so; +{ + if (so->so_rcv.sb_cc) + so->so_state |= SS_FWDRAIN; + else + sofcantsendmore(so); +} + diff --git a/src/slirp/socket.h b/src/slirp/socket.h new file mode 100644 index 0000000..9e9f231 --- /dev/null +++ b/src/slirp/socket.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +/* MINE */ + +#ifndef _SLIRP_SOCKET_H_ +#define _SLIRP_SOCKET_H_ + +#define SO_EXPIRE 240000 +#define SO_EXPIREFAST 10000 + +/* + * Our socket structure + */ + +struct SLIRPsocket { + struct SLIRPsocket *so_next,*so_prev; /* For a linked list of sockets */ + + int s; /* The actual socket */ + + /* XXX union these with not-yet-used sbuf params */ + struct SLIRPmbuf *so_m; /* Pointer to the original SYN packet, + * for non-blocking connect()'s, and + * PING reply's */ + struct tcpiphdr *so_ti; /* Pointer to the original ti within + * so_mconn, for non-blocking connections */ + int so_urgc; + struct in_addr so_faddr; /* foreign host table entry */ + struct in_addr so_laddr; /* local host table entry */ + u_int16_t so_fport; /* foreign port */ + u_int16_t so_lport; /* local port */ + + u_int8_t so_iptos; /* Type of service */ + u_int8_t so_emu; /* Is the socket emulated? */ + + u_char so_type; /* Type of socket, UDP or TCP */ + int so_state; /* internal state flags SS_*, below */ + + struct tcpcb *so_tcpcb; /* pointer to TCP protocol control block */ + u_int so_expire; /* When the socket will expire */ + + int so_queued; /* Number of packets queued from this socket */ + int so_nqueued; /* Number of packets queued in a row + * Used to determine when to "downgrade" a session + * from fastq to batchq */ + + struct sbuf so_rcv; /* Receive buffer */ + struct sbuf so_snd; /* Send buffer */ + void * extra; /* Extra pointer */ +}; + + +/* + * Socket state bits. (peer means the host on the Internet, + * local host means the host on the other end of the modem) + */ +#define SS_NOFDREF 0x001 /* No fd reference */ + +#define SS_ISFCONNECTING 0x002 /* Socket is connecting to peer (non-blocking connect()'s) */ +#define SS_ISFCONNECTED 0x004 /* Socket is connected to peer */ +#define SS_FCANTRCVMORE 0x008 /* Socket can't receive more from peer (for half-closes) */ +#define SS_FCANTSENDMORE 0x010 /* Socket can't send more to peer (for half-closes) */ +/* #define SS_ISFDISCONNECTED 0x020*/ /* Socket has disconnected from peer, in 2MSL state */ +#define SS_FWDRAIN 0x040 /* We received a FIN, drain data and set SS_FCANTSENDMORE */ + +#define SS_CTL 0x080 +#define SS_FACCEPTCONN 0x100 /* Socket is accepting connections from a host on the internet */ +#define SS_FACCEPTONCE 0x200 /* If set, the SS_FACCEPTCONN socket will die after one accept */ + +extern struct SLIRPsocket tcb; + + +#if defined(DECLARE_IOVEC) && !defined(HAVE_READV) +struct iovec { + char *iov_base; + size_t iov_len; +}; +#endif + +void so_init _P((void)); +struct SLIRPsocket * solookup _P((struct SLIRPsocket *, struct in_addr, u_int, struct in_addr, u_int)); +struct SLIRPsocket * socreate _P((void)); +void sofree _P((struct SLIRPsocket *)); +int soread _P((struct SLIRPsocket *)); +void sorecvoob _P((struct SLIRPsocket *)); +int sosendoob _P((struct SLIRPsocket *)); +int sowrite _P((struct SLIRPsocket *)); +void sorecvfrom _P((struct SLIRPsocket *)); +int sosendto _P((struct SLIRPsocket *, struct SLIRPmbuf *)); +struct SLIRPsocket * solisten _P((u_int, u_int32_t, u_int, int)); +void sorwakeup _P((struct SLIRPsocket *)); +void sowwakeup _P((struct SLIRPsocket *)); +void soisfconnecting _P((register struct SLIRPsocket *)); +void soisfconnected _P((register struct SLIRPsocket *)); +void sofcantrcvmore _P((struct SLIRPsocket *)); +void sofcantsendmore _P((struct SLIRPsocket *)); +void soisfdisconnected _P((struct SLIRPsocket *)); +void sofwdrain _P((struct SLIRPsocket *)); + +#endif /* _SOCKET_H_ */ diff --git a/src/slirp/tcp.h b/src/slirp/tcp.h new file mode 100644 index 0000000..36edc5c --- /dev/null +++ b/src/slirp/tcp.h @@ -0,0 +1,181 @@ +/* + * 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. + * + * @(#)tcp.h 8.1 (Berkeley) 6/10/93 + * tcp.h,v 1.3 1994/08/21 05:27:34 paul Exp + */ + +#ifndef _TCP_H_ +#define _TCP_H_ + +typedef u_int32_t tcp_seq; + +#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ +#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ + +extern int tcp_rcvspace; +extern int tcp_sndspace; +extern struct SLIRPsocket *tcp_last_so; + +#define TCP_SNDSPACE 8192 +#define TCP_RCVSPACE 8192 + +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct tcphdr { + u_int16_t th_sport; /* source port */ + u_int16_t th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ +#ifdef WORDS_BIGENDIAN + u_char th_off:4, /* data offset */ + th_x2:4; /* (unused) */ +#else + u_char th_x2:4, /* (unused) */ + th_off:4; /* data offset */ +#endif + u_int8_t th_flags; +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 + u_int16_t th_win; /* window */ + u_int16_t th_sum; /* checksum */ + u_int16_t th_urp; /* urgent pointer */ +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) +#endif + +#include "tcp_var.h" + +#define TCPOPT_EOL 0 +#define TCPOPT_NOP 1 +#define TCPOPT_MAXSEG 2 +#define TCPOLEN_MAXSEG 4 +#define TCPOPT_WINDOW 3 +#define TCPOLEN_WINDOW 3 +#define TCPOPT_SACK_PERMITTED 4 /* Experimental */ +#define TCPOLEN_SACK_PERMITTED 2 +#define TCPOPT_SACK 5 /* Experimental */ +#define TCPOPT_TIMESTAMP 8 +#define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ + +#define TCPOPT_TSTAMP_HDR \ + (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) + +/* + * Default maximum segment size for TCP. + * With an IP MSS of 576, this is 536, + * but 512 is probably more convenient. + * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)). + * + * We make this 1460 because we only care about Ethernet in the qemu context. + */ +#define TCP_MSS 1460 + +#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ + +#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ + +/* + * User-settable options (used with setsockopt). + * + * We don't use the system headers on unix because we have conflicting + * local structures. We can't avoid the system definitions on Windows, + * so we undefine them. + */ +#undef TCP_NODELAY +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#undef TCP_MAXSEG +/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */ + +/* + * TCP FSM state definitions. + * Per RFC793, September, 1981. + */ + +#define TCP_NSTATES 11 + +#define TCPS_CLOSED 0 /* closed */ +#define TCPS_LISTEN 1 /* listening for connection */ +#define TCPS_SYN_SENT 2 /* active, have sent syn */ +#define TCPS_SYN_RECEIVED 3 /* have send and received syn */ +/* states < TCPS_ESTABLISHED are those where connections not established */ +#define TCPS_ESTABLISHED 4 /* established */ +#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */ +/* states > TCPS_CLOSE_WAIT are those where user has closed */ +#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */ +#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */ +#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */ +/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ +#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */ +#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */ + +#define TCPS_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) +#define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) +#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) + +/* + * TCP sequence numbers are 32 bit integers operated + * on with modular arithmetic. These macros can be + * used to compare such integers. + */ +#define SEQ_LT(a,b) ((int)((a)-(b)) < 0) +#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) +#define SEQ_GT(a,b) ((int)((a)-(b)) > 0) +#define SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0) + +/* + * Macros to initialize tcp sequence numbers for + * send and receive from initial send and receive + * sequence numbers. + */ +#define tcp_rcvseqinit(tp) \ + (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1 + +#define tcp_sendseqinit(tp) \ + (tp)->snd_una = (tp)->snd_nxt = (tp)->snd_max = (tp)->snd_up = (tp)->iss + +#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */ + +extern tcp_seq tcp_iss; /* tcp initial send seq # */ + +extern char *tcpstates[]; + +#endif diff --git a/src/slirp/tcp_input.c b/src/slirp/tcp_input.c new file mode 100644 index 0000000..369ec00 --- /dev/null +++ b/src/slirp/tcp_input.c @@ -0,0 +1,1722 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994 + * 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. + * + * @(#)tcp_input.c 8.5 (Berkeley) 4/10/94 + * tcp_input.c,v 1.10 1994/10/13 18:36:32 wollman Exp + */ + +/* + * Changes and additions relating to SLiRP + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include +#include "slirp.h" +#include "ip_icmp.h" + +struct SLIRPsocket tcb; + +int tcprexmtthresh = 3; +struct SLIRPsocket *tcp_last_so = &tcb; + +tcp_seq tcp_iss; /* tcp initial send seq # */ + +#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) + +/* for modulo comparisons of timestamps */ +#define TSTMP_LT(a,b) ((int)((a)-(b)) < 0) +#define TSTMP_GEQ(a,b) ((int)((a)-(b)) >= 0) + +/* + * Insert segment ti into reassembly queue of tcp with + * control block tp. Return TH_FIN if reassembly now includes + * a segment with FIN. The macro form does the common case inline + * (segment is the next to be received on an established connection, + * and the queue is empty), avoiding linkage into and removal + * from the queue and repetition of various conversions. + * Set DELACK for segments received in order, but ack immediately + * when segments are out of order (so fast retransmit can work). + */ +#ifdef TCP_ACK_HACK +#define TCP_REASS(tp, ti, m, so, flags) {\ + if ((ti)->ti_seq == (tp)->rcv_nxt && \ + (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + (tp)->t_state == TCPS_ESTABLISHED) {\ + if (ti->ti_flags & TH_PUSH) \ + tp->t_flags |= TF_ACKNOW; \ + else \ + tp->t_flags |= TF_DELACK; \ + (tp)->rcv_nxt += (ti)->ti_len; \ + flags = (ti)->ti_flags & TH_FIN; \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ + if (so->so_emu) { \ + if (tcp_emu((so),(m))) sbappend((so), (m)); \ + } else \ + sbappend((so), (m)); \ +/* sorwakeup(so); */ \ + } else {\ + (flags) = tcp_reass((tp), (ti), (m)); \ + tp->t_flags |= TF_ACKNOW; \ + } \ +} +#else +#define TCP_REASS(tp, ti, m, so, flags) { \ + if ((ti)->ti_seq == (tp)->rcv_nxt && \ + (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + (tp)->t_state == TCPS_ESTABLISHED) { \ + tp->t_flags |= TF_DELACK; \ + (tp)->rcv_nxt += (ti)->ti_len; \ + flags = (ti)->ti_flags & TH_FIN; \ + tcpstat.tcps_rcvpack++;\ + tcpstat.tcps_rcvbyte += (ti)->ti_len;\ + if (so->so_emu) { \ + if (tcp_emu((so),(m))) sbappend(so, (m)); \ + } else \ + sbappend((so), (m)); \ +/* sorwakeup(so); */ \ + } else { \ + (flags) = tcp_reass((tp), (ti), (m)); \ + tp->t_flags |= TF_ACKNOW; \ + } \ +} +#endif + +int +tcp_reass(tp, ti, m) + struct tcpcb *tp; + struct tcpiphdr *ti; + struct SLIRPmbuf *m; +{ + struct tcpiphdr *q; + struct SLIRPsocket *so = tp->t_socket; + int flags; + + /* + * Call with ti==0 after become established to + * force pre-ESTABLISHED data up to user socket. + */ + if (ti == 0) + goto present; + + /* + * Find a segment which begins after this one does. + */ + for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp; + q = (struct tcpiphdr *)q->ti_next) + if (SEQ_GT(q->ti_seq, ti->ti_seq)) + break; + + /* + * If there is a preceding segment, it may provide some of + * our data already. If so, drop the data from the incoming + * segment. If it provides all of our data, drop us. + */ + if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { + int i; + q = (struct tcpiphdr *)q->ti_prev; + /* conversion to int (in i) handles seq wraparound */ + i = q->ti_seq + q->ti_len - ti->ti_seq; + if (i > 0) { + if (i >= ti->ti_len) { + tcpstat.tcps_rcvduppack++; + tcpstat.tcps_rcvdupbyte += ti->ti_len; + m_freem(m); + /* + * Try to present any queued data + * at the left window edge to the user. + * This is needed after the 3-WHS + * completes. + */ + goto present; /* ??? */ + } + m_adj(m, i); + ti->ti_len -= i; + ti->ti_seq += i; + } + q = (struct tcpiphdr *)(q->ti_next); + } + tcpstat.tcps_rcvoopack++; + tcpstat.tcps_rcvoobyte += ti->ti_len; + REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ + + /* + * While we overlap succeeding segments trim them or, + * if they are completely covered, dequeue them. + */ + while (q != (struct tcpiphdr *)tp) { + int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; + if (i <= 0) + break; + if (i < q->ti_len) { + q->ti_seq += i; + q->ti_len -= i; + m_adj((struct SLIRPmbuf *) REASS_MBUF(q), i); + break; + } + q = (struct tcpiphdr *)q->ti_next; + m = (struct SLIRPmbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev); + remque_32((void *)(q->ti_prev)); + m_freem(m); + } + + /* + * Stick new segment in its place. + */ + insque_32(ti, (void *)(q->ti_prev)); + +present: + /* + * Present data to user, advancing rcv_nxt through + * completed sequence space. + */ + if (!TCPS_HAVEESTABLISHED(tp->t_state)) + return (0); + ti = (struct tcpiphdr *) tp->seg_next; + if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) + return (0); + if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) + return (0); + do { + tp->rcv_nxt += ti->ti_len; + flags = ti->ti_flags & TH_FIN; + remque_32(ti); + m = (struct SLIRPmbuf *) REASS_MBUF(ti); /* XXX */ + ti = (struct tcpiphdr *)ti->ti_next; +/* if (so->so_state & SS_FCANTRCVMORE) */ + if (so->so_state & SS_FCANTSENDMORE) + m_freem(m); + else { + if (so->so_emu) { + if (tcp_emu(so,m)) sbappend(so, m); + } else + sbappend(so, m); + } + } while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt); +/* sorwakeup(so); */ + return (flags); +} + +/* + * TCP input routine, follows pages 65-76 of the + * protocol specification dated September, 1981 very closely. + */ +void +tcp_input(m, iphlen, inso) + struct SLIRPmbuf *m; + int iphlen; + struct SLIRPsocket *inso; +{ + struct ip save_ip, *ip; + struct tcpiphdr *ti; + SLIRPcaddr_t optp = NULL; + int optlen = 0; + int len, tlen, off; + struct tcpcb *tp = 0; + int tiflags; + struct SLIRPsocket *so = 0; + int todrop, acked, ourfinisacked, needoutput = 0; +/* int dropsocket = 0; */ + int iss = 0; + u_long tiwin; + int ret; +/* int ts_present = 0; */ + + DEBUG_CALL("tcp_input"); + DEBUG_ARGS((dfd," m = %8lx iphlen = %2d inso = %lx\n", + (long )m, iphlen, (long )inso )); + + /* + * If called with m == 0, then we're continuing the connect + */ + if (m == NULL) { + so = inso; + + /* Re-set a few variables */ + tp = sototcpcb(so); + m = so->so_m; + so->so_m = 0; + ti = so->so_ti; + tiwin = ti->ti_win; + tiflags = ti->ti_flags; + + goto cont_conn; + } + + + tcpstat.tcps_rcvtotal++; + /* + * Get IP and TCP header together in first SLIRPmbuf. + * Note: IP leaves IP header in first SLIRPmbuf. + */ + ti = mtod(m, struct tcpiphdr *); + if (iphlen > sizeof(struct ip )) { + ip_stripoptions(m, (struct SLIRPmbuf *)0); + iphlen=sizeof(struct ip ); + } + /* XXX Check if too short */ + + + /* + * Save a copy of the IP header in case we want restore it + * for sending an ICMP error message in response. + */ + ip=mtod(m, struct ip *); + save_ip = *ip; + save_ip.ip_len+= iphlen; + + /* + * Checksum extended TCP header and data. + */ + tlen = ((struct ip *)ti)->ip_len; + ti->ti_next = ti->ti_prev = 0; + ti->ti_x1 = 0; + ti->ti_len = htons((u_int16_t)tlen); + len = sizeof(struct ip ) + tlen; + /* keep checksum for ICMP reply + * ti->ti_sum = cksum(m, len); + * if (ti->ti_sum) { */ + if(cksum(m, len)) { + tcpstat.tcps_rcvbadsum++; + goto drop; + } + + /* + * Check that TCP offset makes sense, + * pull out TCP options and adjust length. XXX + */ + off = ti->ti_off << 2; + if (off < sizeof (struct tcphdr) || off > tlen) { + tcpstat.tcps_rcvbadoff++; + goto drop; + } + tlen -= off; + ti->ti_len = tlen; + if (off > sizeof (struct tcphdr)) { + optlen = off - sizeof (struct tcphdr); + optp = mtod(m, SLIRPcaddr_t) + sizeof (struct tcpiphdr); + + /* + * Do quick retrieval of timestamp options ("options + * prediction?"). If timestamp is the only option and it's + * formatted as recommended in RFC 1323 appendix A, we + * quickly get the values now and not bother calling + * tcp_dooptions(), etc. + */ +/* if ((optlen == TCPOLEN_TSTAMP_APPA || + * (optlen > TCPOLEN_TSTAMP_APPA && + * optp[TCPOLEN_TSTAMP_APPA] == TCPOPT_EOL)) && + * *(u_int32_t *)optp == htonl(TCPOPT_TSTAMP_HDR) && + * (ti->ti_flags & TH_SYN) == 0) { + * ts_present = 1; + * ts_val = ntohl(*(u_int32_t *)(optp + 4)); + * ts_ecr = ntohl(*(u_int32_t *)(optp + 8)); + * optp = NULL; / * we've parsed the options * / + * } + */ + } + tiflags = ti->ti_flags; + + /* + * Convert TCP protocol specific fields to host format. + */ + NTOHL(ti->ti_seq); + NTOHL(ti->ti_ack); + NTOHS(ti->ti_win); + NTOHS(ti->ti_urp); + + /* + * Drop TCP, IP headers and TCP options. + */ + m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + m->m_len -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + + /* + * Locate pcb for segment. + */ +findso: + so = tcp_last_so; + if (so->so_fport != ti->ti_dport || + so->so_lport != ti->ti_sport || + so->so_laddr.s_addr != ti->ti_src.s_addr || + so->so_faddr.s_addr != ti->ti_dst.s_addr) { + so = solookup(&tcb, ti->ti_src, ti->ti_sport, + ti->ti_dst, ti->ti_dport); + if (so) + tcp_last_so = so; + ++tcpstat.tcps_socachemiss; + } + + /* + * If the state is CLOSED (i.e., TCB does not exist) then + * all data in the incoming segment is discarded. + * If the TCB exists but is in CLOSED state, it is embryonic, + * but should either do a listen or a connect soon. + * + * state == CLOSED means we've done socreate() but haven't + * attached it to a protocol yet... + * + * XXX If a TCB does not exist, and the TH_SYN flag is + * the only flag set, then create a session, mark it + * as if it was LISTENING, and continue... + */ + if (so == 0) { + if ((tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) != TH_SYN) + goto dropwithreset; + + if ((so = socreate()) == NULL) + goto dropwithreset; + if (tcp_attach(so) < 0) { + free(so); /* Not sofree (if it failed, it's not insqued) */ + goto dropwithreset; + } + + sbreserve(&so->so_snd, tcp_sndspace); + sbreserve(&so->so_rcv, tcp_rcvspace); + + /* tcp_last_so = so; */ /* XXX ? */ + /* tp = sototcpcb(so); */ + + so->so_laddr = ti->ti_src; + so->so_lport = ti->ti_sport; + so->so_faddr = ti->ti_dst; + so->so_fport = ti->ti_dport; + + if ((so->so_iptos = tcp_tos(so)) == 0) + so->so_iptos = ((struct ip *)ti)->ip_tos; + + tp = sototcpcb(so); + tp->t_state = TCPS_LISTEN; + } + + /* + * If this is a still-connecting socket, this probably + * a retransmit of the SYN. Whether it's a retransmit SYN + * or something else, we nuke it. + */ + if (so->so_state & SS_ISFCONNECTING) + goto drop; + + tp = sototcpcb(so); + + /* XXX Should never fail */ + if (tp == 0) + goto dropwithreset; + if (tp->t_state == TCPS_CLOSED) + goto drop; + + /* Unscale the window into a 32-bit value. */ +/* if ((tiflags & TH_SYN) == 0) + * tiwin = ti->ti_win << tp->snd_scale; + * else + */ + tiwin = ti->ti_win; + + /* + * Segment received on connection. + * Reset idle time and keep-alive timer. + */ + tp->t_idle = 0; + if (so_options) + tp->t_timer[TCPT_KEEP] = tcp_keepintvl; + else + tp->t_timer[TCPT_KEEP] = tcp_keepidle; + + /* + * Process options if not in LISTEN state, + * else do it below (after getting remote address). + */ + if (optp && tp->t_state != TCPS_LISTEN) + tcp_dooptions(tp, (u_char *)optp, optlen, ti); +/* , */ +/* &ts_present, &ts_val, &ts_ecr); */ + + /* + * Header prediction: check for the two common cases + * of a uni-directional data xfer. If the packet has + * no control flags, is in-sequence, the window didn't + * change and we're not retransmitting, it's a + * candidate. If the length is zero and the ack moved + * forward, we're the sender side of the xfer. Just + * free the data acked & wake any higher level process + * that was blocked waiting for space. If the length + * is non-zero and the ack didn't move, we're the + * receiver side. If we're getting packets in-order + * (the reassembly queue is empty), add the data to + * the socket buffer and note that we need a delayed ack. + * + * XXX Some of these tests are not needed + * eg: the tiwin == tp->snd_wnd prevents many more + * predictions.. with no *real* advantage.. + */ + if (tp->t_state == TCPS_ESTABLISHED && + (tiflags & (TH_SYN|TH_FIN|TH_RST|TH_URG|TH_ACK)) == TH_ACK && +/* (!ts_present || TSTMP_GEQ(ts_val, tp->ts_recent)) && */ + ti->ti_seq == tp->rcv_nxt && + tiwin && tiwin == tp->snd_wnd && + tp->snd_nxt == tp->snd_max) { + /* + * If last ACK falls within this segment's sequence numbers, + * record the timestamp. + */ +/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && + * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len)) { + * tp->ts_recent_age = tcp_now; + * tp->ts_recent = ts_val; + * } + */ + if (ti->ti_len == 0) { + if (SEQ_GT(ti->ti_ack, tp->snd_una) && + SEQ_LEQ(ti->ti_ack, tp->snd_max) && + tp->snd_cwnd >= tp->snd_wnd) { + /* + * this is a pure ack for outstanding data. + */ + ++tcpstat.tcps_predack; +/* if (ts_present) + * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); + * else + */ if (tp->t_rtt && + SEQ_GT(ti->ti_ack, tp->t_rtseq)) + tcp_xmit_timer(tp, tp->t_rtt); + acked = ti->ti_ack - tp->snd_una; + tcpstat.tcps_rcvackpack++; + tcpstat.tcps_rcvackbyte += acked; + sbdrop(&so->so_snd, acked); + tp->snd_una = ti->ti_ack; + m_freem(m); + + /* + * If all outstanding data are acked, stop + * retransmit timer, otherwise restart timer + * using current (possibly backed-off) value. + * If process is waiting for space, + * wakeup/selwakeup/signal. If data + * are ready to send, let tcp_output + * decide between more output or persist. + */ + if (tp->snd_una == tp->snd_max) + tp->t_timer[TCPT_REXMT] = 0; + else if (tp->t_timer[TCPT_PERSIST] == 0) + tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; + + /* + * There's room in so_snd, sowwakup will read() + * from the socket if we can + */ +/* if (so->so_snd.sb_flags & SB_NOTIFY) + * sowwakeup(so); + */ + /* + * This is called because sowwakeup might have + * put data into so_snd. Since we don't so sowwakeup, + * we don't need this.. XXX??? + */ + if (so->so_snd.sb_cc) + (void) tcp_output(tp); + + return; + } + } else if (ti->ti_ack == tp->snd_una && + tp->seg_next == (tcpiphdrp_32)tp && + ti->ti_len <= sbspace(&so->so_rcv)) { + /* + * this is a pure, in-sequence data packet + * with nothing on the reassembly queue and + * we have enough buffer space to take it. + */ + ++tcpstat.tcps_preddat; + tp->rcv_nxt += ti->ti_len; + tcpstat.tcps_rcvpack++; + tcpstat.tcps_rcvbyte += ti->ti_len; + /* + * Add data to socket buffer. + */ + if (so->so_emu) { + if (tcp_emu(so,m)) sbappend(so, m); + } else + sbappend(so, m); + + /* + * XXX This is called when data arrives. Later, check + * if we can actually write() to the socket + * XXX Need to check? It's be NON_BLOCKING + */ +/* sorwakeup(so); */ + + /* + * If this is a short packet, then ACK now - with Nagel + * congestion avoidance sender won't send more until + * he gets an ACK. + * + * It is better to not delay acks at all to maximize + * TCP throughput. See RFC 2581. + */ + tp->t_flags |= TF_ACKNOW; + tcp_output(tp); + return; + } + } /* header prediction */ + /* + * Calculate amount of space in receive window, + * and then do TCP input processing. + * Receive window is amount of space in rcv queue, + * but not less than advertised window. + */ + { int win; + win = sbspace(&so->so_rcv); + if (win < 0) + win = 0; + tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); + } + + switch (tp->t_state) { + + /* + * If the state is LISTEN then ignore segment if it contains an RST. + * If the segment contains an ACK then it is bad and send a RST. + * If it does not contain a SYN then it is not interesting; drop it. + * Don't bother responding if the destination was a broadcast. + * Otherwise initialize tp->rcv_nxt, and tp->irs, select an initial + * tp->iss, and send a segment: + * + * Also initialize tp->snd_nxt to tp->iss+1 and tp->snd_una to tp->iss. + * Fill in remote peer address fields if not previously specified. + * Enter SYN_RECEIVED state, and process any other fields of this + * segment in this state. + */ + case TCPS_LISTEN: { + + if (tiflags & TH_RST) + goto drop; + if (tiflags & TH_ACK) + goto dropwithreset; + if ((tiflags & TH_SYN) == 0) + goto drop; + + /* + * This has way too many gotos... + * But a bit of spaghetti code never hurt anybody :) + */ + + /* + * If this is destined for the control address, then flag to + * tcp_ctl once connected, otherwise connect + */ + if ((so->so_faddr.s_addr&htonl(0xffffff00)) == special_addr.s_addr) { + int lastbyte=ntohl(so->so_faddr.s_addr) & 0xff; + if (lastbyte!=CTL_ALIAS && lastbyte!=CTL_DNS) { +#if 0 + if(lastbyte==CTL_CMD || lastbyte==CTL_EXEC) { + /* Command or exec adress */ + so->so_state |= SS_CTL; + } else +#endif + { + /* May be an add exec */ + struct ex_list *ex_ptr; + for(ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { + if(ex_ptr->ex_fport == so->so_fport && + lastbyte == ex_ptr->ex_addr) { + so->so_state |= SS_CTL; + break; + } + } + } + if(so->so_state & SS_CTL) goto cont_input; + } + /* CTL_ALIAS: Do nothing, tcp_fconnect will be called on it */ + } + + if (so->so_emu & EMU_NOCONNECT) { + so->so_emu &= ~EMU_NOCONNECT; + goto cont_input; + } + + if((tcp_fconnect(so) == -1) && (errno != EINPROGRESS) && (errno != EWOULDBLOCK)) { + u_char code=ICMP_UNREACH_NET; + DEBUG_MISC((dfd," tcp fconnect errno = %d-%s\n", + errno,strerror(errno))); + if(errno == ECONNREFUSED) { + /* ACK the SYN, send RST to refuse the connection */ + tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0, + TH_RST|TH_ACK); + } else { + if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST; + HTONL(ti->ti_seq); /* restore tcp header */ + HTONL(ti->ti_ack); + HTONS(ti->ti_win); + HTONS(ti->ti_urp); + m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + m->m_len += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr); + *ip=save_ip; + icmp_error(m, ICMP_UNREACH,code, 0,strerror(errno)); + } + tp = tcp_close(tp); + m_free(m); + } else { + /* + * Haven't connected yet, save the current SLIRPmbuf + * and ti, and return + * XXX Some OS's don't tell us whether the connect() + * succeeded or not. So we must time it out. + */ + so->so_m = m; + so->so_ti = ti; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tp->t_state = TCPS_SYN_RECEIVED; + } + return; + + cont_conn: + /* m==NULL + * Check if the connect succeeded + */ + if (so->so_state & SS_NOFDREF) { + tp = tcp_close(tp); + goto dropwithreset; + } + cont_input: + tcp_template(tp); + + if (optp) + tcp_dooptions(tp, (u_char *)optp, optlen, ti); + /* , */ + /* &ts_present, &ts_val, &ts_ecr); */ + + if (iss) + tp->iss = iss; + else + tp->iss = tcp_iss; + tcp_iss += TCP_ISSINCR/2; + tp->irs = ti->ti_seq; + tcp_sendseqinit(tp); + tcp_rcvseqinit(tp); + tp->t_flags |= TF_ACKNOW; + tp->t_state = TCPS_SYN_RECEIVED; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tcpstat.tcps_accepts++; + goto trimthenstep6; + } /* case TCPS_LISTEN */ + + /* + * If the state is SYN_SENT: + * if seg contains an ACK, but not for our SYN, drop the input. + * if seg contains a RST, then drop the connection. + * if seg does not contain SYN, then drop it. + * Otherwise this is an acceptable SYN segment + * initialize tp->rcv_nxt and tp->irs + * if seg contains ack then advance tp->snd_una + * if SYN has been acked change to ESTABLISHED else SYN_RCVD state + * arrange for segment to be acked (eventually) + * continue processing rest of data/controls, beginning with URG + */ + case TCPS_SYN_SENT: + if ((tiflags & TH_ACK) && + (SEQ_LEQ(ti->ti_ack, tp->iss) || + SEQ_GT(ti->ti_ack, tp->snd_max))) + goto dropwithreset; + + if (tiflags & TH_RST) { + if (tiflags & TH_ACK) + tp = tcp_drop(tp,0); /* XXX Check t_softerror! */ + goto drop; + } + + if ((tiflags & TH_SYN) == 0) + goto drop; + if (tiflags & TH_ACK) { + tp->snd_una = ti->ti_ack; + if (SEQ_LT(tp->snd_nxt, tp->snd_una)) + tp->snd_nxt = tp->snd_una; + } + + tp->t_timer[TCPT_REXMT] = 0; + tp->irs = ti->ti_seq; + tcp_rcvseqinit(tp); + tp->t_flags |= TF_ACKNOW; + if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { + tcpstat.tcps_connects++; + soisfconnected(so); + tp->t_state = TCPS_ESTABLISHED; + + /* Do window scaling on this connection? */ +/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == + * (TF_RCVD_SCALE|TF_REQ_SCALE)) { + * tp->snd_scale = tp->requested_s_scale; + * tp->rcv_scale = tp->request_r_scale; + * } + */ + (void) tcp_reass(tp, (struct tcpiphdr *)0, + (struct SLIRPmbuf *)0); + /* + * if we didn't have to retransmit the SYN, + * use its rtt as our initial srtt & rtt var. + */ + if (tp->t_rtt) + tcp_xmit_timer(tp, tp->t_rtt); + } else + tp->t_state = TCPS_SYN_RECEIVED; + +trimthenstep6: + /* + * Advance ti->ti_seq to correspond to first data byte. + * If data, trim to stay within window, + * dropping FIN if necessary. + */ + ti->ti_seq++; + if (ti->ti_len > tp->rcv_wnd) { + todrop = ti->ti_len - tp->rcv_wnd; + m_adj(m, -todrop); + ti->ti_len = tp->rcv_wnd; + tiflags &= ~TH_FIN; + tcpstat.tcps_rcvpackafterwin++; + tcpstat.tcps_rcvbyteafterwin += todrop; + } + tp->snd_wl1 = ti->ti_seq - 1; + tp->rcv_up = ti->ti_seq; + goto step6; + } /* switch tp->t_state */ + /* + * States other than LISTEN or SYN_SENT. + * First check timestamp, if present. + * Then check that at least some bytes of segment are within + * receive window. If segment begins before rcv_nxt, + * drop leading data (and SYN); if nothing left, just ack. + * + * RFC 1323 PAWS: If we have a timestamp reply on this segment + * and it's less than ts_recent, drop it. + */ +/* if (ts_present && (tiflags & TH_RST) == 0 && tp->ts_recent && + * TSTMP_LT(ts_val, tp->ts_recent)) { + * + */ /* Check to see if ts_recent is over 24 days old. */ +/* if ((int)(tcp_now - tp->ts_recent_age) > TCP_PAWS_IDLE) { + */ /* + * * Invalidate ts_recent. If this segment updates + * * ts_recent, the age will be reset later and ts_recent + * * will get a valid value. If it does not, setting + * * ts_recent to zero will at least satisfy the + * * requirement that zero be placed in the timestamp + * * echo reply when ts_recent isn't valid. The + * * age isn't reset until we get a valid ts_recent + * * because we don't want out-of-order segments to be + * * dropped when ts_recent is old. + * */ +/* tp->ts_recent = 0; + * } else { + * tcpstat.tcps_rcvduppack++; + * tcpstat.tcps_rcvdupbyte += ti->ti_len; + * tcpstat.tcps_pawsdrop++; + * goto dropafterack; + * } + * } + */ + + todrop = tp->rcv_nxt - ti->ti_seq; + if (todrop > 0) { + if (tiflags & TH_SYN) { + tiflags &= ~TH_SYN; + ti->ti_seq++; + if (ti->ti_urp > 1) + ti->ti_urp--; + else + tiflags &= ~TH_URG; + todrop--; + } + /* + * Following if statement from Stevens, vol. 2, p. 960. + */ + if (todrop > ti->ti_len + || (todrop == ti->ti_len && (tiflags & TH_FIN) == 0)) { + /* + * Any valid FIN must be to the left of the window. + * At this point the FIN must be a duplicate or out + * of sequence; drop it. + */ + tiflags &= ~TH_FIN; + + /* + * Send an ACK to resynchronize and drop any data. + * But keep on processing for RST or ACK. + */ + tp->t_flags |= TF_ACKNOW; + todrop = ti->ti_len; + tcpstat.tcps_rcvduppack++; + tcpstat.tcps_rcvdupbyte += todrop; + } else { + tcpstat.tcps_rcvpartduppack++; + tcpstat.tcps_rcvpartdupbyte += todrop; + } + m_adj(m, todrop); + ti->ti_seq += todrop; + ti->ti_len -= todrop; + if (ti->ti_urp > todrop) + ti->ti_urp -= todrop; + else { + tiflags &= ~TH_URG; + ti->ti_urp = 0; + } + } + /* + * If new data are received on a connection after the + * user processes are gone, then RST the other end. + */ + if ((so->so_state & SS_NOFDREF) && + tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { + tp = tcp_close(tp); + tcpstat.tcps_rcvafterclose++; + goto dropwithreset; + } + + /* + * If segment ends after window, drop trailing data + * (and PUSH and FIN); if nothing left, just ACK. + */ + todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); + if (todrop > 0) { + tcpstat.tcps_rcvpackafterwin++; + if (todrop >= ti->ti_len) { + tcpstat.tcps_rcvbyteafterwin += ti->ti_len; + /* + * If a new connection request is received + * while in TIME_WAIT, drop the old connection + * and start over if the sequence numbers + * are above the previous ones. + */ + if (tiflags & TH_SYN && + tp->t_state == TCPS_TIME_WAIT && + SEQ_GT(ti->ti_seq, tp->rcv_nxt)) { + iss = tp->rcv_nxt + TCP_ISSINCR; + tp = tcp_close(tp); + goto findso; + } + /* + * If window is closed can only take segments at + * window edge, and have to drop data and PUSH from + * incoming segments. Continue processing, but + * remember to ack. Otherwise, drop segment + * and ack. + */ + if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { + tp->t_flags |= TF_ACKNOW; + tcpstat.tcps_rcvwinprobe++; + } else + goto dropafterack; + } else + tcpstat.tcps_rcvbyteafterwin += todrop; + m_adj(m, -todrop); + ti->ti_len -= todrop; + tiflags &= ~(TH_PUSH|TH_FIN); + } + + /* + * If last ACK falls within this segment's sequence numbers, + * record its timestamp. + */ +/* if (ts_present && SEQ_LEQ(ti->ti_seq, tp->last_ack_sent) && + * SEQ_LT(tp->last_ack_sent, ti->ti_seq + ti->ti_len + + * ((tiflags & (TH_SYN|TH_FIN)) != 0))) { + * tp->ts_recent_age = tcp_now; + * tp->ts_recent = ts_val; + * } + */ + + /* + * If the RST bit is set examine the state: + * SYN_RECEIVED STATE: + * If passive open, return to LISTEN state. + * If active open, inform user that connection was refused. + * ESTABLISHED, FIN_WAIT_1, FIN_WAIT2, CLOSE_WAIT STATES: + * Inform user that connection was reset, and close tcb. + * CLOSING, LAST_ACK, TIME_WAIT STATES + * Close the tcb. + */ + if (tiflags&TH_RST) switch (tp->t_state) { + + case TCPS_SYN_RECEIVED: +/* so->so_error = ECONNREFUSED; */ + goto close; + + case TCPS_ESTABLISHED: + case TCPS_FIN_WAIT_1: + case TCPS_FIN_WAIT_2: + case TCPS_CLOSE_WAIT: +/* so->so_error = ECONNRESET; */ + close: + tp->t_state = TCPS_CLOSED; + tcpstat.tcps_drops++; + tp = tcp_close(tp); + goto drop; + + case TCPS_CLOSING: + case TCPS_LAST_ACK: + case TCPS_TIME_WAIT: + tp = tcp_close(tp); + goto drop; + } + + /* + * If a SYN is in the window, then this is an + * error and we send an RST and drop the connection. + */ + if (tiflags & TH_SYN) { + tp = tcp_drop(tp,0); + goto dropwithreset; + } + + /* + * If the ACK bit is off we drop the segment and return. + */ + if ((tiflags & TH_ACK) == 0) goto drop; + + /* + * Ack processing. + */ + switch (tp->t_state) { + /* + * In SYN_RECEIVED state if the ack ACKs our SYN then enter + * ESTABLISHED state and continue processing, otherwise + * send an RST. una<=ack<=max + */ + case TCPS_SYN_RECEIVED: + + if (SEQ_GT(tp->snd_una, ti->ti_ack) || + SEQ_GT(ti->ti_ack, tp->snd_max)) + goto dropwithreset; + tcpstat.tcps_connects++; + tp->t_state = TCPS_ESTABLISHED; + /* + * The sent SYN is ack'ed with our sequence number +1 + * The first data byte already in the buffer will get + * lost if no correction is made. This is only needed for + * SS_CTL since the buffer is empty otherwise. + * tp->snd_una++; or: + */ + tp->snd_una=ti->ti_ack; + if (so->so_state & SS_CTL) { + /* So tcp_ctl reports the right state */ + ret = tcp_ctl(so); + if (ret == 1) { + soisfconnected(so); + so->so_state &= ~SS_CTL; /* success XXX */ + } else if (ret == 2) { + so->so_state = SS_NOFDREF; /* CTL_CMD */ + } else { + needoutput = 1; + tp->t_state = TCPS_FIN_WAIT_1; + } + } else { + soisfconnected(so); + } + + /* Do window scaling? */ +/* if ((tp->t_flags & (TF_RCVD_SCALE|TF_REQ_SCALE)) == + * (TF_RCVD_SCALE|TF_REQ_SCALE)) { + * tp->snd_scale = tp->requested_s_scale; + * tp->rcv_scale = tp->request_r_scale; + * } + */ + (void) tcp_reass(tp, (struct tcpiphdr *)0, (struct SLIRPmbuf *)0); + tp->snd_wl1 = ti->ti_seq - 1; + /* Avoid ack processing; snd_una==ti_ack => dup ack */ + goto synrx_to_est; + /* fall into ... */ + + /* + * In ESTABLISHED state: drop duplicate ACKs; ACK out of range + * ACKs. If the ack is in the range + * tp->snd_una < ti->ti_ack <= tp->snd_max + * then advance tp->snd_una to ti->ti_ack and drop + * data from the retransmission queue. If this ACK reflects + * more up to date window information we update our window information. + */ + case TCPS_ESTABLISHED: + case TCPS_FIN_WAIT_1: + case TCPS_FIN_WAIT_2: + case TCPS_CLOSE_WAIT: + case TCPS_CLOSING: + case TCPS_LAST_ACK: + case TCPS_TIME_WAIT: + + if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { + if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { + tcpstat.tcps_rcvdupack++; + DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", + (long )m, (long )so)); + /* + * If we have outstanding data (other than + * a window probe), this is a completely + * duplicate ack (ie, window info didn't + * change), the ack is the biggest we've + * seen and we've seen exactly our rexmt + * threshold of them, assume a packet + * has been dropped and retransmit it. + * Kludge snd_nxt & the congestion + * window so we send only this one + * packet. + * + * We know we're losing at the current + * window size so do congestion avoidance + * (set ssthresh to half the current window + * and pull our congestion window back to + * the new ssthresh). + * + * Dup acks mean that packets have left the + * network (they're now cached at the receiver) + * so bump cwnd by the amount in the receiver + * to keep a constant cwnd packets in the + * network. + */ + if (tp->t_timer[TCPT_REXMT] == 0 || + ti->ti_ack != tp->snd_una) + tp->t_dupacks = 0; + else if (++tp->t_dupacks == tcprexmtthresh) { + tcp_seq onxt = tp->snd_nxt; + u_int win = + min(tp->snd_wnd, tp->snd_cwnd) / 2 / + tp->t_maxseg; + + if (win < 2) + win = 2; + tp->snd_ssthresh = win * tp->t_maxseg; + tp->t_timer[TCPT_REXMT] = 0; + tp->t_rtt = 0; + tp->snd_nxt = ti->ti_ack; + tp->snd_cwnd = tp->t_maxseg; + (void) tcp_output(tp); + tp->snd_cwnd = tp->snd_ssthresh + + tp->t_maxseg * tp->t_dupacks; + if (SEQ_GT(onxt, tp->snd_nxt)) + tp->snd_nxt = onxt; + goto drop; + } else if (tp->t_dupacks > tcprexmtthresh) { + tp->snd_cwnd += tp->t_maxseg; + (void) tcp_output(tp); + goto drop; + } + } else + tp->t_dupacks = 0; + break; + } + synrx_to_est: + /* + * If the congestion window was inflated to account + * for the other side's cached packets, retract it. + */ + if (tp->t_dupacks > tcprexmtthresh && + tp->snd_cwnd > tp->snd_ssthresh) + tp->snd_cwnd = tp->snd_ssthresh; + tp->t_dupacks = 0; + if (SEQ_GT(ti->ti_ack, tp->snd_max)) { + tcpstat.tcps_rcvacktoomuch++; + goto dropafterack; + } + acked = ti->ti_ack - tp->snd_una; + tcpstat.tcps_rcvackpack++; + tcpstat.tcps_rcvackbyte += acked; + + /* + * If we have a timestamp reply, update smoothed + * round trip time. If no timestamp is present but + * transmit timer is running and timed sequence + * number was acked, update smoothed round trip time. + * Since we now have an rtt measurement, cancel the + * timer backoff (cf., Phil Karn's retransmit alg.). + * Recompute the initial retransmit timer. + */ +/* if (ts_present) + * tcp_xmit_timer(tp, tcp_now-ts_ecr+1); + * else + */ + if (tp->t_rtt && SEQ_GT(ti->ti_ack, tp->t_rtseq)) + tcp_xmit_timer(tp,tp->t_rtt); + + /* + * If all outstanding data is acked, stop retransmit + * timer and remember to restart (more output or persist). + * If there is more data to be acked, restart retransmit + * timer, using current (possibly backed-off) value. + */ + if (ti->ti_ack == tp->snd_max) { + tp->t_timer[TCPT_REXMT] = 0; + needoutput = 1; + } else if (tp->t_timer[TCPT_PERSIST] == 0) + tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; + /* + * When new data is acked, open the congestion window. + * If the window gives us less than ssthresh packets + * in flight, open exponentially (maxseg per packet). + * Otherwise open linearly: maxseg per window + * (maxseg^2 / cwnd per packet). + */ + { + u_int cw = tp->snd_cwnd; + u_int incr = tp->t_maxseg; + + if (cw > tp->snd_ssthresh) + incr = incr * incr / cw; + tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<snd_scale); + } + if (acked > so->so_snd.sb_cc) { + tp->snd_wnd -= so->so_snd.sb_cc; + sbdrop(&so->so_snd, (int )so->so_snd.sb_cc); + ourfinisacked = 1; + } else { + sbdrop(&so->so_snd, acked); + tp->snd_wnd -= acked; + ourfinisacked = 0; + } + /* + * XXX sowwakup is called when data is acked and there's room for + * for more data... it should read() the socket + */ +/* if (so->so_snd.sb_flags & SB_NOTIFY) + * sowwakeup(so); + */ + tp->snd_una = ti->ti_ack; + if (SEQ_LT(tp->snd_nxt, tp->snd_una)) + tp->snd_nxt = tp->snd_una; + + switch (tp->t_state) { + + /* + * In FIN_WAIT_1 STATE in addition to the processing + * for the ESTABLISHED state if our FIN is now acknowledged + * then enter FIN_WAIT_2. + */ + case TCPS_FIN_WAIT_1: + if (ourfinisacked) { + /* + * If we can't receive any more + * data, then closing user can proceed. + * Starting the timer is contrary to the + * specification, but if we don't get a FIN + * we'll hang forever. + */ + if (so->so_state & SS_FCANTRCVMORE) { + soisfdisconnected(so); + tp->t_timer[TCPT_2MSL] = tcp_maxidle; + } + tp->t_state = TCPS_FIN_WAIT_2; + } + break; + + /* + * In CLOSING STATE in addition to the processing for + * the ESTABLISHED state if the ACK acknowledges our FIN + * then enter the TIME-WAIT state, otherwise ignore + * the segment. + */ + case TCPS_CLOSING: + if (ourfinisacked) { + tp->t_state = TCPS_TIME_WAIT; + tcp_canceltimers(tp); + tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; + soisfdisconnected(so); + } + break; + + /* + * In LAST_ACK, we may still be waiting for data to drain + * and/or to be acked, as well as for the ack of our FIN. + * If our FIN is now acknowledged, delete the TCB, + * enter the closed state and return. + */ + case TCPS_LAST_ACK: + if (ourfinisacked) { + tp = tcp_close(tp); + goto drop; + } + break; + + /* + * In TIME_WAIT state the only thing that should arrive + * is a retransmission of the remote FIN. Acknowledge + * it and restart the finack timer. + */ + case TCPS_TIME_WAIT: + tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; + goto dropafterack; + } + } /* switch(tp->t_state) */ + +step6: + /* + * Update window information. + * Don't look at window if no ACK: TAC's send garbage on first SYN. + */ + if ((tiflags & TH_ACK) && + (SEQ_LT(tp->snd_wl1, ti->ti_seq) || + (tp->snd_wl1 == ti->ti_seq && (SEQ_LT(tp->snd_wl2, ti->ti_ack) || + (tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd))))) { + /* keep track of pure window updates */ + if (ti->ti_len == 0 && + tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) + tcpstat.tcps_rcvwinupd++; + tp->snd_wnd = tiwin; + tp->snd_wl1 = ti->ti_seq; + tp->snd_wl2 = ti->ti_ack; + if (tp->snd_wnd > tp->max_sndwnd) + tp->max_sndwnd = tp->snd_wnd; + needoutput = 1; + } + + /* + * Process segments with URG. + */ + if ((tiflags & TH_URG) && ti->ti_urp && + TCPS_HAVERCVDFIN(tp->t_state) == 0) { + /* + * This is a kludge, but if we receive and accept + * random urgent pointers, we'll crash in + * soreceive. It's hard to imagine someone + * actually wanting to send this much urgent data. + */ + if (ti->ti_urp + so->so_rcv.sb_cc > so->so_rcv.sb_datalen) { + ti->ti_urp = 0; + tiflags &= ~TH_URG; + goto dodata; + } + /* + * If this segment advances the known urgent pointer, + * then mark the data stream. This should not happen + * in CLOSE_WAIT, CLOSING, LAST_ACK or TIME_WAIT STATES since + * a FIN has been received from the remote side. + * In these states we ignore the URG. + * + * According to RFC961 (Assigned Protocols), + * the urgent pointer points to the last octet + * of urgent data. We continue, however, + * to consider it to indicate the first octet + * of data past the urgent section as the original + * spec states (in one of two places). + */ + if (SEQ_GT(ti->ti_seq+ti->ti_urp, tp->rcv_up)) { + tp->rcv_up = ti->ti_seq + ti->ti_urp; + so->so_urgc = so->so_rcv.sb_cc + + (tp->rcv_up - tp->rcv_nxt); /* -1; */ + tp->rcv_up = ti->ti_seq + ti->ti_urp; + + } + } else + /* + * If no out of band data is expected, + * pull receive urgent pointer along + * with the receive window. + */ + if (SEQ_GT(tp->rcv_nxt, tp->rcv_up)) + tp->rcv_up = tp->rcv_nxt; +dodata: + + /* + * Process the segment text, merging it into the TCP sequencing queue, + * and arranging for acknowledgment of receipt if necessary. + * This process logically involves adjusting tp->rcv_wnd as data + * is presented to the user (this happens in tcp_usrreq.c, + * case PRU_RCVD). If a FIN has already been received on this + * connection then we just ignore the text. + */ + if ((ti->ti_len || (tiflags&TH_FIN)) && + TCPS_HAVERCVDFIN(tp->t_state) == 0) { + TCP_REASS(tp, ti, m, so, tiflags); + /* + * Note the amount of data that peer has sent into + * our window, in order to estimate the sender's + * buffer size. + */ + len = so->so_rcv.sb_datalen - (tp->rcv_adv - tp->rcv_nxt); + } else { + m_free(m); + tiflags &= ~TH_FIN; + } + + /* + * If FIN is received ACK the FIN and let the user know + * that the connection is closing. + */ + if (tiflags & TH_FIN) { + if (TCPS_HAVERCVDFIN(tp->t_state) == 0) { + /* + * If we receive a FIN we can't send more data, + * set it SS_FDRAIN + * Shutdown the socket if there is no rx data in the + * buffer. + * soread() is called on completion of shutdown() and + * will got to TCPS_LAST_ACK, and use tcp_output() + * to send the FIN. + */ +/* sofcantrcvmore(so); */ + sofwdrain(so); + + tp->t_flags |= TF_ACKNOW; + tp->rcv_nxt++; + } + switch (tp->t_state) { + + /* + * In SYN_RECEIVED and ESTABLISHED STATES + * enter the CLOSE_WAIT state. + */ + case TCPS_SYN_RECEIVED: + case TCPS_ESTABLISHED: + if(so->so_emu == EMU_CTL) /* no shutdown on socket */ + tp->t_state = TCPS_LAST_ACK; + else + tp->t_state = TCPS_CLOSE_WAIT; + break; + + /* + * If still in FIN_WAIT_1 STATE FIN has not been acked so + * enter the CLOSING state. + */ + case TCPS_FIN_WAIT_1: + tp->t_state = TCPS_CLOSING; + break; + + /* + * In FIN_WAIT_2 state enter the TIME_WAIT state, + * starting the time-wait timer, turning off the other + * standard timers. + */ + case TCPS_FIN_WAIT_2: + tp->t_state = TCPS_TIME_WAIT; + tcp_canceltimers(tp); + tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; + soisfdisconnected(so); + break; + + /* + * In TIME_WAIT state restart the 2 MSL time_wait timer. + */ + case TCPS_TIME_WAIT: + tp->t_timer[TCPT_2MSL] = 2 * TCPTV_MSL; + break; + } + } + + /* + * If this is a small packet, then ACK now - with Nagel + * congestion avoidance sender won't send more until + * he gets an ACK. + * + * See above. + */ +/* if (ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg) { + */ +/* if ((ti->ti_len && (unsigned)ti->ti_len < tp->t_maxseg && + * (so->so_iptos & IPTOS_LOWDELAY) == 0) || + * ((so->so_iptos & IPTOS_LOWDELAY) && + * ((struct tcpiphdr_2 *)ti)->first_char == (char)27)) { + */ + if (ti->ti_len && (unsigned)ti->ti_len <= 5 && + ((struct tcpiphdr_2 *)ti)->first_char == (char)27) { + tp->t_flags |= TF_ACKNOW; + } + + /* + * Return any desired output. + */ + if (needoutput || (tp->t_flags & TF_ACKNOW)) { + (void) tcp_output(tp); + } + return; + +dropafterack: + /* + * Generate an ACK dropping incoming segment if it occupies + * sequence space, where the ACK reflects our state. + */ + if (tiflags & TH_RST) + goto drop; + m_freem(m); + tp->t_flags |= TF_ACKNOW; + (void) tcp_output(tp); + return; + +dropwithreset: + /* reuses m if m!=NULL, m_free() unnecessary */ + if (tiflags & TH_ACK) + tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST); + else { + if (tiflags & TH_SYN) ti->ti_len++; + tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0, + TH_RST|TH_ACK); + } + + return; + +drop: + /* + * Drop space held by incoming segment and return. + */ + m_free(m); + + return; +} + + /* , ts_present, ts_val, ts_ecr) */ +/* int *ts_present; + * u_int32_t *ts_val, *ts_ecr; + */ +void +tcp_dooptions(tp, cp, cnt, ti) + struct tcpcb *tp; + u_char *cp; + int cnt; + struct tcpiphdr *ti; +{ + u_int16_t mss; + int opt, optlen; + + DEBUG_CALL("tcp_dooptions"); + DEBUG_ARGS((dfd," tp = %lx cnt=%i \n", (long )tp, cnt)); + + for (; cnt > 0; cnt -= optlen, cp += optlen) { + opt = cp[0]; + if (opt == TCPOPT_EOL) + break; + if (opt == TCPOPT_NOP) + optlen = 1; + else { + optlen = cp[1]; + if (optlen <= 0) + break; + } + switch (opt) { + + default: + continue; + + case TCPOPT_MAXSEG: + if (optlen != TCPOLEN_MAXSEG) + continue; + if (!(ti->ti_flags & TH_SYN)) + continue; + memcpy((char *) &mss, (char *) cp + 2, sizeof(mss)); + NTOHS(mss); + (void) tcp_mss(tp, mss); /* sets t_maxseg */ + break; + +/* case TCPOPT_WINDOW: + * if (optlen != TCPOLEN_WINDOW) + * continue; + * if (!(ti->ti_flags & TH_SYN)) + * continue; + * tp->t_flags |= TF_RCVD_SCALE; + * tp->requested_s_scale = min(cp[2], TCP_MAX_WINSHIFT); + * break; + */ +/* case TCPOPT_TIMESTAMP: + * if (optlen != TCPOLEN_TIMESTAMP) + * continue; + * *ts_present = 1; + * memcpy((char *) ts_val, (char *)cp + 2, sizeof(*ts_val)); + * NTOHL(*ts_val); + * memcpy((char *) ts_ecr, (char *)cp + 6, sizeof(*ts_ecr)); + * NTOHL(*ts_ecr); + * + */ /* + * * A timestamp received in a SYN makes + * * it ok to send timestamp requests and replies. + * */ +/* if (ti->ti_flags & TH_SYN) { + * tp->t_flags |= TF_RCVD_TSTMP; + * tp->ts_recent = *ts_val; + * tp->ts_recent_age = tcp_now; + * } + */ break; + } + } +} + + +/* + * Pull out of band byte out of a segment so + * it doesn't appear in the user's data queue. + * It is still reflected in the segment length for + * sequencing purposes. + */ + +#ifdef notdef + +void +tcp_pulloutofband(so, ti, m) + struct SLIRPsocket *so; + struct tcpiphdr *ti; + struct SLIRPmbuf *m; +{ + int cnt = ti->ti_urp - 1; + + while (cnt >= 0) { + if (m->m_len > cnt) { + char *cp = mtod(m, SLIRPcaddr_t) + cnt; + struct tcpcb *tp = sototcpcb(so); + + tp->t_iobc = *cp; + tp->t_oobflags |= TCPOOB_HAVEDATA; + memcpy(sp, cp+1, (unsigned)(m->m_len - cnt - 1)); + m->m_len--; + return; + } + cnt -= m->m_len; + m = m->m_next; /* XXX WRONG! Fix it! */ + if (m == 0) + break; + } + panic("tcp_pulloutofband"); +} + +#endif /* notdef */ + +/* + * Collect new round-trip time estimate + * and update averages and current timeout. + */ + +void +tcp_xmit_timer(tp, rtt) + struct tcpcb *tp; + int rtt; +{ + short delta; + + DEBUG_CALL("tcp_xmit_timer"); + DEBUG_ARG("tp = %lx", (long)tp); + DEBUG_ARG("rtt = %d", rtt); + + tcpstat.tcps_rttupdated++; + if (tp->t_srtt != 0) { + /* + * srtt is stored as fixed point with 3 bits after the + * binary point (i.e., scaled by 8). The following magic + * is equivalent to the smoothing algorithm in rfc793 with + * an alpha of .875 (srtt = rtt/8 + srtt*7/8 in fixed + * point). Adjust rtt to origin 0. + */ + delta = rtt - 1 - (tp->t_srtt >> TCP_RTT_SHIFT); + if ((tp->t_srtt += delta) <= 0) + tp->t_srtt = 1; + /* + * We accumulate a smoothed rtt variance (actually, a + * smoothed mean difference), then set the retransmit + * timer to smoothed rtt + 4 times the smoothed variance. + * rttvar is stored as fixed point with 2 bits after the + * binary point (scaled by 4). The following is + * equivalent to rfc793 smoothing with an alpha of .75 + * (rttvar = rttvar*3/4 + |delta| / 4). This replaces + * rfc793's wired-in beta. + */ + if (delta < 0) + delta = -delta; + delta -= (tp->t_rttvar >> TCP_RTTVAR_SHIFT); + if ((tp->t_rttvar += delta) <= 0) + tp->t_rttvar = 1; + } else { + /* + * No rtt measurement yet - use the unsmoothed rtt. + * Set the variance to half the rtt (so our first + * retransmit happens at 3*rtt). + */ + tp->t_srtt = rtt << TCP_RTT_SHIFT; + tp->t_rttvar = rtt << (TCP_RTTVAR_SHIFT - 1); + } + tp->t_rtt = 0; + tp->t_rxtshift = 0; + + /* + * the retransmit should happen at rtt + 4 * rttvar. + * Because of the way we do the smoothing, srtt and rttvar + * will each average +1/2 tick of bias. When we compute + * the retransmit timer, we want 1/2 tick of rounding and + * 1 extra tick because of +-1/2 tick uncertainty in the + * firing of the timer. The bias will give us exactly the + * 1.5 tick we need. But, because the bias is + * statistical, we have to test that we don't drop below + * the minimum feasible timer (which is 2 ticks). + */ + TCPT_RANGESET(tp->t_rxtcur, TCP_REXMTVAL(tp), + (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ + + /* + * We received an ack for a packet that wasn't retransmitted; + * it is probably safe to discard any error indications we've + * received recently. This isn't quite right, but close enough + * for now (a route might have failed after we sent a segment, + * and the return path might not be symmetrical). + */ + tp->t_softerror = 0; +} + +/* + * Determine a reasonable value for maxseg size. + * If the route is known, check route for mtu. + * If none, use an mss that can be handled on the outgoing + * interface without forcing IP to fragment; if bigger than + * an SLIRPmbuf cluster (MCLBYTES), round down to nearest multiple of MCLBYTES + * to utilize large SLIRPmbufs. If no route is found, route has no mtu, + * or the destination isn't local, use a default, hopefully conservative + * size (usually 512 or the default IP max size, but no more than the mtu + * of the interface), as we can't discover anything about intervening + * gateways or networks. We also initialize the congestion/slow start + * window to be a single segment if the destination isn't local. + * While looking at the routing entry, we also initialize other path-dependent + * parameters from pre-set or cached values in the routing entry. + */ + +int +tcp_mss(tp, offer) + struct tcpcb *tp; + u_int offer; +{ + struct SLIRPsocket *so = tp->t_socket; + int mss; + + DEBUG_CALL("tcp_mss"); + DEBUG_ARG("tp = %lx", (long)tp); + DEBUG_ARG("offer = %d", offer); + + mss = min(if_mtu, if_mru) - sizeof(struct tcpiphdr); + if (offer) + mss = min(mss, offer); + mss = max(mss, 32); + if (mss < tp->t_maxseg || offer != 0) + tp->t_maxseg = mss; + + tp->snd_cwnd = mss; + + sbreserve(&so->so_snd, tcp_sndspace+((tcp_sndspace%mss)?(mss-(tcp_sndspace%mss)):0)); + sbreserve(&so->so_rcv, tcp_rcvspace+((tcp_rcvspace%mss)?(mss-(tcp_rcvspace%mss)):0)); + + DEBUG_MISC((dfd, " returning mss = %d\n", mss)); + + return mss; +} diff --git a/src/slirp/tcp_output.c b/src/slirp/tcp_output.c new file mode 100644 index 0000000..8bafb82 --- /dev/null +++ b/src/slirp/tcp_output.c @@ -0,0 +1,601 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1990, 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. + * + * @(#)tcp_output.c 8.3 (Berkeley) 12/30/93 + * tcp_output.c,v 1.3 1994/09/15 10:36:55 davidg Exp + */ + +/* + * Changes and additions relating to SLiRP + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include "slirp.h" + +/* + * Since this is only used in "stats socket", we give meaning + * names instead of the REAL names + */ +char *tcpstates[] = { +/* "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", */ + "REDIRECT", "LISTEN", "SYN_SENT", "SYN_RCVD", + "ESTABLISHED", "CLOSE_WAIT", "FIN_WAIT_1", "CLOSING", + "LAST_ACK", "FIN_WAIT_2", "TIME_WAIT", +}; + +u_char tcp_outflags[TCP_NSTATES] = { + TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK, + TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, + TH_FIN|TH_ACK, TH_ACK, TH_ACK, +}; + + +#define MAX_TCPOPTLEN 32 /* max # bytes that go in options */ + +/* + * Tcp output routine: figure out what should be sent and send it. + */ +int +tcp_output(tp) + struct tcpcb *tp; +{ + struct SLIRPsocket *so = tp->t_socket; + register long len, win; + int off, flags, error; + struct SLIRPmbuf *m; + struct tcpiphdr *ti; + u_char opt[MAX_TCPOPTLEN]; + unsigned optlen, hdrlen; + int idle, sendalot; + + DEBUG_CALL("tcp_output"); + DEBUG_ARG("tp = %lx", (long )tp); + + /* + * Determine length of data that should be transmitted, + * and flags that will be used. + * If there is some data or critical controls (SYN, RST) + * to send, then transmit; otherwise, investigate further. + */ + idle = (tp->snd_max == tp->snd_una); + if (idle && tp->t_idle >= tp->t_rxtcur) + /* + * We have been idle for "a while" and no acks are + * expected to clock out any data we send -- + * slow start to get ack "clock" running again. + */ + tp->snd_cwnd = tp->t_maxseg; +again: + sendalot = 0; + off = tp->snd_nxt - tp->snd_una; + win = min(tp->snd_wnd, tp->snd_cwnd); + + flags = tcp_outflags[tp->t_state]; + + DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n",flags)); + + /* + * If in persist timeout with window of 0, send 1 byte. + * Otherwise, if window is small but nonzero + * and timer expired, we will send what we can + * and go to transmit state. + */ + if (tp->t_force) { + if (win == 0) { + /* + * If we still have some data to send, then + * clear the FIN bit. Usually this would + * happen below when it realizes that we + * aren't sending all the data. However, + * if we have exactly 1 byte of unset data, + * then it won't clear the FIN bit below, + * and if we are in persist state, we wind + * up sending the packet without recording + * that we sent the FIN bit. + * + * We can't just blindly clear the FIN bit, + * because if we don't have any more data + * to send then the probe will be the FIN + * itself. + */ + if (off < so->so_snd.sb_cc) + flags &= ~TH_FIN; + win = 1; + } else { + tp->t_timer[TCPT_PERSIST] = 0; + tp->t_rxtshift = 0; + } + } + + len = min(so->so_snd.sb_cc, win) - off; + + if (len < 0) { + /* + * If FIN has been sent but not acked, + * but we haven't been called to retransmit, + * len will be -1. Otherwise, window shrank + * after we sent into it. If window shrank to 0, + * cancel pending retransmit and pull snd_nxt + * back to (closed) window. We will enter persist + * state below. If the window didn't close completely, + * just wait for an ACK. + */ + len = 0; + if (win == 0) { + tp->t_timer[TCPT_REXMT] = 0; + tp->snd_nxt = tp->snd_una; + } + } + + if (len > tp->t_maxseg) { + len = tp->t_maxseg; + sendalot = 1; + } + if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) + flags &= ~TH_FIN; + + win = sbspace(&so->so_rcv); + + /* + * Sender silly window avoidance. If connection is idle + * and can send all data, a maximum segment, + * at least a maximum default-size segment do it, + * or are forced, do it; otherwise don't bother. + * If peer's buffer is tiny, then send + * when window is at least half open. + * If retransmitting (possibly after persist timer forced us + * to send into a small window), then must resend. + */ + if (len) { + if (len == tp->t_maxseg) + goto send; + if ((1 || idle || tp->t_flags & TF_NODELAY) && + len + off >= so->so_snd.sb_cc) + goto send; + if (tp->t_force) + goto send; + if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0) + goto send; + if (SEQ_LT(tp->snd_nxt, tp->snd_max)) + goto send; + } + + /* + * Compare available window to amount of window + * known to peer (as advertised window less + * next expected input). If the difference is at least two + * max size segments, or at least 50% of the maximum possible + * window, then want to send a window update to peer. + */ + if (win > 0) { + /* + * "adv" is the amount we can increase the window, + * taking into account that we are limited by + * TCP_MAXWIN << tp->rcv_scale. + */ + long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - + (tp->rcv_adv - tp->rcv_nxt); + + if (adv >= (long) (2 * tp->t_maxseg)) + goto send; + if (2 * adv >= (long) so->so_rcv.sb_datalen) + goto send; + } + + /* + * Send if we owe peer an ACK. + */ + if (tp->t_flags & TF_ACKNOW) + goto send; + if (flags & (TH_SYN|TH_RST)) + goto send; + if (SEQ_GT(tp->snd_up, tp->snd_una)) + goto send; + /* + * If our state indicates that FIN should be sent + * and we have not yet done so, or we're retransmitting the FIN, + * then we need to send. + */ + if (flags & TH_FIN && + ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una)) + goto send; + + /* + * TCP window updates are not reliable, rather a polling protocol + * using ``persist'' packets is used to insure receipt of window + * updates. The three ``states'' for the output side are: + * idle not doing retransmits or persists + * persisting to move a small or zero window + * (re)transmitting and thereby not persisting + * + * tp->t_timer[TCPT_PERSIST] + * is set when we are in persist state. + * tp->t_force + * is set when we are called to send a persist packet. + * tp->t_timer[TCPT_REXMT] + * is set when we are retransmitting + * The output side is idle when both timers are zero. + * + * If send window is too small, there is data to transmit, and no + * retransmit or persist is pending, then go to persist state. + * If nothing happens soon, send when timer expires: + * if window is nonzero, transmit what we can, + * otherwise force out a byte. + */ + if (so->so_snd.sb_cc && tp->t_timer[TCPT_REXMT] == 0 && + tp->t_timer[TCPT_PERSIST] == 0) { + tp->t_rxtshift = 0; + tcp_setpersist(tp); + } + + /* + * No reason to send a segment, just return. + */ + tcpstat.tcps_didnuttin++; + + return (0); + +send: + /* + * Before ESTABLISHED, force sending of initial options + * unless TCP set not to do any options. + * NOTE: we assume that the IP/TCP header plus TCP options + * always fit in a single SLIRPmbuf, leaving room for a maximum + * link header, i.e. + * max_linkhdr + sizeof (struct tcpiphdr) + optlen <= MHLEN + */ + optlen = 0; + hdrlen = sizeof (struct tcpiphdr); + if (flags & TH_SYN) { + tp->snd_nxt = tp->iss; + if ((tp->t_flags & TF_NOOPT) == 0) { + u_int16_t mss; + + opt[0] = TCPOPT_MAXSEG; + opt[1] = 4; + mss = htons((u_int16_t) tcp_mss(tp, 0)); + memcpy((SLIRPcaddr_t)(opt + 2), (SLIRPcaddr_t)&mss, sizeof(mss)); + optlen = 4; + +/* if ((tp->t_flags & TF_REQ_SCALE) && + * ((flags & TH_ACK) == 0 || + * (tp->t_flags & TF_RCVD_SCALE))) { + * *((u_int32_t *) (opt + optlen)) = htonl( + * TCPOPT_NOP << 24 | + * TCPOPT_WINDOW << 16 | + * TCPOLEN_WINDOW << 8 | + * tp->request_r_scale); + * optlen += 4; + * } + */ + } + } + + /* + * Send a timestamp and echo-reply if this is a SYN and our side + * wants to use timestamps (TF_REQ_TSTMP is set) or both our side + * and our peer have sent timestamps in our SYN's. + */ +/* if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP && + * (flags & TH_RST) == 0 && + * ((flags & (TH_SYN|TH_ACK)) == TH_SYN || + * (tp->t_flags & TF_RCVD_TSTMP))) { + * u_int32_t *lp = (u_int32_t *)(opt + optlen); + * + * / * Form timestamp option as shown in appendix A of RFC 1323. * / + * *lp++ = htonl(TCPOPT_TSTAMP_HDR); + * *lp++ = htonl(tcp_now); + * *lp = htonl(tp->ts_recent); + * optlen += TCPOLEN_TSTAMP_APPA; + * } + */ + hdrlen += optlen; + + /* + * Adjust data length if insertion of options will + * bump the packet length beyond the t_maxseg length. + */ + if (len > tp->t_maxseg - optlen) { + len = tp->t_maxseg - optlen; + sendalot = 1; + } + + /* + * Grab a header SLIRPmbuf, attaching a copy of data to + * be transmitted, and initialize the header from + * the template for sends on this connection. + */ + if (len) { + if (tp->t_force && len == 1) + tcpstat.tcps_sndprobe++; + else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { + tcpstat.tcps_sndrexmitpack++; + tcpstat.tcps_sndrexmitbyte += len; + } else { + tcpstat.tcps_sndpack++; + tcpstat.tcps_sndbyte += len; + } + + m = m_get(); + if (m == NULL) { +/* error = ENOBUFS; */ + error = 1; + goto out; + } + m->m_data += if_maxlinkhdr; + m->m_len = hdrlen; + + /* + * This will always succeed, since we make sure our SLIRPmbufs + * are big enough to hold one MSS packet + header + ... etc. + */ +/* if (len <= MHLEN - hdrlen - max_linkhdr) { */ + + sbcopy(&so->so_snd, off, (int) len, mtod(m, SLIRPcaddr_t) + hdrlen); + m->m_len += len; + +/* } else { + * m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len); + * if (m->m_next == 0) + * len = 0; + * } + */ + /* + * If we're sending everything we've got, set PUSH. + * (This will keep happy those implementations which only + * give data to the user when a buffer fills or + * a PUSH comes in.) + */ + if (off + len == so->so_snd.sb_cc) + flags |= TH_PUSH; + } else { + if (tp->t_flags & TF_ACKNOW) + tcpstat.tcps_sndacks++; + else if (flags & (TH_SYN|TH_FIN|TH_RST)) + tcpstat.tcps_sndctrl++; + else if (SEQ_GT(tp->snd_up, tp->snd_una)) + tcpstat.tcps_sndurg++; + else + tcpstat.tcps_sndwinup++; + + m = m_get(); + if (m == NULL) { +/* error = ENOBUFS; */ + error = 1; + goto out; + } + m->m_data += if_maxlinkhdr; + m->m_len = hdrlen; + } + + ti = mtod(m, struct tcpiphdr *); + + memcpy((SLIRPcaddr_t)ti, &tp->t_template, sizeof (struct tcpiphdr)); + + /* + * Fill in fields, remembering maximum advertised + * window for use in delaying messages about window sizes. + * If resending a FIN, be sure not to use a new sequence number. + */ + if (flags & TH_FIN && tp->t_flags & TF_SENTFIN && + tp->snd_nxt == tp->snd_max) + tp->snd_nxt--; + /* + * If we are doing retransmissions, then snd_nxt will + * not reflect the first unsent octet. For ACK only + * packets, we do not want the sequence number of the + * retransmitted packet, we want the sequence number + * of the next unsent octet. So, if there is no data + * (and no SYN or FIN), use snd_max instead of snd_nxt + * when filling in ti_seq. But if we are in persist + * state, snd_max might reflect one byte beyond the + * right edge of the window, so use snd_nxt in that + * case, since we know we aren't doing a retransmission. + * (retransmit and persist are mutually exclusive...) + */ + if (len || (flags & (TH_SYN|TH_FIN)) || tp->t_timer[TCPT_PERSIST]) + ti->ti_seq = htonl(tp->snd_nxt); + else + ti->ti_seq = htonl(tp->snd_max); + ti->ti_ack = htonl(tp->rcv_nxt); + if (optlen) { + memcpy((SLIRPcaddr_t)(ti + 1), (SLIRPcaddr_t)opt, optlen); + ti->ti_off = (sizeof (struct tcphdr) + optlen) >> 2; + } + ti->ti_flags = flags; + /* + * Calculate receive window. Don't shrink window, + * but avoid silly window syndrome. + */ + if (win < (long)(so->so_rcv.sb_datalen / 4) && win < (long)tp->t_maxseg) + win = 0; + if (win > (long)TCP_MAXWIN << tp->rcv_scale) + win = (long)TCP_MAXWIN << tp->rcv_scale; + if (win < (long)(tp->rcv_adv - tp->rcv_nxt)) + win = (long)(tp->rcv_adv - tp->rcv_nxt); + ti->ti_win = htons((u_int16_t) (win>>tp->rcv_scale)); + + if (SEQ_GT(tp->snd_up, tp->snd_una)) { + ti->ti_urp = htons((u_int16_t)(tp->snd_up - ntohl(ti->ti_seq))); +#ifdef notdef + if (SEQ_GT(tp->snd_up, tp->snd_nxt)) { + ti->ti_urp = htons((u_int16_t)(tp->snd_up - tp->snd_nxt)); +#endif + ti->ti_flags |= TH_URG; + } else + /* + * If no urgent pointer to send, then we pull + * the urgent pointer to the left edge of the send window + * so that it doesn't drift into the send window on sequence + * number wraparound. + */ + tp->snd_up = tp->snd_una; /* drag it along */ + + /* + * Put TCP length in extended header, and then + * checksum extended header and data. + */ + if (len + optlen) + ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + + optlen + len)); + ti->ti_sum = cksum(m, (int)(hdrlen + len)); + + /* + * In transmit state, time the transmission and arrange for + * the retransmit. In persist state, just set snd_max. + */ + if (tp->t_force == 0 || tp->t_timer[TCPT_PERSIST] == 0) { + tcp_seq startseq = tp->snd_nxt; + + /* + * Advance snd_nxt over sequence space of this segment. + */ + if (flags & (TH_SYN|TH_FIN)) { + if (flags & TH_SYN) + tp->snd_nxt++; + if (flags & TH_FIN) { + tp->snd_nxt++; + tp->t_flags |= TF_SENTFIN; + } + } + tp->snd_nxt += len; + if (SEQ_GT(tp->snd_nxt, tp->snd_max)) { + tp->snd_max = tp->snd_nxt; + /* + * Time this transmission if not a retransmission and + * not currently timing anything. + */ + if (tp->t_rtt == 0) { + tp->t_rtt = 1; + tp->t_rtseq = startseq; + tcpstat.tcps_segstimed++; + } + } + + /* + * Set retransmit timer if not currently set, + * and not doing an ack or a keep-alive probe. + * Initial value for retransmit timer is smoothed + * round-trip time + 2 * round-trip time variance. + * Initialize shift counter which is used for backoff + * of retransmit time. + */ + if (tp->t_timer[TCPT_REXMT] == 0 && + tp->snd_nxt != tp->snd_una) { + tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; + if (tp->t_timer[TCPT_PERSIST]) { + tp->t_timer[TCPT_PERSIST] = 0; + tp->t_rxtshift = 0; + } + } + } else + if (SEQ_GT(tp->snd_nxt + len, tp->snd_max)) + tp->snd_max = tp->snd_nxt + len; + + /* + * Fill in IP length and desired time to live and + * send to IP level. There should be a better way + * to handle ttl and tos; we could keep them in + * the template, but need a way to checksum without them. + */ + m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */ + + { + + ((struct ip *)ti)->ip_len = m->m_len; + + ((struct ip *)ti)->ip_ttl = ip_defttl; + ((struct ip *)ti)->ip_tos = so->so_iptos; + +/* #if BSD >= 43 */ + /* Don't do IP options... */ +/* error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, + * so->so_options & SO_DONTROUTE, 0); + */ + error = ip_output(so, m); + +/* #else + * error = ip_output(m, (struct SLIRPmbuf *)0, &tp->t_inpcb->inp_route, + * so->so_options & SO_DONTROUTE); + * #endif + */ + } + if (error) { +out: +/* if (error == ENOBUFS) { + * tcp_quench(tp->t_inpcb, 0); + * return (0); + * } + */ +/* if ((error == EHOSTUNREACH || error == ENETDOWN) + * && TCPS_HAVERCVDSYN(tp->t_state)) { + * tp->t_softerror = error; + * return (0); + * } + */ + return (error); + } + tcpstat.tcps_sndtotal++; + + /* + * Data sent (as far as we can tell). + * If this advertises a larger window than any other segment, + * then remember the size of the advertised window. + * Any pending ACK has now been sent. + */ + if (win > 0 && SEQ_GT(tp->rcv_nxt+win, tp->rcv_adv)) + tp->rcv_adv = tp->rcv_nxt + win; + tp->last_ack_sent = tp->rcv_nxt; + tp->t_flags &= ~(TF_ACKNOW|TF_DELACK); + if (sendalot) + goto again; + + return (0); +} + +void +tcp_setpersist(tp) + struct tcpcb *tp; +{ + int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; + +/* if (tp->t_timer[TCPT_REXMT]) + * panic("tcp_output REXMT"); + */ + /* + * Start/restart persistence timer. + */ + TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], + t * tcp_backoff[tp->t_rxtshift], + TCPTV_PERSMIN, TCPTV_PERSMAX); + if (tp->t_rxtshift < TCP_MAXRXTSHIFT) + tp->t_rxtshift++; +} diff --git a/src/slirp/tcp_subr.c b/src/slirp/tcp_subr.c new file mode 100644 index 0000000..f275244 --- /dev/null +++ b/src/slirp/tcp_subr.c @@ -0,0 +1,1324 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1990, 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. + * + * @(#)tcp_subr.c 8.1 (Berkeley) 6/10/93 + * tcp_subr.c,v 1.5 1994/10/08 22:39:58 phk Exp + */ + +/* + * Changes and additions relating to SLiRP + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#define WANT_SYS_IOCTL_H +#include +#include "slirp.h" + +/* patchable/settable parameters for tcp */ +int tcp_mssdflt = TCP_MSS; +int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ; +int tcp_do_rfc1323 = 0; /* Don't do rfc1323 performance enhancements */ +int tcp_rcvspace; /* You may want to change this */ +int tcp_sndspace; /* Keep small if you have an error prone link */ + +/* + * Tcp initialization + */ +void +tcp_init() +{ + tcp_iss = 1; /* wrong */ + tcb.so_next = tcb.so_prev = &tcb; + + /* tcp_rcvspace = our Window we advertise to the remote */ + tcp_rcvspace = TCP_RCVSPACE; + tcp_sndspace = TCP_SNDSPACE; + + /* Make sure tcp_sndspace is at least 2*MSS */ + if (tcp_sndspace < 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr))) + tcp_sndspace = 2*(min(if_mtu, if_mru) - sizeof(struct tcpiphdr)); +} + +/* + * Create template to be used to send tcp packets on a connection. + * Call after host entry created, fills + * in a skeletal tcp/ip header, minimizing the amount of work + * necessary when the connection is used. + */ +/* struct tcpiphdr * */ +void +tcp_template(tp) + struct tcpcb *tp; +{ + struct SLIRPsocket *so = tp->t_socket; + struct tcpiphdr *n = &tp->t_template; + + n->ti_next = n->ti_prev = 0; + n->ti_x1 = 0; + n->ti_pr = IPPROTO_TCP; + n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); + n->ti_src = so->so_faddr; + n->ti_dst = so->so_laddr; + n->ti_sport = so->so_fport; + n->ti_dport = so->so_lport; + + n->ti_seq = 0; + n->ti_ack = 0; + n->ti_x2 = 0; + n->ti_off = 5; + n->ti_flags = 0; + n->ti_win = 0; + n->ti_sum = 0; + n->ti_urp = 0; +} + +/* + * Send a single message to the TCP at address specified by + * the given TCP/IP header. If m == 0, then we make a copy + * of the tcpiphdr at ti and send directly to the addressed host. + * This is used to force keep alive messages out using the TCP + * template for a connection tp->t_template. If flags are given + * then we send a message back to the TCP which originated the + * segment ti, and discard the SLIRPmbuf containing it and any other + * attached SLIRPmbufs. + * + * In any case the ack and sequence number of the transmitted + * segment are as specified by the parameters. + */ +void +tcp_respond(tp, ti, m, ack, seq, flags) + struct tcpcb *tp; + struct tcpiphdr *ti; + struct SLIRPmbuf *m; + tcp_seq ack, seq; + int flags; +{ + register int tlen; + int win = 0; + + DEBUG_CALL("tcp_respond"); + DEBUG_ARG("tp = %lx", (long)tp); + DEBUG_ARG("ti = %lx", (long)ti); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("ack = %u", ack); + DEBUG_ARG("seq = %u", seq); + DEBUG_ARG("flags = %x", flags); + + if (tp) + win = sbspace(&tp->t_socket->so_rcv); + if (m == 0) { + if ((m = m_get()) == NULL) + return; +#ifdef TCP_COMPAT_42 + tlen = 1; +#else + tlen = 0; +#endif + m->m_data += if_maxlinkhdr; + *mtod(m, struct tcpiphdr *) = *ti; + ti = mtod(m, struct tcpiphdr *); + flags = TH_ACK; + } else { + /* + * ti points into m so the next line is just making + * the SLIRPmbuf point to ti + */ + m->m_data = (SLIRPcaddr_t)ti; + + m->m_len = sizeof (struct tcpiphdr); + tlen = 0; +#define xchg(a,b,type) { type t; t=a; a=b; b=t; } + xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t); + xchg(ti->ti_dport, ti->ti_sport, u_int16_t); +#undef xchg + } + ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen)); + tlen += sizeof (struct tcpiphdr); + m->m_len = tlen; + + ti->ti_next = ti->ti_prev = 0; + ti->ti_x1 = 0; + ti->ti_seq = htonl(seq); + ti->ti_ack = htonl(ack); + ti->ti_x2 = 0; + ti->ti_off = sizeof (struct tcphdr) >> 2; + ti->ti_flags = flags; + if (tp) + ti->ti_win = htons((u_int16_t) (win >> tp->rcv_scale)); + else + ti->ti_win = htons((u_int16_t)win); + ti->ti_urp = 0; + ti->ti_sum = 0; + ti->ti_sum = cksum(m, tlen); + ((struct ip *)ti)->ip_len = tlen; + + if(flags & TH_RST) + ((struct ip *)ti)->ip_ttl = MAXTTL; + else + ((struct ip *)ti)->ip_ttl = ip_defttl; + + (void) ip_output((struct SLIRPsocket *)0, m); +} + +/* + * Create a new TCP control block, making an + * empty reassembly queue and hooking it to the argument + * protocol control block. + */ +struct tcpcb * +tcp_newtcpcb(so) + struct SLIRPsocket *so; +{ + struct tcpcb *tp; + + tp = (struct tcpcb *)malloc(sizeof(*tp)); + if (tp == NULL) + return ((struct tcpcb *)0); + + memset((char *) tp, 0, sizeof(struct tcpcb)); + tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; + tp->t_maxseg = tcp_mssdflt; + + tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; + tp->t_socket = so; + + /* + * Init srtt to TCPTV_SRTTBASE (0), so we can tell that we have no + * rtt estimate. Set rttvar so that srtt + 2 * rttvar gives + * reasonable initial retransmit time. + */ + tp->t_srtt = TCPTV_SRTTBASE; + tp->t_rttvar = tcp_rttdflt * PR_SLOWHZ << 2; + tp->t_rttmin = TCPTV_MIN; + + TCPT_RANGESET(tp->t_rxtcur, + ((TCPTV_SRTTBASE >> 2) + (TCPTV_SRTTDFLT << 2)) >> 1, + TCPTV_MIN, TCPTV_REXMTMAX); + + tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT; + tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT; + tp->t_state = TCPS_CLOSED; + + so->so_tcpcb = tp; + + return (tp); +} + +/* + * Drop a TCP connection, reporting + * the specified error. If connection is synchronized, + * then send a RST to peer. + */ +struct tcpcb *tcp_drop(struct tcpcb *tp, int err) +{ +/* tcp_drop(tp, errno) + struct tcpcb *tp; + int errno; +{ +*/ + + DEBUG_CALL("tcp_drop"); + DEBUG_ARG("tp = %lx", (long)tp); + DEBUG_ARG("errno = %d", errno); + + if (TCPS_HAVERCVDSYN(tp->t_state)) { + tp->t_state = TCPS_CLOSED; + (void) tcp_output(tp); + tcpstat.tcps_drops++; + } else + tcpstat.tcps_conndrops++; +/* if (errno == ETIMEDOUT && tp->t_softerror) + * errno = tp->t_softerror; + */ +/* so->so_error = errno; */ + return (tcp_close(tp)); +} + +/* + * Close a TCP control block: + * discard all space held by the tcp + * discard internet protocol block + * wake up any sleepers + */ +struct tcpcb * +tcp_close(tp) + struct tcpcb *tp; +{ + struct tcpiphdr *t; + struct SLIRPsocket *so = tp->t_socket; + struct SLIRPmbuf *m; + + DEBUG_CALL("tcp_close"); + DEBUG_ARG("tp = %lx", (long )tp); + + /* free the reassembly queue, if any */ + t = (struct tcpiphdr *) tp->seg_next; + while (t != (struct tcpiphdr *)tp) { + t = (struct tcpiphdr *)t->ti_next; + m = (struct SLIRPmbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev); + remque_32((struct tcpiphdr *) t->ti_prev); + m_freem(m); + } + /* It's static */ +/* if (tp->t_template) + * (void) m_free(dtom(tp->t_template)); + */ +/* free(tp, M_PCB); */ + free(tp); + so->so_tcpcb = 0; + soisfdisconnected(so); + /* clobber input socket cache if we're closing the cached connection */ + if (so == tcp_last_so) + tcp_last_so = &tcb; + closesocket(so->s); + sbfree(&so->so_rcv); + sbfree(&so->so_snd); + sofree(so); + tcpstat.tcps_closed++; + return ((struct tcpcb *)0); +} + +void +tcp_drain() +{ + /* XXX */ +} + +/* + * When a source quench is received, close congestion window + * to one segment. We will gradually open it again as we proceed. + */ + +#ifdef notdef + +void +tcp_quench(i, errno) + + int errno; +{ + struct tcpcb *tp = intotcpcb(inp); + + if (tp) + tp->snd_cwnd = tp->t_maxseg; +} + +#endif /* notdef */ + +/* + * TCP protocol interface to socket abstraction. + */ + +/* + * User issued close, and wish to trail through shutdown states: + * if never received SYN, just forget it. If got a SYN from peer, + * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. + * If already got a FIN from peer, then almost done; go to LAST_ACK + * state. In all other cases, have already sent FIN to peer (e.g. + * after PRU_SHUTDOWN), and just have to play tedious game waiting + * for peer to send FIN or not respond to keep-alives, etc. + * We can let the user exit from the close as soon as the FIN is acked. + */ +void +tcp_sockclosed(tp) + struct tcpcb *tp; +{ + + DEBUG_CALL("tcp_sockclosed"); + DEBUG_ARG("tp = %lx", (long)tp); + + switch (tp->t_state) { + + case TCPS_CLOSED: + case TCPS_LISTEN: + case TCPS_SYN_SENT: + tp->t_state = TCPS_CLOSED; + tp = tcp_close(tp); + break; + + case TCPS_SYN_RECEIVED: + case TCPS_ESTABLISHED: + tp->t_state = TCPS_FIN_WAIT_1; + break; + + case TCPS_CLOSE_WAIT: + tp->t_state = TCPS_LAST_ACK; + break; + } +/* soisfdisconnecting(tp->t_socket); */ + if (tp && tp->t_state >= TCPS_FIN_WAIT_2) + soisfdisconnected(tp->t_socket); + if (tp) + tcp_output(tp); +} + +/* + * Connect to a host on the Internet + * Called by tcp_input + * Only do a connect, the tcp fields will be set in tcp_input + * return 0 if there's a result of the connect, + * else return -1 means we're still connecting + * The return value is almost always -1 since the socket is + * nonblocking. Connect returns after the SYN is sent, and does + * not wait for ACK+SYN. + */ +int tcp_fconnect(so) + struct SLIRPsocket *so; +{ + int ret=0; + + DEBUG_CALL("tcp_fconnect"); + DEBUG_ARG("so = %lx", (long )so); + + if( (ret=so->s=socket(AF_INET,SOCK_STREAM,0)) >= 0) { + int opt, s=so->s; + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + + fd_nonblock(s); + opt = 1; + setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt )); + opt = 1; + setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(opt )); + + addr.sin_family = AF_INET; + if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + /* It's an alias */ + switch(ntohl(so->so_faddr.s_addr) & 0xff) { + case CTL_DNS: + addr.sin_addr = dns_addr; + break; + case CTL_ALIAS: + default: + addr.sin_addr = loopback_addr; + break; + } + } else + addr.sin_addr = so->so_faddr; + addr.sin_port = so->so_fport; + + DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, " + "addr.sin_addr.s_addr=%.16s\n", + ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); + /* We don't care what port we get */ + ret = connect(s,(struct sockaddr *)&addr,sizeof (addr)); + + /* + * If it's not in progress, it failed, so we just return 0, + * without clearing SS_NOFDREF + */ + soisfconnecting(so); + } + + return(ret); +} + +/* + * Accept the socket and connect to the local-host + * + * We have a problem. The correct thing to do would be + * to first connect to the local-host, and only if the + * connection is accepted, then do an accept() here. + * But, a) we need to know who's trying to connect + * to the socket to be able to SYN the local-host, and + * b) we are already connected to the foreign host by + * the time it gets to accept(), so... We simply accept + * here and SYN the local-host. + */ +void +tcp_connect(inso) + struct SLIRPsocket *inso; +{ + struct SLIRPsocket *so; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(struct sockaddr_in); + struct tcpcb *tp; + int s, opt; + + DEBUG_CALL("tcp_connect"); + DEBUG_ARG("inso = %lx", (long)inso); + + /* + * If it's an SS_ACCEPTONCE socket, no need to socreate() + * another socket, just use the accept() socket. + */ + if (inso->so_state & SS_FACCEPTONCE) { + /* FACCEPTONCE already have a tcpcb */ + so = inso; + } else { + if ((so = socreate()) == NULL) { + /* If it failed, get rid of the pending connection */ + closesocket(accept(inso->s,(struct sockaddr *)&addr,&addrlen)); + return; + } + if (tcp_attach(so) < 0) { + free(so); /* NOT sofree */ + return; + } + so->so_laddr = inso->so_laddr; + so->so_lport = inso->so_lport; + } + + (void) tcp_mss(sototcpcb(so), 0); + + if ((s = accept(inso->s,(struct sockaddr *)&addr,&addrlen)) < 0) { + tcp_close(sototcpcb(so)); /* This will sofree() as well */ + return; + } + fd_nonblock(s); + opt = 1; + setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); + opt = 1; + setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); + opt = 1; + setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&opt,sizeof(int)); + + so->so_fport = addr.sin_port; + so->so_faddr = addr.sin_addr; + /* Translate connections from localhost to the real hostname */ + if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) + so->so_faddr = alias_addr; + + /* Close the accept() socket, set right state */ + if (inso->so_state & SS_FACCEPTONCE) { + closesocket(so->s); /* If we only accept once, close the accept() socket */ + so->so_state = SS_NOFDREF; /* Don't select it yet, even though we have an FD */ + /* if it's not FACCEPTONCE, it's already NOFDREF */ + } + so->s = s; + + so->so_iptos = tcp_tos(so); + tp = sototcpcb(so); + + tcp_template(tp); + + /* Compute window scaling to request. */ +/* while (tp->request_r_scale < TCP_MAX_WINSHIFT && + * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) + * tp->request_r_scale++; + */ + +/* soisconnecting(so); */ /* NOFDREF used instead */ + tcpstat.tcps_connattempt++; + + tp->t_state = TCPS_SYN_SENT; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tp->iss = tcp_iss; + tcp_iss += TCP_ISSINCR/2; + tcp_sendseqinit(tp); + tcp_output(tp); +} + +/* + * Attach a TCPCB to a socket. + */ +int +tcp_attach(so) + struct SLIRPsocket *so; +{ + if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) + return -1; + + insque(so, &tcb); + + return 0; +} + +/* + * Set the socket's type of service field + */ +struct tos_t tcptos[] = { + {0, 20, IPTOS_THROUGHPUT, 0}, /* ftp data */ + {21, 21, IPTOS_LOWDELAY, EMU_FTP}, /* ftp control */ + {0, 23, IPTOS_LOWDELAY, 0}, /* telnet */ + {0, 80, IPTOS_THROUGHPUT, 0}, /* WWW */ + {0, 513, IPTOS_LOWDELAY, EMU_RLOGIN|EMU_NOCONNECT}, /* rlogin */ + {0, 514, IPTOS_LOWDELAY, EMU_RSH|EMU_NOCONNECT}, /* shell */ + {0, 544, IPTOS_LOWDELAY, EMU_KSH}, /* kshell */ + {0, 543, IPTOS_LOWDELAY, 0}, /* klogin */ + {0, 6667, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC */ + {0, 6668, IPTOS_THROUGHPUT, EMU_IRC}, /* IRC undernet */ + {0, 7070, IPTOS_LOWDELAY, EMU_REALAUDIO }, /* RealAudio control */ + {0, 113, IPTOS_LOWDELAY, EMU_IDENT }, /* identd protocol */ + {0, 0, 0, 0} +}; + +struct emu_t *tcpemu = 0; + +/* + * Return TOS according to the above table + */ +u_int8_t +tcp_tos(so) + struct SLIRPsocket *so; +{ + int i = 0; + struct emu_t *emup; + + while(tcptos[i].tos) { + if ((tcptos[i].fport && (ntohs(so->so_fport) == tcptos[i].fport)) || + (tcptos[i].lport && (ntohs(so->so_lport) == tcptos[i].lport))) { + so->so_emu = tcptos[i].emu; + return tcptos[i].tos; + } + i++; + } + + /* Nope, lets see if there's a user-added one */ + for (emup = tcpemu; emup; emup = emup->next) { + if ((emup->fport && (ntohs(so->so_fport) == emup->fport)) || + (emup->lport && (ntohs(so->so_lport) == emup->lport))) { + so->so_emu = emup->emu; + return emup->tos; + } + } + + return 0; +} + +int do_echo = -1; + +/* + * Emulate programs that try and connect to us + * This includes ftp (the data connection is + * initiated by the server) and IRC (DCC CHAT and + * DCC SEND) for now + * + * NOTE: It's possible to crash SLiRP by sending it + * unstandard strings to emulate... if this is a problem, + * more checks are needed here + * + * XXX Assumes the whole command came in one packet + * + * XXX Some ftp clients will have their TOS set to + * LOWDELAY and so Nagel will kick in. Because of this, + * we'll get the first letter, followed by the rest, so + * we simply scan for ORT instead of PORT... + * DCC doesn't have this problem because there's other stuff + * in the packet before the DCC command. + * + * Return 1 if the SLIRPmbuf m is still valid and should be + * sbappend()ed + * + * NOTE: if you return 0 you MUST m_free() the SLIRPmbuf! + */ +int +tcp_emu(so, m) + struct SLIRPsocket *so; + struct SLIRPmbuf *m; +{ + u_int n1, n2, n3, n4, n5, n6; + char buff[256]; + u_int32_t laddr; + u_int lport; + char *bptr; + + DEBUG_CALL("tcp_emu"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("m = %lx", (long)m); + + switch(so->so_emu) { + int x, i; + + case EMU_IDENT: + /* + * Identification protocol as per rfc-1413 + */ + + { + struct SLIRPsocket *tmpso; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(struct sockaddr_in); + struct sbuf *so_rcv = &so->so_rcv; + + memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); + so_rcv->sb_wptr += m->m_len; + so_rcv->sb_rptr += m->m_len; + m->m_data[m->m_len] = 0; /* NULL terminate */ + if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { + if (sscanf(so_rcv->sb_data, "%d%*[ ,]%d", &n1, &n2) == 2) { + HTONS(n1); + HTONS(n2); + /* n2 is the one on our host */ + for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { + if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && + tmpso->so_lport == n2 && + tmpso->so_faddr.s_addr == so->so_faddr.s_addr && + tmpso->so_fport == n1) { + if (getsockname(tmpso->s, + (struct sockaddr *)&addr, &addrlen) == 0) + n2 = ntohs(addr.sin_port); + break; + } + } + } + so_rcv->sb_cc = sprintf(so_rcv->sb_data, "%d,%d\r\n", n1, n2); + so_rcv->sb_rptr = so_rcv->sb_data; + so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; + } + m_free(m); + return 0; + } + +#if 0 + case EMU_RLOGIN: + /* + * Rlogin emulation + * First we accumulate all the initial option negotiation, + * then fork_exec() rlogin according to the options + */ + { + int i, i2, n; + char *ptr; + char args[100]; + char term[100]; + struct sbuf *so_snd = &so->so_snd; + struct sbuf *so_rcv = &so->so_rcv; + + /* First check if they have a priveladged port, or too much data has arrived */ + if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || + (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { + memcpy(so_snd->sb_wptr, "Permission denied\n", 18); + so_snd->sb_wptr += 18; + so_snd->sb_cc += 18; + tcp_sockclosed(sototcpcb(so)); + m_free(m); + return 0; + } + + /* Append the current data */ + memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); + so_rcv->sb_wptr += m->m_len; + so_rcv->sb_rptr += m->m_len; + m_free(m); + + /* + * Check if we have all the initial options, + * and build argument list to rlogin while we're here + */ + n = 0; + ptr = so_rcv->sb_data; + args[0] = 0; + term[0] = 0; + while (ptr < so_rcv->sb_wptr) { + if (*ptr++ == 0) { + n++; + if (n == 2) { + sprintf(args, "rlogin -l %s %s", + ptr, inet_ntoa(so->so_faddr)); + } else if (n == 3) { + i2 = so_rcv->sb_wptr - ptr; + for (i = 0; i < i2; i++) { + if (ptr[i] == '/') { + ptr[i] = 0; +#ifdef HAVE_SETENV + sprintf(term, "%s", ptr); +#else + sprintf(term, "TERM=%s", ptr); +#endif + ptr[i] = '/'; + break; + } + } + } + } + } + + if (n != 4) + return 0; + + /* We have it, set our term variable and fork_exec() */ +#ifdef HAVE_SETENV + setenv("TERM", term, 1); +#else + putenv(term); +#endif + fork_exec(so, args, 2); + term[0] = 0; + so->so_emu = 0; + + /* And finally, send the client a 0 character */ + so_snd->sb_wptr[0] = 0; + so_snd->sb_wptr++; + so_snd->sb_cc++; + + return 0; + } + + case EMU_RSH: + /* + * rsh emulation + * First we accumulate all the initial option negotiation, + * then rsh_exec() rsh according to the options + */ + { + int n; + char *ptr; + char *user; + char *args; + struct sbuf *so_snd = &so->so_snd; + struct sbuf *so_rcv = &so->so_rcv; + + /* First check if they have a priveladged port, or too much data has arrived */ + if (ntohs(so->so_lport) > 1023 || ntohs(so->so_lport) < 512 || + (m->m_len + so_rcv->sb_wptr) > (so_rcv->sb_data + so_rcv->sb_datalen)) { + memcpy(so_snd->sb_wptr, "Permission denied\n", 18); + so_snd->sb_wptr += 18; + so_snd->sb_cc += 18; + tcp_sockclosed(sototcpcb(so)); + m_free(m); + return 0; + } + + /* Append the current data */ + memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); + so_rcv->sb_wptr += m->m_len; + so_rcv->sb_rptr += m->m_len; + m_free(m); + + /* + * Check if we have all the initial options, + * and build argument list to rlogin while we're here + */ + n = 0; + ptr = so_rcv->sb_data; + user=""; + args=""; + if (so->extra==NULL) { + struct SLIRPsocket *ns; + struct tcpcb* tp; + int port=atoi(ptr); + if (port <= 0) return 0; + if (port > 1023 || port < 512) { + memcpy(so_snd->sb_wptr, "Permission denied\n", 18); + so_snd->sb_wptr += 18; + so_snd->sb_cc += 18; + tcp_sockclosed(sototcpcb(so)); + return 0; + } + if ((ns=socreate()) == NULL) + return 0; + if (tcp_attach(ns)<0) { + free(ns); + return 0; + } + + ns->so_laddr=so->so_laddr; + ns->so_lport=htons(port); + + (void) tcp_mss(sototcpcb(ns), 0); + + ns->so_faddr=so->so_faddr; + ns->so_fport=htons(IPPORT_RESERVED-1); /* Use a fake port. */ + + if (ns->so_faddr.s_addr == 0 || + ns->so_faddr.s_addr == loopback_addr.s_addr) + ns->so_faddr = alias_addr; + + ns->so_iptos = tcp_tos(ns); + tp = sototcpcb(ns); + + tcp_template(tp); + + /* Compute window scaling to request. */ + /* while (tp->request_r_scale < TCP_MAX_WINSHIFT && + * (TCP_MAXWIN << tp->request_r_scale) < so->so_rcv.sb_hiwat) + * tp->request_r_scale++; + */ + + /*soisfconnecting(ns);*/ + + tcpstat.tcps_connattempt++; + + tp->t_state = TCPS_SYN_SENT; + tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; + tp->iss = tcp_iss; + tcp_iss += TCP_ISSINCR/2; + tcp_sendseqinit(tp); + tcp_output(tp); + so->extra=ns; + } + while (ptr < so_rcv->sb_wptr) { + if (*ptr++ == 0) { + n++; + if (n == 2) { + user=ptr; + } else if (n == 3) { + args=ptr; + } + } + } + + if (n != 4) + return 0; + + rsh_exec(so,so->extra, user, inet_ntoa(so->so_faddr), args); + so->so_emu = 0; + so->extra=NULL; + + /* And finally, send the client a 0 character */ + so_snd->sb_wptr[0] = 0; + so_snd->sb_wptr++; + so_snd->sb_cc++; + + return 0; + } + + case EMU_CTL: + { + int num; + struct sbuf *so_snd = &so->so_snd; + struct sbuf *so_rcv = &so->so_rcv; + + /* + * If there is binary data here, we save it in so->so_m + */ + if (!so->so_m) { + int rxlen; + char *rxdata; + rxdata=mtod(m, char *); + for (rxlen=m->m_len; rxlen; rxlen--) { + if (*rxdata++ & 0x80) { + so->so_m = m; + return 0; + } + } + } /* if(so->so_m==NULL) */ + + /* + * Append the line + */ + sbappendsb(so_rcv, m); + + /* To avoid going over the edge of the buffer, we reset it */ + if (so_snd->sb_cc == 0) + so_snd->sb_wptr = so_snd->sb_rptr = so_snd->sb_data; + + /* + * A bit of a hack: + * If the first packet we get here is 1 byte long, then it + * was done in telnet character mode, therefore we must echo + * the characters as they come. Otherwise, we echo nothing, + * because in linemode, the line is already echoed + * XXX two or more control connections won't work + */ + if (do_echo == -1) { + if (m->m_len == 1) do_echo = 1; + else do_echo = 0; + } + if (do_echo) { + sbappendsb(so_snd, m); + m_free(m); + tcp_output(sototcpcb(so)); /* XXX */ + } else + m_free(m); + + num = 0; + while (num < so->so_rcv.sb_cc) { + if (*(so->so_rcv.sb_rptr + num) == '\n' || + *(so->so_rcv.sb_rptr + num) == '\r') { + int n; + + *(so_rcv->sb_rptr + num) = 0; + if (ctl_password && !ctl_password_ok) { + /* Need a password */ + if (sscanf(so_rcv->sb_rptr, "pass %256s", buff) == 1) { + if (strcmp(buff, ctl_password) == 0) { + ctl_password_ok = 1; + n = sprintf(so_snd->sb_wptr, + "Password OK.\r\n"); + goto do_prompt; + } + } + n = sprintf(so_snd->sb_wptr, + "Error: Password required, log on with \"pass PASSWORD\"\r\n"); + goto do_prompt; + } + cfg_quitting = 0; + n = do_config(so_rcv->sb_rptr, so, PRN_SPRINTF); + if (!cfg_quitting) { + /* Register the printed data */ +do_prompt: + so_snd->sb_cc += n; + so_snd->sb_wptr += n; + /* Add prompt */ + n = sprintf(so_snd->sb_wptr, "Slirp> "); + so_snd->sb_cc += n; + so_snd->sb_wptr += n; + } + /* Drop so_rcv data */ + so_rcv->sb_cc = 0; + so_rcv->sb_wptr = so_rcv->sb_rptr = so_rcv->sb_data; + tcp_output(sototcpcb(so)); /* Send the reply */ + } + num++; + } + return 0; + } +#endif + case EMU_FTP: /* ftp */ + *(m->m_data+m->m_len) = 0; /* NULL terminate for strstr */ + if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { + /* + * Need to emulate the PORT command + */ + x = sscanf(bptr, "ORT %d,%d,%d,%d,%d,%d\r\n%256[^\177]", + &n1, &n2, &n3, &n4, &n5, &n6, buff); + if (x < 6) + return 1; + + laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); + lport = htons((n5 << 8) | (n6)); + + if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) + return 1; + + n6 = ntohs(so->so_fport); + + n5 = (n6 >> 8) & 0xff; + n6 &= 0xff; + + laddr = ntohl(so->so_faddr.s_addr); + + n1 = ((laddr >> 24) & 0xff); + n2 = ((laddr >> 16) & 0xff); + n3 = ((laddr >> 8) & 0xff); + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ + m->m_len += sprintf(bptr,"ORT %d,%d,%d,%d,%d,%d\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + return 1; + } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { + /* + * Need to emulate the PASV response + */ + x = sscanf(bptr, "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%256[^\177]", + &n1, &n2, &n3, &n4, &n5, &n6, buff); + if (x < 6) + return 1; + + laddr = htonl((n1 << 24) | (n2 << 16) | (n3 << 8) | (n4)); + lport = htons((n5 << 8) | (n6)); + + if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) + return 1; + + n6 = ntohs(so->so_fport); + + n5 = (n6 >> 8) & 0xff; + n6 &= 0xff; + + laddr = ntohl(so->so_faddr.s_addr); + + n1 = ((laddr >> 24) & 0xff); + n2 = ((laddr >> 16) & 0xff); + n3 = ((laddr >> 8) & 0xff); + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ + m->m_len += sprintf(bptr,"27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", + n1, n2, n3, n4, n5, n6, x==7?buff:""); + + return 1; + } + + return 1; + + case EMU_KSH: + /* + * The kshell (Kerberos rsh) and shell services both pass + * a local port port number to carry signals to the server + * and stderr to the client. It is passed at the beginning + * of the connection as a NUL-terminated decimal ASCII string. + */ + so->so_emu = 0; + for (lport = 0, i = 0; i < m->m_len-1; ++i) { + if (m->m_data[i] < '0' || m->m_data[i] > '9') + return 1; /* invalid number */ + lport *= 10; + lport += m->m_data[i] - '0'; + } + if (m->m_data[m->m_len-1] == '\0' && lport != 0 && + (so = solisten(0, so->so_laddr.s_addr, htons(lport), SS_FACCEPTONCE)) != NULL) + m->m_len = sprintf(m->m_data, "%d", ntohs(so->so_fport))+1; + return 1; + + case EMU_IRC: + /* + * Need to emulate DCC CHAT, DCC SEND and DCC MOVE + */ + *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ + if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) + return 1; + + /* The %256s is for the broken mIRC */ + if (sscanf(bptr, "DCC CHAT %256s %u %u", buff, &laddr, &lport) == 3) { + if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) + return 1; + + m->m_len = bptr - m->m_data; /* Adjust length */ + m->m_len += sprintf(bptr, "DCC CHAT chat %lu %u%c\n", + (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), 1); + } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { + if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) + return 1; + + m->m_len = bptr - m->m_data; /* Adjust length */ + m->m_len += sprintf(bptr, "DCC SEND %s %lu %u %u%c\n", + buff, (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); + } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { + if ((so = solisten(0, htonl(laddr), htons(lport), SS_FACCEPTONCE)) == NULL) + return 1; + + m->m_len = bptr - m->m_data; /* Adjust length */ + m->m_len += sprintf(bptr, "DCC MOVE %s %lu %u %u%c\n", + buff, (unsigned long)ntohl(so->so_faddr.s_addr), + ntohs(so->so_fport), n1, 1); + } + return 1; + + case EMU_REALAUDIO: + /* + * RealAudio emulation - JP. We must try to parse the incoming + * data and try to find the two characters that contain the + * port number. Then we redirect an udp port and replace the + * number with the real port we got. + * + * The 1.0 beta versions of the player are not supported + * any more. + * + * A typical packet for player version 1.0 (release version): + * + * 0000:50 4E 41 00 05 + * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P + * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH + * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v + * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB + * + * Now the port number 0x1BD7 is found at offset 0x04 of the + * Now the port number 0x1BD7 is found at offset 0x04 of the + * second packet. This time we received five bytes first and + * then the rest. You never know how many bytes you get. + * + * A typical packet for player version 2.0 (beta): + * + * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. + * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 + * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ + * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas + * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B + * + * Port number 0x1BC1 is found at offset 0x0d. + * + * This is just a horrible switch statement. Variable ra tells + * us where we're going. + */ + + bptr = m->m_data; + while (bptr < m->m_data + m->m_len) { + u_short p; + static int ra = 0; + char ra_tbl[4]; + + ra_tbl[0] = 0x50; + ra_tbl[1] = 0x4e; + ra_tbl[2] = 0x41; + ra_tbl[3] = 0; + + switch (ra) { + case 0: + case 2: + case 3: + if (*bptr++ != ra_tbl[ra]) { + ra = 0; + continue; + } + break; + + case 1: + /* + * We may get 0x50 several times, ignore them + */ + if (*bptr == 0x50) { + ra = 1; + bptr++; + continue; + } else if (*bptr++ != ra_tbl[ra]) { + ra = 0; + continue; + } + break; + + case 4: + /* + * skip version number + */ + bptr++; + break; + + case 5: + /* + * The difference between versions 1.0 and + * 2.0 is here. For future versions of + * the player this may need to be modified. + */ + if (*(bptr + 1) == 0x02) + bptr += 8; + else + bptr += 4; + break; + + case 6: + /* This is the field containing the port + * number that RA-player is listening to. + */ + lport = (((u_char*)bptr)[0] << 8) + + ((u_char *)bptr)[1]; + if (lport < 6970) + lport += 256; /* don't know why */ + if (lport < 6970 || lport > 7170) + return 1; /* failed */ + + /* try to get udp port between 6970 - 7170 */ + for (p = 6970; p < 7071; p++) { + if (udp_listen( htons(p), + so->so_laddr.s_addr, + htons(lport), + SS_FACCEPTONCE)) { + break; + } + } + if (p == 7071) + p = 0; + *(u_char *)bptr++ = (p >> 8) & 0xff; + *(u_char *)bptr++ = p & 0xff; + ra = 0; + return 1; /* port redirected, we're done */ + break; + + default: + ra = 0; + } + ra++; + } + return 1; + + default: + /* Ooops, not emulated, won't call tcp_emu again */ + so->so_emu = 0; + return 1; + } +} + +/* + * Do misc. config of SLiRP while its running. + * Return 0 if this connections is to be closed, 1 otherwise, + * return 2 if this is a command-line connection + */ +int +tcp_ctl(so) + struct SLIRPsocket *so; +{ + struct sbuf *sb = &so->so_snd; + int command; + struct ex_list *ex_ptr; + int do_pty; + // struct SLIRPsocket *tmpso; + + DEBUG_CALL("tcp_ctl"); + DEBUG_ARG("so = %lx", (long )so); + +#if 0 + /* + * Check if they're authorised + */ + if (ctl_addr.s_addr && (ctl_addr.s_addr == -1 || (so->so_laddr.s_addr != ctl_addr.s_addr))) { + sb->sb_cc = sprintf(sb->sb_wptr,"Error: Permission denied.\r\n"); + sb->sb_wptr += sb->sb_cc; + return 0; + } +#endif + command = (ntohl(so->so_faddr.s_addr) & 0xff); + + switch(command) { + default: /* Check for exec's */ + + /* + * Check if it's pty_exec + */ + for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) { + if (ex_ptr->ex_fport == so->so_fport && + command == ex_ptr->ex_addr) { + do_pty = ex_ptr->ex_pty; + goto do_exec; + } + } + + /* + * Nothing bound.. + */ + /* tcp_fconnect(so); */ + + /* FALLTHROUGH */ + case CTL_ALIAS: + sb->sb_cc = sprintf(sb->sb_wptr, + "Error: No application configured.\r\n"); + sb->sb_wptr += sb->sb_cc; + return(0); + + do_exec: + DEBUG_MISC((dfd, " executing %s \n",ex_ptr->ex_exec)); + return(fork_exec(so, ex_ptr->ex_exec, do_pty)); + +#if 0 + case CTL_CMD: + for (tmpso = tcb.so_next; tmpso != &tcb; tmpso = tmpso->so_next) { + if (tmpso->so_emu == EMU_CTL && + !(tmpso->so_tcpcb? + (tmpso->so_tcpcb->t_state & (TCPS_TIME_WAIT|TCPS_LAST_ACK)) + :0)) { + /* Ooops, control connection already active */ + sb->sb_cc = sprintf(sb->sb_wptr,"Sorry, already connected.\r\n"); + sb->sb_wptr += sb->sb_cc; + return 0; + } + } + so->so_emu = EMU_CTL; + ctl_password_ok = 0; + sb->sb_cc = sprintf(sb->sb_wptr, "Slirp command-line ready (type \"help\" for help).\r\nSlirp> "); + sb->sb_wptr += sb->sb_cc; + do_echo=-1; + return(2); +#endif + } +} diff --git a/src/slirp/tcp_timer.c b/src/slirp/tcp_timer.c new file mode 100644 index 0000000..db0c0dd --- /dev/null +++ b/src/slirp/tcp_timer.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1990, 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. + * + * @(#)tcp_timer.c 8.1 (Berkeley) 6/10/93 + * tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp + */ + +#include "slirp.h" + +int tcp_keepidle = TCPTV_KEEP_IDLE; +int tcp_keepintvl = TCPTV_KEEPINTVL; +int tcp_maxidle; +int so_options = DO_KEEPALIVE; + +struct tcpstat tcpstat; /* tcp statistics */ +u_int32_t tcp_now; /* for RFC 1323 timestamps */ + +/* + * Fast timeout routine for processing delayed acks + */ +void +tcp_fasttimo() +{ + register struct SLIRPsocket *so; + register struct tcpcb *tp; + + DEBUG_CALL("tcp_fasttimo"); + + so = tcb.so_next; + if (so) + for (; so != &tcb; so = so->so_next) + if ((tp = (struct tcpcb *)so->so_tcpcb) && + (tp->t_flags & TF_DELACK)) { + tp->t_flags &= ~TF_DELACK; + tp->t_flags |= TF_ACKNOW; + tcpstat.tcps_delack++; + (void) tcp_output(tp); + } +} + +/* + * Tcp protocol timeout routine called every 500 ms. + * Updates the timers in all active tcb's and + * causes finite state machine actions if timers expire. + */ +void +tcp_slowtimo() +{ + register struct SLIRPsocket *ip, *ipnxt; + register struct tcpcb *tp; + register int i; + + DEBUG_CALL("tcp_slowtimo"); + + tcp_maxidle = TCPTV_KEEPCNT * tcp_keepintvl; + /* + * Search through tcb's and update active timers. + */ + ip = tcb.so_next; + if (ip == 0) + return; + for (; ip != &tcb; ip = ipnxt) { + ipnxt = ip->so_next; + tp = sototcpcb(ip); + if (tp == 0) + continue; + for (i = 0; i < TCPT_NTIMERS; i++) { + if (tp->t_timer[i] && --tp->t_timer[i] == 0) { + tcp_timers(tp,i); + if (ipnxt->so_prev != ip) + goto tpgone; + } + } + tp->t_idle++; + if (tp->t_rtt) + tp->t_rtt++; +tpgone: + ; + } + tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ +#ifdef TCP_COMPAT_42 + if ((int)tcp_iss < 0) + tcp_iss = 0; /* XXX */ +#endif + tcp_now++; /* for timestamps */ +} + +/* + * Cancel all timers for TCP tp. + */ +void +tcp_canceltimers(tp) + struct tcpcb *tp; +{ + register int i; + + for (i = 0; i < TCPT_NTIMERS; i++) + tp->t_timer[i] = 0; +} + +int tcp_backoff[TCP_MAXRXTSHIFT + 1] = + { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; + +/* + * TCP timer processing. + */ +struct tcpcb * +tcp_timers(tp, timer) + struct tcpcb *tp; + int timer; +{ + int rexmt; + + DEBUG_CALL("tcp_timers"); + + switch (timer) { + + /* + * 2 MSL timeout in shutdown went off. If we're closed but + * still waiting for peer to close and connection has been idle + * too long, or if 2MSL time is up from TIME_WAIT, delete connection + * control block. Otherwise, check again in a bit. + */ + case TCPT_2MSL: + if (tp->t_state != TCPS_TIME_WAIT && + tp->t_idle <= tcp_maxidle) + tp->t_timer[TCPT_2MSL] = tcp_keepintvl; + else + tp = tcp_close(tp); + break; + + /* + * Retransmission timer went off. Message has not + * been acked within retransmit interval. Back off + * to a longer retransmit interval and retransmit one segment. + */ + case TCPT_REXMT: + + /* + * XXXXX If a packet has timed out, then remove all the queued + * packets for that session. + */ + + if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { + /* + * This is a hack to suit our terminal server here at the uni of canberra + * since they have trouble with zeroes... It usually lets them through + * unharmed, but under some conditions, it'll eat the zeros. If we + * keep retransmitting it, it'll keep eating the zeroes, so we keep + * retransmitting, and eventually the connection dies... + * (this only happens on incoming data) + * + * So, if we were gonna drop the connection from too many retransmits, + * don't... instead halve the t_maxseg, which might break up the NULLs and + * let them through + * + * *sigh* + */ + + tp->t_maxseg >>= 1; + if (tp->t_maxseg < 32) { + /* + * We tried our best, now the connection must die! + */ + tp->t_rxtshift = TCP_MAXRXTSHIFT; + tcpstat.tcps_timeoutdrop++; + tp = tcp_drop(tp, tp->t_softerror); + /* tp->t_softerror : ETIMEDOUT); */ /* XXX */ + return (tp); /* XXX */ + } + + /* + * Set rxtshift to 6, which is still at the maximum + * backoff time + */ + tp->t_rxtshift = 6; + } + tcpstat.tcps_rexmttimeo++; + rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; + TCPT_RANGESET(tp->t_rxtcur, rexmt, + (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ + tp->t_timer[TCPT_REXMT] = tp->t_rxtcur; + /* + * If losing, let the lower level know and try for + * a better route. Also, if we backed off this far, + * our srtt estimate is probably bogus. Clobber it + * so we'll take the next rtt measurement as our srtt; + * move the current srtt into rttvar to keep the current + * retransmit times until then. + */ + if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { +/* in_losing(tp->t_inpcb); */ + tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); + tp->t_srtt = 0; + } + tp->snd_nxt = tp->snd_una; + /* + * If timing a segment in this window, stop the timer. + */ + tp->t_rtt = 0; + /* + * Close the congestion window down to one segment + * (we'll open it by one segment for each ack we get). + * Since we probably have a window's worth of unacked + * data accumulated, this "slow start" keeps us from + * dumping all that data as back-to-back packets (which + * might overwhelm an intermediate gateway). + * + * There are two phases to the opening: Initially we + * open by one mss on each ack. This makes the window + * size increase exponentially with time. If the + * window is larger than the path can handle, this + * exponential growth results in dropped packet(s) + * almost immediately. To get more time between + * drops but still "push" the network to take advantage + * of improving conditions, we switch from exponential + * to linear window opening at some threshold size. + * For a threshold, we use half the current window + * size, truncated to a multiple of the mss. + * + * (the minimum cwnd that will give us exponential + * growth is 2 mss. We don't allow the threshold + * to go below this.) + */ + { + u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; + if (win < 2) + win = 2; + tp->snd_cwnd = tp->t_maxseg; + tp->snd_ssthresh = win * tp->t_maxseg; + tp->t_dupacks = 0; + } + (void) tcp_output(tp); + break; + + /* + * Persistence timer into zero window. + * Force a byte to be output, if possible. + */ + case TCPT_PERSIST: + tcpstat.tcps_persisttimeo++; + tcp_setpersist(tp); + tp->t_force = 1; + (void) tcp_output(tp); + tp->t_force = 0; + break; + + /* + * Keep-alive timer went off; send something + * or drop connection if idle for too long. + */ + case TCPT_KEEP: + tcpstat.tcps_keeptimeo++; + if (tp->t_state < TCPS_ESTABLISHED) + goto dropit; + +/* if (tp->t_socket->so_options & SO_KEEPALIVE && */ + if ((so_options) && tp->t_state <= TCPS_CLOSE_WAIT) { + if (tp->t_idle >= tcp_keepidle + tcp_maxidle) + goto dropit; + /* + * Send a packet designed to force a response + * if the peer is up and reachable: + * either an ACK if the connection is still alive, + * or an RST if the peer has closed the connection + * due to timeout or reboot. + * Using sequence number tp->snd_una-1 + * causes the transmitted zero-length segment + * to lie outside the receive window; + * by the protocol spec, this requires the + * correspondent TCP to respond. + */ + tcpstat.tcps_keepprobe++; +#ifdef TCP_COMPAT_42 + /* + * The keepalive packet must have nonzero length + * to get a 4.2 host to respond. + */ + tcp_respond(tp, &tp->t_template, (struct SLIRPmbuf *)NULL, + tp->rcv_nxt - 1, tp->snd_una - 1, 0); +#else + tcp_respond(tp, &tp->t_template, (struct SLIRPmbuf *)NULL, + tp->rcv_nxt, tp->snd_una - 1, 0); +#endif + tp->t_timer[TCPT_KEEP] = tcp_keepintvl; + } else + tp->t_timer[TCPT_KEEP] = tcp_keepidle; + break; + + dropit: + tcpstat.tcps_keepdrops++; + tp = tcp_drop(tp, 0); /* ETIMEDOUT); */ + break; + } + + return (tp); +} diff --git a/src/slirp/tcp_timer.h b/src/slirp/tcp_timer.h new file mode 100644 index 0000000..e860b42 --- /dev/null +++ b/src/slirp/tcp_timer.h @@ -0,0 +1,138 @@ +/* + * 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. + * + * @(#)tcp_timer.h 8.1 (Berkeley) 6/10/93 + * tcp_timer.h,v 1.4 1994/08/21 05:27:38 paul Exp + */ + +#ifndef _TCP_TIMER_H_ +#define _TCP_TIMER_H_ + +/* + * Definitions of the TCP timers. These timers are counted + * down PR_SLOWHZ times a second. + */ +#define TCPT_NTIMERS 4 + +#define TCPT_REXMT 0 /* retransmit */ +#define TCPT_PERSIST 1 /* retransmit persistence */ +#define TCPT_KEEP 2 /* keep alive */ +#define TCPT_2MSL 3 /* 2*msl quiet time timer */ + +/* + * The TCPT_REXMT timer is used to force retransmissions. + * The TCP has the TCPT_REXMT timer set whenever segments + * have been sent for which ACKs are expected but not yet + * received. If an ACK is received which advances tp->snd_una, + * then the retransmit timer is cleared (if there are no more + * outstanding segments) or reset to the base value (if there + * are more ACKs expected). Whenever the retransmit timer goes off, + * we retransmit one unacknowledged segment, and do a backoff + * on the retransmit timer. + * + * The TCPT_PERSIST timer is used to keep window size information + * flowing even if the window goes shut. If all previous transmissions + * have been acknowledged (so that there are no retransmissions in progress), + * and the window is too small to bother sending anything, then we start + * the TCPT_PERSIST timer. When it expires, if the window is nonzero, + * we go to transmit state. Otherwise, at intervals send a single byte + * into the peer's window to force him to update our window information. + * We do this at most as often as TCPT_PERSMIN time intervals, + * but no more frequently than the current estimate of round-trip + * packet time. The TCPT_PERSIST timer is cleared whenever we receive + * a window update from the peer. + * + * The TCPT_KEEP timer is used to keep connections alive. If an + * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time, + * but not yet established, then we drop the connection. Once the connection + * is established, if the connection is idle for TCPTV_KEEP_IDLE time + * (and keepalives have been enabled on the socket), we begin to probe + * the connection. We force the peer to send us a segment by sending: + * + * This segment is (deliberately) outside the window, and should elicit + * an ack segment in response from the peer. If, despite the TCPT_KEEP + * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE + * amount of time probing, then we drop the connection. + */ + +/* + * Time constants. + */ +#define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */ + +#define TCPTV_SRTTBASE 0 /* base roundtrip time; + if 0, no idea yet */ +#define TCPTV_SRTTDFLT ( 3*PR_SLOWHZ) /* assumed RTT if no info */ + +#define TCPTV_PERSMIN ( 5*PR_SLOWHZ) /* retransmit persistence */ +#define TCPTV_PERSMAX ( 60*PR_SLOWHZ) /* maximum persist interval */ + +#define TCPTV_KEEP_INIT ( 75*PR_SLOWHZ) /* initial connect keep alive */ +#define TCPTV_KEEP_IDLE (120*60*PR_SLOWHZ) /* dflt time before probing */ +#define TCPTV_KEEPINTVL ( 75*PR_SLOWHZ) /* default probe interval */ +#define TCPTV_KEEPCNT 8 /* max probes before drop */ + +#define TCPTV_MIN ( 1*PR_SLOWHZ) /* minimum allowable value */ +/* #define TCPTV_REXMTMAX ( 64*PR_SLOWHZ) */ /* max allowable REXMT value */ +#define TCPTV_REXMTMAX ( 12*PR_SLOWHZ) /* max allowable REXMT value */ + +#define TCP_LINGERTIME 120 /* linger at most 2 minutes */ + +#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ + + +#ifdef TCPTIMERS +char *tcptimers[] = + { "REXMT", "PERSIST", "KEEP", "2MSL" }; +#endif + +/* + * Force a time value to be in a certain range. + */ +#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \ + (tv) = (value); \ + if ((tv) < (tvmin)) \ + (tv) = (tvmin); \ + else if ((tv) > (tvmax)) \ + (tv) = (tvmax); \ +} + +extern int tcp_keepidle; /* time before keepalive probes begin */ +extern int tcp_keepintvl; /* time between keepalive probes */ +extern int tcp_maxidle; /* time to drop after starting probes */ +extern int tcp_ttl; /* time to live for TCP segs */ +extern int tcp_backoff[]; + +struct tcpcb; + +void tcp_fasttimo _P((void)); +void tcp_slowtimo _P((void)); +void tcp_canceltimers _P((struct tcpcb *)); +struct tcpcb * tcp_timers _P((register struct tcpcb *, int)); + +#endif diff --git a/src/slirp/tcp_var.h b/src/slirp/tcp_var.h new file mode 100644 index 0000000..422a57b --- /dev/null +++ b/src/slirp/tcp_var.h @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1982, 1986, 1993, 1994 + * 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. + * + * @(#)tcp_var.h 8.3 (Berkeley) 4/10/94 + * tcp_var.h,v 1.3 1994/08/21 05:27:39 paul Exp + */ + +#ifndef _TCP_VAR_H_ +#define _TCP_VAR_H_ + +#include "tcpip.h" +#include "tcp_timer.h" + +#if SIZEOF_CHAR_P == 4 + typedef struct tcpiphdr *tcpiphdrp_32; +#else + typedef u_int32_t tcpiphdrp_32; +#endif + +/* + * Tcp control block, one per tcp; fields: + */ +struct tcpcb { + tcpiphdrp_32 seg_next; /* sequencing queue */ + tcpiphdrp_32 seg_prev; + short t_state; /* state of this connection */ + short t_timer[TCPT_NTIMERS]; /* tcp timers */ + short t_rxtshift; /* log(2) of rexmt exp. backoff */ + short t_rxtcur; /* current retransmit value */ + short t_dupacks; /* consecutive dup acks recd */ + u_short t_maxseg; /* maximum segment size */ + char t_force; /* 1 if forcing out a byte */ + u_short t_flags; +#define TF_ACKNOW 0x0001 /* ack peer immediately */ +#define TF_DELACK 0x0002 /* ack, but try to delay it */ +#define TF_NODELAY 0x0004 /* don't delay packets to coalesce */ +#define TF_NOOPT 0x0008 /* don't use tcp options */ +#define TF_SENTFIN 0x0010 /* have sent FIN */ +#define TF_REQ_SCALE 0x0020 /* have/will request window scaling */ +#define TF_RCVD_SCALE 0x0040 /* other side has requested scaling */ +#define TF_REQ_TSTMP 0x0080 /* have/will request timestamps */ +#define TF_RCVD_TSTMP 0x0100 /* a timestamp was received in SYN */ +#define TF_SACK_PERMIT 0x0200 /* other side said I could SACK */ + + /* Make it static for now */ +/* struct tcpiphdr *t_template; / * skeletal packet for transmit */ + struct tcpiphdr t_template; + + struct SLIRPsocket *t_socket; /* back pointer to socket */ +/* + * The following fields are used as in the protocol specification. + * See RFC783, Dec. 1981, page 21. + */ +/* send sequence variables */ + tcp_seq snd_una; /* send unacknowledged */ + tcp_seq snd_nxt; /* send next */ + tcp_seq snd_up; /* send urgent pointer */ + tcp_seq snd_wl1; /* window update seg seq number */ + tcp_seq snd_wl2; /* window update seg ack number */ + tcp_seq iss; /* initial send sequence number */ + u_int32_t snd_wnd; /* send window */ +/* receive sequence variables */ + u_int32_t rcv_wnd; /* receive window */ + tcp_seq rcv_nxt; /* receive next */ + tcp_seq rcv_up; /* receive urgent pointer */ + tcp_seq irs; /* initial receive sequence number */ +/* + * Additional variables for this implementation. + */ +/* receive variables */ + tcp_seq rcv_adv; /* advertised window */ +/* retransmit variables */ + tcp_seq snd_max; /* highest sequence number sent; + * used to recognize retransmits + */ +/* congestion control (for slow start, source quench, retransmit after loss) */ + u_int32_t snd_cwnd; /* congestion-controlled window */ + u_int32_t snd_ssthresh; /* snd_cwnd size threshold for + * for slow start exponential to + * linear switch + */ +/* + * transmit timing stuff. See below for scale of srtt and rttvar. + * "Variance" is actually smoothed difference. + */ + short t_idle; /* inactivity time */ + short t_rtt; /* round trip time */ + tcp_seq t_rtseq; /* sequence number being timed */ + short t_srtt; /* smoothed round-trip time */ + short t_rttvar; /* variance in round-trip time */ + u_short t_rttmin; /* minimum rtt allowed */ + u_int32_t max_sndwnd; /* largest window peer has offered */ + +/* out-of-band data */ + char t_oobflags; /* have some */ + char t_iobc; /* input character */ +#define TCPOOB_HAVEDATA 0x01 +#define TCPOOB_HADDATA 0x02 + short t_softerror; /* possible error not yet reported */ + +/* RFC 1323 variables */ + u_char snd_scale; /* window scaling for send window */ + u_char rcv_scale; /* window scaling for recv window */ + u_char request_r_scale; /* pending window scaling */ + u_char requested_s_scale; + u_int32_t ts_recent; /* timestamp echo data */ + u_int32_t ts_recent_age; /* when last updated */ + tcp_seq last_ack_sent; + +}; + +#define sototcpcb(so) ((so)->so_tcpcb) + +/* + * The smoothed round-trip time and estimated variance + * are stored as fixed point numbers scaled by the values below. + * For convenience, these scales are also used in smoothing the average + * (smoothed = (1/scale)sample + ((scale-1)/scale)smoothed). + * With these scales, srtt has 3 bits to the right of the binary point, + * and thus an "ALPHA" of 0.875. rttvar has 2 bits to the right of the + * binary point, and is smoothed with an ALPHA of 0.75. + */ +#define TCP_RTT_SCALE 8 /* multiplier for srtt; 3 bits frac. */ +#define TCP_RTT_SHIFT 3 /* shift for srtt; 3 bits frac. */ +#define TCP_RTTVAR_SCALE 4 /* multiplier for rttvar; 2 bits */ +#define TCP_RTTVAR_SHIFT 2 /* multiplier for rttvar; 2 bits */ + +/* + * The initial retransmission should happen at rtt + 4 * rttvar. + * Because of the way we do the smoothing, srtt and rttvar + * will each average +1/2 tick of bias. When we compute + * the retransmit timer, we want 1/2 tick of rounding and + * 1 extra tick because of +-1/2 tick uncertainty in the + * firing of the timer. The bias will give us exactly the + * 1.5 tick we need. But, because the bias is + * statistical, we have to test that we don't drop below + * the minimum feasible timer (which is 2 ticks). + * This macro assumes that the value of TCP_RTTVAR_SCALE + * is the same as the multiplier for rttvar. + */ +#define TCP_REXMTVAL(tp) \ + (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) + +/* XXX + * We want to avoid doing m_pullup on incoming packets but that + * means avoiding dtom on the tcp reassembly code. That in turn means + * keeping an mbuf pointer in the reassembly queue (since we might + * have a cluster). As a quick hack, the source & destination + * port numbers (which are no longer needed once we've located the + * tcpcb) are overlayed with an mbuf pointer. + */ +#if SIZEOF_CHAR_P == 4 +typedef struct SLIRPmbuf *mbufp_32; +#else +typedef u_int32_t mbufp_32; +#endif +#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) + +/* + * TCP statistics. + * Many of these should be kept per connection, + * but that's inconvenient at the moment. + */ +struct tcpstat { + u_long tcps_connattempt; /* connections initiated */ + u_long tcps_accepts; /* connections accepted */ + u_long tcps_connects; /* connections established */ + u_long tcps_drops; /* connections dropped */ + u_long tcps_conndrops; /* embryonic connections dropped */ + u_long tcps_closed; /* conn. closed (includes drops) */ + u_long tcps_segstimed; /* segs where we tried to get rtt */ + u_long tcps_rttupdated; /* times we succeeded */ + u_long tcps_delack; /* delayed acks sent */ + u_long tcps_timeoutdrop; /* conn. dropped in rxmt timeout */ + u_long tcps_rexmttimeo; /* retransmit timeouts */ + u_long tcps_persisttimeo; /* persist timeouts */ + u_long tcps_keeptimeo; /* keepalive timeouts */ + u_long tcps_keepprobe; /* keepalive probes sent */ + u_long tcps_keepdrops; /* connections dropped in keepalive */ + + u_long tcps_sndtotal; /* total packets sent */ + u_long tcps_sndpack; /* data packets sent */ + u_long tcps_sndbyte; /* data bytes sent */ + u_long tcps_sndrexmitpack; /* data packets retransmitted */ + u_long tcps_sndrexmitbyte; /* data bytes retransmitted */ + u_long tcps_sndacks; /* ack-only packets sent */ + u_long tcps_sndprobe; /* window probes sent */ + u_long tcps_sndurg; /* packets sent with URG only */ + u_long tcps_sndwinup; /* window update-only packets sent */ + u_long tcps_sndctrl; /* control (SYN|FIN|RST) packets sent */ + + u_long tcps_rcvtotal; /* total packets received */ + u_long tcps_rcvpack; /* packets received in sequence */ + u_long tcps_rcvbyte; /* bytes received in sequence */ + u_long tcps_rcvbadsum; /* packets received with ccksum errs */ + u_long tcps_rcvbadoff; /* packets received with bad offset */ +/* u_long tcps_rcvshort; */ /* packets received too short */ + u_long tcps_rcvduppack; /* duplicate-only packets received */ + u_long tcps_rcvdupbyte; /* duplicate-only bytes received */ + u_long tcps_rcvpartduppack; /* packets with some duplicate data */ + u_long tcps_rcvpartdupbyte; /* dup. bytes in part-dup. packets */ + u_long tcps_rcvoopack; /* out-of-order packets received */ + u_long tcps_rcvoobyte; /* out-of-order bytes received */ + u_long tcps_rcvpackafterwin; /* packets with data after window */ + u_long tcps_rcvbyteafterwin; /* bytes rcvd after window */ + u_long tcps_rcvafterclose; /* packets rcvd after "close" */ + u_long tcps_rcvwinprobe; /* rcvd window probe packets */ + u_long tcps_rcvdupack; /* rcvd duplicate acks */ + u_long tcps_rcvacktoomuch; /* rcvd acks for unsent data */ + u_long tcps_rcvackpack; /* rcvd ack packets */ + u_long tcps_rcvackbyte; /* bytes acked by rcvd acks */ + u_long tcps_rcvwinupd; /* rcvd window update packets */ +/* u_long tcps_pawsdrop; */ /* segments dropped due to PAWS */ + u_long tcps_predack; /* times hdr predict ok for acks */ + u_long tcps_preddat; /* times hdr predict ok for data pkts */ + u_long tcps_socachemiss; /* tcp_last_so misses */ + u_long tcps_didnuttin; /* Times tcp_output didn't do anything XXX */ +}; + +extern struct tcpstat tcpstat; /* tcp statistics */ +extern u_int32_t tcp_now; /* for RFC 1323 timestamps */ + +#endif diff --git a/src/slirp/tcpip.h b/src/slirp/tcpip.h new file mode 100644 index 0000000..2edccb2 --- /dev/null +++ b/src/slirp/tcpip.h @@ -0,0 +1,70 @@ +/* + * 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. + * + * @(#)tcpip.h 8.1 (Berkeley) 6/10/93 + * tcpip.h,v 1.3 1994/08/21 05:27:40 paul Exp + */ + +#ifndef _TCPIP_H_ +#define _TCPIP_H_ + +/* + * Tcp+ip header, after ip options removed. + */ +struct tcpiphdr { + struct ipovly ti_i; /* overlaid ip structure */ + struct tcphdr ti_t; /* tcp header */ +}; +#define ti_next ti_i.ih_next +#define ti_prev ti_i.ih_prev +#define ti_x1 ti_i.ih_x1 +#define ti_pr ti_i.ih_pr +#define ti_len ti_i.ih_len +#define ti_src ti_i.ih_src +#define ti_dst ti_i.ih_dst +#define ti_sport ti_t.th_sport +#define ti_dport ti_t.th_dport +#define ti_seq ti_t.th_seq +#define ti_ack ti_t.th_ack +#define ti_x2 ti_t.th_x2 +#define ti_off ti_t.th_off +#define ti_flags ti_t.th_flags +#define ti_win ti_t.th_win +#define ti_sum ti_t.th_sum +#define ti_urp ti_t.th_urp + +/* + * Just a clean way to get to the first byte + * of the packet + */ +struct tcpiphdr_2 { + struct tcpiphdr dummy; + char first_char; +}; + +#endif diff --git a/src/slirp/tftp.c b/src/slirp/tftp.c new file mode 100644 index 0000000..3a851a6 --- /dev/null +++ b/src/slirp/tftp.c @@ -0,0 +1,331 @@ +/* + * tftp.c - a simple, read-only tftp server for qemu + * + * Copyright (c) 2004 Magnus Damm + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "slirp.h" + +struct tftp_session { + int in_use; + char filename[TFTP_FILENAME_MAX]; + + struct in_addr client_ip; + u_int16_t client_port; + + int timestamp; +}; + +struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; + +const char *tftp_prefix; + +static void tftp_session_update(struct tftp_session *spt) +{ + spt->timestamp = curtime; + spt->in_use = 1; +} + +static void tftp_session_terminate(struct tftp_session *spt) +{ + spt->in_use = 0; +} + +static int tftp_session_allocate(struct tftp_t *tp) +{ + struct tftp_session *spt; + int k; + + for (k = 0; k < TFTP_SESSIONS_MAX; k++) { + spt = &tftp_sessions[k]; + + if (!spt->in_use) + goto found; + + /* sessions time out after 5 inactive seconds */ + if ((int)(curtime - spt->timestamp) > 5000) + goto found; + } + + return -1; + + found: + memset(spt, 0, sizeof(*spt)); + memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip)); + spt->client_port = tp->udp.uh_sport; + + tftp_session_update(spt); + + return k; +} + +static int tftp_session_find(struct tftp_t *tp) +{ + struct tftp_session *spt; + int k; + + for (k = 0; k < TFTP_SESSIONS_MAX; k++) { + spt = &tftp_sessions[k]; + + if (spt->in_use) { + if (!memcmp(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip))) { + if (spt->client_port == tp->udp.uh_sport) { + return k; + } + } + } + } + + return -1; +} + +static int tftp_read_data(struct tftp_session *spt, u_int16_t block_nr, + u_int8_t *buf, int len) +{ + int fd; + int bytes_read = 0; + + fd = open(spt->filename, O_RDONLY | O_BINARY); + + if (fd < 0) { + return -1; + } + + if (len) { + lseek(fd, block_nr * 512, SEEK_SET); + + bytes_read = read(fd, buf, len); + } + + close(fd); + + return bytes_read; +} + +static int tftp_send_error(struct tftp_session *spt, + u_int16_t errorcode, const char *msg, + struct tftp_t *recv_tp) +{ + struct sockaddr_in saddr, daddr; + struct SLIRPmbuf *m; + struct tftp_t *tp; + + m = m_get(); + + if (!m) { + return -1; + } + + memset(m->m_data, 0, m->m_size); + + m->m_data += if_maxlinkhdr; + tp = (void *)m->m_data; + m->m_data += sizeof(struct udpiphdr); + + tp->tp_op = htons(TFTP_ERROR); + tp->x.tp_error.tp_error_code = htons(errorcode); + strncpy((char *)tp->x.tp_error.tp_msg, msg, sizeof(tp->x.tp_error.tp_msg)); + tp->x.tp_error.tp_msg[sizeof(tp->x.tp_error.tp_msg)-1] = 0; + + saddr.sin_addr = recv_tp->ip.ip_dst; + saddr.sin_port = recv_tp->udp.uh_dport; + + daddr.sin_addr = spt->client_ip; + daddr.sin_port = spt->client_port; + + m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - + sizeof(struct ip) - sizeof(struct udphdr); + + udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); + + tftp_session_terminate(spt); + + return 0; +} + +static int tftp_send_data(struct tftp_session *spt, + u_int16_t block_nr, + struct tftp_t *recv_tp) +{ + struct sockaddr_in saddr, daddr; + struct SLIRPmbuf *m; + struct tftp_t *tp; + int nobytes; + + if (block_nr < 1) { + return -1; + } + + m = m_get(); + + if (!m) { + return -1; + } + + memset(m->m_data, 0, m->m_size); + + m->m_data += if_maxlinkhdr; + tp = (void *)m->m_data; + m->m_data += sizeof(struct udpiphdr); + + tp->tp_op = htons(TFTP_DATA); + tp->x.tp_data.tp_block_nr = htons(block_nr); + + saddr.sin_addr = recv_tp->ip.ip_dst; + saddr.sin_port = recv_tp->udp.uh_dport; + + daddr.sin_addr = spt->client_ip; + daddr.sin_port = spt->client_port; + + nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512); + + if (nobytes < 0) { + m_free(m); + + /* send "file not found" error back */ + + tftp_send_error(spt, 1, "File not found", tp); + + return -1; + } + + m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - + sizeof(struct ip) - sizeof(struct udphdr); + + udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); + + if (nobytes == 512) { + tftp_session_update(spt); + } + else { + tftp_session_terminate(spt); + } + + return 0; +} + +static void tftp_handle_rrq(struct tftp_t *tp, int pktlen) +{ + struct tftp_session *spt; + int s, k, n; + u_int8_t *src, *dst; + + s = tftp_session_allocate(tp); + + if (s < 0) { + return; + } + + spt = &tftp_sessions[s]; + + src = tp->x.tp_buf; + dst = (u_int8_t *)spt->filename; + n = pktlen - ((uint8_t *)&tp->x.tp_buf[0] - (uint8_t *)tp); + + /* get name */ + + for (k = 0; k < n; k++) { + if (k < TFTP_FILENAME_MAX) { + dst[k] = src[k]; + } + else { + return; + } + + if (src[k] == '\0') { + break; + } + } + + if (k >= n) { + return; + } + + k++; + + /* check mode */ + if ((n - k) < 6) { + return; + } + + if (memcmp(&src[k], "octet\0", 6) != 0) { + tftp_send_error(spt, 4, "Unsupported transfer mode", tp); + return; + } + + /* do sanity checks on the filename */ + + if ((spt->filename[0] != '/') + || (spt->filename[strlen(spt->filename) - 1] == '/') + || strstr(spt->filename, "/../")) { + tftp_send_error(spt, 2, "Access violation", tp); + return; + } + + /* only allow exported prefixes */ + + if (!tftp_prefix + || (strncmp(spt->filename, tftp_prefix, strlen(tftp_prefix)) != 0)) { + tftp_send_error(spt, 2, "Access violation", tp); + return; + } + + /* check if the file exists */ + + if (tftp_read_data(spt, 0, (u_int8_t *)spt->filename, 0) < 0) { + tftp_send_error(spt, 1, "File not found", tp); + return; + } + + tftp_send_data(spt, 1, tp); +} + +static void tftp_handle_ack(struct tftp_t *tp, int pktlen) +{ + int s; + + s = tftp_session_find(tp); + + if (s < 0) { + return; + } + + if (tftp_send_data(&tftp_sessions[s], + ntohs(tp->x.tp_data.tp_block_nr) + 1, + tp) < 0) { + return; + } +} + +void tftp_input(struct SLIRPmbuf *m) +{ + struct tftp_t *tp = (struct tftp_t *)m->m_data; + + switch(ntohs(tp->tp_op)) { + case TFTP_RRQ: + tftp_handle_rrq(tp, m->m_len); + break; + + case TFTP_ACK: + tftp_handle_ack(tp, m->m_len); + break; + } +} diff --git a/src/slirp/tftp.h b/src/slirp/tftp.h new file mode 100644 index 0000000..266ce16 --- /dev/null +++ b/src/slirp/tftp.h @@ -0,0 +1,40 @@ +/* tftp defines */ + +#define TFTP_SESSIONS_MAX 3 + +#define TFTP_SERVER 69 + +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 + +#define TFTP_FILENAME_MAX 512 + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct tftp_t { + struct ip ip; + struct udphdr udp; + u_int16_t tp_op; + union { + struct { + u_int16_t tp_block_nr; + u_int8_t tp_buf[512]; + } tp_data; + struct { + u_int16_t tp_error_code; + u_int8_t tp_msg[512]; + } tp_error; + u_int8_t tp_buf[512 + 2]; + } x; +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) +#endif + +void tftp_input(struct SLIRPmbuf *m); diff --git a/src/slirp/udp.c b/src/slirp/udp.c new file mode 100644 index 0000000..928a64f --- /dev/null +++ b/src/slirp/udp.c @@ -0,0 +1,676 @@ +/* + * Copyright (c) 1982, 1986, 1988, 1990, 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_usrreq.c 8.4 (Berkeley) 1/21/94 + * udp_usrreq.c,v 1.4 1994/10/02 17:48:45 phk Exp + */ + +/* + * Changes and additions relating to SLiRP + * Copyright (c) 1995 Danny Gasparovski. + * + * Please read the file COPYRIGHT for the + * terms and conditions of the copyright. + */ + +#include +#include "slirp.h" +#include "ip_icmp.h" + +struct udpstat udpstat; + +struct SLIRPsocket udb; + +/* + * UDP protocol implementation. + * Per RFC 768, August, 1980. + */ +#ifndef COMPAT_42 +int udpcksum = 1; +#else +int udpcksum = 0; /* XXX */ +#endif + +struct SLIRPsocket *udp_last_so = &udb; + +void +udp_init() +{ + udb.so_next = udb.so_prev = &udb; +} +/* m->m_data points at ip packet header + * m->m_len length ip packet + * ip->ip_len length data (IPDU) + */ +void +udp_input(m, iphlen) + struct SLIRPmbuf *m; + int iphlen; +{ + struct ip *ip; + struct udphdr *uh; +/* struct SLIRPmbuf *opts = 0;*/ + int len; + struct ip save_ip; + struct SLIRPsocket *so; + + DEBUG_CALL("udp_input"); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("iphlen = %d", iphlen); + + udpstat.udps_ipackets++; + + /* + * Strip IP options, if any; should skip this, + * make available to user, and use on returned packets, + * but we don't yet have a way to check the checksum + * with options still present. + */ + if(iphlen > sizeof(struct ip)) { + ip_stripoptions(m, (struct SLIRPmbuf *)0); + iphlen = sizeof(struct ip); + } + + /* + * Get IP and UDP header together in first SLIRPmbuf. + */ + ip = mtod(m, struct ip *); + uh = (struct udphdr *)((SLIRPcaddr_t)ip + iphlen); + + /* + * Make SLIRPmbuf data length reflect UDP length. + * If not enough data to reflect UDP length, drop. + */ + len = ntohs((u_int16_t)uh->uh_ulen); + + if (ip->ip_len != len) { + if (len > ip->ip_len) { + udpstat.udps_badlen++; + goto bad; + } + m_adj(m, len - ip->ip_len); + ip->ip_len = len; + } + + /* + * Save a copy of the IP header in case we want restore it + * for sending an ICMP error message in response. + */ + save_ip = *ip; + save_ip.ip_len+= iphlen; /* tcp_input subtracts this */ + + /* + * Checksum extended UDP header and data. + */ + if (udpcksum && uh->uh_sum) { + ((struct ipovly *)ip)->ih_next = 0; + ((struct ipovly *)ip)->ih_prev = 0; + ((struct ipovly *)ip)->ih_x1 = 0; + ((struct ipovly *)ip)->ih_len = uh->uh_ulen; + /* keep uh_sum for ICMP reply + * uh->uh_sum = cksum(m, len + sizeof (struct ip)); + * if (uh->uh_sum) { + */ + if(cksum(m, len + sizeof(struct ip))) { + udpstat.udps_badsum++; + goto bad; + } + } + + /* + * handle DHCP/BOOTP + */ + if (ntohs(uh->uh_dport) == BOOTP_SERVER) { + bootp_input(m); + goto bad; + } + + /* + * handle TFTP + */ + if (ntohs(uh->uh_dport) == TFTP_SERVER) { + tftp_input(m); + goto bad; + } + + /* + * Locate pcb for datagram. + */ + so = udp_last_so; + if (so->so_lport != uh->uh_sport || + so->so_laddr.s_addr != ip->ip_src.s_addr) { + struct SLIRPsocket *tmp; + + for (tmp = udb.so_next; tmp != &udb; tmp = tmp->so_next) { + if (tmp->so_lport == uh->uh_sport && + tmp->so_laddr.s_addr == ip->ip_src.s_addr) { + tmp->so_faddr.s_addr = ip->ip_dst.s_addr; + tmp->so_fport = uh->uh_dport; + so = tmp; + break; + } + } + if (tmp == &udb) { + so = NULL; + } else { + udpstat.udpps_pcbcachemiss++; + udp_last_so = so; + } + } + + if (so == NULL) { + /* + * If there's no socket for this packet, + * create one + */ + if ((so = socreate()) == NULL) goto bad; + if(udp_attach(so) == -1) { + DEBUG_MISC((dfd," udp_attach errno = %d-%s\n", + errno,strerror(errno))); + sofree(so); + goto bad; + } + + /* + * Setup fields + */ + /* udp_last_so = so; */ + so->so_laddr = ip->ip_src; + so->so_lport = uh->uh_sport; + + if ((so->so_iptos = udp_tos(so)) == 0) + so->so_iptos = ip->ip_tos; + + /* + * XXXXX Here, check if it's in udpexec_list, + * and if it is, do the fork_exec() etc. + */ + } + + so->so_faddr = ip->ip_dst; /* XXX */ + so->so_fport = uh->uh_dport; /* XXX */ + + iphlen += sizeof(struct udphdr); + m->m_len -= iphlen; + m->m_data += iphlen; + + /* + * Now we sendto() the packet. + */ + if (so->so_emu) + udp_emu(so, m); + + if(sosendto(so,m) == -1) { + m->m_len += iphlen; + m->m_data -= iphlen; + *ip=save_ip; + DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno))); + icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); + } + + m_free(so->so_m); /* used for ICMP if error on sorecvfrom */ + + /* restore the orig SLIRPmbuf packet */ + m->m_len += iphlen; + m->m_data -= iphlen; + *ip=save_ip; + so->so_m=m; /* ICMP backup */ + + return; +bad: + m_freem(m); + /* if (opts) m_freem(opts); */ + return; +} + +int udp_output2(struct SLIRPsocket *so, struct SLIRPmbuf *m, + struct sockaddr_in *saddr, struct sockaddr_in *daddr, + int iptos) +{ + struct udpiphdr *ui; + int error = 0; + + DEBUG_CALL("udp_output"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("saddr = %lx", (long)saddr->sin_addr.s_addr); + DEBUG_ARG("daddr = %lx", (long)daddr->sin_addr.s_addr); + + /* + * Adjust for header + */ + m->m_data -= sizeof(struct udpiphdr); + m->m_len += sizeof(struct udpiphdr); + + /* + * Fill in SLIRPmbuf with extended UDP header + * and addresses and length put into network format. + */ + ui = mtod(m, struct udpiphdr *); + ui->ui_next = ui->ui_prev = 0; + ui->ui_x1 = 0; + ui->ui_pr = IPPROTO_UDP; + ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ + /* XXXXX Check for from-one-location sockets, or from-any-location sockets */ + ui->ui_src = saddr->sin_addr; + ui->ui_dst = daddr->sin_addr; + ui->ui_sport = saddr->sin_port; + ui->ui_dport = daddr->sin_port; + ui->ui_ulen = ui->ui_len; + + /* + * Stuff checksum and output datagram. + */ + ui->ui_sum = 0; + if (udpcksum) { + if ((ui->ui_sum = cksum(m, /* sizeof (struct udpiphdr) + */ m->m_len)) == 0) + ui->ui_sum = 0xffff; + } + ((struct ip *)ui)->ip_len = m->m_len; + + ((struct ip *)ui)->ip_ttl = ip_defttl; + ((struct ip *)ui)->ip_tos = iptos; + + udpstat.udps_opackets++; + + error = ip_output(so, m); + + return (error); +} + +int udp_output(struct SLIRPsocket *so, struct SLIRPmbuf *m, + struct sockaddr_in *addr) + +{ + struct sockaddr_in saddr, daddr; + + saddr = *addr; + if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr) { + saddr.sin_addr.s_addr = so->so_faddr.s_addr; + if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff)) + saddr.sin_addr.s_addr = alias_addr.s_addr; + } + daddr.sin_addr = so->so_laddr; + daddr.sin_port = so->so_lport; + + return udp_output2(so, m, &saddr, &daddr, so->so_iptos); +} + +int +udp_attach(so) + struct SLIRPsocket *so; +{ + struct sockaddr_in addr; + + if((so->s = socket(AF_INET,SOCK_DGRAM,0)) != -1) { + /* + * Here, we bind() the socket. Although not really needed + * (sendto() on an unbound socket will bind it), it's done + * here so that emulation of ytalk etc. don't have to do it + */ + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = 0; + addr.sin_addr.s_addr = INADDR_ANY; + if(bind(so->s, (struct sockaddr *)&addr, sizeof(addr))<0) { + int lasterrno=errno; + closesocket(so->s); + so->s=-1; +#ifdef _WIN32 + WSASetLastError(lasterrno); +#else + errno=lasterrno; +#endif + } else { + /* success, insert in queue */ + so->so_expire = curtime + SO_EXPIRE; + insque(so,&udb); + } + } + return(so->s); +} + +void +udp_detach(so) + struct SLIRPsocket *so; +{ + closesocket(so->s); + /* if (so->so_m) m_free(so->so_m); done by sofree */ + + sofree(so); +} + +struct tos_t udptos[] = { + {0, 53, IPTOS_LOWDELAY, 0}, /* DNS */ + {517, 517, IPTOS_LOWDELAY, EMU_TALK}, /* talk */ + {518, 518, IPTOS_LOWDELAY, EMU_NTALK}, /* ntalk */ + {0, 7648, IPTOS_LOWDELAY, EMU_CUSEEME}, /* Cu-Seeme */ + {0, 0, 0, 0} +}; + +u_int8_t +udp_tos(so) + struct SLIRPsocket *so; +{ + int i = 0; + + while(udptos[i].tos) { + if ((udptos[i].fport && ntohs(so->so_fport) == udptos[i].fport) || + (udptos[i].lport && ntohs(so->so_lport) == udptos[i].lport)) { + so->so_emu = udptos[i].emu; + return udptos[i].tos; + } + i++; + } + + return 0; +} + +#ifdef EMULATE_TALK +#include "talkd.h" +#endif + +/* + * Here, talk/ytalk/ntalk requests must be emulated + */ +void +udp_emu(so, m) + struct SLIRPsocket *so; + struct SLIRPmbuf *m; +{ + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); +#ifdef EMULATE_TALK + CTL_MSG_OLD *omsg; + CTL_MSG *nmsg; + char buff[sizeof(CTL_MSG)]; + u_char type; + +struct talk_request { + struct talk_request *next; + struct SLIRPsocket *udp_so; + struct SLIRPsocket *tcp_so; +} *req; + + static struct talk_request *req_tbl = 0; + +#endif + +struct cu_header { + uint16_t d_family; // destination family + uint16_t d_port; // destination port + uint32_t d_addr; // destination address + uint16_t s_family; // source family + uint16_t s_port; // source port + uint32_t so_addr; // source address + uint32_t seqn; // sequence number + uint16_t message; // message + uint16_t data_type; // data type + uint16_t pkt_len; // packet length +} *cu_head; + + switch(so->so_emu) { + +#ifdef EMULATE_TALK + case EMU_TALK: + case EMU_NTALK: + /* + * Talk emulation. We always change the ctl_addr to get + * some answers from the daemon. When an ANNOUNCE comes, + * we send LEAVE_INVITE to the local daemons. Also when a + * DELETE comes, we send copies to the local daemons. + */ + if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) + return; + +#define IS_OLD (so->so_emu == EMU_TALK) + +#define COPY_MSG(dest, src) { dest->type = src->type; \ + dest->id_num = src->id_num; \ + dest->pid = src->pid; \ + dest->addr = src->addr; \ + dest->ctl_addr = src->ctl_addr; \ + memcpy(&dest->l_name, &src->l_name, NAME_SIZE_OLD); \ + memcpy(&dest->r_name, &src->r_name, NAME_SIZE_OLD); \ + memcpy(&dest->r_tty, &src->r_tty, TTY_SIZE); } + +#define OTOSIN(ptr, field) ((struct sockaddr_in *)&ptr->field) +/* old_sockaddr to sockaddr_in */ + + + if (IS_OLD) { /* old talk */ + omsg = mtod(m, CTL_MSG_OLD*); + nmsg = (CTL_MSG *) buff; + type = omsg->type; + OTOSIN(omsg, ctl_addr)->sin_port = addr.sin_port; + OTOSIN(omsg, ctl_addr)->sin_addr = our_addr; + strncpy(omsg->l_name, getlogin(), NAME_SIZE_OLD); + } else { /* new talk */ + omsg = (CTL_MSG_OLD *) buff; + nmsg = mtod(m, CTL_MSG *); + type = nmsg->type; + OTOSIN(nmsg, ctl_addr)->sin_port = addr.sin_port; + OTOSIN(nmsg, ctl_addr)->sin_addr = our_addr; + strncpy(nmsg->l_name, getlogin(), NAME_SIZE_OLD); + } + + if (type == LOOK_UP) + return; /* for LOOK_UP this is enough */ + + if (IS_OLD) { /* make a copy of the message */ + COPY_MSG(nmsg, omsg); + nmsg->vers = 1; + nmsg->answer = 0; + } else + COPY_MSG(omsg, nmsg); + + /* + * If if is an ANNOUNCE message, we go through the + * request table to see if a tcp port has already + * been redirected for this socket. If not, we solisten() + * a new socket and add this entry to the table. + * The port number of the tcp socket and our IP + * are put to the addr field of the message structures. + * Then a LEAVE_INVITE is sent to both local daemon + * ports, 517 and 518. This is why we have two copies + * of the message, one in old talk and one in new talk + * format. + */ + + if (type == ANNOUNCE) { + int s; + u_short temp_port; + + for(req = req_tbl; req; req = req->next) + if (so == req->udp_so) + break; /* found it */ + + if (!req) { /* no entry for so, create new */ + req = (struct talk_request *) + malloc(sizeof(struct talk_request)); + req->udp_so = so; + req->tcp_so = solisten(0, + OTOSIN(omsg, addr)->sin_addr.s_addr, + OTOSIN(omsg, addr)->sin_port, + SS_FACCEPTONCE); + req->next = req_tbl; + req_tbl = req; + } + + /* replace port number in addr field */ + addrlen = sizeof(addr); + getsockname(req->tcp_so->s, + (struct sockaddr *) &addr, + &addrlen); + OTOSIN(omsg, addr)->sin_port = addr.sin_port; + OTOSIN(omsg, addr)->sin_addr = our_addr; + OTOSIN(nmsg, addr)->sin_port = addr.sin_port; + OTOSIN(nmsg, addr)->sin_addr = our_addr; + + /* send LEAVE_INVITEs */ + temp_port = OTOSIN(omsg, ctl_addr)->sin_port; + OTOSIN(omsg, ctl_addr)->sin_port = 0; + OTOSIN(nmsg, ctl_addr)->sin_port = 0; + omsg->type = nmsg->type = LEAVE_INVITE; + + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + addr.sin_addr = our_addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(517); + sendto(s, (char *)omsg, sizeof(*omsg), 0, + (struct sockaddr *)&addr, sizeof(addr)); + addr.sin_port = htons(518); + sendto(s, (char *)nmsg, sizeof(*nmsg), 0, + (struct sockaddr *) &addr, sizeof(addr)); + closesocket(s) ; + + omsg->type = nmsg->type = ANNOUNCE; + OTOSIN(omsg, ctl_addr)->sin_port = temp_port; + OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; + } + + /* + * If it is a DELETE message, we send a copy to the + * local daemons. Then we delete the entry corresponding + * to our socket from the request table. + */ + + if (type == DELETE) { + struct talk_request *temp_req, *req_next; + int s; + u_short temp_port; + + temp_port = OTOSIN(omsg, ctl_addr)->sin_port; + OTOSIN(omsg, ctl_addr)->sin_port = 0; + OTOSIN(nmsg, ctl_addr)->sin_port = 0; + + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + addr.sin_addr = our_addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(517); + sendto(s, (char *)omsg, sizeof(*omsg), 0, + (struct sockaddr *)&addr, sizeof(addr)); + addr.sin_port = htons(518); + sendto(s, (char *)nmsg, sizeof(*nmsg), 0, + (struct sockaddr *)&addr, sizeof(addr)); + closesocket(s); + + OTOSIN(omsg, ctl_addr)->sin_port = temp_port; + OTOSIN(nmsg, ctl_addr)->sin_port = temp_port; + + /* delete table entry */ + if (so == req_tbl->udp_so) { + temp_req = req_tbl; + req_tbl = req_tbl->next; + free(temp_req); + } else { + temp_req = req_tbl; + for(req = req_tbl->next; req; req = req_next) { + req_next = req->next; + if (so == req->udp_so) { + temp_req->next = req_next; + free(req); + break; + } else { + temp_req = req; + } + } + } + } + + return; +#endif + + case EMU_CUSEEME: + + /* + * Cu-SeeMe emulation. + * Hopefully the packet is more that 16 bytes long. We don't + * do any other tests, just replace the address and port + * fields. + */ + if (m->m_len >= sizeof (*cu_head)) { + if (getsockname(so->s, (struct sockaddr *)&addr, &addrlen) < 0) + return; + cu_head = mtod(m, struct cu_header *); + cu_head->s_port = addr.sin_port; + cu_head->so_addr = our_addr.s_addr; + } + + return; + } +} + +struct SLIRPsocket * +udp_listen(port, laddr, lport, flags) + u_int port; + u_int32_t laddr; + u_int lport; + int flags; +{ + struct sockaddr_in addr; + struct SLIRPsocket *so; + socklen_t addrlen = sizeof(struct sockaddr_in); + int opt = 1; + + if ((so = socreate()) == NULL) { + free(so); + return NULL; + } + so->s = socket(AF_INET,SOCK_DGRAM,0); + so->so_expire = curtime + SO_EXPIRE; + insque(so,&udb); + + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = port; + + if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) { + udp_detach(so); + return NULL; + } + setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); +/* setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); */ + + getsockname(so->s,(struct sockaddr *)&addr,&addrlen); + so->so_fport = addr.sin_port; + if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) + so->so_faddr = alias_addr; + else + so->so_faddr = addr.sin_addr; + + so->so_lport = lport; + so->so_laddr.s_addr = laddr; + if (flags != SS_FACCEPTONCE) + so->so_expire = 0; + + so->so_state = SS_ISFCONNECTED; + + return so; +} diff --git a/src/slirp/udp.h b/src/slirp/udp.h new file mode 100644 index 0000000..807e55b --- /dev/null +++ b/src/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 diff --git a/src/win-config.c b/src/win-config.c index c22850e..d658f59 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -20,11 +20,17 @@ #include "video.h" #include "vid_voodoo.h" #include "win.h" +#ifdef USE_NETWORKING +#include "nethandler.h" +#endif 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]; +#ifdef USE_NETWORKING +static int settings_network_to_list[20], settings_list_to_network[20]; +#endif static char *hdd_names[16]; int has_been_inited = 0; @@ -114,6 +120,47 @@ static void recalc_snd_list(HWND hdlg, int model) SendMessage(h, CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); } +#ifdef USE_NETWORKING +static void recalc_net_list(HWND hdlg, int model) +{ + HWND h = GetDlgItem(hdlg, IDC_COMBONETCARD); + int c = 0, d = 0; + int set_zero = 0; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + + while (1) + { + char *s = network_card_getname(c); + + if (!s[0]) + break; + + settings_network_to_list[c] = d; + + if (network_card_available(c)) + { + device_t *network_dev = network_card_getdevice(c); + + if (!network_dev || (network_dev->flags & DEVICE_MCA) == (models[model].flags & MODEL_MCA)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + settings_list_to_network[d] = c; + d++; + } + else if (c == network_card_current) + set_zero = 1; + } + + c++; + } + if (set_zero) + SendMessage(h, CB_SETCURSEL, 0, 0); + else + SendMessage(h, CB_SETCURSEL, settings_network_to_list[network_card_current], 0); +} +#endif + static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) { HWND h; @@ -197,7 +244,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR int cpu_type; int temp_mouse_type; int hdd_changed = 0; - +#ifdef USE_NETWORKING + int temp_network_card; +#endif UDACCEL accel; // pclog("Dialog msg %i %08X\n",message,message); switch (message) @@ -400,6 +449,15 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR recalc_hdd_list(hdlg, romstomodel[romset], 0); +#ifdef USE_NETWORKING + recalc_net_list(hdlg, romstomodel[romset]); + + h = GetDlgItem(hdlg, IDC_CONFIGURENETCARD); + if (network_card_has_config(network_card_current)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); +#endif return TRUE; case WM_COMMAND: @@ -465,13 +523,20 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR c = SendMessage(h, CB_GETCURSEL, 0, 0); if (hdd_names[c]) hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); - +#ifdef USE_NETWORKING + h = GetDlgItem(hdlg, IDC_COMBONETCARD); + temp_network_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; +#endif if (temp_model != model || gfx != gfxcard || mem != mem_size || 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type || hdd_changed) + temp_mouse_type != mouse_type || hdd_changed +#ifdef USE_NETWORKING + || temp_network_card != network_card_current +#endif + ) { if (!has_been_inited || MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL)==IDOK) { @@ -489,6 +554,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR voodoo_enabled = temp_voodoo; cpu_use_dynarec = temp_dynarec; mouse_type = temp_mouse_type; +#ifdef USE_NETWORKING + network_card_current = temp_network_card; +#endif fdd_set_type(0, temp_fda_type); fdd_set_type(1, temp_fdb_type); @@ -651,6 +719,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR recalc_hdd_list(hdlg, temp_model, 1); recalc_snd_list(hdlg, temp_model); +#ifdef USE_NETWORKING + recalc_net_list(hdlg, temp_model); +#endif } break; case IDC_COMBOCPUM: @@ -809,6 +880,28 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 3, temp_joystick_type); break; +#ifdef USE_NETWORKING + case IDC_COMBONETCARD: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBONETCARD); + temp_network_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURENETCARD); + if (network_card_has_config(temp_network_card)) + EnableWindow(h, TRUE); + else + EnableWindow(h, FALSE); + } + break; + + case IDC_CONFIGURENETCARD: + h = GetDlgItem(hdlg, IDC_COMBONETCARD); + temp_network_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); + break; +#endif } break; } diff --git a/src/win.c b/src/win.c index 7ba7943..22079bc 100644 --- a/src/win.c +++ b/src/win.c @@ -44,6 +44,10 @@ #include "paths.h" //#include "win-opengl.h" +#ifdef DRMINGW +#include +#endif + #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 #endif @@ -514,6 +518,10 @@ int WINAPI WinMain (HINSTANCE hThisInstance, int c, d; LARGE_INTEGER qpc_freq; +#ifdef DRMINGW + ExcHndlInit(); +#endif + process_command_line(); hinstance=hThisInstance; From 961490cca9e18fa173dd863af3a72c2a8fc98304 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 31 Jul 2017 21:45:08 +0100 Subject: [PATCH 0105/1050] Added network configuration dialogue. --- src/Makefile.mingw-network | 2 +- src/ibm.h | 1 + src/ne2000.c | 10 +- src/nethandler.h | 6 ++ src/pc.c | 9 ++ src/pc.rc | 19 +++- src/resources.h | 4 + src/win-config_sel.c | 5 + src/win-networkconfig.c | 213 +++++++++++++++++++++++++++++++++++++ src/win.h | 1 + 10 files changed, 263 insertions(+), 7 deletions(-) create mode 100644 src/win-networkconfig.c diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 6adadca..8e59a27 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad 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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 + win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xtide.o pc.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 NETOBJ = ne2000.o nethandler.o diff --git a/src/ibm.h b/src/ibm.h index 468dd1e..67f98ac 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -576,5 +576,6 @@ void resetpchard(); void speedchanged(); void saveconfig(char *fn); +void saveconfig_global_only(); #define UNUSED(x) (void)x diff --git a/src/ne2000.c b/src/ne2000.c index afbabb2..384a545 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -1407,11 +1407,11 @@ void *ne2000_init() //0 pcap //1 slirp // - net_is_slirp = config_get_int(CFG_MACHINE, NULL, "net_type", 1); - pclog("ne2000 pcap device %s\n",config_get_string(CFG_MACHINE, NULL,"pcap_device","nothing")); + net_is_slirp = (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_SLIRP) ? 1 : 0; + pclog("ne2000 pcap device %s\n",config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing")); //Check that we have a string setup, otherwise turn pcap off - if (!strcmp("nothing",config_get_string(CFG_MACHINE, NULL,"pcap_device","nothing"))) + if (!strcmp("nothing",config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing"))) net_is_pcap = 0; else if (net_is_slirp == 0) net_is_pcap = 1; @@ -1494,9 +1494,9 @@ void *ne2000_init() { pclog("ne2000 Pcap version [%s]\n",_pcap_lib_version()); - if ((net_pcap=_pcap_open_live(config_get_string(CFG_MACHINE, NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) + if ((net_pcap=_pcap_open_live(config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) { - pclog("ne2000 pcap_open_live error on %s!\n",config_get_string(CFG_MACHINE, NULL,"pcap_device","whatever the ethernet is")); + pclog("ne2000 pcap_open_live error on %s!\n",config_get_string(CFG_GLOBAL, NULL,"pcap_device","whatever the ethernet is")); net_is_pcap=0; return(ne2000); //YUCK!!! } } diff --git a/src/nethandler.h b/src/nethandler.h index 024fad8..3dde87c 100644 --- a/src/nethandler.h +++ b/src/nethandler.h @@ -18,3 +18,9 @@ void initpcap(); void closepcap(); void vlan_reset(); + +enum +{ + NET_SLIRP = 0, + NET_PCAP = 1 +}; diff --git a/src/pc.c b/src/pc.c index b836136..1faa7f7 100644 --- a/src/pc.c +++ b/src/pc.c @@ -920,3 +920,12 @@ void saveconfig(char *fn) config_save(CFG_GLOBAL, global_config_file); } + +void saveconfig_global_only() +{ + char global_config_file[512]; + + append_filename(global_config_file, pcem_path, "pcem.cfg", 511); + + config_save(CFG_GLOBAL, global_config_file); +} diff --git a/src/pc.rc b/src/pc.rc index 2307a57..c89e43e 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -367,6 +367,23 @@ BEGIN DEFPUSHBUTTON "New...", IDC_NEW, 200-54,40, 50, 14, WS_TABSTOP DEFPUSHBUTTON "Configuration...", IDC_CONFIG, 200-54,58, 50, 14, WS_TABSTOP DEFPUSHBUTTON "HDD...", IDC_HDCONF, 200-54,76, 50, 14, WS_TABSTOP - +#ifdef USE_NETWORKING + DEFPUSHBUTTON "Network...",IDC_NETWORK, 200-54,104,50, 14, WS_TABSTOP +#endif LISTBOX IDC_LIST, 4, 4,140,142, WS_TABSTOP|WS_VSCROLL END + +NetworkConfDlg DIALOGEX 0, 0, 400, 80 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Network" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,64,56,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,56,50,14, WS_TABSTOP + + COMBOBOX IDC_COMBONETTYPE,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBONETDEVICE,62,36,327,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + + LTEXT "Type :",IDC_STATIC,15,16,40,10 + LTEXT "Device :",IDC_STATIC,15,36,34,10 +END diff --git a/src/resources.h b/src/resources.h index 4d9193d..69d9306 100644 --- a/src/resources.h +++ b/src/resources.h @@ -142,3 +142,7 @@ #define IDC_LIST 1201 #define IDC_CONFIG 1202 #define IDC_HDCONF 1203 +#define IDC_NETWORK 1204 + +#define IDC_COMBONETTYPE 1200 +#define IDC_COMBONETDEVICE 1201 diff --git a/src/win-config_sel.c b/src/win-config_sel.c index 0d89b51..4134ce9 100644 --- a/src/win-config_sel.c +++ b/src/win-config_sel.c @@ -168,6 +168,11 @@ static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wP return TRUE; } +#ifdef USE_NETWORKING + case IDC_NETWORK: + networkconfig_open(hdlg); + return TRUE; +#endif } break; } diff --git a/src/win-networkconfig.c b/src/win-networkconfig.c new file mode 100644 index 0000000..0a14710 --- /dev/null +++ b/src/win-networkconfig.c @@ -0,0 +1,213 @@ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include + +#include "ibm.h" +#include "config.h" +#include "nethandler.h" +#include "resources.h" +#include "win.h" + +static HINSTANCE net_hLib = 0; +static char *net_lib_name = "wpcap.dll"; +static pcap_if_t *alldevs; +static char *dev_name[20]; + +int (*_pcap_findalldevs)(pcap_if_t **, char *); +void (*_pcap_freealldevs)(pcap_if_t *); +pcap_t *(*_pcap_open_live)(const char *, int, int, int, char *); +int (*_pcap_datalink)(pcap_t *); +void (*_pcap_close)(pcap_t *); + +#define ETH_DEV_NAME_MAX 256 /* maximum device name size */ +#define ETH_DEV_DESC_MAX 256 /* maximum device description size */ +#define ETH_MAX_DEVICE 30 /* maximum ethernet devices */ +#define ETH_PROMISC 1 /* promiscuous mode = true */ +#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */ +#define PCAP_READ_TIMEOUT -1 + +static int get_network_name(char *dev_name, char *regval) +{ + if (dev_name[strlen( "\\Device\\NPF_" )] == '{') + { + char regkey[2048]; + HKEY reghnd; + + sprintf(regkey, "SYSTEM\\CurrentControlSet\\Control\\Network\\" + "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", dev_name+ + strlen("\\Device\\NPF_")); + + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0, KEY_QUERY_VALUE, ®hnd) == ERROR_SUCCESS) + { + DWORD reglen = 2048; + DWORD regtype; + + if (RegQueryValueExA(reghnd, "Name", NULL, ®type, (LPBYTE)regval, ®len) == ERROR_SUCCESS) + { + RegCloseKey (reghnd); + + if ((regtype != REG_SZ) || (reglen > 2048)) + return -1; + + /*Name now in regval*/ + return 0; + } + RegCloseKey (reghnd); + } + } + return -1; +} + +static BOOL CALLBACK networkconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + pcap_if_t *dev; + char errbuf[PCAP_ERRBUF_SIZE]; + int type; + + switch (message) + { + case WM_INITDIALOG: + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"SLiRP"); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); + SendMessage(h, CB_SETCURSEL, 0, 0); + EnableWindow(h, FALSE); + + net_hLib = LoadLibraryA(net_lib_name); + + if (net_hLib) + { + int c = 0; + int match = 0; + + _pcap_findalldevs = (void *)GetProcAddress(net_hLib, "pcap_findalldevs"); + _pcap_freealldevs = (void *)GetProcAddress(net_hLib, "pcap_freealldevs"); + _pcap_open_live = (void *)GetProcAddress(net_hLib, "pcap_open_live"); + _pcap_datalink = (void *)GetProcAddress(net_hLib, "pcap_datalink"); + _pcap_close = (void *)GetProcAddress(net_hLib, "pcap_close"); + + if (_pcap_findalldevs(&alldevs, errbuf) != -1) + { + char *pcap_device = config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); + + h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); + + for (dev = alldevs; dev; dev = dev->next) + { + pcap_t *conn = _pcap_open_live(dev->name, ETH_MAX_PACKET, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf); + int datalink; + + if (conn) + { + datalink = _pcap_datalink(conn); + _pcap_close(conn); + } + + if (conn && datalink == DLT_EN10MB) + { + char desc[2048]; + char s[2048]; + + if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) + continue; + + if (pcap_device) + { + if (!strcmp(pcap_device, dev->name)) + match = c; + } + + dev_name[c++] = dev->name; + if (get_network_name(dev->name, desc)) + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)dev->name); + else + { + sprintf(s, "%s - %s", dev->name, desc); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + } + } + } + if (c) + { + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"PCAP"); + + if (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_PCAP) + { + SendMessage(h, CB_SETCURSEL, 1, 0); + h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); + SendMessage(h, CB_SETCURSEL, match, 0); + EnableWindow(h, TRUE); + } + } + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + type = SendMessage(h, CB_GETCURSEL, 0, 0); + if (type) /*PCAP*/ + { + int dev; + + h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); + dev = SendMessage(h, CB_GETCURSEL, 0, 0); + + config_set_int(CFG_GLOBAL, NULL, "net_type", NET_PCAP); + config_set_string(CFG_GLOBAL, NULL, "pcap_device", dev_name[dev]); + } + else /*SLiRP*/ + { + config_set_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP); + config_set_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); + } + saveconfig_global_only(); + case IDCANCEL: + EndDialog(hdlg, 0); + if (net_hLib) + { + _pcap_freealldevs(alldevs); + _pcap_findalldevs = NULL; + _pcap_freealldevs = NULL; + _pcap_open_live = NULL; + _pcap_datalink = NULL; + _pcap_close = NULL; + FreeLibrary(net_hLib); + } + return TRUE; + + case IDC_COMBONETTYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + int type; + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + type = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); + if (!type) + EnableWindow(h, FALSE); + else + EnableWindow(h, TRUE); + + return TRUE; + } + } + break; + } + return FALSE; +} + +void networkconfig_open(HWND hwnd) +{ + DialogBox(hinstance, TEXT("NetworkConfDlg"), hwnd, (DLGPROC)networkconfig_dlgproc); +} diff --git a/src/win.h b/src/win.h index 2675995..e4f6212 100644 --- a/src/win.h +++ b/src/win.h @@ -30,6 +30,7 @@ struct device_t; void deviceconfig_open(HWND hwnd, struct device_t *device); void joystickconfig_open(HWND hwnd, int joy_nr, int type); +void networkconfig_open(HWND hwnd); extern char openfilestring[260]; From bbeca532812f0f3f16c08968192b2ba24ea21daf Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Aug 2017 08:38:20 +0100 Subject: [PATCH 0106/1050] Fix position of Voodoo configuration button in networking builds. --- src/pc.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc.rc b/src/pc.rc index c89e43e..0334579 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -133,7 +133,7 @@ BEGIN CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,364,118,10 CONTROL "Synchronise time to host clock",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,380,118,10 CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,396,118,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 356, 40, 14, WS_TABSTOP + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 396, 40, 14, WS_TABSTOP #else LTEXT "Mouse :",IDC_STATIC,15,256,40,10 COMBOBOX IDC_COMBOMOUSE,62,256,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP From eb1db1aa72b155d4c7a38ced20ea21b8f8923e02 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Aug 2017 11:52:49 +0100 Subject: [PATCH 0107/1050] wxWidgets config manager now selects last run configuration after shutting down emulated machine. Patch from bit. --- src/wx-config_sel.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index 6542dba..f384e9b 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -3,6 +3,8 @@ #include "wx-utils.h" #include "paths.h" +static int active_config = -1; + extern int config_open(void* hwnd); static void select_config(void* hdlg, char* name) @@ -85,6 +87,8 @@ static int run(void* hdlg) { char cfg[512]; + active_config = wx_sendmessage(wx_getdlgitem(hdlg, WX_ID("IDC_LIST")), WX_LB_GETCURSEL, 0, 0); + strcpy(cfg, configs_path); put_backslash(cfg); strcat(cfg, s); @@ -112,6 +116,10 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L { // pause = 1; config_list_update(hdlg); + + if (active_config >= 0) + wx_sendmessage(wx_getdlgitem(hdlg, WX_ID("IDC_LIST")), WX_LB_SETCURSEL, active_config, 0); + // h = wx_getdlgitem(hdlg, IDC_LIST); // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"AAA"); // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"BBB"); From 427b93340f5de06d2bb71acdcc97fcfd6039cdf0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Aug 2017 11:54:12 +0100 Subject: [PATCH 0108/1050] Fix timer_freq value on wxWidgets/SDL2 port. Patch from bit. --- src/wx-sdl2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 1d9d419..82709d4 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -630,7 +630,7 @@ int start_emulation(void* params) updatewindowsize(640, 480); - timer_freq = timer_read(); + timer_freq = SDL_GetPerformanceFrequency(); if (show_machine_on_start) wx_show_status(ghwnd); From 0c63c99b7191f9bfe8cb936e0a38ce654a1fc884 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Aug 2017 11:55:29 +0100 Subject: [PATCH 0109/1050] mingw-wx-sdl2 makefile now builds if wxrc.exe doesn't exist. Patch from bit. --- src/Makefile.mingw-wx-sdl2 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 50d78cd..0465fd0 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -2,10 +2,9 @@ VPATH = . dosbox resid-fp CPP = g++ CC = gcc WINDRES = windres.exe -WXRC = ../utils/wx/wxrc.exe WXVERSION = 31 WXINCLUDE = C:/MinGW/include/wx/ -CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -IC:\MinGW\lib\mswu +CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ @@ -43,7 +42,7 @@ clean : rm *.res wx-resources.o : pc.xrc - $(WXRC) -c pc.xrc -o wx-resources.cpp + -wxrc -c pc.xrc -o wx-resources.cpp $(CPP) $(CXXFLAGS) -c wx-resources.cpp %.o : %.c From 807ee15f4992936a8707a2b85afa2b6bd768d90d Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Aug 2017 11:59:20 +0100 Subject: [PATCH 0110/1050] wxWidgets/SDL2 port now supports setting custom screen resolution. Patch from bit. --- src/pc.xrc | 5358 ++++++++------- src/wx-resources.cpp | 13330 ++++++++++++++++++------------------ src/wx-sdl2-display-win.c | 14 +- src/wx-sdl2-display.c | 15 +- src/wx-sdl2-video.h | 3 + src/wx-sdl2.c | 61 +- 6 files changed, 9553 insertions(+), 9228 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index d0137d5..18bca4f 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -1,2631 +1,2727 @@ - - - - icons/16x16/drive.png - icons/16x16/diskette.png - icons/16x16/cd.png - - - - icons/24x24/play.png - - - - icons/24x24/pause.png - - - - icons/24x24/stop.png - - - - icons/24x24/refresh.png - - - - - - - - - - - - - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - 1 - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - - - - - 1 - - - - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - - - - - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - - - - - - - - - - - 1 - - - - 1 - - - - 1 - - - - 1 - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - Configure PCem - 1 - - - 0 - 1 - 0 - 0 - - - - - wxALL|wxEXPAND - 5 - - - - 1 - icons/32x32/motherboard.png - - - - 0 - 3 - 0 - 0 - 1 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - wxALL - 5 - - icons/16x16/setting_tools.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 120,-1 - - - - - - - wxALL - 5 - - - 220,-1 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - 0,0 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 0 - 0 - 10 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - 0,0 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - - - 0 - icons/32x32/video_mode.png - - - - 0 - 3 - 0 - 0 - 1 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - wxALL - 5 - - icons/16x16/setting_tools.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxALL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 0 - - - - - - - wxALL - 5 - - icons/16x16/setting_tools.png - 0 - - - - - - - 0 - icons/32x32/sound.png - - - - 0 - 3 - 0 - 0 - 1 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - wxALL - 5 - - icons/16x16/setting_tools.png - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - - 0 - - - - - - - 0 - icons/32x32/drive.png - - - - 0 - 1 - 0 - 0 - 0 - - - - wxEXPAND - 0 - - 0 - 2 - 0 - 0 - 1 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - - - wxEXPAND | wxALL - 5 - - - - - - - wxEXPAND | wxALL - 5 - - - - - 1 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - 0 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - 0 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - 0 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - - - - - 0 - icons/32x32/mouse_pc.png - - - - 0 - 2 - 0 - 0 - 1 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 80,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - - - - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - - 1 - - - - - wxALL - 5 - - - 0 - - - - - - - - - - New Hard Disc - 1 - - - 0 - 1 - 0 - 0 - - - - - wxEXPAND - 5 - - 0 - 3 - 0 - 0 - 1 - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - 80,-1 - - -1 - - - - - wxALL - 5 - - - 350,-1 - - - - - - wxALL - 5 - - - icons/16x16/folder.png - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL - 5 - - - 350,-1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - - 1 - - - - - wxALL - 5 - - - 0 - - - - - - - - - - Hard Disc Parameters - 1 - - - 0 - 1 - 0 - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxEXPAND - 5 - - 0 - 3 - 0 - 0 - 1 - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - wxALIGN_CENTER_VERTICAL|wxALL - 5 - - - -1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL - 5 - - - 350,-1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - - 1 - - - - - wxALL - 5 - - - 0 - - - - - - - - - - PCem Configuration Manager - 1 - - 1 - 1 - 0 - 0 - 0 - 0 - - - wxALL|wxEXPAND - 5 - - 2 - 2 - 0 - 0 - 0 - 0 - - - wxEXPAND - 5 - - wxVERTICAL - - - wxALL|wxEXPAND - 5 - - - 250,300 - - - - - - - - wxEXPAND - 5 - - wxVERTICAL - - - wxALL - 5 - - - Load - icons/32x32/control_play_blue.png - 1 - - - - - wxALL - 5 - - - Configure - icons/32x32/setting_tools.png - 0 - - - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - New - icons/32x32/computer_add.png - 0 - - - - - wxALL - 5 - - - Rename - icons/32x32/computer_edit.png - 0 - - - - - wxALL - 5 - - - Delete - icons/32x32/computer_delete.png - 0 - - - - - - - wxALL - 5 - - - Quit - icons/32x32/door_in.png - 0 - - - - - - - - - - PCem Shader Manager - 1 - - - - wxALL - 5 - - wxHORIZONTAL - - wxALL - 0 - - - 300,350 - - - - wxEXPAND - 0 - - wxVERTICAL - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - - wxEXPAND - - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - wxALL - 0 - - - - - - - - wxEXPAND - - - - wxALL - 0 - - - - - - wxALL - 0 - - - 1 - - - - wxALL - 0 - - - - - - - - - - - - - - - PCem - 1 - - - wxVERTICAL - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - - - - - wxALIGN_CENTER|wxALL - 5 - - - -1 - - - - - - - wxALL - 5 - - - 0 - - - - - wxEXPAND - 5 - - - wxALIGN_CENTER_HORIZONTAL|wxALL - 5 - - - 1 - - - - wxALIGN_CENTER_HORIZONTAL|wxALL - 5 - - - - - - - - - - - - - - 1 - - - wxVERTICAL - - - wxALL - 5 - - - -1 - - - - - wxEXPAND | wxALL - 5 - - - - - - - wxALL - 5 - - - 1 - - - - - - + + + + icons/16x16/drive.png + icons/16x16/diskette.png + icons/16x16/cd.png + + + + icons/24x24/play.png + + + + icons/24x24/pause.png + + + + icons/24x24/stop.png + + + + icons/24x24/refresh.png + + + + + + + + + + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + + + + + + 1 + + + + + + + + 1 + + + + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + + + + + + + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + Configure PCem + 1 + + + 0 + 1 + 0 + 0 + + + + + wxALL|wxEXPAND + 5 + + + + 1 + icons/32x32/motherboard.png + + + + 0 + 3 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 120,-1 + + + + + + + wxALL + 5 + + + 220,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 0 + 0 + 10 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + + + 0 + icons/32x32/video_mode.png + + + + 0 + 3 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxALL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 0 + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + + + 0 + icons/32x32/sound.png + + + + 0 + 3 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 0 + + + + + + + 0 + icons/32x32/drive.png + + + + 0 + 1 + 0 + 0 + 0 + + + + wxEXPAND + 0 + + 0 + 2 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + + + wxEXPAND | wxALL + 5 + + + + + + + wxEXPAND | wxALL + 5 + + + + + 1 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + + + + + 0 + icons/32x32/mouse_pc.png + + + + 0 + 2 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 0 + + + + + + + + + + New Hard Disc + 1 + + + 0 + 1 + 0 + 0 + + + + + wxEXPAND + 5 + + 0 + 3 + 0 + 0 + 1 + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + 80,-1 + + -1 + + + + + wxALL + 5 + + + 350,-1 + + + + + + wxALL + 5 + + + icons/16x16/folder.png + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 0 + + + + + + + + + + Hard Disc Parameters + 1 + + + 0 + 1 + 0 + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxEXPAND + 5 + + 0 + 3 + 0 + 0 + 1 + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 0 + + + + + + + + + + PCem Configuration Manager + 1 + + 1 + 1 + 0 + 0 + 0 + 0 + + + wxALL|wxEXPAND + 5 + + 2 + 2 + 0 + 0 + 0 + 0 + + + wxEXPAND + 5 + + wxVERTICAL + + + wxALL|wxEXPAND + 5 + + + 250,300 + + + + + + + + wxEXPAND + 5 + + wxVERTICAL + + + wxALL + 5 + + + Load + icons/32x32/control_play_blue.png + 1 + + + + + wxALL + 5 + + + Configure + icons/32x32/setting_tools.png + 0 + + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + New + icons/32x32/computer_add.png + 0 + + + + + wxALL + 5 + + + Rename + icons/32x32/computer_edit.png + 0 + + + + + wxALL + 5 + + + Delete + icons/32x32/computer_delete.png + 0 + + + + + + + wxALL + 5 + + + Quit + icons/32x32/door_in.png + 0 + + + + + + + + + + PCem Shader Manager + 1 + + + + wxALL + 5 + + wxHORIZONTAL + + wxALL + 0 + + + 300,350 + + + + wxEXPAND + 0 + + wxVERTICAL + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + wxALL + 0 + + + + + + + + wxEXPAND + + + + wxALL + 0 + + + + + + wxALL + 0 + + + 1 + + + + wxALL + 0 + + + + + + + + + + + + + + + PCem + 1 + + + wxVERTICAL + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + + + + + wxALIGN_CENTER|wxALL + 5 + + + -1 + + + + + + + wxALL + 5 + + + 0 + + + + + wxEXPAND + 5 + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + 1 + + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + + + + + + + + Custom resolution + 1 + + + wxVERTICAL + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 640 + 1 + 16384 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + 480 + 1 + 16384 + + + + + + + wxEXPAND | wxALL + 5 + + + + + + + wxEXPAND + 5 + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + 1 + + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + + + + + + + + + 1 + + + wxVERTICAL + + + wxALL + 5 + + + -1 + + + + + wxEXPAND | wxALL + 5 + + + + + + + wxALL + 5 + + + 1 + + + + + + diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index ec14ae4..3a1d625 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1,6589 +1,6741 @@ -// -// This file was automatically generated by wxrc, do not edit by hand. -// - -#include - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#include -#include -#include -#include - -#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 - #define XRC_ADD_FILE(name, data, size, mime) \ - wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) -#else - #define XRC_ADD_FILE(name, data, size, mime) \ - wxMemoryFSHandler::AddFile(name, data, size) -#endif - -static size_t xml_res_size_0 = 430; -static unsigned char xml_res_file_0[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,1,80,73,68,65,84,120,218,196,147,177,75,195,64,20,198,191,75,2,77,82, -2,66,58,171,32,130,171,130,179,10,34,138,173,155,131,56,248,143,137,184, -9,145,186,168,40,34,104,103,65,119,233,160,117,236,210,160,29,210,187,228, -204,119,70,135,170,181,218,193,7,71,238,184,239,247,229,221,189,123,66, -107,141,81,194,194,136,225,236,238,237,35,77,51,88,150,224,90,151,74,165, -129,64,146,36,252,136,44,211,176,109,11,14,87,89,150,209,68,215,170,235, -120,120,108,13,52,152,156,24,199,241,201,169,22,194,18,52,176,8,247,164, -212,27,181,106,14,63,209,28,66,124,61,184,71,13,181,100,200,58,105,154, -70,59,219,91,144,74,97,102,122,106,184,131,231,102,100,14,162,195,200,81, -74,109,198,207,47,56,59,191,40,118,127,170,138,185,43,172,173,174,128,44, -51,64,210,75,224,249,30,150,151,22,115,94,23,26,209,7,234,55,239,252,239, -151,87,215,134,33,107,12,100,79,194,247,92,40,41,113,115,123,247,113,222, -126,3,190,153,249,185,89,163,37,99,12,148,74,205,196,117,61,116,226,24, -149,74,88,24,124,14,26,80,67,45,25,178,38,3,222,102,185,236,227,190,217, -252,22,126,143,118,187,141,48,12,139,210,231,6,156,216,142,131,32,8,204, -24,54,200,152,50,118,187,221,70,189,126,180,240,219,158,96,166,249,171, -108,48,95,22,127,236,143,173,208,17,255,222,141,175,2,12,0,1,60,177,155, -95,179,104,212,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_1 = 730; -static unsigned char xml_res_file_1[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,124,73,68,65,84,120,218,140,83,77,72,85,65,24,61,115,239,220,247, -158,247,169,207,22,146,253,27,214,162,218,219,198,22,45,42,105,23,180,9, -139,8,162,104,227,182,34,37,242,137,216,162,149,127,139,22,134,36,182,80, -116,19,22,190,130,16,194,140,22,45,130,90,244,71,100,17,6,37,153,250,222, -157,59,157,111,238,141,90,132,116,185,115,103,238,204,57,223,249,190,51, -51,170,161,107,186,35,178,40,86,76,140,40,6,248,174,251,120,108,154,159, -192,247,160,21,58,81,127,109,218,62,91,180,118,246,83,100,255,247,17,172, -112,132,171,141,181,208,212,61,48,252,6,246,242,110,188,90,88,162,134,130, -229,215,198,49,136,135,231,121,238,159,19,216,179,181,206,97,159,159,107, -130,112,37,35,44,27,5,204,12,185,20,71,250,123,49,50,208,139,249,210,20, -158,148,38,81,21,102,113,171,175,7,79,31,76,113,110,50,169,99,102,48,225, -72,57,138,253,207,114,12,221,184,23,101,250,208,222,209,77,85,133,56,54, -46,19,202,162,253,74,55,98,167,102,177,90,49,14,43,28,225,122,138,185,253, -88,139,208,176,255,16,137,49,250,138,29,152,25,191,141,128,14,245,247,116, -226,225,228,29,148,38,70,145,241,225,230,173,53,196,30,118,28,225,106,73, -99,133,246,231,57,202,178,93,42,22,221,110,72,237,23,187,138,46,77,81,151, -224,199,78,158,66,46,0,242,126,194,113,37,72,150,107,252,41,4,10,247,222, -174,160,117,103,72,75,173,51,45,177,242,207,6,138,97,130,41,100,148,227, -8,87,75,149,101,30,132,2,229,175,207,125,199,213,217,111,88,51,169,106, -74,21,140,199,130,179,84,14,41,36,88,225,40,164,37,208,15,84,51,106,217, -120,56,219,164,208,214,188,233,47,101,155,54,133,209,249,207,24,251,96, -145,241,148,227,36,187,144,6,168,146,227,69,96,91,115,61,94,190,255,10, -95,7,78,186,82,137,16,27,227,220,150,181,137,143,139,196,38,1,84,122,50, -81,161,65,57,166,150,97,62,17,243,223,178,113,3,134,111,14,226,252,233, -19,216,198,113,192,5,173,53,162,85,67,140,114,88,225,224,119,9,177,245, -144,15,52,245,121,31,140,69,77,232,97,238,241,44,142,180,30,69,77,78,8, -190,108,139,91,11,57,206,7,158,227,184,0,98,142,246,125,212,133,1,116,133, -7,202,75,22,178,188,44,97,214,197,103,159,113,59,226,115,77,112,213,12, -32,28,199,141,190,188,27,186,113,23,23,162,216,98,169,108,112,166,118,23, -86,120,18,183,239,104,60,222,62,246,8,45,45,7,199,151,233,131,4,168,37, -113,224,254,107,212,242,84,81,25,194,21,31,196,242,205,255,184,185,47,210, -126,223,58,183,123,225,151,0,3,0,201,66,64,174,55,176,170,129,0,0,0,0,73, -69,78,68,174,66,96,130}; - -static size_t xml_res_size_2 = 835; -static unsigned char xml_res_file_2[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,229,73,68,65,84,120,218,100,83,75,76,19,81,20,61,211,118,166,157, -150,22,176,5,1,229,35,82,36,4,99,162,6,18,34,113,39,46,80,227,70,73,220, -201,202,128,184,209,24,119,46,220,104,76,36,4,226,74,55,224,130,141,66, -130,49,16,73,52,98,68,148,40,66,212,128,168,20,249,10,165,244,199,48,191, -231,157,153,242,81,95,114,38,147,247,238,57,247,220,251,238,227,240,207, -106,125,250,185,93,211,217,69,198,224,98,169,61,14,144,236,54,238,225,149, -186,242,198,157,177,140,130,184,45,98,239,248,9,69,99,125,135,131,57,40, -47,244,35,224,230,16,213,128,12,59,16,223,96,24,15,173,96,240,203,2,156, -54,174,182,249,84,69,255,95,2,173,189,99,23,108,28,215,121,186,186,20,170, -192,99,62,1,232,58,224,225,1,55,161,212,107,186,192,106,82,197,163,23,19, -6,177,182,185,174,162,223,16,176,25,2,138,162,117,214,86,29,192,188,198, -99,54,14,184,104,55,91,36,184,128,28,151,69,150,146,26,212,152,142,186, -35,251,33,171,106,223,166,115,71,75,207,135,246,242,226,92,36,236,14,56, -40,107,186,19,200,243,0,94,199,118,173,242,134,142,233,80,18,203,97,25, -254,128,136,163,193,92,220,35,30,29,53,58,84,85,107,40,200,11,128,217,45, -187,89,148,89,36,7,207,70,102,176,16,78,162,40,224,67,85,73,54,92,110,59, -50,152,0,191,223,129,116,33,11,195,95,102,26,76,1,6,221,233,243,216,192, -147,79,183,205,34,15,140,45,226,253,143,136,28,93,158,123,242,43,154,119, -86,222,224,132,218,170,221,88,161,174,166,251,28,224,204,206,233,78,227, -107,211,53,134,108,250,13,8,36,144,178,253,157,172,38,86,23,30,220,189, -116,242,154,28,11,63,94,210,233,58,136,101,144,169,74,208,165,192,43,58, -173,30,48,166,195,158,170,53,186,166,192,151,230,192,62,143,7,82,240,96, -195,253,87,139,170,162,234,245,133,89,110,243,156,46,1,235,4,141,8,177, -68,194,18,224,160,203,73,73,21,164,4,195,236,92,18,62,47,143,234,50,47, -124,75,138,48,17,81,47,23,237,226,113,172,72,52,201,225,13,202,78,22,98, -113,29,6,207,20,136,173,46,117,191,30,157,61,151,197,103,66,82,85,240,162, -29,54,193,142,202,98,30,149,155,206,40,116,126,157,178,235,150,253,159, -211,11,136,134,127,119,167,166,20,5,119,186,6,167,143,151,150,33,63,207, -139,52,114,32,186,104,10,21,32,161,88,150,105,4,204,204,18,145,215,226, -10,38,135,223,226,106,125,77,33,13,82,200,24,164,208,167,55,207,155,6,167, -190,66,16,25,53,135,51,27,181,66,118,35,138,133,53,213,194,50,89,153,26, -121,135,209,161,129,38,131,103,150,96,124,58,91,110,118,128,212,101,89, -105,171,57,84,130,189,249,123,16,103,156,105,217,64,52,201,16,153,159,197, -106,232,27,62,14,189,108,234,48,226,183,31,218,214,242,17,130,55,218,186, -174,251,50,3,103,232,64,112,137,46,200,146,100,4,201,107,225,229,158,91, -77,231,111,83,204,164,209,150,255,94,227,142,85,64,240,27,51,178,99,207, -172,106,211,246,206,231,252,71,128,1,0,112,7,72,225,52,89,175,48,0,0,0, -0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_3 = 758; -static unsigned char xml_res_file_3[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, -0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, -0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, -73,77,69,7,225,5,27,16,40,7,129,43,165,16,0,0,2,131,73,68,65,84,72,199, -173,150,75,72,85,81,20,134,191,181,207,193,30,100,20,133,72,138,40,74,88, -148,98,23,172,73,154,26,145,41,105,13,170,91,87,16,130,102,61,104,208,80, -176,73,163,232,49,8,10,132,64,203,50,172,124,21,36,233,176,129,248,200, -66,169,244,38,248,106,16,22,106,131,186,247,156,213,68,73,229,30,189,222, -252,135,251,44,190,181,215,218,255,62,107,11,203,200,215,222,144,226,154, -112,153,8,37,64,42,144,60,247,105,12,24,65,181,213,178,77,83,87,190,127, -212,139,33,145,22,179,223,54,36,89,226,84,129,158,7,44,150,151,139,72,163, -11,215,250,10,252,35,43,38,240,117,62,46,87,165,22,216,196,234,52,163,72, -160,183,208,223,188,112,209,44,134,63,186,172,74,99,12,112,128,120,65,95, -248,58,234,47,69,172,96,110,231,141,75,147,198,32,87,145,19,243,149,8,64, -86,103,93,178,173,102,48,198,157,71,110,87,88,50,123,143,248,39,12,128, -173,230,186,23,252,66,234,30,106,246,29,38,51,126,235,170,218,133,165,213, -0,226,107,111,72,81,43,28,244,114,203,205,189,7,57,180,61,25,87,149,151, -147,195,220,25,238,99,54,28,138,38,137,19,22,55,213,96,57,229,81,88,17, -35,194,201,29,25,60,223,95,74,105,98,90,100,127,47,150,101,99,149,25,69, -139,87,83,251,182,184,245,84,239,58,192,253,156,34,210,54,110,94,54,86, -85,143,25,144,140,88,78,209,183,37,129,39,185,197,92,76,207,38,206,88,94, -183,56,221,128,38,198,106,21,91,12,149,41,187,105,200,45,38,97,221,134, -72,33,73,102,45,60,25,103,44,44,137,136,114,109,129,9,133,157,177,128,29, -85,158,141,127,225,222,215,126,126,69,118,214,132,173,16,36,134,4,3,51, -83,220,248,212,197,192,204,148,247,33,67,208,70,181,13,145,163,209,130, -167,67,127,120,48,242,145,167,227,159,113,85,151,183,182,106,171,109,217, -166,201,113,244,246,74,119,65,129,87,223,70,184,53,212,195,143,208,239, -104,246,18,14,25,109,49,93,249,254,81,65,30,122,69,13,205,254,228,195,244, -119,42,187,223,80,53,248,46,90,56,64,77,127,65,96,76,254,13,152,240,32, -16,191,70,63,187,105,177,157,204,238,188,138,73,3,240,190,232,212,184,170, -57,13,56,107,0,119,81,2,221,121,21,147,139,6,78,111,209,153,215,130,92, -5,220,255,154,5,202,149,158,162,179,45,158,35,51,167,163,254,184,160,117, -49,180,107,26,113,207,245,20,4,90,61,71,38,64,111,161,191,89,109,59,93, -209,187,64,56,170,150,160,181,98,59,153,75,225,158,175,138,121,101,117, -214,37,219,88,101,224,150,160,146,182,240,217,162,16,52,208,22,18,183,185, -191,32,48,230,197,248,11,86,228,238,84,203,121,117,202,0,0,0,0,73,69,78, -68,174,66,96,130}; - -static size_t xml_res_size_4 = 635; -static unsigned char xml_res_file_4[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, -0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, -0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, -73,77,69,7,225,5,27,16,39,59,41,220,197,88,0,0,2,8,73,68,65,84,72,199,181, -150,79,107,19,81,20,197,127,247,77,42,74,213,77,161,105,59,67,168,180,139, -172,252,12,110,107,193,68,67,43,65,17,164,184,85,113,225,170,8,250,17,92, -43,8,117,211,148,40,77,82,220,250,17,220,117,33,132,66,39,211,70,234,194, -74,241,79,230,205,117,209,36,152,191,198,208,57,48,139,119,223,155,115, -207,59,92,238,125,194,16,4,133,185,148,138,205,160,178,12,209,60,136,119, -186,163,62,152,61,160,130,53,219,110,62,216,31,196,33,253,130,251,133,41, -87,72,60,19,88,3,28,134,35,18,40,138,149,167,179,249,195,189,127,38,8,54, -167,179,42,178,1,92,228,255,240,29,184,235,174,214,75,127,7,77,167,37,201, -71,42,82,28,131,28,224,18,240,62,216,76,62,236,123,131,166,242,98,119,210, -49,16,1,55,91,55,17,0,191,232,122,98,195,221,110,229,226,92,192,156,159, -110,255,103,79,124,0,156,73,175,173,35,250,249,5,181,63,122,236,178,214, -166,83,249,163,32,1,32,97,248,2,233,181,229,242,213,117,38,23,215,218,235, -175,31,111,1,48,117,237,93,59,118,242,249,21,223,62,173,247,216,229,24, -231,57,240,192,4,133,185,20,194,189,254,53,150,232,92,155,115,167,95,71, -108,98,80,125,222,247,139,174,103,80,155,29,161,20,199,129,35,161,205,24, -21,89,34,38,136,232,117,3,186,24,87,2,69,23,12,48,67,108,16,215,16,47,34, -3,18,196,152,32,48,64,53,54,131,160,106,128,157,216,252,65,43,6,107,182, -1,27,3,127,136,51,81,54,205,97,241,166,191,132,70,103,217,69,191,32,250, -61,244,76,251,172,242,218,203,213,124,105,13,24,67,98,183,217,114,207,162, -217,29,55,28,155,158,207,29,29,180,219,245,193,214,204,82,164,90,62,131, -182,17,161,100,221,219,245,114,199,192,153,93,57,252,32,202,147,102,63, -31,159,92,120,220,34,239,59,50,107,133,228,13,224,109,183,93,35,224,88, -133,59,222,74,189,50,112,100,2,184,171,245,146,65,22,16,94,2,225,40,170, -21,217,104,56,54,221,77,62,240,85,209,130,95,116,61,9,109,70,37,90,22,228, -10,224,181,182,4,170,42,178,163,198,41,121,185,154,63,136,227,15,131,228, -187,196,255,21,120,89,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_5 = 622; -static unsigned char xml_res_file_5[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, -0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, -0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, -73,77,69,7,225,5,27,16,40,10,255,154,217,173,0,0,1,251,73,68,65,84,72,199, -181,150,79,107,19,81,20,197,127,247,189,81,20,172,224,78,104,76,83,154, -69,65,92,249,29,4,173,249,163,11,5,91,18,161,184,85,113,225,82,169,31,193, -125,109,154,182,238,146,54,147,20,193,79,224,70,23,74,177,155,198,212,196, -184,20,234,194,66,102,230,186,104,163,113,72,106,26,157,179,155,251,134, -115,238,59,243,230,158,39,28,129,157,84,46,238,88,147,65,153,81,130,4,72, -236,96,69,91,130,105,168,6,53,79,108,37,89,89,106,14,226,144,126,197,230, -245,220,184,103,228,137,8,243,128,229,104,4,8,37,69,30,79,110,20,26,127, -21,248,148,189,155,21,213,21,224,12,199,195,119,163,204,197,221,101,183, -183,104,122,31,118,211,185,7,162,90,26,129,28,96,44,16,214,119,51,249,251, -125,119,112,216,121,41,44,58,2,2,163,220,232,238,68,0,90,55,103,99,158, -239,124,28,177,243,1,118,217,233,184,251,162,237,0,120,190,243,44,76,126, -234,226,52,167,47,95,26,138,237,199,219,15,236,111,109,135,236,242,23,128, -123,178,147,202,197,173,145,122,248,180,156,155,191,195,217,212,149,161, -4,246,170,175,249,182,248,50,92,246,29,235,37,140,99,36,59,196,81,28,5, -214,243,157,140,81,184,74,100,208,107,6,72,70,39,192,148,1,206,71,199,47, -227,134,104,17,24,160,29,161,64,219,0,245,8,63,114,221,160,186,25,25,189, -72,205,120,98,43,128,31,1,191,119,194,120,85,39,89,89,106,54,210,249,2, -7,179,255,247,239,255,230,29,116,58,67,142,138,247,125,130,70,22,99,229, -181,150,3,96,3,125,234,91,185,5,140,117,95,216,223,218,14,207,151,227,96, -79,173,183,240,43,15,46,212,138,95,16,189,253,159,172,10,4,153,75,148,87, -191,254,17,56,137,141,226,43,129,71,64,240,79,228,34,15,39,42,133,234,192, -200,252,156,206,167,3,97,181,215,174,97,109,17,163,179,19,235,197,218,192, -200,4,136,187,203,110,231,164,153,82,120,14,120,195,116,13,186,130,245, -167,195,228,3,111,21,93,28,38,93,6,101,6,97,18,136,117,151,64,235,192,166, -99,125,55,86,94,107,13,226,248,9,156,77,179,166,75,139,17,212,0,0,0,0,73, -69,78,68,174,66,96,130}; - -static size_t xml_res_size_6 = 1144; -static unsigned char xml_res_file_6[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, -0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, -0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, -73,77,69,7,225,5,27,16,40,3,134,70,97,9,0,0,4,5,73,68,65,84,72,199,149, -150,125,76,213,85,24,199,63,231,220,223,21,132,139,74,76,96,23,68,4,2,95, -74,36,204,149,185,28,80,54,112,75,237,143,182,107,184,114,174,173,53,179, -172,173,218,154,110,218,250,167,245,178,176,173,63,154,171,41,190,76,231, -31,10,182,53,2,172,54,209,25,34,182,188,18,112,167,128,225,11,239,92,64, -238,203,239,233,15,188,183,251,194,5,122,254,59,231,57,207,247,123,206, -247,60,207,121,142,98,6,43,174,59,149,101,106,223,22,165,216,12,100,3,153, -143,92,61,192,45,68,106,45,134,62,123,101,163,163,59,22,134,154,110,178, -176,254,84,134,69,249,247,131,236,2,44,204,108,38,74,157,49,225,195,107, -37,142,91,179,18,20,55,30,223,42,194,81,192,198,255,179,81,65,85,182,148, -58,206,197,36,40,110,60,246,174,136,250,10,208,161,243,217,9,11,88,155, -156,74,122,92,34,94,49,233,28,27,230,210,64,47,110,159,55,234,52,10,181, -183,185,212,81,21,69,240,104,231,103,66,193,87,36,61,198,222,188,34,138, -23,165,70,109,215,47,66,205,93,23,135,58,91,25,242,78,134,145,8,106,91, -224,36,10,96,117,99,117,166,33,218,25,42,203,54,123,46,31,231,175,197,80, -83,124,109,238,65,122,31,142,97,85,154,60,219,34,210,226,18,0,24,244,78, -242,246,181,6,254,118,15,133,203,229,83,203,91,54,57,254,49,0,12,209,7, -67,193,95,74,93,202,39,5,235,80,192,197,129,94,190,104,111,230,246,248, -104,48,90,43,197,51,201,233,124,148,191,150,204,249,54,190,91,83,202,27, -205,117,116,79,4,215,36,97,145,3,192,155,170,184,238,84,150,88,124,174, -208,108,249,105,253,22,210,226,18,168,185,235,226,128,243,50,18,227,86, -19,13,43,223,23,149,81,96,75,230,226,64,47,239,180,94,8,83,209,167,204, -108,139,125,231,43,175,3,21,161,158,206,177,97,58,198,134,249,214,213,138, -57,67,218,236,206,41,36,101,94,60,233,241,137,44,153,159,196,170,5,41,60, -151,98,231,215,190,59,8,104,173,180,75,11,82,30,25,120,105,224,46,71,186, -156,248,69,102,204,203,62,207,4,133,11,23,7,199,27,82,236,120,76,63,230, -163,56,17,169,208,160,242,34,3,173,90,163,149,154,53,241,143,117,183,113, -99,116,32,56,238,247,60,228,155,142,107,161,53,144,171,65,210,35,3,63,91, -185,158,183,150,61,57,43,129,41,194,193,155,151,241,201,148,144,159,183, -55,51,226,243,132,46,201,48,34,131,54,164,216,41,91,188,4,191,8,245,247, -187,105,115,15,206,72,210,238,30,226,72,151,147,2,91,50,191,220,239,138, -46,188,226,134,227,109,2,249,129,172,56,189,174,34,152,227,109,238,65,118, -252,241,243,172,119,161,149,194,80,26,143,233,143,116,221,212,2,174,192, -104,79,206,154,32,56,64,129,45,25,71,102,193,156,164,154,6,28,1,151,70, -228,124,160,164,19,12,131,11,125,61,193,5,127,141,244,135,17,78,103,86, -173,217,157,83,200,166,212,172,232,147,137,212,106,139,161,207,2,126,1, -246,221,104,226,131,63,127,15,106,153,100,157,199,15,93,55,102,148,230, -211,21,207,178,115,233,74,222,207,123,42,210,237,243,106,169,209,87,54, -58,186,21,234,199,80,207,151,29,87,185,55,57,78,214,252,36,78,62,93,78, -121,90,54,243,116,216,3,203,19,11,82,56,92,244,2,47,166,102,225,49,77,246, -59,155,34,9,14,95,47,169,236,81,255,53,24,159,19,72,10,120,3,111,140,61, -62,17,128,49,159,23,215,248,48,94,211,196,30,111,35,61,126,74,186,135,126, -63,251,156,77,52,60,8,107,106,35,202,240,47,111,126,126,71,111,176,154, -138,234,79,150,43,101,214,132,190,73,9,22,131,93,217,171,120,53,227,113, -18,44,214,168,139,253,173,255,14,85,157,173,220,30,31,9,239,112,194,214, -171,101,219,107,162,27,78,195,137,61,130,124,29,217,112,172,90,83,180,112, -49,185,137,139,176,40,197,189,201,113,90,134,30,208,231,153,152,46,161, -222,107,41,219,126,40,102,203,44,106,56,241,178,66,170,67,229,154,163,141, -160,204,215,174,150,84,214,134,37,66,228,170,150,82,199,57,49,140,92,65, -170,0,223,28,128,77,144,163,202,240,47,143,4,143,249,171,8,216,234,198, -234,76,3,203,22,48,55,35,106,89,232,183,101,170,136,56,239,85,230,185,235, -37,149,61,177,48,254,5,68,165,141,10,108,236,250,76,0,0,0,0,73,69,78,68, -174,66,96,130}; - -static size_t xml_res_size_7 = 1852; -static unsigned char xml_res_file_7[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,6,222,73,68,65,84,120,218,188,87,107,136,85,85,20,254,246,62,231, -222,59,247,206,181,113,108,212,73,51,51,130,140,32,170,31,61,200,136,222, -132,40,169,101,69,66,101,15,122,64,74,15,169,8,42,168,176,172,44,168,164, -232,97,86,72,143,49,205,158,248,39,66,255,20,84,100,165,65,145,164,53,154, -81,206,204,109,230,156,123,206,61,167,111,173,125,212,123,207,204,144,70, -117,240,56,107,159,253,250,246,183,190,181,246,186,6,128,191,230,206,147, -214,90,196,51,145,166,108,202,251,95,62,134,255,12,18,248,239,205,93,250, -249,69,62,191,148,109,26,205,60,241,178,165,72,147,6,251,140,27,164,111, -54,126,132,101,82,252,19,172,169,78,49,198,226,139,215,239,154,41,123,11, -128,54,68,53,212,251,127,193,150,13,43,0,235,195,216,34,71,121,186,179, -103,129,130,117,211,19,206,182,25,154,40,113,109,89,49,109,61,223,190,246, -48,155,12,39,60,228,177,231,222,200,70,34,159,219,4,128,233,190,226,93, -108,217,253,43,112,198,114,76,232,158,130,223,215,95,201,157,139,4,98,80, -34,142,37,235,138,194,26,158,152,23,98,113,79,73,61,245,232,156,58,23,115, -27,196,13,89,60,129,37,177,150,136,19,93,155,182,109,181,27,137,65,20,69, -14,150,50,205,45,228,255,193,218,239,216,246,195,86,108,251,126,43,134, -6,251,224,179,211,231,66,190,245,200,128,65,165,189,202,183,29,150,243, -42,149,118,181,125,206,191,253,157,118,125,11,30,199,179,115,207,113,247, -226,214,55,13,121,77,208,151,183,223,178,40,249,92,211,227,137,210,198, -62,198,132,1,196,245,24,29,29,157,180,44,162,48,230,32,46,88,112,92,199, -113,130,123,207,236,229,73,98,244,15,0,247,204,24,212,239,181,26,176,244, -252,65,158,216,67,163,81,128,103,82,68,65,13,69,63,165,203,82,196,121,219, -75,245,48,150,135,75,243,0,18,175,132,142,113,19,148,144,196,248,40,149, -124,44,90,227,57,170,103,199,56,235,206,183,57,42,24,69,88,109,248,232, -161,121,40,148,44,194,48,32,213,6,30,65,141,102,147,84,100,126,217,15,96, -251,170,153,152,126,246,117,216,241,213,251,24,162,239,15,153,212,133,246, -234,24,245,43,82,30,21,60,58,23,129,231,187,87,158,70,236,222,98,164,227, -12,69,27,6,117,61,33,221,141,32,111,211,144,8,211,40,203,51,112,194,162, -77,216,185,179,23,213,115,47,68,247,225,71,34,218,112,61,150,207,174,81, -168,41,250,6,140,219,136,19,223,184,123,46,252,82,155,115,13,1,205,127, -224,77,237,147,141,60,178,23,214,3,221,200,35,237,245,156,109,116,140,115, -129,65,14,64,56,212,135,111,190,222,172,155,140,59,180,139,19,83,92,187, -218,215,168,93,62,203,138,16,84,185,157,227,186,80,108,171,232,196,122, -48,232,66,169,145,50,98,185,48,223,48,116,39,181,244,119,56,148,179,9,80, -198,73,100,49,28,90,1,68,245,8,237,149,146,106,64,194,164,66,32,43,23,36, -144,97,253,253,156,64,1,74,208,143,169,150,233,235,178,203,3,20,152,2,179, -217,201,184,89,56,20,104,146,241,76,162,126,111,177,51,1,10,144,84,25,48, -251,1,52,152,28,202,229,178,70,65,220,136,53,4,23,174,138,52,209,60,117, -137,231,0,48,216,43,20,167,231,187,137,5,153,26,215,169,9,79,253,111,69, -3,245,186,138,205,216,17,108,97,128,175,117,25,169,149,129,6,41,41,209, -183,41,1,52,24,118,18,134,149,114,73,147,76,193,11,50,0,33,142,191,248, -46,151,33,53,171,242,20,49,251,76,73,147,143,199,183,78,23,24,2,242,188, -132,126,15,135,217,34,72,25,155,101,193,166,48,76,13,218,202,21,110,104, -244,212,2,196,43,180,185,52,234,197,122,202,125,234,55,217,100,81,51,211, -54,209,194,247,125,231,130,48,212,147,202,70,46,34,154,108,97,195,100,9, -48,31,5,182,88,65,91,181,160,0,36,5,167,60,229,138,249,177,250,105,48,44, -162,231,145,219,24,186,137,10,145,228,144,21,232,194,210,47,9,120,210,248, -14,197,88,207,104,151,136,200,219,78,15,34,25,134,108,30,192,79,175,205, -199,49,167,205,70,255,207,155,17,51,17,217,73,157,184,236,133,72,7,172, -188,170,132,35,216,150,139,196,232,230,6,87,190,20,42,8,1,16,113,173,85, -11,61,141,28,137,2,35,241,78,218,131,156,237,244,0,141,4,168,188,155,68, -56,177,107,44,166,76,158,136,33,179,75,145,210,35,120,235,6,95,55,29,12, -24,13,84,251,94,6,164,111,229,2,104,90,117,23,44,179,39,67,81,194,80,124, -173,57,129,27,71,57,219,9,48,213,136,113,215,104,19,3,178,136,228,236,57, -207,13,168,47,123,110,238,192,197,207,244,113,211,20,47,47,44,227,148,171, -239,151,88,109,45,0,76,166,3,186,236,179,151,239,99,179,160,39,133,170, -61,29,102,187,44,232,106,129,97,137,72,65,48,20,229,150,219,91,144,136, -40,147,140,118,244,237,160,226,163,150,240,217,39,68,175,64,208,34,10,15, -53,138,45,74,172,18,92,11,162,97,182,176,103,108,50,92,132,178,110,196, -240,123,126,129,175,64,6,254,12,240,236,165,174,126,169,179,242,232,89, -177,172,37,116,154,105,144,240,154,54,185,11,49,239,250,37,51,246,104,156, -7,113,21,119,204,248,67,71,4,241,24,44,57,99,143,178,222,72,218,29,232, -116,152,11,160,149,74,200,100,115,194,229,247,184,211,238,165,155,127,78, -26,173,246,146,197,252,34,190,92,253,160,14,60,124,124,69,197,40,39,156, -220,85,209,80,145,156,114,68,247,33,168,199,188,150,69,43,34,70,242,146, -230,93,32,16,153,40,73,247,207,25,221,73,174,208,26,13,64,65,197,38,26, -218,232,93,129,237,219,190,215,174,169,211,142,198,57,118,53,102,63,177, -91,195,123,205,45,227,179,91,152,26,200,39,162,236,126,213,251,122,253, -139,79,114,239,88,35,224,111,235,91,17,22,147,209,81,147,15,149,124,132, -95,123,119,224,227,13,31,104,223,133,179,230,192,159,98,80,29,83,85,0,122, -11,90,151,199,82,140,0,64,228,34,7,154,181,248,97,98,25,65,112,163,49,64, -17,126,219,179,76,75,173,93,187,118,177,100,115,151,149,216,102,170,135, -158,155,164,174,48,8,162,84,43,36,185,8,61,164,35,48,160,138,207,92,112, -144,0,132,137,148,115,183,237,216,137,134,117,119,200,143,219,123,145,158, -108,113,206,195,187,181,253,225,109,227,113,222,178,221,252,59,97,248,93, -160,106,38,55,30,67,233,163,87,159,86,65,30,40,0,9,193,35,89,65,53,56,229, -246,83,123,181,0,145,185,113,50,196,248,239,192,187,139,198,105,197,20, -6,33,62,88,220,169,185,197,51,185,235,88,215,18,84,156,124,193,77,15,186, -10,232,32,24,248,110,237,99,220,48,193,233,215,220,183,127,174,172,79,125, -108,237,121,4,211,231,45,129,34,228,133,246,221,186,199,81,72,70,212,0, -180,12,199,64,175,91,228,128,126,246,24,93,84,42,99,125,250,126,105,154, -235,110,75,77,82,125,92,83,88,149,235,153,109,219,180,130,239,126,29,100, -101,120,90,198,198,181,175,224,192,127,35,186,251,117,106,247,88,109,181, -206,205,250,38,118,96,227,186,236,187,180,15,235,212,189,140,53,205,153, -208,212,62,221,244,73,85,138,80,99,14,254,231,230,111,63,237,247,200,72, -125,205,223,181,109,141,238,185,55,195,8,252,105,124,59,71,207,56,255,250, -35,20,73,174,254,209,104,121,7,48,73,163,136,255,247,145,235,245,207,191, -4,24,0,228,101,43,215,5,253,61,104,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_8 = 1017; -static unsigned char xml_res_file_8[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,3,155,73,68,65,84,120,218,108,83,107,76,28,85,24,61,51,204,192,62,200, -178,180,74,106,85,144,46,143,74,74,85,88,16,180,11,110,155,216,248,10,54, -45,93,72,140,105,13,49,77,68,34,36,45,2,41,181,42,225,33,5,234,143,254, -177,63,76,127,216,198,96,218,106,104,4,45,162,18,90,202,110,154,150,165, -181,117,97,215,2,93,118,102,217,7,236,123,102,118,188,67,72,252,227,73, -78,230,206,157,123,190,239,220,243,101,168,190,254,65,136,162,8,5,130,32, -32,22,143,127,89,110,44,237,96,24,6,118,187,29,222,213,213,31,95,42,41, -105,39,103,70,213,106,245,211,233,26,45,2,235,107,144,68,113,150,162,168, -3,140,34,148,101,121,131,130,32,94,170,124,185,220,242,246,91,111,162,171, -187,219,125,109,100,228,227,18,163,81,78,75,77,181,151,149,150,32,235,137, -39,33,72,34,34,225,8,28,142,249,226,71,203,75,142,141,2,201,100,18,146, -36,125,95,188,123,87,109,117,149,9,63,92,190,140,147,29,237,251,201,167, -191,223,63,114,212,187,179,176,0,52,69,99,226,207,73,132,195,97,132,194, -33,128,162,72,211,36,24,69,156,157,157,13,142,227,106,205,166,61,112,204, -47,160,48,191,0,173,109,29,45,26,141,246,104,52,26,213,234,116,58,220,191, -255,23,180,106,21,92,255,184,208,220,212,104,196,38,24,98,253,138,32,138, -53,150,195,7,49,247,224,33,182,232,245,120,236,118,43,174,142,16,87,107, -241,88,108,163,83,70,70,6,104,154,70,34,145,64,79,223,25,155,36,10,160, -200,59,77,46,80,179,183,186,10,179,246,123,74,24,184,117,107,6,163,99,163, -104,249,164,9,69,69,69,77,49,82,32,22,75,128,37,161,42,182,205,38,147,18, -186,44,41,161,17,69,74,69,229,43,85,235,161,72,110,102,166,30,1,191,15, -103,7,7,222,73,79,99,181,105,108,202,206,170,87,43,96,187,125,7,121,121, -6,50,157,4,52,42,21,114,178,159,65,69,121,25,12,134,92,204,88,109,65,138, -84,217,209,222,209,249,141,70,173,218,27,13,5,199,187,122,122,223,32,123, -79,25,142,159,183,165,179,236,214,241,70,51,22,22,221,120,224,88,128,213, -58,131,156,237,219,176,22,12,34,24,10,91,7,134,134,26,208,223,63,160,100, -177,131,176,84,121,234,186,38,160,59,253,243,133,67,195,243,242,141,128, -44,127,113,221,41,255,58,242,147,124,170,179,83,62,209,210,124,113,243, -156,194,130,158,207,78,130,58,119,166,15,52,153,109,171,184,135,36,42,66, -18,226,223,213,151,61,95,255,65,101,14,206,78,241,88,137,83,240,90,175, -98,244,152,25,211,55,167,197,11,172,241,219,95,238,58,245,44,203,214,42, -33,50,157,241,114,146,100,18,106,57,1,65,20,46,190,190,43,175,78,17,127, -61,229,129,63,46,195,195,251,201,68,224,187,125,99,82,180,101,84,100,181, -154,242,27,168,36,141,223,230,30,94,74,101,216,58,90,5,1,44,233,44,75,194, -240,11,207,110,171,59,177,47,15,195,247,252,240,197,146,88,226,125,240, -56,239,92,155,235,109,48,91,108,169,147,147,235,122,244,143,115,104,219, -111,192,107,249,57,22,81,18,135,233,44,157,6,10,183,166,107,14,14,29,122, -145,116,230,96,95,137,99,209,27,192,162,115,110,140,235,173,111,220,222, -125,253,46,9,89,203,249,56,248,163,18,190,154,240,224,212,187,69,27,26, -154,216,83,44,18,80,56,55,237,71,48,33,227,17,207,97,201,101,31,243,245, -30,62,214,247,105,179,51,73,165,192,253,249,129,143,188,174,217,177,101, -47,135,64,76,198,224,31,62,200,68,147,194,154,234,16,37,127,97,196,207, -155,31,7,35,207,121,86,121,4,60,174,113,190,199,242,97,87,219,113,34,166, -113,83,85,136,45,251,222,243,47,159,174,153,98,118,87,23,7,19,241,220,69, -158,199,154,119,229,119,10,255,193,64,168,223,92,251,9,23,240,255,80,70, -158,185,185,14,252,43,192,0,141,58,185,202,150,159,74,140,0,0,0,0,73,69, -78,68,174,66,96,130}; - -static size_t xml_res_size_9 = 1751; -static unsigned char xml_res_file_9[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,6,121,73,68,65,84,120,218,180,87,91,136,85,85,24,254,215,90,123, -239,115,206,92,116,116,38,157,48,47,35,90,80,129,89,116,33,51,74,165,34, -6,52,20,231,33,240,33,80,8,133,30,213,232,74,15,225,99,161,4,69,15,9,65, -23,203,140,30,122,200,64,208,138,233,98,150,24,42,90,94,162,209,156,25, -103,206,204,156,115,246,109,245,253,107,175,125,206,222,211,25,60,15,181, -14,63,251,236,117,251,191,245,255,223,255,255,107,11,74,154,243,234,190, -15,15,72,229,172,215,90,211,255,217,132,16,20,71,225,161,151,183,15,108, -194,107,40,88,249,139,111,188,127,80,72,167,127,197,138,229,20,51,128,255, -11,3,180,73,0,56,113,226,44,233,56,252,226,181,231,158,126,202,65,119,137, -148,211,191,107,251,102,138,211,137,186,233,218,186,76,111,26,157,241,204, -58,115,107,120,235,199,87,175,164,61,251,62,234,103,221,12,160,24,71,177, -217,96,235,243,111,153,73,137,21,120,168,13,82,32,137,101,5,242,129,116, -138,28,10,217,104,232,41,226,233,65,185,160,192,13,104,170,84,161,192,9, -208,111,182,36,129,245,18,187,122,88,231,106,159,164,134,14,40,241,107, -130,222,124,233,89,252,55,144,139,60,91,104,44,11,35,108,231,57,244,238, -43,91,41,136,24,4,143,63,4,159,29,35,23,255,142,210,195,244,168,56,98,182, -47,64,92,218,128,255,63,144,35,75,84,131,146,145,133,23,40,154,67,20,1, -151,116,239,38,225,118,193,176,130,222,115,183,65,158,161,118,108,18,3, -123,223,234,119,8,231,37,203,53,225,24,179,224,37,8,53,22,40,242,49,169, -234,91,0,162,0,243,181,225,28,34,81,139,71,135,57,55,108,32,60,128,232, -32,165,74,164,221,73,51,92,129,193,98,70,231,97,157,219,142,227,225,212, -174,36,23,90,92,69,198,118,133,130,194,1,67,86,154,176,191,1,32,162,2,102, -177,98,118,65,204,142,133,8,99,72,153,98,229,127,164,120,161,86,88,236, -130,84,108,106,215,116,198,152,18,179,185,148,34,161,48,19,34,164,224,215, -122,43,120,0,0,19,167,209,38,19,102,104,211,233,186,78,26,43,211,152,132, -29,132,52,118,144,117,97,104,248,161,95,113,143,204,14,202,186,48,128,236, -118,172,35,8,67,210,148,1,192,104,124,116,186,142,99,24,157,227,172,81, -172,140,58,202,1,144,38,164,164,129,34,76,167,200,1,80,117,0,217,208,98, -29,126,24,215,45,224,52,0,196,13,11,104,202,88,34,221,89,24,211,11,145, -181,128,74,237,208,240,141,25,132,77,160,88,243,233,101,222,154,198,2,193, -116,14,144,54,157,6,128,206,4,48,9,123,114,97,50,152,152,110,1,134,33,44, -0,101,215,240,160,163,12,8,33,99,195,5,193,134,180,137,130,35,205,184,32, -11,192,112,0,157,94,157,3,169,21,68,114,100,145,170,204,0,16,202,192,83, -134,1,42,217,201,77,66,68,184,46,107,66,56,34,178,48,207,197,22,30,3,136, -56,10,0,32,106,226,130,192,184,64,82,190,20,228,207,204,135,84,34,57,172, -50,220,119,17,142,78,194,129,9,68,64,0,193,160,30,27,36,25,118,80,36,125, -58,89,189,151,62,27,177,233,18,227,253,91,101,46,10,26,0,208,233,57,174, -209,217,160,128,74,34,192,18,141,149,59,214,56,19,52,73,99,250,34,77,196, -62,226,251,42,209,105,28,176,4,97,43,208,53,76,98,166,87,40,18,149,36,115, -177,5,0,160,8,235,248,198,5,212,0,192,113,95,139,216,5,170,73,38,183,236, -2,16,108,69,151,180,177,36,222,135,1,176,140,83,58,141,217,142,37,162,57, -85,178,206,112,72,155,116,107,128,123,94,146,136,226,188,5,40,33,161,231, -228,84,55,78,95,33,95,143,154,76,38,172,27,132,45,51,156,37,117,179,18, -37,40,71,104,157,141,2,63,110,146,9,131,216,48,148,67,152,73,156,112,16, -190,138,203,224,96,100,84,165,7,227,108,41,204,12,196,143,212,117,77,138, -247,141,44,119,209,39,177,111,253,126,17,89,147,115,30,168,54,18,81,61, -10,66,84,138,246,146,162,118,213,48,99,140,234,23,83,213,76,18,230,252, -105,127,186,99,144,171,221,179,38,237,56,120,160,149,15,64,62,69,126,148, -73,68,194,228,235,127,39,34,252,34,132,70,215,108,55,151,54,239,184,111, -45,117,247,44,166,8,12,94,57,188,140,244,96,99,236,133,7,214,210,169,238, -37,80,162,192,183,113,227,227,180,173,25,216,76,65,97,22,69,97,141,182, -109,185,147,244,19,141,177,67,131,14,85,107,97,179,76,24,26,23,100,155, -82,21,212,147,49,227,231,80,130,7,246,204,92,13,71,49,54,162,174,35,16, -81,148,162,169,252,186,145,9,84,197,8,0,2,170,141,84,97,67,84,194,72,112, -109,50,42,253,160,41,0,248,12,87,142,225,234,53,36,49,166,172,130,85,118, -163,118,187,73,4,201,128,46,169,17,132,85,68,10,99,187,162,157,228,98,12, -201,142,100,132,190,43,35,230,25,163,244,69,7,62,78,158,32,139,31,248,116, -249,175,97,240,38,6,121,5,220,92,164,161,225,241,60,9,57,205,242,235,79, -191,13,67,254,206,148,3,244,219,234,196,110,210,66,215,125,41,116,18,7, -41,5,132,185,69,105,147,57,181,176,25,84,219,117,118,140,245,40,176,188, -88,240,234,21,215,228,149,169,242,216,177,159,191,251,118,149,142,227,230, -87,66,109,57,155,62,51,253,211,203,183,176,239,162,73,89,79,223,4,64,84, -38,198,143,217,252,72,157,144,69,144,158,122,84,204,220,228,150,29,187, -215,47,233,91,190,177,216,57,167,55,59,80,45,143,14,253,241,251,217,79, -246,239,125,253,16,205,124,71,77,91,152,164,75,186,40,172,210,146,185,73, -54,191,244,26,208,107,250,7,22,61,242,228,198,193,9,228,139,123,238,186, -149,206,195,175,217,76,179,244,230,110,58,126,226,12,181,57,146,142,124, -249,233,253,135,63,255,224,2,205,124,193,231,126,230,102,197,177,104,202, -86,102,106,133,85,143,109,24,210,133,34,114,121,76,157,179,58,104,221,130, -121,117,38,179,111,175,150,167,200,3,193,52,204,251,224,186,245,223,0,64, -59,134,106,55,250,84,112,90,252,164,104,11,16,82,203,22,206,167,242,100, -133,206,158,187,76,103,166,125,65,49,136,121,61,93,52,167,179,131,126,253, -229,148,178,119,250,255,12,128,27,162,94,247,205,159,43,145,75,105,116, -124,146,42,190,159,227,96,9,245,191,103,118,7,133,65,64,199,185,182,39, -183,131,27,54,213,34,0,175,60,62,250,253,148,156,53,224,224,138,117,91, -223,2,186,125,233,45,180,184,119,46,164,155,22,245,246,96,163,152,78,158, -62,79,95,31,253,145,14,31,220,191,233,234,159,23,206,89,63,223,232,107, -173,165,198,21,125,62,71,203,166,109,59,119,116,245,244,174,115,92,183, -59,107,2,156,124,248,250,181,161,175,14,188,189,103,47,179,27,114,165,21, -23,180,10,64,216,12,220,5,185,9,50,219,130,202,94,121,89,217,24,132,51, -217,117,136,79,45,124,230,182,10,32,235,178,162,85,238,52,137,237,154,53, -123,212,234,134,255,8,48,0,163,88,200,134,33,243,7,106,0,0,0,0,73,69,78, -68,174,66,96,130}; - -static size_t xml_res_size_10 = 1855; -static unsigned char xml_res_file_10[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,6,225,73,68,65,84,120,218,196,87,123,80,84,85,24,255,238,115,31, -160,41,169,37,175,196,16,28,21,75,108,20,21,195,200,124,128,111,39,49,205, -7,154,38,249,154,177,153,242,143,254,232,53,163,142,53,227,24,67,89,227, -148,96,36,166,228,35,95,164,136,104,68,89,249,2,53,65,65,212,69,151,213, -117,217,221,123,239,62,238,189,125,231,238,93,220,20,84,172,198,157,249, -102,239,185,247,156,243,253,206,247,251,94,135,82,85,21,30,231,143,250, -151,235,185,241,175,229,92,197,255,110,12,195,216,119,108,206,125,10,159, -125,237,217,128,121,84,224,47,101,78,143,75,30,146,110,27,147,145,17,54, -120,200,16,56,117,226,132,41,50,246,217,163,245,53,213,117,237,217,136, -126,4,229,244,152,169,243,102,71,197,198,93,202,156,56,17,142,149,151,131, -44,203,160,42,10,72,130,139,107,239,158,108,59,149,51,25,211,22,108,141, -239,149,48,165,95,82,18,148,150,148,128,71,146,208,30,1,38,21,69,161,117, -0,242,255,1,128,203,156,182,240,242,144,212,212,238,70,163,17,126,173,172, -4,142,227,128,161,67,15,220,170,67,115,230,101,165,215,17,221,53,33,119, -228,192,187,125,132,126,40,190,51,178,226,38,207,90,234,205,156,48,161, -59,58,27,212,92,184,160,41,55,153,205,96,68,1,140,36,181,109,143,230,132, -245,233,131,128,162,227,17,136,131,140,219,3,128,30,61,37,123,86,247,152, -30,26,223,54,155,13,44,22,11,24,77,38,77,120,131,1,12,104,141,214,66,153, -75,91,222,17,21,90,77,11,126,200,198,161,71,248,44,125,56,248,164,75,230, -197,7,246,135,90,254,126,0,152,177,175,190,81,212,43,177,247,166,87,70, -143,134,134,250,122,112,58,157,96,34,202,81,169,1,149,27,117,105,13,128, -98,57,101,80,221,183,126,164,76,157,114,205,57,123,215,224,171,27,194,231, -25,51,129,225,134,153,230,22,78,15,234,38,72,216,171,27,83,118,240,148, -63,147,5,63,92,176,135,195,59,71,147,192,196,248,33,101,232,80,136,138, -142,134,250,186,58,77,9,81,126,143,34,244,126,85,231,159,82,149,22,36,114, -77,153,40,214,148,173,226,82,23,149,114,201,89,5,166,236,162,74,241,235, -172,98,127,245,190,121,108,223,140,111,113,202,118,20,145,0,48,113,224, -207,236,154,93,136,123,200,48,152,146,97,122,172,3,76,172,31,68,193,5,215, -209,228,132,111,138,106,157,97,2,140,8,165,146,35,41,154,207,240,243,183, -15,98,195,58,239,146,47,28,30,231,217,255,81,37,221,241,233,101,76,124, -218,122,252,182,217,123,104,109,37,219,103,172,100,156,181,105,154,84,48, -167,128,152,1,73,196,133,126,23,216,74,94,7,225,240,108,104,178,218,192, -106,181,130,219,237,214,156,140,240,77,184,110,77,200,55,208,40,64,16,1, -91,80,190,109,75,235,193,239,109,98,18,210,143,227,248,150,103,239,251, -251,65,246,93,53,205,223,182,2,199,130,234,188,94,68,133,117,33,190,193, -209,45,206,171,72,96,140,136,2,99,231,72,220,212,172,153,59,200,247,125, -5,231,168,119,232,144,53,163,56,44,94,33,111,204,12,213,43,156,49,231,236, -219,138,239,156,202,141,243,95,80,230,8,2,64,149,175,157,222,75,241,230, -52,114,248,128,19,170,148,6,192,208,169,27,208,157,187,1,75,51,192,178, -40,204,253,133,132,36,153,27,36,199,239,247,41,244,146,35,249,166,37,7, -139,113,104,247,253,178,113,37,112,198,151,53,165,13,191,87,32,143,102, -114,96,185,182,188,90,95,194,135,36,34,9,29,212,136,70,81,192,106,191,9, -102,222,139,156,62,184,82,146,12,16,23,254,76,208,2,172,146,155,182,18, -150,149,145,122,32,249,79,21,159,229,211,150,6,104,249,45,191,150,75,201, -14,56,104,93,133,61,152,99,2,0,52,7,147,192,121,173,6,194,13,42,88,155, -250,67,56,239,3,154,82,31,168,92,65,199,239,25,219,67,99,146,97,208,115, -255,89,105,165,144,20,233,11,121,150,239,74,197,56,87,149,128,229,205,192, -24,85,112,139,2,80,202,195,1,144,101,37,16,33,58,15,244,194,61,239,129, -226,111,210,162,33,125,69,116,112,46,159,254,118,76,107,249,250,14,5,178, -0,124,199,206,232,22,42,112,200,63,143,9,147,0,104,43,252,130,33,40,51, -74,232,145,121,229,203,204,143,69,0,146,120,84,182,247,168,13,170,228,60, -74,62,209,145,73,195,112,129,155,60,27,38,173,29,216,138,5,68,224,194,35, -0,12,50,2,96,129,193,47,12,57,24,2,104,51,7,144,116,41,203,45,3,154,97, -201,196,219,252,196,181,73,108,204,128,82,124,17,45,230,141,233,75,190, -210,79,68,173,80,155,27,183,107,96,58,69,167,130,79,172,214,64,6,236,134, -193,64,232,195,40,0,228,62,101,224,64,116,66,63,8,238,102,184,120,185,1, -129,43,109,128,64,11,224,218,96,42,166,104,154,152,67,84,89,158,198,184, -23,189,63,111,152,68,162,193,48,249,211,254,120,162,24,113,211,204,85,90, -204,133,117,153,163,216,106,191,34,129,163,1,240,3,237,108,218,82,212,129, -65,223,248,203,30,6,133,71,45,152,9,125,48,224,249,254,144,152,152,8,87, -26,27,193,227,241,220,3,130,168,165,21,165,197,136,138,94,90,124,219,151, -87,163,199,141,35,96,12,25,31,68,48,49,201,37,138,237,210,58,28,55,27,167, -174,75,70,48,145,82,81,206,102,226,164,4,128,55,106,94,197,136,119,167, -196,14,243,248,20,181,131,65,165,202,119,148,157,35,91,58,237,19,231,98, -54,156,241,92,114,50,88,111,218,64,148,60,247,148,92,18,5,90,58,38,121, -144,162,41,29,151,147,236,107,90,180,103,53,38,156,28,85,116,148,75,133, -243,243,136,66,58,170,127,177,114,253,220,135,250,28,15,1,64,28,163,126, -77,113,67,147,94,161,20,205,40,72,111,197,161,157,107,154,111,223,60,109, -183,219,87,15,31,49,2,4,73,4,151,219,125,143,35,234,15,161,134,241,50,253, -198,119,64,229,111,42,214,154,92,105,203,194,13,248,206,129,89,241,123, -240,121,234,164,173,111,21,232,0,20,86,143,79,146,24,28,33,0,20,253,185, -185,234,143,99,197,183,154,26,235,93,46,215,38,4,97,232,18,241,36,56,176, -44,7,21,170,161,32,66,126,114,213,110,159,80,181,187,143,62,188,109,94, -252,83,9,58,101,111,236,11,94,208,245,73,161,97,24,76,14,161,189,156,172, -163,244,91,26,46,122,177,229,30,41,184,93,249,169,47,166,197,69,98,137, -118,186,92,90,41,134,182,27,50,140,70,104,36,84,98,19,114,0,25,138,68,229, -41,56,182,145,131,233,135,124,168,182,220,175,111,230,185,120,254,100,137, -76,241,145,72,123,66,207,248,120,80,176,124,211,20,173,85,197,234,51,103, -64,112,53,127,119,237,114,237,69,125,115,114,0,15,177,164,108,57,125,196, -123,232,147,124,93,249,205,208,190,240,97,239,5,178,110,50,233,114,237, -217,227,152,252,110,55,55,187,83,123,37,36,2,139,189,2,41,76,213,85,85, -8,192,17,10,160,37,63,169,206,27,162,110,77,199,221,77,105,123,186,98,178, -240,22,249,255,179,226,224,55,141,87,46,157,20,4,97,203,200,81,163,32,60, -44,12,83,9,77,170,35,211,198,58,223,127,121,53,11,52,49,120,29,67,137,205, -204,90,184,147,166,153,78,152,35,156,187,10,243,72,214,179,180,231,94,240, -168,119,67,178,142,71,233,138,18,137,18,166,155,183,94,247,112,245,255, -6,208,210,125,235,202,57,221,204,238,246,94,78,31,251,239,111,1,6,0,48, -107,244,198,77,151,19,83,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_11 = 869; -static unsigned char xml_res_file_11[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,3,7,73,68,65,84,120,218,236,151,223,75,20,81,20,199,207,157,157, -31,251,83,77,122,176,151,232,7,130,73,245,188,161,137,17,26,5,82,244,22, -81,36,98,136,32,21,253,29,81,17,136,36,98,37,209,147,82,8,69,74,36,166, -228,115,5,9,210,22,61,7,169,59,174,59,59,59,247,118,206,29,119,221,93,117, -118,87,150,246,101,239,114,119,118,239,143,115,62,243,189,231,156,217,101, -66,8,168,102,83,160,202,173,6,80,3,168,58,0,243,152,211,39,94,190,178,228, -34,198,246,101,60,147,226,55,174,95,51,240,146,42,71,1,125,252,249,132, -213,218,218,10,182,237,64,58,205,129,115,81,86,167,61,180,151,108,144,45, -178,89,170,2,250,232,216,184,21,141,70,225,203,215,111,16,14,133,209,160, -3,249,74,236,165,136,200,187,115,69,241,129,185,97,194,233,83,39,97,105, -105,9,250,251,122,119,40,81,104,73,31,25,29,179,58,59,58,224,251,242,178, -28,104,111,59,3,235,235,235,176,182,22,135,100,50,9,137,205,77,79,217,131, -129,0,248,253,126,168,175,143,64,93,93,29,44,44,126,150,227,39,90,90,96, -110,126,30,6,250,251,242,32,114,1,244,225,145,167,86,119,119,23,172,172, -252,216,154,18,104,204,128,3,13,13,16,137,68,64,215,53,48,12,195,19,192, -178,44,72,165,108,136,199,227,240,119,117,21,161,173,172,173,230,230,227, -48,51,51,11,131,3,183,179,16,25,0,253,241,147,97,235,202,229,30,136,253, -252,85,16,72,180,85,184,178,150,250,220,192,163,162,227,146,175,2,141,143, -29,61,2,175,223,76,195,157,161,65,9,65,211,234,131,135,143,166,122,111, -221,236,177,237,116,246,28,119,59,94,81,78,106,177,189,103,53,77,133,241, -103,47,166,239,223,187,123,85,197,145,128,207,167,246,152,102,2,222,190, -123,47,23,8,193,161,210,79,73,169,8,83,228,157,92,186,120,1,200,39,249, -38,0,131,115,142,105,147,150,193,67,110,187,206,159,147,0,172,88,165,40, -169,24,184,202,17,192,236,135,143,210,28,249,34,159,228,155,0,20,250,98, -227,32,5,24,71,199,220,225,48,247,105,1,211,72,169,132,127,233,172,243, -108,59,6,177,14,10,130,216,219,0,10,1,64,70,1,85,85,229,6,51,177,1,145, -112,8,1,88,69,36,160,194,68,54,53,77,43,84,0,178,0,60,237,200,5,36,125, -10,83,39,16,8,238,187,4,239,86,146,201,166,134,55,72,54,201,87,1,0,82,98, -224,81,158,19,177,237,56,16,10,21,1,16,185,149,156,123,10,69,0,100,211, -48,52,169,40,249,34,159,249,10,224,32,41,64,45,22,139,121,58,151,249,45, -84,80,28,183,40,113,159,5,130,165,101,189,240,130,104,108,108,116,215,75, -128,130,35,16,130,242,211,53,216,212,116,168,72,158,51,116,238,207,27,227, -190,164,39,64,166,168,185,87,150,15,64,116,20,128,225,112,208,77,191,98, -71,47,92,5,124,220,5,118,20,82,0,55,177,226,0,164,172,12,118,177,125,4, -194,52,227,139,147,147,83,109,52,88,74,253,97,59,62,137,156,247,162,85, -90,66,36,18,27,139,238,173,0,68,176,31,198,126,48,163,200,127,104,84,243, -255,96,255,205,182,156,6,176,251,43,144,244,229,212,167,36,246,205,106, -255,36,196,176,169,253,53,171,1,84,185,253,19,96,0,249,4,138,17,171,4,193, -66,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_12 = 634; -static unsigned char xml_res_file_12[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,28,73,68,65,84,120,218,140,146,205,107,19,65,24,135,159,217,221,144, -108,194,162,104,244,80,177,181,136,32,130,7,169,90,240,82,197,34,86,91, -47,90,68,122,240,31,240,32,166,135,10,122,18,145,106,251,23,136,246,224, -65,76,27,15,106,81,36,82,5,123,144,106,148,94,10,173,45,181,133,32,10,37, -181,77,52,217,143,113,38,9,82,37,196,188,48,187,204,204,251,252,222,175, -17,119,239,141,224,251,1,134,33,80,38,195,225,48,245,172,88,44,234,159, -8,2,137,105,26,88,122,23,4,129,22,145,61,221,167,89,252,178,84,87,96,87, -75,51,79,159,141,75,33,12,161,5,12,13,151,92,87,158,233,233,86,240,178, -22,71,136,218,75,223,105,31,237,171,25,205,90,190,239,39,47,246,93,192, -245,60,246,238,217,77,67,166,196,52,243,48,57,154,180,60,207,235,93,93, -91,231,249,139,151,213,91,249,63,186,252,237,58,121,2,205,234,12,40,150, -138,216,81,155,206,99,71,21,47,171,62,226,31,76,84,191,130,244,196,107, -93,2,129,95,41,1,183,228,18,181,35,120,234,112,42,243,241,79,189,149,108, -53,98,98,138,48,66,134,56,220,214,198,166,216,118,112,67,200,64,160,74, -240,209,34,145,136,77,110,109,149,120,124,107,85,160,18,87,245,154,144, -112,72,103,175,146,89,121,194,253,113,117,106,64,71,248,60,120,93,149,12, -116,55,99,177,40,179,179,159,55,192,58,186,158,115,148,169,31,215,200,57, -105,78,29,129,246,29,9,222,101,135,153,158,123,68,200,254,134,165,97,211, -178,112,28,167,188,254,110,182,138,142,195,131,76,154,227,205,176,94,128, -253,91,134,120,53,55,204,62,181,127,155,155,192,202,231,243,111,82,169, -199,29,82,202,26,253,86,181,7,14,102,11,28,106,234,231,96,211,157,242,249, -229,118,201,135,236,0,147,159,6,203,157,210,195,223,92,111,112,125,35,188, -63,208,10,5,23,174,119,74,110,164,5,209,16,76,47,128,117,243,214,237,249, -90,209,193,80,209,109,102,90,47,81,248,202,216,124,152,115,59,227,48,185, -56,128,165,220,23,178,240,115,133,148,85,247,205,72,83,141,14,198,18,36, -122,135,16,249,95,156,157,89,30,212,15,177,12,143,246,115,69,208,184,169, -182,177,109,195,254,187,90,75,162,118,250,141,219,111,1,6,0,80,239,219, -105,146,138,192,9,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_13 = 632; -static unsigned char xml_res_file_13[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,26,73,68,65,84,120,218,164,83,61,111,19,65,16,125,179,187,103,7,131, -81,8,4,10,155,68,20,72,161,224,67,73,68,75,19,104,41,40,144,16,162,129, -34,5,13,255,0,209,210,128,132,172,132,134,6,148,54,13,66,164,65,66,162, -76,224,226,2,100,36,7,35,36,155,96,130,125,150,239,156,203,221,46,179,119, -206,23,208,32,143,116,186,189,157,153,247,102,222,204,145,49,6,131,152, -192,128,166,202,243,51,139,58,10,175,26,29,39,23,36,36,72,170,50,145,56, -199,95,251,163,169,127,67,132,109,159,178,201,231,103,159,1,91,81,26,36, -37,86,158,220,56,203,32,134,232,15,0,78,34,33,32,84,230,19,19,157,73,0, -140,214,156,188,137,176,242,16,198,16,156,194,53,76,206,62,231,230,250, -201,22,100,27,200,190,148,130,91,186,53,33,73,76,241,253,178,74,28,166, -203,142,3,236,151,136,214,95,241,197,203,36,150,24,196,196,26,65,199,239, -151,110,144,41,92,231,120,131,142,31,94,204,31,204,90,0,118,197,62,132, -51,196,71,105,139,220,97,214,172,75,229,157,139,160,213,177,44,236,225, -137,209,125,8,169,144,115,156,18,235,246,32,5,160,77,75,135,160,29,32,233, -59,165,67,109,165,130,209,177,17,28,191,89,2,18,145,77,250,88,191,147,129, -59,119,251,152,178,101,34,242,240,249,173,139,238,47,111,87,47,214,99,124, -234,52,142,20,142,98,171,250,136,171,214,73,233,22,64,230,138,8,197,4,154, -237,112,73,89,102,191,190,198,202,2,211,247,22,184,157,184,175,150,68,252, -181,4,109,120,85,40,147,150,159,0,107,6,24,71,235,227,42,190,172,247,94, -40,158,55,58,245,26,14,23,121,42,221,42,116,115,137,67,69,10,34,179,124, -218,187,107,172,3,49,211,208,33,252,172,186,184,243,248,195,98,210,66,187, -241,13,197,233,75,220,74,29,148,205,115,170,216,29,225,62,99,0,103,4,126, -99,13,223,27,205,215,171,243,51,158,178,65,193,70,11,185,83,39,129,94,139, -7,49,140,191,54,112,175,101,135,177,177,252,30,181,31,189,133,19,163,76, -230,206,93,246,120,96,121,29,197,176,75,101,118,54,230,223,102,139,50,36, -218,147,119,223,140,149,159,94,241,108,228,133,68,177,255,51,187,247,110, -186,91,3,254,206,191,5,24,0,171,203,191,162,234,194,67,169,0,0,0,0,73,69, -78,68,174,66,96,130}; - -static size_t xml_res_size_14 = 685; -static unsigned char xml_res_file_14[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,79,73,68,65,84,120,218,100,83,61,108,82,81,20,254,30,63,15,144,194, -98,52,154,70,156,28,108,73,140,198,166,49,52,142,226,166,198,196,132,142, -154,176,72,88,93,89,93,136,65,106,28,180,12,38,52,150,69,55,113,174,49, -93,52,8,117,176,46,98,26,45,196,193,247,158,240,248,125,158,239,218,71, -16,110,114,184,156,243,125,231,231,158,115,158,134,153,83,40,20,54,70,163, -209,93,199,113,130,174,77,211,52,219,235,245,110,102,179,217,251,211,92, -225,64,115,149,98,177,120,173,223,239,87,19,107,107,136,199,227,56,22,10, -77,136,157,110,23,141,70,3,239,118,118,160,235,122,50,147,201,188,253,47, -0,157,37,75,53,181,190,14,201,132,111,205,38,186,93,27,154,199,3,103,60, -70,40,20,196,217,88,12,82,25,182,202,101,58,170,32,12,224,97,0,102,78,165, -82,176,237,30,190,236,127,21,226,24,225,112,24,229,242,150,186,169,211, -78,156,60,242,221,234,60,124,115,34,145,128,215,167,227,176,221,150,108, -33,44,44,132,241,236,249,38,86,46,175,168,155,58,237,196,201,35,159,126, -42,192,112,56,188,183,180,188,140,118,171,141,160,174,99,65,50,110,60,121, -138,171,210,139,131,131,239,234,166,78,59,113,242,200,167,159,10,32,18, -32,56,26,15,17,12,6,241,168,240,24,215,147,73,116,165,220,197,197,51,234, -166,78,59,113,242,200,167,31,127,124,238,91,216,60,202,169,147,39,240,166, -90,157,157,174,178,187,156,233,51,9,224,247,251,21,152,78,167,17,8,4,224, -241,112,64,20,7,99,105,162,221,235,73,19,109,197,155,13,208,55,76,83,103, -121,124,207,203,237,10,76,211,152,171,32,18,137,226,246,173,155,240,249, -124,16,190,26,158,10,96,154,230,171,207,123,123,119,46,92,188,4,91,22,198, -248,109,226,199,225,207,185,0,167,199,242,76,201,206,105,212,62,126,0,253, -92,44,150,207,231,157,86,171,237,116,58,93,199,178,254,56,178,68,142,204, -124,34,212,45,203,82,56,121,228,211,207,93,164,102,189,94,207,84,42,219, -176,44,19,126,221,175,54,110,48,24,76,132,186,95,70,72,156,60,242,233,55, -105,98,169,84,122,193,187,215,235,21,87,87,175,96,105,233,188,188,57,242, -111,215,53,141,229,162,86,251,132,221,221,247,202,217,229,227,168,205,238, -137,138,156,203,229,114,15,162,209,232,13,249,175,79,97,125,195,48,94,11, -246,80,254,239,139,24,115,95,227,212,137,137,28,63,90,50,247,72,11,241, -203,45,123,250,115,254,43,192,0,120,74,65,201,19,184,212,222,0,0,0,0,73, -69,78,68,174,66,96,130}; - -static size_t xml_res_size_15 = 1507; -static unsigned char xml_res_file_15[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,5,133,73,68,65,84,120,218,164,87,91,104,28,101,20,62,51,187,155, -236,230,158,77,210,52,218,180,138,109,76,177,105,161,96,125,17,159,4,81, -4,193,7,171,40,98,193,82,237,139,216,168,120,125,200,67,40,105,107,131, -68,107,193,104,180,10,26,168,20,193,90,16,108,169,109,173,13,84,107,45, -33,109,18,91,55,27,211,53,183,221,77,246,58,55,207,247,207,76,50,89,102, -147,221,56,112,216,221,249,207,249,206,247,159,219,255,175,100,24,6,229, -62,146,36,145,203,35,189,127,244,216,3,165,126,255,235,146,236,121,148, -117,2,146,44,145,71,146,73,51,116,50,116,131,24,43,101,232,218,169,76,58, -125,176,253,165,231,47,177,141,225,6,228,244,41,21,66,96,111,251,91,53, -247,181,109,63,87,81,89,177,101,199,214,86,90,215,212,72,21,229,1,177,118, -184,183,159,246,189,184,83,124,159,79,164,40,60,17,161,129,171,67,52,63, -55,127,45,22,155,121,242,237,87,246,140,228,18,89,226,19,63,114,197,201, -165,227,96,207,198,15,191,56,110,92,25,188,110,184,61,29,221,189,174,239, -161,15,187,247,246,119,111,2,78,46,1,91,188,180,252,83,18,92,179,118,248, -161,29,219,168,173,117,35,233,186,198,98,26,202,178,76,30,143,135,210,169, -148,80,212,52,172,233,34,122,50,167,102,219,230,22,146,57,61,103,7,140, -27,188,236,103,201,184,57,144,151,113,238,233,250,168,175,179,101,195,157, -236,252,30,82,21,133,20,69,93,112,100,176,224,73,167,77,92,252,198,123, -172,67,15,250,176,131,253,161,163,199,142,2,175,88,2,126,191,191,172,125, -75,203,221,12,166,145,170,233,98,247,16,100,84,146,76,211,76,38,99,213, -141,44,34,109,235,64,31,68,182,114,228,124,190,210,23,120,49,80,12,1,249, -221,206,195,79,4,252,165,84,89,81,70,170,234,216,57,87,60,50,122,241,247, -63,169,251,211,126,186,183,117,19,29,249,242,4,253,122,229,154,72,52,214, -237,72,168,170,70,85,149,101,116,71,99,29,189,217,113,224,241,220,90,192, -147,175,6,60,89,69,169,107,8,86,17,183,156,233,220,42,78,228,216,195,180, -135,111,142,209,238,167,30,35,188,70,206,63,248,252,56,221,223,182,121, -161,70,236,98,67,157,0,167,58,88,255,44,191,58,145,91,11,249,8,120,171, -107,131,143,84,85,148,51,101,137,52,46,62,195,65,0,223,51,156,251,88,60, -206,107,58,121,217,137,146,85,68,183,153,17,176,116,17,74,214,175,175,173, -166,146,82,255,195,252,179,180,80,2,62,159,215,183,189,154,195,39,138,139, -35,96,56,102,4,156,128,64,34,153,100,2,220,74,28,146,108,54,43,66,111,138, -163,149,217,182,134,211,104,152,157,80,82,104,10,124,178,215,215,212,24, -172,225,208,235,166,115,199,124,16,17,200,100,41,197,131,71,51,108,2,138, -217,219,86,10,36,147,45,218,131,68,221,154,246,114,193,53,32,1,216,231, -21,253,238,156,94,72,9,162,128,29,39,82,73,107,38,72,156,130,172,136,185, -196,250,50,153,4,160,43,51,57,172,75,134,235,84,206,59,138,215,236,239, -249,44,18,137,76,81,137,223,79,229,1,63,5,202,203,24,204,35,114,106,14, -33,123,51,38,33,56,84,181,197,90,65,42,146,201,148,72,149,194,51,161,161, -190,150,218,247,60,215,200,75,255,58,125,230,157,132,94,175,143,246,237, -222,73,149,85,85,86,251,229,18,181,59,106,177,224,12,59,83,18,45,137,64, -60,22,167,254,31,206,186,251,201,71,0,173,151,97,230,82,34,41,118,108,228, -9,225,114,15,34,3,242,89,85,17,159,69,17,128,67,49,86,185,216,188,37,190, -85,19,80,185,56,53,71,106,10,39,192,165,43,177,13,162,32,123,61,171,38, -192,3,141,69,37,210,221,237,243,141,98,35,149,74,93,191,61,61,43,170,29, -206,23,123,188,112,129,29,236,103,227,115,148,100,60,183,11,74,62,2,90, -54,155,30,139,70,19,230,208,201,20,79,194,158,21,152,35,192,1,30,112,11, -37,160,78,69,38,206,128,57,170,153,163,177,170,8,192,14,246,192,1,30,112, -11,37,144,253,233,212,119,39,39,103,162,100,48,130,162,42,34,151,246,73, -183,242,238,117,161,15,59,216,3,7,120,192,45,152,192,173,191,134,167,230, -19,233,76,44,54,47,58,154,239,120,124,38,232,43,166,66,172,179,94,98,62, -33,128,96,15,28,224,21,67,0,77,155,137,206,76,158,28,143,76,139,218,193, -113,28,103,18,56,227,209,33,112,146,43,120,143,117,232,225,148,68,201,193, -30,56,214,41,168,23,115,35,202,12,92,56,243,73,104,124,82,40,73,214,92, -136,207,205,81,42,157,182,28,88,103,63,214,144,115,126,143,117,232,65,159, -143,0,130,61,112,86,115,39,76,95,60,119,122,48,26,139,142,142,132,38,112, -176,91,163,214,88,112,52,203,247,129,40,11,62,109,98,226,68,132,38,235, -143,132,254,33,216,3,7,120,197,18,64,197,206,253,248,253,183,175,14,141, -134,173,203,167,177,144,231,124,162,91,161,215,56,21,67,163,227,4,123,224, -184,117,192,74,4,176,225,196,111,3,23,174,134,67,55,191,186,244,199,13, -51,180,142,123,159,91,245,99,29,55,168,243,151,7,9,118,176,7,78,190,127, -73,242,10,211,20,247,172,153,222,158,174,174,112,56,252,243,47,151,135, -204,123,30,31,78,246,17,108,159,132,230,93,209,60,180,160,7,125,216,193, -222,194,41,234,62,176,228,114,194,82,205,178,126,215,203,175,189,209,188, -254,174,103,54,52,55,210,186,181,245,84,230,47,17,249,6,149,100,58,75,225, -219,83,244,247,88,132,198,66,183,190,238,251,248,208,1,182,9,161,19,115, -39,96,209,255,13,173,67,171,138,165,169,54,88,223,252,244,174,189,239,212, -212,212,61,40,138,109,225,252,151,120,228,78,159,255,166,239,72,231,236, -204,20,198,46,87,46,197,221,114,191,26,2,118,36,240,231,162,134,165,193, -34,228,205,41,90,56,156,100,137,98,130,187,205,254,255,67,192,25,141,128, -117,197,150,115,135,151,229,88,93,14,192,233,243,63,1,6,0,218,58,168,206, -121,36,62,30,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_16 = 1971; -static unsigned char xml_res_file_16[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,7,85,73,68,65,84,120,218,156,87,123,76,149,231,25,255,125,215,115, -225,28,64,4,228,182,34,76,81,196,203,172,174,42,118,118,217,186,46,198, -75,170,105,154,213,206,118,107,27,99,155,45,157,201,178,196,54,248,135, -108,251,103,174,29,75,237,76,219,117,235,26,187,49,131,98,129,182,75,183, -214,86,165,245,194,102,13,181,5,122,40,194,17,116,28,176,128,192,185,125, -223,183,231,249,46,120,14,112,16,247,145,31,129,247,253,158,247,249,61, -247,247,19,48,203,103,245,238,154,116,247,220,226,39,116,81,122,84,135, -184,220,48,0,131,126,248,17,248,71,0,68,232,23,69,93,123,45,60,112,249, -149,243,135,158,30,158,205,185,194,173,246,215,237,249,83,169,232,203,174, -119,169,234,210,205,171,138,176,186,52,7,107,22,100,67,149,146,69,163,154, -129,51,95,132,112,46,208,143,166,127,7,17,137,70,91,245,27,161,251,63,122, -254,199,157,128,205,244,54,9,72,119,87,189,249,162,162,170,187,126,182, -169,2,91,87,22,65,163,197,174,235,26,122,71,52,140,68,245,164,151,253,170, -136,2,191,132,249,115,36,72,244,255,241,150,32,106,222,254,20,177,104,244, -165,83,213,91,159,162,37,237,118,8,40,149,251,154,46,175,89,144,155,95, -253,131,85,68,95,192,133,171,97,116,14,198,77,87,11,211,8,26,14,232,87, -105,150,130,111,228,187,160,107,58,246,213,182,224,124,160,191,239,244, -254,77,197,180,29,155,13,1,101,109,85,67,215,147,247,85,20,236,188,187, -4,29,131,26,254,211,23,6,157,5,145,149,11,169,89,59,4,116,130,36,2,43,243, -221,88,144,37,225,213,19,29,120,245,189,246,222,143,170,55,207,159,76,66, -158,106,121,99,247,174,123,151,228,61,68,202,155,123,162,232,30,138,129, -195,173,72,183,78,24,199,36,135,72,75,111,24,253,163,10,118,222,179,144, -188,97,20,136,66,99,247,233,253,155,239,72,36,33,37,198,188,114,111,221, -161,187,22,21,110,216,179,165,2,231,130,81,92,25,137,67,38,237,18,153,46, -10,156,233,22,68,81,36,88,153,47,36,172,79,236,155,239,88,24,142,232,184, -17,53,176,113,69,46,46,94,254,202,167,86,108,44,232,57,249,247,38,39,49, -29,2,194,138,157,213,139,50,10,74,254,88,243,216,122,74,50,157,226,29,131, -76,110,148,28,183,219,144,104,65,165,13,153,124,108,133,195,176,114,66, -152,10,209,6,147,112,209,251,247,86,228,161,190,229,202,157,25,69,139,254, -118,237,226,251,3,172,88,116,92,159,86,188,188,110,215,119,151,144,164, -136,246,129,40,41,191,105,185,3,137,44,87,101,9,245,31,180,226,153,63,52, -193,163,42,20,26,217,92,79,124,47,89,70,48,207,106,163,51,21,122,255,209, -111,151,193,87,188,162,142,117,78,16,40,90,187,53,219,227,113,151,111,164, -58,255,226,122,204,180,136,99,206,137,148,8,210,109,90,223,210,22,196,129, -199,215,225,231,47,52,192,235,146,104,77,48,247,38,191,239,192,201,159, -0,121,117,243,234,249,80,20,165,156,117,58,4,164,194,202,7,30,251,206,178, -66,68,168,82,7,198,226,166,219,197,20,144,236,82,24,167,184,86,255,112, -13,246,252,158,73,200,212,152,68,83,89,74,57,66,136,206,22,232,143,202, -242,60,20,145,78,88,252,72,214,237,223,113,103,105,46,41,215,233,197,169, -174,79,114,41,39,26,9,69,168,243,237,107,108,67,213,142,187,240,116,77, -3,60,46,133,14,74,29,14,62,147,101,89,199,202,146,28,72,30,255,14,214,205, -4,220,134,172,150,175,40,201,54,147,69,100,43,110,1,139,0,117,63,143,138, -154,247,187,176,247,161,181,248,233,243,111,194,227,182,194,33,73,41,100, -37,43,33,151,21,103,193,144,92,229,172,155,9,200,6,21,173,199,37,32,70, -29,68,18,82,91,239,128,159,24,21,81,26,17,240,121,93,120,165,57,136,170, -71,214,227,201,3,199,77,79,40,196,32,149,247,98,212,208,56,121,89,39,235, -22,97,85,146,217,189,132,25,98,159,8,126,194,26,149,163,170,130,134,20, -89,174,226,216,197,126,252,226,225,111,97,215,111,234,205,68,181,194,56, -73,214,44,120,3,126,159,236,76,39,65,78,236,163,188,200,117,158,170,227, -113,99,145,205,41,104,152,150,184,20,213,60,152,141,81,40,213,227,134,37, -233,148,158,110,76,109,213,146,33,36,205,70,57,113,83,38,23,104,130,145, -154,64,130,7,162,134,8,23,185,91,176,101,215,150,100,226,185,55,62,196, -95,246,110,163,10,137,155,171,162,48,149,128,64,139,253,67,209,9,29,38, -1,110,159,163,17,182,72,52,243,32,53,1,203,173,124,146,70,14,85,21,197, -148,93,146,151,134,131,181,39,240,250,51,219,17,166,49,205,30,113,114,101, -50,1,55,233,24,141,68,38,246,69,203,159,227,29,29,125,67,180,41,220,178, -2,36,187,119,198,13,217,140,127,113,118,26,94,175,59,129,55,170,182,211, -165,68,131,78,212,4,242,98,42,89,15,233,248,164,147,186,48,233,100,221, -124,92,60,28,234,110,56,219,214,11,159,34,204,162,10,44,2,154,40,99,94, -166,23,117,245,39,240,215,125,219,233,6,100,64,215,173,235,89,74,89,98, -145,70,13,248,92,123,31,198,67,151,27,88,55,19,8,7,254,241,242,225,230, -182,171,228,82,80,87,155,217,11,236,51,141,124,28,19,41,243,143,253,19, -71,246,147,242,184,62,163,229,14,124,42,119,80,141,166,226,0,2,239,188, -124,152,117,243,145,209,225,158,207,174,133,66,3,157,255,186,208,135,12, -234,237,220,205,36,187,110,147,192,217,65,86,110,88,118,7,142,29,105,194, -209,106,182,156,252,200,151,21,8,211,203,216,144,233,204,12,106,59,71,78, -118,64,143,142,117,14,145,78,214,45,57,213,161,141,13,93,26,76,95,188,227, -251,171,74,204,18,138,115,50,78,26,175,206,179,102,73,1,54,173,91,72,146, -84,53,186,117,55,156,110,28,39,194,71,134,69,40,65,15,28,61,143,206,183, -14,62,114,163,47,16,32,177,113,231,62,160,211,194,152,191,172,178,228,171, -152,186,248,158,101,243,204,154,214,141,233,73,240,58,223,7,38,174,229, -51,41,55,19,79,196,156,52,1,207,254,185,25,215,122,2,199,219,142,255,238, -53,18,187,206,169,52,65,128,255,233,61,219,120,33,190,240,190,7,243,231, -102,122,203,10,253,20,107,209,44,169,41,183,30,187,80,173,239,129,25,64, -158,116,211,156,206,240,10,120,177,241,18,90,62,15,14,124,124,224,225,31, -145,104,31,199,127,242,149,140,175,205,122,240,100,237,219,61,89,235,239, -47,204,201,244,46,46,242,155,106,204,54,61,11,55,39,221,156,72,185,135, -102,93,186,23,56,216,208,138,119,207,118,132,154,127,189,109,11,29,211, -67,24,182,141,78,34,192,254,140,242,156,185,114,170,246,157,96,214,250, -109,253,195,113,207,55,23,205,35,43,18,239,131,184,121,239,155,110,228, -82,104,92,212,174,211,168,154,198,194,26,126,121,248,28,206,180,118,15, -146,242,173,252,89,65,24,228,242,155,238,82,234,132,34,194,68,130,167,106, -155,198,178,151,231,159,234,24,41,203,76,247,160,226,107,62,107,204,38, -213,181,5,201,158,17,76,212,227,50,231,13,142,53,119,226,183,71,91,208, -213,254,121,211,153,231,118,238,182,149,135,38,95,203,83,126,152,16,230, -16,242,114,151,110,88,90,186,233,39,191,202,205,205,153,191,174,60,31,149, -84,1,165,121,126,202,234,155,51,133,15,225,86,254,201,151,131,248,248,82, -47,78,127,214,139,241,145,161,174,64,211,11,207,254,183,245,195,86,218, -190,106,39,93,236,182,62,205,8,20,65,204,37,228,120,231,22,206,251,250, -198,221,91,188,249,101,223,19,221,190,18,221,48,166,204,9,35,114,227,203, -209,190,246,119,3,111,29,106,24,27,184,194,117,222,79,224,219,239,216,237, -126,154,37,238,43,54,145,52,66,58,33,131,224,73,184,81,39,134,111,156,48, -100,39,217,168,173,56,246,255,126,156,78,231,17,149,7,154,61,69,167,251, -60,140,219,229,21,77,101,241,228,231,127,2,12,0,35,187,154,106,194,98,206, -112,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_17 = 2315; -static unsigned char xml_res_file_17[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,8,173,73,68,65,84,120,218,172,87,11,80,84,231,21,62,123,239,238, -178,32,225,189,8,136,32,136,202,242,168,10,212,166,81,177,106,173,113,212, -234,198,71,104,199,65,109,106,58,153,105,19,141,161,42,248,76,192,33,22, -147,49,38,169,157,56,101,242,176,81,81,48,157,198,180,77,194,99,81,164, -160,147,162,242,94,65,129,125,47,187,236,238,221,247,171,231,191,185,155, -172,136,200,180,189,51,103,118,247,222,255,254,223,119,94,223,249,151,7, -83,188,182,109,223,17,153,152,144,120,66,36,18,21,39,36,36,136,146,103, -36,193,180,105,211,128,166,105,144,223,187,7,61,61,189,178,147,127,120, -115,37,46,245,29,125,189,98,47,69,81,187,189,94,111,146,88,44,6,141,70, -3,60,30,62,240,122,107,237,14,199,1,92,215,143,235,252,100,95,222,20,176, -233,3,101,135,254,40,16,8,118,73,55,110,128,249,185,57,192,163,40,80,40, -149,208,218,250,47,252,84,65,95,95,95,227,123,167,79,237,192,181,134,242, -227,111,246,37,37,36,38,44,91,190,20,196,113,113,224,247,251,17,156,7,78, -167,19,250,251,239,193,215,245,13,160,80,12,103,158,121,255,189,62,66,130, -255,36,240,125,7,202,106,242,243,242,16,123,61,11,108,101,172,80,223,216, -4,178,230,102,232,234,236,172,100,24,203,112,179,172,169,5,215,186,223, -168,168,236,155,55,119,110,66,97,225,18,232,184,125,23,174,95,111,5,140, -4,107,241,211,227,33,55,59,11,146,147,147,224,131,179,127,238,193,245,34, -52,231,100,4,232,253,165,7,107,242,11,242,164,155,164,27,97,116,212,0,6, -163,17,26,16,188,183,183,87,255,86,213,137,45,184,70,135,102,70,99,246, -150,236,127,126,70,98,18,130,47,70,130,50,240,122,60,128,81,3,179,217,76, -60,134,174,238,46,104,168,175,103,131,78,211,20,217,63,108,50,2,36,236, -232,121,62,130,111,128,7,67,35,96,181,89,161,169,73,6,114,185,92,129,224, -91,113,205,16,9,57,154,11,77,24,17,17,113,148,132,189,227,118,39,11,78, -81,52,91,31,38,147,9,94,63,122,100,13,137,80,208,254,198,192,23,106,98, -240,195,53,63,44,40,144,110,122,110,3,220,127,48,132,155,140,1,133,121, -140,141,141,1,198,98,249,134,3,215,160,217,208,60,104,33,152,235,233,241, -113,98,80,171,213,108,206,41,138,7,124,62,159,45,62,188,6,209,238,4,25, -249,109,37,15,198,71,128,127,240,240,177,218,252,188,133,235,73,206,7,6, -239,99,8,25,112,185,156,224,241,122,97,235,230,77,64,83,212,186,136,200, -72,168,58,81,41,13,122,79,64,138,205,108,177,0,65,36,4,136,247,66,161,32, -216,99,237,68,161,30,31,129,80,30,143,226,192,7,17,220,132,213,235,0,167, -195,9,122,253,40,22,222,117,216,244,156,148,108,190,142,172,13,126,145, -16,224,211,124,182,173,190,5,231,179,53,240,164,70,163,198,21,93,117,126, -222,2,80,170,212,48,54,102,6,187,195,5,14,135,3,236,132,4,182,145,70,171, -131,175,234,27,89,48,174,138,191,187,188,30,151,106,112,112,0,226,177,239, -5,2,62,146,64,227,211,224,247,249,38,37,64,232,241,203,143,87,94,17,139, -227,215,166,166,204,132,140,217,233,108,222,195,195,195,17,216,9,46,52, -7,18,33,105,64,97,129,129,129,65,192,100,131,82,161,168,59,116,168,140, -116,130,23,45,118,247,158,189,117,69,69,69,75,163,163,163,161,95,46,103, -243,47,10,9,1,53,138,80,123,123,59,219,138,44,32,91,31,20,84,30,47,15,33, -5,204,231,194,190,246,197,95,239,100,23,212,55,52,193,32,134,159,20,79, -234,172,52,4,118,129,199,237,98,159,13,13,13,131,72,36,100,211,48,102,208, -73,159,162,125,231,119,151,30,218,246,70,233,129,51,171,214,174,95,58,111, -110,6,252,27,251,159,68,8,21,147,37,145,158,158,14,89,18,9,251,91,32,160, -65,165,84,195,229,186,186,1,174,13,89,2,66,139,197,212,84,115,169,118,153, -4,23,134,134,138,216,192,88,44,12,246,123,31,232,116,26,246,55,217,52,50, -34,2,22,204,159,15,183,218,219,32,43,39,27,62,14,95,182,57,230,200,231, -82,207,28,160,243,127,144,5,109,29,157,96,183,219,208,236,172,247,49,81, -81,236,123,108,129,162,30,116,247,244,64,119,119,55,234,193,215,123,131, -83,240,20,90,218,222,146,125,167,51,231,73,10,103,207,73,7,55,122,45,151, -15,64,111,79,119,125,91,91,235,37,1,95,192,195,40,248,211,82,102,110,217, -184,97,195,242,168,184,233,240,234,55,110,216,179,118,37,180,169,24,104, -31,82,65,138,91,5,175,102,248,96,72,163,135,230,235,45,138,200,200,200, -24,172,148,208,105,97,97,232,140,133,5,195,162,110,249,224,79,103,246,225, -215,7,92,27,187,120,92,43,70,161,165,32,137,183,103,207,206,40,76,78,78, -134,142,142,14,56,84,182,255,105,188,175,231,68,132,148,116,204,214,205, -155,143,245,46,218,181,230,183,207,46,131,187,58,59,168,25,7,184,253,20, -220,188,55,8,235,104,57,248,238,54,106,207,156,61,251,75,174,54,40,28,92, -225,168,13,86,78,47,76,28,112,64,192,252,52,153,94,68,18,201,141,27,45, -215,91,37,89,57,185,24,174,153,140,197,212,114,237,90,115,53,222,87,5,228, -54,116,69,113,140,117,197,75,85,37,107,22,195,109,173,29,84,22,59,184,125, -126,240,160,69,132,71,129,108,216,0,141,111,151,252,12,215,222,71,83,18, -242,12,195,40,57,13,208,112,210,109,10,86,197,224,38,37,100,162,209,146, -208,34,56,241,32,138,71,226,199,139,121,233,221,217,233,217,121,253,21, -235,127,12,87,229,70,80,90,28,44,176,27,253,116,251,121,160,192,57,17,230, -53,193,38,253,151,159,237,59,124,164,8,223,113,4,97,248,31,59,112,130,181, -132,11,11,195,129,147,48,217,201,253,152,223,188,147,134,224,242,242,245, -207,176,224,42,198,142,224,192,130,123,16,92,137,224,94,253,0,124,181,45, -27,36,146,121,153,179,226,197,153,127,175,111,168,157,12,120,162,8,76,40, -84,177,251,206,23,47,202,156,91,253,242,242,133,240,197,56,112,47,130,171, -113,78,120,12,15,224,84,158,0,104,158,15,126,148,191,0,118,254,181,15,218, -245,62,48,153,205,87,116,199,214,109,225,242,15,83,145,226,135,158,197, -148,156,219,190,124,126,78,117,217,179,11,225,106,191,129,205,121,48,184, -206,108,132,97,173,18,36,183,170,255,105,208,169,65,128,2,179,241,195,118, -24,163,34,224,47,219,151,194,178,121,105,27,227,14,214,93,28,23,233,199, -166,224,33,240,232,215,206,21,175,88,56,191,122,247,138,108,184,112,215, -192,86,187,215,255,61,184,222,108,0,165,122,4,140,31,150,21,221,110,254, -242,106,152,80,48,235,111,130,236,52,65,124,26,252,126,85,14,252,67,110, -129,95,44,72,6,181,213,43,209,73,86,229,218,100,23,46,77,148,146,137,82, -192,143,46,171,187,248,98,97,129,116,109,110,50,92,236,28,69,112,231,4, -224,195,96,188,80,249,188,237,78,211,77,174,224,18,231,190,115,227,230, -39,59,158,134,183,26,181,96,69,45,153,21,21,6,91,179,99,224,84,67,39,52, -118,245,215,233,203,165,1,233,126,108,4,232,232,210,218,154,61,171,23,75, -127,154,153,8,23,187,70,65,243,56,240,79,43,182,216,238,54,183,225,59,234, -64,167,240,114,86,20,92,233,181,166,122,169,112,32,135,30,135,219,3,35, -22,15,252,106,81,42,104,48,18,218,9,34,65,63,228,121,105,237,37,2,94,152, -17,15,53,232,185,198,58,49,184,179,171,165,194,84,255,201,231,28,184,147, -211,18,191,173,165,246,70,104,238,146,108,15,95,152,26,34,138,100,227,107, -119,77,78,34,64,128,22,151,213,158,221,245,147,69,69,43,209,243,71,193, -177,47,25,11,40,84,15,192,217,121,237,184,254,211,242,143,56,129,114,4, -121,67,72,184,153,27,159,181,134,228,44,145,184,105,97,170,48,244,201,36, -2,4,166,197,174,121,225,98,233,234,5,88,112,193,224,126,214,115,6,15,36, -35,202,1,112,220,145,85,232,207,31,255,152,3,183,143,43,170,239,20,117, -50,18,47,32,9,173,205,39,209,103,175,206,179,54,157,175,9,180,161,104,142, -56,10,31,224,206,152,243,111,91,237,123,240,251,35,253,224,54,168,101,8, -126,142,147,88,43,7,56,254,242,6,20,84,117,114,231,30,70,209,35,211,106, -135,193,138,194,107,69,37,24,54,57,224,114,183,17,74,86,101,225,31,2,1, -123,170,10,16,160,212,22,27,80,56,150,8,56,177,96,112,207,168,74,166,170, -218,254,10,151,243,199,129,79,74,194,134,36,108,72,66,201,184,224,149,218, -91,192,99,140,77,100,192,5,82,16,198,43,248,249,150,172,153,113,81,26,59, -31,156,184,133,25,143,225,67,138,123,168,114,170,102,213,201,29,123,112, -205,48,55,148,188,83,248,55,229,127,36,29,252,144,84,81,88,52,178,26,130, -17,121,167,76,83,85,252,50,62,31,13,232,0,38,10,50,18,202,46,215,242,68, -97,41,120,162,102,143,78,94,237,240,23,170,83,187,14,114,67,201,56,69,112, -152,96,192,165,36,190,246,209,105,161,56,249,25,151,110,164,69,85,85,252, -59,110,207,177,0,1,50,235,99,209,102,112,147,144,226,70,166,145,43,184, -177,201,244,124,138,36,2,83,214,204,213,17,235,80,176,18,10,184,115,154, -144,83,72,31,215,102,246,255,194,243,71,212,149,59,198,11,56,199,236,255, -131,67,255,223,235,63,2,12,0,116,106,129,252,126,87,16,179,0,0,0,0,73,69, -78,68,174,66,96,130}; - -static size_t xml_res_size_18 = 2051; -static unsigned char xml_res_file_18[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,7,165,73,68,65,84,120,218,156,87,125,108,85,103,25,255,189,231,227, -158,123,123,251,129,165,45,216,58,235,112,165,104,132,208,144,97,34,211, -12,199,88,2,24,166,76,103,166,243,47,157,157,78,99,252,136,35,200,76,101, -113,97,14,51,201,22,182,37,115,38,186,153,45,51,196,101,76,145,5,134,5, -66,183,21,16,18,217,40,116,163,31,72,75,139,180,183,189,31,231,158,15,127, -207,123,206,45,183,176,10,235,73,159,158,243,190,247,61,239,243,123,127, -207,239,121,222,247,40,204,238,178,58,158,124,241,101,195,180,214,135,97, -120,221,47,41,165,16,248,222,95,127,249,253,187,239,98,211,211,125,179, -113,254,208,246,23,118,134,202,92,183,100,73,11,130,48,0,174,7,3,61,25, -202,192,241,227,61,80,161,255,234,175,126,120,207,151,75,32,62,236,85,181, -249,137,23,67,159,75,207,185,126,56,89,240,174,219,100,188,188,39,239,203, -60,122,53,179,0,144,12,124,31,110,209,199,190,99,189,248,16,17,96,8,128, -149,75,23,64,222,151,121,104,153,217,0,80,18,119,113,44,19,126,177,109, -65,212,27,78,253,155,241,218,123,236,61,248,65,200,176,133,83,225,183,102, -37,65,121,223,48,144,176,44,108,123,249,128,22,87,105,198,176,4,164,140, -26,121,10,232,120,121,235,13,116,142,105,191,89,211,84,109,81,213,193,181, -57,149,21,60,242,212,75,250,217,160,115,21,243,43,119,59,149,66,162,234, -35,116,24,160,148,33,97,137,25,21,70,253,229,138,22,219,252,187,231,119, -22,253,96,93,219,226,5,215,165,234,16,229,116,171,169,84,82,134,194,209, -35,39,81,147,78,162,117,225,141,240,253,203,32,228,146,182,23,78,239,19, -0,41,24,230,186,77,15,220,13,145,134,49,203,194,16,198,118,199,45,109,216, -242,219,63,226,123,95,91,133,162,23,148,209,173,176,231,200,41,4,94,120, -21,128,164,32,227,80,252,160,227,25,36,19,6,204,56,152,83,225,68,89,187, -44,132,83,109,78,46,145,43,250,33,182,109,188,79,139,97,235,75,157,154, -238,210,123,18,182,101,45,141,154,225,43,1,168,144,3,11,69,160,182,42,133, -191,140,180,33,149,80,112,28,19,182,99,83,104,10,137,132,5,155,168,18,52, -155,109,155,52,137,113,24,108,26,49,211,167,129,244,217,61,4,225,67,17, -141,101,88,8,149,196,59,90,156,138,181,229,249,87,3,128,12,43,184,30,210, -41,113,200,152,36,13,56,52,155,179,59,244,100,90,145,99,13,192,136,1,208, -177,101,134,176,57,151,101,68,43,76,37,109,20,10,30,29,152,88,126,211,39, -53,3,174,114,225,154,17,237,158,235,106,13,148,107,44,202,2,14,204,187, -62,233,183,161,108,19,166,99,192,146,123,194,100,91,0,208,76,3,6,65,24, -4,192,63,138,62,212,119,131,119,165,57,134,126,95,22,98,4,9,60,81,152,7, -145,192,183,43,70,176,246,201,109,116,234,99,103,123,59,139,16,62,128,1, -118,20,138,46,146,164,156,169,168,29,26,182,69,51,35,147,182,24,25,32,14, -173,17,185,147,100,88,2,68,138,139,167,144,36,3,121,2,8,248,251,200,33, -106,66,184,191,221,196,249,87,30,137,116,115,255,253,4,21,76,223,88,74, -50,202,83,4,78,34,193,85,27,218,169,178,204,8,12,159,45,75,194,97,68,33, -48,37,246,12,7,29,123,158,199,204,97,152,18,146,62,33,42,28,135,11,41,178, -218,229,177,249,214,33,29,111,183,152,65,215,238,65,2,8,96,20,178,188,251, -31,192,128,136,208,45,234,21,24,6,29,27,178,98,83,135,193,74,68,119,143, -78,71,93,32,199,52,26,203,121,90,84,97,145,241,38,136,128,171,206,231,129, -205,139,146,96,152,17,6,228,38,84,58,169,109,134,195,116,165,252,250,4, -102,144,41,92,85,136,52,162,60,197,227,48,134,6,185,213,113,167,89,100, -32,235,43,12,184,138,0,12,93,104,36,224,182,163,68,206,58,221,196,79,192, -127,62,199,85,166,230,224,244,249,127,226,52,30,196,67,127,235,67,57,219, -139,26,150,98,121,243,79,208,210,180,129,176,172,43,53,0,198,142,12,144, -75,17,154,69,6,24,89,12,23,200,140,178,160,36,44,4,35,236,136,152,66,229, -151,10,60,65,113,172,73,214,204,36,222,62,119,31,222,189,180,11,107,62, -255,85,44,110,254,49,69,89,161,199,229,220,44,78,156,61,128,87,187,239, -197,80,110,55,157,110,184,50,11,124,166,79,81,51,32,69,165,64,170,38,115, -76,78,198,94,113,181,161,172,158,78,124,10,19,92,169,222,47,152,227,236, -212,21,142,249,131,134,226,122,156,207,239,197,198,13,219,209,63,246,38, -254,209,179,9,67,19,147,122,250,121,149,105,124,102,254,157,216,116,215, -118,108,127,237,103,204,156,225,41,0,70,137,129,44,227,104,147,129,12,87, -61,144,241,144,41,42,76,80,217,25,207,64,198,143,173,24,183,99,155,96,60, -39,61,178,230,238,67,163,243,58,218,215,252,26,157,103,31,69,87,255,159, -112,49,55,137,29,235,67,109,242,220,213,255,60,14,244,61,138,7,214,60,12, -55,253,6,110,254,14,22,11,122,171,180,91,21,40,40,187,198,65,231,183,210, -48,74,149,61,20,170,179,151,171,125,88,218,197,227,237,151,33,177,140,20, -182,254,253,97,180,54,127,29,71,207,253,1,163,217,1,93,152,92,53,253,32, -34,125,242,219,177,115,207,97,237,178,123,241,194,165,103,59,248,83,167, -21,159,48,168,169,16,199,123,47,226,95,167,71,167,85,249,255,119,226,49, -24,2,75,85,227,112,239,97,220,122,115,27,246,191,255,14,43,29,163,196,232, -184,101,2,148,103,51,136,106,71,127,230,223,88,121,227,42,10,29,43,100, -35,20,0,225,196,196,248,193,163,93,135,86,132,165,189,122,106,35,138,78, -47,21,73,7,147,217,124,124,226,0,210,21,73,100,243,5,50,69,241,161,26,102, -10,24,206,119,235,154,255,155,213,87,35,222,241,165,203,125,15,190,174, -40,196,183,74,91,184,84,126,228,127,191,245,231,223,229,189,174,236,128, -162,62,119,219,186,214,213,95,249,230,182,156,175,156,101,75,23,162,247, -63,163,83,147,44,248,232,92,116,31,59,133,234,36,247,253,79,124,10,39,187, -129,9,183,79,211,124,173,75,88,144,177,49,0,173,129,28,173,143,54,92,118, -76,79,174,186,243,27,123,84,170,2,14,249,172,172,74,227,182,198,250,169, -115,224,133,76,22,78,202,129,71,13,156,236,233,213,125,151,242,231,185, -139,178,24,237,83,186,4,231,41,208,199,239,136,86,254,163,221,44,211,86, -180,131,202,152,177,252,32,226,83,156,94,177,156,205,51,177,149,174,90, -151,37,245,211,31,155,135,241,201,28,122,206,12,224,84,153,24,228,12,216, -80,55,7,213,233,52,222,57,209,143,133,13,43,48,122,241,32,230,215,71,43, -20,13,24,101,108,84,208,105,133,29,239,31,204,220,225,11,220,39,178,56, -34,1,157,233,80,106,121,172,116,77,245,53,104,110,170,199,232,216,164,174, -241,165,44,112,108,27,115,107,210,80,92,234,9,175,7,222,224,74,156,153, -56,136,198,6,6,213,142,138,164,83,54,25,247,56,72,9,17,231,178,115,158, -121,15,24,236,198,227,162,79,115,6,0,78,117,109,253,133,75,185,112,117, -37,227,188,248,166,38,44,108,110,68,243,252,90,90,29,170,28,11,167,201, -202,222,67,221,120,243,141,93,27,119,62,179,227,177,186,69,168,25,47,48, -27,155,232,200,138,118,204,253,125,29,232,28,232,0,183,24,13,76,72,57,252, -54,211,177,15,175,188,245,28,158,102,243,191,51,125,154,81,215,104,156, -219,208,216,178,230,158,246,95,84,206,153,187,34,58,45,71,20,72,8,38,198, -70,14,190,246,231,167,183,140,14,157,123,95,132,44,97,251,194,79,177,165, -238,6,172,109,109,97,245,155,23,1,209,167,32,6,121,104,8,120,183,135,206, -251,177,107,255,99,216,200,238,179,18,246,153,0,8,88,97,177,150,70,98,153, -107,211,191,33,68,55,227,177,112,47,198,109,249,212,106,106,185,29,183, -124,252,179,104,79,84,99,73,217,193,25,238,56,142,247,117,225,169,158,61, -56,192,158,65,218,24,116,97,191,198,135,104,204,134,115,197,129,89,82,190, -16,103,80,233,3,83,194,153,142,65,75,74,87,198,125,250,68,78,155,160,141, -196,128,39,227,190,89,125,29,95,227,27,24,118,12,58,81,54,191,112,225,198, -128,139,229,223,112,255,19,96,0,111,126,151,122,57,77,224,198,0,0,0,0,73, -69,78,68,174,66,96,130}; - -static size_t xml_res_size_19 = 2007; -static unsigned char xml_res_file_19[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,7,121,73,68,65,84,120,218,172,87,13,108,85,103,25,126,190,239,156, -115,127,90,74,41,163,180,182,118,115,117,64,21,232,214,176,117,70,22,163, -27,209,17,152,110,254,85,97,63,49,76,129,110,26,166,38,58,38,234,28,209, -204,13,19,204,36,203,100,66,54,49,25,3,231,72,97,108,83,144,159,110,176, -78,91,58,129,149,50,170,164,98,88,215,206,246,246,254,157,191,207,231,59, -247,220,114,239,150,74,169,158,244,237,119,207,189,231,156,231,125,159, -231,125,191,247,61,2,147,59,204,7,127,245,204,14,105,152,159,83,74,77,248, -38,33,4,124,207,125,254,71,247,180,124,145,167,110,240,221,100,192,127, -248,203,223,61,167,132,177,180,177,113,22,124,229,3,19,241,129,72,82,72, -116,119,247,66,40,175,237,39,223,90,118,91,222,137,75,61,202,214,61,246, -140,242,24,122,218,246,84,50,235,78,216,244,245,250,62,125,191,126,78,16, -205,36,28,136,249,158,7,219,241,176,191,235,12,46,65,1,74,0,124,234,154, -122,232,251,245,115,104,137,201,56,32,180,238,26,88,63,240,198,166,250, -220,183,106,236,223,184,199,190,174,62,120,190,162,108,106,76,126,115,82, -41,168,239,151,18,17,211,196,134,29,135,131,228,202,63,81,229,29,41,160, -70,127,242,9,220,60,167,142,224,40,250,205,44,202,106,147,89,237,95,156, -83,29,193,207,30,223,30,124,150,4,23,33,191,122,181,226,113,68,202,42,8, -232,35,95,33,42,207,140,80,185,239,11,51,90,219,186,141,219,158,115,60, -127,105,211,252,250,9,101,181,66,33,221,98,172,148,132,20,232,252,235,73, -148,151,198,48,103,246,149,240,188,11,78,232,195,37,184,11,85,148,55,218, -129,56,164,177,244,129,123,91,160,83,67,78,114,99,80,161,125,230,134,38, -60,244,139,167,209,250,229,69,112,92,63,160,91,137,128,42,188,212,245,22, -60,189,23,200,98,9,98,218,83,94,138,111,62,248,4,98,17,9,35,20,115,76,78, -20,156,23,72,56,118,78,14,180,114,142,167,176,225,254,111,4,201,240,240, -246,67,1,221,250,87,159,160,14,35,107,57,105,99,112,215,105,216,149,162, -200,1,161,120,97,214,1,166,151,197,177,243,157,38,196,35,2,209,168,1,43, -106,49,209,4,34,17,19,22,189,138,208,44,158,91,124,152,54,94,6,139,70,159, -137,41,81,250,143,151,233,132,7,65,111,76,105,50,242,156,222,158,65,240, -19,89,148,92,61,23,163,201,36,86,188,113,12,27,67,7,2,198,245,101,89,219, -69,105,92,3,82,147,152,68,60,78,139,10,148,240,115,52,112,40,52,43,52,237, -72,132,14,240,122,22,3,132,161,120,159,133,108,150,42,43,3,205,87,125,24, -215,210,154,174,170,67,109,170,15,123,171,123,145,30,73,33,53,154,194,112, -85,29,58,214,108,57,79,232,72,174,10,200,64,198,246,72,191,5,97,25,48,162, -18,166,94,35,6,207,41,137,73,51,36,36,65,37,181,228,31,147,94,5,171,228, -42,130,58,67,112,191,14,68,168,8,54,218,85,176,249,221,151,122,118,226, -218,230,102,148,79,159,138,205,79,109,193,205,114,17,50,233,12,34,118,86, -35,151,202,124,89,101,29,27,49,82,206,82,36,160,9,105,105,51,194,149,22, -201,173,134,118,44,112,206,12,156,212,38,233,160,144,6,98,100,64,7,226, -9,19,231,142,0,63,255,253,92,68,167,76,195,148,242,105,232,61,117,26,85, -21,51,240,236,200,31,80,221,223,131,235,55,173,250,88,193,62,160,144,97, -18,68,35,17,62,88,6,192,194,52,114,206,104,16,2,88,100,34,200,1,67,107, -207,124,96,216,174,235,178,114,40,71,36,39,102,60,26,69,146,91,116,146, -140,60,126,238,35,104,104,253,2,26,106,106,241,216,182,131,48,156,81,156, -60,126,130,82,1,91,230,6,109,96,128,150,52,115,10,48,9,109,39,136,64,50, -18,41,53,221,185,232,204,72,110,117,9,58,104,3,105,87,97,56,237,6,137,166, -28,234,77,39,124,210,158,201,10,220,223,80,130,17,219,192,138,129,251,208, -216,122,7,80,253,53,224,149,31,227,94,119,59,214,252,125,29,88,36,248,206, -218,245,216,180,117,135,134,29,165,217,102,174,172,52,3,46,35,161,3,212, -58,208,157,102,146,129,148,39,208,111,11,58,32,131,141,70,11,110,49,25, -225,122,65,185,233,26,247,249,47,235,243,250,248,52,204,120,114,30,22,172, -190,157,224,43,8,254,16,112,170,77,103,40,174,62,191,25,149,173,251,144, -78,167,243,205,168,160,10,232,89,70,51,64,46,117,162,153,100,128,41,134, -183,179,62,6,8,238,235,4,164,230,134,150,136,121,160,229,17,134,17,56,164, -181,119,140,40,82,178,20,205,127,92,146,3,255,192,215,129,87,53,248,174, -160,229,111,58,82,131,219,158,124,11,118,54,9,155,201,151,219,31,10,123, -129,239,177,124,156,128,1,189,169,232,104,146,105,22,167,78,46,70,171,116, -244,4,244,116,205,145,145,160,95,72,62,132,181,238,144,129,97,21,195,129, -115,245,152,189,242,46,70,174,193,215,135,224,14,193,171,209,178,245,77, -188,120,224,13,152,194,99,222,120,69,219,243,24,3,41,234,104,145,129,4, -163,238,79,184,72,240,201,163,174,64,194,149,72,120,161,57,225,121,96,6, -134,61,11,67,254,20,236,239,187,8,248,190,46,220,188,112,62,244,134,231, -49,88,37,138,123,65,208,173,178,76,40,171,60,138,67,119,150,66,230,119, -118,69,173,84,234,194,110,175,242,93,92,192,147,22,183,215,82,12,255,244, -114,204,94,125,231,123,192,73,251,209,106,124,133,224,123,254,212,137,37, -159,104,194,158,63,191,198,156,50,130,6,245,190,118,204,9,131,57,165,208, -125,102,8,199,78,15,22,237,242,239,159,120,152,144,48,144,33,237,139,95, -93,130,235,90,239,10,53,15,193,165,135,39,94,171,193,242,45,199,177,123, -127,23,110,249,100,19,215,163,184,229,198,235,241,194,193,215,137,83,220, -33,181,3,106,116,116,164,189,243,232,43,11,85,190,87,143,53,162,220,244, -82,18,99,125,167,50,65,207,247,9,46,153,237,171,254,189,22,77,247,104,240, -187,139,192,55,191,94,139,211,205,143,224,197,67,212,156,174,238,61,208, -17,236,162,123,184,234,161,212,11,230,132,98,9,50,191,121,248,123,43,185, -206,40,24,80,196,199,111,90,58,231,211,159,191,125,67,218,19,209,5,215, -204,198,153,127,13,6,229,228,200,24,62,219,209,130,198,85,203,73,123,49, -248,175,59,106,80,118,119,27,154,157,4,213,179,115,114,9,81,48,122,171, -160,89,189,151,129,52,237,44,237,237,130,49,61,182,232,214,229,47,139,120, -9,162,164,108,74,89,41,110,170,153,201,182,106,97,176,251,121,76,93,244, -85,160,238,219,192,1,90,239,110,130,171,32,242,169,43,218,96,216,9,102, -181,29,200,90,56,172,92,120,47,240,195,223,46,56,160,103,243,68,104,249, -99,186,237,56,248,232,7,171,48,146,76,163,247,76,63,78,41,210,39,163,104, -28,232,192,135,110,125,4,110,223,94,136,108,6,6,35,223,218,121,5,166,173, -220,205,237,118,132,251,130,23,204,139,227,142,115,122,126,44,248,125,188, -161,212,212,245,90,91,89,142,43,106,43,49,52,156,98,103,19,48,250,247,227, -186,6,222,210,223,6,57,244,38,78,244,189,139,99,39,234,112,184,238,251, -176,94,160,67,190,131,139,205,233,122,243,202,36,19,237,249,76,31,207,1, -247,111,127,105,255,46,231,164,71,23,204,111,64,211,188,89,168,152,81,137, -205,207,254,0,199,205,56,214,44,62,136,157,187,142,160,39,178,16,135,207, -86,173,109,223,180,172,3,19,123,63,66,200,248,59,58,247,254,219,171,89, -156,86,115,217,204,154,89,139,151,173,122,160,172,98,230,13,229,94,63,186, -59,123,112,229,212,119,81,85,63,15,61,233,203,219,247,62,189,97,253,224, -249,127,246,241,218,17,61,248,92,194,248,152,9,115,207,29,207,1,45,82,84, -231,2,109,38,237,178,251,86,223,241,212,192,217,99,219,126,187,187,251, -37,221,197,66,80,157,184,67,225,3,213,100,134,217,139,189,156,154,33,27, -21,180,242,96,127,205,1,107,7,178,249,40,240,63,28,19,125,59,182,66,70, -188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, -73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_20 = 2051; -static unsigned char xml_res_file_20[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,7,165,73,68,65,84,120,218,156,87,107,112,21,103,25,126,190,221,61, -187,231,228,228,2,185,181,73,4,148,66,130,117,200,52,182,214,81,42,14,45, -86,7,80,212,233,216,17,157,78,127,56,26,188,212,209,254,160,25,172,12,242, -163,211,25,227,84,165,78,107,157,90,111,197,214,58,12,140,69,7,28,138,66, -25,29,36,164,212,182,16,174,197,96,106,110,36,57,201,185,236,213,231,221, -221,115,56,73,154,66,115,38,111,118,191,189,124,239,243,62,239,243,190, -223,183,10,243,251,25,219,31,127,238,5,77,55,54,6,65,112,221,47,41,165, -224,123,238,158,109,223,184,247,30,14,221,240,218,124,156,127,255,39,207, -238,14,148,190,161,189,125,57,252,192,7,174,7,3,61,105,74,195,201,147,103, -160,2,239,79,63,120,96,211,231,138,32,222,237,175,234,225,157,207,5,30, -67,207,217,94,48,85,112,175,219,228,121,121,79,222,151,121,194,104,230, -1,32,233,123,30,108,199,195,75,189,231,241,46,50,192,20,0,107,110,89,10, -121,95,230,161,101,230,3,64,73,222,197,177,76,120,103,199,210,232,106,80, -250,55,231,239,96,239,5,120,126,192,180,5,165,244,27,243,146,160,188,175, -105,48,13,3,221,47,28,9,197,85,156,49,40,2,41,163,70,206,124,58,190,189, -109,17,157,99,218,61,99,154,170,13,170,218,191,54,167,18,193,35,79,60,31, -158,107,116,174,98,126,229,152,72,165,96,86,45,164,67,31,197,10,9,138,204, -168,32,186,94,174,104,177,135,127,252,187,221,142,231,111,232,88,185,244, -186,84,29,160,156,110,85,42,37,165,41,156,232,121,3,53,233,36,218,90,223, -7,207,187,10,66,126,50,118,131,233,215,4,64,10,154,190,97,235,55,239,133, -72,67,155,103,99,8,98,251,228,29,29,216,241,163,223,224,235,95,88,11,199, -245,203,232,86,56,208,211,7,223,13,102,1,72,10,50,62,138,111,109,255,57, -146,166,6,61,78,102,41,157,40,27,151,165,176,52,230,228,146,57,199,11,208, -221,245,213,80,12,143,62,127,56,164,187,248,158,164,237,214,229,205,33, -195,51,1,168,128,15,22,28,160,182,42,133,63,14,119,32,101,42,88,150,142, -132,149,160,208,20,76,211,64,130,168,76,90,130,227,4,105,18,227,99,72,208, -136,153,62,53,164,223,60,64,16,30,20,209,24,154,129,64,73,190,163,224,84, -172,45,215,155,13,0,242,88,193,118,145,78,137,67,230,36,169,193,162,37, -56,187,69,79,186,17,57,14,1,104,49,0,58,54,244,0,9,206,101,104,81,132,169, -100,2,133,130,75,7,58,110,95,118,83,200,128,173,108,216,122,68,187,107, -219,161,6,202,53,22,85,1,31,204,219,30,233,79,64,37,116,232,150,6,67,142, -166,206,177,0,160,233,26,52,130,208,8,128,127,20,125,16,30,53,30,85,200, -49,194,247,37,16,205,55,177,179,112,3,68,2,95,169,24,198,250,199,187,233, -212,195,238,206,78,54,33,188,13,3,188,80,112,108,36,73,57,75,49,116,168, -37,12,154,30,153,140,197,200,0,113,132,26,145,35,73,134,33,64,164,185,184, -10,73,50,144,39,0,159,247,135,143,82,19,194,253,39,116,188,181,247,145, -72,55,155,55,19,148,63,125,97,41,202,40,79,17,88,166,201,168,181,208,169, -50,244,8,12,207,13,67,210,161,69,41,208,37,247,76,7,29,187,174,203,202, -97,154,76,41,159,0,21,150,133,60,3,113,130,60,182,174,121,43,204,183,237, -78,224,31,251,251,9,192,135,42,228,24,172,247,54,12,136,8,109,39,140,64, -211,232,88,147,136,245,48,13,134,25,29,93,58,29,177,129,28,203,104,60,231, -134,162,10,28,230,155,32,124,70,157,47,0,91,87,88,200,178,18,10,204,77, -214,244,88,247,34,65,45,202,15,185,23,183,158,95,214,152,138,0,4,81,158, -226,177,152,67,141,220,134,121,167,25,100,32,235,41,244,219,138,0,180,176, -209,72,194,19,150,18,57,135,229,22,40,132,37,104,243,196,172,170,134,253, -239,19,248,216,193,103,176,240,151,223,13,213,31,174,25,252,103,127,104, -13,114,235,190,8,103,241,90,248,12,114,134,6,192,220,145,1,114,41,66,51, -200,0,51,139,193,2,153,81,6,148,164,133,96,132,29,17,83,160,188,98,131, -39,40,13,110,194,132,163,153,104,217,243,11,212,28,123,9,43,63,245,105, -44,232,188,31,122,170,34,138,58,155,197,149,87,123,209,191,179,11,133,83, -199,224,212,119,204,172,2,143,229,227,132,12,72,83,41,248,26,166,114,44, -78,230,94,49,218,64,162,215,117,120,20,38,200,72,184,94,176,198,73,23,163, -97,90,148,137,239,252,245,65,52,142,29,199,242,45,219,80,56,251,58,50,187, -158,130,59,52,16,57,105,104,66,213,135,87,163,253,161,109,56,245,179,199, -208,209,56,80,2,160,21,25,200,50,143,9,50,144,97,212,253,25,23,25,71,97, -146,202,206,184,26,50,94,108,78,60,46,26,155,215,132,151,192,77,255,249, -23,214,14,252,29,173,155,191,141,236,158,93,200,239,223,3,76,102,96,164, -171,67,147,115,185,150,231,189,247,119,62,128,246,129,215,208,125,243,226, -149,210,159,140,226,106,85,160,160,18,53,22,14,223,151,134,86,236,236,129, -80,157,189,218,237,131,226,42,30,47,63,164,223,75,86,96,104,203,211,104, -92,127,15,242,135,254,2,111,240,50,180,100,50,218,44,148,150,41,121,215, -8,239,21,254,182,15,139,214,109,196,7,126,255,219,237,188,113,216,136,119, -24,212,84,128,147,231,71,241,202,217,145,105,93,254,29,119,60,4,224,36, -211,88,125,232,0,106,30,124,8,83,71,254,12,197,86,28,176,227,205,94,82, -85,148,198,115,167,177,176,227,35,72,234,218,42,89,8,5,64,48,57,57,241, -242,137,127,30,93,21,20,215,234,210,66,20,237,94,42,146,22,166,178,249, -120,199,1,164,43,146,200,74,221,17,64,222,172,192,234,4,59,104,255,5,54, -40,133,154,23,123,223,113,213,28,223,120,27,212,165,115,69,120,210,249, -145,127,250,209,45,95,227,177,190,108,131,162,62,122,215,134,182,187,63, -255,229,238,156,167,172,91,111,105,197,249,129,145,210,36,75,155,234,112, -188,183,15,149,41,11,139,86,44,3,254,64,41,141,93,97,3,75,94,115,217,14, -159,225,179,44,31,20,53,144,163,93,162,13,150,37,45,185,246,179,95,58,160, -88,70,22,59,71,101,85,26,119,53,55,148,246,129,67,153,44,44,58,247,72,233, -169,190,11,104,147,53,111,108,20,122,117,13,38,55,221,25,54,167,89,185, -147,29,147,116,86,62,227,143,141,197,26,137,34,150,189,121,38,182,226,175, -214,118,28,220,252,158,27,48,49,149,195,153,115,253,232,43,155,80,246,128, -141,245,11,80,153,174,192,43,167,47,34,127,219,199,49,49,126,25,181,13, -245,240,172,100,212,106,103,75,32,124,143,31,51,24,30,27,199,132,235,245, -32,148,230,28,31,31,46,59,93,75,67,13,150,180,52,96,100,124,138,85,226, -148,170,192,98,206,235,106,210,144,229,238,196,171,167,177,127,225,10,84, -191,209,131,250,166,38,70,105,198,155,142,217,91,114,45,162,29,111,14,12, -97,255,224,216,99,60,181,245,57,0,88,213,181,13,67,99,185,224,238,74,150, -212,202,101,45,104,93,210,140,37,55,214,210,234,81,101,25,56,75,86,14,30, -61,142,99,135,246,117,61,251,204,79,127,184,170,38,85,227,230,242,109,45, -55,54,177,107,74,75,231,130,38,235,10,143,122,184,194,82,168,4,112,252, -245,83,56,51,54,185,183,235,181,139,79,210,207,149,185,62,205,82,180,230, -186,198,230,229,235,54,117,126,175,114,65,221,170,104,183,28,81,32,84,78, -142,15,191,188,111,215,147,59,70,254,247,223,139,34,100,73,219,175,62,184, -124,71,107,109,245,250,101,239,93,140,250,122,106,218,136,9,166,38,134, -135,135,113,246,226,37,156,30,205,188,120,127,79,95,151,16,33,105,159,11, -128,112,101,201,164,180,70,90,245,140,111,8,209,205,68,44,220,209,120,44, -159,90,45,247,45,110,188,227,51,77,181,157,117,134,222,126,117,59,10,140, -184,222,201,189,3,163,79,252,250,210,224,17,14,47,75,69,34,108,236,215, -248,16,141,217,176,102,108,152,101,161,43,196,21,84,252,192,148,116,166, -99,208,82,210,149,241,181,112,71,78,155,164,13,199,128,167,226,107,243, -250,58,190,198,55,48,18,49,104,115,122,47,134,29,3,118,202,219,228,255, -5,24,0,238,123,163,24,29,62,142,101,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_21 = 1382; -static unsigned char xml_res_file_21[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,5,8,73,68,65,84,120,218,188,87,221,107,28,85,20,255,221,123,247, -35,219,205,182,214,26,65,76,137,77,95,170,144,244,69,13,66,13,81,40,166, -44,125,16,95,20,130,246,161,224,187,208,7,65,124,240,73,168,138,255,64, -177,196,40,197,135,250,17,107,179,20,2,106,181,95,84,209,68,12,213,52,164, -105,83,76,98,83,106,147,184,51,115,239,245,156,59,119,55,187,178,205,206, -34,102,147,147,201,206,204,189,231,55,191,243,59,31,3,108,238,71,76,95, -248,178,184,58,247,67,244,193,145,126,75,223,51,169,205,114,124,169,244, -225,174,71,118,118,126,42,97,122,69,42,13,37,36,159,207,203,77,112,174, -230,127,42,125,178,187,187,107,122,109,233,183,222,185,179,199,96,162,8, -66,8,190,150,110,198,64,234,163,55,6,63,203,101,100,81,210,2,145,208,163, -177,22,65,16,160,187,103,31,186,30,123,10,225,234,45,220,152,248,14,209, -234,50,64,215,140,53,80,42,126,246,102,0,114,217,148,40,190,117,106,141, -130,69,0,18,34,48,198,98,229,239,0,151,15,237,195,181,159,199,113,119,105, -22,66,146,43,50,107,66,88,77,12,200,100,0,218,68,140,2,109,116,103,43,0, -172,77,227,250,247,35,88,43,27,90,199,110,200,33,61,57,253,194,16,0,229, -55,107,6,64,8,43,192,244,51,96,153,16,0,7,75,41,5,75,139,140,224,144,192, -81,15,27,135,71,235,176,162,1,36,200,2,11,73,241,106,5,0,127,248,126,118, -70,207,28,3,0,124,252,233,124,20,186,61,19,1,16,70,130,239,149,210,38,7, -64,247,17,1,68,55,135,194,186,135,175,0,176,158,129,74,8,26,165,97,230, -224,123,176,207,29,197,73,6,40,53,135,64,17,101,178,101,211,4,192,104,235, -52,81,103,77,68,152,215,36,148,254,93,120,254,175,55,177,34,202,202,161, -85,196,64,82,17,114,172,37,209,101,109,3,6,232,71,135,161,211,213,189,24, -72,7,26,120,161,239,117,60,219,139,161,177,194,57,40,155,165,5,41,218,84, -182,96,202,229,187,211,129,55,205,71,206,2,42,68,170,134,129,116,241,29, -44,134,26,219,220,69,66,187,86,166,35,114,24,236,125,17,37,117,2,191,47, -127,3,59,57,0,153,9,9,178,78,34,1,167,25,237,247,51,46,1,4,57,39,86,72, -83,145,11,193,122,22,228,217,249,241,87,143,225,86,249,115,174,156,180, -144,110,176,247,99,98,254,4,14,244,190,12,153,30,198,121,249,53,212,47, -207,208,198,1,237,110,18,132,192,198,34,52,113,8,216,121,247,67,51,232, -216,58,143,185,104,176,210,11,28,128,12,63,249,157,242,2,190,189,242,197, -122,185,21,163,228,24,152,252,99,24,131,61,135,40,109,142,227,162,28,71, -219,212,0,237,30,197,94,54,0,192,89,160,141,113,79,175,173,112,212,63,120, -223,18,134,75,143,98,160,168,171,12,84,53,176,162,231,41,24,112,38,50,100, -124,36,120,150,54,186,242,231,199,120,98,207,30,68,157,55,221,73,167,114, -217,204,84,141,8,125,45,32,159,249,92,26,38,12,156,78,170,89,192,88,86, -237,13,168,44,170,12,88,83,83,80,82,1,46,77,79,33,51,223,233,106,2,152, -62,97,55,46,68,194,23,34,91,209,129,113,44,108,201,166,17,82,33,242,17, -136,25,224,77,67,117,19,217,60,197,99,11,145,144,163,11,153,216,82,109, -192,236,34,112,161,212,69,244,239,39,2,168,182,43,56,10,155,153,246,121, -111,201,179,37,0,11,183,119,224,192,147,63,82,33,138,234,52,192,0,238,30, -29,62,215,206,8,89,48,148,37,120,229,165,56,202,87,175,3,151,199,186,80, -184,186,31,50,27,120,200,178,169,8,149,18,113,231,179,194,237,73,42,192, -212,181,157,56,125,62,143,190,167,203,117,205,40,56,117,4,253,116,220,238, -163,145,30,124,27,167,153,133,95,167,129,197,241,14,20,166,73,181,25,202, -77,105,155,59,175,134,64,212,133,192,161,162,221,219,243,169,184,25,249, -94,192,127,87,200,102,200,38,201,38,248,127,86,240,204,28,80,58,137,175, -6,150,30,135,205,26,206,206,4,194,91,55,22,153,49,53,169,232,45,79,173, -61,34,17,214,246,2,170,46,184,77,182,224,109,153,4,140,51,163,56,123,241, -125,188,171,169,240,240,119,169,68,107,149,144,158,194,152,250,74,200,150, -73,81,143,160,24,75,121,239,118,28,142,190,134,189,254,255,40,146,177,98, -121,65,226,102,200,133,200,54,232,5,126,92,99,6,114,27,52,35,14,201,44, -223,75,86,208,116,112,180,10,139,22,122,17,105,64,186,218,175,27,0,8,117, -176,225,60,16,120,115,51,33,47,86,20,3,102,76,192,38,29,7,40,182,42,110, -197,218,214,173,114,253,134,24,16,169,132,19,17,231,176,139,63,68,107,12, -112,3,226,25,208,254,11,54,51,16,82,29,200,183,48,146,185,210,235,250,153, -77,60,18,113,8,226,46,136,245,145,204,143,134,38,42,83,88,115,201,0,164, -69,68,111,15,138,179,176,133,247,2,94,23,235,38,150,146,168,130,224,131, -99,160,70,132,153,161,161,161,114,195,141,104,225,216,50,171,122,201,127, -75,30,2,109,37,206,204,20,176,35,23,161,179,16,34,159,50,136,135,99,206, -130,114,117,34,114,3,201,200,200,200,110,158,11,26,17,224,207,103,254,235, -251,217,3,219,114,185,195,197,158,131,15,119,180,247,109,47,96,111,165, -27,10,191,121,222,59,251,223,94,78,253,254,237,100,91,201,168,229,225,14, -87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, -29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_22 = 113420; -static unsigned char xml_res_file_22[] = { -60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, -110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, -32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, -116,115,46,111,114,103,47,116,114,117,110,107,47,111,118,101,114,118,105, -101,119,95,120,114,99,102,111,114,109,97,116,46,104,116,109,108,32,45,45, -62,10,60,114,101,115,111,117,114,99,101,32,120,109,108,110,115,61,34,104, -116,116,112,58,47,47,119,119,119,46,119,120,119,105,100,103,101,116,115, -46,111,114,103,47,119,120,120,114,99,34,32,118,101,114,115,105,111,110, -61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, -61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, -54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47,111,98,106,101, -99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65, -80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,100,105,115, -107,101,116,116,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,67,68,82,79, -77,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,99,100,46,112,110,103,60,47,111, -98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61,34,116, -111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108,101,62, -119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86,73,68, -69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61, -34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,50,52,120,50,52,95,112,108,97,121,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, -108,62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66, -65,82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, -62,80,97,117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76, -66,65,82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, -83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, -82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, -62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, -111,110,115,95,50,52,120,50,52,95,114,101,102,114,101,115,104,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, -108,62,72,97,114,100,32,114,101,115,101,116,60,47,108,97,98,101,108,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, -101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84, -34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32,32,60,105,100,115, -45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -83,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,70,83,95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,49,48,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34, -49,50,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69, -34,32,115,116,97,114,116,61,34,49,51,48,48,34,47,62,10,32,32,60,105,100, -115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,32,115,116,97,114,116,61,34, -49,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,34,32,115,116,97,114, -116,61,34,50,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80, -85,84,95,83,84,82,69,84,67,72,34,32,115,116,97,114,116,61,34,51,48,48,48, -34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76, -69,34,32,115,116,97,114,116,61,34,51,49,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84, -69,34,32,115,116,97,114,116,61,34,51,50,48,48,34,47,62,10,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,66, -97,114,34,32,110,97,109,101,61,34,115,116,97,116,117,115,95,109,101,110, -117,34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,68, -73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,68,105,115,99,32,97,99,116,105,118,105,116,121,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107, -97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65,67,72,73,78,69,95, -77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,111,117,110,116,32,112,97,116,104,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, -101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83,84,65,84,85,83,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,116,117, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,80,69,69,68,95, -72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,112,101,101,100,32,104,105,115,116,111,114,121,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101, -62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,72,79,87,95,77,65,67,72,73,78,69,95,79,78,95,83,84,65,82,84,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,111,110, -32,115,116,97,114,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, -98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,67,111,110,102,105,103,117,114,101, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,67,79,78,70,73,71,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,77,105,115,99,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,82,69,83,69,84,95,67,79,78,70,73,82,77,65,84,73,79,78,95, -68,73,65,76,79,71,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,82,101,115,101,116,32,99,111,110,102,105,114,109,97,116,105,111, -110,32,100,105,97,108,111,103,115,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111, -114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,65,66,79,85,84,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,65,98,111,117,116,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -34,32,110,97,109,101,61,34,109,97,105,110,95,109,101,110,117,34,62,10,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,121, -115,116,101,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,72,82, -69,83,69,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -72,97,114,100,32,82,101,115,101,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,82,69, -83,69,84,95,67,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,67,116,114,108,43,65,108,116,43,68,101,108,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112, -97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,69,88,73,84,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,104,117,116,100,111, -119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,115,99, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,68,73,83,67,95,65,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,32,100,114,105, -118,101,32,95,65,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,68,73,83,67,95,66,34,62,10,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,32,100, -114,105,118,101,32,95,66,58,46,46,46,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,69,74,69,67,84,95,65, -34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,106,101, -99,116,32,100,114,105,118,101,32,65,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,69,74,69,67,84,95,66, -34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99, -116,32,100,114,105,118,101,32,66,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116, -111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,66,80,66,95,68,73,83,65,66,76,69,34,62,10,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108,101,32,66,80, -66,32,99,104,101,99,107,105,110,103,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104, -101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,34,62,10,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,67,68,45,82,79,77,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,95,76,79,65,68,34,62,10,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97,100,32,105,109, -97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -67,68,82,79,77,95,68,73,83,65,66,76,69,68,34,62,10,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,95,68,105,115,97,98,108,101,100,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, -32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,82,69,83,73,90,69,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,82,101,115,105,122,97,98,108,101,32,119,105, -110,100,111,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, -101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97, -109,112,59,38,97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98, -108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34, -47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76, -69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103, -103,108,101,32,102,117,108,108,115,99,114,101,101,110,92,116,67,116,114, -108,43,65,108,116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -85,76,76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110, -112,117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99, -107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115, -99,114,101,101,110,32,109,111,100,101,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,70,83,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,66,111,114,100,101,114,108,101, -115,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95, -77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,95,69,120,99,108,117,115,105,118,101,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82, -95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,82,101,110,100,101,114,32,100,114,105,118,101,114,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86, -69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,65,117,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116,51,68,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95, -68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,79,112,101,110,71,76,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, -110,71,76,32,51,46,48,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,111,102,116,119,97,114,101, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,86,83,89,78,67,34,62,10,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,86,83,121,110,99,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, -47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73, -77,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,109, -32,100,105,115,112,108,97,121,32,111,110,32,108,111,115,116,32,102,111, -99,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, -104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114, -97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,83,99,97,108,101,32,102,105,108,116,101, -114,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67, -65,76,69,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105, -110,101,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,116,114, -101,116,99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101,108, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73, -110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, -112,117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46, -53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, -69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,52,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, -110,71,76,32,51,46,48,32,114,101,110,100,101,114,101,114,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,116,114,101,116, -99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83, -113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, -114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84, -95,83,84,82,69,84,67,72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99,97, -108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112, -117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53, -120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78, -80,85,84,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, -83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65, -76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51, -46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,114, -101,102,114,101,115,104,32,114,97,116,101,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82, -69,83,72,95,82,65,84,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,97,109,101,32,97,115,32,101,109,117,108, -97,116,101,100,32,100,105,115,112,108,97,121,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, -114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, -82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,48,32,104,122,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -50,53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, -95,82,65,84,69,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,51,48,32,104,122,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, -95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,53,48,32,104,122,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54, -48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82, -65,84,69,91,55,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69, -70,82,69,83,72,95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100, -101,114,32,109,97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102, -101,114,32,108,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,78,68,95,66,85,70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,83,78,68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,50,48,48,32,109,115, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,48,48, -32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115, -99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114,101,101,110,115,104, -111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72, -79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -84,97,107,101,32,115,99,114,101,101,110,115,104,111,116,92,116,67,116,114, -108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, -72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, -79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, -51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, -72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, -97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62, -10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, -68,67,95,67,68,82,79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62, -10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, -68,67,95,69,68,73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,67,95,70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,69,74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,78,69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10, -32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68, -67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56, -48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114, -116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115, -116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114, -97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66, -69,76,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111, -103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108, -103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, -85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117, -114,101,32,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, -99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, -69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, -47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111, -119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, -116,101,98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84, -69,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, -101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, -99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, -114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,51,50,120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, -76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, -65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99, -32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, -104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118, -97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, -67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, -122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, -99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, -99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, -76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, -105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, -100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, -103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, -101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, -99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, -65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, -107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, -115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, -97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, -98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, -99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, -73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, -47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, -60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, -79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, -68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, -49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68, -50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, -111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,104,111,105,99,101,98,111,111,107,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,72,66,95,68,69,70,65,85,76,84,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111, -105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,68,114,105,118,101,32,49,32,40,67,58,41,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101, -100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, -97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, -65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, -108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73, -68,67,95,72,68,68,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47, -118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87, -91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, -54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, -116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99,111,110,116, -114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105,116,109,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,106, -101,99,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, -48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, -47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, -95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, -66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90, -69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, -111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, -116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, -76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,51,32,40,69,58,41, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, -47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, -68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, -97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,48,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, -121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, -111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114, -100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, -111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, -82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108, -117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, -62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, -117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, -62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, -99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, -62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, -69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, -78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50, -53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, -73,90,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, -111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,114,105,118,101,32,52,32,40,70,58,41,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, -116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, -76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,109,111,117,115,101,95,112,99,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, -101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, -112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, -60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, -114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,77,111,117,115,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,77,79,85,83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, -97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,78,101, -119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119, -32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32, -32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, -114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79, -84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, -60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62, -48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111, -119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, -97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, -85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, -101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, -115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,48,109,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, -97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,83,105, -122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,72,97, -114,100,32,68,105,115,99,32,80,97,114,97,109,101,116,101,114,115,60,47, -116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, -62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, -108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, -32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47, -62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116, -105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97,115, -101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, -108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, -115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, -108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, -49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, -101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108, -111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,83, -101,108,101,99,116,105,111,110,68,108,103,34,62,10,32,32,32,32,60,116,105, -116,108,101,62,80,67,101,109,32,67,111,110,102,105,103,117,114,97,116,105, -111,110,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62,10,32, -32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, -114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,60,114,111,119,115,62,49,60,47,114,111,119,115,62, -10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, -103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, -97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -50,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, -60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, -47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, -82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73,78, -71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,53,48,44,51,48,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97, -112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, -79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,116,111,111,108,116,105,112,62,76,111,97,100,60,47,116,111,111,108, -116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,110,116, -114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, -101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100, -100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, -82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97, -109,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, -50,120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76, -69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -99,111,109,112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, -108,116,105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108, -103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, -85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89, -95,79,78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116, -105,116,108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110, -97,103,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110, -116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, -97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76, -34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82, -73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73, -83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, -82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100, -100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,111,110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101, -32,117,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87, -78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,80,80,76, -89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,65,112,112,108,121,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, -101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101, -61,34,67,111,110,102,105,114,109,82,101,109,101,109,98,101,114,68,108,103, -34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76, -84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79, -78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, -108,101,62,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, -99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, -69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115,116,111,99,107,95, -105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79,78,34,32,115,116, -111,99,107,95,99,108,105,101,110,116,61,34,119,120,65,82,84,95,67,77,78, -95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,67, -79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, -82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73, -82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73,82,77,95,82,69, -77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98, -117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72, -79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,67,97,110,99,101,108,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,65,98,111,117,116,68,108,103,34,62,10,32,32,32,32,60,115, -116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, -83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, -108,101,47,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, -47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, -101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,80,67,101,109,32,118,49,50,92,110,104, -116,116,112,115,58,47,47,112,99,101,109,45,101,109,117,108,97,116,111,114, -46,99,111,46,117,107,47,92,110,92,110,84,104,105,115,32,112,114,111,103, -114,97,109,32,105,115,32,108,105,99,101,110,115,101,100,32,117,110,100, -101,114,32,116,104,101,32,71,78,85,32,71,101,110,101,114,97,108,32,80,117, -98,108,105,99,32,76,105,99,101,110,115,101,32,118,101,114,115,105,111,110, -32,50,46,92,110,83,101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109, -111,114,101,32,100,101,116,97,105,108,115,46,92,110,92,110,84,111,111,108, -98,97,114,45,105,99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117, -110,100,105,99,111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117, -110,100,105,99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119, -119,119,46,102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104, -101,114,32,105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116, -67,111,119,32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,116,99, -111,119,46,99,111,109,47,102,114,101,101,45,105,99,111,110,115,47,41,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, -114,99,101,62,10}; - -void InitXmlResource() -{ - - // Check for memory FS. If not present, load the handler: - { - wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); - wxFileSystem fsys; - wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); - wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); - if (f) delete f; - else wxFileSystem::AddHandler(new wxMemoryFSHandler); - } - - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$pc.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); - wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$pc.xrc")); -} +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 430; +static unsigned char xml_res_file_0[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,1,80,73,68,65,84,120,218,196,147,177,75,195,64,20,198,191,75,2,77,82, +2,66,58,171,32,130,171,130,179,10,34,138,173,155,131,56,248,143,137,184, +9,145,186,168,40,34,104,103,65,119,233,160,117,236,210,160,29,210,187,228, +204,119,70,135,170,181,218,193,7,71,238,184,239,247,229,221,189,123,66, +107,141,81,194,194,136,225,236,238,237,35,77,51,88,150,224,90,151,74,165, +129,64,146,36,252,136,44,211,176,109,11,14,87,89,150,209,68,215,170,235, +120,120,108,13,52,152,156,24,199,241,201,169,22,194,18,52,176,8,247,164, +212,27,181,106,14,63,209,28,66,124,61,184,71,13,181,100,200,58,105,154, +70,59,219,91,144,74,97,102,122,106,184,131,231,102,100,14,162,195,200,81, +74,109,198,207,47,56,59,191,40,118,127,170,138,185,43,172,173,174,128,44, +51,64,210,75,224,249,30,150,151,22,115,94,23,26,209,7,234,55,239,252,239, +151,87,215,134,33,107,12,100,79,194,247,92,40,41,113,115,123,247,113,222, +126,3,190,153,249,185,89,163,37,99,12,148,74,205,196,117,61,116,226,24, +149,74,88,24,124,14,26,80,67,45,25,178,38,3,222,102,185,236,227,190,217, +252,22,126,143,118,187,141,48,12,139,210,231,6,156,216,142,131,32,8,204, +24,54,200,152,50,118,187,221,70,189,126,180,240,219,158,96,166,249,171, +108,48,95,22,127,236,143,173,208,17,255,222,141,175,2,12,0,1,60,177,155, +95,179,104,212,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_1 = 730; +static unsigned char xml_res_file_1[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,124,73,68,65,84,120,218,140,83,77,72,85,65,24,61,115,239,220,247, +158,247,169,207,22,146,253,27,214,162,218,219,198,22,45,42,105,23,180,9, +139,8,162,104,227,182,34,37,242,137,216,162,149,127,139,22,134,36,182,80, +116,19,22,190,130,16,194,140,22,45,130,90,244,71,100,17,6,37,153,250,222, +157,59,157,111,238,141,90,132,116,185,115,103,238,204,57,223,249,190,51, +51,170,161,107,186,35,178,40,86,76,140,40,6,248,174,251,120,108,154,159, +192,247,160,21,58,81,127,109,218,62,91,180,118,246,83,100,255,247,17,172, +112,132,171,141,181,208,212,61,48,252,6,246,242,110,188,90,88,162,134,130, +229,215,198,49,136,135,231,121,238,159,19,216,179,181,206,97,159,159,107, +130,112,37,35,44,27,5,204,12,185,20,71,250,123,49,50,208,139,249,210,20, +158,148,38,81,21,102,113,171,175,7,79,31,76,113,110,50,169,99,102,48,225, +72,57,138,253,207,114,12,221,184,23,101,250,208,222,209,77,85,133,56,54, +46,19,202,162,253,74,55,98,167,102,177,90,49,14,43,28,225,122,138,185,253, +88,139,208,176,255,16,137,49,250,138,29,152,25,191,141,128,14,245,247,116, +226,225,228,29,148,38,70,145,241,225,230,173,53,196,30,118,28,225,106,73, +99,133,246,231,57,202,178,93,42,22,221,110,72,237,23,187,138,46,77,81,151, +224,199,78,158,66,46,0,242,126,194,113,37,72,150,107,252,41,4,10,247,222, +174,160,117,103,72,75,173,51,45,177,242,207,6,138,97,130,41,100,148,227, +8,87,75,149,101,30,132,2,229,175,207,125,199,213,217,111,88,51,169,106, +74,21,140,199,130,179,84,14,41,36,88,225,40,164,37,208,15,84,51,106,217, +120,56,219,164,208,214,188,233,47,101,155,54,133,209,249,207,24,251,96, +145,241,148,227,36,187,144,6,168,146,227,69,96,91,115,61,94,190,255,10, +95,7,78,186,82,137,16,27,227,220,150,181,137,143,139,196,38,1,84,122,50, +81,161,65,57,166,150,97,62,17,243,223,178,113,3,134,111,14,226,252,233, +19,216,198,113,192,5,173,53,162,85,67,140,114,88,225,224,119,9,177,245, +144,15,52,245,121,31,140,69,77,232,97,238,241,44,142,180,30,69,77,78,8, +190,108,139,91,11,57,206,7,158,227,184,0,98,142,246,125,212,133,1,116,133, +7,202,75,22,178,188,44,97,214,197,103,159,113,59,226,115,77,112,213,12, +32,28,199,141,190,188,27,186,113,23,23,162,216,98,169,108,112,166,118,23, +86,120,18,183,239,104,60,222,62,246,8,45,45,7,199,151,233,131,4,168,37, +113,224,254,107,212,242,84,81,25,194,21,31,196,242,205,255,184,185,47,210, +126,223,58,183,123,225,151,0,3,0,201,66,64,174,55,176,170,129,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_2 = 835; +static unsigned char xml_res_file_2[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,229,73,68,65,84,120,218,100,83,75,76,19,81,20,61,211,118,166,157, +150,22,176,5,1,229,35,82,36,4,99,162,6,18,34,113,39,46,80,227,70,73,220, +201,202,128,184,209,24,119,46,220,104,76,36,4,226,74,55,224,130,141,66, +130,49,16,73,52,98,68,148,40,66,212,128,168,20,249,10,165,244,199,48,191, +231,157,153,242,81,95,114,38,147,247,238,57,247,220,251,238,227,240,207, +106,125,250,185,93,211,217,69,198,224,98,169,61,14,144,236,54,238,225,149, +186,242,198,157,177,140,130,184,45,98,239,248,9,69,99,125,135,131,57,40, +47,244,35,224,230,16,213,128,12,59,16,223,96,24,15,173,96,240,203,2,156, +54,174,182,249,84,69,255,95,2,173,189,99,23,108,28,215,121,186,186,20,170, +192,99,62,1,232,58,224,225,1,55,161,212,107,186,192,106,82,197,163,23,19, +6,177,182,185,174,162,223,16,176,25,2,138,162,117,214,86,29,192,188,198, +99,54,14,184,104,55,91,36,184,128,28,151,69,150,146,26,212,152,142,186, +35,251,33,171,106,223,166,115,71,75,207,135,246,242,226,92,36,236,14,56, +40,107,186,19,200,243,0,94,199,118,173,242,134,142,233,80,18,203,97,25, +254,128,136,163,193,92,220,35,30,29,53,58,84,85,107,40,200,11,128,217,45, +187,89,148,89,36,7,207,70,102,176,16,78,162,40,224,67,85,73,54,92,110,59, +50,152,0,191,223,129,116,33,11,195,95,102,26,76,1,6,221,233,243,216,192, +147,79,183,205,34,15,140,45,226,253,143,136,28,93,158,123,242,43,154,119, +86,222,224,132,218,170,221,88,161,174,166,251,28,224,204,206,233,78,227, +107,211,53,134,108,250,13,8,36,144,178,253,157,172,38,86,23,30,220,189, +116,242,154,28,11,63,94,210,233,58,136,101,144,169,74,208,165,192,43,58, +173,30,48,166,195,158,170,53,186,166,192,151,230,192,62,143,7,82,240,96, +195,253,87,139,170,162,234,245,133,89,110,243,156,46,1,235,4,141,8,177, +68,194,18,224,160,203,73,73,21,164,4,195,236,92,18,62,47,143,234,50,47, +124,75,138,48,17,81,47,23,237,226,113,172,72,52,201,225,13,202,78,22,98, +113,29,6,207,20,136,173,46,117,191,30,157,61,151,197,103,66,82,85,240,162, +29,54,193,142,202,98,30,149,155,206,40,116,126,157,178,235,150,253,159, +211,11,136,134,127,119,167,166,20,5,119,186,6,167,143,151,150,33,63,207, +139,52,114,32,186,104,10,21,32,161,88,150,105,4,204,204,18,145,215,226, +10,38,135,223,226,106,125,77,33,13,82,200,24,164,208,167,55,207,155,6,167, +190,66,16,25,53,135,51,27,181,66,118,35,138,133,53,213,194,50,89,153,26, +121,135,209,161,129,38,131,103,150,96,124,58,91,110,118,128,212,101,89, +105,171,57,84,130,189,249,123,16,103,156,105,217,64,52,201,16,153,159,197, +106,232,27,62,14,189,108,234,48,226,183,31,218,214,242,17,130,55,218,186, +174,251,50,3,103,232,64,112,137,46,200,146,100,4,201,107,225,229,158,91, +77,231,111,83,204,164,209,150,255,94,227,142,85,64,240,27,51,178,99,207, +172,106,211,246,206,231,252,71,128,1,0,112,7,72,225,52,89,175,48,0,0,0, +0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_3 = 758; +static unsigned char xml_res_file_3[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,7,129,43,165,16,0,0,2,131,73,68,65,84,72,199, +173,150,75,72,85,81,20,134,191,181,207,193,30,100,20,133,72,138,40,74,88, +148,98,23,172,73,154,26,145,41,105,13,170,91,87,16,130,102,61,104,208,80, +176,73,163,232,49,8,10,132,64,203,50,172,124,21,36,233,176,129,248,200, +66,169,244,38,248,106,16,22,106,131,186,247,156,213,68,73,229,30,189,222, +252,135,251,44,190,181,215,218,255,62,107,11,203,200,215,222,144,226,154, +112,153,8,37,64,42,144,60,247,105,12,24,65,181,213,178,77,83,87,190,127, +212,139,33,145,22,179,223,54,36,89,226,84,129,158,7,44,150,151,139,72,163, +11,215,250,10,252,35,43,38,240,117,62,46,87,165,22,216,196,234,52,163,72, +160,183,208,223,188,112,209,44,134,63,186,172,74,99,12,112,128,120,65,95, +248,58,234,47,69,172,96,110,231,141,75,147,198,32,87,145,19,243,149,8,64, +86,103,93,178,173,102,48,198,157,71,110,87,88,50,123,143,248,39,12,128, +173,230,186,23,252,66,234,30,106,246,29,38,51,126,235,170,218,133,165,213, +0,226,107,111,72,81,43,28,244,114,203,205,189,7,57,180,61,25,87,149,151, +147,195,220,25,238,99,54,28,138,38,137,19,22,55,213,96,57,229,81,88,17, +35,194,201,29,25,60,223,95,74,105,98,90,100,127,47,150,101,99,149,25,69, +139,87,83,251,182,184,245,84,239,58,192,253,156,34,210,54,110,94,54,86, +85,143,25,144,140,88,78,209,183,37,129,39,185,197,92,76,207,38,206,88,94, +183,56,221,128,38,198,106,21,91,12,149,41,187,105,200,45,38,97,221,134, +72,33,73,102,45,60,25,103,44,44,137,136,114,109,129,9,133,157,177,128,29, +85,158,141,127,225,222,215,126,126,69,118,214,132,173,16,36,134,4,3,51, +83,220,248,212,197,192,204,148,247,33,67,208,70,181,13,145,163,209,130, +167,67,127,120,48,242,145,167,227,159,113,85,151,183,182,106,171,109,217, +166,201,113,244,246,74,119,65,129,87,223,70,184,53,212,195,143,208,239, +104,246,18,14,25,109,49,93,249,254,81,65,30,122,69,13,205,254,228,195,244, +119,42,187,223,80,53,248,46,90,56,64,77,127,65,96,76,254,13,152,240,32, +16,191,70,63,187,105,177,157,204,238,188,138,73,3,240,190,232,212,184,170, +57,13,56,107,0,119,81,2,221,121,21,147,139,6,78,111,209,153,215,130,92, +5,220,255,154,5,202,149,158,162,179,45,158,35,51,167,163,254,184,160,117, +49,180,107,26,113,207,245,20,4,90,61,71,38,64,111,161,191,89,109,59,93, +209,187,64,56,170,150,160,181,98,59,153,75,225,158,175,138,121,101,117, +214,37,219,88,101,224,150,160,146,182,240,217,162,16,52,208,22,18,183,185, +191,32,48,230,197,248,11,86,228,238,84,203,121,117,202,0,0,0,0,73,69,78, +68,174,66,96,130}; + +static size_t xml_res_size_4 = 635; +static unsigned char xml_res_file_4[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,39,59,41,220,197,88,0,0,2,8,73,68,65,84,72,199,181, +150,79,107,19,81,20,197,127,247,77,42,74,213,77,161,105,59,67,168,180,139, +172,252,12,110,107,193,68,67,43,65,17,164,184,85,113,225,170,8,250,17,92, +43,8,117,211,148,40,77,82,220,250,17,220,117,33,132,66,39,211,70,234,194, +74,241,79,230,205,117,209,36,152,191,198,208,57,48,139,119,223,155,115, +207,59,92,238,125,194,16,4,133,185,148,138,205,160,178,12,209,60,136,119, +186,163,62,152,61,160,130,53,219,110,62,216,31,196,33,253,130,251,133,41, +87,72,60,19,88,3,28,134,35,18,40,138,149,167,179,249,195,189,127,38,8,54, +167,179,42,178,1,92,228,255,240,29,184,235,174,214,75,127,7,77,167,37,201, +71,42,82,28,131,28,224,18,240,62,216,76,62,236,123,131,166,242,98,119,210, +49,16,1,55,91,55,17,0,191,232,122,98,195,221,110,229,226,92,192,156,159, +110,255,103,79,124,0,156,73,175,173,35,250,249,5,181,63,122,236,178,214, +166,83,249,163,32,1,32,97,248,2,233,181,229,242,213,117,38,23,215,218,235, +175,31,111,1,48,117,237,93,59,118,242,249,21,223,62,173,247,216,229,24, +231,57,240,192,4,133,185,20,194,189,254,53,150,232,92,155,115,167,95,71, +108,98,80,125,222,247,139,174,103,80,155,29,161,20,199,129,35,161,205,24, +21,89,34,38,136,232,117,3,186,24,87,2,69,23,12,48,67,108,16,215,16,47,34, +3,18,196,152,32,48,64,53,54,131,160,106,128,157,216,252,65,43,6,107,182, +1,27,3,127,136,51,81,54,205,97,241,166,191,132,70,103,217,69,191,32,250, +61,244,76,251,172,242,218,203,213,124,105,13,24,67,98,183,217,114,207,162, +217,29,55,28,155,158,207,29,29,180,219,245,193,214,204,82,164,90,62,131, +182,17,161,100,221,219,245,114,199,192,153,93,57,252,32,202,147,102,63, +31,159,92,120,220,34,239,59,50,107,133,228,13,224,109,183,93,35,224,88, +133,59,222,74,189,50,112,100,2,184,171,245,146,65,22,16,94,2,225,40,170, +21,217,104,56,54,221,77,62,240,85,209,130,95,116,61,9,109,70,37,90,22,228, +10,224,181,182,4,170,42,178,163,198,41,121,185,154,63,136,227,15,131,228, +187,196,255,21,120,89,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_5 = 622; +static unsigned char xml_res_file_5[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,10,255,154,217,173,0,0,1,251,73,68,65,84,72,199, +181,150,79,107,19,81,20,197,127,247,189,81,20,172,224,78,104,76,83,154, +69,65,92,249,29,4,173,249,163,11,5,91,18,161,184,85,113,225,82,169,31,193, +125,109,154,182,238,146,54,147,20,193,79,224,70,23,74,177,155,198,212,196, +184,20,234,194,66,102,230,186,104,163,113,72,106,26,157,179,155,251,134, +115,238,59,243,230,158,39,28,129,157,84,46,238,88,147,65,153,81,130,4,72, +236,96,69,91,130,105,168,6,53,79,108,37,89,89,106,14,226,144,126,197,230, +245,220,184,103,228,137,8,243,128,229,104,4,8,37,69,30,79,110,20,26,127, +21,248,148,189,155,21,213,21,224,12,199,195,119,163,204,197,221,101,183, +183,104,122,31,118,211,185,7,162,90,26,129,28,96,44,16,214,119,51,249,251, +125,119,112,216,121,41,44,58,2,2,163,220,232,238,68,0,90,55,103,99,158, +239,124,28,177,243,1,118,217,233,184,251,162,237,0,120,190,243,44,76,126, +234,226,52,167,47,95,26,138,237,199,219,15,236,111,109,135,236,242,23,128, +123,178,147,202,197,173,145,122,248,180,156,155,191,195,217,212,149,161, +4,246,170,175,249,182,248,50,92,246,29,235,37,140,99,36,59,196,81,28,5, +214,243,157,140,81,184,74,100,208,107,6,72,70,39,192,148,1,206,71,199,47, +227,134,104,17,24,160,29,161,64,219,0,245,8,63,114,221,160,186,25,25,189, +72,205,120,98,43,128,31,1,191,119,194,120,85,39,89,89,106,54,210,249,2, +7,179,255,247,239,255,230,29,116,58,67,142,138,247,125,130,70,22,99,229, +181,150,3,96,3,125,234,91,185,5,140,117,95,216,223,218,14,207,151,227,96, +79,173,183,240,43,15,46,212,138,95,16,189,253,159,172,10,4,153,75,148,87, +191,254,17,56,137,141,226,43,129,71,64,240,79,228,34,15,39,42,133,234,192, +200,252,156,206,167,3,97,181,215,174,97,109,17,163,179,19,235,197,218,192, +200,4,136,187,203,110,231,164,153,82,120,14,120,195,116,13,186,130,245, +167,195,228,3,111,21,93,28,38,93,6,101,6,97,18,136,117,151,64,235,192,166, +99,125,55,86,94,107,13,226,248,9,156,77,179,166,75,139,17,212,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_6 = 1144; +static unsigned char xml_res_file_6[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,24,0,0,0,24,8,6,0,0, +0,224,119,61,248,0,0,0,6,98,75,71,68,0,255,0,255,0,255,160,189,167,147, +0,0,0,9,112,72,89,115,0,0,13,215,0,0,13,215,1,66,40,155,120,0,0,0,7,116, +73,77,69,7,225,5,27,16,40,3,134,70,97,9,0,0,4,5,73,68,65,84,72,199,149, +150,125,76,213,85,24,199,63,231,220,223,21,132,139,74,76,96,23,68,4,2,95, +74,36,204,149,185,28,80,54,112,75,237,143,182,107,184,114,174,173,53,179, +172,173,218,154,110,218,250,167,245,178,176,173,63,154,171,41,190,76,231, +31,10,182,53,2,172,54,209,25,34,182,188,18,112,167,128,225,11,239,92,64, +238,203,239,233,15,188,183,251,194,5,122,254,59,231,57,207,247,123,206, +247,60,207,121,142,98,6,43,174,59,149,101,106,223,22,165,216,12,100,3,153, +143,92,61,192,45,68,106,45,134,62,123,101,163,163,59,22,134,154,110,178, +176,254,84,134,69,249,247,131,236,2,44,204,108,38,74,157,49,225,195,107, +37,142,91,179,18,20,55,30,223,42,194,81,192,198,255,179,81,65,85,182,148, +58,206,197,36,40,110,60,246,174,136,250,10,208,161,243,217,9,11,88,155, +156,74,122,92,34,94,49,233,28,27,230,210,64,47,110,159,55,234,52,10,181, +183,185,212,81,21,69,240,104,231,103,66,193,87,36,61,198,222,188,34,138, +23,165,70,109,215,47,66,205,93,23,135,58,91,25,242,78,134,145,8,106,91, +224,36,10,96,117,99,117,166,33,218,25,42,203,54,123,46,31,231,175,197,80, +83,124,109,238,65,122,31,142,97,85,154,60,219,34,210,226,18,0,24,244,78, +242,246,181,6,254,118,15,133,203,229,83,203,91,54,57,254,49,0,12,209,7, +67,193,95,74,93,202,39,5,235,80,192,197,129,94,190,104,111,230,246,248, +104,48,90,43,197,51,201,233,124,148,191,150,204,249,54,190,91,83,202,27, +205,117,116,79,4,215,36,97,145,3,192,155,170,184,238,84,150,88,124,174, +208,108,249,105,253,22,210,226,18,168,185,235,226,128,243,50,18,227,86, +19,13,43,223,23,149,81,96,75,230,226,64,47,239,180,94,8,83,209,167,204, +108,139,125,231,43,175,3,21,161,158,206,177,97,58,198,134,249,214,213,138, +57,67,218,236,206,41,36,101,94,60,233,241,137,44,153,159,196,170,5,41,60, +151,98,231,215,190,59,8,104,173,180,75,11,82,30,25,120,105,224,46,71,186, +156,248,69,102,204,203,62,207,4,133,11,23,7,199,27,82,236,120,76,63,230, +163,56,17,169,208,160,242,34,3,173,90,163,149,154,53,241,143,117,183,113, +99,116,32,56,238,247,60,228,155,142,107,161,53,144,171,65,210,35,3,63,91, +185,158,183,150,61,57,43,129,41,194,193,155,151,241,201,148,144,159,183, +55,51,226,243,132,46,201,48,34,131,54,164,216,41,91,188,4,191,8,245,247, +187,105,115,15,206,72,210,238,30,226,72,151,147,2,91,50,191,220,239,138, +46,188,226,134,227,109,2,249,129,172,56,189,174,34,152,227,109,238,65,118, +252,241,243,172,119,161,149,194,80,26,143,233,143,116,221,212,2,174,192, +104,79,206,154,32,56,64,129,45,25,71,102,193,156,164,154,6,28,1,151,70, +228,124,160,164,19,12,131,11,125,61,193,5,127,141,244,135,17,78,103,86, +173,217,157,83,200,166,212,172,232,147,137,212,106,139,161,207,2,126,1, +246,221,104,226,131,63,127,15,106,153,100,157,199,15,93,55,102,148,230, +211,21,207,178,115,233,74,222,207,123,42,210,237,243,106,169,209,87,54, +58,186,21,234,199,80,207,151,29,87,185,55,57,78,214,252,36,78,62,93,78, +121,90,54,243,116,216,3,203,19,11,82,56,92,244,2,47,166,102,225,49,77,246, +59,155,34,9,14,95,47,169,236,81,255,53,24,159,19,72,10,120,3,111,140,61, +62,17,128,49,159,23,215,248,48,94,211,196,30,111,35,61,126,74,186,135,126, +63,251,156,77,52,60,8,107,106,35,202,240,47,111,126,126,71,111,176,154, +138,234,79,150,43,101,214,132,190,73,9,22,131,93,217,171,120,53,227,113, +18,44,214,168,139,253,173,255,14,85,157,173,220,30,31,9,239,112,194,214, +171,101,219,107,162,27,78,195,137,61,130,124,29,217,112,172,90,83,180,112, +49,185,137,139,176,40,197,189,201,113,90,134,30,208,231,153,152,46,161, +222,107,41,219,126,40,102,203,44,106,56,241,178,66,170,67,229,154,163,141, +160,204,215,174,150,84,214,134,37,66,228,170,150,82,199,57,49,140,92,65, +170,0,223,28,128,77,144,163,202,240,47,143,4,143,249,171,8,216,234,198, +234,76,3,203,22,48,55,35,106,89,232,183,101,170,136,56,239,85,230,185,235, +37,149,61,177,48,254,5,68,165,141,10,108,236,250,76,0,0,0,0,73,69,78,68, +174,66,96,130}; + +static size_t xml_res_size_7 = 1852; +static unsigned char xml_res_file_7[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,6,222,73,68,65,84,120,218,188,87,107,136,85,85,20,254,246,62,231, +222,59,247,206,181,113,108,212,73,51,51,130,140,32,170,31,61,200,136,222, +132,40,169,101,69,66,101,15,122,64,74,15,169,8,42,168,176,172,44,168,164, +232,97,86,72,143,49,205,158,248,39,66,255,20,84,100,165,65,145,164,53,154, +81,206,204,109,230,156,123,206,61,167,111,173,125,212,123,207,204,144,70, +117,240,56,107,159,253,250,246,183,190,181,246,186,6,128,191,230,206,147, +214,90,196,51,145,166,108,202,251,95,62,134,255,12,18,248,239,205,93,250, +249,69,62,191,148,109,26,205,60,241,178,165,72,147,6,251,140,27,164,111, +54,126,132,101,82,252,19,172,169,78,49,198,226,139,215,239,154,41,123,11, +128,54,68,53,212,251,127,193,150,13,43,0,235,195,216,34,71,121,186,179, +103,129,130,117,211,19,206,182,25,154,40,113,109,89,49,109,61,223,190,246, +48,155,12,39,60,228,177,231,222,200,70,34,159,219,4,128,233,190,226,93, +108,217,253,43,112,198,114,76,232,158,130,223,215,95,201,157,139,4,98,80, +34,142,37,235,138,194,26,158,152,23,98,113,79,73,61,245,232,156,58,23,115, +27,196,13,89,60,129,37,177,150,136,19,93,155,182,109,181,27,137,65,20,69, +14,150,50,205,45,228,255,193,218,239,216,246,195,86,108,251,126,43,134, +6,251,224,179,211,231,66,190,245,200,128,65,165,189,202,183,29,150,243, +42,149,118,181,125,206,191,253,157,118,125,11,30,199,179,115,207,113,247, +226,214,55,13,121,77,208,151,183,223,178,40,249,92,211,227,137,210,198, +62,198,132,1,196,245,24,29,29,157,180,44,162,48,230,32,46,88,112,92,199, +113,130,123,207,236,229,73,98,244,15,0,247,204,24,212,239,181,26,176,244, +252,65,158,216,67,163,81,128,103,82,68,65,13,69,63,165,203,82,196,121,219, +75,245,48,150,135,75,243,0,18,175,132,142,113,19,148,144,196,248,40,149, +124,44,90,227,57,170,103,199,56,235,206,183,57,42,24,69,88,109,248,232, +161,121,40,148,44,194,48,32,213,6,30,65,141,102,147,84,100,126,217,15,96, +251,170,153,152,126,246,117,216,241,213,251,24,162,239,15,153,212,133,246, +234,24,245,43,82,30,21,60,58,23,129,231,187,87,158,70,236,222,98,164,227, +12,69,27,6,117,61,33,221,141,32,111,211,144,8,211,40,203,51,112,194,162, +77,216,185,179,23,213,115,47,68,247,225,71,34,218,112,61,150,207,174,81, +168,41,250,6,140,219,136,19,223,184,123,46,252,82,155,115,13,1,205,127, +224,77,237,147,141,60,178,23,214,3,221,200,35,237,245,156,109,116,140,115, +129,65,14,64,56,212,135,111,190,222,172,155,140,59,180,139,19,83,92,187, +218,215,168,93,62,203,138,16,84,185,157,227,186,80,108,171,232,196,122, +48,232,66,169,145,50,98,185,48,223,48,116,39,181,244,119,56,148,179,9,80, +198,73,100,49,28,90,1,68,245,8,237,149,146,106,64,194,164,66,32,43,23,36, +144,97,253,253,156,64,1,74,208,143,169,150,233,235,178,203,3,20,152,2,179, +217,201,184,89,56,20,104,146,241,76,162,126,111,177,51,1,10,144,84,25,48, +251,1,52,152,28,202,229,178,70,65,220,136,53,4,23,174,138,52,209,60,117, +137,231,0,48,216,43,20,167,231,187,137,5,153,26,215,169,9,79,253,111,69, +3,245,186,138,205,216,17,108,97,128,175,117,25,169,149,129,6,41,41,209, +183,41,1,52,24,118,18,134,149,114,73,147,76,193,11,50,0,33,142,191,248, +46,151,33,53,171,242,20,49,251,76,73,147,143,199,183,78,23,24,2,242,188, +132,126,15,135,217,34,72,25,155,101,193,166,48,76,13,218,202,21,110,104, +244,212,2,196,43,180,185,52,234,197,122,202,125,234,55,217,100,81,51,211, +54,209,194,247,125,231,130,48,212,147,202,70,46,34,154,108,97,195,100,9, +48,31,5,182,88,65,91,181,160,0,36,5,167,60,229,138,249,177,250,105,48,44, +162,231,145,219,24,186,137,10,145,228,144,21,232,194,210,47,9,120,210,248, +14,197,88,207,104,151,136,200,219,78,15,34,25,134,108,30,192,79,175,205, +199,49,167,205,70,255,207,155,17,51,17,217,73,157,184,236,133,72,7,172, +188,170,132,35,216,150,139,196,232,230,6,87,190,20,42,8,1,16,113,173,85, +11,61,141,28,137,2,35,241,78,218,131,156,237,244,0,141,4,168,188,155,68, +56,177,107,44,166,76,158,136,33,179,75,145,210,35,120,235,6,95,55,29,12, +24,13,84,251,94,6,164,111,229,2,104,90,117,23,44,179,39,67,81,194,80,124, +173,57,129,27,71,57,219,9,48,213,136,113,215,104,19,3,178,136,228,236,57, +207,13,168,47,123,110,238,192,197,207,244,113,211,20,47,47,44,227,148,171, +239,151,88,109,45,0,76,166,3,186,236,179,151,239,99,179,160,39,133,170, +61,29,102,187,44,232,106,129,97,137,72,65,48,20,229,150,219,91,144,136, +40,147,140,118,244,237,160,226,163,150,240,217,39,68,175,64,208,34,10,15, +53,138,45,74,172,18,92,11,162,97,182,176,103,108,50,92,132,178,110,196, +240,123,126,129,175,64,6,254,12,240,236,165,174,126,169,179,242,232,89, +177,172,37,116,154,105,144,240,154,54,185,11,49,239,250,37,51,246,104,156, +7,113,21,119,204,248,67,71,4,241,24,44,57,99,143,178,222,72,218,29,232, +116,152,11,160,149,74,200,100,115,194,229,247,184,211,238,165,155,127,78, +26,173,246,146,197,252,34,190,92,253,160,14,60,124,124,69,197,40,39,156, +220,85,209,80,145,156,114,68,247,33,168,199,188,150,69,43,34,70,242,146, +230,93,32,16,153,40,73,247,207,25,221,73,174,208,26,13,64,65,197,38,26, +218,232,93,129,237,219,190,215,174,169,211,142,198,57,118,53,102,63,177, +91,195,123,205,45,227,179,91,152,26,200,39,162,236,126,213,251,122,253, +139,79,114,239,88,35,224,111,235,91,17,22,147,209,81,147,15,149,124,132, +95,123,119,224,227,13,31,104,223,133,179,230,192,159,98,80,29,83,85,0,122, +11,90,151,199,82,140,0,64,228,34,7,154,181,248,97,98,25,65,112,163,49,64, +17,126,219,179,76,75,173,93,187,118,177,100,115,151,149,216,102,170,135, +158,155,164,174,48,8,162,84,43,36,185,8,61,164,35,48,160,138,207,92,112, +144,0,132,137,148,115,183,237,216,137,134,117,119,200,143,219,123,145,158, +108,113,206,195,187,181,253,225,109,227,113,222,178,221,252,59,97,248,93, +160,106,38,55,30,67,233,163,87,159,86,65,30,40,0,9,193,35,89,65,53,56,229, +246,83,123,181,0,145,185,113,50,196,248,239,192,187,139,198,105,197,20, +6,33,62,88,220,169,185,197,51,185,235,88,215,18,84,156,124,193,77,15,186, +10,232,32,24,248,110,237,99,220,48,193,233,215,220,183,127,174,172,79,125, +108,237,121,4,211,231,45,129,34,228,133,246,221,186,199,81,72,70,212,0, +180,12,199,64,175,91,228,128,126,246,24,93,84,42,99,125,250,126,105,154, +235,110,75,77,82,125,92,83,88,149,235,153,109,219,180,130,239,126,29,100, +101,120,90,198,198,181,175,224,192,127,35,186,251,117,106,247,88,109,181, +206,205,250,38,118,96,227,186,236,187,180,15,235,212,189,140,53,205,153, +208,212,62,221,244,73,85,138,80,99,14,254,231,230,111,63,237,247,200,72, +125,205,223,181,109,141,238,185,55,195,8,252,105,124,59,71,207,56,255,250, +35,20,73,174,254,209,104,121,7,48,73,163,136,255,247,145,235,245,207,191, +4,24,0,228,101,43,215,5,253,61,104,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_8 = 1017; +static unsigned char xml_res_file_8[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,3,155,73,68,65,84,120,218,108,83,107,76,28,85,24,61,51,204,192,62,200, +178,180,74,106,85,144,46,143,74,74,85,88,16,180,11,110,155,216,248,10,54, +45,93,72,140,105,13,49,77,68,34,36,45,2,41,181,42,225,33,5,234,143,254, +177,63,76,127,216,198,96,218,106,104,4,45,162,18,90,202,110,154,150,165, +181,117,97,215,2,93,118,102,217,7,236,123,102,118,188,67,72,252,227,73, +78,230,206,157,123,190,239,220,243,101,168,190,254,65,136,162,8,5,130,32, +32,22,143,127,89,110,44,237,96,24,6,118,187,29,222,213,213,31,95,42,41, +105,39,103,70,213,106,245,211,233,26,45,2,235,107,144,68,113,150,162,168, +3,140,34,148,101,121,131,130,32,94,170,124,185,220,242,246,91,111,162,171, +187,219,125,109,100,228,227,18,163,81,78,75,77,181,151,149,150,32,235,137, +39,33,72,34,34,225,8,28,142,249,226,71,203,75,142,141,2,201,100,18,146, +36,125,95,188,123,87,109,117,149,9,63,92,190,140,147,29,237,251,201,167, +191,223,63,114,212,187,179,176,0,52,69,99,226,207,73,132,195,97,132,194, +33,128,162,72,211,36,24,69,156,157,157,13,142,227,106,205,166,61,112,204, +47,160,48,191,0,173,109,29,45,26,141,246,104,52,26,213,234,116,58,220,191, +255,23,180,106,21,92,255,184,208,220,212,104,196,38,24,98,253,138,32,138, +53,150,195,7,49,247,224,33,182,232,245,120,236,118,43,174,142,16,87,107, +241,88,108,163,83,70,70,6,104,154,70,34,145,64,79,223,25,155,36,10,160, +200,59,77,46,80,179,183,186,10,179,246,123,74,24,184,117,107,6,163,99,163, +104,249,164,9,69,69,69,77,49,82,32,22,75,128,37,161,42,182,205,38,147,18, +186,44,41,161,17,69,74,69,229,43,85,235,161,72,110,102,166,30,1,191,15, +103,7,7,222,73,79,99,181,105,108,202,206,170,87,43,96,187,125,7,121,121, +6,50,157,4,52,42,21,114,178,159,65,69,121,25,12,134,92,204,88,109,65,138, +84,217,209,222,209,249,141,70,173,218,27,13,5,199,187,122,122,223,32,123, +79,25,142,159,183,165,179,236,214,241,70,51,22,22,221,120,224,88,128,213, +58,131,156,237,219,176,22,12,34,24,10,91,7,134,134,26,208,223,63,160,100, +177,131,176,84,121,234,186,38,160,59,253,243,133,67,195,243,242,141,128, +44,127,113,221,41,255,58,242,147,124,170,179,83,62,209,210,124,113,243, +156,194,130,158,207,78,130,58,119,166,15,52,153,109,171,184,135,36,42,66, +18,226,223,213,151,61,95,255,65,101,14,206,78,241,88,137,83,240,90,175, +98,244,152,25,211,55,167,197,11,172,241,219,95,238,58,245,44,203,214,42, +33,50,157,241,114,146,100,18,106,57,1,65,20,46,190,190,43,175,78,17,127, +61,229,129,63,46,195,195,251,201,68,224,187,125,99,82,180,101,84,100,181, +154,242,27,168,36,141,223,230,30,94,74,101,216,58,90,5,1,44,233,44,75,194, +240,11,207,110,171,59,177,47,15,195,247,252,240,197,146,88,226,125,240, +56,239,92,155,235,109,48,91,108,169,147,147,235,122,244,143,115,104,219, +111,192,107,249,57,22,81,18,135,233,44,157,6,10,183,166,107,14,14,29,122, +145,116,230,96,95,137,99,209,27,192,162,115,110,140,235,173,111,220,222, +125,253,46,9,89,203,249,56,248,163,18,190,154,240,224,212,187,69,27,26, +154,216,83,44,18,80,56,55,237,71,48,33,227,17,207,97,201,101,31,243,245, +30,62,214,247,105,179,51,73,165,192,253,249,129,143,188,174,217,177,101, +47,135,64,76,198,224,31,62,200,68,147,194,154,234,16,37,127,97,196,207, +155,31,7,35,207,121,86,121,4,60,174,113,190,199,242,97,87,219,113,34,166, +113,83,85,136,45,251,222,243,47,159,174,153,98,118,87,23,7,19,241,220,69, +158,199,154,119,229,119,10,255,193,64,168,223,92,251,9,23,240,255,80,70, +158,185,185,14,252,43,192,0,141,58,185,202,150,159,74,140,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_9 = 1751; +static unsigned char xml_res_file_9[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,6,121,73,68,65,84,120,218,180,87,91,136,85,85,24,254,215,90,123, +239,115,206,92,116,116,38,157,48,47,35,90,80,129,89,116,33,51,74,165,34, +6,52,20,231,33,240,33,80,8,133,30,213,232,74,15,225,99,161,4,69,15,9,65, +23,203,140,30,122,200,64,208,138,233,98,150,24,42,90,94,162,209,156,25, +103,206,204,156,115,246,109,245,253,107,175,125,206,222,211,25,60,15,181, +14,63,251,236,117,251,191,245,255,223,255,255,107,11,74,154,243,234,190, +15,15,72,229,172,215,90,211,255,217,132,16,20,71,225,161,151,183,15,108, +194,107,40,88,249,139,111,188,127,80,72,167,127,197,138,229,20,51,128,255, +11,3,180,73,0,56,113,226,44,233,56,252,226,181,231,158,126,202,65,119,137, +148,211,191,107,251,102,138,211,137,186,233,218,186,76,111,26,157,241,204, +58,115,107,120,235,199,87,175,164,61,251,62,234,103,221,12,160,24,71,177, +217,96,235,243,111,153,73,137,21,120,168,13,82,32,137,101,5,242,129,116, +138,28,10,217,104,232,41,226,233,65,185,160,192,13,104,170,84,161,192,9, +208,111,182,36,129,245,18,187,122,88,231,106,159,164,134,14,40,241,107, +130,222,124,233,89,252,55,144,139,60,91,104,44,11,35,108,231,57,244,238, +43,91,41,136,24,4,143,63,4,159,29,35,23,255,142,210,195,244,168,56,98,182, +47,64,92,218,128,255,63,144,35,75,84,131,146,145,133,23,40,154,67,20,1, +151,116,239,38,225,118,193,176,130,222,115,183,65,158,161,118,108,18,3, +123,223,234,119,8,231,37,203,53,225,24,179,224,37,8,53,22,40,242,49,169, +234,91,0,162,0,243,181,225,28,34,81,139,71,135,57,55,108,32,60,128,232, +32,165,74,164,221,73,51,92,129,193,98,70,231,97,157,219,142,227,225,212, +174,36,23,90,92,69,198,118,133,130,194,1,67,86,154,176,191,1,32,162,2,102, +177,98,118,65,204,142,133,8,99,72,153,98,229,127,164,120,161,86,88,236, +130,84,108,106,215,116,198,152,18,179,185,148,34,161,48,19,34,164,224,215, +122,43,120,0,0,19,167,209,38,19,102,104,211,233,186,78,26,43,211,152,132, +29,132,52,118,144,117,97,104,248,161,95,113,143,204,14,202,186,48,128,236, +118,172,35,8,67,210,148,1,192,104,124,116,186,142,99,24,157,227,172,81, +172,140,58,202,1,144,38,164,164,129,34,76,167,200,1,80,117,0,217,208,98, +29,126,24,215,45,224,52,0,196,13,11,104,202,88,34,221,89,24,211,11,145, +181,128,74,237,208,240,141,25,132,77,160,88,243,233,101,222,154,198,2,193, +116,14,144,54,157,6,128,206,4,48,9,123,114,97,50,152,152,110,1,134,33,44, +0,101,215,240,160,163,12,8,33,99,195,5,193,134,180,137,130,35,205,184,32, +11,192,112,0,157,94,157,3,169,21,68,114,100,145,170,204,0,16,202,192,83, +134,1,42,217,201,77,66,68,184,46,107,66,56,34,178,48,207,197,22,30,3,136, +56,10,0,32,106,226,130,192,184,64,82,190,20,228,207,204,135,84,34,57,172, +50,220,119,17,142,78,194,129,9,68,64,0,193,160,30,27,36,25,118,80,36,125, +58,89,189,151,62,27,177,233,18,227,253,91,101,46,10,26,0,208,233,57,174, +209,217,160,128,74,34,192,18,141,149,59,214,56,19,52,73,99,250,34,77,196, +62,226,251,42,209,105,28,176,4,97,43,208,53,76,98,166,87,40,18,149,36,115, +177,5,0,160,8,235,248,198,5,212,0,192,113,95,139,216,5,170,73,38,183,236, +2,16,108,69,151,180,177,36,222,135,1,176,140,83,58,141,217,142,37,162,57, +85,178,206,112,72,155,116,107,128,123,94,146,136,226,188,5,40,33,161,231, +228,84,55,78,95,33,95,143,154,76,38,172,27,132,45,51,156,37,117,179,18, +37,40,71,104,157,141,2,63,110,146,9,131,216,48,148,67,152,73,156,112,16, +190,138,203,224,96,100,84,165,7,227,108,41,204,12,196,143,212,117,77,138, +247,141,44,119,209,39,177,111,253,126,17,89,147,115,30,168,54,18,81,61, +10,66,84,138,246,146,162,118,213,48,99,140,234,23,83,213,76,18,230,252, +105,127,186,99,144,171,221,179,38,237,56,120,160,149,15,64,62,69,126,148, +73,68,194,228,235,127,39,34,252,34,132,70,215,108,55,151,54,239,184,111, +45,117,247,44,166,8,12,94,57,188,140,244,96,99,236,133,7,214,210,169,238, +37,80,162,192,183,113,227,227,180,173,25,216,76,65,97,22,69,97,141,182, +109,185,147,244,19,141,177,67,131,14,85,107,97,179,76,24,26,23,100,155, +82,21,212,147,49,227,231,80,130,7,246,204,92,13,71,49,54,162,174,35,16, +81,148,162,169,252,186,145,9,84,197,8,0,2,170,141,84,97,67,84,194,72,112, +109,50,42,253,160,41,0,248,12,87,142,225,234,53,36,49,166,172,130,85,118, +163,118,187,73,4,201,128,46,169,17,132,85,68,10,99,187,162,157,228,98,12, +201,142,100,132,190,43,35,230,25,163,244,69,7,62,78,158,32,139,31,248,116, +249,175,97,240,38,6,121,5,220,92,164,161,225,241,60,9,57,205,242,235,79, +191,13,67,254,206,148,3,244,219,234,196,110,210,66,215,125,41,116,18,7, +41,5,132,185,69,105,147,57,181,176,25,84,219,117,118,140,245,40,176,188, +88,240,234,21,215,228,149,169,242,216,177,159,191,251,118,149,142,227,230, +87,66,109,57,155,62,51,253,211,203,183,176,239,162,73,89,79,223,4,64,84, +38,198,143,217,252,72,157,144,69,144,158,122,84,204,220,228,150,29,187, +215,47,233,91,190,177,216,57,167,55,59,80,45,143,14,253,241,251,217,79, +246,239,125,253,16,205,124,71,77,91,152,164,75,186,40,172,210,146,185,73, +54,191,244,26,208,107,250,7,22,61,242,228,198,193,9,228,139,123,238,186, +149,206,195,175,217,76,179,244,230,110,58,126,226,12,181,57,146,142,124, +249,233,253,135,63,255,224,2,205,124,193,231,126,230,102,197,177,104,202, +86,102,106,133,85,143,109,24,210,133,34,114,121,76,157,179,58,104,221,130, +121,117,38,179,111,175,150,167,200,3,193,52,204,251,224,186,245,223,0,64, +59,134,106,55,250,84,112,90,252,164,104,11,16,82,203,22,206,167,242,100, +133,206,158,187,76,103,166,125,65,49,136,121,61,93,52,167,179,131,126,253, +229,148,178,119,250,255,12,128,27,162,94,247,205,159,43,145,75,105,116, +124,146,42,190,159,227,96,9,245,191,103,118,7,133,65,64,199,185,182,39, +183,131,27,54,213,34,0,175,60,62,250,253,148,156,53,224,224,138,117,91, +223,2,186,125,233,45,180,184,119,46,164,155,22,245,246,96,163,152,78,158, +62,79,95,31,253,145,14,31,220,191,233,234,159,23,206,89,63,223,232,107, +173,165,198,21,125,62,71,203,166,109,59,119,116,245,244,174,115,92,183, +59,107,2,156,124,248,250,181,161,175,14,188,189,103,47,179,27,114,165,21, +23,180,10,64,216,12,220,5,185,9,50,219,130,202,94,121,89,217,24,132,51, +217,117,136,79,45,124,230,182,10,32,235,178,162,85,238,52,137,237,154,53, +123,212,234,134,255,8,48,0,163,88,200,134,33,243,7,106,0,0,0,0,73,69,78, +68,174,66,96,130}; + +static size_t xml_res_size_10 = 1855; +static unsigned char xml_res_file_10[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,6,225,73,68,65,84,120,218,196,87,123,80,84,85,24,255,238,115,31, +160,41,169,37,175,196,16,28,21,75,108,20,21,195,200,124,128,111,39,49,205, +7,154,38,249,154,177,153,242,143,254,232,53,163,142,53,227,24,67,89,227, +148,96,36,166,228,35,95,164,136,104,68,89,249,2,53,65,65,212,69,151,213, +117,217,221,123,239,62,238,189,125,231,238,93,220,20,84,172,198,157,249, +102,239,185,247,156,243,253,206,247,251,94,135,82,85,21,30,231,143,250, +151,235,185,241,175,229,92,197,255,110,12,195,216,119,108,206,125,10,159, +125,237,217,128,121,84,224,47,101,78,143,75,30,146,110,27,147,145,17,54, +120,200,16,56,117,226,132,41,50,246,217,163,245,53,213,117,237,217,136, +126,4,229,244,152,169,243,102,71,197,198,93,202,156,56,17,142,149,151,131, +44,203,160,42,10,72,130,139,107,239,158,108,59,149,51,25,211,22,108,141, +239,149,48,165,95,82,18,148,150,148,128,71,146,208,30,1,38,21,69,161,117, +0,242,255,1,128,203,156,182,240,242,144,212,212,238,70,163,17,126,173,172, +4,142,227,128,161,67,15,220,170,67,115,230,101,165,215,17,221,53,33,119, +228,192,187,125,132,126,40,190,51,178,226,38,207,90,234,205,156,48,161, +59,58,27,212,92,184,160,41,55,153,205,96,68,1,140,36,181,109,143,230,132, +245,233,131,128,162,227,17,136,131,140,219,3,128,30,61,37,123,86,247,152, +30,26,223,54,155,13,44,22,11,24,77,38,77,120,131,1,12,104,141,214,66,153, +75,91,222,17,21,90,77,11,126,200,198,161,71,248,44,125,56,248,164,75,230, +197,7,246,135,90,254,126,0,152,177,175,190,81,212,43,177,247,166,87,70, +143,134,134,250,122,112,58,157,96,34,202,81,169,1,149,27,117,105,13,128, +98,57,101,80,221,183,126,164,76,157,114,205,57,123,215,224,171,27,194,231, +25,51,129,225,134,153,230,22,78,15,234,38,72,216,171,27,83,118,240,148, +63,147,5,63,92,176,135,195,59,71,147,192,196,248,33,101,232,80,136,138, +142,134,250,186,58,77,9,81,126,143,34,244,126,85,231,159,82,149,22,36,114, +77,153,40,214,148,173,226,82,23,149,114,201,89,5,166,236,162,74,241,235, +172,98,127,245,190,121,108,223,140,111,113,202,118,20,145,0,48,113,224, +207,236,154,93,136,123,200,48,152,146,97,122,172,3,76,172,31,68,193,5,215, +209,228,132,111,138,106,157,97,2,140,8,165,146,35,41,154,207,240,243,183, +15,98,195,58,239,146,47,28,30,231,217,255,81,37,221,241,233,101,76,124, +218,122,252,182,217,123,104,109,37,219,103,172,100,156,181,105,154,84,48, +167,128,152,1,73,196,133,126,23,216,74,94,7,225,240,108,104,178,218,192, +106,181,130,219,237,214,156,140,240,77,184,110,77,200,55,208,40,64,16,1, +91,80,190,109,75,235,193,239,109,98,18,210,143,227,248,150,103,239,251, +251,65,246,93,53,205,223,182,2,199,130,234,188,94,68,133,117,33,190,193, +209,45,206,171,72,96,140,136,2,99,231,72,220,212,172,153,59,200,247,125, +5,231,168,119,232,144,53,163,56,44,94,33,111,204,12,213,43,156,49,231,236, +219,138,239,156,202,141,243,95,80,230,8,2,64,149,175,157,222,75,241,230, +52,114,248,128,19,170,148,6,192,208,169,27,208,157,187,1,75,51,192,178, +40,204,253,133,132,36,153,27,36,199,239,247,41,244,146,35,249,166,37,7, +139,113,104,247,253,178,113,37,112,198,151,53,165,13,191,87,32,143,102, +114,96,185,182,188,90,95,194,135,36,34,9,29,212,136,70,81,192,106,191,9, +102,222,139,156,62,184,82,146,12,16,23,254,76,208,2,172,146,155,182,18, +150,149,145,122,32,249,79,21,159,229,211,150,6,104,249,45,191,150,75,201, +14,56,104,93,133,61,152,99,2,0,52,7,147,192,121,173,6,194,13,42,88,155, +250,67,56,239,3,154,82,31,168,92,65,199,239,25,219,67,99,146,97,208,115, +255,89,105,165,144,20,233,11,121,150,239,74,197,56,87,149,128,229,205,192, +24,85,112,139,2,80,202,195,1,144,101,37,16,33,58,15,244,194,61,239,129, +226,111,210,162,33,125,69,116,112,46,159,254,118,76,107,249,250,14,5,178, +0,124,199,206,232,22,42,112,200,63,143,9,147,0,104,43,252,130,33,40,51, +74,232,145,121,229,203,204,143,69,0,146,120,84,182,247,168,13,170,228,60, +74,62,209,145,73,195,112,129,155,60,27,38,173,29,216,138,5,68,224,194,35, +0,12,50,2,96,129,193,47,12,57,24,2,104,51,7,144,116,41,203,45,3,154,97, +201,196,219,252,196,181,73,108,204,128,82,124,17,45,230,141,233,75,190, +210,79,68,173,80,155,27,183,107,96,58,69,167,130,79,172,214,64,6,236,134, +193,64,232,195,40,0,228,62,101,224,64,116,66,63,8,238,102,184,120,185,1, +129,43,109,128,64,11,224,218,96,42,166,104,154,152,67,84,89,158,198,184, +23,189,63,111,152,68,162,193,48,249,211,254,120,162,24,113,211,204,85,90, +204,133,117,153,163,216,106,191,34,129,163,1,240,3,237,108,218,82,212,129, +65,223,248,203,30,6,133,71,45,152,9,125,48,224,249,254,144,152,152,8,87, +26,27,193,227,241,220,3,130,168,165,21,165,197,136,138,94,90,124,219,151, +87,163,199,141,35,96,12,25,31,68,48,49,201,37,138,237,210,58,28,55,27,167, +174,75,70,48,145,82,81,206,102,226,164,4,128,55,106,94,197,136,119,167, +196,14,243,248,20,181,131,65,165,202,119,148,157,35,91,58,237,19,231,98, +54,156,241,92,114,50,88,111,218,64,148,60,247,148,92,18,5,90,58,38,121, +144,162,41,29,151,147,236,107,90,180,103,53,38,156,28,85,116,148,75,133, +243,243,136,66,58,170,127,177,114,253,220,135,250,28,15,1,64,28,163,126, +77,113,67,147,94,161,20,205,40,72,111,197,161,157,107,154,111,223,60,109, +183,219,87,15,31,49,2,4,73,4,151,219,125,143,35,234,15,161,134,241,50,253, +198,119,64,229,111,42,214,154,92,105,203,194,13,248,206,129,89,241,123, +240,121,234,164,173,111,21,232,0,20,86,143,79,146,24,28,33,0,20,253,185, +185,234,143,99,197,183,154,26,235,93,46,215,38,4,97,232,18,241,36,56,176, +44,7,21,170,161,32,66,126,114,213,110,159,80,181,187,143,62,188,109,94, +252,83,9,58,101,111,236,11,94,208,245,73,161,97,24,76,14,161,189,156,172, +163,244,91,26,46,122,177,229,30,41,184,93,249,169,47,166,197,69,98,137, +118,186,92,90,41,134,182,27,50,140,70,104,36,84,98,19,114,0,25,138,68,229, +41,56,182,145,131,233,135,124,168,182,220,175,111,230,185,120,254,100,137, +76,241,145,72,123,66,207,248,120,80,176,124,211,20,173,85,197,234,51,103, +64,112,53,127,119,237,114,237,69,125,115,114,0,15,177,164,108,57,125,196, +123,232,147,124,93,249,205,208,190,240,97,239,5,178,110,50,233,114,237, +217,227,152,252,110,55,55,187,83,123,37,36,2,139,189,2,41,76,213,85,85, +8,192,17,10,160,37,63,169,206,27,162,110,77,199,221,77,105,123,186,98,178, +240,22,249,255,179,226,224,55,141,87,46,157,20,4,97,203,200,81,163,32,60, +44,12,83,9,77,170,35,211,198,58,223,127,121,53,11,52,49,120,29,67,137,205, +204,90,184,147,166,153,78,152,35,156,187,10,243,72,214,179,180,231,94,240, +168,119,67,178,142,71,233,138,18,137,18,166,155,183,94,247,112,245,255, +6,208,210,125,235,202,57,221,204,238,246,94,78,31,251,239,111,1,6,0,48, +107,244,198,77,151,19,83,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_11 = 869; +static unsigned char xml_res_file_11[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,3,7,73,68,65,84,120,218,236,151,223,75,20,81,20,199,207,157,157, +31,251,83,77,122,176,151,232,7,130,73,245,188,161,137,17,26,5,82,244,22, +81,36,98,136,32,21,253,29,81,17,136,36,98,37,209,147,82,8,69,74,36,166, +228,115,5,9,210,22,61,7,169,59,174,59,59,59,247,118,206,29,119,221,93,117, +118,87,150,246,101,239,114,119,118,239,143,115,62,243,189,231,156,217,101, +66,8,168,102,83,160,202,173,6,80,3,168,58,0,243,152,211,39,94,190,178,228, +34,198,246,101,60,147,226,55,174,95,51,240,146,42,71,1,125,252,249,132, +213,218,218,10,182,237,64,58,205,129,115,81,86,167,61,180,151,108,144,45, +178,89,170,2,250,232,216,184,21,141,70,225,203,215,111,16,14,133,209,160, +3,249,74,236,165,136,200,187,115,69,241,129,185,97,194,233,83,39,97,105, +105,9,250,251,122,119,40,81,104,73,31,25,29,179,58,59,58,224,251,242,178, +28,104,111,59,3,235,235,235,176,182,22,135,100,50,9,137,205,77,79,217,131, +129,0,248,253,126,168,175,143,64,93,93,29,44,44,126,150,227,39,90,90,96, +110,126,30,6,250,251,242,32,114,1,244,225,145,167,86,119,119,23,172,172, +252,216,154,18,104,204,128,3,13,13,16,137,68,64,215,53,48,12,195,19,192, +178,44,72,165,108,136,199,227,240,119,117,21,161,173,172,173,230,230,227, +48,51,51,11,131,3,183,179,16,25,0,253,241,147,97,235,202,229,30,136,253, +252,85,16,72,180,85,184,178,150,250,220,192,163,162,227,146,175,2,141,143, +29,61,2,175,223,76,195,157,161,65,9,65,211,234,131,135,143,166,122,111, +221,236,177,237,116,246,28,119,59,94,81,78,106,177,189,103,53,77,133,241, +103,47,166,239,223,187,123,85,197,145,128,207,167,246,152,102,2,222,190, +123,47,23,8,193,161,210,79,73,169,8,83,228,157,92,186,120,1,200,39,249, +38,0,131,115,142,105,147,150,193,67,110,187,206,159,147,0,172,88,165,40, +169,24,184,202,17,192,236,135,143,210,28,249,34,159,228,155,0,20,250,98, +227,32,5,24,71,199,220,225,48,247,105,1,211,72,169,132,127,233,172,243, +108,59,6,177,14,10,130,216,219,0,10,1,64,70,1,85,85,229,6,51,177,1,145, +112,8,1,88,69,36,160,194,68,54,53,77,43,84,0,178,0,60,237,200,5,36,125, +10,83,39,16,8,238,187,4,239,86,146,201,166,134,55,72,54,201,87,1,0,82,98, +224,81,158,19,177,237,56,16,10,21,1,16,185,149,156,123,10,69,0,100,211, +48,52,169,40,249,34,159,249,10,224,32,41,64,45,22,139,121,58,151,249,45, +84,80,28,183,40,113,159,5,130,165,101,189,240,130,104,108,108,116,215,75, +128,130,35,16,130,242,211,53,216,212,116,168,72,158,51,116,238,207,27,227, +190,164,39,64,166,168,185,87,150,15,64,116,20,128,225,112,208,77,191,98, +71,47,92,5,124,220,5,118,20,82,0,55,177,226,0,164,172,12,118,177,125,4, +194,52,227,139,147,147,83,109,52,88,74,253,97,59,62,137,156,247,162,85, +90,66,36,18,27,139,238,173,0,68,176,31,198,126,48,163,200,127,104,84,243, +255,96,255,205,182,156,6,176,251,43,144,244,229,212,167,36,246,205,106, +255,36,196,176,169,253,53,171,1,84,185,253,19,96,0,249,4,138,17,171,4,193, +66,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_12 = 634; +static unsigned char xml_res_file_12[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,28,73,68,65,84,120,218,140,146,205,107,19,65,24,135,159,217,221,144, +108,194,162,104,244,80,177,181,136,32,130,7,169,90,240,82,197,34,86,91, +47,90,68,122,240,31,240,32,166,135,10,122,18,145,106,251,23,136,246,224, +65,76,27,15,106,81,36,82,5,123,144,106,148,94,10,173,45,181,133,32,10,37, +181,77,52,217,143,113,38,9,82,37,196,188,48,187,204,204,251,252,222,175, +17,119,239,141,224,251,1,134,33,80,38,195,225,48,245,172,88,44,234,159, +8,2,137,105,26,88,122,23,4,129,22,145,61,221,167,89,252,178,84,87,96,87, +75,51,79,159,141,75,33,12,161,5,12,13,151,92,87,158,233,233,86,240,178, +22,71,136,218,75,223,105,31,237,171,25,205,90,190,239,39,47,246,93,192, +245,60,246,238,217,77,67,166,196,52,243,48,57,154,180,60,207,235,93,93, +91,231,249,139,151,213,91,249,63,186,252,237,58,121,2,205,234,12,40,150, +138,216,81,155,206,99,71,21,47,171,62,226,31,76,84,191,130,244,196,107, +93,2,129,95,41,1,183,228,18,181,35,120,234,112,42,243,241,79,189,149,108, +53,98,98,138,48,66,134,56,220,214,198,166,216,118,112,67,200,64,160,74, +240,209,34,145,136,77,110,109,149,120,124,107,85,160,18,87,245,154,144, +112,72,103,175,146,89,121,194,253,113,117,106,64,71,248,60,120,93,149,12, +116,55,99,177,40,179,179,159,55,192,58,186,158,115,148,169,31,215,200,57, +105,78,29,129,246,29,9,222,101,135,153,158,123,68,200,254,134,165,97,211, +178,112,28,167,188,254,110,182,138,142,195,131,76,154,227,205,176,94,128, +253,91,134,120,53,55,204,62,181,127,155,155,192,202,231,243,111,82,169, +199,29,82,202,26,253,86,181,7,14,102,11,28,106,234,231,96,211,157,242,249, +229,118,201,135,236,0,147,159,6,203,157,210,195,223,92,111,112,125,35,188, +63,208,10,5,23,174,119,74,110,164,5,209,16,76,47,128,117,243,214,237,249, +90,209,193,80,209,109,102,90,47,81,248,202,216,124,152,115,59,227,48,185, +56,128,165,220,23,178,240,115,133,148,85,247,205,72,83,141,14,198,18,36, +122,135,16,249,95,156,157,89,30,212,15,177,12,143,246,115,69,208,184,169, +182,177,109,195,254,187,90,75,162,118,250,141,219,111,1,6,0,80,239,219, +105,146,138,192,9,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_13 = 632; +static unsigned char xml_res_file_13[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,26,73,68,65,84,120,218,164,83,61,111,19,65,16,125,179,187,103,7,131, +81,8,4,10,155,68,20,72,161,224,67,73,68,75,19,104,41,40,144,16,162,129, +34,5,13,255,0,209,210,128,132,172,132,134,6,148,54,13,66,164,65,66,162, +76,224,226,2,100,36,7,35,36,155,96,130,125,150,239,156,203,221,46,179,119, +206,23,208,32,143,116,186,189,157,153,247,102,222,204,145,49,6,131,152, +192,128,166,202,243,51,139,58,10,175,26,29,39,23,36,36,72,170,50,145,56, +199,95,251,163,169,127,67,132,109,159,178,201,231,103,159,1,91,81,26,36, +37,86,158,220,56,203,32,134,232,15,0,78,34,33,32,84,230,19,19,157,73,0, +140,214,156,188,137,176,242,16,198,16,156,194,53,76,206,62,231,230,250, +201,22,100,27,200,190,148,130,91,186,53,33,73,76,241,253,178,74,28,166, +203,142,3,236,151,136,214,95,241,197,203,36,150,24,196,196,26,65,199,239, +151,110,144,41,92,231,120,131,142,31,94,204,31,204,90,0,118,197,62,132, +51,196,71,105,139,220,97,214,172,75,229,157,139,160,213,177,44,236,225, +137,209,125,8,169,144,115,156,18,235,246,32,5,160,77,75,135,160,29,32,233, +59,165,67,109,165,130,209,177,17,28,191,89,2,18,145,77,250,88,191,147,129, +59,119,251,152,178,101,34,242,240,249,173,139,238,47,111,87,47,214,99,124, +234,52,142,20,142,98,171,250,136,171,214,73,233,22,64,230,138,8,197,4,154, +237,112,73,89,102,191,190,198,202,2,211,247,22,184,157,184,175,150,68,252, +181,4,109,120,85,40,147,150,159,0,107,6,24,71,235,227,42,190,172,247,94, +40,158,55,58,245,26,14,23,121,42,221,42,116,115,137,67,69,10,34,179,124, +218,187,107,172,3,49,211,208,33,252,172,186,184,243,248,195,98,210,66,187, +241,13,197,233,75,220,74,29,148,205,115,170,216,29,225,62,99,0,103,4,126, +99,13,223,27,205,215,171,243,51,158,178,65,193,70,11,185,83,39,129,94,139, +7,49,140,191,54,112,175,101,135,177,177,252,30,181,31,189,133,19,163,76, +230,206,93,246,120,96,121,29,197,176,75,101,118,54,230,223,102,139,50,36, +218,147,119,223,140,149,159,94,241,108,228,133,68,177,255,51,187,247,110, +186,91,3,254,206,191,5,24,0,171,203,191,162,234,194,67,169,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_14 = 685; +static unsigned char xml_res_file_14[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,79,73,68,65,84,120,218,100,83,61,108,82,81,20,254,30,63,15,144,194, +98,52,154,70,156,28,108,73,140,198,166,49,52,142,226,166,198,196,132,142, +154,176,72,88,93,89,93,136,65,106,28,180,12,38,52,150,69,55,113,174,49, +93,52,8,117,176,46,98,26,45,196,193,247,158,240,248,125,158,239,218,71, +16,110,114,184,156,243,125,231,231,158,115,158,134,153,83,40,20,54,70,163, +209,93,199,113,130,174,77,211,52,219,235,245,110,102,179,217,251,211,92, +225,64,115,149,98,177,120,173,223,239,87,19,107,107,136,199,227,56,22,10, +77,136,157,110,23,141,70,3,239,118,118,160,235,122,50,147,201,188,253,47, +0,157,37,75,53,181,190,14,201,132,111,205,38,186,93,27,154,199,3,103,60, +70,40,20,196,217,88,12,82,25,182,202,101,58,170,32,12,224,97,0,102,78,165, +82,176,237,30,190,236,127,21,226,24,225,112,24,229,242,150,186,169,211, +78,156,60,242,221,234,60,124,115,34,145,128,215,167,227,176,221,150,108, +33,44,44,132,241,236,249,38,86,46,175,168,155,58,237,196,201,35,159,126, +42,192,112,56,188,183,180,188,140,118,171,141,160,174,99,65,50,110,60,121, +138,171,210,139,131,131,239,234,166,78,59,113,242,200,167,159,10,32,18, +32,56,26,15,17,12,6,241,168,240,24,215,147,73,116,165,220,197,197,51,234, +166,78,59,113,242,200,167,31,127,124,238,91,216,60,202,169,147,39,240,166, +90,157,157,174,178,187,156,233,51,9,224,247,251,21,152,78,167,17,8,4,224, +241,112,64,20,7,99,105,162,221,235,73,19,109,197,155,13,208,55,76,83,103, +121,124,207,203,237,10,76,211,152,171,32,18,137,226,246,173,155,240,249, +124,16,190,26,158,10,96,154,230,171,207,123,123,119,46,92,188,4,91,22,198, +248,109,226,199,225,207,185,0,167,199,242,76,201,206,105,212,62,126,0,253, +92,44,150,207,231,157,86,171,237,116,58,93,199,178,254,56,178,68,142,204, +124,34,212,45,203,82,56,121,228,211,207,93,164,102,189,94,207,84,42,219, +176,44,19,126,221,175,54,110,48,24,76,132,186,95,70,72,156,60,242,233,55, +105,98,169,84,122,193,187,215,235,21,87,87,175,96,105,233,188,188,57,242, +111,215,53,141,229,162,86,251,132,221,221,247,202,217,229,227,168,205,238, +137,138,156,203,229,114,15,162,209,232,13,249,175,79,97,125,195,48,94,11, +246,80,254,239,139,24,115,95,227,212,137,137,28,63,90,50,247,72,11,241, +203,45,123,250,115,254,43,192,0,120,74,65,201,19,184,212,222,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_15 = 1507; +static unsigned char xml_res_file_15[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,5,133,73,68,65,84,120,218,164,87,91,104,28,101,20,62,51,187,155, +236,230,158,77,210,52,218,180,138,109,76,177,105,161,96,125,17,159,4,81, +4,193,7,171,40,98,193,82,237,139,216,168,120,125,200,67,40,105,107,131, +68,107,193,104,180,10,26,168,20,193,90,16,108,169,109,173,13,84,107,45, +33,109,18,91,55,27,211,53,183,221,77,246,58,55,207,247,207,76,50,89,102, +147,221,56,112,216,221,249,207,249,206,247,159,219,255,175,100,24,6,229, +62,146,36,145,203,35,189,127,244,216,3,165,126,255,235,146,236,121,148, +117,2,146,44,145,71,146,73,51,116,50,116,131,24,43,101,232,218,169,76,58, +125,176,253,165,231,47,177,141,225,6,228,244,41,21,66,96,111,251,91,53, +247,181,109,63,87,81,89,177,101,199,214,86,90,215,212,72,21,229,1,177,118, +184,183,159,246,189,184,83,124,159,79,164,40,60,17,161,129,171,67,52,63, +55,127,45,22,155,121,242,237,87,246,140,228,18,89,226,19,63,114,197,201, +165,227,96,207,198,15,191,56,110,92,25,188,110,184,61,29,221,189,174,239, +161,15,187,247,246,119,111,2,78,46,1,91,188,180,252,83,18,92,179,118,248, +161,29,219,168,173,117,35,233,186,198,98,26,202,178,76,30,143,135,210,169, +148,80,212,52,172,233,34,122,50,167,102,219,230,22,146,57,61,103,7,140, +27,188,236,103,201,184,57,144,151,113,238,233,250,168,175,179,101,195,157, +236,252,30,82,21,133,20,69,93,112,100,176,224,73,167,77,92,252,198,123, +172,67,15,250,176,131,253,161,163,199,142,2,175,88,2,126,191,191,172,125, +75,203,221,12,166,145,170,233,98,247,16,100,84,146,76,211,76,38,99,213, +141,44,34,109,235,64,31,68,182,114,228,124,190,210,23,120,49,80,12,1,249, +221,206,195,79,4,252,165,84,89,81,70,170,234,216,57,87,60,50,122,241,247, +63,169,251,211,126,186,183,117,19,29,249,242,4,253,122,229,154,72,52,214, +237,72,168,170,70,85,149,101,116,71,99,29,189,217,113,224,241,220,90,192, +147,175,6,60,89,69,169,107,8,86,17,183,156,233,220,42,78,228,216,195,180, +135,111,142,209,238,167,30,35,188,70,206,63,248,252,56,221,223,182,121, +161,70,236,98,67,157,0,167,58,88,255,44,191,58,145,91,11,249,8,120,171, +107,131,143,84,85,148,51,101,137,52,46,62,195,65,0,223,51,156,251,88,60, +206,107,58,121,217,137,146,85,68,183,153,17,176,116,17,74,214,175,175,173, +166,146,82,255,195,252,179,180,80,2,62,159,215,183,189,154,195,39,138,139, +35,96,56,102,4,156,128,64,34,153,100,2,220,74,28,146,108,54,43,66,111,138, +163,149,217,182,134,211,104,152,157,80,82,104,10,124,178,215,215,212,24, +172,225,208,235,166,115,199,124,16,17,200,100,41,197,131,71,51,108,2,138, +217,219,86,10,36,147,45,218,131,68,221,154,246,114,193,53,32,1,216,231, +21,253,238,156,94,72,9,162,128,29,39,82,73,107,38,72,156,130,172,136,185, +196,250,50,153,4,160,43,51,57,172,75,134,235,84,206,59,138,215,236,239, +249,44,18,137,76,81,137,223,79,229,1,63,5,202,203,24,204,35,114,106,14, +33,123,51,38,33,56,84,181,197,90,65,42,146,201,148,72,149,194,51,161,161, +190,150,218,247,60,215,200,75,255,58,125,230,157,132,94,175,143,246,237, +222,73,149,85,85,86,251,229,18,181,59,106,177,224,12,59,83,18,45,137,64, +60,22,167,254,31,206,186,251,201,71,0,173,151,97,230,82,34,41,118,108,228, +9,225,114,15,34,3,242,89,85,17,159,69,17,128,67,49,86,185,216,188,37,190, +85,19,80,185,56,53,71,106,10,39,192,165,43,177,13,162,32,123,61,171,38, +192,3,141,69,37,210,221,237,243,141,98,35,149,74,93,191,61,61,43,170,29, +206,23,123,188,112,129,29,236,103,227,115,148,100,60,183,11,74,62,2,90, +54,155,30,139,70,19,230,208,201,20,79,194,158,21,152,35,192,1,30,112,11, +37,160,78,69,38,206,128,57,170,153,163,177,170,8,192,14,246,192,1,30,112, +11,37,144,253,233,212,119,39,39,103,162,100,48,130,162,42,34,151,246,73, +183,242,238,117,161,15,59,216,3,7,120,192,45,152,192,173,191,134,167,230, +19,233,76,44,54,47,58,154,239,120,124,38,232,43,166,66,172,179,94,98,62, +33,128,96,15,28,224,21,67,0,77,155,137,206,76,158,28,143,76,139,218,193, +113,28,103,18,56,227,209,33,112,146,43,120,143,117,232,225,148,68,201,193, +30,56,214,41,168,23,115,35,202,12,92,56,243,73,104,124,82,40,73,214,92, +136,207,205,81,42,157,182,28,88,103,63,214,144,115,126,143,117,232,65,159, +143,0,130,61,112,86,115,39,76,95,60,119,122,48,26,139,142,142,132,38,112, +176,91,163,214,88,112,52,203,247,129,40,11,62,109,98,226,68,132,38,235, +143,132,254,33,216,3,7,120,197,18,64,197,206,253,248,253,183,175,14,141, +134,173,203,167,177,144,231,124,162,91,161,215,56,21,67,163,227,4,123,224, +184,117,192,74,4,176,225,196,111,3,23,174,134,67,55,191,186,244,199,13, +51,180,142,123,159,91,245,99,29,55,168,243,151,7,9,118,176,7,78,190,127, +73,242,10,211,20,247,172,153,222,158,174,174,112,56,252,243,47,151,135, +204,123,30,31,78,246,17,108,159,132,230,93,209,60,180,160,7,125,216,193, +222,194,41,234,62,176,228,114,194,82,205,178,126,215,203,175,189,209,188, +254,174,103,54,52,55,210,186,181,245,84,230,47,17,249,6,149,100,58,75,225, +219,83,244,247,88,132,198,66,183,190,238,251,248,208,1,182,9,161,19,115, +39,96,209,255,13,173,67,171,138,165,169,54,88,223,252,244,174,189,239,212, +212,212,61,40,138,109,225,252,151,120,228,78,159,255,166,239,72,231,236, +204,20,198,46,87,46,197,221,114,191,26,2,118,36,240,231,162,134,165,193, +34,228,205,41,90,56,156,100,137,98,130,187,205,254,255,67,192,25,141,128, +117,197,150,115,135,151,229,88,93,14,192,233,243,63,1,6,0,218,58,168,206, +121,36,62,30,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_16 = 1971; +static unsigned char xml_res_file_16[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,85,73,68,65,84,120,218,156,87,123,76,149,231,25,255,125,215,115, +225,28,64,4,228,182,34,76,81,196,203,172,174,42,118,118,217,186,46,198, +75,170,105,154,213,206,118,107,27,99,155,45,157,201,178,196,54,248,135, +108,251,103,174,29,75,237,76,219,117,235,26,187,49,131,98,129,182,75,183, +214,86,165,245,194,102,13,181,5,122,40,194,17,116,28,176,128,192,185,125, +223,183,231,249,46,120,14,112,16,247,145,31,129,247,253,158,247,249,61, +247,247,19,48,203,103,245,238,154,116,247,220,226,39,116,81,122,84,135, +184,220,48,0,131,126,248,17,248,71,0,68,232,23,69,93,123,45,60,112,249, +149,243,135,158,30,158,205,185,194,173,246,215,237,249,83,169,232,203,174, +119,169,234,210,205,171,138,176,186,52,7,107,22,100,67,149,146,69,163,154, +129,51,95,132,112,46,208,143,166,127,7,17,137,70,91,245,27,161,251,63,122, +254,199,157,128,205,244,54,9,72,119,87,189,249,162,162,170,187,126,182, +169,2,91,87,22,65,163,197,174,235,26,122,71,52,140,68,245,164,151,253,170, +136,2,191,132,249,115,36,72,244,255,241,150,32,106,222,254,20,177,104,244, +165,83,213,91,159,162,37,237,118,8,40,149,251,154,46,175,89,144,155,95, +253,131,85,68,95,192,133,171,97,116,14,198,77,87,11,211,8,26,14,232,87, +105,150,130,111,228,187,160,107,58,246,213,182,224,124,160,191,239,244, +254,77,197,180,29,155,13,1,101,109,85,67,215,147,247,85,20,236,188,187, +4,29,131,26,254,211,23,6,157,5,145,149,11,169,89,59,4,116,130,36,2,43,243, +221,88,144,37,225,213,19,29,120,245,189,246,222,143,170,55,207,159,76,66, +158,106,121,99,247,174,123,151,228,61,68,202,155,123,162,232,30,138,129, +195,173,72,183,78,24,199,36,135,72,75,111,24,253,163,10,118,222,179,144, +188,97,20,136,66,99,247,233,253,155,239,72,36,33,37,198,188,114,111,221, +161,187,22,21,110,216,179,165,2,231,130,81,92,25,137,67,38,237,18,153,46, +10,156,233,22,68,81,36,88,153,47,36,172,79,236,155,239,88,24,142,232,184, +17,53,176,113,69,46,46,94,254,202,167,86,108,44,232,57,249,247,38,39,49, +29,2,194,138,157,213,139,50,10,74,254,88,243,216,122,74,50,157,226,29,131, +76,110,148,28,183,219,144,104,65,165,13,153,124,108,133,195,176,114,66, +152,10,209,6,147,112,209,251,247,86,228,161,190,229,202,157,25,69,139,254, +118,237,226,251,3,172,88,116,92,159,86,188,188,110,215,119,151,144,164, +136,246,129,40,41,191,105,185,3,137,44,87,101,9,245,31,180,226,153,63,52, +193,163,42,20,26,217,92,79,124,47,89,70,48,207,106,163,51,21,122,255,209, +111,151,193,87,188,162,142,117,78,16,40,90,187,53,219,227,113,151,111,164, +58,255,226,122,204,180,136,99,206,137,148,8,210,109,90,223,210,22,196,129, +199,215,225,231,47,52,192,235,146,104,77,48,247,38,191,239,192,201,159, +0,121,117,243,234,249,80,20,165,156,117,58,4,164,194,202,7,30,251,206,178, +66,68,168,82,7,198,226,166,219,197,20,144,236,82,24,167,184,86,255,112, +13,246,252,158,73,200,212,152,68,83,89,74,57,66,136,206,22,232,143,202, +242,60,20,145,78,88,252,72,214,237,223,113,103,105,46,41,215,233,197,169, +174,79,114,41,39,26,9,69,168,243,237,107,108,67,213,142,187,240,116,77, +3,60,46,133,14,74,29,14,62,147,101,89,199,202,146,28,72,30,255,14,214,205, +4,220,134,172,150,175,40,201,54,147,69,100,43,110,1,139,0,117,63,143,138, +154,247,187,176,247,161,181,248,233,243,111,194,227,182,194,33,73,41,100, +37,43,33,151,21,103,193,144,92,229,172,155,9,200,6,21,173,199,37,32,70, +29,68,18,82,91,239,128,159,24,21,81,26,17,240,121,93,120,165,57,136,170, +71,214,227,201,3,199,77,79,40,196,32,149,247,98,212,208,56,121,89,39,235, +22,97,85,146,217,189,132,25,98,159,8,126,194,26,149,163,170,130,134,20, +89,174,226,216,197,126,252,226,225,111,97,215,111,234,205,68,181,194,56, +73,214,44,120,3,126,159,236,76,39,65,78,236,163,188,200,117,158,170,227, +113,99,145,205,41,104,152,150,184,20,213,60,152,141,81,40,213,227,134,37, +233,148,158,110,76,109,213,146,33,36,205,70,57,113,83,38,23,104,130,145, +154,64,130,7,162,134,8,23,185,91,176,101,215,150,100,226,185,55,62,196, +95,246,110,163,10,137,155,171,162,48,149,128,64,139,253,67,209,9,29,38, +1,110,159,163,17,182,72,52,243,32,53,1,203,173,124,146,70,14,85,21,197, +148,93,146,151,134,131,181,39,240,250,51,219,17,166,49,205,30,113,114,101, +50,1,55,233,24,141,68,38,246,69,203,159,227,29,29,125,67,180,41,220,178, +2,36,187,119,198,13,217,140,127,113,118,26,94,175,59,129,55,170,182,211, +165,68,131,78,212,4,242,98,42,89,15,233,248,164,147,186,48,233,100,221, +124,92,60,28,234,110,56,219,214,11,159,34,204,162,10,44,2,154,40,99,94, +166,23,117,245,39,240,215,125,219,233,6,100,64,215,173,235,89,74,89,98, +145,70,13,248,92,123,31,198,67,151,27,88,55,19,8,7,254,241,242,225,230, +182,171,228,82,80,87,155,217,11,236,51,141,124,28,19,41,243,143,253,19, +71,246,147,242,184,62,163,229,14,124,42,119,80,141,166,226,0,2,239,188, +124,152,117,243,145,209,225,158,207,174,133,66,3,157,255,186,208,135,12, +234,237,220,205,36,187,110,147,192,217,65,86,110,88,118,7,142,29,105,194, +209,106,182,156,252,200,151,21,8,211,203,216,144,233,204,12,106,59,71,78, +118,64,143,142,117,14,145,78,214,45,57,213,161,141,13,93,26,76,95,188,227, +251,171,74,204,18,138,115,50,78,26,175,206,179,102,73,1,54,173,91,72,146, +84,53,186,117,55,156,110,28,39,194,71,134,69,40,65,15,28,61,143,206,183, +14,62,114,163,47,16,32,177,113,231,62,160,211,194,152,191,172,178,228,171, +152,186,248,158,101,243,204,154,214,141,233,73,240,58,223,7,38,174,229, +51,41,55,19,79,196,156,52,1,207,254,185,25,215,122,2,199,219,142,255,238, +53,18,187,206,169,52,65,128,255,233,61,219,120,33,190,240,190,7,243,231, +102,122,203,10,253,20,107,209,44,169,41,183,30,187,80,173,239,129,25,64, +158,116,211,156,206,240,10,120,177,241,18,90,62,15,14,124,124,224,225,31, +145,104,31,199,127,242,149,140,175,205,122,240,100,237,219,61,89,235,239, +47,204,201,244,46,46,242,155,106,204,54,61,11,55,39,221,156,72,185,135, +102,93,186,23,56,216,208,138,119,207,118,132,154,127,189,109,11,29,211, +67,24,182,141,78,34,192,254,140,242,156,185,114,170,246,157,96,214,250, +109,253,195,113,207,55,23,205,35,43,18,239,131,184,121,239,155,110,228, +82,104,92,212,174,211,168,154,198,194,26,126,121,248,28,206,180,118,15, +146,242,173,252,89,65,24,228,242,155,238,82,234,132,34,194,68,130,167,106, +155,198,178,151,231,159,234,24,41,203,76,247,160,226,107,62,107,204,38, +213,181,5,201,158,17,76,212,227,50,231,13,142,53,119,226,183,71,91,208, +213,254,121,211,153,231,118,238,182,149,135,38,95,203,83,126,152,16,230, +16,242,114,151,110,88,90,186,233,39,191,202,205,205,153,191,174,60,31,149, +84,1,165,121,126,202,234,155,51,133,15,225,86,254,201,151,131,248,248,82, +47,78,127,214,139,241,145,161,174,64,211,11,207,254,183,245,195,86,218, +190,106,39,93,236,182,62,205,8,20,65,204,37,228,120,231,22,206,251,250, +198,221,91,188,249,101,223,19,221,190,18,221,48,166,204,9,35,114,227,203, +209,190,246,119,3,111,29,106,24,27,184,194,117,222,79,224,219,239,216,237, +126,154,37,238,43,54,145,52,66,58,33,131,224,73,184,81,39,134,111,156,48, +100,39,217,168,173,56,246,255,126,156,78,231,17,149,7,154,61,69,167,251, +60,140,219,229,21,77,101,241,228,231,127,2,12,0,35,187,154,106,194,98,206, +112,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_17 = 2315; +static unsigned char xml_res_file_17[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,8,173,73,68,65,84,120,218,172,87,11,80,84,231,21,62,123,239,238, +178,32,225,189,8,136,32,136,202,242,168,10,212,166,81,177,106,173,113,212, +234,198,71,104,199,65,109,106,58,153,105,19,141,161,42,248,76,192,33,22, +147,49,38,169,157,56,101,242,176,81,81,48,157,198,180,77,194,99,81,164, +160,147,162,242,94,65,129,125,47,187,236,238,221,247,171,231,191,185,155, +172,136,200,180,189,51,103,118,247,222,255,254,223,119,94,223,249,151,7, +83,188,182,109,223,17,153,152,144,120,66,36,18,21,39,36,36,136,146,103, +36,193,180,105,211,128,166,105,144,223,187,7,61,61,189,178,147,127,120, +115,37,46,245,29,125,189,98,47,69,81,187,189,94,111,146,88,44,6,141,70, +3,60,30,62,240,122,107,237,14,199,1,92,215,143,235,252,100,95,222,20,176, +233,3,101,135,254,40,16,8,118,73,55,110,128,249,185,57,192,163,40,80,40, +149,208,218,250,47,252,84,65,95,95,95,227,123,167,79,237,192,181,134,242, +227,111,246,37,37,36,38,44,91,190,20,196,113,113,224,247,251,17,156,7,78, +167,19,250,251,239,193,215,245,13,160,80,12,103,158,121,255,189,62,66,130, +255,36,240,125,7,202,106,242,243,242,16,123,61,11,108,101,172,80,223,216, +4,178,230,102,232,234,236,172,100,24,203,112,179,172,169,5,215,186,223, +168,168,236,155,55,119,110,66,97,225,18,232,184,125,23,174,95,111,5,140, +4,107,241,211,227,33,55,59,11,146,147,147,224,131,179,127,238,193,245,34, +52,231,100,4,232,253,165,7,107,242,11,242,164,155,164,27,97,116,212,0,6, +163,17,26,16,188,183,183,87,255,86,213,137,45,184,70,135,102,70,99,246, +150,236,127,126,70,98,18,130,47,70,130,50,240,122,60,128,81,3,179,217,76, +60,134,174,238,46,104,168,175,103,131,78,211,20,217,63,108,50,2,36,236, +232,121,62,130,111,128,7,67,35,96,181,89,161,169,73,6,114,185,92,129,224, +91,113,205,16,9,57,154,11,77,24,17,17,113,148,132,189,227,118,39,11,78, +81,52,91,31,38,147,9,94,63,122,100,13,137,80,208,254,198,192,23,106,98, +240,195,53,63,44,40,144,110,122,110,3,220,127,48,132,155,140,1,133,121, +140,141,141,1,198,98,249,134,3,215,160,217,208,60,104,33,152,235,233,241, +113,98,80,171,213,108,206,41,138,7,124,62,159,45,62,188,6,209,238,4,25, +249,109,37,15,198,71,128,127,240,240,177,218,252,188,133,235,73,206,7,6, +239,99,8,25,112,185,156,224,241,122,97,235,230,77,64,83,212,186,136,200, +72,168,58,81,41,13,122,79,64,138,205,108,177,0,65,36,4,136,247,66,161,32, +216,99,237,68,161,30,31,129,80,30,143,226,192,7,17,220,132,213,235,0,167, +195,9,122,253,40,22,222,117,216,244,156,148,108,190,142,172,13,126,145, +16,224,211,124,182,173,190,5,231,179,53,240,164,70,163,198,21,93,117,126, +222,2,80,170,212,48,54,102,6,187,195,5,14,135,3,236,132,4,182,145,70,171, +131,175,234,27,89,48,174,138,191,187,188,30,151,106,112,112,0,226,177,239, +5,2,62,146,64,227,211,224,247,249,38,37,64,232,241,203,143,87,94,17,139, +227,215,166,166,204,132,140,217,233,108,222,195,195,195,17,216,9,46,52, +7,18,33,105,64,97,129,129,129,65,192,100,131,82,161,168,59,116,168,140, +116,130,23,45,118,247,158,189,117,69,69,69,75,163,163,163,161,95,46,103, +243,47,10,9,1,53,138,80,123,123,59,219,138,44,32,91,31,20,84,30,47,15,33, +5,204,231,194,190,246,197,95,239,100,23,212,55,52,193,32,134,159,20,79, +234,172,52,4,118,129,199,237,98,159,13,13,13,131,72,36,100,211,48,102,208, +73,159,162,125,231,119,151,30,218,246,70,233,129,51,171,214,174,95,58,111, +110,6,252,27,251,159,68,8,21,147,37,145,158,158,14,89,18,9,251,91,32,160, +65,165,84,195,229,186,186,1,174,13,89,2,66,139,197,212,84,115,169,118,153, +4,23,134,134,138,216,192,88,44,12,246,123,31,232,116,26,246,55,217,52,50, +34,2,22,204,159,15,183,218,219,32,43,39,27,62,14,95,182,57,230,200,231, +82,207,28,160,243,127,144,5,109,29,157,96,183,219,208,236,172,247,49,81, +81,236,123,108,129,162,30,116,247,244,64,119,119,55,234,193,215,123,131, +83,240,20,90,218,222,146,125,167,51,231,73,10,103,207,73,7,55,122,45,151, +15,64,111,79,119,125,91,91,235,37,1,95,192,195,40,248,211,82,102,110,217, +184,97,195,242,168,184,233,240,234,55,110,216,179,118,37,180,169,24,104, +31,82,65,138,91,5,175,102,248,96,72,163,135,230,235,45,138,200,200,200, +24,172,148,208,105,97,97,232,140,133,5,195,162,110,249,224,79,103,246,225, +215,7,92,27,187,120,92,43,70,161,165,32,137,183,103,207,206,40,76,78,78, +134,142,142,14,56,84,182,255,105,188,175,231,68,132,148,116,204,214,205, +155,143,245,46,218,181,230,183,207,46,131,187,58,59,168,25,7,184,253,20, +220,188,55,8,235,104,57,248,238,54,106,207,156,61,251,75,174,54,40,28,92, +225,168,13,86,78,47,76,28,112,64,192,252,52,153,94,68,18,201,141,27,45, +215,91,37,89,57,185,24,174,153,140,197,212,114,237,90,115,53,222,87,5,228, +54,116,69,113,140,117,197,75,85,37,107,22,195,109,173,29,84,22,59,184,125, +126,240,160,69,132,71,129,108,216,0,141,111,151,252,12,215,222,71,83,18, +242,12,195,40,57,13,208,112,210,109,10,86,197,224,38,37,100,162,209,146, +208,34,56,241,32,138,71,226,199,139,121,233,221,217,233,217,121,253,21, +235,127,12,87,229,70,80,90,28,44,176,27,253,116,251,121,160,192,57,17,230, +53,193,38,253,151,159,237,59,124,164,8,223,113,4,97,248,31,59,112,130,181, +132,11,11,195,129,147,48,217,201,253,152,223,188,147,134,224,242,242,245, +207,176,224,42,198,142,224,192,130,123,16,92,137,224,94,253,0,124,181,45, +27,36,146,121,153,179,226,197,153,127,175,111,168,157,12,120,162,8,76,40, +84,177,251,206,23,47,202,156,91,253,242,242,133,240,197,56,112,47,130,171, +113,78,120,12,15,224,84,158,0,104,158,15,126,148,191,0,118,254,181,15,218, +245,62,48,153,205,87,116,199,214,109,225,242,15,83,145,226,135,158,197, +148,156,219,190,124,126,78,117,217,179,11,225,106,191,129,205,121,48,184, +206,108,132,97,173,18,36,183,170,255,105,208,169,65,128,2,179,241,195,118, +24,163,34,224,47,219,151,194,178,121,105,27,227,14,214,93,28,23,233,199, +166,224,33,240,232,215,206,21,175,88,56,191,122,247,138,108,184,112,215, +192,86,187,215,255,61,184,222,108,0,165,122,4,140,31,150,21,221,110,254, +242,106,152,80,48,235,111,130,236,52,65,124,26,252,126,85,14,252,67,110, +129,95,44,72,6,181,213,43,209,73,86,229,218,100,23,46,77,148,146,137,82, +192,143,46,171,187,248,98,97,129,116,109,110,50,92,236,28,69,112,231,4, +224,195,96,188,80,249,188,237,78,211,77,174,224,18,231,190,115,227,230, +39,59,158,134,183,26,181,96,69,45,153,21,21,6,91,179,99,224,84,67,39,52, +118,245,215,233,203,165,1,233,126,108,4,232,232,210,218,154,61,171,23,75, +127,154,153,8,23,187,70,65,243,56,240,79,43,182,216,238,54,183,225,59,234, +64,167,240,114,86,20,92,233,181,166,122,169,112,32,135,30,135,219,3,35, +22,15,252,106,81,42,104,48,18,218,9,34,65,63,228,121,105,237,37,2,94,152, +17,15,53,232,185,198,58,49,184,179,171,165,194,84,255,201,231,28,184,147, +211,18,191,173,165,246,70,104,238,146,108,15,95,152,26,34,138,100,227,107, +119,77,78,34,64,128,22,151,213,158,221,245,147,69,69,43,209,243,71,193, +177,47,25,11,40,84,15,192,217,121,237,184,254,211,242,143,56,129,114,4, +121,67,72,184,153,27,159,181,134,228,44,145,184,105,97,170,48,244,201,36, +2,4,166,197,174,121,225,98,233,234,5,88,112,193,224,126,214,115,6,15,36, +35,202,1,112,220,145,85,232,207,31,255,152,3,183,143,43,170,239,20,117, +50,18,47,32,9,173,205,39,209,103,175,206,179,54,157,175,9,180,161,104,142, +56,10,31,224,206,152,243,111,91,237,123,240,251,35,253,224,54,168,101,8, +126,142,147,88,43,7,56,254,242,6,20,84,117,114,231,30,70,209,35,211,106, +135,193,138,194,107,69,37,24,54,57,224,114,183,17,74,86,101,225,31,2,1, +123,170,10,16,160,212,22,27,80,56,150,8,56,177,96,112,207,168,74,166,170, +218,254,10,151,243,199,129,79,74,194,134,36,108,72,66,201,184,224,149,218, +91,192,99,140,77,100,192,5,82,16,198,43,248,249,150,172,153,113,81,26,59, +31,156,184,133,25,143,225,67,138,123,168,114,170,102,213,201,29,123,112, +205,48,55,148,188,83,248,55,229,127,36,29,252,144,84,81,88,52,178,26,130, +17,121,167,76,83,85,252,50,62,31,13,232,0,38,10,50,18,202,46,215,242,68, +97,41,120,162,102,143,78,94,237,240,23,170,83,187,14,114,67,201,56,69,112, +152,96,192,165,36,190,246,209,105,161,56,249,25,151,110,164,69,85,85,252, +59,110,207,177,0,1,50,235,99,209,102,112,147,144,226,70,166,145,43,184, +177,201,244,124,138,36,2,83,214,204,213,17,235,80,176,18,10,184,115,154, +144,83,72,31,215,102,246,255,194,243,71,212,149,59,198,11,56,199,236,255, +131,67,255,223,235,63,2,12,0,116,106,129,252,126,87,16,179,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_18 = 2051; +static unsigned char xml_res_file_18[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,165,73,68,65,84,120,218,156,87,125,108,85,103,25,255,189,231,227, +158,123,123,251,129,165,45,216,58,235,112,165,104,132,208,144,97,34,211, +12,199,88,2,24,166,76,103,166,243,47,157,157,78,99,252,136,35,200,76,101, +113,97,14,51,201,22,182,37,115,38,186,153,45,51,196,101,76,145,5,134,5, +66,183,21,16,18,217,40,116,163,31,72,75,139,180,183,189,31,231,158,15,127, +207,123,206,45,183,176,10,235,73,159,158,243,190,247,61,239,243,123,127, +207,239,121,222,247,40,204,238,178,58,158,124,241,101,195,180,214,135,97, +120,221,47,41,165,16,248,222,95,127,249,253,187,239,98,211,211,125,179, +113,254,208,246,23,118,134,202,92,183,100,73,11,130,48,0,174,7,3,61,25, +202,192,241,227,61,80,161,255,234,175,126,120,207,151,75,32,62,236,85,181, +249,137,23,67,159,75,207,185,126,56,89,240,174,219,100,188,188,39,239,203, +60,122,53,179,0,144,12,124,31,110,209,199,190,99,189,248,16,17,96,8,128, +149,75,23,64,222,151,121,104,153,217,0,80,18,119,113,44,19,126,177,109, +65,212,27,78,253,155,241,218,123,236,61,248,65,200,176,133,83,225,183,102, +37,65,121,223,48,144,176,44,108,123,249,128,22,87,105,198,176,4,164,140, +26,121,10,232,120,121,235,13,116,142,105,191,89,211,84,109,81,213,193,181, +57,149,21,60,242,212,75,250,217,160,115,21,243,43,119,59,149,66,162,234, +35,116,24,160,148,33,97,137,25,21,70,253,229,138,22,219,252,187,231,119, +22,253,96,93,219,226,5,215,165,234,16,229,116,171,169,84,82,134,194,209, +35,39,81,147,78,162,117,225,141,240,253,203,32,228,146,182,23,78,239,19, +0,41,24,230,186,77,15,220,13,145,134,49,203,194,16,198,118,199,45,109,216, +242,219,63,226,123,95,91,133,162,23,148,209,173,176,231,200,41,4,94,120, +21,128,164,32,227,80,252,160,227,25,36,19,6,204,56,152,83,225,68,89,187, +44,132,83,109,78,46,145,43,250,33,182,109,188,79,139,97,235,75,157,154, +238,210,123,18,182,101,45,141,154,225,43,1,168,144,3,11,69,160,182,42,133, +191,140,180,33,149,80,112,28,19,182,99,83,104,10,137,132,5,155,168,18,52, +155,109,155,52,137,113,24,108,26,49,211,167,129,244,217,61,4,225,67,17, +141,101,88,8,149,196,59,90,156,138,181,229,249,87,3,128,12,43,184,30,210, +41,113,200,152,36,13,56,52,155,179,59,244,100,90,145,99,13,192,136,1,208, +177,101,134,176,57,151,101,68,43,76,37,109,20,10,30,29,152,88,126,211,39, +53,3,174,114,225,154,17,237,158,235,106,13,148,107,44,202,2,14,204,187, +62,233,183,161,108,19,166,99,192,146,123,194,100,91,0,208,76,3,6,65,24, +4,192,63,138,62,212,119,131,119,165,57,134,126,95,22,98,4,9,60,81,152,7, +145,192,183,43,70,176,246,201,109,116,234,99,103,123,59,139,16,62,128,1, +118,20,138,46,146,164,156,169,168,29,26,182,69,51,35,147,182,24,25,32,14, +173,17,185,147,100,88,2,68,138,139,167,144,36,3,121,2,8,248,251,200,33, +106,66,184,191,221,196,249,87,30,137,116,115,255,253,4,21,76,223,88,74, +50,202,83,4,78,34,193,85,27,218,169,178,204,8,12,159,45,75,194,97,68,33, +48,37,246,12,7,29,123,158,199,204,97,152,18,146,62,33,42,28,135,11,41,178, +218,229,177,249,214,33,29,111,183,152,65,215,238,65,2,8,96,20,178,188,251, +31,192,128,136,208,45,234,21,24,6,29,27,178,98,83,135,193,74,68,119,143, +78,71,93,32,199,52,26,203,121,90,84,97,145,241,38,136,128,171,206,231,129, +205,139,146,96,152,17,6,228,38,84,58,169,109,134,195,116,165,252,250,4, +102,144,41,92,85,136,52,162,60,197,227,48,134,6,185,213,113,167,89,100, +32,235,43,12,184,138,0,12,93,104,36,224,182,163,68,206,58,221,196,79,192, +127,62,199,85,166,230,224,244,249,127,226,52,30,196,67,127,235,67,57,219, +139,26,150,98,121,243,79,208,210,180,129,176,172,43,53,0,198,142,12,144, +75,17,154,69,6,24,89,12,23,200,140,178,160,36,44,4,35,236,136,152,66,229, +151,10,60,65,113,172,73,214,204,36,222,62,119,31,222,189,180,11,107,62, +255,85,44,110,254,49,69,89,161,199,229,220,44,78,156,61,128,87,187,239, +197,80,110,55,157,110,184,50,11,124,166,79,81,51,32,69,165,64,170,38,115, +76,78,198,94,113,181,161,172,158,78,124,10,19,92,169,222,47,152,227,236, +212,21,142,249,131,134,226,122,156,207,239,197,198,13,219,209,63,246,38, +254,209,179,9,67,19,147,122,250,121,149,105,124,102,254,157,216,116,215, +118,108,127,237,103,204,156,225,41,0,70,137,129,44,227,104,147,129,12,87, +61,144,241,144,41,42,76,80,217,25,207,64,198,143,173,24,183,99,155,96,60, +39,61,178,230,238,67,163,243,58,218,215,252,26,157,103,31,69,87,255,159, +112,49,55,137,29,235,67,109,242,220,213,255,60,14,244,61,138,7,214,60,12, +55,253,6,110,254,14,22,11,122,171,180,91,21,40,40,187,198,65,231,183,210, +48,74,149,61,20,170,179,151,171,125,88,218,197,227,237,151,33,177,140,20, +182,254,253,97,180,54,127,29,71,207,253,1,163,217,1,93,152,92,53,253,32, +34,125,242,219,177,115,207,97,237,178,123,241,194,165,103,59,248,83,167, +21,159,48,168,169,16,199,123,47,226,95,167,71,167,85,249,255,119,226,49, +24,2,75,85,227,112,239,97,220,122,115,27,246,191,255,14,43,29,163,196,232, +184,101,2,148,103,51,136,106,71,127,230,223,88,121,227,42,10,29,43,100, +35,20,0,225,196,196,248,193,163,93,135,86,132,165,189,122,106,35,138,78, +47,21,73,7,147,217,124,124,226,0,210,21,73,100,243,5,50,69,241,161,26,102, +10,24,206,119,235,154,255,155,213,87,35,222,241,165,203,125,15,190,174, +40,196,183,74,91,184,84,126,228,127,191,245,231,223,229,189,174,236,128, +162,62,119,219,186,214,213,95,249,230,182,156,175,156,101,75,23,162,247, +63,163,83,147,44,248,232,92,116,31,59,133,234,36,247,253,79,124,10,39,187, +129,9,183,79,211,124,173,75,88,144,177,49,0,173,129,28,173,143,54,92,118, +76,79,174,186,243,27,123,84,170,2,14,249,172,172,74,227,182,198,250,169, +115,224,133,76,22,78,202,129,71,13,156,236,233,213,125,151,242,231,185, +139,178,24,237,83,186,4,231,41,208,199,239,136,86,254,163,221,44,211,86, +180,131,202,152,177,252,32,226,83,156,94,177,156,205,51,177,149,174,90, +151,37,245,211,31,155,135,241,201,28,122,206,12,224,84,153,24,228,12,216, +80,55,7,213,233,52,222,57,209,143,133,13,43,48,122,241,32,230,215,71,43, +20,13,24,101,108,84,208,105,133,29,239,31,204,220,225,11,220,39,178,56, +34,1,157,233,80,106,121,172,116,77,245,53,104,110,170,199,232,216,164,174, +241,165,44,112,108,27,115,107,210,80,92,234,9,175,7,222,224,74,156,153, +56,136,198,6,6,213,142,138,164,83,54,25,247,56,72,9,17,231,178,115,158, +121,15,24,236,198,227,162,79,115,6,0,78,117,109,253,133,75,185,112,117, +37,227,188,248,166,38,44,108,110,68,243,252,90,90,29,170,28,11,167,201, +202,222,67,221,120,243,141,93,27,119,62,179,227,177,186,69,168,25,47,48, +27,155,232,200,138,118,204,253,125,29,232,28,232,0,183,24,13,76,72,57,252, +54,211,177,15,175,188,245,28,158,102,243,191,51,125,154,81,215,104,156, +219,208,216,178,230,158,246,95,84,206,153,187,34,58,45,71,20,72,8,38,198, +70,14,190,246,231,167,183,140,14,157,123,95,132,44,97,251,194,79,177,165, +238,6,172,109,109,97,245,155,23,1,209,167,32,6,121,104,8,120,183,135,206, +251,177,107,255,99,216,200,238,179,18,246,153,0,8,88,97,177,150,70,98,153, +107,211,191,33,68,55,227,177,112,47,198,109,249,212,106,106,185,29,183, +124,252,179,104,79,84,99,73,217,193,25,238,56,142,247,117,225,169,158,61, +56,192,158,65,218,24,116,97,191,198,135,104,204,134,115,197,129,89,82,190, +16,103,80,233,3,83,194,153,142,65,75,74,87,198,125,250,68,78,155,160,141, +196,128,39,227,190,89,125,29,95,227,27,24,118,12,58,81,54,191,112,225,198, +128,139,229,223,112,255,19,96,0,111,126,151,122,57,77,224,198,0,0,0,0,73, +69,78,68,174,66,96,130}; + +static size_t xml_res_size_19 = 2007; +static unsigned char xml_res_file_19[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,121,73,68,65,84,120,218,172,87,13,108,85,103,25,126,190,239,156, +115,127,90,74,41,163,180,182,118,115,117,64,21,232,214,176,117,70,22,163, +27,209,17,152,110,254,85,97,63,49,76,129,110,26,166,38,58,38,234,28,209, +204,13,19,204,36,203,100,66,54,49,25,3,231,72,97,108,83,144,159,110,176, +78,91,58,129,149,50,170,164,98,88,215,206,246,246,254,157,191,207,231,59, +247,220,114,239,150,74,169,158,244,237,119,207,189,231,156,231,125,159, +231,125,191,247,61,2,147,59,204,7,127,245,204,14,105,152,159,83,74,77,248, +38,33,4,124,207,125,254,71,247,180,124,145,167,110,240,221,100,192,127, +248,203,223,61,167,132,177,180,177,113,22,124,229,3,19,241,129,72,82,72, +116,119,247,66,40,175,237,39,223,90,118,91,222,137,75,61,202,214,61,246, +140,242,24,122,218,246,84,50,235,78,216,244,245,250,62,125,191,126,78,16, +205,36,28,136,249,158,7,219,241,176,191,235,12,46,65,1,74,0,124,234,154, +122,232,251,245,115,104,137,201,56,32,180,238,26,88,63,240,198,166,250, +220,183,106,236,223,184,199,190,174,62,120,190,162,108,106,76,126,115,82, +41,168,239,151,18,17,211,196,134,29,135,131,228,202,63,81,229,29,41,160, +70,127,242,9,220,60,167,142,224,40,250,205,44,202,106,147,89,237,95,156, +83,29,193,207,30,223,30,124,150,4,23,33,191,122,181,226,113,68,202,42,8, +232,35,95,33,42,207,140,80,185,239,11,51,90,219,186,141,219,158,115,60, +127,105,211,252,250,9,101,181,66,33,221,98,172,148,132,20,232,252,235,73, +148,151,198,48,103,246,149,240,188,11,78,232,195,37,184,11,85,148,55,218, +129,56,164,177,244,129,123,91,160,83,67,78,114,99,80,161,125,230,134,38, +60,244,139,167,209,250,229,69,112,92,63,160,91,137,128,42,188,212,245,22, +60,189,23,200,98,9,98,218,83,94,138,111,62,248,4,98,17,9,35,20,115,76,78, +20,156,23,72,56,118,78,14,180,114,142,167,176,225,254,111,4,201,240,240, +246,67,1,221,250,87,159,160,14,35,107,57,105,99,112,215,105,216,149,162, +200,1,161,120,97,214,1,166,151,197,177,243,157,38,196,35,2,209,168,1,43, +106,49,209,4,34,17,19,22,189,138,208,44,158,91,124,152,54,94,6,139,70,159, +137,41,81,250,143,151,233,132,7,65,111,76,105,50,242,156,222,158,65,240, +19,89,148,92,61,23,163,201,36,86,188,113,12,27,67,7,2,198,245,101,89,219, +69,105,92,3,82,147,152,68,60,78,139,10,148,240,115,52,112,40,52,43,52,237, +72,132,14,240,122,22,3,132,161,120,159,133,108,150,42,43,3,205,87,125,24, +215,210,154,174,170,67,109,170,15,123,171,123,145,30,73,33,53,154,194,112, +85,29,58,214,108,57,79,232,72,174,10,200,64,198,246,72,191,5,97,25,48,162, +18,166,94,35,6,207,41,137,73,51,36,36,65,37,181,228,31,147,94,5,171,228, +42,130,58,67,112,191,14,68,168,8,54,218,85,176,249,221,151,122,118,226, +218,230,102,148,79,159,138,205,79,109,193,205,114,17,50,233,12,34,118,86, +35,151,202,124,89,101,29,27,49,82,206,82,36,160,9,105,105,51,194,149,22, +201,173,134,118,44,112,206,12,156,212,38,233,160,144,6,98,100,64,7,226, +9,19,231,142,0,63,255,253,92,68,167,76,195,148,242,105,232,61,117,26,85, +21,51,240,236,200,31,80,221,223,131,235,55,173,250,88,193,62,160,144,97, +18,68,35,17,62,88,6,192,194,52,114,206,104,16,2,88,100,34,200,1,67,107, +207,124,96,216,174,235,178,114,40,71,36,39,102,60,26,69,146,91,116,146, +140,60,126,238,35,104,104,253,2,26,106,106,241,216,182,131,48,156,81,156, +60,126,130,82,1,91,230,6,109,96,128,150,52,115,10,48,9,109,39,136,64,50, +18,41,53,221,185,232,204,72,110,117,9,58,104,3,105,87,97,56,237,6,137,166, +28,234,77,39,124,210,158,201,10,220,223,80,130,17,219,192,138,129,251,208, +216,122,7,80,253,53,224,149,31,227,94,119,59,214,252,125,29,88,36,248,206, +218,245,216,180,117,135,134,29,165,217,102,174,172,52,3,46,35,161,3,212, +58,208,157,102,146,129,148,39,208,111,11,58,32,131,141,70,11,110,49,25, +225,122,65,185,233,26,247,249,47,235,243,250,248,52,204,120,114,30,22,172, +190,157,224,43,8,254,16,112,170,77,103,40,174,62,191,25,149,173,251,144, +78,167,243,205,168,160,10,232,89,70,51,64,46,117,162,153,100,128,41,134, +183,179,62,6,8,238,235,4,164,230,134,150,136,121,160,229,17,134,17,56,164, +181,119,140,40,82,178,20,205,127,92,146,3,255,192,215,129,87,53,248,174, +160,229,111,58,82,131,219,158,124,11,118,54,9,155,201,151,219,31,10,123, +129,239,177,124,156,128,1,189,169,232,104,146,105,22,167,78,46,70,171,116, +244,4,244,116,205,145,145,160,95,72,62,132,181,238,144,129,97,21,195,129, +115,245,152,189,242,46,70,174,193,215,135,224,14,193,171,209,178,245,77, +188,120,224,13,152,194,99,222,120,69,219,243,24,3,41,234,104,145,129,4, +163,238,79,184,72,240,201,163,174,64,194,149,72,120,161,57,225,121,96,6, +134,61,11,67,254,20,236,239,187,8,248,190,46,220,188,112,62,244,134,231, +49,88,37,138,123,65,208,173,178,76,40,171,60,138,67,119,150,66,230,119, +118,69,173,84,234,194,110,175,242,93,92,192,147,22,183,215,82,12,255,244, +114,204,94,125,231,123,192,73,251,209,106,124,133,224,123,254,212,137,37, +159,104,194,158,63,191,198,156,50,130,6,245,190,118,204,9,131,57,165,208, +125,102,8,199,78,15,22,237,242,239,159,120,152,144,48,144,33,237,139,95, +93,130,235,90,239,10,53,15,193,165,135,39,94,171,193,242,45,199,177,123, +127,23,110,249,100,19,215,163,184,229,198,235,241,194,193,215,137,83,220, +33,181,3,106,116,116,164,189,243,232,43,11,85,190,87,143,53,162,220,244, +82,18,99,125,167,50,65,207,247,9,46,153,237,171,254,189,22,77,247,104,240, +187,139,192,55,191,94,139,211,205,143,224,197,67,212,156,174,238,61,208, +17,236,162,123,184,234,161,212,11,230,132,98,9,50,191,121,248,123,43,185, +206,40,24,80,196,199,111,90,58,231,211,159,191,125,67,218,19,209,5,215, +204,198,153,127,13,6,229,228,200,24,62,219,209,130,198,85,203,73,123,49, +248,175,59,106,80,118,119,27,154,157,4,213,179,115,114,9,81,48,122,171, +160,89,189,151,129,52,237,44,237,237,130,49,61,182,232,214,229,47,139,120, +9,162,164,108,74,89,41,110,170,153,201,182,106,97,176,251,121,76,93,244, +85,160,238,219,192,1,90,239,110,130,171,32,242,169,43,218,96,216,9,102, +181,29,200,90,56,172,92,120,47,240,195,223,46,56,160,103,243,68,104,249, +99,186,237,56,248,232,7,171,48,146,76,163,247,76,63,78,41,210,39,163,104, +28,232,192,135,110,125,4,110,223,94,136,108,6,6,35,223,218,121,5,166,173, +220,205,237,118,132,251,130,23,204,139,227,142,115,122,126,44,248,125,188, +161,212,212,245,90,91,89,142,43,106,43,49,52,156,98,103,19,48,250,247,227, +186,6,222,210,223,6,57,244,38,78,244,189,139,99,39,234,112,184,238,251, +176,94,160,67,190,131,139,205,233,122,243,202,36,19,237,249,76,31,207,1, +247,111,127,105,255,46,231,164,71,23,204,111,64,211,188,89,168,152,81,137, +205,207,254,0,199,205,56,214,44,62,136,157,187,142,160,39,178,16,135,207, +86,173,109,223,180,172,3,19,123,63,66,200,248,59,58,247,254,219,171,89, +156,86,115,217,204,154,89,139,151,173,122,160,172,98,230,13,229,94,63,186, +59,123,112,229,212,119,81,85,63,15,61,233,203,219,247,62,189,97,253,224, +249,127,246,241,218,17,61,248,92,194,248,152,9,115,207,29,207,1,45,82,84, +231,2,109,38,237,178,251,86,223,241,212,192,217,99,219,126,187,187,251, +37,221,197,66,80,157,184,67,225,3,213,100,134,217,139,189,156,154,33,27, +21,180,242,96,127,205,1,107,7,178,249,40,240,63,28,19,125,59,182,66,70, +188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, +73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_20 = 2051; +static unsigned char xml_res_file_20[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,165,73,68,65,84,120,218,156,87,107,112,21,103,25,126,190,221,61, +187,231,228,228,2,185,181,73,4,148,66,130,117,200,52,182,214,81,42,14,45, +86,7,80,212,233,216,17,157,78,127,56,26,188,212,209,254,160,25,172,12,242, +163,211,25,227,84,165,78,107,157,90,111,197,214,58,12,140,69,7,28,138,66, +25,29,36,164,212,182,16,174,197,96,106,110,36,57,201,185,236,213,231,221, +221,115,56,73,154,66,115,38,111,118,191,189,124,239,243,62,239,243,190, +223,183,10,243,251,25,219,31,127,238,5,77,55,54,6,65,112,221,47,41,165, +224,123,238,158,109,223,184,247,30,14,221,240,218,124,156,127,255,39,207, +238,14,148,190,161,189,125,57,252,192,7,174,7,3,61,105,74,195,201,147,103, +160,2,239,79,63,120,96,211,231,138,32,222,237,175,234,225,157,207,5,30, +67,207,217,94,48,85,112,175,219,228,121,121,79,222,151,121,194,104,230, +1,32,233,123,30,108,199,195,75,189,231,241,46,50,192,20,0,107,110,89,10, +121,95,230,161,101,230,3,64,73,222,197,177,76,120,103,199,210,232,106,80, +250,55,231,239,96,239,5,120,126,192,180,5,165,244,27,243,146,160,188,175, +105,48,13,3,221,47,28,9,197,85,156,49,40,2,41,163,70,206,124,58,190,189, +109,17,157,99,218,61,99,154,170,13,170,218,191,54,167,18,193,35,79,60,31, +158,107,116,174,98,126,229,152,72,165,96,86,45,164,67,31,197,10,9,138,204, +168,32,186,94,174,104,177,135,127,252,187,221,142,231,111,232,88,185,244, +186,84,29,160,156,110,85,42,37,165,41,156,232,121,3,53,233,36,218,90,223, +7,207,187,10,66,126,50,118,131,233,215,4,64,10,154,190,97,235,55,239,133, +72,67,155,103,99,8,98,251,228,29,29,216,241,163,223,224,235,95,88,11,199, +245,203,232,86,56,208,211,7,223,13,102,1,72,10,50,62,138,111,109,255,57, +146,166,6,61,78,102,41,157,40,27,151,165,176,52,230,228,146,57,199,11,208, +221,245,213,80,12,143,62,127,56,164,187,248,158,164,237,214,229,205,33, +195,51,1,168,128,15,22,28,160,182,42,133,63,14,119,32,101,42,88,150,142, +132,149,160,208,20,76,211,64,130,168,76,90,130,227,4,105,18,227,99,72,208, +136,153,62,53,164,223,60,64,16,30,20,209,24,154,129,64,73,190,163,224,84, +172,45,215,155,13,0,242,88,193,118,145,78,137,67,230,36,169,193,162,37, +56,187,69,79,186,17,57,14,1,104,49,0,58,54,244,0,9,206,101,104,81,132,169, +100,2,133,130,75,7,58,110,95,118,83,200,128,173,108,216,122,68,187,107, +219,161,6,202,53,22,85,1,31,204,219,30,233,79,64,37,116,232,150,6,67,142, +166,206,177,0,160,233,26,52,130,208,8,128,127,20,125,16,30,53,30,85,200, +49,194,247,37,16,205,55,177,179,112,3,68,2,95,169,24,198,250,199,187,233, +212,195,238,206,78,54,33,188,13,3,188,80,112,108,36,73,57,75,49,116,168, +37,12,154,30,153,140,197,200,0,113,132,26,145,35,73,134,33,64,164,185,184, +10,73,50,144,39,0,159,247,135,143,82,19,194,253,39,116,188,181,247,145, +72,55,155,55,19,148,63,125,97,41,202,40,79,17,88,166,201,168,181,208,169, +50,244,8,12,207,13,67,210,161,69,41,208,37,247,76,7,29,187,174,203,202, +97,154,76,41,159,0,21,150,133,60,3,113,130,60,182,174,121,43,204,183,237, +78,224,31,251,251,9,192,135,42,228,24,172,247,54,12,136,8,109,39,140,64, +211,232,88,147,136,245,48,13,134,25,29,93,58,29,177,129,28,203,104,60,231, +134,162,10,28,230,155,32,124,70,157,47,0,91,87,88,200,178,18,10,204,77, +214,244,88,247,34,65,45,202,15,185,23,183,158,95,214,152,138,0,4,81,158, +226,177,152,67,141,220,134,121,167,25,100,32,235,41,244,219,138,0,180,176, +209,72,194,19,150,18,57,135,229,22,40,132,37,104,243,196,172,170,134,253, +239,19,248,216,193,103,176,240,151,223,13,213,31,174,25,252,103,127,104, +13,114,235,190,8,103,241,90,248,12,114,134,6,192,220,145,1,114,41,66,51, +200,0,51,139,193,2,153,81,6,148,164,133,96,132,29,17,83,160,188,98,131, +39,40,13,110,194,132,163,153,104,217,243,11,212,28,123,9,43,63,245,105, +44,232,188,31,122,170,34,138,58,155,197,149,87,123,209,191,179,11,133,83, +199,224,212,119,204,172,2,143,229,227,132,12,72,83,41,248,26,166,114,44, +78,230,94,49,218,64,162,215,117,120,20,38,200,72,184,94,176,198,73,23,163, +97,90,148,137,239,252,245,65,52,142,29,199,242,45,219,80,56,251,58,50,187, +158,130,59,52,16,57,105,104,66,213,135,87,163,253,161,109,56,245,179,199, +208,209,56,80,2,160,21,25,200,50,143,9,50,144,97,212,253,25,23,25,71,97, +146,202,206,184,26,50,94,108,78,60,46,26,155,215,132,151,192,77,255,249, +23,214,14,252,29,173,155,191,141,236,158,93,200,239,223,3,76,102,96,164, +171,67,147,115,185,150,231,189,247,119,62,128,246,129,215,208,125,243,226, +149,210,159,140,226,106,85,160,160,18,53,22,14,223,151,134,86,236,236,129, +80,157,189,218,237,131,226,42,30,47,63,164,223,75,86,96,104,203,211,104, +92,127,15,242,135,254,2,111,240,50,180,100,50,218,44,148,150,41,121,215, +8,239,21,254,182,15,139,214,109,196,7,126,255,219,237,188,113,216,136,119, +24,212,84,128,147,231,71,241,202,217,145,105,93,254,29,119,60,4,224,36, +211,88,125,232,0,106,30,124,8,83,71,254,12,197,86,28,176,227,205,94,82, +85,148,198,115,167,177,176,227,35,72,234,218,42,89,8,5,64,48,57,57,241, +242,137,127,30,93,21,20,215,234,210,66,20,237,94,42,146,22,166,178,249, +120,199,1,164,43,146,200,74,221,17,64,222,172,192,234,4,59,104,255,5,54, +40,133,154,23,123,223,113,213,28,223,120,27,212,165,115,69,120,210,249, +145,127,250,209,45,95,227,177,190,108,131,162,62,122,215,134,182,187,63, +255,229,238,156,167,172,91,111,105,197,249,129,145,210,36,75,155,234,112, +188,183,15,149,41,11,139,86,44,3,254,64,41,141,93,97,3,75,94,115,217,14, +159,225,179,44,31,20,53,144,163,93,162,13,150,37,45,185,246,179,95,58,160, +88,70,22,59,71,101,85,26,119,53,55,148,246,129,67,153,44,44,58,247,72,233, +169,190,11,104,147,53,111,108,20,122,117,13,38,55,221,25,54,167,89,185, +147,29,147,116,86,62,227,143,141,197,26,137,34,150,189,121,38,182,226,175, +214,118,28,220,252,158,27,48,49,149,195,153,115,253,232,43,155,80,246,128, +141,245,11,80,153,174,192,43,167,47,34,127,219,199,49,49,126,25,181,13, +245,240,172,100,212,106,103,75,32,124,143,31,51,24,30,27,199,132,235,245, +32,148,230,28,31,31,46,59,93,75,67,13,150,180,52,96,100,124,138,85,226, +148,170,192,98,206,235,106,210,144,229,238,196,171,167,177,127,225,10,84, +191,209,131,250,166,38,70,105,198,155,142,217,91,114,45,162,29,111,14,12, +97,255,224,216,99,60,181,245,57,0,88,213,181,13,67,99,185,224,238,74,150, +212,202,101,45,104,93,210,140,37,55,214,210,234,81,101,25,56,75,86,14,30, +61,142,99,135,246,117,61,251,204,79,127,184,170,38,85,227,230,242,109,45, +55,54,177,107,74,75,231,130,38,235,10,143,122,184,194,82,168,4,112,252, +245,83,56,51,54,185,183,235,181,139,79,210,207,149,185,62,205,82,180,230, +186,198,230,229,235,54,117,126,175,114,65,221,170,104,183,28,81,32,84,78, +142,15,191,188,111,215,147,59,70,254,247,223,139,34,100,73,219,175,62,184, +124,71,107,109,245,250,101,239,93,140,250,122,106,218,136,9,166,38,134, +135,135,113,246,226,37,156,30,205,188,120,127,79,95,151,16,33,105,159,11, +128,112,101,201,164,180,70,90,245,140,111,8,209,205,68,44,220,209,120,44, +159,90,45,247,45,110,188,227,51,77,181,157,117,134,222,126,117,59,10,140, +184,222,201,189,3,163,79,252,250,210,224,17,14,47,75,69,34,108,236,215, +248,16,141,217,176,102,108,152,101,161,43,196,21,84,252,192,148,116,166, +99,208,82,210,149,241,181,112,71,78,155,164,13,199,128,167,226,107,243, +250,58,190,198,55,48,18,49,104,115,122,47,134,29,3,118,202,219,228,255, +5,24,0,238,123,163,24,29,62,142,101,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_21 = 1382; +static unsigned char xml_res_file_21[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,5,8,73,68,65,84,120,218,188,87,221,107,28,85,20,255,221,123,247, +35,219,205,182,214,26,65,76,137,77,95,170,144,244,69,13,66,13,81,40,166, +44,125,16,95,20,130,246,161,224,187,208,7,65,124,240,73,168,138,255,64, +177,196,40,197,135,250,17,107,179,20,2,106,181,95,84,209,68,12,213,52,164, +105,83,76,98,83,106,147,184,51,115,239,245,156,59,119,55,187,178,205,206, +34,102,147,147,201,206,204,189,231,55,191,243,59,31,3,108,238,71,76,95, +248,178,184,58,247,67,244,193,145,126,75,223,51,169,205,114,124,169,244, +225,174,71,118,118,126,42,97,122,69,42,13,37,36,159,207,203,77,112,174, +230,127,42,125,178,187,187,107,122,109,233,183,222,185,179,199,96,162,8, +66,8,190,150,110,198,64,234,163,55,6,63,203,101,100,81,210,2,145,208,163, +177,22,65,16,160,187,103,31,186,30,123,10,225,234,45,220,152,248,14,209, +234,50,64,215,140,53,80,42,126,246,102,0,114,217,148,40,190,117,106,141, +130,69,0,18,34,48,198,98,229,239,0,151,15,237,195,181,159,199,113,119,105, +22,66,146,43,50,107,66,88,77,12,200,100,0,218,68,140,2,109,116,103,43,0, +172,77,227,250,247,35,88,43,27,90,199,110,200,33,61,57,253,194,16,0,229, +55,107,6,64,8,43,192,244,51,96,153,16,0,7,75,41,5,75,139,140,224,144,192, +81,15,27,135,71,235,176,162,1,36,200,2,11,73,241,106,5,0,127,248,126,118, +70,207,28,3,0,124,252,233,124,20,186,61,19,1,16,70,130,239,149,210,38,7, +64,247,17,1,68,55,135,194,186,135,175,0,176,158,129,74,8,26,165,97,230, +224,123,176,207,29,197,73,6,40,53,135,64,17,101,178,101,211,4,192,104,235, +52,81,103,77,68,152,215,36,148,254,93,120,254,175,55,177,34,202,202,161, +85,196,64,82,17,114,172,37,209,101,109,3,6,232,71,135,161,211,213,189,24, +72,7,26,120,161,239,117,60,219,139,161,177,194,57,40,155,165,5,41,218,84, +182,96,202,229,187,211,129,55,205,71,206,2,42,68,170,134,129,116,241,29, +44,134,26,219,220,69,66,187,86,166,35,114,24,236,125,17,37,117,2,191,47, +127,3,59,57,0,153,9,9,178,78,34,1,167,25,237,247,51,46,1,4,57,39,86,72, +83,145,11,193,122,22,228,217,249,241,87,143,225,86,249,115,174,156,180, +144,110,176,247,99,98,254,4,14,244,190,12,153,30,198,121,249,53,212,47, +207,208,198,1,237,110,18,132,192,198,34,52,113,8,216,121,247,67,51,232, +216,58,143,185,104,176,210,11,28,128,12,63,249,157,242,2,190,189,242,197, +122,185,21,163,228,24,152,252,99,24,131,61,135,40,109,142,227,162,28,71, +219,212,0,237,30,197,94,54,0,192,89,160,141,113,79,175,173,112,212,63,120, +223,18,134,75,143,98,160,168,171,12,84,53,176,162,231,41,24,112,38,50,100, +124,36,120,150,54,186,242,231,199,120,98,207,30,68,157,55,221,73,167,114, +217,204,84,141,8,125,45,32,159,249,92,26,38,12,156,78,170,89,192,88,86, +237,13,168,44,170,12,88,83,83,80,82,1,46,77,79,33,51,223,233,106,2,152, +62,97,55,46,68,194,23,34,91,209,129,113,44,108,201,166,17,82,33,242,17, +136,25,224,77,67,117,19,217,60,197,99,11,145,144,163,11,153,216,82,109, +192,236,34,112,161,212,69,244,239,39,2,168,182,43,56,10,155,153,246,121, +111,201,179,37,0,11,183,119,224,192,147,63,82,33,138,234,52,192,0,238,30, +29,62,215,206,8,89,48,148,37,120,229,165,56,202,87,175,3,151,199,186,80, +184,186,31,50,27,120,200,178,169,8,149,18,113,231,179,194,237,73,42,192, +212,181,157,56,125,62,143,190,167,203,117,205,40,56,117,4,253,116,220,238, +163,145,30,124,27,167,153,133,95,167,129,197,241,14,20,166,73,181,25,202, +77,105,155,59,175,134,64,212,133,192,161,162,221,219,243,169,184,25,249, +94,192,127,87,200,102,200,38,201,38,248,127,86,240,204,28,80,58,137,175, +6,150,30,135,205,26,206,206,4,194,91,55,22,153,49,53,169,232,45,79,173, +61,34,17,214,246,2,170,46,184,77,182,224,109,153,4,140,51,163,56,123,241, +125,188,171,169,240,240,119,169,68,107,149,144,158,194,152,250,74,200,150, +73,81,143,160,24,75,121,239,118,28,142,190,134,189,254,255,40,146,177,98, +121,65,226,102,200,133,200,54,232,5,126,92,99,6,114,27,52,35,14,201,44, +223,75,86,208,116,112,180,10,139,22,122,17,105,64,186,218,175,27,0,8,117, +176,225,60,16,120,115,51,33,47,86,20,3,102,76,192,38,29,7,40,182,42,110, +197,218,214,173,114,253,134,24,16,169,132,19,17,231,176,139,63,68,107,12, +112,3,226,25,208,254,11,54,51,16,82,29,200,183,48,146,185,210,235,250,153, +77,60,18,113,8,226,46,136,245,145,204,143,134,38,42,83,88,115,201,0,164, +69,68,111,15,138,179,176,133,247,2,94,23,235,38,150,146,168,130,224,131, +99,160,70,132,153,161,161,161,114,195,141,104,225,216,50,171,122,201,127, +75,30,2,109,37,206,204,20,176,35,23,161,179,16,34,159,50,136,135,99,206, +130,114,117,34,114,3,201,200,200,200,110,158,11,26,17,224,207,103,254,235, +251,217,3,219,114,185,195,197,158,131,15,119,180,247,109,47,96,111,165, +27,10,191,121,222,59,251,223,94,78,253,254,237,100,91,201,168,229,225,14, +87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, +29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_22 = 116755; +static unsigned char xml_res_file_22[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, +32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, +116,115,46,111,114,103,47,116,114,117,110,107,47,111,118,101,114,118,105, +101,119,95,120,114,99,102,111,114,109,97,116,46,104,116,109,108,32,45,45, +62,10,60,114,101,115,111,117,114,99,101,32,120,109,108,110,115,61,34,104, +116,116,112,58,47,47,119,119,119,46,119,120,119,105,100,103,101,116,115, +46,111,114,103,47,119,120,120,114,99,34,32,118,101,114,115,105,111,110, +61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, +61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47,111,98,106,101, +99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65, +80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,100,105,115, +107,101,116,116,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,67,68,82,79, +77,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,99,100,46,112,110,103,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61,34,116, +111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86,73,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61, +34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,50,52,120,50,52,95,112,108,97,121,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66, +65,82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,97,117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76, +66,65,82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, +82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, +62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, +111,110,115,95,50,52,120,50,52,95,114,101,102,114,101,115,104,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,97,114,100,32,114,101,115,101,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84, +34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32,32,60,105,100,115, +45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,83,79,76,85,84,73,79,78,34,32,115,116,97,114,116,61,34,57,57,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,70,83,34,32,115,116,97,114,116,61,34,49,48,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,34,32,115,116,97,114, +116,61,34,49,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,34,32, +115,116,97,114,116,61,34,49,50,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67, +65,76,69,95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,51,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,32,115, +116,97,114,116,61,34,49,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114, +97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70, +34,32,115,116,97,114,116,61,34,50,48,48,48,34,47,62,10,32,32,60,105,100, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34,32,115,116,97, +114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73, +78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,51,49,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70, +82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51,50,48,48,34, +47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, +117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, +118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, +67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, +84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, +98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116, +111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,83,72,79,87,95,77,65,67,72,73,78,69,95,79,78,95,83, +84,65,82,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,111,110,32,115,116,97,114,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, +47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,111,110, +102,105,103,117,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,79,78,70,73, +71,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104, +105,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,105,115, +99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,82,69,83,69,84,95,67,79,78,70,73,82, +77,65,84,73,79,78,95,68,73,65,76,79,71,83,34,62,10,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,82,101,115,101,116,32,99,111,110,102,105, +114,109,97,116,105,111,110,32,100,105,97,108,111,103,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101, +112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,65,66,79,85,84,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,65,98,111,117,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,32,110,97,109,101,61,34,109,97,105,110,95,109,101, +110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,95,83,121,115,116,101,109,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70, +73,76,69,95,72,82,69,83,69,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,72,97,114,100,32,82,101,115,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73, +76,69,95,82,69,83,69,84,95,67,65,68,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,67,116,114,108,43,65,108,116,43,68,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,70,73,76,69,95,69,88, +73,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,104, +117,116,100,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +68,105,115,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,68,73,83,67,95,65,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101, +32,100,114,105,118,101,32,95,65,58,46,46,46,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,68,73,83,67,95, +66,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110, +103,101,32,100,114,105,118,101,32,95,66,58,46,46,46,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,69,74, +69,67,84,95,65,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,69,106,101,99,116,32,100,114,105,118,101,32,65,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,69,74, +69,67,84,95,66,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,106,101,99,116,32,100,114,105,118,101,32,66,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114, +97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,66,80,66,95,68,73,83,65,66,76,69,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108,101, +32,66,80,66,32,99,104,101,99,107,105,110,103,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, +47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,68,45,82,79,77,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,95,76,79,65,68,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97,100, +32,105,109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114, +34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,67,68,82,79,77,95,68,73,83,65,66,76,69,68,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,115,97,98,108,101,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,115,111,108,117,116,105,111,110,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73, +79,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,114,105,103,105,110,97,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,105,122,97,98, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83, +79,76,85,84,73,79,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,117,115,116,111,109,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,83,79,76,85,84,73,79,78,95,67,85,83,84,79,77,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,99,117,115, +116,111,109,32,114,101,115,111,108,117,116,105,111,110,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112, +59,38,97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101, +62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101, +32,102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, +116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, +76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, +117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114, +101,101,110,32,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,70,83,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,66,111,114,100,101,114,108,101,115,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69, +91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,69,120,99,108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68, +82,73,86,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,82,101,110,100,101,114,32,100,114,105,118,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +117,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, +78,68,69,82,95,68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116,51,68,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, +73,86,69,82,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,112,101,110,71,76,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76, +32,51,46,48,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, +78,68,69,82,95,68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,111,102,116,119,97,114,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,86,83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104, +101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73,77,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,109,32,100, +105,115,112,108,97,121,32,111,110,32,108,111,115,116,32,102,111,99,117, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, +116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,99,97,108,101,32,102,105,108,116,101,114, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, +76,69,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110, +101,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,116,114,101, +116,99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116, +101,103,101,114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69, +78,85,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46, +53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, +69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,52,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,71,76,32,51,46,48,32,114,101,110,100,101,114,101,114,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,116,114,101,116, +99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83, +113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84, +95,83,84,82,69,84,67,72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99,97, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112, +117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53, +120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78, +80,85,84,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, +83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65, +76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51, +46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,114, +101,102,114,101,115,104,32,114,97,116,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82, +69,83,72,95,82,65,84,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,97,109,101,32,97,115,32,101,109,117,108, +97,116,101,100,32,100,105,115,112,108,97,121,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, +82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,48,32,104,122,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +50,53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, +95,82,65,84,69,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,51,48,32,104,122,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, +95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,53,48,32,104,122,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54, +48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82, +65,84,69,91,55,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69, +70,82,69,83,72,95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100, +101,114,32,109,97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102, +101,114,32,108,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,78,68,95,66,85,70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,83,78,68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,50,48,48,32,109,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,48,48, +32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115, +99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114,101,101,110,115,104, +111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72, +79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +84,97,107,101,32,115,99,114,101,101,110,115,104,111,116,92,116,67,116,114, +108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, +72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, +79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, +51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, +72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62, +10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, +68,67,95,67,68,82,79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62, +10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, +68,67,95,69,68,73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,67,95,70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,78,69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10, +32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68, +67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34, +47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, +34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56, +48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114, +116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115, +116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114, +97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66, +69,76,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111, +103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117, +114,101,32,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, +99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, +69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84, +69,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, +114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,51,50,120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, +65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99, +32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, +122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, +99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, +105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, +103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, +65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, +115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, +97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, +73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68, +50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,111,105,99,101,98,111,111,107,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,72,66,95,68,69,70,65,85,76,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111, +105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,114,105,118,101,32,49,32,40,67,58,41,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, +65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73, +68,67,95,72,68,68,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47, +118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99,111,110,116, +114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105,116,109,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,106, +101,99,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, +95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, +66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90, +69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, +111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, +76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,51,32,40,69,58,41, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, +47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,48,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114, +100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, +82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, +117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50, +53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, +73,90,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, +111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,114,105,118,101,32,52,32,40,70,58,41,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, +76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,109,111,117,115,101,95,112,99,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,117,115,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,77,79,85,83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,78,101, +119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119, +32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32, +32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, +114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79, +84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, +85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, +101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,48,109,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,83,105, +122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,72,97, +114,100,32,68,105,115,99,32,80,97,114,97,109,101,116,101,114,115,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, +62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47, +62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116, +105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97,115, +101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, +108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108, +111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,83, +101,108,101,99,116,105,111,110,68,108,103,34,62,10,32,32,32,32,60,116,105, +116,108,101,62,80,67,101,109,32,67,111,110,102,105,103,117,114,97,116,105, +111,110,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62,10,32, +32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, +114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,114,111,119,115,62,49,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +50,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73,78, +71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,53,48,44,51,48,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97, +112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,116,111,111,108,116,105,112,62,76,111,97,100,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,110,116, +114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100, +100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, +82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97, +109,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, +50,120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76, +69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +99,111,109,112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89, +95,79,78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116, +105,116,108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110, +97,103,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110, +116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76, +34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82, +73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73, +83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100, +100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101, +32,117,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87, +78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,80,80,76, +89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,112,112,108,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101, +61,34,67,111,110,102,105,114,109,82,101,109,101,109,98,101,114,68,108,103, +34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76, +84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79, +78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, +108,101,62,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, +99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, +69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115,116,111,99,107,95, +105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79,78,34,32,115,116, +111,99,107,95,99,108,105,101,110,116,61,34,119,120,65,82,84,95,67,77,78, +95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,67, +79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, +82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73, +82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73,82,77,95,82,69, +77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98, +117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72, +79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,67,117,115,116,111,109,82,101,115,111,108,117,116,105, +111,110,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,116,105,116,108,101,62,67,117,115,116,111,109,32,114,101,115,111, +108,117,116,105,111,110,60,47,116,105,116,108,101,62,10,32,32,32,32,60, +99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, +69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112, +105,110,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,87,73,68, +84,72,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,54,52,48,60,47,118,97,108,117,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,60,47,109,105, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, +62,49,54,51,56,52,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67, +116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,72,69,73,71,72,84,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,62,52,56,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,60,47,109,105,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49, +54,51,56,52,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,76,105, +110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,65,98,111,117,116,68,108, +103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,99,101, +110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, +76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,67,101, +109,32,118,49,50,92,110,104,116,116,112,115,58,47,47,112,99,101,109,45, +101,109,117,108,97,116,111,114,46,99,111,46,117,107,47,92,110,92,110,84, +104,105,115,32,112,114,111,103,114,97,109,32,105,115,32,108,105,99,101, +110,115,101,100,32,117,110,100,101,114,32,116,104,101,32,71,78,85,32,71, +101,110,101,114,97,108,32,80,117,98,108,105,99,32,76,105,99,101,110,115, +101,32,118,101,114,115,105,111,110,32,50,46,92,110,83,101,101,32,67,79, +80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100,101,116,97,105, +108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105,99,111,110,115, +32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99,111,110,115,32, +40,104,116,116,112,115,58,47,47,114,111,117,110,100,105,99,111,110,115, +46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46,102,108,97,116, +105,99,111,110,46,99,111,109,92,110,79,116,104,101,114,32,105,99,111,110, +115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119,32,40,104,116,116, +112,58,47,47,119,119,119,46,102,97,116,99,111,119,46,99,111,109,47,102, +114,101,101,45,105,99,111,110,115,47,41,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$._pc.xrc")); +} diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 9eaac1a..f49d80f 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -49,6 +49,9 @@ SDL_Rect remembered_rect; int remembered_mouse_x = 0; int remembered_mouse_y = 0; +int custom_resolution_width = 640; +int custom_resolution_height = 480; + int win_doresize = 0; int winsizex = 640, winsizey = 480; @@ -517,6 +520,12 @@ void window_setup() rect.w = 640; rect.h = 480; } + + if (vid_resize == 2) + { + rect.w = custom_resolution_width; + rect.h = custom_resolution_height; + } } int window_create() @@ -692,8 +701,11 @@ int render() { window_dosetresize = 0; SDL_GetWindowSize(window, &rect.w, &rect.h); - SDL_SetWindowResizable(window, vid_resize); + SDL_SetWindowResizable(window, vid_resize == 1); SDL_SetWindowSize(window, rect.w, rect.h); + + if (vid_resize == 2) + SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); } if (renderer_doreset) { diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index 3f1bd91..5796bf1 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -39,6 +39,9 @@ SDL_Rect remembered_rect; int remembered_mouse_x = 0; int remembered_mouse_y = 0; +int custom_resolution_width = 640; +int custom_resolution_height = 480; + int win_doresize = 0; int winsizex = 640, winsizey = 480; @@ -304,6 +307,12 @@ void window_setup() rect.w = 640; rect.h = 480; } + + if (vid_resize == 2) + { + rect.w = custom_resolution_width; + rect.h = custom_resolution_height; + } } #ifdef __WINDOWS__ @@ -374,7 +383,7 @@ int window_create() { window = SDL_CreateWindow("PCem Display", rect.x, rect.y, rect.w, rect.h, - requested_render_driver.sdl_window_params | (vid_resize ? SDL_WINDOW_RESIZABLE : 0)); + requested_render_driver.sdl_window_params | (vid_resize == 1 ? SDL_WINDOW_RESIZABLE : 0)); if (!window) { char message[200]; @@ -427,11 +436,13 @@ int render() window_dosetresize = 0; #if SDL_VERSION_ATLEAST(2, 0, 5) SDL_GetWindowSize(window, &rect.w, &rect.h); - SDL_SetWindowResizable(window, vid_resize); + SDL_SetWindowResizable(window, vid_resize == 1); SDL_SetWindowSize(window, rect.w, rect.h); #else window_doreset = 1; #endif + if (vid_resize == 2) + SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); } if (window_doreset) { diff --git a/src/wx-sdl2-video.h b/src/wx-sdl2-video.h index 18dfd13..9265430 100644 --- a/src/wx-sdl2-video.h +++ b/src/wx-sdl2-video.h @@ -64,3 +64,6 @@ void color_flash(FLASH_FUNC func, int time_ms, char r, char g, char b, char a); extern sdl_render_driver requested_render_driver; extern char current_render_driver_name[50]; + +extern int custom_resolution_width; +extern int custom_resolution_height; diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 82709d4..67791e9 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -280,6 +280,9 @@ void sdl_loadconfig() strcpy(screenshot_format, config_get_string(CFG_MACHINE, "SDL2", "screenshot_format", IMAGE_PNG)); screenshot_flash = config_get_int(CFG_MACHINE, "SDL2", "screenshot_flash", 1); + custom_resolution_width = config_get_int(CFG_MACHINE, "SDL2", "custom_width", custom_resolution_width); + custom_resolution_height = config_get_int(CFG_MACHINE, "SDL2", "custom_height", custom_resolution_height); + video_fullscreen = config_get_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); video_fullscreen_mode = config_get_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); video_scale = config_get_int(CFG_MACHINE, "SDL2", "scale", video_scale); @@ -313,6 +316,9 @@ void sdl_saveconfig() config_set_string(CFG_MACHINE, "SDL2", "screenshot_format", screenshot_format); config_set_int(CFG_MACHINE, "SDL2", "screenshot_flash", screenshot_flash); + config_set_int(CFG_MACHINE, "SDL2", "custom_width", custom_resolution_width); + config_set_int(CFG_MACHINE, "SDL2", "custom_height", custom_resolution_height); + config_set_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); config_set_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); config_set_int(CFG_MACHINE, "SDL2", "scale", video_scale); @@ -383,8 +389,9 @@ int wx_setupmenu(void* data) { int c; update_cdrom_menu(menu); - if (vid_resize) - wx_checkmenuitem(menu, WX_ID("IDM_VID_RESIZE"), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_RESOLUTION[%d]", vid_resize); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_enablemenuitem(menu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); sprintf(menuitem, "IDM_VID_FS[%d]", video_fullscreen_scale); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); wx_checkmenuitem(menu, WX_ID("IDM_VID_FULLSCREEN"), video_fullscreen); @@ -731,6 +738,36 @@ void atapi_close(void) } } +int custom_resolution_callback(void* window, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + switch (message) + { + case WX_INITDIALOG: + { + wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_WIDTH")), WX_UDM_SETPOS, 0, custom_resolution_width); + wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_HEIGHT")), WX_UDM_SETPOS, 0, custom_resolution_height); + return TRUE; + } + case WX_COMMAND: + { + if (wParam == wxID_OK) + { + custom_resolution_width = wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_WIDTH")), WX_UDM_GETPOS, 0, 0); + custom_resolution_height = wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_HEIGHT")), WX_UDM_GETPOS, 0, 0); + wx_enddialog(window, 1); + return TRUE; + } + else if (wParam == wxID_CANCEL) + { + wx_enddialog(window, 0); + return TRUE; + } + + } + } + return 0; +} + int wx_handle_command(void* hwnd, int wParam, int checked) { void* hmenu; @@ -814,13 +851,27 @@ int wx_handle_command(void* hwnd, int wParam, int checked) if (emulation_state != EMULATION_STOPPED) wx_togglewindow(hwnd); } - else if (ID_IS("IDM_VID_RESIZE")) + else if (ID_RANGE("IDM_VID_RESOLUTION[start]", "IDM_VID_RESOLUTION[end]")) { - vid_resize = !vid_resize; - wx_checkmenuitem(hmenu, wParam, vid_resize); + vid_resize = wParam - wx_xrcid("IDM_VID_RESOLUTION[start]"); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); window_dosetresize = 1; + wx_enablemenuitem(hmenu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); saveconfig(NULL); } + else if (ID_IS("IDM_VID_RESOLUTION_CUSTOM")) + { + if (wx_dialogbox(hwnd, "CustomResolutionDlg", custom_resolution_callback)) + { + if (vid_resize != 2) + { + vid_resize = 2; + wx_checkmenuitem(hmenu, wx_xrcid("IDM_VID_RESOLUTION[2]"), WX_MB_CHECKED); + wx_enablemenuitem(hmenu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); + } + window_dosetresize = 1; + } + } else if (ID_IS("IDM_SCREENSHOT")) { take_screenshot = 1; From 7ec1adb65f05ee4352854d06f3f7e4168d3aabfe Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Aug 2017 13:53:13 +0100 Subject: [PATCH 0111/1050] SCAT memory changes. Patch from Greatpsycho. --- src/mem.c | 2 +- src/mem.h | 1 + src/scat.c | 131 ++++++++++++++++------------------------------------- 3 files changed, 41 insertions(+), 93 deletions(-) diff --git a/src/mem.c b/src/mem.c index be215ad..a731ddd 100644 --- a/src/mem.c +++ b/src/mem.c @@ -37,7 +37,7 @@ static int _mem_state[0x40000]; static mem_mapping_t base_mapping; mem_mapping_t ram_low_mapping; mem_mapping_t ram_high_mapping; -static mem_mapping_t ram_mid_mapping; +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]; diff --git a/src/mem.h b/src/mem.h index b8c923c..fc4c574 100644 --- a/src/mem.h +++ b/src/mem.h @@ -163,6 +163,7 @@ void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p); void mem_reset_page_blocks(); extern mem_mapping_t ram_low_mapping; +extern mem_mapping_t ram_mid_mapping; void mem_remap_top_256k(); void mem_remap_top_384k(); diff --git a/src/scat.c b/src/scat.c index 14a4406..2bcbb4d 100644 --- a/src/scat.c +++ b/src/scat.c @@ -27,6 +27,7 @@ void scat_shadow_state_update() { int i, val; + // TODO - ROMCS enable features should be implemented later. 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; @@ -95,7 +96,7 @@ void scat_set_xms_bound(uint8_t val) break; } - if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) { if (val != 1) { @@ -133,9 +134,11 @@ uint32_t get_scat_addr(uint32_t addr, scat_t *p) } else if (p == NULL && mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7)) addr &= 0x7FFFF; - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && addr >= 0x100000) - addr -= 0x60000; - + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + { + if(addr >= 0x100000) addr -= 0x60000; + else if(addr >= 0xA0000) addr = 0xFFFFFFFF; + } return addr; } @@ -153,8 +156,9 @@ void scat_set_global_EMS_state(int state) { virt_addr = get_scat_addr(base_addr, &scat_stat[i]); if(i < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[i]); - mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); mem_mapping_enable(&scat_mapping[i]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); + else mem_mapping_set_exec(&scat_mapping[i], NULL); } else { @@ -163,6 +167,7 @@ void scat_set_global_EMS_state(int state) if(i < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[i]); } } + flushmmucache(); } void scat_write(uint16_t port, uint8_t val, void *priv) @@ -206,19 +211,28 @@ 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. + // TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. + val &= 0x40; scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: + // TODO - Implement mysterious address mapping when lower nibble of this register is 3 or 4 and memory size is greater than 1MB. if((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) { if((val & 0x0F) == 3) { + if(mem_size > 640) mem_mapping_disable(&scat_A000_BFFF_mapping); + if(mem_size > 768) mem_mapping_disable(&ram_mid_mapping); mem_mapping_enable(&scat_shadowram_mapping); } else { mem_mapping_disable(&scat_shadowram_mapping); + if(mem_size > 640 && (val & 0x0F) > 3) + { + mem_mapping_enable(&scat_A000_BFFF_mapping); + if(mem_size > 768) mem_mapping_enable(&ram_mid_mapping); + } } if(mem_size < 2048) { @@ -252,6 +266,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } if (scat_reg_valid) scat_regs[scat_index] = val; + else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); if (scat_shadow_update) scat_shadow_state_update(); // pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); @@ -272,20 +287,28 @@ void scat_write(uint16_t port, uint8_t val, void *priv) break; case 0x208: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x218: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // 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_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { + virt_addr = get_scat_addr(base_addr, &scat_stat[index]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_mapping[index], NULL); flushmmucache(); } } break; case 0x209: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x219: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // 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; @@ -300,7 +323,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) { virt_addr = get_scat_addr(base_addr, &scat_stat[index]); if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_mapping[index], NULL); mem_mapping_enable(&scat_mapping[index]); // pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); } @@ -321,64 +345,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } break; case 0x20A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) - { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - scat_ems_reg_2xA = val; - } - break; - - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { -// 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; - - if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) - { - flushmmucache(); - } - } - break; - case 0x219: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { -// 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_2x9 = val; - base_addr = (index + 16) << 14; - if (index >= 24) - base_addr += 0x30000; - - if (scat_regs[SCAT_EMS_CONTROL] & 0x80) - { - if (val & 0x80) - { - virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - mem_mapping_enable(&scat_mapping[index]); - pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); - } - else - { - mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_mapping[index]); - if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); - pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); - } - flushmmucache(); - } - - if (scat_ems_reg_2xA & 0x80) - { - scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & 0x1f); - } - } - break; case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); scat_ems_reg_2xA = val; @@ -413,7 +381,8 @@ uint8_t scat_read(uint16_t port, void *priv) break; case 0x208: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x218: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; @@ -421,7 +390,8 @@ uint8_t scat_read(uint16_t port, void *priv) } break; case 0x209: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) + case 0x219: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; @@ -429,31 +399,8 @@ uint8_t scat_read(uint16_t port, void *priv) } break; case 0x20A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x40) - { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - val = scat_ems_reg_2xA; - } - break; - - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - index = scat_ems_reg_2xA & 0x1F; - val = scat_stat[index].regs_2x8; - } - break; - case 0x219: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) - { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - index = scat_ems_reg_2xA & 0x1F; - val = scat_stat[index].regs_2x9; - } - break; case 0x21A: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == 0x41) + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); val = scat_ems_reg_2xA; From d47ab5df6b35197d26823350362ba6cf0c48d98b Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 2 Aug 2017 20:08:04 +0100 Subject: [PATCH 0112/1050] Add Mouse Systems mouse emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/mouse.c | 2 + src/mouse_msystems.c | 90 ++++++++++++++++++++++++++++++++++++ src/mouse_msystems.h | 1 + 13 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 src/mouse_msystems.c create mode 100644 src/mouse_msystems.h diff --git a/src/Makefile.am b/src/Makefile.am index 3bd5a14..97aeb66 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ -laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ +laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c mouse_msystems.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 430397b..6fa47a8 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -10,7 +10,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 1c97379..7b10f0e 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -9,7 +9,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index fb25ff6..cf89b39 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -9,7 +9,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index a4e5963..06e9b39 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -9,7 +9,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 9d1aa5b..109687a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.mingw-network b/src/Makefile.mingw-network index 8e59a27..8d29cb5 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 0465fd0..abe74a2 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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 10c5193..f90e677 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 9b2983a..2b714a6 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -8,7 +8,7 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/mouse.c b/src/mouse.c index 3ac9b84..b808aac 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,6 +1,7 @@ #include "ibm.h" #include "mouse.h" #include "amstrad.h" +#include "mouse_msystems.h" #include "mouse_ps2.h" #include "mouse_serial.h" #include "keyboard_olim24.h" @@ -8,6 +9,7 @@ static mouse_t *mouse_list[] = { &mouse_serial_microsoft, + &mouse_serial_msystems, &mouse_ps2_2_button, &mouse_intellimouse, &mouse_amstrad, diff --git a/src/mouse_msystems.c b/src/mouse_msystems.c new file mode 100644 index 0000000..340b2f7 --- /dev/null +++ b/src/mouse_msystems.c @@ -0,0 +1,90 @@ +#include +#include "ibm.h" +#include "mouse.h" +#include "pic.h" +#include "serial.h" +#include "timer.h" + +typedef struct mouse_msystems_t +{ + int mousepos, mousedelay; + int oldb; + SERIAL *serial; +} mouse_msystems_t; + +static void mouse_msystems_poll(int x, int y, int z, int b, void *p) +{ + mouse_msystems_t *mouse = (mouse_msystems_t *)p; + SERIAL *serial = mouse->serial; + uint8_t mousedat[4]; + + if (!(serial->ier & 1)) + return; + if (!x && !y && b == mouse->oldb) + return; + + mouse->oldb = b; + y = -y; + if (x > 127) + x = 127; + if (y > 127) + y = 127; + if (x < -128) + x = -128; + if (y < -128) + y = -128; + + /*Use Mouse Systems format*/ + mousedat[0] = 0x87; + if (b & 1) + mousedat[0] &= ~0x04; + if (b & 2) + mousedat[0] &= ~0x01; + if (b & 4) + mousedat[0] &= ~0x02; + + mousedat[1] = x; + mousedat[2] = y; + mousedat[3] = 0; + mousedat[4] = 0; + + 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]); + serial_write_fifo(mouse->serial, mousedat[3]); + serial_write_fifo(mouse->serial, mousedat[4]); + } +} + +static void *mouse_msystems_init() +{ + mouse_msystems_t *mouse = (mouse_msystems_t *)malloc(sizeof(mouse_msystems_t)); + memset(mouse, 0, sizeof(mouse_msystems_t)); + + mouse->serial = &serial1; + serial1.rcr_callback = NULL; + serial1.rcr_callback_p = NULL; + + return mouse; +} + +static void mouse_msystems_close(void *p) +{ + mouse_msystems_t *mouse = (mouse_msystems_t *)p; + + free(mouse); + + serial1.rcr_callback = NULL; +} + +mouse_t mouse_serial_msystems = +{ + "Mouse Systems 3-button mouse (serial)", + mouse_msystems_init, + mouse_msystems_close, + mouse_msystems_poll, + MOUSE_TYPE_SERIAL | MOUSE_TYPE_3BUTTON +}; diff --git a/src/mouse_msystems.h b/src/mouse_msystems.h new file mode 100644 index 0000000..0f1430f --- /dev/null +++ b/src/mouse_msystems.h @@ -0,0 +1 @@ +extern mouse_t mouse_serial_msystems; From 54d260846f650e8c65699bbacb87c13bcd7f8711 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 4 Aug 2017 22:05:54 +0100 Subject: [PATCH 0113/1050] Mask off top bits of VGA palette data. Fixes palette in Amulets & Armor. --- src/vid_svga.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index 7433072..ca09163 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -151,9 +151,9 @@ void svga_out(uint16_t addr, uint8_t val, void *p) svga->dac_pos++; break; case 2: - svga->vgapal[svga->dac_write].r = svga->dac_r; - svga->vgapal[svga->dac_write].g = svga->dac_g; - svga->vgapal[svga->dac_write].b = val; + svga->vgapal[svga->dac_write].r = svga->dac_r & 0x3f; + svga->vgapal[svga->dac_write].g = svga->dac_g & 0x3f; + svga->vgapal[svga->dac_write].b = val & 0x3f; 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 From ec6ba9366571d549dac1731a8bdbb0517e979580 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 5 Aug 2017 20:05:35 +0100 Subject: [PATCH 0114/1050] Fixed build warnings in wxWidgets GUI. --- src/model.h | 2 +- src/wx-config.c | 26 ++++++------------ src/wx-config_sel.c | 2 +- src/wx-deviceconfig.cc | 1 - src/wx-glslp-parser.c | 2 +- src/wx-sdl2-video-gl3.c | 61 ++++++++++++++++++----------------------- src/wx-shader_man.c | 2 -- src/wx-status.cc | 2 +- src/wx-utils.cc | 2 +- 9 files changed, 40 insertions(+), 60 deletions(-) diff --git a/src/model.h b/src/model.h index 3931288..4c23cb1 100644 --- a/src/model.h +++ b/src/model.h @@ -15,7 +15,7 @@ typedef struct { char name[8]; CPU *cpus; - } cpu[4]; + } cpu[5]; int fixed_gfxcard; int flags; int min_ram, max_ram; diff --git a/src/wx-config.c b/src/wx-config.c index 6ce096c..78ba9cc 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -23,7 +23,7 @@ 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 int settings_network_to_list[20], settings_list_to_network[20]; static char *hdd_names[16]; int has_been_inited = 0; @@ -55,14 +55,14 @@ static int mouse_valid(int type, int model) return 1; } -static int mpu401_available(int sound_card) +/*static int mpu401_available(int sound_card) { char* name = sound_card_get_internal_name(sound_card); if (name && (!strcmp(name, "sb16") || !strcmp(name, "sbawe32"))) return TRUE; return FALSE; -} +}*/ static void recalc_vid_list(void* hdlg, int model) { @@ -210,17 +210,14 @@ int config_dlgsave(void* hdlg) { char temp_str[256]; void* h; - int c, d; - int rom, gfx, fpu; + int c; + int gfx, fpu; int temp_cpu, temp_cpu_m, temp_model; int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; int temp_dynarec; - int cpu_flags; int temp_fda_type, temp_fdb_type; - int temp_joystick_type; - int cpu_type; int temp_mouse_type; - int hdd_changed; + int hdd_changed = 0; char s[260]; PcemHDC hd[4]; @@ -412,16 +409,13 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) char temp_str[256]; void* h; int c, d; - int rom, gfx, mem, fpu; + int gfx, mem; int temp_cpu, temp_cpu_m, temp_model; - int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; + int temp_sound_card_current; int temp_dynarec; int cpu_flags; - int temp_fda_type, temp_fdb_type; - int temp_joystick_type; int cpu_type; int temp_mouse_type; - int hdd_changed; switch (message) { @@ -945,6 +939,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) return 0; } } + return 0; } static struct @@ -1094,7 +1089,6 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l int c; PcemHDC hd[4]; FILE *f; - uint8_t buf[512]; int hd_type; switch (message) @@ -1412,7 +1406,6 @@ int hdconf_init(void* hdlg) int hdconf_update(void* hdlg) { char s[260]; - void* h; int is_mfm = hdd_controller_selected_is_mfm(hdlg); @@ -1896,7 +1889,6 @@ int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) int config_dialog_proc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - void* h; switch (message) { case WX_INITDIALOG: diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index f384e9b..7fea760 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -10,7 +10,7 @@ extern int config_open(void* hwnd); static void select_config(void* hdlg, char* name) { char s[512]; - int num, c, p; + int num, c; void* h; h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); diff --git a/src/wx-deviceconfig.cc b/src/wx-deviceconfig.cc index 6bd913f..310b6eb 100644 --- a/src/wx-deviceconfig.cc +++ b/src/wx-deviceconfig.cc @@ -173,7 +173,6 @@ int deviceconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, { device_config_selection_t *selection = config->selection; void* h = 0; - int val_int; switch (config->type) { diff --git a/src/wx-glslp-parser.c b/src/wx-glslp-parser.c index 02aa822..bd17443 100644 --- a/src/wx-glslp-parser.c +++ b/src/wx-glslp-parser.c @@ -41,7 +41,7 @@ static char* load_file(const char* fn) char* data = malloc(fsize+1); - long read = fread(data, fsize, 1, f); + fread(data, fsize, 1, f); fclose(f); data[fsize] = 0; diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index 2030190..e29b949 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -299,7 +299,7 @@ static void create_texture(struct shader_texture* tex) if (tex->height > max_texture_size) tex->height = max_texture_size; pclog("Create texture with size %dx%d\n", tex->width, tex->height); - glGenTextures(1, &tex->id); + glGenTextures(1, (GLuint *)&tex->id); glBindTexture(GL_TEXTURE_2D, tex->id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex->wrap_mode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex->wrap_mode); @@ -314,7 +314,7 @@ static void create_texture(struct shader_texture* tex) static void delete_texture(struct shader_texture* tex) { if (tex->id > 0) - glDeleteTextures(1, &tex->id); + glDeleteTextures(1, (GLuint *)&tex->id); tex->id = 0; } @@ -322,7 +322,7 @@ static void delete_fbo(struct shader_fbo* fbo) { if (fbo->id >= 0) { - glw->glDeleteFramebuffers(1, &fbo->id); + glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); delete_texture(&fbo->texture); } } @@ -336,9 +336,9 @@ static void delete_program(struct shader_program* program) static void delete_vbo(struct shader_vbo* vbo) { - if (vbo->color >= 0) glw->glDeleteBuffers(1, &vbo->color); - glw->glDeleteBuffers(1, &vbo->vertex_coord); - glw->glDeleteBuffers(1, &vbo->tex_coord); + if (vbo->color >= 0) glw->glDeleteBuffers(1, (GLuint *)&vbo->color); + glw->glDeleteBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glDeleteBuffers(1, (GLuint *)&vbo->tex_coord); } static void delete_pass(struct shader_pass* pass) @@ -346,7 +346,7 @@ static void delete_pass(struct shader_pass* pass) delete_fbo(&pass->fbo); delete_vbo(&pass->vbo); delete_program(&pass->program); - glw->glDeleteVertexArrays(1, &pass->vertex_array); + glw->glDeleteVertexArrays(1, (GLuint *)&pass->vertex_array); } static void delete_prev(struct shader_prev* prev) @@ -387,7 +387,7 @@ static void create_fbo(struct shader_fbo* fbo) { create_texture(&fbo->texture); - glw->glGenFramebuffers(1, &fbo->id); + glw->glGenFramebuffers(1, (GLuint *)&fbo->id); glw->glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); glw->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); @@ -435,8 +435,8 @@ static void recreate_fbo(struct shader_fbo* fbo, int width, int height) { if (width != fbo->texture.width || height != fbo->texture.height) { - glw->glDeleteFramebuffers(1, &fbo->id); - glDeleteTextures(1, &fbo->texture.id); + glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); + glDeleteTextures(1, (GLuint *)&fbo->texture.id); fbo->texture.width = width; fbo->texture.height = height; create_fbo(fbo); @@ -450,7 +450,7 @@ static int create_default_shader_tex(struct shader_pass* pass) !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_tex_src, &pass->program.fragment_shader) || !create_program(&pass->program)) return 0; - glw->glGenVertexArrays(1, &pass->vertex_array); + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); struct shader_uniforms* u = &pass->uniforms; int p = pass->program.id; @@ -472,7 +472,7 @@ static int create_default_shader_color(struct shader_pass* pass) !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_color_src, &pass->program.fragment_shader) || !create_program(&pass->program)) return 0; - glw->glGenVertexArrays(1, &pass->vertex_array); + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); struct shader_uniforms* u = &pass->uniforms; int p = pass->program.id; @@ -644,7 +644,7 @@ static glsl_t* load_glslp(glsl_t* glsl, int num_shader, const char* f) } pass->frame_count_mod = shader->frame_count_mod; - glw->glGenVertexArrays(1, &pass->vertex_array); + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); find_uniforms(gshader, i); setup_scale(shader, pass); if (i == p->num_shaders-1) /* last pass may or may not be an fbo depending on scale */ @@ -711,8 +711,6 @@ static glsl_t* load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) const char* f = shaders[i]; if (f && strlen(f)) { - struct glsl_shader* shader = &glsl->shaders[num-i-1]; - if (!load_glslp(glsl, i, f)) { failed = 1; @@ -800,9 +798,6 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM create_texture(&scene_texture); - GLint status; - char buffer[512]; - /* load shader */ // const char* shaders[1]; // shaders[0] = gl3_shader_file; @@ -868,12 +863,12 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM struct shader_vbo* vbo = &active_shader->scene.vbo; - glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(inv_vertex), inv_vertex, GL_STATIC_DRAW); glw->glVertexAttribPointer(active_shader->scene.uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - glw->glGenBuffers(1, &vbo->tex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); glw->glVertexAttribPointer(active_shader->scene.uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); @@ -891,20 +886,20 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM struct shader_vbo* vbo = &shader->passes[i].vbo; - glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); glw->glVertexAttribPointer(u->vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - glw->glGenBuffers(1, &vbo->tex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); glw->glVertexAttribPointer(u->tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); if (u->color) { - glw->glGenBuffers(1, &vbo->color); + glw->glGenBuffers(1, (GLuint *)&vbo->color); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); glw->glVertexAttribPointer(u->color, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)0); @@ -924,12 +919,12 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM glw->glBindVertexArray(prev_pass->vertex_array); - glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); glw->glVertexAttribPointer(prev_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - glw->glGenBuffers(1, &vbo->tex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); glw->glVertexAttribPointer(prev_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); @@ -939,11 +934,11 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM struct shader_prev* prev = &shader->prev[j]; struct shader_vbo* prev_vbo = &prev->vbo; - glw->glGenBuffers(1, &prev_vbo->vertex_coord); + glw->glGenBuffers(1, (GLuint *)&prev_vbo->vertex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->vertex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glGenBuffers(1, &prev_vbo->tex_coord); + glw->glGenBuffers(1, (GLuint *)&prev_vbo->tex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->tex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); } @@ -960,12 +955,12 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM struct shader_vbo* vbo = &final_pass->vbo; - glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); glw->glVertexAttribPointer(final_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - glw->glGenBuffers(1, &vbo->tex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); glw->glVertexAttribPointer(final_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); @@ -979,12 +974,12 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM struct shader_vbo* vbo = &color_pass->vbo; - glw->glGenBuffers(1, &vbo->vertex_coord); + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); glw->glVertexAttribPointer(color_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - glw->glGenBuffers(1, &vbo->color); + glw->glGenBuffers(1, (GLuint *)&vbo->color); glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); glw->glVertexAttribPointer(color_pass->uniforms.color, 4, GL_FLOAT, GL_TRUE, 4*sizeof(GLfloat), (GLvoid*)0); @@ -1058,8 +1053,6 @@ struct render_data { static void render_pass(struct render_data* data) { int i; - char s[64]; - GLint loc; GLuint texture_unit = 0; // pclog("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], pass->state.input_size[1], pass->state.input_texture_size[0], pass->state.input_texture_size[1], pass->state.output_size[0], pass->state.output_size[1], pass->state.output_texture_size[0], pass->state.output_texture_size[1], output_size[0], output_size[1]); @@ -1207,7 +1200,6 @@ void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, return; int s, i, j; - GLuint p; Uint32 ticks = SDL_GetTicks(); @@ -1292,7 +1284,6 @@ void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, for (s = 0; s < active_shader->num_shaders; ++s) { struct glsl_shader* shader = &active_shader->shaders[s]; - int last_shader = s == active_shader->num_shaders-1; // float refresh_rate = shader->shader_refresh_rate; // if (refresh_rate < 0) diff --git a/src/wx-shader_man.c b/src/wx-shader_man.c index 869a3aa..6d277d7 100644 --- a/src/wx-shader_man.c +++ b/src/wx-shader_man.c @@ -47,7 +47,6 @@ static void add_shader(int p, const char* s) static int shader_list_update(void* hdlg) { - char s[512]; int c; void* h; int num = 0; @@ -172,7 +171,6 @@ static int shader_manager_dlgproc(void* hdlg, int message, INT_PARAM wParam, LON } else if (wParam == WX_ID("IDC_REMOVE")) { - char name[64]; void* h; int c; h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); diff --git a/src/wx-status.cc b/src/wx-status.cc index b257d5f..eb00e0d 100644 --- a/src/wx-status.cc +++ b/src/wx-status.cc @@ -138,7 +138,7 @@ void StatusPane::Render(wxDC& dc) size = dc.GetTextExtent(s); dc.DrawText(s, x, height+5+(bitmap.GetHeight()-size.y)/2); width = MAX(width, x+size.x); - height = MAX(height, height+5+MAX(bitmap.GetHeight(), size.y)); + height = height+5+MAX(bitmap.GetHeight(), size.y); } else { x -= bitmap.GetWidth(); dc.DrawBitmap(bitmap, x, 5); diff --git a/src/wx-utils.cc b/src/wx-utils.cc index a88919c..707349e 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -280,7 +280,7 @@ int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) ((wxComboBox*) window)->Append((char*) param2); break; case WX_CB_SETCURSEL: - if (param1 >= 0 && param1 < ((wxComboBox*) window)->GetCount()) + if (param1 >= 0 && param1 < (int)((wxComboBox*) window)->GetCount()) ((wxComboBox*) window)->Select(param1); break; case WX_CB_GETCURSEL: From 03749ab0fb8c6d8262ddd7dd5b7f557e9fbe8e48 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 6 Aug 2017 12:39:53 +0100 Subject: [PATCH 0115/1050] Added network configuration to wxWidgets GUI. --- src/Makefile.mingw-wx-sdl2-network | 62 + src/icons/16x16/network_ethernet.png | Bin 0 -> 1402 bytes src/icons/16x16/widescreen.png | Bin 0 -> 664 bytes src/icons/32x32/network_ethernet.png | Bin 0 -> 2048 bytes src/icons/32x32/widescreen.png | Bin 0 -> 1468 bytes src/pc.xrc | 189 ++- src/wx-config.c | 94 +- src/wx-config_sel.c | 7 + src/wx-hostconfig.c | 229 ++++ src/wx-hostconfig.h | 1 + src/wx-resources.cpp | 1593 +++++++++++++++++--------- src/wx-utils.h | 3 + 12 files changed, 1633 insertions(+), 545 deletions(-) create mode 100644 src/Makefile.mingw-wx-sdl2-network create mode 100644 src/icons/16x16/network_ethernet.png create mode 100644 src/icons/16x16/widescreen.png create mode 100644 src/icons/32x32/network_ethernet.png create mode 100644 src/icons/32x32/widescreen.png create mode 100644 src/wx-hostconfig.c create mode 100644 src/wx-hostconfig.h diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network new file mode 100644 index 0000000..9085f5e --- /dev/null +++ b/src/Makefile.mingw-wx-sdl2-network @@ -0,0 +1,62 @@ +VPATH = . dosbox resid-fp +CPP = g++ +CC = gcc +WINDRES = windres.exe +WXVERSION = 31 +WXINCLUDE = C:/MinGW/include/wx/ +CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING +CXXFLAGS = $(CFLAGS) +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + scat.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ + wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ + wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx.res +DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 +NETOBJ = ne2000.o nethandler.o + +LIBS = -Wl,--subsystem,windows -mthreads -mwindows -lwxmsw$(WXVERSION)u_xrc -lwxmsw$(WXVERSION)u_html -lwxmsw$(WXVERSION)u_adv -lwxbase$(WXVERSION)u_xml -lwxmsw$(WXVERSION)u_core -lwxbase$(WXVERSION)u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -lcomdlg32 -lwinspool -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lmingw32 -lopengl32 -lopenal32 -lstdc++ -lSDL2main -lSDL2 -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc -lwsock32 -liphlpapi + +PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) libslirp.a + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) slirp/libslirp.a -o "PCem-wx-SDL2.exe" $(LIBS) + strip -s PCem-wx-SDL2.exe + +libslirp.a: + $(MAKE) -C slirp + +all : libslirp.a PCem-wx-SDL2.exe + +clean : + rm *.o + rm PCem-wx-SDL2.exe + rm *.res + +wx-resources.o : pc.xrc + -wxrc -c pc.xrc -o wx-resources.cpp + $(CPP) $(CXXFLAGS) -c wx-resources.cpp + +%.o : %.c + $(CC) $(CFLAGS) -c $< + +%.o : %.cc + $(CPP) $(CXXFLAGS) -c $< + +%.o : %.cpp + $(CPP) $(CXXFLAGS) -c $< + +wx.res: wx.rc + $(WINDRES) -I$(WXINCLUDE)/../ -i wx.rc --input-format=rc -o wx.res -O coff diff --git a/src/icons/16x16/network_ethernet.png b/src/icons/16x16/network_ethernet.png new file mode 100644 index 0000000000000000000000000000000000000000..01b1d4cbf5fb6c112d8de44f47cf7c9c912c8ac7 GIT binary patch literal 1402 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh*)icxGNo zet9uiy|1s8XI^nhVqS8pr;Du;&;-5A%oHnQM@wTDOJ@s5b5kcnLsvs5Cu0L=7h@+g z7egllQxg-IUYGpj(%jU%5}4i;gkDRWdO=Acw*Y9fOKMSOS!#+~QGTuh*vnR#xZPrg z(>$o&6x?nx$EjBz=oo!a#3DsBObD2IKumbD1#;jCKQ#}S+KYh6S}E<YzAXIrf(bGz^QL)9uW5;x8>3%zOQJbdfg|%1w-b}0ii#4K z*>q(yttifEU4mB<1g)iWFUjmqDNp~Db|?0G-ei%V2{X38uYEt;JpZ1Nrm948#`fFs zC)YLaJ2^2=YUW&tBlj~*q$X=!cVSX=`FrvRi_U4L=WIO9%6+YUOScIa9x^!c?OK@a z*~cdq2I(!X+TO+fJv$IbG%ex=AYdSSsjNOuJd0nO_W-emnYTzh=c8U>>c~C0BOmi zU%!g}%9-uL^R{~t$3FQ5W)?sCxmp@7)&72F`j)BKU;IM2*2@S1mWb%sh2kA1?uFe< zTOxwy)p;Fz$z`r;T=zRd=b;!&h0~@r($|mkzvp_o%y6FY8J3#+_p`S~B|DjS_$^m^ zwJcEis=!H$kjHLQ4bPs{@^YUU5ZXV%zVO%0M+Z-SG?#goZ}&>`nfh9JD|7V=t*8AT z&v(u=&HR+Oso>|iH|Kox)qjh}>Fhi6OKHh08}5VaWADtaT64Q>?})D#jBA_NZfOz!q}vpX}s znRC74KpPJpH#7Ua@4fGvZ-n)PJC@##Nu)}N%5P)femRb|_^m#;y3 z3nfM&!Bp)mt|!O=4g%IIJXw9)*49=yEDmw0vx~WwL9=O)CI(5WkQ#}ESyPFKM0zAl zA+5*Vs|f;Ed*@ITC0erv^Q{DpW*}=c0$D49L=ngYwG&#hl|!DFaOCPx`7kdcDX1oi zj%#hWj!8sRH6lQe;NXQsUSzSn=wOgnP)0*WC}<`zEJIV)DB3156%|s?#<|c18(oLS z#{?PeC_O_m2~1+y;U0stLNG{00hDYmNwz4E4=k=PRPdt`Jo;G)p=MDq_~+20suV;+ zLDB`J7&U>yg0%~62$o$`2;Au4U|8aW>hU%N=IDTSsAzcCOhEg-EP;yf6|avjD7&B6 z4w$)LIIJx%^1$NHz}qZuiW3*h)qE~I85?8KIRkk zMuc^oLKMTndN^Go<|oJX#>%~$ix)4ieA(?b!~Wc^z^E?4G#u;OW>c zr7oO34eOj=I)8>!ITHk_l;g#l_f%Cv)=uijG`T6Q#n$!?esuR%KYZS~Rlf(aaPYmm ydgRz~Hjx9R$29SmM|YA~m^#}dzD)=I5?}xc)ekn|OcFi-0000 literal 0 HcmV?d00001 diff --git a/src/icons/32x32/network_ethernet.png b/src/icons/32x32/network_ethernet.png new file mode 100644 index 0000000000000000000000000000000000000000..9df8b73300e6367437efbe06b590e50c255e179e GIT binary patch literal 2048 zcmaJ?c~ld39v{P@M5v{Lf(RV~l!_r236PKgF$n~100V}Ayh=z02#`!nh7h8Zh+A9S zdXyE5YX!8eLakJ&eZsPwMM2Aby0Cy2fu#Z#4-gdGi51&FmYw%ze#iTKKHtyxcyDsT zLxZibTd)8CScUMpLUaXckztI_M9po=}i6C)9D0+KFKLjYR_$3tL^#iN|%A|jn_mR_zHrg zuyDVd5(~mX4y=Yi8iC{~C3%xUZz_RICDEyLJV+stNklS*Nb>O{lNdA~28j&5esE|s zwJd=l4XFh9n5Aj)dXVl`4iO!3eBLf>j_Vf<_>N zQF5gWPS?D`3j~Z1r3R5GrBDc$g+mnxa=DD*8^ojXNWMGRJ~TF&%p?2Kxg;K)!llzV zzT6-#cZJJ^rD+OCiL7vCe{eaga*d;)P@$2zkXo*VWI<|J0lrF^Az$4KeO0~JT-oYg z*sF4hs2QTMv43jx$`v|2#_gN2MGtQVA5x;zu13e2+);WF08G&eup@N?-$k)g9e6fN zUR4i<(thzSO^S5BYMR()Xgt;tc+1Sfro=tmEPMMQ!%3{?I}_@Af#2*LGaTjnst%pL zxVthE(^lznrg%r_Al1UPth(x_tgQaIfvJJ2-N9P~TFT?`)&p6~pXHH{oD!b0IRHUp z!B?JQ7T<;Hx9qlAx>ix~Y)h8;l3DQ0g_x3$D>v`E(9At?${_lCUw{9mtLFXHOw5Ok zeuX9PUK;u6B}aUzhb}ynTihNnkLQ(rJM4@3XAHg?`d6cf&+@Rqx0LS^=yPf2H`-Kx zbq|sadee_{@^=zF}2 zT^)r^j+=0FZYJz;w#!`bduuMlo+1L+6}4F%P3I}tb!&#rJhXSCF6VrIWBu`alB%Jm zZESFEug0mPW$UBo1zE0`4ZX+FkZtxC|AOJaAHu9CaHn8gwe|Ohd}p^V2jJ^s^Wtnp zz@3=w(QjAf7X}Ef`&w6)ZjUbOObQ*M3nD4JJy8yUY{S`T^_bZ+psa4RCL1s z!;4`7e(l%KT=-&QpRM0b>vdJmLov^J1gDdLecYL?wo^=S*WU8*4h!z>212Hp|L3bsVH$7a7WV`8mViIF~-rFGNYy>ABJz6Vt&oeY7|68MfHbBVx zRFz}tB{Jcufdemt8(q>))Hq-;ISa^!msoZYuRHw<;K?P&9QmfJv$9}jp(be@yVQj7bDONEu!uV-qDCB(o zQ>Xs%ir`5$r6_N~;6O+lJonyp1_#M{5VkyA@Fa+*=l3=L2=ebt+s?iyoS{x%o4tMd z#@^t?dP+RIGk$1kv1dN5{UgU=t>7AcX?(ofEVbD!yz<$?=INY=2escg4p1Mw5Ipps zHQ6(=xNC8~HY1k+*RZe5Y*Sw`*a()R(`OqpzBn7&o?VjCUvusS$HZJqWj)q$A69=A z(G=F*>d-GACDb~4Sljk!u%>!!&%)?7QxSXY%f7su=>uXfb#U=-_ofD0e{jPGw(#%H zdGhV(W@}V#1s@#ubYoYU`C!}Dc4l>BPaSh~ca9CI@w14V1Yd+1)&RxJJ$r0>J{vOr OlS6o++|nI!+5ZLbszZhV literal 0 HcmV?d00001 diff --git a/src/icons/32x32/widescreen.png b/src/icons/32x32/widescreen.png new file mode 100644 index 0000000000000000000000000000000000000000..60042ace5f26dd6b720668b783ca67ce4b6c6951 GIT binary patch literal 1468 zcmV;t1w;CYP)Gk@0{;^=iEE&oTHsQ4DIm2;T%2p%JCB> ziXL?N^<{(&Q=X>pKJ&!%6mC;-AewvW&6AGJ9ypps`fWw@Am_EoCHhAj7h3S#Zl ztP4M`+reJXaO4QBnK^oK?g-_%gi9510C0}r0}c0A=$+c#RF1)cWe_8rS#riuWML7* zEX9`fIz~P%EP|BflL*ga%!VNfQ{dWBO#V8D_xa-clxD7ogd_C~H%Ze`wPLB%AS#!D zEA?TePMlgCIq!gVWUYX~<$$kaR6;;q!&d+0IZDL@C#Ndnc?`gPd7SfEy_QF<<2T zS<2YDLchKWhDt_rQ!d3C>{S|21|$U>S`l~^ij65i0SL4Nds1PA_I{*!oBQG0qLNnlL&S9$=0FgRpeR|k>mZTD7HYqcq zy4_Bl2B9g%wY0isW~c%T!J+h>jeQg~Y zY>Thk32tr63^i7kPZf$8gzblownW+E=o=WU&d$I7b{+ld&WT&;{BKJe#t+^&LJMaW zsf=DVKl|9j^_5yRvYxgxnF6q>;Ht5 z<_)96w0m%XzW(Ygl1wYGE7#g5M%&y^#%VLn4~*@RMS(6auTmpPHZV{vm1uO=0HtvB zG~N}~wllHarURwg^5xI#W@tKsif=n`6CFOdk8U2{0~?|JClIi|U>8H~lkNPK;D7kv!iH)o_s~xooDkYG`oA2!(|^zZ7GMBz Wz+owNPcqv800000 - + wxALL | wxALIGN_CENTER_VERTICAL 5 @@ -1873,6 +1873,51 @@ + + + 0 + icons/32x32/network_ethernet.png + + + + 0 + 2 + 0 + 0 + 1 + + + + wxALL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + @@ -2377,7 +2422,23 @@ 0 - + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + + icons/32x32/widescreen.png + 0 + + + @@ -2724,4 +2785,128 @@ + + + + 499,175 + Host Configuration + 1 + + wxVERTICAL + + + wxEXPAND | wxALL + 5 + + + + 0 + 1 + 0 + 0 + + + + + wxEXPAND | wxALL + 5 + + + + 0 + icons/32x32/network_ethernet.png + + + + 0 + 2 + 0 + 0 + + + + + wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + 550,-1 + + + + + + + wxALL + 5 + + + -1 + + + + + wxALL + 5 + + + 550,-1 + Combo! + + + + + + + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + wxALIGN_CENTER_HORIZONTAL|wxALL + 5 + + + + + + + + + + + + + diff --git a/src/wx-config.c b/src/wx-config.c index 78ba9cc..90d0dce 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -11,6 +11,7 @@ #include "model.h" #include "mouse.h" #include "mem.h" +#include "nethandler.h" #include "nvr.h" #include "sound.h" #include "video.h" @@ -23,7 +24,9 @@ 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]; +#ifdef USE_NETWORKING +static int settings_network_to_list[20], settings_list_to_network[20]; +#endif static char *hdd_names[16]; int has_been_inited = 0; @@ -206,6 +209,47 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd) } } +#ifdef USE_NETWORKING +static void recalc_net_list(void *hdlg, int model) +{ + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + int c = 0, d = 0; + int set_zero = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + + while (1) + { + char *s = network_card_getname(c); + + if (!s[0]) + break; + + settings_network_to_list[c] = d; + + if (network_card_available(c)) + { + device_t *network_dev = network_card_getdevice(c); + + if (!network_dev || (network_dev->flags & DEVICE_MCA) == (models[model].flags & MODEL_MCA)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + settings_list_to_network[d] = c; + d++; + } + else if (c == network_card_current) + set_zero = 1; + } + + c++; + } + if (set_zero) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, settings_network_to_list[network_card_current], 0); +} +#endif + int config_dlgsave(void* hdlg) { char temp_str[256]; @@ -217,6 +261,9 @@ int config_dlgsave(void* hdlg) int temp_dynarec; int temp_fda_type, temp_fdb_type; int temp_mouse_type; +#ifdef USE_NETWORKING + int temp_network_card; +#endif int hdd_changed = 0; char s[260]; PcemHDC hd[4]; @@ -282,13 +329,21 @@ int config_dlgsave(void* hdlg) if (hdd_names[c]) hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); +#ifdef USE_NETWORKING + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; +#endif if (temp_model != model || gfx != gfxcard || mem != mem_size || 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel) + temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel +#ifdef USE_NETWORKING + || temp_network_card != network_card_current +#endif + ) { if (!has_been_inited || confirm()) { @@ -306,6 +361,9 @@ int config_dlgsave(void* hdlg) voodoo_enabled = temp_voodoo; cpu_use_dynarec = temp_dynarec; mouse_type = temp_mouse_type; +#ifdef USE_NETWORKING + network_card_current = temp_network_card; +#endif fdd_set_type(0, temp_fda_type); fdd_set_type(1, temp_fdb_type); @@ -416,6 +474,9 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) int cpu_flags; int cpu_type; int temp_mouse_type; +#ifdef USE_NETWORKING + int temp_network_card; +#endif switch (message) { @@ -633,6 +694,16 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) hdconf_init(hdlg); +#ifdef USE_NETWORKING + recalc_net_list(hdlg, romstomodel[romset]); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + if (network_card_has_config(network_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); +#endif + return TRUE; } break; @@ -759,6 +830,9 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) recalc_hdd_list(hdlg, temp_model, 1); recalc_snd_list(hdlg, temp_model); +#ifdef USE_NETWORKING + recalc_net_list(hdlg, temp_model); +#endif } else if (wParam == WX_ID("IDC_COMBOCPUM")) { @@ -891,6 +965,19 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { hdconf_update(hdlg); } +#ifdef USE_NETWORKING + else if (wParam == WX_ID("IDC_COMBO_NETCARD")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + if (network_card_has_config(temp_network_card)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } +#endif // // case IDC_COMBOJOY: // if (HIWORD(wParam) == CBN_SELCHANGE) { @@ -1024,9 +1111,6 @@ static void check_hd_type(void* hdlg, off64_t sz) } } -#define ID_IS(s) wParam == wx_xrcid(s) -#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) - static void update_hdd_cdrom(void* hdlg) { void* h; diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index 7fea760..df769b7 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -2,6 +2,7 @@ #include "config.h" #include "wx-utils.h" #include "paths.h" +#include "wx-hostconfig.h" static int active_config = -1; @@ -277,6 +278,12 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L if (lParam == WX_LBN_DBLCLK) run(hdlg); } +#ifdef USE_NETWORKING + else if (wParam == WX_ID("IDC_CONFIG_HOST")) + { + hostconfig_open(hdlg); + } +#endif } break; } diff --git a/src/wx-hostconfig.c b/src/wx-hostconfig.c new file mode 100644 index 0000000..9cac6b8 --- /dev/null +++ b/src/wx-hostconfig.c @@ -0,0 +1,229 @@ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include + +#include "wx-utils.h" +#include "wx-sdl2.h" +#include "wx-hostconfig.h" + +#include "ibm.h" +#include "config.h" +#include "nethandler.h" + +static HINSTANCE net_hLib = 0; +static char *net_lib_name = "wpcap.dll"; +static pcap_if_t *alldevs; +static char *dev_name[20]; + +int (*_pcap_findalldevs)(pcap_if_t **, char *); +void (*_pcap_freealldevs)(pcap_if_t *); +pcap_t *(*_pcap_open_live)(const char *, int, int, int, char *); +int (*_pcap_datalink)(pcap_t *); +void (*_pcap_close)(pcap_t *); + +#define ETH_DEV_NAME_MAX 256 /* maximum device name size */ +#define ETH_DEV_DESC_MAX 256 /* maximum device description size */ +#define ETH_MAX_DEVICE 30 /* maximum ethernet devices */ +#define ETH_PROMISC 1 /* promiscuous mode = true */ +#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */ +#define PCAP_READ_TIMEOUT -1 + +static int get_network_name(char *dev_name, char *regval) +{ + if (dev_name[strlen( "\\Device\\NPF_" )] == '{') + { + char regkey[2048]; + HKEY reghnd; + + sprintf(regkey, "SYSTEM\\CurrentControlSet\\Control\\Network\\" + "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", dev_name+ + strlen("\\Device\\NPF_")); + + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0, KEY_QUERY_VALUE, ®hnd) == ERROR_SUCCESS) + { + DWORD reglen = 2048; + DWORD regtype; + + if (RegQueryValueExA(reghnd, "Name", NULL, ®type, (LPBYTE)regval, ®len) == ERROR_SUCCESS) + { + RegCloseKey (reghnd); + + if ((regtype != REG_SZ) || (reglen > 2048)) + return -1; + + /*Name now in regval*/ + return 0; + } + RegCloseKey (reghnd); + } + } + return -1; +} + +int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + void *h; + pcap_if_t *dev; + char errbuf[PCAP_ERRBUF_SIZE]; + + switch (message) + { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"SLiRP"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, FALSE); + + net_hLib = LoadLibraryA(net_lib_name); + + if (net_hLib) + { + int c = 0; + int match = 0; + + _pcap_findalldevs = (void *)GetProcAddress(net_hLib, "pcap_findalldevs"); + _pcap_freealldevs = (void *)GetProcAddress(net_hLib, "pcap_freealldevs"); + _pcap_open_live = (void *)GetProcAddress(net_hLib, "pcap_open_live"); + _pcap_datalink = (void *)GetProcAddress(net_hLib, "pcap_datalink"); + _pcap_close = (void *)GetProcAddress(net_hLib, "pcap_close"); + + if (_pcap_findalldevs(&alldevs, errbuf) != -1) + { + char *pcap_device = config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + + for (dev = alldevs; dev; dev = dev->next) + { + pcap_t *conn = _pcap_open_live(dev->name, ETH_MAX_PACKET, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf); + int datalink; + + if (conn) + { + datalink = _pcap_datalink(conn); + _pcap_close(conn); + } + + if (conn && datalink == DLT_EN10MB) + { + char desc[2048]; + char s[2048]; + + if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) + continue; + + if (pcap_device) + { + if (!strcmp(pcap_device, dev->name)) + match = c; + } + + dev_name[c++] = dev->name; + if (get_network_name(dev->name, desc)) + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)dev->name); + else + { + sprintf(s, "%s - %s", dev->name, desc); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + } + } + } + if (c) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"PCAP"); + + if (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_PCAP) + { + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + wx_sendmessage(h, WX_CB_SETCURSEL, match, 0); + wx_enablewindow(h, TRUE); + } + } + } + return TRUE; + + case WX_COMMAND: + if (wParam == wxID_OK) + { + int type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (type) /*PCAP*/ + { + int dev; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + dev = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + config_set_int(CFG_GLOBAL, NULL, "net_type", NET_PCAP); + config_set_string(CFG_GLOBAL, NULL, "pcap_device", dev_name[dev]); + } + else /*SLiRP*/ + { + config_set_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP); + config_set_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); + } + saveconfig_global_only(); + + wx_enddialog(hdlg, 1); + + if (net_hLib) + { + _pcap_freealldevs(alldevs); + _pcap_findalldevs = NULL; + _pcap_freealldevs = NULL; + _pcap_open_live = NULL; + _pcap_datalink = NULL; + _pcap_close = NULL; + FreeLibrary(net_hLib); + } + return TRUE; + } + else if (wParam == wxID_CANCEL) + { + wx_enddialog(hdlg, 0); + if (net_hLib) + { + _pcap_freealldevs(alldevs); + _pcap_findalldevs = NULL; + _pcap_freealldevs = NULL; + _pcap_open_live = NULL; + _pcap_datalink = NULL; + _pcap_close = NULL; + FreeLibrary(net_hLib); + } + return TRUE; + } + else if (ID_IS("IDC_COMBO_NETWORK_TYPE")) + { + int type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + if (!type) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + + return TRUE; + } + break; + } + + return TRUE; +} + +int hostconfig_open(void *hwnd) +{ + return wx_dialogbox(hwnd, "HostConfig", hostconfig_dialog_proc); +} diff --git a/src/wx-hostconfig.h b/src/wx-hostconfig.h new file mode 100644 index 0000000..eeb03cd --- /dev/null +++ b/src/wx-hostconfig.h @@ -0,0 +1 @@ +int hostconfig_open(void *hwnd); diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 3a1d625..6360bce 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -850,11 +850,112 @@ static unsigned char xml_res_file_15[] = { 117,197,150,115,135,151,229,88,93,14,192,233,243,63,1,6,0,218,58,168,206, 121,36,62,30,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_16 = 1971; +static size_t xml_res_size_16 = 2048; static unsigned char xml_res_file_16[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,3,34,105,84,88,116,88,77,76,58,99,111,109,46,97,100,111,98,101,46, +120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,103,105, +110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104, +105,72,122,114,101,83,122,78,84,99,122,107,99,57,100,34,63,62,32,60,120, +58,120,109,112,109,101,116,97,32,120,109,108,110,115,58,120,61,34,97,100, +111,98,101,58,110,115,58,109,101,116,97,47,34,32,120,58,120,109,112,116, +107,61,34,65,100,111,98,101,32,88,77,80,32,67,111,114,101,32,53,46,48,45, +99,48,54,49,32,54,52,46,49,52,48,57,52,57,44,32,50,48,49,48,47,49,50,47, +48,55,45,49,48,58,53,55,58,48,49,32,32,32,32,32,32,32,32,34,62,32,60,114, +100,102,58,82,68,70,32,120,109,108,110,115,58,114,100,102,61,34,104,116, +116,112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,49,57,57,57,47, +48,50,47,50,50,45,114,100,102,45,115,121,110,116,97,120,45,110,115,35,34, +62,32,60,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,32,114, +100,102,58,97,98,111,117,116,61,34,34,32,120,109,108,110,115,58,120,109, +112,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99,111, +109,47,120,97,112,47,49,46,48,47,34,32,120,109,108,110,115,58,120,109,112, +77,77,61,34,104,116,116,112,58,47,47,110,115,46,97,100,111,98,101,46,99, +111,109,47,120,97,112,47,49,46,48,47,109,109,47,34,32,120,109,108,110,115, +58,115,116,82,101,102,61,34,104,116,116,112,58,47,47,110,115,46,97,100, +111,98,101,46,99,111,109,47,120,97,112,47,49,46,48,47,115,84,121,112,101, +47,82,101,115,111,117,114,99,101,82,101,102,35,34,32,120,109,112,58,67, +114,101,97,116,111,114,84,111,111,108,61,34,65,100,111,98,101,32,80,104, +111,116,111,115,104,111,112,32,67,83,53,46,49,32,87,105,110,100,111,119, +115,34,32,120,109,112,77,77,58,73,110,115,116,97,110,99,101,73,68,61,34, +120,109,112,46,105,105,100,58,56,70,69,52,69,48,56,66,65,55,53,65,49,49, +69,49,56,57,68,48,69,57,50,68,57,53,67,56,68,70,68,68,34,32,120,109,112, +77,77,58,68,111,99,117,109,101,110,116,73,68,61,34,120,109,112,46,100,105, +100,58,56,70,69,52,69,48,56,67,65,55,53,65,49,49,69,49,56,57,68,48,69,57, +50,68,57,53,67,56,68,70,68,68,34,62,32,60,120,109,112,77,77,58,68,101,114, +105,118,101,100,70,114,111,109,32,115,116,82,101,102,58,105,110,115,116, +97,110,99,101,73,68,61,34,120,109,112,46,105,105,100,58,56,70,69,52,69, +48,56,57,65,55,53,65,49,49,69,49,56,57,68,48,69,57,50,68,57,53,67,56,68, +70,68,68,34,32,115,116,82,101,102,58,100,111,99,117,109,101,110,116,73, +68,61,34,120,109,112,46,100,105,100,58,56,70,69,52,69,48,56,65,65,55,53, +65,49,49,69,49,56,57,68,48,69,57,50,68,57,53,67,56,68,70,68,68,34,47,62, +32,60,47,114,100,102,58,68,101,115,99,114,105,112,116,105,111,110,62,32, +60,47,114,100,102,58,82,68,70,62,32,60,47,120,58,120,109,112,109,101,116, +97,62,32,60,63,120,112,97,99,107,101,116,32,101,110,100,61,34,114,34,63, +62,49,208,174,166,0,0,4,116,73,68,65,84,120,218,172,87,65,108,27,69,20, +253,51,187,235,221,117,226,54,174,104,84,33,176,4,103,206,128,196,141,208, +64,201,5,9,20,169,39,80,5,130,43,129,128,144,10,45,18,231,114,225,64,165, +74,229,128,138,72,56,112,129,150,166,81,185,84,2,206,185,35,153,168,66, +78,219,52,9,36,177,189,187,195,127,127,215,246,218,236,218,187,81,71,26, +77,118,50,243,230,205,123,127,254,140,149,49,134,148,82,148,20,123,101, +101,229,71,173,245,2,250,31,101,193,26,81,20,253,180,184,184,248,26,127, +6,253,5,71,198,249,90,169,133,185,23,95,162,200,68,143,148,128,86,154,214, +215,215,22,176,6,215,189,60,2,94,196,59,159,169,31,167,223,126,255,67,88, +167,212,57,82,129,146,168,207,63,247,44,69,177,170,222,56,2,188,90,44,189, +101,217,196,86,72,61,42,9,44,204,178,75,77,122,146,53,6,197,206,112,139, +39,70,100,219,54,57,142,67,149,74,69,90,16,193,6,210,177,209,35,54,218, +135,110,44,218,237,118,169,211,233,72,107,196,210,255,111,196,206,98,30, +69,134,9,88,228,251,30,125,121,233,18,123,183,206,138,88,20,134,17,213, +235,53,106,109,237,208,236,201,227,244,224,65,172,228,137,19,131,190,237, +237,61,30,171,121,108,72,115,115,115,244,254,210,146,44,14,204,204,216, +200,234,12,13,44,112,200,117,61,186,125,251,87,170,213,106,52,53,53,205, +106,248,116,227,231,11,60,194,145,214,169,120,82,211,125,24,131,177,152, +131,185,192,0,86,152,115,168,50,21,160,40,100,5,52,75,111,49,64,69,118, +47,214,48,223,99,51,247,136,133,144,214,152,88,210,161,62,138,227,6,227, +49,23,24,192,2,102,97,2,32,107,107,155,44,84,203,150,30,120,107,219,138, +54,54,64,202,150,86,128,185,12,247,197,49,128,184,192,92,96,0,43,47,171, +100,19,96,191,52,131,107,246,82,89,0,196,174,44,242,92,69,231,206,125,69, +199,106,158,180,190,87,145,241,233,62,207,141,3,22,129,175,44,35,24,192, +50,57,49,96,231,29,33,200,46,85,33,24,125,249,59,14,246,73,25,50,86,0,65, +184,191,127,208,199,161,50,10,8,1,222,5,42,118,224,87,171,137,175,197,11, +142,225,97,187,221,199,41,65,32,246,91,115,30,208,204,28,242,251,158,127, +36,2,15,213,142,96,0,43,206,25,166,132,2,72,40,73,60,184,158,39,50,2,36, +118,193,228,221,56,241,28,254,63,44,192,92,149,96,21,86,0,216,90,43,89, +16,187,152,159,63,77,183,56,17,185,174,43,89,177,209,104,80,222,77,9,130, +205,102,83,178,95,155,229,199,92,96,0,11,152,89,211,178,79,1,118,194,19, +130,48,160,143,62,94,166,79,63,59,207,183,153,162,151,231,95,21,59,198, +17,8,187,33,221,90,251,69,46,30,144,0,25,96,153,28,21,236,60,32,75,91,178, +80,208,9,68,202,106,213,231,108,22,74,64,102,157,5,213,207,162,113,194, +57,60,56,164,48,8,101,32,176,84,25,2,240,12,249,124,176,83,147,4,86,234, +194,201,189,253,82,193,204,113,203,226,199,27,42,74,0,32,114,13,91,86,159, +128,72,200,237,153,87,230,233,230,218,90,238,185,70,224,97,12,198,42,36, +160,100,81,57,85,90,103,90,55,38,15,88,67,19,32,231,242,242,7,82,39,149, +128,199,106,220,115,122,248,218,46,149,136,112,137,12,51,86,3,69,114,0, +123,255,71,196,35,117,143,190,27,10,17,232,37,28,36,160,178,15,33,149,146, +60,243,238,207,72,102,163,4,204,238,238,238,157,213,213,213,23,6,207,168, +236,124,15,48,60,90,208,6,236,61,44,50,99,30,178,24,7,236,209,3,164,70, +158,229,53,174,13,174,143,141,179,167,231,210,210,135,159,92,191,122,245, +10,109,223,223,58,195,223,221,73,161,193,245,30,215,230,184,71,233,65,50, +160,149,249,128,27,46,117,219,157,38,183,58,67,116,127,235,79,254,222,158, +244,70,69,122,72,214,200,181,32,72,216,237,21,241,252,159,238,52,237,180, +241,202,150,197,91,71,250,193,50,98,65,209,98,221,253,250,212,247,117,207, +126,29,222,118,77,180,57,253,230,230,211,5,108,200,37,80,185,248,249,23, +237,137,239,124,118,165,29,218,52,235,252,77,239,62,241,3,85,223,250,75, +250,247,191,121,146,46,111,190,65,173,238,41,114,173,128,20,77,254,89,119, +241,194,121,151,155,78,207,130,169,107,215,190,157,252,67,3,6,118,52,61, +243,120,68,239,189,163,83,199,79,211,205,27,215,105,227,46,191,29,42,17, +21,212,115,10,4,122,10,212,249,227,41,4,86,65,229,156,214,149,198,119,218, +88,51,114,71,168,240,225,236,219,205,179,37,44,64,204,72,224,246,45,72, +24,57,5,1,112,37,158,76,142,45,37,65,187,5,55,10,206,7,209,127,211,10,148, +141,29,39,33,92,73,190,59,9,96,233,32,252,79,128,1,0,168,254,212,85,21, +212,140,221,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_17 = 1971; +static unsigned char xml_res_file_17[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, 60,0,0,7,85,73,68,65,84,120,218,156,87,123,76,149,231,25,255,125,215,115, 225,28,64,4,228,182,34,76,81,196,203,172,174,42,118,118,217,186,46,198, 75,170,105,154,213,206,118,107,27,99,155,45,157,201,178,196,54,248,135, @@ -951,8 +1052,8 @@ static unsigned char xml_res_file_16[] = { 60,140,219,229,21,77,101,241,228,231,127,2,12,0,35,187,154,106,194,98,206, 112,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_17 = 2315; -static unsigned char xml_res_file_17[] = { +static size_t xml_res_size_18 = 2315; +static unsigned char xml_res_file_18[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1068,8 +1169,83 @@ static unsigned char xml_res_file_17[] = { 131,67,255,223,235,63,2,12,0,116,106,129,252,126,87,16,179,0,0,0,0,73,69, 78,68,174,66,96,130}; -static size_t xml_res_size_18 = 2051; -static unsigned char xml_res_file_18[] = { +static size_t xml_res_size_19 = 1468; +static unsigned char xml_res_file_19[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,5,94,73,68,65,84,120,218,212,87,77,104,92,85,20,62,231,222,247,230, +39,127,77,155,212,68,44,149,86,208,218,85,68,65,65,220,9,110,2,34,6,2,186, +21,187,48,232,50,139,18,127,87,217,41,214,133,226,74,16,41,84,170,224,194, +133,186,178,162,168,52,85,169,26,109,193,159,226,79,27,90,51,201,76,242, +230,189,119,253,206,185,247,205,76,166,147,52,162,37,248,224,204,251,185, +239,221,239,156,239,124,231,220,59,236,156,163,157,60,12,237,240,193,225, +28,61,247,202,241,19,38,138,30,116,249,245,101,132,13,83,158,166,239,62, +243,196,244,20,110,83,113,32,154,123,233,205,147,142,205,228,29,19,135, +40,119,57,145,187,126,225,26,54,180,176,240,29,48,242,247,94,120,234,209, +135,34,60,174,146,177,147,71,103,166,41,15,148,240,38,223,255,91,191,138, +239,31,184,111,130,230,143,29,159,20,108,113,160,146,103,57,101,184,152, +121,246,85,170,196,134,44,247,128,10,98,237,212,172,11,63,174,219,193,94, +207,112,228,8,173,153,57,122,113,238,8,229,185,132,75,21,113,0,112,142, +224,3,13,247,87,232,157,218,221,84,142,193,129,101,16,35,156,89,114,198, +80,100,97,17,195,44,197,150,245,58,70,62,45,44,130,148,229,147,8,207,99, +204,134,33,10,83,224,218,81,76,254,58,135,247,249,226,251,148,102,174,136, +132,35,245,12,55,73,211,81,181,98,169,212,32,42,151,128,43,245,97,165,78, +156,90,28,57,239,128,117,100,173,128,193,228,185,56,192,222,9,1,43,64,35, +61,195,16,156,140,177,0,58,67,165,178,5,86,170,152,170,254,130,87,121,88, +142,99,253,202,96,98,70,196,234,5,0,12,102,80,19,86,48,110,49,38,145,131, +28,98,128,139,178,25,160,108,124,93,27,46,204,225,30,99,112,66,127,49,40, +24,130,229,58,29,144,155,117,60,44,149,34,76,98,240,162,211,73,41,56,97, +108,48,56,193,197,181,101,29,182,198,159,11,64,248,227,133,44,215,10,44, +247,185,8,0,44,24,197,16,44,71,157,14,64,16,45,6,36,6,165,221,207,42,128, +12,206,57,242,76,88,92,155,160,15,31,57,249,200,55,68,45,179,56,189,182, +228,169,247,202,100,42,1,163,9,44,242,34,244,14,228,36,41,200,212,59,215, +226,176,35,250,200,159,213,25,101,129,149,169,34,122,205,185,9,162,147, +156,147,215,130,13,226,115,89,81,49,76,101,209,64,210,67,3,235,73,19,222, +217,206,80,20,68,41,215,124,123,39,172,86,131,156,89,77,128,27,41,0,49, +95,228,252,89,202,216,186,66,191,190,10,134,74,70,115,83,46,197,26,236, +85,26,80,6,36,5,28,90,17,120,21,138,141,41,64,1,8,180,4,228,214,209,64, +147,38,204,5,38,29,107,16,218,198,241,192,73,77,139,165,169,94,187,44,67, +251,117,180,150,228,52,119,168,16,33,117,59,0,13,148,35,47,27,113,66,51, +224,105,206,97,171,25,0,145,58,103,125,122,216,122,150,164,18,100,54,41, +51,161,186,221,78,157,6,161,41,197,181,180,186,102,102,168,2,12,193,162, +78,6,242,162,10,10,6,216,151,151,36,80,162,204,82,159,204,34,255,146,120, +14,34,245,45,206,169,144,185,104,149,204,109,11,1,105,185,34,60,17,250, +58,38,204,54,166,128,60,3,34,66,237,79,254,67,233,88,210,170,184,115,194, +194,138,50,85,0,15,174,121,149,231,121,251,61,57,57,166,86,96,34,244,36, +201,90,77,218,139,16,222,11,3,67,240,78,216,200,240,69,232,148,202,228, +198,198,206,109,135,148,127,14,81,183,149,222,122,215,21,203,8,147,202, +3,239,9,203,43,107,169,50,214,102,32,148,161,197,218,84,111,226,69,163, +65,105,36,82,255,26,145,36,51,24,171,232,108,27,12,185,133,215,228,82,167, +103,74,77,16,33,171,57,29,35,4,9,210,98,52,162,90,87,39,244,26,200,200, +196,85,90,56,50,164,77,132,91,171,154,243,202,114,235,87,47,121,189,246, +54,220,113,207,30,130,165,51,176,95,13,191,189,144,64,204,181,141,14,112, +96,241,204,143,75,180,176,120,105,147,149,223,181,151,98,215,181,159,234, +186,87,9,245,220,85,248,238,89,145,213,206,191,164,14,184,122,109,249,212, +233,207,62,185,183,200,139,219,12,92,150,83,88,95,165,76,171,245,181,98, +14,29,235,239,171,80,125,109,29,26,108,139,175,219,9,110,109,203,12,53, +86,150,79,21,138,25,132,237,135,141,182,68,217,227,232,27,24,172,206,206, +191,254,118,29,253,234,206,137,91,233,252,111,75,27,198,15,222,56,66,11, +103,22,169,140,94,53,63,251,216,195,245,149,90,99,139,205,145,20,182,80, +253,51,7,208,170,236,78,182,216,141,149,158,126,249,173,95,108,127,63,101, +16,215,61,119,29,166,189,131,125,173,148,72,180,23,107,117,250,244,139, +179,218,53,179,149,149,228,249,39,31,185,5,67,201,22,187,179,53,88,35,10, +222,212,130,109,118,236,78,154,77,186,125,223,24,213,86,27,244,195,185, +95,105,177,235,255,132,148,230,13,163,195,180,123,112,128,190,254,234,44, +146,76,43,176,43,215,218,39,70,219,220,79,198,105,51,205,15,140,237,145, +69,129,46,47,175,82,35,73,54,48,80,45,149,104,116,215,0,165,112,244,52, +222,21,214,182,51,177,221,166,3,165,218,242,229,207,235,102,104,58,130, +138,111,59,112,19,29,62,184,143,110,30,223,3,27,161,253,227,163,152,40, +167,111,190,63,79,31,125,252,37,125,120,242,141,169,63,47,252,116,46,208, +188,173,63,38,215,58,202,176,49,17,235,212,227,179,51,195,163,227,247,71, +113,60,210,73,1,34,95,186,114,233,247,15,78,188,54,127,76,196,5,251,3,182, +254,95,57,192,129,210,97,216,94,216,174,224,84,103,39,16,176,191,96,23, +67,238,147,237,252,149,224,127,248,223,194,134,106,41,247,208,79,26,156, +16,218,51,250,191,28,188,211,127,207,255,22,96,0,113,192,97,41,118,79,50, +219,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_20 = 2051; +static unsigned char xml_res_file_20[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1172,8 +1348,8 @@ static unsigned char xml_res_file_18[] = { 128,139,229,223,112,255,19,96,0,111,126,151,122,57,77,224,198,0,0,0,0,73, 69,78,68,174,66,96,130}; -static size_t xml_res_size_19 = 2007; -static unsigned char xml_res_file_19[] = { +static size_t xml_res_size_21 = 2007; +static unsigned char xml_res_file_21[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1274,8 +1450,8 @@ static unsigned char xml_res_file_19[] = { 188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, 73,69,78,68,174,66,96,130}; -static size_t xml_res_size_20 = 2051; -static unsigned char xml_res_file_20[] = { +static size_t xml_res_size_22 = 2051; +static unsigned char xml_res_file_22[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1377,8 +1553,8 @@ static unsigned char xml_res_file_20[] = { 250,58,190,198,55,48,18,49,104,115,122,47,134,29,3,118,202,219,228,255, 5,24,0,238,123,163,24,29,62,142,101,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_21 = 1382; -static unsigned char xml_res_file_21[] = { +static size_t xml_res_size_23 = 1382; +static unsigned char xml_res_file_23[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1447,8 +1623,8 @@ static unsigned char xml_res_file_21[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_22 = 116755; -static unsigned char xml_res_file_22[] = { +static size_t xml_res_size_24 = 124249; +static unsigned char xml_res_file_24[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, 32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, @@ -5343,46 +5519,131 @@ static unsigned char xml_res_file_22[] = { 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,110,101,116,119,111,114,107,95,101,116,104,101, +114,110,101,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109, +95,112,97,110,101,108,110,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, +86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116,97,116, +105,99,84,101,120,116,55,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114,107,32,99, +97,114,100,32,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, +69,84,67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, -97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, @@ -6141,57 +6402,64 @@ static unsigned char xml_res_file_22[] = { 32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, -101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, 47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100, -100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, -82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97, -109,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, -50,120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, +95,72,79,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +119,105,100,101,115,99,114,101,101,110,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85, +95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100,100,46,112, 110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, 102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6205,116 +6473,119 @@ static unsigned char xml_res_file_22[] = { 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76, -69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,82,69,78, +65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, 115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47, +32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97,109,101,60,47, 116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, 114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -99,111,109,112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, -108,116,105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108, -103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, -85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89, -95,79,78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116, -105,116,108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110, -97,103,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110, -116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, -97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76, -34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +99,111,109,112,117,116,101,114,95,101,100,105,116,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82, -73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109, +112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108,103,34, +62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84, +95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78, +95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, +108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110,97,103,101, +114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, +101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73, -83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, -82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100, -100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, @@ -6323,42 +6594,73 @@ static unsigned char xml_res_file_22[] = { 32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32, +32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,111,110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101, -32,117,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87, -78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101,32,117,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,112,112,108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, @@ -6367,121 +6669,122 @@ static unsigned char xml_res_file_22[] = { 32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, 111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,80,80,76, -89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,65,112,112,108,121,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, -101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101, -61,34,67,111,110,102,105,114,109,82,101,109,101,109,98,101,114,68,108,103, -34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76, -84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79, -78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, -108,101,62,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, -99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, -69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,66,105,116,109,97,112,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,105,116,109,97,112,32,115,116,111,99,107,95, -105,100,61,34,119,120,65,82,84,95,81,85,69,83,84,73,79,78,34,32,115,116, -111,99,107,95,99,108,105,101,110,116,61,34,119,120,65,82,84,95,67,77,78, -95,68,73,65,76,79,71,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,67, -79,78,70,73,82,77,95,76,65,66,69,76,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73, -82,77,95,76,65,66,69,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73, -82,77,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,73,68,67,95,67,79,78,70,73,82,77,95,82,69, -77,69,77,66,69,82,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105, +97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82, +101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, +49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81, +85,69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116, +61,34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,82,77,95,82,69,77,69,77,66,69,82,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,67,95, +67,79,78,70,73,82,77,95,82,69,77,69,77,66,69,82,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,100,68,105,97,108,111,103,66,117,116, +116,111,110,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98,117,116,116,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78, +84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, 78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, @@ -6489,101 +6792,175 @@ static unsigned char xml_res_file_22[] = { 32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98, -117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72, -79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,67,97,110,99,101,108,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,67,117,115,116,111,109,82,101,115,111,108,117,116,105, -111,110,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, -68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, -83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101,62,10,32,32, -32,32,60,116,105,116,108,101,62,67,117,115,116,111,109,32,114,101,115,111, -108,117,116,105,111,110,60,47,116,105,116,108,101,62,10,32,32,32,32,60, -99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, -69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112, -105,110,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,87,73,68, -84,72,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,97,108,117,101,62,54,52,48,60,47,118,97,108,117,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,60,47,109,105, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120, -62,49,54,51,56,52,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,117,115,116,111,109, +82,101,115,111,108,117,116,105,111,110,68,108,103,34,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101,62,67,117, +115,116,111,109,32,114,101,115,111,108,117,116,105,111,110,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, +47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,87,73,68,84,72,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82, +79,87,95,75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,54,52,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,62,49,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,97,120,62,49,54,51,56,52,60,47,109,97,120,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,120,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,73, +68,67,95,72,69,73,71,72,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, +75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,52,56,48,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105, +110,62,49,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,109,97,120,62,49,54,51,56,52,60,47,109,97,120,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78, +84,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,100,68,105,97,108,111,103,66,117,116,116, +111,110,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98,117,116,116,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78, +84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, 114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67, -116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,72,69,73,71,72,84,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,62,52,56,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,49,60,47,109,105,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49, -54,51,56,52,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,65,98,111, +117,116,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32, +32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114, +101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84, +95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82, +84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,80,67,101,109,32,118,49,50,92,110,104,116,116,112,115,58,47, +47,112,99,101,109,45,101,109,117,108,97,116,111,114,46,99,111,46,117,107, +47,92,110,92,110,84,104,105,115,32,112,114,111,103,114,97,109,32,105,115, +32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116,104,101, +32,71,78,85,32,71,101,110,101,114,97,108,32,80,117,98,108,105,99,32,76, +105,99,101,110,115,101,32,118,101,114,115,105,111,110,32,50,46,92,110,83, +101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100, +101,116,97,105,108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105, +99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99, +111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117,110,100,105, +99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46, +102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104,101,114,32, +105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119, +32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,116,99,111,119,46, +99,111,109,47,102,114,101,101,45,105,99,111,110,115,47,41,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, @@ -6599,107 +6976,245 @@ static unsigned char xml_res_file_22[] = { 62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101, +61,34,72,111,115,116,67,111,110,102,105,103,34,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,115,105,122,101,62,52,57,57,44,49,55,53, +60,47,115,105,122,101,62,10,32,32,32,32,60,116,105,116,108,101,62,72,111, +115,116,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, +49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86, +69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,109,95,112,97,110,101,108,50,48, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,109,95,110,111,116,101,98, +111,111,107,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, +47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115, +111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120, +51,50,95,110,101,116,119,111,114,107,95,101,116,104,101,114,110,101,116, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109,95,112, +97,110,101,108,49,57,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, +86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116, +97,116,105,99,84,101,120,116,55,50,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,101,116,119,111,114,107,32,116,121,112,101,32,58,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, +69,84,87,79,82,75,95,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, +65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,53,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,109,95,115,116,97,116,105,99,84,101,120, +116,55,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114, +107,32,100,101,118,105,99,101,32,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,87,79,82,75,95, +68,69,86,73,67,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,67,111, +109,98,111,33,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,100,68,105,97,108, +111,103,66,117,116,116,111,110,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78, +84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, 34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98,117,116,116, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, -68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -68,105,97,108,111,103,34,32,110,97,109,101,61,34,65,98,111,117,116,68,108, -103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, -85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,99,101, -110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69, -76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, -60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,67,101, -109,32,118,49,50,92,110,104,116,116,112,115,58,47,47,112,99,101,109,45, -101,109,117,108,97,116,111,114,46,99,111,46,117,107,47,92,110,92,110,84, -104,105,115,32,112,114,111,103,114,97,109,32,105,115,32,108,105,99,101, -110,115,101,100,32,117,110,100,101,114,32,116,104,101,32,71,78,85,32,71, -101,110,101,114,97,108,32,80,117,98,108,105,99,32,76,105,99,101,110,115, -101,32,118,101,114,115,105,111,110,32,50,46,92,110,83,101,101,32,67,79, -80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100,101,116,97,105, -108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105,99,111,110,115, -32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99,111,110,115,32, -40,104,116,116,112,115,58,47,47,114,111,117,110,100,105,99,111,110,115, -46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46,102,108,97,116, -105,99,111,110,46,99,111,109,92,110,79,116,104,101,114,32,105,99,111,110, -115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119,32,40,104,116,116, -112,58,47,47,119,119,119,46,102,97,116,99,111,119,46,99,111,109,47,102, -114,101,101,45,105,99,111,110,115,47,41,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,75,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; void InitXmlResource() { @@ -6730,12 +7245,14 @@ void InitXmlResource() XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_24, xml_res_size_24, wxT("text/xml")); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$._pc.xrc")); } diff --git a/src/wx-utils.h b/src/wx-utils.h index 6ab844b..ab57a21 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -154,3 +154,6 @@ extern void (*wx_idle_func)(void* window, void* event); #define IMAGE_TIFF "tiff" extern int has_been_inited; + +#define ID_IS(s) wParam == wx_xrcid(s) +#define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) From 5a957e5d00b7db0299b9ada0567cbf04f93f62af Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 8 Aug 2017 21:19:36 +0100 Subject: [PATCH 0116/1050] SLiRP 64-bit fixes. Originally written by Gleb Natapov for QEMU. --- src/slirp/ip.h | 65 +++++++------------ src/slirp/ip_input.c | 148 +++++++++++++++++++++--------------------- src/slirp/misc.c | 35 ---------- src/slirp/slirp.c | 5 +- src/slirp/slirp.h | 23 +++---- src/slirp/tcp_input.c | 45 ++++++------- src/slirp/tcp_subr.c | 22 +++---- src/slirp/tcp_var.h | 25 +------ src/slirp/tcpip.h | 11 +++- src/slirp/udp.c | 5 +- src/slirp/udp.h | 3 +- 11 files changed, 155 insertions(+), 232 deletions(-) diff --git a/src/slirp/ip.h b/src/slirp/ip.h index f7fc59f..f11a847 100644 --- a/src/slirp/ip.h +++ b/src/slirp/ip.h @@ -199,23 +199,18 @@ struct ip_timestamp { #define IP_MSS 576 /* default maximum segment size */ -#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */ -#include -#else -#if SIZEOF_CHAR_P == 4 -typedef SLIRPcaddr_t caddr32_t; -#else -typedef u_int32_t caddr32_t; -#endif -#endif +struct mbuf_ptr { + union + { + struct mbuf *mptr; + uint64_t dummy; + } m; +}; -#if SIZEOF_CHAR_P == 4 -typedef struct ipq *ipqp_32; -typedef struct ipasfrag *ipasfragp_32; -#else -typedef caddr32_t ipqp_32; -typedef caddr32_t ipasfragp_32; -#endif + +struct qlink { + void *next, *prev; +}; /* * Overlay for ip header used by other protocols (tcp, udp). @@ -225,7 +220,7 @@ typedef caddr32_t ipasfragp_32; #endif struct ipovly { - caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ + struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ u_int8_t ih_x1; /* (unused) */ u_int8_t ih_pr; /* protocol */ u_int16_t ih_len; /* protocol length */ @@ -249,44 +244,30 @@ struct ipovly { * size 28 bytes */ struct ipq { - ipqp_32 next,prev; /* to other reass headers */ + struct qlink frag_link; /* to ip headers of fragments */ + struct qlink ip_link; /* to other reass headers */ u_int8_t ipq_ttl; /* time for reass q to live */ u_int8_t ipq_p; /* protocol of this fragment */ u_int16_t ipq_id; /* sequence id for reassembly */ - ipasfragp_32 ipq_next,ipq_prev; - /* to ip headers of fragments */ struct in_addr ipq_src,ipq_dst; }; /* * Ip header, when holding a fragment. * - * Note: ipf_next must be at same offset as ipq_next above + * Note: ipf_link must be at same offset as frag_link above */ struct ipasfrag { -#ifdef WORDS_BIGENDIAN - u_char ip_v:4, - ip_hl:4; -#else - u_char ip_hl:4, - ip_v:4; -#endif - /* BUG : u_int changed to u_int8_t. - * sizeof(u_int)==4 on linux 2.0 - */ - u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit - * to avoid destroying tos (PPPDTRuu); - * copied from (ip_off&IP_MF) */ - u_int16_t ip_len; - u_int16_t ip_id; - u_int16_t ip_off; - u_int8_t ip_ttl; - u_int8_t ip_p; - u_int16_t ip_sum; - ipasfragp_32 ipf_next; /* next fragment */ - ipasfragp_32 ipf_prev; /* previous fragment */ + struct qlink ipf_link; + struct ip ipf_ip; }; +#define ipf_off ipf_ip.ip_off +#define ipf_tos ipf_ip.ip_tos +#define ipf_len ipf_ip.ip_len +#define ipf_next ipf_link.next +#define ipf_prev ipf_link.prev + /* * Structure stored in mbuf in inpcb.ip_options * and passed to ip_output when ip options are in use. diff --git a/src/slirp/ip_input.c b/src/slirp/ip_input.c index 70d3fc8..7600f24 100644 --- a/src/slirp/ip_input.c +++ b/src/slirp/ip_input.c @@ -52,7 +52,7 @@ struct ipq ipq; void ip_init() { - ipq.next = ipq.prev = (ipqp_32)&ipq; + ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link; ip_id = tt.tv_sec & 0xffff; udp_init(); tcp_init(); @@ -154,19 +154,21 @@ ip_input(m) * XXX This should fail, don't fragment yet */ if (ip->ip_off &~ IP_DF) { - register struct ipq *fp; + struct ipq *fp; + struct qlink *l; /* * Look for queue of fragments * of this datagram. */ - for (fp = (struct ipq *) ipq.next; fp != &ipq; - fp = (struct ipq *) fp->next) - if (ip->ip_id == fp->ipq_id && - ip->ip_src.s_addr == fp->ipq_src.s_addr && - ip->ip_dst.s_addr == fp->ipq_dst.s_addr && - ip->ip_p == fp->ipq_p) + for (l = (struct qlink*)(ipq.ip_link.next); l != &ipq.ip_link; l = (struct qlink*)(l->next)) { + fp = container_of(l, struct ipq, ip_link); + if (ip->ip_id == fp->ipq_id && + ip->ip_src.s_addr == fp->ipq_src.s_addr && + ip->ip_dst.s_addr == fp->ipq_dst.s_addr && + ip->ip_p == fp->ipq_p) goto found; - fp = 0; + } + fp = NULL; found: /* @@ -176,9 +178,9 @@ ip_input(m) */ ip->ip_len -= hlen; if (ip->ip_off & IP_MF) - ((struct ipasfrag *)ip)->ipf_mff |= 1; + ip->ip_tos |= 1; else - ((struct ipasfrag *)ip)->ipf_mff &= ~1; + ip->ip_tos &= ~1; ip->ip_off <<= 3; @@ -187,9 +189,9 @@ ip_input(m) * or if this is not the first fragment, * attempt reassembly; if it succeeds, proceed. */ - if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { + if ((ip->ip_tos & 1) || ip->ip_off) { ipstat.ips_fragments++; - ip = ip_reass((struct ipasfrag *)ip, fp); + ip = ip_reass(ip, fp); if (ip == 0) return; ipstat.ips_reassembled++; @@ -225,16 +227,16 @@ bad: return; } +#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink))) +#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink))) + /* * Take incoming datagram fragment and try to * reassemble it into whole datagram. If a chain for * reassembly of this datagram already exists, then it * is given as fp; otherwise have to make a chain. */ -struct ip * -ip_reass(ip, fp) - register struct ipasfrag *ip; - register struct ipq *fp; +struct ip *ip_reass(struct ip *ip, struct ipq *fp) { register struct SLIRPmbuf *m = dtom(ip); register struct ipasfrag *q; @@ -261,13 +263,13 @@ ip_reass(ip, fp) struct SLIRPmbuf *t; if ((t = m_get()) == NULL) goto dropfrag; fp = mtod(t, struct ipq *); - insque_32(fp, &ipq); + insque(&fp->ip_link, &ipq.ip_link); fp->ipq_ttl = IPFRAGTTL; fp->ipq_p = ip->ip_p; fp->ipq_id = ip->ip_id; - fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp; - fp->ipq_src = ((struct ip *)ip)->ip_src; - fp->ipq_dst = ((struct ip *)ip)->ip_dst; + fp->frag_link.next = fp->frag_link.prev = &fp->frag_link; + fp->ipq_src = ip->ip_src; + fp->ipq_dst = ip->ip_dst; q = (struct ipasfrag *)fp; goto insert; } @@ -275,19 +277,19 @@ ip_reass(ip, fp) /* * Find a segment which begins after this one does. */ - for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *)q->ipf_next) - if (q->ip_off > ip->ip_off) + for (q = (struct ipasfrag*)fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; q = (struct ipasfrag*)(q->ipf_next)) { + if (q->ipf_off > ip->ip_off) break; + } /* * If there is a preceding segment, it may provide some of * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if (q->ipf_prev != (ipasfragp_32)fp) { - i = ((struct ipasfrag *)(q->ipf_prev))->ip_off + - ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off; + if (q->ipf_prev != &fp->frag_link) { + struct ipasfrag *pq = (struct ipasfrag*)(q->ipf_prev); + i = pq->ipf_off + pq->ipf_len - ip->ip_off; if (i > 0) { if (i >= ip->ip_len) goto dropfrag; @@ -301,17 +303,18 @@ ip_reass(ip, fp) * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { - i = (ip->ip_off + ip->ip_len) - q->ip_off; - if (i < q->ip_len) { - q->ip_len -= i; - q->ip_off += i; + while (q != (struct ipasfrag*)&fp->frag_link && + ip->ip_off + ip->ip_len > q->ipf_off) { + i = (ip->ip_off + ip->ip_len) - q->ipf_off; + if (i < q->ipf_len) { + q->ipf_len -= i; + q->ipf_off += i; m_adj(dtom(q), i); break; } - q = (struct ipasfrag *) q->ipf_next; - m_freem(dtom((struct ipasfrag *) q->ipf_prev)); - ip_deq((struct ipasfrag *) q->ipf_prev); + q = (struct ipasfrag*)(q->ipf_next); + m_freem(dtom(q->ipf_prev)); + ip_deq((struct ipasfrag*)(q->ipf_prev)); } insert: @@ -319,29 +322,27 @@ insert: * Stick new segment in its place; * check for complete reassembly. */ - ip_enq(ip, (struct ipasfrag *) q->ipf_prev); + ip_enq(iptofrag(ip), (struct ipasfrag*)(q->ipf_prev)); next = 0; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = (struct ipasfrag *) q->ipf_next) { - if (q->ip_off != next) - return (0); - next += q->ip_len; + for (q = (struct ipasfrag*)(fp->frag_link.next); q != (struct ipasfrag*)&fp->frag_link; q = (struct ipasfrag*)(q->ipf_next)) { + if (q->ipf_off != next) + return 0; + next += q->ipf_len; } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1) + if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1) return (0); /* * Reassembly is complete; concatenate fragments. */ - q = (struct ipasfrag *) fp->ipq_next; + q = (struct ipasfrag*)(fp->frag_link.next); m = dtom(q); q = (struct ipasfrag *) q->ipf_next; - while (q != (struct ipasfrag *)fp) { - struct SLIRPmbuf *t; - t = dtom(q); - q = (struct ipasfrag *) q->ipf_next; - m_cat(m, t); + while (q != (struct ipasfrag*)&fp->frag_link) { + struct mbuf *t = dtom(q); + q = (struct ipasfrag *) q->ipf_next; + m_cat(m, t); } /* @@ -350,7 +351,7 @@ insert: * dequeue and discard fragment reassembly header. * Make header visible. */ - ip = (struct ipasfrag *) fp->ipq_next; + q = (struct ipasfrag*)(fp->frag_link.next); /* * If the fragments concatenated to an SLIRPmbuf that's @@ -362,23 +363,23 @@ insert: if (m->m_flags & M_EXT) { int delta; delta = (char *)ip - m->m_dat; - ip = (struct ipasfrag *)(m->m_ext + delta); + q = (struct ipasfrag *)(m->m_ext + delta); } /* DEBUG_ARG("ip = %lx", (long)ip); * ip=(struct ipasfrag *)m->m_data; */ + ip = fragtoip(q); ip->ip_len = next; - ip->ipf_mff &= ~1; - ((struct ip *)ip)->ip_src = fp->ipq_src; - ((struct ip *)ip)->ip_dst = fp->ipq_dst; - remque_32(fp); + ip->ip_tos &= ~1; + ip->ip_src = fp->ipq_src; + ip->ip_dst = fp->ipq_dst; + remque(&fp->ip_link); (void) m_free(dtom(fp)); - m = dtom(ip); m->m_len += (ip->ip_hl << 2); m->m_data -= (ip->ip_hl << 2); - return ((struct ip *)ip); + return ip; dropfrag: ipstat.ips_fragdropped++; @@ -396,13 +397,12 @@ ip_freef(fp) { register struct ipasfrag *q, *p; - for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp; - q = p) { - p = (struct ipasfrag *) q->ipf_next; + for (q = (struct ipasfrag*)(fp->frag_link.next); q != (struct ipasfrag*)&fp->frag_link; q = p) { + p = (struct ipasfrag*)(q->ipf_next); ip_deq(q); m_freem(dtom(q)); } - remque_32(fp); + remque(&fp->ip_link); (void) m_free(dtom(fp)); } @@ -416,10 +416,10 @@ ip_enq(p, prev) { DEBUG_CALL("ip_enq"); DEBUG_ARG("prev = %lx", (long)prev); - p->ipf_prev = (ipasfragp_32) prev; + p->ipf_prev = prev; p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p; - prev->ipf_next = (ipasfragp_32) p; + ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p; + prev->ipf_next = p; } /* @@ -438,23 +438,23 @@ ip_deq(p) * if a timer expires on a reassembly * queue, discard it. */ -void -ip_slowtimo() +void ip_slowtimo() { - register struct ipq *fp; + struct qlink *l; DEBUG_CALL("ip_slowtimo"); - fp = (struct ipq *) ipq.next; - if (fp == 0) - return; + l = (struct qlink*)(ipq.ip_link.next); - while (fp != &ipq) { - --fp->ipq_ttl; - fp = (struct ipq *) fp->next; - if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { + if (l == 0) + return; + + while (l != &ipq.ip_link) { + struct ipq *fp = container_of(l, struct ipq, ip_link); + l = (struct qlink*)(l->next); + if (--fp->ipq_ttl == 0) { ipstat.ips_fragtimeout++; - ip_freef((struct ipq *) fp->prev); + ip_freef(fp); } } } diff --git a/src/slirp/misc.c b/src/slirp/misc.c index b1e2df2..e88567e 100644 --- a/src/slirp/misc.c +++ b/src/slirp/misc.c @@ -117,41 +117,6 @@ getouraddr() #undef ANCIENT } -//#if SIZEOF_CHAR_P == 8 -//what?! - -struct quehead_32 { - u_int32_t qh_link; - u_int32_t qh_rlink; -}; - -inline void -insque_32(a, b) - void *a; - void *b; -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - register struct quehead_32 *head = (struct quehead_32 *) b; - element->qh_link = head->qh_link; - head->qh_link = (u_int32_t)element; - element->qh_rlink = (u_int32_t)head; - ((struct quehead_32 *)(element->qh_link))->qh_rlink - = (u_int32_t)element; -} - -inline void -remque_32(a) - void *a; -{ - register struct quehead_32 *element = (struct quehead_32 *) a; - ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; - ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; - element->qh_rlink = 0; -} - -//#endif /* SIZEOF_CHAR_P == 8 */ -//Should be for 64bit - struct quehead { struct quehead *qh_link; struct quehead *qh_rlink; diff --git a/src/slirp/slirp.c b/src/slirp/slirp.c index 1ac66ae..a53ceb8 100644 --- a/src/slirp/slirp.c +++ b/src/slirp/slirp.c @@ -215,9 +215,8 @@ int slirp_select_fill(int *pnfds, * *_slowtimo needs calling if there are IP fragments * in the fragment queue, or there are TCP connections active */ - do_slowtimo = ((tcb.so_next != &tcb) || - ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next)); - + do_slowtimo = ((tcb.so_next != &tcb) || (&ipq.ip_link != ipq.ip_link.next)); + for (so = tcb.so_next; (so != &tcb); so = so_next) { so_next = so->so_next; diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index 83a1b6d..416b402 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -11,6 +11,12 @@ #include "config.h" #include "slirp_config.h" +#ifndef container_of +#define container_of(address, type, field) ((type *)( \ + (uintptr_t)(address) - \ + (uintptr_t)(&((type *)0)->field))) +#endif + #ifdef _WIN32 #ifdef __GNUC__ //MINGW? # include @@ -63,6 +69,7 @@ typedef int ioctlsockopt_t; # define ioctlsocket ioctl # define closesocket(s) close(s) # define O_BINARY 0 +typedef char *SLIRPcaddr_t; #endif #include @@ -320,20 +327,6 @@ void if_start _P((struct ttys *)); void lprint _P((const char *, ...)); -extern int do_echo; - -#ifdef _MSC_VER -#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 *)); -#endif - #ifndef _WIN32 #include #endif @@ -350,7 +343,7 @@ void if_output _P((struct SLIRPsocket *, struct SLIRPmbuf *)); /* ip_input.c */ void ip_init _P((void)); void ip_input _P((struct SLIRPmbuf *)); -struct ip * ip_reass _P((register struct ipasfrag *, register struct ipq *)); +struct ip * ip_reass _P((struct ip *, struct ipq *)); void ip_freef _P((struct ipq *)); void ip_enq _P((register struct ipasfrag *, register struct ipasfrag *)); void ip_deq _P((register struct ipasfrag *)); diff --git a/src/slirp/tcp_input.c b/src/slirp/tcp_input.c index 369ec00..f4c90bf 100644 --- a/src/slirp/tcp_input.c +++ b/src/slirp/tcp_input.c @@ -68,7 +68,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #ifdef TCP_ACK_HACK #define TCP_REASS(tp, ti, m, so, flags) {\ if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + tcpfrag_list_empty(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) {\ if (ti->ti_flags & TH_PUSH) \ tp->t_flags |= TF_ACKNOW; \ @@ -91,7 +91,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ #else #define TCP_REASS(tp, ti, m, so, flags) { \ if ((ti)->ti_seq == (tp)->rcv_nxt && \ - (tp)->seg_next == (tcpiphdrp_32)(tp) && \ + tcpfrag_list_empty(tp) && \ (tp)->t_state == TCPS_ESTABLISHED) { \ tp->t_flags |= TF_DELACK; \ (tp)->rcv_nxt += (ti)->ti_len; \ @@ -130,8 +130,8 @@ tcp_reass(tp, ti, m) /* * Find a segment which begins after this one does. */ - for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp; - q = (struct tcpiphdr *)q->ti_next) + for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); + q = tcpiphdr_next(q)) if (SEQ_GT(q->ti_seq, ti->ti_seq)) break; @@ -140,9 +140,9 @@ tcp_reass(tp, ti, m) * our data already. If so, drop the data from the incoming * segment. If it provides all of our data, drop us. */ - if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) { + if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { int i; - q = (struct tcpiphdr *)q->ti_prev; + q = tcpiphdr_prev(q); /* conversion to int (in i) handles seq wraparound */ i = q->ti_seq + q->ti_len - ti->ti_seq; if (i > 0) { @@ -162,36 +162,36 @@ tcp_reass(tp, ti, m) ti->ti_len -= i; ti->ti_seq += i; } - q = (struct tcpiphdr *)(q->ti_next); + q = tcpiphdr_next(q); } tcpstat.tcps_rcvoopack++; tcpstat.tcps_rcvoobyte += ti->ti_len; - REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ + ti->ti_mbuf = m; /* * While we overlap succeeding segments trim them or, * if they are completely covered, dequeue them. */ - while (q != (struct tcpiphdr *)tp) { + while (!tcpfrag_list_end(q, tp)) { int i = (ti->ti_seq + ti->ti_len) - q->ti_seq; if (i <= 0) break; if (i < q->ti_len) { q->ti_seq += i; q->ti_len -= i; - m_adj((struct SLIRPmbuf *) REASS_MBUF(q), i); + m_adj(q->ti_mbuf, i); break; } - q = (struct tcpiphdr *)q->ti_next; - m = (struct SLIRPmbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev); - remque_32((void *)(q->ti_prev)); + q = tcpiphdr_next(q); + m = tcpiphdr_prev(q)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(q))); m_freem(m); } /* * Stick new segment in its place. */ - insque_32(ti, (void *)(q->ti_prev)); + insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); present: /* @@ -200,17 +200,17 @@ present: */ if (!TCPS_HAVEESTABLISHED(tp->t_state)) return (0); - ti = (struct tcpiphdr *) tp->seg_next; - if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt) + ti = tcpfrag_list_first(tp); + if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt) return (0); if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len) return (0); do { tp->rcv_nxt += ti->ti_len; flags = ti->ti_flags & TH_FIN; - remque_32(ti); - m = (struct SLIRPmbuf *) REASS_MBUF(ti); /* XXX */ - ti = (struct tcpiphdr *)ti->ti_next; + remque(tcpiphdr2qlink(ti)); + m = ti->ti_mbuf; + ti = tcpiphdr_next(ti); /* if (so->so_state & SS_FCANTRCVMORE) */ if (so->so_state & SS_FCANTSENDMORE) m_freem(m); @@ -297,7 +297,8 @@ tcp_input(m, iphlen, inso) * Checksum extended TCP header and data. */ tlen = ((struct ip *)ti)->ip_len; - ti->ti_next = ti->ti_prev = 0; + tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0; + memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); ti->ti_x1 = 0; ti->ti_len = htons((u_int16_t)tlen); len = sizeof(struct ip ) + tlen; @@ -546,8 +547,8 @@ findso: return; } } else if (ti->ti_ack == tp->snd_una && - tp->seg_next == (tcpiphdrp_32)tp && - ti->ti_len <= sbspace(&so->so_rcv)) { + tcpfrag_list_empty(tp) && + ti->ti_len <= sbspace(&so->so_rcv)) { /* * this is a pure, in-sequence data packet * with nothing on the reassembly queue and diff --git a/src/slirp/tcp_subr.c b/src/slirp/tcp_subr.c index f275244..70661c2 100644 --- a/src/slirp/tcp_subr.c +++ b/src/slirp/tcp_subr.c @@ -81,7 +81,7 @@ tcp_template(tp) struct SLIRPsocket *so = tp->t_socket; struct tcpiphdr *n = &tp->t_template; - n->ti_next = n->ti_prev = 0; + n->ti_mbuf = NULL; n->ti_x1 = 0; n->ti_pr = IPPROTO_TCP; n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip)); @@ -164,7 +164,7 @@ tcp_respond(tp, ti, m, ack, seq, flags) tlen += sizeof (struct tcpiphdr); m->m_len = tlen; - ti->ti_next = ti->ti_prev = 0; + ti->ti_mbuf = 0; ti->ti_x1 = 0; ti->ti_seq = htonl(seq); ti->ti_ack = htonl(ack); @@ -204,7 +204,7 @@ tcp_newtcpcb(so) return ((struct tcpcb *)0); memset((char *) tp, 0, sizeof(struct tcpcb)); - tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp; + tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp; tp->t_maxseg = tcp_mssdflt; tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0; @@ -280,11 +280,11 @@ tcp_close(tp) DEBUG_ARG("tp = %lx", (long )tp); /* free the reassembly queue, if any */ - t = (struct tcpiphdr *) tp->seg_next; - while (t != (struct tcpiphdr *)tp) { - t = (struct tcpiphdr *)t->ti_next; - m = (struct SLIRPmbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev); - remque_32((struct tcpiphdr *) t->ti_prev); + t = tcpfrag_list_first(tp); + while (!tcpfrag_list_end(t, tp)) { + t = tcpiphdr_next(t); + m = tcpiphdr_prev(t)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(t))); m_freem(m); } /* It's static */ @@ -1120,7 +1120,7 @@ do_prompt: * A typical packet for player version 1.0 (release version): * * 0000:50 4E 41 00 05 - * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .....×..gælÜc..P + * 0000:00 01 00 02 1B D7 00 00 67 E6 6C DC 63 00 12 50 .......glc..P * 0010:4E 43 4C 49 45 4E 54 20 31 30 31 20 41 4C 50 48 NCLIENT 101 ALPH * 0020:41 6C 00 00 52 00 17 72 61 66 69 6C 65 73 2F 76 Al..R..rafiles/v * 0030:6F 61 2F 65 6E 67 6C 69 73 68 5F 2E 72 61 79 42 oa/english_.rayB @@ -1132,8 +1132,8 @@ do_prompt: * * A typical packet for player version 2.0 (beta): * - * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA...........Á. - * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxõc..Win2.0.0 + * 0000:50 4E 41 00 06 00 02 00 00 00 01 00 02 1B C1 00 PNA............ + * 0010:00 67 75 78 F5 63 00 0A 57 69 6E 32 2E 30 2E 30 .guxc..Win2.0.0 * 0020:2E 35 6C 00 00 52 00 1C 72 61 66 69 6C 65 73 2F .5l..R..rafiles/ * 0030:77 65 62 73 69 74 65 2F 32 30 72 65 6C 65 61 73 website/20releas * 0040:65 2E 72 61 79 53 00 00 06 36 42 e.rayS...6B diff --git a/src/slirp/tcp_var.h b/src/slirp/tcp_var.h index 422a57b..a0281cb 100644 --- a/src/slirp/tcp_var.h +++ b/src/slirp/tcp_var.h @@ -36,18 +36,12 @@ #include "tcpip.h" #include "tcp_timer.h" -#if SIZEOF_CHAR_P == 4 - typedef struct tcpiphdr *tcpiphdrp_32; -#else - typedef u_int32_t tcpiphdrp_32; -#endif - /* * Tcp control block, one per tcp; fields: */ struct tcpcb { - tcpiphdrp_32 seg_next; /* sequencing queue */ - tcpiphdrp_32 seg_prev; + struct tcpiphdr *seg_next; /* sequencing queue */ + struct tcpiphdr *seg_prev; short t_state; /* state of this connection */ short t_timer[TCPT_NTIMERS]; /* tcp timers */ short t_rxtshift; /* log(2) of rexmt exp. backoff */ @@ -166,21 +160,6 @@ struct tcpcb { #define TCP_REXMTVAL(tp) \ (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) -/* XXX - * We want to avoid doing m_pullup on incoming packets but that - * means avoiding dtom on the tcp reassembly code. That in turn means - * keeping an mbuf pointer in the reassembly queue (since we might - * have a cluster). As a quick hack, the source & destination - * port numbers (which are no longer needed once we've located the - * tcpcb) are overlayed with an mbuf pointer. - */ -#if SIZEOF_CHAR_P == 4 -typedef struct SLIRPmbuf *mbufp_32; -#else -typedef u_int32_t mbufp_32; -#endif -#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) - /* * TCP statistics. * Many of these should be kept per connection, diff --git a/src/slirp/tcpip.h b/src/slirp/tcpip.h index 2edccb2..5dbe0ff 100644 --- a/src/slirp/tcpip.h +++ b/src/slirp/tcpip.h @@ -40,8 +40,7 @@ struct tcpiphdr { struct ipovly ti_i; /* overlaid ip structure */ struct tcphdr ti_t; /* tcp header */ }; -#define ti_next ti_i.ih_next -#define ti_prev ti_i.ih_prev +#define ti_mbuf ti_i.ih_mbuf.m.mptr #define ti_x1 ti_i.ih_x1 #define ti_pr ti_i.ih_pr #define ti_len ti_i.ih_len @@ -58,6 +57,14 @@ struct tcpiphdr { #define ti_sum ti_t.th_sum #define ti_urp ti_t.th_urp +#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink))) +#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink))) +#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next) +#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev) +#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next) +#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T)) +#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T)) + /* * Just a clean way to get to the first byte * of the packet diff --git a/src/slirp/udp.c b/src/slirp/udp.c index 928a64f..0efd8e5 100644 --- a/src/slirp/udp.c +++ b/src/slirp/udp.c @@ -128,8 +128,7 @@ udp_input(m, iphlen) * Checksum extended UDP header and data. */ if (udpcksum && uh->uh_sum) { - ((struct ipovly *)ip)->ih_next = 0; - ((struct ipovly *)ip)->ih_prev = 0; + memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr)); ((struct ipovly *)ip)->ih_x1 = 0; ((struct ipovly *)ip)->ih_len = uh->uh_ulen; /* keep uh_sum for ICMP reply @@ -272,7 +271,7 @@ int udp_output2(struct SLIRPsocket *so, struct SLIRPmbuf *m, * and addresses and length put into network format. */ ui = mtod(m, struct udpiphdr *); - ui->ui_next = ui->ui_prev = 0; + memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr)); ui->ui_x1 = 0; ui->ui_pr = IPPROTO_UDP; ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */ diff --git a/src/slirp/udp.h b/src/slirp/udp.h index 807e55b..58ca011 100644 --- a/src/slirp/udp.h +++ b/src/slirp/udp.h @@ -64,8 +64,7 @@ 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_mbuf ui_i.ih_mbuf.m.mptr #define ui_x1 ui_i.ih_x1 #define ui_pr ui_i.ih_pr #define ui_len ui_i.ih_len From 7b081739bfab6b8f7dfc42fee8e5f10ba6b4e285 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 8 Aug 2017 21:32:39 +0100 Subject: [PATCH 0117/1050] Network card configuration added to wxWidgets GUI. --- src/pc.xrc | 10 + src/wx-config.c | 11 +- src/wx-resources.cpp | 720 ++++++++++++++++++++++--------------------- 3 files changed, 391 insertions(+), 350 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index 21c3425..a471e63 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -1913,6 +1913,16 @@ + + + wxALL + 5 + + + icons/16x16/setting_tools.png + 0 + + diff --git a/src/wx-config.c b/src/wx-config.c index 90d0dce..8da63c9 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -697,7 +697,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) #ifdef USE_NETWORKING recalc_net_list(hdlg, romstomodel[romset]); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); if (network_card_has_config(network_card_current)) wx_enablewindow(h, TRUE); else @@ -971,12 +971,19 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); if (network_card_has_config(temp_network_card)) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); } + else if (wParam == WX_ID("IDC_CONFIGURE_NETCARD")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); + } #endif // // case IDC_COMBOJOY: diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 6360bce..615d23d 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1623,7 +1623,7 @@ static unsigned char xml_res_file_23[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_24 = 124249; +static size_t xml_res_size_24 = 124770; static unsigned char xml_res_file_24[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -5599,23 +5599,360 @@ static unsigned char xml_res_file_24[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,95,78,69,84, +67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, +85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103, +95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34, +32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100,32,68,105,115, +99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, +101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, +68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82, +65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, +122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, 60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5624,6 +5961,26 @@ static unsigned char xml_res_file_24[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, @@ -5657,339 +6014,6 @@ static unsigned char xml_res_file_24[] = { 98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,78,101, -119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119, -32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32, -32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, -114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79, -84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, -60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62, -48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111, -119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, -97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, -85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, -101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, -115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,48,109,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, -97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, -78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,83,105, 122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,72,97, 114,100,32,68,105,115,99,32,80,97,114,97,109,101,116,101,114,115,60,47, From 24c552ca3805dcf966dba171d26e12380eefc1a3 Mon Sep 17 00:00:00 2001 From: pcem_emulator Date: Tue, 8 Aug 2017 21:59:53 +0100 Subject: [PATCH 0118/1050] Network support added to Linux build. --- configure | 31 ++++++ configure.ac | 10 ++ src/Makefile.am | 12 ++- src/Makefile.in | 229 +++++++++++++++++++++++++++++--------------- src/ne2000.c | 22 ++++- src/nethandler.c | 2 + src/wx-hostconfig.c | 21 +++- 7 files changed, 244 insertions(+), 83 deletions(-) diff --git a/configure b/configure index 632f62a..29941e4 100755 --- a/configure +++ b/configure @@ -610,6 +610,8 @@ PKG_CONFIG allegro_LIBS allegro_CFLAGS ALLEGRO_CONFIG +USE_NETWORKING_FALSE +USE_NETWORKING_TRUE USE_WX_FALSE USE_WX_TRUE OS_LINUX_FALSE @@ -724,6 +726,7 @@ enable_silent_rules enable_dependency_tracking enable_debug enable_wx +enable_networking with_allegro_prefix with_allegro_exec_prefix enable_allegrotest @@ -1388,6 +1391,7 @@ Optional Features: speeds up one-time build --enable-debug build debug executable --enable-wx use wxWidgets GUI + --enable-networking enable networking --disable-allegrotest Do not try to compile and run a test LIBallegro program --disable-sdltest Do not try to compile and run a test SDL program @@ -4158,6 +4162,21 @@ else $as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable networking" >&5 +$as_echo_n "checking whether to enable networking... " >&6; } +# Check whether --enable-networking was given. +if test "${enable_networking+set}" = set; then : + enableval=$enable_networking; +fi + +if test "$enable_networking" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu" >&5 $as_echo_n "checking for cpu... " >&6; } case "${host_cpu}" in @@ -4221,6 +4240,14 @@ else USE_WX_FALSE= fi + if test "$enable_networking" = "yes"; then + USE_NETWORKING_TRUE= + USE_NETWORKING_FALSE='#' +else + USE_NETWORKING_TRUE='#' + USE_NETWORKING_FALSE= +fi + if test "$enable_wx" != "yes"; then # Do not run test for Allegro with Win32/MinGW version, as binary builds have @@ -5608,6 +5635,10 @@ if test -z "${USE_WX_TRUE}" && test -z "${USE_WX_FALSE}"; then as_fn_error $? "conditional \"USE_WX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_NETWORKING_TRUE}" && test -z "${USE_NETWORKING_FALSE}"; then + as_fn_error $? "conditional \"USE_NETWORKING\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/configure.ac b/configure.ac index 449d532..15e8fd9 100644 --- a/configure.ac +++ b/configure.ac @@ -33,6 +33,15 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([whether to enable networking]) +AC_ARG_ENABLE(networking, + AC_HELP_STRING([--enable-networking], [enable networking])) +if test "$enable_networking" = "yes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + AC_MSG_CHECKING([for cpu]) case "${host_cpu}" in i?86) @@ -58,6 +67,7 @@ AM_CONDITIONAL(OS_WIN, test "$OS" = "win") AM_CONDITIONAL(OS_LINUX, test "$OS" = "linux") AM_CONDITIONAL(USE_WX, test "$enable_wx" = "yes") +AM_CONDITIONAL(USE_NETWORKING, test "$enable_networking" = "yes") if test "$enable_wx" != "yes"; then # Do not run test for Allegro with Win32/MinGW version, as binary builds have diff --git a/src/Makefile.am b/src/Makefile.am index 97aeb66..725252f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,9 @@ CLEANFILES = $(noinst_SCRIPTS) ../pcem: pcem cp pcem .. +slirp/libslirp.a: + $(MAKE) -C slirp + amrefresh: @@ -15,7 +18,7 @@ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ -laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c mouse_serial.c mouse_msystems.c neat.c nmi.c nvr.c olivetti_m24.c \ +laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 \ @@ -45,6 +48,7 @@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc else pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO +pcem_CXXFLAGS = pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES += allegro-gui.c allegro-gui-config-sel.c allegro-gui-configure.c \ allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c \ @@ -61,3 +65,9 @@ if CPU_X86_64 pcem_SOURCES += codegen_x86-64.c endif +if USE_NETWORKING +pcem_CFLAGS += -DUSE_NETWORKING +pcem_CXXFLAGS += -DUSE_NETWORKING +pcem_SOURCES += ne2000.c nethandler.c wx-hostconfig.c +pcem_LDADD += slirp/libslirp.a +endif diff --git a/src/Makefile.in b/src/Makefile.in index fb3161e..1cf4fdb 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -106,6 +106,10 @@ bin_PROGRAMS = pcem$(EXEEXT) @CPU_I386_TRUE@am__append_3 = codegen_x86.c @CPU_I386_TRUE@am__append_4 = -msse2 @CPU_X86_64_TRUE@am__append_5 = codegen_x86-64.c +@USE_NETWORKING_TRUE@am__append_6 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_7 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_8 = ne2000.c nethandler.c wx-hostconfig.c +@USE_NETWORKING_TRUE@am__append_9 = slirp/libslirp.a subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/allegro.m4 \ @@ -132,40 +136,40 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 laserxt.c lpt.c mca.c mcr.c \ - mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c \ - mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c \ - paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ - ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 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_colorplus.c \ - vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ - vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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 \ - vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ - sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ - dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ - wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ - wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ - wx-sdl2-video.c wx-sdl2-midi.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ + mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c \ + mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ + opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c \ + ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ + vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ + vid_incolor.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_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 vid_wy700.c x86seg.c x87.c \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ + wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ + wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c wx-sdl2.c \ + wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c \ wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ wx-shader_man.c wx-shaderconfig.cc allegro-gui.c \ @@ -173,7 +177,8 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 \ - thread-pthread.c codegen_x86.c codegen_x86-64.c + thread-pthread.c codegen_x86.c codegen_x86-64.c ne2000.c \ + nethandler.c wx-hostconfig.c @USE_WX_TRUE@am__objects_1 = pcem-wx-main.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-config_sel.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-dialogbox.$(OBJEXT) \ @@ -209,6 +214,9 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ @USE_WX_FALSE@ pcem-thread-pthread.$(OBJEXT) @CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) @CPU_X86_64_TRUE@am__objects_4 = pcem-codegen_x86-64.$(OBJEXT) +@USE_NETWORKING_TRUE@am__objects_5 = pcem-ne2000.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(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) \ @@ -241,9 +249,9 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-laserxt.$(OBJEXT) pcem-lpt.$(OBJEXT) pcem-mca.$(OBJEXT) \ pcem-mcr.$(OBJEXT) pcem-mem.$(OBJEXT) pcem-mfm_at.$(OBJEXT) \ pcem-mfm_xebec.$(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-mouse.$(OBJEXT) pcem-mouse_msystems.$(OBJEXT) \ + pcem-mouse_ps2.$(OBJEXT) pcem-mouse_serial.$(OBJEXT) \ + pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ pcem-olivetti_m24.$(OBJEXT) pcem-opti495.$(OBJEXT) \ pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pci.$(OBJEXT) \ pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) \ @@ -298,10 +306,12 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-wave8580_PST.$(OBJEXT) pcem-wave8580_P_T.$(OBJEXT) \ pcem-wave8580__ST.$(OBJEXT) pcem-wave.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) + $(am__objects_4) $(am__objects_5) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = -@USE_WX_FALSE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) +@USE_WX_FALSE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@USE_WX_FALSE@ $(am__append_9) +@USE_WX_TRUE@pcem_DEPENDENCIES = $(am__append_9) pcem_LINK = $(CXXLD) $(pcem_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SCRIPTS = $(noinst_SCRIPTS) @@ -513,44 +523,48 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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 laserxt.c lpt.c mca.c mcr.c \ - mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_ps2.c \ - mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c \ - paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ - ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 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_colorplus.c \ - vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ - vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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 \ - vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ - sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ - dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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) $(am__append_3) $(am__append_5) + mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c \ + mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ + opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c \ + ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ + vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ + vid_incolor.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_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 vid_wy700.c x86seg.c x87.c \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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) \ + $(am__append_3) $(am__append_5) $(am__append_8) @USE_WX_FALSE@pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO \ -@USE_WX_FALSE@ $(am__append_4) +@USE_WX_FALSE@ $(am__append_4) $(am__append_6) @USE_WX_TRUE@pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell \ -@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_4) -@USE_WX_TRUE@pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -@USE_WX_FALSE@pcem_LDADD = $(allegro_LIBS) -lopenal -@USE_WX_TRUE@pcem_LDADD = @LIBS@ +@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_4) \ +@USE_WX_TRUE@ $(am__append_6) +@USE_WX_FALSE@pcem_CXXFLAGS = $(am__append_7) +@USE_WX_TRUE@pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell \ +@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_7) +@USE_WX_FALSE@pcem_LDADD = $(allegro_LIBS) -lopenal $(am__append_9) +@USE_WX_TRUE@pcem_LDADD = @LIBS@ $(am__append_9) all: all-am .SUFFIXES: @@ -722,9 +736,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.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_msystems.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-ne2000.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nmi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nukedopl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr.Po@am__quote@ @@ -837,6 +854,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ @@ -1768,6 +1786,20 @@ pcem-mouse.obj: mouse.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_msystems.o: mouse_msystems.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse_msystems.o -MD -MP -MF $(DEPDIR)/pcem-mouse_msystems.Tpo -c -o pcem-mouse_msystems.o `test -f 'mouse_msystems.c' || echo '$(srcdir)/'`mouse_msystems.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mouse_msystems.Tpo $(DEPDIR)/pcem-mouse_msystems.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mouse_msystems.c' object='pcem-mouse_msystems.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse_msystems.o `test -f 'mouse_msystems.c' || echo '$(srcdir)/'`mouse_msystems.c + +pcem-mouse_msystems.obj: mouse_msystems.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse_msystems.obj -MD -MP -MF $(DEPDIR)/pcem-mouse_msystems.Tpo -c -o pcem-mouse_msystems.obj `if test -f 'mouse_msystems.c'; then $(CYGPATH_W) 'mouse_msystems.c'; else $(CYGPATH_W) '$(srcdir)/mouse_msystems.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mouse_msystems.Tpo $(DEPDIR)/pcem-mouse_msystems.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mouse_msystems.c' object='pcem-mouse_msystems.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse_msystems.obj `if test -f 'mouse_msystems.c'; then $(CYGPATH_W) 'mouse_msystems.c'; else $(CYGPATH_W) '$(srcdir)/mouse_msystems.c'; fi` + pcem-mouse_ps2.o: mouse_ps2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-mouse_ps2.Tpo $(DEPDIR)/pcem-mouse_ps2.Po @@ -3518,6 +3550,48 @@ pcem-codegen_x86-64.obj: codegen_x86-64.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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` +pcem-ne2000.o: ne2000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ne2000.o -MD -MP -MF $(DEPDIR)/pcem-ne2000.Tpo -c -o pcem-ne2000.o `test -f 'ne2000.c' || echo '$(srcdir)/'`ne2000.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-ne2000.Tpo $(DEPDIR)/pcem-ne2000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ne2000.c' object='pcem-ne2000.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ne2000.o `test -f 'ne2000.c' || echo '$(srcdir)/'`ne2000.c + +pcem-ne2000.obj: ne2000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ne2000.obj -MD -MP -MF $(DEPDIR)/pcem-ne2000.Tpo -c -o pcem-ne2000.obj `if test -f 'ne2000.c'; then $(CYGPATH_W) 'ne2000.c'; else $(CYGPATH_W) '$(srcdir)/ne2000.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-ne2000.Tpo $(DEPDIR)/pcem-ne2000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ne2000.c' object='pcem-ne2000.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ne2000.obj `if test -f 'ne2000.c'; then $(CYGPATH_W) 'ne2000.c'; else $(CYGPATH_W) '$(srcdir)/ne2000.c'; fi` + +pcem-nethandler.o: nethandler.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nethandler.o -MD -MP -MF $(DEPDIR)/pcem-nethandler.Tpo -c -o pcem-nethandler.o `test -f 'nethandler.c' || echo '$(srcdir)/'`nethandler.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nethandler.Tpo $(DEPDIR)/pcem-nethandler.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nethandler.c' object='pcem-nethandler.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nethandler.o `test -f 'nethandler.c' || echo '$(srcdir)/'`nethandler.c + +pcem-nethandler.obj: nethandler.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nethandler.obj -MD -MP -MF $(DEPDIR)/pcem-nethandler.Tpo -c -o pcem-nethandler.obj `if test -f 'nethandler.c'; then $(CYGPATH_W) 'nethandler.c'; else $(CYGPATH_W) '$(srcdir)/nethandler.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nethandler.Tpo $(DEPDIR)/pcem-nethandler.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nethandler.c' object='pcem-nethandler.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nethandler.obj `if test -f 'nethandler.c'; then $(CYGPATH_W) 'nethandler.c'; else $(CYGPATH_W) '$(srcdir)/nethandler.c'; fi` + +pcem-wx-hostconfig.o: wx-hostconfig.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-hostconfig.o -MD -MP -MF $(DEPDIR)/pcem-wx-hostconfig.Tpo -c -o pcem-wx-hostconfig.o `test -f 'wx-hostconfig.c' || echo '$(srcdir)/'`wx-hostconfig.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-hostconfig.Tpo $(DEPDIR)/pcem-wx-hostconfig.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-hostconfig.c' object='pcem-wx-hostconfig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-hostconfig.o `test -f 'wx-hostconfig.c' || echo '$(srcdir)/'`wx-hostconfig.c + +pcem-wx-hostconfig.obj: wx-hostconfig.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-hostconfig.obj -MD -MP -MF $(DEPDIR)/pcem-wx-hostconfig.Tpo -c -o pcem-wx-hostconfig.obj `if test -f 'wx-hostconfig.c'; then $(CYGPATH_W) 'wx-hostconfig.c'; else $(CYGPATH_W) '$(srcdir)/wx-hostconfig.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-hostconfig.Tpo $(DEPDIR)/pcem-wx-hostconfig.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-hostconfig.c' object='pcem-wx-hostconfig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-hostconfig.obj `if test -f 'wx-hostconfig.c'; then $(CYGPATH_W) 'wx-hostconfig.c'; else $(CYGPATH_W) '$(srcdir)/wx-hostconfig.c'; fi` + .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @@ -4191,6 +4265,9 @@ uninstall-am: uninstall-binPROGRAMS ../pcem: pcem cp pcem .. +slirp/libslirp.a: + $(MAKE) -C slirp + amrefresh: # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/ne2000.c b/src/ne2000.c index 384a545..2d8795d 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -34,7 +34,9 @@ #include "slirp/slirp.h" #include "slirp/queue.h" +#ifdef _WIN32 #include +#endif #include "ibm.h" #include "device.h" @@ -52,6 +54,7 @@ uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; #define NETBLOCKING 0 //we won't block our pcap +#ifdef _WIN32 static HINSTANCE net_hLib = 0; /* handle to DLL */ static char *net_lib_name = "wpcap.dll"; pcap_t *net_pcap; @@ -74,6 +77,7 @@ PCAP_CLOSE _pcap_close; PCAP_GETNONBLOCK _pcap_getnonblock; PCAP_COMPILE _pcap_compile; PCAP_SETFILTER _pcap_setfilter; +#endif queueADT slirpq; int net_slirp_inited = 0; @@ -824,12 +828,13 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); pclog("ne2000 slirp sending packet\n"); } +#ifdef _WIN32 if(net_is_pcap && net_pcap!=NULL) { _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); pclog("ne2000 pcap sending packet\n"); } - +#endif ne2000_tx_event(value, ne2000); // Schedule a timer to trigger a tx-complete interrupt // The number of microseconds is the bit-time / 10. @@ -1350,8 +1355,9 @@ static void ne2000_poller(void *p) ne2000_t *ne2000 = (ne2000_t *)p; struct queuepacket *qp; const unsigned char *data; +#ifdef _WIN32 struct pcap_pkthdr h; - +#endif if (net_is_slirp) { while (QueuePeek(slirpq) > 0) @@ -1373,6 +1379,7 @@ static void ne2000_poller(void *p) slirp_tic(); } }//end slirp +#ifdef _WIN32 if (net_is_pcap && net_pcap!=NULL) { data = _pcap_next(net_pcap,&h); @@ -1389,6 +1396,7 @@ static void ne2000_poller(void *p) ne2000_rx_frame(ne2000,data,h.caplen); } } +#endif } @@ -1407,6 +1415,7 @@ void *ne2000_init() //0 pcap //1 slirp // +#ifdef _WIN32 net_is_slirp = (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_SLIRP) ? 1 : 0; pclog("ne2000 pcap device %s\n",config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing")); @@ -1415,6 +1424,10 @@ void *ne2000_init() net_is_pcap = 0; else if (net_is_slirp == 0) net_is_pcap = 1; +#else + net_is_slirp = 1; + net_is_pcap = 0; +#endif io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); io_sethandler(addr+0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); @@ -1468,6 +1481,7 @@ void *ne2000_init() net_is_slirp=0; } } +#ifdef _WIN32 if (net_is_pcap) { //pcap char errbuf[32768]; @@ -1583,7 +1597,7 @@ void *ne2000_init() pclog("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); } } //end pcap setup - +#endif pclog("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); return ne2000; @@ -1600,12 +1614,14 @@ void ne2000_close(void *p) net_slirp_inited=0; pclog("ne2000 exiting slirp\n"); } +#ifdef _WIN32 if(net_is_pcap && net_pcap!=NULL) { _pcap_close(net_pcap); FreeLibrary(net_hLib); pclog("ne2000 closing pcap\n"); } +#endif pclog("ne2000 close\n"); } diff --git a/src/nethandler.c b/src/nethandler.c index 221a69a..44987a2 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -1,5 +1,7 @@ +#ifdef _WIN32 #include #include +#endif #include #include #include diff --git a/src/wx-hostconfig.c b/src/wx-hostconfig.c index 9cac6b8..95772bc 100644 --- a/src/wx-hostconfig.c +++ b/src/wx-hostconfig.c @@ -1,9 +1,11 @@ +#ifdef _WIN32 #define BITMAP WINDOWS_BITMAP #include #include #undef BITMAP #include +#endif #include "wx-utils.h" #include "wx-sdl2.h" @@ -13,6 +15,7 @@ #include "config.h" #include "nethandler.h" +#ifdef _WIN32 static HINSTANCE net_hLib = 0; static char *net_lib_name = "wpcap.dll"; static pcap_if_t *alldevs; @@ -23,6 +26,7 @@ void (*_pcap_freealldevs)(pcap_if_t *); pcap_t *(*_pcap_open_live)(const char *, int, int, int, char *); int (*_pcap_datalink)(pcap_t *); void (*_pcap_close)(pcap_t *); +#endif #define ETH_DEV_NAME_MAX 256 /* maximum device name size */ #define ETH_DEV_DESC_MAX 256 /* maximum device description size */ @@ -31,6 +35,7 @@ void (*_pcap_close)(pcap_t *); #define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */ #define PCAP_READ_TIMEOUT -1 +#ifdef _WIN32 static int get_network_name(char *dev_name, char *regval) { if (dev_name[strlen( "\\Device\\NPF_" )] == '{') @@ -62,12 +67,14 @@ static int get_network_name(char *dev_name, char *regval) } return -1; } - +#endif int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { void *h; +#ifdef _WIN32 pcap_if_t *dev; char errbuf[PCAP_ERRBUF_SIZE]; +#endif switch (message) { @@ -78,7 +85,7 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); wx_enablewindow(h, FALSE); - +#ifdef _WIN32 net_hLib = LoadLibraryA(net_lib_name); if (net_hLib) @@ -148,6 +155,7 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM } } } +#endif return TRUE; case WX_COMMAND: @@ -157,6 +165,7 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); +#ifdef _WIN32 if (type) /*PCAP*/ { int dev; @@ -169,13 +178,16 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM } else /*SLiRP*/ { +#endif config_set_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP); config_set_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); +#ifdef _WIN32 } +#endif saveconfig_global_only(); wx_enddialog(hdlg, 1); - +#ifdef _WIN32 if (net_hLib) { _pcap_freealldevs(alldevs); @@ -186,11 +198,13 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM _pcap_close = NULL; FreeLibrary(net_hLib); } +#endif return TRUE; } else if (wParam == wxID_CANCEL) { wx_enddialog(hdlg, 0); +#ifdef _WIN32 if (net_hLib) { _pcap_freealldevs(alldevs); @@ -201,6 +215,7 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM _pcap_close = NULL; FreeLibrary(net_hLib); } +#endif return TRUE; } else if (ID_IS("IDC_COMBO_NETWORK_TYPE")) From 94448b885b893a626d9375c7c23f53a93e28e651 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 8 Aug 2017 22:04:22 +0100 Subject: [PATCH 0119/1050] Added Olivetti GO481 graphics card (PVGA1A). Patch from ruben_balea. --- src/ibm.h | 1 + src/vid_paradise.c | 25 ++++++++++++++++++++++++- src/vid_paradise.h | 1 + src/video.c | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/ibm.h b/src/ibm.h index 67f98ac..e6c8cf3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -464,6 +464,7 @@ enum GFX_WY700, /* Wyse 700 */ GFX_GENIUS, /* MDSI Genius */ GFX_MACH64VT2, /*ATI Mach64 VT2*/ + GFX_OLIVETTI_GO481, /*Olivetti GO481 PVGA1A*/ GFX_MAX }; diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 6e12061..f4a3776 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -1,6 +1,6 @@ /*Paradise VGA emulation - PC2086, PC3086 use PVGA1A + PC2086, PC3086, GO481 use PVGA1A MegaPC uses W90C11A */ #include @@ -350,6 +350,18 @@ static void *paradise_wd90c11_megapc_init() return paradise; } +static void *paradise_pvga1a_oli_go481_init() +{ + paradise_t *paradise = paradise_pvga1a_init(); + + if (paradise) + rom_init_interleaved(¶dise->bios_rom, + "oli_go481_lo.bin", + "oli_go481_hi.bin", + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + return paradise; +} + void paradise_close(void *p) { paradise_t *paradise = (paradise_t *)p; @@ -413,3 +425,14 @@ device_t paradise_wd90c11_megapc_device = paradise_force_redraw, paradise_add_status_info }; +device_t paradise_pvga1a_oli_go481_device = +{ + "Paradise PVGA1A (Olivetti GO481)", + 0, + paradise_pvga1a_oli_go481_init, + paradise_close, + NULL, + paradise_speed_changed, + paradise_force_redraw, + paradise_add_status_info +}; diff --git a/src/vid_paradise.h b/src/vid_paradise.h index e25d5b3..c007f5a 100644 --- a/src/vid_paradise.h +++ b/src/vid_paradise.h @@ -1,3 +1,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_pvga1a_oli_go481_device; diff --git a/src/video.c b/src/video.c index 2a1c8e1..b66b1fc 100644 --- a/src/video.c +++ b/src/video.c @@ -67,6 +67,7 @@ static VIDEO_CARD video_cards[] = {"MDSI Genius", "genius", &genius_device, GFX_GENIUS}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX}, {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067}, + {"Olivetti GO481 (Paradise PVGA1A 256Kb)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481}, {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64}, {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32}, {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64}, From 5b90fdf0c23f207ef86afc95b79d906eaa4277b1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 9 Aug 2017 17:54:42 +0100 Subject: [PATCH 0120/1050] Tweak Olivetti GO481 name. --- src/video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video.c b/src/video.c index b66b1fc..df3a2cc 100644 --- a/src/video.c +++ b/src/video.c @@ -67,7 +67,7 @@ static VIDEO_CARD video_cards[] = {"MDSI Genius", "genius", &genius_device, GFX_GENIUS}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX}, {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067}, - {"Olivetti GO481 (Paradise PVGA1A 256Kb)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481}, + {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481}, {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64}, {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32}, {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64}, From 3816e3b6793f181320c7ee35fd2a2735e59a3ff1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 9 Aug 2017 18:02:36 +0100 Subject: [PATCH 0121/1050] Mouse Systems mouse now sends data when serial interrupt disabled. Fixed Visi On. --- src/mouse_msystems.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mouse_msystems.c b/src/mouse_msystems.c index 340b2f7..baa0aea 100644 --- a/src/mouse_msystems.c +++ b/src/mouse_msystems.c @@ -18,8 +18,6 @@ static void mouse_msystems_poll(int x, int y, int z, int b, void *p) SERIAL *serial = mouse->serial; uint8_t mousedat[4]; - if (!(serial->ier & 1)) - return; if (!x && !y && b == mouse->oldb) return; From 9be26e5e0dbea7972cd72e16cdc064c45ebe2520 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 9 Aug 2017 18:09:07 +0100 Subject: [PATCH 0122/1050] Middle button now doesn't release mouse when emulating a 3 button mouse on wxWidgets GUI. --- src/wx-sdl2-display-win.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index f49d80f..29cccb3 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -4,6 +4,7 @@ #include "wx-sdl2-video.h" #include "wx-utils.h" #include "ibm.h" +#include "mouse.h" #include "wx-display.h" #include "plat-keyboard.h" @@ -730,7 +731,7 @@ int render() window_dofullscreen = 1; } } - else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen()) + else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen() && !(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) window_doinputrelease = 1; break; case SDL_MOUSEWHEEL: From ae04fd4ba12bfdc0ee3dd0a8370415363dc9f011 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 10 Aug 2017 21:49:44 +0100 Subject: [PATCH 0123/1050] Unknown Voodoo registers writes with CMDFIFO enabled now log warnings rather than fatal()ing. Jane's WWII Fighters now runs. --- src/vid_voodoo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 3bb8ccb..8be50f6 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -6106,7 +6106,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) default: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) { - fatal("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); + pclog("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); } else { From b9055d9affdf25a5931aacbb501ea15e483f9e16 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 10 Aug 2017 21:50:08 +0100 Subject: [PATCH 0124/1050] Fixed detail factor clamping in Voodoo recompiler. Fixes texture issues in Jane's WWII Fighters. --- src/vid_voodoo_codegen_x86-64.h | 16 ++++++++-------- src/vid_voodoo_codegen_x86.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 8e0aef5..09833b9 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -1047,8 +1047,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[1]); addbyte(0x39); /*CMP EAX, EDX*/ addbyte(0xd0); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EAX, EDX*/ + addbyte(0x4d); addbyte(0xc2); addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); @@ -1201,8 +1201,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[1]); addbyte(0x39); /*CMP EAX, EDX*/ addbyte(0xd0); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EAX, EDX*/ + addbyte(0x4d); addbyte(0xc2); break; case TCA_MSELECT_LOD_FRAC: @@ -1371,8 +1371,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[0]); addbyte(0x39); /*CMP EAX, EDX*/ addbyte(0xd0); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EAX, EDX*/ + addbyte(0x4d); addbyte(0xc2); addbyte(0x66); /*MOVD XMM4, EAX*/ addbyte(0x0f); @@ -1569,8 +1569,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[1]); addbyte(0x39); /*CMP EBX, EDX*/ addbyte(0xd3); - addbyte(0x0f); /*CMOVA EBX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EBX, EDX*/ + addbyte(0x4d); addbyte(0xda); break; case TCA_MSELECT_LOD_FRAC: diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 42df050..7ae1a74 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1030,8 +1030,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[1]); addbyte(0x39); /*CMP EAX, EDX*/ addbyte(0xd0); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EAX, EDX*/ + addbyte(0x4d); addbyte(0xc2); addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); @@ -1182,8 +1182,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[1]); addbyte(0x39); /*CMP EAX, EDX*/ addbyte(0xd0); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EAX, EDX*/ + addbyte(0x4d); addbyte(0xc2); break; case TCA_MSELECT_LOD_FRAC: @@ -1352,8 +1352,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[0]); addbyte(0x39); /*CMP EAX, EDX*/ addbyte(0xd0); - addbyte(0x0f); /*CMOVA EAX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EAX, EDX*/ + addbyte(0x4d); addbyte(0xc2); addbyte(0x66); /*MOVD XMM4, EAX*/ addbyte(0x0f); @@ -1548,8 +1548,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(params->detail_scale[1]); addbyte(0x39); /*CMP EBX, EDX*/ addbyte(0xd3); - addbyte(0x0f); /*CMOVA EBX, EDX*/ - addbyte(0x47); + addbyte(0x0f); /*CMOVNL EBX, EDX*/ + addbyte(0x4d); addbyte(0xda); break; case TCA_MSELECT_LOD_FRAC: From 9a63308ffde929c1c852e9d9e18a3325cc2383dc Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 15 Aug 2017 20:26:06 +0100 Subject: [PATCH 0125/1050] Added Voodoo SLI emulation. --- src/vid_voodoo.c | 737 +++++++++++++++++++++++++++----- src/vid_voodoo_codegen_x86-64.h | 11 +- src/vid_voodoo_codegen_x86.h | 11 +- 3 files changed, 633 insertions(+), 126 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 8be50f6..34b5ebd 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -58,8 +58,6 @@ static uint32_t texture_offset[LOD_MAX+3] = static int tris = 0; static uint64_t status_time = 0; -static uint64_t voodoo_time = 0; -static int voodoo_render_time[2] = {0, 0}; typedef union int_float { @@ -91,7 +89,7 @@ typedef union rgba_u #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx) -#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE-4) #define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx) #define FIFO_TYPE 0xff000000 @@ -225,7 +223,7 @@ typedef struct voodoo_t uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4; uint32_t fbiInit5, fbiInit6, fbiInit7; /*Voodoo 2*/ - uint8_t initEnable; + uint32_t initEnable; uint32_t lfbMode; @@ -247,6 +245,8 @@ typedef struct voodoo_t uint32_t trexInit1[2]; + uint32_t tmuConfig; + int swap_count; int disp_buffer, draw_buffer; @@ -403,11 +403,25 @@ typedef struct voodoo_t uint32_t palette_checksum[2]; int palette_dirty[2]; + + uint64_t time; + int render_time[2]; int use_recompiler; void *codegen_data; + + struct voodoo_set_t *set; } voodoo_t; +typedef struct voodoo_set_t +{ + voodoo_t *voodoos[2]; + + mem_mapping_t snoop_mapping; + + int nr_cards; +} voodoo_set_t; + static inline void wait_for_render_thread_idle(voodoo_t *voodoo); enum @@ -808,11 +822,36 @@ enum FBIINIT0_GRAPHICS_RESET = (1 << 1) }; +enum +{ + FBIINIT1_MULTI_SST = (1 << 2), /*Voodoo Graphics only*/ + FBIINIT1_VIDEO_RESET = (1 << 8), + FBIINIT1_SLI_ENABLE = (1 << 23) +}; + +enum +{ + FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9) +}; + +enum +{ + FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9), + FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9), + FBIINIT2_SWAP_ALGORITHM_PCI_FIFO_STALL = (2 << 9), + FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9) +}; + enum { FBIINIT3_REMAP = 1 }; +enum +{ + FBIINIT5_MULTI_CVG = (1 << 14) +}; + enum { FBIINIT7_CMDFIFO_ENABLE = (1 << 8) @@ -980,6 +1019,11 @@ enum BLTCMD_DST_TILED = (1 << 15) }; +enum +{ + INITENABLE_SLI_MASTER_SLAVE = (1 << 11) +}; + #define TEXTUREMODE_MASK 0x3ffff000 #define TEXTUREMODE_PASSTHROUGH 0 @@ -1032,6 +1076,7 @@ static void voodoo_update_ncc(voodoo_t *voodoo, int tmu) } } +#define SLI_ENABLED (voodoo->fbiInit1 & FBIINIT1_SLI_ENABLE) #define TRIPLE_BUFFER ((voodoo->fbiInit2 & 0x10) || (voodoo->fbiInit5 & 0x600) == 0x400) static void voodoo_recalc(voodoo_t *voodoo) { @@ -1215,7 +1260,6 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) { params->tex_entry[tmu] = c; voodoo->texture_cache[tmu][c].refcount++; - return; } } @@ -1472,7 +1516,7 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL88) + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; else voodoo->texture_cache[tmu][c].palette_checksum = 0; @@ -2530,6 +2574,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood int texels; int c; uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); + int y_diff = SLI_ENABLED ? 2 : 1; if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) @@ -2589,6 +2634,37 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->y = ystart; // yend--; + if (SLI_ENABLED) + { + int test_y; + + if (params->fbzMode & (1 << 17)) + test_y = (voodoo->v_disp-1) - state->y; + else + test_y = state->y; + + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) + { + state->y++; + + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } + } + #ifndef NO_CODEGEN if (voodoo->use_recompiler) voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); @@ -2599,7 +2675,8 @@ 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++) + + for (; state->y < yend; state->y += y_diff) { int x, x2; int real_y = (state->y << 4) + 8; @@ -2632,8 +2709,16 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood else real_y >>= 4; - if ((real_y & voodoo->odd_even_mask) != odd_even) - goto next_line; + if (SLI_ENABLED) + { + if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) + goto next_line; + } + else + { + if ((real_y & voodoo->odd_even_mask) != odd_even) + goto next_line; + } start_x = x; @@ -2722,8 +2807,16 @@ 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 = (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 (SLI_ENABLED) + { + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * voodoo->row_width)]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * voodoo->row_width)) & voodoo->fb_mask]; + } + else + { + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; + } if (voodoo_output) 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); @@ -2836,11 +2929,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (voodoo->trexInit1[0] & (1 << 18)) { state->tex_r[0] = state->tex_g[0] = 0; - - if (voodoo->dual_tmus) - state->tex_b[0] = 1 | (3 << 6); - else - state->tex_b[0] = 1; + state->tex_b[0] = voodoo->tmuConfig; } if (cc_localselect_override) @@ -3154,8 +3243,25 @@ skip_pixel: voodoo->fbiPixelsIn += state->pixel_count; if (voodoo->params.draw_offset == voodoo->params.front_offset) - voodoo->dirty_line[real_y] = 1; + voodoo->dirty_line[real_y >> 1] = 1; next_line: + if (SLI_ENABLED) + { + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } state->base_r += params->dRdY; state->base_g += params->dGdY; state->base_b += params->dBdY; @@ -3169,7 +3275,7 @@ next_line: state->tmu[1].base_w += params->tmu[1].dWdY; state->base_w += params->dWdY; state->xstart += state->dx1; - state->xend += state->dx2; + state->xend += state->dx2; } voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; @@ -3367,7 +3473,7 @@ static void render_thread(void *param, int odd_even) thread_set_event(voodoo->render_not_full_event[odd_even]); end_time = timer_read(); - voodoo_render_time[odd_even] += end_time - start_time; + voodoo->render_time[odd_even] += end_time - start_time; } voodoo->render_voodoo_busy[odd_even] = 0; @@ -3440,24 +3546,52 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) b = (params->color1 >> 3) & 0x1f; col = b | (g << 5) | (r << 11); - for (y = low_y; y < high_y; y++) + if (SLI_ENABLED) { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; + for (y = low_y; y < high_y; y += 2) + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } + } + else + { + for (y = low_y; y < high_y; y++) + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } } } if (params->fbzMode & FBZ_DEPTH_WMASK) { - for (y = low_y; y < high_y; y++) + if (SLI_ENABLED) { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; + for (y = low_y; y < high_y; y += 2) + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } + } + else + { + for (y = low_y; y < high_y; y++) + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } } } } @@ -3834,9 +3968,19 @@ skip_pixel_blit: case BLIT_COMMAND_RECT_FILL: for (y = 0; y <= size_y; y++) { - uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; + uint16_t *dst; int dst_x = voodoo->bltDstX; + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_line_fill; + dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; + } + else + dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; + for (x = 0; x <= size_x; x++) { if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) @@ -3850,7 +3994,7 @@ skip_pixel_blit: skip_pixel_fill: dst_x += x_dir; } - +skip_line_fill: dst_y += y_dir; } break; @@ -3903,11 +4047,16 @@ static void blit_data(voodoo_t *voodoo, uint32_t data) { int src_bits = 32; uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - uint16_t *dst = (uint16_t *)&voodoo->fb_mem[base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride]; + uint16_t *dst; if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) return; + if (SLI_ENABLED) + dst = (uint16_t *)&voodoo->fb_mem[base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride]; + else + dst = (uint16_t *)&voodoo->fb_mem[base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride]; + while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) { int r = 0, g = 0, b = 0; @@ -3980,6 +4129,13 @@ static void blit_data(voodoo_t *voodoo, uint32_t data) src_bits = 0; break; } + + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_pixel; + } if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { @@ -4046,12 +4202,13 @@ static void wait_for_swap_complete(voodoo_t *voodoo) { thread_wait_event(voodoo->wake_fifo_thread, -1); thread_reset_event(voodoo->wake_fifo_thread); - if ((voodoo->swap_pending && voodoo->flush) || FIFO_ENTRIES == 65536) + if ((voodoo->swap_pending && voodoo->flush) || FIFO_ENTRIES >= 65536) { /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ memset(voodoo->dirty_line, 1, 1024); voodoo->front_offset = voodoo->params.front_offset; - voodoo->swap_count--; + if (voodoo->swap_count > 0) + voodoo->swap_count--; voodoo->swap_pending = 0; break; } @@ -4096,14 +4253,15 @@ 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); + pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); // voodoo->front_offset = params->front_offset; wait_for_render_thread_idle(voodoo); if (!(val & 1)) { memset(voodoo->dirty_line, 1, 1024); voodoo->front_offset = voodoo->params.front_offset; - voodoo->swap_count--; + if (voodoo->swap_count > 0) + voodoo->swap_count--; } else if (TRIPLE_BUFFER) { @@ -5181,6 +5339,19 @@ static uint16_t voodoo_fb_readw(uint32_t addr, void *p) x = (addr >> 1) & 0x3ff; y = (addr >> 11) & 0x3ff; + + if (SLI_ENABLED) + { + voodoo_set_t *set = voodoo->set; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + + y >>= 1; + } + read_addr = voodoo->fb_read_offset + (x << 1) + (y * voodoo->row_width); if (read_addr > voodoo->fb_mask) @@ -5200,6 +5371,19 @@ static uint32_t voodoo_fb_readl(uint32_t addr, void *p) x = addr & 0x7fe; y = (addr >> 11) & 0x3ff; + + if (SLI_ENABLED) + { + voodoo_set_t *set = voodoo->set; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + + y >>= 1; + } + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); if (read_addr > voodoo->fb_mask) @@ -5291,6 +5475,15 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) x = addr & 0x7fe; y = (addr >> 11) & 0x3ff; + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } + + if (voodoo->fb_write_offset == voodoo->params.front_offset) voodoo->dirty_line[y] = 1; @@ -5429,6 +5622,14 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) x = addr & 0x7fe; y = (addr >> 11) & 0x3ff; + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } + if (voodoo->fb_write_offset == voodoo->params.front_offset) voodoo->dirty_line[y] = 1; @@ -5593,12 +5794,14 @@ static inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t { fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) + while (FIFO_FULL) { thread_reset_event(voodoo->fifo_not_full_event); if (FIFO_FULL) { - thread_wait_event(voodoo->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ + if (FIFO_FULL) + wake_fifo_thread_now(voodoo); } } @@ -5621,6 +5824,17 @@ static uint16_t voodoo_readw(uint32_t addr, void *p) if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ { + if (SLI_ENABLED) + { + voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + } + voodoo->flush = 1; while (!FIFO_EMPTY) { @@ -5648,6 +5862,13 @@ static void voodoo_flush(voodoo_t *voodoo) voodoo->flush = 0; } +static void wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) +{ + wake_fifo_thread(voodoo); + if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) + wake_fifo_thread(set->voodoos[1]); +} + static uint32_t voodoo_readl(uint32_t addr, void *p) { voodoo_t *voodoo = (voodoo_t *)p; @@ -5663,6 +5884,17 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) } else if (addr & 0x400000) /*Framebuffer*/ { + if (SLI_ENABLED) + { + voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + } + voodoo->flush = 1; while (!FIFO_EMPTY) { @@ -5677,21 +5909,45 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) else switch (addr & 0x3fc) { case SST_status: - fifo_size = 0xffff - FIFO_ENTRIES; - temp = fifo_size << 12; - if (fifo_size < 0x40) - temp |= fifo_size; - else - temp |= 0x3f; - 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) - wake_fifo_thread(voodoo); + { + int fifo_entries = FIFO_ENTRIES; + int swap_count = voodoo->swap_count; + int busy = (voodoo->cmd_written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); + + if (SLI_ENABLED && voodoo->type != VOODOO_2) + { + voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; + + if (voodoo_other->swap_count > swap_count) + swap_count = voodoo_other->swap_count; + if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) + fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; + if ((voodoo_other->cmd_written - voodoo_other->cmd_read) || + (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) + busy = 1; + if (!voodoo_other->voodoo_busy) + wake_fifo_thread(voodoo_other); + } + + fifo_size = 0xffff - fifo_entries; + temp = fifo_size << 12; + if (fifo_size < 0x40) + temp |= fifo_size; + else + temp |= 0x3f; + if (swap_count < 7) + temp |= (swap_count << 28); + else + temp |= (7 << 28); + if (!voodoo->v_retrace) + temp |= 0x40; + + if (busy) + temp |= 0x380; /*Busy*/ + + if (!voodoo->voodoo_busy) + wake_fifo_thread(voodoo); + } break; case SST_fbzColorPath: @@ -5759,7 +6015,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) temp = voodoo->fbiInit0; break; case SST_fbiInit1: - temp = voodoo->fbiInit1 & ~5; /*Pass-thru board with one SST-1*/ + temp = voodoo->fbiInit1; break; case SST_fbiInit2: if (voodoo->initEnable & 0x04) @@ -5768,7 +6024,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) temp = voodoo->fbiInit2; break; case SST_fbiInit3: - temp = voodoo->fbiInit3; + temp = voodoo->fbiInit3 | (1 << 10) | (2 << 8); break; case SST_vRetrace: @@ -5782,7 +6038,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) break; case SST_fbiInit5: - temp = voodoo->fbiInit5 & ~0x41ff; + temp = voodoo->fbiInit5 & ~0x1ff; break; case SST_fbiInit6: temp = voodoo->fbiInit6; @@ -5813,7 +6069,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) fatal("voodoo_readl : bad addr %08X\n", addr); temp = 0xffffffff; } - + return temp; } @@ -5905,7 +6161,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) return; queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); + wake_fifo_threads(voodoo->set, voodoo); break; case SST_triangleCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) @@ -5913,7 +6169,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->cmd_written++; queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); + wake_fifo_threads(voodoo->set, voodoo); break; case SST_ftriangleCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) @@ -5921,7 +6177,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->cmd_written++; queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); + wake_fifo_threads(voodoo->set, voodoo); break; case SST_fastfillCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) @@ -5929,7 +6185,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->cmd_written++; queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); + wake_fifo_threads(voodoo->set, voodoo); break; case SST_nopCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) @@ -5937,7 +6193,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->cmd_written++; queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); + wake_fifo_threads(voodoo->set, voodoo); break; case SST_fbiInit4: @@ -5975,7 +6231,13 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) case SST_fbiInit1: if (voodoo->initEnable & 0x01) { - voodoo->fbiInit1 = val; + if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) + { + voodoo->line = 0; + voodoo->swap_count = 0; + voodoo->retrace_count = 0; + } + voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); // pclog("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); @@ -6072,7 +6334,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) case SST_fbiInit5: if (voodoo->initEnable & 0x01) - voodoo->fbiInit5 = val; + voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6); break; case SST_fbiInit6: if (voodoo->initEnable & 0x01) @@ -6116,6 +6378,34 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) } } +static uint16_t voodoo_snoop_readw(uint32_t addr, void *p) +{ + voodoo_set_t *set = (voodoo_set_t *)p; + + return voodoo_readw(addr, set->voodoos[0]); +} +static uint32_t voodoo_snoop_readl(uint32_t addr, void *p) +{ + voodoo_set_t *set = (voodoo_set_t *)p; + + return voodoo_readl(addr, set->voodoos[0]); +} + +static void voodoo_snoop_writew(uint32_t addr, uint16_t val, void *p) +{ + voodoo_set_t *set = (voodoo_set_t *)p; + + voodoo_writew(addr, val, set->voodoos[0]); + voodoo_writew(addr, val, set->voodoos[1]); +} +static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) +{ + voodoo_set_t *set = (voodoo_set_t *)p; + + voodoo_writel(addr, val, set->voodoos[0]); + voodoo_writel(addr, val, set->voodoos[1]); +} + static uint32_t cmdfifo_get(voodoo_t *voodoo) { uint32_t val; @@ -6202,7 +6492,7 @@ static void fifo_thread(void *param) thread_set_event(voodoo->fifo_not_full_event); end_time = timer_read(); - voodoo_time += end_time - start_time; + voodoo->time += end_time - start_time; } while (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) @@ -6378,24 +6668,70 @@ static void fifo_thread(void *param) } end_time = timer_read(); - voodoo_time += end_time - start_time; + voodoo->time += end_time - start_time; } - voodoo->voodoo_busy = 0; } } -static void voodoo_recalcmapping(voodoo_t *voodoo) +static void voodoo_recalcmapping(voodoo_set_t *set) { - if (voodoo->pci_enable && voodoo->memBaseAddr) + if (set->nr_cards == 2) { - pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); - mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); + if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) + { + if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) + { + pclog("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->voodoos[0]->mapping); + mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + } + else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) + { + pclog("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->voodoos[0]->mapping); + mem_mapping_disable(&set->voodoos[1]->mapping); + mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + return; + } + else + { + pclog("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->snoop_mapping); + mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + } + } + else + { + pclog("voodoo_recalcmapping (pri) : disabled\n"); + mem_mapping_disable(&set->voodoos[0]->mapping); + } + + if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) + { + pclog("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr); + mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000); + } + else + { + pclog("voodoo_recalcmapping (sec) : disabled\n"); + mem_mapping_disable(&set->voodoos[1]->mapping); + } } else { - pclog("voodoo_recalcmapping : disabled\n"); - mem_mapping_disable(&voodoo->mapping); + voodoo_t *voodoo = set->voodoos[0]; + + if (voodoo->pci_enable && voodoo->memBaseAddr) + { + pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); + mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); + } + else + { + pclog("voodoo_recalcmapping : disabled\n"); + mem_mapping_disable(&voodoo->mapping); + } } } @@ -6459,12 +6795,12 @@ void voodoo_pci_write(int func, int addr, uint8_t val, void *p) { case 0x04: voodoo->pci_enable = val & 2; - voodoo_recalcmapping(voodoo); + voodoo_recalcmapping(voodoo->set); break; case 0x13: voodoo->memBaseAddr = val << 24; - voodoo_recalcmapping(voodoo); + voodoo_recalcmapping(voodoo->set); break; case 0x40: @@ -6475,9 +6811,11 @@ void voodoo_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x42: voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16); + voodoo_recalcmapping(voodoo->set); break; case 0x43: voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); + voodoo_recalcmapping(voodoo->set); break; } } @@ -6854,7 +7192,6 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin 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; @@ -6863,13 +7200,33 @@ void voodoo_callback(void *p) { if (voodoo->line < voodoo->v_disp) { - if (voodoo->dirty_line[voodoo->line]) + voodoo_t *draw_voodoo; + int draw_line; + + if (voodoo == voodoo->set->voodoos[1]) + goto skip_draw; + + if (SLI_ENABLED) + { + if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) + draw_voodoo = voodoo; + else + draw_voodoo = voodoo->set->voodoos[1]; + draw_line = voodoo->line >> 1; + } + else + { + draw_voodoo = voodoo; + draw_line = voodoo->line; + } + + if (draw_voodoo->dirty_line[draw_line]) { uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32]; - uint16_t *src = (uint16_t *)&voodoo->fb_mem[voodoo->front_offset + voodoo->line*voodoo->row_width]; + uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line*draw_voodoo->row_width]; int x; - voodoo->dirty_line[voodoo->line] = 0; + draw_voodoo->dirty_line[draw_line] = 0; if (voodoo->line < voodoo->dirty_line_low) { @@ -6897,25 +7254,62 @@ void voodoo_callback(void *p) { for (x = 0; x < voodoo->h_disp; x++) { - p[x] = voodoo->video_16to32[src[x]]; + p[x] = draw_voodoo->video_16to32[src[x]]; } } } } } +skip_draw: 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)) + if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; + if (voodoo == voodoo->set->voodoos[0]) + { + voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; + + /*Only swap if both Voodoos are waiting for buffer swap*/ + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && + voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) + { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + + memset(voodoo_1->dirty_line, 1, 1024); + voodoo_1->retrace_count = 0; + voodoo_1->front_offset = voodoo_1->swap_offset; + if (voodoo_1->swap_count > 0) + voodoo_1->swap_count--; + voodoo_1->swap_pending = 0; + + thread_set_event(voodoo->wake_fifo_thread); + thread_set_event(voodoo_1->wake_fifo_thread); + + voodoo->frame_count++; + voodoo_1->frame_count++; + } + } + } + else + { + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) + { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } } voodoo->v_retrace = 1; } @@ -6950,12 +7344,15 @@ void voodoo_callback(void *p) static void voodoo_add_status_info(char *s, int max_len, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - char temps[256]; + voodoo_set_t *voodoo_set = (voodoo_set_t *)p; + voodoo_t *voodoo = voodoo_set->voodoos[0]; + voodoo_t *voodoo_slave = voodoo_set->voodoos[1]; + char temps[512], temps2[256]; int pixel_count_current[2]; int pixel_count_total; int texel_count_current[2]; int texel_count_total; + int render_time[2]; uint64_t new_time = timer_read(); uint64_t status_diff = new_time - status_time; status_time = new_time; @@ -6967,18 +7364,47 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) pixel_count_current[0] = voodoo->pixel_count[0]; pixel_count_current[1] = voodoo->pixel_count[1]; - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); texel_count_current[0] = voodoo->texel_count[0]; texel_count_current[1] = voodoo->texel_count[1]; + render_time[0] = voodoo->render_time[0]; + render_time[1] = voodoo->render_time[1]; + if (voodoo_set->nr_cards == 2) + { + pixel_count_current[0] += voodoo_slave->pixel_count[0]; + pixel_count_current[1] += voodoo_slave->pixel_count[1]; + texel_count_current[0] += voodoo_slave->texel_count[0]; + texel_count_current[1] += voodoo_slave->texel_count[1]; + render_time[0] = (render_time[0] + voodoo_slave->render_time[0]) / 2; + render_time[1] = (render_time[1] + voodoo_slave->render_time[1]) / 2; + } + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); - sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, + sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, (double)pixel_count_total/1000000.0, - ((double)pixel_count_total/1000000.0) / ((double)voodoo_render_time[0] / status_diff), + ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), (double)texel_count_total/1000000.0, - ((double)texel_count_total/1000000.0) / ((double)voodoo_render_time[0] / status_diff), - (double)voodoo->tri_count/1000.0, ((double)voodoo_time * 100.0) / timer_freq, ((double)voodoo_time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, - ((double)voodoo_render_time[0] * 100.0) / timer_freq, ((double)voodoo_render_time[0] * 100.0) / status_diff, - ((double)voodoo_render_time[1] * 100.0) / timer_freq, ((double)voodoo_render_time[1] * 100.0) / status_diff); + ((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff), + (double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, + ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); + if (voodoo->render_threads == 2) + { + sprintf(temps2, "%f%% CPU (%f%% real)\n", + ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); + strncat(temps, temps2, 512); + } + if (voodoo_set->nr_cards == 2) + { + sprintf(temps2, "%f%% CPU (%f%% real)\n", + ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); + strncat(temps, temps2, 512); + + if (voodoo_slave->render_threads == 2) + { + sprintf(temps2, "%f%% CPU (%f%% real)\n", + ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); + strncat(temps, temps2, 512); + } + } strncat(s, temps, max_len); voodoo->pixel_count_old[0] = pixel_count_current[0]; @@ -6987,23 +7413,41 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) voodoo->texel_count_old[1] = texel_count_current[1]; voodoo->tri_count = voodoo->frame_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; - voodoo_time = 0; - voodoo_render_time[0] = voodoo_render_time[1] = 0; + voodoo->time = 0; + voodoo->render_time[0] = voodoo->render_time[1] = 0; + if (voodoo_set->nr_cards == 2) + { + voodoo_slave->pixel_count_old[0] = pixel_count_current[0]; + voodoo_slave->pixel_count_old[1] = pixel_count_current[1]; + voodoo_slave->texel_count_old[0] = texel_count_current[0]; + voodoo_slave->texel_count_old[1] = texel_count_current[1]; + voodoo_slave->tri_count = voodoo_slave->frame_count = 0; + voodoo_slave->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0; + voodoo_slave->time = 0; + voodoo_slave->render_time[0] = voodoo_slave->render_time[1] = 0; + } voodoo_recomp = 0; } static void voodoo_speed_changed(void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - voodoo_pixelclock_update(voodoo); - 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); + voodoo_pixelclock_update(voodoo_set->voodoos[0]); + voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); + voodoo_set->voodoos[0]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0); + voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1); + if (voodoo_set->nr_cards == 2) + { + voodoo_pixelclock_update(voodoo_set->voodoos[1]); + voodoo_set->voodoos[1]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1); + voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); + voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); + } // 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() +void *voodoo_card_init() { int c; voodoo_t *voodoo = malloc(sizeof(voodoo_t)); @@ -7140,12 +7584,72 @@ void *voodoo_init() return voodoo; } -void voodoo_close(void *p) +void *voodoo_init() +{ + voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); + uint32_t tmuConfig = 1; + int type; + memset(voodoo_set, 0, sizeof(voodoo_set_t)); + + type = device_get_config_int("type"); + + voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; + voodoo_set->voodoos[0] = voodoo_card_init(); + voodoo_set->voodoos[0]->set = voodoo_set; + if (voodoo_set->nr_cards == 2) + { + voodoo_set->voodoos[1] = voodoo_card_init(); + + voodoo_set->voodoos[1]->set = voodoo_set; + + if (type == VOODOO_2) + { + voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG; + voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG; + } + else + { + voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST; + voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST; + } + } + + switch (type) + { + case VOODOO_1: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 3); + else + tmuConfig = 1; + break; + case VOODOO_SB50: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9); + else + tmuConfig = 1 | (3 << 6); + break; + case VOODOO_2: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 6); + else + tmuConfig = 1; + break; + } + + voodoo_set->voodoos[0]->tmuConfig = tmuConfig; + if (voodoo_set->nr_cards == 2) + voodoo_set->voodoos[1]->tmuConfig = tmuConfig; + + mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set); + + return voodoo_set; +} + +void voodoo_card_close(voodoo_t *voodoo) { #ifndef RELEASE_BUILD FILE *f; #endif - voodoo_t *voodoo = (voodoo_t *)p; int c; #ifndef RELEASE_BUILD @@ -7188,6 +7692,17 @@ void voodoo_close(void *p) free(voodoo); } +void voodoo_close(void *p) +{ + voodoo_set_t *voodoo_set = (voodoo_set_t *)p; + + if (voodoo_set->nr_cards == 2) + voodoo_card_close(voodoo_set->voodoos[1]); + voodoo_card_close(voodoo_set->voodoos[0]); + + free(voodoo_set); +} + static device_config_t voodoo_config[] = { { @@ -7286,6 +7801,12 @@ static device_config_t voodoo_config[] = }, .default_int = 2 }, + { + .name = "sli", + .description = "SLI", + .type = CONFIG_BINARY, + .default_int = 0 + }, #ifndef NO_CODEGEN { .name = "recompiler", diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 09833b9..48935da 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -1671,15 +1671,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if (voodoo->trexInit1[0] & (1 << 18)) { - addbyte(0xb8); /*MOV EAX, 0x000001*/ - if (voodoo->dual_tmus) - { - addlong(0x0000c1); - } - else - { - addlong(0x000001); - } + addbyte(0xb8); /*MOV EAX, tmuConfig*/ + addlong(voodoo->tmuConfig); addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 7ae1a74..d146eb2 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1650,15 +1650,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if (voodoo->trexInit1[0] & (1 << 18)) { - addbyte(0xb8); /*MOV EAX, 0x000001*/ - if (voodoo->dual_tmus) - { - addlong(0x0000c1); - } - else - { - addlong(0x000001); - } + addbyte(0xb8); /*MOV EAX, tmuConfig*/ + addlong(voodoo->tmuConfig); addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); From 6589952e9a078f7f0e45618a6b3b350d4f099ef3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 15 Aug 2017 20:53:15 +0100 Subject: [PATCH 0126/1050] Fixed Voodoo 2 non-SLI TMU config. --- src/vid_voodoo.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 34b5ebd..812ba0f 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -7629,10 +7629,7 @@ void *voodoo_init() tmuConfig = 1 | (3 << 6); break; case VOODOO_2: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 6); - else - tmuConfig = 1; + tmuConfig = 1 | (3 << 6); break; } From 76119cc00d1b63bf1568ed07bed2ba131124ce68 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 15 Aug 2017 20:54:27 +0100 Subject: [PATCH 0127/1050] Fixed bug in MOVQ with 16-bit addressing. Patch from JosepMa. --- src/x86_ops_mmx_mov.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86_ops_mmx_mov.h b/src/x86_ops_mmx_mov.h index 2d43663..37899b3 100644 --- a/src/x86_ops_mmx_mov.h +++ b/src/x86_ops_mmx_mov.h @@ -136,7 +136,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) else { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); } return 0; From 9eae781645f8554baf916500afe6eb3cb678ecbc Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 15 Aug 2017 21:15:29 +0100 Subject: [PATCH 0128/1050] Fixes to shader rendering. Patch from bit. --- src/wx-glsl.h | 313 ++-- src/wx-glslp-parser.c | 658 ++++---- src/wx-glslp-parser.h | 110 +- src/wx-sdl2-video-gl3.c | 3308 ++++++++++++++++++++------------------- 4 files changed, 2205 insertions(+), 2184 deletions(-) diff --git a/src/wx-glsl.h b/src/wx-glsl.h index ac371f3..0f8f853 100644 --- a/src/wx-glsl.h +++ b/src/wx-glsl.h @@ -1,155 +1,158 @@ -#ifndef SRC_WX_GLSL_H_ -#define SRC_WX_GLSL_H_ - -#define MAX_PREV 7 - -#define MAX_SHADERS 20 -#define MAX_TEXTURES 20 -#define MAX_PARAMETERS 100 - -#define MAX_USER_SHADERS 20 -//#define SDL2_SHADER_DEBUG - -struct shader_scale { - int mode[2]; - float value[2]; -}; - -struct shader_state { - float input_size[2]; - float input_texture_size[2]; - float output_texture_size[2]; - float output_size[2]; - float tex_coords[8]; -}; - -struct shader_vbo { - int vertex_coord; - int tex_coord; - int color; -}; - -struct shader_texture { - int id; - int width; - int height; - int type; - int internal_format; - int format; - int min_filter; - int mag_filter; - int wrap_mode; - void* data; - int mipmap; -}; - -struct shader_lut_texture { - char name[50]; - struct shader_texture texture; -}; - -struct shader_fbo { - int id; - struct shader_texture texture; - int srgb; -}; - -struct shader_prev { - struct shader_fbo fbo; - struct shader_vbo vbo; -}; - -struct shader_input { - int texture; - int input_size; - int texture_size; - int tex_coord; -}; - -struct shader_uniforms { - int mvp_matrix; - int vertex_coord; - int tex_coord; - int color; - - int texture; - int input_size; - int texture_size; - int output_size; - - int frame_count; - int frame_direction; - - struct shader_input orig; - struct shader_input pass[MAX_SHADERS]; - struct shader_input prev_pass[MAX_SHADERS]; - struct shader_input prev[MAX_PREV]; - - int parameters[MAX_PARAMETERS]; - int lut_textures[MAX_TEXTURES]; -}; - -struct shader_program { - int vertex_shader; - int fragment_shader; - int id; -}; - -struct shader_parameter { - char id[64]; - char description[64]; - float default_value; - float value; - float min; - float max; - float step; -}; - -struct shader_pass { - int active; - char alias[64]; - int vertex_array; - int frame_count_mod; - struct shader_program program; - struct shader_uniforms uniforms; - struct shader_fbo fbo; - struct shader_vbo vbo; - struct shader_state state; - struct shader_scale scale; -}; - -struct glsl_shader { - int active; - char name[64]; - - int num_passes; - struct shader_pass passes[MAX_SHADERS]; - - int num_lut_textures; - struct shader_lut_texture lut_textures[MAX_TEXTURES]; - - int num_parameters; - struct shader_parameter parameters[MAX_PARAMETERS]; - - struct shader_pass prev_scene; - struct shader_prev prev[MAX_PREV+1]; - - int last_prev_update; - int has_prev; - - float shader_refresh_rate; -}; - -typedef struct glsl_t { - int num_shaders; - struct glsl_shader shaders[MAX_USER_SHADERS]; - struct shader_pass scene; - struct shader_pass final_pass; - struct shader_pass fs_color; -#ifdef SDL2_SHADER_DEBUG - struct shader_pass debug; -#endif - int srgb; -} glsl_t; - -#endif +#ifndef SRC_WX_GLSL_H_ +#define SRC_WX_GLSL_H_ + +#define MAX_PREV 7 + +#define MAX_SHADERS 20 +#define MAX_TEXTURES 20 +#define MAX_PARAMETERS 100 + +#define MAX_USER_SHADERS 20 +//#define SDL2_SHADER_DEBUG + +struct shader_scale { + int mode[2]; + float value[2]; +}; + +struct shader_state { + float input_size[2]; + float input_texture_size[2]; + float output_texture_size[2]; + float output_size[2]; + float tex_coords[8]; +}; + +struct shader_vbo { + int vertex_coord; + int tex_coord; + int color; +}; + +struct shader_texture { + int id; + int width; + int height; + int type; + int internal_format; + int format; + int min_filter; + int mag_filter; + int wrap_mode; + void* data; + int mipmap; +}; + +struct shader_lut_texture { + char name[50]; + struct shader_texture texture; +}; + +struct shader_fbo { + int id; + struct shader_texture texture; + int srgb; + int mipmap_input; +}; + +struct shader_prev { + struct shader_fbo fbo; + struct shader_vbo vbo; +}; + +struct shader_input { + int texture; + int input_size; + int texture_size; + int tex_coord; +}; + +struct shader_uniforms { + int mvp_matrix; + int vertex_coord; + int tex_coord; + int color; + + int texture; + int input_size; + int texture_size; + int output_size; + + int frame_count; + int frame_direction; + + struct shader_input orig; + struct shader_input pass[MAX_SHADERS]; + struct shader_input prev_pass[MAX_SHADERS]; + struct shader_input prev[MAX_PREV]; + + int parameters[MAX_PARAMETERS]; + int lut_textures[MAX_TEXTURES]; +}; + +struct shader_program { + int vertex_shader; + int fragment_shader; + int id; +}; + +struct shader_parameter { + char id[64]; + char description[64]; + float default_value; + float value; + float min; + float max; + float step; +}; + +struct shader_pass { + int active; + char alias[64]; + int vertex_array; + int frame_count_mod; + struct shader_program program; + struct shader_uniforms uniforms; + struct shader_fbo fbo; + struct shader_vbo vbo; + struct shader_state state; + struct shader_scale scale; +}; + +struct glsl_shader { + int active; + char name[64]; + + int num_passes; + struct shader_pass passes[MAX_SHADERS]; + + int num_lut_textures; + struct shader_lut_texture lut_textures[MAX_TEXTURES]; + + int num_parameters; + struct shader_parameter parameters[MAX_PARAMETERS]; + + struct shader_pass prev_scene; + struct shader_prev prev[MAX_PREV+1]; + + int last_prev_update; + int has_prev; + + float shader_refresh_rate; + + int input_filter_linear; +}; + +typedef struct glsl_t { + int num_shaders; + struct glsl_shader shaders[MAX_USER_SHADERS]; + struct shader_pass scene; + struct shader_pass final_pass; + struct shader_pass fs_color; +#ifdef SDL2_SHADER_DEBUG + struct shader_pass debug; +#endif + int srgb; +} glsl_t; + +#endif diff --git a/src/wx-glslp-parser.c b/src/wx-glslp-parser.c index bd17443..dd1fec1 100644 --- a/src/wx-glslp-parser.c +++ b/src/wx-glslp-parser.c @@ -1,328 +1,330 @@ -#include "wx-glslp-parser.h" - -#include -#include -#include -#include -#include "wx-utils.h" - -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -extern char* get_filename(char*); -extern void pclog(const char *format, ...); - -static int endswith(const char* str, const char* ext) -{ - int i; - const char* p; - int elen = strlen(ext); - int slen = strlen(str); - if (slen >= elen) - { - p = &str[slen-elen]; - for (i = 0; i < elen; ++i) - { - if (tolower(p[i]) != tolower(ext[i])) - return 0; - } - return 1; - } - return 0; -} - -static char* load_file(const char* fn) -{ - FILE* f = fopen(fn, "rb"); - if (!f) - return 0; - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - - char* data = malloc(fsize+1); - - fread(data, fsize, 1, f); - fclose(f); - - data[fsize] = 0; - - return data; -} - -static void strip_lines(const char* program, const char* starts_with) -{ - /* strip parameters */ - char* ptr = strstr(program, starts_with); - while (ptr) - { - while (*ptr != '\n' && *ptr != '\0') - *ptr++ = ' '; - ptr = strstr(program, starts_with); - } -} - -static void strip_parameters(const char* program) -{ - /* strip parameters */ - strip_lines(program, "#pragma parameter"); -} - -static void strip_defines(const char* program) -{ - /* strip texture define */ - strip_lines(program, "#define texture"); -} - -static int has_parameter(glslp_t* glsl, char* id) -{ - int i; - for (i = 0; i < glsl->num_parameters; ++i) - if (!strcmp(glsl->parameters[i].id, id)) - return 1; - return 0; -} - -static int get_parameters(glslp_t* glsl) -{ - int i; - struct parameter p; - for (i = 0; i < glsl->num_shaders; ++i) - { - struct shader* shader = &glsl->shaders[i]; - FILE* f = fopen(shader->shader_fn, "rb"); - if (!f) - return 0; - - char line[1024]; - while (fgets(line, sizeof(line)-1, f) && glsl->num_parameters < MAX_PARAMETERS) - { - int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, &p.default_value, &p.min, &p.max, &p.step); - if (num < 5) - continue; - p.id[63] = 0; - p.description[63] = 0; - - if (num == 5) - p.step = 0.1f * (p.max-p.min); - - p.value = p.default_value; - - if (!has_parameter(glsl, p.id)) - { - memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); - pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, p.max, p.step); - } - } - - fclose(f); - } - - return 1; -} - -static struct parameter* get_parameter(glslp_t* glslp, const char* id) -{ - int i; - for (i = 0; i < glslp->num_parameters; ++i) - { - if (!strcmp(glslp->parameters[i].id, id)) { - return &glslp->parameters[i]; - } - } - return 0; -} - -static glslp_t* glsl_parse(const char* f) -{ - glslp_t* glslp = malloc(sizeof(glslp_t)); - memset(glslp, 0, sizeof(glslp_t)); - glslp->num_shaders = 1; - struct shader* shader = &glslp->shaders[0]; - strcpy(shader->shader_fn, f); - shader->shader_program = load_file(f); - if (!shader->shader_program) - { - wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; - } - strip_parameters(shader->shader_program); - strip_defines(shader->shader_program); - shader->scale_x = shader->scale_y = 1.0f; - strcpy(shader->scale_type_x, "source"); - strcpy(shader->scale_type_y, "source"); - get_parameters(glslp); - return glslp; -} - -void get_glslp_name(const char* f, char* s, int size) -{ - safe_strncpy(s, get_filename((char*)f), size); -} - -glslp_t* glslp_parse(const char* f) -{ - int i, j, len, sublen; - char s[512], t[512], z[512]; - - s[511] = 0; - if (endswith(f, ".glsl")) - return glsl_parse(f); - - void* cfg = wx_config_load(f); - - if (!cfg) - { - wx_simple_messagebox("GLSLP error", "Could not load GLSLP-file %s\n", f); - return 0; - } - - glslp_t* glslp = malloc(sizeof(glslp_t)); - memset(glslp, 0, sizeof(glslp_t)); - - get_glslp_name(f, glslp->name, sizeof(glslp->name)); - - wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); - - for (i = 0; i < glslp->num_shaders; ++i) - { - struct shader* shader = &glslp->shaders[i]; - - - snprintf(s, sizeof(s)-1, "shader%d", i); - if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) - { - /* shader doesn't exist, lets break here */ - glslp->num_shaders = i; - break; - } - strcpy(s, f); - *get_filename(s) = 0; - snprintf(shader->shader_fn, sizeof(shader->shader_fn)-1, "%s%s", s, t); - shader->shader_program = load_file(shader->shader_fn); - if (!shader->shader_program) - { - wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; - } - strip_parameters(shader->shader_program); - strip_defines(shader->shader_program); - - snprintf(s, sizeof(s)-1, "alias%d", i); - wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); - - snprintf(s, sizeof(s)-1, "filter_linear%d", i); - wx_config_get_bool(cfg, s, &shader->filter_linear, 0); - - snprintf(s, sizeof(s)-1, "wrap_mode%d", i); - wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); - - snprintf(s, sizeof(s)-1, "float_framebuffer%d", i); - wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); - snprintf(s, sizeof(s)-1, "srgb_framebuffer%d", i); - wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); - - snprintf(s, sizeof(s)-1, "mipmap_input%d", i); - wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); - - strcpy(shader->scale_type_x, "source"); - snprintf(s, sizeof(s)-1, "scale_type_x%d", i); - wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); - strcpy(shader->scale_type_y, "source"); - snprintf(s, sizeof(s)-1, "scale_type_y%d", i); - wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); - snprintf(s, sizeof(s)-1, "scale_type%d", i); - if (wx_config_has_entry(cfg, s)) - { - wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); - wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); - } - - snprintf(s, sizeof(s)-1, "scale_x%d", i); - wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); - snprintf(s, sizeof(s)-1, "scale_y%d", i); - wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); - snprintf(s, sizeof(s)-1, "scale%d", i); - if (wx_config_has_entry(cfg, s)) - { - wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); - wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); - } - - snprintf(s, sizeof(s)-1, "frame_count_mod%d", i); - wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); - } - - /* textures */ - glslp->num_textures = 0; - wx_config_get_string(cfg, "textures", t, sizeof(t), 0); - - len = strlen(t); - j = 0; - sublen = 0; - for (i = 0; i < len; ++i) - { - if (t[i] == ';' || i == len-1) - { - sublen = (i-j) + ((i == len-1) ? 1 : 0) + 1; - safe_strncpy(s, t+j, sublen); - s[511 < sublen ? 511 : sublen] = 0; - - struct texture* tex = &glslp->textures[glslp->num_textures++]; - - strcpy(tex->name, s); - wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); - - snprintf(z, sizeof(z)-1, "%s_linear", s); - wx_config_get_bool(cfg, z, &tex->linear, 0); - - snprintf(z, sizeof(z)-1, "%s_mipmap", s); - wx_config_get_bool(cfg, z, &tex->mipmap, 0); - - snprintf(z, sizeof(z)-1, "%s_wrap_mode", s); - wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); - - j = i+1; - } - } - - /* parameters */ - get_parameters(glslp); - - wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); - - len = strlen(t); - j = 0; - sublen = 0; - for (i = 0; i < len; ++i) - { - if (t[i] == ';' || i == len-1) - { - sublen = (i-j) + ((i == len-1) ? 1 : 0) + 1; - safe_strncpy(s, t+j, sublen); - s[511 < sublen ? 511 : sublen] = 0; - - struct parameter* p = get_parameter(glslp, s); - - if (p) - wx_config_get_float(cfg, s, &p->default_value, 0); - - j = i+1; - } - } - - wx_config_free(cfg); - - - return glslp; -} - -void glslp_free(glslp_t* p) -{ - int i; - for (i = 0; i < p->num_shaders; ++i) - if (p->shaders[i].shader_program) - free(p->shaders[i].shader_program); - free(p); -} +#include "wx-glslp-parser.h" + +#include +#include +#include +#include +#include "wx-utils.h" + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +extern char* get_filename(char*); +extern void pclog(const char *format, ...); + +static int endswith(const char* str, const char* ext) +{ + int i; + const char* p; + int elen = strlen(ext); + int slen = strlen(str); + if (slen >= elen) + { + p = &str[slen-elen]; + for (i = 0; i < elen; ++i) + { + if (tolower(p[i]) != tolower(ext[i])) + return 0; + } + return 1; + } + return 0; +} + +static char* load_file(const char* fn) +{ + FILE* f = fopen(fn, "rb"); + if (!f) + return 0; + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char* data = malloc(fsize+1); + + fread(data, fsize, 1, f); + fclose(f); + + data[fsize] = 0; + + return data; +} + +static void strip_lines(const char* program, const char* starts_with) +{ + /* strip parameters */ + char* ptr = strstr(program, starts_with); + while (ptr) + { + while (*ptr != '\n' && *ptr != '\0') + *ptr++ = ' '; + ptr = strstr(program, starts_with); + } +} + +static void strip_parameters(const char* program) +{ + /* strip parameters */ + strip_lines(program, "#pragma parameter"); +} + +static void strip_defines(const char* program) +{ + /* strip texture define */ + strip_lines(program, "#define texture"); +} + +static int has_parameter(glslp_t* glsl, char* id) +{ + int i; + for (i = 0; i < glsl->num_parameters; ++i) + if (!strcmp(glsl->parameters[i].id, id)) + return 1; + return 0; +} + +static int get_parameters(glslp_t* glsl) +{ + int i; + struct parameter p; + for (i = 0; i < glsl->num_shaders; ++i) + { + struct shader* shader = &glsl->shaders[i]; + FILE* f = fopen(shader->shader_fn, "rb"); + if (!f) + return 0; + + char line[1024]; + while (fgets(line, sizeof(line)-1, f) && glsl->num_parameters < MAX_PARAMETERS) + { + int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, &p.default_value, &p.min, &p.max, &p.step); + if (num < 5) + continue; + p.id[63] = 0; + p.description[63] = 0; + + if (num == 5) + p.step = 0.1f * (p.max-p.min); + + p.value = p.default_value; + + if (!has_parameter(glsl, p.id)) + { + memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); + pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, p.max, p.step); + } + } + + fclose(f); + } + + return 1; +} + +static struct parameter* get_parameter(glslp_t* glslp, const char* id) +{ + int i; + for (i = 0; i < glslp->num_parameters; ++i) + { + if (!strcmp(glslp->parameters[i].id, id)) { + return &glslp->parameters[i]; + } + } + return 0; +} + +static glslp_t* glsl_parse(const char* f) +{ + glslp_t* glslp = malloc(sizeof(glslp_t)); + memset(glslp, 0, sizeof(glslp_t)); + glslp->num_shaders = 1; + struct shader* shader = &glslp->shaders[0]; + strcpy(shader->shader_fn, f); + shader->shader_program = load_file(f); + if (!shader->shader_program) + { + wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); + shader->scale_x = shader->scale_y = 1.0f; + strcpy(shader->scale_type_x, "source"); + strcpy(shader->scale_type_y, "source"); + get_parameters(glslp); + return glslp; +} + +void get_glslp_name(const char* f, char* s, int size) +{ + safe_strncpy(s, get_filename((char*)f), size); +} + +glslp_t* glslp_parse(const char* f) +{ + int i, j, len, sublen; + char s[512], t[512], z[512]; + + s[511] = 0; + if (endswith(f, ".glsl")) + return glsl_parse(f); + + void* cfg = wx_config_load(f); + + if (!cfg) + { + wx_simple_messagebox("GLSLP error", "Could not load GLSLP-file %s\n", f); + return 0; + } + + glslp_t* glslp = malloc(sizeof(glslp_t)); + memset(glslp, 0, sizeof(glslp_t)); + + get_glslp_name(f, glslp->name, sizeof(glslp->name)); + + wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); + + wx_config_get_bool(cfg, "filter_linear0", &glslp->input_filter_linear, -1); + + for (i = 0; i < glslp->num_shaders; ++i) + { + struct shader* shader = &glslp->shaders[i]; + + + snprintf(s, sizeof(s)-1, "shader%d", i); + if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) + { + /* shader doesn't exist, lets break here */ + glslp->num_shaders = i; + break; + } + strcpy(s, f); + *get_filename(s) = 0; + snprintf(shader->shader_fn, sizeof(shader->shader_fn)-1, "%s%s", s, t); + shader->shader_program = load_file(shader->shader_fn); + if (!shader->shader_program) + { + wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); + + snprintf(s, sizeof(s)-1, "alias%d", i); + wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); + + snprintf(s, sizeof(s)-1, "filter_linear%d", i+1); + wx_config_get_bool(cfg, s, &shader->filter_linear, 0); + + snprintf(s, sizeof(s)-1, "wrap_mode%d", i); + wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); + + snprintf(s, sizeof(s)-1, "float_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); + snprintf(s, sizeof(s)-1, "srgb_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); + + snprintf(s, sizeof(s)-1, "mipmap_input%d", i); + wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); + + strcpy(shader->scale_type_x, "source"); + snprintf(s, sizeof(s)-1, "scale_type_x%d", i); + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + strcpy(shader->scale_type_y, "source"); + snprintf(s, sizeof(s)-1, "scale_type_y%d", i); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + snprintf(s, sizeof(s)-1, "scale_type%d", i); + if (wx_config_has_entry(cfg, s)) + { + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + } + + snprintf(s, sizeof(s)-1, "scale_x%d", i); + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + snprintf(s, sizeof(s)-1, "scale_y%d", i); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + snprintf(s, sizeof(s)-1, "scale%d", i); + if (wx_config_has_entry(cfg, s)) + { + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + } + + snprintf(s, sizeof(s)-1, "frame_count_mod%d", i); + wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); + } + + /* textures */ + glslp->num_textures = 0; + wx_config_get_string(cfg, "textures", t, sizeof(t), 0); + + len = strlen(t); + j = 0; + sublen = 0; + for (i = 0; i < len; ++i) + { + if (t[i] == ';' || i == len-1) + { + sublen = (i-j) + ((i == len-1) ? 1 : 0) + 1; + safe_strncpy(s, t+j, sublen); + s[511 < sublen ? 511 : sublen] = 0; + + struct texture* tex = &glslp->textures[glslp->num_textures++]; + + strcpy(tex->name, s); + wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); + + snprintf(z, sizeof(z)-1, "%s_linear", s); + wx_config_get_bool(cfg, z, &tex->linear, 0); + + snprintf(z, sizeof(z)-1, "%s_mipmap", s); + wx_config_get_bool(cfg, z, &tex->mipmap, 0); + + snprintf(z, sizeof(z)-1, "%s_wrap_mode", s); + wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); + + j = i+1; + } + } + + /* parameters */ + get_parameters(glslp); + + wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); + + len = strlen(t); + j = 0; + sublen = 0; + for (i = 0; i < len; ++i) + { + if (t[i] == ';' || i == len-1) + { + sublen = (i-j) + ((i == len-1) ? 1 : 0) + 1; + safe_strncpy(s, t+j, sublen); + s[511 < sublen ? 511 : sublen] = 0; + + struct parameter* p = get_parameter(glslp, s); + + if (p) + wx_config_get_float(cfg, s, &p->default_value, 0); + + j = i+1; + } + } + + wx_config_free(cfg); + + + return glslp; +} + +void glslp_free(glslp_t* p) +{ + int i; + for (i = 0; i < p->num_shaders; ++i) + if (p->shaders[i].shader_program) + free(p->shaders[i].shader_program); + free(p); +} diff --git a/src/wx-glslp-parser.h b/src/wx-glslp-parser.h index 94862d7..59ae315 100644 --- a/src/wx-glslp-parser.h +++ b/src/wx-glslp-parser.h @@ -1,54 +1,56 @@ -#ifndef SRC_WX_GLSLP_PARSER_H_ -#define SRC_WX_GLSLP_PARSER_H_ - -#include "wx-glsl.h" - -struct parameter { - char id[64]; - char description[64]; - float default_value; - float value; - float min; - float max; - float step; -}; - -struct texture { - char path[256]; - char name[50]; - int linear; - int mipmap; - char wrap_mode[50]; -}; - -struct shader { - char shader_fn[512]; - char* shader_program; - char alias[64]; - int filter_linear; - int float_framebuffer; - int srgb_framebuffer; - int mipmap_input; - int frame_count_mod; - char wrap_mode[50]; - char scale_type_x[9], scale_type_y[9]; - float scale_x, scale_y; -}; - -typedef struct glslp_t { - char name[64]; - int num_shaders; - struct shader shaders[MAX_SHADERS]; - - int num_textures; - struct texture textures[MAX_TEXTURES]; - - int num_parameters; - struct parameter parameters[MAX_PARAMETERS]; -} glslp_t; - -void get_glslp_name(const char* f, char* s, int size); -glslp_t* glslp_parse(const char* f); -void glslp_free(glslp_t* p); - -#endif /* SRC_WX_GLSLP_PARSER_H_ */ +#ifndef SRC_WX_GLSLP_PARSER_H_ +#define SRC_WX_GLSLP_PARSER_H_ + +#include "wx-glsl.h" + +struct parameter { + char id[64]; + char description[64]; + float default_value; + float value; + float min; + float max; + float step; +}; + +struct texture { + char path[256]; + char name[50]; + int linear; + int mipmap; + char wrap_mode[50]; +}; + +struct shader { + char shader_fn[512]; + char* shader_program; + char alias[64]; + int filter_linear; + int float_framebuffer; + int srgb_framebuffer; + int mipmap_input; + int frame_count_mod; + char wrap_mode[50]; + char scale_type_x[9], scale_type_y[9]; + float scale_x, scale_y; +}; + +typedef struct glslp_t { + char name[64]; + int num_shaders; + struct shader shaders[MAX_SHADERS]; + + int num_textures; + struct texture textures[MAX_TEXTURES]; + + int num_parameters; + struct parameter parameters[MAX_PARAMETERS]; + + int input_filter_linear; +} glslp_t; + +void get_glslp_name(const char* f, char* s, int size); +glslp_t* glslp_parse(const char* f); +void glslp_free(glslp_t* p); + +#endif /* SRC_WX_GLSLP_PARSER_H_ */ diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index e29b949..5aee3e9 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -1,1647 +1,1661 @@ -#include -#define BITMAP WINDOWS_BITMAP -#include -#if SDL_VERSION_ATLEAST(2, 0, 4) -#include -#endif -#undef BITMAP -#include "wx-sdl2-glw.h" -#include -#include -#include -#include "video.h" -#include "wx-sdl2-video.h" -#include "wx-sdl2-video-renderer.h" -#include "ibm.h" -#include "wx-glslp-parser.h" -#include "wx-utils.h" -#include "config.h" -#include "wx-glsl.h" - -extern char* get_filename(char*); - -extern int take_screenshot; -extern void screenshot_taken(unsigned char* rgb, int width, int height); - -#define SCALE_SOURCE 0 -#define SCALE_VIEWPORT 1 -#define SCALE_ABSOLUTE 2 - -float gl3_shader_refresh_rate = 0; -float gl3_input_scale = 1.0f; -int gl3_input_stretch = FULLSCR_SCALE_FULL; -char gl3_shader_file[MAX_USER_SHADERS][512]; - -static int max_texture_size; - -static SDL_GLContext context = NULL; -static struct shader_texture scene_texture; - -static glsl_t* active_shader; - -static glw_t* glw; - -static GLfloat matrix[] = { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 -}; - - -extern int video_scale_mode; -extern int video_vsync; -extern int video_focus_dim; -extern int video_refresh_rate; - -const char* vertex_shader_default_tex_src = - "#version 130\n" - "\n" - "in vec4 VertexCoord;\n" - "in vec2 TexCoord;\n" - "\n" - "out vec2 texCoord;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = VertexCoord;\n" - " texCoord = TexCoord;\n" - "}\n"; - -const char* fragment_shader_default_tex_src = - "#version 130\n" - "\n" - "in vec2 texCoord;\n" - "uniform sampler2D Texture;\n" - "\n" - "out vec4 color;" - "\n" - "void main()\n" - "{\n" - " color = texture(Texture, texCoord);\n" - "}\n"; - -const char* vertex_shader_default_color_src = - "#version 130\n" - "\n" - "in vec4 VertexCoord;\n" - "in vec4 Color;\n" - "\n" - "out vec4 color;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = VertexCoord;\n" - " color = Color;\n" - "}\n"; - -const char* fragment_shader_default_color_src = - "#version 130\n" - "\n" - "in vec4 color;\n" - "\n" - "out vec4 outColor;" - "\n" - "void main()\n" - "{\n" - " outColor = color;\n" - "}\n"; - -static int next_pow2(unsigned int n) -{ - n--; - n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32, - n |= n >> 2; // and then or the results. - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - n++; - - return n; -} - -static int compile_shader(GLenum shader_type, const char* prepend, const char* program, int* dst) -{ - const char* source[3]; - source[0] = ""; - source[1] = prepend ? prepend : ""; - source[2] = 0; - char version[50]; - if (strstr(program, "#version")) - { - char* line = strchr(program, '\n'); - int len = (line-program)+1; - if (len >= sizeof(version)-1) len = sizeof(version)-1; - strncpy(version, program, len); - version[len] = 0; - source[0] = version; - source[2] = line; - } - else - { -// source[0] = "#version 130\n"; - source[2] = program; - } - - GLuint shader = glw->glCreateShader(shader_type); - glw->glShaderSource(shader, 3, source, NULL); - glw->glCompileShader(shader); - - GLint status = 0; - glw->glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (!status) - { - GLint length; - glw->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); - char* log = malloc(length); - glw->glGetShaderInfoLog(shader, length, &length, log); - wx_simple_messagebox("GLSL Error", "Could not compile shader:\n%s", log); - pclog("Could not compile shader: %s\n", log); -// pclog("Shader: %s\n", program); - - free(log); - return 0; - } - - *dst = shader; - - return 1; -} - -static int create_program(struct shader_program* program) -{ - GLint status; - program->id = glw->glCreateProgram(); - glw->glAttachShader(program->id, program->vertex_shader); - glw->glAttachShader(program->id, program->fragment_shader); - - glw->glLinkProgram(program->id); - - glw->glDeleteShader(program->vertex_shader); - glw->glDeleteShader(program->fragment_shader); - - program->vertex_shader = program->fragment_shader = 0; - - glw->glGetProgramiv(program->id, GL_LINK_STATUS, &status); - - if (!status) - { - int maxLength; - int length; - glw->glGetProgramiv(program->id, GL_INFO_LOG_LENGTH, &maxLength); - char* log = malloc(maxLength); - glw->glGetProgramInfoLog(program->id, maxLength, &length, log); - wx_simple_messagebox("GLSL Error", "Program not linked:\n%s", log); - free(log); - return 0; - } - - return 1; -} - -static GLuint get_uniform(GLuint program, const char* name) -{ - return glw->glGetUniformLocation(program, name); -} - -static GLuint get_attrib(GLuint program, const char* name) -{ - return glw->glGetAttribLocation(program, name); -} - -static void find_uniforms(struct glsl_shader* glsl, int num_pass) -{ - int i; - char s[50]; - struct shader_pass* pass = &glsl->passes[num_pass]; - int p = pass->program.id; - glw->glUseProgram(p); - - struct shader_uniforms* u = &pass->uniforms; - - u->mvp_matrix = get_uniform(p, "MVPMatrix"); - u->vertex_coord = get_attrib(p, "VertexCoord"); - u->tex_coord = get_attrib(p, "TexCoord"); - u->color = get_attrib(p, "Color"); - - u->frame_count = get_uniform(p, "FrameCount"); - u->frame_direction = get_uniform(p, "FrameDirection"); - - u->texture = get_uniform(p, "Texture"); - u->input_size = get_uniform(p, "InputSize"); - u->texture_size = get_uniform(p, "TextureSize"); - u->output_size = get_uniform(p, "OutputSize"); - - u->orig.texture = get_uniform(p, "OrigTexture"); - u->orig.input_size = get_uniform(p, "OrigInputSize"); - u->orig.texture_size = get_uniform(p, "OrigTextureSize"); - - for (i = 0; i < glsl->num_passes; ++i) - { - sprintf(s, "Pass%dTexture", (i+1)); - u->pass[i].texture = get_uniform(p, s); - sprintf(s, "Pass%dInputSize", (i+1)); - u->pass[i].input_size = get_uniform(p, s); - sprintf(s, "Pass%dTextureSize", (i+1)); - u->pass[i].texture_size = get_uniform(p, s); - - sprintf(s, "PassPrev%dTexture", num_pass-i); - u->prev_pass[i].texture = get_uniform(p, s); - sprintf(s, "PassPrev%dInputSize", num_pass-i); - u->prev_pass[i].input_size = get_uniform(p, s); - sprintf(s, "PassPrev%dTextureSize", num_pass-i); - u->prev_pass[i].texture_size = get_uniform(p, s); - } - - u->prev[0].texture = get_uniform(p, "PrevTexture"); - u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); - for (i = 1; i < MAX_PREV; ++i) - { - sprintf(s, "Prev%dTexture", i); - u->prev[i].texture = get_uniform(p, s); - sprintf(s, "Prev%dTexCoord", i); - u->prev[i].tex_coord = get_attrib(p, s); - } - for (i = 0; i < MAX_PREV; ++i) - if (u->prev[i].texture >= 0) glsl->has_prev = 1; - - for (i = 0; i < glsl->num_lut_textures; ++i) - u->lut_textures[i] = get_uniform(p, glsl->lut_textures[i].name); - - for (i = 0; i < glsl->num_parameters; ++i) - u->parameters[i] = get_uniform(p, glsl->parameters[i].id); - - glw->glUseProgram(0); -} - -static void set_scale_mode(char* scale, int* dst) -{ - if (!strcmp(scale, "viewport")) - *dst = SCALE_VIEWPORT; - else if (!strcmp(scale, "absolute")) - *dst = SCALE_ABSOLUTE; - else - *dst = SCALE_SOURCE; -} - -static void setup_scale(struct shader* shader, struct shader_pass* pass) -{ - set_scale_mode(shader->scale_type_x, &pass->scale.mode[0]); - set_scale_mode(shader->scale_type_y, &pass->scale.mode[1]); - pass->scale.value[0] = shader->scale_x; - pass->scale.value[1] = shader->scale_y; -} - -static void create_texture(struct shader_texture* tex) -{ - if (tex->width > max_texture_size) - tex->width = max_texture_size; - if (tex->height > max_texture_size) - tex->height = max_texture_size; - pclog("Create texture with size %dx%d\n", tex->width, tex->height); - glGenTextures(1, (GLuint *)&tex->id); - glBindTexture(GL_TEXTURE_2D, tex->id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex->wrap_mode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex->wrap_mode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter); - glTexImage2D(GL_TEXTURE_2D, 0, tex->internal_format, tex->width, tex->height, 0, tex->format, tex->type, tex->data); - if (tex->mipmap) - glw->glGenerateMipmap(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); -} - -static void delete_texture(struct shader_texture* tex) -{ - if (tex->id > 0) - glDeleteTextures(1, (GLuint *)&tex->id); - tex->id = 0; -} - -static void delete_fbo(struct shader_fbo* fbo) -{ - if (fbo->id >= 0) - { - glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); - delete_texture(&fbo->texture); - } -} - -static void delete_program(struct shader_program* program) -{ - if (program->vertex_shader) glw->glDeleteShader(program->vertex_shader); - if (program->fragment_shader) glw->glDeleteShader(program->fragment_shader); - glw->glDeleteProgram(program->id); -} - -static void delete_vbo(struct shader_vbo* vbo) -{ - if (vbo->color >= 0) glw->glDeleteBuffers(1, (GLuint *)&vbo->color); - glw->glDeleteBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glDeleteBuffers(1, (GLuint *)&vbo->tex_coord); -} - -static void delete_pass(struct shader_pass* pass) -{ - delete_fbo(&pass->fbo); - delete_vbo(&pass->vbo); - delete_program(&pass->program); - glw->glDeleteVertexArrays(1, (GLuint *)&pass->vertex_array); -} - -static void delete_prev(struct shader_prev* prev) -{ - delete_fbo(&prev->fbo); - delete_vbo(&prev->vbo); -} - -static void delete_shader(struct glsl_shader* glsl) -{ - int i; - for (i = 0; i < glsl->num_passes; ++i) - delete_pass(&glsl->passes[i]); - if (glsl->has_prev) - { - delete_pass(&glsl->prev_scene); - for (i = 0; i < MAX_PREV; ++i) - delete_prev(&glsl->prev[i]); - } - for (i = 0; i < glsl->num_lut_textures; ++i) - delete_texture(&glsl->lut_textures[i].texture); -} - -static void delete_glsl(glsl_t* glsl) -{ - int i; - for (i = 0; i < glsl->num_shaders; ++i) - delete_shader(&glsl->shaders[i]); - delete_pass(&glsl->scene); - delete_pass(&glsl->fs_color); - delete_pass(&glsl->final_pass); -#ifdef SDL2_SHADER_DEBUG - delete_pass(&glsl->debug); -#endif -} - -static void create_fbo(struct shader_fbo* fbo) -{ - create_texture(&fbo->texture); - - glw->glGenFramebuffers(1, (GLuint *)&fbo->id); - glw->glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); - glw->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); - - if (glw->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - pclog("Could not create framebuffer!\n"); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -static void setup_fbo(struct shader* shader, struct shader_fbo* fbo) -{ - fbo->texture.internal_format = GL_RGBA8; - fbo->texture.format = GL_RGBA; - fbo->texture.min_filter = fbo->texture.mag_filter = shader->filter_linear ? GL_LINEAR : GL_NEAREST; - fbo->texture.width = 1024; - fbo->texture.height = 1024; - fbo->texture.type = GL_UNSIGNED_BYTE; - if (!strcmp(shader->wrap_mode, "repeat")) - fbo->texture.wrap_mode = GL_REPEAT; - else if (!strcmp(shader->wrap_mode, "mirrored_repeat")) - fbo->texture.wrap_mode = GL_MIRRORED_REPEAT; - else if (!strcmp(shader->wrap_mode, "clamp_to_edge")) - fbo->texture.wrap_mode = GL_CLAMP_TO_EDGE; - else - fbo->texture.wrap_mode = GL_CLAMP_TO_BORDER; - fbo->srgb = 0; - if (shader->srgb_framebuffer) - { - fbo->texture.internal_format = GL_SRGB8_ALPHA8; - fbo->srgb = 1; - } - else if (shader->float_framebuffer) - { - fbo->texture.internal_format = GL_RGBA32F; - fbo->texture.type = GL_FLOAT; - } - - if (fbo->texture.mipmap) - fbo->texture.min_filter = shader->filter_linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; - - create_fbo(fbo); -} - -static void recreate_fbo(struct shader_fbo* fbo, int width, int height) -{ - if (width != fbo->texture.width || height != fbo->texture.height) - { - glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); - glDeleteTextures(1, (GLuint *)&fbo->texture.id); - fbo->texture.width = width; - fbo->texture.height = height; - create_fbo(fbo); - } -} - -static int create_default_shader_tex(struct shader_pass* pass) -{ - if ( - !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_tex_src, &pass->program.vertex_shader) || - !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_tex_src, &pass->program.fragment_shader) || - !create_program(&pass->program)) - return 0; - glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); - - struct shader_uniforms* u = &pass->uniforms; - int p = pass->program.id; - memset(u, -1, sizeof(struct shader_uniforms)); - u->vertex_coord = get_attrib(p, "VertexCoord"); - u->tex_coord = get_attrib(p, "TexCoord"); - u->texture = get_uniform(p, "Texture"); - pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; - pass->scale.value[0] = pass->scale.value[1] = 1.0f; - pass->fbo.id = -1; - pass->active = 1; - return 1; -} - -static int create_default_shader_color(struct shader_pass* pass) -{ - if ( - !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_color_src, &pass->program.vertex_shader) || - !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_color_src, &pass->program.fragment_shader) || - !create_program(&pass->program)) - return 0; - glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); - - struct shader_uniforms* u = &pass->uniforms; - int p = pass->program.id; - memset(u, -1, sizeof(struct shader_uniforms)); - u->vertex_coord = get_attrib(p, "VertexCoord"); - u->color = get_attrib(p, "Color"); - pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; - pass->scale.value[0] = pass->scale.value[1] = 1.0f; - pass->fbo.id = -1; - pass->active = 1; - return 1; -} - -/* create the default scene shader */ -static void create_scene_shader() -{ - struct shader scene_shader_conf; - memset(&scene_shader_conf, 0, sizeof(struct shader)); - create_default_shader_tex(&active_shader->scene); - setup_fbo(&scene_shader_conf, &active_shader->scene.fbo); - - memset(&scene_shader_conf, 0, sizeof(struct shader)); - create_default_shader_color(&active_shader->fs_color); - setup_fbo(&scene_shader_conf, &active_shader->fs_color.fbo); -} - -static int load_texture(const char* f, struct shader_texture* tex) -{ - void* img = wx_image_load(f); - if (!img) - return 0; - int width, height; - wx_image_get_size(img, &width, &height); - - if (width != next_pow2(width) || height != next_pow2(height)) - wx_image_rescale(img, next_pow2(width), next_pow2(height)); - - wx_image_get_size(img, &width, &height); - - GLubyte* rgb = wx_image_get_data(img); - GLubyte* alpha = wx_image_get_alpha(img); - - int bpp = alpha ? 4 : 3; - - GLubyte* data = malloc(width*height*bpp); - - int x, y, Y; - for (y = 0; y < height; ++y) - { - Y = height-y-1; - for (x = 0; x < width; x++) - { - data[(y*width+x)*bpp+0] = rgb[(Y*width+x)*3+0]; - data[(y*width+x)*bpp+1] = rgb[(Y*width+x)*3+1]; - data[(y*width+x)*bpp+2] = rgb[(Y*width+x)*3+2]; - - if (alpha) - data[(y*width+x)*bpp+3] = alpha[Y*width+x]; - } - } - wx_image_free(img); - - tex->width = width; - tex->height = height; - tex->internal_format = alpha ? GL_RGBA8 : GL_RGB8; - tex->format = alpha ? GL_RGBA : GL_RGB; - tex->type = GL_UNSIGNED_BYTE; - tex->data = data; - return 1; -} - -static glsl_t* load_glslp(glsl_t* glsl, int num_shader, const char* f) -{ - int i, j; - glslp_t* p = glslp_parse(f); - - if (p) - { - char path[512]; - char file[512]; - int failed = 0; - strcpy(path, f); - char* filename = get_filename(path); - - struct glsl_shader* gshader = &glsl->shaders[num_shader]; - - strcpy(gshader->name, p->name); - *filename = 0; - - gshader->num_lut_textures = p->num_textures; - - for (i = 0; i < p->num_textures; ++i) - { - struct texture* texture = &p->textures[i]; - - sprintf(file, "%s%s", path, texture->path); - - struct shader_lut_texture* tex = &gshader->lut_textures[i]; - strcpy(tex->name, texture->name); - - pclog("Load texture %s...\n", file); - - if (!load_texture(file, &tex->texture)) - { - wx_simple_messagebox("GLSL Error", "Could not load texture: %s", file); - pclog("Could not load texture %s!\n", file); - failed = 1; - break; - } - - if (!strcmp(texture->wrap_mode, "repeat")) - tex->texture.wrap_mode = GL_REPEAT; - else if (!strcmp(texture->wrap_mode, "mirrored_repeat")) - tex->texture.wrap_mode = GL_MIRRORED_REPEAT; - else if (!strcmp(texture->wrap_mode, "clamp_to_edge")) - tex->texture.wrap_mode = GL_CLAMP_TO_EDGE; - else - tex->texture.wrap_mode = GL_CLAMP_TO_BORDER; - - tex->texture.mipmap = texture->mipmap; - - tex->texture.min_filter = tex->texture.mag_filter = texture->linear ? GL_LINEAR : GL_NEAREST; - if (tex->texture.mipmap) - tex->texture.min_filter = texture->linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; - - create_texture(&tex->texture); - free(tex->texture.data); - tex->texture.data = 0; - } - - if (!failed) - { - gshader->num_parameters = p->num_parameters; - for (j = 0; j < gshader->num_parameters; ++j) - memcpy(&gshader->parameters[j], &p->parameters[j], sizeof(struct shader_parameter)); - - gshader->num_passes = p->num_shaders; - - for (i = 0; i < p->num_shaders; ++i) - { - struct shader* shader = &p->shaders[i]; - struct shader_pass* pass = &gshader->passes[i]; - - strcpy(pass->alias, shader->alias); - if (!strlen(pass->alias)) - sprintf(pass->alias, "Pass %u", (i+1)); - - pclog("Creating pass %u (%s)\n", (i+1), pass->alias); - pclog("Loading shader %s...\n", shader->shader_fn); - if (!shader->shader_program) - { - wx_simple_messagebox("GLSL Error", "Could not load shader: %s", shader->shader_fn); - pclog("Could not load shader %s\n", shader->shader_fn); - failed = 1; - break; - } - else - pclog("Shader %s loaded\n", shader->shader_fn); - failed = - !compile_shader(GL_VERTEX_SHADER, "#define VERTEX\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.vertex_shader) || - !compile_shader(GL_FRAGMENT_SHADER, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.fragment_shader); - if (failed) - break; - - if (!create_program(&pass->program)) - { - failed = 1; - break; - } - pass->frame_count_mod = shader->frame_count_mod; - - glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); - find_uniforms(gshader, i); - setup_scale(shader, pass); - if (i == p->num_shaders-1) /* last pass may or may not be an fbo depending on scale */ - { - if (num_shader == glsl->num_shaders-1) - { - pass->fbo.id = -1; - - for (j = 0; j < 2; ++j) - { - if (pass->scale.mode[j] != SCALE_SOURCE || pass->scale.value[j] != 1) - { - setup_fbo(shader, &pass->fbo); - break; - } - } - } - else - setup_fbo(shader, &pass->fbo); - } - else - { - /* check if next pass wants the input mipmapped, if so we need to generate mipmaps of this pass */ - pass->fbo.texture.mipmap = (i+1) < p->num_shaders && p->shaders[i+1].mipmap_input; - setup_fbo(shader, &pass->fbo); - } - if (pass->fbo.srgb) glsl->srgb = 1; - pass->active = 1; - } - if (!failed) - { - if (gshader->has_prev) - { - struct shader scene_shader_conf; - memset(&scene_shader_conf, 0, sizeof(struct shader)); - for (i = 0; i < MAX_PREV; ++i) - { - setup_fbo(&scene_shader_conf, &gshader->prev[i].fbo); - } - - } - } - } - - glslp_free(p); - - return glsl; - } - return 0; -} - -static glsl_t* load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) -{ - int i; - glsl_t* glsl; - - glsl = malloc(sizeof(glsl_t)); - memset(glsl, 0, sizeof(glsl_t)); - - glsl->num_shaders = num; - int failed = 0; - for (i = 0; i < num; ++i) - { - const char* f = shaders[i]; - if (f && strlen(f)) - { - if (!load_glslp(glsl, i, f)) - { - failed = 1; - break; - } - } - - } - if (failed) - { - delete_glsl(glsl); - memset(glsl, 0, sizeof(glsl_t)); - } - return glsl; -} - -static void read_shader_config() -{ - char s[512]; - int i, j; - for (i = 0; i < active_shader->num_shaders; ++i) - { - struct glsl_shader* shader = &active_shader->shaders[i]; - char* name = shader->name; - sprintf(s, "GL3 Shaders - %s", name); -// shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); - for (j = 0; j < shader->num_parameters; ++j) - { - struct shader_parameter* param = &shader->parameters[j]; - param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); - } - } -} - -int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITMAP* screen) -{ - int i, j; - - strcpy(current_render_driver_name, requested_render_driver.name); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); - - context = SDL_GL_CreateContext(window); - - if (!context) - { - pclog("Could not create GL context.\n"); - return FALSE; - } - - SDL_GL_SetSwapInterval(video_vsync ? 1 : 0); - - pclog("OpenGL information: [%s] %s (%s)\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); - int version = -1; - glGetIntegerv(GL_MAJOR_VERSION, &version); - if (version < 3) - { - pclog("OpenGL 3.0 is not available."); - return SDL_FALSE; - } - pclog("Using OpenGL %s\n", glGetString(GL_VERSION)); - pclog("Using Shading Language %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - pclog("Max texture size: %dx%d\n", max_texture_size, max_texture_size); - - //SDL_GL_MakeCurrent(window, context); - - glw = glw_init(); - - glEnable(GL_TEXTURE_2D); - - scene_texture.data = screen->dat; - scene_texture.width = screen->w; - scene_texture.height = screen->h; - scene_texture.internal_format = GL_RGBA8; - scene_texture.format = GL_RGBA; - scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; - scene_texture.wrap_mode = GL_CLAMP_TO_BORDER; - scene_texture.min_filter = scene_texture.mag_filter = video_scale_mode ? GL_LINEAR : GL_NEAREST; - scene_texture.mipmap = 0; - - create_texture(&scene_texture); - - /* load shader */ -// const char* shaders[1]; -// shaders[0] = gl3_shader_file; -// -// active_shader = load_shaders(1, shaders); - -// const char* shaders[3]; -// shaders[0] = "/home/phantasy/git/glsl-shaders/ntsc/ntsc-320px.glslp"; -// shaders[1] = "/home/phantasy/git/glsl-shaders/motionblur/motionblur-simple.glslp"; -// shaders[2] = "/home/phantasy/git/glsl-shaders/crt/crt-lottes-multipass.glslp"; -// -// active_shader = load_shaders(3, shaders); - int num_shaders = 0; - for (i = 0; i < MAX_USER_SHADERS; ++i) - { - if (strlen(gl3_shader_file[i])) - ++num_shaders; - else - break; - } - active_shader = load_shaders(num_shaders, gl3_shader_file); - - create_scene_shader(); - - /* read config */ - read_shader_config(); - - /* buffers */ - - GLfloat vertex[] = { - -1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, -1.0f, - 1.0f, 1.0f - }; - - GLfloat inv_vertex[] = { - -1.0f, 1.0f, - -1.0f, -1.0f, - 1.0f, 1.0f, - 1.0f, -1.0f - }; - - GLfloat tex_coords[] = { - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f - }; - - - GLfloat colors[] = { - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f - }; - - - /* set the scene shader buffers */ - { - glw->glBindVertexArray(active_shader->scene.vertex_array); - - struct shader_vbo* vbo = &active_shader->scene.vbo; - - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(inv_vertex), inv_vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(active_shader->scene.uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(active_shader->scene.uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); - } - - /* set buffers for all passes */ - for (j = 0; j < active_shader->num_shaders; ++j) - { - struct glsl_shader* shader = &active_shader->shaders[j]; - for (i = 0; i < shader->num_passes; ++i) - { - struct shader_uniforms* u = &shader->passes[i].uniforms; - - glw->glBindVertexArray(shader->passes[i].vertex_array); - - struct shader_vbo* vbo = &shader->passes[i].vbo; - - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - - glw->glVertexAttribPointer(u->vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(u->tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); - - if (u->color) - { - glw->glGenBuffers(1, (GLuint *)&vbo->color); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); - glw->glVertexAttribPointer(u->color, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)0); - } - } - } - - for (i = 0; i < active_shader->num_shaders; ++i) - { - struct glsl_shader* shader = &active_shader->shaders[i]; - if (shader->has_prev) - { - struct shader_pass* prev_pass = &shader->prev_scene; - create_default_shader_tex(prev_pass); - - struct shader_vbo* vbo = &prev_pass->vbo; - - glw->glBindVertexArray(prev_pass->vertex_array); - - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(prev_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(prev_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); - - for (j = 0; j < MAX_PREV; ++j) - { - struct shader_prev* prev = &shader->prev[j]; - struct shader_vbo* prev_vbo = &prev->vbo; - - glw->glGenBuffers(1, (GLuint *)&prev_vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - - glw->glGenBuffers(1, (GLuint *)&prev_vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - } - } - } - - /* create final pass */ - if (active_shader->num_shaders == 0 || active_shader->shaders[active_shader->num_shaders-1].passes[active_shader->shaders[active_shader->num_shaders-1].num_passes-1].fbo.id >= 0) - { - struct shader_pass* final_pass = &active_shader->final_pass; - create_default_shader_tex(final_pass); - - glw->glBindVertexArray(final_pass->vertex_array); - - struct shader_vbo* vbo = &final_pass->vbo; - - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(final_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(final_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); - } - - { - struct shader_pass* color_pass = &active_shader->fs_color; - create_default_shader_color(color_pass); - - glw->glBindVertexArray(color_pass->vertex_array); - - struct shader_vbo* vbo = &color_pass->vbo; - - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(color_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - - glw->glGenBuffers(1, (GLuint *)&vbo->color); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(color_pass->uniforms.color, 4, GL_FLOAT, GL_TRUE, 4*sizeof(GLfloat), (GLvoid*)0); - - } -#ifdef SDL2_SHADER_DEBUG - struct shader_pass* debug_pass = &active_shader->debug; - create_default_shader(debug_pass); - - glBindVertexArray(debug_pass->vertex_array); - - struct shader_vbo* vbo = &debug_pass->vbo; - - glGenBuffers(1, &vbo->vertex_coord); - glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glVertexAttribPointer(debug_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); - - glGenBuffers(1, &vbo->tex_coord); - glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glVertexAttribPointer(debug_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); -#endif - - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - glw->glBindVertexArray(0); - - return SDL_TRUE; -} - -void gl3_close() -{ - if (context) - { - delete_texture(&scene_texture); - - if (active_shader) - { - delete_glsl(active_shader); - free(active_shader); - } - active_shader = NULL; - - SDL_GL_DeleteContext(context); - context = NULL; - } - glw_free(glw); -} - -void gl3_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen) -{ - if (!context) - return; - glBindTexture(GL_TEXTURE_2D, scene_texture.id); - glPixelStorei(GL_UNPACK_ROW_LENGTH, screen->w); - glTexSubImage2D(GL_TEXTURE_2D, 0, updated_rect.x, updated_rect.y, updated_rect.w, updated_rect.h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x]); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glBindTexture(GL_TEXTURE_2D, 0); -} - -struct render_data { - int pass; - struct glsl_shader* shader; - struct shader_pass* shader_pass; - GLfloat* output_size; - struct shader_pass* orig_pass; - GLint texture; - int frame_count; -}; - -static void render_pass(struct render_data* data) -{ - int i; - GLuint texture_unit = 0; - -// pclog("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], pass->state.input_size[1], pass->state.input_texture_size[0], pass->state.input_texture_size[1], pass->state.output_size[0], pass->state.output_size[1], pass->state.output_texture_size[0], pass->state.output_texture_size[1], output_size[0], output_size[1]); - - glw->glBindVertexArray(data->shader_pass->vertex_array); - - GLint p = data->shader_pass->program.id; - struct shader_uniforms* u = &data->shader_pass->uniforms; - - glw->glUseProgram(p); - - if (data->texture) - { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, data->texture); - glw->glUniform1i(u->texture, texture_unit); - texture_unit++; - } - - if (u->color >= 0) glw->glEnableVertexAttribArray(u->color); - - if (u->mvp_matrix >= 0) glw->glUniformMatrix4fv(u->mvp_matrix, 1, 0, matrix); - if (u->frame_direction >= 0) glw->glUniform1i(u->frame_direction, 1); - - int framecnt = data->frame_count; - if (data->shader_pass->frame_count_mod > 0) - framecnt = framecnt%data->shader_pass->frame_count_mod; - if (u->frame_count >= 0) glw->glUniform1i(u->frame_count, framecnt); - - if (u->input_size >= 0) glw->glUniform2fv(u->input_size, 1, data->shader_pass->state.input_size); - if (u->texture_size >= 0) glw->glUniform2fv(u->texture_size, 1, data->shader_pass->state.input_texture_size); - if (u->output_size >= 0) glw->glUniform2fv(u->output_size, 1, data->output_size); - - if (data->shader) - { - /* parameters */ - for (i = 0; i < data->shader->num_parameters; ++i) - if (u->parameters[i] >= 0) glw->glUniform1f(u->parameters[i], data->shader->parameters[i].value); - - if (data->pass > 0) - { - struct shader_pass* passes = data->shader->passes; - struct shader_pass* orig = data->orig_pass; - if (u->orig.texture >= 0) - { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, orig->fbo.texture.id); - glw->glUniform1i(u->orig.texture, texture_unit); - texture_unit++; - } - if (u->orig.input_size >= 0) glw->glUniform2fv(u->orig.input_size, 1, orig->state.input_size); - if (u->orig.texture_size >= 0) glw->glUniform2fv(u->orig.texture_size, 1, orig->state.input_texture_size); - - for (i = 0; i < data->pass; ++i) - { - if (u->pass[i].texture >= 0) - { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); - glw->glUniform1i(u->pass[i].texture, texture_unit); - texture_unit++; - } - if (u->pass[i].texture_size >= 0) glw->glUniform2fv(u->pass[i].texture_size, 1, passes[i].state.input_texture_size); - if (u->pass[i].input_size >= 0) glw->glUniform2fv(u->pass[i].input_size, 1, passes[i].state.input_size); - - if (u->prev_pass[i].texture >= 0) - { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); - glw->glUniform1i(u->prev_pass[i].texture, texture_unit); - texture_unit++; - } - if (u->prev_pass[i].texture_size >= 0) glw->glUniform2fv(u->prev_pass[i].texture_size, 1, passes[i].state.input_texture_size); - if (u->prev_pass[i].input_size >= 0) glw->glUniform2fv(u->prev_pass[i].input_size, 1, passes[i].state.input_size); - - } - } - - if (data->shader->has_prev) - { - /* loop through each previous frame */ - for (i = 0; i < MAX_PREV; ++i) - { - if (u->prev[i].texture >= 0) - { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, data->shader->prev[i].fbo.texture.id); - glw->glUniform1i(u->prev[i].texture, texture_unit); - texture_unit++; - } - if (u->prev[i].tex_coord >= 0) - { - glw->glBindBuffer(GL_ARRAY_BUFFER, data->shader->prev[i].vbo.tex_coord); - glw->glVertexAttribPointer(u->prev[i].tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); - glw->glEnableVertexAttribArray(u->prev[i].tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - } - } - } - - for (i = 0; i < data->shader->num_lut_textures; ++i) - { - if (u->lut_textures[i] >= 0) - { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, data->shader->lut_textures[i].texture.id); - glw->glUniform1i(u->lut_textures[i], texture_unit); - texture_unit++; - } - - } - } - - glw->glEnableVertexAttribArray(u->vertex_coord); - glw->glEnableVertexAttribArray(u->tex_coord); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glw->glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - - glw->glDisableVertexAttribArray(data->shader_pass->uniforms.vertex_coord); - glw->glDisableVertexAttribArray(data->shader_pass->uniforms.tex_coord); - if (data->shader_pass->uniforms.color >= 0) glw->glDisableVertexAttribArray(data->shader_pass->uniforms.color); - - if (data->shader && data->shader->has_prev) - { - for (i = 0; i < MAX_PREV; ++i) - { - if (u->prev[i].tex_coord >= 0) - glw->glDisableVertexAttribArray(u->prev[i].tex_coord); - - } - } - - glw->glBindVertexArray(0); - - - glw->glUseProgram(0); -} - -void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, BITMAP* screen) -{ - if (!context) - return; - - int s, i, j; - - Uint32 ticks = SDL_GetTicks(); - - GLfloat orig_output_size[] = { - window_rect.w, window_rect.h - }; - - if (active_shader->srgb) glEnable(GL_FRAMEBUFFER_SRGB); - - struct render_data data; - - /* render scene to texture */ - { - struct shader_pass* pass = &active_shader->scene; - - SDL_Rect rect; - rect.x = rect.y = 0; - rect.w = video_rect.w*gl3_input_scale; - rect.h = video_rect.h*gl3_input_scale; - sdl_scale(gl3_input_stretch, rect, &rect, video_rect.w, video_rect.h); - - pass->state.input_size[0] = pass->state.output_size[0] = rect.w; - pass->state.input_size[1] = pass->state.output_size[1] = rect.h; - - pass->state.input_texture_size[0] = pass->state.output_texture_size[0] = next_pow2(pass->state.output_size[0]); - pass->state.input_texture_size[1] = pass->state.output_texture_size[1] = next_pow2(pass->state.output_size[1]); - - recreate_fbo(&active_shader->scene.fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, active_shader->scene.fbo.id); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - - GLfloat minx = 0; - GLfloat miny = 0; - GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; - GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; - - pass->state.tex_coords[0] = minx; - pass->state.tex_coords[1] = miny; - pass->state.tex_coords[2] = minx; - pass->state.tex_coords[3] = maxy; - pass->state.tex_coords[4] = maxx; - pass->state.tex_coords[5] = miny; - pass->state.tex_coords[6] = maxx; - pass->state.tex_coords[7] = maxy; - - // create input tex coords - minx = video_rect.x/(float)screen->w; - miny = video_rect.y/(float)screen->h; - maxx = (video_rect.x+video_rect.w)/(float)screen->w; - maxy = (video_rect.y+video_rect.h)/(float)screen->h; - - GLfloat tex_coords[] = { - minx, miny, - minx, maxy, - maxx, miny, - maxx, maxy - }; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -1; - data.shader_pass = &active_shader->scene; - data.texture = scene_texture.id; - data.output_size = orig_output_size; - render_pass(&data); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - struct shader_pass* orig = &active_shader->scene; - struct shader_pass* input = &active_shader->scene; - - for (s = 0; s < active_shader->num_shaders; ++s) - { - struct glsl_shader* shader = &active_shader->shaders[s]; - -// float refresh_rate = shader->shader_refresh_rate; -// if (refresh_rate < 0) -// refresh_rate = gl3_shader_refresh_rate; - float refresh_rate = gl3_shader_refresh_rate; - if (refresh_rate == 0) - refresh_rate = video_refresh_rate; - int frame_count = ticks/(1000.0f/refresh_rate); - - /* loop through each pass */ - for (i = 0; i < shader->num_passes; ++i) - { - struct shader_pass* pass = &shader->passes[i]; - - memcpy(pass->state.input_size, input->state.output_size, 2*sizeof(GLfloat)); - memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2*sizeof(GLfloat)); - - for (j = 0; j < 2; ++j) - { - if (pass->scale.mode[j] == SCALE_VIEWPORT) - pass->state.output_size[j] = orig_output_size[j]*pass->scale.value[j]; - else if (pass->scale.mode[j] == SCALE_ABSOLUTE) - pass->state.output_size[j] = pass->scale.value[j]; - else - pass->state.output_size[j] = pass->state.input_size[j]*pass->scale.value[j]; - - pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); - } - - if (pass->fbo.id >= 0) - { - recreate_fbo(&pass->fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, pass->fbo.id); - glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - } - else - glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); - - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - GLfloat minx = 0; - GLfloat miny = 0; - GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; - GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; - - pass->state.tex_coords[0] = minx; - pass->state.tex_coords[1] = miny; - pass->state.tex_coords[2] = minx; - pass->state.tex_coords[3] = maxy; - pass->state.tex_coords[4] = maxx; - pass->state.tex_coords[5] = miny; - pass->state.tex_coords[6] = maxx; - pass->state.tex_coords[7] = maxy; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), input->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.shader = shader; - data.pass = i; - data.shader_pass = pass; - data.texture = input->fbo.texture.id; - data.output_size = orig_output_size; - data.orig_pass = orig; - data.frame_count = frame_count; - - render_pass(&data); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (pass->fbo.texture.mipmap) - { - glw->glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, pass->fbo.texture.id); - glw->glGenerateMipmap(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - - - } - - input = pass; - } - - if (shader->has_prev && (ticks-shader->last_prev_update) >= (1000.f/refresh_rate)) - { - shader->last_prev_update = ticks; - - /* shift array */ - memmove(&shader->prev[1], &shader->prev[0], MAX_PREV*sizeof(struct shader_prev)); - memcpy(&shader->prev[0], &shader->prev[MAX_PREV], sizeof(struct shader_prev)); - - struct shader_pass* pass = orig; - struct shader_pass* prev_pass = &shader->prev_scene; - struct shader_prev* prev = &shader->prev[0]; - - memcpy(&prev_pass->state, &pass->state, sizeof(struct shader_state)); - - recreate_fbo(&prev->fbo, prev_pass->state.output_texture_size[0], prev_pass->state.output_texture_size[1]); - - memcpy(&prev_pass->fbo, &prev->fbo, sizeof(struct shader_fbo)); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, prev->fbo.id); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - - glw->glBindVertexArray(prev_pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, prev->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), pass->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - glw->glBindBuffer(GL_ARRAY_BUFFER, prev_pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), pass->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.shader = shader; - data.pass = -10; - data.shader_pass = prev_pass; - data.texture = pass->fbo.texture.id; - data.output_size = orig_output_size; - - render_pass(&data); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - orig = input; - } - - if (active_shader->final_pass.active) - { - struct shader_pass* pass = &active_shader->final_pass; - - memcpy(pass->state.input_size, input->state.output_size, 2*sizeof(GLfloat)); - memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2*sizeof(GLfloat)); - - for (j = 0; j < 2; ++j) - { - if (pass->scale.mode[j] == SCALE_VIEWPORT) - pass->state.output_size[j] = orig_output_size[j]*pass->scale.value[j]; - else if (pass->scale.mode[j] == SCALE_ABSOLUTE) - pass->state.output_size[j] = pass->scale.value[j]; - else - pass->state.output_size[j] = pass->state.input_size[j]*pass->scale.value[j]; - - pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); - } - - glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); - - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - GLfloat minx = 0; - GLfloat miny = 0; - GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; - GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; - - pass->state.tex_coords[0] = minx; - pass->state.tex_coords[1] = miny; - pass->state.tex_coords[2] = minx; - pass->state.tex_coords[3] = maxy; - pass->state.tex_coords[4] = maxx; - pass->state.tex_coords[5] = miny; - pass->state.tex_coords[6] = maxx; - pass->state.tex_coords[7] = maxy; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), input->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -2; - data.shader_pass = pass; - data.texture = input->fbo.texture.id; - data.output_size = orig_output_size; - data.orig_pass = orig; - - render_pass(&data); - } - - if (!take_screenshot) - { - if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) - { - struct shader_pass* pass = &active_shader->fs_color; - GLfloat r = 0; - GLfloat g = 0; - GLfloat b = 0; - GLfloat a = 0x80/(float)0xff; - - GLfloat colors[] = { - r, g, b, a, - r, g, b, a, - r, g, b, a, - r, g, b, a - }; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16*sizeof(GLfloat), colors); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -3; - data.shader_pass = pass; - data.texture = 0; - data.output_size = orig_output_size; - data.orig_pass = orig; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - render_pass(&data); - glDisable(GL_BLEND); - } - if (flash.enabled) - { - struct shader_pass* pass = &active_shader->fs_color; - GLfloat r = (flash.color[0]&0xff)/(float)0xff; - GLfloat g = (flash.color[1]&0xff)/(float)0xff; - GLfloat b = (flash.color[2]&0xff)/(float)0xff; - GLfloat a = (flash.color[3]&0xff)/(float)0xff; - - GLfloat colors[] = { - r, g, b, a, - r, g, b, a, - r, g, b, a, - r, g, b, a - }; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16*sizeof(GLfloat), colors); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -3; - data.shader_pass = pass; - data.texture = 0; - data.output_size = orig_output_size; - data.orig_pass = orig; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - render_pass(&data); - glDisable(GL_BLEND); - } - } - else - { - take_screenshot = 0; - - int width = window_rect.w; - int height = window_rect.h; - - SDL_GetWindowSize(window, &width, &height); - - unsigned char* rgba = (unsigned char*)malloc(width*height*4); - - glFinish(); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); - - int x, y; - unsigned char* rgb = (unsigned char*)malloc(width*height*3); - - for (x = 0; x < width; ++x) - { - for (y = 0; y < height; ++y) - { - rgb[(y*width+x)*3+0] = rgba[((height-y-1)*width+x)*4+0]; - rgb[(y*width+x)*3+1] = rgba[((height-y-1)*width+x)*4+1]; - rgb[(y*width+x)*3+2] = rgba[((height-y-1)*width+x)*4+2]; - } - } - - screenshot_taken(rgb, width, height); - - free(rgb); - free(rgba); - } - - // DEBUG: render FBO -#ifdef SDL2_SHADER_DEBUG -// GLint texture = scene_texture.id; - GLint texture = active_shader->lut_textures[0].texture.id; -// GLint texture = active_shader->scene.fbo.texture; - - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, orig_output_size[0], orig_output_size[1]); - - struct shader_pass* pass = &active_shader->debug; - - render_pass(-999, pass, orig_output_size, texture); -#endif - - glDisable(GL_FRAMEBUFFER_SRGB); - - SDL_GL_SwapWindow(window); - -} - -sdl_renderer_t* gl3_renderer_create() -{ - sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t)); - renderer->init = gl3_init; - renderer->close = gl3_close; - renderer->update = gl3_update; - renderer->present = gl3_present; - renderer->always_update = 1; - return renderer; -} - -void gl3_renderer_close(sdl_renderer_t* renderer) -{ - free(renderer); -} - -static int available = -1; - -int gl3_renderer_available(struct sdl_render_driver* driver) -{ - if (available < 0) - { - available = 0; - SDL_Window* window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); - if (window) - { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); - - SDL_GLContext context = SDL_GL_CreateContext(window); - if (context) - { - int version = -1; - glGetIntegerv(GL_MAJOR_VERSION, &version); - - SDL_GL_DeleteContext(context); - - available = version >= 3; - } - SDL_DestroyWindow(window); - } - - } - return available; -} +#include +#define BITMAP WINDOWS_BITMAP +#include +#if SDL_VERSION_ATLEAST(2, 0, 4) +#include +#endif +#undef BITMAP +#include "wx-sdl2-glw.h" +#include +#include +#include +#include "video.h" +#include "wx-sdl2-video.h" +#include "wx-sdl2-video-renderer.h" +#include "ibm.h" +#include "wx-glslp-parser.h" +#include "wx-utils.h" +#include "config.h" +#include "wx-glsl.h" + +extern char* get_filename(char*); + +extern int take_screenshot; +extern void screenshot_taken(unsigned char* rgb, int width, int height); + +#define SCALE_SOURCE 0 +#define SCALE_VIEWPORT 1 +#define SCALE_ABSOLUTE 2 + +float gl3_shader_refresh_rate = 0; +float gl3_input_scale = 1.0f; +int gl3_input_stretch = FULLSCR_SCALE_FULL; +char gl3_shader_file[MAX_USER_SHADERS][512]; + +static int max_texture_size; + +static SDL_GLContext context = NULL; +static struct shader_texture scene_texture; + +static glsl_t* active_shader; + +static glw_t* glw; + +static GLfloat matrix[] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +}; + + +extern int video_scale_mode; +extern int video_vsync; +extern int video_focus_dim; +extern int video_refresh_rate; + +static int glsl_version[2]; + +const char* vertex_shader_default_tex_src = + "#version 130\n" + "\n" + "in vec4 VertexCoord;\n" + "in vec2 TexCoord;\n" + "\n" + "out vec2 texCoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " texCoord = TexCoord;\n" + "}\n"; + +const char* fragment_shader_default_tex_src = + "#version 130\n" + "\n" + "in vec2 texCoord;\n" + "uniform sampler2D Texture;\n" + "\n" + "out vec4 color;" + "\n" + "void main()\n" + "{\n" + " color = texture(Texture, texCoord);\n" + "}\n"; + +const char* vertex_shader_default_color_src = + "#version 130\n" + "\n" + "in vec4 VertexCoord;\n" + "in vec4 Color;\n" + "\n" + "out vec4 color;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " color = Color;\n" + "}\n"; + +const char* fragment_shader_default_color_src = + "#version 130\n" + "\n" + "in vec4 color;\n" + "\n" + "out vec4 outColor;" + "\n" + "void main()\n" + "{\n" + " outColor = color;\n" + "}\n"; + +static int next_pow2(unsigned int n) +{ + n--; + n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32, + n |= n >> 2; // and then or the results. + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; + + return n; +} + +static int compile_shader(GLenum shader_type, const char* prepend, const char* program, int* dst) +{ + const char* source[3]; + char version[50]; + int ver = 0; + char *version_loc = strstr(program, "#version"); + if (version_loc) + ver = (int)strtol(version_loc + 8, (char**)&program, 10); + else + { + ver = glsl_version[0] * 100 + glsl_version[1] * 10; + if (ver == 300) + ver = 130; + else if (ver == 310) + ver = 140; + else if (ver == 320) + ver = 150; + } + sprintf(version, "#version %d\n", ver); + source[0] = version; + source[1] = prepend ? prepend : ""; + source[2] = program; + + pclog("GLSL version %d\n", ver); + + GLuint shader = glw->glCreateShader(shader_type); + glw->glShaderSource(shader, 3, source, NULL); + glw->glCompileShader(shader); + + GLint status = 0; + glw->glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status) + { + GLint length; + glw->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); + char* log = malloc(length); + glw->glGetShaderInfoLog(shader, length, &length, log); + wx_simple_messagebox("GLSL Error", "Could not compile shader:\n%s", log); + pclog("Could not compile shader: %s\n", log); +// pclog("Shader: %s\n", program); + + free(log); + return 0; + } + + *dst = shader; + + return 1; +} + +static int create_program(struct shader_program* program) +{ + GLint status; + program->id = glw->glCreateProgram(); + glw->glAttachShader(program->id, program->vertex_shader); + glw->glAttachShader(program->id, program->fragment_shader); + + glw->glLinkProgram(program->id); + + glw->glDeleteShader(program->vertex_shader); + glw->glDeleteShader(program->fragment_shader); + + program->vertex_shader = program->fragment_shader = 0; + + glw->glGetProgramiv(program->id, GL_LINK_STATUS, &status); + + if (!status) + { + int maxLength; + int length; + glw->glGetProgramiv(program->id, GL_INFO_LOG_LENGTH, &maxLength); + char* log = malloc(maxLength); + glw->glGetProgramInfoLog(program->id, maxLength, &length, log); + wx_simple_messagebox("GLSL Error", "Program not linked:\n%s", log); + free(log); + return 0; + } + + return 1; +} + +static GLuint get_uniform(GLuint program, const char* name) +{ + return glw->glGetUniformLocation(program, name); +} + +static GLuint get_attrib(GLuint program, const char* name) +{ + return glw->glGetAttribLocation(program, name); +} + +static void find_uniforms(struct glsl_shader* glsl, int num_pass) +{ + int i; + char s[50]; + struct shader_pass* pass = &glsl->passes[num_pass]; + int p = pass->program.id; + glw->glUseProgram(p); + + struct shader_uniforms* u = &pass->uniforms; + + u->mvp_matrix = get_uniform(p, "MVPMatrix"); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->tex_coord = get_attrib(p, "TexCoord"); + u->color = get_attrib(p, "Color"); + + u->frame_count = get_uniform(p, "FrameCount"); + u->frame_direction = get_uniform(p, "FrameDirection"); + + u->texture = get_uniform(p, "Texture"); + u->input_size = get_uniform(p, "InputSize"); + u->texture_size = get_uniform(p, "TextureSize"); + u->output_size = get_uniform(p, "OutputSize"); + + u->orig.texture = get_uniform(p, "OrigTexture"); + u->orig.input_size = get_uniform(p, "OrigInputSize"); + u->orig.texture_size = get_uniform(p, "OrigTextureSize"); + + for (i = 0; i < glsl->num_passes; ++i) + { + sprintf(s, "Pass%dTexture", (i+1)); + u->pass[i].texture = get_uniform(p, s); + sprintf(s, "Pass%dInputSize", (i+1)); + u->pass[i].input_size = get_uniform(p, s); + sprintf(s, "Pass%dTextureSize", (i+1)); + u->pass[i].texture_size = get_uniform(p, s); + + sprintf(s, "PassPrev%dTexture", num_pass-i); + u->prev_pass[i].texture = get_uniform(p, s); + sprintf(s, "PassPrev%dInputSize", num_pass-i); + u->prev_pass[i].input_size = get_uniform(p, s); + sprintf(s, "PassPrev%dTextureSize", num_pass-i); + u->prev_pass[i].texture_size = get_uniform(p, s); + } + + u->prev[0].texture = get_uniform(p, "PrevTexture"); + u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); + for (i = 1; i < MAX_PREV; ++i) + { + sprintf(s, "Prev%dTexture", i); + u->prev[i].texture = get_uniform(p, s); + sprintf(s, "Prev%dTexCoord", i); + u->prev[i].tex_coord = get_attrib(p, s); + } + for (i = 0; i < MAX_PREV; ++i) + if (u->prev[i].texture >= 0) glsl->has_prev = 1; + + for (i = 0; i < glsl->num_lut_textures; ++i) + u->lut_textures[i] = get_uniform(p, glsl->lut_textures[i].name); + + for (i = 0; i < glsl->num_parameters; ++i) + u->parameters[i] = get_uniform(p, glsl->parameters[i].id); + + glw->glUseProgram(0); +} + +static void set_scale_mode(char* scale, int* dst) +{ + if (!strcmp(scale, "viewport")) + *dst = SCALE_VIEWPORT; + else if (!strcmp(scale, "absolute")) + *dst = SCALE_ABSOLUTE; + else + *dst = SCALE_SOURCE; +} + +static void setup_scale(struct shader* shader, struct shader_pass* pass) +{ + set_scale_mode(shader->scale_type_x, &pass->scale.mode[0]); + set_scale_mode(shader->scale_type_y, &pass->scale.mode[1]); + pass->scale.value[0] = shader->scale_x; + pass->scale.value[1] = shader->scale_y; +} + +static void create_texture(struct shader_texture* tex) +{ + if (tex->width > max_texture_size) + tex->width = max_texture_size; + if (tex->height > max_texture_size) + tex->height = max_texture_size; + pclog("Create texture with size %dx%d\n", tex->width, tex->height); + glGenTextures(1, (GLuint *)&tex->id); + glBindTexture(GL_TEXTURE_2D, tex->id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter); + glTexImage2D(GL_TEXTURE_2D, 0, tex->internal_format, tex->width, tex->height, 0, tex->format, tex->type, tex->data); + if (tex->mipmap) + glw->glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} + +static void delete_texture(struct shader_texture* tex) +{ + if (tex->id > 0) + glDeleteTextures(1, (GLuint *)&tex->id); + tex->id = 0; +} + +static void delete_fbo(struct shader_fbo* fbo) +{ + if (fbo->id >= 0) + { + glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); + delete_texture(&fbo->texture); + } +} + +static void delete_program(struct shader_program* program) +{ + if (program->vertex_shader) glw->glDeleteShader(program->vertex_shader); + if (program->fragment_shader) glw->glDeleteShader(program->fragment_shader); + glw->glDeleteProgram(program->id); +} + +static void delete_vbo(struct shader_vbo* vbo) +{ + if (vbo->color >= 0) glw->glDeleteBuffers(1, (GLuint *)&vbo->color); + glw->glDeleteBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glDeleteBuffers(1, (GLuint *)&vbo->tex_coord); +} + +static void delete_pass(struct shader_pass* pass) +{ + delete_fbo(&pass->fbo); + delete_vbo(&pass->vbo); + delete_program(&pass->program); + glw->glDeleteVertexArrays(1, (GLuint *)&pass->vertex_array); +} + +static void delete_prev(struct shader_prev* prev) +{ + delete_fbo(&prev->fbo); + delete_vbo(&prev->vbo); +} + +static void delete_shader(struct glsl_shader* glsl) +{ + int i; + for (i = 0; i < glsl->num_passes; ++i) + delete_pass(&glsl->passes[i]); + if (glsl->has_prev) + { + delete_pass(&glsl->prev_scene); + for (i = 0; i < MAX_PREV; ++i) + delete_prev(&glsl->prev[i]); + } + for (i = 0; i < glsl->num_lut_textures; ++i) + delete_texture(&glsl->lut_textures[i].texture); +} + +static void delete_glsl(glsl_t* glsl) +{ + int i; + for (i = 0; i < glsl->num_shaders; ++i) + delete_shader(&glsl->shaders[i]); + delete_pass(&glsl->scene); + delete_pass(&glsl->fs_color); + delete_pass(&glsl->final_pass); +#ifdef SDL2_SHADER_DEBUG + delete_pass(&glsl->debug); +#endif +} + +static void create_fbo(struct shader_fbo* fbo) +{ + create_texture(&fbo->texture); + + glw->glGenFramebuffers(1, (GLuint *)&fbo->id); + glw->glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); + glw->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); + + if (glw->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + pclog("Could not create framebuffer!\n"); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +static void setup_fbo(struct shader* shader, struct shader_fbo* fbo) +{ + fbo->texture.internal_format = GL_RGBA8; + fbo->texture.format = GL_RGBA; + fbo->texture.min_filter = fbo->texture.mag_filter = shader->filter_linear ? GL_LINEAR : GL_NEAREST; + fbo->texture.width = 1024; + fbo->texture.height = 1024; + fbo->texture.type = GL_UNSIGNED_BYTE; + if (!strcmp(shader->wrap_mode, "repeat")) + fbo->texture.wrap_mode = GL_REPEAT; + else if (!strcmp(shader->wrap_mode, "mirrored_repeat")) + fbo->texture.wrap_mode = GL_MIRRORED_REPEAT; + else if (!strcmp(shader->wrap_mode, "clamp_to_edge")) + fbo->texture.wrap_mode = GL_CLAMP_TO_EDGE; + else + fbo->texture.wrap_mode = GL_CLAMP_TO_BORDER; + fbo->srgb = 0; + if (shader->srgb_framebuffer) + { + fbo->texture.internal_format = GL_SRGB8_ALPHA8; + fbo->srgb = 1; + } + else if (shader->float_framebuffer) + { + fbo->texture.internal_format = GL_RGBA32F; + fbo->texture.type = GL_FLOAT; + } + + if (fbo->texture.mipmap) + fbo->texture.min_filter = shader->filter_linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; + + create_fbo(fbo); +} + +static void recreate_fbo(struct shader_fbo* fbo, int width, int height) +{ + if (width != fbo->texture.width || height != fbo->texture.height) + { + glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); + glDeleteTextures(1, (GLuint *)&fbo->texture.id); + fbo->texture.width = width; + fbo->texture.height = height; + create_fbo(fbo); + } +} + +static int create_default_shader_tex(struct shader_pass* pass) +{ + if ( + !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_tex_src, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_tex_src, &pass->program.fragment_shader) || + !create_program(&pass->program)) + return 0; + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); + + struct shader_uniforms* u = &pass->uniforms; + int p = pass->program.id; + memset(u, -1, sizeof(struct shader_uniforms)); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->tex_coord = get_attrib(p, "TexCoord"); + u->texture = get_uniform(p, "Texture"); + pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; + pass->scale.value[0] = pass->scale.value[1] = 1.0f; + pass->fbo.id = -1; + pass->active = 1; + return 1; +} + +static int create_default_shader_color(struct shader_pass* pass) +{ + if ( + !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_color_src, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_color_src, &pass->program.fragment_shader) || + !create_program(&pass->program)) + return 0; + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); + + struct shader_uniforms* u = &pass->uniforms; + int p = pass->program.id; + memset(u, -1, sizeof(struct shader_uniforms)); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->color = get_attrib(p, "Color"); + pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; + pass->scale.value[0] = pass->scale.value[1] = 1.0f; + pass->fbo.id = -1; + pass->active = 1; + return 1; +} + +/* create the default scene shader */ +static void create_scene_shader() +{ + struct shader scene_shader_conf; + memset(&scene_shader_conf, 0, sizeof(struct shader)); + create_default_shader_tex(&active_shader->scene); + scene_shader_conf.filter_linear = video_scale_mode; + if (active_shader->num_shaders > 0 && active_shader->shaders[0].input_filter_linear >= 0) + scene_shader_conf.filter_linear = active_shader->shaders[0].input_filter_linear; + setup_fbo(&scene_shader_conf, &active_shader->scene.fbo); + + memset(&scene_shader_conf, 0, sizeof(struct shader)); + create_default_shader_color(&active_shader->fs_color); + setup_fbo(&scene_shader_conf, &active_shader->fs_color.fbo); +} + +static int load_texture(const char* f, struct shader_texture* tex) +{ + void* img = wx_image_load(f); + if (!img) + return 0; + int width, height; + wx_image_get_size(img, &width, &height); + + if (width != next_pow2(width) || height != next_pow2(height)) + wx_image_rescale(img, next_pow2(width), next_pow2(height)); + + wx_image_get_size(img, &width, &height); + + GLubyte* rgb = wx_image_get_data(img); + GLubyte* alpha = wx_image_get_alpha(img); + + int bpp = alpha ? 4 : 3; + + GLubyte* data = malloc(width*height*bpp); + + int x, y, Y; + for (y = 0; y < height; ++y) + { + Y = height-y-1; + for (x = 0; x < width; x++) + { + data[(y*width+x)*bpp+0] = rgb[(Y*width+x)*3+0]; + data[(y*width+x)*bpp+1] = rgb[(Y*width+x)*3+1]; + data[(y*width+x)*bpp+2] = rgb[(Y*width+x)*3+2]; + + if (alpha) + data[(y*width+x)*bpp+3] = alpha[Y*width+x]; + } + } + wx_image_free(img); + + tex->width = width; + tex->height = height; + tex->internal_format = alpha ? GL_RGBA8 : GL_RGB8; + tex->format = alpha ? GL_RGBA : GL_RGB; + tex->type = GL_UNSIGNED_BYTE; + tex->data = data; + return 1; +} + +static glsl_t* load_glslp(glsl_t* glsl, int num_shader, const char* f) +{ + int i, j; + glslp_t* p = glslp_parse(f); + + if (p) + { + char path[512]; + char file[512]; + int failed = 0; + strcpy(path, f); + char* filename = get_filename(path); + + struct glsl_shader* gshader = &glsl->shaders[num_shader]; + + strcpy(gshader->name, p->name); + *filename = 0; + + gshader->num_lut_textures = p->num_textures; + + for (i = 0; i < p->num_textures; ++i) + { + struct texture* texture = &p->textures[i]; + + sprintf(file, "%s%s", path, texture->path); + + struct shader_lut_texture* tex = &gshader->lut_textures[i]; + strcpy(tex->name, texture->name); + + pclog("Load texture %s...\n", file); + + if (!load_texture(file, &tex->texture)) + { + wx_simple_messagebox("GLSL Error", "Could not load texture: %s", file); + pclog("Could not load texture %s!\n", file); + failed = 1; + break; + } + + if (!strcmp(texture->wrap_mode, "repeat")) + tex->texture.wrap_mode = GL_REPEAT; + else if (!strcmp(texture->wrap_mode, "mirrored_repeat")) + tex->texture.wrap_mode = GL_MIRRORED_REPEAT; + else if (!strcmp(texture->wrap_mode, "clamp_to_edge")) + tex->texture.wrap_mode = GL_CLAMP_TO_EDGE; + else + tex->texture.wrap_mode = GL_CLAMP_TO_BORDER; + + tex->texture.mipmap = texture->mipmap; + + tex->texture.min_filter = tex->texture.mag_filter = texture->linear ? GL_LINEAR : GL_NEAREST; + if (tex->texture.mipmap) + tex->texture.min_filter = texture->linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; + + create_texture(&tex->texture); + free(tex->texture.data); + tex->texture.data = 0; + } + + if (!failed) + { + gshader->input_filter_linear = p->input_filter_linear; + + gshader->num_parameters = p->num_parameters; + for (j = 0; j < gshader->num_parameters; ++j) + memcpy(&gshader->parameters[j], &p->parameters[j], sizeof(struct shader_parameter)); + + gshader->num_passes = p->num_shaders; + + for (i = 0; i < p->num_shaders; ++i) + { + struct shader* shader = &p->shaders[i]; + struct shader_pass* pass = &gshader->passes[i]; + + strcpy(pass->alias, shader->alias); + if (!strlen(pass->alias)) + sprintf(pass->alias, "Pass %u", (i+1)); + + pclog("Creating pass %u (%s)\n", (i+1), pass->alias); + pclog("Loading shader %s...\n", shader->shader_fn); + if (!shader->shader_program) + { + wx_simple_messagebox("GLSL Error", "Could not load shader: %s", shader->shader_fn); + pclog("Could not load shader %s\n", shader->shader_fn); + failed = 1; + break; + } + else + pclog("Shader %s loaded\n", shader->shader_fn); + failed = + !compile_shader(GL_VERTEX_SHADER, "#define VERTEX\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.fragment_shader); + if (failed) + break; + + if (!create_program(&pass->program)) + { + failed = 1; + break; + } + pass->frame_count_mod = shader->frame_count_mod; + pass->fbo.mipmap_input = shader->mipmap_input; + + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); + find_uniforms(gshader, i); + setup_scale(shader, pass); + if (i == p->num_shaders-1) /* last pass may or may not be an fbo depending on scale */ + { + if (num_shader == glsl->num_shaders-1) + { + pass->fbo.id = -1; + + for (j = 0; j < 2; ++j) + { + if (pass->scale.mode[j] != SCALE_SOURCE || pass->scale.value[j] != 1) + { + setup_fbo(shader, &pass->fbo); + break; + } + } + } + else + { + /* check if next shaders' first pass wants the input mipmapped (will this ever happen?) */ + pass->fbo.texture.mipmap = glsl->shaders[num_shader+1].num_passes > 0 && glsl->shaders[num_shader+1].passes[0].fbo.mipmap_input; + /* check if next shader wants the output of this pass to be filtered */ + if (glsl->shaders[num_shader+1].num_passes > 0 && glsl->shaders[num_shader+1].input_filter_linear >= 0) + shader->filter_linear = glsl->shaders[num_shader+1].input_filter_linear; + setup_fbo(shader, &pass->fbo); + } + } + else + { + /* check if next pass wants the input mipmapped, if so we need to generate mipmaps of this pass */ + pass->fbo.texture.mipmap = (i+1) < p->num_shaders && p->shaders[i+1].mipmap_input; + setup_fbo(shader, &pass->fbo); + } + if (pass->fbo.srgb) glsl->srgb = 1; + pass->active = 1; + } + if (!failed) + { + if (gshader->has_prev) + { + struct shader scene_shader_conf; + memset(&scene_shader_conf, 0, sizeof(struct shader)); + for (i = 0; i < MAX_PREV; ++i) + { + setup_fbo(&scene_shader_conf, &gshader->prev[i].fbo); + } + + } + } + } + + glslp_free(p); + + return glsl; + } + return 0; +} + +static glsl_t* load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) +{ + int i; + glsl_t* glsl; + + glsl = malloc(sizeof(glsl_t)); + memset(glsl, 0, sizeof(glsl_t)); + + glsl->num_shaders = num; + int failed = 0; + for (i = num-1; i >= 0; --i) + { + const char* f = shaders[i]; + if (f && strlen(f)) + { + if (!load_glslp(glsl, i, f)) + { + failed = 1; + break; + } + } + + } + if (failed) + { + delete_glsl(glsl); + memset(glsl, 0, sizeof(glsl_t)); + } + return glsl; +} + +static void read_shader_config() +{ + char s[512]; + int i, j; + for (i = 0; i < active_shader->num_shaders; ++i) + { + struct glsl_shader* shader = &active_shader->shaders[i]; + char* name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); +// shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); + for (j = 0; j < shader->num_parameters; ++j) + { + struct shader_parameter* param = &shader->parameters[j]; + param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); + } + } +} + +int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITMAP* screen) +{ + int i, j; + + strcpy(current_render_driver_name, requested_render_driver.name); + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + context = SDL_GL_CreateContext(window); + + if (!context) + { + pclog("Could not create GL context.\n"); + return FALSE; + } + + SDL_GL_SetSwapInterval(video_vsync ? 1 : 0); + + pclog("OpenGL information: [%s] %s (%s)\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); + glsl_version[0] = glsl_version[1] = -1; + glGetIntegerv(GL_MAJOR_VERSION, &glsl_version[0]); + glGetIntegerv(GL_MINOR_VERSION, &glsl_version[1]); + if (glsl_version[0] < 3) + { + pclog("OpenGL 3.0 is not available."); + return SDL_FALSE; + } + pclog("Using OpenGL %s\n", glGetString(GL_VERSION)); + pclog("Using Shading Language %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + pclog("Max texture size: %dx%d\n", max_texture_size, max_texture_size); + + //SDL_GL_MakeCurrent(window, context); + + glw = glw_init(); + + glEnable(GL_TEXTURE_2D); + + scene_texture.data = screen->dat; + scene_texture.width = screen->w; + scene_texture.height = screen->h; + scene_texture.internal_format = GL_RGBA8; + scene_texture.format = GL_RGBA; + scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; + scene_texture.wrap_mode = GL_CLAMP_TO_BORDER; + scene_texture.min_filter = scene_texture.mag_filter = video_scale_mode ? GL_LINEAR : GL_NEAREST; + scene_texture.mipmap = 0; + + create_texture(&scene_texture); + + /* load shader */ +// const char* shaders[1]; +// shaders[0] = gl3_shader_file; +// +// active_shader = load_shaders(1, shaders); + +// const char* shaders[3]; +// shaders[0] = "/home/phantasy/git/glsl-shaders/ntsc/ntsc-320px.glslp"; +// shaders[1] = "/home/phantasy/git/glsl-shaders/motionblur/motionblur-simple.glslp"; +// shaders[2] = "/home/phantasy/git/glsl-shaders/crt/crt-lottes-multipass.glslp"; +// +// active_shader = load_shaders(3, shaders); + int num_shaders = 0; + for (i = 0; i < MAX_USER_SHADERS; ++i) + { + if (strlen(gl3_shader_file[i])) + ++num_shaders; + else + break; + } + active_shader = load_shaders(num_shaders, gl3_shader_file); + + create_scene_shader(); + + /* read config */ + read_shader_config(); + + /* buffers */ + + GLfloat vertex[] = { + -1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f + }; + + GLfloat inv_vertex[] = { + -1.0f, 1.0f, + -1.0f, -1.0f, + 1.0f, 1.0f, + 1.0f, -1.0f + }; + + GLfloat tex_coords[] = { + 0.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 0.0f, + 1.0f, 1.0f + }; + + + GLfloat colors[] = { + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + + + /* set the scene shader buffers */ + { + glw->glBindVertexArray(active_shader->scene.vertex_array); + + struct shader_vbo* vbo = &active_shader->scene.vbo; + + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(inv_vertex), inv_vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(active_shader->scene.uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(active_shader->scene.uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + } + + /* set buffers for all passes */ + for (j = 0; j < active_shader->num_shaders; ++j) + { + struct glsl_shader* shader = &active_shader->shaders[j]; + for (i = 0; i < shader->num_passes; ++i) + { + struct shader_uniforms* u = &shader->passes[i].uniforms; + + glw->glBindVertexArray(shader->passes[i].vertex_array); + + struct shader_vbo* vbo = &shader->passes[i].vbo; + + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + + glw->glVertexAttribPointer(u->vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(u->tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + + if (u->color) + { + glw->glGenBuffers(1, (GLuint *)&vbo->color); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); + glw->glVertexAttribPointer(u->color, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (GLvoid*)0); + } + } + } + + for (i = 0; i < active_shader->num_shaders; ++i) + { + struct glsl_shader* shader = &active_shader->shaders[i]; + if (shader->has_prev) + { + struct shader_pass* prev_pass = &shader->prev_scene; + create_default_shader_tex(prev_pass); + + struct shader_vbo* vbo = &prev_pass->vbo; + + glw->glBindVertexArray(prev_pass->vertex_array); + + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(prev_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(prev_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + + for (j = 0; j < MAX_PREV; ++j) + { + struct shader_prev* prev = &shader->prev[j]; + struct shader_vbo* prev_vbo = &prev->vbo; + + glw->glGenBuffers(1, (GLuint *)&prev_vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + + glw->glGenBuffers(1, (GLuint *)&prev_vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + } + } + } + + /* create final pass */ + if (active_shader->num_shaders == 0 || active_shader->shaders[active_shader->num_shaders-1].passes[active_shader->shaders[active_shader->num_shaders-1].num_passes-1].fbo.id >= 0) + { + struct shader_pass* final_pass = &active_shader->final_pass; + create_default_shader_tex(final_pass); + + glw->glBindVertexArray(final_pass->vertex_array); + + struct shader_vbo* vbo = &final_pass->vbo; + + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(final_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(final_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + } + + { + struct shader_pass* color_pass = &active_shader->fs_color; + create_default_shader_color(color_pass); + + glw->glBindVertexArray(color_pass->vertex_array); + + struct shader_vbo* vbo = &color_pass->vbo; + + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(color_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glw->glGenBuffers(1, (GLuint *)&vbo->color); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(color_pass->uniforms.color, 4, GL_FLOAT, GL_TRUE, 4*sizeof(GLfloat), (GLvoid*)0); + + } +#ifdef SDL2_SHADER_DEBUG + struct shader_pass* debug_pass = &active_shader->debug; + create_default_shader(debug_pass); + + glBindVertexArray(debug_pass->vertex_array); + + struct shader_vbo* vbo = &debug_pass->vbo; + + glGenBuffers(1, &vbo->vertex_coord); + glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glVertexAttribPointer(debug_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + + glGenBuffers(1, &vbo->tex_coord); + glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glVertexAttribPointer(debug_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); +#endif + + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + glw->glBindVertexArray(0); + + return SDL_TRUE; +} + +void gl3_close() +{ + if (context) + { + delete_texture(&scene_texture); + + if (active_shader) + { + delete_glsl(active_shader); + free(active_shader); + } + active_shader = NULL; + + SDL_GL_DeleteContext(context); + context = NULL; + } + glw_free(glw); +} + +void gl3_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen) +{ + if (!context) + return; + glBindTexture(GL_TEXTURE_2D, scene_texture.id); + glPixelStorei(GL_UNPACK_ROW_LENGTH, screen->w); + glTexSubImage2D(GL_TEXTURE_2D, 0, updated_rect.x, updated_rect.y, updated_rect.w, updated_rect.h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glBindTexture(GL_TEXTURE_2D, 0); +} + +struct render_data { + int pass; + struct glsl_shader* shader; + struct shader_pass* shader_pass; + GLfloat* output_size; + struct shader_pass* orig_pass; + GLint texture; + int frame_count; +}; + +static void render_pass(struct render_data* data) +{ + int i; + GLuint texture_unit = 0; + +// pclog("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], pass->state.input_size[1], pass->state.input_texture_size[0], pass->state.input_texture_size[1], pass->state.output_size[0], pass->state.output_size[1], pass->state.output_texture_size[0], pass->state.output_texture_size[1], output_size[0], output_size[1]); + + glw->glBindVertexArray(data->shader_pass->vertex_array); + + GLint p = data->shader_pass->program.id; + struct shader_uniforms* u = &data->shader_pass->uniforms; + + glw->glUseProgram(p); + + if (data->texture) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->texture); + glw->glUniform1i(u->texture, texture_unit); + texture_unit++; + } + + if (u->color >= 0) glw->glEnableVertexAttribArray(u->color); + + if (u->mvp_matrix >= 0) glw->glUniformMatrix4fv(u->mvp_matrix, 1, 0, matrix); + if (u->frame_direction >= 0) glw->glUniform1i(u->frame_direction, 1); + + int framecnt = data->frame_count; + if (data->shader_pass->frame_count_mod > 0) + framecnt = framecnt%data->shader_pass->frame_count_mod; + if (u->frame_count >= 0) glw->glUniform1i(u->frame_count, framecnt); + + if (u->input_size >= 0) glw->glUniform2fv(u->input_size, 1, data->shader_pass->state.input_size); + if (u->texture_size >= 0) glw->glUniform2fv(u->texture_size, 1, data->shader_pass->state.input_texture_size); + if (u->output_size >= 0) glw->glUniform2fv(u->output_size, 1, data->output_size); + + if (data->shader) + { + /* parameters */ + for (i = 0; i < data->shader->num_parameters; ++i) + if (u->parameters[i] >= 0) glw->glUniform1f(u->parameters[i], data->shader->parameters[i].value); + + if (data->pass > 0) + { + struct shader_pass* passes = data->shader->passes; + struct shader_pass* orig = data->orig_pass; + if (u->orig.texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, orig->fbo.texture.id); + glw->glUniform1i(u->orig.texture, texture_unit); + texture_unit++; + } + if (u->orig.input_size >= 0) glw->glUniform2fv(u->orig.input_size, 1, orig->state.input_size); + if (u->orig.texture_size >= 0) glw->glUniform2fv(u->orig.texture_size, 1, orig->state.input_texture_size); + + for (i = 0; i < data->pass; ++i) + { + if (u->pass[i].texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); + glw->glUniform1i(u->pass[i].texture, texture_unit); + texture_unit++; + } + if (u->pass[i].texture_size >= 0) glw->glUniform2fv(u->pass[i].texture_size, 1, passes[i].state.input_texture_size); + if (u->pass[i].input_size >= 0) glw->glUniform2fv(u->pass[i].input_size, 1, passes[i].state.input_size); + + if (u->prev_pass[i].texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); + glw->glUniform1i(u->prev_pass[i].texture, texture_unit); + texture_unit++; + } + if (u->prev_pass[i].texture_size >= 0) glw->glUniform2fv(u->prev_pass[i].texture_size, 1, passes[i].state.input_texture_size); + if (u->prev_pass[i].input_size >= 0) glw->glUniform2fv(u->prev_pass[i].input_size, 1, passes[i].state.input_size); + + } + } + + if (data->shader->has_prev) + { + /* loop through each previous frame */ + for (i = 0; i < MAX_PREV; ++i) + { + if (u->prev[i].texture >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->shader->prev[i].fbo.texture.id); + glw->glUniform1i(u->prev[i].texture, texture_unit); + texture_unit++; + } + if (u->prev[i].tex_coord >= 0) + { + glw->glBindBuffer(GL_ARRAY_BUFFER, data->shader->prev[i].vbo.tex_coord); + glw->glVertexAttribPointer(u->prev[i].tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + glw->glEnableVertexAttribArray(u->prev[i].tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + } + } + } + + for (i = 0; i < data->shader->num_lut_textures; ++i) + { + if (u->lut_textures[i] >= 0) + { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->shader->lut_textures[i].texture.id); + glw->glUniform1i(u->lut_textures[i], texture_unit); + texture_unit++; + } + + } + } + + glw->glEnableVertexAttribArray(u->vertex_coord); + glw->glEnableVertexAttribArray(u->tex_coord); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glw->glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.vertex_coord); + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.tex_coord); + if (data->shader_pass->uniforms.color >= 0) glw->glDisableVertexAttribArray(data->shader_pass->uniforms.color); + + if (data->shader && data->shader->has_prev) + { + for (i = 0; i < MAX_PREV; ++i) + { + if (u->prev[i].tex_coord >= 0) + glw->glDisableVertexAttribArray(u->prev[i].tex_coord); + + } + } + + glw->glBindVertexArray(0); + + + glw->glUseProgram(0); +} + +void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, BITMAP* screen) +{ + if (!context) + return; + + int s, i, j; + + Uint32 ticks = SDL_GetTicks(); + + GLfloat orig_output_size[] = { + window_rect.w, window_rect.h + }; + + if (active_shader->srgb) glEnable(GL_FRAMEBUFFER_SRGB); + + struct render_data data; + + /* render scene to texture */ + { + struct shader_pass* pass = &active_shader->scene; + + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = video_rect.w*gl3_input_scale; + rect.h = video_rect.h*gl3_input_scale; + sdl_scale(gl3_input_stretch, rect, &rect, video_rect.w, video_rect.h); + + pass->state.input_size[0] = pass->state.output_size[0] = rect.w; + pass->state.input_size[1] = pass->state.output_size[1] = rect.h; + + pass->state.input_texture_size[0] = pass->state.output_texture_size[0] = next_pow2(pass->state.output_size[0]); + pass->state.input_texture_size[1] = pass->state.output_texture_size[1] = next_pow2(pass->state.output_size[1]); + + recreate_fbo(&active_shader->scene.fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, active_shader->scene.fbo.id); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + // create input tex coords + minx = video_rect.x/(float)screen->w; + miny = video_rect.y/(float)screen->h; + maxx = (video_rect.x+video_rect.w)/(float)screen->w; + maxy = (video_rect.y+video_rect.h)/(float)screen->h; + + GLfloat tex_coords[] = { + minx, miny, + minx, maxy, + maxx, miny, + maxx, maxy + }; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -1; + data.shader_pass = &active_shader->scene; + data.texture = scene_texture.id; + data.output_size = orig_output_size; + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + struct shader_pass* orig = &active_shader->scene; + struct shader_pass* input = &active_shader->scene; + + for (s = 0; s < active_shader->num_shaders; ++s) + { + struct glsl_shader* shader = &active_shader->shaders[s]; + +// float refresh_rate = shader->shader_refresh_rate; +// if (refresh_rate < 0) +// refresh_rate = gl3_shader_refresh_rate; + float refresh_rate = gl3_shader_refresh_rate; + if (refresh_rate == 0) + refresh_rate = video_refresh_rate; + int frame_count = ticks/(1000.0f/refresh_rate); + + /* loop through each pass */ + for (i = 0; i < shader->num_passes; ++i) + { + struct shader_pass* pass = &shader->passes[i]; + + memcpy(pass->state.input_size, input->state.output_size, 2*sizeof(GLfloat)); + memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2*sizeof(GLfloat)); + + for (j = 0; j < 2; ++j) + { + if (pass->scale.mode[j] == SCALE_VIEWPORT) + pass->state.output_size[j] = orig_output_size[j]*pass->scale.value[j]; + else if (pass->scale.mode[j] == SCALE_ABSOLUTE) + pass->state.output_size[j] = pass->scale.value[j]; + else + pass->state.output_size[j] = pass->state.input_size[j]*pass->scale.value[j]; + + pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); + } + + if (pass->fbo.id >= 0) + { + recreate_fbo(&pass->fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, pass->fbo.id); + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + } + else + glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), input->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.shader = shader; + data.pass = i; + data.shader_pass = pass; + data.texture = input->fbo.texture.id; + data.output_size = orig_output_size; + data.orig_pass = orig; + data.frame_count = frame_count; + + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + + if (pass->fbo.texture.mipmap) + { + glw->glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, pass->fbo.texture.id); + glw->glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + + + } + + input = pass; + } + + if (shader->has_prev && (ticks-shader->last_prev_update) >= (1000.f/refresh_rate)) + { + shader->last_prev_update = ticks; + + /* shift array */ + memmove(&shader->prev[1], &shader->prev[0], MAX_PREV*sizeof(struct shader_prev)); + memcpy(&shader->prev[0], &shader->prev[MAX_PREV], sizeof(struct shader_prev)); + + struct shader_pass* pass = orig; + struct shader_pass* prev_pass = &shader->prev_scene; + struct shader_prev* prev = &shader->prev[0]; + + memcpy(&prev_pass->state, &pass->state, sizeof(struct shader_state)); + + recreate_fbo(&prev->fbo, prev_pass->state.output_texture_size[0], prev_pass->state.output_texture_size[1]); + + memcpy(&prev_pass->fbo, &prev->fbo, sizeof(struct shader_fbo)); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, prev->fbo.id); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + + glw->glBindVertexArray(prev_pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, prev->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), pass->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), pass->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.shader = shader; + data.pass = -10; + data.shader_pass = prev_pass; + data.texture = pass->fbo.texture.id; + data.output_size = orig_output_size; + + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + orig = input; + } + + if (active_shader->final_pass.active) + { + struct shader_pass* pass = &active_shader->final_pass; + + memcpy(pass->state.input_size, input->state.output_size, 2*sizeof(GLfloat)); + memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2*sizeof(GLfloat)); + + for (j = 0; j < 2; ++j) + { + if (pass->scale.mode[j] == SCALE_VIEWPORT) + pass->state.output_size[j] = orig_output_size[j]*pass->scale.value[j]; + else if (pass->scale.mode[j] == SCALE_ABSOLUTE) + pass->state.output_size[j] = pass->scale.value[j]; + else + pass->state.output_size[j] = pass->state.input_size[j]*pass->scale.value[j]; + + pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); + } + + glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0]/(GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1]/(GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8*sizeof(GLfloat), input->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -2; + data.shader_pass = pass; + data.texture = input->fbo.texture.id; + data.output_size = orig_output_size; + data.orig_pass = orig; + + render_pass(&data); + } + + if (!take_screenshot) + { + if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) + { + struct shader_pass* pass = &active_shader->fs_color; + GLfloat r = 0; + GLfloat g = 0; + GLfloat b = 0; + GLfloat a = 0x80/(float)0xff; + + GLfloat colors[] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a + }; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16*sizeof(GLfloat), colors); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -3; + data.shader_pass = pass; + data.texture = 0; + data.output_size = orig_output_size; + data.orig_pass = orig; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + render_pass(&data); + glDisable(GL_BLEND); + } + if (flash.enabled) + { + struct shader_pass* pass = &active_shader->fs_color; + GLfloat r = (flash.color[0]&0xff)/(float)0xff; + GLfloat g = (flash.color[1]&0xff)/(float)0xff; + GLfloat b = (flash.color[2]&0xff)/(float)0xff; + GLfloat a = (flash.color[3]&0xff)/(float)0xff; + + GLfloat colors[] = { + r, g, b, a, + r, g, b, a, + r, g, b, a, + r, g, b, a + }; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16*sizeof(GLfloat), colors); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -3; + data.shader_pass = pass; + data.texture = 0; + data.output_size = orig_output_size; + data.orig_pass = orig; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + render_pass(&data); + glDisable(GL_BLEND); + } + } + else + { + take_screenshot = 0; + + int width = window_rect.w; + int height = window_rect.h; + + SDL_GetWindowSize(window, &width, &height); + + unsigned char* rgba = (unsigned char*)malloc(width*height*4); + + glFinish(); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + + int x, y; + unsigned char* rgb = (unsigned char*)malloc(width*height*3); + + for (x = 0; x < width; ++x) + { + for (y = 0; y < height; ++y) + { + rgb[(y*width+x)*3+0] = rgba[((height-y-1)*width+x)*4+0]; + rgb[(y*width+x)*3+1] = rgba[((height-y-1)*width+x)*4+1]; + rgb[(y*width+x)*3+2] = rgba[((height-y-1)*width+x)*4+2]; + } + } + + screenshot_taken(rgb, width, height); + + free(rgb); + free(rgba); + } + + // DEBUG: render FBO +#ifdef SDL2_SHADER_DEBUG +// GLint texture = scene_texture.id; + GLint texture = active_shader->lut_textures[0].texture.id; +// GLint texture = active_shader->scene.fbo.texture; + + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, orig_output_size[0], orig_output_size[1]); + + struct shader_pass* pass = &active_shader->debug; + + render_pass(-999, pass, orig_output_size, texture); +#endif + + glDisable(GL_FRAMEBUFFER_SRGB); + + SDL_GL_SwapWindow(window); + +} + +sdl_renderer_t* gl3_renderer_create() +{ + sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t)); + renderer->init = gl3_init; + renderer->close = gl3_close; + renderer->update = gl3_update; + renderer->present = gl3_present; + renderer->always_update = 1; + return renderer; +} + +void gl3_renderer_close(sdl_renderer_t* renderer) +{ + free(renderer); +} + +static int available = -1; + +int gl3_renderer_available(struct sdl_render_driver* driver) +{ + if (available < 0) + { + available = 0; + SDL_Window* window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + if (window) + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + SDL_GLContext context = SDL_GL_CreateContext(window); + if (context) + { + int version = -1; + glGetIntegerv(GL_MAJOR_VERSION, &version); + + SDL_GL_DeleteContext(context); + + available = version >= 3; + } + SDL_DestroyWindow(window); + } + + } + return available; +} From bb64507b7b178541c0e3f9340adb7f0e821b35c8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 16 Aug 2017 19:38:24 +0100 Subject: [PATCH 0129/1050] Fix strncat() use in voodoo_add_status_info(). --- src/vid_voodoo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 812ba0f..187b14c 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -7390,19 +7390,19 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) { sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); - strncat(temps, temps2, 512); + strncat(temps, temps2, sizeof(temps)-1); } if (voodoo_set->nr_cards == 2) { sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); - strncat(temps, temps2, 512); + strncat(temps, temps2, sizeof(temps)-1); if (voodoo_slave->render_threads == 2) { sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); - strncat(temps, temps2, 512); + strncat(temps, temps2, sizeof(temps)-1); } } strncat(s, temps, max_len); From b0215f309a7c33385f8aa5625e8c4264578a86ab Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 16 Aug 2017 20:09:00 +0100 Subject: [PATCH 0130/1050] Voodoo output now works when only the secondary card has output enabled. --- src/vid_voodoo.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 187b14c..311907d 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -6216,7 +6216,10 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) if (voodoo->initEnable & 0x01) { voodoo->fbiInit0 = val; - svga_set_override(voodoo->svga, val & 1); + if (voodoo->set->nr_cards == 2) + svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1); + else + svga_set_override(voodoo->svga, val & 1); if (val & FBIINIT0_GRAPHICS_RESET) { /*Reset display/draw buffer selection. This may not actually @@ -7203,11 +7206,11 @@ void voodoo_callback(void *p) voodoo_t *draw_voodoo; int draw_line; - if (voodoo == voodoo->set->voodoos[1]) - goto skip_draw; - if (SLI_ENABLED) { + if (voodoo == voodoo->set->voodoos[1]) + goto skip_draw; + if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) draw_voodoo = voodoo; else @@ -7216,6 +7219,8 @@ void voodoo_callback(void *p) } else { + if (!(voodoo->fbiInit0 & 1)) + goto skip_draw; draw_voodoo = voodoo; draw_line = voodoo->line; } From 668a0dd18da43f1e31af364cead2e2451b19f4d0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 17 Aug 2017 21:59:51 +0100 Subject: [PATCH 0131/1050] Re-implemented UM8669F emulation. --- src/um8669f.c | 244 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 158 insertions(+), 86 deletions(-) diff --git a/src/um8669f.c b/src/um8669f.c index 8132ff0..67e2ba4 100644 --- a/src/um8669f.c +++ b/src/um8669f.c @@ -5,36 +5,21 @@ 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 +bit 7 - enable PnP registers -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 +PnP registers : -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 - - */ +07 - device : + 0 = FDC + 1 = COM1 + 2 = COM2 + 3 = LPT1 + 5 = Game port +30 - enable +60/61 - addr +70 - IRQ +74 - DMA*/ #include "ibm.h" @@ -44,91 +29,178 @@ COM2 : #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) +typedef struct um8669f_t { - int temp; -// pclog("um8669f_write : port=%04x reg %02X = %02X locked=%i\n", port, um8669f_curreg, val, um8669f_locked); - if (um8669f_locked) + int locked; + int cur_reg_108; + uint8_t regs_108[256]; + + int cur_reg; + int cur_device; + struct + { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[8]; +} um8669f_t; + +static um8669f_t um8669f_global; + +#define DEV_FDC 0 +#define DEV_COM1 1 +#define DEV_COM2 2 +#define DEV_LPT1 3 +#define DEV_GAME 5 + +#define REG_DEVICE 0x07 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 + +void um8669f_pnp_write(uint16_t port, uint8_t val, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + + if (port == 0x279) + um8669f->cur_reg = val; + else + { + if (um8669f->cur_reg == REG_DEVICE) + um8669f->cur_device = val & 7; + else + { +// pclog("Write UM8669F %02x [%02x] %02x\n", um8669f->cur_reg, um8669f->cur_device, val); + switch (um8669f->cur_reg) + { + case REG_ENABLE: + um8669f->dev[um8669f->cur_device].enable = val; + break; + case REG_ADDRLO: + um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + um8669f->dev[um8669f->cur_device].irq = val; + break; + case REG_DMA: + um8669f->dev[um8669f->cur_device].dma = val; + break; + } + + switch (um8669f->cur_device) + { + case DEV_FDC: + fdc_remove(); + if (um8669f->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (um8669f->dev[DEV_COM1].enable & 1) + serial1_set(um8669f->dev[DEV_COM1].addr, um8669f->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (um8669f->dev[DEV_COM2].enable & 1) + serial2_set(um8669f->dev[DEV_COM2].addr, um8669f->dev[DEV_COM2].irq); + break; + case DEV_LPT1: + lpt1_remove(); + lpt2_remove(); + if (um8669f->dev[DEV_LPT1].enable & 1) + lpt1_init(um8669f->dev[DEV_LPT1].addr); + break; + } + } + } +} + +uint8_t um8669f_pnp_read(uint16_t port, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + +// pclog("Read UM8669F %02x\n", um8669f->cur_reg); + + switch (um8669f->cur_reg) + { + case REG_DEVICE: + return um8669f->cur_device; + case REG_ENABLE: + return um8669f->dev[um8669f->cur_device].enable; + case REG_ADDRLO: + return um8669f->dev[um8669f->cur_device].addr & 0xff; + case REG_ADDRHI: + return um8669f->dev[um8669f->cur_device].addr >> 8; + case REG_IRQ: + return um8669f->dev[um8669f->cur_device].irq; + case REG_DMA: + return um8669f->dev[um8669f->cur_device].dma; + } + + return 0xff; +} + +void um8669f_write(uint16_t port, uint8_t val, void *p) +{ + um8669f_t *um8669f = (um8669f_t *)p; + + if (um8669f->locked) { if (port == 0x108 && val == 0xaa) - um8669f_locked = 0; + um8669f->locked = 0; } else { if (port == 0x108) { if (val == 0x55) - um8669f_locked = 1; + um8669f->locked = 1; else - um8669f_curreg = val; + um8669f->cur_reg_108 = val; } else { - um8669f_regs[um8669f_curreg] = val; +// pclog("Write UM8669f register %02x %02x %04x:%04x %i\n", um8669f_curreg, val, CS,cpu_state.pc, ins); + um8669f->regs_108[um8669f->cur_reg_108] = val; - fdc_remove(); - if (um8669f_regs[0xc0] & 1) - fdc_add(); - - if (um8669f_regs[0xc0] & 2) + io_removehandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_removehandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_removehandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f); + if (um8669f->regs_108[0xc1] & 0x80) { - temp = um8669f_regs[0xc3] & 1; /*might be & 2*/ - if (!(um8669f_regs[0xc1] & 2)) - 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; - } - } - - 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: 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; - } - } - - 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; + io_sethandler(0x0279, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_sethandler(0x0a79, 0x0001, NULL, NULL, NULL, um8669f_pnp_write, NULL, NULL, um8669f); + io_sethandler(0x03e3, 0x0001, um8669f_pnp_read, NULL, NULL, NULL, NULL, NULL, um8669f); } } } } -uint8_t um8669f_read(uint16_t port, void *priv) +uint8_t um8669f_read(uint16_t port, void *p) { -// pclog("um8669f_read : port=%04x reg %02X locked=%i\n", port, um8669f_curreg, um8669f_locked); - if (um8669f_locked) - return 0xff; + um8669f_t *um8669f = (um8669f_t *)p; + +// pclog("um8669f_read : port=%04x reg %02X locked=%i %02x\n", port, um8669f_curreg, um8669f_locked, um8669f_regs[um8669f_curreg]); + if (um8669f->locked) + return 0xff; if (port == 0x108) - return um8669f_curreg; /*???*/ + return um8669f->cur_reg_108; /*???*/ else - return um8669f_regs[um8669f_curreg]; + return um8669f->regs_108[um8669f->cur_reg_108]; } void um8669f_init() { - io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, NULL); - um8669f_locked = 1; + memset(&um8669f_global, 0, sizeof(um8669f_t)); + + um8669f_global.locked = 1; + + io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global); } From 980fd2dcfa25a42702fdf370e4e23287156f7995 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 20 Aug 2017 14:48:00 +0100 Subject: [PATCH 0132/1050] Fixed serial port configuration on WD76C10 (Amstrad MegaPC). --- src/wd76c10.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/wd76c10.c b/src/wd76c10.c index e164ed6..9c77b7d 100644 --- a/src/wd76c10.c +++ b/src/wd76c10.c @@ -44,19 +44,29 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv) case 0x2072: wd76c10_2072 = val; - switch ((val >> 5) & 7) + serial1_remove(); + if (!(val & 0x10)) { - 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; + 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; + default: serial1_remove(); break; + } } - switch ((val >> 1) & 7) + serial2_remove(); + if (!(val & 0x01)) { - 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; + 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; + default: serial2_remove(); break; + } } break; From 9dbedefc5f83e003d932bfb9bf7eddcc4ae11e37 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 20 Aug 2017 21:49:33 +0100 Subject: [PATCH 0133/1050] Improvements to Acermate 386SX25/N : - Implemented serial & parallel port configuration - Implemented shadow RAM - OTI-067 now configured as on-board device rather than separate card --- src/acer386sx.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++- src/acer386sx.h | 1 + src/vid_oti067.c | 21 ++++++-- src/vid_oti067.h | 2 + src/video.c | 2 +- 5 files changed, 147 insertions(+), 6 deletions(-) diff --git a/src/acer386sx.c b/src/acer386sx.c index 77a7ef2..456ef35 100644 --- a/src/acer386sx.c +++ b/src/acer386sx.c @@ -1,22 +1,92 @@ #include "ibm.h" +#include "device.h" #include "io.h" #include "cpu.h" +#include "lpt.h" +#include "mem.h" +#include "serial.h" +#include "vid_oti067.h" #include "acer386sx.h" static int acer_index = 0; static uint8_t acer_regs[256]; +static uint8_t acer_last_write; +static int acer_locked; +static void *acer_oti067; + +void acer386sx_set_oti067(void *oti067) +{ + acer_oti067 = oti067; +} void acer386sx_write(uint16_t addr, uint8_t val, void *priv) { if (addr & 1) - acer_regs[acer_index] = val; + { + if (acer_locked) + { + if (acer_last_write == 0x14 && val == 0x09) + acer_locked = 0; + + acer_last_write = val; + return; + } + + if (acer_index == 0xff && val == 0xff) + acer_locked = 1; + else + { + pclog("Write ACER reg %02x %02x %08x\n", acer_index, val, cs); + acer_regs[acer_index] = val; + + switch (acer_index) + { + case 0xa: + switch ((val >> 4) & 3) + { + case 0: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + break; + case 0xb: + switch ((val >> 4) & 3) + { + case 0: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + break; + } + } + } else - acer_index = val; + acer_index = val; } uint8_t acer386sx_read(uint16_t addr, void *priv) { + if (acer_locked) + return 0xff; if (addr & 1) { if ((acer_index >= 0xc0 || acer_index == 0x20) && cpu_iscyrix) @@ -27,7 +97,60 @@ uint8_t acer386sx_read(uint16_t addr, void *priv) return acer_index; } +static uint8_t acer386sx_37f = 0, acer386sx_io = 0; +void acer386sx_io_write(uint16_t addr, uint8_t val, void *priv) +{ + switch (addr) + { + case 0x37f: + acer386sx_37f = val; + if (val & 4) + oti067_enable_disable(acer_oti067, 0); + else + oti067_enable_disable(acer_oti067, 1); + break; + + case 0x3f3: + acer386sx_io = val; + serial1_remove(); + serial2_remove(); + lpt1_remove(); + lpt2_remove(); + + switch (val & 3) + { + case 0: lpt1_init(0x378); break; + case 1: lpt1_init(0x3bc); break; + case 2: lpt1_init(0x278); break; + } + if (!(val & 0x04)) + serial1_set(0x3f8, 4); + if (!(val & 0x08)) + serial2_set(0x2f8, 3); + break; + } +} + +uint8_t acer386sx_io_read(uint16_t addr, void *priv) +{ + switch (addr) + { + case 0x37f: + return acer386sx_37f; + + case 0x3f3: + return acer386sx_io; + } + + return 0xff; +} + void acer386sx_init() { io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL); + io_sethandler(0x037f, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL); + io_sethandler(0x03f3, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL); + + acer386sx_io = 0; + acer386sx_37f = 0; } diff --git a/src/acer386sx.h b/src/acer386sx.h index 12d98f1..3d91d5c 100644 --- a/src/acer386sx.h +++ b/src/acer386sx.h @@ -1 +1,2 @@ void acer386sx_init(); +void acer386sx_set_oti067(void *oti067); diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 7088bbf..e528e01 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -8,6 +8,7 @@ #include "video.h" #include "vid_oti067.h" #include "vid_svga.h" +#include "acer386sx.h" typedef struct oti067_t { @@ -171,6 +172,21 @@ void *oti067_common_init(char *bios_fn, int vram_size) return oti067; } +void oti067_enable_disable(void *p, int enable) +{ + oti067_t *oti067 = (oti067_t *)p; + + mem_mapping_disable(&oti067->bios_rom.mapping); + io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + io_removehandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + if (enable) + { + mem_mapping_enable(&oti067->bios_rom.mapping); + io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + } +} + void *oti067_init() { int vram_size = device_get_config_int("memory"); @@ -181,9 +197,8 @@ void *oti067_acer386_init() { oti067_t *oti067 = oti067_common_init("acer386/oti067.bin", 512); - if (oti067) - oti067->bios_rom.rom[0x5d] = 0x74; - + acer386sx_set_oti067(oti067); + return oti067; } diff --git a/src/vid_oti067.h b/src/vid_oti067.h index 81d4358..cf1fa1b 100644 --- a/src/vid_oti067.h +++ b/src/vid_oti067.h @@ -1,2 +1,4 @@ extern device_t oti067_device; extern device_t oti067_acer386_device; + +void oti067_enable_disable(void *p, int enable); diff --git a/src/video.c b/src/video.c index df3a2cc..e7567e5 100644 --- a/src/video.c +++ b/src/video.c @@ -297,7 +297,7 @@ void video_init() return; case ROM_ACER386: - device_add(&oti067_device); + device_add(&oti067_acer386_device); return; case ROM_IBMPS1_2011: From f9bd0b844f12ae3349a27e4534d195a07a649f9a Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Aug 2017 18:20:08 +0100 Subject: [PATCH 0134/1050] More SCAT improvements. Patch from Greatpsycho. --- src/scat.c | 118 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/src/scat.c b/src/scat.c index 2bcbb4d..a565047 100644 --- a/src/scat.c +++ b/src/scat.c @@ -15,8 +15,7 @@ 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; -static mem_mapping_t scat_shadowram_mapping; -static mem_mapping_t scat_512k_clip_mapping; +static mem_mapping_t scat_shadowram_mapping[6]; static mem_mapping_t scat_4000_9FFF_mapping[24]; static mem_mapping_t scat_A000_BFFF_mapping; @@ -55,8 +54,9 @@ void scat_shadow_state_update() void scat_set_xms_bound(uint8_t val) { uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10; + int i; - switch (val) + switch (val & 0x0F) { case 1: scat_xms_bound = 0x100000; @@ -96,17 +96,21 @@ void scat_set_xms_bound(uint8_t val) break; } - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + if ((val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) { if (val != 1) { - mem_mapping_enable(&scat_shadowram_mapping); - if (val == 0) + if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); + for(i=0;i<6;i++) + mem_mapping_enable(&scat_shadowram_mapping[i]); + if ((val & 0x0F) == 0) scat_xms_bound = 0x160000; } else { - mem_mapping_disable(&scat_shadowram_mapping); + for(i=0;i<6;i++) + mem_mapping_disable(&scat_shadowram_mapping[i]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); } pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) @@ -116,6 +120,10 @@ void scat_set_xms_bound(uint8_t val) } else { + for(i=0;i<6;i++) + mem_mapping_disable(&scat_shadowram_mapping[i]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); + if (scat_xms_bound > max_xms_size) scat_xms_bound = max_xms_size; pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); @@ -129,19 +137,43 @@ void scat_set_xms_bound(uint8_t val) uint32_t get_scat_addr(uint32_t addr, scat_t *p) { if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) - { addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; - } - else if (p == NULL && mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7)) - addr &= 0x7FFFF; - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + + if (mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7 || (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) != 0)) + addr = (addr & ~0x780000) | ((addr & 0x600000) >> 2); + else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) { - if(addr >= 0x100000) addr -= 0x60000; - else if(addr >= 0xA0000) addr = 0xFFFFFFFF; + addr &= ~0x600000; + if(mem_size >= 2048) + addr |= (addr & 0x180000) << 2; } + + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) + addr ^= mem_size < 2048 ? 0x1F0000 : 0x670000; return addr; } +void scat_memmap_state_update() +{ + int i; + uint32_t addr; + + for(i=16;i<24;i++) + { + addr = get_scat_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&scat_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + } + addr = get_scat_addr(0xA0000, NULL); + mem_mapping_set_exec(&scat_A000_BFFF_mapping, addr < (mem_size << 10) ? ram + addr : NULL); + for(i=0;i<6;i++) + { + addr = get_scat_addr(0x100000 + (i << 16), NULL); + mem_mapping_set_exec(&scat_shadowram_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + } + + flushmmucache(); +} + void scat_set_global_EMS_state(int state) { int i; @@ -172,7 +204,7 @@ void scat_set_global_EMS_state(int state) void scat_write(uint16_t port, uint8_t val, void *priv) { - uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index; + uint8_t scat_reg_valid = 0, scat_shadow_update = 0, scat_map_update = 0, index; uint32_t base_addr, virt_addr; switch (port) @@ -216,31 +248,28 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: - // TODO - Implement mysterious address mapping when lower nibble of this register is 3 or 4 and memory size is greater than 1MB. if((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) { if((val & 0x0F) == 3) { - if(mem_size > 640) mem_mapping_disable(&scat_A000_BFFF_mapping); - if(mem_size > 768) mem_mapping_disable(&ram_mid_mapping); - mem_mapping_enable(&scat_shadowram_mapping); + if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); + for(index=0;index<6;index++) + mem_mapping_enable(&scat_shadowram_mapping[index]); } else { - mem_mapping_disable(&scat_shadowram_mapping); - if(mem_size > 640 && (val & 0x0F) > 3) - { - mem_mapping_enable(&scat_A000_BFFF_mapping); - if(mem_size > 768) mem_mapping_enable(&ram_mid_mapping); - } - } - if(mem_size < 2048) - { - if ((val & 0x0F) > 7) mem_mapping_enable(&scat_512k_clip_mapping); - else mem_mapping_disable(&scat_512k_clip_mapping); + for(index=0;index<6;index++) + mem_mapping_disable(&scat_shadowram_mapping[index]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); } } - flushmmucache(); + else + { + for(index=0;index<6;index++) + mem_mapping_disable(&scat_shadowram_mapping[index]); + if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); + } + scat_map_update = 1; cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; cpu_update_waitstates(); @@ -248,9 +277,9 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_EXTENDED_BOUNDARY: - scat_set_xms_bound(val & 0x0f); + scat_set_xms_bound(val & 0x4f); mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - flushmmucache(); + if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0x40) scat_map_update = 1; scat_reg_valid = 1; break; case SCAT_ROM_ENABLE: @@ -269,6 +298,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); if (scat_shadow_update) scat_shadow_state_update(); + if (scat_map_update) + scat_memmap_state_update(); // pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); break; @@ -463,14 +494,11 @@ void scat_init() for (i = 0; i < 24; i++) { - if(mem_size > 256 + (i << 4)) - { - mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x40000 + (i << 14), MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); - } + mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_4000_9FFF_mapping[i]); } - mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); mem_mapping_enable(&scat_A000_BFFF_mapping); for (i = 0; i < 32; i++) @@ -489,16 +517,8 @@ void scat_init() 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); } - if (mem_size == 1024) - { - mem_mapping_add(&scat_shadowram_mapping, 0x100000, 0x60000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, 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. - mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_disable(&scat_512k_clip_mapping); - // --- + for(i=0;i<6;i++) + mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); scat_set_xms_bound(0); scat_shadow_state_update(); From 5d1b2e4f835e186706622914d71c7e4ec2c4b20e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Aug 2017 19:25:50 +0100 Subject: [PATCH 0135/1050] Added video 'Alternative update-lock' option that may help performance on some machines. Patch from bit. --- src/pc.xrc | 4 + src/wx-display.h | 1 + src/wx-resources.cpp | 2636 +++++++++++++++++----------------- src/wx-sdl2-video-gl3.c | 18 +- src/wx-sdl2-video-renderer.c | 360 ++--- src/wx-sdl2-video.c | 64 +- src/wx-sdl2-video.h | 4 +- src/wx-sdl2.c | 10 + 8 files changed, 1561 insertions(+), 1536 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index a471e63..75af390 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -205,6 +205,10 @@ 1 + + + 1 + diff --git a/src/wx-display.h b/src/wx-display.h index 2c98c75..09f6315 100644 --- a/src/wx-display.h +++ b/src/wx-display.h @@ -21,6 +21,7 @@ extern int video_scale_mode; extern int video_vsync; extern int video_focus_dim; extern int video_fullscreen_mode; +extern int video_alternative_update_lock; extern int win_doresize; diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 615d23d..a2210cc 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1623,7 +1623,7 @@ static unsigned char xml_res_file_23[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_24 = 124770; +static size_t xml_res_size_24 = 124939; static unsigned char xml_res_file_24[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -1983,457 +1983,665 @@ static unsigned char xml_res_file_24[] = { 115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, 99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, -116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,99,97,108,101,32,102,105,108,116,101,114, -105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, -76,69,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110, -101,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,116,114,101, -116,99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116, -101,103,101,114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,65,76, +84,69,82,78,65,84,73,86,69,95,85,80,68,65,84,69,95,76,79,67,75,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,108,116,101,114,110, +97,116,105,118,101,32,117,112,100,97,116,101,45,108,111,99,107,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98, +108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34, +47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79, +68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, 111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69, -78,85,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, -112,117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,117,116,112,117,116,32,115,116,114,101,116,99,104,45,109, +111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46, -53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, -69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,52,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, -110,71,76,32,51,46,48,32,114,101,110,100,101,114,101,114,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,116,114,101,116, -99,104,45,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101, +114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116, +32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, +67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83, -113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, -114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84, -95,83,84,82,69,84,67,72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99,97, -108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112, -117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53, -120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78, -80,85,84,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, -83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65, -76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51, -46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,114, -101,102,114,101,115,104,32,114,97,116,101,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82, -69,83,72,95,82,65,84,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,97,109,101,32,97,115,32,101,109,117,108, -97,116,101,100,32,100,105,115,112,108,97,121,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, -114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, -82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,48,32,104,122,60, +34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46, +48,32,114,101,110,100,101,114,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,110,112,117,116,32,115,116,114,101,116,99,104,45,109,111, +100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53, +51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101, +32,112,105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67, +72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,99,97, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85, +84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, +83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91, +52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,53,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,104,97,100,101,114,32,114,101,102,114,101,115, +104,32,114,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84, +69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,97,109,101,32,97,115,32,101,109,117,108,97,116,101,100,32,100, +105,115,112,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69, +83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,49,48,32,104,122,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68, +69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,53,32,104,122, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, +76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,51, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,51,48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83, +72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,53,48,32,104,122,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, +82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54,48,32,104,122,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,55,50, 93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -50,53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, 77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, -95,82,65,84,69,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,51,48,32,104,122,60,47,108,97,98,101,108,62,10, +95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, -95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,53,48,32,104,122,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54, -48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82, -65,84,69,91,55,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69, -70,82,69,83,72,95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100, -101,114,32,109,97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102, -101,114,32,108,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,78,68,95,66,85,70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,83,78,68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,50,48,48,32,109,115, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,48,48, -32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115, -99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114,101,101,110,115,104, -111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72, -79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -84,97,107,101,32,115,99,114,101,101,110,115,104,111,116,92,116,67,116,114, -108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, +76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,109, +97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111,117,110,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102,101,114,32,108,101, +110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85, +70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, -72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, -79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78, +68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, -51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, -72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, -97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62, -10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, -68,67,95,67,68,82,79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62, -10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, -68,67,95,69,68,73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,67,95,70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,50,48,48,32,109,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,83,99,114,101,101,110,115,104,111,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,84,97,107,101,32,115,99,114, +101,101,110,115,104,111,116,92,116,67,116,114,108,43,65,108,116,43,80,97, +103,101,85,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,70,111,114,109,97,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84, +95,70,79,82,77,65,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,78,71,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77, +65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,73,70,70,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66, +77,80,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67, +82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,51,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,80,71,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,76,65, +83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +108,97,115,104,32,115,99,114,101,101,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49, +60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,77,97,99,104,105,110,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,80, +65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105,100, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,67,68,82, +79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, +60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, +70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, +74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, +69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, 62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,69,74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,78,69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10, -32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68, -67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34, -47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61, -34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56, -48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114, -116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115, -116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114, -97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66, -69,76,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111, -103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108, -103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, -85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117, -114,101,32,80,67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60, -99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78, -69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, -47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111, -119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, -116,101,98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84, -69,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, -101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, -99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, -114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,51,50,120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, -76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, +48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, +61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115, +116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108,103,34,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117,114,101,32,80, +67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, +101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, +108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, +85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, +105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -2460,8 +2668,91 @@ static unsigned char xml_res_file_24[] = { 32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, +115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, +61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, +120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, 62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, 65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, @@ -2476,478 +2767,6 @@ static unsigned char xml_res_file_24[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99, -32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, -104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118, -97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, -67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, -122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, -99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, -99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, -76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, @@ -2970,32 +2789,110 @@ static unsigned char xml_res_file_24[] = { 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, +67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, +32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, 47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, 47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, -105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, -100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3011,180 +2908,51 @@ static unsigned char xml_res_file_24[] = { 98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, -103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, -101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, -99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, -65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, 103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, -107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, -115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, @@ -3210,6 +2978,208 @@ static unsigned char xml_res_file_24[] = { 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, +73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, 62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, @@ -3217,167 +3187,144 @@ static unsigned char xml_res_file_24[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, -97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, +115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, -98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, -99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, -73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, -47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, -60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, +83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,100,114,105,118,101,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,80,65,78,69,76,95,68,82,73,86,69,83,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, -79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, 68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, @@ -3408,7 +3355,7 @@ static unsigned char xml_res_file_24[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, 45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68, -50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +49,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, 47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, @@ -3438,7 +3385,7 @@ static unsigned char xml_res_file_24[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, 111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +77,66,79,68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, 119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, 68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, @@ -3454,103 +3401,164 @@ static unsigned char xml_res_file_24[] = { 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,104,111,105,99,101,98,111,111,107,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,72,66,95,68,69,70,65,85,76,84,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111, -105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,68,114,105,118,101,32,49,32,40,67,58,41,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101, -100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, -97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, -65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, -108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, 76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, 84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,60,108,97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, +79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,66,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,73,95,72,79, +82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,111, +105,99,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72,66, +95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,49,32, +40,67,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index 5aee3e9..f8895b3 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -762,7 +762,7 @@ static void read_shader_config() } } -int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITMAP* screen) +int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, SDL_Rect screen) { int i, j; @@ -801,9 +801,9 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITM glEnable(GL_TEXTURE_2D); - scene_texture.data = screen->dat; - scene_texture.width = screen->w; - scene_texture.height = screen->h; + scene_texture.data = NULL; + scene_texture.width = screen.w; + scene_texture.height = screen.h; scene_texture.internal_format = GL_RGBA8; scene_texture.format = GL_RGBA; scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; @@ -1209,7 +1209,7 @@ static void render_pass(struct render_data* data) glw->glUseProgram(0); } -void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, BITMAP* screen) +void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, SDL_Rect screen) { if (!context) return; @@ -1265,10 +1265,10 @@ void gl3_present(SDL_Window* window, SDL_Rect video_rect, SDL_Rect window_rect, pass->state.tex_coords[7] = maxy; // create input tex coords - minx = video_rect.x/(float)screen->w; - miny = video_rect.y/(float)screen->h; - maxx = (video_rect.x+video_rect.w)/(float)screen->w; - maxy = (video_rect.y+video_rect.h)/(float)screen->h; + minx = video_rect.x/(float)screen.w; + miny = video_rect.y/(float)screen.h; + maxx = (video_rect.x+video_rect.w)/(float)screen.w; + maxy = (video_rect.y+video_rect.h)/(float)screen.h; GLfloat tex_coords[] = { minx, miny, diff --git a/src/wx-sdl2-video-renderer.c b/src/wx-sdl2-video-renderer.c index 81445ac..c06d64c 100644 --- a/src/wx-sdl2-video-renderer.c +++ b/src/wx-sdl2-video-renderer.c @@ -1,180 +1,180 @@ -#include -#include -#include -#include -#include "video.h" -#include "wx-utils.h" -#include "wx-sdl2-video.h" -#include "wx-sdl2-video-renderer.h" - -static SDL_Texture* texture = NULL; -static SDL_Renderer* renderer = NULL; - -extern int video_scale_mode; -extern int video_vsync; -extern int video_focus_dim; -extern int take_screenshot; -extern void screenshot_taken(unsigned char* rgb, int width, int height); - -int sdl_video_renderer_init(SDL_Window* window, sdl_render_driver requested_render_driver, BITMAP* screen) -{ - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); - const char* driver = requested_render_driver.sdl_id; - if (!driver) driver = "0"; - SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); - - int flags = SDL_RENDERER_ACCELERATED; - if (video_vsync) { - flags |= SDL_RENDERER_PRESENTVSYNC; - } - renderer = SDL_CreateRenderer(window, -1, flags); - - if (!renderer) - { - char message[200]; - sprintf(message, - "SDL window could not be created! Error: %s\n", - SDL_GetError()); - wx_messagebox(0, message, "SDL Error", WX_MB_OK); - return SDL_FALSE; - } - - SDL_RendererInfo rendererInfo; - SDL_GetRendererInfo(renderer, &rendererInfo); - sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); - if (!d) - strcpy(current_render_driver_name, "Unknown"); - else - strcpy(current_render_driver_name, d->name); - - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, - screen->w, screen->h); - - return SDL_TRUE; - -} - -void sdl_video_renderer_close() -{ - if (texture) - { - SDL_DestroyTexture(texture); - texture = NULL; - } - if (renderer) - { - SDL_DestroyRenderer(renderer); - renderer = NULL; - } -} - -void sdl_video_renderer_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen) -{ - SDL_UpdateTexture(texture, &updated_rect, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x], screen->w * 4); -} - -void sdl_video_renderer_present(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, BITMAP* screen) -{ - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); - int sshot = take_screenshot; - if (!sshot) - { - if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); - SDL_RenderFillRect(renderer, NULL); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - } - if (flash.enabled) - { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, flash.color[0], flash.color[1], flash.color[2], flash.color[3]); - SDL_RenderFillRect(renderer, NULL); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - } - } - SDL_RenderPresent(renderer); - - if (sshot) - { - take_screenshot = 0; - - int width = window_rect.w; - int height = window_rect.h; - - SDL_GetWindowSize(window, &width, &height); - - /* seems to work without rendering to texture first */ -// SDL_Texture* tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_TARGET, width, height); -// -// SDL_SetRenderTarget(renderer, tex); -// SDL_RenderClear(renderer); -// SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); -// SDL_RenderPresent(renderer); - - unsigned char* rgba = (unsigned char*)malloc(width*height*4); - int res = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width*4); - -// SDL_SetRenderTarget(renderer, NULL); -// SDL_DestroyTexture(tex); - - if (!res) - { - int x, y; - unsigned char* rgb = (unsigned char*)malloc(width*height*3); - - for (x = 0; x < width; ++x) - { - for (y = 0; y < height; ++y) - { - rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; - rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; - rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; - } - } - - screenshot_taken(rgb, width, height); - - free(rgb); - } - else - screenshot_taken(0, 0, 0); - - free(rgba); - } - -} - -sdl_renderer_t* sdl2_renderer_create() -{ - sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t)); - renderer->init = sdl_video_renderer_init; - renderer->close = sdl_video_renderer_close; - renderer->update = sdl_video_renderer_update; - renderer->present = sdl_video_renderer_present; - renderer->always_update = 0; - return renderer; -} - -void sdl2_renderer_close(sdl_renderer_t* renderer) -{ - free(renderer); -} - -int sdl2_renderer_available(struct sdl_render_driver* driver) -{ - int i; - SDL_RendererInfo renderInfo; - for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) - { - SDL_GetRenderDriverInfo(i, &renderInfo); - if (!strcmp(driver->sdl_id, renderInfo.name)) - return 1; - } - return 0; - -} +#include +#include +#include +#include +#include "video.h" +#include "wx-utils.h" +#include "wx-sdl2-video.h" +#include "wx-sdl2-video-renderer.h" + +static SDL_Texture* texture = NULL; +static SDL_Renderer* renderer = NULL; + +extern int video_scale_mode; +extern int video_vsync; +extern int video_focus_dim; +extern int take_screenshot; +extern void screenshot_taken(unsigned char* rgb, int width, int height); + +int sdl_video_renderer_init(SDL_Window* window, sdl_render_driver requested_render_driver, SDL_Rect screen) +{ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); + const char* driver = requested_render_driver.sdl_id; + if (!driver) driver = "0"; + SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); + + int flags = SDL_RENDERER_ACCELERATED; + if (video_vsync) { + flags |= SDL_RENDERER_PRESENTVSYNC; + } + renderer = SDL_CreateRenderer(window, -1, flags); + + if (!renderer) + { + char message[200]; + sprintf(message, + "SDL window could not be created! Error: %s\n", + SDL_GetError()); + wx_messagebox(0, message, "SDL Error", WX_MB_OK); + return SDL_FALSE; + } + + SDL_RendererInfo rendererInfo; + SDL_GetRendererInfo(renderer, &rendererInfo); + sdl_render_driver* d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); + if (!d) + strcpy(current_render_driver_name, "Unknown"); + else + strcpy(current_render_driver_name, d->name); + + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + screen.w, screen.h); + + return SDL_TRUE; + +} + +void sdl_video_renderer_close() +{ + if (texture) + { + SDL_DestroyTexture(texture); + texture = NULL; + } + if (renderer) + { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } +} + +void sdl_video_renderer_update(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen) +{ + SDL_UpdateTexture(texture, &updated_rect, &((uint32_t*) screen->dat)[updated_rect.y * screen->w + updated_rect.x], screen->w * 4); +} + +void sdl_video_renderer_present(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, SDL_Rect screen) +{ + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); + int sshot = take_screenshot; + if (!sshot) + { + if (video_focus_dim && !(SDL_GetWindowFlags(window)&SDL_WINDOW_INPUT_FOCUS)) { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + if (flash.enabled) + { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, flash.color[0], flash.color[1], flash.color[2], flash.color[3]); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + } + SDL_RenderPresent(renderer); + + if (sshot) + { + take_screenshot = 0; + + int width = window_rect.w; + int height = window_rect.h; + + SDL_GetWindowSize(window, &width, &height); + + /* seems to work without rendering to texture first */ +// SDL_Texture* tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_TARGET, width, height); +// +// SDL_SetRenderTarget(renderer, tex); +// SDL_RenderClear(renderer); +// SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); +// SDL_RenderPresent(renderer); + + unsigned char* rgba = (unsigned char*)malloc(width*height*4); + int res = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width*4); + +// SDL_SetRenderTarget(renderer, NULL); +// SDL_DestroyTexture(tex); + + if (!res) + { + int x, y; + unsigned char* rgb = (unsigned char*)malloc(width*height*3); + + for (x = 0; x < width; ++x) + { + for (y = 0; y < height; ++y) + { + rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; + rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; + rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; + } + } + + screenshot_taken(rgb, width, height); + + free(rgb); + } + else + screenshot_taken(0, 0, 0); + + free(rgba); + } + +} + +sdl_renderer_t* sdl2_renderer_create() +{ + sdl_renderer_t* renderer = malloc(sizeof(sdl_renderer_t)); + renderer->init = sdl_video_renderer_init; + renderer->close = sdl_video_renderer_close; + renderer->update = sdl_video_renderer_update; + renderer->present = sdl_video_renderer_present; + renderer->always_update = 0; + return renderer; +} + +void sdl2_renderer_close(sdl_renderer_t* renderer) +{ + free(renderer); +} + +int sdl2_renderer_available(struct sdl_render_driver* driver) +{ + int i; + SDL_RendererInfo renderInfo; + for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) + { + SDL_GetRenderDriverInfo(i, &renderInfo); + if (!strcmp(driver->sdl_id, renderInfo.name)) + return 1; + } + return 0; + +} diff --git a/src/wx-sdl2-video.c b/src/wx-sdl2-video.c index 851bfb0..f6551b0 100644 --- a/src/wx-sdl2-video.c +++ b/src/wx-sdl2-video.c @@ -12,17 +12,16 @@ void video_blit_complete(); -static BITMAP *buffer32_vscale; BITMAP *screen; -SDL_Rect old_screen_rect; -SDL_Rect screen_rect; -SDL_Rect updated_rect; -SDL_Rect window_rect; -SDL_Rect blit_rect; -SDL_Rect texture_rect; -int updated = 0; +static BITMAP *screen_copy = NULL; +static SDL_Rect screen_rect; +static SDL_Rect updated_rect; +static SDL_Rect updated_rect_copy; +static SDL_Rect blit_rect; +static SDL_Rect texture_rect; +static int updated = 0; -SDL_mutex* blitMutex = NULL; +static SDL_mutex* blitMutex = NULL; static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); @@ -30,6 +29,7 @@ int video_scale_mode = 1; int video_vsync = 0; int video_focus_dim = 0; int video_fullscreen_mode = 0; +int video_alternative_update_lock = 0; static sdl_render_driver sdl_render_drivers[] = { { RENDERER_AUTO, "auto", "Auto", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available }, @@ -55,22 +55,6 @@ void hline(BITMAP *b, int x1, int y, int x2, int col) ((uint32_t *)b->line[y])[x1] = col; } -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) { free(b); @@ -254,8 +238,9 @@ int sdl_video_init() video_blit_memtoscreen_func = sdl_blit_memtoscreen; requested_render_driver = sdl_get_render_driver_by_id(RENDERER_AUTO, RENDERER_AUTO); - buffer32_vscale = create_bitmap(2048, 2048); - screen = create_bitmap(2048, 2048); + screen_rect.w = screen_rect.h = 2048; + + screen = create_bitmap(screen_rect.w, screen_rect.h); return SDL_TRUE; } @@ -264,15 +249,20 @@ void sdl_video_close() { requested_render_driver.renderer_close(renderer); renderer = NULL; - destroy_bitmap(buffer32_vscale); destroy_bitmap(screen); + screen = NULL; SDL_DestroyMutex(blitMutex); } int sdl_renderer_init(SDL_Window* window) { + if (video_alternative_update_lock) + screen_copy = create_bitmap(screen_rect.w, screen_rect.h); + else + screen_copy = NULL; + renderer = requested_render_driver.renderer_create(); - return renderer->init(window, requested_render_driver, screen); + return renderer->init(window, requested_render_driver, screen_rect); } void sdl_renderer_close() @@ -280,6 +270,10 @@ void sdl_renderer_close() if (renderer) renderer->close(); renderer = NULL; + + if (screen_copy) + destroy_bitmap(screen_copy); + screen_copy = NULL; } int sdl_renderer_update(SDL_Window* window) @@ -289,12 +283,20 @@ int sdl_renderer_update(SDL_Window* window) if (updated) { updated = 0; - renderer->update(window, updated_rect, screen); + if (screen_copy) + { + memcpy(&updated_rect_copy, &updated_rect, sizeof(updated_rect)); + memcpy(screen_copy->dat + (updated_rect.y * screen_copy->w * 4), screen->dat + (updated_rect.y * screen->w * 4), updated_rect.h * screen->w * 4); + } + else + renderer->update(window, updated_rect, screen); texture_rect.w = blit_rect.w; texture_rect.h = blit_rect.h; render = 1; } SDL_UnlockMutex(blitMutex); + if (screen_copy && render) + renderer->update(window, updated_rect_copy, screen_copy); return render || renderer->always_update; } @@ -312,7 +314,7 @@ void sdl_renderer_present(SDL_Window* window) SDL_Rect wr; SDL_GetWindowSize(window, &wr.w, &wr.h); sdl_scale(video_fullscreen_scale, wr, &wr, texture_rect.w, texture_rect.h); - renderer->present(window, texture_rect, wr, screen); + renderer->present(window, texture_rect, wr, screen_rect); } diff --git a/src/wx-sdl2-video.h b/src/wx-sdl2-video.h index 9265430..a32d97d 100644 --- a/src/wx-sdl2-video.h +++ b/src/wx-sdl2-video.h @@ -9,10 +9,10 @@ struct sdl_render_driver; typedef struct sdl_renderer_t { - int (*init)(SDL_Window* window, struct sdl_render_driver driver, BITMAP* screen); + int (*init)(SDL_Window* window, struct sdl_render_driver driver, SDL_Rect screen); void (*close)(); void (*update)(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen); - void (*present)(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, BITMAP* screen); + void (*present)(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, SDL_Rect screen); int always_update; } sdl_renderer_t; diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 67791e9..43616dd 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -289,6 +289,7 @@ void sdl_loadconfig() video_scale_mode = config_get_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); video_vsync = config_get_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); video_focus_dim = config_get_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); + video_alternative_update_lock = config_get_int(CFG_MACHINE, "SDL2", "alternative_update_lock", video_alternative_update_lock); requested_render_driver = sdl_get_render_driver_by_name(config_get_string(CFG_MACHINE, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); gl3_input_scale = config_get_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); @@ -325,6 +326,7 @@ void sdl_saveconfig() config_set_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); config_set_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); config_set_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); + config_set_int(CFG_MACHINE, "SDL2", "alternative_update_lock", video_alternative_update_lock); config_set_string(CFG_MACHINE, "SDL2", "render_driver", (char*)requested_render_driver.sdl_id); config_set_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); @@ -413,6 +415,7 @@ int wx_setupmenu(void* data) wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); wx_checkmenuitem(menu, WX_ID("IDM_VID_VSYNC"), video_vsync); wx_checkmenuitem(menu, WX_ID("IDM_VID_LOST_FOCUS_DIM"), video_focus_dim); + wx_checkmenuitem(menu, WX_ID("IDM_VID_ALTERNATIVE_UPDATE_LOCK"), video_alternative_update_lock); int format = 0; if (!strcmp(screenshot_format, IMAGE_TIFF)) @@ -973,6 +976,13 @@ int wx_handle_command(void* hwnd, int wParam, int checked) wx_checkmenuitem(menu, wParam, video_focus_dim); saveconfig(NULL); } + else if (ID_IS("IDM_VID_ALTERNATIVE_UPDATE_LOCK")) + { + video_alternative_update_lock = !video_alternative_update_lock; + wx_checkmenuitem(menu, wParam, video_alternative_update_lock); + renderer_doreset = 1; + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_GL3_INPUT_STRETCH[start]", "IDM_VID_GL3_INPUT_STRETCH[end]")) { gl3_input_stretch = wParam - wx_xrcid("IDM_VID_GL3_INPUT_STRETCH[start]"); From 75a483f1a60d7d70e1916b57485accfd05d6187a Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Aug 2017 19:37:23 +0100 Subject: [PATCH 0136/1050] Fixed Windows CD-ROM configuration in xx GUI. Patch from bit. --- src/wx-sdl2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 43616dd..49f3d76 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -378,11 +378,11 @@ void wx_initmenu() if (GetDriveTypeA(s)==DRIVE_CDROM) { sprintf(s, "Host CD/DVD Drive (%c:)", c); - wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+(c-'A'), s, wxITEM_RADIO); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+c, s, wxITEM_RADIO); } } #elif __linux__ - wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+1, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); #endif } @@ -1151,7 +1151,7 @@ int wx_handle_command(void* hwnd, int wParam, int checked) return 0; } } - new_cdrom_drive = wParam-IDM_CDROM_REAL+1; + new_cdrom_drive = wParam-IDM_CDROM_REAL; if ((cdrom_drive == new_cdrom_drive) && cdrom_enabled) { /* Switching to the same drive. Do nothing. */ From 25620bdc635a866d6ab65f5d8730163281fe329a Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Aug 2017 19:48:51 +0100 Subject: [PATCH 0137/1050] Add copy button to wx GUI. Patch from bit. --- src/pc.xrc | 11 + src/wx-config_sel.c | 50 ++ src/wx-resources.cpp | 588 +++++++++------- src/wx-utils.cc | 1549 +++++++++++++++++++++--------------------- src/wx-utils.h | 1 + 5 files changed, 1194 insertions(+), 1005 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index 75af390..98c78b8 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -2482,6 +2482,17 @@ 0 + + + wxALL + 5 + + + Copy + icons/32x32/computer_go.png + 0 + + wxALL diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index df769b7..962c194 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -248,6 +248,56 @@ static int config_selection_dlgproc(void* hdlg, int message, INT_PARAM wParam, L return TRUE; } + else if (wParam == WX_ID("IDC_COPY")) + { + char name[64]; + char old_name[64]; + void* h; + int c; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) + { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); + strcpy(name, old_name); + + while (!done) + { + if (wx_textentrydialog(hdlg, "Enter name:", "New name", name, 1, 64, (LONG_PARAM)name)) + { + char old_path[512]; + char new_path[512]; + + strcpy(old_path, configs_path); + put_backslash(old_path); + strcat(old_path, old_name); + strcat(old_path, ".cfg"); + + strcpy(new_path, configs_path); + put_backslash(new_path); + strcat(new_path, name); + strcat(new_path, ".cfg"); + + pclog("Copy %s to %s\n", old_path, new_path); + + if (!wx_file_exists(new_path)) + { + wx_copy_file(old_path, new_path, 1); + + config_list_update(hdlg); + done = 1; + } + else + wx_simple_messagebox("Already exists", "A configuration with that name already exists."); + } + else + done = 1; + } + } + + return TRUE; + } else if (wParam == WX_ID("IDC_DELETE")) { char name[64]; diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index a2210cc..0621be6 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1450,11 +1450,110 @@ static unsigned char xml_res_file_21[] = { 188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, 73,69,78,68,174,66,96,130}; -static size_t xml_res_size_22 = 2051; +static size_t xml_res_size_22 = 1967; static unsigned char xml_res_file_22[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,7,81,73,68,65,84,120,218,180,87,125,108,93,101,25,255,189,239,57, +231,158,115,123,215,142,174,235,166,67,35,84,199,24,100,72,157,153,102, +69,19,101,200,199,10,138,81,23,62,226,248,131,232,192,143,63,140,134,232, +152,134,65,130,136,35,209,108,134,96,52,33,58,194,103,22,65,182,105,153, +115,27,69,6,186,205,106,169,118,99,13,100,31,108,107,217,218,219,246,222, +123,190,94,127,207,57,231,94,110,187,22,70,19,79,250,244,124,190,239,243, +123,126,207,239,121,223,231,42,204,236,176,239,217,244,196,211,218,178, +191,104,140,57,231,65,74,41,196,81,248,135,159,124,107,213,87,120,27,38, +207,102,226,252,199,191,124,108,139,81,86,231,101,151,45,68,108,98,224, +92,48,208,147,86,26,61,61,7,161,76,244,199,245,223,189,249,198,42,136,247, +123,52,174,219,248,132,137,24,122,201,143,204,88,37,60,103,147,239,101, +156,140,151,121,146,104,102,0,192,139,163,8,126,16,97,231,129,195,120,31, +25,96,10,128,207,93,222,6,25,47,243,208,138,51,1,160,36,239,226,88,38,252, +124,123,91,250,212,212,254,77,123,252,229,192,0,162,216,48,109,166,150, +126,123,70,18,148,241,90,35,103,219,216,240,244,139,137,184,170,51,154, +42,144,58,106,228,42,166,227,101,139,62,76,231,152,240,206,158,160,106, +155,170,142,223,155,83,137,224,254,135,159,76,174,53,157,171,140,95,57, +59,249,60,114,141,205,116,24,163,90,33,166,202,140,50,233,243,122,69,139, +173,251,197,230,45,65,20,119,182,47,105,59,39,85,27,212,211,173,106,165, +164,180,194,254,125,125,152,93,240,176,232,162,11,17,69,239,128,144,67, +238,67,51,241,153,0,200,67,91,157,107,191,189,10,34,13,61,195,133,193,100, +118,245,21,237,184,247,161,223,225,206,175,173,64,16,198,117,116,43,116, +237,235,71,28,154,179,0,120,130,140,159,226,59,247,60,2,47,167,97,101,201, +172,165,19,117,247,117,41,172,221,115,114,201,92,16,25,108,248,225,55,18, +49,60,240,228,158,132,238,234,56,73,219,210,133,11,18,134,39,3,80,134,31, +86,2,96,78,99,30,207,12,182,35,159,83,112,93,11,142,235,80,104,10,185,156, +13,135,168,114,52,135,247,14,105,18,227,103,112,104,196,76,159,26,133,55, +186,8,34,130,34,26,91,219,48,74,242,157,6,167,50,109,133,209,217,0,32,159, +85,252,16,133,188,56,100,78,60,13,151,230,112,118,151,158,44,59,117,156, +0,208,25,0,58,182,45,3,135,115,217,58,141,48,239,57,168,84,66,58,176,176, +236,99,31,77,24,240,149,15,223,74,105,15,125,63,209,64,189,198,210,42,224, +135,101,63,34,253,14,148,99,193,114,53,108,57,231,44,222,11,0,154,165,161, +9,66,19,0,255,40,122,147,156,53,207,42,225,24,201,120,9,68,199,57,108,172, +204,135,72,224,246,134,65,172,220,180,129,78,35,108,89,179,134,139,16,166, +96,128,15,42,129,15,143,148,179,20,19,135,218,177,105,86,106,114,47,70, +6,136,35,209,136,156,73,50,108,1,34,139,75,168,224,145,129,50,1,196,124, +63,248,18,53,33,220,95,101,225,173,103,239,79,117,115,199,29,4,21,79,220, +88,170,50,42,83,4,110,46,199,168,117,226,84,217,86,10,134,215,182,45,233, +208,105,10,44,201,61,211,65,199,97,24,178,114,152,166,156,148,143,65,3, +47,202,126,133,121,30,199,218,171,142,241,28,33,240,207,224,229,237,111, +18,64,12,229,151,25,108,52,5,3,34,66,63,72,34,208,154,142,181,68,108,37, +105,176,115,233,57,164,211,33,31,40,177,140,134,75,97,34,42,19,48,223,4, +17,51,234,114,25,88,187,72,0,4,20,98,5,126,56,146,10,78,176,133,41,237, +134,206,35,238,33,6,147,0,200,203,50,197,227,50,135,154,220,38,121,167, +217,100,96,60,82,56,226,43,2,208,201,66,35,9,119,92,37,114,78,202,205,168, +52,133,82,243,13,174,147,4,34,1,69,178,225,196,172,36,237,37,244,135,113, +41,41,65,217,11,234,25,208,169,6,144,32,247,72,161,8,205,38,3,204,44,78, +86,98,156,162,243,88,4,200,242,176,36,69,212,134,164,71,89,86,2,72,68,169, +116,10,206,243,114,73,42,35,58,90,241,233,75,136,47,135,245,93,23,224,215, +175,44,193,103,150,93,76,192,54,129,68,103,3,16,105,86,18,13,56,201,162, +82,137,53,78,149,98,210,205,8,57,113,204,232,13,29,70,4,17,145,149,136, +14,35,233,110,152,174,88,89,100,129,227,56,185,231,230,201,128,204,167, +240,167,238,62,92,189,252,194,68,172,75,230,21,113,219,198,57,100,163,137, +197,96,79,40,195,26,3,227,204,163,67,6,138,140,250,72,49,68,49,80,24,165, +178,139,161,70,49,202,44,200,238,105,163,161,133,177,208,38,216,89,8,208, +204,168,230,160,208,48,31,81,88,224,164,77,184,161,99,49,118,252,237,76, +66,255,170,142,31,96,241,7,78,227,217,222,219,88,190,5,178,149,155,164, +1,89,136,40,40,103,182,139,61,95,151,9,178,149,221,72,209,142,191,179,218, +155,234,46,78,218,201,138,99,21,240,171,157,215,99,215,127,95,32,237,192, +186,231,146,229,0,134,243,47,95,127,107,242,105,178,0,234,2,174,251,196, +87,241,252,254,167,240,251,87,110,130,101,110,159,8,64,201,42,197,25,122, +14,191,141,127,30,26,154,176,202,79,215,241,40,82,111,171,38,108,239,123, +1,143,223,185,9,167,131,231,249,185,93,107,51,77,109,235,142,89,161,45, +232,61,254,20,174,255,228,45,216,214,179,25,253,56,51,1,128,25,29,29,233, +222,191,247,165,14,83,221,171,107,27,81,218,189,52,120,46,198,198,203,89, +199,1,82,237,161,84,14,57,184,9,138,141,85,49,56,141,61,253,91,147,215, +106,170,173,91,61,7,97,189,247,228,102,172,92,186,26,78,238,81,156,185, +23,191,233,90,135,27,5,64,249,183,15,220,245,77,158,231,214,53,40,106,249, +149,157,139,190,240,229,91,55,148,34,229,46,189,252,34,28,62,62,84,155, +180,237,131,45,216,119,224,16,154,189,185,248,215,32,48,26,29,227,230,48, +125,31,88,235,150,104,7,135,30,199,167,22,95,138,151,251,122,59,165,21, +16,135,37,218,155,180,147,117,1,120,43,190,116,75,151,202,55,192,229,98, +50,171,177,128,43,23,180,214,250,192,83,197,113,184,121,15,33,171,64,142, +146,57,202,253,99,250,30,223,100,171,175,150,77,203,170,96,239,161,94,84, +70,176,83,26,40,59,235,205,139,153,85,143,57,126,16,224,146,15,205,199, +200,88,9,7,95,63,130,254,58,49,72,15,216,58,247,60,52,55,180,2,39,128,138, +117,20,110,97,10,0,38,21,97,24,164,183,22,189,13,28,1,250,246,125,22,59, +239,219,253,61,62,10,166,107,74,237,144,43,221,249,173,179,241,145,243, +91,49,52,60,198,42,9,106,85,224,58,14,90,102,55,66,7,14,230,235,118,252, +236,209,191,167,59,226,100,255,226,156,225,173,190,41,29,58,240,6,240,218, +222,14,52,15,175,238,6,118,15,10,121,211,1,8,255,253,143,238,239,179,149, +248,249,210,37,23,163,253,210,54,52,53,53,162,138,96,100,164,136,158,215, +6,240,106,207,235,56,177,235,227,63,218,181,109,255,171,211,244,228,206, +53,63,197,54,39,15,244,31,4,118,108,199,238,23,31,236,94,15,116,191,197, +119,195,226,103,186,180,113,8,22,180,204,91,176,240,186,155,215,220,61, +235,188,150,142,180,91,54,217,26,192,69,106,120,168,123,235,99,15,223,55, +116,242,216,0,31,142,72,207,57,197,60,205,43,31,196,127,58,174,0,254,186, +3,67,127,190,27,215,242,217,241,204,121,233,221,0,200,10,233,138,22,104, +243,104,77,147,126,67,132,153,83,17,238,219,82,73,211,48,48,239,134,135, +112,130,26,24,217,122,23,174,225,253,97,218,96,61,216,247,250,113,106,103, +108,184,147,26,102,209,117,165,26,197,187,140,111,166,93,144,205,115,148, +118,74,132,55,233,55,235,255,245,144,69,191,33,187,30,155,236,92,142,255, +9,48,0,241,195,153,86,37,156,12,221,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_23 = 2051; +static unsigned char xml_res_file_23[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, 60,0,0,7,165,73,68,65,84,120,218,156,87,107,112,21,103,25,126,190,221,61, 187,231,228,228,2,185,181,73,4,148,66,130,117,200,52,182,214,81,42,14,45, 86,7,80,212,233,216,17,157,78,127,56,26,188,212,209,254,160,25,172,12,242, @@ -1553,8 +1652,8 @@ static unsigned char xml_res_file_22[] = { 250,58,190,198,55,48,18,49,104,115,122,47,134,29,3,118,202,219,228,255, 5,24,0,238,123,163,24,29,62,142,101,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_23 = 1382; -static unsigned char xml_res_file_23[] = { +static size_t xml_res_size_24 = 1382; +static unsigned char xml_res_file_24[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1623,8 +1722,8 @@ static unsigned char xml_res_file_23[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_24 = 124939; -static unsigned char xml_res_file_24[] = { +static size_t xml_res_size_25 = 125407; +static unsigned char xml_res_file_25[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, 32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, @@ -6527,113 +6626,179 @@ static unsigned char xml_res_file_24[] = { 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47,116,111,111, -108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109, -112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, -76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80,89,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, 101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101, +114,95,103,111,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, -101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108,103,34, -62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84, -95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78, -95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, -108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110,97,103,101, -114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, -101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, -115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, -65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, +84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,68,101, +108,101,116,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,100,101,108, +101,116,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79, +68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117,105,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,111,111,114, +95,105,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97,100,101,114, +77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,32,83,104, +97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73, +78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, +70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,46,46, +46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,85,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,111,118,101,32,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118, +101,32,100,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, 68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6645,135 +6810,91 @@ static unsigned char xml_res_file_24[] = { 60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, -110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101,32,117,112, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,112,112, +108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -65,112,112,108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, -76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105, -97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82, -101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, -108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, -76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, -101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116, -105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, -49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, -97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81, -85,69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116, -61,34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, +108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82,101, +109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, +47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85, +69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61, +34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -7283,8 +7404,9 @@ void InitXmlResource() XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_24, xml_res_size_24, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_go.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_24, xml_res_size_24, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$._pc.xrc")); } diff --git a/src/wx-utils.cc b/src/wx-utils.cc index 707349e..e633373 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -1,772 +1,777 @@ -#include "wx-utils.h" - -#include -#ifndef WX_PRECOMP -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "wx-dialogbox.h" -#include "wx-app.h" -#include "wx-common.h" -#include "wx-status.h" - -extern "C" -{ -#include "thread.h" -} - -int confirm() -{ - if (emulation_state != EMULATION_STOPPED) { - return wx_messagebox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", WX_MB_OKCANCEL) == WX_IDOK; - } - return 1; -} - -int wx_messagebox(void* window, const char* message, const char* title = NULL, int style = 5) -{ - return wxMessageBox(message, title, style | wxCENTRE | wxSTAY_ON_TOP, (wxWindow*) window); -} - -void wx_simple_messagebox(const char* title, const char *format, ...) -{ - char message[2048]; - va_list ap; - va_start(ap, format); - vsnprintf(message, 2047, format, ap); - message[2047] = 0; - va_end(ap); - wx_messagebox(0, message, title, WX_MB_OK); -} - - -int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, unsigned int min_length, unsigned int max_length, LONG_PARAM result) -{ - while (1) - { - wxTextEntryDialog dlg((wxWindow*)window, message, title, value); - if (max_length > 0) - dlg.SetMaxLength(max_length); - if (dlg.ShowModal() == wxID_OK) - { - wxString value = dlg.GetValue(); - if (value.Length() >= min_length) - { - strcpy((char*)result, value.mb_str()); - return TRUE; - } - } - else - return FALSE; - } - return FALSE; -} - -void wx_setwindowtitle(void* window, char* s) -{ - ((wxFrame*) window)->SetTitle(s); -} - -int wx_xrcid(const char* s) -{ - return XRCID(s); -} - -int wx_filedialog(void* window, const char* title, const char* path, - const char* extensions, const char* extension, int open, char* file) -{ - wxFileDialog dlg((wxWindow*) window, title, "", path, extensions, - open ? (wxFD_OPEN | wxFD_FILE_MUST_EXIST) : (wxFD_SAVE | wxFD_OVERWRITE_PROMPT)); - if (dlg.ShowModal() == wxID_OK) - { - wxString p = dlg.GetPath(); - wxFileName f(p); - if (!open && !f.HasExt() && extension) - { - wxString e = extension; - if (!p.EndsWith(".")) - p += "."; - p += extension; - strcpy(file, p.mb_str()); - } - else - strcpy(file, p.mb_str()); - return 0; - } - return 1; -} - -void wx_checkmenuitem(void* menu, int id, int checked) -{ - wxMenuItem* item = NULL; - if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) - item = ((wxMenuBar*) menu)->FindItem(id); - else - item = ((wxMenu*) menu)->FindItem(id); - - if (item) - item->Check(checked); - else - std::cout << "Menu item not found: " << id << std::endl; -} - -void wx_enablemenuitem(void* menu, int id, int enable) -{ - wxMenuItem* item = NULL; - if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) - item = ((wxMenuBar*) menu)->FindItem(id); - else - item = ((wxMenu*) menu)->FindItem(id); - - if (item) - item->Enable(enable); - else - std::cout << "Menu item not found: " << id << std::endl; -} - -void* wx_getsubmenu(void* menu, int id) -{ - wxMenuItem* m = ((wxMenu*) menu)->FindItem(id); - if (m) - return m->GetSubMenu(); - - return 0; -} - -void* wx_getnativemenu(void* menu) -{ -#ifdef _WIN32 - return ((wxMenu*)menu)->GetHMenu(); -#endif - return 0; -} - -void* wx_getnativewindow(void* window) -{ -#ifdef _WIN32 - return ((wxWindow*)window)->GetHWND(); -#endif - return 0; -} - -#ifdef _WIN32 -void wx_winsendmessage(void* window, int msg, INT_PARAM wParam, LONG_PARAM lParam) -{ - WinSendMessageEvent* event = new WinSendMessageEvent(wx_getnativewindow(window), msg, wParam, lParam); - wxQueueEvent((wxWindow*)window, event); -} -#endif - -void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type) -{ - ((wxMenu*) sub_menu)->Append(id, title, wxEmptyString, type); -} - - -void wx_enabletoolbaritem(void* toolbar, int id, int enable) -{ - ((wxToolBar*) toolbar)->EnableTool(id, enable); -} - -void* wx_getmenu(void* window) -{ - return ((Frame*) window)->GetMenu(); -} - -void* wx_getmenubar(void* window) -{ - return ((wxFrame*) window)->GetMenuBar(); -} - -void* wx_gettoolbar(void* window) -{ - return ((wxFrame*) window)->GetToolBar(); -} - -void* wx_getdlgitem(void* window, int id) -{ - return ((wxWindow*) window)->FindWindow(id); -} - -void wx_setdlgitemtext(void* window, int id, char* str) -{ - wxWindow* w = ((wxWindow*) window)->FindWindow(id); - if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - ((wxTextCtrl*) w)->SetValue(str); - else - ((wxStaticText*) w)->SetLabel(str); -} - -void wx_enablewindow(void* window, int enabled) -{ - ((wxWindow*) window)->Enable(enabled); -} - -void wx_showwindow(void* window, int show) -{ - wxCommandEvent* event = new wxCommandEvent(WX_SHOW_WINDOW_EVENT, wxID_ANY); - event->SetEventObject((wxWindow*)window); - event->SetInt(show); - wxQueueEvent((wxWindow*)window, event); -} - -int wx_iswindowvisible(void* window) -{ - return ((wxWindow*) window)->IsShown(); -} - -void wx_togglewindow(void* window) -{ - wx_showwindow(window, -1); -} - -void wx_callback(void* window, WX_CALLBACK callback, void* data) -{ - CallbackEvent* event = new CallbackEvent(callback, data); - wxQueueEvent((wxWindow*)window, event); -} - -void wx_enddialog(void* window, int ret_code) -{ - ((wxDialog*) window)->EndModal(ret_code); -} - -int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type) -{ - wxWindow* w = ((wxWindow*) window)->FindWindow(id); - if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) - { - wxListBox* list = (wxListBox*)w; - list->Clear(); - wxArrayString items; - wxString f = wxFindFirstFile(path); - while (!f.empty()) - { - wxFileName file(f); - items.Add(file.GetName()); - f = wxFindNextFile(); - } - items.Sort(); - list->Set(items); - return TRUE; - } - return FALSE; -} - -int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id) -{ - wxWindow* w = ((wxWindow*) window)->FindWindow(id); - if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) - { - wxListBox* list = (wxListBox*)w; - strcpy((char*)path, (list->GetStringSelection() + ".").GetData().AsChar()); - return TRUE; - } - return FALSE; -} - -int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) -{ - switch (type) - { - case WX_CB_ADDSTRING: - ((wxComboBox*) window)->Append((char*) param2); - break; - case WX_CB_SETCURSEL: - if (param1 >= 0 && param1 < (int)((wxComboBox*) window)->GetCount()) - ((wxComboBox*) window)->Select(param1); - break; - case WX_CB_GETCURSEL: - return ((wxComboBox*) window)->GetCurrentSelection(); - break; - case WX_CB_GETLBTEXT: - strcpy((char*) param2, ((wxComboBox*) window)->GetString(param1).mb_str()); - break; - case WX_CB_RESETCONTENT: - { -#ifndef __WXOSX_MAC__ - ((wxComboBox*) window)->SetValue(""); - ((wxComboBox*) window)->Clear(); -#else - /* Clear() does not work on OSX */ - wxComboBox* cb = (wxComboBox*) window; - int count = cb->GetCount(); - while (count--) - cb->Delete(0); -#endif - break; - } - case WX_BM_SETCHECK: - ((wxCheckBox*) window)->SetValue(param1); - break; - case WX_BM_GETCHECK: - return ((wxCheckBox*) window)->GetValue(); - break; - case WX_WM_SETTEXT: - { - if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - ((wxTextCtrl*) window)->SetValue((char*) param2); - else - ((wxStaticText*) window)->SetLabel((char*) param2); - } - break; - case WX_WM_GETTEXT: - if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - strcpy((char*) param2, ((wxTextCtrl*) window)->GetValue().mb_str()); - else - strcpy((char*) param2, ((wxStaticText*) window)->GetLabel().mb_str()); - break; - case WX_UDM_SETPOS: - ((wxSpinCtrl*) window)->SetValue(param2); - break; - case WX_UDM_GETPOS: - return ((wxSpinCtrl*) window)->GetValue(); - case WX_UDM_SETRANGE: - { - int min = (param2 >> 16) & 0xffff; - int max = param2 & 0xffff; - ((wxSpinCtrl*) window)->SetRange(min, max); - break; - } - case WX_UDM_SETINCR: - { - /* SetIncrement-method may not exist on all platforms */ -#ifdef __WXGTK__ - ((wxSpinCtrl*) window)->SetIncrement(param2); -#endif - break; - } - case WX_LB_GETCOUNT: - { - return ((wxListBox*) window)->GetCount(); - } - case WX_LB_GETCURSEL: - { - return ((wxListBox*) window)->GetSelection(); - } - case WX_LB_SETCURSEL: - { - ((wxListBox*) window)->SetSelection(param1); - break; - } - case WX_LB_GETTEXT: - { - strcpy((char*) param2, ((wxListBox*) window)->GetString(param1).mb_str()); - break; - } - case WX_LB_INSERTSTRING: - { - ((wxListBox*) window)->Insert((char*) param2, param1); - break; - } - case WX_LB_DELETESTRING: - { - ((wxListBox*) window)->Delete(param1); - break; - } - case WX_LB_RESETCONTENT: - { - ((wxListBox*) window)->Clear(); - break; - } - } - - ((wxWindow*)window)->Fit(); - - return 0; -} - -int wx_dialogbox(void* window, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) -{ - PCemDialogBox dlg((wxWindow*) window, name, callback); - dlg.OnInit(); - dlg.Fit(); - int ret = dlg.ShowModal(); - dlg.Destroy(); - return ret; -} - -void wx_exit(void* window, int value) -{ - wxCommandEvent* event = new wxCommandEvent(WX_EXIT_EVENT, wxID_ANY); - event->SetEventObject((wxWindow*)window); - event->SetInt(value); - wxQueueEvent((wxWindow*)window, event); -} - -void wx_stop_emulation(void* window) -{ - wxCommandEvent* event = new wxCommandEvent(WX_STOP_EMULATION_EVENT, wxID_ANY); - event->SetEventObject((wxWindow*)window); - wxQueueEvent((wxWindow*)window, event); -} - -int wx_yield() -{ - return wxYield(); -} - -/* Timer stuff */ - -class PCemTimer : public wxTimer -{ -public: - PCemTimer(void (*fn)()) - { - this->fn = fn; - } - virtual ~PCemTimer() {}; - - void Notify() - { - fn(); - } -private: - void (*fn)(); -}; - -void* wx_createtimer(void (*fn)()) -{ - return new PCemTimer(fn); -} - -void wx_starttimer(void* timer, int milliseconds, int once) -{ - wxTimer* t = (wxTimer*)timer; - t->Start(milliseconds, once); -} - -void wx_stoptimer(void* timer) -{ - wxTimer* t = (wxTimer*)timer; - t->Stop(); -} - -void wx_destroytimer(void* timer) -{ - wx_stoptimer(timer); - delete (wxTimer*)timer; -} - -void wx_popupmenu(void* window, void* menu, int* x, int* y) -{ - PopupMenuEvent* event = new PopupMenuEvent((wxWindow*)window, (wxMenu*)menu, x, y); - wxQueueEvent((wxWindow*)window, event); -} - -void* wx_create_status_frame(void* window) -{ - StatusFrame* frame = new StatusFrame((wxWindow*)window); - return frame; -} - -void wx_destroy_status_frame(void* window) -{ - StatusFrame* frame = (StatusFrame*)window; - delete frame; -} - -void wx_setwindowposition(void* window, int x, int y) -{ - ((wxFrame*) window)->SetPosition(wxPoint(x, y)); -} - -void wx_setwindowsize(void* window, int width, int height) -{ - ((wxFrame*) window)->SetSize(wxSize(width, height)); -} - -void wx_show_status(void* window) -{ - wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); - if (!status) - { - StatusFrame* statusFrame = new StatusFrame((wxWindow*) window); - statusFrame->Show(); - } -} - -void wx_close_status(void* window) -{ - wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); - if (status) - { - status->Close(); - } -} - -void wx_get_home_directory(char* path) -{ - wxString home = wxFileName::GetHomeDir(); - if (!home.EndsWith(wxFileName::GetPathSeparator())) { - home.Append(wxFileName::GetPathSeparator()); - } - strcpy(path, home.mb_str()); -} - -int wx_create_directory(char* path) -{ - return wxFileName::Mkdir(path); -} - -int wx_setup(char* path) -{ - wxFileName p(path); - if (!p.DirExists()) - { - if (!p.Mkdir()) - return FALSE; - wxFileName configs(p); - configs.AppendDir("configs"); - if (!configs.DirExists() && !configs.Mkdir()) - return FALSE; - - wxFileName roms(p); - roms.AppendDir("roms"); - if (!roms.DirExists() && !roms.Mkdir()) - return FALSE; - - wxFileName nvr(p); - nvr.AppendDir("nvr"); - if (!nvr.DirExists() && !nvr.Mkdir()) - return FALSE; - - wxFileName screenshots(p); - screenshots.AppendDir("screenshots"); - if (!screenshots.DirExists() && !screenshots.Mkdir()) - return FALSE; - - wxFileName logs(p); - logs.AppendDir("logs"); - if (!logs.DirExists() && !logs.Mkdir()) - return FALSE; - } - - return TRUE; -} - -int wx_file_exists(char* path) -{ - wxFileName p(path); - return p.Exists(); -} - -int wx_dir_exists(char* path) -{ - wxFileName p(path); - return p.DirExists(); -} - -int wx_image_save(const char* path, const char* name, const char* format, unsigned char* rgba, int width, int height, int alpha) -{ - int x, y; - wxLogNull logNull; - wxImage image(width, height); - if (alpha) - { - unsigned char* rgb = (unsigned char*)malloc(width*height*3); - unsigned char* a = (unsigned char*)malloc(width*height); - for (x = 0; x < width; ++x) - { - for (y = 0; y < height; ++y) - { - rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; - rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; - rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; - a[y*width+x] = rgba[(y*width+x)*4+3]; - } - } - image.SetData(rgb); - image.SetAlpha(a); - } - else - image.SetData(rgba, true); - - wxImageHandler* h; - wxString ext; - - if (!strcmp(format, IMAGE_TIFF)) - { - h = new wxTIFFHandler(); - ext = "tif"; - } - else if (!strcmp(format, IMAGE_BMP)) - { - h = new wxBMPHandler(); - ext = "bmp"; - } - else if (!strcmp(format, IMAGE_JPG)) - { - h = new wxJPEGHandler(); - ext = "jpg"; - } - else - { - h = new wxPNGHandler(); - ext = "png"; - } - - int res = 0; - if (h) - { - wxString p(path); - if (!p.EndsWith("/")) - p = p.Append("/"); - p = p.Append(name).Append(".").Append(ext); - - wxFileOutputStream stream(p); - res = h->SaveFile(&image, stream, false); - delete h; - } - - return res; -} - -void* wx_image_load(const char* path) -{ - wxLogNull logNull; /* removes sRGB-warnings on Windows */ - wxImage* image = new wxImage(path); - if (image->IsOk()) - return image; - delete image; - return 0; -} - -void wx_image_free(void* image) -{ - delete (wxImage*)image; -} - -void wx_image_rescale(void* image, int width, int height) -{ - ((wxImage*)image)->Rescale(width, height); -} - -void wx_image_get_size(void* image, int* width, int* height) -{ - *width = ((wxImage*)image)->GetWidth(); - *height = ((wxImage*)image)->GetHeight(); -} - -unsigned char* wx_image_get_data(void* image) -{ - return ((wxImage*)image)->GetData(); -} - -unsigned char* wx_image_get_alpha(void* image) -{ - return ((wxImage*)image)->GetAlpha(); -} - -/* wxFileConfig */ - -void* wx_config_load(const char* path) -{ - if (!wxFileExists(path)) - return 0; - wxFileInputStream stream(path); - if (stream.IsOk()) - return new wxFileConfig(stream); - return 0; -} -int wx_config_get_string(void* config, const char* name, char* dst, int size, const char* defVal) -{ - wxFileConfig* c = ((wxFileConfig*)config); - wxString val; - bool res = c->Read(name, &val, wxString(defVal)); - strncpy(dst, val.GetData().AsChar(), size-1); - dst[size-1] = 0; - return res; -} -int wx_config_get_int(void* config, const char* name, int* dst, int defVal) -{ - wxFileConfig* c = ((wxFileConfig*)config); - return c->Read(name, dst, defVal); -} - -int wx_config_get_float(void* config, const char* name, float* dst, float defVal) -{ - wxFileConfig* c = ((wxFileConfig*)config); - return c->Read(name, dst, defVal); - -} - -int wx_config_get_bool(void* config, const char* name, int* dst, int defVal) -{ - wxFileConfig* c = ((wxFileConfig*)config); - wxString val; - bool res = 1; - if (c->Read(name, &val)) - { - val.LowerCase(); - if (val.StartsWith("true")) - *dst = 1; - else if (val.StartsWith("false")) - *dst = 0; - else - res = 0; - } - if (!res) - res = c->Read(name, (bool*)dst, (bool)defVal); - - return res; -} - -int wx_config_has_entry(void* config, const char* name) -{ - wxFileConfig* c = ((wxFileConfig*)config); - return c->HasEntry(name); -} - -void wx_config_free(void* config) -{ - delete (wxFileConfig*)config; -} - -typedef struct progress_data_t { - WX_CALLBACK callback; - void* data; - int active; - int result; -} progress_data_t; - -static void progress_callback(void* data) -{ - progress_data_t* d = (progress_data_t*) data; - d->result = d->callback(d->data); - d->active = 0; -} - -int wx_progressdialogpulse(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data) -{ - struct progress_data_t pdata; - pdata.callback = callback; - pdata.data = data; - pdata.active = 1; - pdata.result = 0; - - thread_t* t = thread_create(progress_callback, &pdata); - - wxProgressDialog dlg(title, message, 100, (wxWindow*)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); - while (pdata.active) - { - dlg.Pulse(); - wxMilliSleep(50); - } - thread_kill(t); - - return pdata.result; -} - -void wx_date_format(char* s, const char* format) -{ - wxString res = wxDateTime::Now().Format(format); - strcpy(s, res.mb_str()); -} +#include "wx-utils.h" + +#include +#ifndef WX_PRECOMP +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "wx-dialogbox.h" +#include "wx-app.h" +#include "wx-common.h" +#include "wx-status.h" + +extern "C" +{ +#include "thread.h" +} + +int confirm() +{ + if (emulation_state != EMULATION_STOPPED) { + return wx_messagebox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", WX_MB_OKCANCEL) == WX_IDOK; + } + return 1; +} + +int wx_messagebox(void* window, const char* message, const char* title = NULL, int style = 5) +{ + return wxMessageBox(message, title, style | wxCENTRE | wxSTAY_ON_TOP, (wxWindow*) window); +} + +void wx_simple_messagebox(const char* title, const char *format, ...) +{ + char message[2048]; + va_list ap; + va_start(ap, format); + vsnprintf(message, 2047, format, ap); + message[2047] = 0; + va_end(ap); + wx_messagebox(0, message, title, WX_MB_OK); +} + + +int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, unsigned int min_length, unsigned int max_length, LONG_PARAM result) +{ + while (1) + { + wxTextEntryDialog dlg((wxWindow*)window, message, title, value); + if (max_length > 0) + dlg.SetMaxLength(max_length); + if (dlg.ShowModal() == wxID_OK) + { + wxString value = dlg.GetValue(); + if (value.Length() >= min_length) + { + strcpy((char*)result, value.mb_str()); + return TRUE; + } + } + else + return FALSE; + } + return FALSE; +} + +void wx_setwindowtitle(void* window, char* s) +{ + ((wxFrame*) window)->SetTitle(s); +} + +int wx_xrcid(const char* s) +{ + return XRCID(s); +} + +int wx_filedialog(void* window, const char* title, const char* path, + const char* extensions, const char* extension, int open, char* file) +{ + wxFileDialog dlg((wxWindow*) window, title, "", path, extensions, + open ? (wxFD_OPEN | wxFD_FILE_MUST_EXIST) : (wxFD_SAVE | wxFD_OVERWRITE_PROMPT)); + if (dlg.ShowModal() == wxID_OK) + { + wxString p = dlg.GetPath(); + wxFileName f(p); + if (!open && !f.HasExt() && extension) + { + wxString e = extension; + if (!p.EndsWith(".")) + p += "."; + p += extension; + strcpy(file, p.mb_str()); + } + else + strcpy(file, p.mb_str()); + return 0; + } + return 1; +} + +void wx_checkmenuitem(void* menu, int id, int checked) +{ + wxMenuItem* item = NULL; + if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar*) menu)->FindItem(id); + else + item = ((wxMenu*) menu)->FindItem(id); + + if (item) + item->Check(checked); + else + std::cout << "Menu item not found: " << id << std::endl; +} + +void wx_enablemenuitem(void* menu, int id, int enable) +{ + wxMenuItem* item = NULL; + if (((wxObject*)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar*) menu)->FindItem(id); + else + item = ((wxMenu*) menu)->FindItem(id); + + if (item) + item->Enable(enable); + else + std::cout << "Menu item not found: " << id << std::endl; +} + +void* wx_getsubmenu(void* menu, int id) +{ + wxMenuItem* m = ((wxMenu*) menu)->FindItem(id); + if (m) + return m->GetSubMenu(); + + return 0; +} + +void* wx_getnativemenu(void* menu) +{ +#ifdef _WIN32 + return ((wxMenu*)menu)->GetHMenu(); +#endif + return 0; +} + +void* wx_getnativewindow(void* window) +{ +#ifdef _WIN32 + return ((wxWindow*)window)->GetHWND(); +#endif + return 0; +} + +#ifdef _WIN32 +void wx_winsendmessage(void* window, int msg, INT_PARAM wParam, LONG_PARAM lParam) +{ + WinSendMessageEvent* event = new WinSendMessageEvent(wx_getnativewindow(window), msg, wParam, lParam); + wxQueueEvent((wxWindow*)window, event); +} +#endif + +void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type) +{ + ((wxMenu*) sub_menu)->Append(id, title, wxEmptyString, type); +} + + +void wx_enabletoolbaritem(void* toolbar, int id, int enable) +{ + ((wxToolBar*) toolbar)->EnableTool(id, enable); +} + +void* wx_getmenu(void* window) +{ + return ((Frame*) window)->GetMenu(); +} + +void* wx_getmenubar(void* window) +{ + return ((wxFrame*) window)->GetMenuBar(); +} + +void* wx_gettoolbar(void* window) +{ + return ((wxFrame*) window)->GetToolBar(); +} + +void* wx_getdlgitem(void* window, int id) +{ + return ((wxWindow*) window)->FindWindow(id); +} + +void wx_setdlgitemtext(void* window, int id, char* str) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl*) w)->SetValue(str); + else + ((wxStaticText*) w)->SetLabel(str); +} + +void wx_enablewindow(void* window, int enabled) +{ + ((wxWindow*) window)->Enable(enabled); +} + +void wx_showwindow(void* window, int show) +{ + wxCommandEvent* event = new wxCommandEvent(WX_SHOW_WINDOW_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + event->SetInt(show); + wxQueueEvent((wxWindow*)window, event); +} + +int wx_iswindowvisible(void* window) +{ + return ((wxWindow*) window)->IsShown(); +} + +void wx_togglewindow(void* window) +{ + wx_showwindow(window, -1); +} + +void wx_callback(void* window, WX_CALLBACK callback, void* data) +{ + CallbackEvent* event = new CallbackEvent(callback, data); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_enddialog(void* window, int ret_code) +{ + ((wxDialog*) window)->EndModal(ret_code); +} + +int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) + { + wxListBox* list = (wxListBox*)w; + list->Clear(); + wxArrayString items; + wxString f = wxFindFirstFile(path); + while (!f.empty()) + { + wxFileName file(f); + items.Add(file.GetName()); + f = wxFindNextFile(); + } + items.Sort(); + list->Set(items); + return TRUE; + } + return FALSE; +} + +int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id) +{ + wxWindow* w = ((wxWindow*) window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) + { + wxListBox* list = (wxListBox*)w; + strcpy((char*)path, (list->GetStringSelection() + ".").GetData().AsChar()); + return TRUE; + } + return FALSE; +} + +int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) +{ + switch (type) + { + case WX_CB_ADDSTRING: + ((wxComboBox*) window)->Append((char*) param2); + break; + case WX_CB_SETCURSEL: + if (param1 >= 0 && param1 < (int)((wxComboBox*) window)->GetCount()) + ((wxComboBox*) window)->Select(param1); + break; + case WX_CB_GETCURSEL: + return ((wxComboBox*) window)->GetCurrentSelection(); + break; + case WX_CB_GETLBTEXT: + strcpy((char*) param2, ((wxComboBox*) window)->GetString(param1).mb_str()); + break; + case WX_CB_RESETCONTENT: + { +#ifndef __WXOSX_MAC__ + ((wxComboBox*) window)->SetValue(""); + ((wxComboBox*) window)->Clear(); +#else + /* Clear() does not work on OSX */ + wxComboBox* cb = (wxComboBox*) window; + int count = cb->GetCount(); + while (count--) + cb->Delete(0); +#endif + break; + } + case WX_BM_SETCHECK: + ((wxCheckBox*) window)->SetValue(param1); + break; + case WX_BM_GETCHECK: + return ((wxCheckBox*) window)->GetValue(); + break; + case WX_WM_SETTEXT: + { + if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl*) window)->SetValue((char*) param2); + else + ((wxStaticText*) window)->SetLabel((char*) param2); + } + break; + case WX_WM_GETTEXT: + if (((wxWindow*) window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + strcpy((char*) param2, ((wxTextCtrl*) window)->GetValue().mb_str()); + else + strcpy((char*) param2, ((wxStaticText*) window)->GetLabel().mb_str()); + break; + case WX_UDM_SETPOS: + ((wxSpinCtrl*) window)->SetValue(param2); + break; + case WX_UDM_GETPOS: + return ((wxSpinCtrl*) window)->GetValue(); + case WX_UDM_SETRANGE: + { + int min = (param2 >> 16) & 0xffff; + int max = param2 & 0xffff; + ((wxSpinCtrl*) window)->SetRange(min, max); + break; + } + case WX_UDM_SETINCR: + { + /* SetIncrement-method may not exist on all platforms */ +#ifdef __WXGTK__ + ((wxSpinCtrl*) window)->SetIncrement(param2); +#endif + break; + } + case WX_LB_GETCOUNT: + { + return ((wxListBox*) window)->GetCount(); + } + case WX_LB_GETCURSEL: + { + return ((wxListBox*) window)->GetSelection(); + } + case WX_LB_SETCURSEL: + { + ((wxListBox*) window)->SetSelection(param1); + break; + } + case WX_LB_GETTEXT: + { + strcpy((char*) param2, ((wxListBox*) window)->GetString(param1).mb_str()); + break; + } + case WX_LB_INSERTSTRING: + { + ((wxListBox*) window)->Insert((char*) param2, param1); + break; + } + case WX_LB_DELETESTRING: + { + ((wxListBox*) window)->Delete(param1); + break; + } + case WX_LB_RESETCONTENT: + { + ((wxListBox*) window)->Clear(); + break; + } + } + + ((wxWindow*)window)->Fit(); + + return 0; +} + +int wx_dialogbox(void* window, const char* name, int (*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)) +{ + PCemDialogBox dlg((wxWindow*) window, name, callback); + dlg.OnInit(); + dlg.Fit(); + int ret = dlg.ShowModal(); + dlg.Destroy(); + return ret; +} + +void wx_exit(void* window, int value) +{ + wxCommandEvent* event = new wxCommandEvent(WX_EXIT_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + event->SetInt(value); + wxQueueEvent((wxWindow*)window, event); +} + +void wx_stop_emulation(void* window) +{ + wxCommandEvent* event = new wxCommandEvent(WX_STOP_EMULATION_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + wxQueueEvent((wxWindow*)window, event); +} + +int wx_yield() +{ + return wxYield(); +} + +/* Timer stuff */ + +class PCemTimer : public wxTimer +{ +public: + PCemTimer(void (*fn)()) + { + this->fn = fn; + } + virtual ~PCemTimer() {}; + + void Notify() + { + fn(); + } +private: + void (*fn)(); +}; + +void* wx_createtimer(void (*fn)()) +{ + return new PCemTimer(fn); +} + +void wx_starttimer(void* timer, int milliseconds, int once) +{ + wxTimer* t = (wxTimer*)timer; + t->Start(milliseconds, once); +} + +void wx_stoptimer(void* timer) +{ + wxTimer* t = (wxTimer*)timer; + t->Stop(); +} + +void wx_destroytimer(void* timer) +{ + wx_stoptimer(timer); + delete (wxTimer*)timer; +} + +void wx_popupmenu(void* window, void* menu, int* x, int* y) +{ + PopupMenuEvent* event = new PopupMenuEvent((wxWindow*)window, (wxMenu*)menu, x, y); + wxQueueEvent((wxWindow*)window, event); +} + +void* wx_create_status_frame(void* window) +{ + StatusFrame* frame = new StatusFrame((wxWindow*)window); + return frame; +} + +void wx_destroy_status_frame(void* window) +{ + StatusFrame* frame = (StatusFrame*)window; + delete frame; +} + +void wx_setwindowposition(void* window, int x, int y) +{ + ((wxFrame*) window)->SetPosition(wxPoint(x, y)); +} + +void wx_setwindowsize(void* window, int width, int height) +{ + ((wxFrame*) window)->SetSize(wxSize(width, height)); +} + +void wx_show_status(void* window) +{ + wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); + if (!status) + { + StatusFrame* statusFrame = new StatusFrame((wxWindow*) window); + statusFrame->Show(); + } +} + +void wx_close_status(void* window) +{ + wxWindow* status = ((wxWindow*)window)->FindWindowById(STATUS_WINDOW_ID); + if (status) + { + status->Close(); + } +} + +void wx_get_home_directory(char* path) +{ + wxString home = wxFileName::GetHomeDir(); + if (!home.EndsWith(wxFileName::GetPathSeparator())) { + home.Append(wxFileName::GetPathSeparator()); + } + strcpy(path, home.mb_str()); +} + +int wx_create_directory(char* path) +{ + return wxFileName::Mkdir(path); +} + +int wx_setup(char* path) +{ + wxFileName p(path); + if (!p.DirExists()) + { + if (!p.Mkdir()) + return FALSE; + wxFileName configs(p); + configs.AppendDir("configs"); + if (!configs.DirExists() && !configs.Mkdir()) + return FALSE; + + wxFileName roms(p); + roms.AppendDir("roms"); + if (!roms.DirExists() && !roms.Mkdir()) + return FALSE; + + wxFileName nvr(p); + nvr.AppendDir("nvr"); + if (!nvr.DirExists() && !nvr.Mkdir()) + return FALSE; + + wxFileName screenshots(p); + screenshots.AppendDir("screenshots"); + if (!screenshots.DirExists() && !screenshots.Mkdir()) + return FALSE; + + wxFileName logs(p); + logs.AppendDir("logs"); + if (!logs.DirExists() && !logs.Mkdir()) + return FALSE; + } + + return TRUE; +} + +int wx_file_exists(char* path) +{ + wxFileName p(path); + return p.Exists(); +} + +int wx_dir_exists(char* path) +{ + wxFileName p(path); + return p.DirExists(); +} + +int wx_copy_file(char* from, char* to, int overwrite) +{ + return wxCopyFile(from, to, overwrite); +} + +int wx_image_save(const char* path, const char* name, const char* format, unsigned char* rgba, int width, int height, int alpha) +{ + int x, y; + wxLogNull logNull; + wxImage image(width, height); + if (alpha) + { + unsigned char* rgb = (unsigned char*)malloc(width*height*3); + unsigned char* a = (unsigned char*)malloc(width*height); + for (x = 0; x < width; ++x) + { + for (y = 0; y < height; ++y) + { + rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; + rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; + rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; + a[y*width+x] = rgba[(y*width+x)*4+3]; + } + } + image.SetData(rgb); + image.SetAlpha(a); + } + else + image.SetData(rgba, true); + + wxImageHandler* h; + wxString ext; + + if (!strcmp(format, IMAGE_TIFF)) + { + h = new wxTIFFHandler(); + ext = "tif"; + } + else if (!strcmp(format, IMAGE_BMP)) + { + h = new wxBMPHandler(); + ext = "bmp"; + } + else if (!strcmp(format, IMAGE_JPG)) + { + h = new wxJPEGHandler(); + ext = "jpg"; + } + else + { + h = new wxPNGHandler(); + ext = "png"; + } + + int res = 0; + if (h) + { + wxString p(path); + if (!p.EndsWith("/")) + p = p.Append("/"); + p = p.Append(name).Append(".").Append(ext); + + wxFileOutputStream stream(p); + res = h->SaveFile(&image, stream, false); + delete h; + } + + return res; +} + +void* wx_image_load(const char* path) +{ + wxLogNull logNull; /* removes sRGB-warnings on Windows */ + wxImage* image = new wxImage(path); + if (image->IsOk()) + return image; + delete image; + return 0; +} + +void wx_image_free(void* image) +{ + delete (wxImage*)image; +} + +void wx_image_rescale(void* image, int width, int height) +{ + ((wxImage*)image)->Rescale(width, height); +} + +void wx_image_get_size(void* image, int* width, int* height) +{ + *width = ((wxImage*)image)->GetWidth(); + *height = ((wxImage*)image)->GetHeight(); +} + +unsigned char* wx_image_get_data(void* image) +{ + return ((wxImage*)image)->GetData(); +} + +unsigned char* wx_image_get_alpha(void* image) +{ + return ((wxImage*)image)->GetAlpha(); +} + +/* wxFileConfig */ + +void* wx_config_load(const char* path) +{ + if (!wxFileExists(path)) + return 0; + wxFileInputStream stream(path); + if (stream.IsOk()) + return new wxFileConfig(stream); + return 0; +} +int wx_config_get_string(void* config, const char* name, char* dst, int size, const char* defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + wxString val; + bool res = c->Read(name, &val, wxString(defVal)); + strncpy(dst, val.GetData().AsChar(), size-1); + dst[size-1] = 0; + return res; +} +int wx_config_get_int(void* config, const char* name, int* dst, int defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + return c->Read(name, dst, defVal); +} + +int wx_config_get_float(void* config, const char* name, float* dst, float defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + return c->Read(name, dst, defVal); + +} + +int wx_config_get_bool(void* config, const char* name, int* dst, int defVal) +{ + wxFileConfig* c = ((wxFileConfig*)config); + wxString val; + bool res = 1; + if (c->Read(name, &val)) + { + val.LowerCase(); + if (val.StartsWith("true")) + *dst = 1; + else if (val.StartsWith("false")) + *dst = 0; + else + res = 0; + } + if (!res) + res = c->Read(name, (bool*)dst, (bool)defVal); + + return res; +} + +int wx_config_has_entry(void* config, const char* name) +{ + wxFileConfig* c = ((wxFileConfig*)config); + return c->HasEntry(name); +} + +void wx_config_free(void* config) +{ + delete (wxFileConfig*)config; +} + +typedef struct progress_data_t { + WX_CALLBACK callback; + void* data; + int active; + int result; +} progress_data_t; + +static void progress_callback(void* data) +{ + progress_data_t* d = (progress_data_t*) data; + d->result = d->callback(d->data); + d->active = 0; +} + +int wx_progressdialogpulse(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data) +{ + struct progress_data_t pdata; + pdata.callback = callback; + pdata.data = data; + pdata.active = 1; + pdata.result = 0; + + thread_t* t = thread_create(progress_callback, &pdata); + + wxProgressDialog dlg(title, message, 100, (wxWindow*)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); + while (pdata.active) + { + dlg.Pulse(); + wxMilliSleep(50); + } + thread_kill(t); + + return pdata.result; +} + +void wx_date_format(char* s, const char* format) +{ + wxString res = wxDateTime::Now().Format(format); + strcpy(s, res.mb_str()); +} diff --git a/src/wx-utils.h b/src/wx-utils.h index ab57a21..f06b055 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -77,6 +77,7 @@ extern "C" { int wx_setup(char* path); int wx_file_exists(char* path); int wx_dir_exists(char* path); + int wx_copy_file(char* from, char* to, int overwrite); void wx_date_format(char* s, const char* format); From 47f9a66859617bf7273a56ab6faf72a92ed103ba Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Aug 2017 21:31:40 +0100 Subject: [PATCH 0138/1050] Fixed issue when serial ports mapped at unusual addresses - fixes joystick on 430VX model. --- src/serial.c | 14 ++++++-------- src/serial.h | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/serial.c b/src/serial.c index 5b40691..f638e22 100644 --- a/src/serial.c +++ b/src/serial.c @@ -254,6 +254,7 @@ 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.addr = addr; serial1.rcr_callback = NULL; timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); } @@ -262,13 +263,11 @@ 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; + serial1.addr = addr; } void serial1_remove() { - 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(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(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } void serial2_init(uint16_t addr, int irq) @@ -276,6 +275,7 @@ void serial2_init(uint16_t addr, int irq) memset(&serial2, 0, sizeof(serial2)); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); serial2.irq = irq; + serial2.addr = addr; serial2.rcr_callback = NULL; timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); } @@ -284,11 +284,9 @@ 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; + serial2.addr = addr; } void serial2_remove() { - 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(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(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); } diff --git a/src/serial.h b/src/serial.h index 748ad07..930292a 100644 --- a/src/serial.h +++ b/src/serial.h @@ -18,6 +18,7 @@ typedef struct uint8_t fcr; int irq; + uint16_t addr; void (*rcr_callback)(struct SERIAL *serial, void *p); void *rcr_callback_p; From 9b84ce5218677876d74c0139e319558122068509 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 23 Aug 2017 20:17:32 +0100 Subject: [PATCH 0139/1050] Add IO configuration to Commodore PC 30 III. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/cbm_io.c | 39 ++++++++++++++++++++++++++++++ src/cbm_io.h | 1 + src/model.c | 10 +++++++- 14 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 src/cbm_io.c create mode 100644 src/cbm_io.h diff --git a/src/Makefile.am b/src/Makefile.am index 725252f..c9a7652 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ slirp/libslirp.a: amrefresh: -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 6fa47a8..3bc4ec2 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -5,7 +5,7 @@ CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m32 LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 7b10f0e..cb8f5a1 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index cf89b39..7b356b2 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -4,7 +4,7 @@ CC = gcc CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 06e9b39..dc3baa8 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 109687a..109d18a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 8d29cb5..509c330 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -4,7 +4,7 @@ CC = gcc.exe MAKE = make.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -DUSE_NETWORKING -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index abe74a2..f8d2254 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = C:/MinGW/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 9085f5e..3652a39 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = C:/MinGW/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index f90e677..b67ff1b 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 2b714a6..b9175d0 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -3,7 +3,7 @@ CPP = g++ CC = gcc WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/cbm_io.c b/src/cbm_io.c new file mode 100644 index 0000000..ec73560 --- /dev/null +++ b/src/cbm_io.c @@ -0,0 +1,39 @@ +#include "ibm.h" + +#include "io.h" +#include "lpt.h" +#include "serial.h" + +static void cbm_io_write(uint16_t port, uint8_t val, void *p) +{ + serial1_remove(); + serial2_remove(); + lpt1_remove(); + lpt2_remove(); + switch (val & 3) + { + case 1: + lpt1_init(0x3bc); + break; + case 2: + lpt1_init(0x378); + break; + case 3: + lpt1_init(0x278); + break; + } + switch (val & 0xc) + { + case 0x4: + serial1_set(0x2f8, 3); + break; + case 0x8: + serial1_set(0x3f8, 4); + break; + } +} + +void cbm_io_init() +{ + io_sethandler(0x0230, 0x0001, NULL,NULL,NULL, cbm_io_write,NULL,NULL, NULL); +} diff --git a/src/cbm_io.h b/src/cbm_io.h new file mode 100644 index 0000000..1e3d5e6 --- /dev/null +++ b/src/cbm_io.h @@ -0,0 +1 @@ +void cbm_io_init(); diff --git a/src/model.c b/src/model.c index 8fecc2a..eaa424b 100644 --- a/src/model.c +++ b/src/model.c @@ -7,6 +7,7 @@ #include "acer386sx.h" #include "ali1429.h" #include "amstrad.h" +#include "cbm_io.h" #include "compaq.h" #include "dells200.h" #include "device.h" @@ -67,6 +68,7 @@ void olim24_init(); void at_init(); void ibm_at_init(); void at_ide_init(); +void at_cbm_init(); void dells200_init(); void deskpro386_init(); void ps1_m2011_init(); @@ -117,7 +119,7 @@ MODEL models[] = {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, - {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_ide_init, NULL}, + {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_cbm_init, NULL}, {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, @@ -332,6 +334,12 @@ void at_ide_init() mem_remap_top_384k(); } +void at_cbm_init() +{ + at_ide_init(); + cbm_io_init(); +} + void deskpro386_init() { at_init(); From 4cea3c7b04a689ef03c2f121fe1b9388428dc2c0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 31 Aug 2017 14:09:01 +0100 Subject: [PATCH 0140/1050] Numerous improvements to AWE32 emulation. Patch from JosepMa. --- src/sound_emu8k.c | 2315 ++++++++++++++++++++++++++++++++++++++------- src/sound_emu8k.h | 815 ++++++++++++++-- 2 files changed, 2710 insertions(+), 420 deletions(-) diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index 640eb06..c736e32 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -1,8 +1,3 @@ -/*12log2(r) * 4096 - - freq = 2^((in - 0xe000) / 4096)*/ -/*LFO - lowest (0.042 Hz) = 2^20 steps = 1048576 - highest (10.72 Hz) = 2^12 steps = 4096*/ #include #include #include "ibm.h" @@ -11,74 +6,479 @@ #include "sound.h" #include "sound_emu8k.h" #include "timer.h" +#include + +#if !defined FILTER_INITIAL && !defined FILTER_MOOG && !defined FILTER_CONSTANT +//#define FILTER_INITIAL +#define FILTER_MOOG +//#define FILTER_CONSTANT +#endif + +#if !defined RESAMPLER_LINEAR && !defined RESAMPLER_CUBIC +//#define RESAMPLER_LINEAR +#define RESAMPLER_CUBIC +#endif + +//#define EMU8K_DEBUG_REGISTERS + +char *PORT_NAMES[][8] = +{ + /* Data 0 ( 0x620/0x622) */ + { "AWE_CPF", + "AWE_PTRX", + "AWE_CVCF", + "AWE_VTFT", + "Unk-620-4", + "Unk-620-5", + "AWE_PSST", + "AWE_CSL", + }, + /* Data 1 0xA20 */ + { "AWE_CCCA", + 0, + /* + "AWE_HWCF4" + "AWE_HWCF5" + "AWE_HWCF6" + "AWE_HWCF7" + "AWE_SMALR" + "AWE_SMARR" + "AWE_SMALW" + "AWE_SMARW" + "AWE_SMLD" + "AWE_SMRD" + "AWE_WC" + "AWE_HWCF1" + "AWE_HWCF2" + "AWE_HWCF3" + */ + 0,//"AWE_INIT1", + 0,//"AWE_INIT3", + "AWE_ENVVOL", + "AWE_DCYSUSV", + "AWE_ENVVAL", + "AWE_DCYSUS", + }, + /* Data 2 0xA22 */ + { "AWE_CCCA", + 0, + 0,//"AWE_INIT2", + 0,//"AWE_INIT4", + "AWE_ATKHLDV", + "AWE_LFO1VAL", + "AWE_ATKHLD", + "AWE_LFO2VAL", + }, + /* Data 3 0xE20 */ + { "AWE_IP", + "AWE_IFATN", + "AWE_PEFE", + "AWE_FMMOD", + "AWE_TREMFRQ", + "AWE_FM2FRQ2", + 0, + 0, + }, +}; enum { ENV_STOPPED = 0, - ENV_ATTACK = 1, - ENV_DECAY = 2, - ENV_SUSTAIN = 3, - ENV_RELEASE = 4 + ENV_DELAY = 1, + ENV_ATTACK = 2, + ENV_HOLD = 3, + //ENV_DECAY = 4, + ENV_SUSTAIN = 5, + //ENV_RELEASE = 6, + ENV_RAMP_DOWN = 7, + ENV_RAMP_UP = 8 }; + +static int random_helper = 0; +int dmareadbit = 0; +int dmawritebit = 0; + + +/* cubic and linear tables resolution. Note: higher than 10 does not improve the result. */ +#define CUBIC_RESOLUTION_LOG 10 +#define CUBIC_RESOLUTION (1<> 15 to move back to +/-1 range). */ +static int32_t lfotable[65536]; +/* Table to transform the speed parameter to emu8k_mem_internal_t range. */ +static int64_t lfofreqtospeed[256]; -#define READ16(addr, var) switch ((addr) & 2) \ +/* LFO used for the chorus. a sine wave.(signed 16bits with 32768 max int. >> 15 to move back to +/-1 range). */ +static double chortable[65536]; + +static const int REV_BUFSIZE_STEP=242; + + +/* These lines come from the awe32faq, describing the NRPN control for the initial filter + * where it describes a linear increment filter instead of an octave-incremented one. + * NRPN LSB 21 (Initial Filter Cutoff) + * Range : [0, 127] + * Unit : 62Hz + * Filter cutoff from 100Hz to 8000Hz + + * This table comes from the awe32faq, describing the NRPN control for the filter Q. + * I don't know if is meant to be interpreted as the actual measured output of the + * filter or what. Especially, I don't understand the "low" and "high" ranges. + * What is otherwise documented is that the Q ranges from 0dB to 24dB and the attenuation + * is half of the Q ( i.e. for 12dB Q, attenuate the input signal with -6dB) +Coeff Low Fc(Hz)Low Q(dB)High Fc(kHz)High Q(dB)DC Attenuation(dB) +* 0 92 5 Flat Flat -0.0 +* 1 93 6 8.5 0.5 -0.5 +* 2 94 8 8.3 1 -1.2 +* 3 95 10 8.2 2 -1.8 +* 4 96 11 8.1 3 -2.5 +* 5 97 13 8.0 4 -3.3 +* 6 98 14 7.9 5 -4.1 +* 7 99 16 7.8 6 -5.5 +* 8 100 17 7.7 7 -6.0 +* 9 100 19 7.5 9 -6.6 +* 10 100 20 7.4 10 -7.2 +* 11 100 22 7.3 11 -7.9 +* 12 100 23 7.2 13 -8.5 +* 13 100 25 7.1 15 -9.3 +* 14 100 26 7.1 16 -10.1 +* 15 100 28 7.0 18 -11.0 +* +* Attenuation as above, codified in amplitude.*/ +static int32_t filter_atten[16] = +{ + 65536, 61869, 57079, 53269, 49145, 44820, 40877, 34792, 32845, 30653, 28607, + 26392, 24630, 22463, 20487, 18470 +}; + +/*Coefficients for the filters for a defined Q and cutoff.*/ +static int32_t filt_coeffs[16][256][3]; + +#define READ16_SWITCH(addr, var) switch ((addr) & 2) \ { \ case 0: ret = (var) & 0xffff; break; \ case 2: ret = ((var) >> 16) & 0xffff; break; \ } -#define WRITE16(addr, var, val) switch ((addr) & 2) \ +#define WRITE16_SWITCH(addr, var, val) switch ((addr) & 2) \ { \ case 0: var = (var & 0xffff0000) | (val); break; \ case 2: var = (var & 0x0000ffff) | ((val) << 16); break; \ } +#ifdef EMU8K_DEBUG_REGISTERS +uint32_t dw_value = 0; +uint32_t last_read = 0; +uint32_t last_write = 0; +uint32_t rep_count_r = 0; +uint32_t rep_count_w = 0; + +# define READ16(addr, var) READ16_SWITCH(addr, var) \ + { \ + const char *name=0; \ + switch(addr) \ + { \ + case 0x620: case 0x622: \ + name = PORT_NAMES[0][emu8k->cur_reg]; \ + break; \ + case 0xA20: \ + name = PORT_NAMES[1][emu8k->cur_reg]; \ + break; \ + case 0xA22: \ + name = PORT_NAMES[2][emu8k->cur_reg]; \ + break; \ + } \ + if (name == 0) \ + { \ + /*pclog("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_voice,ret);*/ \ + } \ + else \ + { \ + pclog("EMU8K READ %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice, ret); \ + }\ + } +# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) \ + { \ + const char *name=0; \ + switch(addr) \ + { \ + case 0x620: case 0x622: \ + name = PORT_NAMES[0][emu8k->cur_reg]; \ + break; \ + case 0xA20: \ + name = PORT_NAMES[1][emu8k->cur_reg]; \ + break; \ + case 0xA22: \ + name = PORT_NAMES[2][emu8k->cur_reg]; \ + break; \ + } \ + if (name == 0) \ + { \ + /*pclog("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, val);*/ \ + } \ + else \ + { \ + pclog("EMU8K WRITE %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice,val); \ + }\ + } + +#else +# define READ16(addr, var) READ16_SWITCH(addr, var) +# define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) +#endif //EMU8K_DEBUG_REGISTERS + + static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) { - addr &= 0xffffff; - if (addr < 0x80000) - return emu8k->rom[addr]; - if (addr < 0x200000 || addr >= emu8k->ram_end_addr) - return 0; - if (!emu8k->ram) - return 0; - return emu8k->ram[addr - 0x200000]; + const register emu8k_mem_pointers_t addrmem = {{addr}}; + return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; } -static inline int16_t EMU8K_READ_INTERP(emu8k_t *emu8k, uint32_t addr) +static inline int16_t EMU8K_READ_INTERP_LINEAR(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) { - 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; + /* The interpolation in AWE32 used a so-called patented 3-point interpolation + * ( I guess some sort of spline having one point before and one point after). + * Also, it has the consequence that the playback is delayed by one sample. + * I simulate the "one sample later" than the address with addr+1 and addr+2 + * instead of +0 and +1 */ + int16_t dat1 = EMU8K_READ(emu8k, int_addr+1); + int32_t dat2 = EMU8K_READ(emu8k, int_addr+2); + dat1 += ((dat2-(int32_t)dat1)* fract) >> 16; + return dat1; +} + +static inline int32_t EMU8K_READ_INTERP_CUBIC(emu8k_t *emu8k, uint32_t int_addr, uint16_t fract) +{ + /*Since there are four floats in the table for each fraction, the position is 16byte aligned. */ + fract >>= 16-CUBIC_RESOLUTION_LOG; + fract <<=2; + + /* TODO: I still have to verify how this works, but I think that + * the card could use two oscillators (usually 31 and 32) where it would + * be writing the OPL3 output, and to which, chorus and reverb could be applied to get + * those effects for OPL3 sounds.*/ +// if ((addr & EMU8K_FM_MEM_ADDRESS) == EMU8K_FM_MEM_ADDRESS) {} + + /* This is cubic interpolation. + * Not the same than 3-point interpolation, but a better approximation than linear + * interpolation. + * Also, it takes into account the "Note that the actual audio location is the point + * 1 word higher than this value due to interpolation offset". + * That's why the pointers are 0, 1, 2, 3 and not -1, 0, 1, 2 */ + int32_t dat2 = EMU8K_READ(emu8k, int_addr+1); + const float *table = &cubic_table[fract]; + const int32_t dat1 = EMU8K_READ(emu8k, int_addr); + const int32_t dat3 = EMU8K_READ(emu8k, int_addr+2); + const int32_t dat4 = EMU8K_READ(emu8k, int_addr+3); + /* Note: I've ended using float for the table values to avoid some cases of integer overflow. */ + dat2 = dat1*table[0] + dat2*table[1] + dat3*table[2] + dat4*table[3]; + return dat2; } static inline void EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) { - addr &= 0xffffff; - if (emu8k->ram && addr >= 0x200000 && addr < emu8k->ram_end_addr) - emu8k->ram[addr - 0x200000] = val; + addr &= EMU8K_MEM_ADDRESS_MASK; + if ( !emu8k->ram || addr < EMU8K_RAM_MEM_START || addr >= EMU8K_FM_MEM_ADDRESS ) + 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. */ + 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) { emu8k_t *emu8k = (emu8k_t *)p; uint16_t ret = 0xffff; -/* pclog("emu8k_inw %04X reg=%i voice=%i\n", addr, emu8k->cur_reg, emu8k->cur_voice);*/ - - addr -= 0x220; - switch (addr & 0xc02) + +#ifdef EMU8K_DEBUG_REGISTERS + if (addr == 0xE22) { - case 0x400: case 0x402: /*Data0*/ + pclog("EMU8K READ POINTER: %d\n", + ((0x80 | ((random_helper + 1) & 0x1F)) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice); + } + else if ((addr&0xF00) == 0x600) + { + /* These are automatically reported by READ16 */ + if (rep_count_r>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r=0; + } + last_read=0; + } + else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) + { + /* These are automatically reported by READ16 */ + if (rep_count_r>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r=0; + } + last_read=0; + } + else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) + { + uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); + if (tmpz != last_read) + { + if (rep_count_r>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r=0; + } + last_read=tmpz; + pclog("EMU8K READ RAM I/O or configuration or clock \n"); + } + //pclog("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); + } + else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) + { + uint32_t tmpz = ((addr&0xF00) << 16); + if (tmpz != last_read) + { + if (rep_count_r>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r=0; + } + last_read=tmpz; + pclog("EMU8K READ INIT \n"); + } + //pclog("EMU8K READ %04X-%02X(%d/%d)\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); + } + else + { + uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; + if (tmpz != last_read) + { + char* name = 0; + uint16_t val = 0xBAAD; + if (addr == 0xA20) + { + name = PORT_NAMES[1][emu8k->cur_reg]; + switch (emu8k->cur_reg) + { + case 2: val = emu8k->init1[emu8k->cur_voice]; break; + case 3: val = emu8k->init3[emu8k->cur_voice]; break; + case 4: val = emu8k->voice[emu8k->cur_voice].envvol; break; + case 5: val = emu8k->voice[emu8k->cur_voice].dcysusv; break; + case 6: val = emu8k->voice[emu8k->cur_voice].envval; break; + case 7: val = emu8k->voice[emu8k->cur_voice].dcysus; break; + } + } + else if (addr == 0xA22) + { + name = PORT_NAMES[2][emu8k->cur_reg]; + switch (emu8k->cur_reg) + { + case 2: val = emu8k->init2[emu8k->cur_voice]; break; + case 3: val = emu8k->init4[emu8k->cur_voice]; break; + case 4: val = emu8k->voice[emu8k->cur_voice].atkhldv; break; + case 5: val = emu8k->voice[emu8k->cur_voice].lfo1val; break; + case 6: val = emu8k->voice[emu8k->cur_voice].atkhld; break; + case 7: val = emu8k->voice[emu8k->cur_voice].lfo2val; break; + } + } + else if (addr == 0xE20) + { + name = PORT_NAMES[3][emu8k->cur_reg]; + switch (emu8k->cur_reg) + { + case 0: val = emu8k->voice[emu8k->cur_voice].ip; break; + case 1: val = emu8k->voice[emu8k->cur_voice].ifatn; break; + case 2: val = emu8k->voice[emu8k->cur_voice].pefe; break; + case 3: val = emu8k->voice[emu8k->cur_voice].fmmod; break; + case 4: val = emu8k->voice[emu8k->cur_voice].tremfrq; break; + case 5: val = emu8k->voice[emu8k->cur_voice].fm2frq2;break; + case 6: val = 0xffff; break; + case 7: val = 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); break; + } + } + if (rep_count_r>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_r); + } + if (name == 0) + { + pclog("EMU8K READ %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice,val); + } + else + { + pclog("EMU8K READ %s (%d): %04X\n",name,emu8k->cur_voice, val); + } + + rep_count_r=0; + last_read=tmpz; + } + rep_count_r++; + } +#endif // EMU8K_DEBUG_REGISTERS + + + switch (addr & 0xF02) + { + case 0x600: case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ switch (emu8k->cur_reg) { case 0: @@ -97,32 +497,48 @@ uint16_t emu8k_inw(uint16_t addr, void *p) READ16(addr, emu8k->voice[emu8k->cur_voice].vtft); return ret; - case 4: case 5: /*???*/ - return 0xffff; + case 4: + READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); + return ret; + + case 5: + READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); + return ret; case 6: READ16(addr, emu8k->voice[emu8k->cur_voice].psst); return ret; case 7: - READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); + READ16(addr, emu8k->voice[emu8k->cur_voice].csl); return ret; } break; - case 0x800: /*Data1*/ + case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ switch (emu8k->cur_reg) { 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; - } + READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); + return ret; case 1: switch (emu8k->cur_voice) { + case 9: + READ16(addr, emu8k->hwcf4); + return ret; + case 10: + READ16(addr, emu8k->hwcf5); + return ret; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ + case 13: + READ16(addr, emu8k->hwcf6); + return ret; + case 14: + READ16(addr, emu8k->hwcf7); + return ret; + case 20: READ16(addr, emu8k->smalr); return ret; @@ -140,84 +556,123 @@ uint16_t emu8k_inw(uint16_t addr, void *p) { uint16_t val = emu8k->smld_buffer; emu8k->smld_buffer = EMU8K_READ(emu8k, emu8k->smalr); -/* pclog("emu8k_SMLR in %04X (%04X) %08X\n", val, emu8k->smld_buffer, emu8k->smalr);*/ - emu8k->smalr++; + emu8k->smalr = (emu8k->smalr+1) & EMU8K_MEM_ADDRESS_MASK; return val; } + /*The EMU8000 PGM describes the return values of these registers as 'a VLSI error'*/ case 29: /*Configuration Word 1*/ return (emu8k->hwcf1 & 0xfe) | (emu8k->hwcf3 & 0x01); case 30: /*Configuration Word 2*/ - return ((emu8k->hwcf2 >> 4) & 0x0e) | (emu8k->hwcf1 & 0x01) | ((emu8k->hwcf3 & 0x02) ? 0x10 : 0) | ((emu8k->hwcf3 & 0x04) ? 0x40 : 0) | ((emu8k->hwcf3 & 0x08) ? 0x20 : 0) | ((emu8k->hwcf3 & 0x10) ? 0x80 : 0); + return ((emu8k->hwcf2 >> 4) & 0x0e) | (emu8k->hwcf1 & 0x01) | ((emu8k->hwcf3 & 0x02) ? 0x10 : 0) | ((emu8k->hwcf3 & 0x04) ? 0x40 : 0) + | ((emu8k->hwcf3 & 0x08) ? 0x20 : 0) | ((emu8k->hwcf3 & 0x10) ? 0x80 : 0); case 31: /*Configuration Word 3*/ return emu8k->hwcf2 & 0x1f; } break; - case 2: /*INIT1*/ - case 3: /*INIT3*/ - return 0xffff; /*Can we read anything useful from here?*/ + case 2: + return emu8k->init1[emu8k->cur_voice]; + case 3: + return emu8k->init3[emu8k->cur_voice]; + + case 4: + return emu8k->voice[emu8k->cur_voice].envvol; + case 5: return emu8k->voice[emu8k->cur_voice].dcysusv; + + case 6: + return emu8k->voice[emu8k->cur_voice].envval; case 7: return emu8k->voice[emu8k->cur_voice].dcysus; } break; - case 0x802: /*Data2*/ + case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ switch (emu8k->cur_reg) { 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; - } + READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); + return ret; case 1: switch (emu8k->cur_voice) { + case 9: + READ16(addr, emu8k->hwcf4); + return ret; + case 10: + READ16(addr, emu8k->hwcf5); + return ret; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + READ16(addr, emu8k->hwcf6); + return ret; + case 14: + READ16(addr, emu8k->hwcf7); + return ret; + + /* Simulating empty/full bits by unsetting it once read. */ case 20: - READ16(addr, emu8k->smalr | ff); - ff ^= 0x80000000; + READ16(addr, emu8k->smalr|dmareadbit); + /* xor with itself to set to zero faster. */ + dmareadbit^=dmareadbit; return ret; case 21: - READ16(addr, emu8k->smarr | ff); - ff ^= 0x80000000; + READ16(addr, emu8k->smarr|dmareadbit); + /* xor with itself to set to zero faster.*/ + dmareadbit^=dmareadbit; return ret; case 22: - READ16(addr, emu8k->smalw); + READ16(addr, emu8k->smalw|dmawritebit); + /*xor with itself to set to zero faster.*/ + dmawritebit^=dmawritebit; return ret; case 23: - READ16(addr, emu8k->smarw); + READ16(addr, emu8k->smarw|dmawritebit); + /*xor with itself to set to zero faster.*/ + dmawritebit^=dmawritebit; return ret; case 26: { uint16_t val = emu8k->smrd_buffer; emu8k->smrd_buffer = EMU8K_READ(emu8k, emu8k->smarr); -/* pclog("emu8k_SMRR in %04X (%04X) %08X\n", val, emu8k->smrd_buffer, emu8k->smarr);*/ - emu8k->smarr++; + emu8k->smarr = (emu8k->smarr+1) & EMU8K_MEM_ADDRESS_MASK; return val; } - - case 27: /*Sample Counter*/ + /*TODO: We need to improve the precision of this clock, since + it is used by programs to wait. Not critical, but should help reduce + the amount of calls and wait time */ + case 27: /*Sample Counter ( 44Khz clock) */ return emu8k->wc; } break; - case 2: /*INIT2*/ - case 3: /*INIT4*/ - return 0xffff; /*Can we read anything useful from here?*/ + case 2: + return emu8k->init2[emu8k->cur_voice]; + + case 3: + return emu8k->init4[emu8k->cur_voice]; case 4: return emu8k->voice[emu8k->cur_voice].atkhldv; + + case 5: + return emu8k->voice[emu8k->cur_voice].lfo1val; + + case 6: + return emu8k->voice[emu8k->cur_voice].atkhld; + + case 7: + return emu8k->voice[emu8k->cur_voice].lfo2val; } break; - case 0xc00: /*Data3*/ + case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ switch (emu8k->cur_reg) { case 0: @@ -245,13 +700,17 @@ 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 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ + /* 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 that it has set, and the variability + * of the MS byte to determine that it really is an AWE32. + * cubic player has a similar code, where it waits until value & 0x1000 is nonzero, and then waits again until it changes to zero.*/ + random_helper = (random_helper + 1) & 0x1F; + return ((0x80 | random_helper) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; } -/* fatal("Bad EMU8K inw from %08X\n", addr);*/ + pclog("EMU8K READ : Unknown register read: %04X-%02X(%d/%d) \n", addr, (emu8k->cur_reg << 5) | emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice); return 0xffff; } @@ -259,16 +718,113 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) { emu8k_t *emu8k = (emu8k_t *)p; + /*TODO: I would like to not call this here, but i found it was needed or else cubic player would not finish opening (take a looot more of time than usual). + * Basically, being here means that the audio is generated in the emulation thread, instead of the audio thread.*/ 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) + +#ifdef EMU8K_DEBUG_REGISTERS + if (addr == 0xE22) { - case 0x400: case 0x402: /*Data0*/ + //pclog("EMU8K WRITE POINTER: %d\n", val); + } + else if ((addr&0xF00) == 0x600) + { + /* These are automatically reported by WRITE16 */ + if (rep_count_w>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w=0; + } + last_write=0; + } + else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 0) + { + /* These are automatically reported by WRITE16 */ + if (rep_count_w>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w=0; + } + last_write=0; + } + else if ((addr&0xF00) == 0xA00 && emu8k->cur_reg == 1) + { + uint32_t tmpz = ((addr&0xF00) << 16)|(emu8k->cur_reg<<5); + if (tmpz != last_write) + { + if (rep_count_w>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w=0; + } + last_write=tmpz; + pclog("EMU8K WRITE RAM I/O or configuration \n"); + } + //pclog("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + } + else if ((addr&0xF00) == 0xA00 && (emu8k->cur_reg == 2 || emu8k->cur_reg == 3)) + { + uint32_t tmpz = ((addr&0xF00) << 16); + if (tmpz != last_write) + { + if (rep_count_w>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w=0; + } + last_write=tmpz; + pclog("EMU8K WRITE INIT \n"); + } + //pclog("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + } + else if (addr != 0xE22) + { + uint32_t tmpz = (addr << 16)|(emu8k->cur_reg<<5)| emu8k->cur_voice; + //if (tmpz != last_write) + if(1) + { + char* name = 0; + if (addr == 0xA20) + { + name = PORT_NAMES[1][emu8k->cur_reg]; + } + else if (addr == 0xA22) + { + name = PORT_NAMES[2][emu8k->cur_reg]; + } + else if (addr == 0xE20) + { + name = PORT_NAMES[3][emu8k->cur_reg]; + } + + if (rep_count_w>1) + { + pclog("EMU8K ...... for %d times\n", rep_count_w); + } + if (name == 0) + { + pclog("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); + } + else + { + pclog("EMU8K WRITE %s (%d): %04X\n",name,emu8k->cur_voice, val); + } + + rep_count_w=0; + last_write=tmpz; + } + rep_count_w++; + } +#endif //EMU8K_DEBUG_REGISTERS + + + switch (addr & 0xF02) + { + case 0x600: case 0x602: /*Data0. also known as BLASTER+0x400 and EMU+0x000 */ switch (emu8k->cur_reg) { case 0: + /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over ptrx */ WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); return; @@ -277,6 +833,7 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) return; case 2: + /* The docs says that this value is constantly updating, and it should have no actual effect. Actions should be done over vtft */ WRITE16(addr, emu8k->voice[emu8k->cur_voice].cvcf, val); return; @@ -284,37 +841,62 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) WRITE16(addr, emu8k->voice[emu8k->cur_voice].vtft, val); return; + case 4: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); + return; + + case 5: + WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); + return; + 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; - if (addr & 2) { - emu8k->voice[emu8k->cur_voice].vol_l = val >> 8; - emu8k->voice[emu8k->cur_voice].vol_r = 255 - (val >> 8); + emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; + WRITE16(addr, emu_voice->psst, val); + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu_voice->loop_start.int_address = emu_voice->psst & EMU8K_MEM_ADDRESS_MASK; + if (addr & 2) + { + emu_voice->vol_l = emu_voice->psst_pan; + emu_voice->vol_r = 255 - (emu_voice->psst_pan); + } } -/* pclog("emu8k_outl : write PSST %08X l %i r %i\n", emu8k->voice[emu8k->cur_voice].psst, emu8k->voice[emu8k->cur_voice].vol_l, emu8k->voice[emu8k->cur_voice].vol_r);*/ 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.int_address = emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK; return; } break; - case 0x800: /*Data1*/ + case 0xA00: /*Data1. also known as BLASTER+0x800 and EMU+0x400 */ switch (emu8k->cur_reg) { 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; -/* pclog("emu8k_outl : write CCCA %08X\n", emu8k->voice[emu8k->cur_voice].ccca);*/ + /* 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.int_address = emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK; return; case 1: switch (emu8k->cur_voice) { + case 9: + WRITE16(addr, emu8k->hwcf4, val); + return; + case 10: + WRITE16(addr, emu8k->hwcf5, val); + return; + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset. */ + case 13: + WRITE16(addr, emu8k->hwcf6, val); + return; + case 14: + WRITE16(addr, emu8k->hwcf7, val); + return; + case 20: WRITE16(addr, emu8k->smalr, val); return; @@ -330,166 +912,574 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) case 26: EMU8K_WRITE(emu8k, emu8k->smalw, val); -/* pclog("emu8k_SMLW %04X %08X\n", val, emu8k->smalw);*/ -/* if (val = 0xffff && emu8k->smalw == 0x200000) - output = 3;*/ - emu8k->smalw++; - break; + emu8k->smalw = (emu8k->smalw+1) & EMU8K_MEM_ADDRESS_MASK; + return; - case 29: /*Configuration Word 1*/ + case 29: emu8k->hwcf1 = val; return; - case 30: /*Configuration Word 2*/ + case 30: emu8k->hwcf2 = val; return; - case 31: /*Configuration Word 3*/ + case 31: emu8k->hwcf3 = val; return; } break; - case 5: -/* pclog("emu8k_outw : write DCYSUSV %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].dcysusv = val; - emu8k->voice[emu8k->cur_voice].env_sustain = (((val >> 8) & 0x7f) << 5) << 9; - if (val & 0x8000) /*Release*/ + case 2: + emu8k->init1[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) { - emu8k->voice[emu8k->cur_voice].env_state = ENV_RELEASE; - emu8k->voice[emu8k->cur_voice].env_release = val & 0x7f; + switch(emu8k->cur_voice) + { + case 0x3: emu8k->reverb_engine.out_mix = val&0xFF; + break; + case 0x5: + { + int c; + for (c=0;c<8;c++) + { + emu8k->reverb_engine.allpass[c].feedback=(val&0xFF)/((float)0xFF); + } + } + break; + case 0x7: emu8k->reverb_engine.link_return_type = (val==0x8474)? 1:0; + break; + case 0xF: emu8k->reverb_engine.reflections[0].output_gain = ((val&0xF0)>>4)/15.0; + break; + case 0x17: emu8k->reverb_engine.reflections[1].output_gain = ((val&0xF0)>>4)/15.0; + break; + case 0x1F: emu8k->reverb_engine.reflections[2].output_gain = ((val&0xF0)>>4)/15.0; + break; + case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val&0xF)/15.0; + break; + case 0xB: //emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; + break; + case 0x11:emu8k->reverb_engine.reflections[1].feedback = (val&0xF)/15.0; + break; + case 0x13: //emu8k->reverb_engine.reflections[1].feedback_r = (val&0xF)/15.0; + break; + case 0x19: emu8k->reverb_engine.reflections[2].feedback = (val&0xF)/15.0; + break; + case 0x1B: //emu8k->reverb_engine.reflections[2].feedback_r = (val&0xF)/15.0; + break; + } } - else /*Decay*/ - emu8k->voice[emu8k->cur_voice].env_decay = val & 0x7f; - if (val & 0x80) - emu8k->voice[emu8k->cur_voice].env_state = ENV_STOPPED; + return; + + case 3: + emu8k->init3[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) + { + switch(emu8k->cur_voice) + { + case 9: + emu8k->chorus_engine.feedback = (val&0xFF); + break; + case 12: + emu8k->chorus_engine.delay_samples_central = val; + break; + + case 1: emu8k->reverb_engine.refl_in_amp = val&0xFF; + break; + case 3: //emu8k->reverb_engine.refl_in_amp_r = val&0xFF; + break; + } + } + return; + + case 4: + emu8k->voice[emu8k->cur_voice].envvol = val; + emu8k->voice[emu8k->cur_voice].vol_envelope.delay_samples = ENVVOL_TO_EMU_SAMPLES(val); + return; + + case 5: + { + emu8k->voice[emu8k->cur_voice].dcysusv = val; + emu8k_envelope_t * const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; + int old_on=emu8k->voice[emu8k->cur_voice].env_engine_on; + emu8k->voice[emu8k->cur_voice].env_engine_on = DCYSUSV_GENERATOR_ENGINE_ON(val); + + if (emu8k->voice[emu8k->cur_voice].env_engine_on && + old_on != emu8k->voice[emu8k->cur_voice].env_engine_on) + { + if (emu8k->hwcf3 != 0x04 && emu8k->cur_voice == 31) + { + /* This is a hack for some programs like Doom or cubic player 1.7 that don't initialize + the hwcfg and init registers (doom does not init the card at all. only tests the cfg registers) */ + emu8k->hwcf3 = 0x04; + } + + //reset lfos. + emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; + emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; + // Trigger envelopes + if (ATKHLDV_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhldv)) + { + vol_env->value_amp_hz = 0; + if (vol_env->delay_samples) + { + vol_env->state = ENV_DELAY; + } + else if (vol_env->attack_amount_amp_hz == 0) + { + vol_env->state = ENV_STOPPED; + } + else + { + vol_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal mute, + * or it means skip attack, go to hold". + if (vol_env->attack_amount == 0) + { + vol_env->value = (1 << 21); + vol_env->state = ENV_HOLD; + }*/ + } + } + + if (ATKHLD_TRIGGER(emu8k->voice[emu8k->cur_voice].atkhld)) + { + emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + mod_env->value_amp_hz = 0; + mod_env->value_db_oct = 0; + if (mod_env->delay_samples) + { + mod_env->state = ENV_DELAY; + } + else if (mod_env->attack_amount_amp_hz == 0) + { + mod_env->state = ENV_STOPPED; + } + else + { + mod_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal start, + * or it means skip attack, go to hold". + if (mod_env->attack_amount == 0) + { + mod_env->value = (1 << 21); + mod_env->state = ENV_HOLD; + }*/ + } + } + } + + + /* Converting the input in dBs to envelope value range. */ + vol_env->sustain_value_db_oct = DCYSUSV_SUS_TO_ENV_RANGE(DCYSUSV_SUSVALUE_GET(val)); + vol_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUSV_DECAYRELEASE_GET(val)]; + if (DCYSUSV_IS_RELEASE(val)) + { + if (vol_env->state == ENV_DELAY || vol_env->state == ENV_ATTACK || vol_env->state == ENV_HOLD) + { + vol_env->value_db_oct = env_vol_amplitude_to_db[vol_env->value_amp_hz >> 5] << 5; + if (vol_env->value_db_oct > (1 << 21)) + vol_env->value_db_oct = 1 << 21; + } + + vol_env->state = (vol_env->value_db_oct >= vol_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; + } + } + return; + + case 6: + emu8k->voice[emu8k->cur_voice].envval = val; + emu8k->voice[emu8k->cur_voice].mod_envelope.delay_samples = ENVVAL_TO_EMU_SAMPLES(val); return; case 7: -/* pclog("emu8k_outw : write DCYSUS %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].dcysus = val; - emu8k->voice[emu8k->cur_voice].menv_sustain = (((val >> 8) & 0x7f) << 5) << 9; - if (val & 0x8000) /*Release*/ { - emu8k->voice[emu8k->cur_voice].menv_state = ENV_RELEASE; - emu8k->voice[emu8k->cur_voice].menv_release = val & 0x7f; + //TODO: Look for a bug on delay (first trigger it works, next trigger it doesn't) + emu8k->voice[emu8k->cur_voice].dcysus = val; + emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + /* Converting the input in octaves to envelope value range. */ + mod_env->sustain_value_db_oct = DCYSUS_SUS_TO_ENV_RANGE(DCYSUS_SUSVALUE_GET(val)); + mod_env->ramp_amount_db_oct = env_decay_to_dbs_or_oct[DCYSUS_DECAYRELEASE_GET(val)]; + if (DCYSUS_IS_RELEASE(val)) + { + if (mod_env->state == ENV_DELAY || mod_env->state == ENV_ATTACK || mod_env->state == ENV_HOLD) + { + mod_env->value_db_oct = env_mod_hertz_to_octave[mod_env->value_amp_hz >> 9] << 9; + if (mod_env->value_db_oct >= (1 << 21)) + mod_env->value_db_oct = (1 << 21)-1; + } + + mod_env->state = (mod_env->value_db_oct >= mod_env->sustain_value_db_oct) ? ENV_RAMP_DOWN : ENV_RAMP_UP; + } } - else /*Decay*/ - emu8k->voice[emu8k->cur_voice].menv_decay = val & 0x7f; - if (val & 0x80) - emu8k->voice[emu8k->cur_voice].menv_state = ENV_STOPPED; return; } break; - case 0x802: /*Data2*/ + case 0xA02: /*Data2. also known as BLASTER+0x802 and EMU+0x402 */ switch (emu8k->cur_reg) { 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; - - q = (float)(emu8k->voice[emu8k->cur_voice].ccca >> 28) / 15.0f; - q /= 10.0f; /*Horrible and wrong hack*/ - emu8k->voice[emu8k->cur_voice].q = (int32_t)((1.0f / (0.707f + q)) * 256.0f); - -/* pclog("emu8k_outl : write CCCA %08X Q %f invQ %X\n", emu8k->voice[emu8k->cur_voice].ccca, q, emu8k->voice[emu8k->cur_voice].q);*/ + emu8k_voice_t *emu_voice = &emu8k->voice[emu8k->cur_voice]; + WRITE16(addr, emu_voice->ccca, val); + emu_voice->addr.int_address = emu_voice->ccca & EMU8K_MEM_ADDRESS_MASK; + uint32_t paramq = CCCA_FILTQ_GET(emu_voice->ccca); + emu_voice->filt_att = filter_atten[paramq]; + emu_voice->filterq_idx = paramq; } return; case 1: switch (emu8k->cur_voice) { - case 20: - WRITE16(addr, emu8k->smalr, val); + case 9: + WRITE16(addr, emu8k->hwcf4, val); + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) + { + /*(1/256th of a 44Khz sample) */ + emu8k->chorus_engine.delay_offset_samples_right = ((double)emu8k->hwcf4)/256.0; + } return; - case 21: - WRITE16(addr, emu8k->smarr, val); + case 10: + WRITE16(addr, emu8k->hwcf5, val); + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) + { + /* The scale of this value is unknown. I've taken it as milliHz. + * Another interpretation could be periods. (and so, Hz = 1/period)*/ + double osc_speed = emu8k->hwcf5;//*1.316; +#if 1 // milliHz + /*milliHz to lfotable samples.*/ + osc_speed *= 65.536/44100.0; +#elif 0 //periods + /* 44.1Khz ticks to lfotable samples.*/ + osc_speed = 65.536/osc_speed; +#endif + /*left shift 32bits for 32.32 fixed.point*/ + osc_speed *= 65536.0*65536.0; + emu8k->chorus_engine.lfo_inc.addr = (uint64_t)osc_speed; + } return; - case 22: - WRITE16(addr, emu8k->smalw, val); + /* Actually, these two might be command words rather than registers, or some LFO position/buffer reset.*/ + case 13: + WRITE16(addr, emu8k->hwcf6, val); return; - case 23: - WRITE16(addr, emu8k->smarw, val); + case 14: + WRITE16(addr, emu8k->hwcf7, val); + return; + + case 20: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ + WRITE16(addr, emu8k->smalr, val&0xFF); + dmareadbit=0x8000; + return; + case 21: /*Top 8 bits are for Empty (MT) bit or non-addressable.*/ + WRITE16(addr, emu8k->smarr, val&0xFF); + dmareadbit=0x8000; + return; + case 22: /*Top 8 bits are for full bit or non-addressable.*/ + WRITE16(addr, emu8k->smalw, val&0xFF); + return; + case 23: /*Top 8 bits are for full bit or non-addressable.*/ + WRITE16(addr, emu8k->smarw, val&0xFF); return; case 26: + dmawritebit=0x8000; EMU8K_WRITE(emu8k, emu8k->smarw, val); -/* pclog("emu8k_SMRW %04X %08X\n", val, emu8k->smarw);*/ emu8k->smarw++; - break; + return; } break; + case 2: + emu8k->init2[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) + { + switch(emu8k->cur_voice) + { + case 0x14: + { + int multip = ((val&0xF00)>>8)+18; + emu8k->reverb_engine.reflections[5].bufsize = multip*REV_BUFSIZE_STEP; + emu8k->reverb_engine.tailL.bufsize = (multip+1)*REV_BUFSIZE_STEP; + if ( emu8k->reverb_engine.link_return_type == 0) + { + emu8k->reverb_engine.tailR.bufsize = (multip+1)*REV_BUFSIZE_STEP; + } + } + break; + case 0x16: + if ( emu8k->reverb_engine.link_return_type == 1) + { + int multip = ((val&0xF00)>>8)+18; + emu8k->reverb_engine.tailR.bufsize = (multip+1)*REV_BUFSIZE_STEP; + } + break; + case 0x7: emu8k->reverb_engine.reflections[3].output_gain = ((val&0xF0)>>4)/15.0; + break; + case 0xf: emu8k->reverb_engine.reflections[4].output_gain = ((val&0xF0)>>4)/15.0; + break; + case 0x17: emu8k->reverb_engine.reflections[5].output_gain = ((val&0xF0)>>4)/15.0; + break; + case 0x1d: + { + int c; + for (c=0;c<6;c++) + { + emu8k->reverb_engine.reflections[c].damp1=(val&0xFF)/255.0; + emu8k->reverb_engine.reflections[c].damp2=(0xFF-(val&0xFF))/255.0; + emu8k->reverb_engine.reflections[c].filterstore=0; + } + emu8k->reverb_engine.damper.damp1=(val&0xFF)/255.0; + emu8k->reverb_engine.damper.damp2=(0xFF-(val&0xFF))/255.0; + emu8k->reverb_engine.damper.filterstore=0; + } + break; + case 0x1f: /* filter r */ + break; + case 0x1: emu8k->reverb_engine.reflections[3].feedback = (val&0xF)/15.0; + break; + case 0x3: //emu8k->reverb_engine.reflections[3].feedback_r = (val&0xF)/15.0; + break; + case 0x9: emu8k->reverb_engine.reflections[4].feedback = (val&0xF)/15.0; + break; + case 0xb: //emu8k->reverb_engine.reflections[4].feedback_r = (val&0xF)/15.0; + break; + case 0x11: emu8k->reverb_engine.reflections[5].feedback = (val&0xF)/15.0; + break; + case 0x13: //emu8k->reverb_engine.reflections[5].feedback_r = (val&0xF)/15.0; + break; + } + } + return; + + case 3: + emu8k->init4[emu8k->cur_voice] = val; + /* Skip if in first/second initialization step */ + if (emu8k->init1[0] != 0x03FF) + { + switch(emu8k->cur_voice) + { + case 0x3: + { + int32_t samples = ((val&0xFF)*emu8k->chorus_engine.delay_samples_central) >> 8; + emu8k->chorus_engine.lfodepth_multip = samples; + } + break; + + case 0x1F: + emu8k->reverb_engine.link_return_amp = val&0xFF; + break; + } + } + return ; + case 4: -/* pclog("emu8k_outw : write ATKHLDV %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].atkhldv = val; - emu8k->voice[emu8k->cur_voice].env_attack = (val & 0x7f) << 6; - if (!(val & 0x8000)) /*Trigger attack*/ - emu8k->voice[emu8k->cur_voice].env_state = ENV_ATTACK; + { + emu8k->voice[emu8k->cur_voice].atkhldv = val; + emu8k_envelope_t* const vol_env = &emu8k->voice[emu8k->cur_voice].vol_envelope; + vol_env->attack_samples = env_attack_to_samples[ATKHLDV_ATTACK(val)]; + if (vol_env->attack_samples == 0) + { + vol_env->attack_amount_amp_hz = 0; + } + else + { + /* Linear amplitude increase each sample. */ + vol_env->attack_amount_amp_hz = (1<<21) / vol_env->attack_samples; + } + vol_env->hold_samples = ATKHLDV_HOLD_TO_EMU_SAMPLES(val); + if (ATKHLDV_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) + { + /*TODO: I assume that "envelope trigger" is the same as new note + * (since changing the IP can be done when modulating pitch too) */ + emu8k->voice[emu8k->cur_voice].lfo1_count.addr = 0; + emu8k->voice[emu8k->cur_voice].lfo2_count.addr = 0; + + vol_env->value_amp_hz = 0; + if (vol_env->delay_samples) + { + vol_env->state = ENV_DELAY; + } + else if (vol_env->attack_amount_amp_hz == 0) + { + vol_env->state = ENV_STOPPED; + } + else + { + vol_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal mute, + * or it means skip attack, go to hold". + if (vol_env->attack_amount == 0) + { + vol_env->value = (1 << 21); + vol_env->state = ENV_HOLD; + }*/ + } + } + } + return; + + case 5: + emu8k->voice[emu8k->cur_voice].lfo1val = val; + /* TODO: verify if this is set once, or set every time. */ + emu8k->voice[emu8k->cur_voice].lfo1_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); return; case 6: -/* pclog("emu8k_outw : write ATKHLD %04X\n", val);*/ - emu8k->voice[emu8k->cur_voice].atkhld = val; - emu8k->voice[emu8k->cur_voice].menv_attack = (val & 0x7f) << 6; - if (!(val & 0x8000)) /*Trigger attack*/ - emu8k->voice[emu8k->cur_voice].menv_state = ENV_ATTACK; + { + emu8k->voice[emu8k->cur_voice].atkhld = val; + emu8k_envelope_t* const mod_env = &emu8k->voice[emu8k->cur_voice].mod_envelope; + mod_env->attack_samples = env_attack_to_samples[ATKHLD_ATTACK(val)]; + if (mod_env->attack_samples == 0) + { + mod_env->attack_amount_amp_hz = 0; + } + else + { + /* Linear amplitude increase each sample. */ + mod_env->attack_amount_amp_hz = (1<<21) / mod_env->attack_samples; + } + mod_env->hold_samples = ATKHLD_HOLD_TO_EMU_SAMPLES(val); + if (ATKHLD_TRIGGER(val) && emu8k->voice[emu8k->cur_voice].env_engine_on) + { + mod_env->value_amp_hz = 0; + mod_env->value_db_oct = 0; + if (mod_env->delay_samples) + { + mod_env->state = ENV_DELAY; + } + else if (mod_env->attack_amount_amp_hz == 0) + { + mod_env->state = ENV_STOPPED; + } + else + { + mod_env->state = ENV_ATTACK; + /* TODO: Verify if "never attack" means eternal start, + * or it means skip attack, go to hold". + if (mod_env->attack_amount == 0) + { + mod_env->value = (1 << 21); + mod_env->state = ENV_HOLD; + }*/ + } + } + } + return; + + case 7: + emu8k->voice[emu8k->cur_voice].lfo2val = val; + emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); + return; } break; - case 0xc00: /*Data3*/ + case 0xE00: /*Data3. also known as BLASTER+0xC00 and EMU+0x800 */ switch (emu8k->cur_reg) { case 0: emu8k->voice[emu8k->cur_voice].ip = val; - emu8k->voice[emu8k->cur_voice].pitch = val; + emu8k->voice[emu8k->cur_voice].ptrx_pit_target = freqtable[val] >> 18; return; case 1: - emu8k->voice[emu8k->cur_voice].ifatn = val; - emu8k->voice[emu8k->cur_voice].attenuation = attentable[val & 0xff]; - emu8k->voice[emu8k->cur_voice].cutoff = (val >> 8); -/* pclog("Attenuation now %02X %i\n", val & 0xff, emu8k->voice[emu8k->cur_voice].attenuation);*/ + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + if ((val&0xFF) == 0 && the_voice->cvcf_curr_volume == 0 && the_voice->vtft_vol_target == 0 + && the_voice->dcysusv == 0x80 && the_voice->ip == 0) + { + // Patch to avoid some clicking noises with Impulse tracker or other software that sets different values to 0 + // to set noteoff, but here, 0 means no attenuation = full volume. + return; + } + the_voice->ifatn = val; + the_voice->initial_att = (((int32_t)the_voice->ifatn_attenuation <<21)/0xFF); + the_voice->vtft_vol_target = attentable[the_voice->ifatn_attenuation]; + + the_voice->initial_filter = (((int32_t)the_voice->ifatn_init_filter <<21)/0xFF); + if (the_voice->ifatn_init_filter==0xFF) + { + the_voice->vtft_filter_target = 0xFFFF; + } + else + { + the_voice->vtft_filter_target = the_voice->initial_filter >> 5; + } + } return; case 2: - emu8k->voice[emu8k->cur_voice].pefe = val; - emu8k->voice[emu8k->cur_voice].fe_height = (int8_t)(val & 0xff); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->pefe = val; + + int divider = (the_voice->pefe_modenv_filter_height < 0) ? 0x80 : 0x7F; + the_voice->fixed_modenv_filter_height = ((int32_t)the_voice->pefe_modenv_filter_height)*0x4000/divider; + + divider = (the_voice->pefe_modenv_pitch_height < 0) ? 0x80 : 0x7F; + the_voice->fixed_modenv_pitch_height = ((int32_t)the_voice->pefe_modenv_pitch_height)*0x4000/divider; + } return; case 3: - emu8k->voice[emu8k->cur_voice].fmmod = val; - emu8k->voice[emu8k->cur_voice].lfo1_fmmod = (val >> 8); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->fmmod = val; + + int divider = (the_voice->fmmod_lfo1_filt_mod < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo1_filt_mod = ((int32_t)the_voice->fmmod_lfo1_filt_mod)*0x4000/divider; + + divider = (the_voice->fmmod_lfo1_vibrato < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo1_vibrato = ((int32_t)the_voice->fmmod_lfo1_vibrato)*0x4000/divider; + } return; case 4: - emu8k->voice[emu8k->cur_voice].tremfrq = val; - emu8k->voice[emu8k->cur_voice].lfo1_trem = (val >> 8); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->tremfrq = val; + the_voice->lfo1_speed = lfofreqtospeed[the_voice->tremfrq_lfo1_freq]; + + int divider = (the_voice->tremfrq_lfo1_tremolo < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo1_tremolo = ((int32_t)the_voice->tremfrq_lfo1_tremolo)*0x4000/divider; + } return; case 5: - emu8k->voice[emu8k->cur_voice].fm2frq2 = val; - emu8k->voice[emu8k->cur_voice].lfo2_fmmod = (val >> 8); + { + emu8k_voice_t * const the_voice = &emu8k->voice[emu8k->cur_voice]; + the_voice->fm2frq2 = val; + the_voice->lfo2_speed = lfofreqtospeed[the_voice->fm2frq2_lfo2_freq]; + + int divider = (the_voice->fm2frq2_lfo2_vibrato < 0) ? 0x80 : 0x7F; + the_voice->fixed_lfo2_vibrato = ((int32_t)the_voice->fm2frq2_lfo2_vibrato)*0x4000/divider; + } return; - case 7: /*ID?*/ + case 7: /*ID? I believe that this allows applications to know if the emu is in use by another application */ emu8k->id = val; return; } break; - case 0xc02: /*Pointer*/ + case 0xE02: /* Pointer. also known as BLASTER+0xC02 and EMU+0x802 */ emu8k->cur_voice = (val & 31); emu8k->cur_reg = ((val >> 5) & 7); return; } + pclog("EMU8K WRITE: Unknown register write: %04X-%02X(%d/%d): %04X \n", addr, (emu8k->cur_reg)<<5|emu8k->cur_voice, + emu8k->cur_reg,emu8k->cur_voice, val); + } uint8_t emu8k_inb(uint16_t addr, void *p) { + /* Reading a single byte is a feature that at least Impulse tracker uses, + * but only on detection code and not for odd addresses.*/ if (addr & 1) return emu8k_inw(addr & ~1, p) >> 1; return emu8k_inw(addr, p) & 0xff; @@ -497,254 +1487,864 @@ uint8_t emu8k_inb(uint16_t addr, void *p) void emu8k_outb(uint16_t addr, uint8_t val, void *p) { + /* TODO: AWE32 docs says that you cannot write in bytes, but if + * an app were to use this implementation, the content of the LS Byte would be lost.*/ if (addr & 1) emu8k_outw(addr & ~1, val << 8, p); else emu8k_outw(addr, val, p); } +/* TODO: This is not a correct emulation, just a workalike implementation. */ +void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engine, int count) +{ + int pos; + for (pos = 0; pos < count; pos++) + { + double lfo_inter1 = chortable[engine->lfo_pos.int_address]; + // double lfo_inter2 = chortable[(engine->lfo_pos.int_address+1)&0xFFFF]; + + double offset_lfo =lfo_inter1; //= lfo_inter1 + ((lfo_inter2-lfo_inter1)*engine->lfo_pos.fract_address/65536.0); + offset_lfo *= engine->lfodepth_multip; + + /* Work left */ + double readdouble = (double)engine->write - (double)engine->delay_samples_central - offset_lfo; + int read = (int32_t)floor(readdouble); + int fraction_part = (readdouble - (double)read)*65536.0; + if (read < 0) + read = 0; + int next_value = read + 1; + if(read < 0) + { + read += MAXSOUNDBUFLEN; + if(next_value < 0) next_value += MAXSOUNDBUFLEN; + } + else if(next_value >= MAXSOUNDBUFLEN) + { + next_value -= MAXSOUNDBUFLEN; + if(read >= MAXSOUNDBUFLEN) read -= MAXSOUNDBUFLEN; + } + int32_t dat1 = engine->chorus_left_buffer[read]; + int32_t dat2 = engine->chorus_left_buffer[next_value]; + dat1 += ((dat2-dat1)* fraction_part) >> 16; + + engine->chorus_left_buffer[engine->write] = *inbuf + ((dat1 * engine->feedback)>>8); + + + /* Work right */ + readdouble = (double)engine->write - (double)engine->delay_samples_central - engine->delay_offset_samples_right - offset_lfo; + read = (int32_t)floor(readdouble); + if (read < 0) + read = 0; + next_value = read + 1; + if(read < 0) + { + read += MAXSOUNDBUFLEN; + if(next_value < 0) next_value += MAXSOUNDBUFLEN; + } + else if(next_value >= MAXSOUNDBUFLEN) + { + next_value -= MAXSOUNDBUFLEN; + if(read >= MAXSOUNDBUFLEN) read -= MAXSOUNDBUFLEN; + } + int32_t dat3 = engine->chorus_right_buffer[read]; + int32_t dat4 = engine->chorus_right_buffer[next_value]; + dat3 += ((dat4-dat3)* fraction_part) >> 16; + + engine->chorus_right_buffer[engine->write] = *inbuf + ((dat3 * engine->feedback)>>8); + + ++engine->write; + engine->write %= MAXSOUNDBUFLEN; + engine->lfo_pos.addr +=engine->lfo_inc.addr; + engine->lfo_pos.int_address &= 0xFFFF; + + (*outbuf++) += dat1; + (*outbuf++) += dat3; + inbuf++; + } + +} + +int32_t emu8k_reverb_comb_work(emu8k_reverb_combfilter_t* comb, int32_t in) +{ + + int32_t bufin; + /* get echo */ + int32_t output = comb->reflection[comb->read_pos]; + /* apply lowpass */ + comb->filterstore = (output*comb->damp2) + (comb->filterstore*comb->damp1); + /* appply feedback */ + bufin = in - (comb->filterstore*comb->feedback); + /* store new value in delayed buffer */ + comb->reflection[comb->read_pos] = bufin; + + if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; + + return output*comb->output_gain; +} + +int32_t emu8k_reverb_diffuser_work(emu8k_reverb_combfilter_t* comb, int32_t in) +{ + + int32_t bufout = comb->reflection[comb->read_pos]; + /*diffuse*/ + int32_t bufin = -in + (bufout*comb->feedback); + int32_t output = bufout - (bufin*comb->feedback); + /* store new value in delayed buffer */ + comb->reflection[comb->read_pos] = bufin; + + if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; + + return output; +} + +int32_t emu8k_reverb_tail_work(emu8k_reverb_combfilter_t* comb, emu8k_reverb_combfilter_t* allpasses, int32_t in) +{ + int32_t output = comb->reflection[comb->read_pos]; + /* store new value in delayed buffer */ + comb->reflection[comb->read_pos] = in; + + //output = emu8k_reverb_allpass_work(&allpasses[0],output); + output = emu8k_reverb_diffuser_work(&allpasses[1],output); + output = emu8k_reverb_diffuser_work(&allpasses[2],output); + //output = emu8k_reverb_allpass_work(&allpasses[3],output); + + if(++comb->read_pos>=comb->bufsize) comb->read_pos = 0; + + return output; +} +int32_t emu8k_reverb_damper_work(emu8k_reverb_combfilter_t* comb, int32_t in) +{ + /* apply lowpass */ + comb->filterstore = (in*comb->damp2) + (comb->filterstore*comb->damp1); + return comb->filterstore; +} + +/* TODO: This is not a correct emulation, just a workalike implementation. */ +void emu8k_work_reverb(int32_t *inbuf, int32_t *outbuf, emu8k_reverb_eng_t *engine, int count) +{ + int pos; + if (engine->link_return_type) + { + for (pos = 0; pos < count; pos++) + { + int32_t dat1, dat2, in, in2; + in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); + in2 = (in * engine->refl_in_amp) >> 8; + dat2 = emu8k_reverb_comb_work(&engine->reflections[0], in2); + dat2 += emu8k_reverb_comb_work(&engine->reflections[1], in2); + dat1 = emu8k_reverb_comb_work(&engine->reflections[2], in2); + dat2 += emu8k_reverb_comb_work(&engine->reflections[3], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); + dat2 += emu8k_reverb_comb_work(&engine->reflections[5], in2); + + dat1 += (emu8k_reverb_tail_work(&engine->tailL,&engine->allpass[0], in+dat1)*engine->link_return_amp) >> 8; + dat2 += (emu8k_reverb_tail_work(&engine->tailR,&engine->allpass[4], in+dat2)*engine->link_return_amp) >> 8; + + (*outbuf++) += (dat1 * engine->out_mix) >> 8; + (*outbuf++) += (dat2 * engine->out_mix) >> 8; + } + } + else + { + for (pos = 0; pos < count; pos++) + { + int32_t dat1, dat2, in, in2; + in = emu8k_reverb_damper_work(&engine->damper, inbuf[pos]); + in2 = (in * engine->refl_in_amp) >> 8; + dat1 = emu8k_reverb_comb_work(&engine->reflections[0], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[1], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[2], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[3], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[4], in2); + dat1 += emu8k_reverb_comb_work(&engine->reflections[5], in2); + dat2 = dat1; + + dat1 += (emu8k_reverb_tail_work(&engine->tailL,&engine->allpass[0], in+dat1)*engine->link_return_amp) >> 8; + dat2 += (emu8k_reverb_tail_work(&engine->tailR,&engine->allpass[4], in+dat2)*engine->link_return_amp) >> 8; + + (*outbuf++) += (dat1 * engine->out_mix) >> 8; + (*outbuf++) += (dat2 * engine->out_mix) >> 8; + } + } +} +void emu8k_work_eq(int32_t *inoutbuf, int count) +{ + // TODO: Work EQ over buf +} + + +int32_t emu8k_vol_slide(emu8k_slide_t* slide, int32_t target) +{ + if (slide->last < target) + { + slide->last+=0x400; + if (slide->last > target) slide->last = target; + } + else if (slide->last > target) + { + slide->last-=0x400; + if (slide->last < target) slide->last = target; + } + return slide->last; +} + +//int32_t old_pitch[32]={0}; +//int32_t old_cut[32]={0}; +//int32_t old_vol[32]={0}; void emu8k_update(emu8k_t *emu8k) { int new_pos = (sound_pos_global * 44100) / 48000; - if (emu8k->pos < new_pos) + if (emu8k->pos >= new_pos) + return; + + int32_t *buf; + emu8k_voice_t* emu_voice; + int pos; + int c; + + /* Clean the buffers since we will accumulate into them. */ + buf = &emu8k->buffer[emu8k->pos*2]; + memset(buf, 0, 2*(new_pos-emu8k->pos)*sizeof(emu8k->buffer[0])); + memset(&emu8k->chorus_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->chorus_in_buffer[0])); + memset(&emu8k->reverb_in_buffer[emu8k->pos], 0, (new_pos-emu8k->pos)*sizeof(emu8k->reverb_in_buffer[0])); + + /* Voices section */ + for (c = 0; c < 32; c++) { - int32_t *buf; - int pos; - int c; - + emu_voice = &emu8k->voice[c]; buf = &emu8k->buffer[emu8k->pos*2]; - for (pos = emu8k->pos; pos < new_pos; pos++) - emu8k->buffer[pos*2] = emu8k->buffer[pos*2 + 1] = 0; - - for (c = 0; c < 32; c++) + for (pos = emu8k->pos; pos < new_pos; pos++) { - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) + int32_t dat; + + /* Waveform oscillator */ +#ifdef RESAMPLER_LINEAR + dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); + +#elif defined RESAMPLER_CUBIC + dat = EMU8K_READ_INTERP_CUBIC(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); +#endif + + /* Filter section */ + if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF ) { - 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; + int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; + const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; + const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; + const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; + /* clip at twice the range */ + #define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 : buf - if (freqtable[emu8k->voice[c].pitch] >> 32) - dat = EMU8K_READ(emu8k, emu8k->voice[c].addr >> 32); - else - dat = EMU8K_READ_INTERP(emu8k, emu8k->voice[c].addr >> 24); - - dat = (dat * emu8k->voice[c].attenuation) >> 16; - - dat = (dat * envtable[emu8k->voice[c].env_vol >> 9]) >> 16; - - if ((emu8k->voice[c].ccca >> 28) || (emu8k->voice[c].cutoff != 0xff)) - { - int cutoff = emu8k->voice[c].cutoff + ((emu8k->voice[c].menv_vol * emu8k->voice[c].fe_height) >> 20); - if (cutoff < 0) - cutoff = 0; - if (cutoff > 255) - cutoff = 255; - - emu8k->voice[c].vhp = ((-emu8k->voice[c].vbp * emu8k->voice[c].q) >> 8) - emu8k->voice[c].vlp - dat; - emu8k->voice[c].vlp += (emu8k->voice[c].vbp * filt_w0[cutoff]) >> 8; - emu8k->voice[c].vbp += (emu8k->voice[c].vhp * filt_w0[cutoff]) >> 8; - if (emu8k->voice[c].vlp < -32767) - dat = -32767; - else if (emu8k->voice[c].vlp > 32767) - dat = 32767; - else - dat = (int16_t)emu8k->voice[c].vlp; - } - - voice_l = (dat * emu8k->voice[c].vol_l) >> 7; - voice_r = (dat * emu8k->voice[c].vol_r) >> 7; - - (*buf++) += voice_l * 8192; - (*buf++) += voice_r * 8192; - - switch (emu8k->voice[c].env_state) - { - case ENV_ATTACK: - emu8k->voice[c].env_vol += emu8k->voice[c].env_attack; - emu8k->voice[c].vtft |= 0xffff0000; - if (emu8k->voice[c].env_vol >= (1 << 21)) - { - emu8k->voice[c].env_vol = 1 << 21; - emu8k->voice[c].env_state = ENV_DECAY; - } - break; - - case ENV_DECAY: - emu8k->voice[c].env_vol -= emu8k->voice[c].env_decay; - emu8k->voice[c].vtft = (emu8k->voice[c].vtft & ~0xffff0000) | ((emu8k->voice[c].env_sustain >> 5) << 16); - if (emu8k->voice[c].env_vol <= emu8k->voice[c].env_sustain) - { - emu8k->voice[c].env_vol = emu8k->voice[c].env_sustain; - emu8k->voice[c].env_state = ENV_SUSTAIN; - } - break; - - case ENV_RELEASE: - emu8k->voice[c].env_vol -= emu8k->voice[c].env_release; - emu8k->voice[c].vtft &= ~0xffff0000; - if (emu8k->voice[c].env_vol <= 0) - { - emu8k->voice[c].env_vol = 0; - emu8k->voice[c].env_state = ENV_STOPPED; - } - break; - } - - if (emu8k->voice[c].env_vol >= (1 << 21)) - emu8k->voice[c].cvcf &= ~0xffff0000; - else - emu8k->voice[c].cvcf = (emu8k->voice[c].cvcf & ~0xffff0000) | ((emu8k->voice[c].env_vol >> 5) << 16); - - switch (emu8k->voice[c].menv_state) - { - case ENV_ATTACK: - emu8k->voice[c].menv_vol += emu8k->voice[c].menv_attack; - if (emu8k->voice[c].menv_vol >= (1 << 21)) - { - emu8k->voice[c].menv_vol = 1 << 21; - emu8k->voice[c].menv_state = ENV_DECAY; - } - break; - - case ENV_DECAY: - emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_decay; - if (emu8k->voice[c].menv_vol <= emu8k->voice[c].menv_sustain) - { - emu8k->voice[c].menv_vol = emu8k->voice[c].menv_sustain; - emu8k->voice[c].menv_state = ENV_SUSTAIN; - } - break; - - case ENV_RELEASE: - emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_release; - if (emu8k->voice[c].menv_vol <= 0) - { - emu8k->voice[c].menv_vol = 0; - emu8k->voice[c].menv_state = ENV_STOPPED; - } - break; - } - - lfo1_vibrato = (lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_fmmod) >> 9; - lfo2_vibrato = (lfotable[(emu8k->voice[c].lfo2_count >> 8) & 4095] * emu8k->voice[c].lfo2_fmmod) >> 9; + #ifdef FILTER_INITIAL + #define NOOP(x) (void)x; + NOOP(coef1) + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). + * Work in 24bits. */ + dat = (dat * emu_voice->filt_att) >> 8; - emu8k->voice[c].addr += freqtable[(emu8k->voice[c].pitch + lfo1_vibrato + lfo2_vibrato) & 0xffff]; - if (emu8k->voice[c].addr >= emu8k->voice[c].loop_end) - emu8k->voice[c].addr -= (emu8k->voice[c].loop_end - emu8k->voice[c].loop_start); + int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; + emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; + emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; + dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } - emu8k->voice[c].lfo1_count += (emu8k->voice[c].tremfrq & 0xff); - emu8k->voice[c].lfo2_count += (emu8k->voice[c].fm2frq2 & 0xff); + #elif defined FILTER_MOOG + + /*move to 24bits*/ + dat <<= 8; + + dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ + int64_t t1 = emu_voice->filt_buffer[1]; + emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + int64_t t2 = emu_voice->filt_buffer[2]; + emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; + emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); + + int64_t t3 = emu_voice->filt_buffer[3]; + emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; + emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); + + emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; + emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); + + emu_voice->filt_buffer[0] = ClipBuffer(dat); + + dat = (int32_t)(emu_voice->filt_buffer[4] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #elif defined FILTER_CONSTANT + + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). + * Also stay at 24bits.*/ + dat = (dat * emu_voice->filt_att) >> 8; + + emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] + + coef0 * (dat + + ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1]))>>24)) + ) >> 24; + emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] + + coef0 * emu_voice->filt_buffer[0]) >> 24; + + emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #endif + } - } + if (( emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) + { + /*volume and pan*/ + dat = (dat * emu_voice->cvcf_curr_volume) >> 16; - buf = &emu8k->buffer[emu8k->pos*2]; - - for (pos = emu8k->pos; pos < new_pos; pos++) - { - buf[0] >>= 15; - buf[1] >>= 15; - - if (buf[0] < -32768) - buf[0] = -32768; - else if (buf[0] > 32767) - buf[0] = 32767; - - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; - - buf += 2; - } + (*buf++) += (dat * emu_voice->vol_l) >> 8; + (*buf++) += (dat * emu_voice->vol_r) >> 8; - emu8k->wc += (new_pos - emu8k->pos); + /* Effects section */ + if (emu_voice->ptrx_revb_send > 0) + { + emu8k->reverb_in_buffer[pos]+=(dat*emu_voice->ptrx_revb_send) >> 8; + } + if (emu_voice->csl_chor_send > 0) + { + emu8k->chorus_in_buffer[pos]+=(dat*emu_voice->csl_chor_send) >> 8; + } + } + + if ( emu_voice->env_engine_on) + { + int32_t attenuation = emu_voice->initial_att; + int32_t filtercut = emu_voice->initial_filter; + int32_t currentpitch = emu_voice->ip; + /* run envelopes */ + emu8k_envelope_t *volenv = &emu_voice->vol_envelope; + switch (volenv->state) + { + case ENV_DELAY: + volenv->delay_samples--; + if (volenv->delay_samples <=0) + { + volenv->state=ENV_ATTACK; + volenv->delay_samples=0; + } + attenuation = 0x1FFFFF; + break; + + case ENV_ATTACK: + /* Attack amount is in linear amplitude */ + volenv->value_amp_hz += volenv->attack_amount_amp_hz; + if (volenv->value_amp_hz >= (1 << 21)) + { + volenv->value_amp_hz = 1 << 21; + volenv->value_db_oct = 0; + if (volenv->hold_samples) + { + volenv->state = ENV_HOLD; + } + else + { + /* RAMP_UP since db value is inverted and it is 0 at this point. */ + volenv->state = ENV_RAMP_UP; + } + } + attenuation += env_vol_amplitude_to_db[volenv->value_amp_hz >> 5] << 5; + break; + + case ENV_HOLD: + volenv->hold_samples--; + if (volenv->hold_samples <=0) + { + volenv->state=ENV_RAMP_UP; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_RAMP_DOWN: + /* Decay/release amount is in fraction of dBs and is always positive */ + volenv->value_db_oct -= volenv->ramp_amount_db_oct; + if (volenv->value_db_oct <= volenv->sustain_value_db_oct) + { + volenv->value_db_oct = volenv->sustain_value_db_oct; + volenv->state = ENV_SUSTAIN; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_RAMP_UP: + /* Decay/release amount is in fraction of dBs and is always positive */ + volenv->value_db_oct += volenv->ramp_amount_db_oct; + if (volenv->value_db_oct >= volenv->sustain_value_db_oct) + { + volenv->value_db_oct = volenv->sustain_value_db_oct; + volenv->state = ENV_SUSTAIN; + } + attenuation += volenv->value_db_oct; + break; + + case ENV_SUSTAIN: + attenuation += volenv->value_db_oct; + break; + + case ENV_STOPPED: + attenuation = 0x1FFFFF; + break; + } + + emu8k_envelope_t *modenv = &emu_voice->mod_envelope; + switch (modenv->state) + { + case ENV_DELAY: + modenv->delay_samples--; + if (modenv->delay_samples <=0) + { + modenv->state=ENV_ATTACK; + modenv->delay_samples=0; + } + break; + + case ENV_ATTACK: + /* Attack amount is in linear amplitude */ + modenv->value_amp_hz += modenv->attack_amount_amp_hz; + modenv->value_db_oct = env_mod_hertz_to_octave[modenv->value_amp_hz >> 5] << 5; + if (modenv->value_amp_hz >= (1 << 21)) + { + modenv->value_amp_hz = 1 << 21; + modenv->value_db_oct = 1 << 21; + if (modenv->hold_samples) + { + modenv->state = ENV_HOLD; + } + else + { + modenv->state = ENV_RAMP_DOWN; + } + } + break; + + case ENV_HOLD: + modenv->hold_samples--; + if (modenv->hold_samples <=0) + { + modenv->state=ENV_RAMP_UP; + } + break; + + case ENV_RAMP_DOWN: + /* Decay/release amount is in fraction of octave and is always positive */ + modenv->value_db_oct -= modenv->ramp_amount_db_oct; + if (modenv->value_db_oct <= modenv->sustain_value_db_oct) + { + modenv->value_db_oct = modenv->sustain_value_db_oct; + modenv->state = ENV_SUSTAIN; + } + break; + + case ENV_RAMP_UP: + /* Decay/release amount is in fraction of octave and is always positive */ + modenv->value_db_oct += modenv->ramp_amount_db_oct; + if (modenv->value_db_oct >= modenv->sustain_value_db_oct) + { + modenv->value_db_oct = modenv->sustain_value_db_oct; + modenv->state = ENV_SUSTAIN; + } + break; + } + + /* run lfos */ + if (emu_voice->lfo1_delay_samples) + { + emu_voice->lfo1_delay_samples--; + } + else + { + emu_voice->lfo1_count.addr += emu_voice->lfo1_speed; + emu_voice->lfo1_count.int_address &= 0xFFFF; + } + if (emu_voice->lfo2_delay_samples) + { + emu_voice->lfo2_delay_samples--; + } + else + { + emu_voice->lfo2_count.addr += emu_voice->lfo2_speed; + emu_voice->lfo2_count.int_address &= 0xFFFF; + } + + + if (emu_voice->fixed_modenv_pitch_height) + { + /* modenv range 1<<21, pitch height range 1<<14 desired range 0x1000 (+/-one octave) */ + currentpitch += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_pitch_height) >> 14; + } + + if (emu_voice->fixed_lfo1_vibrato) + { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ + int32_t lfo1_vibrato = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_vibrato) >> 17; + currentpitch += lfo1_vibrato; + } + if (emu_voice->fixed_lfo2_vibrato) + { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x1000 (+/-one octave) */ + int32_t lfo2_vibrato = (lfotable[emu_voice->lfo2_count.int_address]*emu_voice->fixed_lfo2_vibrato) >> 17; + currentpitch += lfo2_vibrato; + } + + if (emu_voice->fixed_modenv_filter_height) + { + /* modenv range 1<<21, pitch height range 1<<14 desired range 0x200000 (+/-full filter range) */ + filtercut += ((modenv->value_db_oct>>9)*emu_voice->fixed_modenv_filter_height) >> 5; + } + + if (emu_voice->fixed_lfo1_filt_mod) + { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x100000 (+/-three octaves) */ + int32_t lfo1_filtmod = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_filt_mod) >> 9; + filtercut += lfo1_filtmod; + } + + if (emu_voice->fixed_lfo1_tremolo) + { + /* table range 1<<15, pitch mod range 1<<14 desired range 0x40000 (+/-12dBs). */ + int32_t lfo1_tremolo = (lfotable[emu_voice->lfo1_count.int_address]*emu_voice->fixed_lfo1_tremolo) >> 11; + attenuation += lfo1_tremolo; + } + + if (currentpitch > 0xFFFF) currentpitch = 0xFFFF; + if (currentpitch < 0) currentpitch = 0; + if (attenuation > 0x1FFFFF) attenuation = 0x1FFFFF; + if (attenuation < 0) attenuation = 0; + if (filtercut > 0x1FFFFF) filtercut = 0x1FFFFF; + if (filtercut < 0) filtercut = 0; + + emu_voice->vtft_vol_target = env_vol_db_to_vol_target[attenuation >> 5]; + emu_voice->vtft_filter_target = filtercut >> 5; + emu_voice->ptrx_pit_target = freqtable[currentpitch]>>18; + + } +/* +I've recopilated these sentences to get an idea of how to loop + +- Set its PSST register and its CLS register to zero to cause no loops to occur. +-Setting the Loop Start Offset and the Loop End Offset to the same value, will cause the oscillator to loop the entire memory. + +-Setting the PlayPosition greater than the Loop End Offset, will cause the oscillator to play in reverse, back to the Loop End Offset. + It's pretty neat, but appears to be uncontrollable (the rate at which the samples are played in reverse). + +-Note that due to interpolator offset, the actual loop point is one greater than the start address +-Note that due to interpolator offset, the actual loop point will end at an address one greater than the loop address +-Note that the actual audio location is the point 1 word higher than this value due to interpolation offset +-In programs that use the awe, they generally set the loop address as "loopaddress -1" to compensate for the above. +(Note: I am already using address+1 in the interpolators so these things are already as they should.) +*/ + emu_voice->addr.addr += ((uint64_t)emu_voice->cpf_curr_pitch) << 18; + if (emu_voice->addr.addr >= emu_voice->loop_end.addr) + { + emu_voice->addr.int_address -= (emu_voice->loop_end.int_address - emu_voice->loop_start.int_address); + emu_voice->addr.int_address &= EMU8K_MEM_ADDRESS_MASK; + } + + /* TODO: How and when are the target and current values updated */ + emu_voice->cpf_curr_pitch = emu_voice->ptrx_pit_target; + emu_voice->cvcf_curr_volume = emu8k_vol_slide(&emu_voice->volumeslide,emu_voice->vtft_vol_target); + emu_voice->cvcf_curr_filt_ctoff = emu_voice->vtft_filter_target; + } - emu8k->pos = new_pos; + /* Update EMU voice registers. */ + emu_voice->ccca = (((uint32_t)emu_voice->ccca_qcontrol) << 24) | emu_voice->addr.int_address; + emu_voice->cpf_curr_frac_addr = emu_voice->addr.fract_address; + + //if ( emu_voice->cvcf_curr_volume != old_vol[c]) { + // pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); + // old_vol[c]=emu_voice->cvcf_curr_volume; + //} + //pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); } -} + + buf = &emu8k->buffer[emu8k->pos*2]; + emu8k_work_reverb(&emu8k->reverb_in_buffer[emu8k->pos], buf, &emu8k->reverb_engine, new_pos-emu8k->pos); + emu8k_work_chorus(&emu8k->chorus_in_buffer[emu8k->pos], buf, &emu8k->chorus_engine, new_pos-emu8k->pos); + emu8k_work_eq(buf, new_pos-emu8k->pos); + + // Clip signal + for (pos = emu8k->pos; pos < new_pos; pos++) + { + if (buf[0] < -32768) + buf[0] = -32768; + else if (buf[0] > 32767) + buf[0] = 32767; + + if (buf[1] < -32768) + buf[1] = -32768; + else if (buf[1] > 32767) + buf[1] = 32767; + + buf += 2; + } + + /* Update EMU clock. */ + emu8k->wc += (new_pos - emu8k->pos); + + emu8k->pos = new_pos; +} +/* onboard_ram in kilobytes */ void emu8k_init(emu8k_t *emu8k, int onboard_ram) { + uint32_t const BLOCK_SIZE_WORDS = 0x10000; FILE *f; int c; double out; - + f = romfopen("awe32.raw", "rb"); if (!f) fatal("AWE32.RAW not found\n"); - if (onboard_ram) - { - emu8k->ram = malloc(onboard_ram * 1024); - emu8k->ram_end_addr = 0x200000 + ((onboard_ram * 1024) / 2); - } - - emu8k->rom = malloc(1024 * 1024); - + emu8k->rom = malloc(1024 * 1024); fread(emu8k->rom, 1024 * 1024, 1, f); fclose(f); - /*AWE-DUMP creates ROM images offset by 2 bytes, so if we detect this then correct it*/ if (emu8k->rom[3] == 0x314d && emu8k->rom[4] == 0x474d) { - memcpy(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); + memmove(&emu8k->rom[0], &emu8k->rom[1], (1024 * 1024) - 2); emu8k->rom[0x7ffff] = 0; } + + emu8k->empty = malloc(2*BLOCK_SIZE_WORDS); + memset(emu8k->empty, 0, 2*BLOCK_SIZE_WORDS); + + int j=0; + for (;j<0x8;j++) + { + emu8k->ram_pointers[j]=emu8k->rom+(j*BLOCK_SIZE_WORDS); + } + for (;j<0x20;j++) + { + emu8k->ram_pointers[j]=emu8k->empty; + } + + 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); + memset(emu8k->ram, 0, onboard_ram * 1024); + const int i_end=onboard_ram>>7; + int i=0; + for(;iram_pointers[j]=emu8k->ram+(i*BLOCK_SIZE_WORDS); + } + emu8k->ram_end_addr = EMU8K_RAM_MEM_START + (onboard_ram<<9); + } + else + { + emu8k->ram = 0; + emu8k->ram_end_addr = EMU8K_RAM_MEM_START; + } + for (;j < 0x100;j++) + { + emu8k->ram_pointers[j]=emu8k->empty; + + } + io_sethandler(0x0620, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); io_sethandler(0x0a20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); io_sethandler(0x0e20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - /*Create frequency table*/ + /*Create frequency table. (Convert initial pitch register value to a linear speed change) + * The input is encoded such as 0xe000 is center note (no pitch shift) + * and from then on , changing up or down 0x1000 (4096) increments/decrements an octave. + * Note that this is in reference to the 44.1Khz clock that the channels play at. + * The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. + */ for (c = 0; c < 0x10000; c++) { freqtable[c] = (uint64_t)(exp2((double)(c - 0xe000) / 4096.0) * 65536.0 * 65536.0); } + /* Shortcut: minimum pitch equals stopped. I don't really know if this is true, but it's better + * since some programs set the pitch to 0 for unused channels. */ + freqtable[0] = 0; - out = 65536.0; - + /* starting at 65535 because it is used for "volume target" register conversion. */ + out = 65535.0; for (c = 0; c < 256; c++) { - attentable[c] = (int)out; + attentable[c] = (int32_t)out; out /= sqrt(1.09018); /*0.375 dB steps*/ } + /* Shortcut: max attenuation is silent, not -96dB. */ + attentable[255]=0; - out = 65536; - - for (c = 0; c < 4096; c++) + /* Note: these two tables have "db" inverted: 0 dB is max volume, 65535 "db" (-96.32dBFS) is silence. + * Important: Using 65535 as max output value because this is intended to be used with the volume target register! */ + out = 65535.0; + for (c = 0; c < 0x10000; c++) { - envtable[4095 - c] = (int)out; - out /= 1.002709201; /*0.0235 dB Steps*/ - } - - for (c = 0; c < 4096; c++) - { - int d = (c + 1024) & 4095; - if (d >= 2048) - lfotable[c] = 4096 - ((2048 - d) * 4); - else - lfotable[c] = (d * 4) - 4096; + //double db = -(c*6.0205999/65535.0)*16.0; + //out = powf(10.f,db/20.f) * 65536.0; + env_vol_db_to_vol_target[c] = (int32_t)out; + /* calculated from the 65536th root of 65536 */ + out /= 1.00016923970; } + /* Shortcut: max attenuation is silent, not -96dB. */ + env_vol_db_to_vol_target[0x10000-1]=0; + /* One more position to accept max value being 65536. */ + env_vol_db_to_vol_target[0x10000]=0; - out = 125.0; + for (c = 1; c < 0x10000; c++) + { + out = -680.32142884264* 20.0 * log10(((double)c)/65535.0); + env_vol_amplitude_to_db[c] = (int32_t)out; + } + /*Shortcut: max attenuation is silent, not -96dB.*/ + env_vol_amplitude_to_db[0]=65535; + /* One more position to accept max value being 65536. */ + env_vol_amplitude_to_db[0x10000]=0; + + + for (c = 1; c < 0x10000; c++) + { + out = log2((((double)c)/0x10000)+1.0) *65536.0; + env_mod_hertz_to_octave[c] = (int32_t)out; + } + /*No hertz change, no octave change. */ + env_mod_hertz_to_octave[0]=0; + /* One more position to accept max value being 65536. */ + env_mod_hertz_to_octave[0x10000]=65536; + + + /* This formula comes from vince vu/judge dredd's awe32p10 and corresponds to what the freebsd/linux AWE32 driver has. */ + float millis; + for (c=0;c<128;c++) + { + if (c==0) + millis = 0; /* This means never attack. */ + else if (c < 32) + millis = 11878.0/c; + else + millis = 360*exp((c - 32) / (16.0/log(1.0/2.0))); + + env_attack_to_samples[c] = 44.1*millis; + /* This is an alternate formula with linear increments, but probably incorrect: + * millis = (256+4096*(0x7F-c)) */ + } + + /* The LFOs use a triangular waveform starting at zero and going 1/-1/1/-1. + * This table is stored in signed 16bits precision, with a period of 65536 samples */ + for (c = 0; c < 65536; c++) + { + int d = (c + 16384) & 65535; + if (d >= 32768) + lfotable[c] = 32768 + ((32768 - d)*2); + else + lfotable[c] = (d*2) - 32768; + } + /* The 65536 * 65536 is in order to left-shift the 32bit value to a 64bit value as a 32.32 fixed point. */ + out = 0.01; for (c = 0; c < 256; c++) { -/* filt_w0[c] = (int32_t)((2.0 * 3.142 * (out / 44100.0)) * 0.707 * 256.0);*/ -/* filt_w0[c] = 2.0 * 3.142 * (out / 44100.0);*/ - filt_w0[c] = (int32_t)(2.0 * 3.142 * (out / 44100.0) * 256.0); - out *= 1.016378315; + lfofreqtospeed[c] = (uint64_t)(out *65536.0/44100.0 * 65536.0 * 65536.0); + out += 0.042; } + for (c = 0; c < 65536; c++) + { + chortable[c] = sin(c*M_PI/32768.0); + } + + + /* Filter coefficients tables. Note: Values are multiplied by *16777216 to left shift 24 bits. (i.e. 8.24 fixed point) */ + int qidx; + for (qidx = 0; qidx < 16; qidx++) + { + out = 125.0; /* Start at 125Hz */ + for (c = 0; c < 256; c++) + { +#ifdef FILTER_INITIAL + float w0 = sin(2.0*M_PI*out / 44100.0); + /* The value 102.5f has been selected a bit randomly. Pretends to reach 0.2929 at w0 = 1.0 */ + float q = (qidx / 102.5f) * (1.0 + 1.0 / w0); + /* Limit max value. Else it would be 470. */ + if (q > 200) q=200; + filt_coeffs[qidx][c][0] = (int32_t)(w0 * 16777216.0); + filt_coeffs[qidx][c][1] = 16777216.0; + filt_coeffs[qidx][c][2] = (int32_t)((1.0f / (0.7071f + q)) * 16777216.0); +#elif defined FILTER_MOOG + float w0 = sin(2.0*M_PI*out / 44100.0); + float q_factor = 1.0f - w0; + float p = w0 + 0.8f * w0 * q_factor; + float f = p + p - 1.0f; + float resonance = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; + float q = resonance * (1.0f + 0.5f * q_factor * (w0 + 5.6f * q_factor * q_factor)); + filt_coeffs[qidx][c][0] = (int32_t)(p * 16777216.0); + filt_coeffs[qidx][c][1] = (int32_t)(f * 16777216.0); + filt_coeffs[qidx][c][2] = (int32_t)(q * 16777216.0); +#elif defined FILTER_CONSTANT + float q = (1.0-pow(2.0,-qidx*24.0/90.0))*0.8; + float coef0 = sin(2.0*M_PI*out / 44100.0); + float coef1 = 1.0 - coef0; + float coef2 = q * (1.0 + 1.0 / coef1); + filt_coeffs[qidx][c][0] = (int32_t)(coef0 * 16777216.0); + filt_coeffs[qidx][c][1] = (int32_t)(coef1 * 16777216.0); + filt_coeffs[qidx][c][2] = (int32_t)(coef2 * 16777216.0); +#endif //FILTER_TYPE + /* 42.66 divisions per octave (the doc says quarter seminotes which is 48, but then it would be almost an octave less) */ + out *= 1.016378315; + /* 42 divisions. This moves the max frequency to 8.5Khz.*/ + //out *= 1.0166404394; + /* This is a linear increment method, that corresponds to the NRPN table, but contradicts the EMU8KPRM doc: */ + //out = 100.0 + (c+1.0)*31.25; //31.25Hz steps */ + } + } + /* NOTE! read_pos and buffer content is implicitly initialized to zero by the sb_t structure memset on sb_awe32_init() */ + emu8k->reverb_engine.reflections[0].bufsize=2*REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[1].bufsize=4*REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[2].bufsize=8*REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[3].bufsize=13*REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[4].bufsize=19*REV_BUFSIZE_STEP; + emu8k->reverb_engine.reflections[5].bufsize=26*REV_BUFSIZE_STEP; + + /*This is a bit random.*/ + for (c=0;c<4;c++) + { + emu8k->reverb_engine.allpass[3-c].feedback=0.5; + emu8k->reverb_engine.allpass[3-c].bufsize=(4*c)*REV_BUFSIZE_STEP+55; + emu8k->reverb_engine.allpass[7-c].feedback=0.5; + emu8k->reverb_engine.allpass[7-c].bufsize=(4*c)*REV_BUFSIZE_STEP+55; + } + + + + /* Cubic Resampling ( 4point cubic spline) */ + double const resdouble = 1.0/(double)CUBIC_RESOLUTION; + for (c = 0; c < CUBIC_RESOLUTION; c++) + { + double x = (double)c * resdouble; + /* Cubic resolution is made of four table, but I've put them all in one table to optimize memory access. */ + cubic_table[c*4] = (-0.5 * x * x * x + x * x - 0.5 * x) ; + cubic_table[c*4+1] = ( 1.5 * x * x * x - 2.5 * x * x + 1.0) ; + cubic_table[c*4+2] = (-1.5 * x * x * x + 2.0 * x * x + 0.5 * x) ; + cubic_table[c*4+3] = ( 0.5 * x * x * x - 0.5 * x * x) ; + } + /* If this is not set here, AWE card is not detected on Windows with Aweman driver. It's weird that the EMU8k says that this + * has to be set by applications, and the AWE driver does not set it. */ emu8k->hwcf1 = 0x59; emu8k->hwcf2 = 0x20; - emu8k->hwcf3 = 0x04; + /* Initial state is muted. 0x04 is unmuted. */ + emu8k->hwcf3 = 0x00; } void emu8k_close(emu8k_t *emu8k) @@ -752,3 +2352,4 @@ void emu8k_close(emu8k_t *emu8k) free(emu8k->rom); free(emu8k->ram); } + diff --git a/src/sound_emu8k.h b/src/sound_emu8k.h index f54576a..7fad2ba 100644 --- a/src/sound_emu8k.h +++ b/src/sound_emu8k.h @@ -1,65 +1,356 @@ + +/* All these defines are in samples, not in bytes. */ +#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF +#define EMU8K_RAM_MEM_START 0x200000 +#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0 +#define EMU8K_RAM_POINTERS_MASK 0x3F +#define EMU8K_LFOCHORUS_SIZE 0x4000 +/* + * Everything in this file assumes little endian + */ +/* used for the increment of oscillator position*/ +typedef struct emu8k_mem_internal_t { + union { + uint64_t addr; + struct { + uint16_t fract_lw_address; + uint16_t fract_address; + uint32_t int_address; + }; + }; +} emu8k_mem_internal_t; + +/* used for access to ram pointers from oscillator position. */ +typedef struct emu8k_mem_pointers_t { + union { + uint32_t addr; + struct { + uint16_t lw_address; + uint8_t hb_address; + uint8_t unused_address; + }; + }; +} emu8k_mem_pointers_t; + +/* + * From the Soundfount 2.0 fileformat Spec.: + * + An envelope generates a control signal in six phases. + When key-on occurs, a delay period begins during which the envelope value is zero. + The envelope then rises in a convex curve to a value of one during the attack phase. + " Note that the attack is convex; the curve is nominally such that when applied to a + decibel or semitone parameter, the result is linear in amplitude or Hz respectively" + + When a value of one is reached, the envelope enters a hold phase during which it remains at one. + When the hold phase ends, the envelope enters a decay phase during which its value decreases linearly to a sustain level. + " For the Volume Envelope, the decay phase linearly ramps toward the sustain level, causing a constant dB change for each time unit. " + When the sustain level is reached, the envelope enters sustain phase, during which the envelope stays at the sustain level. + + Whenever a key-off occurs, the envelope immediately enters a release phase during which the value linearly ramps from the current value to zero. + " For the Volume Envelope, the release phase linearly ramps toward zero from the current level, causing a constant dB change for each time unit" + + When zero is reached, the envelope value remains at zero. + + Modulation of pitch and filter cutoff are in octaves, semitones, and cents. + These parameters can be modulated to varying degree, either positively or negatively, by the modulation envelope. + The degree of modulation is specified in cents for the full-scale attack peak. + + The volume envelope operates in dB, with the attack peak providing a full scale output, appropriately scaled by the initial volume. + The zero value, however, is actually zero gain. + The implementation in the EMU8000 provides for 96 dB of amplitude control. + When 96 dB of attenuation is reached in the final gain amplifier, an abrupt jump to zero gain + (infinite dB of attenuation) occurs. In a 16-bit system, this jump is inaudible +*/ +/* It seems that the envelopes don't really have a decay/release stage, + * but instead they have a volume ramper that can be triggered + * automatically (after hold period), or manually (by activating release) + * and the "sustain" value is the target of any of both cases. + * Some programs like cubic player and AWEAmp use this, and it was + * described in the following way in Vince Vu/Judge Dredd's awe32p10.txt: + * If the MSB (most significant bit or bit 15) of this register is set, + * the Decay/Release will begin immediately, overriding the Delay, Attack, + * and Hold. Otherwise the Decay/Release will wait until the Delay, Attack, + * and Hold are finished. If you set the MSB of this register, you can use + * it as a volume ramper, as on the GUS. The upper byte (except the MSB), + * contains the destination volume, and the lower byte contains the ramp time. + */ + +/* attack_amount is linear amplitude (added directly to value). + * ramp_amount_db is linear dB (added directly to value too, but needs conversion to get linear amplitude). + * value range is 21bits for both, linear amplitude being 1<<21 = 0dBFS and 0 = -96dBFS (which is shortcut to silence), + * and db amplutide being 0 = 0dBFS and -(1<<21) = -96dBFS (which is shortcut to silence). + * This allows to operate db values by simply adding them. + */ +typedef struct emu8k_envelope_t { + int state; + int32_t delay_samples, hold_samples, attack_samples; + int32_t value_amp_hz, value_db_oct; + int32_t sustain_value_db_oct; + int32_t attack_amount_amp_hz, ramp_amount_db_oct; +} emu8k_envelope_t; + + + +typedef struct emu8k_chorus_eng_t { + int32_t write; + int32_t feedback; + int32_t delay_samples_central; + double lfodepth_multip; + double delay_offset_samples_right; + emu8k_mem_internal_t lfo_inc; + emu8k_mem_internal_t lfo_pos; + + int32_t chorus_left_buffer[EMU8K_LFOCHORUS_SIZE]; + int32_t chorus_right_buffer[EMU8K_LFOCHORUS_SIZE]; + +} emu8k_chorus_eng_t; + +/* 32 * 242. 32 comes from the "right" room resso case.*/ +#define MAX_REFL_SIZE 7744 + + +/* Reverb parameters description, extracted from AST sources. + Mix level + Decay + Link return amp + Link type Switches between normal or panned + Room reso ( ms) L&R (Ref 6 +1) + Ref 1 x2 (11 ms)R + Ref 2 x4 (22 ms)R + Ref 3 x8 (44 ms)L + Ref 4 x13(71 ms)R + Ref 5 x19(105ms)L + Ref 6 x ( ms)R (multiplier changes with room reso) + Ref 1-6 filter L&R + Ref 1-6 amp L&R + Ref 1 feedback L&R + Ref 2 feedback L&R + Ref 3 feedback L&R + Ref 4 feedback L&R + Ref 5 feedback L&R + Ref 6 feedback L&R +*/ +typedef struct emu8k_reverb_combfilter_t { + int read_pos; + int32_t reflection[MAX_REFL_SIZE]; + float output_gain; + float feedback; + float damp1; + float damp2; + int bufsize; + int32_t filterstore; +} emu8k_reverb_combfilter_t; + +typedef struct emu8k_reverb_eng_t { + + int16_t out_mix; + int16_t link_return_amp; /* tail part output gain ? */ + int8_t link_return_type; + + uint8_t refl_in_amp; + + emu8k_reverb_combfilter_t reflections[6]; + emu8k_reverb_combfilter_t allpass[8]; + emu8k_reverb_combfilter_t tailL; + emu8k_reverb_combfilter_t tailR; + + emu8k_reverb_combfilter_t damper; +} emu8k_reverb_eng_t; + +typedef struct emu8k_slide_t { + int32_t last; +} emu8k_slide_t; + + +typedef struct emu8k_voice_t +{ + union { + uint32_t cpf; + struct { + uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */ + uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ + }; + }; + union { + uint32_t ptrx; + struct { + uint8_t ptrx_pan_aux; + uint8_t ptrx_revb_send; + uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */ + }; + }; + union { + uint32_t cvcf; + struct { + uint16_t cvcf_curr_filt_ctoff; + uint16_t cvcf_curr_volume; + }; + }; + emu8k_slide_t volumeslide; + union { + uint32_t vtft; + struct { + uint16_t vtft_filter_target; + uint16_t vtft_vol_target; /* written to by the envelope engine. */ + }; + }; + /* These registers are used at least by the Windows drivers, and seem to be resetting + * something, similarly to targets and current, but... of what? + * what is curious is that if they are already zero, they are not written to, so it really + * looks like they are information about the status of the channel. (lfo position maybe?) */ + uint32_t unknown_data0_4; + uint32_t unknown_data0_5; + union { + uint32_t psst; + struct { + uint16_t psst_lw_address; + uint8_t psst_hw_address; + uint8_t psst_pan; + }; + #define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t csl; + struct { + uint16_t csl_lw_address; + uint8_t csl_hw_address; + uint8_t csl_chor_send; + }; + #define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t ccca; + struct { + uint16_t ccca_lw_addr; + uint8_t ccca_hb_addr; + uint8_t ccca_qcontrol; + }; + }; + #define CCCA_FILTQ_GET(ccca) (ccca>>28) + #define CCCA_FILTQ_SET(ccca,q) ccca = (ccca&0x0FFFFFFF) | (q<<28) + /* Bit 27 should always be zero */ + #define CCCA_DMA_ACTIVE(ccca) (ccca&0x04000000) + #define CCCA_DMA_WRITE_MODE(ccca) (ccca&0x02000000) + #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca&0x01000000) + + uint16_t envvol; + #define ENVVOL_NODELAY(envol) (envvol&0x8000) + /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ + #define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol&0x8000) ? 0 : ((0x8000-(envvol&0x7FFF)) <<5) + + uint16_t dcysusv; + #define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv&0x8000) + #define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv&0x0080) + #define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv>>8)&0x7F) + /* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */ + #define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F-susvalue) << 21)/0x7F) + #define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv&0x7F) + + uint16_t envval; + #define ENVVAL_NODELAY(enval) (envval&0x8000) + /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ + #define ENVVAL_TO_EMU_SAMPLES(envval)(envval&0x8000) ? 0 : ((0x8000-(envval&0x7FFF)) <<5) + + uint16_t dcysus; + #define DCYSUS_IS_RELEASE(dcysus) (dcysus&0x8000) + #define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus>>8)&0x7F) + #define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21)/0x7F) + #define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus&0x7F) + + uint16_t atkhldv; + #define ATKHLDV_TRIGGER(atkhldv) !(atkhldv&0x8000) + #define ATKHLDV_HOLD(atkhldv) ((atkhldv>>8)&0x7F) + #define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096*(0x7F-((atkhldv>>8)&0x7F))) + #define ATKHLDV_ATTACK(atkhldv) (atkhldv&0x7F) + + uint16_t lfo1val, lfo2val; + #define LFOxVAL_NODELAY(lfoxval) (lfoxval&0x8000) + #define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval&0x8000) ? 0 : ((0x8000-(lfoxval&0x7FFF)) <<5) + + uint16_t atkhld; + #define ATKHLD_TRIGGER(atkhld) !(atkhld&0x8000) + #define ATKHLD_HOLD(atkhld) ((atkhld>>8)&0x7F) + #define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096*(0x7F-((atkhld>>8)&0x7F))) + #define ATKHLD_ATTACK(atkhld) (atkhld&0x7F) + + + uint16_t ip; + #define INTIAL_PITCH_CENTER 0xE000 + #define INTIAL_PITCH_OCTAVE 0x1000 + + union { + uint16_t ifatn; + struct{ + uint8_t ifatn_attenuation; + uint8_t ifatn_init_filter; + }; + }; + union { + uint16_t pefe; + struct { + int8_t pefe_modenv_filter_height; + int8_t pefe_modenv_pitch_height; + }; + }; + union { + uint16_t fmmod; + struct { + int8_t fmmod_lfo1_filt_mod; + int8_t fmmod_lfo1_vibrato; + }; + }; + union { + uint16_t tremfrq; + struct { + uint8_t tremfrq_lfo1_freq; + int8_t tremfrq_lfo1_tremolo; + }; + }; + union { + uint16_t fm2frq2; + struct { + uint8_t fm2frq2_lfo2_freq; + int8_t fm2frq2_lfo2_vibrato; + }; + }; + + int env_engine_on; + + emu8k_mem_internal_t addr, loop_start, loop_end; + + int32_t initial_att; + int32_t initial_filter; + + emu8k_envelope_t vol_envelope; + emu8k_envelope_t mod_envelope; + + int64_t lfo1_speed, lfo2_speed; + emu8k_mem_internal_t lfo1_count, lfo2_count; + int32_t lfo1_delay_samples, lfo2_delay_samples; + int vol_l, vol_r; + + int16_t fixed_modenv_filter_height; + int16_t fixed_modenv_pitch_height; + int16_t fixed_lfo1_filt_mod; + int16_t fixed_lfo1_vibrato; + int16_t fixed_lfo1_tremolo; + int16_t fixed_lfo2_vibrato; + + /* filter internal data. */ + int filterq_idx; + int32_t filt_att; + int64_t filt_buffer[5]; + +} emu8k_voice_t; + typedef struct emu8k_t { - struct - { - uint32_t cpf; - uint32_t ptrx; - uint32_t cvcf; - uint32_t vtft; - uint32_t psst; - uint32_t csl; - - uint32_t ccca; + emu8k_voice_t voice[32]; - uint16_t init1, init2, init3, init4; - - uint16_t envvol; - uint16_t dcysusv; - uint16_t envval; - uint16_t dcysus; - uint16_t atkhldv; - uint16_t lfo1val, lfo2val; - uint16_t atkhld; - uint16_t ip; - uint16_t ifatn; - uint16_t pefe; - uint16_t fmmod; - uint16_t tremfrq; - uint16_t fm2frq2; - - int voice_on; - - uint64_t addr; - uint64_t loop_start, loop_end; - - uint16_t pitch; - int attenuation; - int env_state, env_vol; - int env_attack, env_decay, env_sustain, env_release; + uint16_t hwcf1, hwcf2, hwcf3; + uint32_t hwcf4, hwcf5, hwcf6, hwcf7; - int menv_state, menv_vol; - int menv_attack, menv_decay, menv_sustain, menv_release; - - int lfo1_count, lfo2_count; - int8_t lfo1_fmmod, lfo2_fmmod; - int8_t lfo1_trem; - int vol_l, vol_r; - - int8_t fe_height; - - int64_t vlp, vbp, vhp; - int32_t q; - - int filter_offset; - -/* float vlp, vbp, vhp; - float q;*/ - - int cutoff; - } voice[32]; - - uint32_t hwcf1, hwcf2, hwcf3; - uint32_t hwcf4, hwcf5, hwcf6; + uint16_t init1[32], init2[32], init3[32], init4[32]; uint32_t smalr, smarr, smalw, smarw; uint16_t smld_buffer, smrd_buffer; @@ -68,23 +359,421 @@ typedef struct emu8k_t uint16_t c02_read; - uint16_t id; - - int16_t *ram, *rom; - + uint16_t id; + + /* The empty block is used to act as an unallocated memory returning zero. */ + int16_t *ram, *rom, *empty; + + /* RAM pointers are a way to avoid checking ram boundaries on read */ + int16_t *ram_pointers[0x100]; uint32_t ram_end_addr; - + int cur_reg, cur_voice; int timer_count; int16_t out_l, out_r; + emu8k_chorus_eng_t chorus_engine; + int32_t chorus_in_buffer[MAXSOUNDBUFLEN]; + emu8k_reverb_eng_t reverb_engine; + int32_t reverb_in_buffer[MAXSOUNDBUFLEN]; + int pos; int32_t buffer[MAXSOUNDBUFLEN * 2]; } emu8k_t; + + void emu8k_init(emu8k_t *emu8k, int onboard_ram); void emu8k_close(emu8k_t *emu8k); void emu8k_update(emu8k_t *emu8k); + + + + +/* + +Section E - Introduction to the EMU8000 Chip + + The EMU8000 has its roots in E-mu's Proteus sample playback + modules and their renowned Emulator sampler. The EMU8000 has + 32 individual oscillators, each playing back at 44.1 kHz. By + incorporating sophisticated sample interpolation algorithms + and digital filtering, the EMU8000 is capable of producing + high fidelity sample playback. + + The EMU8000 has an extensive modulation capability using two + sine-wave LFOs (Low Frequency Oscillator) and two multi- + stage envelope generators. + + What exactly does modulation mean? Modulation means to + dynamically change a parameter of an audio signal, whether + it be the volume (amplitude modulation, or tremolo), pitch + (frequency modulation, or vibrato) or filter cutoff + frequency (filter modulation, or wah-wah). To modulate + something we would require a modulation source, and a + modulation destination. In the EMU8000, the modulation + sources are the LFOs and the envelope generators, and the + modulation destinations can be the pitch, the volume or the + filter cutoff frequency. + + The EMU8000's LFOs and envelope generators provide a complex + modulation environment. Each sound producing element of the + EMU8000 consists of a resonant low-pass filter, two LFOs, in + which one modulates the pitch (LFO2), and the other + modulates pitch, filter cutoff and volume (LFO1) + simultaneously. There are two envelope generators; envelope + 1 contours both pitch and filter cutoff simultaneously, and + envelope 2 contours volume. The output stage consists of an + effects engine that mixes the dry signals with the + Reverb/chorus level signals to produce the final mix. + + What are the EMU8000 sound elements? + + Each of the sound elements in an EMU8000 consists of the + following: + + Oscillator + An oscillator is the source of an audio signal. + + Low Pass Filter + The low pass filter is responsible for modifying the + timbres of an instrument. The low pass filter's filter + cutoff values can be varied from 100 Hz to 8000 Hz. By + changing the values of the filter cutoff, a myriad of + analogue sounding filter sweeps can be achieved. An + example of a GM instrument that makes use of filter sweep + is instrument number 87, Lead 7 (fifths). + + Amplifier + The amplifier determines the loudness of an audio signal. + + LFO1 + An LFO, or Low Frequency Oscillator, is normally used to + periodically modulate, that is, change a sound parameter, + whether it be volume (amplitude modulation), pitch + (frequency modulation) or filter cutoff (filter + modulation). It operates at sub-audio frequency from + 0.042 Hz to 10.71 Hz. The LFO1 in the EMU8000 modulates + the pitch, volume and filter cutoff simultaneously. + + LFO2 + The LFO2 is similar to the LFO1, except that it modulates + the pitch of the audio signal only. + + Resonance + A filter alone would be like an equalizer, making a + bright audio signal duller, but the addition of resonance + greatly increases the creative potential of a filter. + Increasing the resonance of a filter makes it emphasize + signals at the cutoff frequency, giving the audio signal + a subtle wah-wah, that is, imagine a siren sound going + from bright to dull to bright again periodically. + + LFO1 to Volume (Tremolo) + The LFO1's output is routed to the amplifier, with the + depth of oscillation determined by LFO1 to Volume. LFO1 + to Volume produces tremolo, which is a periodic + fluctuation of volume. Lets say you are listening to a + piece of music on your home stereo system. When you + rapidly increase and decrease the playback volume, you + are creating tremolo effect, and the speed in which you + increases and decreases the volume is the tremolo rate + (which corresponds to the speed at which the LFO is + oscillating). An example of a GM instrument that makes + use of LFO1 to Volume is instrument number 45, Tremolo + Strings. + + LFO1 to Filter Cutoff (Wah-Wah) + The LFO1's output is routed to the filter, with the depth + of oscillation determined by LFO1 to Filter. LFO1 to + Filter produces a periodic fluctuation in the filter + cutoff frequency, producing an effect very similar to + that of a wah-wah guitar (see resonance for a description + of wah-wah) An example of a GM instrument that makes + use of LFO1 to Filter Cutoff is instrument number 19, + Rock Organ. + + LFO1 to Pitch (Vibrato) + The LFO1's output is routed to the oscillator, with the + depth of oscillation determined by LFO1 to Pitch. LFO1 to + Pitch produces a periodic fluctuation in the pitch of the + oscillator, producing a vibrato effect. An example of a + GM instrument that makes use of LFO1 to Pitch is + instrument number 57, Trumpet. + + LFO2 to Pitch (Vibrato) + The LFO1 in the EMU8000 can simultaneously modulate + pitch, volume and filter. LFO2, on the other hand, + modulates only the pitch, with the depth of modulation + determined by LFO2 to Pitch. LFO2 to Pitch produces a + periodic fluctuation in the pitch of the oscillator, + producing a vibrato effect. When this is coupled with + LFO1 to Pitch, a complex vibrato effect can be achieved. + + Volume Envelope + The character of a musical instrument is largely + determined by its volume envelope, the way in which the + level of the sound changes with time. For example, + percussive sounds usually start suddenly and then die + away, whereas a bowed sound might take quite some time to + start and then sustain at a more or less fixed level. + + A six-stage envelope makes up the volume envelope of the + EMU8000. The six stages are delay, attack, hold, decay, + sustain and release. The stages can be described as + follows: + + Delay The time between when a key is played and when + the attack phase begins + Attack The time it takes to go from zero to the peak + (full) level. + Hold The time the envelope will stay at the peak + level before starting the decay phase. + Decay The time it takes the envelope to go from the + peak level to the sustain level. + Sustain The level at which the envelope remains as long + as a key is held down. + Release The time it takes the envelope to fall to the + zero level after the key is released. + + Using these six parameters can yield very realistic + reproduction of the volume envelope characteristics of + many musical instruments. + + Pitch and Filter Envelope + The pitch and filter envelope is similar to the volume + envelope in that it has the same envelope stages. The + difference between them is that whereas the volume + envelope contours the volume of the instrument over time, + the pitch and filter envelope contours the pitch and + filter values of the instrument over time. The pitch + envelope is particularly useful in putting the finishing + touches in simulating a natural instrument. For example, + some wind instruments tend to go slightly sharp when they + are first blown, and this characteristic can be simulated + by setting up a pitch envelope with a fairly fast attack + and decay. The filter envelope, on the other hand, is + useful in creating synthetic sci-fi sound textures. An + example of a GM instrument that makes use of the filter + envelope is instrument number 86, Pad 8 (Sweep). + + Pitch/Filter Envelope Modulation + These two parameters determine the modulation depth of + the pitch and filter envelope. In the wind instrument + example above, a small amount of pitch envelope + modulation is desirable to simulate its natural pitch + characteristics. + + This rich modulation capability of the EMU8000 is fully + exploited by the SB AWE32 MIDI drivers. The driver also + provides you with a means to change these parameters over + MIDI in real time. Refer to the section "How do I change an + instrument's sound parameter in real time" for more + information. + + + + + Room 1 - 3 + This group of reverb variation simulates the natural + ambiance of a room. Room 1 simulates a small room, Room 2 + simulates a slightly bigger room, and Room 3 simulates a + big room. + + Hall 1 - 2 + This group of reverb variation simulates the natural + ambiance of a concert hall. It has greater depth than the + room variations. Again, Hall 1 simulates a small hall, + and Hall 2 simulates a larger hall. + + Plate + Back in the old days, reverb effects were sometimes + produced using a metal plate, and this type of reverb + produces a metallic echo. The SB AWE32's Plate variation + simulates this form of reverb. + + Delay + This reverb produces a delay, that is, echo effect. + + Panning Delay + This reverb variation produces a delay effect that is + continuously panned left and right. + + Chorus 1 - 4 + Chorus produces a "beating" effect. The chorus effects + are more prominent going from chorus 1 to chorus 4. + + Feedback Chorus + This chorus variation simulates a soft "swishing" effect. + + Flanger + This chorus variation produces a more prominent feedback + chorus effect. + + Short Delay + This chorus variation simulates a delay repeated in a + short time. + + Short Delay (feed back) + This chorus variation simulates a short delay repeated + (feedback) many times. + + + +Registers to write the Chorus Parameters to (all are 16-bit, unless noted): +(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) +( 3409 = register 3, port A20, voice 9) + +0x3409 +0x340C +0x3603 +0x1409 (32-Bit) +0x140A (32-Bit) +then write 0x8000 to 0x140D (32-Bit) +and then 0x0000 to 0x140E (32-Bit) + +Chorus Parameters: + +Chorus 1 Chorus 2 Chorus 3 Chorus 4 Feedback Flanger + +0xE600 0xE608 0xE610 0xE620 0xE680 0xE6E0 +0x03F6 0x031A 0x031A 0x0269 0x04D3 0x044E +0xBC2C 0xBC6E 0xBC84 0xBC6E 0xBCA6 0xBC37 +0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 +0x006D 0x017C 0x0083 0x017C 0x005B 0x0026 + +Short Delay Short Delay + Feedback + +0xE600 0xE6C0 +0x0B06 0x0B06 +0xBC00 0xBC00 +0xE000 0xE000 +0x0083 0x0083 + +// Chorus Params +typedef struct { + WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) + WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] + WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) + DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] + DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) + } CHORUS_TYPE; + + +Registers to write the Reverb Parameters to (they are all 16-bit): +(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) +( 3409 = register 3, port A20, voice 9) + +0x2403,0x2405,0x361F,0x2407,0x2614,0x2616,0x240F,0x2417, +0x241F,0x2607,0x260F,0x2617,0x261D,0x261F,0x3401,0x3403, +0x2409,0x240B,0x2411,0x2413,0x2419,0x241B,0x2601,0x2603, +0x2609,0x260B,0x2611,0x2613 + +Reverb Parameters: + +Room 1: + +0xB488,0xA450,0x9550,0x84B5,0x383A,0x3EB5,0x72F4,0x72A4, +0x7254,0x7204,0x7204,0x7204,0x4416,0x4516,0xA490,0xA590, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Room 2: + +0xB488,0xA458,0x9558,0x84B5,0x383A,0x3EB5,0x7284,0x7254, +0x7224,0x7224,0x7254,0x7284,0x4448,0x4548,0xA440,0xA540, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Room 3: + +0xB488,0xA460,0x9560,0x84B5,0x383A,0x3EB5,0x7284,0x7254, +0x7224,0x7224,0x7254,0x7284,0x4416,0x4516,0xA490,0xA590, +0x842C,0x852C,0x842C,0x852C,0x842B,0x852B,0x842B,0x852B, +0x842A,0x852A,0x842A,0x852A + +Hall 1: + +0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7284,0x7254, +0x7224,0x7224,0x7254,0x7284,0x4448,0x4548,0xA440,0xA540, +0x842B,0x852B,0x842B,0x852B,0x842A,0x852A,0x842A,0x852A, +0x8429,0x8529,0x8429,0x8529 + +Hall 2: + +0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7254,0x7234, +0x7224,0x7254,0x7264,0x7294,0x44C3,0x45C3,0xA404,0xA504, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Plate: + +0xB4FF,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7234,0x7234, +0x7234,0x7234,0x7234,0x7234,0x4448,0x4548,0xA440,0xA540, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Delay: + +0xB4FF,0xA470,0x9500,0x84B5,0x333A,0x39B5,0x7204,0x7204, +0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500,0xA4FF,0xA5FF, +0x8420,0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, +0x8420,0x8520,0x8420,0x8520 + +Panning Delay: + +0xB4FF,0xA490,0x9590,0x8474,0x333A,0x39B5,0x7204,0x7204, +0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500,0xA4FF,0xA5FF, +0x8420,0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, +0x8420,0x8520,0x8420,0x8520 + +Registers to write the EQ Parameters to (16-Bit): +(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) +( 3409 = register 3, port A20, voice 9) + +Bass: + +0x3601 +0x3611 + +Treble: + +0x3411 +0x3413 +0x341B +0x3607 +0x360B +0x360D +0x3617 +0x3619 + +Total: + +write the 0x0263 + 3rd parameter of the Bass EQ + 9th parameter of Treble EQ to 0x3615. +write the 0x8363 + 3rd parameter of the Bass EQ + 9th parameter of Treble EQ to 0x3615. + + +Bass Parameters: + +0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: + +0xD26A 0xD25B 0xD24C 0xD23D 0xD21F 0xC208 0xC219 0xC22A 0xC24C 0xC26E 0xC248 0xC26A +0xD36A 0xD35B 0xD34C 0xD33D 0xC31F 0xC308 0xC308 0xC32A 0xC34C 0xC36E 0xC384 0xC36A +0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 + +Treble Parameters: + +0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: +0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821D 0x821C +0xC26A 0xC25B 0xC24C 0xC23D 0xC21F 0xD208 0xD208 0xD208 0xD208 0xD208 0xD219 0xD22A +0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031D 0x031C +0xC36A 0xC35B 0xC34C 0xC33D 0xC31F 0xD308 0xD308 0xD308 0xD308 0xD308 0xD319 0xD32A +0x021E 0x021E 0x021E 0x021E 0x021E 0x021E 0x021D 0x021C 0x021A 0x0219 0x0219 0x0219 +0xD208 0xD208 0xD208 0xD208 0xD208 0xD208 0xD219 0xD22A 0xD24C 0xD26E 0xD26E 0xD26E +0x831E 0x831E 0x831E 0x831E 0x831E 0x831E 0x831D 0x831C 0x831A 0x8319 0x8319 0x8319 +0xD308 0xD308 0xD308 0xD308 0xD308 0xD308 0xD3019 0xD32A 0xD34C 0xD36E 0xD36E 0xD36E +0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 +*/ From b1f4748eafdbb03ca528e4e8c65597850811d923 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 31 Aug 2017 14:26:54 +0100 Subject: [PATCH 0141/1050] Fixed colour compare in EGA/VGA - fixes graphics issues in Crystal Dream II. --- src/vid_ega.c | 16 ++++++++-------- src/vid_svga.c | 32 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index ca5af05..6531b0b 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -860,18 +860,18 @@ uint8_t ega_read(uint32_t addr, void *p) ega->ld = ega->vram[addr | 0x3]; if (ega->readmode) { - temp = (ega->colournocare & 1) ? 0xff : 0; - temp &= ega->la; + temp = ega->la; temp ^= (ega->colourcompare & 1) ? 0xff : 0; - temp2 = (ega->colournocare & 2) ? 0xff : 0; - temp2 &= ega->lb; + temp &= (ega->colournocare & 1) ? 0xff : 0; + temp2 = ega->lb; temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; - temp3 = (ega->colournocare & 4) ? 0xff : 0; - temp3 &= ega->lc; + temp2 &= (ega->colournocare & 2) ? 0xff : 0; + temp3 = ega->lc; temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; - temp4 = (ega->colournocare & 8) ? 0xff : 0; - temp4 &= ega->ld; + temp3 &= (ega->colournocare & 4) ? 0xff : 0; + temp4 = ega->ld; temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; + temp4 &= (ega->colournocare & 8) ? 0xff : 0; return ~(temp | temp2 | temp3 | temp4); } return ega->vram[addr | readplane]; diff --git a/src/vid_svga.c b/src/vid_svga.c index ca09163..7e9f7e7 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -994,18 +994,18 @@ uint8_t svga_read(uint32_t addr, void *p) if (svga->readmode) { - temp = (svga->colournocare & 1) ? 0xff : 0; - temp &= svga->la; + temp = svga->la; temp ^= (svga->colourcompare & 1) ? 0xff : 0; - temp2 = (svga->colournocare & 2) ? 0xff : 0; - temp2 &= svga->lb; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; - temp3 = (svga->colournocare & 4) ? 0xff : 0; - temp3 &= svga->lc; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; - temp4 = (svga->colournocare & 8) ? 0xff : 0; - temp4 &= svga->ld; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 8) ? 0xff : 0; return ~(temp | temp2 | temp3 | temp4); } //pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); @@ -1231,18 +1231,18 @@ uint8_t svga_read_linear(uint32_t addr, void *p) svga->ld = svga->vram[addr | 0x3]; if (svga->readmode) { - temp = (svga->colournocare & 1) ? 0xff : 0; - temp &= svga->la; + temp = svga->la; temp ^= (svga->colourcompare & 1) ? 0xff : 0; - temp2 = (svga->colournocare & 2) ? 0xff : 0; - temp2 &= svga->lb; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; - temp3 = (svga->colournocare & 4) ? 0xff : 0; - temp3 &= svga->lc; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; - temp4 = (svga->colournocare & 8) ? 0xff : 0; - temp4 &= svga->ld; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 8) ? 0xff : 0; return ~(temp | temp2 | temp3 | temp4); } //printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); From b349bdc141b5c5cde192f51be65583eaa15309a9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 31 Aug 2017 15:14:44 +0100 Subject: [PATCH 0142/1050] Improved SB16 tone controls. Patch from JosepMa. --- src/sound_sb.c | 57 +++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index f52fea6..3355bfe 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -42,6 +42,12 @@ typedef struct sb_t int opl_emu; } sb_t; +/* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. + Note that for positive dB values, this is not amplitude, it is amplitude-1. */ +const float sb_bass_treble_4bits[]= { + 0.199526231, 0.25, 0.316227766, 0.398107170, 0.5, 0.63095734, 0.794328234, 1, + 0, 0.25892541, 0.584893192, 1, 1.511886431, 2.16227766, 3, 4.011872336 +}; static int sb_att[]= { @@ -82,14 +88,15 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { - if (mixer->bass_l>8) out_l = (out_l + (((int16_t) low_iir(0, (float)out_l) * (mixer->bass_l - 8)) >> 1)) * ((15 - mixer->bass_l) + 16) >> 5; - if (mixer->bass_r>8) out_r = (out_r + (((int16_t) low_iir(1, (float)out_r) * (mixer->bass_r - 8)) >> 1)) * ((15 - mixer->bass_r) + 16) >> 5; - if (mixer->treble_l>8) out_l = (out_l + (((int16_t) high_iir(0, (float)out_l) * (mixer->treble_l - 8)) >> 1)) * ((15 - mixer->treble_l) + 16) >> 5; - if (mixer->treble_r>8) out_r = (out_r + (((int16_t) high_iir(1, (float)out_r) * (mixer->treble_r - 8)) >> 1)) * ((15 - mixer->treble_r) + 16) >> 5; - if (mixer->bass_l<8) out_l = (out_l + (((int16_t) low_cut_iir(0, (float)out_l) * (8 - mixer->bass_l)) >> 1)) * (mixer->bass_l + 16) >> 5; - if (mixer->bass_r<8) out_r = (out_r + (((int16_t) low_cut_iir(1, (float)out_r) * (8 - mixer->bass_r)) >> 1)) * (mixer->bass_r + 16) >> 5; - if (mixer->treble_l<8) out_l = (out_l + (((int16_t)high_cut_iir(0, (float)out_l) * (8 - mixer->treble_l)) >> 1)) * (mixer->treble_l + 16) >> 5; - if (mixer->treble_r<8) out_r = (out_r + (((int16_t)high_cut_iir(1, (float)out_r) * (8 - mixer->treble_r)) >> 1)) * (mixer->treble_r + 16) >> 5; + // This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage + if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); + if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); + if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); + if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); + if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->bass_l])); + if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->bass_r])); + if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->treble_l])); + if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->treble_r])); } buffer[c] += out_l; @@ -133,14 +140,15 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { - if (mixer->bass_l>8) out_l = (out_l + (((int16_t) low_iir(0, (float)out_l) * (mixer->bass_l - 8)) >> 1)) * ((15 - mixer->bass_l) + 16) >> 5; - if (mixer->bass_r>8) out_r = (out_r + (((int16_t) low_iir(1, (float)out_r) * (mixer->bass_r - 8)) >> 1)) * ((15 - mixer->bass_r) + 16) >> 5; - if (mixer->treble_l>8) out_l = (out_l + (((int16_t) high_iir(0, (float)out_l) * (mixer->treble_l - 8)) >> 1)) * ((15 - mixer->treble_l) + 16) >> 5; - if (mixer->treble_r>8) out_r = (out_r + (((int16_t) high_iir(1, (float)out_r) * (mixer->treble_r - 8)) >> 1)) * ((15 - mixer->treble_r) + 16) >> 5; - if (mixer->bass_l<8) out_l = (out_l + (((int16_t) low_cut_iir(0, (float)out_l) * (8 - mixer->bass_l)) >> 1)) * (mixer->bass_l + 16) >> 5; - if (mixer->bass_r<8) out_r = (out_r + (((int16_t) low_cut_iir(1, (float)out_r) * (8 - mixer->bass_r)) >> 1)) * (mixer->bass_r + 16) >> 5; - if (mixer->treble_l<8) out_l = (out_l + (((int16_t)high_cut_iir(0, (float)out_l) * (8 - mixer->treble_l)) >> 1)) * (mixer->treble_l + 16) >> 5; - if (mixer->treble_r<8) out_r = (out_r + (((int16_t)high_cut_iir(1, (float)out_r) * (8 - mixer->treble_r)) >> 1)) * (mixer->treble_r + 16) >> 5; + // This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage + if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); + if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); + if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); + if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); + if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->bass_l])); + if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->bass_r])); + if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->treble_l])); + if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->treble_r])); } buffer[c] += out_l; @@ -190,14 +198,15 @@ static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { - if (mixer->bass_l>8) out_l = (out_l + (((int16_t) low_iir(0, (float)out_l) * (mixer->bass_l - 8)) >> 1)) * ((15 - mixer->bass_l) + 16) >> 5; - if (mixer->bass_r>8) out_r = (out_r + (((int16_t) low_iir(1, (float)out_r) * (mixer->bass_r - 8)) >> 1)) * ((15 - mixer->bass_r) + 16) >> 5; - if (mixer->treble_l>8) out_l = (out_l + (((int16_t) high_iir(0, (float)out_l) * (mixer->treble_l - 8)) >> 1)) * ((15 - mixer->treble_l) + 16) >> 5; - if (mixer->treble_r>8) out_r = (out_r + (((int16_t) high_iir(1, (float)out_r) * (mixer->treble_r - 8)) >> 1)) * ((15 - mixer->treble_r) + 16) >> 5; - if (mixer->bass_l<8) out_l = (out_l + (((int16_t) low_cut_iir(0, (float)out_l) * (8 - mixer->bass_l)) >> 1)) * (mixer->bass_l + 16) >> 5; - if (mixer->bass_r<8) out_r = (out_r + (((int16_t) low_cut_iir(1, (float)out_r) * (8 - mixer->bass_r)) >> 1)) * (mixer->bass_r + 16) >> 5; - if (mixer->treble_l<8) out_l = (out_l + (((int16_t)high_cut_iir(0, (float)out_l) * (8 - mixer->treble_l)) >> 1)) * (mixer->treble_l + 16) >> 5; - if (mixer->treble_r<8) out_r = (out_r + (((int16_t)high_cut_iir(1, (float)out_r) * (8 - mixer->treble_r)) >> 1)) * (mixer->treble_r + 16) >> 5; + // This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage + if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); + if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); + if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); + if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); + if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->bass_l])); + if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->bass_r])); + if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->treble_l])); + if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->treble_r])); } buffer[c] += out_l; From a3a60211b0726371415b89444227bda0dd368efe Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 31 Aug 2017 16:19:34 +0100 Subject: [PATCH 0143/1050] Fixed off-by-one error in 16-bit autoinit DMA. --- src/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dma.c b/src/dma.c index 7c82747..8c58bb2 100644 --- a/src/dma.c +++ b/src/dma.c @@ -663,7 +663,7 @@ int dma_channel_write(int channel, uint16_t val) { if (dma16.mode[channel] & 0x10) /*Auto-init*/ { - dma16.cc[channel] = dma16.cb[channel] + 1; + dma16.cc[channel] = dma16.cb[channel]; dma16.ac[channel] = dma16.ab[channel]; } else From d3232adef5f6277218b6a3996177fab967de3bff Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 1 Sep 2017 11:34:20 +0100 Subject: [PATCH 0144/1050] Add LPT device emulation framework. Move long-broken DAC and Sound Source emulation to new framework. Add stereo DAC emulation. --- src/Makefile.am | 4 +- src/Makefile.linux32 | 4 +- src/Makefile.linux32-wx-sdl2 | 4 +- src/Makefile.linux64 | 4 +- src/Makefile.linux64-wx-sdl2 | 4 +- src/Makefile.mingw | 4 +- src/Makefile.mingw-network | 4 +- src/Makefile.mingw-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2-network | 6 +- src/Makefile.mingw64 | 4 +- src/Makefile.osx64-wx-sdl2 | 4 +- src/amstrad.c | 3 +- src/dac.c | 70 ---- src/dac.h | 3 - src/filters.h | 66 ++++ src/lpt.c | 73 +++- src/lpt.h | 18 + src/lpt_dac.c | 115 ++++++ src/lpt_dac.h | 2 + src/lpt_dss.c | 111 ++++++ src/lpt_dss.h | 1 + src/pc.c | 11 +- src/pc.xrc | 44 +++ src/wx-config.c | 26 +- src/wx-resources.cpp | 546 ++++++++++++++++------------- 25 files changed, 793 insertions(+), 342 deletions(-) delete mode 100644 src/dac.c delete mode 100644 src/dac.h create mode 100644 src/lpt_dac.c create mode 100644 src/lpt_dac.h create mode 100644 src/lpt_dss.c create mode 100644 src/lpt_dss.h diff --git a/src/Makefile.am b/src/Makefile.am index c9a7652..0f1d680 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,10 +15,10 @@ amrefresh: pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ -dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ +dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ -laserxt.c lpt.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ +laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 3bc4ec2..5e620c1 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -7,10 +7,10 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index cb8f5a1..feb4453 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -6,10 +6,10 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(sh CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 7b356b2..336cdfc 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -6,10 +6,10 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index dc3baa8..8a99245 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -6,10 +6,10 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(sh CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ -dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 109d18a..2593924 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -4,10 +4,10 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.mingw-network b/src/Makefile.mingw-network index 509c330..67b7239 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -5,10 +5,10 @@ MAKE = make.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -DUSE_NETWORKING OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index f8d2254..e207c89 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -7,10 +7,10 @@ WXINCLUDE = C:/MinGW/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 3652a39..93e7d23 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -3,14 +3,14 @@ CPP = g++ CC = gcc WINDRES = windres.exe WXVERSION = 31 -WXINCLUDE = C:/MinGW/include/wx/ +WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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 b67ff1b..b0f64b1 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -4,10 +4,10 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ + codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ scat.o serial.o sio.o sis496.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.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index b9175d0..a96aa59 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -5,10 +5,10 @@ WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ -dac.o device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ +device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/amstrad.c b/src/amstrad.c index 4c5cdf9..b5502c1 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -1,6 +1,5 @@ #include #include "ibm.h" -#include "dac.h" #include "io.h" #include "keyboard.h" #include "lpt.h" @@ -16,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 b8f7052..0000000 --- a/src/dac.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "ibm.h" -#include "dac.h" -#include "sound.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) -{ -// printf("Write DAC ctrl %02X %i\n",val,lptfifo); - if (dacctrl&8 && !(val&8) && (lptfifo!=16)) - { -// dac=dac2; - 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[MAXSOUNDBUFLEN+20]; -int dacbufferpos=0; -void getdacsamp() -{ - if (dacbufferposSOUNDBUFLEN) dacbufferpos=SOUNDBUFLEN; - for (c=0;c0; n--) { + x[n] = x[n-1]; + y[n] = y[n-1]; + } + + //Calculate the new output + x[0] = NewSample; + y[0] = ACoef[0] * x[0]; + for(n=1; n<=NCoef; n++) + y[0] += ACoef[n] * x[n] - BCoef[n] * y[n]; + + return y[0]; +} + +#undef NCoef +#define NCoef 1 +/*Basic high pass to remove DC bias. fc=10Hz*/ +static float dac_iir(int i, float NewSample) { + float ACoef[NCoef+1] = { + 0.99901119820285345000, + -0.99901119820285345000 + }; + + float BCoef[NCoef+1] = { + 1.00000000000000000000, + -0.99869185905052738000 + }; + + static float y[2][NCoef+1]; //output samples + static float x[2][NCoef+1]; //input samples + int n; + + //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 + x[i][0] = NewSample; + y[i][0] = ACoef[0] * x[i][0]; + for(n=1; n<=NCoef; n++) + y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n]; + + return y[i][0]; +} diff --git a/src/lpt.c b/src/lpt.c index 5550a98..2f47c6b 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -1,8 +1,65 @@ #include "ibm.h" -#include "dac.h" #include "io.h" #include "lpt.h" +#include "lpt_dac.h" +#include "lpt_dss.h" + +char lpt1_device_name[16]; + +static struct +{ + char name[64]; + char internal_name[16]; + lpt_device_t *device; +} lpt_devices[] = +{ + {"None", "none", NULL}, + {"Disney Sound Source", "dss", &dss_device}, + {"LPT DAC / Covox Speech Thing", "lpt_dac", &lpt_dac_device}, + {"Stereo LPT DAC", "lpt_dac_stereo", &lpt_dac_stereo_device}, + {"", "", NULL} +}; + +char *lpt_device_get_name(int id) +{ + if (strlen(lpt_devices[id].name) == 0) + return NULL; + return lpt_devices[id].name; +} +char *lpt_device_get_internal_name(int id) +{ + if (strlen(lpt_devices[id].internal_name) == 0) + return NULL; + return lpt_devices[id].internal_name; +} + +static lpt_device_t *lpt1_device; +static void *lpt1_device_p; + +void lpt1_device_init() +{ + int c = 0; + + while (strcmp(lpt_devices[c].internal_name, lpt1_device_name) && strlen(lpt_devices[c].internal_name) != 0) + c++; + + if (strlen(lpt_devices[c].internal_name) == 0) + lpt1_device = NULL; + else + { + lpt1_device = lpt_devices[c].device; + if (lpt1_device) + lpt1_device_p = lpt1_device->init(); + } +} + +void lpt1_device_close() +{ + if (lpt1_device) + lpt1_device->close(lpt1_device_p); + lpt1_device = NULL; +} static uint8_t lpt1_dat, lpt2_dat; static uint8_t lpt1_ctrl, lpt2_ctrl; @@ -12,11 +69,13 @@ void lpt1_write(uint16_t port, uint8_t val, void *priv) switch (port & 3) { case 0: - writedac(0,val); + if (lpt1_device) + lpt1_device->write_data(val, lpt1_device_p); lpt1_dat = val; break; case 2: - writedacctrl(0,val); + if (lpt1_device) + lpt1_device->write_ctrl(val, lpt1_device_p); lpt1_ctrl = val; break; } @@ -28,7 +87,9 @@ uint8_t lpt1_read(uint16_t port, void *priv) case 0: return lpt1_dat; case 1: - return readdacfifo(); + if (lpt1_device) + return lpt1_device->read_status(lpt1_device_p); + return 0; case 2: return lpt1_ctrl; } @@ -40,11 +101,9 @@ void lpt2_write(uint16_t port, uint8_t val, void *priv) switch (port & 3) { case 0: - writedac(0,val); lpt2_dat = val; break; case 2: - writedacctrl(0,val); lpt2_ctrl = val; break; } @@ -56,7 +115,7 @@ uint8_t lpt2_read(uint16_t port, void *priv) case 0: return lpt2_dat; case 1: - return readdacfifo(); + return 0; case 2: return lpt2_ctrl; } diff --git a/src/lpt.h b/src/lpt.h index 0ff2e7b..7d12593 100644 --- a/src/lpt.h +++ b/src/lpt.h @@ -4,3 +4,21 @@ extern void lpt1_remove(); extern void lpt2_init(uint16_t port); extern void lpt2_remove(); extern void lpt2_remove_ams(); + +void lpt1_device_init(); +void lpt1_device_close(); + +char *lpt_device_get_name(int id); +char *lpt_device_get_internal_name(int id); + +extern char lpt1_device_name[16]; + +typedef struct +{ + char name[80]; + void *(*init)(); + void (*close)(void *p); + void (*write_data)(uint8_t val, void *p); + void (*write_ctrl)(uint8_t val, void *p); + uint8_t (*read_status)(void *p); +} lpt_device_t; diff --git a/src/lpt_dac.c b/src/lpt_dac.c new file mode 100644 index 0000000..4daf7d2 --- /dev/null +++ b/src/lpt_dac.c @@ -0,0 +1,115 @@ +#include +#include "ibm.h" +#include "filters.h" +#include "lpt.h" +#include "lpt_dac.h" +#include "sound.h" + +typedef struct lpt_dac_t +{ + uint8_t dac_val_l, dac_val_r; + + int is_stereo; + int channel; + + int16_t buffer[2][MAXSOUNDBUFLEN]; + int pos; +} lpt_dac_t; + +static void dac_update(lpt_dac_t *lpt_dac) +{ + for (; lpt_dac->pos < sound_pos_global; lpt_dac->pos++) + { + lpt_dac->buffer[0][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_l ^ 0x80) * 0x40; + lpt_dac->buffer[1][lpt_dac->pos] = (int8_t)(lpt_dac->dac_val_r ^ 0x80) * 0x40; + } +} + + +static void dac_write_data(uint8_t val, void *p) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + + if (lpt_dac->is_stereo) + { + if (lpt_dac->channel) + lpt_dac->dac_val_r = val; + else + lpt_dac->dac_val_l = val; + } + else + lpt_dac->dac_val_l = lpt_dac->dac_val_r = val; + dac_update(lpt_dac); +} + +static void dac_write_ctrl(uint8_t val, void *p) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + + if (lpt_dac->is_stereo) + lpt_dac->channel = val & 0x01; +} + +static uint8_t dac_read_status(void *p) +{ + return 0; +} + + +static void dac_get_buffer(int32_t *buffer, int len, void *p) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + int c; + + dac_update(lpt_dac); + + for (c = 0; c < len; c++) + { + buffer[c*2] += dac_iir(0, lpt_dac->buffer[0][c]); + buffer[c*2 + 1] += dac_iir(1, lpt_dac->buffer[1][c]); + } + lpt_dac->pos = 0; +} + +static void *dac_init() +{ + lpt_dac_t *lpt_dac = malloc(sizeof(lpt_dac_t)); + memset(lpt_dac, 0, sizeof(lpt_dac_t)); + + sound_add_handler(dac_get_buffer, lpt_dac); + + return lpt_dac; +} +static void *dac_stereo_init() +{ + lpt_dac_t *lpt_dac = dac_init(); + + lpt_dac->is_stereo = 1; + + return lpt_dac; +} +static void dac_close(void *p) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + + free(lpt_dac); +} + +lpt_device_t lpt_dac_device = +{ + "LPT DAC / Covox Speech Thing", + dac_init, + dac_close, + dac_write_data, + dac_write_ctrl, + dac_read_status +}; +lpt_device_t lpt_dac_stereo_device = +{ + "Stereo LPT DAC", + dac_stereo_init, + dac_close, + dac_write_data, + dac_write_ctrl, + dac_read_status +}; diff --git a/src/lpt_dac.h b/src/lpt_dac.h new file mode 100644 index 0000000..b5f9815 --- /dev/null +++ b/src/lpt_dac.h @@ -0,0 +1,2 @@ +extern lpt_device_t lpt_dac_device; +extern lpt_device_t lpt_dac_stereo_device; diff --git a/src/lpt_dss.c b/src/lpt_dss.c new file mode 100644 index 0000000..3e3c55e --- /dev/null +++ b/src/lpt_dss.c @@ -0,0 +1,111 @@ +#include +#include "ibm.h" +#include "filters.h" +#include "lpt.h" +#include "lpt_dac.h" +#include "sound.h" + +typedef struct dss_t +{ + uint8_t fifo[16]; + int read_idx, write_idx; + + uint8_t dac_val; + + int time; + + int16_t buffer[MAXSOUNDBUFLEN]; + int pos; +} dss_t; + +static void dss_update(dss_t *dss) +{ + for (; dss->pos < sound_pos_global; dss->pos++) + dss->buffer[dss->pos] = (int8_t)(dss->dac_val ^ 0x80) * 0x40; +} + + +static void dss_write_data(uint8_t val, void *p) +{ + dss_t *dss = (dss_t *)p; + + if ((dss->write_idx - dss->read_idx) < 16) + { + dss->fifo[dss->write_idx & 15] = val; + dss->write_idx++; + } +} + +static void dss_write_ctrl(uint8_t val, void *p) +{ +} + +static uint8_t dss_read_status(void *p) +{ + dss_t *dss = (dss_t *)p; + + if ((dss->write_idx - dss->read_idx) >= 16) + return 0x40; + return 0; +} + + +static void dss_get_buffer(int32_t *buffer, int len, void *p) +{ + dss_t *dss = (dss_t *)p; + int c; + + dss_update(dss); + + for (c = 0; c < len*2; c += 2) + { + int16_t val = (int16_t)dss_iir((float)dss->buffer[c >> 1]); + + buffer[c] += val; + buffer[c+1] += val; + } + + dss->pos = 0; +} + +static void dss_callback(void *p) +{ + dss_t *dss = (dss_t *)p; + + dss_update(dss); + + if ((dss->write_idx - dss->read_idx) > 0) + { + dss->dac_val = dss->fifo[dss->read_idx & 15]; + dss->read_idx++; + } + + dss->time += (TIMER_USEC * (1000000.0 / 7000.0)); +} + +static void *dss_init() +{ + dss_t *dss = malloc(sizeof(dss_t)); + memset(dss, 0, sizeof(dss_t)); + + sound_add_handler(dss_get_buffer, dss); + timer_add(dss_callback, &dss->time, TIMER_ALWAYS_ENABLED, dss); + + return dss; +} +static void dss_close(void *p) +{ + dss_t *dss = (dss_t *)p; + + free(dss); +} + +lpt_device_t dss_device = +{ + "Disney Sound Source", + dss_init, + dss_close, + dss_write_data, + dss_write_ctrl, + dss_read_status +}; diff --git a/src/lpt_dss.h b/src/lpt_dss.h new file mode 100644 index 0000000..6f85c1a --- /dev/null +++ b/src/lpt_dss.h @@ -0,0 +1 @@ +extern lpt_device_t dss_device; diff --git a/src/pc.c b/src/pc.c index 1faa7f7..76e452a 100644 --- a/src/pc.c +++ b/src/pc.c @@ -24,6 +24,7 @@ #include "ide.h" #include "keyboard.h" #include "keyboard_at.h" +#include "lpt.h" #include "model.h" #include "mouse.h" #include "nvr.h" @@ -381,7 +382,8 @@ void resetpchard() model_init(); mouse_emu_init(); video_init(); - speaker_init(); + speaker_init(); + lpt1_device_init(); #ifdef USE_NETWORKING vlan_reset(); //NETWORK @@ -590,6 +592,7 @@ void closepc() disc_close(1); dumpregs(); closevideo(); + lpt1_device_close(); mouse_emu_close(); device_close_all(); } @@ -774,6 +777,10 @@ void loadconfig(char *fn) enable_sync = config_get_int(CFG_MACHINE, NULL, "enable_sync", 1); + p = (char *)config_get_string(CFG_MACHINE, NULL, "lpt1_device", ""); + if (p) strcpy(lpt1_device_name, p); + else strcpy(lpt1_device_name, ""); + #ifdef USE_NETWORKING //network ethif = config_get_int(CFG_GLOBAL, NULL, "netinterface", 1); @@ -908,6 +915,8 @@ void saveconfig(char *fn) config_set_string(CFG_MACHINE, NULL, "netcard", network_card_get_internal_name(network_card_current)); #endif + config_set_string(CFG_MACHINE, NULL, "lpt1_device", lpt1_device_name); + for (d = 0; d < num_config_callbacks; ++d) if (config_callbacks[d].saveconfig) config_callbacks[d].saveconfig(); diff --git a/src/pc.xrc b/src/pc.xrc index 98c78b8..d99ce13 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -899,6 +899,50 @@ 0 + + + wxEXPAND + 5 + 0,0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + diff --git a/src/wx-config.c b/src/wx-config.c index 8da63c9..9aca8b5 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -8,6 +8,7 @@ #include "fdd.h" #include "gameport.h" #include "hdd.h" +#include "lpt.h" #include "model.h" #include "mouse.h" #include "mem.h" @@ -261,6 +262,7 @@ int config_dlgsave(void* hdlg) int temp_dynarec; int temp_fda_type, temp_fdb_type; int temp_mouse_type; + int temp_lpt1_device; #ifdef USE_NETWORKING int temp_network_card; #endif @@ -329,6 +331,9 @@ int config_dlgsave(void* hdlg) if (hdd_names[c]) hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); + temp_lpt1_device = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + #ifdef USE_NETWORKING h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; @@ -339,7 +344,8 @@ int config_dlgsave(void* hdlg) temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || temp_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel + temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel || + strcmp(lpt1_device_name, lpt_device_get_internal_name(temp_lpt1_device)) #ifdef USE_NETWORKING || temp_network_card != network_card_current #endif @@ -361,6 +367,7 @@ int config_dlgsave(void* hdlg) voodoo_enabled = temp_voodoo; cpu_use_dynarec = temp_dynarec; mouse_type = temp_mouse_type; + strcpy(lpt1_device_name, lpt_device_get_internal_name(temp_lpt1_device)); #ifdef USE_NETWORKING network_card_current = temp_network_card; #endif @@ -687,6 +694,23 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) } wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); + c = d = 0; + while (1) + { + char *s = lpt_device_get_name(c); + + if (!s) + break; + + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (!strcmp(lpt1_device_name, lpt_device_get_internal_name(c))) + d = c; + + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + recalc_hdd_list(hdlg, romstomodel[romset], 0); hd_changed = 0; diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 0621be6..9b89204 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1722,7 +1722,7 @@ static unsigned char xml_res_file_24[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_25 = 125407; +static size_t xml_res_size_25 = 127112; static unsigned char xml_res_file_25[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -3331,99 +3331,236 @@ static unsigned char xml_res_file_25[] = { 62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,100,114,105,118,101,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -32,110,97,109,101,61,34,80,65,78,69,76,95,68,82,73,86,69,83,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, -119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, -47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, -97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, -78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,68,68,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, +73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62,10, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, 68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, @@ -3454,7 +3591,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, 45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68, -49,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, 47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, @@ -3484,7 +3621,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, 111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, 119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, 68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, @@ -3500,164 +3637,103 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,111,105,99,101,98,111,111,107,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,72,66,95,68,69,70,65,85,76,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111, +105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,114,105,118,101,32,49,32,40,67,58,41,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, +65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, 76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, 84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, -79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,66,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, -78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,73,95,72,79, -82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,111, -105,99,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72,66, -95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,49,32, -40,67,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, -109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, -79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, From 970882c7ac978207ab074b6add84455c7f380ee6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 1 Sep 2017 11:34:36 +0100 Subject: [PATCH 0145/1050] Swap default LPT1 and LPT2 port assignments. --- src/lpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lpt.c b/src/lpt.c index 2f47c6b..d3264b2 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -124,8 +124,8 @@ uint8_t lpt2_read(uint16_t port, void *priv) void lpt_init() { - io_sethandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_sethandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + 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); } void lpt1_init(uint16_t port) From 17ea1ace1c0f8dd7a7c317ddd2853874da5180fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 1 Sep 2017 17:08:37 +0100 Subject: [PATCH 0146/1050] Tweaked timing system on 286+ interpreted CPUs - improves DAC sound quality. --- src/386.c | 3 ++- src/lpt_dac.c | 2 ++ src/lpt_dss.c | 2 ++ src/timer.c | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/386.c b/src/386.c index 6b81d79..10d6a79 100644 --- a/src/386.c +++ b/src/386.c @@ -217,12 +217,13 @@ void exec386(int cycs) int tempi; int cycdiff; int oldcyc; - int cycle_period = cycs / 2000; /*Use a 5us timing granularity*/ cycles+=cycs; // output=3; while (cycles>0) { + int cycle_period = (timer_count >> TIMER_SHIFT) + 1; + cycdiff=0; oldcyc=cycles; timer_start_period(cycles << TIMER_SHIFT); diff --git a/src/lpt_dac.c b/src/lpt_dac.c index 4daf7d2..d12f249 100644 --- a/src/lpt_dac.c +++ b/src/lpt_dac.c @@ -29,6 +29,8 @@ static void dac_update(lpt_dac_t *lpt_dac) static void dac_write_data(uint8_t val, void *p) { lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + + timer_clock(); if (lpt_dac->is_stereo) { diff --git a/src/lpt_dss.c b/src/lpt_dss.c index 3e3c55e..0f53edd 100644 --- a/src/lpt_dss.c +++ b/src/lpt_dss.c @@ -29,6 +29,8 @@ static void dss_write_data(uint8_t val, void *p) { dss_t *dss = (dss_t *)p; + timer_clock(); + if ((dss->write_idx - dss->read_idx) < 16) { dss->fifo[dss->write_idx & 15] = val; diff --git a/src/timer.c b/src/timer.c index 964e19a..381562e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -84,7 +84,7 @@ void timer_update_outstanding() if (*timers[c].enable && *timers[c].count < timer_latch) timer_latch = *timers[c].count; } - timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)) >> TIMER_SHIFT; + timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)); } void timer_reset() From ebf7faaae7553699cf41543e33f9dcd7799d67e0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 2 Sep 2017 07:59:08 +0100 Subject: [PATCH 0147/1050] Marked dac_iir() as inline. --- src/filters.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filters.h b/src/filters.h index 15047e2..dfeb91b 100644 --- a/src/filters.h +++ b/src/filters.h @@ -316,7 +316,7 @@ static inline float dss_iir(float NewSample) { #undef NCoef #define NCoef 1 /*Basic high pass to remove DC bias. fc=10Hz*/ -static float dac_iir(int i, float NewSample) { +static inline float dac_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.99901119820285345000, -0.99901119820285345000 From 96905fa3dec53e5d2bddf2c28ff5888edd9d41a8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 5 Sep 2017 21:06:20 +0100 Subject: [PATCH 0148/1050] Fixes to AWE32 chorus emulation. Patch from JosepMa. --- src/sound_emu8k.c | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index c736e32..9b15d6c 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -232,15 +232,15 @@ uint32_t rep_count_w = 0; # define READ16(addr, var) READ16_SWITCH(addr, var) \ { \ const char *name=0; \ - switch(addr) \ + switch(addr&0xF02) \ { \ - case 0x620: case 0x622: \ + case 0x600: case 0x602: \ name = PORT_NAMES[0][emu8k->cur_reg]; \ break; \ - case 0xA20: \ + case 0xA00: \ name = PORT_NAMES[1][emu8k->cur_reg]; \ break; \ - case 0xA22: \ + case 0xA02: \ name = PORT_NAMES[2][emu8k->cur_reg]; \ break; \ } \ @@ -256,15 +256,15 @@ uint32_t rep_count_w = 0; # define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) \ { \ const char *name=0; \ - switch(addr) \ + switch(addr&0xF02) \ { \ - case 0x620: case 0x622: \ + case 0x600: case 0x602: \ name = PORT_NAMES[0][emu8k->cur_reg]; \ break; \ - case 0xA20: \ + case 0xA00: \ name = PORT_NAMES[1][emu8k->cur_reg]; \ break; \ - case 0xA22: \ + case 0xA02: \ name = PORT_NAMES[2][emu8k->cur_reg]; \ break; \ } \ @@ -980,7 +980,8 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) emu8k->chorus_engine.feedback = (val&0xFF); break; case 12: - emu8k->chorus_engine.delay_samples_central = val; + /* Limiting this to a sane value given our buffer. */ + emu8k->chorus_engine.delay_samples_central = (val&0x1FFF); break; case 1: emu8k->reverb_engine.refl_in_amp = val&0xFF; @@ -1006,7 +1007,7 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) if (emu8k->voice[emu8k->cur_voice].env_engine_on && old_on != emu8k->voice[emu8k->cur_voice].env_engine_on) { - if (emu8k->hwcf3 != 0x04 && emu8k->cur_voice == 31) + if (emu8k->hwcf3 != 0x04) { /* This is a hack for some programs like Doom or cubic player 1.7 that don't initialize the hwcfg and init registers (doom does not init the card at all. only tests the cfg registers) */ @@ -1138,7 +1139,9 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) if (emu8k->init1[0] != 0x03FF) { /*(1/256th of a 44Khz sample) */ - emu8k->chorus_engine.delay_offset_samples_right = ((double)emu8k->hwcf4)/256.0; + /* clip the value to a reasonable value given our buffer */ + int32_t tmp = emu8k->hwcf4&0x1FFFFF; + emu8k->chorus_engine.delay_offset_samples_right = ((double)tmp)/256.0; } return; case 10: @@ -1266,6 +1269,7 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) { int32_t samples = ((val&0xFF)*emu8k->chorus_engine.delay_samples_central) >> 8; emu8k->chorus_engine.lfodepth_multip = samples; + } break; @@ -1511,18 +1515,16 @@ void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engi double readdouble = (double)engine->write - (double)engine->delay_samples_central - offset_lfo; int read = (int32_t)floor(readdouble); int fraction_part = (readdouble - (double)read)*65536.0; - if (read < 0) - read = 0; int next_value = read + 1; if(read < 0) { - read += MAXSOUNDBUFLEN; - if(next_value < 0) next_value += MAXSOUNDBUFLEN; + read += EMU8K_LFOCHORUS_SIZE; + if(next_value < 0) next_value += EMU8K_LFOCHORUS_SIZE; } - else if(next_value >= MAXSOUNDBUFLEN) + else if(next_value >= EMU8K_LFOCHORUS_SIZE) { - next_value -= MAXSOUNDBUFLEN; - if(read >= MAXSOUNDBUFLEN) read -= MAXSOUNDBUFLEN; + next_value -= EMU8K_LFOCHORUS_SIZE; + if(read >= EMU8K_LFOCHORUS_SIZE) read -= EMU8K_LFOCHORUS_SIZE; } int32_t dat1 = engine->chorus_left_buffer[read]; int32_t dat2 = engine->chorus_left_buffer[next_value]; @@ -1534,18 +1536,16 @@ void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engi /* Work right */ readdouble = (double)engine->write - (double)engine->delay_samples_central - engine->delay_offset_samples_right - offset_lfo; read = (int32_t)floor(readdouble); - if (read < 0) - read = 0; next_value = read + 1; if(read < 0) { - read += MAXSOUNDBUFLEN; - if(next_value < 0) next_value += MAXSOUNDBUFLEN; + read += EMU8K_LFOCHORUS_SIZE; + if(next_value < 0) next_value += EMU8K_LFOCHORUS_SIZE; } - else if(next_value >= MAXSOUNDBUFLEN) + else if(next_value >= EMU8K_LFOCHORUS_SIZE) { - next_value -= MAXSOUNDBUFLEN; - if(read >= MAXSOUNDBUFLEN) read -= MAXSOUNDBUFLEN; + next_value -= EMU8K_LFOCHORUS_SIZE; + if(read >= EMU8K_LFOCHORUS_SIZE) read -= EMU8K_LFOCHORUS_SIZE; } int32_t dat3 = engine->chorus_right_buffer[read]; int32_t dat4 = engine->chorus_right_buffer[next_value]; @@ -1554,7 +1554,7 @@ void emu8k_work_chorus(int32_t *inbuf, int32_t *outbuf, emu8k_chorus_eng_t *engi engine->chorus_right_buffer[engine->write] = *inbuf + ((dat3 * engine->feedback)>>8); ++engine->write; - engine->write %= MAXSOUNDBUFLEN; + engine->write %= EMU8K_LFOCHORUS_SIZE; engine->lfo_pos.addr +=engine->lfo_inc.addr; engine->lfo_pos.int_address &= 0xFFFF; @@ -2339,8 +2339,8 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram) cubic_table[c*4+2] = (-1.5 * x * x * x + 2.0 * x * x + 0.5 * x) ; cubic_table[c*4+3] = ( 0.5 * x * x * x - 0.5 * x * x) ; } - /* If this is not set here, AWE card is not detected on Windows with Aweman driver. It's weird that the EMU8k says that this - * has to be set by applications, and the AWE driver does not set it. */ + /* Even when the documentation says that this has to be written by applications to initialize the card, + * several applications and drivers ( aweman on windows, linux oss driver..) read it to detect an AWE card. */ emu8k->hwcf1 = 0x59; emu8k->hwcf2 = 0x20; /* Initial state is muted. 0x04 is unmuted. */ From 9283d0e1b0df221bab2f50952c5f685db5aada74 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 9 Sep 2017 11:45:02 +0100 Subject: [PATCH 0149/1050] Added Atari PC3 emulation. Patch from dns2k. --- src/ibm.h | 1 + src/keyboard_xt.c | 11 +++++++++++ src/mem.c | 7 +++++++ src/model.c | 1 + 4 files changed, 20 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index e6c8cf3..a4ffc2d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -428,6 +428,7 @@ enum ROM_IBMPS2_M50, ROM_IBMPS2_M55SX, ROM_IBMPS2_M80, + ROM_ATARIPC3, ROM_MAX }; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index d7e69bd..b579e68 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -116,6 +116,10 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) else temp = 0x6D; } + else if ((romset == ROM_ATARIPC3) && (keyboard_xt.pb & 0x80)) + { + temp = 0x7f; + } else { temp = keyboard_xt.pa; @@ -144,6 +148,13 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) else temp = ((mem_size-64) / 32) >> 4; } + else if (romset == ROM_ATARIPC3) + { + if (keyboard_xt.pb & 0x04) + temp = 0xf; + else + temp = 4; + } else { if (keyboard_xt.pb & 0x08) diff --git a/src/mem.c b/src/mem.c index a731ddd..30076c0 100644 --- a/src/mem.c +++ b/src/mem.c @@ -669,6 +669,13 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_ATARIPC3: + f=romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN","rb"); + if (!f) break; + fread(rom+0x8000,32768,1,f); + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index eaa424b..f3798cc 100644 --- a/src/model.c +++ b/src/model.c @@ -96,6 +96,7 @@ int AMSTRAD, AT, PCI, TANDY; MODEL models[] = { {"[8088] AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, xt_init, NULL}, From 4ca6d67f87969d0be03f02a92bdd3acffe76a3a4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 9 Sep 2017 14:58:07 +0100 Subject: [PATCH 0150/1050] Sound Blaster improvements : - Implemented audio recording on SB16 & AWE32 (MIDI only) - Mixer improvements - SB 2.0 CD mixer can be emulated - DSP tweaks, mainly for SB Pro. Implemented speaker on/off and limited high speed DMA to SB 2.0 & Pro - A few other things Patch from JosepMa. --- src/sound_emu8k.c | 12 +- src/sound_emu8k.h | 6 +- src/sound_sb.c | 1220 ++++++++++++++++++++++++++++++++++---------- src/sound_sb_dsp.c | 264 ++++++++-- src/sound_sb_dsp.h | 9 +- 5 files changed, 1201 insertions(+), 310 deletions(-) diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index 9b15d6c..e283922 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -1396,8 +1396,8 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) if ((val&0xFF) == 0 && the_voice->cvcf_curr_volume == 0 && the_voice->vtft_vol_target == 0 && the_voice->dcysusv == 0x80 && the_voice->ip == 0) { - // Patch to avoid some clicking noises with Impulse tracker or other software that sets different values to 0 - // to set noteoff, but here, 0 means no attenuation = full volume. + // Patch to avoid some clicking noises with Impulse tracker or other software that sets + // different values to 0 to set noteoff, but here, 0 means no attenuation = full volume. return; } the_voice->ifatn = val; @@ -2100,7 +2100,7 @@ I've recopilated these sentences to get an idea of how to loop emu8k->pos = new_pos; } /* onboard_ram in kilobytes */ -void emu8k_init(emu8k_t *emu8k, int onboard_ram) +void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) { uint32_t const BLOCK_SIZE_WORDS = 0x10000; FILE *f; @@ -2160,9 +2160,9 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram) } - io_sethandler(0x0620, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_sethandler(0x0a20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); - io_sethandler(0x0e20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_sethandler(emu_addr, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_sethandler(emu_addr+0x400, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); + io_sethandler(emu_addr+0x800, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k); /*Create frequency table. (Convert initial pitch register value to a linear speed change) * The input is encoded such as 0xe000 is center note (no pitch shift) diff --git a/src/sound_emu8k.h b/src/sound_emu8k.h index 7fad2ba..4094863 100644 --- a/src/sound_emu8k.h +++ b/src/sound_emu8k.h @@ -357,8 +357,6 @@ typedef struct emu8k_t uint16_t wc; - uint16_t c02_read; - uint16_t id; /* The empty block is used to act as an unallocated memory returning zero. */ @@ -370,8 +368,6 @@ typedef struct emu8k_t int cur_reg, cur_voice; - int timer_count; - int16_t out_l, out_r; emu8k_chorus_eng_t chorus_engine; @@ -385,7 +381,7 @@ typedef struct emu8k_t -void emu8k_init(emu8k_t *emu8k, int onboard_ram); +void emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram); void emu8k_close(emu8k_t *emu8k); void emu8k_update(emu8k_t *emu8k); diff --git a/src/sound_sb.c b/src/sound_sb.c index 3355bfe..945ed5f 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -14,25 +14,100 @@ #include "filters.h" -typedef struct sb_mixer_t +//#define SB_DSP_RECORD_DEBUG + +#ifdef SB_DSP_RECORD_DEBUG +FILE* soundfsb = 0/*NULL*/; +FILE* soundfsbin = 0/*NULL*/; +#endif + + + +/* SB 2.0 CD version */ +typedef struct sb_ct1335_mixer_t { - int master_l, master_r; - int voice_l, voice_r; - int fm_l, fm_r; - int cd_l, cd_r; + int32_t master; + int32_t voice; + int32_t fm; + int32_t cd; + + uint8_t index; + uint8_t regs[256]; +} sb_ct1335_mixer_t; +/* SB PRO */ +typedef struct sb_ct1345_mixer_t +{ + int32_t master_l, master_r; + int32_t voice_l, voice_r; + int32_t fm_l, fm_r; + int32_t cd_l, cd_r; + int32_t line_l, line_r; + int32_t mic; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; + + int input_filter; + int in_filter_freq; + int output_filter; + + int stereo; + int stereo_isleft; + + uint8_t index; + uint8_t regs[256]; + +} sb_ct1345_mixer_t; +/* SB16 and AWE32 */ +typedef struct sb_ct1745_mixer_t +{ + int32_t master_l, master_r; + int32_t voice_l, voice_r; + int32_t fm_l, fm_r; + int32_t cd_l, cd_r; + int32_t line_l, line_r; + int32_t mic; + int32_t speaker; + int bass_l, bass_r; int treble_l, treble_r; - int filter; + + int output_selector; + #define OUTPUT_MIC 1 + #define OUTPUT_CD_R 2 + #define OUTPUT_CD_L 4 + #define OUTPUT_LINE_R 8 + #define OUTPUT_LINE_L 16 - int index; + int input_selector_left; + int input_selector_right; + #define INPUT_MIC 1 + #define INPUT_CD_R 2 + #define INPUT_CD_L 4 + #define INPUT_LINE_R 8 + #define INPUT_LINE_L 16 + #define INPUT_MIDI_R 32 + #define INPUT_MIDI_L 64 + + int mic_agc; + + int32_t input_gain_L; + int32_t input_gain_R; + int32_t output_gain_L; + int32_t output_gain_R; + + uint8_t index; uint8_t regs[256]; -} sb_mixer_t; +} sb_ct1745_mixer_t; typedef struct sb_t { opl_t opl; sb_dsp_t dsp; - sb_mixer_t mixer; + union { + sb_ct1335_mixer_t mixer_sb2; + sb_ct1345_mixer_t mixer_sbpro; + sb_ct1745_mixer_t mixer_sb16; + }; mpu401_uart_t mpu; emu8k_t emu8k; @@ -49,17 +124,27 @@ const float sb_bass_treble_4bits[]= { 0, 0.25892541, 0.584893192, 1, 1.511886431, 2.16227766, 3, 4.011872336 }; -static int sb_att[]= +/* Attenuation tables for the mixer. Max volume = 32767 in order to give 6dB of + * headroom and avoid integer overflow */ +const int32_t sb_att_2dbstep_5bits[]= { - 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 + 25,32,41,51,65,82,103,130,164,206,260,327,412,519,653, + 822,1036,1304,1641,2067,2602,3276,4125,5192,6537,8230,10362,13044, + 16422,20674,26027,32767 +}; +const int32_t sb_att_4dbstep_3bits[]= +{ + 164,2067,3276,5193,8230,13045,20675,32767 +}; +const int32_t sb_att_7dbstep_2bits[]= +{ + 164,6537,14637,32767 }; -static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) +/* sb 1, 1.5, 2, 2 mvc do not have a mixer, so signal is hardwired */ +static void sb_get_buffer_sb2(int32_t *buffer, int len, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; int c; @@ -67,40 +152,13 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) sb_dsp_update(&sb->dsp); for (c = 0; c < len * 2; c += 2) { - int32_t out_l, out_r; - - 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) - { - 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) >> 16; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; - } - - out_l = (out_l * mixer->master_l) >> 16; - out_r = (out_r * mixer->master_r) >> 16; - - if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) - { - // This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage - if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); - if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); - if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); - if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); - if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->bass_l])); - if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->bass_r])); - if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->treble_l])); - if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->treble_r])); - } - - buffer[c] += out_l; - buffer[c + 1] += out_r; + int32_t out; + out = ((sb->opl.buffer[c] * 51000) >> 16); + //TODO: Recording: Mic and line In with AGC + out += (int32_t)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * 65536) / 3) >> 16; + + buffer[c] += out; + buffer[c + 1] += out; } sb->pos = 0; @@ -108,49 +166,71 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) sb->dsp.pos = 0; } -static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) +static void sb_get_buffer_sb2_mixer(int32_t *buffer, int len, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; + sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; int c; - opl3_update2(&sb->opl); + opl2_update2(&sb->opl); + sb_dsp_update(&sb->dsp); + for (c = 0; c < len * 2; c += 2) + { + int32_t out; + + out = ((((sb->opl.buffer[c] * mixer->fm) >> 16) * 51000) >> 15); + /* TODO: Recording : I assume it has direct mic and line in like sb2 */ + /* It is unclear from the docs if it has a filter, but it probably does */ + out += (int32_t)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice) / 3) >> 15; + + out = (out * mixer->master) >> 15; + + buffer[c] += out; + buffer[c + 1] += out; + } + + sb->pos = 0; + sb->opl.pos = 0; + sb->dsp.pos = 0; +} + +static void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) +{ + sb_t *sb = (sb_t *)p; + sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + + int c; + + if (sb->dsp.sb_type == SBPRO) + opl2_update2(&sb->opl); + else + opl3_update2(&sb->opl); + sb_dsp_update(&sb->dsp); for (c = 0; c < len * 2; c += 2) { int32_t out_l, out_r; - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 16); - - if (sb->mixer.filter) + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); + + /*TODO: Implement the stereo switch on the mixer instead of on the dsp? */ + if (mixer->output_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 += (int32_t)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 15; + out_r += (int32_t)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 15; } 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) >> 15; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 15; } + //TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. - out_l = (out_l * mixer->master_l) >> 16; - out_r = (out_r * mixer->master_r) >> 16; + 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) - { - // This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage - if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); - if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); - if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); - if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); - if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->bass_l])); - if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->bass_r])); - if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->treble_l])); - if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->treble_r])); - } - buffer[c] += out_l; buffer[c + 1] += out_r; } @@ -158,102 +238,358 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) sb->pos = 0; sb->opl.pos = 0; sb->dsp.pos = 0; - sb->emu8k.pos = 0; } +static void sb_get_buffer_sb16(int32_t *buffer, int len, void *p) +{ + sb_t *sb = (sb_t *)p; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + + int c; + + opl3_update2(&sb->opl); + sb_dsp_update(&sb->dsp); + const int dsp_rec_pos = sb->dsp.record_pos_write; + for (c = 0; c < len * 2; c += 2) + { + int32_t out_l, out_r, in_l, in_r; + + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 15); + + /*TODO: multi-recording mic with agc/+20db, cd and line in with channel inversion */ + in_l = (mixer->input_selector_left&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_left&INPUT_MIDI_R) ? out_r : 0; + in_r = (mixer->input_selector_right&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_right&INPUT_MIDI_R) ? out_r : 0; + + /*TODO: CT1745 features dynamic filtering. https://www.vogons.org/viewtopic.php?f=62&t=51514 */ + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 15; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 15; + + 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) + { + /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage */ + if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); + if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); + if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); + if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); + if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->bass_l])); + if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->bass_r])); + if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->treble_l])); + if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->treble_r])); + } + if (sb->dsp.sb_enable_i) + { + int c_record = dsp_rec_pos; + c_record +=(((c/2) * sb->dsp.sb_freq) / 48000)*2; + in_l <<= mixer->input_gain_L; + in_r <<= mixer->input_gain_R; + // Clip signal + if (in_l < -32768) + in_l = -32768; + else if (in_l > 32767) + in_l = 32767; + + if (in_r < -32768) + in_r = -32768; + else if (in_r > 32767) + in_r = 32767; + sb->dsp.record_buffer[c_record&0xFFFF] = in_l; + sb->dsp.record_buffer[(c_record+1)&0xFFFF] = in_r; + } + + buffer[c] += (out_l << mixer->output_gain_L); + buffer[c + 1] += (out_r << mixer->output_gain_R); + } + sb->dsp.record_pos_write+=((len * sb->dsp.sb_freq) / 48000)*2; + sb->dsp.record_pos_write&=0xFFFF; + + sb->pos = 0; + sb->opl.pos = 0; + sb->dsp.pos = 0; +} +#ifdef SB_DSP_RECORD_DEBUG +int old_dsp_rec_pos=0; +int buf_written=0; +int last_crecord=0; +#endif static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; int c; opl3_update2(&sb->opl); - sb_dsp_update(&sb->dsp); emu8k_update(&sb->emu8k); + sb_dsp_update(&sb->dsp); + const int dsp_rec_pos = sb->dsp.record_pos_write; for (c = 0; c < len * 2; c += 2) { + int32_t out_l, out_r, in_l, in_r; int c_emu8k = (((c/2) * 44100) / 48000)*2; - int32_t out_l, out_r; - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (sb->opl_emu ? 47000 : 51000)) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 15) * (sb->opl_emu ? 47000 : 51000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 15) * (sb->opl_emu ? 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); - - 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; - } - 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 += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 15); + out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_r) >> 15); - out_l = (out_l * mixer->master_l) >> 16; - out_r = (out_r * mixer->master_r) >> 16; + /*TODO: multi-recording mic with agc/+20db, cd and line in with channel inversion */ + in_l = (mixer->input_selector_left&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_left&INPUT_MIDI_R) ? out_r : 0; + in_r = (mixer->input_selector_right&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_right&INPUT_MIDI_R) ? out_r : 0; + + + /*TODO: CT1745 features dynamic filtering. https://www.vogons.org/viewtopic.php?f=62&t=51514 */ + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 15; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 15; + + 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) { - // This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage + /* This is not exactly how one does bass/treble controls, but the end result is like it. A better implementation would reduce the cpu usage */ if (mixer->bass_l>8) out_l += (int32_t)(low_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->bass_l]); if (mixer->bass_r>8) out_r += (int32_t)(low_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->bass_r]); if (mixer->treble_l>8) out_l += (int32_t)(high_iir(0, (float)out_l)*sb_bass_treble_4bits[mixer->treble_l]); if (mixer->treble_r>8) out_r += (int32_t)(high_iir(1, (float)out_r)*sb_bass_treble_4bits[mixer->treble_r]); - if (mixer->bass_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->bass_l])); - if (mixer->bass_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->bass_r])); - if (mixer->treble_l<8) out_l = (int32_t)((out_l )*sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.0-sb_bass_treble_4bits[mixer->treble_l])); - if (mixer->treble_r<8) out_r = (int32_t)((out_r )*sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.0-sb_bass_treble_4bits[mixer->treble_r])); + if (mixer->bass_l<8) out_l = (int32_t)(out_l *sb_bass_treble_4bits[mixer->bass_l] + low_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->bass_l])); + if (mixer->bass_r<8) out_r = (int32_t)(out_r *sb_bass_treble_4bits[mixer->bass_r] + low_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->bass_r])); + if (mixer->treble_l<8) out_l = (int32_t)(out_l *sb_bass_treble_4bits[mixer->treble_l] + high_cut_iir(0, (float)out_l)*(1.f-sb_bass_treble_4bits[mixer->treble_l])); + if (mixer->treble_r<8) out_r = (int32_t)(out_r *sb_bass_treble_4bits[mixer->treble_r] + high_cut_iir(1, (float)out_r)*(1.f-sb_bass_treble_4bits[mixer->treble_r])); } - - buffer[c] += out_l; - buffer[c + 1] += out_r; - } + if (sb->dsp.sb_enable_i) + { +// in_l += (mixer->input_selector_left&INPUT_CD_L) ? audio_cd_buffer[cd_read_pos+c_emu8k] : 0 + (mixer->input_selector_left&INPUT_CD_R) ? audio_cd_buffer[cd_read_pos+c_emu8k+1] : 0; +// in_r += (mixer->input_selector_right&INPUT_CD_L) ? audio_cd_buffer[cd_read_pos+c_emu8k]: 0 + (mixer->input_selector_right&INPUT_CD_R) ? audio_cd_buffer[cd_read_pos+c_emu8k+1] : 0; + int c_record = dsp_rec_pos; + c_record +=(((c/2) * sb->dsp.sb_freq) / 48000)*2; + #ifdef SB_DSP_RECORD_DEBUG + if (c_record > 0xFFFF && !buf_written) + { + if (!soundfsb) soundfsb=fopen("sound_sb.pcm","wb"); + fwrite(sb->dsp.record_buffer,2,0x10000,soundfsb); + old_dsp_rec_pos = dsp_rec_pos; + buf_written=1; + } + #endif + in_l <<= mixer->input_gain_L; + in_r <<= mixer->input_gain_R; + // Clip signal + if (in_l < -32768) + in_l = -32768; + else if (in_l > 32767) + in_l = 32767; + + if (in_r < -32768) + in_r = -32768; + else if (in_r > 32767) + in_r = 32767; + sb->dsp.record_buffer[c_record&0xFFFF] = in_l; + sb->dsp.record_buffer[(c_record+1)&0xFFFF] = in_r; + #ifdef SB_DSP_RECORD_DEBUG + if (c_record != last_crecord) + { + if (!soundfsbin) soundfsbin=fopen("sound_sb_in.pcm","wb"); + fwrite(&sb->dsp.record_buffer[c_record&0xFFFF],2,2,soundfsbin); + last_crecord=c_record; + } + #endif + } + + buffer[c] += (out_l << mixer->output_gain_L); + buffer[c + 1] += (out_r << mixer->output_gain_R); + } + #ifdef SB_DSP_RECORD_DEBUG + if (old_dsp_rec_pos > dsp_rec_pos) + { + buf_written=0; + old_dsp_rec_pos=dsp_rec_pos; + } + #endif + + sb->dsp.record_pos_write+=((len * sb->dsp.sb_freq) / 48000)*2; + sb->dsp.record_pos_write&=0xFFFF; sb->pos = 0; sb->opl.pos = 0; sb->dsp.pos = 0; sb->emu8k.pos = 0; } -void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p) + +void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; + sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; if (!(addr & 1)) - mixer->index = val & 0xff; + { + mixer->index = val; + mixer->regs[0x01] = val; + } else { - mixer->regs[mixer->index] = val; - - mixer->master_l = sb_att[(mixer->regs[0x22] >> 4) | 0x11]; - mixer->master_r = sb_att[(mixer->regs[0x22] & 0xf) | 0x11]; - mixer->voice_l = sb_att[(mixer->regs[0x04] >> 4) | 0x11]; - mixer->voice_r = sb_att[(mixer->regs[0x04] & 0xf) | 0x11]; - mixer->fm_l = sb_att[(mixer->regs[0x26] >> 4) | 0x11]; - mixer->fm_r = sb_att[(mixer->regs[0x26] & 0xf) | 0x11]; - mixer->cd_l = sb_att[(mixer->regs[0x28] >> 4) | 0x11]; - mixer->cd_r = sb_att[(mixer->regs[0x28] & 0xf) | 0x11]; - 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); -// 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); + if (mixer->index == 0) + { + /* Reset */ + mixer->regs[0x02] = 4 << 1; + mixer->regs[0x06] = 4 << 1; + mixer->regs[0x08] = 0 << 1; + /* changed default from -46dB to 0dB*/ + mixer->regs[0x0A] = 3 << 1; + } + else + { + mixer->regs[mixer->index] = val; + switch (mixer->index) + { + case 0x00: case 0x02: case 0x06: case 0x08: case 0x0A: + break; + + default: + pclog("sb_ct1335: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } + mixer->master = sb_att_4dbstep_3bits[(mixer->regs[0x02] >> 1)&0x7]; + mixer->fm = sb_att_4dbstep_3bits[(mixer->regs[0x06] >> 1)&0x7]; + mixer->cd = sb_att_4dbstep_3bits[(mixer->regs[0x08] >> 1)&0x7]; + mixer->voice = sb_att_7dbstep_2bits[(mixer->regs[0x0A] >> 1)&0x3]; + + sound_set_cd_volume(((uint32_t)mixer->master * (uint32_t)mixer->cd) / 65535, + ((uint32_t)mixer->master * (uint32_t)mixer->cd) / 65535); } } -uint8_t sb_pro_mixer_read(uint16_t addr, void *p) +uint8_t sb_ct1335_mixer_read(uint16_t addr, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; + sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + + if (!(addr & 1)) + return mixer->index; + + switch (mixer->index) + { + case 0x00: case 0x02: case 0x06: case 0x08: case 0x0A: + return mixer->regs[mixer->index]; + default: + pclog("sb_ct1335: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + + return 0xff; +} + +void sb_ct1335_mixer_reset(sb_t* sb) +{ + sb_ct1335_mixer_write(0x254,0,sb); + sb_ct1335_mixer_write(0x255,0,sb); +} + +void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p) +{ + sb_t *sb = (sb_t *)p; + sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; + + if (!(addr & 1)) + { + mixer->index = val; + mixer->regs[0x01] = val; + } + else + { + if (mixer->index == 0) + { + /* Reset */ + mixer->regs[0x0A] = 0 << 1; + mixer->regs[0x0C] = (0 << 5) | (0 << 3) | (0 << 1); + mixer->regs[0x0E] = (0 << 5) | (0 << 1); + /* changed default from -11dB to 0dB */ + mixer->regs[0x04] = (7 << 5) | (7 << 1); + mixer->regs[0x22] = (7 << 5) | (7 << 1); + mixer->regs[0x26] = (7 << 5) | (7 << 1); + mixer->regs[0x28] = (0 << 5) | (0 << 1); + mixer->regs[0x2E] = (0 << 5) | (0 << 1); + sb_dsp_set_stereo(&sb->dsp, mixer->regs[0x0E] & 2); + } + else + { + mixer->regs[mixer->index] = val; + switch (mixer->index) + { + /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ + case 0x02: case 0x06: + mixer->regs[mixer->index+0x20]=((val&0xE) << 4)||(val&0xE) << 4; + break; + + case 0x22: case 0x26: + mixer->regs[mixer->index-0x20]=(val&0xE); + break; + + /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h,028h for 038h. */ + case 0x30: case 0x32: case 0x36: case 0x38: + mixer->regs[mixer->index-0x10]=(val&0xEE); + break; + + case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: + case 0x28: case 0x2e: + break; + + + default: + pclog("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + } + + mixer->voice_l = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 5)&0x7]; + mixer->voice_r = sb_att_4dbstep_3bits[(mixer->regs[0x04] >> 1)&0x7]; + mixer->master_l = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 5)&0x7]; + mixer->master_r = sb_att_4dbstep_3bits[(mixer->regs[0x22] >> 1)&0x7]; + mixer->fm_l = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 5)&0x7]; + mixer->fm_r = sb_att_4dbstep_3bits[(mixer->regs[0x26] >> 1)&0x7]; + mixer->cd_l = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 5)&0x7]; + mixer->cd_r = sb_att_4dbstep_3bits[(mixer->regs[0x28] >> 1)&0x7]; + mixer->line_l = sb_att_4dbstep_3bits[(mixer->regs[0x2E] >> 5)&0x7]; + mixer->line_r = sb_att_4dbstep_3bits[(mixer->regs[0x2E] >> 1)&0x7]; + + mixer->mic = sb_att_7dbstep_2bits[(mixer->regs[0x0A] >> 1)&0x3]; + + mixer->output_filter = !(mixer->regs[0xE] & 0x20); + mixer->input_filter = !(mixer->regs[0xC] & 0x20); + mixer->in_filter_freq = ((mixer->regs[0xC] & 0x8) == 0) ? 3200 : 8800; + mixer->stereo = mixer->regs[0xE] & 2; + if (mixer->index == 0xE) + sb_dsp_set_stereo(&sb->dsp, val & 2); + + switch ((mixer->regs[0xc]&6)) + { + case 2: + mixer->input_selector = INPUT_CD_L|INPUT_CD_R; + break; + case 6: + mixer->input_selector = INPUT_LINE_L|INPUT_LINE_R; + break; + default: + mixer->input_selector = INPUT_MIC; + break; + } + + /* TODO: pcspeaker volume? Or is it not worth? */ + 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); + } +} + +uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p) +{ + sb_t *sb = (sb_t *)p; + sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; if (!(addr & 1)) return mixer->index; @@ -261,106 +597,251 @@ uint8_t sb_pro_mixer_read(uint16_t addr, void *p) switch (mixer->index) { case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: - case 0x22: case 0x26: case 0x28: case 0x2e: + case 0x22: case 0x26: case 0x28: case 0x2e: case 0x02: case 0x06: + case 0x30: case 0x32: case 0x36: case 0x38: return mixer->regs[mixer->index]; + + default: + pclog("sb_ct1345: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; } return 0xff; } +void sb_ct1345_mixer_reset(sb_t* sb) +{ + sb_ct1345_mixer_write(4,0,sb); + sb_ct1345_mixer_write(5,0,sb); +} -void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) +void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; if (!(addr & 1)) + { mixer->index = val; + } else { - mixer->regs[mixer->index] = val; + // TODO: and this? 001h: + /*DESCRIPTION + Contains previously selected register value. Mixer Data Register value + NOTES + * SoundBlaster 16 sets bit 7 if previous mixer index invalid. + * Status bytes initially 080h on startup for all but level bytes (SB16) + */ + + if (mixer->index == 0) + { + /* Reset */ + /* Changed defaults from -14dB to 0dB*/ + mixer->regs[0x30]=31 << 3; + mixer->regs[0x31]=31 << 3; + mixer->regs[0x32]=31 << 3; + mixer->regs[0x33]=31 << 3; + mixer->regs[0x34]=31 << 3; + mixer->regs[0x35]=31 << 3; + mixer->regs[0x36]=0 << 3; + mixer->regs[0x37]=0 << 3; + mixer->regs[0x38]=0 << 3; + mixer->regs[0x39]=0 << 3; + + mixer->regs[0x3A]=0 << 3; + mixer->regs[0x3B]=0 << 6; + mixer->regs[0x3C] = OUTPUT_MIC|OUTPUT_CD_R|OUTPUT_CD_L|OUTPUT_LINE_R|OUTPUT_LINE_L; + mixer->regs[0x3D] = INPUT_MIC|INPUT_CD_L|INPUT_LINE_L|INPUT_MIDI_L; + mixer->regs[0x3E] = INPUT_MIC|INPUT_CD_R|INPUT_LINE_R|INPUT_MIDI_R; + + mixer->regs[0x3F] = mixer->regs[0x40] = 0 << 6; + mixer->regs[0x41] = mixer->regs[0x42] = 0 << 6; + + mixer->regs[0x44] = mixer->regs[0x45] = 8 << 4; + mixer->regs[0x46] = mixer->regs[0x47] = 8 << 4; + + mixer->regs[0x43] = 0; + } + else + { + mixer->regs[mixer->index] = val; + } switch (mixer->index) { + /* SBPro compatibility. Copy values to sb16 registers. */ case 0x22: - mixer->regs[0x30] = ((mixer->regs[0x22] >> 4) | 0x11) << 3; - mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) | 0x11) << 3; + mixer->regs[0x30] = (mixer->regs[0x22] & 0xF0) | 0x8; + mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) << 4) | 0x8; break; case 0x04: - mixer->regs[0x32] = ((mixer->regs[0x04] >> 4) | 0x11) << 3; - mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) | 0x11) << 3; + mixer->regs[0x32] = (mixer->regs[0x04] & 0xF0) | 0x8; + mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) << 4) | 0x8; break; case 0x26: - mixer->regs[0x34] = ((mixer->regs[0x26] >> 4) | 0x11) << 3; - mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) | 0x11) << 3; + mixer->regs[0x34] = (mixer->regs[0x26] & 0xF0) | 0x8; + mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) << 4) | 0x8; break; case 0x28: - mixer->regs[0x36] = ((mixer->regs[0x28] >> 4) | 0x11) << 3; - mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) | 0x11) << 3; + mixer->regs[0x36] = (mixer->regs[0x28] & 0xF0) | 0x8; + mixer->regs[0x37] = ((mixer->regs[0x28] & 0xf) << 4) | 0x8; break; + case 0x2E: + mixer->regs[0x38] = (mixer->regs[0x2E] & 0xF0) | 0x8; + mixer->regs[0x39] = ((mixer->regs[0x2E] & 0xf) << 4) | 0x8; + break; + case 0x0A: + mixer->regs[0x3A] = (mixer->regs[0x0A]*3)+10; + break; + + /* + (DSP 4.xx feature) The Interrupt Setup register, addressed as register 80h on the Mixer register map, is used to configure or determine the Interrupt request line. The DMA setup register, addressed as register 81h on the Mixer register map, is used to configure or determine the DMA channels. + + Note: Registers 80h and 81h are Read-only for PnP boards. + */ case 0x80: - if (val & 1) sb->dsp.sb_irqnum = 2; - if (val & 2) sb->dsp.sb_irqnum = 5; - if (val & 4) sb->dsp.sb_irqnum = 7; - if (val & 8) sb->dsp.sb_irqnum = 10; + if (val & 1) sb_dsp_setirq(&sb->dsp,2); + if (val & 2) sb_dsp_setirq(&sb->dsp,5); + if (val & 4) sb_dsp_setirq(&sb->dsp,7); + if (val & 8) sb_dsp_setirq(&sb->dsp,10); + break; + + case 0x81: + /* The documentation is confusing. sounds as if multple dma8 channels could be set. */ + if (val & 1) sb_dsp_setdma8(&sb->dsp,0); + if (val & 2) sb_dsp_setdma8(&sb->dsp,1); + if (val & 8) sb_dsp_setdma8(&sb->dsp,3); + if (val & 0x20) sb_dsp_setdma16(&sb->dsp,5); + if (val & 0x40) sb_dsp_setdma16(&sb->dsp,6); + if (val & 0x80) sb_dsp_setdma16(&sb->dsp,7); break; } - mixer->master_l = sb_att[mixer->regs[0x30] >> 3]; - mixer->master_r = sb_att[mixer->regs[0x31] >> 3]; - mixer->voice_l = sb_att[mixer->regs[0x32] >> 3]; - mixer->voice_r = sb_att[mixer->regs[0x33] >> 3]; - mixer->fm_l = sb_att[mixer->regs[0x34] >> 3]; - mixer->fm_r = sb_att[mixer->regs[0x35] >> 3]; - mixer->cd_l = sb_att[mixer->regs[0x36] >> 3]; - mixer->cd_r = sb_att[mixer->regs[0x37] >> 3]; + + mixer->output_selector = mixer->regs[0x3C]; + mixer->input_selector_left = mixer->regs[0x3D]; + mixer->input_selector_right = mixer->regs[0x3E]; + + mixer->master_l = sb_att_2dbstep_5bits[mixer->regs[0x30] >> 3]; + mixer->master_r = sb_att_2dbstep_5bits[mixer->regs[0x31] >> 3]; + mixer->voice_l = sb_att_2dbstep_5bits[mixer->regs[0x32] >> 3]; + mixer->voice_r = sb_att_2dbstep_5bits[mixer->regs[0x33] >> 3]; + mixer->fm_l = sb_att_2dbstep_5bits[mixer->regs[0x34] >> 3]; + mixer->fm_r = sb_att_2dbstep_5bits[mixer->regs[0x35] >> 3]; + mixer->cd_l = (mixer->output_selector&OUTPUT_CD_L) ? sb_att_2dbstep_5bits[mixer->regs[0x36] >> 3] : 0; + mixer->cd_r = (mixer->output_selector&OUTPUT_CD_R) ? sb_att_2dbstep_5bits[mixer->regs[0x37] >> 3] : 0; + mixer->line_l = (mixer->output_selector&OUTPUT_LINE_L) ? sb_att_2dbstep_5bits[mixer->regs[0x38] >> 3] : 0; + mixer->line_r = (mixer->output_selector&OUTPUT_LINE_R) ? sb_att_2dbstep_5bits[mixer->regs[0x39] >> 3] : 0; + + mixer->mic = sb_att_2dbstep_5bits[mixer->regs[0x3A] >> 3]; + mixer->speaker = sb_att_2dbstep_5bits[mixer->regs[0x3B]*3 + 22]; + + + mixer->input_gain_L = (mixer->regs[0x3F] >> 6); + mixer->input_gain_R = (mixer->regs[0x40] >> 6); + mixer->output_gain_L = (mixer->regs[0x41] >> 6); + mixer->output_gain_R = (mixer->regs[0x42] >> 6); + mixer->bass_l = mixer->regs[0x46] >> 4; mixer->bass_r = mixer->regs[0x47] >> 4; mixer->treble_l = mixer->regs[0x44] >> 4; mixer->treble_r = mixer->regs[0x45] >> 4; - mixer->filter = 0; + + /*TODO: pcspeaker volume, with "output_selector" check? or better not? */ 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); +// pclog("sb_ct1745: Received register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); } } -uint8_t sb_16_mixer_read(uint16_t addr, void *p) +uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) { sb_t *sb = (sb_t *)p; - sb_mixer_t *mixer = &sb->mixer; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; if (!(addr & 1)) return mixer->index; +// pclog("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + + if (mixer->index>=0x30 && mixer->index<=0x47) + { + return mixer->regs[mixer->index]; + } switch (mixer->index) { - case 0x40: return 0xff; + case 0x00: case 0x04: case 0x0A: case 0x22: case 0x26: case 0x28: case 0x2E: + return mixer->regs[mixer->index]; + + case 0x48: + // Undocumented. The Creative Windows Mixer calls this after calling 3C (input selector). even when writing. + // Also, the version I have (5.17) does not use the MIDI.L/R input selectors. it uses the volume to mute (Affecting the output, obviously) + return mixer->regs[mixer->index]; + case 0x80: + /*TODO: Unaffected by mixer reset or soft reboot. + * Enabling multiple bits enables multiple IRQs. + */ + switch (sb->dsp.sb_irqnum) { - case 2: return 1; /*IRQ 7*/ - case 5: return 2; /*IRQ 7*/ - case 7: return 4; /*IRQ 7*/ - case 10: return 8; /*IRQ 7*/ + case 2: return 1; + case 5: return 2; + case 7: return 4; + case 10: return 8; } break; + case 0x81: - return 0x22; /*DMA 1 and 5*/ + { + /* TODO: Unaffected by mixer reset or soft reboot. + * Enabling multiple 8 or 16-bit DMA bits enables multiple DMA channels. + * Disabling all 8-bit DMA channel bits disables 8-bit DMA requests, + including translated 16-bit DMA requests. + * Disabling all 16-bit DMA channel bits enables translation of 16-bit DMA + requests to 8-bit ones, using the selected 8-bit DMA channel.*/ + + uint8_t result=0; + switch (sb->dsp.sb_8_dmanum) + { + case 0: result |= 1; break; + case 1: result |= 2; break; + case 3: result |= 8; break; + } + switch (sb->dsp.sb_16_dmanum) + { + case 5: result |= 0x20; break; + case 6: result |= 0x40; break; + case 7: result |= 0x80; break; + } + return result; + } + + /* The Interrupt status register, addressed as register 82h on the Mixer register map, + is used by the ISR to determine whether the interrupt is meant for it or for some other ISR, + in which case it should chain to the previous routine. + */ case 0x82: - return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0); + /* 0 = none, 1 = digital 8bit or SBMIDI, 2 = digital 16bit, 4 = MPU-401 */ + /* 0x02000 DSP v4.04, 0x4000 DSP v4.05 0x8000 DSP v4.12. I haven't seen this making any difference, but I'm keeping it for now. */ + return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | 0x4000; + + /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ + + + default: + pclog("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; } - return mixer->regs[mixer->index]; + + return 0xff; } -void sb_mixer_init(sb_mixer_t *mixer) +void sb_ct1745_mixer_reset(sb_t* sb) { - mixer->master_l = mixer->master_r = 65535; - mixer->voice_l = mixer->voice_r = 65535; - mixer->fm_l = mixer->fm_r = 65535; - mixer->bass_l = mixer->bass_r = 8; - mixer->treble_l = mixer->treble_r = 8; - mixer->filter = 1; + sb_ct1745_mixer_write(4,0,sb); + sb_ct1745_mixer_write(5,0,sb); } + static uint16_t sb_mcv_addr[8] = {0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270}; uint8_t sb_mcv_read(int port, void *p) @@ -385,6 +866,7 @@ void sb_mcv_write(int port, uint8_t val, void *p) 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); + /* DSP I/O handler is activated in sb_dsp_setaddr */ sb_dsp_setaddr(&sb->dsp, 0); sb->pos_regs[port & 7] = val; @@ -395,6 +877,7 @@ void sb_mcv_write(int port, uint8_t val, void *p) 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); + /* DSP I/O handler is activated in sb_dsp_setaddr */ sb_dsp_setaddr(&sb->dsp, addr); } } @@ -424,7 +907,8 @@ void sb_pro_mcv_write(int port, uint8_t val, void *p) 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); + io_removehandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ sb_dsp_setaddr(&sb->dsp, 0); sb->pos_regs[port & 7] = val; @@ -436,16 +920,20 @@ void sb_pro_mcv_write(int port, uint8_t val, void *p) 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); - + io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ 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() { + /*sb1/2 port mappings, 210h to 260h in 10h steps + 2x0 to 2x3 -> CMS chip + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip*/ sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -455,14 +943,19 @@ void *sb_1_init() 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); + /* CMS I/O handler is activated on the dedicated sound_cms module + DSP I/O handler is activated in sb_dsp_setaddr */ 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); - sound_add_handler(sb_get_buffer_opl2, sb); + sound_add_handler(sb_get_buffer_sb2, sb); return sb; } void *sb_15_init() { + /*sb1/2 port mappings, 210h to 260h in 10h steps + 2x0 to 2x3 -> CMS chip + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip*/ sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -472,15 +965,19 @@ void *sb_15_init() 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); + /* CMS I/O handler is activated on the dedicated sound_cms module + DSP I/O handler is activated in sb_dsp_setaddr */ 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); - sound_add_handler(sb_get_buffer_opl2, sb); + sound_add_handler(sb_get_buffer_sb2, sb); return sb; } void *sb_mcv_init() { + /*sb1/2 port mappings, 210h to 260h in 10h steps + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip*/ sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); @@ -489,8 +986,8 @@ void *sb_mcv_init() sb_dsp_setaddr(&sb->dsp, 0);//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); - sound_add_handler(sb_get_buffer_opl2, sb); + sound_add_handler(sb_get_buffer_sb2, sb); + /* I/O handlers activated in sb_mcv_write */ mca_add(sb_mcv_read, sb_mcv_write, sb); sb->pos_regs[0] = 0x84; sb->pos_regs[1] = 0x50; @@ -498,6 +995,13 @@ void *sb_mcv_init() } void *sb_2_init() { + /*sb2 port mappings. 220h or 240h. + 2x0 to 2x3 -> CMS chip + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip + "CD version" also uses 250h or 260h for + 2x0 to 2x3 -> CDROM interface + 2x4 to 2x5 -> Mixer interface*/ sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -507,15 +1011,32 @@ void *sb_2_init() 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); + sb_ct1335_mixer_reset(sb); + /* CMS I/O handler is activated on the dedicated sound_cms module + DSP I/O handler is activated in sb_dsp_setaddr */ 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); - sound_add_handler(sb_get_buffer_opl2, sb); + + int mixer_addr = device_get_config_int("mixaddr"); + if (mixer_addr > 0) + { + io_sethandler(mixer_addr+4, 0x0002, sb_ct1335_mixer_read, NULL, NULL, sb_ct1335_mixer_write, NULL, NULL, sb); + sound_add_handler(sb_get_buffer_sb2_mixer, sb); + } + else + sound_add_handler(sb_get_buffer_sb2, sb); + return sb; } void *sb_pro_v1_init() { + /*sbpro port mappings. 220h or 240h. + 2x0 to 2x3 -> FM chip, Left and Right (9*2 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices) + 2x0+10 to 2x0+13 CDROM interface.*/ sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -525,66 +1046,65 @@ void *sb_pro_v1_init() 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); + sb_ct1345_mixer_reset(sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ io_sethandler(addr+0, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl); io_sethandler(addr+2, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl); 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); - io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); - sound_add_handler(sb_get_buffer_opl2, sb); - - sb->mixer.regs[0x22] = 0xff; - sb->mixer.regs[0x04] = 0xff; - sb->mixer.regs[0x26] = 0xff; - sb->mixer.regs[0xe] = 0; + io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); + sound_add_handler(sb_get_buffer_sbpro, sb); return sb; } void *sb_pro_v2_init() { + /*sbpro port mappings. 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices) + 2x0+10 to 2x0+13 CDROM interface.*/ sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); + uint16_t addr = device_get_config_int("addr"); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); 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); + sb_ct1345_mixer_reset(sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ 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); - 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; + io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb); + sound_add_handler(sb_get_buffer_sbpro, sb); return sb; } void *sb_pro_mcv_init() { + /*sbpro port mappings. 220h or 240h. + 2x0 to 2x3 -> FM chip, Left and Right (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip (9 voices)*/ sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); sb_dsp_init(&sb->dsp, SBPRO2); - 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; + sb_ct1345_mixer_reset(sb); + /* I/O handlers activated in sb_mcv_write */ + sound_add_handler(sb_get_buffer_sbpro, sb); + /* I/O handlers activated in sb_pro_mcv_write */ mca_add(sb_pro_mcv_read, sb_pro_mcv_write, sb); sb->pos_regs[0] = 0x03; sb->pos_regs[1] = 0x51; @@ -597,31 +1117,20 @@ void *sb_16_init() sb_t *sb = malloc(sizeof(sb_t)); memset(sb, 0, sizeof(sb_t)); + uint16_t addr = device_get_config_int("addr"); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); sb_dsp_init(&sb->dsp, SB16); - sb_dsp_setaddr(&sb->dsp, 0x0220); - 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); + sb_dsp_setaddr(&sb->dsp, addr); + // TODO: irq and dma options too? + sb_ct1745_mixer_reset(sb); + io_sethandler(addr, 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); - sound_add_handler(sb_get_buffer_opl3, sb); + io_sethandler(addr+4, 0x0002, sb_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); + sound_add_handler(sb_get_buffer_sb16, sb); mpu401_uart_init(&sb->mpu, 0x330); - sb->mixer.regs[0x30] = 31 << 3; - sb->mixer.regs[0x31] = 31 << 3; - sb->mixer.regs[0x32] = 31 << 3; - sb->mixer.regs[0x33] = 31 << 3; - sb->mixer.regs[0x34] = 31 << 3; - sb->mixer.regs[0x35] = 31 << 3; - sb->mixer.regs[0x44] = 8 << 4; - sb->mixer.regs[0x45] = 8 << 4; - sb->mixer.regs[0x46] = 8 << 4; - sb->mixer.regs[0x47] = 8 << 4; - 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); return sb; } @@ -637,39 +1146,41 @@ void *sb_awe32_init() int onboard_ram = device_get_config_int("onboard_ram"); memset(sb, 0, sizeof(sb_t)); + uint16_t addr = device_get_config_int("addr"); + uint16_t emu_addr = device_get_config_int("emu_addr"); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); sb_dsp_init(&sb->dsp, SB16 + 1); - sb_dsp_setaddr(&sb->dsp, 0x0220); - 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); + sb_dsp_setaddr(&sb->dsp, addr); + // TODO: irq and dma options too? + sb_ct1745_mixer_reset(sb); + io_sethandler(addr, 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_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_uart_init(&sb->mpu, 0x330); - emu8k_init(&sb->emu8k, onboard_ram); + mpu401_uart_init(&sb->mpu, 0x330); + emu8k_init(&sb->emu8k, emu_addr, onboard_ram); - sb->mixer.regs[0x30] = 31 << 3; - sb->mixer.regs[0x31] = 31 << 3; - sb->mixer.regs[0x32] = 31 << 3; - sb->mixer.regs[0x33] = 31 << 3; - sb->mixer.regs[0x34] = 31 << 3; - sb->mixer.regs[0x35] = 31 << 3; - sb->mixer.regs[0x44] = 8 << 4; - sb->mixer.regs[0x45] = 8 << 4; - sb->mixer.regs[0x46] = 8 << 4; - sb->mixer.regs[0x47] = 8 << 4; - 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); - return sb; } void sb_close(void *p) { sb_t *sb = (sb_t *)p; + sb_dsp_close(&sb->dsp); + #ifdef SB_DSP_RECORD_DEBUG + if (soundfsb != 0) + { + fclose(soundfsb); + soundfsb=0; + } + if (soundfsbin!= 0) + { + fclose(soundfsbin); + soundfsbin=0; + } + #endif free(sb); } @@ -680,7 +1191,7 @@ void sb_awe32_close(void *p) emu8k_close(&sb->emu8k); - free(sb); + sb_close(sb); } void sb_speed_changed(void *p) @@ -702,7 +1213,97 @@ static device_config_t sb_config[] = { .name = "addr", .description = "Address", - .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x210", + .value = 0x210 + }, + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x230", + .value = 0x230 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x250", + .value = 0x250 + }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "" + } + }, + .default_int = 0x220 + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 2", + .value = 2 + }, + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { + .description = "" + } + }, + .default_int = 1 + }, + { + .type = -1 + } +}; + +static device_config_t sb2_config[] = +{ + { + .name = "addr", + .description = "Address", .type = CONFIG_SELECTION, .selection = { @@ -720,6 +1321,30 @@ static device_config_t sb_config[] = }, .default_int = 0x220 }, + { + .name = "mixaddr", + .description = "Mixer Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "No mixer", + .value = 0 + }, + { + .description = "0x250", + .value = 0x250 + }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "" + } + }, + .default_int = 0 + }, { .name = "irq", .description = "IRQ", @@ -829,7 +1454,6 @@ static device_config_t sb_pro_v1_config[] = { .name = "addr", .description = "Address", - .type = CONFIG_BINARY, .type = CONFIG_SELECTION, .selection = { @@ -905,7 +1529,6 @@ static device_config_t sb_pro_v2_config[] = { .name = "addr", .description = "Address", - .type = CONFIG_BINARY, .type = CONFIG_SELECTION, .selection = { @@ -1019,6 +1642,34 @@ static device_config_t sb_pro_mcv_config[] = static device_config_t sb_16_config[] = { + { + .name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "0x280", + .value = 0x280 + }, + { + .description = "" + } + }, + .default_int = 0x220 + }, { .name = "midi", .description = "MIDI out device", @@ -1050,7 +1701,62 @@ static device_config_t sb_16_config[] = static device_config_t sb_awe32_config[] = { { - .name = "midi", + .name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "0x280", + .value = 0x280 + }, + { + .description = "" + } + }, + .default_int = 0x220 + }, + { + .name = "emu_addr", + .description = "EMU8000 Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x620", + .value = 0x620 + }, + { + .description = "0x640", + .value = 0x640 + }, + { + .description = "0x660", + .value = 0x660 + }, + { + .description = "0x680", + .value = 0x680 + }, + { + .description = "" + } + }, + .default_int = 0x620 + }, + { .name = "midi", .description = "MIDI out device", .type = CONFIG_MIDI, .default_int = 0 @@ -1155,7 +1861,7 @@ device_t sb_2_device = sb_speed_changed, NULL, sb_add_status_info, - sb_config + sb2_config }; device_t sb_pro_v1_device = { @@ -1210,7 +1916,7 @@ device_t sb_awe32_device = "Sound Blaster AWE32", 0, sb_awe32_init, - sb_close, + sb_awe32_close, sb_awe32_available, sb_speed_changed, NULL, diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index b0dbe1d..6bb1639 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -16,10 +16,22 @@ #include "sound_sb_dsp.h" #include "timer.h" +/*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ +#define SB_DSP_REC_SAFEFTY_MARGIN 4096 + void pollsb(void *p); void sb_poll_i(void *p); +//#define SB_DSP_RECORD_DEBUG +//#define SB_TEST_RECORDING_SAW +#ifdef SB_DSP_RECORD_DEBUG +FILE* soundf = 0/*NULL*/; +#endif + +#ifdef SB_TEST_RECORDING_SAW +int counttest; +#endif static int sbe2dat[4][9] = { { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, @@ -133,9 +145,20 @@ void sb_dsp_reset(sb_dsp_t *dsp) dsp->sbreset = 0; dsp->sbenable = dsp->sb_enable_i = dsp->sb_count_i = 0; + dsp->record_pos_read=0; + dsp->record_pos_write=SB_DSP_REC_SAFEFTY_MARGIN; + picintc(1 << dsp->sb_irqnum); dsp->asp_data_len = 0; + + #ifdef SB_DSP_RECORD_DEBUG + if (soundf != 0) + { + fclose(soundf); + soundf=0; + } + #endif } void sb_doreset(sb_dsp_t *dsp) @@ -205,8 +228,8 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0; dsp->sb_16_output = 1; timer_process(); - dsp->sbenable = dsp->sb_16_enable; - timer_update_outstanding(); + 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); } } @@ -215,6 +238,13 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l { if (dma8) { +#ifdef SB_TEST_RECORDING_SAW + switch (dsp->sb_8_format) + { + case 00:case 20:counttest=0x80;break; + case 10:case 30:counttest=0;break; + } +#endif dsp->sb_8_length = len; dsp->sb_8_format = format; dsp->sb_8_autoinit = autoinit; @@ -229,6 +259,13 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l } else { +#ifdef SB_TEST_RECORDING_SAW + switch (dsp->sb_16_format) + { + case 00:case 20:counttest=0x8000;break; + case 10:case 30:counttest=0;break; + } +#endif dsp->sb_16_length = len; dsp->sb_16_format = format; dsp->sb_16_autoinit = autoinit; @@ -241,6 +278,16 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l timer_update_outstanding(); // pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); } + memset(dsp->record_buffer,0,sizeof(dsp->record_buffer)); + + #ifdef SB_DSP_RECORD_DEBUG + if (soundf != 0) + { + fclose(soundf); + soundf=0; + } + #endif + } int sb_8_read_dma(sb_dsp_t *dsp) @@ -250,14 +297,23 @@ int sb_8_read_dma(sb_dsp_t *dsp) void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val) { dma_channel_write(dsp->sb_8_dmanum, val); +#ifdef SB_DSP_RECORD_DEBUG + if (!soundf) soundf=fopen("sound_dsp.pcm","wb"); + fwrite(&val,1,1,soundf); +#endif } uint16_t sb_16_read_dma(sb_dsp_t *dsp) { - return dma_channel_read(5); + return dma_channel_read(dsp->sb_16_dmanum); } -void sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) +int sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) { - dma_channel_write(5, val); + int ret = dma_channel_write(dsp->sb_16_dmanum, val); +#ifdef SB_DSP_RECORD_DEBUG + if (!soundf) soundf=fopen("sound_dsp.pcm","wb"); + fwrite(&val,2,1,soundf); +#endif + return (ret == DMA_NODATA); } void sb_dsp_setirq(sb_dsp_t *dsp, int irq) @@ -270,6 +326,10 @@ void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) dsp->sb_8_dmanum = dma; } +void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) +{ + dsp->sb_16_dmanum = dma; +} void sb_exec_command(sb_dsp_t *dsp) { int temp,c; @@ -310,7 +370,19 @@ void sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_length--; break; case 0x20: /*8-bit direct input*/ - sb_add_data(dsp, 0); + sb_add_data(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); + /*Due to the current implementation, I need to emulate a samplerate, even if this + * mode does not imply such samplerate. Position is increased in sb_poll_i*/ + if (dsp->sb_enable_i==0) + { + dsp->sb_timei = 256 - 22; + dsp->sblatchi = TIMER_USEC * 22; + temp = 1000000 / 22; + dsp->sb_freq = temp; + timer_process(); + dsp->sb_enable_i = 1; + timer_update_outstanding(); + } break; case 0x24: /*8-bit single cycle DMA input*/ sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); @@ -373,28 +445,30 @@ void sb_exec_command(sb_dsp_t *dsp) 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(); + timer_process(); dsp->sbenable = 1; timer_update_outstanding(); break; case 0x90: /*High speed 8-bit autoinit DMA output*/ - if (dsp->sb_type < SB2) break; + if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x91: /*High speed 8-bit single cycle DMA output*/ - if (dsp->sb_type < SB2) break; + if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0x98: /*High speed 8-bit autoinit DMA input*/ - if (dsp->sb_type < SB2) break; + if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x99: /*High speed 8-bit single cycle DMA input*/ - if (dsp->sb_type < SB2) break; + if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0xA0: /*Set input mode to mono*/ case 0xA8: /*Set input mode to stereo*/ + if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; + //TODO: Implement. 3.xx-only command. break; case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7: /*16-bit DMA output*/ @@ -424,9 +498,17 @@ void sb_exec_command(sb_dsp_t *dsp) dsp->sb_8_pause = 1; break; case 0xD1: /*Speaker on*/ + if (dsp->sb_type < SB15 ) + dsp->sb_8_pause = 1; + else if ( dsp->sb_type < SB16 ) + dsp->muted = 0; dsp->sb_speaker = 1; break; case 0xD3: /*Speaker off*/ + if (dsp->sb_type < SB15 ) + dsp->sb_8_pause = 1; + else if ( dsp->sb_type < SB16 ) + dsp->muted = 1; dsp->sb_speaker = 0; break; case 0xD4: /*Continue 8-bit DMA*/ @@ -481,6 +563,10 @@ void sb_exec_command(sb_dsp_t *dsp) // pclog("Trigger IRQ\n"); sb_irq(dsp, 1); break; + case 0xF3: /*Trigger 16-bit IRQ*/ +// pclog("Trigger IRQ\n"); + sb_irq(dsp, 0); + break; case 0xE7: /*???*/ case 0xFA: /*???*/ break; @@ -517,6 +603,22 @@ void sb_exec_command(sb_dsp_t *dsp) break; // default: // fatal("Exec bad SB command %02X\n",sb_command); + + + /*TODO: Some more data about the DSP registeres + * http://the.earth.li/~tfm/oldpage/sb_dsp.html + * http://www.synchrondata.com/pheaven/www/area19.htm + * http://www.dcee.net/Files/Programm/Sound/ + 0E3h DSP Copyright SBPro2??? + 0F0h Sine Generator SB + 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 + 0F2h IRQ Request, 8-bit SB + 0F3h IRQ Request, 16-bit SB16 + 0FBh DSP Status SB16 + 0FCh DSP Auxiliary Status SB16 + 0FDh DSP Command Status SB16 + */ + } } @@ -570,7 +672,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) { @@ -613,8 +714,10 @@ void sb_dsp_init(sb_dsp_t *dsp, int type) { dsp->sb_type = type; + // Default values. Use sb_dsp_setxxx() methods to change. dsp->sb_irqnum = 7; dsp->sb_8_dmanum = 1; + dsp->sb_16_dmanum = 5; sb_doreset(dsp); @@ -670,7 +773,7 @@ void pollsb(void *p) dsp->sbleftright = !dsp->sbleftright; } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; dsp->sb_8_length--; break; case 0x10: /*Mono signed*/ @@ -685,7 +788,7 @@ void pollsb(void *p) dsp->sbleftright = !dsp->sbleftright; } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; dsp->sb_8_length--; break; case 0x20: /*Stereo unsigned*/ @@ -737,7 +840,7 @@ void pollsb(void *p) dsp->sbleftright = !dsp->sbleftright; } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; case ADPCM_26: @@ -771,7 +874,7 @@ void pollsb(void *p) dsp->sbleftright = !dsp->sbleftright; } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; case ADPCM_2: @@ -801,7 +904,7 @@ void pollsb(void *p) dsp->sbleftright = !dsp->sbleftright; } else - dsp->sbdatl = dsp->sbdatr = dsp->sbdat; + dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; // default: @@ -839,7 +942,6 @@ 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); } @@ -867,32 +969,57 @@ void pollsb(void *p) void sb_poll_i(void *p) { sb_dsp_t *dsp = (sb_dsp_t *)p; - + int processed=0; 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) { - case 0x00: /*Mono unsigned*/ - sb_8_write_dma(dsp, 0x80); +#ifdef SB_TEST_RECORDING_SAW + case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ + case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ + sb_8_write_dma(dsp, counttest); + counttest+=0x10; + counttest&=0xFF; dsp->sb_8_length--; break; - case 0x10: /*Mono signed*/ - sb_8_write_dma(dsp, 0x00); + case 0x20: /*Unsigned stereo*/ + case 0x30: /*Signed stereo*/ + sb_8_write_dma(dsp, counttest); + sb_8_write_dma(dsp, counttest); + counttest+=0x10; + counttest&=0xFF; + dsp->sb_8_length -= 2; + break; +#else + case 0x00: /*Mono unsigned As the manual says, only the left channel is recorded*/ + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); dsp->sb_8_length--; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; + break; + case 0x10: /*Mono signed As the manual says, only the left channel is recorded*/ + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)); + dsp->sb_8_length--; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; break; case 0x20: /*Stereo unsigned*/ - sb_8_write_dma(dsp, 0x80); - sb_8_write_dma(dsp, 0x80); + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)^0x80); + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read+1]>>8)^0x80); dsp->sb_8_length -= 2; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; break; case 0x30: /*Stereo signed*/ - sb_8_write_dma(dsp, 0x00); - sb_8_write_dma(dsp, 0x00); + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8)); + sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read+1]>>8)); dsp->sb_8_length -= 2; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; break; - +#endif // default: // fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format); } @@ -901,33 +1028,65 @@ void sb_poll_i(void *p) { // 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; + else dsp->sb_8_enable = dsp->sb_enable_i = 0; sb_irq(dsp, 1); } + processed=1; } if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && !dsp->sb_16_output) { switch (dsp->sb_16_format) { - case 0x00: /*Unsigned mono*/ - sb_16_write_dma(dsp, 0x8000); - dsp->sb_16_length--; - break; - case 0x10: /*Signed mono*/ - sb_16_write_dma(dsp, 0); +#ifdef SB_TEST_RECORDING_SAW + case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ + case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ + if (sb_16_write_dma(dsp, counttest)) + return; + counttest+=0x1000; + counttest&=0xFFFF; dsp->sb_16_length--; break; case 0x20: /*Unsigned stereo*/ - sb_16_write_dma(dsp, 0x8000); - sb_16_write_dma(dsp, 0x8000); + case 0x30: /*Signed stereo*/ + if (sb_16_write_dma(dsp, counttest)) + return; + sb_16_write_dma(dsp, counttest); + counttest+=0x1000; + counttest&=0xFFFF; dsp->sb_16_length -= 2; break; +#else + case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) + return; + dsp->sb_16_length--; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; + break; + case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) + return; + dsp->sb_16_length--; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; + break; + case 0x20: /*Unsigned stereo*/ + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) + return; + sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read+1]^0x8000); + dsp->sb_16_length -= 2; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; + break; case 0x30: /*Signed stereo*/ - sb_16_write_dma(dsp, 0); - sb_16_write_dma(dsp, 0); + if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read])) + return; + sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read+1]); dsp->sb_16_length -= 2; + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; break; - +#endif // default: // fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format); } @@ -936,20 +1095,43 @@ void sb_poll_i(void *p) { // 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; + else dsp->sb_16_enable = dsp->sb_enable_i = 0; sb_irq(dsp, 0); } + processed=1; + } + //Assume this is direct mode + if (!processed) + { + dsp->record_pos_read+=2; + dsp->record_pos_read&=0xFFFF; } } void sb_dsp_update(sb_dsp_t *dsp) { + /*this "if" implements two things: speaker on/off and buffer cleanup after stopping audio. */ + if (!dsp->sbenable || dsp->muted) + { + dsp->sbdatl=0; + dsp->sbdatr=0; + } for (; dsp->pos < sound_pos_global; dsp->pos++) { dsp->buffer[dsp->pos*2] = dsp->sbdatl; dsp->buffer[dsp->pos*2 + 1] = dsp->sbdatr; } } +void sb_dsp_close(sb_dsp_t *dsp) +{ + #ifdef SB_DSP_RECORD_DEBUG + if (soundf != 0) + { + fclose(soundf); + soundf=0; + } + #endif +} void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) { diff --git a/src/sound_sb_dsp.h b/src/sound_sb_dsp.h index e945b40..3c100e5 100644 --- a/src/sound_sb_dsp.h +++ b/src/sound_sb_dsp.h @@ -5,11 +5,13 @@ typedef struct sb_dsp_t int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; int sb_8_dmanum; int sb_16_length, sb_16_format, sb_16_autoinit, sb_16_pause, sb_16_enable, sb_16_autolen, sb_16_output; + int sb_16_dmanum; int sb_pausetime; uint8_t sb_read_data[256]; int sb_read_wp, sb_read_rp; int sb_speaker; + int muted; int sb_data_stat; @@ -56,15 +58,20 @@ typedef struct sb_dsp_t int asp_data_len; int wb_time, wb_full; - + + int record_pos_read; + int record_pos_write; + int16_t record_buffer[0xFFFF]; int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; } sb_dsp_t; void sb_dsp_init(sb_dsp_t *dsp, int type); +void sb_dsp_close(sb_dsp_t *dsp); void sb_dsp_setirq(sb_dsp_t *dsp, int irq); void sb_dsp_setdma8(sb_dsp_t *dsp, int dma); +void sb_dsp_setdma16(sb_dsp_t *dsp, int dma); void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr); void sb_dsp_speed_changed(sb_dsp_t *dsp); From 06f7cd3c6c35d65b9aff3f2a8b821b36707227b2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Oct 2017 15:42:32 +0100 Subject: [PATCH 0151/1050] Hard disc controllers can now be selected on all machines. Added device configuration for hard disc controller to Wx GUI. --- src/device.h | 5 + src/hdd.c | 79 +- src/hdd.h | 5 + src/ide.c | 62 +- src/ide.h | 5 +- src/model.c | 24 +- src/pc.xrc | 23 +- src/wx-config.c | 144 +- src/wx-resources.cpp | 6886 +++++++++++++++++++++--------------------- src/xtide.c | 4 +- 10 files changed, 3711 insertions(+), 3526 deletions(-) diff --git a/src/device.h b/src/device.h index 0e2dd8c..3127362 100644 --- a/src/device.h +++ b/src/device.h @@ -1,3 +1,6 @@ +#ifndef _DEVICE_H_ +#define _DEVICE_H_ + #define CONFIG_STRING 0 #define CONFIG_INT 1 #define CONFIG_BINARY 2 @@ -54,3 +57,5 @@ enum int model_get_config_int(char *s); char *model_get_config_string(char *s); + +#endif diff --git a/src/hdd.c b/src/hdd.c index 9cf3a40..f342592 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -4,6 +4,7 @@ #include "esdi_at.h" #include "hdd_esdi.h" +#include "ide.h" #include "mfm_at.h" #include "mfm_xebec.h" #include "xtide.h" @@ -20,17 +21,19 @@ static struct char internal_name[16]; device_t *device; int is_mfm; + int is_ide; } hdd_controllers[] = { - {"None", "none", &null_hdd_device, 0}, - {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1}, - {"[MFM] DTC 5150X", "dtc5150x", &dtc_5150x_device, 1}, - {"[MFM] Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1}, - {"[ESDI] IBM ESDI Fixed Disk Controller", "esdi_mca", &hdd_esdi_device, 1}, - {"[ESDI] Western Digital WD1007V-SE1", "wd1007vse1", &wd1007vse1_device, 0}, - {"[IDE] XTIDE", "xtide", &xtide_device, 0}, - {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, - {"", "", NULL, 0} + {"None", "none", &null_hdd_device, 0, 0}, + {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1, 0}, + {"[MFM] DTC 5150X", "dtc5150x", &dtc_5150x_device, 1, 0}, + {"[MFM] Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1, 0}, + {"[ESDI] IBM ESDI Fixed Disk Controller", "esdi_mca", &hdd_esdi_device, 1, 0}, + {"[ESDI] Western Digital WD1007V-SE1", "wd1007vse1", &wd1007vse1_device, 0, 0}, + {"[IDE] Standard IDE", "ide", &ide_device, 0, 1}, + {"[IDE] XTIDE", "xtide", &xtide_device, 0, 1}, + {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0, 1}, + {"", "", NULL, 0, 0} }; char *hdd_controller_get_name(int hdd) @@ -53,7 +56,7 @@ int hdd_controller_available(int hdd) return device_available(hdd_controllers[hdd].device); } -int hdd_controller_is_mfm(char* internal_name) +int hdd_controller_is_mfm(char *internal_name) { int c = 0; @@ -70,11 +73,67 @@ int hdd_controller_is_mfm(char* internal_name) return 0; } +int hdd_controller_is_ide(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")) + return hdd_controllers[c].is_ide; + } + c++; + } + + return 0; +} +int hdd_controller_has_config(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")) + return hdd_controllers[c].device->config ? 1 : 0; + } + c++; + } + + return 0; +} + +device_t *hdd_controller_get_device(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")) + return hdd_controllers[c].device; + } + c++; + } + + return NULL; +} int hdd_controller_current_is_mfm() { return hdd_controller_is_mfm(hdd_controller_name); } +int hdd_controller_current_is_ide() +{ + return hdd_controller_is_ide(hdd_controller_name); +} void hdd_controller_init(char *internal_name) { diff --git a/src/hdd.h b/src/hdd.h index 26faa2b..65e1989 100644 --- a/src/hdd.h +++ b/src/hdd.h @@ -1,9 +1,14 @@ +#include "device.h" + 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_is_mfm(char* internal_name); +int hdd_controller_has_config(char *internal_name); +device_t *hdd_controller_get_device(char *internal_name); int hdd_controller_current_is_mfm(); +int hdd_controller_current_is_ide(); void hdd_controller_init(char *internal_name); extern char hdd_controller_name[16]; diff --git a/src/ide.c b/src/ide.c index 085097b..0991203 100644 --- a/src/ide.c +++ b/src/ide.c @@ -20,6 +20,7 @@ #include "arm.h" #else #include "ibm.h" + #include "hdd.h" #include "io.h" #include "pic.h" #include "timer.h" @@ -708,29 +709,31 @@ void resetide(void) memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ idecallback[0]=idecallback[1]=0; + if (hdd_controller_current_is_ide()) + { #ifdef RPCEMU_IDE - loadhd(&ide_drives[0], 0, "hd4.hdf"); - if (!config.cdromenabled) { - loadhd(&ide_drives[1], 1, "hd5.hdf"); - } - else - ide_drives[1].type = IDE_CDROM; + loadhd(&ide_drives[0], 0, "hd4.hdf"); + if (!config.cdromenabled) + loadhd(&ide_drives[1], 1, "hd5.hdf"); + else + ide_drives[1].type = IDE_CDROM; #else - for (d = 0; d < 4; d++) - { - ide_drives[d].drive = d; - ide_drives[d].packetstatus = 0xFF; + for (d = 0; d < 4; d++) + { + ide_drives[d].drive = d; + ide_drives[d].packetstatus = 0xFF; - if ((cdrom_channel == d) && cdrom_enabled) - { - ide_drives[d].type = IDE_CDROM; - } - else - { - loadhd(&ide_drives[d], d, ide_fn[d]); - } + if ((cdrom_channel == d) && cdrom_enabled) + { + ide_drives[d].type = IDE_CDROM; + } + else + { + loadhd(&ide_drives[d], d, ide_fn[d]); + } - ide_set_signature(&ide_drives[d]); + ide_set_signature(&ide_drives[d]); + } } #endif @@ -2850,7 +2853,7 @@ void ide_sec_disable() io_removehandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); } -void ide_init() +static void *ide_init() { ide_pri_enable(); ide_sec_enable(); @@ -2858,6 +2861,12 @@ void ide_init() timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); + + return (void *)-1; +} + +static void ide_close(void *p) +{ } 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)) @@ -2866,3 +2875,16 @@ void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*wr ide_bus_master_write_sector = write_sector; ide_bus_master_set_irq = set_irq; } + +device_t ide_device = +{ + "Standard IDE", + DEVICE_AT, + ide_init, + ide_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/ide.h b/src/ide.h index 4c4e0b6..45de5e5 100644 --- a/src/ide.h +++ b/src/ide.h @@ -1,6 +1,8 @@ #ifndef __IDE__ #define __IDE__ +#include "device.h" + struct IDE; extern void writeide(int ide_board, uint16_t addr, uint8_t val); @@ -9,7 +11,6 @@ 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_pri_enable(); extern void ide_sec_enable(); extern void ide_pri_disable(); @@ -58,4 +59,6 @@ uint32_t atapi_get_cd_volume(int channel); #define CDROM_IMAGE 200 +extern device_t ide_device; + #endif //__IDE__ diff --git a/src/model.c b/src/model.c index f3798cc..39d2c9a 100644 --- a/src/model.c +++ b/src/model.c @@ -67,7 +67,6 @@ void europc_init(); void olim24_init(); void at_init(); void ibm_at_init(); -void at_ide_init(); void at_cbm_init(); void dells200_init(); void deskpro386_init(); @@ -328,16 +327,9 @@ void ibm_at_init() mem_remap_top_384k(); } -void at_ide_init() -{ - at_init(); - ide_init(); - mem_remap_top_384k(); -} - void at_cbm_init() { - at_ide_init(); + at_init(); cbm_io_init(); } @@ -360,7 +352,6 @@ void ps1_common_init() mem_add_bios(); pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); - ide_init(); keyboard_at_init(); nvr_init(); pic2_init(); @@ -391,7 +382,6 @@ void ps2_m30_286_init() mem_add_bios(); pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); - ide_init(); keyboard_at_init(); // mouse_ps2_init(); nvr_init(); @@ -407,7 +397,6 @@ static void ps2_common_init() mem_add_bios(); dma16_init(); ps2_dma_init(); - ide_init(); keyboard_at_init(); keyboard_at_init_ps2(); // mouse_ps2_init(); @@ -438,56 +427,48 @@ void ps2_model_80_init() void at_neat_init() { at_init(); - ide_init(); neat_init(); } void at_scat_init() { at_init(); - ide_init(); scat_init(); } void at_acer386sx_init() { at_init(); - ide_init(); acer386sx_init(); } void at_wd76c10_init() { at_init(); - ide_init(); wd76c10_init(); } void at_headland_init() { at_init(); - ide_init(); headland_init(); } void at_opti495_init() { at_init(); - ide_init(); opti495_init(); } void at_ali1429_init() { at_init(); - ide_init(); ali1429_init(); } void at_sis496_init() { at_init(); - ide_init(); pci_init(PCI_CONFIG_TYPE_1); pci_slot(0xb); pci_slot(0xd); @@ -498,7 +479,6 @@ void at_sis496_init() void at_batman_init() { at_init(); - ide_init(); pci_init(PCI_CONFIG_TYPE_2); pci_slot(0xc); pci_slot(0xe); @@ -512,7 +492,6 @@ void at_batman_init() void at_endeavor_init() { at_init(); - ide_init(); pci_init(PCI_CONFIG_TYPE_1); pci_slot(0xd); pci_slot(0xe); @@ -528,7 +507,6 @@ void at_endeavor_init() void at_i430vx_init() { at_init(); - ide_init(); pci_init(PCI_CONFIG_TYPE_1); pci_slot(0x11); pci_slot(0x12); diff --git a/src/pc.xrc b/src/pc.xrc index d99ce13..42cb4fb 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -964,7 +964,7 @@ 0 0 - 2 + 3 0 0 1 @@ -998,6 +998,15 @@ + + + wxALL + 5 + + icons/16x16/setting_tools.png + 0 + + wxALL | wxALIGN_CENTER_VERTICAL @@ -1027,6 +1036,12 @@ + + + wxEXPAND + 5 + 0,0 + wxALL | wxALIGN_CENTER_VERTICAL @@ -1056,6 +1071,12 @@ + + + wxEXPAND + 5 + 0,0 + diff --git a/src/wx-config.c b/src/wx-config.c index 9aca8b5..e3ca304 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -45,6 +45,9 @@ extern void deviceconfig_open(void* hwnd, device_t *device); extern int hdconf_init(void* hdlg); extern int hdconf_update(void* hdlg); +static int hdd_controller_selected_has_config(void *hdlg); +static device_t *hdd_controller_selected_get_device(void *hdlg); + static int mouse_valid(int type, int model) { if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2) @@ -142,72 +145,75 @@ static void recalc_snd_list(void* hdlg, int model) wx_sendmessage(h, WX_CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); } -static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd) +static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int force_ide) { void* h; + char *s; + int valid = 0; + char old_name[16]; + int c, d; h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - if (models[model].flags & MODEL_HAS_IDE) + if (force_ide) + strcpy(old_name, "ide"); + else if (use_selected_hdd) { - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Internal IDE"); - wx_enablewindow(h, FALSE); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + strncpy(old_name, hdd_names[c], sizeof(old_name)-1); + else + { + if (models[model].flags & MODEL_HAS_IDE) + strcpy(old_name, "none"); + else + strcpy(old_name, "ide"); + } } else - { - char *s; - int valid = 0; - char old_name[16]; - int c, d; - - if (use_selected_hdd) - { - c = wx_sendmessage(h, WX_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); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) - { - s = hdd_controller_get_name(c); - if (s[0] == 0) + wx_sendmessage(h, WX_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)) || - (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model].flags & MODEL_MCA)) && c) - { - c++; - continue; - } - if (!hdd_controller_available(c)) - { - c++; - continue; - } - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - hdd_names[d] = hdd_controller_get_internal_name(c); - if (!strcmp(old_name, hdd_names[d])) - { - wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - valid = 1; - } + if ((((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) || + (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model].flags & MODEL_MCA)) && c) + { c++; - d++; + continue; } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + hdd_names[d] = hdd_controller_get_internal_name(c); - if (!valid) + if (!strcmp(old_name, hdd_names[d])) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, TRUE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); + if (hdd_controller_selected_has_config(hdlg)) wx_enablewindow(h, TRUE); - } + else + wx_enablewindow(h, FALSE); } #ifdef USE_NETWORKING @@ -469,6 +475,7 @@ int config_dlgsave(void* hdlg) return TRUE; } +static int prev_model; int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { char temp_str[256]; @@ -510,6 +517,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) c++; } wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); + prev_model = model; recalc_vid_list(hdlg, romstomodel[romset]); @@ -711,7 +719,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) } wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - recalc_hdd_list(hdlg, romstomodel[romset], 0); + recalc_hdd_list(hdlg, romstomodel[romset], 0, 0); hd_changed = 0; new_cdrom_channel = cdrom_channel; @@ -735,8 +743,15 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { if (wParam == WX_ID("IDC_COMBO1")) { + int force_ide = 0; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + if ((models[temp_model].flags & MODEL_HAS_IDE) && !(models[prev_model].flags & MODEL_HAS_IDE)) + force_ide = 1; + + prev_model = temp_model; /*Rebuild manufacturer list*/ h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); @@ -851,7 +866,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) recalc_vid_list(hdlg, temp_model); - recalc_hdd_list(hdlg, temp_model, 1); + recalc_hdd_list(hdlg, temp_model, 1, force_ide); recalc_snd_list(hdlg, temp_model); #ifdef USE_NETWORKING @@ -989,6 +1004,10 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { hdconf_update(hdlg); } + else if (wParam == WX_ID("IDC_CONFIGUREHDD")) + { + deviceconfig_open(hdlg, (void *)hdd_controller_selected_get_device(hdlg)); + } #ifdef USE_NETWORKING else if (wParam == WX_ID("IDC_COMBO_NETCARD")) { @@ -1088,6 +1107,22 @@ static int hdd_controller_selected_is_mfm(void* hdlg) return hdd_controller_is_mfm(hdd_names[c]); return 0; } +static int hdd_controller_selected_has_config(void* hdlg) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_has_config(hdd_names[c]); + return 0; +} +static device_t *hdd_controller_selected_get_device(void *hdlg) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_get_device(hdd_names[c]); + return NULL; +} static void check_hd_type(void* hdlg, off64_t sz) { @@ -1521,6 +1556,7 @@ int hdconf_init(void* hdlg) int hdconf_update(void* hdlg) { char s[260]; + void *h; int is_mfm = hdd_controller_selected_is_mfm(hdlg); @@ -1561,6 +1597,12 @@ int hdconf_update(void* hdlg) } } + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); + if (hdd_controller_selected_has_config(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + return TRUE; } diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 9b89204..426c161 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1722,7 +1722,7 @@ static unsigned char xml_res_file_24[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_25 = 127112; +static size_t xml_res_size_25 = 128231; static unsigned char xml_res_file_25[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -1735,103 +1735,104 @@ static unsigned char xml_res_file_25[] = { 61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, 61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, -54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47,111,98,106,101, -99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65, -80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,100,105,115, -107,101,116,116,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,67,68,82,79, -77,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,99,100,46,112,110,103,60,47,111, +101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47, +111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34, +66,73,84,77,65,80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +54,120,49,54,95,100,105,115,107,101,116,116,101,46,112,110,103,60,47,111, 98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61,34,116, -111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108,101,62, -119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86,73,68, -69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61, -34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,50,52,120,50,52,95,112,108,97,121,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, -108,62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66, -65,82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, -62,80,97,117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76, -66,65,82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, -83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, +115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73, +84,77,65,80,95,67,68,82,79,77,34,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54,120, +49,54,95,99,100,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,111,111, +108,66,97,114,34,32,110,97,109,101,61,34,116,111,111,108,95,98,97,114,34, +62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,84,66,95,70,76,65,84, +124,119,120,84,66,95,78,79,68,73,86,73,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116, +111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,82,85,78, +34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110, +115,95,50,52,120,50,52,95,112,108,97,121,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,117,110,60, +47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116,111, +111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,80,65,85,83, +69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, +110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97, +117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, -82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, -62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, -111,110,115,95,50,52,120,50,52,95,114,101,102,114,101,115,104,46,112,110, +82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48, +45,105,99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110, 103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, -108,62,72,97,114,100,32,114,101,115,101,116,60,47,108,97,98,101,108,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, -101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84, -34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32,32,60,105,100,115, -45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, -69,83,79,76,85,84,73,79,78,34,32,115,116,97,114,116,61,34,57,57,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,70,83,34,32,115,116,97,114,116,61,34,49,48,48,48, -34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,34,32,115,116,97,114, -116,61,34,49,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,34,32, -115,116,97,114,116,61,34,49,50,48,48,34,47,62,10,32,32,60,105,100,115,45, -114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67, -65,76,69,95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,51,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,32,115, -116,97,114,116,61,34,49,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114, -97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70, -34,32,115,116,97,114,116,61,34,50,48,48,48,34,47,62,10,32,32,60,105,100, -115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34,32,115,116,97, -114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73, -78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,51,49,48,48, -34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70, -82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51,50,48,48,34, -47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, -117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, -118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, -101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, -67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, -84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, -98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +108,62,83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76, +66,65,82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +48,48,48,45,105,99,111,110,115,95,50,52,120,50,52,95,114,101,102,114,101, +115,104,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,60,108,97,98,101,108,62,72,97,114,100,32,114,101,115,101,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95, +70,79,82,77,65,84,34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77, +95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,34,32,115,116,97,114,116,61, +34,57,57,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,34,32,115,116,97,114,116, +61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,34, +32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,105,100,115, +45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, +67,65,76,69,34,32,115,116,97,114,116,61,34,49,50,48,48,34,47,62,10,32,32, +60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,95,77,79,68,69,34,32,115,116,97,114,116,61,34, +49,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73, +86,69,82,34,32,115,116,97,114,116,61,34,49,52,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83, +78,68,95,66,85,70,34,32,115,116,97,114,116,61,34,50,48,48,48,34,47,62,10, +32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34, +32,115,116,97,114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115, +45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, +76,51,95,73,78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34, +51,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, +95,82,69,70,82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51, +50,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116, +97,116,117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97, +99,116,105,118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +77,65,67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97, +116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95, +83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, 83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, 60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, @@ -2508,239 +2509,39 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, 100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110, +115,95,51,50,120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, -108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, +65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, -85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, -80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, -105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, +60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -2767,91 +2568,8 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, -61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, -120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, 62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, 65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, @@ -2866,17 +2584,290 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,115, +101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110, +97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111, +114,121,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67,116, +114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, +75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109, +105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, +77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, 105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, +79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, @@ -2887,44 +2878,267 @@ static unsigned char xml_res_file_25[] = { 60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, -67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, -32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, +122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, +99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45, +105,99,111,110,115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111, +100,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, +86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82, +69,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54, +120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +112,101,101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, +83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79, +79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111, +32,71,114,97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79, +79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54, +120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99, +116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, +110,115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47, 98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, 108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, @@ -2983,218 +3197,6 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, -73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, -60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, 67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, 67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, @@ -3222,24 +3224,62 @@ static unsigned char xml_res_file_25[] = { 34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, 97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105, +110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60, +47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3248,31 +3288,31 @@ static unsigned char xml_res_file_25[] = { 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -3286,9 +3326,9 @@ static unsigned char xml_res_file_25[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, -115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, +95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, +97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, @@ -3305,435 +3345,441 @@ static unsigned char xml_res_file_25[] = { 60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, -83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, -62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, -101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, -99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, -73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, -47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, -60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, 116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50, +95,100,114,105,118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,80,65,78,69,76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84, +82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, +85,82,69,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, +114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99, +111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111, +111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, -79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, -68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, -49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, +68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, 103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68, -50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, -111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,116,97,116,105,99,76,105,110,101,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,76,73,95,72,79,82,73,90,79,78,84,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,32,124,32,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,104,111,105,99,101,98,111,111,107,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,72,66,95,68,69,70,65,85,76,84,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111, -105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,68,114,105,118,101,32,49,32,40,67,58,41,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101, -100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, -97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, -65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, -108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,66,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,73,95, +72,79,82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +111,105,99,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72, +66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,49, +32,40,67,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, @@ -3813,7 +3859,495 @@ static unsigned char xml_res_file_25[] = { 116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, +48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, +124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, +66,69,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,72,80,67,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,52,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69, +88,84,95,83,73,90,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68, +67,95,80,65,78,69,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,48,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,91, +49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32, +100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, +82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, 54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, 98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, @@ -3837,145 +4371,233 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, 111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, 116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45, +105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91, +49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105, +108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, +48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99,111,110,116, -114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105,116,109,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,106, -101,99,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, -48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, -47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, +124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,49,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, +124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,69,68,73,84,95,72,80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,52,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, +108,105,110,100,101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3996,7 +4618,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, -95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +95,67,89,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, 97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, @@ -4016,9 +4638,9 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93,34,62,10,32,32,32,32,32, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47, 108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, 97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, @@ -4039,33 +4661,122 @@ static unsigned char xml_res_file_25[] = { 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10, +97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111,105,99,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105, +118,101,32,51,32,40,69,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,50,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, +83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76, +65,66,69,76,91,50,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, -66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73, +68,67,95,72,68,68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47, +118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, @@ -4082,163 +4793,10 @@ static unsigned char xml_res_file_25[] = { 98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32, +119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,68,82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90, -69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, -111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, -116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, -76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, +32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, 60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4247,75 +4805,52 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, 116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, @@ -4324,34 +4859,34 @@ static unsigned char xml_res_file_25[] = { 114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32, +109,101,61,34,73,68,67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, 116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, 109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, 120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +76,91,50,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, 70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4371,7 +4906,7 @@ static unsigned char xml_res_file_25[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, 95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, @@ -4394,162 +4929,75 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, +48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, +124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, 60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -4570,7 +5018,7 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4591,76 +5039,162 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +76,65,66,69,76,91,50,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,51,32,40,69,58,41, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, -47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, -68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69, +68,73,84,95,72,80,67,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,52,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110, +100,101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,50,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,84,69,88,84,95,83,73,90,69,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,52,32,40,70,58, +41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48, +60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,73,68,67,95,80,65,78,69,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, 97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, 48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4681,7 +5215,7 @@ static unsigned char xml_res_file_25[] = { 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,48,93,34, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,48,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47, 115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4721,7 +5255,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, 111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, 108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4747,7 +5281,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, 111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, -82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, 98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4782,575 +5316,89 @@ static unsigned char xml_res_file_25[] = { 114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,51,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, 62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, -117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, 98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, -62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45, +105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, -99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, -62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, -69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, -78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50, -53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, -73,90,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, -111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,114,105,118,101,32,52,32,40,70,58,41,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, -116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, -76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91, +51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105, +108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5371,159 +5419,72 @@ static unsigned char xml_res_file_25[] = { 110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, +48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, +124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, 60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -5544,7 +5505,7 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5565,271 +5526,373 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +76,65,66,69,76,91,51,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, +124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,69,68,73,84,95,72,80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,52,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, +108,105,110,100,101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, +95,67,89,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,51,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50, +95,109,111,117,115,101,95,112,99,46,112,110,103,60,47,98,105,116,109,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117, +115,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85, +83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,109,111,117,115,101,95,112,99,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, -101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, -112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, -60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, -114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50, +95,110,101,116,119,111,114,107,95,101,116,104,101,114,110,101,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,109,95,112,97,110,101,108, +110,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,77,111,117,115,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,77,79,85,83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,110,101,116,119,111,114,107,95,101,116,104,101, -114,110,101,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109, -95,112,97,110,101,108,110,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, -86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, -62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, -60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116,97,116, -105,99,84,101,120,116,55,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114,107,32,99, -97,114,100,32,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, -69,84,67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +34,32,110,97,109,101,61,34,109,95,115,116,97,116,105,99,84,101,120,116, +55,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +108,97,98,101,108,62,78,101,116,119,111,114,107,32,99,97,114,100,32,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,95,78,69,84, -67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, -85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103, -95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,67,65,82,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,67,79,78,70,73,71,85,82,69,95,78,69,84,67,65,82,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, +114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99, +111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111, +111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, +79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, 105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, @@ -5839,179 +5902,195 @@ static unsigned char xml_res_file_25[] = { 98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34, -32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34,62,10,32,32,32, -32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100,32,68,105,115, -99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, -101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32, -32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, -10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, -62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, -111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, -111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, -114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, -69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, -49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, -68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82, -65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, -102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, -97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,72,100,78,101,119,68,108,103,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,78,101,119,32,72,97,114,100,32,68,105,115,99,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, +49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, +68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54, +95,102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, -99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47,108, 97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -6025,7 +6104,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, 114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, -116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50, +116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, @@ -6041,101 +6120,91 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, -122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, -34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109, +98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, 60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6144,26 +6213,6 @@ static unsigned char xml_res_file_25[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, @@ -6581,94 +6630,95 @@ static unsigned char xml_res_file_25[] = { 32,60,116,111,111,108,116,105,112,62,76,111,97,100,60,47,116,111,111,108, 116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,110,116, -114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, -116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, -95,72,79,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -119,105,100,101,115,99,114,101,101,110,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50,95,99, +111,110,116,114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, +70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114, +101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110, +115,95,51,50,120,51,50,95,115,101,116,116,105,110,103,95,116,111,111,108, +115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85, -95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, -62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100,100,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,73,68,67,95,67,79,78,70,73,71,95,72,79,83,84,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +48,48,48,45,105,99,111,110,115,95,51,50,120,51,50,95,119,105,100,101,115, +99,114,101,101,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, +82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,78,101,119,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51, +50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, 102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6687,179 +6737,123 @@ static unsigned char xml_res_file_25[] = { 32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97,109,101,60,47, 116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -99,111,109,112,117,116,101,114,95,101,100,105,116,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80,89,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108,116,105,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101, -114,95,103,111,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, -84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,68,101, -108,101,116,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,100,101,108, -101,116,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79, -68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117,105,116,60,47,116, -111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50, +120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80, +89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,111,111,114, -95,105,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47, -100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97,100,101,114, -77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, -108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, -76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, -101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,32,83,104, -97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62, -10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, -116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, -79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, -101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50,95,99, +111,109,112,117,116,101,114,95,103,111,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,68,101,108,101,116,101,60,47,116,111,111,108,116,105, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116, +101,114,95,100,101,108,101,116,101,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, 120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73, -78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, +85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117, +105,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51, +50,95,100,111,111,114,95,105,110,46,112,110,103,60,47,98,105,116,109,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97, +100,101,114,77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109, +32,83,104,97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116, +108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47, +99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,68, -68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, -70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,46,46, -46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,85,80,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,111,118,101,32,117,112,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66, +95,83,73,78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, @@ -6867,17 +6861,10 @@ static unsigned char xml_res_file_25[] = { 100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118, -101,32,100,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, @@ -6886,91 +6873,154 @@ static unsigned char xml_res_file_25[] = { 60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,112,112, -108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, -100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, -108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82,101, -109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108, -101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, -69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105, -116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, -47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, -101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85, -69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61, -34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105, +103,117,114,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79, +86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,111,118,101,32,117,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,111,118,101,32,100,111,119,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,112,112,108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105, +97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82, +101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, +49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81, +85,69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116, +61,34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -7266,161 +7316,147 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, 47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115, -111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120, -51,50,95,110,101,116,119,111,114,107,95,101,116,104,101,114,110,101,116, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109,95,112, -97,110,101,108,49,57,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, -86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, -50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116, -97,116,105,99,84,101,120,116,55,50,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,78,101,116,119,111,114,107,32,116,121,112,101,32,58,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, -69,84,87,79,82,75,95,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, -65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,53,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115, +95,51,50,120,51,50,95,110,101,116,119,111,114,107,95,101,116,104,101,114, +110,101,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,109,95,112,97,110,101,108,49,57,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65, +66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,109,95,115,116,97,116,105,99,84,101,120, -116,55,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114, -107,32,100,101,118,105,99,101,32,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,87,79,82,75,95, -68,69,86,73,67,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,67,111, -109,98,111,33,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, -110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,109,95,115,116,97,116,105,99,84,101,120,116,55,50,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,78,101,116,119,111,114,107,32,116,121,112,101, +32,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,95,78,69,84,87,79,82,75,95,84,89,80,69,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,53,53,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,100,68,105,97,108, -111,103,66,117,116,116,111,110,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78, -84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, -59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116,97,116, +105,99,84,101,120,116,55,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101, +116,119,111,114,107,32,100,101,118,105,99,101,32,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,87, +79,82,75,95,68,69,86,73,67,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,53,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,62,67,111,109,98,111,33,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98,117,116,116, 111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, @@ -7429,21 +7465,35 @@ static unsigned char xml_res_file_25[] = { 32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, -110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, -60,47,114,101,115,111,117,114,99,101,62,10}; +110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; void InitXmlResource() { @@ -7458,29 +7508,29 @@ void InitXmlResource() else wxFileSystem::AddHandler(new wxMemoryFSHandler); } - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_go.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_network_ethernet.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_control_play_blue.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_setting_tools.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_computer_go.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_24, xml_res_size_24, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); diff --git a/src/xtide.c b/src/xtide.c index 5178a5c..5c16b8f 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -71,7 +71,7 @@ static void *xtide_init() memset(xtide, 0, sizeof(xtide_t)); rom_init(&xtide->bios_rom, "ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); + device_add(&ide_device); ide_pri_disable(); ide_sec_disable(); io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); @@ -85,7 +85,7 @@ static void *xtide_at_init() memset(xtide, 0, sizeof(xtide_t)); rom_init(&xtide->bios_rom, "ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); + device_add(&ide_device); return xtide; } From 50a874c287bbe88d133904fbc93efe22f6a56c0f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Oct 2017 16:08:54 +0100 Subject: [PATCH 0152/1050] Added SCSI hard drive emulation. Added NCR 58c400-based SCSI adapters : - Longshine LCS-6821N - Ranco RT1000B - Trantor T130B --- src/Makefile.am | 4 +- src/Makefile.linux32 | 4 +- src/Makefile.linux32-wx-sdl2 | 4 +- src/Makefile.linux64 | 4 +- src/Makefile.linux64-wx-sdl2 | 4 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 4 +- src/hdd.c | 4 + src/scsi.c | 356 +++++++++++++ src/scsi.h | 103 ++++ src/scsi_53c400.c | 826 +++++++++++++++++++++++++++++ src/scsi_53c400.h | 3 + src/scsi_hd.c | 806 ++++++++++++++++++++++++++++ src/scsi_hd.h | 1 + 18 files changed, 2116 insertions(+), 17 deletions(-) create mode 100644 src/scsi.c create mode 100644 src/scsi.h create mode 100644 src/scsi_53c400.c create mode 100644 src/scsi_53c400.h create mode 100644 src/scsi_hd.c create mode 100644 src/scsi_hd.h diff --git a/src/Makefile.am b/src/Makefile.am index 0f1d680..7a9de4f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,8 +19,8 @@ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.c sis496.c sound.c \ -sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \ +opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c scsi.c scsi_53c400.c scsi_hd.c \ +serial.c sio.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 \ timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 5e620c1..bc74fcd 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -11,8 +11,8 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ -sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_hd.o +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index feb4453..fabb34b 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -10,8 +10,8 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ -sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_hd.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 336cdfc..b41b86f 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -10,8 +10,8 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ -sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_hd.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 8a99245..1ae689f 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -10,8 +10,8 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ -sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_hd.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 2593924..b11a52c 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 ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 67b7239..b95bbf5 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index e207c89..09f850d 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 93e7d23..95f7d81 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_hd.o serial.o sio.o sis496.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 um8881f.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 b0f64b1..7681945 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 ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index a96aa59..f432c30 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -9,8 +9,8 @@ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o serial.o sio.o sis496.o sound.o \ -sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_hd.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/hdd.c b/src/hdd.c index f342592..83f939e 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -7,6 +7,7 @@ #include "ide.h" #include "mfm_at.h" #include "mfm_xebec.h" +#include "scsi_53c400.h" #include "xtide.h" char hdd_controller_name[16]; @@ -33,6 +34,9 @@ static struct {"[IDE] Standard IDE", "ide", &ide_device, 0, 1}, {"[IDE] XTIDE", "xtide", &xtide_device, 0, 1}, {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0, 1}, + {"[SCSI] Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device, 0, 0}, + {"[SCSI] Rancho RT1000B", "rt1000b", &scsi_rt1000b_device, 0, 0}, + {"[SCSI] Trantor T130B", "t130b", &scsi_t130b_device, 0, 0}, {"", "", NULL, 0, 0} }; diff --git a/src/scsi.c b/src/scsi.c new file mode 100644 index 0000000..01d4c98 --- /dev/null +++ b/src/scsi.c @@ -0,0 +1,356 @@ +#include "ibm.h" +#include "ide.h" +#include "scsi.h" +#include "scsi_cd.h" +#include "scsi_hd.h" + +#define STATE_IDLE 0 +#define STATE_COMMAND 1 +#define STATE_COMMANDWAIT 2 +#define STATE_DATAIN 3 +#define STATE_DATAOUT 4 +#define STATE_STATUS 5 +#define STATE_MESSAGEIN 6 +#define STATE_PHASESEL 7 + +#define SET_BUS_STATE(bus, state) bus->bus_out = (bus->bus_out & ~(BUS_CD | BUS_IO | BUS_MSG)) | (state & (BUS_CD | BUS_IO | BUS_MSG)) + +static int cmd_len[8] = {6, 10, 10, 6, 16, 12, 6, 6}; + +static int get_dev_id(uint8_t data) +{ + int c; + + for (c = 0; c < 8; c++) + { + if (data & (1 << c)) + return c; + } + + return -1; +} + +int scsi_bus_update(scsi_bus_t *bus, int bus_assert) +{ + scsi_device_t *dev = NULL; + void *dev_data = NULL; + +// pclog("scsi_hd_bus_update: state=%d bus_assert=%04x bus_in=%02x %i %02x %p\n", bus->state, bus_assert, bus->bus_in, bus->clear_req, bus->bus_out, bus); + + if (bus_assert & BUS_ARB) + bus->state = STATE_IDLE; + + if (bus->dev_id != -1) + { + dev = bus->devices[bus->dev_id]; + dev_data = bus->device_data[bus->dev_id]; + } + + switch (bus->state) + { + case STATE_IDLE: + bus->clear_req = bus->change_state_delay = bus->new_req_delay = 0; + if ((bus_assert & BUS_SEL) && !(bus_assert & BUS_BSY)) + { + uint8_t sel_data = BUS_GETDATA(bus_assert); + + //bus->state = STATE_PHASESEL; + bus->dev_id = get_dev_id(sel_data); +// pclog("PHASESEL %02x %2x %i %p\n", sel_data, bus->bus_out, bus->dev_id, bus->devices[bus->dev_id]); + if (bus->dev_id != -1 && bus->devices[bus->dev_id]) + { + bus->bus_out |= BUS_BSY; + bus->state = STATE_PHASESEL; +// pclog("Move to phase sel\n"); + } + break; + } + break; + case STATE_PHASESEL: + if (!(bus_assert & BUS_SEL)) + { + if (!(bus_assert & BUS_ATN)) + { +/* uint8_t sel_data = BUS_GETDATA(bus_assert); + + bus->dev_id = get_dev_id(sel_data);*/ +// pclog("STATE_PHASESEL: %i %p\n", bus->dev_id, bus->devices[bus->dev_id]); + if (bus->dev_id != -1 && bus->devices[bus->dev_id]) + { + bus->state = STATE_COMMAND; + bus->bus_out = BUS_BSY | BUS_REQ; + bus->command_pos = 0; + SET_BUS_STATE(bus, BUS_CD); + } + else + { + bus->state = STATE_IDLE; + bus->bus_out = 0; + } + } + else + fatal("dropped sel %x\n", bus_assert & BUS_ATN); + } + break; + case STATE_COMMAND: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) + { +// pclog(" get data %02x\n", BUS_GETDATA(bus_assert)); + bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert); + bus->clear_req = 3; + bus->new_state = bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG); + bus->bus_out &= ~BUS_REQ; + + if (cmd_len[bus->command[0] >> 5] == bus->command_pos) + { + int new_state; + + dev->start_command(dev_data); + new_state = dev->command(bus->command, dev_data); +// pclog("COMMAND new_state = %x\n", new_state); + if ((new_state & (BUS_IO | BUS_CD | BUS_MSG)) == BUS_CD) + { + bus->state = STATE_COMMANDWAIT; + bus->clear_req = 0; + } + else + { +// pclog("Set change_state_delay COMMAND\n"); + bus->new_state = new_state; + bus->change_state_delay = 4; + } + } + } + break; + + case STATE_COMMANDWAIT: + { + int new_state; + +// pclog("COMMANDWAIT\n"); + new_state = dev->command(bus->command, dev_data); +// pclog("new_state=%x\n", new_state); + if ((new_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + { +// pclog("Set change_state_delay\n"); + bus->new_state = new_state; + bus->change_state_delay = 4; + bus->clear_req = 4; + } + } + break; + + case STATE_DATAIN: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) + { + if (dev->read_complete(dev_data)) + { +// pclog("Read complete\n"); + bus->bus_out &= ~BUS_REQ; + //bus->clear_req = 3; + bus->new_state = BUS_CD | BUS_IO; +// pclog("change_state_delay STATE_DATAIN\n"); + bus->change_state_delay = 4; + bus->new_req_delay = 8; +// SET_BUS_STATE(data, BUS_CD | BUS_IO); + } + else + { + uint8_t val = dev->read(dev_data); + +// pclog(" Read data pos %04x %02x %x %x\n", bus->data_pos_read, bus->data_in[bus->data_pos_read], bus->data_pos_read, bus->data_pos_write); + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; +// bus->bus_out |= BUS_REQ; + bus->clear_req = 3; + bus->bus_out &= ~BUS_REQ; + bus->new_state = BUS_IO; + } +// scsi_hd_command(bus->command, data); + } + break; + + case STATE_DATAOUT: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) + { + dev->write(BUS_GETDATA(bus_assert), dev_data); +// pclog("Got data %02x\n", BUS_GETDATA(bus_assert)); +// pclog(" Write data pos %04x %02x %08x %08x\n", bus->data_pos_write-1, bus->data_out[bus->data_pos_write-1], cpu_getd(5), cpu_getd(6)); + + if (dev->write_complete(dev_data)) + { + int new_state; + //pclog(" Write data, command complete\n"); + bus->bus_out &= ~BUS_REQ; + new_state = dev->command(bus->command, dev_data); + + bus->new_state = new_state; +// pclog("change_state_delay STATE_DATAOUT\n"); + bus->change_state_delay = 4; + bus->new_req_delay = 8; + } + else + { + bus->bus_out |= BUS_REQ; + } + } + break; + + case STATE_STATUS: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) + { + bus->bus_out &= ~BUS_REQ; +/* bus->clear_req = 3;*/ + bus->new_state = BUS_CD | BUS_IO | BUS_MSG; +// pclog("change_state_delay STATE_STATUS\n"); + bus->change_state_delay = 4; + bus->new_req_delay = 8; +/* bus->state = STATE_MESSAGEIN;*/ + } + break; + + case STATE_MESSAGEIN: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) + { +// pclog("Scheduling change to idle\n"); + bus->bus_out &= ~BUS_REQ; + bus->new_state = BUS_IDLE; +// pclog("change_state_delay STATE_MESSAGEIN\n"); + bus->change_state_delay = 4; +/* bus->bus_out &= ~BUS_BSY; + SET_BUS_STATE(bus, BUS_CD | BUS_IO); + bus->state = STATE_IDLE;*/ + } + break; + } + bus->bus_in = bus_assert; + + return bus->bus_out | bus->bus_in; +} + +int scsi_bus_read(scsi_bus_t *bus) +{ + scsi_device_t *dev = NULL; + void *dev_data = NULL; + + if (bus->dev_id != -1) + { + dev = bus->devices[bus->dev_id]; + dev_data = bus->device_data[bus->dev_id]; + } + +// pclog("scsi_hd_bus_read: bus_out=%02x bus_in=%02x %i %i %i\n", bus->bus_out, bus->bus_in, bus->clear_req, bus->change_state_delay, bus->new_req_delay); + + if (bus->clear_req) + { + bus->clear_req--; + if (!bus->clear_req) + { + SET_BUS_STATE(bus, bus->new_state); +// pclog("clear_req\n"); + bus->bus_out |= BUS_REQ; + } + } + + if (bus->change_state_delay) + { + bus->change_state_delay--; + if (!bus->change_state_delay) + { + uint8_t val; + +// pclog("change_state_delay %08x\n", bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG | BUS_IDLE)); + SET_BUS_STATE(bus, bus->new_state); + + switch (bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG)) + { + case BUS_IO: + bus->state = STATE_DATAIN; + val = dev->read(dev_data); + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP; + break; + + case 0: + if (bus->new_state & BUS_IDLE) + { + bus->state = STATE_IDLE; + bus->bus_out &= ~BUS_BSY; + } + else + bus->state = STATE_DATAOUT; + break; + + case (BUS_IO | BUS_CD): + bus->state = STATE_STATUS; + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(dev->get_status(dev_data)) | BUS_DBP; + break; + + case (BUS_CD | BUS_IO | BUS_MSG): + bus->state = STATE_MESSAGEIN; + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; + break; + + default: + fatal("change_state_delay bad state %x\n", bus->bus_out); + } + + } + } + if (bus->new_req_delay) + { + bus->new_req_delay--; + if (!bus->new_req_delay) + { +// pclog("new_req_delay\n"); + bus->bus_out |= BUS_REQ; + } + } + +// pclog(" bus_out now %02x\n", bus->bus_out); + return bus->bus_out;// | bus->bus_in; +} + +int scsi_bus_match(scsi_bus_t *bus, int bus_assert) +{ +// pclog("bus_match %02x %02x\n", bus_assert & (BUS_CD | BUS_IO | BUS_MSG), bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG)); + + return (bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) == (bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG)); +} + +void scsi_bus_kick(scsi_bus_t *bus) +{ +// pclog("scsi_bus_kick\n"); + scsi_bus_update(bus, 0); +} + +void scsi_bus_init(scsi_bus_t *bus) +{ + int c; + + memset(bus->devices, 0, sizeof(bus->devices)); + memset(bus->device_data, 0, sizeof(bus->device_data)); + + for (c = 0; c < 4; c++) + { + if (cdrom_channel != c) + { + bus->devices[c] = &scsi_hd; + bus->device_data[c] = bus->devices[c]->init(bus, c); + if (!bus->device_data[c]) + bus->devices[c] = NULL; + } + } +} + +void scsi_bus_close(scsi_bus_t *bus) +{ + int c; + + memset(bus->devices, 0, sizeof(bus->devices)); + memset(bus->device_data, 0, sizeof(bus->device_data)); + + for (c = 0; c < 8; c++) + { + if (bus->device_data[c]) + bus->devices[c]->close(bus->device_data[c]); + } +} diff --git a/src/scsi.h b/src/scsi.h new file mode 100644 index 0000000..4c2bdab --- /dev/null +++ b/src/scsi.h @@ -0,0 +1,103 @@ +struct scsi_bus_t; + +typedef struct scsi_device_t +{ + void *(*init)(struct scsi_bus_t *bus, int id); + void (*close)(void *p); + + void (*start_command)(void *p); + int (*command)(uint8_t *cdb, void *p); + + uint8_t (*get_status)(void *p); + + uint8_t (*read)(void *p); + void (*write)(uint8_t val, void *p); + int (*read_complete)(void *p); + int (*write_complete)(void *p); +} scsi_device_t; + +typedef struct scsi_bus_t +{ + int state; + int new_state; + int clear_req; + uint32_t bus_in, bus_out; + int dev_id; + + int command_pos; + uint8_t command[20]; + + scsi_device_t *devices[8]; + void *device_data[8]; + + int change_state_delay; + int new_req_delay; +} scsi_bus_t; + +//int scsi_add_data(uint8_t val); +//int scsi_get_data(); +void scsi_set_phase(uint8_t phase); +void scsi_set_irq(uint8_t status); + +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REZERO_UNIT 0x01 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_FORMAT 0x04 +#define SCSI_READ_6 0x08 +#define SCSI_WRITE_6 0x0a +#define SCSI_SEEK_6 0x0b +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT_6 0x15 +#define SCSI_MODE_SENSE_6 0x1a +#define SCSI_START_STOP_UNIT 0x1b +#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e +#define SCSI_READ_CAPACITY_10 0x25 +#define SCSI_READ_10 0x28 +#define SCSI_WRITE_10 0x2a +#define SCSI_SEEK_10 0x2b +#define SCSI_VERIFY_10 0x2f +#define SCSI_READ_BUFFER 0x3c + +#define SCSI_RESERVE 0x16 +#define SCSI_RELEASE 0x17 +#define SEND_DIAGNOSTIC 0x1d + +#define STATUS_GOOD 0x00 +#define STATUS_CHECK_CONDITION 0x02 + +#define MSG_COMMAND_COMPLETE 0x00 + +#define BUS_DBP 0x01 +#define BUS_SEL 0x02 +#define BUS_IO 0x04 +#define BUS_CD 0x08 +#define BUS_MSG 0x10 +#define BUS_REQ 0x20 +#define BUS_BSY 0x40 +#define BUS_RST 0x80 +#define BUS_ACK 0x200 +#define BUS_ATN 0x200 +#define BUS_ARB 0x8000 +#define BUS_SETDATA(val) ((uint32_t)val << 16) +#define BUS_GETDATA(val) ((val >> 16) & 0xff) +#define BUS_DATAMASK 0xff0000 + +#define BUS_IDLE (1 << 31) + +int scsi_bus_update(scsi_bus_t *bus, int bus_assert); +int scsi_bus_read(scsi_bus_t *bus); +int scsi_bus_match(scsi_bus_t *bus, int bus_assert); +void scsi_bus_kick(scsi_bus_t *bus); +void scsi_bus_init(scsi_bus_t *bus); +void scsi_bus_close(scsi_bus_t *bus); + +#define KEY_ILLEGAL_REQ 5 + +#define ASC_INVALID_LUN 0x25 + +#define SCSI_PHASE_DATA_OUT 0 +#define SCSI_PHASE_DATA_IN BUS_IO +#define SCSI_PHASE_COMMAND BUS_CD +#define SCSI_PHASE_STATUS (BUS_CD | BUS_IO) +#define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD) +#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO) diff --git a/src/scsi_53c400.c b/src/scsi_53c400.c new file mode 100644 index 0000000..ad90245 --- /dev/null +++ b/src/scsi_53c400.c @@ -0,0 +1,826 @@ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "scsi.h" +#include "scsi_53c400.h" +#include "timer.h" + +#define POLL_TIME_US 10 +#define MAX_BYTES_TRANSFERRED_PER_POLL 50 +/*10us poll period with 50 bytes transferred per poll = 5MB/sec*/ + +typedef struct ncr5380_t +{ + uint8_t output_data; + uint8_t icr; + uint8_t mode; + uint8_t tcr; + uint8_t ser; + uint8_t isr; + + int target_id; + int target_bsy; + int target_req; + + uint8_t bus_status; + + int dma_mode; + + void (*dma_changed)(struct ncr5380_t *ncr, int mode, int enable); + void *p; + + scsi_bus_t bus; +} ncr5380_t; + +typedef struct lcs6821n_t +{ + rom_t bios_rom; + + mem_mapping_t mapping; + + uint8_t block_count; + int block_count_loaded; + + uint8_t status_ctrl; + + uint8_t buffer[0x80]; + int buffer_pos; + int buffer_host_pos; + + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; + + ncr5380_t ncr; + + int ncr5380_dma_enabled; + + int dma_callback; + int dma_enabled; + + int ncr_busy; +} lcs6821n_t; + +#define ICR_DBP 0x01 +#define ICR_ATN 0x02 +#define ICR_SEL 0x04 +#define ICR_BSY 0x08 +#define ICR_ACK 0x10 +#define ICR_ARB_LOST 0x20 +#define ICR_ARB_IN_PROGRESS 0x40 + +#define MODE_ARBITRATE 0x01 +#define MODE_DMA 0x02 +#define MODE_MONITOR_BUSY 0x04 +#define MODE_ENA_EOP_INT 0x08 + +#define STATUS_ACK 0x01 +#define STATUS_BUSY_ERROR 0x04 +#define STATUS_INT 0x10 +#define STATUS_DRQ 0x40 +#define STATUS_END_OF_DMA 0x80 + +#define TCR_IO 0x01 +#define TCR_CD 0x02 +#define TCR_MSG 0x04 +#define TCR_REQ 0x08 +#define TCR_LAST_BYTE_SENT 0x80 + +enum +{ + DMA_IDLE = 0, + DMA_SEND, + DMA_TARGET_RECEIVE, + DMA_INITIATOR_RECEIVE +}; + +static void ncr53c400_dma_changed(ncr5380_t *ncr, int mode, int enable) +{ + lcs6821n_t *scsi = (lcs6821n_t *)ncr->p; + + scsi->ncr5380_dma_enabled = (mode && enable); + + scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded); +} + +void ncr5380_reset(ncr5380_t *ncr) +{ + memset(ncr, 0, sizeof(ncr)); +} + +static uint32_t get_bus_host(ncr5380_t *ncr) +{ + uint32_t bus_host = 0; + + if (ncr->icr & ICR_DBP) + bus_host |= BUS_DBP; + if (ncr->icr & ICR_SEL) + bus_host |= BUS_SEL; + if (ncr->icr & ICR_ATN) + bus_host |= BUS_ATN; + if (ncr->tcr & TCR_IO) + bus_host |= BUS_IO; + if (ncr->tcr & TCR_CD) + bus_host |= BUS_CD; + if (ncr->tcr & TCR_MSG) + bus_host |= BUS_MSG; + if (ncr->tcr & TCR_REQ) + bus_host |= BUS_REQ; + if (ncr->icr & ICR_BSY) + bus_host |= BUS_BSY; + if (ncr->icr & ICR_ACK) + bus_host |= BUS_ACK; + if (ncr->mode & MODE_ARBITRATE) + bus_host |= BUS_ARB; +// pclog("get_bus_host %02x %08x\n", ncr->output_data, BUS_SETDATA(ncr->output_data)); + return bus_host | BUS_SETDATA(ncr->output_data); +} + +void ncr5380_write(uint32_t addr, uint8_t val, void *p) +{ + ncr5380_t *ncr = (ncr5380_t *)p; + int bus_host = 0; + +// pclog("ncr5380_write: addr=%06x val=%02x %04x:%04x\n", addr, val, CS,cpu_state.pc); + switch (addr & 7) + { + case 0: /*Output data register*/ + ncr->output_data = val; + break; + + case 1: /*Initiator Command Register*/ + if ((val & (ICR_BSY | ICR_SEL)) == (ICR_BSY | ICR_SEL) && + (ncr->icr & (ICR_BSY | ICR_SEL)) == ICR_SEL) + { + uint8_t temp = ncr->output_data & 0x7f; + + ncr->target_id = -1; + while (temp) + { + temp >>= 1; + ncr->target_id++; + } +// pclog("Select - target ID = %i\n", ncr->target_id); + + if (!ncr->target_id) + ncr->target_bsy = 1; + } + + ncr->icr = val; + break; + + case 2: /*Mode register*/ + if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) + { + ncr->icr &= ~ICR_ARB_LOST; + ncr->icr |= ICR_ARB_IN_PROGRESS; + } + +// output = 1; + ncr->mode = val; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + if (!(ncr->mode & MODE_DMA)) + { + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + ncr->dma_mode = DMA_IDLE; + } + break; + + case 3: /*Target Command Register*/ + ncr->tcr = val; +/* switch (val & (TCR_MSG | TCR_CD | TCR_IO)) + { + case TCR_CD: + ncr->target_req = 1; + break; + }*/ + break; + case 4: /*Select Enable Register*/ + ncr->ser = val; + break; + + case 5: /*Start DMA Send*/ + ncr->dma_mode = DMA_SEND; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + break; + + case 7: /*Start DMA Initiator Receive*/ + ncr->dma_mode = DMA_INITIATOR_RECEIVE; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + break; + + default: + pclog("Bad NCR5380 write %06x %02x\n", addr, val); + } + + bus_host = get_bus_host(ncr); + + scsi_bus_update(&ncr->bus, bus_host); +} + +uint8_t ncr5380_read(uint32_t addr, void *p) +{ + ncr5380_t *ncr = (ncr5380_t *)p; + uint32_t bus = 0; + uint8_t temp = 0xff; + + switch (addr & 7) + { + case 0: /*Current SCSI Data*/ + //output = 3; + //fatal("Here\n"); + if (ncr->icr & ICR_DBP) + temp = ncr->output_data; + else + { + bus = scsi_bus_read(&ncr->bus); + temp = BUS_GETDATA(bus); + } + break; + case 1: /*Initiator Command Register*/ + temp = ncr->icr; + break; + case 2: /*Mode Register*/ + temp = ncr->mode; + break; + case 3: /*Target Command Register*/ + temp = ncr->tcr; + break; + + case 4: /*Current SCSI Bus Status*/ + temp = 0;//get_bus_host(ncr); + bus = scsi_bus_read(&ncr->bus); +// pclog(" SCSI bus status = %02x %02x\n", temp, bus); + temp |= (bus & 0xff); +// pclog(" SCSI bus status = %02x\n", temp); + break; + + case 5: /*Bus and Status Register*/ + temp = 0; + + bus = get_bus_host(ncr); + if (scsi_bus_match(&ncr->bus, bus)) + temp |= 8; + bus = scsi_bus_read(&ncr->bus); + + if (bus & BUS_ACK) + temp |= STATUS_ACK; + if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) + temp |= STATUS_DRQ; + if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) + { + int bus_state = 0; + if (bus & BUS_IO) + bus_state |= TCR_IO; + if (bus & BUS_CD) + bus_state |= TCR_CD; + if (bus & BUS_MSG) + bus_state |= TCR_MSG; + if ((ncr->tcr & 7) != bus_state) + ncr->isr |= STATUS_INT; + } + if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) + temp |= STATUS_BUSY_ERROR; + temp |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); + +// pclog(" bus and status register = %02x\n", temp); + break; + + case 7: /*Reset Parity/Interrupt*/ + ncr->isr &= ~STATUS_INT; + break; + + default: + pclog("Bad NCR5380 read %06x\n", addr); + } +// pclog("ncr5380_read: addr=%06x temp=%02x pc=%04x:%04x\n", addr, temp, CS,cpu_state.pc); + return temp; +} + +#define CTRL_DATA_DIR (1 << 6) + +#define STATUS_BUFFER_NOT_READY (1 << 2) +#define STATUS_53C80_ACCESSIBLE (1 << 7) + +static uint8_t lcs6821n_read(uint32_t addr, void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + uint8_t temp = 0xff; +//if (addr >= 0xca000) + addr &= 0x3fff; +// pclog("lcs6821n_read %08x\n", addr); + if (addr < 0x2000) + temp = scsi->bios_rom.rom[addr & 0x1fff]; + else if (addr < 0x3800) + temp = 0xff; + else if (addr >= 0x3a00) + temp = scsi->ext_ram[addr - 0x3a00]; + else switch (addr & 0x3f80) + { + case 0x3800: +// pclog("Read intRAM %02x %02x\n", addr & 0x3f, scsi->int_ram[addr & 0x3f]); + temp = scsi->int_ram[addr & 0x3f]; + break; + + case 0x3880: +// pclog("Read 53c80 %04x\n", addr); + temp = ncr5380_read(addr, &scsi->ncr); + break; + + case 0x3900: +//pclog(" Read 3900 %i %02x\n", scsi->buffer_host_pos, scsi->status_ctrl); + if (scsi->buffer_host_pos >= 128 || !(scsi->status_ctrl & CTRL_DATA_DIR)) + temp = 0xff; + else + { + temp = scsi->buffer[scsi->buffer_host_pos++]; + + if (scsi->buffer_host_pos == 128) + scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + } + break; + + case 0x3980: + switch (addr) + { + case 0x3980: /*Status*/ + temp = scsi->status_ctrl;// | 0x80; + if (!scsi->ncr_busy) + temp |= STATUS_53C80_ACCESSIBLE; + break; + case 0x3981: /*Block counter register*/ + temp = scsi->block_count; + break; + case 0x3982: /*Switch register read*/ +// temp = 7 | (7 << 3); + temp = 0xff; + break; + case 0x3983: + temp = 0xff; + break; + } + break; + } + +// if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc); + + return temp; +} + +static void lcs6821n_write(uint32_t addr, uint8_t val, void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + + addr &= 0x3fff; + +// /*if (addr >= 0x3880) */pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl); + + if (addr >= 0x3a00) + scsi->ext_ram[addr - 0x3a00] = val; + else switch (addr & 0x3f80) + { + case 0x3800: +// pclog("Write intram %02x %02x\n", addr & 0x3f, val); + scsi->int_ram[addr & 0x3f] = val; + break; + + case 0x3880: +// pclog("Write 53c80 %04x %02x\n", addr, val); + ncr5380_write(addr, val, &scsi->ncr); + break; + + case 0x3900: + if (!(scsi->status_ctrl & CTRL_DATA_DIR) && scsi->buffer_host_pos < 128) + { +// pclog(" Write %i %02x\n", scsi->buffer_host_pos, val); + scsi->buffer[scsi->buffer_host_pos++] = val; + if (scsi->buffer_host_pos == 128) + { + scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + scsi->ncr_busy = 1; + } + } + break; + + case 0x3980: + switch (addr) + { + case 0x3980: /*Control*/ + if ((val & CTRL_DATA_DIR) && !(scsi->status_ctrl & CTRL_DATA_DIR)) + { + scsi->buffer_host_pos = 128; + scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + } + else if (!(val & CTRL_DATA_DIR) && (scsi->status_ctrl & CTRL_DATA_DIR)) + { + scsi->buffer_host_pos = 0; + scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + scsi->status_ctrl = (scsi->status_ctrl & 0x87) | (val & 0x78); + break; + case 0x3981: /*Block counter register*/ + scsi->block_count = val; + scsi->block_count_loaded = 1; + scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded); + if (scsi->status_ctrl & CTRL_DATA_DIR) + { + scsi->buffer_host_pos = 128; + scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + } + else + { + scsi->buffer_host_pos = 0; + scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + } + break; + } + break; + } +} + +static uint8_t t130b_read(uint32_t addr, void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + uint8_t temp = 0xff; +//if (addr >= 0xca000) + addr &= 0x3fff; + + if (addr < 0x1800) + temp = scsi->bios_rom.rom[addr & 0x1fff]; + else if (addr < 0x1880) + temp = scsi->ext_ram[addr & 0x7f]; +// else +// pclog("Bad T130B read %04x\n", addr); + +// if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc); + + return temp; +} +static void t130b_write(uint32_t addr, uint8_t val, void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + + addr &= 0x3fff; + +// if (addr >= 0x3880) pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl); + + if (addr >= 0x1800 && addr < 0x1880) + scsi->ext_ram[addr & 0x7f] = val; +// else +// pclog("Bad T130B write %04x %02x\n", addr, val); +} + +static uint8_t t130b_in(uint16_t port, void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + uint8_t temp = 0xff; + + switch (port & 0xf) + { + case 0x0: case 0x1: case 0x2: case 0x3: + temp = lcs6821n_read((port & 7) | 0x3980, scsi); + break; + + case 0x4: case 0x5: + temp = lcs6821n_read(0x3900, scsi); + break; + + case 0x8: case 0x9: case 0xa: case 0xb: + case 0xc: case 0xd: case 0xe: case 0xf: + temp = ncr5380_read(port, &scsi->ncr); + break; + } + + if (CS != 0xdc00) + { + //pclog("t130b_in: port=%04x val=%02x %04x:%04x\n", port, temp, CS,cpu_state.pc); + //output = 3; + //fatal("Here\n"); + } + return temp; +} +static void t130b_out(uint16_t port, uint8_t val, void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + + //if (CS != 0xdc00) pclog("t130b_out: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + + switch (port & 0xf) + { + case 0x0: case 0x1: case 0x2: case 0x3: + lcs6821n_write((port & 7) | 0x3980, val, scsi); + break; + + case 0x4: case 0x5: + lcs6821n_write(0x3900, val, scsi); + break; + + case 0x8: case 0x9: case 0xa: case 0xb: + case 0xc: case 0xd: case 0xe: case 0xf: + ncr5380_write(port, val, &scsi->ncr); + break; + } +} + +static void ncr53c400_dma_callback(void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + ncr5380_t *ncr = &scsi->ncr; + int c; + int bytes_transferred = 0; + +//pclog("dma_Callback poll\n"); + scsi->dma_callback += POLL_TIME_US; + + switch (scsi->ncr.dma_mode) + { + case DMA_SEND: + if (scsi->status_ctrl & CTRL_DATA_DIR) + { + pclog("DMA_SEND with DMA direction set wrong\n"); + break; + } + +// if (!device_data[ncr->target_id]) +// fatal("DMA with no device\n"); + + if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) + { +// pclog(" !(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)\n"); + break; + } + + if (!scsi->block_count_loaded) + { +// pclog("!scsi->block_count_loaded\n"); + break; + } + + while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int bus; + uint8_t data; + + for (c = 0; c < 10; c++) + { + uint8_t status = scsi_bus_read(&ncr->bus); + + if (status & BUS_REQ) + break; + } + if (c == 10) + { +// pclog(" No req\n"); + break; + } + + /*Data ready*/ + data = scsi->buffer[scsi->buffer_pos]; + bus = get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(data); + + scsi_bus_update(&ncr->bus, bus | BUS_ACK); + scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); +// pclog(" Sent data %02x %i\n", data, scsi->buffer_pos); + + scsi->buffer_pos++; + bytes_transferred++; + + if (scsi->buffer_pos == 128) + { + scsi->buffer_pos = 0; + scsi->buffer_host_pos = 0; + scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + scsi->block_count = (scsi->block_count - 1) & 255; + scsi->ncr_busy = 0; +// pclog("Sent buffer %i\n", scsi->block_count); + if (!scsi->block_count) + { + scsi->block_count_loaded = 0; + scsi->dma_enabled = 0; +// scsi->buffer_host_pos = 128; +// scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + if (ncr->mode & MODE_ENA_EOP_INT) + ncr->isr |= STATUS_INT; + } + break; + } + } + break; + + case DMA_INITIATOR_RECEIVE: + if (!(scsi->status_ctrl & CTRL_DATA_DIR)) + { + pclog("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); + break; + } + + if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) + break; + + if (!scsi->block_count_loaded) + break; + + while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int bus; + uint8_t temp; + + for (c = 0; c < 10; c++) + { + uint8_t status = scsi_bus_read(&ncr->bus); + + if (status & BUS_REQ) + break; + } + if (c == 10) + break; + + /*Data ready*/ + bus = scsi_bus_read(&ncr->bus); + temp = BUS_GETDATA(bus); +// pclog(" Got data %02x %i\n", temp, scsi->buffer_pos); + + bus = get_bus_host(ncr); + + scsi_bus_update(&ncr->bus, bus | BUS_ACK); + scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); + + scsi->buffer[scsi->buffer_pos++] = temp; + bytes_transferred++; + + if (scsi->buffer_pos == 128) + { + scsi->buffer_pos = 0; + scsi->buffer_host_pos = 0; + scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + scsi->block_count = (scsi->block_count - 1) & 255; +// pclog("Got buffer %i\n", scsi->block_count); + if (!scsi->block_count) + { + scsi->block_count_loaded = 0; + scsi->dma_enabled = 0; + +// output=3; + ncr->isr |= STATUS_END_OF_DMA; + if (ncr->mode & MODE_ENA_EOP_INT) + ncr->isr |= STATUS_INT; + } + break; + } + } + break; + + default: + pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode); + break; + } + + { + int bus = scsi_bus_read(&ncr->bus); + + if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) + { + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + } + } +} + +static void *scsi_53c400_init(char *bios_fn) +{ + lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); + memset(scsi, 0, sizeof(lcs6821n_t)); + + scsi->ncr.dma_changed = ncr53c400_dma_changed; + scsi->ncr.p = scsi; + + rom_init(&scsi->bios_rom, bios_fn, 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&scsi->bios_rom.mapping); + + mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, + lcs6821n_read, NULL, NULL, + lcs6821n_write, NULL, NULL, + scsi->bios_rom.rom, 0, scsi); + + ncr5380_reset(&scsi->ncr); + + scsi->status_ctrl = STATUS_BUFFER_NOT_READY; + scsi->buffer_host_pos = 128; + + scsi_bus_init(&scsi->ncr.bus); + + timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi); + + return scsi; +} + +static void *scsi_lcs6821n_init() +{ + return scsi_53c400_init("Longshine LCS-6821N - BIOS version 1.04.bin"); +} +static void *scsi_rt1000b_init() +{ + return scsi_53c400_init("Rancho_RT1000_RTBios_version_8.10R.bin"); +} + +static void *scsi_t130b_init(char *bios_fn) +{ + lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); + memset(scsi, 0, sizeof(lcs6821n_t)); + + scsi->ncr.dma_changed = ncr53c400_dma_changed; + scsi->ncr.p = scsi; + + rom_init(&scsi->bios_rom, "trantor_t130b_bios_v2.14.bin", 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, + t130b_read, NULL, NULL, + t130b_write, NULL, NULL, + scsi->bios_rom.rom, 0, scsi); + io_sethandler(0x0350, 0x0010, + t130b_in, NULL, NULL, + t130b_out, NULL, NULL, + scsi); + + ncr5380_reset(&scsi->ncr); + + scsi->status_ctrl = STATUS_BUFFER_NOT_READY; + scsi->buffer_host_pos = 128; + + scsi_bus_init(&scsi->ncr.bus); + + timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi); + + return scsi; +} + +static void scsi_53c400_close(void *p) +{ + lcs6821n_t *scsi = (lcs6821n_t *)p; + + scsi_bus_close(&scsi->ncr.bus); + + free(scsi); +} + +static int scsi_lcs6821n_available() +{ + return rom_present("Longshine LCS-6821N - BIOS version 1.04.bin"); +} + +static int scsi_rt1000b_available() +{ + return rom_present("Rancho_RT1000_RTBios_version_8.10R.bin"); +} + +static int scsi_t130b_available() +{ + return rom_present("trantor_t130b_bios_v2.14.bin"); +} + +device_t scsi_lcs6821n_device = +{ + "Longshine LCS-6821N (SCSI)", + 0, + scsi_lcs6821n_init, + scsi_53c400_close, + scsi_lcs6821n_available, + NULL, + NULL, + NULL, + NULL +}; + +device_t scsi_rt1000b_device = +{ + "Ranco RT1000B (SCSI)", + 0, + scsi_rt1000b_init, + scsi_53c400_close, + scsi_rt1000b_available, + NULL, + NULL, + NULL, + NULL +}; + +device_t scsi_t130b_device = +{ + "Trantor T130B (SCSI)", + 0, + scsi_t130b_init, + scsi_53c400_close, + scsi_t130b_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/scsi_53c400.h b/src/scsi_53c400.h new file mode 100644 index 0000000..d1dc52d --- /dev/null +++ b/src/scsi_53c400.h @@ -0,0 +1,3 @@ +extern device_t scsi_lcs6821n_device; +extern device_t scsi_rt1000b_device; +extern device_t scsi_t130b_device; diff --git a/src/scsi_hd.c b/src/scsi_hd.c new file mode 100644 index 0000000..c03d87a --- /dev/null +++ b/src/scsi_hd.c @@ -0,0 +1,806 @@ +#include +#include +#include +#include +#include "ibm.h" +#include "hdd_file.h" +#include "scsi.h" +#include "scsi_hd.h" +#include "timer.h" + +extern char ide_fn[4][512]; + +#define BUFFER_SIZE (256*1024) + +#define RW_DELAY (TIMER_USEC * 500) + +enum +{ + CMD_POS_IDLE = 0, + CMD_POS_WAIT, + CMD_POS_START_SECTOR, + CMD_POS_TRANSFER +}; + +typedef struct scsi_hd_data +{ + int blocks; + + int cmd_pos, new_cmd_pos; + + int addr, len; + int sector_pos; + + uint8_t buf[512]; + + uint8_t status; + + uint8_t data_in[BUFFER_SIZE]; + uint8_t data_out[BUFFER_SIZE]; + int data_pos_read, data_pos_write; + + int bytes_received, bytes_required; + + hdd_file_t hdd; + + int sense_key, asc, ascq; + + int hd_id; + + int callback; + + scsi_bus_t *bus; +} scsi_hd_data; + +static void scsi_hd_callback(void *p) +{ + scsi_hd_data *data = p; + + data->callback = 0; + + if (data->cmd_pos == CMD_POS_WAIT) + { + data->cmd_pos = data->new_cmd_pos; + scsi_bus_kick(data->bus); + } +} + +static void *scsi_hd_init(scsi_bus_t *bus, int id) +{ + scsi_hd_data *data = malloc(sizeof(scsi_hd_data)); + memset(data, 0, sizeof(scsi_hd_data)); + + hdd_load(&data->hdd, id, ide_fn[id]); + + if (!data->hdd.f) + { + free(data); + return NULL; + } + + data->hd_id = id; + data->bus = bus; + timer_add(scsi_hd_callback, &data->callback, &data->callback, data); + + return data; +} + +static void scsi_hd_close(void *p) +{ + scsi_hd_data *data = p; + + hdd_close(&data->hdd); + free(data); +} + +static int scsi_add_data(uint8_t val, void *p) +{ + scsi_hd_data *data = p; + +// pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); + + data->data_in[data->data_pos_write++] = val; + +// if (data->bus_out & BUS_REQ) +// return -1; + +// data->bus_out = (data->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; + + return 0; +} + +static int scsi_get_data(void *p) +{ + scsi_hd_data *data = p; + uint8_t val = data->data_out[data->data_pos_read++]; + + if (data->data_pos_read > BUFFER_SIZE) + fatal("scsi_get_data beyond buffer limits\n"); + + return val; +} + +static void scsi_hd_illegal(scsi_hd_data *data) +{ + data->status = STATUS_CHECK_CONDITION; + data->sense_key = KEY_ILLEGAL_REQ; + data->asc = ASC_INVALID_LUN; + data->ascq = 0; +} + +#define add_data_len(v) \ + if (i < len) \ + scsi_add_data(v, data); \ + i++; + + +static int scsi_hd_command(uint8_t *cdb, void *p) +{ + scsi_hd_data *data = p; + int /*addr, */len; + int i = 0; + int desc; + int bus_state = 0; + +// if (data->cmd_pos == CMD_POS_IDLE) +// pclog("SCSI HD command %02x\n", cdb[0]); + data->status = STATUS_GOOD; + data->data_pos_read = data->data_pos_write = 0; + + if ((cdb[0] != SCSI_REQUEST_SENSE/* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) + { +// pclog("non-zero LUN\n"); + /*Non-zero LUN - abort command*/ + scsi_hd_illegal(data); + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + + switch (cdb[0]) + { + case SCSI_TEST_UNIT_READY: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_REZERO_UNIT: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_REQUEST_SENSE: + desc = cdb[1] & 1; + len = cdb[4]; + + if (!desc) + { + add_data_len(0x70); + add_data_len(0); + add_data_len(data->sense_key); /*Sense key*/ + add_data_len(0); /*Information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Additional sense length*/ + add_data_len(0); /*Command specific information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); /*FRU code*/ + add_data_len(0); /*Sense key specific (3 bytes)*/ + add_data_len(0); + add_data_len(0); + } + else + { + add_data_len(0x72); + add_data_len(data->sense_key); /*Sense Key*/ + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*additional sense length*/ + } + + data->sense_key = data->asc = data->ascq = 0; + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + + case SCSI_INQUIRY: + len = cdb[4] | (cdb[3] << 8); +// pclog("INQUIRY %d %02x %02x %02x %02x %02x %02x %i\n", len, cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5], data->hd_id); + + if (cdb[1] & 0xe0) + { + add_data_len(0 | (3 << 5)); /*No physical device on this LUN*/ + } + else + { + add_data_len(0 | (0 << 5)); /*Hard disc*/ + } + add_data_len(0); /*Not removeable*/ + add_data_len(0); /*No version*/ + add_data_len(2); /*Response data*/ + add_data_len(0); /*Additional length*/ + add_data_len(0); + add_data_len(0); + add_data_len(2); + + add_data_len('P'); + add_data_len('C'); + add_data_len('e'); + add_data_len('m'); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + + add_data_len('S'); + add_data_len('C'); + add_data_len('S'); + add_data_len('I'); + add_data_len('_'); + add_data_len('H'); + add_data_len('D'); + add_data_len(' '); + + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + + add_data_len(0); /*Product revision level*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Drive serial number*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Vendor unique*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Vendor descriptor*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Reserved*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_MODE_SENSE_6: + len = cdb[4]; + + add_data_len(0); + add_data_len(0); + + add_data_len(0x08); + add_data_len(0); + + add_data_len((data->hdd.sectors >> 24) & 0xff); + add_data_len((data->hdd.sectors >> 16) & 0xff); + add_data_len((data->hdd.sectors >> 8) & 0xff); + add_data_len( data->hdd.sectors & 0xff); + add_data_len((512 >> 24) & 0xff); + add_data_len((512 >> 16) & 0xff); + add_data_len((512 >> 8) & 0xff); + add_data_len( 512 & 0xff); + + if ((cdb[2] & 0x3f) == 0x03 || (cdb[2] & 0x3f) == 0x3f) + { + add_data_len(3); + add_data_len(0x16); + add_data_len(0); add_data_len(1); /*Tracks per zone*/ + add_data_len(0); add_data_len(1); /*Alternate sectors per zone*/ + add_data_len(0); add_data_len(1); /*Alternate tracks per zone*/ + add_data_len(0); add_data_len(1); /*Alternate tracks per volume*/ + add_data_len(1); add_data_len(0); /*Sectors per track*/ + add_data_len(2); add_data_len(0); /*Data bytes per physical sector*/ + add_data_len(0); add_data_len(0); /*Interleave*/ + add_data_len(0); add_data_len(0); /*Track skew*/ + add_data_len(0); add_data_len(0); /*Cylinder skew*/ + add_data_len(0); /*Drive type*/ + add_data_len(0); add_data_len(0); add_data_len(0); + } + + if ((cdb[2] & 0x3f) == 0x04 || (cdb[2] & 0x3f) == 0x3f) + { + add_data_len(4); + add_data_len(0x16); + add_data_len(0); add_data_len(0x10); add_data_len(0); /*Cylinder count*/ + add_data_len(64); /*Heads*/ + add_data_len(0); add_data_len(0); add_data_len(0); /*Write recomp*/ + add_data_len(0); add_data_len(0); add_data_len(0); /*Reduced write current*/ + add_data_len(0); add_data_len(0); /*Drive step rate*/ + add_data_len(0); add_data_len(0); add_data_len(0); /*Landing zone cylinder*/ + add_data_len(0); /*RPL*/ + add_data_len(0); /*Rotational offset*/ + add_data_len(0); + add_data_len(0x10); add_data_len(0); /*Rotain rate*/ + add_data_len(0); add_data_len(0); + } + + if ((cdb[2] & 0x3f) == 0x30 || (cdb[2] & 0x3f) == 0x3f) + { + add_data_len(0xb0); + add_data_len(0x16); + add_data_len('P'); + add_data_len('C'); + add_data_len('E'); + add_data_len('M'); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + } + + for (; len >= 0; len--) + add_data_len(0); + +// scsi_illegal_field(); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_CAPACITY_10: + scsi_add_data((data->hdd.sectors >> 24) & 0xff, data); + scsi_add_data((data->hdd.sectors >> 16) & 0xff, data); + scsi_add_data((data->hdd.sectors >> 8) & 0xff, data); + scsi_add_data( data->hdd.sectors & 0xff, data); + scsi_add_data((512 >> 24) & 0xff, data); + scsi_add_data((512 >> 16) & 0xff, data); + scsi_add_data((512 >> 8) & 0xff, data); + scsi_add_data( 512 & 0xff, data); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_6: +// pclog("SCSI_READ_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + + if (data->cmd_pos == CMD_POS_IDLE) + { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; +// pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } +// else +// pclog("SCSI_READ_6 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); + while (data->len) + { + if (data->cmd_pos == CMD_POS_START_SECTOR) + { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_add_data(data->buf[data->sector_pos], data); + + if (ret == -1) + { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) + { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_10: +// pclog("SCSI_READ_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + + if (data->cmd_pos == CMD_POS_IDLE) + { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); +// pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } +// else +// pclog("SCSI_READ_10 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); + while (data->len) + { + if (data->cmd_pos == CMD_POS_START_SECTOR) + { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_add_data(data->buf[data->sector_pos], data); +// pclog("SCSI_READ_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) + { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) + { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_WRITE_6: +// pclog("SCSI_WRITE_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) + { + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + readflash_set(READFLASH_HDC, data->hd_id); +// pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) + { + bus_state = 0; + break; + } + + while (data->len) + { + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_get_data(data); + if (ret == -1) + { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) + { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } + + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_WRITE_10: +// pclog("SCSI_WRITE_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) + { + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + readflash_set(READFLASH_HDC, data->hd_id); +// pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) + { + bus_state = 0; + break; + } + + while (data->len) + { + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_get_data(data); +// pclog("SCSI_WRITE_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) + { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) + { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } + + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; +// output = 3; + break; + + case SCSI_VERIFY_10: + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_MODE_SELECT_6: + if (!data->bytes_received) + { + data->bytes_required = cdb[4]; +// pclog("SCSI_MODE_SELECT_6 bytes_required=%i\n", data->bytes_required); + bus_state = 0; + break; + } +// pclog("SCSI_MODE_SELECT_6 complete\n"); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_FORMAT: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_START_STOP_UNIT: + bus_state = BUS_CD | BUS_IO; + break; + + /*These aren't really meaningful in a single initiator system, so just return*/ + case SCSI_RESERVE: + case SCSI_RELEASE: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_SEEK_6: + case SCSI_SEEK_10: + bus_state = BUS_CD | BUS_IO; + break; + + case SEND_DIAGNOSTIC: + if (cdb[1] & (1 << 2)) + { + /*Self-test*/ + /*Always passes*/ + bus_state = BUS_CD | BUS_IO; + } + else + { + /*Treat all other diagnostic requests as illegal*/ + scsi_hd_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; + + default: + pclog("Bad SCSI HD command %02x\n", cdb[0]); + scsi_hd_illegal(data); + bus_state = BUS_CD | BUS_IO; + break; + } + + return bus_state; +} + +static uint8_t scsi_hd_read(void *p) +{ + scsi_hd_data *data = p; + + return data->data_in[data->data_pos_read++]; +} + +static void scsi_hd_write(uint8_t val, void *p) +{ + scsi_hd_data *data = p; + + data->data_out[data->data_pos_write++] = val; + + data->bytes_received++; + + if (data->data_pos_write > BUFFER_SIZE) + fatal("Exceeded data_out buffer size\n"); +} + +static int scsi_hd_read_complete(void *p) +{ + scsi_hd_data *data = p; + + return (data->data_pos_read == data->data_pos_write); +} +static int scsi_hd_write_complete(void *p) +{ + scsi_hd_data *data = p; + + return (data->bytes_received == data->bytes_required); +} + +static void scsi_hd_start_command(void *p) +{ + scsi_hd_data *data = p; + + data->bytes_received = 0; + data->bytes_required = 0; + data->data_pos_read = data->data_pos_write = 0; +} + +static uint8_t scsi_hd_get_status(void *p) +{ + scsi_hd_data *data = p; + + return data->status; +} + +scsi_device_t scsi_hd = +{ + scsi_hd_init, + scsi_hd_close, + + scsi_hd_start_command, + scsi_hd_command, + + scsi_hd_get_status, + + scsi_hd_read, + scsi_hd_write, + scsi_hd_read_complete, + scsi_hd_write_complete, +}; diff --git a/src/scsi_hd.h b/src/scsi_hd.h new file mode 100644 index 0000000..9f0bdf5 --- /dev/null +++ b/src/scsi_hd.h @@ -0,0 +1 @@ +extern scsi_device_t scsi_hd; From 2c2e325f60eaabb0dd5585a79fbac5843699df1b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Oct 2017 16:26:12 +0100 Subject: [PATCH 0153/1050] Added emulation of Adaptec AHA-1542C and BusLogic BT-545S SCSI adapters. --- nvr/aha1542c.nvr | Bin 0 -> 32 bytes src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/hdd.c | 3 + src/mem.c | 44 +- src/mem.h | 4 + src/scsi_aha1540.c | 2537 ++++++++++++++++++++++++++++ src/scsi_aha1540.h | 2 + 17 files changed, 2600 insertions(+), 12 deletions(-) create mode 100644 nvr/aha1542c.nvr create mode 100644 src/scsi_aha1540.c create mode 100644 src/scsi_aha1540.h diff --git a/nvr/aha1542c.nvr b/nvr/aha1542c.nvr new file mode 100644 index 0000000000000000000000000000000000000000..f62cc4bdef8aada151abd16edab1a7f24689a685 GIT binary patch literal 32 RcmZQC+{S> 14] && !(addr & 1)) + return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); + + return mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); +} +uint32_t mem_readl_phys(uint32_t addr) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_read_l[addr >> 14] && !(addr & 3)) + return _mem_read_l[addr >> 14](addr, _mem_priv_r[addr >> 14]); + + return mem_readw_phys(addr) | (mem_readw_phys(addr + 2) << 16); +} void mem_writeb_phys(uint32_t addr, uint8_t val) { mem_logical_addr = 0xffffffff; - + if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); } +void mem_writew_phys(uint32_t addr, uint16_t val) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_write_w[addr >> 14] && !(addr & 1)) + _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + else + { + mem_writeb_phys(addr, val); + mem_writeb_phys(addr+1, val >> 8); + } +} +void mem_writel_phys(uint32_t addr, uint32_t val) +{ + mem_logical_addr = 0xffffffff; + + if (_mem_write_l[addr >> 14] && !(addr & 3)) + _mem_write_l[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + else + { + mem_writew_phys(addr, val); + mem_writew_phys(addr+2, val >> 16); + } +} uint8_t mem_read_ram(uint32_t addr, void *priv) { diff --git a/src/mem.h b/src/mem.h index fc4c574..618e8dc 100644 --- a/src/mem.h +++ b/src/mem.h @@ -79,7 +79,11 @@ 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); +uint32_t mem_readl_phys(uint32_t addr); void mem_writeb_phys(uint32_t addr, uint8_t val); +void mem_writew_phys(uint32_t addr, uint16_t val); +void mem_writel_phys(uint32_t addr, uint32_t val); uint8_t mem_read_ram(uint32_t addr, void *priv); uint16_t mem_read_ramw(uint32_t addr, void *priv); diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c new file mode 100644 index 0000000..43720a6 --- /dev/null +++ b/src/scsi_aha1540.c @@ -0,0 +1,2537 @@ +/*AH1542C firmware notes : + + d1a - command dispatch + 193c - send data + 1954 - get data + + FW data - 164e + + BIOS command table - f4b*/ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "nvr.h" +#include "pic.h" +#include "rom.h" +#include "scsi.h" +#include "scsi_aha1540.h" +#include "timer.h" + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +int primed = 0; +typedef enum +{ + SCSI_AHA1542C, + SCSI_BT545S +} scsi_type_t; + +/*Firmware emulation is implemented via three state machines : + + - Command state - foreground command processing + - CCB state - CCB/mailbox processing - triggered by commands 0x02/0x82 + - SCSI state - SCSI bus handling / data transfer*/ +typedef enum +{ + CMD_STATE_RESET, + CMD_STATE_IDLE, + CMD_STATE_GET_PARAMS, + CMD_STATE_CMD_IN_PROGRESS, + CMD_STATE_SEND_RESULT +} cmd_state_t; + +typedef enum +{ + CCB_STATE_IDLE, + CCB_STATE_SEND_COMMAND, + CCB_STATE_WAIT_COMMAND, + CCB_STATE_SEND_REQUEST_SENSE, + CCB_STATE_WAIT_REQUEST_SENSE +} ccb_state_t; + +typedef enum +{ + SCSI_STATE_IDLE, + SCSI_STATE_SELECT, + SCSI_STATE_SELECT_FAILED, + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_NEXT_PHASE, + SCSI_STATE_END_PHASE, + SCSI_STATE_READ_DATA, + SCSI_STATE_WRITE_DATA, + SCSI_STATE_READ_STATUS, + SCSI_STATE_READ_MESSAGE +} scsi_state_t; + +typedef enum +{ + MB_FORMAT_4, + MB_FORMAT_8 +} mb_format_t; + +typedef struct aha154x_t +{ + rom_t bios_rom; + mem_mapping_t mapping; + uint32_t bios_addr; + + uint8_t shadow_ram[0x4000]; + uint8_t shadow; + + uint32_t bios_bank; + + uint8_t eeprom[256]; + char fn[256]; + + scsi_type_t type; + + scsi_bus_t bus; + + uint8_t isr; + uint8_t isr_pending; + uint8_t status; + + uint8_t cmd_data; + uint8_t data_in; + + uint8_t command; + int command_len; + int cur_param; + uint8_t params[64]; + + int result_pos, result_len; + uint8_t result[256]; + + uint8_t dma_buffer[64]; + + uint8_t bon, boff; + uint8_t atbs; + + int mbc; + uint32_t mba; + uint32_t mba_i; + int mbo_req; + mb_format_t mb_format; + + int bios_mbc; + uint32_t bios_mba; + int bios_mbo_req; + + cmd_state_t cmd_state; + ccb_state_t ccb_state; + scsi_state_t scsi_state; + + int bios_cmd_state; + + int timer; + + int current_mbo; + int current_mbo_is_bios; + int current_mbi; + + uint8_t mblt, mbu; + + uint8_t int_buffer[512]; + + uint8_t e_d; + uint16_t to; + + uint8_t dipsw; + int irq, dma, host_id; + + struct + { + uint32_t addr; + + uint8_t opcode; + int target_id, transfer_dir, lun; + int scsi_cmd_len; + int req_sense_len; + uint32_t data_len; + uint32_t data_pointer; + uint32_t link_pointer; + uint8_t link_id; + + uint8_t cdb[256]; + + uint8_t status; + + int from_mailbox; + + uint32_t data_seg_list_pointer; + uint32_t data_seg_list_len; + uint32_t data_seg_list_idx; + + int residual; + + int bytes_transferred; + uint32_t total_data_len; + } ccb; + + struct + { + int idx, len; + uint8_t data[256]; + + int data_idx, data_len; + uint32_t data_pointer; + + uint8_t last_status; + + uint32_t data_seg_list_pointer; + uint32_t data_seg_list_len; + uint32_t data_seg_list_idx; + + int scatter_gather; + int bytes_transferred; + } cdb; +} aha154x_t; + +#define STATUS_INVDCMD 0x01 +#define STATUS_DF 0x04 +#define STATUS_CDF 0x08 +#define STATUS_IDLE 0x10 +#define STATUS_INIT 0x20 +#define STATUS_STST 0x80 + +#define CTRL_BRST 0x10 +#define CTRL_IRST 0x20 +#define CTRL_SRST 0x40 +#define CTRL_RESET 0x80 + +#define ISR_MBIF 0x01 +#define ISR_MBOA 0x02 +#define ISR_HACC 0x04 +#define ISR_ANYINTR 0x80 + +#define COMMAND_NOP 0x00 +#define COMMAND_MAILBOX_INITIALIZATION 0x01 +#define COMMAND_START_SCSI_COMMAND 0x02 +#define COMMAND_START_BIOS_COMMAND 0x03 +#define COMMAND_ADAPTER_INQUIRY 0x04 +#define COMMAND_SET_SELECTION_TIMEOUT 0x06 +#define COMMAND_SET_BUS_ON_TIME 0x07 +#define COMMAND_SET_BUS_OFF_TIME 0x08 +#define COMMAND_SET_AT_BUS_SPEED 0x09 +#define COMMAND_RETURN_CONFIG_DATA 0x0b +#define COMMAND_RETURN_SETUP_DATA 0x0d +#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a +#define COMMAND_READ_CHANNEL_2_BUF 0x1b +#define COMMAND_ECHO 0x1f + +#define COMMAND_ADAPTEC_PROGRAM_EEPROM 0x22 +#define COMMAND_ADAPTEC_RETURN_EEPROM_DATA 0x23 +#define COMMAND_ADAPTEC_SET_SHADOW_PARAMS 0x24 +#define COMMAND_ADAPTEC_BIOS_MAILBOX_INIT 0x25 +#define COMMAND_ADAPTEC_SET_BIOS_BANK_1 0x26 +#define COMMAND_ADAPTEC_SET_BIOS_BANK_2 0x27 +#define COMMAND_ADAPTEC_GET_EXT_BIOS_INFO 0x28 +#define COMMAND_ENABLE_MAILBOX_INTERFACE 0x29 +#define COMMAND_ADAPTEC_START_BIOS_SCSI_CMD 0x82 + +#define COMMAND_BUSLOGIC_22 0x22 +#define COMMAND_BUSLOGIC_81 0x81 +#define COMMAND_BUSLOGIC_84 0x84 +#define COMMAND_BUSLOGIC_85 0x85 +#define COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO 0x8d +#define COMMAND_BUSLOGIC_STRICT_RR 0x8f +#define COMMAND_BUSLOGIC_SET_CCB_FORMAT 0x96 + +#define COMMAND_FREE_CCB 0 +#define COMMAND_START_CCB 1 +#define COMMAND_ABORT_CCB 2 + +#define CCB_INITIATOR 0 +#define CCB_INITIATOR_SCATTER_GATHER 2 +#define CCB_INITIATOR_RESIDUAL 3 +#define CCB_INITIATOR_SCATTER_GATHER_RESIDUAL 4 + +#define CCB_SENSE_14 0x00 +#define CCB_SENSE_NONE 0x01 + +#define MBI_CCB_COMPLETE 0x01 +#define MBI_CCB_ABORTED 0x02 +#define MBI_CCB_COMPLETE_WITH_ERROR 0x04 + +#define HOST_STATUS_COMMAND_COMPLETE 0x00 +#define HOST_STATUS_SELECTION_TIME_OUT 0x11 + +#define POLL_TIME_US 10 +#define MAX_BYTES_TRANSFERRED_PER_POLL 50 +/*10us poll period with 50 bytes transferred per poll = 5MB/sec*/ + +static void aha1542c_eeprom_save(aha154x_t *scsi); +static void process_cmd(aha154x_t *scsi); + +static void set_irq(aha154x_t *scsi, uint8_t val) +{ +// pclog("set_irq %02x %02x\n", scsi->isr, val); + if (!scsi->isr) + picint(1 << scsi->irq); + scsi->isr |= val; +} + +static void clear_irq(aha154x_t *scsi) +{ + picintc(1 << scsi->irq); +} + +static void aha154x_out(uint16_t port, uint8_t val, void *p) +{ + aha154x_t *scsi = (aha154x_t *)p; + + if (CS != 0xc800) + { +// pclog("aha154x_out: port=%04x val=%02x %04x:%04x %i\n", port, val, CS, cpu_state.pc, scsi->cmd_state); + } + + switch (port & 3) + { + case 0: /*Control register*/ + if (val & CTRL_RESET) + { + scsi->isr = 0; + clear_irq(scsi); + scsi->status = STATUS_STST; + pclog("hardware reset\n"); + scsi->cmd_state = CMD_STATE_RESET; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->mb_format = MB_FORMAT_4; + scsi->current_mbi = 0; + } + if (val & CTRL_SRST) + { + scsi->isr = 0; + clear_irq(scsi); + if (scsi->type == SCSI_BT545S) + scsi->status = STATUS_INIT; + else + scsi->status = 0; +// pclog("software reset\n"); + scsi->cmd_state = CMD_STATE_IDLE; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->mb_format = MB_FORMAT_4; + scsi->current_mbi = 0; + } + if (val & CTRL_IRST) + { + scsi->isr = 0; + clear_irq(scsi); +// update_irq(scsi); + if (scsi->type == SCSI_AHA1542C) + scsi->status &= ~STATUS_INVDCMD; + } + if (val & CTRL_BRST) + { + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; +// output = 3; + } + break; + + case 1: /*Command/data register*/ + if (scsi->status & STATUS_CDF) + break; + if (scsi->type == SCSI_BT545S) + scsi->status &= ~STATUS_INVDCMD; +// fatal("Write command reg while full\n"); + scsi->status |= STATUS_CDF; + scsi->cmd_data = val; + pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc); + process_cmd(scsi); + break; + } +} + +static uint8_t aha154x_in(uint16_t port, void *p) +{ + aha154x_t *scsi = (aha154x_t *)p; + uint8_t temp = 0xff; + +// if (primed) +// output = 3; + switch (port & 3) + { + case 0: /*Status register*/ + temp = scsi->status; + if (scsi->cmd_state == CMD_STATE_IDLE && scsi->ccb_state == CCB_STATE_IDLE && scsi->scsi_state == SCSI_STATE_IDLE) + temp |= STATUS_IDLE; + break; + + case 1: /*Data in register*/ +/* if (!(scsi->status & STATUS_DF)) + fatal("Read data in while empty\n");*/ + scsi->status &= ~STATUS_DF; + temp = scsi->data_in; + break; + + case 2: /*Interrupt status register*/ + temp = scsi->isr & ~0x70; + if (scsi->isr) + temp |= ISR_ANYINTR; + break; + + case 3: /*???*/ + if (scsi->type == SCSI_BT545S) + temp = 0x29; /*BT-545S BIOS expects this to return not zero or 0xff for six consecutive reads*/ + else + temp = 0xff; + break; + } + if (CS != 0xc800) + { +// pclog("aha154x_in: port=%04x val=%02x %04x(%08x):%04x %i %i\n", port, temp, CS, cs, cpu_state.pc, ins, scsi->cmd_state); + } + + return temp; +} + +static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) +{ + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(bus); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) + { + if (!req_needed || (bus_state & BUS_REQ)) + return 1; + } + } + + return 0; +} + +static void process_cdb(aha154x_t *scsi) +{ + int c; + uint8_t temp; + + scsi->ccb.opcode = mem_readb_phys(scsi->ccb.addr); + switch (scsi->ccb.opcode) + { + case CCB_INITIATOR: + case CCB_INITIATOR_RESIDUAL: + temp = mem_readb_phys(scsi->ccb.addr + 0x01); +// pclog("Read addr+ctrl %02x %06x\n", temp, scsi->ccb.addr+0x01); + scsi->ccb.transfer_dir = (temp >> 3) & 3; + scsi->ccb.scsi_cmd_len = mem_readb_phys(scsi->ccb.addr + 0x02); + scsi->ccb.req_sense_len = mem_readb_phys(scsi->ccb.addr + 0x03); + + if (scsi->mb_format == MB_FORMAT_4) + { + scsi->ccb.lun = temp & 7; + scsi->ccb.target_id = (temp >> 5) & 7; + + scsi->ccb.data_len = mem_readb_phys(scsi->ccb.addr + 0x06) | (mem_readb_phys(scsi->ccb.addr + 0x05) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x04) << 16); + scsi->ccb.data_pointer = mem_readb_phys(scsi->ccb.addr + 0x09) | (mem_readb_phys(scsi->ccb.addr + 0x08) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x07) << 16); + scsi->ccb.link_pointer = mem_readb_phys(scsi->ccb.addr + 0x0c) | (mem_readb_phys(scsi->ccb.addr + 0x0b) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x0a) << 16); + scsi->ccb.link_id = mem_readb_phys(scsi->ccb.addr + 0x0d); + } + else + { + scsi->ccb.data_len = mem_readl_phys(scsi->ccb.addr + 0x04); + scsi->ccb.data_pointer = mem_readl_phys(scsi->ccb.addr + 0x08); + + scsi->ccb.target_id = mem_readb_phys(scsi->ccb.addr + 0x10); + scsi->ccb.lun = mem_readb_phys(scsi->ccb.addr + 0x11) & 0x1f; +// pclog("Target ID = %02x addr=%08x len=%08x\n", scsi->ccb.target_id, scsi->ccb.data_pointer, scsi->ccb.data_len); + } + for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) + scsi->ccb.cdb[c] = mem_readb_phys(scsi->ccb.addr+0x12+c); +// pclog("CCB_INITIATOR: target=%i lun=%i\n", scsi->ccb.target_id, scsi->ccb.lun); +// pclog(" scsi_len=%i data_len=%06x data_pointer=%06x\n", scsi->ccb.scsi_cmd_len, scsi->ccb.data_len, scsi->ccb.data_pointer); + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->ccb.status = 0; + scsi->ccb.from_mailbox = 1; + scsi->ccb.residual = (scsi->ccb.opcode == CCB_INITIATOR_RESIDUAL); + scsi->ccb.total_data_len = scsi->ccb.data_len; + break; + + case CCB_INITIATOR_SCATTER_GATHER: + case CCB_INITIATOR_SCATTER_GATHER_RESIDUAL: +// pclog("Scatter-gather : %08x %08x %08x %08x %08x %i %02x\n", mem_readl_phys(scsi->ccb.addr),mem_readl_phys(scsi->ccb.addr+4),mem_readl_phys(scsi->ccb.addr+8),mem_readl_phys(scsi->ccb.addr+12),mem_readl_phys(scsi->ccb.addr+16), scsi->mb_format == MB_FORMAT_4, scsi->ccb.opcode); + temp = mem_readb_phys(scsi->ccb.addr + 0x01); +// pclog("Read addr+ctrl %02x %06x\n", temp, scsi->ccb.addr+0x01); + scsi->ccb.transfer_dir = (temp >> 3) & 3; + scsi->ccb.scsi_cmd_len = mem_readb_phys(scsi->ccb.addr + 0x02); + scsi->ccb.req_sense_len = mem_readb_phys(scsi->ccb.addr + 0x03); + + if (scsi->mb_format == MB_FORMAT_4) + { + scsi->ccb.lun = temp & 7; + scsi->ccb.target_id = (temp >> 5) & 7; + + scsi->ccb.data_seg_list_len = mem_readb_phys(scsi->ccb.addr + 0x06) | (mem_readb_phys(scsi->ccb.addr + 0x05) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x04) << 16); + scsi->ccb.data_seg_list_pointer = mem_readb_phys(scsi->ccb.addr + 0x09) | (mem_readb_phys(scsi->ccb.addr + 0x08) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x07) << 16); + scsi->ccb.data_seg_list_idx = 0; + if (scsi->ccb.data_seg_list_len < 6) + pclog("Scatter gather table < 6 bytes\n"); + + scsi->ccb.link_pointer = mem_readb_phys(scsi->ccb.addr + 0x0c) | (mem_readb_phys(scsi->ccb.addr + 0x0b) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x0a) << 16); + scsi->ccb.link_id = mem_readb_phys(scsi->ccb.addr + 0x0d); + } + else + { + scsi->ccb.data_seg_list_len = mem_readl_phys(scsi->ccb.addr + 0x04); + scsi->ccb.data_seg_list_pointer = mem_readl_phys(scsi->ccb.addr + 0x08); + scsi->ccb.data_seg_list_idx = 0; + if (scsi->ccb.data_seg_list_len < 8) + pclog("Scatter gather table < 8 bytes\n"); + + scsi->ccb.target_id = mem_readb_phys(scsi->ccb.addr + 0x10); + scsi->ccb.lun = mem_readb_phys(scsi->ccb.addr + 0x11) & 0x1f; +// pclog("Target ID = %02x\n", scsi->ccb.target_id); + } + for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) + scsi->ccb.cdb[c] = mem_readb_phys(scsi->ccb.addr+0x12+c); +// pclog("CCB_INITIATOR_SCATTER_GATHER: target=%i lun=%i\n", scsi->ccb.target_id, scsi->ccb.lun); +// pclog(" scsi_len=%i data_len=%06x data_pointer=%06x\n", scsi->ccb.scsi_cmd_len, scsi->ccb.data_len, scsi->ccb.data_pointer); + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->ccb.status = 0; + scsi->ccb.from_mailbox = 1; + scsi->ccb.residual = (scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER_RESIDUAL); + + if (scsi->ccb.residual) + { + /*Read total data length from scatter list, to use when calculating residual*/ + uint32_t addr = scsi->ccb.data_seg_list_pointer; + + scsi->ccb.total_data_len = 0; + + if (scsi->mb_format == MB_FORMAT_4) + { + for (c = 0; c < scsi->ccb.data_seg_list_len; c += 6) + { + uint32_t len = mem_readb_phys(addr + c + 2) | + (mem_readb_phys(addr + c + 1) << 8) | + (mem_readb_phys(addr + c) << 16); + + scsi->ccb.total_data_len += len; + } + } + else + { + for (c = 0; c < scsi->ccb.data_seg_list_len; c += 6) + { + uint32_t len = mem_readl_phys(addr + c); + + scsi->ccb.total_data_len += len; + } + } + } + break; + + default: + fatal("Unknown CCD opcode %02x\n", scsi->ccb.opcode); + } + pclog("Start CCB at %06x\n", scsi->ccb.addr); +} + +static void process_cmd(aha154x_t *scsi) +{ + uint32_t addr; + int c; + + switch (scsi->cmd_state) + { + case CMD_STATE_RESET: + scsi->status = STATUS_INIT; + scsi->cmd_state = CMD_STATE_IDLE; + pclog("AHA154x reset complete\n"); + break; + + case CMD_STATE_IDLE: + if (scsi->status & STATUS_CDF) + { + int invalid = 0; + + scsi->status &= ~STATUS_CDF; + + scsi->command = scsi->cmd_data; + pclog("New command %02x\n", scsi->command); +// if (scsi->command == 0x22) +// fatal("Here\n"); +// output = 3; + switch (scsi->command) + { + case COMMAND_NOP: + case COMMAND_START_SCSI_COMMAND: + case COMMAND_ADAPTER_INQUIRY: + case COMMAND_RETURN_CONFIG_DATA: + scsi->command_len = 0; + break; + + case COMMAND_ADAPTEC_SET_BIOS_BANK_1: + case COMMAND_ADAPTEC_SET_BIOS_BANK_2: + case COMMAND_ADAPTEC_GET_EXT_BIOS_INFO: + case COMMAND_ADAPTEC_START_BIOS_SCSI_CMD: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 0; + else + invalid = 1; + break; + + case COMMAND_BUSLOGIC_84: + case COMMAND_BUSLOGIC_85: + if (scsi->type == SCSI_BT545S) + scsi->command_len = 0; + else + invalid = 1; + break; + + case COMMAND_ECHO: + case COMMAND_SET_BUS_ON_TIME: + case COMMAND_SET_BUS_OFF_TIME: + case COMMAND_SET_AT_BUS_SPEED: + case COMMAND_RETURN_SETUP_DATA: + scsi->command_len = 1; + break; + + case COMMAND_ADAPTEC_SET_SHADOW_PARAMS: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 1; + else + invalid = 1; + break; + + case 0x22: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 35; /*COMMAND_ADAPTEC_PROGRAM_EEPROM*/ + else + { +// scsi->command_len = 1; /*COMMAND_BUSLOGIC_22*/ + pclog("Get 22\n"); +// scsi->command_len = 0; + invalid = 1; + primed = 1; + } + break; + + case COMMAND_BUSLOGIC_SET_CCB_FORMAT: + case COMMAND_BUSLOGIC_STRICT_RR: + case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: + if (scsi->type == SCSI_BT545S) + scsi->command_len = 1; + else + invalid = 1; + break; + + case COMMAND_ENABLE_MAILBOX_INTERFACE: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 2; + else + invalid = 1; + break; + + case COMMAND_WRITE_CHANNEL_2_BUF: + case COMMAND_READ_CHANNEL_2_BUF: + scsi->command_len = 3; + break; + + case COMMAND_SET_SELECTION_TIMEOUT: + scsi->command_len = 4; + break; + + case COMMAND_ADAPTEC_RETURN_EEPROM_DATA: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 3; + else + invalid = 1; + break; + + case COMMAND_MAILBOX_INITIALIZATION: + scsi->command_len = 4; + break; + + case COMMAND_BUSLOGIC_81: + if (scsi->type == SCSI_BT545S) + scsi->command_len = 5; + else + invalid = 1; + break; + + case COMMAND_START_BIOS_COMMAND: + scsi->command_len = 10; + scsi->bios_cmd_state = 0; + break; + + case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 4; + else + invalid = 1; + break; + +/* case 0x40: case 0x42: case 0x44: case 0xff: + invalid = 1; + break;*/ + + default: + if (scsi->type == SCSI_AHA1542C) + { + if ((scsi->command > 0xd && scsi->command < 0x1a) || (scsi->command > 0x2a && scsi->command != 0x82)) + invalid = 1; + else + fatal("Bad AHA154x command %02x\n", scsi->command); + } + else + { + if (scsi->command > 0x22 && (scsi->command < 0xfa || scsi->command > 0xfc) && + !(scsi->command >= 0x81 && scsi->command <= 0x9d) && + scsi->command != 0xda && scsi->command != 0xdc) + invalid = 1; + else + fatal("Bad BT545S command %02x\n", scsi->command); + } + break; + } + + if (invalid) + { + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + } + else if (!scsi->command_len) + scsi->cmd_state = CMD_STATE_CMD_IN_PROGRESS; + else + { + scsi->cmd_state = CMD_STATE_GET_PARAMS; + scsi->cur_param = 0; + } + } + if (scsi->cmd_state != CMD_STATE_CMD_IN_PROGRESS) + { +// pclog("Command not fallthrough\n"); + break; + } +// pclog("Command fallthrough\n"); + /*Fallthrough*/ + + case CMD_STATE_CMD_IN_PROGRESS: + switch (scsi->command) + { + case COMMAND_NOP: +// pclog("NOP complete\n"); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_MAILBOX_INITIALIZATION: + scsi->mbc = scsi->params[0]; + scsi->mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); + scsi->mba_i = scsi->mba + scsi->mbc*4; + scsi->mb_format = MB_FORMAT_4; + pclog("Mailbox init: MBC=%02x MBC=%06x\n", scsi->mbc, scsi->mba); + scsi->status &= ~STATUS_INIT; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_START_SCSI_COMMAND: + pclog("START_SCSI_COMMAND %i %i\n", scsi->ccb_state, scsi->scsi_state); + scsi->mbo_req++; + scsi->cmd_state = CMD_STATE_IDLE; + /*Don't send IRQ until we actually start processing a mailbox*/ + break; + + case COMMAND_START_BIOS_COMMAND: + if (scsi->ccb_state != CCB_STATE_IDLE) + break; + if (!scsi->bios_cmd_state) + pclog("Start BIOS command %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + scsi->params[0], scsi->params[1], scsi->params[2], scsi->params[3], scsi->params[4], + scsi->params[5], scsi->params[6], scsi->params[7], scsi->params[8], scsi->params[9]); + if (scsi->params[0] >= 0x16) + { + /*Only commands below 0x16 are implemented*/ + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + } + else switch (scsi->params[0]) + { + case 0x00: /*Reset Disk System*/ + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x01: /*Get Status of Last Operation*/ + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x02: /*Read Sector(s) Into Memory*/ + switch (scsi->bios_cmd_state) + { + case 0: + { + int sector = scsi->params[5]; + int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); + int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); + + pclog("Cylinder=%i head=%i sector=%i\n", cylinder, head, sector); + addr = sector + (head * 32) + (cylinder * 64 * 32); + } + scsi->ccb.cdb[0] = SCSI_READ_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = addr >> 24; + scsi->ccb.cdb[3] = addr >> 16; + scsi->ccb.cdb[4] = addr >> 8; + scsi->ccb.cdb[5] = addr & 0xff; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = scsi->params[6]; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16);; + scsi->ccb.data_len = 512 * scsi->params[6]; + scsi->ccb.req_sense_len = CCB_SENSE_14; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + pclog("Read sector %08x %06x\n", addr, scsi->ccb.data_pointer); + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->ccb.status) + fatal("Read sector fail %02x\n", scsi->ccb.status); + scsi->data_in = 0x00; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case 0x03: /*Write Disk Sector(s)*/ + switch (scsi->bios_cmd_state) + { + case 0: + { + int sector = scsi->params[5]; + int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); + int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); + + addr = sector + (head * 32) + (cylinder * 64 * 32); + } + scsi->ccb.cdb[0] = SCSI_WRITE_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = addr >> 24; + scsi->ccb.cdb[3] = addr >> 16; + scsi->ccb.cdb[4] = addr >> 8; + scsi->ccb.cdb[5] = addr & 0xff; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = scsi->params[6]; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16);; + scsi->ccb.data_len = 512 * scsi->params[6]; + scsi->ccb.req_sense_len = CCB_SENSE_14; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + pclog("Write sector %08x %06x\n", addr, scsi->ccb.data_pointer); + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->ccb.status) + fatal("Write sector fail %02x\n", scsi->ccb.status); + scsi->data_in = 0x00; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case 0x04: /*Verify Disk Sector(s)*/ + switch (scsi->bios_cmd_state) + { + case 0: + { + int sector = scsi->params[5]; + int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); + int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); + + addr = sector + (head * 32) + (cylinder * 64 * 32); + } + scsi->ccb.cdb[0] = SCSI_VERIFY_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = addr >> 24; + scsi->ccb.cdb[3] = addr >> 16; + scsi->ccb.cdb[4] = addr >> 8; + scsi->ccb.cdb[5] = addr & 0xff; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = scsi->params[6]; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16);; + scsi->ccb.data_len = 512 * scsi->params[6]; + scsi->ccb.req_sense_len = CCB_SENSE_14; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + pclog("Verify sector %08x %06x\n", addr, scsi->ccb.data_pointer); + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->ccb.status) + fatal("Verify sector fail %02x\n", scsi->ccb.status); + scsi->data_in = 0x00; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + /*AHA1542C firmware just fails all of these*/ + case 0x05: case 0x06: case 0x07: + case 0x0a: case 0x0b: + case 0x12: case 0x13: + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x08: /*Get Drive Parameters*/ + switch (scsi->bios_cmd_state) + { + case 0: + scsi->ccb.cdb[0] = SCSI_READ_CAPACITY_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = 0; + scsi->ccb.cdb[3] = 0; + scsi->ccb.cdb[4] = 0; + scsi->ccb.cdb[5] = 0; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = 0; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = -1; + scsi->ccb.data_len = 8; + scsi->ccb.req_sense_len = CCB_SENSE_NONE; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->bios_cmd_state++; + break; + case 1: + addr = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + mem_writeb_phys(addr, scsi->int_buffer[0]); + mem_writeb_phys(addr+1, scsi->int_buffer[1]); + mem_writeb_phys(addr+2, scsi->int_buffer[2]); + mem_writeb_phys(addr+3, scsi->int_buffer[3]); + pclog("Got size %06x %02x%02x%02x%02x\n", addr, scsi->int_buffer[3],scsi->int_buffer[2],scsi->int_buffer[1],scsi->int_buffer[0]); + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case 0x09: /*Initialize Drive Parameters*/ + case 0x0c: /*Seek To Cylinder*/ + case 0x0d: /*Reset Hard Disks*/ + case 0x0e: /*Read Sector Buffer*/ + case 0x0f: /*Write Sector Buffer*/ + case 0x10: /*Check If Drive Ready*/ + case 0x11: /*Recalibrate Drive*/ + case 0x14: /*Controller Internal Diagnostic*/ + pclog("Unimplemented AHA1542 BIOS command - 0x%02x\n", scsi->params[0]); + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x15: /*Get Disk Type*/ + switch (scsi->bios_cmd_state) + { + case 0: + scsi->ccb.cdb[0] = SCSI_INQUIRY; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = 0; + scsi->ccb.cdb[3] = 0; + scsi->ccb.cdb[4] = 36; + scsi->ccb.cdb[5] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 6; + scsi->ccb.data_pointer = -1; + scsi->ccb.data_len = 36; + scsi->ccb.req_sense_len = CCB_SENSE_NONE; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->ccb.from_mailbox = 0; + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->int_buffer[0] & 0x1f) + { + /*Not a direct-access device*/ + fatal("Not a direct-access device\n"); + } + scsi->ccb.cdb[0] = SCSI_READ_CAPACITY_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = 0; + scsi->ccb.cdb[3] = 0; + scsi->ccb.cdb[4] = 0; + scsi->ccb.cdb[5] = 0; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = 0; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = -1; + scsi->ccb.data_len = 8; + scsi->ccb.req_sense_len = CCB_SENSE_NONE; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->bios_cmd_state++; + break; + case 2: + addr = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + mem_writeb_phys(addr, scsi->int_buffer[0]); + mem_writeb_phys(addr+1, scsi->int_buffer[1]); + mem_writeb_phys(addr+2, scsi->int_buffer[2]); + mem_writeb_phys(addr+3, scsi->int_buffer[3]); + pclog("Got size %06x %02x%02x%02x%02x\n", addr, scsi->int_buffer[3],scsi->int_buffer[2],scsi->int_buffer[1],scsi->int_buffer[0]); + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + default: + fatal("Get Disk Type state %i\n", scsi->bios_cmd_state); + } + //fatal("data_pointer %06x\n", scsi->ccb.data_pointer); + break; + + default: + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case COMMAND_ADAPTER_INQUIRY: + if (scsi->type == SCSI_BT545S) + { + scsi->result[0] = 0x41; + scsi->result[1] = 0x41; /*Standard model*/ + scsi->result[2] = 0x33; /*Firmware revision*/ + scsi->result[3] = 0x33; + } + else + { + scsi->result[0] = 0x44; /*AHA-1542CF*/ + scsi->result[1] = 0x30; + scsi->result[2] = 0x30; /*Firmware revision*/ + scsi->result[3] = 0x31; + } + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 4; + break; + + case COMMAND_SET_SELECTION_TIMEOUT: + scsi->e_d = scsi->params[0]; + scsi->to = (scsi->params[1] << 8) | scsi->params[2]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_BUS_ON_TIME: + scsi->bon = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_BUS_OFF_TIME: + scsi->boff = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_AT_BUS_SPEED: + scsi->atbs = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_RETURN_CONFIG_DATA: + scsi->result[0] = 1 << scsi->dma; + scsi->result[1] = 1 << (scsi->irq-9); + scsi->result[2] = scsi->host_id; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 3; + break; + + case COMMAND_ECHO: + pclog("ECHO\n"); + scsi->result[0] = scsi->params[0]; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 1; + break; + + case COMMAND_RETURN_SETUP_DATA: + pclog("Return setup data %i %02x %06x\n", scsi->params[0], scsi->mbc, scsi->mba); + scsi->result[0] = 0x00; /*SPS*/ + scsi->result[1] = scsi->atbs; /*AT bus speed*/ + scsi->result[2] = scsi->bon; /*BON*/ + scsi->result[3] = scsi->boff; /*BOFF*/ + scsi->result[4] = scsi->mbc; /*DS:E8 - mailbox count*/ + scsi->result[5] = scsi->mba >> 16; /*DS:DA - set by command 0x81?*/ + scsi->result[6] = scsi->mba >> 8; /*DS:DB*/ + scsi->result[7] = scsi->mba & 0xff; /*DS:DC*/ + scsi->result[8] = 0x00; /*STA0*/ + scsi->result[9] = 0x00; /*STA1*/ + scsi->result[10] = 0x00; /*STA2*/ + scsi->result[11] = 0x00; /*STA3*/ + scsi->result[12] = 0x00; /*STA4*/ + scsi->result[13] = 0x00; /*STA5*/ + scsi->result[14] = 0x00; /*STA6*/ + scsi->result[15] = 0x00; /*STA7*/ + scsi->result[16] = 0x00; /*DS (DS:1e5b)*/ + if (scsi->type == SCSI_BT545S) + { + scsi->result[17] = 0x42; /*Firmware version*/ + scsi->result[18] = 0x44; + scsi->result[19] = 0x41; + } + else + { + for (c = 0; c < 20; c++) + scsi->result[c+17] = 0; /*Customer signature*/ + scsi->result[37] = 0; /*Auto-retry*/ + scsi->result[38] = 0; /*Board switches*/ + scsi->result[39] = 0xa3; /*Checksum*/ + scsi->result[40] = 0xc2; + scsi->result[41] = scsi->bios_mba >> 16; + scsi->result[42] = scsi->bios_mba >> 8; + scsi->result[43] = scsi->bios_mba & 0xff; + } + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 20); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_WRITE_CHANNEL_2_BUF: + addr = scsi->params[2] | (scsi->params[1] << 8) | (scsi->params[0] << 16); + pclog("WRITE_CHANNEL_2_BUF %06x\n", addr); + for (c = 0; c < 64; c++) + scsi->dma_buffer[c] = mem_readb_phys(addr + c); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + pclog("Command complete\n"); + break; + + case COMMAND_READ_CHANNEL_2_BUF: + addr = scsi->params[2] | (scsi->params[1] << 8) | (scsi->params[0] << 16); + pclog("READ_CHANNEL_2_BUF %06x\n", addr); + for (c = 0; c < 64; c++) + mem_writeb_phys(addr + c, scsi->dma_buffer[c]); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + pclog("Command complete\n"); + break; + + case 0x22: + if (scsi->type == SCSI_AHA1542C) + { + /*COMMAND_ADAPTEC_PROGRAM_EEPROM*/ + for (c = 0; c < scsi->params[1]; c++) + { + pclog("EEPROM %02x = %02x\n", (scsi->params[2] + c) & 0xff, scsi->params[c+3]); + scsi->eeprom[(scsi->params[2] + c) & 0xff] = scsi->params[c+3]; + } + scsi->host_id = scsi->eeprom[0] & 7; + scsi->dma = (scsi->eeprom[1] >> 4) & 7; + scsi->irq = (scsi->eeprom[1] & 7) + 9; + pclog("Program EEPROM: IRQ=%i DMA=%i host_id=%i\n", scsi->irq, scsi->dma, scsi->host_id); + + aha1542c_eeprom_save(scsi); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + } + else + { + /*COMMAND_BUSLOGIC_22*/ + pclog("BUSLOGIC_22\n"); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + primed = 1; +// scsi->result[0] = 1 << scsi->dma; /*DMA7*/ +// scsi->result[1] = 1 << (scsi->irq-9); /*IRQ10*/ +// scsi->result[2] = scsi->host_id; /*SCSI ID*/ +// scsi->cmd_state = CMD_STATE_SEND_RESULT; +// scsi->result_pos = 0; +// scsi->result_len = 3; + } + break; + + case COMMAND_ADAPTEC_RETURN_EEPROM_DATA: + pclog("Return EEPROM data %02x %02x %02x\n", scsi->params[0], scsi->params[1], scsi->params[2]); + for (c = 0; c < scsi->params[1]; c++) + { + scsi->result[c] = scsi->eeprom[(scsi->params[2] + c) & 0xff]; + pclog(" EEPROM data %02x %02x\n", (scsi->params[2] + c) & 0xff, scsi->result[c]); + } + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = c; + break; + + case COMMAND_ADAPTEC_SET_SHADOW_PARAMS: + pclog("Set shadow params %02x\n", scsi->params[0]); + scsi->shadow = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT: + scsi->bios_mbc = scsi->params[0]; + scsi->bios_mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); + pclog("BIOS mailbox init: MBC=%02x MBC=%06x\n", scsi->bios_mbc, scsi->bios_mba); + scsi->status &= ~STATUS_INIT; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_SET_BIOS_BANK_1: + mem_mapping_set_exec(&scsi->mapping, &scsi->bios_rom.rom[0]); + scsi->bios_bank = 0x0000; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_SET_BIOS_BANK_2: + mem_mapping_set_exec(&scsi->mapping, &scsi->bios_rom.rom[0x4000]); + scsi->bios_bank = 0x4000; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_GET_EXT_BIOS_INFO: + scsi->result[0] = 0; + scsi->result[1] = scsi->mblt; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 2; + break; + + case COMMAND_ENABLE_MAILBOX_INTERFACE: + scsi->mbu = scsi->params[0]; + scsi->mblt = scsi->params[1]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_START_BIOS_SCSI_CMD: + pclog("START_BIOS_SCSI_COMMAND %02x %08x %i\n", scsi->bios_mbc, scsi->bios_mba, scsi->ccb_state); + scsi->bios_mbo_req++; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_BUSLOGIC_81: + scsi->mbc = scsi->params[0]; + scsi->mba = scsi->params[1] | (scsi->params[2] << 8) | (scsi->params[3] << 16) | (scsi->params[4] << 24); + scsi->mba_i = scsi->mba + scsi->mbc*8; + scsi->mb_format = MB_FORMAT_8; + pclog("Mailbox init: MBC=%02x MBC=%08x\n", scsi->mbc, scsi->mba); + scsi->status &= ~STATUS_INIT; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_BUSLOGIC_84: + scsi->result[0] = 0x31; /*Firmware sub-version?*/ + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 1; + break; + + case COMMAND_BUSLOGIC_85: + scsi->result[0] = 0x20; /*???*/ + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 1; + break; + + case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: + pclog("Extended setup info %i\n", scsi->params[0]); + scsi->result[0] = 0x41; + scsi->result[1] = scsi->bios_addr >> 12; /*BIOS addr*/ + scsi->result[2] = 0x00; + scsi->result[3] = 0x20; + scsi->result[4] = 0x00; /*DS:E8 >> 3*/ + scsi->result[5] = 0x00; /*DS:DA - set by command 0x81?*/ + scsi->result[6] = 0x00; /*DS:DB*/ + scsi->result[7] = 0x00; /*DS:DC*/ + scsi->result[8] = 0x00; /*DS:DD*/ + scsi->result[9] = 0x33; /*FFFF:9*/ + scsi->result[10] = 0x33; /*FFFF:A*/ + scsi->result[11] = 0x31; /*FFFF:B*/ + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 12); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_BUSLOGIC_STRICT_RR: + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_BUSLOGIC_SET_CCB_FORMAT: + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + default: + fatal("Bad AHA154x command in progress %02x\n", scsi->command); + } + break; + + case CMD_STATE_GET_PARAMS: + if (scsi->status & STATUS_CDF) + { + scsi->status &= ~STATUS_CDF; + + scsi->params[scsi->cur_param++] = scsi->cmd_data; + + if (scsi->cur_param == scsi->command_len) + scsi->cmd_state = CMD_STATE_CMD_IN_PROGRESS; + } + break; + + case CMD_STATE_SEND_RESULT: + if (!(scsi->status & STATUS_DF)) + { + if (scsi->result_pos == scsi->result_len) + { + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + pclog("Command complete\n"); + } + else + { + scsi->status |= STATUS_DF; + scsi->data_in = scsi->result[scsi->result_pos++]; + pclog("Return data %02x %i %i\n", scsi->data_in, scsi->result_pos-1, scsi->result_len); + } + } + break; + + default: + fatal("Unknown state %d\n", scsi->cmd_state); + } +} + +static void process_ccb(aha154x_t *scsi) +{ + int c; + + switch (scsi->ccb_state) + { + case CCB_STATE_IDLE: + if (scsi->status & STATUS_INIT) + break; + if (scsi->mbo_req) + { +// pclog("mbo_req %i\n", scsi->mbc); + for (c = 0; c < scsi->mbc; c++) + { + uint32_t ccb; + uint8_t command; + + if (scsi->mb_format == MB_FORMAT_4) + { + uint32_t mbo = mem_readl_phys(scsi->mba + c*4); + command = mbo & 0xff; + ccb = (mbo >> 24) | ((mbo >> 8) & 0xff00) | ((mbo << 8) & 0xff0000); +// pclog("MBO%02x = %08x\n", c, mbo); + } + else + { + ccb = mem_readl_phys(scsi->mba + c*8); + command = mem_readb_phys(scsi->mba + c*8 + 7); +// pclog("MBO%02x = %08x %02x\n", c, ccb, command); + } + + if (command == COMMAND_START_CCB) + { + pclog("Start CCB %08x %i\n", ccb, c); + + scsi->current_mbo = c; + scsi->current_mbo_is_bios = 0; + scsi->ccb.addr = ccb; + + process_cdb(scsi); + + scsi->mbo_req--; + + set_irq(scsi, ISR_HACC); + break; + } + else if (command == COMMAND_ABORT_CCB) + { +// fatal("Abort command\n"); + scsi->mbo_req--; + + if (scsi->mb_format == MB_FORMAT_4) + { + mem_writeb_phys(scsi->mba + c*8, 0); + + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4, MBI_CCB_ABORTED); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 1, ccb >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 2, ccb >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 3, ccb & 0xff); + } + else + { + mem_writeb_phys(scsi->mba + c*8 + 7, 0); + + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8, ccb); + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_ABORTED); + } + + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, ISR_MBOA | ISR_MBIF | ISR_HACC); + break; + } + } + } + if (scsi->bios_mbo_req) + { + for (c = 0; c < scsi->bios_mbc; c++) + { + uint32_t ccb; + uint8_t command; + + uint32_t mbo = mem_readl_phys(scsi->bios_mba + c*4); + command = mbo & 0xff; + ccb = (mbo >> 24) | ((mbo >> 8) & 0xff00) | ((mbo << 8) & 0xff0000); + + if (command == COMMAND_START_CCB) + { + pclog("Start BIOS CCB %08x %i\n", ccb, c); + + scsi->current_mbo = c; + scsi->current_mbo_is_bios = 1; + scsi->ccb.addr = ccb; + + process_cdb(scsi); + + scsi->bios_mbo_req--; + set_irq(scsi, ISR_HACC); + break; + } + } + } + break; + + case CCB_STATE_SEND_COMMAND: + if (scsi->scsi_state != SCSI_STATE_IDLE) + break; /*Wait until SCSI state machine is ready for new command*/ + for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) + { + scsi->cdb.data[c] = scsi->ccb.cdb[c]; +// pclog(" CDB[%02x]=%02x\n", c, scsi->cdb.data[c]); + } + scsi->cdb.len = scsi->ccb.scsi_cmd_len; + scsi->cdb.idx = 0; + if (scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER || scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER_RESIDUAL) + { + scsi->cdb.data_seg_list_len = scsi->ccb.data_seg_list_len; + scsi->cdb.data_seg_list_pointer = scsi->ccb.data_seg_list_pointer; + scsi->cdb.data_seg_list_idx = 0; + scsi->cdb.scatter_gather = 1; + scsi->cdb.data_len = 0; + scsi->cdb.data_idx = 0; + } + else + { + scsi->cdb.data_pointer = scsi->ccb.data_pointer; + scsi->cdb.data_len = scsi->ccb.data_len; + scsi->cdb.scatter_gather = 0; + } + scsi->cdb.bytes_transferred = 0; + scsi->cdb.data_idx = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + /*SCSI will now select the device and execute the command*/ + scsi->ccb_state = CCB_STATE_WAIT_COMMAND; + break; + + case CCB_STATE_WAIT_COMMAND: + if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) + { + pclog("Command select has failed\n"); + if (scsi->ccb.from_mailbox) + { + mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_SELECTION_TIME_OUT); + + if (scsi->mb_format == MB_FORMAT_4) + { + if (scsi->current_mbo_is_bios) + { + mem_writeb_phys(scsi->bios_mba + scsi->current_mbo*4, COMMAND_FREE_CCB); + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); + } + else + { + mem_writeb_phys(scsi->mba + scsi->current_mbo*4, COMMAND_FREE_CCB); + + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4, MBI_CCB_COMPLETE_WITH_ERROR); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 1, scsi->ccb.addr >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 2, scsi->ccb.addr >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 3, scsi->ccb.addr & 0xff); + } + } + else + { + if (scsi->current_mbo_is_bios) + fatal("MBO_IS_BIOS MB_FORMAT_8\n"); + mem_writeb_phys(scsi->mba + scsi->current_mbo*8 + 7, COMMAND_FREE_CCB); + + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8, scsi->ccb.addr); + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE_WITH_ERROR << 24); + } + + if (!scsi->current_mbo_is_bios) + { + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, ISR_MBOA | ISR_MBIF); + } + else + set_irq(scsi, ISR_MBOA); + } +// set_irq(scsi, ISR_HACC); + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + break; + } + if (scsi->scsi_state != SCSI_STATE_IDLE) + break; /*Wait until SCSI state machine has completed command*/ + scsi->ccb.status = scsi->cdb.last_status; + scsi->ccb.bytes_transferred = scsi->cdb.bytes_transferred; + scsi->ccb_state = CCB_STATE_SEND_REQUEST_SENSE; + break; + + case CCB_STATE_SEND_REQUEST_SENSE: + if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) + { +// pclog("No sense data\n"); + if (scsi->ccb.from_mailbox) + { + uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; + +// pclog("Residue=%08x %x %x %i MBI=%i\n", residue, scsi->ccb.total_data_len, scsi->ccb.bytes_transferred, scsi->ccb.residual, scsi->current_mbi); + mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); + + if (scsi->mb_format == MB_FORMAT_4) + { + if (scsi->ccb.residual) + { + mem_writeb_phys(scsi->ccb.addr + 0x4, residue >> 16); + mem_writeb_phys(scsi->ccb.addr + 0x5, residue >> 8); + mem_writeb_phys(scsi->ccb.addr + 0x6, residue & 0xff); + } + + if (scsi->current_mbo_is_bios) + { + mem_writeb_phys(scsi->bios_mba + scsi->current_mbo*4, COMMAND_FREE_CCB); + + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); + } + else + { + mem_writeb_phys(scsi->mba + scsi->current_mbo*4, COMMAND_FREE_CCB); + + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4, MBI_CCB_COMPLETE_WITH_ERROR); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 1, scsi->ccb.addr >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 2, scsi->ccb.addr >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 3, scsi->ccb.addr & 0xff); + } + } + else + { + if (scsi->current_mbo_is_bios) + fatal("MBO_IS_BIOS MB_FORMAT_8\n"); + + if (scsi->ccb.residual) + mem_writel_phys(scsi->ccb.addr + 0x4, residue); + + mem_writeb_phys(scsi->mba + scsi->current_mbo*8 + 7, COMMAND_FREE_CCB); + + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8, scsi->ccb.addr); + if (scsi->ccb.status == STATUS_GOOD) + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE << 24); + else + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE_WITH_ERROR << 24); + } + + if (!scsi->current_mbo_is_bios) + { + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, ISR_MBOA | ISR_MBIF); + } + else + set_irq(scsi, ISR_MBOA); + } + scsi->ccb_state = CCB_STATE_IDLE; + break; + } + /*Build request sense command*/ + scsi->cdb.data[0] = SCSI_REQUEST_SENSE; + scsi->cdb.data[1] = scsi->ccb.lun << 5; + scsi->cdb.data[2] = 0x00; + scsi->cdb.data[3] = 0x00; + if (scsi->ccb.req_sense_len == CCB_SENSE_14) + scsi->cdb.data[4] = 14; + else + scsi->cdb.data[4] = scsi->ccb.req_sense_len; + scsi->cdb.data[5] = 14; + scsi->cdb.len = 6; + scsi->cdb.idx = 0; + if (scsi->ccb.from_mailbox) + scsi->cdb.data_pointer = -1; + else + scsi->cdb.data_pointer = scsi->ccb.addr + 0x12 + scsi->ccb.scsi_cmd_len; + scsi->cdb.data_idx = 0; + scsi->cdb.data_len = scsi->cdb.data[4]; + scsi->cdb.scatter_gather = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->ccb_state = CCB_STATE_WAIT_REQUEST_SENSE; + break; + + case CCB_STATE_WAIT_REQUEST_SENSE: + if (scsi->scsi_state != SCSI_STATE_IDLE) + break; /*Wait until SCSI state machine has completed command*/ + + if (scsi->ccb.from_mailbox) + { + uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; +// pclog("residue=%x %x %x\n", residue, scsi->ccb.total_data_len, scsi->ccb.bytes_transferred); + mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); + + if (scsi->mb_format == MB_FORMAT_4) + { + if (scsi->ccb.residual) + { + mem_writeb_phys(scsi->ccb.addr + 0x4, residue >> 16); + mem_writeb_phys(scsi->ccb.addr + 0x5, residue >> 8); + mem_writeb_phys(scsi->ccb.addr + 0x6, residue & 0xff); + } + + if (scsi->current_mbo_is_bios) + { + mem_writeb_phys(scsi->bios_mba + scsi->current_mbo*4, COMMAND_FREE_CCB); + + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); + } + else + { + mem_writeb_phys(scsi->mba + scsi->current_mbo*4, COMMAND_FREE_CCB); + +// pclog("CCB status %02x\n", scsi->ccb.status); + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4, MBI_CCB_COMPLETE_WITH_ERROR); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 1, scsi->ccb.addr >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 2, scsi->ccb.addr >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi*4 + 3, scsi->ccb.addr & 0xff); + } + } + else + { + if (scsi->current_mbo_is_bios) + fatal("MBO_IS_BIOS MB_FORMAT_8\n"); + + if (scsi->ccb.residual) + mem_writel_phys(scsi->ccb.addr + 0x4, residue); + + mem_writeb_phys(scsi->mba + scsi->current_mbo*8 + 7, COMMAND_FREE_CCB); + + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8, scsi->ccb.addr); + if (scsi->ccb.status == STATUS_GOOD) + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE << 24); + else + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE_WITH_ERROR << 24); + } + + if (!scsi->current_mbo_is_bios) + { + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, ISR_MBOA | ISR_MBIF); + } + else + set_irq(scsi, ISR_MBOA); + + set_irq(scsi, ISR_MBOA | ISR_MBIF); + } +// pclog("CCB_STATE_WAIT_REQUEST_SENSE over %i\n", scsi->ccb.from_mailbox); + scsi->ccb_state = CCB_STATE_IDLE; + break; + + default: + fatal("Unknown CCB_state %d\n", scsi->ccb_state); + } +} + +static void process_scsi(aha154x_t *scsi) +{ + int c; + int bytes_transferred = 0; + + switch (scsi->scsi_state) + { + case SCSI_STATE_IDLE: + break; + + case SCSI_STATE_SELECT: + scsi->cdb.last_status = 0; +// pclog("Select target ID %i\n", scsi->ccb.target_id); + scsi_bus_update(&scsi->bus, BUS_SEL | BUS_SETDATA(1 << scsi->ccb.target_id)); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY) || scsi->ccb.target_id > 6) + { + pclog("STATE_SCSI_SELECT failed to select target %i\n", scsi->ccb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + break; + } + + scsi_bus_update(&scsi->bus, 0); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY)) + { + pclog("STATE_SCSI_SELECT failed to select target %i 2\n", scsi->ccb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + break; + } + + /*Device should now be selected*/ + if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) + fatal("Device failed to request command\n"); + + scsi->scsi_state = SCSI_STATE_SEND_COMMAND; + break; + + case SCSI_STATE_SELECT_FAILED: + break; + + case SCSI_STATE_SEND_COMMAND: + while (scsi->cdb.idx < scsi->cdb.len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int bus_out; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + fatal("SEND_COMMAND - bus phase incorrect\n"); + if (bus_state & BUS_REQ) + break; + } + if (c == 20) + { + pclog("SEND_COMMAND timed out\n"); + break; + } + + bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); +// pclog(" Command send %02x\n", scsi->cdb.data[scsi->cdb.idx]); +// if (!scsi->cdb.idx && scsi->cdb.data[scsi->cdb.idx] == 0x25 && scsi->current_mbo == 1) +// output = 3; + scsi->cdb.idx++; + bytes_transferred++; + + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + } + if (scsi->cdb.idx == scsi->cdb.len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + + case SCSI_STATE_NEXT_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + fatal("NEXT_PHASE - dropped BSY waiting\n"); + + if (bus_state & BUS_REQ) + { +// pclog("SCSI next phase - %x\n", bus_state); + switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) + { + case 0: +// pclog("Move to write data\n"); + scsi->scsi_state = SCSI_STATE_WRITE_DATA; + break; + + case BUS_IO: +// pclog("Move to read data\n"); + scsi->scsi_state = SCSI_STATE_READ_DATA; + break; + + case (BUS_CD | BUS_IO): +// pclog("Move to read status\n"); + scsi->scsi_state = SCSI_STATE_READ_STATUS; + break; + + case (BUS_CD | BUS_IO | BUS_MSG): +// pclog("Move to read message\n"); + scsi->scsi_state = SCSI_STATE_READ_MESSAGE; + break; + + default: + fatal(" Bad new phase %x\n", bus_state); + } + break; + } + } + break; + + case SCSI_STATE_END_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + { + pclog("END_PHASE - dropped BSY waiting\n"); +// if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) +// fatal("No sense data\n"); + scsi->scsi_state = SCSI_STATE_IDLE; + break; + } + + if (bus_state & BUS_REQ) + fatal("END_PHASE - unexpected REQ\n"); + } + break; + + case SCSI_STATE_READ_DATA: +//pclog("READ_DATA %i,%i %i\n", scsi->cdb.data_idx,scsi->cdb.data_len, scsi->cdb.scatter_gather); + while (scsi->cdb.data_idx < scsi->cdb.data_len && scsi->scsi_state == SCSI_STATE_READ_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int d; + + for (d = 0; d < 20; d++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + fatal("READ_DATA - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) + { + pclog("READ_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t data = BUS_GETDATA(bus_state); + int bus_out = 0; + + if (scsi->cdb.data_pointer == -1) + scsi->int_buffer[scsi->cdb.data_idx] = data; + else + mem_writeb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx, data); + scsi->cdb.data_idx++; + scsi->cdb.bytes_transferred++; + +// pclog("Read data %02x %i %06x\n", data, scsi->cdb.data_idx, scsi->cdb.data_pointer + scsi->cdb.data_idx); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } + + bytes_transferred++; + } + if (scsi->cdb.data_idx == scsi->cdb.data_len) + { + if (scsi->cdb.scatter_gather) + { + if (scsi->cdb.data_seg_list_idx >= scsi->cdb.data_seg_list_len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + else + { + if (scsi->mb_format == MB_FORMAT_4) + { + scsi->cdb.data_len = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 2) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 1) << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx) << 16); + scsi->cdb.data_pointer = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 5) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4) << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 3) << 16); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 6; + } + else + { + scsi->cdb.data_len = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx); + scsi->cdb.data_pointer = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 8; +// output = 3; + } + pclog("Got scatter gather %08x %08x\n", scsi->cdb.data_pointer, scsi->cdb.data_len); + } + } + else + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + } + break; + + case SCSI_STATE_WRITE_DATA: + while (scsi->cdb.data_idx < scsi->cdb.data_len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int d; + + for (d = 0; d < 20; d++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + fatal("WRITE_DATA - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) + { + pclog("WRITE_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t data;// = BUS_GETDATA(bus_state); + int bus_out; + + if (scsi->cdb.data_pointer == -1) + data = scsi->int_buffer[scsi->cdb.data_idx]; + else + data = mem_readb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx); + scsi->cdb.data_idx++; + scsi->cdb.bytes_transferred++; + +// pclog("Write data %02x %i\n", data, scsi->cdb.data_idx); + bus_out = BUS_SETDATA(data); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } + + bytes_transferred++; + } + if (scsi->cdb.data_idx == scsi->cdb.data_len) + { + if (scsi->cdb.scatter_gather) + { + if (scsi->cdb.data_seg_list_idx >= scsi->cdb.data_seg_list_len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + else + { + if (scsi->mb_format == MB_FORMAT_4) + { + scsi->cdb.data_len = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 2) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 1) << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx) << 16); + scsi->cdb.data_pointer = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 5) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4) << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 3) << 16); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 6; + } + else + { + scsi->cdb.data_len = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx); + scsi->cdb.data_pointer = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 8; + } + pclog("Got scatter gather %08x %08x\n", scsi->cdb.data_pointer, scsi->cdb.data_len); + } + } + else + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + } + break; + + case SCSI_STATE_READ_STATUS: + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + fatal("READ_STATUS - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) + { + pclog("READ_STATUS - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t status = BUS_GETDATA(bus_state); + int bus_out = 0; + +// pclog("Read status %02x\n", status); + if (scsi->ccb.from_mailbox) + mem_writeb_phys(scsi->ccb.addr + 0xf, status); + scsi->cdb.last_status = status; + + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + } + break; + + case SCSI_STATE_READ_MESSAGE: + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + fatal("READ_MESSAGE - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) + { + pclog("READ_MESSAGE - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t msg = BUS_GETDATA(bus_state); + int bus_out = 0; + +// pclog("Read message %02x\n", msg); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + + switch (msg) + { + case MSG_COMMAND_COMPLETE: + scsi->scsi_state = SCSI_STATE_END_PHASE; + break; + + default: + fatal("READ_MESSAGE - unknown message %02x\n", msg); + } + break; + } + } + break; + + default: + fatal("Unknown SCSI_state %d\n", scsi->scsi_state); + } +} + +static void aha154x_callback(void *p) +{ + aha154x_t *scsi = (aha154x_t *)p; + + scsi->timer += TIMER_USEC * POLL_TIME_US; + +// pclog("poll %i\n", scsi->cmd_state); + process_cmd(scsi); + process_ccb(scsi); + process_scsi(scsi); +} + +static uint8_t aha1542c_read(uint32_t addr, void *p) +{ + aha154x_t *scsi = (aha154x_t *)p; + uint8_t temp = 0xff; + + addr &= 0x3fff; + + + if (addr == 0x3f7e) /*DIP switches*/ + temp = scsi->dipsw; + else if (addr == 0x3f7f) /*Negation of DIP switches, to satisfy BIOS checksum!*/ + temp = (scsi->dipsw ^ 0xff) + 1; + else if (addr >= 0x3f80 && (scsi->shadow & 2)) + temp = scsi->shadow_ram[addr]; + else + temp = scsi->bios_rom.rom[addr | scsi->bios_bank]; + + return temp; +} +static void aha1542c_write(uint32_t addr, uint8_t val, void *p) +{ + aha154x_t *scsi = (aha154x_t *)p; + + addr &= 0x3fff; + + if (addr >= 0x3f80 && (scsi->shadow & 1)) + scsi->shadow_ram[addr] = val; +} + +static void aha1542c_eeprom_load(aha154x_t *scsi, char *fn) +{ + FILE *f; + + strcpy(scsi->fn, fn); + f = nvrfopen(scsi->fn, "rb"); + if (!f) + { + memset(scsi->eeprom, 0, 35); + return; + } + fread(scsi->eeprom, 1, 32, f); + fclose(f); +} + +static void aha1542c_eeprom_save(aha154x_t *scsi) +{ + FILE *f = nvrfopen(scsi->fn, "wb"); + + if (!f) + return; + fwrite(scsi->eeprom, 1, 32, f); + fclose(f); +} + +static uint16_t port_sw_mapping[8] = +{ + 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, -1, -1 +}; + +static void *scsi_aha1542c_init(char *bios_fn) +{ + aha154x_t *scsi = malloc(sizeof(aha154x_t)); + uint32_t addr; + int c; + memset(scsi, 0, sizeof(aha154x_t)); + + rom_init(&scsi->bios_rom, "adaptec_aha1542c_bios_534201-00.bin", 0xd8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&scsi->bios_rom.mapping); + + addr = device_get_config_int("bios_addr"); + mem_mapping_add(&scsi->mapping, addr, 0x4000, + aha1542c_read, NULL, NULL, + aha1542c_write, NULL, NULL, + scsi->bios_rom.rom, 0, scsi); + + scsi->status = 0; + scsi->cmd_state = CMD_STATE_IDLE; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + + timer_add(aha154x_callback, &scsi->timer, TIMER_ALWAYS_ENABLED, scsi); + + addr = device_get_config_int("addr"); + io_sethandler(addr, 0x0004, + aha154x_in, NULL, NULL, + aha154x_out, NULL, NULL, + scsi); + for (c = 0; c < 8; c++) + { + if (port_sw_mapping[c] == addr) + { + scsi->dipsw = c; + break; + } + } + + scsi_bus_init(&scsi->bus); + + scsi->type = SCSI_AHA1542C; + + aha1542c_eeprom_load(scsi, "aha1542c.nvr"); + + scsi->host_id = scsi->eeprom[0] & 7; + scsi->dma = (scsi->eeprom[1] >> 4) & 7; + scsi->irq = (scsi->eeprom[1] & 7) + 9; + pclog("Init IRQ=%i DMA=%i ID=%i\n", scsi->irq, scsi->dma, scsi->host_id); + + return scsi; +} + +static void *scsi_bt545s_init(char *bios_fn) +{ + aha154x_t *scsi = malloc(sizeof(aha154x_t)); + uint32_t addr; + memset(scsi, 0, sizeof(aha154x_t)); + + addr = device_get_config_int("bios_addr"); + rom_init(&scsi->bios_rom, "BusLogic_BT-545S_U15_27128_5002026-4.50.bin", addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + scsi->bios_addr = addr; + + scsi->status = 0; + scsi->cmd_state = CMD_STATE_IDLE; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + + timer_add(aha154x_callback, &scsi->timer, TIMER_ALWAYS_ENABLED, scsi); + + addr = device_get_config_int("addr"); + io_sethandler(addr, 0x0004, + aha154x_in, NULL, NULL, + aha154x_out, NULL, NULL, + scsi); + + scsi_bus_init(&scsi->bus); + + scsi->type = SCSI_BT545S; + + scsi->host_id = device_get_config_int("host_id"); + scsi->dma = device_get_config_int("dma"); + scsi->irq = device_get_config_int("irq"); + + return scsi; +} + +static void scsi_aha1542c_close(void *p) +{ + aha154x_t *scsi = (aha154x_t *)p; + + scsi_bus_close(&scsi->bus); + + free(scsi); +} + +static int scsi_aha1542c_available() +{ + return rom_present("adaptec_aha1542c_bios_534201-00.bin"); +} + +static int scsi_bt545s_available() +{ + return rom_present("BusLogic_BT-545S_U15_27128_5002026-4.50.bin"); +} + +static device_config_t aha1542c_config[] = +{ + { + .name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "130", + .value = 0x130 + }, + { + .description = "134", + .value = 0x134 + }, + { + .description = "230", + .value = 0x230 + }, + { + .description = "234", + .value = 0x234 + }, + { + .description = "330", + .value = 0x330 + }, + { + .description = "334", + .value = 0x334 + }, + { + .description = "" + } + }, + .default_int = 0x334 + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "C8000", + .value = 0xc8000 + }, + { + .description = "CC000", + .value = 0xcc000 + }, + { + .description = "D0000", + .value = 0xd0000 + }, + { + .description = "D4000", + .value = 0xd4000 + }, + { + .description = "D8000", + .value = 0xd8000 + }, + { + .description = "DC000", + .value = 0xdc000 + }, + { + .description = "" + } + }, + .default_int = 0xdc000 + }, + { + .type = -1 + } +}; + +static device_config_t bt545s_config[] = +{ + { + .name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "130", + .value = 0x130 + }, + { + .description = "134", + .value = 0x134 + }, + { + .description = "230", + .value = 0x230 + }, + { + .description = "234", + .value = 0x234 + }, + { + .description = "330", + .value = 0x330 + }, + { + .description = "334", + .value = 0x334 + }, + { + .description = "" + } + }, + .default_int = 0x334 + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "C8000", + .value = 0xc8000 + }, + { + .description = "D8000", + .value = 0xd8000 + }, + { + .description = "DC000", + .value = 0xdc000 + }, + { + .description = "" + } + }, + .default_int = 0xdc000 + }, + { + .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 = 10 + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DMA 5", + .value = 5 + }, + { + .description = "DMA 6", + .value = 6 + }, + { + .description = "DMA 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .name = "host_id", + .description = "Host ID", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "ID 0", + .value = 0 + }, + { + .description = "ID 1", + .value = 1 + }, + { + .description = "ID 2", + .value = 2 + }, + { + .description = "ID 3", + .value = 3 + }, + { + .description = "ID 4", + .value = 4 + }, + { + .description = "ID 5", + .value = 5 + }, + { + .description = "ID 6", + .value = 6 + }, + { + .description = "ID 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .type = -1 + } +}; + +device_t scsi_aha1542c_device = +{ + "Adaptec AHA-1542C (SCSI)", + DEVICE_AT, + scsi_aha1542c_init, + scsi_aha1542c_close, + scsi_aha1542c_available, + NULL, + NULL, + NULL, + aha1542c_config +}; +device_t scsi_bt545s_device = +{ + "BusLogic BT-545S (SCSI)", + DEVICE_AT, + scsi_bt545s_init, + scsi_aha1542c_close, + scsi_bt545s_available, + NULL, + NULL, + NULL, + bt545s_config +}; diff --git a/src/scsi_aha1540.h b/src/scsi_aha1540.h new file mode 100644 index 0000000..d4db67d --- /dev/null +++ b/src/scsi_aha1540.h @@ -0,0 +1,2 @@ +extern device_t scsi_aha1542c_device; +extern device_t scsi_bt545s_device; From 64b1aa89ff9a89030e8435648ceffc000bcac1aa Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Oct 2017 16:29:22 +0100 Subject: [PATCH 0154/1050] Fixed header includes in scsi.c. --- src/scsi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scsi.c b/src/scsi.c index 01d4c98..27e806e 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -1,7 +1,6 @@ #include "ibm.h" #include "ide.h" #include "scsi.h" -#include "scsi_cd.h" #include "scsi_hd.h" #define STATE_IDLE 0 From 5d5b4dce8a47e6e991fbe9a9e4e17d2576000be5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 3 Oct 2017 17:31:14 +0100 Subject: [PATCH 0155/1050] Fixed typo in ncr5380_reset(). --- src/scsi_53c400.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi_53c400.c b/src/scsi_53c400.c index ad90245..476ec7b 100644 --- a/src/scsi_53c400.c +++ b/src/scsi_53c400.c @@ -107,7 +107,7 @@ static void ncr53c400_dma_changed(ncr5380_t *ncr, int mode, int enable) void ncr5380_reset(ncr5380_t *ncr) { - memset(ncr, 0, sizeof(ncr)); + memset(ncr, 0, sizeof(ncr5380_t)); } static uint32_t get_bus_host(ncr5380_t *ncr) From b5c8ad4bd62a7ebafc211924ffcf428e07b0e9b2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Oct 2017 16:59:32 +0100 Subject: [PATCH 0156/1050] Adaptec/BusLogic SCSI improvements - more commands, a few bug fixes --- src/scsi_aha1540.c | 133 +++++++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 40 deletions(-) diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index 43720a6..bb39379 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -93,6 +93,8 @@ typedef struct aha154x_t uint8_t isr_pending; uint8_t status; + int mbo_irq_enable; + uint8_t cmd_data; uint8_t data_in; @@ -118,6 +120,7 @@ typedef struct aha154x_t int bios_mbc; uint32_t bios_mba; int bios_mbo_req; + int bios_mbo_inited; cmd_state_t cmd_state; ccb_state_t ccb_state; @@ -187,6 +190,8 @@ typedef struct aha154x_t int scatter_gather; int bytes_transferred; } cdb; + + int reg3_idx; } aha154x_t; #define STATUS_INVDCMD 0x01 @@ -206,20 +211,22 @@ typedef struct aha154x_t #define ISR_HACC 0x04 #define ISR_ANYINTR 0x80 -#define COMMAND_NOP 0x00 -#define COMMAND_MAILBOX_INITIALIZATION 0x01 -#define COMMAND_START_SCSI_COMMAND 0x02 -#define COMMAND_START_BIOS_COMMAND 0x03 -#define COMMAND_ADAPTER_INQUIRY 0x04 -#define COMMAND_SET_SELECTION_TIMEOUT 0x06 -#define COMMAND_SET_BUS_ON_TIME 0x07 -#define COMMAND_SET_BUS_OFF_TIME 0x08 -#define COMMAND_SET_AT_BUS_SPEED 0x09 -#define COMMAND_RETURN_CONFIG_DATA 0x0b -#define COMMAND_RETURN_SETUP_DATA 0x0d -#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a -#define COMMAND_READ_CHANNEL_2_BUF 0x1b -#define COMMAND_ECHO 0x1f +#define COMMAND_NOP 0x00 +#define COMMAND_MAILBOX_INITIALIZATION 0x01 +#define COMMAND_START_SCSI_COMMAND 0x02 +#define COMMAND_START_BIOS_COMMAND 0x03 +#define COMMAND_ADAPTER_INQUIRY 0x04 +#define COMMAND_MAILBOX_OUT_IRQ_ENA 0x05 +#define COMMAND_SET_SELECTION_TIMEOUT 0x06 +#define COMMAND_SET_BUS_ON_TIME 0x07 +#define COMMAND_SET_BUS_OFF_TIME 0x08 +#define COMMAND_SET_AT_BUS_SPEED 0x09 +#define COMMAND_INQUIRE_INSTALLED_DEVICES 0x0a +#define COMMAND_RETURN_CONFIG_DATA 0x0b +#define COMMAND_RETURN_SETUP_DATA 0x0d +#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a +#define COMMAND_READ_CHANNEL_2_BUF 0x1b +#define COMMAND_ECHO 0x1f #define COMMAND_ADAPTEC_PROGRAM_EEPROM 0x22 #define COMMAND_ADAPTEC_RETURN_EEPROM_DATA 0x23 @@ -235,6 +242,8 @@ typedef struct aha154x_t #define COMMAND_BUSLOGIC_81 0x81 #define COMMAND_BUSLOGIC_84 0x84 #define COMMAND_BUSLOGIC_85 0x85 +#define COMMAND_BUSLOGIC_ADAPTER_MODEL_NR 0x8b +#define COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD 0x8c #define COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO 0x8d #define COMMAND_BUSLOGIC_STRICT_RR 0x8f #define COMMAND_BUSLOGIC_SET_CCB_FORMAT 0x96 @@ -267,9 +276,7 @@ static void process_cmd(aha154x_t *scsi); static void set_irq(aha154x_t *scsi, uint8_t val) { -// pclog("set_irq %02x %02x\n", scsi->isr, val); - if (!scsi->isr) - picint(1 << scsi->irq); + picint(1 << scsi->irq); scsi->isr |= val; } @@ -301,21 +308,20 @@ static void aha154x_out(uint16_t port, uint8_t val, void *p) scsi->scsi_state = SCSI_STATE_IDLE; scsi->mb_format = MB_FORMAT_4; scsi->current_mbi = 0; + scsi->mbo_irq_enable = 0; } if (val & CTRL_SRST) { scsi->isr = 0; clear_irq(scsi); - if (scsi->type == SCSI_BT545S) - scsi->status = STATUS_INIT; - else - scsi->status = 0; + scsi->status = STATUS_INIT; // pclog("software reset\n"); scsi->cmd_state = CMD_STATE_IDLE; scsi->ccb_state = CCB_STATE_IDLE; scsi->scsi_state = SCSI_STATE_IDLE; scsi->mb_format = MB_FORMAT_4; scsi->current_mbi = 0; + scsi->mbo_irq_enable = 0; } if (val & CTRL_IRST) { @@ -341,7 +347,7 @@ static void aha154x_out(uint16_t port, uint8_t val, void *p) // fatal("Write command reg while full\n"); scsi->status |= STATUS_CDF; scsi->cmd_data = val; - pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc); +// pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc); process_cmd(scsi); break; } @@ -379,7 +385,16 @@ static uint8_t aha154x_in(uint16_t port, void *p) if (scsi->type == SCSI_BT545S) temp = 0x29; /*BT-545S BIOS expects this to return not zero or 0xff for six consecutive reads*/ else - temp = 0xff; + { + scsi->reg3_idx++; + switch (scsi->reg3_idx & 3) + { + case 0: temp = 'A'; break; + case 1: temp = 'D'; break; + case 2: temp = 'A'; break; + case 3: temp = 'P'; break; + } + } break; } if (CS != 0xc800) @@ -564,6 +579,7 @@ static void process_cmd(aha154x_t *scsi) case COMMAND_NOP: case COMMAND_START_SCSI_COMMAND: case COMMAND_ADAPTER_INQUIRY: + case COMMAND_INQUIRE_INSTALLED_DEVICES: case COMMAND_RETURN_CONFIG_DATA: scsi->command_len = 0; break; @@ -587,6 +603,7 @@ static void process_cmd(aha154x_t *scsi) break; case COMMAND_ECHO: + case COMMAND_MAILBOX_OUT_IRQ_ENA: case COMMAND_SET_BUS_ON_TIME: case COMMAND_SET_BUS_OFF_TIME: case COMMAND_SET_AT_BUS_SPEED: @@ -617,6 +634,8 @@ static void process_cmd(aha154x_t *scsi) case COMMAND_BUSLOGIC_SET_CCB_FORMAT: case COMMAND_BUSLOGIC_STRICT_RR: case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: + case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR: + case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD: if (scsi->type == SCSI_BT545S) scsi->command_len = 1; else @@ -1053,6 +1072,12 @@ static void process_cmd(aha154x_t *scsi) scsi->result_len = 4; break; + case COMMAND_MAILBOX_OUT_IRQ_ENA: + scsi->mbo_irq_enable = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + case COMMAND_SET_SELECTION_TIMEOUT: scsi->e_d = scsi->params[0]; scsi->to = (scsi->params[1] << 8) | scsi->params[2]; @@ -1077,6 +1102,14 @@ static void process_cmd(aha154x_t *scsi) set_irq(scsi, ISR_HACC); scsi->cmd_state = CMD_STATE_IDLE; break; + + case COMMAND_INQUIRE_INSTALLED_DEVICES: + for (c = 0; c < 8; c++) + scsi->result[c] = scsi->bus.devices[c] ? 1 : 0; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 8; + break; case COMMAND_RETURN_CONFIG_DATA: scsi->result[0] = 1 << scsi->dma; @@ -1215,8 +1248,8 @@ static void process_cmd(aha154x_t *scsi) case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT: scsi->bios_mbc = scsi->params[0]; scsi->bios_mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); + scsi->bios_mbo_inited = 1; pclog("BIOS mailbox init: MBC=%02x MBC=%06x\n", scsi->bios_mbc, scsi->bios_mba); - scsi->status &= ~STATUS_INIT; set_irq(scsi, ISR_HACC); scsi->cmd_state = CMD_STATE_IDLE; break; @@ -1280,7 +1313,31 @@ static void process_cmd(aha154x_t *scsi) scsi->result_pos = 0; scsi->result_len = 1; break; - + + case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR: + scsi->result[0] = '5'; + scsi->result[1] = '4'; + scsi->result[2] = '2'; + scsi->result[3] = 'B'; + scsi->result[4] = 'H'; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 5); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD: + for (c = 0; c < 8; c++) + scsi->result[c] = 0; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 8); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: pclog("Extended setup info %i\n", scsi->params[0]); scsi->result[0] = 0x41; @@ -1359,9 +1416,7 @@ static void process_ccb(aha154x_t *scsi) switch (scsi->ccb_state) { case CCB_STATE_IDLE: - if (scsi->status & STATUS_INIT) - break; - if (scsi->mbo_req) + if (!(scsi->status & STATUS_INIT) && scsi->mbo_req) { // pclog("mbo_req %i\n", scsi->mbc); for (c = 0; c < scsi->mbc; c++) @@ -1395,7 +1450,7 @@ static void process_ccb(aha154x_t *scsi) scsi->mbo_req--; - set_irq(scsi, ISR_HACC); + //set_irq(scsi, ISR_HACC); break; } else if (command == COMMAND_ABORT_CCB) @@ -1423,12 +1478,12 @@ static void process_ccb(aha154x_t *scsi) scsi->current_mbi++; if (scsi->current_mbi >= scsi->mbc) scsi->current_mbi = 0; - set_irq(scsi, ISR_MBOA | ISR_MBIF | ISR_HACC); + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF | ISR_HACC); break; } } } - if (scsi->bios_mbo_req) + if (scsi->bios_mbo_inited && scsi->bios_mbo_req) { for (c = 0; c < scsi->bios_mbc; c++) { @@ -1529,9 +1584,9 @@ static void process_ccb(aha154x_t *scsi) scsi->current_mbi++; if (scsi->current_mbi >= scsi->mbc) scsi->current_mbi = 0; - set_irq(scsi, ISR_MBOA | ISR_MBIF); + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); } - else + else if (scsi->mbo_irq_enable) set_irq(scsi, ISR_MBOA); } // set_irq(scsi, ISR_HACC); @@ -1610,9 +1665,9 @@ static void process_ccb(aha154x_t *scsi) scsi->current_mbi++; if (scsi->current_mbi >= scsi->mbc) scsi->current_mbi = 0; - set_irq(scsi, ISR_MBOA | ISR_MBIF); + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); } - else + else if (scsi->mbo_irq_enable) set_irq(scsi, ISR_MBOA); } scsi->ccb_state = CCB_STATE_IDLE; @@ -1705,12 +1760,10 @@ static void process_ccb(aha154x_t *scsi) scsi->current_mbi++; if (scsi->current_mbi >= scsi->mbc) scsi->current_mbi = 0; - set_irq(scsi, ISR_MBOA | ISR_MBIF); + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); } - else + else if (scsi->mbo_irq_enable) set_irq(scsi, ISR_MBOA); - - set_irq(scsi, ISR_MBOA | ISR_MBIF); } // pclog("CCB_STATE_WAIT_REQUEST_SENSE over %i\n", scsi->ccb.from_mailbox); scsi->ccb_state = CCB_STATE_IDLE; @@ -1783,7 +1836,7 @@ static void process_scsi(aha154x_t *scsi) } bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); -// pclog(" Command send %02x\n", scsi->cdb.data[scsi->cdb.idx]); +// pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len); // if (!scsi->cdb.idx && scsi->cdb.data[scsi->cdb.idx] == 0x25 && scsi->current_mbo == 1) // output = 3; scsi->cdb.idx++; From ecbdad6b1a808d76dbe7112189e56fabe823fba8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Oct 2017 17:07:20 +0100 Subject: [PATCH 0157/1050] Added SCSI CD-ROM emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ide.h | 29 +- src/ide_atapi.h | 33 + src/scsi.c | 8 + src/scsi.h | 4 +- src/scsi_cd.c | 1142 +++++ src/scsi_cd.h | 1 + src/wx-resources.cpp | 6895 ++++++++++++++-------------- 18 files changed, 4596 insertions(+), 3538 deletions(-) create mode 100644 src/ide_atapi.h create mode 100644 src/scsi_cd.c create mode 100644 src/scsi_cd.h diff --git a/src/Makefile.am b/src/Makefile.am index f32ee7b..38e0145 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_hd.c \ +opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ serial.c sio.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 \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index b2ae4e0..69b2416 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -11,7 +11,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 8bd7ab0..347cc77 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index b0782ad..15cd4fe 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 5e783cb..525152b 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 7041ac5..4e3036f 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 ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index e790d8a..7cddda5 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index f3faf8d..d57f91d 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 3e3dcbe..4e7f135 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.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 um8881f.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 1068b10..4627e7d 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 ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 80cb44e..7efe58b 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -9,7 +9,7 @@ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ diff --git a/src/ide.h b/src/ide.h index 45de5e5..fc7936b 100644 --- a/src/ide.h +++ b/src/ide.h @@ -17,34 +17,7 @@ extern void ide_pri_disable(); extern void ide_sec_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)); -/*ATAPI stuff*/ -typedef struct ATAPI -{ - 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 maxlen); - uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); - int (*readsector)(uint8_t *b, int sector); - void (*readsector_raw)(uint8_t *b, int sector); - 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); -} ATAPI; - -extern ATAPI *atapi; - -void atapi_discchanged(); -void atapi_insert_cdrom(); +#include "ide_atapi.h" extern int ideboard; diff --git a/src/ide_atapi.h b/src/ide_atapi.h new file mode 100644 index 0000000..5530f1c --- /dev/null +++ b/src/ide_atapi.h @@ -0,0 +1,33 @@ +#ifndef __IDE_ATAPI__ +#define __IDE_ATAPI__ + +/*ATAPI stuff*/ +typedef struct ATAPI +{ + 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 maxlen); + uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); + int (*readsector)(uint8_t *b, int sector); + void (*readsector_raw)(uint8_t *b, int sector); + 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); +} ATAPI; + +extern ATAPI *atapi; + +void atapi_discchanged(); +void atapi_insert_cdrom(); + +#endif diff --git a/src/scsi.c b/src/scsi.c index 27e806e..b703700 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -1,6 +1,7 @@ #include "ibm.h" #include "ide.h" #include "scsi.h" +#include "scsi_cd.h" #include "scsi_hd.h" #define STATE_IDLE 0 @@ -337,6 +338,13 @@ void scsi_bus_init(scsi_bus_t *bus) if (!bus->device_data[c]) bus->devices[c] = NULL; } + else + { + bus->devices[c] = &scsi_cd; + bus->device_data[c] = bus->devices[c]->init(bus, c); + if (!bus->device_data[c]) + bus->devices[c] = NULL; + } } } diff --git a/src/scsi.h b/src/scsi.h index 4c2bdab..75ade74 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -16,6 +16,8 @@ typedef struct scsi_device_t int (*write_complete)(void *p); } scsi_device_t; +#define CDB_MAX_LEN 20 + typedef struct scsi_bus_t { int state; @@ -25,7 +27,7 @@ typedef struct scsi_bus_t int dev_id; int command_pos; - uint8_t command[20]; + uint8_t command[CDB_MAX_LEN]; scsi_device_t *devices[8]; void *device_data[8]; diff --git a/src/scsi_cd.c b/src/scsi_cd.c new file mode 100644 index 0000000..1f9e411 --- /dev/null +++ b/src/scsi_cd.c @@ -0,0 +1,1142 @@ +#include +#include +#include +#include +#include "ibm.h" +#include "ide_atapi.h" +#include "scsi.h" +#include "scsi_cd.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + + +#define BUFFER_SIZE (256*1024) + +#define MAX_NR_SECTORS 2 + +enum +{ + CMD_POS_IDLE = 0, + CMD_POS_WAIT, + CMD_POS_START_SECTOR, + CMD_POS_TRANSFER +}; + +/* ATAPI Commands */ +#define GPCMD_TEST_UNIT_READY 0x00 +#define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_READ_6 0x08 +#define GPCMD_INQUIRY 0x12 +#define GPCMD_MODE_SELECT_6 0x15 +#define GPCMD_MODE_SENSE_6 0x1a +#define GPCMD_START_STOP_UNIT 0x1b +#define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_CDROM_CAPACITY 0x25 +#define GPCMD_READ_10 0x28 +#define GPCMD_SEEK 0x2b +#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_PLAY_AUDIO_MSF 0x47 +#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a +#define GPCMD_PAUSE_RESUME 0x4b +#define GPCMD_STOP_PLAY_SCAN 0x4e +#define GPCMD_READ_DISC_INFORMATION 0x51 +#define GPCMD_MODE_SELECT_10 0x55 +#define GPCMD_MODE_SENSE_10 0x5a +#define GPCMD_PLAY_AUDIO_12 0xa5 +#define GPCMD_READ_12 0xa8 +#define GPCMD_SEND_DVD_STRUCTURE 0xad +#define GPCMD_SET_SPEED 0xbb +#define GPCMD_MECHANISM_STATUS 0xbd +#define GPCMD_READ_CD 0xbe + +/* Mode page codes for mode sense/set */ +#define GPMODE_R_W_ERROR_PAGE 0x01 +#define GPMODE_CDROM_PAGE 0x0d +#define GPMODE_CDROM_AUDIO_PAGE 0x0e +#define GPMODE_CAPABILITIES_PAGE 0x2a +#define GPMODE_ALL_PAGES 0x3f + +/* ATAPI Sense Keys */ +#define SENSE_NONE 0 +#define SENSE_NOT_READY 2 +#define SENSE_ILLEGAL_REQUEST 5 +#define SENSE_UNIT_ATTENTION 6 + +/* ATAPI 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_MEDIUM_MAY_HAVE_CHANGED 0x28 +#define ASC_MEDIUM_NOT_PRESENT 0x3a +#define ASC_DATA_PHASE_ERROR 0x4b +#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 + +#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 +#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 +#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 + +/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). + Not that it means anything */ +#define CDROM_SPEED 706 + +/* Event notification classes for GET EVENT STATUS NOTIFICATION */ +#define GESN_NO_EVENTS 0 +#define GESN_OPERATIONAL_CHANGE 1 +#define GESN_POWER_MANAGEMENT 2 +#define GESN_EXTERNAL_REQUEST 3 +#define GESN_MEDIA 4 +#define GESN_MULTIPLE_HOSTS 5 +#define GESN_DEVICE_BUSY 6 + +/* Event codes for MEDIA event status notification */ +#define MEC_NO_CHANGE 0 +#define MEC_EJECT_REQUESTED 1 +#define MEC_NEW_MEDIA 2 +#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ +#define MEC_MEDIA_CHANGED 4 /* only for media changers */ +#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ +#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ +#define MS_TRAY_OPEN 1 +#define MS_MEDIA_PRESENT 2 + +#define CHECK_READY 2 +#define ALLOW_UA 1 + +/* Table of all ATAPI commands and their flags, needed for the new disc change / not ready handler. */ +static uint8_t atapi_cmd_table[0x100] = +{ + [GPCMD_TEST_UNIT_READY] = CHECK_READY, + [GPCMD_REQUEST_SENSE] = ALLOW_UA, + [GPCMD_READ_6] = CHECK_READY, + [GPCMD_INQUIRY] = ALLOW_UA, + [GPCMD_MODE_SELECT_6] = 0, + [GPCMD_MODE_SENSE_6] = 0, + [GPCMD_START_STOP_UNIT] = 0, + [GPCMD_PREVENT_REMOVAL] = CHECK_READY, + [GPCMD_READ_CDROM_CAPACITY] = CHECK_READY, + [GPCMD_READ_10] = CHECK_READY, + [GPCMD_SEEK] = CHECK_READY, + [GPCMD_READ_SUBCHANNEL] = CHECK_READY, + [GPCMD_READ_TOC_PMA_ATIP] = CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS */ + [GPCMD_READ_HEADER] = CHECK_READY, + [GPCMD_PLAY_AUDIO_10] = CHECK_READY, + [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_MODE_SELECT_10] = 0, + [GPCMD_MODE_SENSE_10] = 0, + [GPCMD_PLAY_AUDIO_12] = CHECK_READY, + [GPCMD_READ_12] = CHECK_READY, + [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY, /* Read DVD structure (NOT IMPLEMENTED YET) */ + [GPCMD_SET_SPEED] = 0, + [GPCMD_MECHANISM_STATUS] = 0, + [GPCMD_READ_CD] = CHECK_READY, + [0xBF] = CHECK_READY /* Send DVD structure (NOT IMPLEMENTED YET) */ +}; + +#define IMPLEMENTED 1 + +static 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 mode_pages_in[256][256]; +#define PAGE_CHANGEABLE 1 +#define PAGE_CHANGED 2 +static 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, +}; + +extern int cd_status; + +typedef struct scsi_cd_data_t +{ + uint8_t data_in[BUFFER_SIZE]; + uint8_t data_out[BUFFER_SIZE]; + + int blocks; + + int cmd_pos; + + int addr, len; + int sector_pos; + + uint8_t buf[512]; + + uint8_t status; + + int data_pos_read, data_pos_write; + int data_bytes_read, bytes_expected; + + int cdlen, cdpos; + + int bytes_received, bytes_required; + + + int sense_key, asc, ascq; + + int id; + + + int received_cdb; + uint8_t cdb[CDB_MAX_LEN]; + + int prev_status; + int cd_status; + + uint8_t prefix_len; + uint8_t page_current; + +} scsi_cd_data_t; + +static void scsi_add_data(scsi_cd_data_t *data, uint8_t val) +{ + data->data_in[data->data_pos_write++] = val; + data->bytes_expected++; +} + +static void atapi_cmd_error(scsi_cd_data_t *data, int sensekey, int asc, int ascq) +{ + data->status = STATUS_CHECK_CONDITION; + data->sense_key = sensekey; + data->asc = asc; + data->ascq = ascq; +} + +static void atapi_sense_clear(scsi_cd_data_t *data, int command, int ignore_ua) +{ + if ((data->sense_key == SENSE_UNIT_ATTENTION) || ignore_ua) + { + data->sense_key = 0; + data->asc = 0; + data->ascq = 0; + } +} + +static int atapi_event_status(uint8_t *buffer) +{ + uint8_t event_code, media_status = 0; + + if (buffer[5]) + { + media_status = MS_TRAY_OPEN; + atapi->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; + atapi->load(); + } + else if (buffer[4]==2) + { + event_code = MEC_EJECT_REQUESTED; + atapi->eject(); + } + } + + buffer[4] = event_code; + buffer[5] = media_status; + buffer[6] = 0; + buffer[7] = 0; + + return 8; +} + +static void ide_padstr8(uint8_t *buf, int buf_size, const char *src) +{ + int i; + + for (i = 0; i < buf_size; i++) { + if (*src != '\0') { + buf[i] = *src++; + } else { + buf[i] = ' '; + } + } +} + +static void *scsi_cd_init(scsi_bus_t *bus, int id) +{ + scsi_cd_data_t *data = malloc(sizeof(scsi_cd_data_t)); + memset(data, 0, sizeof(scsi_cd_data_t)); + + data->id = 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. */ + page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; + + return data; +} + +static void scsi_cd_close(void *p) +{ + scsi_cd_data_t *data = p; + + free(data); +} + +static void scsi_cd_illegal(scsi_cd_data_t *data) +{ + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INVALID_LUN, 0); +} + +/** + * Fill in ide->buffer with the output of the ATAPI "MODE SENSE" command + * + * @param pos Offset within the buffer to start filling in data + * + * @return Offset within the buffer after the end of the data + */ +static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t type) +{ + uint8_t *buf = (uint8_t *)data->data_in; +// pclog("ide_atapi_mode_sense %02X\n",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; +} + +static int scsi_cd_command(uint8_t *cdb, void *p) +{ + scsi_cd_data_t *data = p; + uint8_t rcdmode = 0; + int c; + int len; + int msf; + int pos=0; +// unsigned char temp; + uint32_t size; + int is_error; + 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; + + if (!data->received_cdb) + memcpy(data->cdb, cdb, CDB_MAX_LEN); + + if ((cdb[0] != SCSI_REQUEST_SENSE/* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) + { + pclog("non-zero LUN\n"); + /*Non-zero LUN - abort command*/ + scsi_cd_illegal(data); + return BUS_CD | BUS_IO; + } + + pclog("New CD command %02X %i\n", cdb[0], ins); + msf = cdb[1] & 2; + + is_error = 0; + + if (atapi->medium_changed()) + { + atapi_insert_cdrom(); + } + /*If UNIT_ATTENTION is set, error out with NOT_READY. + VIDE-CDD.SYS will then issue a READ_TOC, which can pass through UNIT_ATTENTION and will clear sense. + NT 3.1 / AZTIDECD.SYS will then issue a REQUEST_SENSE, which can also pass through UNIT_ATTENTION but will clear sense AFTER sending it back. + In any case, if the command cannot pass through, set our state to errored.*/ + if (!(atapi_cmd_table[cdb[0]] & ALLOW_UA) && data->sense_key == SENSE_UNIT_ATTENTION) + { +// fatal("atapi_cmd_error(ide, data->sense_key, data->asc);\n"); + is_error = 1; + } + /*Unless the command issued was a REQUEST_SENSE or TEST_UNIT_READY, clear sense. + This is important because both VIDE-CDD.SYS and NT 3.1 / AZTIDECD.SYS rely on this behaving VERY specifically. + VIDE-CDD.SYS will clear sense through READ_TOC, while NT 3.1 / AZTIDECD.SYS will issue a REQUEST_SENSE.*/ + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[0] != GPCMD_TEST_UNIT_READY)) + { + /* GPCMD_TEST_UNIT_READY is NOT supposed to clear sense! */ + atapi_sense_clear(data, cdb[0], 1); + } + + /*If our state has been set to errored, clear it, and return.*/ + if (is_error) + { +// fatal("Clear error state\n"); + is_error = 0; + return SCSI_PHASE_STATUS; + } + + if ((atapi_cmd_table[cdb[0]] & CHECK_READY) && !atapi->ready()) + { + atapi_cmd_error(data, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); + return SCSI_PHASE_STATUS; + } + + data->prev_status = data->cd_status; + data->cd_status = atapi->status(); + if (((data->prev_status == CD_STATUS_PLAYING) || (data->prev_status == CD_STATUS_PAUSED)) && ((data->cd_status != CD_STATUS_PLAYING) && (data->cd_status != CD_STATUS_PAUSED))) + completed = 1; + else + completed = 0; + +// pclog(" msf %i completed %i\n", msf, completed); + + data->status = STATUS_GOOD; + + switch (cdb[0]) + { + case GPCMD_TEST_UNIT_READY: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case SCSI_REZERO_UNIT: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case SCSI_REQUEST_SENSE: /* Used by ROS 4+ */ +// pclog("CD REQ SENSE\n"); + alloc_length = cdb[4]; + temp_command = cdb[0]; + //atapi_command_send_init(ide, temp_command, 18, alloc_length); + + /*Will return 18 bytes of 0*/ + memset(data->data_in, 0, 512); + + data->data_in[0] = 0x80 | 0x70; + + if ((data->sense_key > 0) || (cd_status < CD_STATUS_PLAYING)) + { + if (completed) + { +// pclog("completed\n"); + data->data_in[2] = SENSE_ILLEGAL_REQUEST; + data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; + data->data_in[13] = ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; + } + else + { +// pclog("!completed %02x %02x %02x\n", data->sense_key, data->asc, data->ascq); + data->data_in[2] = data->sense_key; + data->data_in[12] = data->asc; + data->data_in[13] = data->ascq; + } + } + else + { + data->data_in[2] = SENSE_ILLEGAL_REQUEST; + data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; + data->data_in[13] = (cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + } + + //data->data_in[7] = 10; + data->data_in[7] = 0; + + /* Clear the sense stuff as per the spec. */ + atapi_sense_clear(data, temp_command, 0); + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, 18); + return SCSI_PHASE_DATA_IN; + + case SCSI_SEEK_6: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_SET_SPEED: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_MECHANISM_STATUS: /*0xbd*/ + alloc_length = (cdb[7]<<16) | (cdb[8]<<8) | cdb[9]; + + if (alloc_length == 0) + fatal("Zero allocation length to MECHANISM STATUS not impl.\n"); + + data->data_in[0] = 0; + data->data_in[1] = 0; + data->data_in[2] = 0; + data->data_in[3] = 0; + data->data_in[4] = 0; + data->data_in[5] = 1; + data->data_in[6] = 0; + data->data_in[7] = 0; + // len = 8; + + data->data_pos_read = 0; + data->bytes_expected = data->data_pos_write = alloc_length; + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_TOC_PMA_ATIP: +// pclog("Read TOC ready? %08X\n",ide); + toc_format = cdb[2] & 0xf; + if (toc_format == 0) + toc_format = (cdb[9] >> 6) & 3; + switch (toc_format) + { + case 0: /*Normal*/ +// pclog("ATAPI: READ TOC type requested: Normal\n"); + len = cdb[8] + (cdb[7] << 8); + len = atapi->readtoc(data->data_in, cdb[6], msf, len, 0); + break; + case 1: /*Multi session*/ +// pclog("ATAPI: READ TOC type requested: Multi-session\n"); + len = cdb[8] + (cdb[7] << 8); + len = atapi->readtoc_session(data->data_in, msf, len); + data->data_in[0] = 0; + data->data_in[1] = 0xA; + break; + case 2: /*Raw*/ +// pclog("ATAPI: READ TOC type requested: Raw TOC\n"); + len = cdb[8] + (cdb[7] << 8); + len = atapi->readtoc_raw(data->data_in, len); + break; + default: + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->data_pos_read = 0; + data->bytes_expected = data->data_pos_write = len; + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_CD: +// pclog("Read CD : start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n",cdb[2],cdb[3],cdb[4],cdb[5],cdb[6],cdb[7],cdb[8],cdb[9]); + rcdmode = cdb[9] & 0xF8; + if ((rcdmode != 0x10) && (rcdmode != 0xF8)) + { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + + if (data->cmd_pos == CMD_POS_IDLE) + { + data->cdlen = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + data->cmd_pos = CMD_POS_TRANSFER; + data->bytes_expected = data->cdlen * ((rcdmode == 0x10) ? 2048 : 2352); + } + if (!data->cdlen) + { + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + + for (c = 0; c < MAX_NR_SECTORS; c++) + { + if (rcdmode == 0x10) + { + if (atapi->readsector(&data->data_in[c*2048], data->cdpos)) + { +// pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + } + else + { + atapi->readsector_raw(&data->data_in[c*2352], data->cdpos); + } + data->cdpos++; + data->cdlen--; + if (!data->cdlen) + break; + } + readflash_set(READFLASH_HDC, data->id); + + data->data_pos_read = 0; + data->data_pos_write = c * ((rcdmode == 0x10) ? 2048 : 2352); + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: +// pclog("Read: cmd_pos=%i cdlen=%i %p\n", data->cmd_pos, data->cdlen, &data->data_in[0]); + +// readcdmode = 0; + if (data->cmd_pos == CMD_POS_IDLE) + { + if (cdb[0] == GPCMD_READ_6) + { + data->cdlen = cdb[4]; + data->cdpos = (((uint32_t)cdb[1] & 0x1f) << 16) | ((uint32_t)cdb[2] << 8) | (uint32_t)cdb[3]; + } + else if (cdb[0] == GPCMD_READ_10) + { + data->cdlen = (cdb[7] << 8) | cdb[8]; + data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + } + else + { + data->cdlen = ((uint32_t)cdb[6] << 24) | ((uint32_t)cdb[7] << 16) | ((uint32_t)cdb[8] << 8) | (uint32_t)cdb[9]; + data->cdpos = ((uint32_t)cdb[2] << 24) | ((uint32_t)cdb[3] << 16) | ((uint32_t)cdb[4] << 8) | (uint32_t)cdb[5]; + } +// pclog("cdpos=%08x cdlen=%08x\n", data->cdpos, data->cdlen); + + data->cmd_pos = CMD_POS_TRANSFER; + data->bytes_expected = data->cdlen * 2048; + } + + if (!data->cdlen) + { + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + readflash_set(READFLASH_HDC, data->id); + for (c = 0; c < MAX_NR_SECTORS; c++) + { + if (atapi->readsector(&data->data_in[c*2048], data->cdpos)) + { + pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->cdpos++; + data->cdlen--; + if (!data->cdlen) + break; + } + + data->data_pos_read = 0; + data->data_pos_write = c * 2048; + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_HEADER: + if (msf) + { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + for (c = 0; c < 4; c++) + data->data_in[c+4] = cdb[c+2]; + data->data_in[0] = 1; /*2048 bytes user data*/ + data->data_in[1] = data->data_in[2] = data->data_in[3] = 0; + + data->bytes_expected = data->data_pos_write = 6; + return SCSI_PHASE_DATA_IN; + + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + temp_command = cdb[0]; + + if (temp_command == GPCMD_MODE_SENSE_6) + len = cdb[4]; + else + len = cdb[8] | (cdb[7] << 8); + + c = cdb[2] & 0x3F; + + memset(data->data_in, 0, len); + alloc_length = len; + // for (c=0;cdata_in[0] = len - 1; + data->data_in[1] = 3; /*120mm data CD-ROM*/ + } + else + { + len = ide_atapi_mode_sense(data, 8, c); + data->data_in[0] = (len - 2)>>8; + data->data_in[1] = (len - 2)&255; + data->data_in[2] = 3; /*120mm data CD-ROM*/ + } + + data->bytes_expected = data->data_pos_write = len; + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_DATA_IN; + + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (data->cmd_pos == CMD_POS_IDLE) + { + int len; + + if (cdb[0] == GPCMD_MODE_SELECT_6) + { + len = cdb[4]; + data->prefix_len = 6; + } + else + { + len = (cdb[7]<<8) | cdb[8]; + data->prefix_len = 10; + } + data->page_current = cdb[2]; + if (page_flags[data->page_current] & PAGE_CHANGEABLE) + page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; + + data->cmd_pos = CMD_POS_TRANSFER; + data->bytes_required = len; + pclog("MODE_SELECT len=%i\n", len); + return SCSI_PHASE_DATA_OUT; + } + pclog("MODE_SELECT complete\n"); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: /*0x4a*/ + temp_command = cdb[0]; + alloc_length = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + + { + 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; + + struct __attribute__((__packed__)) + { + uint16_t len; + uint8_t notification_class; + uint8_t supported_events; + } *gesn_event_header; + unsigned int used_len; + + gesn_cdb = (void *)cdb; + gesn_event_header = (void *)data->data_in; + + /* 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_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + + /* 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 = atapi_event_status(data->data_in); + } + else + { + gesn_event_header->notification_class = 0x80; /* No event available */ + used_len = sizeof(*gesn_event_header); + } + len = used_len; + gesn_event_header->len = used_len - sizeof(*gesn_event_header); + } + + data->bytes_expected = data->data_pos_write = len; + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_DISC_INFORMATION: + data->data_in[1] = 32; + data->data_in[2] = 0xe; /* last session complete, disc finalized */ + data->data_in[3] = 1; /* first track on disc */ + data->data_in[4] = 1; /* # of sessions */ + data->data_in[5] = 1; /* first track of last session */ + data->data_in[6] = 1; /* last track of last session */ + data->data_in[7] = 0x20; /* unrestricted use */ + data->data_in[8] = 0x00; /* CD-ROM */ + + data->bytes_expected = data->data_pos_write = 34; + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_DATA_IN; + + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_12: + 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*/ + 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) || (cd_status <= CD_STATUS_DATA_ONLY) || + !atapi->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) + { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0); + return SCSI_PHASE_STATUS; + } + + atapi->playaudio(pos, len, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_READ_SUBCHANNEL: + if (cdb[3] != 1) + { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + pos = 0; + data->data_in[pos++] = 0; + data->data_in[pos++] = 0; /*Audio status*/ + data->data_in[pos++] = 0; data->data_in[pos++] = 0; /*Subchannel length*/ + data->data_in[pos++] = 1; /*Format code*/ + data->data_in[1] = atapi->getcurrentsubchannel(&data->data_in[5], msf); +// pclog("Read subchannel complete - audio status %02X\n",idebufferb[1]); + len = 11+5; + if (!(cdb[2] & 0x40)) len=4; + + data->bytes_expected = data->data_pos_write = len; + return SCSI_PHASE_DATA_IN; + + case GPCMD_START_STOP_UNIT: + if (cdb[4] != 2 && cdb[4] != 3 && cdb[4]) + { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + if (!cdb[4]) atapi->stop(); + else if (cdb[4] == 2) atapi->eject(); + else atapi->load(); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_INQUIRY: + page_code = cdb[2]; + max_len = cdb[4]; + alloc_length = max_len; + temp_command = cdb[0]; + + if (cdb[1] & 1) + { + preamble_len = 4; + size_idx = 3; + + data->data_in[idx++] = 05; + data->data_in[idx++] = page_code; + data->data_in[idx++] = 0; + + idx++; + + switch (page_code) + { + case 0x00: + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 0x83; + break; + + case 0x83: + if (idx + 24 > max_len) + { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_DATA_PHASE_ERROR, 0); + return SCSI_PHASE_STATUS; + } + data->data_in[idx++] = 0x02; + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 20; + ide_padstr8(data->data_in + idx, 20, "53R141"); /* Serial */ + idx += 20; + + if (idx + 72 > max_len) + { + goto atapi_out; + } + data->data_in[idx++] = 0x02; + data->data_in[idx++] = 0x01; + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 68; + ide_padstr8(data->data_in + idx, 8, "PCem"); /* Vendor */ + idx += 8; + ide_padstr8(data->data_in + idx, 40, "PCemCD v1.0"); /* Product */ + idx += 40; + ide_padstr8(data->data_in + idx, 20, "53R141"); /* Product */ + idx += 20; + break; + + default: + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return SCSI_PHASE_STATUS; + } + } + else + { + preamble_len = 5; + size_idx = 4; + + data->data_in[0] = 5; /*CD-ROM*/ + data->data_in[1] = 0x80; /*Removable*/ + data->data_in[2] = 0; + data->data_in[3] = 0x21; + data->data_in[4] = 31; + data->data_in[5] = 0; + data->data_in[6] = 0; + data->data_in[7] = 0; + + ide_padstr8(data->data_in + 8, 8, "PCem"); /* Vendor */ + ide_padstr8(data->data_in + 16, 16, "PCemCD"); /* Product */ + ide_padstr8(data->data_in + 32, 4, "1.0"); /* Revision */ + + idx = 36; + } + +atapi_out: + data->data_in[size_idx] = idx - preamble_len; + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, idx); + return SCSI_PHASE_DATA_IN; + + case GPCMD_PREVENT_REMOVAL: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_PAUSE_RESUME: + if (cdb[8] & 1) atapi->resume(); + else atapi->pause(); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_SEEK: + pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + atapi->seek(pos); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_READ_CDROM_CAPACITY: + size = atapi->size(); + scsi_add_data(data, (size >> 24) & 0xff); + scsi_add_data(data, (size >> 16) & 0xff); + scsi_add_data(data, (size >> 8) & 0xff); + scsi_add_data(data, size & 0xff); + scsi_add_data(data, (2048 >> 24) & 0xff); + scsi_add_data(data, (2048 >> 16) & 0xff); + scsi_add_data(data, (2048 >> 8) & 0xff); + scsi_add_data(data, 2048 & 0xff); + pclog("READ_CDROM_CAPACITY %08x\n", size); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_DATA_IN; + + case GPCMD_STOP_PLAY_SCAN: + atapi->stop(); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_SEND_DVD_STRUCTURE: + default: + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } +} + +static uint8_t scsi_cd_read(void *p) +{ + scsi_cd_data_t *data = p; + uint8_t temp; + + data->data_bytes_read++; + temp = data->data_in[data->data_pos_read++]; + + if (data->data_pos_read == data->data_pos_write && data->data_bytes_read < data->bytes_expected) + scsi_cd_command(data->cdb, data); + + return temp; +} + +static void scsi_cd_write(uint8_t val, void *p) +{ + scsi_cd_data_t *data = p; + + data->data_out[data->data_pos_write++] = val; + + data->bytes_received++; + + if (data->data_pos_write > BUFFER_SIZE) + fatal("Exceeded data_out buffer size\n"); +} + +static int scsi_cd_read_complete(void *p) +{ + scsi_cd_data_t *data = p; + + return (data->data_bytes_read == data->bytes_expected); +} +static int scsi_cd_write_complete(void *p) +{ + scsi_cd_data_t *data = p; + + return (data->bytes_received == data->bytes_required); +} + +static void scsi_cd_start_command(void *p) +{ + scsi_cd_data_t *data = p; + + data->bytes_received = 0; + data->bytes_required = 0; + data->data_pos_read = data->data_pos_write = 0; + data->data_bytes_read = data->bytes_expected = 0; + + data->received_cdb = 0; + + data->cmd_pos = CMD_POS_IDLE; + memset(data->data_in, 0, 256); +} + +static uint8_t scsi_cd_get_status(void *p) +{ + scsi_cd_data_t *data = p; + + return data->status; +} + +scsi_device_t scsi_cd = +{ + scsi_cd_init, + scsi_cd_close, + + scsi_cd_start_command, + scsi_cd_command, + + scsi_cd_get_status, + + scsi_cd_read, + scsi_cd_write, + scsi_cd_read_complete, + scsi_cd_write_complete, +}; diff --git a/src/scsi_cd.h b/src/scsi_cd.h new file mode 100644 index 0000000..77f81fb --- /dev/null +++ b/src/scsi_cd.h @@ -0,0 +1 @@ +extern scsi_device_t scsi_cd; diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 426c161..2445479 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1450,104 +1450,9 @@ static unsigned char xml_res_file_21[] = { 188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, 73,69,78,68,174,66,96,130}; -static size_t xml_res_size_22 = 1967; +static size_t xml_res_size_22 = 0; static unsigned char xml_res_file_22[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, -0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, -0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, -60,0,0,7,81,73,68,65,84,120,218,180,87,125,108,93,101,25,255,189,239,57, -231,158,115,123,215,142,174,235,166,67,35,84,199,24,100,72,157,153,102, -69,19,101,200,199,10,138,81,23,62,226,248,131,232,192,143,63,140,134,232, -152,134,65,130,136,35,209,108,134,96,52,33,58,194,103,22,65,182,105,153, -115,27,69,6,186,205,106,169,118,99,13,100,31,108,107,217,218,219,246,222, -123,190,94,127,207,57,231,94,110,187,22,70,19,79,250,244,124,190,239,243, -123,126,207,239,121,223,231,42,204,236,176,239,217,244,196,211,218,178, -191,104,140,57,231,65,74,41,196,81,248,135,159,124,107,213,87,120,27,38, -207,102,226,252,199,191,124,108,139,81,86,231,101,151,45,68,108,98,224, -92,48,208,147,86,26,61,61,7,161,76,244,199,245,223,189,249,198,42,136,247, -123,52,174,219,248,132,137,24,122,201,143,204,88,37,60,103,147,239,101, -156,140,151,121,146,104,102,0,192,139,163,8,126,16,97,231,129,195,120,31, -25,96,10,128,207,93,222,6,25,47,243,208,138,51,1,160,36,239,226,88,38,252, -124,123,91,250,212,212,254,77,123,252,229,192,0,162,216,48,109,166,150, -126,123,70,18,148,241,90,35,103,219,216,240,244,139,137,184,170,51,154, -42,144,58,106,228,42,166,227,101,139,62,76,231,152,240,206,158,160,106, -155,170,142,223,155,83,137,224,254,135,159,76,174,53,157,171,140,95,57, -59,249,60,114,141,205,116,24,163,90,33,166,202,140,50,233,243,122,69,139, -173,251,197,230,45,65,20,119,182,47,105,59,39,85,27,212,211,173,106,165, -164,180,194,254,125,125,152,93,240,176,232,162,11,17,69,239,128,144,67, -238,67,51,241,153,0,200,67,91,157,107,191,189,10,34,13,61,195,133,193,100, -118,245,21,237,184,247,161,223,225,206,175,173,64,16,198,117,116,43,116, -237,235,71,28,154,179,0,120,130,140,159,226,59,247,60,2,47,167,97,101,201, -172,165,19,117,247,117,41,172,221,115,114,201,92,16,25,108,248,225,55,18, -49,60,240,228,158,132,238,234,56,73,219,210,133,11,18,134,39,3,80,134,31, -86,2,96,78,99,30,207,12,182,35,159,83,112,93,11,142,235,80,104,10,185,156, -13,135,168,114,52,135,247,14,105,18,227,103,112,104,196,76,159,26,133,55, -186,8,34,130,34,26,91,219,48,74,242,157,6,167,50,109,133,209,217,0,32,159, -85,252,16,133,188,56,100,78,60,13,151,230,112,118,151,158,44,59,117,156, -0,208,25,0,58,182,45,3,135,115,217,58,141,48,239,57,168,84,66,58,176,176, -236,99,31,77,24,240,149,15,223,74,105,15,125,63,209,64,189,198,210,42,224, -135,101,63,34,253,14,148,99,193,114,53,108,57,231,44,222,11,0,154,165,161, -9,66,19,0,255,40,122,147,156,53,207,42,225,24,201,120,9,68,199,57,108,172, -204,135,72,224,246,134,65,172,220,180,129,78,35,108,89,179,134,139,16,166, -96,128,15,42,129,15,143,148,179,20,19,135,218,177,105,86,106,114,47,70, -6,136,35,209,136,156,73,50,108,1,34,139,75,168,224,145,129,50,1,196,124, -63,248,18,53,33,220,95,101,225,173,103,239,79,117,115,199,29,4,21,79,220, -88,170,50,42,83,4,110,46,199,168,117,226,84,217,86,10,134,215,182,45,233, -208,105,10,44,201,61,211,65,199,97,24,178,114,152,166,156,148,143,65,3, -47,202,126,133,121,30,199,218,171,142,241,28,33,240,207,224,229,237,111, -18,64,12,229,151,25,108,52,5,3,34,66,63,72,34,208,154,142,181,68,108,37, -105,176,115,233,57,164,211,33,31,40,177,140,134,75,97,34,42,19,48,223,4, -17,51,234,114,25,88,187,72,0,4,20,98,5,126,56,146,10,78,176,133,41,237, -134,206,35,238,33,6,147,0,200,203,50,197,227,50,135,154,220,38,121,167, -217,100,96,60,82,56,226,43,2,208,201,66,35,9,119,92,37,114,78,202,205,168, -52,133,82,243,13,174,147,4,34,1,69,178,225,196,172,36,237,37,244,135,113, -41,41,65,217,11,234,25,208,169,6,144,32,247,72,161,8,205,38,3,204,44,78, -86,98,156,162,243,88,4,200,242,176,36,69,212,134,164,71,89,86,2,72,68,169, -116,10,206,243,114,73,42,35,58,90,241,233,75,136,47,135,245,93,23,224,215, -175,44,193,103,150,93,76,192,54,129,68,103,3,16,105,86,18,13,56,201,162, -82,137,53,78,149,98,210,205,8,57,113,204,232,13,29,70,4,17,145,149,136, -14,35,233,110,152,174,88,89,100,129,227,56,185,231,230,201,128,204,167, -240,167,238,62,92,189,252,194,68,172,75,230,21,113,219,198,57,100,163,137, -197,96,79,40,195,26,3,227,204,163,67,6,138,140,250,72,49,68,49,80,24,165, -178,139,161,70,49,202,44,200,238,105,163,161,133,177,208,38,216,89,8,208, -204,168,230,160,208,48,31,81,88,224,164,77,184,161,99,49,118,252,237,76, -66,255,170,142,31,96,241,7,78,227,217,222,219,88,190,5,178,149,155,164, -1,89,136,40,40,103,182,139,61,95,151,9,178,149,221,72,209,142,191,179,218, -155,234,46,78,218,201,138,99,21,240,171,157,215,99,215,127,95,32,237,192, -186,231,146,229,0,134,243,47,95,127,107,242,105,178,0,234,2,174,251,196, -87,241,252,254,167,240,251,87,110,130,101,110,159,8,64,201,42,197,25,122, -14,191,141,127,30,26,154,176,202,79,215,241,40,82,111,171,38,108,239,123, -1,143,223,185,9,167,131,231,249,185,93,107,51,77,109,235,142,89,161,45, -232,61,254,20,174,255,228,45,216,214,179,25,253,56,51,1,128,25,29,29,233, -222,191,247,165,14,83,221,171,107,27,81,218,189,52,120,46,198,198,203,89, -199,1,82,237,161,84,14,57,184,9,138,141,85,49,56,141,61,253,91,147,215, -106,170,173,91,61,7,97,189,247,228,102,172,92,186,26,78,238,81,156,185, -23,191,233,90,135,27,5,64,249,183,15,220,245,77,158,231,214,53,40,106,249, -149,157,139,190,240,229,91,55,148,34,229,46,189,252,34,28,62,62,84,155, -180,237,131,45,216,119,224,16,154,189,185,248,215,32,48,26,29,227,230,48, -125,31,88,235,150,104,7,135,30,199,167,22,95,138,151,251,122,59,165,21, -16,135,37,218,155,180,147,117,1,120,43,190,116,75,151,202,55,192,229,98, -50,171,177,128,43,23,180,214,250,192,83,197,113,184,121,15,33,171,64,142, -146,57,202,253,99,250,30,223,100,171,175,150,77,203,170,96,239,161,94,84, -70,176,83,26,40,59,235,205,139,153,85,143,57,126,16,224,146,15,205,199, -200,88,9,7,95,63,130,254,58,49,72,15,216,58,247,60,52,55,180,2,39,128,138, -117,20,110,97,10,0,38,21,97,24,164,183,22,189,13,28,1,250,246,125,22,59, -239,219,253,61,62,10,166,107,74,237,144,43,221,249,173,179,241,145,243, -91,49,52,60,198,42,9,106,85,224,58,14,90,102,55,66,7,14,230,235,118,252, -236,209,191,167,59,226,100,255,226,156,225,173,190,41,29,58,240,6,240,218, -222,14,52,15,175,238,6,118,15,10,121,211,1,8,255,253,143,238,239,179,149, -248,249,210,37,23,163,253,210,54,52,53,53,162,138,96,100,164,136,158,215, -6,240,106,207,235,56,177,235,227,63,218,181,109,255,171,211,244,228,206, -53,63,197,54,39,15,244,31,4,118,108,199,238,23,31,236,94,15,116,191,197, -119,195,226,103,186,180,113,8,22,180,204,91,176,240,186,155,215,220,61, -235,188,150,142,180,91,54,217,26,192,69,106,120,168,123,235,99,15,223,55, -116,242,216,0,31,142,72,207,57,197,60,205,43,31,196,127,58,174,0,254,186, -3,67,127,190,27,215,242,217,241,204,121,233,221,0,200,10,233,138,22,104, -243,104,77,147,126,67,132,153,83,17,238,219,82,73,211,48,48,239,134,135, -112,130,26,24,217,122,23,174,225,253,97,218,96,61,216,247,250,113,106,103, -108,184,147,26,102,209,117,165,26,197,187,140,111,166,93,144,205,115,148, -118,74,132,55,233,55,235,255,245,144,69,191,33,187,30,155,236,92,142,255, -9,48,0,241,195,153,86,37,156,12,221,0,0,0,0,73,69,78,68,174,66,96,130}; +}; static size_t xml_res_size_23 = 2051; static unsigned char xml_res_file_23[] = { @@ -1722,7 +1627,7 @@ static unsigned char xml_res_file_24[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_25 = 128231; +static size_t xml_res_size_25 = 128075; static unsigned char xml_res_file_25[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -1735,104 +1640,103 @@ static unsigned char xml_res_file_25[] = { 61,34,50,46,53,46,51,46,48,34,62,10,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101, 61,34,66,73,84,77,65,80,95,72,65,82,68,68,73,83,75,34,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, -110,115,95,49,54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47, -111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34, -66,73,84,77,65,80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, -54,120,49,54,95,100,105,115,107,101,116,116,101,46,112,110,103,60,47,111, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,100,114,105,118,101,46,112,110,103,60,47,111,98,106,101, +99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65, +80,95,70,76,79,80,80,89,34,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,100,105,115, +107,101,116,116,101,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,34,32,110,97,109,101,61,34,66,73,84,77,65,80,95,67,68,82,79, +77,34,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,99,100,46,112,110,103,60,47,111, 98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,105,116,109,97,112,34,32,110,97,109,101,61,34,66,73, -84,77,65,80,95,67,68,82,79,77,34,62,119,120,45,114,101,115,111,117,114, -99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54,120, -49,54,95,99,100,46,112,110,103,60,47,111,98,106,101,99,116,62,10,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,111,111, -108,66,97,114,34,32,110,97,109,101,61,34,116,111,111,108,95,98,97,114,34, -62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,84,66,95,70,76,65,84, -124,119,120,84,66,95,78,79,68,73,86,73,68,69,82,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116, -111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,82,85,78, -34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110, -115,95,50,52,120,50,52,95,112,108,97,121,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,117,110,60, -47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,116,111, -111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65,82,95,80,65,85,83, -69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, -110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97, -117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, -82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48, -45,105,99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110, +115,61,34,119,120,84,111,111,108,66,97,114,34,32,110,97,109,101,61,34,116, +111,111,108,95,98,97,114,34,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,66,95,70,76,65,84,124,119,120,84,66,95,78,79,68,73,86,73,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61, +34,84,79,79,76,66,65,82,95,82,85,78,34,62,10,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,50,52,120,50,52,95,112,108,97,121,46,112,110, 103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, +108,62,82,117,110,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66, +65,82,95,80,65,85,83,69,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,50,52,120,50,52,95,112,97,117,115,101,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,97,117,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76, -66,65,82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -48,48,48,45,105,99,111,110,115,95,50,52,120,50,52,95,114,101,102,114,101, -115,104,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,60,108,97,98,101,108,62,72,97,114,100,32,114,101,115,101,116,60,47,108, -97,98,101,108,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95, -70,79,82,77,65,84,34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32, -32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77, -95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,34,32,115,116,97,114,116,61, -34,57,57,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,34,32,115,116,97,114,116, -61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,34, -32,115,116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,105,100,115, -45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, -67,65,76,69,34,32,115,116,97,114,116,61,34,49,50,48,48,34,47,62,10,32,32, -60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,95,77,79,68,69,34,32,115,116,97,114,116,61,34, -49,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73, -86,69,82,34,32,115,116,97,114,116,61,34,49,52,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83, -78,68,95,66,85,70,34,32,115,116,97,114,116,61,34,50,48,48,48,34,47,62,10, -32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34, -32,115,116,97,114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115, -45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, -76,51,95,73,78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34, -51,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, -95,82,69,70,82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51, -50,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116, -97,116,117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97, -99,116,105,118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -77,65,67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97, -116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, -104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95, -83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +66,65,82,95,83,84,79,80,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,50,52,120,50,52,95,115,116,111,112,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,116,111,111,108,34,32,110,97,109,101,61,34,84,79,79,76,66,65, +82,95,82,69,83,69,84,34,62,10,32,32,32,32,32,32,60,98,105,116,109,97,112, +62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99, +111,110,115,95,50,52,120,50,52,95,114,101,102,114,101,115,104,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,97,114,100,32,114,101,115,101,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84, +34,32,115,116,97,114,116,61,34,57,53,48,34,47,62,10,32,32,60,105,100,115, +45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,83,79,76,85,84,73,79,78,34,32,115,116,97,114,116,61,34,57,57,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,70,83,34,32,115,116,97,114,116,61,34,49,48,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,34,32,115,116,97,114, +116,61,34,49,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,34,32, +115,116,97,114,116,61,34,49,50,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67, +65,76,69,95,77,79,68,69,34,32,115,116,97,114,116,61,34,49,51,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,32,115, +116,97,114,116,61,34,49,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114, +97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70, +34,32,115,116,97,114,116,61,34,50,48,48,48,34,47,62,10,32,32,60,105,100, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34,32,115,116,97, +114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73, +78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,51,49,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70, +82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51,50,48,48,34, +47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, +117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, +118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, +67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, +84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, +98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, 83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, 60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, @@ -2509,39 +2413,239 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, 100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110, -115,95,51,50,120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, -65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, +108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, +85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, +105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -2568,8 +2672,91 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32, +115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, +61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, +120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, 62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, 65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, @@ -2584,290 +2771,17 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,115, -101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, -97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, -110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110, -97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, -100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111, -114,121,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67,116, -114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, -75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109, -105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, -77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, 105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, -79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, @@ -2878,267 +2792,44 @@ static unsigned char xml_res_file_25[] = { 60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, -122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, -99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, -99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45, -105,99,111,110,115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111, -100,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, -86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, -62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, -60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, -120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, +67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, +32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82, -69,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54, -120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -112,101,101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, -98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, -83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79, -79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111, -32,71,114,97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79, -79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54, -120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99, -116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, -110,115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, 98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, 108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, @@ -3197,6 +2888,218 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, +73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, 67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, 67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, @@ -3224,62 +3127,24 @@ static unsigned char xml_res_file_25[] = { 34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, 97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105, -110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116, -101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60, -47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3288,31 +3153,31 @@ static unsigned char xml_res_file_25[] = { 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -3326,9 +3191,9 @@ static unsigned char xml_res_file_25[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, -97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, +115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, @@ -3345,36 +3210,217 @@ static unsigned char xml_res_file_25[] = { 60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, +83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, +73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, @@ -3384,349 +3430,206 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, 114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,72, +68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115, +111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120, +49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, -111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50, -95,100,114,105,118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, -34,80,65,78,69,76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84, -82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, -119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, -112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, -98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, -97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, -111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,72,68,68,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,79,77,66,79,72,68,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, -124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, -116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, -85,82,69,72,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, -114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99, -111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111, -111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,68,68,49,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, +79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,65,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, -98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, -68,82,65,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, -66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,68,68,50,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,66,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, -124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,68,82,66,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,73,95,72,79, +82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, 111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120,65, 76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,76,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,73,95, -72,79,82,73,90,79,78,84,65,76,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,32,124,32,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, -111,105,99,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72, -66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,111, +105,99,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72,66, +95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,49,32, +40,67,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107, -112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,49, -32,40,67,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, -101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, -97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3859,495 +3762,7 @@ static unsigned char xml_res_file_25[] = { 116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, -110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, -101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, -105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, -54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, -48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, -51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, -124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,72,68,68,95,76,65,66,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,48,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, -66,69,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,72,80,67,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, -34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,52,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, -101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, -78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69, -88,84,95,83,73,90,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68, -67,95,80,65,78,69,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, -62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, -47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, -111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, -109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,48,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, -112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,91, -49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114,100,32, -100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, -111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, -82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108, -117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, -62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, 54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, 98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, @@ -4371,233 +3786,145 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, 111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, 116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45, -105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91, -49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105, -108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, -54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, -48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99,111,110,116, +114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105,116,109,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,106, +101,99,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, -51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, -124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,72,68,68,95,76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, -124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,69,68,73,84,95,72,80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,52,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, -108,105,110,100,101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4618,7 +3945,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, -95,67,89,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, 97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, @@ -4638,9 +3965,9 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93,34,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47, 108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, 97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, @@ -4661,122 +3988,33 @@ static unsigned char xml_res_file_25[] = { 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,49,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104,111,105,99,101, -98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105, -118,101,32,51,32,40,69,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,91,50,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, -83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111, -119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, -98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76, -65,66,69,76,91,50,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73, -68,67,95,72,68,68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47, -118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, +66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, @@ -4793,10 +4031,163 @@ static unsigned char xml_res_file_25[] = { 98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,68,82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90, +69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, +111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, +76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, 60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4805,52 +4196,75 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87, -91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111, -110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, 116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, @@ -4859,34 +4273,34 @@ static unsigned char xml_res_file_25[] = { 114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32, +109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, 116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, 109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, -101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, 120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,50,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +76,91,49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, 70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4906,7 +4320,7 @@ static unsigned char xml_res_file_25[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, 95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, @@ -4929,75 +4343,162 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, -54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, -48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, -51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, -124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,72,68,68,95,76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, +32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, 60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -5018,7 +4519,7 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5039,162 +4540,76 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69, -68,73,84,95,72,80,67,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,52,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110, -100,101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76, -91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,50,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,84,69,88,84,95,83,73,90,69,91,50,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103, -101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,52,32,40,70,58, -41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48, -60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, -34,73,68,67,95,80,65,78,69,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,51,32,40,69,58,41, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, +47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, 97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, 48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5215,7 +4630,7 @@ static unsigned char xml_res_file_25[] = { 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,48,93,34, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,48,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47, 115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5255,7 +4670,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, 111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, 108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5281,7 +4696,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, 111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, -82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, 98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5316,89 +4731,575 @@ static unsigned char xml_res_file_25[] = { 114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,51,93,34, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, 62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, -54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, +117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, 98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, -116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45, -105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91, -51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105, -108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50, +53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, -82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, +73,90,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, +111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,114,105,118,101,32,52,32,40,70,58,41,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, +76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, +60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5419,72 +5320,159 @@ static unsigned char xml_res_file_25[] = { 110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49, -54,120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, -48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, -51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, -124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,72,68,68,95,76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, +32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, 60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -5505,7 +5493,7 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -5526,373 +5514,271 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32, -124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, -67,95,69,68,73,84,95,72,80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,52,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, -108,105,110,100,101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, -95,67,89,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,51,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, -111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50, -95,109,111,117,115,101,95,112,99,46,112,110,103,60,47,98,105,116,109,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, -120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, -98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117, -115,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,77,79,85, -83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, -80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50, -95,110,101,116,119,111,114,107,95,101,116,104,101,114,110,101,116,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,32,110,97,109,101,61,34,109,95,112,97,110,101,108, -110,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,109,111,117,115,101,95,112,99,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,32,110,97,109,101,61,34,109,95,115,116,97,116,105,99,84,101,120,116, -55,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,78,101,116,119,111,114,107,32,99,97,114,100,32,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,117,115,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,77,79,85,83,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,110,101,116,119,111,114,107,95,101,116,104,101, +114,110,101,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109, +95,112,97,110,101,108,110,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, +86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116,97,116, +105,99,84,101,120,116,55,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114,107,32,99, +97,114,100,32,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,67,65,82,68,34, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, -110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,67,79,78,70,73,71,85,82,69,95,78,69,84,67,65,82,68,34,62,10,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45, -114,101,115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99, -111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111, -111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, +69,84,67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, -79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, -80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, -48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, -68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60, -47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,95,78,69,84, +67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, +85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103, +95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, 105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, @@ -5902,195 +5788,179 @@ static unsigned char xml_res_file_25[] = { 98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,72,100,78,101,119,68,108,103,34,62,10,32,32,32,32,60,116, -105,116,108,101,62,78,101,119,32,72,97,114,100,32,68,105,115,99,60,47,116, -105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, -49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, -97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, -120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34, +32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100,32,68,105,115, +99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, +101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, +68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82, +65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, -68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,49,54,120,49,54, -95,102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, -80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, -48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, -119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, -86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, -109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, -65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100, -115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47,108, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108, 97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -6104,7 +5974,7 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, 114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, -116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51, +116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, @@ -6120,91 +5990,101 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109, -98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, -111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, +122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, 60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6213,6 +6093,26 @@ static unsigned char xml_res_file_25[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, @@ -6630,95 +6530,94 @@ static unsigned char xml_res_file_25[] = { 32,60,116,111,111,108,116,105,112,62,76,111,97,100,60,47,116,111,111,108, 116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50,95,99, -111,110,116,114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, -70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114, -101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110, -115,95,51,50,120,51,50,95,115,101,116,116,105,110,103,95,116,111,111,108, -115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, -101,61,34,73,68,67,95,67,79,78,70,73,71,95,72,79,83,84,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -48,48,48,45,105,99,111,110,115,95,51,50,120,51,50,95,119,105,100,101,115, -99,114,101,101,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,110,116, +114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, -82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,78,101,119,60, -47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51, -50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, +95,72,79,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +119,105,100,101,115,99,114,101,101,110,46,112,110,103,60,47,98,105,116, +109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85, +95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, 102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6737,123 +6636,179 @@ static unsigned char xml_res_file_25[] = { 32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97,109,101,60,47, 116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50, -120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80, -89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,116,111,111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108, -116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,48,48,48,45,105,99,111,110,115,95,51,50,120,51,50,95,99, -111,109,112,117,116,101,114,95,103,111,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, -108,116,105,112,62,68,101,108,101,116,101,60,47,116,111,111,108,116,105, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116, -101,114,95,100,101,108,101,116,101,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, -85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117, -105,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51, -50,95,100,111,111,114,95,105,110,46,112,110,103,60,47,98,105,116,109,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97, -100,101,114,77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60, -115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, -95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115, -116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109, -32,83,104,97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116, -108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47, -99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, -61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, +99,111,109,112,117,116,101,114,95,101,100,105,116,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80,89,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101, +114,95,103,111,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, -114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, +84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,68,101, +108,101,116,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,100,101,108, +101,116,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79, +68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117,105,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,111,111,114, +95,105,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97,100,101,114, +77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,32,83,104, +97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73, +78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34, -32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66, -95,83,73,78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111, -114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, +70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,46,46, +46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,85,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,111,118,101,32,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, @@ -6861,10 +6816,17 @@ static unsigned char xml_res_file_25[] = { 100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118, +101,32,100,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, @@ -6873,154 +6835,91 @@ static unsigned char xml_res_file_25[] = { 60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, -109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105, -103,117,114,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79, -86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,77,111,118,101,32,117,112,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,111,118,101,32,100,111,119,110,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,112,112, +108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -65,112,112,108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, -76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105, -97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82, -101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, -108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, -76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, -101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116, -105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, -49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, -97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81, -85,69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116, -61,34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, +108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82,101, +109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, +47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85, +69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61, +34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, @@ -7316,147 +7215,161 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, 47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115, -111,117,114,99,101,115,46,99,112,112,36,48,48,48,45,105,99,111,110,115, -95,51,50,120,51,50,95,110,101,116,119,111,114,107,95,101,116,104,101,114, -110,101,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, -34,109,95,112,97,110,101,108,49,57,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65, -66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120, +51,50,95,110,101,116,119,111,114,107,95,101,116,104,101,114,110,101,116, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109,95,112, +97,110,101,108,49,57,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, +86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, -114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116, +97,116,105,99,84,101,120,116,55,50,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,101,116,119,111,114,107,32,116,121,112,101,32,58,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, +69,84,87,79,82,75,95,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, +65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,53,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,109,95,115,116,97,116,105,99,84,101,120, +116,55,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114, +107,32,100,101,118,105,99,101,32,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,87,79,82,75,95, +68,69,86,73,67,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,67,111, +109,98,111,33,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,109,95,115,116,97,116,105,99,84,101,120,116,55,50,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,78,101,116,119,111,114,107,32,116,121,112,101, -32,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,95,78,69,84,87,79,82,75,95,84,89,80,69,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, -120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,53,53,48,44,45,49,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116,97,116, -105,99,84,101,120,116,55,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101, -116,119,111,114,107,32,100,101,118,105,99,101,32,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,87, -79,82,75,95,68,69,86,73,67,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,53,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,62,67,111,109,98,111,33,60,47,118,97,108,117,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, -111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76, -60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, -97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, 119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,116,100,68,105,97,108,111,103,66,117,116,116,111,110,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,100,68,105,97,108, +111,103,66,117,116,116,111,110,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78, +84,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,98,117,116,116, 111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, @@ -7465,35 +7378,21 @@ static unsigned char xml_res_file_25[] = { 32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, -110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,98,117,116,116,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, -68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, -59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, -98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; void InitXmlResource() { @@ -7508,29 +7407,29 @@ void InitXmlResource() else wxFileSystem::AddHandler(new wxMemoryFSHandler); } - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_network_ethernet.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_control_play_blue.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_setting_tools.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$000-icons_32x32_computer_go.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive.png"), xml_res_file_0, xml_res_size_0, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_diskette.png"), xml_res_file_1, xml_res_size_1, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_cd.png"), xml_res_file_2, xml_res_size_2, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_play.png"), xml_res_file_3, xml_res_size_3, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_pause.png"), xml_res_file_4, xml_res_size_4, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_stop.png"), xml_res_file_5, xml_res_size_5, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_24x24_refresh.png"), xml_res_file_6, xml_res_size_6, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_motherboard.png"), xml_res_file_7, xml_res_size_7, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_setting_tools.png"), xml_res_file_8, xml_res_size_8, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_go.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_24, xml_res_size_24, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); From 72c6716f4937d244e35652b0ce30828b34a093d6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Oct 2017 09:46:05 +0100 Subject: [PATCH 0158/1050] Fix missing icons in wx GUI. --- src/icons/16x16/computer_go.png | Bin 0 -> 795 bytes src/icons/32x32/computer_go.png | Bin 0 -> 1967 bytes src/wx-resources.cpp | 99 +++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/icons/16x16/computer_go.png create mode 100644 src/icons/32x32/computer_go.png diff --git a/src/icons/16x16/computer_go.png b/src/icons/16x16/computer_go.png new file mode 100644 index 0000000000000000000000000000000000000000..2cf1c6bc03f10bb8091e69c5182852cb43cb786b GIT binary patch literal 795 zcmV+$1LXXPP)P{ULr+0s5K09Fm0dOj1L?w24`IDT1VuzgihSd}RT)hVSB&XSlbWB`ZYxZU=|UNgp#=gWssoU~cu z%&|%$GN4#>UOZO~Zc6an&TJ2|Jch|=vy+}G?zQ!zu4X?nGD-F|N+1GBR??|7${WWK z3aZG3K2)Aq`{-ojayAcSw5GYU) z40`EV2w!jme1Rf(y&fo3e_hpOY$_N;PihB=d&z+U#j?AUNW8XR5 zo9Tlj6@yB#Cds%D)#WFEXct-sYpCqAL_iLf5-BLod?cw0v6MiD1Ete_czB@&@l3z1 zBuR+#5JqOYaAfBxym;4%G0fOgK}En!j6CW0W3}&g&2?6u`Psv#oTcB(U3b3 zLRm>Mb;E`6sU;+S#jy~R7 z?5SkdKZn@tbZf_*hSmek7^Xn5b9>j0 zuIr{lBUHy2WJsNvW$&bufB|K-7?`52fmwA$CW&ps8qX>QwVdsIv zcpn*H3V_dD-Ub;j^U#Vj0iY!B;#em9e0y8^)YSe>d;I0V0HWA1ZKjrfdqxtJ@meEi z+t~2*i;1|ZGny)pI%?!9rsHLcK1}DB@Xnr~YMZK#-lzqgo-R%8WAU^Lj;#t^391EkP7_wl8TrCsiBN)2(Wyq_o2ReSMf+@UZBj3lT-{ zfRID(Lo@N20LVjIoom0n3L*_X!-c_QcJ&qQxc8yo;m)tEKoG`tbSrf2>qi`#vjBL4 zjGy8=_dEhGr(tEutfdom_jM_(-E(ruTo4&-_~ADaF+A|(o`mk|I7!>mg$ojfCj(H1 zA65cjPGcU=47MYmQ*d1ij_Xip3b~vOhp2KihxZO?660rZXv9pP8ihBy2qJp$S400RJd@ zlbkirD&ZK(cnL(uIc%)Vhe+V|hC!^{w1G||Y+190ix8$@fDbBx508|y6cdNqv1wLn zaxX>(h$GR6oJlfl0V0b_sNj)-G6BSVKll3bO;jL%yPjz$09Rw9m+*qnIDpLe* zF2|^K;#ApI3WnFVE$Pr{3M|Pz(?Q2!7_xGhrks?IK?5(!eua4+$J(oo@f;!W&*0_l zZxTQZ<(C<3Gz9}9LO)0%(3+05L~JE#uyg4-q|+fED6x!&OJO1^6ENQd5i{y?8CbhW z00b0b1%5b^3Qn+vDeZ>NBkmyvlK{xeGR5OEhnn0bd8gTAU_4Sd;wu8s$wDIucU&cM zPRh-wG=)<04X%>}A^}CR;l!*Y?IrYwaVaT5*$e6!(5VKHAoob22+bw~%q&h;Vw|G$ zSOm!Oup~v)hNMSXRsu*wsdNg?^KwZlBRX2~=}U+&hxJ_-;McD#!Dp6TOu#mQL}vpK zX;u;qILV??i8W4@V$#hBIdRPB4IM@V5s{UM4kPJqn66k^WP#&2x##A|fXt`xr|v#n zz5K#NtV`w7CXienYuJ3?|T7{-?<5=gXj6V zU28K-j9 z0aERuR1P_~35tzXF*uDq{acgQYO1YUJqKaE_vB`*T)G-g?oph%7r*IRhZ_Yz`L_?; z^-Z4V)-@<<`IViEzVPK+H2Fnu3b z>y~H-haShL7GH{&`+7U26%dCd+MBeKbpd!QzI02M$~VB}Vlu0-fGZcY*80Fx#c{ZK z4ab{bTwb-(;(=mQBm5VDF(`R7S8<8YnyK&5M~;k2!u2;F1r`$H-U-2VXye z{yH&857;{QJTy170w;iqbrf!43IHY*VHl*h7QGD|0s8iR7CZ0T{XISkrfW*=kSpE! zt+Vlw^II`AJjN;sYE|Gm4q9e6LI)1!>vsI?(Z8oV;$;8goZ+p$DIGfS2JqV64m1z1 z?gn-b3VG832><<$?(ege`1#T$7o+{sHZ(OgqKaT-q==r^2JmXn>o~FN<3HN9ZU3v& z^yJPpKgBjD5A+`dc5KJ)7a#0i4|Ko9cf;amy0mc!7PQP;u<*K@*W5kpyq1o%TQ=Dm zz(s0!sC(;U58pR*^4I_$j!4fr#XQX`AH;t;t^oeJ14Dnl8`tvL@yvPY-2li6>53L; z^JqC+4&2yA?N`yD*H|ziPkVU^CyB?eDT#o+ Date: Mon, 9 Oct 2017 22:04:22 +0100 Subject: [PATCH 0159/1050] Add joystick support to wx GUI. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ibm.h | 2 + src/icons/16x16/joystick.png | Bin 0 -> 714 bytes src/icons/32x32/joystick.png | Bin 0 -> 1208 bytes src/pc.xrc | 96 +++ src/scsi_aha1540.c | 2 - src/wx-config.c | 140 ++-- src/wx-joystickconfig.cc | 358 +++++++++ src/wx-joystickconfig.h | 15 + src/wx-resources.cpp | 1120 +++++++++++++++++----------- src/wx-sdl2-joystick.c | 152 +++- src/wx-sdl2.c | 2 + 17 files changed, 1388 insertions(+), 511 deletions(-) create mode 100644 src/icons/16x16/joystick.png create mode 100644 src/icons/32x32/joystick.png create mode 100644 src/wx-joystickconfig.cc create mode 100644 src/wx-joystickconfig.h diff --git a/src/Makefile.am b/src/Makefile.am index 38e0145..d8c4494 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,7 @@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc else pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO pcem_CXXFLAGS = diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 347cc77..184f352 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -23,7 +23,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 525152b..c0c9101 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -23,7 +23,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index d57f91d..8f89956 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -24,7 +24,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx.res + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 4e7f135..fa11f96 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -24,7 +24,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx.res + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 NETOBJ = ne2000.o nethandler.o diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 7efe58b..ca0f59b 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -22,7 +22,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/ibm.h b/src/ibm.h index a4ffc2d..8738bb3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -581,3 +581,5 @@ void saveconfig(char *fn); void saveconfig_global_only(); #define UNUSED(x) (void)x + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/src/icons/16x16/joystick.png b/src/icons/16x16/joystick.png new file mode 100644 index 0000000000000000000000000000000000000000..ee165efb5dc8ed0060c9c5efe47f503fbc2f327a GIT binary patch literal 714 zcmV;*0yX`KP)eRyIUmKiZ!8_ z7(qeA#ELOKiAur~FZ2aJs*))2QJ#ni8cpO!KuCBZ(L@bxV)Tj7qDV}978Htz3bcI5 zwt}?S-JSJLZAptCG2Y~6W_RYCd+xczI&a@Wewf0>-kNGO-Mh7zvf*Kj!R64FIvbkG z*~T|0C=32!|D zwsOhyKV%L(e$@Llk=P7}hY?@ZF*z}TXfz68S(`6Mp7(Co%T2>TE{${=9UV9I`Ptd7 z<)vj*RP2|YAfbQ3%F1%rmDa1erfJAe9*Zp?M*Yeva^)m97#!$hjAz=-DGP^&`hN9` zL6t63nd|`U43Ym*YuvJ|3@~dfd_G?szX@JQNB~Jliy*SW!J*6)Od>0Bm1fKQ;T;Gd zAi!EIYQbUxXX{VlNN`2YcLZ zghIn4+lJe{o8GvE#*OzlH2DAlZyTn@$NUbBY3!o^vfbW(1Ci+uuoM-7k`ss<-@&MV z*|#8HOhqHTimV7lm^fTrh3@VisM5D-0#A;=`Dq|I$TBb+Tdpy=&3nR$?Xl)&Kwi07*qoM6N<$f_1M*IsgCw literal 0 HcmV?d00001 diff --git a/src/icons/32x32/joystick.png b/src/icons/32x32/joystick.png new file mode 100644 index 0000000000000000000000000000000000000000..c7fb11e2d4eea49d58f9b29fe9ab0e3ecb47acd1 GIT binary patch literal 1208 zcmV;p1V{UcP)WV$g|K;}Hzr$VbcUE921#63!k;iDnPhjyCEhIDEPgF9-gsqzcCKKyxtj?Hn&`zo zqHaSeYbm9zFpw7LY0sC>dwN=7n_Js}-t29k_C4pk?|FXD*Li-28HR!Xb4dJ$F;>!^ z;jQ>C&2U5)awi0`;c14kmy67*S@}E#R6eG1Vwm2I@xn-$l-9b&Lvam5(T`t<2mSH=0~LMKhH+-QDPpVra;YR zF9$B1Z!ZQ!u^ypvcg_42jW9&A(ybRN&4!9X8XT;}khL#TDTAP53PQ8b0mxze$* z(LO8o`bGlCdto6s6+9CPg|Kf=0}A1@BpQvL;cJSuzEl9F7cPA>G;sae4OCTCnO1YR zE7>fT7UuE&=kR-FNo&6Xry~-&UyaXbdT*C6oD$*-5ZvJwU%oUI&#UBn|#no>w zWB#QBxZ^#6)Sod#rh?oR0iUmb9f-96NO`BJys>dVwmF@6W%w+1|2_%gS{T0pOq}~1 zf}Dn7QL%gvU;=}{gd6}#!uuC5Ar`v=iQ*S(YQ)H^@8K`<*5u?L7Knd5kq00h^LPU^ zZ98!Ac{ppGP-(M9)@Y(Fr@+u4Dj6`Yn8(@3=RV7SVGtPI41o;>-$$24T_vKbLLz(# z3e~OOe&y+Lkyuj)&xt%Es-)K1*8T1~xHB=azOs2vyP%h5Jb8dMN@M#FPTkIPNj{B+qX?!_p@R{meW5hF5>Wy + + 0 + icons/32x32/joystick.png + + + + 2 + 0 + 0 + 0 + + + + + 0 + 4 + 0 + 0 + 1 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + + + 0 + 4 + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 1 + + + + + wxALL + 5 + + + 1 + + + + + + + 0 diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index bb39379..e103c35 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -19,8 +19,6 @@ #include "scsi_aha1540.h" #include "timer.h" -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - int primed = 0; typedef enum { diff --git a/src/wx-config.c b/src/wx-config.c index e3ca304..368b9fd 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -1,5 +1,6 @@ #include "wx-utils.h" #include "wx-sdl2.h" +#include "wx-joystickconfig.h" #include "ibm.h" #include "ide.h" @@ -269,6 +270,7 @@ int config_dlgsave(void* hdlg) int temp_fda_type, temp_fdb_type; int temp_mouse_type; int temp_lpt1_device; + int temp_joystick_type; #ifdef USE_NETWORKING int temp_network_card; #endif @@ -327,8 +329,9 @@ int config_dlgsave(void* hdlg) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; @@ -468,8 +471,8 @@ int config_dlgsave(void* hdlg) speedchanged(); -// joystick_type = temp_joystick_type; -// gameport_update_joystick_type(); + joystick_type = temp_joystick_type; + gameport_update_joystick_type(); return TRUE; @@ -640,24 +643,24 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); - // h = wx_getdlgitem(hdlg, ID("IDC_COMBOJOY")); - // c = 0; - // while (joystick_get_name(c)) - // { - // wx_sendmessage(h, CB_ADDSTRING, 0, joystick_get_name(c)); - // c++; - // } - // wx_enablewindow(h, TRUE); - // wx_sendmessage(h, CB_SETCURSEL, joystick_type, 0); - // - // h = wx_getdlgitem(hdlg, ID("IDC_JOY1")); - // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); - // h = wx_getdlgitem(hdlg, ID("IDC_JOY2")); - // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); - // h = wx_getdlgitem(hdlg, ID("IDC_JOY3")); - // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); - // h = wx_getdlgitem(hdlg, ID("IDC_JOY4")); - // wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + c = 0; + while (joystick_get_name(c)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)joystick_get_name(c)); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, joystick_type, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY1")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY2")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY3")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY4")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "System default"); @@ -1028,51 +1031,54 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); } #endif - // - // case IDC_COMBOJOY: - // if (HIWORD(wParam) == CBN_SELCHANGE) { - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // - // h = wx_getdlgitem(hdlg, IDC_JOY1); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? - // TRUE : FALSE); - // h = wx_getdlgitem(hdlg, IDC_JOY2); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? - // TRUE : FALSE); - // h = wx_getdlgitem(hdlg, IDC_JOY3); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? - // TRUE : FALSE); - // h = wx_getdlgitem(hdlg, IDC_JOY4); - // wx_enablewindow(h, - // (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? - // TRUE : FALSE); - // } - // break; - // - // case IDC_JOY1: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 0, temp_joystick_type); - // break; - // case IDC_JOY2: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 1, temp_joystick_type); - // break; - // case IDC_JOY3: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 2, temp_joystick_type); - // break; - // case IDC_JOY4: - // h = wx_getdlgitem(hdlg, IDC_COMBOJOY); - // temp_joystick_type = wx_sendmessage(h, CB_GETCURSEL, 0, 0); - // joystickconfig_open(hdlg, 3, temp_joystick_type); - // break; + else if (wParam == WX_ID("IDC_COMBOJOY")) + { + int temp_joystick_type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY1")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY2")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY3")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY4")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? TRUE : FALSE); + } + else if (wParam == WX_ID("IDC_JOY1")) + { + int temp_joystick_type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 0, temp_joystick_type); + } + else if (wParam == WX_ID("IDC_JOY2")) + { + int temp_joystick_type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 1, temp_joystick_type); + } + else if (wParam == WX_ID("IDC_JOY3")) + { + int temp_joystick_type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 2, temp_joystick_type); + } + else if (wParam == WX_ID("IDC_JOY4")) + { + int temp_joystick_type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 3, temp_joystick_type); + } return 0; } } diff --git a/src/wx-joystickconfig.cc b/src/wx-joystickconfig.cc new file mode 100644 index 0000000..37150c0 --- /dev/null +++ b/src/wx-joystickconfig.cc @@ -0,0 +1,358 @@ +#include "wx-joystickconfig.h" + +#include "wx-utils.h" +#include "wx/wxprec.h" + +#include "wx-dialogbox.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/xrc/xmlres.h" + +extern "C" { +void pclog(const char *format, ...); +#include "config.h" +#include "device.h" +#include "gameport.h" +#include "plat-joystick.h" +} + +#define IDC_CONFIG_BASE 1000 + +static int joystick_nr; +static int joystick_config_type; +#define AXIS_STRINGS_MAX 3 +static char axis_strings[AXIS_STRINGS_MAX][10] = {"X Axis", "Y Axis", "Z Axis"}; + +static void rebuild_axis_button_selections(void *hdlg) +{ + int id = IDC_CONFIG_BASE + 3; + void *h; + int joystick; + int c, d; + + h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE+1); + joystick = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) + { + int sel = c; + + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + + if (joystick) + { + for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) + { + wx_sendmessage(h, WX_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); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); + wx_enablewindow(h, TRUE); + } + else + wx_enablewindow(h, FALSE); + + id += 2; + } + + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + + if (joystick) + { + for (d = 0; d < plat_joystick_state[joystick-1].nr_buttons; d++) + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].button[d].name); + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + wx_enablewindow(h, TRUE); + } + else + wx_enablewindow(h, FALSE); + + id += 2; + } + + for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++) + { + int sel = c; + + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_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); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); + } + wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); + wx_enablewindow(h, TRUE); + } + else + wx_enablewindow(h, FALSE); + + id += 2; + } + +} + +static int get_axis(void *hdlg, int id) +{ + void *h = wx_getdlgitem(hdlg, id); + int axis_sel = wx_sendmessage(h, WX_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(void *hdlg, int id) +{ + void *h = wx_getdlgitem(hdlg, id); + int axis_sel = wx_sendmessage(h, WX_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 int joystickconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) +{ + switch (message) + { + case WX_INITDIALOG: + { +// rebuild_axis_button_selections(hdlg); + + void *h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE+1); + int c; + int id = IDC_CONFIG_BASE + 3; + int joystick = joystick_state[joystick_nr].plat_joystick_nr; + + wx_sendmessage(h, WX_CB_SETCURSEL, joystick, 0); + + rebuild_axis_button_selections(hdlg); + + 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; + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) + { + int mapping = joystick_state[joystick_nr].axis_mapping[c]; + + h = wx_getdlgitem(hdlg, id); + if (mapping & POV_X) + wx_sendmessage(h, WX_CB_SETCURSEL, nr_axes + (mapping & 3)*2, 0); + else if (mapping & POV_Y) + wx_sendmessage(h, WX_CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, mapping, 0); + id += 2; + } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); + id += 2; + } + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) + { + int mapping; + + h = wx_getdlgitem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + if (mapping & POV_X) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3)*2, 0); + else if (mapping & POV_Y) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3)*2 + 1, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, mapping + nr_povs*2, 0); + id += 2; + h = wx_getdlgitem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][1]; + if (mapping & POV_X) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3)*2, 0); + else if (mapping & POV_Y) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3)*2 + 1, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, mapping + nr_povs*2, 0); + id += 2; + } + } + } + return TRUE; + + case WX_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIG_BASE+1: +// if (HIWORD(wParam) == CBN_SELCHANGE) + rebuild_axis_button_selections(hdlg); + break; + + case wxID_OK: + { + void *h; + int c; + int id = IDC_CONFIG_BASE + 3; + + h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE+1); + joystick_state[joystick_nr].plat_joystick_nr = wx_sendmessage(h, WX_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 = wx_getdlgitem(hdlg, id); + joystick_state[joystick_nr].button_mapping[c] = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + id += 2; + } + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) + { + h = wx_getdlgitem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); + id += 2; + h = wx_getdlgitem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); + id += 2; + } + } + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + +void joystickconfig_open(void *hwnd, int joy_nr, int type) +{ + char s[257]; + int c; + + PCemDialogBox dialog((wxWindow*) hwnd, joystickconfig_dlgproc); +// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + joystick_nr = joy_nr; + joystick_config_type = type; + + dialog.SetTitle("Joystick Configuration"); + + wxFlexGridSizer* root = new wxFlexGridSizer(0, 1, 0, 0); + root->SetFlexibleDirection(wxBOTH); + root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + dialog.SetSizer(root); + + wxFlexGridSizer* sizer = new wxFlexGridSizer(0, 2, 0, 0); + sizer->SetFlexibleDirection(wxBOTH); + sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + sizer->AddGrowableCol(1); + root->Add(sizer, 1, wxEXPAND, 5); + + int id = IDC_CONFIG_BASE; + + + sizer->Add(new wxStaticText(&dialog, id++, "Device:"), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer* comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + + cb->Append("None"); + for (c = 0; c < joysticks_present; c++) + cb->Append(plat_joystick_state[c].name); + + for (c = 0; c < joystick_get_axis_count(type); c++) + { + sprintf(s, "Axis %i:", c); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer* comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + } + + for (c = 0; c < joystick_get_button_count(type); c++) + { + sprintf(s, "Button %i:", c); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer* comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + } + + for (c = 0; c < joystick_get_pov_count(type)*2; c++) + { + sprintf(s, "POV %i:", c); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer* comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox* cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + } + + wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + root->Add(okCancelSizer, 1, wxEXPAND, 5); + + okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); + + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); +} diff --git a/src/wx-joystickconfig.h b/src/wx-joystickconfig.h new file mode 100644 index 0000000..32c9aad --- /dev/null +++ b/src/wx-joystickconfig.h @@ -0,0 +1,15 @@ +#ifndef SRC_WX_DEVICECONFIG_H_ +#define SRC_WX_DEVICECONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +void joystickconfig_open(void *hwnd, int joy_nr, int type); + +#ifdef __cplusplus +} +#endif + +#endif /* SRC_WX_DEVICECONFIG_H_ */ diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index cc3f835..5ba3393 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -850,11 +850,73 @@ static unsigned char xml_res_file_15[] = { 117,197,150,115,135,151,229,88,93,14,192,233,243,63,1,6,0,218,58,168,206, 121,36,62,30,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_16 = 2048; +static size_t xml_res_size_16 = 1208; static unsigned char xml_res_file_16[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, +60,0,0,4,90,73,68,65,84,120,218,236,87,221,79,91,101,24,255,189,231,156, +74,217,44,140,169,43,180,27,236,131,133,176,121,163,55,38,91,102,116,134, +152,32,6,73,92,87,194,159,48,37,153,100,119,198,37,222,44,220,44,126,45, +49,222,120,101,128,118,174,96,182,185,155,9,8,154,232,197,62,162,110,67, +41,107,41,165,173,48,144,22,232,105,207,151,207,123,122,90,97,155,91,219, +128,222,236,109,159,246,61,231,188,239,121,126,207,215,121,126,135,25,134, +129,255,115,72,252,135,49,86,210,158,225,173,248,46,205,112,68,23,114,39, +4,178,225,105,134,177,151,147,56,74,135,106,201,0,138,93,219,221,115,202, +175,216,42,222,106,184,210,11,81,82,160,91,184,69,18,67,183,31,105,63,216, +165,72,242,234,224,215,190,190,99,197,2,97,60,4,69,120,64,58,217,115,106, +200,225,112,180,206,37,83,232,18,5,188,184,227,57,232,96,230,71,164,237, +63,207,70,241,81,98,30,162,166,64,205,102,47,7,46,156,111,47,6,68,177,30, +168,148,36,169,181,165,229,53,248,47,12,226,203,180,140,47,238,134,161, +104,26,52,18,93,37,61,244,111,35,72,146,100,131,166,40,173,124,15,73,234, +113,55,22,138,117,255,84,48,120,154,4,111,190,209,138,189,59,93,216,66, +86,87,104,42,236,186,134,74,154,215,108,221,130,237,53,53,60,24,72,36,226, +167,139,53,174,216,16,112,107,118,119,159,236,185,94,231,116,86,184,92, +181,168,174,222,134,84,42,133,229,212,10,82,203,73,196,227,9,204,205,205, +65,150,229,140,223,215,255,2,173,15,145,164,55,42,4,25,146,123,225,187, +83,189,132,248,131,240,244,52,185,89,133,102,232,208,117,18,30,10,235,63, +30,139,245,242,181,214,30,108,84,8,116,30,207,161,193,64,31,85,92,230,240, +161,67,168,117,187,32,8,2,68,81,52,133,207,185,210,177,177,209,62,43,246, +250,70,2,200,123,97,33,56,21,60,19,10,133,176,111,79,3,10,225,179,36,26, +141,158,225,107,138,181,190,84,0,166,23,46,125,51,52,112,253,218,13,84, +85,85,153,86,115,183,43,217,44,150,22,230,241,253,232,240,64,41,214,151, +10,32,239,133,164,32,242,109,235,19,215,74,228,100,41,214,151,3,128,91, +166,62,88,53,44,15,71,45,197,250,114,0,108,248,120,2,224,9,128,178,1,220, +95,8,198,127,239,1,182,6,5,169,47,147,218,253,91,55,148,188,157,93,231, +233,124,251,186,162,166,181,230,147,79,209,224,114,215,241,206,7,85,81, +232,88,65,106,105,17,142,234,26,232,180,198,176,92,196,44,11,73,199,80, +127,223,87,111,63,140,160,60,12,128,232,57,222,233,103,130,208,81,187,171, +30,142,237,207,64,167,102,195,168,243,9,217,12,116,122,236,118,30,247,96, +102,102,134,250,126,174,5,243,86,60,59,59,139,253,77,77,208,232,94,170, +40,129,145,8,116,239,229,133,123,136,71,166,137,178,233,1,223,128,73,213, +180,71,1,16,61,30,175,159,78,116,236,218,187,15,142,29,117,104,30,56,7, +231,79,183,144,36,179,174,157,253,24,44,189,202,41,23,188,4,34,153,92,194, +242,202,42,210,43,50,110,254,114,147,204,21,144,37,197,31,14,95,197,213, +111,47,99,254,165,3,184,227,61,129,212,159,49,68,166,130,220,21,1,159,175, +127,29,136,181,0,72,121,167,169,188,177,113,63,182,57,157,120,101,248,44, +118,255,62,9,226,90,24,191,1,76,156,251,28,130,156,134,97,81,177,124,15, +96,2,131,192,132,28,0,73,194,251,23,47,33,22,187,2,137,226,23,106,106,196, +200,171,239,225,47,242,214,228,228,31,22,136,127,60,145,7,32,29,243,120, +3,52,109,59,112,240,121,56,107,157,80,105,179,70,214,104,162,45,167,192, +208,32,42,25,48,174,152,199,217,200,231,62,203,127,97,16,24,221,12,129, +13,6,223,71,151,69,93,37,162,170,66,34,124,9,10,213,173,223,126,229,233, +113,145,88,83,7,207,137,60,35,170,164,214,218,214,253,238,59,184,51,49, +177,190,180,152,90,72,122,60,37,113,14,252,200,172,54,172,182,100,48,45, +55,163,155,48,91,78,77,67,189,27,175,183,28,197,39,159,126,214,150,39,173, +121,0,118,158,187,161,112,24,35,35,163,57,183,150,246,178,242,216,97,152, +94,51,96,183,219,97,213,137,125,45,0,198,99,24,137,68,224,118,239,220,212, +39,31,215,97,230,139,69,40,10,164,84,16,68,186,24,69,83,115,51,47,153,77, +81,78,165,141,137,219,183,77,93,247,179,98,67,150,211,63,44,46,226,240, +143,227,227,216,172,23,86,30,86,78,227,184,174,66,138,89,85,224,160,121, +61,201,179,37,190,47,150,51,120,86,207,147,76,243,28,40,148,161,149,149, +246,7,200,222,198,15,110,185,108,189,180,168,127,11,48,0,131,178,248,28, +75,223,85,170,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_17 = 2048; +static unsigned char xml_res_file_17[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, +0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, +0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, 60,0,0,3,34,105,84,88,116,88,77,76,58,99,111,109,46,97,100,111,98,101,46, 120,109,112,0,0,0,0,0,60,63,120,112,97,99,107,101,116,32,98,101,103,105, 110,61,34,239,187,191,34,32,105,100,61,34,87,53,77,48,77,112,67,101,104, @@ -951,8 +1013,8 @@ static unsigned char xml_res_file_16[] = { 141,29,39,33,92,73,190,59,9,96,233,32,252,79,128,1,0,168,254,212,85,21, 212,140,221,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_17 = 1971; -static unsigned char xml_res_file_17[] = { +static size_t xml_res_size_18 = 1971; +static unsigned char xml_res_file_18[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1052,8 +1114,8 @@ static unsigned char xml_res_file_17[] = { 60,140,219,229,21,77,101,241,228,231,127,2,12,0,35,187,154,106,194,98,206, 112,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_18 = 2315; -static unsigned char xml_res_file_18[] = { +static size_t xml_res_size_19 = 2315; +static unsigned char xml_res_file_19[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1169,8 +1231,8 @@ static unsigned char xml_res_file_18[] = { 131,67,255,223,235,63,2,12,0,116,106,129,252,126,87,16,179,0,0,0,0,73,69, 78,68,174,66,96,130}; -static size_t xml_res_size_19 = 1468; -static unsigned char xml_res_file_19[] = { +static size_t xml_res_size_20 = 1468; +static unsigned char xml_res_file_20[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1244,8 +1306,8 @@ static unsigned char xml_res_file_19[] = { 16,218,51,250,191,28,188,211,127,207,255,22,96,0,113,192,97,41,118,79,50, 219,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_20 = 2051; -static unsigned char xml_res_file_20[] = { +static size_t xml_res_size_21 = 2051; +static unsigned char xml_res_file_21[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1348,8 +1410,8 @@ static unsigned char xml_res_file_20[] = { 128,139,229,223,112,255,19,96,0,111,126,151,122,57,77,224,198,0,0,0,0,73, 69,78,68,174,66,96,130}; -static size_t xml_res_size_21 = 2007; -static unsigned char xml_res_file_21[] = { +static size_t xml_res_size_22 = 2007; +static unsigned char xml_res_file_22[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1450,8 +1512,8 @@ static unsigned char xml_res_file_21[] = { 188,16,216,199,255,233,248,143,0,3,0,149,57,130,56,76,237,54,38,0,0,0,0, 73,69,78,68,174,66,96,130}; -static size_t xml_res_size_22 = 1967; -static unsigned char xml_res_file_22[] = { +static size_t xml_res_size_23 = 1967; +static unsigned char xml_res_file_23[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1549,8 +1611,8 @@ static unsigned char xml_res_file_22[] = { 118,74,132,55,233,55,235,255,245,144,69,191,33,187,30,155,236,92,142,255, 9,48,0,241,195,153,86,37,156,12,221,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_23 = 2051; -static unsigned char xml_res_file_23[] = { +static size_t xml_res_size_24 = 2051; +static unsigned char xml_res_file_24[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1652,8 +1714,8 @@ static unsigned char xml_res_file_23[] = { 250,58,190,198,55,48,18,49,104,115,122,47,134,29,3,118,202,219,228,255, 5,24,0,238,123,163,24,29,62,142,101,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_24 = 1382; -static unsigned char xml_res_file_24[] = { +static size_t xml_res_size_25 = 1382; +static unsigned char xml_res_file_25[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1722,8 +1784,8 @@ static unsigned char xml_res_file_24[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_25 = 128075; -static unsigned char xml_res_file_25[] = { +static size_t xml_res_size_26 = 132267; +static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, 32,104,116,116,112,58,47,47,100,111,99,115,46,119,120,119,105,100,103,101, @@ -5748,84 +5810,249 @@ static unsigned char xml_res_file_25[] = { 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, 108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, 120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,110,101,116,119,111,114,107,95,101,116,104,101, -114,110,101,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +115,95,51,50,120,51,50,95,106,111,121,115,116,105,99,107,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,50,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,48,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,109, -95,112,97,110,101,108,110,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65, -86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, -62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, -60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, 101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,109,95,115,116,97,116, -105,99,84,101,120,116,55,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,78,101,116,119,111,114,107,32,99, -97,114,100,32,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,111,121,115, +116,105,99,107,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, 88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,74,79,89,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,95,78, -69,84,67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,74,79,89,49,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,74,111,121,115,116,105,99,107,32,49,46,46,46,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,74,79,89,50,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,74,111,121,115,116,105,99,107,32,50,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,74,79,89,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,111,121, +115,116,105,99,107,32,51,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,74,79,89,52,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,74,111,121,115,116,105,99,107,32,52,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, +47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,110, +101,116,119,111,114,107,95,101,116,104,101,114,110,101,116,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,109,95,112,97,110,101,108,110,101,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,109,95,115,116,97,116,105,99,84,101,120,116,55,48,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,101,116,119,111,114,107,32,99,97,114,100,32,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, @@ -5835,140 +6062,81 @@ static unsigned char xml_res_file_25[] = { 32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,95,78,69,84, -67,65,82,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, -85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103, -95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,73,68,67,95,67,79,77,66,79,95,78,69,84,67,65,82,68,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99,101,108, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,78,70,73,71,85,82,69,95,78,69,84,67,65,82,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54, +120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34, -32,110,97,109,101,61,34,72,100,78,101,119,68,108,103,34,62,10,32,32,32, -32,60,116,105,116,108,101,62,78,101,119,32,72,97,114,100,32,68,105,115, -99,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, -101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32, -32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, -10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, -62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, -111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, -111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, -114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, -69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, -49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73, -68,67,95,69,68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, @@ -5978,69 +6146,180 @@ static unsigned char xml_res_file_25[] = { 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82, -65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, -102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, 116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, -97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, -99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,78,101, +119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119, +32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32, +32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, +114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79, +84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, +85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, +101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, 116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, 114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -6055,52 +6334,9 @@ static unsigned char xml_res_file_25[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, -116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6108,126 +6344,139 @@ static unsigned char xml_res_file_25[] = { 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, -122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, -34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,48,109,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, -108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, @@ -7518,15 +7767,16 @@ void InitXmlResource() XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_go.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_24, xml_res_size_24, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_joystick.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_add.png"), xml_res_file_21, xml_res_size_21, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_edit.png"), xml_res_file_22, xml_res_size_22, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_go.png"), xml_res_file_23, xml_res_size_23, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_computer_delete.png"), xml_res_file_24, xml_res_size_24, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_door_in.png"), xml_res_file_25, xml_res_size_25, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$._pc.xrc"), xml_res_file_26, xml_res_size_26, wxT("text/xml")); wxXmlResource::Get()->Load(wxT("memory:XRC_resource/wx-resources.cpp$._pc.xrc")); } diff --git a/src/wx-sdl2-joystick.c b/src/wx-sdl2-joystick.c index 9aed5d7..8aa487b 100644 --- a/src/wx-sdl2-joystick.c +++ b/src/wx-sdl2-joystick.c @@ -1,15 +1,165 @@ +#include +#include +#include +#include "ibm.h" +#include "device.h" +#include "gameport.h" #include "plat-joystick.h" int joysticks_present; joystick_t joystick_state[MAX_JOYSTICKS]; +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; + void joystick_init() { - joysticks_present = 0; + int c; + + SDL_InitSubSystem(SDL_INIT_JOYSTICK); + joysticks_present = SDL_NumJoysticks(); + + memset(sdl_joy, 0, sizeof(sdl_joy)); + for (c = 0; c < joysticks_present; c++) + { + sdl_joy[c] = SDL_JoystickOpen(c); + + if (sdl_joy[c]) + { + int d; + + pclog("Opened Joystick %i\n", c); + pclog(" Name: %s\n", SDL_JoystickName(sdl_joy[c])); + pclog(" Number of Axes: %d\n", SDL_JoystickNumAxes(sdl_joy[c])); + pclog(" Number of Buttons: %d\n", SDL_JoystickNumButtons(sdl_joy[c])); + pclog(" Number of Hats: %d\n", SDL_JoystickNumHats(sdl_joy[c])); + + strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); + plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); + plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); + plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + + for (d = 0; d < MIN(plat_joystick_state[c].nr_axes, 8); d++) + { + sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); + plat_joystick_state[c].axis[d].id = d; + } + for (d = 0; d < MIN(plat_joystick_state[c].nr_buttons, 8); d++) + { + sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); + plat_joystick_state[c].button[d].id = d; + } + for (d = 0; d < MIN(plat_joystick_state[c].nr_povs, 4); d++) + { + sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); + plat_joystick_state[c].pov[d].id = d; + } + } + } } void joystick_close() { + int c; + + for (c = 0; c < joysticks_present; c++) + { + if (sdl_joy[c]) + SDL_JoystickClose(sdl_joy[c]); + } +} + +static int joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) + { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) + { + case SDL_HAT_LEFTUP: case SDL_HAT_LEFT: case SDL_HAT_LEFTDOWN: + return -32767; + + case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHT: case SDL_HAT_RIGHTDOWN: + return 32767; + + default: + return 0; + } + } + else if (mapping & POV_Y) + { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) + { + case SDL_HAT_LEFTUP: case SDL_HAT_UP: case SDL_HAT_RIGHTUP: + return -32767; + + case SDL_HAT_LEFTDOWN: case SDL_HAT_DOWN: case SDL_HAT_RIGHTDOWN: + return 32767; + + default: + return 0; + } + } + else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } void joystick_poll() { + int c, d; + + SDL_JoystickUpdate(); + for (c = 0; c < joysticks_present; c++) + { + int b; + + plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); + plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); + plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); + plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); + plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); + plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); + + for (b = 0; b < 16; b++) + plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); + + for (b = 0; b < 4; b++) + plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], 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/wx-sdl2.c b/src/wx-sdl2.c index 49f3d76..39a5607 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -27,6 +27,7 @@ #include "model.h" #include "mouse.h" #include "nvr.h" +#include "plat-joystick.h" #include "sound.h" #include "thread.h" #include "disc.h" @@ -512,6 +513,7 @@ int pc_main(int argc, char** argv) display_init(); #endif sdl_video_init(); + joystick_init(); return TRUE; } From 3489af10c4508fdf82e2a7232c9692782955f16c Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 10 Oct 2017 18:42:23 +0100 Subject: [PATCH 0160/1050] Fixed Windows-isms in wx-joystickconfig.cc. --- src/wx-joystickconfig.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wx-joystickconfig.cc b/src/wx-joystickconfig.cc index 37150c0..2c00c65 100644 --- a/src/wx-joystickconfig.cc +++ b/src/wx-joystickconfig.cc @@ -47,10 +47,10 @@ static void rebuild_axis_button_selections(void *hdlg) { for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)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)) + if (!strcasecmp(axis_strings[c], plat_joystick_state[joystick-1].axis[d].name)) sel = d; } } @@ -59,9 +59,9 @@ static void rebuild_axis_button_selections(void *hdlg) char s[80]; sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); } wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); wx_enablewindow(h, TRUE); @@ -80,7 +80,7 @@ static void rebuild_axis_button_selections(void *hdlg) if (joystick) { for (d = 0; d < plat_joystick_state[joystick-1].nr_buttons; d++) - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].button[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick-1].button[d].name); wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); wx_enablewindow(h, TRUE); } @@ -104,13 +104,13 @@ static void rebuild_axis_button_selections(void *hdlg) char s[80]; sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); } for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick-1].axis[d].name); } wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); wx_enablewindow(h, TRUE); @@ -224,7 +224,7 @@ static int joystickconfig_dlgproc(void* hdlg, int message, INT_PARAM wParam, LON return TRUE; case WX_COMMAND: - switch (LOWORD(wParam)) + switch (wParam) { case IDC_CONFIG_BASE+1: // if (HIWORD(wParam) == CBN_SELCHANGE) From 95c04340cff1e9702e94f8233179390b46acf4db Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 10 Oct 2017 19:36:15 +0100 Subject: [PATCH 0161/1050] wx/SDL2 port now initialises MIDI correctly (currently Windows only). --- src/wx-sdl2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 39a5607..72c6a18 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -28,6 +28,7 @@ #include "mouse.h" #include "nvr.h" #include "plat-joystick.h" +#include "plat-midi.h" #include "sound.h" #include "thread.h" #include "disc.h" @@ -634,6 +635,7 @@ int start_emulation(void* params) loadbios(); resetpchard(); + midi_init(); display_start(params); mainthreadh = SDL_CreateThread(mainthread, "Main Thread", NULL); @@ -684,6 +686,8 @@ int stop_emulation() endblit(); SDL_DestroyMutex(ghMutex); + midi_close(); + pclog("Emulation stopped.\n"); wx_close_status(ghwnd); From c532d874a11f00e3e10c125d3f11e14cf953219d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Oct 2017 20:26:47 +0100 Subject: [PATCH 0162/1050] Added Linux MIDI output via ALSA. --- Makefile.in | 1 + aclocal.m4 | 58 +++++-- configure | 150 ++++++++++++++++-- configure.ac | 17 ++ src/Makefile.am | 8 +- src/Makefile.in | 414 +++++++++++++++++++++++++++++++++--------------- src/midi_alsa.c | 184 +++++++++++++++++++++ 7 files changed, 674 insertions(+), 158 deletions(-) create mode 100644 src/midi_alsa.c diff --git a/Makefile.in b/Makefile.in index 3bdd759..d83741a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -247,6 +247,7 @@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ SDL2_CONFIG = @SDL2_CONFIG@ +SDL2_FRAMEWORK = @SDL2_FRAMEWORK@ SDL_CFLAGS = @SDL_CFLAGS@ SDL_LIBS = @SDL_LIBS@ SET_MAKE = @SET_MAKE@ diff --git a/aclocal.m4 b/aclocal.m4 index b525be4..53df7ec 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -21,7 +21,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29.1) +dnl serial 11 (pkg-config-0.29) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -63,7 +63,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) +[m4_define([PKG_MACROS_VERSION], [0.29]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -302,6 +302,9 @@ AS_VAR_IF([$1], [""], [$5], [$4])dnl # stolen back from Frank Belew # stolen from Manish Singh # Shamelessly stolen from Owen Taylor +# +# Changelog: +# * also look for SDL2.framework under Mac OS X # serial 1 @@ -318,6 +321,10 @@ AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL sdl_exec_prefix="$withval", sdl_exec_prefix="") AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], , enable_sdltest=yes) +AC_ARG_ENABLE(sdlframework, [ --disable-sdlframework Do not search for SDL2.framework], + , search_sdl_framework=yes) + +AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework]) min_sdl_version=ifelse([$1], ,2.0.0,$1) @@ -351,14 +358,36 @@ AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run fi AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) PATH="$as_save_PATH" - AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) no_sdl="" - if test "$SDL2_CONFIG" = "no" ; then - no_sdl=yes - else - SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + if test "$SDL2_CONFIG" = "no" -a "x$search_sdl_framework" = "xyes"; then + AC_MSG_CHECKING(for SDL2.framework) + if test "x$SDL2_FRAMEWORK" != x; then + sdl_framework=$SDL2_FRAMEWORK + else + for d in / ~/ /System/; do + if test -d "$dLibrary/Frameworks/SDL2.framework"; then + sdl_framework="$dLibrary/Frameworks/SDL2.framework" + fi + done + fi + + if test -d $sdl_framework; then + AC_MSG_RESULT($sdl_framework) + sdl_framework_dir=`dirname $sdl_framework` + SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include" + SDL_LIBS="-F$sdl_framework_dir -Wl,-framework,SDL2" + else + no_sdl=yes + fi + fi + + if test "$SDL2_CONFIG" != "no"; then + if test "x$sdl_pc" = "xno"; then + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + fi sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` @@ -439,12 +468,15 @@ int main (int argc, char *argv[]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" + + fi + if test "x$sdl_pc" = "xno"; then + if test "x$no_sdl" = "xyes"; then + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi fi - fi - if test "x$no_sdl" = x ; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) fi fi if test "x$no_sdl" = x ; then diff --git a/configure b/configure index 29941e4..b5acc65 100755 --- a/configure +++ b/configure @@ -607,9 +607,12 @@ SDL_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG +SDL2_FRAMEWORK allegro_LIBS allegro_CFLAGS ALLEGRO_CONFIG +USE_ALSA_FALSE +USE_ALSA_TRUE USE_NETWORKING_FALSE USE_NETWORKING_TRUE USE_WX_FALSE @@ -727,12 +730,14 @@ enable_dependency_tracking enable_debug enable_wx enable_networking +enable_alsa with_allegro_prefix with_allegro_exec_prefix enable_allegrotest with_sdl_prefix with_sdl_exec_prefix enable_sdltest +enable_sdlframework with_wxdir with_wx_config with_wx_prefix @@ -749,6 +754,7 @@ CPPFLAGS CXX CXXFLAGS CCC +SDL2_FRAMEWORK PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR @@ -1392,8 +1398,10 @@ Optional Features: --enable-debug build debug executable --enable-wx use wxWidgets GUI --enable-networking enable networking + --enable-alsa use ALSA for MIDI --disable-allegrotest Do not try to compile and run a test LIBallegro program --disable-sdltest Do not try to compile and run a test SDL program + --disable-sdlframework Do not search for SDL2.framework Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1418,6 +1426,8 @@ Some influential environment variables: you have headers in a nonstandard directory CXX C++ compiler command CXXFLAGS C++ compiler flags + SDL2_FRAMEWORK + Path to SDL2.framework PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path @@ -4177,6 +4187,21 @@ else $as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use ALSA for MIDI output" >&5 +$as_echo_n "checking whether to use ALSA for MIDI output... " >&6; } +# Check whether --enable-alsa was given. +if test "${enable_alsa+set}" = set; then : + enableval=$enable_alsa; +fi + +if test "$enable_alsa" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu" >&5 $as_echo_n "checking for cpu... " >&6; } case "${host_cpu}" in @@ -4248,6 +4273,14 @@ else USE_NETWORKING_FALSE= fi + if test "$enable_alsa" = "yes"; then + USE_ALSA_TRUE= + USE_ALSA_FALSE='#' +else + USE_ALSA_TRUE='#' + USE_ALSA_FALSE= +fi + if test "$enable_wx" != "yes"; then # Do not run test for Allegro with Win32/MinGW version, as binary builds have @@ -4666,6 +4699,15 @@ else enable_sdltest=yes fi +# Check whether --enable-sdlframework was given. +if test "${enable_sdlframework+set}" = set; then : + enableval=$enable_sdlframework; +else + search_sdl_framework=yes +fi + + + min_sdl_version=$SDL_VERSION @@ -4807,15 +4849,39 @@ fi PATH="$as_save_PATH" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 -$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } no_sdl="" - if test "$SDL2_CONFIG" = "no" ; then - no_sdl=yes - else - SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + if test "$SDL2_CONFIG" = "no" -a "x$search_sdl_framework" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL2.framework" >&5 +$as_echo_n "checking for SDL2.framework... " >&6; } + if test "x$SDL2_FRAMEWORK" != x; then + sdl_framework=$SDL2_FRAMEWORK + else + for d in / ~/ /System/; do + if test -d "$dLibrary/Frameworks/SDL2.framework"; then + sdl_framework="$dLibrary/Frameworks/SDL2.framework" + fi + done + fi + + if test -d $sdl_framework; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sdl_framework" >&5 +$as_echo "$sdl_framework" >&6; } + sdl_framework_dir=`dirname $sdl_framework` + SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include" + SDL_LIBS="-F$sdl_framework_dir -Wl,-framework,SDL2" + else + no_sdl=yes + fi + fi + + if test "$SDL2_CONFIG" != "no"; then + if test "x$sdl_pc" = "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 +$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + fi sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` @@ -4907,14 +4973,17 @@ fi CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" + fi - fi - if test "x$no_sdl" = x ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + if test "x$sdl_pc" = "xno"; then + if test "x$no_sdl" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + fi fi fi if test "x$no_sdl" = x ; then @@ -5394,6 +5463,57 @@ else fi +if test "$enable_alsa" == "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for snd_pcm_open in -lasound" >&5 +$as_echo_n "checking for snd_pcm_open in -lasound... " >&6; } +if ${ac_cv_lib_asound_snd_pcm_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lasound $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char snd_pcm_open (); +int +main () +{ +return snd_pcm_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_asound_snd_pcm_open=yes +else + ac_cv_lib_asound_snd_pcm_open=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_pcm_open" >&5 +$as_echo "$ac_cv_lib_asound_snd_pcm_open" >&6; } +if test "x$ac_cv_lib_asound_snd_pcm_open" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBASOUND 1 +_ACEOF + + LIBS="-lasound $LIBS" + +else + echo "You need to install the ALSA library." + exit -1 +fi + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_create+:} false; then : @@ -5639,6 +5759,10 @@ if test -z "${USE_NETWORKING_TRUE}" && test -z "${USE_NETWORKING_FALSE}"; then as_fn_error $? "conditional \"USE_NETWORKING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${USE_ALSA_TRUE}" && test -z "${USE_ALSA_FALSE}"; then + as_fn_error $? "conditional \"USE_ALSA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 diff --git a/configure.ac b/configure.ac index 15e8fd9..93b22a6 100644 --- a/configure.ac +++ b/configure.ac @@ -42,6 +42,15 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([whether to use ALSA for MIDI output]) +AC_ARG_ENABLE(alsa, + AC_HELP_STRING([--enable-alsa], [use ALSA for MIDI])) +if test "$enable_alsa" = "yes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + AC_MSG_CHECKING([for cpu]) case "${host_cpu}" in i?86) @@ -68,6 +77,7 @@ AM_CONDITIONAL(OS_LINUX, test "$OS" = "linux") AM_CONDITIONAL(USE_WX, test "$enable_wx" = "yes") AM_CONDITIONAL(USE_NETWORKING, test "$enable_networking" = "yes") +AM_CONDITIONAL(USE_ALSA, test "$enable_alsa" = "yes") if test "$enable_wx" != "yes"; then # Do not run test for Allegro with Win32/MinGW version, as binary builds have @@ -109,6 +119,13 @@ AC_CHECK_LIB([openal], [alGetError], [], \ [echo "You need to install the OpenAL library." exit -1]) +if test "$enable_alsa" == "yes"; then + AC_CHECK_LIB(asound, snd_pcm_open, + [], + [echo "You need to install the ALSA library." + exit -1]) +fi + AC_CHECK_LIB([pthread], [pthread_create]) AC_OUTPUT([Makefile src/Makefile]) diff --git a/src/Makefile.am b/src/Makefile.am index d8c4494..5857a44 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,10 +42,16 @@ pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) pcem_LDADD = @LIBS@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ - wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c \ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc +if USE_ALSA +pcem_LDADD += -lasound +pcem_SOURCES += midi_alsa.c +else +pcem_SOURCES += wx-sdl2-midi.c +endif else pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO pcem_CXXFLAGS = diff --git a/src/Makefile.in b/src/Makefile.in index 1cf4fdb..89d0d0a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -93,23 +93,26 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcem$(EXEEXT) @USE_WX_TRUE@am__append_1 = wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ -@USE_WX_TRUE@ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c \ +@USE_WX_TRUE@ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c \ @USE_WX_TRUE@ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ @USE_WX_TRUE@ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ -@USE_WX_TRUE@ wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc +@USE_WX_TRUE@ wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc -@USE_WX_FALSE@am__append_2 = allegro-gui.c allegro-gui-config-sel.c allegro-gui-configure.c \ +@USE_ALSA_TRUE@@USE_WX_TRUE@am__append_2 = -lasound +@USE_ALSA_TRUE@@USE_WX_TRUE@am__append_3 = midi_alsa.c +@USE_ALSA_FALSE@@USE_WX_TRUE@am__append_4 = wx-sdl2-midi.c +@USE_WX_FALSE@am__append_5 = allegro-gui.c allegro-gui-config-sel.c allegro-gui-configure.c \ @USE_WX_FALSE@ allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c \ @USE_WX_FALSE@ allegro-keyboard.c allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ @USE_WX_FALSE@ thread-pthread.c -@CPU_I386_TRUE@am__append_3 = codegen_x86.c -@CPU_I386_TRUE@am__append_4 = -msse2 -@CPU_X86_64_TRUE@am__append_5 = codegen_x86-64.c -@USE_NETWORKING_TRUE@am__append_6 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_7 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_8 = ne2000.c nethandler.c wx-hostconfig.c -@USE_NETWORKING_TRUE@am__append_9 = slirp/libslirp.a +@CPU_I386_TRUE@am__append_6 = codegen_x86.c +@CPU_I386_TRUE@am__append_7 = -msse2 +@CPU_X86_64_TRUE@am__append_8 = codegen_x86-64.c +@USE_NETWORKING_TRUE@am__append_9 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_10 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_11 = ne2000.c nethandler.c wx-hostconfig.c +@USE_NETWORKING_TRUE@am__append_12 = slirp/libslirp.a subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/allegro.m4 \ @@ -123,24 +126,25 @@ 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 amstrad.c cdrom-ioctl-linux.c \ + acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-ioctl-linux.c \ cdrom-image.cc cdrom-null.c codegen.c codegen_ops.c \ codegen_timing_486.c codegen_timing_686.c \ codegen_timing_common.c codegen_timing_pentium.c \ - codegen_timing_winchip.c compaq.c config.c cpu.c dac.c \ - dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c \ - dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ - hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c \ - i430vx.c ide.c intel.c intel_flash.c io.c jim.c \ + codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ + device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ + esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 laserxt.c lpt.c mca.c mcr.c \ - mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c \ - mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ - opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c \ - ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.c \ - sis496.c sound.c sound_ad1848.c sound_adlib.c \ + keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c lpt_dac.c \ + lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ + mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ + nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pci.c pic.c \ + piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c \ + scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ + serial.c sio.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 \ @@ -168,11 +172,12 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ resid-fp/wave8580_P_T.cc resid-fp/wave8580__ST.cc \ resid-fp/wave.cc wx-main.cc wx-config_sel.c wx-dialogbox.cc \ wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ - wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2-midi.c wx-sdl2.c \ - wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ + wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ + wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c \ wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ - wx-shader_man.c wx-shaderconfig.cc allegro-gui.c \ + wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ + midi_alsa.c wx-sdl2-midi.c allegro-gui.c \ allegro-gui-config-sel.c allegro-gui-configure.c \ allegro-gui-deviceconfig.c allegro-gui-hdconf.c \ allegro-joystick.c allegro-keyboard.c allegro-main.c \ @@ -187,7 +192,6 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ @USE_WX_TRUE@ pcem-wx-sdl2-mouse.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-sdl2-keyboard.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-sdl2-video.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-midi.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-sdl2.$(OBJEXT) pcem-wx-config.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-deviceconfig.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-status.$(OBJEXT) \ @@ -199,8 +203,12 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ @USE_WX_TRUE@ pcem-wx-sdl2-video-gl3.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-glslp-parser.$(OBJEXT) \ @USE_WX_TRUE@ pcem-wx-shader_man.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-shaderconfig.$(OBJEXT) -@USE_WX_FALSE@am__objects_2 = pcem-allegro-gui.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-shaderconfig.$(OBJEXT) \ +@USE_WX_TRUE@ pcem-wx-joystickconfig.$(OBJEXT) +@USE_ALSA_TRUE@@USE_WX_TRUE@am__objects_2 = pcem-midi_alsa.$(OBJEXT) +@USE_ALSA_FALSE@@USE_WX_TRUE@am__objects_3 = \ +@USE_ALSA_FALSE@@USE_WX_TRUE@ pcem-wx-sdl2-midi.$(OBJEXT) +@USE_WX_FALSE@am__objects_4 = pcem-allegro-gui.$(OBJEXT) \ @USE_WX_FALSE@ pcem-allegro-gui-config-sel.$(OBJEXT) \ @USE_WX_FALSE@ pcem-allegro-gui-configure.$(OBJEXT) \ @USE_WX_FALSE@ pcem-allegro-gui-deviceconfig.$(OBJEXT) \ @@ -212,23 +220,23 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ @USE_WX_FALSE@ pcem-allegro-mouse.$(OBJEXT) \ @USE_WX_FALSE@ pcem-allegro-video.$(OBJEXT) \ @USE_WX_FALSE@ pcem-thread-pthread.$(OBJEXT) -@CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) -@CPU_X86_64_TRUE@am__objects_4 = pcem-codegen_x86-64.$(OBJEXT) -@USE_NETWORKING_TRUE@am__objects_5 = pcem-ne2000.$(OBJEXT) \ +@CPU_I386_TRUE@am__objects_5 = pcem-codegen_x86.$(OBJEXT) +@CPU_X86_64_TRUE@am__objects_6 = pcem-codegen_x86-64.$(OBJEXT) +@USE_NETWORKING_TRUE@am__objects_7 = pcem-ne2000.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(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-amstrad.$(OBJEXT) pcem-cdrom-ioctl-linux.$(OBJEXT) \ - pcem-cdrom-image.$(OBJEXT) pcem-cdrom-null.$(OBJEXT) \ - pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ - pcem-codegen_timing_486.$(OBJEXT) \ + pcem-amstrad.$(OBJEXT) pcem-cbm_io.$(OBJEXT) \ + pcem-cdrom-ioctl-linux.$(OBJEXT) pcem-cdrom-image.$(OBJEXT) \ + pcem-cdrom-null.$(OBJEXT) pcem-codegen.$(OBJEXT) \ + pcem-codegen_ops.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_common.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ pcem-codegen_timing_winchip.$(OBJEXT) pcem-compaq.$(OBJEXT) \ - pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) pcem-dac.$(OBJEXT) \ + pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) \ pcem-dells200.$(OBJEXT) pcem-device.$(OBJEXT) \ pcem-disc.$(OBJEXT) pcem-disc_fdi.$(OBJEXT) \ pcem-disc_img.$(OBJEXT) pcem-disc_sector.$(OBJEXT) \ @@ -246,54 +254,58 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(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-laserxt.$(OBJEXT) pcem-lpt.$(OBJEXT) pcem-mca.$(OBJEXT) \ - pcem-mcr.$(OBJEXT) pcem-mem.$(OBJEXT) pcem-mfm_at.$(OBJEXT) \ - pcem-mfm_xebec.$(OBJEXT) pcem-model.$(OBJEXT) \ - pcem-mouse.$(OBJEXT) pcem-mouse_msystems.$(OBJEXT) \ - pcem-mouse_ps2.$(OBJEXT) pcem-mouse_serial.$(OBJEXT) \ - pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ + pcem-laserxt.$(OBJEXT) pcem-lpt.$(OBJEXT) \ + pcem-lpt_dac.$(OBJEXT) pcem-lpt_dss.$(OBJEXT) \ + pcem-mca.$(OBJEXT) pcem-mcr.$(OBJEXT) pcem-mem.$(OBJEXT) \ + pcem-mfm_at.$(OBJEXT) pcem-mfm_xebec.$(OBJEXT) \ + pcem-model.$(OBJEXT) pcem-mouse.$(OBJEXT) \ + pcem-mouse_msystems.$(OBJEXT) pcem-mouse_ps2.$(OBJEXT) \ + pcem-mouse_serial.$(OBJEXT) pcem-neat.$(OBJEXT) \ + pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ pcem-olivetti_m24.$(OBJEXT) pcem-opti495.$(OBJEXT) \ pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pci.$(OBJEXT) \ pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) \ pcem-ppi.$(OBJEXT) pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) \ pcem-ps2_mca.$(OBJEXT) pcem-ps2_nvr.$(OBJEXT) \ pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) pcem-scat.$(OBJEXT) \ - pcem-serial.$(OBJEXT) pcem-sio.$(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_ps1.$(OBJEXT) pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ - pcem-tandy_eeprom.$(OBJEXT) pcem-tandy_rom.$(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_colorplus.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ - pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ - pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ - pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ - pcem-vid_incolor.$(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_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ - pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ + pcem-scsi.$(OBJEXT) pcem-scsi_53c400.$(OBJEXT) \ + pcem-scsi_aha1540.$(OBJEXT) pcem-scsi_cd.$(OBJEXT) \ + pcem-scsi_hd.$(OBJEXT) pcem-serial.$(OBJEXT) \ + pcem-sio.$(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_ps1.$(OBJEXT) \ + pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) \ + pcem-soundopenal.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ + pcem-tandy_rom.$(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_colorplus.$(OBJEXT) \ + pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ + pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ + pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ + pcem-vid_ics2595.$(OBJEXT) pcem-vid_incolor.$(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_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) \ + pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ pcem-cdrom_image.$(OBJEXT) pcem-dbopl.$(OBJEXT) \ pcem-nukedopl.$(OBJEXT) pcem-vid_cga_comp.$(OBJEXT) \ @@ -306,12 +318,14 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-wave8580_PST.$(OBJEXT) pcem-wave8580_P_T.$(OBJEXT) \ pcem-wave8580__ST.$(OBJEXT) pcem-wave.$(OBJEXT) \ $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) + $(am__objects_4) $(am__objects_5) $(am__objects_6) \ + $(am__objects_7) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = @USE_WX_FALSE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) \ -@USE_WX_FALSE@ $(am__append_9) -@USE_WX_TRUE@pcem_DEPENDENCIES = $(am__append_9) +@USE_WX_FALSE@ $(am__append_12) +@USE_WX_TRUE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@USE_WX_TRUE@ $(am__append_12) pcem_LINK = $(CXXLD) $(pcem_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SCRIPTS = $(noinst_SCRIPTS) @@ -434,6 +448,7 @@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ SDL2_CONFIG = @SDL2_CONFIG@ +SDL2_FRAMEWORK = @SDL2_FRAMEWORK@ SDL_CFLAGS = @SDL_CFLAGS@ SDL_LIBS = @SDL_LIBS@ SET_MAKE = @SET_MAKE@ @@ -510,24 +525,25 @@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = ../pcem CLEANFILES = $(noinst_SCRIPTS) pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ - acer386sx.c ali1429.c amstrad.c cdrom-ioctl-linux.c \ + acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-ioctl-linux.c \ cdrom-image.cc cdrom-null.c codegen.c codegen_ops.c \ codegen_timing_486.c codegen_timing_686.c \ codegen_timing_common.c codegen_timing_pentium.c \ - codegen_timing_winchip.c compaq.c config.c cpu.c dac.c \ - dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c \ - dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ - hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c \ - i430vx.c ide.c intel.c intel_flash.c io.c jim.c \ + codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ + device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ + esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 laserxt.c lpt.c mca.c mcr.c \ - mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c \ - mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ - opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c \ - ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c serial.c sio.c \ - sis496.c sound.c sound_ad1848.c sound_adlib.c \ + keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c lpt_dac.c \ + lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ + mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ + nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pci.c pic.c \ + piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c \ + scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ + serial.c sio.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 \ @@ -553,18 +569,19 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ 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) \ - $(am__append_3) $(am__append_5) $(am__append_8) + resid-fp/wave.cc $(am__append_1) $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_8) $(am__append_11) @USE_WX_FALSE@pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO \ -@USE_WX_FALSE@ $(am__append_4) $(am__append_6) +@USE_WX_FALSE@ $(am__append_7) $(am__append_9) @USE_WX_TRUE@pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell \ -@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_4) \ -@USE_WX_TRUE@ $(am__append_6) -@USE_WX_FALSE@pcem_CXXFLAGS = $(am__append_7) +@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_7) \ +@USE_WX_TRUE@ $(am__append_9) +@USE_WX_FALSE@pcem_CXXFLAGS = $(am__append_10) @USE_WX_TRUE@pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell \ -@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_7) -@USE_WX_FALSE@pcem_LDADD = $(allegro_LIBS) -lopenal $(am__append_9) -@USE_WX_TRUE@pcem_LDADD = @LIBS@ $(am__append_9) +@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_10) +@USE_WX_FALSE@pcem_LDADD = $(allegro_LIBS) -lopenal $(am__append_12) +@USE_WX_TRUE@pcem_LDADD = @LIBS@ $(am__append_2) $(am__append_12) all: all-am .SUFFIXES: @@ -669,6 +686,7 @@ distclean-compile: @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-cbm_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.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@ @@ -687,7 +705,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-convolve.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-dbopl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-device.Po@am__quote@ @@ -729,11 +746,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_xt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-laserxt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.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-mfm_at.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.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_msystems.Po@am__quote@ @@ -762,6 +782,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ @@ -855,6 +880,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ @@ -988,6 +1014,20 @@ pcem-amstrad.obj: amstrad.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-cbm_io.o: cbm_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cbm_io.o -MD -MP -MF $(DEPDIR)/pcem-cbm_io.Tpo -c -o pcem-cbm_io.o `test -f 'cbm_io.c' || echo '$(srcdir)/'`cbm_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cbm_io.Tpo $(DEPDIR)/pcem-cbm_io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cbm_io.c' object='pcem-cbm_io.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cbm_io.o `test -f 'cbm_io.c' || echo '$(srcdir)/'`cbm_io.c + +pcem-cbm_io.obj: cbm_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cbm_io.obj -MD -MP -MF $(DEPDIR)/pcem-cbm_io.Tpo -c -o pcem-cbm_io.obj `if test -f 'cbm_io.c'; then $(CYGPATH_W) 'cbm_io.c'; else $(CYGPATH_W) '$(srcdir)/cbm_io.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cbm_io.Tpo $(DEPDIR)/pcem-cbm_io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cbm_io.c' object='pcem-cbm_io.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cbm_io.obj `if test -f 'cbm_io.c'; then $(CYGPATH_W) 'cbm_io.c'; else $(CYGPATH_W) '$(srcdir)/cbm_io.c'; fi` + pcem-cdrom-ioctl-linux.o: cdrom-ioctl-linux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po @@ -1156,20 +1196,6 @@ pcem-cpu.obj: cpu.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-dac.Tpo $(DEPDIR)/pcem-dac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dac.c' object='pcem-dac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-dac.Tpo $(DEPDIR)/pcem-dac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dac.c' object='pcem-dac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-dells200.o: dells200.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.o -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po @@ -1688,6 +1714,34 @@ pcem-lpt.obj: lpt.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-lpt_dac.o: lpt_dac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-lpt_dac.o -MD -MP -MF $(DEPDIR)/pcem-lpt_dac.Tpo -c -o pcem-lpt_dac.o `test -f 'lpt_dac.c' || echo '$(srcdir)/'`lpt_dac.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-lpt_dac.Tpo $(DEPDIR)/pcem-lpt_dac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lpt_dac.c' object='pcem-lpt_dac.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-lpt_dac.o `test -f 'lpt_dac.c' || echo '$(srcdir)/'`lpt_dac.c + +pcem-lpt_dac.obj: lpt_dac.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-lpt_dac.obj -MD -MP -MF $(DEPDIR)/pcem-lpt_dac.Tpo -c -o pcem-lpt_dac.obj `if test -f 'lpt_dac.c'; then $(CYGPATH_W) 'lpt_dac.c'; else $(CYGPATH_W) '$(srcdir)/lpt_dac.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-lpt_dac.Tpo $(DEPDIR)/pcem-lpt_dac.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lpt_dac.c' object='pcem-lpt_dac.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-lpt_dac.obj `if test -f 'lpt_dac.c'; then $(CYGPATH_W) 'lpt_dac.c'; else $(CYGPATH_W) '$(srcdir)/lpt_dac.c'; fi` + +pcem-lpt_dss.o: lpt_dss.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-lpt_dss.o -MD -MP -MF $(DEPDIR)/pcem-lpt_dss.Tpo -c -o pcem-lpt_dss.o `test -f 'lpt_dss.c' || echo '$(srcdir)/'`lpt_dss.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-lpt_dss.Tpo $(DEPDIR)/pcem-lpt_dss.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lpt_dss.c' object='pcem-lpt_dss.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-lpt_dss.o `test -f 'lpt_dss.c' || echo '$(srcdir)/'`lpt_dss.c + +pcem-lpt_dss.obj: lpt_dss.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-lpt_dss.obj -MD -MP -MF $(DEPDIR)/pcem-lpt_dss.Tpo -c -o pcem-lpt_dss.obj `if test -f 'lpt_dss.c'; then $(CYGPATH_W) 'lpt_dss.c'; else $(CYGPATH_W) '$(srcdir)/lpt_dss.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-lpt_dss.Tpo $(DEPDIR)/pcem-lpt_dss.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lpt_dss.c' object='pcem-lpt_dss.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-lpt_dss.obj `if test -f 'lpt_dss.c'; then $(CYGPATH_W) 'lpt_dss.c'; else $(CYGPATH_W) '$(srcdir)/lpt_dss.c'; fi` + pcem-mca.o: mca.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mca.o -MD -MP -MF $(DEPDIR)/pcem-mca.Tpo -c -o pcem-mca.o `test -f 'mca.c' || echo '$(srcdir)/'`mca.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mca.Tpo $(DEPDIR)/pcem-mca.Po @@ -2094,6 +2148,76 @@ pcem-scat.obj: scat.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scat.obj `if test -f 'scat.c'; then $(CYGPATH_W) 'scat.c'; else $(CYGPATH_W) '$(srcdir)/scat.c'; fi` +pcem-scsi.o: scsi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi.o -MD -MP -MF $(DEPDIR)/pcem-scsi.Tpo -c -o pcem-scsi.o `test -f 'scsi.c' || echo '$(srcdir)/'`scsi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi.Tpo $(DEPDIR)/pcem-scsi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi.c' object='pcem-scsi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi.o `test -f 'scsi.c' || echo '$(srcdir)/'`scsi.c + +pcem-scsi.obj: scsi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi.obj -MD -MP -MF $(DEPDIR)/pcem-scsi.Tpo -c -o pcem-scsi.obj `if test -f 'scsi.c'; then $(CYGPATH_W) 'scsi.c'; else $(CYGPATH_W) '$(srcdir)/scsi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi.Tpo $(DEPDIR)/pcem-scsi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi.c' object='pcem-scsi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi.obj `if test -f 'scsi.c'; then $(CYGPATH_W) 'scsi.c'; else $(CYGPATH_W) '$(srcdir)/scsi.c'; fi` + +pcem-scsi_53c400.o: scsi_53c400.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_53c400.o -MD -MP -MF $(DEPDIR)/pcem-scsi_53c400.Tpo -c -o pcem-scsi_53c400.o `test -f 'scsi_53c400.c' || echo '$(srcdir)/'`scsi_53c400.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_53c400.Tpo $(DEPDIR)/pcem-scsi_53c400.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_53c400.c' object='pcem-scsi_53c400.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_53c400.o `test -f 'scsi_53c400.c' || echo '$(srcdir)/'`scsi_53c400.c + +pcem-scsi_53c400.obj: scsi_53c400.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_53c400.obj -MD -MP -MF $(DEPDIR)/pcem-scsi_53c400.Tpo -c -o pcem-scsi_53c400.obj `if test -f 'scsi_53c400.c'; then $(CYGPATH_W) 'scsi_53c400.c'; else $(CYGPATH_W) '$(srcdir)/scsi_53c400.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_53c400.Tpo $(DEPDIR)/pcem-scsi_53c400.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_53c400.c' object='pcem-scsi_53c400.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_53c400.obj `if test -f 'scsi_53c400.c'; then $(CYGPATH_W) 'scsi_53c400.c'; else $(CYGPATH_W) '$(srcdir)/scsi_53c400.c'; fi` + +pcem-scsi_aha1540.o: scsi_aha1540.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_aha1540.o -MD -MP -MF $(DEPDIR)/pcem-scsi_aha1540.Tpo -c -o pcem-scsi_aha1540.o `test -f 'scsi_aha1540.c' || echo '$(srcdir)/'`scsi_aha1540.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_aha1540.Tpo $(DEPDIR)/pcem-scsi_aha1540.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_aha1540.c' object='pcem-scsi_aha1540.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_aha1540.o `test -f 'scsi_aha1540.c' || echo '$(srcdir)/'`scsi_aha1540.c + +pcem-scsi_aha1540.obj: scsi_aha1540.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_aha1540.obj -MD -MP -MF $(DEPDIR)/pcem-scsi_aha1540.Tpo -c -o pcem-scsi_aha1540.obj `if test -f 'scsi_aha1540.c'; then $(CYGPATH_W) 'scsi_aha1540.c'; else $(CYGPATH_W) '$(srcdir)/scsi_aha1540.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_aha1540.Tpo $(DEPDIR)/pcem-scsi_aha1540.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_aha1540.c' object='pcem-scsi_aha1540.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_aha1540.obj `if test -f 'scsi_aha1540.c'; then $(CYGPATH_W) 'scsi_aha1540.c'; else $(CYGPATH_W) '$(srcdir)/scsi_aha1540.c'; fi` + +pcem-scsi_cd.o: scsi_cd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_cd.o -MD -MP -MF $(DEPDIR)/pcem-scsi_cd.Tpo -c -o pcem-scsi_cd.o `test -f 'scsi_cd.c' || echo '$(srcdir)/'`scsi_cd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_cd.Tpo $(DEPDIR)/pcem-scsi_cd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_cd.c' object='pcem-scsi_cd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_cd.o `test -f 'scsi_cd.c' || echo '$(srcdir)/'`scsi_cd.c + +pcem-scsi_cd.obj: scsi_cd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_cd.obj -MD -MP -MF $(DEPDIR)/pcem-scsi_cd.Tpo -c -o pcem-scsi_cd.obj `if test -f 'scsi_cd.c'; then $(CYGPATH_W) 'scsi_cd.c'; else $(CYGPATH_W) '$(srcdir)/scsi_cd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_cd.Tpo $(DEPDIR)/pcem-scsi_cd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_cd.c' object='pcem-scsi_cd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_cd.obj `if test -f 'scsi_cd.c'; then $(CYGPATH_W) 'scsi_cd.c'; else $(CYGPATH_W) '$(srcdir)/scsi_cd.c'; fi` + +pcem-scsi_hd.o: scsi_hd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_hd.o -MD -MP -MF $(DEPDIR)/pcem-scsi_hd.Tpo -c -o pcem-scsi_hd.o `test -f 'scsi_hd.c' || echo '$(srcdir)/'`scsi_hd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_hd.Tpo $(DEPDIR)/pcem-scsi_hd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_hd.c' object='pcem-scsi_hd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_hd.o `test -f 'scsi_hd.c' || echo '$(srcdir)/'`scsi_hd.c + +pcem-scsi_hd.obj: scsi_hd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_hd.obj -MD -MP -MF $(DEPDIR)/pcem-scsi_hd.Tpo -c -o pcem-scsi_hd.obj `if test -f 'scsi_hd.c'; then $(CYGPATH_W) 'scsi_hd.c'; else $(CYGPATH_W) '$(srcdir)/scsi_hd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_hd.Tpo $(DEPDIR)/pcem-scsi_hd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_hd.c' object='pcem-scsi_hd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_hd.obj `if test -f 'scsi_hd.c'; then $(CYGPATH_W) 'scsi_hd.c'; else $(CYGPATH_W) '$(srcdir)/scsi_hd.c'; fi` + pcem-serial.o: serial.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-serial.Tpo $(DEPDIR)/pcem-serial.Po @@ -3200,20 +3324,6 @@ pcem-wx-sdl2-video.obj: wx-sdl2-video.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-video.obj `if test -f 'wx-sdl2-video.c'; then $(CYGPATH_W) 'wx-sdl2-video.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-video.c'; fi` -pcem-wx-sdl2-midi.o: wx-sdl2-midi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-midi.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-midi.Tpo -c -o pcem-wx-sdl2-midi.o `test -f 'wx-sdl2-midi.c' || echo '$(srcdir)/'`wx-sdl2-midi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-midi.Tpo $(DEPDIR)/pcem-wx-sdl2-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-midi.c' object='pcem-wx-sdl2-midi.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.o `test -f 'wx-sdl2-midi.c' || echo '$(srcdir)/'`wx-sdl2-midi.c - -pcem-wx-sdl2-midi.obj: wx-sdl2-midi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-midi.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-midi.Tpo -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-midi.Tpo $(DEPDIR)/pcem-wx-sdl2-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-midi.c' object='pcem-wx-sdl2-midi.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` - pcem-wx-sdl2.o: wx-sdl2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2.Tpo -c -o pcem-wx-sdl2.o `test -f 'wx-sdl2.c' || echo '$(srcdir)/'`wx-sdl2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2.Tpo $(DEPDIR)/pcem-wx-sdl2.Po @@ -3354,6 +3464,34 @@ pcem-wx-shader_man.obj: wx-shader_man.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-shader_man.obj `if test -f 'wx-shader_man.c'; then $(CYGPATH_W) 'wx-shader_man.c'; else $(CYGPATH_W) '$(srcdir)/wx-shader_man.c'; fi` +pcem-midi_alsa.o: midi_alsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-midi_alsa.o -MD -MP -MF $(DEPDIR)/pcem-midi_alsa.Tpo -c -o pcem-midi_alsa.o `test -f 'midi_alsa.c' || echo '$(srcdir)/'`midi_alsa.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-midi_alsa.Tpo $(DEPDIR)/pcem-midi_alsa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='midi_alsa.c' object='pcem-midi_alsa.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-midi_alsa.o `test -f 'midi_alsa.c' || echo '$(srcdir)/'`midi_alsa.c + +pcem-midi_alsa.obj: midi_alsa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-midi_alsa.obj -MD -MP -MF $(DEPDIR)/pcem-midi_alsa.Tpo -c -o pcem-midi_alsa.obj `if test -f 'midi_alsa.c'; then $(CYGPATH_W) 'midi_alsa.c'; else $(CYGPATH_W) '$(srcdir)/midi_alsa.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-midi_alsa.Tpo $(DEPDIR)/pcem-midi_alsa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='midi_alsa.c' object='pcem-midi_alsa.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-midi_alsa.obj `if test -f 'midi_alsa.c'; then $(CYGPATH_W) 'midi_alsa.c'; else $(CYGPATH_W) '$(srcdir)/midi_alsa.c'; fi` + +pcem-wx-sdl2-midi.o: wx-sdl2-midi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-midi.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-midi.Tpo -c -o pcem-wx-sdl2-midi.o `test -f 'wx-sdl2-midi.c' || echo '$(srcdir)/'`wx-sdl2-midi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-midi.Tpo $(DEPDIR)/pcem-wx-sdl2-midi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-midi.c' object='pcem-wx-sdl2-midi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.o `test -f 'wx-sdl2-midi.c' || echo '$(srcdir)/'`wx-sdl2-midi.c + +pcem-wx-sdl2-midi.obj: wx-sdl2-midi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-midi.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-midi.Tpo -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-midi.Tpo $(DEPDIR)/pcem-wx-sdl2-midi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-midi.c' object='pcem-wx-sdl2-midi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` + pcem-allegro-gui.o: allegro-gui.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po @@ -4040,6 +4178,20 @@ pcem-wx-shaderconfig.obj: wx-shaderconfig.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-shaderconfig.obj `if test -f 'wx-shaderconfig.cc'; then $(CYGPATH_W) 'wx-shaderconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-shaderconfig.cc'; fi` +pcem-wx-joystickconfig.o: wx-joystickconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-joystickconfig.o -MD -MP -MF $(DEPDIR)/pcem-wx-joystickconfig.Tpo -c -o pcem-wx-joystickconfig.o `test -f 'wx-joystickconfig.cc' || echo '$(srcdir)/'`wx-joystickconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-joystickconfig.Tpo $(DEPDIR)/pcem-wx-joystickconfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-joystickconfig.cc' object='pcem-wx-joystickconfig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-joystickconfig.o `test -f 'wx-joystickconfig.cc' || echo '$(srcdir)/'`wx-joystickconfig.cc + +pcem-wx-joystickconfig.obj: wx-joystickconfig.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-joystickconfig.obj -MD -MP -MF $(DEPDIR)/pcem-wx-joystickconfig.Tpo -c -o pcem-wx-joystickconfig.obj `if test -f 'wx-joystickconfig.cc'; then $(CYGPATH_W) 'wx-joystickconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-joystickconfig.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-joystickconfig.Tpo $(DEPDIR)/pcem-wx-joystickconfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-joystickconfig.cc' object='pcem-wx-joystickconfig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-joystickconfig.obj `if test -f 'wx-joystickconfig.cc'; then $(CYGPATH_W) 'wx-joystickconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-joystickconfig.cc'; fi` + .cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po diff --git a/src/midi_alsa.c b/src/midi_alsa.c new file mode 100644 index 0000000..f513c23 --- /dev/null +++ b/src/midi_alsa.c @@ -0,0 +1,184 @@ +#include +#include "ibm.h" +#include "config.h" +#include "plat-midi.h" + +#define MAX_MIDI_DEVICES 128 + +static struct +{ + int card; + int device; + int sub; + char name[50]; +} midi_devices[MAX_MIDI_DEVICES]; + +static int midi_device_count = 0; + +static int midi_queried = 0; + +static snd_rawmidi_t *midiout = NULL; + +static void midi_query() +{ + int status; + int card = -1; + + midi_queried = 1; + + if ((status = snd_card_next(&card)) < 0) + return; + + if (card < 0) + return; /*No cards*/ + + while (card >= 0) + { + char *shortname; + + if ((status = snd_card_get_name(card, &shortname)) >= 0) + { + snd_ctl_t *ctl; + char name[32]; + + sprintf(name, "hw:%i", card); + + if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) + { + int device = -1; + + do + { + status = snd_ctl_rawmidi_next_device(ctl, &device); + if (status >= 0 && device != -1) + { + snd_rawmidi_info_t *info; + int sub_nr, sub; + + snd_rawmidi_info_alloca(&info); + snd_rawmidi_info_set_device(info, device); + snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); + snd_ctl_rawmidi_info(ctl, info); + sub_nr = snd_rawmidi_info_get_subdevices_count(info); + pclog("sub_nr=%i\n",sub_nr); + + for (sub = 0; sub < sub_nr; sub++) + { + snd_rawmidi_info_set_subdevice(info, sub); + + if (snd_ctl_rawmidi_info(ctl, info) == 0) + { + pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device,sub); + + midi_devices[midi_device_count].card = card; + midi_devices[midi_device_count].device = device; + midi_devices[midi_device_count].sub = sub; + snprintf(midi_devices[midi_device_count].name, 50, "%s (%i:%i:%i)", shortname, card, device, sub); + midi_device_count++; + if (midi_device_count >= MAX_MIDI_DEVICES) + return; + } + } + } + } while (device >= 0); + } + } + + if (snd_card_next(&card) < 0) + break; + } +} + +void midi_init() +{ + char portname[32]; + int midi_id; + + if (!midi_queried) + midi_query(); + + midi_id = config_get_int(CFG_MACHINE, NULL, "midi", 0); + + sprintf(portname, "hw:%i,%i,%i", midi_devices[midi_id].card, + midi_devices[midi_id].device, + midi_devices[midi_id].sub); + pclog("Opening MIDI port %s\n", portname); + + if (snd_rawmidi_open(NULL, &midiout, portname, SND_RAWMIDI_SYNC) < 0) + { + pclog("Failed to open MIDI\n"); + return; + } +} + +void midi_close() +{ + if (midiout != NULL) + { + snd_rawmidi_close(midiout); + midiout = NULL; + } +} + +static int midi_pos, midi_len; +static uint8_t midi_command[4]; +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]; + +void midi_write(uint8_t val) +{ + //pclog("Write MIDI %02x\n", val); + + if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) + { + midi_pos = 0; + midi_len = midi_lengths[(val >> 4) & 7]; + midi_command[0] = midi_command[1] = midi_command[2] = midi_command[3] = 0; + if (val == 0xf0) + midi_insysex = 1; + } + + if (midi_insysex) + { + midi_sysex_data[midi_pos++] = val; + + if (val == 0xf7 || midi_pos >= 1024+2) + { +/* pclog("MIDI send sysex %i: ", midi_pos); + for (int i = 0; i < midi_pos; i++) + pclog("%02x ", midi_sysex_data[i]); + pclog("\n");*/ + snd_rawmidi_write(midiout, midi_sysex_data, midi_pos); +// pclog("Sent sysex\n"); + midi_insysex = 0; + } + return; + } + + if (midi_len) + { + midi_command[midi_pos] = val; + + midi_pos++; + + if (midi_pos == midi_len) + { +// pclog("MIDI send %i: %02x %02x %02x %02x\n", midi_len, midi_command[0], midi_command[1], midi_command[2], midi_command[3]); + snd_rawmidi_write(midiout, midi_command, midi_len); + } + } +} + +int midi_get_num_devs() +{ + if (!midi_queried) + midi_query(); + + return midi_device_count; +} + +void midi_get_dev_name(int num, char *s) +{ + strcpy(s, midi_devices[num].name); +} From 9f2b58b7c414f7d6f330b3f3bb2220dc0f7c8d33 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Oct 2017 20:56:33 +0100 Subject: [PATCH 0163/1050] Added new SCAT chipset machines - GW-286CT GEAR, Samsung SPC-4216P and KMX-C-02. Patch from Greatpsycho. --- src/ibm.h | 3 + src/mem.c | 39 +++++++++++ src/model.c | 10 +++ src/nvr.c | 6 ++ src/scat.c | 182 +++++++++++++++++++++++++++++++++++++++++++--------- src/scat.h | 7 ++ 6 files changed, 216 insertions(+), 31 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 8738bb3..4a4f28d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -405,11 +405,14 @@ enum ROM_CMDPC30, ROM_AMI286, ROM_AWARD286, + ROM_GW286CT, ROM_SPC4200P, + ROM_SPC4216P, ROM_DELL200, ROM_MISC286, ROM_IBMAT386, ROM_ACER386, + ROM_KMXC02, ROM_MEGAPC, ROM_AMI386SX, ROM_AMI486, diff --git a/src/mem.c b/src/mem.c index 2af1e99..65154a6 100644 --- a/src/mem.c +++ b/src/mem.c @@ -370,6 +370,13 @@ int loadbios() fclose(f); return 1; + case ROM_KMXC02: + f=romfopen("kmxc02/3ctm005.bin","rb"); + if (!f) break; + fread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_AMI286: f=romfopen("ami286/amic206.bin","rb"); if (!f) break; @@ -385,6 +392,13 @@ int loadbios() fclose(f); return 1; + case ROM_GW286CT: + f=romfopen("gw286ct/2ctc001.bin","rb"); + if (!f) break; + fread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_SPC4200P: f=romfopen("spc4200p/u8.01","rb"); if (!f) break; @@ -392,6 +406,31 @@ int loadbios() fclose(f); return 1; + case ROM_SPC4216P: + f=romfopen("spc4216p/phoenix.bin","rb"); + if (!f) + { + f = romfopen("spc4216p/7101.u8", "rb"); + ff = romfopen("spc4216p/ac64.u10","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; + } + else + { + fread(rom,65536,1,f); + + fclose(f); + return 1; + } + break; + case ROM_EUROPC: // return 0; f=romfopen("europc/50145","rb"); diff --git a/src/model.c b/src/model.c index 39d2c9a..1613279 100644 --- a/src/model.c +++ b/src/model.c @@ -78,6 +78,7 @@ void ps2_model_55sx_init(); void ps2_model_80_init(); void at_neat_init(); void at_scat_init(); +void at_scatsx_init(); void at_acer386sx_init(); void at_wd76c10_init(); void at_ali1429_init(); @@ -121,11 +122,13 @@ MODEL models[] = {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_cbm_init, NULL}, {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, + {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT , 512,16384,128, at_scat_init, NULL}, {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512,2048, 128, at_scat_init, NULL}, + {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, @@ -133,6 +136,7 @@ MODEL models[] = {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, + {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT , 512,16384,512, at_scatsx_init, NULL}, {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, @@ -436,6 +440,12 @@ void at_scat_init() scat_init(); } +void at_scatsx_init() +{ + at_init(); + scatsx_init(); +} + void at_acer386sx_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index e4934e0..0e27a02 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -232,11 +232,14 @@ void loadnvr() case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break; case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); nvrmask = 127; break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break; + case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; + case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); nvrmask = 127; break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); break; case ROM_ACER386: f = nvrfopen("acer386.nvr", "rb"); nvrmask = 127; break; + case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "rb"); nvrmask = 127; break; case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "rb"); nvrmask = 127; break; case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "rb"); nvrmask = 127; break; case ROM_AMI486: f = nvrfopen("ami486.nvr", "rb"); nvrmask = 127; break; @@ -296,11 +299,14 @@ void savenvr() case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "wb"); break; case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break; + case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; + case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); break; case ROM_ACER386: f = nvrfopen("acer386.nvr", "wb"); break; + case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "wb"); break; case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "wb"); break; case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "wb"); break; case ROM_AMI486: f = nvrfopen("ami486.nvr", "wb"); break; diff --git a/src/scat.c b/src/scat.c index a565047..0c0c74e 100644 --- a/src/scat.c +++ b/src/scat.c @@ -19,6 +19,13 @@ static mem_mapping_t scat_shadowram_mapping[6]; static mem_mapping_t scat_4000_9FFF_mapping[24]; static mem_mapping_t scat_A000_BFFF_mapping; +// TODO - 82C836 chipset's memory address mapping isn't fully implemented yet, so memory configuration is hardcoded now. +static int scatsx_mem_conf_val[33] = { 0x00, 0x01, 0x03, 0x04, 0x05, 0x08, 0x06, 0x06, + 0x0c, 0x09, 0x07, 0x07, 0x0d, 0x0a, 0x0f, 0x0f, + 0x0e, 0x0e, 0x10, 0x10, 0x13, 0x13, 0x11, 0x11, + 0x14, 0x14, 0x12, 0x12, 0x15, 0x15, 0x15, 0x15, + 0x16 }; + uint8_t scat_read(uint16_t port, void *priv); void scat_write(uint16_t port, uint8_t val, void *priv); @@ -53,7 +60,7 @@ void scat_shadow_state_update() void scat_set_xms_bound(uint8_t val) { - uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10; + uint32_t max_xms_size = (mem_size >= 16128) ? (((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) ? 0xFE0000 : 0xFC0000) : mem_size << 10; int i; switch (val & 0x0F) @@ -77,26 +84,38 @@ void scat_set_xms_bound(uint8_t val) scat_xms_bound = 0x400000; break; case 7: - scat_xms_bound = 0x600000; + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x600000 : 0x500000; break; case 8: - scat_xms_bound = 0x800000; + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x800000 : 0x700000; break; case 9: - scat_xms_bound = 0xA00000; + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0xA00000 : 0x800000; break; case 10: - scat_xms_bound = 0xC00000; + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0xC00000 : 0x900000; break; case 11: - scat_xms_bound = 0xE00000; + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0xE00000 : 0xA00000; + break; + case 12: + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xB00000; + break; + case 13: + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xC00000; + break; + case 14: + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xD00000; + break; + case 15: + scat_xms_bound = (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? max_xms_size : 0xF00000; break; default: - scat_xms_bound = (mem_size >= 16384 ? 0xFC0000 : mem_size << 10); + scat_xms_bound = max_xms_size; break; } - if ((val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) + if ((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) { if (val != 1) { @@ -139,17 +158,25 @@ uint32_t get_scat_addr(uint32_t addr, scat_t *p) if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; - if (mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7 || (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) != 0)) - addr = (addr & ~0x780000) | ((addr & 0x600000) >> 2); - else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) + if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - addr &= ~0x600000; - if(mem_size >= 2048) - addr |= (addr & 0x180000) << 2; - } + if (mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7 || (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) != 0)) + addr = (addr & ~0x780000) | ((addr & 0x600000) >> 2); + else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) + { + addr &= ~0x600000; + if(mem_size > 2048 || (mem_size == 2048 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 6)) + addr |= (addr & 0x180000) << 2; + } - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) - addr ^= mem_size < 2048 ? 0x1F0000 : 0x670000; + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) + addr ^= mem_size < 2048 ? 0x1F0000 : 0x670000; + } + else + { + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) + addr ^= 0x1F0000; + } return addr; } @@ -179,7 +206,7 @@ void scat_set_global_EMS_state(int state) int i; uint32_t base_addr, virt_addr; - for(i=0; i<32; i++) + for(i=((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0 : 24; i<32; i++) { base_addr = (i + 16) << 14; if(i >= 24) @@ -244,13 +271,13 @@ void scat_write(uint16_t port, uint8_t val, void *priv) break; case SCAT_POWER_MANAGEMENT: // TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. - val &= 0x40; + val &= (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x40 : 0x60; scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: - if((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((scat_regs[SCAT_VERSION] & 0xF0) != 0)) { - if((val & 0x0F) == 3) + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (val & 0x1F) == 3)) { if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); for(index=0;index<6;index++) @@ -271,13 +298,21 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } scat_map_update = 1; - cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; - cpu_update_waitstates(); + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) + { + cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; + cpu_update_waitstates(); + } + else + { + if(mem_size != 1024 || ((val & 0x1F) != 2 && (val & 0x1F) != 3)) + val = (val & 0xe0) | scatsx_mem_conf_val[mem_size >> 9]; + } scat_reg_valid = 1; break; case SCAT_EXTENDED_BOUNDARY: - scat_set_xms_bound(val & 0x4f); + scat_set_xms_bound(val & ((scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x4f : 0x1f)); mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0x40) scat_map_update = 1; scat_reg_valid = 1; @@ -290,6 +325,19 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; scat_shadow_update = 1; break; + case SCATSX_LAPTOP_FEATURES: + if((scat_regs[SCAT_VERSION] & 0xF0) != 0) + { + val = (val & ~8) | (scat_regs[SCATSX_LAPTOP_FEATURES] & 8); + scat_reg_valid = 1; + } + break; + case SCATSX_FAST_VIDEO_CONTROL: + case SCATSX_FAST_VIDEORAM_ENABLE: + case SCATSX_HIGH_PERFORMANCE_REFRESH: + case SCATSX_CAS_TIMING_FOR_DMA: + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) scat_reg_valid = 1; + break; default: break; } @@ -322,7 +370,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // 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; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; scat_stat[index].regs_2x8 = val; base_addr = (index + 16) << 14; if(index >= 24) @@ -342,7 +391,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // 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; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; scat_stat[index].regs_2x9 = val; base_addr = (index + 16) << 14; if(index >= 24) @@ -371,7 +421,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if (scat_ems_reg_2xA & 0x80) { - scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & 0x1f); + scat_ems_reg_2xA = (scat_ems_reg_2xA & 0xe0) | ((scat_ems_reg_2xA + 1) & (((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0x1f : 3)); } } break; @@ -380,7 +430,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - scat_ems_reg_2xA = val; + scat_ems_reg_2xA = ((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? val : val & 0xc3; } break; } @@ -398,7 +448,9 @@ uint8_t scat_read(uint16_t port, void *priv) val = (scat_regs[scat_index] & 0x3f) | (~nmi_mask & 0x80) | ((mem_a20_key & 2) << 5); break; case SCAT_DRAM_CONFIGURATION: - val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); + if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); + else if(mem_size != 1024) val = (scat_regs[scat_index] & 0xe0) | scatsx_mem_conf_val[mem_size >> 9]; + else val = scat_regs[scat_index]; break; default: val = scat_regs[scat_index]; @@ -416,7 +468,8 @@ uint8_t scat_read(uint16_t port, void *priv) if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - index = scat_ems_reg_2xA & 0x1F; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; val = scat_stat[index].regs_2x8; } break; @@ -425,7 +478,8 @@ uint8_t scat_read(uint16_t port, void *priv) if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - index = scat_ems_reg_2xA & 0x1F; + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) index = scat_ems_reg_2xA & 0x1F; + else index = ((scat_ems_reg_2xA & 0x40) >> 4) + (scat_ems_reg_2xA & 0x3) + 24; val = scat_stat[index].regs_2x9; } break; @@ -523,3 +577,69 @@ void scat_init() scat_set_xms_bound(0); scat_shadow_state_update(); } + +void scatsx_init() +{ + int i; + + io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_sethandler(0x0080, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); + + for (i = 0; i < 256; i++) + { + scat_regs[i] = 0xff; + } + + scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; + scat_regs[SCAT_VERSION] = 0x13; + scat_regs[SCAT_CLOCK_CONTROL] = 6; + scat_regs[SCAT_PERIPHERAL_CONTROL] = 0; + scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; + scat_regs[SCAT_POWER_MANAGEMENT] = 0; + scat_regs[SCAT_ROM_ENABLE] = 0xC0; + scat_regs[SCAT_RAM_WRITE_PROTECT] = 0; + scat_regs[SCAT_SHADOW_RAM_ENABLE_1] = 0; + scat_regs[SCAT_SHADOW_RAM_ENABLE_2] = 0; + scat_regs[SCAT_SHADOW_RAM_ENABLE_3] = 0; + scat_regs[SCAT_DRAM_CONFIGURATION] = 1; + scat_regs[SCAT_EXTENDED_BOUNDARY] = 0; + scat_regs[SCAT_EMS_CONTROL] = 0; + scat_regs[SCATSX_LAPTOP_FEATURES] = 0; + scat_regs[SCATSX_FAST_VIDEO_CONTROL] = 0; + scat_regs[SCATSX_FAST_VIDEORAM_ENABLE] = 0; + scat_regs[SCATSX_HIGH_PERFORMANCE_REFRESH] = 8; + scat_regs[SCATSX_CAS_TIMING_FOR_DMA] = 3; + scat_port_92 = 0; + + mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + + for (i = 16; i < 24; i++) + { + mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + } + + mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_A000_BFFF_mapping); + + for (i = 24; i < 32; i++) + { + scat_stat[i].regs_2x8 = 0xff; + scat_stat[i].regs_2x9 = 0x03; + mem_mapping_add(&scat_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + ((i + 28) << 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. + 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); + } + + for(i=0;i<6;i++) + mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + + scat_set_xms_bound(0); + scat_shadow_state_update(); +} diff --git a/src/scat.h b/src/scat.h index 8c822ec..cab41ba 100644 --- a/src/scat.h +++ b/src/scat.h @@ -13,6 +13,12 @@ #define SCAT_EXTENDED_BOUNDARY 0x4E #define SCAT_EMS_CONTROL 0x4F +#define SCATSX_LAPTOP_FEATURES 0x60 +#define SCATSX_FAST_VIDEO_CONTROL 0x61 +#define SCATSX_FAST_VIDEORAM_ENABLE 0x62 +#define SCATSX_HIGH_PERFORMANCE_REFRESH 0x63 +#define SCATSX_CAS_TIMING_FOR_DMA 0x64 + typedef struct scat_t { uint8_t regs_2x8; @@ -20,3 +26,4 @@ typedef struct scat_t } scat_t; void scat_init(); +void scatsx_init(); From a44fcb196bf907d51326ebf0b5da46cc194135b9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Oct 2017 21:36:41 +0100 Subject: [PATCH 0164/1050] NVR files now stored per-config. --- nvr/default/430vx.nvr | Bin 0 -> 128 bytes nvr/default/acer386.nvr | Bin 0 -> 128 bytes nvr/default/adgold.bin | Bin 0 -> 24 bytes nvr/default/aha1542c.nvr | Bin 0 -> 32 bytes nvr/default/ami286.nvr | Bin 0 -> 128 bytes nvr/default/ami386.nvr | Bin 0 -> 128 bytes nvr/default/ami386dx_opti495.nvr | Bin 0 -> 128 bytes nvr/default/ami486.nvr | Bin 0 -> 128 bytes nvr/default/at.nvr | Bin 0 -> 128 bytes nvr/default/award286.nvr | Bin 0 -> 128 bytes nvr/default/cmdpc30.nvr | Bin 0 -> 128 bytes nvr/default/dell200.nvr | Bin 0 -> 128 bytes nvr/default/deskpro386.nvr | Bin 0 -> 128 bytes nvr/default/endeavor.nvr | Bin 0 -> 128 bytes nvr/default/europc.nvr | Bin 0 -> 16 bytes nvr/default/gw286ct.nvr | Bin 0 -> 128 bytes nvr/default/hot-433.nvr | Bin 0 -> 128 bytes nvr/default/ibmps1_2011.nvr | Bin 0 -> 128 bytes nvr/default/ibmps1_2121.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m50.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m55sx.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m60.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m65sx.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m70.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m70_sec.nvr | Bin 0 -> 8192 bytes nvr/default/ibmps2_m80.nvr | Bin 0 -> 128 bytes nvr/default/ibmps2_m80_sec.nvr | Bin 0 -> 8192 bytes nvr/default/kmxc02.nvr | Bin 0 -> 128 bytes nvr/default/megapc.nvr | Bin 0 -> 128 bytes nvr/default/mr386dx_opti495.nvr | Bin 0 -> 128 bytes nvr/default/pc1512.nvr | Bin 0 -> 128 bytes nvr/default/pc1640.nvr | Bin 0 -> 128 bytes nvr/default/pc200.nvr | 1 + nvr/default/pc2086.nvr | Bin 0 -> 128 bytes nvr/default/pc3086.nvr | Bin 0 -> 128 bytes nvr/default/revenge.nvr | Bin 0 -> 128 bytes nvr/default/sis496.nvr | Bin 0 -> 128 bytes nvr/default/spc4200p.nvr | Bin 0 -> 128 bytes nvr/default/spc4216p.nvr | Bin 0 -> 128 bytes nvr/default/tandy1000hx.bin | Bin 0 -> 128 bytes nvr/default/tandy1000sl2.bin | Bin 0 -> 128 bytes nvr/default/win486.nvr | Bin 0 -> 128 bytes src/config.c | 1 + src/config.h | 1 + src/nvr.c | 25 +++++++++++++++++++++++-- src/vid_ati_eeprom.c | 5 +++-- src/wx-config_sel.c | 3 +++ 47 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 nvr/default/430vx.nvr create mode 100644 nvr/default/acer386.nvr create mode 100644 nvr/default/adgold.bin create mode 100644 nvr/default/aha1542c.nvr create mode 100644 nvr/default/ami286.nvr create mode 100644 nvr/default/ami386.nvr create mode 100644 nvr/default/ami386dx_opti495.nvr create mode 100644 nvr/default/ami486.nvr create mode 100644 nvr/default/at.nvr create mode 100644 nvr/default/award286.nvr create mode 100644 nvr/default/cmdpc30.nvr create mode 100644 nvr/default/dell200.nvr create mode 100644 nvr/default/deskpro386.nvr create mode 100644 nvr/default/endeavor.nvr create mode 100644 nvr/default/europc.nvr create mode 100644 nvr/default/gw286ct.nvr create mode 100644 nvr/default/hot-433.nvr create mode 100644 nvr/default/ibmps1_2011.nvr create mode 100644 nvr/default/ibmps1_2121.nvr create mode 100644 nvr/default/ibmps2_m50.nvr create mode 100644 nvr/default/ibmps2_m55sx.nvr create mode 100644 nvr/default/ibmps2_m60.nvr create mode 100644 nvr/default/ibmps2_m65sx.nvr create mode 100644 nvr/default/ibmps2_m70.nvr create mode 100644 nvr/default/ibmps2_m70_sec.nvr create mode 100644 nvr/default/ibmps2_m80.nvr create mode 100644 nvr/default/ibmps2_m80_sec.nvr create mode 100644 nvr/default/kmxc02.nvr create mode 100644 nvr/default/megapc.nvr create mode 100644 nvr/default/mr386dx_opti495.nvr create mode 100644 nvr/default/pc1512.nvr create mode 100644 nvr/default/pc1640.nvr create mode 100644 nvr/default/pc200.nvr create mode 100644 nvr/default/pc2086.nvr create mode 100644 nvr/default/pc3086.nvr create mode 100644 nvr/default/revenge.nvr create mode 100644 nvr/default/sis496.nvr create mode 100644 nvr/default/spc4200p.nvr create mode 100644 nvr/default/spc4216p.nvr create mode 100644 nvr/default/tandy1000hx.bin create mode 100644 nvr/default/tandy1000sl2.bin create mode 100644 nvr/default/win486.nvr diff --git a/nvr/default/430vx.nvr b/nvr/default/430vx.nvr new file mode 100644 index 0000000000000000000000000000000000000000..17ac54ec2b4a5170ccc4232c312d20c107d52345 GIT binary patch literal 128 zcmWIgulir)KRbtjxEfQze+GttCm)#k8<-gW=<65!2l7FHnc=^^!2kdM?CrU|8U83V z{D%Pk4YOZJp3>a=qrRi#fByG>Aklw+8GwrA1DAu9`~>O*0>}UV^?}BKm<%8W7=U;x GdH(@hqe12X literal 0 HcmV?d00001 diff --git a/nvr/default/acer386.nvr b/nvr/default/acer386.nvr new file mode 100644 index 0000000000000000000000000000000000000000..22bff6c1d5f70870d8937eb2ddc3d0166aa25dc0 GIT binary patch literal 128 zcmWGyP+<^dV2}_HRbvYHFTmi!@PWaxfr)|VKLZfhGccqGfEZA~yp@4Pf#DSc12atI HKZO7QJDf+3 literal 0 HcmV?d00001 diff --git a/nvr/default/adgold.bin b/nvr/default/adgold.bin new file mode 100644 index 0000000000000000000000000000000000000000..566bffc4abf2b00a1ce550dd0cef57386acaf960 GIT binary patch literal 24 bcmZQzU|{(FpN;JtBM<=DKp<>T$iM&qH%kMN literal 0 HcmV?d00001 diff --git a/nvr/default/aha1542c.nvr b/nvr/default/aha1542c.nvr new file mode 100644 index 0000000000000000000000000000000000000000..f62cc4bdef8aada151abd16edab1a7f24689a685 GIT binary patch literal 32 RcmZQC+{S*JApl2K B1|R?c literal 0 HcmV?d00001 diff --git a/nvr/default/ami386dx_opti495.nvr b/nvr/default/ami386dx_opti495.nvr new file mode 100644 index 0000000000000000000000000000000000000000..b6de20e01d144b622e8c6a2fb42496a8176f8ac0 GIT binary patch literal 128 zcma!GU|~>VVA5a{S7QqJ&%ofY`-1^*0~3RcKEnzo0R{#R1_pZu7|3QxWRQ_O$-vLh b01;y4hDqU~nH-)lT>U7}&;Zo(9}55gwY?z- literal 0 HcmV?d00001 diff --git a/nvr/default/ami486.nvr b/nvr/default/ami486.nvr new file mode 100644 index 0000000000000000000000000000000000000000..7055279865cf2ad0e11ef6bfb457ae57b6d1cfe9 GIT binary patch literal 128 zcmXqDFlSI;U}feIQe$vvVBieh{eO>t0~14yzW#q^f&c$G{xjSEXLf)v_I|Gws15liU`2ZUuBarc*LI3~= CVMLDr literal 0 HcmV?d00001 diff --git a/nvr/default/cmdpc30.nvr b/nvr/default/cmdpc30.nvr new file mode 100644 index 0000000000000000000000000000000000000000..3e6551836d0acdee935ee5d1a4db0a967e6d2aca GIT binary patch literal 128 zcmXr{ul`@)KPxkbP#c58e*p#;1_lPl1||j`APoYN5DH2%>M-#9-~S&08WBwLSODpi BQ@H>D literal 0 HcmV?d00001 diff --git a/nvr/default/dell200.nvr b/nvr/default/dell200.nvr new file mode 100644 index 0000000000000000000000000000000000000000..b16f18490881a1fcf6115c6dfe6d788aa8d1237a GIT binary patch literal 128 xcmZ=|;9wAEU=tS-WMgt@Fko=`&+y-|fr)|VKQf|UI!r6vt5pVP#$h138BO4gc|he~b$h7#Nt~N&ufnL literal 0 HcmV?d00001 diff --git a/nvr/default/ibmps1_2011.nvr b/nvr/default/ibmps1_2011.nvr new file mode 100644 index 0000000000000000000000000000000000000000..2029c7bf3088e975f104d454b17c43532bd871d7 GIT binary patch literal 128 zcmXq>$uv`JCW9iIs2W2+0|SE#0|O&N0}}%a13F*Pq_e+GuMdIn~O2BrpH1_)q;(hLo}K&hrF49(vz0ND!vsRRHm CR8%nl literal 0 HcmV?d00001 diff --git a/nvr/default/ibmps2_m50.nvr b/nvr/default/ibmps2_m50.nvr new file mode 100644 index 0000000000000000000000000000000000000000..9d63cdc75566cb636e444939529ae1cd7491de40 GIT binary patch literal 128 zcmY%R&-P#8Kbr=NI2%*Je+C8z1_lPk2Brp9=D`1V{{w;IhmWU1#esq#2_T;Tm{XvE NRT9Vo1CSC*002GsQL6v| literal 0 HcmV?d00001 diff --git a/nvr/default/ibmps2_m55sx.nvr b/nvr/default/ibmps2_m55sx.nvr new file mode 100644 index 0000000000000000000000000000000000000000..e83ab4fdcb7a65d6fcc2c0c867a8fbe30e72241e GIT binary patch literal 128 zcmWGzU}cbCU=n2&S7QqJFTmiyz`(%Rz{J4v|L%V<2o(nkfCQm<|AETD0GBdi#Q`N7Vw3;? literal 0 HcmV?d00001 diff --git a/nvr/default/ibmps2_m65sx.nvr b/nvr/default/ibmps2_m65sx.nvr new file mode 100644 index 0000000000000000000000000000000000000000..7bee33c481643131a166fc9d4164e399084c0d58 GIT binary patch literal 128 xcmZQ%2x1UpU=?E*S7QqJ&&1@wz@Wg`z{DW?9|xG9ct(IhR+0egUbXMcqM_#zyOCTqJ;r7BVYvp literal 0 HcmV?d00001 diff --git a/nvr/default/ibmps2_m80_sec.nvr b/nvr/default/ibmps2_m80_sec.nvr new file mode 100644 index 0000000000000000000000000000000000000000..e7e171ec012191ffb8663c4b2f158b40fbe96165 GIT binary patch literal 8192 zcmeIyF$%&!5CzcLU4tQ@q_fb%!Xs#(N-S*z+msf9H_#%5ttapnRu+2^?~pQ8#z`Ql zmZZ@H@ehP7^Ov3Q0-J0HinOAJ;+Nh{8ghx4squ(k+`^x!+aXAUwxh(y9v>0;Y<%0c z*_m&g-G6OHbe38QYxSg*=XC1LBU5+z7J>1?zbYF>#M1o)ncv7>}gVyNt*MeO3JruEP4=t00bZa0SG_<0uX=z b1Rwwb2tWV=5P$##AOHafKmY;|_=>FxUez1PEScInTf#`H|s2 X149GT|NjgP4F3rMA)q?k;0q%FUiD5M literal 0 HcmV?d00001 diff --git a/nvr/default/mr386dx_opti495.nvr b/nvr/default/mr386dx_opti495.nvr new file mode 100644 index 0000000000000000000000000000000000000000..9146987cb0319cca87dedd333b0d99c078f375fd GIT binary patch literal 128 zcmWGJ5PU%K0IRy7m>N^Te`W@Uo(~+X4NMF&`V18k3;zGNxBm|W3m61|^a2Ln(+o0_ i$;=;^KQu7@|F6Ix=*Ym#;MAb-fB^`s`~yL1Ndo}auT6CT literal 0 HcmV?d00001 diff --git a/nvr/default/pc1512.nvr b/nvr/default/pc1512.nvr new file mode 100644 index 0000000000000000000000000000000000000000..b1f758b3eb1e48c42a9253b22710a853d1f9c5b0 GIT binary patch literal 128 rcmXqIP-0MKU=tS-WMg1xP*Mi5Qh8I1KdUmkxEfQze+CAJ$pQ>~4NMF+3=RMPGjLlnpa7Oa1{;O{9~gjAM1rY|o0!~mt#!Ue9ClLGq literal 0 HcmV?d00001 diff --git a/nvr/default/sis496.nvr b/nvr/default/sis496.nvr new file mode 100644 index 0000000000000000000000000000000000000000..6d35a3cc52db23637d2a0bbf003f9fbed95287bc GIT binary patch literal 128 zcmdP+ulir|KQoJfxEfQze+CAJEey>34NMF*3=F^i1Nl(EBJltJe`b3Qe})=`1|Smz z*#AvE5&1uM$-n*vh5v6}wg344|KDE;`B{5D?fL)zYdu)aKQM`85X?XZpoEh6|Nj6* CBR%W@ literal 0 HcmV?d00001 diff --git a/nvr/default/spc4200p.nvr b/nvr/default/spc4200p.nvr new file mode 100644 index 0000000000000000000000000000000000000000..e1602c29df31d4c7b01d1ec9f9d7c6960721f8e0 GIT binary patch literal 128 zcmb1O5MdBwU=?E*S7QqJ&%ogD|G|I91||j|_zwYK8p;v5z`&sJ|NZ~}aKYywMfp&r L|9QP&EMjQ@oe^Li literal 0 HcmV?d00001 diff --git a/nvr/default/spc4216p.nvr b/nvr/default/spc4216p.nvr new file mode 100644 index 0000000000000000000000000000000000000000..f1ab56d90ec9510a3bed485de97d6c117881911c GIT binary patch literal 128 zcmY#q2x3rRU=|b*S7QqJ&%ogH|G|I91||j;28RC-0H&cFk!uVr3jg2#{|^^@4pO8K NRr;To3&tXr1^}~mUtype = type; strcpy(eeprom->fn, fn); - f = romfopen(eeprom->fn, "rb"); + f = nvrfopen(eeprom->fn, "rb"); if (!f) { memset(eeprom->data, 0, eeprom->type ? 512 : 128); @@ -45,7 +46,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, "wb"); if (!f) return; fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); fclose(f); diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index 962c194..e4253a3 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -98,6 +98,9 @@ static int run(void* hdlg) pclog("Config name %s\n", cfg); strcpy(config_file_default, cfg); + strcpy(config_name, s); + if (config_name[strlen(config_name)-1] == '.') + config_name[strlen(config_name)-1] = 0; wx_enddialog(hdlg, 1); // pause = 0; From a3ae6a6eed43396954d75e5f57f935b5cc301880 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Oct 2017 22:09:26 +0100 Subject: [PATCH 0165/1050] Added IBM XT Model 286 emulation. --- nvr/default/ibmxt286.nvr | Bin 0 -> 128 bytes src/cpu.c | 7 +++++++ src/cpu.h | 1 + src/ibm.h | 1 + src/mem.c | 13 +++++++++++++ src/model.c | 1 + src/nvr.c | 2 ++ 7 files changed, 25 insertions(+) create mode 100644 nvr/default/ibmxt286.nvr diff --git a/nvr/default/ibmxt286.nvr b/nvr/default/ibmxt286.nvr new file mode 100644 index 0000000000000000000000000000000000000000..b5c94c19fcbdcd8ddd8d02746d84db620f07fc06 GIT binary patch literal 128 ucmd;JFkld6U=tUbsOH4bV8Ecnz`)?xzyu_*f~O2Tk_|u^9;~ut2m%1y&IF+V literal 0 HcmV?d00001 diff --git a/src/cpu.c b/src/cpu.c index 4f1b6ec..79e6ab6 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -197,6 +197,13 @@ CPU cpus_ibmat[] = {"", -1, 0, 0, 0, 0} }; +CPU cpus_ibmxt286[] = +{ + /*286*/ + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2}, + {"", -1, 0, 0, 0, 0} +}; + CPU cpus_ps1_m2011[] = { /*286*/ diff --git a/src/cpu.h b/src/cpu.h index 2a94816..2b26555 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -92,6 +92,7 @@ extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; extern CPU cpus_pc1512[]; extern CPU cpus_ibmat[]; +extern CPU cpus_ibmxt286[]; extern CPU cpus_ps1_m2011[]; extern CPU cpus_ps2_m30_286[]; extern CPU cpus_acer[]; diff --git a/src/ibm.h b/src/ibm.h index 4a4f28d..250feab 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -432,6 +432,7 @@ enum ROM_IBMPS2_M55SX, ROM_IBMPS2_M80, ROM_ATARIPC3, + ROM_IBMXT286, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index 65154a6..8b80783 100644 --- a/src/mem.c +++ b/src/mem.c @@ -715,6 +715,19 @@ int loadbios() fread(rom+0x8000,32768,1,f); fclose(f); return 1; + + case ROM_IBMXT286: + f = romfopen("ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN", "rb"); + ff =romfopen("ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.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; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 1613279..5105083 100644 --- a/src/model.c +++ b/src/model.c @@ -127,6 +127,7 @@ MODEL models[] = {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512,2048, 128, at_scat_init, NULL}, {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 35a2a83..88b88b5 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -244,6 +244,7 @@ void loadnvr() case ROM_PC2086: f = nvrfopen("pc2086.nvr", "rb"); break; case ROM_PC3086: f = nvrfopen("pc3086.nvr", "rb"); break; case ROM_IBMAT: f = nvrfopen("at.nvr", "rb"); break; + case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "rb"); break; case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break; case ROM_IBMPS1_2121: f = nvrfopen("ibmps1_2121.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS2_M30_286: f = nvrfopen("ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */break; @@ -311,6 +312,7 @@ void savenvr() case ROM_PC2086: f = nvrfopen("pc2086.nvr", "wb"); break; case ROM_PC3086: f = nvrfopen("pc3086.nvr", "wb"); break; case ROM_IBMAT: f = nvrfopen("at.nvr", "wb"); break; + case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "wb"); break; case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "wb"); break; case ROM_IBMPS1_2121: f = nvrfopen("ibmps1_2121.nvr", "wb"); break; case ROM_IBMPS2_M30_286: f = nvrfopen("ibmps2_m30_286.nvr", "wb"); break; From 56b9c337808b345faaf98d97d3d38ddf7774cce0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Oct 2017 18:31:43 +0100 Subject: [PATCH 0166/1050] Add PS/1 XTIDE variant to HDD controller list. --- src/device.h | 3 ++- src/hdd.c | 1 + src/mem.c | 14 -------------- src/wx-config.c | 6 ++++++ src/xtide.c | 28 ++++++++++++++++++++++++++++ src/xtide.h | 1 + 6 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/device.h b/src/device.h index 3127362..67bdda1 100644 --- a/src/device.h +++ b/src/device.h @@ -52,7 +52,8 @@ 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_MCA = 0x20, /*Device requires an MCA system*/ - DEVICE_PCI = 0x40 /*Device requires a PCI system*/ + DEVICE_PCI = 0x40, /*Device requires a PCI system*/ + DEVICE_PS1 = 0x80 /*Device is only for IBM PS/1 Model 2011*/ }; int model_get_config_int(char *s); diff --git a/src/hdd.c b/src/hdd.c index 0f166f5..b4f2dff 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -35,6 +35,7 @@ static struct {"[IDE] Standard IDE", "ide", &ide_device, 0, 1}, {"[IDE] XTIDE", "xtide", &xtide_device, 0, 1}, {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0, 1}, + {"[IDE] XTIDE (PS/1)", "xtide_ps1", &xtide_ps1_device, 0, 1}, {"[SCSI] Adaptec AHA-1542C", "aha1542c", &scsi_aha1542c_device, 0, 0}, {"[SCSI] BusLogic BT-545S", "bt545s", &scsi_bt545s_device, 0, 0}, {"[SCSI] Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device, 0, 0}, diff --git a/src/mem.c b/src/mem.c index 8b80783..841f018 100644 --- a/src/mem.c +++ b/src/mem.c @@ -57,19 +57,6 @@ int cachesize=256; uint8_t *ram, *rom = NULL; uint8_t romext[32768]; -static void mem_load_atide115_bios() -{ - FILE *f; - f=romfopen("ide_at_1_1_5.bin","rb"); - -// is486=0; - if (f) - { - fread(romext,16384,1,f); - fclose(f); - } -} - static int mem_load_basic(char *path) { char s[256]; @@ -564,7 +551,6 @@ int loadbios() fclose(f); //#endif biosmask = 0x1ffff; - mem_load_atide115_bios(); return 1; case ROM_IBMPS1_2121: diff --git a/src/wx-config.c b/src/wx-config.c index 368b9fd..942c02c 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -188,6 +188,12 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for c++; continue; } + if ((((hdd_controller_get_flags(c) & DEVICE_PS1) && models[model].id != ROM_IBMPS1_2011) || + (!(hdd_controller_get_flags(c) & DEVICE_PS1) && models[model].id == ROM_IBMPS1_2011)) && c) + { + c++; + continue; + } if (!hdd_controller_available(c)) { c++; diff --git a/src/xtide.c b/src/xtide.c index 5c16b8f..22058f5 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -90,6 +90,17 @@ static void *xtide_at_init() return xtide; } +static void *xtide_ps1_init() +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, "ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + device_add(&ide_device); + + return xtide; +} + static void xtide_close(void *p) { xtide_t *xtide = (xtide_t *)p; @@ -107,6 +118,11 @@ static int xtide_at_available() return rom_present("ide_at.bin"); } +static int xtide_ps1_available() +{ + return rom_present("ide_at_1_1_5.bin"); +} + device_t xtide_device = { "XTIDE", @@ -131,3 +147,15 @@ device_t xtide_at_device = NULL, NULL }; +device_t xtide_ps1_device = +{ + "XTIDE (PS/1)", + DEVICE_PS1, + xtide_ps1_init, + xtide_close, + xtide_ps1_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/xtide.h b/src/xtide.h index 739c987..798c03c 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_ps1_device; From 132a2eb1101afc0314a1db8ead6ec6c6f7998c3b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Oct 2017 22:42:59 +0100 Subject: [PATCH 0167/1050] Add NMI support to dynamic recompiler. --- src/386_dynarec.c | 22 +++++++++++++++++++++- src/386_dynarec_ops.c | 1 + src/x86_ops_io.h | 24 ++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index c250d9c..b2a74f3 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -10,6 +10,7 @@ #include "codegen.h" #include "cpu.h" #include "fdc.h" +#include "nmi.h" #include "pic.h" #include "timer.h" @@ -560,7 +561,9 @@ void exec386_dynarec(int cycs) CPU_BLOCK_END(); if (trap) CPU_BLOCK_END(); - + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + ins++; insc++; @@ -719,6 +722,8 @@ inrecomp=0; if (trap) CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); if (cpu_state.abrt) { @@ -795,6 +800,8 @@ inrecomp=0; if (trap) CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); if (cpu_state.abrt) { @@ -869,6 +876,19 @@ inrecomp=0; loadcs(readmemw(0,addr+2)); } } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; + oldcs = CS; +// 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(); diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index bef86c8..5be12c1 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -6,6 +6,7 @@ #include "x87.h" #include "x86_flags.h" #include "mem.h" +#include "nmi.h" #include "pic.h" #include "codegen.h" diff --git a/src/x86_ops_io.h b/src/x86_ops_io.h index 292bcb5..d427a7f 100644 --- a/src/x86_ops_io.h +++ b/src/x86_ops_io.h @@ -5,6 +5,8 @@ static int opIN_AL_imm(uint32_t fetchdat) AL = inb(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opIN_AX_imm(uint32_t fetchdat) @@ -15,6 +17,8 @@ static int opIN_AX_imm(uint32_t fetchdat) AX = inw(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opIN_EAX_imm(uint32_t fetchdat) @@ -27,6 +31,8 @@ static int opIN_EAX_imm(uint32_t fetchdat) EAX = inl(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } @@ -39,6 +45,8 @@ static int opOUT_AL_imm(uint32_t fetchdat) PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); if (port == 0x64) return x86_was_reset; + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opOUT_AX_imm(uint32_t fetchdat) @@ -49,6 +57,8 @@ static int opOUT_AX_imm(uint32_t fetchdat) outw(port, AX); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opOUT_EAX_imm(uint32_t fetchdat) @@ -61,6 +71,8 @@ static int opOUT_EAX_imm(uint32_t fetchdat) outl(port, EAX); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } @@ -70,6 +82,8 @@ static int opIN_AL_DX(uint32_t fetchdat) AL = inb(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opIN_AX_DX(uint32_t fetchdat) @@ -79,6 +93,8 @@ static int opIN_AX_DX(uint32_t fetchdat) AX = inw(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opIN_EAX_DX(uint32_t fetchdat) @@ -90,6 +106,8 @@ static int opIN_EAX_DX(uint32_t fetchdat) EAX = inl(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } @@ -99,6 +117,8 @@ static int opOUT_AL_DX(uint32_t fetchdat) outb(DX, AL); CLOCK_CYCLES(11); PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return x86_was_reset; } static int opOUT_AX_DX(uint32_t fetchdat) @@ -109,6 +129,8 @@ static int opOUT_AX_DX(uint32_t fetchdat) outw(DX, AX); CLOCK_CYCLES(11); PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } static int opOUT_EAX_DX(uint32_t fetchdat) @@ -119,5 +141,7 @@ static int opOUT_EAX_DX(uint32_t fetchdat) check_io_perm(DX + 3); outl(DX, EAX); PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; return 0; } From 2611d27e91b03b31b4e5b8b5a9ea7446a3e5681b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Oct 2017 22:43:14 +0100 Subject: [PATCH 0168/1050] Disable LPT if port is set to 0. --- src/lpt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lpt.c b/src/lpt.c index d3264b2..0f7cf42 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -130,7 +130,8 @@ void lpt_init() void lpt1_init(uint16_t port) { - io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + if (port) + io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); } void lpt1_remove() { @@ -140,7 +141,8 @@ void lpt1_remove() } void lpt2_init(uint16_t port) { - io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + if (port) + io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); } void lpt2_remove() { From af2f3180e802d9c1633af2b50043a41a26205af2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Oct 2017 22:51:52 +0100 Subject: [PATCH 0169/1050] Added Ensoniq AudioPCI / Sound Blaster PCI 128 emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32 | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/sound.c | 33 +- src/sound_audiopci.c | 1081 ++++++++++++++++++++++++++++ src/sound_audiopci.h | 1 + 14 files changed, 1111 insertions(+), 26 deletions(-) create mode 100644 src/sound_audiopci.c create mode 100644 src/sound_audiopci.h diff --git a/src/Makefile.am b/src/Makefile.am index 5857a44..dfb8fab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,7 @@ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ -serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \ +serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index 69b2416..ee86b5a 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -12,7 +12,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 184f352..90b2f6e 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -11,7 +11,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 15cd4fe..3750ae1 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -11,7 +11,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index c0c9101..1951791 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -11,7 +11,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 4e3036f..baae45f 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 ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 7cddda5..7e135a6 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 8f89956..9f331f0 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index fa11f96..5f5383a 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.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 4627e7d..1f4678e 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 ali1429.o amstrad i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index ca0f59b..1c3edbd 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -10,7 +10,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/sound.c b/src/sound.c index d8a351b..96ad7b1 100644 --- a/src/sound.c +++ b/src/sound.c @@ -14,6 +14,7 @@ #include "sound.h" #include "sound_adlib.h" #include "sound_adlibgold.h" +#include "sound_audiopci.h" #include "sound_pas16.h" #include "sound_sb.h" #include "sound_sb_dsp.h" @@ -34,21 +35,23 @@ typedef struct static SOUND_CARD sound_cards[] = { - {"None", "none", NULL}, - {"Adlib", "adlib", &adlib_device}, - {"Adlib", "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}, - {"Pro Audio Spectrum 16", "pas16", &pas16_device}, + {"None", "none", NULL}, + {"Adlib", "adlib", &adlib_device}, + {"Adlib", "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}, + {"Pro Audio Spectrum 16", "pas16", &pas16_device}, + {"Ensoniq AudioPCI (ES1371)", "es1371", &es1371_device}, + {"Sound Blaster PCI 128", "sbpci128", &es1371_device}, {"", "", NULL} }; diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c new file mode 100644 index 0000000..4fd9f76 --- /dev/null +++ b/src/sound_audiopci.c @@ -0,0 +1,1081 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "pci.h" +#include "sound.h" + +typedef struct es1371_t +{ + uint8_t pci_command, pci_serr; + + uint32_t base_addr; + + uint8_t int_line; + + uint16_t pmcsr; + + uint32_t int_ctrl; + uint32_t int_status; + + uint32_t legacy_ctrl; + + int mem_page; + + uint32_t si_cr; + + uint32_t sr_cir; + uint16_t sr_ram[128]; + + uint8_t uart_ctrl; + uint8_t uart_status; + + uint16_t codec_regs[64]; + uint32_t codec_ctrl; + + struct + { + uint32_t addr, addr_latch; + uint16_t count, size; + + uint16_t samp_ct, curr_samp_ct; + + int time, latch; + + uint32_t vf, ac; + + int16_t buffer_l[64], buffer_r[64]; + int buffer_pos, buffer_pos_end; + + int16_t out_l, out_r; + + int32_t vol_l, vol_r; + } dac[2]; + + int dac_latch, dac_time; + + int master_vol_l, master_vol_r; + + int card; + + int pos; + int16_t buffer[MAXSOUNDBUFLEN * 2]; +} es1371_t; + +#define LEGACY_SB_ADDR (1 << 29) +#define LEGACY_SSCAPE_ADDR_SHIFT 27 +#define LEGACY_CODEC_ADDR_SHIFT 25 +#define LEGACY_FORCE_IRQ (1 << 24) +#define LEGACY_CAPTURE_SLAVE_DMA (1 << 23) +#define LEGACY_CAPTURE_SLAVE_PIC (1 << 22) +#define LEGACY_CAPTURE_MASTER_DMA (1 << 21) +#define LEGACY_CAPTURE_MASTER_PIC (1 << 20) +#define LEGACY_CAPTURE_ADLIB (1 << 19) +#define LEGACY_CAPTURE_SB (1 << 18) +#define LEGACY_CAPTURE_CODEC (1 << 17) +#define LEGACY_CAPTURE_SSCAPE (1 << 16) +#define LEGACY_EVENT_SSCAPE (0 << 8) +#define LEGACY_EVENT_CODEC (1 << 8) +#define LEGACY_EVENT_SB (2 << 8) +#define LEGACY_EVENT_ADLIB (3 << 8) +#define LEGACY_EVENT_MASTER_PIC (4 << 8) +#define LEGACY_EVENT_MASTER_DMA (5 << 8) +#define LEGACY_EVENT_SLAVE_PIC (6 << 8) +#define LEGACY_EVENT_SLAVE_DMA (7 << 8) +#define LEGACY_EVENT_MASK (7 << 8) +#define LEGACY_EVENT_ADDR_SHIFT 3 +#define LEGACY_EVENT_ADDR_MASK (0x1f << 3) +#define LEGACY_EVENT_TYPE_RW (1 << 2) +#define LEGACY_INT (1 << 0) + +#define SRC_RAM_WE (1 << 24) + +#define CODEC_READ (1 << 23) +#define CODEC_READY (1 << 31) + +#define INT_DAC1_EN (1 << 6) +#define INT_DAC2_EN (1 << 5) + +#define SI_P2_INTR_EN (1 << 9) +#define SI_P1_INTR_EN (1 << 8) + +#define INT_STATUS_INTR (1 << 31) +#define INT_STATUS_DAC1 (1 << 2) +#define INT_STATUS_DAC2 (1 << 1) + +#define FORMAT_MONO_8 0 +#define FORMAT_STEREO_8 1 +#define FORMAT_MONO_16 2 +#define FORMAT_STEREO_16 3 + +const int32_t codec_attn[]= +{ + 25,32,41,51,65,82,103,130,164,206,260,327,412,519,653, + 822,1036,1304,1641,2067,2602,3276,4125,5192,6537,8230,10362,13044, + 16422,20674,26027,32767 +}; + +static void es1371_fetch(es1371_t *es1371, int dac_nr); +static void update_legacy(es1371_t *es1371); + +static void es1371_update_irqs(es1371_t *es1371) +{ + int irq = 0; + + if ((es1371->int_status & INT_STATUS_DAC1) && (es1371->si_cr & SI_P1_INTR_EN)) + irq = 1; + if ((es1371->int_status & INT_STATUS_DAC2) && (es1371->si_cr & SI_P2_INTR_EN)) + irq = 1; + + if (irq) + es1371->int_status |= INT_STATUS_INTR; + else + es1371->int_status &= ~INT_STATUS_INTR; + + if (es1371->legacy_ctrl & LEGACY_FORCE_IRQ) + irq = 1; + + if (irq) + { + pci_set_irq(es1371->card, PCI_INTA); +// pclog("Raise IRQ\n"); + } + else + { + pci_clear_irq(es1371->card, PCI_INTA); +// pclog("Drop IRQ\n"); + } +} + +static uint8_t es1371_inb(uint16_t port, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + uint8_t ret = 0; + + switch (port & 0x3f) + { + case 0x00: + ret = es1371->int_ctrl & 0xff; + break; + case 0x01: + ret = (es1371->int_ctrl >> 8) & 0xff; + break; + case 0x02: + ret = (es1371->int_ctrl >> 16) & 0xff; + break; + case 0x03: + ret = (es1371->int_ctrl >> 24) & 0xff; + break; + + case 0x04: + ret = es1371->int_status & 0xff; + break; + case 0x05: + ret = (es1371->int_status >> 8) & 0xff; + break; + case 0x06: + ret = (es1371->int_status >> 16) & 0xff; + break; + case 0x07: + ret = (es1371->int_status >> 24) & 0xff; + break; + + + case 0x09: + ret = es1371->uart_status; + break; + + case 0x1a: + ret = es1371->legacy_ctrl >> 16; + break; + case 0x1b: + ret = es1371->legacy_ctrl >> 24; + break; + + case 0x20: + ret = es1371->si_cr & 0xff; + break; + case 0x21: + ret = es1371->si_cr >> 8; + break; + case 0x22: + ret = (es1371->si_cr >> 16) | 0x80; + break; + case 0x23: + ret = 0xff; + break; + + default: + pclog("Bad es1371_inb: port=%04x\n", port); + } + +// pclog("es1371_inb: port=%04x ret=%02x\n", port, ret); +// output = 3; + return ret; +} +static uint16_t es1371_inw(uint16_t port, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + uint16_t ret = 0; + + switch (port & 0x3e) + { + case 0x00: + ret = es1371->int_ctrl & 0xffff; + break; + case 0x02: + ret = (es1371->int_ctrl >> 16) & 0xffff; + break; + + case 0x18: + ret = es1371->legacy_ctrl & 0xffff; +// pclog("Read legacy ctrl %04x\n", ret); + break; + + case 0x26: + ret = es1371->dac[0].curr_samp_ct; + break; + + case 0x2a: + ret = es1371->dac[1].curr_samp_ct; + break; + + case 0x36: + switch (es1371->mem_page) + { + case 0xc: + ret = es1371->dac[0].count; + break; + + default: + pclog("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); + } + break; + + case 0x3e: + switch (es1371->mem_page) + { + case 0xc: + ret = es1371->dac[1].count; + break; + + default: + pclog("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); + } + break; + + default: + pclog("Bad es1371_inw: port=%04x\n", port); + } + +// pclog("es1371_inw: port=%04x ret=%04x %04x:%08x\n", port, ret, CS,cpu_state.pc); + return ret; +} +static uint32_t es1371_inl(uint16_t port, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + uint32_t ret = 0; + + switch (port & 0x3c) + { + case 0x00: + ret = es1371->int_ctrl; + break; + case 0x04: + ret = es1371->int_status; + break; + + case 0x10: + ret = es1371->sr_cir & ~0xffff; + ret |= es1371->sr_ram[es1371->sr_cir >> 25]; + break; + + case 0x14: + ret = es1371->codec_ctrl & 0x00ff0000; + ret |= es1371->codec_regs[(es1371->codec_ctrl >> 16) & 0x3f]; + ret |= CODEC_READY; + break; + + default: + pclog("Bad es1371_inl: port=%04x\n", port); + } + +// pclog("es1371_inl: port=%04x ret=%08x %08x\n", port, ret, cpu_state.pc); + return ret; +} + +static void es1371_outb(uint16_t port, uint8_t val, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + +// pclog("es1371_outb: port=%04x val=%02x %04x:%08x\n", port, val, cs, cpu_state.pc); + switch (port & 0x3f) + { + case 0x00: + if (!(es1371->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) + { + es1371->dac[0].addr = es1371->dac[0].addr_latch; + es1371->dac[0].buffer_pos = 0; + es1371->dac[0].buffer_pos_end = 0; + es1371_fetch(es1371, 0); + } + if (!(es1371->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) + { + es1371->dac[1].addr = es1371->dac[1].addr_latch; + es1371->dac[1].buffer_pos = 0; + es1371->dac[1].buffer_pos_end = 0; + es1371_fetch(es1371, 1); + } + es1371->int_ctrl = (es1371->int_ctrl & 0xffffff00) | val; + break; + case 0x01: + es1371->int_ctrl = (es1371->int_ctrl & 0xffff00ff) | (val << 8); + break; + case 0x02: + es1371->int_ctrl = (es1371->int_ctrl & 0xff00ffff) | (val << 16); + break; + case 0x03: + es1371->int_ctrl = (es1371->int_ctrl & 0x00ffffff) | (val << 24); + break; + + case 0x09: + es1371->uart_ctrl = val; + break; + + case 0x0c: + es1371->mem_page = val & 0xf; + break; + + case 0x18: + es1371->legacy_ctrl |= LEGACY_INT; + nmi = 0; + break; + case 0x1a: + es1371->legacy_ctrl = (es1371->legacy_ctrl & 0xff00ffff) | (val << 16); + update_legacy(es1371); + break; + case 0x1b: + es1371->legacy_ctrl = (es1371->legacy_ctrl & 0x00ffffff) | (val << 24); + es1371_update_irqs(es1371); +// output = 3; + update_legacy(es1371); + break; + + case 0x20: + es1371->si_cr = (es1371->si_cr & 0xffff00) | val; + break; + case 0x21: + es1371->si_cr = (es1371->si_cr & 0xff00ff) | (val << 8); + if (!(es1371->si_cr & SI_P1_INTR_EN)) + es1371->int_status &= ~INT_STATUS_DAC1; + if (!(es1371->si_cr & SI_P2_INTR_EN)) + es1371->int_status &= ~INT_STATUS_DAC2; + es1371_update_irqs(es1371); + break; + case 0x22: + es1371->si_cr = (es1371->si_cr & 0x00ffff) | (val << 16); + break; + + default: + pclog("Bad es1371_outb: port=%04x val=%02x\n", port, val); + } +} +static void es1371_outw(uint16_t port, uint16_t val, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + +// pclog("es1371_outw: port=%04x val=%04x\n", port, val); + switch (port & 0x3f) + { + case 0x0c: + es1371->mem_page = val & 0xf; + break; + + case 0x24: + es1371->dac[0].samp_ct = val; + break; + + case 0x28: + es1371->dac[1].samp_ct = val; + break; + + default: + pclog("Bad es1371_outw: port=%04x val=%04x\n", port, val); + } +} +static void es1371_outl(uint16_t port, uint32_t val, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + +// pclog("es1371_outl: port=%04x val=%08x %04x:%08x\n", port, val, CS, cpu_state.pc); + switch (port & 0x3f) + { + case 0x04: + break; + + case 0x0c: + es1371->mem_page = val & 0xf; + break; + + case 0x10: + es1371->sr_cir = val; + if (es1371->sr_cir & SRC_RAM_WE) + { +// pclog("Write SR RAM %02x %04x\n", es1371->sr_cir >> 25, val & 0xffff); + es1371->sr_ram[es1371->sr_cir >> 25] = val & 0xffff; + switch (es1371->sr_cir >> 25) + { + case 0x71: + es1371->dac[0].vf = (es1371->dac[0].vf & ~0x1f8000) | ((val & 0xfc00) << 5); + es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + break; + case 0x72: + es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7fff) | (val & 0x7fff); + break; + case 0x73: + es1371->dac[0].vf = (es1371->dac[0].vf & ~0x7fff) | (val & 0x7fff); + break; + + case 0x75: + es1371->dac[1].vf = (es1371->dac[1].vf & ~0x1f8000) | ((val & 0xfc00) << 5); + es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + break; + case 0x76: + es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7fff) | (val & 0x7fff); + break; + case 0x77: + es1371->dac[1].vf = (es1371->dac[1].vf & ~0x7fff) | (val & 0x7fff); + break; + + case 0x7c: + es1371->dac[0].vol_l = (int32_t)(int16_t)(val & 0xffff); + break; + case 0x7d: + es1371->dac[0].vol_r = (int32_t)(int16_t)(val & 0xffff); + break; + case 0x7e: + es1371->dac[1].vol_l = (int32_t)(int16_t)(val & 0xffff); + break; + case 0x7f: + es1371->dac[1].vol_r = (int32_t)(int16_t)(val & 0xffff); + break; + } + } + break; + + case 0x14: + es1371->codec_ctrl = val; + if (!(val & CODEC_READ)) + { +// pclog("Write codec %02x %04x\n", (val >> 16) & 0x3f, val & 0xffff); + es1371->codec_regs[(val >> 16) & 0x3f] = val & 0xffff; + switch ((val >> 16) & 0x3f) + { + case 0x02: /*Master volume*/ + if (val & 0x8000) + es1371->master_vol_l = es1371->master_vol_r = 0; + else + { + if (val & 0x2000) + es1371->master_vol_l = codec_attn[0]; + else + es1371->master_vol_l = codec_attn[0x1f - ((val >> 8) & 0x1f)]; + if (val & 0x20) + es1371->master_vol_r = codec_attn[0]; + else + es1371->master_vol_r = codec_attn[0x1f - (val & 0x1f)]; + } + break; + case 0x12: /*CD volume*/ + if (val & 0x8000) + sound_set_cd_volume(0, 0); + else + sound_set_cd_volume(codec_attn[0x1f - ((val >> 8) & 0x1f)] * 2, codec_attn[0x1f - (val & 0x1f)] * 2); + break; + } + } + break; + + case 0x24: + es1371->dac[0].samp_ct = val & 0xffff; + break; + + case 0x28: + es1371->dac[1].samp_ct = val & 0xffff; + break; + + case 0x30: + switch (es1371->mem_page) + { + case 0x0: case 0x1: case 0x2: case 0x3: + case 0x4: case 0x5: case 0x6: case 0x7: + case 0x8: case 0x9: case 0xa: case 0xb: + break; + + case 0xc: + es1371->dac[0].addr_latch = val; +// pclog("DAC1 addr %08x\n", val); + break; + + default: + pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); + } + break; + case 0x34: + switch (es1371->mem_page) + { + case 0x0: case 0x1: case 0x2: case 0x3: + case 0x4: case 0x5: case 0x6: case 0x7: + case 0x8: case 0x9: case 0xa: case 0xb: + break; + + case 0xc: + es1371->dac[0].size = val & 0xffff; + es1371->dac[0].count = val >> 16; + if (es1371->dac[0].count) + es1371->dac[0].count -= 4; + break; + + default: + pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); + } + break; + case 0x38: + switch (es1371->mem_page) + { + case 0x0: case 0x1: case 0x2: case 0x3: + case 0x4: case 0x5: case 0x6: case 0x7: + case 0x8: case 0x9: case 0xa: case 0xb: + break; + + case 0xc: + es1371->dac[1].addr_latch = val; + break; + + case 0xd: + break; + + default: + pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); + } + break; + case 0x3c: + switch (es1371->mem_page) + { + case 0x0: case 0x1: case 0x2: case 0x3: + case 0x4: case 0x5: case 0x6: case 0x7: + case 0x8: case 0x9: case 0xa: case 0xb: + break; + + case 0xc: + es1371->dac[1].size = val & 0xffff; + es1371->dac[1].count = val >> 16; + break; + + case 0xd: + break; + + default: + pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); + } + break; + + default: + pclog("Bad es1371_outl: port=%04x val=%08x\n", port, val); + } +} + +static void capture_event(es1371_t *es1371, int type, int rw, uint16_t port) +{ + es1371->legacy_ctrl &= ~(LEGACY_EVENT_MASK | LEGACY_EVENT_ADDR_MASK); + es1371->legacy_ctrl |= type; + if (rw) + es1371->legacy_ctrl |= LEGACY_EVENT_TYPE_RW; + else + es1371->legacy_ctrl &= ~LEGACY_EVENT_TYPE_RW; + es1371->legacy_ctrl |= ((port << LEGACY_EVENT_ADDR_SHIFT) & LEGACY_EVENT_ADDR_MASK); + es1371->legacy_ctrl &= ~LEGACY_INT; + nmi = 1; +// pclog("Event! %s %04x\n", rw ? "write" : "read", port); +} + +static void capture_write_sscape(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_SSCAPE, 1, port); +} +static void capture_write_codec(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_CODEC, 1, port); +} +static void capture_write_sb(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_SB, 1, port); +} +static void capture_write_adlib(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_ADLIB, 1, port); +} +static void capture_write_master_pic(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_MASTER_PIC, 1, port); +} +static void capture_write_master_dma(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_MASTER_DMA, 1, port); +} +static void capture_write_slave_pic(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_SLAVE_PIC, 1, port); +} +static void capture_write_slave_dma(uint16_t port, uint8_t val, void *p) +{ + capture_event(p, LEGACY_EVENT_SLAVE_DMA, 1, port); +} + +static uint8_t capture_read_sscape(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_SSCAPE, 0, port); + return 0xff; +} +static uint8_t capture_read_codec(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_CODEC, 0, port); + return 0xff; +} +static uint8_t capture_read_sb(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_SB, 0, port); + return 0xff; +} +static uint8_t capture_read_adlib(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_ADLIB, 0, port); + return 0xff; +} +static uint8_t capture_read_master_pic(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_MASTER_PIC, 0, port); + return 0xff; +} +static uint8_t capture_read_master_dma(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_MASTER_DMA, 0, port); + return 0xff; +} +static uint8_t capture_read_slave_pic(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_SLAVE_PIC, 0, port); + return 0xff; +} +static uint8_t capture_read_slave_dma(uint16_t port, void *p) +{ + capture_event(p, LEGACY_EVENT_SLAVE_DMA, 0, port); + return 0xff; +} + +static void update_legacy(es1371_t *es1371) +{ + io_removehandler(0x0320, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); + io_removehandler(0x0330, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); + io_removehandler(0x0340, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); + io_removehandler(0x0350, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); + + io_removehandler(0x5300, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); + io_removehandler(0xe800, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); + io_removehandler(0xf400, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); + + io_removehandler(0x0220, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); + io_removehandler(0x0240, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); + + io_removehandler(0x0388, 0x0004, capture_read_adlib,NULL,NULL, capture_write_adlib,NULL,NULL, es1371); + + io_removehandler(0x0020, 0x0002, capture_read_master_pic,NULL,NULL, capture_write_master_pic,NULL,NULL, es1371); + io_removehandler(0x0000, 0x0010, capture_read_master_dma,NULL,NULL, capture_write_master_dma,NULL,NULL, es1371); + io_removehandler(0x00a0, 0x0002, capture_read_slave_pic,NULL,NULL, capture_write_slave_pic,NULL,NULL, es1371); + io_removehandler(0x00c0, 0x0020, capture_read_slave_dma,NULL,NULL, capture_write_slave_dma,NULL,NULL, es1371); + + if (es1371->legacy_ctrl & LEGACY_CAPTURE_SSCAPE) + { + switch ((es1371->legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) + { + case 0: io_sethandler(0x0320, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + case 1: io_sethandler(0x0330, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + case 2: io_sethandler(0x0340, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + case 3: io_sethandler(0x0350, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + } + } + if (es1371->legacy_ctrl & LEGACY_CAPTURE_CODEC) + { + switch ((es1371->legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) + { + case 0: io_sethandler(0x5300, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; + case 2: io_sethandler(0xe800, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; + case 3: io_sethandler(0xf400, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; + } + } + if (es1371->legacy_ctrl & LEGACY_CAPTURE_SB) + { + if (!(es1371->legacy_ctrl & LEGACY_SB_ADDR)) + io_sethandler(0x0220, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); + else + io_sethandler(0x0240, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); + } + if (es1371->legacy_ctrl & LEGACY_CAPTURE_ADLIB) + io_sethandler(0x0388, 0x0004, capture_read_adlib,NULL,NULL, capture_write_adlib,NULL,NULL, es1371); + if (es1371->legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) + io_sethandler(0x0020, 0x0002, capture_read_master_pic,NULL,NULL, capture_write_master_pic,NULL,NULL, es1371); + if (es1371->legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) + io_sethandler(0x0000, 0x0010, capture_read_master_dma,NULL,NULL, capture_write_master_dma,NULL,NULL, es1371); + if (es1371->legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) + io_sethandler(0x00a0, 0x0002, capture_read_slave_pic,NULL,NULL, capture_write_slave_pic,NULL,NULL, es1371); + if (es1371->legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) + io_sethandler(0x00c0, 0x0020, capture_read_slave_dma,NULL,NULL, capture_write_slave_dma,NULL,NULL, es1371); +} + + +static uint8_t es1371_pci_read(int func, int addr, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + if (func) + return 0; + + //pclog("ES1371 PCI read %08X PC=%08x\n", addr, cpu_state.pc); + + switch (addr) + { + case 0x00: return 0x74; /*Ensoniq*/ + case 0x01: return 0x12; + + case 0x02: return 0x71; /*ES1371*/ + case 0x03: return 0x13; + + case 0x04: return es1371->pci_command; + case 0x05: return es1371->pci_serr; + + case 0x06: return 0x10; /*Supports ACPI*/ + case 0x07: return 0; + + case 0x08: return 2; /*Revision ID*/ + case 0x09: return 0x00; /*Multimedia audio device*/ + case 0x0a: return 0x01; + case 0x0b: return 0x04; + + case 0x10: return 0x01 | (es1371->base_addr & 0xc0); /*memBaseAddr*/ + case 0x11: return es1371->base_addr >> 8; + case 0x12: return es1371->base_addr >> 16; + case 0x13: return es1371->base_addr >> 24; + + case 0x2c: return 0x74; /*Subsystem vendor ID*/ + case 0x2d: return 0x12; + case 0x2e: return 0x71; + case 0x2f: return 0x13; + + case 0x34: return 0xdc; /*Capabilites pointer*/ + + case 0x3c: return es1371->int_line; + case 0x3d: return 0x01; /*INTA*/ + + case 0x3e: return 0xc; /*Minimum grant*/ + case 0x3f: return 0x80; /*Maximum latency*/ + + case 0xdc: return 0x01; /*Capabilities identifier*/ + case 0xdd: return 0x00; /*Next item pointer*/ + case 0xde: return 0x31; /*Power management capabilities*/ + case 0xdf: return 0x6c; + + case 0xe0: return es1371->pmcsr & 0xff; + case 0xe1: return es1371->pmcsr >> 8; + } + return 0; +} + +static void es1371_pci_write(int func, int addr, uint8_t val, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + if (func) + return; + +// pclog("ES1371 PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); + + switch (addr) + { + case 0x04: + if (es1371->pci_command & PCI_COMMAND_IO) + io_removehandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); + es1371->pci_command = val & 0x05; + if (es1371->pci_command & PCI_COMMAND_IO) + io_sethandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); + break; + case 0x05: + es1371->pci_serr = val & 1; + break; + + case 0x10: + if (es1371->pci_command & PCI_COMMAND_IO) + io_removehandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); + es1371->base_addr = (es1371->base_addr & 0xffffff00) | (val & 0xc0); + if (es1371->pci_command & PCI_COMMAND_IO) + io_sethandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); + break; + case 0x11: + if (es1371->pci_command & PCI_COMMAND_IO) + io_removehandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); + es1371->base_addr = (es1371->base_addr & 0xffff00c0) | (val << 8); + if (es1371->pci_command & PCI_COMMAND_IO) + io_sethandler(es1371->base_addr, 0x0040, es1371_inb, es1371_inw, es1371_inl, es1371_outb, es1371_outw, es1371_outl, es1371); + break; + case 0x12: + es1371->base_addr = (es1371->base_addr & 0xff00ffc0) | (val << 16); + break; + case 0x13: + es1371->base_addr = (es1371->base_addr & 0x00ffffc0) | (val << 24); + break; + + case 0x3c: + es1371->int_line = val; + break; + + case 0xe0: + es1371->pmcsr = (es1371->pmcsr & 0xff00) | (val & 0x03); + break; + case 0xe1: + es1371->pmcsr = (es1371->pmcsr & 0x00ff) | ((val & 0x01) << 8); + break; + } +// pclog("es1371->base_addr %08x\n", es1371->base_addr); +} + +static void es1371_fetch(es1371_t *es1371, int dac_nr) +{ + int format = dac_nr ? ((es1371->si_cr >> 2) & 3) : (es1371->si_cr & 3); + int pos = es1371->dac[dac_nr].buffer_pos & 63; + int c; + +//pclog("Fetch format=%i %08x %08x %08x %08x %08x\n", format, es1371->dac[dac_nr].count, es1371->dac[dac_nr].size, es1371->dac[dac_nr].curr_samp_ct,es1371->dac[dac_nr].samp_ct, es1371->dac[dac_nr].addr); + switch (format) + { + case FORMAT_MONO_8: + for (c = 0; c < 32; c += 4) + { + es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr) ^ 0x80) << 8; + es1371->dac[dac_nr].buffer_l[(pos+c+1) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+1) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr+1) ^ 0x80) << 8; + es1371->dac[dac_nr].buffer_l[(pos+c+2) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+2) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr+2) ^ 0x80) << 8; + es1371->dac[dac_nr].buffer_l[(pos+c+3) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+3) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr+3) ^ 0x80) << 8; + es1371->dac[dac_nr].addr += 4; + + es1371->dac[dac_nr].buffer_pos_end += 4; + es1371->dac[dac_nr].count++; + if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) + { + es1371->dac[dac_nr].count = 0; + es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; + break; + } + } + break; + case FORMAT_STEREO_8: + for (c = 0; c < 16; c += 2) + { + es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr) ^ 0x80) << 8; + es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr + 1) ^ 0x80) << 8; + es1371->dac[dac_nr].buffer_l[(pos+c+1) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr + 2) ^ 0x80) << 8; + es1371->dac[dac_nr].buffer_r[(pos+c+1) & 63] = (mem_readb_phys(es1371->dac[dac_nr].addr + 3) ^ 0x80) << 8; + es1371->dac[dac_nr].addr += 4; + + es1371->dac[dac_nr].buffer_pos_end += 2; + es1371->dac[dac_nr].count++; + if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) + { + es1371->dac[dac_nr].count = 0; + es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; + break; + } + } + break; + case FORMAT_MONO_16: + for (c = 0; c < 16; c += 2) + { + es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr); + es1371->dac[dac_nr].buffer_l[(pos+c+1) & 63] = es1371->dac[dac_nr].buffer_r[(pos+c+1) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr + 2); + es1371->dac[dac_nr].addr += 4; + + es1371->dac[dac_nr].buffer_pos_end += 2; + es1371->dac[dac_nr].count++; + if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) + { + es1371->dac[dac_nr].count = 0; + es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; + break; + } + } + break; + case FORMAT_STEREO_16: + for (c = 0; c < 4; c++) + { + es1371->dac[dac_nr].buffer_l[(pos+c) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr); + es1371->dac[dac_nr].buffer_r[(pos+c) & 63] = mem_readw_phys(es1371->dac[dac_nr].addr + 2); +// pclog("Fetch %02x %08x %04x %04x\n", (pos+c) & 63, es1371->dac[dac_nr].addr, es1371->dac[dac_nr].buffer_l[(pos+c) & 63], es1371->dac[dac_nr].buffer_r[(pos+c) & 63]); + es1371->dac[dac_nr].addr += 4; + + es1371->dac[dac_nr].buffer_pos_end++; + es1371->dac[dac_nr].count++; + if (es1371->dac[dac_nr].count > es1371->dac[dac_nr].size) + { + es1371->dac[dac_nr].count = 0; + es1371->dac[dac_nr].addr = es1371->dac[dac_nr].addr_latch; + break; + } + } + break; + } +} + +static void es1371_next_sample(es1371_t *es1371, int dac_nr) +{ + if ((es1371->dac[dac_nr].buffer_pos - es1371->dac[dac_nr].buffer_pos_end) >= 0) + { + es1371_fetch(es1371, dac_nr); + } + + es1371->dac[dac_nr].out_l = es1371->dac[dac_nr].buffer_l[es1371->dac[dac_nr].buffer_pos & 63]; + es1371->dac[dac_nr].out_r = es1371->dac[dac_nr].buffer_r[es1371->dac[dac_nr].buffer_pos & 63]; +// pclog("Use %02x %04x %04x\n", es1371->dac[dac_nr].buffer_pos & 63, es1371->dac[dac_nr].out_l, es1371->dac[dac_nr].out_r); + + es1371->dac[dac_nr].buffer_pos++; +// pclog("Next sample %08x %08x %08x\n", es1371->dac[dac_nr].buffer_pos, es1371->dac[dac_nr].buffer_pos_end, es1371->dac[dac_nr].curr_samp_ct); +} + +//static FILE *es1371_f;//,*es1371_f2; +static void es1371_poll(void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + es1371->dac[1].time += es1371->dac[1].latch; + + if (es1371->int_ctrl & INT_DAC1_EN) + { +// pclog("1Samp %i %i %08x\n", es1371->dac[0].curr_samp_ct, es1371->dac[0].samp_ct, es1371->dac[0].ac); + es1371->dac[0].ac += es1371->dac[0].vf; + if (es1371->dac[0].ac & (~0 << (15+4))) + { + es1371->dac[0].ac &= ~(~0 << (15+4)); + es1371_next_sample(es1371, 0); + + es1371->dac[0].curr_samp_ct++; + if (es1371->dac[0].curr_samp_ct == es1371->dac[0].samp_ct) + { +// pclog("DAC1 IRQ\n"); + es1371->int_status |= INT_STATUS_DAC1; + es1371_update_irqs(es1371); + } + if (es1371->dac[0].curr_samp_ct > es1371->dac[0].samp_ct) + { + es1371->dac[0].curr_samp_ct = 0; + } + } + } + + if (es1371->int_ctrl & INT_DAC2_EN) + { +// pclog("2Samp %i %i %08x\n", es1371->dac[1].curr_samp_ct, es1371->dac[1].samp_ct, es1371->dac[1].ac); + es1371->dac[1].ac += es1371->dac[1].vf; + if (es1371->dac[1].ac & (~0 << (15+4))) + { + es1371->dac[1].ac &= ~(~0 << (15+4)); + es1371_next_sample(es1371, 1); + + es1371->dac[1].curr_samp_ct++; + if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) + { + es1371->dac[1].curr_samp_ct = 0; +// pclog("DAC2 IRQ\n"); + es1371->int_status |= INT_STATUS_DAC2; + es1371_update_irqs(es1371); + } + } + } + + for (; es1371->pos < sound_pos_global; es1371->pos++) + { + int32_t l, r; + + l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12; + l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12); + r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12; + r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12); + + l >>= 1; + r >>= 1; + + l = (l * es1371->master_vol_l) >> 15; + r = (r * es1371->master_vol_r) >> 15; + + if (l < -32768) + l = -32768; + else if (l > 32767) + l = 32767; + if (r < -32768) + r = -32768; + else if (r > 32767) + r = 32767; + + es1371->buffer[es1371->pos*2] = l; + es1371->buffer[es1371->pos*2 + 1] = r; + } +} + +static void es1371_get_buffer(int32_t *buffer, int len, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + int c; + + for (c = 0; c < len * 2; c++) + buffer[c] += (es1371->buffer[c] / 2); + + es1371->pos = 0; +} + +static void *es1371_init() +{ + es1371_t *es1371 = malloc(sizeof(es1371_t)); + memset(es1371, 0, sizeof(es1371_t)); + + sound_add_handler(es1371_get_buffer, es1371); + + es1371->card = pci_add(es1371_pci_read, es1371_pci_write, es1371); + + timer_add(es1371_poll, &es1371->dac[1].time, TIMER_ALWAYS_ENABLED, es1371); + + return es1371; +} + +static void es1371_close(void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + free(es1371); +} + +static void es1371_speed_changed(void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + es1371->dac[1].latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); +} + +device_t es1371_device = +{ + "Ensoniq AudioPCI (ES1371)", + 0, + es1371_init, + es1371_close, + NULL, + es1371_speed_changed, + NULL, + NULL, + NULL +}; diff --git a/src/sound_audiopci.h b/src/sound_audiopci.h new file mode 100644 index 0000000..726b1d0 --- /dev/null +++ b/src/sound_audiopci.h @@ -0,0 +1 @@ +extern device_t es1371_device; From 72691e558512d1ff374c3b46912e2636904bfe4c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Oct 2017 11:54:56 +0100 Subject: [PATCH 0170/1050] Implemented a few missing AudioPCI registers - now works with Windows ME WDM drivers. --- src/sound_audiopci.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index 4fd9f76..fb6ef0c 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -52,7 +52,7 @@ typedef struct es1371_t int16_t out_l, out_r; int32_t vol_l, vol_r; - } dac[2]; + } dac[2], adc; int dac_latch, dac_time; @@ -186,6 +186,10 @@ static uint8_t es1371_inb(uint16_t port, void *p) case 0x09: ret = es1371->uart_status; break; + + case 0x0c: + ret = es1371->mem_page; + break; case 0x1a: ret = es1371->legacy_ctrl >> 16; @@ -297,6 +301,34 @@ static uint32_t es1371_inl(uint16_t port, void *p) ret |= es1371->codec_regs[(es1371->codec_ctrl >> 16) & 0x3f]; ret |= CODEC_READY; break; + + case 0x34: + switch (es1371->mem_page) + { + case 0xc: + ret = es1371->dac[0].size | (es1371->dac[0].count << 16); + break; + + case 0xd: + ret = es1371->adc.size | (es1371->adc.count << 16); + break; + + default: + pclog("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); + } + break; + + case 0x3c: + switch (es1371->mem_page) + { + case 0xc: + ret = es1371->dac[1].size | (es1371->dac[1].count << 16); + break; + + default: + pclog("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); + } + break; default: pclog("Bad es1371_inl: port=%04x\n", port); @@ -538,6 +570,11 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) es1371->dac[0].count -= 4; break; + case 0xd: + es1371->adc.size = val & 0xffff; + es1371->adc.count = val >> 16; + break; + default: pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); } @@ -573,9 +610,6 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) es1371->dac[1].size = val & 0xffff; es1371->dac[1].count = val >> 16; break; - - case 0xd: - break; default: pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); From c28490cc2f28b18120afdfc158b760c21374577e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Oct 2017 12:31:47 +0100 Subject: [PATCH 0171/1050] Added Epson PC AX, AX2e and AX3 models. Patch from dns2kv2. --- src/ibm.h | 3 +++ src/mem.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/model.c | 3 +++ src/nvr.c | 6 ++++++ 4 files changed, 53 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index 250feab..ff343c1 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -433,6 +433,9 @@ enum ROM_IBMPS2_M80, ROM_ATARIPC3, ROM_IBMXT286, + ROM_EPSON_PCAX, + ROM_EPSON_PCAX2E, + ROM_EPSON_PCAX3, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index 841f018..54575a2 100644 --- a/src/mem.c +++ b/src/mem.c @@ -714,6 +714,47 @@ int loadbios() fclose(ff); fclose(f); return 1; + + case ROM_EPSON_PCAX: + f = romfopen("epson_pcax/EVAX", "rb"); + ff = romfopen("epson_pcax/ODAX", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + + case ROM_EPSON_PCAX2E: + f = romfopen("epson_pcax2e/EVAXE", "rb"); + ff = romfopen("epson_pcax2e/ODAXE", "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_EPSON_PCAX3: + f = romfopen("epson_pcax3/EVAX3", "rb"); + ff = romfopen("epson_pcax3/ODAX3", "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; + } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 5105083..00734ba 100644 --- a/src/model.c +++ b/src/model.c @@ -122,6 +122,8 @@ MODEL models[] = {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_cbm_init, NULL}, {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, + {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, + {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT , 512,16384,128, at_scat_init, NULL}, {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, @@ -135,6 +137,7 @@ MODEL models[] = {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, + {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT , 512,16384,512, at_scatsx_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 88b88b5..355281d 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -275,6 +275,9 @@ void loadnvr() case ROM_DTK386: f = nvrfopen("dtk386.nvr", "rb"); nvrmask = 127; break; case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "rb"); nvrmask = 127; break; case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "rb"); nvrmask = 127; break; + case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "rb"); nvrmask = 127; break; + case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); nvrmask = 127; break; + case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); nvrmask = 127; break; default: return; } if (!f) @@ -343,6 +346,9 @@ void savenvr() case ROM_DTK386: f = nvrfopen("dtk386.nvr", "wb"); break; case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "wb"); break; case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "wb"); break; + case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "wb"); break; + case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); break; + case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); break; default: return; } fwrite(nvrram,128,1,f); From 5d5fa1402a999767ef534031e2a51a86fc844107 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Oct 2017 14:20:38 +0100 Subject: [PATCH 0172/1050] Added Toshiba T3100e emulation. Patch from John Elliott. --- src/Makefile.am | 3 +- src/Makefile.linux32 | 4 +- src/Makefile.linux32-wx-sdl2 | 4 +- src/Makefile.linux64 | 4 +- src/Makefile.linux64-wx-sdl2 | 4 +- src/Makefile.mingw | 4 +- src/Makefile.mingw-network | 4 +- src/Makefile.mingw-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2-network | 4 +- src/Makefile.mingw64 | 4 +- src/Makefile.osx64-wx-sdl2 | 4 +- src/ibm.h | 3 +- src/keyboard_at.c | 16 + src/mem.c | 9 +- src/model.c | 4 +- src/nvr.c | 3 + src/t3100e.c | 596 ++++++++++++++++++++++++++++ src/vid_t3100e.c | 606 +++++++++++++++++++++++++++++ src/vid_t3100e.h | 3 + src/video.c | 18 +- src/video.h | 2 +- 21 files changed, 1277 insertions(+), 26 deletions(-) create mode 100644 src/t3100e.c create mode 100644 src/vid_t3100e.c create mode 100644 src/vid_t3100e.h diff --git a/src/Makefile.am b/src/Makefile.am index dfb8fab..ddd8cc9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,11 +23,12 @@ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_ serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ +t3100e.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ vid_icd2061.c vid_ics2595.c vid_incolor.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_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_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t3100e.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 vid_wy700.c \ x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ dosbox/nukedopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index ee86b5a..8b31bae 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -14,12 +14,12 @@ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o thread-pthread.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.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 wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.o diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 90b2f6e..e86d876 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -13,12 +13,12 @@ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 3750ae1..030f711 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -13,12 +13,12 @@ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 thread-pthread.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o thread-pthread.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.o diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 1951791..53905fd 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -13,12 +13,12 @@ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index baae45f..5ada033 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -12,12 +12,12 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 7e135a6..8e8abac 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -13,12 +13,12 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xtide.o pc.res diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 9f331f0..941f0dd 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -15,12 +15,12 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 5f5383a..e5b3515 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -15,12 +15,12 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 1f4678e..0604e1a 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -12,12 +12,12 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 1c3edbd..761cc82 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -12,12 +12,12 @@ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ diff --git a/src/ibm.h b/src/ibm.h index ff343c1..8c09065 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -370,7 +370,7 @@ char discfns[2][256]; int driveempty[2]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || 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 && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -436,6 +436,7 @@ enum ROM_EPSON_PCAX, ROM_EPSON_PCAX2E, ROM_EPSON_PCAX3, + ROM_T3100E, ROM_MAX }; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index c4a3c72..e7b6453 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -357,6 +357,9 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) key_ctrl_queue_start = key_ctrl_queue_end = 0; keyboard_at.status &= ~STAT_OFULL; } + /* T3100e expects STAT_IFULL to be set immediately + * after sending 0xAA */ + keyboard_at.status |= STAT_IFULL; keyboard_at.status |= STAT_SYSFLAG; keyboard_at.mem[0] |= 0x04; keyboard_at_adddata(0x55); @@ -382,6 +385,18 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xae: /*Enable keyboard*/ keyboard_at.mem[0] &= ~0x10; break; + + case 0xbb: /* Read 'Fn' key - sent by Toshiba 3100e + BIOS. Return it for right Ctrl and right + Alt; on the real T3100e, these keystrokes + could only be generated using 'Fn'. */ + if (pcem_key[0xb8] || /* Right Alt */ + pcem_key[0x9d]) /* Right Ctrl */ + { + keyboard_at_adddata(0x04); + } + else keyboard_at_adddata(0x00); + break; case 0xc0: /*Read input port*/ keyboard_at_adddata(keyboard_at.input_port | 4); @@ -504,6 +519,7 @@ static void at_refresh(void *p) void keyboard_at_init() { //return; + memset(&keyboard_at, 0, sizeof(keyboard_at)); io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL, NULL); keyboard_at_reset(); keyboard_send = keyboard_at_adddata_keyboard; diff --git a/src/mem.c b/src/mem.c index 54575a2..9a5b6b8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -38,7 +38,7 @@ static mem_mapping_t base_mapping; mem_mapping_t ram_low_mapping; mem_mapping_t ram_high_mapping; mem_mapping_t ram_mid_mapping; -static mem_mapping_t ram_remapped_mapping; +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; @@ -755,6 +755,13 @@ int loadbios() fclose(f); return 1; + case ROM_T3100E: + loadfont("t3100e/t3100e_font.bin", 5); + f=romfopen("t3100e/t3100e.rom","rb"); + if (!f) break; + fread(rom,65536,1,f); + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 00734ba..a0962bf 100644 --- a/src/model.c +++ b/src/model.c @@ -89,6 +89,7 @@ void at_i430vx_init(); void at_batman_init(); void at_endeavor_init(); void xt_laserxt_init(); +void at_t3100e_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -132,7 +133,8 @@ MODEL models[] = {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512,2048, 128, at_scat_init, NULL}, {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, - + {"[286] Toshiba 3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_HAS_IDE, 1024,5120,256, at_t3100e_init, NULL}, + {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 355281d..bd4794a 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -278,6 +278,8 @@ void loadnvr() case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); nvrmask = 127; break; + case ROM_T3100E: f = nvrfopen("t3100e.nvr", "rb"); break; + default: return; } if (!f) @@ -349,6 +351,7 @@ void savenvr() case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "wb"); break; case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); break; + case ROM_T3100E: f = nvrfopen("t3100e.nvr", "wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/t3100e.c b/src/t3100e.c new file mode 100644 index 0000000..4f03b83 --- /dev/null +++ b/src/t3100e.c @@ -0,0 +1,596 @@ +#include "ibm.h" +#include "cpu.h" +#include "model.h" +#include "io.h" +#include "mouse.h" +#include "mem.h" +#include "device.h" +#include "vid_t3100e.h" + +/* The Toshiba 3100e is a 286-based portable. + * + * To bring up the BIOS setup screen hold down the 'Fn' key on booting + * + * Memory management + * ~~~~~~~~~~~~~~~~~ + * + * Motherboard memory is divided into: + * - Conventional memory: Either 512k or 640k + * - Upper memory: Either 512k or 384k, depending on amount of + * conventional memory. Upper memory can be + * used either as EMS or XMS. + * - High memory: 0-4Mb, depending on RAM installed. The BIOS + * setup screen allows some or all of this to be + * used as EMS; the remainder is XMS. + * + * Additional memory (either EMS or XMS) can also be provided by ISA + * expansion cards. + * + * Under test in PCEM, the BIOS will boot with up to 65368Kb of memory in + * total (16Mb less 16k). However it will give an error with RAM sizes + * above 8Mb, if any of the high memory is allocated as EMS, because the + * builtin EMS page registers can only access up to 8Mb. + * + * Memory is controlled by writes to I/O port 8084h: + * Bit 7: Always 0 } + * Bit 6: Always 1 } These bits select which motherboard function to + * Bit 5: Always 0 } access. + * Bit 4: Set to treat upper RAM as XMS + * Bit 3: Enable external RAM boards? + * Bit 2: Set for 640k conventional memory, clear for 512k + * Bit 1: Enable RAM beyond 1Mb. + * Bit 0: Enable EMS. + * + * The last value written to this port is saved at 0040:0093h, and in + * CMOS memory at offset 0x37. If the top bit of the CMOS byte is set, + * then high memory is being provided by an add-on card rather than the + * mainboard; accordingly, the BIOS will not allow high memory to be + * used as EMS. + * + * EMS is controlled by 16 page registers: + * + * Page mapped at 0xD000 0xD400 0xD800 0xDC00 + * ------------------------------------------------------ + * Pages 0x00-0x7F 0x208 0x4208 0x8208 0xc208 + * Pages 0x80-0xFF 0x218 0x4218 0x8218 0xc218 + * Pages 0x100-0x17F 0x258 0x4258 0x8258 0xc258 + * Pages 0x180-0x1FF 0x268 0x4268 0x8268 0xc268 + * + * The value written has bit 7 set to enable EMS, reset to disable it. + * + * So: OUT 0x208, 0x80 will page in the first 16k page at 0xD0000. + * OUT 0x208, 0x00 will page out EMS, leaving nothing at 0xD0000. + * OUT 0x4208, 0x80 will page in the first 16k page at 0xD4000. + * OUT 0x218, 0x80 will page in the 129th 16k page at 0xD0000. + * + * etc. + * + * To use EMS from DOS, you will need the Toshiba EMS driver (TOSHEMM.ZIP). + * This supports the above system, plus further ranges of ports at + * 0x_2A8, 0x_2B8, 0x_2C8. + * + */ + +static const int t3100e_log = 0; + +extern uint8_t *ram; /* Physical RAM */ + +/* Features not implemented: + * > Four video fonts. + * > BIOS-controlled mapping of serial ports to IRQs. + * > Custom keyboard controller. This has a number of extra commands in the + * 0xB0-0xBC range, for such things as turbo on/off, and switching the + * keyboard between AT and PS/2 modes. Currently I have only implemented + * command 0xBB, so that self-test completes successfully. Commands include: + * + * 0xB0: Turbo on + * 0xB1: Turbo off + * 0xB2: Internal display on? + * 0xB3: Internal display off? + * 0xB5: Get settings byte (bottom bit is colour / mono setting) + * 0xB6: Set settings byte + * 0xB7: Behave as 101-key PS/2 keyboard + * 0xB8: Behave as 84-key AT keyboard + * 0xBB: Return a byte, bit 2 is Fn key state, other bits unknown. + * + * The other main I/O port needed to POST is: + * 0x8084: System control. + * Top 3 bits give command, bottom 5 bits give parameters. + * 000 => set serial port IRQ / addresses + * bit 4: IRQ5 serial port base: 1 => 0x338, 0 => 0x3E8 + * bits 3, 2, 0 specify serial IRQs for COM1, COM2, COM3: + * 00 0 => 4, 3, 5 + * 00 1 => 4, 5, 3 + * 01 0 => 3, 4, 5 + * 01 1 => 3, 5, 4 + * 10 0 => 4, -, 3 + * 10 1 => 3, -, 4 + * 010 => set memory mappings + * bit 4 set if upper RAM is XMS + * bit 3 enable add-on memory boards beyond 5Mb? + * bit 2 set for 640k sysram, clear for 512k sysram + * bit 1 enable mainboard XMS + * bit 0 enable mainboard EMS + * 100 => set parallel mode / LCD settings + * bit 4 set for bidirectional parallel port + * bit 3 set to disable internal CGA + * bit 2 set for single-pixel LCD font + * bits 0,1 for display font + */ + +void at_init(); + +/* The T3100e motherboard can (and does) dynamically reassign RAM between + * conventional, XMS and EMS. This translates to monkeying with the mappings. + */ + +extern mem_mapping_t base_mapping; + +extern mem_mapping_t ram_low_mapping; /* This is to switch conventional RAM + * between 512k and 640k */ + +extern mem_mapping_t ram_mid_mapping; /* This will not be used */ + +extern mem_mapping_t ram_high_mapping; /* This is RAM beyond 1Mb if any */ + +extern mem_mapping_t ram_remapped_mapping; /* This will not be used */ + +extern uint8_t *ram; + +static unsigned t3100e_ems_page_reg[] = +{ + 0x208, 0x4208, 0x8208, 0xc208, /* The first four map the first 2Mb */ + /* of RAM into the page frame */ + 0x218, 0x4218, 0x8218, 0xc218, /* The next four map the next 2Mb */ + /* of RAM */ + 0x258, 0x4258, 0x8258, 0xc258, /* and so on. */ + 0x268, 0x4268, 0x8268, 0xc268, +}; + +struct t3100e_ems_regs +{ + uint8_t page[16]; + mem_mapping_t mapping[4]; + uint32_t page_exec[4]; /* Physical location of memory pages */ + uint32_t upper_base; /* Start of upper RAM */ + uint8_t upper_pages; /* Pages of EMS available from upper RAM */ + uint8_t upper_is_ems; /* Upper RAM is EMS? */ + mem_mapping_t upper_mapping; + +} t3100e_ems; + +void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); + + +/* Given a memory address (which ought to be in the page frame at 0xD0000), + * which page does it relate to? */ +static int addr_to_page(uint32_t addr) +{ + if ((addr & 0xF0000) == 0xD0000) + { + return ((addr >> 14) & 3); + } + return -1; +} + +/* And vice versa: Given a page slot, which memory address does it + * correspond to? */ +static uint32_t page_to_addr(int pg) +{ + return 0xD0000 + ((pg & 3) * 16384); +} + +/* Given an EMS page ID, return its physical address in RAM. */ +uint32_t t3100e_ems_execaddr(struct t3100e_ems_regs *regs, + int pg, uint16_t val) +{ + uint32_t addr; + + if (!(val & 0x80)) return 0; /* Bit 7 reset => not mapped */ + + val &= 0x7F; + val += (0x80 * (pg >> 2)); /* The high bits of the register bank */ + /* are used to extend val to allow up */ + /* to 8Mb of EMS to be accessed */ + + /* Is it in the upper memory range? */ + if (regs->upper_is_ems) + { + if (val < regs->upper_pages) + { + addr = regs->upper_base + 0x4000 * val; + return addr; + } + val -= regs->upper_pages; + } + /* Otherwise work down from the top of high RAM (so, the more EMS, + * the less XMS) */ + if ((val * 0x4000) + 0x100000 >= (mem_size * 1024)) + { + return 0; /* Not enough high RAM for this page */ + } + /* High RAM found */ + addr = (mem_size * 1024) - 0x4000 * (val + 1); + + return addr; +} + + +/* The registers governing the EMS ports are in rather a nonintuitive order */ +static int port_to_page(uint16_t addr) +{ + switch (addr) + { + case 0x208: return 0; + case 0x4208: return 1; + case 0x8208: return 2; + case 0xC208: return 3; + case 0x218: return 4; + case 0x4218: return 5; + case 0x8218: return 6; + case 0xC218: return 7; + case 0x258: return 8; + case 0x4258: return 9; + case 0x8258: return 10; + case 0xC258: return 11; + case 0x268: return 12; + case 0x4268: return 13; + case 0x8268: return 14; + case 0xC268: return 15; + } + return -1; +} + +/* Used to dump the memory mapping table, for debugging +void dump_mappings() +{ + mem_mapping_t *mm = base_mapping.next; + + if (!t3100e_log) return; + while (mm) + { + const char *name = ""; + uint32_t offset = (uint32_t)(mm->exec - ram); + + if (mm == &ram_low_mapping ) name = "LOW "; + if (mm == &ram_mid_mapping ) name = "MID "; + if (mm == &ram_high_mapping) name = "HIGH"; + if (mm == &t3100e_ems.upper_mapping) name = "UPPR"; + if (mm == &t3100e_ems.mapping[0]) + { + name = "EMS0"; + offset = t3100e_ems.page_exec[0]; + } + if (mm == &t3100e_ems.mapping[1]) + { + name = "EMS1"; + offset = t3100e_ems.page_exec[1]; + } + if (mm == &t3100e_ems.mapping[2]) + { + name = "EMS2"; + offset = t3100e_ems.page_exec[2]; + } + if (mm == &t3100e_ems.mapping[3]) + { + name = "EMS3"; + offset = t3100e_ems.page_exec[3]; + } + + pclog(" %p | base=%05x size=%05x %c @ %06x %s\n", mm, + mm->base, mm->size, mm->enable ? 'Y' : 'N', + offset, name); + + mm = mm->next; + } +}*/ + +void t3100e_map_ram(uint8_t val) +{ + int n; + int32_t upper_len; + + if (t3100e_log) + { + pclog("OUT 0x8084, %02x [ set memory mapping :", val | 0x40); + if (val & 1) pclog("ENABLE_EMS "); + if (val & 2) pclog("ENABLE_XMS "); + if (val & 4) pclog("640K "); + if (val & 8) pclog("X8X "); + if (val & 16) pclog("UPPER_IS_XMS "); + pclog("\n"); + } + /* Bit 2 controls size of conventional memory */ + if (val & 4) + { + t3100e_ems.upper_base = 0xA0000; + t3100e_ems.upper_pages = 24; + } + else + { + t3100e_ems.upper_base = 0x80000; + t3100e_ems.upper_pages = 32; + } + upper_len = t3100e_ems.upper_pages * 16384; + + mem_mapping_set_addr(&ram_low_mapping, 0, t3100e_ems.upper_base); + /* Bit 0 set if upper RAM is EMS */ + t3100e_ems.upper_is_ems = (val & 1); + + /* Bit 1 set if high RAM is enabled */ + if (val & 2) + { + mem_mapping_enable(&ram_high_mapping); + } + else + { + mem_mapping_disable(&ram_high_mapping); + } + + /* Bit 4 set if upper RAM is mapped to high memory + * (and bit 1 set if XMS enabled) */ + if ((val & 0x12) == 0x12) + { + mem_mapping_set_addr(&t3100e_ems.upper_mapping, + mem_size * 1024, + upper_len); + mem_mapping_enable(&t3100e_ems.upper_mapping); + } + else + { + mem_mapping_disable(&t3100e_ems.upper_mapping); + } + /* Recalculate EMS mappings */ + for (n = 0; n < 4; n++) + { + t3100e_ems_out(t3100e_ems_page_reg[n], t3100e_ems.page[n], + &t3100e_ems); + } + + //dump_mappings(); +} + + +uint8_t t3100e_sys_in(uint16_t addr, void *p) +{ +// struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; + + /* XXX Not implemented. Seems to return 0x0C on real hardware */ + if (t3100e_log) pclog("IN 0x8084\n"); + return 0x0C; +} + + + +/* Handle writes to the T3100e system control port at 0x8084 */ +void t3100e_sys_out(uint16_t addr, uint8_t val, void *p) +{ +// struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; + + switch (val & 0xE0) + { + case 0x00: /* Set serial port IRQs. Not implemented */ + if (t3100e_log) pclog("OUT 0x8084, %02x [ set serial port IRQs]\n", val); + break; + case 0x40: /* Set RAM mappings. */ + t3100e_map_ram(val & 0x1F); + break; + + case 0x80: /* Set video options. */ + t3100e_video_options_set(val & 0x1F); break; + + /* Other options not implemented. */ + default: if (t3100e_log) pclog("OUT 0x8084, %02x\n", val); break; + } +} + +/* Read EMS page register */ +uint8_t t3100e_ems_in(uint16_t addr, void *p) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; + + return regs->page[port_to_page(addr)]; + +} + +/* Write EMS page register */ +void t3100e_ems_out(uint16_t addr, uint8_t val, void *p) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; + int pg = port_to_page(addr); + + regs->page_exec[pg & 3] = t3100e_ems_execaddr(regs, pg, val); + if (t3100e_log) pclog("EMS: page %d %02x -> %02x [%06x]\n", + pg, regs->page[pg], val, regs->page_exec[pg & 3]); + regs->page[pg] = val; + + pg &= 3; +/* Bit 7 set if page is enabled, reset if page is disabled */ + if (regs->page_exec[pg]) + { + if (t3100e_log) pclog("Enabling EMS RAM at %05x\n", + page_to_addr(pg)); + mem_mapping_enable(®s->mapping[pg]); + } + else + { + if (t3100e_log) pclog("Disabling EMS RAM at %05x\n", + page_to_addr(pg)); + mem_mapping_disable(®s->mapping[pg]); + } +} + + +/* Read RAM in the EMS page frame */ +static uint8_t ems_read_ram(uint32_t addr, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return 0xFF; + addr = regs->page_exec[pg] + (addr & 0x3FFF); + return ram[addr]; +} + + + + +static uint16_t ems_read_ramw(uint32_t addr, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return 0xFF; + //pclog("ems_read_ramw addr=%05x ", addr); + addr = regs->page_exec[pg] + (addr & 0x3FFF); + //pclog("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); + return *(uint16_t *)&ram[addr]; +} + + +static uint32_t ems_read_raml(uint32_t addr, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return 0xFF; + addr = regs->page_exec[pg] + (addr & 0x3FFF); + return *(uint32_t *)&ram[addr]; +} + +/* Write RAM in the EMS page frame */ +static void ems_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return; + addr = regs->page_exec[pg] + (addr & 0x3FFF); + ram[addr] = val; +} + + +static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return; + //pclog("ems_write_ramw addr=%05x ", addr); + addr = regs->page_exec[pg] + (addr & 0x3FFF); + //pclog("-> %06x val=%04x\n", addr, val); + + *(uint16_t *)&ram[addr] = val; +} + + +static void ems_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return; + addr = regs->page_exec[pg] + (addr & 0x3FFF); + *(uint32_t *)&ram[addr] = val; +} + + + +/* Read RAM in the upper area. This is basically what the 'remapped' + * mapping in mem.c does, except that the upper area can move around */ +static uint8_t upper_read_ram(uint32_t addr, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + + addr = (addr - (1024 * mem_size)) + regs->upper_base; + return ram[addr]; +} + +static uint16_t upper_read_ramw(uint32_t addr, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + + addr = (addr - (1024 * mem_size)) + regs->upper_base; + return *(uint16_t *)&ram[addr]; +} + +static uint32_t upper_read_raml(uint32_t addr, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + + addr = (addr - (1024 * mem_size)) + regs->upper_base; + return *(uint32_t *)&ram[addr]; +} + + +static void upper_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + + addr = (addr - (1024 * mem_size)) + regs->upper_base; + ram[addr] = val; +} + + +static void upper_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + + addr = (addr - (1024 * mem_size)) + regs->upper_base; + *(uint16_t *)&ram[addr] = val; +} + + + +static void upper_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + + addr = (addr - (1024 * mem_size)) + regs->upper_base; + *(uint32_t *)&ram[addr] = val; +} + + + + +void at_t3100e_init() +{ + int pg; + + memset(&t3100e_ems, 0, sizeof(t3100e_ems)); + + at_init(); + /* Hook up system control port */ + io_sethandler(0x8084, 0x0001, + t3100e_sys_in, NULL, NULL, + t3100e_sys_out, NULL, NULL, &t3100e_ems); + + /* Start monitoring all 16 EMS registers */ + for (pg = 0; pg < 16; pg++) + { + io_sethandler(t3100e_ems_page_reg[pg], 0x0001, + t3100e_ems_in, NULL, NULL, + t3100e_ems_out, NULL, NULL, &t3100e_ems); + } + + /* Map the EMS page frame */ + for (pg = 0; pg < 4; pg++) + { + if (t3100e_log) pclog("Adding memory map at %x for page %d\n", page_to_addr(pg), pg); + mem_mapping_add(&t3100e_ems.mapping[pg], + page_to_addr(pg), 16384, + ems_read_ram, ems_read_ramw, ems_read_raml, + ems_write_ram, ems_write_ramw, ems_write_raml, + NULL, MEM_MAPPING_EXTERNAL, + &t3100e_ems); + /* Start them all off disabled */ + mem_mapping_disable(&t3100e_ems.mapping[pg]); + } + /* Mapping for upper RAM when in use as XMS*/ + mem_mapping_add(&t3100e_ems.upper_mapping, mem_size * 1024, 384 * 1024, + upper_read_ram, upper_read_ramw, upper_read_raml, + upper_write_ram, upper_write_ramw, upper_write_raml, + NULL, MEM_MAPPING_INTERNAL, &t3100e_ems); + mem_mapping_disable(&t3100e_ems.upper_mapping); + mem_mapping_disable(&ram_remapped_mapping); +} diff --git a/src/vid_t3100e.c b/src/vid_t3100e.c new file mode 100644 index 0000000..94078e0 --- /dev/null +++ b/src/vid_t3100e.c @@ -0,0 +1,606 @@ +/* Emulate the Toshiba 3100e plasma display. This display has a fixed 640x400 + * resolution. */ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "timer.h" +#include "video.h" +#include "vid_t3100e.h" + +#define T3100E_XSIZE 640 +#define T3100E_YSIZE 400 + +/* T3100e CRTC regs (from the ROM): + * + * Selecting a character height of 3 seems to be sufficient to convert the + * 640x200 graphics mode to 640x400 (and, by analogy, 320x200 to 320x400). + * + * + * Horiz-----> Vert------> I ch + * 38 28 2D 0A 1F 06 19 1C 02 07 06 07 CO40 + * 71 50 5A 0A 1F 06 19 1C 02 07 06 07 CO80 + * 38 28 2D 0A 7F 06 64 70 02 01 06 07 Graphics + * 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO + * 2D 28 22 0A 67 00 64 67 02 03 06 07 640x400 + */ +void updatewindowsize(int x, int y); + +/* Mapping of attributes to colours */ +static uint32_t amber, black; +static uint32_t blinkcols[256][2]; +static uint32_t normcols[256][2]; + +/* Video options set by the motherboard; they will be picked up by the card + * on the next poll. + * + * Bit 3: Disable built-in video (for add-on card) + * Bit 2: Thin font + * Bits 0,1: Font set (not currently implemented) + */ +static uint8_t st_video_options; + +void t3100e_video_options_set(uint8_t options) +{ + st_video_options = options; +} + + +typedef struct t3100e_t +{ + mem_mapping_t mapping; + + uint8_t cga_crtc[32]; /* The CRTC as the host PC sees it. Most + * of the registers are ignored by the plasma + * display. */ + int cga_crtcreg; /* Current CRTC register */ + uint8_t cga_ctrl; /* CGA control register */ + uint8_t cga_colour; /* CGA colour register */ + uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + + int font; /* Current font, 0-3 */ + int enabled; /* Hardware enabled, 0 or 1 */ + + int dispontime, dispofftime; + int vidtime; + + int linepos, displine; + int vc; + int dispon, blink; + int vsynctime; + uint8_t video_options; + + uint8_t *vram; +} t3100e_t; + + +void t3100e_recalctimings(t3100e_t *t3100e); +void t3100e_write(uint32_t addr, uint8_t val, void *p); +uint8_t t3100e_read(uint32_t addr, void *p); + + +void t3100e_out(uint16_t addr, uint8_t val, void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + switch (addr) + { + /* Emulated CRTC, register select */ + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: + t3100e->cga_crtcreg = val & 31; + break; + + /* Emulated CRTC, value */ + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + t3100e->cga_crtc[t3100e->cga_crtcreg] = val; + + t3100e_recalctimings(t3100e); + return; + + /* CGA control register */ + case 0x3D8: + t3100e->cga_ctrl = val; + return; + /* CGA colour register */ + case 0x3D9: + t3100e->cga_colour = val; + return; + } +} + +uint8_t t3100e_in(uint16_t addr, void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + switch (addr) + { + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: + return t3100e->cga_crtcreg; + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + return t3100e->cga_crtc[t3100e->cga_crtcreg]; + case 0x3d8: + return t3100e->cga_ctrl; + case 0x3d9: + return t3100e->cga_colour; + case 0x3da: + return t3100e->cga_stat; + } + return 0xff; +} + + + + +void t3100e_write(uint32_t addr, uint8_t val, void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + egawrites++; + +// pclog("CGA_WRITE %04X %02X\n", addr, val); + t3100e->vram[addr & 0x7fff] = val; + cycles -= 4; +} + + + +uint8_t t3100e_read(uint32_t addr, void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + egareads++; + cycles -= 4; + +// pclog("CGA_READ %04X\n", addr); + return t3100e->vram[addr & 0x7fff]; +} + + + +void t3100e_recalctimings(t3100e_t *t3100e) +{ + double disptime; + double _dispontime, _dispofftime; + + disptime = 651; + _dispontime = 640; + _dispofftime = disptime - _dispontime; + t3100e->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + t3100e->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +} + + +/* Draw a row of text in 80-column mode */ +void t3100e_text_row80(t3100e_t *t3100e) +{ + uint32_t cols[2]; + int x, c; + uint8_t chr, attr; + int drawcursor; + int cursorline; + int bold; + int blink; + uint16_t addr; + uint8_t sc; + uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; + uint16_t ca = (t3100e->cga_crtc[15] | (t3100e->cga_crtc[14] << 8)) & 0x7fff; + + sc = (t3100e->displine) & 15; + addr = ((ma & ~1) + (t3100e->displine >> 4) * 80) * 2; + ma += (t3100e->displine >> 4) * 80; + + if ((t3100e->cga_crtc[10] & 0x60) == 0x20) + { + cursorline = 0; + } + else + { + cursorline = ((t3100e->cga_crtc[10] & 0x0F)*2 <= sc) && + ((t3100e->cga_crtc[11] & 0x0F)*2 >= sc); + } + for (x = 0; x < 80; x++) + { + chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; + attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && + (t3100e->cga_ctrl & 8) && (t3100e->blink & 16)); + + blink = ((t3100e->blink & 16) && (t3100e->cga_ctrl & 0x20) && + (attr & 0x80) && !drawcursor); + + /* XXX We should also be taking account of bits 0,1 of + * options to select one of the four ROM character sets; + * but these are not currently emulated. */ + + if (t3100e->video_options & 4) + bold = (attr & 8) ? chr + 256 : chr; + else + bold = (attr & 8) ? chr : chr + 256; + + if (t3100e->cga_ctrl & 0x20) /* Blink */ + { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + if (blink) cols[1] = cols[0]; + } + else + { + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + if (drawcursor) + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } + } + else + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + ++ma; + } +} + +/* Draw a row of text in 40-column mode */ +void t3100e_text_row40(t3100e_t *t3100e) +{ + uint32_t cols[2]; + int x, c; + uint8_t chr, attr; + int drawcursor; + int cursorline; + int bold; + int blink; + uint16_t addr; + uint8_t sc; + uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; + uint16_t ca = (t3100e->cga_crtc[15] | (t3100e->cga_crtc[14] << 8)) & 0x7fff; + + sc = (t3100e->displine) & 15; + addr = ((ma & ~1) + (t3100e->displine >> 4) * 40) * 2; + ma += (t3100e->displine >> 4) * 40; + + if ((t3100e->cga_crtc[10] & 0x60) == 0x20) + { + cursorline = 0; + } + else + { + cursorline = ((t3100e->cga_crtc[10] & 0x0F)*2 <= sc) && + ((t3100e->cga_crtc[11] & 0x0F)*2 >= sc); + } + for (x = 0; x < 40; x++) + { + chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; + attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; + drawcursor = ((ma == ca) && cursorline && + (t3100e->cga_ctrl & 8) && (t3100e->blink & 16)); + + blink = ((t3100e->blink & 16) && (t3100e->cga_ctrl & 0x20) && + (attr & 0x80) && !drawcursor); + + if (t3100e->video_options & 4) + bold = (attr & 8) ? chr + 256 : chr; + else bold = (attr & 8) ? chr : chr + 256; + + if (t3100e->cga_ctrl & 0x20) /* Blink */ + { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + if (blink) cols[1] = cols[0]; + } + else + { + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + if (drawcursor) + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2] = + ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } + } + else + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2] = + ((uint32_t *)buffer32->line[t3100e->displine])[(x << 4) + c*2+1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ++ma; + } +} + + + + +/* Draw a line in CGA 640x200 or T3100e 640x400 mode */ +void t3100e_cgaline6(t3100e_t *t3100e) +{ + int x, c; + uint8_t dat; + uint32_t ink = 0; + uint16_t addr; + uint32_t fg = (t3100e->cga_colour & 0x0F) ? amber : black; + uint32_t bg = black; + + uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; + + if (t3100e->cga_crtc[9] == 3) /* 640*400 */ + { + addr = ((t3100e->displine) & 1) * 0x2000 + + ((t3100e->displine >> 1) & 1) * 0x4000 + + (t3100e->displine >> 2) * 80 + + ((ma & ~1) << 1); + } + else + { + addr = ((t3100e->displine >> 1) & 1) * 0x2000 + + (t3100e->displine >> 2) * 80 + + ((ma & ~1) << 1); + } + for (x = 0; x < 80; x++) + { + dat = t3100e->vram[addr & 0x7FFF]; + addr++; + + for (c = 0; c < 8; c++) + { + ink = (dat & 0x80) ? fg : bg; + if (!(t3100e->cga_ctrl & 8)) ink = black; + ((uint32_t *)buffer32->line[t3100e->displine])[x*8+c] = ink; + dat = dat << 1; + } + } +} + + +/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to + * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ +void t3100e_cgaline4(t3100e_t *t3100e) +{ + int x, c; + uint8_t dat, pattern; + uint32_t ink0, ink1; + uint16_t addr; + + uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; + if (t3100e->cga_crtc[9] == 3) /* 320*400 undocumented */ + { + addr = ((t3100e->displine) & 1) * 0x2000 + + ((t3100e->displine >> 1) & 1) * 0x4000 + + (t3100e->displine >> 2) * 80 + + ((ma & ~1) << 1); + } + else /* 320*200 */ + { + addr = ((t3100e->displine >> 1) & 1) * 0x2000 + + (t3100e->displine >> 2) * 80 + + ((ma & ~1) << 1); + } + for (x = 0; x < 80; x++) + { + dat = t3100e->vram[addr & 0x7FFF]; + addr++; + + for (c = 0; c < 4; c++) + { + pattern = (dat & 0xC0) >> 6; + if (!(t3100e->cga_ctrl & 8)) pattern = 0; + + switch (pattern & 3) + { + case 0: ink0 = ink1 = black; break; + case 1: if (t3100e->displine & 1) + { + ink0 = black; ink1 = black; + } + else + { + ink0 = amber; ink1 = black; + } + break; + case 2: if (t3100e->displine & 1) + { + ink0 = black; ink1 = amber; + } + else + { + ink0 = amber; ink1 = black; + } + break; + case 3: ink0 = ink1 = amber; break; + + } + ((uint32_t *)buffer32->line[t3100e->displine])[x*8+2*c] = ink0; + ((uint32_t *)buffer32->line[t3100e->displine])[x*8+2*c+1] = ink1; + dat = dat << 2; + } + } +} + + + + + + +void t3100e_poll(void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + + if (t3100e->video_options != st_video_options) + { + t3100e->video_options = st_video_options; + + if (t3100e->video_options & 8) /* Disable internal CGA */ + mem_mapping_disable(&t3100e->mapping); + else mem_mapping_enable(&t3100e->mapping); + + } + + if (!t3100e->linepos) + { + t3100e->vidtime += t3100e->dispofftime; + t3100e->cga_stat |= 1; + t3100e->linepos = 1; + if (t3100e->dispon) + { + if (t3100e->displine == 0) + { + video_wait_for_buffer(); + } + + /* Graphics */ + if (t3100e->cga_ctrl & 0x02) + { + if (t3100e->cga_ctrl & 0x10) + t3100e_cgaline6(t3100e); + else t3100e_cgaline4(t3100e); + } + else + if (t3100e->cga_ctrl & 0x01) /* High-res text */ + { + t3100e_text_row80(t3100e); + } + else + { + t3100e_text_row40(t3100e); + } + } + t3100e->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (t3100e->displine == 400) /* Start of VSYNC */ + { + t3100e->cga_stat |= 8; + t3100e->dispon = 0; + } + if (t3100e->displine == 416) /* End of VSYNC */ + { + t3100e->displine = 0; + t3100e->cga_stat &= ~8; + t3100e->dispon = 1; + } + } + else + { + if (t3100e->dispon) + { + t3100e->cga_stat &= ~1; + } + t3100e->vidtime += t3100e->dispontime; + t3100e->linepos = 0; + + if (t3100e->displine == 400) + { +/* Hardcode 640x400 window size */ + if (T3100E_XSIZE != xsize || T3100E_YSIZE != ysize) + { + xsize = T3100E_XSIZE; + ysize = T3100E_YSIZE; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + + frames++; + /* Fixed 640x400 resolution */ + video_res_x = T3100E_XSIZE; + video_res_y = T3100E_YSIZE; + + if (t3100e->cga_ctrl & 0x02) + { + if (t3100e->cga_ctrl & 0x10) + video_bpp = 1; + else video_bpp = 2; + + } + else video_bpp = 0; + t3100e->blink++; + } + } +} + +void *t3100e_init() +{ + int n; + t3100e_t *t3100e = malloc(sizeof(t3100e_t)); + memset(t3100e, 0, sizeof(t3100e_t)); + + /* 32k video RAM */ + t3100e->vram = malloc(0x8000); + + timer_add(t3100e_poll, &t3100e->vidtime, TIMER_ALWAYS_ENABLED, t3100e); + + /* Occupy memory between 0xB8000 and 0xBFFFF */ + mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e); + /* Respond to CGA I/O ports */ + io_sethandler(0x03d0, 0x000c, t3100e_in, NULL, NULL, t3100e_out, NULL, NULL, t3100e); + + /* Set up colours */ + amber = makecol(0xf7, 0x7C, 0x34); + black = makecol(0x17, 0x0C, 0x00); + + /* Initialise the attribute mapping. Start by defaulting everything + * to black on amber */ + for (n = 0; n < 256; n++) + { + blinkcols[n][0] = normcols[n][0] = amber; + blinkcols[n][1] = normcols[n][1] = black; + } + /* Except 00-0F and 80-8F which are amber on black */ + for (n = 0; n < 16; n++) + { + blinkcols[n][0] = normcols[n][0] = black; + blinkcols[n][1] = normcols[n][1] = amber; + blinkcols[n+128][0] = normcols[n+128][0] = black; + blinkcols[n+128][1] = normcols[n+128][1] = amber; + } + /* In the normal range, 00 11 22 .. FF are black */ + for (n = 0; n <= 0xFF; n += 0x11) + { + normcols[n][0] = normcols[n][1] = black; + } + /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */ + for (n = 0; n <= 0x77; n += 0x11) + { + blinkcols[n][0] = blinkcols[n][1] = black; + blinkcols[n+128][0] = blinkcols[n+128][1] = black; + } + +/* Start off in 80x25 text mode */ + t3100e->cga_stat = 0xF4; + t3100e->enabled = 1; + t3100e->video_options = 0xFF; + return t3100e; +} + +void t3100e_close(void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + + free(t3100e->vram); + free(t3100e); +} + +void t3100e_speed_changed(void *p) +{ + t3100e_t *t3100e = (t3100e_t *)p; + + t3100e_recalctimings(t3100e); +} + +device_t t3100e_device = +{ + "Toshiba T3100e", + 0, + t3100e_init, + t3100e_close, + NULL, + t3100e_speed_changed, + NULL, + NULL +}; diff --git a/src/vid_t3100e.h b/src/vid_t3100e.h new file mode 100644 index 0000000..107cef6 --- /dev/null +++ b/src/vid_t3100e.h @@ -0,0 +1,3 @@ +extern device_t t3100e_device; + +void t3100e_video_options_set(uint8_t options); diff --git a/src/video.c b/src/video.c index e7567e5..4ac9350 100644 --- a/src/video.c +++ b/src/video.c @@ -41,6 +41,7 @@ #include "vid_tvga.h" #include "vid_vga.h" #include "vid_wy700.h" +#include "vid_t3100e.h" typedef struct { @@ -311,6 +312,10 @@ void video_init() case ROM_IBMPS1_2121: device_add(&ps1_m2121_svga_device); return; + + case ROM_T3100E: + device_add(&t3100e_device); + return; } device_add(video_cards[video_old_to_new(gfxcard)].device); } @@ -319,7 +324,7 @@ void video_init() BITMAP *buffer32; uint8_t fontdat[256][8]; -uint8_t fontdatm[256][16]; +uint8_t fontdatm[512][16]; uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ @@ -329,6 +334,8 @@ void loadfont(char *s, int format) { FILE *f=romfopen(s,"rb"); int c,d; + + pclog("loadfont %i %s %p\n", format, s, f); if (!f) { return; @@ -412,6 +419,15 @@ void loadfont(char *s, int format) } } break; + case 5: /* Toshiba 3100e */ + for (c=0;c<512;c++) + { + for (d=0;d<16;d++) + { + fontdatm[c][d]=getc(f); + } + } + break; } fclose(f); diff --git a/src/video.h b/src/video.h index e3565b6..e301dcb 100644 --- a/src/video.h +++ b/src/video.h @@ -59,7 +59,7 @@ extern int fullchange; extern int changeframecount; extern uint8_t fontdat[256][8]; -extern uint8_t fontdatm[256][16]; +extern uint8_t fontdatm[512][16]; extern uint32_t *video_15to32, *video_16to32; From 3ba03410fd59eb1a6d551cf50bf324e1cf15287d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Oct 2017 21:28:52 +0100 Subject: [PATCH 0173/1050] MMU now handles CPL on read-only pages correctly. Fixes AT&T SVR4 2.1. --- src/mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mem.c b/src/mem.c index 9a5b6b8..50ddcd7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -970,7 +970,7 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3 && !cpl_override) || 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,pc,SS,ESP,ins,CPL,rw); @@ -995,7 +995,7 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) 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 (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || 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,pc,SS,ESP,ins,CPL,rw); From 5f0d43f782004d8cda7ff66d25170d1cacc295a3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Oct 2017 21:29:49 +0100 Subject: [PATCH 0174/1050] Prefetch simulation no longer counts prefixes when prefetch calculation disabled (eg when CPU cache enabled). Fixes hang on reset on 486+ CPUs. --- src/386_dynarec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index b2a74f3..7411ad3 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -388,7 +388,7 @@ static void prefetch_flush() #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) -#define PREFETCH_PREFIX() prefetch_prefixes++ +#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) #define PREFETCH_FLUSH() prefetch_flush() From c71963727a4057c9ed19e2c4b690a229b290322d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Oct 2017 21:32:01 +0100 Subject: [PATCH 0175/1050] Recompiler now uses logical address of 0xffffffff rather than 0 to represent invalid block. Fixes some Unixes when recompiler enabled. --- src/386_dynarec.c | 4 ++-- src/codegen.h | 2 ++ src/codegen_x86-64.c | 24 +++++++++++++++++------- src/codegen_x86.c | 23 ++++++++++++++++------- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 7411ad3..144177e 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -612,7 +612,7 @@ void exec386_dynarec(int cycs) { codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); page->dirty_mask[(phys_addr >> 10) & 3] = 0; - if (!block->pc) + if (block->pc == BLOCK_PC_INVALID) valid_block = 0; } if (valid_block && block->page_mask2) @@ -632,7 +632,7 @@ void exec386_dynarec(int cycs) { 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) + if (block->pc == BLOCK_PC_INVALID) valid_block = 0; } } diff --git a/src/codegen.h b/src/codegen.h index 8eaab36..3a8a955 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -74,6 +74,8 @@ typedef struct codeblock_t /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 +#define BLOCK_PC_INVALID 0xffffffff + static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) { codeblock_t *block = pages[phys >> 12].head; diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index 7220966..0c21a3a 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -61,6 +61,8 @@ static int last_ssegs; void codegen_init() { + int c; + #ifdef __linux__ void *start; size_t len; @@ -78,6 +80,9 @@ void codegen_init() memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; + #ifdef __linux__ start = (void *)((long)codeblock & pagemask); len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; @@ -92,9 +97,14 @@ void codegen_init() void codegen_reset() { + int c; + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); mem_reset_page_blocks(); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; } void dump_block() @@ -136,8 +146,8 @@ static void add_to_block_list(codeblock_t *block) if (block->next) { - if (!block->next->pc) - fatal("block->next->pc=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); + if (block->next->pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); } if (block->page_mask2) @@ -208,9 +218,9 @@ static void delete_block(codeblock_t *block) if (block == codeblock_hash[HASH(block->phys)]) codeblock_hash[HASH(block->phys)] = NULL; - if (!block->pc) + if (block->pc == BLOCK_PC_INVALID) fatal("Deleting deleted block\n"); - block->pc = 0; + block->pc = BLOCK_PC_INVALID; codeblock_tree_delete(block); remove_from_block_list(block, old_pc); @@ -260,7 +270,7 @@ void codegen_block_init(uint32_t phys_addr) // if (block->pc == 0xb00b4ff5) // pclog("Init target block\n"); - if (block->pc != 0) + if (block->pc != BLOCK_PC_INVALID) { // pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); delete_block(block); @@ -453,8 +463,8 @@ void codegen_block_generate_end_mask() 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); + if (block->next_2->pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %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/codegen_x86.c b/src/codegen_x86.c index 14f076e..688a363 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -1123,6 +1123,7 @@ static uint32_t gen_MEM_CHECK_WRITE_L() void codegen_init() { + int c; #ifdef __linux__ void *start; size_t len; @@ -1140,6 +1141,9 @@ void codegen_init() memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; + #ifdef __linux__ start = (void *)((long)codeblock & pagemask); len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; @@ -1205,9 +1209,14 @@ void codegen_init() void codegen_reset() { + int c; + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); mem_reset_page_blocks(); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; } void dump_block() @@ -1249,8 +1258,8 @@ static void add_to_block_list(codeblock_t *block) if (block->next) { - if (!block->next->pc) - fatal("block->next->pc=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); + if (block->next->pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); } if (block->page_mask2) @@ -1321,9 +1330,9 @@ static void delete_block(codeblock_t *block) if (block == codeblock_hash[HASH(block->phys)]) codeblock_hash[HASH(block->phys)] = NULL; - if (!block->pc) + if (block->pc == BLOCK_PC_INVALID) fatal("Deleting deleted block\n"); - block->pc = 0; + block->pc = BLOCK_PC_INVALID; codeblock_tree_delete(block); remove_from_block_list(block, old_pc); @@ -1373,7 +1382,7 @@ void codegen_block_init(uint32_t phys_addr) // if (block->pc == 0xb00b4ff5) // pclog("Init target block\n"); - if (block->pc != 0) + if (block->pc != BLOCK_PC_INVALID) { // pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); delete_block(block); @@ -1540,8 +1549,8 @@ void codegen_block_generate_end_mask() 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); + if (block->next_2->pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)block->next_2); } block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; From 8b4ab935d24d01779b507ff20cd64d175f50d799 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 16 Oct 2017 19:42:31 +0100 Subject: [PATCH 0176/1050] SCAT fixes. Patch from Greatpsycho. --- src/scat.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/scat.c b/src/scat.c index 0c0c74e..84aa492 100644 --- a/src/scat.c +++ b/src/scat.c @@ -336,7 +336,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case SCATSX_FAST_VIDEORAM_ENABLE: case SCATSX_HIGH_PERFORMANCE_REFRESH: case SCATSX_CAS_TIMING_FOR_DMA: - if((scat_regs[SCAT_VERSION] & 0xF0) == 0) scat_reg_valid = 1; + if((scat_regs[SCAT_VERSION] & 0xF0) != 0) scat_reg_valid = 1; break; default: break; @@ -583,7 +583,6 @@ void scatsx_init() int i; io_sethandler(0x0022, 0x0002, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); - io_sethandler(0x0080, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, scat_read, NULL, NULL, scat_write, NULL, NULL, NULL); for (i = 0; i < 256; i++) From 9a2f5418985a13446f42687257b907a589c6426a Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 17 Oct 2017 20:38:45 +0100 Subject: [PATCH 0177/1050] Corrected T3100e font ROM loading. Patch from John Elliott. --- src/video.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/video.c b/src/video.c index 4ac9350..784b155 100644 --- a/src/video.c +++ b/src/video.c @@ -420,14 +420,23 @@ void loadfont(char *s, int format) } break; case 5: /* Toshiba 3100e */ - for (c=0;c<512;c++) + for (c=0;c<256;c++) { - for (d=0;d<16;d++) - { - fontdatm[c][d]=getc(f); - } + fread(&fontdatm[c][8], 1, 8, f); } - break; + for (c=0;c<256;c++) + { + fread(&fontdatm[c+256][8], 1, 8, f); + } + for (c=0;c<256;c++) + { + fread(&fontdatm[c][0], 1, 8, f); + } + for (c=0;c<256;c++) + { + fread(&fontdatm[c+256][0], 1, 8, f); + } + break; } fclose(f); From 1e75653c5c075502fbf801bed8f0b569d9e34e20 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 17 Oct 2017 21:39:37 +0100 Subject: [PATCH 0178/1050] Fixed CMS/Game Blaster detection. --- src/sound_cms.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/sound_cms.c b/src/sound_cms.c index 6361dd9..dd2fa27 100644 --- a/src/sound_cms.c +++ b/src/sound_cms.c @@ -22,6 +22,8 @@ typedef struct cms_t uint16_t noisefreq[2][2]; int noisecount[2][2]; int noisetype[2][2]; + + uint8_t latched_data; int16_t buffer[MAXSOUNDBUFLEN * 2]; @@ -106,12 +108,18 @@ void cms_write(uint16_t addr, uint8_t val, void *p) int voice; int chip = (addr & 2) >> 1; - pclog("cms_write : addr %04X val %02X\n", addr, val); +// pclog("cms_write : addr %04X val %02X\n", addr, val); - if (addr & 1) - cms->addrs[chip] = val & 31; - else + switch (addr & 0xf) { + case 1: + cms->addrs[0] = val & 31; + break; + case 3: + cms->addrs[1] = val & 31; + break; + + case 0: case 2: cms_update(cms); cms->regs[chip][cms->addrs[chip] & 31] = val; switch (cms->addrs[chip] & 31) @@ -140,18 +148,30 @@ void cms_write(uint16_t addr, uint8_t val, void *p) cms->noisetype[chip][1] = (val >> 4) & 3; break; } + break; + case 0x6: case 0x7: + cms->latched_data = val; + break; } } uint8_t cms_read(uint16_t addr, void *p) { cms_t *cms = (cms_t *)p; - int chip = (addr & 2) >> 1; - if (addr & 1) - return cms->addrs[chip]; - - return cms->regs[chip][cms->addrs[chip] & 31]; +// pclog("cms_read : addr %04X\n", addr); + switch (addr & 0xf) + { + case 0x1: + return cms->addrs[0]; + case 0x3: + return cms->addrs[1]; + case 0x4: + return 0x7f; + case 0xa: case 0xb: + return cms->latched_data; + } + return 0xff; } void *cms_init() @@ -160,7 +180,7 @@ void *cms_init() memset(cms, 0, sizeof(cms_t)); pclog("cms_init\n"); - io_sethandler(0x0220, 0x0004, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); + io_sethandler(0x0220, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); sound_add_handler(cms_get_buffer, cms); return cms; } From 6b7682105bad8a32c240c3b19fe52dde5080f20f Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Oct 2017 20:03:56 +0100 Subject: [PATCH 0179/1050] Corrected read of SB Pro mixer registers on SB16. Fixes sound in One Must Fall, Jazz Jackrabbit and probably other games. --- src/sound_sb.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index 945ed5f..3cee369 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -768,8 +768,22 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) } switch (mixer->index) { - case 0x00: case 0x04: case 0x0A: case 0x22: case 0x26: case 0x28: case 0x2E: + case 0x00: return mixer->regs[mixer->index]; + + /*SB Pro compatibility*/ + case 0x04: + return ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); + case 0x0a: + return (mixer->regs[0x2a] - 10) / 3; + case 0x22: + return ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); + case 0x26: + return ((mixer->regs[0x35] >> 4) & 0x0f) | (mixer->regs[0x34] & 0xf0); + case 0x28: + return ((mixer->regs[0x37] >> 4) & 0x0f) | (mixer->regs[0x36] & 0xf0); + case 0x2e: + return ((mixer->regs[0x39] >> 4) & 0x0f) | (mixer->regs[0x38] & 0xf0); case 0x48: // Undocumented. The Creative Windows Mixer calls this after calling 3C (input selector). even when writing. From 0dfc69af243ca664cf21202caad40807c429473d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Oct 2017 20:16:24 +0100 Subject: [PATCH 0180/1050] When loading config file specified on the command line, use the correct CMOS RAM files. --- src/pc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/pc.c b/src/pc.c index 76e452a..0afa2da 100644 --- a/src/pc.c +++ b/src/pc.c @@ -250,9 +250,22 @@ void initpc(int argc, char *argv[]) } else if (!strcasecmp(argv[c], "--config")) { + int d; + if ((c+1) == argc) break; strncpy(config_file_default, argv[c+1], 256); + strcpy(config_name, get_filename(config_file_default)); + + for (d = 0; d < strlen(config_name); d++) + { + if (config_name[d] == '.') + { + config_name[d] = 0; + break; + } + } + config_override = 1; c++; } From f4fe56edb280dbd1518166b23ae96ba1ea52f6a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Oct 2017 21:01:11 +0100 Subject: [PATCH 0181/1050] Reworked TGUI code to avoid altering memory mappings outside of main thread. --- src/vid_tgui9440.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 06c6d4e..426f116 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -94,6 +94,8 @@ typedef struct tgui_t int blitter_busy; uint64_t blitter_time; uint64_t status_time; + + volatile int write_blitter; } tgui_t; void tgui_recalcmapping(tgui_t *tgui); @@ -108,7 +110,8 @@ void tgui_accel_write(uint32_t addr, uint8_t val, void *priv); void tgui_accel_write_w(uint32_t addr, uint16_t val, void *priv); void tgui_accel_write_l(uint32_t addr, uint32_t val, void *priv); - +void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); +void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); void tgui_out(uint16_t addr, uint8_t val, void *p) @@ -525,7 +528,7 @@ void *tgui9440_init() tgui_hwcursor_draw, NULL); - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &tgui->svga); + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); mem_mapping_disable(&tgui->accel_mapping); @@ -616,9 +619,6 @@ enum svga->changedvram[((addr) & 0xfffff) >> 11] = changeframecount; \ } -void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); -void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); - void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { svga_t *svga = &tgui->svga; @@ -714,8 +714,9 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { // 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); - + { + tgui->write_blitter = 1; + } if (tgui->accel.use_src) return; } @@ -767,8 +768,7 @@ 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); + tgui->write_blitter = 0; } return; } @@ -784,7 +784,9 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { // 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); + { + tgui->write_blitter = 1; + } // pclog(" %i\n", tgui->accel.command); if (tgui->accel.use_src) @@ -828,8 +830,7 @@ 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); + tgui->write_blitter = 0; } return; } @@ -1245,24 +1246,33 @@ 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); + + if (tgui->write_blitter) + tgui_queue(tgui, addr, val, FIFO_WRITE_FB_BYTE); + else + svga_write_linear(addr, val, svga); } void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *)p; tgui_t *tgui = (tgui_t *)svga->p; -// pclog("tgui_accel_write_fb_w %08X %04X\n", addr, val); - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD); + + if (tgui->write_blitter) + tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD); + else + svga_writew_linear(addr, val, svga); } void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *)p; tgui_t *tgui = (tgui_t *)svga->p; -// pclog("tgui_accel_write_fb_l %08X %08X\n", addr, val); - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG); + + if (tgui->write_blitter) + tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG); + else + svga_writel_linear(addr, val, svga); } void tgui_add_status_info(char *s, int max_len, void *p) From 0d5d7ac005de1a3b270148a2cb0da8ac94936260 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Oct 2017 21:19:18 +0100 Subject: [PATCH 0182/1050] Removed Allegro port. --- Makefile.in | 6 +- aclocal.m4 | 1 - allegro.m4 | 192 -------- configure | 335 +------------ configure.ac | 65 +-- src/Makefile.am | 10 - src/Makefile.in | 516 +++++++------------- src/Makefile.linux32 | 47 -- src/Makefile.linux64 | 46 -- src/allegro-gui-config-sel.c | 266 ----------- src/allegro-gui-configure.c | 837 --------------------------------- src/allegro-gui-deviceconfig.c | 303 ------------ src/allegro-gui-hdconf.c | 537 --------------------- src/allegro-gui.c | 288 ------------ src/allegro-gui.h | 15 - src/allegro-joystick.c | 49 -- src/allegro-keyboard.c | 49 -- src/allegro-main.c | 280 ----------- src/allegro-main.h | 19 - src/allegro-midi.c | 45 -- src/allegro-mouse.c | 32 -- src/allegro-video.c | 53 --- src/allegro-video.h | 3 - src/pc.c | 1 - src/video.h | 10 - 25 files changed, 214 insertions(+), 3791 deletions(-) delete mode 100644 allegro.m4 delete mode 100644 src/Makefile.linux32 delete mode 100644 src/Makefile.linux64 delete mode 100644 src/allegro-gui-config-sel.c 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 diff --git a/Makefile.in b/Makefile.in index d83741a..903d123 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,8 +89,7 @@ build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/allegro.m4 \ - $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ @@ -202,7 +201,6 @@ am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ -ALLEGRO_CONFIG = @ALLEGRO_CONFIG@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ @@ -273,8 +271,6 @@ 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@ diff --git a/aclocal.m4 b/aclocal.m4 index 53df7ec..925cb54 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -2721,4 +2721,3 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR -m4_include([allegro.m4]) diff --git a/allegro.m4 b/allegro.m4 deleted file mode 100644 index 364cbac..0000000 --- a/allegro.m4 +++ /dev/null @@ -1,192 +0,0 @@ -# Configure paths for Allegro -# Shamelessly stolen from libxml.a4 -# Jon Rafkind 2004-06-06 -# Adapted from: -# Configure paths for libXML -# Toshio Kuratomi 2001-04-21 -# Adapted from: -# Configure paths for GLIB -# Owen Taylor 97-11-3 - -dnl AM_PATH_allegro([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for allegro, and define allegro_CFLAGS and allegro_LIBS -dnl -AC_DEFUN([AM_PATH_ALLEGRO],[ -AC_ARG_WITH(allegro-prefix, - [ --with-allegro-prefix=PFX Prefix where liballegro is installed (optional)], - ALLEGRO_CONFIG_prefix="$withval", ALLEGRO_CONFIG_prefix="") -AC_ARG_WITH(allegro-exec-prefix, - [ --with-allegro-exec-prefix=PFX Exec prefix where liballegro is installed (optional)], - ALLEGRO_CONFIG_exec_prefix="$withval", ALLEGRO_CONFIG_exec_prefix="") -AC_ARG_ENABLE(allegrotest, - [ --disable-allegrotest Do not try to compile and run a test LIBallegro program],, - enable_allegrotest=yes) - - if test x$ALLEGRO_CONFIG_exec_prefix != x ; then - ALLEGRO_CONFIG_args="$ALLEGRO_CONFIG_args --exec-prefix=$ALLEGRO_CONFIG_exec_prefix" - if test x${ALLEGRO_CONFIG+set} != xset ; then - ALLEGRO_CONFIG=$ALLEGRO_CONFIG_exec_prefix/bin/allegro-config - fi - fi - if test x$ALLEGRO_CONFIG_prefix != x ; then - ALLEGRO_CONFIG_args="$ALLEGRO_CONFIG_args --prefix=$ALLEGRO_CONFIG_prefix" - if test x${ALLEGRO_CONFIG+set} != xset ; then - ALLEGRO_CONFIG=$ALLEGRO_CONFIG_prefix/bin/allegro-config - fi - fi - - AC_PATH_PROG(ALLEGRO_CONFIG, allegro-config, no) - min_allegro_version=ifelse([$1], ,4.0.0,[$1]) - AC_MSG_CHECKING(for Allegro - version >= $min_allegro_version) - no_allegro="" - if test "$ALLEGRO_CONFIG" = "no" ; then - no_allegro=yes - else - allegro_CFLAGS=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --cflags` - allegro_LIBS=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --libs` - ALLEGRO_CONFIG_major_version=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - ALLEGRO_CONFIG_minor_version=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - ALLEGRO_CONFIG_micro_version=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_allegrotest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $allegro_CFLAGS" - LIBS="$allegro_LIBS $LIBS" -dnl -dnl Now check if the installed liballegro is sufficiently new. -dnl (Also sanity checks the results of allegro-config to some extent) -dnl - rm -f conf.allegrotest - AC_TRY_RUN([ -#include -#include -#include -#include - -int -main() -{ - int allegro_major_version, allegro_minor_version, allegro_micro_version; - int major, minor, micro; - char *tmp_version; - int tmp_int_version; - - system("touch conf.allegrotest"); - - /* Capture allegro-config output via autoconf/configure variables */ - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = (char *)strdup("$min_allegro_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string from allegro-config\n", "$min_allegro_version"); - free(tmp_version); - exit(1); - } - free(tmp_version); - - /* Capture the version information from the header files */ - allegro_major_version = ALLEGRO_VERSION; - allegro_minor_version = ALLEGRO_SUB_VERSION; - allegro_micro_version = ALLEGRO_WIP_VERSION; - - /* Compare allegro-config output to the Allegro headers */ - if ((allegro_major_version != $ALLEGRO_CONFIG_major_version) || - (allegro_minor_version != $ALLEGRO_CONFIG_minor_version)) - - { - printf("*** Allegro header files (version %d.%d.%d) do not match\n", - allegro_major_version, allegro_minor_version, allegro_micro_version); - printf("*** allegro-config (version %d.%d.%d)\n", - $ALLEGRO_CONFIG_major_version, $ALLEGRO_CONFIG_minor_version, $ALLEGRO_CONFIG_micro_version); - return 1; - } -/* Compare the headers to the library to make sure we match */ - /* Less than ideal -- doesn't provide us with return value feedback, - * only exits if there's a serious mismatch between header and library. - */ - /* TODO: - * This doesnt work! - */ - /* ALLEGRO_TEST_VERSION; */ - - /* Test that the library is greater than our minimum version */ - if (($ALLEGRO_CONFIG_major_version > major) || - (($ALLEGRO_CONFIG_major_version == major) && ($ALLEGRO_CONFIG_minor_version > minor)) || - (($ALLEGRO_CONFIG_major_version == major) && ($ALLEGRO_CONFIG_minor_version == minor) && - ($ALLEGRO_CONFIG_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** An old version of Allegro (%d.%d.%d) was found.\n", - allegro_major_version, allegro_minor_version, allegro_micro_version); - printf("*** You need a version of Allegro newer than %d.%d.%d. The latest version of\n", - major, minor, micro); - printf("*** Allegro is always available from http://alleg.sf.net.\n"); - printf("***\n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the allegro-config shell script is\n"); - printf("*** being found. The easiest way to fix this is to remove the old version\n"); - printf("*** of Allegro, but you can also set the ALLEGRO_CONFIG environment to point to the\n"); - printf("*** correct copy of allegro-config. (In this case, you will have to\n"); - printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); - printf("*** so that the correct libraries are found at run-time))\n"); - } - return 1; -} END_OF_MAIN() -],, no_allegro=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - - if test "x$no_allegro" = x ; then - AC_MSG_RESULT(yes (version $ALLEGRO_CONFIG_major_version.$ALLEGRO_CONFIG_minor_version.$ALLEGRO_CONFIG_micro_version)) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$ALLEGRO_CONFIG" = "no" ; then - echo "*** The allegro-config script installed by Allegro could not be found" - echo "*** If Allegro was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the ALLEGRO_CONFIG environment variable to the" - echo "*** full path to allegro-config." - else - if test -f conf.allegrotest ; then - : - else - echo "*** Could not run Allegro test program, checking why..." - CFLAGS="$CFLAGS $allegro_CFLAGS" - LIBS="$LIBS $allegro_LIBS" - AC_TRY_LINK([ -#include -#include -], [ allegro_error; return 0;], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding Allegro or finding the wrong" - echo "*** version of Allegro. If it is not finding Allegro, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means Allegro was incorrectly installed" - echo "*** or that you have moved Allegro since it was installed. In the latter case, you" - echo "*** may want to edit the allegro-config script: $ALLEGRO_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - - allegro_CFLAGS="" - allegro_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(allegro_CFLAGS) - AC_SUBST(allegro_LIBS) - rm -f conf.allegrotest -]) diff --git a/configure b/configure index b5acc65..375d8c7 100755 --- a/configure +++ b/configure @@ -608,9 +608,6 @@ PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG SDL2_FRAMEWORK -allegro_LIBS -allegro_CFLAGS -ALLEGRO_CONFIG USE_ALSA_FALSE USE_ALSA_TRUE USE_NETWORKING_FALSE @@ -728,12 +725,8 @@ enable_option_checking enable_silent_rules enable_dependency_tracking enable_debug -enable_wx enable_networking enable_alsa -with_allegro_prefix -with_allegro_exec_prefix -enable_allegrotest with_sdl_prefix with_sdl_exec_prefix enable_sdltest @@ -1396,18 +1389,14 @@ Optional Features: --disable-dependency-tracking speeds up one-time build --enable-debug build debug executable - --enable-wx use wxWidgets GUI --enable-networking enable networking --enable-alsa use ALSA for MIDI - --disable-allegrotest Do not try to compile and run a test LIBallegro program --disable-sdltest Do not try to compile and run a test SDL program --disable-sdlframework Do not search for SDL2.framework Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-allegro-prefix=PFX Prefix where liballegro is installed (optional) - --with-allegro-exec-prefix=PFX Exec prefix where liballegro is installed (optional) --with-sdl-prefix=PFX Prefix where SDL is installed (optional) --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) --with-wxdir=PATH Use uninstalled version of wxWidgets in PATH @@ -4157,21 +4146,6 @@ else $as_echo "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use the wxWidgets-based GUI" >&5 -$as_echo_n "checking whether to use the wxWidgets-based GUI... " >&6; } -# Check whether --enable-wx was given. -if test "${enable_wx+set}" = set; then : - enableval=$enable_wx; -fi - -if test "$enable_wx" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable networking" >&5 $as_echo_n "checking whether to enable networking... " >&6; } # Check whether --enable-networking was given. @@ -4282,280 +4256,7 @@ else fi -if test "$enable_wx" != "yes"; then - # Do not run test for Allegro with Win32/MinGW version, as binary builds have - # `allegro-config' missing. - # NOTE: For the following Autoconf macro to be supported, you need to extract - # allegro.m4 from the DOS/Windows Allegro sources (the file is contained - # in `misc') and copy it to this directory or MSYS's `/share/aclocal'. - if test "$OS" != "win"; then - - - - -# Check whether --with-allegro-prefix was given. -if test "${with_allegro_prefix+set}" = set; then : - withval=$with_allegro_prefix; ALLEGRO_CONFIG_prefix="$withval" -else - ALLEGRO_CONFIG_prefix="" -fi - - -# Check whether --with-allegro-exec-prefix was given. -if test "${with_allegro_exec_prefix+set}" = set; then : - withval=$with_allegro_exec_prefix; ALLEGRO_CONFIG_exec_prefix="$withval" -else - ALLEGRO_CONFIG_exec_prefix="" -fi - -# Check whether --enable-allegrotest was given. -if test "${enable_allegrotest+set}" = set; then : - enableval=$enable_allegrotest; -else - enable_allegrotest=yes -fi - - - if test x$ALLEGRO_CONFIG_exec_prefix != x ; then - ALLEGRO_CONFIG_args="$ALLEGRO_CONFIG_args --exec-prefix=$ALLEGRO_CONFIG_exec_prefix" - if test x${ALLEGRO_CONFIG+set} != xset ; then - ALLEGRO_CONFIG=$ALLEGRO_CONFIG_exec_prefix/bin/allegro-config - fi - fi - if test x$ALLEGRO_CONFIG_prefix != x ; then - ALLEGRO_CONFIG_args="$ALLEGRO_CONFIG_args --prefix=$ALLEGRO_CONFIG_prefix" - if test x${ALLEGRO_CONFIG+set} != xset ; then - ALLEGRO_CONFIG=$ALLEGRO_CONFIG_prefix/bin/allegro-config - fi - fi - - # Extract the first word of "allegro-config", so it can be a program name with args. -set dummy allegro-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ALLEGRO_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ALLEGRO_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ALLEGRO_CONFIG="$ALLEGRO_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ALLEGRO_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_ALLEGRO_CONFIG" && ac_cv_path_ALLEGRO_CONFIG="no" - ;; -esac -fi -ALLEGRO_CONFIG=$ac_cv_path_ALLEGRO_CONFIG -if test -n "$ALLEGRO_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ALLEGRO_CONFIG" >&5 -$as_echo "$ALLEGRO_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - min_allegro_version=4.0.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Allegro - version >= $min_allegro_version" >&5 -$as_echo_n "checking for Allegro - version >= $min_allegro_version... " >&6; } - no_allegro="" - if test "$ALLEGRO_CONFIG" = "no" ; then - no_allegro=yes - else - allegro_CFLAGS=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --cflags` - allegro_LIBS=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --libs` - ALLEGRO_CONFIG_major_version=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --version | \ - sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` - ALLEGRO_CONFIG_minor_version=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --version | \ - sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` - ALLEGRO_CONFIG_micro_version=`$ALLEGRO_CONFIG $ALLEGRO_CONFIG_args --version | \ - sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` - if test "x$enable_allegrotest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $allegro_CFLAGS" - LIBS="$allegro_LIBS $LIBS" - rm -f conf.allegrotest - if test "$cross_compiling" = yes; then : - echo $ac_n "cross compiling; assumed OK... $ac_c" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include - -int -main() -{ - int allegro_major_version, allegro_minor_version, allegro_micro_version; - int major, minor, micro; - char *tmp_version; - int tmp_int_version; - - system("touch conf.allegrotest"); - - /* Capture allegro-config output via autoconf/configure variables */ - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = (char *)strdup("$min_allegro_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string from allegro-config\n", "$min_allegro_version"); - free(tmp_version); - exit(1); - } - free(tmp_version); - - /* Capture the version information from the header files */ - allegro_major_version = ALLEGRO_VERSION; - allegro_minor_version = ALLEGRO_SUB_VERSION; - allegro_micro_version = ALLEGRO_WIP_VERSION; - - /* Compare allegro-config output to the Allegro headers */ - if ((allegro_major_version != $ALLEGRO_CONFIG_major_version) || - (allegro_minor_version != $ALLEGRO_CONFIG_minor_version)) - - { - printf("*** Allegro header files (version %d.%d.%d) do not match\n", - allegro_major_version, allegro_minor_version, allegro_micro_version); - printf("*** allegro-config (version %d.%d.%d)\n", - $ALLEGRO_CONFIG_major_version, $ALLEGRO_CONFIG_minor_version, $ALLEGRO_CONFIG_micro_version); - return 1; - } -/* Compare the headers to the library to make sure we match */ - /* Less than ideal -- doesn't provide us with return value feedback, - * only exits if there's a serious mismatch between header and library. - */ - /* TODO: - * This doesnt work! - */ - /* ALLEGRO_TEST_VERSION; */ - - /* Test that the library is greater than our minimum version */ - if (($ALLEGRO_CONFIG_major_version > major) || - (($ALLEGRO_CONFIG_major_version == major) && ($ALLEGRO_CONFIG_minor_version > minor)) || - (($ALLEGRO_CONFIG_major_version == major) && ($ALLEGRO_CONFIG_minor_version == minor) && - ($ALLEGRO_CONFIG_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** An old version of Allegro (%d.%d.%d) was found.\n", - allegro_major_version, allegro_minor_version, allegro_micro_version); - printf("*** You need a version of Allegro newer than %d.%d.%d. The latest version of\n", - major, minor, micro); - printf("*** Allegro is always available from http://alleg.sf.net.\n"); - printf("***\n"); - printf("*** If you have already installed a sufficiently new version, this error\n"); - printf("*** probably means that the wrong copy of the allegro-config shell script is\n"); - printf("*** being found. The easiest way to fix this is to remove the old version\n"); - printf("*** of Allegro, but you can also set the ALLEGRO_CONFIG environment to point to the\n"); - printf("*** correct copy of allegro-config. (In this case, you will have to\n"); - printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); - printf("*** so that the correct libraries are found at run-time))\n"); - } - return 1; -} END_OF_MAIN() - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - no_allegro=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - - if test "x$no_allegro" = x ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $ALLEGRO_CONFIG_major_version.$ALLEGRO_CONFIG_minor_version.$ALLEGRO_CONFIG_micro_version)" >&5 -$as_echo "yes (version $ALLEGRO_CONFIG_major_version.$ALLEGRO_CONFIG_minor_version.$ALLEGRO_CONFIG_micro_version)" >&6; } - : - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - if test "$ALLEGRO_CONFIG" = "no" ; then - echo "*** The allegro-config script installed by Allegro could not be found" - echo "*** If Allegro was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the ALLEGRO_CONFIG environment variable to the" - echo "*** full path to allegro-config." - else - if test -f conf.allegrotest ; then - : - else - echo "*** Could not run Allegro test program, checking why..." - CFLAGS="$CFLAGS $allegro_CFLAGS" - LIBS="$LIBS $allegro_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ - allegro_error; return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding Allegro or finding the wrong" - echo "*** version of Allegro. If it is not finding Allegro, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" -else - echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means Allegro was incorrectly installed" - echo "*** or that you have moved Allegro since it was installed. In the latter case, you" - echo "*** may want to edit the allegro-config script: $ALLEGRO_CONFIG" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CFLAGS="$ac_save_CFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - - allegro_CFLAGS="" - allegro_LIBS="" - as_fn_error $? "building PCem requires Allegro to be installed" "$LINENO" 5 - fi - - - rm -f conf.allegrotest - - fi -else - SDL_VERSION=2.0.1 +SDL_VERSION=2.0.1 @@ -4677,6 +4378,7 @@ $as_echo "no" >&6; } fi fi + # Check whether --with-sdl-prefix was given. if test "${with_sdl_prefix+set}" = set; then : withval=$with_sdl_prefix; sdl_prefix="$withval" @@ -5055,6 +4757,7 @@ rm -f core conftest.err conftest.$ac_objext \ + # Check whether --with-wxdir was given. if test "${with_wxdir+set}" = set; then : withval=$with_wxdir; wx_config_name="$withval/wx-config" @@ -5084,7 +4787,7 @@ else fi - reqwx=3.0.0 +reqwx=3.0.0 if test x${WX_CONFIG_NAME+set} != xset ; then @@ -5350,18 +5053,19 @@ $as_echo "no (version $WX_VERSION is not new enough)" >&6; } - if test "$wxWin" != 1; then - as_fn_error $? " - wxWidgets must be installed on your system. +if test "$wxWin" != 1; then + as_fn_error $? " + wxWidgets must be installed on your system. - Please check that wx-config is in path, the directory - where wxWidgets libraries are installed (returned by - 'wx-config --libs' or 'wx-config --static --libs' command) - is in LD_LIBRARY_PATH or equivalent variable and - wxWidgets version is $reqwx or above. - " "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 + Please check that wx-config is in path, the directory + where wxWidgets libraries are installed (returned by + 'wx-config --libs' or 'wx-config --static --libs' command) + is in LD_LIBRARY_PATH or equivalent variable and + wxWidgets version is $reqwx or above. + " "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 $as_echo_n "checking for glGetError in -lGL... " >&6; } if ${ac_cv_lib_GL_glGetError+:} false; then : $as_echo_n "(cached) " >&6 @@ -5406,12 +5110,11 @@ _ACEOF else \ - echo "You need to install the OpenGL library." - exit -1 + echo "You need to install the OpenGL library." + exit -1 fi - LIBS="$LIBS $WX_LIBS $SDL_LIBS" -fi +LIBS="$LIBS $WX_LIBS $SDL_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 $as_echo_n "checking for alGetError in -lopenal... " >&6; } diff --git a/configure.ac b/configure.ac index 93b22a6..b7b3422 100644 --- a/configure.ac +++ b/configure.ac @@ -24,15 +24,6 @@ else AC_MSG_RESULT([no]) fi -AC_MSG_CHECKING([whether to use the wxWidgets-based GUI]) -AC_ARG_ENABLE(wx, - AC_HELP_STRING([--enable-wx], [use wxWidgets GUI])) -if test "$enable_wx" = "yes"; then - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - AC_MSG_CHECKING([whether to enable networking]) AC_ARG_ENABLE(networking, AC_HELP_STRING([--enable-networking], [enable networking])) @@ -79,42 +70,32 @@ AM_CONDITIONAL(USE_WX, test "$enable_wx" = "yes") AM_CONDITIONAL(USE_NETWORKING, test "$enable_networking" = "yes") AM_CONDITIONAL(USE_ALSA, test "$enable_alsa" = "yes") -if test "$enable_wx" != "yes"; then - # Do not run test for Allegro with Win32/MinGW version, as binary builds have - # `allegro-config' missing. - # NOTE: For the following Autoconf macro to be supported, you need to extract - # allegro.m4 from the DOS/Windows Allegro sources (the file is contained - # in `misc') and copy it to this directory or MSYS's `/share/aclocal'. - if test "$OS" != "win"; then - AC_CONFIG_MACRO_DIR([./]) - AM_PATH_ALLEGRO(, , AC_MSG_ERROR(building PCem requires Allegro to be installed)) - fi -else - SDL_VERSION=2.0.1 - AM_PATH_SDL2($SDL_VERSION, - :, - AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) - ) - AM_OPTIONS_WXCONFIG - reqwx=3.0.0 - AM_PATH_WXCONFIG($reqwx, wxWin=1) - if test "$wxWin" != 1; then - AC_MSG_ERROR([ - wxWidgets must be installed on your system. +SDL_VERSION=2.0.1 +AM_PATH_SDL2($SDL_VERSION, + :, + AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) +) + +AM_OPTIONS_WXCONFIG +reqwx=3.0.0 +AM_PATH_WXCONFIG($reqwx, wxWin=1) +if test "$wxWin" != 1; then + AC_MSG_ERROR([ + wxWidgets must be installed on your system. - Please check that wx-config is in path, the directory - where wxWidgets libraries are installed (returned by - 'wx-config --libs' or 'wx-config --static --libs' command) - is in LD_LIBRARY_PATH or equivalent variable and - wxWidgets version is $reqwx or above. - ]) - fi - AC_CHECK_LIB([GL], [glGetError], [], \ - [echo "You need to install the OpenGL library." - exit -1]) - LIBS="$LIBS $WX_LIBS $SDL_LIBS" + Please check that wx-config is in path, the directory + where wxWidgets libraries are installed (returned by + 'wx-config --libs' or 'wx-config --static --libs' command) + is in LD_LIBRARY_PATH or equivalent variable and + wxWidgets version is $reqwx or above. + ]) fi +AC_CHECK_LIB([GL], [glGetError], [], \ + [echo "You need to install the OpenGL library." + exit -1]) +LIBS="$LIBS $WX_LIBS $SDL_LIBS" + AC_CHECK_LIB([openal], [alGetError], [], \ [echo "You need to install the OpenAL library." exit -1]) diff --git a/src/Makefile.am b/src/Makefile.am index ddd8cc9..59e544c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,7 +38,6 @@ 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 USE_WX pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) pcem_LDADD = @LIBS@ @@ -53,15 +52,6 @@ pcem_SOURCES += midi_alsa.c else pcem_SOURCES += wx-sdl2-midi.c endif -else -pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO -pcem_CXXFLAGS = -pcem_LDADD = $(allegro_LIBS) -lopenal -pcem_SOURCES += allegro-gui.c allegro-gui-config-sel.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 \ - thread-pthread.c -endif if CPU_I386 pcem_SOURCES += codegen_x86.c diff --git a/src/Makefile.in b/src/Makefile.in index 89d0d0a..3d6303b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -92,31 +92,19 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcem$(EXEEXT) -@USE_WX_TRUE@am__append_1 = wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ -@USE_WX_TRUE@ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c \ -@USE_WX_TRUE@ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ -@USE_WX_TRUE@ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ -@USE_WX_TRUE@ wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc - -@USE_ALSA_TRUE@@USE_WX_TRUE@am__append_2 = -lasound -@USE_ALSA_TRUE@@USE_WX_TRUE@am__append_3 = midi_alsa.c -@USE_ALSA_FALSE@@USE_WX_TRUE@am__append_4 = wx-sdl2-midi.c -@USE_WX_FALSE@am__append_5 = allegro-gui.c allegro-gui-config-sel.c allegro-gui-configure.c \ -@USE_WX_FALSE@ allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c \ -@USE_WX_FALSE@ allegro-keyboard.c allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ -@USE_WX_FALSE@ thread-pthread.c - -@CPU_I386_TRUE@am__append_6 = codegen_x86.c -@CPU_I386_TRUE@am__append_7 = -msse2 -@CPU_X86_64_TRUE@am__append_8 = codegen_x86-64.c -@USE_NETWORKING_TRUE@am__append_9 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_10 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_11 = ne2000.c nethandler.c wx-hostconfig.c -@USE_NETWORKING_TRUE@am__append_12 = slirp/libslirp.a +@USE_ALSA_TRUE@am__append_1 = -lasound +@USE_ALSA_TRUE@am__append_2 = midi_alsa.c +@USE_ALSA_FALSE@am__append_3 = wx-sdl2-midi.c +@CPU_I386_TRUE@am__append_4 = codegen_x86.c +@CPU_I386_TRUE@am__append_5 = -msse2 +@CPU_X86_64_TRUE@am__append_6 = codegen_x86-64.c +@USE_NETWORKING_TRUE@am__append_7 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_8 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_9 = ne2000.c nethandler.c wx-hostconfig.c +@USE_NETWORKING_TRUE@am__append_10 = slirp/libslirp.a subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/allegro.m4 \ - $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) @@ -145,84 +133,46 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c \ scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ serial.c sio.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 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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ - vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ - vid_incolor.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_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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ - wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ - wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ - wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c \ - wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ - wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ - midi_alsa.c wx-sdl2-midi.c allegro-gui.c \ - allegro-gui-config-sel.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 \ - thread-pthread.c codegen_x86.c codegen_x86-64.c ne2000.c \ + sound_adlibgold.c sound_audiopci.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 \ + t3100e.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_colorplus.c \ + vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ + vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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_t3100e.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 vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ + wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ + wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ + wx-status.cc wx-sdl2-status.c wx-resources.cpp wx-thread.c \ + wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c \ + wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ + wx-shaderconfig.cc wx-joystickconfig.cc midi_alsa.c \ + wx-sdl2-midi.c codegen_x86.c codegen_x86-64.c ne2000.c \ nethandler.c wx-hostconfig.c -@USE_WX_TRUE@am__objects_1 = pcem-wx-main.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-config_sel.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-dialogbox.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-utils.$(OBJEXT) pcem-wx-app.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-joystick.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-mouse.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-keyboard.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-video.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2.$(OBJEXT) pcem-wx-config.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-deviceconfig.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-status.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-status.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-resources.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-thread.$(OBJEXT) pcem-wx-common.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-video-renderer.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-sdl2-video-gl3.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-glslp-parser.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-shader_man.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-shaderconfig.$(OBJEXT) \ -@USE_WX_TRUE@ pcem-wx-joystickconfig.$(OBJEXT) -@USE_ALSA_TRUE@@USE_WX_TRUE@am__objects_2 = pcem-midi_alsa.$(OBJEXT) -@USE_ALSA_FALSE@@USE_WX_TRUE@am__objects_3 = \ -@USE_ALSA_FALSE@@USE_WX_TRUE@ pcem-wx-sdl2-midi.$(OBJEXT) -@USE_WX_FALSE@am__objects_4 = pcem-allegro-gui.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-gui-config-sel.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-gui-configure.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-gui-deviceconfig.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-gui-hdconf.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-joystick.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-keyboard.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-main.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-midi.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-mouse.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-allegro-video.$(OBJEXT) \ -@USE_WX_FALSE@ pcem-thread-pthread.$(OBJEXT) -@CPU_I386_TRUE@am__objects_5 = pcem-codegen_x86.$(OBJEXT) -@CPU_X86_64_TRUE@am__objects_6 = pcem-codegen_x86-64.$(OBJEXT) -@USE_NETWORKING_TRUE@am__objects_7 = pcem-ne2000.$(OBJEXT) \ +@USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) +@USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) +@CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) +@CPU_X86_64_TRUE@am__objects_4 = pcem-codegen_x86-64.$(OBJEXT) +@USE_NETWORKING_TRUE@am__objects_5 = pcem-ne2000.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(OBJEXT) am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ @@ -273,16 +223,17 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-scsi_hd.$(OBJEXT) pcem-serial.$(OBJEXT) \ pcem-sio.$(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_ps1.$(OBJEXT) \ - pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) \ - pcem-soundopenal.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ - pcem-tandy_rom.$(OBJEXT) pcem-timer.$(OBJEXT) \ + pcem-sound_adlibgold.$(OBJEXT) pcem-sound_audiopci.$(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_ps1.$(OBJEXT) pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ + pcem-tandy_eeprom.$(OBJEXT) pcem-tandy_rom.$(OBJEXT) \ + pcem-t3100e.$(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) \ @@ -299,13 +250,14 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-vid_ps1_svga.$(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_tandysl.$(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-vid_wy700.$(OBJEXT) \ - pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ + pcem-vid_svga_render.$(OBJEXT) pcem-vid_t3100e.$(OBJEXT) \ + pcem-vid_tandy.$(OBJEXT) pcem-vid_tandysl.$(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-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ + pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ pcem-cdrom_image.$(OBJEXT) pcem-dbopl.$(OBJEXT) \ pcem-nukedopl.$(OBJEXT) pcem-vid_cga_comp.$(OBJEXT) \ @@ -317,15 +269,25 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-wave6581__ST.$(OBJEXT) pcem-wave8580_PS_.$(OBJEXT) \ pcem-wave8580_PST.$(OBJEXT) pcem-wave8580_P_T.$(OBJEXT) \ pcem-wave8580__ST.$(OBJEXT) pcem-wave.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) + pcem-wx-main.$(OBJEXT) pcem-wx-config_sel.$(OBJEXT) \ + pcem-wx-dialogbox.$(OBJEXT) pcem-wx-utils.$(OBJEXT) \ + pcem-wx-app.$(OBJEXT) pcem-wx-sdl2-joystick.$(OBJEXT) \ + pcem-wx-sdl2-mouse.$(OBJEXT) pcem-wx-sdl2-keyboard.$(OBJEXT) \ + pcem-wx-sdl2-video.$(OBJEXT) pcem-wx-sdl2.$(OBJEXT) \ + pcem-wx-config.$(OBJEXT) pcem-wx-deviceconfig.$(OBJEXT) \ + pcem-wx-status.$(OBJEXT) pcem-wx-sdl2-status.$(OBJEXT) \ + pcem-wx-resources.$(OBJEXT) pcem-wx-thread.$(OBJEXT) \ + pcem-wx-common.$(OBJEXT) pcem-wx-sdl2-display.$(OBJEXT) \ + pcem-wx-sdl2-video-renderer.$(OBJEXT) \ + pcem-wx-sdl2-video-gl3.$(OBJEXT) \ + pcem-wx-glslp-parser.$(OBJEXT) pcem-wx-shader_man.$(OBJEXT) \ + pcem-wx-shaderconfig.$(OBJEXT) \ + pcem-wx-joystickconfig.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = -@USE_WX_FALSE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) \ -@USE_WX_FALSE@ $(am__append_12) -@USE_WX_TRUE@pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) \ -@USE_WX_TRUE@ $(am__append_12) +pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_10) pcem_LINK = $(CXXLD) $(pcem_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SCRIPTS = $(noinst_SCRIPTS) @@ -403,7 +365,6 @@ CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ -ALLEGRO_CONFIG = @ALLEGRO_CONFIG@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ @@ -474,8 +435,6 @@ 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@ @@ -544,44 +503,46 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c \ scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ serial.c sio.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 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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c \ - vid_genius.c vid_hercules.c vid_icd2061.c vid_ics2595.c \ - vid_incolor.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_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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_8) $(am__append_11) -@USE_WX_FALSE@pcem_CFLAGS = $(allegro_CFLAGS) -DPCEM_ALLEGRO \ -@USE_WX_FALSE@ $(am__append_7) $(am__append_9) -@USE_WX_TRUE@pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell \ -@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_7) \ -@USE_WX_TRUE@ $(am__append_9) -@USE_WX_FALSE@pcem_CXXFLAGS = $(am__append_10) -@USE_WX_TRUE@pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell \ -@USE_WX_TRUE@ sdl2-config --cflags) $(am__append_10) -@USE_WX_FALSE@pcem_LDADD = $(allegro_LIBS) -lopenal $(am__append_12) -@USE_WX_TRUE@pcem_LDADD = @LIBS@ $(am__append_2) $(am__append_12) + sound_adlibgold.c sound_audiopci.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 \ + t3100e.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_colorplus.c \ + vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ + vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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_t3100e.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 vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ + wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ + wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ + wx-status.cc wx-sdl2-status.c wx-resources.cpp wx-thread.c \ + wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c \ + wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ + wx-shaderconfig.cc wx-joystickconfig.cc $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_6) \ + $(am__append_9) +pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ + --cflags) $(am__append_5) $(am__append_7) +pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ + --cflags) $(am__append_8) +pcem_LDADD = @LIBS@ $(am__append_1) $(am__append_10) all: all-am .SUFFIXES: @@ -674,17 +635,6 @@ distclean-compile: @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-config-sel.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-deviceconfig.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-cbm_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.Po@am__quote@ @@ -795,6 +745,7 @@ distclean-compile: @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_audiopci.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_dbopl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_emu8k.Po@am__quote@ @@ -813,9 +764,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_wss.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ym7128.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.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@ @@ -851,6 +802,7 @@ distclean-compile: @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_t3100e.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_tandysl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tgui9440.Po@am__quote@ @@ -2316,6 +2268,20 @@ pcem-sound_adlibgold.obj: sound_adlibgold.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_audiopci.o: sound_audiopci.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_audiopci.o -MD -MP -MF $(DEPDIR)/pcem-sound_audiopci.Tpo -c -o pcem-sound_audiopci.o `test -f 'sound_audiopci.c' || echo '$(srcdir)/'`sound_audiopci.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_audiopci.Tpo $(DEPDIR)/pcem-sound_audiopci.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sound_audiopci.c' object='pcem-sound_audiopci.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_audiopci.o `test -f 'sound_audiopci.c' || echo '$(srcdir)/'`sound_audiopci.c + +pcem-sound_audiopci.obj: sound_audiopci.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_audiopci.obj -MD -MP -MF $(DEPDIR)/pcem-sound_audiopci.Tpo -c -o pcem-sound_audiopci.obj `if test -f 'sound_audiopci.c'; then $(CYGPATH_W) 'sound_audiopci.c'; else $(CYGPATH_W) '$(srcdir)/sound_audiopci.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_audiopci.Tpo $(DEPDIR)/pcem-sound_audiopci.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sound_audiopci.c' object='pcem-sound_audiopci.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_audiopci.obj `if test -f 'sound_audiopci.c'; then $(CYGPATH_W) 'sound_audiopci.c'; else $(CYGPATH_W) '$(srcdir)/sound_audiopci.c'; fi` + pcem-sound_cms.o: sound_cms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-sound_cms.Tpo $(DEPDIR)/pcem-sound_cms.Po @@ -2568,6 +2534,20 @@ pcem-tandy_rom.obj: tandy_rom.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-tandy_rom.obj `if test -f 'tandy_rom.c'; then $(CYGPATH_W) 'tandy_rom.c'; else $(CYGPATH_W) '$(srcdir)/tandy_rom.c'; fi` +pcem-t3100e.o: t3100e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-t3100e.o -MD -MP -MF $(DEPDIR)/pcem-t3100e.Tpo -c -o pcem-t3100e.o `test -f 't3100e.c' || echo '$(srcdir)/'`t3100e.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-t3100e.Tpo $(DEPDIR)/pcem-t3100e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t3100e.c' object='pcem-t3100e.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-t3100e.o `test -f 't3100e.c' || echo '$(srcdir)/'`t3100e.c + +pcem-t3100e.obj: t3100e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-t3100e.obj -MD -MP -MF $(DEPDIR)/pcem-t3100e.Tpo -c -o pcem-t3100e.obj `if test -f 't3100e.c'; then $(CYGPATH_W) 't3100e.c'; else $(CYGPATH_W) '$(srcdir)/t3100e.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-t3100e.Tpo $(DEPDIR)/pcem-t3100e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t3100e.c' object='pcem-t3100e.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-t3100e.obj `if test -f 't3100e.c'; then $(CYGPATH_W) 't3100e.c'; else $(CYGPATH_W) '$(srcdir)/t3100e.c'; fi` + pcem-timer.o: timer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-timer.Tpo $(DEPDIR)/pcem-timer.Po @@ -3044,6 +3024,20 @@ pcem-vid_svga_render.obj: vid_svga_render.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_t3100e.o: vid_t3100e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_t3100e.o -MD -MP -MF $(DEPDIR)/pcem-vid_t3100e.Tpo -c -o pcem-vid_t3100e.o `test -f 'vid_t3100e.c' || echo '$(srcdir)/'`vid_t3100e.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_t3100e.Tpo $(DEPDIR)/pcem-vid_t3100e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_t3100e.c' object='pcem-vid_t3100e.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_t3100e.o `test -f 'vid_t3100e.c' || echo '$(srcdir)/'`vid_t3100e.c + +pcem-vid_t3100e.obj: vid_t3100e.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_t3100e.obj -MD -MP -MF $(DEPDIR)/pcem-vid_t3100e.Tpo -c -o pcem-vid_t3100e.obj `if test -f 'vid_t3100e.c'; then $(CYGPATH_W) 'vid_t3100e.c'; else $(CYGPATH_W) '$(srcdir)/vid_t3100e.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_t3100e.Tpo $(DEPDIR)/pcem-vid_t3100e.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_t3100e.c' object='pcem-vid_t3100e.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_t3100e.obj `if test -f 'vid_t3100e.c'; then $(CYGPATH_W) 'vid_t3100e.c'; else $(CYGPATH_W) '$(srcdir)/vid_t3100e.c'; fi` + pcem-vid_tandy.o: vid_tandy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_tandy.Tpo $(DEPDIR)/pcem-vid_tandy.Po @@ -3492,174 +3486,6 @@ pcem-wx-sdl2-midi.obj: wx-sdl2-midi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` -pcem-allegro-gui.o: allegro-gui.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-config-sel.o: allegro-gui-config-sel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-config-sel.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo -c -o pcem-allegro-gui-config-sel.o `test -f 'allegro-gui-config-sel.c' || echo '$(srcdir)/'`allegro-gui-config-sel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo $(DEPDIR)/pcem-allegro-gui-config-sel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-config-sel.c' object='pcem-allegro-gui-config-sel.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-config-sel.o `test -f 'allegro-gui-config-sel.c' || echo '$(srcdir)/'`allegro-gui-config-sel.c - -pcem-allegro-gui-config-sel.obj: allegro-gui-config-sel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-config-sel.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo -c -o pcem-allegro-gui-config-sel.obj `if test -f 'allegro-gui-config-sel.c'; then $(CYGPATH_W) 'allegro-gui-config-sel.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-config-sel.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-config-sel.Tpo $(DEPDIR)/pcem-allegro-gui-config-sel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-config-sel.c' object='pcem-allegro-gui-config-sel.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-config-sel.obj `if test -f 'allegro-gui-config-sel.c'; then $(CYGPATH_W) 'allegro-gui-config-sel.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-config-sel.c'; fi` - -pcem-allegro-gui-configure.o: allegro-gui-configure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-deviceconfig.o: allegro-gui-deviceconfig.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-deviceconfig.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo -c -o pcem-allegro-gui-deviceconfig.o `test -f 'allegro-gui-deviceconfig.c' || echo '$(srcdir)/'`allegro-gui-deviceconfig.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo $(DEPDIR)/pcem-allegro-gui-deviceconfig.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-deviceconfig.c' object='pcem-allegro-gui-deviceconfig.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-deviceconfig.o `test -f 'allegro-gui-deviceconfig.c' || echo '$(srcdir)/'`allegro-gui-deviceconfig.c - -pcem-allegro-gui-deviceconfig.obj: allegro-gui-deviceconfig.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-deviceconfig.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo -c -o pcem-allegro-gui-deviceconfig.obj `if test -f 'allegro-gui-deviceconfig.c'; then $(CYGPATH_W) 'allegro-gui-deviceconfig.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-deviceconfig.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-deviceconfig.Tpo $(DEPDIR)/pcem-allegro-gui-deviceconfig.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='allegro-gui-deviceconfig.c' object='pcem-allegro-gui-deviceconfig.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-deviceconfig.obj `if test -f 'allegro-gui-deviceconfig.c'; then $(CYGPATH_W) 'allegro-gui-deviceconfig.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-deviceconfig.c'; fi` - -pcem-allegro-gui-hdconf.o: allegro-gui-hdconf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-thread-pthread.o: thread-pthread.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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-codegen_x86.o: codegen_x86.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_x86.Tpo $(DEPDIR)/pcem-codegen_x86.Po diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 deleted file mode 100644 index 8b31bae..0000000 --- a/src/Makefile.linux32 +++ /dev/null @@ -1,47 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++ -CC = gcc -CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m32 -LDFLAGS = -m32 -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ -allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ -codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ -dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ -sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t3100e.o tandy_eeprom.o tandy_rom.o thread-pthread.o \ -timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.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_t3100e.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 wd76c10.o \ -x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - - -LIBS = -lopenal -lstdc++ -lalleg -lpthread -lm - -PCem: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(LDFLAGS) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem" $(LIBS) - -all : PCem - -clean : - rm *.o - rm PCem - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CFLAGS) -c $< - -%.o : %.cpp - $(CPP) $(CFLAGS) -c $< diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 deleted file mode 100644 index 030f711..0000000 --- a/src/Makefile.linux64 +++ /dev/null @@ -1,46 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++ -CC = gcc -CFLAGS = -DPCEM_ALLEGRO -O3 -fomit-frame-pointer -msse2 -m64 -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ -allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ -codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ -dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ -sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t3100e.o tandy_eeprom.o tandy_rom.o thread-pthread.o \ -timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.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_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - - -LIBS = -lopenal -lstdc++ -lalleg -lpthread -lm - -PCem64: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64" $(LIBS) - -all : PCem64 - -clean : - rm *.o - rm PCem64 - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CFLAGS) -c $< - -%.o : %.cpp - $(CPP) $(CFLAGS) -c $< diff --git a/src/allegro-gui-config-sel.c b/src/allegro-gui-config-sel.c deleted file mode 100644 index 708889b..0000000 --- a/src/allegro-gui-config-sel.c +++ /dev/null @@ -1,266 +0,0 @@ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "config.h" -#include "paths.h" -#undef printf -typedef struct config_t -{ - char name[512]; - struct config_t *next; -} config_t; - -static config_t *config_head; - -static char *get_config(int nr); -static int get_config_nr(); -static void free_configs(); -static void populate_configs(); - -static char *list_proc_joystick(int index, int *list_size) -{ - int c = 0; - config_t *config = config_head; - - if (index < 0) - { - while (config) - { - c++; - config = config->next; - } - - *list_size = c; - return NULL; - } - - for (; c < index; c++) - { - if (!config) - return NULL; - config = config->next; - } - - if (!config) - return NULL; - - return config->name; -// return joystick_list[index].name; -} - -static char config_name[256]; - -static DIALOG new_config_dialog[] = -{ - {d_shadow_box_proc, 0, 0, 480,80,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 240-148, 56, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 240+4, 56, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_edit_proc, 8, 32, 464, 16, 0, 0xffffff, 0, 0, 255, 0, config_name, 0, 0}, // 3 - - {d_text_proc, 240-29*4, 16, 29*8, 16, 0, 0xffffff, 0, 0, 255, 0, "Please type new config name :", 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int new_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - int c; - - config_name[0] = 0; - new_config_dialog[3].d2 = 0; - - position_dialog(new_config_dialog, SCREEN_W/2 - new_config_dialog[0].w/2, SCREEN_H/2 - new_config_dialog[0].h/2); - - c = popup_dialog(new_config_dialog, 1); - - position_dialog(new_config_dialog, -(SCREEN_W/2 - new_config_dialog[0].w/2), -(SCREEN_H/2 - new_config_dialog[0].h/2)); - - if (c == 1) - { - sprintf(config_file_default, "%s%s.cfg", configs_path, config_name); - c = settings_configure(); - free_configs(); - populate_configs(); - return c; - } - - return D_O_K; - } - - return ret; -} - -static int config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - char *name = get_config(get_config_nr()); - - if (name) - { - sprintf(config_file_default, "%s%s.cfg", configs_path, name); - loadconfig(NULL); - return settings_configure(); - } - - return D_O_K; - } - - return ret; -} - -static int hdd_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - char *name = get_config(get_config_nr()); - - if (name) - { - sprintf(config_file_default, "%s%s.cfg", configs_path, name); - loadconfig(NULL); - return disc_hdconf(); - } - - return D_O_K; - } - - return ret; -} - -static DIALOG config_sel_dialog[] = -{ - {d_shadow_box_proc, 0, 0, 568,372,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 416, 8, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Load", 0, 0}, // 1 - {d_button_proc, 416, 348, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Quit", 0, 0}, // 2 - - {new_proc, 416, 56, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "New...", 0, 0}, // 3 - {config_proc, 416, 80, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, // 4 - {hdd_proc, 416, 104, 144, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "HDD...", 0, 0}, // 5 - - {d_list_proc, 8, 8, 400, 356, 0, 0xffffff, 0, 0, 0, 0, list_proc_joystick, 0, 0}, // 6 - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int get_config_nr() -{ - return config_sel_dialog[6].d1; -} - -static void populate_configs() -{ - struct al_ffblk info; - char cfg[512]; - config_t *config = NULL; - - strcpy(cfg, configs_path); - strcat(cfg, "*.cfg"); - printf("cfg %s\n", cfg); - if (al_findfirst(cfg, &info, FA_ALL)) - return; - - do - { - config_t *old_config = config; - char *ext; - - config = malloc(sizeof(config_t)); - if (old_config) - old_config->next = config; - else - config_head = config; - config->next = 0; - strcpy(config->name, info.name); - - ext = get_extension(config->name); - if (ext && ext[0]) - { - ext--; - *ext = 0; - } - - printf("Found %s\n", info.name); - } while (al_findnext(&info) == 0); - - al_findclose(&info); -} - -static char *get_config(int nr) -{ - config_t *config = config_head; - int c; - - for (c = 0; c < nr; c++) - { - if (!config) - return NULL; - config = config->next; - } - if (!config) - return NULL; - - return config->name; -} - -static void free_configs() -{ - config_t *config = config_head; - - while (config) - { - config_t *old_config = config; - - config = config->next; - free(old_config); - } -} - -int config_sel() -{ - populate_configs(); - set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); - while (1) - { - int c; - - position_dialog(config_sel_dialog, SCREEN_W/2 - config_sel_dialog[0].w/2, SCREEN_H/2 - config_sel_dialog[0].h/2); - - c = popup_dialog(config_sel_dialog, 1); - - position_dialog(config_sel_dialog, -(SCREEN_W/2 - config_sel_dialog[0].w/2), -(SCREEN_H/2 - config_sel_dialog[0].h/2)); - - if (c == 1) - { - char *name = get_config(config_sel_dialog[6].d1); - - if (name) - { - sprintf(config_file_default, "%s%s.cfg", configs_path, name); - pclog("config_file_default=%s\n", config_file_default); - free_configs(); - return 0; - } - } - - if (c == 2) - return 1; - } - - free_configs(); - - return 1; -} - diff --git a/src/allegro-gui-configure.c b/src/allegro-gui-configure.c deleted file mode 100644 index 349ed91..0000000 --- a/src/allegro-gui-configure.c +++ /dev/null @@ -1,837 +0,0 @@ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "cpu.h" -#include "fdd.h" -#include "gameport.h" -#include "hdd.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "sound.h" -#include "video.h" -#include "vid_voodoo.h" - -static int romstolist[ROM_MAX]; -static int settings_mouse_to_list[20], settings_list_to_mouse[20]; - -typedef struct allegro_list_t -{ - char name[256]; - int num; -} allegro_list_t; - -typedef struct allegro_list_str_t -{ - char name[256]; - char *internal_name; -} allegro_list_str_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 allegro_list_t mouse_list[32]; -static allegro_list_str_t hdd_list[32]; - -static char mem_size_str[10], mem_size_units[3]; - -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 allegro_list_t waitstate_list[] = -{ - {"System default", 0}, - {"0 W/S", 1}, - {"1 W/S", 2}, - {"2 W/S", 3}, - {"3 W/S", 4}, - {"4 W/S", 5}, - {"5 W/S", 6}, - {"6 W/S", 7}, - {"7 W/S", 8}, - {"", -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_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_hdd(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (hdd_list[c].internal_name) - c++; - - *list_size = c; - return NULL; - } - - return hdd_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 char *list_proc_mouse(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (mouse_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return mouse_list[index].name; -} - -static char *list_proc_ws(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (waitstate_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return waitstate_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 model_config_proc(int msg, DIALOG *d, int c); -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,372,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 226, 348, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 296, 348, 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, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0}, //7 - {list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //8 - - {d_edit_proc, 70*2, 276, 48, 14, 0, 0xffffff, 0, 0, 5, 0, mem_size_str, 0, 0}, - - {d_text_proc, 98*2, 276, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, - - {d_check_proc, 14*2, 292, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0}, - {d_check_proc, 14*2, 308, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0}, - {d_check_proc, 14*2, 324, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0}, - {d_check_proc, 14*2, 336, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0}, //14 - - {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, 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, 276, 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, 196, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive A: :", 0, 0}, - {d_text_proc, 16*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive B: :", 0, 0}, - {d_list_proc, 70*2, 192, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0}, //25 - {d_list_proc, 70*2, 212, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0}, - - {video_config_proc, 452, 36, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, //27 - {sound_config_proc, 452, 156, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - {voodoo_config_proc, 452, 336, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - - {d_text_proc, 16*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Joystick :", 0, 0}, - {d_list_proc, 70*2, 232, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_joystick, 0, 0}, //31 - - {d_text_proc, 16*2, 256, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Mouse :", 0, 0}, - {d_list_proc, 70*2, 252, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_mouse, 0, 0}, //33 - - {model_config_proc, 452, 12, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - - {d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Waitstates :", 0, 0}, - {d_list_proc, 70*2, 112, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_ws, 0, 0}, //36 - - {d_text_proc, 16*2, 176, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "HDD :", 0, 0}, - {d_list_proc, 70*2, 172, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_hdd, 0, 0}, //38 - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static void update_hdd_list(int model, int use_selected_hdd) -{ - memset(hdd_list, 0, sizeof(hdd_list)); - - if (models[model].flags & MODEL_HAS_IDE) - { - strcpy(hdd_list[0].name, "Internal IDE"); - hdd_list[0].internal_name = "internal_ide"; - } - else - { - int c = 0, d = 0; - char old_name[16]; - - if (use_selected_hdd) - { - c = configure_dialog[38].d1; - - if (c != -1 && hdd_list[c].internal_name) - strncpy(old_name, hdd_list[c].internal_name, sizeof(old_name)-1); - else - strcpy(old_name, "none"); - } - else - strncpy(old_name, hdd_controller_name, sizeof(old_name)-1); - - configure_dialog[38].d1 = 0; - pclog("HDD list %i\n", model); - c = 0; - while (1) - { - char *s = hdd_controller_get_name(c); - - if (s[0] == 0) - break; - - if ((((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) || - (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model].flags & MODEL_MCA)) && c) - { - pclog("Skip %i 1 %s\n", c, s); - c++; - continue; - } - if (!hdd_controller_available(c)) - { - pclog("Skip %i 2 %s\n", c, s); - c++; - continue; - } - - strcpy(hdd_list[d].name, s); - hdd_list[d].internal_name = hdd_controller_get_internal_name(c); - - if (!strcmp(old_name, hdd_list[d].internal_name)) - configure_dialog[38].d1 = d; - - c++; - d++; - } - } -} - -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 update_mouse_list() -{ - int sel_model = model_list[configure_dialog[3].d1].num; - int c = 0, d = 0; - int new_mouse = settings_list_to_mouse[configure_dialog[33].d1]; - - while (mouse_get_name(c)) - { - int type = mouse_get_type(c); - - settings_mouse_to_list[c] = d; - - if (mouse_valid(type, sel_model)) - { - strcpy(mouse_list[d].name, mouse_get_name(c)); - settings_list_to_mouse[d] = c; - d++; - } - - c++; - } - mouse_list[d].name[0] = 0; - - if (mouse_valid(mouse_get_type(new_mouse), sel_model)) - configure_dialog[33].d1 = settings_mouse_to_list[new_mouse]; - else - configure_dialog[33].d1 = 0; -} - -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[22].flags & D_SELECTED; - int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num); - int new_mem_size; - int cpu_flags, cpu_type; - - 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[22].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[22].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].flags & MODEL_AT) && models[new_model].ram_granularity < 128) - sprintf(mem_size_units, "MB"); - else - sprintf(mem_size_units, "kB"); - - if (!video_card_has_config(new_gfxcard)) - configure_dialog[27].flags |= D_DISABLED; - else - configure_dialog[27].flags &= ~D_DISABLED; - - if (!sound_card_has_config(configure_dialog[9].d1)) - configure_dialog[28].flags |= D_DISABLED; - else - configure_dialog[28].flags &= ~D_DISABLED; - - update_mouse_list(); - - if (!model_getdevice(new_model)) - configure_dialog[34].flags |= D_DISABLED; - else - configure_dialog[34].flags &= ~D_DISABLED; - - cpu_type = models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_type; - if (cpu_type < CPU_286 || cpu_type > CPU_386DX) - configure_dialog[36].flags |= D_DISABLED; - else - configure_dialog[36].flags &= ~D_DISABLED; - - update_hdd_list(new_model, 1); - - 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[8].d1].num; - - deviceconfig_open(sound_card_getdevice(new_sndcard)); - return D_O_K; - } - - return ret; -} -static int model_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - int model = model_list[configure_dialog[3].d1].num; - - deviceconfig_open(model_getdevice(model)); - 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[27].flags |= D_DISABLED; - else - configure_dialog[27].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[8].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[31].d1 = c; - - c++; - } - - configure_dialog[33].d1 = 0; - update_mouse_list(); - configure_dialog[33].d1 = settings_mouse_to_list[mouse_type]; - - update_hdd_list(model, 0); - - if (!sound_card_has_config(configure_dialog[8].d1)) - configure_dialog[28].flags |= D_DISABLED; - else - configure_dialog[28].flags &= ~D_DISABLED; - - configure_dialog[5].d1 = cpu_manufacturer; - configure_dialog[6].d1 = cpu; - configure_dialog[7].d1 = video_speed; - configure_dialog[36].d1 = cpu_waitstates; - 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[11].flags |= D_SELECTED; - else - configure_dialog[11].flags &= ~D_SELECTED; - - if (GUS) - configure_dialog[12].flags |= D_SELECTED; - else - configure_dialog[12].flags &= ~D_SELECTED; - - if (SSI2001) - configure_dialog[13].flags |= D_SELECTED; - else - configure_dialog[13].flags &= ~D_SELECTED; - - if (voodoo_enabled) - configure_dialog[14].flags |= D_SELECTED; - else - configure_dialog[14].flags &= ~D_SELECTED; - - if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) - sprintf(mem_size_str, "%i", mem_size / 1024); - else - sprintf(mem_size_str, "%i", mem_size); - - if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) - sprintf(mem_size_units, "MB"); - else - sprintf(mem_size_units, "kB"); - - if (!model_getdevice(model)) - configure_dialog[34].flags |= D_DISABLED; - else - configure_dialog[34].flags &= ~D_DISABLED; - - cpu_flags = models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; - configure_dialog[22].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[22].flags |= D_DISABLED; - - configure_dialog[25].d1 = fdd_get_type(0); - configure_dialog[26].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[8].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[11].flags & D_SELECTED) ? 1 : 0; - int new_GUS = (configure_dialog[12].flags & D_SELECTED) ? 1 : 0; - int new_SSI2001 = (configure_dialog[13].flags & D_SELECTED) ? 1 : 0; - int new_voodoo = (configure_dialog[14].flags & D_SELECTED) ? 1 : 0; - int new_dynarec = (configure_dialog[22].flags & D_SELECTED) ? 1 : 0; - int new_fda = configure_dialog[25].d1; - int new_fdb = configure_dialog[26].d1; - int new_mouse = settings_list_to_mouse[configure_dialog[33].d1]; - int new_hdd = configure_dialog[38].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].flags & MODEL_AT) && models[new_model].ram_granularity < 128) - 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) || - new_mouse != mouse_type || strncmp(hdd_list[new_hdd].internal_name, hdd_controller_name, sizeof(hdd_controller_name)-1)) - { - if (has_been_inited && alert("This will reset PCem!", "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; - mouse_type = new_mouse; - - if (hdd_list[new_hdd].internal_name) - strncpy(hdd_controller_name, hdd_list[new_hdd].internal_name, sizeof(hdd_controller_name)-1); - else - strcpy(hdd_controller_name, "none"); - - mem_resize(); - loadbios(); - resetpchard(); - - fdd_set_type(0, new_fda); - fdd_set_type(1, new_fdb); - } - - video_speed = configure_dialog[7].d1; - - cpu_manufacturer = new_cpu_m; - cpu = new_cpu; - cpu_set(); - - cpu_waitstates = configure_dialog[36].d1; - cpu_update_waitstates(); - - joystick_type = configure_dialog[31].d1; - gameport_update_joystick_type(); - - saveconfig(NULL); - - 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 3899ce9..0000000 --- a/src/allegro-gui-deviceconfig.c +++ /dev/null @@ -1,303 +0,0 @@ -#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(CFG_MACHINE, 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(CFG_MACHINE, 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(CFG_MACHINE, 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(CFG_MACHINE, 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 PCem!", "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(CFG_MACHINE, 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(CFG_MACHINE, config_device->name, config->name, val); - - dialog_pos += 2; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - saveconfig(NULL); - - 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 050be68..0000000 --- a/src/allegro-gui-hdconf.c +++ /dev/null @@ -1,537 +0,0 @@ -#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 PcemHDC 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); - if ((sz % 17) == 0 && sz <= 142606336) - { - sprintf(hd_sectors_new, "17"); - if (sz <= 26738688) - { - sprintf(hd_heads_new, "4"); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 4) / 17); - } - else if ((sz % 3072) == 0 && sz <= 53477376) - { - sprintf(hd_heads_new, "6"); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 6) / 17); - } - else - { - int i; - for(i=5;i<16;i++) - { - if((sz % (i * 512)) == 0 && sz <= 1024*i*17*512) break; - if (i == 5) i++; - } - sprintf(hd_heads_new, "%i",i); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / i) / 17); - } - } - else - { - 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; - uint8_t buf[512]; - FILE *f = fopen64(hd_path_new, "wb"); - 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); - - return 0; -} - -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; - - 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; - - 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 (!has_been_inited || alert("This will reset PCem!", "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(NULL); - - 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 427c226..0000000 --- a/src/allegro-gui.c +++ /dev/null @@ -1,288 +0,0 @@ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "disc.h" -#include "ide.h" -#include "cdrom-ioctl.h" -#include "cdrom-image.h" -#include "cdrom-null.h" - -void warning(const char *format, ...) -{ - char buf[1024]; - va_list ap; - - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - - alert("Warning:", buf, NULL, "OK", NULL, 0, 0); -} - - -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(NULL); - } - 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(NULL); - } - return D_O_K; -} - -static int disc_eject_a() -{ - disc_close(0); - saveconfig(NULL); - - return D_O_K; -} - -static int disc_eject_b() -{ - disc_close(1); - saveconfig(NULL); - - 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 switch (cdrom_drive) - { - case -1: - cdrom_menu[1].flags = D_SELECTED; - break; - case CDROM_IMAGE: - cdrom_menu[3].flags = D_SELECTED; - break; - default: - cdrom_menu[2].flags = D_SELECTED; - break; - } -} - -static int cdrom_disabled() -{ - if (!cdrom_enabled) - return D_O_K; - - if (alert("This will reset PCem!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - atapi->exit(); - cdrom_enabled = 0; - saveconfig(NULL); - 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 PCem!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - cdrom_drive = -1; - cdrom_enabled = 1; - cdrom_null_open(cdrom_drive); - saveconfig(NULL); - resetpchard(); - cdrom_update(); - } - - return D_O_K; -} - -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 PCem!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - cdrom_drive = 1; - cdrom_enabled = 1; - ioctl_open(cdrom_drive); - saveconfig(NULL); - resetpchard(); - cdrom_update(); - } - - return D_O_K; -} - -static int cdrom_image() -{ - char fn[260]; - int ret; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - - strcpy(fn, image_path); - ret = file_select_ex("Please choose an image image", fn, "ISO;CUE", 260, xsize, ysize); - if (ret) - { - if (!cdrom_enabled) - { - if (alert("This will reset PCem!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1) - return D_O_K; - } - else - { - atapi->exit(); - } - - cdrom_drive = CDROM_IMAGE; - image_open(fn); - if (!cdrom_enabled) - { - cdrom_enabled = 1; - resetpchard(); - } - cdrom_update(); - saveconfig(NULL); - } - return D_O_K; -} - -static MENU cdrom_menu[] = -{ - {"&Disabled", cdrom_disabled, NULL, 0, NULL}, - {"&Empty", cdrom_empty, NULL, 0, NULL}, - {"/dev/cdrom", cdrom_dev, NULL, 0, NULL}, - {"&Image...", cdrom_image, 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 pcem_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(pcem_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 2c98f82..0000000 --- a/src/allegro-gui.h +++ /dev/null @@ -1,15 +0,0 @@ -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); -int config_sel(); - -extern int has_been_inited; diff --git a/src/allegro-joystick.c b/src/allegro-joystick.c deleted file mode 100644 index 953399a..0000000 --- a/src/allegro-joystick.c +++ /dev/null @@ -1,49 +0,0 @@ -#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 335f842..0000000 --- a/src/allegro-keyboard.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "allegro-main.h" -#include "plat-keyboard.h" - -int pcem_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] != pcem_key[key_idx]) - pcem_key[key_idx] = key[c]; - } -} diff --git a/src/allegro-main.c b/src/allegro-main.c deleted file mode 100644 index 2d60650..0000000 --- a/src/allegro-main.c +++ /dev/null @@ -1,280 +0,0 @@ -#include "ibm.h" -#include "device.h" -#include "allegro-gui.h" -#include "allegro-main.h" -#include "allegro-video.h" -#include "config.h" -#include "cpu.h" -#include "mem.h" -#include "model.h" -#include "nvr.h" -#include "plat-joystick.h" -#include "plat-keyboard.h" -#include "plat-midi.h" -#include "plat-mouse.h" -#include "sound.h" -#include "video.h" -#include -#include -#include -#include -#include -#include "paths.h" - - #undef printf - -int has_been_inited = 0; - -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 dir_exists(char *path) -{ - DIR *dir = opendir(path); - if (dir) - { - closedir(dir); - return 1; - } - return 0; -} - -int create_dir(char *path) -{ - if (!mkdir(path, 0755)) - return 1; - return 0; -} - -void get_pcem_path(char *s, int size) -{ - struct passwd *pw = getpwuid(getuid()); - - strncpy(s, pw->pw_dir, size-10); - append_slash(s, size); - strcat(s, ".pcem/"); - //get_executable_name(s, size); -} - -int main(int argc, char *argv[]) -{ - char s[512]; - int frames = 0; - int c; - FILE *f; - - 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(); - - paths_init(); - - /* create directories if they don't exist */ - if (!dir_exists(pcem_path)) { - if (!create_dir(pcem_path)) - return 0; - append_filename(s, pcem_path, "configs", 511); - if (!dir_exists(s) && !create_dir(s)) - return 0; - - append_filename(s, pcem_path, "roms", 511); - if (!dir_exists(s) && !create_dir(s)) - return 0; - - append_filename(s, pcem_path, "nvr", 511); - if (!dir_exists(s) && !create_dir(s)) - return 0; - - append_filename(s, pcem_path, "logs", 511); - if (!dir_exists(s) && !create_dir(s)) - return 0; - } - - /* set up default paths */ - sprintf(s, "%s%s%c%s", pcem_path, "roms/", get_path_separator(), "/usr/share/pcem/roms/"); - set_default_roms_paths(s); - append_filename(s, pcem_path, "nvr/", 511); - set_default_nvr_path(s); - append_filename(s, pcem_path, "configs/", 511); - set_default_configs_path(s); - append_filename(s, pcem_path, "logs/", 511); - set_default_logs_path(s); - - sound_init(); - - initpc(argc, argv); - - /* check if cfg exists, and if not create it */ - append_filename(s, pcem_path, "pcem.cfg", 511); - f = fopen(s, "r"); - if (f) - fclose(f); - else - saveconfig(NULL); - - keyboard_init(); - mouse_init(); - joystick_init(); - - 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 PCem."); - return 0; - } - - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); - - while (1) - { - has_been_inited = 0; - if (config_sel()) - return 0; - has_been_inited = 1; - - quited = 0; - - loadconfig(NULL); - - 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(NULL); - resetpchard(); - break; - } - } - } - - 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(NULL); - 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; - } - } - - savenvr(); - } - - closepc(); - - joystick_close(); - mouse_close(); - keyboard_close(); - midi_close(); - - return 0; -} - -END_OF_MAIN(); diff --git a/src/allegro-main.h b/src/allegro-main.h deleted file mode 100644 index ba96a4f..0000000 --- a/src/allegro-main.h +++ /dev/null @@ -1,19 +0,0 @@ -#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 b491db1..0000000 --- a/src/allegro-midi.c +++ /dev/null @@ -1,45 +0,0 @@ -#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 9cceaa9..0000000 --- a/src/allegro-mouse.c +++ /dev/null @@ -1,32 +0,0 @@ -#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, int *z) -{ - if (mousecapture) - { - get_mouse_mickeys(x, y); - *z = 0; -// position_mouse(64, 64); - } - else - *x = *y = *z = 0; -} - diff --git a/src/allegro-video.c b/src/allegro-video.c deleted file mode 100644 index 694f586..0000000 --- a/src/allegro-video.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "allegro-main.h" -#include "ibm.h" -#include "video.h" - -#include "allegro-video.h" - -static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static BITMAP *buffer32_vscale; -void allegro_video_init() -{ - set_color_depth(32); - set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); - video_blit_memtoscreen_func = allegro_blit_memtoscreen; - - 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); - } - } - - video_blit_complete(); - 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); - video_blit_complete(); - } -} - diff --git a/src/allegro-video.h b/src/allegro-video.h deleted file mode 100644 index e82419a..0000000 --- a/src/allegro-video.h +++ /dev/null @@ -1,3 +0,0 @@ -void allegro_video_init(); -void allegro_video_close(); -void allegro_video_update_size(int x, int y); diff --git a/src/pc.c b/src/pc.c index 0afa2da..eb487dd 100644 --- a/src/pc.c +++ b/src/pc.c @@ -233,7 +233,6 @@ void initpc(int argc, char *argv[]) //char *p; // char *config_file = NULL; int c; -// allegro_init(); for (c = 1; c < argc; c++) { diff --git a/src/video.h b/src/video.h index e301dcb..f4ca12a 100644 --- a/src/video.h +++ b/src/video.h @@ -1,11 +1,3 @@ -#ifdef PCEM_ALLEGRO - -#undef MAX_JOYSTICKS -#include "allegro-main.h" -#define MAX_JOYSTICKS 4 - -#else - typedef struct { int w, h; @@ -27,8 +19,6 @@ typedef RGB PALETTE[256]; #define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) #define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) -#endif - extern BITMAP *buffer32; int video_card_available(int card); From ed000e77c89cccfee80f7223990c171d64ddf676 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Oct 2017 12:38:45 +0100 Subject: [PATCH 0183/1050] Only set IFULL immediately following keyboard selftest on Toshiba T3100e. Fixes Samsung SPC systems. Patch from Greatpsycho. --- src/keyboard_at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index e7b6453..96357d2 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -359,7 +359,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) } /* T3100e expects STAT_IFULL to be set immediately * after sending 0xAA */ - keyboard_at.status |= STAT_IFULL; + if(romset == ROM_T3100E) keyboard_at.status |= STAT_IFULL; keyboard_at.status |= STAT_SYSFLAG; keyboard_at.mem[0] |= 0x04; keyboard_at_adddata(0x55); From 3f29d38288f2374dd1930d31cab78c49e16d7d75 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Oct 2017 12:39:28 +0100 Subject: [PATCH 0184/1050] Reset CPU on all AT commands that pulse bit 0, not just 0xf0. Fixes XENIX286. Patch from Greatpsycho. --- 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 96357d2..9fd4050 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -441,7 +441,8 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xef: /*??? - sent by AMI486*/ break; - case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/ + case 0xf0: case 0xf2: case 0xf4: case 0xf6: + case 0xf8: case 0xfa: case 0xfc: case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/ softresetx86(); /*Pulse reset!*/ cpu_set_edx(); break; From da6e537b3167c58ec1f687f87d88f219a425cf89 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Oct 2017 12:40:09 +0100 Subject: [PATCH 0185/1050] Add S3 Enhanced Mode Mappings address override. Fixes some hangs with Trio64 and Windows 95. --- src/vid_s3.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 13f71cf..d8f5fe9 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1034,7 +1034,14 @@ void s3_updatemapping(s3_t *s3) } // pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ + { + /*Enhanced mapping forces 64kb at 0xa0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } + else switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); From 39a68d757b3c9ead7d55bd7f6093133862279e72 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Oct 2017 12:41:10 +0100 Subject: [PATCH 0186/1050] Rework video memory handling to cater for open bus and VRAM address wrapping. Fixes more hangs with Trio64 and Windows 95. --- src/vid_ati_mach64.c | 4 +- src/vid_cl5429.c | 21 ++++---- src/vid_et4000w32.c | 4 +- src/vid_oti067.c | 4 +- src/vid_s3.c | 25 ++++++++- src/vid_s3_virge.c | 6 +-- src/vid_svga.c | 122 +++++++++++++++++++++++++----------------- src/vid_svga.h | 15 +++++- src/vid_svga_render.c | 88 +++++++++++++++--------------- src/vid_tvga.c | 2 +- 10 files changed, 174 insertions(+), 117 deletions(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 371638e..f6c7720 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -468,12 +468,12 @@ void mach64_recalctimings(svga_t *svga) break; } - svga->vrammask = mach64->vram_mask; + svga->vram_display_mask = 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 { - svga->vrammask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; + svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; } } diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 6616b59..15a805d 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -350,9 +350,10 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) { addr <<= 2; } - addr &= 0x7fffff; - if (addr >= svga->vram_limit) + addr &= svga->decode_mask; + if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; // if (svga_output) pclog("%08X\n", addr); svga->changedvram[addr >> 12] = changeframecount; @@ -595,16 +596,16 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) switch (gd5429->blt.mode & 0xc0) { case 0x00: - src = svga->vram[gd5429->blt.src_addr & svga->vrammask]; + src = svga->vram[gd5429->blt.src_addr & svga->vram_mask]; gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); mask = 1; break; case 0x40: - src = svga->vram[(gd5429->blt.src_addr & (svga->vrammask & ~7)) | (gd5429->blt.dst_addr & 7)]; + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)]; mask = 1; break; case 0x80: - mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> gd5429->blt.x_count); + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; gd5429->blt.x_count++; if (gd5429->blt.x_count == 8) @@ -614,16 +615,16 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) } break; case 0xc0: - mask = svga->vram[gd5429->blt.src_addr & svga->vrammask] & (0x80 >> (gd5429->blt.dst_addr & 7)); + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7)); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; break; } count--; } - dst = svga->vram[gd5429->blt.dst_addr & svga->vrammask]; - svga->changedvram[(gd5429->blt.dst_addr & svga->vrammask) >> 12] = changeframecount; + dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask]; + svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; - pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vrammask, svga->vram[gd5429->blt.src_addr & svga->vrammask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); + pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); switch (gd5429->blt.rop) { case 0x00: dst = 0; break; @@ -647,7 +648,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) && !((gd5429->blt.mode & 0x08) && !mask)) - svga->vram[gd5429->blt.dst_addr & svga->vrammask] = dst; + svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 97fca5f..201701b 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -554,7 +554,7 @@ void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) } else { - if ((addr&0x1fff) + et4000->mmu.base[bank] < svga->vram_limit) + if ((addr&0x1fff) + et4000->mmu.base[bank] < svga->vram_max) { svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val; svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 12] = changeframecount; @@ -614,7 +614,7 @@ uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) /*???*/ return temp; } - if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_limit) + if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_max) return 0xff; return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]]; diff --git a/src/vid_oti067.c b/src/vid_oti067.c index e528e01..4a2cbc8 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -65,13 +65,13 @@ void oti067_out(uint16_t addr, uint8_t val, void *p) switch (oti067->index) { case 0xD: - svga->vrammask = (val & 0xc) ? oti067->vram_mask : 0x3ffff; + svga->vram_display_mask = (val & 0xc) ? oti067->vram_mask : 0x3ffff; if ((val & 0x80) && oti067->vram_size == 256) mem_mapping_disable(&svga->mapping); else mem_mapping_enable(&svga->mapping); if (!(val & 0x80)) - svga->vrammask = 0x3ffff; + svga->vram_display_mask = 0x3ffff; break; case 0x11: svga->read_bank = (val & 0xf) * 65536; diff --git a/src/vid_s3.c b/src/vid_s3.c index d8f5fe9..653eb76 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -818,7 +818,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); break; case 0x32: - svga->vrammask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; break; case 0x50: @@ -2222,6 +2222,29 @@ static void *s3_init(char *bios_fn, int chip) s3_hwcursor_draw, NULL); + svga->decode_mask = (4 << 20) - 1; + switch (vram) + { + case 0: /*512kb*/ + svga->vram_mask = (1 << 19) - 1; + svga->vram_max = 2 << 20; + break; + case 1: /*1MB*/ + /*VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus*/ + svga->vram_mask = (1 << 20) - 1; + svga->vram_max = 2 << 20; + break; + case 2: default: /*2MB*/ + /*VRAM in first 2 MB, 3rd and 4th MBs are open bus*/ + svga->vram_mask = (2 << 20) - 1; + svga->vram_max = 2 << 20; + break; + case 4: /*4MB*/ + svga->vram_mask = (4 << 20) - 1; + svga->vram_max = 4 << 20; + break; + } + if (PCI) svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); else diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 625901b..9451755 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -370,7 +370,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) break; case 0x32: if ((svga->crtc[0x67] & 0xc) != 0xc) - svga->vrammask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + svga->vram_display_mask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); s3_virge_update_irqs(virge); break; @@ -583,7 +583,7 @@ static void s3_virge_recalctimings(svga_t *svga) { svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ } - svga->vrammask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + svga->vram_display_mask = (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*/ @@ -631,7 +631,7 @@ static void s3_virge_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; break; } - svga->vrammask = (virge->memory_size << 20) - 1; + svga->vram_display_mask = (virge->memory_size << 20) - 1; } if (((svga->miscout >> 2) & 3) == 3) diff --git a/src/vid_svga.c b/src/vid_svga.c index 7e9f7e7..6b45d84 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -483,7 +483,7 @@ void svga_poll(void *p) { svga->hdisp_on=1; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; if (svga->firstline == 2000) { svga->firstline = svga->displine; @@ -561,7 +561,7 @@ void svga_poll(void *p) svga->maback += (svga->rowoffset << 3); if (svga->interlace) svga->maback += (svga->rowoffset << 3); - svga->maback &= svga->vrammask; + svga->maback &= svga->vram_display_mask; svga->ma = svga->maback; } else @@ -594,7 +594,7 @@ void svga_poll(void *p) svga->fullchange = 2; svga->blink++; - for (x = 0; x < (svga->vram_limit >> 12); x++) + for (x = 0; x < ((svga->vram_mask+1) >> 12); x++) { if (svga->changedvram[x]) svga->changedvram[x]--; @@ -728,8 +728,10 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->dispofftime = 1000 * (1 << TIMER_SHIFT); svga->bpp = 8; svga->vram = malloc(memsize); - svga->vram_limit = memsize; - svga->vrammask = memsize - 1; + svga->vram_max = memsize; + svga->vram_display_mask = memsize - 1; + svga->vram_mask = memsize - 1; + svga->decode_mask = 0x7fffff; svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x800000 >> 12); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; @@ -790,10 +792,12 @@ void svga_write(uint32_t addr, uint8_t val, void *p) { addr<<=2; } - addr &= 0x7fffff; + addr &= svga->decode_mask; - if (addr >= svga->vram_limit) + if (addr >= svga->vram_max) return; + + addr &= svga->vram_mask; if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); svga->changedvram[addr >> 12] = changeframecount; @@ -954,19 +958,20 @@ uint8_t svga_read(uint32_t addr, void *p) egareads++; // pclog("Readega %06X ",addr); + addr &= svga->banked_mask; addr += svga->read_bank; - - latch_addr = (addr << 2) & 0x7fffff; + + latch_addr = (addr << 2) & svga->decode_mask; // 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 &= 0x7fffff; - if (addr >= svga->vram_limit) - return 0xff; - return svga->vram[addr]; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + return svga->vram[addr & svga->vram_mask]; } else if (svga->chain2_read) { @@ -976,22 +981,27 @@ uint8_t svga_read(uint32_t addr, void *p) } else addr<<=2; + + addr &= svga->decode_mask; - addr &= 0x7fffff; - - if (addr >= svga->vram_limit) - return 0xff; - - if (latch_addr < svga->vram_limit) + if (latch_addr >= svga->vram_max) + { + svga->la = svga->lb = svga->lc = svga->ld = 0xff; + } + else { + latch_addr &= svga->vram_mask; 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]; } - else - svga->la = svga->lb = svga->lc = svga->ld = 0xff; + if (addr >= svga->vram_max) + return 0xff; + + addr &= svga->vram_mask; + if (svga->readmode) { temp = svga->la; @@ -1009,6 +1019,7 @@ uint8_t svga_read(uint32_t addr, void *p) return ~(temp | temp2 | temp3 | temp4); } //pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | readplane]; } @@ -1043,9 +1054,10 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) { addr<<=2; } - addr &= 0x7fffff; - if (addr >= svga->vram_limit) + addr &= svga->decode_mask; + if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; if (svga_output) pclog("%08X\n", addr); svga->changedvram[addr >> 12]=changeframecount; @@ -1206,10 +1218,10 @@ uint8_t svga_read_linear(uint32_t addr, void *p) if (svga->chain4 || svga->fb_only) { - addr &= 0x7fffff; - if (addr >= svga->vram_limit) - return 0xff; - return svga->vram[addr & 0x7fffff]; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + return svga->vram[addr & svga->vram_mask]; } else if (svga->chain2_read) { @@ -1220,10 +1232,12 @@ uint8_t svga_read_linear(uint32_t addr, void *p) else addr<<=2; - addr &= 0x7fffff; + addr &= svga->decode_mask; - if (addr >= svga->vram_limit) - return 0xff; + if (addr >= svga->vram_max) + return 0xff; + + addr &= svga->vram_mask; svga->la = svga->vram[addr]; svga->lb = svga->vram[addr | 0x1]; @@ -1296,9 +1310,10 @@ 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 &= 0x7FFFFF; - if (addr >= svga->vram_limit) + addr &= svga->decode_mask; + if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; if (svga_output) pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *)&svga->vram[addr] = val; @@ -1324,9 +1339,10 @@ 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 &= 0x7FFFFF; - if (addr >= svga->vram_limit) + addr &= svga->decode_mask; + if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); svga->changedvram[addr >> 12] = changeframecount; @@ -1347,11 +1363,12 @@ uint16_t svga_readw(uint32_t addr, void *p) // pclog("Readw %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; - addr &= 0x7FFFFF; + addr &= svga->decode_mask; // pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); - if (addr >= svga->vram_limit) return 0xffff; + if (addr >= svga->vram_max) + return 0xffff; - return *(uint16_t *)&svga->vram[addr]; + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } uint32_t svga_readl(uint32_t addr, void *p) @@ -1368,11 +1385,12 @@ uint32_t svga_readl(uint32_t addr, void *p) // pclog("Readl %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; - addr &= 0x7FFFFF; + addr &= svga->decode_mask; // pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); - if (addr >= svga->vram_limit) return 0xffffffff; + if (addr >= svga->vram_max) + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr]; + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } void svga_writew_linear(uint32_t addr, uint16_t val, void *p) @@ -1392,9 +1410,10 @@ 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 &= 0x7FFFFF; - if (addr >= svga->vram_limit) + addr &= svga->decode_mask; + if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *)&svga->vram[addr] = val; } @@ -1418,9 +1437,10 @@ 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 &= 0x7fffff; - if (addr >= svga->vram_limit) + addr &= svga->decode_mask; + if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; svga->changedvram[addr >> 12] = changeframecount; *(uint32_t *)&svga->vram[addr] = val; } @@ -1437,10 +1457,11 @@ uint16_t svga_readw_linear(uint32_t addr, void *p) cycles -= video_timing_w; cycles_lost += video_timing_w; - addr &= 0x7FFFFF; - if (addr >= svga->vram_limit) return 0xffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; - return *(uint16_t *)&svga->vram[addr]; + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } uint32_t svga_readl_linear(uint32_t addr, void *p) @@ -1455,10 +1476,11 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) cycles -= video_timing_l; cycles_lost += video_timing_l; - addr &= 0x7FFFFF; - if (addr >= svga->vram_limit) return 0xffffffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr]; + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } diff --git a/src/vid_svga.h b/src/vid_svga.h index 9dbacd7..f3455a3 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -15,7 +15,18 @@ typedef struct svga_t uint8_t miscout; int vidclock; - uint32_t vram_limit; + /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : + 0MB-1MB - VRAM + 1MB-2MB - VRAM mirror + 2MB-4MB - open bus + 4MB-xMB - mirror of above + + For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB + (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) + */ + uint32_t decode_mask; + uint32_t vram_max; + uint32_t vram_mask; uint8_t la, lb, lc, ld; @@ -71,7 +82,7 @@ typedef struct svga_t uint8_t *vram; uint8_t *changedvram; - int vrammask; + uint32_t vram_display_mask; uint32_t banked_mask; uint32_t write_bank, read_bank; diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 173fe6c..4e7af2b 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -51,8 +51,8 @@ void svga_render_text_40(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vrammask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vrammask]; + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -91,7 +91,7 @@ void svga_render_text_40(svga_t *svga) svga->ma += 4; p += xinc; } - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -114,8 +114,8 @@ void svga_render_text_80(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vrammask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vrammask]; + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -154,7 +154,7 @@ void svga_render_text_80(svga_t *svga) svga->ma += 4; p += xinc; } - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -192,7 +192,7 @@ void svga_render_2bpp_lowres(svga_t *svga) dat[1] = svga->vram[(svga->ma << 1) + 1]; } svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; @@ -242,7 +242,7 @@ void svga_render_2bpp_highres(svga_t *svga) dat[1] = svga->vram[(svga->ma << 1) + 1]; } svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; @@ -277,7 +277,7 @@ void svga_render_4bpp_lowres(svga_t *svga) *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; @@ -326,7 +326,7 @@ void svga_render_4bpp_highres(svga_t *svga) else *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; @@ -360,7 +360,7 @@ void svga_render_8bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = p[1] = svga->pallook[dat & 0xff]; p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; @@ -370,7 +370,7 @@ void svga_render_8bpp_lowres(svga_t *svga) svga->ma += 4; p += 8; } - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -389,13 +389,13 @@ void svga_render_8bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { uint32_t dat; - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = svga->pallook[dat & 0xff]; p[1] = svga->pallook[(dat >> 8) & 0xff]; p[2] = svga->pallook[(dat >> 16) & 0xff]; p[3] = svga->pallook[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); p[4] = svga->pallook[dat & 0xff]; p[5] = svga->pallook[(dat >> 8) & 0xff]; p[6] = svga->pallook[(dat >> 16) & 0xff]; @@ -404,7 +404,7 @@ void svga_render_8bpp_highres(svga_t *svga) svga->ma += 8; p += 8; } - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -422,18 +422,18 @@ void svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_15to32[dat & 0xffff]; p[x + 1] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); p[x] = video_15to32[dat & 0xffff]; p[x + 1] = video_15to32[dat >> 16]; } svga->ma += x << 1; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -451,24 +451,24 @@ void svga_render_15bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_15to32[dat & 0xffff]; p[x + 1] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); p[x + 2] = video_15to32[dat & 0xffff]; p[x + 3] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); p[x + 4] = video_15to32[dat & 0xffff]; p[x + 5] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); p[x + 6] = video_15to32[dat & 0xffff]; p[x + 7] = video_15to32[dat >> 16]; } svga->ma += x << 1; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -486,18 +486,18 @@ void svga_render_16bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; } svga->ma += x << 1; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -515,24 +515,24 @@ void svga_render_16bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); p[x + 2] = video_16to32[dat & 0xffff]; p[x + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); p[x + 4] = video_16to32[dat & 0xffff]; p[x + 5] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); p[x + 6] = video_16to32[dat & 0xffff]; p[x + 7] = video_16to32[dat >> 16]; } svga->ma += x << 1; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -553,7 +553,7 @@ void svga_render_24bpp_lowres(svga_t *svga) { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; } } @@ -573,21 +573,21 @@ 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 & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[x] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); p[x + 1] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); p[x + 2] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vrammask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); p[x + 3] = dat & 0xffffff; svga->ma += 12; } - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -608,7 +608,7 @@ void svga_render_32bpp_lowres(svga_t *svga) { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; } } @@ -630,11 +630,11 @@ void svga_render_32bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = dat & 0xffffff; } svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -652,11 +652,11 @@ void svga_render_ABGR8888_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } @@ -674,10 +674,10 @@ void svga_render_RGBA8888_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vrammask]); + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = dat >> 8; } svga->ma += 4; - svga->ma &= svga->vrammask; + svga->ma &= svga->vram_display_mask; } } diff --git a/src/vid_tvga.c b/src/vid_tvga.c index a5c6ae6..9d24c8b 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -128,7 +128,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) switch (svga->crtcreg) { case 0x1e: - svga->vrammask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; + svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; break; } return; From 4a489dab1b14a922925d660c2f6133074be166d9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Oct 2017 12:41:38 +0100 Subject: [PATCH 0187/1050] Remove 512kb configuration from Trio64 - this is not actually supported by the chip. --- src/vid_s3.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 653eb76..438e2ef 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2495,10 +2495,6 @@ static device_config_t s3_phoenix_trio64_config[] = .type = CONFIG_SELECTION, .selection = { - { - .description = "512 KB", - .value = 0 - }, { .description = "1 MB", .value = 1 From 7d484e0928efd88f391bf4c2dc15a775f34995f0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 25 Oct 2017 20:53:32 +0100 Subject: [PATCH 0188/1050] Mask off accesses to SDAC extended registers. Fixes out-of-bounds register writes causing corruption seen sometimes in Windows 95. --- src/vid_sdac_ramdac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index 0098d60..c02eed4 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -50,8 +50,8 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t * ramdac->magic_count = 0; if (ramdac->rs2) { - if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val; - else ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8); + if (!ramdac->reg_ff) ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 0xff00) | val; + else ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 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++; @@ -106,8 +106,8 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) // } if (ramdac->rs2) { - if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff; - else temp = ramdac->regs[ramdac->rindex] >> 8; + if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex & 0xff] & 0xff; + else temp = ramdac->regs[ramdac->rindex & 0xff] >> 8; ramdac->reg_ff = !ramdac->reg_ff; if (!ramdac->reg_ff) { From 4974c9cfb1974d3c4db0a5c1b49ff628d6d7c457 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 25 Oct 2017 21:09:03 +0100 Subject: [PATCH 0189/1050] Use standard VGA RAMDAC on Trio32/64 instead of SDAC - the internal Trio RAMDAC does not implement any extended registers. --- src/vid_s3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 438e2ef..b6aa40f 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -798,7 +798,10 @@ 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); - sdac_ramdac_out(addr, val, &s3->ramdac, svga); + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + svga_out(addr, val, svga); + else + sdac_ramdac_out(addr, val, &s3->ramdac, svga); return; case 0x3D4: @@ -933,6 +936,8 @@ 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_TRIO32 || s3->chip == S3_TRIO64) + return svga_in(addr, svga); return sdac_ramdac_in(addr, &s3->ramdac, svga); case 0x3d4: From c0f948931a0991bca42cddb6921190cfa27a7780 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 27 Oct 2017 22:15:42 +0100 Subject: [PATCH 0190/1050] Added segment limit checking to opcodes A0 & A1. Fixes all hanging with Trio64 in Windows 95. --- src/x86_ops_mov.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index bdd968c..64072bf 100644 --- a/src/x86_ops_mov.h +++ b/src/x86_ops_mov.h @@ -250,7 +250,9 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) static int opMOV_AL_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); - uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint8_t temp; + CHECK_READ(cpu_state.ea_seg, addr, addr); + 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); @@ -259,7 +261,9 @@ static int opMOV_AL_a16(uint32_t fetchdat) static int opMOV_AL_a32(uint32_t fetchdat) { uint32_t addr = getlong(); - uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint8_t temp; + CHECK_READ(cpu_state.ea_seg, addr, addr); + 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); @@ -268,7 +272,9 @@ static int opMOV_AL_a32(uint32_t fetchdat) static int opMOV_AX_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); - uint16_t temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint16_t temp; + CHECK_READ(cpu_state.ea_seg, addr, addr+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); @@ -277,7 +283,9 @@ static int opMOV_AX_a16(uint32_t fetchdat) static int opMOV_AX_a32(uint32_t fetchdat) { uint32_t addr = getlong(); - uint16_t temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint16_t temp; + CHECK_READ(cpu_state.ea_seg, addr, addr+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); @@ -286,7 +294,9 @@ static int opMOV_AX_a32(uint32_t fetchdat) static int opMOV_EAX_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); - uint32_t temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint32_t temp; + CHECK_READ(cpu_state.ea_seg, addr, addr+3); + 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); @@ -295,7 +305,9 @@ static int opMOV_EAX_a16(uint32_t fetchdat) static int opMOV_EAX_a32(uint32_t fetchdat) { uint32_t addr = getlong(); - uint32_t temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint32_t temp; + CHECK_READ(cpu_state.ea_seg, addr, addr+3); + 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); From 4747d90702b30748fbc89365593bded0cc75c51a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 28 Oct 2017 15:07:24 +0100 Subject: [PATCH 0191/1050] Fix PCI mapping on ET4000W32/p. --- src/vid_et4000w32.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 201701b..1775977 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -1085,7 +1085,6 @@ 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; // pclog("ET4000 PCI read %08X\n", addr); @@ -1110,8 +1109,8 @@ uint8_t et4000w32p_pci_read(int func, int addr, void *p) case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return svga->crtc[0x5a] & 0x80; - case 0x13: return svga->crtc[0x59]; + case 0x12: return 0x00; + case 0x13: return et4000->pci_regs[0x13]; case 0x30: return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; @@ -1137,7 +1136,8 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x13: - et4000->linearbase = val << 24; + et4000->linearbase = val << 24; + et4000->pci_regs[0x13] = val; et4000w32p_recalcmapping(et4000); break; From 65a9d17674da8a26e6b43a8a0072d444a9fceeee Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 28 Oct 2017 16:03:44 +0100 Subject: [PATCH 0192/1050] Toshiba T3100e improvements : * Enables [Fn]+key combinations (using right-Ctrl or right-Alt as [Fn]). In particular: * Implements switching the built-in display adapter between the 'internal' plasma display ([Fn]+[Home]) and an 'external' CGA monitor ([Fn]+[End]) * Allows the video font to be toggled between thin and thick ([Fn]+[Right arrow]). * Implements the four hardware fonts of the original, selectable in BIOS setup. * Implements CRTC register 12h (attribute mapping and display type) Patch from John Elliott --- src/keyboard_at.c | 42 +++++++ src/t3100e.c | 19 ++- src/t3100e.h | 2 + src/vid_cga.c | 8 +- src/vid_cga.h | 1 + src/vid_t3100e.c | 288 ++++++++++++++++++++++++++++++++-------------- src/vid_t3100e.h | 1 + src/video.c | 48 +++++--- src/video.h | 4 +- 9 files changed, 297 insertions(+), 116 deletions(-) create mode 100644 src/t3100e.h diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 9fd4050..4866c89 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -5,6 +5,7 @@ #include "pit.h" #include "sound.h" #include "sound_speaker.h" +#include "t3100e.h" #include "timer.h" #include "x86.h" @@ -138,6 +139,29 @@ void keyboard_at_adddata_keyboard(uint8_t val) if (key_1c == 4) output = 3; }*/ + + /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ + if (romset == ROM_T3100E && (pcem_key[0xb8] || pcem_key[0x9d])) + { + switch (val) + { + case 0x4f: t3100e_notify_set(0x01); break; /* End */ + case 0x50: t3100e_notify_set(0x02); break; /* Down */ + case 0x51: t3100e_notify_set(0x03); break; /* PgDn */ + case 0x52: t3100e_notify_set(0x04); break; /* Ins */ + case 0x53: t3100e_notify_set(0x05); break; /* Del */ + case 0x54: t3100e_notify_set(0x06); break; /* SysRQ */ + case 0x45: t3100e_notify_set(0x07); break; /* NumLock */ + case 0x46: t3100e_notify_set(0x08); break; /* ScrLock */ + case 0x47: t3100e_notify_set(0x09); break; /* Home */ + case 0x48: t3100e_notify_set(0x0A); break; /* Up */ + case 0x49: t3100e_notify_set(0x0B); break; /* PgUp */ + case 0x4A: t3100e_notify_set(0x0C); break; /* Keypad -*/ + case 0x4B: t3100e_notify_set(0x0D); break; /* Left */ + case 0x4C: t3100e_notify_set(0x0E); break; /* KP 5 */ + case 0x4D: t3100e_notify_set(0x0F); break; /* Right */ + } + } key_queue[key_queue_end] = val; key_queue_end = (key_queue_end + 1) & 0xf; // pclog("keyboard_at : %02X added to key queue\n", val); @@ -397,6 +421,24 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) } else keyboard_at_adddata(0x00); break; + + /* For the T3100e, 0xB0 is 'turbo on' and 0xB1 is + * 'turbo off' */ + + case 0xb2: /* T3100e: Select external display */ + if (romset == ROM_T3100E) + t3100e_display_set(0x00); + break; + + case 0xb3: /* T3100e: Select internal display */ + if (romset == ROM_T3100E) + t3100e_display_set(0x01); + break; + + case 0xbc: /* T3100e: Reset Fn+Key notification */ + if (romset == ROM_T3100E) + t3100e_notify_set(0x00); + break; case 0xc0: /*Read input port*/ keyboard_at_adddata(keyboard_at.input_port | 4); diff --git a/src/t3100e.c b/src/t3100e.c index 4f03b83..ebfbb8e 100644 --- a/src/t3100e.c +++ b/src/t3100e.c @@ -5,6 +5,7 @@ #include "mouse.h" #include "mem.h" #include "device.h" +#include "t3100e.h" #include "vid_t3100e.h" /* The Toshiba 3100e is a 286-based portable. @@ -156,7 +157,7 @@ struct t3100e_ems_regs uint8_t upper_pages; /* Pages of EMS available from upper RAM */ uint8_t upper_is_ems; /* Upper RAM is EMS? */ mem_mapping_t upper_mapping; - + uint8_t notify; } t3100e_ems; void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); @@ -335,6 +336,7 @@ void t3100e_map_ram(uint8_t val) mem_size * 1024, upper_len); mem_mapping_enable(&t3100e_ems.upper_mapping); + mem_mapping_set_exec(&t3100e_ems.upper_mapping, ram + t3100e_ems.upper_base); } else { @@ -351,13 +353,21 @@ void t3100e_map_ram(uint8_t val) } +void t3100e_notify_set(uint8_t value) +{ + t3100e_ems.notify = value; +} + + uint8_t t3100e_sys_in(uint16_t addr, void *p) { -// struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; - /* XXX Not implemented. Seems to return 0x0C on real hardware */ + /* The low 4 bits always seem to be 0x0C. The high 4 are a + * notification sent by the keyboard controller when it detects + * an [Fn] key combination */ if (t3100e_log) pclog("IN 0x8084\n"); - return 0x0C; + return 0x0C | (regs->notify << 4); } @@ -411,6 +421,7 @@ void t3100e_ems_out(uint16_t addr, uint8_t val, void *p) if (t3100e_log) pclog("Enabling EMS RAM at %05x\n", page_to_addr(pg)); mem_mapping_enable(®s->mapping[pg]); + mem_mapping_set_exec(®s->mapping[pg], ram + regs->page_exec[pg]); } else { diff --git a/src/t3100e.h b/src/t3100e.h new file mode 100644 index 0000000..d0ada48 --- /dev/null +++ b/src/t3100e.h @@ -0,0 +1,2 @@ +void t3100e_notify_set(uint8_t value); +void t3100e_display_set(uint8_t value); diff --git a/src/vid_cga.c b/src/vid_cga.c index 59aa6ef..eb1e8cf 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -187,12 +187,12 @@ void cga_poll(void *p) if (drawcursor) { for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } cga->ma++; } @@ -221,13 +221,13 @@ void cga_poll(void *p) { for (c = 0; c < 8; c++) ((uint32_t *)buffer32->line[cga->displine])[(x << 4)+(c << 1) + 8] = - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } diff --git a/src/vid_cga.h b/src/vid_cga.h index db4355b..7594bf1 100644 --- a/src/vid_cga.h +++ b/src/vid_cga.h @@ -9,6 +9,7 @@ typedef struct cga_t uint8_t cgamode, cgacol; + int fontbase; int linepos, displine; int sc, vc; int cgadispon; diff --git a/src/vid_t3100e.c b/src/vid_t3100e.c index 94078e0..fcd1227 100644 --- a/src/vid_t3100e.c +++ b/src/vid_t3100e.c @@ -7,6 +7,7 @@ #include "mem.h" #include "timer.h" #include "video.h" +#include "vid_cga.h" #include "vid_t3100e.h" #define T3100E_XSIZE 640 @@ -29,6 +30,7 @@ void updatewindowsize(int x, int y); /* Mapping of attributes to colours */ static uint32_t amber, black; +static uint8_t boldcols[256]; /* Which attributes use the bold font */ static uint32_t blinkcols[256][2]; static uint32_t normcols[256][2]; @@ -40,34 +42,37 @@ static uint32_t normcols[256][2]; * Bits 0,1: Font set (not currently implemented) */ static uint8_t st_video_options; +static uint8_t st_display_internal = -1; void t3100e_video_options_set(uint8_t options) { st_video_options = options; } +void t3100e_display_set(uint8_t internal) +{ + st_display_internal = internal; +} + typedef struct t3100e_t { mem_mapping_t mapping; - uint8_t cga_crtc[32]; /* The CRTC as the host PC sees it. Most - * of the registers are ignored by the plasma - * display. */ - int cga_crtcreg; /* Current CRTC register */ - uint8_t cga_ctrl; /* CGA control register */ - uint8_t cga_colour; /* CGA colour register */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + cga_t cga; /* The CGA is used for the external + * display; most of its registers are + * ignored by the plasma display. */ int font; /* Current font, 0-3 */ int enabled; /* Hardware enabled, 0 or 1 */ + int internal; /* Using internal display? */ + uint8_t attrmap; /* Attribute mapping register */ int dispontime, dispofftime; - int vidtime; int linepos, displine; int vc; - int dispon, blink; + int dispon; int vsynctime; uint8_t video_options; @@ -78,6 +83,7 @@ typedef struct t3100e_t void t3100e_recalctimings(t3100e_t *t3100e); void t3100e_write(uint32_t addr, uint8_t val, void *p); uint8_t t3100e_read(uint32_t addr, void *p); +void t3100e_recalcattrs(t3100e_t *t3100e); void t3100e_out(uint16_t addr, uint8_t val, void *p) @@ -87,23 +93,31 @@ void t3100e_out(uint16_t addr, uint8_t val, void *p) { /* Emulated CRTC, register select */ case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - t3100e->cga_crtcreg = val & 31; + cga_out(addr, val, &t3100e->cga); break; /* Emulated CRTC, value */ case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - t3100e->cga_crtc[t3100e->cga_crtcreg] = val; + /* Register 0x12 controls the attribute mappings for the + * plasma screen. */ + if (t3100e->cga.crtcreg == 0x12) + { + t3100e->attrmap = val; + t3100e_recalcattrs(t3100e); + return; + } + cga_out(addr, val, &t3100e->cga); t3100e_recalctimings(t3100e); return; /* CGA control register */ case 0x3D8: - t3100e->cga_ctrl = val; + cga_out(addr, val, &t3100e->cga); return; /* CGA colour register */ case 0x3D9: - t3100e->cga_colour = val; + cga_out(addr, val, &t3100e->cga); return; } } @@ -111,20 +125,20 @@ void t3100e_out(uint16_t addr, uint8_t val, void *p) uint8_t t3100e_in(uint16_t addr, void *p) { t3100e_t *t3100e = (t3100e_t *)p; + uint8_t val; + switch (addr) { - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - return t3100e->cga_crtcreg; - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - return t3100e->cga_crtc[t3100e->cga_crtcreg]; - case 0x3d8: - return t3100e->cga_ctrl; - case 0x3d9: - return t3100e->cga_colour; - case 0x3da: - return t3100e->cga_stat; - } - return 0xff; + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + if (t3100e->cga.crtcreg == 0x12) + { + val = t3100e->attrmap & 0x0F; + if (t3100e->internal) val |= 0x30; /* Plasma / CRT */ + return val; + } + } + + return cga_in(addr, &t3100e->cga); } @@ -159,6 +173,11 @@ void t3100e_recalctimings(t3100e_t *t3100e) double disptime; double _dispontime, _dispofftime; + if (!t3100e->internal) + { + cga_recalctimings(&t3100e->cga); + return; + } disptime = 651; _dispontime = 640; _dispofftime = disptime - _dispontime; @@ -179,42 +198,39 @@ void t3100e_text_row80(t3100e_t *t3100e) int blink; uint16_t addr; uint8_t sc; - uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga_crtc[15] | (t3100e->cga_crtc[14] << 8)) & 0x7fff; + uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; + uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; sc = (t3100e->displine) & 15; addr = ((ma & ~1) + (t3100e->displine >> 4) * 80) * 2; ma += (t3100e->displine >> 4) * 80; - if ((t3100e->cga_crtc[10] & 0x60) == 0x20) + if ((t3100e->cga.crtc[10] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((t3100e->cga_crtc[10] & 0x0F)*2 <= sc) && - ((t3100e->cga_crtc[11] & 0x0F)*2 >= sc); + cursorline = ((t3100e->cga.crtc[10] & 0x0F)*2 <= sc) && + ((t3100e->cga.crtc[11] & 0x0F)*2 >= sc); } for (x = 0; x < 80; x++) { chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; drawcursor = ((ma == ca) && cursorline && - (t3100e->cga_ctrl & 8) && (t3100e->blink & 16)); + (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); - blink = ((t3100e->blink & 16) && (t3100e->cga_ctrl & 0x20) && + blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - /* XXX We should also be taking account of bits 0,1 of - * options to select one of the four ROM character sets; - * but these are not currently emulated. */ - if (t3100e->video_options & 4) - bold = (attr & 8) ? chr + 256 : chr; + bold = boldcols[attr] ? chr + 256 : chr; else - bold = (attr & 8) ? chr : chr + 256; + bold = boldcols[attr] ? chr : chr + 256; + bold += 512 * (t3100e->video_options & 3); - if (t3100e->cga_ctrl & 0x20) /* Blink */ + if (t3100e->cga.cgamode & 0x20) /* Blink */ { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; @@ -253,37 +269,38 @@ void t3100e_text_row40(t3100e_t *t3100e) int blink; uint16_t addr; uint8_t sc; - uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga_crtc[15] | (t3100e->cga_crtc[14] << 8)) & 0x7fff; + uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; + uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; sc = (t3100e->displine) & 15; addr = ((ma & ~1) + (t3100e->displine >> 4) * 40) * 2; ma += (t3100e->displine >> 4) * 40; - if ((t3100e->cga_crtc[10] & 0x60) == 0x20) + if ((t3100e->cga.crtc[10] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((t3100e->cga_crtc[10] & 0x0F)*2 <= sc) && - ((t3100e->cga_crtc[11] & 0x0F)*2 >= sc); + cursorline = ((t3100e->cga.crtc[10] & 0x0F)*2 <= sc) && + ((t3100e->cga.crtc[11] & 0x0F)*2 >= sc); } for (x = 0; x < 40; x++) { chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; drawcursor = ((ma == ca) && cursorline && - (t3100e->cga_ctrl & 8) && (t3100e->blink & 16)); + (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); - blink = ((t3100e->blink & 16) && (t3100e->cga_ctrl & 0x20) && + blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); if (t3100e->video_options & 4) - bold = (attr & 8) ? chr + 256 : chr; - else bold = (attr & 8) ? chr : chr + 256; + bold = boldcols[attr] ? chr + 256 : chr; + else bold = boldcols[attr] ? chr : chr + 256; + bold += 512 * (t3100e->video_options & 3); - if (t3100e->cga_ctrl & 0x20) /* Blink */ + if (t3100e->cga.cgamode & 0x20) /* Blink */ { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; @@ -324,12 +341,12 @@ void t3100e_cgaline6(t3100e_t *t3100e) uint8_t dat; uint32_t ink = 0; uint16_t addr; - uint32_t fg = (t3100e->cga_colour & 0x0F) ? amber : black; + uint32_t fg = (t3100e->cga.cgacol & 0x0F) ? amber : black; uint32_t bg = black; - uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; + uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - if (t3100e->cga_crtc[9] == 3) /* 640*400 */ + if (t3100e->cga.crtc[9] == 3) /* 640*400 */ { addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + @@ -350,7 +367,7 @@ void t3100e_cgaline6(t3100e_t *t3100e) for (c = 0; c < 8; c++) { ink = (dat & 0x80) ? fg : bg; - if (!(t3100e->cga_ctrl & 8)) ink = black; + if (!(t3100e->cga.cgamode & 8)) ink = black; ((uint32_t *)buffer32->line[t3100e->displine])[x*8+c] = ink; dat = dat << 1; } @@ -367,8 +384,8 @@ void t3100e_cgaline4(t3100e_t *t3100e) uint32_t ink0, ink1; uint16_t addr; - uint16_t ma = (t3100e->cga_crtc[13] | (t3100e->cga_crtc[12] << 8)) & 0x7fff; - if (t3100e->cga_crtc[9] == 3) /* 320*400 undocumented */ + uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; + if (t3100e->cga.crtc[9] == 3) /* 320*400 undocumented */ { addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + @@ -389,7 +406,7 @@ void t3100e_cgaline4(t3100e_t *t3100e) for (c = 0; c < 4; c++) { pattern = (dat & 0xC0) >> 6; - if (!(t3100e->cga_ctrl & 8)) pattern = 0; + if (!(t3100e->cga.cgamode & 8)) pattern = 0; switch (pattern & 3) { @@ -439,12 +456,28 @@ void t3100e_poll(void *p) mem_mapping_disable(&t3100e->mapping); else mem_mapping_enable(&t3100e->mapping); + /* Set the font used for the external display */ + t3100e->cga.fontbase = (512 * (t3100e->video_options & 3)) + + ((t3100e->video_options & 4) ? 256 : 0); + } + /* Switch between internal plasma and external CRT display. */ + if (st_display_internal != -1 && st_display_internal != t3100e->internal) + { + t3100e->internal = st_display_internal; + t3100e_recalctimings(t3100e); + } + if (!t3100e->internal) + { + cga_poll(&t3100e->cga); + return; + } + if (!t3100e->linepos) { - t3100e->vidtime += t3100e->dispofftime; - t3100e->cga_stat |= 1; + t3100e->cga.vidtime += t3100e->dispofftime; + t3100e->cga.cgastat |= 1; t3100e->linepos = 1; if (t3100e->dispon) { @@ -454,14 +487,14 @@ void t3100e_poll(void *p) } /* Graphics */ - if (t3100e->cga_ctrl & 0x02) + if (t3100e->cga.cgamode & 0x02) { - if (t3100e->cga_ctrl & 0x10) + if (t3100e->cga.cgamode & 0x10) t3100e_cgaline6(t3100e); else t3100e_cgaline4(t3100e); } else - if (t3100e->cga_ctrl & 0x01) /* High-res text */ + if (t3100e->cga.cgamode & 0x01) /* High-res text */ { t3100e_text_row80(t3100e); } @@ -474,13 +507,13 @@ void t3100e_poll(void *p) /* Hardcode a fixed refresh rate and VSYNC timing */ if (t3100e->displine == 400) /* Start of VSYNC */ { - t3100e->cga_stat |= 8; + t3100e->cga.cgastat |= 8; t3100e->dispon = 0; } if (t3100e->displine == 416) /* End of VSYNC */ { t3100e->displine = 0; - t3100e->cga_stat &= ~8; + t3100e->cga.cgastat &= ~8; t3100e->dispon = 1; } } @@ -488,9 +521,9 @@ void t3100e_poll(void *p) { if (t3100e->dispon) { - t3100e->cga_stat &= ~1; + t3100e->cga.cgastat &= ~1; } - t3100e->vidtime += t3100e->dispontime; + t3100e->cga.vidtime += t3100e->dispontime; t3100e->linepos = 0; if (t3100e->displine == 400) @@ -511,55 +544,109 @@ void t3100e_poll(void *p) video_res_x = T3100E_XSIZE; video_res_y = T3100E_YSIZE; - if (t3100e->cga_ctrl & 0x02) + if (t3100e->cga.cgamode & 0x02) { - if (t3100e->cga_ctrl & 0x10) + if (t3100e->cga.cgamode & 0x10) video_bpp = 1; else video_bpp = 2; } else video_bpp = 0; - t3100e->blink++; + t3100e->cga.cgablink++; } } } -void *t3100e_init() + + +void t3100e_recalcattrs(t3100e_t *t3100e) { - int n; - t3100e_t *t3100e = malloc(sizeof(t3100e_t)); - memset(t3100e, 0, sizeof(t3100e_t)); + int n; - /* 32k video RAM */ - t3100e->vram = malloc(0x8000); - - timer_add(t3100e_poll, &t3100e->vidtime, TIMER_ALWAYS_ENABLED, t3100e); - - /* Occupy memory between 0xB8000 and 0xBFFFF */ - mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e); - /* Respond to CGA I/O ports */ - io_sethandler(0x03d0, 0x000c, t3100e_in, NULL, NULL, t3100e_out, NULL, NULL, t3100e); + /* val behaves as follows: + * Bit 0: Attributes 01-06, 08-0E are inverse video + * Bit 1: Attributes 01-06, 08-0E are bold + * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF + * are inverse video + * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF + * are bold */ /* Set up colours */ amber = makecol(0xf7, 0x7C, 0x34); black = makecol(0x17, 0x0C, 0x00); /* Initialise the attribute mapping. Start by defaulting everything - * to black on amber */ + * to black on amber, and with bold set by bit 3 */ for (n = 0; n < 256; n++) { + boldcols[n] = (n & 8) != 0; blinkcols[n][0] = normcols[n][0] = amber; blinkcols[n][1] = normcols[n][1] = black; } - /* Except 00-0F and 80-8F which are amber on black */ - for (n = 0; n < 16; n++) + + /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the + * passed value. Exclude x0 and x8, which are always black on + * amber. */ + for (n = 0x11; n <= 0xFF; n++) + { + if ((n & 7) == 0) continue; + if (t3100e->attrmap & 4) /* Inverse */ + { + blinkcols[n][0] = normcols[n][0] = amber; + blinkcols[n][1] = normcols[n][1] = black; + blinkcols[n+128][0] = normcols[n+128][0] = amber; + blinkcols[n+128][1] = normcols[n+128][1] = black; + } + else /* Normal */ + { + blinkcols[n][0] = normcols[n][0] = black; + blinkcols[n][1] = normcols[n][1] = amber; + blinkcols[n+128][0] = normcols[n+128][0] = black; + blinkcols[n+128][1] = normcols[n+128][1] = amber; + } + if (t3100e->attrmap & 8) boldcols[n] = 1; /* Bold */ + } + /* Set up the 01-0E range, controlled by bits 0 and 1 of the + * passed value. When blinking is enabled this also affects 81-8E. */ + for (n = 0x01; n <= 0x0E; n++) + { + if (n == 7) continue; + if (t3100e->attrmap & 1) + { + blinkcols[n][0] = normcols[n][0] = amber; + blinkcols[n][1] = normcols[n][1] = black; + blinkcols[n+128][0] = amber; + blinkcols[n+128][1] = black; + } + else + { + blinkcols[n][0] = normcols[n][0] = black; + blinkcols[n][1] = normcols[n][1] = amber; + blinkcols[n+128][0] = black; + blinkcols[n+128][1] = amber; + } + if (t3100e->attrmap & 2) boldcols[n] = 1; + } + /* Colours 07 and 0F are always amber on black. If blinking is + * enabled so are 87 and 8F. */ + for (n = 0x07; n <= 0x0F; n += 8) { blinkcols[n][0] = normcols[n][0] = black; blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n+128][0] = normcols[n+128][0] = black; - blinkcols[n+128][1] = normcols[n+128][1] = amber; + blinkcols[n+128][0] = black; + blinkcols[n+128][1] = amber; } - /* In the normal range, 00 11 22 .. FF are black */ + /* When not blinking, colours 81-8F are always amber on black. */ + for (n = 0x81; n <= 0x8F; n ++) + { + normcols[n][0] = black; + normcols[n][1] = amber; + boldcols[n] = (n & 0x08) != 0; + } + + + /* Finally do the ones which are solid black. These differ between + * the normal and blinking mappings */ for (n = 0; n <= 0xFF; n += 0x11) { normcols[n][0] = normcols[n][1] = black; @@ -570,9 +657,34 @@ void *t3100e_init() blinkcols[n][0] = blinkcols[n][1] = black; blinkcols[n+128][0] = blinkcols[n+128][1] = black; } +} + + +void *t3100e_init() +{ + t3100e_t *t3100e = malloc(sizeof(t3100e_t)); + memset(t3100e, 0, sizeof(t3100e_t)); + cga_init(&t3100e->cga); + + t3100e->internal = 1; + + /* 32k video RAM */ + t3100e->vram = malloc(0x8000); + + timer_add(t3100e_poll, &t3100e->cga.vidtime, TIMER_ALWAYS_ENABLED, t3100e); + + /* Occupy memory between 0xB8000 and 0xBFFFF */ + mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e); + /* Respond to CGA I/O ports */ + io_sethandler(0x03d0, 0x000c, t3100e_in, NULL, NULL, t3100e_out, NULL, NULL, t3100e); + + /* Default attribute mapping is 4 */ + t3100e->attrmap = 4; + t3100e_recalcattrs(t3100e); /* Start off in 80x25 text mode */ - t3100e->cga_stat = 0xF4; + t3100e->cga.cgastat = 0xF4; + t3100e->cga.vram = t3100e->vram; t3100e->enabled = 1; t3100e->video_options = 0xFF; return t3100e; diff --git a/src/vid_t3100e.h b/src/vid_t3100e.h index 107cef6..b09688c 100644 --- a/src/vid_t3100e.h +++ b/src/vid_t3100e.h @@ -1,3 +1,4 @@ extern device_t t3100e_device; void t3100e_video_options_set(uint8_t options); +void t3100e_display_set(uint8_t internal); diff --git a/src/video.c b/src/video.c index 784b155..aae872a 100644 --- a/src/video.c +++ b/src/video.c @@ -323,8 +323,8 @@ void video_init() BITMAP *buffer32; -uint8_t fontdat[256][8]; -uint8_t fontdatm[512][16]; +uint8_t fontdat[2048][8]; +uint8_t fontdatm[2048][16]; uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ @@ -420,22 +420,34 @@ void loadfont(char *s, int format) } break; case 5: /* Toshiba 3100e */ - for (c=0;c<256;c++) - { - fread(&fontdatm[c][8], 1, 8, f); - } - for (c=0;c<256;c++) - { - fread(&fontdatm[c+256][8], 1, 8, f); - } - for (c=0;c<256;c++) - { - fread(&fontdatm[c][0], 1, 8, f); - } - for (c=0;c<256;c++) - { - fread(&fontdatm[c+256][0], 1, 8, f); - } + for (d = 0; d < 2048; d += 512) /* Four languages... */ + { + for (c = d; c < d+256; c++) + { + fread(&fontdatm[c][8], 1, 8, f); + } + for (c = d+256; c < d+512; c++) + { + fread(&fontdatm[c][8], 1, 8, f); + } + for (c = d; c < d+256; c++) + { + fread(&fontdatm[c][0], 1, 8, f); + } + for (c = d+256; c < d+512; c++) + { + fread(&fontdatm[c][0], 1, 8, f); + } + fseek(f, 4096, SEEK_CUR); /* Skip blank section */ + for (c = d; c < d+256; c++) + { + fread(&fontdat[c][0], 1, 8, f); + } + for (c = d+256; c < d+512; c++) + { + fread(&fontdat[c][0], 1, 8, f); + } + } break; } diff --git a/src/video.h b/src/video.h index f4ca12a..36bf395 100644 --- a/src/video.h +++ b/src/video.h @@ -48,8 +48,8 @@ extern int egareads,egawrites; extern int fullchange; extern int changeframecount; -extern uint8_t fontdat[256][8]; -extern uint8_t fontdatm[512][16]; +extern uint8_t fontdat[2048][8]; +extern uint8_t fontdatm[2048][16]; extern uint32_t *video_15to32, *video_16to32; From e388086943635ac492f0426d22e69ae2acfe8e71 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 29 Oct 2017 16:07:46 +0000 Subject: [PATCH 0193/1050] Fixed a number of issues in Voodoo recompiler, fixes dark rendering in MiG-29 Fulcrum. --- src/vid_voodoo_codegen_x86.h | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index d146eb2..3c6d413 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1129,10 +1129,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0xc8); } - addbyte(0x66); /*PACKUSWB XMM3, XMM1*/ + addbyte(0xf3); /*MOVD XMM3, XMM1*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xd9); + addbyte(0x66); /*PACKUSWB XMM3, XMM3*/ addbyte(0x0f); addbyte(0x67); - addbyte(0xd9); + addbyte(0xdb); if (tca_sub_clocal_1) { addbyte(0x66); /*MOVD EBX, XMM3*/ @@ -1457,17 +1461,9 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xff); addbyte(0x66); /*PADDW XMM1, XMM4*/ addbyte(0x0f); - addbyte(0xfc); + addbyte(0xfd); addbyte(0xcc); } - if (tc_invert_output) - { - addbyte(0x66); /*PXOR XMM1, FF*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x0d); - addlong((uint32_t)&xmm_ff_w); - } addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ addbyte(0x0f); @@ -1481,6 +1477,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xc9); + if (tc_invert_output) + { + addbyte(0x66); /*PXOR XMM1, FF*/ + addbyte(0x0f); + addbyte(0xef); + addbyte(0x0d); + addlong((uint32_t)&xmm_ff_b); + } if (tca_zero_other) { @@ -1658,7 +1662,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); } - if (params->alphaMode & ((1 << 0) | (1 << 4))) + if ((params->alphaMode & ((1 << 0) | (1 << 4))) || (!(cc_mselect == 0 && cc_reverse_blend == 0) && (cc_mselect == CC_MSELECT_AOTHER || cc_mselect == CC_MSELECT_ALOCAL))) { /*EBX = a_other*/ switch (a_sel) From 0e028ca64c205881e9650274435e0966c2b9343b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 3 Nov 2017 21:09:41 +0000 Subject: [PATCH 0194/1050] Fixed typo in Voodoo recompiler, fixes crash in Powerslide. --- src/vid_voodoo_codegen_x86.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 3c6d413..f0c8a8b 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1208,7 +1208,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } - addbyte(0x8e); /*ADD EAX, 1*/ + addbyte(0x83); /*ADD EAX, 1*/ addbyte(0xc0); addbyte(1); addbyte(0x0f); /*IMUL EAX, EBX*/ From c14bacd7838013670d532ed379aeab891647d3e1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 3 Nov 2017 21:16:49 +0000 Subject: [PATCH 0195/1050] Added support for multiple texture base addresses on Voodoo. Fixes bad textures in Powerslide. --- src/vid_voodoo.c | 151 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 116 insertions(+), 35 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 311907d..d2a8b8b 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -169,6 +169,7 @@ typedef struct voodoo_params_t uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; uint32_t tex_base[2][LOD_MAX+2]; + uint32_t tex_end[2][LOD_MAX+2]; int tex_width[2]; int tex_w_mask[2][LOD_MAX+2]; int tex_w_nmask[2][LOD_MAX+2]; @@ -200,7 +201,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 addr_start[4], addr_end[4]; uint32_t *data; } texture_t; @@ -994,11 +995,12 @@ enum enum { - LOD_ODD = (1 << 18), - LOD_SPLIT = (1 << 19), - LOD_S_IS_WIDER = (1 << 20), - LOD_TMIRROR_S = (1 << 28), - LOD_TMIRROR_T = (1 << 29) + LOD_ODD = (1 << 18), + LOD_SPLIT = (1 << 19), + LOD_S_IS_WIDER = (1 << 20), + LOD_TMULTIBASEADDR = (1 << 24), + LOD_TMIRROR_S = (1 << 28), + LOD_TMIRROR_T = (1 << 29) }; enum { @@ -1157,6 +1159,7 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) int shift = 8; int lod; uint32_t base = voodoo->params.texBaseAddr[tmu]; + uint32_t offset = 0; int tex_lod = 0; if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) @@ -1173,6 +1176,8 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) height >>= 1; shift--; tex_lod++; + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) + base = voodoo->params.texBaseAddr1[tmu]; } for (lod = 0; lod <= LOD_MAX+1; lod++) @@ -1183,7 +1188,11 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) height = 1; if (shift < 0) shift = 0; - voodoo->params.tex_base[tmu][lod] = base; + voodoo->params.tex_base[tmu][lod] = base + offset; + if (voodoo->params.tformat[tmu] & 8) + voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2); + else + voodoo->params.tex_end[tmu][lod] = base + offset + (width * height); voodoo->params.tex_w_mask[tmu][lod] = width - 1; voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1); voodoo->params.tex_h_mask[tmu][lod] = height - 1; @@ -1195,9 +1204,9 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) { if (voodoo->params.tformat[tmu] & 8) - base += width * height * 2; + offset += width * height * 2; else - base += width * height; + offset += width * height; if (voodoo->params.tLOD[tmu] & LOD_SPLIT) { @@ -1213,6 +1222,25 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) shift--; tex_lod++; } + + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) + { + switch (tex_lod) + { + case 0: + base = voodoo->params.texBaseAddr[tmu]; + break; + case 1: + base = voodoo->params.texBaseAddr1[tmu]; + break; + case 2: + base = voodoo->params.texBaseAddr2[tmu]; + break; + default: + base = voodoo->params.texBaseAddr38[tmu]; + break; + } + } } } } @@ -1224,7 +1252,7 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) { - int c; + int c, d; int lod; int lod_min, lod_max; uint32_t addr = 0, addr_end; @@ -1251,10 +1279,15 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) else palette_checksum = 0; + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + addr = params->texBaseAddr1[tmu]; + else + addr = params->texBaseAddr[tmu]; + /*Try to find texture in cache*/ for (c = 0; c < TEX_CACHE_MAX; c++) { - if (voodoo->texture_cache[tmu][c].base == params->texBaseAddr[tmu] && + if (voodoo->texture_cache[tmu][c].base == addr && voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) { @@ -1283,12 +1316,16 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) c = voodoo->texture_last_removed; - voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; + + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; + else + voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; lod_min = (params->tLOD[tmu] >> 2) & 15; lod_max = (params->tLOD[tmu] >> 8) & 15; -// 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); +// pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); for (lod = lod_min; lod <= lod_max; lod++) { @@ -1520,13 +1557,51 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; else voodoo->texture_cache[tmu][c].palette_checksum = 0; - - 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; + + if (lod_min == 0) + { + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; + voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; + } + else + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; + + if (lod_min <= 1 && lod_max >= 1) + { + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; + voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; + } + else + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; + + if (lod_min <= 2 && lod_max >= 2) + { + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; + voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; + } + else + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; + + if (lod_max >= 3) + { + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; + voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; + } + else + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; + + + for (d = 0; d < 4; d++) + { + addr = voodoo->texture_cache[tmu][c].addr_start[d]; + addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + + if (addr_end != 0) + { + for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } + } params->tex_entry[tmu] = c; voodoo->texture_cache[tmu][c].refcount++; @@ -1543,23 +1618,31 @@ static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) { if (voodoo->texture_cache[tmu][c].base != -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)) + int d; + + for (d = 0; d < 4; d++) { + int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; + int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + + if (addr_end != 0) + { + 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])) - wait_for_idle = 1; + if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || + (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) + wait_for_idle = 1; - voodoo->texture_cache[tmu][c].base = -1; - } - else - { - for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + voodoo->texture_cache[tmu][c].base = -1; + } + else + { + for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } + } } } } @@ -2664,7 +2747,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->xend += state->dx2; } } - #ifndef NO_CODEGEN if (voodoo->use_recompiler) voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); @@ -2825,7 +2907,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->texel_count = 0; state->x = x; state->x2 = x2; - #ifndef NO_CODEGEN if (voodoo->use_recompiler) { From d497fb04fcad222cab2fdc21cd8a63b0556dae0e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 3 Nov 2017 21:17:24 +0000 Subject: [PATCH 0196/1050] Increase size of Voodoo texture cache to account for split LODs. Fixes crashes on emulator exit with some games (eg Powerslide). --- src/vid_voodoo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index d2a8b8b..3492c00 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -7582,12 +7582,12 @@ void *voodoo_card_init() for (c = 0; c < TEX_CACHE_MAX; c++) { - voodoo->texture_cache[0][c].data = malloc((256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1) * 4); + voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); voodoo->texture_cache[0][c].base = -1; /*invalid*/ voodoo->texture_cache[0][c].refcount = 0; if (voodoo->dual_tmus) { - voodoo->texture_cache[1][c].data = malloc((256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1) * 4); + voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); voodoo->texture_cache[1][c].base = -1; /*invalid*/ voodoo->texture_cache[1][c].refcount = 0; } From 3fa1e23cf5b3cef2b083e44980a6124c5d59348a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 Nov 2017 12:38:40 +0000 Subject: [PATCH 0197/1050] Fixed bugs in Voodoo recompiler. Fixes Descent Freespace. --- src/vid_voodoo_codegen_x86.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index f0c8a8b..417d86b 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1827,7 +1827,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0xf6); /*TEST state->tex_a, 0x80*/ addbyte(0x87); - addbyte(0x23); addlong(offsetof(voodoo_state_t, tex_a)); addbyte(0x80); addbyte(0x74);/*JZ !cc_localselect*/ @@ -1837,7 +1836,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x6e); addbyte(0x8e); addlong(offsetof(voodoo_params_t, color0)); - /*JMP +*/ + addbyte(0xeb); /*JMP +*/ + addbyte(8); /*!cc_localselect:*/ addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); From bc4f98d814a872f6367e09a66a8d35e31cfc1b34 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 Nov 2017 13:45:39 +0000 Subject: [PATCH 0198/1050] Changes to LaserXT/3 : - Changed LaserXT/3 processor to 8086. - Changed LaserXT/3's minimum memory size to 512KB and granularity to 128KB. - Changed EMS size granularity to 256KB on Laser Turbo XT and 512KB on LaserXT/3. Base memory size is calculated automatically. - The mem_set_mem_state() function call for above of 1MB is called only when the memory size is more than 1024KB. Patch from Greatpsycho. --- src/laserxt.c | 5 ++++- src/mem.c | 8 ++++++-- src/model.c | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/laserxt.c b/src/laserxt.c index d66c92b..361ced7 100644 --- a/src/laserxt.c +++ b/src/laserxt.c @@ -11,7 +11,9 @@ static int laserxt_ems_baseaddr_index = 0; static 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); + { + addr = (romset == ROM_LTXT ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)) + ((laserxt_emspage[(addr >> 14) & 3] & 0x0F) << 14) + ((laserxt_emspage[(addr >> 14) & 3] & 0x40) << 12) + (addr & 0x3FFF); + } return addr; } @@ -99,6 +101,7 @@ void laserxt_init() 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); + mem_mapping_set_addr(&ram_low_mapping, 0, romset == ROM_LTXT ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)); } for (i = 0; i < 4; i++) diff --git a/src/mem.c b/src/mem.c index 50ddcd7..65eeaa3 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2124,11 +2124,13 @@ 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); 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) + { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } 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); @@ -2215,11 +2217,13 @@ 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); 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) + { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } 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); diff --git a/src/model.c b/src/model.c index a0962bf..e8784a4 100644 --- a/src/model.c +++ b/src/model.c @@ -109,7 +109,6 @@ MODEL models[] = {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, - {"[8088] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, @@ -118,6 +117,7 @@ MODEL models[] = {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 0, 0, 512,1152, 128, xt_laserxt_init, NULL}, {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, From 363fc1b01c05c1dd4615d85736e1e3b2ec301ef4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 Nov 2017 14:53:19 +0000 Subject: [PATCH 0199/1050] Improve NE2000 interrupt handling. --- src/ne2000.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ne2000.c b/src/ne2000.c index 2d8795d..edafd26 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -415,7 +415,6 @@ uint16_t ne2000_dma_read(int io_len, void *p) if (ne2000->IMR.rdma_inte) { picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); } } @@ -465,7 +464,6 @@ void ne2000_dma_write(int io_len, void *p) if (ne2000->IMR.rdma_inte) { picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); } } } @@ -862,7 +860,6 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) if (ne2000->IMR.rdma_inte) { picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); //DEV_pic_raise_irq(ne2000->base_irq); } } @@ -1051,7 +1048,6 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) { pclog("tx irq retrigger\n"); picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); } break; } From 5af136bc61d86eac74eacabdb2f1b5e8cafa85cd Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 Nov 2017 15:00:10 +0000 Subject: [PATCH 0200/1050] Disable NE2000 debug output by default. --- src/ne2000.c | 112 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/src/ne2000.c b/src/ne2000.c index edafd26..3dcb63f 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -54,6 +54,8 @@ uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; #define NETBLOCKING 0 //we won't block our pcap +//#define NE2000_DEBUG + #ifdef _WIN32 static HINSTANCE net_hLib = 0; /* handle to DLL */ static char *net_lib_name = "wpcap.dll"; @@ -438,9 +440,9 @@ uint16_t ne2000_asic_read_w(uint16_t offset, void *p) retval = ne2000_chipmem_read_b(ne2000->remote_dma, ne2000); ne2000_dma_read(1, ne2000); } - +#ifdef NE2000_DEBUG pclog("asic read val=0x%04x\n", retval); - +#endif return retval; } @@ -471,9 +473,9 @@ void ne2000_dma_write(int io_len, void *p) void ne2000_asic_write_w(uint16_t offset, uint16_t value, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; - +#ifdef NE2000_DEBUG pclog("asic write val=0x%04x\n", value); - +#endif if (ne2000->remote_bytes == 0) return; if (ne2000->DCR.wdsize & 0x01) { @@ -521,10 +523,11 @@ void ne2000_reset_write(uint16_t offset, uint8_t value, void *p) uint8_t ne2000_read(uint16_t address, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; - - pclog("read addr %x\n", address); int ret = 0; - + +#ifdef NE2000_DEBUG + pclog("read addr %x\n", address); +#endif address &= 0xf; if (address == 0x00) @@ -534,15 +537,18 @@ uint8_t ne2000_read(uint16_t address, void *p) (ne2000->CR.tx_packet << 2) | (ne2000->CR.start << 1) | (ne2000->CR.stop)); +#ifdef NE2000_DEBUG pclog("read CR returns 0x%08x\n", ret); +#endif } else { switch (ne2000->CR.pgsel) { case 0x00: +#ifdef NE2000_DEBUG pclog("page 0 read from port %04x\n", address); - +#endif switch (address) { case 0x1: // CLDA0 @@ -568,7 +574,9 @@ uint8_t ne2000_read(uint16_t address, void *p) case 0x6: // FIFO // reading FIFO is only valid in loopback mode +#ifdef NE2000_DEBUG pclog("reading FIFO not supported yet\n"); +#endif return ne2000->fifo; case 0x7: // ISR @@ -588,11 +596,15 @@ uint8_t ne2000_read(uint16_t address, void *p) return ne2000->remote_dma >> 8; case 0xa: // reserved +#ifdef NE2000_DEBUG pclog("reserved read - page 0, 0xa\n"); +#endif return 0xff; case 0xb: // reserved +#ifdef NE2000_DEBUG pclog("reserved read - page 0, 0xb\n"); +#endif return 0xff; case 0xc: // RSR @@ -618,8 +630,9 @@ uint8_t ne2000_read(uint16_t address, void *p) return 0; case 0x01: +#ifdef NE2000_DEBUG pclog("page 1 read from port %04x\n", address); - +#endif switch (address) { case 0x1: // PAR0-5 @@ -631,7 +644,9 @@ uint8_t ne2000_read(uint16_t address, void *p) return ne2000->physaddr[address - 1]; case 0x7: // CURR +#ifdef NE2000_DEBUG pclog("returning current page: %02x\n", (ne2000->curr_page)); +#endif return ne2000->curr_page; case 0x8: // MAR0-7 @@ -648,8 +663,9 @@ uint8_t ne2000_read(uint16_t address, void *p) return 0; case 0x02: +#ifdef NE2000_DEBUG pclog("page 2 read from port %04x\n", address); - +#endif switch (address) { case 0x1: // PSTART @@ -677,7 +693,9 @@ uint8_t ne2000_read(uint16_t address, void *p) case 0x9: case 0xa: case 0xb: +#ifdef NE2000_DEBUG pclog("reserved read - page 2, 0x%02x\n", address); +#endif break; case 0xc: // RCR @@ -729,9 +747,9 @@ uint8_t ne2000_read(uint16_t address, void *p) void ne2000_write(uint16_t address, uint8_t value, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; - +#ifdef NE2000_DEBUG pclog("write address %x, val=%x\n", address, value); - +#endif address &= 0xf; // @@ -742,12 +760,15 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) // if (address == 0x00) { +#ifdef NE2000_DEBUG pclog("wrote 0x%02x to CR\n", value); - +#endif // Validate remote-DMA if ((value & 0x38) == 0x00) { +#ifdef NE2000_DEBUG pclog("CR write - invalid rDMA value 0\n"); +#endif value |= 0x20; /* dma_cmd == 4 is a safe default */ //value = 0x22; /* dma_cmd == 4 is a safe default */ } @@ -779,9 +800,11 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) ne2000->bound_ptr * 256; ne2000->remote_bytes = *((uint16_t*) & ne2000->mem[ne2000->bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]); +#ifdef NE2000_DEBUG pclog("Sending buffer #x%x length %d\n", ne2000->remote_start, ne2000->remote_bytes); +#endif } // Check for start-tx @@ -790,7 +813,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) // loopback mode if (ne2000->TCR.loop_cntl != 1) { +#ifdef NE2000_DEBUG pclog("Loop mode %d not supported.\n", ne2000->TCR.loop_cntl); +#endif } else { @@ -811,12 +836,13 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) else if (value & 0x04) { // start-tx and no loopback +#ifdef NE2000_DEBUG if (ne2000->CR.stop || !ne2000->CR.start) pclog("CR write - tx start, dev in reset\n"); if (ne2000->tx_bytes == 0) pclog("CR write - tx start, tx bytes == 0\n"); - +#endif // Send the packet to the system driver /* TODO: Transmit packet */ //BX_NE2K_THIS ethdev->sendpkt(& ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); @@ -824,13 +850,17 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) if (net_is_slirp) { slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); +#ifdef NE2000_DEBUG pclog("ne2000 slirp sending packet\n"); +#endif } #ifdef _WIN32 if(net_is_pcap && net_pcap!=NULL) { _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); +#ifdef NE2000_DEBUG pclog("ne2000 pcap sending packet\n"); +#endif } #endif ne2000_tx_event(value, ne2000); @@ -869,8 +899,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) switch (ne2000->CR.pgsel) { case 0x00: +#ifdef NE2000_DEBUG pclog("page 0 write to port %04x\n", address); - +#endif // It appears to be a common practice to use outw on page0 regs... switch (address) @@ -961,9 +992,10 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) case 0xc: // RCR // Check if the reserved bits are set +#ifdef NE2000_DEBUG if (value & 0xc0) pclog("RCR write, reserved bits set\n"); - +#endif // Set all other bit-fields ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); @@ -973,20 +1005,25 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) ne2000->RCR.monitor = ((value & 0x20) == 0x20); // Monitor bit is a little suspicious... +#ifdef NE2000_DEBUG if (value & 0x20) pclog("RCR write, monitor bit set!\n"); +#endif break; case 0xd: // TCR // Check reserved bits +#ifdef NE2000_DEBUG if (value & 0xe0) pclog("TCR write, reserved bits set\n"); - +#endif // Test loop mode (not supported) if (value & 0x06) { ne2000->TCR.loop_cntl = (value & 0x6) >> 1; +#ifdef NE2000_DEBUG pclog("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); +#endif } else ne2000->TCR.loop_cntl = 0; @@ -995,7 +1032,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) if (value & 0x01) { //fatal("ne2000 TCR write, inhibit-CRC not supported\n"); +#ifdef NE2000_DEBUG pclog("ne2000 TCR write, inhibit-CRC not supported\n"); +#endif return; } @@ -1003,7 +1042,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) if (value & 0x08) { //fatal("ne2000 TCR write, auto transmit disable not supported\n"); +#ifdef NE2000_DEBUG pclog("ne2000 TCR write, auto transmit disable not supported\n"); +#endif } // Allow collision-offset to be set, although not used @@ -1012,6 +1053,7 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) case 0xe: // DCR // the loopback mode is not suppported yet +#ifdef NE2000_DEBUG if (!(value & 0x08)) pclog("DCR write, loopback mode selected\n"); @@ -1021,7 +1063,7 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) pclog("DCR write - LAS set ???\n"); if (value & 0x10) pclog("DCR write - AR set ???\n"); - +#endif // Set other values. ne2000->DCR.wdsize = ((value & 0x01) == 0x01); ne2000->DCR.endian = ((value & 0x02) == 0x02); @@ -1033,9 +1075,10 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) case 0xf: // IMR // Check for reserved bit +#ifdef NE2000_DEBUG if (value & 0x80) pclog("IMR write, reserved bit set\n"); - +#endif // Set other values ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); @@ -1046,7 +1089,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); if (ne2000->ISR.pkt_tx && ne2000->IMR.tx_inte) { +#ifdef NE2000_DEBUG pclog("tx irq retrigger\n"); +#endif picint(1 << ne2000->base_irq); } break; @@ -1054,7 +1099,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) break; case 0x01: +#ifdef NE2000_DEBUG pclog("page 1 w offset %04x\n", address); +#endif switch (address) { case 0x1: // PAR0-5 @@ -1084,9 +1131,10 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) break; case 0x02: +#ifdef NE2000_DEBUG if (address != 0) pclog("page 2 write ?\n"); - +#endif switch (address) { case 0x1: // CLDA0 @@ -1108,7 +1156,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) case 0x4: //fatal("page 2 write to reserved offset 4\n"); //OS/2 Warp can cause this to freak out. +#ifdef NE2000_DEBUG pclog("ne2000 page 2 write to reserved offset 4\n"); +#endif break; case 0x5: // Local Next-packet pointer @@ -1136,7 +1186,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) case 0xe: case 0xf: //fatal("page 2 write to reserved offset %0x\n", address); +#ifdef NE2000_DEBUG pclog("ne2000 page 2 write to reserved offset %0x\n", address); +#endif default: break; } @@ -1144,7 +1196,9 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) default: //fatal("ne2K: unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); +#ifdef NE2000_DEBUG pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); +#endif break; } } @@ -1198,9 +1252,10 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) uint8_t *startptr; static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; +#ifdef NE2000_DEBUG if(io_len != 60) pclog("rx_frame with length %d\n", io_len); - +#endif //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); @@ -1229,13 +1284,17 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) #endif ) { +#ifdef NE2000_DEBUG pclog("no space\n"); +#endif return; } if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) { +#ifdef NE2000_DEBUG pclog("rejected small packet, length %d\n", io_len); +#endif return; } // some computers don't care... @@ -1261,6 +1320,7 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) else if (0 != memcmp(buf, ne2000->physaddr, 6)) return; } +#ifdef NE2000_DEBUG else pclog("rx_frame promiscuous receive\n"); @@ -1268,7 +1328,7 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) 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]); - +#endif nextpage = ne2000->curr_page + pages; if (nextpage >= ne2000->page_stop) nextpage -= ne2000->page_stop - ne2000->page_start; @@ -1326,7 +1386,9 @@ void ne2000_tx_timer(void *p) { ne2000_t *ne2000 = (ne2000_t *)p; +#ifdef NE2000_DEBUG pclog("tx_timer\n"); +#endif ne2000->TSR.tx_ok = 1; // Generate an interrupt if not masked and not one in progress if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) @@ -1365,7 +1427,9 @@ static void ne2000_poller(void *p) return; } ne2000_rx_frame(ne2000,&qp->data,qp->len); +#ifdef NE2000_DEBUG pclog("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); +#endif free(qp); } fizz++; @@ -1388,7 +1452,9 @@ static void ne2000_poller(void *p) if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) return; +#ifdef NE2000_DEBUG pclog("ne2000 pcap received a frame %d bytes\n",h.caplen); +#endif ne2000_rx_frame(ne2000,data,h.caplen); } } @@ -1724,7 +1790,9 @@ void slirp_output (const unsigned char *pkt, int pkt_len) p->len=pkt_len; memcpy(p->data,pkt,pkt_len); QueueEnter(slirpq,p); +#ifdef NE2000_DEBUG pclog("ne2000 slirp_output %d @%d\n",pkt_len,p); +#endif } // Instead of calling this and crashing some times From b97d525e0cc8359598fd5b190d4a73eac071eb5b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 Nov 2017 15:42:04 +0000 Subject: [PATCH 0201/1050] Fix 8-bit RAMDAC palette handling. --- src/vid_svga.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index 6b45d84..072861f 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -151,9 +151,9 @@ void svga_out(uint16_t addr, uint8_t val, void *p) svga->dac_pos++; break; case 2: - svga->vgapal[svga->dac_write].r = svga->dac_r & 0x3f; - svga->vgapal[svga->dac_write].g = svga->dac_g & 0x3f; - svga->vgapal[svga->dac_write].b = val & 0x3f; + svga->vgapal[svga->dac_write].r = svga->dac_r; + svga->vgapal[svga->dac_write].g = svga->dac_g; + svga->vgapal[svga->dac_write].b = val; if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b); else @@ -243,14 +243,20 @@ uint8_t svga_in(uint16_t addr, void *p) { case 0: svga->dac_pos++; - return svga->vgapal[svga->dac_read].r; + if (svga->ramdac_type == RAMDAC_8BIT) + return svga->vgapal[svga->dac_read].r; + return svga->vgapal[svga->dac_read].r & 0x3f; case 1: svga->dac_pos++; - return svga->vgapal[svga->dac_read].g; + if (svga->ramdac_type == RAMDAC_8BIT) + return svga->vgapal[svga->dac_read].g; + return svga->vgapal[svga->dac_read].g & 0x3f; case 2: svga->dac_pos=0; svga->dac_read = (svga->dac_read + 1) & 255; - return svga->vgapal[(svga->dac_read - 1) & 255].b; + if (svga->ramdac_type == RAMDAC_8BIT) + return svga->vgapal[(svga->dac_read - 1) & 255].b; + return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; } break; case 0x3CC: From bb4fbdd9c24b3b488136c04cc955a8e9c94a14f9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 Nov 2017 17:17:58 +0000 Subject: [PATCH 0202/1050] Fixed >32 bit shifts on 808x CPUs. Fixes Titus the Fox. --- src/808x.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/808x.c b/src/808x.c index 793229e..971367e 100644 --- a/src/808x.c +++ b/src/808x.c @@ -2690,9 +2690,17 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?8:28); break; case 0x20: case 0x30: /*SHL b,CL*/ - if ((temp<<(c-1))&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; - temp<<=c; + if (c > 8) + { + temp = 0; + flags &= ~C_FLAG; + } + else + { + if ((temp<<(c-1))&0x80) flags|=C_FLAG; + else flags&=~C_FLAG; + temp<<=c; + } seteab(temp); setznp8(temp); cycles-=(c*4); @@ -2700,9 +2708,17 @@ void execx86(int cycs) flags|=A_FLAG; break; case 0x28: /*SHR b,CL*/ - if ((temp>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; - temp>>=c; + if (c > 8) + { + temp = 0; + flags &= ~C_FLAG; + } + else + { + if ((temp>>(c-1))&1) flags|=C_FLAG; + else flags&=~C_FLAG; + temp>>=c; + } seteab(temp); setznp8(temp); cycles-=(c*4); @@ -2827,9 +2843,17 @@ void execx86(int cycs) break; case 0x28: /*SHR w,CL*/ - if ((tempw>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; - tempw>>=c; + if (c > 16) + { + tempw = 0; + flags &= ~C_FLAG; + } + else + { + if ((tempw>>(c-1))&1) flags|=C_FLAG; + else flags&=~C_FLAG; + tempw>>=c; + } seteaw(tempw); setznp16(tempw); cycles-=(c*4); From f2e1e307c6fef5388ebe20936f59d50050ac53b5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 6 Nov 2017 21:38:07 +0000 Subject: [PATCH 0203/1050] Don't write directly to PC speaker state when writing PIT control byte. Fixes engine cacophony in Hard Drivin' II. --- src/pit.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pit.c b/src/pit.c index c6e96f8..af493a6 100644 --- a/src/pit.c +++ b/src/pit.c @@ -401,7 +401,6 @@ void pit_write(uint16_t addr, uint8_t val, void *p) pit->rl[t] = pit_read_timer(pit, t); } 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); From 4c42cc1596a2a499aad44e3ffd0a42922fbefb39 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 6 Nov 2017 22:10:32 +0000 Subject: [PATCH 0204/1050] Implement Headland fast reset. Fixes AMI 386SX clone. --- src/headland.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/headland.c b/src/headland.c index b4f460f..b3bc4d0 100644 --- a/src/headland.c +++ b/src/headland.c @@ -2,6 +2,7 @@ #include "io.h" #include "mem.h" #include "cpu.h" +#include "x86.h" #include "headland.h" @@ -12,6 +13,8 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) { if (addr & 1) { + uint8_t old_val = headland_regs[headland_index]; + if (headland_index == 0xc1 && !is486) val = 0; headland_regs[headland_index] = val; pclog("Headland write %02X %02X\n",headland_index,val); @@ -24,6 +27,11 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) else mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); } + else if (headland_index == 0x87) + { + if ((val & 1) && !(old_val & 1)) + softresetx86(); + } } else headland_index = val; From 170cf99ffb426d707bd9ea2a8df216239f4d5e69 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:16:40 +0000 Subject: [PATCH 0205/1050] Fix out-of-bounds array access in Mouse Systems mouse emulation. --- src/mouse_msystems.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mouse_msystems.c b/src/mouse_msystems.c index baa0aea..9424191 100644 --- a/src/mouse_msystems.c +++ b/src/mouse_msystems.c @@ -16,7 +16,7 @@ static void mouse_msystems_poll(int x, int y, int z, int b, void *p) { mouse_msystems_t *mouse = (mouse_msystems_t *)p; SERIAL *serial = mouse->serial; - uint8_t mousedat[4]; + uint8_t mousedat[5]; if (!x && !y && b == mouse->oldb) return; From 7c9bb73b57f939ba184e95b1a8e55b93610114d1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:20:16 +0000 Subject: [PATCH 0206/1050] Voodoo x86-64 recompiler now works correctly with addresses above 4GB. --- src/vid_voodoo_codegen_x86-64.h | 328 +++++++++++++++++++------------- 1 file changed, 193 insertions(+), 135 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 48935da..587e595 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -157,10 +157,11 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x89); /*MOV state->tex_s, EBX*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0x0f); /*MOVZX EAX, logtable[RAX]*/ + addbyte(0x41); /*MOVZX EAX, R9(logtable)[RAX]*/ + addbyte(0x0f); addbyte(0xb6); - addbyte(0x80); - addlong((uint32_t)(uintptr_t)logtable); + addbyte(0x04); + addbyte(0x01); addbyte(0x09); /*OR EAX, EDX*/ addbyte(0xd0); addbyte(0x03); /*ADD EAX, state->lod*/ @@ -334,11 +335,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(1); if (state->clamp_t[tmu]) { - addbyte(0x0f); /*CMOVS EDX, zero*/ + addbyte(0x41); /*CMOVS EDX, R10(alookup[0](zero))*/ + addbyte(0x0f); addbyte(0x48); - addbyte(0x14); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); + addbyte(0x12); addbyte(0x3b); /*CMP EDX, params->tex_h_mask[ESI]*/ addbyte(0x96); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -348,11 +348,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); addbyte(0x85); /*TEST EBX,EBX*/ addbyte(0xdb); - addbyte(0x0f); /*CMOVS EBX, zero*/ + addbyte(0x41); /*CMOVS EBX, R10(alookup[0](zero))*/ + addbyte(0x0f); addbyte(0x48); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); + addbyte(0x1a); addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -395,11 +394,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV ebp_store2, RSI*/ addbyte(0xb7); addlong(offsetof(voodoo_state_t, ebp_store)); - addbyte(0x0f); /*CMOVS EAX, zero*/ + addbyte(0x41); /*CMOVS EAX, R10(alookup[0](zero))*/ + addbyte(0x0f); addbyte(0x48); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); + addbyte(0x02); addbyte(0x78); /*JS + - clamp on 0*/ addbyte(2+3+2+ 5+5+2); addbyte(0x3b); /*CMP EAX, EBP*/ @@ -610,11 +608,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v { addbyte(0x85); /*TEST EAX, EAX*/ addbyte(0xc0); - addbyte(0x0f); /*CMOVS EAX, zero*/ + addbyte(0x41); /*CMOVS EAX, R10(alookup[0](zero))*/ + addbyte(0x0f); addbyte(0x48); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); + addbyte(0x02); addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI+ECX*4]*/ addbyte(0x84); addbyte(0x8e); @@ -637,11 +634,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v { addbyte(0x85); /*TEST EBX, EBX*/ addbyte(0xdb); - addbyte(0x0f); /*CMOVS EBX, zero*/ + addbyte(0x41); /*CMOVS EBX, R10(alookup[0](zero))*/ + addbyte(0x0f); addbyte(0x48); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&zero); + addbyte(0x1a); addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI+ECX*4]*/ addbyte(0x9c); addbyte(0x8e); @@ -707,11 +703,48 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x57); /*PUSH RDI*/ addbyte(0x56); /*PUSH RSI*/ addbyte(0x53); /*PUSH RBX*/ + addbyte(0x41); /*PUSH R12*/ + addbyte(0x54); + addbyte(0x41); /*PUSH R13*/ + addbyte(0x55); addbyte(0x41); /*PUSH R14*/ addbyte(0x56); addbyte(0x41); /*PUSH R15*/ addbyte(0x57); + addbyte(0x49); /*MOV R15, xmm_01_w*/ + addbyte(0xbf); + addquad((uint64_t)(uintptr_t)&xmm_01_w); + addbyte(0x66); /*MOVDQA XMM8, [R15]*/ + addbyte(0x45); + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x07 | (0 << 3)); + addbyte(0x49); /*MOV R15, xmm_ff_w*/ + addbyte(0xbf); + addquad((uint64_t)(uintptr_t)&xmm_ff_w); + addbyte(0x66); /*MOVDQA XMM9, [R15]*/ + addbyte(0x45); + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x07 | (1 << 3)); + addbyte(0x49); /*MOV R15, xmm_ff_b*/ + addbyte(0xbf); + addquad((uint64_t)(uintptr_t)&xmm_ff_b); + addbyte(0x66); /*MOVDQA XMM10, [R15]*/ + addbyte(0x45); + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x07 | (2 << 3)); + addbyte(0x49); /*MOV R15, minus_254*/ + addbyte(0xbf); + addquad((uint64_t)(uintptr_t)&minus_254); + addbyte(0x66); /*MOVDQA XMM11, [R15]*/ + addbyte(0x45); + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x07 | (3 << 3)); + #if WIN64 addbyte(0x48); /*MOV RDI, RCX (voodoo_state)*/ addbyte(0x89); @@ -723,13 +756,30 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x89); addbyte(0xce); #else - addbyte(0x49); /*MOV R9, RCX (real_y)*/ + addbyte(0x49); /*MOV R14, RCX (real_y)*/ addbyte(0x89); - addbyte(0xc9); + addbyte(0xce); addbyte(0x49); /*MOV R15, RSI (voodoo_state)*/ addbyte(0x89); addbyte(0xf7); #endif + + addbyte(0x49); /*MOV R9, logtable*/ + addbyte(0xb8 | (9 & 7)); + addquad((uint64_t)(uintptr_t)&logtable); + addbyte(0x49); /*MOV R10, alookup*/ + addbyte(0xb8 | (10 & 7)); + addquad((uint64_t)(uintptr_t)&alookup); + addbyte(0x49); /*MOV R11, aminuslookup*/ + addbyte(0xb8 | (11 & 7)); + addquad((uint64_t)(uintptr_t)&aminuslookup); + addbyte(0x49); /*MOV R12, xmm_00_ff_w*/ + addbyte(0xb8 | (12 & 7)); + addquad((uint64_t)(uintptr_t)&xmm_00_ff_w); + addbyte(0x49); /*MOV R13, i_00_ff_w*/ + addbyte(0xb8 | (13 & 7)); + addquad((uint64_t)(uintptr_t)&i_00_ff_w); + loop_jump_pos = block_pos; addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); @@ -1075,27 +1125,26 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) { - addbyte(0x66); /*PXOR XMM0, xmm_00_ff_w[EBX]*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0x83); - addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend_1) - { - addbyte(0x66); /*PXOR XMM0, xmm_ff_w*/ + addbyte(0x66); /*PXOR XMM0, R12(xmm_00_ff_w)[EBX]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xef); addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); + addbyte(0x1c); } - addbyte(0x66); /*PADDW XMM0, xmm_01_w*/ + else if (!tc_reverse_blend_1) + { + addbyte(0x66); /*PXOR XMM0, XMM9(xmm_ff_w)*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xef); + addbyte(0xc1); + } + addbyte(0x66); /*PADDW XMM0, XMM8(xmm_01_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_01_w); + addbyte(0xc0); addbyte(0xf3); /*MOVQ XMM1, XMM2*/ addbyte(0x0f); addbyte(0x7e); @@ -1213,10 +1262,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) { - addbyte(0x33); /*XOR EAX, i_00_ff_w[ECX*4]*/ - addbyte(0x04); + addbyte(0x41); /*XOR EAX, R13(i_00_ff_w)[ECX*4]*/ + addbyte(0x33); + addbyte(0x44); addbyte(0x8d); - addlong((uint32_t)(uintptr_t)i_00_ff_w); + addbyte(0); } else if (!tc_reverse_blend_1) { @@ -1399,27 +1449,26 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { - addbyte(0x66); /*PXOR XMM4, xmm_00_ff_w[EBX]*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xa3); - addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend) - { - addbyte(0x66); /*PXOR XMM4, FF*/ + addbyte(0x66); /*PXOR XMM4, R12(xmm_00_ff_w)[EBX]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xef); addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); + addbyte(0x1c); } - addbyte(0x66); /*PADDW XMM4, 1*/ + else if (!tc_reverse_blend) + { + addbyte(0x66); /*PXOR XMM4, XMM9(xmm_ff_w)*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xef); + addbyte(0xe1); + } + addbyte(0x66); /*PADDW XMM4, XMM8(xmm_01_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_01_w); + addbyte(0xe0); addbyte(0xf3); /*MOVQ XMM5, XMM1*/ addbyte(0x0f); addbyte(0x7e); @@ -1483,11 +1532,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } if (tc_invert_output) { - addbyte(0x66); /*PXOR XMM1, FF*/ + addbyte(0x66); /*PXOR XMM1, XMM9(xmm_ff_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xef); - addbyte(0x0d); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); + addbyte(0xc9); } addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ @@ -1581,10 +1630,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { - addbyte(0x33); /*XOR EBX, i_00_ff_w[ECX*4]*/ - addbyte(0x1c); + addbyte(0x41); /*XOR EBX, R13(i_00_ff_w)[ECX*4]*/ + addbyte(0x33); + addbyte(0x5c); addbyte(0x8d); - addlong((uint32_t)(uintptr_t)i_00_ff_w); + addbyte(0); } else if (!tca_reverse_blend) { @@ -2130,19 +2180,17 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe0); if (!cc_reverse_blend) { - addbyte(0x66); /*PXOR XMM3, 0xff*/ + addbyte(0x66); /*PXOR XMM3, XMM9(xmm_ff_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xef); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); + addbyte(0xd9); } - addbyte(0x66); /*PADDW XMM3, 1*/ + addbyte(0x66); /*PADDW XMM3, XMM8(xmm_01_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_01_w); + addbyte(0xd8); addbyte(0x66); /*PMULLW XMM0, XMM3*/ addbyte(0x0f); addbyte(0xd5); @@ -2181,12 +2229,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if (cc_invert_output) { - addbyte(0x66); /*PXOR XMM0, 0xff*/ + addbyte(0x66); /*PXOR XMM0, XMM10(xmm_ff_b)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xef); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_b); + addbyte(0xc2); } if (params->fogMode & FOG_ENABLE) @@ -2343,11 +2390,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xd5); - addbyte(0x1c); - addbyte(0xc5); - addlong(((uintptr_t)alookup) + 16); + addbyte(0x5c); + addbyte(0xc2); + addbyte(16); addbyte(0x66); /*PSRAW XMM3, 7*/ addbyte(0x0f); addbyte(0x71); @@ -2476,22 +2524,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe4); break; case AFUNC_ASRC_ALPHA: - addbyte(0x66); /*PMULLW XMM4, alookup[EDX*8]*/ + fatal("dest AFUNC_ASRC_ALPHA\n"); + addbyte(0x66); /*PMULLW XMM4, R10(alookup)[EDX*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xd5); addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)alookup); + addbyte(0xd2); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x62); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2508,6 +2557,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_A_COLOR: + fatal("dest AFUNC_A_COLOR\n"); addbyte(0x66); /*PMULLW XMM4, XMM0*/ addbyte(0x0f); addbyte(0xd5); @@ -2516,12 +2566,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x62); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2542,22 +2592,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo case AFUNC_AONE: break; case AFUNC_AOMSRC_ALPHA: - addbyte(0x66); /*PMULLW XMM4, aminuslookup[EDX*8]*/ + //fatal("dest AFUNC_AOMSRC_ALPHA\n"); + addbyte(0x66); /*PMULLW XMM4, R11(aminuslookup)[EDX*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xd5); addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)aminuslookup); + addbyte(0xd3); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x62); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2574,12 +2625,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_AOM_COLOR: - addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ + fatal("dest AFUNC_AOM_COLOR\n"); + addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0x7e); - addbyte(0x2c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); + addbyte(0xe9); addbyte(0x66); /*PSUBW XMM5, XMM0*/ addbyte(0x0f); addbyte(0xf9); @@ -2593,11 +2644,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xec); addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x62); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2620,22 +2671,22 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe4); break; case AFUNC_ASATURATE: - addbyte(0x66); /*PMULLW XMM4, minus_254*/ + fatal("dest AFUNC_ASATURATE\n"); + addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xd5); - addbyte(0x24); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)&minus_254); + addbyte(0xe3); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xec); addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x24); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x62); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2661,22 +2712,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); break; case AFUNC_ASRC_ALPHA: - addbyte(0x66); /*PMULLW XMM0, alookup[EDX*8]*/ + //fatal("src AFUNC_ASRC_ALPHA\n"); + addbyte(0x66); /*PMULLW XMM0, R10(alookup)[EDX*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xd5); addbyte(0x04); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)alookup); + addbyte(0xd2); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM0, R10(alookup)[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x42); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2693,6 +2745,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_A_COLOR: + //fatal("src AFUNC_A_COLOR\n"); addbyte(0x66); /*PMULLW XMM0, XMM6*/ addbyte(0x0f); addbyte(0xd5); @@ -2701,12 +2754,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xe8); - addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM0, R10(alookup)[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x42); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2727,22 +2780,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo case AFUNC_AONE: break; case AFUNC_AOMSRC_ALPHA: - addbyte(0x66); /*PMULLW XMM0, aminuslookup[EDX*8]*/ + fatal("src AFUNC_AOMSRC_ALPHA\n"); + addbyte(0x66); /*PMULLW XMM0, R11(aminuslookup)[EDX*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xd5); addbyte(0x04); - addbyte(0xd5); - addlong((uint32_t)(uintptr_t)aminuslookup); + addbyte(0xd3); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe8); addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x42); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2759,12 +2813,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_AOM_COLOR: - addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ + fatal("src AFUNC_AOM_COLOR\n"); + addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/ + addbyte(0x41); addbyte(0x0f); addbyte(0x7e); - addbyte(0x2c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&xmm_ff_w); + addbyte(0xe9); addbyte(0x66); /*PSUBW XMM5, XMM6*/ addbyte(0x0f); addbyte(0xf9); @@ -2778,11 +2832,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xe8); addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ + addbyte(0x41); addbyte(0x0f); addbyte(0xfd); - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)alookup + 16); + addbyte(0x42); + addbyte(8*2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -3233,6 +3287,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x5f); addbyte(0x41); /*POP R14*/ addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); addbyte(0x5b); /*POP RBX*/ addbyte(0x5e); /*POP RSI*/ addbyte(0x5f); /*POP RDI*/ From e8919433b24f00fb4006ea13fd903e93da9d5fd4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:20:35 +0000 Subject: [PATCH 0207/1050] Fix OpenAL include path on Mac OS X. --- src/soundopenal.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/soundopenal.c b/src/soundopenal.c index 5dd088f..d24334c 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -3,9 +3,14 @@ #include #include #ifdef USE_OPENAL +#ifdef __APPLE__ +#include +#include +#else #include #include #endif +#endif #include "ibm.h" #include "sound.h" From 64cb5f580f4dcdf143db4b5fc2d54d5b6ee71a11 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:21:20 +0000 Subject: [PATCH 0208/1050] Recompiler now works on Mac OS X. --- src/codegen_x86-64.c | 6 +++--- src/codegen_x86.c | 6 +++--- src/vid_voodoo_codegen_x86-64.h | 6 +++--- src/vid_voodoo_codegen_x86.h | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index 0c21a3a..b832a60 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -15,7 +15,7 @@ #include "codegen_ops.h" #include "codegen_ops_x86-64.h" -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) #include #include #endif @@ -63,7 +63,7 @@ void codegen_init() { int c; -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) void *start; size_t len; long pagesize = sysconf(_SC_PAGESIZE); @@ -83,7 +83,7 @@ void codegen_init() for (c = 0; c < BLOCK_SIZE; c++) codeblock[c].pc = BLOCK_PC_INVALID; -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock & pagemask); len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) diff --git a/src/codegen_x86.c b/src/codegen_x86.c index 688a363..b230074 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -15,7 +15,7 @@ #include "codegen_ops.h" #include "codegen_ops_x86.h" -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) #include #include #endif @@ -1124,7 +1124,7 @@ static uint32_t gen_MEM_CHECK_WRITE_L() void codegen_init() { int c; -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) void *start; size_t len; long pagesize = sysconf(_SC_PAGESIZE); @@ -1144,7 +1144,7 @@ void codegen_init() for (c = 0; c < BLOCK_SIZE; c++) codeblock[c].pc = BLOCK_PC_INVALID; -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock & pagemask); len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 587e595..fda8b3f 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -5,7 +5,7 @@ fbzColorPath */ -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) #include #include #endif @@ -3352,7 +3352,7 @@ voodoo_recomp++; static void voodoo_codegen_init(voodoo_t *voodoo) { int c; -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) void *start; size_t len; long pagesize = sysconf(_SC_PAGESIZE); @@ -3365,7 +3365,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2); #endif -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) start = (void *)((long)voodoo->codegen_data & pagemask); len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 417d86b..be4aad2 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -5,7 +5,7 @@ fbzColorPath */ -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) #include #include #endif @@ -3282,7 +3282,7 @@ voodoo_recomp++; static void voodoo_codegen_init(voodoo_t *voodoo) { int c; -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) void *start; size_t len; long pagesize = sysconf(_SC_PAGESIZE); @@ -3295,7 +3295,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); #endif -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) start = (void *)((long)voodoo->codegen_data & pagemask); len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM*2) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) From 43eabc727c71e3ebc396242ae201d7580f588948 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:23:01 +0000 Subject: [PATCH 0209/1050] Added OS X support to build system. --- Makefile.in | 13 +- aclocal.m4 | 60 +++---- configure | 412 +++++++++++++++++++++++++++++++----------------- configure.ac | 50 ++++-- src/Makefile.am | 12 +- src/Makefile.in | 119 ++++++++------ 6 files changed, 418 insertions(+), 248 deletions(-) diff --git a/Makefile.in b/Makefile.in index 903d123..ca54b6c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -308,7 +308,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -526,7 +525,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -552,7 +551,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -570,7 +569,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -580,7 +579,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/aclocal.m4 b/aclocal.m4 index 925cb54..f6be9fe 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,9 +20,9 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29) -dnl +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl @@ -63,7 +63,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29]) +[m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -164,7 +164,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -174,11 +174,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -195,7 +195,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -1591,7 +1591,7 @@ AC_DEFUN([AM_PATH_WXCONFIG], [ ]) AC_DEFUN([AM_PATH_WXRC], [WXRC_CHECK([$1],[$2])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1606,7 +1606,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -1622,14 +1622,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1681,7 +1681,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1712,7 +1712,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1903,7 +1903,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1979,7 +1979,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2176,7 +2176,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2197,7 +2197,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2218,7 +2218,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2268,7 +2268,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2307,7 +2307,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2336,7 +2336,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2383,7 +2383,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2402,7 +2402,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2483,7 +2483,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2543,7 +2543,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2571,7 +2571,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2590,7 +2590,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index 375d8c7..0c74530 100755 --- a/configure +++ b/configure @@ -588,6 +588,12 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +OS_MACOSX_FALSE +OS_MACOSX_TRUE +OS_WINDOWS_FALSE +OS_WINDOWS_TRUE +OS_LINUX_FALSE +OS_LINUX_TRUE WX_VERSION_MICRO WX_VERSION_MINOR WX_VERSION_MAJOR @@ -614,10 +620,6 @@ USE_NETWORKING_FALSE USE_NETWORKING_TRUE USE_WX_FALSE USE_WX_TRUE -OS_LINUX_FALSE -OS_LINUX_TRUE -OS_WIN_FALSE -OS_WIN_TRUE CPU_X86_64_FALSE CPU_X86_64_TRUE CPU_I386_FALSE @@ -699,7 +701,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -791,7 +792,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1044,15 +1044,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1190,7 +1181,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1343,7 +1334,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -4214,23 +4204,6 @@ fi #AC_MSG_CHECKING([for libz]) #AX_CHECK_ZLIB - if test "$OS" = "win"; then - OS_WIN_TRUE= - OS_WIN_FALSE='#' -else - OS_WIN_TRUE='#' - OS_WIN_FALSE= -fi - - if test "$OS" = "linux"; then - OS_LINUX_TRUE= - OS_LINUX_FALSE='#' -else - OS_LINUX_TRUE='#' - OS_LINUX_FALSE= -fi - - if test "$enable_wx" = "yes"; then USE_WX_TRUE= USE_WX_FALSE='#' @@ -4416,8 +4389,8 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 -$as_echo_n "checking for SDL... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 +$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -4457,7 +4430,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -4475,7 +4448,7 @@ fi sdl_pc=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } sdl_pc=no else @@ -5065,107 +5038,6 @@ if test "$wxWin" != 1; then " "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 -$as_echo_n "checking for glGetError in -lGL... " >&6; } -if ${ac_cv_lib_GL_glGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lGL $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char glGetError (); -int -main () -{ -return glGetError (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_GL_glGetError=yes -else - ac_cv_lib_GL_glGetError=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 -$as_echo "$ac_cv_lib_GL_glGetError" >&6; } -if test "x$ac_cv_lib_GL_glGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGL 1 -_ACEOF - - LIBS="-lGL $LIBS" - -else - \ - echo "You need to install the OpenGL library." - exit -1 -fi - -LIBS="$LIBS $WX_LIBS $SDL_LIBS" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 -$as_echo_n "checking for alGetError in -lopenal... " >&6; } -if ${ac_cv_lib_openal_alGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lopenal $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char alGetError (); -int -main () -{ -return alGetError (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_openal_alGetError=yes -else - ac_cv_lib_openal_alGetError=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 -$as_echo "$ac_cv_lib_openal_alGetError" >&6; } -if test "x$ac_cv_lib_openal_alGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBOPENAL 1 -_ACEOF - - LIBS="-lopenal $LIBS" - -else - \ - echo "You need to install the OpenAL library." - exit -1 -fi - - if test "$enable_alsa" == "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for snd_pcm_open in -lasound" >&5 $as_echo_n "checking for snd_pcm_open in -lasound... " >&6; } @@ -5263,6 +5135,247 @@ _ACEOF fi +build_macosx="no" +build_linux="no" +build_win="no" + +case "$host" in + *-*-darwin*) + LIBS="$LIBS -framework OpenGL" + LIBS="$LIBS -framework OpenAL" + build_macosx="yes" + ;; + *-*-cygwin* | *-*-mingw32*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +$as_echo_n "checking for glGetError in -lGL... " >&6; } +if ${ac_cv_lib_GL_glGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glGetError (); +int +main () +{ +return glGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_glGetError=yes +else + ac_cv_lib_GL_glGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +$as_echo "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGL 1 +_ACEOF + + LIBS="-lGL $LIBS" + +else + \ + echo "You need to install the OpenGL library." + exit -1 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +$as_echo_n "checking for alGetError in -lopenal... " >&6; } +if ${ac_cv_lib_openal_alGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopenal $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char alGetError (); +int +main () +{ +return alGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_openal_alGetError=yes +else + ac_cv_lib_openal_alGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +$as_echo "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBOPENAL 1 +_ACEOF + + LIBS="-lopenal $LIBS" + +else + \ + echo "You need to install the OpenAL library." + exit -1 +fi + + build_win="yes" + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +$as_echo_n "checking for glGetError in -lGL... " >&6; } +if ${ac_cv_lib_GL_glGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glGetError (); +int +main () +{ +return glGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_glGetError=yes +else + ac_cv_lib_GL_glGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +$as_echo "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGL 1 +_ACEOF + + LIBS="-lGL $LIBS" + +else + \ + echo "You need to install the OpenGL library." + exit -1 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +$as_echo_n "checking for alGetError in -lopenal... " >&6; } +if ${ac_cv_lib_openal_alGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopenal $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char alGetError (); +int +main () +{ +return alGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_openal_alGetError=yes +else + ac_cv_lib_openal_alGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +$as_echo "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBOPENAL 1 +_ACEOF + + LIBS="-lopenal $LIBS" + +else + \ + echo "You need to install the OpenAL library." + exit -1 +fi + + build_linux="yes" + ;; +esac + +LIBS="$LIBS $WX_LIBS $SDL_LIBS" + + if test "$build_linux" = "yes"; then + OS_LINUX_TRUE= + OS_LINUX_FALSE='#' +else + OS_LINUX_TRUE='#' + OS_LINUX_FALSE= +fi + + if test "$build_win" = "yes"; then + OS_WINDOWS_TRUE= + OS_WINDOWS_FALSE='#' +else + OS_WINDOWS_TRUE='#' + OS_WINDOWS_FALSE= +fi + + if test "$build_macosx" = "yes"; then + OS_MACOSX_TRUE= + OS_MACOSX_FALSE='#' +else + OS_MACOSX_TRUE='#' + OS_MACOSX_FALSE= +fi + + ac_config_files="$ac_config_files Makefile src/Makefile" cat >confcache <<\_ACEOF @@ -5446,14 +5559,6 @@ if test -z "${CPU_X86_64_TRUE}" && test -z "${CPU_X86_64_FALSE}"; then as_fn_error $? "conditional \"CPU_X86_64\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${OS_WIN_TRUE}" && test -z "${OS_WIN_FALSE}"; then - as_fn_error $? "conditional \"OS_WIN\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${OS_LINUX_TRUE}" && test -z "${OS_LINUX_FALSE}"; then - as_fn_error $? "conditional \"OS_LINUX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${USE_WX_TRUE}" && test -z "${USE_WX_FALSE}"; then as_fn_error $? "conditional \"USE_WX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -5466,6 +5571,18 @@ if test -z "${USE_ALSA_TRUE}" && test -z "${USE_ALSA_FALSE}"; then as_fn_error $? "conditional \"USE_ALSA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${OS_LINUX_TRUE}" && test -z "${OS_LINUX_FALSE}"; then + as_fn_error $? "conditional \"OS_LINUX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OS_WINDOWS_TRUE}" && test -z "${OS_WINDOWS_FALSE}"; then + as_fn_error $? "conditional \"OS_WINDOWS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${OS_MACOSX_TRUE}" && test -z "${OS_MACOSX_FALSE}"; then + as_fn_error $? "conditional \"OS_MACOSX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -6600,4 +6717,3 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi - diff --git a/configure.ac b/configure.ac index b7b3422..3e4688e 100644 --- a/configure.ac +++ b/configure.ac @@ -63,9 +63,6 @@ AM_CONDITIONAL(CPU_X86_64, test "$CPU" = "x86_64") #AC_MSG_CHECKING([for libz]) #AX_CHECK_ZLIB -AM_CONDITIONAL(OS_WIN, test "$OS" = "win") -AM_CONDITIONAL(OS_LINUX, test "$OS" = "linux") - AM_CONDITIONAL(USE_WX, test "$enable_wx" = "yes") AM_CONDITIONAL(USE_NETWORKING, test "$enable_networking" = "yes") AM_CONDITIONAL(USE_ALSA, test "$enable_alsa" = "yes") @@ -91,15 +88,6 @@ if test "$wxWin" != 1; then ]) fi -AC_CHECK_LIB([GL], [glGetError], [], \ - [echo "You need to install the OpenGL library." - exit -1]) -LIBS="$LIBS $WX_LIBS $SDL_LIBS" - -AC_CHECK_LIB([openal], [alGetError], [], \ - [echo "You need to install the OpenAL library." - exit -1]) - if test "$enable_alsa" == "yes"; then AC_CHECK_LIB(asound, snd_pcm_open, [], @@ -109,4 +97,40 @@ fi AC_CHECK_LIB([pthread], [pthread_create]) -AC_OUTPUT([Makefile src/Makefile]) +build_macosx="no" +build_linux="no" +build_win="no" + +case "$host" in + *-*-darwin*) + LIBS="$LIBS -framework OpenGL" + LIBS="$LIBS -framework OpenAL" + build_macosx="yes" + ;; + *-*-cygwin* | *-*-mingw32*) + AC_CHECK_LIB([GL], [glGetError], [], \ + [echo "You need to install the OpenGL library." + exit -1]) + AC_CHECK_LIB([openal], [alGetError], [], \ + [echo "You need to install the OpenAL library." + exit -1]) + build_win="yes" + ;; + *) + AC_CHECK_LIB([GL], [glGetError], [], \ + [echo "You need to install the OpenGL library." + exit -1]) + AC_CHECK_LIB([openal], [alGetError], [], \ + [echo "You need to install the OpenAL library." + exit -1]) + build_linux="yes" + ;; +esac + +LIBS="$LIBS $WX_LIBS $SDL_LIBS" + +AM_CONDITIONAL(OS_LINUX, [test "$build_linux" = "yes"]) +AM_CONDITIONAL(OS_WINDOWS, [test "$build_win" = "yes"]) +AM_CONDITIONAL(OS_MACOSX, [test "$build_macosx" = "yes"]) + +AC_OUTPUT([Makefile src/Makefile]) \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 59e544c..98df3b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,7 +13,7 @@ slirp/libslirp.a: amrefresh: -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-ioctl-linux.c cdrom-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ @@ -68,3 +68,13 @@ pcem_CXXFLAGS += -DUSE_NETWORKING pcem_SOURCES += ne2000.c nethandler.c wx-hostconfig.c pcem_LDADD += slirp/libslirp.a endif + +if OS_MACOSX +pcem_SOURCES += cdrom-ioctl-osx.c +pcem_CFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +pcem_CXXFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +endif + +if OS_LINUX +pcem_SOURCES += cdrom-ioctl-linux.c +endif \ No newline at end of file diff --git a/src/Makefile.in b/src/Makefile.in index 3d6303b..ff1b6be 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -102,6 +102,10 @@ bin_PROGRAMS = pcem$(EXEEXT) @USE_NETWORKING_TRUE@am__append_8 = -DUSE_NETWORKING @USE_NETWORKING_TRUE@am__append_9 = ne2000.c nethandler.c wx-hostconfig.c @USE_NETWORKING_TRUE@am__append_10 = slirp/libslirp.a +@OS_MACOSX_TRUE@am__append_11 = cdrom-ioctl-osx.c +@OS_MACOSX_TRUE@am__append_12 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +@OS_MACOSX_TRUE@am__append_13 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +@OS_LINUX_TRUE@am__append_14 = cdrom-ioctl-linux.c subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -114,18 +118,17 @@ 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 amstrad.c cbm_io.c cdrom-ioctl-linux.c \ - cdrom-image.cc cdrom-null.c codegen.c codegen_ops.c \ - codegen_timing_486.c codegen_timing_686.c \ - codegen_timing_common.c codegen_timing_pentium.c \ - codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ - device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ - esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ - hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ + acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc \ + cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c \ + codegen_timing_686.c codegen_timing_common.c \ + codegen_timing_pentium.c codegen_timing_winchip.c compaq.c \ + config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ + disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ + fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ + headland.c i430lx.c i430fx.c i430vx.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ @@ -167,7 +170,8 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ wx-shaderconfig.cc wx-joystickconfig.cc midi_alsa.c \ wx-sdl2-midi.c codegen_x86.c codegen_x86-64.c ne2000.c \ - nethandler.c wx-hostconfig.c + nethandler.c wx-hostconfig.c cdrom-ioctl-osx.c \ + cdrom-ioctl-linux.c @USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) @USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) @CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) @@ -175,13 +179,15 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ @USE_NETWORKING_TRUE@am__objects_5 = pcem-ne2000.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(OBJEXT) +@OS_MACOSX_TRUE@am__objects_6 = pcem-cdrom-ioctl-osx.$(OBJEXT) +@OS_LINUX_TRUE@am__objects_7 = pcem-cdrom-ioctl-linux.$(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-amstrad.$(OBJEXT) pcem-cbm_io.$(OBJEXT) \ - pcem-cdrom-ioctl-linux.$(OBJEXT) pcem-cdrom-image.$(OBJEXT) \ - pcem-cdrom-null.$(OBJEXT) pcem-codegen.$(OBJEXT) \ - pcem-codegen_ops.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ + pcem-cdrom-image.$(OBJEXT) pcem-cdrom-null.$(OBJEXT) \ + pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ + pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_common.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ @@ -284,7 +290,7 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-wx-shaderconfig.$(OBJEXT) \ pcem-wx-joystickconfig.$(OBJEXT) $(am__objects_1) \ $(am__objects_2) $(am__objects_3) $(am__objects_4) \ - $(am__objects_5) + $(am__objects_5) $(am__objects_6) $(am__objects_7) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_10) @@ -472,7 +478,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -484,18 +489,17 @@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = ../pcem CLEANFILES = $(noinst_SCRIPTS) pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ - acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-ioctl-linux.c \ - cdrom-image.cc cdrom-null.c codegen.c codegen_ops.c \ - codegen_timing_486.c codegen_timing_686.c \ - codegen_timing_common.c codegen_timing_pentium.c \ - codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ - device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ - esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ - hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ + acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc \ + cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c \ + codegen_timing_686.c codegen_timing_common.c \ + codegen_timing_pentium.c codegen_timing_winchip.c compaq.c \ + config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ + disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ + fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ + headland.c i430lx.c i430fx.c i430vx.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ @@ -537,11 +541,13 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ wx-shaderconfig.cc wx-joystickconfig.cc $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_6) \ - $(am__append_9) + $(am__append_9) $(am__append_11) $(am__append_14) pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) $(am__append_5) $(am__append_7) + --cflags) -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello \ + -Doff64_t=off_t $(am__append_5) $(am__append_7) \ + $(am__append_12) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) $(am__append_8) + --cflags) $(am__append_8) $(am__append_13) pcem_LDADD = @LIBS@ $(am__append_1) $(am__append_10) all: all-am @@ -639,6 +645,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.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-ioctl-osx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ @@ -980,20 +987,6 @@ pcem-cbm_io.obj: cbm_io.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cbm_io.obj `if test -f 'cbm_io.c'; then $(CYGPATH_W) 'cbm_io.c'; else $(CYGPATH_W) '$(srcdir)/cbm_io.c'; fi` -pcem-cdrom-ioctl-linux.o: cdrom-ioctl-linux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-null.Tpo $(DEPDIR)/pcem-cdrom-null.Po @@ -3556,6 +3549,34 @@ pcem-wx-hostconfig.obj: wx-hostconfig.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-hostconfig.obj `if test -f 'wx-hostconfig.c'; then $(CYGPATH_W) 'wx-hostconfig.c'; else $(CYGPATH_W) '$(srcdir)/wx-hostconfig.c'; fi` +pcem-cdrom-ioctl-osx.o: cdrom-ioctl-osx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-osx.c' object='pcem-cdrom-ioctl-osx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c + +pcem-cdrom-ioctl-osx.obj: cdrom-ioctl-osx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.obj `if test -f 'cdrom-ioctl-osx.c'; then $(CYGPATH_W) 'cdrom-ioctl-osx.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-osx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-osx.c' object='pcem-cdrom-ioctl-osx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-osx.obj `if test -f 'cdrom-ioctl-osx.c'; then $(CYGPATH_W) 'cdrom-ioctl-osx.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-osx.c'; fi` + +pcem-cdrom-ioctl-linux.o: cdrom-ioctl-linux.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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` + .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po From 0634cba2242b43139e2d0aba4b7007ec815a79cb Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:48:03 +0000 Subject: [PATCH 0210/1050] Added autoconf test for off64_t and related calls. --- configure | 124 +++++++++++++++++++++++++++++++----------------- configure.ac | 6 +++ src/Makefile.am | 4 ++ src/Makefile.in | 6 +-- 4 files changed, 94 insertions(+), 46 deletions(-) diff --git a/configure b/configure index 0c74530..c57343d 100755 --- a/configure +++ b/configure @@ -614,6 +614,8 @@ PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG SDL2_FRAMEWORK +HAS_OFF64T_FALSE +HAS_OFF64T_TRUE USE_ALSA_FALSE USE_ALSA_TRUE USE_NETWORKING_FALSE @@ -1571,48 +1573,6 @@ fi } # ac_fn_cxx_try_compile -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1658,6 +1618,48 @@ fi as_fn_set_status $ac_retval } # ac_fn_c_try_link + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -4201,6 +4203,30 @@ else fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5 +$as_echo_n "checking for off64_t... " >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +off64_t n=0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + has_lfs="yes" +else + has_lfs="no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_lfs" >&5 +$as_echo "$has_lfs" >&6; } + #AC_MSG_CHECKING([for libz]) #AX_CHECK_ZLIB @@ -4229,6 +4255,15 @@ else fi + if test "$has_lfs" = "yes"; then + HAS_OFF64T_TRUE= + HAS_OFF64T_FALSE='#' +else + HAS_OFF64T_TRUE='#' + HAS_OFF64T_FALSE= +fi + + SDL_VERSION=2.0.1 @@ -4351,7 +4386,6 @@ $as_echo "no" >&6; } fi fi - # Check whether --with-sdl-prefix was given. if test "${with_sdl_prefix+set}" = set; then : withval=$with_sdl_prefix; sdl_prefix="$withval" @@ -5571,6 +5605,10 @@ if test -z "${USE_ALSA_TRUE}" && test -z "${USE_ALSA_FALSE}"; then as_fn_error $? "conditional \"USE_ALSA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAS_OFF64T_TRUE}" && test -z "${HAS_OFF64T_FALSE}"; then + as_fn_error $? "conditional \"HAS_OFF64T\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${OS_LINUX_TRUE}" && test -z "${OS_LINUX_FALSE}"; then as_fn_error $? "conditional \"OS_LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/configure.ac b/configure.ac index 3e4688e..30b88bc 100644 --- a/configure.ac +++ b/configure.ac @@ -60,6 +60,10 @@ esac AM_CONDITIONAL(CPU_I386, test "$CPU" = "i386") AM_CONDITIONAL(CPU_X86_64, test "$CPU" = "x86_64") +AC_MSG_CHECKING([for off64_t]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[off64_t n=0;]])],[has_lfs="yes"],[has_lfs="no"]) +AC_MSG_RESULT($has_lfs) + #AC_MSG_CHECKING([for libz]) #AX_CHECK_ZLIB @@ -67,6 +71,8 @@ AM_CONDITIONAL(USE_WX, test "$enable_wx" = "yes") AM_CONDITIONAL(USE_NETWORKING, test "$enable_networking" = "yes") AM_CONDITIONAL(USE_ALSA, test "$enable_alsa" = "yes") +AM_CONDITIONAL(HAS_OFF64T, test "$has_lfs" = "yes") + SDL_VERSION=2.0.1 AM_PATH_SDL2($SDL_VERSION, :, diff --git a/src/Makefile.am b/src/Makefile.am index 98df3b8..eccce04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -77,4 +77,8 @@ endif if OS_LINUX pcem_SOURCES += cdrom-ioctl-linux.c +endif + +if !HAS_OFF64T +pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell endif \ No newline at end of file diff --git a/src/Makefile.in b/src/Makefile.in index ff1b6be..221de07 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -106,6 +106,7 @@ bin_PROGRAMS = pcem$(EXEEXT) @OS_MACOSX_TRUE@am__append_12 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP @OS_MACOSX_TRUE@am__append_13 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP @OS_LINUX_TRUE@am__append_14 = cdrom-ioctl-linux.c +@HAS_OFF64T_FALSE@am__append_15 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -543,9 +544,8 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ $(am__append_3) $(am__append_4) $(am__append_6) \ $(am__append_9) $(am__append_11) $(am__append_14) pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello \ - -Doff64_t=off_t $(am__append_5) $(am__append_7) \ - $(am__append_12) + --cflags) $(am__append_5) $(am__append_7) $(am__append_12) \ + $(am__append_15) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ --cflags) $(am__append_8) $(am__append_13) pcem_LDADD = @LIBS@ $(am__append_1) $(am__append_10) From a8ce4ebc86c46a036a2c1c3ffba802583978ccd3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Nov 2017 20:50:51 +0000 Subject: [PATCH 0211/1050] Voodoo now clamps texture caching to valid LOD levels. --- src/vid_voodoo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 3492c00..d6c2319 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -1326,7 +1326,8 @@ 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 tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); - + lod_min = MIN(lod_min, 8); + lod_max = MIN(lod_max, 8); for (lod = lod_min; lod <= lod_max; lod++) { uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; From a16fdb195ec4be5648d490a83d33e51e05c2ee18 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 12 Nov 2017 12:53:22 +0000 Subject: [PATCH 0212/1050] Adaptec/BusLogic cards now pad out command with zeros if command length is longer than stated in the CCB. Fixes Windows NT 4.0 installation (sends 10 byte instead of 12 for READ CD). --- src/scsi_aha1540.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index e103c35..520ce06 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -1858,6 +1858,7 @@ static void process_scsi(aha154x_t *scsi) if (bus_state & BUS_REQ) { + int bus_out; // pclog("SCSI next phase - %x\n", bus_state); switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { @@ -1881,6 +1882,13 @@ static void process_scsi(aha154x_t *scsi) scsi->scsi_state = SCSI_STATE_READ_MESSAGE; break; + case BUS_CD: + bus_out = BUS_SETDATA(0); + + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + default: fatal(" Bad new phase %x\n", bus_state); } From 13496ba7b9d449e4547c7b9705ac49a4cfeceba5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 13 Nov 2017 21:56:44 +0000 Subject: [PATCH 0213/1050] Implement IDE Check Power Mode command. Fixes Windows NT4 with SP4 or later. --- src/ide.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ide.c b/src/ide.c index 0991203..50de0ee 100644 --- a/src/ide.c +++ b/src/ide.c @@ -62,6 +62,7 @@ #define WIN_READ_DMA 0xC8 #define WIN_WRITE_DMA 0xCA #define WIN_SETIDLE1 0xE3 +#define WIN_CHECK_POWER_MODE 0xE5 #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ /* ATAPI Commands */ @@ -1058,6 +1059,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ // output=1; case WIN_SETIDLE1: /* Idle */ + case WIN_CHECK_POWER_MODE: ide->atastat = BUSY_STAT; timer_process(); callbackide(ide_board); @@ -1719,6 +1721,17 @@ void callbackide(int ide_board) } return; + + case WIN_CHECK_POWER_MODE: + if (ide->type == IDE_NONE) + { + goto abort_cmd; + } + ide->secount = 0xff; + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; + case WIN_PACKETCMD: /* ATAPI Packet */ if (!IDE_DRIVE_IS_CDROM(ide)) goto abort_cmd; // pclog("Packet callback! %i %08X\n",ide->packetstatus,ide); From 717d8156045f10665e37d9ec84a186b5471b10fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 15 Nov 2017 21:55:27 +0000 Subject: [PATCH 0214/1050] Tweak flat DS/SS dynarec optimisation, should reduce block churn when routines are called both with and without flat DS/SS. Fixed incorrect STACK32 flag when entering V86 mode that was hidden by block churn. Protected and V86 mode status now considered when selecting block. --- src/386_dynarec.c | 6 +++-- src/codegen_ops_x86-64.h | 56 ++++++++++++++++++++-------------------- src/codegen_ops_x86.h | 42 +++++++++++++++--------------- src/codegen_x86-64.c | 6 +++-- src/codegen_x86.c | 6 +++-- src/ibm.h | 12 +++++++-- src/x86_ops_misc.h | 16 ++++++------ src/x86_ops_mov_ctrl.h | 8 ++++++ src/x86_ops_pmode.h | 4 +++ src/x86seg.c | 28 +++++++++++--------- 10 files changed, 107 insertions(+), 77 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 144177e..77161e1 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -589,7 +589,8 @@ 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->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); @@ -601,7 +602,8 @@ 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->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); if (valid_block) block = new_block; } diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index c0fa7c5..423a33d 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -869,7 +869,7 @@ static inline void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; if (IS_32_ADDR(&seg->base)) @@ -905,7 +905,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; if (IS_32_ADDR(&seg->base)) @@ -933,7 +933,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) return; if (IS_32_ADDR(&seg->base)) @@ -972,7 +972,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1045,7 +1045,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1131,7 +1131,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1209,7 +1209,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1330,7 +1330,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1414,7 +1414,7 @@ static inline void MEM_STORE_ADDR_EA_B(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1505,7 +1505,7 @@ static inline void MEM_STORE_ADDR_EA_W(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -1594,7 +1594,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } 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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5283,7 +5283,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5335,7 +5335,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5367,7 +5367,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg) addbyte(0); // addbyte(0xc3); /*RET*/ - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ @@ -5413,7 +5413,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5461,7 +5461,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5470,7 +5470,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x8d); /*LEA ESI, 1[EDI]*/ addbyte(0x77); addbyte(0x01); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x74); /*JE slowpath*/ jump4 = &codeblock[block_current].data[block_pos]; @@ -5526,7 +5526,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); @@ -5562,7 +5562,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5610,7 +5610,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xfe); @@ -5619,7 +5619,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x8d); /*LEA ESI, 3[EDI]*/ addbyte(0x77); addbyte(0x03); - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x74); /*JE slowpath*/ jump4 = &codeblock[block_current].data[block_pos]; @@ -5675,7 +5675,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); @@ -5706,7 +5706,7 @@ static inline void MEM_CHECK_WRITE_L(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5778,7 +5778,7 @@ static inline int MEM_LOAD_ADDR_EA_B_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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5856,7 +5856,7 @@ static inline int MEM_LOAD_ADDR_EA_W_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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); @@ -5956,7 +5956,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -6033,7 +6033,7 @@ static inline void MEM_STORE_ADDR_EA_B_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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -6117,7 +6117,7 @@ static inline void MEM_STORE_ADDR_EA_W_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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 77d284f..e6ba9b5 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -618,7 +618,7 @@ static inline void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; - if (seg == &_ds && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; addbyte(0x83); /*CMP seg->base, -1*/ @@ -641,7 +641,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; - if (seg == &_ds && codegen_flat_ds) + if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; addbyte(0x83); /*CMP seg->base, -1*/ @@ -656,7 +656,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) } static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) return; addbyte(0x3b); /*CMP EAX, seg->limit_low*/ @@ -684,7 +684,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -702,7 +702,7 @@ static inline void MEM_LOAD_ADDR_EA_B(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -722,7 +722,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -740,7 +740,7 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -761,7 +761,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -781,7 +781,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -800,7 +800,7 @@ static inline void MEM_LOAD_ADDR_EA_L(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -821,7 +821,7 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -859,7 +859,7 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -880,7 +880,7 @@ static inline void MEM_STORE_ADDR_EA_B(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -901,7 +901,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -922,7 +922,7 @@ static inline void MEM_STORE_ADDR_EA_W(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -943,7 +943,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -964,7 +964,7 @@ static inline void MEM_STORE_ADDR_EA_L(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -995,7 +995,7 @@ static inline 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 && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3922,7 +3922,7 @@ static inline void LOAD_EA() static inline void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3940,7 +3940,7 @@ static inline void MEM_CHECK_WRITE(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -3958,7 +3958,7 @@ static inline void MEM_CHECK_WRITE_W(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)) + if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); diff --git a/src/codegen_x86-64.c b/src/codegen_x86-64.c index b832a60..2c599f0 100644 --- a/src/codegen_x86-64.c +++ b/src/codegen_x86-64.c @@ -312,6 +312,8 @@ void codegen_block_start_recompile(codeblock_t *block) if (block->pc != cs + cpu_state.pc || block->was_recompiled) fatal("Recompile to used block!\n"); + block->status = cpu_cur_status; + block_pos = BLOCK_GPF_OFFSET; #if WIN64 addbyte(0x48); /*XOR RCX, RCX*/ @@ -397,8 +399,8 @@ void codegen_block_start_recompile(codeblock_t *block) block->was_recompiled = 1; - codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; - codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); } void codegen_block_remove() diff --git a/src/codegen_x86.c b/src/codegen_x86.c index b230074..b61008c 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -1424,6 +1424,8 @@ void codegen_block_start_recompile(codeblock_t *block) if (block->pc != cs + cpu_state.pc || block->was_recompiled) fatal("Recompile to used block!\n"); + block->status = cpu_cur_status; + block_pos = BLOCK_GPF_OFFSET; addbyte(0xc7); /*MOV [ESP],0*/ addbyte(0x04); @@ -1483,8 +1485,8 @@ 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; + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); } void codegen_block_remove() diff --git a/src/ibm.h b/src/ibm.h index 8c09065..8d59f4a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -175,11 +175,19 @@ struct extern uint32_t cpu_cur_status; +/*The flags below must match in both cpu_cur_status and block->status for a block + to be valid*/ #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_STATUS_PMODE (1 << 2) +#define CPU_STATUS_V86 (1 << 3) +#define CPU_STATUS_FLAGS 0xffff +/*If the flags below are set in cpu_cur_status, they must be set in block->status. + Otherwise they are ignored*/ +#define CPU_STATUS_NOTFLATDS (1 << 16) +#define CPU_STATUS_NOTFLATSS (1 << 17) +#define CPU_STATUS_MASK 0xffff0000 #define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index ebd9a0d..f6eb918 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -762,16 +762,16 @@ static int opLOADALL(uint32_t fetchdat) _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; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; 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; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); gdt.limit = readmemw(0, 0x852); ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); @@ -822,16 +822,16 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) if (s == &_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } diff --git a/src/x86_ops_mov_ctrl.h b/src/x86_ops_mov_ctrl.h index 088cc73..7b21bf7 100644 --- a/src/x86_ops_mov_ctrl.h +++ b/src/x86_ops_mov_ctrl.h @@ -131,6 +131,10 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) cpu_cache_int_enabled = 0; if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; break; case 2: cr2 = cpu_state.regs[cpu_rm].l; @@ -183,6 +187,10 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) cpu_cache_int_enabled = 0; if (is486 && ((cr0 ^ old_cr0) & (1 << 30))) cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; break; case 2: cr2 = cpu_state.regs[cpu_rm].l; diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index 562b6ba..288d1bb 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -375,6 +375,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) } else tempw &= 0xF; msw = tempw; + if (msw & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; diff --git a/src/x86seg.c b/src/x86seg.c index 7c2bf59..87cf2c7 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -229,16 +229,16 @@ static void do_seg_load(x86seg *s, uint16_t *segdat) if (s == &_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } @@ -321,7 +321,7 @@ void loadseg(uint16_t seg, x86seg *s) s->access = 0; s->base=-1; if (s == &_ds) - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; // 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,pc); return; } @@ -452,7 +452,7 @@ void loadseg(uint16_t seg, x86seg *s) s->base = seg << 4; s->seg = seg; if (s == &_ss) - stack32 = 0; + set_stack32(0); s->checked = 1; if (s == &_ds) codegen_flat_ds = 0; @@ -463,16 +463,16 @@ void loadseg(uint16_t seg, x86seg *s) if (s == &_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } @@ -1980,6 +1980,7 @@ void pmodeint(int num, int soft) #endif eflags&=~VM_FLAG; + cpu_cur_status &= ~CPU_STATUS_V86; if (!(type&0x100)) { flags&=~I_FLAG; @@ -2141,11 +2142,12 @@ void pmodeiret(int is32) segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } // pclog("Pop stack %04X:%04X\n",newss,newsp); eflags=tempflags>>16; + cpu_cur_status |= CPU_STATUS_V86; loadseg(segs[0],&_es); do_seg_v86_init(&_es); loadseg(segs[1],&_ds); do_seg_v86_init(&_ds); - cpu_cur_status &= ~CPU_STATUS_FLATDS; + cpu_cur_status |= CPU_STATUS_NOTFLATDS; loadseg(segs[2],&_fs); do_seg_v86_init(&_fs); loadseg(segs[3],&_gs); @@ -2166,7 +2168,7 @@ void pmodeiret(int is32) ESP=newsp; loadseg(newss,&_ss); do_seg_v86_init(&_ss); - cpu_cur_status &= ~CPU_STATUS_FLATSS; + cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32=0; cpu_cur_status &= ~CPU_STATUS_USE32; flags=(tempflags&0xFFD5)|2; @@ -2562,6 +2564,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { loadcs(new_cs); set_use32(0); + cpu_cur_status |= CPU_STATUS_V86; } else { @@ -2631,6 +2634,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat2[3] & 0x40); + cpu_cur_status &= ~CPU_STATUS_V86; } EAX=new_eax; From 97ac443f70b75fc08dde874bfa4836d429703c7d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 Nov 2017 21:30:42 +0000 Subject: [PATCH 0215/1050] More fixes/improvements to T3100e. Patch from John Elliott. --- src/keyboard_at.c | 63 +++++++++++++++++++++----- src/t3100e.c | 110 +++++++++++++++++++++++++++++++++++++++++++++- src/t3100e.h | 5 +++ src/vid_t3100e.c | 5 +++ 4 files changed, 170 insertions(+), 13 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4866c89..1153bc5 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -211,6 +211,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) } break; + case 0xb6: /* T3100e - set colour/mono switch */ + if (romset == ROM_T3100E) + t3100e_mono_set(val); + break; + case 0xcb: /*AMI - set keyboard mode*/ break; @@ -410,20 +415,15 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.mem[0] &= ~0x10; break; - case 0xbb: /* Read 'Fn' key - sent by Toshiba 3100e - BIOS. Return it for right Ctrl and right - Alt; on the real T3100e, these keystrokes - could only be generated using 'Fn'. */ - if (pcem_key[0xb8] || /* Right Alt */ - pcem_key[0x9d]) /* Right Ctrl */ - { - keyboard_at_adddata(0x04); - } - else keyboard_at_adddata(0x00); + case 0xb0: /* T3100e: Turbo on */ + if (romset == ROM_T3100E) + t3100e_turbo_set(1); break; - /* For the T3100e, 0xB0 is 'turbo on' and 0xB1 is - * 'turbo off' */ + case 0xb1: /* T3100e: Turbo off */ + if (romset == ROM_T3100E) + t3100e_turbo_set(0); + break; case 0xb2: /* T3100e: Select external display */ if (romset == ROM_T3100E) @@ -435,12 +435,51 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) t3100e_display_set(0x01); break; + case 0xb4: /* T3100e: Get configuration / status */ + if (romset == ROM_T3100E) + keyboard_at_adddata(t3100e_config_get()); + break; + + case 0xb5: /* T3100e: Get colour / mono byte */ + if (romset == ROM_T3100E) + keyboard_at_adddata(t3100e_mono_get()); + break; + + case 0xb6: /* T3100e: Set colour / mono byte */ + if (romset == ROM_T3100E) + keyboard_at.want60 = 1; + break; + + /* T3100e commands not implemented: + * 0xB7: Emulate PS/2 keyboard + * 0xB8: Emulate AT keyboard */ + + case 0xbb: /* T3100e: Read 'Fn' key. + Return it for right Ctrl and right + Alt; on the real T3100e, these keystrokes + could only be generated using 'Fn'. */ + if (romset == ROM_T3100E) + { + if (pcem_key[0xb8] || /* Right Alt */ + pcem_key[0x9d]) /* Right Ctrl */ + { + keyboard_at_adddata(0x04); + } + else keyboard_at_adddata(0x00); + } + break; + case 0xbc: /* T3100e: Reset Fn+Key notification */ if (romset == ROM_T3100E) t3100e_notify_set(0x00); break; case 0xc0: /*Read input port*/ + /* The T3100e returns all bits set except bit 6 which + * is set by t3100e_mono_set() */ + if (romset == ROM_T3100E) + keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; + keyboard_at_adddata(keyboard_at.input_port | 4); keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); break; diff --git a/src/t3100e.c b/src/t3100e.c index ebfbb8e..e9730d7 100644 --- a/src/t3100e.c +++ b/src/t3100e.c @@ -2,6 +2,7 @@ #include "cpu.h" #include "model.h" #include "io.h" +#include "fdd.h" #include "mouse.h" #include "mem.h" #include "device.h" @@ -157,7 +158,10 @@ struct t3100e_ems_regs uint8_t upper_pages; /* Pages of EMS available from upper RAM */ uint8_t upper_is_ems; /* Upper RAM is EMS? */ mem_mapping_t upper_mapping; - uint8_t notify; + uint8_t notify; /* Notification from keyboard controller */ + uint8_t turbo; /* 0 for 6MHz, else full speed */ + uint8_t mono; /* Emulates PC/AT 'mono' motherboard switch */ + /* Bit 0 is 0 for colour, 1 for mono */ } t3100e_ems; void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); @@ -358,6 +362,33 @@ void t3100e_notify_set(uint8_t value) t3100e_ems.notify = value; } +void t3100e_mono_set(uint8_t value) +{ + t3100e_ems.mono = value; +} + +uint8_t t3100e_mono_get(void) +{ + return t3100e_ems.mono; +} + +void t3100e_turbo_set(uint8_t value) +{ + t3100e_ems.turbo = value; + if (!value) + { + int c = cpu; + cpu = 0; /* 286/6 */ + cpu_set(); + cpu = c; + } + else + { + cpu_set(); + } +} + + uint8_t t3100e_sys_in(uint16_t addr, void *p) { @@ -394,6 +425,83 @@ void t3100e_sys_out(uint16_t addr, uint8_t val, void *p) } } + +uint8_t t3100e_config_get(void) +{ +/* The byte returned: + Bit 7: Set if internal plasma display enabled + Bit 6: Set if running at 6MHz, clear at full speed + Bit 5: Always 1? + Bit 4: Set if the FD2MB jumper is present (internal floppy is ?tri-mode) + Bit 3: Clear if the FD2 jumper is present (two internal floppies) + Bit 2: Set if the internal drive is A:, clear if B: + Bit 1: Set if the parallel port is configured as a floppy connector + for the second drive. + Bit 0: Set if the F2HD jumper is present (internal floppy is 720k) + */ + uint8_t value = 0x28; /* Start with bits 5 and 3 set. */ + + int type_a = fdd_get_type(0); + int type_b = fdd_get_type(1); + int prt_switch; /* External drive type: 0=> none, 1=>A, 2=>B */ + +/* Get display setting */ + if (t3100e_display_get()) value |= 0x80; + if (!t3100e_ems.turbo) value |= 0x40; + +/* Try to determine the floppy types.*/ + + prt_switch = (type_b ? 2 : 0); + switch(type_a) + { +/* Since a T3100e cannot have an internal 5.25" drive, mark 5.25" A: drive as + * being external, and set the internal type based on type_b. */ + case 1: /* 360k */ + case 2: /* 1.2Mb */ + case 3: /* 1.2Mb RPMx2*/ + prt_switch = 1; /* External drive is A: */ + switch (type_b) + { + case 1: /* 360k */ + case 4: value |= 1; break; /* 720k */ + case 6: value |= 0x10; break; /* Tri-mode */ + /* All others will be treated as 1.4M */ + } + break; + case 4: value |= 0x01; /* 720k */ + if (type_a == type_b) + { + value &= (~8); /* Two internal drives */ + prt_switch = 0; /* No external drive */ + } + break; + case 5: /* 1.4M */ + case 7: /* 2.8M */ + if (type_a == type_b) + { + value &= (~8); /* Two internal drives */ + prt_switch = 0; /* No external drive */ + } + break; + case 6: /* 3-mode */ + value |= 0x10; + if (type_a == type_b) + { + value &= (~8); /* Two internal drives */ + prt_switch = 0; /* No external drive */ + } + break; + } /* End switch */ + switch (prt_switch) + { + case 0: value |= 4; break; /* No external floppy */ + case 1: value |= 2; break; /* External floppy is A: */ + case 2: value |= 6; break; /* External floppy is B: */ + } + return value; +} + + /* Read EMS page register */ uint8_t t3100e_ems_in(uint16_t addr, void *p) { diff --git a/src/t3100e.h b/src/t3100e.h index d0ada48..ab41153 100644 --- a/src/t3100e.h +++ b/src/t3100e.h @@ -1,2 +1,7 @@ void t3100e_notify_set(uint8_t value); void t3100e_display_set(uint8_t value); +uint8_t t3100e_display_get(); +uint8_t t3100e_config_get(); +void t3100e_turbo_set(uint8_t value); +uint8_t t3100e_mono_get(); +void t3100e_mono_set(uint8_t value); diff --git a/src/vid_t3100e.c b/src/vid_t3100e.c index fcd1227..4172f8f 100644 --- a/src/vid_t3100e.c +++ b/src/vid_t3100e.c @@ -54,6 +54,11 @@ void t3100e_display_set(uint8_t internal) st_display_internal = internal; } +uint8_t t3100e_display_get() +{ + return st_display_internal; +} + typedef struct t3100e_t { From 4af811699ec288c7211194a76db1f399151660f1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 Nov 2017 21:55:49 +0000 Subject: [PATCH 0216/1050] Fix dynarec timer granularity to 5us. Fixed speed issues in Tubular Worlds. --- src/386_dynarec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 77161e1..1fa2624 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -493,14 +493,14 @@ void exec386_dynarec(int cycs) int tempi; int cycdiff; int oldcyc; - + int cyc_period = cycs / 2000; /*5us*/ //output = 3; cycles_main += cycs; while (cycles_main > 0) { int cycles_start; - cycles += 1000; + cycles += cyc_period; cycles_start = cycles; timer_start_period(cycles << TIMER_SHIFT); From a1fc8da064cb7ec7d589479effa534bd91a6ebac Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 20 Nov 2017 20:48:27 +0000 Subject: [PATCH 0217/1050] Fixed clipping rectangle on Voodoo, Return Fire II now works. --- src/vid_voodoo.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index d6c2319..73c6824 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -2712,8 +2712,8 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood ystart = params->clipLowY; } - if ((params->fbzMode & 1) && (yend > params->clipHighY)) - yend = params->clipHighY; + if ((params->fbzMode & 1) && (yend >= params->clipHighY)) + yend = params->clipHighY-1; state->y = ystart; // yend--; @@ -2856,14 +2856,14 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood x = params->clipLeft; } - if (x2 > params->clipRight) - x2 = params->clipRight; + if (x2 >= params->clipRight) + x2 = params->clipRight-1; } else { - if (x > params->clipRight) + if (x >= params->clipRight) { - int dx = params->clipRight - x; + int dx = (params->clipRight-1) - x; state->ir += params->dRdX*dx; state->ig += params->dGdX*dx; @@ -2878,7 +2878,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->tmu1_w += params->tmu[1].dWdX*dx; state->w += params->dWdX*dx; - x = params->clipRight; + x = params->clipRight-1; } if (x2 < params->clipLeft) x2 = params->clipLeft; @@ -3995,8 +3995,8 @@ static void blit_start(voodoo_t *voodoo) if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { - if (dst_x < voodoo->bltClipLeft || dst_x > voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y > voodoo->bltClipHighY) + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || + dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) goto skip_pixel_blit; } @@ -4067,8 +4067,8 @@ skip_pixel_blit: { if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { - if (dst_x < voodoo->bltClipLeft || dst_x > voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y > voodoo->bltClipHighY) + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || + dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) goto skip_pixel_fill; } @@ -4221,8 +4221,8 @@ static void blit_data(voodoo_t *voodoo, uint32_t data) if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { - if (x < voodoo->bltClipLeft || x > voodoo->bltClipRight || - voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y > voodoo->bltClipHighY) + if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || + voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) goto skip_pixel; } From e80921f29dded10835df842ad0d9a4d437b51965 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 22 Nov 2017 21:00:42 +0000 Subject: [PATCH 0218/1050] Fix Voodoo caching of textures ending at the exact end of texture memory. Fixes FMV in Return to Castle Wolfenstein. --- src/vid_voodoo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 73c6824..319170c 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -1628,7 +1628,12 @@ static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) if (addr_end != 0) { - if (dirty_addr >= (addr_start & voodoo->texture_mask & ~0x3ff) && dirty_addr < (((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff)) + int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; + int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; + + if (addr_end_masked < addr_start_masked) + addr_end_masked = voodoo->texture_mask+1; + if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) { // pclog(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); From 542eb754834e040d437d1fbced1bc9a4ab3f9d60 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 23 Nov 2017 21:11:43 +0000 Subject: [PATCH 0219/1050] Fixed bug in Voodoo recompiler breaking cc_localselect_override. Fixes colours in Return Fire II. --- src/vid_voodoo_codegen_x86-64.h | 3 ++- src/vid_voodoo_codegen_x86.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index fda8b3f..e6e1c5a 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -1904,7 +1904,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x6e); addbyte(0x8e); addlong(offsetof(voodoo_params_t, color0)); - /*JMP +*/ + addbyte(0xeb); /*JMP +*/ + addbyte(8+5+4+4); /*!cc_localselect:*/ addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index be4aad2..48b0cca 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1837,7 +1837,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8e); addlong(offsetof(voodoo_params_t, color0)); addbyte(0xeb); /*JMP +*/ - addbyte(8); + addbyte(8+5+4+4); /*!cc_localselect:*/ addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); From ae52810cc82e862fe7abf0fcbd350120c91f00b2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 26 Nov 2017 17:01:35 +0000 Subject: [PATCH 0220/1050] Separate Voodoo command written count from main thread and FIFO thread. Fixes hangs in some games. --- src/vid_voodoo.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 319170c..30fb18d 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -310,7 +310,7 @@ typedef struct voodoo_t fifo_entry_t fifo[FIFO_SIZE]; volatile int fifo_read_idx, fifo_write_idx; - int cmd_read, cmd_written; + volatile int cmd_read, cmd_written, cmd_written_fifo; voodoo_params_t params_buffer[PARAM_SIZE]; volatile int params_read_idx[2], params_write_idx; @@ -5999,17 +5999,19 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) { int fifo_entries = FIFO_ENTRIES; int swap_count = voodoo->swap_count; - int busy = (voodoo->cmd_written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); if (SLI_ENABLED && voodoo->type != VOODOO_2) { voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; - + int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; + if (voodoo_other->swap_count > swap_count) swap_count = voodoo_other->swap_count; if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; - if ((voodoo_other->cmd_written - voodoo_other->cmd_read) || + if ((other_written - voodoo_other->cmd_read) || (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) busy = 1; if (!voodoo_other->voodoo_busy) @@ -6627,7 +6629,7 @@ static void fifo_thread(void *param) uint32_t val = cmdfifo_get(voodoo); if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written++; + voodoo->cmd_written_fifo++; voodoo_reg_writel(addr, val, voodoo); @@ -6711,8 +6713,8 @@ static void fifo_thread(void *param) uint32_t val = cmdfifo_get(voodoo); if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written++; - + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); } From f0b213fef095deacc0a83338363aa5bb353665fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 26 Nov 2017 17:46:21 +0000 Subject: [PATCH 0221/1050] Mask ViRGE source colour to current destination colour depth. Fixes chroma transparency in Beasts and Bumpkins. --- src/vid_s3_virge.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 9451755..cc7d9be 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -1923,6 +1923,7 @@ 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_fg_clr, src_bg_clr; switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { @@ -1931,12 +1932,16 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) x_mul = 1; cpu_dat_shift = 8; pattern_data = virge->s3d.pattern_8; + src_fg_clr = virge->s3d.src_fg_clr & 0xff; + src_bg_clr = virge->s3d.src_bg_clr & 0xff; break; case CMD_SET_FORMAT_16: bpp = 1; x_mul = 2; cpu_dat_shift = 16; pattern_data = virge->s3d.pattern_16; + src_fg_clr = virge->s3d.src_fg_clr & 0xffff; + src_bg_clr = virge->s3d.src_bg_clr & 0xffff; break; case CMD_SET_FORMAT_24: default: @@ -1944,6 +1949,8 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) x_mul = 3; cpu_dat_shift = 24; pattern_data = virge->s3d.pattern_32; + src_fg_clr = virge->s3d.src_fg_clr; + src_bg_clr = virge->s3d.src_bg_clr; break; } if (virge->s3d.cmd_set & CMD_SET_MP) @@ -2026,7 +2033,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) case 0: case CMD_SET_MS: READ(src_addr, source); - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == virge->s3d.src_fg_clr) + if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) update = 0; break; case CMD_SET_IDS: @@ -2057,11 +2064,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) count = 0; } } - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == virge->s3d.src_fg_clr) + if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) update = 0; break; case CMD_SET_IDS | CMD_SET_MS: - source = (cpu_dat & (1 << 31)) ? virge->s3d.src_fg_clr : virge->s3d.src_bg_clr; + source = (cpu_dat & (1 << 31)) ? src_fg_clr : src_bg_clr; if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) update = 0; cpu_dat <<= 1; From 2f1514d3b280679fde202964bfa01131c64299fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 27 Nov 2017 21:09:42 +0000 Subject: [PATCH 0222/1050] Dynarec now jumps straight to GPF handler if it hits a NULL selector instead of relying on interpreter code to detect the GPF. Fixes hang in Windows 98 SE upgrade setup. --- src/codegen_ops_x86-64.h | 8 ++++---- src/codegen_ops_x86.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 423a33d..9501a5f 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -889,9 +889,9 @@ static inline void CHECK_SEG_READ(x86seg *seg) addbyte(0xe8 | REG_ESI); addbyte(0xff); } - addbyte(0x0f); /*JE end*/ + addbyte(0x0f); /*JE BLOCK_GPF_OFFSET*/ addbyte(0x84); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); seg->checked = 1; } @@ -925,9 +925,9 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) addbyte(0xe8 | REG_ESI); addbyte(0xff); } - addbyte(0x0f); /*JE end*/ + addbyte(0x0f); /*JE BLOCK_GPF_OFFSET*/ addbyte(0x84); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); seg->checked = 1; } diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index e6ba9b5..4066482 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -626,8 +626,8 @@ static inline void CHECK_SEG_READ(x86seg *seg) addlong((uint32_t)&seg->base); addbyte(-1); addbyte(0x0f); - addbyte(0x84); /*JE end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); seg->checked = 1; } @@ -649,8 +649,8 @@ static inline void CHECK_SEG_WRITE(x86seg *seg) addlong((uint32_t)&seg->base); addbyte(-1); addbyte(0x0f); - addbyte(0x84); /*JE end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); seg->checked = 1; } From e12eb0ff0d0f6fdd310fd81c1c47af18de406c14 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 28 Nov 2017 19:47:46 +0000 Subject: [PATCH 0223/1050] Don't mirror VRAM at 1 MB for Phoenix Trio64 with 1 MB. Fixes memory size detection. This is most likely a difference in memory mapping between FPM and EDO Trio64 configurations. --- src/vid_s3.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vid_s3.c b/src/vid_s3.c index b6aa40f..1b8a3cd 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2236,6 +2236,8 @@ static void *s3_init(char *bios_fn, int chip) break; case 1: /*1MB*/ /*VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus*/ + /*This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, + but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference?*/ svga->vram_mask = (1 << 20) - 1; svga->vram_max = 2 << 20; break; @@ -2344,6 +2346,8 @@ void *s3_phoenix_trio64_init() s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; + if (device_get_config_int("memory") == 1) + s3->svga.vram_max = 1 << 20; /*Phoenix BIOS does not expect VRAM to be mirrored*/ s3->getclock = s3_trio64_getclock; s3->getclock_p = s3; From 5c3ae2556a38eb79aa2112f695b24ce29513b280 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 2 Dec 2017 18:04:04 +0000 Subject: [PATCH 0224/1050] Don't mute Sound Blaster DSP output when DMA disabled. Fixes use of SB Direct Output. --- src/sound_sb_dsp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 6bb1639..6aebef1 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -1110,8 +1110,7 @@ void sb_poll_i(void *p) void sb_dsp_update(sb_dsp_t *dsp) { - /*this "if" implements two things: speaker on/off and buffer cleanup after stopping audio. */ - if (!dsp->sbenable || dsp->muted) + if (dsp->muted) { dsp->sbdatl=0; dsp->sbdatr=0; From e6d20ca199ec7053f8b93ab1c34966cd6ef73a23 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 3 Dec 2017 12:55:53 +0000 Subject: [PATCH 0225/1050] Fixed PIT readback command, and timing synchronisation when loading a timer. Fixes Sound Blaster detection in Lemmings 2. --- src/pit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pit.c b/src/pit.c index af493a6..fdcb6c9 100644 --- a/src/pit.c +++ b/src/pit.c @@ -88,7 +88,7 @@ static void pit_set_out(PIT *pit, int t, int out) static void pit_load(PIT *pit, int t) { int l = pit->l[t] ? pit->l[t] : 0x10000; - timer_process(); + timer_clock(); pit->newcount[t] = 0; pit->disabled[t] = 0; // pclog("pit_load: t=%i l=%x\n", t, l); @@ -343,11 +343,11 @@ void pit_write(uint16_t addr, uint8_t val, void *p) 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_read_timer(pit, 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_read_timer(pit, 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_read_timer(pit, 2); } if (!(val & 0x10)) { From 75cdefe0b45ff76ead05c9ffef43917c481ec1f1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 3 Dec 2017 21:41:09 +0000 Subject: [PATCH 0226/1050] Return 0 for block decoded I/O address on Mach64 GX. Fixes hang in OS/2 Warp install when using this card. --- src/vid_ati_mach64.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index f6c7720..6f92116 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -3210,7 +3210,10 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x12: return mach64->linear_base >> 16; case 0x13: return mach64->linear_base >> 24; - case 0x14: return 0x01; /*Block decoded IO address*/ + case 0x14: + if (mach64->type == MACH64_VT2) + return 0x01; /*Block decoded IO address*/ + return 0; case 0x15: return mach64->block_decoded_io >> 8; case 0x16: return mach64->block_decoded_io >> 16; case 0x17: return mach64->block_decoded_io >> 24; From 0db852eb92f225698c52aed3071e568b9fe288a6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Dec 2017 18:24:37 +0000 Subject: [PATCH 0227/1050] Fix call through NULL pointer when using 53c400-based SCSI cards. --- src/scsi_53c400.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/scsi_53c400.c b/src/scsi_53c400.c index 476ec7b..ffc3a59 100644 --- a/src/scsi_53c400.c +++ b/src/scsi_53c400.c @@ -699,9 +699,6 @@ static void *scsi_53c400_init(char *bios_fn) lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); memset(scsi, 0, sizeof(lcs6821n_t)); - scsi->ncr.dma_changed = ncr53c400_dma_changed; - scsi->ncr.p = scsi; - rom_init(&scsi->bios_rom, bios_fn, 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&scsi->bios_rom.mapping); @@ -712,6 +709,9 @@ static void *scsi_53c400_init(char *bios_fn) ncr5380_reset(&scsi->ncr); + scsi->ncr.dma_changed = ncr53c400_dma_changed; + scsi->ncr.p = scsi; + scsi->status_ctrl = STATUS_BUFFER_NOT_READY; scsi->buffer_host_pos = 128; @@ -736,9 +736,6 @@ static void *scsi_t130b_init(char *bios_fn) lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); memset(scsi, 0, sizeof(lcs6821n_t)); - scsi->ncr.dma_changed = ncr53c400_dma_changed; - scsi->ncr.p = scsi; - rom_init(&scsi->bios_rom, "trantor_t130b_bios_v2.14.bin", 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, @@ -752,6 +749,9 @@ static void *scsi_t130b_init(char *bios_fn) ncr5380_reset(&scsi->ncr); + scsi->ncr.dma_changed = ncr53c400_dma_changed; + scsi->ncr.p = scsi; + scsi->status_ctrl = STATUS_BUFFER_NOT_READY; scsi->buffer_host_pos = 128; From 8af8ab7e8a52cf8ec7844173988c4d946a6194fb Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Dec 2017 18:25:42 +0000 Subject: [PATCH 0228/1050] Don't fatal() on AHA-1542C/BT-545S when SCSI device fails to request a command. --- src/scsi_aha1540.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index 520ce06..1d980b5 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -1803,7 +1803,11 @@ static void process_scsi(aha154x_t *scsi) /*Device should now be selected*/ if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) - fatal("Device failed to request command\n"); + { + pclog("Device failed to request command\n"); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + break; + } scsi->scsi_state = SCSI_STATE_SEND_COMMAND; break; From c3a127f01cfaded60567c67daf34237eeacbe684 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Dec 2017 22:15:30 +0000 Subject: [PATCH 0229/1050] Fixed alignment check in x86-64 recompiler. Fixes crash in Windows 95 setup. --- src/codegen_ops_x86-64.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 9501a5f..f50eba2 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -5885,9 +5885,9 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(1); + addlong(3); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ From 12d3ac437765692d83f3c6b468b022533c5d403a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 6 Dec 2017 22:14:51 +0000 Subject: [PATCH 0230/1050] Fix PIIX IDE bus mastering initialisation. Ubuntu 10.04 boots again. --- src/ide.c | 1 - src/model.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ide.c b/src/ide.c index 50de0ee..a9cacd9 100644 --- a/src/ide.c +++ b/src/ide.c @@ -2870,7 +2870,6 @@ static void *ide_init() { ide_pri_enable(); ide_sec_enable(); - ide_bus_master_read_sector = ide_bus_master_write_sector = NULL; timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); diff --git a/src/model.c b/src/model.c index e8784a4..3a11c05 100644 --- a/src/model.c +++ b/src/model.c @@ -538,6 +538,7 @@ void model_init() { pclog("Initting as %s\n", model_getname()); AMSTRAD = AT = PCI = TANDY = 0; + ide_set_bus_master(NULL, NULL, NULL); io_init(); models[model].init(); From 6555ecd3e3e4277a9b5958a9b5f5700d3f6480e8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Dec 2017 22:26:19 +0000 Subject: [PATCH 0231/1050] Disable NMI masking on PS/2 MCA machines - fixes '103' POST error. --- src/model.c | 2 ++ src/nvr.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index 3a11c05..805e0f0 100644 --- a/src/model.c +++ b/src/model.c @@ -414,6 +414,8 @@ static void ps2_common_init() pic2_init(); pit_ps2_init(); + + nmi_mask = 0x80; } void ps2_model_50_init() diff --git a/src/nvr.c b/src/nvr.c index bd4794a..bdd9462 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -7,6 +7,7 @@ #include "rtc.h" #include "paths.h" #include "config.h" +#include "model.h" #include "nmi.h" int oldromset; @@ -201,7 +202,13 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) else { nvraddr=val&nvrmask; - nmi_mask = ~val & 0x80; + /*PS/2 BIOSes will disable NMIs and expect the watchdog timer to still be able + to fire them. I suspect the watchdog is exempt from NMI masking. Currently NMIs + are always enabled for PS/2 machines - this would mean that other peripherals + could fire NMIs regardless of the mask state, but as there aren't any emulated + MCA peripherals that do this it's currently a moot point.*/ + if (!(models[model].flags & MODEL_MCA)) + nmi_mask = ~val & 0x80; } } From a8e72802a148214891ac517522e3be2089533e5f Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Dec 2017 22:26:57 +0000 Subject: [PATCH 0232/1050] Implement PS/2 DMA status register - fixes OS/2 v1.3 on PS/2 machines. --- src/dma.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/dma.c b/src/dma.c index 8c58bb2..bc4aba2 100644 --- a/src/dma.c +++ b/src/dma.c @@ -165,6 +165,21 @@ static uint8_t dma_ps2_read(uint16_t addr, void *priv) 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 6: /*Read DMA status*/ + if (dma.byte_ptr) + { + temp = dma16.stat_rq | (dma16.stat << 4); + dma16.stat = 0; + dma16.stat_rq = 0; + } + else + { + temp = dma.stat_rq | (dma.stat << 4); + dma.stat = 0; + dma.stat_rq = 0; + } + 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; @@ -505,6 +520,7 @@ int dma_channel_read(int channel) return DMA_NODATA; temp = _dma_read(dma.ac[channel]); + dma.stat_rq |= (1 << channel); if (dma.mode[channel] & 0x20) { @@ -548,6 +564,7 @@ int dma_channel_read(int channel) temp = _dma_read(dma16.ac[channel]) | (_dma_read(dma16.ac[channel] + 1) << 8); + dma16.stat_rq |= (1 << channel); if (dma16.mode[channel] & 0x20) { @@ -600,7 +617,8 @@ int dma_channel_write(int channel, uint16_t val) return DMA_NODATA; _dma_write(dma.ac[channel], val); - + dma.stat_rq |= (1 << channel); + if (dma.mode[channel] & 0x20) { if (dma.is_ps2) @@ -642,6 +660,7 @@ int dma_channel_write(int channel, uint16_t val) _dma_write(dma16.ac[channel], val); _dma_write(dma16.ac[channel] + 1, val >> 8); + dma16.stat_rq |= (1 << channel); if (dma16.mode[channel] & 0x20) { From 50a3aaf1a8f2ecdb106b7cbda177b3a318283a0b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 19:13:46 +0000 Subject: [PATCH 0233/1050] Added dma.stat_rq variable required by rev 950. --- src/ibm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ibm.h b/src/ibm.h index 8d59f4a..2ad1aa3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -336,7 +336,7 @@ typedef struct DMA int wp; uint8_t m,mode[4]; uint8_t page[4]; - uint8_t stat; + uint8_t stat, stat_rq; uint8_t command; int xfr_command, xfr_channel; From f5009ef43c3a9c5cde1fcfe167781d40b396513b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 20:10:59 +0000 Subject: [PATCH 0234/1050] Fix HD indicator LED on IBM ESDI adapter. --- src/hdd_esdi.c | 1 + src/ibm.h | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 1b32b1b..8bbc41e 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -437,6 +437,7 @@ static void esdi_callback(void *p) if (esdi->rba >= hdd_file->sectors) fatal("Read past end of drive\n"); hdd_read_sectors(hdd_file, esdi->rba, 1, esdi->data); + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); } // pclog("Read sector %i %i %08x\n", esdi->sector_pos, esdi->data_pos, esdi->rba*512); while (esdi->data_pos < 256) diff --git a/src/ibm.h b/src/ibm.h index 2ad1aa3..a314370 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -5,9 +5,9 @@ #define READFLASH_FDC 0 #define READFLASH_HDC 4 -#define readflash_set(offset, drive) readflash |= 1<<(offset+drive) -#define readflash_clear(offset, drive) readflash &= ~(1<<(offset+drive)) -#define readflash_get(offset, drive) ((readflash&(1<<(offset+drive))) != 0) +#define readflash_set(offset, drive) readflash |= 1<<((offset)+(drive)) +#define readflash_clear(offset, drive) readflash &= ~(1<<((offset)+(drive))) +#define readflash_get(offset, drive) ((readflash&(1<<((offset)+(drive)))) != 0) /*Memory*/ uint8_t *ram; From cd8e5dbd545a41a52052bd01232b1edcc7d58dc9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 20:11:29 +0000 Subject: [PATCH 0235/1050] IBM ESDI adapter now handles out-of-range reads/writes. --- src/hdd_esdi.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 8bbc41e..c45e4f1 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -355,6 +355,25 @@ static void device_not_present(esdi_t *esdi) esdi_set_irq(esdi); } +static void rba_out_of_range(esdi_t *esdi) +{ + esdi->status_len = 9; + esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; + esdi->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/ + esdi->status_data[2] = 0x0007; /*RBA out of range*/ + 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) \ @@ -412,6 +431,12 @@ static void esdi_callback(void *p) esdi->sector_pos = 0; esdi->sector_count = esdi->cmd_data[1]; + + if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) + { + rba_out_of_range(esdi); + return; + } esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; @@ -492,6 +517,12 @@ static void esdi_callback(void *p) esdi->sector_pos = 0; esdi->sector_count = esdi->cmd_data[1]; + if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) + { + rba_out_of_range(esdi); + return; + } + 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; @@ -560,6 +591,12 @@ static void esdi_callback(void *p) return; } + if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) + { + rba_out_of_range(esdi); + return; + } + esdi->status = STATUS_IRQ; esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; esdi->irq_in_progress = 1; From 3f6e5282c6c65ff3075ead4244f16bf5df2b4492 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 20:11:50 +0000 Subject: [PATCH 0236/1050] Added Get Device Status command to IBM ESDI adapter. --- src/hdd_esdi.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index c45e4f1..66c799c 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -110,6 +110,7 @@ typedef struct esdi_t #define CMD_READ_VERIFY 0x03 #define CMD_WRITE_VERIFY 0x04 #define CMD_SEEK 0x05 +#define CMD_GET_DEV_STATUS 0x08 #define CMD_GET_DEV_CONFIG 0x09 #define CMD_GET_POS_INFO 0x0a @@ -618,6 +619,37 @@ static void esdi_callback(void *p) esdi_set_irq(esdi); break; + case CMD_GET_DEV_STATUS: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) + { + 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 = 9; + esdi->status_data[0] = CMD_GET_DEV_STATUS | STATUS_LEN(9) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0x0000; /*Error bits*/ + esdi->status_data[2] = 0x1900; /*Device status*/ + esdi->status_data[3] = 0; /*ESDI Standard Status*/ + esdi->status_data[4] = 0; /*ESDI Vendor Unique Status*/ + 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_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + case CMD_GET_DEV_CONFIG: ESDI_DRIVE_ONLY(); From f9670eb707fe61e36527799d99aac33308e7f1c7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 20:12:05 +0000 Subject: [PATCH 0237/1050] Fix return data on IBM ESDI adapter Get Device Config command. --- src/hdd_esdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 66c799c..8cd4ddb 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -665,7 +665,7 @@ static void esdi_callback(void *p) 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[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; esdi->status_data[1] = 0x10; /*Zero defect*/ esdi->status_data[2] = hdd_file->sectors & 0xffff; esdi->status_data[3] = hdd_file->sectors >> 16; From ae37557c3dc06396790c036e39477c071914aef7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 20:12:13 +0000 Subject: [PATCH 0238/1050] Speed up IBM ESDI adapter a bit. --- src/hdd_esdi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 8cd4ddb..0999ba4 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -22,7 +22,7 @@ #include "hdd_esdi.h" -#define ESDI_TIME (2000 * TIMER_USEC) +#define ESDI_TIME (500 * TIMER_USEC) #define CMD_ADAPTER 0 From 640c6a61e240d83447aff935697a2f9ea2a34b1a Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Dec 2017 20:39:36 +0000 Subject: [PATCH 0239/1050] Added output volume control. --- src/pc.c | 2 + src/pc.xrc | 44 + src/sound.c | 1 + src/sound.h | 2 + src/soundopenal.c | 7 + src/wx-resources.cpp | 2103 ++++++++++++++++++++++-------------------- src/wx-sdl2.c | 8 +- 7 files changed, 1148 insertions(+), 1019 deletions(-) diff --git a/src/pc.c b/src/pc.c index eb487dd..21ad726 100644 --- a/src/pc.c +++ b/src/pc.c @@ -669,6 +669,7 @@ void loadconfig(char *fn) window_remember = config_get_int(CFG_GLOBAL, NULL, "window_remember", 0); sound_buf_len = config_get_int(CFG_GLOBAL, NULL, "sound_buf_len", 200); + sound_gain = config_get_int(CFG_GLOBAL, NULL, "sound_gain", 0); GAMEBLASTER = config_get_int(CFG_MACHINE, NULL, "gameblaster", 0); GUS = config_get_int(CFG_MACHINE, NULL, "gus", 0); @@ -840,6 +841,7 @@ void saveconfig(char *fn) config_set_int(CFG_GLOBAL, NULL, "window_remember", window_remember); config_set_int(CFG_GLOBAL, NULL, "sound_buf_len", sound_buf_len); + config_set_int(CFG_GLOBAL, NULL, "sound_gain", sound_gain); config_set_int(CFG_MACHINE, NULL, "gameblaster", GAMEBLASTER); config_set_int(CFG_MACHINE, NULL, "gus", GUS); diff --git a/src/pc.xrc b/src/pc.xrc index dc988d6..6df87ea 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -31,6 +31,7 @@ + @@ -394,6 +395,49 @@ 1 + + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + + + 1 + + diff --git a/src/sound.c b/src/sound.c index 96ad7b1..f5f9cf3 100644 --- a/src/sound.c +++ b/src/sound.c @@ -125,6 +125,7 @@ static event_t *sound_cd_event; static unsigned int cd_vol_l, cd_vol_r; int sound_buf_len = 48000 / 10; +int sound_gain = 0; void sound_update_buf_length() { diff --git a/src/sound.h b/src/sound.h index 4bf0395..d97406f 100644 --- a/src/sound.h +++ b/src/sound.h @@ -31,5 +31,7 @@ void givealbuffer_cd(int16_t *buf); extern int sound_buf_len; void sound_update_buf_length(); +extern int sound_gain; + extern int SOUNDBUFLEN; #define MAXSOUNDBUFLEN (48000 / 10) diff --git a/src/soundopenal.c b/src/soundopenal.c index d24334c..b07695c 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -2,6 +2,7 @@ #include #include #include +#include #ifdef USE_OPENAL #ifdef __APPLE__ #include @@ -180,6 +181,9 @@ void givealbuffer(int32_t *buf) { int c; ALuint buffer; + double gain = pow(10.0, (double)sound_gain / 20.0); + + alSourcef(source[0], AL_GAIN, gain); alSourceUnqueueBuffers(source[0], 1, &buffer); // printf("U "); @@ -244,6 +248,9 @@ void givealbuffer_cd(int16_t *buf) if (processed>=1) { ALuint buffer; + double gain = pow(10.0, (double)sound_gain / 20.0); + + alSourcef(source[1], AL_GAIN, gain); alSourceUnqueueBuffers(source[1], 1, &buffer); // printf("U "); diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 5ba3393..cfbb7da 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 132267; +static size_t xml_res_size_26 = 133760; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -1860,40 +1860,42 @@ static unsigned char xml_res_file_26[] = { 116,97,114,116,61,34,49,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114, 97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70, 34,32,115,116,97,114,116,61,34,50,48,48,48,34,47,62,10,32,32,60,105,100, -115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34,32,115,116,97, -114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73, -78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,51,49,48,48, -34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70, -82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51,50,48,48,34, -47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116,97,116, -117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97,99,116,105, -118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, -101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,77,65, -67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97,116,104, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95,83, -84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97, -98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,83,78,68, +95,71,65,73,78,34,32,115,116,97,114,116,61,34,50,49,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,77, +95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,34,32, +115,116,97,114,116,61,34,51,48,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,73,78,80,85,84,95,83,67,65,76,69,34,32,115,116,97,114,116,61,34,51, +49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, +95,82,69,70,82,69,83,72,95,82,65,84,69,34,32,115,116,97,114,116,61,34,51, +50,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,66,97,114,34,32,110,97,109,101,61,34,115,116, +97,116,117,115,95,109,101,110,117,34,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,68,73,83,67,95,65,67,84,73,86,73,84,89,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,99,32,97, +99,116,105,118,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +77,65,67,72,73,78,69,95,77,79,85,78,84,95,80,65,84,72,83,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,117,110,116,32,112,97, +116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,72,79,87,95, +83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,117,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, 83,80,69,69,68,95,72,73,83,84,79,82,89,34,62,10,32,32,32,32,32,32,32,32, 60,108,97,98,101,108,62,83,112,101,101,100,32,104,105,115,116,111,114,121, @@ -2455,627 +2457,258 @@ static unsigned char xml_res_file_26[] = { 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, 49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, -32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,83,99,114,101,101,110,115,104,111,116,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,84,97,107,101,32,115,99,114, -101,101,110,115,104,111,116,92,116,67,116,114,108,43,65,108,116,43,80,97, -103,101,85,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,70,111,114,109,97,116, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84, -95,70,79,82,77,65,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,80,78,71,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77, -65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,84,73,70,70,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,50,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66, -77,80,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,79,117,116,112,117,116,32,108,101,118,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,114,109,97,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,50,32, +100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +43,95,52,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71, +65,73,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,43,95,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, +78,68,95,71,65,73,78,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,43,95,56,32,100,66,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,83,78,68,95,71,65,73,78,91,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,43,95,49,48,32,100,66,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,54,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,50,32,100,66,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,55,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,52, +32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73, +78,91,56,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,43,49,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68, +95,71,65,73,78,91,57,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,43,49,56,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,77,105,115,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114, +101,101,110,115,104,111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, 101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67, -82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,51,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,80,71,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,76,65, -83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, -108,97,115,104,32,115,99,114,101,101,110,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49, -60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,77,97,99,104,105,110,101,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,80, -65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105,100, -115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,67,68,82, -79,77,34,32,115,116,97,114,116,61,34,50,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, -60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, -70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, -74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, -69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, -32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, -95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, -48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, -101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, -61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115, -116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108,103,34,62,10, -32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, -73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32, -32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117,114,101,32,80, -67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, -101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, -110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, -10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, -62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, -111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, -98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79, -79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +82,69,69,78,83,72,79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,84,97,107,101,32,115,99,114,101,101,110,115,104,111,116, +92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,78,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78, +83,72,79,84,95,70,79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, +79,82,77,65,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, +67,82,69,69,78,83,72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,108,97,115,104,32,115,99,114,101, +101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105, +110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114, +116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,34,32,115,116,97,114,116,61, +34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,67,95,67,68,82,79,77,34,32,115,116,97,114,116,61, +34,50,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34,32,115,116,97,114, +116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32,115,116,97,114,116, +61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32,115,116,97,114,116, +61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, +110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116,97,114,116,61,34, +54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114, +116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116, +97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34, +32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, +73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72, +68,68,95,76,65,66,69,76,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,103, +117,114,101,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110, +102,105,103,117,114,101,32,80,67,101,109,60,47,116,105,116,108,101,62,10, +32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116, +101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79, +79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62, +48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +73,68,67,95,78,79,84,69,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,68,69,70,65,85,76,84, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,51,50,120,51,50,95,109,111,116,104,101,114,98,111, +97,114,100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, +65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, -108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, -85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, -80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, -105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, -61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, -120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, -65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, -67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, -32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3083,341 +2716,35 @@ static unsigned char xml_res_file_26[] = { 101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, 105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, -73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, -60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, -115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, -83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, -62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99, +101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101, +116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -3445,30 +2772,490 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, +61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, 121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, 66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110, +97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111, +114,121,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67,116, +114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, +75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109, +105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, +77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, +79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, +122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, +99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, 101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, +105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, +103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, @@ -3478,47 +3265,327 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, 99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, 116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, 112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, -73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, +65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, +115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, +97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, -47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105, +118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69, +76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, +83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 72c6a18..8fb2948 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -406,7 +406,7 @@ int wx_setupmenu(void* data) sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len/MIN_SND_BUF)/log(2))); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len/MIN_SND_BUF)/log(2))); + sprintf(menuitem, "IDM_SND_GAIN[%d]", (int)(sound_gain / 2)); wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); @@ -1030,6 +1030,12 @@ int wx_handle_command(void* hwnd, int wParam, int checked) wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); saveconfig(NULL); } + else if (ID_RANGE("IDM_SND_GAIN[start]", "IDM_SND_GAIN[end]")) + { + sound_gain = 2 * (wParam - wx_xrcid("IDM_SND_GAIN[start]")); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_IS("IDM_CDROM_DISABLED")) { if (cdrom_enabled) From 882da6537d666593fad23d83156325081da16e2d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 9 Dec 2017 15:48:21 +0000 Subject: [PATCH 0240/1050] Stop disc drive on write protect error. Fixes Hitchhiker's Guide booter. --- src/disc_sector.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/disc_sector.c b/src/disc_sector.c index 8aad435..b7805d6 100644 --- a/src/disc_sector.c +++ b/src/disc_sector.c @@ -284,6 +284,7 @@ void disc_sector_poll() if (writeprot[disc_sector_drive]) { fdc_writeprotect(); + disc_sector_state = STATE_IDLE; return; } if (index_count > 1) @@ -349,6 +350,7 @@ void disc_sector_poll() if (writeprot[disc_sector_drive]) { fdc_writeprotect(); + disc_sector_state = STATE_IDLE; return; } if (!index_count || fdc_get_bitcell_period() != get_bitcell_period() || From 5205f372e19162dc6959bdb320289d450161a11b Mon Sep 17 00:00:00 2001 From: Teemu N?tkinniemi Date: Sat, 9 Dec 2017 18:59:36 +0000 Subject: [PATCH 0241/1050] Fix compilation with MSYS2 --- src/cdrom-ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index f1b133c..62c8319 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -2,7 +2,7 @@ #include #include -#ifdef __MINGW64__ +#ifdef __MINGW64_VERSION_MAJOR #include "ntddcdrm.h" #include "ntddscsi.h" #else @@ -16,7 +16,7 @@ int cdrom_drive; int old_cdrom_drive; -#ifndef __MINGW64__ +#ifndef __MINGW64_VERSION_MAJOR typedef struct _CDROM_TOC_SESSION_DATA { UCHAR Length[2]; UCHAR FirstCompleteSession; From cb7b54bc8af9897c51e08a901347a3b415f202f6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 9 Dec 2017 22:09:30 +0000 Subject: [PATCH 0242/1050] Correct path of Western Digital WD1007V-SE1 ROM image. --- src/esdi_at.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/esdi_at.c b/src/esdi_at.c index c174d1c..927ebe9 100644 --- a/src/esdi_at.c +++ b/src/esdi_at.c @@ -794,7 +794,7 @@ void *wd1007vse1_init() esdi->status = STAT_READY | STAT_DSC; esdi->error = 1; /*No errors*/ - rom_init(&esdi->bios_rom, "roms/62-000279-061.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&esdi->bios_rom, "62-000279-061.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_set_handler(&esdi->bios_rom.mapping, rom_read, rom_readw, rom_readl, @@ -821,7 +821,7 @@ void wd1007vse1_close(void *p) static int wd1007vse1_available() { - return rom_present("roms/62-000279-061.bin"); + return rom_present("62-000279-061.bin"); } device_t wd1007vse1_device = From 30017ea58bdcb4f5e4f8ff276b07a38c91bb310d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 9 Dec 2017 22:10:43 +0000 Subject: [PATCH 0243/1050] Fix LPT port accesses on Amstrad machines - Amstrad machines work again. --- src/amstrad.c | 21 ++++++++++++++++----- src/lpt.h | 3 +++ src/model.c | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/amstrad.c b/src/amstrad.c index b5502c1..ca2861a 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -11,15 +11,20 @@ static uint8_t amstrad_dead; uint8_t amstrad_read(uint16_t port, void *priv) { + uint8_t temp; + pclog("amstrad_read : %04X\n",port); switch (port) { + case 0x378: + return lpt1_read(port, NULL); case 0x379: - return 7; + return lpt1_read(port, NULL) | 7; case 0x37a: - if (romset == ROM_PC1512) return 0x20; - if (romset == ROM_PC200) return 0x80; - return 0; + temp = lpt1_read(port, NULL) & 0x1f; + if (romset == ROM_PC1512) return temp | 0x20; + if (romset == ROM_PC200) return temp | 0x80; + return temp; case 0xdead: return amstrad_dead; } @@ -30,6 +35,12 @@ void amstrad_write(uint16_t port, uint8_t val, void *priv) { switch (port) { + case 0x378: + case 0x379: + case 0x37a: + lpt1_write(port, val, NULL); + break; + case 0xdead: amstrad_dead = val; break; @@ -108,6 +119,6 @@ void amstrad_init() io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); - io_sethandler(0x0379, 0x0002, amstrad_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x0378, 0x0003, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); } diff --git a/src/lpt.h b/src/lpt.h index 7d12593..117524a 100644 --- a/src/lpt.h +++ b/src/lpt.h @@ -5,6 +5,9 @@ extern void lpt2_init(uint16_t port); extern void lpt2_remove(); extern void lpt2_remove_ams(); +void lpt1_write(uint16_t port, uint8_t val, void *priv); +uint8_t lpt1_read(uint16_t port, void *priv); + void lpt1_device_init(); void lpt1_device_close(); diff --git a/src/model.c b/src/model.c index 805e0f0..e76a34c 100644 --- a/src/model.c +++ b/src/model.c @@ -282,6 +282,7 @@ void ams_init() AMSTRAD = 1; common_init(); mem_add_bios(); + lpt1_remove(); amstrad_init(); keyboard_amstrad_init(); nvr_init(); From 45b627dfcd96f3dd78ceffa5ea718d5a35956cf4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 10 Dec 2017 12:25:23 +0000 Subject: [PATCH 0244/1050] Fix timer usage in AT MFM controller. Fixes OS/2 v1.0 installation. --- src/mfm_at.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/mfm_at.c b/src/mfm_at.c index c3c7346..1084229 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -215,7 +215,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) // pclog("Restore\n"); mfm->command &= ~0x0f; /*Mask off step rate*/ mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -224,7 +224,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) // pclog("Seek to cylinder %i\n", mfm->cylinder); mfm->command &= ~0x0f; /*Mask off step rate*/ mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -239,7 +239,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) if (val & 2) fatal("Read with ECC\n"); mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -258,7 +258,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) // 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(); + timer_clock(); mfm->callback = 200 * IDE_TIME; timer_update_outstanding(); break; @@ -271,14 +271,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p) case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 30*IDE_TIME; timer_update_outstanding(); break; case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -286,7 +286,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) default: pclog("Bad MFM command %02X\n", val); mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -297,7 +297,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) case 0x3F6: /* Device control */ if ((mfm->fdisk & 4) && !(val & 4)) { - timer_process(); + timer_clock(); mfm->callback = 500*IDE_TIME; timer_update_outstanding(); mfm->reset = 1; @@ -307,7 +307,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) if (val & 4) { /*Drive held in reset*/ - timer_process(); + timer_clock(); mfm->callback = 0; timer_update_outstanding(); mfm->status = STAT_BUSY; @@ -331,7 +331,7 @@ void mfm_writew(uint16_t port, uint16_t val, void *p) { mfm->pos = 0; mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 6*IDE_TIME; timer_update_outstanding(); } @@ -402,7 +402,7 @@ uint16_t mfm_readw(uint16_t port, void *p) { mfm_next_sector(mfm); mfm->status = STAT_BUSY; - timer_process(); + timer_clock(); mfm->callback = 6*IDE_TIME; timer_update_outstanding(); } From 6cdb91a804a15bdf28511c02957972e9d4590cae Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 10 Dec 2017 12:36:40 +0000 Subject: [PATCH 0245/1050] Fix timer usage on WD1007V-SE1 ESDI controller. Fixes OS/2 v1.0 installation. --- src/esdi_at.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/esdi_at.c b/src/esdi_at.c index 927ebe9..ae8d81e 100644 --- a/src/esdi_at.c +++ b/src/esdi_at.c @@ -224,7 +224,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) // pclog("Restore\n"); esdi->command &= ~0x0f; /*Mask off step rate*/ esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -233,7 +233,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) // pclog("Seek to cylinder %i\n", esdi->cylinder); esdi->command &= ~0x0f; /*Mask off step rate*/ esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -243,7 +243,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) { case CMD_NOP: esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -256,7 +256,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) fatal("Read with ECC\n"); case 0xa0: esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -275,7 +275,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) // pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); esdi->command &= ~1; esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200 * IDE_TIME; timer_update_outstanding(); break; @@ -288,14 +288,14 @@ void esdi_write(uint16_t port, uint8_t val, void *p) case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 30*IDE_TIME; timer_update_outstanding(); break; case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -303,7 +303,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) case 0xe0: /*???*/ case CMD_READ_PARAMETERS: esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -312,7 +312,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) pclog("Bad esdi command %02X\n", val); case 0xe8: /*???*/ esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 200*IDE_TIME; timer_update_outstanding(); break; @@ -323,7 +323,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) case 0x3F6: /* Device control */ if ((esdi->fdisk & 4) && !(val & 4)) { - timer_process(); + timer_clock(); esdi->callback = 500*IDE_TIME; timer_update_outstanding(); esdi->reset = 1; @@ -333,7 +333,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) if (val & 4) { /*Drive held in reset*/ - timer_process(); + timer_clock(); esdi->callback = 0; timer_update_outstanding(); esdi->status = STAT_BUSY; @@ -357,7 +357,7 @@ void esdi_writew(uint16_t port, uint16_t val, void *p) { esdi->pos = 0; esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 6*IDE_TIME; timer_update_outstanding(); } @@ -428,7 +428,7 @@ uint16_t esdi_readw(uint16_t port, void *p) { esdi_next_sector(esdi); esdi->status = STAT_BUSY; - timer_process(); + timer_clock(); esdi->callback = 6*IDE_TIME; timer_update_outstanding(); } From 04cbcfb587c0baa943de7e1f728188bbc45ad7d1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 10 Dec 2017 17:34:36 +0000 Subject: [PATCH 0246/1050] Added Pentium 133 to Advanced/EV CPU list. --- src/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu.c b/src/cpu.c index 79e6ab6..1572d5a 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -420,6 +420,7 @@ CPU cpus_PentiumS5[] = {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6}, {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4}, {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, + {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7}, {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, From a957e87da47272132dc8faed770b48d4c32b67d8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 10 Dec 2017 17:42:02 +0000 Subject: [PATCH 0247/1050] Olivetti GO481 now only available if the BIOS is present. --- src/vid_paradise.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_paradise.c b/src/vid_paradise.c index f4a3776..80347e6 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -392,6 +392,11 @@ void paradise_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, ¶dise->svga); } +static int oli_go481_available() +{ + return (rom_present("oli_go481_lo.bin") && rom_present("oli_go481_hi.bin")); +} + device_t paradise_pvga1a_pc2086_device = { "Paradise PVGA1A (Amstrad PC2086)", @@ -431,7 +436,7 @@ device_t paradise_pvga1a_oli_go481_device = 0, paradise_pvga1a_oli_go481_init, paradise_close, - NULL, + oli_go481_available, paradise_speed_changed, paradise_force_redraw, paradise_add_status_info From 2ebbec2863d4bdb0a3923c0e301e230e0909c2dc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 10 Dec 2017 22:22:12 +0000 Subject: [PATCH 0248/1050] Fixed put_backslash() function - PCem now correctly reads default CMOS RAM files. --- src/config.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 663c349..b880aab 100644 --- a/src/config.c +++ b/src/config.c @@ -444,7 +444,10 @@ void put_backslash(char *s) { int c = strlen(s) - 1; if (s[c] != '/' && s[c] != '\\') - s[c] = '/'; + { + s[c+1] = '/'; + s[c+2] = 0; + } } char *get_extension(char *s) From 1edbb679f045126162f6cfdf39b3418e32974a65 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 09:06:19 +0000 Subject: [PATCH 0249/1050] Emulate memory spinner granularity on systems that don't implement wxSpinCtrl->SetIncrement(). --- src/wx-config.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/wx-config.c b/src/wx-config.c index 942c02c..d917449 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -1085,6 +1085,38 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 3, temp_joystick_type); } +#ifndef __WXGTK__ + /*Emulate spinner granularity on systems that don't implement wxSpinCtrl->SetIncrement()*/ + else if (wParam == WX_ID("IDC_MEMSPIN")) + { + int mem; + int granularity; + int granularity_mask; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + + granularity = models[temp_model].ram_granularity; + granularity_mask = granularity - 1; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + if (mem & granularity_mask) + { + if ((mem & granularity_mask) < (granularity / 2)) + { + /*Assume increase*/ + mem = (mem + granularity_mask) & ~granularity_mask; + } + else + { + /*Assumg decrease*/ + mem &= ~granularity_mask; + } + mem = wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + } + } +#endif return 0; } } From 6447d4d91ab82ddec0e45f726dd08622b160fd36 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 10:44:43 +0000 Subject: [PATCH 0250/1050] Fix automatic mouse type selection when changing model in configuration dialogue. --- src/wx-config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wx-config.c b/src/wx-config.c index d917449..672d208 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -868,7 +868,8 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) c++; } - if (mouse_valid(temp_mouse_type, temp_model)) + + if (mouse_valid(mouse_get_type(temp_mouse_type), temp_model)) wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); else wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); From 9ac6f975e2e9b6ecf3e6b7f51c0b5c0d08f700dc Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 16:32:23 +0000 Subject: [PATCH 0251/1050] Fixes to Linux CDROM IOCTL handling. --- src/cdrom-ioctl-linux.c | 184 +++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 97 deletions(-) diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c index 820e7e6..7b8ece1 100644 --- a/src/cdrom-ioctl-linux.c +++ b/src/cdrom-ioctl-linux.c @@ -16,8 +16,10 @@ 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 struct cdrom_tocentry toc[256]; +static int toc_tracks; static int first_track, last_track; +static int ioctl_fd = 0; int old_cdrom_drive; @@ -37,7 +39,6 @@ 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()); @@ -46,9 +47,8 @@ void ioctl_audio_callback(int16_t *output, int len) memset(output, 0, len * 2); return; } - fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - if (fd <= 0) + if (ioctl_fd <= 0) { memset(output, 0, len * 2); return; @@ -63,7 +63,7 @@ void ioctl_audio_callback(int16_t *output, int len) read_audio.nframes = 1; read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; - if (ioctl(fd, CDROMREADAUDIO, &read_audio) < 0) + if (ioctl(ioctl_fd, CDROMREADAUDIO, &read_audio) < 0) { // pclog("DeviceIoControl returned false\n"); memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); @@ -84,7 +84,7 @@ void ioctl_audio_callback(int16_t *output, int len) 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]; @@ -197,6 +197,7 @@ static int read_toc(int fd, struct cdrom_tocentry *btoc) { struct cdrom_tochdr toc_hdr; int track, err; + int c; //pclog("read_toc\n"); err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); if (err == -1) @@ -210,18 +211,23 @@ static int read_toc(int fd, struct cdrom_tocentry *btoc) //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); memset(btoc, 0, sizeof(btoc)); - for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) + c = 0; + for (track = 0; track < 256; track++) { - btoc[track].cdte_track = track; - btoc[track].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &btoc[track]); + btoc[c].cdte_track = track; + btoc[c].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &btoc[c]); if (err == -1) { // pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); - return 0; + continue; } -// 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); + c++; +// pclog("read_toc: %i Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, track, btoc[c].cdte_track, btoc[c].cdte_ctrl, btoc[c].cdte_adr, 0, btoc[c].cdte_addr.msf.minute, btoc[c].cdte_addr.msf.second, btoc[c].cdte_addr.msf.frame); } + + toc_tracks = c; + return 1; } @@ -232,26 +238,28 @@ static int ioctl_ready(void) struct cdrom_tochdr toc_hdr; struct cdrom_tocentry toc_entry; int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - if (fd <= 0) + if (ioctl_fd <= 0) return 0; - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + err = ioctl(ioctl_fd, CDROM_MEDIA_CHANGED, 0); + if (err) + tocvalid = 0; + + if (tocvalid) + return 1; + + err = ioctl(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); + err = ioctl(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) || @@ -261,11 +269,9 @@ static int ioctl_ready(void) int track; ioctl_cd_state = CD_STOPPED; - tocvalid = read_toc(fd, toc); - close(fd); - return 1; + tocvalid = read_toc(ioctl_fd, toc); } - close(fd); + return 1; } @@ -275,16 +281,14 @@ static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, i int lb = 0; int tv = 0; struct cdrom_tocentry lbtoc[100]; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - if (fd <= 0) + if (ioctl_fd <= 0) return 0; ioctl_cd_state = CD_STOPPED; - tv = read_toc(fd, lbtoc); - - close(fd); + if (!tocvalid) + tv = read_toc(ioctl_fd, lbtoc); if (!tv) return 0; @@ -307,25 +311,20 @@ static int ioctl_medium_changed(void) struct cdrom_tochdr toc_hdr; struct cdrom_tocentry toc_entry; int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - if (fd <= 0) + if (ioctl_fd <= 0) return 0; - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + err = ioctl(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); + err = ioctl(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) || @@ -394,38 +393,29 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) static void ioctl_eject(void) { - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) + if (ioctl_fd <= 0) return; - ioctl(fd, CDROMEJECT); - - close(fd); + ioctl(ioctl_fd, CDROMEJECT); } static void ioctl_load(void) { - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) + if (ioctl_fd <= 0) return; - ioctl(fd, CDROMEJECT); - - close(fd); + ioctl(ioctl_fd, CDROMEJECT); cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); } static int ioctl_readsector(uint8_t *b, int sector) { - int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - if (cdrom <= 0) + if (ioctl_fd <= 0) return -1; - lseek(cdrom, sector*2048, SEEK_SET); - read(cdrom, b, 2048); - close(cdrom); + + lseek(ioctl_fd, sector*2048, SEEK_SET); + read(ioctl_fd, b, 2048); return 0; } @@ -445,9 +435,8 @@ 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) + if (ioctl_fd <= 0) return; raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); @@ -456,7 +445,7 @@ static void ioctl_readsector_raw(uint8_t *b, int sector) 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); + err = ioctl(ioctl_fd, CDROMREADRAW, (void *) &raw_read_params); if (err == -1) { pclog("read_toc: CDROMREADTOCHDR failed\n"); @@ -465,8 +454,6 @@ static void ioctl_readsector_raw(uint8_t *b, int sector) memcpy(b, raw_read_params.b, 2352); - close(cdrom); - free(raw_read_params.msf); } @@ -476,16 +463,15 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in long size; int c,d; uint32_t temp; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + uint32_t last_address = 0; - if (fd <= 0) + if (ioctl_fd <= 0) return 0; ioctl_cd_state = CD_STOPPED; - tocvalid = read_toc(fd, toc); - - close(fd); + if (!tocvalid) + tocvalid = read_toc(ioctl_fd, toc); if (!tocvalid) return 4; @@ -495,9 +481,9 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in b[3] = last_track; d = 0; //pclog("Read TOC starttrack=%i\n", starttrack); - for (c = 1; c <= last_track; c++) + for (c = 0; c <= toc_tracks; c++) { - if (toc[c].cdte_track >= starttrack) + if (toc[c].cdte_track && toc[c].cdte_track >= starttrack) { d = c; break; @@ -505,17 +491,21 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in } b[2] = toc[c].cdte_track; last_block = 0; - for (c = d; c <= last_track; c++) + + for (c = d; c <= toc_tracks; 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)); + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address < last_address) + continue; + last_address = address; 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; @@ -537,6 +527,7 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in 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); @@ -554,25 +545,21 @@ 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) + if (ioctl_fd <= 0) return 0; session.addr_format = CDROM_MSF; - err = ioctl(fd, CDROMMULTISESSION, &session); + err = ioctl(ioctl_fd, CDROMMULTISESSION, &session); if (err == -1) - { - close(fd); return 0; - } - b[2] = 0; - b[3] = 0; + b[2] = 1; + b[3] = 1; b[len++] = 0; /*Reserved*/ - b[len++] = (toc[0].cdte_adr << 4) | toc[0].cdte_ctrl; - b[len++] = toc[0].cdte_track; + b[len++] = (toc[first_track].cdte_adr << 4) | toc[first_track].cdte_ctrl; + b[len++] = toc[first_track].cdte_track; b[len++] = 0; /*Reserved*/ if (msf) { @@ -599,12 +586,13 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen) 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) + if (ioctl_fd <= 0) return 0; - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) { pclog("read_toc: CDROMREADTOCHDR failed\n"); @@ -622,19 +610,15 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen) 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]); + err = ioctl(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; @@ -649,7 +633,7 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen) b[len++] = toc2[track].cdte_addr.msf.second; b[len++] = toc2[track].cdte_addr.msf.frame; } - close(fd); + return len; } @@ -674,31 +658,37 @@ static int ioctl_status() } void ioctl_reset() { - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); //pclog("ioctl_reset: fd=%i\n", fd); tocvalid = 0; - if (fd <= 0) + if (ioctl_fd <= 0) return; - tocvalid = read_toc(fd, toc); - - close(fd); + tocvalid = read_toc(ioctl_fd, toc); } void ioctl_set_drive(char d) { + ioctl_close(); atapi=&ioctl_atapi; + ioctl_open(d); } int ioctl_open(char d) { atapi=&ioctl_atapi; + ioctl_fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + return 0; } void ioctl_close(void) { + if (ioctl_fd) + { + close(ioctl_fd); + ioctl_fd = 0; + } } static void ioctl_exit(void) From baf6b83cfd44f948ece44020aca3f0d77221cbab Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 16:32:48 +0000 Subject: [PATCH 0252/1050] Improved pthread code. --- src/wx-thread.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/wx-thread.c b/src/wx-thread.c index 1015356..1ab591f 100644 --- a/src/wx-thread.c +++ b/src/wx-thread.c @@ -77,6 +77,7 @@ typedef struct event_pthread_t { pthread_cond_t cond; pthread_mutex_t mutex; + int state; } event_pthread_t; thread_t *thread_create(void (*thread_rout)(void *param), void *param) @@ -104,6 +105,7 @@ event_t *thread_create_event() pthread_cond_init(&event->cond, NULL); pthread_mutex_init(&event->mutex, NULL); + event->state = 0; return (event_t *)event; } @@ -113,12 +115,18 @@ void thread_set_event(event_t *handle) event_pthread_t *event = (event_pthread_t *)handle; pthread_mutex_lock(&event->mutex); + event->state = 1; pthread_cond_broadcast(&event->cond); pthread_mutex_unlock(&event->mutex); } void thread_reset_event(event_t *handle) { + event_pthread_t *event = (event_pthread_t *)handle; + + pthread_mutex_lock(&event->mutex); + event->state = 0; + pthread_mutex_unlock(&event->mutex); } int thread_wait_event(event_t *handle, int timeout) @@ -144,8 +152,11 @@ int thread_wait_event(event_t *handle, int timeout) pthread_mutex_lock(&event->mutex); if (timeout == -1) - pthread_cond_wait(&event->cond, &event->mutex); - else + { + while (!event->state) + pthread_cond_wait(&event->cond, &event->mutex); + } + else if (!event->state) pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); pthread_mutex_unlock(&event->mutex); From 68853090ab61c71f26221c5eacf8154b5ac83872 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 16:33:10 +0000 Subject: [PATCH 0253/1050] Remove unnecessary fatal()s from Voodoo x86-64 recompiler. --- src/vid_voodoo_codegen_x86-64.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index e6e1c5a..d729231 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -2525,7 +2525,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe4); break; case AFUNC_ASRC_ALPHA: - fatal("dest AFUNC_ASRC_ALPHA\n"); addbyte(0x66); /*PMULLW XMM4, R10(alookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2558,7 +2557,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_A_COLOR: - fatal("dest AFUNC_A_COLOR\n"); addbyte(0x66); /*PMULLW XMM4, XMM0*/ addbyte(0x0f); addbyte(0xd5); @@ -2593,7 +2591,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo case AFUNC_AONE: break; case AFUNC_AOMSRC_ALPHA: - //fatal("dest AFUNC_AOMSRC_ALPHA\n"); addbyte(0x66); /*PMULLW XMM4, R11(aminuslookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2626,7 +2623,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_AOM_COLOR: - fatal("dest AFUNC_AOM_COLOR\n"); addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); @@ -2672,7 +2668,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe4); break; case AFUNC_ASATURATE: - fatal("dest AFUNC_ASATURATE\n"); addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/ addbyte(0x41); addbyte(0x0f); @@ -2713,7 +2708,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); break; case AFUNC_ASRC_ALPHA: - //fatal("src AFUNC_ASRC_ALPHA\n"); addbyte(0x66); /*PMULLW XMM0, R10(alookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2746,7 +2740,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_A_COLOR: - //fatal("src AFUNC_A_COLOR\n"); addbyte(0x66); /*PMULLW XMM0, XMM6*/ addbyte(0x0f); addbyte(0xd5); @@ -2781,7 +2774,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo case AFUNC_AONE: break; case AFUNC_AOMSRC_ALPHA: - fatal("src AFUNC_AOMSRC_ALPHA\n"); addbyte(0x66); /*PMULLW XMM0, R11(aminuslookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2814,7 +2806,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); break; case AFUNC_AOM_COLOR: - fatal("src AFUNC_AOM_COLOR\n"); addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); From 74adbca249881f8fbaa682236863e56aafa3b619 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 16:43:29 +0000 Subject: [PATCH 0254/1050] Add ./configure option to create release build. --- Makefile.in | 13 ++++++----- aclocal.m4 | 60 ++++++++++++++++++++++++------------------------- configure | 54 +++++++++++++++++++++++++++++++++++++++----- configure.ac | 12 +++++++++- src/Makefile.am | 33 +++++++++++++++------------ src/Makefile.in | 11 +++++---- 6 files changed, 123 insertions(+), 60 deletions(-) diff --git a/Makefile.in b/Makefile.in index ca54b6c..903d123 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -308,6 +308,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -525,7 +526,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -551,7 +552,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -569,7 +570,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -579,7 +580,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/aclocal.m4 b/aclocal.m4 index f6be9fe..925cb54 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.15 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,9 +20,9 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 12 (pkg-config-0.29.2) - +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29) +dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl @@ -63,7 +63,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.2]) +[m4_define([PKG_MACROS_VERSION], [0.29]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -164,7 +164,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $2]) +AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -174,11 +174,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -195,7 +195,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -1591,7 +1591,7 @@ AC_DEFUN([AM_PATH_WXCONFIG], [ ]) AC_DEFUN([AM_PATH_WXRC], [WXRC_CHECK([$1],[$2])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1606,7 +1606,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -1622,14 +1622,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1681,7 +1681,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1712,7 +1712,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1903,7 +1903,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1979,7 +1979,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2176,7 +2176,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2197,7 +2197,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2218,7 +2218,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2268,7 +2268,7 @@ rm -f confinc confmf # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2307,7 +2307,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2336,7 +2336,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2383,7 +2383,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2402,7 +2402,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2483,7 +2483,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2543,7 +2543,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2571,7 +2571,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2590,7 +2590,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index c57343d..dd280fd 100755 --- a/configure +++ b/configure @@ -626,6 +626,8 @@ CPU_X86_64_FALSE CPU_X86_64_TRUE CPU_I386_FALSE CPU_I386_TRUE +RELEASE_BUILD_FALSE +RELEASE_BUILD_TRUE am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE @@ -703,6 +705,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -727,6 +730,7 @@ ac_user_opts=' enable_option_checking enable_silent_rules enable_dependency_tracking +enable_release_build enable_debug enable_networking enable_alsa @@ -794,6 +798,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1046,6 +1051,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1183,7 +1197,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1336,6 +1350,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1380,6 +1395,7 @@ Optional Features: do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build + --enable-release-build build for release --enable-debug build debug executable --enable-networking enable networking --enable-alsa use ALSA for MIDI @@ -4121,6 +4137,29 @@ fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build for release" >&5 +$as_echo_n "checking whether to build for release... " >&6; } +# Check whether --enable-release_build was given. +if test "${enable_release_build+set}" = set; then : + enableval=$enable_release_build; +fi + +if test "$enable_release_build" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + if test "$enable_release_build" = "yes"; then + RELEASE_BUILD_TRUE= + RELEASE_BUILD_FALSE='#' +else + RELEASE_BUILD_TRUE='#' + RELEASE_BUILD_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 $as_echo_n "checking whether to enable debugging... " >&6; } # Check whether --enable-debug was given. @@ -4423,8 +4462,8 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 -$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 +$as_echo_n "checking for SDL... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -4464,7 +4503,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -4482,7 +4521,7 @@ fi sdl_pc=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } sdl_pc=no else @@ -5585,6 +5624,10 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${RELEASE_BUILD_TRUE}" && test -z "${RELEASE_BUILD_FALSE}"; then + as_fn_error $? "conditional \"RELEASE_BUILD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${CPU_I386_TRUE}" && test -z "${CPU_I386_FALSE}"; then as_fn_error $? "conditional \"CPU_I386\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -6755,3 +6798,4 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + diff --git a/configure.ac b/configure.ac index 30b88bc..815aa33 100644 --- a/configure.ac +++ b/configure.ac @@ -13,6 +13,16 @@ AM_PROG_CC_C_O +AC_MSG_CHECKING([whether to build for release]) +AC_ARG_ENABLE(release_build, + AC_HELP_STRING([--enable-release-build], [build for release])) +if test "$enable_release_build" = "yes"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi +AM_CONDITIONAL(RELEASE_BUILD, [test "$enable_release_build" = "yes"]) + AC_MSG_CHECKING([whether to enable debugging]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [build debug executable])) @@ -139,4 +149,4 @@ AM_CONDITIONAL(OS_LINUX, [test "$build_linux" = "yes"]) AM_CONDITIONAL(OS_WINDOWS, [test "$build_win" = "yes"]) AM_CONDITIONAL(OS_MACOSX, [test "$build_macosx" = "yes"]) -AC_OUTPUT([Makefile src/Makefile]) \ No newline at end of file +AC_OUTPUT([Makefile src/Makefile]) diff --git a/src/Makefile.am b/src/Makefile.am index eccce04..dae893a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,17 +68,22 @@ pcem_CXXFLAGS += -DUSE_NETWORKING pcem_SOURCES += ne2000.c nethandler.c wx-hostconfig.c pcem_LDADD += slirp/libslirp.a endif - -if OS_MACOSX -pcem_SOURCES += cdrom-ioctl-osx.c -pcem_CFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -pcem_CXXFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -endif - -if OS_LINUX -pcem_SOURCES += cdrom-ioctl-linux.c -endif - -if !HAS_OFF64T -pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell -endif \ No newline at end of file + +if OS_MACOSX +pcem_SOURCES += cdrom-ioctl-osx.c +pcem_CFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +pcem_CXXFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +endif + +if OS_LINUX +pcem_SOURCES += cdrom-ioctl-linux.c +endif + +if !HAS_OFF64T +pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell +endif + +if RELEASE_BUILD +pcem_CFLAGS += -DRELEASE_BUILD +pcem_CXXFLAGS += -DRELEASE_BUILD +endif diff --git a/src/Makefile.in b/src/Makefile.in index 221de07..0233f65 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -107,6 +107,8 @@ bin_PROGRAMS = pcem$(EXEEXT) @OS_MACOSX_TRUE@am__append_13 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP @OS_LINUX_TRUE@am__append_14 = cdrom-ioctl-linux.c @HAS_OFF64T_FALSE@am__append_15 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell +@RELEASE_BUILD_TRUE@am__append_16 = -DRELEASE_BUILD +@RELEASE_BUILD_TRUE@am__append_17 = -DRELEASE_BUILD subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -479,6 +481,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -545,9 +548,9 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ $(am__append_9) $(am__append_11) $(am__append_14) pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ --cflags) $(am__append_5) $(am__append_7) $(am__append_12) \ - $(am__append_15) + $(am__append_15) $(am__append_16) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) $(am__append_8) $(am__append_13) + --cflags) $(am__append_8) $(am__append_13) $(am__append_17) pcem_LDADD = @LIBS@ $(am__append_1) $(am__append_10) all: all-am From 5c9b74a0ec2052e3b4d2c8cd7a9c73e44ace66bb Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 20:33:31 +0000 Subject: [PATCH 0255/1050] Fix uninitialised variable in wx-hostconfig.c --- src/wx-hostconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wx-hostconfig.c b/src/wx-hostconfig.c index 95772bc..9dff296 100644 --- a/src/wx-hostconfig.c +++ b/src/wx-hostconfig.c @@ -108,7 +108,7 @@ int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM for (dev = alldevs; dev; dev = dev->next) { pcap_t *conn = _pcap_open_live(dev->name, ETH_MAX_PACKET, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf); - int datalink; + int datalink = 0; if (conn) { From e6d3d05d8555dbe9c8eab9d1249fcc2caaed746b Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 20:33:54 +0000 Subject: [PATCH 0256/1050] Update readme.txt for v13 release. --- readme.txt | 1163 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 732 insertions(+), 431 deletions(-) diff --git a/readme.txt b/readme.txt index 95b22e3..4761654 100644 --- a/readme.txt +++ b/readme.txt @@ -1,206 +1,94 @@ -PCem v12 +PCem v13 PCem is licensed under the GPL, see COPYING for more details. -Changes since v11: +Changes since v12: -- New machines added - AMI 386DX, MR 386DX -- New graphics cards - Plantronics ColorPlus, Wyse WY-700, Obsidian SB50, Voodoo 2 -- CPU optimisations - up to 50% speedup seen -- 3DFX optimisations -- Improved joystick emulation - analogue joystick up to 8 buttons, CH Flightstick Pro, ThrustMaster FCS, SideWinder pad(s) -- Mouse can be selected between serial, PS/2, and IntelliMouse -- Basic 286/386 prefetch emulation - 286 & 386 performance much closer to real systems -- Improved CGA/PCjr/Tandy composite emulation +- New machines added - Atari PC3, Epson PC AX, Epson PC AX2e, GW-286CT GEAR, IBM PS/2 Model 30-286, + IBM PS/2 Model 50, IBM PS/2 Model 55SX, IBM PS/2 Model 80, IBM XT Model 286, KMX-C-02, + Samsung SPC-4200P, Samsung SPC-4216P, Toshiba 3100e, +- New graphics cards - MDSI Genius, Plantronics ColorPlus +- New sound cards added - Disney Sound Source, Ensoniq AudioPCI (ES1371), LPT DAC, Sound Blaster PCI 128 +- New hard drive controllers added - AT Fixed Disk Adapter, DTC 5150X, Fixed Disk Adapter (Xebec), + IBM ESDI Fixed Disk Controller, Western Digital WD1007V-SE1 +- New SCSI adapters added - Adaptec AHA-1542C, BusLogic BT-545S, Longshine LCS-6821N, Rancho RT1000B, + Trantor T130B +- New network adapters added - NE2000 compatible +- New cross-platform GUI +- Voodoo SLI emulation +- Improvements to Sound Blaster emulation +- Improvements to Pentium timing - Various bug fixes +- Minor optimisations + +Thanks to AmatCoder, basic2004, bit, dns2k, ecksemess, Greatpsycho, hOMER247, James-F, John Elliott, +JosepMa, leilei, neozeed, ruben_balea, SA1988 and tomaszkam for contributions towards this release. PCem emulates the following machines: -IBM 5150 PC (1981) -The original PC. This shipped in 1981 with a 4.77mhz 8088, 64k of RAM, and a cassette port. -Disc drives quickly became standard, along with more memory. - -ROM files needed: - -ibmpc\pc102782.bin -ibmpc\basicc11.f6 -ibmpc\basicc11.f8 -ibmpc\basicc11.fa -ibmpc\basicc11.fc - - -IBM 5160 XT (1983) -From a hardware perspective, this is a minor tweak of the original PC. It originally shipped -with 128k of RAM and a 10mb hard disc, both of which could be easily fitted to the 1981 machine. -However, this was targetted as businesses and was more successful than the original. - -ROM files needed: - -ibmxt\5000027.u19 -ibmxt\1501512.u18 - - -IBM PCjr (1984) -A home machine, which had better graphics and sound than most XTs but was not hardware compatible -with the PC. - -ROM files needed: - -ibmpcjr\bios.rom - - -IBM AT (1984) -This was the 'next generation' PC, fully 16-bit with an 80286. The original model came with a 6mhz -286, which ran three times as fast as the XT. This model also introduced EGA. - -ROM files needed: - -ibmat\at111585.0 -ibmat\at111585.1 - - -Olivetti M24 (1984) -An enhanced XT clone, also known as the AT&T PC 6300. Has an 8086 CPU, and an unusual 'double-res' -CGA display. - -ROM files needed: - -olivetti_m24\olivetti_m24_version_1.43_low.bin -olivetti_m24\olivetti_m24_version_1.43_high.bin - - -Tandy 1000 (1984) -This is a clone of the unsuccessful IBM PCjr, which added better graphics and sound to the XT, -but removed much expandability plus some other hardware (such as the DMA controller). The Tandy -puts back the DMA controller and ISA slots, making it a much more useful machine. Many games -from the late 80s support the Tandy. - -ROM files needed: - -tandy\tandy1t1.020 - - -Tandy 1000HX (1987) -A Tandy 1000 with a faster 7.16 MHz 8088, and DOS in ROM. - -ROM files needed: - -tandy1000hx\v020000.u12 - - -Tandy 1000SL/2 (1989) -An enhanced Tandy 1000 with a 9.54 MHz 8086, and enhanced graphics and sound. - -ROM files needed: - -tandy1000sl2\8079047.hu1 -tandy1000sl2\8079048.hu2 - - -DTK Clone XT (1986) -A generic clone XT board. - -ROM files needed: - -dtk\dtk_erso_2.42_2764.bin - - -Amstrad PC1512 (1986) -This was Amstrad's first entry into the PC clone market (after the CPC and PCW machines), and -was the first cheap PC available in the UK, selling for only £500. It was a 'turbo' clone, -having an 8mhz 8086, as opposed to an 8088, and had 512k RAM as standard. It also had a -perculiar modification to its onboard CGA controller - the 640x200 mode had 16 colours instead -of the usual 2. This was put to good use by GEM, which shipped with the machine. - -Amstrad's CGA implementation has a few oddities, these are emulated as best as possible. This -mainly affects games defining unusual video modes, though 160x100x16 still works (as on the real -machine). - -ROM files needed: - -pc1512\40043.v1 -pc1512\40044.v2 -pc1512\40078.ic127 - - -Amstrad PC1640 (1987) -Amstrad's followup to the PC1512, the PC1640 had 640k of RAM and onboard EGA, but was otherwise -mostly the same. - -ROM files needed: - -pc1640\40043.v3 -pc1640\40044.v3 -pc1640\40100 - - -Sinclair PC200/Amstrad PC20 (1988) -This was Amstrad's entry to the 16-bit home computer market, intended to compete with the Atari -ST and Commodore Amiga. It's similar to the PC1512, but is based on Amstrad's portable PPC512 -system. With stock CGA and PC speaker, it couldn't compare with the ST or Amiga. - -ROM files needed: - -pc200\pc20v2.0 -pc200\pc20v2.1 -pc200\40109.bin - - -Schneider Euro PC (1988) -A German XT clone. An 'all-in-one' system like the Sinclair PC200. I don't know much about this -machine to be honest! This doesn't appear to work with the XTIDE BIOS, so therefore this is the -only model that does not support hard discs. - -ROM files needed: - -europc\50145 -europc\50146 - - -(c)Anonymous Generic Turbo XT BIOS (1988?) -This is a BIOS whose source code was made available on Usenet in 1988. It appears to be an -anonymous BIOS from an XT clone board. It was then heavily modified to fix bugs. The history of -this BIOS (and the source code) is at http://dizzie.narod.ru/bios.txt - -ROM files needed: - -genxt\pcxt.rom - +8088 based : AMI XT clone (1989) -ROM files needed: - -amixt\ami_8088_bios_31jan89.bin - - -DTK XT clone (1988) +8088 at 8+ MHz, 64-640kb RAM. ROM files needed: - -dtk\dtk_erso_2.42_2764.bin + amixt\ami_8088_bios_31jan89.bin -VTech Laser Turbo XT (1987) +Atari PC3 (19xx) + +8088 at 8 MHz, 640kb RAM. ROM files needed: - -ltxt\27c64.bin + ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN -VTech Laser XT3 (1989) +DTK Clone XT (1986) + +8088 at 8/10 MHz, 64kb-640kb RAM. ROM files needed: - -lxt3\27c64d.bin + dtk/dtk_erso_2.42_2764.bin -Phoenix XT clone (1986) +(c)Anonymous Generic Turbo XT BIOS (1988?) + +8088 at 8+ MHz, 64-640kb RAM. ROM files needed: + genxt\pcxt.rom -pxxt\000p001.bin + +IBM PC (1981) + +8088 at 4.77 MHz, 16-640kb RAM (PCem emulates minimum 64kb) + +ROM files needed: + ibmpc\pc102782.bin + ibmpc\basicc11.f6 + ibmpc\basicc11.f8 + ibmpc\basicc11.fa + ibmpc\basicc11.fc + + +IBM PCjr (1984) + +8088 at 4.77 MHz, 64-640kb RAM (PCem emulates minimum 128kb), built-in 16 colour graphics, 3 voice sound. +Not generally PC compatible. + +ROM files needed: + ibmpcjr\bios.rom + + +IBM XT (1983) + +8088 at 4.77 MHz, 64-640kb RAM + +ROM files needed: + ibmxt\5000027.u19 + ibmxt\1501512.u18 Juko XT clone (1988) @@ -210,45 +98,130 @@ ROM files needed: jukopc\000o001.bin -Commodore PC30-III (1988) -A fairly generic 286 clone. +Phoenix XT clone (1986) ROM files needed: -cmdpc30\commodore pc 30 iii even.bin -cmdpc30\commodore pc 30 iii odd.bin +pxxt\000p001.bin + + +Schneider Euro PC (1988) + +ROM files needed: + +europc\50145 +europc\50146 + + +Tandy 1000 (1984) + +8088 at 4.77 MHz, 128kb-640kb RAM, built-in 16 colour graphics + 3 voice sound + +ROM files needed: + tandy\tandy1t1.020 + + +Tandy 1000HX (1987) + +8088 at 7.16 MHz, 256-640kb RAM, built-in 16 colour graphics + 3 voice sound. +Has DOS 2.11 in ROM. +A Tandy 1000 with a faster 7.16 MHz 8088, and DOS in ROM. + +ROM files needed: + tandy1000hx\v020000.u12 + + +VTech Laser Turbo XT (1987) + +ROM files needed: + +ltxt\27c64.bin + + + +8086 based : + + +Amstrad PC1512 (1986) + +8086 at 8 MHz, 512kb-640kb RAM, enhanced CGA (supports 640x200x16), custom mouse port. + +ROM files needed: + pc1512\40043.v1 + pc1512\40044.v2 + pc1512\40078.ic127 + + +Amstrad PC1640 (1987) + +8086 at 8 MHz, 640kb RAM, built-in Paradise EGA, custom mouse port. + +ROM files needed: + pc1640\40043.v3 + pc1640\40044.v3 + pc1640\40100 Amstrad PC2086 (1989) -The PC2086 is essentially a PC1640 with VGA and 3.5" floppy drives. + +8086 at 8 MHz, 640kb, built-in VGA. ROM files needed: - -pc2086\40179.ic129 -pc2086\40180.ic132 -pc2086\40186.ic171 + pc2086\40179.ic129 + pc2086\40180.ic132 + pc2086\40186.ic171 Amstrad PC3086 (1990) -The PC3086 is a version of the PC2086 with a more standard case. + +8086 at 8 MHz, 640kb, built-in VGA. + +ROM files needed: + pc3086\fc00.bin + pc3086\c000.bin + + +Olivetti M24 (1984) + +8086 at 8 MHz, 128kb-640kb RAM, built-in enhanced CGA (supports 640x400x2). + +ROM files needed: + olivetti_m24\olivetti_m24_version_1.43_low.bin + olivetti_m24\olivetti_m24_version_1.43_high.bin + + +Sinclair PC200/Amstrad PC20 (1988) + +8086 at 8 MHz, 512-640kb RAM, built-in CGA. + +ROM files needed: + pc200\pc20v2.0 + pc200\pc20v2.1 + pc200\40109.bin + + +Tandy 1000SL/2 (1989) + +8086 at 9.54 MHz, 512-768kb RAM, built-in 16 colour graphics + 4 voice sound. + +ROM files needed: + tandy1000sl2\8079047.hu1 + tandy1000sl2\8079048.hu2 + + +VTech Laser XT3 (1989) ROM files needed: -pc3086\fc00.bin -pc3086\c000.bin +lxt3\27c64d.bin -Dell System 200 (1990?) -This is a pretty generic 286 clone with a Phoenix BIOS. -ROM files needed: - -dells200\dell0.bin -dells200\dell1.bin +286 based : AMI 286 clone (1990) -This is a generic 286 clone with an AMI BIOS. +286 at 8+ MHz, 512kb - 16MB RAM. ROM files needed: @@ -256,71 +229,237 @@ ami286\amic206.bin Award 286 clone (1990) -This is a generic 286 clone with an Award BIOS. +286 at 8+ MHz, 512kb - 16MB RAM. ROM files needed: award286\award.bin +Commodore PC30-III (1988) +286 at 12 MHz, 512kb - 16MB RAM. + +ROM files needed: + +cmdpc30\commodore pc 30 iii even.bin +cmdpc30\commodore pc 30 iii odd.bin + + +Dell System 200 (1990?) + +286 at 12 MHz, 640kb-16MB RAM. + +ROM files needed: + dells200\dell0.bin + dells200\dell1.bin + + +Epson PC AX (1989) + +286, 256kb - 16MB RAM. + +ROM files needed : + epson_pcax\EVAX + epson_pcax\ODAX + + +Epson PC AX2e (1989) + +286 at 12 MHz, 256kb - 16MB RAM. + +ROM files needed : + epson_pcax2e\EVAX + epson_pcax2e\ODAX + + +GW-286CT GEAR + +286 at 8+ MHz, 512kb - 16MB RAM. + +ROM files needed: + + gw286ct/2ctc001.bin + + +IBM AT (1984) + +286 at 6 or 8 MHz, 256kb-16mb RAM + +ROM files needed: + ibmat\at111585.0 + ibmat\at111585.1 + + IBM PS/1 Model 2011 (1990) -This is a 286 with integrated VGA and a basic GUI and DOS 4.01 in ROM. -ROM files needed: +286 at 10 MHz, 512kb-16MB RAM, built-in VGA, DOS 4.01 + GUI menu system in ROM. -ibmps1\f80000.bin +ROM files needed : + ibmps1\f80000.bin -Compaq Deskpro 386 (1989) -An early 386 system. I don't think this BIOS is from the original 1986 version -(the very first 386 system), but from a 1989 refresh. +IBM PS/2 Model 30-286 (1988) -ROM files needed: +286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. -deskpro386\109592-005.u11.bin -deskpro386\109591-005.u13.bin +ROM files needed : + ibmps2_m30_286\33f5381a.bin -IBM PS/1 Model 2121 (1990) -This is a 386SX with integrated VGA. +IBM PS/2 Model 50 (1987) -ROM files needed: +286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. -ibmps1_2121\fc0000.bin +ROM files needed : + i8550021\90x7420.zm13 + i8550021\90x7423.zm14 + i8550021\90x7426.zm16 + i8550021\90x7429.zm18 + + +IBM XT Model 286 (1986) + +286 at 6, 256kb-16mb RAM + +ROM files needed : + ibmxt286\BIOS_5162_21APR86_U34_78X7460_27256.BIN + ibmxt286\BIOS_5162_21APR86_U35_78X7461_27256.BIN + + +Samsung SPC-4200P + +286 at 12 MHz, 512kb - 2MB RAM + +ROM files needed : +spc4200p\u8.01 + + +Samsung SPC-4216P + +286 at 12 MHz, 1MB - 5MB RAM + +ROM files needed : + spc4216p\phoenix.bin +or + spc4216p\7101.u8 + spc4216p\ac64.u10 + + +Toshiba 3100e (1986) + +286 at 12 MHz, 1MB - 5MB RAM, CGA on gas-plasma display + +PCem maps [Fn] to right-Ctrl and right-Alt. + +ROM files needed : + t3100e\t3100e_font.bin + t3100e\t3100e.rom + + + +386SX based : Acermate 386SX/25N (1992?) -An integrated 386SX clone, with onboard Oak SVGA and IO. -ROM files needed: +386SX at 25 MHz, 2-16MB RAM, built-in Oak SVGA. -acer386\acer386.bin -acer386\oti067.bin +ROM files needed : + acer386\acer386.bin + acer386\oti067.bin + + +AMI 386SX clone (1994) + +386SX at 25 MHz, 1-16MB RAM. + +ROM files needed : + ami386\ami386.bin + + +Amstrad MegaPC (1992) + +386SX at 25 MHz, 1-16MB RAM, built-in VGA. + +The original machine had a built-in Sega MegaDrive. This is not emulated in PCem. + +ROM files needed : + megapc\41651-bios lo.u18 + megapc\211253-bios hi.u19 DTK 386SX clone (1990) -ROM files needed: +386SX, 512kb - 16MB RAM. + +ROM files needed : dtk386\3cto001.bin -Amstrad MegaPC (1992) -A 386SX clone (otherwise known as the PC7386SX) with a built-in Sega Megadrive. Only the PC section -is emulated, obv. +Epson PC AX3 (1989) + +386SX at 16 MHz, 256kb-16MB RAM. + +ROM files needed : + + epson_pcax3\EVAX3 + epson_pcax3\ODAX3 + + +IBM PS/1 Model 2121 (1990) + +386SX at 20 MHz, 1MB-16MB RAM, built-in VGA. ROM files needed: - -megapc\41651-bios lo.u18 -megapc\211253-bios hi.u19 + ibmps1_2121\fc0000.bin -AMI 386SX clone (1994) -This is a generic 386SX clone with an AMI BIOS. +IBM PS/2 Model 55SX (1989) + +386SX at 16 MHz, 1MB-8MB RAM, built-in VGA, MCA bus. + +ROM files needed : + i8555081\33f8146.zm41 + i8555081\33f8145.zm40 + + +KMX-C-02 + +386SX, 512kb-16MB RAM. + +ROM files needed : + kmxc02\3ctm005.bin + + + +386DX based : + + +AMI 386DX clone (1994) + +386DX at 40 MHz, 1-32MB RAM. ROM files needed: + ami386dx\opt495sx.ami -ami386\ami386.bin + +Compaq Deskpro 386 (1989) + +386DX at 20 MHz, 1MB-15MB RAM. + +ROM files needed: + deskpro386\109592-005.u11.bin + deskpro386\109591-005.u13.bin + + +IBM PS/2 Model 80 (1987) + +386DX at 20 MHz, 1MB-12MB RAM, built-in VGA, MCA bus. + +ROM files needed : + i8580111\15f6637.bin + i8580111\15f6639.bin MR 386DX clone (1994) @@ -331,83 +470,86 @@ ROM files needed: mr386dx\opt495sx.mr -AMI 386DX clone (1994) -This is a generic 386DX clone with an AMI BIOS. This is the only currently emulated 386DX system -to support an external cache. -ROM files needed: - -ami386dx\opt495sx.ami +486 based : AMI 486 clone (1993) -This is a generic 486 clone with an AMI BIOS. The BIOS came from my 486SX/25, bought in December -1993. + +486 at 16-66 MHz, 1-32MB RAM. ROM files needed: - -ami486\ami486.bin + ami486\ami486.bin AMI WinBIOS 486 clone (1994) -A 486 clone with a newer AMI BIOS. + +486 at 16-66 MHz, 1-32MB RAM. ROM files needed: - -win486\ali1429g.amw + win486\ali1429g.amw Award SiS 496/497 (1995) -A 486 clone using the SiS 496/497 chipset, with PCI bus and Award BIOS. + +486 at 16-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive +at 63-83 MHz. 1-64MB RAM. ROM files needed: - -sis496\sis496-1.awa + sis496\sis496-1.awa -Intel Premiere/PCI (Batman's Revenge) (1994) -A Socket 4 based board with 430LX chipset. -ROM files needed: - -revenge\1009af2_.bi0 -revenge\1009af2_.bi1 - - -Intel Advanced/EV (Endeavor) (1995) -A Socket 5/7 based board with 430FX chipset. The real board has a Sound Blaster Vibra 16 on board, -which is not emulated - use a discrete card instead. Some Advanced/EVs also had a Trio64 on board, -the emulated board does not have this either. - -ROM files needed: - -endeavor\1006cb0_.bi0 -endeavor\1006cb0_.bi1 +Pentium based : Award 430VX PCI (1996) -A generic Socket 5/7 board with 430VX chipset. + +Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, +Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- +PR400(285 MHz), IDT WinChip at 75-240 MHz. 1-128MB RAM (PCem allows up to 256). ROM files needed: + 430vx\55xwuq0e.bin + + +Intel Advanced/EV (Endeavor) (1995) + +Pentium at 75-200 MHz, 1-128MB RAM. + +The real board has a Sound Blaster 16 onboard, and optionally an S3 Trio64. Neither +are emulated as onboard devices. + +ROM files needed: + endeavor\1006cb0_.bi0 + endeavor\1006cb0_.bi1 + + +Intel Premiere/PCI (Batman's Revenge) (1994) + +Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz. + +ROM files needed: + revenge\1009af2_.bi0 + revenge\1009af2_.bi1 -430vx\55xwuq0e.bin PCem emulates the following graphics adapters : -MDA -The original PC adapter. This displays 80x25 text in monochrome. + +MDA (1981) +80x25 monochrome text. -Hercules -A clone of MDA, with the addition of a high-resolution 720x348 graphics mode. +CGA (1981) +40x25 and 80x25 text, 320x200 in 4 colours, 620x200 in 2 colours. Supports composite +output for ~16 colours. -CGA -The most common of the original adapters, supporting 40x25 and 80x25 text, and -320x200 in 4 colours, 640x200 in 2 colours, and a composite mode giving 160x200 -in 16 colours. +Hercules (1982) +80x25 monochrome text, 720x348 in monochrome. Plantronics ColorPlus @@ -418,100 +560,134 @@ Wyse WY-700 A CGA-compatible board, with support for a 1280x800 mode -IBM EGA -The original 1984 IBM EGA card, with 256k VRAM. +IBM EGA (1984) +Text up to 80x43, graphics up to 640x350 in 16 colours. ROM files needed: -ibm_6277356_ega_card_u44_27128.bin + ibm_6277356_ega_card_u44_27128.bin Hercules InColor An enhanced Hercules with a custom 720x350 16 colour mode. -IBM VGA -The original VGA card. +Unaccelerated (S)VGA cards : + + +ATI VGA Edge-16 +512kb VRAM, supports up to 8-bit colour. ROM files needed: -ibm_vga.bin + vgaedge16.vbi + + +ATI VGA Charger +512kb VRAM, supports up to 8-bit colour. + +ROM files needed: + bios.bin + + +IBM VGA (1987) +256kb VRAM, Text up to 80x50, graphics up to 320x200 in 256 colours or 640x480 in 16 colours. + +ROM files needed: + ibm_vga.bin + + +OAK OTI-067 +256kb-512kb VRAM, supports up to 8-bit colour. + +ROM files needed: + oti067\bios.bin + + +Olivetti GO481 (Paradise PVGA1A) +512kb VRAM, supports up to 8-bit colour. + +ROM files needed : + oli_go481_lo.bin + oli_go481_hi.bin Trident 8900D SVGA -A low cost SVGA board circa 1992/1993. Not the greatest board in it's day, but -it has a reasonable VESA driver and (buggy) 15/16/24-bit colour modes. +256kb-1MB VRAM, supports up to 24-bit colour. ROM files needed: -trident.bin + trident.bin + + +Tseng ET4000AX SVGA +1MB VRAM, supports up to 8-bit colour. + +ROM files needed: + et4000.bin + + +2D accelerated SVGA cards : + +ATI Graphics Pro Turbo +Mach64GX based. 1-4MB VRAM. + +ROM files needed: + mach64gx\bios.bin + + +ATI Video Xpression +Mach64VT2 based. 2-4MB VRAM. Has video acceleration. + +ROM files needed : + atimach64vt2pci.bin + + +Diamond Stealth 32 SVGA +ET4000/W32p based. 1-2MB VRAM. + +ROM files needed: + et4000w32.bin + + +Number Nine 9FX +S3 Trio64 based. 1-2MB VRAM. + +ROM files needed: + s3_764.bin + + +Paradise Bahamas 64 +S3 Vision864 based. 1-4MB VRAM. + +ROM files needed: + bahamas64.bin + + +Phoenix S3 Trio32 +S3 Trio32 based. 512kb-2MB VRAM. + +ROM files needed: + 86c732p.bin + + +Phoenix S3 Trio64 +S3 Trio64 based. 1MB-4MB VRAM. + +ROM files needed: + 86c764x1.bin Trident TGUI9440 -A later Trident board with GUI acceleration. Windows 9x doesn't include drivers -for this, so they have to be downloaded and installed separately. +Trident TGUI9440 based. 1-2MB VRAM. ROM files needed: 9440.vbi -Tseng ET4000AX SVGA -A somewhat better SVGA board than the Trident, here you get better compatibility -and speed (on the real card, not the emulator) in exchange for being limited to -8-bit colour. -ROM files needed: -et4000.bin - - -Diamond Stealth 32 SVGA -An ET4000/W32p based board, has 15/16/24-bit colour modes, plus acceleration. - -ROM files needed: -et4000w32.bin - - -Paradise Bahamas 64 -An S3 Vision864 based board. - -ROM files needed: -bahamas64.bin - - -Number Nine 9FX -An S3 Trio64 based board. - -ROM files needed: -s3_764.bin - - -ATI VGA Edge-16 -A basic SVGA clone. - -ROM files needed: -vgaedge16.vbi - - -ATI VGA Charger -A basic SVGA clone, similar to the Edge-16. - -ROM files needed: -bios.bin - - -ATI Graphics Pro Turbo -A Mach64GX based board. - -ROM files needed: -mach64gx/bios.bin - - -OAK OTI-067 -A basic SVGA clone. - -ROM files needed: -oti067/bios.bin +3D accelerated SVGA cards : Diamond Stealth 3D 2000 -An S3 ViRGE/325 based board. +S3 ViRGE/325 based. 2-4MB VRAM. PCem emulates the ViRGE S3D engine in software. This works with most games I tried, but there may be some issues. The Direct3D drivers for the /325 are fairly poor (often showing @@ -520,18 +696,22 @@ as missing triangles), so use of the /DX instead is recommended. The streams processor (video overlay) is also emulated, however many features are missing. ROM files needed: -s3virge.bin + s3virge.bin S3 ViRGE/DX -An S3 ViRGE/DX based board. The drivers that come with Windows are similar to those for the -/325, however better ones do exist (try the 8-21-1997 version). With the correct drivers, -many early Direct3D games work okay (if slowly). +S3 ViRGE/DX based. 2-4MB VRAM. + +The drivers that come with Windows are similar to those for the /325, however better ones +do exist (try the 8-21-1997 version). With the correct drivers, many early Direct3D games +work okay (if slowly). ROM files needed: 86c375_1.bin +3D only cards : + 3DFX Voodoo Graphics 3D accelerator. Widely supported in late 90s games. @@ -607,7 +787,7 @@ The standard beeper on all PCs. Supports samples/RealSound. Tandy PSG The Texas Instruments chip in the PCjr and Tandy 1000. Supports 3 voices plus noise. I reused the emulator in B-em for this (slightly modified). -v11 now emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 +PCem emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 (currently assigned to the Tandy 1000HX). Maniac Mansion and Zak McKraken will only sound correct on the latter. @@ -662,6 +842,111 @@ from compatible boards with additional components (eg Turtle Beach Monte Carlo) Innovation SSI-2001 SID6581. Emulated using resid-fp. Board is fixed to port 280. +Ensoniq AudioPCI (ES1371) / Sound Blaster PCI 128 +Basic PCI sound card. Emulates Sound Blaster in software. + + +PCem emulates the following hard drive controllers : + +[MFM] Fixed Disk Adapter (Xebec) +MFM controller originally included in the IBM XT. This controller only supports HD types 0, 2, 13 +and 16. + +ROM files needed : +ibm_xebec_62x0822_1985.bin + + +[MFM] DTC 5150X +8-bit MFM controller. To configure drive types, run DEBUG.EXE and enter 'g=c800:5'. + +ROM files needed : +dtc_cxd21a.bin + + +[MFM] AT Fixed Disk Adapter +MFM controller originally included in the IBM AT. Supported by all AT-compatible BIOSes. + + +[ESDI] Western Digital WD1007V-SE1 +16-bit ESDI controller. + +ROM files needed : +62-000279-061.bin + + +[ESDI] IBM ESDI Fixed Disk Controller +MCA ESDI controller. Only supported on PS/2 models. + +ROM files needed : +90x8969.bin +90x8970.bin + + +[IDE] Standard IDE +Standard IDE controller. Supported by all AT-compatible BIOSes. Use this if in any doubt! + + +[IDE] XTIDE +8-bit IDE controller. The BIOS is available at : + +http://code.google.com/p/xtideuniversalbios/ + +v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues. + +ROM files needed : +ide_xt.bin + + +[IDE] XTIDE (AT) +16-bit IDE controller. + +ROM files needed : +ide_at.bin + + +[IDE] XTIDE (PS/1) +IDE controller for the PS/1 model 2033. For this machine you will need BIOS version v1.1.5. The +PS/1 is a bit fussy with XTIDE, and I've found that it works best when the XTIDE configuration +has 'Full Operating Mode' disabled. + +ROM files needed : +ide_at_1_1_5.bin + + +[SCSI] Longshine LCS-6821N +8-bit SCSI controller. + +ROM files needed : +Longshine LCS-6821N - BIOS version 1.04.bin + + +[SCSI] Rancho RT1000B +8-bit SCSI controller. + +ROM files needed : +Rancho_RT1000_RTBios_version_8.10R.bin + + +[SCSI] Trantor T130B +8-bit SCSI controller. + +ROM files needed : +trantor_t130b_bios_v2.14.bin + + +[SCSI] Adaptec AHA-1542C +16-bit SCSI controller. + +ROM files needed : +adaptec_aha1542c_bios_534201-00.bin + + +[SCSI] BusLogic BT-545S +16-bit SCSI controller. + +ROM files needed : +BusLogic_BT-545S_U15_27128_5002026-4.50.bin + Other stuff emulated : @@ -685,100 +970,81 @@ ATAPI CD-ROM Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've tried. -XTIDE : -The XTIDE board is emulated for machines that don't natively support IDE hard discs. - -You will need to download the XTIDE BIOS seperately. Of the various versions, ide_at.bin and ide_xt.bin -should be placed in the ROMS directory. ide_xt is used on all XT models, and ide_at is used on the IBM AT -and Commodore PC30-III machines. - -The BIOS is available at : - -http://code.google.com/p/xtideuniversalbios/ - -v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues. - -For the PS/1, you will need v1.1.5. The PS/1 is a bit fussy with XTIDE, and I've found that it works best -when the XTIDE configuration has 'Full Operating Mode' disabled. This version must be called -ide_at_1_1_5.bin and should also be placed in the ROMS directory. - - -Notes : - -- The time on the PC1512 clock is wrong. The date is correct, though since the PC1512's bios isn't - Y2k compliant, it thinks it's 1988. - -- The envelope system on the Gameblaster isn't emulated. The noise may not be right either. - -- Some of the more unusual VGA features are not emulated. I haven't found anything that uses them yet. - -- On some versions of Windows the AWE32 is not set up correctly, claiming a resource conflict. To correct - this open the relevant item in Device Manager, choose 'Set Configuration Manually' and accept the - options presented. Software tested: -MS-DOS 1.25 -MS-DOS 2.11 -MS-DOS 3.31 -Compaq DOS 3.31 +PC-DOS 1.0 +PC-DOS 2.10 +MS-DOS 3.30 MS-DOS 5.0 +MS-DOS 6.0 MS-DOS 6.22 DR-DOS 6.0 Windows 1.03 Windows 2.03 +Windows/286 2.11 Windows/386 2.11 Windows 3.0 Windows 3.1 Windows for Workgroups 3.11 Windows 95 -Windows 95 OSR 2 +Windows 95 OSR2 Windows 98 Windows 98 SE Windows ME +Windows NT 3.1 Windows NT 3.51 Windows NT 4 Windows 2000 Windows XP +OS/2 v1.0 OS/2 v1.1 OS/2 v1.2 OS/2 v1.3 -OS/2 v2.1 +OS/2 v2.0 OS/2 Warp 3 OS/2 Warp 4 -GEM 3.11 +Red Hat Linux 7.1 (Seawolf) +Ubuntu 10.04 -Corel Linux 1.2 -Ubuntu 10.04 (very slow, does not support serial mouse) +BeOS 5 Personal +BeOS 5 Professional -BeOS 5.0 Professional +DESQview/X -Adobe Photoshop 3.0.4 -CorelDRAW! 2.5 (OS/2) -CorelDRAW! 5.0 -FastTracker v2.08 -Lotus 1-2-3 2.1 (OS/2) -Microsoft Excel 3.0 (OS/2) -Microsoft Word 1.1 (OS/2) -Microsoft Word for Windows 6.1 -Microsoft Works for Windows 3.0 +GEM Desktop 3.11 + +Borland C++ v3.1 +Fasttracker v2.08 +Internet Explorer 5.0 +Microsoft Office 95 Microsoft Visual Basic 3.0 -Microsoft Visual C++ 1.0 -Microsoft Visual C++ 6.0 -StarOffice 3.1 (OS/2) +Microsoft Word for OS/2 1.1 +Microsoft Word for Windows 1.1 +Microsoft Works for Windows 3.0 +Micrografx Windows Draw 1.04 +PC Paintbrush for Windows v1.05 +Ventura Publisher v3.0 Age of Empires +Aladdin Alien vs Predator (3DFX) +All New World of Lemmings +Alone in the Dark +American McGee's Alice (3DFX) +Arkanoid +Beasts and Bumpkins Blake Stone -Breakneck (3DFX) +BreakNeck (3DFX) Caesar III +Cannon Fodder 2 Civilization Civilization II Colin McRae Rally (3DFX) @@ -787,108 +1053,143 @@ Command & Conquer : Red Alert Command & Conquer : Red Alert 2 Commander Keen : Goodbye Galaxy Commander Keen : Invasion of the Vorticons +Corridor 7 Croc (3DFX) Curse of Monkey Island Dawn Patrol -Deus Ex (3DFX, slow) +Descent Freespace (3DFX) +Deus Ex (3DFX) Discworld II Doom Doom II Duke Nukem 3D Dune Dune II +Ecstatica Epic Pinball +Expendable (3DFX) +Final Fantasy VII (3DFX) +Formula 1 '97 (3DFX) +Freespace 2 (3DFX) +G-Police (3DFX) +Grim Fandango (3DFX) Grand Theft Auto (3DFX) -GTA 2 (3DFX) +GTA2 (3DFX) Half-Life (3DFX) -Heretic +Heartlight +Hitchhiker's Guide to the Galaxy +Hocus Pocus House of the Dead 2 (3DFX) -Icon Incoming (3DFX) -Indiana Jones and the Last Crusade -Jetpack -King's Quest (PCjr, Tandy) -King's Quest II (Tandy) -Klotz -Lemmings -Lemmings 2 -Little Big Adventure 2 -Lotus III -Maniac Mansion +International Rally Championship (3DFX) +Interstate 76 +Jazz Jackrabbit +Jazz Jackrabbit 2 +Jedi Knight (3DFX) +Jill of the Jungle +LBA 2 +Lode Runner : The Legend Returns +Kings Quest Microsoft Arcade +MiG-29 Fulcrum (3DFX) Monkey Island 2 +Monster Bash +Mortal Kombat Mystic Towers Need for Speed II SE (3DFX) Need for Speed III (3DFX) Network Q RAC Rally +No One Lives Forever (3DFX) Oddworld : Abe's Oddysee -Overlord -Populous : The Beginning (3DFX) +Pinball Fantasies +Police Quest +Power Drive +Prince of Persia Pro Pinball : Big Race USA -Pro Pinball : The Web +Pro Pinball : Timeshock! Psycho Pinball -Resident Evil 2 (3DFX) -Rollercoaster Tycoon Quake (3DFX) Quake II (3DFX) Quake III Arena (3DFX) -Scorched Earth +Railroad Tycoon II +Rayman +Rebel Moon Rising +Resident Evil 2 (3DFX) +Return Fire II (3DFX) +Return to Castle Wolfenstein (3DFX) +Rise of the Triad +Rollercoaster Tycoon +Rollercoaster Tycoon 2 +Sam & Max Hit the Road Screamer Screamer Rally (not 3DFX) Secret of Monkey Island -SimCity (DOS, OS/2) -SimCity 2000 (DOs, Windows, OS/2) +Sensible World of Soccer +Sid Meier's Alpha Centauri +SimCity 2000 SimCity 3000 -Spear of Destiny -Star Goose +SiN (3DFX) +Sonic & Knuckles Collection +Star Wars Episode 1 Racer (3DFX) Stargunner -Stunt Island System Shock -System Shock 2 (3DFX) -Terminal Velocity +System Shock 2 (3DFX - SLOW) +The Chaos Engine The Humans +The Lion King Theme Hospital -Tomb Raider (3DFX) +Tie Fighter +TOCA 2 (3DFX) +Tomb Raider (3DFX, ViRGE) +Tomb Raider II (3DFX) Tomb Raider III (3DFX) Tony Hawk's Pro Skater 2 (3DFX) Total Annihilation Transport Tycoon +Trespasser (3DFX) Turok (3DFX) Turok 2 (3DFX) +Turrican II Tyrian -UFO : Enemy Unknown Unreal (3DFX) Unreal Tournament (3DFX) Wacky Wheels Wing Commander +Wizkid Wolfenstein 3D World Cup 98 (3DFX) Worms -Worms 2 +Worms World Party X-Com : Apocalypse X-Com : Terror From The Deep -X-Wing +Xenon +Xenon 2 +Zak McKracken Zone 66 +Cascada - Cronologia Complex - Cyboman 2 EMF - Verses Future Crew - Second Reality Gazebo - Cyboman! +Hornet - Introjr +KFMF - Dance, Move, Shake KFMF - Trip (3DFX) Logic Design - Fashion -Orange - X14 +Orange - x14 Renaissance - Amnesia -Skull - Putrefaction -Tran - Ambience (flickery with a host display at 60 Hz) +Skull - Putre Faction +Tran - Ambience +Tran - Luminati Tran - Timeless Triton - Crystal Dream -Triton - Crystal Dream II (visual artifacts in titles) +Triton - Crystal Dream II +Ultraforce - Coldcut Ultraforce - Vectdemo -Witan - Witan House BeebInC v0.99f Fellow v0.33 -Kgen98 v0.4b -PacifiST v0.48 -SNES9x v0.96 -vMac v0.1.9.1 +KGen98 v0.4b +PaCifiST v0.45 +ZSNES v0.800 +SNES9x v0.96 \ No newline at end of file From 1e0b7d3632b71f5f0dc0a6fb89c81fce44983cb5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 11 Dec 2017 20:34:09 +0000 Subject: [PATCH 0257/1050] Update version number for v13 release. --- src/pc.c | 2 +- src/wx-sdl2-display-win.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pc.c b/src/pc.c index 21ad726..b7e3547 100644 --- a/src/pc.c +++ b/src/pc.c @@ -560,7 +560,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v12 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem v13 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 29cccb3..e3c209d 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -583,7 +583,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v12", /* Title Text */ + "PCem v13", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From f0a12dcac26540094b102fdb2383f4b130b6a800 Mon Sep 17 00:00:00 2001 From: Salvador Pardi?as Date: Tue, 12 Dec 2017 14:51:59 -0300 Subject: [PATCH 0258/1050] Fixed for compilation with gcc 7.2.1 by including to ip_input.c --- src/slirp/ip_input.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slirp/ip_input.c b/src/slirp/ip_input.c index 7600f24..f6fc4a3 100644 --- a/src/slirp/ip_input.c +++ b/src/slirp/ip_input.c @@ -40,6 +40,7 @@ #include "slirp.h" #include "ip_icmp.h" +#include int ip_defttl; struct ipstat ipstat; From ac5c9a923d4a2ffdb9663bb0be193743964d60b7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 14 Dec 2017 18:24:40 +0000 Subject: [PATCH 0259/1050] Fix test for extra divide on SN76489 and clones. Fixes music in King's Quest III. --- src/sound_sn76489.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sound_sn76489.c b/src/sound_sn76489.c index 6acb24f..6db3d10 100644 --- a/src/sound_sn76489.c +++ b/src/sound_sn76489.c @@ -92,7 +92,7 @@ void sn76489_write(uint16_t addr, uint8_t data, void *p) case 0: sn76489->freqlo[3] = data & 0xf; sn76489->latch[3] = (sn76489->freqlo[3] | (sn76489->freqhi[3] << 4)) << 6; - if (sn76489->extra_divide) + if (!sn76489->extra_divide) sn76489->latch[3] &= 0x3ff; if (!sn76489->latch[3]) sn76489->latch[3] = (sn76489->extra_divide ? 2048 : 1024) << 6; @@ -105,7 +105,7 @@ void sn76489_write(uint16_t addr, uint8_t data, void *p) case 0x20: sn76489->freqlo[2] = data & 0xf; sn76489->latch[2] = (sn76489->freqlo[2] | (sn76489->freqhi[2] << 4)) << 6; - if (sn76489->extra_divide) + if (!sn76489->extra_divide) sn76489->latch[2] &= 0x3ff; if (!sn76489->latch[2]) sn76489->latch[2] = (sn76489->extra_divide ? 2048 : 1024) << 6; @@ -118,7 +118,7 @@ void sn76489_write(uint16_t addr, uint8_t data, void *p) case 0x40: sn76489->freqlo[1] = data & 0xf; sn76489->latch[1] = (sn76489->freqlo[1] | (sn76489->freqhi[1] << 4)) << 6; - if (sn76489->extra_divide) + if (!sn76489->extra_divide) sn76489->latch[1] &= 0x3ff; if (!sn76489->latch[1]) sn76489->latch[1] = (sn76489->extra_divide ? 2048 : 1024) << 6; @@ -134,7 +134,7 @@ void sn76489_write(uint16_t addr, uint8_t data, void *p) sn76489->noise = data & 0xf; if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; else sn76489->latch[0] = 0x400 << (data & 3); - if (sn76489->extra_divide) + if (!sn76489->extra_divide) sn76489->latch[0] &= 0x3ff; if (!sn76489->latch[0]) sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; @@ -161,7 +161,7 @@ void sn76489_write(uint16_t addr, uint8_t data, void *p) { sn76489->freqhi[sn76489->lasttone] = data & 0x7F; freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4); - if (sn76489->extra_divide) + if (!sn76489->extra_divide) freq &= 0x3ff; if (!freq) freq = sn76489->extra_divide ? 2048 : 1024; From c0048bc24f7f7aa21ccdf9086cede5d402744a18 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 14 Dec 2017 18:49:09 +0000 Subject: [PATCH 0260/1050] Fixed handling of configurations with full stops in the name. --- src/pc.c | 14 ++++++-------- src/wx-config_sel.c | 18 +----------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/pc.c b/src/pc.c index b7e3547..472677a 100644 --- a/src/pc.c +++ b/src/pc.c @@ -249,22 +249,20 @@ void initpc(int argc, char *argv[]) } else if (!strcasecmp(argv[c], "--config")) { - int d; + char *ext; if ((c+1) == argc) break; strncpy(config_file_default, argv[c+1], 256); strcpy(config_name, get_filename(config_file_default)); - for (d = 0; d < strlen(config_name); d++) + ext = get_extension(config_name); + if (ext && ext[0]) { - if (config_name[d] == '.') - { - config_name[d] = 0; - break; - } + ext--; + *ext = 0; } - + config_override = 1; c++; } diff --git a/src/wx-config_sel.c b/src/wx-config_sel.c index e4253a3..b21f307 100644 --- a/src/wx-config_sel.c +++ b/src/wx-config_sel.c @@ -32,7 +32,7 @@ static void select_config(void* hdlg, char* name) static void config_list_update(void* hdlg) { char s[512]; - int num, c, p; + int num, p; void* h; strcpy(s, configs_path); @@ -47,22 +47,6 @@ static void config_list_update(void* hdlg) num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); - for (c = 0; c < num; c++) - { - char *ext; - - wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)s); - ext = get_extension(s); - if (ext && ext[0]) - { - ext--; - *ext = 0; - } - - wx_sendmessage(h, WX_LB_DELETESTRING, c, 0); - wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)s); - } - if (num > 0) { if (p >= num) From fd1fc444ddd75d825d0af850a348f349e92404d3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 14 Dec 2017 22:09:53 +0000 Subject: [PATCH 0261/1050] Fixed SN76489 white noise that was broken in rev 975. --- src/sound_sn76489.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sound_sn76489.c b/src/sound_sn76489.c index 6db3d10..3dbbd2f 100644 --- a/src/sound_sn76489.c +++ b/src/sound_sn76489.c @@ -134,8 +134,6 @@ void sn76489_write(uint16_t addr, uint8_t data, void *p) sn76489->noise = data & 0xf; if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; else sn76489->latch[0] = 0x400 << (data & 3); - if (!sn76489->extra_divide) - sn76489->latch[0] &= 0x3ff; if (!sn76489->latch[0]) sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; break; From a602cb058013fa9904b2cc715b6f3a23f54cd9b6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Dec 2017 17:26:42 +0000 Subject: [PATCH 0262/1050] Tweaked recompiler block lookup. Fixes massive slowdown seen on some Windows 9x installations at startup & possibly some other slowdowns. --- src/codegen.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/codegen.h b/src/codegen.h index 3a8a955..c5ad1ed 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -84,8 +84,12 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) while (block) { if (a == block->cmp) - break; - else if (a < block->cmp) + { + if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) + break; + } + if (a < block->cmp) block = block->left; else block = block->right; From d75a973bf621ad78bf3b7648b42efa5d3c18682d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Dec 2017 17:28:07 +0000 Subject: [PATCH 0263/1050] Updated ancient Linux documentation. --- Readme-LINUX.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Readme-LINUX.txt b/Readme-LINUX.txt index c3aff39..ff25866 100644 --- a/Readme-LINUX.txt +++ b/Readme-LINUX.txt @@ -1,31 +1,31 @@ -PCem v8.1 Linux supplement +PCem v13 Linux supplement You will need the following libraries : -Allegro 4.x +SDL2 +wxWidgets 3.x OpenAL -ALut and their dependencies. Open a terminal window, navigate to the PCem directory then enter -./configure +./configure --enable-release make then ./pcem to run. +The Linux version stores BIOS ROM images, configuration files, and other data in ~/.pcem -The Linux port is currently entirely unpolished, and mainly exists as a starting point for -anyone who wants to make a better port. +configure options are : + --enable-release-build : Generate release build. Recommended for regular use. + --enable-debug : Compile with debugging enabled. + --enable-networking : Build with networking support. + --enable-alsa : Build with support for MIDI output through ALSA. Requires libasound. -The menu is not available all the time. Press CTRL-ALT-PGDN to open it. -The mouse does not work very well, at least on my machine. This is most likely an Allegro issue. - -Fullscreen mode is not present. - -Video acceleration is not used at all, so performance is inferior to the Windows version. +The menu is a pop-up menu in the Linux port. Right-click on the main window when mouse is not +captured. CD-ROM support currently only accesses /dev/cdrom. It has not been heavily tested. From d28cdb49e7e2b5cc75924188bad1cfeea64f99e3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Dec 2017 17:56:50 +0000 Subject: [PATCH 0264/1050] Sound output gain now controls listener gain instead of source gain. Fixes gain control when using OpenAL Soft. --- src/soundopenal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soundopenal.c b/src/soundopenal.c index b07695c..a77a492 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -183,7 +183,7 @@ void givealbuffer(int32_t *buf) ALuint buffer; double gain = pow(10.0, (double)sound_gain / 20.0); - alSourcef(source[0], AL_GAIN, gain); + alListenerf(AL_GAIN, gain); alSourceUnqueueBuffers(source[0], 1, &buffer); // printf("U "); @@ -250,7 +250,7 @@ void givealbuffer_cd(int16_t *buf) ALuint buffer; double gain = pow(10.0, (double)sound_gain / 20.0); - alSourcef(source[1], AL_GAIN, gain); + alListenerf(AL_GAIN, gain); alSourceUnqueueBuffers(source[1], 1, &buffer); // printf("U "); From 5adac80648cbf86cdeb6cf1eb9d39ff525553740 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Dec 2017 21:13:17 +0000 Subject: [PATCH 0265/1050] Fixed a couple of uninitialised variables. --- src/x86_ops_misc.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index f6eb918..c8d31f5 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -46,7 +46,7 @@ static int opSETALC(uint32_t fetchdat) static int opF6_a16(uint32_t fetchdat) { - int tempws, tempws2; + int tempws, tempws2 = 0; uint16_t tempw, src16; uint8_t src, dst; int8_t temps; @@ -144,7 +144,7 @@ static int opF6_a16(uint32_t fetchdat) } static int opF6_a32(uint32_t fetchdat) { - int tempws, tempws2; + int tempws, tempws2 = 0; uint16_t tempw, src16; uint8_t src, dst; int8_t temps; @@ -246,7 +246,7 @@ static int opF6_a32(uint32_t fetchdat) static int opF7_w_a16(uint32_t fetchdat) { uint32_t templ, templ2; - int tempws, tempws2; + int tempws, tempws2 = 0; int16_t temps16; uint16_t src, dst; @@ -340,7 +340,7 @@ static int opF7_w_a16(uint32_t fetchdat) static int opF7_w_a32(uint32_t fetchdat) { uint32_t templ, templ2; - int tempws, tempws2; + int tempws, tempws2 = 1; int16_t temps16; uint16_t src, dst; From 496b3884ab066c28e8de25d2ef3bc370fdda384a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Dec 2017 21:14:05 +0000 Subject: [PATCH 0266/1050] Fixed out-of-bounds array accesses in Toshiba 3100e video code - fixes display when using profile guided optimisation. --- src/vid_t3100e.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vid_t3100e.c b/src/vid_t3100e.c index 4172f8f..c1195b6 100644 --- a/src/vid_t3100e.c +++ b/src/vid_t3100e.c @@ -599,15 +599,11 @@ void t3100e_recalcattrs(t3100e_t *t3100e) { blinkcols[n][0] = normcols[n][0] = amber; blinkcols[n][1] = normcols[n][1] = black; - blinkcols[n+128][0] = normcols[n+128][0] = amber; - blinkcols[n+128][1] = normcols[n+128][1] = black; } else /* Normal */ { blinkcols[n][0] = normcols[n][0] = black; blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n+128][0] = normcols[n+128][0] = black; - blinkcols[n+128][1] = normcols[n+128][1] = amber; } if (t3100e->attrmap & 8) boldcols[n] = 1; /* Bold */ } From 40ddf31d30b9ae127c9f71b0153fa426954d8abf Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 17 Dec 2017 09:03:19 +0000 Subject: [PATCH 0267/1050] Update version numbers and documentation for v13.1 release. --- Readme-LINUX.txt | 2 +- readme.txt | 13 +++++++++++-- src/pc.c | 2 +- src/pc.xrc | 2 +- src/wx-resources.cpp | 28 ++++++++++++++-------------- src/wx-sdl2-display-win.c | 2 +- 6 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Readme-LINUX.txt b/Readme-LINUX.txt index ff25866..b8c418d 100644 --- a/Readme-LINUX.txt +++ b/Readme-LINUX.txt @@ -1,4 +1,4 @@ -PCem v13 Linux supplement +PCem v13.1 Linux supplement You will need the following libraries : diff --git a/readme.txt b/readme.txt index 4761654..31441bd 100644 --- a/readme.txt +++ b/readme.txt @@ -1,7 +1,16 @@ -PCem v13 +PCem v13.1 PCem is licensed under the GPL, see COPYING for more details. +Changes since v13: + +- Minor recompiler tweak, fixed slowdown in some situations (mainly seen on Windows 9x just after booting) +- Fixed issues with PCJr/Tandy sound on some Sierra games +- Fixed plasma display on Toshiba 3100e +- Fixed handling of configurations with full stops in the name +- Fixed sound output gain when using OpenAL Soft +- Switched to using OpenAL Soft by default + Changes since v12: - New machines added - Atari PC3, Epson PC AX, Epson PC AX2e, GW-286CT GEAR, IBM PS/2 Model 30-286, @@ -603,7 +612,7 @@ ROM files needed: Olivetti GO481 (Paradise PVGA1A) -512kb VRAM, supports up to 8-bit colour. +256kb VRAM, supports up to 8-bit colour. ROM files needed : oli_go481_lo.bin diff --git a/src/pc.c b/src/pc.c index 472677a..1109060 100644 --- a/src/pc.c +++ b/src/pc.c @@ -558,7 +558,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v13 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem v13.1 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/pc.xrc b/src/pc.xrc index 6df87ea..fcb7877 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -2991,7 +2991,7 @@ wxALL 5 - + -1 diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index cfbb7da..829c070 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 133760; +static size_t xml_res_size_26 = 133762; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -7533,19 +7533,19 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, 84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,80,67,101,109,32,118,49,50,92,110,104,116,116,112,115,58,47, -47,112,99,101,109,45,101,109,117,108,97,116,111,114,46,99,111,46,117,107, -47,92,110,92,110,84,104,105,115,32,112,114,111,103,114,97,109,32,105,115, -32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116,104,101, -32,71,78,85,32,71,101,110,101,114,97,108,32,80,117,98,108,105,99,32,76, -105,99,101,110,115,101,32,118,101,114,115,105,111,110,32,50,46,92,110,83, -101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100, -101,116,97,105,108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105, -99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99, -111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117,110,100,105, -99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46, -102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104,101,114,32, -105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119, +101,108,62,80,67,101,109,32,118,49,51,46,49,92,110,104,116,116,112,115, +58,47,47,112,99,101,109,45,101,109,117,108,97,116,111,114,46,99,111,46, +117,107,47,92,110,92,110,84,104,105,115,32,112,114,111,103,114,97,109,32, +105,115,32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116, +104,101,32,71,78,85,32,71,101,110,101,114,97,108,32,80,117,98,108,105,99, +32,76,105,99,101,110,115,101,32,118,101,114,115,105,111,110,32,50,46,92, +110,83,101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109,111,114,101, +32,100,101,116,97,105,108,115,46,92,110,92,110,84,111,111,108,98,97,114, +45,105,99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117,110,100, +105,99,111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117,110,100, +105,99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119,119,119, +46,102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104,101,114, +32,105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119, 32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,116,99,111,119,46, 99,111,109,47,102,114,101,101,45,105,99,111,110,115,47,41,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index e3c209d..a4fdb28 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -583,7 +583,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v13", /* Title Text */ + "PCem v13.1", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From 8a5b552a9a43c2c65de99cdc609ed8932ff818df Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:50:48 +0000 Subject: [PATCH 0268/1050] Correct CS:IP initialisation on 286+ reset. Patch from Greatpsycho. --- src/808x.c | 29 ++++++++++++++++++++++++----- src/x86seg.c | 12 ++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/808x.c b/src/808x.c index 971367e..c761199 100644 --- a/src/808x.c +++ b/src/808x.c @@ -628,7 +628,6 @@ void resetx86() stack32=0; // i86_Reset(); // cs=0xFFFF0; - cpu_state.pc=0; msw=0; if (is486) cr0 = 1 << 30; @@ -639,8 +638,18 @@ void resetx86() cr4 = 0; eflags=0; cgate32=0; - loadcs(0xFFFF); - rammask = AT ? 0xFFFFFFFF : 0xfffff; + if (AT) + { + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + } + else + { + loadcs(0xFFFF); + cpu_state.pc = 0; + rammask = 0xfffff; + } idt.base = 0; flags=2; makeznptable(); @@ -667,13 +676,23 @@ void softresetx86() cpu_cur_status = 0; // i86_Reset(); // cs=0xFFFF0; - cpu_state.pc=0; msw=0; cr0=0; cr4 = 0; eflags=0; cgate32=0; - loadcs(0xFFFF); + if (AT) + { + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + } + else + { + loadcs(0xFFFF); + cpu_state.pc = 0; + rammask = 0xfffff; + } //rammask=0xFFFFFFFF; flags=2; idt.base = 0; diff --git a/src/x86seg.c b/src/x86seg.c index 87cf2c7..23d6294 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -68,6 +68,18 @@ static void seg_reset(x86seg *s) s->limit = 0xFFFF; s->limit_low = 0; s->limit_high = 0xffff; + if (s == &_cs) + { + // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. + //s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; + s->base = AT ? 0xF0000 : 0xFFFF0; + s->seg = AT ? 0xF000 : 0xFFFF; + } + else + { + s->base = 0; + s->seg = 0; + } } void x86seg_reset() From b60eff610d0bc64be40531876b71bc6217fb4bba Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:51:06 +0000 Subject: [PATCH 0269/1050] Fix IDT limit on reset. Patch from Greatpsycho. --- src/808x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/808x.c b/src/808x.c index c761199..ca2fd96 100644 --- a/src/808x.c +++ b/src/808x.c @@ -651,6 +651,7 @@ void resetx86() rammask = 0xfffff; } idt.base = 0; + idt.limit = is386 ? 0x03FF : 0xFFFF; flags=2; makeznptable(); resetreadlookup(); @@ -696,6 +697,7 @@ void softresetx86() //rammask=0xFFFFFFFF; flags=2; idt.base = 0; + idt.limit = is386 ? 0x03FF : 0xFFFF; x86seg_reset(); x86_was_reset = 1; } From e070341f803f97657bb6eae3cd2770e37bc88d91 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:51:57 +0000 Subject: [PATCH 0270/1050] Correct high ROM mapping on 286/386SX systems. Patch from Greatpsycho. --- src/mem.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/mem.c b/src/mem.c index 65eeaa3..1925fa0 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2062,14 +2062,14 @@ void mem_add_bios() mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL, 0); mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_high_mapping[0], 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, 0, 0); - mem_mapping_add(&bios_high_mapping[1], 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[2], 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[3], 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[4], 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[5], 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[6], 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[7], 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, 0, 0); + mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), 0, 0); } int mem_a20_key = 0, mem_a20_alt = 0; @@ -2104,7 +2104,7 @@ void mem_init() for (c = 0; c < (mem_size / 64); c++) { isram[c] = 1; - if (c >= 0xa && c <= 0xf) + if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff)) isram[c] = 0; } @@ -2128,8 +2128,16 @@ void mem_init() 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) { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + if (cpu_16bitbus && mem_size > 16256) + { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + else + { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } } 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); @@ -2199,7 +2207,7 @@ void mem_resize() for (c = 0; c < (mem_size / 64); c++) { isram[c] = 1; - if (c >= 0xa && c <= 0xf) + if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff)) isram[c] = 0; } @@ -2221,8 +2229,16 @@ void mem_resize() 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) { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + if (cpu_16bitbus && mem_size > 16256) + { + mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } + else + { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + } } 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); From 6798ebf0a6d5c2a08684c4d9c9fcbd1cee4d4851 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:52:45 +0000 Subject: [PATCH 0271/1050] Correct address mask on 286/386SX systems. Patch from Greatpsycho. --- src/mem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mem.c b/src/mem.c index 1925fa0..476b83b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2272,12 +2272,12 @@ void mem_a20_recalc() // pclog("A20 recalc %i %i\n", state, mem_a20_state); if (state && !mem_a20_state) { - rammask = 0xffffffff; + rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; flushmmucache(); } else if (!state && mem_a20_state) { - rammask = 0xffefffff; + rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; flushmmucache(); } // pclog("rammask now %08X\n", rammask); From f336dd9589342cfb2a0a403d2ea28480961b2d0c Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:54:19 +0000 Subject: [PATCH 0272/1050] Implemented IDT limit checking on real mode interrupts. Patch from Greatpsycho. --- src/386_dynarec.c | 90 ++++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 1fa2624..bd1a928 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -198,27 +198,43 @@ void x86_int(int num) } else { - if (stack32) + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) { - writememw(ss,ESP-2,flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; + if (idt.limit < 35) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + pclog("Triple fault in real mode - reset\n"); + } + else + x86_int(8); } else { - writememw(ss,((SP-2)&0xFFFF),flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - addr = (num << 2) + idt.base; + if (stack32) + { + writememw(ss,ESP-2,flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } - flags&=~I_FLAG; - flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); + flags&=~I_FLAG; + flags&=~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } } cycles-=70; CPU_BLOCK_END(); @@ -237,28 +253,36 @@ void x86_int_sw(int num) } else { - if (stack32) + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) { - writememw(ss,ESP-2,flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; + x86_int(13); } else { - writememw(ss,((SP-2)&0xFFFF),flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - addr = (num << 2) + idt.base; + if (stack32) + { + writememw(ss,ESP-2,flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } - flags&=~I_FLAG; - flags&=~T_FLAG; - oxpc=cpu_state.pc; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - cycles -= timing_int_rm; + flags&=~I_FLAG; + flags&=~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + cycles -= timing_int_rm; + } } trap = 0; CPU_BLOCK_END(); From 5416c948a3917779ff2956c3a0631ad64b0c371c Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:54:47 +0000 Subject: [PATCH 0273/1050] Don't push exception error code on triple fault reset. Patch from Greatpsycho. --- src/x86seg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86seg.c b/src/x86seg.c index 23d6294..9840c0b 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -136,7 +136,7 @@ void x86_doabrt(int x86_abrt) return; } - if (cpu_state.abrt) return; + if (cpu_state.abrt || x86_was_reset) return; if (intgatesize == 16) { From 4d29b1c71f2bc4c8a6506cb5690c373cc29be817 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 20:57:04 +0000 Subject: [PATCH 0274/1050] Move CPU type set to before memory initialisation. Patch from Greatpsycho. --- src/pc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pc.c b/src/pc.c index 1109060..b922965 100644 --- a/src/pc.c +++ b/src/pc.c @@ -207,7 +207,6 @@ void onesec() void pc_reset() { - cpu_set(); resetx86(); //timer_reset(); dma_reset(); @@ -358,6 +357,7 @@ void initpc(int argc, char *argv[]) void resetpc() { + cpu_set(); pc_reset(); // cpuspeed2=(AT)?2:1; // atfullspeed=0; @@ -383,6 +383,7 @@ void resetpchard() timer_reset(); sound_reset(); + cpu_set(); mem_resize(); fdc_init(); disc_reset(); From 2957dae2d5f73434acfa69cd4e99172dca9abc1c Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Jan 2018 21:10:46 +0000 Subject: [PATCH 0275/1050] Fixes to x86_was_reset handling. Based on patch from Greatpsycho. --- src/386.c | 3 +++ src/386_dynarec.c | 1 + 2 files changed, 4 insertions(+) diff --git a/src/386.c b/src/386.c index 10d6a79..cb78c4e 100644 --- a/src/386.c +++ b/src/386.c @@ -224,6 +224,7 @@ void exec386(int cycs) { int cycle_period = (timer_count >> TIMER_SHIFT) + 1; + x86_was_reset = 0; cycdiff=0; oldcyc=cycles; timer_start_period(cycles << TIMER_SHIFT); @@ -260,6 +261,8 @@ dontprint=0; } cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; } if (!use32) cpu_state.pc &= 0xffff; diff --git a/src/386_dynarec.c b/src/386_dynarec.c index bd1a928..2ccc1dd 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -543,6 +543,7 @@ void exec386_dynarec(int cycs) if (!CACHE_ON()) /*Interpret block*/ { cpu_block_end = 0; + x86_was_reset = 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) { From f1ee3cddbac238ab514d0f49f4eb7dadc47ef60b Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 9 Jan 2018 18:39:22 +0000 Subject: [PATCH 0276/1050] Fixed Cyrix I/O registers broken by commit 994. --- src/model.c | 1 - src/pc.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index e76a34c..e53ee9e 100644 --- a/src/model.c +++ b/src/model.c @@ -542,7 +542,6 @@ void model_init() pclog("Initting as %s\n", model_getname()); AMSTRAD = AT = PCI = TANDY = 0; ide_set_bus_master(NULL, NULL, NULL); - io_init(); models[model].init(); if (models[model].device) diff --git a/src/pc.c b/src/pc.c index b922965..f28da95 100644 --- a/src/pc.c +++ b/src/pc.c @@ -22,6 +22,7 @@ #include "gameport.h" #include "sound_gus.h" #include "ide.h" +#include "io.h" #include "keyboard.h" #include "keyboard_at.h" #include "lpt.h" @@ -289,6 +290,7 @@ void initpc(int argc, char *argv[]) timer_reset(); sound_reset(); + io_init(); fdc_init(); disc_init(); fdi_init(); @@ -383,6 +385,7 @@ void resetpchard() timer_reset(); sound_reset(); + io_init(); cpu_set(); mem_resize(); fdc_init(); From 3c431794f0bf62132367eb0b8ebb5bbfef931418 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 9 Jan 2018 20:07:27 +0000 Subject: [PATCH 0277/1050] Cleared null count bit in PIT status byte. Fixes Wing Commander III, Wings of Fury and probably other Origin games. --- src/pit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pit.c b/src/pit.c index fdcb6c9..e479f31 100644 --- a/src/pit.c +++ b/src/pit.c @@ -353,17 +353,17 @@ void pit_write(uint16_t addr, uint8_t val, void *p) { if (val & 2) { - pit->read_status[0] = (pit->ctrls[0] & 0x3f) | 0x40 | (pit->out[0] ? 0x80 : 0); + pit->read_status[0] = (pit->ctrls[0] & 0x3f) | (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->read_status[1] = (pit->ctrls[1] & 0x3f) | (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->read_status[2] = (pit->ctrls[2] & 0x3f) | (pit->out[2] ? 0x80 : 0); pit->do_read_status[2] = 1; } } From be7bb04c6bb22597ec557fb961893e4060abeb34 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 10 Jan 2018 18:48:11 +0000 Subject: [PATCH 0278/1050] Implemented Sound Blaster DSP busy cycling when playing DMA audio. Fixes stalls in Wing Commander : Privateer when sound enabled. --- src/sound_sb_dsp.c | 6 +++++- src/sound_sb_dsp.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 6aebef1..fb1532a 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -685,7 +685,11 @@ uint8_t sb_read(uint16_t a, void *priv) // pclog("SB read %02X\n",sbreaddat); return dsp->sbreaddat; case 0xC: /*Write data ready*/ - if (dsp->wb_full) + if (dsp->sb_8_enable || dsp->sb_type >= SB16 ) + dsp->busy_count = (dsp->busy_count + 1) & 15; + else + dsp->busy_count = 0; + if (dsp->wb_full || (dsp->busy_count & 8)) { dsp->wb_full = dsp->wb_time; return 0xff; diff --git a/src/sound_sb_dsp.h b/src/sound_sb_dsp.h index 3c100e5..68f260a 100644 --- a/src/sound_sb_dsp.h +++ b/src/sound_sb_dsp.h @@ -58,6 +58,8 @@ typedef struct sb_dsp_t int asp_data_len; int wb_time, wb_full; + + int busy_count; int record_pos_read; int record_pos_write; From c40a421700db06955e046df9729caf3b571614f8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 10 Jan 2018 20:44:31 +0000 Subject: [PATCH 0279/1050] Added Toshiba T1000 emulation. Patch from John Elliott. --- src/Makefile.am | 6 +- src/Makefile.linux32-wx-sdl2 | 8 +- src/Makefile.linux64-wx-sdl2 | 8 +- src/Makefile.mingw | 6 +- src/Makefile.mingw-network | 6 +- src/Makefile.mingw-wx-sdl2 | 6 +- src/Makefile.mingw-wx-sdl2-network | 6 +- src/Makefile.mingw64 | 6 +- src/Makefile.osx64-wx-sdl2 | 8 +- src/fdc.h | 1 + src/ibm.h | 3 +- src/keyboard_xt.c | 31 ++ src/mem.c | 10 + src/model.c | 3 + src/nvr.c | 10 + src/nvr.h | 4 + src/nvr_tc8521.c | 98 ++++ src/nvr_tc8521.h | 12 + src/rtc_tc8521.c | 221 +++++++++ src/rtc_tc8521.h | 33 ++ src/t1000.c | 579 ++++++++++++++++++++++++ src/t1000.h | 7 + src/vid_t1000.c | 695 +++++++++++++++++++++++++++++ src/vid_t1000.h | 4 + src/video.c | 7 +- 25 files changed, 1746 insertions(+), 32 deletions(-) create mode 100644 src/nvr_tc8521.c create mode 100644 src/nvr_tc8521.h create mode 100644 src/rtc_tc8521.c create mode 100644 src/rtc_tc8521.h create mode 100644 src/t1000.c create mode 100644 src/t1000.h create mode 100644 src/vid_t1000.c create mode 100644 src/vid_t1000.h diff --git a/src/Makefile.am b/src/Makefile.am index dae893a..098d4d5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,16 +19,16 @@ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ +opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ -t3100e.c \ +t1000.c t3100e.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ vid_icd2061.c vid_ics2595.c vid_incolor.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_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_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ +vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c \ x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ dosbox/nukedopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index e86d876..ff77aa6 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -9,16 +9,16 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t3100e.o tandy_eeprom.o tandy_rom.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ +vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 53905fd..f274909 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -9,16 +9,16 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t3100e.o tandy_eeprom.o tandy_rom.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ +vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 5ada033..0022aab 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,16 +8,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 8e8abac..57038f9 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -9,16 +9,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xtide.o pc.res diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 941f0dd..2928106 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -11,16 +11,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index e5b3515..794d72c 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -11,16 +11,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 0604e1a..be7f9fb 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -8,16 +8,16 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 761cc82..e88dd86 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -8,16 +8,16 @@ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t3100e.o tandy_eeprom.o tandy_rom.o \ +sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ +vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ diff --git a/src/fdc.h b/src/fdc.h index 618cf19..ec198b8 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -11,6 +11,7 @@ void fdc_set_dskchg_activelow(); void fdc_3f1_enable(int enable); void fdc_set_ps1(); int fdc_get_bitcell_period(); +uint8_t fdc_read(uint16_t addr, void *priv); /* A few functions to communicate between Super I/O chips and the FDC. */ void fdc_update_is_nsc(int is_nsc); diff --git a/src/ibm.h b/src/ibm.h index a314370..37e7101 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -378,7 +378,7 @@ char discfns[2][256]; int driveempty[2]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || 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 && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -445,6 +445,7 @@ enum ROM_EPSON_PCAX2E, ROM_EPSON_PCAX3, ROM_T3100E, + ROM_T1000, ROM_MAX }; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index b579e68..72cbf28 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -8,6 +8,7 @@ #include "sound_speaker.h" #include "tandy_eeprom.h" #include "timer.h" +#include "t1000.h" #include "keyboard.h" #include "keyboard_xt.h" @@ -56,6 +57,36 @@ void keyboard_xt_poll() void keyboard_xt_adddata(uint8_t val) { + /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ + if (romset == ROM_T1000) + { + if (pcem_key[0xb8] || pcem_key[0x9D]) /* 'Fn' pressed */ + { + t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ + switch (val) + { + case 0x45: /* Num Lock => toggle numpad */ + t1000_syskey(0x00, 0x00, 0x10); break; + case 0x47: /* Home => internal display */ + t1000_syskey(0x40, 0x00, 0x00); break; + case 0x49: /* PgDn => turbo on */ + t1000_syskey(0x80, 0x00, 0x00); break; + case 0x4D: /* Right => toggle LCD font */ + t1000_syskey(0x00, 0x00, 0x20); break; + case 0x4F: /* End => external display */ + t1000_syskey(0x00, 0x40, 0x00); break; + case 0x51: /* PgDn => turbo off */ + t1000_syskey(0x00, 0x80, 0x00); break; + case 0x54: /* SysRQ => toggle window */ + t1000_syskey(0x00, 0x00, 0x08); break; + } + } + else + { + t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */ + } + } + key_queue[key_queue_end] = val; pclog("keyboard_xt : %02X added to key queue at %i\n", val, key_queue_end); key_queue_end = (key_queue_end + 1) & 0xf; diff --git a/src/mem.c b/src/mem.c index 476b83b..adc4de8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -762,6 +762,16 @@ int loadbios() fread(rom,65536,1,f); fclose(f); return 1; + + case ROM_T1000: + loadfont("t1000/t1000font.rom", 2); + f=romfopen("t1000/t1000.rom","rb"); + if (!f) break; + fread(rom, 0x8000,1,f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index e53ee9e..6b9273d 100644 --- a/src/model.c +++ b/src/model.c @@ -56,6 +56,7 @@ #include "um8669f.h" #include "vid_pcjr.h" #include "vid_tandy.h" +#include "vid_t1000.h" #include "wd76c10.h" void xt_init(); @@ -90,6 +91,7 @@ void at_batman_init(); void at_endeavor_init(); void xt_laserxt_init(); void at_t3100e_init(); +void xt_t1000_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -108,6 +110,7 @@ MODEL models[] = {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 512,1280, 768, xt_t1000_init, &t1000_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index bdd9462..7f4476c 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "io.h" #include "nvr.h" +#include "nvr_tc8521.h" #include "pic.h" #include "timer.h" #include "rtc.h" @@ -9,6 +10,7 @@ #include "config.h" #include "model.h" #include "nmi.h" +#include "t1000.h" int oldromset; int nvrmask=63; @@ -286,6 +288,10 @@ void loadnvr() case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); nvrmask = 127; break; case ROM_T3100E: f = nvrfopen("t3100e.nvr", "rb"); break; + case ROM_T1000: tc8521_loadnvr(); + t1000_configsys_loadnvr(); + t1000_emsboard_loadnvr(); + return; default: return; } @@ -359,6 +365,10 @@ void savenvr() case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); break; case ROM_T3100E: f = nvrfopen("t3100e.nvr", "wb"); break; + case ROM_T1000: tc8521_savenvr(); + t1000_configsys_savenvr(); + t1000_emsboard_savenvr(); + return; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/nvr.h b/src/nvr.h index 1a60fdf..f92942b 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -10,3 +10,7 @@ void savenvr(); void nvr_recalc(); FILE *nvrfopen(char *fn, char *mode); + +extern uint8_t nvrram[128]; +extern int nvrmask; +extern int oldromset; diff --git a/src/nvr_tc8521.c b/src/nvr_tc8521.c new file mode 100644 index 0000000..6e20c41 --- /dev/null +++ b/src/nvr_tc8521.c @@ -0,0 +1,98 @@ +#include +#include "ibm.h" +#include "io.h" +#include "nvr.h" +#include "nvr_tc8521.h" +#include "rtc_tc8521.h" +#include "pic.h" +#include "timer.h" +#include "rtc.h" +#include "paths.h" +#include "config.h" +#include "nmi.h" + +static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; + +static void tc8521_onesec(void *p) +{ + nvr_onesec_cnt++; + if (nvr_onesec_cnt >= 100) + { + tc8521_tick(); + nvr_onesec_cnt = 0; + } + nvr_onesec_time += (int)(10000 * TIMER_USEC); +} + +void write_tc8521(uint16_t addr, uint8_t val, void *priv) +{ + uint8_t page = nvrram[0x0D] & 3; + + addr &= 0x0F; + if (addr < 0x0D) addr += 16 * page; + + if (addr >= 0x10 && nvrram[addr] != val) + nvr_dosave = 1; + + nvrram[addr] = val; +} + + +uint8_t read_tc8521(uint16_t addr, void *priv) +{ + uint8_t page = nvrram[0x0D] & 3; + + addr &= 0x0F; + if (addr < 0x0D) addr += 16 * page; + + return nvrram[addr]; +} + + +void tc8521_loadnvr() +{ + FILE *f; + + nvrmask=63; + oldromset=romset; + switch (romset) + { + case ROM_T1000: f = nvrfopen("t1000.nvr", "rb"); break; + default: return; + } + if (!f) + { + memset(nvrram,0xFF,64); + nvrram[0x0E] = 0; /* Test register */ + if (!enable_sync) + { + memset(nvrram, 0, 16); + } + return; + } + fread(nvrram,64,1,f); + if (enable_sync) + tc8521_internal_sync(nvrram); + else + tc8521_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */ + fclose(f); +} + + +void tc8521_savenvr() +{ + FILE *f; + switch (oldromset) + { + case ROM_T1000: f = nvrfopen("t1000.nvr", "wb"); break; + default: return; + } + fwrite(nvrram,64,1,f); + fclose(f); +} + +void nvr_tc8521_init() +{ + io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL); + timer_add(tc8521_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL); +} diff --git a/src/nvr_tc8521.h b/src/nvr_tc8521.h new file mode 100644 index 0000000..c8edce6 --- /dev/null +++ b/src/nvr_tc8521.h @@ -0,0 +1,12 @@ +void nvr_tc8521_init(); + +extern int enable_sync; + +extern int nvr_dosave; + +void tc8521_loadnvr(); +void tc8521_savenvr(); + +void tc8521_nvr_recalc(); + +FILE *nvrfopen(char *fn, char *mode); diff --git a/src/rtc_tc8521.c b/src/rtc_tc8521.c new file mode 100644 index 0000000..e5b8649 --- /dev/null +++ b/src/rtc_tc8521.c @@ -0,0 +1,221 @@ +/* Emulation of: + Toshiba TC8521 Real Time Clock */ + +#include +#include +#include +#include +#include +#include "nvr.h" +#include "rtc_tc8521.h" + +#define peek2(a) (nvrram[(a##1)] + 10 * nvrram[(a##10)]) + +struct +{ + int sec; + int min; + int hour; + int mday; + int mon; + int year; +} internal_clock; + +/* 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}; + +/* Called to determine whether the year is leap or not */ +static int rtc_is_leap(int org_year) +{ + if (org_year % 400 == 0) return 1; + if (org_year % 100 == 0) return 0; + if (org_year % 4 == 0) return 1; + return 0; +} + +/* Called to determine the days in the current month */ +static int rtc_get_days(int org_month, int org_year) +{ + if (org_month != 2) + return rtc_days_in_month[org_month]; + else + return rtc_is_leap(org_year) ? 29 : 28; +} + +/* Called when the internal clock gets updated */ +static void tc8521_recalc() +{ + if (internal_clock.sec == 60) + { + internal_clock.sec = 0; + internal_clock.min++; + } + if (internal_clock.min == 60) + { + internal_clock.min = 0; + internal_clock.hour++; + } + if (internal_clock.hour == 24) + { + internal_clock.hour = 0; + internal_clock.mday++; + } + if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1)) + { + internal_clock.mday = 1; + internal_clock.mon++; + } + if (internal_clock.mon == 13) + { + internal_clock.mon = 1; + internal_clock.year++; + } +} + +/* Called when ticking the second */ +void tc8521_tick() +{ + internal_clock.sec++; + tc8521_recalc(); +} + +/* Called when modifying the NVR registers */ +void tc8521_update(uint8_t *nvrram, int reg) +{ + int temp; + + switch(reg) + { + case TC8521_SECOND1: + case TC8521_SECOND10: + internal_clock.sec = peek2(TC8521_SECOND); + break; + case TC8521_MINUTE1: + case TC8521_MINUTE10: + internal_clock.min = peek2(TC8521_MINUTE); + break; + case TC8521_HOUR1: + case TC8521_HOUR10: + temp = peek2(TC8521_HOUR); + if (nvrram[TC8521_24HR] & 1) + internal_clock.hour = temp; + else + internal_clock.hour = ((temp & ~0x20) % 12) + ((temp & 0x20) ? 12 : 0); + break; + case TC8521_DAY1: + case TC8521_DAY10: + internal_clock.mday = peek2(TC8521_DAY); + break; + case TC8521_MONTH1: + case TC8521_MONTH10: + internal_clock.mon = peek2(TC8521_MONTH); + break; + case TC8521_YEAR1: + case TC8521_YEAR10: + internal_clock.year = 1980 + peek2(TC8521_YEAR); + break; + } +} + +/* Called to obtain the current day of the week based on the internal clock */ +static int time_week_day() +{ + int day_of_month = internal_clock.mday; + int month2 = internal_clock.mon; + int year2 = internal_clock.year % 100; + int century = ((internal_clock.year - year2) / 100) % 4; + int sum = day_of_month + month2 + year2 + century; + /* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */ + int raw_wd = ((sum + 6) % 7); + return raw_wd; +} + +/* Called to get time into the internal clock */ +static void tc8521_internal_get(struct tm *time_var) +{ + time_var->tm_sec = internal_clock.sec; + time_var->tm_min = internal_clock.min; + time_var->tm_hour = internal_clock.hour; + time_var->tm_wday = time_week_day(); + time_var->tm_mday = internal_clock.mday; + time_var->tm_mon = internal_clock.mon - 1; + time_var->tm_year = internal_clock.year - 1900; +} + +static void tc8521_internal_set(struct tm *time_var) +{ + internal_clock.sec = time_var->tm_sec; + internal_clock.min = time_var->tm_min; + internal_clock.hour = time_var->tm_hour; + internal_clock.mday = time_var->tm_mday; + internal_clock.mon = time_var->tm_mon + 1; + internal_clock.year = time_var->tm_year + 1900; +} + +static void tc8521_set_nvrram(uint8_t *nvrram, struct tm *cur_time_tm) +{ + nvrram[TC8521_SECOND1] = cur_time_tm->tm_sec % 10; + nvrram[TC8521_SECOND10] = cur_time_tm->tm_sec / 10; + nvrram[TC8521_MINUTE1] = cur_time_tm->tm_min % 10; + nvrram[TC8521_MINUTE10] = cur_time_tm->tm_min / 10; + if (nvrram[TC8521_24HR] & 1) + { + nvrram[TC8521_HOUR1] = cur_time_tm->tm_hour % 10; + nvrram[TC8521_HOUR10] = cur_time_tm->tm_hour / 10; + } + else + { + nvrram[TC8521_HOUR1] = (cur_time_tm->tm_hour % 12) % 10; + nvrram[TC8521_HOUR10] = ((cur_time_tm->tm_hour % 12) / 10) + | (cur_time_tm->tm_hour >= 12) ? 2 : 0; + } + nvrram[TC8521_WEEKDAY] = cur_time_tm->tm_wday; + nvrram[TC8521_DAY1] = cur_time_tm->tm_mday % 10; + nvrram[TC8521_DAY10] = cur_time_tm->tm_mday / 10; + nvrram[TC8521_MONTH1] = (cur_time_tm->tm_mon + 1) / 10; + nvrram[TC8521_MONTH10] = (cur_time_tm->tm_mon + 1) % 10; + nvrram[TC8521_YEAR1] = (cur_time_tm->tm_year - 80) % 10; + nvrram[TC8521_YEAR10] = ((cur_time_tm->tm_year - 80) % 100) / 10; +} + + +void tc8521_internal_set_nvrram(uint8_t *nvrram) +{ + /* Load the entire internal clock state from the NVR. */ + internal_clock.sec = peek2(TC8521_SECOND); + internal_clock.min = peek2(TC8521_MINUTE); + if (nvrram[TC8521_24HR] & 1) + { + internal_clock.hour = peek2(TC8521_HOUR); + } + else + { + internal_clock.hour = (peek2(TC8521_HOUR) % 12) + + (nvrram[TC8521_HOUR10] & 2) ? 12 : 0; + } + internal_clock.mday = peek2(TC8521_DAY); + internal_clock.mon = peek2(TC8521_MONTH); + internal_clock.year = 1980 + peek2(TC8521_YEAR); +} + +void tc8521_internal_sync(uint8_t *nvrram) +{ + struct tm *cur_time_tm; + time_t cur_time; + + time(&cur_time); + cur_time_tm = localtime(&cur_time); + + tc8521_internal_set(cur_time_tm); + + tc8521_set_nvrram(nvrram, cur_time_tm); +} + +void tc8521_get(uint8_t *nvrram) +{ + struct tm cur_time_tm; + + tc8521_internal_get(&cur_time_tm); + + tc8521_set_nvrram(nvrram, &cur_time_tm); +} diff --git a/src/rtc_tc8521.h b/src/rtc_tc8521.h new file mode 100644 index 0000000..158bd97 --- /dev/null +++ b/src/rtc_tc8521.h @@ -0,0 +1,33 @@ + +/* The TC8521 is a 4-bit RTC, so each memory location can only hold a single + * BCD digit. Hence everything has 'ones' and 'tens' digits. */ +enum TC8521_ADDR +{ + /* Page 0 registers */ + TC8521_SECOND1, + TC8521_SECOND10, + TC8521_MINUTE1, + TC8521_MINUTE10, + TC8521_HOUR1, + TC8521_HOUR10, + TC8521_WEEKDAY, + TC8521_DAY1, + TC8521_DAY10, + TC8521_MONTH1, + TC8521_MONTH10, + TC8521_YEAR1, + TC8521_YEAR10, + TC8521_PAGE, /* PAGE register */ + TC8521_TEST, /* TEST register */ + TC8521_RESET, /* RESET register */ + /* Page 1 registers */ + TC8521_24HR = 0x1A, + TC8521_LEAPYEAR = 0x1B +}; + + +void tc8521_tick(); +void tc8521_update(uint8_t *nvrram, int reg); +void tc8521_get(uint8_t *nvrram); +void tc8521_internal_set_nvrram(uint8_t *nvrram); +void tc8521_internal_sync(uint8_t *nvrram); diff --git a/src/t1000.c b/src/t1000.c new file mode 100644 index 0000000..1076489 --- /dev/null +++ b/src/t1000.c @@ -0,0 +1,579 @@ +#include +#include "ibm.h" +#include "cpu.h" +#include "model.h" +#include "io.h" +#include "fdc.h" +#include "fdd.h" +#include "mouse.h" +#include "mem.h" +#include "nmi.h" +#include "nvr.h" +#include "nvr_tc8521.h" +#include "pit.h" +#include "device.h" +#include "keyboard_xt.h" +#include "vid_t1000.h" + +/* The T1000 is the T3100e's little brother -- a real laptop with a + * rechargeable battery. + * + * Features: 80C88 at 4.77MHz + * 512k system RAM + * 640x200 monochrome LCD + * 82-key keyboard + * Real-time clock. Not the normal 146818, but a TC8521, which + * is a 4-bit chip. + * A ROM drive (128k, 256k or 512k) which acts as a mini hard + * drive and contains a copy of DOS 2.11. + * 160 bytes of non-volatile RAM for the CONFIG.SYS used when + * booting from the ROM drive. + * + * An optional memory expansion board can be fitted. This adds 768k of RAM, + * which can be used for up to three purposes: + * > Conventional memory -- 128k between 512k and 640k + * > HardRAM -- a battery-backed RAM drive. + * > EMS + * + * This means that there are up to three different implementations of + * non-volatile RAM in the same computer (52 nibbles in the TC8521, 160 + * bytes of CONFIG.SYS, and up to 768k of HardRAM). + * + */ + +void common_init(); + +uint8_t config_sys[160]; + +static struct t1000_system +{ + /* ROM drive */ + uint8_t *romdrive; + uint8_t rom_ctl; + uint32_t rom_offset; + mem_mapping_t rom_mapping; + + /* System control registers */ + uint8_t sys_ctl[16]; + uint8_t syskeys; + + /* NVRAM control */ + uint8_t nvr_c0; + uint8_t nvr_tick; + int nvr_addr; + uint8_t nvr_active; + + /* EMS data */ + uint8_t ems_reg[4]; + mem_mapping_t mapping[4]; + uint32_t page_exec[4]; + uint8_t ems_port_index; + uint16_t ems_port; + uint8_t is_640k; + uint32_t ems_base; + int32_t ems_pages; +} t1000; + +#define T1000_ROMSIZE (512 * 1024) /* Maximum ROM drive size is 512k */ + +/* The CONFIG.SYS storage (160 bytes) and battery-backed EMS (all RAM + * above 512k) are implemented as NVR devices */ + +void t1000_configsys_loadnvr() +{ + FILE *f; + + memset(config_sys, 0x1A, sizeof(config_sys)); + f = nvrfopen("t1000_config.nvr", "rb"); + if (f) + { + fread(config_sys, sizeof(config_sys), 1, f); + fclose(f); + } +} + +/* All RAM beyond 512k is non-volatile */ +void t1000_emsboard_loadnvr() +{ + FILE *f; + + if (mem_size > 512) + { + f = nvrfopen("t1000_ems.nvr", "rb"); + if (f) + { + fread(&ram[512 * 1024], + 1024, (mem_size - 512), f); + fclose(f); + } + } +} + +void t1000_configsys_savenvr() +{ + FILE *f; + + f = nvrfopen("t1000_config.nvr", "wb"); + if (f) + { + fwrite(config_sys, sizeof(config_sys), 1, f); + fclose(f); + } +} + + +void t1000_emsboard_savenvr() +{ + FILE *f; + + if (mem_size > 512) + { + f = nvrfopen("t1000_ems.nvr", "wb"); + if (f) + { + fwrite(&ram[512 * 1024], + 1024, (mem_size - 512), f); + fclose(f); + } + } +} + + + +/* Given an EMS page ID, return its physical address in RAM. */ +uint32_t ems_execaddr(struct t1000_system *sys, int pg, uint16_t val) +{ + if (!(val & 0x80)) return 0; /* Bit 7 reset => not mapped */ + if (!sys->ems_pages) return 0; /* No EMS available: all used by + * HardRAM or conventional RAM */ + + val &= 0x7F; + +/* pclog("Select EMS page: %d of %d\n", val, sys->ems_pages); */ + if (val < sys->ems_pages) + { +/* EMS is any memory above 512k, with ems_base giving the start address */ + return (512 * 1024) + (sys->ems_base * 0x10000) + (0x4000 * val); + } + return 0; +} + + +static uint8_t ems_in(uint16_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + +/* pclog("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]); */ + return sys->ems_reg[(addr >> 14) & 3]; +} + +static void ems_out(uint16_t addr, uint8_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = (addr >> 14) & 3; + +/* pclog("ems_out(%04x, %02x) pg=%d\n", addr, val, pg); */ + sys->ems_reg[pg] = val; + sys->page_exec[pg] = ems_execaddr(sys, pg, val); + if (sys->page_exec[pg]) /* Page present */ + { + mem_mapping_enable(&sys->mapping[pg]); + mem_mapping_set_exec(&sys->mapping[pg], ram + sys->page_exec[pg]); + } + else + { + mem_mapping_disable(&sys->mapping[pg]); + } +} + + +/* Hardram size is in 64k units */ +static void ems_set_hardram(struct t1000_system *sys, uint8_t val) +{ + int n; + + val &= 0x1F; /* Mask off pageframe address */ + if (val && mem_size > 512) + { + sys->ems_base = val; + } + else + { + sys->ems_base = 0; + } +/* pclog("EMS base set to %02x\n", val); */ + sys->ems_pages = 48 - 4 * sys->ems_base; + if (sys->ems_pages < 0) sys->ems_pages = 0; + /* Recalculate EMS mappings */ + for (n = 0; n < 4; n++) + { + ems_out(n << 14, sys->ems_reg[n], sys); + } +} + + +static void ems_set_640k(struct t1000_system *sys, uint8_t val) +{ + if (val && mem_size >= 640) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 640 * 1024); + sys->is_640k = 1; + } + else + { + mem_mapping_set_addr(&ram_low_mapping, 0, 512 * 1024); + sys->is_640k = 0; + } +} + +static void ems_set_port(struct t1000_system *sys, uint8_t val) +{ + int n; + +/* pclog("ems_set_port(%d)", val & 0x0F); */ + if (sys->ems_port) + { + for (n = 0; n <= 0xC000; n += 0x4000) + { + io_removehandler(sys->ems_port + n, 0x01, + ems_in, NULL, NULL, ems_out, NULL, NULL, sys); + } + sys->ems_port = 0; + } + val &= 0x0F; + sys->ems_port_index = val; + if (val == 7) /* No EMS */ + { + sys->ems_port = 0; + } + else + { + sys->ems_port = 0x208 | (val << 4); + for (n = 0; n <= 0xC000; n += 0x4000) + { + io_sethandler(sys->ems_port + n, 0x01, + ems_in, NULL, NULL, ems_out, NULL, NULL, sys); + } + sys->ems_port = 0; + } +/* pclog(" -> %04x\n", sys->ems_port); */ +} + +static int addr_to_page(uint32_t addr) +{ + return (addr - 0xD0000) / 0x4000; +} + +/* Read RAM in the EMS page frame */ +static uint8_t ems_read_ram(uint32_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return 0xFF; + addr = sys->page_exec[pg] + (addr & 0x3FFF); + return ram[addr]; +} + + + + +static uint16_t ems_read_ramw(uint32_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return 0xFF; + /* pclog("ems_read_ramw addr=%05x ", addr); */ + addr = sys->page_exec[pg] + (addr & 0x3FFF); + /* pclog("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); */ + return *(uint16_t *)&ram[addr]; +} + + +static uint32_t ems_read_raml(uint32_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return 0xFF; + addr = sys->page_exec[pg] + (addr & 0x3FFF); + return *(uint32_t *)&ram[addr]; +} + +/* Write RAM in the EMS page frame */ +static void ems_write_ram(uint32_t addr, uint8_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return; + addr = sys->page_exec[pg] + (addr & 0x3FFF); + if (ram[addr] != val) nvr_dosave = 1; + ram[addr] = val; +} + + +static void ems_write_ramw(uint32_t addr, uint16_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return; + /* pclog("ems_write_ramw addr=%05x ", addr); */ + addr = sys->page_exec[pg] + (addr & 0x3FFF); + /* pclog("-> %06x val=%04x\n", addr, val); */ + + if (*(uint16_t *)&ram[addr] != val) nvr_dosave = 1; + *(uint16_t *)&ram[addr] = val; +} + + +static void ems_write_raml(uint32_t addr, uint32_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); + + if (pg < 0) return; + addr = sys->page_exec[pg] + (addr & 0x3FFF); + if (*(uint32_t *)&ram[addr] != val) nvr_dosave = 1; + *(uint32_t *)&ram[addr] = val; +} + + + + + +void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) +{ + t1000.syskeys &= ~andmask; + t1000.syskeys |= ormask; + t1000.syskeys ^= xormask; +} + + + +static uint8_t read_t1000_ctl(uint16_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + switch (addr & 0x0F) + { + case 1: return sys->syskeys; +/* Detect EMS board */ + case 0x0F: switch (sys->sys_ctl[0x0E]) + { + case 0x50: if (mem_size <= 512) + return 0xFF; + return 0x90 | sys->ems_port_index; +/* 0x60 is the page frame address: (0xD000 - 0xC400) / 0x20 */ + case 0x51: return sys->ems_base | 0x60; + case 0x52: return sys->is_640k ? 0x80 : 0; + } + return 0xFF; + default: return sys->sys_ctl[addr & 0x0F]; + } +} + +static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + sys->sys_ctl[addr & 0x0F] = val; + switch (addr & 0x0F) + { + /* Video control */ + case 4: if (sys->sys_ctl[3] == 0x5A) + { + t1000_video_options_set((val & 0x20) ? 1 : 0); + t1000_display_set((val & 0x40) ? 0 : 1); + } + break; + /* EMS control*/ + case 0x0F: + switch (sys->sys_ctl[0x0E]) + { + case 0x50: ems_set_port(sys, val); break; + case 0x51: ems_set_hardram(sys, val); break; + case 0x52: ems_set_640k(sys, val); break; + } + break; + + } +} + +/* Ports 0xC0 to 0xC3 appear to have two purposes: + * + * > Access to the 160 bytes of non-volatile RAM containing CONFIG.SYS + * > Reading the floppy changeline. I don't know why the Toshiba doesn't + * use the normal port 0x3F7 for this, but it doesn't. + * + */ +static uint8_t read_t1000_nvram(uint16_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + uint8_t tmp; + + switch (addr) + { + case 0xC2: /* Read next byte from NVRAM */ + tmp = 0xFF; + if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) + tmp = config_sys[sys->nvr_addr]; + ++sys->nvr_addr; + return tmp; + + case 0xC3: /* Read floppy changeline and NVRAM ready state */ + tmp = fdc_read(0x3F7, NULL); + + tmp = (tmp & 0x80) >> 3; /* Bit 4 is changeline */ + tmp |= (sys->nvr_active & 0xC0);/* Bits 6,7 are r/w mode */ + tmp |= 0x2E; /* Bits 5,3,2,1 always 1 */ + tmp |= (sys->nvr_active & 0x40) >> 6; /* Ready state */ + return tmp; + } + return 0xFF; +} + +static void write_t1000_nvram(uint16_t addr, uint8_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + switch (addr) + { +/* On the real T1000, port 0xC1 is only usable as the high byte of a 16-bit + * write to port 0xC0, with 0x5A in the low byte. */ + case 0xC0: sys->nvr_c0 = val; + break; +/* Write next byte to NVRAM */ + case 0xC1: if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) + { + if (config_sys[sys->nvr_addr] != val) + nvr_dosave = 1; + config_sys[sys->nvr_addr] = val; + } + ++sys->nvr_addr; + break; + case 0xC2: break; +/* At start of NVRAM read / write, 0x80 is written to port 0xC3. This seems + * to reset the NVRAM address counter. A single byte is then written (0xFF + * for write, 0x00 for read) which appears to be ignored. Simulate that by + * starting the address counter off at -1 */ + case 0xC3: sys->nvr_active = val; + if (val == 0x80) sys->nvr_addr = -1; + break; + } +} + +/* Port 0xC8 controls the ROM drive */ +static uint8_t read_t1000_rom_ctl(uint16_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + return sys->rom_ctl; +} + +static void write_t1000_rom_ctl(uint16_t addr, uint8_t val, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + sys->rom_ctl = val; + if (sys->romdrive && (val & 0x80)) /* Enable */ + { + sys->rom_offset = ((val & 0x7F) * 0x10000) % T1000_ROMSIZE; + mem_mapping_set_addr(&sys->rom_mapping, 0xA0000, 0x10000); + mem_mapping_set_exec(&sys->rom_mapping, sys->romdrive + + sys->rom_offset); + mem_mapping_enable(&sys->rom_mapping); + } + else + { + mem_mapping_disable(&sys->rom_mapping); + } +} + + +/* Read the ROM drive */ +static uint8_t t1000_read_rom(uint32_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + if (!sys->romdrive) return 0xFF; + return sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]; +} + +static uint16_t t1000_read_romw(uint32_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + if (!sys->romdrive) return 0xFFFF; + return *(uint16_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]); +} + + +static uint32_t t1000_read_roml(uint32_t addr, void *priv) +{ + struct t1000_system *sys = (struct t1000_system *)priv; + + if (!sys->romdrive) return 0xFFFFFFFF; + return *(uint32_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]); +} + + +void xt_t1000_init() +{ + FILE *f; + int pg; + + memset(&t1000, 0, sizeof(t1000)); + t1000.ems_port_index = 7; /* EMS disabled */ +/* The ROM drive is optional. If the file is missing, continue to boot; the + * BIOS will complain 'No ROM drive' but boot normally from floppy. */ + + f = romfopen("t1000/t1000dos.rom", "rb"); + if (f) + { + t1000.romdrive = malloc(T1000_ROMSIZE); + if (t1000.romdrive) + { + memset(t1000.romdrive, 0xFF, T1000_ROMSIZE); + fread(t1000.romdrive, T1000_ROMSIZE, 1, f); + } + fclose(f); + } + mem_mapping_add(&t1000.rom_mapping, 0xA0000, 0x10000, + t1000_read_rom, t1000_read_romw, t1000_read_roml, + NULL, NULL, NULL, NULL, MEM_MAPPING_INTERNAL, &t1000); + mem_mapping_disable(&t1000.rom_mapping); + + /* Map the EMS page frame */ + for (pg = 0; pg < 4; pg++) + { + mem_mapping_add(&t1000.mapping[pg], + 0xD0000 + (0x4000 * pg), 16384, + ems_read_ram, ems_read_ramw, ems_read_raml, + ems_write_ram, ems_write_ramw, ems_write_raml, + NULL, MEM_MAPPING_EXTERNAL, + &t1000); + /* Start them all off disabled */ + mem_mapping_disable(&t1000.mapping[pg]); + } + + /* Non-volatile RAM for CONFIG.SYS */ + io_sethandler(0xC0, 4, read_t1000_nvram, NULL, NULL, + write_t1000_nvram, NULL, NULL, &t1000); + /* ROM drive */ + io_sethandler(0xC8, 1, read_t1000_rom_ctl, NULL, NULL, + write_t1000_rom_ctl, NULL, NULL, &t1000); + /* System control functions, and add-on memory board */ + io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL, + write_t1000_ctl, NULL, NULL, &t1000); + + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); + nvr_tc8521_init(); +/* No gameport, and no provision to fit one device_add(&gameport_device); */ +} diff --git a/src/t1000.h b/src/t1000.h new file mode 100644 index 0000000..34cc548 --- /dev/null +++ b/src/t1000.h @@ -0,0 +1,7 @@ +void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask); + +void t1000_configsys_loadnvr(); +void t1000_emsboard_loadnvr(); + +void t1000_configsys_savenvr(); +void t1000_emsboard_savenvr(); diff --git a/src/vid_t1000.c b/src/vid_t1000.c new file mode 100644 index 0000000..69939d8 --- /dev/null +++ b/src/vid_t1000.c @@ -0,0 +1,695 @@ +/* Emulate the Toshiba 1000 plasma display. This display has a fixed 640x200 + * resolution. */ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "timer.h" +#include "video.h" +#include "vid_cga.h" +#include "vid_t1000.h" + +#define T1000_XSIZE 640 +#define T1000_YSIZE 200 + +/* Mapping of attributes to colours */ +static uint32_t blue, grey; +static uint8_t boldcols[256]; /* Which attributes use the bold font */ +static uint32_t blinkcols[256][2]; +static uint32_t normcols[256][2]; + +/* Video options set by the motherboard; they will be picked up by the card + * on the next poll. + * + * Bit 1: Danish + * Bit 0: Thin font + */ +static uint8_t st_video_options; +static uint8_t st_display_internal = -1; + +void t1000_video_options_set(uint8_t options) +{ + st_video_options = options & 1; + st_video_options |= device_get_config_int("display_language") ? 2 : 0; +} + +void t1000_display_set(uint8_t internal) +{ + st_display_internal = internal; +} + +uint8_t t1000_display_get() +{ + return st_display_internal; +} + + +typedef struct t1000_t +{ + mem_mapping_t mapping; + + cga_t cga; /* The CGA is used for the external + * display; most of its registers are + * ignored by the plasma display. */ + + int font; /* Current font, 0-3 */ + int enabled; /* Hardware enabled, 0 or 1 */ + int internal; /* Using internal display? */ + uint8_t attrmap; /* Attribute mapping register */ + + int dispontime, dispofftime; + + int linepos, displine; + int vc; + int dispon; + int vsynctime; + uint8_t video_options; + + uint8_t *vram; +} t1000_t; + + +static void t1000_recalctimings(t1000_t *t1000); +static void t1000_write(uint32_t addr, uint8_t val, void *p); +static uint8_t t1000_read(uint32_t addr, void *p); +static void t1000_recalcattrs(t1000_t *t1000); + + +static void t1000_out(uint16_t addr, uint8_t val, void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + switch (addr) + { + /* Emulated CRTC, register select */ + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: + cga_out(addr, val, &t1000->cga); + break; + + /* Emulated CRTC, value */ + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + /* Register 0x12 controls the attribute mappings for the + * LCD screen. */ + if (t1000->cga.crtcreg == 0x12) + { + t1000->attrmap = val; + t1000_recalcattrs(t1000); + return; + } + cga_out(addr, val, &t1000->cga); + + t1000_recalctimings(t1000); + return; + + /* CGA control register */ + case 0x3D8: + cga_out(addr, val, &t1000->cga); + return; + /* CGA colour register */ + case 0x3D9: + cga_out(addr, val, &t1000->cga); + return; + } +} + +static uint8_t t1000_in(uint16_t addr, void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + uint8_t val; + + switch (addr) + { + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + if (t1000->cga.crtcreg == 0x12) + { + val = t1000->attrmap & 0x0F; + if (t1000->internal) val |= 0x20; /* LCD / CRT */ + return val; + } + } + + return cga_in(addr, &t1000->cga); +} + + + + +static void t1000_write(uint32_t addr, uint8_t val, void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + egawrites++; + +// pclog("CGA_WRITE %04X %02X\n", addr, val); + t1000->vram[addr & 0x3fff] = val; + cycles -= 4; +} + +static uint8_t t1000_read(uint32_t addr, void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + egareads++; + cycles -= 4; + +// pclog("CGA_READ %04X\n", addr); + return t1000->vram[addr & 0x3fff]; +} + + + +static void t1000_recalctimings(t1000_t *t1000) +{ + double disptime; + double _dispontime, _dispofftime; + + if (!t1000->internal) + { + cga_recalctimings(&t1000->cga); + return; + } + disptime = 651; + _dispontime = 640; + _dispofftime = disptime - _dispontime; + t1000->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +} + +/* Draw a row of text in 80-column mode */ +static void t1000_text_row80(t1000_t *t1000) +{ + uint32_t cols[2]; + int x, c; + uint8_t chr, attr; + int drawcursor; + int cursorline; + int bold; + int blink; + uint16_t addr; + uint8_t sc; + uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; + uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; + + sc = (t1000->displine) & 7; + addr = ((ma & ~1) + (t1000->displine >> 3) * 80) * 2; + ma += (t1000->displine >> 3) * 80; + + if ((t1000->cga.crtc[10] & 0x60) == 0x20) + { + cursorline = 0; + } + else + { + cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && + ((t1000->cga.crtc[11] & 0x0F) >= sc); + } + for (x = 0; x < 80; x++) + { + chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; + attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && + (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); + + blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && + (attr & 0x80) && !drawcursor); + + if (t1000->video_options & 1) + bold = boldcols[attr] ? chr : chr + 256; + else + bold = boldcols[attr] ? chr + 256 : chr; + if (t1000->video_options & 2) + bold += 512; + + if (t1000->cga.cgamode & 0x20) /* Blink */ + { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + if (blink) cols[1] = cols[0]; + } + else + { + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + if (drawcursor) + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); + } + } + else + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + ++ma; + } +} + +/* Draw a row of text in 40-column mode */ +static void t1000_text_row40(t1000_t *t1000) +{ + uint32_t cols[2]; + int x, c; + uint8_t chr, attr; + int drawcursor; + int cursorline; + int bold; + int blink; + uint16_t addr; + uint8_t sc; + uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; + uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; + + sc = (t1000->displine) & 7; + addr = ((ma & ~1) + (t1000->displine >> 3) * 40) * 2; + ma += (t1000->displine >> 3) * 40; + + if ((t1000->cga.crtc[10] & 0x60) == 0x20) + { + cursorline = 0; + } + else + { + cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && + ((t1000->cga.crtc[11] & 0x0F) >= sc); + } + for (x = 0; x < 40; x++) + { + chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; + attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && + (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); + + blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && + (attr & 0x80) && !drawcursor); + + if (t1000->video_options & 1) + bold = boldcols[attr] ? chr : chr + 256; + else + bold = boldcols[attr] ? chr + 256 : chr; + if (t1000->video_options & 2) + bold += 512; + + if (t1000->cga.cgamode & 0x20) /* Blink */ + { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + if (blink) cols[1] = cols[0]; + } + else + { + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + if (drawcursor) + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] = + ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); + } + } + else + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2] = + ((uint32_t *)buffer32->line[t1000->displine])[(x << 4) + c*2+1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ++ma; + } +} + +/* Draw a line in CGA 640x200 mode */ +static void t1000_cgaline6(t1000_t *t1000) +{ + int x, c; + uint8_t dat; + uint32_t ink = 0; + uint16_t addr; + uint32_t fg = (t1000->cga.cgacol & 0x0F) ? blue : grey; + uint32_t bg = grey; + + uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; + + addr = ((t1000->displine) & 1) * 0x2000 + + (t1000->displine >> 1) * 80 + + ((ma & ~1) << 1); + + for (x = 0; x < 80; x++) + { + dat = t1000->vram[addr & 0x3FFF]; + addr++; + + for (c = 0; c < 8; c++) + { + ink = (dat & 0x80) ? fg : bg; + if (!(t1000->cga.cgamode & 8)) + ink = grey; + ((uint32_t *)buffer32->line[t1000->displine])[x*8+c] = ink; + dat = dat << 1; + } + } +} + +/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to + * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ +static void t1000_cgaline4(t1000_t *t1000) +{ + int x, c; + uint8_t dat, pattern; + uint32_t ink0, ink1; + uint16_t addr; + + uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; + addr = ((t1000->displine) & 1) * 0x2000 + + (t1000->displine >> 1) * 80 + + ((ma & ~1) << 1); + + for (x = 0; x < 80; x++) + { + dat = t1000->vram[addr & 0x3FFF]; + addr++; + + for (c = 0; c < 4; c++) + { + pattern = (dat & 0xC0) >> 6; + if (!(t1000->cga.cgamode & 8)) pattern = 0; + + switch (pattern & 3) + { + case 0: ink0 = ink1 = grey; break; + case 1: if (t1000->displine & 1) + { + ink0 = grey; ink1 = grey; + } + else + { + ink0 = blue; ink1 = grey; + } + break; + case 2: if (t1000->displine & 1) + { + ink0 = grey; ink1 = blue; + } + else + { + ink0 = blue; ink1 = grey; + } + break; + case 3: ink0 = ink1 = blue; break; + + } + ((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c] = ink0; + ((uint32_t *)buffer32->line[t1000->displine])[x*8+2*c+1] = ink1; + dat = dat << 2; + } + } +} + +static void t1000_poll(void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + + if (t1000->video_options != st_video_options) + { + t1000->video_options = st_video_options; + + /* Set the font used for the external display */ + t1000->cga.fontbase = ((t1000->video_options & 3) * 256); + } + /* Switch between internal plasma and external CRT display. */ + if (st_display_internal != -1 && st_display_internal != t1000->internal) + { + t1000->internal = st_display_internal; + t1000_recalctimings(t1000); + } + if (!t1000->internal) + { + cga_poll(&t1000->cga); + return; + } + + if (!t1000->linepos) + { + t1000->cga.vidtime += t1000->dispofftime; + t1000->cga.cgastat |= 1; + t1000->linepos = 1; + if (t1000->dispon) + { + if (t1000->displine == 0) + { + video_wait_for_buffer(); + } + + /* Graphics */ + if (t1000->cga.cgamode & 0x02) + { + if (t1000->cga.cgamode & 0x10) + t1000_cgaline6(t1000); + else t1000_cgaline4(t1000); + } + else + if (t1000->cga.cgamode & 0x01) /* High-res text */ + { + t1000_text_row80(t1000); + } + else + { + t1000_text_row40(t1000); + } + } + t1000->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (t1000->displine == 200) /* Start of VSYNC */ + { + t1000->cga.cgastat |= 8; + t1000->dispon = 0; + } + if (t1000->displine == 216) /* End of VSYNC */ + { + t1000->displine = 0; + t1000->cga.cgastat &= ~8; + t1000->dispon = 1; + } + } + else + { + if (t1000->dispon) + { + t1000->cga.cgastat &= ~1; + } + t1000->cga.vidtime += t1000->dispontime; + t1000->linepos = 0; + + if (t1000->displine == 200) + { + /* Hardcode 640x200 window size */ + if (T1000_XSIZE != xsize || T1000_YSIZE != ysize) + { + xsize = T1000_XSIZE; + ysize = T1000_YSIZE; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + + frames++; + /* Fixed 640x200 resolution */ + video_res_x = T1000_XSIZE; + video_res_y = T1000_YSIZE; + + if (t1000->cga.cgamode & 0x02) + { + if (t1000->cga.cgamode & 0x10) + video_bpp = 1; + else video_bpp = 2; + + } + else video_bpp = 0; + t1000->cga.cgablink++; + } + } +} + +static void t1000_recalcattrs(t1000_t *t1000) +{ + int n; + + /* val behaves as follows: + * Bit 0: Attributes 01-06, 08-0E are inverse video + * Bit 1: Attributes 01-06, 08-0E are bold + * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF + * are inverse video + * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF + * are bold */ + + /* Set up colours */ + blue = makecol(0x2D, 0x39, 0x5A); + grey = makecol(0x85, 0xa0, 0xD6); + + /* Initialise the attribute mapping. Start by defaulting everything + * to grey on blue, and with bold set by bit 3 */ + for (n = 0; n < 256; n++) + { + boldcols[n] = (n & 8) != 0; + blinkcols[n][0] = normcols[n][0] = blue; + blinkcols[n][1] = normcols[n][1] = grey; + } + + /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the + * passed value. Exclude x0 and x8, which are always grey on + * blue. */ + for (n = 0x11; n <= 0xFF; n++) + { + if ((n & 7) == 0) continue; + if (t1000->attrmap & 4) /* Inverse */ + { + blinkcols[n][0] = normcols[n][0] = blue; + blinkcols[n][1] = normcols[n][1] = grey; + } + else /* Normal */ + { + blinkcols[n][0] = normcols[n][0] = grey; + blinkcols[n][1] = normcols[n][1] = blue; + } + if (t1000->attrmap & 8) boldcols[n] = 1; /* Bold */ + } + /* Set up the 01-0E range, controlled by bits 0 and 1 of the + * passed value. When blinking is enabled this also affects 81-8E. */ + for (n = 0x01; n <= 0x0E; n++) + { + if (n == 7) continue; + if (t1000->attrmap & 1) + { + blinkcols[n][0] = normcols[n][0] = blue; + blinkcols[n][1] = normcols[n][1] = grey; + blinkcols[n+128][0] = blue; + blinkcols[n+128][1] = grey; + } + else + { + blinkcols[n][0] = normcols[n][0] = grey; + blinkcols[n][1] = normcols[n][1] = blue; + blinkcols[n+128][0] = grey; + blinkcols[n+128][1] = blue; + } + if (t1000->attrmap & 2) boldcols[n] = 1; + } + /* Colours 07 and 0F are always blue on grey. If blinking is + * enabled so are 87 and 8F. */ + for (n = 0x07; n <= 0x0F; n += 8) + { + blinkcols[n][0] = normcols[n][0] = grey; + blinkcols[n][1] = normcols[n][1] = blue; + blinkcols[n+128][0] = grey; + blinkcols[n+128][1] = blue; + } + /* When not blinking, colours 81-8F are always blue on grey. */ + for (n = 0x81; n <= 0x8F; n ++) + { + normcols[n][0] = grey; + normcols[n][1] = blue; + boldcols[n] = (n & 0x08) != 0; + } + + + /* Finally do the ones which are solid grey. These differ between + * the normal and blinking mappings */ + for (n = 0; n <= 0xFF; n += 0x11) + { + normcols[n][0] = normcols[n][1] = grey; + } + /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are grey */ + for (n = 0; n <= 0x77; n += 0x11) + { + blinkcols[n][0] = blinkcols[n][1] = grey; + blinkcols[n+128][0] = blinkcols[n+128][1] = grey; + } +} + + +static void *t1000_init() +{ + t1000_t *t1000 = malloc(sizeof(t1000_t)); + memset(t1000, 0, sizeof(t1000_t)); + cga_init(&t1000->cga); + + t1000->internal = 1; + + /* 16k video RAM */ + t1000->vram = malloc(0x4000); + + timer_add(t1000_poll, &t1000->cga.vidtime, TIMER_ALWAYS_ENABLED, t1000); + + /* Occupy memory between 0xB8000 and 0xBFFFF */ + mem_mapping_add(&t1000->mapping, 0xb8000, 0x8000, t1000_read, NULL, NULL, t1000_write, NULL, NULL, NULL, 0, t1000); + /* Respond to CGA I/O ports */ + io_sethandler(0x03d0, 0x000c, t1000_in, NULL, NULL, t1000_out, NULL, NULL, t1000); + + /* Default attribute mapping is 4 */ + t1000->attrmap = 4; + t1000_recalcattrs(t1000); + + /* Start off in 80x25 text mode */ + t1000->cga.cgastat = 0xF4; + t1000->cga.vram = t1000->vram; + t1000->enabled = 1; + t1000->video_options = 0x01; + return t1000; +} + +static void t1000_close(void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + + free(t1000->vram); + free(t1000); +} + +static void t1000_speed_changed(void *p) +{ + t1000_t *t1000 = (t1000_t *)p; + + t1000_recalctimings(t1000); +} + +static device_config_t t1000_config[] = +{ + { + .name = "display_language", + .description = "Language", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "USA", + .value = 0 + }, + { + .description = "Danish", + .value = 1 + } + }, + .default_int = 0 + }, + { + .type = -1 + } +}; + + +device_t t1000_device = +{ + "Toshiba T1000", + 0, + t1000_init, + t1000_close, + NULL, + t1000_speed_changed, + NULL, + NULL, + t1000_config +}; diff --git a/src/vid_t1000.h b/src/vid_t1000.h new file mode 100644 index 0000000..d85e9c6 --- /dev/null +++ b/src/vid_t1000.h @@ -0,0 +1,4 @@ +extern device_t t1000_device; + +void t1000_video_options_set(uint8_t options); +void t1000_display_set(uint8_t internal); diff --git a/src/video.c b/src/video.c index aae872a..952828e 100644 --- a/src/video.c +++ b/src/video.c @@ -42,6 +42,7 @@ #include "vid_vga.h" #include "vid_wy700.h" #include "vid_t3100e.h" +#include "vid_t1000.h" typedef struct { @@ -316,6 +317,10 @@ void video_init() case ROM_T3100E: device_add(&t3100e_device); return; + + case ROM_T1000: + device_add(&t1000_device); + return; } device_add(video_cards[video_old_to_new(gfxcard)].device); } @@ -393,7 +398,7 @@ void loadfont(char *s, int format) break; default: case 2: /* CGA */ - for (c=0;c<256;c++) + for (c=0;c<2048;c++) /* Allow up to 2048 chars */ { for (d=0;d<8;d++) { From 0fe4a837405545acb053accd8ed8909dd9cabb2e Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 11 Jan 2018 21:59:44 +0000 Subject: [PATCH 0280/1050] Added Realtek RTL8029AS emulation. --- src/ne2000.c | 280 +++++++++++++++++++++++++++++++++++++++++++---- src/ne2000.h | 1 + src/nethandler.c | 5 +- src/wx-config.c | 21 ++-- 4 files changed, 274 insertions(+), 33 deletions(-) diff --git a/src/ne2000.c b/src/ne2000.c index 3dcb63f..aa59b90 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -47,11 +47,20 @@ #include "io.h" #include "ne2000.h" #include "pic.h" +#include "pci.h" #include "timer.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}; +typedef enum +{ + NE2000_NE2000, + NE2000_RTL8029AS +} ne2000_type; + +#define NE2000_PCI_IRQ -1 + #define NETBLOCKING 0 //we won't block our pcap //#define NE2000_DEBUG @@ -250,6 +259,19 @@ typedef struct ne2000_t int base_irq; int tx_timer_index; int tx_timer_active; + + ne2000_type type; + + /*PCI stuff*/ + int is_pci; + int card; + uint32_t base_addr; + uint8_t pci_command; + uint8_t int_line; + + /*RTL8029AS registers*/ + uint8_t config0, config2, config3; + uint8_t _9346cr; } ne2000_t; static void ne2000_tx_event(int val, void *p); @@ -260,6 +282,23 @@ static void ne2000_setirq(ne2000_t *ne2000, int irq) { ne2000->base_irq = irq; } + +static void ne2000_raise_irq(ne2000_t *ne2000) +{ + if (ne2000->is_pci) + pci_set_irq(ne2000->card, PCI_INTA); + else + picint(1 << ne2000->base_irq); +} + +static void ne2000_lower_irq(ne2000_t *ne2000) +{ + if (ne2000->is_pci) + pci_clear_irq(ne2000->card, PCI_INTA); + else + picintc(1 << ne2000->base_irq); +} + // // reset - restore state to power-up, cancelling all i/o // @@ -328,8 +367,9 @@ static void ne2000_reset(int type, void *p) ne2000->CR.rdma_cmd = 4; ne2000->ISR.reset = 1; ne2000->DCR.longaddr = 1; - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); + ne2000_lower_irq(ne2000); + //DEV_pic_lower_irq(ne2000->base_irq); } @@ -416,7 +456,7 @@ uint16_t ne2000_dma_read(int io_len, void *p) ne2000->ISR.rdma_done = 1; if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); } } @@ -465,7 +505,7 @@ void ne2000_dma_write(int io_len, void *p) ne2000->ISR.rdma_done = 1; if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); } } } @@ -731,8 +771,35 @@ uint8_t ne2000_read(uint16_t address, void *p) } break; - default: - fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); + case 0x03: + if (ne2000->type != NE2000_RTL8029AS) + fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); +#ifdef NE2000_DEBUG + pclog("page 3 read from port %04x\n", address); +#endif + switch (address) + { + case 0x1: /*9346CR*/ + return ne2000->_9346cr; + + case 0x3: /*CONFIG0*/ + return 0x00; /*Cable not BNC*/ + + case 0x5: /*CONFIG2*/ + return ne2000->config2 & 0xe0; /*No boot ROM*/ + + case 0x6: /*CONFIG3*/ + return ne2000->config3 & 0x46; + + case 0xe: /*8029ASID0*/ + return 0x29; + + case 0xf: /*8029ASID1*/ + return 0x08; + } + + pclog("reserved read - page 3, 0x%02x\n", address); + break; } } @@ -828,7 +895,7 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { //LOG_MSG("tx complete interrupt"); - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); } ne2000->ISR.pkt_tx = 1; } @@ -889,7 +956,7 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) ne2000->ISR.rdma_done = 1; if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); //DEV_pic_raise_irq(ne2000->base_irq); } } @@ -960,7 +1027,7 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) (ne2000->IMR.tx_inte << 1) | (ne2000->IMR.rx_inte)); if (value == 0) - picintc(1 << ne2000->base_irq); + ne2000_lower_irq(ne2000); //DEV_pic_lower_irq(ne2000->base_irq); break; @@ -1092,7 +1159,7 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) #ifdef NE2000_DEBUG pclog("tx irq retrigger\n"); #endif - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); } break; } @@ -1194,11 +1261,36 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) } break; - default: - //fatal("ne2K: unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + case 0x03: + if (ne2000->type != NE2000_RTL8029AS) + { + pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + break; + } #ifdef NE2000_DEBUG - pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + pclog("page 3 write to port %04x\n", address); #endif + switch (address) + { + case 0x1: /*9346CR*/ + ne2000->_9346cr = value & 0xfe; + break; + + case 0x5: /*CONFIG2*/ + ne2000->config2 = value & 0xe0; + break; + + case 0x6: /*CONFIG3*/ + ne2000->config3 = value & 0x46; + break; + + case 0x9: /*HLTCLK*/ + break; + + default: + pclog("reserved write - page 3, 0x%02x\n", address); + break; + } break; } } @@ -1376,7 +1468,7 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) if (ne2000->IMR.rx_inte) { //LOG_MSG("packet rx interrupt"); - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); //DEV_pic_raise_irq(ne2000->base_irq); } //else LOG_MSG("no packet rx interrupt"); @@ -1394,7 +1486,7 @@ void ne2000_tx_timer(void *p) if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { //LOG_MSG("tx complete interrupt"); - picint(1 << ne2000->base_irq); + ne2000_raise_irq(ne2000); //DEV_pic_raise_irq(ne2000->base_irq); } //else LOG_MSG("no tx complete interrupt"); @@ -1408,6 +1500,110 @@ static void ne2000_tx_event(int val, void *p) ne2000_tx_timer(ne2000); } +static void ne2000_pci_add(ne2000_t *ne2000) +{ + io_sethandler(ne2000->base_addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_sethandler(ne2000->base_addr+0x10, 0x000f, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); + io_sethandler(ne2000->base_addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); +} + +static void ne2000_pci_remove(ne2000_t *ne2000) +{ + io_removehandler(ne2000->base_addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_removehandler(ne2000->base_addr+0x10, 0x000f, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); + io_removehandler(ne2000->base_addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); +} + +static uint8_t rtl8029_pci_read(int func, int addr, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + if (func) + return 0; + +// pclog("RTL8029 PCI read %08X PC=%08x\n", addr, cpu_state.pc); + + switch (addr) + { + case 0x00: return 0xec; /*Realtek*/ + case 0x01: return 0x10; + + case 0x02: return 0x29; /*RTL8029AS*/ + case 0x03: return 0x80; + + case 0x04: return ne2000->pci_command; + + case 0x07: return 0x02; + + case 0x08: return 0; /*Revision ID*/ + case 0x09: return 0; /*Programming interface*/ + case 0x0a: return 0; /*Ethernet controller*/ + case 0x0b: return 0x02; /*Network controller*/ + + case 0x10: return 0x01 | (ne2000->base_addr & 0xe0); /*memBaseAddr*/ + case 0x11: return ne2000->base_addr >> 8; + case 0x12: return ne2000->base_addr >> 16; + case 0x13: return ne2000->base_addr >> 24; + + case 0x2c: return 0xec; /*Subsystem vendor - Realtek*/ + case 0x2d: return 0x10; + + case 0x2e: return 0x29; /*Subsystem ID - RTL8029AS*/ + case 0x2f: return 0x80; + + case 0x3c: return ne2000->int_line; + case 0x3d: return 0x01; /*INTA*/ + } + return 0; +} + +static void rtl8029_pci_write(int func, int addr, uint8_t val, void *p) +{ + ne2000_t *ne2000 = (ne2000_t *)p; + + if (func) + return; + +// pclog("RTL8029 PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); + + switch (addr) + { + case 0x04: + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_remove(ne2000); + ne2000->pci_command = val & 3; + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_add(ne2000); + break; + + case 0x10: + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_remove(ne2000); + ne2000->base_addr = (ne2000->base_addr & 0xffffff00) | (val & 0xe0); + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_add(ne2000); + break; + case 0x11: + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_remove(ne2000); + ne2000->base_addr = (ne2000->base_addr & 0xffff00e0) | (val << 8); + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_add(ne2000); + break; + case 0x12: + ne2000->base_addr = (ne2000->base_addr & 0xff00ffe0) | (val << 16); + break; + case 0x13: + ne2000->base_addr = (ne2000->base_addr & 0x00ffffe0) | (val << 24); + break; + + case 0x3c: + ne2000->int_line = val; + break; + } +} + + static void ne2000_poller(void *p) { ne2000_t *ne2000 = (ne2000_t *)p; @@ -1462,7 +1658,7 @@ static void ne2000_poller(void *p) } -void *ne2000_init() +void *ne2000_common_init() { struct in_addr myaddr; int rc; @@ -1470,9 +1666,6 @@ void *ne2000_init() ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); - uint16_t addr = device_get_config_int("addr"); - ne2000_setirq(ne2000, device_get_config_int("irq")); - //net_type //0 pcap //1 slirp @@ -1491,15 +1684,12 @@ void *ne2000_init() net_is_pcap = 0; #endif - io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); memcpy(ne2000->physaddr, maclocal, 6); ne2000_reset(BX_RESET_HARDWARE, ne2000); vlan_handler(ne2000_poller, ne2000); - pclog("ne2000 init 0x%X %d\tslirp is %d net_is_pcap is %d\n",addr,device_get_config_int("irq"),net_is_slirp,net_is_pcap); + pclog("ne2000 init\tslirp is %d net_is_pcap is %d\n",net_is_slirp,net_is_pcap); //need a switch statment for more network types. @@ -1665,6 +1855,37 @@ void *ne2000_init() return ne2000; } +void *ne2000_init() +{ + ne2000_t *ne2000 = ne2000_common_init(); + uint16_t addr; + + ne2000->type = NE2000_NE2000; + + ne2000_setirq(ne2000, device_get_config_int("irq")); + + addr = device_get_config_int("addr"); + io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); + + return ne2000; +} + +void *rtl8029_init() +{ + ne2000_t *ne2000 = ne2000_common_init(); + + ne2000->is_pci = 1; + ne2000->type = NE2000_RTL8029AS; + + ne2000->card = pci_add(rtl8029_pci_read, rtl8029_pci_write, ne2000); + + ne2000_setirq(ne2000, NE2000_PCI_IRQ); + + return ne2000; +} + void ne2000_close(void *p) { ne2000_t *ne2000 = (ne2000_t *)p; @@ -1776,6 +1997,19 @@ device_t ne2000_device = ne2000_config }; +device_t rtl8029as_device = +{ + "Realtek RTL8029AS", + DEVICE_PCI, + rtl8029_init, + ne2000_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + //SLIRP stuff int slirp_can_output(void) diff --git a/src/ne2000.h b/src/ne2000.h index a3f1fea..e413877 100644 --- a/src/ne2000.h +++ b/src/ne2000.h @@ -1 +1,2 @@ extern device_t ne2000_device; +extern device_t rtl8029as_device; diff --git a/src/nethandler.c b/src/nethandler.c index 44987a2..871ef5c 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -26,8 +26,9 @@ typedef struct static NETWORK_CARD network_cards[] = { - {"None", "", NULL}, - {"Novell NE2000", "ne2000", &ne2000_device}, + {"None", "", NULL}, + {"Novell NE2000", "ne2000", &ne2000_device}, + {"Realtek RTL8029AS", "rtl8029as", &rtl8029as_device}, {"", "", NULL} }; diff --git a/src/wx-config.c b/src/wx-config.c index 672d208..2bee083 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -228,20 +228,24 @@ static void recalc_net_list(void *hdlg, int model) { void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); int c = 0, d = 0; - int set_zero = 0; + int found_card = 0; wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); while (1) { char *s = network_card_getname(c); + device_t *dev; if (!s[0]) break; settings_network_to_list[c] = d; - - if (network_card_available(c)) + + dev = network_card_getdevice(c); + + if (network_card_available(c) && + (!dev || (models[model].flags & MODEL_PCI) || !(dev->flags & DEVICE_PCI))) { device_t *network_dev = network_card_getdevice(c); @@ -249,18 +253,19 @@ static void recalc_net_list(void *hdlg, int model) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); settings_list_to_network[d] = c; + if (c == network_card_current) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + } d++; } - else if (c == network_card_current) - set_zero = 1; } c++; } - if (set_zero) + if (!found_card) wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, settings_network_to_list[network_card_current], 0); } #endif From bc690b3d2f999b6d3513d56a29e6742383e627c3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 16 Jan 2018 20:05:56 +0000 Subject: [PATCH 0281/1050] CD-ROM fixes : - Fixed track handling in is_track_audio() - ioctl_readtoc() First Track field returns first track in the TOC, not the first track specified by the command - SCSI CD-ROM code now looks at correct cd_status variable - SCSI CD-ROM now identifies as SCSI compliant Fixes CD audio via QCD with Adaptec SCSI card + ASPI drivers. --- src/cdrom-ioctl.c | 10 +++++++--- src/scsi_cd.c | 12 ++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 62c8319..58e05da 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -500,14 +500,19 @@ static int is_track_audio(uint32_t pos) if (!tocvalid) return 0; - for (c = toc.FirstTrack; c < toc.LastTrack; c++) + for (c = 0; toc.TrackData[c].TrackNumber != 0xaa; c++) { uint32_t track_address = toc.TrackData[c].Address[3] + (toc.TrackData[c].Address[2] * 75) + (toc.TrackData[c].Address[1] * 75 * 60); - if (track_address <= pos) + if (toc.TrackData[c].TrackNumber >= toc.FirstTrack && + toc.TrackData[c].TrackNumber <= toc.LastTrack && + track_address >= pos) + { control = toc.TrackData[c].Control; + break; + } } return (control & 4) ? 0 : 1; } @@ -562,7 +567,6 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in break; } } - b[2]=toc.TrackData[c].TrackNumber; last_block = 0; for (c=d;c<=toc.LastTrack;c++) { diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 1f9e411..fb32c01 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -355,10 +355,10 @@ static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t } else { + buf[pos++] = 5; /* Reserved */ buf[pos++] = 4; /* Reserved */ buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0x80; /* 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 */ @@ -502,7 +502,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[0] = 0x80 | 0x70; - if ((data->sense_key > 0) || (cd_status < CD_STATUS_PLAYING)) + if ((data->sense_key > 0) || (data->cd_status < CD_STATUS_PLAYING)) { if (completed) { @@ -523,7 +523,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) { data->data_in[2] = SENSE_ILLEGAL_REQUEST; data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; - data->data_in[13] = (cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + data->data_in[13] = (data->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; } //data->data_in[7] = 10; @@ -895,7 +895,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) } - if ((cdrom_drive < 1) || (cd_status <= CD_STATUS_DATA_ONLY) || + if ((cdrom_drive < 1) || (data->cd_status <= CD_STATUS_DATA_ONLY) || !atapi->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) { atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0); @@ -1002,7 +1002,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[0] = 5; /*CD-ROM*/ data->data_in[1] = 0x80; /*Removable*/ - data->data_in[2] = 0; + data->data_in[2] = 2; /*SCSI-2 compliant*/ data->data_in[3] = 0x21; data->data_in[4] = 31; data->data_in[5] = 0; From 6ecdd2efd02a443f0b50944108f472418e9b7cf3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Jan 2018 15:59:29 +0000 Subject: [PATCH 0282/1050] Unify ATAPI and SCSI CD-ROM code. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ibm.h | 2 + src/ide.c | 1530 ++-------------------------- src/ide.h | 13 + src/ide_atapi.c | 469 +++++++++ src/ide_atapi.h | 34 +- src/scsi.c | 37 +- src/scsi.h | 35 +- src/scsi_cd.c | 88 +- src/scsi_hd.c | 29 + src/wx-sdl2.c | 15 - 19 files changed, 761 insertions(+), 1509 deletions(-) create mode 100644 src/ide_atapi.c diff --git a/src/Makefile.am b/src/Makefile.am index 098d4d5..5683bc3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ amrefresh: pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ +hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index ff77aa6..580f1a9 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -7,7 +7,7 @@ CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index f274909..27108e2 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -7,7 +7,7 @@ CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 0022aab..e475974 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -6,7 +6,7 @@ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werro OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.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 \ + i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 57038f9..64e37e2 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -7,7 +7,7 @@ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werro OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.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 \ + i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 2928106..6941bc8 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -9,7 +9,7 @@ CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.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 \ + i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 794d72c..2853360 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -9,7 +9,7 @@ CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.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 \ + i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index be7f9fb..a2fbd9b 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -6,7 +6,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.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 \ + i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index e88dd86..dd2713b 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64= OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ diff --git a/src/ibm.h b/src/ibm.h index 37e7101..6b10a9e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -600,3 +600,5 @@ void saveconfig_global_only(); #define UNUSED(x) (void)x #define MIN(a, b) ((a) < (b) ? (a) : (b)) + +void ide_padstr(char *str, const char *src, int len); diff --git a/src/ide.c b/src/ide.c index a9cacd9..56f6f0a 100644 --- a/src/ide.c +++ b/src/ide.c @@ -25,21 +25,11 @@ #include "pic.h" #include "timer.h" #include "hdd_file.h" + #include "scsi.h" + #include "scsi_cd.h" #endif #include "ide.h" -/* Bits of 'atastat' */ -#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 */ - /* ATA Commands */ #define WIN_SRST 0x08 /* ATAPI Device Reset */ #define WIN_RECAL 0x10 @@ -65,172 +55,9 @@ #define WIN_CHECK_POWER_MODE 0xE5 #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -/* ATAPI Commands */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_READ_6 0x08 -#define GPCMD_INQUIRY 0x12 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_SEEK 0x2b -#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_PLAY_AUDIO_MSF 0x47 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_SEND_DVD_STRUCTURE 0xad -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe - -/* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f - -/* ATAPI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 - -/* ATAPI 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_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_MEDIUM_NOT_PRESENT 0x3a -#define ASC_DATA_PHASE_ERROR 0x4b -#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 - -#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 - -/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). - Not that it means anything */ -#define CDROM_SPEED 706 - /** Evaluate to non-zero if the currently selected drive is an ATAPI device */ #define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) -/* -\ - (!ide.drive)*/ -/* Event notification classes for GET EVENT STATUS NOTIFICATION */ -#define GESN_NO_EVENTS 0 -#define GESN_OPERATIONAL_CHANGE 1 -#define GESN_POWER_MANAGEMENT 2 -#define GESN_EXTERNAL_REQUEST 3 -#define GESN_MEDIA 4 -#define GESN_MULTIPLE_HOSTS 5 -#define GESN_DEVICE_BUSY 6 - -/* Event codes for MEDIA event status notification */ -#define MEC_NO_CHANGE 0 -#define MEC_EJECT_REQUESTED 1 -#define MEC_NEW_MEDIA 2 -#define MEC_MEDIA_REMOVAL 3 /* only for media changers */ -#define MEC_MEDIA_CHANGED 4 /* only for media changers */ -#define MEC_BG_FORMAT_COMPLETED 5 /* MRW or DVD+RW b/g format completed */ -#define MEC_BG_FORMAT_RESTARTED 6 /* MRW or DVD+RW b/g format restarted */ -#define MS_TRAY_OPEN 1 -#define MS_MEDIA_PRESENT 2 - -#define CHECK_READY 2 -#define ALLOW_UA 1 - -/* Table of all ATAPI commands and their flags, needed for the new disc change / not ready handler. */ -uint8_t atapi_cmd_table[0x100] = -{ - [GPCMD_TEST_UNIT_READY] = CHECK_READY, - [GPCMD_REQUEST_SENSE] = ALLOW_UA, - [GPCMD_READ_6] = CHECK_READY, - [GPCMD_INQUIRY] = ALLOW_UA, - [GPCMD_MODE_SELECT_6] = 0, - [GPCMD_MODE_SENSE_6] = 0, - [GPCMD_START_STOP_UNIT] = 0, - [GPCMD_PREVENT_REMOVAL] = CHECK_READY, - [GPCMD_READ_CDROM_CAPACITY] = CHECK_READY, - [GPCMD_READ_10] = CHECK_READY, - [GPCMD_SEEK] = CHECK_READY, - [GPCMD_READ_SUBCHANNEL] = CHECK_READY, - [GPCMD_READ_TOC_PMA_ATIP] = CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS */ - [GPCMD_READ_HEADER] = CHECK_READY, - [GPCMD_PLAY_AUDIO_10] = CHECK_READY, - [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_MODE_SELECT_10] = 0, - [GPCMD_MODE_SENSE_10] = 0, - [GPCMD_PLAY_AUDIO_12] = CHECK_READY, - [GPCMD_READ_12] = CHECK_READY, - [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY, /* Read DVD structure (NOT IMPLEMENTED YET) */ - [GPCMD_SET_SPEED] = 0, - [GPCMD_MECHANISM_STATUS] = 0, - [GPCMD_READ_CD] = CHECK_READY, - [0xBF] = CHECK_READY /* Send DVD structure (NOT IMPLEMENTED YET) */ -}; - -#define IMPLEMENTED 1 - -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 -}; - -ATAPI *atapi; - -int atapi_command = 0; -int readcdmode = 0; - -int cdrom_channel = 2; - -/* Mode sense/select stuff. */ -uint8_t mode_pages_in[256][256]; -#define PAGE_CHANGEABLE 1 -#define PAGE_CHANGED 2 -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, -}; -uint8_t prefix_len; -uint8_t page_current; - -#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_ERROR 0x80 -#define ATAPI_STATUS_ERROR_2 0x81 enum { @@ -239,6 +66,8 @@ enum IDE_CDROM }; +struct IDE; + typedef struct IDE { int type; @@ -249,10 +78,6 @@ typedef struct IDE uint8_t command; uint8_t fdisk; int pos; - int packlen; - int packetstatus; - int cdpos,cdlen; - uint8_t asc; int reset; uint16_t buffer[65536]; int irqstat; @@ -270,9 +95,12 @@ typedef struct IDE int tracks; #else hdd_file_t hdd_file; + atapi_device_t atapi; #endif } IDE; +int cdrom_channel = 2; + IDE ide_drives[4]; IDE *ext_ide; @@ -283,17 +111,13 @@ int (*ide_bus_master_read_sector)(int channel, uint8_t *data); int (*ide_bus_master_write_sector)(int channel, uint8_t *data); void (*ide_bus_master_set_irq)(int channel); -static void callnonreadcd(IDE *ide); -static void callreadcd(IDE *ide); -static void atapicommand(int ide_board); - int idecallback[2] = {0, 0}; int cur_ide[2]; uint8_t getstat(IDE *ide) { return ide->atastat; } -static inline void ide_irq_raise(IDE *ide) +void ide_irq_raise(IDE *ide) { // pclog("IDE_IRQ_RAISE\n"); if (!(ide->fdisk&2)) { @@ -353,8 +177,7 @@ void ide_irq_update(IDE *ide) * @param len Length of destination buffer to fill in. Strings shorter than * this length will be padded with spaces. */ -static void -ide_padstr(char *str, const char *src, int len) +void ide_padstr(char *str, const char *src, int len) { int i, v; @@ -368,29 +191,6 @@ ide_padstr(char *str, const char *src, int len) } } -/** - * Copy a string into a buffer, padding with spaces. Does not add string - * terminator. - * - * @param buf Destination buffer - * @param buf_size Size of destination buffer to fill in. Strings shorter than - * this length will be padded with spaces. - * @param src Source string - */ -static void -ide_padstr8(uint8_t *buf, int buf_size, const char *src) -{ - int i; - - for (i = 0; i < buf_size; i++) { - if (*src != '\0') { - buf[i] = *src++; - } else { - buf[i] = ' '; - } - } -} - /** * Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command */ @@ -436,127 +236,6 @@ static void ide_identify(IDE *ide) ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ } -/** - * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command - */ -static void ide_atapi_identify(IDE *ide) -{ - memset(ide->buffer, 0, 512); - - 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), "v1.0", 8); /* Firmware */ -#ifdef RPCEMU_IDE - ide_padstr((char *) (ide->buffer + 27), "RPCemuCD", 40); /* Model */ -#else - ide_padstr((char *) (ide->buffer + 27), "PCemCD", 40); /* Model */ -#endif - ide->buffer[49] = 0x200; /* LBA supported */ -} - -/** - * Fill in ide->buffer with the output of the ATAPI "MODE SENSE" command - * - * @param pos Offset within the buffer to start filling in data - * - * @return Offset within the buffer after the end of the data - */ -static uint32_t ide_atapi_mode_sense(IDE *ide, uint32_t pos, uint8_t type) -{ - uint8_t *buf = (uint8_t *) ide->buffer; -// pclog("ide_atapi_mode_sense %02X\n",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; -} - -uint32_t atapi_get_cd_channel(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 atapi_get_cd_volume(int channel) -{ - return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 9 : 7] : 0xFF; -} - /* * Return the sector offset for the current register values */ @@ -706,9 +385,6 @@ void resetide(void) ide_drives[d].board = (d & 2) ? 1 : 0; } - 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; if (hdd_controller_current_is_ide()) { @@ -722,11 +398,11 @@ void resetide(void) for (d = 0; d < 4; d++) { ide_drives[d].drive = d; - ide_drives[d].packetstatus = 0xFF; if ((cdrom_channel == d) && cdrom_enabled) { ide_drives[d].type = IDE_CDROM; + scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d); } else { @@ -734,26 +410,27 @@ void resetide(void) } ide_set_signature(&ide_drives[d]); + + ide_drives[d].atapi.ide = &ide_drives[d]; + ide_drives[d].atapi.board = (d & 2) ? 1 : 0; + ide_drives[d].atapi.atastat = &ide_drives[d].atastat; + ide_drives[d].atapi.error = &ide_drives[d].error; + ide_drives[d].atapi.cylinder = &ide_drives[d].cylinder; } } #endif + cur_ide[0] = 0; cur_ide[1] = 2; - -// ide_drives[1].type = IDE_CDROM; - - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; } + int idetimes=0; void writeidew(int ide_board, uint16_t val) { IDE *ide = &ide_drives[cur_ide[ide_board]]; - /*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; #ifndef RPCEMU_IDE /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) { @@ -764,58 +441,26 @@ void writeidew(int ide_board, uint16_t val) #ifdef _RPCEMU_BIG_ENDIAN val=(val>>8)|(val<<8); #endif -// pclog("Write IDEw %04X\n",val); - ide->buffer[ide->pos >> 1] = val; - ide->pos+=2; + if (ide->command == WIN_PACKETCMD) + { + atapi_data_write(&ide->atapi, val); + } + else + { + ide->buffer[ide->pos >> 1] = val; + ide->pos += 2; - if (ide->packetstatus == ATAPI_STATUS_PACKET_REQ) - { - if ((ide->pos>=prefix_len+4) && (page_flags[page_current] & PAGE_CHANGEABLE)) - { - 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]; - } - if (ide->pos>=(ide->packlen+2)) + if (ide->pos>=512) { - ide->packetstatus = ATAPI_STATUS_PACKET_RECEIVED; + 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; -/* idecallback[ide_board]=6*IDE_TIME;*/ - timer_process(); - callbackide(ide_board); - timer_update_outstanding(); -// idecallback[ide_board]=60*IDE_TIME; -// if ((ide->buffer[0]&0xFF)==0x43) idecallback[ide_board]=1*IDE_TIME; -// pclog("Packet now waiting!\n"); -/* if (ide->buffer[0]==0x243) - { - idetimes++; - output=3; - }*/ - } - 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(); } } @@ -1078,12 +723,19 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) return; case WIN_PACKETCMD: /* ATAPI Packet */ - ide->packetstatus = ATAPI_STATUS_IDLE; + if (ide->type == IDE_CDROM) + atapi_command_start(&ide->atapi); + ide->atastat = BUSY_STAT; timer_process(); + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); + + ide->atapi.bus_state = 0; +/* timer_process(); idecallback[ide_board]=1;//30*IDE_TIME; timer_update_outstanding(); - ide->pos=0; + ide->pos=0;*/ return; case 0xF0: @@ -1158,7 +810,10 @@ uint8_t readide(int ide_board, uint16_t addr) case 0x1F2: /* Sector count */ // pclog("Read sector count %02X\n",ide->secount); - temp = (uint8_t)ide->secount; + if (ide->type == IDE_CDROM && ide->command == WIN_PACKETCMD) + temp = atapi_read_iir(&ide->atapi); + else + temp = (uint8_t)ide->secount; break; case 0x1F3: /* Sector */ @@ -1191,6 +846,13 @@ uint8_t readide(int ide_board, uint16_t addr) { // pclog("Read CDROM status %02X\n",(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0)); temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + if (ide->command == WIN_PACKETCMD) + { + if (atapi_read_drq(&ide->atapi)) + temp |= DRQ_STAT; + else + temp &= ~DRQ_STAT; + } } else { @@ -1213,6 +875,13 @@ uint8_t readide(int ide_board, uint16_t addr) { // pclog("Read CDROM status %02X\n",(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0)); temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + if (ide->command == WIN_PACKETCMD) + { + if (atapi_read_drq(&ide->atapi)) + temp |= DRQ_STAT; + else + temp &= ~DRQ_STAT; + } } else { @@ -1241,31 +910,19 @@ uint16_t readidew(int ide_board) // return 0xFFFF; // pclog("Read IDEw %04X %04X:%04X %02X %i %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins, ide->pos); -//if (idedebug) pclog("Read IDEW %08X\n",PC); - - temp = ide->buffer[ide->pos >> 1]; - #ifdef _RPCEMU_BIG_ENDIAN - temp=(temp>>8)|(temp<<8); - #endif - ide->pos+=2; - if ((ide->command == WIN_PACKETCMD) && ((ide->packetstatus == ATAPI_STATUS_REQ_SENSE) || (ide->packetstatus==8))) - { - callnonreadcd(ide); - return temp; - } - if ((ide->pos>=512 && ide->command != WIN_PACKETCMD) || (ide->command == WIN_PACKETCMD && ide->pos>=ide->packlen)) + if (ide->command == WIN_PACKETCMD) { -// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); - ide->pos=0; - if (ide->command == WIN_PACKETCMD)// && ide.packetstatus==6) - { -// pclog("Call readCD\n"); - callreadcd(ide); - } - else + temp = atapi_data_read(&ide->atapi); + } + else + { + temp = ide->buffer[ide->pos >> 1]; + ide->pos += 2; + if (ide->pos >= 512 && ide->command) { +// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + ide->pos = 0; 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; @@ -1275,9 +932,9 @@ uint16_t readidew(int ide_board) ide->atastat = BUSY_STAT; timer_process(); if (ide->command == WIN_READ_MULTIPLE) - callbackide(ide_board); + callbackide(ide_board); else - idecallback[ide_board]=6*IDE_TIME; + idecallback[ide_board] = 6 * IDE_TIME; timer_update_outstanding(); // pclog("set idecallback\n"); // callbackide(ide_board); @@ -1287,6 +944,9 @@ uint16_t readidew(int ide_board) } } } +#ifdef _RPCEMU_BIG_ENDIAN + temp=(temp>>8)|(temp<<8); +#endif // pclog("Read IDEw %04X\n",temp); return temp; } @@ -1304,6 +964,7 @@ void callbackide(int ide_board) { IDE *ide = &ide_drives[cur_ide[ide_board]]; IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; + atapi_device_t *atapi_dev = &ide->atapi; #if RPCEMU_IDE off64_t addr; int c; @@ -1672,7 +1333,8 @@ void callbackide(int ide_board) case WIN_PIDENTIFY: /* Identify Packet Device */ if (IDE_DRIVE_IS_CDROM(ide)) { // pclog("ATAPI identify\n"); - ide_atapi_identify(ide); + atapi_dev->bus.devices[0]->atapi_identify(ide->buffer, atapi_dev->bus.device_data[0]); + ide->pos=0; ide->error=0; ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1734,77 +1396,9 @@ void callbackide(int ide_board) case WIN_PACKETCMD: /* ATAPI Packet */ if (!IDE_DRIVE_IS_CDROM(ide)) goto abort_cmd; -// pclog("Packet callback! %i %08X\n",ide->packetstatus,ide); - - if (ide->packetstatus == ATAPI_STATUS_IDLE) - { - readcdmode=0; - ide->pos=0; - ide->secount = (uint8_t)((ide->secount&0xF8)|1); - ide->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT); - //ide_irq_raise(ide); -// pclog("1 Preparing to recieve packet max DRQ count %04X\n",ide->cylinder); - } - else if (ide->packetstatus == ATAPI_STATUS_COMMAND) - { - ide->atastat = BUSY_STAT|(ide->atastat&ERR_STAT); -// pclog("Running ATAPI command 2\n"); - atapicommand(ide_board); -// exit(-1); - } - else if (ide->packetstatus == ATAPI_STATUS_COMPLETE) - { -// pclog("packetstatus==2\n"); - ide->atastat = READY_STAT; - ide->secount=3; - ide_irq_raise(ide); -// if (iomd.irqb.mask&2) output=1; - } - else if (ide->packetstatus == ATAPI_STATUS_DATA) - { - ide->atastat = READY_STAT|DRQ_STAT|(ide->atastat&ERR_STAT); -// rpclog("Recieve data packet 3! %02X\n",ide->atastat); - ide_irq_raise(ide); - ide->packetstatus=0xFF; - } - else if (ide->packetstatus == ATAPI_STATUS_PACKET_REQ) - { - ide->atastat = 0x58 | (ide->atastat & ERR_STAT); -// pclog("Send data packet 4!\n"); - ide_irq_raise(ide); -// ide.packetstatus=5; - ide->pos=2; - } - else if (ide->packetstatus == ATAPI_STATUS_PACKET_RECEIVED) - { -// pclog("Packetstatus 5 !\n"); - atapicommand(ide_board); - } - else if (ide->packetstatus == ATAPI_STATUS_READCD) /*READ CD callback*/ - { - ide->atastat = DRQ_STAT|(ide->atastat&ERR_STAT); -// pclog("Recieve data packet 6!\n"); - ide_irq_raise(ide); -// ide.packetstatus=0xFF; - } - else if (ide->packetstatus == ATAPI_STATUS_REQ_SENSE) /*REQUEST SENSE callback #1*/ - { - pclog("REQUEST SENSE callback #1: setting status to 0x5A\n"); - ide->atastat = 0x58 | (ide->atastat & ERR_STAT); - ide_irq_raise(ide); - } - else if (ide->packetstatus == ATAPI_STATUS_ERROR) /*Error callback*/ - { -// pclog("Packet 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("Packet check status\n"); - ide->atastat = ERR_STAT; - ide_irq_raise(ide); - } + + atapi_process_packet(atapi_dev); + return; } @@ -1828,968 +1422,6 @@ void ide_callback_sec() callbackide(1); } -/*ATAPI CD-ROM emulation*/ - -struct -{ - int sensekey,asc,ascq; -} atapi_sense; - -static uint32_t atapi_event_status(IDE *ide, uint8_t *buffer) -{ - uint8_t event_code, media_status = 0; - - if (buffer[5]) - { - media_status = MS_TRAY_OPEN; - atapi->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; - atapi->load(); - } - else if (buffer[4]==2) - { - event_code = MEC_EJECT_REQUESTED; - atapi->eject(); - } - } - - buffer[4] = event_code; - buffer[5] = media_status; - buffer[6] = 0; - buffer[7] = 0; - - return 8; -} - -void atapi_cmd_error(IDE *ide, uint8_t sensekey, uint8_t asc) -{ - ide->error = (sensekey << 4); - ide->atastat = READY_STAT | ERR_STAT; - ide->secount = (ide->secount & ~7) | 3; - ide->packetstatus = 0x80; - idecallback[ide->board]=50*IDE_TIME; -} - -uint8_t atapi_prev; -int toctimes=0; - -void atapi_insert_cdrom() -{ - atapi_sense.sensekey=SENSE_UNIT_ATTENTION; - atapi_sense.asc=ASC_MEDIUM_MAY_HAVE_CHANGED; - atapi_sense.ascq=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)) - { - pclog("Odd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%04x\n", ide->cylinder, command, ide->cylinder - 1); - ide->cylinder--; - } - - if (alloc_length < 0) - fatal("Allocation length < 0\n"); - if (alloc_length == 0) - alloc_length = ide->cylinder; - - // Status: 0x80 (busy), 0x08 (drq), 0x01 (err) - // Interrupt: 0x02 (i_o), 0x01 (c_d) - /* No atastat setting: PCem actually emulates the callback cycle. */ - 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; - - //pclog("atapi_command_send_init(ide, %02X, %04X, %04X)\n", command, req_length, alloc_length); - //pclog("IDE settings: Pos=%08X, Secount=%08X, Cylinder=%08X\n", ide->pos, ide->secount, ide->cylinder); -} - -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 ((atapi_sense.sensekey == SENSE_UNIT_ATTENTION) || ignore_ua) - { - atapi_prev=command; - atapi_sense.sensekey=0; - atapi_sense.asc=0; - atapi_sense.ascq=0; - } -} - -int cd_status = CD_STATUS_EMPTY; -int prev_status; - -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; - int is_error; - 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; - -#ifndef RPCEMU_IDE - pclog("New ATAPI command %02X %i\n",idebufferb[0],ins); -#endif -// readflash_set(READFLASH_HDD, ide->drive, 1); - msf=idebufferb[1]&2; - ide->cdlen=0; - - is_error = 0; - - if (atapi->medium_changed()) - { - atapi_insert_cdrom(); - } - /*If UNIT_ATTENTION is set, error out with NOT_READY. - VIDE-CDD.SYS will then issue a READ_TOC, which can pass through UNIT_ATTENTION and will clear sense. - NT 3.1 / AZTIDECD.SYS will then issue a REQUEST_SENSE, which can also pass through UNIT_ATTENTION but will clear sense AFTER sending it back. - In any case, if the command cannot pass through, set our state to errored.*/ - if (!(atapi_cmd_table[idebufferb[0]] & ALLOW_UA) && atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - { - atapi_cmd_error(ide, atapi_sense.sensekey, atapi_sense.asc); - is_error = 1; - } - /*Unless the command issued was a REQUEST_SENSE or TEST_UNIT_READY, clear sense. - This is important because both VIDE-CDD.SYS and NT 3.1 / AZTIDECD.SYS rely on this behaving VERY specifically. - VIDE-CDD.SYS will clear sense through READ_TOC, while NT 3.1 / AZTIDECD.SYS will issue a REQUEST_SENSE.*/ - if ((idebufferb[0]!=GPCMD_REQUEST_SENSE) && (idebufferb[0]!=GPCMD_TEST_UNIT_READY)) - { - /* GPCMD_TEST_UNIT_READY is NOT supposed to clear sense! */ - atapi_sense_clear(idebufferb[0], 1); - } - - /*If our state has been set to errored, clear it, and return.*/ - if (is_error) - { - is_error = 0; - return; - } - - if ((atapi_cmd_table[idebufferb[0]] & CHECK_READY) && !atapi->ready()) - { - atapi_cmd_error(ide, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); - atapi_sense.sensekey = SENSE_NOT_READY; - atapi_sense.asc = ASC_MEDIUM_NOT_PRESENT; - atapi_sense.ascq = 0; - return; - } - - prev_status = cd_status; - cd_status = atapi->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]; - atapi_command_send_init(ide, temp_command, 18, alloc_length); - - /*Will return 18 bytes of 0*/ - memset(idebufferb,0,512); - - idebufferb[0]=0x80|0x70; - - if ((atapi_sense.sensekey > 0) || (cd_status < CD_STATUS_PLAYING)) - { - if (completed) - { - idebufferb[2]=SENSE_ILLEGAL_REQUEST; - idebufferb[12]=ASC_AUDIO_PLAY_OPERATION; - idebufferb[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } - else - { - idebufferb[2]=atapi_sense.sensekey; - idebufferb[12]=atapi_sense.asc; - idebufferb[13]=atapi_sense.ascq; - } - } - else - { - 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; - } - - idebufferb[7]=10; - - // pclog("REQUEST SENSE start\n"); - atapi_command_ready(ide_board, 18); - - /* Clear the sense stuff as per the spec. */ - atapi_sense_clear(temp_command, 0); - break; - - case GPCMD_SET_SPEED: - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_MECHANISM_STATUS: /*0xbd*/ - alloc_length = (idebufferb[7]<<16)|(idebufferb[8]<<8)|idebufferb[9]; - - if (alloc_length == 0) - fatal("Zero allocation length to MECHANISM STATUS not impl.\n"); - - atapi_command_send_init(ide, idebufferb[0], 8, alloc_length); - - idebufferb[0] = 0; - idebufferb[1] = 0; - idebufferb[2] = 0; - idebufferb[3] = 0; - idebufferb[4] = 0; - idebufferb[5] = 1; - idebufferb[6] = 0; - idebufferb[7] = 0; - // len = 8; - - atapi_command_ready(ide_board, 8); - break; - - case GPCMD_READ_TOC_PMA_ATIP: -// pclog("Read TOC ready? %08X\n",ide); - toctimes++; -// if (toctimes==2) output=3; -// pclog("Read TOC %02X\n",idebufferb[9]); - toc_format = idebufferb[2] & 0xf; - if (toc_format == 0) - toc_format = (idebufferb[9]>>6) & 3; - switch (toc_format) - { - case 0: /*Normal*/ - // pclog("ATAPI: READ TOC type requested: Normal\n"); - len=idebufferb[8]+(idebufferb[7]<<8); - len=atapi->readtoc(idebufferb,idebufferb[6],msf,len,0); - break; - case 1: /*Multi session*/ - // pclog("ATAPI: READ TOC type requested: Multi-session\n"); - len=idebufferb[8]+(idebufferb[7]<<8); - len=atapi->readtoc_session(idebufferb,msf,len); - idebufferb[0]=0; idebufferb[1]=0xA; - break; - case 2: /*Raw*/ - // pclog("ATAPI: READ TOC type requested: Raw TOC\n"); - len=idebufferb[8]+(idebufferb[7]<<8); - len=atapi->readtoc_raw(idebufferb,len); - break; - default: - // pclog("ATAPI: Unknown READ TOC type requested: %i\n", (idebufferb[9]>>6)); - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - ide->error |= MCR_ERR; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - return; -/* pclog("Bad read TOC format\n"); - pclog("Packet data :\n"); - for (c=0;c<12;c++) - pclog("%02X ",idebufferb[c]); - pclog("\n"); - exit(-1);*/ - } -// pclog("ATAPI buffer len %i\n",len); - ide->packetstatus = ATAPI_STATUS_DATA; - ide->cylinder=len; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=len; - return; - - case GPCMD_READ_CD: -// 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]); - rcdmode = idebufferb[9] & 0xF8; - if ((rcdmode != 0x10) && (rcdmode != 0xF8)) - { - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - ide->error |= MCR_ERR; - atapi_sense.asc = ASC_ILLEGAL_OPCODE; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - break; -// pclog("Bad flags bits %02X\n",idebufferb[9]); -// exit(-1); - } -/* if (idebufferb[6] || idebufferb[7] || (idebufferb[8]!=1)) - { - pclog("More than 1 sector!\n"); - exit(-1); - }*/ - ide->cdlen=(idebufferb[6]<<16)|(idebufferb[7]<<8)|idebufferb[8]; - ide->cdpos=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; -// pclog("Read at %08X %08X\n",ide.cdpos,ide.cdpos*2048); - if (rcdmode == 0x10) - atapi->readsector(idebufferb,ide->cdpos); - else - atapi->readsector_raw(idebufferb,ide->cdpos); -#ifndef RPCEMU_IDE - readflash_set(READFLASH_HDC, ide->drive); -#endif - readcdmode = (rcdmode == 0xF8); - ide->cdpos++; - ide->cdlen--; - if (ide->cdlen >= 0) - ide->packetstatus = ATAPI_STATUS_READCD; - else - ide->packetstatus = ATAPI_STATUS_DATA; - ide->cylinder=(idebufferb[9] == 0x10) ? 2048 : 2352; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=(idebufferb[9] == 0x10) ? 2048 : 2352; - 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]); - - readcdmode = 0; - - if (idebufferb[0] == GPCMD_READ_6) - { - ide->cdlen=idebufferb[4]; - ide->cdpos=((((uint32_t) idebufferb[1]) & 0x1f)<<16)|(((uint32_t) idebufferb[2])<<8)|((uint32_t) idebufferb[3]); - } - else if (idebufferb[0] == GPCMD_READ_10) - { - ide->cdlen=(idebufferb[7]<<8)|idebufferb[8]; - ide->cdpos=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - } - else - { - ide->cdlen=(((uint32_t) idebufferb[6])<<24)|(((uint32_t) idebufferb[7])<<16)|(((uint32_t) idebufferb[8])<<8)|((uint32_t) idebufferb[9]); - ide->cdpos=(((uint32_t) idebufferb[2])<<24)|(((uint32_t) idebufferb[3])<<16)|(((uint32_t) idebufferb[4])<<8)|((uint32_t) idebufferb[5]); - } - if (!ide->cdlen) - { -// pclog("All done - callback set\n"); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=20*IDE_TIME; - break; - } - - if (atapi->readsector(idebufferb,ide->cdpos)) - { -// pclog("Read sector failed\n"); - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_LBA_OUT_OF_RANGE; - atapi_sense.ascq = 0; - - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - { - ide->error |= MCR_ERR; - } - atapi_sense.asc = ASC_ILLEGAL_OPCODE; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - break; - } -#ifndef RPCEMU_IDE - readflash_set(READFLASH_HDC, ide->drive); -#endif - ide->cdpos++; - ide->cdlen--; - if (ide->cdlen >= 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 (msf) - { - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - { - ide->error |= MCR_ERR; - } - atapi_sense.asc = ASC_ILLEGAL_OPCODE; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - break; -// pclog("Read Header MSF!\n"); -// exit(-1); - } - for (c=0;c<4;c++) idebufferb[c+4]=idebufferb[c+2]; - idebufferb[0]=1; /*2048 bytes user data*/ - idebufferb[1]=idebufferb[2]=idebufferb[3]=0; - - 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; - // for (c=0;catastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - idecallback[ide_board]=50*IDE_TIME; - atapi_cmd_error(ide, atapi_sense.sensekey, atapi_sense.asc); - ide->atastat = 0x53; - ide->packetstatus = ATAPI_STATUS_ERROR; - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_INV_FIELD_IN_CMD_PACKET; - atapi_sense.ascq = 0; - return; - } - - if (temp_command == GPCMD_MODE_SENSE_6) - { - len = ide_atapi_mode_sense(ide,4,temp); - idebufferb[0] = len - 1; - idebufferb[1]=3; /*120mm data CD-ROM*/ - } - else - { - len = ide_atapi_mode_sense(ide,8,temp); - 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); - 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; - // pclog("Length - %02X%02X\n",idebufferb[0],idebufferb[1]); -// pclog("Page %02X length %02X\n",idebufferb[8],idebufferb[9]); - } - 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[GPMODE_CDROM_AUDIO_PAGE] |= 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; -/* pclog("Waiting for ARM to send packet %i\n",len); - pclog("Packet data :\n"); - for (c=0;c<12;c++) - pclog("%02X ",idebufferb[c]); - pclog("\n");*/ - } - return; - - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: /*0x4a*/ - temp_command = idebufferb[0]; - alloc_length = (idebufferb[7]<<16)|(idebufferb[8]<<8)|idebufferb[9]; - - { - 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; - - struct __attribute__((__packed__)) - { - uint16_t len; - uint8_t notification_class; - uint8_t supported_events; - } *gesn_event_header; - unsigned int used_len; - - 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 pollign is supported, asynchronous mode is not. */ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - idecallback[ide_board]=50*IDE_TIME; - atapi_cmd_error(ide, atapi_sense.sensekey, atapi_sense.asc); - ide->atastat = 0x53; - ide->packetstatus=0x80; - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_INV_FIELD_IN_CMD_PACKET; - atapi_sense.ascq = 0; - 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 = atapi_event_status(ide, idebufferb); - } - else - { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - len = used_len; - gesn_event_header->len = used_len - sizeof(*gesn_event_header); - } - - atapi_command_send_init(ide, temp_command, len, alloc_length); - - atapi_command_ready(ide_board, len); - break; - - case GPCMD_READ_DISC_INFORMATION: - idebufferb[1] = 32; - idebufferb[2] = 0xe; /* last session complete, disc finalized */ - idebufferb[3] = 1; /* first track on disc */ - idebufferb[4] = 1; /* # of sessions */ - idebufferb[5] = 1; /* first track of last session */ - idebufferb[6] = 1; /* last track of last session */ - idebufferb[7] = 0x20; /* unrestricted use */ - idebufferb[8] = 0x00; /* CD-ROM */ - - len=34; - 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: - /*This is apparently deprecated in the ATAPI spec, and apparently - has been since 1995 (!). Hence I'm having to guess most of it*/ - 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) - { - 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) || (cd_status <= CD_STATUS_DATA_ONLY) || - !atapi->is_track_audio(pos, (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) - { - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - atapi_sense.ascq = 0; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - atapi_cmd_error(ide, atapi_sense.sensekey, atapi_sense.asc); - break; - } - - atapi->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: - temp=idebufferb[2]&0x40; - if (idebufferb[3]!=1) - { -// pclog("Read subchannel check condition %02X\n",idebufferb[3]); - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - ide->error |= MCR_ERR; - // ide->discchanged=1; /* Fixes some bugs with NT 3.1. */ - atapi_sense.asc = ASC_ILLEGAL_OPCODE; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - break; -/* pclog("Bad read subchannel!\n"); - pclog("Packet data :\n"); - for (c=0;c<12;c++) - pclog("%02X\n",idebufferb[c]); - dumpregs(); - exit(-1);*/ - } - pos=0; - idebufferb[pos++]=0; - idebufferb[pos++]=0; /*Audio status*/ - idebufferb[pos++]=0; idebufferb[pos++]=0; /*Subchannel length*/ - idebufferb[pos++]=1; /*Format code*/ - idebufferb[1]=atapi->getcurrentsubchannel(&idebufferb[5],msf); -// pclog("Read subchannel complete - audio status %02X\n",idebufferb[1]); - len=11+5; - if (!temp) len=4; - 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_START_STOP_UNIT: - if (idebufferb[4]!=2 && idebufferb[4]!=3 && idebufferb[4]) - { - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - ide->error |= MCR_ERR; - atapi_sense.asc = ASC_ILLEGAL_OPCODE; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - break; -/* pclog("Bad start/stop unit command\n"); - pclog("Packet data :\n"); - for (c=0;c<12;c++) - pclog("%02X\n",idebufferb[c]); - exit(-1);*/ - } - if (!idebufferb[4]) atapi->stop(); - else if (idebufferb[4]==2) atapi->eject(); - else atapi->load(); - 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_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_DATA_PHASE_ERROR); - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_DATA_PHASE_ERROR; - 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, "PCem"); /* Vendor */ - idx += 8; - ide_padstr8(idebufferb + idx, 40, "PCemCD v1.0"); /* Product */ - idx += 40; - ide_padstr8(idebufferb + idx, 20, "53R141"); /* Product */ - idx += 20; - - break; - default: - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET); - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_INV_FIELD_IN_CMD_PACKET; - return; - } - } - else - { - preamble_len = 5; - size_idx = 4; - - idebufferb[0] = 5; /*CD-ROM*/ - idebufferb[1] = 0x80; /*Removable*/ - idebufferb[2] = 0; - idebufferb[3] = 0x21; - idebufferb[4] = 31; - idebufferb[5] = 0; - idebufferb[6] = 0; - idebufferb[7] = 0; -#ifdef RPCEMU_IDE - ide_padstr8(idebufferb + 8, 8, "RPCemu"); /* Vendor */ - ide_padstr8(idebufferb + 16, 16, "RPCemuCD"); /* Product */ -#else - ide_padstr8(idebufferb + 8, 8, "PCem"); /* Vendor */ - ide_padstr8(idebufferb + 16, 16, "PCemCD"); /* Product */ -#endif - ide_padstr8(idebufferb + 32, 4, "1.0"); /* Revision */ - - idx = 36; - } - -atapi_out: - idebufferb[size_idx] = idx - preamble_len; - len=idx; - - 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) atapi->resume(); - else atapi->pause(); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_SEEK: - pos=(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - atapi->seek(pos); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_READ_CDROM_CAPACITY: - atapi_command_send_init(ide, 0, 8, 8); - size = atapi->size(); - idebufferb[0] = (size >> 24) & 0xff; - idebufferb[1] = (size >> 16) & 0xff; - idebufferb[2] = (size >> 8) & 0xff; - idebufferb[3] = size & 0xff; - idebufferb[4] = (2048 >> 24) & 0xff; - idebufferb[5] = (2048 >> 16) & 0xff; - idebufferb[6] = (2048 >> 8) & 0xff; - idebufferb[7] = 2048 & 0xff; - len=8; - atapi_command_ready(ide_board, len); - break; - - case GPCMD_SEND_DVD_STRUCTURE: - default: - ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ - ide->error = (SENSE_ILLEGAL_REQUEST << 4) | ABRT_ERR; - if (atapi_sense.sensekey == SENSE_UNIT_ATTENTION) - ide->error |= MCR_ERR; - atapi_sense.sensekey = SENSE_ILLEGAL_REQUEST; - atapi_sense.asc = ASC_ILLEGAL_OPCODE; - ide->packetstatus = ATAPI_STATUS_ERROR; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_STOP_PLAY_SCAN: - atapi->stop(); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; -/* default: - pclog("Bad ATAPI command %02X\n",idebufferb[0]); - pclog("Packet data :\n"); - for (c=0;c<12;c++) - pclog("%02X\n",idebufferb[c]); - exit(-1);*/ - } -} - -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) -{ - ide_irq_lower(ide); - if (ide->cdlen<=0) - { -// pclog("All done - callback set\n"); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide->board]=20*IDE_TIME; - ide->atastat = BUSY_STAT; - return; - } -// pclog("Continue readcd! %i blocks left\n",ide->cdlen); - ide->atastat = BUSY_STAT; - - if (readcdmode) - atapi->readsector_raw((uint8_t *) ide->buffer, ide->cdpos); - else - atapi->readsector((uint8_t *) ide->buffer, ide->cdpos); -#ifndef RPCEMU_IDE - readflash_set(READFLASH_HDC, ide->drive); -#endif - ide->cdpos++; - ide->cdlen--; - ide->packetstatus = ATAPI_STATUS_READCD; - ide->cylinder=readcdmode ? 2352 : 2048; - ide->secount=2; - ide->pos=0; - idecallback[ide->board]=60*IDE_TIME; - ide->packlen=readcdmode ? 2352 : 2048; -} - void ide_write_pri(uint16_t addr, uint8_t val, void *priv) diff --git a/src/ide.h b/src/ide.h index fc7936b..ea16483 100644 --- a/src/ide.h +++ b/src/ide.h @@ -16,6 +16,7 @@ extern void ide_sec_enable(); extern void ide_pri_disable(); extern void ide_sec_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)); +void ide_irq_raise(struct IDE *ide); #include "ide_atapi.h" @@ -34,4 +35,16 @@ uint32_t atapi_get_cd_volume(int channel); extern device_t ide_device; +/* Bits of 'atastat' */ +#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 */ + #endif //__IDE__ diff --git a/src/ide_atapi.c b/src/ide_atapi.c new file mode 100644 index 0000000..1faa977 --- /dev/null +++ b/src/ide_atapi.c @@ -0,0 +1,469 @@ +#include "ibm.h" +#include "ide.h" +#include "ide_atapi.h" +#include "scsi.h" +#include "timer.h" + +#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) + +#define ATAPI_STATE_IDLE 0 +#define ATAPI_STATE_COMMAND 1 +#define ATAPI_STATE_GOT_COMMAND 2 +#define ATAPI_STATE_NEXT_PHASE 3 +#define ATAPI_STATE_READ_STATUS 4 +#define ATAPI_STATE_READ_MESSAGE 5 +#define ATAPI_STATE_END_PHASE 6 +#define ATAPI_STATE_READ_DATA 7 +#define ATAPI_STATE_READ_DATA_WAIT 8 +#define ATAPI_STATE_WRITE_DATA 9 +#define ATAPI_STATE_WRITE_DATA_WAIT 10 + +ATAPI *atapi; + +void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val) +{ + switch (atapi_dev->state) + { + case ATAPI_STATE_COMMAND: + atapi_dev->command[atapi_dev->command_pos++] = val & 0xff; + atapi_dev->command[atapi_dev->command_pos++] = val >> 8; + if (atapi_dev->command_pos >= 12) + { + atapi_dev->state = ATAPI_STATE_GOT_COMMAND; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + + case ATAPI_STATE_WRITE_DATA_WAIT: + atapi_dev->data[atapi_dev->data_write_pos++] = val & 0xff; + atapi_dev->data[atapi_dev->data_write_pos++] = val >> 8; +// pclog("Write ATAPI data %i %i %i\n", atapi_dev->data_write_pos, atapi_dev->data_read_pos, idecallback[atapi_dev->board]); + if (atapi_dev->data_write_pos >= atapi_dev->data_read_pos) + { + atapi_dev->bus_state = 0; + atapi_dev->state = ATAPI_STATE_WRITE_DATA; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + } +} + +uint16_t atapi_data_read(atapi_device_t *atapi_dev) +{ + uint16_t temp = 0xffff; + + switch (atapi_dev->state) + { + case ATAPI_STATE_READ_DATA_WAIT: + if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) + { +// pclog("ATAPI_STATE_READ_DATA_WAIT - out of data!\n"); + break; + } + + temp = atapi_dev->data[atapi_dev->data_read_pos++]; + if (atapi_dev->data_read_pos < atapi_dev->data_write_pos) + temp |= (atapi_dev->data[atapi_dev->data_read_pos++] << 8); +// pclog("Read data %04x\n", temp); + if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) + { + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + idecallback[atapi_dev->board] = 6*IDE_TIME; + } + break; + } + + return temp; +} + +static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) +{ + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(bus); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) + { + if (!req_needed || (bus_state & BUS_REQ)) + return 1; + } + } + + return 0; +} + +void atapi_command_start(atapi_device_t *atapi) +{ + scsi_bus_t *bus = &atapi->bus; + + scsi_bus_update(bus, BUS_SEL | BUS_SETDATA(1 << 0)); + if (!(scsi_bus_read(bus) & BUS_BSY)) + fatal("STATE_SCSI_SELECT failed to select target\n"); + + scsi_bus_update(bus, 0); + if (!(scsi_bus_read(bus) & BUS_BSY)) + fatal("STATE_SCSI_SELECT failed to select target 2\n"); + + /*Device should now be selected*/ + if (!wait_for_bus(bus, BUS_CD, 1)) + fatal("Device failed to request command\n"); + + atapi->state = ATAPI_STATE_COMMAND; + atapi->command_pos = 0; +} + +uint8_t atapi_read_iir(atapi_device_t *atapi_dev) +{ + uint8_t val = 0; + int bus_status = atapi_dev->bus_state;//scsi_bus_read(&atapi_dev->bus); + + if (bus_status & BUS_CD) + val |= 1; + if (bus_status & BUS_IO) + val |= 2; + +// pclog("Read IIR %02X %02x\n", val, bus_status); + + return val; +} + +uint8_t atapi_read_drq(atapi_device_t *atapi_dev) +{ + return atapi_dev->bus_state & BUS_REQ; +} + +void atapi_process_packet(atapi_device_t *atapi_dev) +{ +// pclog("atapi_process_packet: state=%i\n", atapi_dev->state); + switch (atapi_dev->state) + { + case ATAPI_STATE_COMMAND: + *atapi_dev->atastat = READY_STAT | (*atapi_dev->atastat & ERR_STAT); + atapi_dev->max_transfer_len = *atapi_dev->cylinder; + atapi_dev->bus_state = BUS_CD | BUS_REQ; + break; + + case ATAPI_STATE_GOT_COMMAND: + { + int pos = 0; + int bus_state; + int c; + + for (c = 0; c < 20; c++) + { + bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + fatal("SEND_COMMAND - bus phase incorrect\n"); + if (bus_state & BUS_REQ) + break; + } + if (c == 20) + fatal("SEND_COMMAND timed out\n"); + + while (1) + { + int bus_out; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + break; + if (bus_state & BUS_REQ) + break; + } + if (c == 20) + { +// pclog("SEND_COMMAND timed out %x\n", scsi_bus_read(&atapi_dev->bus)); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + break; + } + + bus_state = scsi_bus_read(&atapi_dev->bus); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG | BUS_REQ)) != (BUS_CD | BUS_REQ)) + { +// pclog("SEND_COMMAND - bus state changed %x\n", bus_state); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + break; + } + + if (pos >= atapi_dev->command_pos) + bus_out = BUS_SETDATA(0); /*Pad out with zeroes*/ + else + bus_out = BUS_SETDATA(atapi_dev->command[pos++]); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + +// if (pos >= atapi_dev->command_pos) +// fatal("Out of data!\n"); + } + } + break; + + case ATAPI_STATE_NEXT_PHASE: + { + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + +// if (!c) +// pclog("NEXT_PHASE - %x\n", bus_state); + if (!(bus_state & BUS_BSY)) + fatal("NEXT_PHASE - dropped BSY waiting\n"); + + if (bus_state & BUS_REQ) + { + scsi_device_t *scsi_dev = atapi_dev->bus.devices[0]; + void *scsi_data = atapi_dev->bus.device_data[0]; + + switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) + { + case 0: + atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT; + + atapi_dev->data_read_pos = scsi_dev->get_bytes_required(scsi_data); + if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len) + atapi_dev->data_read_pos = atapi_dev->max_transfer_len; + + atapi_dev->data_write_pos = 0; + *atapi_dev->cylinder = atapi_dev->data_read_pos; + +// pclog("WRITE_DATA: bytes=%i\n", *atapi_dev->cylinder); + *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); + atapi_dev->bus_state = BUS_REQ; + ide_irq_raise(atapi_dev->ide); + break; + + case BUS_IO: + atapi_dev->state = ATAPI_STATE_READ_DATA; + atapi_dev->data_read_pos = atapi_dev->data_write_pos = 0; + break; + + case (BUS_IO | BUS_CD): + atapi_dev->state = ATAPI_STATE_READ_STATUS; + break; + + case (BUS_CD | BUS_IO | BUS_MSG): + atapi_dev->state = ATAPI_STATE_READ_MESSAGE; + break; + + default: + fatal("NEXT_PHASE - bus state changed %x\n", bus_state); + } + break; + } + } + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + + case ATAPI_STATE_READ_STATUS: + { + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + fatal("READ_STATUS - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) + fatal("READ_STATUS - changed phase\n"); + + if (bus_state & BUS_REQ) + { +// uint8_t status = BUS_GETDATA(bus_state); + int bus_out = 0; + +// pclog("Read status %02x\n", status); + + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + break; + } + } + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + + case ATAPI_STATE_READ_MESSAGE: + { + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + fatal("READ_MESSAGE - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) + { +// pclog("READ_MESSAGE - changed phase\n"); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t msg = BUS_GETDATA(bus_state); + int bus_out = 0; + +// pclog("Read message %02x\n", msg); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + + switch (msg) + { + case MSG_COMMAND_COMPLETE: + atapi_dev->state = ATAPI_STATE_END_PHASE; + break; + + default: + fatal("READ_MESSAGE - unknown message %02x\n", msg); + } + break; + } + } + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + + case ATAPI_STATE_READ_DATA: + { + while (atapi_dev->data_write_pos < atapi_dev->max_transfer_len) + { + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + fatal("READ_DATA - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) + { +// pclog("READ_DATA - changed phase\n"); + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t data = BUS_GETDATA(bus_state); + int bus_out = 0; + + atapi_dev->data[atapi_dev->data_write_pos++] = data; + +// pclog("Read data %02x %i\n", data, atapi_dev->data_write_pos); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + break; + } + } + if ((scsi_bus_read(&atapi_dev->bus) & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) + break; + } + atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT; + *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); + *atapi_dev->cylinder = atapi_dev->data_write_pos; +// pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder); + atapi_dev->bus_state = BUS_IO | BUS_REQ; + ide_irq_raise(atapi_dev->ide); + } + break; + + case ATAPI_STATE_WRITE_DATA: + { + atapi_dev->data_read_pos = 0; +// pclog("ATAPI_STATE_WRITE_DATA - %i\n", atapi_dev->data_write_pos); + while (atapi_dev->data_read_pos < atapi_dev->data_write_pos) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + fatal("WRITE_DATA - dropped BSY waiting\n"); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) + { +// pclog("WRITE_DATA - changed phase\n"); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t data = atapi_dev->data[atapi_dev->data_read_pos++]; + int bus_out; + +// pclog("Write data %02x %i\n", data, atapi_dev->data_read_pos-1); + bus_out = BUS_SETDATA(data); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + } + } + + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + + case ATAPI_STATE_END_PHASE: + { + int c; + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&atapi_dev->bus); + + if (!(bus_state & BUS_BSY)) + { +// pclog("END_PHASE - dropped BSY waiting\n"); + atapi_dev->state = ATAPI_STATE_IDLE; + break; + } + + if (bus_state & BUS_REQ) + fatal("END_PHASE - unexpected REQ\n"); + } + if (atapi_dev->state == ATAPI_STATE_IDLE) + { + scsi_device_t *scsi_dev = atapi_dev->bus.devices[0]; + void *scsi_data = atapi_dev->bus.device_data[0]; + + *atapi_dev->atastat = READY_STAT; + atapi_dev->bus_state = BUS_IO | BUS_CD; + if (scsi_dev->get_status(scsi_data) != STATUS_GOOD) + { + *atapi_dev->error = (scsi_dev->get_sense_key(scsi_data) << 4) | ABRT_ERR; + if (scsi_dev->get_sense_key(scsi_data) == KEY_UNIT_ATTENTION) + *atapi_dev->error |= MCR_ERR; + *atapi_dev->atastat |= ERR_STAT; + } + ide_irq_raise(atapi_dev->ide); + } + else + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + break; + } +} diff --git a/src/ide_atapi.h b/src/ide_atapi.h index 5530f1c..43ca829 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -1,6 +1,8 @@ #ifndef __IDE_ATAPI__ #define __IDE_ATAPI__ +#include "scsi.h" + /*ATAPI stuff*/ typedef struct ATAPI { @@ -28,6 +30,36 @@ typedef struct ATAPI extern ATAPI *atapi; void atapi_discchanged(); -void atapi_insert_cdrom(); + +typedef struct atapi_device_t +{ + scsi_bus_t bus; + + uint8_t command[12]; + int command_pos; + + int state; + + int max_transfer_len; + + uint8_t data[65536]; + int data_read_pos, data_write_pos; + + int bus_state; + + struct IDE *ide; + + int board; + uint8_t *atastat; + uint8_t *error; + int *cylinder; +} atapi_device_t; + +void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val); +uint16_t atapi_data_read(atapi_device_t *atapi_dev); +void atapi_command_start(atapi_device_t *atapi); +uint8_t atapi_read_iir(atapi_device_t *atapi_dev); +uint8_t atapi_read_drq(atapi_device_t *atapi_dev); +void atapi_process_packet(atapi_device_t *atapi_dev); #endif diff --git a/src/scsi.c b/src/scsi.c index b703700..c87456f 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -101,7 +101,7 @@ int scsi_bus_update(scsi_bus_t *bus, int bus_assert) bus->new_state = bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG); bus->bus_out &= ~BUS_REQ; - if (cmd_len[bus->command[0] >> 5] == bus->command_pos) + if (bus->command_pos == (bus->is_atapi ? 12 : cmd_len[bus->command[0] >> 5])) { int new_state; @@ -322,6 +322,19 @@ void scsi_bus_kick(scsi_bus_t *bus) scsi_bus_update(bus, 0); } +void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id) +{ + memset(bus->devices, 0, sizeof(bus->devices)); + memset(bus->device_data, 0, sizeof(bus->device_data)); + + bus->devices[0] = device; + bus->device_data[0] = bus->devices[0]->atapi_init(bus, id); + if (!bus->device_data[0]) + bus->devices[0] = NULL; + + bus->is_atapi = 1; +} + void scsi_bus_init(scsi_bus_t *bus) { int c; @@ -331,21 +344,17 @@ void scsi_bus_init(scsi_bus_t *bus) for (c = 0; c < 4; c++) { - if (cdrom_channel != c) - { - bus->devices[c] = &scsi_hd; - bus->device_data[c] = bus->devices[c]->init(bus, c); - if (!bus->device_data[c]) - bus->devices[c] = NULL; - } - else - { + if (cdrom_channel == c) bus->devices[c] = &scsi_cd; - bus->device_data[c] = bus->devices[c]->init(bus, c); - if (!bus->device_data[c]) - bus->devices[c] = NULL; - } + else + bus->devices[c] = &scsi_hd; + + bus->device_data[c] = bus->devices[c]->init(bus, c); + if (!bus->device_data[c]) + bus->devices[c] = NULL; } + + bus->is_atapi = 0; } void scsi_bus_close(scsi_bus_t *bus) diff --git a/src/scsi.h b/src/scsi.h index 75ade74..e824639 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -1,14 +1,22 @@ +#ifndef _SCSI_H_ +#define _SCSI_H_ + struct scsi_bus_t; typedef struct scsi_device_t { void *(*init)(struct scsi_bus_t *bus, int id); + void *(*atapi_init)(struct scsi_bus_t *bus, int id); void (*close)(void *p); void (*start_command)(void *p); int (*command)(uint8_t *cdb, void *p); uint8_t (*get_status)(void *p); + uint8_t (*get_sense_key)(void *p); + int (*get_bytes_required)(void *p); + + void (*atapi_identify)(uint16_t *buffer, void *p); uint8_t (*read)(void *p); void (*write)(uint8_t val, void *p); @@ -34,6 +42,8 @@ typedef struct scsi_bus_t int change_state_delay; int new_req_delay; + + int is_atapi; } scsi_bus_t; //int scsi_add_data(uint8_t val); @@ -59,6 +69,7 @@ void scsi_set_irq(uint8_t status); #define SCSI_SEEK_10 0x2b #define SCSI_VERIFY_10 0x2f #define SCSI_READ_BUFFER 0x3c +#define SCSI_MODE_SENSE_10 0x5a #define SCSI_RESERVE 0x16 #define SCSI_RELEASE 0x17 @@ -92,10 +103,25 @@ int scsi_bus_match(scsi_bus_t *bus, int bus_assert); void scsi_bus_kick(scsi_bus_t *bus); void scsi_bus_init(scsi_bus_t *bus); void scsi_bus_close(scsi_bus_t *bus); +void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id); -#define KEY_ILLEGAL_REQ 5 +#define KEY_NONE 0 +#define KEY_NOT_READY 2 +#define KEY_ILLEGAL_REQ 5 +#define KEY_UNIT_ATTENTION 6 +#define KEY_DATA_PROTECT 7 + +#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_INVALID_LUN 0x25 +#define ASC_WRITE_PROTECT 0x27 +#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 +#define ASC_MEDIUM_NOT_PRESENT 0x3a +#define ASC_DATA_PHASE_ERROR 0x4b +#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 -#define ASC_INVALID_LUN 0x25 #define SCSI_PHASE_DATA_OUT 0 #define SCSI_PHASE_DATA_IN BUS_IO @@ -103,3 +129,8 @@ void scsi_bus_close(scsi_bus_t *bus); #define SCSI_PHASE_STATUS (BUS_CD | BUS_IO) #define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD) #define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO) + +#define START_STOP_START 0x01 +#define START_STOP_LOEJ 0x02 + +#endif /*_SCSI_H_*/ diff --git a/src/scsi_cd.c b/src/scsi_cd.c index fb32c01..3ba4b60 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -65,16 +65,6 @@ enum #define SENSE_ILLEGAL_REQUEST 5 #define SENSE_UNIT_ATTENTION 6 -/* ATAPI 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_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_MEDIUM_NOT_PRESENT 0x3a -#define ASC_DATA_PHASE_ERROR 0x4b -#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 - #define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 #define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 #define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 @@ -202,6 +192,7 @@ typedef struct scsi_cd_data_t uint8_t prefix_len; uint8_t page_current; + int is_atapi; } scsi_cd_data_t; static void scsi_add_data(scsi_cd_data_t *data, uint8_t val) @@ -292,6 +283,15 @@ static void *scsi_cd_init(scsi_bus_t *bus, int id) return data; } +static void *scsi_cd_atapi_init(scsi_bus_t *bus, int id) +{ + scsi_cd_data_t *data = scsi_cd_init(bus, id); + + data->is_atapi = 1; + + return data; +} + static void scsi_cd_close(void *p) { scsi_cd_data_t *data = p; @@ -397,6 +397,15 @@ static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t return pos; } +uint32_t atapi_get_cd_channel(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 atapi_get_cd_volume(int channel) +{ + return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 9 : 7] : 0xFF; +} static int scsi_cd_command(uint8_t *cdb, void *p) { scsi_cd_data_t *data = p; @@ -417,6 +426,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) int temp_command; int alloc_length; int completed; + int changed; if (!data->received_cdb) memcpy(data->cdb, cdb, CDB_MAX_LEN); @@ -433,11 +443,8 @@ static int scsi_cd_command(uint8_t *cdb, void *p) msf = cdb[1] & 2; is_error = 0; + changed = atapi->medium_changed(); - if (atapi->medium_changed()) - { - atapi_insert_cdrom(); - } /*If UNIT_ATTENTION is set, error out with NOT_READY. VIDE-CDD.SYS will then issue a READ_TOC, which can pass through UNIT_ATTENTION and will clear sense. NT 3.1 / AZTIDECD.SYS will then issue a REQUEST_SENSE, which can also pass through UNIT_ATTENTION but will clear sense AFTER sending it back. @@ -469,7 +476,13 @@ static int scsi_cd_command(uint8_t *cdb, void *p) atapi_cmd_error(data, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); return SCSI_PHASE_STATUS; } - + if ((atapi_cmd_table[cdb[0]] & CHECK_READY) && changed) + { + pclog("Medium changed\n"); + atapi_cmd_error(data, SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); + return SCSI_PHASE_STATUS; + } + data->prev_status = data->cd_status; data->cd_status = atapi->status(); if (((data->prev_status == CD_STATUS_PLAYING) || (data->prev_status == CD_STATUS_PAUSED)) && ((data->cd_status != CD_STATUS_PLAYING) && (data->cd_status != CD_STATUS_PAUSED))) @@ -526,8 +539,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[13] = (data->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; } - //data->data_in[7] = 10; - data->data_in[7] = 0; + data->data_in[7] = 0; /* Clear the sense stuff as per the spec. */ atapi_sense_clear(data, temp_command, 0); @@ -1002,8 +1014,16 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[0] = 5; /*CD-ROM*/ data->data_in[1] = 0x80; /*Removable*/ - data->data_in[2] = 2; /*SCSI-2 compliant*/ - data->data_in[3] = 0x21; + if (data->is_atapi) + { + data->data_in[2] = 0; /*Not ANSI compliant*/ + data->data_in[3] = 0x21; /*ATAPI compliant*/ + } + else + { + data->data_in[2] = 2; /*SCSI-2 compliant*/ + data->data_in[3] = 0x02; + } data->data_in[4] = 31; data->data_in[5] = 0; data->data_in[6] = 0; @@ -1125,15 +1145,45 @@ static uint8_t scsi_cd_get_status(void *p) return data->status; } +static uint8_t scsi_cd_get_sense_key(void *p) +{ + scsi_cd_data_t *data = p; + + return data->sense_key; +} + +static int scsi_cd_get_bytes_required(void *p) +{ + scsi_cd_data_t *data = p; + + return data->bytes_required - data->bytes_received; +} + +static void scsi_cd_atapi_identify(uint16_t *buffer, void *p) +{ + memset(buffer, 0, 512); + + buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ + ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *)(buffer + 23), "v1.0", 8); /* Firmware */ + ide_padstr((char *)(buffer + 27), "PCemCD", 40); /* Model */ + buffer[49] = 0x200; /* LBA supported */ +} + scsi_device_t scsi_cd = { scsi_cd_init, + scsi_cd_atapi_init, scsi_cd_close, scsi_cd_start_command, scsi_cd_command, scsi_cd_get_status, + scsi_cd_get_sense_key, + scsi_cd_get_bytes_required, + + scsi_cd_atapi_identify, scsi_cd_read, scsi_cd_write, diff --git a/src/scsi_hd.c b/src/scsi_hd.c index c03d87a..9cd60ba 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -418,6 +418,16 @@ static int scsi_hd_command(uint8_t *cdb, void *p) for (; len >= 0; len--) add_data_len(0); + len = data->data_pos_write; + if (cdb[0] == SCSI_MODE_SENSE_6) + { + data->data_in[0] = len - 1; + } + else + { + data->data_in[0] = (len - 2) >> 8; + data->data_in[1] = (len - 2) & 255; + } // scsi_illegal_field(); data->cmd_pos = CMD_POS_IDLE; bus_state = BUS_IO; @@ -789,15 +799,34 @@ static uint8_t scsi_hd_get_status(void *p) return data->status; } +static uint8_t scsi_hd_get_sense_key(void *p) +{ + scsi_hd_data *data = p; + + return data->sense_key; +} + +static int scsi_hd_get_bytes_required(void *p) +{ + scsi_hd_data *data = p; + + return data->bytes_required - data->bytes_received; +} + scsi_device_t scsi_hd = { scsi_hd_init, + NULL, scsi_hd_close, scsi_hd_start_command, scsi_hd_command, scsi_hd_get_status, + scsi_hd_get_sense_key, + scsi_hd_get_bytes_required, + + NULL, scsi_hd_read, scsi_hd_write, diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 8fb2948..2fe4465 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -1087,11 +1087,6 @@ int wx_handle_command(void* hwnd, int wParam, int checked) atapi->exit(); atapi_close(); ioctl_set_drive(0); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - atapi_insert_cdrom(); - } old_cdrom_drive = cdrom_drive; cdrom_drive = 0; saveconfig(NULL); @@ -1133,11 +1128,6 @@ int wx_handle_command(void* hwnd, int wParam, int checked) atapi->exit(); atapi_close(); image_open(temp_image_path); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - atapi_insert_cdrom(); - } cdrom_drive = CDROM_IMAGE; saveconfig(NULL); if (!cdrom_enabled) @@ -1174,11 +1164,6 @@ int wx_handle_command(void* hwnd, int wParam, int checked) atapi->exit(); atapi_close(); ioctl_set_drive(new_cdrom_drive); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - atapi_insert_cdrom(); - } cdrom_drive = new_cdrom_drive; saveconfig(NULL); if (!cdrom_enabled) From 5fd2fd40aa403ac2efa7d0350d99967ae2250b2f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Jan 2018 16:05:39 +0000 Subject: [PATCH 0283/1050] Add Iomega Zip drive emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/hdd_file.c | 29 +- src/hdd_file.h | 2 + src/ide.c | 13 +- src/ide.h | 2 +- src/pc.c | 8 +- src/pc.xrc | 92 +- src/scsi.c | 3 + src/scsi_zip.c | 1099 +++++++++ src/scsi_zip.h | 7 + src/wx-config.c | 232 +- src/wx-resources.cpp | 3433 ++++++++++++++-------------- src/wx-sdl2-status.c | 15 +- src/wx-sdl2.c | 16 + 22 files changed, 3057 insertions(+), 1912 deletions(-) create mode 100644 src/scsi_zip.c create mode 100644 src/scsi_zip.h diff --git a/src/Makefile.am b/src/Makefile.am index 5683bc3..db6a1b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ +opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 580f1a9..8fa4daa 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 27108e2..d07f1ce 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e475974..649478b 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 ali1429.o amstrad i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 64e37e2..ff33020 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 6941bc8..91ced6c 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 2853360..89c6308 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.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 a2fbd9b..de15103 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 ali1429.o amstrad i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index dd2713b..74296a5 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -9,7 +9,7 @@ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o \ +opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ diff --git a/src/hdd_file.c b/src/hdd_file.c index 7d250e7..27cba2e 100644 --- a/src/hdd_file.c +++ b/src/hdd_file.c @@ -6,16 +6,19 @@ #include "ibm.h" #include "hdd_file.h" -void hdd_load(hdd_file_t *hdd, int d, const char *fn) +void hdd_load_ext(hdd_file_t *hdd, const char *fn, int spt, int hpc, int tracks, int read_only) { if (hdd->f == NULL) { /* Try to open existing hard disk image */ - hdd->f = fopen64(fn, "rb+"); + if (read_only) + hdd->f = fopen64(fn, "rb"); + else + hdd->f = fopen64(fn, "rb+"); if (hdd->f == NULL) { /* Failed to open existing hard disk image */ - if (errno == ENOENT) + if (errno == ENOENT && !read_only) { /* Failed because it does not exist, so try to create new file */ @@ -37,10 +40,16 @@ void hdd_load(hdd_file_t *hdd, int d, const char *fn) } } - hdd->spt = hdc[d].spt; - hdd->hpc = hdc[d].hpc; - hdd->tracks = hdc[d].tracks; - hdd->sectors = hdc[d].spt * hdc[d].hpc * hdc[d].tracks; + hdd->spt = spt; + hdd->hpc = hpc; + hdd->tracks = tracks; + hdd->sectors = spt * hpc * tracks; + hdd->read_only = read_only; +} + +void hdd_load(hdd_file_t *hdd, int d, const char *fn) +{ + hdd_load_ext(hdd, fn, hdc[d].spt, hdc[d].hpc, hdc[d].tracks, 0); } void hdd_close(hdd_file_t *hdd) @@ -73,6 +82,9 @@ int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { off64_t addr; int transfer_sectors = nr_sectors; + + if (hdd->read_only) + return 1; if ((hdd->sectors - offset) < transfer_sectors) transfer_sectors = hdd->sectors - offset; @@ -93,6 +105,9 @@ int hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) uint8_t zero_buffer[512]; int transfer_sectors = nr_sectors; + if (hdd->read_only) + return 1; + memset(zero_buffer, 0, 512); if ((hdd->sectors - offset) < transfer_sectors) diff --git a/src/hdd_file.h b/src/hdd_file.h index cd2997c..e3265e3 100644 --- a/src/hdd_file.h +++ b/src/hdd_file.h @@ -5,9 +5,11 @@ typedef struct hdd_file_t int hpc; int tracks; int sectors; + int read_only; } hdd_file_t; void hdd_load(hdd_file_t *hdd, int d, const char *fn); +void hdd_load_ext(hdd_file_t *hdd, const char *fn, int spt, int hpc, int tracks, int read_only); void hdd_close(hdd_file_t *hdd); int hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer); diff --git a/src/ide.c b/src/ide.c index 56f6f0a..3c80042 100644 --- a/src/ide.c +++ b/src/ide.c @@ -27,6 +27,7 @@ #include "hdd_file.h" #include "scsi.h" #include "scsi_cd.h" + #include "scsi_zip.h" #endif #include "ide.h" @@ -100,6 +101,7 @@ typedef struct IDE } IDE; int cdrom_channel = 2; +int zip_channel = -1; IDE ide_drives[4]; @@ -404,7 +406,12 @@ void resetide(void) ide_drives[d].type = IDE_CDROM; scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d); } - else + else if (zip_channel == d) + { + ide_drives[d].type = IDE_CDROM; + scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_zip, d); + } + else { loadhd(&ide_drives[d], d, ide_fn[d]); } @@ -732,10 +739,6 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) timer_update_outstanding(); ide->atapi.bus_state = 0; -/* timer_process(); - idecallback[ide_board]=1;//30*IDE_TIME; - timer_update_outstanding(); - ide->pos=0;*/ return; case 0xF0: diff --git a/src/ide.h b/src/ide.h index ea16483..3775f51 100644 --- a/src/ide.h +++ b/src/ide.h @@ -26,7 +26,7 @@ extern int idecallback[2]; extern char ide_fn[4][512]; -extern int cdrom_channel; +extern int cdrom_channel, zip_channel; uint32_t atapi_get_cd_channel(int channel); uint32_t atapi_get_cd_volume(int channel); diff --git a/src/pc.c b/src/pc.c index f28da95..3a78b8b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -35,6 +35,7 @@ #include "plat-keyboard.h" #include "plat-midi.h" #include "plat-mouse.h" +#include "scsi_zip.h" #include "serial.h" #include "sound.h" #include "sound_cms.h" @@ -609,6 +610,7 @@ void closepc() lpt1_device_close(); mouse_emu_close(); device_close_all(); + zip_eject(); } /*int main() @@ -727,6 +729,8 @@ void loadconfig(char *fn) cdrom_enabled = config_get_int(CFG_MACHINE, NULL, "cdrom_enabled", 0); cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2); + zip_channel = config_get_int(CFG_MACHINE, NULL, "zip_channel", -1); + p = (char *)config_get_string(CFG_MACHINE, NULL, "cdrom_path", ""); if (p) strcpy(image_path, p); else strcpy(image_path, ""); @@ -870,7 +874,9 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "cdrom_enabled", cdrom_enabled); config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel); config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path); - + + config_set_int(CFG_MACHINE, NULL, "zip_channel", zip_channel); + config_set_int(CFG_MACHINE, NULL, "hdc_sectors", hdc[0].spt); config_set_int(CFG_MACHINE, NULL, "hdc_heads", hdc[0].hpc); config_set_int(CFG_MACHINE, NULL, "hdc_cylinders", hdc[0].tracks); diff --git a/src/pc.xrc b/src/pc.xrc index fcb7877..8209103 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -110,6 +110,13 @@ 1 + + + + + + + @@ -477,8 +484,7 @@ - - + @@ -1164,24 +1170,16 @@ wxEXPAND 5 - wxHORIZONTAL + wxHORIZONTAL - wxALL | wxALIGN_CENTER_VERTICAL + wxALL 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 + + + 350,-1 + + @@ -1367,21 +1365,13 @@ wxHORIZONTAL - wxALL | wxALIGN_CENTER_VERTICAL + wxALL 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 + + + 350,-1 + + @@ -1567,21 +1557,13 @@ wxHORIZONTAL - wxALL | wxALIGN_CENTER_VERTICAL + wxALL 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 + + + 350,-1 + + @@ -1767,21 +1749,13 @@ wxHORIZONTAL - wxALL | wxALIGN_CENTER_VERTICAL + wxALL 5 - - - - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - 0 + + + 350,-1 + + diff --git a/src/scsi.c b/src/scsi.c index c87456f..ba207bc 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -3,6 +3,7 @@ #include "scsi.h" #include "scsi_cd.h" #include "scsi_hd.h" +#include "scsi_zip.h" #define STATE_IDLE 0 #define STATE_COMMAND 1 @@ -346,6 +347,8 @@ void scsi_bus_init(scsi_bus_t *bus) { if (cdrom_channel == c) bus->devices[c] = &scsi_cd; + else if (zip_channel == c) + bus->devices[c] = &scsi_zip; else bus->devices[c] = &scsi_hd; diff --git a/src/scsi_zip.c b/src/scsi_zip.c new file mode 100644 index 0000000..539a3b1 --- /dev/null +++ b/src/scsi_zip.c @@ -0,0 +1,1099 @@ +#include +#include +#include +#include +#include "ibm.h" +#include "hdd_file.h" +#include "scsi.h" +#include "scsi_zip.h" +#include "timer.h" + +#define BUFFER_SIZE (256*1024) + +#define ZIP_SECTORS (96*2048) + +#define RW_DELAY (TIMER_USEC * 500) + +#define SCSI_IOMEGA_SENSE 0x06 +#define SCSI_IOMEGA_EJECT 0x0d /*ATAPI only?*/ + + /*Page 1 - 0x58 bytes*/ + /*Page 2 (Disk Status Page) - 0x3d bytes + Byte 21 bits 0-3 - protection code + 0 - not write-protected + 2 - write-protected + 3 - password write-protected + Bytes 22 - 61 - serial number + */ +#define SCSI_IOMEGA_SET_PROTECTION_MODE 0x0c + /*cmd[1] = mode + cmd[6-x] = password*/ + +enum +{ + CMD_POS_IDLE = 0, + CMD_POS_WAIT, + CMD_POS_START_SECTOR, + CMD_POS_TRANSFER +}; + +typedef struct scsi_zip_data +{ + int blocks; + + int cmd_pos, new_cmd_pos; + + int addr, len; + int sector_pos; + + uint8_t buf[512]; + + uint8_t status; + + uint8_t data_in[BUFFER_SIZE]; + uint8_t data_out[BUFFER_SIZE]; + int data_pos_read, data_pos_write; + + int bytes_received, bytes_required; + + hdd_file_t hdd; + int disc_loaded; + int disc_changed; + + int sense_key, asc, ascq; + + int hd_id; + + int callback; + + scsi_bus_t *bus; + + int is_atapi; + + int read_only; +} scsi_zip_data; + +static scsi_zip_data *zip_data; + +#define CHECK_READY 2 + +static uint8_t scsi_zip_cmd_flags[0x100] = +{ + [SCSI_TEST_UNIT_READY] = CHECK_READY, + [SCSI_REQUEST_SENSE] = 0, + [SCSI_READ_6] = CHECK_READY, + [SCSI_INQUIRY] = 0, + [SCSI_MODE_SELECT_6] = 0, + [SCSI_MODE_SENSE_6] = 0, + [SCSI_START_STOP_UNIT] = 0, + [SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL] = CHECK_READY, + [SCSI_READ_10] = CHECK_READY, + [SCSI_SEEK_6] = CHECK_READY, + [SCSI_SEEK_10] = CHECK_READY, + [SCSI_IOMEGA_SENSE] = 0, + [SCSI_REZERO_UNIT] = CHECK_READY, + [SCSI_READ_CAPACITY_10] = CHECK_READY, + [SCSI_WRITE_6] = CHECK_READY, + [SCSI_WRITE_10] = CHECK_READY, + [SCSI_VERIFY_10] = CHECK_READY, + [SCSI_FORMAT] = CHECK_READY, + [SCSI_RESERVE] = 0, + [SCSI_RELEASE] = 0, + [SEND_DIAGNOSTIC] = 0 + +}; + +void zip_load(char *fn) +{ + if (zip_data) + { + FILE *f; + int read_only = 0; + + f = fopen(fn, "rb+"); + if (!f) + { + f = fopen(fn, "rb"); + read_only = 1; + } + if (f) + { + int size; + + fseek(f, -1, SEEK_END); + size = ftell(f)+1; + fclose(f); + + if (size != ZIP_SECTORS*512) + { + warning("File is incorrect size for Zip image\nMust be exactly %i bytes\n", ZIP_SECTORS*512); + return; + } + + if (zip_data->disc_loaded) + hdd_close(&zip_data->hdd); + + hdd_load_ext(&zip_data->hdd, fn, 2048,1,96, read_only); + + if (zip_data->hdd.f) + { + zip_data->disc_loaded = 1; + zip_data->disc_changed = 1; + zip_data->read_only = read_only; + } + } + } +} + +void zip_eject() +{ + if (zip_data) + { + if (zip_data->disc_loaded) + { + hdd_close(&zip_data->hdd); + zip_data->disc_loaded = 0; + } + } +} + +int zip_loaded() +{ + if (zip_data) + return zip_data->disc_loaded; + return 0; +} + +static void scsi_zip_callback(void *p) +{ + scsi_zip_data *data = p; + + data->callback = 0; + + if (data->cmd_pos == CMD_POS_WAIT) + { + data->cmd_pos = data->new_cmd_pos; + scsi_bus_kick(data->bus); + } +} + +static void *scsi_zip_init(scsi_bus_t *bus, int id) +{ + scsi_zip_data *data = malloc(sizeof(scsi_zip_data)); + memset(data, 0, sizeof(scsi_zip_data)); + + data->disc_loaded = 0; + + data->hd_id = id; + data->bus = bus; + timer_add(scsi_zip_callback, &data->callback, &data->callback, data); + + zip_data = data; + return data; +} + +static void *scsi_zip_atapi_init(scsi_bus_t *bus, int id) +{ + scsi_zip_data *data = scsi_zip_init(bus, id); + + data->is_atapi = 1; + + return data; +} + +static void scsi_zip_close(void *p) +{ + scsi_zip_data *data = p; + + if (data->disc_loaded) + hdd_close(&data->hdd); + free(data); + zip_data = NULL; +} + +static int scsi_add_data(uint8_t val, void *p) +{ + scsi_zip_data *data = p; + + pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); + + data->data_in[data->data_pos_write++] = val; + +// if (data->bus_out & BUS_REQ) +// return -1; + +// data->bus_out = (data->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; + + return 0; +} + +static int scsi_get_data(void *p) +{ + scsi_zip_data *data = p; + uint8_t val = data->data_out[data->data_pos_read++]; + + if (data->data_pos_read > BUFFER_SIZE) + fatal("scsi_get_data beyond buffer limits\n"); + + return val; +} + +static void scsi_zip_illegal(scsi_zip_data *data) +{ + data->status = STATUS_CHECK_CONDITION; + data->sense_key = KEY_ILLEGAL_REQ; + data->asc = ASC_INVALID_LUN; + data->ascq = 0; +} + +static void scsi_zip_cmd_error(scsi_zip_data *data, int sensekey, int asc, int ascq) +{ + data->status = STATUS_CHECK_CONDITION; + data->sense_key = sensekey; + data->asc = asc; + data->ascq = ascq; +} + +#define add_data_len(v) \ + do \ + { \ + if (i < len) \ + scsi_add_data(v, data); \ + i++; \ + } while (0) + + +static int scsi_zip_command(uint8_t *cdb, void *p) +{ + scsi_zip_data *data = p; + int /*addr, */len; + int i = 0, c; + int desc; + int bus_state = 0; + + if (data->cmd_pos == CMD_POS_IDLE) + pclog("SCSI ZIP command %02x %i %p\n", cdb[0], data->disc_loaded, data); + data->status = STATUS_GOOD; + data->data_pos_read = data->data_pos_write = 0; + + if ((cdb[0] != SCSI_REQUEST_SENSE/* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) + { + pclog("non-zero LUN\n"); + /*Non-zero LUN - abort command*/ + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + + if ((scsi_zip_cmd_flags[cdb[0]] & CHECK_READY) && !data->disc_loaded) + { + pclog("Disc not loaded\n"); + scsi_zip_cmd_error(data, KEY_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + if ((scsi_zip_cmd_flags[cdb[0]] & CHECK_READY) && data->disc_changed) + { + pclog("Disc changed\n"); + scsi_zip_cmd_error(data, KEY_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); + data->disc_changed = 0; + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + + switch (cdb[0]) + { + case SCSI_TEST_UNIT_READY: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_IOMEGA_SENSE: + len = cdb[4]; + if (cdb[2] == 1) + { + pclog("SCSI_IOMEGA_SENSE 1 %02x\n", len); + add_data_len(0x58); + add_data_len(0); + /*This page is related to disc health status - setting this page to 0 + makes disc health read as 'marginal'*/ + for (c = 2; c < 0x58; c++) + add_data_len(0xff); + for (; i < len; i++) + add_data_len(0); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + } + else if (cdb[2] == 2) + { + pclog("SCSI_IOMEGA_SENSE 2 %02x\n", len); + add_data_len(0x3d); + add_data_len(0); + for (c = 0; c < 19; c++) + add_data_len(0); + if (data->read_only) + add_data_len(2); + else + add_data_len(0); + for (c = 0; c < 39; c++) + add_data_len(0); + for (; i < len; i++) + add_data_len(0); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + } + else + { + pclog("IOMEGA_SENSE %02x %02x\n", cdb[2], len); + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; + + case SCSI_REZERO_UNIT: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_REQUEST_SENSE: + desc = cdb[1] & 1; + len = cdb[4]; + + if (!desc) + { + add_data_len(0x70); + add_data_len(0); + add_data_len(data->sense_key); /*Sense key*/ + add_data_len(0); /*Information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Additional sense length*/ + add_data_len(0); /*Command specific information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); /*FRU code*/ + add_data_len(0); /*Sense key specific (3 bytes)*/ + add_data_len(0); + add_data_len(0); + } + else + { + add_data_len(0x72); + add_data_len(data->sense_key); /*Sense Key*/ + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*additional sense length*/ + } + + data->sense_key = data->asc = data->ascq = 0; + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_INQUIRY: + len = cdb[4] | (cdb[3] << 8); +// pclog("INQUIRY %d %02x %02x %02x %02x %02x %02x %i\n", len, cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5], data->hd_id); + + if (cdb[1] & 0xe0) + { + add_data_len(0 | (3 << 5)); /*No physical device on this LUN*/ + } + else + { + add_data_len(0 | (0 << 5)); /*Hard disc*/ + } + add_data_len(0x80); /*Removeable device*/ + if (data->is_atapi) + { + add_data_len(0); /*Not ANSI compliant*/ + add_data_len(0x21); /*ATAPI compliant*/ + } + else + { + add_data_len(2); /*SCSI-2 compliant*/ + add_data_len(0x02); + } +// add_data_len(0); /*No version*/ +// add_data_len(2); /*Response data*/ + add_data_len(0); /*Additional length*/ + add_data_len(0); + add_data_len(0); + add_data_len(2); + + add_data_len('I'); + add_data_len('O'); + add_data_len('M'); + add_data_len('E'); + add_data_len('G'); + add_data_len('A'); + add_data_len(' '); + add_data_len(' '); + + add_data_len('Z'); + add_data_len('I'); + add_data_len('P'); + add_data_len(' '); + add_data_len('1'); + add_data_len('0'); + add_data_len('0'); + add_data_len(' '); + + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + + add_data_len('E'); /*Product revision level*/ + add_data_len('.'); + add_data_len('0'); + add_data_len('8'); + + add_data_len(0); /*Drive serial number*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Vendor unique*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Vendor descriptor*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Reserved*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_MODE_SENSE_6: + case SCSI_MODE_SENSE_10: + pclog("MODE_SENSE_6 %02x %02x\n", cdb[2], cdb[4]); + if ((cdb[2] & 0x3f) != 0x01 && (cdb[2] & 0x3f) != 0x02 && (cdb[2] & 0x3f) != 0x2f && (cdb[2] & 0x3f) != 0x3f) + { + pclog("Invalid MODE_SENSE\n"); + scsi_zip_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + bus_state = BUS_CD | BUS_IO; + break; + } + if (cdb[0] == SCSI_MODE_SENSE_6) + { + len = cdb[4]; + + add_data_len(0); + add_data_len(0); + + if (data->read_only) + add_data_len(0x80); + else + add_data_len(0); + add_data_len(0x08); + } + else + { + len = cdb[8] | (cdb[9] << 8); + + add_data_len(0); + add_data_len(0); + add_data_len(0); + + if (data->read_only) + add_data_len(0x80); + else + add_data_len(0); + + add_data_len(0); + add_data_len(0); + + add_data_len(0); + add_data_len(0x08); + } + + add_data_len((ZIP_SECTORS >> 24) & 0xff); + add_data_len((ZIP_SECTORS >> 16) & 0xff); + add_data_len((ZIP_SECTORS >> 8) & 0xff); + add_data_len( ZIP_SECTORS & 0xff); + add_data_len((512 >> 24) & 0xff); + add_data_len((512 >> 16) & 0xff); + add_data_len((512 >> 8) & 0xff); + add_data_len( 512 & 0xff); + + if ((cdb[2] & 0x3f) == 0x01 || (cdb[2] & 0x3f) == 0x3f) + { + add_data_len(0x01); + add_data_len(0x0a); + add_data_len(0xc8); /*Automatic read and write allocation enable, most expedient error recovery*/ + add_data_len(22); /*Read retry count = 22*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(90); /*Write retry count = 90*/ + add_data_len(0); + add_data_len(20512 >> 8); + add_data_len(20512 & 0xff); + } + + if ((cdb[2] & 0x3f) == 0x02 || (cdb[2] & 0x3f) == 0x3f) + { + add_data_len(0x02); + add_data_len(0x0e); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + } + + if ((cdb[2] & 0x3f) == 0x2f || (cdb[2] & 0x3f) == 0x3f) + { + add_data_len(0x2f); + add_data_len(0x04); + add_data_len(0x5c); + add_data_len(0x0f); + add_data_len(0xff); + add_data_len(0x0f); + } + + for (; i < len; i++) + add_data_len(0); + + len = data->data_pos_write; + if (cdb[0] == SCSI_MODE_SENSE_6) + { + data->data_in[0] = len - 1; + } + else + { + data->data_in[0] = (len - 2) >> 8; + data->data_in[1] = (len - 2) & 255; + } + +// scsi_illegal_field(); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_CAPACITY_10: +// len = 96 * 2048; + scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); + scsi_add_data( ZIP_SECTORS & 0xff, data); + scsi_add_data((512 >> 24) & 0xff, data); + scsi_add_data((512 >> 16) & 0xff, data); + scsi_add_data((512 >> 8) & 0xff, data); + scsi_add_data( 512 & 0xff, data); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_6: +// pclog("SCSI_READ_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + + if (data->cmd_pos == CMD_POS_IDLE) + { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } +// else +// pclog("SCSI_READ_6 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); + while (data->len) + { + if (data->cmd_pos == CMD_POS_START_SECTOR) + { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_add_data(data->buf[data->sector_pos], data); + + if (ret == -1) + { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) + { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_10: +// pclog("SCSI_READ_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + + if (data->cmd_pos == CMD_POS_IDLE) + { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } +// else +// pclog("SCSI_READ_10 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); + while (data->len) + { + if (data->cmd_pos == CMD_POS_START_SECTOR) + { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_add_data(data->buf[data->sector_pos], data); +// pclog("SCSI_READ_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) + { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) + { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_WRITE_6: + if (data->read_only) + { + pclog("zip read only\n"); + scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); + bus_state = BUS_CD | BUS_IO; + break; + } +// pclog("SCSI_WRITE_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) + { + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + readflash_set(READFLASH_HDC, data->hd_id); + pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) + { + bus_state = 0; + break; + } + + while (data->len) + { + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_get_data(data); + if (ret == -1) + { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) + { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } + + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_WRITE_10: + if (data->read_only) + { + pclog("zip read only\n"); + scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); + bus_state = BUS_CD | BUS_IO; + break; + } +// pclog("SCSI_WRITE_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) + { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) + { + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + readflash_set(READFLASH_HDC, data->hd_id); + pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; + + data->cmd_pos = CMD_POS_WAIT; + data->callback = RW_DELAY; + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; + + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) + { + bus_state = 0; + break; + } + + while (data->len) + { + for (; data->sector_pos < 512; data->sector_pos++) + { + int ret = scsi_get_data(data); +// pclog("SCSI_WRITE_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) + { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) + { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } + + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; +// output = 3; + break; + + case SCSI_VERIFY_10: + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_MODE_SELECT_6: + if (!data->bytes_received) + { + data->bytes_required = cdb[4]; +// pclog("SCSI_MODE_SELECT_6 bytes_required=%i\n", data->bytes_required); + bus_state = 0; + break; + } +// pclog("SCSI_MODE_SELECT_6 complete\n"); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_FORMAT: + if (data->read_only) + { + scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); + bus_state = BUS_CD | BUS_IO; + break; + } + readflash_set(READFLASH_HDC, 0); + hdd_format_sectors(&data->hdd, 0, ZIP_SECTORS); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_START_STOP_UNIT: + /*if ((cdb[4] & (START_STOP_LOEJ | START_STOP_START)) == START_STOP_LOEJ)*/ + /*This is incorrect based on the SCSI spec, but it's what the Iomega Win9x drivers send to eject a disc*/ + if ((cdb[4] & (START_STOP_LOEJ | START_STOP_START)) == 0) + zip_eject(); + bus_state = BUS_CD | BUS_IO; + break; + + /*These aren't really meaningful in a single initiator system, so just return*/ + case SCSI_RESERVE: + case SCSI_RELEASE: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_SEEK_6: + case SCSI_SEEK_10: + bus_state = BUS_CD | BUS_IO; + break; + + case SEND_DIAGNOSTIC: + if (cdb[1] & (1 << 2)) + { + /*Self-test*/ + /*Always passes*/ + bus_state = BUS_CD | BUS_IO; + } + else + { + /*Treat all other diagnostic requests as illegal*/ + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; + + case SCSI_IOMEGA_EJECT: + if (data->is_atapi) + zip_eject(); + else + scsi_zip_illegal(data); + + bus_state = BUS_CD | BUS_IO; + break; + + default: + fatal("Bad SCSI ZIP command %02x\n", cdb[0]); + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + break; + } + + return bus_state; +} + +static uint8_t scsi_zip_read(void *p) +{ + scsi_zip_data *data = p; + + return data->data_in[data->data_pos_read++]; +} + +static void scsi_zip_write(uint8_t val, void *p) +{ + scsi_zip_data *data = p; + + data->data_out[data->data_pos_write++] = val; + + data->bytes_received++; + + if (data->data_pos_write > BUFFER_SIZE) + fatal("Exceeded data_out buffer size\n"); +} + +static int scsi_zip_read_complete(void *p) +{ + scsi_zip_data *data = p; + + return (data->data_pos_read == data->data_pos_write); +} +static int scsi_zip_write_complete(void *p) +{ + scsi_zip_data *data = p; + + return (data->bytes_received == data->bytes_required); +} + +static void scsi_zip_start_command(void *p) +{ + scsi_zip_data *data = p; + + data->bytes_received = 0; + data->bytes_required = 0; + data->data_pos_read = data->data_pos_write = 0; +} + +static uint8_t scsi_zip_get_status(void *p) +{ + scsi_zip_data *data = p; + + return data->status; +} + +static uint8_t scsi_zip_get_sense_key(void *p) +{ + scsi_zip_data *data = p; + + return data->sense_key; +} + +static int scsi_zip_get_bytes_required(void *p) +{ + scsi_zip_data *data = p; + + return data->bytes_required - data->bytes_received; +} + +static void scsi_zip_atapi_identify(uint16_t *buffer, void *p) +{ + memset(buffer, 0, 512); + + buffer[0] = 0x8000 | (0<<8) | 0x80 | (2<<5); /* ATAPI device, direct-access device, removable media, accelerated DRQ */ + ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *)(buffer + 23), "E.08", 8); /* Firmware */ + ide_padstr((char *)(buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ + buffer[49] = 0x200; /* LBA supported */ +} + +scsi_device_t scsi_zip = +{ + scsi_zip_init, + scsi_zip_atapi_init, + scsi_zip_close, + + scsi_zip_start_command, + scsi_zip_command, + + scsi_zip_get_status, + scsi_zip_get_sense_key, + scsi_zip_get_bytes_required, + + scsi_zip_atapi_identify, + + scsi_zip_read, + scsi_zip_write, + scsi_zip_read_complete, + scsi_zip_write_complete, +}; diff --git a/src/scsi_zip.h b/src/scsi_zip.h new file mode 100644 index 0000000..16935fa --- /dev/null +++ b/src/scsi_zip.h @@ -0,0 +1,7 @@ +#include "scsi.h" + +extern scsi_device_t scsi_zip; + +void zip_load(char *fn); +void zip_eject(); +int zip_loaded(); diff --git a/src/wx-config.c b/src/wx-config.c index 2bee083..806f52e 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -39,6 +39,7 @@ static char hd_new_name[512]; static int hd_new_spt, hd_new_hpc, hd_new_cyl; static int hd_new_type; static int new_cdrom_channel; +static int new_zip_channel; extern int pause; @@ -365,7 +366,7 @@ int config_dlgsave(void* hdlg) temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || temp_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel || - strcmp(lpt1_device_name, lpt_device_get_internal_name(temp_lpt1_device)) + zip_channel != new_zip_channel || strcmp(lpt1_device_name, lpt_device_get_internal_name(temp_lpt1_device)) #ifdef USE_NETWORKING || temp_network_card != network_card_current #endif @@ -454,6 +455,7 @@ int config_dlgsave(void* hdlg) hdc[3] = hd[3]; cdrom_channel = new_cdrom_channel; + zip_channel = new_zip_channel; if (has_been_inited) { @@ -737,9 +739,51 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) hd_changed = 0; new_cdrom_channel = cdrom_channel; - + new_zip_channel = zip_channel; + hdconf_init(hdlg); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[0]")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); + if (cdrom_channel == 0) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (zip_channel == 0) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[1]")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); + if (cdrom_channel == 1) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (zip_channel == 1) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[2]")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); + if (cdrom_channel == 2) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (zip_channel == 2) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[3]")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); + if (cdrom_channel == 3) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (zip_channel == 3) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + #ifdef USE_NETWORKING recalc_net_list(hdlg, romstomodel[romset]); @@ -1237,13 +1281,16 @@ static void update_hdd_cdrom(void* hdlg) for (i = 0; i < 4; ++i) { - b = !is_mfm && (new_cdrom_channel == i); - sprintf(s, "IDC_HDD[%d]", i); + b = !is_mfm && ((new_cdrom_channel == i) || (new_zip_channel == i)); + pclog("update_hdd_cdrom: i=%i b=%i new_cdrom_channel=%i new_zip_channel=%i\n", i, b, new_cdrom_channel, new_zip_channel); + sprintf(s, "IDC_COMBODRIVETYPE[%d]", i); h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_BM_SETCHECK, b ? 0 : 1, 0); - sprintf(s, "IDC_CDROM[%d]", i); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_BM_SETCHECK, b ? 1 : 0, 0); + if (i == new_cdrom_channel) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (i == new_zip_channel) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); sprintf(s, "IDC_EDIT_FN[%d]", i); wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); sprintf(s, "IDC_FILE[%d]", i); @@ -1612,39 +1659,14 @@ int hdconf_update(void* hdlg) update_hdd_cdrom(hdlg); - int i, j; + int i; for (i = 0; i < 4; ++i) { sprintf(s, "IDC_HDD_LABEL[%d]", i*10); wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_HDD[%d]", i); + sprintf(s, "IDC_COMBODRIVETYPE[%d]", i); + h = wx_getdlgitem(hdlg, WX_ID(s)); wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_CDROM[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - if (i >= 2) - { - sprintf(s, "IDC_EDIT_FN[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_FILE[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_EJECT[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_NEW[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_EDIT_SPT[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_EDIT_HPC[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_EDIT_CYL[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_TEXT_SIZE[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - for (j = 1; j < 6; ++j) - { - sprintf(s, "IDC_HDD_LABEL[%d]", i*10+j); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - } - } } h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); @@ -2036,60 +2058,122 @@ int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); return TRUE; } - else if (ID_IS("IDC_HDD[0]")) + else if (ID_IS("IDC_COMBODRIVETYPE[0]")) { - if (new_cdrom_channel == 0) - new_cdrom_channel = -1; + int type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[0]")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + switch (type) + { + case 0: /*Hard drive*/ + if (new_cdrom_channel == 0) + new_cdrom_channel = -1; + if (new_zip_channel == 0) + new_zip_channel = -1; + break; + case 1: /*CD-ROM*/ + new_cdrom_channel = 0; + if (new_zip_channel == 0) + new_zip_channel = -1; + break; + case 2: /*Zip*/ + new_zip_channel = 0; + if (new_cdrom_channel == 0) + new_cdrom_channel = -1; + break; + } update_hdd_cdrom(hdlg); return TRUE; } - else if (ID_IS("IDC_HDD[1]")) + else if (ID_IS("IDC_COMBODRIVETYPE[1]")) { - if (new_cdrom_channel == 1) - new_cdrom_channel = -1; + int type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[1]")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + switch (type) + { + case 0: /*Hard drive*/ + if (new_cdrom_channel == 1) + new_cdrom_channel = -1; + if (new_zip_channel == 1) + new_zip_channel = -1; + break; + case 1: /*CD-ROM*/ + new_cdrom_channel = 1; + if (new_zip_channel == 1) + new_zip_channel = -1; + break; + case 2: /*Zip*/ + new_zip_channel = 1; + if (new_cdrom_channel == 1) + new_cdrom_channel = -1; + break; + } update_hdd_cdrom(hdlg); return TRUE; } - else if (ID_IS("IDC_HDD[2]")) + else if (ID_IS("IDC_COMBODRIVETYPE[2]")) { - if (new_cdrom_channel == 2) - new_cdrom_channel = -1; + int type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[2]")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + switch (type) + { + case 0: /*Hard drive*/ + if (new_cdrom_channel == 2) + new_cdrom_channel = -1; + if (new_zip_channel == 2) + new_zip_channel = -1; + break; + case 1: /*CD-ROM*/ + new_cdrom_channel = 2; + if (new_zip_channel == 2) + new_zip_channel = -1; + break; + case 2: /*Zip*/ + new_zip_channel = 2; + if (new_cdrom_channel == 2) + new_cdrom_channel = -1; + break; + } update_hdd_cdrom(hdlg); return TRUE; } - else if (ID_IS("IDC_HDD[3]")) + else if (ID_IS("IDC_COMBODRIVETYPE[3]")) { - if (new_cdrom_channel == 3) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - - } - else if (ID_IS("IDC_CDROM[0]")) - { - new_cdrom_channel = 0; + int type; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[3]")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + switch (type) + { + case 0: /*Hard drive*/ + if (new_cdrom_channel == 3) + new_cdrom_channel = -1; + if (new_zip_channel == 3) + new_zip_channel = -1; + break; + case 1: /*CD-ROM*/ + new_cdrom_channel = 3; + if (new_zip_channel == 3) + new_zip_channel = -1; + break; + case 2: /*Zip*/ + new_zip_channel = 3; + if (new_cdrom_channel == 3) + new_cdrom_channel = -1; + break; + } update_hdd_cdrom(hdlg); return TRUE; } - else if (ID_IS("IDC_CDROM[1]")) - { - new_cdrom_channel = 1; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_CDROM[2]")) - { - new_cdrom_channel = 2; - update_hdd_cdrom(hdlg); - return TRUE; - } - else if (ID_IS("IDC_CDROM[3]")) - { - new_cdrom_channel = 3; - update_hdd_cdrom(hdlg); - return TRUE; - } - } return FALSE; } diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 829c070..a4eb804 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 133762; +static size_t xml_res_size_26 = 132009; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -1988,282 +1988,294 @@ static unsigned char xml_res_file_26[] = { 32,66,80,66,32,99,104,101,99,107,105,110,103,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, 47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,34,62,10, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,68,45,82,79,77,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,95,76,79,65,68,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97,100, -32,105,109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114, -34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,67,68,82,79,77,95,68,73,83,65,66,76,69,68,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,115,97,98,108,101,100, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,82,101,115,111,108,117,116,105,111,110,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73, -79,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,114,105,103,105,110,97,108,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,105,122,97,98, -108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83, -79,76,85,84,73,79,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,117,115,116,111,109,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32, +97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,82,69,83,79,76,85,84,73,79,78,95,67,85,83,84,79,77,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,99,117,115, -116,111,109,32,114,101,115,111,108,117,116,105,111,110,46,46,46,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, -69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112, -59,38,97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101, -62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,68,73, +83,67,95,90,73,80,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,111,97,100,32,95,90,73,80,32,100,114,105,118,101,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101, -32,102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, -116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, -76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, -117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114, -101,101,110,32,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,70,83,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,66,111,114,100,101,114,108,101,115,115, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69, -91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,69,120,99,108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68, -82,73,86,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,82,101,110,100,101,114,32,100,114,105,118,101,114,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, -117,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, -78,68,69,82,95,68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116,51,68,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, -73,86,69,82,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,79,112,101,110,71,76,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76, -32,51,46,48,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, -78,68,69,82,95,68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,83,111,102,116,119,97,114,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +69,74,69,67,84,95,90,73,80,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,69,106,101,99,116,32,90,73,80,32,100,114,105,118,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110, +97,109,101,61,34,73,68,77,95,67,68,82,79,77,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,67,68,45,82,79,77,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,86,83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104, -101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73,77,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,109,32,100, -105,115,112,108,97,121,32,111,110,32,108,111,115,116,32,102,111,99,117, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +77,95,67,68,82,79,77,95,73,77,65,71,69,95,76,79,65,68,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97,100,32,105,109,97,103, +101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67, +68,82,79,77,95,68,73,83,65,66,76,69,68,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,68,105,115,97,98,108,101,100,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,82,101,115,111,108,117,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,114,105, +103,105,110,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,115,105,122,97,98,108,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,117,115,116,111,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112, +97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85, +84,73,79,78,95,67,85,83,84,79,77,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,101,116,32,99,117,115,116,111,109,32,114,101, +115,111,108,117,116,105,111,110,46,46,46,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,77,69,77,66,69, +82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +101,109,98,101,114,32,115,105,122,101,32,38,97,109,112,59,38,97,109,112, +59,32,112,111,115,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99, +104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101,32,102,117,108, +108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108,116,43,80,97, +103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69, +69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108, +108,115,99,114,101,101,110,32,111,110,32,105,110,112,117,116,32,103,114, +97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, 99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, +116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110,32, +109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,65,76, -84,69,82,78,65,84,73,86,69,95,85,80,68,65,84,69,95,76,79,67,75,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,108,116,101,114,110, -97,116,105,118,101,32,117,112,100,97,116,101,45,108,111,99,107,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98, -108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34, -47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79, -68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,79,117,116,112,117,116,32,115,116,114,101,116,99,104,45,109, -111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, +95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,66,111,114,100,101,114,108,101,115,115,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101, -114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,120,99, +108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116, -32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82, +34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,82,101,110, +100,101,114,32,100,114,105,118,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,48,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95, +68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,105,114,101,99,116,51,68,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112, +101,110,71,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46,48,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95, +68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,111,102,116,119,97,114,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98, +108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73,77,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,68,105,109,32,100,105,115,112,108, +97,121,32,111,110,32,108,111,115,116,32,102,111,99,117,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, +101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,65,76,84,69,82,78,65,84, +73,86,69,95,85,80,68,65,84,69,95,76,79,67,75,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,108,116,101,114,110,97,116,105,118,101, +32,117,112,100,97,116,101,45,108,111,99,107,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, +47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +99,97,108,101,32,102,105,108,116,101,114,105,110,103,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,48,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,101,97, +114,101,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, 117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, -67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,76,105,110,101,97,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,117,116,112,117,116,32,115,116,114,101,116,99,104,45,109,111,100,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,49, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52, +58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,50, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83, +113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99, +97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,99, +97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, +76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, 101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, 105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98, +68,77,95,86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46, -48,32,114,101,110,100,101,114,101,114,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,73,110,112,117,116,32,115,116,114,101,116,99,104,45,109,111, +101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46,48,32, +114,101,110,100,101,114,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,73,110,112,117,116,32,115,116,114,101,116,99,104,45,109,111, 100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, @@ -2582,133 +2594,566 @@ static unsigned char xml_res_file_26[] = { 47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101, 32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114, 116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,34,32,115,116,97,114,116,61, -34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,67,95,67,68,82,79,77,34,32,115,116,97,114,116,61, -34,50,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34,32,115,116,97,114, -116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32,115,116,97,114,116, -61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32,115,116,97,114,116, -61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, -110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116,97,114,116,61,34, -54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34,32,115,116,97,114, -116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,34,32,115,116, -97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,34, -32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32,32,60,105,100,115,45, -114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, -73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,72, -68,68,95,76,65,66,69,76,34,32,115,116,97,114,116,61,34,49,49,48,48,34,47, -62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,103, -117,114,101,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108,101,62,119, -120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,60,47,115, -116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110, -102,105,103,117,114,101,32,80,67,101,109,60,47,116,105,116,108,101,62,10, -32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116, -101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79, -79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97, -112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103, -97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32, -32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, -73,68,67,95,78,79,84,69,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,68,69,70,65,85,76,84, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, -111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,51,50,120,51,50,95,109,111,116,104,101,114,98,111, -97,114,100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, -65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, -62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, -108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84,89, +80,69,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, +60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, +70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, +74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, +69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, +62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, +48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, +61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115, +116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108,103,34,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117,114,101,32,80, +67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, +101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, +108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, +85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, +105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, +61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, +120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, +65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, +67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, +32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -2716,35 +3161,341 @@ static unsigned char xml_res_file_26[] = { 101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, 105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, +73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79, -68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99, -101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101, -116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, +115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, +83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -2772,490 +3523,30 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32, +61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, 121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, 66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, -110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110, -97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, -100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111, -114,121,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67,116, -114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, -75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109, -105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, -77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, -79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, -122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, -99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, -99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, -76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, 101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, -105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, -100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, -103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, @@ -3265,327 +3556,47 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, 99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, 116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, 112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, -65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, -107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, -115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, -97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, +73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, -111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105, -118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69, -76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, -83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, -60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, -98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, -115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3911,116 +3922,69 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73, -68,67,95,72,68,68,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, +68,82,73,86,69,84,89,80,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47, -118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109, +97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78, +69,87,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,68,82,79,77,91,48,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87, -91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, -54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, -111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108, -116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4029,82 +3993,46 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, 116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, +36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, +112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62,10,32,32,32,32, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99,111,110,116, -114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105,116,109,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,106, -101,99,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, -48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, @@ -4112,49 +4040,87 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, 116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, -118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, -47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, -84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, +54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4168,74 +4134,10 @@ static unsigned char xml_res_file_26[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84, -95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, -66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97,98,101,108, +108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, 47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4256,7 +4158,7 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10,32,32,32,32,32,32, +73,68,67,95,69,68,73,84,95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -4276,60 +4178,147 @@ static unsigned char xml_res_file_26[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, +101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90, -69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, 117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, -111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, +66,69,76,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84, +95,83,73,90,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +104,111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, @@ -4399,127 +4388,105 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,68,82,73,86,69,84,89,80,69,91,49,93,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,67,68,82,79,77,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115, +101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, @@ -4886,67 +4853,45 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, 111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, -111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,114, -100,32,100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69, +84,89,80,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, -111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,68, -82,79,77,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,67,68,45,82,79,77,60,47,108,97,98,101,108,62,10,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108, -117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, @@ -5373,127 +5318,105 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, 110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,68,82,73,86,69,84,89,80,69,91,51,93,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,72,68,68,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,72,97,114,100,32,100,114,105,118,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48, -60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,73,68,67,95,67,68,82,79,77,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115, +101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 9286c9c..9341d17 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -13,6 +13,7 @@ #include "hdd.h" #include "ide.h" #include "cdrom-image.h" +#include "scsi_zip.h" #include "wx-common.h" drive_info_t drive_info[10]; @@ -79,7 +80,19 @@ drive_info_t* get_machine_info(char* s, int* num_drive_info) { drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); readflash_clear(READFLASH_HDC, i); pos++; - } else if (strlen(ide_fn[i]) > 0) + } + else if (!hdd_controller_current_is_mfm() && i == zip_channel) + { + strcpy(drive_info[pos].fn, ""); + drive_info[pos].enabled = zip_loaded(); + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_FDD; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } + else if (strlen(ide_fn[i]) > 0) { strcpy(drive_info[pos].fn, ide_fn[i]); drive_info[pos].enabled = 1; diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 2fe4465..216f19c 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -29,6 +29,7 @@ #include "nvr.h" #include "plat-joystick.h" #include "plat-midi.h" +#include "scsi_zip.h" #include "sound.h" #include "thread.h" #include "disc.h" @@ -855,6 +856,21 @@ int wx_handle_command(void* hwnd, int wParam, int checked) wx_checkmenuitem(hmenu, wParam, bpb_disable); saveconfig(NULL); } + else if (ID_IS("IDM_DISC_ZIP")) + { + char zip_fn[256] = ""; + + if (!getfile(hwnd, + "Disc image (*.img)|*.img|All files (*.*)|*.*", + zip_fn)) + { + zip_load(openfilestring); + } + } + else if (ID_IS("IDM_EJECT_ZIP")) + { + zip_eject(); + } else if (ID_IS("IDM_MACHINE_TOGGLE")) { if (emulation_state != EMULATION_STOPPED) From 0e37f08cb5c065823b2fb99c0890ce4949cab243 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Jan 2018 16:13:41 +0000 Subject: [PATCH 0284/1050] Add menu option to create blank disc image. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/pc.xrc | 4 + src/wx-createdisc.cc | 143 ++ src/wx-createdisc.h | 8 + src/wx-resources.cpp | 2871 ++++++++++++++-------------- src/wx-sdl2.c | 6 + 11 files changed, 1606 insertions(+), 1438 deletions(-) create mode 100644 src/wx-createdisc.cc create mode 100644 src/wx-createdisc.h diff --git a/src/Makefile.am b/src/Makefile.am index db6a1b0..864c77c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,7 @@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c \ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc wx-createdisc.cc if USE_ALSA pcem_LDADD += -lasound pcem_SOURCES += midi_alsa.c diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 8fa4daa..7dc3437 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -23,7 +23,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index d07f1ce..3670495 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -23,7 +23,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 91ced6c..e7056fe 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -24,7 +24,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx.res + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 89c6308..dccbcc5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -24,7 +24,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx.res + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 NETOBJ = ne2000.o nethandler.o diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 74296a5..50ba24f 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -22,7 +22,7 @@ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy70 x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o +wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/pc.xrc b/src/pc.xrc index 8209103..698c304 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -111,6 +111,10 @@ 1 + + + + diff --git a/src/wx-createdisc.cc b/src/wx-createdisc.cc new file mode 100644 index 0000000..ea0db8f --- /dev/null +++ b/src/wx-createdisc.cc @@ -0,0 +1,143 @@ +extern "C" void pclog(const char *format, ...); + +#include "wx-createdisc.h" + +#include "wx-utils.h" +#include "wx/wxprec.h" + +#include "wx-dialogbox.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/xrc/xmlres.h" + +#define IDC_CONFIG_BASE 1000 + +static struct +{ + char name[80]; + int nr_sectors; +} disc_formats[] = +{ + {"160 kB", 1*40*8}, + {"180 kB", 1*40*9}, + {"320 kB", 2*40*8}, + {"360 kB", 2*40*9}, + {"720 kB", 2*80*9}, + {"1.44 MB", 2*80*18}, + {"2.88 MB", 2*80*36}, + {"100 MB (Zip)", 2048*96}, + {"", 0} +}; + +static int creatediscimage_dlgproc(void *hdlg, int message, INT_PARAM wParam, + LONG_PARAM lParam) +{ + wxWindow *window = (wxWindow *)hdlg; + int c; + + switch (message) + { + case WX_INITDIALOG: + return TRUE; + + case WX_COMMAND: + switch (wParam) + { + case wxID_OK: + c = 0; + + while (disc_formats[c].nr_sectors) + { + wxWindow *rb_win = window->FindWindow(IDC_CONFIG_BASE + c); + wxRadioButton *rb = wxDynamicCast(rb_win, wxRadioButton); + + if (rb->GetValue()) + break; + c++; + } + + if (disc_formats[c].nr_sectors) + { + char openfilestring[260]; + int ret; + + memset(openfilestring, 0, sizeof(openfilestring)); + ret = wx_filedialog(hdlg, "Save", "", + "Disc image (*.img;*.ima)|*.img;*.ima|All files (*.*)|*.*", + ".img", + 0, openfilestring); + + if (!ret) + { + FILE *f = fopen(openfilestring, "wb"); + if (f) + { + uint8_t sector[512]; + int d; + + memset(sector, 0, 512); + + for (d = 0; d < disc_formats[c].nr_sectors; d++) + fwrite(sector, 512, 1, f); + + fclose(f); + } + } + } + + wx_enddialog(hdlg, 0); + return TRUE; + + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + +void creatediscimage_open(void *hwnd) +{ + int id = IDC_CONFIG_BASE; + int c = 0; + + PCemDialogBox dialog((wxWindow *)hwnd, creatediscimage_dlgproc); + + dialog.SetTitle("Create Disc Image"); + + wxFlexGridSizer* root = new wxFlexGridSizer(0, 1, 0, 0); + root->SetFlexibleDirection(wxBOTH); + root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + dialog.SetSizer(root); + + wxFlexGridSizer* sizer = new wxFlexGridSizer(0, 1, 0, 0); + sizer->SetFlexibleDirection(wxBOTH); + sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + root->Add(sizer, 1, wxEXPAND, 5); + + while (disc_formats[c].nr_sectors) + { + wxBoxSizer *radioSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(radioSizer, 1, wxEXPAND, 5); + wxRadioButton *rb = new wxRadioButton(&dialog, id++, disc_formats[c].name); + radioSizer->Add(rb, 1, wxALL, 5); + + c++; + } + + wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + root->Add(okCancelSizer, 1, wxEXPAND, 5); + + okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); + + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); +} diff --git a/src/wx-createdisc.h b/src/wx-createdisc.h new file mode 100644 index 0000000..dae4c1b --- /dev/null +++ b/src/wx-createdisc.h @@ -0,0 +1,8 @@ +#ifndef SRC_WX_CREATEDISC_H_ +#define SRC_WX_CREATEDISC_H_ + +extern "C" { +void creatediscimage_open(void *hwnd); +} + +#endif /* SRC_WX_CREATEDISC_H_ */ diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index a4eb804..441d490 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 132009; +static size_t xml_res_size_26 = 132166; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -1992,1168 +1992,741 @@ static unsigned char xml_res_file_26[] = { 97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, 101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,68,73, -83,67,95,90,73,80,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,76,111,97,100,32,95,90,73,80,32,100,114,105,118,101,46,46,46,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -69,74,69,67,84,95,90,73,80,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,69,106,101,99,116,32,90,73,80,32,100,114,105,118,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110, -97,109,101,61,34,73,68,77,95,67,68,82,79,77,34,62,10,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,67,68,45,82,79,77,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,67,68,82,79,77,95,73,77,65,71,69,95,76,79,65,68,34,62,10,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97,100,32,105,109,97,103, +83,67,95,67,82,69,65,84,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,114,101,97,116,101,32,98,108,97,110,107,32,100,105,115,99, +32,105,109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114, +34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,68,73,83,67,95,90,73,80,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,111,97,100,32,95,90,73,80,32,100,114,105,118, 101,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67, -68,82,79,77,95,68,73,83,65,66,76,69,68,34,62,10,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,68,105,115,97,98,108,101,100,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, -114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32, -32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,82,101,115,111,108,117,116,105,111,110,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,114,105, -103,105,110,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, -69,83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,82,101,115,105,122,97,98,108,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, -49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78, -91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -67,117,115,116,111,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112, -97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85, -84,73,79,78,95,67,85,83,84,79,77,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,116,32,99,117,115,116,111,109,32,114,101, -115,111,108,117,116,105,111,110,46,46,46,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,77,69,77,66,69, -82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, -101,109,98,101,114,32,115,105,122,101,32,38,97,109,112,59,38,97,109,112, -59,32,112,111,115,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99, -104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101,32,102,117,108, -108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108,116,43,80,97, -103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69, -69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108, -108,115,99,114,101,101,110,32,111,110,32,105,110,112,117,116,32,103,114, -97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,69,74,69,67,84,95,90,73,80,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,106,101,99,116,32,90,73,80,32, +100,114,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,95,67,68,45,82,79,77, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,95,76, +79,65,68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76, +111,97,100,32,105,109,97,103,101,46,46,46,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, 116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110,32, -109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83, -95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,66,111,114,100,101,114,108,101,115,115,60,47,108,97,98, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,67,68,82,79,77,95,68,73,83,65,66,76,69,68,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,115,97, +98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,69,77,80,84,89, +34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,109,112, +116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,109,97,103,101, +46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,86, +105,100,101,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,111,108, +117,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,83,79,76,85,84,73,79,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,114,105,103,105,110,97,108,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,120,99, -108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82, -34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,82,101,110, -100,101,114,32,100,114,105,118,101,114,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,48,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95, -68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,68,105,114,101,99,116,51,68,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91, +49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82, +101,115,105,122,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47, 62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112, -101,110,71,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, -69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46,48,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95, -68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,111,102,116,119,97,114,101,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98, -108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,95,67,85,83,84, +79,77,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +101,116,32,99,117,115,116,111,109,32,114,101,115,111,108,117,116,105,111, +110,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,101,109,98,101,114,32,115,105, +122,101,32,38,97,109,112,59,38,97,109,112,59,32,112,111,115,105,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114, +97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78, +95,84,79,71,71,76,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,111,103,103,108,101,32,102,117,108,108,115,99,114,101,101,110, +92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,68,111,119,110,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110, +32,111,110,32,105,110,112,117,116,32,103,114,97,98,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62, +49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,117,108,108,115,99,114,101,101,110,32,109,111,100,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,48,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,111,114, +100,101,114,108,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73,77,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,68,105,109,32,100,105,115,112,108, -97,121,32,111,110,32,108,111,115,116,32,102,111,99,117,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, -101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,65,76,84,69,82,78,65,84, -73,86,69,95,85,80,68,65,84,69,95,76,79,67,75,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,65,108,116,101,114,110,97,116,105,118,101, -32,117,112,100,97,116,101,45,108,111,99,107,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60, -47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -99,97,108,101,32,102,105,108,116,101,114,105,110,103,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,48,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,101,97, -114,101,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, -67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,95,76,105,110,101,97,114,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -79,117,116,112,117,116,32,115,116,114,101,116,99,104,45,109,111,100,101, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110, -101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,49, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52, -58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,50, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83, -113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62, +73,68,95,70,83,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,69,120,99,108,117,115,105,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,82,101,110,100,101,114,32,100,114,105, +118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78, +68,69,82,95,68,82,73,86,69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,117,116,111,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99, -97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,99, -97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, -76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105, +114,101,99,116,51,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, 110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, +73,86,69,82,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,112,101,110,71,76,32,51,46,48,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,53, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111, +102,116,119,97,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86,83,89,78,67,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,86,83,121,110,99, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,76,79,83, +84,95,70,79,67,85,83,95,68,73,77,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,68,105,109,32,100,105,115,112,108,97,121,32,111,110, +32,108,111,115,116,32,102,111,99,117,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47, +99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,65,76,84,69,82,78,65,84,73,86,69,95,85,80, +68,65,84,69,95,76,79,67,75,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,65,108,116,101,114,110,97,116,105,118,101,32,117,112,100,97, +116,101,45,108,111,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,97,108,101,32,102,105, +108,116,101,114,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, 101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +68,95,83,67,65,76,69,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,78,101,97,114,101,115,116,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79, +68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,76,105,110,101,97,114,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, 62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98,101, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116, +32,115,116,114,101,116,99,104,45,109,111,100,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, 47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46,48,32, -114,101,110,100,101,114,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +101,61,34,73,68,77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112, +105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, +67,65,76,69,95,77,69,78,85,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,117,116,112,117,116,32,115,99,97,108,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53,120,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53, +120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, +69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, +76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,51,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,73,110,112,117,116,32,115,116,114,101,116,99,104,45,109,111, -100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111, +114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77, +95,86,73,68,95,71,76,51,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,110,71,76,32,51,46,48,32,114,101,110,100,101,114,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112,117,116,32, +115,116,114,101,116,99,104,45,109,111,100,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69, +84,67,72,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82, +69,84,67,72,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69, +84,67,72,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,51,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101, +114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,112,117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101, -32,112,105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67, -72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,99,97, -108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97, +51,95,73,78,80,85,84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, 111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, 116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108, +95,73,78,80,85,84,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, 47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, 32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85, -84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32, +84,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, 97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, -83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, 62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, 73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91, -52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,51,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,53,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,104,97,100,101,114,32,114,101,102,114,101,115, -104,32,114,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84, -69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,97,109,101,32,97,115,32,101,109,117,108,97,116,101,100,32,100, -105,115,112,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69, -83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,49,48,32,104,122,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68, -69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,53,32,104,122, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, -76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,51, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,51,48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83, -72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,53,48,32,104,122,60,47,108,97,98,101,108,62, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,114, +101,102,114,101,115,104,32,114,97,116,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82, +69,83,72,95,82,65,84,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,97,109,101,32,97,115,32,101,109,117,108, +97,116,101,100,32,100,105,115,112,108,97,121,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, 114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, 110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, -82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54,48,32,104,122,60, +82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,48,32,104,122,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,55,50, +51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53, 93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +50,53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, 77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, -95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98,101,108,62,10, +95,82,65,84,69,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,51,48,32,104,122,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, -76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,109, -97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111,117,110,100, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102,101,114,32,108,101, -110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85, -70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78, -68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,95,50,48,48,32,109,115,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, -49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, +95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,53,48,32,104,122,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54, +48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,79,117,116,112,117,116,32,108,101,118,101,108,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,114,109,97,108,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,50,32, -100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78, -91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -43,95,52,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71, -65,73,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,43,95,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, -78,68,95,71,65,73,78,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,43,95,56,32,100,66,60,47,108,97,98,101,108,62,10,32, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82, +65,84,69,91,55,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,83,78,68,95,71,65,73,78,91,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,43,95,49,48,32,100,66,60,47,108,97,98, +105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69, +70,82,69,83,72,95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100, +101,114,32,109,97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102, +101,114,32,108,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,78,68,95,66,85,70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,83,78,68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,54,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,50,32,100,66,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,50,48,48,32,109,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, 105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,55,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,52, -32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73, -78,91,56,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,43,49,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68, -95,71,65,73,78,91,57,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,43,49,56,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98, -101,108,62,77,105,115,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114, -101,101,110,115,104,111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67, -82,69,69,78,83,72,79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,84,97,107,101,32,115,99,114,101,101,110,115,104,111,116, -92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,80,78,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,48,48, +32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,79,117,116,112,117,116,32,108,101,118, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,78,111,114,109,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78, -83,72,79,84,95,70,79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, -79,82,77,65,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78, +68,95,71,65,73,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,43,95,50,32,100,66,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,83,78,68,95,71,65,73,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,43,95,52,32,100,66,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,83,78,68,95,71,65,73,78,91,51,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,43,95,54,32,100,66,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,52,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,56,32,100,66, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,49, +48,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65, +73,78,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,43,49,50,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, 10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, -67,82,69,69,78,83,72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,70,108,97,115,104,32,115,99,114,101, -101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, -101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105, -110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114, -116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84,89, -80,69,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, -60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, -70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, -74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, -69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, -32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, -95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, +78,68,95,71,65,73,78,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,43,49,52,32,100,66,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,83,78,68,95,71,65,73,78,91,56,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,43,49,54,32,100,66,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,57,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,56,32,100,66,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,83,99,114,101,101,110,115,104,111,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,84,97,107,101,32, +115,99,114,101,101,110,115,104,111,116,92,116,67,116,114,108,43,65,108, +116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,70,111,114, +109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69, +78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95, +70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77, +65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,80, +71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84, +95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, +101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, +101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, -48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, -101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, -61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115, -116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108,103,34,62,10, -32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, -73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32, -32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117,114,101,32,80, -67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, -101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, -110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, -10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, -62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, -111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, -98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79, -79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10, +73,68,67,95,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62, +10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, +68,67,95,67,79,77,66,79,68,82,73,86,69,84,89,80,69,34,32,115,116,97,114, +116,61,34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34,32,115,116, +97,114,116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32,115,116,97, +114,116,61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32,115,116,97, +114,116,61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116,97,114,116, +61,34,54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, +110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34,32,115,116, +97,114,116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,34, +32,115,116,97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67, +89,76,34,32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,84,69, +88,84,95,83,73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62, +10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, +68,67,95,72,68,68,95,76,65,66,69,76,34,32,115,116,97,114,116,61,34,49,49, +48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110, +102,105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101, +62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47,116,105,116, +108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47, +99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,73,68,67,95,78,79,84,69,66,79,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,68,69,70,65, +85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,109,111,116,104,101,114, +98,111,97,114,100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, -108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, -85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, -80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, -105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, -61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, -120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, -65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, -67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, -32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3161,341 +2734,35 @@ static unsigned char xml_res_file_26[] = { 101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, 105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, -73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, -60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, -115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, -83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, -62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99, +101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101, +116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -3523,30 +2790,490 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, +61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, 121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, 66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110, +97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111, +114,121,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67,116, +114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, +75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109, +105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, +77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, +79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, +122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, +99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, 101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, +105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, +103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, @@ -3556,47 +3283,327 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, 99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, 116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, 112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, -73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, +65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, +115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, +97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, -47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105, +118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69, +76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, +83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 216f19c..6b81cec 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -42,6 +42,8 @@ #include "wx-common.h" #include "wx-display.h" +extern void creatediscimage_open(void *hwnd); + #define ID_IS(s) wParam == wx_xrcid(s) #define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) @@ -856,6 +858,10 @@ int wx_handle_command(void* hwnd, int wParam, int checked) wx_checkmenuitem(hmenu, wParam, bpb_disable); saveconfig(NULL); } + else if (ID_IS("IDM_DISC_CREATE")) + { + creatediscimage_open(hwnd); + } else if (ID_IS("IDM_DISC_ZIP")) { char zip_fn[256] = ""; From d65368c0c0732421b4807bbb88585d07c9bd5c6d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Jan 2018 16:19:27 +0000 Subject: [PATCH 0285/1050] Add SCSI Write and Verify command to Zip drive. --- src/scsi.h | 1 + src/scsi_zip.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/scsi.h b/src/scsi.h index e824639..b290aec 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -67,6 +67,7 @@ void scsi_set_irq(uint8_t status); #define SCSI_READ_10 0x28 #define SCSI_WRITE_10 0x2a #define SCSI_SEEK_10 0x2b +#define SCSI_WRITE_AND_VERIFY 0x2e #define SCSI_VERIFY_10 0x2f #define SCSI_READ_BUFFER 0x3c #define SCSI_MODE_SENSE_10 0x5a diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 539a3b1..43cefc8 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -95,6 +95,7 @@ static uint8_t scsi_zip_cmd_flags[0x100] = [SCSI_READ_CAPACITY_10] = CHECK_READY, [SCSI_WRITE_6] = CHECK_READY, [SCSI_WRITE_10] = CHECK_READY, + [SCSI_WRITE_AND_VERIFY] = CHECK_READY, [SCSI_VERIFY_10] = CHECK_READY, [SCSI_FORMAT] = CHECK_READY, [SCSI_RESERVE] = 0, @@ -852,6 +853,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) break; case SCSI_WRITE_10: + case SCSI_WRITE_AND_VERIFY: if (data->read_only) { pclog("zip read only\n"); From 1dd96251c41567f34652619d2afe58809240ea24 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Jan 2018 16:19:50 +0000 Subject: [PATCH 0286/1050] Reduce amount of debug output from Zip drive emulation. --- src/scsi_zip.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 43cefc8..89a9386 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -216,7 +216,7 @@ static int scsi_add_data(uint8_t val, void *p) { scsi_zip_data *data = p; - pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); +// pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); data->data_in[data->data_pos_write++] = val; @@ -678,7 +678,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->len = cdb[4]; if (!data->len) data->len = 256; - pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); +// pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); data->cmd_pos = CMD_POS_WAIT; data->callback = RW_DELAY; @@ -738,7 +738,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) readflash_set(READFLASH_HDC, data->hd_id); data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); data->len = cdb[8] | (cdb[7] << 8); - pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); +// pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); data->cmd_pos = CMD_POS_WAIT; data->callback = RW_DELAY; @@ -805,7 +805,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) if (!data->len) data->len = 256; readflash_set(READFLASH_HDC, data->hd_id); - pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); +// pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); data->bytes_required = data->len * 512; data->cmd_pos = CMD_POS_WAIT; @@ -872,7 +872,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); data->len = cdb[8] | (cdb[7] << 8); readflash_set(READFLASH_HDC, data->hd_id); - pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); +// pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); data->bytes_required = data->len * 512; data->cmd_pos = CMD_POS_WAIT; From 25087bf4ec9c555cbdc828d9192d316a68e0d999 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Jan 2018 16:39:00 +0000 Subject: [PATCH 0287/1050] Strip RPCemu support code out of ide.c. --- src/ide.c | 288 ++++++------------------------------------------------ 1 file changed, 30 insertions(+), 258 deletions(-) diff --git a/src/ide.c b/src/ide.c index 3c80042..bff9b26 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1,7 +1,3 @@ -/*RPCemu v0.6 by Tom Walker - IDE emulation*/ -//#define RPCEMU_IDE - #define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) #define _LARGEFILE_SOURCE @@ -14,21 +10,15 @@ #include -#ifdef RPCEMU_IDE - #include "rpcemu.h" - #include "iomd.h" - #include "arm.h" -#else - #include "ibm.h" - #include "hdd.h" - #include "io.h" - #include "pic.h" - #include "timer.h" - #include "hdd_file.h" - #include "scsi.h" - #include "scsi_cd.h" - #include "scsi_zip.h" -#endif +#include "ibm.h" +#include "hdd.h" +#include "io.h" +#include "pic.h" +#include "timer.h" +#include "hdd_file.h" +#include "scsi.h" +#include "scsi_cd.h" +#include "scsi_zip.h" #include "ide.h" /* ATA Commands */ @@ -90,14 +80,8 @@ typedef struct IDE uint8_t sector_buffer[256*512]; int do_initial_read; int sector_pos; -#ifdef RPCEMU_IDE - FILE *hdfile; - int spt,hpc; - int tracks; -#else hdd_file_t hdd_file; atapi_device_t atapi; -#endif } IDE; int cdrom_channel = 2; @@ -123,15 +107,10 @@ void ide_irq_raise(IDE *ide) { // pclog("IDE_IRQ_RAISE\n"); if (!(ide->fdisk&2)) { -#ifdef RPCEMU_IDE - iomd.irqb.status |= IOMD_IRQB_IDE; - updateirqs(); -#else // if (ide->board && !ide->irqstat) pclog("IDE_IRQ_RAISE\n"); picint((ide->board)?(1<<15):(1<<14)); if (ide_bus_master_set_irq) ide_bus_master_set_irq(ide->board); -#endif } ide->irqstat=1; ide->service=1; @@ -141,34 +120,17 @@ static inline void ide_irq_lower(IDE *ide) { // pclog("IDE_IRQ_LOWER\n"); // if (ide.board == 0) { -#ifdef RPCEMU_IDE - iomd.irqb.status &= ~IOMD_IRQB_IDE; - updateirqs(); -#else picintc((ide->board)?(1<<15):(1<<14)); -#endif // } ide->irqstat=0; } void ide_irq_update(IDE *ide) { -#ifdef RPCEMU_IDE - if (ide->irqstat && !(iomd.irqb.status & IOMD_IRQB_IDE) && !(ide->fdisk & 2)) { - iomd.irqb.status |= IOMD_IRQB_IDE; - updateirqs(); - } - else if (iomd.irqb.status & IOMD_IRQB_IDE) - { - iomd.irqb.status &= ~IOMD_IRQB_IDE; - updateirqs(); - } -#else if (ide->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(ide->fdisk & 2)) picint((ide->board)?(1<<15):(1<<14)); else if ((pic2.pend|pic2.ins)&0x40) picintc((ide->board)?(1<<15):(1<<14)); -#endif } /** * Copy a string into a buffer, padding with spaces, and placing characters as @@ -202,22 +164,14 @@ static void ide_identify(IDE *ide) //ide->buffer[1] = 101; /* Cylinders */ -#ifdef RPCEMU_IDE - ide->buffer[1] = 65535; /* Cylinders */ - ide->buffer[3] = 16; /* Heads */ - ide->buffer[6] = 63; /* Sectors */ -#else 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 */ -#endif + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), "v1.0", 8); /* Firmware */ -#ifdef RPCEMU_IDE - ide_padstr((char *) (ide->buffer + 27), "RPCemuHD", 40); /* Model */ -#else ide_padstr((char *) (ide->buffer + 27), "PCemHD", 40); /* Model */ -#endif + ide->buffer[20] = 3; /*Buffer type*/ ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ @@ -227,13 +181,8 @@ static void ide_identify(IDE *ide) ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[52] = 2 << 8; /*DMA timing mode*/ ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; -#ifdef RPCEMU_IDE - ide->buffer[60] = (65535 * 16 * 63) & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = (65535 * 16 * 63) >> 16; -#else 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; -#endif ide->buffer[63] = 7; /*Multiword DMA*/ ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ } @@ -249,13 +198,9 @@ static off64_t ide_get_sector(IDE *ide) } else { -#ifdef RPCEMU_IDE - int heads = ide->hpc; - int sectors = ide->spt; -#else int heads = ide->hdd_file.hpc; int sectors = ide->hdd_file.spt; -#endif + return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (ide->sector - 1) + ide->skip512; } @@ -273,18 +218,12 @@ static void ide_next_sector(IDE *ide) else { ide->sector++; -#ifdef RPCEMU_IDE - if (ide->sector == (ide->spt + 1)) { -#else + if (ide->sector == (ide->hdd_file.spt + 1)) { -#endif ide->sector = 1; ide->head++; -#ifdef RPCEMU_IDE - if (ide->head == ide->hpc) { -#else + if (ide->head == ide->hdd_file.hpc) { -#endif ide->head = 0; ide->cylinder++; } @@ -292,61 +231,6 @@ static void ide_next_sector(IDE *ide) } } -#ifdef RPCEMU_IDE -static void loadhd(IDE *ide, int d, const char *fn) -{ - char pathname[512]; - - append_filename(pathname, rpcemu_get_datadir(), fn, 512); - - rpclog("Loading %s\n",pathname); - if (ide->hdfile == NULL) { - /* Try to open existing hard disk image */ - ide->hdfile = fopen64(pathname, "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 = fopen64(pathname, "wb+"); - if (ide->hdfile == NULL) { - fatal("Cannot create file '%s': %s", - pathname, strerror(errno)); - } - } else { - /* Failed for another reason */ - fatal("Cannot open file '%s': %s", - pathname, strerror(errno)); - } - } - } - - fseek(ide->hdfile, 0xfc1, SEEK_SET); - ide->spt = getc(ide->hdfile); - ide->hpc = getc(ide->hdfile); - ide->skip512 = 1; -// rpclog("First check - spt %i hpc %i\n",ide.spt[0],ide.hpc[0]); - if (!ide->spt || !ide->hpc) - { - fseek(ide->hdfile, 0xdc1, SEEK_SET); - ide->spt = getc(ide->hdfile); - ide->hpc = getc(ide->hdfile); -// rpclog("Second check - spt %i hpc %i\n",ide.spt[0],ide.hpc[0]); - ide->skip512 = 0; - if (!ide->spt || !ide->hpc) - { - ide->spt=63; - ide->hpc=16; - ide->skip512 = 1; -// rpclog("Final check - spt %i hpc %i\n",ide.spt[0],ide.hpc[0]); - } - } - - ide->type = IDE_HDD; - - rpclog("%i %i %i\n",ide->spt,ide->hpc,ide->skip512); -} -#else static void loadhd(IDE *ide, int d, const char *fn) { hdd_load(&ide->hdd_file, d, fn); @@ -356,7 +240,6 @@ static void loadhd(IDE *ide, int d, const char *fn) else ide->type = IDE_NONE; } -#endif void ide_set_signature(IDE *ide) { @@ -374,14 +257,8 @@ void resetide(void) /* Close hard disk image files (if previously open) */ for (d = 0; d < 4; d++) { ide_drives[d].type = IDE_NONE; -#ifdef RPCEMU_IDE - if (ide_drives[d].hdfile != NULL) { - fclose(ide_drives[d].hdfile); - ide_drives[d].hdfile = NULL; - } -#else hdd_close(&ide_drives[d].hdd_file); -#endif + ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; ide_drives[d].board = (d & 2) ? 1 : 0; @@ -390,13 +267,6 @@ void resetide(void) idecallback[0]=idecallback[1]=0; if (hdd_controller_current_is_ide()) { -#ifdef RPCEMU_IDE - loadhd(&ide_drives[0], 0, "hd4.hdf"); - if (!config.cdromenabled) - loadhd(&ide_drives[1], 1, "hd5.hdf"); - else - ide_drives[1].type = IDE_CDROM; -#else for (d = 0; d < 4; d++) { ide_drives[d].drive = d; @@ -425,7 +295,6 @@ void resetide(void) ide_drives[d].atapi.cylinder = &ide_drives[d].cylinder; } } -#endif cur_ide[0] = 0; @@ -438,16 +307,6 @@ void writeidew(int ide_board, uint16_t val) { IDE *ide = &ide_drives[cur_ide[ide_board]]; -#ifndef RPCEMU_IDE -/* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) - { -// pclog("Failed write IDE %04X:%08X\n",CS,pc); - return; - }*/ -#endif -#ifdef _RPCEMU_BIG_ENDIAN - val=(val>>8)|(val<<8); -#endif if (ide->command == WIN_PACKETCMD) { atapi_data_write(&ide->atapi, val); @@ -482,15 +341,15 @@ 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]; -#ifndef RPCEMU_IDE + /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) { // pclog("Failed write IDE %04X:%08X\n",CS,pc); return; }*/ -#endif // if ((cr0&1) && !(eflags&VM_FLAG)) -// pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, pc, ins); +// if (ide_board) +// pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, cpu_state.pc, ins); // return; addr|=0x80; // if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat); @@ -784,13 +643,12 @@ uint8_t readide(int ide_board, uint16_t addr) uint16_t tempw; addr|=0x80; -#ifndef RPCEMU_IDE + /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) { // pclog("Failed read IDE %04X:%08X\n",CS,pc); return 0xFF; }*/ -#endif // if ((cr0&1) && !(eflags&VM_FLAG)) // pclog("ReadIDE %04X from %04X(%08X):%08X\n", addr, CS, cs, pc); // return 0xFF; @@ -894,7 +752,7 @@ 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,pc,ide_board); +// 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); return temp; // fatal("Bad IDE read %04X\n", addr); } @@ -903,13 +761,12 @@ uint16_t readidew(int ide_board) { IDE *ide = &ide_drives[cur_ide[ide_board]]; uint16_t temp; -#ifndef RPCEMU_IDE + /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) { // pclog("Failed read IDEw %04X:%08X\n",CS,pc); return 0xFFFF; }*/ -#endif // return 0xFFFF; // pclog("Read IDEw %04X %04X:%04X %02X %i %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins, ide->pos); @@ -947,9 +804,6 @@ uint16_t readidew(int ide_board) } } } -#ifdef _RPCEMU_BIG_ENDIAN - temp=(temp>>8)|(temp<<8); -#endif // pclog("Read IDEw %04X\n",temp); return temp; } @@ -968,10 +822,7 @@ void callbackide(int ide_board) IDE *ide = &ide_drives[cur_ide[ide_board]]; IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; atapi_device_t *atapi_dev = &ide->atapi; -#if RPCEMU_IDE - off64_t addr; - int c; -#endif + ext_ide = ide; // return; if (ide->command==0x30) times30++; @@ -1048,16 +899,7 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; -#ifdef RPCEMU_IDE - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, addr, SEEK_SET); - if (ide->secount) - fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); - else - fread(ide->sector_buffer, 256*512, 1, ide->hdfile); -#else hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); -#endif } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); ide->sector_pos++; @@ -1071,9 +913,8 @@ void callbackide(int ide_board) // 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; ide_irq_raise(ide); -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_READ_DMA: @@ -1084,16 +925,7 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; -#ifdef RPCEMU_IDE - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, addr, SEEK_SET); - if (ide->secount) - fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); - else - fread(ide->sector_buffer, 256*512, 1, ide->hdfile); -#else hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); -#endif } ide->pos=0; @@ -1120,9 +952,8 @@ void callbackide(int ide_board) } } } -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_READ_MULTIPLE: @@ -1133,16 +964,7 @@ void callbackide(int ide_board) { ide->do_initial_read = 0; ide->sector_pos = 0; -#ifdef RPCEMU_IDE - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, addr, SEEK_SET); - if (ide->secount) - fread(ide->sector_buffer, ide->secount*512, 1, ide->hdfile); - else - fread(ide->sector_buffer, 256*512, 1, ide->hdfile); -#else hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); -#endif } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); ide->sector_pos++; @@ -1156,9 +978,8 @@ void callbackide(int ide_board) ide->blockcount++; if (ide->blockcount >= ide->blocksize) ide->blockcount = 0; -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_WRITE: @@ -1166,14 +987,7 @@ void callbackide(int ide_board) if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } -#ifdef RPCEMU_IDE - addr = ide_get_sector(ide) * 512; -// pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); - fseeko64(ide->hdfile, addr, SEEK_SET); - fwrite(ide->buffer, 512, 1, ide->hdfile); -#else hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); -#endif ide_irq_raise(ide); ide->secount = (ide->secount - 1) & 0xff; if (ide->secount) @@ -1184,9 +998,8 @@ void callbackide(int ide_board) } else ide->atastat = READY_STAT | DSC_STAT; -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_WRITE_DMA: @@ -1201,13 +1014,7 @@ void callbackide(int ide_board) else { /*DMA successful*/ -#ifdef RPCEMU_IDE - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, addr, SEEK_SET); - fwrite(ide->buffer, 512, 1, ide->hdfile); -#else hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); -#endif ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1224,23 +1031,15 @@ void callbackide(int ide_board) } } } -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_WRITE_MULTIPLE: if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } -#ifdef RPCEMU_IDE - addr = ide_get_sector(ide) * 512; -// pclog("Write sector callback %i %i %i offset %08X %i left %i\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt); - fseeko64(ide->hdfile, addr, SEEK_SET); - fwrite(ide->buffer, 512, 1, ide->hdfile); -#else hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); -#endif ide->blockcount++; if (ide->blockcount >= ide->blocksize || ide->secount == 1) { @@ -1256,9 +1055,8 @@ void callbackide(int ide_board) } else ide->atastat = READY_STAT | DSC_STAT; -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_VERIFY: @@ -1270,32 +1068,19 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; // pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); ide_irq_raise(ide); -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_FORMAT: if (IDE_DRIVE_IS_CDROM(ide)) { goto abort_cmd; } -#ifdef RPCEMU_IDE - 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); - fseeko64(ide->hdfile, addr, SEEK_SET); - memset(ide->buffer, 0, 512); - for (c=0;csecount;c++) - { - fwrite(ide->buffer, 512, 1, ide->hdfile); - } -#else hdd_format_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount); -#endif ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); -#ifndef RPCEMU_IDE + readflash_set(READFLASH_HDC, ide->drive); -#endif return; case WIN_DRIVE_DIAGNOSTICS: @@ -1314,22 +1099,13 @@ void callbackide(int ide_board) case WIN_SPECIFY: /* Initialize Drive Parameters */ if (IDE_DRIVE_IS_CDROM(ide)) { -#ifndef RPCEMU_IDE pclog("IS CDROM - ABORT\n"); -#endif goto abort_cmd; } -#if RPCEMU_IDE - ide->spt = ide->secount; - ide->hpc = ide->head+1; -#else ide->hdd_file.spt = ide->secount; ide->hdd_file.hpc = ide->head+1; -#endif ide->atastat = READY_STAT | DSC_STAT; -#ifndef RPCEMU_IDE // pclog("SPECIFY - %i sectors per track, %i heads per cylinder %i %i\n",ide->spt,ide->hpc,cur_ide[ide_board],ide_board); -#endif ide_irq_raise(ide); return; @@ -1349,16 +1125,12 @@ void callbackide(int ide_board) case WIN_SET_MULTIPLE_MODE: if (IDE_DRIVE_IS_CDROM(ide)) { -#ifndef RPCEMU_IDE pclog("IS CDROM - ABORT\n"); -#endif goto abort_cmd; } ide->blocksize = ide->secount; ide->atastat = READY_STAT | DSC_STAT; -#ifndef RPCEMU_IDE pclog("Set multiple mode - %i\n", ide->blocksize); -#endif ide_irq_raise(ide); return; From 966e787a25163c6b1764508c7987e3e1d9819ed2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Jan 2018 21:31:37 +0000 Subject: [PATCH 0288/1050] FDC Sense Interrupt Status doesn't send track number when no interrupt pending. Fixes floppy drive on early Linux kernels. --- src/fdc.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index 948df5b..6bc6e52 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -63,6 +63,8 @@ typedef struct FDC int fifo, tfifo; int fifobufpos; uint8_t fifobuf[16]; + + int int_pending; } FDC; static FDC fdc; @@ -464,13 +466,24 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.stat=0x90; break; case 8: /*Sense interrupt status*/ -// 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(); + if (fdc.int_pending || fdc_reset_stat) + { +// 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(); + } + else + { + fdc.stat=0x10; + discint=0xfc; + timer_process(); + disctime = 200 * (1 << TIMER_SHIFT); + timer_update_outstanding(); + } break; case 10: /*Read sector ID*/ fdc.pnum=0; @@ -967,6 +980,7 @@ void fdc_callback() fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdc.head?4:0); else fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head?4:0); + fdc.int_pending = 1; discint=-3; timer_process(); disctime = 2048 * (1 << TIMER_SHIFT); @@ -987,7 +1001,7 @@ void fdc_callback() if (fdc_reset_stat) fdc_reset_stat--; if (!fdc_reset_stat) - fdc.st0 = 0x80; + fdc.int_pending = 0; paramstogo = 2; discint = 0; @@ -1053,6 +1067,7 @@ void fdc_callback() fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdc.head?4:0); else fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head?4:0); + fdc.int_pending = 1; discint=-3; timer_process(); disctime = 2048 * (1 << TIMER_SHIFT); From 604dce908b29d958fea7d5ecdacf3a8817f37de2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 27 Jan 2018 13:52:43 +0000 Subject: [PATCH 0289/1050] SCAT improvements : - Improved ROMCS mapping on top address area. - Changed SCAT chipset revision. - DMA wait control state register is now writable. Patch from Greatpsycho. --- src/scat.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/scat.c b/src/scat.c index 84aa492..966814f 100644 --- a/src/scat.c +++ b/src/scat.c @@ -243,6 +243,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) case 0x23: switch (scat_index) { + case SCAT_DMA_WAIT_STATE_CONTROL: case SCAT_CLOCK_CONTROL: case SCAT_PERIPHERAL_CONTROL: scat_reg_valid = 1; @@ -529,7 +530,7 @@ void scat_init() } scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; - scat_regs[SCAT_VERSION] = 10; + scat_regs[SCAT_VERSION] = 4; scat_regs[SCAT_CLOCK_CONTROL] = 2; scat_regs[SCAT_PERIPHERAL_CONTROL] = 0x80; scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; @@ -568,7 +569,7 @@ void scat_init() // 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); + 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) & biosmask), 0, NULL); } for(i=0;i<6;i++) @@ -633,7 +634,7 @@ void scatsx_init() // 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); + 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) & biosmask), 0, NULL); } for(i=0;i<6;i++) From 3b335f32aaecb7adf8b5036ba9aefa2fe9edf9a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 27 Jan 2018 14:56:14 +0000 Subject: [PATCH 0290/1050] Add default video timing option. Patch from leilei. --- src/pc.c | 2 +- src/video.c | 121 +++++++++++++++++++++++++++++------------------- src/wx-config.c | 5 +- 3 files changed, 78 insertions(+), 50 deletions(-) diff --git a/src/pc.c b/src/pc.c index 3a78b8b..4752655 100644 --- a/src/pc.c +++ b/src/pc.c @@ -700,7 +700,7 @@ void loadconfig(char *fn) gfxcard = video_get_video_from_internal_name(p); else gfxcard = 0; - video_speed = config_get_int(CFG_MACHINE, NULL, "video_speed", 3); + video_speed = config_get_int(CFG_MACHINE, NULL, "video_speed", -1); p = (char *)config_get_string(CFG_MACHINE, NULL, "sndcard", ""); if (p) sound_card_current = sound_card_get_from_internal_name(p); diff --git a/src/video.c b/src/video.c index 952828e..43b8d23 100644 --- a/src/video.c +++ b/src/video.c @@ -44,43 +44,54 @@ #include "vid_t3100e.h" #include "vid_t1000.h" +enum +{ + VIDEO_ISA = 0, + VIDEO_BUS +}; + typedef struct { char name[64]; char internal_name[24]; device_t *device; int legacy_id; + struct + { + int type; + int b, w, l; + } timing; } VIDEO_CARD; static VIDEO_CARD video_cards[] = { - {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX}, - {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2}, - {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER}, - {"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 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE}, - {"EGA", "ega", &ega_device, GFX_EGA}, - {"Hercules", "hercules", &hercules_device, GFX_HERCULES}, - {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR}, - {"MDA", "mda", &mda_device, GFX_MDA}, - {"MDSI Genius", "genius", &genius_device, GFX_GENIUS}, - {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX}, - {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067}, - {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481}, - {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64}, - {"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 TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA}, - {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000}, - {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440}, - {"VGA", "vga", &vga_device, GFX_VGA}, - {"Wyse 700", "wy700", &wy700_device, GFX_WY700}, - {"", "", NULL, 0} + {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, {VIDEO_BUS, 4, 8, 16}}, + {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, {VIDEO_BUS, 3, 3, 4}}, + {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, {VIDEO_ISA, 3, 3, 6}}, + {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 3, 3, 6}}, + {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32}}, + {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_ISA, 3, 3, 6}}, + {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 5, 10}}, + {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 3, 5, 10}}, + {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32}}, + {"Hercules", "hercules", &hercules_device, GFX_HERCULES, {VIDEO_ISA, 8, 16, 32}}, + {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, {VIDEO_ISA, 8, 16, 32}}, + {"MDA", "mda", &mda_device, GFX_MDA, {VIDEO_ISA, 8, 16, 32}}, + {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, {VIDEO_ISA, 8, 16, 32}}, + {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, {VIDEO_BUS, 3, 5, 10}}, + {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, {VIDEO_ISA, 6, 8, 16}}, + {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, {VIDEO_ISA, 6, 8, 16}}, + {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, {VIDEO_BUS, 4, 5, 10}}, + {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, {VIDEO_BUS, 4, 5, 10}}, + {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, {VIDEO_BUS, 3, 5, 10}}, + {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, {VIDEO_ISA, 8, 16, 32}}, + {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, {VIDEO_BUS, 2, 3, 4}}, + {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, {VIDEO_ISA, 3, 3, 6}}, + {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, {VIDEO_ISA, 3, 3, 6}}, + {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, {VIDEO_BUS, 4, 8, 16}}, + {"VGA", "vga", &vga_device, GFX_VGA, {VIDEO_ISA, 8, 16, 32}}, + {"Wyse 700", "wy700", &wy700_device, GFX_WY700, {VIDEO_ISA, 8, 16, 32}}, + {"", "", NULL, 0} }; int video_card_available(int card) @@ -210,14 +221,8 @@ Fast VLB/PCI - L = 4 bus clocks */ -enum -{ - VIDEO_ISA = 0, - VIDEO_BUS -}; - int video_speed = 0; -int video_timing[6][4] = +int video_timing[7][4] = { {VIDEO_ISA, 8, 16, 32}, {VIDEO_ISA, 6, 8, 16}, @@ -229,20 +234,42 @@ int video_timing[6][4] = void video_updatetiming() { - if (video_timing[video_speed][0] == VIDEO_ISA) - { - video_timing_b = (int)(isa_timing * video_timing[video_speed][1]); - video_timing_w = (int)(isa_timing * video_timing[video_speed][2]); - video_timing_l = (int)(isa_timing * video_timing[video_speed][3]); + if (video_speed == -1) + { + int new_gfxcard = video_old_to_new(gfxcard); + + if (video_cards[new_gfxcard].timing.type == VIDEO_ISA) + { + video_timing_b = (int)(isa_timing * video_cards[new_gfxcard].timing.b); + video_timing_w = (int)(isa_timing * video_cards[new_gfxcard].timing.w); + video_timing_l = (int)(isa_timing * video_cards[new_gfxcard].timing.l); + } + else + { + video_timing_b = (int)(bus_timing * video_cards[new_gfxcard].timing.b); + video_timing_w = (int)(bus_timing * video_cards[new_gfxcard].timing.w); + video_timing_l = (int)(bus_timing * video_cards[new_gfxcard].timing.l); + } + if (cpu_16bitbus) + video_timing_l = video_timing_w * 2; + } + else + { + if (video_timing[video_speed][0] == VIDEO_ISA) + { + video_timing_b = (int)(isa_timing * video_timing[video_speed][1]); + video_timing_w = (int)(isa_timing * video_timing[video_speed][2]); + video_timing_l = (int)(isa_timing * video_timing[video_speed][3]); + } + else + { + video_timing_b = (int)(bus_timing * video_timing[video_speed][1]); + video_timing_w = (int)(bus_timing * video_timing[video_speed][2]); + video_timing_l = (int)(bus_timing * video_timing[video_speed][3]); + } + if (cpu_16bitbus) + video_timing_l = video_timing_w * 2; } - else - { - video_timing_b = (int)(bus_timing * video_timing[video_speed][1]); - video_timing_w = (int)(bus_timing * video_timing[video_speed][2]); - video_timing_l = (int)(bus_timing * video_timing[video_speed][3]); - } - if (cpu_16bitbus) - video_timing_l = video_timing_w * 2; } int video_timing_b, video_timing_w, video_timing_l; diff --git a/src/wx-config.c b/src/wx-config.c index 806f52e..40f5abd 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -469,7 +469,7 @@ int config_dlgsave(void* hdlg) } h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); - video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0) - 1; cpu_manufacturer = temp_cpu_m; cpu = temp_cpu; @@ -592,13 +592,14 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Default"); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "8-bit"); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow 16-bit"); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast 16-bit"); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow VLB/PCI"); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Mid VLB/PCI"); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast VLB/PCI"); - wx_sendmessage(h, WX_CB_SETCURSEL, video_speed, 0); + wx_sendmessage(h, WX_CB_SETCURSEL, video_speed+1, 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); printf("%d\n", models[model].ram_granularity); From b9f196d641cde7a84ff3bc28cedb7606acc779b2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 20:01:18 +0000 Subject: [PATCH 0291/1050] ISA timing now based on integer ATCLK instead of fixed point division. --- src/cpu.c | 366 +++++++++++++++++++++++++++--------------------------- src/cpu.h | 4 +- 2 files changed, 185 insertions(+), 185 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 1572d5a..95bc194 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -132,254 +132,254 @@ static struct 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}, - {"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}, + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_pcjr[] = { /*8088 PCjr*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 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}, + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_8086[] = { /*8086 standard*/ - {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, - {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, - {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, - {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, - {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, {"", -1, 0, 0, 0, 0} }; CPU cpus_pc1512[] = { /*8086 Amstrad*/ - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_286[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2}, - {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2}, - {"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}, + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ibmat[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3}, - {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3}, + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ibmxt286[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2}, + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ps1_m2011[] = { /*286*/ - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2}, + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, {"", -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}, + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, {"", -1, 0, 0, 0, 0} }; CPU cpus_i386SX[] = { /*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/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, {"", -1, 0, 0, 0} }; CPU cpus_i386DX[] = { /*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}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3}, + {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, {"", -1, 0, 0, 0} }; CPU cpus_acer[] = { /*i386SX*/ - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4}, + {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3}, {"", -1, 0, 0, 0} }; CPU cpus_Am386SX[] = { /*Am386*/ - {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3}, - {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3}, - {"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}, + {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, {"", -1, 0, 0, 0} }; CPU cpus_Am386DX[] = { /*Am386*/ - {"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}, + {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, {"", -1, 0, 0, 0} }; CPU cpus_486SLC[] = { /*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}, + {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 2*2}, + {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, + {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, {"", -1, 0, 0, 0} }; CPU cpus_486DLC[] = { /*Cx486DLC*/ - {"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}, + {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3}, + {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4}, + {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5}, + {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 2*2}, + {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, + {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, + {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 2*4}, {"", -1, 0, 0, 0} }; CPU cpus_i486[] = { /*i486*/ - {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3}, - {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3}, - {"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}, - {"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}, - {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, - {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, - {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, - {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7}, - {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8}, + {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2}, + {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, + {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, (5*3)/2}, + {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, (5*4)/2}, {"", -1, 0, 0, 0} }; CPU cpus_Am486[] = { /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3}, - {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3}, - {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ - {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3}, - {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3}, - {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, - {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, - {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6}, - {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, - {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9}, - {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9}, - {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9}, - {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12}, - {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12}, + {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 2*5}, + {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, + {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, + {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, + {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 4*5}, {"", -1, 0, 0, 0} }; CPU cpus_Cx486[] = { /*Cx486/5x86*/ - {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3}, - {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3}, - {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3}, - {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3}, - {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3}, - {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, - {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, - {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16}, - {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9}, - {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9}, - {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9}, - {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9}, - {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12}, + {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 2*5}, + {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, + {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, + {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, {"", -1, 0, 0, 0} }; CPU cpus_6x86[] = { /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6}, - {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6}, - {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6}, - {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, + {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, + {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6}, - {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, + {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7}, - {"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-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, + {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, + {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, + {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, {"", -1, 0, 0, 0} }; @@ -388,81 +388,81 @@ CPU cpus_Cx486[] = CPU cpus_WinChip[] = { /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4}, - {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4}, - {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4}, - {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, - {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6}, - {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7}, - {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7}, - {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12}, + {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, (3*6)/2}, + {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*7)/2}, + {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*8)/2}, + {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*7}, + {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*8}, + {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*7)/2}, + {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2}, + {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7}, + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, {"", -1, 0, 0, 0} }; CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3}, - {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3}, - {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, + {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, + {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, {"", -1, 0, 0, 0} }; CPU cpus_PentiumS5[] = { /*Intel Pentium (Socket 5)*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, + {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, + {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, + {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, + {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, {"", -1, 0, 0, 0} }; CPU cpus_Pentium[] = { /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, - {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, - {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10}, - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, + {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, + {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, + {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, + {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 4*8}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, (9*8)/2}, + {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, {"", -1, 0, 0, 0} }; @@ -502,8 +502,8 @@ void cpu_set() ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; cpu_update_waitstates(); - - isa_cycles = (int)(((int64_t)cpu_s->rspeed << ISA_CYCLES_SHIFT) / 8000000ll); + + isa_cycles = cpu_s->atclk_div; if (cpu_s->pci_speed) { diff --git a/src/cpu.h b/src/cpu.h index 2b26555..20cfd53 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -68,6 +68,7 @@ typedef struct int cpu_flags; int mem_read_cycles, mem_write_cycles; int cache_read_cycles, cache_write_cycles; + int atclk_div; } CPU; extern CPU cpus_8088[]; @@ -140,9 +141,8 @@ extern int cpu_use_dynarec; extern int xt_cpu_multi; -#define ISA_CYCLES_SHIFT 6 extern int isa_cycles; -#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT) +#define ISA_CYCLES(x) (x * isa_cycles) void cpu_update_waitstates(); void cpu_set(); From ca4d8e9ffe04f78ce021f35acaca6cd6a2a1595d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 20:02:54 +0000 Subject: [PATCH 0292/1050] Mach64 now supports SVGA word/longword accesses. --- src/vid_ati_mach64.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 6f92116..f997892 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -293,7 +293,11 @@ enum }; void mach64_write(uint32_t addr, uint8_t val, void *priv); +void mach64_writew(uint32_t addr, uint16_t val, void *priv); +void mach64_writel(uint32_t addr, uint32_t val, void *priv); uint8_t mach64_read(uint32_t addr, void *priv); +uint16_t mach64_readw(uint32_t addr, void *priv); +uint32_t mach64_readl(uint32_t addr, void *priv); void mach64_updatemapping(mach64_t *mach64); void mach64_recalctimings(svga_t *svga); void mach64_start_fill(mach64_t *mach64); @@ -497,14 +501,14 @@ void mach64_updatemapping(mach64_t *mach64) switch (svga->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL); + mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); mem_mapping_set_p(&mach64->svga.mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_enable(&mach64->mmio_mapping); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL); + mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); mem_mapping_set_p(&mach64->svga.mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; @@ -2825,6 +2829,22 @@ void mach64_write(uint32_t addr, uint8_t val, void *p) // pclog("%08X\n", addr); svga_write_linear(addr, val, svga); } +void mach64_writew(uint32_t addr, uint16_t val, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; + + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_writew_linear(addr, val, svga); +} +void mach64_writel(uint32_t addr, uint32_t val, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; + + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_writel_linear(addr, val, svga); +} uint8_t mach64_read(uint32_t addr, void *p) { @@ -2837,6 +2857,22 @@ uint8_t mach64_read(uint32_t addr, void *p) // pclog("%08X %02X\n", addr, ret); return ret; } +uint16_t mach64_readw(uint32_t addr, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; + + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + return svga_readw_linear(addr, svga); +} +uint32_t mach64_readl(uint32_t addr, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; + + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + return svga_readl_linear(addr, svga); +} void mach64_hwcursor_draw(svga_t *svga, int displine) { From 26fb271fdc10a20760781216716cc27ba0e5d492 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 20:03:14 +0000 Subject: [PATCH 0293/1050] Paradise now supports SVGA word accesses. --- src/vid_paradise.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 80347e6..e8ad9a2 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -30,11 +30,8 @@ typedef struct paradise_t uint32_t read_bank[4], write_bank[4]; } paradise_t; -void paradise_write(uint32_t addr, uint8_t val, void *p); -uint8_t paradise_read(uint32_t addr, void *p); void paradise_remap(paradise_t *paradise); - void paradise_out(uint16_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; @@ -236,7 +233,7 @@ void paradise_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; } -void paradise_write(uint32_t addr, uint8_t val, void *p) +static void paradise_write(uint32_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; // pclog("paradise_write : %05X %02X ", addr, val); @@ -244,8 +241,14 @@ void paradise_write(uint32_t addr, uint8_t val, void *p) // pclog("%08X\n", addr); svga_write_linear(addr, val, ¶dise->svga); } +static void paradise_writew(uint32_t addr, uint16_t val, void *p) +{ + paradise_t *paradise = (paradise_t *)p; + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + svga_writew_linear(addr, val, ¶dise->svga); +} -uint8_t paradise_read(uint32_t addr, void *p) +static uint8_t paradise_read(uint32_t addr, void *p) { paradise_t *paradise = (paradise_t *)p; // pclog("paradise_read : %05X ", addr); @@ -253,6 +256,12 @@ uint8_t paradise_read(uint32_t addr, void *p) // pclog("%08X\n", addr); return svga_read_linear(addr, ¶dise->svga); } +static uint16_t paradise_readw(uint32_t addr, void *p) +{ + paradise_t *paradise = (paradise_t *)p; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + return svga_readw_linear(addr, ¶dise->svga); +} void *paradise_pvga1a_init() { @@ -268,7 +277,7 @@ void *paradise_pvga1a_init() NULL, NULL); - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, NULL, NULL, paradise_write, NULL, NULL); + mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); mem_mapping_set_p(¶dise->svga.mapping, paradise); svga->crtc[0x31] = 'W'; @@ -299,7 +308,7 @@ void *paradise_wd90c11_init() NULL, NULL); - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, NULL, NULL, paradise_write, NULL, NULL); + mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); mem_mapping_set_p(¶dise->svga.mapping, paradise); svga->crtc[0x31] = 'W'; From 475f51ba0f287592dd4bee57549856418e71902b Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 21:09:11 +0000 Subject: [PATCH 0294/1050] Video timing improvements : - Separated read and write timings - Added timings for onboard video chips - Updated timings based on VIDSPEED testing --- src/vid_cl5429.c | 4 +- src/vid_ega.c | 8 +- src/vid_svga.c | 48 ++++++------ src/video.c | 196 +++++++++++++++++++++++++++++++++++------------ src/video.h | 3 +- 5 files changed, 178 insertions(+), 81 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 15a805d..e31378c 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -333,8 +333,8 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) uint8_t vala, valb, valc, vald, wm = svga->writemask; int writemask2 = svga->writemask; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; egawrites++; diff --git a/src/vid_ega.c b/src/vid_ega.c index 6531b0b..3805012 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -696,8 +696,8 @@ void ega_write(uint32_t addr, uint8_t val, void *p) int writemask2 = ega->writemask; egawrites++; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; if (addr >= 0xB0000) addr &= 0x7fff; else addr &= 0xffff; @@ -835,8 +835,8 @@ uint8_t ega_read(uint32_t addr, void *p) int readplane = ega->readplane; egareads++; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; // pclog("Readega %06X ",addr); if (addr >= 0xb0000) addr &= 0x7fff; else addr &= 0xffff; diff --git a/src/vid_svga.c b/src/vid_svga.c index 072861f..ab984a1 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -773,8 +773,8 @@ void svga_write(uint32_t addr, uint8_t val, void *p) egawrites++; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; if (svga_output) pclog("Writeega %06X ",addr); addr &= svga->banked_mask; @@ -959,8 +959,8 @@ uint8_t svga_read(uint32_t addr, void *p) uint32_t latch_addr; int readplane = svga->readplane; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; egareads++; // pclog("Readega %06X ",addr); @@ -1035,8 +1035,8 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) uint8_t vala, valb, valc, vald, wm = svga->writemask; int writemask2 = svga->writemask; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; egawrites++; @@ -1217,8 +1217,8 @@ uint8_t svga_read_linear(uint32_t addr, void *p) uint8_t temp, temp2, temp3, temp4; int readplane = svga->readplane; - cycles -= video_timing_b; - cycles_lost += video_timing_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; egareads++; @@ -1311,8 +1311,8 @@ void svga_writew(uint32_t addr, uint16_t val, void *p) egawrites += 2; - cycles -= video_timing_w; - cycles_lost += video_timing_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; if (svga_output) pclog("svga_writew: %05X ", addr); addr = (addr & svga->banked_mask) + svga->write_bank; @@ -1340,8 +1340,8 @@ void svga_writel(uint32_t addr, uint32_t val, void *p) egawrites += 4; - cycles -= video_timing_l; - cycles_lost += video_timing_l; + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; if (svga_output) pclog("svga_writel: %05X ", addr); addr = (addr & svga->banked_mask) + svga->write_bank; @@ -1364,8 +1364,8 @@ uint16_t svga_readw(uint32_t addr, void *p) egareads += 2; - cycles -= video_timing_w; - cycles_lost += video_timing_w; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; // pclog("Readw %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; @@ -1386,8 +1386,8 @@ uint32_t svga_readl(uint32_t addr, void *p) egareads += 4; - cycles -= video_timing_l; - cycles_lost += video_timing_l; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; // pclog("Readl %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; @@ -1412,8 +1412,8 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *p) egawrites += 2; - cycles -= video_timing_w; - cycles_lost += video_timing_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val); addr &= svga->decode_mask; @@ -1439,8 +1439,8 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p) egawrites += 4; - cycles -= video_timing_l; - cycles_lost += video_timing_l; + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); addr &= svga->decode_mask; @@ -1460,8 +1460,8 @@ uint16_t svga_readw_linear(uint32_t addr, void *p) egareads += 2; - cycles -= video_timing_w; - cycles_lost += video_timing_w; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -1479,8 +1479,8 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) egareads += 4; - cycles -= video_timing_l; - cycles_lost += video_timing_l; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) diff --git a/src/video.c b/src/video.c index 43b8d23..325361f 100644 --- a/src/video.c +++ b/src/video.c @@ -50,50 +50,66 @@ enum VIDEO_BUS }; +typedef struct +{ + int type; + int write_b, write_w, write_l; + int read_b, read_w, read_l; +} video_timings_t; + typedef struct { char name[64]; char internal_name[24]; device_t *device; int legacy_id; - struct - { - int type; - int b, w, l; - } timing; + video_timings_t timing; } VIDEO_CARD; static VIDEO_CARD video_cards[] = { - {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, {VIDEO_BUS, 4, 8, 16}}, - {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, {VIDEO_BUS, 3, 3, 4}}, - {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, {VIDEO_ISA, 3, 3, 6}}, - {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 3, 3, 6}}, - {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32}}, - {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_ISA, 3, 3, 6}}, - {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 5, 10}}, - {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 3, 5, 10}}, - {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32}}, - {"Hercules", "hercules", &hercules_device, GFX_HERCULES, {VIDEO_ISA, 8, 16, 32}}, - {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, {VIDEO_ISA, 8, 16, 32}}, - {"MDA", "mda", &mda_device, GFX_MDA, {VIDEO_ISA, 8, 16, 32}}, - {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, {VIDEO_ISA, 8, 16, 32}}, - {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, {VIDEO_BUS, 3, 5, 10}}, - {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, {VIDEO_ISA, 6, 8, 16}}, - {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, {VIDEO_ISA, 6, 8, 16}}, - {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, {VIDEO_BUS, 4, 5, 10}}, - {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, {VIDEO_BUS, 4, 5, 10}}, - {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, {VIDEO_BUS, 3, 5, 10}}, - {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, {VIDEO_ISA, 8, 16, 32}}, - {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, {VIDEO_BUS, 2, 3, 4}}, - {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, {VIDEO_ISA, 3, 3, 6}}, - {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, {VIDEO_ISA, 3, 3, 6}}, - {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, {VIDEO_BUS, 4, 8, 16}}, - {"VGA", "vga", &vga_device, GFX_VGA, {VIDEO_ISA, 8, 16, 32}}, - {"Wyse 700", "wy700", &wy700_device, GFX_WY700, {VIDEO_ISA, 8, 16, 32}}, + {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_ISA, 3, 3, 6, 3, 3, 6}}, + {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Hercules", "hercules", &hercules_device, GFX_HERCULES, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"MDA", "mda", &mda_device, GFX_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, + {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"VGA", "vga", &vga_device, GFX_VGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Wyse 700", "wy700", &wy700_device, GFX_WY700, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"", "", NULL, 0} }; +static video_timings_t timing_dram = {VIDEO_BUS, 0,0,0, 0,0,0}; /*No additional waitstates*/ +static video_timings_t timing_pc1512 = {VIDEO_BUS, 0,0,0, 0,0,0}; /*PC1512 video code handles waitstates itself*/ +static video_timings_t timing_pc1640 = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_pc200 = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_m24 = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_pvga1a = {VIDEO_ISA, 6, 8,16, 6, 8,16}; +static video_timings_t timing_wd90c11 = {VIDEO_ISA, 3, 3, 6, 5, 5,10}; +static video_timings_t timing_oti067 = {VIDEO_ISA, 6, 8,16, 6, 8,16}; +static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; +static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; + int video_card_available(int card) { if (video_cards[card].device) @@ -236,43 +252,123 @@ void video_updatetiming() { if (video_speed == -1) { - int new_gfxcard = video_old_to_new(gfxcard); + video_timings_t *timing; + int new_gfxcard = 0; - if (video_cards[new_gfxcard].timing.type == VIDEO_ISA) + switch (romset) + { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + timing = &timing_dram; + break; + + case ROM_PC1512: + timing = &timing_pc1512; + break; + + case ROM_PC1640: + timing = &timing_pc1640; + break; + + case ROM_PC200: + timing = &timing_pc200; + break; + + case ROM_OLIM24: + timing = &timing_m24; + break; + + case ROM_PC2086: + case ROM_PC3086: + timing = &timing_pvga1a; + break; + + case ROM_MEGAPC: + timing = &timing_wd90c11; + break; + + case ROM_ACER386: + timing = &timing_oti067; + break; + + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: + timing = &timing_vga; + break; + + case ROM_IBMPS1_2121: + timing = &timing_ps1_svga; + break; + + case ROM_T3100E: + timing = &timing_t3100e; + break; + + case ROM_T1000: + timing = &timing_t1000; + break; + + default: + new_gfxcard = video_old_to_new(gfxcard); + timing = &video_cards[new_gfxcard].timing; + break; + } + + + if (timing->type == VIDEO_ISA) { - video_timing_b = (int)(isa_timing * video_cards[new_gfxcard].timing.b); - video_timing_w = (int)(isa_timing * video_cards[new_gfxcard].timing.w); - video_timing_l = (int)(isa_timing * video_cards[new_gfxcard].timing.l); + video_timing_read_b = ISA_CYCLES(timing->read_b); + video_timing_read_w = ISA_CYCLES(timing->read_w); + video_timing_read_l = ISA_CYCLES(timing->read_l); + video_timing_write_b = ISA_CYCLES(timing->write_b); + video_timing_write_w = ISA_CYCLES(timing->write_w); + video_timing_write_l = ISA_CYCLES(timing->write_l); } else { - video_timing_b = (int)(bus_timing * video_cards[new_gfxcard].timing.b); - video_timing_w = (int)(bus_timing * video_cards[new_gfxcard].timing.w); - video_timing_l = (int)(bus_timing * video_cards[new_gfxcard].timing.l); + video_timing_read_b = (int)(bus_timing * timing->read_b); + video_timing_read_w = (int)(bus_timing * timing->read_w); + video_timing_read_l = (int)(bus_timing * timing->read_l); + video_timing_write_b = (int)(bus_timing * timing->write_b); + video_timing_write_w = (int)(bus_timing * timing->write_w); + video_timing_write_l = (int)(bus_timing * timing->write_l); } - if (cpu_16bitbus) - video_timing_l = video_timing_w * 2; } else { if (video_timing[video_speed][0] == VIDEO_ISA) { - video_timing_b = (int)(isa_timing * video_timing[video_speed][1]); - video_timing_w = (int)(isa_timing * video_timing[video_speed][2]); - video_timing_l = (int)(isa_timing * video_timing[video_speed][3]); + video_timing_read_b = ISA_CYCLES(video_timing[video_speed][1]); + video_timing_read_w = ISA_CYCLES(video_timing[video_speed][2]); + video_timing_read_l = ISA_CYCLES(video_timing[video_speed][3]); + video_timing_write_b = ISA_CYCLES(video_timing[video_speed][1]); + video_timing_write_w = ISA_CYCLES(video_timing[video_speed][2]); + video_timing_write_l = ISA_CYCLES(video_timing[video_speed][3]); } else { - video_timing_b = (int)(bus_timing * video_timing[video_speed][1]); - video_timing_w = (int)(bus_timing * video_timing[video_speed][2]); - video_timing_l = (int)(bus_timing * video_timing[video_speed][3]); + video_timing_read_b = (int)(bus_timing * video_timing[video_speed][1]); + video_timing_read_w = (int)(bus_timing * video_timing[video_speed][2]); + video_timing_read_l = (int)(bus_timing * video_timing[video_speed][3]); + video_timing_write_b = (int)(bus_timing * video_timing[video_speed][1]); + video_timing_write_w = (int)(bus_timing * video_timing[video_speed][2]); + video_timing_write_l = (int)(bus_timing * video_timing[video_speed][3]); } - if (cpu_16bitbus) - video_timing_l = video_timing_w * 2; + } + if (cpu_16bitbus) + { + video_timing_read_l = video_timing_read_w * 2; + video_timing_write_l = video_timing_write_w * 2; } } -int video_timing_b, video_timing_w, video_timing_l; +int video_timing_read_b, video_timing_read_w, video_timing_read_l; +int video_timing_write_b, video_timing_write_w, video_timing_write_l; int video_res_x, video_res_y, video_bpp; diff --git a/src/video.h b/src/video.h index 36bf395..7319e74 100644 --- a/src/video.h +++ b/src/video.h @@ -67,7 +67,8 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); extern void (*video_blit_memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); -extern int video_timing_b, video_timing_w, video_timing_l; +extern int video_timing_read_b, video_timing_read_w, video_timing_read_l; +extern int video_timing_write_b, video_timing_write_w, video_timing_write_l; extern int video_speed; extern int video_res_x, video_res_y, video_bpp; From 0ca43d37d4a5d49ba47a5809113eb1030acfbcfa Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 21:20:26 +0000 Subject: [PATCH 0295/1050] Emulated EGA/VGA CRTC register 8 (Preset Row Scan Register). --- src/vid_ega.c | 2 +- src/vid_svga.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index 3805012..8444382 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -678,7 +678,7 @@ void ega_poll(void *p) if (ega->vc == ega->vtotal) { ega->vc = 0; - ega->sc = 0; + ega->sc = ega->crtc[8] & 0x1f; ega->dispon = 1; ega->displine = 0; ega->scrollcache = ega->attrregs[0x13] & 7; diff --git a/src/vid_svga.c b/src/vid_svga.c index ab984a1..c91a92a 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -684,7 +684,7 @@ void svga_poll(void *p) // printf("Frame over at line %i %i %i %i\n",displine,vc,svga_vsyncstart,svga_dispend); svga->vc = 0; - svga->sc = 0; + svga->sc = svga->crtc[8] & 0x1f; svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; svga->scrollcache = svga->attrregs[0x13] & 7; From 8f04b6b9a43873fea3986e0f35bf0ef1f63a36dd Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 21:53:23 +0000 Subject: [PATCH 0296/1050] Added Toshiba T1200 emulation. Patch from John Elliott. --- src/ibm.h | 3 +- src/keyboard_xt.c | 2 +- src/mem.c | 10 ++++++ src/model.c | 2 ++ src/nvr.c | 6 ++++ src/nvr_tc8521.c | 2 ++ src/t1000.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-- src/vid_t1000.c | 4 ++- src/video.c | 1 + 9 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 6b10a9e..8873741 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -378,7 +378,7 @@ char discfns[2][256]; int driveempty[2]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || 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 && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000 && romset != ROM_T1200) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -446,6 +446,7 @@ enum ROM_EPSON_PCAX3, ROM_T3100E, ROM_T1000, + ROM_T1200, ROM_MAX }; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 72cbf28..45fd521 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -58,7 +58,7 @@ void keyboard_xt_poll() void keyboard_xt_adddata(uint8_t val) { /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T1000) + if (romset == ROM_T1000 || romset == ROM_T1200) { if (pcem_key[0xb8] || pcem_key[0x9D]) /* 'Fn' pressed */ { diff --git a/src/mem.c b/src/mem.c index adc4de8..7a03c12 100644 --- a/src/mem.c +++ b/src/mem.c @@ -772,6 +772,16 @@ int loadbios() biosmask = 0x7fff; fclose(f); return 1; + + case ROM_T1200: + loadfont("t1200/t1000font.rom", 2); + f=romfopen("t1200/t1200_019e.ic15.bin","rb"); + if (!f) break; + romfread(rom, 0x8000,1,f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 6b9273d..e2504f1 100644 --- a/src/model.c +++ b/src/model.c @@ -92,6 +92,7 @@ void at_endeavor_init(); void xt_laserxt_init(); void at_t3100e_init(); void xt_t1000_init(); +void xt_t1200_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -120,6 +121,7 @@ MODEL models[] = {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + {"[8088] Toshiba 1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 1024,2048,1024, xt_t1200_init, &t1000_device}, {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 0, 0, 512,1152, 128, xt_laserxt_init, NULL}, {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 7f4476c..25dd137 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -292,6 +292,9 @@ void loadnvr() t1000_configsys_loadnvr(); t1000_emsboard_loadnvr(); return; + case ROM_T1200: tc8521_loadnvr(); + t1000_emsboard_loadnvr(); + return; default: return; } @@ -369,6 +372,9 @@ void savenvr() t1000_configsys_savenvr(); t1000_emsboard_savenvr(); return; + case ROM_T1200: tc8521_savenvr(); + t1000_emsboard_savenvr(); + return; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/nvr_tc8521.c b/src/nvr_tc8521.c index 6e20c41..f221c00 100644 --- a/src/nvr_tc8521.c +++ b/src/nvr_tc8521.c @@ -58,6 +58,7 @@ void tc8521_loadnvr() switch (romset) { case ROM_T1000: f = nvrfopen("t1000.nvr", "rb"); break; + case ROM_T1200: f = nvrfopen("t1200.nvr", "rb"); break; default: return; } if (!f) @@ -85,6 +86,7 @@ void tc8521_savenvr() switch (oldromset) { case ROM_T1000: f = nvrfopen("t1000.nvr", "wb"); break; + case ROM_T1200: f = nvrfopen("t1200.nvr", "wb"); break; default: return; } fwrite(nvrram,64,1,f); diff --git a/src/t1000.c b/src/t1000.c index 1076489..7dae292 100644 --- a/src/t1000.c +++ b/src/t1000.c @@ -27,7 +27,8 @@ * A ROM drive (128k, 256k or 512k) which acts as a mini hard * drive and contains a copy of DOS 2.11. * 160 bytes of non-volatile RAM for the CONFIG.SYS used when - * booting from the ROM drive. + * booting from the ROM drive. Possibly physically located + * in the keyboard controller RAM. * * An optional memory expansion board can be fitted. This adds 768k of RAM, * which can be used for up to three purposes: @@ -38,7 +39,13 @@ * This means that there are up to three different implementations of * non-volatile RAM in the same computer (52 nibbles in the TC8521, 160 * bytes of CONFIG.SYS, and up to 768k of HardRAM). - * + * + * The T1200 is a slightly upgraded version with a turbo mode (double CPU + * clock, 9.54MHz) and an optional hard drive. The interface for this is + * proprietary both at the physical and programming level. + * + * 01F2h: If hard drive is present, low 4 bits are 0Ch [20Mb] or 0Dh [10Mb]. + * */ void common_init(); @@ -56,6 +63,7 @@ static struct t1000_system /* System control registers */ uint8_t sys_ctl[16]; uint8_t syskeys; + uint8_t turbo; /* NVRAM control */ uint8_t nvr_c0; @@ -375,6 +383,26 @@ static uint8_t read_t1000_ctl(uint16_t addr, void *priv) } } +static void t1200_turbo_set(uint8_t value) +{ + if (value == t1000.turbo) + { + return; + } + t1000.turbo = value; + if (!value) + { + int c = cpu; + cpu = 0; /* 8088/4.77MHz */ + cpu_set(); + cpu = c; + } + else + { + cpu_set(); + } +} + static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) { struct t1000_system *sys = (struct t1000_system *)priv; @@ -387,6 +415,10 @@ static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) { t1000_video_options_set((val & 0x20) ? 1 : 0); t1000_display_set((val & 0x40) ? 0 : 1); + if (romset == ROM_T1200) + { + t1200_turbo_set((val & 0x80) ? 1 : 0); + } } break; /* EMS control*/ @@ -526,6 +558,7 @@ void xt_t1000_init() int pg; memset(&t1000, 0, sizeof(t1000)); + t1000.turbo = 0xff; t1000.ems_port_index = 7; /* EMS disabled */ /* The ROM drive is optional. If the file is missing, continue to boot; the * BIOS will complain 'No ROM drive' but boot normally from floppy. */ @@ -577,3 +610,43 @@ void xt_t1000_init() nvr_tc8521_init(); /* No gameport, and no provision to fit one device_add(&gameport_device); */ } + + +void xt_t1200_init() +{ + int pg; + + memset(&t1000, 0, sizeof(t1000)); + t1000.ems_port_index = 7; /* EMS disabled */ + + mem_mapping_add(&t1000.rom_mapping, 0xA0000, 0x10000, + t1000_read_rom, t1000_read_romw, t1000_read_roml, + NULL, NULL, NULL, NULL, MEM_MAPPING_INTERNAL, &t1000); + mem_mapping_disable(&t1000.rom_mapping); + + /* Map the EMS page frame */ + for (pg = 0; pg < 4; pg++) + { + mem_mapping_add(&t1000.mapping[pg], + 0xD0000 + (0x4000 * pg), 16384, + ems_read_ram, ems_read_ramw, ems_read_raml, + ems_write_ram, ems_write_ramw, ems_write_raml, + NULL, MEM_MAPPING_EXTERNAL, + &t1000); + /* Start them all off disabled */ + mem_mapping_disable(&t1000.mapping[pg]); + } + + /* System control functions, and add-on memory board */ + io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL, + write_t1000_ctl, NULL, NULL, &t1000); + + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); + nvr_tc8521_init(); +/* No gameport, and no provision to fit one device_add(&gameport_device); */ +} + diff --git a/src/vid_t1000.c b/src/vid_t1000.c index 69939d8..ce9b310 100644 --- a/src/vid_t1000.c +++ b/src/vid_t1000.c @@ -18,6 +18,7 @@ static uint32_t blue, grey; static uint8_t boldcols[256]; /* Which attributes use the bold font */ static uint32_t blinkcols[256][2]; static uint32_t normcols[256][2]; +static uint8_t language; /* Video options set by the motherboard; they will be picked up by the card * on the next poll. @@ -31,7 +32,7 @@ static uint8_t st_display_internal = -1; void t1000_video_options_set(uint8_t options) { st_video_options = options & 1; - st_video_options |= device_get_config_int("display_language") ? 2 : 0; + st_video_options |= language; } void t1000_display_set(uint8_t internal) @@ -638,6 +639,7 @@ static void *t1000_init() t1000->cga.vram = t1000->vram; t1000->enabled = 1; t1000->video_options = 0x01; + language = device_get_config_int("display_language") ? 2 : 0; return t1000; } diff --git a/src/video.c b/src/video.c index 325361f..1166b75 100644 --- a/src/video.c +++ b/src/video.c @@ -442,6 +442,7 @@ void video_init() return; case ROM_T1000: + case ROM_T1200: device_add(&t1000_device); return; } From 36ba814c0087a833e2b611088bca2799d3cb63be Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 1 Feb 2018 18:06:41 +0000 Subject: [PATCH 0297/1050] Added romfread function to work around warnings from ignoring fread return value. Patch from John Elliott. --- src/mem.c | 111 +++++++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 51 deletions(-) diff --git a/src/mem.c b/src/mem.c index 7a03c12..dcf4cdc 100644 --- a/src/mem.c +++ b/src/mem.c @@ -57,6 +57,15 @@ int cachesize=256; uint8_t *ram, *rom = NULL; uint8_t romext[32768]; +static void romfread(uint8_t *buf, size_t size, size_t count, FILE *fp) +{ + int result = fread(buf,size,count,fp); + if (result < count) + { + pclog("ROM read failed: Expected %d, read %d\n", count, result); + } +} + static int mem_load_basic(char *path) { char s[256]; @@ -69,27 +78,27 @@ static int mem_load_basic(char *path) sprintf(s, "%s/basicc11.f6", path); f = romfopen(s, "rb"); if (!f) return 1; /*I don't really care if BASIC is there or not*/ - fread(rom + 0x6000, 8192, 1, f); + romfread(rom + 0x6000, 8192, 1, f); fclose(f); sprintf(s, "%s/basicc11.f8", path); f = romfopen(s, "rb"); if (!f) return 0; /*But if some of it is there, then all of it must be*/ - fread(rom + 0x8000, 8192, 1, f); + romfread(rom + 0x8000, 8192, 1, f); fclose(f); sprintf(s, "%s/basicc11.fa", path); f = romfopen(s, "rb"); if (!f) return 0; - fread(rom + 0xA000, 8192, 1, f); + romfread(rom + 0xA000, 8192, 1, f); fclose(f); sprintf(s, "%s/basicc11.fc", path); f = romfopen(s, "rb"); if (!f) return 0; - fread(rom + 0xC000, 8192, 1, f); + romfread(rom + 0xC000, 8192, 1, f); fclose(f); } else { - fread(rom + 0x6000, 32768, 1, f); + romfread(rom + 0x6000, 32768, 1, f); fclose(f); } @@ -160,13 +169,13 @@ int loadbios() case ROM_TANDY: f=romfopen("tandy/tandy1t1.020","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_TANDY1000HX: f = romfopen("tandy1000hx/v020000.u12", "rb"); if (!f) break; - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -186,10 +195,10 @@ int loadbios() return 1; /* case ROM_IBMPCJR: f=fopen("pcjr/bios.rom","rb"); - fread(rom+0xE000,8192,1,f); + romfread(rom+0xE000,8192,1,f); fclose(f); f=fopen("pcjr/basic.rom","rb"); - fread(rom+0x6000,32768,1,f); + romfread(rom+0x6000,32768,1,f); fclose(f); break;*/ case ROM_IBMXT: @@ -199,15 +208,15 @@ int loadbios() f = romfopen("ibmxt/5000027.u19", "rb"); ff = romfopen("ibmxt/1501512.u18","rb"); if (!f || !ff) break; - fread(rom, 0x8000, 1, f); - fread(rom + 0x8000, 0x8000, 1, ff); + romfread(rom, 0x8000, 1, f); + romfread(rom + 0x8000, 0x8000, 1, ff); fclose(ff); fclose(f); return 1; } else { - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; } @@ -216,20 +225,20 @@ int loadbios() case ROM_IBMPCJR: f = romfopen("ibmpcjr/bios.rom","rb"); if (!f) break; - fread(rom, 0x10000, 1, f); + romfread(rom, 0x10000, 1, f); fclose(f); return 1; case ROM_GENXT: f=romfopen("genxt/pcxt.rom","rb"); if (!f) break; - fread(rom+0xE000,8192,1,f); + romfread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_DTKXT: f=romfopen("dtk/dtk_erso_2.42_2764.bin","rb"); if (!f) break; - fread(rom+0xE000,8192,1,f); + romfread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_OLIM24: @@ -267,7 +276,7 @@ int loadbios() case ROM_PC3086: f = romfopen("pc3086/fc00.bin" ,"rb"); if (!f) break; - fread(rom, 0x4000, 1, f); + romfread(rom, 0x4000, 1, f); fclose(f); f = romfopen("pc3086/c000.bin", "rb"); if (!f) break; @@ -278,7 +287,7 @@ int loadbios() case ROM_IBMAT: /* f=romfopen("amic206.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1;*/ case ROM_IBMAT386: @@ -321,34 +330,34 @@ int loadbios() /* case ROM_IBMAT386: f=romfopen("at386/at386.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1;*/ case ROM_AMI386SX: // f=romfopen("at386/at386.bin","rb"); f=romfopen("ami386/ami386.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ f=romfopen("ami386dx/opt495sx.ami","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ f=romfopen("mr386dx/opt495sx.mr","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_ACER386: f=romfopen("acer386/acer386.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); rom[0xB0]=0xB0-0x51; rom[0x40d4]=0x51; /*PUSH CX*/ @@ -360,14 +369,14 @@ int loadbios() case ROM_KMXC02: f=romfopen("kmxc02/3ctm005.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_AMI286: f=romfopen("ami286/amic206.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); // memset(romext,0x63,0x8000); return 1; @@ -375,21 +384,21 @@ int loadbios() case ROM_AWARD286: f=romfopen("award286/award.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_GW286CT: f=romfopen("gw286ct/2ctc001.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; case ROM_SPC4200P: f=romfopen("spc4200p/u8.01","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; @@ -411,7 +420,7 @@ int loadbios() } else { - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; @@ -422,7 +431,7 @@ int loadbios() // return 0; f=romfopen("europc/50145","rb"); if (!f) break; - fread(rom+0x8000,32768,1,f); + romfread(rom+0x8000,32768,1,f); fclose(f); // memset(romext,0x63,0x8000); return 1; @@ -431,7 +440,7 @@ int loadbios() f=romfopen("ibmpc/pc102782.bin","rb"); if (!f) break; // f=fopen("pc081682.bin","rb"); - fread(rom+0xE000,8192,1,f); + romfread(rom+0xE000,8192,1,f); fclose(f); if (!mem_load_basic("ibmpc")) break; @@ -455,7 +464,7 @@ int loadbios() case ROM_AMI486: f=romfopen("ami486/ami486.bin","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); //is486=1; return 1; @@ -464,7 +473,7 @@ int loadbios() // f=romfopen("win486/win486.bin","rb"); f=romfopen("win486/ali1429g.amw","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); //is486=1; return 1; @@ -472,7 +481,7 @@ int loadbios() case ROM_PCI486: f=romfopen("hot-433/hot-433.ami","rb"); if (!f) break; - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -481,7 +490,7 @@ int loadbios() case ROM_SIS496: f = romfopen("sis496/sis496-1.awa", "rb"); if (!f) break; - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); @@ -493,7 +502,7 @@ int loadbios() f = romfopen("430vx/55xwuq0e.bin", "rb"); // f=romfopen("430vx/430vx","rb"); if (!f) break; - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -503,12 +512,12 @@ int loadbios() f = romfopen("revenge/1009af2_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - fread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("revenge/1009af2_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - fread(rom, 0xc000, 1, f); + romfread(rom, 0xc000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -517,12 +526,12 @@ int loadbios() f = romfopen("endeavor/1006cb0_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - fread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("endeavor/1006cb0_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - fread(rom, 0xd000, 1, f); + romfread(rom, 0xd000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -547,7 +556,7 @@ int loadbios() f = romfopen("ibmps1es/f80000.bin", "rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); //#endif biosmask = 0x1ffff; @@ -557,7 +566,7 @@ int loadbios() f = romfopen("ibmps1_2121/fc0000.bin", "rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -579,14 +588,14 @@ int loadbios() case ROM_AMIXT: f = romfopen("amixt/ami_8088_bios_31jan89.bin", "rb"); if (!f) break; - fread(rom + 0xE000, 8192, 1, f); + romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_LTXT: f = romfopen("ltxt/27c64.bin", "rb"); if (!f) break; - fread(rom + 0xE000, 8192, 1, f); + romfread(rom + 0xE000, 8192, 1, f); fclose(f); if (!mem_load_basic("ltxt")) break; @@ -595,7 +604,7 @@ int loadbios() case ROM_LXT3: f = romfopen("lxt3/27c64d.bin", "rb"); if (!f) break; - fread(rom + 0xE000, 8192, 1, f); + romfread(rom + 0xE000, 8192, 1, f); fclose(f); if (!mem_load_basic("lxt3")) break; @@ -617,28 +626,28 @@ int loadbios() case ROM_DTK386: /*Uses NEAT chipset*/ f = romfopen("dtk386/3cto001.bin", "rb"); if (!f) break; - fread(rom, 65536, 1, f); + romfread(rom, 65536, 1, f); fclose(f); return 1; case ROM_PXXT: f = romfopen("pxxt/000p001.bin", "rb"); if (!f) break; - fread(rom + 0xE000, 8192, 1, f); + romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_JUKOPC: f = romfopen("jukopc/000o001.bin", "rb"); if (!f) break; - fread(rom + 0xE000, 8192, 1, f); + romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_IBMPS2_M30_286: f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); if (!f) break; - fread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -698,7 +707,7 @@ int loadbios() case ROM_ATARIPC3: f=romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN","rb"); if (!f) break; - fread(rom+0x8000,32768,1,f); + romfread(rom+0x8000,32768,1,f); fclose(f); return 1; @@ -759,7 +768,7 @@ int loadbios() loadfont("t3100e/t3100e_font.bin", 5); f=romfopen("t3100e/t3100e.rom","rb"); if (!f) break; - fread(rom,65536,1,f); + romfread(rom,65536,1,f); fclose(f); return 1; @@ -767,7 +776,7 @@ int loadbios() loadfont("t1000/t1000font.rom", 2); f=romfopen("t1000/t1000.rom","rb"); if (!f) break; - fread(rom, 0x8000,1,f); + romfread(rom, 0x8000,1,f); memcpy(rom + 0x8000, rom, 0x8000); biosmask = 0x7fff; fclose(f); From 7ddc01baf73f6a4912481ecd1fd885d7a50e816e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Feb 2018 20:35:34 +0000 Subject: [PATCH 0298/1050] Added guards against accessing out-of-bounds floppy drives. --- src/disc.c | 20 ++++++++------------ src/fdd.c | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/disc.c b/src/disc.c index 10274cc..d4fa316 100644 --- a/src/disc.c +++ b/src/disc.c @@ -125,7 +125,7 @@ int disc_hole(int drive) { drive ^= fdd_swap; - if (drives[drive].hole) + if (drive < 2 && drives[drive].hole) { return drives[drive].hole(drive); } @@ -139,7 +139,7 @@ void disc_poll() { disc_poll_time += disc_period * TIMER_USEC; - if (drives[disc_drivesel].poll) + if (disc_drivesel < 2 && drives[disc_drivesel].poll) drives[disc_drivesel].poll(); if (disc_notfound) @@ -228,10 +228,6 @@ void disc_reset() void disc_init() { -// pclog("disc_init %p\n", drives); - drives[0].poll = drives[1].poll = 0; - drives[0].seek = drives[1].seek = 0; - drives[0].readsector = drives[1].readsector = 0; disc_reset(); } @@ -239,7 +235,7 @@ int oldtrack[2] = {0, 0}; void disc_seek(int drive, int track) { // pclog("disc_seek: drive=%i track=%i\n", drive, track); - if (drives[drive].seek) + if (drive < 2 && drives[drive].seek) drives[drive].seek(drive, track); // if (track != oldtrack[drive]) // fdc_discchange_clear(drive); @@ -251,7 +247,7 @@ void disc_readsector(int drive, int sector, int track, int side, int density, in { drive ^= fdd_swap; - if (drives[drive].readsector) + if (drive < 2 && drives[drive].readsector) drives[drive].readsector(drive, sector, track, side, density, sector_size); else disc_notfound = 1000; @@ -261,7 +257,7 @@ void disc_writesector(int drive, int sector, int track, int side, int density, i { drive ^= fdd_swap; - if (drives[drive].writesector) + if (drive < 2 && drives[drive].writesector) drives[drive].writesector(drive, sector, track, side, density, sector_size); else disc_notfound = 1000; @@ -271,7 +267,7 @@ void disc_readaddress(int drive, int track, int side, int density) { drive ^= fdd_swap; - if (drives[drive].readaddress) + if (drive < 2 && drives[drive].readaddress) drives[drive].readaddress(drive, track, side, density); } @@ -279,7 +275,7 @@ void disc_format(int drive, int track, int side, int density, uint8_t fill) { drive ^= fdd_swap; - if (drives[drive].format) + if (drive < 2 && drives[drive].format) drives[drive].format(drive, track, side, density, fill); else disc_notfound = 1000; @@ -289,7 +285,7 @@ void disc_stop(int drive) { drive ^= fdd_swap; - if (drives[drive].stop) + if (drive < 2 && drives[drive].stop) drives[drive].stop(drive); } diff --git a/src/fdd.c b/src/fdd.c index 7092f70..17e61ec 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -79,6 +79,9 @@ int fdd_swap = 0; void fdd_seek(int drive, int track_diff) { drive ^= fdd_swap; + + if (drive >= 2) + return; fdd[drive].track += track_diff; @@ -101,13 +104,17 @@ void fdd_disc_changed(int drive) drive ^= fdd_swap; /*Force reload of current track data*/ - disc_seek(drive, fdd[drive].track); + if (drive < 2) + disc_seek(drive, fdd[drive].track); } int fdd_track0(int drive) { drive ^= fdd_swap; + if (drive >= 2) + return 0; + /* If drive is disabled, TRK0 never gets set. */ if (!drive_types[fdd[drive].type].max_track) return 0; @@ -122,9 +129,14 @@ void fdd_set_densel(int densel) int fdd_getrpm(int drive) { - int hole = disc_hole(drive); + int hole; drive ^= fdd_swap; + + if (drive >= 2) + return 0; + + hole = disc_hole(drive); if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_360)) return 300; if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_300)) return 360; @@ -162,9 +174,14 @@ void fdd_setswap(int swap) int fdd_can_read_medium(int drive) { - int hole = disc_hole(drive); + int hole; drive ^= fdd_swap; + + if (drive >= 2) + return 0; + + hole = disc_hole(drive); hole = 1 << (hole + 3); @@ -174,25 +191,34 @@ int fdd_can_read_medium(int drive) int fdd_doublestep_40(int drive) { + if (drive >= 2) + return 0; return drive_types[fdd[drive].type].flags & FLAG_DOUBLE_STEP; } void fdd_set_type(int drive, int type) { - fdd[drive].type = type; + if (drive < 2) + fdd[drive].type = type; } int fdd_get_type(int drive) { + if (drive >= 2) + return 0; return fdd[drive].type; } int fdd_is_525(int drive) { + if (drive >= 2) + return 0; return drive_types[fdd[drive].type].flags & FLAG_525; } int fdd_is_ed(int drive) { + if (drive >= 2) + return 0; return drive_types[fdd[drive].type].flags & FLAG_HOLE2; } From 91acf474880323c7cb143f5d6c67207993af499a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 10 Feb 2018 11:08:09 +0000 Subject: [PATCH 0299/1050] FDC seek commands on non-existant drives should still complete. Fixes hangs in some Windows 9x startups. --- src/fdd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/fdd.c b/src/fdd.c index 17e61ec..69a196f 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -81,7 +81,10 @@ void fdd_seek(int drive, int track_diff) drive ^= fdd_swap; if (drive >= 2) + { + disctime = 5000; return; + } fdd[drive].track += track_diff; From 2f733380819eb0c3a90011ffdfe156c96e3d95f2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 10 Feb 2018 11:30:26 +0000 Subject: [PATCH 0300/1050] Changes to autoconf/automake scripts to improve MSYS2 compatibility. Patch from darksabre76. --- configure | 86 ++- configure.ac | 47 +- src/Makefile.am | 58 +- src/Makefile.in | 1441 ++++++++++++++++++++++++++++++++-------------- src/nethandler.c | 2 +- src/wx-main.cc | 1 + 6 files changed, 1134 insertions(+), 501 deletions(-) diff --git a/configure b/configure index dd280fd..c3fc3f7 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PCem v12. +# Generated by GNU Autoconf 2.69 for PCem v13.1. # # Report bugs to >. # @@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCem' PACKAGE_TARNAME='pcem' -PACKAGE_VERSION='v12' -PACKAGE_STRING='PCem v12' +PACKAGE_VERSION='v13.1' +PACKAGE_STRING='PCem v13.1' PACKAGE_BUGREPORT='Sarah Walker ' PACKAGE_URL='' @@ -1310,7 +1310,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PCem v12 to adapt to many kinds of systems. +\`configure' configures PCem v13.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1381,7 +1381,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCem v12:";; + short | recursive ) echo "Configuration of PCem v13.1:";; esac cat <<\_ACEOF @@ -1499,7 +1499,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCem configure v12 +PCem configure v13.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1680,7 +1680,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PCem $as_me v12, which was +It was created by PCem $as_me v13.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2616,7 +2616,7 @@ fi # Define the identity of the package. PACKAGE='pcem' - VERSION='v12' + VERSION='v13.1' cat >>confdefs.h <<_ACEOF @@ -4210,19 +4210,19 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu" >&5 $as_echo_n "checking for cpu... " >&6; } case "${host_cpu}" in - i?86) - CPU=i386 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 + i?86) + CPU=i386 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 $as_echo "${host_cpu}" >&6; } - ;; - x86_64) - CPU=x86_64 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 + ;; + x86_64) + CPU=x86_64 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 $as_echo "${host_cpu}" >&6; } - ;; - *) - as_fn_error $? "Unsupported CPU." "$LINENO" 5 - ;; + ;; + *) + as_fn_error $? "Unsupported CPU." "$LINENO" 5 + ;; esac if test "$CPU" = "i386"; then @@ -5157,7 +5157,7 @@ _ACEOF else echo "You need to install the ALSA library." - exit -1 + exit -1 fi fi @@ -5219,48 +5219,42 @@ case "$host" in build_macosx="yes" ;; *-*-cygwin* | *-*-mingw32*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 -$as_echo_n "checking for glGetError in -lGL... " >&6; } -if ${ac_cv_lib_GL_glGetError+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 +$as_echo_n "checking for main in -lopengl32... " >&6; } +if ${ac_cv_lib_opengl32_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lGL $LIBS" +LIBS="-lopengl32 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char glGetError (); + int main () { -return glGetError (); +return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_GL_glGetError=yes + ac_cv_lib_opengl32_main=yes else - ac_cv_lib_GL_glGetError=no + ac_cv_lib_opengl32_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 -$as_echo "$ac_cv_lib_GL_glGetError" >&6; } -if test "x$ac_cv_lib_GL_glGetError" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 +$as_echo "$ac_cv_lib_opengl32_main" >&6; } +if test "x$ac_cv_lib_opengl32_main" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGL 1 +#define HAVE_LIBOPENGL32 1 _ACEOF - LIBS="-lGL $LIBS" + LIBS="-lopengl32 $LIBS" else \ @@ -5313,11 +5307,13 @@ _ACEOF else \ - echo "You need to install the OpenAL library." - exit -1 + echo "You need to install the OpenAL library." + exit -1 fi build_win="yes" + SET_MAKE='MAKE=mingw32-make' + ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 @@ -5414,8 +5410,8 @@ _ACEOF else \ - echo "You need to install the OpenAL library." - exit -1 + echo "You need to install the OpenAL library." + exit -1 fi build_linux="yes" @@ -6061,7 +6057,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PCem $as_me v12, which was +This file was extended by PCem $as_me v13.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6118,7 +6114,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PCem config.status v12 +PCem config.status v13.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 815aa33..5cf2690 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # AC_PREREQ([2.61]) -AC_INIT(PCem, v12, Sarah Walker , pcem) +AC_INIT(PCem, v13.1, Sarah Walker , pcem) AC_CANONICAL_HOST @@ -15,7 +15,7 @@ AM_PROG_CC_C_O AC_MSG_CHECKING([whether to build for release]) AC_ARG_ENABLE(release_build, - AC_HELP_STRING([--enable-release-build], [build for release])) + AC_HELP_STRING([--enable-release-build], [build for release])) if test "$enable_release_build" = "yes"; then AC_MSG_RESULT([yes]) else @@ -25,7 +25,7 @@ AM_CONDITIONAL(RELEASE_BUILD, [test "$enable_release_build" = "yes"]) AC_MSG_CHECKING([whether to enable debugging]) AC_ARG_ENABLE(debug, - AC_HELP_STRING([--enable-debug], [build debug executable])) + AC_HELP_STRING([--enable-debug], [build debug executable])) if test "$enable_debug" = "yes"; then CFLAGS="-Wall -O0 -g -D_DEBUG" AC_MSG_RESULT([yes]) @@ -36,7 +36,7 @@ fi AC_MSG_CHECKING([whether to enable networking]) AC_ARG_ENABLE(networking, - AC_HELP_STRING([--enable-networking], [enable networking])) + AC_HELP_STRING([--enable-networking], [enable networking])) if test "$enable_networking" = "yes"; then AC_MSG_RESULT([yes]) else @@ -45,7 +45,7 @@ fi AC_MSG_CHECKING([whether to use ALSA for MIDI output]) AC_ARG_ENABLE(alsa, - AC_HELP_STRING([--enable-alsa], [use ALSA for MIDI])) + AC_HELP_STRING([--enable-alsa], [use ALSA for MIDI])) if test "$enable_alsa" = "yes"; then AC_MSG_RESULT([yes]) else @@ -54,17 +54,17 @@ fi AC_MSG_CHECKING([for cpu]) case "${host_cpu}" in - i?86) - CPU=i386 - AC_MSG_RESULT(${host_cpu}) - ;; - x86_64) - CPU=x86_64 - AC_MSG_RESULT(${host_cpu}) - ;; - *) - AC_MSG_ERROR([Unsupported CPU.]) - ;; + i?86) + CPU=i386 + AC_MSG_RESULT(${host_cpu}) + ;; + x86_64) + CPU=x86_64 + AC_MSG_RESULT(${host_cpu}) + ;; + *) + AC_MSG_ERROR([Unsupported CPU.]) + ;; esac AM_CONDITIONAL(CPU_I386, test "$CPU" = "i386") @@ -108,7 +108,7 @@ if test "$enable_alsa" == "yes"; then AC_CHECK_LIB(asound, snd_pcm_open, [], [echo "You need to install the ALSA library." - exit -1]) + exit -1]) fi AC_CHECK_LIB([pthread], [pthread_create]) @@ -124,21 +124,22 @@ case "$host" in build_macosx="yes" ;; *-*-cygwin* | *-*-mingw32*) - AC_CHECK_LIB([GL], [glGetError], [], \ + AC_CHECK_LIB([opengl32], [main], [], \ [echo "You need to install the OpenGL library." exit -1]) AC_CHECK_LIB([openal], [alGetError], [], \ - [echo "You need to install the OpenAL library." - exit -1]) + [echo "You need to install the OpenAL library." + exit -1]) build_win="yes" - ;; + AC_SUBST(SET_MAKE, 'MAKE=mingw32-make') + ;; *) AC_CHECK_LIB([GL], [glGetError], [], \ [echo "You need to install the OpenGL library." exit -1]) AC_CHECK_LIB([openal], [alGetError], [], \ - [echo "You need to install the OpenAL library." - exit -1]) + [echo "You need to install the OpenAL library." + exit -1]) build_linux="yes" ;; esac diff --git a/src/Makefile.am b/src/Makefile.am index 864c77c..9f2ca5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,18 +1,28 @@ # Makefile.am for PCem +AUTOMAKE_OPTIONS = subdir-objects bin_PROGRAMS = pcem -noinst_SCRIPTS = ../pcem -CLEANFILES = $(noinst_SCRIPTS) +noinst_SCRIPTS = +CLEANFILES = +if !OS_WINDOWS +CLEANFILES += $(noinst_SCRIPTS) +noinst_SCRIPTS += ../pcem ../pcem: pcem cp pcem .. - -slirp/libslirp.a: - $(MAKE) -C slirp +endif amrefresh: +# Special wxWidgets files +WINDRES = $(shell wx-config --rescomp) +wx.res: wx.rc + $(WINDRES) -i wx.rc --input-format=rc -o wx.res -O coff + +wx-resources.cpp : pc.xrc + -wxrc -c pc.xrc -o wx-resources.cpp +# PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ @@ -30,22 +40,28 @@ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti06 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_t1000.c vid_t3100e.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 vid_wy700.c \ -x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ -dosbox/nukedopl.cpp dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \ +x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc + +# DOSBox +pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c + +# resid-fp +pcem_SOURCES += 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 -pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +pcem_CFLAGS = $(subst -fpermissive,,$(shell wx-config --cxxflags) $(shell sdl2-config --cflags)) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) pcem_LDADD = @LIBS@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c \ wx-sdl2.c wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ - wx-resources.cpp wx-thread.c wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc wx-createdisc.cc + wx-thread.c wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc wx-createdisc.cc \ + wx-resources.cpp if USE_ALSA pcem_LDADD += -lasound pcem_SOURCES += midi_alsa.c @@ -66,17 +82,31 @@ if USE_NETWORKING pcem_CFLAGS += -DUSE_NETWORKING pcem_CXXFLAGS += -DUSE_NETWORKING pcem_SOURCES += ne2000.c nethandler.c wx-hostconfig.c -pcem_LDADD += slirp/libslirp.a +# SLiRP +pcem_SOURCES += slirp/bootp.c slirp/cksum.c slirp/debug.c slirp/if.c slirp/ip_icmp.c \ +slirp/ip_input.c slirp/ip_output.c slirp/mbuf.c slirp/misc.c slirp/queue.c \ +slirp/sbuf.c slirp/slirp.c slirp/socket.c slirp/tcp_input.c slirp/tcp_output.c \ +slirp/tcp_subr.c slirp/tcp_timer.c slirp/tftp.c slirp/udp.c + +if OS_WINDOWS +pcem_LDADD += -lwsock32 -liphlpapi +endif +endif + +if OS_LINUX +pcem_SOURCES += cdrom-ioctl-linux.c wx-sdl2-display.c endif if OS_MACOSX -pcem_SOURCES += cdrom-ioctl-osx.c +pcem_SOURCES += cdrom-ioctl-osx.c wx-sdl2-display.c pcem_CFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP pcem_CXXFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP endif -if OS_LINUX -pcem_SOURCES += cdrom-ioctl-linux.c +if OS_WINDOWS +#DEFAULT_INCLUDES = -iquote . +pcem_SOURCES += cdrom-ioctl.c wx-sdl2-display-win.c +pcem_LDADD += wx.res endif if !HAS_OFF64T diff --git a/src/Makefile.in b/src/Makefile.in index 0233f65..822176b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -92,23 +92,39 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcem$(EXEEXT) -@USE_ALSA_TRUE@am__append_1 = -lasound -@USE_ALSA_TRUE@am__append_2 = midi_alsa.c -@USE_ALSA_FALSE@am__append_3 = wx-sdl2-midi.c -@CPU_I386_TRUE@am__append_4 = codegen_x86.c -@CPU_I386_TRUE@am__append_5 = -msse2 -@CPU_X86_64_TRUE@am__append_6 = codegen_x86-64.c -@USE_NETWORKING_TRUE@am__append_7 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_8 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_9 = ne2000.c nethandler.c wx-hostconfig.c -@USE_NETWORKING_TRUE@am__append_10 = slirp/libslirp.a -@OS_MACOSX_TRUE@am__append_11 = cdrom-ioctl-osx.c -@OS_MACOSX_TRUE@am__append_12 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -@OS_MACOSX_TRUE@am__append_13 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -@OS_LINUX_TRUE@am__append_14 = cdrom-ioctl-linux.c -@HAS_OFF64T_FALSE@am__append_15 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell -@RELEASE_BUILD_TRUE@am__append_16 = -DRELEASE_BUILD -@RELEASE_BUILD_TRUE@am__append_17 = -DRELEASE_BUILD +@OS_WINDOWS_FALSE@am__append_1 = $(noinst_SCRIPTS) +@OS_WINDOWS_FALSE@am__append_2 = ../pcem +@USE_ALSA_TRUE@am__append_3 = -lasound +@USE_ALSA_TRUE@am__append_4 = midi_alsa.c +@USE_ALSA_FALSE@am__append_5 = wx-sdl2-midi.c +@CPU_I386_TRUE@am__append_6 = codegen_x86.c +@CPU_I386_TRUE@am__append_7 = -msse2 +@CPU_X86_64_TRUE@am__append_8 = codegen_x86-64.c +@USE_NETWORKING_TRUE@am__append_9 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_10 = -DUSE_NETWORKING +# SLiRP +@USE_NETWORKING_TRUE@am__append_11 = ne2000.c nethandler.c \ +@USE_NETWORKING_TRUE@ wx-hostconfig.c slirp/bootp.c \ +@USE_NETWORKING_TRUE@ slirp/cksum.c slirp/debug.c slirp/if.c \ +@USE_NETWORKING_TRUE@ slirp/ip_icmp.c slirp/ip_input.c \ +@USE_NETWORKING_TRUE@ slirp/ip_output.c slirp/mbuf.c \ +@USE_NETWORKING_TRUE@ slirp/misc.c slirp/queue.c slirp/sbuf.c \ +@USE_NETWORKING_TRUE@ slirp/slirp.c slirp/socket.c \ +@USE_NETWORKING_TRUE@ slirp/tcp_input.c slirp/tcp_output.c \ +@USE_NETWORKING_TRUE@ slirp/tcp_subr.c slirp/tcp_timer.c \ +@USE_NETWORKING_TRUE@ slirp/tftp.c slirp/udp.c +@OS_WINDOWS_TRUE@@USE_NETWORKING_TRUE@am__append_12 = -lwsock32 -liphlpapi +@OS_LINUX_TRUE@am__append_13 = cdrom-ioctl-linux.c wx-sdl2-display.c +@OS_MACOSX_TRUE@am__append_14 = cdrom-ioctl-osx.c wx-sdl2-display.c +@OS_MACOSX_TRUE@am__append_15 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +@OS_MACOSX_TRUE@am__append_16 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP + +#DEFAULT_INCLUDES = -iquote . +@OS_WINDOWS_TRUE@am__append_17 = cdrom-ioctl.c wx-sdl2-display-win.c +@OS_WINDOWS_TRUE@am__append_18 = wx.res +@HAS_OFF64T_FALSE@am__append_19 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell +@RELEASE_BUILD_TRUE@am__append_20 = -DRELEASE_BUILD +@RELEASE_BUILD_TRUE@am__append_21 = -DRELEASE_BUILD subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -128,23 +144,24 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ - intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c \ + headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pci.c pic.c \ - piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c \ - scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ + piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ + nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ + scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c \ sound_adlibgold.c sound_audiopci.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 \ - t3100e.c timer.c um8669f.c um8881f.c vid_ati_eeprom.c \ + t1000.c t3100e.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_colorplus.c \ vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ @@ -152,38 +169,68 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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_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_t3100e.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 vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ - sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ - dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ - wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ - wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ - wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ - wx-status.cc wx-sdl2-status.c wx-resources.cpp wx-thread.c \ - wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c \ - wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ - wx-shaderconfig.cc wx-joystickconfig.cc midi_alsa.c \ - wx-sdl2-midi.c codegen_x86.c codegen_x86-64.c ne2000.c \ - nethandler.c wx-hostconfig.c cdrom-ioctl-osx.c \ - cdrom-ioctl-linux.c + vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c \ + vid_t3100e.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 vid_wy700.c x86seg.c x87.c \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ + wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ + wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ + wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ + wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ + wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ + midi_alsa.c wx-sdl2-midi.c codegen_x86.c codegen_x86-64.c \ + ne2000.c nethandler.c wx-hostconfig.c slirp/bootp.c \ + slirp/cksum.c slirp/debug.c slirp/if.c slirp/ip_icmp.c \ + slirp/ip_input.c slirp/ip_output.c slirp/mbuf.c slirp/misc.c \ + slirp/queue.c slirp/sbuf.c slirp/slirp.c slirp/socket.c \ + slirp/tcp_input.c slirp/tcp_output.c slirp/tcp_subr.c \ + slirp/tcp_timer.c slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c \ + wx-sdl2-display.c cdrom-ioctl-osx.c cdrom-ioctl.c \ + wx-sdl2-display-win.c +am__dirstamp = $(am__leading_dot)dirstamp @USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) @USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) @CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) @CPU_X86_64_TRUE@am__objects_4 = pcem-codegen_x86-64.$(OBJEXT) @USE_NETWORKING_TRUE@am__objects_5 = pcem-ne2000.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ -@USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(OBJEXT) -@OS_MACOSX_TRUE@am__objects_6 = pcem-cdrom-ioctl-osx.$(OBJEXT) -@OS_LINUX_TRUE@am__objects_7 = pcem-cdrom-ioctl-linux.$(OBJEXT) +@USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-bootp.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-cksum.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-debug.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-if.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-ip_icmp.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-ip_input.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-ip_output.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-mbuf.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-misc.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-queue.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-sbuf.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-slirp.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-socket.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-tcp_input.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-tcp_output.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-tcp_subr.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-tcp_timer.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-tftp.$(OBJEXT) \ +@USE_NETWORKING_TRUE@ slirp/pcem-udp.$(OBJEXT) +@OS_LINUX_TRUE@am__objects_6 = pcem-cdrom-ioctl-linux.$(OBJEXT) \ +@OS_LINUX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) +@OS_MACOSX_TRUE@am__objects_7 = pcem-cdrom-ioctl-osx.$(OBJEXT) \ +@OS_MACOSX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) +@OS_WINDOWS_TRUE@am__objects_8 = pcem-cdrom-ioctl.$(OBJEXT) \ +@OS_WINDOWS_TRUE@ pcem-wx-sdl2-display-win.$(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) \ @@ -205,7 +252,8 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-hdd.$(OBJEXT) pcem-hdd_esdi.$(OBJEXT) \ pcem-hdd_file.$(OBJEXT) pcem-headland.$(OBJEXT) \ pcem-i430lx.$(OBJEXT) pcem-i430fx.$(OBJEXT) \ - pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) pcem-intel.$(OBJEXT) \ + pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ + pcem-ide_atapi.$(OBJEXT) pcem-intel.$(OBJEXT) \ pcem-intel_flash.$(OBJEXT) pcem-io.$(OBJEXT) \ pcem-jim.$(OBJEXT) pcem-joystick_ch_flightstick_pro.$(OBJEXT) \ pcem-joystick_standard.$(OBJEXT) \ @@ -226,10 +274,12 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) \ pcem-ppi.$(OBJEXT) pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) \ pcem-ps2_mca.$(OBJEXT) pcem-ps2_nvr.$(OBJEXT) \ - pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) pcem-scat.$(OBJEXT) \ - pcem-scsi.$(OBJEXT) pcem-scsi_53c400.$(OBJEXT) \ - pcem-scsi_aha1540.$(OBJEXT) pcem-scsi_cd.$(OBJEXT) \ - pcem-scsi_hd.$(OBJEXT) pcem-serial.$(OBJEXT) \ + pcem-nvr_tc8521.$(OBJEXT) pcem-rom.$(OBJEXT) \ + pcem-rtc.$(OBJEXT) pcem-rtc_tc8521.$(OBJEXT) \ + pcem-scat.$(OBJEXT) pcem-scsi.$(OBJEXT) \ + pcem-scsi_53c400.$(OBJEXT) pcem-scsi_aha1540.$(OBJEXT) \ + pcem-scsi_cd.$(OBJEXT) pcem-scsi_hd.$(OBJEXT) \ + pcem-scsi_zip.$(OBJEXT) pcem-serial.$(OBJEXT) \ pcem-sio.$(OBJEXT) pcem-sis496.$(OBJEXT) pcem-sound.$(OBJEXT) \ pcem-sound_ad1848.$(OBJEXT) pcem-sound_adlib.$(OBJEXT) \ pcem-sound_adlibgold.$(OBJEXT) pcem-sound_audiopci.$(OBJEXT) \ @@ -242,24 +292,25 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-sound_ssi2001.$(OBJEXT) pcem-sound_wss.$(OBJEXT) \ pcem-sound_ym7128.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ pcem-tandy_eeprom.$(OBJEXT) pcem-tandy_rom.$(OBJEXT) \ - pcem-t3100e.$(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_colorplus.$(OBJEXT) \ - pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ - pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ - pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ - pcem-vid_ics2595.$(OBJEXT) pcem-vid_incolor.$(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_ps1_svga.$(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_t3100e.$(OBJEXT) \ + pcem-t1000.$(OBJEXT) pcem-t3100e.$(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_colorplus.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ + pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ + pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ + pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ + pcem-vid_incolor.$(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_ps1_svga.$(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_t1000.$(OBJEXT) pcem-vid_t3100e.$(OBJEXT) \ pcem-vid_tandy.$(OBJEXT) pcem-vid_tandysl.$(OBJEXT) \ pcem-vid_tgui9440.$(OBJEXT) pcem-vid_tkd8001_ramdac.$(OBJEXT) \ pcem-vid_tvga.$(OBJEXT) pcem-vid_unk_ramdac.$(OBJEXT) \ @@ -268,35 +319,43 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ - pcem-cdrom_image.$(OBJEXT) pcem-dbopl.$(OBJEXT) \ - pcem-nukedopl.$(OBJEXT) pcem-vid_cga_comp.$(OBJEXT) \ - pcem-convolve.$(OBJEXT) pcem-convolve-sse.$(OBJEXT) \ - pcem-envelope.$(OBJEXT) pcem-extfilt.$(OBJEXT) \ - pcem-filter.$(OBJEXT) pcem-pot.$(OBJEXT) pcem-sid.$(OBJEXT) \ - pcem-voice.$(OBJEXT) pcem-wave6581_PS_.$(OBJEXT) \ - pcem-wave6581_PST.$(OBJEXT) pcem-wave6581_P_T.$(OBJEXT) \ - pcem-wave6581__ST.$(OBJEXT) pcem-wave8580_PS_.$(OBJEXT) \ - pcem-wave8580_PST.$(OBJEXT) pcem-wave8580_P_T.$(OBJEXT) \ - pcem-wave8580__ST.$(OBJEXT) pcem-wave.$(OBJEXT) \ - pcem-wx-main.$(OBJEXT) pcem-wx-config_sel.$(OBJEXT) \ - pcem-wx-dialogbox.$(OBJEXT) pcem-wx-utils.$(OBJEXT) \ - pcem-wx-app.$(OBJEXT) pcem-wx-sdl2-joystick.$(OBJEXT) \ - pcem-wx-sdl2-mouse.$(OBJEXT) pcem-wx-sdl2-keyboard.$(OBJEXT) \ - pcem-wx-sdl2-video.$(OBJEXT) pcem-wx-sdl2.$(OBJEXT) \ - pcem-wx-config.$(OBJEXT) pcem-wx-deviceconfig.$(OBJEXT) \ - pcem-wx-status.$(OBJEXT) pcem-wx-sdl2-status.$(OBJEXT) \ - pcem-wx-resources.$(OBJEXT) pcem-wx-thread.$(OBJEXT) \ - pcem-wx-common.$(OBJEXT) pcem-wx-sdl2-display.$(OBJEXT) \ - pcem-wx-sdl2-video-renderer.$(OBJEXT) \ + dosbox/pcem-cdrom_image.$(OBJEXT) dosbox/pcem-dbopl.$(OBJEXT) \ + dosbox/pcem-nukedopl.$(OBJEXT) \ + dosbox/pcem-vid_cga_comp.$(OBJEXT) \ + resid-fp/pcem-convolve.$(OBJEXT) \ + resid-fp/pcem-convolve-sse.$(OBJEXT) \ + resid-fp/pcem-envelope.$(OBJEXT) \ + resid-fp/pcem-extfilt.$(OBJEXT) resid-fp/pcem-filter.$(OBJEXT) \ + resid-fp/pcem-pot.$(OBJEXT) resid-fp/pcem-sid.$(OBJEXT) \ + resid-fp/pcem-voice.$(OBJEXT) \ + resid-fp/pcem-wave6581_PS_.$(OBJEXT) \ + resid-fp/pcem-wave6581_PST.$(OBJEXT) \ + resid-fp/pcem-wave6581_P_T.$(OBJEXT) \ + resid-fp/pcem-wave6581__ST.$(OBJEXT) \ + resid-fp/pcem-wave8580_PS_.$(OBJEXT) \ + resid-fp/pcem-wave8580_PST.$(OBJEXT) \ + resid-fp/pcem-wave8580_P_T.$(OBJEXT) \ + resid-fp/pcem-wave8580__ST.$(OBJEXT) \ + resid-fp/pcem-wave.$(OBJEXT) pcem-wx-main.$(OBJEXT) \ + pcem-wx-config_sel.$(OBJEXT) pcem-wx-dialogbox.$(OBJEXT) \ + pcem-wx-utils.$(OBJEXT) pcem-wx-app.$(OBJEXT) \ + pcem-wx-sdl2-joystick.$(OBJEXT) pcem-wx-sdl2-mouse.$(OBJEXT) \ + pcem-wx-sdl2-keyboard.$(OBJEXT) pcem-wx-sdl2-video.$(OBJEXT) \ + pcem-wx-sdl2.$(OBJEXT) pcem-wx-config.$(OBJEXT) \ + pcem-wx-deviceconfig.$(OBJEXT) pcem-wx-status.$(OBJEXT) \ + pcem-wx-sdl2-status.$(OBJEXT) pcem-wx-thread.$(OBJEXT) \ + pcem-wx-common.$(OBJEXT) pcem-wx-sdl2-video-renderer.$(OBJEXT) \ pcem-wx-sdl2-video-gl3.$(OBJEXT) \ pcem-wx-glslp-parser.$(OBJEXT) pcem-wx-shader_man.$(OBJEXT) \ pcem-wx-shaderconfig.$(OBJEXT) \ - pcem-wx-joystickconfig.$(OBJEXT) $(am__objects_1) \ - $(am__objects_2) $(am__objects_3) $(am__objects_4) \ - $(am__objects_5) $(am__objects_6) $(am__objects_7) + pcem-wx-joystickconfig.$(OBJEXT) pcem-wx-createdisc.$(OBJEXT) \ + pcem-wx-resources.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = -pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__append_10) +pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__append_18) pcem_LINK = $(CXXLD) $(pcem_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SCRIPTS = $(noinst_SCRIPTS) @@ -490,8 +549,18 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -noinst_SCRIPTS = ../pcem -CLEANFILES = $(noinst_SCRIPTS) +AUTOMAKE_OPTIONS = subdir-objects +noinst_SCRIPTS = $(am__append_2) +CLEANFILES = $(am__append_1) + +# Special wxWidgets files +WINDRES = $(shell wx-config --rescomp) + +# PCem + +# DOSBox + +# resid-fp pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc \ cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c \ @@ -500,23 +569,24 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ - intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c \ + headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pci.c pic.c \ - piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c rom.c rtc.c \ - scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ + piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ + nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ + scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c \ sound_adlibgold.c sound_audiopci.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 \ - t3100e.c timer.c um8669f.c um8881f.c vid_ati_eeprom.c \ + t1000.c t3100e.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_colorplus.c \ vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ @@ -524,34 +594,35 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.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_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_t3100e.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 vid_wy700.c x86seg.c x87.c xtide.c sound_dbopl.cc \ - sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ - dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ - wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ - wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ - wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ - wx-status.cc wx-sdl2-status.c wx-resources.cpp wx-thread.c \ - wx-common.c wx-sdl2-display.c wx-sdl2-video-renderer.c \ - wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ - wx-shaderconfig.cc wx-joystickconfig.cc $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_6) \ - $(am__append_9) $(am__append_11) $(am__append_14) -pcem_CFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) $(am__append_5) $(am__append_7) $(am__append_12) \ - $(am__append_15) $(am__append_16) + vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c \ + vid_t3100e.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 vid_wy700.c x86seg.c x87.c \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ + wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ + wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ + wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ + wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ + wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_8) $(am__append_11) $(am__append_13) \ + $(am__append_14) $(am__append_17) +pcem_CFLAGS = $(subst -fpermissive,,$(shell wx-config --cxxflags) \ + $(shell sdl2-config --cflags)) $(am__append_7) $(am__append_9) \ + $(am__append_15) $(am__append_19) $(am__append_20) pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) $(am__append_8) $(am__append_13) $(am__append_17) -pcem_LDADD = @LIBS@ $(am__append_1) $(am__append_10) + --cflags) $(am__append_10) $(am__append_16) $(am__append_21) +pcem_LDADD = @LIBS@ $(am__append_3) $(am__append_12) $(am__append_18) all: all-am .SUFFIXES: @@ -627,6 +698,104 @@ uninstall-binPROGRAMS: clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +dosbox/$(am__dirstamp): + @$(MKDIR_P) dosbox + @: > dosbox/$(am__dirstamp) +dosbox/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) dosbox/$(DEPDIR) + @: > dosbox/$(DEPDIR)/$(am__dirstamp) +dosbox/pcem-cdrom_image.$(OBJEXT): dosbox/$(am__dirstamp) \ + dosbox/$(DEPDIR)/$(am__dirstamp) +dosbox/pcem-dbopl.$(OBJEXT): dosbox/$(am__dirstamp) \ + dosbox/$(DEPDIR)/$(am__dirstamp) +dosbox/pcem-nukedopl.$(OBJEXT): dosbox/$(am__dirstamp) \ + dosbox/$(DEPDIR)/$(am__dirstamp) +dosbox/pcem-vid_cga_comp.$(OBJEXT): dosbox/$(am__dirstamp) \ + dosbox/$(DEPDIR)/$(am__dirstamp) +resid-fp/$(am__dirstamp): + @$(MKDIR_P) resid-fp + @: > resid-fp/$(am__dirstamp) +resid-fp/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) resid-fp/$(DEPDIR) + @: > resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-convolve.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-convolve-sse.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-envelope.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-extfilt.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-filter.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-pot.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-sid.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-voice.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave6581_PS_.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave6581_PST.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave6581_P_T.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave6581__ST.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave8580_PS_.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave8580_PST.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave8580_P_T.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave8580__ST.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +resid-fp/pcem-wave.$(OBJEXT): resid-fp/$(am__dirstamp) \ + resid-fp/$(DEPDIR)/$(am__dirstamp) +slirp/$(am__dirstamp): + @$(MKDIR_P) slirp + @: > slirp/$(am__dirstamp) +slirp/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) slirp/$(DEPDIR) + @: > slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-bootp.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-cksum.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-debug.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-if.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-ip_icmp.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-ip_input.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-ip_output.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-mbuf.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-misc.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-queue.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-sbuf.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-slirp.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-socket.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-tcp_input.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-tcp_output.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-tcp_subr.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-tcp_timer.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-tftp.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) +slirp/pcem-udp.$(OBJEXT): slirp/$(am__dirstamp) \ + slirp/$(DEPDIR)/$(am__dirstamp) pcem$(EXEEXT): $(pcem_OBJECTS) $(pcem_DEPENDENCIES) $(EXTRA_pcem_DEPENDENCIES) @rm -f pcem$(EXEEXT) @@ -634,6 +803,9 @@ pcem$(EXEEXT): $(pcem_OBJECTS) $(pcem_DEPENDENCIES) $(EXTRA_pcem_DEPENDENCIES) mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f dosbox/*.$(OBJEXT) + -rm -f resid-fp/*.$(OBJEXT) + -rm -f slirp/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @@ -649,8 +821,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.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-ioctl-osx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom_image.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@ @@ -662,10 +834,7 @@ distclean-compile: @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-convolve-sse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-convolve.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dbopl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.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@ @@ -673,14 +842,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_img.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_sector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-envelope.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-extfilt.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-fdd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdi2raw.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ @@ -690,6 +856,7 @@ distclean-compile: @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-ide_atapi.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@ @@ -723,8 +890,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nmi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nukedopl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr_tc8521.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ @@ -733,7 +900,6 @@ distclean-compile: @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-pot.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-ps2.Po@am__quote@ @@ -741,14 +907,15 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.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@ @@ -774,6 +941,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_wss.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ym7128.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.Po@am__quote@ @@ -786,7 +954,6 @@ distclean-compile: @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_cga_comp.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_colorplus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ega.Po@am__quote@ @@ -812,6 +979,7 @@ distclean-compile: @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_t1000.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.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_tandysl.Po@am__quote@ @@ -823,21 +991,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_wy700.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-voice.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ @@ -845,6 +1004,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ @@ -863,17 +1023,59 @@ distclean-compile: @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@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` @@ -1438,6 +1640,20 @@ pcem-ide.obj: ide.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-ide_atapi.o: ide_atapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ide_atapi.o -MD -MP -MF $(DEPDIR)/pcem-ide_atapi.Tpo -c -o pcem-ide_atapi.o `test -f 'ide_atapi.c' || echo '$(srcdir)/'`ide_atapi.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-ide_atapi.Tpo $(DEPDIR)/pcem-ide_atapi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ide_atapi.c' object='pcem-ide_atapi.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide_atapi.o `test -f 'ide_atapi.c' || echo '$(srcdir)/'`ide_atapi.c + +pcem-ide_atapi.obj: ide_atapi.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ide_atapi.obj -MD -MP -MF $(DEPDIR)/pcem-ide_atapi.Tpo -c -o pcem-ide_atapi.obj `if test -f 'ide_atapi.c'; then $(CYGPATH_W) 'ide_atapi.c'; else $(CYGPATH_W) '$(srcdir)/ide_atapi.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-ide_atapi.Tpo $(DEPDIR)/pcem-ide_atapi.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ide_atapi.c' object='pcem-ide_atapi.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide_atapi.obj `if test -f 'ide_atapi.c'; then $(CYGPATH_W) 'ide_atapi.c'; else $(CYGPATH_W) '$(srcdir)/ide_atapi.c'; fi` + pcem-intel.o: intel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-intel.Tpo $(DEPDIR)/pcem-intel.Po @@ -2054,6 +2270,20 @@ pcem-ps2_nvr.obj: ps2_nvr.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ps2_nvr.obj `if test -f 'ps2_nvr.c'; then $(CYGPATH_W) 'ps2_nvr.c'; else $(CYGPATH_W) '$(srcdir)/ps2_nvr.c'; fi` +pcem-nvr_tc8521.o: nvr_tc8521.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nvr_tc8521.o -MD -MP -MF $(DEPDIR)/pcem-nvr_tc8521.Tpo -c -o pcem-nvr_tc8521.o `test -f 'nvr_tc8521.c' || echo '$(srcdir)/'`nvr_tc8521.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nvr_tc8521.Tpo $(DEPDIR)/pcem-nvr_tc8521.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nvr_tc8521.c' object='pcem-nvr_tc8521.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nvr_tc8521.o `test -f 'nvr_tc8521.c' || echo '$(srcdir)/'`nvr_tc8521.c + +pcem-nvr_tc8521.obj: nvr_tc8521.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nvr_tc8521.obj -MD -MP -MF $(DEPDIR)/pcem-nvr_tc8521.Tpo -c -o pcem-nvr_tc8521.obj `if test -f 'nvr_tc8521.c'; then $(CYGPATH_W) 'nvr_tc8521.c'; else $(CYGPATH_W) '$(srcdir)/nvr_tc8521.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nvr_tc8521.Tpo $(DEPDIR)/pcem-nvr_tc8521.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nvr_tc8521.c' object='pcem-nvr_tc8521.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nvr_tc8521.obj `if test -f 'nvr_tc8521.c'; then $(CYGPATH_W) 'nvr_tc8521.c'; else $(CYGPATH_W) '$(srcdir)/nvr_tc8521.c'; fi` + pcem-rom.o: rom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-rom.Tpo $(DEPDIR)/pcem-rom.Po @@ -2082,6 +2312,20 @@ pcem-rtc.obj: rtc.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-rtc.obj `if test -f 'rtc.c'; then $(CYGPATH_W) 'rtc.c'; else $(CYGPATH_W) '$(srcdir)/rtc.c'; fi` +pcem-rtc_tc8521.o: rtc_tc8521.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-rtc_tc8521.o -MD -MP -MF $(DEPDIR)/pcem-rtc_tc8521.Tpo -c -o pcem-rtc_tc8521.o `test -f 'rtc_tc8521.c' || echo '$(srcdir)/'`rtc_tc8521.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-rtc_tc8521.Tpo $(DEPDIR)/pcem-rtc_tc8521.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtc_tc8521.c' object='pcem-rtc_tc8521.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-rtc_tc8521.o `test -f 'rtc_tc8521.c' || echo '$(srcdir)/'`rtc_tc8521.c + +pcem-rtc_tc8521.obj: rtc_tc8521.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-rtc_tc8521.obj -MD -MP -MF $(DEPDIR)/pcem-rtc_tc8521.Tpo -c -o pcem-rtc_tc8521.obj `if test -f 'rtc_tc8521.c'; then $(CYGPATH_W) 'rtc_tc8521.c'; else $(CYGPATH_W) '$(srcdir)/rtc_tc8521.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-rtc_tc8521.Tpo $(DEPDIR)/pcem-rtc_tc8521.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rtc_tc8521.c' object='pcem-rtc_tc8521.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-rtc_tc8521.obj `if test -f 'rtc_tc8521.c'; then $(CYGPATH_W) 'rtc_tc8521.c'; else $(CYGPATH_W) '$(srcdir)/rtc_tc8521.c'; fi` + pcem-scat.o: scat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scat.o -MD -MP -MF $(DEPDIR)/pcem-scat.Tpo -c -o pcem-scat.o `test -f 'scat.c' || echo '$(srcdir)/'`scat.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scat.Tpo $(DEPDIR)/pcem-scat.Po @@ -2166,6 +2410,20 @@ pcem-scsi_hd.obj: scsi_hd.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_hd.obj `if test -f 'scsi_hd.c'; then $(CYGPATH_W) 'scsi_hd.c'; else $(CYGPATH_W) '$(srcdir)/scsi_hd.c'; fi` +pcem-scsi_zip.o: scsi_zip.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_zip.o -MD -MP -MF $(DEPDIR)/pcem-scsi_zip.Tpo -c -o pcem-scsi_zip.o `test -f 'scsi_zip.c' || echo '$(srcdir)/'`scsi_zip.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_zip.Tpo $(DEPDIR)/pcem-scsi_zip.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_zip.c' object='pcem-scsi_zip.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_zip.o `test -f 'scsi_zip.c' || echo '$(srcdir)/'`scsi_zip.c + +pcem-scsi_zip.obj: scsi_zip.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_zip.obj -MD -MP -MF $(DEPDIR)/pcem-scsi_zip.Tpo -c -o pcem-scsi_zip.obj `if test -f 'scsi_zip.c'; then $(CYGPATH_W) 'scsi_zip.c'; else $(CYGPATH_W) '$(srcdir)/scsi_zip.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_zip.Tpo $(DEPDIR)/pcem-scsi_zip.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_zip.c' object='pcem-scsi_zip.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_zip.obj `if test -f 'scsi_zip.c'; then $(CYGPATH_W) 'scsi_zip.c'; else $(CYGPATH_W) '$(srcdir)/scsi_zip.c'; fi` + pcem-serial.o: serial.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-serial.Tpo $(DEPDIR)/pcem-serial.Po @@ -2530,6 +2788,20 @@ pcem-tandy_rom.obj: tandy_rom.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-tandy_rom.obj `if test -f 'tandy_rom.c'; then $(CYGPATH_W) 'tandy_rom.c'; else $(CYGPATH_W) '$(srcdir)/tandy_rom.c'; fi` +pcem-t1000.o: t1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-t1000.o -MD -MP -MF $(DEPDIR)/pcem-t1000.Tpo -c -o pcem-t1000.o `test -f 't1000.c' || echo '$(srcdir)/'`t1000.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-t1000.Tpo $(DEPDIR)/pcem-t1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1000.c' object='pcem-t1000.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-t1000.o `test -f 't1000.c' || echo '$(srcdir)/'`t1000.c + +pcem-t1000.obj: t1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-t1000.obj -MD -MP -MF $(DEPDIR)/pcem-t1000.Tpo -c -o pcem-t1000.obj `if test -f 't1000.c'; then $(CYGPATH_W) 't1000.c'; else $(CYGPATH_W) '$(srcdir)/t1000.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-t1000.Tpo $(DEPDIR)/pcem-t1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t1000.c' object='pcem-t1000.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-t1000.obj `if test -f 't1000.c'; then $(CYGPATH_W) 't1000.c'; else $(CYGPATH_W) '$(srcdir)/t1000.c'; fi` + pcem-t3100e.o: t3100e.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-t3100e.o -MD -MP -MF $(DEPDIR)/pcem-t3100e.Tpo -c -o pcem-t3100e.o `test -f 't3100e.c' || echo '$(srcdir)/'`t3100e.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-t3100e.Tpo $(DEPDIR)/pcem-t3100e.Po @@ -3020,6 +3292,20 @@ pcem-vid_svga_render.obj: vid_svga_render.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_t1000.o: vid_t1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_t1000.o -MD -MP -MF $(DEPDIR)/pcem-vid_t1000.Tpo -c -o pcem-vid_t1000.o `test -f 'vid_t1000.c' || echo '$(srcdir)/'`vid_t1000.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_t1000.Tpo $(DEPDIR)/pcem-vid_t1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_t1000.c' object='pcem-vid_t1000.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_t1000.o `test -f 'vid_t1000.c' || echo '$(srcdir)/'`vid_t1000.c + +pcem-vid_t1000.obj: vid_t1000.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_t1000.obj -MD -MP -MF $(DEPDIR)/pcem-vid_t1000.Tpo -c -o pcem-vid_t1000.obj `if test -f 'vid_t1000.c'; then $(CYGPATH_W) 'vid_t1000.c'; else $(CYGPATH_W) '$(srcdir)/vid_t1000.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_t1000.Tpo $(DEPDIR)/pcem-vid_t1000.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_t1000.c' object='pcem-vid_t1000.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_t1000.obj `if test -f 'vid_t1000.c'; then $(CYGPATH_W) 'vid_t1000.c'; else $(CYGPATH_W) '$(srcdir)/vid_t1000.c'; fi` + pcem-vid_t3100e.o: vid_t3100e.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_t3100e.o -MD -MP -MF $(DEPDIR)/pcem-vid_t3100e.Tpo -c -o pcem-vid_t3100e.o `test -f 'vid_t3100e.c' || echo '$(srcdir)/'`vid_t3100e.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_t3100e.Tpo $(DEPDIR)/pcem-vid_t3100e.Po @@ -3230,19 +3516,19 @@ pcem-xtide.obj: xtide.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-vid_cga_comp.o: dosbox/vid_cga_comp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_cga_comp.o -MD -MP -MF $(DEPDIR)/pcem-vid_cga_comp.Tpo -c -o pcem-vid_cga_comp.o `test -f 'dosbox/vid_cga_comp.c' || echo '$(srcdir)/'`dosbox/vid_cga_comp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_cga_comp.Tpo $(DEPDIR)/pcem-vid_cga_comp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dosbox/vid_cga_comp.c' object='pcem-vid_cga_comp.o' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-vid_cga_comp.o: dosbox/vid_cga_comp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT dosbox/pcem-vid_cga_comp.o -MD -MP -MF dosbox/$(DEPDIR)/pcem-vid_cga_comp.Tpo -c -o dosbox/pcem-vid_cga_comp.o `test -f 'dosbox/vid_cga_comp.c' || echo '$(srcdir)/'`dosbox/vid_cga_comp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-vid_cga_comp.Tpo dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dosbox/vid_cga_comp.c' object='dosbox/pcem-vid_cga_comp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cga_comp.o `test -f 'dosbox/vid_cga_comp.c' || echo '$(srcdir)/'`dosbox/vid_cga_comp.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o dosbox/pcem-vid_cga_comp.o `test -f 'dosbox/vid_cga_comp.c' || echo '$(srcdir)/'`dosbox/vid_cga_comp.c -pcem-vid_cga_comp.obj: dosbox/vid_cga_comp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_cga_comp.obj -MD -MP -MF $(DEPDIR)/pcem-vid_cga_comp.Tpo -c -o pcem-vid_cga_comp.obj `if test -f 'dosbox/vid_cga_comp.c'; then $(CYGPATH_W) 'dosbox/vid_cga_comp.c'; else $(CYGPATH_W) '$(srcdir)/dosbox/vid_cga_comp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_cga_comp.Tpo $(DEPDIR)/pcem-vid_cga_comp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dosbox/vid_cga_comp.c' object='pcem-vid_cga_comp.obj' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-vid_cga_comp.obj: dosbox/vid_cga_comp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT dosbox/pcem-vid_cga_comp.obj -MD -MP -MF dosbox/$(DEPDIR)/pcem-vid_cga_comp.Tpo -c -o dosbox/pcem-vid_cga_comp.obj `if test -f 'dosbox/vid_cga_comp.c'; then $(CYGPATH_W) 'dosbox/vid_cga_comp.c'; else $(CYGPATH_W) '$(srcdir)/dosbox/vid_cga_comp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-vid_cga_comp.Tpo dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dosbox/vid_cga_comp.c' object='dosbox/pcem-vid_cga_comp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cga_comp.obj `if test -f 'dosbox/vid_cga_comp.c'; then $(CYGPATH_W) 'dosbox/vid_cga_comp.c'; else $(CYGPATH_W) '$(srcdir)/dosbox/vid_cga_comp.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o dosbox/pcem-vid_cga_comp.obj `if test -f 'dosbox/vid_cga_comp.c'; then $(CYGPATH_W) 'dosbox/vid_cga_comp.c'; else $(CYGPATH_W) '$(srcdir)/dosbox/vid_cga_comp.c'; fi` pcem-wx-config_sel.o: wx-config_sel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-config_sel.o -MD -MP -MF $(DEPDIR)/pcem-wx-config_sel.Tpo -c -o pcem-wx-config_sel.o `test -f 'wx-config_sel.c' || echo '$(srcdir)/'`wx-config_sel.c @@ -3384,20 +3670,6 @@ pcem-wx-common.obj: wx-common.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-common.obj `if test -f 'wx-common.c'; then $(CYGPATH_W) 'wx-common.c'; else $(CYGPATH_W) '$(srcdir)/wx-common.c'; fi` -pcem-wx-sdl2-display.o: wx-sdl2-display.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display.Tpo -c -o pcem-wx-sdl2-display.o `test -f 'wx-sdl2-display.c' || echo '$(srcdir)/'`wx-sdl2-display.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display.Tpo $(DEPDIR)/pcem-wx-sdl2-display.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display.c' object='pcem-wx-sdl2-display.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.o `test -f 'wx-sdl2-display.c' || echo '$(srcdir)/'`wx-sdl2-display.c - -pcem-wx-sdl2-display.obj: wx-sdl2-display.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display.Tpo -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display.Tpo $(DEPDIR)/pcem-wx-sdl2-display.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display.c' object='pcem-wx-sdl2-display.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` - pcem-wx-sdl2-video-renderer.o: wx-sdl2-video-renderer.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-video-renderer.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-video-renderer.Tpo -c -o pcem-wx-sdl2-video-renderer.o `test -f 'wx-sdl2-video-renderer.c' || echo '$(srcdir)/'`wx-sdl2-video-renderer.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-video-renderer.Tpo $(DEPDIR)/pcem-wx-sdl2-video-renderer.Po @@ -3552,19 +3824,271 @@ pcem-wx-hostconfig.obj: wx-hostconfig.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-hostconfig.obj `if test -f 'wx-hostconfig.c'; then $(CYGPATH_W) 'wx-hostconfig.c'; else $(CYGPATH_W) '$(srcdir)/wx-hostconfig.c'; fi` -pcem-cdrom-ioctl-osx.o: cdrom-ioctl-osx.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-osx.c' object='pcem-cdrom-ioctl-osx.o' libtool=no @AMDEPBACKSLASH@ +slirp/pcem-bootp.o: slirp/bootp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-bootp.o -MD -MP -MF slirp/$(DEPDIR)/pcem-bootp.Tpo -c -o slirp/pcem-bootp.o `test -f 'slirp/bootp.c' || echo '$(srcdir)/'`slirp/bootp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-bootp.Tpo slirp/$(DEPDIR)/pcem-bootp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/bootp.c' object='slirp/pcem-bootp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-bootp.o `test -f 'slirp/bootp.c' || echo '$(srcdir)/'`slirp/bootp.c -pcem-cdrom-ioctl-osx.obj: cdrom-ioctl-osx.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.obj `if test -f 'cdrom-ioctl-osx.c'; then $(CYGPATH_W) 'cdrom-ioctl-osx.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-osx.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-osx.c' object='pcem-cdrom-ioctl-osx.obj' libtool=no @AMDEPBACKSLASH@ +slirp/pcem-bootp.obj: slirp/bootp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-bootp.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-bootp.Tpo -c -o slirp/pcem-bootp.obj `if test -f 'slirp/bootp.c'; then $(CYGPATH_W) 'slirp/bootp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/bootp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-bootp.Tpo slirp/$(DEPDIR)/pcem-bootp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/bootp.c' object='slirp/pcem-bootp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-osx.obj `if test -f 'cdrom-ioctl-osx.c'; then $(CYGPATH_W) 'cdrom-ioctl-osx.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-osx.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-bootp.obj `if test -f 'slirp/bootp.c'; then $(CYGPATH_W) 'slirp/bootp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/bootp.c'; fi` + +slirp/pcem-cksum.o: slirp/cksum.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-cksum.o -MD -MP -MF slirp/$(DEPDIR)/pcem-cksum.Tpo -c -o slirp/pcem-cksum.o `test -f 'slirp/cksum.c' || echo '$(srcdir)/'`slirp/cksum.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-cksum.Tpo slirp/$(DEPDIR)/pcem-cksum.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/cksum.c' object='slirp/pcem-cksum.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-cksum.o `test -f 'slirp/cksum.c' || echo '$(srcdir)/'`slirp/cksum.c + +slirp/pcem-cksum.obj: slirp/cksum.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-cksum.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-cksum.Tpo -c -o slirp/pcem-cksum.obj `if test -f 'slirp/cksum.c'; then $(CYGPATH_W) 'slirp/cksum.c'; else $(CYGPATH_W) '$(srcdir)/slirp/cksum.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-cksum.Tpo slirp/$(DEPDIR)/pcem-cksum.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/cksum.c' object='slirp/pcem-cksum.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-cksum.obj `if test -f 'slirp/cksum.c'; then $(CYGPATH_W) 'slirp/cksum.c'; else $(CYGPATH_W) '$(srcdir)/slirp/cksum.c'; fi` + +slirp/pcem-debug.o: slirp/debug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-debug.o -MD -MP -MF slirp/$(DEPDIR)/pcem-debug.Tpo -c -o slirp/pcem-debug.o `test -f 'slirp/debug.c' || echo '$(srcdir)/'`slirp/debug.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-debug.Tpo slirp/$(DEPDIR)/pcem-debug.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/debug.c' object='slirp/pcem-debug.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-debug.o `test -f 'slirp/debug.c' || echo '$(srcdir)/'`slirp/debug.c + +slirp/pcem-debug.obj: slirp/debug.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-debug.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-debug.Tpo -c -o slirp/pcem-debug.obj `if test -f 'slirp/debug.c'; then $(CYGPATH_W) 'slirp/debug.c'; else $(CYGPATH_W) '$(srcdir)/slirp/debug.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-debug.Tpo slirp/$(DEPDIR)/pcem-debug.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/debug.c' object='slirp/pcem-debug.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-debug.obj `if test -f 'slirp/debug.c'; then $(CYGPATH_W) 'slirp/debug.c'; else $(CYGPATH_W) '$(srcdir)/slirp/debug.c'; fi` + +slirp/pcem-if.o: slirp/if.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-if.o -MD -MP -MF slirp/$(DEPDIR)/pcem-if.Tpo -c -o slirp/pcem-if.o `test -f 'slirp/if.c' || echo '$(srcdir)/'`slirp/if.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-if.Tpo slirp/$(DEPDIR)/pcem-if.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/if.c' object='slirp/pcem-if.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-if.o `test -f 'slirp/if.c' || echo '$(srcdir)/'`slirp/if.c + +slirp/pcem-if.obj: slirp/if.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-if.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-if.Tpo -c -o slirp/pcem-if.obj `if test -f 'slirp/if.c'; then $(CYGPATH_W) 'slirp/if.c'; else $(CYGPATH_W) '$(srcdir)/slirp/if.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-if.Tpo slirp/$(DEPDIR)/pcem-if.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/if.c' object='slirp/pcem-if.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-if.obj `if test -f 'slirp/if.c'; then $(CYGPATH_W) 'slirp/if.c'; else $(CYGPATH_W) '$(srcdir)/slirp/if.c'; fi` + +slirp/pcem-ip_icmp.o: slirp/ip_icmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-ip_icmp.o -MD -MP -MF slirp/$(DEPDIR)/pcem-ip_icmp.Tpo -c -o slirp/pcem-ip_icmp.o `test -f 'slirp/ip_icmp.c' || echo '$(srcdir)/'`slirp/ip_icmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-ip_icmp.Tpo slirp/$(DEPDIR)/pcem-ip_icmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/ip_icmp.c' object='slirp/pcem-ip_icmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-ip_icmp.o `test -f 'slirp/ip_icmp.c' || echo '$(srcdir)/'`slirp/ip_icmp.c + +slirp/pcem-ip_icmp.obj: slirp/ip_icmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-ip_icmp.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-ip_icmp.Tpo -c -o slirp/pcem-ip_icmp.obj `if test -f 'slirp/ip_icmp.c'; then $(CYGPATH_W) 'slirp/ip_icmp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/ip_icmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-ip_icmp.Tpo slirp/$(DEPDIR)/pcem-ip_icmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/ip_icmp.c' object='slirp/pcem-ip_icmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-ip_icmp.obj `if test -f 'slirp/ip_icmp.c'; then $(CYGPATH_W) 'slirp/ip_icmp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/ip_icmp.c'; fi` + +slirp/pcem-ip_input.o: slirp/ip_input.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-ip_input.o -MD -MP -MF slirp/$(DEPDIR)/pcem-ip_input.Tpo -c -o slirp/pcem-ip_input.o `test -f 'slirp/ip_input.c' || echo '$(srcdir)/'`slirp/ip_input.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-ip_input.Tpo slirp/$(DEPDIR)/pcem-ip_input.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/ip_input.c' object='slirp/pcem-ip_input.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-ip_input.o `test -f 'slirp/ip_input.c' || echo '$(srcdir)/'`slirp/ip_input.c + +slirp/pcem-ip_input.obj: slirp/ip_input.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-ip_input.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-ip_input.Tpo -c -o slirp/pcem-ip_input.obj `if test -f 'slirp/ip_input.c'; then $(CYGPATH_W) 'slirp/ip_input.c'; else $(CYGPATH_W) '$(srcdir)/slirp/ip_input.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-ip_input.Tpo slirp/$(DEPDIR)/pcem-ip_input.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/ip_input.c' object='slirp/pcem-ip_input.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-ip_input.obj `if test -f 'slirp/ip_input.c'; then $(CYGPATH_W) 'slirp/ip_input.c'; else $(CYGPATH_W) '$(srcdir)/slirp/ip_input.c'; fi` + +slirp/pcem-ip_output.o: slirp/ip_output.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-ip_output.o -MD -MP -MF slirp/$(DEPDIR)/pcem-ip_output.Tpo -c -o slirp/pcem-ip_output.o `test -f 'slirp/ip_output.c' || echo '$(srcdir)/'`slirp/ip_output.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-ip_output.Tpo slirp/$(DEPDIR)/pcem-ip_output.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/ip_output.c' object='slirp/pcem-ip_output.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-ip_output.o `test -f 'slirp/ip_output.c' || echo '$(srcdir)/'`slirp/ip_output.c + +slirp/pcem-ip_output.obj: slirp/ip_output.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-ip_output.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-ip_output.Tpo -c -o slirp/pcem-ip_output.obj `if test -f 'slirp/ip_output.c'; then $(CYGPATH_W) 'slirp/ip_output.c'; else $(CYGPATH_W) '$(srcdir)/slirp/ip_output.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-ip_output.Tpo slirp/$(DEPDIR)/pcem-ip_output.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/ip_output.c' object='slirp/pcem-ip_output.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-ip_output.obj `if test -f 'slirp/ip_output.c'; then $(CYGPATH_W) 'slirp/ip_output.c'; else $(CYGPATH_W) '$(srcdir)/slirp/ip_output.c'; fi` + +slirp/pcem-mbuf.o: slirp/mbuf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-mbuf.o -MD -MP -MF slirp/$(DEPDIR)/pcem-mbuf.Tpo -c -o slirp/pcem-mbuf.o `test -f 'slirp/mbuf.c' || echo '$(srcdir)/'`slirp/mbuf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-mbuf.Tpo slirp/$(DEPDIR)/pcem-mbuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/mbuf.c' object='slirp/pcem-mbuf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-mbuf.o `test -f 'slirp/mbuf.c' || echo '$(srcdir)/'`slirp/mbuf.c + +slirp/pcem-mbuf.obj: slirp/mbuf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-mbuf.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-mbuf.Tpo -c -o slirp/pcem-mbuf.obj `if test -f 'slirp/mbuf.c'; then $(CYGPATH_W) 'slirp/mbuf.c'; else $(CYGPATH_W) '$(srcdir)/slirp/mbuf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-mbuf.Tpo slirp/$(DEPDIR)/pcem-mbuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/mbuf.c' object='slirp/pcem-mbuf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-mbuf.obj `if test -f 'slirp/mbuf.c'; then $(CYGPATH_W) 'slirp/mbuf.c'; else $(CYGPATH_W) '$(srcdir)/slirp/mbuf.c'; fi` + +slirp/pcem-misc.o: slirp/misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-misc.o -MD -MP -MF slirp/$(DEPDIR)/pcem-misc.Tpo -c -o slirp/pcem-misc.o `test -f 'slirp/misc.c' || echo '$(srcdir)/'`slirp/misc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-misc.Tpo slirp/$(DEPDIR)/pcem-misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/misc.c' object='slirp/pcem-misc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-misc.o `test -f 'slirp/misc.c' || echo '$(srcdir)/'`slirp/misc.c + +slirp/pcem-misc.obj: slirp/misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-misc.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-misc.Tpo -c -o slirp/pcem-misc.obj `if test -f 'slirp/misc.c'; then $(CYGPATH_W) 'slirp/misc.c'; else $(CYGPATH_W) '$(srcdir)/slirp/misc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-misc.Tpo slirp/$(DEPDIR)/pcem-misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/misc.c' object='slirp/pcem-misc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-misc.obj `if test -f 'slirp/misc.c'; then $(CYGPATH_W) 'slirp/misc.c'; else $(CYGPATH_W) '$(srcdir)/slirp/misc.c'; fi` + +slirp/pcem-queue.o: slirp/queue.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-queue.o -MD -MP -MF slirp/$(DEPDIR)/pcem-queue.Tpo -c -o slirp/pcem-queue.o `test -f 'slirp/queue.c' || echo '$(srcdir)/'`slirp/queue.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-queue.Tpo slirp/$(DEPDIR)/pcem-queue.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/queue.c' object='slirp/pcem-queue.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-queue.o `test -f 'slirp/queue.c' || echo '$(srcdir)/'`slirp/queue.c + +slirp/pcem-queue.obj: slirp/queue.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-queue.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-queue.Tpo -c -o slirp/pcem-queue.obj `if test -f 'slirp/queue.c'; then $(CYGPATH_W) 'slirp/queue.c'; else $(CYGPATH_W) '$(srcdir)/slirp/queue.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-queue.Tpo slirp/$(DEPDIR)/pcem-queue.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/queue.c' object='slirp/pcem-queue.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-queue.obj `if test -f 'slirp/queue.c'; then $(CYGPATH_W) 'slirp/queue.c'; else $(CYGPATH_W) '$(srcdir)/slirp/queue.c'; fi` + +slirp/pcem-sbuf.o: slirp/sbuf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-sbuf.o -MD -MP -MF slirp/$(DEPDIR)/pcem-sbuf.Tpo -c -o slirp/pcem-sbuf.o `test -f 'slirp/sbuf.c' || echo '$(srcdir)/'`slirp/sbuf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-sbuf.Tpo slirp/$(DEPDIR)/pcem-sbuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/sbuf.c' object='slirp/pcem-sbuf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-sbuf.o `test -f 'slirp/sbuf.c' || echo '$(srcdir)/'`slirp/sbuf.c + +slirp/pcem-sbuf.obj: slirp/sbuf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-sbuf.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-sbuf.Tpo -c -o slirp/pcem-sbuf.obj `if test -f 'slirp/sbuf.c'; then $(CYGPATH_W) 'slirp/sbuf.c'; else $(CYGPATH_W) '$(srcdir)/slirp/sbuf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-sbuf.Tpo slirp/$(DEPDIR)/pcem-sbuf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/sbuf.c' object='slirp/pcem-sbuf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-sbuf.obj `if test -f 'slirp/sbuf.c'; then $(CYGPATH_W) 'slirp/sbuf.c'; else $(CYGPATH_W) '$(srcdir)/slirp/sbuf.c'; fi` + +slirp/pcem-slirp.o: slirp/slirp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-slirp.o -MD -MP -MF slirp/$(DEPDIR)/pcem-slirp.Tpo -c -o slirp/pcem-slirp.o `test -f 'slirp/slirp.c' || echo '$(srcdir)/'`slirp/slirp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-slirp.Tpo slirp/$(DEPDIR)/pcem-slirp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/slirp.c' object='slirp/pcem-slirp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-slirp.o `test -f 'slirp/slirp.c' || echo '$(srcdir)/'`slirp/slirp.c + +slirp/pcem-slirp.obj: slirp/slirp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-slirp.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-slirp.Tpo -c -o slirp/pcem-slirp.obj `if test -f 'slirp/slirp.c'; then $(CYGPATH_W) 'slirp/slirp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/slirp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-slirp.Tpo slirp/$(DEPDIR)/pcem-slirp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/slirp.c' object='slirp/pcem-slirp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-slirp.obj `if test -f 'slirp/slirp.c'; then $(CYGPATH_W) 'slirp/slirp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/slirp.c'; fi` + +slirp/pcem-socket.o: slirp/socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-socket.o -MD -MP -MF slirp/$(DEPDIR)/pcem-socket.Tpo -c -o slirp/pcem-socket.o `test -f 'slirp/socket.c' || echo '$(srcdir)/'`slirp/socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-socket.Tpo slirp/$(DEPDIR)/pcem-socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/socket.c' object='slirp/pcem-socket.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-socket.o `test -f 'slirp/socket.c' || echo '$(srcdir)/'`slirp/socket.c + +slirp/pcem-socket.obj: slirp/socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-socket.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-socket.Tpo -c -o slirp/pcem-socket.obj `if test -f 'slirp/socket.c'; then $(CYGPATH_W) 'slirp/socket.c'; else $(CYGPATH_W) '$(srcdir)/slirp/socket.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-socket.Tpo slirp/$(DEPDIR)/pcem-socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/socket.c' object='slirp/pcem-socket.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-socket.obj `if test -f 'slirp/socket.c'; then $(CYGPATH_W) 'slirp/socket.c'; else $(CYGPATH_W) '$(srcdir)/slirp/socket.c'; fi` + +slirp/pcem-tcp_input.o: slirp/tcp_input.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_input.o -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_input.Tpo -c -o slirp/pcem-tcp_input.o `test -f 'slirp/tcp_input.c' || echo '$(srcdir)/'`slirp/tcp_input.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_input.Tpo slirp/$(DEPDIR)/pcem-tcp_input.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_input.c' object='slirp/pcem-tcp_input.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_input.o `test -f 'slirp/tcp_input.c' || echo '$(srcdir)/'`slirp/tcp_input.c + +slirp/pcem-tcp_input.obj: slirp/tcp_input.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_input.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_input.Tpo -c -o slirp/pcem-tcp_input.obj `if test -f 'slirp/tcp_input.c'; then $(CYGPATH_W) 'slirp/tcp_input.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_input.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_input.Tpo slirp/$(DEPDIR)/pcem-tcp_input.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_input.c' object='slirp/pcem-tcp_input.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_input.obj `if test -f 'slirp/tcp_input.c'; then $(CYGPATH_W) 'slirp/tcp_input.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_input.c'; fi` + +slirp/pcem-tcp_output.o: slirp/tcp_output.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_output.o -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_output.Tpo -c -o slirp/pcem-tcp_output.o `test -f 'slirp/tcp_output.c' || echo '$(srcdir)/'`slirp/tcp_output.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_output.Tpo slirp/$(DEPDIR)/pcem-tcp_output.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_output.c' object='slirp/pcem-tcp_output.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_output.o `test -f 'slirp/tcp_output.c' || echo '$(srcdir)/'`slirp/tcp_output.c + +slirp/pcem-tcp_output.obj: slirp/tcp_output.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_output.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_output.Tpo -c -o slirp/pcem-tcp_output.obj `if test -f 'slirp/tcp_output.c'; then $(CYGPATH_W) 'slirp/tcp_output.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_output.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_output.Tpo slirp/$(DEPDIR)/pcem-tcp_output.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_output.c' object='slirp/pcem-tcp_output.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_output.obj `if test -f 'slirp/tcp_output.c'; then $(CYGPATH_W) 'slirp/tcp_output.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_output.c'; fi` + +slirp/pcem-tcp_subr.o: slirp/tcp_subr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_subr.o -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_subr.Tpo -c -o slirp/pcem-tcp_subr.o `test -f 'slirp/tcp_subr.c' || echo '$(srcdir)/'`slirp/tcp_subr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_subr.Tpo slirp/$(DEPDIR)/pcem-tcp_subr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_subr.c' object='slirp/pcem-tcp_subr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_subr.o `test -f 'slirp/tcp_subr.c' || echo '$(srcdir)/'`slirp/tcp_subr.c + +slirp/pcem-tcp_subr.obj: slirp/tcp_subr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_subr.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_subr.Tpo -c -o slirp/pcem-tcp_subr.obj `if test -f 'slirp/tcp_subr.c'; then $(CYGPATH_W) 'slirp/tcp_subr.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_subr.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_subr.Tpo slirp/$(DEPDIR)/pcem-tcp_subr.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_subr.c' object='slirp/pcem-tcp_subr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_subr.obj `if test -f 'slirp/tcp_subr.c'; then $(CYGPATH_W) 'slirp/tcp_subr.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_subr.c'; fi` + +slirp/pcem-tcp_timer.o: slirp/tcp_timer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_timer.o -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_timer.Tpo -c -o slirp/pcem-tcp_timer.o `test -f 'slirp/tcp_timer.c' || echo '$(srcdir)/'`slirp/tcp_timer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_timer.Tpo slirp/$(DEPDIR)/pcem-tcp_timer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_timer.c' object='slirp/pcem-tcp_timer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_timer.o `test -f 'slirp/tcp_timer.c' || echo '$(srcdir)/'`slirp/tcp_timer.c + +slirp/pcem-tcp_timer.obj: slirp/tcp_timer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tcp_timer.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-tcp_timer.Tpo -c -o slirp/pcem-tcp_timer.obj `if test -f 'slirp/tcp_timer.c'; then $(CYGPATH_W) 'slirp/tcp_timer.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_timer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tcp_timer.Tpo slirp/$(DEPDIR)/pcem-tcp_timer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tcp_timer.c' object='slirp/pcem-tcp_timer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tcp_timer.obj `if test -f 'slirp/tcp_timer.c'; then $(CYGPATH_W) 'slirp/tcp_timer.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tcp_timer.c'; fi` + +slirp/pcem-tftp.o: slirp/tftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tftp.o -MD -MP -MF slirp/$(DEPDIR)/pcem-tftp.Tpo -c -o slirp/pcem-tftp.o `test -f 'slirp/tftp.c' || echo '$(srcdir)/'`slirp/tftp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tftp.Tpo slirp/$(DEPDIR)/pcem-tftp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tftp.c' object='slirp/pcem-tftp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tftp.o `test -f 'slirp/tftp.c' || echo '$(srcdir)/'`slirp/tftp.c + +slirp/pcem-tftp.obj: slirp/tftp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-tftp.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-tftp.Tpo -c -o slirp/pcem-tftp.obj `if test -f 'slirp/tftp.c'; then $(CYGPATH_W) 'slirp/tftp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tftp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-tftp.Tpo slirp/$(DEPDIR)/pcem-tftp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/tftp.c' object='slirp/pcem-tftp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-tftp.obj `if test -f 'slirp/tftp.c'; then $(CYGPATH_W) 'slirp/tftp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/tftp.c'; fi` + +slirp/pcem-udp.o: slirp/udp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-udp.o -MD -MP -MF slirp/$(DEPDIR)/pcem-udp.Tpo -c -o slirp/pcem-udp.o `test -f 'slirp/udp.c' || echo '$(srcdir)/'`slirp/udp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-udp.Tpo slirp/$(DEPDIR)/pcem-udp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/udp.c' object='slirp/pcem-udp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-udp.o `test -f 'slirp/udp.c' || echo '$(srcdir)/'`slirp/udp.c + +slirp/pcem-udp.obj: slirp/udp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT slirp/pcem-udp.obj -MD -MP -MF slirp/$(DEPDIR)/pcem-udp.Tpo -c -o slirp/pcem-udp.obj `if test -f 'slirp/udp.c'; then $(CYGPATH_W) 'slirp/udp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/udp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) slirp/$(DEPDIR)/pcem-udp.Tpo slirp/$(DEPDIR)/pcem-udp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='slirp/udp.c' object='slirp/pcem-udp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o slirp/pcem-udp.obj `if test -f 'slirp/udp.c'; then $(CYGPATH_W) 'slirp/udp.c'; else $(CYGPATH_W) '$(srcdir)/slirp/udp.c'; fi` pcem-cdrom-ioctl-linux.o: cdrom-ioctl-linux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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 @@ -3580,16 +4104,74 @@ pcem-cdrom-ioctl-linux.obj: cdrom-ioctl-linux.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-wx-sdl2-display.o: wx-sdl2-display.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display.Tpo -c -o pcem-wx-sdl2-display.o `test -f 'wx-sdl2-display.c' || echo '$(srcdir)/'`wx-sdl2-display.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display.Tpo $(DEPDIR)/pcem-wx-sdl2-display.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display.c' object='pcem-wx-sdl2-display.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.o `test -f 'wx-sdl2-display.c' || echo '$(srcdir)/'`wx-sdl2-display.c + +pcem-wx-sdl2-display.obj: wx-sdl2-display.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display.Tpo -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display.Tpo $(DEPDIR)/pcem-wx-sdl2-display.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display.c' object='pcem-wx-sdl2-display.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` + +pcem-cdrom-ioctl-osx.o: cdrom-ioctl-osx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-osx.c' object='pcem-cdrom-ioctl-osx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c + +pcem-cdrom-ioctl-osx.obj: cdrom-ioctl-osx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.obj `if test -f 'cdrom-ioctl-osx.c'; then $(CYGPATH_W) 'cdrom-ioctl-osx.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-osx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-osx.c' object='pcem-cdrom-ioctl-osx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-osx.obj `if test -f 'cdrom-ioctl-osx.c'; then $(CYGPATH_W) 'cdrom-ioctl-osx.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-osx.c'; fi` + +pcem-cdrom-ioctl.o: cdrom-ioctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl.Tpo -c -o pcem-cdrom-ioctl.o `test -f 'cdrom-ioctl.c' || echo '$(srcdir)/'`cdrom-ioctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl.Tpo $(DEPDIR)/pcem-cdrom-ioctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl.c' object='pcem-cdrom-ioctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl.o `test -f 'cdrom-ioctl.c' || echo '$(srcdir)/'`cdrom-ioctl.c + +pcem-cdrom-ioctl.obj: cdrom-ioctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl.Tpo -c -o pcem-cdrom-ioctl.obj `if test -f 'cdrom-ioctl.c'; then $(CYGPATH_W) 'cdrom-ioctl.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl.Tpo $(DEPDIR)/pcem-cdrom-ioctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl.c' object='pcem-cdrom-ioctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl.obj `if test -f 'cdrom-ioctl.c'; then $(CYGPATH_W) 'cdrom-ioctl.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl.c'; fi` + +pcem-wx-sdl2-display-win.o: wx-sdl2-display-win.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display-win.o -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display-win.Tpo -c -o pcem-wx-sdl2-display-win.o `test -f 'wx-sdl2-display-win.c' || echo '$(srcdir)/'`wx-sdl2-display-win.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display-win.Tpo $(DEPDIR)/pcem-wx-sdl2-display-win.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display-win.c' object='pcem-wx-sdl2-display-win.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display-win.o `test -f 'wx-sdl2-display-win.c' || echo '$(srcdir)/'`wx-sdl2-display-win.c + +pcem-wx-sdl2-display-win.obj: wx-sdl2-display-win.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-sdl2-display-win.obj -MD -MP -MF $(DEPDIR)/pcem-wx-sdl2-display-win.Tpo -c -o pcem-wx-sdl2-display-win.obj `if test -f 'wx-sdl2-display-win.c'; then $(CYGPATH_W) 'wx-sdl2-display-win.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display-win.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-sdl2-display-win.Tpo $(DEPDIR)/pcem-wx-sdl2-display-win.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wx-sdl2-display-win.c' object='pcem-wx-sdl2-display-win.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display-win.obj `if test -f 'wx-sdl2-display-win.c'; then $(CYGPATH_W) 'wx-sdl2-display-win.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display-win.c'; fi` + .cc.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` @@ -3636,285 +4218,285 @@ pcem-sound_resid.obj: sound_resid.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sound_resid.obj `if test -f 'sound_resid.cc'; then $(CYGPATH_W) 'sound_resid.cc'; else $(CYGPATH_W) '$(srcdir)/sound_resid.cc'; fi` -pcem-cdrom_image.o: dosbox/cdrom_image.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-cdrom_image.o -MD -MP -MF $(DEPDIR)/pcem-cdrom_image.Tpo -c -o pcem-cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom_image.Tpo $(DEPDIR)/pcem-cdrom_image.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='pcem-cdrom_image.o' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-cdrom_image.o: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT dosbox/pcem-cdrom_image.o -MD -MP -MF dosbox/$(DEPDIR)/pcem-cdrom_image.Tpo -c -o dosbox/pcem-cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-cdrom_image.Tpo dosbox/$(DEPDIR)/pcem-cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='dosbox/pcem-cdrom_image.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o dosbox/pcem-cdrom_image.o `test -f 'dosbox/cdrom_image.cpp' || echo '$(srcdir)/'`dosbox/cdrom_image.cpp -pcem-cdrom_image.obj: dosbox/cdrom_image.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-cdrom_image.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom_image.Tpo -c -o pcem-cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom_image.Tpo $(DEPDIR)/pcem-cdrom_image.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='pcem-cdrom_image.obj' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-cdrom_image.obj: dosbox/cdrom_image.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT dosbox/pcem-cdrom_image.obj -MD -MP -MF dosbox/$(DEPDIR)/pcem-cdrom_image.Tpo -c -o dosbox/pcem-cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-cdrom_image.Tpo dosbox/$(DEPDIR)/pcem-cdrom_image.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/cdrom_image.cpp' object='dosbox/pcem-cdrom_image.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o dosbox/pcem-cdrom_image.obj `if test -f 'dosbox/cdrom_image.cpp'; then $(CYGPATH_W) 'dosbox/cdrom_image.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/cdrom_image.cpp'; fi` -pcem-dbopl.o: dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-dbopl.o -MD -MP -MF $(DEPDIR)/pcem-dbopl.Tpo -c -o pcem-dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dbopl.Tpo $(DEPDIR)/pcem-dbopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='pcem-dbopl.o' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-dbopl.o: dosbox/dbopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT dosbox/pcem-dbopl.o -MD -MP -MF dosbox/$(DEPDIR)/pcem-dbopl.Tpo -c -o dosbox/pcem-dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-dbopl.Tpo dosbox/$(DEPDIR)/pcem-dbopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='dosbox/pcem-dbopl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o dosbox/pcem-dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp -pcem-dbopl.obj: dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-dbopl.obj -MD -MP -MF $(DEPDIR)/pcem-dbopl.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-dbopl.Tpo $(DEPDIR)/pcem-dbopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='pcem-dbopl.obj' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-dbopl.obj: dosbox/dbopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT dosbox/pcem-dbopl.obj -MD -MP -MF dosbox/$(DEPDIR)/pcem-dbopl.Tpo -c -o dosbox/pcem-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_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-dbopl.Tpo dosbox/$(DEPDIR)/pcem-dbopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/dbopl.cpp' object='dosbox/pcem-dbopl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-dbopl.obj `if test -f 'dosbox/dbopl.cpp'; then $(CYGPATH_W) 'dosbox/dbopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/dbopl.cpp'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o dosbox/pcem-dbopl.obj `if test -f 'dosbox/dbopl.cpp'; then $(CYGPATH_W) 'dosbox/dbopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/dbopl.cpp'; fi` -pcem-nukedopl.o: dosbox/nukedopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-nukedopl.o -MD -MP -MF $(DEPDIR)/pcem-nukedopl.Tpo -c -o pcem-nukedopl.o `test -f 'dosbox/nukedopl.cpp' || echo '$(srcdir)/'`dosbox/nukedopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nukedopl.Tpo $(DEPDIR)/pcem-nukedopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/nukedopl.cpp' object='pcem-nukedopl.o' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-nukedopl.o: dosbox/nukedopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT dosbox/pcem-nukedopl.o -MD -MP -MF dosbox/$(DEPDIR)/pcem-nukedopl.Tpo -c -o dosbox/pcem-nukedopl.o `test -f 'dosbox/nukedopl.cpp' || echo '$(srcdir)/'`dosbox/nukedopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-nukedopl.Tpo dosbox/$(DEPDIR)/pcem-nukedopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/nukedopl.cpp' object='dosbox/pcem-nukedopl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-nukedopl.o `test -f 'dosbox/nukedopl.cpp' || echo '$(srcdir)/'`dosbox/nukedopl.cpp +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o dosbox/pcem-nukedopl.o `test -f 'dosbox/nukedopl.cpp' || echo '$(srcdir)/'`dosbox/nukedopl.cpp -pcem-nukedopl.obj: dosbox/nukedopl.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-nukedopl.obj -MD -MP -MF $(DEPDIR)/pcem-nukedopl.Tpo -c -o pcem-nukedopl.obj `if test -f 'dosbox/nukedopl.cpp'; then $(CYGPATH_W) 'dosbox/nukedopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/nukedopl.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-nukedopl.Tpo $(DEPDIR)/pcem-nukedopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/nukedopl.cpp' object='pcem-nukedopl.obj' libtool=no @AMDEPBACKSLASH@ +dosbox/pcem-nukedopl.obj: dosbox/nukedopl.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT dosbox/pcem-nukedopl.obj -MD -MP -MF dosbox/$(DEPDIR)/pcem-nukedopl.Tpo -c -o dosbox/pcem-nukedopl.obj `if test -f 'dosbox/nukedopl.cpp'; then $(CYGPATH_W) 'dosbox/nukedopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/nukedopl.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) dosbox/$(DEPDIR)/pcem-nukedopl.Tpo dosbox/$(DEPDIR)/pcem-nukedopl.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dosbox/nukedopl.cpp' object='dosbox/pcem-nukedopl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-nukedopl.obj `if test -f 'dosbox/nukedopl.cpp'; then $(CYGPATH_W) 'dosbox/nukedopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/nukedopl.cpp'; fi` +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o dosbox/pcem-nukedopl.obj `if test -f 'dosbox/nukedopl.cpp'; then $(CYGPATH_W) 'dosbox/nukedopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/nukedopl.cpp'; fi` -pcem-convolve.o: resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve.o -MD -MP -MF $(DEPDIR)/pcem-convolve.Tpo -c -o pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-convolve.Tpo $(DEPDIR)/pcem-convolve.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='pcem-convolve.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-convolve.o: resid-fp/convolve.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-convolve.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-convolve.Tpo -c -o resid-fp/pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-convolve.Tpo resid-fp/$(DEPDIR)/pcem-convolve.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='resid-fp/pcem-convolve.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc -pcem-convolve.obj: resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve.obj -MD -MP -MF $(DEPDIR)/pcem-convolve.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-convolve.Tpo $(DEPDIR)/pcem-convolve.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='pcem-convolve.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-convolve.obj: resid-fp/convolve.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-convolve.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-convolve.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-convolve.Tpo resid-fp/$(DEPDIR)/pcem-convolve.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve.cc' object='resid-fp/pcem-convolve.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-convolve-sse.o: resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve-sse.o -MD -MP -MF $(DEPDIR)/pcem-convolve-sse.Tpo -c -o pcem-convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-convolve-sse.Tpo $(DEPDIR)/pcem-convolve-sse.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='pcem-convolve-sse.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-convolve-sse.o: resid-fp/convolve-sse.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-convolve-sse.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-convolve-sse.Tpo -c -o resid-fp/pcem-convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-convolve-sse.Tpo resid-fp/$(DEPDIR)/pcem-convolve-sse.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='resid-fp/pcem-convolve-sse.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc -pcem-convolve-sse.obj: resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-convolve-sse.obj -MD -MP -MF $(DEPDIR)/pcem-convolve-sse.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-convolve-sse.Tpo $(DEPDIR)/pcem-convolve-sse.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='pcem-convolve-sse.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-convolve-sse.obj: resid-fp/convolve-sse.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-convolve-sse.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-convolve-sse.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-convolve-sse.Tpo resid-fp/$(DEPDIR)/pcem-convolve-sse.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/convolve-sse.cc' object='resid-fp/pcem-convolve-sse.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-envelope.o: resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-envelope.o -MD -MP -MF $(DEPDIR)/pcem-envelope.Tpo -c -o pcem-envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-envelope.Tpo $(DEPDIR)/pcem-envelope.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='pcem-envelope.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-envelope.o: resid-fp/envelope.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-envelope.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-envelope.Tpo -c -o resid-fp/pcem-envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-envelope.Tpo resid-fp/$(DEPDIR)/pcem-envelope.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='resid-fp/pcem-envelope.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc -pcem-envelope.obj: resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-envelope.obj -MD -MP -MF $(DEPDIR)/pcem-envelope.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-envelope.Tpo $(DEPDIR)/pcem-envelope.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='pcem-envelope.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-envelope.obj: resid-fp/envelope.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-envelope.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-envelope.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-envelope.Tpo resid-fp/$(DEPDIR)/pcem-envelope.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/envelope.cc' object='resid-fp/pcem-envelope.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-extfilt.o: resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-extfilt.o -MD -MP -MF $(DEPDIR)/pcem-extfilt.Tpo -c -o pcem-extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-extfilt.Tpo $(DEPDIR)/pcem-extfilt.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='pcem-extfilt.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-extfilt.o: resid-fp/extfilt.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-extfilt.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-extfilt.Tpo -c -o resid-fp/pcem-extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-extfilt.Tpo resid-fp/$(DEPDIR)/pcem-extfilt.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='resid-fp/pcem-extfilt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc -pcem-extfilt.obj: resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-extfilt.obj -MD -MP -MF $(DEPDIR)/pcem-extfilt.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-extfilt.Tpo $(DEPDIR)/pcem-extfilt.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='pcem-extfilt.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-extfilt.obj: resid-fp/extfilt.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-extfilt.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-extfilt.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-extfilt.Tpo resid-fp/$(DEPDIR)/pcem-extfilt.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/extfilt.cc' object='resid-fp/pcem-extfilt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-filter.o: resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-filter.o -MD -MP -MF $(DEPDIR)/pcem-filter.Tpo -c -o pcem-filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-filter.Tpo $(DEPDIR)/pcem-filter.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='pcem-filter.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-filter.o: resid-fp/filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-filter.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-filter.Tpo -c -o resid-fp/pcem-filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-filter.Tpo resid-fp/$(DEPDIR)/pcem-filter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='resid-fp/pcem-filter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc -pcem-filter.obj: resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-filter.obj -MD -MP -MF $(DEPDIR)/pcem-filter.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-filter.Tpo $(DEPDIR)/pcem-filter.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='pcem-filter.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-filter.obj: resid-fp/filter.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-filter.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-filter.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-filter.Tpo resid-fp/$(DEPDIR)/pcem-filter.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/filter.cc' object='resid-fp/pcem-filter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-pot.o: resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-pot.o -MD -MP -MF $(DEPDIR)/pcem-pot.Tpo -c -o pcem-pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pot.Tpo $(DEPDIR)/pcem-pot.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='pcem-pot.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-pot.o: resid-fp/pot.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-pot.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-pot.Tpo -c -o resid-fp/pcem-pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-pot.Tpo resid-fp/$(DEPDIR)/pcem-pot.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='resid-fp/pcem-pot.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc -pcem-pot.obj: resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-pot.obj -MD -MP -MF $(DEPDIR)/pcem-pot.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-pot.Tpo $(DEPDIR)/pcem-pot.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='pcem-pot.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-pot.obj: resid-fp/pot.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-pot.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-pot.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-pot.Tpo resid-fp/$(DEPDIR)/pcem-pot.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/pot.cc' object='resid-fp/pcem-pot.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-sid.o: resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sid.o -MD -MP -MF $(DEPDIR)/pcem-sid.Tpo -c -o pcem-sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sid.Tpo $(DEPDIR)/pcem-sid.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='pcem-sid.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-sid.o: resid-fp/sid.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-sid.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-sid.Tpo -c -o resid-fp/pcem-sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-sid.Tpo resid-fp/$(DEPDIR)/pcem-sid.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='resid-fp/pcem-sid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc -pcem-sid.obj: resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-sid.obj -MD -MP -MF $(DEPDIR)/pcem-sid.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-sid.Tpo $(DEPDIR)/pcem-sid.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='pcem-sid.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-sid.obj: resid-fp/sid.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-sid.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-sid.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-sid.Tpo resid-fp/$(DEPDIR)/pcem-sid.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/sid.cc' object='resid-fp/pcem-sid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-voice.o: resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-voice.o -MD -MP -MF $(DEPDIR)/pcem-voice.Tpo -c -o pcem-voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-voice.Tpo $(DEPDIR)/pcem-voice.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='pcem-voice.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-voice.o: resid-fp/voice.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-voice.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-voice.Tpo -c -o resid-fp/pcem-voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-voice.Tpo resid-fp/$(DEPDIR)/pcem-voice.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='resid-fp/pcem-voice.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc -pcem-voice.obj: resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-voice.obj -MD -MP -MF $(DEPDIR)/pcem-voice.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-voice.Tpo $(DEPDIR)/pcem-voice.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='pcem-voice.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-voice.obj: resid-fp/voice.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-voice.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-voice.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-voice.Tpo resid-fp/$(DEPDIR)/pcem-voice.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/voice.cc' object='resid-fp/pcem-voice.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave6581_PS_.o: resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PS_.o -MD -MP -MF $(DEPDIR)/pcem-wave6581_PS_.Tpo -c -o pcem-wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PS_.Tpo $(DEPDIR)/pcem-wave6581_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='pcem-wave6581_PS_.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581_PS_.o: resid-fp/wave6581_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581_PS_.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Tpo -c -o resid-fp/pcem-wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Tpo resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='resid-fp/pcem-wave6581_PS_.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc -pcem-wave6581_PS_.obj: resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PS_.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581_PS_.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PS_.Tpo $(DEPDIR)/pcem-wave6581_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='pcem-wave6581_PS_.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581_PS_.obj: resid-fp/wave6581_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581_PS_.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Tpo resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PS_.cc' object='resid-fp/pcem-wave6581_PS_.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave6581_PST.o: resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PST.o -MD -MP -MF $(DEPDIR)/pcem-wave6581_PST.Tpo -c -o pcem-wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PST.Tpo $(DEPDIR)/pcem-wave6581_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='pcem-wave6581_PST.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581_PST.o: resid-fp/wave6581_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581_PST.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581_PST.Tpo -c -o resid-fp/pcem-wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581_PST.Tpo resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='resid-fp/pcem-wave6581_PST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc -pcem-wave6581_PST.obj: resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_PST.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581_PST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_PST.Tpo $(DEPDIR)/pcem-wave6581_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='pcem-wave6581_PST.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581_PST.obj: resid-fp/wave6581_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581_PST.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581_PST.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581_PST.Tpo resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_PST.cc' object='resid-fp/pcem-wave6581_PST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave6581_P_T.o: resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_P_T.o -MD -MP -MF $(DEPDIR)/pcem-wave6581_P_T.Tpo -c -o pcem-wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_P_T.Tpo $(DEPDIR)/pcem-wave6581_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='pcem-wave6581_P_T.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581_P_T.o: resid-fp/wave6581_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581_P_T.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Tpo -c -o resid-fp/pcem-wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Tpo resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='resid-fp/pcem-wave6581_P_T.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc -pcem-wave6581_P_T.obj: resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581_P_T.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581_P_T.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581_P_T.Tpo $(DEPDIR)/pcem-wave6581_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='pcem-wave6581_P_T.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581_P_T.obj: resid-fp/wave6581_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581_P_T.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Tpo resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581_P_T.cc' object='resid-fp/pcem-wave6581_P_T.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave6581__ST.o: resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581__ST.o -MD -MP -MF $(DEPDIR)/pcem-wave6581__ST.Tpo -c -o pcem-wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581__ST.Tpo $(DEPDIR)/pcem-wave6581__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='pcem-wave6581__ST.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581__ST.o: resid-fp/wave6581__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581__ST.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581__ST.Tpo -c -o resid-fp/pcem-wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581__ST.Tpo resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='resid-fp/pcem-wave6581__ST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc -pcem-wave6581__ST.obj: resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave6581__ST.obj -MD -MP -MF $(DEPDIR)/pcem-wave6581__ST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave6581__ST.Tpo $(DEPDIR)/pcem-wave6581__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='pcem-wave6581__ST.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave6581__ST.obj: resid-fp/wave6581__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave6581__ST.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave6581__ST.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave6581__ST.Tpo resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave6581__ST.cc' object='resid-fp/pcem-wave6581__ST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave8580_PS_.o: resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PS_.o -MD -MP -MF $(DEPDIR)/pcem-wave8580_PS_.Tpo -c -o pcem-wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PS_.Tpo $(DEPDIR)/pcem-wave8580_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='pcem-wave8580_PS_.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580_PS_.o: resid-fp/wave8580_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580_PS_.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Tpo -c -o resid-fp/pcem-wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Tpo resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='resid-fp/pcem-wave8580_PS_.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc -pcem-wave8580_PS_.obj: resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PS_.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580_PS_.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PS_.Tpo $(DEPDIR)/pcem-wave8580_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='pcem-wave8580_PS_.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580_PS_.obj: resid-fp/wave8580_PS_.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580_PS_.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Tpo resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PS_.cc' object='resid-fp/pcem-wave8580_PS_.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave8580_PST.o: resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PST.o -MD -MP -MF $(DEPDIR)/pcem-wave8580_PST.Tpo -c -o pcem-wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PST.Tpo $(DEPDIR)/pcem-wave8580_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='pcem-wave8580_PST.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580_PST.o: resid-fp/wave8580_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580_PST.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580_PST.Tpo -c -o resid-fp/pcem-wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580_PST.Tpo resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='resid-fp/pcem-wave8580_PST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc -pcem-wave8580_PST.obj: resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_PST.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580_PST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_PST.Tpo $(DEPDIR)/pcem-wave8580_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='pcem-wave8580_PST.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580_PST.obj: resid-fp/wave8580_PST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580_PST.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580_PST.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580_PST.Tpo resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_PST.cc' object='resid-fp/pcem-wave8580_PST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave8580_P_T.o: resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_P_T.o -MD -MP -MF $(DEPDIR)/pcem-wave8580_P_T.Tpo -c -o pcem-wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_P_T.Tpo $(DEPDIR)/pcem-wave8580_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='pcem-wave8580_P_T.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580_P_T.o: resid-fp/wave8580_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580_P_T.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Tpo -c -o resid-fp/pcem-wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Tpo resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='resid-fp/pcem-wave8580_P_T.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc -pcem-wave8580_P_T.obj: resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580_P_T.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580_P_T.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580_P_T.Tpo $(DEPDIR)/pcem-wave8580_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='pcem-wave8580_P_T.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580_P_T.obj: resid-fp/wave8580_P_T.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580_P_T.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Tpo resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580_P_T.cc' object='resid-fp/pcem-wave8580_P_T.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave8580__ST.o: resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580__ST.o -MD -MP -MF $(DEPDIR)/pcem-wave8580__ST.Tpo -c -o pcem-wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580__ST.Tpo $(DEPDIR)/pcem-wave8580__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='pcem-wave8580__ST.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580__ST.o: resid-fp/wave8580__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580__ST.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580__ST.Tpo -c -o resid-fp/pcem-wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580__ST.Tpo resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='resid-fp/pcem-wave8580__ST.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc -pcem-wave8580__ST.obj: resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave8580__ST.obj -MD -MP -MF $(DEPDIR)/pcem-wave8580__ST.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave8580__ST.Tpo $(DEPDIR)/pcem-wave8580__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='pcem-wave8580__ST.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave8580__ST.obj: resid-fp/wave8580__ST.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave8580__ST.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave8580__ST.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave8580__ST.Tpo resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave8580__ST.cc' object='resid-fp/pcem-wave8580__ST.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` -pcem-wave.o: resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave.o -MD -MP -MF $(DEPDIR)/pcem-wave.Tpo -c -o pcem-wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wave.Tpo $(DEPDIR)/pcem-wave.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='pcem-wave.o' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave.o: resid-fp/wave.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave.o -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave.Tpo -c -o resid-fp/pcem-wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave.Tpo resid-fp/$(DEPDIR)/pcem-wave.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='resid-fp/pcem-wave.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc -pcem-wave.obj: resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wave.obj -MD -MP -MF $(DEPDIR)/pcem-wave.Tpo -c -o pcem-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_V_at)$(am__mv) $(DEPDIR)/pcem-wave.Tpo $(DEPDIR)/pcem-wave.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='pcem-wave.obj' libtool=no @AMDEPBACKSLASH@ +resid-fp/pcem-wave.obj: resid-fp/wave.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT resid-fp/pcem-wave.obj -MD -MP -MF resid-fp/$(DEPDIR)/pcem-wave.Tpo -c -o resid-fp/pcem-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_V_at)$(am__mv) resid-fp/$(DEPDIR)/pcem-wave.Tpo resid-fp/$(DEPDIR)/pcem-wave.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='resid-fp/wave.cc' object='resid-fp/pcem-wave.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-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_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o resid-fp/pcem-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` pcem-wx-main.o: wx-main.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-main.o -MD -MP -MF $(DEPDIR)/pcem-wx-main.Tpo -c -o pcem-wx-main.o `test -f 'wx-main.cc' || echo '$(srcdir)/'`wx-main.cc @@ -4000,20 +4582,6 @@ pcem-wx-status.obj: wx-status.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-status.obj `if test -f 'wx-status.cc'; then $(CYGPATH_W) 'wx-status.cc'; else $(CYGPATH_W) '$(srcdir)/wx-status.cc'; fi` -pcem-wx-resources.o: wx-resources.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-resources.o -MD -MP -MF $(DEPDIR)/pcem-wx-resources.Tpo -c -o pcem-wx-resources.o `test -f 'wx-resources.cpp' || echo '$(srcdir)/'`wx-resources.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-resources.Tpo $(DEPDIR)/pcem-wx-resources.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-resources.cpp' object='pcem-wx-resources.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.o `test -f 'wx-resources.cpp' || echo '$(srcdir)/'`wx-resources.cpp - -pcem-wx-resources.obj: wx-resources.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-resources.obj -MD -MP -MF $(DEPDIR)/pcem-wx-resources.Tpo -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-resources.Tpo $(DEPDIR)/pcem-wx-resources.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-resources.cpp' object='pcem-wx-resources.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` - pcem-wx-shaderconfig.o: wx-shaderconfig.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-shaderconfig.o -MD -MP -MF $(DEPDIR)/pcem-wx-shaderconfig.Tpo -c -o pcem-wx-shaderconfig.o `test -f 'wx-shaderconfig.cc' || echo '$(srcdir)/'`wx-shaderconfig.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-shaderconfig.Tpo $(DEPDIR)/pcem-wx-shaderconfig.Po @@ -4042,16 +4610,46 @@ pcem-wx-joystickconfig.obj: wx-joystickconfig.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-joystickconfig.obj `if test -f 'wx-joystickconfig.cc'; then $(CYGPATH_W) 'wx-joystickconfig.cc'; else $(CYGPATH_W) '$(srcdir)/wx-joystickconfig.cc'; fi` +pcem-wx-createdisc.o: wx-createdisc.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-createdisc.o -MD -MP -MF $(DEPDIR)/pcem-wx-createdisc.Tpo -c -o pcem-wx-createdisc.o `test -f 'wx-createdisc.cc' || echo '$(srcdir)/'`wx-createdisc.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-createdisc.Tpo $(DEPDIR)/pcem-wx-createdisc.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-createdisc.cc' object='pcem-wx-createdisc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-createdisc.o `test -f 'wx-createdisc.cc' || echo '$(srcdir)/'`wx-createdisc.cc + +pcem-wx-createdisc.obj: wx-createdisc.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-createdisc.obj -MD -MP -MF $(DEPDIR)/pcem-wx-createdisc.Tpo -c -o pcem-wx-createdisc.obj `if test -f 'wx-createdisc.cc'; then $(CYGPATH_W) 'wx-createdisc.cc'; else $(CYGPATH_W) '$(srcdir)/wx-createdisc.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-createdisc.Tpo $(DEPDIR)/pcem-wx-createdisc.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-createdisc.cc' object='pcem-wx-createdisc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-createdisc.obj `if test -f 'wx-createdisc.cc'; then $(CYGPATH_W) 'wx-createdisc.cc'; else $(CYGPATH_W) '$(srcdir)/wx-createdisc.cc'; fi` + +pcem-wx-resources.o: wx-resources.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-resources.o -MD -MP -MF $(DEPDIR)/pcem-wx-resources.Tpo -c -o pcem-wx-resources.o `test -f 'wx-resources.cpp' || echo '$(srcdir)/'`wx-resources.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-resources.Tpo $(DEPDIR)/pcem-wx-resources.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-resources.cpp' object='pcem-wx-resources.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.o `test -f 'wx-resources.cpp' || echo '$(srcdir)/'`wx-resources.cpp + +pcem-wx-resources.obj: wx-resources.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -MT pcem-wx-resources.obj -MD -MP -MF $(DEPDIR)/pcem-wx-resources.Tpo -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-resources.Tpo $(DEPDIR)/pcem-wx-resources.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='wx-resources.cpp' object='pcem-wx-resources.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CXXFLAGS) $(CXXFLAGS) -c -o pcem-wx-resources.obj `if test -f 'wx-resources.cpp'; then $(CYGPATH_W) 'wx-resources.cpp'; else $(CYGPATH_W) '$(srcdir)/wx-resources.cpp'; fi` + .cpp.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` @@ -4172,6 +4770,12 @@ clean-generic: 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) + -rm -f dosbox/$(DEPDIR)/$(am__dirstamp) + -rm -f dosbox/$(am__dirstamp) + -rm -f resid-fp/$(DEPDIR)/$(am__dirstamp) + -rm -f resid-fp/$(am__dirstamp) + -rm -f slirp/$(DEPDIR)/$(am__dirstamp) + -rm -f slirp/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -4181,7 +4785,7 @@ clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -4227,7 +4831,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -4263,14 +4867,15 @@ uninstall-am: uninstall-binPROGRAMS .PRECIOUS: Makefile - -../pcem: pcem - cp pcem .. - -slirp/libslirp.a: - $(MAKE) -C slirp +@OS_WINDOWS_FALSE@../pcem: pcem +@OS_WINDOWS_FALSE@ cp pcem .. amrefresh: +wx.res: wx.rc + $(WINDRES) -i wx.rc --input-format=rc -o wx.res -O coff + +wx-resources.cpp : pc.xrc + -wxrc -c pc.xrc -o wx-resources.cpp # 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. diff --git a/src/nethandler.c b/src/nethandler.c index 871ef5c..dec5c8a 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -1,6 +1,6 @@ #ifdef _WIN32 -#include #include +#include #endif #include #include diff --git a/src/wx-main.cc b/src/wx-main.cc index 393eb0e..53a9371 100644 --- a/src/wx-main.cc +++ b/src/wx-main.cc @@ -1,4 +1,5 @@ #include "wx-app.h" +#include extern "C" { From c3b876524d9a08615262c1931a01939d757195fc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 10 Feb 2018 12:46:09 +0000 Subject: [PATCH 0301/1050] Clear sound_cd_event in CD audio thread. Patch from ja've. --- src/sound.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound.c b/src/sound.c index f5f9cf3..cb5820d 100644 --- a/src/sound.c +++ b/src/sound.c @@ -150,6 +150,7 @@ static void sound_cd_thread(void *param) int c; thread_wait_event(sound_cd_event, -1); + thread_reset_event(sound_cd_event); memset(cd_buffer, 0, CD_BUFLEN*2 * 2); ioctl_audio_callback(cd_buffer, CD_BUFLEN*2); image_audio_callback(cd_buffer, CD_BUFLEN*2); From cdf42681af1b31f7067e7d9eeb4813864750c3ca Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 10 Feb 2018 12:48:07 +0000 Subject: [PATCH 0302/1050] Removed redundant CD-ROM Disabled option. --- src/ibm.h | 1 - src/ide.c | 2 +- src/pc.c | 3 - src/pc.xrc | 4 - src/wx-resources.cpp | 2844 +++++++++++++++++++++--------------------- src/wx-sdl2-status.c | 2 +- src/wx-sdl2.c | 105 +- 7 files changed, 1429 insertions(+), 1532 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 8873741..326cda3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -545,7 +545,6 @@ int keybsenddelay; extern int cdrom_drive; extern int old_cdrom_drive; extern int idecallback[2]; -extern int cdrom_enabled; #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 diff --git a/src/ide.c b/src/ide.c index bff9b26..3f2b32e 100644 --- a/src/ide.c +++ b/src/ide.c @@ -271,7 +271,7 @@ void resetide(void) { ide_drives[d].drive = d; - if ((cdrom_channel == d) && cdrom_enabled) + if (cdrom_channel == d) { ide_drives[d].type = IDE_CDROM; scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d); diff --git a/src/pc.c b/src/pc.c index 4752655..2e916de 100644 --- a/src/pc.c +++ b/src/pc.c @@ -63,7 +63,6 @@ int window_w, window_h, window_x, window_y, window_remember; int start_in_fullscreen = 0; -int cdrom_enabled; int CPUID; int vid_resize, vid_api; @@ -726,7 +725,6 @@ void loadconfig(char *fn) mem_size = (((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) ? models[model].min_ram*1024 : models[model].min_ram); cdrom_drive = config_get_int(CFG_MACHINE, NULL, "cdrom_drive", 0); - cdrom_enabled = config_get_int(CFG_MACHINE, NULL, "cdrom_enabled", 0); cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2); zip_channel = config_get_int(CFG_MACHINE, NULL, "zip_channel", -1); @@ -871,7 +869,6 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "mem_size", mem_size); config_set_int(CFG_MACHINE, NULL, "cdrom_drive", cdrom_drive); - config_set_int(CFG_MACHINE, NULL, "cdrom_enabled", cdrom_enabled); config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel); config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path); diff --git a/src/pc.xrc b/src/pc.xrc index 698c304..166cd0c 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -128,10 +128,6 @@ - - - 1 - 1 diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 441d490..9af6fee 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 132166; +static size_t xml_res_size_26 = 132032; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -2020,713 +2020,1141 @@ static unsigned char xml_res_file_26[] = { 111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, 116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,67,68,82,79,77,95,68,73,83,65,66,76,69,68,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,115,97, -98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,69,77,80,84,89, -34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,109,112, -116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,109,97,103,101, -46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,86, -105,100,101,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,111,108, -117,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, -69,83,79,76,85,84,73,79,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,79,114,105,103,105,110,97,108,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91, -49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82, -101,115,105,122,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +109,101,61,34,73,68,77,95,67,68,82,79,77,95,69,77,80,84,89,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,109,112,116,121,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,95,67,85,83,84, -79,77,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -101,116,32,99,117,115,116,111,109,32,114,101,115,111,108,117,116,105,111, -110,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,82,69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,82,101,109,101,109,98,101,114,32,115,105, -122,101,32,38,97,109,112,59,38,97,109,112,59,32,112,111,115,105,116,105, -111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104, -101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62, -10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114, -97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78, -95,84,79,71,71,76,69,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,84,111,103,103,108,101,32,102,117,108,108,115,99,114,101,101,110, -92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,68,111,119,110,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101,101,110, -32,111,110,32,105,110,112,117,116,32,103,114,97,98,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62, -49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,70,117,108,108,115,99,114,101,101,110,32,109,111,100,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,48,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,111,114, -100,101,114,108,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,70,83,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,69,120,99,108,117,115,105,118,101,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,82,101,110,100,101,114,32,100,114,105, -118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +34,73,68,77,95,67,68,82,79,77,95,73,77,65,71,69,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,95,73,109,97,103,101,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,111,108,117,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84, +73,79,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,114,105,103,105,110,97,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,105,122,97,98, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78, -68,69,82,95,68,82,73,86,69,82,91,48,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,65,117,116,111,60,47,108,97,98,101,108,62, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83, +79,76,85,84,73,79,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,117,115,116,111,109,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,49, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105, -114,101,99,116,51,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,60,47,108, +115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,83,79,76,85,84,73,79,78,95,67,85,83,84,79,77,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,99,117,115, +116,111,109,32,114,101,115,111,108,117,116,105,111,110,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, +69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112, +59,38,97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101, +62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101, +32,102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, +116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, +76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, +117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114, +101,101,110,32,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,70,83,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,66,111,114,100,101,114,108,101,115,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69, +91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,69,120,99,108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68, +82,73,86,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +95,82,101,110,100,101,114,32,100,114,105,118,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +117,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, +78,68,69,82,95,68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116,51,68,60,47,108, 97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, 62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, 110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, -73,86,69,82,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,79,112,101,110,71,76,32,51,46,48,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,53, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111, -102,116,119,97,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86,83,89,78,67,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,86,83,121,110,99, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99, -107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,76,79,83, -84,95,70,79,67,85,83,95,68,73,77,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,68,105,109,32,100,105,115,112,108,97,121,32,111,110, -32,108,111,115,116,32,102,111,99,117,115,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47, -99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,65,76,84,69,82,78,65,84,73,86,69,95,85,80, -68,65,84,69,95,76,79,67,75,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,65,108,116,101,114,110,97,116,105,118,101,32,117,112,100,97, -116,101,45,108,111,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,97,108,101,32,102,105, -108,116,101,114,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,83,67,65,76,69,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,78,101,97,114,101,115,116,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79, -68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,76,105,110,101,97,114,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116, -32,115,116,114,101,116,99,104,45,109,111,100,101,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,70,83,91,49,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,70,83,91,50,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112, -105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, -49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, -67,65,76,69,95,77,69,78,85,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,79,117,116,112,117,116,32,115,99,97,108,101,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,48,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53,120,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,50,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53, -120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, -69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, -76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, -95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,51,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +73,86,69,82,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,112,101,110,71,76,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, 62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111, -114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77, -95,86,73,68,95,71,76,51,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,112,101,110,71,76,32,51,46,48,32,114,101,110,100,101,114,101, -114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112,117,116,32, -115,116,114,101,116,99,104,45,109,111,100,101,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69, -84,67,72,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82, -69,84,67,72,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69, -84,67,72,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,51,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101, -114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, -110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -73,110,112,117,116,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76, +32,51,46,48,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, +78,68,69,82,95,68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,111,102,116,119,97,114,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,86,83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104, +101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60, +73,68,77,95,86,73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73,77,34,62, +10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,109,32,100, +105,115,112,108,97,121,32,111,110,32,108,111,115,116,32,102,111,99,117, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,65,76, +84,69,82,78,65,84,73,86,69,95,85,80,68,65,84,69,95,76,79,67,75,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,108,116,101,114,110, +97,116,105,118,101,32,117,112,100,97,116,101,45,108,111,99,107,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98, +108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34, +47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79, +68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,117,116,112,117,116,32,115,116,114,101,116,99,104,45,109, +111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, +83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101, +114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109, +101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116, +32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, +67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, +62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46, +48,32,114,101,110,100,101,114,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,110,112,117,116,32,115,116,114,101,116,99,104,45,109,111, +100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97, +51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101, +32,112,105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67, +72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,99,97, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, 111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, 116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108, +95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, 47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, 32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85, -84,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32, +84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, 97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, -83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, 62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, 73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91, -54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,51,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,114, -101,102,114,101,115,104,32,114,97,116,101,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82, -69,83,72,95,82,65,84,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,97,109,101,32,97,115,32,101,109,117,108, -97,116,101,100,32,100,105,115,112,108,97,121,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, -114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, -82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,49,48,32,104,122,60, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,53,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53, +51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,104,97,100,101,114,32,114,101,102,114,101,115, +104,32,114,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84, +69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,97,109,101,32,97,115,32,101,109,117,108,97,116,101,100,32,100, +105,115,112,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69, +83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,49,48,32,104,122,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68, +69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,53,32,104,122, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, +76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,51, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,51,48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83, +72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,53,48,32,104,122,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, +82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54,48,32,104,122,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, +51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,55,50, 93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -50,53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, 77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, -95,82,65,84,69,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,51,48,32,104,122,60,47,108,97,98,101,108,62,10, +95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, -95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,53,48,32,104,122,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54, -48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82, -65,84,69,91,55,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, -105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69, -70,82,69,83,72,95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62, -10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100, -101,114,32,109,97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102, -101,114,32,108,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,78,68,95,66,85,70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,83,78,68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,50,48,48,32,109,115, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,48,48, -32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,79,117,116,112,117,116,32,108,101,118, -101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78, -91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,78,111,114,109,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, +76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,109, +97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111,117,110,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102,101,114,32,108,101, +110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85, +70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, 101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78, -68,95,71,65,73,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,43,95,50,32,100,66,60,47,108,97,98,101,108,62,10,32,32, +68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32, 32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, 111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,83,78,68,95,71,65,73,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,43,95,52,32,100,66,60,47,108,97,98,101,108, +77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,50,48,48,32,109,115,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, 62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,83,78,68,95,71,65,73,78,91,51,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,43,95,54,32,100,66,60,47,108,97, +34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, 49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,52,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,56,32,100,66, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,53,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,49, -48,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65, -73,78,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,43,49,50,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,79,117,116,112,117,116,32,108,101,118,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,48,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,114,109,97,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,50,32, +100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78, +91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +43,95,52,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71, +65,73,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,43,95,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, 10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, -78,68,95,71,65,73,78,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,43,49,52,32,100,66,60,47,108,97,98,101,108,62,10,32, +78,68,95,71,65,73,78,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,43,95,56,32,100,66,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, 105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,83,78,68,95,71,65,73,78,91,56,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,43,49,54,32,100,66,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,57,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,56,32,100,66,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62, -10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,83,99,114,101,101,110,115,104,111,116,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, -97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,84,97,107,101,32, -115,99,114,101,101,110,115,104,111,116,92,116,67,116,114,108,43,65,108, -116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,70,111,114, -109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69, -78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, -49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95, -70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, -100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +68,77,95,83,78,68,95,71,65,73,78,91,53,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,43,95,49,48,32,100,66,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, +60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77, -65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,80, -71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,54,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,50,32,100,66,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,55,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,52, +32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, 114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, -109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84, -95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, -101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109, -101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73, +78,91,56,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,43,49,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68, +95,71,65,73,78,91,57,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,43,49,56,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,77,105,115,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114, +101,101,110,115,104,111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67, +82,69,69,78,83,72,79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,84,97,107,101,32,115,99,114,101,101,110,115,104,111,116, +92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,78,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, +100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78, +83,72,79,84,95,70,79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, +47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, +79,82,77,65,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, +67,82,69,69,78,83,72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,108,97,115,104,32,115,99,114,101, +101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105, +110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114, +116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84,89, +80,69,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, +60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, +70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, +74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, +105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, +69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, 62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49,48,34,47,62, -10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, -68,67,95,67,79,77,66,79,68,82,73,86,69,84,89,80,69,34,32,115,116,97,114, -116,61,34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34,32,115,116, -97,114,116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32,115,116,97, -114,116,61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32,115,116,97, -114,116,61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116,97,114,116, -61,34,54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32, -110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34,32,115,116, -97,114,116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, -103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,34, -32,115,116,97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105,100,115,45, -114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67, -89,76,34,32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,84,69, -88,84,95,83,73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48,34,47,62, -10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73, -68,67,95,72,68,68,95,76,65,66,69,76,34,32,115,116,97,114,116,61,34,49,49, -48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110, -102,105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,115,116,121, -108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, -76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116,108,101, -62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47,116,105,116, -108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47, -99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, -61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111, -119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99, -111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, -101,61,34,73,68,67,95,78,79,84,69,66,79,79,75,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,68,69,70,65, -85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, -98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101, -99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,109,111,116,104,101,114, -98,111,97,114,100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, +48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, +101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, +61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115, +116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, +97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108,103,34,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117,114,101,32,80, +67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, +101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79, +79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, -119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, -112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, -98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, +47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,104,105,110,101,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, +108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, +85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, +105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, +61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, +120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, +65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, +67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, +32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, +100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -2734,35 +3162,341 @@ static unsigned char xml_res_file_26[] = { 101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, 105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, +73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, +46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,77,79, -68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99, -101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101, -116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85,58,60,47,108,97,98,101, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, +112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, +67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, +116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, +115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, +83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, 108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -2790,490 +3524,30 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62,10,32,32,32,32,32,32, +61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, 121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, 66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,51,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, -110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, 111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110, -97,109,105,99,32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, -100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, -67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111, -114,121,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,112,105,110,67,116, -114,108,34,32,110,97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95, -75,69,89,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -62,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109, -105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95, -77,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, -105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, -79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, -99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, -83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, -122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, -99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, -99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, -76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, -108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, 101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, -105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, -100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, -116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, -103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, @@ -3283,327 +3557,47 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, 99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, 116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, 112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, -65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, -69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, -105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, -107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, -115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, -97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, +73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, -119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, -116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, -111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105, -118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69, -76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, -83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, -108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, -97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, -60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, -98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, -115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 9341d17..1f6e525 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -61,7 +61,7 @@ drive_info_t* get_machine_info(char* s, int* num_drive_info) { for (i = 0; i < num_hdds; ++i) { drive = 'C'+i; - if (cdrom_enabled && !hdd_controller_current_is_mfm() && i == cdrom_channel) + if (!hdd_controller_current_is_mfm() && i == cdrom_channel) { if (cdrom_drive < 0) continue; diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 6b81cec..940d931 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -353,17 +353,12 @@ void sdl_saveconfig() void update_cdrom_menu(void* hmenu) { - if (!cdrom_enabled) - wx_checkmenuitem(menu, WX_ID("IDM_CDROM_DISABLED"), WX_MB_CHECKED); + if (cdrom_drive == CDROM_IMAGE) + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_IMAGE"), WX_MB_CHECKED); + else if (cdrom_drive > 0) + wx_checkmenuitem(menu, IDM_CDROM_REAL+cdrom_drive, WX_MB_CHECKED); else - { - if (cdrom_drive == CDROM_IMAGE) - wx_checkmenuitem(menu, WX_ID("IDM_CDROM_IMAGE"), WX_MB_CHECKED); - else if (cdrom_drive > 0) - wx_checkmenuitem(menu, IDM_CDROM_REAL+cdrom_drive, WX_MB_CHECKED); - else - wx_checkmenuitem(menu, WX_ID("IDM_CDROM_EMPTY"), WX_MB_CHECKED); - } + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_EMPTY"), WX_MB_CHECKED); } void wx_initmenu() @@ -1058,49 +1053,9 @@ int wx_handle_command(void* hwnd, int wParam, int checked) wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); saveconfig(NULL); } - else if (ID_IS("IDM_CDROM_DISABLED")) - { - if (cdrom_enabled) - { - if (!confirm()) - { - update_cdrom_menu(hmenu); - return 0; - } - } - if (!cdrom_enabled) - { - /* Switching from disabled to disabled. Do nothing. */ - update_cdrom_menu(hmenu); - return 0; - } - atapi->exit(); - atapi_close(); - ioctl_set_drive(0); - old_cdrom_drive = cdrom_drive; - cdrom_drive = 0; - if (cdrom_enabled) - { - pause = 1; - SDL_Delay(100); - cdrom_enabled = 0; - saveconfig(NULL); - resetpchard(); - pause = 0; - } - update_cdrom_menu(hmenu); - } else if (ID_IS("IDM_CDROM_EMPTY")) { - if (!cdrom_enabled) - { - if (!confirm()) - { - update_cdrom_menu(hmenu); - return 0; - } - } - if ((cdrom_drive == 0) && cdrom_enabled) + if (cdrom_drive == 0) { update_cdrom_menu(hmenu); /* Switch from empty to empty. Do nothing. */ @@ -1112,15 +1067,6 @@ int wx_handle_command(void* hwnd, int wParam, int checked) old_cdrom_drive = cdrom_drive; cdrom_drive = 0; saveconfig(NULL); - if (!cdrom_enabled) - { - pause = 1; - SDL_Delay(100); - cdrom_enabled = 1; - saveconfig(NULL); - resetpchard(); - pause = 0; - } update_cdrom_menu(hmenu); } else if (ID_IS("IDM_CDROM_IMAGE") || ID_IS("IDM_CDROM_IMAGE_LOAD")) @@ -1129,19 +1075,10 @@ int wx_handle_command(void* hwnd, int wParam, int checked) "CD-ROM image (*.iso;*.cue)|*.iso;*.cue|All files (*.*)|*.*", image_path)) { - if (!cdrom_enabled) - { - if (!confirm()) - { - update_cdrom_menu(hmenu); - return 0; - } - } old_cdrom_drive = cdrom_drive; strcpy(temp_image_path, openfilestring); if ((strcmp(image_path, temp_image_path) == 0) - && (cdrom_drive == CDROM_IMAGE) - && cdrom_enabled) + && (cdrom_drive == CDROM_IMAGE)) { /* Switching from ISO to the same ISO. Do nothing. */ update_cdrom_menu(hmenu); @@ -1152,31 +1089,14 @@ int wx_handle_command(void* hwnd, int wParam, int checked) image_open(temp_image_path); cdrom_drive = CDROM_IMAGE; saveconfig(NULL); - if (!cdrom_enabled) - { - pause = 1; - SDL_Delay(100); - cdrom_enabled = 1; - saveconfig(NULL); - resetpchard(); - pause = 0; - } update_cdrom_menu(hmenu); } else update_cdrom_menu(hmenu); } else if (wParam >= IDM_CDROM_REAL && wParam < IDM_CDROM_REAL+100) { - if (!cdrom_enabled) - { - if (!confirm()) - { - update_cdrom_menu(hmenu); - return 0; - } - } new_cdrom_drive = wParam-IDM_CDROM_REAL; - if ((cdrom_drive == new_cdrom_drive) && cdrom_enabled) + if (cdrom_drive == new_cdrom_drive) { /* Switching to the same drive. Do nothing. */ update_cdrom_menu(hmenu); @@ -1188,15 +1108,6 @@ int wx_handle_command(void* hwnd, int wParam, int checked) ioctl_set_drive(new_cdrom_drive); cdrom_drive = new_cdrom_drive; saveconfig(NULL); - if (!cdrom_enabled) - { - pause = 1; - SDL_Delay(100); - cdrom_enabled = 1; - saveconfig(NULL); - resetpchard(); - pause = 0; - } update_cdrom_menu(hmenu); } return 0; From 32f794adc4bebc6d4cbf5d019603b703d54a5d05 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 14:21:27 +0000 Subject: [PATCH 0303/1050] Added Trident TGUI9400CXi emulation. --- src/ibm.h | 1 + src/vid_tgui9440.c | 504 ++++++++++++++++++++++++++++++++++++++++++--- src/vid_tgui9440.h | 1 + src/video.c | 1 + 4 files changed, 477 insertions(+), 30 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 326cda3..70990a9 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -484,6 +484,7 @@ enum GFX_GENIUS, /* MDSI Genius */ GFX_MACH64VT2, /*ATI Mach64 VT2*/ GFX_OLIVETTI_GO481, /*Olivetti GO481 PVGA1A*/ + GFX_TGUI9400CXI, GFX_MAX }; diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 426f116..0014cc5 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -1,4 +1,4 @@ -/*Trident TGUI9440 emulation*/ +/*Trident TGUI9400CXi & TGUI9440 emulation*/ #include #include "ibm.h" #include "device.h" @@ -13,6 +13,42 @@ #include "vid_tkd8001_ramdac.h" #include "vid_tgui9440.h" +/*TGUI9400CXi has extended write modes, controlled by extended GDC registers : + + GDC[0x10] - Control + bit 0 - pixel width (1 = 16 bit, 0 = 8 bit) + bit 1 - mono->colour expansion (1 = enabled, 0 = disabled) + bit 2 - mono->colour expansion transparency (1 = tranparent, 0 = opaque) + bit 3 - extended latch copy + GDC[0x11] - Background colour (low byte) + GDC[0x12] - Background colour (high byte) + GDC[0x14] - Foreground colour (low byte) + GDC[0x15] - Foreground colour (high byte) + GDC[0x17] - Write mask (low byte) + GDC[0x18] - Write mask (high byte) + + Mono->colour expansion will expand written data 8:1 to 8/16 consecutive bytes. + MSB is processed first. On word writes, low byte is processed first. 1 bits write + foreground colour, 0 bits write background colour unless transparency is enabled. + If the relevant bit is clear in the write mask then the data is not written. + + With 16-bit pixel width, each bit still expands to one byte, so the TGUI driver + doubles up monochrome data. + + While there is room in the register map for three byte colours, I don't believe + 24-bit colour is supported. The TGUI9440 blitter has the same limitation. + + I don't think double word writes are supported. + + Extended latch copy uses an internal 16 byte latch. Reads load the latch, writing + writes out 16 bytes. I don't think the access size or host data has any affect, + but the Windows 3.1 driver always reads bytes and write words of 0xffff.*/ + +#define EXT_CTRL_16BIT 0x01 +#define EXT_CTRL_MONO_EXPANSION 0x02 +#define EXT_CTRL_MONO_TRANSPARENT 0x04 +#define EXT_CTRL_LATCH_COPY 0x08 + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) @@ -24,6 +60,12 @@ #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff +enum +{ + TGUI_9400CXI = 0, + TGUI_9440 +}; + enum { FIFO_INVALID = (0x00 << 24), @@ -47,6 +89,10 @@ typedef struct tgui_t rom_t bios_rom; svga_t svga; + + tkd8001_ramdac_t ramdac; /*TGUI9400CXi*/ + + int type; struct { @@ -70,9 +116,13 @@ typedef struct tgui_t uint16_t tgui_pattern[8][8]; } accel; + + uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ + uint8_t copy_latch[16]; uint8_t tgui_3d8, tgui_3d9; int oldmode; + uint8_t oldctrl1; uint8_t oldctrl2,newctrl2; uint32_t linear_base, linear_size; @@ -114,6 +164,16 @@ void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *priv); void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); +static uint8_t tgui_ext_linear_read(uint32_t addr, void *p); +static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p); +static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p); +static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p); + +static uint8_t tgui_ext_read(uint32_t addr, void *p); +static void tgui_ext_write(uint32_t addr, uint8_t val, void *p); +static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p); +static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p); + void tgui_out(uint16_t addr, uint8_t val, void *p) { tgui_t *tgui = (tgui_t *)p; @@ -137,21 +197,31 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) svga->seqregs[0xc] = val; break; case 0xd: - if (tgui->oldmode) + if (tgui->oldmode) tgui->oldctrl2 = val; else tgui->newctrl2=val; break; case 0xE: - svga->seqregs[0xe] = val ^ 2; - svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = svga->write_bank; + if (tgui->oldmode) + tgui->oldctrl1 = val; + else + { + svga->seqregs[0xe] = val ^ 2; + svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; + if (!(svga->gdcreg[0xf] & 1)) + svga->read_bank = svga->write_bank; + } return; } break; case 0x3C6: + if (tgui->type == TGUI_9400CXI) + { + tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); + return; + } if (tgui->ramdac_state == 4) { tgui->ramdac_state = 0; @@ -174,10 +244,23 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) return; } case 0x3C7: case 0x3C8: case 0x3C9: + if (tgui->type == TGUI_9400CXI) + { + tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); + return; + } tgui->ramdac_state = 0; break; case 0x3CF: + if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) + { + old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; + tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; + if (svga->gdcaddr == 16) + tgui_recalcmapping(tgui); + return; + } switch (svga->gdcaddr & 15) { case 0x6: @@ -235,15 +318,19 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: - svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; - svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; - svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; - svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8); + if (tgui->type >= TGUI_9440) + { + svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; + svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; + svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8); + } break; case 0x50: - svga->hwcursor.ena = val & 0x80; + if (tgui->type >= TGUI_9440) + svga->hwcursor.ena = val & 0x80; break; } return; @@ -297,7 +384,13 @@ uint8_t tgui_in(uint16_t addr, void *p) { // printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); tgui->oldmode = 0; - return 0xe3; /*TGUI9440AGi*/ + switch (tgui->type) + { + case TGUI_9400CXI: + return 0x93; /*TGUI9400CXi*/ + case TGUI_9440: + return 0xe3; /*TGUI9440AGi*/ + } } if ((svga->seqaddr & 0xf) == 0xc) { @@ -306,18 +399,32 @@ uint8_t tgui_in(uint16_t addr, void *p) } if ((svga->seqaddr & 0xf) == 0xd) { - if (tgui->oldmode) return tgui->oldctrl2; + if (tgui->oldmode) + return tgui->oldctrl2; return tgui->newctrl2; } + if ((svga->seqaddr & 0xf) == 0xe) + { + if (tgui->oldmode) + return tgui->oldctrl1; + } break; case 0x3C6: + if (tgui->type == TGUI_9400CXI) + return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); if (tgui->ramdac_state == 4) return tgui->ramdac_ctrl; tgui->ramdac_state++; break; case 0x3C7: case 0x3C8: case 0x3C9: + if (tgui->type == TGUI_9400CXI) + return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); tgui->ramdac_state = 0; break; + case 0x3CF: + if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) + return tgui->ext_gdc_regs[svga->gdcaddr & 15]; + break; case 0x3D4: return svga->crtcreg; case 0x3D5: @@ -337,7 +444,7 @@ void tgui_recalctimings(svga_t *svga) if (svga->crtc[0x29] & 0x10) svga->rowoffset += 0x100; - if (svga->bpp == 24) + if (tgui->type >= TGUI_9440 && svga->bpp == 24) svga->hdisp = (svga->crtc[1] + 1) * 8; if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; @@ -345,24 +452,64 @@ void tgui_recalctimings(svga_t *svga) if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000; if (tgui->oldctrl2 & 0x10) - { svga->rowoffset <<= 1; + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) svga->ma_latch <<= 1; - } + if (tgui->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ svga->lowres=0; svga->lowres = !(svga->crtc[0x2a] & 0x40); svga->interlace = svga->crtc[0x1e] & 4; - - if (svga->miscout & 8) - svga->clock = cpuclock / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); + if (svga->interlace && tgui->type < TGUI_9440) + svga->rowoffset >>= 1; - if (svga->gdcreg[0xf] & 0x08) - svga->clock *= 2; - else if (svga->gdcreg[0xf] & 0x40) - svga->clock *= 3; + if (svga->crtc[0x17] & 4) + { + svga->vtotal *= 2; + svga->dispend *= 2; + svga->vsyncstart *= 2; + svga->split *= 2; + svga->vblankstart *= 2; + } + + if (tgui->type >= TGUI_9440) + { + if (svga->miscout & 8) + svga->clock = cpuclock / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); + + if (svga->gdcreg[0xf] & 0x08) + svga->clock *= 2; + else if (svga->gdcreg[0xf] & 0x40) + svga->clock *= 3; + } + else + { + switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) + { + case 0x02: svga->clock = cpuclock/ 44900000.0; break; + case 0x03: svga->clock = cpuclock/ 36000000.0; break; + case 0x04: svga->clock = cpuclock/ 57272000.0; break; + case 0x05: svga->clock = cpuclock/ 65000000.0; break; + case 0x06: svga->clock = cpuclock/ 50350000.0; break; + case 0x07: svga->clock = cpuclock/ 40000000.0; break; + case 0x08: svga->clock = cpuclock/ 88000000.0; break; + case 0x09: svga->clock = cpuclock/ 98000000.0; break; + case 0x0a: svga->clock = cpuclock/118800000.0; break; + case 0x0b: svga->clock = cpuclock/108000000.0; break; + case 0x0c: svga->clock = cpuclock/ 72000000.0; break; + case 0x0d: svga->clock = cpuclock/ 77000000.0; break; + case 0x0e: svga->clock = cpuclock/ 80000000.0; break; + case 0x0f: svga->clock = cpuclock/ 75000000.0; break; + } + if (svga->gdcreg[0xf] & 0x08) + { + svga->htotal *= 2; + svga->hdisp *= 2; + svga->hdisp_time *= 2; + } + } if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) { @@ -372,13 +519,19 @@ void tgui_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_highres; break; case 15: - svga->render = svga_render_15bpp_highres; + svga->render = svga_render_15bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp /= 2; break; case 16: svga->render = svga_render_16bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp /= 2; break; case 24: svga->render = svga_render_24bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp = (svga->hdisp * 2) / 3; break; } } @@ -390,12 +543,69 @@ void tgui_recalcmapping(tgui_t *tgui) // pclog("tgui_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]); + if (tgui->type == TGUI_9400CXI) + { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) + { + mem_mapping_set_handler(&tgui->linear_mapping, + tgui_ext_linear_read, NULL, NULL, + tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); + mem_mapping_set_handler(&svga->mapping, + tgui_ext_read, NULL, NULL, + tgui_ext_write, tgui_ext_writew, tgui_ext_writel); + } + else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) + { + mem_mapping_set_handler(&tgui->linear_mapping, + svga_read_linear, svga_readw_linear, svga_readl_linear, + tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); + mem_mapping_set_handler(&svga->mapping, + svga_read, svga_readw, svga_readl, + tgui_ext_write, tgui_ext_writew, tgui_ext_writel); + } + else + { + mem_mapping_set_handler(&tgui->linear_mapping, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear); + mem_mapping_set_handler(&svga->mapping, + svga_read, svga_readw, svga_readl, + svga_write, svga_writew, svga_writel); + } + } + if (svga->crtc[0x21] & 0x20) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); // pclog("Trident linear framebuffer at %08X - size %06X\n", tgui->linear_base, tgui->linear_size); - mem_mapping_enable(&tgui->accel_mapping); + if (tgui->type >= TGUI_9440) + { + mem_mapping_enable(&tgui->accel_mapping); + mem_mapping_disable(&svga->mapping); + } + else + { + switch (svga->gdcreg[6] & 0xC) + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } } else { @@ -512,15 +722,17 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) } } -void *tgui9440_init() +static void *tgui_init(char *bios_fn, int type) { tgui_t *tgui = malloc(sizeof(tgui_t)); memset(tgui, 0, sizeof(tgui_t)); tgui->vram_size = device_get_config_int("memory") << 20; tgui->vram_mask = tgui->vram_size - 1; + + tgui->type = type; - rom_init(&tgui->bios_rom, "9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tgui->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tgui->svga, tgui, tgui->vram_size, tgui_recalctimings, @@ -533,9 +745,11 @@ void *tgui9440_init() mem_mapping_disable(&tgui->accel_mapping); io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + if (tgui->type >= TGUI_9440) + io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - pci_add(tgui_pci_read, tgui_pci_write, tgui); + if (tgui->type >= TGUI_9440) + pci_add(tgui_pci_read, tgui_pci_write, tgui); tgui->wake_fifo_thread = thread_create_event(); tgui->fifo_not_full_event = thread_create_event(); @@ -544,6 +758,21 @@ void *tgui9440_init() return tgui; } +static void *tgui9400cxi_init() +{ + return tgui_init("9400CXI.vbi", TGUI_9400CXI); +} + +static void *tgui9440_init() +{ + return tgui_init("9440.vbi", TGUI_9440); +} + +static int tgui9400cxi_available() +{ + return rom_present("9400CXI.VBI"); +} + static int tgui9440_available() { return rom_present("9440.vbi"); @@ -576,6 +805,208 @@ void tgui_force_redraw(void *p) tgui->svga.fullchange = changeframecount; } + +static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; + int c; + + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + addr &= ~0xf; + for (c = 0; c < 16; c++) + tgui->copy_latch[c] = svga->vram[addr+c]; + + return svga->vram[addr & svga->vram_mask]; +} + +static uint8_t tgui_ext_read(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + return tgui_ext_linear_read(addr, svga); +} + +static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; + int c; + uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; + uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; + uint8_t mask = tgui->ext_gdc_regs[7]; + + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= ~0x7; + svga->changedvram[addr >> 12] = changeframecount; + + switch (tgui->ext_gdc_regs[0] & 0xf) + { + /*8-bit mono->colour expansion, unmasked*/ + case 2: + for (c = 7; c >= 0; c--) + { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; + addr++; + } + break; + + /*16-bit mono->colour expansion, unmasked*/ + case 3: + for (c = 7; c >= 0; c--) + { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr++; + } + break; + + /*8-bit mono->colour expansion, masked*/ + case 6: + for (c = 7; c >= 0; c--) + { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[0]; + addr++; + } + break; + + /*16-bit mono->colour expansion, masked*/ + case 7: + for (c = 7; c >= 0; c--) + { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; + addr++; + } + break; + + case 0x8: case 0x9: case 0xa: case 0xb: + case 0xc: case 0xd: case 0xe: case 0xf: + addr &= ~0xf; + for (c = 0; c < 16; c++) + *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; + break; + } +} + +static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; + int c; + uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; + uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; + uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; + + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= ~0xf; + svga->changedvram[addr >> 12] = changeframecount; + + val = (val >> 8) | (val << 8); + + switch (tgui->ext_gdc_regs[0] & 0xf) + { + /*8-bit mono->colour expansion, unmasked*/ + case 2: + for (c = 15; c >= 0; c--) + { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; + addr++; + } + break; + + /*16-bit mono->colour expansion, unmasked*/ + case 3: + for (c = 15; c >= 0; c--) + { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr++; + } + break; + + /*8-bit mono->colour expansion, masked*/ + case 6: + for (c = 15; c >= 0; c--) + { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[0]; + addr++; + } + break; + + /*16-bit mono->colour expansion, masked*/ + case 7: + for (c = 15; c >= 0; c--) + { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; + addr++; + } + break; + + case 0x8: case 0x9: case 0xa: case 0xb: + case 0xc: case 0xd: case 0xe: case 0xf: + for (c = 0; c < 16; c++) + *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; + break; + } +} + +static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) +{ + tgui_ext_linear_writew(addr, val, p); +} + +static void tgui_ext_write(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + tgui_ext_linear_write(addr, val, svga); +} +static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + tgui_ext_linear_writew(addr, val, svga); +} +static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + tgui_ext_linear_writel(addr, val, svga); +} + + enum { TGUI_BITBLT = 1 @@ -1318,6 +1749,19 @@ static device_config_t tgui9440_config[] = } }; +device_t tgui9400cxi_device = +{ + "Trident TGUI 9400CXi", + 0, + tgui9400cxi_init, + tgui_close, + tgui9400cxi_available, + tgui_speed_changed, + tgui_force_redraw, + tgui_add_status_info, + tgui9440_config +}; + device_t tgui9440_device = { "Trident TGUI 9440", diff --git a/src/vid_tgui9440.h b/src/vid_tgui9440.h index 828562d..6826d04 100644 --- a/src/vid_tgui9440.h +++ b/src/vid_tgui9440.h @@ -1 +1,2 @@ +extern device_t tgui9400cxi_device; extern device_t tgui9440_device; diff --git a/src/video.c b/src/video.c index 1166b75..a69d5a0 100644 --- a/src/video.c +++ b/src/video.c @@ -91,6 +91,7 @@ static VIDEO_CARD video_cards[] = {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"VGA", "vga", &vga_device, GFX_VGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Wyse 700", "wy700", &wy700_device, GFX_WY700, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From c88fb61aab039c8c4a1121b5c2f0f71f0a745de6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 14:47:53 +0000 Subject: [PATCH 0304/1050] Fix SVGA decode mask for Trident TGUI9440. --- src/vid_tgui9440.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 0014cc5..de748b0 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -311,6 +311,7 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) { tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; + tgui->svga.decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; } tgui_recalcmapping(tgui); } @@ -710,12 +711,14 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) case 0x12: tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); tgui->linear_size = 2 << 20; + tgui->svga.decode_mask = 0x1fffff; svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4); tgui_recalcmapping(tgui); break; case 0x13: tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); tgui->linear_size = 2 << 20; + tgui->svga.decode_mask = 0x1fffff; svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6); tgui_recalcmapping(tgui); break; From 2df886b1d89c1fe249bb0e544884b956bb7535c6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 15:36:59 +0000 Subject: [PATCH 0305/1050] Only offset TGUI9440 blitter CPU data when CPU source is mono. Fixes some corruption in Windows 3.x. --- src/vid_tgui9440.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index de748b0..f2b2134 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -1068,7 +1068,7 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (tgui->accel.bpp == 0) trans_col &= 0xff; - if (count != -1 && !tgui->accel.x) + if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { count -= tgui->accel.offset; cpu_dat <<= tgui->accel.offset; From 245ad1cd4234bffa8c0d21e301972bf812f50a64 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 15:37:25 +0000 Subject: [PATCH 0306/1050] Fix TGUI9440 cursor in interlaced modes. --- src/vid_tgui9440.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index f2b2134..cdc6ef6 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -642,6 +642,9 @@ void tgui_hwcursor_draw(svga_t *svga, int displine) int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 8; + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; for (xx = 0; xx < 32; xx++) @@ -660,6 +663,9 @@ void tgui_hwcursor_draw(svga_t *svga, int displine) dat[1] <<= 1; } svga->hwcursor_latch.addr += 8; + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 8; } uint8_t tgui_pci_read(int func, int addr, void *p) From 1d93b73e3a417da80b2713981405a984655f4fd2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 15:40:41 +0000 Subject: [PATCH 0307/1050] Implement configurable hardware cursor size on TGUI9440. --- src/vid_svga.c | 9 +++++++-- src/vid_tgui9440.c | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index c91a92a..8817ca9 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -459,13 +459,17 @@ void svga_poll(void *p) // 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; + svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; + if (svga->hwcursor_on < 0) + svga->hwcursor_on = 0; svga->hwcursor_oddeven = 0; } if (svga->displine == svga->hwcursor_latch.y+1 && svga->hwcursor_latch.ena && svga->interlace) { - svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff; + svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; + if (svga->hwcursor_on < 0) + svga->hwcursor_on = 0; svga->hwcursor_oddeven = 1; } @@ -744,6 +748,7 @@ 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->hwcursor.ysize = 64; // _svga_recalctimings(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); diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index cdc6ef6..9333981 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -331,7 +331,11 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) case 0x50: if (tgui->type >= TGUI_9440) + { svga->hwcursor.ena = val & 0x80; + svga->hwcursor.xsize = (val & 1) ? 64 : 32; + svga->hwcursor.ysize = (val & 1) ? 64 : 32; + } break; } return; From f0889fd981c842d545ba7694733e206086dc8dcc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 15:45:41 +0000 Subject: [PATCH 0308/1050] Fix automake include path for Windows. --- src/Makefile.am | 2 +- src/Makefile.in | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 9f2ca5f..7a08697 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,7 +104,7 @@ pcem_CXXFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP endif if OS_WINDOWS -#DEFAULT_INCLUDES = -iquote . +DEFAULT_INCLUDES = -iquote . pcem_SOURCES += cdrom-ioctl.c wx-sdl2-display-win.c pcem_LDADD += wx.res endif diff --git a/src/Makefile.in b/src/Makefile.in index 822176b..733dfff 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -118,8 +118,7 @@ bin_PROGRAMS = pcem$(EXEEXT) @OS_MACOSX_TRUE@am__append_14 = cdrom-ioctl-osx.c wx-sdl2-display.c @OS_MACOSX_TRUE@am__append_15 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP @OS_MACOSX_TRUE@am__append_16 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP - -#DEFAULT_INCLUDES = -iquote . +DEFAULT_INCLUDES = -I.@am__isrc@ @OS_WINDOWS_TRUE@am__append_17 = cdrom-ioctl.c wx-sdl2-display-win.c @OS_WINDOWS_TRUE@am__append_18 = wx.res @HAS_OFF64T_FALSE@am__append_19 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell @@ -371,7 +370,6 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f @@ -623,6 +621,7 @@ pcem_CFLAGS = $(subst -fpermissive,,$(shell wx-config --cxxflags) \ pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ --cflags) $(am__append_10) $(am__append_16) $(am__append_21) pcem_LDADD = @LIBS@ $(am__append_3) $(am__append_12) $(am__append_18) +@OS_WINDOWS_TRUE@DEFAULT_INCLUDES = -iquote . all: all-am .SUFFIXES: From 0e7c28261dd7aebc733ace435bbab606351ff642 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Feb 2018 18:16:36 +0000 Subject: [PATCH 0309/1050] Sound Blaster ADPCM playback now counts the reference byte into the sample length. Fixes clicking/popping in Monster Bash. --- src/sound_sb_dsp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index fb1532a..5d1f30f 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -358,6 +358,8 @@ void sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = sb_8_read_dma(dsp); dsp->sb_8_length--; + if (dsp->sb_command == 0x17) + dsp->sb_8_length--; break; case 0x1C: /*8-bit autoinit DMA output*/ if (dsp->sb_type < SB15) break; @@ -420,6 +422,8 @@ void sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = sb_8_read_dma(dsp); dsp->sb_8_length--; + if (dsp->sb_command == 0x75) + dsp->sb_8_length--; break; case 0x77: /*2.6-bit ADPCM output with reference*/ dsp->sbref = sb_8_read_dma(dsp); @@ -429,6 +433,8 @@ void sb_exec_command(sb_dsp_t *dsp) sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = sb_8_read_dma(dsp); dsp->sb_8_length--; + if (dsp->sb_command == 0x77) + dsp->sb_8_length--; break; case 0x7D: /*4-bit ADPCM autoinit output*/ if (dsp->sb_type < SB15) break; From 75ec50cfd7d2d78354bfcdcfd349858411056e9e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 12:00:32 +0000 Subject: [PATCH 0310/1050] Implemented dynamic low-pass filter for SB16/AWE32 DSP playback. --- src/filters.h | 30 ++++++++++++++++++++++++++++++ src/sound_sb.c | 11 ++++------- src/sound_sb_dsp.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/filters.h b/src/filters.h index dfeb91b..c3431d4 100644 --- a/src/filters.h +++ b/src/filters.h @@ -345,3 +345,33 @@ static inline float dac_iir(int i, float NewSample) { return y[i][0]; } + + +#define SB16_NCoef 51 + +extern float low_fir_sb16_coef[SB16_NCoef]; + +static inline float low_fir_sb16(int i, float NewSample) +{ + static float x[2][SB16_NCoef+1]; //input samples + static int pos = 0; + float out = 0.0; + int n; + + //Calculate the new output + x[i][pos] = NewSample; + + for (n = 0; n < ((SB16_NCoef+1)-pos); n++) + out += low_fir_sb16_coef[n] * x[i][n+pos]; + for (; n < SB16_NCoef; n++) + out += low_fir_sb16_coef[n] * x[i][(n+pos) - (SB16_NCoef+1)]; + + if (i == 1) + { + pos++; + if (pos > SB16_NCoef) + pos = 0; + } + + return out; +} diff --git a/src/sound_sb.c b/src/sound_sb.c index 3cee369..cb3eaf9 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -261,9 +261,8 @@ static void sb_get_buffer_sb16(int32_t *buffer, int len, void *p) in_l = (mixer->input_selector_left&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_left&INPUT_MIDI_R) ? out_r : 0; in_r = (mixer->input_selector_right&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_right&INPUT_MIDI_R) ? out_r : 0; - /*TODO: CT1745 features dynamic filtering. https://www.vogons.org/viewtopic.php?f=62&t=51514 */ - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 15; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 15; + out_l += ((int32_t)(low_fir_sb16(0, (float)sb->dsp.buffer[c]) * mixer->voice_l) / 3) >> 15; + out_r += ((int32_t)(low_fir_sb16(1, (float)sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3) >> 15; out_l = (out_l * mixer->master_l) >> 15; out_r = (out_r * mixer->master_r) >> 15; @@ -341,10 +340,8 @@ static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) in_l = (mixer->input_selector_left&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_left&INPUT_MIDI_R) ? out_r : 0; in_r = (mixer->input_selector_right&INPUT_MIDI_L) ? out_l : 0 + (mixer->input_selector_right&INPUT_MIDI_R) ? out_r : 0; - - /*TODO: CT1745 features dynamic filtering. https://www.vogons.org/viewtopic.php?f=62&t=51514 */ - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 15; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 15; + out_l += ((int32_t)(low_fir_sb16(0, (float)sb->dsp.buffer[c]) * mixer->voice_l) / 3) >> 15; + out_r += ((int32_t)(low_fir_sb16(1, (float)sb->dsp.buffer[c + 1]) * mixer->voice_r) / 3) >> 15; out_l = (out_l * mixer->master_l) >> 15; out_r = (out_r * mixer->master_r) >> 15; diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 5d1f30f..d720478 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -6,10 +6,12 @@ #include #include +#include #include "ibm.h" #include "dma.h" +#include "filters.h" #include "io.h" #include "pic.h" #include "sound.h" @@ -108,6 +110,42 @@ uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x 252, 0, 252, 0 }; +float low_fir_sb16_coef[SB16_NCoef]; + +static inline double sinc(double x) +{ + return sin(M_PI * x) / (M_PI * x); +} + +static void recalc_sb16_filter(int playback_freq) +{ + /*Cutoff frequency = playback / 2*/ + float fC = ((float)playback_freq / 2.0) / 48000.0; + float gain; + int n; + + for (n = 0; n < SB16_NCoef; n++) + { + /*Blackman window*/ + double w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(SB16_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(SB16_NCoef-1))); + /*Sinc filter*/ + double h = sinc(2.0 * fC * ((double)n - ((double)(SB16_NCoef-1) / 2.0))); + + /*Create windowed-sinc filter*/ + low_fir_sb16_coef[n] = w * h; + } + + low_fir_sb16_coef[(SB16_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < SB16_NCoef; n++) + gain += low_fir_sb16_coef[n]; + + /*Normalise filter, to produce unity gain*/ + for (n = 0; n < SB16_NCoef; n++) + low_fir_sb16_coef[n] /= gain; +} + void sb_irq(sb_dsp_t *dsp, int irq8) @@ -399,6 +437,8 @@ void sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; // pclog("Sample rate - %ihz (%i)\n",temp, dsp->sblatcho); + if (dsp->sb_freq != temp && dsp->sb_type >= SB16) + recalc_sb16_filter(temp); dsp->sb_freq = temp; break; case 0x41: /*Set output sampling rate*/ @@ -406,10 +446,13 @@ void sb_exec_command(sb_dsp_t *dsp) 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); + temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256 + dsp->sb_freq; dsp->sblatchi = dsp->sblatcho; dsp->sb_timei = dsp->sb_timeo; + if (dsp->sb_freq != temp && dsp->sb_type >= SB16) + recalc_sb16_filter(dsp->sb_freq); break; case 0x48: /*Set DSP block transfer size*/ dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); From 90c8d0939c81e934afd6270987d16a908be236f4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 12:37:21 +0000 Subject: [PATCH 0311/1050] Added Packard Bell Legend 300SX. Patch from dns2kv2. --- src/ibm.h | 1 + src/mem.c | 8 ++++++++ src/model.c | 7 +++++++ src/model.h | 2 +- src/nvr.c | 2 ++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ibm.h b/src/ibm.h index 70990a9..adea934 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -447,6 +447,7 @@ enum ROM_T3100E, ROM_T1000, ROM_T1200, + ROM_PB_L300SX, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index dcf4cdc..960370b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -791,6 +791,14 @@ int loadbios() biosmask = 0x7fff; fclose(f); return 1; + + case ROM_PB_L300SX: + f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); + if (!f) break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index e2504f1..6f2e63d 100644 --- a/src/model.c +++ b/src/model.c @@ -71,6 +71,7 @@ void ibm_at_init(); void at_cbm_init(); void dells200_init(); void deskpro386_init(); +void pb_l300sx_init(); void ps1_m2011_init(); void ps1_m2121_init(); void ps2_m30_286_init(); @@ -148,6 +149,7 @@ MODEL models[] = {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT , 512,16384,512, at_scatsx_init, NULL}, + {"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL}, {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, @@ -490,6 +492,11 @@ void at_ali1429_init() ali1429_init(); } +void pb_l300sx_init() +{ + at_init(); +} + void at_sis496_init() { at_init(); diff --git a/src/model.h b/src/model.h index 4c23cb1..6c94345 100644 --- a/src/model.h +++ b/src/model.h @@ -8,7 +8,7 @@ typedef struct { - char name[32]; + char name[64]; int id; char internal_name[24]; struct diff --git a/src/nvr.c b/src/nvr.c index 25dd137..847cebf 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -286,6 +286,7 @@ void loadnvr() case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); nvrmask = 127; break; + case ROM_PB_L300SX: f = nvrfopen("pb_l300sx.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); nvrmask = 127; break; case ROM_T3100E: f = nvrfopen("t3100e.nvr", "rb"); break; case ROM_T1000: tc8521_loadnvr(); @@ -367,6 +368,7 @@ void savenvr() case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "wb"); break; case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); break; + case ROM_PB_L300SX: f = nvrfopen("pb_l300sx.nvr", "wb"); break; case ROM_T3100E: f = nvrfopen("t3100e.nvr", "wb"); break; case ROM_T1000: tc8521_savenvr(); t1000_configsys_savenvr(); From e5b38d7e6806d0ab3a13e16d8a24644dfc6871f1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 12:45:29 +0000 Subject: [PATCH 0312/1050] Added NCR PC4i. Patch from dns2kv2. --- src/ibm.h | 1 + src/mem.c | 7 +++++++ src/model.c | 1 + 3 files changed, 9 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index adea934..6ea7934 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -448,6 +448,7 @@ enum ROM_T1000, ROM_T1200, ROM_PB_L300SX, + ROM_NCR_PC4I, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index 960370b..b4f3d4a 100644 --- a/src/mem.c +++ b/src/mem.c @@ -799,6 +799,13 @@ int loadbios() fclose(f); return 1; + case ROM_NCR_PC4I: + f=romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN" ,"rb"); + if (!f) break; + romfread(rom, 0x4000, 1, f); + fclose(f); + biosmask = 0x3fff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 6f2e63d..b75b066 100644 --- a/src/model.c +++ b/src/model.c @@ -108,6 +108,7 @@ MODEL models[] = {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 64, pcjr_init, &pcjr_device}, {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, From 788402b8799cd9d82ba26b7f459a295a79929538 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 13:24:00 +0000 Subject: [PATCH 0313/1050] Added Thomson TO16 PC. Patch from dns2kv2. --- src/ibm.h | 1 + src/mem.c | 7 +++++++ src/model.c | 1 + 3 files changed, 9 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index 6ea7934..d263be5 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -449,6 +449,7 @@ enum ROM_T1200, ROM_PB_L300SX, ROM_NCR_PC4I, + ROM_TO16_PC, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index b4f3d4a..a7faf37 100644 --- a/src/mem.c +++ b/src/mem.c @@ -806,6 +806,13 @@ int loadbios() fclose(f); biosmask = 0x3fff; return 1; + + case ROM_TO16_PC: + f=romfopen("to16_pc/TO16_103.bin","rb"); + if (!f) break; + romfread(rom+0x8000,32768,1,f); + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index b75b066..493301c 100644 --- a/src/model.c +++ b/src/model.c @@ -113,6 +113,7 @@ MODEL models[] = {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, xt_init, NULL}, {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 512,1280, 768, xt_t1000_init, &t1000_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, From 1d4b9af7e2e2fd5b0dac6c22667afcbeb54ee1c7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 13:40:17 +0000 Subject: [PATCH 0314/1050] Added Compaq Portable II. Patch from dns2kv2. --- src/ibm.h | 1 + src/mem.c | 14 ++++++++++++++ src/model.c | 1 + src/nvr.c | 2 ++ 4 files changed, 18 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index d263be5..ee63c36 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -450,6 +450,7 @@ enum ROM_PB_L300SX, ROM_NCR_PC4I, ROM_TO16_PC, + ROM_COMPAQ_PII, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index a7faf37..fc4c1ec 100644 --- a/src/mem.c +++ b/src/mem.c @@ -813,6 +813,20 @@ int loadbios() romfread(rom+0x8000,32768,1,f); fclose(f); return 1; + + case ROM_COMPAQ_PII: + f = romfopen("compaq_pii/109740-001.rom", "rb"); + ff = romfopen("compaq_pii/109739-001.rom", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 493301c..7c67ab1 100644 --- a/src/model.c +++ b/src/model.c @@ -130,6 +130,7 @@ MODEL models[] = {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_cbm_init, NULL}, + {"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 256,15872,128, ibm_at_init, NULL}, {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 847cebf..dca9c8b 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -288,6 +288,7 @@ void loadnvr() case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); nvrmask = 127; break; case ROM_PB_L300SX: f = nvrfopen("pb_l300sx.nvr", "rb"); nvrmask = 127; break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); nvrmask = 127; break; + case ROM_COMPAQ_PII: f = nvrfopen("compaq_pii.nvr", "rb"); break; case ROM_T3100E: f = nvrfopen("t3100e.nvr", "rb"); break; case ROM_T1000: tc8521_loadnvr(); t1000_configsys_loadnvr(); @@ -368,6 +369,7 @@ void savenvr() case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "wb"); break; case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); break; case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); break; + case ROM_COMPAQ_PII: f = nvrfopen("compaq_pii.nvr", "wb"); break; case ROM_PB_L300SX: f = nvrfopen("pb_l300sx.nvr", "wb"); break; case ROM_T3100E: f = nvrfopen("t3100e.nvr", "wb"); break; case ROM_T1000: tc8521_savenvr(); From 72c2cb6f7daa13216572914b46143621245a511d Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 15:55:25 +0000 Subject: [PATCH 0315/1050] Added basic emulation of ACC Micro 2036 chipset (used by Packard Bell Legend 300SX). --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/acc2036.c | 99 ++++++++++++++++++++++++++++++ src/acc2036.h | 1 + src/mem.h | 1 + src/model.c | 2 + 13 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 src/acc2036.c create mode 100644 src/acc2036.h diff --git a/src/Makefile.am b/src/Makefile.am index 7a08697..198619b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 7dc3437..31f48bc 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 3670495..07a0917 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 649478b..802265c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index ff33020..5a23b3c 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -4,7 +4,7 @@ CC = gcc.exe MAKE = make.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -DUSE_NETWORKING -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index e7056fe..43d8e15 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = C:/MinGW/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index dccbcc5..079c4d5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index de15103..cdca013 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 50ba24f..b12a0ac 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -3,7 +3,7 @@ CPP = g++ CC = gcc WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/acc2036.c b/src/acc2036.c new file mode 100644 index 0000000..bf511fb --- /dev/null +++ b/src/acc2036.c @@ -0,0 +1,99 @@ +#include "ibm.h" +#include "acc2036.h" +#include "io.h" +#include "mem.h" + +static struct +{ + int reg_idx; + uint8_t regs[256]; +} acc2036; + +static void acc2036_shadow_recalc() +{ + if (acc2036.regs[0x2c] & 8) + { + switch (acc2036.regs[0x22] & 3) + { + case 0: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + } + else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + if (acc2036.regs[0x2c] & 4) + { + switch (acc2036.regs[0x22] & 3) + { + case 0: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + } + else + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + +static void acc2036_write(uint16_t addr, uint8_t val, void *p) +{ + if (!(addr & 1)) + acc2036.reg_idx = val; + else + { + acc2036.regs[acc2036.reg_idx] = val; +// pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins); + + switch (acc2036.reg_idx) + { + case 0x22: + case 0x2c: + acc2036_shadow_recalc(); + break; + + case 0x23: + mem_mapping_disable(&ram_remapped_mapping); + if (val & 0x10) + { + if (acc2036.regs[0x2c] & 0xc) + mem_remap_top_256k(); + else + mem_remap_top_384k(); + } + break; + } + } +} + +static uint8_t acc2036_read(uint16_t addr, void *p) +{ + if (!(addr & 1)) + return acc2036.reg_idx; + + return acc2036.regs[acc2036.reg_idx]; +} + +void acc2036_init() +{ + memset(&acc2036, 0, sizeof(acc2036)); + io_sethandler(0x00f2, 0x0002, acc2036_read, NULL, NULL, acc2036_write, NULL, NULL, NULL); +} diff --git a/src/acc2036.h b/src/acc2036.h new file mode 100644 index 0000000..40561fa --- /dev/null +++ b/src/acc2036.h @@ -0,0 +1 @@ +void acc2036_init(); diff --git a/src/mem.h b/src/mem.h index 618e8dc..7bcce0b 100644 --- a/src/mem.h +++ b/src/mem.h @@ -107,6 +107,7 @@ mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; extern mem_mapping_t ram_high_mapping; +extern mem_mapping_t ram_remapped_mapping; typedef struct page_t { diff --git a/src/model.c b/src/model.c index 7c67ab1..ebe66d6 100644 --- a/src/model.c +++ b/src/model.c @@ -4,6 +4,7 @@ #include "io.h" #include "mouse.h" +#include "acc2036.h" #include "acer386sx.h" #include "ali1429.h" #include "amstrad.h" @@ -498,6 +499,7 @@ void at_ali1429_init() void pb_l300sx_init() { at_init(); + acc2036_init(); } void at_sis496_init() From 4cc15d9b7ec019be8e3a70a290a1f4599b439aa7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Feb 2018 20:06:00 +0000 Subject: [PATCH 0316/1050] Added Elonex PC-425X emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ibm.h | 1 + src/mem.c | 17 +++++++ src/model.c | 9 ++++ src/nvr.c | 2 + src/sl82c460.c | 76 ++++++++++++++++++++++++++++++ src/sl82c460.h | 1 + src/vid_tgui9440.c | 37 +++++++++++++-- src/vid_tgui9440.h | 1 + src/video.c | 11 +++++ 18 files changed, 160 insertions(+), 13 deletions(-) create mode 100644 src/sl82c460.c create mode 100644 src/sl82c460.h diff --git a/src/Makefile.am b/src/Makefile.am index 198619b..e6fbd4a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,7 +30,7 @@ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atap joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ -serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c sound_cms.c sound_emu8k.c sound_gus.c \ +serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ t1000.c t3100e.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 31f48bc..a7a9e02 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -11,7 +11,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atap joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 07a0917..a570355 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -11,7 +11,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atap joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 802265c..5233ddc 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 acc2036.o acer386sx.o ali1429 i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 5a23b3c..2cbced2 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 43d8e15..9ab5e4d 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 079c4d5..99f7bbc 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -12,7 +12,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.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 cdca013..60e7828 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 acc2036.o acer386sx.o ali1429 i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index b12a0ac..07ecbac 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -10,7 +10,7 @@ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atap joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ -serial.o sio.o sis496.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ +serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ diff --git a/src/ibm.h b/src/ibm.h index ee63c36..06b2036 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -451,6 +451,7 @@ enum ROM_NCR_PC4I, ROM_TO16_PC, ROM_COMPAQ_PII, + ROM_ELX_PC425X, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index fc4c1ec..b38248e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -827,6 +827,23 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; + + case ROM_ELX_PC425X: + /*PC-425X uses a single ROM chip containing both main and video BIOSes. + First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. + Alternatively, seperate BIOS + video BIOS dumps are supported.*/ + f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); + if (!f) + { + f = romfopen("elx_pc425x/elx_pc425x_bios.bin", "rb"); + if (!f) + break; + } + else + fseek(f, 0x10000, SEEK_SET); + romfread(rom, 65536, 1, f); + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index ebe66d6..c88f75a 100644 --- a/src/model.c +++ b/src/model.c @@ -49,6 +49,7 @@ #include "serial.h" #include "sio.h" #include "sis496.h" +#include "sl82c460.h" #include "sound_ps1.h" #include "sound_pssj.h" #include "sound_sn76489.h" @@ -95,6 +96,7 @@ void xt_laserxt_init(); void at_t3100e_init(); void xt_t1000_init(); void xt_t1200_init(); +void at_sl82c460_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -163,6 +165,7 @@ MODEL models[] = {"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, + {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 1, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, @@ -512,6 +515,12 @@ void at_sis496_init() device_add(&sis496_device); } +void at_sl82c460_init() +{ + at_init(); + sl82c460_init(); +} + void at_batman_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index dca9c8b..dc92b11 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -297,6 +297,7 @@ void loadnvr() case ROM_T1200: tc8521_loadnvr(); t1000_emsboard_loadnvr(); return; + case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -379,6 +380,7 @@ void savenvr() case ROM_T1200: tc8521_savenvr(); t1000_emsboard_savenvr(); return; + case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/sl82c460.c b/src/sl82c460.c new file mode 100644 index 0000000..8118b05 --- /dev/null +++ b/src/sl82c460.c @@ -0,0 +1,76 @@ +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "sl82c460.h" + +static struct +{ + int reg_idx; + uint8_t regs[256]; +} sl82c460; + +static void sl82c460_shadow_set(uint32_t base, uint32_t size, int state) +{ + switch (state) + { + case 0: + mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + +} + +static void sl82c460_shadow_recalc() +{ + sl82c460_shadow_set(0xc0000, 0x4000, sl82c460.regs[0x18] & 3); + sl82c460_shadow_set(0xc4000, 0x4000, (sl82c460.regs[0x18] >> 2) & 3); + sl82c460_shadow_set(0xc8000, 0x4000, (sl82c460.regs[0x18] >> 4) & 3); + sl82c460_shadow_set(0xcc000, 0x4000, (sl82c460.regs[0x18] >> 6) & 3); + sl82c460_shadow_set(0xd0000, 0x4000, sl82c460.regs[0x19] & 3); + sl82c460_shadow_set(0xd4000, 0x4000, (sl82c460.regs[0x19] >> 2) & 3); + sl82c460_shadow_set(0xd8000, 0x4000, (sl82c460.regs[0x19] >> 4) & 3); + sl82c460_shadow_set(0xdc000, 0x4000, (sl82c460.regs[0x19] >> 6) & 3); + sl82c460_shadow_set(0xe0000, 0x10000, (sl82c460.regs[0x1b] >> 4) & 3); + sl82c460_shadow_set(0xf0000, 0x10000, (sl82c460.regs[0x1b] >> 2) & 3); +} + +static void sl82c460_write(uint16_t addr, uint8_t val, void *p) +{ + if (!(addr & 1)) + sl82c460.reg_idx = val; + else + { +// pclog("SL82C460 write %02x %02x\n", sl82c460.reg_idx, val); + sl82c460.regs[sl82c460.reg_idx] = val; + + switch (sl82c460.reg_idx) + { + case 0x18: case 0x19: case 0x1b: + sl82c460_shadow_recalc(); + break; + } + } +} + +static uint8_t sl82c460_read(uint16_t addr, void *p) +{ + if (!(addr & 1)) + return sl82c460.reg_idx; + + return sl82c460.regs[sl82c460.reg_idx]; +} + +void sl82c460_init() +{ + memset(&sl82c460, 0, sizeof(sl82c460)); + io_sethandler(0x00a8, 0x0002, sl82c460_read, NULL, NULL, sl82c460_write, NULL, NULL, NULL); +} diff --git a/src/sl82c460.h b/src/sl82c460.h new file mode 100644 index 0000000..883a8aa --- /dev/null +++ b/src/sl82c460.h @@ -0,0 +1 @@ +void sl82c460_init(); diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 9333981..bb8194c 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -735,12 +735,15 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *tgui_init(char *bios_fn, int type) +static void *tgui_init(char *bios_fn, int type, int mem_size) { tgui_t *tgui = malloc(sizeof(tgui_t)); memset(tgui, 0, sizeof(tgui_t)); - tgui->vram_size = device_get_config_int("memory") << 20; + if (mem_size) + tgui->vram_size = mem_size; + else + tgui->vram_size = device_get_config_int("memory") << 20; tgui->vram_mask = tgui->vram_size - 1; tgui->type = type; @@ -773,12 +776,25 @@ static void *tgui_init(char *bios_fn, int type) static void *tgui9400cxi_init() { - return tgui_init("9400CXI.vbi", TGUI_9400CXI); + return tgui_init("9400CXI.vbi", TGUI_9400CXI, 0); +} + +static void *tgui9400cxi_elx_init() +{ + /*Try combined ROM dump first. If not present, use seperated dump*/ + FILE *f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); + if (f) + { + fclose(f); + return tgui_init("elx_pc425x/elx_pc425x.bin", TGUI_9400CXI, 512 << 10); + } + + return tgui_init("elx_pc425x/elx_pc425x_vbios.bin", TGUI_9400CXI, 512 << 10); } static void *tgui9440_init() { - return tgui_init("9440.vbi", TGUI_9440); + return tgui_init("9440.vbi", TGUI_9440, 0); } static int tgui9400cxi_available() @@ -1775,6 +1791,19 @@ device_t tgui9400cxi_device = tgui9440_config }; +device_t tgui9400cxi_elx_device = +{ + "Trident TGUI 9400CXi (Elonex PC-425X)", + 0, + tgui9400cxi_elx_init, + tgui_close, + tgui9400cxi_available, + tgui_speed_changed, + tgui_force_redraw, + tgui_add_status_info, + tgui9440_config +}; + device_t tgui9440_device = { "Trident TGUI 9440", diff --git a/src/vid_tgui9440.h b/src/vid_tgui9440.h index 6826d04..66db2d0 100644 --- a/src/vid_tgui9440.h +++ b/src/vid_tgui9440.h @@ -1,2 +1,3 @@ extern device_t tgui9400cxi_device; +extern device_t tgui9400cxi_elx_device; extern device_t tgui9440_device; diff --git a/src/video.c b/src/video.c index a69d5a0..282c44e 100644 --- a/src/video.c +++ b/src/video.c @@ -110,6 +110,7 @@ static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_pc425x = {VIDEO_BUS, 5, 5, 9, 20,20,30}; int video_card_available(int card) { @@ -314,6 +315,11 @@ void video_updatetiming() timing = &timing_t1000; break; + case ROM_ELX_PC425X: + timing = &timing_pc425x; + pclog("PC425 timing\n"); + break; + default: new_gfxcard = video_old_to_new(gfxcard); timing = &video_cards[new_gfxcard].timing; @@ -361,6 +367,7 @@ void video_updatetiming() video_timing_write_l = (int)(bus_timing * video_timing[video_speed][3]); } } + pclog("Video timing %i %i %i\n",video_timing_write_b, video_timing_write_w,video_timing_write_l); if (cpu_16bitbus) { video_timing_read_l = video_timing_read_w * 2; @@ -446,6 +453,10 @@ void video_init() case ROM_T1200: device_add(&t1000_device); return; + + case ROM_ELX_PC425X: + device_add(&tgui9400cxi_elx_device); + return; } device_add(video_cards[video_old_to_new(gfxcard)].device); } From 96deba1ffad4ede392a7f6209765c516b0146047 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 14 Feb 2018 17:52:19 +0000 Subject: [PATCH 0317/1050] Fixed out-of-bounds access in SB16/AWE32 DSP filter. --- src/filters.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filters.h b/src/filters.h index c3431d4..6c84c04 100644 --- a/src/filters.h +++ b/src/filters.h @@ -361,7 +361,7 @@ static inline float low_fir_sb16(int i, float NewSample) //Calculate the new output x[i][pos] = NewSample; - for (n = 0; n < ((SB16_NCoef+1)-pos); n++) + for (n = 0; n < ((SB16_NCoef+1)-pos) && n < SB16_NCoef; n++) out += low_fir_sb16_coef[n] * x[i][n+pos]; for (; n < SB16_NCoef; n++) out += low_fir_sb16_coef[n] * x[i][(n+pos) - (SB16_NCoef+1)]; From ee759e4d589cebbb0dd018502816edf43ebfd3c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 14 Feb 2018 17:59:50 +0000 Subject: [PATCH 0318/1050] Initialise SB16 DSP filter to sensible values on DSP init. --- src/sound_sb_dsp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index d720478..fb4c153 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -777,6 +777,10 @@ void sb_dsp_init(sb_dsp_t *dsp, int type) timer_add(pollsb, &dsp->sbcount, &dsp->sbenable, dsp); timer_add(sb_poll_i, &dsp->sb_count_i, &dsp->sb_enable_i, dsp); timer_add(sb_wb_clear, &dsp->wb_time, &dsp->wb_time, dsp); + + /*Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when + a set frequency command is sent.*/ + recalc_sb16_filter(3200*2); } void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) From 25eb84284fe1342e41989e23d0e222251e1b21a8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 14 Feb 2018 18:44:55 +0000 Subject: [PATCH 0319/1050] Fixed odd/even mode on CL-GD5429. --- src/vid_cl5429.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index e31378c..914a330 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -107,6 +107,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) else svga->writemode = svga->gdcreg[5] & 3; svga->readmode = val & 8; + svga->chain2_read = val & 0x10; // pclog("writemode = %i\n", svga->writemode); return; } @@ -341,11 +342,19 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) // if (svga_output) pclog("Write LFB %08X %02X ", addr, val); if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (svga->chain4 && (svga->writemode < 4)) + if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; } + else if (svga->chain2_write) + { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } else { addr <<= 2; From 93d0db4d9b0cf07896c7d03ff1f2c2dff5ccf5e6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 15 Feb 2018 21:00:12 +0000 Subject: [PATCH 0320/1050] CL-GD5429 improvements : - Support >8 bpp on RAMDAC - Support 16-bit pixel depth on blitter - Support 16-bit pixel depth on write modes 4/5 - Support blitter on PIO - Support interlaced modes - Extended size of graphics controller register array to prevent out-of-bounds accesses --- src/vid_cl5429.c | 378 +++++++++++++++++++++++++++++++++++++++-------- src/vid_svga.c | 2 +- src/vid_svga.h | 2 +- 3 files changed, 318 insertions(+), 64 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 914a330..d3e0b81 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -35,6 +35,8 @@ typedef struct gd5429_t int x_count; } blt; + uint8_t hidden_dac_reg; + int dac_3c6_count; } gd5429_t; void gd5429_write(uint32_t addr, uint8_t val, void *p); @@ -74,20 +76,22 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x10: case 0x30: case 0x50: case 0x70: case 0x90: case 0xb0: case 0xd0: case 0xf0: svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); - pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); +// pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); break; case 0x11: case 0x31: case 0x51: case 0x71: case 0x91: case 0xb1: case 0xd1: case 0xf1: svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); - pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); +// pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); break; case 0x12: svga->hwcursor.ena = val & 1; - pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); + svga->hwcursor.ysize = (val & 4) ? 64 : 32; + svga->hwcursor.yoff = 0; +// pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); break; case 0x13: svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); - pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); +// pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; case 0x17: @@ -98,7 +102,24 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) } break; + case 0x3c6: +// pclog("CL write 3c6 %02x %i\n", val, gd5429->dac_3c6_count); + if (gd5429->dac_3c6_count == 4) + { + gd5429->dac_3c6_count = 0; + gd5429->hidden_dac_reg = val; + svga_recalctimings(svga); + return; + } + gd5429->dac_3c6_count = 0; + break; + case 0x3cf: +// pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); + if (svga->gdcaddr == 0) + gd5429_mmio_write(0x00, val, gd5429); + if (svga->gdcaddr == 1) + gd5429_mmio_write(0x04, val, gd5429); if (svga->gdcaddr == 5) { svga->gdcreg[5] = val; @@ -133,6 +154,73 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) else svga->writemode = svga->gdcreg[5] & 3; break; + + case 0x10: + gd5429_mmio_write(0x01, val, gd5429); + break; + case 0x11: + gd5429_mmio_write(0x05, val, gd5429); + break; + + case 0x20: + gd5429_mmio_write(0x08, val, gd5429); + break; + case 0x21: + gd5429_mmio_write(0x09, val, gd5429); + break; + case 0x22: + gd5429_mmio_write(0x0a, val, gd5429); + break; + case 0x23: + gd5429_mmio_write(0x0b, val, gd5429); + break; + case 0x24: + gd5429_mmio_write(0x0c, val, gd5429); + break; + case 0x25: + gd5429_mmio_write(0x0d, val, gd5429); + break; + case 0x26: + gd5429_mmio_write(0x0e, val, gd5429); + break; + case 0x27: + gd5429_mmio_write(0x0f, val, gd5429); + break; + + case 0x28: + gd5429_mmio_write(0x10, val, gd5429); + break; + case 0x29: + gd5429_mmio_write(0x11, val, gd5429); + break; + case 0x2a: + gd5429_mmio_write(0x12, val, gd5429); + break; + + case 0x2c: + gd5429_mmio_write(0x14, val, gd5429); + break; + case 0x2d: + gd5429_mmio_write(0x15, val, gd5429); + break; + case 0x2e: + gd5429_mmio_write(0x16, val, gd5429); + break; + + case 0x2f: + gd5429_mmio_write(0x17, val, gd5429); + break; + case 0x30: + gd5429_mmio_write(0x18, val, gd5429); + break; + + case 0x32: + gd5429_mmio_write(0x1a, val, gd5429); + break; + + case 0x31: + gd5429_mmio_write(0x40, val, gd5429); + break; } return; } @@ -185,6 +273,16 @@ uint8_t gd5429_in(uint16_t addr, void *p) return svga->seqregs[svga->seqaddr & 0x3f]; } break; + + case 0x3c6: +// pclog("CL read 3c6 %i\n", gd5429->dac_3c6_count); + if (gd5429->dac_3c6_count == 4) + { + gd5429->dac_3c6_count = 0; + return gd5429->hidden_dac_reg; + } + gd5429->dac_3c6_count++; + break; case 0x3cf: if (svga->gdcaddr > 8) @@ -230,7 +328,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) { svga_t *svga = &gd5429->svga; - pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); +// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ @@ -259,15 +357,45 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) void gd5429_recalctimings(svga_t *svga) { -// gd5429_t *gd5429 = (gd5429_t *)svga->p; + gd5429_t *gd5429 = (gd5429_t *)svga->p; + + if (!svga->rowoffset) + svga->rowoffset = 0x100; + + svga->interlace = svga->crtc[0x1a] & 1; if (svga->seqregs[7] & 0x01) { svga->render = svga_render_8bpp_highres; + svga->bpp = 8; } svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); +// pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); + + if (gd5429->hidden_dac_reg & 0x80) + { + if (gd5429->hidden_dac_reg & 0x40) + { + switch (gd5429->hidden_dac_reg & 0xf) + { + case 0x0: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case 0x1: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case 0x5: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + } + } + else + svga->render = svga_render_15bpp_highres; + } } void gd5429_hwcursor_draw(svga_t *svga, int displine) @@ -276,8 +404,10 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) uint8_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - - pclog("HWcursor %i %i %i %i %x %02X %02X\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, offset, displine, svga->hwcursor_latch.addr, svga->vram[svga->hwcursor_latch.addr], svga->vram[svga->hwcursor_latch.addr + 0x80]); + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; + for (x = 0; x < 32; x += 8) { dat[0] = svga->vram[svga->hwcursor_latch.addr]; @@ -298,6 +428,9 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) } svga->hwcursor_latch.addr++; } + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; } @@ -369,41 +502,117 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) switch (svga->writemode) { case 4: - pclog("Writemode 4 : %X ", addr); - addr <<= 1; - svga->changedvram[addr >> 12] = changeframecount; - pclog("%X %X\n", addr, val); - if (val & 0x80) - svga->vram[addr + 0] = svga->gdcreg[1]; - if (val & 0x40) - svga->vram[addr + 1] = svga->gdcreg[1]; - if (val & 0x20) - svga->vram[addr + 2] = svga->gdcreg[1]; - if (val & 0x10) - svga->vram[addr + 3] = svga->gdcreg[1]; - if (val & 0x08) - svga->vram[addr + 4] = svga->gdcreg[1]; - if (val & 0x04) - svga->vram[addr + 5] = svga->gdcreg[1]; - if (val & 0x02) - svga->vram[addr + 6] = svga->gdcreg[1]; - if (val & 0x01) - svga->vram[addr + 7] = svga->gdcreg[1]; + if (svga->gdcreg[0xb] & 0x10) + { +// pclog("Writemode 4 : %X ", addr); + addr <<= 2; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (val & 0x80) + { + svga->vram[addr + 0] = svga->gdcreg[1]; + svga->vram[addr + 1] = svga->gdcreg[0x11]; + } + if (val & 0x40) + { + svga->vram[addr + 2] = svga->gdcreg[1]; + svga->vram[addr + 3] = svga->gdcreg[0x11]; + } + if (val & 0x20) + { + svga->vram[addr + 4] = svga->gdcreg[1]; + svga->vram[addr + 5] = svga->gdcreg[0x11]; + } + if (val & 0x10) + { + svga->vram[addr + 6] = svga->gdcreg[1]; + svga->vram[addr + 7] = svga->gdcreg[0x11]; + } + if (val & 0x08) + { + svga->vram[addr + 8] = svga->gdcreg[1]; + svga->vram[addr + 9] = svga->gdcreg[0x11]; + } + if (val & 0x04) + { + svga->vram[addr + 10] = svga->gdcreg[1]; + svga->vram[addr + 11] = svga->gdcreg[0x11]; + } + if (val & 0x02) + { + svga->vram[addr + 12] = svga->gdcreg[1]; + svga->vram[addr + 13] = svga->gdcreg[0x11]; + } + if (val & 0x01) + { + svga->vram[addr + 14] = svga->gdcreg[1]; + svga->vram[addr + 15] = svga->gdcreg[0x11]; + } + } + else + { +// pclog("Writemode 4 : %X ", addr); + addr <<= 1; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (val & 0x80) + svga->vram[addr + 0] = svga->gdcreg[1]; + if (val & 0x40) + svga->vram[addr + 1] = svga->gdcreg[1]; + if (val & 0x20) + svga->vram[addr + 2] = svga->gdcreg[1]; + if (val & 0x10) + svga->vram[addr + 3] = svga->gdcreg[1]; + if (val & 0x08) + svga->vram[addr + 4] = svga->gdcreg[1]; + if (val & 0x04) + svga->vram[addr + 5] = svga->gdcreg[1]; + if (val & 0x02) + svga->vram[addr + 6] = svga->gdcreg[1]; + if (val & 0x01) + svga->vram[addr + 7] = svga->gdcreg[1]; + } break; case 5: - pclog("Writemode 5 : %X ", addr); - addr <<= 1; - svga->changedvram[addr >> 12] = changeframecount; - pclog("%X %X\n", addr, val); - svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->gdcreg[0xb] & 0x10) + { +// pclog("Writemode 5 : %X ", addr); + addr <<= 2; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x80) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 2] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x40) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 4] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x20) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 6] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x10) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 8] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 9] = (val & 0x08) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 10] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 11] = (val & 0x04) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 12] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 13] = (val & 0x02) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + 14] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 15] = (val & 0x01) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + else + { +// pclog("Writemode 5 : %X ", addr); + addr <<= 1; + svga->changedvram[addr >> 12] = changeframecount; +// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + } break; case 1: @@ -415,7 +624,7 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) case 0: if (svga->gdcreg[3] & 7) val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || (svga->seqregs[7] & 1))) { if (writemask2 & 1) svga->vram[addr] = val; if (writemask2 & 2) svga->vram[addr | 0x1] = val; @@ -552,8 +761,12 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; + int blt_mask = gd5429->blt.mask & 7; - pclog("gd5429_start_blit %i\n", count); + if (gd5429->blt.mode & 0x10) + blt_mask *= 2; + +// pclog("gd5429_start_blit %i\n", count); if (count == -1) { gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr; @@ -561,7 +774,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.width_backup = gd5429->blt.width; gd5429->blt.height_internal = gd5429->blt.height; gd5429->blt.x_count = gd5429->blt.mask & 7; - pclog("gd5429_start_blit : size %i, %i\n", gd5429->blt.width, gd5429->blt.height); + if (gd5429->blt.mode & 0x10) + gd5429->blt.x_count *= 2; +// pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count); if (gd5429->blt.mode & 0x04) { @@ -577,6 +792,8 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429_recalc_mapping(gd5429); } } + else if (gd5429->blt.height_internal == 0xffff) + return; while (count) { @@ -587,6 +804,8 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { if (gd5429->blt.mode & 0x80) { + if (gd5429->blt.mode & 0x10) + fatal("Here blt.mode & 0x10\n"); src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col; mask = cpu_dat & 0x80; cpu_dat <<= 1; @@ -610,22 +829,54 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) mask = 1; break; case 0x40: - src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)]; + if (gd5429->blt.mode & 0x10) + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~15)) | (gd5429->blt.dst_addr & 15)]; + else + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)]; mask = 1; break; case 0x80: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - gd5429->blt.x_count++; - if (gd5429->blt.x_count == 8) + if (gd5429->blt.mode & 0x10) { - gd5429->blt.x_count = 0; - gd5429->blt.src_addr++; + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); + if (gd5429->blt.dst_addr & 1) + src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); + else + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; +// pclog(" src=%02x mask=%i fg_col=%04x bg_col=%04x %i %08x\n", src, mask, gd5429->blt.fg_col, gd5429->blt.bg_col, gd5429->blt.x_count, gd5429->blt.src_addr); + gd5429->blt.x_count++; + if (gd5429->blt.x_count == 16) + { + gd5429->blt.x_count = 0; + gd5429->blt.src_addr++; + } + } + else + { + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + gd5429->blt.x_count++; + if (gd5429->blt.x_count == 8) + { + gd5429->blt.x_count = 0; + gd5429->blt.src_addr++; + } } break; - case 0xc0: - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7)); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + case 0xc0: + if (gd5429->blt.mode & 0x10) + { + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> ((gd5429->blt.dst_addr >> 1) & 7)); + if (gd5429->blt.dst_addr & 1) + src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); + else + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + } + else + { + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7)); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + } break; } count--; @@ -633,7 +884,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask]; svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; - pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); +// pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); switch (gd5429->blt.rop) { case 0x00: dst = 0; break; @@ -653,9 +904,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) case 0xd6: dst = ~src | dst; break; case 0xda: dst = ~(src & dst); break; } - pclog("%02X %02X\n", dst, mask); + //pclog("%02X %02X\n", dst, mask); - if ((gd5429->blt.width_backup - gd5429->blt.width) >= (gd5429->blt.mask & 7) && + if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && !((gd5429->blt.mode & 0x08) && !mask)) svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; @@ -675,7 +926,10 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.src_addr = gd5429->blt.src_addr_backup = gd5429->blt.src_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.src_pitch : gd5429->blt.src_pitch); break; case 0x40: - gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38); + if (gd5429->blt.mode & 0x10) + gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -16 : 16)) & 0x70) | (gd5429->blt.src_addr & ~0x70); + else + gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38); break; case 0x80: if (gd5429->blt.x_count != 0) @@ -711,7 +965,7 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; - pclog("MMIO write %08X %02X\n", addr, val); +// pclog("MMIO write %08X %02X\n", addr, val); switch (addr & 0xff) { case 0x00: @@ -795,7 +1049,7 @@ uint8_t gd5429_mmio_read(uint32_t addr, void *p) { // gd5429_t *gd5429 = (gd5429_t *)p; - pclog("MMIO read %08X\n", addr); +// pclog("MMIO read %08X\n", addr); switch (addr & 0xff) { case 0x40: /*BLT status*/ @@ -806,7 +1060,7 @@ uint8_t gd5429_mmio_read(uint32_t addr, void *p) void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) { - pclog("gd5429_blt_write_w %08X %08X\n", addr, val); +// pclog("gd5429_blt_write_w %08X %08X\n", addr, val); gd5429_start_blit(val, 16, p); } @@ -814,7 +1068,7 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; - pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); +// pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); if ((gd5429->blt.mode & 0x84) == 0x84) { gd5429_start_blit( val & 0xff, 8, p); diff --git a/src/vid_svga.c b/src/vid_svga.c index 8817ca9..b98f460 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -501,7 +501,7 @@ void svga_poll(void *p) } if (svga->hwcursor_on || svga->overlay_on) - svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = 2; + svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = svga->interlace ? 3 : 2; if (!svga->override) svga->render(svga); diff --git a/src/vid_svga.h b/src/vid_svga.h index f3455a3..5c89483 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -4,7 +4,7 @@ typedef struct svga_t uint8_t crtcreg; uint8_t crtc[128]; - uint8_t gdcreg[16]; + uint8_t gdcreg[64]; int gdcaddr; uint8_t attrregs[32]; int attraddr, attrff; From 6c41e5baa80cbadfbbc1d60579a59e0518394e17 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 15 Feb 2018 21:19:59 +0000 Subject: [PATCH 0321/1050] Implemented CL-GD5429 VCLK control. --- src/vid_cl5429.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index d3e0b81..290685d 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -358,6 +358,9 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) void gd5429_recalctimings(svga_t *svga) { gd5429_t *gd5429 = (gd5429_t *)svga->p; + int clock = (svga->miscout >> 2) & 3; + int n, d, p; + double vclk; if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -396,6 +399,22 @@ void gd5429_recalctimings(svga_t *svga) else svga->render = svga_render_15bpp_highres; } + + n = svga->seqregs[0xb + clock] & 0x7f; + d = (svga->seqregs[0x1b + clock] >> 1) & 0x1f; + p = svga->seqregs[0x1b + clock] & 1; + + vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p); + switch (svga->seqregs[7] & 6) + { + case 2: + vclk /= 2.0; + break; + case 4: + vclk /= 3.0; + break; + } + svga->clock = cpuclock / vclk; } void gd5429_hwcursor_draw(svga_t *svga, int displine) @@ -1105,6 +1124,17 @@ void *gd5429_init() svga->hwcursor.xoff = 0; gd5429->bank[1] = 0x8000; + + /*Default VCLK values*/ + svga->seqregs[0xb] = 0x66; + svga->seqregs[0xc] = 0x5b; + svga->seqregs[0xd] = 0x45; + svga->seqregs[0xe] = 0x7e; + svga->seqregs[0x1b] = 0x3b; + svga->seqregs[0x1c] = 0x2f; + svga->seqregs[0x1d] = 0x30; + svga->seqregs[0x1e] = 0x33; + return gd5429; } From d713ad4555dda0f254bf62040196ea8744663e37 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Feb 2018 20:10:39 +0000 Subject: [PATCH 0322/1050] Can now configure RAM size on CL-GD5429. --- src/vid_cl5429.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 290685d..2c2096c 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -90,7 +90,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) // pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); break; case 0x13: - svga->hwcursor.addr = 0x1fc000 + ((val & 0x3f) * 256); + svga->hwcursor.addr = (0x1fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; // pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; @@ -1103,11 +1103,14 @@ void *gd5429_init() { gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); svga_t *svga = &gd5429->svga; + int vram_size; memset(gd5429, 0, sizeof(gd5429_t)); + + vram_size = device_get_config_int("memory"); rom_init(&gd5429->bios_rom, "5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&gd5429->svga, gd5429, 1 << 21, /*2mb*/ + svga_init(&gd5429->svga, gd5429, vram_size << 20, gd5429_recalctimings, gd5429_in, gd5429_out, gd5429_hwcursor_draw, @@ -1174,6 +1177,33 @@ void gd5429_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &gd5429->svga); } +static device_config_t gd5429_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 2 + }, + { + .type = -1 + } +}; + device_t gd5429_device = { "Cirrus Logic GD5429", @@ -1183,5 +1213,6 @@ device_t gd5429_device = gd5429_available, gd5429_speed_changed, gd5429_force_redraw, - gd5429_add_status_info + gd5429_add_status_info, + gd5429_config }; From 2f5bbb3b661108f7cded2cd8650837e28047fa6e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Feb 2018 22:21:01 +0000 Subject: [PATCH 0323/1050] Fixed pattern offsets in CL-GD5429 blitter. --- src/vid_cl5429.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 2c2096c..8a9db66 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -792,9 +792,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.src_addr_backup = gd5429->blt.src_addr; gd5429->blt.width_backup = gd5429->blt.width; gd5429->blt.height_internal = gd5429->blt.height; - gd5429->blt.x_count = gd5429->blt.mask & 7; - if (gd5429->blt.mode & 0x10) - gd5429->blt.x_count *= 2; + gd5429->blt.x_count = 0; // pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count); if (gd5429->blt.mode & 0x04) @@ -862,30 +860,17 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); else src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; -// pclog(" src=%02x mask=%i fg_col=%04x bg_col=%04x %i %08x\n", src, mask, gd5429->blt.fg_col, gd5429->blt.bg_col, gd5429->blt.x_count, gd5429->blt.src_addr); - gd5429->blt.x_count++; - if (gd5429->blt.x_count == 16) - { - gd5429->blt.x_count = 0; - gd5429->blt.src_addr++; - } } else { mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - gd5429->blt.x_count++; - if (gd5429->blt.x_count == 8) - { - gd5429->blt.x_count = 0; - gd5429->blt.src_addr++; - } } break; case 0xc0: if (gd5429->blt.mode & 0x10) { - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> ((gd5429->blt.dst_addr >> 1) & 7)); + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); if (gd5429->blt.dst_addr & 1) src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); else @@ -893,7 +878,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) } else { - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.dst_addr & 7)); + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; } break; @@ -930,6 +915,14 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); + + gd5429->blt.x_count++; + if (gd5429->blt.x_count == ((gd5429->blt.mode & 0x10) ? 16 : 8)) + { + gd5429->blt.x_count = 0; + if ((gd5429->blt.mode & 0xc0) == 0x80) + gd5429->blt.src_addr++; + } gd5429->blt.width--; @@ -952,15 +945,14 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) break; case 0x80: if (gd5429->blt.x_count != 0) - { - gd5429->blt.x_count = 0; gd5429->blt.src_addr++; - } break; case 0xc0: gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429->blt.src_addr & ~7); break; } + + gd5429->blt.x_count = 0; gd5429->blt.height_internal--; if (gd5429->blt.height_internal == 0xffff) From 796ff2b536765e428f333ae2ce720484dbd5cf1c Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Feb 2018 22:21:17 +0000 Subject: [PATCH 0324/1050] Implemented write mask on CL-GD5429 extended write modes. --- src/vid_cl5429.c | 112 ++++++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 40 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 8a9db66..b30e0c1 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -527,42 +527,42 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) addr <<= 2; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - if (val & 0x80) + if (val & svga->seqregs[2] & 0x80) { svga->vram[addr + 0] = svga->gdcreg[1]; svga->vram[addr + 1] = svga->gdcreg[0x11]; } - if (val & 0x40) + if (val & svga->seqregs[2] & 0x40) { svga->vram[addr + 2] = svga->gdcreg[1]; svga->vram[addr + 3] = svga->gdcreg[0x11]; } - if (val & 0x20) + if (val & svga->seqregs[2] & 0x20) { svga->vram[addr + 4] = svga->gdcreg[1]; svga->vram[addr + 5] = svga->gdcreg[0x11]; } - if (val & 0x10) + if (val & svga->seqregs[2] & 0x10) { svga->vram[addr + 6] = svga->gdcreg[1]; svga->vram[addr + 7] = svga->gdcreg[0x11]; } - if (val & 0x08) + if (val & svga->seqregs[2] & 0x08) { svga->vram[addr + 8] = svga->gdcreg[1]; svga->vram[addr + 9] = svga->gdcreg[0x11]; } - if (val & 0x04) + if (val & svga->seqregs[2] & 0x04) { svga->vram[addr + 10] = svga->gdcreg[1]; svga->vram[addr + 11] = svga->gdcreg[0x11]; } - if (val & 0x02) + if (val & svga->seqregs[2] & 0x02) { svga->vram[addr + 12] = svga->gdcreg[1]; svga->vram[addr + 13] = svga->gdcreg[0x11]; } - if (val & 0x01) + if (val & svga->seqregs[2] & 0x01) { svga->vram[addr + 14] = svga->gdcreg[1]; svga->vram[addr + 15] = svga->gdcreg[0x11]; @@ -574,21 +574,21 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) addr <<= 1; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - if (val & 0x80) + if (val & svga->seqregs[2] & 0x80) svga->vram[addr + 0] = svga->gdcreg[1]; - if (val & 0x40) + if (val & svga->seqregs[2] & 0x40) svga->vram[addr + 1] = svga->gdcreg[1]; - if (val & 0x20) + if (val & svga->seqregs[2] & 0x20) svga->vram[addr + 2] = svga->gdcreg[1]; - if (val & 0x10) + if (val & svga->seqregs[2] & 0x10) svga->vram[addr + 3] = svga->gdcreg[1]; - if (val & 0x08) + if (val & svga->seqregs[2] & 0x08) svga->vram[addr + 4] = svga->gdcreg[1]; - if (val & 0x04) + if (val & svga->seqregs[2] & 0x04) svga->vram[addr + 5] = svga->gdcreg[1]; - if (val & 0x02) + if (val & svga->seqregs[2] & 0x02) svga->vram[addr + 6] = svga->gdcreg[1]; - if (val & 0x01) + if (val & svga->seqregs[2] & 0x01) svga->vram[addr + 7] = svga->gdcreg[1]; } break; @@ -600,22 +600,46 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) addr <<= 2; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 1] = (val & 0x80) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 2] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 3] = (val & 0x40) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 4] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 5] = (val & 0x20) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 6] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 7] = (val & 0x10) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 8] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 9] = (val & 0x08) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 10] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 11] = (val & 0x04) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 12] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 13] = (val & 0x02) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - svga->vram[addr + 14] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 15] = (val & 0x01) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + if (svga->seqregs[2] & 0x80) + { + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x80) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x40) + { + svga->vram[addr + 2] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x40) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x20) + { + svga->vram[addr + 4] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x20) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x10) + { + svga->vram[addr + 6] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x10) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x08) + { + svga->vram[addr + 8] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 9] = (val & 0x08) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x04) + { + svga->vram[addr + 10] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 11] = (val & 0x04) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x02) + { + svga->vram[addr + 12] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 13] = (val & 0x02) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x01) + { + svga->vram[addr + 14] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 15] = (val & 0x01) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } } else { @@ -623,14 +647,22 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) addr <<= 1; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x80) + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x40) + svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x20) + svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x10) + svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x08) + svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x04) + svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x02) + svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x01) + svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; } break; From 1a430b574fd670d5c72ebbd5048b6d31c09275cd Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Feb 2018 11:08:46 +0000 Subject: [PATCH 0325/1050] Implement 256kb wrap on CL-GD5429. --- src/vid_cl5429.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index b30e0c1..fedfc2e 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -21,6 +21,8 @@ typedef struct gd5429_t uint32_t bank[2]; uint32_t mask; + + uint32_t vram_mask; struct { @@ -415,6 +417,8 @@ void gd5429_recalctimings(svga_t *svga) break; } svga->clock = cpuclock / vclk; + + svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd5429->vram_mask : 0x3ffff; } void gd5429_hwcursor_draw(svga_t *svga, int displine) @@ -1131,6 +1135,7 @@ void *gd5429_init() memset(gd5429, 0, sizeof(gd5429_t)); vram_size = device_get_config_int("memory"); + gd5429->vram_mask = (vram_size << 20) - 1; rom_init(&gd5429->bios_rom, "5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); From c5d11b5d736eb2e411918488adc72e352befcd2c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Feb 2018 12:58:38 +0000 Subject: [PATCH 0326/1050] Implemented word & long read/write handlers for CL-GD5429. --- src/vid_cl5429.c | 61 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index fedfc2e..f124261 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -41,9 +41,6 @@ typedef struct gd5429_t int dac_3c6_count; } gd5429_t; -void gd5429_write(uint32_t addr, uint8_t val, void *p); -uint8_t gd5429_read(uint32_t addr, void *p); - void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); uint8_t gd5429_mmio_read(uint32_t addr, void *p); @@ -459,7 +456,7 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) void gd5429_write_linear(uint32_t addr, uint8_t val, void *p); -void gd5429_write(uint32_t addr, uint8_t val, void *p) +static void gd5429_write(uint32_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; @@ -469,8 +466,42 @@ void gd5429_write(uint32_t addr, uint8_t val, void *p) // pclog("%08X\n", addr); gd5429_write_linear(addr, val, p); } +static void gd5429_writew(uint32_t addr, uint16_t val, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; -uint8_t gd5429_read(uint32_t addr, void *p) + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + + if (svga->writemode < 4) + svga_writew_linear(addr, val, svga); + else + { + gd5429_write_linear(addr, val, p); + gd5429_write_linear(addr+1, val >> 8, p); + } +} +static void gd5429_writel(uint32_t addr, uint32_t val, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + + if (svga->writemode < 4) + svga_writel_linear(addr, val, svga); + else + { + gd5429_write_linear(addr, val, p); + gd5429_write_linear(addr+1, val >> 8, p); + gd5429_write_linear(addr+2, val >> 16, p); + gd5429_write_linear(addr+3, val >> 24, p); + } +} + +static uint8_t gd5429_read(uint32_t addr, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; @@ -482,6 +513,24 @@ uint8_t gd5429_read(uint32_t addr, void *p) // pclog("%08X %02X\n", addr, ret); return ret; } +static uint16_t gd5429_readw(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + return svga_readw_linear(addr, &gd5429->svga); +} +static uint32_t gd5429_readl(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + return svga_readw_linear(addr, &gd5429->svga); +} void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) { @@ -1145,7 +1194,7 @@ void *gd5429_init() gd5429_hwcursor_draw, NULL); - mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); + mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); mem_mapping_set_p(&gd5429->svga.mapping, gd5429); mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL, 0, gd5429); From 15e8c842558f5171e03b0e3e7b34885d6ce76786 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Feb 2018 13:38:33 +0000 Subject: [PATCH 0327/1050] More accurate CL-GD5429 timing. --- src/vid_cl5429.c | 2 +- src/video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index f124261..8452395 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -529,7 +529,7 @@ static uint32_t gd5429_readl(uint32_t addr, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - return svga_readw_linear(addr, &gd5429->svga); + return svga_readl_linear(addr, &gd5429->svga); } void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) diff --git a/src/video.c b/src/video.c index 282c44e..0bc4476 100644 --- a/src/video.c +++ b/src/video.c @@ -73,7 +73,7 @@ static VIDEO_CARD video_cards[] = {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_ISA, 3, 3, 6, 3, 3, 6}}, + {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From 28749fa3dd85779ce67f23f9c507f5024b5c6ed0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Feb 2018 16:37:45 +0000 Subject: [PATCH 0328/1050] More fixes to CL-GD5429 blitter pattern mode. --- src/vid_cl5429.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 8452395..23611cf 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -34,7 +34,7 @@ typedef struct gd5429_t uint32_t dst_addr_backup, src_addr_backup; uint16_t width_backup, height_internal; - int x_count; + int x_count, y_count; } blt; uint8_t hidden_dac_reg; @@ -878,6 +878,10 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.width_backup = gd5429->blt.width; gd5429->blt.height_internal = gd5429->blt.height; gd5429->blt.x_count = 0; + if ((gd5429->blt.mode & 0xc0) == 0xc0) + gd5429->blt.y_count = gd5429->blt.src_addr & 7; + else + gd5429->blt.y_count = 0; // pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count); if (gd5429->blt.mode & 0x04) @@ -932,9 +936,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) break; case 0x40: if (gd5429->blt.mode & 0x10) - src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~15)) | (gd5429->blt.dst_addr & 15)]; + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 4) + (gd5429->blt.x_count & 15)]; else - src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) | (gd5429->blt.dst_addr & 7)]; + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) + (gd5429->blt.y_count << 3) + (gd5429->blt.x_count & 7)]; mask = 1; break; case 0x80: @@ -955,7 +959,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) case 0xc0: if (gd5429->blt.mode & 0x10) { - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1)); if (gd5429->blt.dst_addr & 1) src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); else @@ -963,7 +967,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) } else { - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> gd5429->blt.x_count); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; } break; @@ -1022,22 +1026,17 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) case 0x00: gd5429->blt.src_addr = gd5429->blt.src_addr_backup = gd5429->blt.src_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.src_pitch : gd5429->blt.src_pitch); break; - case 0x40: - if (gd5429->blt.mode & 0x10) - gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -16 : 16)) & 0x70) | (gd5429->blt.src_addr & ~0x70); - else - gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -8 : 8)) & 0x38) | (gd5429->blt.src_addr & ~0x38); - break; case 0x80: if (gd5429->blt.x_count != 0) gd5429->blt.src_addr++; break; - case 0xc0: - gd5429->blt.src_addr = ((gd5429->blt.src_addr + ((gd5429->blt.mode & 0x01) ? -1 : 1)) & 7) | (gd5429->blt.src_addr & ~7); - break; } gd5429->blt.x_count = 0; + if (gd5429->blt.mode & 0x10) + gd5429->blt.y_count = (gd5429->blt.y_count - 1) & 7; + else + gd5429->blt.y_count = (gd5429->blt.y_count + 1) & 7; gd5429->blt.height_internal--; if (gd5429->blt.height_internal == 0xffff) From 456009ef21273498e187f55cc1613fd9a8c24660 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Feb 2018 16:57:29 +0000 Subject: [PATCH 0329/1050] Remove DEVICE_NOT_WORKING flag from CL-GD5429. --- src/vid_cl5429.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 23611cf..dd5e483 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1284,7 +1284,7 @@ static device_config_t gd5429_config[] = device_t gd5429_device = { "Cirrus Logic GD5429", - DEVICE_NOT_WORKING, + 0, gd5429_init, gd5429_close, gd5429_available, From 5c9a1e9664af62ac3b839ab1e4bd6a2cce00da98 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 18 Feb 2018 12:33:09 +0000 Subject: [PATCH 0330/1050] Added CL-GD5430 emulation. --- src/ibm.h | 1 + src/vid_cl5429.c | 336 ++++++++++++++++++++++++++++++++++++++++++----- src/vid_cl5429.h | 1 + src/vid_svga.c | 8 +- src/vid_svga.h | 2 + src/video.c | 1 + 6 files changed, 309 insertions(+), 40 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 06b2036..a3a5a5f 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -490,6 +490,7 @@ enum GFX_MACH64VT2, /*ATI Mach64 VT2*/ GFX_OLIVETTI_GO481, /*Olivetti GO481 PVGA1A*/ GFX_TGUI9400CXI, + GFX_CL_GD5430, /*Cirrus Logic CL-GD5430*/ GFX_MAX }; diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index dd5e483..71e0974 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -4,6 +4,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "pci.h" #include "rom.h" #include "video.h" #include "vid_cl5429.h" @@ -11,9 +12,16 @@ #include "vid_svga_render.h" #include "vid_unk_ramdac.h" +enum +{ + CL_TYPE_GD5429 = 0, + CL_TYPE_GD5430 +}; + typedef struct gd5429_t { mem_mapping_t mmio_mapping; + mem_mapping_t linear_mapping; svga_t svga; @@ -24,6 +32,8 @@ typedef struct gd5429_t uint32_t vram_mask; + int type; + struct { uint16_t bg_col, fg_col; @@ -39,6 +49,12 @@ typedef struct gd5429_t uint8_t hidden_dac_reg; int dac_3c6_count; + + uint8_t pci_regs[256]; + uint8_t int_line; + int card; + + uint32_t lfb_base; } gd5429_t; void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); @@ -93,6 +109,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) // pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; + case 0x07: + svga->set_reset_disabled = svga->seqregs[7] & 1; case 0x17: gd5429_recalc_mapping(gd5429); break; @@ -296,7 +314,18 @@ uint8_t gd5429_in(uint16_t addr, void *p) switch (svga->crtcreg) { case 0x27: /*ID*/ - return 0x9c; /*GD5429*/ + switch (gd5429->type) + { + case CL_TYPE_GD5429: + return 0x9c; /*GD5429*/ + case CL_TYPE_GD5430: + return 0xa0; /*GD5430*/ + } + break; + case 0x28: /*Class ID*/ + if (gd5429->type == CL_TYPE_GD5430) + return 0xff; /*Standard CL-GD5430*/ + break; } return svga->crtc[svga->crtcreg]; } @@ -327,31 +356,73 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) { svga_t *svga = &gd5429->svga; -// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); - switch (svga->gdcreg[6] & 0x0C) + if (PCI && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&gd5429->linear_mapping); mem_mapping_disable(&gd5429->mmio_mapping); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + return; + } + +// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); + if (!(svga->seqregs[7] & 0xf0)) + { + mem_mapping_disable(&gd5429->linear_mapping); + switch (svga->gdcreg[6] & 0x0C) + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&gd5429->mmio_mapping); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + if (svga->seqregs[0x17] & 0x04) + mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_disable(&gd5429->mmio_mapping); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_disable(&gd5429->mmio_mapping); + svga->banked_mask = 0x7fff; + break; + } + } + else + { + uint32_t base, size; + + if (gd5429->type <= CL_TYPE_GD5429) + { + base = (svga->seqregs[7] & 0xf0) << 16; + if (svga->gdcreg[0xb] & 0x20) + size = 1 * 1024 * 1024; + else + size = 2 * 1024 * 1024; + } + else if (PCI) + { + base = gd5429->lfb_base; + size = 4 * 1024 * 1024; + } + else + { + base = 128*1024*1024; + size = 4 * 1024 * 1024; + } + + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&gd5429->linear_mapping, base, size); if (svga->seqregs[0x17] & 0x04) mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&gd5429->mmio_mapping); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&gd5429->mmio_mapping); - svga->banked_mask = 0x7fff; - break; - } + else + mem_mapping_disable(&gd5429->mmio_mapping); + } } void gd5429_recalctimings(svga_t *svga) @@ -728,7 +799,7 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) case 0: if (svga->gdcreg[3] & 7) val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || (svga->seqregs[7] & 1))) + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { if (writemask2 & 1) svga->vram[addr] = val; if (writemask2 & 2) svga->vram[addr | 0x1] = val; @@ -861,6 +932,49 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) } } +static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + gd5429_t *gd5429 = (gd5429_t *)svga->p; + +// pclog("gd5429_writeb : %08X %02X\n", addr, val); + if (svga->writemode < 4) + svga_write_linear(addr, val, svga); + else + gd5429_write_linear(addr, val & 0xff, gd5429); +} +static void gd5429_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + gd5429_t *gd5429 = (gd5429_t *)svga->p; + +// pclog("gd5429_writew : %08X %04X\n", addr, val); + if (svga->writemode < 4) + svga_writew_linear(addr, val, svga); + else + { + gd5429_write_linear(addr, val & 0xff, gd5429); + gd5429_write_linear(addr+1, val >> 8, gd5429); + } +} +static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + gd5429_t *gd5429 = (gd5429_t *)svga->p; + +// pclog("gd5429_writel : %08X %08X %i\n", addr, val, svga->writemode); + if (svga->writemode < 4) + svga_writel_linear(addr, val, svga); + else + { + gd5429_write_linear(addr, val & 0xff, gd5429); + gd5429_write_linear(addr+1, val >> 8, gd5429); + gd5429_write_linear(addr+2, val >> 16, gd5429); + gd5429_write_linear(addr+3, val >> 24, gd5429); + } +} + + void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; @@ -887,14 +1001,31 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) if (gd5429->blt.mode & 0x04) { // pclog("blt.mode & 0x04\n"); - mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); - mem_mapping_set_p(&svga->mapping, gd5429); + if (!(svga->seqregs[7] & 0xf0)) + { + mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); + mem_mapping_set_p(&svga->mapping, gd5429); + } + else + { + mem_mapping_set_handler(&gd5429->linear_mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); + mem_mapping_set_p(&gd5429->linear_mapping, gd5429); + } + gd5429_recalc_mapping(gd5429); return; } else { - mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); - mem_mapping_set_p(&gd5429->svga.mapping, gd5429); + if (!(svga->seqregs[7] & 0xf0)) + { + mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); + mem_mapping_set_p(&svga->mapping, gd5429); + } + else + { + mem_mapping_set_handler(&gd5429->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); + mem_mapping_set_p(&gd5429->linear_mapping, svga); + } gd5429_recalc_mapping(gd5429); } } @@ -910,12 +1041,16 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { if (gd5429->blt.mode & 0x80) { - if (gd5429->blt.mode & 0x10) - fatal("Here blt.mode & 0x10\n"); - src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col; + if ((gd5429->blt.mode & 0x10) && (gd5429->blt.x_count & 1)) + src = (cpu_dat & 0x80) ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); + else + src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col; mask = cpu_dat & 0x80; - cpu_dat <<= 1; - count--; + if (!(gd5429->blt.mode & 0x10) || (gd5429->blt.x_count & 1)) + { + cpu_dat <<= 1; + count--; + } } else { @@ -1043,8 +1178,18 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { if (gd5429->blt.mode & 0x04) { - mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); - mem_mapping_set_p(&gd5429->svga.mapping, gd5429); + if (!(svga->seqregs[7] & 0xf0)) + { + mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); + mem_mapping_set_p(&svga->mapping, gd5429); + } + else + { + mem_mapping_set_handler(&gd5429->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); + mem_mapping_set_p(&gd5429->linear_mapping, svga); + } +// mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); +// mem_mapping_set_p(&gd5429->svga.mapping, gd5429); gd5429_recalc_mapping(gd5429); } return; @@ -1175,7 +1320,90 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) gd5429_start_blit(val, 32, p); } -void *gd5429_init() +static uint8_t cl_pci_read(int func, int addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + +// pclog("CL PCI read %08X\n", addr); + switch (addr) + { + case 0x00: return 0x13; /*Cirrus Logic*/ + case 0x01: return 0x10; + + case 0x02: + switch (gd5429->type) + { + case CL_TYPE_GD5430: + return 0xa0; + } + return 0xff; + case 0x03: return 0x00; + + case PCI_REG_COMMAND: + return gd5429->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + + case 0x07: return 0 << 1; /*Fast DEVSEL timing*/ + + case 0x08: return 0; /*Revision ID*/ + case 0x09: return 0; /*Programming interface*/ + + case 0x0a: return 0x00; /*Supports VGA interface*/ + case 0x0b: return 0x03; + + case 0x10: return 0x08; /*Linear frame buffer address*/ + case 0x11: return 0x00; + case 0x12: return 0x00; + case 0x13: return gd5429->lfb_base >> 24; + + case 0x30: return gd5429->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: return 0x00; + case 0x32: return gd5429->pci_regs[0x32]; + case 0x33: return gd5429->pci_regs[0x33]; + + case 0x3c: return gd5429->int_line; + case 0x3d: return PCI_INTA; + } + return 0; +} + +static void cl_pci_write(int func, int addr, uint8_t val, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + +// pclog("cl_pci_write: addr=%02x val=%02x\n", addr, val); + switch (addr) + { + case PCI_REG_COMMAND: + gd5429->pci_regs[PCI_REG_COMMAND] = val & 0x23; + io_removehandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (val & PCI_COMMAND_IO) + io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429_recalc_mapping(gd5429); + break; + + case 0x13: + gd5429->lfb_base = val << 24; + gd5429_recalc_mapping(gd5429); + break; + + case 0x30: case 0x32: case 0x33: + gd5429->pci_regs[addr] = val; + if (gd5429->pci_regs[0x30] & 0x01) + { + uint32_t addr = (gd5429->pci_regs[0x32] << 16) | (gd5429->pci_regs[0x33] << 24); + mem_mapping_set_addr(&gd5429->bios_rom.mapping, addr, 0x8000); + } + else + mem_mapping_disable(&gd5429->bios_rom.mapping); + return; + + case 0x3c: + gd5429->int_line = val; + return; + } +} + +static void *cl_init(int type, char *fn) { gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); svga_t *svga = &gd5429->svga; @@ -1184,8 +1412,10 @@ void *gd5429_init() vram_size = device_get_config_int("memory"); gd5429->vram_mask = (vram_size << 20) - 1; + + gd5429->type = type; - rom_init(&gd5429->bios_rom, "5429.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&gd5429->svga, gd5429, vram_size << 20, gd5429_recalctimings, @@ -1197,6 +1427,7 @@ void *gd5429_init() mem_mapping_set_p(&gd5429->svga.mapping, gd5429); mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL, 0, gd5429); + mem_mapping_add(&gd5429->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga); io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); @@ -1215,10 +1446,30 @@ void *gd5429_init() svga->seqregs[0x1d] = 0x30; svga->seqregs[0x1e] = 0x33; + if (PCI && type >= CL_TYPE_GD5430) + { + gd5429->card = pci_add(cl_pci_read, cl_pci_write, gd5429); + + gd5429->pci_regs[0x04] = 7; + + gd5429->pci_regs[0x30] = 0x00; + gd5429->pci_regs[0x32] = 0x0c; + gd5429->pci_regs[0x33] = 0x00; + } return gd5429; } + +static void *gd5429_init() +{ + return cl_init(CL_TYPE_GD5429, "5429.vbi"); +} +static void *gd5430_init() +{ + return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin"); +} + static int gd5429_available() { return rom_present("5429.vbi"); @@ -1293,3 +1544,16 @@ device_t gd5429_device = gd5429_add_status_info, gd5429_config }; + +device_t gd5430_device = +{ + "Cirrus Logic GD5430", + 0, + gd5430_init, + gd5429_close, + gd5429_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config +}; diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index b4a159c..9537552 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1 +1,2 @@ extern device_t gd5429_device; +extern device_t gd5430_device; diff --git a/src/vid_svga.c b/src/vid_svga.c index b98f460..1780ae3 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -824,7 +824,7 @@ void svga_write(uint32_t addr, uint8_t val, void *p) case 0: if (svga->gdcreg[3] & 7) val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { if (writemask2 & 1) svga->vram[addr] = val; if (writemask2 & 2) svga->vram[addr | 0x1] = val; @@ -873,7 +873,7 @@ void svga_write(uint32_t addr, uint8_t val, void *p) } break; case 2: - if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { if (writemask2 & 1) svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); @@ -1083,7 +1083,7 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) case 0: if (svga->gdcreg[3] & 7) val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { if (writemask2 & 1) svga->vram[addr] = val; if (writemask2 & 2) svga->vram[addr | 0x1] = val; @@ -1132,7 +1132,7 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) } break; case 2: - if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { if (writemask2 & 1) svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); if (writemask2 & 2) svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); diff --git a/src/vid_svga.h b/src/vid_svga.h index 5c89483..db5f817 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -46,6 +46,8 @@ typedef struct svga_t int chain4, chain2_write, chain2_read; uint8_t writemask; uint32_t charseta, charsetb; + + int set_reset_disabled; uint8_t egapal[16]; uint32_t pallook[256]; diff --git a/src/video.c b/src/video.c index 0bc4476..c75ca33 100644 --- a/src/video.c +++ b/src/video.c @@ -74,6 +74,7 @@ static VIDEO_CARD video_cards[] = {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From 103ebe5347e52359d34d3a62cca5cbb5f42c6e23 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 18 Feb 2018 12:33:31 +0000 Subject: [PATCH 0331/1050] Fix hang with long ATAPI transfers. --- src/ide_atapi.c | 2 +- src/scsi_cd.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 1faa977..b916898 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -141,7 +141,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { case ATAPI_STATE_COMMAND: *atapi_dev->atastat = READY_STAT | (*atapi_dev->atastat & ERR_STAT); - atapi_dev->max_transfer_len = *atapi_dev->cylinder; + atapi_dev->max_transfer_len = (*atapi_dev->cylinder) & ~1; atapi_dev->bus_state = BUS_CD | BUS_REQ; break; diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 3ba4b60..0f0ceb7 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -651,7 +651,10 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cdpos++; data->cdlen--; if (!data->cdlen) + { + c++; break; + } } readflash_set(READFLASH_HDC, data->id); @@ -706,7 +709,10 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cdpos++; data->cdlen--; if (!data->cdlen) + { + c++; break; + } } data->data_pos_read = 0; From 2ff5e8651488627ea9944b2bb7d84d8adc8b2fd0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Feb 2018 21:33:52 +0000 Subject: [PATCH 0332/1050] Correct PCI ID for 430FX. --- src/i430fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i430fx.c b/src/i430fx.c index 4db750e..8a7fe79 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -143,7 +143,7 @@ void i430fx_init() memset(card_i430fx, 0, 256); card_i430fx[0x00] = 0x86; card_i430fx[0x01] = 0x80; /*Intel*/ - card_i430fx[0x02] = 0x22; card_i430fx[0x03] = 0x01; /*SB82437FX-66*/ + card_i430fx[0x02] = 0x2d; card_i430fx[0x03] = 0x12; /*SB82437FX-66*/ card_i430fx[0x04] = 0x06; card_i430fx[0x05] = 0x00; card_i430fx[0x06] = 0x00; card_i430fx[0x07] = 0x82; card_i430fx[0x08] = 0x00; /*A0 stepping*/ From 1c3bb20044beb370e3857ce98ff9c0fe5a00efab Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Feb 2018 21:35:30 +0000 Subject: [PATCH 0333/1050] Support IDE port enable/disable on PIIX. --- src/piix.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/piix.c b/src/piix.c index 1c3bc28..7538a66 100644 --- a/src/piix.c +++ b/src/piix.c @@ -49,24 +49,12 @@ void piix_write(int func, int addr, uint8_t val, void *priv) card_piix_ide[0x40] = val; break; case 0x41: - if ((val ^ card_piix_ide[0x41]) & 0x80) - { - ide_pri_disable(); - if (val & 0x80) - ide_pri_enable(); - } card_piix_ide[0x41] = val; break; case 0x42: card_piix_ide[0x42] = val; break; case 0x43: - if ((val ^ card_piix_ide[0x43]) & 0x80) - { - ide_sec_disable(); - if (val & 0x80) - ide_sec_enable(); - } card_piix_ide[0x43] = val; break; } @@ -77,6 +65,18 @@ void piix_write(int func, int addr, uint8_t val, void *priv) if (card_piix_ide[0x04] & 1) io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); } + if (addr == 4 || addr == 0x41 || addr == 0x43) + { + ide_pri_disable(); + ide_sec_disable(); + if (card_piix_ide[0x04] & 1) + { + if (card_piix_ide[0x41] & 0x80) + ide_pri_enable(); + if (card_piix_ide[0x43] & 0x80) + ide_sec_enable(); + } + } // pclog("PIIX write %02X %02X\n", addr, val); } else @@ -367,7 +367,7 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) card_piix_ide[0x00] = 0x86; card_piix_ide[0x01] = 0x80; /*Intel*/ card_piix_ide[0x02] = 0x30; card_piix_ide[0x03] = 0x12; /*82371FB (PIIX)*/ - card_piix_ide[0x04] = 0x00; card_piix_ide[0x05] = 0x00; + card_piix_ide[0x04] = 0x02; card_piix_ide[0x05] = 0x00; card_piix_ide[0x06] = 0x80; card_piix_ide[0x07] = 0x02; card_piix_ide[0x08] = 0x00; card_piix_ide[0x09] = 0x80; card_piix_ide[0x0a] = 0x01; card_piix_ide[0x0b] = 0x01; @@ -383,4 +383,7 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) pci_set_card_routing(pci_b, PCI_INTB); pci_set_card_routing(pci_c, PCI_INTC); pci_set_card_routing(pci_d, PCI_INTD); + + ide_pri_disable(); + ide_sec_disable(); } From f62652da3b12b92a63d5f18a984a9c8302bf921f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Feb 2018 21:39:05 +0000 Subject: [PATCH 0334/1050] Implement PC87306 SuperIO on Advanced/EV. --- nvr/default/endeavor.nvr | Bin 128 -> 128 bytes src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/model.c | 3 +- src/pc87306.c | 205 +++++++++++++++++++++++++++++ src/pc87306.h | 1 + 13 files changed, 217 insertions(+), 10 deletions(-) create mode 100644 src/pc87306.c create mode 100644 src/pc87306.h diff --git a/nvr/default/endeavor.nvr b/nvr/default/endeavor.nvr index f9910df0d41c17c62bb1574f510344b58b5430f9..ade1a43acf993b887bffcd282a2015fa0da6eba6 100644 GIT binary patch delta 70 zcmZo*Y+$qq{V(=k@jr_slY|;m!G8t@hnWHl{0&SDG7Jj;|NrN(WIzEdUl?R0TM8Kd P|DWh6KQVxFVuAtyo9z;j delta 70 zcmZo*Y+$qq|Ihkg;y=42o46WN!G8t@hlv6V{0&SDHVg{?|NrN(WIzF|JPbApEgu;E P|DWh6KQVxFVuAtylf)8N diff --git a/src/Makefile.am b/src/Makefile.am index e6fbd4a..25cc85e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,7 @@ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c paths.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ +opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index a7a9e02..014e1a8 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ +opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index a570355..9ba1d36 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -10,7 +10,7 @@ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ +opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 5233ddc..8e4d53d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 2cbced2..7f3b3f1 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -9,7 +9,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 9ab5e4d..f62d9ea 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -11,7 +11,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 99f7bbc..722061f 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -11,7 +11,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 60e7828..e5514eb 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ + mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 07ecbac..ed36927 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -9,7 +9,7 @@ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ +opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ diff --git a/src/model.c b/src/model.c index c88f75a..b90c4cb 100644 --- a/src/model.c +++ b/src/model.c @@ -38,6 +38,7 @@ #include "nvr.h" #include "olivetti_m24.h" #include "opti495.h" +#include "pc87306.h" #include "pci.h" #include "pic.h" #include "piix.h" @@ -544,7 +545,7 @@ void at_endeavor_init() pci_slot(0x10); i430fx_init(); piix_init(7, 0xd, 0xe, 0xf, 0x10); - um8669f_init(); + pc87306_init(0x2e); intel_endeavor_init(); device_add(&intel_flash_bxt_ami_device); } diff --git a/src/pc87306.c b/src/pc87306.c new file mode 100644 index 0000000..dc96d9b --- /dev/null +++ b/src/pc87306.c @@ -0,0 +1,205 @@ +#include "ibm.h" +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" + +#include "pc87306.h" + +typedef struct pc87306_t +{ + int first_read; + int cur_addr; + + uint8_t regs[32]; + + uint8_t gpio_1, gpio_2; +} pc87306_t; + +static pc87306_t pc87306_global; + +#define REG_FER 0x00 +#define REG_FAR 0x01 +#define REG_GPBA 0x0f +#define REG_SCF0 0x12 +#define REG_PNP0 0x1b + +#define FER_LPT_ENA (1 << 0) +#define FER_COM1_ENA (1 << 1) +#define FER_COM2_ENA (1 << 2) +#define FER_FDC_ENA (1 << 3) + +static uint16_t get_com_addr(pc87306_t *pc87306, int reg) +{ + switch (reg) + { + case 0: + return 0x3f8; + case 1: + return 0x2f8; + case 2: + switch (pc87306->regs[REG_FAR] >> 6) + { + case 0: + return 0x3e8; + case 1: + return 0x338; + case 2: + return 0x2e8; + case 3: + return 0x220; + } + break; + case 3: + switch (pc87306->regs[REG_FAR] >> 6) + { + case 0: + return 0x2e8; + case 1: + return 0x238; + case 2: + return 0x2e0; + case 3: + return 0x228; + } + break; + } + fatal("get_com_addr invalid\n"); + return 0xff; +} + +static uint8_t pc87306_gpio_read(uint16_t port, void *p) +{ + pc87306_t *pc87306 = (pc87306_t *)p; + uint8_t temp; + + if (!(port & 1)) + temp = pc87306->gpio_1; + else + temp = pc87306->gpio_2; + +// pclog("Read GPIO %04x %02x\n", port, temp); + return temp; +} + +static void pc87306_gpio_write(uint16_t port, uint8_t val, void *p) +{ + pc87306_t *pc87306 = (pc87306_t *)p; + +// pclog("Write GPIO %04x %02x\n", port, val); + if (!(port & 1)) + pc87306->gpio_1 = val; +} + +static uint8_t pc87306_read(uint16_t port, void *p) +{ + pc87306_t *pc87306 = (pc87306_t *)p; + + if (!(port & 1)) + { + if (pc87306->first_read) + { + pc87306->first_read = 0; + return 0x88; /*ID*/ + } + return pc87306->cur_addr; + } + else + { + pc87306->regs[8] = 0x70; +// pclog("PC87306 read %02x %02x %04x:%04x\n", pc87306->cur_addr, pc87306->regs[pc87306->cur_addr], CS,cpu_state.pc); +// if (pc87306->cur_addr == 0) +// output = 3; + return pc87306->regs[pc87306->cur_addr]; + } +} + +static void pc87306_write(uint16_t port, uint8_t val, void *p) +{ + pc87306_t *pc87306 = (pc87306_t *)p; +//pclog("pc87306_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + if (!(port & 1)) + pc87306->cur_addr = val & 0x1f; + else + { + uint16_t old_gpio_addr = pc87306_global.regs[REG_GPBA] << 2; + + pc87306->regs[pc87306->cur_addr] = val; + +// pclog("PC87306 write %02x %02x\n", pc87306->cur_addr, val); + + fdc_remove(); + if (pc87306->regs[REG_FER] & FER_FDC_ENA) + fdc_add(); + serial1_remove(); + if (pc87306->regs[REG_FER] & FER_COM1_ENA) + { + uint16_t addr = get_com_addr(pc87306, (pc87306->regs[REG_FAR] >> 2) & 3); + + switch ((pc87306->regs[REG_FAR] >> 2) & 3) + { + case 0: case 2: + serial1_set(addr, 4); + break; + case 1: case 3: + serial1_set(addr, 3); + break; + } + } + serial2_remove(); + if (pc87306->regs[REG_FER] & FER_COM2_ENA) + { + uint16_t addr = get_com_addr(pc87306, (pc87306->regs[REG_FAR] >> 4) & 3); + + switch ((pc87306->regs[REG_FAR] >> 4) & 3) + { + case 0: case 2: + serial2_set(addr, 4); + break; + case 1: case 3: + serial2_set(addr, 3); + break; + } + } + lpt1_remove(); + lpt2_remove(); + if (pc87306->regs[REG_FER] & FER_LPT_ENA) + { + int reg; + + reg = pc87306->regs[REG_FAR] & 3; + reg |= (pc87306->regs[REG_PNP0] & 0x30) >> 2; + + switch (reg) + { + case 0x0: case 0x8: + case 0x4: case 0x5: case 0x6: case 0x7: + lpt1_init(0x378); + break; + case 0x1: case 0x9: + lpt1_init(0x3bc); + break; + case 0x2: case 0xa: + case 0xc: case 0xd: case 0xe: case 0xf: + lpt1_init(0x278); + break; + } + } + io_removehandler(old_gpio_addr, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); + io_sethandler(pc87306_global.regs[REG_GPBA] << 2, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); + } +} + +void pc87306_init(uint16_t port) +{ + memset(&pc87306_global, 0, sizeof(pc87306_t)); + + pc87306_global.first_read = 1; + io_sethandler(port, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, &pc87306_global); + pc87306_global.regs[REG_FER] = 0; + pc87306_global.regs[REG_FAR] = 0x10; + pc87306_global.regs[REG_GPBA] = 0x78 >> 2; + pc87306_global.regs[REG_SCF0] = 0x30; + pc87306_global.gpio_2 = 0xfa; + io_sethandler(0x0078, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); +} diff --git a/src/pc87306.h b/src/pc87306.h new file mode 100644 index 0000000..17fdc59 --- /dev/null +++ b/src/pc87306.h @@ -0,0 +1 @@ +void pc87306_init(uint16_t addr); From ce5ae22307acd59b3dac352ce23cd43e71112c41 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Feb 2018 22:09:56 +0000 Subject: [PATCH 0335/1050] Add Packard Bell PB570 emulation. --- nvr/default/pb570.nvr | Bin 0 -> 128 bytes src/ibm.h | 1 + src/intel_flash.c | 3 +++ src/mem.c | 17 +++++++++++++++++ src/model.c | 1 + src/nvr.c | 5 ++++- src/vid_cl5429.c | 23 ++++++++++++++++++++++- src/vid_cl5429.h | 1 + src/video.c | 10 +++++++++- 9 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 nvr/default/pb570.nvr diff --git a/nvr/default/pb570.nvr b/nvr/default/pb570.nvr new file mode 100644 index 0000000000000000000000000000000000000000..cc21f81f9ea1a85f24f1c3d9261d64bd49701d49 GIT binary patch literal 128 zcma$2@AO~sKZ_)j1RGPqe+CAJnF0)a4NMF&3@ZQs|L3q|Kmjb@8Dtb13K;$aRT2l< Y6d0Ho7{O|V7#IYgnw)?%$Y@440PKMf5dZ)H literal 0 HcmV?d00001 diff --git a/src/ibm.h b/src/ibm.h index a3a5a5f..53d2338 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -452,6 +452,7 @@ enum ROM_TO16_PC, ROM_COMPAQ_PII, ROM_ELX_PC425X, + ROM_PB570, ROM_MAX }; diff --git a/src/intel_flash.c b/src/intel_flash.c index 9846b93..2aa6a45 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -167,6 +167,9 @@ void *intel_flash_init(uint8_t type) case ROM_ENDEAVOR: strcpy(flash_path, "endeavor/"); break; + case ROM_PB570: + strcpy(flash_path, "pb570/"); + break; case ROM_430VX: strcpy(flash_path, "430vx/"); break; diff --git a/src/mem.c b/src/mem.c index b38248e..0c39836 100644 --- a/src/mem.c +++ b/src/mem.c @@ -844,6 +844,23 @@ int loadbios() romfread(rom, 65536, 1, f); fclose(f); return 1; + + case ROM_PB570: + if (!rom_present("gd5430/pci.bin")) + break; + f = romfopen("pb570/1007by0r.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("pb570/1007by0r.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + romfread(rom+0xc000, 0x1000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index b90c4cb..4cdc03f 100644 --- a/src/model.c +++ b/src/model.c @@ -171,6 +171,7 @@ MODEL models[] = {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index dc92b11..e462f11 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -298,7 +298,8 @@ void loadnvr() t1000_emsboard_loadnvr(); return; case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); nvrmask = 127; break; - + case ROM_PB570: f = nvrfopen("pb570.nvr", "rb"); nvrmask = 127; break; + default: return; } if (!f) @@ -381,6 +382,8 @@ void savenvr() t1000_emsboard_savenvr(); return; case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); break; + case ROM_PB570: f = nvrfopen("pb570.nvr", "wb"); break; + default: return; } fwrite(nvrram,128,1,f); diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 71e0974..edb943c 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1469,11 +1469,19 @@ static void *gd5430_init() { return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin"); } +static void *gd5430_pb570_init() +{ + return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin"); +} static int gd5429_available() { return rom_present("5429.vbi"); } +static int gd5430_available() +{ + return rom_present("gd5430/pci.bin"); +} void gd5429_close(void *p) { @@ -1551,7 +1559,20 @@ device_t gd5430_device = 0, gd5430_init, gd5429_close, - gd5429_available, + gd5430_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config +}; + +device_t gd5430_pb570_device = +{ + "Cirrus Logic GD5430 (PB570)", + 0, + gd5430_pb570_init, + gd5429_close, + gd5430_available, gd5429_speed_changed, gd5429_force_redraw, gd5429_add_status_info, diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index 9537552..b6d2abf 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1,2 +1,3 @@ extern device_t gd5429_device; extern device_t gd5430_device; +extern device_t gd5430_pb570_device; diff --git a/src/video.c b/src/video.c index c75ca33..98f042f 100644 --- a/src/video.c +++ b/src/video.c @@ -112,6 +112,7 @@ static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_pc425x = {VIDEO_BUS, 5, 5, 9, 20,20,30}; +static video_timings_t timing_pb570 = {VIDEO_BUS, 4, 4, 8, 10,10,20}; int video_card_available(int card) { @@ -318,7 +319,10 @@ void video_updatetiming() case ROM_ELX_PC425X: timing = &timing_pc425x; - pclog("PC425 timing\n"); + break; + + case ROM_PB570: + timing = &timing_pb570; break; default: @@ -458,6 +462,10 @@ void video_init() case ROM_ELX_PC425X: device_add(&tgui9400cxi_elx_device); return; + + case ROM_PB570: + device_add(&gd5430_pb570_device); + return; } device_add(video_cards[video_old_to_new(gfxcard)].device); } From 84a0f0bacb61eb35835bc475e493a3615903d5c2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Feb 2018 10:34:46 +0000 Subject: [PATCH 0336/1050] Added Intel Advanced/ZP emulation. Patch from EluanCM. --- src/ibm.h | 1 + src/intel.c | 16 ++++++++++++++++ src/intel.h | 1 + src/intel_flash.c | 3 +++ src/mem.c | 14 ++++++++++++++ src/model.c | 16 ++++++++++++++++ src/nvr.c | 4 +++- 7 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/ibm.h b/src/ibm.h index 53d2338..71d4265 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -453,6 +453,7 @@ enum ROM_COMPAQ_PII, ROM_ELX_PC425X, ROM_PB570, + ROM_ZAPPA, ROM_MAX }; diff --git a/src/intel.c b/src/intel.c index a7194f3..21e91b1 100644 --- a/src/intel.c +++ b/src/intel.c @@ -106,3 +106,19 @@ void intel_endeavor_init() { io_sethandler(0x0079, 0x0001, endeavor_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); } + +static uint8_t zappa_brdconfig(uint16_t port, void *p) +{ +// pclog("zappa_brdconfig read port=%04x\n", port); + switch (port) + { + case 0x79: + return 0xff; + } + return 0; +} + +void intel_zappa_init() +{ + io_sethandler(0x0079, 0x0001, zappa_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); +} diff --git a/src/intel.h b/src/intel.h index eccd668..4e14ddc 100644 --- a/src/intel.h +++ b/src/intel.h @@ -1,2 +1,3 @@ void intel_batman_init(); void intel_endeavor_init(); +void intel_zappa_init(); diff --git a/src/intel_flash.c b/src/intel_flash.c index 2aa6a45..bf169a4 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -170,6 +170,9 @@ void *intel_flash_init(uint8_t type) case ROM_PB570: strcpy(flash_path, "pb570/"); break; + case ROM_ZAPPA: + strcpy(flash_path, "zappa/"); + break; case ROM_430VX: strcpy(flash_path, "430vx/"); break; diff --git a/src/mem.c b/src/mem.c index 0c39836..d7cb896 100644 --- a/src/mem.c +++ b/src/mem.c @@ -861,6 +861,20 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_ZAPPA: + f = romfopen("zappa/1006bs0_.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + fread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("zappa/1006bs0_.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + fread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 4cdc03f..030b554 100644 --- a/src/model.c +++ b/src/model.c @@ -98,6 +98,7 @@ void at_t3100e_init(); void xt_t1000_init(); void xt_t1200_init(); void at_sl82c460_init(); +void at_zappa_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -171,6 +172,7 @@ MODEL models[] = {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, @@ -550,6 +552,20 @@ void at_endeavor_init() intel_endeavor_init(); device_add(&intel_flash_bxt_ami_device); } +void at_zappa_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); + i430fx_init(); + piix_init(7, 0xd, 0xe, 0xf, 0x10); + pc87306_init(0x2e); + intel_zappa_init(); + device_add(&intel_flash_bxt_ami_device); +} void at_i430vx_init() { diff --git a/src/nvr.c b/src/nvr.c index e462f11..02096e7 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -299,7 +299,8 @@ void loadnvr() return; case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); nvrmask = 127; break; case ROM_PB570: f = nvrfopen("pb570.nvr", "rb"); nvrmask = 127; break; - + case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "rb"); nvrmask = 127; break; + default: return; } if (!f) @@ -383,6 +384,7 @@ void savenvr() return; case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); break; case ROM_PB570: f = nvrfopen("pb570.nvr", "wb"); break; + case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "wb"); break; default: return; } From 2c985a6c79ab9ee410e82eccabb92cefef1f79c3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Feb 2018 14:49:29 +0000 Subject: [PATCH 0337/1050] Added CL-GD5434 emulation. --- src/ibm.h | 3 +- src/vid_cl5429.c | 264 +++++++++++++++++++++++++++++++++++++++-------- src/vid_cl5429.h | 1 + src/video.c | 1 + 4 files changed, 224 insertions(+), 45 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 71d4265..ba2d856 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -491,8 +491,9 @@ enum GFX_GENIUS, /* MDSI Genius */ GFX_MACH64VT2, /*ATI Mach64 VT2*/ GFX_OLIVETTI_GO481, /*Olivetti GO481 PVGA1A*/ - GFX_TGUI9400CXI, + GFX_TGUI9400CXI, /*Trident TGUI9440CXi*/ GFX_CL_GD5430, /*Cirrus Logic CL-GD5430*/ + GFX_CL_GD5434, /*Cirrus Logic CL-GD5434*/ GFX_MAX }; diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index edb943c..19d7829 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -15,9 +15,13 @@ enum { CL_TYPE_GD5429 = 0, - CL_TYPE_GD5430 + CL_TYPE_GD5430, + CL_TYPE_GD5434 }; +#define BLIT_DEPTH_8 0 +#define BLIT_DEPTH_16 1 +#define BLIT_DEPTH_32 3 typedef struct gd5429_t { mem_mapping_t mmio_mapping; @@ -36,7 +40,7 @@ typedef struct gd5429_t struct { - uint16_t bg_col, fg_col; + uint32_t bg_col, fg_col; uint16_t width, height; uint16_t dst_pitch, src_pitch; uint32_t dst_addr, src_addr; @@ -45,6 +49,7 @@ typedef struct gd5429_t uint32_t dst_addr_backup, src_addr_backup; uint16_t width_backup, height_internal; int x_count, y_count; + int depth; } blt; uint8_t hidden_dac_reg; @@ -105,7 +110,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) // pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); break; case 0x13: - svga->hwcursor.addr = (0x1fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; + svga->hwcursor.addr = (0x3fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; // pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; @@ -178,6 +183,18 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x11: gd5429_mmio_write(0x05, val, gd5429); break; + case 0x12: + gd5429_mmio_write(0x02, val, gd5429); + break; + case 0x13: + gd5429_mmio_write(0x06, val, gd5429); + break; + case 0x14: + gd5429_mmio_write(0x03, val, gd5429); + break; + case 0x15: + gd5429_mmio_write(0x07, val, gd5429); + break; case 0x20: gd5429_mmio_write(0x08, val, gd5429); @@ -320,6 +337,8 @@ uint8_t gd5429_in(uint16_t addr, void *p) return 0x9c; /*GD5429*/ case CL_TYPE_GD5430: return 0xa0; /*GD5430*/ + case CL_TYPE_GD5434: + return 0xa8; /*GD5434*/ } break; case 0x28: /*Class ID*/ @@ -337,14 +356,14 @@ void gd5429_recalc_banking(gd5429_t *gd5429) svga_t *svga = &gd5429->svga; if (svga->gdcreg[0xb] & 0x20) - gd5429->bank[0] = (svga->gdcreg[0x09] & 0x7f) << 14; + gd5429->bank[0] = (svga->gdcreg[0x09] & 0xff) << 14; else gd5429->bank[0] = svga->gdcreg[0x09] << 12; if (svga->gdcreg[0xb] & 0x01) { if (svga->gdcreg[0xb] & 0x20) - gd5429->bank[1] = (svga->gdcreg[0x0a] & 0x7f) << 14; + gd5429->bank[1] = (svga->gdcreg[0x0a] & 0xff) << 14; else gd5429->bank[1] = svga->gdcreg[0x0a] << 12; } @@ -415,7 +434,6 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) base = 128*1024*1024; size = 4 * 1024 * 1024; } - mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd5429->linear_mapping, base, size); if (svga->seqregs[0x17] & 0x04) @@ -431,7 +449,10 @@ void gd5429_recalctimings(svga_t *svga) int clock = (svga->miscout >> 2) & 3; int n, d, p; double vclk; - + + if (svga->crtc[0x1b] & 0x10) + svga->rowoffset |= 0x100; + if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -461,13 +482,25 @@ void gd5429_recalctimings(svga_t *svga) svga->bpp = 16; break; case 0x5: - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; + if (gd5429->type >= CL_TYPE_GD5434 && (svga->seqregs[7] & 8)) + { + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + svga->rowoffset *= 2; + } + else + { + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + } break; } } else + { svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + } } n = svga->seqregs[0xb + clock] & 0x7f; @@ -475,7 +508,7 @@ void gd5429_recalctimings(svga_t *svga) p = svga->seqregs[0x1b + clock] & 1; vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p); - switch (svga->seqregs[7] & 6) + switch (svga->seqregs[7] & ((gd5429->type >= CL_TYPE_GD5434) ? 0xe : 0x6)) { case 2: vclk /= 2.0; @@ -980,9 +1013,22 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; int blt_mask = gd5429->blt.mask & 7; + int x_max = 0; - if (gd5429->blt.mode & 0x10) + switch (gd5429->blt.depth) + { + case BLIT_DEPTH_8: + x_max = 8; + break; + case BLIT_DEPTH_16: + x_max = 16; blt_mask *= 2; + break; + case BLIT_DEPTH_32: + x_max = 32; + blt_mask *= 4; + break; + } // pclog("gd5429_start_blit %i\n", count); if (count == -1) @@ -1036,20 +1082,44 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { uint8_t src = 0, dst; int mask = 0; + int shift; + + if (gd5429->blt.depth == BLIT_DEPTH_32) + shift = (gd5429->blt.x_count & 3) * 8; + else if (gd5429->blt.depth == BLIT_DEPTH_8) + shift = 0; + else + shift = (gd5429->blt.x_count & 1) * 8; if (gd5429->blt.mode & 0x04) { if (gd5429->blt.mode & 0x80) - { - if ((gd5429->blt.mode & 0x10) && (gd5429->blt.x_count & 1)) - src = (cpu_dat & 0x80) ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); - else - src = (cpu_dat & 0x80) ? gd5429->blt.fg_col : gd5429->blt.bg_col; + { mask = cpu_dat & 0x80; - if (!(gd5429->blt.mode & 0x10) || (gd5429->blt.x_count & 1)) + + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; cpu_dat <<= 1; count--; + break; + case BLIT_DEPTH_16: + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + if (gd5429->blt.x_count & 1) + { + cpu_dat <<= 1; + count--; + } + break; + case BLIT_DEPTH_32: + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + if ((gd5429->blt.x_count & 3) == 3) + { + cpu_dat <<= 1; + count--; + } + break; } } else @@ -1070,40 +1140,52 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) mask = 1; break; case 0x40: - if (gd5429->blt.mode & 0x10) - src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 4) + (gd5429->blt.x_count & 15)]; - else + switch (gd5429->blt.depth) + { + case BLIT_DEPTH_8: src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) + (gd5429->blt.y_count << 3) + (gd5429->blt.x_count & 7)]; + break; + case BLIT_DEPTH_16: + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 4) + (gd5429->blt.x_count & 15)]; + break; + case BLIT_DEPTH_32: + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 5) + (gd5429->blt.x_count & 31)]; + break; + } mask = 1; break; case 0x80: - if (gd5429->blt.mode & 0x10) - { - mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); - if (gd5429->blt.dst_addr & 1) - src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); - else - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - } - else + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + break; + case BLIT_DEPTH_16: + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; + case BLIT_DEPTH_32: + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 2)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; } break; case 0xc0: - if (gd5429->blt.mode & 0x10) - { - mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1)); - if (gd5429->blt.dst_addr & 1) - src = mask ? (gd5429->blt.fg_col >> 8) : (gd5429->blt.bg_col >> 8); - else - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - } - else + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> gd5429->blt.x_count); src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + break; + case BLIT_DEPTH_16: + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; + case BLIT_DEPTH_32: + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 2)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; } break; } @@ -1141,7 +1223,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); gd5429->blt.x_count++; - if (gd5429->blt.x_count == ((gd5429->blt.mode & 0x10) ? 16 : 8)) + if (gd5429->blt.x_count == x_max) { gd5429->blt.x_count = 0; if ((gd5429->blt.mode & 0xc0) == 0x80) @@ -1168,7 +1250,7 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) } gd5429->blt.x_count = 0; - if (gd5429->blt.mode & 0x10) + if (gd5429->blt.mode & 0x01) gd5429->blt.y_count = (gd5429->blt.y_count - 1) & 7; else gd5429->blt.y_count = (gd5429->blt.y_count + 1) & 7; @@ -1209,17 +1291,45 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) switch (addr & 0xff) { case 0x00: - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffffff00) | val; + else + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; break; case 0x01: - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffff00ff) | (val << 8); + else + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); + break; + case 0x02: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x03: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ffffff) | (val << 24); break; case 0x04: - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffffff00) | val; + else + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; break; case 0x05: - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffff00ff) | (val << 8); + else + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); + break; + case 0x06: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x07: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ffffff) | (val << 24); break; case 0x08: @@ -1227,12 +1337,17 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x09: gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.width &= 0x1fff; + else + gd5429->blt.width &= 0x07ff; break; case 0x0a: gd5429->blt.height = (gd5429->blt.height & 0xff00) | val; break; case 0x0b: gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); + gd5429->blt.height &= 0x03ff; break; case 0x0c: gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; @@ -1255,6 +1370,10 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x12: gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.dst_addr &= 0x3fffff; + else + gd5429->blt.dst_addr &= 0x1fffff; break; case 0x14: @@ -1265,6 +1384,10 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x16: gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.src_addr &= 0x3fffff; + else + gd5429->blt.src_addr &= 0x1fffff; break; case 0x17: @@ -1272,6 +1395,10 @@ void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) break; case 0x18: gd5429->blt.mode = val; + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.depth = (val >> 4) & 3; + else + gd5429->blt.depth = (val >> 4) & 1; break; case 0x1a: @@ -1335,6 +1462,8 @@ static uint8_t cl_pci_read(int func, int addr, void *p) { case CL_TYPE_GD5430: return 0xa0; + case CL_TYPE_GD5434: + return 0xa8; } return 0xff; case 0x03: return 0x00; @@ -1473,6 +1602,10 @@ static void *gd5430_pb570_init() { return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin"); } +static void *gd5434_init() +{ + return cl_init(CL_TYPE_GD5434, "gd5434.bin"); +} static int gd5429_available() { @@ -1482,6 +1615,10 @@ static int gd5430_available() { return rom_present("gd5430/pci.bin"); } +static int gd5434_available() +{ + return rom_present("gd5434.bin"); +} void gd5429_close(void *p) { @@ -1539,6 +1676,32 @@ static device_config_t gd5429_config[] = .type = -1 } }; +static device_config_t gd5434_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; device_t gd5429_device = { @@ -1578,3 +1741,16 @@ device_t gd5430_pb570_device = gd5429_add_status_info, gd5429_config }; + +device_t gd5434_device = +{ + "Cirrus Logic GD5434", + 0, + gd5434_init, + gd5429_close, + gd5434_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5434_config +}; diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index b6d2abf..6b92f46 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1,3 +1,4 @@ extern device_t gd5429_device; extern device_t gd5430_device; extern device_t gd5430_pb570_device; +extern device_t gd5434_device; diff --git a/src/video.c b/src/video.c index 98f042f..9bef9f5 100644 --- a/src/video.c +++ b/src/video.c @@ -75,6 +75,7 @@ static VIDEO_CARD video_cards[] = {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From cc60e2b2c5303d599e4aea260ad90d7b036efdee Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Feb 2018 15:55:46 +0000 Subject: [PATCH 0338/1050] Added Packard Bell PB520r emulation. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/cmd640.c | 71 ++++++++++++++++++++++++++++++ src/cmd640.h | 1 + src/ibm.h | 1 + src/intel_flash.c | 3 ++ src/mem.c | 15 +++++++ src/model.c | 16 +++++++ src/nvr.c | 4 +- src/vid_cl5429.c | 17 +++++++ src/vid_cl5429.h | 1 + src/video.c | 9 ++++ 19 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 src/cmd640.c create mode 100644 src/cmd640.h diff --git a/src/Makefile.am b/src/Makefile.am index 25cc85e..c833a9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 014e1a8..651e680 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ -codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ +cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 9ba1d36..0c4fd5d 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -5,7 +5,7 @@ WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ -codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ +cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 8e4d53d..4448a70 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -4,7 +4,7 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ + cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 7f3b3f1..8a3c8df 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -5,7 +5,7 @@ MAKE = make.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -DUSE_NETWORKING OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ + cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index f62d9ea..b9ee97a 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -7,7 +7,7 @@ WXINCLUDE = C:/MinGW/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ + cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 722061f..0a3fd57 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -7,7 +7,7 @@ WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ + cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index e5514eb..f164a5c 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -4,7 +4,7 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ + cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index ed36927..4e2f4f3 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ -codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ +cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ diff --git a/src/cmd640.c b/src/cmd640.c new file mode 100644 index 0000000..1e8b8f9 --- /dev/null +++ b/src/cmd640.c @@ -0,0 +1,71 @@ +/*CMD640 emulation + Currently only legacy mode emulated*/ +#include "ibm.h" +#include "cmd640.h" +#include "ide.h" +#include "pci.h" + +static uint8_t card_cmd640[256]; + +void cmd640_write(int func, int addr, uint8_t val, void *priv) +{ +// pclog("cmd640_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); + if (func > 0) + return; + + switch (addr) + { + case 0x04: + ide_pri_disable(); + ide_sec_disable(); + if (val & 0x01) + { + ide_pri_enable(); + ide_sec_enable(); + } + card_cmd640[0x04] = val & 0x41; + break; + case 0x07: + card_cmd640[0x07] = val & 0x86; + break; + case 0x3c: + card_cmd640[0x3c] = val; + break; + } +} + +static uint8_t cmd640_read(int func, int addr, void *p) +{ +// pclog("cmd640_read: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, card_cmd640[addr], CS, cpu_state.pc); + if (func > 0) + return 0xff; + + return card_cmd640[addr]; +} + +void cmd640b_init(int card) +{ + pci_add_specific(card, cmd640_read, cmd640_write, NULL); + + memset(card_cmd640, 0, 256); + card_cmd640[0x00] = 0x95; card_cmd640[0x01] = 0x10; /**/ + card_cmd640[0x02] = 0x40; card_cmd640[0x03] = 0x06; /*CMD640*/ + card_cmd640[0x04] = 0x01; card_cmd640[0x05] = 0x00; + card_cmd640[0x06] = 0x00; card_cmd640[0x07] = 0x02; + card_cmd640[0x08] = 0x00; /*Revision*/ + card_cmd640[0x09] = 0x00; /*Programming interface*/ + card_cmd640[0x0a] = 0x01; /*Sub class - IDE controller*/ + card_cmd640[0x0b] = 0x01; /*Base class - Mass storage controller*/ + + + card_cmd640[0x3c] = 0x0e; /*Interrupt line*/ + card_cmd640[0x3d] = 1; + + card_cmd640[0x50] = 0x02; /*Revision = 2*/ + card_cmd640[0x51] = 0x80; /*2nd port disabled, drive 1 read ahead disabled*/ + card_cmd640[0x57] = 0x0c; /*Drive 2/3 read ahead disabled*/ + card_cmd640[0x59] = 0x40; /*Burst length*/ + + ide_pri_disable(); + ide_sec_disable(); +} diff --git a/src/cmd640.h b/src/cmd640.h new file mode 100644 index 0000000..5371669 --- /dev/null +++ b/src/cmd640.h @@ -0,0 +1 @@ +void cmd640b_init(int card); diff --git a/src/ibm.h b/src/ibm.h index ba2d856..d094b6a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -454,6 +454,7 @@ enum ROM_ELX_PC425X, ROM_PB570, ROM_ZAPPA, + ROM_PB520R, ROM_MAX }; diff --git a/src/intel_flash.c b/src/intel_flash.c index bf169a4..f2de0bb 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -164,6 +164,9 @@ void *intel_flash_init(uint8_t type) case ROM_REVENGE: strcpy(flash_path, "revenge/"); break; + case ROM_PB520R: + strcpy(flash_path, "pb520r/"); + break; case ROM_ENDEAVOR: strcpy(flash_path, "endeavor/"); break; diff --git a/src/mem.c b/src/mem.c index d7cb896..c9a9eb2 100644 --- a/src/mem.c +++ b/src/mem.c @@ -875,6 +875,21 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_PB520R: + f = romfopen("pb520r/1009bc0r.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("pb520r/1009bc0r.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + romfread(rom+0xc000, 0x1000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 030b554..27c37f7 100644 --- a/src/model.c +++ b/src/model.c @@ -9,6 +9,7 @@ #include "ali1429.h" #include "amstrad.h" #include "cbm_io.h" +#include "cmd640.h" #include "compaq.h" #include "dells200.h" #include "device.h" @@ -99,6 +100,7 @@ void xt_t1000_init(); void xt_t1200_init(); void at_sl82c460_init(); void at_zappa_init(); +void at_pb520r_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -170,6 +172,7 @@ MODEL models[] = {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 1, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, + {"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL}, {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, @@ -538,6 +541,19 @@ void at_batman_init() intel_batman_init(); device_add(&intel_flash_bxt_ami_device); } +void at_pb520r_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + i430lx_init(); + sio_init(2, 0xc, 0xe, 0x6, 0); + cmd640b_init(1); + intel_batman_init(); + device_add(&intel_flash_bxt_ami_device); +} void at_endeavor_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 02096e7..59272be 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -300,7 +300,8 @@ void loadnvr() case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); nvrmask = 127; break; case ROM_PB570: f = nvrfopen("pb570.nvr", "rb"); nvrmask = 127; break; case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "rb"); nvrmask = 127; break; - + case ROM_PB520R: f = nvrfopen("pb520r.nvr", "rb"); nvrmask = 127; break; + default: return; } if (!f) @@ -385,6 +386,7 @@ void savenvr() case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); break; case ROM_PB570: f = nvrfopen("pb570.nvr", "wb"); break; case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "wb"); break; + case ROM_PB520R: f = nvrfopen("pb520r.nvr", "wb"); break; default: return; } diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 19d7829..4f04a1e 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1606,6 +1606,10 @@ static void *gd5434_init() { return cl_init(CL_TYPE_GD5434, "gd5434.bin"); } +static void *gd5434_pb520r_init() +{ + return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin"); +} static int gd5429_available() { @@ -1754,3 +1758,16 @@ device_t gd5434_device = gd5429_add_status_info, gd5434_config }; + +device_t gd5434_pb520r_device = +{ + "Cirrus Logic GD5434 (PB520r)", + 0, + gd5434_pb520r_init, + gd5429_close, + gd5434_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5434_config +}; diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index 6b92f46..a045e6e 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -2,3 +2,4 @@ extern device_t gd5429_device; extern device_t gd5430_device; extern device_t gd5430_pb570_device; extern device_t gd5434_device; +extern device_t gd5434_pb520r_device; diff --git a/src/video.c b/src/video.c index 9bef9f5..29cbafc 100644 --- a/src/video.c +++ b/src/video.c @@ -114,6 +114,7 @@ static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_pc425x = {VIDEO_BUS, 5, 5, 9, 20,20,30}; static video_timings_t timing_pb570 = {VIDEO_BUS, 4, 4, 8, 10,10,20}; +static video_timings_t timing_pb520r = {VIDEO_BUS, 4, 4, 8, 10,10,20}; int video_card_available(int card) { @@ -325,6 +326,10 @@ void video_updatetiming() case ROM_PB570: timing = &timing_pb570; break; + + case ROM_PB520R: + timing = &timing_pb520r; + break; default: new_gfxcard = video_old_to_new(gfxcard); @@ -467,6 +472,10 @@ void video_init() case ROM_PB570: device_add(&gd5430_pb570_device); return; + + case ROM_PB520R: + device_add(&gd5434_pb520r_device); + return; } device_add(video_cards[video_old_to_new(gfxcard)].device); } From e349e4b14e8bf60bffef32d3d92cbefd41130c76 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Feb 2018 22:04:54 +0000 Subject: [PATCH 0339/1050] Fixed Cirrus Logic MMIO mapping. Fixes hang when opening Windows 9x DOS box. --- src/vid_cl5429.c | 327 ++++++++++++++++++++++++++++------------------- 1 file changed, 195 insertions(+), 132 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 4f04a1e..19983cb 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -60,10 +60,16 @@ typedef struct gd5429_t int card; uint32_t lfb_base; + + int mmio_vram_overlap; } gd5429_t; -void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); -uint8_t gd5429_mmio_read(uint32_t addr, void *p); +static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); +static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p); +static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p); +static uint8_t gd5429_mmio_read(uint32_t addr, void *p); +static uint16_t gd5429_mmio_readw(uint32_t addr, void *p); +static uint32_t gd5429_mmio_readl(uint32_t addr, void *p); void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p); void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p); @@ -383,6 +389,8 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) return; } + gd5429->mmio_vram_overlap = 0; + // pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); if (!(svga->seqregs[7] & 0xf0)) { @@ -390,27 +398,27 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&gd5429->mmio_mapping); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - if (svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&gd5429->mmio_mapping); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&gd5429->mmio_mapping); svga->banked_mask = 0x7fff; + gd5429->mmio_vram_overlap = 1; break; } + if (svga->seqregs[0x17] & 0x04) + mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); + else + mem_mapping_disable(&gd5429->mmio_mapping); } else { @@ -1283,146 +1291,201 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) } } -void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) +static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; -// pclog("MMIO write %08X %02X\n", addr, val); - switch (addr & 0xff) + if ((addr & ~0xff) == 0xb8000) { - case 0x00: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffffff00) | val; - else - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; - break; - case 0x01: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffff00ff) | (val << 8); - else - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); - break; - case 0x02: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x03: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ffffff) | (val << 24); - break; + // pclog("MMIO write %08X %02X\n", addr, val); + switch (addr & 0xff) + { + case 0x00: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffffff00) | val; + else + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; + break; + case 0x01: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffff00ff) | (val << 8); + else + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); + break; + case 0x02: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x03: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ffffff) | (val << 24); + break; - case 0x04: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffffff00) | val; - else - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; - break; - case 0x05: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffff00ff) | (val << 8); - else - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); - break; - case 0x06: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x07: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ffffff) | (val << 24); - break; + case 0x04: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffffff00) | val; + else + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; + break; + case 0x05: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffff00ff) | (val << 8); + else + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); + break; + case 0x06: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x07: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ffffff) | (val << 24); + break; - case 0x08: - gd5429->blt.width = (gd5429->blt.width & 0xff00) | val; - break; - case 0x09: - gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8); - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.width &= 0x1fff; - else - gd5429->blt.width &= 0x07ff; - break; - case 0x0a: - gd5429->blt.height = (gd5429->blt.height & 0xff00) | val; - break; - case 0x0b: - gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); - gd5429->blt.height &= 0x03ff; - break; - case 0x0c: - gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; - break; - case 0x0d: - gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0x00ff) | (val << 8); - break; - case 0x0e: - gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0xff00) | val; - break; - case 0x0f: - gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0x00ff) | (val << 8); - break; + case 0x08: + gd5429->blt.width = (gd5429->blt.width & 0xff00) | val; + break; + case 0x09: + gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.width &= 0x1fff; + else + gd5429->blt.width &= 0x07ff; + break; + case 0x0a: + gd5429->blt.height = (gd5429->blt.height & 0xff00) | val; + break; + case 0x0b: + gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); + gd5429->blt.height &= 0x03ff; + break; + case 0x0c: + gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; + break; + case 0x0d: + gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0x00ff) | (val << 8); + break; + case 0x0e: + gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0xff00) | val; + break; + case 0x0f: + gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0x00ff) | (val << 8); + break; - case 0x10: - gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xffff00) | val; - break; - case 0x11: - gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x12: - gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16); - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.dst_addr &= 0x3fffff; - else - gd5429->blt.dst_addr &= 0x1fffff; - break; + case 0x10: + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xffff00) | val; + break; + case 0x11: + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xff00ff) | (val << 8); + break; + case 0x12: + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.dst_addr &= 0x3fffff; + else + gd5429->blt.dst_addr &= 0x1fffff; + break; - case 0x14: - gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xffff00) | val; - break; - case 0x15: - gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x16: - gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16); - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.src_addr &= 0x3fffff; - else - gd5429->blt.src_addr &= 0x1fffff; - break; + case 0x14: + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xffff00) | val; + break; + case 0x15: + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xff00ff) | (val << 8); + break; + case 0x16: + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.src_addr &= 0x3fffff; + else + gd5429->blt.src_addr &= 0x1fffff; + break; - case 0x17: - gd5429->blt.mask = val; - break; - case 0x18: - gd5429->blt.mode = val; - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.depth = (val >> 4) & 3; - else - gd5429->blt.depth = (val >> 4) & 1; - break; + case 0x17: + gd5429->blt.mask = val; + break; + case 0x18: + gd5429->blt.mode = val; + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.depth = (val >> 4) & 3; + else + gd5429->blt.depth = (val >> 4) & 1; + break; - case 0x1a: - gd5429->blt.rop = val; - break; + case 0x1a: + gd5429->blt.rop = val; + break; - case 0x40: - if (val & 0x02) - gd5429_start_blit(0, -1, gd5429); - break; + case 0x40: + if (val & 0x02) + gd5429_start_blit(0, -1, gd5429); + break; + } } + else if (gd5429->mmio_vram_overlap) + gd5429_write(addr, val, gd5429); +} +static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + + if ((addr & ~0xff) == 0xb8000) + { + gd5429_mmio_write(addr, val & 0xff, gd5429); + gd5429_mmio_write(addr + 1, val >> 8, gd5429); + } + else if (gd5429->mmio_vram_overlap) + gd5429_writew(addr, val, gd5429); +} +static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + + if ((addr & ~0xff) == 0xb8000) + { + gd5429_mmio_writew(addr, val & 0xffff, gd5429); + gd5429_mmio_writew(addr + 2, val >> 16, gd5429); + } + else if (gd5429->mmio_vram_overlap) + gd5429_writel(addr, val, gd5429); } -uint8_t gd5429_mmio_read(uint32_t addr, void *p) +static uint8_t gd5429_mmio_read(uint32_t addr, void *p) { -// gd5429_t *gd5429 = (gd5429_t *)p; - -// pclog("MMIO read %08X\n", addr); - switch (addr & 0xff) + gd5429_t *gd5429 = (gd5429_t *)p; + + if ((addr & ~0xff) == 0xb8000) { - case 0x40: /*BLT status*/ - return 0; +// pclog("MMIO read %08X\n", addr); + switch (addr & 0xff) + { + case 0x40: /*BLT status*/ + return 0; + } + return 0xff; /*All other registers read-only*/ } - return 0xff; /*All other registers read-only*/ + if (gd5429->mmio_vram_overlap) + return gd5429_read(addr, gd5429); + return 0xff; +} +static uint16_t gd5429_mmio_readw(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + + if ((addr & ~0xff) == 0xb8000) + return gd5429_mmio_read(addr, gd5429) | (gd5429_mmio_read(addr+1, gd5429) << 8); + if (gd5429->mmio_vram_overlap) + return gd5429_readw(addr, gd5429); + return 0xffff; +} +static uint32_t gd5429_mmio_readl(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + + if ((addr & ~0xff) == 0xb8000) + return gd5429_mmio_readw(addr, gd5429) | (gd5429_mmio_readw(addr+2, gd5429) << 16); + if (gd5429->mmio_vram_overlap) + return gd5429_readl(addr, gd5429); + return 0xffffffff; } void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) @@ -1555,7 +1618,7 @@ static void *cl_init(int type, char *fn) mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); mem_mapping_set_p(&gd5429->svga.mapping, gd5429); - mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, NULL, NULL, gd5429_mmio_write, NULL, NULL, NULL, 0, gd5429); + mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); mem_mapping_add(&gd5429->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga); io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); From de4a6e5c2e34971dac804cba99aee86b1e80c966 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 22 Feb 2018 21:03:51 +0000 Subject: [PATCH 0340/1050] Fix IO port access to Cirrus Logic blitter. --- src/vid_cl5429.c | 52 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 19983cb..a6dd8b3 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -145,9 +145,9 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x3cf: // pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); if (svga->gdcaddr == 0) - gd5429_mmio_write(0x00, val, gd5429); + gd5429_mmio_write(0xb8000, val, gd5429); if (svga->gdcaddr == 1) - gd5429_mmio_write(0x04, val, gd5429); + gd5429_mmio_write(0xb8004, val, gd5429); if (svga->gdcaddr == 5) { svga->gdcreg[5] = val; @@ -184,82 +184,82 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) break; case 0x10: - gd5429_mmio_write(0x01, val, gd5429); + gd5429_mmio_write(0xb8001, val, gd5429); break; case 0x11: - gd5429_mmio_write(0x05, val, gd5429); + gd5429_mmio_write(0xb8005, val, gd5429); break; case 0x12: - gd5429_mmio_write(0x02, val, gd5429); + gd5429_mmio_write(0xb8002, val, gd5429); break; case 0x13: - gd5429_mmio_write(0x06, val, gd5429); + gd5429_mmio_write(0xb8006, val, gd5429); break; case 0x14: - gd5429_mmio_write(0x03, val, gd5429); + gd5429_mmio_write(0xb8003, val, gd5429); break; case 0x15: - gd5429_mmio_write(0x07, val, gd5429); + gd5429_mmio_write(0xb8007, val, gd5429); break; case 0x20: - gd5429_mmio_write(0x08, val, gd5429); + gd5429_mmio_write(0xb8008, val, gd5429); break; case 0x21: - gd5429_mmio_write(0x09, val, gd5429); + gd5429_mmio_write(0xb8009, val, gd5429); break; case 0x22: - gd5429_mmio_write(0x0a, val, gd5429); + gd5429_mmio_write(0xb800a, val, gd5429); break; case 0x23: - gd5429_mmio_write(0x0b, val, gd5429); + gd5429_mmio_write(0xb800b, val, gd5429); break; case 0x24: - gd5429_mmio_write(0x0c, val, gd5429); + gd5429_mmio_write(0xb800c, val, gd5429); break; case 0x25: - gd5429_mmio_write(0x0d, val, gd5429); + gd5429_mmio_write(0xb800d, val, gd5429); break; case 0x26: - gd5429_mmio_write(0x0e, val, gd5429); + gd5429_mmio_write(0xb800e, val, gd5429); break; case 0x27: - gd5429_mmio_write(0x0f, val, gd5429); + gd5429_mmio_write(0xb800f, val, gd5429); break; case 0x28: - gd5429_mmio_write(0x10, val, gd5429); + gd5429_mmio_write(0xb8010, val, gd5429); break; case 0x29: - gd5429_mmio_write(0x11, val, gd5429); + gd5429_mmio_write(0xb8011, val, gd5429); break; case 0x2a: - gd5429_mmio_write(0x12, val, gd5429); + gd5429_mmio_write(0xb8012, val, gd5429); break; case 0x2c: - gd5429_mmio_write(0x14, val, gd5429); + gd5429_mmio_write(0xb8014, val, gd5429); break; case 0x2d: - gd5429_mmio_write(0x15, val, gd5429); + gd5429_mmio_write(0xb8015, val, gd5429); break; case 0x2e: - gd5429_mmio_write(0x16, val, gd5429); + gd5429_mmio_write(0xb8016, val, gd5429); break; case 0x2f: - gd5429_mmio_write(0x17, val, gd5429); + gd5429_mmio_write(0xb8017, val, gd5429); break; case 0x30: - gd5429_mmio_write(0x18, val, gd5429); + gd5429_mmio_write(0xb8018, val, gd5429); break; case 0x32: - gd5429_mmio_write(0x1a, val, gd5429); + gd5429_mmio_write(0xb801a, val, gd5429); break; case 0x31: - gd5429_mmio_write(0x40, val, gd5429); + gd5429_mmio_write(0xb8040, val, gd5429); break; } return; From 55dbe592ad3d7aa7d3aa154189e43ece9968f2ba Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 22 Feb 2018 21:04:32 +0000 Subject: [PATCH 0341/1050] Fixed bus type detection on Cirrus Logic. --- src/cpu.c | 2 ++ src/cpu.h | 2 ++ src/vid_cl5429.c | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 95bc194..8a06311 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -8,6 +8,7 @@ #include "codegen.h" int isa_cycles; +int has_vlb; static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; OpFn *x86_dynarec_opcodes; @@ -500,6 +501,7 @@ void cpu_set() cpu_hasMSR = 0; cpu_hasCR4 = 0; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); cpu_update_waitstates(); diff --git a/src/cpu.h b/src/cpu.h index 20cfd53..1141864 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -148,4 +148,6 @@ void cpu_update_waitstates(); void cpu_set(); void cpu_set_edx(); +extern int has_vlb; + #endif diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index a6dd8b3..16c9fcd 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1,6 +1,7 @@ /*Cirrus Logic CL-GD5429 emulation*/ #include #include "ibm.h" +#include "cpu.h" #include "device.h" #include "io.h" #include "mem.h" @@ -22,6 +23,14 @@ enum #define BLIT_DEPTH_8 0 #define BLIT_DEPTH_16 1 #define BLIT_DEPTH_32 3 + +#define CL_GD5429_SYSTEM_BUS_VESA 5 +#define CL_GD5429_SYSTEM_BUS_ISA 7 + +#define CL_GD543X_SYSTEM_BUS_PCI 4 +#define CL_GD543X_SYSTEM_BUS_VESA 6 +#define CL_GD543X_SYSTEM_BUS_ISA 7 + typedef struct gd5429_t { mem_mapping_t mmio_mapping; @@ -305,10 +314,33 @@ uint8_t gd5429_in(uint16_t addr, void *p) case 0x3c5: if (svga->seqaddr > 5) { + uint8_t temp; + switch (svga->seqaddr) { case 6: return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; + + case 0x17: + temp = svga->gdcreg[0x17]; + temp &= ~(7 << 3); + if (gd5429->type == CL_TYPE_GD5429) + { + if (has_vlb) + temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); + else + temp |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + } + else + { + if (PCI) + temp |= (CL_GD543X_SYSTEM_BUS_PCI << 3); + else if (has_vlb) + temp |= (CL_GD543X_SYSTEM_BUS_VESA << 3); + else + temp |= (CL_GD543X_SYSTEM_BUS_ISA << 3); + } + return temp; } return svga->seqregs[svga->seqaddr & 0x3f]; } @@ -424,7 +456,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) { uint32_t base, size; - if (gd5429->type <= CL_TYPE_GD5429) + if (gd5429->type <= CL_TYPE_GD5429 || (!PCI && !has_vlb)) { base = (svga->seqregs[7] & 0xf0) << 16; if (svga->gdcreg[0xb] & 0x20) @@ -437,7 +469,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) base = gd5429->lfb_base; size = 4 * 1024 * 1024; } - else + else /*VLB*/ { base = 128*1024*1024; size = 4 * 1024 * 1024; From 23e5aa2208aa478502c2552b852da8b49d2e630c Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 23 Feb 2018 21:07:47 +0000 Subject: [PATCH 0342/1050] Corrected PCI IRQ mapping on Advanced/ZP. --- src/model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index 27c37f7..6089be4 100644 --- a/src/model.c +++ b/src/model.c @@ -577,7 +577,7 @@ void at_zappa_init() pci_slot(0xf); pci_slot(0x10); i430fx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0xd, 0xf, 0xe, 0x10); pc87306_init(0x2e); intel_zappa_init(); device_add(&intel_flash_bxt_ami_device); From ff03442e765e521d15a3da15398d00f6353c09e4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 23 Feb 2018 21:57:53 +0000 Subject: [PATCH 0343/1050] Added fixed PCI device mapping for CL chips on Packard Bell machines. --- src/vid_cl5429.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 16c9fcd..c361f20 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1627,7 +1627,7 @@ static void cl_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *cl_init(int type, char *fn) +static void *cl_init(int type, char *fn, int pci_card) { gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); svga_t *svga = &gd5429->svga; @@ -1672,7 +1672,13 @@ static void *cl_init(int type, char *fn) if (PCI && type >= CL_TYPE_GD5430) { - gd5429->card = pci_add(cl_pci_read, cl_pci_write, gd5429); + if (pci_card != -1) + { + pci_add_specific(pci_card, cl_pci_read, cl_pci_write, gd5429); + gd5429->card = pci_card; + } + else + gd5429->card = pci_add(cl_pci_read, cl_pci_write, gd5429); gd5429->pci_regs[0x04] = 7; @@ -1687,23 +1693,23 @@ static void *cl_init(int type, char *fn) static void *gd5429_init() { - return cl_init(CL_TYPE_GD5429, "5429.vbi"); + return cl_init(CL_TYPE_GD5429, "5429.vbi", -1); } static void *gd5430_init() { - return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin"); + return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1); } static void *gd5430_pb570_init() { - return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin"); + return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8); } static void *gd5434_init() { - return cl_init(CL_TYPE_GD5434, "gd5434.bin"); + return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1); } static void *gd5434_pb520r_init() { - return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin"); + return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3); } static int gd5429_available() From 445cf601e8cca7eedbe8f7a7fed85d4033e2b7f1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 23 Feb 2018 21:58:30 +0000 Subject: [PATCH 0344/1050] Corrected PCI IRQ mapping on Packard Bell PB570. --- src/model.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index 6089be4..27be47d 100644 --- a/src/model.c +++ b/src/model.c @@ -101,6 +101,7 @@ void xt_t1200_init(); void at_sl82c460_init(); void at_zappa_init(); void at_pb520r_init(); +void at_pb570_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -176,7 +177,7 @@ MODEL models[] = {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, - {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, @@ -568,6 +569,18 @@ void at_endeavor_init() intel_endeavor_init(); device_add(&intel_flash_bxt_ami_device); } +void at_pb570_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x13); + i430fx_init(); + piix_init(7, 0x11, 0x13, 0xb, 0x8); + pc87306_init(0x2e); + intel_endeavor_init(); + device_add(&intel_flash_bxt_ami_device); +} void at_zappa_init() { at_init(); From 0ee7c7a354c316bebaad5568178ad1ea8dbb8e70 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 11:39:22 +0000 Subject: [PATCH 0345/1050] Added Oak OTI-037 emulation. Patch from EluanCM. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ibm.h | 1 + src/vid_oti037.c | 207 +++++++++++++++++++++++++++++ src/vid_oti037.h | 1 + src/vid_svga.c | 33 +++++ src/video.c | 2 + 14 files changed, 253 insertions(+), 9 deletions(-) create mode 100644 src/vid_oti037.c create mode 100644 src/vid_oti037.h diff --git a/src/Makefile.am b/src/Makefile.am index c833a9a..97dd5a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,7 +36,7 @@ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_e t1000.c t3100e.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ -vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \ +vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.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_t1000.c vid_t3100e.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 vid_wy700.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 651e680..a657d8d 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -16,7 +16,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 0c4fd5d..bdf229f 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -16,7 +16,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 4448a70..ce05ed2 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -15,7 +15,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 8a3c8df..02d6b9e 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -16,7 +16,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index b9ee97a..bba8c6b 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -18,7 +18,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 0a3fd57..cb3e2f5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -18,7 +18,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index f164a5c..0f594dd 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 acc2036.o acer386sx.o ali1429 soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 4e2f4f3..09ccb4b 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -15,7 +15,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ diff --git a/src/ibm.h b/src/ibm.h index d094b6a..ea77e29 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -495,6 +495,7 @@ enum GFX_TGUI9400CXI, /*Trident TGUI9440CXi*/ GFX_CL_GD5430, /*Cirrus Logic CL-GD5430*/ GFX_CL_GD5434, /*Cirrus Logic CL-GD5434*/ + GFX_OTI037, /*Oak OTI-037*/ GFX_MAX }; diff --git a/src/vid_oti037.c b/src/vid_oti037.c new file mode 100644 index 0000000..3843c1f --- /dev/null +++ b/src/vid_oti037.c @@ -0,0 +1,207 @@ +/*Oak OTI037 emulation*/ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "video.h" +#include "vid_oti037.h" +#include "vid_svga.h" + +typedef struct oti037_t +{ + svga_t svga; + + rom_t bios_rom; + + int index; + uint8_t regs[32]; + + uint8_t enable_register; +} oti037_t; + +void oti037_out(uint16_t addr, uint8_t val, void *p) +{ + oti037_t *oti037 = (oti037_t *)p; + svga_t *svga = &oti037->svga; + uint8_t old; + uint8_t idx; + + if (!(oti037->enable_register & 1) && addr != 0x3C3) + return; + + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; // mono / color addr selection + +// pclog("oti037_out : %04X %02X %02X %i ", addr, val, ram[0x489], ins); +// pclog(" %04X:%04X\n", CS,cpu_state.pc); + switch (addr) + { + case 0x3C3: + oti037->enable_register = val & 1; + return; + case 0x3D4: + svga->crtcreg = val /*& 31*/; // fixme: bios wants to set the test bit? + return; + case 0x3D5: + if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) + return; + if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg & 31]; + svga->crtc[svga->crtcreg & 31] = val; + if (old != val) + { + if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) + { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + + case 0x3DE: + oti037->index = val /*& 0x1f*/; + return; + case 0x3DF: + idx = oti037->index & 0x1f; + oti037->regs[idx] = val; + switch (idx) + { + case 0xD: + if (val & 0x80) + mem_mapping_disable(&svga->mapping); + else + mem_mapping_enable(&svga->mapping); + break; + case 0x11: + svga->read_bank = (val & 0xf) * 65536; + svga->write_bank = (val >> 4) * 65536; + break; + } + return; + } + svga_out(addr, val, svga); +} + +uint8_t oti037_in(uint16_t addr, void *p) +{ + oti037_t *oti037 = (oti037_t *)p; + svga_t *svga = &oti037->svga; + uint8_t temp; + + if (!(oti037->enable_register & 1) && addr != 0x3C3) + return 0xff; + + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; // mono / color addr selection + +// if (addr != 0x3da && addr != 0x3ba) pclog("oti037_in : %04X ", addr); + + switch (addr) + { + case 0x3C3: + temp = oti037->enable_register; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg & 31]; + break; + + case 0x3DE: + temp = oti037->index; + break; + case 0x3DF: + if ((oti037->index & 0x1f)==0x10) temp = 0x18; + else temp = oti037->regs[oti037->index & 0x1f]; + break; + + default: + temp = svga_in(addr, svga); + break; + } +// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); + return temp; +} + +void oti037_recalctimings(svga_t *svga) +{ + oti037_t *oti037 = (oti037_t *)svga->p; + + if (oti037->regs[0x14] & 0x08) svga->ma_latch |= 0x10000; + if (oti037->regs[0x0d] & 0x0c) svga->rowoffset <<= 1; + svga->interlace = oti037->regs[0x14] & 0x80; +} + +void *oti037_common_init(char *bios_fn, int vram_size) +{ + oti037_t *oti037 = malloc(sizeof(oti037_t)); + memset(oti037, 0, sizeof(oti037_t)); + + rom_init(&oti037->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + svga_init(&oti037->svga, oti037, vram_size << 10, + oti037_recalctimings, + oti037_in, oti037_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, oti037_in, NULL, NULL, oti037_out, NULL, NULL, oti037); + + oti037->svga.miscout = 1; + oti037->regs[0] = 0x08; // fixme: bios wants to read this at index 0? this index is undocumented + return oti037; +} + +void *oti037_init() +{ + return oti037_common_init("oti037/bios.bin", 256); +} + +static int oti037_available() +{ + return rom_present("oti037/bios.bin"); +} + +void oti037_close(void *p) +{ + oti037_t *oti037 = (oti037_t *)p; + + svga_close(&oti037->svga); + + free(oti037); +} + +void oti037_speed_changed(void *p) +{ + oti037_t *oti037 = (oti037_t *)p; + + svga_recalctimings(&oti037->svga); +} + +void oti037_force_redraw(void *p) +{ + oti037_t *oti037 = (oti037_t *)p; + + oti037->svga.fullchange = changeframecount; +} + +void oti037_add_status_info(char *s, int max_len, void *p) +{ + oti037_t *oti037 = (oti037_t *)p; + + svga_add_status_info(s, max_len, &oti037->svga); +} + +device_t oti037_device = +{ + "Oak OTI-037", + 0, + oti037_init, + oti037_close, + oti037_available, + oti037_speed_changed, + oti037_force_redraw, + oti037_add_status_info +}; diff --git a/src/vid_oti037.h b/src/vid_oti037.h new file mode 100644 index 0000000..e20e296 --- /dev/null +++ b/src/vid_oti037.h @@ -0,0 +1 @@ +extern device_t oti037_device; diff --git a/src/vid_svga.c b/src/vid_svga.c index 1780ae3..5835aa6 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -267,11 +267,44 @@ uint8_t svga_in(uint16_t addr, void *p) return svga->gdcreg[svga->gdcaddr & 0xf]; case 0x3DA: svga->attrff = 0; + + /* old diagnostic code if (svga->cgastat & 0x01) svga->cgastat &= ~0x30; else svga->cgastat ^= 0x30; return svga->cgastat; + */ + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) + { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + return svga->cgastat; } // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); return 0xFF; diff --git a/src/video.c b/src/video.c index 29cbafc..6b49103 100644 --- a/src/video.c +++ b/src/video.c @@ -26,6 +26,7 @@ #include "vid_colorplus.h" #include "vid_mda.h" #include "vid_olivetti_m24.h" +#include "vid_oti037.h" #include "vid_oti067.h" #include "vid_paradise.h" #include "vid_pc1512.h" @@ -84,6 +85,7 @@ static VIDEO_CARD video_cards[] = {"MDA", "mda", &mda_device, GFX_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"OAK OTI-037", "oti037", &oti037_device, GFX_OTI037, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, From dd590d20937be1dc534cc2120ebb4c1b9fcb730d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 14:05:38 +0000 Subject: [PATCH 0346/1050] Added Compaq CGA emulation. Patch from John Elliott. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ibm.h | 3 +- src/vid_cga.c | 2 +- src/vid_compaq_cga.c | 393 +++++++++++++++++++++++++++++ src/vid_compaq_cga.h | 1 + src/video.c | 2 + 14 files changed, 408 insertions(+), 11 deletions(-) create mode 100644 src/vid_compaq_cga.c create mode 100644 src/vid_compaq_cga.h diff --git a/src/Makefile.am b/src/Makefile.am index 97dd5a0..2c8e84f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,7 @@ sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb. sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c \ t1000.c t3100e.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_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ +vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c vid_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.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_t1000.c vid_t3100e.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index a657d8d..1120166 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -15,7 +15,7 @@ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_ad sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index bdf229f..c0cc80c 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -15,7 +15,7 @@ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_ad sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ce05ed2..52b12e7 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 acc2036.o acer386sx.o ali1429 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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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 \ diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 02d6b9e..6e830c2 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -14,7 +14,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index bba8c6b..e33a7c2 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -16,7 +16,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index cb3e2f5..584f699 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -16,7 +16,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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 \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 0f594dd..582f58f 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 acc2036.o acer386sx.o ali1429 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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o \ + vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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 \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 09ccb4b..2f679f5 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -14,7 +14,7 @@ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_ad sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ +vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ diff --git a/src/ibm.h b/src/ibm.h index ea77e29..dd2d556 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -378,7 +378,7 @@ char discfns[2][256]; int driveempty[2]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || 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 && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000 && romset != ROM_T1200) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && gfxcard != GFX_COMPAQ_CGA && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -496,6 +496,7 @@ enum GFX_CL_GD5430, /*Cirrus Logic CL-GD5430*/ GFX_CL_GD5434, /*Cirrus Logic CL-GD5434*/ GFX_OTI037, /*Oak OTI-037*/ + GFX_COMPAQ_CGA, /*Compaq CGA*/ GFX_MAX }; diff --git a/src/vid_cga.c b/src/vid_cga.c index eb1e8cf..7b616fc 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -476,7 +476,7 @@ void cga_speed_changed(void *p) cga_recalctimings(cga); } -static device_config_t cga_config[] = +device_config_t cga_config[] = { { .name = "display_type", diff --git a/src/vid_compaq_cga.c b/src/vid_compaq_cga.c new file mode 100644 index 0000000..d25cc24 --- /dev/null +++ b/src/vid_compaq_cga.c @@ -0,0 +1,393 @@ +/*Compaq CGA emulation*/ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "timer.h" +#include "video.h" +#include "vid_cga.h" +#include "vid_compaq_cga.h" + +typedef struct compaq_cga_t +{ + cga_t cga; + +} compaq_cga_t; + +static uint8_t mdaattr[256][2][2]; + +void compaq_cga_recalctimings(compaq_cga_t *self) +{ + double _dispontime, _dispofftime, disptime; + disptime = self->cga.crtc[0] + 1; + _dispontime = self->cga.crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + self->cga.dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + self->cga.dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +} + +void compaq_cga_poll(void *p) +{ + compaq_cga_t *self = (compaq_cga_t *)p; + uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + uint32_t cols[4]; + int oldsc; + int underline; + int blink; + + /* If in graphics mode or character height is not 13, behave as CGA */ + if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) + { + cga_poll(&self->cga); + return; + } + +/* We are in Compaq 350-line CGA territory */ + if (!self->cga.linepos) + { + self->cga.vidtime += self->cga.dispofftime; + self->cga.cgastat |= 1; + self->cga.linepos = 1; + oldsc = self->cga.sc; + if ((self->cga.crtc[8] & 3) == 3) + self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; + if (self->cga.cgadispon) + { + if (self->cga.displine < self->cga.firstline) + { + self->cga.firstline = self->cga.displine; + video_wait_for_buffer(); +// printf("Firstline %i\n",firstline); + } + self->cga.lastline = self->cga.displine; + + cols[0] = (self->cga.cgacol & 15); + + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[self->cga.displine])[c] = cols[0]; + if (self->cga.cgamode & 1) + ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 3) + 8] = cols[0]; + else + ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 4) + 8] = cols[0]; + } + if (self->cga.cgamode & 1) + { + for (x = 0; x < self->cga.crtc[1]; x++) + { + chr = self->cga.charbuffer[x << 1]; + attr = self->cga.charbuffer[(x << 1) + 1]; + drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); + underline = 0; + blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + if (self->cga.cgamode & 0x80) + { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + if (self->cga.sc == 12 && (attr & 7) == 1) underline = 1; + } + else if (self->cga.cgamode & 0x20) + { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if (blink) + cols[1] = cols[0]; + } + else + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + if (underline) + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = mdaattr[attr][blink][1]; + } + else if (drawcursor) + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + else + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + self->cga.ma++; + } + } + else + { + for (x = 0; x < self->cga.crtc[1]; x++) + { + chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)]; + attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)]; + drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); + underline = 0; + blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + if (self->cga.cgamode & 0x80) + { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + if (self->cga.sc == 12 && (attr & 7) == 1) underline = 1; + } + else if (self->cga.cgamode & 0x20) + { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if (blink) + cols[1] = cols[0]; + } + else + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + self->cga.ma++; + if (underline) + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4)+(c << 1) + 8] = + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4)+(c << 1) + 9] = mdaattr[attr][blink][1]; + } + else if (drawcursor) + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4)+(c << 1) + 8] = + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + else + { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + } + else + { + cols[0] = (self->cga.cgacol & 15); + if (self->cga.cgamode & 1) hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); + else hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); + } + + if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16; + else x = (self->cga.crtc[1] << 4) + 16; + + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[c] = cgapal[((uint32_t *)buffer32->line[self->cga.displine])[c] & 0xf]; + + self->cga.sc = oldsc; + if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) + self->cga.cgastat |= 8; + self->cga.displine++; + if (self->cga.displine >= 500) + self->cga.displine = 0; + } + else + { + self->cga.vidtime += self->cga.dispontime; + self->cga.linepos = 0; + if (self->cga.vsynctime) + { + self->cga.vsynctime--; + if (!self->cga.vsynctime) + self->cga.cgastat &= ~8; + } + if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) + { + self->cga.con = 0; + self->cga.coff = 1; + } + if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) + self->cga.maback = self->cga.ma; + if (self->cga.vadj) + { + self->cga.sc++; + self->cga.sc &= 31; + self->cga.ma = self->cga.maback; + self->cga.vadj--; + if (!self->cga.vadj) + { + self->cga.cgadispon = 1; + self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; + self->cga.sc = 0; + } + } + else if (self->cga.sc == self->cga.crtc[9]) + { + self->cga.maback = self->cga.ma; + self->cga.sc = 0; + oldvc = self->cga.vc; + self->cga.vc++; + self->cga.vc &= 127; + + if (self->cga.vc == self->cga.crtc[6]) + self->cga.cgadispon = 0; + + if (oldvc == self->cga.crtc[4]) + { + self->cga.vc = 0; + self->cga.vadj = self->cga.crtc[5]; + if (!self->cga.vadj) self->cga.cgadispon = 1; + if (!self->cga.vadj) self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; + if ((self->cga.crtc[10] & 0x60) == 0x20) self->cga.cursoron = 0; + else self->cga.cursoron = self->cga.cgablink & 8; + } + + if (self->cga.vc == self->cga.crtc[7]) + { + self->cga.cgadispon = 0; + self->cga.displine = 0; + self->cga.vsynctime = 16; + if (self->cga.crtc[7]) + { + if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16; + else x = (self->cga.crtc[1] << 4) + 16; + self->cga.lastline++; + if (x != xsize || (self->cga.lastline - self->cga.firstline) != ysize) + { + xsize = x; + ysize = self->cga.lastline - self->cga.firstline; + + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize + 16); + } + + video_blit_memtoscreen(0, self->cga.firstline - 4, 0, (self->cga.lastline - self->cga.firstline) + 8, xsize, (self->cga.lastline - self->cga.firstline) + 8); + frames++; + + video_res_x = xsize - 16; + video_res_y = ysize; + if (self->cga.cgamode & 1) + { + video_res_x /= 8; + video_res_y /= self->cga.crtc[9] + 1; + video_bpp = 0; + } + else if (!(self->cga.cgamode & 2)) + { + video_res_x /= 16; + video_res_y /= self->cga.crtc[9] + 1; + video_bpp = 0; + } + else if (!(self->cga.cgamode & 16)) + { + video_res_x /= 2; + video_bpp = 2; + } + else + { + video_bpp = 1; + } + } + self->cga.firstline = 1000; + self->cga.lastline = 0; + self->cga.cgablink++; + self->cga.oddeven ^= 1; + } + } + else + { + self->cga.sc++; + self->cga.sc &= 31; + self->cga.ma = self->cga.maback; + } + if (self->cga.cgadispon) + self->cga.cgastat &= ~1; + if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))) + self->cga.con = 1; + if (self->cga.cgadispon && (self->cga.cgamode & 1)) + { + for (x = 0; x < (self->cga.crtc[1] << 1); x++) + self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)]; + } + } + +} + +void *compaq_cga_init() +{ + int display_type; + int contrast; + int c; + compaq_cga_t *self = malloc(sizeof(compaq_cga_t)); + memset(self, 0, sizeof(compaq_cga_t)); + + self->cga.vram = malloc(0x4000); + + timer_add(compaq_cga_poll, &self->cga.vidtime, TIMER_ALWAYS_ENABLED, self); + mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, self); + io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); + + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); + cgapal_rebuild(display_type, contrast); + + for (c = 0; c < 256; c++) + { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 0; + if (c & 8) mdaattr[c][0][1] = 0xf; + else mdaattr[c][0][1] = 0x7; + } + mdaattr[0x70][0][1] = 0; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 0xf; + mdaattr[0xF0][0][1] = 0; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 0xf; + mdaattr[0x78][0][1] = 0x7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 0xf; + mdaattr[0xF8][0][1] = 0x7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 0xf; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 0; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 0; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 0; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 0; + + return self; +} + +void compaq_cga_close(void *p) +{ + compaq_cga_t *self = (compaq_cga_t *)p; + + free(self->cga.vram); + free(self); +} + +void compaq_cga_speed_changed(void *p) +{ + compaq_cga_t *self = (compaq_cga_t *)p; + + if (self->cga.crtc[9] == 13) /* Character height */ + { + compaq_cga_recalctimings(self); + } + else + { + cga_recalctimings(&self->cga); + } +} + +extern device_config_t cga_config[]; + +device_t compaq_cga_device = +{ + "Compaq CGA", + 0, + compaq_cga_init, + compaq_cga_close, + NULL, + compaq_cga_speed_changed, + NULL, + NULL, + cga_config +}; diff --git a/src/vid_compaq_cga.h b/src/vid_compaq_cga.h new file mode 100644 index 0000000..adbab4c --- /dev/null +++ b/src/vid_compaq_cga.h @@ -0,0 +1 @@ +extern device_t compaq_cga_device; diff --git a/src/video.c b/src/video.c index 6b49103..3f7eb0f 100644 --- a/src/video.c +++ b/src/video.c @@ -17,6 +17,7 @@ #include "vid_ati_mach64.h" #include "vid_cga.h" #include "vid_cl5429.h" +#include "vid_compaq_cga.h" #include "vid_ega.h" #include "vid_et4000.h" #include "vid_et4000w32.h" @@ -77,6 +78,7 @@ static VIDEO_CARD video_cards[] = {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From d7dfc6a178ccf0a959d816d212e9f379286f06ba Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 14:31:37 +0000 Subject: [PATCH 0347/1050] Added Compaq Portable Plus emulation. Patch from dns2kv2. --- src/ibm.h | 1 + src/mem.c | 8 ++++++++ src/model.c | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index dd2d556..136f740 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -455,6 +455,7 @@ enum ROM_PB570, ROM_ZAPPA, ROM_PB520R, + ROM_COMPAQ_PIP, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index c9a9eb2..c3bcdb2 100644 --- a/src/mem.c +++ b/src/mem.c @@ -890,6 +890,14 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_COMPAQ_PIP: + f=romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin","rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; + } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 27be47d..3981744 100644 --- a/src/model.c +++ b/src/model.c @@ -102,6 +102,7 @@ void at_sl82c460_init(); void at_zappa_init(); void at_pb520r_init(); void at_pb570_init(); +void compaq_pip_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -110,6 +111,7 @@ MODEL models[] = { {"[8088] AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 64, compaq_pip_init, NULL}, {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, xt_init, NULL}, @@ -258,6 +260,14 @@ void xt_init() device_add(&gameport_device); } +void compaq_pip_init() +{ + xt_init(); + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); +} + void pcjr_init() { mem_add_bios(); From ff94c18a919a1160288433e5d3e2f2b2a6f907d4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 14:44:24 +0000 Subject: [PATCH 0348/1050] PIT readback of timer with mode 3 and gate disabled now reads the counter directly rather than converting the emulator timer value. Fixes 101 error on Compaq Portable Plus. --- src/pit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pit.c b/src/pit.c index e479f31..90dab32 100644 --- a/src/pit.c +++ b/src/pit.c @@ -310,7 +310,7 @@ 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] && !(pit->m[t] == 3 && !pit->gate[t])) { int read = (int)((pit->c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT; if (pit->m[t] == 2) From 636fd9748d3b5ace16a4bb355e397763692ad344 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 15:09:03 +0000 Subject: [PATCH 0349/1050] Fixed hardcoded memory size on Toshiba T1000/T1200. Added ability to disable video on T1200. Patch form John Elliott. --- src/t1000.c | 10 +++++++++- src/vid_t1000.c | 14 +++++++++++++- src/vid_t1000.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/t1000.c b/src/t1000.c index 7dae292..fb5399a 100644 --- a/src/t1000.c +++ b/src/t1000.c @@ -210,7 +210,7 @@ static void ems_set_hardram(struct t1000_system *sys, uint8_t val) sys->ems_base = 0; } /* pclog("EMS base set to %02x\n", val); */ - sys->ems_pages = 48 - 4 * sys->ems_base; + sys->ems_pages = ((mem_size - 512) / 16) - 4 * sys->ems_base; if (sys->ems_pages < 0) sys->ems_pages = 0; /* Recalculate EMS mappings */ for (n = 0; n < 4; n++) @@ -421,6 +421,14 @@ static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) } } break; + /* It looks as if the T1200, like the T3100, can disable + * its builtin video chipset if it detects the presence of + * another video card. */ + case 6: if (romset == ROM_T1200) + { + t1000_video_enable(val & 0x01 ? 0 : 1); + } + break; /* EMS control*/ case 0x0F: switch (sys->sys_ctl[0x0E]) diff --git a/src/vid_t1000.c b/src/vid_t1000.c index ce9b310..def3eff 100644 --- a/src/vid_t1000.c +++ b/src/vid_t1000.c @@ -27,6 +27,7 @@ static uint8_t language; * Bit 0: Thin font */ static uint8_t st_video_options; +static uint8_t st_enabled = 1; static uint8_t st_display_internal = -1; void t1000_video_options_set(uint8_t options) @@ -35,6 +36,11 @@ void t1000_video_options_set(uint8_t options) st_video_options |= language; } +void t1000_video_enable(uint8_t enabled) +{ + st_enabled = enabled; +} + void t1000_display_set(uint8_t internal) { st_display_internal = internal; @@ -413,12 +419,18 @@ static void t1000_poll(void *p) { t1000_t *t1000 = (t1000_t *)p; - if (t1000->video_options != st_video_options) + if (t1000->video_options != st_video_options || + t1000->enabled != st_enabled) { t1000->video_options = st_video_options; + t1000->enabled = st_enabled; /* Set the font used for the external display */ t1000->cga.fontbase = ((t1000->video_options & 3) * 256); + + if (t1000->enabled) /* Disable internal chipset */ + mem_mapping_enable(&t1000->mapping); + else mem_mapping_disable(&t1000->mapping); } /* Switch between internal plasma and external CRT display. */ if (st_display_internal != -1 && st_display_internal != t1000->internal) diff --git a/src/vid_t1000.h b/src/vid_t1000.h index d85e9c6..f754cfa 100644 --- a/src/vid_t1000.h +++ b/src/vid_t1000.h @@ -2,3 +2,4 @@ extern device_t t1000_device; void t1000_video_options_set(uint8_t options); void t1000_display_set(uint8_t internal); +void t1000_video_enable(uint8_t enabled); From bcfd38f42e8df13c6e07148cf105cb0220ffb3cb Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 15:32:47 +0000 Subject: [PATCH 0350/1050] Removed MDA and VGA macros. Replaced with video_is_mda()/video_is_vga()/video_is_ega_vga() functions. --- src/ibm.h | 2 - src/keyboard_at.c | 3 +- src/keyboard_xt.c | 9 +-- src/video.c | 167 +++++++++++++++++++++++++++++++++++++--------- src/video.h | 3 + 5 files changed, 146 insertions(+), 38 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 136f740..302c36c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -377,8 +377,6 @@ int disctime; char discfns[2][256]; int driveempty[2]; -#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || 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_CGA && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 1153bc5..4726987 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -7,6 +7,7 @@ #include "sound_speaker.h" #include "t3100e.h" #include "timer.h" +#include "video.h" #include "x86.h" #include "keyboard.h" @@ -583,7 +584,7 @@ void keyboard_at_reset() keyboard_at.mem[0] = 0x11; keyboard_at.wantirq = 0; keyboard_at.output_port = 0xcf; - keyboard_at.input_port = (MDA) ? 0xf0 : 0xb0; + keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; keyboard_at.out_new = -1; keyboard_at.last_irq = 0; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 45fd521..a622211 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -9,6 +9,7 @@ #include "tandy_eeprom.h" #include "timer.h" #include "t1000.h" +#include "video.h" #include "keyboard.h" #include "keyboard_xt.h" @@ -140,9 +141,9 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) case 0x60: if ((romset == ROM_IBMPC) && (keyboard_xt.pb & 0x80)) { - if (VGA || gfxcard == GFX_EGA) + if (video_is_ega_vga()) temp = 0x4D; - else if (MDA) + else if (video_is_mda()) temp = 0x7D; else temp = 0x6D; @@ -190,9 +191,9 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) { if (keyboard_xt.pb & 0x08) { - if (VGA || gfxcard == GFX_EGA) + if (video_is_ega_vga()) temp = 4; - else if (MDA) + else if (video_is_mda()) temp = 7; else temp = 6; diff --git a/src/video.c b/src/video.c index 3f7eb0f..eb0aae6 100644 --- a/src/video.c +++ b/src/video.c @@ -52,6 +52,12 @@ enum VIDEO_BUS }; +#define VIDEO_FLAG_TYPE_CGA 0 +#define VIDEO_FLAG_TYPE_MDA 1 +#define VIDEO_FLAG_TYPE_SPECIAL 2 +#define VIDEO_FLAG_TYPE_MASK 3 + + typedef struct { int type; @@ -65,42 +71,43 @@ typedef struct char internal_name[24]; device_t *device; int legacy_id; + int flags; video_timings_t timing; } VIDEO_CARD; static VIDEO_CARD video_cards[] = { - {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, - {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"CGA", "cga", &cga_device, GFX_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, - {"Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, - {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"EGA", "ega", &ega_device, GFX_EGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Hercules", "hercules", &hercules_device, GFX_HERCULES, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"MDA", "mda", &mda_device, GFX_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"OAK OTI-037", "oti037", &oti037_device, GFX_OTI037, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, - {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, - {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, - {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, - {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, - {"VGA", "vga", &vga_device, GFX_VGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Wyse 700", "wy700", &wy700_device, GFX_WY700, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, + {"Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, + {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"OAK OTI-037", "oti037", &oti037_device, GFX_OTI037, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, + {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, + {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, + {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"", "", NULL, 0} }; @@ -195,6 +202,104 @@ int video_get_video_from_internal_name(char *s) return 0; } +int video_is_mda() +{ + switch (romset) + { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + case ROM_PC1512: + case ROM_PC1640: + case ROM_PC200: + case ROM_OLIM24: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: + case ROM_IBMPS1_2121: + case ROM_T3100E: + case ROM_T1000: + case ROM_ELX_PC425X: + case ROM_PB570: + case ROM_PB520R: + return 0; + } + return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA; +} +int video_is_cga() +{ + switch (romset) + { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + case ROM_PC1512: + case ROM_PC200: + case ROM_OLIM24: + case ROM_T3100E: + case ROM_T1000: + return 1; + + case ROM_PC1640: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: + case ROM_IBMPS1_2121: + case ROM_ELX_PC425X: + case ROM_PB570: + case ROM_PB520R: + return 0; + } + return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA; +} +int video_is_ega_vga() +{ + switch (romset) + { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + case ROM_PC1512: + case ROM_PC200: + case ROM_OLIM24: + case ROM_T3100E: + case ROM_T1000: + return 0; + + case ROM_PC1640: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: + case ROM_IBMPS1_2121: + case ROM_ELX_PC425X: + case ROM_PB570: + case ROM_PB520R: + return 1; + } + return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL; +} + int video_fullscreen = 0, video_fullscreen_scale, video_fullscreen_first; int video_force_aspect_ration = 0; int vid_disc_indicator = 0; diff --git a/src/video.h b/src/video.h index 7319e74..5b605c7 100644 --- a/src/video.h +++ b/src/video.h @@ -30,6 +30,9 @@ 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); +int video_is_mda(); +int video_is_cga(); +int video_is_ega_vga(); extern int video_fullscreen, video_fullscreen_scale, video_fullscreen_first; extern int video_force_aspect_ration; From ad1889864fee8ce8840ec530772102766555c29b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 15:44:49 +0000 Subject: [PATCH 0351/1050] Removed obsolete AMIBIOS hack. --- src/ibm.h | 1 - src/mem.c | 6 ------ 2 files changed, 7 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 302c36c..9971d8e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -378,7 +378,6 @@ char discfns[2][256]; int driveempty[2]; #define PCJR (romset == ROM_IBMPCJR) -#define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) int GAMEBLASTER, GUS, SSI2001, voodoo_enabled; extern int AMSTRAD, AT, is386, PCI, TANDY; diff --git a/src/mem.c b/src/mem.c index c3bcdb2..87e8715 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1920,12 +1920,6 @@ void mem_write_remappedl(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?*/ - { -// pclog("Read magic addr %04X(%06X):%04X\n",CS,cs,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]; } From f7384bf0851fff772562fb622e4c8fcc55289128 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 15:52:28 +0000 Subject: [PATCH 0352/1050] Display warning when a PCI device can not be initialised due to insufficient available PCI slots. --- src/device.c | 3 +++ src/device.h | 2 ++ src/pci.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/device.c b/src/device.c index c94b7b2..1e0572f 100644 --- a/src/device.c +++ b/src/device.c @@ -9,6 +9,7 @@ static void *device_priv[256]; static device_t *devices[256]; static device_t *current_device; +char *current_device_name = NULL; void device_init() { @@ -27,6 +28,7 @@ void device_add(device_t *d) fatal("device_add : too many devices\n"); current_device = d; + current_device_name = d->name; if (d->init != NULL) { @@ -37,6 +39,7 @@ void device_add(device_t *d) devices[c] = d; device_priv[c] = priv; + current_device_name = NULL; } void device_close_all() diff --git a/src/device.h b/src/device.h index 67bdda1..38a46bc 100644 --- a/src/device.h +++ b/src/device.h @@ -44,6 +44,8 @@ void device_speed_changed(); void device_force_redraw(); void device_add_status_info(char *s, int max_len); +extern char *current_device_name; + int device_get_config_int(char *name); char *device_get_config_string(char *name); diff --git a/src/pci.c b/src/pci.c index 8e9694d..8102fd7 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,4 +1,5 @@ #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "pic.h" @@ -218,5 +219,9 @@ int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int f } } + if (current_device_name) + warning("Failed to initialise PCI device '%s' due to insufficient available slots", current_device_name); + else + warning("Failed to initialise PCI device due to insufficient available slots"); return -1; } From 31dff3a509b23b691707bbbd49c6d29da68aade6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 18:08:36 +0000 Subject: [PATCH 0353/1050] Added Xi8088 emulation. Patch from EluanCM. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/fdc.c | 5 +++-- src/ibm.h | 1 + src/keyboard_at.c | 20 +++++++++++++++++ src/mem.c | 13 +++++++++-- src/model.c | 17 ++++++++++++++ src/nvr.c | 2 ++ src/xi8088.c | 36 ++++++++++++++++++++++++++++++ src/xi8088.h | 3 +++ 17 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 src/xi8088.c create mode 100644 src/xi8088.h diff --git a/src/Makefile.am b/src/Makefile.am index 2c8e84f..d0cd1a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,7 @@ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti03 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_t1000.c vid_t3100e.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 vid_wy700.c \ -x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc +x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 1120166..febf188 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -20,7 +20,7 @@ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti03 vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index c0cc80c..2530657 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -20,7 +20,7 @@ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti03 vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 52b12e7..ae8e225 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -20,7 +20,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 + win-status.o win-video.o x86seg.o x87.o xi8088.c xtide.o pc.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network index 6e830c2..616eb24 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xtide.o pc.res + win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xi8088.c xtide.o pc.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 NETOBJ = ne2000.o nethandler.o diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index e33a7c2..8b4824f 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ + vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 584f699..cbc712d 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xtide.o win-midi.o \ + vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 582f58f..2b6f091 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -20,7 +20,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.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 + win-status.o win-video.o x86seg.o x87.o xi8088.c xtide.o pc.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 2f679f5..0c5b11c 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -19,7 +19,7 @@ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti03 vid_pc1512.o vid_pc1640.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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o \ +x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o diff --git a/src/fdc.c b/src/fdc.c index 6bc6e52..bec48bc 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -87,7 +87,7 @@ void fdc_reset() fdc.lock = 0; fdc.head = 0; fdc.abort = 0; - if (!AT) + if (!AT && romset != ROM_XI8088) { fdc.rate = 2; // fdc_update_rate(); @@ -672,7 +672,8 @@ bad_command: } return; case 7: - if (!AT) return; + if (!AT && romset != ROM_XI8088) + return; fdc.rate=val&3; disc_3f7=val; diff --git a/src/ibm.h b/src/ibm.h index 9971d8e..eadd91b 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -453,6 +453,7 @@ enum ROM_ZAPPA, ROM_PB520R, ROM_COMPAQ_PIP, + ROM_XI8088, ROM_MAX }; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4726987..4cc899c 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -9,6 +9,7 @@ #include "timer.h" #include "video.h" #include "x86.h" +#include "xi8088.h" #include "keyboard.h" #include "keyboard_at.h" @@ -180,6 +181,8 @@ void keyboard_at_adddata_mouse(uint8_t val) void keyboard_at_write(uint16_t port, uint8_t val, void *priv) { // pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]); + if (romset == ROM_XI8088 && port == 0x63) + port = 0x61; /* if (ram[8] == 0xc3) { output = 3; @@ -335,6 +338,14 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) if (speaker_enable) was_speaker_enable = 1; pit_set_gate(&pit, 2, val & 1); + + if (romset == ROM_XI8088) + { + if (val & 0x04) + xi8088_turbo_set(1); + else + xi8088_turbo_set(0); + } break; case 0x64: @@ -544,6 +555,8 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) { uint8_t temp = 0xff; // if (port != 0x61) pclog("keyboard_at : read %04X ", port); + if (romset == ROM_XI8088 && port == 0x63) + port = 0x61; switch (port) { case 0x60: @@ -564,6 +577,13 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) else temp &= ~0x10; } + if (romset == ROM_XI8088) + { + if (xi8088_turbo_get()) + temp |= 0x04; + else + temp &= ~0x04; + } break; case 0x64: diff --git a/src/mem.c b/src/mem.c index 87e8715..7b4de06 100644 --- a/src/mem.c +++ b/src/mem.c @@ -866,12 +866,12 @@ int loadbios() f = romfopen("zappa/1006bs0_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - fread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("zappa/1006bs0_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - fread(rom, 0xd000, 1, f); + romfread(rom, 0xd000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -898,6 +898,15 @@ int loadbios() fclose(f); return 1; + case ROM_XI8088: + f = romfopen("xi8088/bios-xi8088.bin", "rb"); /* use the bios without xt-ide because it's configurable in pcem */ + if (!f) break; + /* high bit is flipped in xi8088 */ + romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom, 0x10000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 3981744..a4b3ca9 100644 --- a/src/model.c +++ b/src/model.c @@ -62,6 +62,7 @@ #include "vid_tandy.h" #include "vid_t1000.h" #include "wd76c10.h" +#include "xi8088.h" void xt_init(); void pcjr_init(); @@ -103,6 +104,7 @@ void at_zappa_init(); void at_pb520r_init(); void at_pb570_init(); void compaq_pip_init(); +void xt_xi8088_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -126,6 +128,7 @@ MODEL models[] = {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, xt_init, NULL}, {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 512,1280, 768, xt_t1000_init, &t1000_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, + {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2, 64,1024, 128, xt_xi8088_init, NULL}, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, @@ -350,6 +353,20 @@ void xt_laserxt_init() laserxt_init(); } +void xt_xi8088_init() +{ + /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ + common_init(); + mem_add_bios(); + keyboard_at_init(); + keyboard_at_init_ps2(); + nmi_init(); + nvr_init(); + pic2_init(); + device_add(&gameport_device); + xi8088_init(); +} + void at_init() { AT = 1; diff --git a/src/nvr.c b/src/nvr.c index 59272be..3a77f2c 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -301,6 +301,7 @@ void loadnvr() case ROM_PB570: f = nvrfopen("pb570.nvr", "rb"); nvrmask = 127; break; case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "rb"); nvrmask = 127; break; case ROM_PB520R: f = nvrfopen("pb520r.nvr", "rb"); nvrmask = 127; break; + case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -387,6 +388,7 @@ void savenvr() case ROM_PB570: f = nvrfopen("pb570.nvr", "wb"); break; case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "wb"); break; case ROM_PB520R: f = nvrfopen("pb520r.nvr", "wb"); break; + case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); break; default: return; } diff --git a/src/xi8088.c b/src/xi8088.c new file mode 100644 index 0000000..ad04e7e --- /dev/null +++ b/src/xi8088.c @@ -0,0 +1,36 @@ +#include "ibm.h" +#include "io.h" +#include "cpu.h" +#include "keyboard_at.h" + +#include "xi8088.h" + +static uint8_t xi8088_turbo; + +uint8_t xi8088_turbo_get() +{ + return xi8088_turbo; +} + +void xi8088_turbo_set(uint8_t value) +{ + xi8088_turbo = value; + if (!value) + { + pclog("Xi8088 turbo off\n"); + int c = cpu; + cpu = 0; /* 8088/4.77 */ + cpu_set(); + cpu = c; + } + else + { + pclog("Xi8088 turbo on\n"); + cpu_set(); + } +} + +void xi8088_init() +{ + xi8088_turbo = 1; +} diff --git a/src/xi8088.h b/src/xi8088.h new file mode 100644 index 0000000..ef40e19 --- /dev/null +++ b/src/xi8088.h @@ -0,0 +1,3 @@ +uint8_t xi8088_turbo_get(); +void xi8088_turbo_set(uint8_t value); +void xi8088_init(); From 3a369bd3f625dc97235bc6179d8d279f77f2f117 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 18:29:47 +0000 Subject: [PATCH 0354/1050] Configuration dialog now shows 'Built-in video' for machines with build in video. --- src/wx-config.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/wx-config.c b/src/wx-config.c index 40f5abd..bfcb75f 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -81,6 +81,16 @@ static void recalc_vid_list(void* hdlg, int model) wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + if (models[model].fixed_gfxcard) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Built-in video"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + wx_enablewindow(h, FALSE); + return; + } while (1) { @@ -106,7 +116,13 @@ static void recalc_vid_list(void* hdlg, int model) } if (!found_card) wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_enablewindow(h, models[model].fixed_gfxcard ? FALSE : TRUE); + wx_enablewindow(h, TRUE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(video_old_to_new(gfxcard))) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); wx_enablewindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); @@ -619,7 +635,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_enablewindow(h, FALSE); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(video_old_to_new(gfxcard))) + if (video_card_has_config(video_old_to_new(gfxcard)) && !models[romstomodel[romset]].fixed_gfxcard) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); @@ -1027,13 +1043,16 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) } else if (wParam == WX_ID("IDC_COMBOVID")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), (LONG_PARAM) temp_str); gfx = video_card_getid(temp_str); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(gfx)) + if (video_card_has_config(gfx) && !models[temp_model].fixed_gfxcard) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); From 9bdfc9348feda3bd63345e9518b67f964a9c6309 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Feb 2018 22:27:32 +0000 Subject: [PATCH 0355/1050] Video card can now be changed on Amstrad PC1640, PC2086, PC3086, and Sinclair PC200. --- src/amstrad.c | 36 +++++++++- src/amstrad.h | 10 +++ src/ibm.h | 1 + src/io.c | 8 +++ src/model.c | 146 +++++++++++++++++++++----------------- src/model.h | 13 +++- src/mouse.h | 5 ++ src/video.c | 183 ++++++++++++++++++++++++++++++++++++++++-------- src/wx-config.c | 43 ++++++++---- 9 files changed, 333 insertions(+), 112 deletions(-) diff --git a/src/amstrad.c b/src/amstrad.c index ca2861a..8817229 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -4,10 +4,12 @@ #include "keyboard.h" #include "lpt.h" #include "mouse.h" +#include "video.h" #include "amstrad.h" static uint8_t amstrad_dead; +int amstrad_latch = 0; uint8_t amstrad_read(uint16_t port, void *priv) { @@ -23,8 +25,38 @@ uint8_t amstrad_read(uint16_t port, void *priv) case 0x37a: temp = lpt1_read(port, NULL) & 0x1f; if (romset == ROM_PC1512) return temp | 0x20; - if (romset == ROM_PC200) return temp | 0x80; + if (romset == ROM_PC200) + { + if (video_is_cga()) + temp |= 0x80; + else if (video_is_mda()) + temp |= 0xc0; + return temp; + } + if (romset == ROM_PC1640) + { + if (video_is_cga()) + temp |= 0x80; + else if (video_is_mda()) + temp |= 0xc0; + + switch (amstrad_latch) + { + case AMSTRAD_NOLATCH: + temp &= ~0x20; + break; + case AMSTRAD_SW9: + temp &= ~0x20; + break; + case AMSTRAD_SW10: + temp |= 0x20; + break; + } + } return temp; + case 0x3de: + return 0x20; /*PC200 - use external video. If internal video is being used + then this port is handled in vid_pc200.c*/ case 0xdead: return amstrad_dead; } @@ -121,4 +153,6 @@ void amstrad_init() io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); io_sethandler(0x0378, 0x0003, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); + if (romset == ROM_PC200 && gfxcard != GFX_BUILTIN) + io_sethandler(0x03de, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); } diff --git a/src/amstrad.h b/src/amstrad.h index a4250d3..bc13c37 100644 --- a/src/amstrad.h +++ b/src/amstrad.h @@ -1,3 +1,13 @@ +#include "mouse.h" + void amstrad_init(); extern mouse_t mouse_amstrad; +extern int amstrad_latch; + +enum +{ + AMSTRAD_NOLATCH, + AMSTRAD_SW9, + AMSTRAD_SW10 +}; diff --git a/src/ibm.h b/src/ibm.h index eadd91b..97b661c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -465,6 +465,7 @@ int romset; enum { + GFX_BUILTIN = -1, GFX_CGA = 0, GFX_MDA, GFX_HERCULES, diff --git a/src/io.c b/src/io.c index 318575c..3c6cfd9 100644 --- a/src/io.c +++ b/src/io.c @@ -1,4 +1,5 @@ #include "ibm.h" +#include "amstrad.h" #include "ide.h" #include "io.h" #include "video.h" @@ -135,6 +136,13 @@ uint8_t inb(uint16_t port) if (port_inb[port][1]) temp &= port_inb[port][1](port, port_priv[port][1]); + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10; + else + amstrad_latch = AMSTRAD_SW9; + /* if (!port_inb[port][0] && !port_inb[port][1]) pclog("Bad INB %04X %04X:%04X\n", port, CS, pc);*/ diff --git a/src/model.c b/src/model.c index a4b3ca9..cff18ee 100644 --- a/src/model.c +++ b/src/model.c @@ -111,80 +111,80 @@ int AMSTRAD, AT, PCI, TANDY; MODEL models[] = { - {"[8088] AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 64, compaq_pip_init, NULL}, - {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, xt_init, NULL}, - {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 64, pcjr_init, &pcjr_device}, - {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, europc_init, NULL}, - {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, - {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, - {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, xt_init, NULL}, - {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 1, 0, 512,1280, 768, xt_t1000_init, &t1000_device}, - {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, 0, 64,1152, 64, xt_laserxt_init, NULL}, - {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2, 64,1024, 128, xt_xi8088_init, NULL}, + {"[8088] AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 64, compaq_pip_init, NULL}, + {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 32, xt_init, NULL}, + {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 64, pcjr_init, &pcjr_device}, + {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, europc_init, NULL}, + {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 128, tandy1k_init, &tandy1000_device}, + {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}, + {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, &t1000_device}, + {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}, + {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, NULL}, - {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, - {"[8088] Toshiba 1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 1024,2048,1024, xt_t1200_init, &t1000_device}, - {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 0, 0, 512,1152, 128, xt_laserxt_init, NULL}, + {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, + {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW, 512, 768, 128, tandy1ksl2_init, NULL}, + {"[8088] Toshiba 1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, &t1000_device}, + {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 1152, 128, xt_laserxt_init, NULL}, - {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, - {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_scat_init, NULL}, - {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 640,16384,128, at_cbm_init, NULL}, - {"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 256,15872,128, ibm_at_init, NULL}, - {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 640,16384,128, dells200_init, NULL}, - {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, - {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, - {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT , 512,16384,128, at_scat_init, NULL}, - {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, - {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 512,16384,512, ps1_m2011_init, NULL}, - {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, - {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872,128, ibm_at_init, NULL}, - {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512,2048, 128, at_scat_init, NULL}, - {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, - {"[286] Toshiba 3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_HAS_IDE, 1024,5120,256, at_t3100e_init, NULL}, + {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, + {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_scat_init, NULL}, + {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 640,16384, 128, at_cbm_init, NULL}, + {"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 256,15872, 128, ibm_at_init, NULL}, + {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 640,16384, 128, dells200_init, NULL}, + {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, + {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, + {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 128, at_scat_init, NULL}, + {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, + {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 512,16384, 512, ps1_m2011_init, NULL}, + {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, + {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, + {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL}, + {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, + {"[286] Toshiba 3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}, - {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, - {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_headland_init, NULL}, - {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, - {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, - {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT, 256,15872,128, at_init, NULL}, - {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, - {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT , 512,16384,512, at_scatsx_init, NULL}, - {"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, 0, MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL}, + {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, + {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, + {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, + {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, + {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, + {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 512, at_scatsx_init, NULL}, + {"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL}, - {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, - {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 1, MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, - {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, + {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, - {"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, - {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, - {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 0, MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, - {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, 1, MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, + {"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, + {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, - {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, - {"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL}, + {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, + {"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL}, - {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, - {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, - {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 1, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, + {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, + {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, - {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, 0, MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; @@ -242,6 +242,20 @@ int model_get_model_from_internal_name(char *s) return 0; } +int model_has_fixed_gfx(int model) +{ + int gfx_flags = models[model].flags & MODEL_GFX_MASK; + + return (gfx_flags == MODEL_GFX_FIXED || gfx_flags == MODEL_GFX_DISABLE_SW); +} + +int model_has_optional_gfx(int model) +{ + int gfx_flags = models[model].flags & MODEL_GFX_MASK; + + return (gfx_flags == MODEL_GFX_DISABLE_HW); +} + void common_init() { dma_init(); diff --git a/src/model.h b/src/model.h index 6c94345..11c442d 100644 --- a/src/model.h +++ b/src/model.h @@ -6,6 +6,16 @@ #define MODEL_MCA 0x20 #define MODEL_PCI 0x40 +/*Machine has no integrated graphics*/ +#define MODEL_GFX_NONE 0x000 +/*Machine has integrated graphics that can not be disabled*/ +#define MODEL_GFX_FIXED 0x100 +/*Machine has integrated graphics that can be disabled by jumpers or switches*/ +#define MODEL_GFX_DISABLE_HW 0x200 +/*Machine has integrated graphics that can be disabled through software*/ +#define MODEL_GFX_DISABLE_SW 0x300 +#define MODEL_GFX_MASK 0x300 + typedef struct { char name[64]; @@ -16,7 +26,6 @@ typedef struct char name[8]; CPU *cpus; } cpu[5]; - int fixed_gfxcard; int flags; int min_ram, max_ram; int ram_granularity; @@ -36,3 +45,5 @@ 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_has_fixed_gfx(int model); +int model_has_optional_gfx(int model); diff --git a/src/mouse.h b/src/mouse.h index 216ed73..d39f539 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -1,3 +1,6 @@ +#ifndef _MOUSE_H_ +#define _MOUSE_H_ + void mouse_emu_init(); void mouse_emu_close(); void mouse_poll(int x, int y, int z, int b); @@ -24,3 +27,5 @@ typedef struct } mouse_t; extern int mouse_type; + +#endif diff --git a/src/video.c b/src/video.c index eb0aae6..e0d85f2 100644 --- a/src/video.c +++ b/src/video.c @@ -129,6 +129,9 @@ static video_timings_t timing_pb520r = {VIDEO_BUS, 4, 4, 8, 10,10,20}; int video_card_available(int card) { + if (card == GFX_BUILTIN) + return 1; + if (video_cards[card].device) return device_available(video_cards[card].device); @@ -137,16 +140,90 @@ int video_card_available(int card) char *video_card_getname(int card) { + if (card == GFX_BUILTIN) + return "Built-in video"; return video_cards[card].name; } device_t *video_card_getdevice(int card) { + switch (romset) + { + case ROM_IBMPCJR: + return &pcjr_video_device; + + case ROM_TANDY: + case ROM_TANDY1000HX: + return &tandy_device; + + case ROM_TANDY1000SL2: + return &tandysl_device; + + case ROM_PC1512: + return &pc1512_device; + + case ROM_PC1640: + if (gfxcard == GFX_BUILTIN) + return &pc1640_device; + break; + + case ROM_PC200: + if (gfxcard == GFX_BUILTIN) + return &pc200_device; + break; + + case ROM_OLIM24: + return &m24_device; + + case ROM_PC2086: + if (gfxcard == GFX_BUILTIN) + return ¶dise_pvga1a_pc2086_device; + break; + + case ROM_PC3086: + if (gfxcard == GFX_BUILTIN) + return ¶dise_pvga1a_pc3086_device; + break; + + case ROM_MEGAPC: + return ¶dise_wd90c11_megapc_device; + + case ROM_ACER386: + return &oti067_acer386_device; + + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: + return &ps1vga_device; + + case ROM_IBMPS1_2121: + return &ps1_m2121_svga_device; + + case ROM_T3100E: + return &t3100e_device; + + case ROM_T1000: + case ROM_T1200: + return &t1000_device; + + case ROM_ELX_PC425X: + return &tgui9400cxi_elx_device; + + case ROM_PB570: + return &gd5430_pb570_device; + + case ROM_PB520R: + return &gd5434_pb520r_device; + } return video_cards[card].device; } int video_card_has_config(int card) { + if (card == GFX_BUILTIN) + return 0; return video_cards[card].device->config ? 1 : 0; } @@ -161,6 +238,9 @@ int video_card_getid(char *s) c++; } + if (!strcmp(s, "Built-in video")) + return GFX_BUILTIN; + return 0; } @@ -168,6 +248,9 @@ int video_old_to_new(int card) { int c = 0; + if (card == GFX_BUILTIN) + return GFX_BUILTIN; + while (video_cards[c].device) { if (video_cards[c].legacy_id == card) @@ -180,11 +263,17 @@ int video_old_to_new(int card) int video_new_to_old(int card) { + if (card == GFX_BUILTIN) + return GFX_BUILTIN; + return video_cards[card].legacy_id; } char *video_get_internal_name(int card) { + if (card == GFX_BUILTIN) + return "builtin"; + return video_cards[card].internal_name; } @@ -192,6 +281,9 @@ int video_get_video_from_internal_name(char *s) { int c = 0; + if (!strcmp(s, "builtin")) + return GFX_BUILTIN; + while (video_cards[c].legacy_id != -1) { if (!strcmp(video_cards[c].internal_name, s)) @@ -206,18 +298,20 @@ int video_is_mda() { switch (romset) { + case ROM_PC1640: + case ROM_PC200: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + if (gfxcard != GFX_BUILTIN) + break; case ROM_IBMPCJR: case ROM_TANDY: case ROM_TANDY1000HX: case ROM_TANDY1000SL2: case ROM_PC1512: - case ROM_PC1640: - case ROM_PC200: case ROM_OLIM24: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_ACER386: case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: @@ -237,12 +331,14 @@ int video_is_cga() { switch (romset) { + case ROM_PC200: + if (gfxcard != GFX_BUILTIN) + break; case ROM_IBMPCJR: case ROM_TANDY: case ROM_TANDY1000HX: case ROM_TANDY1000SL2: case ROM_PC1512: - case ROM_PC200: case ROM_OLIM24: case ROM_T3100E: case ROM_T1000: @@ -253,6 +349,8 @@ int video_is_cga() case ROM_PC3086: case ROM_MEGAPC: case ROM_ACER386: + if (gfxcard != GFX_BUILTIN) + break; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: @@ -370,6 +468,9 @@ void video_updatetiming() video_timings_t *timing; int new_gfxcard = 0; + new_gfxcard = video_old_to_new(gfxcard); + timing = &video_cards[new_gfxcard].timing; + switch (romset) { case ROM_IBMPCJR: @@ -384,11 +485,13 @@ void video_updatetiming() break; case ROM_PC1640: - timing = &timing_pc1640; + if (gfxcard == GFX_BUILTIN) + timing = &timing_pc1640; break; case ROM_PC200: - timing = &timing_pc200; + if (gfxcard == GFX_BUILTIN) + timing = &timing_pc200; break; case ROM_OLIM24: @@ -397,15 +500,18 @@ void video_updatetiming() case ROM_PC2086: case ROM_PC3086: - timing = &timing_pvga1a; + if (gfxcard == GFX_BUILTIN) + timing = &timing_pvga1a; break; case ROM_MEGAPC: - timing = &timing_wd90c11; + if (gfxcard == GFX_BUILTIN) + timing = &timing_wd90c11; break; case ROM_ACER386: - timing = &timing_oti067; + if (gfxcard == GFX_BUILTIN) + timing = &timing_oti067; break; case ROM_IBMPS1_2011: @@ -439,11 +545,6 @@ void video_updatetiming() case ROM_PB520R: timing = &timing_pb520r; break; - - default: - new_gfxcard = video_old_to_new(gfxcard); - timing = &video_cards[new_gfxcard].timing; - break; } @@ -526,32 +627,56 @@ void video_init() return; case ROM_PC1640: - device_add(&pc1640_device); - return; + if (gfxcard == GFX_BUILTIN) + { + device_add(&pc1640_device); + return; + } + break; case ROM_PC200: - device_add(&pc200_device); - return; + if (gfxcard == GFX_BUILTIN) + { + device_add(&pc200_device); + return; + } + break; case ROM_OLIM24: device_add(&m24_device); return; case ROM_PC2086: - device_add(¶dise_pvga1a_pc2086_device); - return; + if (gfxcard == GFX_BUILTIN) + { + device_add(¶dise_pvga1a_pc2086_device); + return; + } + break; case ROM_PC3086: - device_add(¶dise_pvga1a_pc3086_device); - return; + if (gfxcard == GFX_BUILTIN) + { + device_add(¶dise_pvga1a_pc3086_device); + return; + } + break; case ROM_MEGAPC: - device_add(¶dise_wd90c11_megapc_device); - return; + if (gfxcard == GFX_BUILTIN) + { + device_add(¶dise_wd90c11_megapc_device); + return; + } + break; case ROM_ACER386: - device_add(&oti067_acer386_device); - return; + if (gfxcard == GFX_BUILTIN) + { + device_add(&oti067_acer386_device); + return; + } + break; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: diff --git a/src/wx-config.c b/src/wx-config.c index bfcb75f..30b2dc7 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -73,16 +73,17 @@ static int mouse_valid(int type, int model) return FALSE; }*/ -static void recalc_vid_list(void* hdlg, int model) +static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) { void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); int c = 0, d = 0; int found_card = 0; + int cur_gfxcard = gfxcard; wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - if (models[model].fixed_gfxcard) + if (model_has_fixed_gfx(model)) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Built-in video"); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); @@ -92,6 +93,18 @@ static void recalc_vid_list(void* hdlg, int model) return; } + if (model_has_optional_gfx(model)) + { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Built-in video"); + if (gfxcard == GFX_BUILTIN || force_builtin_video) + { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + cur_gfxcard = GFX_BUILTIN; + } + d++; + } + while (1) { char *s = video_card_getname(c); @@ -103,7 +116,7 @@ static void recalc_vid_list(void* hdlg, int model) ((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - if (video_new_to_old(c) == gfxcard) + if (video_new_to_old(c) == gfxcard && !found_card) { wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); found_card = 1; @@ -119,7 +132,7 @@ static void recalc_vid_list(void* hdlg, int model) wx_enablewindow(h, TRUE); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(video_old_to_new(gfxcard))) + if (video_card_has_config(video_old_to_new(cur_gfxcard))) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); @@ -551,7 +564,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); prev_model = model; - recalc_vid_list(hdlg, romstomodel[romset]); + recalc_vid_list(hdlg, romstomodel[romset], 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); c = 0; @@ -634,12 +647,6 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(video_old_to_new(gfxcard)) && !models[romstomodel[romset]].fixed_gfxcard) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); if (sound_card_has_config(sound_card_current)) wx_enablewindow(h, TRUE); @@ -818,14 +825,20 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { if (wParam == WX_ID("IDC_COMBO1")) { - int force_ide = 0; + int force_ide = 0; + int force_builtin_video = 0; h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + if (temp_model == prev_model) + break; + if ((models[temp_model].flags & MODEL_HAS_IDE) && !(models[prev_model].flags & MODEL_HAS_IDE)) force_ide = 1; - + if (model_has_optional_gfx(temp_model)) + force_builtin_video = 1; + prev_model = temp_model; /*Rebuild manufacturer list*/ @@ -940,7 +953,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - recalc_vid_list(hdlg, temp_model); + recalc_vid_list(hdlg, temp_model, force_builtin_video); recalc_hdd_list(hdlg, temp_model, 1, force_ide); @@ -1052,7 +1065,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) gfx = video_card_getid(temp_str); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(gfx) && !models[temp_model].fixed_gfxcard) + if (video_card_has_config(gfx) && !model_has_fixed_gfx(temp_model)) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); From 78adae497f4214515e404c2b1f5e30bd73d602cd Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 25 Feb 2018 11:47:01 +0000 Subject: [PATCH 0356/1050] Video card can now be changed on Acer 386SX25/N, Packard Bell PB520R, and Packard Bell PB570. --- src/model.c | 6 +++--- src/vid_oti067.c | 2 ++ src/video.c | 19 +++++++++++++++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/model.c b/src/model.c index cff18ee..e0719a7 100644 --- a/src/model.c +++ b/src/model.c @@ -136,7 +136,7 @@ MODEL models[] = {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW, 512, 768, 128, tandy1ksl2_init, NULL}, + {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}, {"[8088] Toshiba 1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, &t1000_device}, {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 1152, 128, xt_laserxt_init, NULL}, @@ -246,14 +246,14 @@ int model_has_fixed_gfx(int model) { int gfx_flags = models[model].flags & MODEL_GFX_MASK; - return (gfx_flags == MODEL_GFX_FIXED || gfx_flags == MODEL_GFX_DISABLE_SW); + return (gfx_flags == MODEL_GFX_FIXED); } int model_has_optional_gfx(int model) { int gfx_flags = models[model].flags & MODEL_GFX_MASK; - return (gfx_flags == MODEL_GFX_DISABLE_HW); + return (gfx_flags == MODEL_GFX_DISABLE_HW || gfx_flags == MODEL_GFX_DISABLE_SW); } void common_init() diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 4a2cbc8..7ae5a8d 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -179,11 +179,13 @@ void oti067_enable_disable(void *p, int enable) mem_mapping_disable(&oti067->bios_rom.mapping); io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); io_removehandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + mem_mapping_disable(&oti067->svga.mapping); if (enable) { mem_mapping_enable(&oti067->bios_rom.mapping); io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + mem_mapping_enable(&oti067->svga.mapping); } } diff --git a/src/video.c b/src/video.c index e0d85f2..0c923b4 100644 --- a/src/video.c +++ b/src/video.c @@ -671,12 +671,13 @@ void video_init() break; case ROM_ACER386: - if (gfxcard == GFX_BUILTIN) + device_add(&oti067_acer386_device); + if (gfxcard != GFX_BUILTIN) { - device_add(&oti067_acer386_device); - return; + svga_set_override(svga_get_pri(), 1); + break; } - break; + return; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: @@ -705,10 +706,20 @@ void video_init() case ROM_PB570: device_add(&gd5430_pb570_device); + if (gfxcard != GFX_BUILTIN) + { + svga_set_override(svga_get_pri(), 1); + break; + } return; case ROM_PB520R: device_add(&gd5434_pb520r_device); + if (gfxcard != GFX_BUILTIN) + { + svga_set_override(svga_get_pri(), 1); + break; + } return; } device_add(video_cards[video_old_to_new(gfxcard)].device); From d28a908839db7f2e4916dadbc4bee25188fb34d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 25 Feb 2018 15:13:45 +0000 Subject: [PATCH 0357/1050] Video card can now be changed on Amstrad MegaPC. --- src/model.c | 2 +- src/rom.h | 5 +++++ src/vid_paradise.c | 19 +++++++++++++++++++ src/video.c | 9 +++++---- src/wd76c10.c | 19 +++++++++++++++++++ src/wd76c10.h | 3 +++ 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/model.c b/src/model.c index e0719a7..16c7396 100644 --- a/src/model.c +++ b/src/model.c @@ -159,7 +159,7 @@ MODEL models[] = {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, - {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, diff --git a/src/rom.h b/src/rom.h index 0e32d57..5e578ed 100644 --- a/src/rom.h +++ b/src/rom.h @@ -1,3 +1,6 @@ +#ifndef _ROM_H_ +#define _ROM_H_ + FILE *romfopen(char *fn, char *mode); int rom_present(char *fn); @@ -14,3 +17,5 @@ int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t addre uint8_t rom_read(uint32_t addr, void *p); uint16_t rom_readw(uint32_t addr, void *p); uint32_t rom_readl(uint32_t addr, void *p); + +#endif diff --git a/src/vid_paradise.c b/src/vid_paradise.c index e8ad9a2..d371597 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -14,6 +14,7 @@ #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_unk_ramdac.h" +#include "wd76c10.h" typedef struct paradise_t { @@ -32,6 +33,9 @@ typedef struct paradise_t void paradise_remap(paradise_t *paradise); +void paradise_out(uint16_t addr, uint8_t val, void *p); +uint8_t paradise_in(uint16_t addr, void *p); + void paradise_out(uint16_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; @@ -132,6 +136,16 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) } } break; + + case 0x46e8: + io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_disable(¶dise->svga.mapping); + if (val & 8) + { + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_enable(¶dise->svga.mapping); + } + break; } svga_out(addr, val, svga); } @@ -356,6 +370,8 @@ static void *paradise_wd90c11_megapc_init() "megapc/211253-bios hi.u19", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + wd76c10_set_bios_rom(¶dise->bios_rom); + return paradise; } @@ -368,6 +384,9 @@ static void *paradise_pvga1a_oli_go481_init() "oli_go481_lo.bin", "oli_go481_hi.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + return paradise; } diff --git a/src/video.c b/src/video.c index 0c923b4..be77753 100644 --- a/src/video.c +++ b/src/video.c @@ -663,12 +663,13 @@ void video_init() break; case ROM_MEGAPC: - if (gfxcard == GFX_BUILTIN) + device_add(¶dise_wd90c11_megapc_device); + if (gfxcard != GFX_BUILTIN) { - device_add(¶dise_wd90c11_megapc_device); - return; + svga_set_override(svga_get_pri(), 1); + break; } - break; + return; case ROM_ACER386: device_add(&oti067_acer386_device); diff --git a/src/wd76c10.c b/src/wd76c10.c index 9c77b7d..47062c9 100644 --- a/src/wd76c10.c +++ b/src/wd76c10.c @@ -2,6 +2,7 @@ #include "fdc.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "serial.h" #include "wd76c10.h" @@ -9,6 +10,13 @@ static uint16_t wd76c10_0092; static uint16_t wd76c10_2072; static uint16_t wd76c10_2872; static uint16_t wd76c10_5872; +static uint16_t wd76c10_6072; +static rom_t *video_bios_rom = NULL; + +void wd76c10_set_bios_rom(rom_t *rom) +{ + video_bios_rom = rom; +} uint16_t wd76c10_read(uint16_t port, void *priv) { @@ -25,6 +33,9 @@ uint16_t wd76c10_read(uint16_t port, void *priv) case 0x5872: return wd76c10_5872; + + case 0x6072: + return wd76c10_6072; } return 0; } @@ -81,6 +92,13 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv) case 0x5872: wd76c10_5872 = val; break; + + case 0x6072: + wd76c10_6072 = val; + mem_mapping_disable(&video_bios_rom->mapping); + if ((val & 0xc) == 8) + mem_mapping_enable(&video_bios_rom->mapping); + break; } } @@ -106,4 +124,5 @@ void wd76c10_init() io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x6072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); } diff --git a/src/wd76c10.h b/src/wd76c10.h index 70ed1c9..0ba62e0 100644 --- a/src/wd76c10.h +++ b/src/wd76c10.h @@ -1 +1,4 @@ +#include "rom.h" + void wd76c10_init(); +void wd76c10_set_bios_rom(rom_t *rom); From 81936054691323d09d0acb0352e1e78d5acf89e8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Feb 2018 19:52:10 +0000 Subject: [PATCH 0358/1050] Treat zero ATAPI maximum transfer as 65534. Fixes crash sometimes when booting PB570. --- src/ide_atapi.c | 2 ++ src/scsi_cd.c | 1 + src/scsi_zip.c | 1 + 3 files changed, 4 insertions(+) diff --git a/src/ide_atapi.c b/src/ide_atapi.c index b916898..7ac20a2 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -142,6 +142,8 @@ void atapi_process_packet(atapi_device_t *atapi_dev) case ATAPI_STATE_COMMAND: *atapi_dev->atastat = READY_STAT | (*atapi_dev->atastat & ERR_STAT); atapi_dev->max_transfer_len = (*atapi_dev->cylinder) & ~1; + if (!atapi_dev->max_transfer_len) + atapi_dev->max_transfer_len = 0xfffe; atapi_dev->bus_state = BUS_CD | BUS_REQ; break; diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 0f0ceb7..9a33674 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -1174,6 +1174,7 @@ static void scsi_cd_atapi_identify(uint16_t *buffer, void *p) ide_padstr((char *)(buffer + 23), "v1.0", 8); /* Firmware */ ide_padstr((char *)(buffer + 27), "PCemCD", 40); /* Model */ buffer[49] = 0x200; /* LBA supported */ + buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ } scsi_device_t scsi_cd = diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 89a9386..8af34d9 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -1077,6 +1077,7 @@ static void scsi_zip_atapi_identify(uint16_t *buffer, void *p) ide_padstr((char *)(buffer + 23), "E.08", 8); /* Firmware */ ide_padstr((char *)(buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ buffer[49] = 0x200; /* LBA supported */ + buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ } scsi_device_t scsi_zip = From c14c22169d2fddb2d9d0a266dc972914682ae691 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Feb 2018 20:38:51 +0000 Subject: [PATCH 0359/1050] MegaPC uses a jumper to disable onboard video instead of doing it automatically. --- src/model.c | 2 +- src/vid_paradise.c | 2 -- src/video.c | 9 ++++----- src/wd76c10.c | 9 --------- src/wd76c10.h | 3 --- 5 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/model.c b/src/model.c index 16c7396..df90f94 100644 --- a/src/model.c +++ b/src/model.c @@ -159,7 +159,7 @@ MODEL models[] = {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, - {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, diff --git a/src/vid_paradise.c b/src/vid_paradise.c index d371597..b42482d 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -370,8 +370,6 @@ static void *paradise_wd90c11_megapc_init() "megapc/211253-bios hi.u19", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - wd76c10_set_bios_rom(¶dise->bios_rom); - return paradise; } diff --git a/src/video.c b/src/video.c index be77753..0c923b4 100644 --- a/src/video.c +++ b/src/video.c @@ -663,13 +663,12 @@ void video_init() break; case ROM_MEGAPC: - device_add(¶dise_wd90c11_megapc_device); - if (gfxcard != GFX_BUILTIN) + if (gfxcard == GFX_BUILTIN) { - svga_set_override(svga_get_pri(), 1); - break; + device_add(¶dise_wd90c11_megapc_device); + return; } - return; + break; case ROM_ACER386: device_add(&oti067_acer386_device); diff --git a/src/wd76c10.c b/src/wd76c10.c index 47062c9..5416c62 100644 --- a/src/wd76c10.c +++ b/src/wd76c10.c @@ -11,12 +11,6 @@ static uint16_t wd76c10_2072; static uint16_t wd76c10_2872; static uint16_t wd76c10_5872; static uint16_t wd76c10_6072; -static rom_t *video_bios_rom = NULL; - -void wd76c10_set_bios_rom(rom_t *rom) -{ - video_bios_rom = rom; -} uint16_t wd76c10_read(uint16_t port, void *priv) { @@ -95,9 +89,6 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv) case 0x6072: wd76c10_6072 = val; - mem_mapping_disable(&video_bios_rom->mapping); - if ((val & 0xc) == 8) - mem_mapping_enable(&video_bios_rom->mapping); break; } } diff --git a/src/wd76c10.h b/src/wd76c10.h index 0ba62e0..70ed1c9 100644 --- a/src/wd76c10.h +++ b/src/wd76c10.h @@ -1,4 +1 @@ -#include "rom.h" - void wd76c10_init(); -void wd76c10_set_bios_rom(rom_t *rom); From 4ba95a18533619843f2eff910e90c1d52dc02374 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Feb 2018 22:06:17 +0000 Subject: [PATCH 0360/1050] Apply ISA timing delays to RTC accesses. Fixes hang when booting Ontrack Disk Manager. --- src/nvr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nvr.c b/src/nvr.c index 3a77f2c..4241c43 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -154,6 +154,8 @@ void nvr_onesec(void *p) void writenvr(uint16_t addr, uint8_t val, void *priv) { int c, old; + + cycles -= ISA_CYCLES(8); // printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins); if (addr&1) { @@ -218,6 +220,7 @@ 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); + cycles -= ISA_CYCLES(8); if (addr&1) { if (nvraddr == RTC_REGA) From b7193df5ac506ad39636db18a67ecffbe8735b8d Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 27 Feb 2018 21:59:09 +0000 Subject: [PATCH 0361/1050] Add meaningful process indicator to hard drive image creation. --- src/wx-config.c | 8 ++++++-- src/wx-utils.cc | 6 +++--- src/wx-utils.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/wx-config.c b/src/wx-config.c index 30b2dc7..6ddd6ef 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -1348,6 +1348,7 @@ static void update_hdd_cdrom(void* hdlg) } } +static volatile int create_drive_pos; static int create_drive(void* data) { int c; @@ -1355,7 +1356,10 @@ static int create_drive(void* data) FILE* f = (FILE*)data; memset(buf, 0, 512); for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) - fwrite(buf, 512, 1, f); + { + create_drive_pos = c; + fwrite(buf, 512, 1, f); + } fclose(f); @@ -1443,7 +1447,7 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l wx_messagebox(hdlg, "Can't open file for write", "PCem error", WX_MB_OK); return TRUE; } - wx_progressdialogpulse(hdlg, "PCem", "Creating drive, please wait...", create_drive, f); + wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive, f, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos); wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", WX_MB_OK); diff --git a/src/wx-utils.cc b/src/wx-utils.cc index e633373..6faa359 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -749,7 +749,7 @@ static void progress_callback(void* data) d->active = 0; } -int wx_progressdialogpulse(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data) +int wx_progressdialog(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data, int range, volatile int *pos) { struct progress_data_t pdata; pdata.callback = callback; @@ -759,10 +759,10 @@ int wx_progressdialogpulse(void* window, const char* title, const char* message, thread_t* t = thread_create(progress_callback, &pdata); - wxProgressDialog dlg(title, message, 100, (wxWindow*)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); + wxProgressDialog dlg(title, message, range, (wxWindow*)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); while (pdata.active) { - dlg.Pulse(); + dlg.Update(*pos); wxMilliSleep(50); } thread_kill(t); diff --git a/src/wx-utils.h b/src/wx-utils.h index f06b055..3a8a3a5 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -44,7 +44,7 @@ extern "C" { void* wx_getnativewindow(void* window); void wx_callback(void* window, WX_CALLBACK callback, void* data); void wx_togglewindow(void* window); - int wx_progressdialogpulse(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data); + int wx_progressdialog(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data, int range, volatile int *pos); void wx_enddialog(void* window, int ret_code); From 59aad3eaafd6a033bdfa12f643a36a26426dd534 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 27 Feb 2018 22:00:24 +0000 Subject: [PATCH 0362/1050] Support IDE hard drives up to 127 GB. --- src/ide.c | 5 ++++- src/wx-config.c | 14 ++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ide.c b/src/ide.c index 3f2b32e..3b738d7 100644 --- a/src/ide.c +++ b/src/ide.c @@ -164,7 +164,10 @@ static void ide_identify(IDE *ide) //ide->buffer[1] = 101; /* Cylinders */ - ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ + if ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >= 16514064) + ide->buffer[1] = 16383; + else + 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 */ diff --git a/src/wx-config.c b/src/wx-config.c index 6ddd6ef..e539185 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -19,6 +19,8 @@ #include "video.h" #include "vid_voodoo.h" +//#define MAX_CYLINDERS ((((1 << 28)-1) / 16) / 63) +#define MAX_CYLINDERS 265264 /*Award 430VX won't POST with a larger drive*/ extern int pause; extern int is486; @@ -1435,9 +1437,11 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l wx_messagebox(hdlg, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); return TRUE; } - if (hd_new_cyl > 16383) + if (hd_new_cyl > MAX_CYLINDERS) { - wx_messagebox(hdlg, "Drive has too many cylinders (maximum is 16383)", "PCem error", WX_MB_OK); + char s[256]; + sprintf(s, "Drive has too many cylinders (maximum is %i)", MAX_CYLINDERS); + wx_messagebox(hdlg, s, "PCem error", WX_MB_OK); return TRUE; } @@ -1577,9 +1581,11 @@ static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM wx_messagebox(hdlg,"Drive has too many heads (maximum is 16)","PCem error",WX_MB_OK); return TRUE; } - if (hd_new_cyl > 16383) + if (hd_new_cyl > MAX_CYLINDERS) { - wx_messagebox(hdlg,"Drive has too many cylinders (maximum is 16383)","PCem error",WX_MB_OK); + char s[256]; + sprintf(s, "Drive has too many cylinders (maximum is %i)", MAX_CYLINDERS); + wx_messagebox(hdlg,s,"PCem error",WX_MB_OK); return TRUE; } From b75c8376e620fd8ba82f120384809bfe4b2c60cc Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Feb 2018 18:38:45 +0000 Subject: [PATCH 0363/1050] Hard drive creation dialogue can now accept size in MB instead of/as well as specifying C/H/S settings. --- src/pc.xrc | 7 ++--- src/wx-config.c | 37 +++++++++++++++++++----- src/wx-resources.cpp | 68 +++++++++++++++++++++----------------------- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index 166cd0c..145996c 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -2274,7 +2274,7 @@ wxALIGN_CENTER_VERTICAL|wxALL 5 - + -1 @@ -2282,9 +2282,8 @@ wxALIGN_CENTER_VERTICAL|wxALL 5 - - - -1 + + diff --git a/src/wx-config.c b/src/wx-config.c index e539185..9a2b511 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -1376,6 +1376,7 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l PcemHDC hd[4]; FILE *f; int hd_type; + int size; switch (message) { @@ -1393,8 +1394,8 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)""); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "%imb", (((511*16*63)*512)/1024)/1024); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + sprintf(s, "%i", (((511*16*63)*512)/1024)/1024); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); // hd_type = 0; @@ -1481,8 +1482,8 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l pclog("EDIT3: %s\n", s); sscanf(s, "%i", &hd[0].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "%imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + sprintf(s, "%i", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); hd_type = 0; @@ -1499,7 +1500,29 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); return TRUE; - } else if (ID_IS("IDC_HDTYPE")) { + } + else if (ID_IS("IDC_EDIT4")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT4: %s\n", s); + sscanf(s, "%i", &size); + + hd[0].spt = 63; + hd[0].hpc = 16; + hd[0].tracks = (int)(((int64_t)size * 1024 * 1024) / (16 * 63 * 512)); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", 63); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", 16); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd[0].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } + else if (ID_IS("IDC_HDTYPE")) { h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); if (hd_type) @@ -1513,8 +1536,8 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"17"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "%imb", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + sprintf(s, "%i", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); } return TRUE; diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 9af6fee..cd0a5c4 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 132032; +static size_t xml_res_size_26 = 131989; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -6355,41 +6355,39 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, 116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,32,40,77,66,41,58,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,52,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,48,109,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, 65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, From 8d7a6c03eb19e944a5b878482a88cdfb3ab15ca9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Feb 2018 21:27:14 +0000 Subject: [PATCH 0364/1050] Fixed MDA/CGA switch on Xi8088. Patch from EluanCM. --- src/keyboard_at.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4cc899c..c2e8de8 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -604,7 +604,10 @@ void keyboard_at_reset() keyboard_at.mem[0] = 0x11; keyboard_at.wantirq = 0; keyboard_at.output_port = 0xcf; - keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; + if (romset == ROM_XI8088) + keyboard_at.input_port = (video_is_mda()) ? 0xb0 : 0xf0; + else + keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; keyboard_at.out_new = -1; keyboard_at.last_irq = 0; From c298e706a4765ea0e211bc20a3132e5c5095e14a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Feb 2018 21:36:15 +0000 Subject: [PATCH 0365/1050] Added flash size and turbo switches to Xi8088. Patch from EluanCM. --- src/mem.c | 19 +++++++++--- src/model.c | 3 +- src/xi8088.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/xi8088.h | 6 +++- 4 files changed, 101 insertions(+), 13 deletions(-) diff --git a/src/mem.c b/src/mem.c index 7b4de06..18bc37b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -17,6 +17,7 @@ #include "rom.h" #include "x86_ops.h" #include "codegen.h" +#include "xi8088.h" page_t *pages; page_t **page_lookup; @@ -901,11 +902,19 @@ int loadbios() case ROM_XI8088: f = romfopen("xi8088/bios-xi8088.bin", "rb"); /* use the bios without xt-ide because it's configurable in pcem */ if (!f) break; - /* high bit is flipped in xi8088 */ - romfread(rom + 0x10000, 0x10000, 1, f); - romfread(rom, 0x10000, 1, f); + if (xi8088_bios_128kb()) + { + /* high bit is flipped in xi8088 */ + romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom, 0x10000, 1, f); + biosmask = 0x1ffff; + } + else + { + /* smaller bios, more UMBs */ + romfread(rom, 0x10000, 1, f); + } fclose(f); - biosmask = 0x1ffff; return 1; } printf("Failed to load ROM!\n"); @@ -2189,7 +2198,7 @@ void mem_set_mem_state(uint32_t base, uint32_t size, int state) void mem_add_bios() { - if (AT) + if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) { mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL, 0); mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL, 0); diff --git a/src/model.c b/src/model.c index df90f94..630387b 100644 --- a/src/model.c +++ b/src/model.c @@ -128,7 +128,7 @@ MODEL models[] = {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}, {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, &t1000_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}, - {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, NULL}, + {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, @@ -378,7 +378,6 @@ void xt_xi8088_init() nvr_init(); pic2_init(); device_add(&gameport_device); - xi8088_init(); } void at_init() diff --git a/src/xi8088.c b/src/xi8088.c index ad04e7e..d4b7930 100644 --- a/src/xi8088.c +++ b/src/xi8088.c @@ -5,16 +5,27 @@ #include "xi8088.h" -static uint8_t xi8088_turbo; +typedef struct xi8088_t +{ + uint8_t turbo; + + int turbo_setting; + int bios_128kb; +} xi8088_t; + +static xi8088_t xi8088; uint8_t xi8088_turbo_get() { - return xi8088_turbo; + return xi8088.turbo; } void xi8088_turbo_set(uint8_t value) { - xi8088_turbo = value; + if (!xi8088.turbo_setting) + return; + + xi8088.turbo = value; if (!value) { pclog("Xi8088 turbo off\n"); @@ -30,7 +41,72 @@ void xi8088_turbo_set(uint8_t value) } } -void xi8088_init() +int xi8088_bios_128kb() { - xi8088_turbo = 1; + return xi8088.bios_128kb; } + +static void *xi8088_init() +{ + /* even though the bios by default turns the turbo off when controlling by hotkeys, pcem always starts at full speed */ + xi8088.turbo = 1; + xi8088.turbo_setting = device_get_config_int("turbo_setting"); + xi8088.bios_128kb = device_get_config_int("bios_128kb"); + + return &xi8088; +} + +static device_config_t xi8088_config[] = +{ + { + .name = "turbo_setting", + .description = "Turbo", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Always at selected speed", + .value = 0 + }, + { + .description = "Hotkeys (starts off)", + .value = 1 + } + }, + .default_int = 0 + }, + { + .name = "bios_128kb", + .description = "BIOS size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "64KB", + .value = 0 + }, + { + .description = "128KB", + .value = 1 + } + }, + .default_int = 1 + }, + { + .type = -1 + } +}; + + +device_t xi8088_device = +{ + "Xi8088", + 0, + xi8088_init, + NULL, + NULL, + NULL, + NULL, + NULL, + xi8088_config +}; diff --git a/src/xi8088.h b/src/xi8088.h index ef40e19..54178da 100644 --- a/src/xi8088.h +++ b/src/xi8088.h @@ -1,3 +1,7 @@ +#include "device.h" + +extern device_t xi8088_device; + uint8_t xi8088_turbo_get(); void xi8088_turbo_set(uint8_t value); -void xi8088_init(); +int xi8088_bios_128kb(); From 0d36eeaabed3312bb9d73c3d8e40ea3da0d9b088 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Mar 2018 21:54:20 +0000 Subject: [PATCH 0366/1050] SCSI now supports 7 devices. Reworked hard drive / CD-ROM / Zip configuration functions a bit. --- src/hdd.c | 52 +- src/hdd.h | 3 + src/ibm.h | 2 +- src/ide.c | 4 +- src/ide.h | 2 +- src/pc.c | 30 + src/pc.xrc | 2091 ++++++++++++------- src/scsi.c | 2 +- src/wx-config.c | 1000 ++++----- src/wx-resources.cpp | 4741 ++++++++++++++++++++++-------------------- src/wx-sdl2-status.c | 2 +- src/wx-utils.cc | 25 + src/wx-utils.h | 8 + 13 files changed, 4283 insertions(+), 3679 deletions(-) diff --git a/src/hdd.c b/src/hdd.c index b4f2dff..f2a9fd7 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -24,23 +24,24 @@ static struct device_t *device; int is_mfm; int is_ide; + int is_scsi; } hdd_controllers[] = { - {"None", "none", &null_hdd_device, 0, 0}, - {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1, 0}, - {"[MFM] DTC 5150X", "dtc5150x", &dtc_5150x_device, 1, 0}, - {"[MFM] Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1, 0}, - {"[ESDI] IBM ESDI Fixed Disk Controller", "esdi_mca", &hdd_esdi_device, 1, 0}, - {"[ESDI] Western Digital WD1007V-SE1", "wd1007vse1", &wd1007vse1_device, 0, 0}, - {"[IDE] Standard IDE", "ide", &ide_device, 0, 1}, - {"[IDE] XTIDE", "xtide", &xtide_device, 0, 1}, - {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0, 1}, - {"[IDE] XTIDE (PS/1)", "xtide_ps1", &xtide_ps1_device, 0, 1}, - {"[SCSI] Adaptec AHA-1542C", "aha1542c", &scsi_aha1542c_device, 0, 0}, - {"[SCSI] BusLogic BT-545S", "bt545s", &scsi_bt545s_device, 0, 0}, - {"[SCSI] Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device, 0, 0}, - {"[SCSI] Rancho RT1000B", "rt1000b", &scsi_rt1000b_device, 0, 0}, - {"[SCSI] Trantor T130B", "t130b", &scsi_t130b_device, 0, 0}, + {"None", "none", &null_hdd_device, 0, 0, 0}, + {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1, 0, 0}, + {"[MFM] DTC 5150X", "dtc5150x", &dtc_5150x_device, 1, 0, 0}, + {"[MFM] Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1, 0, 0}, + {"[ESDI] IBM ESDI Fixed Disk Controller", "esdi_mca", &hdd_esdi_device, 1, 0, 0}, + {"[ESDI] Western Digital WD1007V-SE1", "wd1007vse1", &wd1007vse1_device, 0, 0, 0}, + {"[IDE] Standard IDE", "ide", &ide_device, 0, 1, 0}, + {"[IDE] XTIDE", "xtide", &xtide_device, 0, 1, 0}, + {"[IDE] XTIDE (AT)", "xtide_at", &xtide_at_device, 0, 1, 0}, + {"[IDE] XTIDE (PS/1)", "xtide_ps1", &xtide_ps1_device, 0, 1, 0}, + {"[SCSI] Adaptec AHA-1542C", "aha1542c", &scsi_aha1542c_device, 0, 0, 1}, + {"[SCSI] BusLogic BT-545S", "bt545s", &scsi_bt545s_device, 0, 0, 1}, + {"[SCSI] Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device, 0, 0, 1}, + {"[SCSI] Rancho RT1000B", "rt1000b", &scsi_rt1000b_device, 0, 0, 1}, + {"[SCSI] Trantor T130B", "t130b", &scsi_t130b_device, 0, 0, 1}, {"", "", NULL, 0, 0} }; @@ -98,6 +99,23 @@ int hdd_controller_is_ide(char *internal_name) return 0; } +int hdd_controller_is_scsi(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")) + return hdd_controllers[c].is_scsi; + } + c++; + } + + return 0; +} int hdd_controller_has_config(char *internal_name) { int c = 0; @@ -142,6 +160,10 @@ int hdd_controller_current_is_ide() { return hdd_controller_is_ide(hdd_controller_name); } +int hdd_controller_current_is_scsi() +{ + return hdd_controller_is_scsi(hdd_controller_name); +} void hdd_controller_init(char *internal_name) { diff --git a/src/hdd.h b/src/hdd.h index 65e1989..47a02c0 100644 --- a/src/hdd.h +++ b/src/hdd.h @@ -5,10 +5,13 @@ char *hdd_controller_get_internal_name(int hdd); int hdd_controller_get_flags(int hdd); int hdd_controller_available(int hdd); int hdd_controller_is_mfm(char* internal_name); +int hdd_controller_is_ide(char *internal_name); +int hdd_controller_is_scsi(char *internal_name); int hdd_controller_has_config(char *internal_name); device_t *hdd_controller_get_device(char *internal_name); int hdd_controller_current_is_mfm(); int hdd_controller_current_is_ide(); +int hdd_controller_current_is_scsi(); void hdd_controller_init(char *internal_name); extern char hdd_controller_name[16]; diff --git a/src/ibm.h b/src/ibm.h index 97b661c..be6c68a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -548,7 +548,7 @@ typedef struct int tracks; } PcemHDC; -PcemHDC hdc[4]; +PcemHDC hdc[7]; /*Keyboard*/ int keybsenddelay; diff --git a/src/ide.c b/src/ide.c index 3b738d7..0661db5 100644 --- a/src/ide.c +++ b/src/ide.c @@ -87,11 +87,11 @@ typedef struct IDE int cdrom_channel = 2; int zip_channel = -1; -IDE ide_drives[4]; +IDE ide_drives[7]; IDE *ext_ide; -char ide_fn[4][512]; +char ide_fn[7][512]; int (*ide_bus_master_read_sector)(int channel, uint8_t *data); int (*ide_bus_master_write_sector)(int channel, uint8_t *data); diff --git a/src/ide.h b/src/ide.h index 3775f51..3389c4d 100644 --- a/src/ide.h +++ b/src/ide.h @@ -24,7 +24,7 @@ extern int ideboard; extern int idecallback[2]; -extern char ide_fn[4][512]; +extern char ide_fn[7][512]; extern int cdrom_channel, zip_channel; diff --git a/src/pc.c b/src/pc.c index 2e916de..a12a56f 100644 --- a/src/pc.c +++ b/src/pc.c @@ -757,6 +757,24 @@ void loadconfig(char *fn) p = (char *)config_get_string(CFG_MACHINE, NULL, "hdf_fn", ""); if (p) strcpy(ide_fn[3], p); else strcpy(ide_fn[3], ""); + hdc[4].spt = config_get_int(CFG_MACHINE, NULL, "hdg_sectors", 0); + hdc[4].hpc = config_get_int(CFG_MACHINE, NULL, "hdg_heads", 0); + hdc[4].tracks = config_get_int(CFG_MACHINE, NULL, "hdg_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdg_fn", ""); + if (p) strcpy(ide_fn[4], p); + else strcpy(ide_fn[4], ""); + hdc[5].spt = config_get_int(CFG_MACHINE, NULL, "hdh_sectors", 0); + hdc[5].hpc = config_get_int(CFG_MACHINE, NULL, "hdh_heads", 0); + hdc[5].tracks = config_get_int(CFG_MACHINE, NULL, "hdh_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdh_fn", ""); + if (p) strcpy(ide_fn[5], p); + else strcpy(ide_fn[5], ""); + hdc[6].spt = config_get_int(CFG_MACHINE, NULL, "hdi_sectors", 0); + hdc[6].hpc = config_get_int(CFG_MACHINE, NULL, "hdi_heads", 0); + hdc[6].tracks = config_get_int(CFG_MACHINE, NULL, "hdi_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdi_fn", ""); + if (p) strcpy(ide_fn[6], p); + else strcpy(ide_fn[6], ""); fdd_set_type(0, config_get_int(CFG_MACHINE, NULL, "drive_a_type", 7)); fdd_set_type(1, config_get_int(CFG_MACHINE, NULL, "drive_b_type", 7)); @@ -890,6 +908,18 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "hdf_heads", hdc[3].hpc); config_set_int(CFG_MACHINE, NULL, "hdf_cylinders", hdc[3].tracks); config_set_string(CFG_MACHINE, NULL, "hdf_fn", ide_fn[3]); + config_set_int(CFG_MACHINE, NULL, "hdg_sectors", hdc[4].spt); + config_set_int(CFG_MACHINE, NULL, "hdg_heads", hdc[4].hpc); + config_set_int(CFG_MACHINE, NULL, "hdg_cylinders", hdc[4].tracks); + config_set_string(CFG_MACHINE, NULL, "hdg_fn", ide_fn[4]); + config_set_int(CFG_MACHINE, NULL, "hdh_sectors", hdc[5].spt); + config_set_int(CFG_MACHINE, NULL, "hdh_heads", hdc[5].hpc); + config_set_int(CFG_MACHINE, NULL, "hdh_cylinders", hdc[5].tracks); + config_set_string(CFG_MACHINE, NULL, "hdh_fn", ide_fn[5]); + config_set_int(CFG_MACHINE, NULL, "hdi_sectors", hdc[6].spt); + config_set_int(CFG_MACHINE, NULL, "hdi_heads", hdc[6].hpc); + config_set_int(CFG_MACHINE, NULL, "hdi_cylinders", hdc[6].tracks); + config_set_string(CFG_MACHINE, NULL, "hdi_fn", ide_fn[6]); config_set_int(CFG_MACHINE, NULL, "drive_a_type", fdd_get_type(0)); config_set_int(CFG_MACHINE, NULL, "drive_b_type", fdd_get_type(1)); diff --git a/src/pc.xrc b/src/pc.xrc index 145996c..cd9b6d6 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -444,7 +444,7 @@ 1 - + @@ -483,7 +483,7 @@ - + @@ -1141,776 +1141,8 @@ wxEXPAND | wxALL 5 - + - - - 1 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - 0 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - 0 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - - - - 0 - - - - 0 - 3 - 0 - 0 - 2 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - 75,-1 - - -1 - - - - - wxEXPAND - 5 - - wxHORIZONTAL - - - wxALL - 5 - - - 350,-1 - - - - - - - wxEXPAND - 5 - 0,0 - - - - wxALL - 5 - - New - icons/16x16/drive_add.png - 0 - - - - - - - wxALL - 5 - - Browse - icons/16x16/folder.png - 0 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL|wxEXPAND - 5 - - - 350,-1 - - - - - - wxALL - 5 - - icons/16x16/control_eject.png - Eject - 0 - - - - - wxEXPAND - 5 - 0,0 - - - - wxEXPAND - 5 - - 0 - 4 - 0 - 0 - 1,3 - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - -1 - - - - - wxALL | wxALIGN_CENTER_VERTICAL - 5 - - - - - - - - - wxEXPAND - 5 - 0,0 - - - - @@ -2146,6 +1378,1323 @@ + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + + + + 0 + 3 + 0 + 0 + 2 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 75,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL + 5 + + New + icons/16x16/drive_add.png + 0 + + + + + + + wxALL + 5 + + Browse + icons/16x16/folder.png + 0 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL|wxEXPAND + 5 + + + 350,-1 + + + + + + wxALL + 5 + + icons/16x16/control_eject.png + Eject + 0 + + + + + wxEXPAND + 5 + 0,0 + + + + wxEXPAND + 5 + + 0 + 4 + 0 + 0 + 1,3 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + + wxEXPAND + 5 + 0,0 + + diff --git a/src/scsi.c b/src/scsi.c index ba207bc..09b53b7 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -343,7 +343,7 @@ void scsi_bus_init(scsi_bus_t *bus) memset(bus->devices, 0, sizeof(bus->devices)); memset(bus->device_data, 0, sizeof(bus->device_data)); - for (c = 0; c < 4; c++) + for (c = 0; c < 7; c++) { if (cdrom_channel == c) bus->devices[c] = &scsi_cd; diff --git a/src/wx-config.c b/src/wx-config.c index 9a2b511..fbe9bc9 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -185,6 +185,7 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for int valid = 0; char old_name[16]; int c, d; + int hdd_type; h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); @@ -248,11 +249,80 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for wx_enablewindow(h, TRUE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); if (hdd_controller_selected_has_config(hdlg)) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + hdd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDCBOOK")); + + while (wx_sendmessage(h, WX_CHB_GETPAGECOUNT, 0, 0)) + wx_sendmessage(h, WX_CHB_REMOVEPAGE, 0, 0); + + for (c = 0; c < 7; c++) + { + void *page; + char s[80]; + + sprintf(s, "IDC_HDPANEL[%i]", c); + + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + wx_sendmessage(h, WX_CHB_ADDPAGE, (LONG_PARAM)page, (LONG_PARAM)"dummy name"); + } + if (hdd_controller_is_scsi(hdd_names[hdd_type])) + { + for (c = 0; c < 7; c++) + { + void *page; + char s[80]; + + sprintf(s, "IDC_HDPANEL[%i]", c); + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + sprintf(s, "SCSI ID %i (%c:)", c, 'C'+c); + wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); + } + } + else if (hdd_controller_is_ide(hdd_names[hdd_type])) + { + for (c = 0; c < 4; c++) + { + void *page; + char s[80]; + + sprintf(s, "IDC_HDPANEL[%i]", c); + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + sprintf(s, "Drive %i %s %s (%c:)", c, (c & 2) ? "Secondary" : "Primary", (c & 1) ? "Slave" : "Master", 'C'+c); + wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); + } + for (c = 6; c >= 4; c--) + { + wx_sendmessage(h, WX_CHB_REMOVEPAGE, c, 0); + } + } + else + { + for (c = 0; c < 2; c++) + { + void *page; + char s[80]; + + sprintf(s, "IDC_HDPANEL[%i]", c); + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + sprintf(s, "Drive %i %s (%c:)", c, (c & 1) ? "Secondary" : "Primary", 'C'+c); + wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); + } + for (c = 6; c >= 2; c--) + { + wx_sendmessage(h, WX_CHB_REMOVEPAGE, c, 0); + } + } } #ifdef USE_NETWORKING @@ -319,7 +389,7 @@ int config_dlgsave(void* hdlg) #endif int hdd_changed = 0; char s[260]; - PcemHDC hd[4]; + PcemHDC hd[7]; h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; @@ -432,58 +502,26 @@ int config_dlgsave(void* hdlg) else strcpy(hdd_controller_name, "none"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[0]); + for (c = 0; c < 7; c++) + { + sprintf(s, "IDC_EDIT_SPT[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[c].spt); + sprintf(s, "IDC_EDIT_HPC[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[c].hpc); + sprintf(s, "IDC_EDIT_CYL[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[c].tracks); + sprintf(s, "IDC_EDIT_FN[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[c]); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[1]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[2]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[3]); - - hdc[0] = hd[0]; - hdc[1] = hd[1]; - hdc[2] = hd[2]; - hdc[3] = hd[3]; + hdc[c] = hd[c]; + } cdrom_channel = new_cdrom_channel; zip_channel = new_zip_channel; @@ -768,47 +806,23 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) new_zip_channel = zip_channel; hdconf_init(hdlg); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[0]")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); - if (cdrom_channel == 0) - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - else if (zip_channel == 0) - wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[1]")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); - if (cdrom_channel == 1) - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - else if (zip_channel == 1) - wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[2]")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); - if (cdrom_channel == 2) - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - else if (zip_channel == 2) - wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[3]")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); - if (cdrom_channel == 3) - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - else if (zip_channel == 3) - wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + for (c = 0; c < 7; c++) + { + char s[80]; + + sprintf(s, "IDC_COMBODRIVETYPE[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); + if (cdrom_channel == c) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (zip_channel == c) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + } #ifdef USE_NETWORKING recalc_net_list(hdlg, romstomodel[romset]); @@ -1097,6 +1111,10 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_COMBOHDD")) { hdconf_update(hdlg); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + recalc_hdd_list(hdlg, temp_model, 1, 0); } else if (wParam == WX_ID("IDC_CONFIGUREHDD")) { @@ -1314,7 +1332,7 @@ static void update_hdd_cdrom(void* hdlg) int is_mfm = hdd_controller_selected_is_mfm(hdlg); - for (i = 0; i < 4; ++i) + for (i = 0; i < 7; ++i) { b = !is_mfm && ((new_cdrom_channel == i) || (new_zip_channel == i)); pclog("update_hdd_cdrom: i=%i b=%i new_cdrom_channel=%i new_zip_channel=%i\n", i, b, new_cdrom_channel, new_zip_channel); @@ -1373,7 +1391,7 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l char s[260]; void* h; int c; - PcemHDC hd[4]; + PcemHDC hd[7]; FILE *f; int hd_type; int size; @@ -1640,78 +1658,35 @@ static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM int hdconf_init(void* hdlg) { - char s[260]; - void* h; - PcemHDC hd[4]; + int c; + + for (c = 0; c < 7; c++) + { + char s[260]; + void *h; + + sprintf(s, "IDC_EDIT_SPT[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%i", hdc[c].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_EDIT_HPC[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%i", hdc[c].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_EDIT_CYL[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%i", hdc[c].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_EDIT_FN[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[c]); - hd[0] = hdc[0]; - hd[1] = hdc[1]; - hd[2] = hdc[2]; - hd[3] = hdc[3]; + sprintf(s, "IDC_TEXT_SIZE[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%imb", (int)(((((uint64_t)hdc[c].tracks*(uint64_t)hdc[c].hpc)*(uint64_t)hdc[c].spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - sprintf(s, "%i", hdc[0].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - sprintf(s, "%i", hdc[0].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - sprintf(s, "%i", hdc[0].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[0]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - sprintf(s, "%i", hdc[1].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - sprintf(s, "%i", hdc[1].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - sprintf(s, "%i", hdc[1].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[1]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - sprintf(s, "%i", hdc[2].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - sprintf(s, "%i", hdc[2].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - sprintf(s, "%i", hdc[2].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[2]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - sprintf(s, "%i", hdc[3].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - sprintf(s, "%i", hdc[3].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - sprintf(s, "%i", hdc[3].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h= wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[3]); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd[1].tracks*(uint64_t)hd[1].hpc)*(uint64_t)hd[1].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd[2].tracks*(uint64_t)hd[2].hpc)*(uint64_t)hd[2].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd[3].tracks*(uint64_t)hd[3].hpc)*(uint64_t)hd[3].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } return hdconf_update(hdlg); } @@ -1726,7 +1701,7 @@ int hdconf_update(void* hdlg) update_hdd_cdrom(hdlg); int i; - for (i = 0; i < 4; ++i) + for (i = 0; i < 7; ++i) { sprintf(s, "IDC_HDD_LABEL[%d]", i*10); wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); @@ -1744,13 +1719,170 @@ int hdconf_update(void* hdlg) return TRUE; } +static int hd_eject(void *hdlg, int drive) +{ + char s[80]; + + ide_fn[drive][0] = 0; + sprintf(s, "IDC_EDIT_SPT[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), "0"); + sprintf(s, "IDC_EDIT_HPC[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), "0"); + sprintf(s, "IDC_EDIT_CYL[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), "0"); + sprintf(s, "IDC_EDIT_FN[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), ""); + hd_changed = 1; + + return TRUE; +} + +static int hd_new(void *hdlg, int drive) +{ + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) + { + char s[80]; + char id[80]; + void *h; + + sprintf(id, "IDC_EDIT_SPT[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_HPC[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_CYL[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_FN[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + + sprintf(id, "IDC_TEXT_SIZE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + return TRUE; +} + +static int hd_file(void *hdlg, int drive) +{ + if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + { + off64_t sz; + FILE *f = fopen64(openfilestring, "rb"); + if (!f) + { + wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); + return TRUE; + } + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) + { + char s[80]; + char id[80]; + void *h; + + sprintf(id, "IDC_EDIT_SPT[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_HPC[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_CYL[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_FN[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + + sprintf(id, "IDC_TEXT_SIZE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + hd_changed = 1; + } + } + return TRUE; +} + +static int hd_edit(void *hdlg, int drive) +{ + char s[80]; + char id[80]; + void *h; + int spt, hpc, tracks; + + sprintf(id, "IDC_EDIT_SPT[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &spt); + sprintf(id, "IDC_EDIT_HPC[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hpc); + sprintf(id, "IDC_EDIT_CYL[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &tracks); + + sprintf(id, "IDC_TEXT_SIZE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%imb", ((((tracks*hpc)*spt)*512)/1024)/1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + + return TRUE; +} + +static int hd_combodrivetype(void *hdlg, int drive) +{ + int type; + char id[80]; + void *h; + + sprintf(id, "IDC_COMBODRIVETYPE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + switch (type) + { + case 0: /*Hard drive*/ + if (new_cdrom_channel == drive) + new_cdrom_channel = -1; + if (new_zip_channel == drive) + new_zip_channel = -1; + break; + case 1: /*CD-ROM*/ + new_cdrom_channel = drive; + if (new_zip_channel == drive) + new_zip_channel = -1; + break; + case 2: /*Zip*/ + new_zip_channel = drive; + if (new_cdrom_channel == drive) + new_cdrom_channel = -1; + break; + } + update_hdd_cdrom(hdlg); + return TRUE; +} + int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - char s[260]; - void* h; - PcemHDC hd[4]; - FILE *f; - off64_t sz; switch (message) { case WX_INITDIALOG: @@ -1759,487 +1891,75 @@ int hdconf_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) case WX_COMMAND: if (ID_IS("IDC_EJECT[0]")) - { - hd[0].spt = 0; - hd[0].hpc = 0; - hd[0].tracks = 0; - ide_fn[0][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[0]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[0]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[0]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[0]"), ""); - hd_changed = 1; - return TRUE; - } else if (ID_IS("IDC_EJECT[1]")) - { - hd[1].spt = 0; - hd[1].hpc = 0; - hd[1].tracks = 0; - ide_fn[1][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[1]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[1]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[1]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[1]"), ""); - hd_changed = 1; - return TRUE; - } else if (ID_IS("IDC_EJECT[2]")) - { - hd[2].spt = 0; - hd[2].hpc = 0; - hd[2].tracks = 0; - ide_fn[2][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[2]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[2]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[2]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[2]"), ""); - hd_changed = 1; - return TRUE; - } else if (ID_IS("IDC_EJECT[3]")) - { - hd[3].spt = 0; - hd[3].hpc = 0; - hd[3].tracks = 0; - ide_fn[3][0] = 0; - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_SPT[3]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_HPC[3]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_CYL[3]"), "0"); - wx_setdlgitemtext(hdlg, WX_ID("IDC_EDIT_FN[3]"), ""); - hd_changed = 1; - return TRUE; - } + return hd_eject(hdlg, 0); + else if (ID_IS("IDC_EJECT[1]")) + return hd_eject(hdlg, 1); + else if (ID_IS("IDC_EJECT[2]")) + return hd_eject(hdlg, 2); + else if (ID_IS("IDC_EJECT[3]")) + return hd_eject(hdlg, 3); + else if (ID_IS("IDC_EJECT[4]")) + return hd_eject(hdlg, 4); + else if (ID_IS("IDC_EJECT[5]")) + return hd_eject(hdlg, 5); + else if (ID_IS("IDC_EJECT[6]")) + return hd_eject(hdlg, 6); else if (ID_IS("IDC_NEW[0]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[0]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(hdlg, sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[0]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - - } + return hd_new(hdlg, 0); else if (ID_IS("IDC_NEW[1]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[1]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(hdlg, sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[1]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - } + return hd_new(hdlg, 1); else if (ID_IS("IDC_NEW[2]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } - else if (ID_IS("IDC_FILE[2]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(hdlg, sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[2]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - } + return hd_new(hdlg, 2); else if (ID_IS("IDC_NEW[3]")) - { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - - h= wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - return TRUE; - } + return hd_new(hdlg, 3); + else if (ID_IS("IDC_NEW[4]")) + return hd_new(hdlg, 4); + else if (ID_IS("IDC_NEW[5]")) + return hd_new(hdlg, 5); + else if (ID_IS("IDC_NEW[6]")) + return hd_new(hdlg, 6); + else if (ID_IS("IDC_FILE[0]")) + return hd_file(hdlg, 0); + else if (ID_IS("IDC_FILE[1]")) + return hd_file(hdlg, 1); + else if (ID_IS("IDC_FILE[2]")) + return hd_file(hdlg, 2); else if (ID_IS("IDC_FILE[3]")) - { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(hdlg, sz); - - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_FN[3]")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; - } + return hd_file(hdlg, 3); + else if (ID_IS("IDC_FILE[4]")) + return hd_file(hdlg, 4); + else if (ID_IS("IDC_FILE[5]")) + return hd_file(hdlg, 5); + else if (ID_IS("IDC_FILE[6]")) + return hd_file(hdlg, 6); else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[0]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[0]")); - sprintf(s, "%imb", ((((hd[0].tracks*hd[0].hpc)*hd[0].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } + return hd_edit(hdlg, 0); else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[1]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[1].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[1]")); - sprintf(s, "%imb", ((((hd[1].tracks*hd[1].hpc)*hd[1].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } + return hd_edit(hdlg, 1); else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[2]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[2].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[2]")); - sprintf(s, "%imb", ((((hd[2].tracks*hd[2].hpc)*hd[2].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } + return hd_edit(hdlg, 2); else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_SPT[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_HPC[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT_CYL[3]")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[3].tracks); - - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_SIZE[3]")); - sprintf(s, "%imb", ((((hd[3].tracks*hd[3].hpc)*hd[3].spt)*512)/1024)/1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } + return hd_edit(hdlg, 3); + else if (ID_IS("IDC_EDIT_SPT[4]") || ID_IS("IDC_EDIT_HPC[4]") || ID_IS("IDC_EDIT_CYL[4]")) + return hd_edit(hdlg, 4); + else if (ID_IS("IDC_EDIT_SPT[5]") || ID_IS("IDC_EDIT_HPC[5]") || ID_IS("IDC_EDIT_CYL[5]")) + return hd_edit(hdlg, 5); + else if (ID_IS("IDC_EDIT_SPT[6]") || ID_IS("IDC_EDIT_HPC[6]") || ID_IS("IDC_EDIT_CYL[6]")) + return hd_edit(hdlg, 6); else if (ID_IS("IDC_COMBODRIVETYPE[0]")) - { - int type; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[0]")); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - - switch (type) - { - case 0: /*Hard drive*/ - if (new_cdrom_channel == 0) - new_cdrom_channel = -1; - if (new_zip_channel == 0) - new_zip_channel = -1; - break; - case 1: /*CD-ROM*/ - new_cdrom_channel = 0; - if (new_zip_channel == 0) - new_zip_channel = -1; - break; - case 2: /*Zip*/ - new_zip_channel = 0; - if (new_cdrom_channel == 0) - new_cdrom_channel = -1; - break; - } - update_hdd_cdrom(hdlg); - return TRUE; - } + return hd_combodrivetype(hdlg, 0); else if (ID_IS("IDC_COMBODRIVETYPE[1]")) - { - int type; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[1]")); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - - switch (type) - { - case 0: /*Hard drive*/ - if (new_cdrom_channel == 1) - new_cdrom_channel = -1; - if (new_zip_channel == 1) - new_zip_channel = -1; - break; - case 1: /*CD-ROM*/ - new_cdrom_channel = 1; - if (new_zip_channel == 1) - new_zip_channel = -1; - break; - case 2: /*Zip*/ - new_zip_channel = 1; - if (new_cdrom_channel == 1) - new_cdrom_channel = -1; - break; - } - update_hdd_cdrom(hdlg); - return TRUE; - } + return hd_combodrivetype(hdlg, 1); else if (ID_IS("IDC_COMBODRIVETYPE[2]")) - { - int type; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[2]")); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - - switch (type) - { - case 0: /*Hard drive*/ - if (new_cdrom_channel == 2) - new_cdrom_channel = -1; - if (new_zip_channel == 2) - new_zip_channel = -1; - break; - case 1: /*CD-ROM*/ - new_cdrom_channel = 2; - if (new_zip_channel == 2) - new_zip_channel = -1; - break; - case 2: /*Zip*/ - new_zip_channel = 2; - if (new_cdrom_channel == 2) - new_cdrom_channel = -1; - break; - } - update_hdd_cdrom(hdlg); - return TRUE; - } + return hd_combodrivetype(hdlg, 2); else if (ID_IS("IDC_COMBODRIVETYPE[3]")) - { - int type; - - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRIVETYPE[3]")); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - - switch (type) - { - case 0: /*Hard drive*/ - if (new_cdrom_channel == 3) - new_cdrom_channel = -1; - if (new_zip_channel == 3) - new_zip_channel = -1; - break; - case 1: /*CD-ROM*/ - new_cdrom_channel = 3; - if (new_zip_channel == 3) - new_zip_channel = -1; - break; - case 2: /*Zip*/ - new_zip_channel = 3; - if (new_cdrom_channel == 3) - new_cdrom_channel = -1; - break; - } - update_hdd_cdrom(hdlg); - return TRUE; - } + return hd_combodrivetype(hdlg, 3); + else if (ID_IS("IDC_COMBODRIVETYPE[4]")) + return hd_combodrivetype(hdlg, 4); + else if (ID_IS("IDC_COMBODRIVETYPE[5]")) + return hd_combodrivetype(hdlg, 5); + else if (ID_IS("IDC_COMBODRIVETYPE[6]")) + return hd_combodrivetype(hdlg, 6); } return FALSE; } diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index cd0a5c4..f685b0b 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -668,113 +668,8 @@ static unsigned char xml_res_file_11[] = { 255,36,196,176,169,253,53,171,1,84,185,253,19,96,0,249,4,138,17,171,4,193, 66,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_12 = 634; +static size_t xml_res_size_12 = 1507; static unsigned char xml_res_file_12[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,28,73,68,65,84,120,218,140,146,205,107,19,65,24,135,159,217,221,144, -108,194,162,104,244,80,177,181,136,32,130,7,169,90,240,82,197,34,86,91, -47,90,68,122,240,31,240,32,166,135,10,122,18,145,106,251,23,136,246,224, -65,76,27,15,106,81,36,82,5,123,144,106,148,94,10,173,45,181,133,32,10,37, -181,77,52,217,143,113,38,9,82,37,196,188,48,187,204,204,251,252,222,175, -17,119,239,141,224,251,1,134,33,80,38,195,225,48,245,172,88,44,234,159, -8,2,137,105,26,88,122,23,4,129,22,145,61,221,167,89,252,178,84,87,96,87, -75,51,79,159,141,75,33,12,161,5,12,13,151,92,87,158,233,233,86,240,178, -22,71,136,218,75,223,105,31,237,171,25,205,90,190,239,39,47,246,93,192, -245,60,246,238,217,77,67,166,196,52,243,48,57,154,180,60,207,235,93,93, -91,231,249,139,151,213,91,249,63,186,252,237,58,121,2,205,234,12,40,150, -138,216,81,155,206,99,71,21,47,171,62,226,31,76,84,191,130,244,196,107, -93,2,129,95,41,1,183,228,18,181,35,120,234,112,42,243,241,79,189,149,108, -53,98,98,138,48,66,134,56,220,214,198,166,216,118,112,67,200,64,160,74, -240,209,34,145,136,77,110,109,149,120,124,107,85,160,18,87,245,154,144, -112,72,103,175,146,89,121,194,253,113,117,106,64,71,248,60,120,93,149,12, -116,55,99,177,40,179,179,159,55,192,58,186,158,115,148,169,31,215,200,57, -105,78,29,129,246,29,9,222,101,135,153,158,123,68,200,254,134,165,97,211, -178,112,28,167,188,254,110,182,138,142,195,131,76,154,227,205,176,94,128, -253,91,134,120,53,55,204,62,181,127,155,155,192,202,231,243,111,82,169, -199,29,82,202,26,253,86,181,7,14,102,11,28,106,234,231,96,211,157,242,249, -229,118,201,135,236,0,147,159,6,203,157,210,195,223,92,111,112,125,35,188, -63,208,10,5,23,174,119,74,110,164,5,209,16,76,47,128,117,243,214,237,249, -90,209,193,80,209,109,102,90,47,81,248,202,216,124,152,115,59,227,48,185, -56,128,165,220,23,178,240,115,133,148,85,247,205,72,83,141,14,198,18,36, -122,135,16,249,95,156,157,89,30,212,15,177,12,143,246,115,69,208,184,169, -182,177,109,195,254,187,90,75,162,118,250,141,219,111,1,6,0,80,239,219, -105,146,138,192,9,0,0,0,0,73,69,78,68,174,66,96,130}; - -static size_t xml_res_size_13 = 632; -static unsigned char xml_res_file_13[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,26,73,68,65,84,120,218,164,83,61,111,19,65,16,125,179,187,103,7,131, -81,8,4,10,155,68,20,72,161,224,67,73,68,75,19,104,41,40,144,16,162,129, -34,5,13,255,0,209,210,128,132,172,132,134,6,148,54,13,66,164,65,66,162, -76,224,226,2,100,36,7,35,36,155,96,130,125,150,239,156,203,221,46,179,119, -206,23,208,32,143,116,186,189,157,153,247,102,222,204,145,49,6,131,152, -192,128,166,202,243,51,139,58,10,175,26,29,39,23,36,36,72,170,50,145,56, -199,95,251,163,169,127,67,132,109,159,178,201,231,103,159,1,91,81,26,36, -37,86,158,220,56,203,32,134,232,15,0,78,34,33,32,84,230,19,19,157,73,0, -140,214,156,188,137,176,242,16,198,16,156,194,53,76,206,62,231,230,250, -201,22,100,27,200,190,148,130,91,186,53,33,73,76,241,253,178,74,28,166, -203,142,3,236,151,136,214,95,241,197,203,36,150,24,196,196,26,65,199,239, -151,110,144,41,92,231,120,131,142,31,94,204,31,204,90,0,118,197,62,132, -51,196,71,105,139,220,97,214,172,75,229,157,139,160,213,177,44,236,225, -137,209,125,8,169,144,115,156,18,235,246,32,5,160,77,75,135,160,29,32,233, -59,165,67,109,165,130,209,177,17,28,191,89,2,18,145,77,250,88,191,147,129, -59,119,251,152,178,101,34,242,240,249,173,139,238,47,111,87,47,214,99,124, -234,52,142,20,142,98,171,250,136,171,214,73,233,22,64,230,138,8,197,4,154, -237,112,73,89,102,191,190,198,202,2,211,247,22,184,157,184,175,150,68,252, -181,4,109,120,85,40,147,150,159,0,107,6,24,71,235,227,42,190,172,247,94, -40,158,55,58,245,26,14,23,121,42,221,42,116,115,137,67,69,10,34,179,124, -218,187,107,172,3,49,211,208,33,252,172,186,184,243,248,195,98,210,66,187, -241,13,197,233,75,220,74,29,148,205,115,170,216,29,225,62,99,0,103,4,126, -99,13,223,27,205,215,171,243,51,158,178,65,193,70,11,185,83,39,129,94,139, -7,49,140,191,54,112,175,101,135,177,177,252,30,181,31,189,133,19,163,76, -230,206,93,246,120,96,121,29,197,176,75,101,118,54,230,223,102,139,50,36, -218,147,119,223,140,149,159,94,241,108,228,133,68,177,255,51,187,247,110, -186,91,3,254,206,191,5,24,0,171,203,191,162,234,194,67,169,0,0,0,0,73,69, -78,68,174,66,96,130}; - -static size_t xml_res_size_14 = 685; -static unsigned char xml_res_file_14[] = { -137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, -0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, -65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, -0,0,2,79,73,68,65,84,120,218,100,83,61,108,82,81,20,254,30,63,15,144,194, -98,52,154,70,156,28,108,73,140,198,166,49,52,142,226,166,198,196,132,142, -154,176,72,88,93,89,93,136,65,106,28,180,12,38,52,150,69,55,113,174,49, -93,52,8,117,176,46,98,26,45,196,193,247,158,240,248,125,158,239,218,71, -16,110,114,184,156,243,125,231,231,158,115,158,134,153,83,40,20,54,70,163, -209,93,199,113,130,174,77,211,52,219,235,245,110,102,179,217,251,211,92, -225,64,115,149,98,177,120,173,223,239,87,19,107,107,136,199,227,56,22,10, -77,136,157,110,23,141,70,3,239,118,118,160,235,122,50,147,201,188,253,47, -0,157,37,75,53,181,190,14,201,132,111,205,38,186,93,27,154,199,3,103,60, -70,40,20,196,217,88,12,82,25,182,202,101,58,170,32,12,224,97,0,102,78,165, -82,176,237,30,190,236,127,21,226,24,225,112,24,229,242,150,186,169,211, -78,156,60,242,221,234,60,124,115,34,145,128,215,167,227,176,221,150,108, -33,44,44,132,241,236,249,38,86,46,175,168,155,58,237,196,201,35,159,126, -42,192,112,56,188,183,180,188,140,118,171,141,160,174,99,65,50,110,60,121, -138,171,210,139,131,131,239,234,166,78,59,113,242,200,167,159,10,32,18, -32,56,26,15,17,12,6,241,168,240,24,215,147,73,116,165,220,197,197,51,234, -166,78,59,113,242,200,167,31,127,124,238,91,216,60,202,169,147,39,240,166, -90,157,157,174,178,187,156,233,51,9,224,247,251,21,152,78,167,17,8,4,224, -241,112,64,20,7,99,105,162,221,235,73,19,109,197,155,13,208,55,76,83,103, -121,124,207,203,237,10,76,211,152,171,32,18,137,226,246,173,155,240,249, -124,16,190,26,158,10,96,154,230,171,207,123,123,119,46,92,188,4,91,22,198, -248,109,226,199,225,207,185,0,167,199,242,76,201,206,105,212,62,126,0,253, -92,44,150,207,231,157,86,171,237,116,58,93,199,178,254,56,178,68,142,204, -124,34,212,45,203,82,56,121,228,211,207,93,164,102,189,94,207,84,42,219, -176,44,19,126,221,175,54,110,48,24,76,132,186,95,70,72,156,60,242,233,55, -105,98,169,84,122,193,187,215,235,21,87,87,175,96,105,233,188,188,57,242, -111,215,53,141,229,162,86,251,132,221,221,247,202,217,229,227,168,205,238, -137,138,156,203,229,114,15,162,209,232,13,249,175,79,97,125,195,48,94,11, -246,80,254,239,139,24,115,95,227,212,137,137,28,63,90,50,247,72,11,241, -203,45,123,250,115,254,43,192,0,120,74,65,201,19,184,212,222,0,0,0,0,73, -69,78,68,174,66,96,130}; - -static size_t xml_res_size_15 = 1507; -static unsigned char xml_res_file_15[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -850,8 +745,8 @@ static unsigned char xml_res_file_15[] = { 117,197,150,115,135,151,229,88,93,14,192,233,243,63,1,6,0,218,58,168,206, 121,36,62,30,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_16 = 1208; -static unsigned char xml_res_file_16[] = { +static size_t xml_res_size_13 = 1208; +static unsigned char xml_res_file_13[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -912,8 +807,8 @@ static unsigned char xml_res_file_16[] = { 246,7,200,222,198,15,110,185,108,189,180,168,127,11,48,0,131,178,248,28, 75,223,85,170,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_17 = 2048; -static unsigned char xml_res_file_17[] = { +static size_t xml_res_size_14 = 2048; +static unsigned char xml_res_file_14[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, 0,115,122,122,244,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101, 0,65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101, @@ -1013,6 +908,111 @@ static unsigned char xml_res_file_17[] = { 141,29,39,33,92,73,190,59,9,96,233,32,252,79,128,1,0,168,254,212,85,21, 212,140,221,0,0,0,0,73,69,78,68,174,66,96,130}; +static size_t xml_res_size_15 = 634; +static unsigned char xml_res_file_15[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,28,73,68,65,84,120,218,140,146,205,107,19,65,24,135,159,217,221,144, +108,194,162,104,244,80,177,181,136,32,130,7,169,90,240,82,197,34,86,91, +47,90,68,122,240,31,240,32,166,135,10,122,18,145,106,251,23,136,246,224, +65,76,27,15,106,81,36,82,5,123,144,106,148,94,10,173,45,181,133,32,10,37, +181,77,52,217,143,113,38,9,82,37,196,188,48,187,204,204,251,252,222,175, +17,119,239,141,224,251,1,134,33,80,38,195,225,48,245,172,88,44,234,159, +8,2,137,105,26,88,122,23,4,129,22,145,61,221,167,89,252,178,84,87,96,87, +75,51,79,159,141,75,33,12,161,5,12,13,151,92,87,158,233,233,86,240,178, +22,71,136,218,75,223,105,31,237,171,25,205,90,190,239,39,47,246,93,192, +245,60,246,238,217,77,67,166,196,52,243,48,57,154,180,60,207,235,93,93, +91,231,249,139,151,213,91,249,63,186,252,237,58,121,2,205,234,12,40,150, +138,216,81,155,206,99,71,21,47,171,62,226,31,76,84,191,130,244,196,107, +93,2,129,95,41,1,183,228,18,181,35,120,234,112,42,243,241,79,189,149,108, +53,98,98,138,48,66,134,56,220,214,198,166,216,118,112,67,200,64,160,74, +240,209,34,145,136,77,110,109,149,120,124,107,85,160,18,87,245,154,144, +112,72,103,175,146,89,121,194,253,113,117,106,64,71,248,60,120,93,149,12, +116,55,99,177,40,179,179,159,55,192,58,186,158,115,148,169,31,215,200,57, +105,78,29,129,246,29,9,222,101,135,153,158,123,68,200,254,134,165,97,211, +178,112,28,167,188,254,110,182,138,142,195,131,76,154,227,205,176,94,128, +253,91,134,120,53,55,204,62,181,127,155,155,192,202,231,243,111,82,169, +199,29,82,202,26,253,86,181,7,14,102,11,28,106,234,231,96,211,157,242,249, +229,118,201,135,236,0,147,159,6,203,157,210,195,223,92,111,112,125,35,188, +63,208,10,5,23,174,119,74,110,164,5,209,16,76,47,128,117,243,214,237,249, +90,209,193,80,209,109,102,90,47,81,248,202,216,124,152,115,59,227,48,185, +56,128,165,220,23,178,240,115,133,148,85,247,205,72,83,141,14,198,18,36, +122,135,16,249,95,156,157,89,30,212,15,177,12,143,246,115,69,208,184,169, +182,177,109,195,254,187,90,75,162,118,250,141,219,111,1,6,0,80,239,219, +105,146,138,192,9,0,0,0,0,73,69,78,68,174,66,96,130}; + +static size_t xml_res_size_16 = 632; +static unsigned char xml_res_file_16[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,26,73,68,65,84,120,218,164,83,61,111,19,65,16,125,179,187,103,7,131, +81,8,4,10,155,68,20,72,161,224,67,73,68,75,19,104,41,40,144,16,162,129, +34,5,13,255,0,209,210,128,132,172,132,134,6,148,54,13,66,164,65,66,162, +76,224,226,2,100,36,7,35,36,155,96,130,125,150,239,156,203,221,46,179,119, +206,23,208,32,143,116,186,189,157,153,247,102,222,204,145,49,6,131,152, +192,128,166,202,243,51,139,58,10,175,26,29,39,23,36,36,72,170,50,145,56, +199,95,251,163,169,127,67,132,109,159,178,201,231,103,159,1,91,81,26,36, +37,86,158,220,56,203,32,134,232,15,0,78,34,33,32,84,230,19,19,157,73,0, +140,214,156,188,137,176,242,16,198,16,156,194,53,76,206,62,231,230,250, +201,22,100,27,200,190,148,130,91,186,53,33,73,76,241,253,178,74,28,166, +203,142,3,236,151,136,214,95,241,197,203,36,150,24,196,196,26,65,199,239, +151,110,144,41,92,231,120,131,142,31,94,204,31,204,90,0,118,197,62,132, +51,196,71,105,139,220,97,214,172,75,229,157,139,160,213,177,44,236,225, +137,209,125,8,169,144,115,156,18,235,246,32,5,160,77,75,135,160,29,32,233, +59,165,67,109,165,130,209,177,17,28,191,89,2,18,145,77,250,88,191,147,129, +59,119,251,152,178,101,34,242,240,249,173,139,238,47,111,87,47,214,99,124, +234,52,142,20,142,98,171,250,136,171,214,73,233,22,64,230,138,8,197,4,154, +237,112,73,89,102,191,190,198,202,2,211,247,22,184,157,184,175,150,68,252, +181,4,109,120,85,40,147,150,159,0,107,6,24,71,235,227,42,190,172,247,94, +40,158,55,58,245,26,14,23,121,42,221,42,116,115,137,67,69,10,34,179,124, +218,187,107,172,3,49,211,208,33,252,172,186,184,243,248,195,98,210,66,187, +241,13,197,233,75,220,74,29,148,205,115,170,216,29,225,62,99,0,103,4,126, +99,13,223,27,205,215,171,243,51,158,178,65,193,70,11,185,83,39,129,94,139, +7,49,140,191,54,112,175,101,135,177,177,252,30,181,31,189,133,19,163,76, +230,206,93,246,120,96,121,29,197,176,75,101,118,54,230,223,102,139,50,36, +218,147,119,223,140,149,159,94,241,108,228,133,68,177,255,51,187,247,110, +186,91,3,254,206,191,5,24,0,171,203,191,162,234,194,67,169,0,0,0,0,73,69, +78,68,174,66,96,130}; + +static size_t xml_res_size_17 = 685; +static unsigned char xml_res_file_17[] = { +137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0, +0,31,243,255,97,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0, +65,100,111,98,101,32,73,109,97,103,101,82,101,97,100,121,113,201,101,60, +0,0,2,79,73,68,65,84,120,218,100,83,61,108,82,81,20,254,30,63,15,144,194, +98,52,154,70,156,28,108,73,140,198,166,49,52,142,226,166,198,196,132,142, +154,176,72,88,93,89,93,136,65,106,28,180,12,38,52,150,69,55,113,174,49, +93,52,8,117,176,46,98,26,45,196,193,247,158,240,248,125,158,239,218,71, +16,110,114,184,156,243,125,231,231,158,115,158,134,153,83,40,20,54,70,163, +209,93,199,113,130,174,77,211,52,219,235,245,110,102,179,217,251,211,92, +225,64,115,149,98,177,120,173,223,239,87,19,107,107,136,199,227,56,22,10, +77,136,157,110,23,141,70,3,239,118,118,160,235,122,50,147,201,188,253,47, +0,157,37,75,53,181,190,14,201,132,111,205,38,186,93,27,154,199,3,103,60, +70,40,20,196,217,88,12,82,25,182,202,101,58,170,32,12,224,97,0,102,78,165, +82,176,237,30,190,236,127,21,226,24,225,112,24,229,242,150,186,169,211, +78,156,60,242,221,234,60,124,115,34,145,128,215,167,227,176,221,150,108, +33,44,44,132,241,236,249,38,86,46,175,168,155,58,237,196,201,35,159,126, +42,192,112,56,188,183,180,188,140,118,171,141,160,174,99,65,50,110,60,121, +138,171,210,139,131,131,239,234,166,78,59,113,242,200,167,159,10,32,18, +32,56,26,15,17,12,6,241,168,240,24,215,147,73,116,165,220,197,197,51,234, +166,78,59,113,242,200,167,31,127,124,238,91,216,60,202,169,147,39,240,166, +90,157,157,174,178,187,156,233,51,9,224,247,251,21,152,78,167,17,8,4,224, +241,112,64,20,7,99,105,162,221,235,73,19,109,197,155,13,208,55,76,83,103, +121,124,207,203,237,10,76,211,152,171,32,18,137,226,246,173,155,240,249, +124,16,190,26,158,10,96,154,230,171,207,123,123,119,46,92,188,4,91,22,198, +248,109,226,199,225,207,185,0,167,199,242,76,201,206,105,212,62,126,0,253, +92,44,150,207,231,157,86,171,237,116,58,93,199,178,254,56,178,68,142,204, +124,34,212,45,203,82,56,121,228,211,207,93,164,102,189,94,207,84,42,219, +176,44,19,126,221,175,54,110,48,24,76,132,186,95,70,72,156,60,242,233,55, +105,98,169,84,122,193,187,215,235,21,87,87,175,96,105,233,188,188,57,242, +111,215,53,141,229,162,86,251,132,221,221,247,202,217,229,227,168,205,238, +137,138,156,203,229,114,15,162,209,232,13,249,175,79,97,125,195,48,94,11, +246,80,254,239,139,24,115,95,227,212,137,137,28,63,90,50,247,72,11,241, +203,45,123,250,115,254,43,192,0,120,74,65,201,19,184,212,222,0,0,0,0,73, +69,78,68,174,66,96,130}; + static size_t xml_res_size_18 = 1971; static unsigned char xml_res_file_18[] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0, @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 131989; +static size_t xml_res_size_26 = 136019; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -2593,10 +2593,10 @@ static unsigned char xml_res_file_26[] = { 110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,80,65,78,69,76,34,32,115,116,97,114, -116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84,89, -80,69,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105, +32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,34,32,115,116, +97,114,116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, +101,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84, +89,80,69,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105, 100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, 73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, 60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, @@ -3848,1876 +3848,16 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,111, -105,99,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72,66, -95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,49,32, -40,67,58,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, -109,101,61,34,73,68,67,95,80,65,78,69,76,91,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72, -79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, -98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, -68,82,73,86,69,84,89,80,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, -78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, -111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +105,99,101,98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,72,68, +67,66,79,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,72,66,95,68,69,70, +65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109, -97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78, -69,87,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112,110, -103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100,101,114,46, -112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, -105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, -101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,48,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65, -66,69,76,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84, -95,83,73,90,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, -104,111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,114,105,118,101,32,50,32,40,68,58,41,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, -116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, -76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,68,82,73,86,69,84,89,80,69,91,49,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, -79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117, -108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115, -101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, -101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,49,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,49,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,99,104,111,105,99,101,98,111,111,107,112,97,103,101, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,68,114,105,118,101,32,51,32,40,69,58,41, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60, -47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, -68,67,95,80,65,78,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, -97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,48,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, -121,112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69, -84,89,80,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, -67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60, -47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, -62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,100,114,105,118,101,95,97,100,100,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97, -117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,66,114,111,119,115,101,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, -62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, -97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, -99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, -62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, -69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, -78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,50, -53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,83, -73,90,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, -108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,104, -111,105,99,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,114,105,118,101,32,52,32,40,70,58,41,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, -116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,73,68,67,95,80,65,78,69, -76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, -84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, -114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, -116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68, -68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,55,53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,68,82,73,86,69,84,89,80,69,91,51,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, -79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, -73,68,67,95,78,69,87,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111,111,108,116, -105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117, -108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115, -101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, -101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, -120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, -76,91,51,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, -95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49, -54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108, -116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, -115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44,51,60,47,103,114, -111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,51, -93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, -84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, -80,67,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76,91,51,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76, -73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, -76,65,66,69,76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, -95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, 97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, 108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, @@ -6146,54 +4286,71 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,78,101, -119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78,101,119, -32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62,10,32,32, -32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, -114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82,79,79, -84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, -60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62, -48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111, -119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, -97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,91,48,93,34,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82, +65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66, +79,68,82,73,86,69,84,89,80,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, @@ -6202,12 +4359,133 @@ static unsigned char xml_res_file_26[] = { 62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, -34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,48,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, +62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,48,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, 84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99, +111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,50,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,83,80,84,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, @@ -6215,166 +4493,155 @@ static unsigned char xml_res_file_26[] = { 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,51, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,69,68,73,84,95,72,80,67,91,48,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95, +76,65,66,69,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,67,89,76, +91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122, +101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67,95,84,69, +88,84,95,83,73,90,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,73, +68,67,95,72,68,80,65,78,69,76,91,49,93,34,62,10,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,48, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55, +53,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, 76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66, -85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, -111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, -108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, -101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, -82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, -101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, -114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, -115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,105,122,101,32,40,77,66,41,58,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, -67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,52,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84,89,80,69,91,49,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, @@ -6389,45 +4656,394 @@ static unsigned char xml_res_file_26[] = { 101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,78,69,87,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,100,114,105, +118,101,95,97,100,100,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,70,73,76,69,91,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,114,111,119, +115,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +102,111,108,100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105, +108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95, +70,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,69,74,69,67,84,91,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54, +120,49,54,95,99,111,110,116,114,111,108,95,101,106,101,99,116,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,116,111,111,108,116,105,112,62,69,106,101,99,116,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,44,51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, 65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, 100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,68,95,76,65,66,69,76,91,49,50,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99, +116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,83,80,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, 100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, -120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, -119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, -68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, -97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,49,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,49,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,49,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,67,89,76,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,49,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,49,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,91,50,93, +34,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,50,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66, +79,68,82,73,86,69,84,89,80,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,50,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,50,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99, +111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, 32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, @@ -6435,9 +5051,1431 @@ static unsigned char xml_res_file_26[] = { 78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, 114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,50,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111, +114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,83,80,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,50,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,50,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,50,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,67,89,76,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,50,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,50,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,91,51,93, +34,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,51,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66, +79,68,82,73,86,69,84,89,80,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,51,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,51,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,51,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99, +111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,51,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111, +114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,83,80,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,51,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,51,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,51,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,67,89,76,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,51,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,51,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,91,52,93, +34,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,52,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66, +79,68,82,73,86,69,84,89,80,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,52,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,52,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,52,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99, +111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,52,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111, +114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,83,80,84,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,52,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,52,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,52,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,67,89,76,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,52,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,52,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,91,53,93, +34,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,53,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66, +79,68,82,73,86,69,84,89,80,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,53,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99, +111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,53,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111, +114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,83,80,84,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,53,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,53,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,53,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,67,89,76,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,53,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,53,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,91,54,93, +34,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95, +84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,54,48,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,53,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66, +79,68,82,73,86,69,84,89,80,69,91,54,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,91,54,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,49,54,120,49,54,95,100,114,105,118,101,95,97,100,100,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,70,73,76,69,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,66,114,111,119,115,101,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46, +99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108,100, +101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +73,68,67,95,72,68,68,95,76,65,66,69,76,91,54,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,91,54,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,69,74,69,67,84,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114, +99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,99, +111,110,116,114,111,108,95,101,106,101,99,116,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,106,101,99,116,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,44, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,68,95,76,65,66,69,76,91,54,50,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111, +114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,83,80,84,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,54,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,69,68,73,84,95,72,80,67,91,54,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,72,68,68,95,76,65,66,69,76,91,54,52,93,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100, +101,114,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,73,68,67, +95,69,68,73,84,95,67,89,76,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69, +76,91,54,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,91,54,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100, +78,101,119,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,78, +101,119,32,72,97,114,100,32,68,105,115,99,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, +68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108, +100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, 114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, 111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, @@ -6449,24 +6487,233 @@ static unsigned char xml_res_file_26[] = { 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, +97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, +122,101,32,40,77,66,41,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,73,68,67,95,69,68,73,84,52,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, -97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, 78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, @@ -7752,12 +7999,12 @@ void InitXmlResource() XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_video_mode.png"), xml_res_file_9, xml_res_size_9, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_sound.png"), xml_res_file_10, xml_res_size_10, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_drive.png"), xml_res_file_11, xml_res_size_11, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_joystick.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); - XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_mouse_pc.png"), xml_res_file_12, xml_res_size_12, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_joystick.png"), xml_res_file_13, xml_res_size_13, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_network_ethernet.png"), xml_res_file_14, xml_res_size_14, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_drive_add.png"), xml_res_file_15, xml_res_size_15, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_folder.png"), xml_res_file_16, xml_res_size_16, wxT("image/png")); + XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_16x16_control_eject.png"), xml_res_file_17, xml_res_size_17, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_control_play_blue.png"), xml_res_file_18, xml_res_size_18, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_setting_tools.png"), xml_res_file_19, xml_res_size_19, wxT("image/png")); XRC_ADD_FILE(wxT("XRC_resource/wx-resources.cpp$icons_32x32_widescreen.png"), xml_res_file_20, xml_res_size_20, wxT("image/png")); diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 1f6e525..8d16081 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -57,7 +57,7 @@ drive_info_t* get_machine_info(char* s, int* num_drive_info) { pos++; } } - int num_hdds = hdd_controller_current_is_mfm() ? 2 : 4; + int num_hdds = hdd_controller_current_is_mfm() ? 2 : (hdd_controller_current_is_scsi() ? 7 : 4); for (i = 0; i < num_hdds; ++i) { drive = 'C'+i; diff --git a/src/wx-utils.cc b/src/wx-utils.cc index 6faa359..c13cce6 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include "wx-dialogbox.h" #include "wx-app.h" @@ -376,6 +377,30 @@ int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) ((wxListBox*) window)->Clear(); break; } + case WX_CHB_SETPAGETEXT: + { + ((wxChoicebook*)window)->SetPageText(param1, (char *)param2); + break; + } + case WX_CHB_ADDPAGE: + { + ((wxChoicebook*)window)->AddPage((wxWindow *)param1, (char *)param2); + break; + } + case WX_CHB_REMOVEPAGE: + { + ((wxChoicebook*)window)->RemovePage(param1); + break; + } + case WX_CHB_GETPAGECOUNT: + { + return ((wxChoicebook*)window)->GetPageCount(); + } + case WX_REPARENT: + { + ((wxWindow *)window)->Reparent((wxWindow *)param1); + break; + } } ((wxWindow*)window)->Fit(); diff --git a/src/wx-utils.h b/src/wx-utils.h index 3a8a3a5..fd00931 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -145,6 +145,14 @@ extern void (*wx_idle_func)(void* window, void* event); #define WX_LB_SETCURSEL 66 #define WX_LBN_DBLCLK 67 +#define WX_CHB_SETPAGETEXT 68 +#define WX_CHB_ADDPAGE 69 +#define WX_CHB_REMOVEPAGE 70 +#define WX_CHB_GETPAGECOUNT 71 + +#define WX_REPARENT 72 + + #define WX_MB_OK wxOK #define WX_MB_OKCANCEL wxOK|wxCANCEL #define WX_IDOK wxOK From 77a969f9cc633f50cc022a5eed0b229cef55135b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Mar 2018 21:58:45 +0000 Subject: [PATCH 0367/1050] Don't attempt to register PCI devices on systems that don't have PCI. Fixes warnings on startup. --- src/pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index 8102fd7..0775965 100644 --- a/src/pci.c +++ b/src/pci.c @@ -207,7 +207,10 @@ void pci_add_specific(int card, uint8_t (*read)(int func, int addr, 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; - + + if (!PCI) + return -1; + for (c = 0; c < 32; c++) { if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) From f59e405737a25af68ff02bbecb8ea6557e872bc2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Mar 2018 22:01:13 +0000 Subject: [PATCH 0368/1050] Include stdint.h in wx-createdisc.cc. --- src/wx-createdisc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wx-createdisc.cc b/src/wx-createdisc.cc index ea0db8f..cd8ccbc 100644 --- a/src/wx-createdisc.cc +++ b/src/wx-createdisc.cc @@ -1,3 +1,5 @@ +#include + extern "C" void pclog(const char *format, ...); #include "wx-createdisc.h" From c07b76dc8e9ea9a85c2eb53c23b2040e5f52e968 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 3 Mar 2018 21:32:24 +0000 Subject: [PATCH 0369/1050] ATAPI sector accesses can not be split over multiple transfers. Fixes Windows XP installer. --- src/ide.c | 4 ++-- src/ide_atapi.c | 6 ++++++ src/ide_atapi.h | 1 + src/scsi.c | 5 +++-- src/scsi.h | 6 ++++-- src/scsi_cd.c | 9 ++++++++- src/scsi_zip.c | 9 ++++++++- 7 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/ide.c b/src/ide.c index 0661db5..3f8a6a7 100644 --- a/src/ide.c +++ b/src/ide.c @@ -277,12 +277,12 @@ void resetide(void) if (cdrom_channel == d) { ide_drives[d].type = IDE_CDROM; - scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d); + scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d, &ide_drives[d].atapi); } else if (zip_channel == d) { ide_drives[d].type = IDE_CDROM; - scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_zip, d); + scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_zip, d, &ide_drives[d].atapi); } else { diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 7ac20a2..0570eba 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -134,6 +134,12 @@ uint8_t atapi_read_drq(atapi_device_t *atapi_dev) return atapi_dev->bus_state & BUS_REQ; } +void atapi_set_transfer_granularity(atapi_device_t *atapi_dev, int size) +{ + if (atapi_dev->max_transfer_len > size) + atapi_dev->max_transfer_len -= (atapi_dev->max_transfer_len % size); +} + void atapi_process_packet(atapi_device_t *atapi_dev) { // pclog("atapi_process_packet: state=%i\n", atapi_dev->state); diff --git a/src/ide_atapi.h b/src/ide_atapi.h index 43ca829..517417a 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -61,5 +61,6 @@ void atapi_command_start(atapi_device_t *atapi); uint8_t atapi_read_iir(atapi_device_t *atapi_dev); uint8_t atapi_read_drq(atapi_device_t *atapi_dev); void atapi_process_packet(atapi_device_t *atapi_dev); +void atapi_set_transfer_granularity(atapi_device_t *atapi_dev, int size); #endif diff --git a/src/scsi.c b/src/scsi.c index 09b53b7..df4b8a8 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "ide.h" +#include "ide_atapi.h" #include "scsi.h" #include "scsi_cd.h" #include "scsi_hd.h" @@ -323,13 +324,13 @@ void scsi_bus_kick(scsi_bus_t *bus) scsi_bus_update(bus, 0); } -void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id) +void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id, atapi_device_t *atapi_dev) { memset(bus->devices, 0, sizeof(bus->devices)); memset(bus->device_data, 0, sizeof(bus->device_data)); bus->devices[0] = device; - bus->device_data[0] = bus->devices[0]->atapi_init(bus, id); + bus->device_data[0] = bus->devices[0]->atapi_init(bus, id, atapi_dev); if (!bus->device_data[0]) bus->devices[0] = NULL; diff --git a/src/scsi.h b/src/scsi.h index b290aec..a89010c 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -2,11 +2,12 @@ #define _SCSI_H_ struct scsi_bus_t; +struct atapi_device_t; typedef struct scsi_device_t { void *(*init)(struct scsi_bus_t *bus, int id); - void *(*atapi_init)(struct scsi_bus_t *bus, int id); + void *(*atapi_init)(struct scsi_bus_t *bus, int id, struct atapi_device_t *atapi_dev); void (*close)(void *p); void (*start_command)(void *p); @@ -104,7 +105,8 @@ int scsi_bus_match(scsi_bus_t *bus, int bus_assert); void scsi_bus_kick(scsi_bus_t *bus); void scsi_bus_init(scsi_bus_t *bus); void scsi_bus_close(scsi_bus_t *bus); -void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id); + +void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id, struct atapi_device_t *atapi_dev); #define KEY_NONE 0 #define KEY_NOT_READY 2 diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 9a33674..718c3a9 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -193,6 +193,7 @@ typedef struct scsi_cd_data_t uint8_t page_current; int is_atapi; + atapi_device_t *atapi_dev; } scsi_cd_data_t; static void scsi_add_data(scsi_cd_data_t *data, uint8_t val) @@ -283,11 +284,12 @@ static void *scsi_cd_init(scsi_bus_t *bus, int id) return data; } -static void *scsi_cd_atapi_init(scsi_bus_t *bus, int id) +static void *scsi_cd_atapi_init(scsi_bus_t *bus, int id, atapi_device_t *atapi_dev) { scsi_cd_data_t *data = scsi_cd_init(bus, id); data->is_atapi = 1; + data->atapi_dev = atapi_dev; return data; } @@ -625,6 +627,10 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cmd_pos = CMD_POS_TRANSFER; data->bytes_expected = data->cdlen * ((rcdmode == 0x10) ? 2048 : 2352); + if (rcdmode == 0x10) + atapi_set_transfer_granularity(data->atapi_dev, 2048); + else + atapi_set_transfer_granularity(data->atapi_dev, 2352); } if (!data->cdlen) { @@ -689,6 +695,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cmd_pos = CMD_POS_TRANSFER; data->bytes_expected = data->cdlen * 2048; + atapi_set_transfer_granularity(data->atapi_dev, 2048); } if (!data->cdlen) diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 8af34d9..e6bb291 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -4,6 +4,7 @@ #include #include "ibm.h" #include "hdd_file.h" +#include "ide_atapi.h" #include "scsi.h" #include "scsi_zip.h" #include "timer.h" @@ -69,6 +70,7 @@ typedef struct scsi_zip_data scsi_bus_t *bus; int is_atapi; + atapi_device_t *atapi_dev; int read_only; } scsi_zip_data; @@ -193,11 +195,12 @@ static void *scsi_zip_init(scsi_bus_t *bus, int id) return data; } -static void *scsi_zip_atapi_init(scsi_bus_t *bus, int id) +static void *scsi_zip_atapi_init(scsi_bus_t *bus, int id, atapi_device_t *atapi_dev) { scsi_zip_data *data = scsi_zip_init(bus, id); data->is_atapi = 1; + data->atapi_dev = atapi_dev; return data; } @@ -686,6 +689,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->sector_pos = 0; bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); break; } // else @@ -746,6 +750,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->sector_pos = 0; bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); break; } // else @@ -814,6 +819,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->sector_pos = 0; bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); break; } if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) @@ -881,6 +887,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->sector_pos = 0; bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); break; } if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) From 919f2dd45d4dca3af35ef5e1c09416ac6c71e50b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 3 Mar 2018 21:32:56 +0000 Subject: [PATCH 0370/1050] Implemented CMPXCHG8B on Winchip. Patch from nerd73. --- src/386_ops.h | 8 ++++---- src/808x.c | 2 ++ src/codegen_timing_winchip.c | 4 ++-- src/cpu.c | 8 ++++++++ src/cpu.h | 1 + 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/386_ops.h b/src/386_ops.h index 36e421e..f091c93 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -383,7 +383,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, /*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, /*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, /*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, @@ -405,7 +405,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, /*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, /*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, /*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, @@ -427,7 +427,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, @@ -449,7 +449,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, diff --git a/src/808x.c b/src/808x.c index ca2fd96..e93e5f2 100644 --- a/src/808x.c +++ b/src/808x.c @@ -626,6 +626,7 @@ void resetx86() use32=0; cpu_cur_status = 0; stack32=0; + cpu_hasCX8 = 0; // i86_Reset(); // cs=0xFFFF0; msw=0; @@ -682,6 +683,7 @@ void softresetx86() cr4 = 0; eflags=0; cgate32=0; + cpu_hasCX8 = 0; if (AT) { loadcs(0xF000); diff --git a/src/codegen_timing_winchip.c b/src/codegen_timing_winchip.c index 9846e55..bdf499e 100644 --- a/src/codegen_timing_winchip.c +++ b/src/codegen_timing_winchip.c @@ -74,7 +74,7 @@ static int *opcode_timings_0f[256] = /*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), /*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), /*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, @@ -96,7 +96,7 @@ static int *opcode_timings_0f_mod3[256] = /*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30), /*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), -/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), /*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, /*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, diff --git a/src/cpu.c b/src/cpu.c index 8a06311..eed48a4 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -74,6 +74,7 @@ int cpu_busspeed; int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; +int cpu_hasCX8; int cpu_hasVME; int cpu_use_dynarec; int cpu_cyrix_alignment; @@ -500,6 +501,7 @@ void cpu_set() cpu_hasMMX = 0; cpu_hasMSR = 0; cpu_hasCR4 = 0; + cpu_hasCX8 = 0; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); @@ -1299,6 +1301,8 @@ void cpu_CPUID() EAX = 0x540; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_hasCX8) + EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) EDX |= CPUID_MMX; } @@ -1504,6 +1508,10 @@ void cpu_WRMSR() case 0x107: msr.fcr = EAX; cpu_hasMMX = EAX & (1 << 9); + if (EAX & (1 << 1)) + cpu_hasCX8 = 1; + else + cpu_hasCX8 = 0; if (EAX & (1 << 29)) CPUID = 0; else diff --git a/src/cpu.h b/src/cpu.h index 1141864..2614994 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -110,6 +110,7 @@ extern int cpu_hasMSR; extern int cpu_hasMMX; extern int cpu_hasCR4; extern int cpu_hasVME; +extern int cpu_hasCX8; #define CR4_TSD (1 << 2) #define CR4_DE (1 << 3) From 319a929a20105222d407c263307473448215b1fc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Mar 2018 13:58:02 +0000 Subject: [PATCH 0371/1050] Changed wx_sendmessage() param1 to LONG_PARAM. Fixes crashed on 64-bit builds. --- src/wx-utils.cc | 2 +- src/wx-utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wx-utils.cc b/src/wx-utils.cc index c13cce6..db4c624 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -273,7 +273,7 @@ int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id) return FALSE; } -int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2) +int wx_sendmessage(void* window, int type, LONG_PARAM param1, LONG_PARAM param2) { switch (type) { diff --git a/src/wx-utils.h b/src/wx-utils.h index fd00931..945d54f 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -35,7 +35,7 @@ extern "C" { int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id); void wx_setwindowtitle(void* window, char* s); - int wx_sendmessage(void* window, int type, INT_PARAM param1, LONG_PARAM param2); + int wx_sendmessage(void* window, int type, LONG_PARAM param1, LONG_PARAM param2); void* wx_getdlgitem(void* window, int id); void wx_setdlgitemtext(void* window, int id, char* str); void wx_enablewindow(void* window, int enabled); From 8e52c00ffcf6bca785515ce77e2abfcd5c018b41 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Mar 2018 13:58:45 +0000 Subject: [PATCH 0372/1050] Autoconf setup now sets build flags for C++. --- configure | 2 + configure.ac | 2 + src/Makefile.in | 365 +++++++++++++++++++++++++++++++----------------- 3 files changed, 242 insertions(+), 127 deletions(-) diff --git a/configure b/configure index c3fc3f7..3153f81 100755 --- a/configure +++ b/configure @@ -4169,10 +4169,12 @@ fi if test "$enable_debug" = "yes"; then CFLAGS="-Wall -O0 -g -D_DEBUG" + CXXFLAGS="-Wall -O0 -g -D_DEBUG" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else CFLAGS="-O3" + CXXFLAGS="-O3" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi diff --git a/configure.ac b/configure.ac index 5cf2690..9d09ca5 100644 --- a/configure.ac +++ b/configure.ac @@ -28,9 +28,11 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [build debug executable])) if test "$enable_debug" = "yes"; then CFLAGS="-Wall -O0 -g -D_DEBUG" + CXXFLAGS="-Wall -O0 -g -D_DEBUG" AC_MSG_RESULT([yes]) else CFLAGS="-O3" + CXXFLAGS="-O3" AC_MSG_RESULT([no]) fi diff --git a/src/Makefile.in b/src/Makefile.in index 733dfff..bd8acad 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -136,67 +136,68 @@ 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 amstrad.c cbm_io.c cdrom-image.cc \ - cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c \ - codegen_timing_686.c codegen_timing_common.c \ - codegen_timing_pentium.c codegen_timing_winchip.c compaq.c \ - config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ - disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ - fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ + acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c \ + cdrom-image.cc cdrom-null.c cmd640.c codegen.c codegen_ops.c \ + codegen_timing_486.c codegen_timing_686.c \ + codegen_timing_common.c codegen_timing_pentium.c \ + codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ + device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ + esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c \ + ide.c ide_atapi.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ - nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pci.c pic.c \ - piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ + nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c \ + pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ - serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c \ - sound_adlibgold.c sound_audiopci.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 \ - t1000.c t3100e.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_colorplus.c \ - vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ - vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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_t1000.c \ - vid_t3100e.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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ - wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ - wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ - wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ - wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ - midi_alsa.c wx-sdl2-midi.c codegen_x86.c codegen_x86-64.c \ - ne2000.c nethandler.c wx-hostconfig.c slirp/bootp.c \ - slirp/cksum.c slirp/debug.c slirp/if.c slirp/ip_icmp.c \ - slirp/ip_input.c slirp/ip_output.c slirp/mbuf.c slirp/misc.c \ - slirp/queue.c slirp/sbuf.c slirp/slirp.c slirp/socket.c \ - slirp/tcp_input.c slirp/tcp_output.c slirp/tcp_subr.c \ - slirp/tcp_timer.c slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c \ - wx-sdl2-display.c cdrom-ioctl-osx.c cdrom-ioctl.c \ - wx-sdl2-display-win.c + serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ + sound_adlib.c sound_adlibgold.c sound_audiopci.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 t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c \ + vid_et4000w32.c vid_genius.c vid_hercules.c vid_icd2061.c \ + vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c \ + vid_oti037.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_t1000.c vid_t3100e.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 \ + vid_wy700.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ + wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ + wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ + wx-status.cc wx-sdl2-status.c wx-thread.c wx-common.c \ + wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ + wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ + wx-createdisc.cc wx-resources.cpp midi_alsa.c wx-sdl2-midi.c \ + codegen_x86.c codegen_x86-64.c ne2000.c nethandler.c \ + wx-hostconfig.c slirp/bootp.c slirp/cksum.c slirp/debug.c \ + slirp/if.c slirp/ip_icmp.c slirp/ip_input.c slirp/ip_output.c \ + slirp/mbuf.c slirp/misc.c slirp/queue.c slirp/sbuf.c \ + slirp/slirp.c slirp/socket.c slirp/tcp_input.c \ + slirp/tcp_output.c slirp/tcp_subr.c slirp/tcp_timer.c \ + slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c wx-sdl2-display.c \ + cdrom-ioctl-osx.c cdrom-ioctl.c wx-sdl2-display-win.c am__dirstamp = $(am__leading_dot)dirstamp @USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) @USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) @@ -232,9 +233,10 @@ am__dirstamp = $(am__leading_dot)dirstamp @OS_WINDOWS_TRUE@ pcem-wx-sdl2-display-win.$(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-amstrad.$(OBJEXT) pcem-cbm_io.$(OBJEXT) \ - pcem-cdrom-image.$(OBJEXT) pcem-cdrom-null.$(OBJEXT) \ + pcem-acc2036.$(OBJEXT) pcem-acer386sx.$(OBJEXT) \ + pcem-ali1429.$(OBJEXT) pcem-amstrad.$(OBJEXT) \ + pcem-cbm_io.$(OBJEXT) pcem-cdrom-image.$(OBJEXT) \ + pcem-cdrom-null.$(OBJEXT) pcem-cmd640.$(OBJEXT) \ pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ @@ -269,17 +271,18 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-mouse_serial.$(OBJEXT) pcem-neat.$(OBJEXT) \ pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ pcem-olivetti_m24.$(OBJEXT) pcem-opti495.$(OBJEXT) \ - pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pci.$(OBJEXT) \ - pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) \ - pcem-ppi.$(OBJEXT) pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) \ - pcem-ps2_mca.$(OBJEXT) pcem-ps2_nvr.$(OBJEXT) \ - pcem-nvr_tc8521.$(OBJEXT) pcem-rom.$(OBJEXT) \ - pcem-rtc.$(OBJEXT) pcem-rtc_tc8521.$(OBJEXT) \ - pcem-scat.$(OBJEXT) pcem-scsi.$(OBJEXT) \ - pcem-scsi_53c400.$(OBJEXT) pcem-scsi_aha1540.$(OBJEXT) \ - pcem-scsi_cd.$(OBJEXT) pcem-scsi_hd.$(OBJEXT) \ - pcem-scsi_zip.$(OBJEXT) pcem-serial.$(OBJEXT) \ - pcem-sio.$(OBJEXT) pcem-sis496.$(OBJEXT) pcem-sound.$(OBJEXT) \ + pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pc87306.$(OBJEXT) \ + pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) \ + pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) pcem-ps1.$(OBJEXT) \ + pcem-ps2.$(OBJEXT) pcem-ps2_mca.$(OBJEXT) \ + pcem-ps2_nvr.$(OBJEXT) pcem-nvr_tc8521.$(OBJEXT) \ + pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) \ + pcem-rtc_tc8521.$(OBJEXT) pcem-scat.$(OBJEXT) \ + pcem-scsi.$(OBJEXT) pcem-scsi_53c400.$(OBJEXT) \ + pcem-scsi_aha1540.$(OBJEXT) pcem-scsi_cd.$(OBJEXT) \ + pcem-scsi_hd.$(OBJEXT) pcem-scsi_zip.$(OBJEXT) \ + pcem-serial.$(OBJEXT) pcem-sio.$(OBJEXT) pcem-sis496.$(OBJEXT) \ + pcem-sl82c460.$(OBJEXT) pcem-sound.$(OBJEXT) \ pcem-sound_ad1848.$(OBJEXT) pcem-sound_adlib.$(OBJEXT) \ pcem-sound_adlibgold.$(OBJEXT) pcem-sound_audiopci.$(OBJEXT) \ pcem-sound_cms.$(OBJEXT) pcem-sound_emu8k.$(OBJEXT) \ @@ -297,12 +300,13 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(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_colorplus.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ - pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ - pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ - pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ - pcem-vid_incolor.$(OBJEXT) pcem-vid_mda.$(OBJEXT) \ - pcem-vid_olivetti_m24.$(OBJEXT) pcem-vid_oti067.$(OBJEXT) \ + pcem-vid_colorplus.$(OBJEXT) pcem-vid_compaq_cga.$(OBJEXT) \ + pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ + pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ + pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ + pcem-vid_ics2595.$(OBJEXT) pcem-vid_incolor.$(OBJEXT) \ + pcem-vid_mda.$(OBJEXT) pcem-vid_olivetti_m24.$(OBJEXT) \ + pcem-vid_oti037.$(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_ps1_svga.$(OBJEXT) \ @@ -316,7 +320,7 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-vid_vga.$(OBJEXT) pcem-vid_voodoo.$(OBJEXT) \ pcem-video.$(OBJEXT) pcem-wd76c10.$(OBJEXT) \ pcem-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ - pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ + pcem-x87.$(OBJEXT) pcem-xi8088.$(OBJEXT) pcem-xtide.$(OBJEXT) \ pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ dosbox/pcem-cdrom_image.$(OBJEXT) dosbox/pcem-dbopl.$(OBJEXT) \ dosbox/pcem-nukedopl.$(OBJEXT) \ @@ -559,62 +563,64 @@ WINDRES = $(shell wx-config --rescomp) # DOSBox # resid-fp -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c \ acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc \ - cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c \ - codegen_timing_686.c codegen_timing_common.c \ - codegen_timing_pentium.c codegen_timing_winchip.c compaq.c \ - config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ - disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ - fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ + cdrom-null.c cmd640.c codegen.c codegen_ops.c \ + codegen_timing_486.c codegen_timing_686.c \ + codegen_timing_common.c codegen_timing_pentium.c \ + codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ + device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ + esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c \ + ide.c ide_atapi.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ - nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pci.c pic.c \ - piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ + nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c \ + pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ - serial.c sio.c sis496.c sound.c sound_ad1848.c sound_adlib.c \ - sound_adlibgold.c sound_audiopci.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 \ - t1000.c t3100e.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_colorplus.c \ - vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c \ - vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.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_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_t1000.c \ - vid_t3100e.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 vid_wy700.c x86seg.c x87.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ - wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ - wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ - wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ - wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_8) $(am__append_11) $(am__append_13) \ - $(am__append_14) $(am__append_17) + serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ + sound_adlib.c sound_adlibgold.c sound_audiopci.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 t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c \ + vid_et4000w32.c vid_genius.c vid_hercules.c vid_icd2061.c \ + vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c \ + vid_oti037.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_t1000.c vid_t3100e.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 \ + vid_wy700.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ + wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ + wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ + wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ + wx-status.cc wx-sdl2-status.c wx-thread.c wx-common.c \ + wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ + wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ + wx-createdisc.cc wx-resources.cpp $(am__append_4) \ + $(am__append_5) $(am__append_6) $(am__append_8) \ + $(am__append_11) $(am__append_13) $(am__append_14) \ + $(am__append_17) pcem_CFLAGS = $(subst -fpermissive,,$(shell wx-config --cxxflags) \ $(shell sdl2-config --cflags)) $(am__append_7) $(am__append_9) \ $(am__append_15) $(am__append_19) $(am__append_20) @@ -813,6 +819,7 @@ distclean-compile: @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-acc2036.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-amstrad.Po@am__quote@ @@ -822,6 +829,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.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@ @@ -895,6 +903,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.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@ @@ -917,6 +926,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.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@ @@ -955,6 +965,7 @@ distclean-compile: @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_colorplus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.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@ @@ -965,6 +976,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.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_oti037.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@ @@ -1021,6 +1033,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.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-xi8088.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ @@ -1135,6 +1148,20 @@ pcem-808x.obj: 808x.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-acc2036.o: acc2036.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc2036.o -MD -MP -MF $(DEPDIR)/pcem-acc2036.Tpo -c -o pcem-acc2036.o `test -f 'acc2036.c' || echo '$(srcdir)/'`acc2036.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc2036.Tpo $(DEPDIR)/pcem-acc2036.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc2036.c' object='pcem-acc2036.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc2036.o `test -f 'acc2036.c' || echo '$(srcdir)/'`acc2036.c + +pcem-acc2036.obj: acc2036.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc2036.obj -MD -MP -MF $(DEPDIR)/pcem-acc2036.Tpo -c -o pcem-acc2036.obj `if test -f 'acc2036.c'; then $(CYGPATH_W) 'acc2036.c'; else $(CYGPATH_W) '$(srcdir)/acc2036.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc2036.Tpo $(DEPDIR)/pcem-acc2036.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc2036.c' object='pcem-acc2036.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc2036.obj `if test -f 'acc2036.c'; then $(CYGPATH_W) 'acc2036.c'; else $(CYGPATH_W) '$(srcdir)/acc2036.c'; fi` + pcem-acer386sx.o: acer386sx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-acer386sx.Tpo $(DEPDIR)/pcem-acer386sx.Po @@ -1205,6 +1232,20 @@ pcem-cdrom-null.obj: cdrom-null.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-cmd640.o: cmd640.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cmd640.o -MD -MP -MF $(DEPDIR)/pcem-cmd640.Tpo -c -o pcem-cmd640.o `test -f 'cmd640.c' || echo '$(srcdir)/'`cmd640.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cmd640.Tpo $(DEPDIR)/pcem-cmd640.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd640.c' object='pcem-cmd640.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cmd640.o `test -f 'cmd640.c' || echo '$(srcdir)/'`cmd640.c + +pcem-cmd640.obj: cmd640.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cmd640.obj -MD -MP -MF $(DEPDIR)/pcem-cmd640.Tpo -c -o pcem-cmd640.obj `if test -f 'cmd640.c'; then $(CYGPATH_W) 'cmd640.c'; else $(CYGPATH_W) '$(srcdir)/cmd640.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cmd640.Tpo $(DEPDIR)/pcem-cmd640.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd640.c' object='pcem-cmd640.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cmd640.obj `if test -f 'cmd640.c'; then $(CYGPATH_W) 'cmd640.c'; else $(CYGPATH_W) '$(srcdir)/cmd640.c'; fi` + pcem-codegen.o: codegen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen.Tpo $(DEPDIR)/pcem-codegen.Po @@ -2143,6 +2184,20 @@ pcem-pc.obj: pc.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-pc87306.o: pc87306.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pc87306.o -MD -MP -MF $(DEPDIR)/pcem-pc87306.Tpo -c -o pcem-pc87306.o `test -f 'pc87306.c' || echo '$(srcdir)/'`pc87306.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pc87306.Tpo $(DEPDIR)/pcem-pc87306.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pc87306.c' object='pcem-pc87306.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc87306.o `test -f 'pc87306.c' || echo '$(srcdir)/'`pc87306.c + +pcem-pc87306.obj: pc87306.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pc87306.obj -MD -MP -MF $(DEPDIR)/pcem-pc87306.Tpo -c -o pcem-pc87306.obj `if test -f 'pc87306.c'; then $(CYGPATH_W) 'pc87306.c'; else $(CYGPATH_W) '$(srcdir)/pc87306.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pc87306.Tpo $(DEPDIR)/pcem-pc87306.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pc87306.c' object='pcem-pc87306.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc87306.obj `if test -f 'pc87306.c'; then $(CYGPATH_W) 'pc87306.c'; else $(CYGPATH_W) '$(srcdir)/pc87306.c'; fi` + pcem-pci.o: pci.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-pci.Tpo $(DEPDIR)/pcem-pci.Po @@ -2465,6 +2520,20 @@ pcem-sis496.obj: sis496.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-sl82c460.o: sl82c460.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sl82c460.o -MD -MP -MF $(DEPDIR)/pcem-sl82c460.Tpo -c -o pcem-sl82c460.o `test -f 'sl82c460.c' || echo '$(srcdir)/'`sl82c460.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sl82c460.Tpo $(DEPDIR)/pcem-sl82c460.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sl82c460.c' object='pcem-sl82c460.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sl82c460.o `test -f 'sl82c460.c' || echo '$(srcdir)/'`sl82c460.c + +pcem-sl82c460.obj: sl82c460.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sl82c460.obj -MD -MP -MF $(DEPDIR)/pcem-sl82c460.Tpo -c -o pcem-sl82c460.obj `if test -f 'sl82c460.c'; then $(CYGPATH_W) 'sl82c460.c'; else $(CYGPATH_W) '$(srcdir)/sl82c460.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sl82c460.Tpo $(DEPDIR)/pcem-sl82c460.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sl82c460.c' object='pcem-sl82c460.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sl82c460.obj `if test -f 'sl82c460.c'; then $(CYGPATH_W) 'sl82c460.c'; else $(CYGPATH_W) '$(srcdir)/sl82c460.c'; fi` + pcem-sound.o: sound.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-sound.Tpo $(DEPDIR)/pcem-sound.Po @@ -2969,6 +3038,20 @@ pcem-vid_colorplus.obj: vid_colorplus.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_colorplus.obj `if test -f 'vid_colorplus.c'; then $(CYGPATH_W) 'vid_colorplus.c'; else $(CYGPATH_W) '$(srcdir)/vid_colorplus.c'; fi` +pcem-vid_compaq_cga.o: vid_compaq_cga.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_compaq_cga.o -MD -MP -MF $(DEPDIR)/pcem-vid_compaq_cga.Tpo -c -o pcem-vid_compaq_cga.o `test -f 'vid_compaq_cga.c' || echo '$(srcdir)/'`vid_compaq_cga.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_compaq_cga.Tpo $(DEPDIR)/pcem-vid_compaq_cga.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_compaq_cga.c' object='pcem-vid_compaq_cga.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_compaq_cga.o `test -f 'vid_compaq_cga.c' || echo '$(srcdir)/'`vid_compaq_cga.c + +pcem-vid_compaq_cga.obj: vid_compaq_cga.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_compaq_cga.obj -MD -MP -MF $(DEPDIR)/pcem-vid_compaq_cga.Tpo -c -o pcem-vid_compaq_cga.obj `if test -f 'vid_compaq_cga.c'; then $(CYGPATH_W) 'vid_compaq_cga.c'; else $(CYGPATH_W) '$(srcdir)/vid_compaq_cga.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_compaq_cga.Tpo $(DEPDIR)/pcem-vid_compaq_cga.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_compaq_cga.c' object='pcem-vid_compaq_cga.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_compaq_cga.obj `if test -f 'vid_compaq_cga.c'; then $(CYGPATH_W) 'vid_compaq_cga.c'; else $(CYGPATH_W) '$(srcdir)/vid_compaq_cga.c'; fi` + pcem-vid_ega.o: vid_ega.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ega.Tpo $(DEPDIR)/pcem-vid_ega.Po @@ -3109,6 +3192,20 @@ pcem-vid_olivetti_m24.obj: vid_olivetti_m24.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_oti037.o: vid_oti037.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_oti037.o -MD -MP -MF $(DEPDIR)/pcem-vid_oti037.Tpo -c -o pcem-vid_oti037.o `test -f 'vid_oti037.c' || echo '$(srcdir)/'`vid_oti037.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_oti037.Tpo $(DEPDIR)/pcem-vid_oti037.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_oti037.c' object='pcem-vid_oti037.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_oti037.o `test -f 'vid_oti037.c' || echo '$(srcdir)/'`vid_oti037.c + +pcem-vid_oti037.obj: vid_oti037.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_oti037.obj -MD -MP -MF $(DEPDIR)/pcem-vid_oti037.Tpo -c -o pcem-vid_oti037.obj `if test -f 'vid_oti037.c'; then $(CYGPATH_W) 'vid_oti037.c'; else $(CYGPATH_W) '$(srcdir)/vid_oti037.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_oti037.Tpo $(DEPDIR)/pcem-vid_oti037.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_oti037.c' object='pcem-vid_oti037.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_oti037.obj `if test -f 'vid_oti037.c'; then $(CYGPATH_W) 'vid_oti037.c'; else $(CYGPATH_W) '$(srcdir)/vid_oti037.c'; fi` + pcem-vid_oti067.o: vid_oti067.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_oti067.Tpo $(DEPDIR)/pcem-vid_oti067.Po @@ -3501,6 +3598,20 @@ pcem-x87.obj: x87.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-xi8088.o: xi8088.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-xi8088.o -MD -MP -MF $(DEPDIR)/pcem-xi8088.Tpo -c -o pcem-xi8088.o `test -f 'xi8088.c' || echo '$(srcdir)/'`xi8088.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-xi8088.Tpo $(DEPDIR)/pcem-xi8088.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xi8088.c' object='pcem-xi8088.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-xi8088.o `test -f 'xi8088.c' || echo '$(srcdir)/'`xi8088.c + +pcem-xi8088.obj: xi8088.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-xi8088.obj -MD -MP -MF $(DEPDIR)/pcem-xi8088.Tpo -c -o pcem-xi8088.obj `if test -f 'xi8088.c'; then $(CYGPATH_W) 'xi8088.c'; else $(CYGPATH_W) '$(srcdir)/xi8088.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-xi8088.Tpo $(DEPDIR)/pcem-xi8088.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xi8088.c' object='pcem-xi8088.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-xi8088.obj `if test -f 'xi8088.c'; then $(CYGPATH_W) 'xi8088.c'; else $(CYGPATH_W) '$(srcdir)/xi8088.c'; fi` + pcem-xtide.o: xtide.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-xtide.Tpo $(DEPDIR)/pcem-xtide.Po From bab6695b2c85ae71c151f4c9946b19d785a768a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 4 Mar 2018 13:59:39 +0000 Subject: [PATCH 0373/1050] CD-ROM emulation now reads multiple sectors at once. --- src/cdrom-image.cc | 4 +-- src/cdrom-ioctl-linux.c | 4 +-- src/cdrom-ioctl-osx.c | 2 +- src/cdrom-ioctl.c | 28 +++++++++++----- src/cdrom-null.c | 2 +- src/ide_atapi.h | 2 +- src/scsi_cd.c | 71 ++++++++++++++++++++--------------------- 7 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 23e3fcb..99ce8ad 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -284,10 +284,10 @@ static void image_load(void) { } -static int image_readsector(uint8_t *b, int sector) +static int image_readsector(uint8_t *b, int sector, int count) { if (!cdrom) return -1; - return !cdrom->ReadSector(b, false, sector); + return !cdrom->ReadSectors((PhysPt)b, false, sector, count); } static void image_readsector_raw(uint8_t *b, int sector) diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c index 7b8ece1..5876eca 100644 --- a/src/cdrom-ioctl-linux.c +++ b/src/cdrom-ioctl-linux.c @@ -409,13 +409,13 @@ static void ioctl_load(void) cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); } -static int ioctl_readsector(uint8_t *b, int sector) +static int ioctl_readsector(uint8_t *b, int sector, int count) { if (ioctl_fd <= 0) return -1; lseek(ioctl_fd, sector*2048, SEEK_SET); - read(ioctl_fd, b, 2048); + read(ioctl_fd, b, count*2048); return 0; } diff --git a/src/cdrom-ioctl-osx.c b/src/cdrom-ioctl-osx.c index 7f1e750..37c800f 100644 --- a/src/cdrom-ioctl-osx.c +++ b/src/cdrom-ioctl-osx.c @@ -86,7 +86,7 @@ static void ioctl_load(void) { } -static int ioctl_readsector(uint8_t *b, int sector) +static int ioctl_readsector(uint8_t *b, int sector, int count) { return 0; } diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 58e05da..3ae7a23 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -432,11 +432,11 @@ typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER { UCHAR SenseBuf[32]; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; -static int ioctl_readsector(uint8_t *b, int sector) +static int ioctl_readsector(uint8_t *b, int sector, int count) { LARGE_INTEGER pos; BOOL status; - long size; + long size = 0; if (!cdrom_drive) return -1; @@ -448,16 +448,18 @@ static int ioctl_readsector(uint8_t *b, int sector) pos.QuadPart=sector*2048; ioctl_open(0); SetFilePointer(hIOCTL,pos.LowPart,&pos.HighPart,FILE_BEGIN); - status = ReadFile(hIOCTL,b,2048,(LPDWORD)&size,NULL); + status = ReadFile(hIOCTL, b, count*2048, (LPDWORD)&size, NULL); ioctl_close(); /*If the read failed, try again using SPTI*/ - if (!status || size != 2048) + if (!status || size != count*2048) { uint8_t cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; DWORD returned; - uint8_t data_buffer[IOCTL_DATA_BUFFER]; + uint8_t *data_buffer;//[IOCTL_DATA_BUFFER]; + + data_buffer = malloc(count * IOCTL_DATA_BUFFER); ioctl_open(0); @@ -466,6 +468,9 @@ static int ioctl_readsector(uint8_t *b, int sector) cmd[3] = (uint8_t)(sector >> 16); cmd[4] = (uint8_t)(sector >> 8); cmd[5] = (uint8_t)(sector >> 0); + cmd[6] = (uint8_t)(count >> 16); + cmd[7] = (uint8_t)(count >> 8); + cmd[8] = (uint8_t)(count >> 0); memset(&swb, 0, sizeof (swb)); memcpy(swb.spt.Cdb, cmd, 12); @@ -473,9 +478,9 @@ static int ioctl_readsector(uint8_t *b, int sector) swb.spt.Length = sizeof (SCSI_PASS_THROUGH); swb.spt.CdbLength = 12; swb.spt.DataIn = SCSI_IOCTL_DATA_IN; - swb.spt.DataTransferLength = IOCTL_DATA_BUFFER; + swb.spt.DataTransferLength = count*IOCTL_DATA_BUFFER; swb.spt.DataBuffer = data_buffer; - memset(data_buffer, 0, IOCTL_DATA_BUFFER); + memset(data_buffer, 0, count*IOCTL_DATA_BUFFER); swb.spt.TimeOutValue = 80 * 60; swb.spt.SenseInfoOffset = (uintptr_t)&swb.SenseBuf - (uintptr_t)&swb;//offsetof(swb, SenseBuf); swb.spt.SenseInfoLength = 32; @@ -484,9 +489,16 @@ static int ioctl_readsector(uint8_t *b, int sector) &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &swb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &returned, NULL)) - memcpy(b, data_buffer, 2048); + { + memcpy(b, data_buffer, count*2048); + status = 1; + } + else + status = 0; ioctl_close(); + + free(data_buffer); } return !status; diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 5ba7320..d62f28b 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -59,7 +59,7 @@ static void null_load(void) { } -static int null_readsector(uint8_t *b, int sector) +static int null_readsector(uint8_t *b, int sector, int count) { return 0; } diff --git a/src/ide_atapi.h b/src/ide_atapi.h index 517417a..c46511c 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -12,7 +12,7 @@ typedef struct ATAPI int (*readtoc_session)(uint8_t *b, int msf, int maxlen); int (*readtoc_raw)(uint8_t *b, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); - int (*readsector)(uint8_t *b, int sector); + int (*readsector)(uint8_t *b, int sector, int count); void (*readsector_raw)(uint8_t *b, int sector); void (*playaudio)(uint32_t pos, uint32_t len, int ismsf); void (*seek)(uint32_t pos); diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 718c3a9..f7721f5 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -12,7 +12,7 @@ #define BUFFER_SIZE (256*1024) -#define MAX_NR_SECTORS 2 +#define MAX_NR_SECTORS 16 enum { @@ -638,28 +638,32 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; } - for (c = 0; c < MAX_NR_SECTORS; c++) - { - if (rcdmode == 0x10) - { - if (atapi->readsector(&data->data_in[c*2048], data->cdpos)) - { -// pclog("Read sector failed\n"); - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - } - else - { - atapi->readsector_raw(&data->data_in[c*2352], data->cdpos); - } - data->cdpos++; - data->cdlen--; - if (!data->cdlen) + if (rcdmode == 0x10) + { + c = MIN(data->cdlen, MAX_NR_SECTORS); + if (atapi->readsector(data->data_in, data->cdpos, c)) { - c++; - break; +// pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->cdpos += c; + data->cdlen -= c; + } + else + { + for (c = 0; c < MAX_NR_SECTORS; c++) + { + atapi->readsector_raw(&data->data_in[c*2352], data->cdpos); + + data->cdpos++; + data->cdlen--; + if (!data->cdlen) + { + c++; + break; + } } } readflash_set(READFLASH_HDC, data->id); @@ -704,23 +708,16 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; } readflash_set(READFLASH_HDC, data->id); - for (c = 0; c < MAX_NR_SECTORS; c++) + c = MIN(data->cdlen, MAX_NR_SECTORS); + if (atapi->readsector(data->data_in, data->cdpos, c)) { - if (atapi->readsector(&data->data_in[c*2048], data->cdpos)) - { - pclog("Read sector failed\n"); - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - data->cdpos++; - data->cdlen--; - if (!data->cdlen) - { - c++; - break; - } +// pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; } + data->cdpos += c; + data->cdlen -= c; data->data_pos_read = 0; data->data_pos_write = c * 2048; From a076741c6aca811c49a41e73bb5cb6956177e976 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 6 Mar 2018 21:59:22 +0000 Subject: [PATCH 0374/1050] Add OS X CD-ROM support. --- src/cdrom-ioctl-osx.c | 651 ++++++++++++++++++++++++++++++++++++++++-- src/wx-sdl2.c | 29 +- 2 files changed, 657 insertions(+), 23 deletions(-) diff --git a/src/cdrom-ioctl-osx.c b/src/cdrom-ioctl-osx.c index 37c800f..4d81bce 100644 --- a/src/cdrom-ioctl-osx.c +++ b/src/cdrom-ioctl-osx.c @@ -4,78 +4,413 @@ #include "ibm.h" #include "ide.h" #include "cdrom-ioctl.h" - +#include +#include +#include +#include +#include +#include +#include +#include +#include static ATAPI ioctl_atapi; int old_cdrom_drive; +static uint32_t cdrom_capacity = 0; +static int tocvalid = 0; +static int toc_tracks; +static int first_track, last_track; +static CDTOC *toc = NULL; +static CDDiscInfo disc_info; +static int track_addr[256]; + +static int msf_to_lba(CDMSF *msf) +{ + return msf->frame + (msf->second * 75) + (msf->minute * 60 * 75); +} + +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; +static int cd_drive = -1; + +static int cd_open() +{ + char s[80]; + + if (cd_drive < 0) + return 0; + + sprintf(s, "disk%i", cd_drive); + return opendev(s, O_RDONLY, 0, NULL); +} +static void cd_close(int fd) +{ + close(fd); +} + void ioctl_audio_callback(int16_t *output, int len) { - memset(output, 0, len * 2); + int ioctl_fd; + +// 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; + } + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + { + memset(output, 0, len * 2); + return; + } + + while (cd_buflen < len) + { + if (ioctl_cd_pos < ioctl_cd_end) + { + dk_cd_read_t cd_read; + + bzero(&cd_read, sizeof(cd_read)); + + cd_read.offset = (ioctl_cd_pos-150)*kCDSectorSizeCDDA; + cd_read.buffer = &cd_buffer[cd_buflen]; + cd_read.bufferLength = kCDSectorSizeCDDA; + cd_read.sectorType = kCDSectorTypeCDDA; + cd_read.sectorArea = kCDSectorAreaUser; + //pclog("CDDA read %llx %d %d\n", cd_read.offset, cd_read.bufferLength, ioctl_cd_pos); + + if (ioctl(ioctl_fd, DKIOCCDREAD, &cd_read) < 0) + { + //pclog("DeviceIoControl returned false %d\n", errno); + 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; + } + } + + cd_close(ioctl_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) { - return 0; + int c; + int track = 0; + + if (!tocvalid) + return 0; + + for (c = first_track; c < last_track; c++) + { + uint32_t track_address = toc->descriptors[c].p.frame + + (toc->descriptors[c].p.second * 75) + + (toc->descriptors[c].p.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) { - return 0; + int c; + int control = 0; + //pclog("is_track_audio: %08x %i\n", pos, tocvalid); + if (!tocvalid) + return 0; + //pclog(" scan tracks %i-%i\n", first_track, last_track); + for (c = first_track; c < last_track; c++) + { + uint32_t track_address = toc->descriptors[c].p.frame + + (toc->descriptors[c].p.second * 75) + + (toc->descriptors[c].p.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->descriptors[c].control; + } + return (control & 4) ? 0 : 1; } static int ioctl_is_track_audio(uint32_t pos, int ismsf) { - return 0; + if (ismsf) + { + CDMSF msf; + msf.minute = (pos >> 16) & 0xff; + msf.second = (pos >> 8) & 0xff; + msf.frame = pos & 0xff; + pos = msf_to_lba(&msf); + } + 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) +static int read_toc(int fd) { - return 0; + dk_cd_read_toc_t cd_read_toc; + dk_cd_read_disc_info_t cd_read_disc_info; + int result; + int c; + + bzero(&cd_read_toc, sizeof(cd_read_toc)); + bzero(&cd_read_disc_info, sizeof(cd_read_disc_info)); + bzero(toc, sizeof(CDTOC) + sizeof(CDTOCDescriptor)*100); + + cd_read_toc.format = kCDTOCFormatTOC; + cd_read_toc.buffer = toc; + cd_read_toc.bufferLength = 2048;//sizeof(CDTOC) + sizeof(CDTOCDescriptor)*100; + //pclog("buffer=%p bufferLength=%u\n", cd_read_toc.buffer, cd_read_toc.bufferLength); + result = ioctl(fd, DKIOCCDREADTOC, &cd_read_toc); + + //pclog("Read_toc - fd=%d result=%d errno=%d toc=%p\n", fd, result, errno, toc); + if (result < 0) + { + //pclog("read_toc: DKIOCCDREADTOC failed\n"); + return 0; + } + + //pclog("toc length=%u first=%u last=%u\n", toc->length, toc->sessionFirst, toc->sessionFirst); + first_track = 1; + last_track = 0; + toc_tracks = CDTOCGetDescriptorCount(toc); + + for (c = 0; c < toc_tracks; c++) + { + if (toc->descriptors[c].session > 1) + continue; + track_addr[c] = msf_to_lba(&toc->descriptors[c].p); + //pclog("Track %i %02x addr %08x\n", c, toc->descriptors[c].point, track_addr[c]); + if (toc->descriptors[c].point <= 99 && toc->descriptors[c].adr == 1) + last_track++; + } + + //pclog("Tracks %i %i %i\n", first_track, last_track, toc_tracks); + + cd_read_disc_info.buffer = &disc_info; + cd_read_disc_info.bufferLength = sizeof(disc_info); + result = ioctl(fd, DKIOCCDREADDISCINFO, &cd_read_disc_info); + if (result < 0) + { + //pclog("read_toc: DKIOCCDREADDISCINFO failed\n"); + return 0; + } + + return 1; } static int ioctl_ready(void) { - return 0; + int ioctl_fd = cd_open(); + //pclog("ioctl_ready - %d %d\n", ioctl_fd, tocvalid); + if (ioctl_fd <= 0) + return 0; + cd_close(ioctl_fd); + + if (tocvalid) + return 1; + + return 0; } static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) { - return 0; + int c; + int lb = 0; + int tv = 0; + int ioctl_fd; + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return 0; + + //ioctl_cd_state = CD_STOPPED; + + if (!tocvalid) + tv = read_toc(ioctl_fd); + + cd_close(ioctl_fd); + + if (!tv) + return 0; + + for (c = 0; c <= toc_tracks; c++) + { + if (track_addr[c] > lb) + lb = track_addr[c]; + } + return lb; } static int ioctl_medium_changed(void) { - return 0; + dk_cd_read_disc_info_t cd_read_disc_info; + CDDiscInfo new_disc_info; + int result; + int ioctl_fd; + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return 1; + + bzero(&cd_read_disc_info, sizeof(cd_read_disc_info)); + cd_read_disc_info.buffer = &new_disc_info; + cd_read_disc_info.bufferLength = sizeof(new_disc_info); + result = ioctl(ioctl_fd, DKIOCCDREADDISCINFO, &cd_read_disc_info); + if (result < 0) + { + //pclog("medium_changed: DKIOCCDREADDISCINFO failed\n"); + ioctl_cd_state = CD_STOPPED; + tocvalid = 0; + cd_close(ioctl_fd); + return 1; + } + + if (memcmp(&disc_info, &new_disc_info, sizeof(CDDiscInfo))) + { + //pclog("medium_changed: disc changed\n"); + ioctl_cd_state = CD_STOPPED; + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); + return 1; + } + + cd_close(ioctl_fd); + return 0; } static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) { - return 0x13; + uint32_t cdpos = ioctl_cd_pos; + int track = get_track_nr(cdpos); + uint32_t track_address = track_addr[track]; + long size; + int pos=0; + int err; + uint8_t ret; + + + if (ioctl_cd_state == CD_PLAYING) + ret = 0x11; + else if (ioctl_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + + b[pos++] = (toc->descriptors[track].adr << 4) | toc->descriptors[track].control; + b[pos++] = toc->descriptors[track].point; + 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; + } + + //pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i state=%i ret=%02x\n", cdpos, track_address, track, ioctl_cd_state, ret); + + return ret; } static void ioctl_eject(void) @@ -88,59 +423,331 @@ static void ioctl_load(void) static int ioctl_readsector(uint8_t *b, int sector, int count) { - return 0; -} + dk_cd_read_t cd_read; + int res; + int ioctl_fd; + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return -1; + //pclog("Read sector %x %i\n", sector, count); + + bzero(&cd_read, sizeof(cd_read)); + + cd_read.offset = sector*2048; + cd_read.buffer = b; + cd_read.bufferLength = count*2048; + cd_read.sectorType = kCDSectorTypeMode1; + cd_read.sectorArea = kCDSectorAreaUser; + + res = ioctl(ioctl_fd, DKIOCCDREAD, &cd_read); + //pclog("read res = %i %i %i\n", res, cd_read.bufferLength, errno); -static int lba_to_msf(int lba) -{ - return 0; + cd_close(ioctl_fd); + + return 0; } static void ioctl_readsector_raw(uint8_t *b, int sector) { + dk_cd_read_t cd_read; + int res; + int ioctl_fd; + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return; + //pclog("Read sector %x %i\n", sector, count); + + bzero(&cd_read, sizeof(cd_read)); + + cd_read.offset = sector*kCDSectorSizeWhole; + cd_read.buffer = b; + cd_read.bufferLength = kCDSectorSizeWhole; + cd_read.sectorType = kCDSectorTypeUnknown; + cd_read.sectorArea = kCDSectorAreaUser; + + res = ioctl(ioctl_fd, DKIOCCDREAD, &cd_read); + //pclog("read res = %i %i %i\n", res, cd_read.bufferLength, errno); + + cd_close(ioctl_fd); } static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - return 0; + int len=4; + int c,d; + uint32_t temp; + uint32_t last_address = 0; + int seenAA = 0; + + pclog("ioctl_readtoc\n"); + //ioctl_cd_state = CD_STOPPED; + + if (!tocvalid) + { + int ioctl_fd = cd_open(); + + if (ioctl_fd <= 0) + return 4; + + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_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 = 0; c <= toc_tracks; c++) + { + if (toc->descriptors[c].point && toc->descriptors[c].point >= starttrack && toc->descriptors[c].point <= 99) + { + d = c; + break; + } + } + //pclog("Start from track %i\n",d); + b[2] = toc->descriptors[c].point; + //last_block = 0; + + for (c = d; c <= toc_tracks; 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->descriptors[c].point,toc->descriptors[c].adr,toc->descriptors[c].control,toc->descriptors[c].p.minute, toc->descriptors[c].p.second, toc->descriptors[c].p.frame,track_addr[c]); + address = track_addr[c]; + if (address < last_address) + continue; + if (toc->descriptors[c].point == 0xaa) + seenAA = 1; + last_address = address; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc->descriptors[c].adr << 4) | toc->descriptors[c].control; + b[len++] = toc->descriptors[c].point; + b[len++] = 0; /*Reserved*/ + //if (address > last_block) + // last_block = address; + + if (msf) + { + b[len++] = 0; + b[len++] = toc->descriptors[c].p.minute; + b[len++] = toc->descriptors[c].p.second; + b[len++] = toc->descriptors[c].p.frame; + } + else + { + temp = track_addr[c]; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + + if (!seenAA && !single) + { + uint32_t lb = 0; + + for (c = 0; c <= toc_tracks; c++) + { + if (track_addr[c] > lb) + lb = track_addr[c]; + } + //pclog("Track AA - %08x %i\n", lb, len); + b[len++] = 0; /*Reserved*/ + b[len++] = (1 << 4) | 1; + b[len++] = 0xaa; + b[len++] = 0; /*Reserved*/ + + if (msf) + { + b[len++] = 0; + b[len++] = (lb / 60) / 75; + b[len++] = (lb / 75) % 60; + b[len++] = lb % 75; + } + else + { + temp = track_addr[c]; + b[len++] = lb >> 24; + b[len++] = lb >> 16; + b[len++] = lb >> 8; + b[len++] = lb; + } + } + + 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) { - return 0; + int len = 4; + int session = 0, first_track_nr = 0; + int c, d; + + if (!tocvalid) + { + int ioctl_fd = cd_open(); + + if (ioctl_fd <= 0) + return 4; + + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); + } + + if (!tocvalid) + return 4; + + for (c = 0; c <= toc_tracks; c++) + { + if (toc->descriptors[c].point && toc->descriptors[c].point <= 99) + { + if (toc->descriptors[c].session > session || (toc->descriptors[c].session == session && toc->descriptors[c].point < first_track_nr)) + { + session = toc->descriptors[c].session; + first_track_nr = toc->descriptors[c].point; + d = c; + } + } + } + + b[2] = toc->sessionFirst; + b[3] = toc->sessionLast; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc->descriptors[d].adr << 4) | toc->descriptors[d].control; + b[len++] = toc->descriptors[d].point; + b[len++] = 0; /*Reserved*/ + if (msf) + { + b[len++] = 0; + b[len++] = toc->descriptors[d].p.minute; + b[len++] = toc->descriptors[d].p.second; + b[len++] = toc->descriptors[d].p.frame; + } + else + { + uint32_t temp = track_addr[d]; + 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) { - return 0; + int len = 4; + int ioctl_fd; + int track; + +//pclog("read_toc\n"); + if (!tocvalid) + return 0; + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return 0; + cd_close(ioctl_fd); + + b[2] = toc->sessionFirst; + b[3] = toc->sessionLast; + + for (track = 0; track <= toc_tracks; track++) + { + if ((len + 11) > maxlen) + { + pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + +// 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++] = toc->descriptors[track].session; + b[len++] = (toc->descriptors[track].adr << 4) | toc->descriptors[track].control; + b[len++] = toc->descriptors[track].tno; + b[len++] = toc->descriptors[track].point; + b[len++] = toc->descriptors[track].address.minute; + b[len++] = toc->descriptors[track].address.second; + b[len++] = toc->descriptors[track].address.frame; + b[len++] = toc->descriptors[track].zero; + b[len++] = toc->descriptors[track].p.minute; + b[len++] = toc->descriptors[track].p.second; + b[len++] = toc->descriptors[track].p.frame; + } + + return len; } static uint32_t ioctl_size() { - return 0; + return cdrom_capacity; } static int ioctl_status() { - return CD_STATUS_EMPTY; + if (!ioctl_ready) + return CD_STATUS_EMPTY; + return CD_STATUS_STOPPED; } void ioctl_reset() { + int ioctl_fd; + + tocvalid = 0; + + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return; + + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); } void ioctl_set_drive(char d) { - atapi = &ioctl_atapi; + ioctl_close(); + atapi=&ioctl_atapi; + ioctl_open(d); } int ioctl_open(char d) { atapi = &ioctl_atapi; + + toc = malloc(2048); + + cd_drive = d; return 0; } void ioctl_close(void) { + if (toc) + { + free(toc); + toc = NULL; + } } static void ioctl_exit(void) diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 940d931..50e7a44 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -42,6 +42,14 @@ #include "wx-common.h" #include "wx-display.h" +#if __APPLE__ +#define pause __pause +#include +#include +#include +#undef pause +#endif + extern void creatediscimage_open(void *hwnd); #define ID_IS(s) wParam == wx_xrcid(s) @@ -383,8 +391,27 @@ void wx_initmenu() } #elif __linux__ wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+1, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); +#elif __APPLE__ + int c; + + for (c = 1; c < 99; c++) + { + char s[80]; + int fd; + + sprintf(s, "disk%i", c); + fd = opendev(s, O_RDONLY, 0, NULL); + if (fd > 0) + { + char name[255]; + + close(fd); + + sprintf(name, "Host CD/DVD Drive (/dev/disk%i)", c); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL+c, name, wxITEM_RADIO); + } + } #endif - } int wx_setupmenu(void* data) From 4182b10e10bd300e55247a740abb0b1d39d10e37 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 09:43:54 +0000 Subject: [PATCH 0375/1050] Refactored DMA code. --- src/dma.c | 779 ++++++++++++++++++++++++++++++------------------------ src/ibm.h | 27 +- 2 files changed, 442 insertions(+), 364 deletions(-) diff --git a/src/dma.c b/src/dma.c index bc4aba2..76d88a8 100644 --- a/src/dma.c +++ b/src/dma.c @@ -4,6 +4,7 @@ #include "fdc.h" #include "io.h" #include "mem.h" +#include "ps2_mca.h" #include "video.h" #include "x86.h" @@ -11,57 +12,73 @@ static uint8_t dmaregs[16]; static uint8_t dma16regs[16]; static uint8_t dmapages[16]; +static int dma_wp, dma16_wp; +static uint8_t dma_m; +static uint8_t dma_stat; +static uint8_t dma_stat_rq; +static uint8_t dma_command, dma16_command; + +static struct +{ + int xfr_command, xfr_channel; + int byte_ptr; + + int is_ps2; +} dma_ps2; + +#define DMA_PS2_IOA (1 << 0) +#define DMA_PS2_XFER_MEM_TO_IO (1 << 2) +#define DMA_PS2_XFER_IO_TO_MEM (3 << 2) +#define DMA_PS2_XFER_MASK (3 << 2) +#define DMA_PS2_DEC2 (1 << 4) +#define DMA_PS2_SIZE16 (1 << 6) + +static void dma_ps2_run(int channel); + void dma_reset() { int c; - dma.wp = 0; + + dma_wp = dma16_wp = 0; + dma_m = 0; + for (c = 0; c < 16; c++) dmaregs[c] = 0; - for (c = 0; c < 4; c++) + for (c = 0; c < 8; c++) { - dma.mode[c] = 0; - dma.ac[c] = 0; - dma.cc[c] = 0; - dma.ab[c] = 0; - dma.cb[c] = 0; + dma[c].mode = 0; + dma[c].ac = 0; + dma[c].cc = 0; + dma[c].ab = 0; + dma[c].cb = 0; + dma[c].size = (c & 4) ? 1 : 0; } - dma.m = 0; - - dma16.wp = 0; - for (c = 0; c < 16; c++) - dma16regs[c] = 0; - for (c = 0; c < 4; c++) - { - dma16.mode[c] = 0; - dma16.ac[c] = 0; - dma16.cc[c] = 0; - dma16.ab[c] = 0; - dma16.cb[c] = 0; - } - dma16.m = 0; } uint8_t dma_read(uint16_t addr, void *priv) { + int channel = (addr >> 1) & 3; 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) & 0xff; + dma_wp ^= 1; + if (dma_wp) + return dma[channel].ac & 0xff; + return (dma[channel].ac >> 8) & 0xff; case 1: case 3: case 5: case 7: /*Count registers*/ - dma.wp ^= 1; - if (dma.wp) temp = dma.cc[(addr >> 1) & 3] & 0xff; - else temp = dma.cc[(addr >> 1) & 3] >> 8; + dma_wp ^= 1; + if (dma_wp) + temp = dma[channel].cc & 0xff; + else + temp = dma[channel].cc >> 8; return temp; case 8: /*Status register*/ - temp = dma.stat; - dma.stat = 0; + temp = dma_stat & 0xf; + dma_stat &= ~0xf; return temp; case 0xd: @@ -73,122 +90,131 @@ uint8_t dma_read(uint16_t addr, void *priv) void dma_write(uint16_t addr, uint8_t val, void *priv) { + int channel = (addr >> 1) & 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] & 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]; + dma_wp ^= 1; + if (dma_wp) + dma[channel].ab = (dma[channel].ab & 0xffff00) | val; + else + dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); + dma[channel].ac = dma[channel].ab; // pclog("Addr = %04x\n", 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); - dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3]; + dma_wp ^= 1; + if (dma_wp) + dma[channel].cb = (dma[channel].cb & 0xff00) | val; + else + dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); + dma[channel].cc = dma[channel].cb; return; case 8: /*Control register*/ - dma.command = val; + dma_command = val; return; case 0xa: /*Mask*/ - if (val & 4) dma.m |= (1 << (val & 3)); - else dma.m &= ~(1 << (val & 3)); + if (val & 4) + dma_m |= (1 << (val & 3)); + else + dma_m &= ~(1 << (val & 3)); return; case 0xb: /*Mode*/ - dma.mode[val & 3] = val; - if (dma.is_ps2) + channel = (val & 3); + dma[channel].mode = val; + if (dma_ps2.is_ps2) { - dma.ps2_mode[val & 3] &= ~0x1c; + dma[channel].ps2_mode &= ~0x1c; if (val & 0x20) - dma.ps2_mode[val & 3] |= 0x10; + dma[channel].ps2_mode |= 0x10; if ((val & 0xc) == 8) - dma.ps2_mode[val & 3] |= 4; + dma[channel].ps2_mode |= 4; else if ((val & 0xc) == 4) - dma.ps2_mode[val & 3] |= 0xc; + dma[channel].ps2_mode |= 0xc; } return; case 0xc: /*Clear FF*/ - dma.wp = 0; + dma_wp = 0; return; case 0xd: /*Master clear*/ - dma.wp = 0; - dma.m = 0xf; + dma_wp = 0; + dma_m |= 0xf; return; case 0xf: /*Mask write*/ - dma.m = val & 0xf; + dma_m = (dma_m & 0xf0) | (val & 0xf); return; } } static uint8_t dma_ps2_read(uint16_t addr, void *priv) { + dma_t *dma_c = &dma[dma_ps2.xfr_channel]; uint8_t temp = 0xff; switch (addr) { case 0x1a: - switch (dma.xfr_command) + switch (dma_ps2.xfr_command) { case 2: /*Address*/ case 3: - switch (dma.byte_ptr) + switch (dma_ps2.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; + temp = dma_c->ac & 0xff; + dma_ps2.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; + temp = (dma_c->ac >> 8) & 0xff; + dma_ps2.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; + temp = (dma_c->ac >> 16) & 0xff; + dma_ps2.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); + if (dma_ps2.byte_ptr) + temp = dma_c->cc >> 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; + temp = dma_c->cc & 0xff; + dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; break; case 6: /*Read DMA status*/ - if (dma.byte_ptr) + if (dma_ps2.byte_ptr) { - temp = dma16.stat_rq | (dma16.stat << 4); - dma16.stat = 0; - dma16.stat_rq = 0; + temp = ((dma_stat_rq & 0xf0) >> 4) | (dma_stat & 0xf0); + dma_stat &= ~0xf0; + dma_stat_rq &= ~0xf0; } else { - temp = dma.stat_rq | (dma.stat << 4); - dma.stat = 0; - dma.stat_rq = 0; + temp = (dma_stat_rq & 0xf) | ((dma_stat & 0xf) << 4); + dma_stat &= ~0xf; + dma_stat_rq &= ~0xf; } - dma.byte_ptr = (dma.byte_ptr + 1) & 1; + dma_ps2.byte_ptr = (dma_ps2.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]; + temp = dma_c->ps2_mode; break; case 8: /*Arbitration Level*/ - temp = (dma.xfr_channel & 4) ? dma16.arb_level[dma.xfr_channel & 3] : dma.arb_level[dma.xfr_channel]; + temp = dma_c->arb_level; break; default: - fatal("Bad XFR Read command %i channel %i\n", dma.xfr_command, dma.xfr_channel); + fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); } break; } @@ -200,6 +226,7 @@ static uint8_t dma_ps2_read(uint16_t addr, void *priv) static void dma_ps2_write(uint16_t addr, uint8_t val, void *priv) { + dma_t *dma_c = &dma[dma_ps2.xfr_channel]; uint8_t mode; // pclog("Write PS2 DMA %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); @@ -207,114 +234,83 @@ static void dma_ps2_write(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x18: - dma.xfr_channel = val & 0x7; - dma.xfr_command = val >> 4; - dma.byte_ptr = 0; - switch (dma.xfr_command) + dma_ps2.xfr_channel = val & 0x7; + dma_ps2.xfr_command = val >> 4; + dma_ps2.byte_ptr = 0; + switch (dma_ps2.xfr_command) { case 9: /*Set DMA mask*/ - if (dma.xfr_channel & 4) - dma16.m |= (1 << (dma.xfr_channel & 3)); - else - dma.m |= (1 << dma.xfr_channel); + dma_m |= (1 << dma_ps2.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); + dma_m &= ~(1 << dma_ps2.xfr_channel); break; + case 0xb: + if (!(dma_m & (1 << dma_ps2.xfr_channel))) + dma_ps2_run(dma_ps2.xfr_channel); + break; + +// case 0xb: output = 3; break; } break; case 0x1a: - switch (dma.xfr_command) + switch (dma_ps2.xfr_command) { + case 0: /*I/O address*/ + if (dma_ps2.byte_ptr) + dma_c->io_addr = (dma_c->io_addr & 0x00ff) | (val << 8); + else + dma_c->io_addr = (dma_c->io_addr & 0xff00) | val; + dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; + break; + case 2: /*Address*/ - switch (dma.byte_ptr) + switch (dma_ps2.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; + dma_c->ac = (dma_c->ac & 0xffff00) | val; + dma_ps2.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; + dma_c->ac = (dma_c->ac & 0xff00ff) | (val << 8); + dma_ps2.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; + dma_c->ac = (dma_c->ac & 0x00ffff) | (val << 16); + dma_ps2.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]; + dma_c->ab = dma_c->ac; 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); - } + if (dma_ps2.byte_ptr) + dma_c->cc = (dma_c->cc & 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]; + dma_c->cc = (dma_c->cc & 0xff00) | val; + dma_ps2.byte_ptr = (dma_ps2.byte_ptr + 1) & 1; + dma_c->cb = dma_c->cc; break; case 7: /*Mode register*/ mode = 0; - if (val & 0x10) + if (val & DMA_PS2_DEC2) mode |= 0x20; - if ((val & 0xc) == 4) + if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_MEM_TO_IO) mode |= 8; - else if ((val & 0xc) == 0xc) + else if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_IO_TO_MEM) 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; - } + dma_c->mode = (dma_c->mode & ~0x2c) | mode; + dma_c->ps2_mode = val; + dma_c->size = val & DMA_PS2_SIZE16; break; case 8: /*Arbitration Level*/ - if (dma.xfr_channel & 4) - dma16.arb_level[dma.xfr_channel & 3] = val; - else - dma.arb_level[dma.xfr_channel] = val; + dma_c->arb_level = val; break; default: - fatal("Bad XFR command %i channel %i val %02x\n", dma.xfr_command, dma.xfr_channel, val); + fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); } break; } @@ -322,32 +318,35 @@ static void dma_ps2_write(uint16_t addr, uint8_t val, void *priv) uint8_t dma16_read(uint16_t addr, void *priv) { + int channel = ((addr >> 2) & 3) + 4; uint8_t temp; // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); addr >>= 1; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ - dma16.wp ^= 1; - if (dma.is_ps2) + dma16_wp ^= 1; + if (dma_ps2.is_ps2) { - if (dma16.wp) - return dma16.ac[(addr >> 1) & 3] & 0xff; - return (dma16.ac[(addr >> 1) & 3] >> 8) & 0xff; + if (dma16_wp) + return dma[channel].ac; + return (dma[channel].ac >> 8) & 0xff; } - if (dma16.wp) - return (dma16.ac[(addr >> 1) & 3] >> 1) & 0xff; - return (dma16.ac[(addr >> 1) & 3] >> 9) & 0xff; + if (dma16_wp) + return (dma[channel].ac >> 1) & 0xff; + return (dma[channel].ac >> 9) & 0xff; case 1: case 3: case 5: case 7: /*Count registers*/ - dma16.wp ^= 1; - if (dma16.wp) temp = dma16.cc[(addr >> 1) & 3] & 0xff; - else temp = dma16.cc[(addr >> 1) & 3] >> 8; + dma16_wp ^= 1; + if (dma16_wp) + temp = dma[channel].cc & 0xff; + else + temp = dma[channel].cc >> 8; return temp; case 8: /*Status register*/ - temp = dma16.stat; - dma16.stat = 0; + temp = dma_stat >> 4; + dma_stat &= ~0xf0; return temp; } return dma16regs[addr & 0xf]; @@ -355,66 +354,76 @@ uint8_t dma16_read(uint16_t addr, void *priv) void dma16_write(uint16_t addr, uint8_t val, void *priv) { + int channel = ((addr >> 2) & 3) + 4; // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); addr >>= 1; dma16regs[addr & 0xf] = val; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ - dma16.wp ^= 1; - if (dma.is_ps2) + dma16_wp ^= 1; + if (dma_ps2.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); + if (dma16_wp) + dma[channel].ab = (dma[channel].ab & 0xffff00) | val; + else + dma[channel].ab = (dma[channel].ab & 0xff00ff) | (val << 8); } else { - if (dma16.wp) 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); + if (dma16_wp) + dma[channel].ab = (dma[channel].ab & 0xfffe00) | (val << 1); + else + dma[channel].ab = (dma[channel].ab & 0xfe01ff) | (val << 9); } - dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3]; + dma[channel].ac = dma[channel].ab; 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); - dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3]; + dma16_wp ^= 1; + if (dma16_wp) + dma[channel].cb = (dma[channel].cb & 0xff00) | val; + else + dma[channel].cb = (dma[channel].cb & 0x00ff) | (val << 8); + dma[channel].cc = dma[channel].cb; return; case 8: /*Control register*/ return; case 0xa: /*Mask*/ - if (val & 4) dma16.m |= (1 << (val & 3)); - else dma16.m &= ~(1 << (val & 3)); + if (val & 4) + dma_m |= (0x10 << (val & 3)); + else + dma_m &= ~(0x10 << (val & 3)); return; case 0xb: /*Mode*/ - dma16.mode[val & 3] = val; - if (dma.is_ps2) + channel = (val & 3) + 4; + dma[channel].mode = val; + if (dma_ps2.is_ps2) { - dma16.ps2_mode[val & 3] &= ~0x1c; + dma[channel].ps2_mode &= ~0x1c; if (val & 0x20) - dma16.ps2_mode[val & 3] |= 0x10; + dma[channel].ps2_mode |= 0x10; if ((val & 0xc) == 8) - dma16.ps2_mode[val & 3] |= 4; + dma[channel].ps2_mode |= 4; else if ((val & 0xc) == 4) - dma16.ps2_mode[val & 3] |= 0xc; + dma[channel].ps2_mode |= 0xc; } return; case 0xc: /*Clear FF*/ - dma16.wp = 0; + dma16_wp = 0; return; case 0xd: /*Master clear*/ - dma16.wp = 0; - dma16.m = 0xf; + dma16_wp = 0; + dma_m |= 0xf0; return; case 0xf: /*Mask write*/ - dma16.m = val&0xf; + dma_m = (dma_m & 0x0f) | ((val & 0xf) << 4); return; } } @@ -426,39 +435,39 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) 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); + dma[2].page = (AT) ? val : val & 0xf; + dma[2].ab = (dma[2].ab & 0xffff) | (dma[2].page << 16); + dma[2].ac = (dma[2].ac & 0xffff) | (dma[2].page << 16); break; case 2: - dma.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); + dma[3].page = (AT) ? val : val & 0xf; + dma[3].ab = (dma[3].ab & 0xffff) | (dma[3].page << 16); + dma[3].ac = (dma[3].ac & 0xffff) | (dma[3].page << 16); break; case 3: - dma.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); + dma[1].page = (AT) ? val : val & 0xf; + dma[1].ab = (dma[1].ab & 0xffff) | (dma[1].page << 16); + dma[1].ac = (dma[1].ac & 0xffff) | (dma[1].page << 16); break; case 7: - dma.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); + dma[0].page = (AT) ? val : val & 0xf; + dma[0].ab = (dma[0].ab & 0xffff) | (dma[0].page << 16); + dma[0].ac = (dma[0].ac & 0xffff) | (dma[0].page << 16); break; case 0x9: - 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); + dma[6].page = val & 0xfe; + dma[6].ab = (dma[6].ab & 0x1ffff) | (dma[6].page << 16); + dma[6].ac = (dma[6].ac & 0x1ffff) | (dma[6].page << 16); break; case 0xa: - 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); + dma[7].page = val & 0xfe; + dma[7].ab = (dma[7].ab & 0x1ffff) | (dma[7].page << 16); + dma[7].ac = (dma[7].ac & 0x1ffff) | (dma[7].page << 16); break; case 0xb: - 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); + dma[5].page = val & 0xfe; + dma[5].ab = (dma[5].ab & 0x1ffff) | (dma[5].page << 16); + dma[5].ac = (dma[5].ac & 0x1ffff) | (dma[5].page << 16); break; } } @@ -472,7 +481,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; + dma_ps2.is_ps2 = 0; } void dma16_init() @@ -485,7 +494,7 @@ 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; + dma_ps2.is_ps2 = 1; } @@ -503,195 +512,267 @@ void _dma_write(uint32_t addr, uint8_t val) int dma_channel_read(int channel) { + dma_t *dma_c = &dma[channel]; uint16_t temp; int tc = 0; - if (dma.command & 0x04) - return DMA_NODATA; - - if (!AT) - refreshread(); - if (channel < 4) { - if (dma.m & (1 << channel)) - return DMA_NODATA; - if ((dma.mode[channel] & 0xC) != 8) - return DMA_NODATA; - - temp = _dma_read(dma.ac[channel]); - dma.stat_rq |= (1 << 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) - return temp | DMA_OVER; - return temp; + if (dma_command & 0x04) + return DMA_NODATA; } else { - channel &= 3; - if (dma16.m & (1 << channel)) - return DMA_NODATA; - if ((dma16.mode[channel] & 0xC) != 8) - return DMA_NODATA; + if (dma16_command & 0x04) + return DMA_NODATA; + } + + if (!AT) + refreshread(); - temp = _dma_read(dma16.ac[channel]) | - (_dma_read(dma16.ac[channel] + 1) << 8); - dma16.stat_rq |= (1 << channel); + if (dma_m & (1 << channel)) + return DMA_NODATA; + if ((dma_c->mode & 0xC) != 8) + return DMA_NODATA; + + if (!dma_c->size) + { + temp = _dma_read(dma_c->ac); - if (dma16.mode[channel] & 0x20) + if (dma_c->mode & 0x20) { - if (dma.is_ps2) - dma16.ac[channel] -= 2; + if (dma_ps2.is_ps2) + dma_c->ac--; else - dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] - 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); } else { - if (dma.is_ps2) - dma16.ac[channel] += 2; + if (dma_ps2.is_ps2) + dma_c->ac++; else - dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] + 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); } - - 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; } + else + { + temp = _dma_read(dma_c->ac) | + (_dma_read(dma_c->ac + 1) << 8); + + if (dma_c->mode & 0x20) + { + if (dma_ps2.is_ps2) + dma_c->ac -= 2; + else + dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); + } + else + { + if (dma_ps2.is_ps2) + dma_c->ac += 2; + else + dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); + } + } + + dma_stat_rq |= (1 << channel); + + dma_c->cc--; + if (dma_c->cc < 0) + { + tc = 1; + if (dma_c->mode & 0x10) /*Auto-init*/ + { + dma_c->cc = dma_c->cb; + dma_c->ac = dma_c->ab; + } + else + dma_m |= (1 << channel); + dma_stat |= (1 << channel); + } + + if (tc) + return temp | DMA_OVER; + return temp; } int dma_channel_write(int channel, uint16_t val) { - if (dma.command & 0x04) - return DMA_NODATA; + dma_t *dma_c = &dma[channel]; + + if (channel < 4) + { + if (dma_command & 0x04) + return DMA_NODATA; + } + else + { + if (dma16_command & 0x04) + return DMA_NODATA; + } if (!AT) refreshread(); - if (channel < 4) - { - if (dma.m & (1 << channel)) - return DMA_NODATA; - if ((dma.mode[channel] & 0xC) != 4) - return DMA_NODATA; + if (dma_m & (1 << channel)) + return DMA_NODATA; + if ((dma_c->mode & 0xC) != 4) + return DMA_NODATA; - _dma_write(dma.ac[channel], val); - dma.stat_rq |= (1 << channel); + if (!dma_c->size) + { + _dma_write(dma_c->ac, val); - if (dma.mode[channel] & 0x20) + if (dma_c->mode & 0x20) { - if (dma.is_ps2) - dma.ac[channel]--; + if (dma_ps2.is_ps2) + dma_c->ac--; else - dma.ac[channel] = (dma.ac[channel] & 0xff0000) | ((dma.ac[channel] - 1) & 0xffff); + dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac - 1) & 0xffff); } else { - if (dma.is_ps2) - dma.ac[channel]++; + if (dma_ps2.is_ps2) + dma_c->ac++; else - dma.ac[channel] = (dma.ac[channel] & 0xff0000) | ((dma.ac[channel] + 1) & 0xffff); + dma_c->ac = (dma_c->ac & 0xff0000) | ((dma_c->ac + 1) & 0xffff); } - - 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.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; + _dma_write(dma_c->ac, val); + _dma_write(dma_c->ac + 1, val >> 8); - _dma_write(dma16.ac[channel], val); - _dma_write(dma16.ac[channel] + 1, val >> 8); - dma16.stat_rq |= (1 << channel); - - if (dma16.mode[channel] & 0x20) + if (dma_c->mode & 0x20) { - if (dma.is_ps2) - dma16.ac[channel] -= 2; + if (dma_ps2.is_ps2) + dma_c->ac -= 2; else - dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] - 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac - 2) & 0x1ffff); } else { - if (dma.is_ps2) - dma16.ac[channel] += 2; + if (dma_ps2.is_ps2) + dma_c->ac += 2; else - dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] + 2) & 0x1ffff); + dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); } - - dma16.cc[channel]--; - if (dma16.cc[channel] < 0) - { - 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 (dma16.m & (1 << channel)) - return DMA_OVER; } + + dma_stat_rq |= (1 << channel); + + dma_c->cc--; + if (dma_c->cc < 0) + { + if (dma_c->mode & 0x10) /*Auto-init*/ + { + dma_c->cc = dma_c->cb; + dma_c->ac = dma_c->ab; + } + else + dma_m |= (1 << channel); + dma_stat |= (1 << channel); + } + + if (dma_m & (1 << channel)) + return DMA_OVER; + return 0; } + +static void dma_ps2_run(int channel) +{ + dma_t *dma_c = &dma[channel]; + + switch (dma_c->ps2_mode & DMA_PS2_XFER_MASK) + { + case DMA_PS2_XFER_MEM_TO_IO: + do + { + if (!dma_c->size) + { + uint8_t temp = _dma_read(dma_c->ac); + outb(dma_c->io_addr, temp); + + if (dma_c->ps2_mode & DMA_PS2_DEC2) + dma_c->ac--; + else + dma_c->ac++; + } + else + { + uint16_t temp = _dma_read(dma_c->ac) | (_dma_read(dma_c->ac + 1) << 8); + outw(dma_c->io_addr, temp); + + if (dma_c->ps2_mode & DMA_PS2_DEC2) + dma_c->ac -= 2; + else + dma_c->ac += 2; + } + + dma_stat_rq |= (1 << channel); + dma_c->cc--; + } while (dma_c->cc > 0); + + dma_stat |= (1 << channel); + break; + + case DMA_PS2_XFER_IO_TO_MEM: + do + { + if (!dma_c->size) + { + uint8_t temp = inb(dma_c->io_addr); + _dma_write(dma_c->ac, temp); + + if (dma_c->ps2_mode & DMA_PS2_DEC2) + dma_c->ac--; + else + dma_c->ac++; + } + else + { + uint16_t temp = inw(dma_c->io_addr); + _dma_write(dma_c->ac, temp & 0xff); + _dma_write(dma_c->ac + 1, temp >> 8); + + if (dma_c->ps2_mode & DMA_PS2_DEC2) + dma_c->ac -= 2; + else + dma_c->ac += 2; + } + + dma_stat_rq |= (1 << channel); + dma_c->cc--; + } while (dma_c->cc > 0); + + ps2_cache_clean(); + dma_stat |= (1 << channel); + break; + + default: /*Memory verify*/ + do + { + if (!dma_c->size) + { + if (dma_c->ps2_mode & DMA_PS2_DEC2) + dma_c->ac--; + else + dma_c->ac++; + } + else + { + if (dma_c->ps2_mode & DMA_PS2_DEC2) + dma_c->ac -= 2; + else + dma_c->ac += 2; + } + + dma_stat_rq |= (1 << channel); + dma->cc--; + } while (dma->cc > 0); + + dma_stat |= (1 << channel); + break; + } +} diff --git a/src/ibm.h b/src/ibm.h index be6c68a..6f1c001 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -328,27 +328,24 @@ float pit_timer0_freq(); /*DMA*/ -typedef struct DMA +typedef struct dma_t { - uint32_t ab[4],ac[4]; - uint16_t cb[4]; - int cc[4]; + uint32_t ab, ac; + uint16_t cb; + int cc; int wp; - uint8_t m,mode[4]; - uint8_t page[4]; + uint8_t m, mode; + uint8_t page; uint8_t stat, stat_rq; uint8_t command; + int size; - 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; + uint8_t ps2_mode; + uint8_t arb_level; + uint16_t io_addr; +} dma_t; +dma_t dma[8]; /*PPI*/ typedef struct PPI From 8546ce14f0705ba2baa4cc6ed7cabde733d13c2c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 11:03:20 +0000 Subject: [PATCH 0376/1050] Added waitstates on instruction fetch from ROM. --- src/cpu.c | 12 ++++++++++-- src/cpu.h | 2 +- src/mem.c | 44 +++++++++++++++++++++----------------------- src/mem.h | 2 ++ src/rom.c | 4 ++-- 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index eed48a4..dfe6c65 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -82,7 +82,7 @@ int cpu_cyrix_alignment; 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_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; @@ -508,6 +508,8 @@ void cpu_set() cpu_update_waitstates(); isa_cycles = cpu_s->atclk_div; + + cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; if (cpu_s->pci_speed) { @@ -1627,7 +1629,10 @@ void cpu_update_waitstates() { cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu]; - cpu_prefetch_width = cpu_16bitbus ? 2 : 4; + if (is486) + cpu_prefetch_width = 16; + else + cpu_prefetch_width = cpu_16bitbus ? 2 : 4; if (cpu_cache_int_enabled) { @@ -1661,4 +1666,7 @@ void cpu_update_waitstates() cpu_cycles_write = cpu_s->mem_write_cycles; cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; } + if (is486) + cpu_prefetch_cycles *= 4; + cpu_mem_prefetch_cycles = cpu_prefetch_cycles; } diff --git a/src/cpu.h b/src/cpu.h index 2614994..62429e1 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -123,7 +123,7 @@ extern uint64_t cpu_CR4_mask; #define CPU_REQUIRES_DYNAREC 2 extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; -extern int cpu_prefetch_cycles, cpu_prefetch_width; +extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles; extern int cpu_waitstates; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; diff --git a/src/mem.c b/src/mem.c index 18bc37b..429df08 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1304,15 +1304,13 @@ uint8_t *getpccache(uint32_t a) } a&=rammask; - if (isram[a>>16]) - { - if ((a >> 16) != 0xF || shadowbios) - addreadlookup(a2, a); - return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)]; - } - if (_mem_exec[a >> 14]) { + if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM) + cpu_prefetch_cycles = cpu_rom_prefetch_cycles; + else + cpu_prefetch_cycles = cpu_mem_prefetch_cycles; + return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (uintptr_t)(a2 & ~0xFFF)]; } @@ -2200,24 +2198,24 @@ void mem_add_bios() { if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) { - mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); } - mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL, 0); - mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL, 0); + mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, 0, 0); - mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), 0, 0); - mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), 0, 0); + mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0); } int mem_a20_key = 0, mem_a20_alt = 0; diff --git a/src/mem.h b/src/mem.h index 7bcce0b..edde319 100644 --- a/src/mem.h +++ b/src/mem.h @@ -28,6 +28,8 @@ typedef struct mem_mapping_t #define MEM_MAPPING_EXTERNAL 1 /*Only present on internal bus (RAM)*/ #define MEM_MAPPING_INTERNAL 2 +/*Executing from ROM may involve additional wait states*/ +#define MEM_MAPPING_ROM 4 extern uint8_t *ram,*rom; extern uint8_t romext[32768]; diff --git a/src/rom.c b/src/rom.c index 49f0fc1..f326326 100644 --- a/src/rom.c +++ b/src/rom.c @@ -79,7 +79,7 @@ int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int fil mem_write_nullw, mem_write_nulll, rom->rom, - flags, + flags | MEM_MAPPING_ROM, rom); return 0; @@ -124,7 +124,7 @@ int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t addre mem_write_nullw, mem_write_nulll, rom->rom, - flags, + flags | MEM_MAPPING_ROM, rom); return 0; From c8e6fc7ce3c10c5cd172e43177dd2c5caf4e9a90 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 11:45:30 +0000 Subject: [PATCH 0377/1050] Added PS/2 Model 70 (type 3 & 4) emulation. --- src/ibm.h | 2 + src/mem.c | 30 +++++ src/model.c | 11 +- src/nvr.c | 8 +- src/ps2_mca.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++++- src/ps2_mca.h | 3 + src/ps2_nvr.c | 8 +- src/video.c | 12 ++ 8 files changed, 405 insertions(+), 7 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 6f1c001..dad81be 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -451,6 +451,8 @@ enum ROM_PB520R, ROM_COMPAQ_PIP, ROM_XI8088, + ROM_IBMPS2_M70_TYPE3, + ROM_IBMPS2_M70_TYPE4, ROM_MAX }; diff --git a/src/mem.c b/src/mem.c index 429df08..b4bbfd1 100644 --- a/src/mem.c +++ b/src/mem.c @@ -916,6 +916,36 @@ int loadbios() } fclose(f); return 1; + + case ROM_IBMPS2_M70_TYPE3: + f = romfopen("ibmps2_m70_type3/70-a_even.bin","rb"); + ff = romfopen("ibmps2_m70_type3/70-a_odd.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_IBMPS2_M70_TYPE4: + f = romfopen("ibmps2_m70_type4/70-b_even.bin","rb"); + ff = romfopen("ibmps2_m70_type4/70-b_odd.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"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 630387b..b8960f7 100644 --- a/src/model.c +++ b/src/model.c @@ -82,6 +82,7 @@ void ps1_m2121_init(); void ps2_m30_286_init(); void ps2_model_50_init(); void ps2_model_55sx_init(); +void ps2_model_70_init(); void ps2_model_80_init(); void at_neat_init(); void at_scat_init(); @@ -169,6 +170,7 @@ MODEL models[] = {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, @@ -176,7 +178,8 @@ MODEL models[] = {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, - + {"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, + {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, {"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL}, @@ -493,6 +496,12 @@ void ps2_model_55sx_init() ps2_mca_board_model_55sx_init(); } +void ps2_model_70_init() +{ + ps2_common_init(); + ps2_mca_board_model_70_type34_init(romset == ROM_IBMPS2_M70_TYPE4); +} + void ps2_model_80_init() { ps2_common_init(); diff --git a/src/nvr.c b/src/nvr.c index 4241c43..5e44fa6 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -305,7 +305,9 @@ void loadnvr() case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "rb"); nvrmask = 127; break; case ROM_PB520R: f = nvrfopen("pb520r.nvr", "rb"); nvrmask = 127; break; case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); nvrmask = 127; break; - + case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break; + case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break; + default: return; } if (!f) @@ -392,7 +394,9 @@ void savenvr() case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "wb"); break; case ROM_PB520R: f = nvrfopen("pb520r.nvr", "wb"); break; case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); break; - + case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break; + case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break; + default: return; } fwrite(nvrram,128,1,f); diff --git a/src/ps2_mca.c b/src/ps2_mca.c index c482ab5..5113642 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -35,6 +35,7 @@ static struct mem_mapping_t shadow_mapping; mem_mapping_t split_mapping; mem_mapping_t expansion_mapping; + mem_mapping_t cache_mapping; uint8_t (*planar_read)(uint16_t port); void (*planar_write)(uint16_t port, uint8_t val); @@ -44,8 +45,94 @@ static struct uint32_t split_addr; uint8_t mem_pos_regs[8]; + + int pending_cache_miss; } ps2; +/*The model 70 type 3/4 BIOS performs cache testing. Since PCem doesn't have any + proper cache emulation, it's faked a bit here. + + Port E2 is used for cache diagnostics. Bit 7 seems to be set on a cache miss, + toggling bit 2 seems to clear this. The BIOS performs at least the following + tests : + + - Disable RAM, access low 64kb (386) / 8kb (486), execute code from cache to + access low memory and verify that there are no cache misses. + - Write to low memory using DMA, read low memory and verify that all accesses + cause cache misses. + - Read low memory, verify that first access is cache miss. Read again and + verify that second access is cache hit. + + These tests are also performed on the 486 model 70, despite there being no + external cache on this system. Port E2 seems to control the internal cache on + these systems. Presumably this port is connected to KEN#/FLUSH# on the 486. + This behaviour is required to pass the timer interrupt test on the 486 version + - the BIOS uses a fixed length loop that will terminate too early on a 486/25 + if it executes from internal cache. + + To handle this, PCem uses some basic heuristics : + - If cache is enabled but RAM is disabled, accesses to low memory go directly + to cache memory. + - Reads to cache addresses not 'valid' will set the cache miss flag, and mark + that line as valid. + - Cache flushes will clear the valid array. + - DMA via the undocumented PS/2 command 0xb will clear the valid array. + - Disabling the cache will clear the valid array. + - Disabling the cache will also mark shadowed ROM areas as using ROM timings. + This works around the timing loop mentioned above. +*/ +static uint8_t ps2_cache[65536]; +static int ps2_cache_valid[65536/8]; + +static uint8_t ps2_read_cache_ram(uint32_t addr, void *priv) +{ +// pclog("ps2_read_cache_ram: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc); + if (!ps2_cache_valid[addr >> 3]) + { + ps2_cache_valid[addr >> 3] = 1; + ps2.mem_regs[2] |= 0x80; + } + else + ps2.pending_cache_miss = 0; + + return ps2_cache[addr]; +} +static uint16_t ps2_read_cache_ramw(uint32_t addr, void *priv) +{ +// pclog("ps2_read_cache_ramw: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc); + if (!ps2_cache_valid[addr >> 3]) + { + ps2_cache_valid[addr >> 3] = 1; + ps2.mem_regs[2] |= 0x80; + } + else + ps2.pending_cache_miss = 0; + + return *(uint16_t *)&ps2_cache[addr]; +} +static uint32_t ps2_read_cache_raml(uint32_t addr, void *priv) +{ +// pclog("ps2_read_cache_raml: addr=%08x %i %04x:%04x\n", addr, ps2_cache_valid[addr >> 3], CS,cpu_state.pc); + if (!ps2_cache_valid[addr >> 3]) + { + ps2_cache_valid[addr >> 3] = 1; + ps2.mem_regs[2] |= 0x80; + } + else + ps2.pending_cache_miss = 0; + + return *(uint32_t *)&ps2_cache[addr]; +} +static void ps2_write_cache_ram(uint32_t addr, uint8_t val, void *priv) +{ +// pclog("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc, ins); + ps2_cache[addr] = val; +} + +void ps2_cache_clean() +{ + memset(ps2_cache_valid, 0, sizeof(ps2_cache_valid)); +} static uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv) { @@ -164,6 +251,30 @@ static uint8_t model_55sx_read(uint16_t port) return 0xff; } +static uint8_t model_70_type3_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xf9; + 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_80_read(uint16_t port) { switch (port) @@ -321,6 +432,55 @@ static void model_55sx_write(uint16_t port, uint8_t val) } } +static void model_70_type3_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 0x105: + ps2.option[3] = val; + 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) @@ -469,14 +629,14 @@ uint8_t ps2_mca_read(uint16_t port, void *p) break; } - pclog("ps2_read: port=%04x temp=%02x\n", port, temp); +// pclog("ps2_read: port=%04x temp=%02x %04x:%04x %i\n", port, temp, CS, cpu_state.pc, ins); 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); +// pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); switch (port) { @@ -685,6 +845,70 @@ static void mem_encoding_write(uint16_t addr, uint8_t val, void *p) mem_encoding_update(); } +static uint8_t mem_encoding_read_cached(uint16_t addr, void *p) +{ + switch (addr) + { + case 0xe0: + return ps2.mem_regs[0]; + case 0xe1: + return ps2.mem_regs[1]; + case 0xe2: + return ps2.mem_regs[2]; + } + return 0xff; +} +static void mem_encoding_write_cached(uint16_t addr, uint8_t val, void *p) +{ + uint8_t old; + + switch (addr) + { + case 0xe0: + ps2.mem_regs[0] = val; + break; + case 0xe1: + ps2.mem_regs[1] = val; + break; + case 0xe2: + old = ps2.mem_regs[2]; + ps2.mem_regs[2] = (ps2.mem_regs[2] & 0x80) | (val & ~0x88); + if (val & 2) + { +// pclog("Clear latch - %i\n", ps2.pending_cache_miss); + if (ps2.pending_cache_miss) + ps2.mem_regs[2] |= 0x80; + else + ps2.mem_regs[2] &= ~0x80; + ps2.pending_cache_miss = 0; + } + + if ((val & 0x21) == 0x20 && (old & 0x21) != 0x20) + ps2.pending_cache_miss = 1; + if ((val & 0x21) == 0x01 && (old & 0x21) != 0x01) + ps2_cache_clean(); + if (val & 0x01) + ram_mid_mapping.flags |= MEM_MAPPING_ROM; + else + ram_mid_mapping.flags &= ~MEM_MAPPING_ROM; + break; + } +// pclog("mem_encoding_write: addr=%02x val=%02x %04x:%04x %02x %02x\n", addr, val, CS,cpu_state.pc, ps2.mem_regs[1],ps2.mem_regs[2]); + mem_encoding_update(); + if ((ps2.mem_regs[1] & 0x10) && (ps2.mem_regs[2] & 0x21) == 0x20) + { + mem_mapping_disable(&ram_low_mapping); + mem_mapping_enable(&ps2.cache_mapping); + flushmmucache(); + } + else + { + mem_mapping_disable(&ps2.cache_mapping); + mem_mapping_enable(&ram_low_mapping); + flushmmucache(); + } +} + static uint8_t ps2_mem_expansion_read(int port, void *p) { return ps2.mem_pos_regs[port & 7]; @@ -703,6 +927,116 @@ static void ps2_mem_expansion_write(int port, uint8_t val, void *p) mem_mapping_disable(&ps2.expansion_mapping); } +void ps2_mca_board_model_70_type34_init(int is_type4) +{ + ps2_mca_board_common_init(); + + mem_remap_top_256k(); + ps2.split_addr = mem_size * 1024; + mca_init(4); + + ps2.planar_read = model_70_type3_read; + ps2.planar_write = model_70_type3_write; + + device_add(&ps2_nvr_device); + + io_sethandler(0x00e0, 0x0003, mem_encoding_read_cached, NULL, NULL, mem_encoding_write_cached, NULL, NULL, NULL); + + ps2.mem_regs[1] = 2; + + switch (mem_size/1024) + { + case 2: + ps2.option[1] = 0xa6; + ps2.option[2] = 0x01; + break; + case 4: + ps2.option[1] = 0xaa; + ps2.option[2] = 0x01; + break; + case 6: + ps2.option[1] = 0xca; + ps2.option[2] = 0x01; + break; + case 8: + default: + ps2.option[1] = 0xca; + ps2.option[2] = 0x02; + break; + } + + if (is_type4) + ps2.option[2] |= 0x04; /*486 CPU*/ + + 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); + + mem_mapping_add(&ps2.cache_mapping, + 0, + is_type4 ? (8 * 1024) : (64 * 1024), + ps2_read_cache_ram, + ps2_read_cache_ramw, + ps2_read_cache_raml, + ps2_write_cache_ram, + NULL, + NULL, + ps2_cache, + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.cache_mapping); + + if (mem_size > 8192) + { + /* Only 8 MB supported on planar, create a memory expansion card for the rest */ + mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x700000); + + ps2.mem_pos_regs[0] = 0xff; + ps2.mem_pos_regs[1] = 0xfc; + + switch (mem_size/1024) + { + case 10: + ps2.mem_pos_regs[4] = 0xfe; + break; + case 12: + ps2.mem_pos_regs[4] = 0xfa; + break; + case 14: + ps2.mem_pos_regs[4] = 0xea; + break; + case 16: + ps2.mem_pos_regs[4] = 0xaa; + break; + } + + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); + mem_mapping_add(&ps2.expansion_mapping, + 0x800000, + (mem_size - 8192)*1024, + mem_read_ram, + mem_read_ramw, + mem_read_raml, + mem_write_ram, + mem_write_ramw, + mem_write_raml, + &ram[0x800000], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.expansion_mapping); + } +} + void ps2_mca_board_model_80_type2_init() { ps2_mca_board_common_init(); diff --git a/src/ps2_mca.h b/src/ps2_mca.h index d7a2e13..9e20914 100644 --- a/src/ps2_mca.h +++ b/src/ps2_mca.h @@ -1,3 +1,6 @@ void ps2_mca_board_model_50_init(); void ps2_mca_board_model_55sx_init(); +void ps2_mca_board_model_70_type34_init(int is_type4); void ps2_mca_board_model_80_type2_init(); + +void ps2_cache_clean(); diff --git a/src/ps2_nvr.c b/src/ps2_nvr.c index ed1896b..50829fb 100644 --- a/src/ps2_nvr.c +++ b/src/ps2_nvr.c @@ -58,7 +58,9 @@ static void *ps2_nvr_init() switch (romset) { - case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80_sec.nvr", "rb"); break; + case ROM_IBMPS2_M70_TYPE3:f = nvrfopen("ibmps2_m70_type3_sec.nvr", "rb"); break; + case ROM_IBMPS2_M70_TYPE4:f = nvrfopen("ibmps2_m70_type4_sec.nvr", "rb"); break; + case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80_sec.nvr", "rb"); break; } if (f) { @@ -78,7 +80,9 @@ static void ps2_nvr_close(void *p) switch (romset) { - case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80_sec.nvr", "wb"); break; + case ROM_IBMPS2_M70_TYPE3:f = nvrfopen("ibmps2_m70_type3_sec.nvr", "wb"); break; + case ROM_IBMPS2_M70_TYPE4:f = nvrfopen("ibmps2_m70_type4_sec.nvr", "wb"); break; + case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80_sec.nvr", "wb"); break; } if (f) { diff --git a/src/video.c b/src/video.c index 0c923b4..3a97dba 100644 --- a/src/video.c +++ b/src/video.c @@ -195,6 +195,8 @@ device_t *video_card_getdevice(int card) case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: return &ps1vga_device; @@ -316,6 +318,8 @@ int video_is_mda() case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: case ROM_T3100E: @@ -355,6 +359,8 @@ int video_is_cga() case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: case ROM_ELX_PC425X: @@ -388,6 +394,8 @@ int video_is_ega_vga() case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: case ROM_ELX_PC425X: @@ -518,6 +526,8 @@ void video_updatetiming() case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: timing = &timing_vga; break; @@ -683,6 +693,8 @@ void video_init() case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: device_add(&ps1vga_device); return; From 2f5f4a5b47cbcb0c1daeaa4b1632b72bd6a9afd5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 14:29:56 +0000 Subject: [PATCH 0378/1050] Fixed double IO mapping of Mono VGA registers. --- src/vid_svga.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index 5835aa6..91c5b3d 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -78,16 +78,9 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 0x3C2: svga->miscout = val; svga->vidclock = val & 4;// printf("3C2 write %02X\n",val); - 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_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + if (!(val & 1)) io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - } svga_recalctimings(svga); break; case 0x3C4: From 2567c30353137c2ab2ffd2a4a956a5450724bf95 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 15:46:24 +0000 Subject: [PATCH 0379/1050] Added ATI Korean VGA emulation. Patch from Greatpsycho. --- src/ibm.h | 1 + src/vid_ati28800.c | 231 +++++++++++++++++++++++++++++++++++++++++- src/vid_ati28800.h | 1 + src/vid_svga.c | 8 +- src/vid_svga_render.c | 158 ++++++++++++++++++++++------- src/vid_svga_render.h | 1 + src/video.c | 11 ++ src/video.h | 1 + 8 files changed, 371 insertions(+), 41 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index dad81be..c5668d9 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -478,6 +478,7 @@ enum GFX_TGUI9440, /*Trident TGUI9440*/ GFX_VGA, /*IBM VGA*/ GFX_VGAEDGE16, /*ATI VGA Edge-16 (18800-1)*/ + GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/ GFX_VGACHARGER, /*ATI VGA Charger (28800-5)*/ GFX_OTI067, /*Oak OTI-067*/ GFX_MACH64GX, /*ATI Graphics Pro Turbo (Mach64)*/ diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 393f41e..55f9c45 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -1,4 +1,4 @@ -/*ATI 28800 emulation (VGA Charger)*/ +/*ATI 28800 emulation (VGA Charger & Korean VGA)*/ #include #include "ibm.h" #include "device.h" @@ -20,6 +20,14 @@ typedef struct ati28800_t uint8_t regs[256]; int index; + + uint8_t port_03dd_val; + uint16_t get_korean_font_kind; + int in_get_korean_font_kind_set; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; + int ksc5601_mode_enabled; } ati28800_t; void ati28800_out(uint16_t addr, uint8_t val, void *p) @@ -39,6 +47,7 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) ati28800->index = val; break; case 0x1cf: + old = ati28800->regs[ati28800->index]; ati28800->regs[ati28800->index] = val; switch (ati28800->index) { @@ -51,10 +60,24 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) } else /*Single bank mode*/ svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; + if (ati28800->index == 0xbe && ((old ^ val) & 0x10)) + svga_recalctimings(svga); break; case 0xb3: ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); break; + case 0xb6: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xb8: + if ((old ^ val) & 0x40) + svga_recalctimings(svga); + break; + case 0xb9: + if ((old ^ val) & 2) + svga_recalctimings(svga); + break; } break; @@ -81,6 +104,63 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); } +void ati28800k_out(uint16_t addr, uint8_t val, void *p) +{ + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; + + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) + addr ^= 0x60; + + switch (addr) + { + case 0x1CF: + if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) + { + ati28800->ksc5601_mode_enabled = val & 0x20; +// pclog("Switching mode to %s at %04X:%04X\n", ksc5601_mode_enabled ? "DBCS" : "SBCS", CS, cpu_state.oldpc); + svga_recalctimings(svga); + } + ati28800_out(oldaddr, val, p); + break; + case 0x3DD: +// pclog("ati28800k_out : set port 03DD to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + ati28800->port_03dd_val = val; + if (val == 1) + ati28800->get_korean_font_enabled = 0; + if (ati28800->in_get_korean_font_kind_set) + { + ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); + ati28800->get_korean_font_enabled = 1; + ati28800->get_korean_font_index = 0; + ati28800->in_get_korean_font_kind_set = 0; + } + break; + case 0x3DE: +// pclog("ati28800k_out : set port 03DE to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + ati28800->in_get_korean_font_kind_set = 0; + switch (ati28800->port_03dd_val) + { + case 0x10: + ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); + break; + case 8: + ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; + if (val & 2) + ati28800->in_get_korean_font_kind_set = 1; + break; + } + break; + default: + ati28800_out(oldaddr, val, p); + break; + } +} + uint8_t ati28800_in(uint16_t addr, void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -127,7 +207,45 @@ uint8_t ati28800_in(uint16_t addr, void *p) temp = svga_in(addr, svga); break; } - if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); +// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); + return temp; +} + +uint8_t ati28800k_in(uint16_t addr, void *p) +{ + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; + uint8_t temp = 0xFF; + +// if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); + + if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; + + switch (addr) + { + case 0x3DE: + if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) + { + switch (ati28800->get_korean_font_kind >> 8) + { + case 4: /* ROM font */ + temp = fontdatksc5601[ati28800->get_korean_font_base][ati28800->get_korean_font_index++]; + break; + case 2: /* User defined font - TODO : Should be implemented later */ + temp = 0; + break; + default: + break; + } + ati28800->get_korean_font_index &= 0x1F; + } + break; + default: + temp = ati28800_in(oldaddr, p); + break; + } +// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); return temp; } @@ -135,6 +253,43 @@ void ati28800_recalctimings(svga_t *svga) { ati28800_t *ati28800 = (ati28800_t *)svga->p; pclog("ati28800_recalctimings\n"); + + switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) + { + case 0x00: svga->clock = cpuclock / 42954000.0; break; + case 0x01: svga->clock = cpuclock / 48771000.0; break; + case 0x03: svga->clock = cpuclock / 36000000.0; break; + case 0x04: svga->clock = cpuclock / 50350000.0; break; + case 0x05: svga->clock = cpuclock / 56640000.0; break; + case 0x07: svga->clock = cpuclock / 44900000.0; break; + case 0x08: svga->clock = cpuclock / 30240000.0; break; + case 0x09: svga->clock = cpuclock / 32000000.0; break; + case 0x0A: svga->clock = cpuclock / 37500000.0; break; + case 0x0B: svga->clock = cpuclock / 39000000.0; break; + case 0x0C: svga->clock = cpuclock / 40000000.0; break; + case 0x0D: svga->clock = cpuclock / 56644000.0; break; + case 0x0E: svga->clock = cpuclock / 75000000.0; break; + case 0x0F: svga->clock = cpuclock / 65000000.0; break; + default: break; + } + if (ati28800->regs[0xb8] & 0x40) + svga->clock *= 2; + if (ati28800->regs[0xb6] & 0x10) + { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->rowoffset <<= 1; + } + + if (svga->crtc[0x17] & 4) + { + svga->vtotal <<= 1; + svga->dispend <<= 1; + svga->vsyncstart <<= 1; + svga->split <<= 1; + svga->vblankstart <<= 1; + } + if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ { pclog("8bpp_highres\n"); @@ -144,6 +299,18 @@ void ati28800_recalctimings(svga_t *svga) } } +void ati28800k_recalctimings(svga_t *svga) +{ + ati28800_t *ati28800 = (ati28800_t *)svga->p; + + ati28800_recalctimings(svga); + + if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) + { + svga->render = svga_render_text_80_ksc5601; + } +} + void *ati28800_init() { ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); @@ -167,11 +334,48 @@ void *ati28800_init() return ati28800; } +void *ati28800k_init() +{ + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); + + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; + + rom_init(&ati28800->bios_rom, "atikorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("ati_ksc5601.rom", 6); + + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800k_recalctimings, + ati28800k_in, ati28800k_out, + NULL, + NULL); + + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + + ati28800->svga.miscout = 1; + + ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0); + + return ati28800; +} + static int ati28800_available() { return rom_present("bios.bin"); } +static int ati28800k_available() +{ + return rom_present("atikorvga.bin") && rom_present("ati_ksc5601.rom"); +} + void ati28800_close(void *p) { ati28800_t *ati28800 = (ati28800_t *)p; @@ -202,6 +406,17 @@ void ati28800_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &ati28800->svga); } +void ati28800k_add_status_info(char *s, int max_len, void *p) +{ + ati28800_t *ati28800 = (ati28800_t *)p; + char temps[128]; + + svga_add_status_info(s, max_len, &ati28800->svga); + + sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); + strncat(s, temps, max_len); +} + device_t ati28800_device = { "ATI-28800", @@ -213,3 +428,15 @@ device_t ati28800_device = ati28800_force_redraw, ati28800_add_status_info }; + +device_t ati28800k_device = +{ + "ATI Korean VGA", + 0, + ati28800k_init, + ati28800_close, + ati28800k_available, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800k_add_status_info +}; diff --git a/src/vid_ati28800.h b/src/vid_ati28800.h index 6cb3617..51f3615 100644 --- a/src/vid_ati28800.h +++ b/src/vid_ati28800.h @@ -1 +1,2 @@ extern device_t ati28800_device; +extern device_t ati28800k_device; diff --git a/src/vid_svga.c b/src/vid_svga.c index 91c5b3d..1de0a20 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -372,7 +372,7 @@ void svga_recalctimings(svga_t *svga) svga->render = svga_render_blank; if (!svga->scrblank && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1)) /*Text mode*/ + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ { if (svga->seqregs[1] & 8) /*40 column*/ { @@ -680,7 +680,7 @@ 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*/ + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ { svga->video_res_x /= (svga->seqregs[1] & 1) ? 8 : 9; svga->video_res_y /= (svga->crtc[9] & 31) + 1; @@ -690,7 +690,9 @@ void svga_poll(void *p) { if (svga->crtc[9] & 0x80) svga->video_res_y /= 2; - if (!(svga->crtc[0x17] & 1)) + if (!(svga->crtc[0x17] & 2)) + svga->video_res_y *= 4; + else if (!(svga->crtc[0x17] & 1)) svga->video_res_y *= 2; svga->video_res_y /= (svga->crtc[9] & 31) + 1; if (svga->lowres) diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 4e7af2b..808540e 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -158,14 +158,125 @@ void svga_render_text_80(svga_t *svga) } } +void svga_render_text_80_ksc5601(svga_t *svga) +{ + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (svga->fullchange) + { + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[32]; + int x, xx; + int drawcursor; + uint8_t chr, attr, dat, nextchr; + uint32_t charaddr; + int fg, bg; + int xinc = (svga->seqregs[1] & 1) ? 8 : 9; + + for (x = 0; x < svga->hdisp; x += xinc) + { + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + + if (drawcursor) + { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } + else + { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) + { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } + + if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) + { + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; + } + else + { + if (attr & 8) charaddr = svga->charsetb + (chr * 128); + else charaddr = svga->charseta + (chr * 128); + + dat = svga->vram[charaddr + (svga->sc << 2)]; + } + if (svga->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; + + if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) + { + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + + if (drawcursor) + { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } + else + { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) + { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } + + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; + if (svga->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } + + svga->ma += 4; + p += xinc; + x += xinc; + } + } + svga->ma &= svga->vram_display_mask; + } +} + void svga_render_2bpp_lowres(svga_t *svga) { int changed_offset; - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - changed_offset = (svga->ma << 1) >> 12; - else - changed_offset = ((svga->ma << 1) + 0x8000) >> 12; + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { @@ -181,16 +292,8 @@ void svga_render_2bpp_lowres(svga_t *svga) { uint8_t dat[2]; - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - { - dat[0] = svga->vram[(svga->ma << 1) + 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + 0x8001]; - } - else - { - dat[0] = svga->vram[(svga->ma << 1)]; - dat[1] = svga->vram[(svga->ma << 1) + 1]; - } + dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; + dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -212,10 +315,7 @@ void svga_render_2bpp_highres(svga_t *svga) { int changed_offset; - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - changed_offset = ((svga->ma << 1) | 0x8000) >> 12; - else - changed_offset = (svga->ma << 1) >> 12; + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { @@ -231,16 +331,8 @@ void svga_render_2bpp_highres(svga_t *svga) { uint8_t dat[2]; - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - { - dat[0] = svga->vram[(svga->ma << 1) + 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + 0x8001]; - } - else - { - dat[0] = svga->vram[(svga->ma << 1)]; - dat[1] = svga->vram[(svga->ma << 1) + 1]; - } + dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; + dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -301,10 +393,7 @@ void svga_render_4bpp_highres(svga_t *svga) { int changed_offset; - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - changed_offset = (svga->ma | 0x8000) >> 12; - else - changed_offset = svga->ma >> 12; + changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { @@ -321,10 +410,7 @@ void svga_render_4bpp_highres(svga_t *svga) uint8_t edat[4]; uint8_t dat; - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | 0x8000]); - else - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]); svga->ma += 4; svga->ma &= svga->vram_display_mask; diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index a0115ad..fb88e8d 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -12,6 +12,7 @@ extern uint8_t edatlookup[4][4]; void svga_render_blank(svga_t *svga); void svga_render_text_40(svga_t *svga); void svga_render_text_80(svga_t *svga); +void svga_render_text_80_ksc5601(svga_t *svga); void svga_render_2bpp_lowres(svga_t *svga); void svga_render_2bpp_highres(svga_t *svga); diff --git a/src/video.c b/src/video.c index 3a97dba..a08c92e 100644 --- a/src/video.c +++ b/src/video.c @@ -79,6 +79,7 @@ static VIDEO_CARD video_cards[] = { {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"ATI Korean VGA (ATI-28800)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, @@ -744,6 +745,7 @@ uint8_t fontdat[2048][8]; uint8_t fontdatm[2048][16]; uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */ int xsize=1,ysize=1; @@ -866,6 +868,15 @@ void loadfont(char *s, int format) } } break; + case 6: /* Korean KSC-5601 */ + for (c=0;c<16384;c++) + { + for (d=0;d<32;d++) + { + fontdatksc5601[c][d]=getc(f); + } + } + break; } fclose(f); diff --git a/src/video.h b/src/video.h index 5b605c7..71090e0 100644 --- a/src/video.h +++ b/src/video.h @@ -53,6 +53,7 @@ extern int changeframecount; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; +extern uint8_t fontdatksc5601[16384][32]; extern uint32_t *video_15to32, *video_16to32; From 4f0fe705c53fce92c3e0e8cc3066ab216741f8fc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 15:51:12 +0000 Subject: [PATCH 0380/1050] Add missing tooltip for 'Configure Host' button. Patch from ecksemmess. --- src/pc.xrc | 1 + src/wx-resources.cpp | 630 ++++++++++++++++++++++--------------------- 2 files changed, 317 insertions(+), 314 deletions(-) diff --git a/src/pc.xrc b/src/pc.xrc index cd9b6d6..bc38ddc 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -3175,6 +3175,7 @@ 5 + Configure Host icons/32x32/widescreen.png 0 diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index f685b0b..76e94d7 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 136019; +static size_t xml_res_size_26 = 136071; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -7160,25 +7160,49 @@ static unsigned char xml_res_file_26[] = { 95,72,79,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, 60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -119,105,100,101,115,99,114,101,101,110,46,112,110,103,60,47,98,105,116, -109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,111,110,102,105,103, +117,114,101,32,72,111,115,116,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,51,50,120,51,50,95,119,105,100,101,115,99,114,101,101, +110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, +78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109, +112,117,116,101,114,95,97,100,100,46,112,110,103,60,47,98,105,116,109,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, @@ -7188,222 +7212,156 @@ static unsigned char xml_res_file_26[] = { 114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85, -95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, -62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100,100,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,82,69,78, -65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97,109,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -99,111,109,112,117,116,101,114,95,101,100,105,116,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80,89,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, -111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108,116,105,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112, -36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101, -114,95,103,111,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, -116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32,32,32,32,32,32,32,32,32, +110,97,109,101,61,34,73,68,67,95,82,69,78,65,77,69,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,82,101,110,97,109,101,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, +105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114, +95,101,100,105,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,73,68,67,95,67,79,80,89,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, 84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,68,101, -108,101,116,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,100,101,108, -101,116,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79, -68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117,105,116,60,47,116, -111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,111,111,114, -95,105,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47, -100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97,100,101,114, -77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, -108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, -76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, -101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,32,83,104, -97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62, -10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, -116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, -79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, -101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73, -78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, -101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,68, -68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, -70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,46,46, -46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,111, +112,121,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, +50,120,51,50,95,99,111,109,112,117,116,101,114,95,103,111,46,112,110,103, +60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,85,80,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,111,118,101,32,117,112,60,47,108,97,98,101,108,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118, -101,32,100,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109, +112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103,60,47,98, +105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108,103,34, +62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84, +95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78, +95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, +108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110,97,103,101, +114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, +101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, 68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -7415,91 +7373,135 @@ static unsigned char xml_res_file_26[] = { 60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,112,112, -108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101,32,117,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, -100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, -111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, -108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82,101, -109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108, -101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, -69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101, -62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105, -116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, -47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, -101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, -62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85, -69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61, -34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, 115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,112,112,108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105, +97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82, +101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, +49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, +109,97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81, +85,69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116, +61,34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, From b530bdafeaae8487508acb01d71f37e268342f58 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 16:43:32 +0000 Subject: [PATCH 0381/1050] Cleaned up turbo handling. --- src/cpu.c | 37 +++++++++++++++++++++++++++++++++++++ src/cpu.h | 2 ++ src/ibm.h | 1 - src/pc.c | 13 +++++++------ src/pit.c | 2 +- src/t1000.c | 11 ++--------- src/t3100e.c | 11 ++--------- src/wx-sdl2-status.c | 2 +- src/xi8088.c | 7 ++----- 9 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index dfe6c65..64a9702 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -7,6 +7,9 @@ #include "pci.h" #include "codegen.h" +static int cpu_turbo_speed, cpu_nonturbo_speed; +static int cpu_turbo = 1; + int isa_cycles; int has_vlb; static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6; @@ -505,6 +508,14 @@ void cpu_set() ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); + cpu_turbo_speed = cpu_s->rspeed; + if (cpu_s->cpu_type < CPU_286) + cpu_nonturbo_speed = 4772728; + else if (cpu_s->rspeed < 8000000) + cpu_nonturbo_speed = cpu_s->rspeed; + else + cpu_nonturbo_speed = 8000000; + cpu_update_waitstates(); isa_cycles = cpu_s->atclk_div; @@ -1670,3 +1681,29 @@ void cpu_update_waitstates() cpu_prefetch_cycles *= 4; cpu_mem_prefetch_cycles = cpu_prefetch_cycles; } + +void cpu_set_turbo(int turbo) +{ + if (cpu_turbo != turbo) + { + cpu_turbo = turbo; + + cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu]; + if (cpu_s->cpu_type >= CPU_286) + { + if (cpu_turbo) + setpitclock(cpu_turbo_speed); + else + setpitclock(cpu_nonturbo_speed); + } + else + setpitclock(14318184.0); + } +} + +int cpu_get_speed() +{ + if (cpu_turbo) + return cpu_turbo_speed; + return cpu_nonturbo_speed; +} diff --git a/src/cpu.h b/src/cpu.h index 62429e1..ef21835 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -148,6 +148,8 @@ extern int isa_cycles; void cpu_update_waitstates(); void cpu_set(); void cpu_set_edx(); +void cpu_set_turbo(int turbo); +int cpu_get_speed(); extern int has_vlb; diff --git a/src/ibm.h b/src/ibm.h index c5668d9..491116f 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -273,7 +273,6 @@ extern uint8_t opcode; extern int insc; extern int fpucount; extern float mips,flops; -extern int clockrate; extern int cgate16; extern int CPUID; diff --git a/src/pc.c b/src/pc.c index a12a56f..71fd9f4 100644 --- a/src/pc.c +++ b/src/pc.c @@ -70,7 +70,6 @@ int cycles_lost = 0; int config_override = 0; -int clockrate; int insc=0; float mips,flops; extern int mmuflush; @@ -361,6 +360,7 @@ void resetpc() { cpu_set(); pc_reset(); + cpu_set_turbo(1); // cpuspeed2=(AT)?2:1; // atfullspeed=0; ///* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); @@ -467,6 +467,7 @@ void resetpchard() } sound_update_buf_length(); + cpu_set_turbo(1); } 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"}; @@ -490,21 +491,21 @@ void runpc() { char s[200]; int done=0; + int cycles_to_run = cpu_get_speed() / 100; startblit(); - clockrate = models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed; if (is386) { if (cpu_use_dynarec) - exec386_dynarec(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); + exec386_dynarec(cycles_to_run); else - exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); + exec386(cycles_to_run); } else if (AT) - exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); + exec386(cycles_to_run); else - execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); + execx86(cycles_to_run); keyboard_poll_host(); keyboard_process(); diff --git a/src/pit.c b/src/pit.c index 90dab32..eb0f828 100644 --- a/src/pit.c +++ b/src/pit.c @@ -41,7 +41,7 @@ void setpitclock(float clock) // 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); + xt_cpu_multi = (int)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)cpu_get_speed()); // pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock); /* if (video_recalctimings) video_recalctimings();*/ diff --git a/src/t1000.c b/src/t1000.c index fb5399a..42937eb 100644 --- a/src/t1000.c +++ b/src/t1000.c @@ -391,16 +391,9 @@ static void t1200_turbo_set(uint8_t value) } t1000.turbo = value; if (!value) - { - int c = cpu; - cpu = 0; /* 8088/4.77MHz */ - cpu_set(); - cpu = c; - } + cpu_set_turbo(0); else - { - cpu_set(); - } + cpu_set_turbo(1); } static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) diff --git a/src/t3100e.c b/src/t3100e.c index e9730d7..5456c23 100644 --- a/src/t3100e.c +++ b/src/t3100e.c @@ -376,16 +376,9 @@ void t3100e_turbo_set(uint8_t value) { t3100e_ems.turbo = value; if (!value) - { - int c = cpu; - cpu = 0; /* 286/6 */ - cpu_set(); - cpu = c; - } + cpu_set_turbo(0); else - { - cpu_set(); - } + cpu_set_turbo(1); } diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 8d16081..735fa44 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -145,7 +145,7 @@ int get_status(char* machine, char* device) #endif*/ segareads, segawrites, - clockrate - scycles_lost, + cpu_get_speed() - scycles_lost, pit_timer0_freq(), ((double)main_time * 100.0) / status_diff, ((double)main_time * 100.0) / timer_freq, diff --git a/src/xi8088.c b/src/xi8088.c index d4b7930..6ea95e6 100644 --- a/src/xi8088.c +++ b/src/xi8088.c @@ -29,15 +29,12 @@ void xi8088_turbo_set(uint8_t value) if (!value) { pclog("Xi8088 turbo off\n"); - int c = cpu; - cpu = 0; /* 8088/4.77 */ - cpu_set(); - cpu = c; + cpu_set_turbo(0); } else { pclog("Xi8088 turbo on\n"); - cpu_set(); + cpu_set_turbo(1); } } From 3c656caa4824dc94202f06acc021d38541dea4bb Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 11 Mar 2018 17:59:05 +0000 Subject: [PATCH 0382/1050] Added software turbo control to Generic XT clone, DTK XT clone, AMI XT clone and Phoenix XT clone. --- src/keyboard_xt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index a622211..aaabda0 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -32,6 +32,7 @@ struct uint8_t pb; int tandy; + int pb2_turbo; } keyboard_xt; static uint8_t key_queue[16]; @@ -115,6 +116,9 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) timer_process(); timer_update_outstanding(); + + if (keyboard_xt.pb2_turbo) + cpu_set_turbo((val & 4) ? 0 : 1); speaker_update(); speaker_gated = val & 1; @@ -230,6 +234,7 @@ void keyboard_xt_init() keyboard_send = keyboard_xt_adddata; keyboard_poll = keyboard_xt_poll; keyboard_xt.tandy = 0; + keyboard_xt.pb2_turbo = (romset == ROM_GENXT || romset == ROM_DTKXT || romset == ROM_AMIXT || romset == ROM_PXXT) ? 1 : 0; timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); } From 7e23388ed0af3a9e142e3c125351a478908c9bc1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Mar 2018 20:31:01 +0000 Subject: [PATCH 0383/1050] Results from keyboard controller commands take priority over pending key presses/releases. Fixes keyboard hang on KMX-C-02. --- src/keyboard_at.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index c2e8de8..9b9104c 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -35,7 +35,7 @@ struct uint8_t status; uint8_t mem[0x20]; uint8_t out; - int out_new; + int out_new, out_delayed; uint8_t input_port; uint8_t output_port; @@ -86,7 +86,7 @@ void keyboard_at_poll() { if (keyboard_at.mem[0] & 0x01) picint(2); - keyboard_at.out = keyboard_at.out_new; + keyboard_at.out = keyboard_at.out_new & 0xff; keyboard_at.out_new = -1; keyboard_at.status |= STAT_OFULL; keyboard_at.status &= ~STAT_IFULL; @@ -99,9 +99,21 @@ void keyboard_at_poll() 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]; + keyboard_at.out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; } + else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && + keyboard_at.out_delayed != -1) + { + keyboard_at.out_new = keyboard_at.out_delayed; + keyboard_at.out_delayed = -1; + } + else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && + !(keyboard_at.mem[0] & 0x10) && keyboard_at.out_delayed != -1) + { + keyboard_at.out_new = keyboard_at.out_delayed; + keyboard_at.out_delayed = -1; + } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && /*!(keyboard_at.mem[0] & 0x20) &&*/ mouse_queue_start != mouse_queue_end) { @@ -118,19 +130,14 @@ void keyboard_at_poll() 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; + key_ctrl_queue[key_ctrl_queue_end] = val; + key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; + + if (!(keyboard_at.out_new & 0x300)) + { + keyboard_at.out_delayed = keyboard_at.out_new; + keyboard_at.out_new = -1; } - 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);*/ } void keyboard_at_adddata_keyboard(uint8_t val) From 576243126036618b987924b2c4b4e57b0826d922 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Mar 2018 20:52:07 +0000 Subject: [PATCH 0384/1050] Don't add ROM waitstates on slow CPUs (<= 8 MHz). Fixes IBM AT. --- src/cpu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpu.c b/src/cpu.c index 64a9702..1e62d9b 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -520,7 +520,10 @@ void cpu_set() isa_cycles = cpu_s->atclk_div; - cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; + if (cpu_s->rspeed <= 8000000) + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; + else + cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000; if (cpu_s->pci_speed) { @@ -1680,6 +1683,8 @@ void cpu_update_waitstates() if (is486) cpu_prefetch_cycles *= 4; cpu_mem_prefetch_cycles = cpu_prefetch_cycles; + if (cpu_s->rspeed <= 8000000) + cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; } void cpu_set_turbo(int turbo) From 74b8047f2f0e9ecd7ae842eb3f0e8371a066263e Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Mar 2018 20:46:08 +0000 Subject: [PATCH 0385/1050] Fixed crackling audio on AudioPCI. --- src/sound_audiopci.c | 64 +++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index fb6ef0c..6cedb23 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -984,12 +984,46 @@ static void es1371_next_sample(es1371_t *es1371, int dac_nr) } //static FILE *es1371_f;//,*es1371_f2; + +static void es1371_update(es1371_t *es1371) +{ + int32_t l, r; + + l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12; + l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12); + r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12; + r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12); + + l >>= 1; + r >>= 1; + + l = (l * es1371->master_vol_l) >> 15; + r = (r * es1371->master_vol_r) >> 15; + + if (l < -32768) + l = -32768; + else if (l > 32767) + l = 32767; + if (r < -32768) + r = -32768; + else if (r > 32767) + r = 32767; + + for (; es1371->pos < sound_pos_global; es1371->pos++) + { + es1371->buffer[es1371->pos*2] = l; + es1371->buffer[es1371->pos*2 + 1] = r; + } +} + static void es1371_poll(void *p) { es1371_t *es1371 = (es1371_t *)p; es1371->dac[1].time += es1371->dac[1].latch; + es1371_update(es1371); + if (es1371->int_ctrl & INT_DAC1_EN) { // pclog("1Samp %i %i %08x\n", es1371->dac[0].curr_samp_ct, es1371->dac[0].samp_ct, es1371->dac[0].ac); @@ -1032,34 +1066,6 @@ static void es1371_poll(void *p) } } } - - for (; es1371->pos < sound_pos_global; es1371->pos++) - { - int32_t l, r; - - l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12; - l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12); - r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12; - r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12); - - l >>= 1; - r >>= 1; - - l = (l * es1371->master_vol_l) >> 15; - r = (r * es1371->master_vol_r) >> 15; - - if (l < -32768) - l = -32768; - else if (l > 32767) - l = 32767; - if (r < -32768) - r = -32768; - else if (r > 32767) - r = 32767; - - es1371->buffer[es1371->pos*2] = l; - es1371->buffer[es1371->pos*2 + 1] = r; - } } static void es1371_get_buffer(int32_t *buffer, int len, void *p) @@ -1067,6 +1073,8 @@ static void es1371_get_buffer(int32_t *buffer, int len, void *p) es1371_t *es1371 = (es1371_t *)p; int c; + es1371_update(es1371); + for (c = 0; c < len * 2; c++) buffer[c] += (es1371->buffer[c] / 2); From 2e395d2ce8235d43c46a5d48067dfbdb37204f3e Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Mar 2018 21:51:40 +0000 Subject: [PATCH 0386/1050] Implement proper resampling on AudioPCI. --- src/sound_audiopci.c | 137 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 126 insertions(+), 11 deletions(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index 6cedb23..bd47be9 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -1,5 +1,6 @@ #include #include +#include #include "ibm.h" #include "device.h" #include "io.h" @@ -7,6 +8,12 @@ #include "pci.h" #include "sound.h" +#define N 16 + +#define ES1371_NCoef 91 + +static float low_fir_es1371_coef[ES1371_NCoef]; + typedef struct es1371_t { uint8_t pci_command, pci_serr; @@ -49,6 +56,9 @@ typedef struct es1371_t int16_t buffer_l[64], buffer_r[64]; int buffer_pos, buffer_pos_end; + int filtered_l[32], filtered_r[32]; + int f_pos; + int16_t out_l, out_r; int32_t vol_l, vol_r; @@ -462,6 +472,7 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) case 0x71: es1371->dac[0].vf = (es1371->dac[0].vf & ~0x1f8000) | ((val & 0xfc00) << 5); es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + es1371->dac[0].f_pos = 0; break; case 0x72: es1371->dac[0].ac = (es1371->dac[0].ac & ~0x7fff) | (val & 0x7fff); @@ -473,6 +484,7 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) case 0x75: es1371->dac[1].vf = (es1371->dac[1].vf & ~0x1f8000) | ((val & 0xfc00) << 5); es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7f8000) | ((val & 0x00ff) << 15); + es1371->dac[1].f_pos = 0; break; case 0x76: es1371->dac[1].ac = (es1371->dac[1].ac & ~0x7fff) | (val & 0x7fff); @@ -968,15 +980,60 @@ static void es1371_fetch(es1371_t *es1371, int dac_nr) } } -static void es1371_next_sample(es1371_t *es1371, int dac_nr) +static inline float low_fir_es1371(int dac_nr, int i, float NewSample) { + static float x[2][2][128]; //input samples + static int x_pos[2] = {0, 0}; + float out = 0.0; + int read_pos; + int n_coef; + int pos = x_pos[dac_nr]; + + x[dac_nr][i][pos] = NewSample; + + /*Since only 1/16th of input samples are non-zero, only filter those that + are valid.*/ + read_pos = (pos + 15) & (127 & ~15); + n_coef = (16 - pos) & 15; + + while (n_coef < ES1371_NCoef) + { + out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; + read_pos = (read_pos + 16) & (127 & ~15); + n_coef += 16; + } + + if (i == 1) + { + x_pos[dac_nr] = (x_pos[dac_nr] + 1) & 127; + if (x_pos[dac_nr] > 127) + x_pos[dac_nr] = 0; + } + + return out; +} + +static void es1371_next_sample_filtered(es1371_t *es1371, int dac_nr, int out_idx) +{ + int out_l, out_r; + int c; + if ((es1371->dac[dac_nr].buffer_pos - es1371->dac[dac_nr].buffer_pos_end) >= 0) { es1371_fetch(es1371, dac_nr); } - es1371->dac[dac_nr].out_l = es1371->dac[dac_nr].buffer_l[es1371->dac[dac_nr].buffer_pos & 63]; - es1371->dac[dac_nr].out_r = es1371->dac[dac_nr].buffer_r[es1371->dac[dac_nr].buffer_pos & 63]; + out_l = es1371->dac[dac_nr].buffer_l[es1371->dac[dac_nr].buffer_pos & 63]; + out_r = es1371->dac[dac_nr].buffer_r[es1371->dac[dac_nr].buffer_pos & 63]; + + es1371->dac[dac_nr].filtered_l[out_idx] = (int)low_fir_es1371(dac_nr, 0, (float)out_l); + es1371->dac[dac_nr].filtered_r[out_idx] = (int)low_fir_es1371(dac_nr, 1, (float)out_r); + for (c = 1; c < 16; c++) + { + es1371->dac[dac_nr].filtered_l[out_idx+c] = (int)low_fir_es1371(dac_nr, 0, 0); + es1371->dac[dac_nr].filtered_r[out_idx+c] = (int)low_fir_es1371(dac_nr, 1, 0); + } + // pclog("Use %02x %04x %04x\n", es1371->dac[dac_nr].buffer_pos & 63, es1371->dac[dac_nr].out_l, es1371->dac[dac_nr].out_r); es1371->dac[dac_nr].buffer_pos++; @@ -1026,12 +1083,22 @@ static void es1371_poll(void *p) if (es1371->int_ctrl & INT_DAC1_EN) { + int frac = es1371->dac[0].ac & 0x7fff; + int idx = es1371->dac[0].ac >> 15; + int samp1_l = es1371->dac[0].filtered_l[idx]; + int samp1_r = es1371->dac[0].filtered_r[idx]; + int samp2_l = es1371->dac[0].filtered_l[(idx + 1) & 31]; + int samp2_r = es1371->dac[0].filtered_r[(idx + 1) & 31]; + + es1371->dac[0].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + es1371->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; // pclog("1Samp %i %i %08x\n", es1371->dac[0].curr_samp_ct, es1371->dac[0].samp_ct, es1371->dac[0].ac); es1371->dac[0].ac += es1371->dac[0].vf; - if (es1371->dac[0].ac & (~0 << (15+4))) + es1371->dac[0].ac &= ((32 << 15) - 1); + if ((es1371->dac[0].ac >> (15+4)) != es1371->dac[0].f_pos) { - es1371->dac[0].ac &= ~(~0 << (15+4)); - es1371_next_sample(es1371, 0); + es1371_next_sample_filtered(es1371, 0, es1371->dac[0].f_pos ? 16 : 0); + es1371->dac[0].f_pos = (es1371->dac[0].f_pos + 1) & 1; es1371->dac[0].curr_samp_ct++; if (es1371->dac[0].curr_samp_ct == es1371->dac[0].samp_ct) @@ -1049,21 +1116,33 @@ static void es1371_poll(void *p) if (es1371->int_ctrl & INT_DAC2_EN) { + int frac = es1371->dac[1].ac & 0x7fff; + int idx = es1371->dac[1].ac >> 15; + int samp1_l = es1371->dac[1].filtered_l[idx]; + int samp1_r = es1371->dac[1].filtered_r[idx]; + int samp2_l = es1371->dac[1].filtered_l[(idx + 1) & 31]; + int samp2_r = es1371->dac[1].filtered_r[(idx + 1) & 31]; + + es1371->dac[1].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + es1371->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; // pclog("2Samp %i %i %08x\n", es1371->dac[1].curr_samp_ct, es1371->dac[1].samp_ct, es1371->dac[1].ac); es1371->dac[1].ac += es1371->dac[1].vf; - if (es1371->dac[1].ac & (~0 << (15+4))) + es1371->dac[1].ac &= ((32 << 15) - 1); + if ((es1371->dac[1].ac >> (15+4)) != es1371->dac[1].f_pos) { - es1371->dac[1].ac &= ~(~0 << (15+4)); - es1371_next_sample(es1371, 1); + es1371_next_sample_filtered(es1371, 1, es1371->dac[1].f_pos ? 16 : 0); + es1371->dac[1].f_pos = (es1371->dac[1].f_pos + 1) & 1; es1371->dac[1].curr_samp_ct++; - if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) + if (es1371->dac[1].curr_samp_ct == es1371->dac[1].samp_ct) { - es1371->dac[1].curr_samp_ct = 0; +// es1371->dac[1].curr_samp_ct = 0; // pclog("DAC2 IRQ\n"); es1371->int_status |= INT_STATUS_DAC2; es1371_update_irqs(es1371); } + if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) + es1371->dac[1].curr_samp_ct = 0; } } } @@ -1081,6 +1160,40 @@ static void es1371_get_buffer(int32_t *buffer, int len, void *p) es1371->pos = 0; } +static inline double sinc(double x) +{ + return sin(M_PI * x) / (M_PI * x); +} + +static void generate_es1371_filter() +{ + /*Cutoff frequency = 1 / 32*/ + float fC = 1.0 / 32.0; + float gain; + int n; + + for (n = 0; n < ES1371_NCoef; n++) + { + /*Blackman window*/ + double w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(ES1371_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(ES1371_NCoef-1))); + /*Sinc filter*/ + double h = sinc(2.0 * fC * ((double)n - ((double)(ES1371_NCoef-1) / 2.0))); + + /*Create windowed-sinc filter*/ + low_fir_es1371_coef[n] = w * h; + } + + low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; + + gain = 0.0; + for (n = 0; n < ES1371_NCoef; n++) + gain += low_fir_es1371_coef[n] / (float)N; + + /*Normalise filter, to produce unity gain*/ + for (n = 0; n < ES1371_NCoef; n++) + low_fir_es1371_coef[n] /= gain; +} + static void *es1371_init() { es1371_t *es1371 = malloc(sizeof(es1371_t)); @@ -1091,6 +1204,8 @@ static void *es1371_init() es1371->card = pci_add(es1371_pci_read, es1371_pci_write, es1371); timer_add(es1371_poll, &es1371->dac[1].time, TIMER_ALWAYS_ENABLED, es1371); + + generate_es1371_filter(); return es1371; } From 1d5afd1d9a4ea8e4ca5473f556df02abb261fe26 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Mar 2018 22:08:32 +0000 Subject: [PATCH 0387/1050] Added AudioPCI info to status window. --- src/sound_audiopci.c | 50 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index bd47be9..bb2cd73 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -1224,6 +1224,54 @@ static void es1371_speed_changed(void *p) es1371->dac[1].latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); } +void es1371_add_status_info_dac(es1371_t *es1371, char *s, int max_len, int dac_nr) +{ + int ena = dac_nr ? INT_DAC2_EN : INT_DAC1_EN; + char *dac_name = dac_nr ? "DAC2 (Wave)" : "DAC1 (MIDI)"; + char temps[128]; + + if (es1371->int_ctrl & ena) + { + int format = dac_nr ? ((es1371->si_cr >> 2) & 3) : (es1371->si_cr & 3); + double freq = 48000.0 * ((double)es1371->dac[dac_nr].vf / (32768.0 * 16.0)); + + switch (format) + { + case FORMAT_MONO_8: + snprintf(temps, 128, "%s format : 8-bit mono\n", dac_name); + break; + case FORMAT_STEREO_8: + snprintf(temps, 128, "%s format : 8-bit stereo\n", dac_name); + break; + case FORMAT_MONO_16: + snprintf(temps, 128, "%s format : 16-bit mono\n", dac_name); + break; + case FORMAT_STEREO_16: + snprintf(temps, 128, "%s format : 16-bit stereo\n", dac_name); + break; + } + + strncat(s, temps, max_len); + max_len -= strlen(temps); + + snprintf(temps, 128, "Playback frequency : %i Hz\n", (int)freq); + strncat(s, temps, max_len); + } + else + { + snprintf(temps, max_len, "%s stopped\n", dac_name); + strncat(s, temps, max_len); + } +} + +void es1371_add_status_info(char *s, int max_len, void *p) +{ + es1371_t *es1371 = (es1371_t *)p; + + es1371_add_status_info_dac(es1371, s, max_len, 0); + es1371_add_status_info_dac(es1371, s, max_len, 1); +} + device_t es1371_device = { "Ensoniq AudioPCI (ES1371)", @@ -1233,6 +1281,6 @@ device_t es1371_device = NULL, es1371_speed_changed, NULL, - NULL, + es1371_add_status_info, NULL }; From 6602368cc4243fa6c9d43c288b0326a76ac1c87f Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 15 Mar 2018 19:36:30 +0000 Subject: [PATCH 0388/1050] Implemented ATAPI DMA transfer modes. --- src/ide.c | 35 +++++++++----- src/ide.h | 14 +++++- src/ide_atapi.c | 120 +++++++++++++++++++++++++++++++++++++++++------- src/ide_atapi.h | 4 +- src/piix.c | 44 +++++++++--------- src/scsi.h | 1 + src/scsi_cd.c | 62 ++++++++++++++++++++++++- src/scsi_hd.c | 1 + src/scsi_zip.c | 62 ++++++++++++++++++++++++- 9 files changed, 289 insertions(+), 54 deletions(-) diff --git a/src/ide.c b/src/ide.c index 3f8a6a7..09933f4 100644 --- a/src/ide.c +++ b/src/ide.c @@ -45,6 +45,7 @@ #define WIN_SETIDLE1 0xE3 #define WIN_CHECK_POWER_MODE 0xE5 #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xEF /** Evaluate to non-zero if the currently selected drive is an ATAPI device */ #define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) @@ -93,8 +94,8 @@ IDE *ext_ide; char ide_fn[7][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_data)(int channel, uint8_t *data, int size); +int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size); void (*ide_bus_master_set_irq)(int channel); int idecallback[2] = {0, 0}; @@ -582,7 +583,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) return; case WIN_IDENTIFY: /* Identify Device */ - case 0xEF: + case WIN_SET_FEATURES: // output=3; // timetolive=500; ide->atastat = BUSY_STAT; @@ -593,7 +594,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_PACKETCMD: /* ATAPI Packet */ if (ide->type == IDE_CDROM) - atapi_command_start(&ide->atapi); + atapi_command_start(&ide->atapi, ide->cylprecomp); ide->atastat = BUSY_STAT; timer_process(); @@ -932,9 +933,9 @@ void callbackide(int ide_board) } ide->pos=0; - if (ide_bus_master_read_sector) + if (ide_bus_master_read_data) { - if (ide_bus_master_read_sector(ide_board, &ide->sector_buffer[ide->sector_pos*512])) + if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512)) idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ else { @@ -1010,9 +1011,9 @@ void callbackide(int ide_board) goto abort_cmd; } - if (ide_bus_master_write_sector) + if (ide_bus_master_write_data) { - if (ide_bus_master_write_sector(ide_board, (uint8_t *)ide->buffer)) + if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512)) idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ else { @@ -1138,7 +1139,6 @@ void callbackide(int ide_board) return; case WIN_SETIDLE1: /* Idle */ - case 0xEF: goto abort_cmd; case WIN_IDENTIFY: /* Identify Device */ @@ -1161,7 +1161,18 @@ void callbackide(int ide_board) } return; + case WIN_SET_FEATURES: + if (ide->type == IDE_NONE) + goto abort_cmd; + if (!IDE_DRIVE_IS_CDROM(ide)) + goto abort_cmd; + if (!atapi_dev->bus.devices[0]->atapi_set_feature(ide->cylprecomp, ide->secount, atapi_dev->bus.device_data[0])) + goto abort_cmd; + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; + case WIN_CHECK_POWER_MODE: if (ide->type == IDE_NONE) { @@ -1291,10 +1302,10 @@ static void ide_close(void *p) { } -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_data)(int channel, uint8_t *data, int size), int (*write_data)(int channel, uint8_t *data, int size), void (*set_irq)(int channel)) { - ide_bus_master_read_sector = read_sector; - ide_bus_master_write_sector = write_sector; + ide_bus_master_read_data = read_data; + ide_bus_master_write_data = write_data; ide_bus_master_set_irq = set_irq; } diff --git a/src/ide.h b/src/ide.h index 3389c4d..cb497ea 100644 --- a/src/ide.h +++ b/src/ide.h @@ -15,9 +15,13 @@ extern void ide_pri_enable(); extern void ide_sec_enable(); extern void ide_pri_disable(); extern void ide_sec_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_data)(int channel, uint8_t *data, int size), int (*write_data)(int channel, uint8_t *data, int size), void (*set_irq)(int channel)); void ide_irq_raise(struct IDE *ide); +extern int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size); +extern int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size); +extern void (*ide_bus_master_set_irq)(int channel); + #include "ide_atapi.h" extern int ideboard; @@ -47,4 +51,12 @@ extern device_t ide_device; #define ABRT_ERR 0x04 /* Command aborted */ #define MCR_ERR 0x08 /* Media change request */ +#define FEATURE_SET_TRANSFER_MODE 0x03 +#define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d +#define FEATURE_ENABLE_IRQ_SERVICE 0x5e +#define FEATURE_DISABLE_REVERT 0x66 +#define FEATURE_ENABLE_REVERT 0xcc +#define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd +#define FEATURE_DISABLE_IRQ_SERVICE 0xde + #endif //__IDE__ diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 0570eba..ccd7136 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -17,6 +17,11 @@ #define ATAPI_STATE_READ_DATA_WAIT 8 #define ATAPI_STATE_WRITE_DATA 9 #define ATAPI_STATE_WRITE_DATA_WAIT 10 +#define ATAPI_STATE_RETRY_READ_DMA 11 +#define ATAPI_STATE_RETRY_WRITE_DMA 12 + +#define FEATURES_DMA 0x01 +#define FEATURES_OVERLAP 0x02 ATAPI *atapi; @@ -94,9 +99,11 @@ static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) return 0; } -void atapi_command_start(atapi_device_t *atapi) +void atapi_command_start(atapi_device_t *atapi, uint8_t features) { scsi_bus_t *bus = &atapi->bus; + + atapi->use_dma = features & 1; scsi_bus_update(bus, BUS_SEL | BUS_SETDATA(1 << 0)); if (!(scsi_bus_read(bus) & BUS_BSY)) @@ -243,19 +250,47 @@ void atapi_process_packet(atapi_device_t *atapi_dev) switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { case 0: - atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT; - atapi_dev->data_read_pos = scsi_dev->get_bytes_required(scsi_data); - if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len) - atapi_dev->data_read_pos = atapi_dev->max_transfer_len; atapi_dev->data_write_pos = 0; - *atapi_dev->cylinder = atapi_dev->data_read_pos; + + if (atapi_dev->use_dma) + { + if (ide_bus_master_write_data) + { + if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos)) + { + atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; + idecallback[atapi_dev->board] = 1*IDE_TIME; + } + else + + atapi_dev->data_write_pos = atapi_dev->data_read_pos; { + atapi_dev->bus_state = 0; + atapi_dev->state = ATAPI_STATE_WRITE_DATA; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + } + else + { + atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; + idecallback[atapi_dev->board] = 1*IDE_TIME; + } + } + else + { + if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len) + atapi_dev->data_read_pos = atapi_dev->max_transfer_len; + + atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT; -// pclog("WRITE_DATA: bytes=%i\n", *atapi_dev->cylinder); - *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); - atapi_dev->bus_state = BUS_REQ; - ide_irq_raise(atapi_dev->ide); + *atapi_dev->cylinder = atapi_dev->data_read_pos; + +// pclog("WRITE_DATA: bytes=%i\n", *atapi_dev->cylinder); + *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); + atapi_dev->bus_state = BUS_REQ; + ide_irq_raise(atapi_dev->ide); + } break; case BUS_IO: @@ -391,12 +426,36 @@ void atapi_process_packet(atapi_device_t *atapi_dev) if ((scsi_bus_read(&atapi_dev->bus) & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) break; } - atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT; - *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); - *atapi_dev->cylinder = atapi_dev->data_write_pos; -// pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder); - atapi_dev->bus_state = BUS_IO | BUS_REQ; - ide_irq_raise(atapi_dev->ide); + if (atapi_dev->use_dma) + { + if (ide_bus_master_read_data) + { + if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos)) + { + atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; + idecallback[atapi_dev->board] = 1*IDE_TIME; + } + else + { + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + idecallback[atapi_dev->board] = 6*IDE_TIME; + } + } + else + { + atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; + idecallback[atapi_dev->board] = 1*IDE_TIME; + } + } + else + { + atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT; + *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); + *atapi_dev->cylinder = atapi_dev->data_write_pos; +// pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder); + atapi_dev->bus_state = BUS_IO | BUS_REQ; + ide_irq_raise(atapi_dev->ide); + } } break; @@ -473,5 +532,34 @@ void atapi_process_packet(atapi_device_t *atapi_dev) idecallback[atapi_dev->board] = 6 * IDE_TIME; } break; + + case ATAPI_STATE_RETRY_READ_DMA: + { + if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos)) + { + idecallback[atapi_dev->board] = 1*IDE_TIME; + } + else + { + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + idecallback[atapi_dev->board] = 6*IDE_TIME; + } + } + break; + + case ATAPI_STATE_RETRY_WRITE_DMA: + { + if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos)) + { + idecallback[atapi_dev->board] = 1*IDE_TIME; + } + else + { + atapi_dev->bus_state = 0; + atapi_dev->state = ATAPI_STATE_WRITE_DATA; + idecallback[atapi_dev->board] = 6 * IDE_TIME; + } + } + break; } } diff --git a/src/ide_atapi.h b/src/ide_atapi.h index c46511c..f737090 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -53,11 +53,13 @@ typedef struct atapi_device_t uint8_t *atastat; uint8_t *error; int *cylinder; + + int use_dma; } atapi_device_t; void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val); uint16_t atapi_data_read(atapi_device_t *atapi_dev); -void atapi_command_start(atapi_device_t *atapi); +void atapi_command_start(atapi_device_t *atapi, uint8_t features); uint8_t atapi_read_iir(atapi_device_t *atapi_dev); uint8_t atapi_read_drq(atapi_device_t *atapi_dev); void atapi_process_packet(atapi_device_t *atapi_dev); diff --git a/src/piix.c b/src/piix.c index 7538a66..b902419 100644 --- a/src/piix.c +++ b/src/piix.c @@ -216,21 +216,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_data_read(int channel, uint8_t *data, int size) { int transferred = 0; if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ - while (transferred < 512) + while (transferred < size) { - 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 < (size - transferred) && piix_busmaster[channel].eot) + fatal("DMA on channel %i - Read count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot, size); - mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+511); + mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+(size-1)); - if (piix_busmaster[channel].count < (512 - transferred)) + if (piix_busmaster[channel].count < (size - transferred)) { // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); if (piix_busmaster[channel].addr < (mem_size * 1024)) @@ -246,17 +246,17 @@ int piix_bus_master_sector_read(int channel, uint8_t *data) } else { -// pclog("Transferring larger - %i bytes\n", 512 - transferred); +// pclog("Transferring larger - %i bytes\n", size - transferred); if (piix_busmaster[channel].addr < (mem_size * 1024)) { - int count = 512 - transferred; + int count = size - transferred; if ((piix_busmaster[channel].addr + count) > (mem_size * 1024)) count = (mem_size * 1024) - piix_busmaster[channel].addr; memcpy(&ram[piix_busmaster[channel].addr], data + transferred, count); } - piix_busmaster[channel].addr += (512 - transferred); - piix_busmaster[channel].count -= (512 - transferred); - transferred += (512 - transferred); + piix_busmaster[channel].addr += (size - transferred); + piix_busmaster[channel].count -= (size - transferred); + transferred += (size - 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); @@ -275,19 +275,19 @@ 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_data_write(int channel, uint8_t *data, int size) { int transferred = 0; if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ - while (transferred < 512) + while (transferred < size) { - 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 < (size - transferred) && piix_busmaster[channel].eot) + fatal("DMA on channel %i - Write count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot, size); - if (piix_busmaster[channel].count < (512 - transferred)) + if (piix_busmaster[channel].count < (size - transferred)) { // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); if (piix_busmaster[channel].addr < (mem_size * 1024)) @@ -303,17 +303,17 @@ int piix_bus_master_sector_write(int channel, uint8_t *data) } else { -// pclog("Transferring larger - %i bytes\n", 512 - transferred); +// pclog("Transferring larger - %i bytes\n", size - transferred); if (piix_busmaster[channel].addr < (mem_size * 1024)) { - int count = 512 - transferred; + int count = size - transferred; if ((piix_busmaster[channel].addr + count) > (mem_size * 1024)) count = (mem_size * 1024) - piix_busmaster[channel].addr; memcpy(data + transferred, &ram[piix_busmaster[channel].addr], count); } - piix_busmaster[channel].addr += (512 - transferred); - piix_busmaster[channel].count -= (512 - transferred); - transferred += (512 - transferred); + piix_busmaster[channel].addr += (size - transferred); + piix_busmaster[channel].count -= (size - transferred); + transferred += (size - 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); @@ -377,7 +377,7 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; - 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_data_read, piix_bus_master_data_write, piix_bus_master_set_irq); pci_set_card_routing(pci_a, PCI_INTA); pci_set_card_routing(pci_b, PCI_INTB); diff --git a/src/scsi.h b/src/scsi.h index a89010c..8791011 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -18,6 +18,7 @@ typedef struct scsi_device_t int (*get_bytes_required)(void *p); void (*atapi_identify)(uint16_t *buffer, void *p); + int (*atapi_set_feature)(uint8_t feature, uint8_t val, void *p); uint8_t (*read)(void *p); void (*write)(uint8_t val, void *p); diff --git a/src/scsi_cd.c b/src/scsi_cd.c index f7721f5..d782d78 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -3,6 +3,7 @@ #include #include #include "ibm.h" +#include "ide.h" #include "ide_atapi.h" #include "scsi.h" #include "scsi_cd.h" @@ -194,6 +195,8 @@ typedef struct scsi_cd_data_t int is_atapi; atapi_device_t *atapi_dev; + + int pio_mode, mdma_mode; } scsi_cd_data_t; static void scsi_add_data(scsi_cd_data_t *data, uint8_t val) @@ -1171,16 +1174,72 @@ static int scsi_cd_get_bytes_required(void *p) static void scsi_cd_atapi_identify(uint16_t *buffer, void *p) { + scsi_cd_data_t *data = p; + memset(buffer, 0, 512); buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *)(buffer + 23), "v1.0", 8); /* Firmware */ ide_padstr((char *)(buffer + 27), "PCemCD", 40); /* Model */ - buffer[49] = 0x200; /* LBA supported */ + buffer[49] = 0x300; /*DMA and LBA supported*/ + buffer[51] = 120; + buffer[52] = 120; + buffer[53] = 2; /*Words 64-70 are valid*/ + buffer[62] = 0x0000; + buffer[63] = 0x0007 | (0x100 << data->mdma_mode); /*Multi-word DMA 0, 1 & 2*/ + buffer[64] = 0x0003; /*PIO Modes 3 & 4*/ + if (data->pio_mode >= 3) + buffer[64] |= (0x100 << (data->pio_mode - 3)); + buffer[65] = 120; /*Minimum multi-word cycle time*/ + buffer[66] = 120; /*Recommended multi-word cycle time*/ + buffer[67] = 120; /*Minimum PIO cycle time*/ buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ } +static int scsi_cd_atapi_set_feature(uint8_t feature, uint8_t val, void *p) +{ + scsi_cd_data_t *data = p; + + switch (feature) + { + case FEATURE_SET_TRANSFER_MODE: + if (!(val & 0xfe)) + { + /*Default transfer mode*/ + data->pio_mode = 0; + return 1; + } + else if ((val & 0xf8) == 0x08) + { + /*PIO transfer mode*/ + if ((val & 7) > 4) + return 0; + data->pio_mode = (val & 7); + return 1; + } + else if ((val & 0xf8) == 0x20) + { + /*Multi-word DMA transfer mode*/ + if ((val & 7) > 2) + return 0; + data->mdma_mode = (val & 7); + return 1; + } + return 0; /*Invalid data*/ + + case FEATURE_ENABLE_IRQ_OVERLAPPED: + case FEATURE_ENABLE_IRQ_SERVICE: + case FEATURE_DISABLE_REVERT: + case FEATURE_DISABLE_IRQ_OVERLAPPED: + case FEATURE_DISABLE_IRQ_SERVICE: + case FEATURE_ENABLE_REVERT: + return 1; + } + + return 0; /*Feature not supported*/ +} + scsi_device_t scsi_cd = { scsi_cd_init, @@ -1195,6 +1254,7 @@ scsi_device_t scsi_cd = scsi_cd_get_bytes_required, scsi_cd_atapi_identify, + scsi_cd_atapi_set_feature, scsi_cd_read, scsi_cd_write, diff --git a/src/scsi_hd.c b/src/scsi_hd.c index 9cd60ba..f314ebf 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -826,6 +826,7 @@ scsi_device_t scsi_hd = scsi_hd_get_sense_key, scsi_hd_get_bytes_required, + NULL, NULL, scsi_hd_read, diff --git a/src/scsi_zip.c b/src/scsi_zip.c index e6bb291..18421c5 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -4,6 +4,7 @@ #include #include "ibm.h" #include "hdd_file.h" +#include "ide.h" #include "ide_atapi.h" #include "scsi.h" #include "scsi_zip.h" @@ -73,6 +74,8 @@ typedef struct scsi_zip_data atapi_device_t *atapi_dev; int read_only; + + int pio_mode, mdma_mode; } scsi_zip_data; static scsi_zip_data *zip_data; @@ -1077,16 +1080,72 @@ static int scsi_zip_get_bytes_required(void *p) static void scsi_zip_atapi_identify(uint16_t *buffer, void *p) { + scsi_zip_data *data = p; + memset(buffer, 0, 512); buffer[0] = 0x8000 | (0<<8) | 0x80 | (2<<5); /* ATAPI device, direct-access device, removable media, accelerated DRQ */ ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *)(buffer + 23), "E.08", 8); /* Firmware */ ide_padstr((char *)(buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ - buffer[49] = 0x200; /* LBA supported */ + buffer[49] = 0x300; /*DMA and LBA supported*/ + buffer[51] = 120; + buffer[52] = 120; + buffer[53] = 2; /*Words 64-70 are valid*/ + buffer[62] = 0x0000; + buffer[63] = 0x0003 | (0x100 << data->mdma_mode); /*Multi-word DMA 0 & 1*/ + buffer[64] = 0x0001; /*PIO Mode 3*/ + if (data->pio_mode >= 3) + buffer[64] |= (0x100 << (data->pio_mode - 3)); + buffer[65] = 120; /*Minimum multi-word cycle time*/ + buffer[66] = 120; /*Recommended multi-word cycle time*/ + buffer[67] = 120; /*Minimum PIO cycle time*/ buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ } +static int scsi_zip_atapi_set_feature(uint8_t feature, uint8_t val, void *p) +{ + scsi_zip_data *data = p; + + switch (feature) + { + case FEATURE_SET_TRANSFER_MODE: + if (!(val & 0xfe)) + { + /*Default transfer mode*/ + data->pio_mode = 0; + return 1; + } + else if ((val & 0xf8) == 0x08) + { + /*PIO transfer mode*/ + if ((val & 7) > 3) + return 0; + data->pio_mode = (val & 7); + return 1; + } + else if ((val & 0xf8) == 0x20) + { + /*Multi-word DMA transfer mode*/ + if ((val & 7) > 1) + return 0; + data->mdma_mode = (val & 7); + return 1; + } + return 0; /*Invalid data*/ + + case FEATURE_ENABLE_IRQ_OVERLAPPED: + case FEATURE_ENABLE_IRQ_SERVICE: + case FEATURE_DISABLE_REVERT: + case FEATURE_DISABLE_IRQ_OVERLAPPED: + case FEATURE_DISABLE_IRQ_SERVICE: + case FEATURE_ENABLE_REVERT: + return 1; + } + + return 0; /*Feature not supported*/ +} + scsi_device_t scsi_zip = { scsi_zip_init, @@ -1101,6 +1160,7 @@ scsi_device_t scsi_zip = scsi_zip_get_bytes_required, scsi_zip_atapi_identify, + scsi_zip_atapi_set_feature, scsi_zip_read, scsi_zip_write, From db5a5ea13f88e0702352c76b5233d8b785807e54 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 16 Mar 2018 18:22:00 +0000 Subject: [PATCH 0389/1050] Fixed typo in ide_atapi.c. --- src/ide_atapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ide_atapi.c b/src/ide_atapi.c index ccd7136..78a57bd 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -264,8 +264,8 @@ void atapi_process_packet(atapi_device_t *atapi_dev) idecallback[atapi_dev->board] = 1*IDE_TIME; } else - - atapi_dev->data_write_pos = atapi_dev->data_read_pos; { + { + atapi_dev->data_write_pos = atapi_dev->data_read_pos; atapi_dev->bus_state = 0; atapi_dev->state = ATAPI_STATE_WRITE_DATA; idecallback[atapi_dev->board] = 6 * IDE_TIME; From a22b735da048764c5452a57b73d61e680ab3696a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Mar 2018 11:39:33 +0000 Subject: [PATCH 0390/1050] Added configurable CD-ROM speed. --- src/ide_atapi.c | 4 +- src/pc.c | 5 + src/pc.xrc | 35 ++++++ src/scsi_cd.c | 285 ++++++++++++++++++++++++++++++++++++++++--- src/scsi_cd.h | 6 + src/wx-config.c | 31 +++++ src/wx-resources.cpp | 74 ++++++++++- 7 files changed, 421 insertions(+), 19 deletions(-) diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 78a57bd..1760a43 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -438,7 +438,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) else { atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 6*IDE_TIME; + idecallback[atapi_dev->board] = 1*IDE_TIME; } } else @@ -490,7 +490,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) } atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + idecallback[atapi_dev->board] = 1 * IDE_TIME; } break; diff --git a/src/pc.c b/src/pc.c index 71fd9f4..67b99a0 100644 --- a/src/pc.c +++ b/src/pc.c @@ -35,6 +35,7 @@ #include "plat-keyboard.h" #include "plat-midi.h" #include "plat-mouse.h" +#include "scsi_cd.h" #include "scsi_zip.h" #include "serial.h" #include "sound.h" @@ -781,6 +782,8 @@ void loadconfig(char *fn) fdd_set_type(1, config_get_int(CFG_MACHINE, NULL, "drive_b_type", 7)); bpb_disable = config_get_int(CFG_MACHINE, NULL, "bpb_disable", 0); + cd_speed = config_get_int(CFG_MACHINE, NULL, "cd_speed", 24); + joystick_type = config_get_int(CFG_MACHINE, NULL, "joystick_type", 0); mouse_type = config_get_int(CFG_MACHINE, NULL, "mouse_type", 0); @@ -926,6 +929,8 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "drive_b_type", fdd_get_type(1)); config_set_int(CFG_MACHINE, NULL, "bpb_disable", bpb_disable); + config_set_int(CFG_MACHINE, NULL, "cd_speed", cd_speed); + config_set_int(CFG_MACHINE, NULL, "joystick_type", joystick_type); config_set_int(CFG_MACHINE, NULL, "mouse_type", mouse_type); diff --git a/src/pc.xrc b/src/pc.xrc index bc38ddc..06ac8a1 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -1127,6 +1127,41 @@ 5 0,0 + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + diff --git a/src/scsi_cd.c b/src/scsi_cd.c index d782d78..33b11ad 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -7,8 +7,10 @@ #include "ide_atapi.h" #include "scsi.h" #include "scsi_cd.h" +#include "timer.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define ABS(x) ((x) > 0 ? (x) : -(x)) #define BUFFER_SIZE (256*1024) @@ -20,7 +22,8 @@ enum CMD_POS_IDLE = 0, CMD_POS_WAIT, CMD_POS_START_SECTOR, - CMD_POS_TRANSFER + CMD_POS_TRANSFER, + CMD_POS_COMPLETE }; /* ATAPI Commands */ @@ -162,7 +165,10 @@ typedef struct scsi_cd_data_t int blocks; - int cmd_pos; + int cmd_pos, new_cmd_pos; + int callback; + int wait_time; + scsi_bus_t *bus; int addr, len; int sector_pos; @@ -197,8 +203,115 @@ typedef struct scsi_cd_data_t atapi_device_t *atapi_dev; int pio_mode, mdma_mode; + + int short_seek, long_seek; + int max_speed, cur_speed; } scsi_cd_data_t; +static scsi_cd_data_t *cd_data = NULL; + +/*Note - all transfer speeds currently assume CAV behaviour. Drives above about 8x + should use CLV instead, but this is not currently supported.*/ +static struct +{ + int speed; + int short_seek; + int long_seek; +} cd_speeds[] = +{ + {1, 240, 1446}, + {2, 160, 1000}, + {3, 150, 900}, + {4, 112, 675}, + {6, 112, 675}, + {8, 112, 675}, + {12, 75, 400}, + {16, 58, 350}, + {20, 50, 300}, + {24, 45, 270}, + {32, 45, 270}, + {40, 50, 300}, + {44, 50, 300}, + {48, 50, 300}, + {52, 45, 270}, + {72, 45, 270}, +}; + +int cd_speed; + +int cd_get_speed(int i) +{ + return cd_speeds[i].speed; +} + +void cd_set_speed(int speed) +{ + if (cd_data) + { + int c = 0; + + while (1) + { + if (cd_speeds[c].speed == speed) + break; + if (cd_speeds[c].speed >= MAX_CD_SPEED) + break; + + c++; + } + + cd_data->max_speed = speed; + cd_data->cur_speed = speed; + cd_data->short_seek = cd_speeds[c].short_seek; + cd_data->long_seek = cd_speeds[c].long_seek; + } +} + +static void scsi_cd_callback(void *p) +{ + scsi_cd_data_t *data = p; + + if (data->cmd_pos == CMD_POS_WAIT) + { + data->wait_time--; + if (!data->wait_time) + { + data->callback = 0; + data->cmd_pos = data->new_cmd_pos; + scsi_bus_kick(data->bus); + } + else + data->callback = 1000 * TIMER_USEC; + } + else + data->callback = 0; +} + +//#define SECTOR_TIME 13333 /*Time between sectors on 1x drive*/ +#define SECTOR_TIME 12000 /*Adjusted from above value to account for transfer time on current SCSI/ATAPI code*/ + +/*The seek model is currently very basic. Seeks of less than MIN_SEEK sectors are treated as + immediate. Seeks between MIN_SEEK and MAX_SEEK sectors scale linearly between short_seek and + long seek. + + This really shouldn't be a linear scale, but this is a good enough approximation for now.*/ +#define MIN_SEEK 2000 +#define MAX_SEEK 333000 + +static int get_seek_time(scsi_cd_data_t *data, uint32_t start, uint32_t dest) +{ + uint32_t diff = ABS((int)(start - dest)); + + if (diff < MIN_SEEK) + return 0; + if (diff > MAX_SEEK) + diff = MAX_SEEK; + + diff -= MIN_SEEK; + + return data->short_seek + ((data->long_seek * diff) / (MAX_SEEK - MIN_SEEK)); +} + static void scsi_add_data(scsi_cd_data_t *data, uint8_t val) { data->data_in[data->data_pos_write++] = val; @@ -278,11 +391,17 @@ static void *scsi_cd_init(scsi_bus_t *bus, int id) scsi_cd_data_t *data = malloc(sizeof(scsi_cd_data_t)); memset(data, 0, sizeof(scsi_cd_data_t)); + data->bus = bus; data->id = 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. */ page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; + + timer_add(scsi_cd_callback, &data->callback, &data->callback, data); + + cd_data = data; + cd_set_speed(cd_speed); return data; } @@ -301,6 +420,7 @@ static void scsi_cd_close(void *p) { scsi_cd_data_t *data = p; + cd_data = NULL; free(data); } @@ -387,12 +507,12 @@ static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t 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++] = (uint8_t) ((data->max_speed * 176) >> 8); + buf[pos++] = (uint8_t) (data->max_speed * 176); /* 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++] = (uint8_t) ((data->cur_speed * 176) >> 8); + buf[pos++] = (uint8_t) (data->cur_speed * 176); /* Current speed */ buf[pos++] = 0; /* Reserved */ buf[pos++] = 0; /* Drive digital format */ buf[pos++] = 0; /* Reserved */ @@ -506,6 +626,23 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; case SCSI_REZERO_UNIT: + if (data->cmd_pos == CMD_POS_IDLE) + { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdpos = 0; + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) + { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_COMPLETE; + data->wait_time = seek_time; + data->callback = 1000 * TIMER_USEC; + return SCSI_PHASE_COMMAND; + } + } data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; @@ -553,10 +690,32 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_DATA_IN; case SCSI_SEEK_6: + if (data->cmd_pos == CMD_POS_IDLE) + { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdpos = (((uint32_t)cdb[1] & 0x1f) << 16) | ((uint32_t)cdb[2] << 8) | (uint32_t)cdb[3]; + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) + { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_COMPLETE; + data->wait_time = seek_time; + data->callback = 1000 * TIMER_USEC; + return SCSI_PHASE_COMMAND; + } + } data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; case GPCMD_SET_SPEED: + data->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; + if (data->cur_speed < 1) + data->cur_speed = 1; + else if (data->cur_speed > data->max_speed) + data->cur_speed = data->max_speed; data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; @@ -625,21 +784,60 @@ static int scsi_cd_command(uint8_t *cdb, void *p) if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + data->cdlen = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - data->cmd_pos = CMD_POS_TRANSFER; + data->cmd_pos = CMD_POS_START_SECTOR; data->bytes_expected = data->cdlen * ((rcdmode == 0x10) ? 2048 : 2352); - if (rcdmode == 0x10) - atapi_set_transfer_granularity(data->atapi_dev, 2048); - else - atapi_set_transfer_granularity(data->atapi_dev, 2352); + if (data->is_atapi) + { + if (rcdmode == 0x10) + atapi_set_transfer_granularity(data->atapi_dev, 2048); + else + atapi_set_transfer_granularity(data->atapi_dev, 2352); + } + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) + { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->wait_time = seek_time; + data->callback = 1000 * TIMER_USEC; + return SCSI_PHASE_COMMAND; + } } + if (data->cmd_pos == CMD_POS_WAIT) + return SCSI_PHASE_COMMAND; if (!data->cdlen) { data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; } + if (data->cmd_pos == CMD_POS_START_SECTOR) + { + uint64_t time = (((uint64_t)SECTOR_TIME * (uint64_t)TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; + + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_TRANSFER; + + if (time > 0x7fffffffull) + { + data->wait_time = (int)(time / ((uint64_t)TIMER_USEC * 1000ull)); + data->callback = (int)(time % ((uint64_t)TIMER_USEC * 1000ull));; + } + else + { + data->callback = time; + data->wait_time = 1; + } + if (data->callback == 0) + data->callback = 1; + return SCSI_PHASE_COMMAND; + } if (rcdmode == 0x10) { @@ -683,6 +881,9 @@ static int scsi_cd_command(uint8_t *cdb, void *p) // readcdmode = 0; if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + if (cdb[0] == GPCMD_READ_6) { data->cdlen = cdb[4]; @@ -700,16 +901,51 @@ static int scsi_cd_command(uint8_t *cdb, void *p) } // pclog("cdpos=%08x cdlen=%08x\n", data->cdpos, data->cdlen); - data->cmd_pos = CMD_POS_TRANSFER; + data->cmd_pos = CMD_POS_START_SECTOR; data->bytes_expected = data->cdlen * 2048; - atapi_set_transfer_granularity(data->atapi_dev, 2048); - } + if (data->is_atapi) + atapi_set_transfer_granularity(data->atapi_dev, 2048); + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) + { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->wait_time = seek_time; + data->callback = 1000 * TIMER_USEC; + return SCSI_PHASE_COMMAND; + } + } + if (data->cmd_pos == CMD_POS_WAIT) + return SCSI_PHASE_COMMAND; if (!data->cdlen) { data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; } + if (data->cmd_pos == CMD_POS_START_SECTOR) + { + uint64_t time = (((uint64_t)SECTOR_TIME * (uint64_t)TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; + + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_TRANSFER; + + if (time > 0x7fffffffull) + { + data->wait_time = (int)(time / ((uint64_t)TIMER_USEC * 1000ull)); + data->callback = (int)(time % ((uint64_t)TIMER_USEC * 1000ull));; + } + else + { + data->callback = time; + data->wait_time = 1; + } + if (data->callback == 0) + data->callback = 1; + return SCSI_PHASE_COMMAND; + } + readflash_set(READFLASH_HDC, data->id); c = MIN(data->cdlen, MAX_NR_SECTORS); if (atapi->readsector(data->data_in, data->cdpos, c)) @@ -1066,8 +1302,25 @@ atapi_out: return SCSI_PHASE_STATUS; case GPCMD_SEEK: - pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - atapi->seek(pos); + if (data->cmd_pos == CMD_POS_IDLE) + { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdpos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + atapi->seek(data->cdpos); + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) + { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_COMPLETE; + data->wait_time = seek_time; + data->callback = 1000 * TIMER_USEC; + return SCSI_PHASE_COMMAND; + } + } data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; diff --git a/src/scsi_cd.h b/src/scsi_cd.h index 77f81fb..dc86826 100644 --- a/src/scsi_cd.h +++ b/src/scsi_cd.h @@ -1 +1,7 @@ extern scsi_device_t scsi_cd; + +#define MAX_CD_SPEED 72 +int cd_get_speed(int i); +void cd_set_speed(int speed); + +extern int cd_speed; diff --git a/src/wx-config.c b/src/wx-config.c index fbe9bc9..618363d 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -15,6 +15,7 @@ #include "mem.h" #include "nethandler.h" #include "nvr.h" +#include "scsi_cd.h" #include "sound.h" #include "video.h" #include "vid_voodoo.h" @@ -325,6 +326,30 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for } } +static void recalc_cd_list(void *hdlg, int cur_speed) +{ + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + int c = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + while (1) + { + char s[8]; + int speed; + + speed = cd_get_speed(c); + sprintf(s, "%iX", speed); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + + if (speed == cur_speed) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + + c++; + if (speed >= MAX_CD_SPEED) + break; + } +} + #ifdef USE_NETWORKING static void recalc_net_list(void *hdlg, int model) { @@ -548,6 +573,10 @@ int config_dlgsave(void* hdlg) cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); cpu_update_waitstates(); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + cd_speed = cd_get_speed(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + cd_set_speed(cd_speed); + if (has_been_inited) saveconfig(NULL); @@ -823,6 +852,8 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); } + + recalc_cd_list(hdlg, cd_speed); #ifdef USE_NETWORKING recalc_net_list(hdlg, romstomodel[romset]); diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 76e94d7..13ad3f9 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 136071; +static size_t xml_res_size_26 = 137689; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -3821,6 +3821,78 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, 60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, +77,66,79,95,67,68,83,80,69,69,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, From 48853d372588dbc2c70b8d1e771a34b54c7080aa Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Mar 2018 12:26:51 +0000 Subject: [PATCH 0391/1050] Added missing CD-ROM mode select functionality. --- src/scsi_cd.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 33b11ad..c85f5c8 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -522,6 +522,65 @@ static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t return pos; } +static void cdrom_mode_select(scsi_cd_data_t *data, int data_len) +{ + int len = data->data_out[1] | (data->data_out[0] << 8); + int pos = 8 + len; /*Skip over mode parameter header*/ + + while (pos < data_len) + { + int page_code = data->data_out[pos] & 0x3f; + len = data->data_out[pos+1]; + + pos += 2; + + switch (page_code) + { + case GPMODE_CDROM_AUDIO_PAGE: + if (len != 0xe) + { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + memcpy(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], &data->data_out[pos], 0xe); + page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; + pos += len; + break; + + case GPMODE_R_W_ERROR_PAGE: + if (len != 0x6) + { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + pos += len; + break; + + case GPMODE_CDROM_PAGE: + if (len != 0x6) + { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + pos += len; + break; + + case GPMODE_CAPABILITIES_PAGE: + if (len != 0x12) + { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + pos += len; + break; + + default: + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + } +} + uint32_t atapi_get_cd_channel(int channel) { return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 8 : 6] : (channel + 1); @@ -1030,18 +1089,18 @@ static int scsi_cd_command(uint8_t *cdb, void *p) len = (cdb[7]<<8) | cdb[8]; data->prefix_len = 10; } - data->page_current = cdb[2]; - if (page_flags[data->page_current] & PAGE_CHANGEABLE) - page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; data->cmd_pos = CMD_POS_TRANSFER; data->bytes_required = len; - pclog("MODE_SELECT len=%i\n", len); return SCSI_PHASE_DATA_OUT; } - pclog("MODE_SELECT complete\n"); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; + if (data->bytes_received == data->bytes_required) + { + cdrom_mode_select(data, data->bytes_required); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + return SCSI_PHASE_DATA_OUT; case GPCMD_GET_EVENT_STATUS_NOTIFICATION: /*0x4a*/ temp_command = cdb[0]; From 7915a72604da90383073a8735052c561e6bf1c79 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Mar 2018 12:27:15 +0000 Subject: [PATCH 0392/1050] CD-ROM capabilities now reflect audio level control. --- src/scsi_cd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scsi_cd.c b/src/scsi_cd.c index c85f5c8..32e4012 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -506,10 +506,10 @@ static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t 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++] = 0x03; /* Some other stuff not supported */ buf[pos++] = (uint8_t) ((data->max_speed * 176) >> 8); buf[pos++] = (uint8_t) (data->max_speed * 176); /* Maximum speed */ - buf[pos++] = 0; buf[pos++] = 2; /* Number of audio levels - on and off only */ + buf[pos++] = 1; buf[pos++] = 0; /* Number of audio levels - on and off only */ buf[pos++] = 0; buf[pos++] = 0; /* Buffer size - none */ buf[pos++] = (uint8_t) ((data->cur_speed * 176) >> 8); buf[pos++] = (uint8_t) (data->cur_speed * 176); /* Current speed */ From 98a9c975f451235fda2c6d46de6f115e7ba5af40 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 18 Mar 2018 17:27:54 +0000 Subject: [PATCH 0393/1050] Added command line option to specify floppy disc images. --- src/pc.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/pc.c b/src/pc.c index 67b99a0..12cc456 100644 --- a/src/pc.c +++ b/src/pc.c @@ -64,6 +64,8 @@ int window_w, window_h, window_x, window_y, window_remember; int start_in_fullscreen = 0; +static int override_drive_a = 0, override_drive_b = 0; + int CPUID; int vid_resize, vid_api; @@ -241,6 +243,8 @@ 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("--fullscreen - start in fullscreen mode\n"); + printf("--load_drive_a file.img - load drive A: with the given disc image\n"); + printf("--load_drive_b file.img - load drive B: with the given disc image\n"); exit(-1); } else if (!strcasecmp(argv[c], "--fullscreen")) @@ -266,6 +270,24 @@ void initpc(int argc, char *argv[]) config_override = 1; c++; } + else if (!strcasecmp(argv[c], "--load_drive_a")) + { + if ((c+1) == argc) + break; + + strncpy(discfns[0], argv[c+1], 260); + c++; + override_drive_a = 1; + } + else if (!strcasecmp(argv[c], "--load_drive_b")) + { + if ((c+1) == argc) + break; + + strncpy(discfns[1], argv[c+1], 260); + c++; + override_drive_b = 1; + } } // append_filename(config_file_default, pcempath, "pcem.cfg", 511); @@ -493,6 +515,8 @@ void runpc() char s[200]; int done=0; int cycles_to_run = cpu_get_speed() / 100; + + override_drive_a = override_drive_b = 0; startblit(); @@ -708,13 +732,19 @@ void loadconfig(char *fn) else sound_card_current = 0; - p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_a", ""); - if (p) strcpy(discfns[0], p); - else strcpy(discfns[0], ""); + if (!override_drive_a) + { + p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_a", ""); + if (p) strcpy(discfns[0], p); + else strcpy(discfns[0], ""); + } - p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_b", ""); - if (p) strcpy(discfns[1], p); - else strcpy(discfns[1], ""); + if (!override_drive_b) + { + p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_b", ""); + if (p) strcpy(discfns[1], p); + else strcpy(discfns[1], ""); + } p = (char *)config_get_string(CFG_MACHINE, NULL, "hdd_controller", ""); if (p) From a9ae16b0bf4d030137e4e3a2a0cfd10ca071b509 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Mar 2018 18:05:44 +0000 Subject: [PATCH 0394/1050] Corrected read value of SB16 mixer register 0xa. Fixes SimCity 2000 SB16 detection. --- src/sound_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index cb3eaf9..2095c39 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -772,7 +772,7 @@ uint8_t sb_ct1745_mixer_read(uint16_t addr, void *p) case 0x04: return ((mixer->regs[0x33] >> 4) & 0x0f) | (mixer->regs[0x32] & 0xf0); case 0x0a: - return (mixer->regs[0x2a] - 10) / 3; + return (mixer->regs[0x3a] - 10) / 3; case 0x22: return ((mixer->regs[0x31] >> 4) & 0x0f) | (mixer->regs[0x30] & 0xf0); case 0x26: From f4db376aab214640a6307f852f9e2c86d34d8011 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 17:49:55 +0000 Subject: [PATCH 0395/1050] Added 56x CD-ROM speed. --- src/scsi_cd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 32e4012..215e5e7 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -234,6 +234,7 @@ static struct {44, 50, 300}, {48, 50, 300}, {52, 45, 270}, + {56, 45, 270}, {72, 45, 270}, }; From 9309c2aefb0bc869f71b2eddb9ef36bb25dcc68f Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 17:55:04 +0000 Subject: [PATCH 0396/1050] Implemented T1000/T1200 non-volatile RAM. Patch from JohnElliott. --- src/nvr.c | 2 ++ src/t1000.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++------ src/t1000.h | 2 ++ 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/nvr.c b/src/nvr.c index 5e44fa6..32510aa 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -298,6 +298,7 @@ void loadnvr() t1000_emsboard_loadnvr(); return; case ROM_T1200: tc8521_loadnvr(); + t1200_state_loadnvr(); t1000_emsboard_loadnvr(); return; case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); nvrmask = 127; break; @@ -387,6 +388,7 @@ void savenvr() t1000_emsboard_savenvr(); return; case ROM_T1200: tc8521_savenvr(); + t1200_state_savenvr(); t1000_emsboard_savenvr(); return; case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); break; diff --git a/src/t1000.c b/src/t1000.c index 42937eb..aa8c959 100644 --- a/src/t1000.c +++ b/src/t1000.c @@ -50,7 +50,8 @@ void common_init(); -uint8_t config_sys[160]; +uint8_t t1000_nvram[160]; +uint8_t t1200_nvram[2048]; static struct t1000_system { @@ -70,6 +71,7 @@ static struct t1000_system uint8_t nvr_tick; int nvr_addr; uint8_t nvr_active; + mem_mapping_t nvr_mapping; /* T1200 NVRAM mapping */ /* EMS data */ uint8_t ems_reg[4]; @@ -91,15 +93,29 @@ void t1000_configsys_loadnvr() { FILE *f; - memset(config_sys, 0x1A, sizeof(config_sys)); + memset(t1000_nvram, 0x1A, sizeof(t1000_nvram)); f = nvrfopen("t1000_config.nvr", "rb"); if (f) { - fread(config_sys, sizeof(config_sys), 1, f); + fread(t1000_nvram, sizeof(t1000_nvram), 1, f); fclose(f); } } +void t1200_state_loadnvr() +{ + FILE *f; + + memset(t1200_nvram, 0, sizeof(t1200_nvram)); + f = nvrfopen("t1200_state.nvr", "rb"); + if (f) + { + fread(t1200_nvram, sizeof(t1200_nvram), 1, f); + fclose(f); + } +} + + /* All RAM beyond 512k is non-volatile */ void t1000_emsboard_loadnvr() { @@ -124,11 +140,25 @@ void t1000_configsys_savenvr() f = nvrfopen("t1000_config.nvr", "wb"); if (f) { - fwrite(config_sys, sizeof(config_sys), 1, f); + fwrite(t1000_nvram, sizeof(t1000_nvram), 1, f); fclose(f); } } +void t1200_state_savenvr() +{ + FILE *f; + + f = nvrfopen("t1200_state.nvr", "wb"); + if (f) + { + fwrite(t1200_nvram, sizeof(t1200_nvram), 1, f); + fclose(f); + } +} + + + void t1000_emsboard_savenvr() { @@ -452,7 +482,7 @@ static uint8_t read_t1000_nvram(uint16_t addr, void *priv) case 0xC2: /* Read next byte from NVRAM */ tmp = 0xFF; if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) - tmp = config_sys[sys->nvr_addr]; + tmp = t1000_nvram[sys->nvr_addr]; ++sys->nvr_addr; return tmp; @@ -481,9 +511,9 @@ static void write_t1000_nvram(uint16_t addr, uint8_t val, void *priv) /* Write next byte to NVRAM */ case 0xC1: if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) { - if (config_sys[sys->nvr_addr] != val) + if (t1000_nvram[sys->nvr_addr] != val) nvr_dosave = 1; - config_sys[sys->nvr_addr] = val; + t1000_nvram[sys->nvr_addr] = val; } ++sys->nvr_addr; break; @@ -552,6 +582,19 @@ static uint32_t t1000_read_roml(uint32_t addr, void *priv) return *(uint32_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]); } +static uint8_t read_t1200_nvram(uint32_t addr, void *priv) +{ + return t1200_nvram[addr & 0x7FF]; +} + +static void write_t1200_nvram(uint32_t addr, uint8_t value, void *priv) +{ + if (t1200_nvram[addr & 0x7FF] != value) + { + nvr_dosave = 1; + } + t1200_nvram[addr & 0x7FF] = value; +} void xt_t1000_init() { @@ -644,6 +687,10 @@ void xt_t1200_init() common_init(); mem_add_bios(); + mem_mapping_add(&t1000.nvr_mapping, + 0xF0000, 2048, read_t1200_nvram, NULL, NULL, + write_t1200_nvram, NULL, NULL, + NULL, 0, &t1000); pit_set_out_func(&pit, 1, pit_refresh_timer_xt); keyboard_xt_init(); nmi_init(); diff --git a/src/t1000.h b/src/t1000.h index 34cc548..f822fc8 100644 --- a/src/t1000.h +++ b/src/t1000.h @@ -2,6 +2,8 @@ void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask); void t1000_configsys_loadnvr(); void t1000_emsboard_loadnvr(); +void t1200_state_loadnvr(); void t1000_configsys_savenvr(); void t1000_emsboard_savenvr(); +void t1200_state_savenvr(); From 6c4dcce66eb56344233907c8c86dea32c64b8072 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 17:55:18 +0000 Subject: [PATCH 0397/1050] Add stdint.h to wx-createdisc.cc. Patch from JohnElliott. --- src/wx-createdisc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wx-createdisc.cc b/src/wx-createdisc.cc index cd8ccbc..d9d1a66 100644 --- a/src/wx-createdisc.cc +++ b/src/wx-createdisc.cc @@ -8,6 +8,7 @@ extern "C" void pclog(const char *format, ...); #include "wx/wxprec.h" #include "wx-dialogbox.h" +#include #ifndef WX_PRECOMP #include "wx/wx.h" From 2e90e5fd4c6ac27a73967fa9744c787c5a732329 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 18:04:37 +0000 Subject: [PATCH 0398/1050] This patch implements user-defined character handling on ATI Korean VGA. Patch from Greatpsycho. --- src/vid_ati28800.c | 46 +++++++++++++++++++++++++++++-------------- src/vid_svga_render.c | 10 ++++++++-- src/video.c | 1 + src/video.h | 1 + 4 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 55f9c45..275432d 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -140,19 +140,31 @@ void ati28800k_out(uint16_t addr, uint8_t val, void *p) case 0x3DE: // pclog("ati28800k_out : set port 03DE to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); ati28800->in_get_korean_font_kind_set = 0; - switch (ati28800->port_03dd_val) + if(ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) { - case 0x10: - ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); - break; - case 8: - ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1: - ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; - if (val & 2) - ati28800->in_get_korean_font_kind_set = 1; - break; + if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20][ati28800->get_korean_font_index] = val; + ati28800->get_korean_font_index++; + ati28800->get_korean_font_index &= 0x1F; + } + else + { + switch (ati28800->port_03dd_val) + { + case 0x10: + ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); + break; + case 8: + ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; + if (val & 2) + ati28800->in_get_korean_font_kind_set = 1; + break; + default: + break; + } } break; default: @@ -232,8 +244,12 @@ uint8_t ati28800k_in(uint16_t addr, void *p) case 4: /* ROM font */ temp = fontdatksc5601[ati28800->get_korean_font_base][ati28800->get_korean_font_index++]; break; - case 2: /* User defined font - TODO : Should be implemented later */ - temp = 0; + case 2: /* User defined font */ + if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20][ati28800->get_korean_font_index]; + else + temp = 0xFF; + ati28800->get_korean_font_index++; break; default: break; @@ -411,7 +427,7 @@ void ati28800k_add_status_info(char *s, int max_len, void *p) ati28800_t *ati28800 = (ati28800_t *)p; char temps[128]; - svga_add_status_info(s, max_len, &ati28800->svga); + ati28800_add_status_info(s, max_len, p); sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); strncat(s, temps, max_len); diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 808540e..1deb874 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -200,7 +200,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) { - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; + if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc]; + else + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; } else { @@ -247,7 +250,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; + if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16]; + else + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) diff --git a/src/video.c b/src/video.c index a08c92e..ab0ff7f 100644 --- a/src/video.c +++ b/src/video.c @@ -746,6 +746,7 @@ uint8_t fontdatm[2048][16]; uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */ +uint8_t fontdatksc5601_user[192][32]; /* Korean KSC-5601 user defined font */ int xsize=1,ysize=1; diff --git a/src/video.h b/src/video.h index 71090e0..f8edf05 100644 --- a/src/video.h +++ b/src/video.h @@ -54,6 +54,7 @@ extern int changeframecount; extern uint8_t fontdat[2048][8]; extern uint8_t fontdatm[2048][16]; extern uint8_t fontdatksc5601[16384][32]; +extern uint8_t fontdatksc5601_user[192][32]; extern uint32_t *video_15to32, *video_16to32; From fc7ac479543b7cef3ec4cf1caf02e2055ef4c564 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 22:09:50 +0000 Subject: [PATCH 0399/1050] Various fixes to SDAC RAMDAC emulation. Fixes Paradise Bahamas 64 with Xfree86, UNIVBE RAMDAC detection, and probably others. --- src/vid_s3.c | 12 ++- src/vid_sdac_ramdac.c | 184 ++++++++++++++++++++++++------------------ src/vid_sdac_ramdac.h | 2 + 3 files changed, 118 insertions(+), 80 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 1b8a3cd..461facf 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -801,7 +801,12 @@ void s3_out(uint16_t addr, uint8_t val, void *p) if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) svga_out(addr, val, svga); else - sdac_ramdac_out(addr, val, &s3->ramdac, svga); + { + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + sdac_ramdac_out((addr & 3) | 4, val, &s3->ramdac, svga); + else + sdac_ramdac_out(addr & 3, val, &s3->ramdac, svga); + } return; case 0x3D4: @@ -938,7 +943,9 @@ uint8_t s3_in(uint16_t addr, void *p) // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) return svga_in(addr, svga); - return sdac_ramdac_in(addr, &s3->ramdac, svga); + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + return sdac_ramdac_in((addr & 3) | 4, &s3->ramdac, svga); + return sdac_ramdac_in(addr & 3, &s3->ramdac, svga); case 0x3d4: return svga->crtcreg; @@ -2291,6 +2298,7 @@ void *s3_bahamas64_init() s3->getclock = sdac_getclock; s3->getclock_p = &s3->ramdac; + sdac_init(&s3->ramdac); return s3; } diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index c02eed4..0c62f23 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -1,76 +1,108 @@ /*87C716 'SDAC' true colour RAMDAC emulation*/ -/*Misidentifies as AT&T 21C504*/ #include "ibm.h" #include "mem.h" #include "video.h" #include "vid_svga.h" #include "vid_sdac_ramdac.h" +static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) +{ + ramdac->command = val; +// pclog("RAMDAC command reg now %02X\n", val); + switch (val >> 4) + { + case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; + case 0x4: case 0xe: svga->bpp = 24; break; + case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; + case 0x7: svga->bpp = 32; break; + + case 0: case 1: default: svga->bpp = 8; break; + } +} + +static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) +{ + if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) + { + if (!ramdac->reg_ff) + ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; + else + ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); + } + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->windex++; +} + +static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) +{ + uint8_t temp; + + if (!ramdac->reg_ff) + temp = ramdac->regs[reg] & 0xff; + else + temp = ramdac->regs[reg] >> 8; + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->rindex++; + + return temp; +} + void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) { -// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2); +// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i %i %i\n",addr,val,ramdac->magic_count,CS,cpu_state.pc, ramdac->rs2, ramdac->rindex, ramdac->windex); switch (addr) - { - case 0x3C6: - if (val == 0xff) - { - ramdac->rs2 = 0; - ramdac->magic_count = 0; - break; - } - if (ramdac->magic_count < 4) break; + { + case 2: if (ramdac->magic_count == 4) - { - ramdac->command = val; -// pclog("RAMDAC command reg now %02X\n", val); - switch (val >> 4) - { - case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; - case 0x4: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; - } - } - //ramdac->magic_count = 0; + sdac_control_write(ramdac, svga, val); + ramdac->magic_count = 0; break; - case 0x3C7: + case 3: ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->rindex = val; break; - case 0x3C8: + case 0: ramdac->magic_count = 0; - if (ramdac->rs2) - ramdac->windex = val; break; - case 0x3C9: + case 1: ramdac->magic_count = 0; - if (ramdac->rs2) - { - if (!ramdac->reg_ff) ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 0xff00) | val; - else ramdac->regs[ramdac->windex & 0xff] = (ramdac->regs[ramdac->windex & 0xff] & 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; + + case 4: + ramdac->windex = val; + ramdac->reg_ff = 0; + break; + case 5: + sdac_reg_write(ramdac, ramdac->windex & 0xff, val); + break; + case 6: + sdac_control_write(ramdac, svga, val); + break; + case 7: + ramdac->rindex = val; + ramdac->reg_ff = 0; break; } - svga_out(addr, val, svga); + if (!(addr & 4)) + { + if (addr < 2) + svga_out(addr + 0x3c8, val, svga); + else + svga_out(addr + 0x3c4, val, svga); + } } uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) { uint8_t temp; -// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, ramdac->rs2); +// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i %i %i\n",addr,CS,cpu_state.pc, ramdac->rs2, ramdac->rindex, ramdac->windex); switch (addr) { - case 0x3C6: - ramdac->reg_ff = 0; + case 2: if (ramdac->magic_count < 5) - ramdac->magic_count++; + ramdac->magic_count++; if (ramdac->magic_count == 4) { temp = 0x70; /*SDAC ID*/ @@ -82,43 +114,33 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) ramdac->magic_count = 0; } return temp; - case 0x3C7: -// if (ramdac->magic_count < 4) -// { - ramdac->magic_count=0; -// break; -// } - if (ramdac->rs2) return ramdac->rindex; + case 3: + ramdac->magic_count=0; break; - case 0x3C8: -// if (ramdac->magic_count < 4) -// { - ramdac->magic_count=0; -// break; -// } - if (ramdac->rs2) return ramdac->windex; + case 0: + ramdac->magic_count=0; 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] & 0xff; - else temp = ramdac->regs[ramdac->rindex & 0xff] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - { - ramdac->rindex++; - ramdac->magic_count = 0; - } - return temp; - } + case 1: + ramdac->magic_count=0; break; + + case 4: + return ramdac->windex; + case 5: + return sdac_reg_read(ramdac, ramdac->rindex & 0xff); + case 6: + return ramdac->command; + case 7: + return ramdac->rindex; } - return svga_in(addr, svga); + if (!(addr & 4)) + { + if (addr < 2) + return svga_in(addr + 0x3c8, svga); + else + return svga_in(addr + 0x3c4, svga); + } + return 0xff; } float sdac_getclock(int clock, void *p) @@ -137,3 +159,9 @@ float sdac_getclock(int clock, void *p) // 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; } + +void sdac_init(sdac_ramdac_t *ramdac) +{ + ramdac->regs[0] = 0x6128; + ramdac->regs[1] = 0x623d; +} diff --git a/src/vid_sdac_ramdac.h b/src/vid_sdac_ramdac.h index 3029d12..cd1d6f7 100644 --- a/src/vid_sdac_ramdac.h +++ b/src/vid_sdac_ramdac.h @@ -8,6 +8,8 @@ typedef struct sdac_ramdac_t int rs2; } sdac_ramdac_t; +void sdac_init(sdac_ramdac_t *ramdac); + void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga); uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga); From 63b431cc9ebc7af5d632db54d36cea92df97fe0b Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 22:10:52 +0000 Subject: [PATCH 0400/1050] Fix S3 Vision864 & Trio cursor colours in XFree86. --- src/vid_s3.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 461facf..db851d5 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -136,6 +136,9 @@ typedef struct s3_t uint64_t status_time; uint8_t subsys_cntl, subsys_stat; + + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; } s3_t; #define INT_VSY (1 << 0) @@ -883,6 +886,37 @@ void s3_out(uint16_t addr, uint8_t val, void *p) if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) svga->hwcursor.x <<= 1; break; + + case 0x4a: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x4b: + switch (s3->hwc_col_stack_pos) + { + case 0: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; case 0x53: case 0x58: case 0x59: case 0x5a: @@ -959,6 +993,7 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x45: s3->hwc_col_stack_pos = 0; break; case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; @@ -2015,11 +2050,44 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat void s3_hwcursor_draw(svga_t *svga, int displine) { + s3_t *s3 = (s3_t *)svga->p; int x; uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - + uint32_t fg = 0, bg = 0; + + switch (svga->bpp) + { + case 15: + fg = video_15to32[s3->hwc_fg_col & 0xffff]; + bg = video_15to32[s3->hwc_bg_col & 0xffff]; + break; + + case 16: + fg = video_16to32[s3->hwc_fg_col & 0xffff]; + bg = video_16to32[s3->hwc_bg_col & 0xffff]; + break; + + case 24: case 32: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + default: + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + { + fg = svga->pallook[s3->hwc_fg_col & 0xff]; + bg = svga->pallook[s3->hwc_bg_col & 0xff]; + } + else + { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } + break; + } + if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -2033,7 +2101,7 @@ 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])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); From b164fe1e4f34f78969e6b193f593c021f10b8765 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Mar 2018 22:11:42 +0000 Subject: [PATCH 0401/1050] Add ATAPI Read Format Capacities command to Zip drive - fixes various Linuxes when Zip enabled. --- src/scsi_zip.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 18421c5..62a28cb 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -31,6 +31,8 @@ /*cmd[1] = mode cmd[6-x] = password*/ +#define ATAPI_READ_FORMAT_CAPACITIES 0x23 + enum { CMD_POS_IDLE = 0, @@ -1005,6 +1007,50 @@ static int scsi_zip_command(uint8_t *cdb, void *p) bus_state = BUS_CD | BUS_IO; break; + + case ATAPI_READ_FORMAT_CAPACITIES: + if (data->is_atapi) + { + len = cdb[8] | (cdb[7] << 8); + + /*List header*/ + scsi_add_data(0, data); + scsi_add_data(0, data); + scsi_add_data(0, data); + scsi_add_data(16, data); /*list length*/ + + /*Current/Maximum capacity header*/ + scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); + scsi_add_data( ZIP_SECTORS & 0xff, data); + if (data->disc_loaded) + scsi_add_data(2, data); /*Formatted media - current media capacity*/ + else + scsi_add_data(3, data); /*Maximum formattable capacity*/ + scsi_add_data(512 >> 16, data); + scsi_add_data(512 >> 8, data); + scsi_add_data(512 & 0xff, data); + + /*Formattable capacity descriptor*/ + scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); + scsi_add_data( ZIP_SECTORS & 0xff, data); + scsi_add_data(0, data); + scsi_add_data(512 >> 16, data); + scsi_add_data(512 >> 8, data); + scsi_add_data(512 & 0xff, data); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + } + else + { + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; default: fatal("Bad SCSI ZIP command %02x\n", cdb[0]); From 593c3f2b2f0abcd1317c974ae7392981251babda Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Mar 2018 21:51:06 +0000 Subject: [PATCH 0402/1050] Removed non-existent CRTC R50 handling from ViRGE. --- src/vid_s3_virge.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index cc7d9be..5a04671 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -119,8 +119,6 @@ typedef struct virge_t uint8_t bank; uint8_t ma_ext; - int width; - int bpp; uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; @@ -374,18 +372,6 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) s3_virge_update_irqs(virge); break; - case 0x50: - switch (svga->crtc[0x50] & 0xc1) - { - case 0x00: virge->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break; - case 0x01: virge->width = 1152; break; - case 0x40: virge->width = 640; break; - case 0x80: virge->width = 800; break; - case 0x81: virge->width = 1600; break; - case 0xc0: virge->width = 1280; break; - } - virge->bpp = (svga->crtc[0x50] >> 4) & 3; - break; case 0x69: virge->ma_ext = val & 0x1f; break; From a5bbd87a2db09fc63ada796b37729385ee35bf13 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Mar 2018 21:52:07 +0000 Subject: [PATCH 0403/1050] ViRGE 256kb wrapping is disabled when enhanced mappings are in use. Fixes ViRGE on XFree86. --- src/vid_s3_virge.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 5a04671..0980594 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -367,8 +367,6 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); break; case 0x32: - if ((svga->crtc[0x67] & 0xc) != 0xc) - svga->vram_display_mask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); s3_virge_update_irqs(virge); break; @@ -569,7 +567,7 @@ static void s3_virge_recalctimings(svga_t *svga) { svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ } - svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (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*/ From 977b798eda45284df7094b08829e1590ece21f04 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Mar 2018 21:53:04 +0000 Subject: [PATCH 0404/1050] Fixed ViRGE cursor colour handling. --- src/vid_s3_virge.c | 70 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 0980594..3e4838d 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -140,8 +140,8 @@ typedef struct virge_t event_t *wake_main_thread; event_t *not_full_event; - uint32_t hwcursor_col[2]; - int hwcursor_col_pos; + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; struct { @@ -410,16 +410,34 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) break; case 0x4a: - virge->hwcursor_col[1] = (virge->hwcursor_col[1] & ~(0xff << (virge->hwcursor_col_pos * 8))) | - (val << (virge->hwcursor_col_pos * 8)); - virge->hwcursor_col_pos++; - virge->hwcursor_col_pos &= 3; + switch (virge->hwc_col_stack_pos) + { + case 0: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; break; case 0x4b: - virge->hwcursor_col[0] = (virge->hwcursor_col[0] & ~(0xff << (virge->hwcursor_col_pos * 8))) | - (val << (virge->hwcursor_col_pos * 8)); - virge->hwcursor_col_pos++; - virge->hwcursor_col_pos &= 3; + switch (virge->hwc_col_stack_pos) + { + case 0: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; break; case 0x53: @@ -498,7 +516,7 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; case 0x35: ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); break; case 0x36: ret = (svga->crtc[0x36] & 0xfc) | 2; break; /*PCI bus*/ - case 0x45: virge->hwcursor_col_pos = 0; ret = svga->crtc[0x45]; break; + case 0x45: virge->hwc_col_stack_pos = 0; ret = svga->crtc[0x45]; break; case 0x51: ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); break; case 0x69: ret = virge->ma_ext; break; case 0x6a: ret = virge->bank; break; @@ -3359,8 +3377,32 @@ 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; + uint32_t fg, bg; -// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); +// pclog("HWcursor %i %i %08x %08x\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, virge->hwcursor_col[0],virge->hwcursor_col[1]); + switch (svga->bpp) + { + case 15: + fg = video_15to32[virge->hwc_fg_col & 0xffff]; + bg = video_15to32[virge->hwc_bg_col & 0xffff]; + break; + + case 16: + fg = video_16to32[virge->hwc_fg_col & 0xffff]; + bg = video_16to32[virge->hwc_bg_col & 0xffff]; + break; + + case 24: case 32: + fg = virge->hwc_fg_col; + bg = virge->hwc_bg_col; + break; + + default: + fg = svga->pallook[virge->hwc_fg_col & 0xff]; + bg = svga->pallook[virge->hwc_bg_col & 0xff]; + break; + } + for (x = 0; x < 64; x += 16) { dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; @@ -3373,7 +3415,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (dat[0] & 0x8000) - ((uint32_t *)buffer32->line[displine])[offset + 32] = virge->hwcursor_col[dat[1] >> 15]; + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; } offset++; @@ -3389,7 +3431,7 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = virge->hwcursor_col[dat[1] >> 15]; + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]); From cb4c92c0f28d73b4412854d3cd1f5b7ccf4a52c7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Mar 2018 21:53:33 +0000 Subject: [PATCH 0405/1050] Fixed ViRGE blitter memory masking when only 2MB video memory available. --- src/vid_s3_virge.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 3e4838d..7f2b72e 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -1826,20 +1826,20 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) switch (bpp) \ { \ case 0: /*8 bpp*/ \ - val = vram[addr & 0x3fffff]; \ + val = vram[addr & svga->vram_mask]; \ break; \ case 1: /*16 bpp*/ \ - val = *(uint16_t *)&vram[addr & 0x3fffff]; \ + val = *(uint16_t *)&vram[addr & svga->vram_mask]; \ break; \ case 2: /*24 bpp*/ \ - val = (*(uint32_t *)&vram[addr & 0x3fffff]) & 0xffffff; \ + val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \ break; \ } \ } while (0) -#define Z_READ(addr) *(uint16_t *)&vram[addr & 0x3fffff] +#define Z_READ(addr) *(uint16_t *)&vram[addr & svga->vram_mask] -#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & 0x3fffff] = val +#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & svga->vram_mask] = val #define CLIP(x, y) \ do \ @@ -1899,23 +1899,24 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) switch (bpp) \ { \ case 0: /*8 bpp*/ \ - vram[addr & 0x3fffff] = val; \ - virge->svga.changedvram[(addr & 0x3fffff) >> 12] = changeframecount; \ + vram[addr & svga->vram_mask] = val; \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ break; \ case 1: /*16 bpp*/ \ - *(uint16_t *)&vram[addr & 0x3fffff] = val; \ - virge->svga.changedvram[(addr & 0x3fffff) >> 12] = changeframecount; \ + *(uint16_t *)&vram[addr & svga->vram_mask] = val; \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ break; \ case 2: /*24 bpp*/ \ - *(uint32_t *)&vram[addr & 0x3fffff] = (val & 0xffffff) | \ - (vram[(addr + 3) & 0x3fffff] << 24); \ - virge->svga.changedvram[(addr & 0x3fffff) >> 12] = changeframecount; \ + *(uint32_t *)&vram[addr & svga->vram_mask] = (val & 0xffffff) | \ + (vram[(addr + 3) & svga->vram_mask] << 24); \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ break; \ } \ } while (0) static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { + svga_t *svga = &virge->svga; uint8_t *vram = virge->svga.vram; uint32_t mono_pattern[64]; int count_mask; @@ -2930,6 +2931,7 @@ static void dest_pixel_lit_texture_modulate(s3d_state_t *state) static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) { + svga_t *svga = &virge->svga; uint8_t *vram = virge->svga.vram; int x_dir = s3d_tri->tlr ? 1 : -1; @@ -3061,7 +3063,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 } } - virge->svga.changedvram[(dest_offset & 0x3fffff) >> 12] = changeframecount; + virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount; dest_addr = dest_offset + (x * (bpp + 1)); z_addr = z_offset + (x << 1); @@ -3095,11 +3097,11 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 /*Not implemented yet*/ break; case 1: /*16 bpp*/ - src_col = *(uint16_t *)&vram[dest_addr & 0x3fffff]; + src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask]; RGB15_TO_24(src_col, src_r, src_g, src_b); break; case 2: /*24 bpp*/ - src_col = (*(uint32_t *)&vram[dest_addr & 0x3fffff]) & 0xffffff; + src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff; RGB24_TO_24(src_col, src_r, src_g, src_b); break; } From 6412d01deb4b375ff5965e6f13dacb5928059919 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Mar 2018 15:29:10 +0000 Subject: [PATCH 0406/1050] Added level-sensitive IRQs on PIIX and SiS497. Fixes hanging audio with AudioPCI on Windows 2000. --- src/ibm.h | 1 + src/pic.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- src/pic.h | 1 + src/piix.c | 3 +++ src/sis496.c | 3 +++ 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 491116f..5fdb9f6 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -363,6 +363,7 @@ typedef struct PIC int icw; uint8_t vector; int read; + uint8_t level_sensitive; } PIC; PIC pic,pic2; diff --git a/src/pic.c b/src/pic.c index 26918f3..b1110a4 100644 --- a/src/pic.c +++ b/src/pic.c @@ -36,6 +36,8 @@ void pic_reset() pic.mask2=0; pic2.pend=pic2.ins=0; pic_intpending = 0; + pic.level_sensitive = 0; + pic2.level_sensitive = 0; } void pic_update_mask(uint8_t *mask, uint8_t ins) @@ -275,6 +277,41 @@ void pic2_init() io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL); } +static uint8_t pic_elcrx_read(uint16_t addr, void *p) +{ + uint8_t temp = 0xff; + + switch (addr) + { + case 0x4d0: + temp = pic.level_sensitive; + break; + case 0x4d1: + temp = pic2.level_sensitive; + break; + } + + return temp; +} + +static void pic_elcrx_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("pic_elcrx_write: addr=%04x val=%02x\n", addr, val); + switch (addr) + { + case 0x4d0: + pic.level_sensitive = val & 0xf8; + break; + case 0x4d1: + pic2.level_sensitive = val & 0xde; + break; + } +} + +void pic_init_elcrx() +{ + io_sethandler(0x04d0, 0x0002, pic_elcrx_read, NULL, NULL, pic_elcrx_write, NULL, NULL, NULL); +} void clearpic() { @@ -364,7 +401,8 @@ uint8_t picinterrupt() { if (temp & (1 << c)) { - pic.pend &= ~(1 << c); + if (!(pic.level_sensitive & (1 << c))) + pic.pend &= ~(1 << c); pic.ins |= (1 << c); pic_update_mask(&pic.mask2, pic.ins); @@ -385,11 +423,13 @@ uint8_t picinterrupt() { if (temp2 & (1 << c)) { - pic2.pend &= ~(1 << c); + if (!(pic2.level_sensitive & (1 << c))) + pic2.pend &= ~(1 << c); pic2.ins |= (1 << c); pic_update_mask(&pic2.mask2, pic2.ins); - pic.pend &= ~(1 << c); + if (!(pic2.level_sensitive & (1 << c))) + pic.pend &= ~(1 << c); pic.ins |= (1 << 2); /*Cascade IRQ*/ pic_update_mask(&pic.mask2, pic.ins); @@ -406,7 +446,8 @@ uint8_t picinterrupt() { if (temp & (1 << c)) { - pic.pend &= ~(1 << c); + if (!(pic.level_sensitive & (1 << c))) + pic.pend &= ~(1 << c); pic.ins |= (1 << c); pic_update_mask(&pic.mask2, pic.ins); pic_updatepending(); diff --git a/src/pic.h b/src/pic.h index e386313..1e129f3 100644 --- a/src/pic.h +++ b/src/pic.h @@ -1,5 +1,6 @@ void pic_init(); void pic2_init(); +void pic_init_elcrx(); void pic_reset(); void picint(uint16_t num); diff --git a/src/piix.c b/src/piix.c index b902419..342cce5 100644 --- a/src/piix.c +++ b/src/piix.c @@ -10,6 +10,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "pic.h" #include "piix.h" @@ -386,4 +387,6 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) ide_pri_disable(); ide_sec_disable(); + + pic_init_elcrx(); } diff --git a/src/sis496.c b/src/sis496.c index a5ec77f..b958feb 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -4,6 +4,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "pic.h" #include "sis496.h" @@ -137,6 +138,8 @@ void *sis496_init() pci_set_card_routing(13, PCI_INTD); pci_set_card_routing(11, PCI_INTC); + pic_init_elcrx(); + return sis496; } From 0209adc35ee1d5cbb72be506c76ee7b473495737 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Mar 2018 16:58:32 +0000 Subject: [PATCH 0407/1050] Improve Cyrix 6x86 AGI timing. --- src/codegen_timing_686.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/codegen_timing_686.c b/src/codegen_timing_686.c index 5bcd55e..a1dca43 100644 --- a/src/codegen_timing_686.c +++ b/src/codegen_timing_686.c @@ -56,6 +56,7 @@ static uint32_t prev_regmask; static uint64_t *prev_deps; static uint32_t prev_fetchdat; +static uint32_t last_regmask_modified; static uint32_t regmask_modified; static uint32_t opcode_timings[256] = @@ -773,7 +774,7 @@ static inline int COUNT(uint32_t c, int op_32) void codegen_timing_686_block_start() { prev_full = decode_delay = 0; - regmask_modified = 0; + regmask_modified = last_regmask_modified = 0; } void codegen_timing_686_start() @@ -798,7 +799,16 @@ static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_3 if (addr_regmask & IMPL_ESP) addr_regmask |= (1 << REG_ESP); - return regmask_modified & addr_regmask; + if (regmask_modified & addr_regmask) + { + regmask_modified = 0; + return 2; + } + + if (last_regmask_modified & addr_regmask) + return 1; + + return 0; } void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) @@ -940,8 +950,7 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if (regmask & IMPL_ESP) regmask |= SRCDEP_ESP | DSTDEP_ESP; - if (check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32)) - agi_stall = 2; + agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); /*Second instruction in the pair*/ if ((timings[opcode] & PAIR_MASK) == PAIR_NP) @@ -951,6 +960,7 @@ 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 + agi_stall; decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; prev_full = 0; + last_regmask_modified = regmask_modified; regmask_modified = prev_regmask; // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } @@ -962,6 +972,7 @@ 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 + agi_stall; decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; prev_full = 0; + last_regmask_modified = regmask_modified; regmask_modified = prev_regmask; // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } @@ -972,6 +983,7 @@ 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 + agi_stall; decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall; prev_full = 0; + last_regmask_modified = regmask_modified; regmask_modified = prev_regmask; // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } @@ -984,12 +996,12 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if (!t_pair) fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); - if (check_agi(deps, opcode, fetchdat, op_32)) - agi_stall = 2; + agi_stall = check_agi(deps, opcode, fetchdat, op_32); codegen_block_cycles += t_pair + agi_stall; decode_delay = (-t_pair) + 1 + agi_stall; + last_regmask_modified = regmask_modified; regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; prev_full = 0; // pclog("Pairable %i %i %i %02x %02x\n", t_pair, t1, t2, opcode, prev_opcode); @@ -1005,11 +1017,11 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) /*Instruction not pairable*/ int agi_stall = 0; - if (check_agi(deps, opcode, fetchdat, op_32)) - agi_stall = 2; + agi_stall = check_agi(deps, opcode, fetchdat, op_32); codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall; decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall; + last_regmask_modified = regmask_modified; regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); // pclog("Not pairable %i\n", COUNT(timings[opcode], op_32) + decode_delay); } From 1b7a821effa7e8b1cd085fc28357a6bc839b4256 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Mar 2018 16:58:45 +0000 Subject: [PATCH 0408/1050] Improve Cyrix 6x86 prefix timing. --- src/codegen_timing_686.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/codegen_timing_686.c b/src/codegen_timing_686.c index a1dca43..9559e03 100644 --- a/src/codegen_timing_686.c +++ b/src/codegen_timing_686.c @@ -785,6 +785,18 @@ void codegen_timing_686_start() void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) { + if ((prefix & 0xf8) == 0xd8) + { + last_prefix = prefix; + return; + } + if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) + { + /*0fh prefix is 'free' when used on conditional jumps*/ + last_prefix = prefix; + return; + } + /*6x86 can decode 1 prefix per instruction per clock with no penalty. If either instruction has more than one prefix then decode is delayed by one cycle for each additional prefix*/ @@ -938,7 +950,9 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) break; } } - + + /*One prefix per instruction is free*/ + decode_delay--; if (decode_delay < 0) decode_delay = 0; From 2505dee5e8d6eebf34fbce382b0a88359acfb052 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Mar 2018 16:59:00 +0000 Subject: [PATCH 0409/1050] Fix minor bug in Pentium prefix timing. --- src/codegen_timing_pentium.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index a142024..4194e3a 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -962,7 +962,7 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; return; } - if (prefix == 0x0f && (opcode & 0xf0) == 0x80) + if (prefix == 0x0f && (fetchdat & 0xf0) == 0x80) { /*On Pentium 0fh prefix is 'free' when used on conditional jumps*/ last_prefix = prefix; From e3052075a772514a83f2708f342797d0f08bd773 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Mar 2018 18:18:18 +0000 Subject: [PATCH 0410/1050] Fixed custom resolution setting sometimes being ignored. --- src/wx-sdl2-display-win.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index a4fdb28..9cc79e8 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -862,6 +862,7 @@ int render() if (win_doresize) { + int flags = SDL_GetWindowFlags(window); win_doresize = 0; if (!vid_resize || (flags&SDL_WINDOW_FULLSCREEN)) { SDL_GetWindowSize(window, &rect.w, &rect.h); From fb14e1881f0a1da9fe9396c26d9bcdf812994380 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Mar 2018 19:50:26 +0000 Subject: [PATCH 0411/1050] Moved post-rev1065 0x3da code to OTI-037C specific code. Restored pre-rev1065 generic SVGA 0x3da code. Fixes PS/2 VGA self test. --- src/vid_oti037.c | 39 +++++++++++++++++++++++++++++++++++++++ src/vid_svga.c | 32 -------------------------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/vid_oti037.c b/src/vid_oti037.c index 3843c1f..eb06416 100644 --- a/src/vid_oti037.c +++ b/src/vid_oti037.c @@ -109,6 +109,45 @@ uint8_t oti037_in(uint16_t addr, void *p) temp = svga->crtc[svga->crtcreg & 31]; break; + case 0x3DA: + svga->attrff = 0; + + /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again + and expects the diagnostic bits to equal the current border colour. As I understand + it, the 0x3da active enable status does not include the border time, so this may be + an area where OTI-037C is not entirely VGA compatible.*/ + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) + { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + return svga->cgastat; + + case 0x3DE: temp = oti037->index; break; diff --git a/src/vid_svga.c b/src/vid_svga.c index 1de0a20..d94606f 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -261,43 +261,11 @@ uint8_t svga_in(uint16_t addr, void *p) case 0x3DA: svga->attrff = 0; - /* old diagnostic code if (svga->cgastat & 0x01) svga->cgastat &= ~0x30; else svga->cgastat ^= 0x30; return svga->cgastat; - */ - svga->cgastat &= ~0x30; - /* copy color diagnostic info from the overscan color register */ - switch (svga->attrregs[0x12] & 0x30) - { - case 0x00: /* P0 and P2 */ - if (svga->attrregs[0x11] & 0x01) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x04) - svga->cgastat |= 0x20; - break; - case 0x10: /* P4 and P5 */ - if (svga->attrregs[0x11] & 0x10) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x20) - svga->cgastat |= 0x20; - break; - case 0x20: /* P1 and P3 */ - if (svga->attrregs[0x11] & 0x02) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x08) - svga->cgastat |= 0x20; - break; - case 0x30: /* P6 and P7 */ - if (svga->attrregs[0x11] & 0x40) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x80) - svga->cgastat |= 0x20; - break; - } - return svga->cgastat; } // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); return 0xFF; From ade27bf52608968a10f2a988e1934606e6218461 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 25 Mar 2018 18:03:05 +0100 Subject: [PATCH 0412/1050] Fix MMU accesses to remapped memory. Fixes OS/2 v2.0 on PS/2 Model 70, and possibly other machines. --- src/mem.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/mem.c b/src/mem.c index b4bbfd1..12f058b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1116,6 +1116,16 @@ int pctrans=0; extern uint32_t testr[9]; +static inline uint32_t mmu_readl(uint32_t addr) +{ + return *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff]; +} + +static inline void mmu_writel(uint32_t addr, uint32_t val) +{ + *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff] = val; +} + uint32_t mmutranslatereal(uint32_t addr, int rw) { uint32_t addr2; @@ -1131,7 +1141,7 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) 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]; + temp = temp2 = mmu_readl(addr2); // 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))) { @@ -1176,7 +1186,7 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) return (temp & ~0x3fffff) + (addr & 0x3fffff); } - temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; + temp = mmu_readl((temp & ~0xfff) + ((addr >> 10) & 0xffc)); 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 && !cpl_override) || cr0&WP_FLAG))) @@ -1203,8 +1213,8 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) return -1; } mmu_perm=temp&4; - ((uint32_t *)ram)[addr2>>2]|=0x20; - ((uint32_t *)ram)[((temp2&~0xFFF)+((addr>>10)&0xFFC))>>2]|=(rw?0x60:0x20); + mmu_writel(addr2, temp2 | 0x20); + mmu_writel((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), temp | (rw ? 0x60 : 0x20)); // /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),temp,cs,pc,EDI); return (temp&~0xFFF)+(addr&0xFFF); @@ -1219,7 +1229,7 @@ uint32_t mmutranslate_noabrt(uint32_t addr, int rw) return -1; addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp=temp2=((uint32_t *)ram)[addr2>>2]; + temp = temp2 = mmu_readl(addr2); if (!(temp&1)) return -1; @@ -1233,7 +1243,7 @@ uint32_t mmutranslate_noabrt(uint32_t addr, int rw) return (temp & ~0x3fffff) + (addr & 0x3fffff); } - temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; + temp = mmu_readl((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3=temp&temp2; if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) From 63e3913c3151648f1b248cbf76c7593d7150d5dd Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 25 Mar 2018 18:03:45 +0100 Subject: [PATCH 0413/1050] Implement IBM MCA ESDI controller command status properly. Fixes appalling I/O performance on OS/2 v2.0. --- src/hdd_esdi.c | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 0999ba4..23e1f75 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -115,6 +115,7 @@ typedef struct esdi_t #define CMD_GET_POS_INFO 0x0a #define STATUS_LEN(x) ((x) << 8) +#define STATUS_DEVICE(x) ((x) << 5) #define STATUS_DEVICE_HOST_ADAPTER (7 << 5) static inline void esdi_set_irq(esdi_t *esdi) @@ -182,6 +183,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p) esdi->cmd_dev = ATTN_HOST_ADAPTER; esdi->status |= STATUS_BUSY; esdi->cmd_pos = 0; + esdi->status_pos = 0; break; case ATTN_EOI: @@ -212,6 +214,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p) esdi->cmd_dev = ATTN_DEVICE_0; esdi->status |= STATUS_BUSY; esdi->cmd_pos = 0; + esdi->status_pos = 0; break; case ATTN_EOI: @@ -235,6 +238,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p) esdi->cmd_dev = ATTN_DEVICE_1; esdi->status |= STATUS_BUSY; esdi->cmd_pos = 0; + esdi->status_pos = 0; break; case ATTN_EOI: @@ -268,7 +272,7 @@ static uint16_t esdi_readw(uint16_t port, void *p) case 0x3510: /*Status Interface Register*/ if (esdi->status_pos >= esdi->status_len) return 0; - temp = esdi->status_data[esdi->status_pos++]; + temp = esdi->status_data[esdi->status_pos++]; if (esdi->status_pos >= esdi->status_len) { esdi->status &= ~STATUS_STATUS_OUT_FULL; @@ -375,6 +379,21 @@ static void rba_out_of_range(esdi_t *esdi) esdi_set_irq(esdi); } +static void complete_command_status(esdi_t *esdi) +{ + esdi->status_len = 7; + if (esdi->cmd_dev == ATTN_DEVICE_0) + esdi->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); + else + esdi->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); + esdi->status_data[1] = 0x0000; /*Error bits*/ + esdi->status_data[2] = 0x1900; /*Device status*/ + esdi->status_data[3] = 0; /*Number of blocks left to do*/ + esdi->status_data[4] = (esdi->rba-1) & 0xffff; /*Last RBA processed*/ + esdi->status_data[5] = (esdi->rba-1) >> 8; + esdi->status_data[6] = 0; /*Number of blocks requiring error recovery*/ +} + #define ESDI_ADAPTER_ONLY() do \ { \ if (esdi->cmd_dev != ATTN_HOST_ADAPTER) \ @@ -492,7 +511,9 @@ static void esdi_callback(void *p) case 2: // pclog("Read sector complete\n"); - esdi->status = STATUS_IRQ; + complete_command_status(esdi); + + 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); @@ -575,7 +596,9 @@ static void esdi_callback(void *p) case 2: // pclog("Write sector complete\n"); - esdi->status = STATUS_IRQ; + complete_command_status(esdi); + + 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); @@ -597,8 +620,9 @@ static void esdi_callback(void *p) rba_out_of_range(esdi); return; } - - esdi->status = STATUS_IRQ; + esdi->rba += esdi->sector_count; + complete_command_status(esdi); + 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); @@ -613,7 +637,8 @@ static void esdi_callback(void *p) return; } - esdi->status = STATUS_IRQ; + complete_command_status(esdi); + 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); @@ -628,8 +653,6 @@ static void esdi_callback(void *p) 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); @@ -659,8 +682,6 @@ static void esdi_callback(void *p) 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); @@ -685,8 +706,7 @@ static void esdi_callback(void *p) 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); @@ -832,8 +852,7 @@ static void esdi_callback(void *p) 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); From a4b8eba56bc3422b2cda2117364a3f6329c30332 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Mar 2018 20:33:18 +0100 Subject: [PATCH 0414/1050] Add better rounded value for FLDLN2. Fixes rendering in Zone Raiders. --- src/codegen_ops_fpu.h | 9 ++++++++- src/x87_ops.h | 15 +++++++++++++++ src/x87_ops_misc.h | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/codegen_ops_fpu.h b/src/codegen_ops_fpu.h index de7cf4c..5065094 100644 --- a/src/codegen_ops_fpu.h +++ b/src/codegen_ops_fpu.h @@ -634,5 +634,12 @@ opFLDimm(L2T, 3.3219280948873623) opFLDimm(L2E, 1.4426950408889634); opFLDimm(PI, 3.141592653589793); opFLDimm(EG2, 0.3010299956639812); -opFLDimm(LN2, 0.693147180559945); opFLDimm(Z, 0.0) + +static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); + + return op_pc; +} diff --git a/src/x87_ops.h b/src/x87_ops.h index 1bb5fd5..dc15866 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -43,6 +43,21 @@ static inline void x87_push(double i) cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; } +static inline void x87_push_u64(uint64_t i) +{ + union + { + double d; + uint64_t ll; + } td; + + td.ll = i; + + cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.ST[cpu_state.TOP] = td.d; + cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; +} + static inline double x87_pop() { double t = cpu_state.ST[cpu_state.TOP]; diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 806c4a6..4305487 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -460,7 +460,7 @@ static int opFLDLN2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; if (fplog) pclog("FLDLN2\n"); - x87_push(0.693147180559945); + x87_push_u64(0x3fe62e42fefa39f0ull); CLOCK_CYCLES(8); return 0; } From 51874cf2a803c2f4f09b03420e4264f6d663a107 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Mar 2018 21:10:08 +0100 Subject: [PATCH 0415/1050] Tweaked AudioPCI resampling filter gain to reduce clipping. --- src/sound_audiopci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index bb2cd73..61e1b33 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -1189,6 +1189,8 @@ static void generate_es1371_filter() for (n = 0; n < ES1371_NCoef; n++) gain += low_fir_es1371_coef[n] / (float)N; + gain /= 0.95; + /*Normalise filter, to produce unity gain*/ for (n = 0; n < ES1371_NCoef; n++) low_fir_es1371_coef[n] /= gain; From cb60383e551ab2e0ff629287d2978ba6c7f42b92 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 2 Apr 2018 21:07:57 +0100 Subject: [PATCH 0416/1050] Update NE2000 IRQ status on writes to IMR. Fixes problems with RTL8029 when level-sensitive IRQs are in use. --- src/ne2000.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/ne2000.c b/src/ne2000.c index aa59b90..e0ce985 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -1154,13 +1154,24 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - if (ne2000->ISR.pkt_tx && ne2000->IMR.tx_inte) - { -#ifdef NE2000_DEBUG - pclog("tx irq retrigger\n"); -#endif + 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) ne2000_raise_irq(ne2000); - } + else + ne2000_lower_irq(ne2000); break; } break; From 9f8eed95c20c7ad49b466afc1b86cdbae5dd946a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Apr 2018 21:24:04 +0100 Subject: [PATCH 0417/1050] Implement read & write masks on S3 blitter. Fixes text rendering on OS/2 and XFree86 with S3 cards. --- src/vid_s3.c | 77 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index db851d5..dc5ae35 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1433,28 +1433,37 @@ uint8_t s3_accel_read(uint32_t addr, void *p) return 0; } -#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; +#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ + else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \ + dat &= s3->accel.rd_mask; -#define MIX switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = ~0; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ +#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ + else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; + +#define MIX { \ + uint32_t old_dest_dat = dest_dat; \ + switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ + { \ + case 0x0: dest_dat = ~dest_dat; break; \ + case 0x1: dest_dat = 0; break; \ + case 0x2: dest_dat = ~0; break; \ + case 0x3: dest_dat = dest_dat; break; \ + case 0x4: dest_dat = ~src_dat; break; \ + case 0x5: dest_dat = src_dat ^ dest_dat; break; \ + case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ + case 0x7: dest_dat = src_dat; break; \ + case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ + case 0x9: dest_dat = ~src_dat | dest_dat; break; \ + case 0xa: dest_dat = src_dat | ~dest_dat; break; \ + case 0xb: dest_dat = src_dat | dest_dat; break; \ + case 0xc: dest_dat = src_dat & dest_dat; break; \ + case 0xd: dest_dat = src_dat & ~dest_dat; break; \ + case 0xe: dest_dat = ~src_dat & dest_dat; break; \ + case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ + } \ + dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ } @@ -1560,7 +1569,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX @@ -1610,7 +1619,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + READ_DST((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); @@ -1708,7 +1717,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3->accel.dest + s3->accel.cx, dest_dat); + READ_DST(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); @@ -1793,9 +1802,10 @@ 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_SRC(s3->accel.src + s3->accel.cx, src_dat); + READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); + + dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); WRITE(s3->accel.dest + s3->accel.dx); } @@ -1835,7 +1845,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) + READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) + mix_dat = mix_dat ? mix_mask : 0; } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) @@ -1843,14 +1854,14 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 0: src_dat = s3->accel.bkgd_color; break; case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + s3->accel.cx, src_dat); break; + case 3: READ_SRC(s3->accel.src + s3->accel.cx, src_dat); break; } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3->accel.dest + s3->accel.dx, dest_dat); + READ_DST(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); @@ -1966,7 +1977,7 @@ 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) + READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) mix_dat = mix_dat ? mix_mask : 0; } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) @@ -1974,14 +1985,14 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 0: src_dat = s3->accel.bkgd_color; break; case 1: src_dat = s3->accel.frgd_color; break; case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + s3->accel.cx, src_dat); break; + case 3: READ_SRC(s3->accel.src + s3->accel.cx, src_dat); break; } if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3->accel.dest + s3->accel.dx, dest_dat); + READ_DST(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); From b840d79691c4e0d269f3c872b50a6524a6280c84 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Apr 2018 21:25:00 +0100 Subject: [PATCH 0418/1050] Force S3 blitter busy bit to be high for a while after the start of a command, to compensate for timing variations between main and blitter threads. Fixes S3 blitter lockups on OS/2. --- src/vid_s3.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index dc5ae35..1e2744b 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -139,6 +139,8 @@ typedef struct s3_t uint32_t hwc_fg_col, hwc_bg_col; int hwc_col_stack_pos; + + volatile int force_busy; } s3_t; #define INT_VSY (1 << 0) @@ -1282,10 +1284,11 @@ uint8_t s3_accel_in(uint16_t port, void *p) if (!s3->blitter_busy) wake_fifo_thread(s3); temp = 0; - if (!FIFO_EMPTY) + if (!FIFO_EMPTY || s3->force_busy) temp |= 0x02; /*Hardware busy*/ else temp |= 0x04; /*FIFO empty*/ + s3->force_busy = 0; if (FIFO_FULL) temp |= 0xf8; /*FIFO full*/ return temp; @@ -1498,6 +1501,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint32_t *vram_l = (uint32_t *)svga->vram; uint32_t compare = s3->accel.color_cmp; int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; + + s3->force_busy = 1; //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); From 8186a884d79b9c396945ec9c6a8b4333f1590701 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Apr 2018 21:25:47 +0100 Subject: [PATCH 0419/1050] S3 BitBlt commands don't update current X/Y registers at the end of a blit. Fixes some S3 graphics issues in OS/2. --- src/vid_s3.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 1e2744b..0950e3c 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1833,11 +1833,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.sy--; if (s3->accel.sy < 0) - { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; return; - } } } } @@ -1926,11 +1922,7 @@ 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; - } } } } From 8ce9832c168e5c5b675599247fe9a605c473d6d9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 5 Apr 2018 20:54:50 +0100 Subject: [PATCH 0420/1050] Tweaked SB DSP write data ready timing. Fixes SB16 detection on Windows 98. --- src/sound_sb_dsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index fb4c153..0300c24 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -734,11 +734,11 @@ uint8_t sb_read(uint16_t a, void *priv) // pclog("SB read %02X\n",sbreaddat); return dsp->sbreaddat; case 0xC: /*Write data ready*/ - if (dsp->sb_8_enable || dsp->sb_type >= SB16 ) - dsp->busy_count = (dsp->busy_count + 1) & 15; + if (dsp->sb_8_enable || dsp->sb_type >= SB16) + dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; - if (dsp->wb_full || (dsp->busy_count & 8)) + if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = dsp->wb_time; return 0xff; From edea3bf26a4b6c5887411ce6b5c63019f16d192a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Apr 2018 14:03:15 +0100 Subject: [PATCH 0421/1050] Fixed data padding on ZIP drive SCSI/ATAPI commands. Fixes NT4 with ATAPI ZIP. --- src/scsi_zip.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 62a28cb..38067d7 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -327,7 +327,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) makes disc health read as 'marginal'*/ for (c = 2; c < 0x58; c++) add_data_len(0xff); - for (; i < len; i++) + while (i < len) add_data_len(0); data->cmd_pos = CMD_POS_IDLE; bus_state = BUS_IO; @@ -345,7 +345,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) add_data_len(0); for (c = 0; c < 39; c++) add_data_len(0); - for (; i < len; i++) + while (i < len) add_data_len(0); data->cmd_pos = CMD_POS_IDLE; bus_state = BUS_IO; @@ -565,7 +565,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) } else { - len = cdb[8] | (cdb[9] << 8); + len = cdb[8] | (cdb[7] << 8); add_data_len(0); add_data_len(0); @@ -638,7 +638,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) add_data_len(0x0f); } - for (; i < len; i++) + while (i < len) add_data_len(0); len = data->data_pos_write; From e411652b2788ef27b7b4b3d7721f32fecf530776 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Apr 2018 14:03:34 +0100 Subject: [PATCH 0422/1050] Don't kill the emulator on an unknown ZIP drive SCSI/ATAPI command. --- src/scsi_zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 38067d7..91956e2 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -1053,7 +1053,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) break; default: - fatal("Bad SCSI ZIP command %02x\n", cdb[0]); + pclog("Bad SCSI ZIP command %02x\n", cdb[0]); scsi_zip_illegal(data); bus_state = BUS_CD | BUS_IO; break; From 1ff836bfc10d684efe88fa2a510739deb773c0a7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Apr 2018 07:56:12 +0100 Subject: [PATCH 0423/1050] Shortened time between ATAPI packet command starting and requesting command data. Fixes CD-ROM on BeOS. --- src/ide.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ide.c b/src/ide.c index 09933f4..5d1a29b 100644 --- a/src/ide.c +++ b/src/ide.c @@ -598,7 +598,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide->atastat = BUSY_STAT; timer_process(); - idecallback[ide_board]=200*IDE_TIME; + idecallback[ide_board] = IDE_TIME; timer_update_outstanding(); ide->atapi.bus_state = 0; From 82ad52674514891f5a3b880e3d6846e1676e7a15 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Apr 2018 07:56:48 +0100 Subject: [PATCH 0424/1050] PIIX zero length transfer represents 64 kbytes. Fixes CD-ROM on BeOS. --- src/piix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/piix.c b/src/piix.c index 342cce5..d8a2a18 100644 --- a/src/piix.c +++ b/src/piix.c @@ -154,6 +154,8 @@ static void piix_bus_master_next_addr(int channel) { piix_busmaster[channel].addr = (*(uint32_t *)(&ram[piix_busmaster[channel].ptr_cur])) & ~1; piix_busmaster[channel].count = (*(uint32_t *)(&ram[piix_busmaster[channel].ptr_cur + 4])) & 0xfffe; + if (!piix_busmaster[channel].count) + piix_busmaster[channel].count = 0x10000; 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); From 7ffb01996248199b64911c9f25c5dc92001c6f09 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Apr 2018 12:42:22 +0100 Subject: [PATCH 0425/1050] CL-GD54xx now defaults to 8 bpp correctly when enhanced RAMDAC modes not set. --- src/vid_cl5429.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index c361f20..f2e5b05 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -499,14 +499,12 @@ void gd5429_recalctimings(svga_t *svga) svga->interlace = svga->crtc[0x1a] & 1; if (svga->seqregs[7] & 0x01) - { svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - } svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); // pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); + svga->bpp = 8; if (gd5429->hidden_dac_reg & 0x80) { if (gd5429->hidden_dac_reg & 0x40) From 031f64c1a37440ba75553397bd616910be0750ef Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Apr 2018 17:16:04 +0100 Subject: [PATCH 0426/1050] Invalid CPUID instructions should return zero in EBX/ECX/EDX. Fixes CPU type test and subsequent invalid 3DNow! instruction execution in NFL Blitz 2000. --- src/cpu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 1e62d9b..d380c6b 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1239,7 +1239,7 @@ void cpu_CPUID() EDX = CPUID_FPU; /*FPU*/ } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; case CPU_iDX4: @@ -1257,7 +1257,7 @@ void cpu_CPUID() EDX = CPUID_FPU | CPUID_VME; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; case CPU_Am486SX: @@ -1274,7 +1274,7 @@ void cpu_CPUID() EBX = ECX = EDX = 0; /*No FPU*/ } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; case CPU_Am486DX: @@ -1292,7 +1292,7 @@ void cpu_CPUID() EDX = CPUID_FPU; /*FPU*/ } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; case CPU_WINCHIP: @@ -1323,7 +1323,7 @@ void cpu_CPUID() EDX |= CPUID_MMX; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; case CPU_PENTIUM: @@ -1341,7 +1341,7 @@ void cpu_CPUID() EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; case CPU_PENTIUMMMX: @@ -1359,7 +1359,7 @@ void cpu_CPUID() EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; @@ -1378,7 +1378,7 @@ void cpu_CPUID() EDX = CPUID_FPU; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; @@ -1397,7 +1397,7 @@ void cpu_CPUID() EDX = CPUID_FPU | CPUID_CMPXCHG8B; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; @@ -1416,7 +1416,7 @@ void cpu_CPUID() EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; @@ -1436,7 +1436,7 @@ void cpu_CPUID() EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; } else - EAX = 0; + EAX = EBX = ECX = EDX = 0; break; } From 25ac99a6efc727abcbf9242a7df3d1e5111902ae Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Apr 2018 21:38:48 +0100 Subject: [PATCH 0427/1050] Clamp CD-ROM command data to the allocation length. Fixes some emulator deaths when DMA enabled. --- src/scsi_cd.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 215e5e7..c6bd0aa 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -796,7 +796,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) // len = 8; data->data_pos_read = 0; - data->bytes_expected = data->data_pos_write = alloc_length; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, 8); return SCSI_PHASE_DATA_IN; case GPCMD_READ_TOC_PMA_ATIP: @@ -804,24 +804,22 @@ static int scsi_cd_command(uint8_t *cdb, void *p) toc_format = cdb[2] & 0xf; if (toc_format == 0) toc_format = (cdb[9] >> 6) & 3; + alloc_length = cdb[8] + (cdb[7] << 8); switch (toc_format) { case 0: /*Normal*/ // pclog("ATAPI: READ TOC type requested: Normal\n"); - len = cdb[8] + (cdb[7] << 8); - len = atapi->readtoc(data->data_in, cdb[6], msf, len, 0); + len = atapi->readtoc(data->data_in, cdb[6], msf, alloc_length, 0); break; case 1: /*Multi session*/ // pclog("ATAPI: READ TOC type requested: Multi-session\n"); - len = cdb[8] + (cdb[7] << 8); - len = atapi->readtoc_session(data->data_in, msf, len); + len = atapi->readtoc_session(data->data_in, msf, alloc_length); data->data_in[0] = 0; data->data_in[1] = 0xA; break; case 2: /*Raw*/ // pclog("ATAPI: READ TOC type requested: Raw TOC\n"); - len = cdb[8] + (cdb[7] << 8); - len = atapi->readtoc_raw(data->data_in, len); + len = atapi->readtoc_raw(data->data_in, alloc_length); break; default: atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); @@ -829,7 +827,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; } data->data_pos_read = 0; - data->bytes_expected = data->data_pos_write = len; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); return SCSI_PHASE_DATA_IN; case GPCMD_READ_CD: @@ -1023,6 +1021,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_DATA_IN; case GPCMD_READ_HEADER: + alloc_length = cdb[8] | (cdb[7] << 8); if (msf) { atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); @@ -1033,7 +1032,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[0] = 1; /*2048 bytes user data*/ data->data_in[1] = data->data_in[2] = data->data_in[3] = 0; - data->bytes_expected = data->data_pos_write = 6; + data->bytes_expected = data->data_pos_write = MIN(6, alloc_length); return SCSI_PHASE_DATA_IN; case GPCMD_MODE_SENSE_6: @@ -1070,7 +1069,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[2] = 3; /*120mm data CD-ROM*/ } - data->bytes_expected = data->data_pos_write = len; + data->bytes_expected = data->data_pos_write = MIN(len, alloc_length); data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_DATA_IN; @@ -1176,11 +1175,13 @@ static int scsi_cd_command(uint8_t *cdb, void *p) gesn_event_header->len = used_len - sizeof(*gesn_event_header); } - data->bytes_expected = data->data_pos_write = len; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_DATA_IN; case GPCMD_READ_DISC_INFORMATION: + alloc_length = cdb[8] | (cdb[7] << 8); + data->data_in[1] = 32; data->data_in[2] = 0xe; /* last session complete, disc finalized */ data->data_in[3] = 1; /* first track on disc */ @@ -1190,7 +1191,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[7] = 0x20; /* unrestricted use */ data->data_in[8] = 0x00; /* CD-ROM */ - data->bytes_expected = data->data_pos_write = 34; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, 34); data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_DATA_IN; @@ -1228,6 +1229,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_STATUS; case GPCMD_READ_SUBCHANNEL: + alloc_length = cdb[8] | (cdb[7] << 8); if (cdb[3] != 1) { atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); @@ -1243,7 +1245,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) len = 11+5; if (!(cdb[2] & 0x40)) len=4; - data->bytes_expected = data->data_pos_write = len; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); return SCSI_PHASE_DATA_IN; case GPCMD_START_STOP_UNIT: From 38fa1cbfd12f79c83012c5aa5fa42b89b5cf6e66 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 10 Apr 2018 16:20:17 +0100 Subject: [PATCH 0428/1050] Trio64 maps 32-bits to colour & mask registers even when 32-bit registers are disabled. Fixes bad colours in OS/2 Warp in 32-bit colour mode. --- src/vid_s3.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/vid_s3.c b/src/vid_s3.c index 0950e3c..57480db 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -276,10 +276,25 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa2ea: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } break; case 0xa2eb: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xa6e8: @@ -299,10 +314,25 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa6ea: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } break; case 0xa6eb: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xaae8: @@ -322,10 +352,25 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xaaea: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } break; case 0xaaeb: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xaee8: @@ -345,10 +390,25 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xaeea: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } break; case 0xaeeb: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xb2e8: @@ -368,10 +428,25 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb2ea: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } break; case 0xb2eb: if (s3->accel.multifunc[0xe] & 0x200) s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) + { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } break; case 0xb6e8: From 138430ad8f75b6763c5addb2d544446d0b7965c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 10 Apr 2018 16:20:48 +0100 Subject: [PATCH 0429/1050] Fixes to Trio64 read mask handling. Fixes some graphics issues in OS/2 Warp. --- src/vid_s3.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 57480db..70b10cd 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1514,7 +1514,8 @@ uint8_t s3_accel_read(uint32_t addr, void *p) #define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \ - dat &= s3->accel.rd_mask; + if (vram_mask) \ + dat = ((dat & rd_mask) == rd_mask); #define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ @@ -1576,6 +1577,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint32_t *vram_l = (uint32_t *)svga->vram; uint32_t compare = s3->accel.color_cmp; int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; + uint32_t rd_mask = s3->accel.rd_mask; s3->force_busy = 1; //return; @@ -1602,6 +1604,11 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->bpp == 1) count >>= 1; if (s3->bpp == 3) count >>= 2; } + + if (s3->bpp == 0) + rd_mask &= 0xff; + else if (s3->bpp == 1) + rd_mask &= 0xffff; switch (s3->accel.cmd & 0x600) { From 4263bc8227807ef0405b37c9b414f8c68fdefa6c Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 10 Apr 2018 17:21:18 +0100 Subject: [PATCH 0430/1050] Added monitor type configuration to Plantronics Colorplus. Plantronics now doesn't inherit settings from the last emulated CGA system. --- src/vid_colorplus.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/vid_colorplus.c b/src/vid_colorplus.c index acb10cb..6a28a23 100644 --- a/src/vid_colorplus.c +++ b/src/vid_colorplus.c @@ -336,15 +336,21 @@ void colorplus_poll(void *p) void *colorplus_init() { + int display_type, contrast; colorplus_t *colorplus = malloc(sizeof(colorplus_t)); memset(colorplus, 0, sizeof(colorplus_t)); colorplus->cga.vram = malloc(0x8000); colorplus->cga.composite = colorplus->cga.snow_enabled = 0; + + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); 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); + + cgapal_rebuild(display_type, contrast); return colorplus; } @@ -364,6 +370,51 @@ void colorplus_speed_changed(void *p) cga_recalctimings(&colorplus->cga); } +device_config_t colorplus_config[] = +{ + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "RGB", + .value = DISPLAY_RGB + }, + { + .description = "RGB (no brown)", + .value = DISPLAY_RGB_NO_BROWN + }, + { + .description = "Green Monochrome", + .value = DISPLAY_GREEN + }, + { + .description = "Amber Monochrome", + .value = DISPLAY_AMBER + }, + { + .description = "White Monochrome", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + }, + .default_int = DISPLAY_RGB + }, + { + .name = "contrast", + .description = "Alternate monochrome contrast", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .type = -1 + } +}; + device_t colorplus_device = { "Colorplus", @@ -374,5 +425,5 @@ device_t colorplus_device = colorplus_speed_changed, NULL, NULL, - NULL + colorplus_config }; From 0fe9b999532e12935cba1af9509fc36a46fb1c9c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Apr 2018 15:22:35 +0100 Subject: [PATCH 0431/1050] SB16/AWE32 support SB2/Pro style high speed DMA commands, contrary to Creative Labs documentation. Fixes sound in Earthworm Jim. --- src/sound_sb_dsp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 0300c24..e17d1f1 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -499,19 +499,19 @@ void sb_exec_command(sb_dsp_t *dsp) timer_update_outstanding(); break; case 0x90: /*High speed 8-bit autoinit DMA output*/ - if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; + if (dsp->sb_type < SB2) break; sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x91: /*High speed 8-bit single cycle DMA output*/ - if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; + if (dsp->sb_type < SB2) break; sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0x98: /*High speed 8-bit autoinit DMA input*/ - if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; + if (dsp->sb_type < SB2) break; sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x99: /*High speed 8-bit single cycle DMA input*/ - if (dsp->sb_type < SB2 || dsp->sb_type > SBPRO2) break; + if (dsp->sb_type < SB2) break; sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0xA0: /*Set input mode to mono*/ From d6b74b945baa52f7b77cda0d1b6a96d4b5ac5b75 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Apr 2018 15:25:30 +0100 Subject: [PATCH 0432/1050] Clear _mem_exec array when clearing out old memory mappings. Patch from Greatpsycho. --- src/mem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mem.c b/src/mem.c index 12f058b..c9e2983 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2076,6 +2076,7 @@ static void mem_mapping_recalc(uint64_t base, uint64_t size) _mem_read_l[c >> 14] = NULL; _mem_priv_r[c >> 14] = NULL; _mem_mapping_r[c >> 14] = NULL; + _mem_exec[c >> 14] = NULL; _mem_write_b[c >> 14] = NULL; _mem_write_w[c >> 14] = NULL; _mem_write_l[c >> 14] = NULL; From 4ba11c5a1355b29479d8b38953fd1c5ea949fc1c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Apr 2018 17:00:58 +0100 Subject: [PATCH 0433/1050] Always decode CRTC index bit 5 on VGA compatibles. Fixes Joe Montana Football. --- src/vid_oti067.c | 9 +++++++-- src/vid_paradise.c | 9 +++++---- src/vid_ps1_svga.c | 9 +++++++-- src/vid_vga.c | 9 +++++++-- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 7ae5a8d..1b7c20d 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -38,9 +38,11 @@ void oti067_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3D4: - svga->crtcreg = val & 31; + svga->crtcreg = val & 0x3f; return; case 0x3D5: + if (svga->crtcreg & 0x20) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -99,7 +101,10 @@ uint8_t oti067_in(uint16_t addr, void *p) temp = svga->crtcreg; break; case 0x3D5: - temp = svga->crtc[svga->crtcreg]; + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; break; case 0x3DE: diff --git a/src/vid_paradise.c b/src/vid_paradise.c index b42482d..3aabd3a 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -110,12 +110,11 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) break; case 0x3D4: - if (paradise->type == PVGA1A) - svga->crtcreg = val & 0x1f; - else - svga->crtcreg = val & 0x3f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -191,6 +190,8 @@ uint8_t paradise_in(uint16_t addr, void *p) case 0x3D4: return svga->crtcreg; case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return 0xff; if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) return 0xff; return svga->crtc[svga->crtcreg]; diff --git a/src/vid_ps1_svga.c b/src/vid_ps1_svga.c index 731bd94..8c8564f 100644 --- a/src/vid_ps1_svga.c +++ b/src/vid_ps1_svga.c @@ -42,9 +42,11 @@ void ps1_m2121_svga_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3D4: - svga->crtcreg = val & 0x1f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: + if (svga->crtcreg & 0x20) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -104,7 +106,10 @@ uint8_t ps1_m2121_svga_in(uint16_t addr, void *p) temp = svga->crtcreg; break; case 0x3D5: - temp = svga->crtc[svga->crtcreg]; + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; break; case 0x2108: diff --git a/src/vid_vga.c b/src/vid_vga.c index 40472f7..241166f 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -30,9 +30,11 @@ void vga_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3D4: - svga->crtcreg = val & 0x1f; + svga->crtcreg = val & 0x3f; return; case 0x3D5: + if (svga->crtcreg & 0x20) + return; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -69,7 +71,10 @@ uint8_t vga_in(uint16_t addr, void *p) temp = svga->crtcreg; break; case 0x3D5: - temp = svga->crtc[svga->crtcreg]; + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; break; default: temp = svga_in(addr, svga); From bd06b5a1cca16765f4f032cc6b008fecb2ef6900 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Apr 2018 17:37:41 +0100 Subject: [PATCH 0434/1050] Add segment limit checking to opcode F6 (16-bit version) as temporary workaround for hang when opening Windows 9x DOS box on Diamond Stealth 32. --- src/x86_ops_misc.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index c8d31f5..4949b27 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -52,6 +52,10 @@ static int opF6_a16(uint32_t fetchdat) int8_t temps; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + { + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + } dst = geteab(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) { From 8300b3a7e2ed266cffd1ceac6381132e8030744d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Apr 2018 20:16:08 +0100 Subject: [PATCH 0435/1050] Speed up AT keyboard controller. Fixes OS/2 v1.x PS/2 mouse driver on PS/2 systems. --- src/keyboard_at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 9b9104c..17d9af5 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -65,7 +65,7 @@ int mouse_queue_start = 0, mouse_queue_end = 0; void keyboard_at_poll() { - keybsenddelay += (1000 * TIMER_USEC); + keybsenddelay += (100 * TIMER_USEC); if (keyboard_at.out_new != -1 && !keyboard_at.last_irq) { From 4cea5cc59fff0098bc12247e6e4cb13d33641ee5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Apr 2018 21:26:45 +0100 Subject: [PATCH 0436/1050] Implemented Trio64 polygon fill commands. Fixes issues with Paintbrush on Windows 3.1. --- src/ibm.h | 7 ++ src/scsi_cd.c | 2 - src/vid_s3.c | 313 ++++++++++++++++++++++++++++++++++++++++++++--- src/vid_voodoo.c | 5 - 4 files changed, 306 insertions(+), 21 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 5fdb9f6..549acc2 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -1,6 +1,13 @@ #include #include #include + +#ifdef ABS +#undef ABS +#endif + +#define ABS(x) ((x) > 0 ? (x) : -(x)) + #define printf pclog #define READFLASH_FDC 0 diff --git a/src/scsi_cd.c b/src/scsi_cd.c index c6bd0aa..5c534d1 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -10,8 +10,6 @@ #include "timer.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define ABS(x) ((x) > 0 ? (x) : -(x)) - #define BUFFER_SIZE (256*1024) diff --git a/src/vid_s3.c b/src/vid_s3.c index 70b10cd..762e88a 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -95,12 +95,13 @@ typedef struct s3_t uint8_t subsys_cntl; uint8_t setup_md; uint8_t advfunc_cntl; - uint16_t cur_y; - uint16_t cur_x; - int16_t desty_axstp; + uint16_t cur_y, cur_y2; + uint16_t cur_x, cur_x2; + uint16_t x2; + int16_t desty_axstp, desty_axstp2; int16_t destx_distp; - int16_t err_term; - int16_t maj_axis_pcnt; + int16_t err_term, err_term2; + int16_t maj_axis_pcnt, maj_axis_pcnt2; uint16_t cmd; uint16_t short_stroke; uint32_t bkgd_color; @@ -119,6 +120,12 @@ typedef struct s3_t int dx, dy; uint32_t src, dest, pattern; int pix_trans_count; + + int poly_cx, poly_cx2; + int poly_cy, poly_cy2; + int point_1_updated, point_2_updated; + int poly_dx1, poly_dx2; + int poly_x; uint32_t dat_buf; int dat_count; @@ -194,34 +201,78 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { case 0x82e8: s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; + s3->accel.poly_cy = s3->accel.cur_y; break; case 0x82e9: s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cy = s3->accel.cur_y; + break; + case 0x82ea: + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; + s3->accel.poly_cy2 = s3->accel.cur_y2; + break; + case 0x82eb: + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cy2 = s3->accel.cur_y2; break; case 0x86e8: s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; + s3->accel.poly_cx = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x86e9: s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + break; + case 0x86ea: + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; + s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; + break; + case 0x86eb: + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; break; case 0x8ae8: s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; + s3->accel.point_1_updated = 1; break; case 0x8ae9: s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3->accel.desty_axstp |= ~0x3fff; + s3->accel.desty_axstp |= ~0x3fff; + s3->accel.point_1_updated = 1; + break; + case 0x8aea: + s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; + s3->accel.point_2_updated = 1; + break; + case 0x8aeb: + s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.desty_axstp2 |= ~0x3fff; + s3->accel.point_2_updated = 1; break; case 0x8ee8: s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; + s3->accel.point_1_updated = 1; break; case 0x8ee9: s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) - s3->accel.destx_distp |= ~0x3fff; + s3->accel.destx_distp |= ~0x3fff; + s3->accel.point_1_updated = 1; + break; + case 0x8eea: + s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; + s3->accel.point_2_updated = 1; + break; + case 0x8eeb: + s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0xf) << 8); + s3->accel.point_2_updated = 1; break; case 0x92e8: @@ -232,6 +283,14 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (val & 0x20) s3->accel.err_term |= ~0x3fff; break; + case 0x92ea: + s3->accel.err_term2 = (s3->accel.err_term2 & 0x3f00) | val; + break; + case 0x92eb: + s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.err_term2 |= ~0x3fff; + break; case 0x96e8: s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0x3f00) | val; @@ -241,6 +300,14 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (val & 0x08) s3->accel.maj_axis_pcnt |= ~0x0fff; break; + case 0x96ea: + s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xf00) | val; + break; + case 0x96eb: + s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); + if (val & 0x08) + s3->accel.maj_axis_pcnt2 |= ~0x0fff; + break; case 0x9ae8: s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; @@ -1511,6 +1578,47 @@ uint8_t s3_accel_read(uint32_t addr, void *p) return 0; } +static void polygon_setup(s3_t *s3) +{ + if (s3->accel.point_1_updated) + { + int start_x = s3->accel.poly_cx; + int start_y = s3->accel.poly_cy; + int end_x = s3->accel.destx_distp << 20; + int end_y = s3->accel.desty_axstp; + + if (end_y - start_y) + s3->accel.poly_dx1 = (end_x - start_x) / (end_y - start_y); + else + s3->accel.poly_dx1 = 0; + + s3->accel.point_1_updated = 0; + + if (end_y == s3->accel.poly_cy) + { + s3->accel.poly_cx = end_x; + s3->accel.poly_x = end_x >> 20; + } + } + if (s3->accel.point_2_updated) + { + int start_x = s3->accel.poly_cx2; + int start_y = s3->accel.poly_cy2; + int end_x = s3->accel.x2 << 20; + int end_y = s3->accel.desty_axstp2; + + if (end_y - start_y) + s3->accel.poly_dx2 = (end_x - start_x) / (end_y - start_y); + else + s3->accel.poly_dx2 = 0; + + s3->accel.point_2_updated = 0; + + if (end_y == s3->accel.poly_cy) + s3->accel.poly_cx2 = end_x; + } +} + #define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \ @@ -1578,6 +1686,10 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint32_t compare = s3->accel.color_cmp; int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; uint32_t rd_mask = s3->accel.rd_mask; + int cmd = s3->accel.cmd >> 13; + + if ((s3->chip == S3_TRIO64) && (s3->accel.cmd & (1 << 11))) + cmd |= 8; s3->force_busy = 1; //return; @@ -1620,7 +1732,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->bpp == 0) compare &= 0xff; if (s3->bpp == 1) compare &= 0xffff; - switch (s3->accel.cmd >> 13) + switch (cmd) { case 1: /*Draw line*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ @@ -2135,6 +2247,167 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } break; + + case 3: /*Polygon Fill Solid (Trio64 only)*/ + { + int end_y1, end_y2; + + if (s3->chip != S3_TRIO64) + break; + + polygon_setup(s3); + + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + + end_y1 = s3->accel.desty_axstp; + end_y2 = s3->accel.desty_axstp2; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + + + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) + { + int y = s3->accel.poly_cy; + int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; + + s3->accel.dest = y * s3->width; + + while (x_count-- && count--) + { + if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && + s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) + { + switch (frgd_mix) + { + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; + case 2: src_dat = cpu_dat; break; + case 3: src_dat = 0; /*Nor supported?*/ break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || + compare_mode < 2) + { + READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); + + MIX + + WRITE(s3->accel.dest + s3->accel.poly_x); + } + } + if (s3->bpp == 0) cpu_dat >>= 8; + else cpu_dat >>= 16; + + if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) + s3->accel.poly_x++; + else + s3->accel.poly_x--; + } + + s3->accel.poly_cx += s3->accel.poly_dx1; + s3->accel.poly_cx2 += s3->accel.poly_dx2; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + + s3->accel.poly_cy++; + s3->accel.poly_cy2++; + + if (!count) + break; + } + + s3->accel.cur_x = s3->accel.poly_cx & 0xfff; + s3->accel.cur_y = s3->accel.poly_cy & 0xfff; + s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + } + break; + + case 11: /*Polygon Fill Pattern (Trio64 only)*/ + { + int end_y1, end_y2; + + if (s3->chip != S3_TRIO64) + break; + + polygon_setup(s3); + + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + + end_y1 = s3->accel.desty_axstp; + end_y2 = s3->accel.desty_axstp2; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) + { + int y = s3->accel.poly_cy; + int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; + + s3->accel.src = s3->accel.pattern + ((y & 7) * s3->width); + s3->accel.dest = y * s3->width; + + while (x_count-- && count--) + { + int pat_x = s3->accel.poly_x & 7; + + if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && + s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) + { + if (vram_mask) + { + READ_SRC(s3->accel.src + pat_x, mix_dat) + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) + { + case 0: src_dat = s3->accel.bkgd_color; break; + case 1: src_dat = s3->accel.frgd_color; break; + case 2: src_dat = cpu_dat; break; + case 3: READ_SRC(s3->accel.src + pat_x, src_dat); break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || + compare_mode < 2) + { + READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); + + MIX + + WRITE(s3->accel.dest + s3->accel.poly_x); + } + } + if (s3->bpp == 0) cpu_dat >>= 8; + else cpu_dat >>= 16; + + mix_dat <<= 1; + mix_dat |= 1; + + if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) + s3->accel.poly_x++; + else + s3->accel.poly_x--; + } + + s3->accel.poly_cx += s3->accel.poly_dx1; + s3->accel.poly_cx2 += s3->accel.poly_dx2; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + + s3->accel.poly_cy++; + s3->accel.poly_cy2++; + + if (!count) + break; + } + + s3->accel.cur_x = s3->accel.poly_cx & 0xfff; + s3->accel.cur_y = s3->accel.poly_cy & 0xfff; + s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + } + break; } } @@ -2243,12 +2516,24 @@ static void s3_io_set(s3_t *s3) io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip == S3_TRIO64) + { + io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } + else + { + io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 30fb18d..fdbe914 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -15,9 +15,6 @@ #ifdef MIN #undef MIN #endif -#ifdef ABS -#undef ABS -#endif #ifdef CLAMP #undef CLAMP #endif @@ -3962,8 +3959,6 @@ enum case 0xf: dst_dat = 0xffff; break; \ } -#define ABS(x) ((x) > 0 ? (x) : -(x)) - static void blit_start(voodoo_t *voodoo) { uint64_t dat64; From 9dc02e718543e2ef547b4c5e6be30419299f88f0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Apr 2018 21:31:01 +0100 Subject: [PATCH 0437/1050] Implemented Trio32-only host data mode. Fixes text in Windows 3.1. --- src/vid_s3.c | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 762e88a..723cb47 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -557,7 +557,14 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe2eb: s3->accel.pix_trans[3] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x600 && (s3->accel.cmd & 0x100) && s3->chip == S3_TRIO32) + { + s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + } + else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x400) == 0x400 && (s3->accel.cmd & 0x100)) s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); else if ((s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); @@ -574,6 +581,11 @@ static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) + { + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } if ((s3->accel.cmd & 0x600) == 0x000) s3_accel_start(8, 1, val | (val << 16), 0, s3); else @@ -596,7 +608,16 @@ 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 & 0x400) + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } + else if (s3->accel.cmd & 0x400) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); @@ -757,7 +778,12 @@ static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x000) + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) + { + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } + else if ((s3->accel.cmd & 0x600) == 0x000) s3_accel_start(8, 1, val | (val << 16), 0, s3); else s3_accel_start(16, 1, val | (val << 16), 0, s3); @@ -789,7 +815,16 @@ static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3->accel.cmd & 0x400) + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } + else if (s3->accel.cmd & 0x400) { if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); @@ -1727,7 +1762,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 0x000: mix_mask = 0x80; break; case 0x200: mix_mask = 0x8000; break; case 0x400: mix_mask = 0x80000000; break; - case 0x600: mix_mask = 0x80000000; break; + case 0x600: mix_mask = (s3->chip == S3_TRIO32) ? 0x80 : 0x80000000; break; } if (s3->bpp == 0) compare &= 0xff; From 20e255ceb7d9808677fb844eff80b76425e1288e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Apr 2018 21:16:33 +0100 Subject: [PATCH 0438/1050] Don't process Sound Blaster 16-bit transfers when DMA disabled. Fixes Visual Player 2.0. --- src/sound_sb_dsp.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index e17d1f1..df6954a 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -340,7 +340,7 @@ void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val) fwrite(&val,1,1,soundf); #endif } -uint16_t sb_16_read_dma(sb_dsp_t *dsp) +int sb_16_read_dma(sb_dsp_t *dsp) { return dma_channel_read(dsp->sb_16_dmanum); } @@ -977,26 +977,42 @@ void pollsb(void *p) } if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && dsp->sb_16_output) { + int data[2]; + sb_dsp_update(dsp); switch (dsp->sb_16_format) { case 0x00: /*Mono unsigned*/ - dsp->sbdatl = dsp->sbdatr = sb_16_read_dma(dsp) ^ 0x8000; + data[0] = sb_16_read_dma(dsp); + if (data[0] == DMA_NODATA) + break; + dsp->sbdatl = dsp->sbdatr = data[0] ^ 0x8000; dsp->sb_16_length--; break; case 0x10: /*Mono signed*/ - dsp->sbdatl = dsp->sbdatr = sb_16_read_dma(dsp); + data[0] = sb_16_read_dma(dsp); + if (data[0] == DMA_NODATA) + break; + dsp->sbdatl = dsp->sbdatr = data[0]; dsp->sb_16_length--; break; case 0x20: /*Stereo unsigned*/ - dsp->sbdatl = sb_16_read_dma(dsp) ^ 0x8000; - dsp->sbdatr = sb_16_read_dma(dsp) ^ 0x8000; + data[0] = sb_16_read_dma(dsp); + data[1] = sb_16_read_dma(dsp); + if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) + break; + dsp->sbdatl = data[0] ^ 0x8000; + dsp->sbdatr = data[1] ^ 0x8000; dsp->sb_16_length -= 2; break; case 0x30: /*Stereo signed*/ - dsp->sbdatl = sb_16_read_dma(dsp); - dsp->sbdatr = sb_16_read_dma(dsp); + data[0] = sb_16_read_dma(dsp); + data[1] = sb_16_read_dma(dsp); + if (data[0] == DMA_NODATA || data[1] == DMA_NODATA) + break; + dsp->sbdatl = data[0]; + dsp->sbdatr = data[1]; dsp->sb_16_length -= 2; break; // default: From 37c8a16478c25675e0dd644fd3ea3fab37c8322c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Apr 2018 20:37:08 +0100 Subject: [PATCH 0439/1050] Reset AHA-1542/BusLogic mailbox pointers on mailbox initialisation command. Fixes Solaris 2.4 with AHA-1542. --- src/scsi_aha1540.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index 1d980b5..1557760 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -746,6 +746,8 @@ static void process_cmd(aha154x_t *scsi) scsi->mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); scsi->mba_i = scsi->mba + scsi->mbc*4; scsi->mb_format = MB_FORMAT_4; + scsi->current_mbo = 0; + scsi->current_mbi = 0; pclog("Mailbox init: MBC=%02x MBC=%06x\n", scsi->mbc, scsi->mba); scsi->status &= ~STATUS_INIT; set_irq(scsi, ISR_HACC); @@ -1292,6 +1294,8 @@ static void process_cmd(aha154x_t *scsi) scsi->mba = scsi->params[1] | (scsi->params[2] << 8) | (scsi->params[3] << 16) | (scsi->params[4] << 24); scsi->mba_i = scsi->mba + scsi->mbc*8; scsi->mb_format = MB_FORMAT_8; + scsi->current_mbo = 0; + scsi->current_mbi = 0; pclog("Mailbox init: MBC=%02x MBC=%08x\n", scsi->mbc, scsi->mba); scsi->status &= ~STATUS_INIT; set_irq(scsi, ISR_HACC); From 3feeea3bbea21d1f4fd3a7883c0e9c031090e5bf Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Apr 2018 20:37:55 +0100 Subject: [PATCH 0440/1050] All bits of BusLogic ISR register are read/write. Fixes BusLogic detection on Solaris 2.4. --- src/scsi_aha1540.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index 1557760..37c09f5 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -275,7 +275,7 @@ static void process_cmd(aha154x_t *scsi); static void set_irq(aha154x_t *scsi, uint8_t val) { picint(1 << scsi->irq); - scsi->isr |= val; + scsi->isr |= val | ISR_ANYINTR; } static void clear_irq(aha154x_t *scsi) @@ -348,6 +348,11 @@ static void aha154x_out(uint16_t port, uint8_t val, void *p) // pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc); process_cmd(scsi); break; + + case 2: + if (scsi->type == SCSI_BT545S) + scsi->isr = val; + break; } } @@ -374,9 +379,10 @@ static uint8_t aha154x_in(uint16_t port, void *p) break; case 2: /*Interrupt status register*/ - temp = scsi->isr & ~0x70; - if (scsi->isr) - temp |= ISR_ANYINTR; + if (scsi->type == SCSI_BT545S) + temp = scsi->isr; + else + temp = scsi->isr & ~0x70; break; case 3: /*???*/ From 5bfd5aa82301de710e8b10ebd0687156e1fa6500 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Apr 2018 20:38:39 +0100 Subject: [PATCH 0441/1050] Write SCSI status to AHA-1542C/BusLogic CCB and BusLogic malibox following command completion. Fixes Windows 2000 with BusLogic. --- src/scsi_aha1540.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index 37c09f5..9174ffc 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -1619,7 +1619,8 @@ static void process_ccb(aha154x_t *scsi) // pclog("Residue=%08x %x %x %i MBI=%i\n", residue, scsi->ccb.total_data_len, scsi->ccb.bytes_transferred, scsi->ccb.residual, scsi->current_mbi); mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); - + mem_writeb_phys(scsi->ccb.addr + 0xf, scsi->ccb.status); + if (scsi->mb_format == MB_FORMAT_4) { if (scsi->ccb.residual) @@ -1665,7 +1666,7 @@ static void process_ccb(aha154x_t *scsi) if (scsi->ccb.status == STATUS_GOOD) mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE << 24); else - mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE_WITH_ERROR << 24); + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, (MBI_CCB_COMPLETE_WITH_ERROR << 24) | (scsi->ccb.status << 8)); } if (!scsi->current_mbo_is_bios) @@ -1713,6 +1714,7 @@ static void process_ccb(aha154x_t *scsi) uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; // pclog("residue=%x %x %x\n", residue, scsi->ccb.total_data_len, scsi->ccb.bytes_transferred); mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); + mem_writeb_phys(scsi->ccb.addr + 0xf, scsi->ccb.status); if (scsi->mb_format == MB_FORMAT_4) { @@ -1760,7 +1762,7 @@ static void process_ccb(aha154x_t *scsi) if (scsi->ccb.status == STATUS_GOOD) mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE << 24); else - mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, MBI_CCB_COMPLETE_WITH_ERROR << 24); + mem_writel_phys(scsi->mba_i + scsi->current_mbi*8 + 4, (MBI_CCB_COMPLETE_WITH_ERROR << 24) | (scsi->ccb.status << 8)); } if (!scsi->current_mbo_is_bios) From 796f401b710d648968c401703f832dc5cd8129b0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Apr 2018 20:39:26 +0100 Subject: [PATCH 0442/1050] SCSI CD-ROM should not fail on START_STOP_UNIT command with Start set and LoEj clear. Fixes Solaris 4.2 with AHA-1542C. --- src/scsi_cd.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 5c534d1..de2363e 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -1247,14 +1247,9 @@ static int scsi_cd_command(uint8_t *cdb, void *p) return SCSI_PHASE_DATA_IN; case GPCMD_START_STOP_UNIT: - if (cdb[4] != 2 && cdb[4] != 3 && cdb[4]) - { - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); - return SCSI_PHASE_STATUS; - } if (!cdb[4]) atapi->stop(); else if (cdb[4] == 2) atapi->eject(); - else atapi->load(); + else if (cdb[4] == 3) atapi->load(); data->cmd_pos = CMD_POS_IDLE; return SCSI_PHASE_STATUS; From 1107fc4f28746936dc096ae68fbc355dc2675a61 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 16 Apr 2018 17:29:42 +0100 Subject: [PATCH 0443/1050] Force full display redraw on window resize and enter/leave fullscreen. --- src/wx-sdl2-display-win.c | 6 ++++++ src/wx-sdl2-display.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 9cc79e8..43f16ec 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -707,6 +707,8 @@ int render() if (vid_resize == 2) SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); + + device_force_redraw(); } if (renderer_doreset) { @@ -740,6 +742,8 @@ int render() case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_CLOSE) wx_stop_emulation(window_ptr); + if (event.window.event == SDL_WINDOWEVENT_RESIZED) + device_force_redraw(); if (window_remember) { @@ -831,6 +835,7 @@ int render() remembered_rect.y -= border_y; SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + device_force_redraw(); } if (window_doinputgrab) { window_doinputgrab = 0; @@ -858,6 +863,7 @@ int render() SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); + device_force_redraw(); } if (win_doresize) diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index 5796bf1..18bbc9e 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -443,6 +443,8 @@ int render() #endif if (vid_resize == 2) SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); + + device_force_redraw(); } if (window_doreset) { @@ -486,6 +488,8 @@ int render() case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_CLOSE) wx_stop_emulation(ghwnd); + if (event.window.event == SDL_WINDOWEVENT_RESIZED) + device_force_redraw(); if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { if (is_fullscreen()) @@ -605,6 +609,7 @@ int render() remembered_rect.y -= border_y; SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + device_force_redraw(); } if (window_doinputgrab) { window_doinputgrab = 0; @@ -629,6 +634,7 @@ int render() #if SDL_VERSION_ATLEAST(2, 0, 4) SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); #endif + device_force_redraw(); } if (win_doresize) From 7644c771dea6d63b5d4854744dc7211c98a36bdc Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 17 Apr 2018 17:17:39 +0100 Subject: [PATCH 0444/1050] Voodoo 2D blitter now marks destination areas as dirty when writing to the front buffer. Fixes FMV in Urban Chaos. --- src/vid_voodoo.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index fdbe914..e40cfa1 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -4129,15 +4129,29 @@ static void blit_data(voodoo_t *voodoo, uint32_t data) { int src_bits = 32; uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); + uint32_t addr; uint16_t *dst; if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) return; if (SLI_ENABLED) - dst = (uint16_t *)&voodoo->fb_mem[base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride]; + { + addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; + dst = (uint16_t *)&voodoo->fb_mem[addr]; + } else - dst = (uint16_t *)&voodoo->fb_mem[base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride]; + { + addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride; + dst = (uint16_t *)&voodoo->fb_mem[addr]; + } + + if (addr >= voodoo->front_offset && voodoo->row_width) + { + int y = (addr - voodoo->front_offset) / voodoo->row_width; + if (y < voodoo->v_disp) + voodoo->dirty_line[y] = 2; + } while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) { From 51db026b90e2d760dab60b4eb8c71c6f6fb42b0c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Apr 2018 16:05:01 +0100 Subject: [PATCH 0445/1050] SB 2.0 mirrors the OPL2 at ports 2x0/2x1 when CMS/Gameblaster chips are not present. Fixes music in Syndicate. --- src/sound_sb.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sound_sb.c b/src/sound_sb.c index 2095c39..0fb5d48 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -1013,6 +1013,12 @@ void *sb_2_init() "CD version" also uses 250h or 260h for 2x0 to 2x3 -> CDROM interface 2x4 to 2x5 -> Mixer interface*/ + /*My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is + disabled when the CMS chips are present. + This mirror may also exist on SB 1.5 & MCV, however I am unable to + test this. It shouldn't exist on SB 1.0 as the CMS chips are always + present there. + Syndicate requires this mirror for music to play.*/ sb_t *sb = malloc(sizeof(sb_t)); uint16_t addr = device_get_config_int("addr"); memset(sb, 0, sizeof(sb_t)); @@ -1025,6 +1031,8 @@ void *sb_2_init() sb_ct1335_mixer_reset(sb); /* CMS I/O handler is activated on the dedicated sound_cms module DSP I/O handler is activated in sb_dsp_setaddr */ + if (!GAMEBLASTER) + io_sethandler(addr, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 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); From de3379a19f1df64e458fbf72e7e180fcf0f1c15e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Apr 2018 20:59:01 +0100 Subject: [PATCH 0446/1050] Tweaked XT keyboard code a bit. Fixes Keyboard Error reported by AMI XT clone. --- src/keyboard_xt.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index aaabda0..a36e707 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "device.h" +#include "fdd.h" #include "io.h" #include "mem.h" #include "pic.h" @@ -31,6 +32,8 @@ struct uint8_t pa; uint8_t pb; + int shift_full; + int tandy; int pb2_turbo; } keyboard_xt; @@ -41,14 +44,17 @@ static int key_queue_start = 0, key_queue_end = 0; void keyboard_xt_poll() { keybsenddelay += (1000 * TIMER_USEC); + if (!(keyboard_xt.pb & 0x40) && romset != ROM_TANDY) + return; if (keyboard_xt.wantirq) { keyboard_xt.wantirq = 0; keyboard_xt.pa = keyboard_xt.key_waiting; + keyboard_xt.shift_full = 1; picint(2); pclog("keyboard_xt : take IRQ\n"); } - if (key_queue_start != key_queue_end && !keyboard_xt.pa) + if (key_queue_start != key_queue_end && !keyboard_xt.shift_full) { keyboard_xt.key_waiting = key_queue[key_queue_start]; pclog("Reading %02X from the key queue at %i\n", keyboard_xt.key_waiting, key_queue_start); @@ -109,6 +115,9 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) if (!(keyboard_xt.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/ { pclog("keyboard_xt : reset keyboard\n"); + key_queue_start = key_queue_end = 0; + keyboard_xt.wantirq = 0; + keyboard_xt.shift_full = 0; keyboard_xt_adddata(0xaa); } keyboard_xt.pb = val; @@ -130,6 +139,7 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) if (val & 0x80) { keyboard_xt.pa = 0; + keyboard_xt.shift_full = 0; picintc(2); } break; @@ -159,16 +169,6 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) else { temp = keyboard_xt.pa; - if (key_queue_start == key_queue_end) - { - keyboard_xt.wantirq = 0; - } - else - { - keyboard_xt.key_waiting = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_xt.wantirq = 1; - } } break; From 0b964d51c1070cf06178f07b33705e1fd3d3ff19 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Apr 2018 20:59:18 +0100 Subject: [PATCH 0447/1050] Mark Epson PC AX2e as having PS/2 mouse. Fixes 8602 error. --- src/model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index b8960f7..2e7726a 100644 --- a/src/model.c +++ b/src/model.c @@ -147,7 +147,7 @@ MODEL models[] = {"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 256,15872, 128, ibm_at_init, NULL}, {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 640,16384, 128, dells200_init, NULL}, {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, - {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, + {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 256,15872, 128, at_init, NULL}, {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 128, at_scat_init, NULL}, {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 512,16384, 512, ps1_m2011_init, NULL}, From e4ddbd8441cf86bbe7aec628ab98114ea00ac52e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Apr 2018 21:10:01 +0100 Subject: [PATCH 0448/1050] Remove waitstates from PIT register accesses. Fixes speed issues with Desert Strike. --- src/pit.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pit.c b/src/pit.c index eb0f828..dd27729 100644 --- a/src/pit.c +++ b/src/pit.c @@ -332,7 +332,6 @@ 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) @@ -457,7 +456,6 @@ uint8_t pit_read(uint16_t addr, void *p) PIT *pit = (PIT *)p; int t; uint8_t temp = 0xff; - cycles -= (int)PITCONST; // printf("Read PIT %04X ",addr); switch (addr&3) { From 3d388564c105041ecb798eb4076eef8f1488a943 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Apr 2018 22:00:09 +0100 Subject: [PATCH 0449/1050] Clear carry flag on DIV/IDIV on non-Cyrix processors. Fixes CPU type detection on Elonex PC-425X. --- src/x86_ops_misc.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index 4949b27..d8b4ccb 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -106,6 +106,7 @@ static int opF6_a16(uint32_t fetchdat) { flags_rebuild(); flags |= 0x8D5; /*Not a Cyrix*/ + flags &= ~1; } } else @@ -128,6 +129,7 @@ static int opF6_a16(uint32_t fetchdat) { flags_rebuild(); flags|=0x8D5; /*Not a Cyrix*/ + flags &= ~1; } } else @@ -204,6 +206,7 @@ static int opF6_a32(uint32_t fetchdat) { flags_rebuild(); flags |= 0x8D5; /*Not a Cyrix*/ + flags &= ~1; } } else @@ -226,6 +229,7 @@ static int opF6_a32(uint32_t fetchdat) { flags_rebuild(); flags|=0x8D5; /*Not a Cyrix*/ + flags &= ~1; } } else From 056eefb196cb5e6965fc53e8d64f1129c86abf22 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Apr 2018 22:00:33 +0100 Subject: [PATCH 0450/1050] Reset internal cache status correctly on soft CPU reset. Fixes CPU speed detection on Elonex PC-425X. --- src/808x.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/808x.c b/src/808x.c index e93e5f2..e50a13c 100644 --- a/src/808x.c +++ b/src/808x.c @@ -679,7 +679,12 @@ void softresetx86() // i86_Reset(); // cs=0xFFFF0; msw=0; - cr0=0; + if (is486) + cr0 = 1 << 30; + else + cr0 = 0; + cpu_cache_int_enabled = 0; + cpu_update_waitstates(); cr4 = 0; eflags=0; cgate32=0; From 1a28e657b51c8d765593bf9f5c2b85a64f7af82a Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Apr 2018 22:01:01 +0100 Subject: [PATCH 0451/1050] NCR PC4i shipped with 256kb RAM as minimum. --- src/model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index 2e7726a..369d207 100644 --- a/src/model.c +++ b/src/model.c @@ -121,7 +121,7 @@ MODEL models[] = {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 64, pcjr_init, &pcjr_device}, {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, - {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 256, 640, 64, xt_init, NULL}, {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, europc_init, NULL}, {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 128, tandy1k_init, &tandy1000_device}, From d4f56b1f27b379ebabde87d9cbc493e606659ae3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Apr 2018 22:01:27 +0100 Subject: [PATCH 0452/1050] Correct names of Toshiba laptops. --- src/model.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/model.c b/src/model.c index 369d207..5dfde71 100644 --- a/src/model.c +++ b/src/model.c @@ -127,7 +127,7 @@ MODEL models[] = {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 128, tandy1k_init, &tandy1000_device}, {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}, - {"[8088] Toshiba 1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, &t1000_device}, + {"[8088] Toshiba T1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, &t1000_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}, {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}, @@ -138,7 +138,7 @@ MODEL models[] = {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}, - {"[8088] Toshiba 1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, &t1000_device}, + {"[8088] Toshiba T1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, &t1000_device}, {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 1152, 128, xt_laserxt_init, NULL}, {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, @@ -156,7 +156,7 @@ MODEL models[] = {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL}, {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, - {"[286] Toshiba 3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}, + {"[286] Toshiba T3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}, {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, From a33f719808523747354dab2f1a9af7c06fbcc54c Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Apr 2018 22:05:02 +0100 Subject: [PATCH 0453/1050] Fix up ROM presence detection on Elonex PC-425X and Packard Bell PB520R and PB570. --- src/mem.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mem.c b/src/mem.c index c9e2983..739d16d 100644 --- a/src/mem.c +++ b/src/mem.c @@ -836,6 +836,8 @@ int loadbios() f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); if (!f) { + if (!rom_present("elx_pc425x/elx_pc425x_vbios.bin")) + break; f = romfopen("elx_pc425x/elx_pc425x_bios.bin", "rb"); if (!f) break; @@ -847,7 +849,7 @@ int loadbios() return 1; case ROM_PB570: - if (!rom_present("gd5430/pci.bin")) + if (!rom_present("pb570/gd5430.bin")) break; f = romfopen("pb570/1007by0r.bio", "rb"); if (!f) break; @@ -878,6 +880,8 @@ int loadbios() return 1; case ROM_PB520R: + if (!rom_present("pb520r/gd5434.bin")) + break; f = romfopen("pb520r/1009bc0r.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); From 270b6d733abaf8a66f3a1d2ebc8d6dc1c2dd42b7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Apr 2018 22:12:21 +0100 Subject: [PATCH 0454/1050] Updates to readme.txt --- readme.txt | 271 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 232 insertions(+), 39 deletions(-) diff --git a/readme.txt b/readme.txt index 31441bd..7be2872 100644 --- a/readme.txt +++ b/readme.txt @@ -54,6 +54,14 @@ ROM files needed: ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN +Compaq Portable Plus (1983) + +8088 at 4.77 MHz, 128-640kb RAM. + +ROM files needed: + compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin + + DTK Clone XT (1986) 8088 at 8/10 MHz, 64kb-640kb RAM. @@ -107,19 +115,29 @@ ROM files needed: jukopc\000o001.bin -Phoenix XT clone (1986) +NCR PC4i (1985) + +8088 at 4.77 MHz, 256-640kb RAM ROM files needed: + ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN -pxxt\000p001.bin + +Phoenix XT clone (1986) + +8088 at 8/10 MHz, 64kb-640kb RAM. + +ROM files needed: + pxxt\000p001.bin Schneider Euro PC (1988) -ROM files needed: +8088 at 9.54 MHz, 512-640kb RAM. -europc\50145 -europc\50146 +ROM files needed: + europc\50145 + europc\50146 Tandy 1000 (1984) @@ -140,13 +158,47 @@ ROM files needed: tandy1000hx\v020000.u12 +Thomson TO16 PC (1987) + +8088 at 9.54 MHz, 512-640kb RAM. + +ROM files needed: + to16_pc/TO16_103.bin + + +Toshiba T1000 (1987) + +8088 at 4.77 MHz, 512-1024 kb RAM, CGA on built-in LCD. + +PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : + Fn + Num Lock - toggle numpad + Fn + Home - Internal LCD display + Fn + Page Down - Turbo on + Fn + Right - Toggle LCD font + Fn + End - External CRT display + Fn + SysRQ - Toggle window + +ROM files needed: + t1000/t1000.rom + t1000/t1000font.rom + + VTech Laser Turbo XT (1987) +8088 at 10 MHz, 640kb RAM + ROM files needed: ltxt\27c64.bin +Xi8088 (2015) + +8088 at 4.77 - 13.33 MHz, 640kb RAM + +ROM files needed: + xi8088/bios-xi8088.bin + 8086 based : @@ -218,11 +270,29 @@ ROM files needed: tandy1000sl2\8079048.hu2 -VTech Laser XT3 (1989) +Toshiba T1200 (1987) + +8086 at 9.54 MHz, 1-2 MB RAM, CGA on built-in LCD. + +PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : + Fn + Num Lock - toggle numpad + Fn + Home - Internal LCD display + Fn + Page Down - Turbo on + Fn + Right - Toggle LCD font + Fn + End - External CRT display + Fn + SysRQ - Toggle window ROM files needed: + t1200/t1200_019e.ic15.bin + t1200/t1000font.rom -lxt3\27c64d.bin + +VTech Laser XT3 (1988) + +8086 at 10 MHz, 512-1152kb RAM. + +ROM files needed: + lxt3\27c64d.bin @@ -230,28 +300,37 @@ lxt3\27c64d.bin AMI 286 clone (1990) + 286 at 8+ MHz, 512kb - 16MB RAM. ROM files needed: - -ami286\amic206.bin + ami286\amic206.bin Award 286 clone (1990) + 286 at 8+ MHz, 512kb - 16MB RAM. ROM files needed: - -award286\award.bin + award286\award.bin Commodore PC30-III (1988) + 286 at 12 MHz, 512kb - 16MB RAM. ROM files needed: + cmdpc30\commodore pc 30 iii even.bin + cmdpc30\commodore pc 30 iii odd.bin -cmdpc30\commodore pc 30 iii even.bin -cmdpc30\commodore pc 30 iii odd.bin + +Compaq Portable II (1986) + +286 at 8 MHz, 256kb-15MB RAM. + +ROM files needed: + compaq_pii/109739-001.rom + compaq_pii/109740-001.rom Dell System 200 (1990?) @@ -328,7 +407,7 @@ ROM files needed : IBM XT Model 286 (1986) -286 at 6, 256kb-16mb RAM +286 at 6 MHz, 256kb-16mb RAM ROM files needed : ibmxt286\BIOS_5162_21APR86_U34_78X7460_27256.BIN @@ -354,7 +433,7 @@ or spc4216p\ac64.u10 -Toshiba 3100e (1986) +Toshiba T3100e (1986) 286 at 12 MHz, 1MB - 5MB RAM, CGA on gas-plasma display @@ -402,8 +481,7 @@ DTK 386SX clone (1990) 386SX, 512kb - 16MB RAM. ROM files needed : - -dtk386\3cto001.bin + dtk386\3cto001.bin Epson PC AX3 (1989) @@ -411,7 +489,6 @@ Epson PC AX3 (1989) 386SX at 16 MHz, 256kb-16MB RAM. ROM files needed : - epson_pcax3\EVAX3 epson_pcax3\ODAX3 @@ -441,6 +518,14 @@ ROM files needed : kmxc02\3ctm005.bin +Packard Bell Legend 300SX (1992) + +386 SX at 16 MHz, 1-16MB RAM + +ROM files needed : + pb_l300sx/pb_l300sx.bin + + 386DX based : @@ -462,6 +547,15 @@ ROM files needed: deskpro386\109591-005.u13.bin +IBM PS/2 Model 70 (type 3) (1989) + +386DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. + +ROM files needed : + ibmps2_m70_type3/70-a_even.bin + ibmps2_m70_type3/70-a_odd.bin + + IBM PS/2 Model 80 (1987) 386DX at 20 MHz, 1MB-12MB RAM, built-in VGA, MCA bus. @@ -508,6 +602,29 @@ ROM files needed: sis496\sis496-1.awa +Elonex PC-425X (1993) + +486SX at 25 MHz, 1-256MB RAM, built-in Trident TGUI9440CXi + +ROM files needed: + elx_pc425x/elx_pc425x.bin +or + elx_pc425x/elx_pc425x_bios.bin + elx_pc425x/elx_pc425x_vbios.bin + + +IBM PS/2 Model 70 (type 4) (1990) + +486DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. + +PCem's FPU emulation is not bit accurate and can not pass IBM's floating point tests. As a result, +this machine will always print 12903 and 162 errors on bootup. These can be ignored - F1 will boot +the machine. + +ROM files needed : + ibmps2_m70_type3/70-a_even.bin + ibmps2_m70_type3/70-a_odd.bin + Pentium based : @@ -524,9 +641,9 @@ ROM files needed: Intel Advanced/EV (Endeavor) (1995) -Pentium at 75-200 MHz, 1-128MB RAM. +Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. -The real board has a Sound Blaster 16 onboard, and optionally an S3 Trio64. Neither +The real board has a Sound Blaster 16 onboard, and optionally an S3 Trio64V+. Neither are emulated as onboard devices. ROM files needed: @@ -534,6 +651,15 @@ ROM files needed: endeavor\1006cb0_.bi1 +Intel Advanced/ZP (Zappa) (1995) + +Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. + +ROM files needed: + zappa/1006bs0_.bio + zappa/1006bs0_.bi1 + + Intel Premiere/PCI (Batman's Revenge) (1994) Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz. @@ -543,6 +669,26 @@ ROM files needed: revenge\1009af2_.bi1 +Packard Bell PB520R (Robin LC) (1995) + +Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz, 1-128MB RAM, built-in Cirrus +Logic GD-5434. + +ROM files needed: + pb520r/1009bc0r.bio + pb520r/1009bc0r.bi1 + pb520r/gd5434.bin + + +Packard Bell PB570 (Hillary) (1995) + +Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM, built-in Cirrus +Logic GD-5430. + +ROM files needed: + pb570/1007by0r.bio + pb570/1007by0r.bi1 + pb570/gd5430.bin PCem emulates the following graphics adapters : @@ -626,6 +772,13 @@ ROM files needed: trident.bin +Trident TGUI9400CXi +1-2MB VRAM, supports up to 24-bit colour. + +ROM files needed: +9440.vbi + + Tseng ET4000AX SVGA 1MB VRAM, supports up to 8-bit colour. @@ -649,6 +802,28 @@ ROM files needed : atimach64vt2pci.bin +Cirrus Logic GD-5429 +1-2MB VRAM. + +ROM files needed: + 5429.vbi + + +Cirrus Logic GD-5430 +1-2MB VRAM. + +ROM files needed: + gd5430/pci.bin + + +Cirrus Logic GD-5434 +2-4MB VRAM. Real chip also supports 1MB configurations, however this is not currently +supported in PCem. + +ROM files needed: + gd5434.bin + + Diamond Stealth 32 SVGA ET4000/W32p based. 1-2MB VRAM. @@ -751,28 +926,26 @@ systems. Some models have fixed graphics adapters : -IBM PCjr -CGA with various new modes - 160x200x16, 320x200x16, 640x200x4. +Amstrad MegaPC +Paradise 90C11. A development of the PVGA1, with 512kb VRAM. Can use external video card. -Olivetti M24 -CGA with double-res text modes and a 640x400 mode. I haven't seen a dump of the font -ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd -as it is 14-line instead of 16-line. - -Tandy 1000 -Clone of PCjr video. Widely supported in 80s games. - -Tandy 1000 SL/2 -Improvement of Tandy 1000, with support for 640x200x16. +Acer 386SX/25N +Oak OTI-067. Another 512kb SVGA clone. Can use external video card. Amstrad PC1512 -CGA with a new mode (640x200x16). Only supported in GEM to my knowledge. +CGA with a new mode (640x200x16). Amstrad PC1640 -Paradise EGA. +Paradise EGA. Can use external video card. Amstrad PC2086/PC3086 -Paradise PVGA1. An early SVGA clone with 256kb VRAM. +Paradise PVGA1. An early SVGA clone with 256kb VRAM. Can use external video card. + +Elonex PC-425X +Trident TGUI9400CXi with 512kb VRAM. + +IBM PCjr +CGA with various new modes - 160x200x16, 320x200x16, 640x200x4. IBM PS/1 Model 2011 Stock VGA with 256kb VRAM. @@ -780,11 +953,31 @@ Stock VGA with 256kb VRAM. IBM PS/1 Model 2121 Basic (and unknown) SVGA with 256kb VRAM. -Amstrad MegaPC -Paradise 90C11. A development of the PVGA1, with 512kb VRAM. +IBM PS/2 machines +Stock VGA with 256kb VRAM. -Acer 386SX/25N -Oak OTI-067. Another 512kb SVGA clone. +Olivetti M24 +CGA with double-res text modes and a 640x400 mode. I haven't seen a dump of the font +ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd +as it is 14-line instead of 16-line. + +Packard Bell PB520R +Cirrus Logic GD-5434. Can use external video card. + +Packard Bell PB570 +Cirrus Logic GD-5430. Can use external video card. + +Sinclair PC200 +CGA. Can use external video card. + +Tandy 1000 +Clone of PCjr video. Widely supported in 80s games. + +Tandy 1000 SL/2 +Improvement of Tandy 1000, with support for 640x200x16. + +Toshiba T-series +CGA on built-in LCD or plasma display. From d489dddeee3ab3d106db69968a524089f2cff2a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Apr 2018 10:58:12 +0100 Subject: [PATCH 0455/1050] Tweak 486 prefetch timing when cache disabled, to account for burst accesses. Improves CPU speed detection on SiS496/497. --- src/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu.c b/src/cpu.c index d380c6b..c5958c5 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1681,7 +1681,7 @@ void cpu_update_waitstates() cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->mem_write_cycles; } if (is486) - cpu_prefetch_cycles *= 4; + cpu_prefetch_cycles = (cpu_prefetch_cycles * 11) / 16; cpu_mem_prefetch_cycles = cpu_prefetch_cycles; if (cpu_s->rspeed <= 8000000) cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles; From 8a1cef985103f95f6c8a2e5655a3eb93df57b9ab Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Apr 2018 10:58:43 +0100 Subject: [PATCH 0456/1050] Tweak DIV timing for Cyrix 486es. Improves Cyrix 486 CPU speed detection on SiS496/497. --- src/x86_ops_misc.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index d8b4ccb..43c0d97 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -114,8 +114,8 @@ static int opF6_a16(uint32_t fetchdat) x86_int(0); return 1; } - CLOCK_CYCLES(is486 ? 16 : 14); - PREFETCH_RUN(is486 ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x38: /*IDIV AL,b*/ tempws = (int)(int16_t)AX; @@ -214,8 +214,8 @@ static int opF6_a32(uint32_t fetchdat) x86_int(0); return 1; } - CLOCK_CYCLES(is486 ? 16 : 14); - PREFETCH_RUN(is486 ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x38: /*IDIV AL,b*/ tempws = (int)(int16_t)AX; @@ -316,8 +316,8 @@ static int opF7_w_a16(uint32_t fetchdat) x86_int(0); return 1; } - CLOCK_CYCLES(is486 ? 24 : 22); - PREFETCH_RUN(is486 ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x38: /*IDIV AX,w*/ tempws = (int)((DX << 16)|AX); @@ -410,8 +410,8 @@ static int opF7_w_a32(uint32_t fetchdat) x86_int(0); return 1; } - CLOCK_CYCLES(is486 ? 24 : 22); - PREFETCH_RUN(is486 ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x38: /*IDIV AX,w*/ tempws = (int)((DX << 16)|AX); From 7ce5c0c35605b6785913b672ee0bcd5ca00dba52 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Apr 2018 11:19:51 +0100 Subject: [PATCH 0457/1050] More readme.txt updates. --- readme.txt | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index 7be2872..fc5e3a6 100644 --- a/readme.txt +++ b/readme.txt @@ -729,15 +729,23 @@ An enhanced Hercules with a custom 720x350 16 colour mode. Unaccelerated (S)VGA cards : +ATI Korean VGA +ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. Korean font support. + +ROM files needed: + atikorvga.bin + ati_ksc5601.rom + + ATI VGA Edge-16 -512kb VRAM, supports up to 8-bit colour. +ATI-18800 based. 512kb VRAM, supports up to 8-bit colour. ROM files needed: vgaedge16.vbi ATI VGA Charger -512kb VRAM, supports up to 8-bit colour. +ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. ROM files needed: bios.bin @@ -750,6 +758,13 @@ ROM files needed: ibm_vga.bin +OAK OTI-037C +256kb VRAM, supports up to 8-bit colour. + +ROM files needed: + oti037\bios.bin + + OAK OTI-067 256kb-512kb VRAM, supports up to 8-bit colour. From 429f49abd1904ee9e8fc15009a59ec90b20adcf0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Apr 2018 14:14:10 +0100 Subject: [PATCH 0458/1050] Update version number and readme for v14 release. --- readme.txt | 320 +++++++++++++++++++++----------------- src/pc.c | 2 +- src/pc.xrc | 2 +- src/wx-resources.cpp | 28 ++-- src/wx-sdl2-display-win.c | 2 +- 5 files changed, 192 insertions(+), 162 deletions(-) diff --git a/readme.txt b/readme.txt index fc5e3a6..6441056 100644 --- a/readme.txt +++ b/readme.txt @@ -1,37 +1,34 @@ -PCem v13.1 +PCem v14 PCem is licensed under the GPL, see COPYING for more details. -Changes since v13: +Changes since v13.1: -- Minor recompiler tweak, fixed slowdown in some situations (mainly seen on Windows 9x just after booting) -- Fixed issues with PCJr/Tandy sound on some Sierra games -- Fixed plasma display on Toshiba 3100e -- Fixed handling of configurations with full stops in the name -- Fixed sound output gain when using OpenAL Soft -- Switched to using OpenAL Soft by default +- New machines added - Compaq Portable Plus, Compaq Portable II, Elonex PC-425X, + IBM PS/2 Model 70 (types 3 & 4), Intel Advanced/ZP, NCR PC4i, Packard Bell Legend 300SX, + Packard Bell PB520R, Packard Bell PB570, Thomson TO16 PC, Toshiba T1000, Toshiba T1200, Xi8088 +- New graphics cards added - ATI Korean VGA, Cirrus Logic CL-GD5429, Cirrus Logic CL-GD5430, + Cirrus Logic CL-GD5435, OAK OTI-037, Trident TGUI9400CXi +- New network adapters added - Realtek RTL8029AS +- Iomega Zip drive emulation +- Added option for default video timing +- Added dynamic low-pass filter for SB16/AWE32 DSP playback +- Can select external video card on some systems with built-in video +- Can use IDE hard drives up to 127 GB +- Can now use 7 SCSI devices +- Implemented CMPXCHG8B on Winchip. Can now boot Windows XP on Winchip processors +- CD-ROM emulation on OS X +- Tweaks to Pentium and 6x86 timing +- Numerous bug fixes - fixes Wing Commander : Privateer, Wing Commander III, Wings of Fury, + Zone Raiders, NFL Blitz 2000, Joe Montana Football, SB16 with Earthworm Jim, SB16 with SimCity + 2000, SB16 with Visual Player 2.0, AHA-1542C with Solaris 2.4, Voodoo 2 with FMV in Urban Chaos, + SB2.0 with Syndicate, floppy on early Linux kernels, clicking ADPCM sound playback, varying speed + in Desert Strike, keyboard hang on KMX-C-02, S3 video cards with Linux and OS/2 Warp, AudioPCI + hangs on Windows 2000/XP, OS/2 v2.0 on machines with remapped memory (eg PS/2), OS/2 v2.0 IO + performance with PS/2 ESDI, etc etc -Changes since v12: - -- New machines added - Atari PC3, Epson PC AX, Epson PC AX2e, GW-286CT GEAR, IBM PS/2 Model 30-286, - IBM PS/2 Model 50, IBM PS/2 Model 55SX, IBM PS/2 Model 80, IBM XT Model 286, KMX-C-02, - Samsung SPC-4200P, Samsung SPC-4216P, Toshiba 3100e, -- New graphics cards - MDSI Genius, Plantronics ColorPlus -- New sound cards added - Disney Sound Source, Ensoniq AudioPCI (ES1371), LPT DAC, Sound Blaster PCI 128 -- New hard drive controllers added - AT Fixed Disk Adapter, DTC 5150X, Fixed Disk Adapter (Xebec), - IBM ESDI Fixed Disk Controller, Western Digital WD1007V-SE1 -- New SCSI adapters added - Adaptec AHA-1542C, BusLogic BT-545S, Longshine LCS-6821N, Rancho RT1000B, - Trantor T130B -- New network adapters added - NE2000 compatible -- New cross-platform GUI -- Voodoo SLI emulation -- Improvements to Sound Blaster emulation -- Improvements to Pentium timing -- Various bug fixes -- Minor optimisations - -Thanks to AmatCoder, basic2004, bit, dns2k, ecksemess, Greatpsycho, hOMER247, James-F, John Elliott, -JosepMa, leilei, neozeed, ruben_balea, SA1988 and tomaszkam for contributions towards this release. +Thanks to darksabre76, dns2kv2, EluanCM, Greatpsycho, ja've, John Elliott, leilei and nerd73 for +contributions towards this release. PCem emulates the following machines: @@ -1192,17 +1189,18 @@ Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've Software tested: +CP/M-86 1.0 + PC-DOS 1.0 -PC-DOS 2.10 +MS-DOS 2.11 MS-DOS 3.30 +PC-DOS 4.01 MS-DOS 5.0 +PC-DOS 5.02 MS-DOS 6.0 MS-DOS 6.22 -DR-DOS 6.0 - Windows 1.03 -Windows 2.03 Windows/286 2.11 Windows/386 2.11 Windows 3.0 @@ -1214,7 +1212,6 @@ Windows 98 Windows 98 SE Windows ME -Windows NT 3.1 Windows NT 3.51 Windows NT 4 Windows 2000 @@ -1224,12 +1221,15 @@ OS/2 v1.0 OS/2 v1.1 OS/2 v1.2 OS/2 v1.3 -OS/2 v2.0 +OS/2 v2.1 OS/2 Warp 3 OS/2 Warp 4 +Corel Linux 1.2 Red Hat Linux 7.1 (Seawolf) -Ubuntu 10.04 + +Solaris 2.4 +Solaris 2.5.1 BeOS 5 Personal BeOS 5 Professional @@ -1238,151 +1238,181 @@ DESQview/X GEM Desktop 3.11 -Borland C++ v3.1 -Fasttracker v2.08 -Internet Explorer 5.0 +After Dark 3.0 +Aldus PageMaker 5.0 +Ami Pro 3.0 +Borland C++ 3.1 +Cubasis v1.13 +Fasttracker 2.08 +Firefox 12.0 +Internet Explorer 5 (windows 3.x and 9x versions tested) +Microsoft Basic 4.0 Microsoft Office 95 -Microsoft Visual Basic 3.0 -Microsoft Word for OS/2 1.1 +Microsoft Visual C++ 6.0 Standard Edition +Microsoft Word 1.1 Microsoft Word for Windows 1.1 +Microsoft Word for Windows 2.0c +Microsoft Word 6.0 +Microsoft Works 2.0 Microsoft Works for Windows 3.0 -Micrografx Windows Draw 1.04 -PC Paintbrush for Windows v1.05 -Ventura Publisher v3.0 +Netscape Communicator 4.73 +Norton Utilities 8.0 +PC Paintbrush v1.05 +Photoshop v3.0.4 +Tantrakr +Actua Soccer Age of Empires Aladdin -Alien vs Predator (3DFX) All New World of Lemmings -Alone in the Dark -American McGee's Alice (3DFX) +American McGee's Alice +Area 51 Arkanoid -Beasts and Bumpkins -Blake Stone -BreakNeck (3DFX) -Caesar III +Ascendancy +Battlezone +Beyond Castle Wolfenstein +Bio Menace (shareware) +Blood 2 +Boppin' +Brix (shareware) +Bust-A-Move 2 +Caesar 3 Cannon Fodder 2 -Civilization +CART: Precision Racing Civilization II -Colin McRae Rally (3DFX) -Colonization -Command & Conquer : Red Alert -Command & Conquer : Red Alert 2 -Commander Keen : Goodbye Galaxy -Commander Keen : Invasion of the Vorticons +Clusterball +Command and Conquer : Red Alert +Commando +Commandos: Behind Enemy Lines +Commandos: Beyond the Call of Duty +Conquest Corridor 7 -Croc (3DFX) Curse of Monkey Island Dawn Patrol -Descent Freespace (3DFX) -Deus Ex (3DFX) +Desert Strike +Dethkarz +Deus Ex Discworld II -Doom -Doom II -Duke Nukem 3D +Digger +Dogz +Doom (v1.2 registered) +Doom II (v1.666) +Double Dragon +Down Under Dan +Drakan : Order of the Flame +Dreamweb +Duke Nukem 3D (shareware) Dune Dune II -Ecstatica -Epic Pinball -Expendable (3DFX) -Final Fantasy VII (3DFX) -Formula 1 '97 (3DFX) -Freespace 2 (3DFX) -G-Police (3DFX) -Grim Fandango (3DFX) -Grand Theft Auto (3DFX) -GTA2 (3DFX) -Half-Life (3DFX) +Dungeon Keeper 2 +Earthworm Jim (DOS) +Epic Pinball (v2.1 registered) +Final Fantasy VII +Forsaken +Frogger +G-Police +Grand Theft Auto +Hardwar Heartlight -Hitchhiker's Guide to the Galaxy -Hocus Pocus -House of the Dead 2 (3DFX) -Incoming (3DFX) -International Rally Championship (3DFX) -Interstate 76 +Heretic +Heretic II +Hitch-Hiker's Guide to the Galaxy +Hocus Pocus (v1.1 shareware) +House of the Dead 2 +Incoming Jazz Jackrabbit Jazz Jackrabbit 2 -Jedi Knight (3DFX) -Jill of the Jungle -LBA 2 -Lode Runner : The Legend Returns -Kings Quest +Joe Montana Football +Jumpman +King's Quest +King's Quest II +Lemmings +Lemmings 2 : The Tribes +Little Big Adventure 2 +Lotus III +Mageslayer +Maniac Mansion +Maniac Mansion (enhanced) Microsoft Arcade -MiG-29 Fulcrum (3DFX) Monkey Island 2 -Monster Bash -Mortal Kombat -Mystic Towers -Need for Speed II SE (3DFX) -Need for Speed III (3DFX) +Monster Bash (shareware) +Monster Truck Madness +Mortal Kombat II +Mortal Kombat Trilogy +Necrodome +Need for Speed II SE +Nerf Arena Blast Network Q RAC Rally -No One Lives Forever (3DFX) -Oddworld : Abe's Oddysee +NFL Blitz +NFL Blitz 2000 +Pax Corpus Pinball Fantasies -Police Quest +Pinball Illusions +Police Quest II Power Drive Prince of Persia Pro Pinball : Big Race USA -Pro Pinball : Timeshock! -Psycho Pinball -Quake (3DFX) -Quake II (3DFX) -Quake III Arena (3DFX) +Pro Pinball : The Web +Pro Pinball : Timeshock +Puyo Puyo Tsu +Quake (v1.01 registered) +Quake 2 +Quake III Arena Railroad Tycoon II +Rampage World Tour Rayman -Rebel Moon Rising -Resident Evil 2 (3DFX) -Return Fire II (3DFX) -Return to Castle Wolfenstein (3DFX) -Rise of the Triad +Redline Racer (1998 US release) +Revolution X Rollercoaster Tycoon -Rollercoaster Tycoon 2 -Sam & Max Hit the Road +Rollo and the Brush Bros Screamer -Screamer Rally (not 3DFX) +Screamer 2 Secret of Monkey Island -Sensible World of Soccer -Sid Meier's Alpha Centauri -SimCity 2000 -SimCity 3000 -SiN (3DFX) -Sonic & Knuckles Collection -Star Wars Episode 1 Racer (3DFX) +SimCity 2000 (DOS) +SimCity 2000 (OS/2) +SimCity 3000 (Linux) +Slipstream 5000 +Sonic R +Space Strike +Star Trek : Starfleet Command +Star Trek : Voyager - Elite Force Stargunner +Super Zaxxon +Syndicate System Shock -System Shock 2 (3DFX - SLOW) -The Chaos Engine +Take No Prisoners +Terminal Velocity +TFX The Humans The Lion King +The Ultimate Doom (v1.9) Theme Hospital -Tie Fighter -TOCA 2 (3DFX) -Tomb Raider (3DFX, ViRGE) -Tomb Raider II (3DFX) -Tomb Raider III (3DFX) -Tony Hawk's Pro Skater 2 (3DFX) +Theme Park (floppy version) +Tomb Raider +Tomb Raider II +Tony Hawks Pro Skater 2 Total Annihilation Transport Tycoon -Trespasser (3DFX) -Turok (3DFX) -Turok 2 (3DFX) +Transport Tycoon Deluxe +Turok : Dinosaur Hunter Turrican II -Tyrian -Unreal (3DFX) -Unreal Tournament (3DFX) +UFO : Enemy Unknown (v1.2) +Unreal +Unreal Tournament Wacky Wheels -Wing Commander -Wizkid -Wolfenstein 3D -World Cup 98 (3DFX) +Warcraft II +Wargasm +Wetrix +Wing Commander 3 +Wing Commander Privateer +Wolfenstein 3D (v1.4 registered) Worms -Worms World Party -X-Com : Apocalypse -X-Com : Terror From The Deep -Xenon -Xenon 2 +Worms United +Worms 2 +X-Wing (floppy version) Zak McKracken -Zone 66 +Zone 66 (shareware) +Zone Raiders Cascada - Cronologia Complex - Cyboman 2 @@ -1390,12 +1420,10 @@ EMF - Verses Future Crew - Second Reality Gazebo - Cyboman! Hornet - Introjr -KFMF - Dance, Move, Shake -KFMF - Trip (3DFX) Logic Design - Fashion -Orange - x14 +Orange - X14 Renaissance - Amnesia -Skull - Putre Faction +Skull - Putrefaction Tran - Ambience Tran - Luminati Tran - Timeless @@ -1403,10 +1431,12 @@ Triton - Crystal Dream Triton - Crystal Dream II Ultraforce - Coldcut Ultraforce - Vectdemo +Witan - Witan House BeebInC v0.99f Fellow v0.33 KGen98 v0.4b PaCifiST v0.45 -ZSNES v0.800 -SNES9x v0.96 \ No newline at end of file +SNES9x v0.96 +vMac v1.9.1.1 +ZSNES v0.800 \ No newline at end of file diff --git a/src/pc.c b/src/pc.c index 12cc456..b70b0db 100644 --- a/src/pc.c +++ b/src/pc.c @@ -588,7 +588,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v13.1 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem v14 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/pc.xrc b/src/pc.xrc index 06ac8a1..66b6ca8 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -3549,7 +3549,7 @@ wxALL 5 - + -1 diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 13ad3f9..a5ba214 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 137689; +static size_t xml_res_size_26 = 137687; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -7776,19 +7776,19 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, 84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,80,67,101,109,32,118,49,51,46,49,92,110,104,116,116,112,115, -58,47,47,112,99,101,109,45,101,109,117,108,97,116,111,114,46,99,111,46, -117,107,47,92,110,92,110,84,104,105,115,32,112,114,111,103,114,97,109,32, -105,115,32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116, -104,101,32,71,78,85,32,71,101,110,101,114,97,108,32,80,117,98,108,105,99, -32,76,105,99,101,110,115,101,32,118,101,114,115,105,111,110,32,50,46,92, -110,83,101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109,111,114,101, -32,100,101,116,97,105,108,115,46,92,110,92,110,84,111,111,108,98,97,114, -45,105,99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117,110,100, -105,99,111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117,110,100, -105,99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119,119,119, -46,102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104,101,114, -32,105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119, +101,108,62,80,67,101,109,32,118,49,52,92,110,104,116,116,112,115,58,47, +47,112,99,101,109,45,101,109,117,108,97,116,111,114,46,99,111,46,117,107, +47,92,110,92,110,84,104,105,115,32,112,114,111,103,114,97,109,32,105,115, +32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116,104,101, +32,71,78,85,32,71,101,110,101,114,97,108,32,80,117,98,108,105,99,32,76, +105,99,101,110,115,101,32,118,101,114,115,105,111,110,32,50,46,92,110,83, +101,101,32,67,79,80,89,73,78,71,32,102,111,114,32,109,111,114,101,32,100, +101,116,97,105,108,115,46,92,110,92,110,84,111,111,108,98,97,114,45,105, +99,111,110,115,32,109,97,100,101,32,98,121,32,82,111,117,110,100,105,99, +111,110,115,32,40,104,116,116,112,115,58,47,47,114,111,117,110,100,105, +99,111,110,115,46,99,111,109,47,41,32,102,114,111,109,32,119,119,119,46, +102,108,97,116,105,99,111,110,46,99,111,109,92,110,79,116,104,101,114,32, +105,99,111,110,115,32,109,97,100,101,32,98,121,32,70,97,116,67,111,119, 32,40,104,116,116,112,58,47,47,119,119,119,46,102,97,116,99,111,119,46, 99,111,109,47,102,114,101,101,45,105,99,111,110,115,47,41,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112, diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 43f16ec..939e74c 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -583,7 +583,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v13.1", /* Title Text */ + "PCem v14", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From d70382380eac393a5b1434f89eddc9047bff008b Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Apr 2018 14:16:22 +0100 Subject: [PATCH 0459/1050] Update version number in configure/configure.ac for v14 release. --- Readme-LINUX.txt | 2 +- configure | 20 ++++++++++---------- configure.ac | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Readme-LINUX.txt b/Readme-LINUX.txt index b8c418d..514d331 100644 --- a/Readme-LINUX.txt +++ b/Readme-LINUX.txt @@ -1,4 +1,4 @@ -PCem v13.1 Linux supplement +PCem v14 Linux supplement You will need the following libraries : diff --git a/configure b/configure index 3153f81..1aa97de 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PCem v13.1. +# Generated by GNU Autoconf 2.69 for PCem v14. # # Report bugs to >. # @@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCem' PACKAGE_TARNAME='pcem' -PACKAGE_VERSION='v13.1' -PACKAGE_STRING='PCem v13.1' +PACKAGE_VERSION='v14' +PACKAGE_STRING='PCem v14' PACKAGE_BUGREPORT='Sarah Walker ' PACKAGE_URL='' @@ -1310,7 +1310,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PCem v13.1 to adapt to many kinds of systems. +\`configure' configures PCem v14 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1381,7 +1381,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCem v13.1:";; + short | recursive ) echo "Configuration of PCem v14:";; esac cat <<\_ACEOF @@ -1499,7 +1499,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCem configure v13.1 +PCem configure v14 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1680,7 +1680,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PCem $as_me v13.1, which was +It was created by PCem $as_me v14, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2616,7 +2616,7 @@ fi # Define the identity of the package. PACKAGE='pcem' - VERSION='v13.1' + VERSION='v14' cat >>confdefs.h <<_ACEOF @@ -6059,7 +6059,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PCem $as_me v13.1, which was +This file was extended by PCem $as_me v14, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6116,7 +6116,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PCem config.status v13.1 +PCem config.status v14 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 9d09ca5..00dd888 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # AC_PREREQ([2.61]) -AC_INIT(PCem, v13.1, Sarah Walker , pcem) +AC_INIT(PCem, v14, Sarah Walker , pcem) AC_CANONICAL_HOST From d5b7a69ff691027ca7d3112d3d5a45569203e5a3 Mon Sep 17 00:00:00 2001 From: Greg V Date: Fri, 18 May 2018 02:48:43 +0300 Subject: [PATCH 0460/1050] Respect the WX_CONFIG_PATH variable The configure script takes a --with-wx-config argument, we should respect it. It is very necessary for FreeBSD, which installs wx configs under more specific names such as 'wxgtk2u-3.0-config'. --- src/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index d0cd1a1..1c0fd4c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ endif amrefresh: # Special wxWidgets files -WINDRES = $(shell wx-config --rescomp) +WINDRES = $(shell $(WX_CONFIG_PATH) --rescomp) wx.res: wx.rc $(WINDRES) -i wx.rc --input-format=rc -o wx.res -O coff @@ -53,8 +53,8 @@ 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 -pcem_CFLAGS = $(subst -fpermissive,,$(shell wx-config --cxxflags) $(shell sdl2-config --cflags)) -pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) +pcem_CFLAGS = $(subst -fpermissive,,$(shell $(WX_CONFIG_PATH) --cxxflags) $(shell sdl2-config --cflags)) +pcem_CXXFLAGS = $(shell $(WX_CONFIG_PATH) --cxxflags) $(shell sdl2-config --cflags) pcem_LDADD = @LIBS@ pcem_SOURCES += wx-main.cc wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c \ From f002abe258f5d1406d01ebc3fda05c8a87709dfb Mon Sep 17 00:00:00 2001 From: Greg V Date: Fri, 18 May 2018 02:51:33 +0300 Subject: [PATCH 0461/1050] Add dummy cdrom ioctl module for other OSes --- configure.ac | 13 ++++++++++++- src/Makefile.am | 4 ++++ src/cdrom-ioctl-dummy.c | 20 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/cdrom-ioctl-dummy.c diff --git a/configure.ac b/configure.ac index 00dd888..1e3b094 100644 --- a/configure.ac +++ b/configure.ac @@ -118,6 +118,7 @@ AC_CHECK_LIB([pthread], [pthread_create]) build_macosx="no" build_linux="no" build_win="no" +build_other="no" case "$host" in *-*-darwin*) @@ -135,7 +136,7 @@ case "$host" in build_win="yes" AC_SUBST(SET_MAKE, 'MAKE=mingw32-make') ;; - *) + *-*-linux*) AC_CHECK_LIB([GL], [glGetError], [], \ [echo "You need to install the OpenGL library." exit -1]) @@ -144,12 +145,22 @@ case "$host" in exit -1]) build_linux="yes" ;; + *) + AC_CHECK_LIB([GL], [glGetError], [], \ + [echo "You need to install the OpenGL library." + exit -1]) + AC_CHECK_LIB([openal], [alGetError], [], \ + [echo "You need to install the OpenAL library." + exit -1]) + build_other="yes" + ;; esac LIBS="$LIBS $WX_LIBS $SDL_LIBS" AM_CONDITIONAL(OS_LINUX, [test "$build_linux" = "yes"]) AM_CONDITIONAL(OS_WINDOWS, [test "$build_win" = "yes"]) +AM_CONDITIONAL(OS_OTHER, [test "$build_other" = "yes"]) AM_CONDITIONAL(OS_MACOSX, [test "$build_macosx" = "yes"]) AC_OUTPUT([Makefile src/Makefile]) diff --git a/src/Makefile.am b/src/Makefile.am index 1c0fd4c..7bbb5be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -97,6 +97,10 @@ if OS_LINUX pcem_SOURCES += cdrom-ioctl-linux.c wx-sdl2-display.c endif +if OS_OTHER +pcem_SOURCES += cdrom-ioctl-dummy.c wx-sdl2-display.c +endif + if OS_MACOSX pcem_SOURCES += cdrom-ioctl-osx.c wx-sdl2-display.c pcem_CFLAGS += -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP diff --git a/src/cdrom-ioctl-dummy.c b/src/cdrom-ioctl-dummy.c new file mode 100644 index 0000000..a4229ac --- /dev/null +++ b/src/cdrom-ioctl-dummy.c @@ -0,0 +1,20 @@ +/*Dummy CD-ROM support for other OSes*/ + +#include + +int old_cdrom_drive; + +void ioctl_audio_callback(int16_t *output, int len) { } + +void ioctl_audio_stop() { } + +void ioctl_reset() { } + +void ioctl_set_drive(char d) { } + +int ioctl_open(char d) +{ + return 0; +} + +void ioctl_close(void) { } From e3f801c2e852fde0780aee9c375070cde878d5c0 Mon Sep 17 00:00:00 2001 From: Greg V Date: Fri, 18 May 2018 02:52:11 +0300 Subject: [PATCH 0462/1050] Disable lfs on FreeBSD It has the off64_t type, but none of the legacy *64 functions. --- configure.ac | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.ac b/configure.ac index 1e3b094..4a30d37 100644 --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,11 @@ AM_CONDITIONAL(CPU_X86_64, test "$CPU" = "x86_64") AC_MSG_CHECKING([for off64_t]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[off64_t n=0;]])],[has_lfs="yes"],[has_lfs="no"]) +case "$host" in + *-*-freebsd*) # has off64_t but no fopen64/etc. + has_lfs="no" + ;; +esac AC_MSG_RESULT($has_lfs) #AC_MSG_CHECKING([for libz]) From 2955df2c5abcddf73afea30f69268533db867732 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 20:06:11 +0100 Subject: [PATCH 0463/1050] Fixed strncpy() length when parsing command line. --- src/pc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pc.c b/src/pc.c index b70b0db..c29f07b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -275,7 +275,7 @@ void initpc(int argc, char *argv[]) if ((c+1) == argc) break; - strncpy(discfns[0], argv[c+1], 260); + strncpy(discfns[0], argv[c+1], 256); c++; override_drive_a = 1; } @@ -284,7 +284,7 @@ void initpc(int argc, char *argv[]) if ((c+1) == argc) break; - strncpy(discfns[1], argv[c+1], 260); + strncpy(discfns[1], argv[c+1], 256); c++; override_drive_b = 1; } From 82fcbd99deeb5857484335c07ebd41207e057df4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 20:19:47 +0100 Subject: [PATCH 0464/1050] Allow 704kb on Generic XT clone when MDA/CGA/Hercules are in use. Patch from Greatpsycho. --- src/mem.c | 8 ++++---- src/model.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mem.c b/src/mem.c index 739d16d..6464873 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2313,10 +2313,10 @@ void mem_init() memset(_mem_state, 0, sizeof(_mem_state)); - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x000000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - 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); + mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : 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) { if (cpu_16bitbus && mem_size > 16256) @@ -2414,10 +2414,10 @@ void mem_resize() memset(_mem_state, 0, sizeof(_mem_state)); - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x000000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - 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); + mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : 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) { if (cpu_16bitbus && mem_size > 16256) diff --git a/src/model.c b/src/model.c index 5dfde71..55be58b 100644 --- a/src/model.c +++ b/src/model.c @@ -116,7 +116,7 @@ MODEL models[] = {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 64, compaq_pip_init, NULL}, {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, - {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 32, 704, 16, xt_init, NULL}, {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 32, xt_init, NULL}, {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 64, pcjr_init, &pcjr_device}, {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, From 38e842d88d5966eb8dd5fd5ee5357d50e50e3562 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 20:20:05 +0100 Subject: [PATCH 0465/1050] Load BASIC on Generic XT clone if present. Patch from Greatpsycho. --- src/mem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mem.c b/src/mem.c index 6464873..23d6523 100644 --- a/src/mem.c +++ b/src/mem.c @@ -235,6 +235,8 @@ int loadbios() if (!f) break; romfread(rom+0xE000,8192,1,f); fclose(f); + if (!mem_load_basic("genxt")) + break; return 1; case ROM_DTKXT: f=romfopen("dtk/dtk_erso_2.42_2764.bin","rb"); From cbf4b9f8138a94dea3e0207b0a8ca5bebee2f6d3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 21:02:36 +0100 Subject: [PATCH 0466/1050] Configurable MAC address. Patch from Tux. --- src/ne2000.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/ne2000.c b/src/ne2000.c index e0ce985..329af7e 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -50,8 +50,8 @@ #include "pci.h" #include "timer.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}; +/*MAC address*/ +uint8_t maclocal[6]; typedef enum { @@ -1673,10 +1673,36 @@ void *ne2000_common_init() { struct in_addr myaddr; int rc; + unsigned int macint[6]; + char *macstring; ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); + macstring = config_get_string(CFG_MACHINE, NULL, "macaddr", ""); + + if (sscanf(macstring, "%02x:%02x:%02x:%02x:%02x:%02x", + &macint[0],&macint[1],&macint[2],&macint[3],&macint[4],&macint[5]) != 6) + { + maclocal[0] = 0xac; + maclocal[1] = 0xde; + maclocal[2] = 0x48; + maclocal[3] = 0x88; + maclocal[4] = 0xbb; + maclocal[5] = 0xaa; + pclog("ne2000: Using default MAC address (AC:DE:48:88:BB:AA)\n"); + } + else + { + maclocal[0] = macint[0]; + maclocal[1] = macint[1]; + maclocal[2] = macint[2]; + maclocal[3] = macint[3]; + maclocal[4] = macint[4]; + maclocal[5] = macint[5]; + pclog("ne2000: Using MAC address from pcem.cfg: %s\n", macstring); + } + //net_type //0 pcap //1 slirp From 8ac2157f8709a7327e49018ab3434cc17af821f2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 21:38:18 +0100 Subject: [PATCH 0467/1050] Fixed AT systems broken by rev 1184. --- src/mem.c | 14 ++++++++++---- src/mem.h | 2 ++ src/pc.c | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/mem.c b/src/mem.c index 23d6523..6b6f590 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2315,10 +2315,10 @@ void mem_init() memset(_mem_state, 0, sizeof(_mem_state)); - mem_set_mem_state(0x000000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + 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_mapping_add(&ram_low_mapping, 0x00000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : 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); + 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) { if (cpu_16bitbus && mem_size > 16256) @@ -2377,6 +2377,12 @@ void mem_remap_top_384k() mem_remap_top(384); } +void mem_set_704kb() +{ + mem_set_mem_state(0x000000, (mem_size > 704) ? 0xb0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_low_mapping, 0x00000, (mem_size > 704) ? 0xb0000 : mem_size * 1024); +} + void mem_resize() { int c; @@ -2416,10 +2422,10 @@ void mem_resize() memset(_mem_state, 0, sizeof(_mem_state)); - mem_set_mem_state(0x000000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + 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_mapping_add(&ram_low_mapping, 0x00000, (mem_size > (AT ? 640 : 768)) ? (AT ? 0xa0000 : 0xc0000) : 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); + 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) { if (cpu_16bitbus && mem_size > 16256) diff --git a/src/mem.h b/src/mem.h index edde319..2aabde9 100644 --- a/src/mem.h +++ b/src/mem.h @@ -182,6 +182,8 @@ void mem_add_bios(); void mem_init(); void mem_resize(); +void mem_set_704kb(); + void flushmmucache(); void flushmmucache_nopc(); void flushmmucache_cr3(); diff --git a/src/pc.c b/src/pc.c index c29f07b..faeaa1a 100644 --- a/src/pc.c +++ b/src/pc.c @@ -417,6 +417,8 @@ void resetpchard() disc_load(1, discfns[1]); model_init(); + if (!AT) + mem_set_704kb(); mouse_emu_init(); video_init(); speaker_init(); From b62127f7a8752dd65a28852782073bc2b00ec0ac Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 22:03:45 +0100 Subject: [PATCH 0468/1050] Move BIOS loading out of mem.c. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw-network | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.mingw64 | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/mem.c | 903 ---------------------------- src/mem_bios.c | 908 +++++++++++++++++++++++++++++ src/mem_bios.h | 1 + 12 files changed, 918 insertions(+), 912 deletions(-) create mode 100644 src/mem_bios.c create mode 100644 src/mem_bios.h diff --git a/src/Makefile.am b/src/Makefile.am index 7bbb5be..56741ab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codeg dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ -laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ +laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index febf188..861ec27 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -9,7 +9,7 @@ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codeg dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 2530657..4b2e9e3 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -9,7 +9,7 @@ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codeg dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ae8e225..5d74a3f 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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.mingw-network b/src/Makefile.mingw-network index 616eb24..853e631 100644 --- a/src/Makefile.mingw-network +++ b/src/Makefile.mingw-network @@ -8,7 +8,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 8b4824f..3bfb669 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index cbc712d..20bc8bd 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -10,7 +10,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 2b6f091..ff492b9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -7,7 +7,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 0c5b11c..2549db1 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -8,7 +8,7 @@ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codeg device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ +laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb.o sound_sb_dsp.o sound_sn76489.o \ diff --git a/src/mem.c b/src/mem.c index 6b6f590..eabbcaa 100644 --- a/src/mem.c +++ b/src/mem.c @@ -58,909 +58,6 @@ int cachesize=256; uint8_t *ram, *rom = NULL; uint8_t romext[32768]; -static void romfread(uint8_t *buf, size_t size, size_t count, FILE *fp) -{ - int result = fread(buf,size,count,fp); - if (result < count) - { - pclog("ROM read failed: Expected %d, read %d\n", count, result); - } -} - -static int mem_load_basic(char *path) -{ - char s[256]; - FILE *f; - - sprintf(s, "%s/ibm-basic-1.10.rom", path); - f = romfopen(s, "rb"); - if (!f) - { - sprintf(s, "%s/basicc11.f6", path); - f = romfopen(s, "rb"); - if (!f) return 1; /*I don't really care if BASIC is there or not*/ - romfread(rom + 0x6000, 8192, 1, f); - fclose(f); - sprintf(s, "%s/basicc11.f8", path); - f = romfopen(s, "rb"); - if (!f) return 0; /*But if some of it is there, then all of it must be*/ - romfread(rom + 0x8000, 8192, 1, f); - fclose(f); - sprintf(s, "%s/basicc11.fa", path); - f = romfopen(s, "rb"); - if (!f) return 0; - romfread(rom + 0xA000, 8192, 1, f); - fclose(f); - sprintf(s, "%s/basicc11.fc", path); - f = romfopen(s, "rb"); - if (!f) return 0; - romfread(rom + 0xC000, 8192, 1, f); - fclose(f); - } - else - { - romfread(rom + 0x6000, 32768, 1, f); - fclose(f); - } - - return 1; -} - -int loadbios() -{ - FILE *f=NULL,*ff=NULL; - int c; - - loadfont("mda.rom", 0); - loadfont("wy700.rom", 3); - loadfont("8x12.bin", 4); - - biosmask = 0xffff; - - if (!rom) - rom = malloc(0x20000); - memset(romext,0x63,0x4000); - memset(rom, 0xff, 0x20000); - - pclog("Starting with romset %i\n", romset); - - switch (romset) - { - case ROM_PC1512: - f=romfopen("pc1512/40043.v1","rb"); - ff=romfopen("pc1512/40044.v1","rb"); - if (!f || !ff) break; - for (c=0xC000;c<0x10000;c+=2) - { - rom[c]=getc(f); - rom[c+1]=getc(ff); - } - fclose(ff); - fclose(f); - loadfont("pc1512/40078.ic127", 2); - return 1; - case ROM_PC1640: - f=romfopen("pc1640/40044.v3","rb"); - ff=romfopen("pc1640/40043.v3","rb"); - if (!f || !ff) break; - for (c=0xC000;c<0x10000;c+=2) - { - rom[c]=getc(f); - rom[c+1]=getc(ff); - } - fclose(ff); - fclose(f); - f=romfopen("pc1640/40100","rb"); - if (!f) break; - fclose(f); - return 1; - case ROM_PC200: - f=romfopen("pc200/pc20v2.1","rb"); - ff=romfopen("pc200/pc20v2.0","rb"); - if (!f || !ff) break; - for (c=0xC000;c<0x10000;c+=2) - { - rom[c]=getc(f); - rom[c+1]=getc(ff); - } - fclose(ff); - fclose(f); - loadfont("pc200/40109.bin", 1); - return 1; - case ROM_TANDY: - f=romfopen("tandy/tandy1t1.020","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - case ROM_TANDY1000HX: - f = romfopen("tandy1000hx/v020000.u12", "rb"); - if (!f) break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - case ROM_TANDY1000SL2: - f = romfopen("tandy1000sl2/8079047.hu1" ,"rb"); - ff = romfopen("tandy1000sl2/8079048.hu2","rb"); - if (!f || !ff) break; - fseek(f, 0x30000/2, SEEK_SET); - fseek(ff, 0x30000/2, SEEK_SET); - for (c = 0x0000; c < 0x10000; c += 2) - { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; -/* case ROM_IBMPCJR: - f=fopen("pcjr/bios.rom","rb"); - romfread(rom+0xE000,8192,1,f); - fclose(f); - f=fopen("pcjr/basic.rom","rb"); - romfread(rom+0x6000,32768,1,f); - fclose(f); - break;*/ - case ROM_IBMXT: - f=romfopen("ibmxt/xt.rom","rb"); - if (!f) - { - f = romfopen("ibmxt/5000027.u19", "rb"); - ff = romfopen("ibmxt/1501512.u18","rb"); - if (!f || !ff) break; - romfread(rom, 0x8000, 1, f); - romfread(rom + 0x8000, 0x8000, 1, ff); - fclose(ff); - fclose(f); - return 1; - } - else - { - romfread(rom,65536,1,f); - fclose(f); - return 1; - } - break; - - case ROM_IBMPCJR: - f = romfopen("ibmpcjr/bios.rom","rb"); - if (!f) break; - romfread(rom, 0x10000, 1, f); - fclose(f); - return 1; - - case ROM_GENXT: - f=romfopen("genxt/pcxt.rom","rb"); - if (!f) break; - romfread(rom+0xE000,8192,1,f); - fclose(f); - if (!mem_load_basic("genxt")) - break; - return 1; - case ROM_DTKXT: - f=romfopen("dtk/dtk_erso_2.42_2764.bin","rb"); - if (!f) break; - romfread(rom+0xE000,8192,1,f); - fclose(f); - return 1; - case ROM_OLIM24: - f = romfopen("olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); - ff = romfopen("olivetti_m24/olivetti_m24_version_1.43_high.bin","rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x4000; c += 2) - { - rom[c + 0xc000] = getc(f); - rom[c + 0xc001] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; - - case ROM_PC2086: - f = romfopen("pc2086/40179.ic129" ,"rb"); - ff = romfopen("pc2086/40180.ic132","rb"); - if (!f || !ff) break; - pclog("Loading BIOS\n"); - for (c = 0x0000; c < 0x4000; c += 2) - { - rom[c + 0x0000] = getc(f); - rom[c + 0x0001] = getc(ff); - } - pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); - fclose(ff); - fclose(f); - f = romfopen("pc2086/40186.ic171", "rb"); - if (!f) break; - fclose(f); - biosmask = 0x3fff; - return 1; - - case ROM_PC3086: - f = romfopen("pc3086/fc00.bin" ,"rb"); - if (!f) break; - romfread(rom, 0x4000, 1, f); - fclose(f); - f = romfopen("pc3086/c000.bin", "rb"); - if (!f) break; - fclose(f); - biosmask = 0x3fff; - return 1; - - case ROM_IBMAT: -/* f=romfopen("amic206.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1;*/ - case ROM_IBMAT386: - f = romfopen("ibmat/62x0820.u27", "rb"); - ff =romfopen("ibmat/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_CMDPC30: - f = romfopen("cmdpc30/commodore pc 30 iii even.bin", "rb"); - ff = romfopen("cmdpc30/commodore pc 30 iii odd.bin", "rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x8000; c += 2) - { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; - case ROM_DELL200: - f=romfopen("dells200/dell0.bin","rb"); - ff=romfopen("dells200/dell1.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; -/* case ROM_IBMAT386: - f=romfopen("at386/at386.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1;*/ - case ROM_AMI386SX: -// f=romfopen("at386/at386.bin","rb"); - f=romfopen("ami386/ami386.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f=romfopen("ami386dx/opt495sx.ami","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f=romfopen("mr386dx/opt495sx.mr","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_ACER386: - f=romfopen("acer386/acer386.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - rom[0xB0]=0xB0-0x51; - rom[0x40d4]=0x51; /*PUSH CX*/ - f=romfopen("acer386/oti067.bin","rb"); - if (!f) break; - fclose(f); - return 1; - - case ROM_KMXC02: - f=romfopen("kmxc02/3ctm005.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_AMI286: - f=romfopen("ami286/amic206.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); -// memset(romext,0x63,0x8000); - return 1; - - case ROM_AWARD286: - f=romfopen("award286/award.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_GW286CT: - f=romfopen("gw286ct/2ctc001.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_SPC4200P: - f=romfopen("spc4200p/u8.01","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_SPC4216P: - f=romfopen("spc4216p/phoenix.bin","rb"); - if (!f) - { - f = romfopen("spc4216p/7101.u8", "rb"); - ff = romfopen("spc4216p/ac64.u10","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; - } - else - { - romfread(rom,65536,1,f); - - fclose(f); - return 1; - } - break; - - case ROM_EUROPC: -// return 0; - f=romfopen("europc/50145","rb"); - if (!f) break; - romfread(rom+0x8000,32768,1,f); - fclose(f); -// memset(romext,0x63,0x8000); - return 1; - - case ROM_IBMPC: - f=romfopen("ibmpc/pc102782.bin","rb"); - if (!f) break; -// f=fopen("pc081682.bin","rb"); - romfread(rom+0xE000,8192,1,f); - fclose(f); - if (!mem_load_basic("ibmpc")) - break; - return 1; - - case ROM_MEGAPC: - f = romfopen("megapc/41651-bios lo.u18", "rb"); - ff = romfopen("megapc/211253-bios hi.u19", "rb"); - if (!f || !ff) break; - fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); - for (c = 0x0000; c < 0x10000; c+=2) - { - rom[c]=getc(f); - rom[c+1]=getc(ff); - } - fclose(ff); - fclose(f); - return 1; - - case ROM_AMI486: - f=romfopen("ami486/ami486.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - //is486=1; - return 1; - - case ROM_WIN486: -// f=romfopen("win486/win486.bin","rb"); - f=romfopen("win486/ali1429g.amw","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - //is486=1; - return 1; - - case ROM_PCI486: - f=romfopen("hot-433/hot-433.ami","rb"); - if (!f) break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; - - case ROM_SIS496: - f = romfopen("sis496/sis496-1.awa", "rb"); - if (!f) break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); - return 1; - - case ROM_430VX: -// f = romfopen("430vx/ga586atv.bin", "rb"); -// f = fopen("430vx/vx29.bin", "rb"); - f = romfopen("430vx/55xwuq0e.bin", "rb"); -// f=romfopen("430vx/430vx","rb"); - if (!f) break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; - - case ROM_REVENGE: - f = romfopen("revenge/1009af2_.bio", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("revenge/1009af2_.bi1", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; - case ROM_ENDEAVOR: - f = romfopen("endeavor/1006cb0_.bio", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("endeavor/1006cb0_.bi1", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xd000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; - - case ROM_IBMPS1_2011: -#if 0 - f=romfopen("ibmps1es/ibm_1057757_24-05-90.bin","rb"); - ff=romfopen("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("ibmps1es/f80000.bin", "rb"); - if (!f) break; - fseek(f, 0x60000, SEEK_SET); - romfread(rom, 0x20000, 1, f); - fclose(f); -//#endif - biosmask = 0x1ffff; - return 1; - - case ROM_IBMPS1_2121: - f = romfopen("ibmps1_2121/fc0000.bin", "rb"); - if (!f) break; - fseek(f, 0x20000, SEEK_SET); - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - - case ROM_DESKPRO_386: - f=romfopen("deskpro386/109592-005.u11.bin","rb"); - ff=romfopen("deskpro386/109591-005.u13.bin","rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x8000; c += 2) - { - rom[c] = getc(f); - rom[c+1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; - - case ROM_AMIXT: - f = romfopen("amixt/ami_8088_bios_31jan89.bin", "rb"); - if (!f) break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; - - case ROM_LTXT: - f = romfopen("ltxt/27c64.bin", "rb"); - if (!f) break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - if (!mem_load_basic("ltxt")) - break; - return 1; - - case ROM_LXT3: - f = romfopen("lxt3/27c64d.bin", "rb"); - if (!f) break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - if (!mem_load_basic("lxt3")) - break; - return 1; - - case ROM_PX386: /*Phoenix 80386 BIOS*/ - f=romfopen("px386/3iip001l.bin","rb"); - ff=romfopen("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; - - case ROM_DTK386: /*Uses NEAT chipset*/ - f = romfopen("dtk386/3cto001.bin", "rb"); - if (!f) break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - - case ROM_PXXT: - f = romfopen("pxxt/000p001.bin", "rb"); - if (!f) break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; - - case ROM_JUKOPC: - f = romfopen("jukopc/000o001.bin", "rb"); - if (!f) break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; - - case ROM_IBMPS2_M30_286: - f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); - if (!f) break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - - case ROM_IBMPS2_M50: - f=romfopen("i8550021/90x7423.zm14","rb"); - ff=romfopen("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("i8550021/90x7420.zm13","rb"); - ff=romfopen("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("i8555081/33f8146.zm41","rb"); - ff=romfopen("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("i8580111/15f6637.bin","rb"); - ff=romfopen("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; - - case ROM_ATARIPC3: - f=romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN","rb"); - if (!f) break; - romfread(rom+0x8000,32768,1,f); - fclose(f); - return 1; - - case ROM_IBMXT286: - f = romfopen("ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN", "rb"); - ff =romfopen("ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.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; - - case ROM_EPSON_PCAX: - f = romfopen("epson_pcax/EVAX", "rb"); - ff = romfopen("epson_pcax/ODAX", "rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x8000; c += 2) - { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; - - case ROM_EPSON_PCAX2E: - f = romfopen("epson_pcax2e/EVAXE", "rb"); - ff = romfopen("epson_pcax2e/ODAXE", "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_EPSON_PCAX3: - f = romfopen("epson_pcax3/EVAX3", "rb"); - ff = romfopen("epson_pcax3/ODAX3", "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_T3100E: - loadfont("t3100e/t3100e_font.bin", 5); - f=romfopen("t3100e/t3100e.rom","rb"); - if (!f) break; - romfread(rom,65536,1,f); - fclose(f); - return 1; - - case ROM_T1000: - loadfont("t1000/t1000font.rom", 2); - f=romfopen("t1000/t1000.rom","rb"); - if (!f) break; - romfread(rom, 0x8000,1,f); - memcpy(rom + 0x8000, rom, 0x8000); - biosmask = 0x7fff; - fclose(f); - return 1; - - case ROM_T1200: - loadfont("t1200/t1000font.rom", 2); - f=romfopen("t1200/t1200_019e.ic15.bin","rb"); - if (!f) break; - romfread(rom, 0x8000,1,f); - memcpy(rom + 0x8000, rom, 0x8000); - biosmask = 0x7fff; - fclose(f); - return 1; - - case ROM_PB_L300SX: - f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); - if (!f) break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - - case ROM_NCR_PC4I: - f=romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN" ,"rb"); - if (!f) break; - romfread(rom, 0x4000, 1, f); - fclose(f); - biosmask = 0x3fff; - return 1; - - case ROM_TO16_PC: - f=romfopen("to16_pc/TO16_103.bin","rb"); - if (!f) break; - romfread(rom+0x8000,32768,1,f); - fclose(f); - return 1; - - case ROM_COMPAQ_PII: - f = romfopen("compaq_pii/109740-001.rom", "rb"); - ff = romfopen("compaq_pii/109739-001.rom", "rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x8000; c += 2) - { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; - - case ROM_ELX_PC425X: - /*PC-425X uses a single ROM chip containing both main and video BIOSes. - First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. - Alternatively, seperate BIOS + video BIOS dumps are supported.*/ - f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); - if (!f) - { - if (!rom_present("elx_pc425x/elx_pc425x_vbios.bin")) - break; - f = romfopen("elx_pc425x/elx_pc425x_bios.bin", "rb"); - if (!f) - break; - } - else - fseek(f, 0x10000, SEEK_SET); - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - - case ROM_PB570: - if (!rom_present("pb570/gd5430.bin")) - break; - f = romfopen("pb570/1007by0r.bio", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("pb570/1007by0r.bi1", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); - romfread(rom+0xc000, 0x1000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - - case ROM_ZAPPA: - f = romfopen("zappa/1006bs0_.bio", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("zappa/1006bs0_.bi1", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xd000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - - case ROM_PB520R: - if (!rom_present("pb520r/gd5434.bin")) - break; - f = romfopen("pb520r/1009bc0r.bio", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("pb520r/1009bc0r.bi1", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); - romfread(rom+0xc000, 0x1000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - - case ROM_COMPAQ_PIP: - f=romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin","rb"); - if (!f) break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; - - case ROM_XI8088: - f = romfopen("xi8088/bios-xi8088.bin", "rb"); /* use the bios without xt-ide because it's configurable in pcem */ - if (!f) break; - if (xi8088_bios_128kb()) - { - /* high bit is flipped in xi8088 */ - romfread(rom + 0x10000, 0x10000, 1, f); - romfread(rom, 0x10000, 1, f); - biosmask = 0x1ffff; - } - else - { - /* smaller bios, more UMBs */ - romfread(rom, 0x10000, 1, f); - } - fclose(f); - return 1; - - case ROM_IBMPS2_M70_TYPE3: - f = romfopen("ibmps2_m70_type3/70-a_even.bin","rb"); - ff = romfopen("ibmps2_m70_type3/70-a_odd.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_IBMPS2_M70_TYPE4: - f = romfopen("ibmps2_m70_type4/70-b_even.bin","rb"); - ff = romfopen("ibmps2_m70_type4/70-b_odd.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"); - if (f) fclose(f); - if (ff) fclose(ff); - return 0; -} - - - //int abrt=0; void resetreadlookup() diff --git a/src/mem_bios.c b/src/mem_bios.c new file mode 100644 index 0000000..dc5a904 --- /dev/null +++ b/src/mem_bios.c @@ -0,0 +1,908 @@ +#include +#include "ibm.h" +#include "mem.h" +#include "mem_bios.h" +#include "rom.h" +#include "video.h" +#include "xi8088.h" + +static void romfread(uint8_t *buf, size_t size, size_t count, FILE *fp) +{ + int result = fread(buf,size,count,fp); + if (result < count) + { + pclog("ROM read failed: Expected %d, read %d\n", count, result); + } +} + +static int mem_load_basic(char *path) +{ + char s[256]; + FILE *f; + + sprintf(s, "%s/ibm-basic-1.10.rom", path); + f = romfopen(s, "rb"); + if (!f) + { + sprintf(s, "%s/basicc11.f6", path); + f = romfopen(s, "rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + romfread(rom + 0x6000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.f8", path); + f = romfopen(s, "rb"); + if (!f) return 0; /*But if some of it is there, then all of it must be*/ + romfread(rom + 0x8000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.fa", path); + f = romfopen(s, "rb"); + if (!f) return 0; + romfread(rom + 0xA000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.fc", path); + f = romfopen(s, "rb"); + if (!f) return 0; + romfread(rom + 0xC000, 8192, 1, f); + fclose(f); + } + else + { + romfread(rom + 0x6000, 32768, 1, f); + fclose(f); + } + + return 1; +} + +int loadbios() +{ + FILE *f=NULL,*ff=NULL; + int c; + + loadfont("mda.rom", 0); + loadfont("wy700.rom", 3); + loadfont("8x12.bin", 4); + + biosmask = 0xffff; + + if (!rom) + rom = malloc(0x20000); + memset(romext,0x63,0x4000); + memset(rom, 0xff, 0x20000); + + pclog("Starting with romset %i\n", romset); + + switch (romset) + { + case ROM_PC1512: + f=romfopen("pc1512/40043.v1","rb"); + ff=romfopen("pc1512/40044.v1","rb"); + if (!f || !ff) break; + for (c=0xC000;c<0x10000;c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + loadfont("pc1512/40078.ic127", 2); + return 1; + case ROM_PC1640: + f=romfopen("pc1640/40044.v3","rb"); + ff=romfopen("pc1640/40043.v3","rb"); + if (!f || !ff) break; + for (c=0xC000;c<0x10000;c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + f=romfopen("pc1640/40100","rb"); + if (!f) break; + fclose(f); + return 1; + case ROM_PC200: + f=romfopen("pc200/pc20v2.1","rb"); + ff=romfopen("pc200/pc20v2.0","rb"); + if (!f || !ff) break; + for (c=0xC000;c<0x10000;c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + loadfont("pc200/40109.bin", 1); + return 1; + case ROM_TANDY: + f=romfopen("tandy/tandy1t1.020","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_TANDY1000HX: + f = romfopen("tandy1000hx/v020000.u12", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_TANDY1000SL2: + f = romfopen("tandy1000sl2/8079047.hu1" ,"rb"); + ff = romfopen("tandy1000sl2/8079048.hu2","rb"); + if (!f || !ff) break; + fseek(f, 0x30000/2, SEEK_SET); + fseek(ff, 0x30000/2, SEEK_SET); + for (c = 0x0000; c < 0x10000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; +/* case ROM_IBMPCJR: + f=fopen("pcjr/bios.rom","rb"); + romfread(rom+0xE000,8192,1,f); + fclose(f); + f=fopen("pcjr/basic.rom","rb"); + romfread(rom+0x6000,32768,1,f); + fclose(f); + break;*/ + case ROM_IBMXT: + f=romfopen("ibmxt/xt.rom","rb"); + if (!f) + { + f = romfopen("ibmxt/5000027.u19", "rb"); + ff = romfopen("ibmxt/1501512.u18","rb"); + if (!f || !ff) break; + romfread(rom, 0x8000, 1, f); + romfread(rom + 0x8000, 0x8000, 1, ff); + fclose(ff); + fclose(f); + return 1; + } + else + { + romfread(rom,65536,1,f); + fclose(f); + return 1; + } + break; + + case ROM_IBMPCJR: + f = romfopen("ibmpcjr/bios.rom","rb"); + if (!f) break; + romfread(rom, 0x10000, 1, f); + fclose(f); + return 1; + + case ROM_GENXT: + f=romfopen("genxt/pcxt.rom","rb"); + if (!f) break; + romfread(rom+0xE000,8192,1,f); + fclose(f); + if (!mem_load_basic("genxt")) + break; + return 1; + case ROM_DTKXT: + f=romfopen("dtk/dtk_erso_2.42_2764.bin","rb"); + if (!f) break; + romfread(rom+0xE000,8192,1,f); + fclose(f); + return 1; + case ROM_OLIM24: + f = romfopen("olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); + ff = romfopen("olivetti_m24/olivetti_m24_version_1.43_high.bin","rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x4000; c += 2) + { + rom[c + 0xc000] = getc(f); + rom[c + 0xc001] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + + case ROM_PC2086: + f = romfopen("pc2086/40179.ic129" ,"rb"); + ff = romfopen("pc2086/40180.ic132","rb"); + if (!f || !ff) break; + pclog("Loading BIOS\n"); + for (c = 0x0000; c < 0x4000; c += 2) + { + rom[c + 0x0000] = getc(f); + rom[c + 0x0001] = getc(ff); + } + pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); + fclose(ff); + fclose(f); + f = romfopen("pc2086/40186.ic171", "rb"); + if (!f) break; + fclose(f); + biosmask = 0x3fff; + return 1; + + case ROM_PC3086: + f = romfopen("pc3086/fc00.bin" ,"rb"); + if (!f) break; + romfread(rom, 0x4000, 1, f); + fclose(f); + f = romfopen("pc3086/c000.bin", "rb"); + if (!f) break; + fclose(f); + biosmask = 0x3fff; + return 1; + + case ROM_IBMAT: +/* f=romfopen("amic206.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1;*/ + case ROM_IBMAT386: + f = romfopen("ibmat/62x0820.u27", "rb"); + ff =romfopen("ibmat/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_CMDPC30: + f = romfopen("cmdpc30/commodore pc 30 iii even.bin", "rb"); + ff = romfopen("cmdpc30/commodore pc 30 iii odd.bin", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + case ROM_DELL200: + f=romfopen("dells200/dell0.bin","rb"); + ff=romfopen("dells200/dell1.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; +/* case ROM_IBMAT386: + f=romfopen("at386/at386.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1;*/ + case ROM_AMI386SX: +// f=romfopen("at386/at386.bin","rb"); + f=romfopen("ami386/ami386.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ + f=romfopen("ami386dx/opt495sx.ami","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ + f=romfopen("mr386dx/opt495sx.mr","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_ACER386: + f=romfopen("acer386/acer386.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + rom[0xB0]=0xB0-0x51; + rom[0x40d4]=0x51; /*PUSH CX*/ + f=romfopen("acer386/oti067.bin","rb"); + if (!f) break; + fclose(f); + return 1; + + case ROM_KMXC02: + f=romfopen("kmxc02/3ctm005.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_AMI286: + f=romfopen("ami286/amic206.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); +// memset(romext,0x63,0x8000); + return 1; + + case ROM_AWARD286: + f=romfopen("award286/award.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_GW286CT: + f=romfopen("gw286ct/2ctc001.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_SPC4200P: + f=romfopen("spc4200p/u8.01","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_SPC4216P: + f=romfopen("spc4216p/phoenix.bin","rb"); + if (!f) + { + f = romfopen("spc4216p/7101.u8", "rb"); + ff = romfopen("spc4216p/ac64.u10","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; + } + else + { + romfread(rom,65536,1,f); + + fclose(f); + return 1; + } + break; + + case ROM_EUROPC: +// return 0; + f=romfopen("europc/50145","rb"); + if (!f) break; + romfread(rom+0x8000,32768,1,f); + fclose(f); +// memset(romext,0x63,0x8000); + return 1; + + case ROM_IBMPC: + f=romfopen("ibmpc/pc102782.bin","rb"); + if (!f) break; +// f=fopen("pc081682.bin","rb"); + romfread(rom+0xE000,8192,1,f); + fclose(f); + if (!mem_load_basic("ibmpc")) + break; + return 1; + + case ROM_MEGAPC: + f = romfopen("megapc/41651-bios lo.u18", "rb"); + ff = romfopen("megapc/211253-bios hi.u19", "rb"); + if (!f || !ff) break; + fseek(f, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); + for (c = 0x0000; c < 0x10000; c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + return 1; + + case ROM_AMI486: + f=romfopen("ami486/ami486.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + //is486=1; + return 1; + + case ROM_WIN486: +// f=romfopen("win486/win486.bin","rb"); + f=romfopen("win486/ali1429g.amw","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + //is486=1; + return 1; + + case ROM_PCI486: + f=romfopen("hot-433/hot-433.ami","rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + //is486=1; + return 1; + + case ROM_SIS496: + f = romfopen("sis496/sis496-1.awa", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); + return 1; + + case ROM_430VX: +// f = romfopen("430vx/ga586atv.bin", "rb"); +// f = fopen("430vx/vx29.bin", "rb"); + f = romfopen("430vx/55xwuq0e.bin", "rb"); +// f=romfopen("430vx/430vx","rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + //is486=1; + return 1; + + case ROM_REVENGE: + f = romfopen("revenge/1009af2_.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("revenge/1009af2_.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + fclose(f); + biosmask = 0x1ffff; + //is486=1; + return 1; + case ROM_ENDEAVOR: + f = romfopen("endeavor/1006cb0_.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("endeavor/1006cb0_.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + //is486=1; + return 1; + + case ROM_IBMPS1_2011: +#if 0 + f=romfopen("ibmps1es/ibm_1057757_24-05-90.bin","rb"); + ff=romfopen("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("ibmps1es/f80000.bin", "rb"); + if (!f) break; + fseek(f, 0x60000, SEEK_SET); + romfread(rom, 0x20000, 1, f); + fclose(f); +//#endif + biosmask = 0x1ffff; + return 1; + + case ROM_IBMPS1_2121: + f = romfopen("ibmps1_2121/fc0000.bin", "rb"); + if (!f) break; + fseek(f, 0x20000, SEEK_SET); + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_DESKPRO_386: + f=romfopen("deskpro386/109592-005.u11.bin","rb"); + ff=romfopen("deskpro386/109591-005.u13.bin","rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c+1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + + case ROM_AMIXT: + f = romfopen("amixt/ami_8088_bios_31jan89.bin", "rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; + + case ROM_LTXT: + f = romfopen("ltxt/27c64.bin", "rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + if (!mem_load_basic("ltxt")) + break; + return 1; + + case ROM_LXT3: + f = romfopen("lxt3/27c64d.bin", "rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + if (!mem_load_basic("lxt3")) + break; + return 1; + + case ROM_PX386: /*Phoenix 80386 BIOS*/ + f=romfopen("px386/3iip001l.bin","rb"); + ff=romfopen("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; + + case ROM_DTK386: /*Uses NEAT chipset*/ + f = romfopen("dtk386/3cto001.bin", "rb"); + if (!f) break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + + case ROM_PXXT: + f = romfopen("pxxt/000p001.bin", "rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; + + case ROM_JUKOPC: + f = romfopen("jukopc/000o001.bin", "rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; + + case ROM_IBMPS2_M30_286: + f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_IBMPS2_M50: + f=romfopen("i8550021/90x7423.zm14","rb"); + ff=romfopen("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("i8550021/90x7420.zm13","rb"); + ff=romfopen("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("i8555081/33f8146.zm41","rb"); + ff=romfopen("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("i8580111/15f6637.bin","rb"); + ff=romfopen("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; + + case ROM_ATARIPC3: + f=romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN","rb"); + if (!f) break; + romfread(rom+0x8000,32768,1,f); + fclose(f); + return 1; + + case ROM_IBMXT286: + f = romfopen("ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN", "rb"); + ff =romfopen("ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.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; + + case ROM_EPSON_PCAX: + f = romfopen("epson_pcax/EVAX", "rb"); + ff = romfopen("epson_pcax/ODAX", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + + case ROM_EPSON_PCAX2E: + f = romfopen("epson_pcax2e/EVAXE", "rb"); + ff = romfopen("epson_pcax2e/ODAXE", "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_EPSON_PCAX3: + f = romfopen("epson_pcax3/EVAX3", "rb"); + ff = romfopen("epson_pcax3/ODAX3", "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_T3100E: + loadfont("t3100e/t3100e_font.bin", 5); + f=romfopen("t3100e/t3100e.rom","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + + case ROM_T1000: + loadfont("t1000/t1000font.rom", 2); + f=romfopen("t1000/t1000.rom","rb"); + if (!f) break; + romfread(rom, 0x8000,1,f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; + + case ROM_T1200: + loadfont("t1200/t1000font.rom", 2); + f=romfopen("t1200/t1200_019e.ic15.bin","rb"); + if (!f) break; + romfread(rom, 0x8000,1,f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; + + case ROM_PB_L300SX: + f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); + if (!f) break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + + case ROM_NCR_PC4I: + f=romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN" ,"rb"); + if (!f) break; + romfread(rom, 0x4000, 1, f); + fclose(f); + biosmask = 0x3fff; + return 1; + + case ROM_TO16_PC: + f=romfopen("to16_pc/TO16_103.bin","rb"); + if (!f) break; + romfread(rom+0x8000,32768,1,f); + fclose(f); + return 1; + + case ROM_COMPAQ_PII: + f = romfopen("compaq_pii/109740-001.rom", "rb"); + ff = romfopen("compaq_pii/109739-001.rom", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + + case ROM_ELX_PC425X: + /*PC-425X uses a single ROM chip containing both main and video BIOSes. + First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. + Alternatively, seperate BIOS + video BIOS dumps are supported.*/ + f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); + if (!f) + { + if (!rom_present("elx_pc425x/elx_pc425x_vbios.bin")) + break; + f = romfopen("elx_pc425x/elx_pc425x_bios.bin", "rb"); + if (!f) + break; + } + else + fseek(f, 0x10000, SEEK_SET); + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + + case ROM_PB570: + if (!rom_present("pb570/gd5430.bin")) + break; + f = romfopen("pb570/1007by0r.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("pb570/1007by0r.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + romfread(rom+0xc000, 0x1000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_ZAPPA: + f = romfopen("zappa/1006bs0_.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("zappa/1006bs0_.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_PB520R: + if (!rom_present("pb520r/gd5434.bin")) + break; + f = romfopen("pb520r/1009bc0r.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("pb520r/1009bc0r.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + romfread(rom+0xc000, 0x1000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_COMPAQ_PIP: + f=romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin","rb"); + if (!f) break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; + + case ROM_XI8088: + f = romfopen("xi8088/bios-xi8088.bin", "rb"); /* use the bios without xt-ide because it's configurable in pcem */ + if (!f) break; + if (xi8088_bios_128kb()) + { + /* high bit is flipped in xi8088 */ + romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom, 0x10000, 1, f); + biosmask = 0x1ffff; + } + else + { + /* smaller bios, more UMBs */ + romfread(rom, 0x10000, 1, f); + } + fclose(f); + return 1; + + case ROM_IBMPS2_M70_TYPE3: + f = romfopen("ibmps2_m70_type3/70-a_even.bin","rb"); + ff = romfopen("ibmps2_m70_type3/70-a_odd.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_IBMPS2_M70_TYPE4: + f = romfopen("ibmps2_m70_type4/70-b_even.bin","rb"); + ff = romfopen("ibmps2_m70_type4/70-b_odd.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"); + if (f) fclose(f); + if (ff) fclose(ff); + return 0; +} diff --git a/src/mem_bios.h b/src/mem_bios.h new file mode 100644 index 0000000..e3fc1f8 --- /dev/null +++ b/src/mem_bios.h @@ -0,0 +1 @@ +int loadbios(); From e44ca65ad6125f30cedcda660264f9be968e253c Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Jun 2018 22:08:38 +0100 Subject: [PATCH 0469/1050] Removed old bitrotted Win32 port. --- src/Makefile.mingw | 47 -- src/Makefile.mingw-network | 51 -- src/Makefile.mingw64 | 47 -- src/win-config.c | 914 ---------------------- src/win-config_sel.c | 193 ----- src/win-d3d-fs.cc | 386 ---------- src/win-d3d-fs.h | 10 - src/win-d3d.cc | 303 -------- src/win-d3d.h | 10 - src/win-ddraw-fs.cc | 237 ------ src/win-ddraw-fs.h | 8 - src/win-ddraw.cc | 213 ----- src/win-ddraw.h | 9 - src/win-deviceconfig.c | 352 --------- src/win-hdconf.c | 934 ---------------------- src/win-joystick.cc | 275 ------- src/win-joystickconfig.c | 541 ------------- src/win-keyboard.cc | 47 -- src/win-mouse.cc | 70 -- src/win-networkconfig.c | 213 ----- src/win-status.c | 103 --- src/win-video.c | 49 -- src/win.c | 1497 ------------------------------------ src/win.h | 42 - 24 files changed, 6551 deletions(-) delete mode 100644 src/Makefile.mingw delete mode 100644 src/Makefile.mingw-network delete mode 100644 src/Makefile.mingw64 delete mode 100644 src/win-config.c delete mode 100644 src/win-config_sel.c 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.cc delete mode 100644 src/win-ddraw.h delete mode 100644 src/win-deviceconfig.c delete mode 100644 src/win-hdconf.c delete mode 100644 src/win-joystick.cc delete mode 100644 src/win-joystickconfig.c delete mode 100644 src/win-keyboard.cc delete mode 100644 src/win-mouse.cc delete mode 100644 src/win-networkconfig.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/Makefile.mingw b/src/Makefile.mingw deleted file mode 100644 index 5d74a3f..0000000 --- a/src/Makefile.mingw +++ /dev/null @@ -1,47 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++.exe -CC = gcc.exe -WINDRES = windres.exe -CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.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 xi8088.c xtide.o pc.res -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - - -LIBS = -mwindows -lwinmm -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lstdc++ - -PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem.exe" $(LIBS) - -all : PCem.exe - -clean : - rm *.o - rm *.exe - rm *.res - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CFLAGS) -c $< - -pc.res: pc.rc - $(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff diff --git a/src/Makefile.mingw-network b/src/Makefile.mingw-network deleted file mode 100644 index 853e631..0000000 --- a/src/Makefile.mingw-network +++ /dev/null @@ -1,51 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++.exe -CC = gcc.exe -MAKE = make.exe -WINDRES = windres.exe -CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -DUSE_NETWORKING -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-networkconfig.o win-status.o win-video.o x86seg.o x87.o xi8088.c xtide.o pc.res -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 -NETOBJ = ne2000.o nethandler.o - -LIBS = -mwindows -lwinmm -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lwsock32 -liphlpapi -lstdc++ - -PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) libslirp.a - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) slirp/libslirp.a -o "PCem.exe" $(LIBS) - -libslirp.a: - $(MAKE) -C slirp - -all : libslirp.a PCem.exe - -clean : - rm *.o - rm *.exe - rm *.res - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CFLAGS) -c $< - -pc.res: pc.rc - $(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff -D USE_NETWORKING diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 deleted file mode 100644 index ff492b9..0000000 --- a/src/Makefile.mingw64 +++ /dev/null @@ -1,47 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++.exe -CC = gcc.exe -WINDRES = windres.exe -CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o \ - dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.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 xi8088.c xtide.o pc.res -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - - -LIBS = -mwindows -lwinmm -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lstdc++ - -PCem64.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64.exe" $(LIBS) - -all : PCem64.exe - -clean : - rm *.o - rm *.exe - rm *.res - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CFLAGS) -c $< - -pc.res: pc.rc - $(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff diff --git a/src/win-config.c b/src/win-config.c deleted file mode 100644 index d658f59..0000000 --- a/src/win-config.c +++ /dev/null @@ -1,914 +0,0 @@ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include - -#include "ibm.h" -#include "cpu.h" -#include "device.h" -#include "fdd.h" -#include "gameport.h" -#include "hdd.h" -#include "mem.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" -#ifdef USE_NETWORKING -#include "nethandler.h" -#endif - -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]; -#ifdef USE_NETWORKING -static int settings_network_to_list[20], settings_list_to_network[20]; -#endif -static char *hdd_names[16]; - -int has_been_inited = 0; - -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_vid_list(HWND hdlg, int model) -{ - HWND h = GetDlgItem(hdlg, IDC_COMBOVID); - int c = 0, d = 0; - int found_card = 0; - - 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[model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - 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[model].fixed_gfxcard ? FALSE : TRUE); - - h = GetDlgItem(hdlg, IDC_CHECKVOODOO); - EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_CONFIGUREVOODOO); - EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); -} - -static void recalc_snd_list(HWND hdlg, int model) -{ - HWND h = GetDlgItem(hdlg, IDC_COMBOSND); - int c = 0, d = 0; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - - while (1) - { - char *s = sound_card_getname(c); - - if (!s[0]) - break; - - settings_sound_to_list[c] = d; - - if (sound_card_available(c)) - { - device_t *sound_dev = sound_card_getdevice(c); - - if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[model].flags & MODEL_MCA)) - { - 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); -} - -#ifdef USE_NETWORKING -static void recalc_net_list(HWND hdlg, int model) -{ - HWND h = GetDlgItem(hdlg, IDC_COMBONETCARD); - int c = 0, d = 0; - int set_zero = 0; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - - while (1) - { - char *s = network_card_getname(c); - - if (!s[0]) - break; - - settings_network_to_list[c] = d; - - if (network_card_available(c)) - { - device_t *network_dev = network_card_getdevice(c); - - if (!network_dev || (network_dev->flags & DEVICE_MCA) == (models[model].flags & MODEL_MCA)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - settings_list_to_network[d] = c; - d++; - } - else if (c == network_card_current) - set_zero = 1; - } - - c++; - } - if (set_zero) - SendMessage(h, CB_SETCURSEL, 0, 0); - else - SendMessage(h, CB_SETCURSEL, settings_network_to_list[network_card_current], 0); -} -#endif - -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)) || - (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model].flags & MODEL_MCA)) && c) - { - 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); - - EnableWindow(h, TRUE); - } -} - -static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - char temp_str[256]; - HWND h; - int c, d; - int 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_dynarec; - int cpu_flags; - int temp_fda_type, temp_fdb_type; - int temp_joystick_type; - int cpu_type; - int temp_mouse_type; - int hdd_changed = 0; -#ifdef USE_NETWORKING - int temp_network_card; -#endif - 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); - - recalc_vid_list(hdlg, romstomodel[romset]); - - h = GetDlgItem(hdlg, IDC_COMBOCPUM); - c = 0; - while (models[romstomodel[romset]].cpu[c].cpus != NULL && c < 3) - { - 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); - - recalc_snd_list(hdlg, romstomodel[romset]); - - 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); - - 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_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); - if (!((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128)) - 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); - - 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_COMBODRA); - 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"); - 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_COMBODRB); - 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"); - 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_TEXT_MB); - if ((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128) - 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); - -#ifdef USE_NETWORKING - recalc_net_list(hdlg, romstomodel[romset]); - - h = GetDlgItem(hdlg, IDC_CONFIGURENETCARD); - if (network_card_has_config(network_card_current)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); -#endif - 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) && models[temp_model].ram_granularity < 128) - 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_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_COMBODRA); - temp_fda_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBODRB); - temp_fdb_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 (hdd_names[c]) - hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1); -#ifdef USE_NETWORKING - h = GetDlgItem(hdlg, IDC_COMBONETCARD); - temp_network_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; -#endif - if (temp_model != model || gfx != gfxcard || mem != mem_size || - 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type || hdd_changed -#ifdef USE_NETWORKING - || temp_network_card != network_card_current -#endif - ) - { - if (!has_been_inited || MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",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; - cpu_use_dynarec = temp_dynarec; - mouse_type = temp_mouse_type; -#ifdef USE_NETWORKING - network_card_current = temp_network_card; -#endif - - fdd_set_type(0, temp_fda_type); - fdd_set_type(1, temp_fdb_type); - - if (hdd_names[c]) - strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); - else - strcpy(hdd_controller_name, "none"); - - if (has_been_inited) - { - 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(); - - if (has_been_inited) - saveconfig(NULL); - - speedchanged(); - - joystick_type = temp_joystick_type; - 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)]; - - /*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 < 3) - { - 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) && models[temp_model].ram_granularity < 128) - 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_vid_list(hdlg, temp_model); - - recalc_hdd_list(hdlg, temp_model, 1); - - recalc_snd_list(hdlg, temp_model); -#ifdef USE_NETWORKING - recalc_net_list(hdlg, temp_model); -#endif - } - 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_CONFIGUREVOODOO: - deviceconfig_open(hdlg, (void *)&voodoo_device); - 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; -#ifdef USE_NETWORKING - case IDC_COMBONETCARD: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBONETCARD); - temp_network_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURENETCARD); - if (network_card_has_config(temp_network_card)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - } - break; - - case IDC_CONFIGURENETCARD: - h = GetDlgItem(hdlg, IDC_COMBONETCARD); - temp_network_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); - break; -#endif - } - break; - } - return FALSE; -} - -void config_open(HWND hwnd) -{ - DialogBox(hinstance, TEXT("ConfigureDlg"), hwnd, (DLGPROC)config_dlgproc); -} diff --git a/src/win-config_sel.c b/src/win-config_sel.c deleted file mode 100644 index 4134ce9..0000000 --- a/src/win-config_sel.c +++ /dev/null @@ -1,193 +0,0 @@ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include - -#include "ibm.h" -#include "config.h" -#include "resources.h" -#include "win.h" -#include "paths.h" - -static void config_list_update(HWND hdlg) -{ - char s[512]; - int num, c; - HWND h; - - strcpy(s, configs_path); - put_backslash(s); - strcat(s, "*.cfg"); - pclog("Dir %s\n", s); - - DlgDirList(hdlg, s, IDC_LIST, 0, 0); - - h = GetDlgItem(hdlg, IDC_LIST); - num = SendMessage(h, LB_GETCOUNT, 0, 0); - - for (c = 0; c < num; c++) - { - char *ext; - - SendMessage(h, LB_GETTEXT, c, (LPARAM)s); - ext = get_extension(s); - if (ext && ext[0]) - { - ext--; - *ext = 0; - } - - SendMessage(h, LB_DELETESTRING, c, 0); - SendMessage(h, LB_INSERTSTRING, c, (LPARAM)s); - } -} - -static BOOL CALLBACK config_selection_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - //HWND h; - - switch (message) - { - case WM_INITDIALOG: -// pause = 1; - config_list_update(hdlg); -// h = GetDlgItem(hdlg, IDC_LIST); -// SendMessage(h, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)"AAA"); -// SendMessage(h, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)"BBB"); - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - { - char s[512]; - - int ret = DlgDirSelectEx(hdlg, s, 512, IDC_LIST); - - pclog("DlgDirSelectEx returned %i %s\n", ret, s); - if (s[0]) - { - char cfg[512]; - - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); -// sprintf(cfg, "%s\\configs\\%scfg", configs_path, s); - pclog("Config name %s\n", cfg); - - strcpy(config_file_default, cfg); - - EndDialog(hdlg, 1); -// pause = 0; - return TRUE; - } - } - return FALSE; - - case IDCANCEL: - EndDialog(hdlg, 0); -// pause = 0; - return TRUE; - - case IDC_NEW: - { - char s[512]; - int c; - - strcpy(s, configs_path); - put_backslash(s); - strcat(s, "*.cfg"); - for (c = 0; c < strlen(s); c++) - { - if (s[c] == '/') - s[c] = '\\'; - } - - if (!getsfile(hdlg, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", s, s, "cfg")) - { - config_open(hdlg); - - saveconfig(openfilestring); - } - - config_list_update(hdlg); - - return TRUE; - } - - case IDC_CONFIG: - { - char s[512]; - - int ret = DlgDirSelectEx(hdlg, s, 512, IDC_LIST); - - pclog("DlgDirSelectEx returned %i %s\n", ret, s); - if (s[0]) - { - char cfg[512]; - - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); - pclog("Config name %s\n", cfg); - - loadconfig(cfg); - config_open(hdlg); - saveconfig(cfg); - } - - return TRUE; - } - - case IDC_HDCONF: - { - char s[512]; - - int ret = DlgDirSelectEx(hdlg, s, 512, IDC_LIST); - - pclog("DlgDirSelectEx returned %i %s\n", ret, s); - if (s[0]) - { - char cfg[512]; - - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); - pclog("Config name %s\n", cfg); - - loadconfig(cfg); - hdconf_open(hdlg); - saveconfig(cfg); - } - - return TRUE; - } -#ifdef USE_NETWORKING - case IDC_NETWORK: - networkconfig_open(hdlg); - return TRUE; -#endif - } - break; - } - return FALSE; -} - -int config_selection_open(HWND hwnd, int inited) -{ - int ret; - - has_been_inited = inited; - - ret = DialogBox(hinstance, TEXT("ConfigureSelectionDlg"), hwnd, (DLGPROC)config_selection_dlgproc); - - has_been_inited = 1; - - return ret; -} diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc deleted file mode 100644 index 5e0e8b6..0000000 --- a/src/win-d3d-fs.cc +++ /dev/null @@ -1,386 +0,0 @@ -#include -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "resources.h" -#include "video.h" -#include "win-d3d-fs.h" -#include "win.h" - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(); - -static void d3d_fs_init_objects(); -static void d3d_fs_close_objects(); -static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); - -extern "C" void video_blit_complete(); - -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 - DWORD color; - FLOAT tu, tv; -}; - -static CUSTOMVERTEX d3d_verts[] = -{ - { 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}, - - { 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} -}; - -void d3d_fs_init(HWND h) -{ - d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); - d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); - - d3d_hwnd = h; - - d3d_device_window = CreateWindowEx ( - 0, - szSubClassName, - "PCem v12", - WS_POPUP, - CW_USEDEFAULT, - CW_USEDEFAULT, - 640, - 480, - HWND_DESKTOP, - NULL, - NULL, - NULL - ); - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - - 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; - - if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) - fatal("CreateDevice failed\n"); - - d3d_fs_init_objects(); - - video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen; -} - -static void d3d_fs_close_objects() -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -static void d3d_fs_init_objects() -{ - D3DLOCKED_RECT dr; - int y; - RECT r; - - if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL))) - fatal("CreateVertexBuffer failed\n"); - - if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) - fatal("CreateTexture failed\n"); - - 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 *)((uintptr_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() -{ - 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() -{ - d3d_fs_close_objects(); - 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 = 0, t = 0, r = 0, b = 0; - - if (y1 == y2) - { - 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; - - hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); - if (hr == D3D_OK) - { - for (yy = y1; yy < y2; yy++) - 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); - } - else - { - video_blit_complete(); - return; - } - } - 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)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK && readflash && vid_disc_indicator) - { - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); - readflash = 0; - } - - 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); -} diff --git a/src/win-d3d-fs.h b/src/win-d3d-fs.h deleted file mode 100644 index 821537d..0000000 --- a/src/win-d3d-fs.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - void 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 c138fad..0000000 --- a/src/win-d3d.cc +++ /dev/null @@ -1,303 +0,0 @@ -#include -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "resources.h" -#include "win-d3d.h" -#include "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 video_blit_complete(); - -void d3d_init_objects(); -void d3d_close_objects(); -void d3d_blit_memtoscreen(int x, int y, int y1, int y2, 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 - DWORD color; - FLOAT tu, tv; -}; - -static CUSTOMVERTEX d3d_verts[] = -{ - { 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}, - - { 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} -}; - -void d3d_init(HWND h) -{ - d3d_hwnd = h; - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - - 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; - - if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) - fatal("CreateDevice failed\n"); - - d3d_init_objects(); - - video_blit_memtoscreen_func = d3d_blit_memtoscreen; -} - -void d3d_close_objects() -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -void d3d_init_objects() -{ - D3DLOCKED_RECT dr; - int y; - RECT r; - - if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL))) - fatal("CreateVertexBuffer failed\n"); - - if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) - fatal("CreateTexture failed\n"); - - 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 *)((uintptr_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() -{ - HRESULT hr; - - if (!d3ddev) - return; - 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() -{ - 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 (y1 == y2 || h <= 0) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - hr = d3dTexture->LockRect(0, &dr, &r, 0); - if (hr == D3D_OK) - { - for (yy = y1; yy < y2; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) - 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); - } - else - { - video_blit_complete(); - return; - } - - 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; - 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 - 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_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 && readflash && vid_disc_indicator) - { - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 6, 2); - readflash = 0; - } - - 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); -} diff --git a/src/win-d3d.h b/src/win-d3d.h deleted file mode 100644 index bd90795..0000000 --- a/src/win-d3d.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - void 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 aa929a0..0000000 --- a/src/win-ddraw-fs.cc +++ /dev/null @@ -1,237 +0,0 @@ -#include -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win-ddraw-fs.h" -#include "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 ddraw_fs_init(HWND h); -extern "C" void ddraw_fs_close(); - -extern "C" void video_blit_complete(); - -static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, 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 LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; -static DDSURFACEDESC2 ddsd; - -static HWND ddraw_hwnd; -static int ddraw_w, ddraw_h; - -void ddraw_fs_init(HWND h) -{ - ddraw_w = GetSystemMetrics(SM_CXSCREEN); - ddraw_h = GetSystemMetrics(SM_CYSCREEN); - - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - fatal("DirectDrawCreate failed\n"); - - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) - fatal("QueryInterface failed\n"); - - lpdd->Release(); - lpdd = NULL; - - atexit(ddraw_fs_close); - - if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW | - DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT))) - fatal("SetCooperativeLevel failed\n"); - - if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) - fatal("SetDisplayMode failed\n"); - - 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(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) - fatal("CreateSurface failed\n"); - - ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; - if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2))) - fatal("CreateSurface back failed\n"); - - 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(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - fatal("CreateSurface back failed\n"); - } - - pclog("DDRAW_INIT complete\n"); - ddraw_hwnd = h; - video_blit_memtoscreen_func = ddraw_fs_blit_memtoscreen; -} - -void ddraw_fs_close() -{ - 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 (lpdd4) - { - lpdd4->Release(); - lpdd4 = 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; - - 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++) - memcpy((void *)((uintptr_t)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 && vid_disc_indicator) - { - 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); - } -} diff --git a/src/win-ddraw-fs.h b/src/win-ddraw-fs.h deleted file mode 100644 index 122b98d..0000000 --- a/src/win-ddraw-fs.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - void ddraw_fs_init(HWND h); - void ddraw_fs_close(); -#ifdef __cplusplus -} -#endif diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc deleted file mode 100644 index 88b4756..0000000 --- a/src/win-ddraw.cc +++ /dev/null @@ -1,213 +0,0 @@ -#include -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win-ddraw.h" -#include "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 ddraw_init(HWND h); -extern "C" void ddraw_close(); - -extern "C" void video_blit_complete(); - -static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, 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 LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; -static DDSURFACEDESC2 ddsd; - -static HWND ddraw_hwnd; - -void ddraw_init(HWND h) -{ - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - fatal("DirectDrawCreate failed\n"); - - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) - fatal("QueryInterface failed\n"); - - lpdd->Release(); - lpdd = NULL; - - atexit(ddraw_close); - - if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_NORMAL))) - fatal("SetCooperativeLevel failed\n"); - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) - fatal("CreateSurface failed\n"); - - 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(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - fatal("CreateSurface back failed\n"); - } - - 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(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) - { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) - fatal("CreateSurface back failed\n"); - } - - if (FAILED(lpdd4->CreateClipper(0, &lpdd_clipper, NULL))) - fatal("CreateClipper failed\n"); - if (FAILED(lpdd_clipper->SetHWnd(0, h))) - fatal("SetHWnd failed\n"); - if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) - fatal("SetClipper failed\n"); - - pclog("DDRAW_INIT complete\n"); - ddraw_hwnd = h; - video_blit_memtoscreen_func = ddraw_blit_memtoscreen; -} - -void ddraw_close() -{ - 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 (lpdd4) - { - lpdd4->Release(); - lpdd4 = 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 (h <= 0) - { - video_blit_complete(); - return; - } - - 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) < buffer32->h) - memcpy((void *)((uintptr_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 && vid_disc_indicator) - { - readflash = 0; - 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 *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - } - 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); - } -} diff --git a/src/win-ddraw.h b/src/win-ddraw.h deleted file mode 100644 index 7561cca..0000000 --- a/src/win-ddraw.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - void 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 45780a1..0000000 --- a/src/win-deviceconfig.c +++ /dev/null @@ -1,352 +0,0 @@ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "plat-midi.h" -#include "resources.h" -#include "win.h" - -static device_t *config_device; - -static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - 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; - HWND h = GetDlgItem(hdlg, id); - int val_int; - int num; - char s[80]; - - switch (config->type) - { - case CONFIG_BINARY: - val_int = config_get_int(CFG_MACHINE, 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(CFG_MACHINE, 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_MIDI: - val_int = config_get_int(CFG_MACHINE, 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++; - } - } - 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; - HWND h = GetDlgItem(hdlg, id); - int val_int; - - switch (config->type) - { - case CONFIG_BINARY: - val_int = config_get_int(CFG_MACHINE, 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(CFG_MACHINE, 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_MIDI: - val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (val_int != c) - changed = 1; - - id += 2; - break; - } - config++; - } - - if (!changed) - { - EndDialog(hdlg, 0); - return TRUE; - } - - if (has_been_inited && MessageBox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", 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; - HWND h = GetDlgItem(hdlg, id); - - switch (config->type) - { - case CONFIG_BINARY: - config_set_int(CFG_MACHINE, 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(CFG_MACHINE, config_device->name, config->name, selection->value); - - id += 2; - break; - - case CONFIG_MIDI: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int(CFG_MACHINE, NULL, config->name, c); - - id += 2; - break; - } - config++; - } - - saveconfig(NULL); - - if (has_been_inited) - 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 (((uintptr_t)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 = 200; - 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: - case CONFIG_MIDI: - /*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 (((uintptr_t)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 (((uintptr_t)data) & 2) - data++; - - y += 20; - break; - } - - if (((uintptr_t)data) & 2) - data++; - - config++; - } - - 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->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 (((uintptr_t)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, (DLGPROC)deviceconfig_dlgproc); - - free(data_block); -} diff --git a/src/win-hdconf.c b/src/win-hdconf.c deleted file mode 100644 index c1107e9..0000000 --- a/src/win-hdconf.c +++ /dev/null @@ -1,934 +0,0 @@ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "hdd.h" -#include "ide.h" -#include "resources.h" -#include "win.h" - -static struct -{ - int cylinders; - int heads; -} hd_types[] = -{ - {306, 4}, {615, 4}, {615, 6}, {940, 8}, - {940, 6}, {615, 4}, {462, 8}, {733, 5}, - {900, 15}, {820, 3}, {855, 5}, {855, 7}, - {306, 8}, {733, 7}, {0, 0}, {612, 4}, - {977, 5}, {977, 7}, {1024, 7}, {733, 5}, - {733, 7}, {733, 5}, {306, 4}, {925, 7}, - {925, 9}, {754, 7}, {754, 11}, {699, 7}, - {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, - {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, - {615, 8}, {987, 3}, {462, 7}, {820, 6}, - {977, 5}, {981, 5}, {830, 7}, {830, 10}, - {917, 15}, {1224, 15} -}; - -static int hd_changed = 0; - -static char hd_new_name[512]; -static int hd_new_spt, hd_new_hpc, hd_new_cyl; -static int hd_new_type; -static int new_cdrom_channel; - -static void check_hd_type(off64_t sz) -{ - int c; - - hd_new_type = 0; - - if (hdd_controller_current_is_mfm()) - { - for (c = 0; c < 46; c++) - { - if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) - { - hd_new_spt = 17; - hd_new_hpc = hd_types[c].heads; - hd_new_cyl = hd_types[c].cylinders; - hd_new_type = c+1; - return; - } - } - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - } - else - { - if ((sz % 17) == 0 && sz <= 142606336) - { - hd_new_spt = 17; - - if (sz <= 26738688) - hd_new_hpc = 4; - else if ((sz % 3072) == 0 && sz <= 53477376) - hd_new_hpc = 6; - else - { - for (c=5;c<16;c++) - { - if((sz % (c * 512)) == 0 && sz <= 1024*c*17*512) break; - if (c == 5) c++; - } - hd_new_hpc = c; - } - hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; - } - else - { - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - } - } -} - -static void update_hdd_cdrom(HWND hdlg) -{ - HWND h; - - h = GetDlgItem(hdlg, IDC_CHDD); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 0) ? 0 : 1, 0); - h = GetDlgItem(hdlg, IDC_CCDROM); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 0) ? 1 : 0, 0); - h = GetDlgItem(hdlg, IDC_DHDD); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 1) ? 0 : 1, 0); - h = GetDlgItem(hdlg, IDC_DCDROM); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 1) ? 1 : 0, 0); - h = GetDlgItem(hdlg, IDC_EHDD); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 2) ? 0 : 1, 0); - h = GetDlgItem(hdlg, IDC_ECDROM); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 2) ? 1 : 0, 0); - h = GetDlgItem(hdlg, IDC_FHDD); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 3) ? 0 : 1, 0); - h = GetDlgItem(hdlg, IDC_FCDROM); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == 3) ? 1 : 0, 0); -} - -static BOOL CALLBACK hdnew_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - char s[260]; - HWND h; - int c; - PcemHDC hd[4]; - FILE *f; - uint8_t buf[512]; - int hd_type; - - switch (message) - { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_EDIT1); - sprintf(s, "%i", 63); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT2); - sprintf(s, "%i", 16); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT3); - sprintf(s, "%i", 511); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - h = GetDlgItem(hdlg, IDC_EDITC); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)""); - - h = GetDlgItem(hdlg, IDC_TEXT1); - sprintf(s, "Size : %imb", (((511*16*63)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - -// hd_type = 0; - h = GetDlgItem(hdlg, IDC_HDTYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Custom type"); - for (c = 1; c <= 46; c++) - { - sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - } - SendMessage(h, CB_SETCURSEL, 0, 0); - - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - 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","PCem error",MB_OK); - return TRUE; - } - h = GetDlgItem(hdlg, IDC_EDIT1); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd_new_spt); - h = GetDlgItem(hdlg, IDC_EDIT2); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd_new_hpc); - h = GetDlgItem(hdlg, IDC_EDIT3); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd_new_cyl); - - if (hd_new_spt > 63) - { - MessageBox(ghwnd, "Drive has too many sectors (maximum is 63)", "PCem error", MB_OK); - return TRUE; - } - if (hd_new_hpc > 16) - { - MessageBox(ghwnd, "Drive has too many heads (maximum is 16)", "PCem error", MB_OK); - return TRUE; - } - if (hd_new_cyl > 16383) - { - MessageBox(ghwnd, "Drive has too many cylinders (maximum is 16383)", "PCem error", MB_OK); - return TRUE; - } - - f = fopen64(hd_new_name, "wb"); - if (!f) - { - MessageBox(ghwnd, "Can't open file for write", "PCem error", MB_OK); - return TRUE; - } - memset(buf, 0, 512); - for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) - fwrite(buf, 512, 1, f); - fclose(f); - - MessageBox(ghwnd, "Remember to partition and format the new drive", "PCem", MB_OK); - - EndDialog(hdlg, 1); - return TRUE; - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!getsfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "", NULL, "img")) - { - h = GetDlgItem(hdlg, IDC_EDITC); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - } - return TRUE; - - case IDC_EDIT1: case IDC_EDIT2: case IDC_EDIT3: - h = GetDlgItem(hdlg, IDC_EDIT1); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - pclog("EDIT1: %s\n", s); - sscanf(s, "%i", &hd[0].spt); - h = GetDlgItem(hdlg, IDC_EDIT2); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - pclog("EDIT2: %s\n", s); - sscanf(s, "%i", &hd[0].hpc); - h = GetDlgItem(hdlg, IDC_EDIT3); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - pclog("EDIT3: %s\n", s); - sscanf(s, "%i", &hd[0].tracks); - - h = GetDlgItem(hdlg, IDC_TEXT1); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_type = 0; - for (c = 1; c <= 46; c++) - { - pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt,17, hd[0].hpc,hd_types[c-1].heads, hd[0].tracks,hd_types[c-1].cylinders); - if (hd[0].spt == 17 && hd[0].hpc == hd_types[c-1].heads && hd[0].tracks == hd_types[c-1].cylinders) - { - hd_type = c; - break; - } - } - h = GetDlgItem(hdlg, IDC_HDTYPE); - SendMessage(h, CB_SETCURSEL, hd_type, 0); - - return TRUE; - - case IDC_HDTYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_HDTYPE); - hd_type = SendMessage(h, CB_GETCURSEL, 0, 0); - if (hd_type) - { - h = GetDlgItem(hdlg, IDC_EDIT3); - sprintf(s, "%i", hd_types[hd_type-1].cylinders); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT2); - sprintf(s, "%i", hd_types[hd_type-1].heads); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT1); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)"17"); - - h = GetDlgItem(hdlg, IDC_TEXT1); - sprintf(s, "Size : %imb", (int)(((uint64_t)hd_types[hd_type-1].cylinders*hd_types[hd_type-1].heads*17*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - } - } - return TRUE; - } - break; - - } - return FALSE; -} - -BOOL CALLBACK hdsize_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - char s[260]; - HWND h; - PcemHDC hd[2]; - int c; - - switch (message) - { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_HDTYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Custom type"); - for (c = 1; c <= 46; c++) - { - sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c-1].cylinders, hd_types[c-1].heads, (hd_types[c-1].cylinders * hd_types[c-1].heads * 17 * 512) / (1024 * 1024)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - } - SendMessage(h, CB_SETCURSEL, hd_new_type, 0); - - h = GetDlgItem(hdlg, IDC_EDIT1); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT2); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT3); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - h = GetDlgItem(hdlg, IDC_TEXT1); - sprintf(s, "Size : %imb", (int)((((uint64_t)hd_new_spt*(uint64_t)hd_new_hpc*(uint64_t)hd_new_cyl)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - h = GetDlgItem(hdlg, IDC_EDIT1); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd_new_spt); - h = GetDlgItem(hdlg, IDC_EDIT2); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd_new_hpc); - h = GetDlgItem(hdlg, IDC_EDIT3); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd_new_cyl); - - if (hd_new_spt > 63) - { - MessageBox(ghwnd,"Drive has too many sectors (maximum is 63)","PCem error",MB_OK); - return TRUE; - } - if (hd_new_hpc > 16) - { - MessageBox(ghwnd,"Drive has too many heads (maximum is 16)","PCem error",MB_OK); - return TRUE; - } - if (hd_new_cyl > 16383) - { - MessageBox(ghwnd,"Drive has too many cylinders (maximum is 16383)","PCem error",MB_OK); - return TRUE; - } - - EndDialog(hdlg,1); - return TRUE; - case IDCANCEL: - EndDialog(hdlg,0); - return TRUE; - - case IDC_EDIT1: case IDC_EDIT2: case IDC_EDIT3: - h = GetDlgItem(hdlg, IDC_EDIT1); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = GetDlgItem(hdlg, IDC_EDIT2); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = GetDlgItem(hdlg, IDC_EDIT3); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].tracks); - - h = GetDlgItem(hdlg, IDC_TEXT1); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - return TRUE; - } - break; - - } - return FALSE; -} - -static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - char s[260]; - HWND h; - PcemHDC hd[4]; - FILE *f; - off64_t sz; - switch (message) - { - case WM_INITDIALOG: - pause = 1; - hd[0] = hdc[0]; - hd[1] = hdc[1]; - hd[2] = hdc[2]; - hd[3] = hdc[3]; - hd_changed = 0; - - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); - sprintf(s, "%i", hdc[0].spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC); - sprintf(s, "%i", hdc[0].hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL); - sprintf(s, "%i", hdc[0].tracks); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)ide_fn[0]); - - h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); - sprintf(s, "%i", hdc[1].spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_HPC); - sprintf(s, "%i", hdc[1].hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_CYL); - sprintf(s, "%i", hdc[1].tracks); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h= GetDlgItem(hdlg, IDC_EDIT_D_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)ide_fn[1]); - - h = GetDlgItem(hdlg, IDC_EDIT_E_SPT); - sprintf(s, "%i", hdc[2].spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_HPC); - sprintf(s, "%i", hdc[2].hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_CYL); - sprintf(s, "%i", hdc[2].tracks); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h= GetDlgItem(hdlg, IDC_EDIT_E_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)ide_fn[2]); - - h = GetDlgItem(hdlg, IDC_EDIT_F_SPT); - sprintf(s, "%i", hdc[3].spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_HPC); - sprintf(s, "%i", hdc[3].hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_CYL); - sprintf(s, "%i", hdc[3].tracks); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h= GetDlgItem(hdlg, IDC_EDIT_F_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)ide_fn[3]); - - h = GetDlgItem(hdlg, IDC_TEXT_C_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[0].tracks*(uint64_t)hd[0].hpc)*(uint64_t)hd[0].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - h = GetDlgItem(hdlg, IDC_TEXT_D_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[1].tracks*(uint64_t)hd[1].hpc)*(uint64_t)hd[1].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - h = GetDlgItem(hdlg, IDC_TEXT_E_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[2].tracks*(uint64_t)hd[2].hpc)*(uint64_t)hd[2].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - h = GetDlgItem(hdlg, IDC_TEXT_F_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd[3].tracks*(uint64_t)hd[3].hpc)*(uint64_t)hd[3].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - new_cdrom_channel = cdrom_channel; - - update_hdd_cdrom(hdlg); - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - if (hd_changed || cdrom_channel != new_cdrom_channel) - { - if (!has_been_inited || MessageBox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", MB_OKCANCEL) == IDOK) - { - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].tracks); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN); - SendMessage(h, WM_GETTEXT, 511, (LPARAM)ide_fn[0]); - - h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[1].spt); - h = GetDlgItem(hdlg, IDC_EDIT_D_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[1].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_D_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[1].tracks); - h = GetDlgItem(hdlg, IDC_EDIT_D_FN); - SendMessage(h, WM_GETTEXT, 511, (LPARAM)ide_fn[1]); - - h = GetDlgItem(hdlg, IDC_EDIT_E_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[2].spt); - h = GetDlgItem(hdlg, IDC_EDIT_E_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[2].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_E_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[2].tracks); - h = GetDlgItem(hdlg, IDC_EDIT_E_FN); - SendMessage(h, WM_GETTEXT, 511, (LPARAM)ide_fn[2]); - - h = GetDlgItem(hdlg, IDC_EDIT_F_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[3].spt); - h = GetDlgItem(hdlg, IDC_EDIT_F_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[3].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_F_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[3].tracks); - h = GetDlgItem(hdlg, IDC_EDIT_F_FN); - SendMessage(h, WM_GETTEXT, 511, (LPARAM)ide_fn[3]); - - hdc[0] = hd[0]; - hdc[1] = hd[1]; - hdc[2] = hd[2]; - hdc[3] = hd[3]; - - cdrom_channel = new_cdrom_channel; - - if (has_been_inited) - { - saveconfig(NULL); - - resetpchard(); - } - } - } - case IDCANCEL: - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - - case IDC_EJECTC: - hd[0].spt = 0; - hd[0].hpc = 0; - hd[0].tracks = 0; - ide_fn[0][0] = 0; - SetDlgItemText(hdlg, IDC_EDIT_C_SPT, "0"); - SetDlgItemText(hdlg, IDC_EDIT_C_HPC, "0"); - SetDlgItemText(hdlg, IDC_EDIT_C_CYL, "0"); - SetDlgItemText(hdlg, IDC_EDIT_C_FN, ""); - hd_changed = 1; - return TRUE; - case IDC_EJECTD: - hd[1].spt = 0; - hd[1].hpc = 0; - hd[1].tracks = 0; - ide_fn[1][0] = 0; - SetDlgItemText(hdlg, IDC_EDIT_D_SPT, "0"); - SetDlgItemText(hdlg, IDC_EDIT_D_HPC, "0"); - SetDlgItemText(hdlg, IDC_EDIT_D_CYL, "0"); - SetDlgItemText(hdlg, IDC_EDIT_D_FN, ""); - hd_changed = 1; - return TRUE; - case IDC_EJECTE: - hd[2].spt = 0; - hd[2].hpc = 0; - hd[2].tracks = 0; - ide_fn[2][0] = 0; - SetDlgItemText(hdlg, IDC_EDIT_E_SPT, "0"); - SetDlgItemText(hdlg, IDC_EDIT_E_HPC, "0"); - SetDlgItemText(hdlg, IDC_EDIT_E_CYL, "0"); - SetDlgItemText(hdlg, IDC_EDIT_E_FN, ""); - hd_changed = 1; - return TRUE; - case IDC_EJECTF: - hd[3].spt = 0; - hd[3].hpc = 0; - hd[3].tracks = 0; - ide_fn[3][0] = 0; - SetDlgItemText(hdlg, IDC_EDIT_F_SPT, "0"); - SetDlgItemText(hdlg, IDC_EDIT_F_HPC, "0"); - SetDlgItemText(hdlg, IDC_EDIT_F_CYL, "0"); - SetDlgItemText(hdlg, IDC_EDIT_F_FN, ""); - hd_changed = 1; - return TRUE; - - case IDC_CNEW: - if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdNewDlgMfm") : TEXT("HdNewDlg"), hdlg, (DLGPROC)hdnew_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)hd_new_name); - - h = GetDlgItem(hdlg, IDC_TEXT_C_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - return TRUE; - - case IDC_CFILE: - if (!getfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - MessageBox(ghwnd,"Can't open file for read","PCem error",MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdSizeDlgMfm") : TEXT("HdSizeDlg"), hdlg, (DLGPROC)hdsize_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - - h= GetDlgItem(hdlg, IDC_TEXT_C_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - } - return TRUE; - - case IDC_DNEW: - if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdNewDlgMfm") : TEXT("HdNewDlg"), hdlg, (DLGPROC)hdnew_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)hd_new_name); - - h= GetDlgItem(hdlg, IDC_TEXT_D_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - return TRUE; - - case IDC_DFILE: - if (!getfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - MessageBox(ghwnd,"Can't open file for read","PCem error",MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (DialogBox(hinstance, hdd_controller_current_is_mfm() ? TEXT("HdSizeDlgMfm") : TEXT("HdSizeDlg"), hdlg, (DLGPROC)hdsize_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_D_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - - h = GetDlgItem(hdlg, IDC_TEXT_D_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - } - return TRUE; - - case IDC_ENEW: - if (DialogBox(hinstance, TEXT("HdNewDlg"), hdlg, (DLGPROC)hdnew_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_E_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)hd_new_name); - - h= GetDlgItem(hdlg, IDC_TEXT_E_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - return TRUE; - - case IDC_EFILE: - if (!getfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - MessageBox(ghwnd,"Can't open file for read","PCem error",MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, (DLGPROC)hdsize_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_E_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_E_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - - h = GetDlgItem(hdlg, IDC_TEXT_E_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - } - return TRUE; - - case IDC_FNEW: - if (DialogBox(hinstance, TEXT("HdNewDlg"), hdlg, (DLGPROC)hdnew_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_F_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)hd_new_name); - - h= GetDlgItem(hdlg, IDC_TEXT_F_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - return TRUE; - - case IDC_FFILE: - if (!getfile(hdlg, "Hard disc image (*.IMG)\0*.IMG\0All files (*.*)\0*.*\0", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - MessageBox(ghwnd,"Can't open file for read","PCem error",MB_OK); - return TRUE; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(sz); - - if (DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, (DLGPROC)hdsize_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_F_SPT); - sprintf(s, "%i", hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_HPC); - sprintf(s, "%i", hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_CYL); - sprintf(s, "%i", hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_F_FN); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - - h = GetDlgItem(hdlg, IDC_TEXT_F_SIZE); - sprintf(s, "Size : %imb", (int)(((((uint64_t)hd_new_cyl*(uint64_t)hd_new_hpc)*(uint64_t)hd_new_spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - } - return TRUE; - - case IDC_EDIT_C_SPT: case IDC_EDIT_C_HPC: case IDC_EDIT_C_CYL: - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[0].tracks); - - h = GetDlgItem(hdlg, IDC_TEXT_C_SIZE); - sprintf(s, "Size : %imb", ((((hd[0].tracks*hd[0].hpc)*hd[0].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - return TRUE; - - case IDC_EDIT_D_SPT: case IDC_EDIT_D_HPC: case IDC_EDIT_D_CYL: - h = GetDlgItem(hdlg, IDC_EDIT_D_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[1].spt); - h = GetDlgItem(hdlg, IDC_EDIT_D_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[1].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_D_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[1].tracks); - - h = GetDlgItem(hdlg, IDC_TEXT_D_SIZE); - sprintf(s, "Size : %imb", ((((hd[1].tracks*hd[1].hpc)*hd[1].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - return TRUE; - - case IDC_EDIT_E_SPT: case IDC_EDIT_E_HPC: case IDC_EDIT_E_CYL: - h = GetDlgItem(hdlg, IDC_EDIT_E_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[2].spt); - h = GetDlgItem(hdlg, IDC_EDIT_E_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[2].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_E_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[2].tracks); - - h = GetDlgItem(hdlg, IDC_TEXT_E_SIZE); - sprintf(s, "Size : %imb", ((((hd[2].tracks*hd[2].hpc)*hd[2].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - return TRUE; - - case IDC_EDIT_F_SPT: case IDC_EDIT_F_HPC: case IDC_EDIT_F_CYL: - h = GetDlgItem(hdlg, IDC_EDIT_F_SPT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[3].spt); - h = GetDlgItem(hdlg, IDC_EDIT_F_HPC); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[3].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_F_CYL); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%i", &hd[3].tracks); - - h = GetDlgItem(hdlg, IDC_TEXT_F_SIZE); - sprintf(s, "Size : %imb", ((((hd[3].tracks*hd[3].hpc)*hd[3].spt)*512)/1024)/1024); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - return TRUE; - - case IDC_CHDD: - if (new_cdrom_channel == 0) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - case IDC_DHDD: - if (new_cdrom_channel == 1) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - case IDC_EHDD: - if (new_cdrom_channel == 2) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - case IDC_FHDD: - if (new_cdrom_channel == 3) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - - case IDC_CCDROM: - new_cdrom_channel = 0; - update_hdd_cdrom(hdlg); - return TRUE; - case IDC_DCDROM: - new_cdrom_channel = 1; - update_hdd_cdrom(hdlg); - return TRUE; - case IDC_ECDROM: - new_cdrom_channel = 2; - update_hdd_cdrom(hdlg); - return TRUE; - case IDC_FCDROM: - new_cdrom_channel = 3; - update_hdd_cdrom(hdlg); - return TRUE; - } - break; - - } - return FALSE; -} - -void hdconf_open(HWND hwnd) -{ - if (hdd_controller_current_is_mfm()) - DialogBox(hinstance, TEXT("HdConfDlgMfm"), hwnd, (DLGPROC)hdconf_dlgproc); - else - DialogBox(hinstance, TEXT("HdConfDlg"), hwnd, (DLGPROC)hdconf_dlgproc); -} diff --git a/src/win-joystick.cc b/src/win-joystick.cc deleted file mode 100644 index 48ed2cc..0000000 --- a/src/win-joystick.cc +++ /dev/null @@ -1,275 +0,0 @@ -#define DIRECTINPUT_VERSION 0x0700 -#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 LPDIRECTINPUT lpdi; -static LPDIRECTINPUTDEVICE2 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; - - atexit(joystick_close); - - joysticks_present = 0; - - if (FAILED(DirectInputCreate(hinstance, DIRECTINPUT_VERSION, &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++) - { - LPDIRECTINPUTDEVICE 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_IDirectInputDevice2, (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 48ede2c..0000000 --- a/src/win-joystickconfig.c +++ /dev/null @@ -1,541 +0,0 @@ -#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 "resources.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) -{ - switch (message) - { - case WM_INITDIALOG: - { - HWND h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - int c; - int id = IDC_CONFIG_BASE + 2; - int 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) - { - int nr_axes = plat_joystick_state[joystick-1].nr_axes; - int 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++) - { - int mapping; - - 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: - { - HWND h; - int c; - int 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) -{ -// 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; - 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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)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 (((uintptr_t)data) & 2) - data++; - - y += 20; - } - - 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->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 (((uintptr_t)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, (DLGPROC)joystickconfig_dlgproc); - - free(data_block); -} diff --git a/src/win-keyboard.cc b/src/win-keyboard.cc deleted file mode 100644 index 360dad4..0000000 --- a/src/win-keyboard.cc +++ /dev/null @@ -1,47 +0,0 @@ -#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 pcem_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 pcem_key[272]; - -void keyboard_init() -{ - atexit(keyboard_close); - - memset(pcem_key, 0, sizeof(pcem_key)); - pclog("Keyboard initialized!\n"); -} - -void keyboard_close() -{ -} - -void keyboard_poll_host() -{ - int c; - - for (c = 0; c < 272; c++) - pcem_key[c] = rawinputkey[c]; - - if ((rawinputkey[0x1D] || rawinputkey[0x9D]) && - (rawinputkey[0x38] || rawinputkey[0xB8]) && - (rawinputkey[0x51] || rawinputkey[0xD1]) && - video_fullscreen) - leave_fullscreen(); -} diff --git a/src/win-mouse.cc b/src/win-mouse.cc deleted file mode 100644 index df37162..0000000 --- a/src/win-mouse.cc +++ /dev/null @@ -1,70 +0,0 @@ -#define DIRECTINPUT_VERSION 0x0700 -#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 LPDIRECTINPUT lpdi; -static LPDIRECTINPUTDEVICE lpdi_mouse = NULL; -static DIMOUSESTATE mousestate; -static int mouse_x = 0, mouse_y = 0, mouse_z = 0; -int mouse_buttons = 0; - -void mouse_init() -{ - if (FAILED(DirectInputCreate(hinstance, DIRECTINPUT_VERSION, &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_z = 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-networkconfig.c b/src/win-networkconfig.c deleted file mode 100644 index 0a14710..0000000 --- a/src/win-networkconfig.c +++ /dev/null @@ -1,213 +0,0 @@ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include - -#include "ibm.h" -#include "config.h" -#include "nethandler.h" -#include "resources.h" -#include "win.h" - -static HINSTANCE net_hLib = 0; -static char *net_lib_name = "wpcap.dll"; -static pcap_if_t *alldevs; -static char *dev_name[20]; - -int (*_pcap_findalldevs)(pcap_if_t **, char *); -void (*_pcap_freealldevs)(pcap_if_t *); -pcap_t *(*_pcap_open_live)(const char *, int, int, int, char *); -int (*_pcap_datalink)(pcap_t *); -void (*_pcap_close)(pcap_t *); - -#define ETH_DEV_NAME_MAX 256 /* maximum device name size */ -#define ETH_DEV_DESC_MAX 256 /* maximum device description size */ -#define ETH_MAX_DEVICE 30 /* maximum ethernet devices */ -#define ETH_PROMISC 1 /* promiscuous mode = true */ -#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */ -#define PCAP_READ_TIMEOUT -1 - -static int get_network_name(char *dev_name, char *regval) -{ - if (dev_name[strlen( "\\Device\\NPF_" )] == '{') - { - char regkey[2048]; - HKEY reghnd; - - sprintf(regkey, "SYSTEM\\CurrentControlSet\\Control\\Network\\" - "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", dev_name+ - strlen("\\Device\\NPF_")); - - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0, KEY_QUERY_VALUE, ®hnd) == ERROR_SUCCESS) - { - DWORD reglen = 2048; - DWORD regtype; - - if (RegQueryValueExA(reghnd, "Name", NULL, ®type, (LPBYTE)regval, ®len) == ERROR_SUCCESS) - { - RegCloseKey (reghnd); - - if ((regtype != REG_SZ) || (reglen > 2048)) - return -1; - - /*Name now in regval*/ - return 0; - } - RegCloseKey (reghnd); - } - } - return -1; -} - -static BOOL CALLBACK networkconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - pcap_if_t *dev; - char errbuf[PCAP_ERRBUF_SIZE]; - int type; - - switch (message) - { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"SLiRP"); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, FALSE); - - net_hLib = LoadLibraryA(net_lib_name); - - if (net_hLib) - { - int c = 0; - int match = 0; - - _pcap_findalldevs = (void *)GetProcAddress(net_hLib, "pcap_findalldevs"); - _pcap_freealldevs = (void *)GetProcAddress(net_hLib, "pcap_freealldevs"); - _pcap_open_live = (void *)GetProcAddress(net_hLib, "pcap_open_live"); - _pcap_datalink = (void *)GetProcAddress(net_hLib, "pcap_datalink"); - _pcap_close = (void *)GetProcAddress(net_hLib, "pcap_close"); - - if (_pcap_findalldevs(&alldevs, errbuf) != -1) - { - char *pcap_device = config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); - - h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); - - for (dev = alldevs; dev; dev = dev->next) - { - pcap_t *conn = _pcap_open_live(dev->name, ETH_MAX_PACKET, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf); - int datalink; - - if (conn) - { - datalink = _pcap_datalink(conn); - _pcap_close(conn); - } - - if (conn && datalink == DLT_EN10MB) - { - char desc[2048]; - char s[2048]; - - if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) - continue; - - if (pcap_device) - { - if (!strcmp(pcap_device, dev->name)) - match = c; - } - - dev_name[c++] = dev->name; - if (get_network_name(dev->name, desc)) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)dev->name); - else - { - sprintf(s, "%s - %s", dev->name, desc); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - } - } - } - } - if (c) - { - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"PCAP"); - - if (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_PCAP) - { - SendMessage(h, CB_SETCURSEL, 1, 0); - h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); - SendMessage(h, CB_SETCURSEL, match, 0); - EnableWindow(h, TRUE); - } - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - type = SendMessage(h, CB_GETCURSEL, 0, 0); - if (type) /*PCAP*/ - { - int dev; - - h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); - dev = SendMessage(h, CB_GETCURSEL, 0, 0); - - config_set_int(CFG_GLOBAL, NULL, "net_type", NET_PCAP); - config_set_string(CFG_GLOBAL, NULL, "pcap_device", dev_name[dev]); - } - else /*SLiRP*/ - { - config_set_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP); - config_set_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); - } - saveconfig_global_only(); - case IDCANCEL: - EndDialog(hdlg, 0); - if (net_hLib) - { - _pcap_freealldevs(alldevs); - _pcap_findalldevs = NULL; - _pcap_freealldevs = NULL; - _pcap_open_live = NULL; - _pcap_datalink = NULL; - _pcap_close = NULL; - FreeLibrary(net_hLib); - } - return TRUE; - - case IDC_COMBONETTYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - int type; - - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBONETDEVICE); - if (!type) - EnableWindow(h, FALSE); - else - EnableWindow(h, TRUE); - - return TRUE; - } - } - break; - } - return FALSE; -} - -void networkconfig_open(HWND hwnd) -{ - DialogBox(hinstance, TEXT("NetworkConfDlg"), hwnd, (DLGPROC)networkconfig_dlgproc); -} diff --git a/src/win-status.c b/src/win-status.c deleted file mode 100644 index f60fa2c..0000000 --- a/src/win-status.c +++ /dev/null @@ -1,103 +0,0 @@ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "device.h" -#include "video.h" -#include "resources.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]; - 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" - -/* "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" - "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" -// "\nFully recompiled ins %% : %f%%" - ,mips, - flops, -/*#ifndef DYNAREC - sreadlnum, - swritelnum, -#endif*/ - 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) -// ((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; - 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, (DLGPROC)status_dlgproc); - ShowWindow(status_hwnd, SW_SHOW); -} diff --git a/src/win-video.c b/src/win-video.c deleted file mode 100644 index 7f0ca5c..0000000 --- a/src/win-video.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include "video.h" - -BITMAP *screen; - -void hline(BITMAP *b, int x1, int y, int x2, int col) -{ - if (y < 0 || y >= buffer32->h) - return; - - for (; x1 < x2; x1++) - ((uint32_t *)b->line[y])[x1] = col; -} - -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 22079bc..0000000 --- a/src/win.c +++ /dev/null @@ -1,1497 +0,0 @@ -#define _WIN32_WINNT 0x0501 -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include - -#include - -#include -#include -#include -#include -#include "ibm.h" -#include "cdrom-ioctl.h" -#include "cdrom-image.h" -#include "config.h" -#include "cpu.h" -#include "device.h" -#include "disc.h" -#include "disc_img.h" -#include "ide.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "nvr.h" -#include "resources.h" -#include "sound.h" -#include "thread.h" -#include "video.h" - -#include "plat-joystick.h" -#include "plat-midi.h" -#include "plat-mouse.h" -#include "plat-keyboard.h" - -#include "win.h" -#include "win-ddraw.h" -#include "win-ddraw-fs.h" -#include "win-d3d.h" -#include "win-d3d-fs.h" -#include "paths.h" -//#include "win-opengl.h" - -#ifdef DRMINGW -#include -#endif - -#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 -{ - void (*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 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); - -HWND ghwnd; - -HINSTANCE hinstance; - -HMENU menu; - -extern int updatestatus; - -int pause=0; - -static int win_doresize = 0; - -static int leave_fullscreen_flag = 0; - -void warning(const char *format, ...) -{ - char buf[1024]; - va_list ap; - - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - - MessageBox(ghwnd, buf, "PCem", MB_OK); -} - -void updatewindowsize(int x, int y) -{ - if (vid_resize) return; - - if (video_force_aspect_ration) - { - float aspect = (float)x / (float)y; - - if (aspect > 1.33) - y = (x * 3) / 4; - else - x = (y * 4) / 3; - } - - winsizex=x; winsizey=y; - win_doresize = 1; -} - -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; - -void mainthread(LPVOID param) -{ - int frames = 0; - DWORD old_time, new_time; - -// Sleep(500); - 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) - { - uint64_t start_time = timer_read(); - uint64_t end_time; - 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) - { - RECT r; - video_wait_for_blit(); - 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, - 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); -} - -static void initmenu(void) -{ - int c; - HMENU m; - char s[32]; - m=GetSubMenu(menu,2); /*Settings*/ - m=GetSubMenu(m,1); /*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_REAL+c,s); - } - } -} - -int dir_exists(char *path) -{ - DWORD dwAttrib = GetFileAttributes(path); - - return (dwAttrib != INVALID_FILE_ATTRIBUTES && - (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); -} - -void get_pcem_path(char *s, int size) -{ - GetModuleFileName(hinstance, s, size); -} - -void set_window_title(const char *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 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() -{ - char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - char *valueName = "Scancode Map"; - 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; - pclog("Preparing scan code map list...\n"); - /* 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, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS) - { - UINT32 *bufEx2 = (UINT32 *) buf; - int scMapCount = bufEx2[2]; - pclog("%lu scan code mappings found!\n", scMapCount); - if ((bufSize != 0) && (scMapCount != 0)) - { - UINT16 *bufEx = (UINT16 *) (buf + 12); - pclog("More than zero scan code mappings found, processing...\n"); - 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); - - scancode_map[scancode_unmapped] = scancode_mapped; - pclog("Scan code mapping %u detected: %X -> %X\n", scancode_unmapped, scancode_mapped, scancode_map[scancode_unmapped]); - } - pclog("Done processing!\n"); - } - } - RegCloseKey(hKey); - } - pclog("Done preparing!\n"); -} - -static char **argv; -static int argc; -static char *argbuf; - -static void process_command_line() -{ - char *cmdline; - int argc_max; - int i, q; - - cmdline = GetCommandLine(); - i = strlen(cmdline) + 1; - argbuf = malloc(i); - memcpy(argbuf, cmdline, i); - - argc = 0; - argc_max = 64; - argv = malloc(sizeof(char *) * argc_max); - if (!argv) - { - free(argbuf); - return; - } - - i = 0; - - /* parse commandline into argc/argv format */ - while (argbuf[i]) - { - while (argbuf[i] == ' ') - i++; - - if (argbuf[i]) - { - if ((argbuf[i] == '\'') || (argbuf[i] == '"')) - { - 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(char *) * argc_max); - if (!argv) - { - free(argbuf); - return; - } - } - - while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != ' '))) - i++; - - if (argbuf[i]) - { - argbuf[i] = 0; - i++; - } - //pclog("Arg %i - %s\n",argc-1,argv[argc-1]); - } - } - - argv[argc] = NULL; -} - -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; - LARGE_INTEGER qpc_freq; - -#ifdef DRMINGW - ExcHndlInit(); -#endif - - process_command_line(); - - 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 (NULL, IDI_APPLICATION); - wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); - wincl.hCursor = NULL;//LoadCursor (NULL, IDC_ARROW); - 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; - - paths_init(); - - timeBeginPeriod(1); - - atexit(releasemouse); - - QueryPerformanceFrequency(&qpc_freq); - timer_freq = qpc_freq.QuadPart; - - sound_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) - { - MessageBox(NULL, "No ROMs present!\nYou must have at least one romset to use PCem.","PCem fatal error",MB_OK); - return 0; - } - - romset = d; - - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); - - while (1) - { - quited = 0; - - if (!config_override) - { - if (!config_selection_open(NULL, 0)) - break; - } - - ghMutex = CreateMutex(NULL, FALSE, NULL); - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - initmenu(); - - /* The class is registered, let's create the program*/ - hwnd = CreateWindowEx ( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - "PCem v12", /* Title Text */ - WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* 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); - - 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; - - loadconfig(NULL); - - 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); - - if (!cdrom_enabled) - CheckMenuItem(menu, IDM_CDROM_DISABLED, MF_CHECKED); - else - { - if (cdrom_drive == CDROM_IMAGE) - CheckMenuItem(menu, IDM_CDROM_IMAGE, MF_CHECKED); - else - CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); - } - if (vid_resize) - CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); - if (video_force_aspect_ration) - CheckMenuItem(menu, IDM_VID_ASPECT, 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_BPB_DISABLE, bpb_disable ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_DISC, vid_disc_indicator ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_BUF_100MS, (sound_buf_len == 100) ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_BUF_200MS, (sound_buf_len == 200) ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_BUF_400MS, (sound_buf_len == 400) ? MF_CHECKED : MF_UNCHECKED); - - if (!loadbios()) - { - if (romset != -1) - MessageBox(hwnd,"Configured romset not available.\nDefaulting to available romset.","PCem error",MB_OK); - for (c = 0; c < ROM_MAX; c++) - { - if (romspresent[c]) - { - romset = c; - model = model_getmodel(romset); - break; - } - } - } - - if (!video_card_available(video_old_to_new(gfxcard))) - { - if (romset != -1) - MessageBox(hwnd,"Configured video BIOS not available.\nDefaulting to available romset.","PCem error",MB_OK); - for (c = GFX_MAX-1; c >= 0; c--) - { - if (gfx_present[c]) - { - gfxcard = c; - break; - } - } - } - - loadbios(); - resetpchard(); - - vid_apis[0][vid_api].init(ghwnd); - - mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); - SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); - - updatewindowsize(640, 480); - - keyboard_init(); - mouse_init(); - joystick_init(); - midi_init(); - - if (start_in_fullscreen) - { - startblit(); - 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 (window_remember) - { - MoveWindow(hwnd, window_x, window_y, - window_w, - window_h, - TRUE); - } - - /* Run the message loop. It will run until GetMessage() returns 0 */ - while (!quited) - { - while (GetMessage(&messages,NULL,0,0) && !quited) - { - if (messages.message==WM_QUIT) quited=1; - TranslateMessage(&messages); - DispatchMessage(&messages); - if ((pcem_key[KEY_LCONTROL] || pcem_key[KEY_RCONTROL]) && pcem_key[KEY_END] && mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - } - - quited=1; - } - - startblit(); -// pclog("Sleep 1000\n"); - Sleep(200); -// pclog("TerminateThread\n"); - TerminateThread(mainthreadh,0); - -// endblit(); - -// pclog("Quited? %i\n",quited); -// pclog("Closepc\n"); - savenvr(); - if (save_window_pos && window_remember) - saveconfig(NULL); -// pclog("dumpregs\n"); - - vid_apis[video_fullscreen][vid_api].close(); - - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - } - - keyboard_close(); - mouse_close(); - joystick_close(); - midi_close(); - - DestroyWindow(hwnd); - CloseHandle(ghMutex); - - if (config_override) - break; - } - - closepc(); - - timeEndPeriod(1); -// dumpregs(); - - 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, char *dir, char *ext) -{ - 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 = dir; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - ofn.lpstrDefExt = ext; - - // 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; - -LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) -{ - if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); - - KBDLLHOOKSTRUCT* 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 - BOOL 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 atapi_close(void) -{ - switch (cdrom_drive) - { - case CDROM_IMAGE: - image_close(); - break; - default: - ioctl_close(); - break; - } -} - -LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - HMENU hmenu; - RECT rect; - char temp_image_path[1024]; - int new_cdrom_drive; -// pclog("Message %i %08X\n",message,message); - switch (message) - { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - break; - - case WM_COMMAND: -// pclog("WM_COMMAND %i\n",LOWORD(wParam)); - hmenu=GetMenu(hwnd); - switch (LOWORD(wParam)) - { - case IDM_FILE_RESET: - pause=1; - Sleep(100); - savenvr(); - resetpc(); - pause=0; - break; - case IDM_FILE_HRESET: - pause=1; - Sleep(100); - savenvr(); - resetpchard(); - pause=0; - break; - case IDM_FILE_RESET_CAD: - pause=1; - Sleep(100); - savenvr(); - resetpc_cad(); - pause=0; - break; - case IDM_FILE_EXIT: - PostMessage(hwnd, WM_CLOSE, 0, 0); - break; - case IDM_DISC_A: - if (!getfile(hwnd,"Disc image (*.IMG;*.IMA;*.FDI)\0*.IMG;*.IMA;*.FDI\0All files (*.*)\0*.*\0",discfns[0])) - { - disc_close(0); - disc_load(0, openfilestring); - saveconfig(NULL); - } - break; - case IDM_DISC_B: - if (!getfile(hwnd,"Disc image (*.IMG;*.IMA;*.FDI)\0*.IMG;*.IMA;*.FDI\0All files (*.*)\0*.*\0",discfns[1])) - { - disc_close(1); - disc_load(1, openfilestring); - saveconfig(NULL); - } - break; - case IDM_EJECT_A: - disc_close(0); - saveconfig(NULL); - break; - case IDM_EJECT_B: - disc_close(1); - saveconfig(NULL); - break; - case IDM_BPB_DISABLE: - bpb_disable = !bpb_disable; - CheckMenuItem(hmenu, IDM_BPB_DISABLE, bpb_disable ? MF_CHECKED : MF_UNCHECKED); - saveconfig(NULL); - break; - case IDM_HDCONF: - hdconf_open(hwnd); - break; - case IDM_CONFIG: - config_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); - GetWindowRect(hwnd,&rect); - SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - saveconfig(NULL); - break; - case IDM_VID_ASPECT: - video_force_aspect_ration = !video_force_aspect_ration; - CheckMenuItem(hmenu, IDM_VID_ASPECT, video_force_aspect_ration ? MF_CHECKED : MF_UNCHECKED); - saveconfig(NULL); - 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(NULL); - 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(ghwnd); - endblit(); - saveconfig(NULL); - device_force_redraw(); - break; - - case IDM_VID_FULLSCREEN: - if (video_fullscreen_first) - { - video_fullscreen_first = 0; - MessageBox(hwnd, "Use CTRL + ALT + PAGE DOWN to return to windowed mode", "PCem", MB_OK); - } - 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(NULL); - break; - - case IDM_VID_DISC: - vid_disc_indicator = !vid_disc_indicator; - CheckMenuItem(hmenu, IDM_VID_DISC, vid_disc_indicator ? MF_CHECKED : MF_UNCHECKED); - saveconfig(NULL); - break; - - case IDM_BUF_100MS: case IDM_BUF_200MS: case IDM_BUF_400MS: - switch (LOWORD(wParam)) - { - case IDM_BUF_100MS: - sound_buf_len = 100; - break; - case IDM_BUF_200MS: - sound_buf_len = 200; - break; - case IDM_BUF_400MS: - sound_buf_len = 400; - break; - } - CheckMenuItem(hmenu, IDM_BUF_100MS, (sound_buf_len == 100) ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_BUF_200MS, (sound_buf_len == 200) ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_BUF_400MS, (sound_buf_len == 400) ? MF_CHECKED : MF_UNCHECKED); - saveconfig(NULL); - break; - - case IDM_CDROM_DISABLED: - if (cdrom_enabled) - { - if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL) != IDOK) - break; - } - if (!cdrom_enabled) - { - /* Switching from disabled to disabled. Do nothing. */ - break; - } - atapi->exit(); - atapi_close(); - ioctl_set_drive(0); - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_CHECKED); - CheckMenuItem(hmenu, IDM_CDROM_IMAGE, 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(NULL); - resetpchard(); - pause = 0; - } - break; - - case IDM_CDROM_EMPTY: - if (!cdrom_enabled) - { - if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL) != IDOK) - break; - } - if ((cdrom_drive == 0) && cdrom_enabled) - { - /* Switch from empty to empty. Do nothing. */ - break; - } - atapi->exit(); - atapi_close(); - ioctl_set_drive(0); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - atapi_insert_cdrom(); - } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); - old_cdrom_drive = cdrom_drive; - cdrom_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED); - saveconfig(NULL); - if (!cdrom_enabled) - { - pause = 1; - Sleep(100); - cdrom_enabled = 1; - saveconfig(NULL); - resetpchard(); - pause = 0; - } - break; - - case IDM_CDROM_IMAGE: - if (!getfile(hwnd,"CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0",image_path)) - { - if (!cdrom_enabled) - { - if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL) != IDOK) - break; - } - old_cdrom_drive = cdrom_drive; - strcpy(temp_image_path, openfilestring); - if ((strcmp(image_path, temp_image_path) == 0) && (cdrom_drive == CDROM_IMAGE) && cdrom_enabled) - { - /* Switching from ISO to the same ISO. Do nothing. */ - break; - } - atapi->exit(); - atapi_close(); - image_open(temp_image_path); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - atapi_insert_cdrom(); - } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); - cdrom_drive = CDROM_IMAGE; - CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_CHECKED); - saveconfig(NULL); - if (!cdrom_enabled) - { - pause = 1; - Sleep(100); - cdrom_enabled = 1; - saveconfig(NULL); - resetpchard(); - pause = 0; - } - } - break; - - default: - if (LOWORD(wParam)>=IDM_CDROM_REAL && LOWORD(wParam)<(IDM_CDROM_REAL+100)) - { - if (!cdrom_enabled) - { - if (MessageBox(NULL,"This will reset PCem!\nOkay to continue?","PCem",MB_OKCANCEL) != IDOK) - break; - } - new_cdrom_drive = LOWORD(wParam)-IDM_CDROM_REAL; - if ((cdrom_drive == new_cdrom_drive) && cdrom_enabled) - { - /* Switching to the same drive. Do nothing. */ - break; - } - old_cdrom_drive = cdrom_drive; - atapi->exit(); - atapi_close(); - ioctl_set_drive(new_cdrom_drive); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - atapi_insert_cdrom(); - } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); - saveconfig(NULL); - if (!cdrom_enabled) - { - pause = 1; - Sleep(100); - cdrom_enabled = 1; - saveconfig(NULL); - resetpchard(); - 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); - - /* Here we read the raw input data for the keyboard */ - GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); - - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) - { - 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)) - { - 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); - } - } - free(raw); - - } - break; - - case WM_SETFOCUS: - infocus=1; - // QueryPerformanceCounter(&counter_posold); -// pclog("Set focus!\n"); - break; - case WM_KILLFOCUS: - infocus=0; - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } -// pclog("Lost focus!\n"); - memset(rawinputkey, 0, sizeof(rawinputkey)); - if (video_fullscreen) - leave_fullscreen_flag = 1; - 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; -// ShowCursor(FALSE); - 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: -// if (key[KEY_ALT] || key[KEY_ALTGR]) return 0; - break; - - case WM_SIZING: - if (video_force_aspect_ration && vid_resize) - { - RECT *r = (RECT *)lParam; - int x = r->right - r->left; - int y = r->bottom - r->top; - float aspect = (float)x / (float)y; - - switch (wParam) - { - case WMSZ_LEFT: - case WMSZ_RIGHT: - r->bottom = r->top + ((x * 3) / 4); - break; - case WMSZ_TOP: - case WMSZ_BOTTOM: - r->right = r->left + ((y * 4) / 3); - break; - - case WMSZ_TOPLEFT: - if (aspect > 1.33) - r->top = r->bottom - ((x * 3) / 4); - else - r->left = r->right - ((y * 4) / 3); - break; - case WMSZ_TOPRIGHT: - if (aspect > 1.33) - r->top = r->bottom - ((x * 3) / 4); - else - r->right = r->left + ((y * 4) / 3); - break; - case WMSZ_BOTTOMLEFT: - if (aspect > 1.33) - r->bottom = r->top + ((x * 3) / 4); - else - r->left = r->right - ((y * 4) / 3); - break; - case WMSZ_BOTTOMRIGHT: - if (aspect > 1.33) - r->bottom = r->top + ((x * 3) / 4); - else - r->right = r->left + ((y * 4) / 3); - break; - } - - return TRUE; - } - break; - - case WM_SIZE: - winsizex=lParam&0xFFFF; - winsizey=lParam>>16; - - 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) - { - 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: -// if (mousecapture) - return 0; -// return DefWindowProc (hwnd, message, wParam, lParam); - - - case WM_DESTROY: - UnhookWindowsHookEx( hKeyboardHook ); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - - case WM_SYSCOMMAND: - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) - return 0; /*disable ALT key for menu*/ - - default: -// pclog("Def %08X %i\n",message,message); - 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; -} diff --git a/src/win.h b/src/win.h deleted file mode 100644 index e4f6212..0000000 --- a/src/win.h +++ /dev/null @@ -1,42 +0,0 @@ -extern HINSTANCE hinstance; -extern HWND ghwnd; -extern int mousecapture; - -#ifdef __cplusplus -extern "C" { -#endif - -#define szClassName "PCemMainWnd" -#define szSubClassName "PCemSubWnd" - -void leave_fullscreen(); - -#ifdef __cplusplus -} -#endif - - -void status_open(HWND hwnd); -extern HWND status_hwnd; -extern int status_is_open; - -void hdconf_open(HWND hwnd); - -void config_open(HWND hwnd); - -int config_selection_open(HWND hwnd, int inited); - -struct device_t; - -void deviceconfig_open(HWND hwnd, struct device_t *device); -void joystickconfig_open(HWND hwnd, int joy_nr, int type); -void networkconfig_open(HWND hwnd); - -extern char openfilestring[260]; - -int getfile(HWND hwnd, char *f, char *fn); -int getsfile(HWND hwnd, char *f, char *fn, char *dir, char *ext); - -extern int pause; - -extern int has_been_inited; From e6dce0920b08dab704e90ac695ac9a0fef01f0d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 5 Jun 2018 18:22:47 +0100 Subject: [PATCH 0470/1050] Disable SDL thread naming on Windows. Fixes running PCem through GDB. --- src/wx-sdl2-display-win.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 939e74c..f1062d5 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -306,6 +306,7 @@ LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR int display_init() { + SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1"); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { printf("SDL could not initialize! Error: %s\n", SDL_GetError()); From 03fe25d8184aa25dd23d8a2c52684b1aa36ef431 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 17 Jun 2018 20:26:15 +0100 Subject: [PATCH 0471/1050] First stage of dynamic recompiler rewrite. Basic IR generation calls C implementation of all instructions. Backend generation implemented for x86, x86-64, ARM and ARM64. --- Makefile.in | 24 +- configure | 380 +- configure.ac | 14 +- src/386_dynarec.c | 1 + src/386_dynarec_ops.c | 92 +- src/Makefile.am | 14 +- src/Makefile.in | 1620 ++++++-- src/codegen.c | 43 + src/codegen.h | 52 +- src/codegen_backend.c | 416 ++ src/codegen_backend.h | 65 + src/codegen_backend_arm.c | 101 + src/codegen_backend_arm.h | 33 + src/codegen_backend_arm64.c | 115 + src/codegen_backend_arm64.h | 40 + src/codegen_backend_arm64_defs.h | 72 + src/codegen_backend_arm64_uops.c | 300 ++ src/codegen_backend_arm_defs.h | 44 + src/codegen_backend_arm_uops.c | 314 ++ src/codegen_backend_x86-64.c | 156 + src/codegen_backend_x86-64.h | 16 + src/codegen_backend_x86-64_defs.h | 8 + src/codegen_backend_x86-64_uops.c | 232 ++ src/codegen_backend_x86.c | 121 + src/codegen_backend_x86.h | 16 + src/codegen_backend_x86_defs.h | 8 + src/codegen_backend_x86_uops.c | 195 + src/codegen_ir.c | 34 + src/codegen_ir.h | 5 + src/codegen_ir_defs.h | 152 + src/codegen_ops.c | 591 --- src/codegen_ops_arith.h | 1028 ----- src/codegen_ops_fpu.h | 645 --- src/codegen_ops_jump.h | 270 -- src/codegen_ops_logic.h | 564 --- src/codegen_ops_misc.h | 269 -- src/codegen_ops_mmx.h | 277 -- src/codegen_ops_mov.h | 656 --- src/codegen_ops_shift.h | 125 - src/codegen_ops_stack.h | 269 -- src/codegen_ops_x86-64.h | 6213 ----------------------------- src/codegen_ops_x86.h | 3995 ------------------- src/codegen_ops_xchg.h | 93 - src/codegen_x86.c | 2180 ---------- src/codegen_x86.h | 42 - src/wx-utils.cc | 1 + 46 files changed, 4134 insertions(+), 17767 deletions(-) create mode 100644 src/codegen_backend.c create mode 100644 src/codegen_backend.h create mode 100644 src/codegen_backend_arm.c create mode 100644 src/codegen_backend_arm.h create mode 100644 src/codegen_backend_arm64.c create mode 100644 src/codegen_backend_arm64.h create mode 100644 src/codegen_backend_arm64_defs.h create mode 100644 src/codegen_backend_arm64_uops.c create mode 100644 src/codegen_backend_arm_defs.h create mode 100644 src/codegen_backend_arm_uops.c create mode 100644 src/codegen_backend_x86-64.c create mode 100644 src/codegen_backend_x86-64.h create mode 100644 src/codegen_backend_x86-64_defs.h create mode 100644 src/codegen_backend_x86-64_uops.c create mode 100644 src/codegen_backend_x86.c create mode 100644 src/codegen_backend_x86.h create mode 100644 src/codegen_backend_x86_defs.h create mode 100644 src/codegen_backend_x86_uops.c create mode 100644 src/codegen_ir.c create mode 100644 src/codegen_ir.h create mode 100644 src/codegen_ir_defs.h delete mode 100644 src/codegen_ops.c delete mode 100644 src/codegen_ops_arith.h delete mode 100644 src/codegen_ops_fpu.h delete mode 100644 src/codegen_ops_jump.h delete mode 100644 src/codegen_ops_logic.h delete mode 100644 src/codegen_ops_misc.h delete mode 100644 src/codegen_ops_mmx.h delete mode 100644 src/codegen_ops_mov.h delete mode 100644 src/codegen_ops_shift.h delete mode 100644 src/codegen_ops_stack.h delete mode 100644 src/codegen_ops_x86-64.h delete mode 100644 src/codegen_ops_x86.h delete mode 100644 src/codegen_ops_xchg.h delete mode 100644 src/codegen_x86.c delete mode 100644 src/codegen_x86.h diff --git a/Makefile.in b/Makefile.in index 903d123..bcd0ae0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -133,7 +133,7 @@ am__recursive_targets = \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck + cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -308,7 +308,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -342,8 +341,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -461,7 +460,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -526,7 +528,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -552,7 +554,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -570,7 +572,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -580,7 +582,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/configure b/configure index 1aa97de..a6186e3 100755 --- a/configure +++ b/configure @@ -590,6 +590,8 @@ LTLIBOBJS LIBOBJS OS_MACOSX_FALSE OS_MACOSX_TRUE +OS_OTHER_FALSE +OS_OTHER_TRUE OS_WINDOWS_FALSE OS_WINDOWS_TRUE OS_LINUX_FALSE @@ -622,6 +624,10 @@ USE_NETWORKING_FALSE USE_NETWORKING_TRUE USE_WX_FALSE USE_WX_TRUE +CPU_ARM64_FALSE +CPU_ARM64_TRUE +CPU_ARM_FALSE +CPU_ARM_TRUE CPU_X86_64_FALSE CPU_X86_64_TRUE CPU_I386_FALSE @@ -641,7 +647,6 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR OBJEXT @@ -705,7 +710,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -724,7 +728,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -798,7 +803,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1051,15 +1055,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1197,7 +1192,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1350,7 +1345,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -2130,7 +2124,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac -am__api_version='1.15' +am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2646,8 +2640,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -2698,7 +2692,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3560,45 +3554,45 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -4220,10 +4214,20 @@ $as_echo "${host_cpu}" >&6; } x86_64) CPU=x86_64 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 +$as_echo "${host_cpu}" >&6; } + ;; + armv7l) + CPU=arm + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 +$as_echo "${host_cpu}" >&6; } + ;; + aarch64) + CPU=arm64 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 $as_echo "${host_cpu}" >&6; } ;; *) - as_fn_error $? "Unsupported CPU." "$LINENO" 5 + as_fn_error $? "Unsupported CPU. ${host_cpu}" "$LINENO" 5 ;; esac @@ -4243,9 +4247,25 @@ else CPU_X86_64_FALSE= fi + if test "$CPU" = "arm"; then + CPU_ARM_TRUE= + CPU_ARM_FALSE='#' +else + CPU_ARM_TRUE='#' + CPU_ARM_FALSE= +fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5 -$as_echo_n "checking for off64_t... " >&6; } + if test "$CPU" = "arm64"; then + CPU_ARM64_TRUE= + CPU_ARM64_FALSE='#' +else + CPU_ARM64_TRUE='#' + CPU_ARM64_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t $CPU" >&5 +$as_echo_n "checking for off64_t $CPU... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4265,6 +4285,11 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext +case "$host" in + *-*-freebsd*) # has off64_t but no fopen64/etc. + has_lfs="no" + ;; +esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_lfs" >&5 $as_echo "$has_lfs" >&6; } @@ -4464,8 +4489,8 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 -$as_echo_n "checking for SDL... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 +$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -4505,7 +4530,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -4523,7 +4548,7 @@ fi sdl_pc=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } sdl_pc=no else @@ -5213,6 +5238,7 @@ fi build_macosx="no" build_linux="no" build_win="no" +build_other="no" case "$host" in *-*-darwin*) @@ -5317,7 +5343,7 @@ fi SET_MAKE='MAKE=mingw32-make' ;; - *) + *-*-linux*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 $as_echo_n "checking for glGetError in -lGL... " >&6; } if ${ac_cv_lib_GL_glGetError+:} false; then : @@ -5418,6 +5444,107 @@ fi build_linux="yes" ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +$as_echo_n "checking for glGetError in -lGL... " >&6; } +if ${ac_cv_lib_GL_glGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glGetError (); +int +main () +{ +return glGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_glGetError=yes +else + ac_cv_lib_GL_glGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +$as_echo "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGL 1 +_ACEOF + + LIBS="-lGL $LIBS" + +else + \ + echo "You need to install the OpenGL library." + exit -1 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +$as_echo_n "checking for alGetError in -lopenal... " >&6; } +if ${ac_cv_lib_openal_alGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopenal $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char alGetError (); +int +main () +{ +return alGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_openal_alGetError=yes +else + ac_cv_lib_openal_alGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +$as_echo "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBOPENAL 1 +_ACEOF + + LIBS="-lopenal $LIBS" + +else + \ + echo "You need to install the OpenAL library." + exit -1 +fi + + build_other="yes" + ;; esac LIBS="$LIBS $WX_LIBS $SDL_LIBS" @@ -5438,6 +5565,14 @@ else OS_WINDOWS_FALSE= fi + if test "$build_other" = "yes"; then + OS_OTHER_TRUE= + OS_OTHER_FALSE='#' +else + OS_OTHER_TRUE='#' + OS_OTHER_FALSE= +fi + if test "$build_macosx" = "yes"; then OS_MACOSX_TRUE= OS_MACOSX_FALSE='#' @@ -5634,6 +5769,14 @@ if test -z "${CPU_X86_64_TRUE}" && test -z "${CPU_X86_64_FALSE}"; then as_fn_error $? "conditional \"CPU_X86_64\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${CPU_ARM_TRUE}" && test -z "${CPU_ARM_FALSE}"; then + as_fn_error $? "conditional \"CPU_ARM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CPU_ARM64_TRUE}" && test -z "${CPU_ARM64_FALSE}"; then + as_fn_error $? "conditional \"CPU_ARM64\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${USE_WX_TRUE}" && test -z "${USE_WX_FALSE}"; then as_fn_error $? "conditional \"USE_WX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -5658,6 +5801,10 @@ if test -z "${OS_WINDOWS_TRUE}" && test -z "${OS_WINDOWS_FALSE}"; then as_fn_error $? "conditional \"OS_WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${OS_OTHER_TRUE}" && test -z "${OS_OTHER_FALSE}"; then + as_fn_error $? "conditional \"OS_OTHER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${OS_MACOSX_TRUE}" && test -z "${OS_MACOSX_FALSE}"; then as_fn_error $? "conditional \"OS_MACOSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -6224,7 +6371,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" _ACEOF @@ -6670,29 +6817,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -6710,53 +6863,48 @@ $as_echo X"$mf" | q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)[^/].*/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; diff --git a/configure.ac b/configure.ac index 4a30d37..e4a6932 100644 --- a/configure.ac +++ b/configure.ac @@ -64,15 +64,25 @@ case "${host_cpu}" in CPU=x86_64 AC_MSG_RESULT(${host_cpu}) ;; + armv7l) + CPU=arm + AC_MSG_RESULT(${host_cpu}) + ;; + aarch64) + CPU=arm64 + AC_MSG_RESULT(${host_cpu}) + ;; *) - AC_MSG_ERROR([Unsupported CPU.]) + AC_MSG_ERROR([Unsupported CPU. ${host_cpu}]) ;; esac AM_CONDITIONAL(CPU_I386, test "$CPU" = "i386") AM_CONDITIONAL(CPU_X86_64, test "$CPU" = "x86_64") +AM_CONDITIONAL(CPU_ARM, test "$CPU" = "arm") +AM_CONDITIONAL(CPU_ARM64, test "$CPU" = "arm64") -AC_MSG_CHECKING([for off64_t]) +AC_MSG_CHECKING([for off64_t $CPU]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],[[off64_t n=0;]])],[has_lfs="yes"],[has_lfs="no"]) case "$host" in *-*-freebsd*) # has off64_t but no fopen64/etc. diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 2ccc1dd..4dff9e7 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -8,6 +8,7 @@ #include "x87.h" #include "mem.h" #include "codegen.h" +#include "codegen_backend.h" #include "cpu.h" #include "fdc.h" #include "nmi.h" diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index 5be12c1..23c8036 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -23,6 +23,64 @@ static inline void fetch_ea_32_long(uint32_t rmdat) eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; ea_rseg = cpu_state.ea_seg->seg; + if (cpu_rm == 4) + { + uint8_t sib = rmdat >> 8; + + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + 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; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) + { + easeg = ss; + ea_rseg = SS; + cpu_state.ea_seg = &_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } + else + { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) + { + if (cpu_rm == 5 && !cpu_state.ssegs) + { + easeg = ss; + ea_rseg = SS; + cpu_state.ea_seg = &_ss; + } + if (cpu_mod == 1) + { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } + else + { + cpu_state.eaaddr += getlong(); + } + } + else if (cpu_rm == 5) + { + cpu_state.eaaddr = getlong(); + } + } if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; @@ -38,6 +96,33 @@ static inline void fetch_ea_16_long(uint32_t rmdat) eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; ea_rseg = cpu_state.ea_seg->seg; + if (!cpu_mod && cpu_rm == 6) + { + cpu_state.eaaddr = getword(); + } + else + { + switch (cpu_mod) + { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) + { + easeg = ss; + ea_rseg = SS; + cpu_state.ea_seg = &_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; @@ -48,8 +133,8 @@ static inline void fetch_ea_16_long(uint32_t rmdat) } } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); +#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } +#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) @@ -57,7 +142,8 @@ static inline void fetch_ea_16_long(uint32_t rmdat) #define PREFETCH_FLUSH() #define OP_TABLE(name) dynarec_ops_ ## name -#define CLOCK_CYCLES(c) +/*Temporary*/ +#define CLOCK_CYCLES(c) cycles -= (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #include "386_ops.h" diff --git a/src/Makefile.am b/src/Makefile.am index 56741ab..ff90dfa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_backend.c codegen_ir.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ @@ -70,12 +70,20 @@ pcem_SOURCES += wx-sdl2-midi.c endif if CPU_I386 -pcem_SOURCES += codegen_x86.c +pcem_SOURCES += codegen_backend_x86.c codegen_backend_x86_uops.c pcem_CFLAGS += -msse2 endif if CPU_X86_64 -pcem_SOURCES += codegen_x86-64.c +pcem_SOURCES += codegen_backend_x86-64.c codegen_backend_x86-64_uops.c +endif + +if CPU_ARM +pcem_SOURCES += codegen_backend_arm.c codegen_backend_arm_uops.c +endif + +if CPU_ARM64 +pcem_SOURCES += codegen_backend_arm64.c codegen_backend_arm64_uops.c endif if USE_NETWORKING diff --git a/src/Makefile.in b/src/Makefile.in index bd8acad..ba15208 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -97,13 +97,15 @@ bin_PROGRAMS = pcem$(EXEEXT) @USE_ALSA_TRUE@am__append_3 = -lasound @USE_ALSA_TRUE@am__append_4 = midi_alsa.c @USE_ALSA_FALSE@am__append_5 = wx-sdl2-midi.c -@CPU_I386_TRUE@am__append_6 = codegen_x86.c +@CPU_I386_TRUE@am__append_6 = codegen_backend_x86.c codegen_backend_x86_uops.c @CPU_I386_TRUE@am__append_7 = -msse2 -@CPU_X86_64_TRUE@am__append_8 = codegen_x86-64.c -@USE_NETWORKING_TRUE@am__append_9 = -DUSE_NETWORKING -@USE_NETWORKING_TRUE@am__append_10 = -DUSE_NETWORKING +@CPU_X86_64_TRUE@am__append_8 = codegen_backend_x86-64.c codegen_backend_x86-64_uops.c +@CPU_ARM_TRUE@am__append_9 = codegen_backend_arm.c codegen_backend_arm_uops.c +@CPU_ARM64_TRUE@am__append_10 = codegen_backend_arm64.c codegen_backend_arm64_uops.c +@USE_NETWORKING_TRUE@am__append_11 = -DUSE_NETWORKING +@USE_NETWORKING_TRUE@am__append_12 = -DUSE_NETWORKING # SLiRP -@USE_NETWORKING_TRUE@am__append_11 = ne2000.c nethandler.c \ +@USE_NETWORKING_TRUE@am__append_13 = ne2000.c nethandler.c \ @USE_NETWORKING_TRUE@ wx-hostconfig.c slirp/bootp.c \ @USE_NETWORKING_TRUE@ slirp/cksum.c slirp/debug.c slirp/if.c \ @USE_NETWORKING_TRUE@ slirp/ip_icmp.c slirp/ip_input.c \ @@ -113,17 +115,19 @@ bin_PROGRAMS = pcem$(EXEEXT) @USE_NETWORKING_TRUE@ slirp/tcp_input.c slirp/tcp_output.c \ @USE_NETWORKING_TRUE@ slirp/tcp_subr.c slirp/tcp_timer.c \ @USE_NETWORKING_TRUE@ slirp/tftp.c slirp/udp.c -@OS_WINDOWS_TRUE@@USE_NETWORKING_TRUE@am__append_12 = -lwsock32 -liphlpapi -@OS_LINUX_TRUE@am__append_13 = cdrom-ioctl-linux.c wx-sdl2-display.c -@OS_MACOSX_TRUE@am__append_14 = cdrom-ioctl-osx.c wx-sdl2-display.c -@OS_MACOSX_TRUE@am__append_15 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -@OS_MACOSX_TRUE@am__append_16 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +@OS_WINDOWS_TRUE@@USE_NETWORKING_TRUE@am__append_14 = -lwsock32 -liphlpapi +@OS_LINUX_TRUE@am__append_15 = cdrom-ioctl-linux.c wx-sdl2-display.c +@OS_OTHER_TRUE@am__append_16 = cdrom-ioctl-dummy.c wx-sdl2-display.c +@OS_MACOSX_TRUE@am__append_17 = cdrom-ioctl-osx.c wx-sdl2-display.c +@OS_MACOSX_TRUE@am__append_18 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP +@OS_MACOSX_TRUE@am__append_19 = -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP DEFAULT_INCLUDES = -I.@am__isrc@ -@OS_WINDOWS_TRUE@am__append_17 = cdrom-ioctl.c wx-sdl2-display-win.c -@OS_WINDOWS_TRUE@am__append_18 = wx.res -@HAS_OFF64T_FALSE@am__append_19 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell -@RELEASE_BUILD_TRUE@am__append_20 = -DRELEASE_BUILD -@RELEASE_BUILD_TRUE@am__append_21 = -DRELEASE_BUILD +@OS_WINDOWS_TRUE@am__append_20 = cdrom-ioctl.c wx-sdl2-display-win.c +@OS_WINDOWS_TRUE@am__append_21 = wx.res + +#pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell +@RELEASE_BUILD_TRUE@am__append_22 = -DRELEASE_BUILD +@RELEASE_BUILD_TRUE@am__append_23 = -DRELEASE_BUILD subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -137,23 +141,23 @@ am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c \ - cdrom-image.cc cdrom-null.c cmd640.c codegen.c codegen_ops.c \ - codegen_timing_486.c codegen_timing_686.c \ - codegen_timing_common.c codegen_timing_pentium.c \ - codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ - device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ - esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ - hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c \ - ide.c ide_atapi.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 \ + cdrom-image.cc cdrom-null.c cmd640.c codegen.c \ + codegen_backend.c codegen_ir.c codegen_timing_486.c \ + codegen_timing_686.c codegen_timing_common.c \ + codegen_timing_pentium.c codegen_timing_winchip.c compaq.c \ + config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ + disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ + fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ + headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 laserxt.c lpt.c lpt_dac.c \ - lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ - mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ - nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c \ - pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ - nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ + lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ + model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ + neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c \ + pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ + ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ sound_adlib.c sound_adlibgold.c sound_audiopci.c sound_cms.c \ @@ -190,20 +194,31 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ wx-createdisc.cc wx-resources.cpp midi_alsa.c wx-sdl2-midi.c \ - codegen_x86.c codegen_x86-64.c ne2000.c nethandler.c \ - wx-hostconfig.c slirp/bootp.c slirp/cksum.c slirp/debug.c \ - slirp/if.c slirp/ip_icmp.c slirp/ip_input.c slirp/ip_output.c \ - slirp/mbuf.c slirp/misc.c slirp/queue.c slirp/sbuf.c \ - slirp/slirp.c slirp/socket.c slirp/tcp_input.c \ + codegen_backend_x86.c codegen_backend_x86_uops.c \ + codegen_backend_x86-64.c codegen_backend_x86-64_uops.c \ + codegen_backend_arm.c codegen_backend_arm_uops.c \ + codegen_backend_arm64.c codegen_backend_arm64_uops.c ne2000.c \ + nethandler.c wx-hostconfig.c slirp/bootp.c slirp/cksum.c \ + slirp/debug.c slirp/if.c slirp/ip_icmp.c slirp/ip_input.c \ + slirp/ip_output.c slirp/mbuf.c slirp/misc.c slirp/queue.c \ + slirp/sbuf.c slirp/slirp.c slirp/socket.c slirp/tcp_input.c \ slirp/tcp_output.c slirp/tcp_subr.c slirp/tcp_timer.c \ slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c wx-sdl2-display.c \ - cdrom-ioctl-osx.c cdrom-ioctl.c wx-sdl2-display-win.c + cdrom-ioctl-dummy.c cdrom-ioctl-osx.c cdrom-ioctl.c \ + wx-sdl2-display-win.c am__dirstamp = $(am__leading_dot)dirstamp @USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) @USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) -@CPU_I386_TRUE@am__objects_3 = pcem-codegen_x86.$(OBJEXT) -@CPU_X86_64_TRUE@am__objects_4 = pcem-codegen_x86-64.$(OBJEXT) -@USE_NETWORKING_TRUE@am__objects_5 = pcem-ne2000.$(OBJEXT) \ +@CPU_I386_TRUE@am__objects_3 = pcem-codegen_backend_x86.$(OBJEXT) \ +@CPU_I386_TRUE@ pcem-codegen_backend_x86_uops.$(OBJEXT) +@CPU_X86_64_TRUE@am__objects_4 = \ +@CPU_X86_64_TRUE@ pcem-codegen_backend_x86-64.$(OBJEXT) \ +@CPU_X86_64_TRUE@ pcem-codegen_backend_x86-64_uops.$(OBJEXT) +@CPU_ARM_TRUE@am__objects_5 = pcem-codegen_backend_arm.$(OBJEXT) \ +@CPU_ARM_TRUE@ pcem-codegen_backend_arm_uops.$(OBJEXT) +@CPU_ARM64_TRUE@am__objects_6 = pcem-codegen_backend_arm64.$(OBJEXT) \ +@CPU_ARM64_TRUE@ pcem-codegen_backend_arm64_uops.$(OBJEXT) +@USE_NETWORKING_TRUE@am__objects_7 = pcem-ne2000.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-wx-hostconfig.$(OBJEXT) \ @USE_NETWORKING_TRUE@ slirp/pcem-bootp.$(OBJEXT) \ @@ -225,11 +240,13 @@ am__dirstamp = $(am__leading_dot)dirstamp @USE_NETWORKING_TRUE@ slirp/pcem-tcp_timer.$(OBJEXT) \ @USE_NETWORKING_TRUE@ slirp/pcem-tftp.$(OBJEXT) \ @USE_NETWORKING_TRUE@ slirp/pcem-udp.$(OBJEXT) -@OS_LINUX_TRUE@am__objects_6 = pcem-cdrom-ioctl-linux.$(OBJEXT) \ +@OS_LINUX_TRUE@am__objects_8 = pcem-cdrom-ioctl-linux.$(OBJEXT) \ @OS_LINUX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) -@OS_MACOSX_TRUE@am__objects_7 = pcem-cdrom-ioctl-osx.$(OBJEXT) \ +@OS_OTHER_TRUE@am__objects_9 = pcem-cdrom-ioctl-dummy.$(OBJEXT) \ +@OS_OTHER_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) +@OS_MACOSX_TRUE@am__objects_10 = pcem-cdrom-ioctl-osx.$(OBJEXT) \ @OS_MACOSX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) -@OS_WINDOWS_TRUE@am__objects_8 = pcem-cdrom-ioctl.$(OBJEXT) \ +@OS_WINDOWS_TRUE@am__objects_11 = pcem-cdrom-ioctl.$(OBJEXT) \ @OS_WINDOWS_TRUE@ pcem-wx-sdl2-display-win.$(OBJEXT) am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-386_dynarec_ops.$(OBJEXT) pcem-808x.$(OBJEXT) \ @@ -237,8 +254,8 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-ali1429.$(OBJEXT) pcem-amstrad.$(OBJEXT) \ pcem-cbm_io.$(OBJEXT) pcem-cdrom-image.$(OBJEXT) \ pcem-cdrom-null.$(OBJEXT) pcem-cmd640.$(OBJEXT) \ - pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ - pcem-codegen_timing_486.$(OBJEXT) \ + pcem-codegen.$(OBJEXT) pcem-codegen_backend.$(OBJEXT) \ + pcem-codegen_ir.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_common.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ @@ -265,11 +282,11 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-laserxt.$(OBJEXT) pcem-lpt.$(OBJEXT) \ pcem-lpt_dac.$(OBJEXT) pcem-lpt_dss.$(OBJEXT) \ pcem-mca.$(OBJEXT) pcem-mcr.$(OBJEXT) pcem-mem.$(OBJEXT) \ - pcem-mfm_at.$(OBJEXT) pcem-mfm_xebec.$(OBJEXT) \ - pcem-model.$(OBJEXT) pcem-mouse.$(OBJEXT) \ - pcem-mouse_msystems.$(OBJEXT) pcem-mouse_ps2.$(OBJEXT) \ - pcem-mouse_serial.$(OBJEXT) pcem-neat.$(OBJEXT) \ - pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ + pcem-mem_bios.$(OBJEXT) pcem-mfm_at.$(OBJEXT) \ + pcem-mfm_xebec.$(OBJEXT) pcem-model.$(OBJEXT) \ + pcem-mouse.$(OBJEXT) pcem-mouse_msystems.$(OBJEXT) \ + pcem-mouse_ps2.$(OBJEXT) pcem-mouse_serial.$(OBJEXT) \ + pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ pcem-olivetti_m24.$(OBJEXT) pcem-opti495.$(OBJEXT) \ pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pc87306.$(OBJEXT) \ pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) \ @@ -354,11 +371,12 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-wx-joystickconfig.$(OBJEXT) pcem-wx-createdisc.$(OBJEXT) \ pcem-wx-resources.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \ - $(am__objects_6) $(am__objects_7) $(am__objects_8) + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) pcem_OBJECTS = $(am_pcem_OBJECTS) am__DEPENDENCIES_1 = pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__append_18) + $(am__append_21) pcem_LINK = $(CXXLD) $(pcem_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SCRIPTS = $(noinst_SCRIPTS) @@ -375,7 +393,194 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/pcem-386.Po \ + ./$(DEPDIR)/pcem-386_dynarec.Po \ + ./$(DEPDIR)/pcem-386_dynarec_ops.Po ./$(DEPDIR)/pcem-808x.Po \ + ./$(DEPDIR)/pcem-acc2036.Po ./$(DEPDIR)/pcem-acer386sx.Po \ + ./$(DEPDIR)/pcem-ali1429.Po ./$(DEPDIR)/pcem-amstrad.Po \ + ./$(DEPDIR)/pcem-cbm_io.Po ./$(DEPDIR)/pcem-cdrom-image.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl.Po ./$(DEPDIR)/pcem-cdrom-null.Po \ + ./$(DEPDIR)/pcem-cmd640.Po ./$(DEPDIR)/pcem-codegen.Po \ + ./$(DEPDIR)/pcem-codegen_backend.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm64.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po \ + ./$(DEPDIR)/pcem-codegen_ir.Po \ + ./$(DEPDIR)/pcem-codegen_timing_486.Po \ + ./$(DEPDIR)/pcem-codegen_timing_686.Po \ + ./$(DEPDIR)/pcem-codegen_timing_common.Po \ + ./$(DEPDIR)/pcem-codegen_timing_pentium.Po \ + ./$(DEPDIR)/pcem-codegen_timing_winchip.Po \ + ./$(DEPDIR)/pcem-compaq.Po ./$(DEPDIR)/pcem-config.Po \ + ./$(DEPDIR)/pcem-cpu.Po ./$(DEPDIR)/pcem-dells200.Po \ + ./$(DEPDIR)/pcem-device.Po ./$(DEPDIR)/pcem-disc.Po \ + ./$(DEPDIR)/pcem-disc_fdi.Po ./$(DEPDIR)/pcem-disc_img.Po \ + ./$(DEPDIR)/pcem-disc_sector.Po ./$(DEPDIR)/pcem-dma.Po \ + ./$(DEPDIR)/pcem-esdi_at.Po ./$(DEPDIR)/pcem-fdc.Po \ + ./$(DEPDIR)/pcem-fdc37c665.Po ./$(DEPDIR)/pcem-fdd.Po \ + ./$(DEPDIR)/pcem-fdi2raw.Po ./$(DEPDIR)/pcem-gameport.Po \ + ./$(DEPDIR)/pcem-hdd.Po ./$(DEPDIR)/pcem-hdd_esdi.Po \ + ./$(DEPDIR)/pcem-hdd_file.Po ./$(DEPDIR)/pcem-headland.Po \ + ./$(DEPDIR)/pcem-i430fx.Po ./$(DEPDIR)/pcem-i430lx.Po \ + ./$(DEPDIR)/pcem-i430vx.Po ./$(DEPDIR)/pcem-ide.Po \ + ./$(DEPDIR)/pcem-ide_atapi.Po ./$(DEPDIR)/pcem-intel.Po \ + ./$(DEPDIR)/pcem-intel_flash.Po ./$(DEPDIR)/pcem-io.Po \ + ./$(DEPDIR)/pcem-jim.Po \ + ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po \ + ./$(DEPDIR)/pcem-joystick_standard.Po \ + ./$(DEPDIR)/pcem-joystick_sw_pad.Po \ + ./$(DEPDIR)/pcem-joystick_tm_fcs.Po \ + ./$(DEPDIR)/pcem-keyboard.Po \ + ./$(DEPDIR)/pcem-keyboard_amstrad.Po \ + ./$(DEPDIR)/pcem-keyboard_at.Po \ + ./$(DEPDIR)/pcem-keyboard_olim24.Po \ + ./$(DEPDIR)/pcem-keyboard_pcjr.Po \ + ./$(DEPDIR)/pcem-keyboard_xt.Po ./$(DEPDIR)/pcem-laserxt.Po \ + ./$(DEPDIR)/pcem-lpt.Po ./$(DEPDIR)/pcem-lpt_dac.Po \ + ./$(DEPDIR)/pcem-lpt_dss.Po ./$(DEPDIR)/pcem-mca.Po \ + ./$(DEPDIR)/pcem-mcr.Po ./$(DEPDIR)/pcem-mem.Po \ + ./$(DEPDIR)/pcem-mem_bios.Po ./$(DEPDIR)/pcem-mfm_at.Po \ + ./$(DEPDIR)/pcem-mfm_xebec.Po ./$(DEPDIR)/pcem-midi_alsa.Po \ + ./$(DEPDIR)/pcem-model.Po ./$(DEPDIR)/pcem-mouse.Po \ + ./$(DEPDIR)/pcem-mouse_msystems.Po \ + ./$(DEPDIR)/pcem-mouse_ps2.Po ./$(DEPDIR)/pcem-mouse_serial.Po \ + ./$(DEPDIR)/pcem-ne2000.Po ./$(DEPDIR)/pcem-neat.Po \ + ./$(DEPDIR)/pcem-nethandler.Po ./$(DEPDIR)/pcem-nmi.Po \ + ./$(DEPDIR)/pcem-nvr.Po ./$(DEPDIR)/pcem-nvr_tc8521.Po \ + ./$(DEPDIR)/pcem-olivetti_m24.Po ./$(DEPDIR)/pcem-opti495.Po \ + ./$(DEPDIR)/pcem-paths.Po ./$(DEPDIR)/pcem-pc.Po \ + ./$(DEPDIR)/pcem-pc87306.Po ./$(DEPDIR)/pcem-pci.Po \ + ./$(DEPDIR)/pcem-pic.Po ./$(DEPDIR)/pcem-piix.Po \ + ./$(DEPDIR)/pcem-pit.Po ./$(DEPDIR)/pcem-ppi.Po \ + ./$(DEPDIR)/pcem-ps1.Po ./$(DEPDIR)/pcem-ps2.Po \ + ./$(DEPDIR)/pcem-ps2_mca.Po ./$(DEPDIR)/pcem-ps2_nvr.Po \ + ./$(DEPDIR)/pcem-rom.Po ./$(DEPDIR)/pcem-rtc.Po \ + ./$(DEPDIR)/pcem-rtc_tc8521.Po ./$(DEPDIR)/pcem-scat.Po \ + ./$(DEPDIR)/pcem-scsi.Po ./$(DEPDIR)/pcem-scsi_53c400.Po \ + ./$(DEPDIR)/pcem-scsi_aha1540.Po ./$(DEPDIR)/pcem-scsi_cd.Po \ + ./$(DEPDIR)/pcem-scsi_hd.Po ./$(DEPDIR)/pcem-scsi_zip.Po \ + ./$(DEPDIR)/pcem-serial.Po ./$(DEPDIR)/pcem-sio.Po \ + ./$(DEPDIR)/pcem-sis496.Po ./$(DEPDIR)/pcem-sl82c460.Po \ + ./$(DEPDIR)/pcem-sound.Po ./$(DEPDIR)/pcem-sound_ad1848.Po \ + ./$(DEPDIR)/pcem-sound_adlib.Po \ + ./$(DEPDIR)/pcem-sound_adlibgold.Po \ + ./$(DEPDIR)/pcem-sound_audiopci.Po \ + ./$(DEPDIR)/pcem-sound_cms.Po ./$(DEPDIR)/pcem-sound_dbopl.Po \ + ./$(DEPDIR)/pcem-sound_emu8k.Po ./$(DEPDIR)/pcem-sound_gus.Po \ + ./$(DEPDIR)/pcem-sound_mpu401_uart.Po \ + ./$(DEPDIR)/pcem-sound_opl.Po ./$(DEPDIR)/pcem-sound_pas16.Po \ + ./$(DEPDIR)/pcem-sound_ps1.Po ./$(DEPDIR)/pcem-sound_pssj.Po \ + ./$(DEPDIR)/pcem-sound_resid.Po ./$(DEPDIR)/pcem-sound_sb.Po \ + ./$(DEPDIR)/pcem-sound_sb_dsp.Po \ + ./$(DEPDIR)/pcem-sound_sn76489.Po \ + ./$(DEPDIR)/pcem-sound_speaker.Po \ + ./$(DEPDIR)/pcem-sound_ssi2001.Po \ + ./$(DEPDIR)/pcem-sound_wss.Po ./$(DEPDIR)/pcem-sound_ym7128.Po \ + ./$(DEPDIR)/pcem-soundopenal.Po ./$(DEPDIR)/pcem-t1000.Po \ + ./$(DEPDIR)/pcem-t3100e.Po ./$(DEPDIR)/pcem-tandy_eeprom.Po \ + ./$(DEPDIR)/pcem-tandy_rom.Po ./$(DEPDIR)/pcem-timer.Po \ + ./$(DEPDIR)/pcem-um8669f.Po ./$(DEPDIR)/pcem-um8881f.Po \ + ./$(DEPDIR)/pcem-vid_ati18800.Po \ + ./$(DEPDIR)/pcem-vid_ati28800.Po \ + ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_ati_eeprom.Po \ + ./$(DEPDIR)/pcem-vid_ati_mach64.Po ./$(DEPDIR)/pcem-vid_cga.Po \ + ./$(DEPDIR)/pcem-vid_cl5429.Po \ + ./$(DEPDIR)/pcem-vid_colorplus.Po \ + ./$(DEPDIR)/pcem-vid_compaq_cga.Po ./$(DEPDIR)/pcem-vid_ega.Po \ + ./$(DEPDIR)/pcem-vid_et4000.Po \ + ./$(DEPDIR)/pcem-vid_et4000w32.Po \ + ./$(DEPDIR)/pcem-vid_genius.Po \ + ./$(DEPDIR)/pcem-vid_hercules.Po \ + ./$(DEPDIR)/pcem-vid_icd2061.Po \ + ./$(DEPDIR)/pcem-vid_ics2595.Po \ + ./$(DEPDIR)/pcem-vid_incolor.Po ./$(DEPDIR)/pcem-vid_mda.Po \ + ./$(DEPDIR)/pcem-vid_olivetti_m24.Po \ + ./$(DEPDIR)/pcem-vid_oti037.Po ./$(DEPDIR)/pcem-vid_oti067.Po \ + ./$(DEPDIR)/pcem-vid_paradise.Po \ + ./$(DEPDIR)/pcem-vid_pc1512.Po ./$(DEPDIR)/pcem-vid_pc1640.Po \ + ./$(DEPDIR)/pcem-vid_pc200.Po ./$(DEPDIR)/pcem-vid_pcjr.Po \ + ./$(DEPDIR)/pcem-vid_ps1_svga.Po ./$(DEPDIR)/pcem-vid_s3.Po \ + ./$(DEPDIR)/pcem-vid_s3_virge.Po \ + ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_stg_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_svga.Po \ + ./$(DEPDIR)/pcem-vid_svga_render.Po \ + ./$(DEPDIR)/pcem-vid_t1000.Po ./$(DEPDIR)/pcem-vid_t3100e.Po \ + ./$(DEPDIR)/pcem-vid_tandy.Po ./$(DEPDIR)/pcem-vid_tandysl.Po \ + ./$(DEPDIR)/pcem-vid_tgui9440.Po \ + ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_tvga.Po \ + ./$(DEPDIR)/pcem-vid_unk_ramdac.Po ./$(DEPDIR)/pcem-vid_vga.Po \ + ./$(DEPDIR)/pcem-vid_voodoo.Po ./$(DEPDIR)/pcem-vid_wy700.Po \ + ./$(DEPDIR)/pcem-video.Po ./$(DEPDIR)/pcem-wd76c10.Po \ + ./$(DEPDIR)/pcem-wx-app.Po ./$(DEPDIR)/pcem-wx-common.Po \ + ./$(DEPDIR)/pcem-wx-config.Po \ + ./$(DEPDIR)/pcem-wx-config_sel.Po \ + ./$(DEPDIR)/pcem-wx-createdisc.Po \ + ./$(DEPDIR)/pcem-wx-deviceconfig.Po \ + ./$(DEPDIR)/pcem-wx-dialogbox.Po \ + ./$(DEPDIR)/pcem-wx-glslp-parser.Po \ + ./$(DEPDIR)/pcem-wx-hostconfig.Po \ + ./$(DEPDIR)/pcem-wx-joystickconfig.Po \ + ./$(DEPDIR)/pcem-wx-main.Po ./$(DEPDIR)/pcem-wx-resources.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-display.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-midi.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-status.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-video.Po ./$(DEPDIR)/pcem-wx-sdl2.Po \ + ./$(DEPDIR)/pcem-wx-shader_man.Po \ + ./$(DEPDIR)/pcem-wx-shaderconfig.Po \ + ./$(DEPDIR)/pcem-wx-status.Po ./$(DEPDIR)/pcem-wx-thread.Po \ + ./$(DEPDIR)/pcem-wx-utils.Po ./$(DEPDIR)/pcem-x86seg.Po \ + ./$(DEPDIR)/pcem-x87.Po ./$(DEPDIR)/pcem-xi8088.Po \ + ./$(DEPDIR)/pcem-xtide.Po dosbox/$(DEPDIR)/pcem-cdrom_image.Po \ + dosbox/$(DEPDIR)/pcem-dbopl.Po \ + dosbox/$(DEPDIR)/pcem-nukedopl.Po \ + dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po \ + resid-fp/$(DEPDIR)/pcem-convolve-sse.Po \ + resid-fp/$(DEPDIR)/pcem-convolve.Po \ + resid-fp/$(DEPDIR)/pcem-envelope.Po \ + resid-fp/$(DEPDIR)/pcem-extfilt.Po \ + resid-fp/$(DEPDIR)/pcem-filter.Po \ + resid-fp/$(DEPDIR)/pcem-pot.Po resid-fp/$(DEPDIR)/pcem-sid.Po \ + resid-fp/$(DEPDIR)/pcem-voice.Po \ + resid-fp/$(DEPDIR)/pcem-wave.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po \ + slirp/$(DEPDIR)/pcem-bootp.Po slirp/$(DEPDIR)/pcem-cksum.Po \ + slirp/$(DEPDIR)/pcem-debug.Po slirp/$(DEPDIR)/pcem-if.Po \ + slirp/$(DEPDIR)/pcem-ip_icmp.Po \ + slirp/$(DEPDIR)/pcem-ip_input.Po \ + slirp/$(DEPDIR)/pcem-ip_output.Po slirp/$(DEPDIR)/pcem-mbuf.Po \ + slirp/$(DEPDIR)/pcem-misc.Po slirp/$(DEPDIR)/pcem-queue.Po \ + slirp/$(DEPDIR)/pcem-sbuf.Po slirp/$(DEPDIR)/pcem-slirp.Po \ + slirp/$(DEPDIR)/pcem-socket.Po \ + slirp/$(DEPDIR)/pcem-tcp_input.Po \ + slirp/$(DEPDIR)/pcem-tcp_output.Po \ + slirp/$(DEPDIR)/pcem-tcp_subr.Po \ + slirp/$(DEPDIR)/pcem-tcp_timer.Po slirp/$(DEPDIR)/pcem-tftp.Po \ + slirp/$(DEPDIR)/pcem-udp.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -542,7 +747,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -556,7 +760,7 @@ noinst_SCRIPTS = $(am__append_2) CLEANFILES = $(am__append_1) # Special wxWidgets files -WINDRES = $(shell wx-config --rescomp) +WINDRES = $(shell $(WX_CONFIG_PATH) --rescomp) # PCem @@ -565,7 +769,7 @@ WINDRES = $(shell wx-config --rescomp) # resid-fp pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c \ acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc \ - cdrom-null.c cmd640.c codegen.c codegen_ops.c \ + cdrom-null.c cmd640.c codegen.c codegen_backend.c codegen_ir.c \ codegen_timing_486.c codegen_timing_686.c \ codegen_timing_common.c codegen_timing_pentium.c \ codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ @@ -577,11 +781,11 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.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 laserxt.c lpt.c lpt_dac.c \ - lpt_dss.c mca.c mcr.c mem.c mfm_at.c mfm_xebec.c model.c \ - mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c \ - nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c \ - pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c \ - nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ + lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ + model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ + neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c \ + pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ + ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ sound_adlib.c sound_adlibgold.c sound_audiopci.c sound_cms.c \ @@ -619,14 +823,16 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c \ wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ wx-createdisc.cc wx-resources.cpp $(am__append_4) \ $(am__append_5) $(am__append_6) $(am__append_8) \ - $(am__append_11) $(am__append_13) $(am__append_14) \ - $(am__append_17) -pcem_CFLAGS = $(subst -fpermissive,,$(shell wx-config --cxxflags) \ - $(shell sdl2-config --cflags)) $(am__append_7) $(am__append_9) \ - $(am__append_15) $(am__append_19) $(am__append_20) -pcem_CXXFLAGS = $(shell wx-config --cxxflags) $(shell sdl2-config \ - --cflags) $(am__append_10) $(am__append_16) $(am__append_21) -pcem_LDADD = @LIBS@ $(am__append_3) $(am__append_12) $(am__append_18) + $(am__append_9) $(am__append_10) $(am__append_13) \ + $(am__append_15) $(am__append_16) $(am__append_17) \ + $(am__append_20) +pcem_CFLAGS = $(subst -fpermissive,,$(shell $(WX_CONFIG_PATH) \ + --cxxflags) $(shell sdl2-config --cflags)) $(am__append_7) \ + $(am__append_11) $(am__append_18) $(am__append_22) +pcem_CXXFLAGS = $(shell $(WX_CONFIG_PATH) --cxxflags) $(shell \ + sdl2-config --cflags) $(am__append_12) $(am__append_19) \ + $(am__append_23) +pcem_LDADD = @LIBS@ $(am__append_3) $(am__append_14) $(am__append_21) @OS_WINDOWS_TRUE@DEFAULT_INCLUDES = -iquote . all: all-am @@ -649,8 +855,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *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);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -815,266 +1021,281 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@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-acc2036.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-amstrad.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.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-ioctl-osx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.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_686.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.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_timing_winchip.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-dells200.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-disc_sector.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.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-fdd.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-hdd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.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-ide_atapi.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-joystick_ch_flightstick_pro.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_standard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_sw_pad.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_tm_fcs.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-laserxt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.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-mfm_at.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.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_msystems.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-ne2000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.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-nvr_tc8521.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.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-ps2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_mca.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.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_audiopci.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_dbopl.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_ps1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.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-sound_ym7128.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.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_colorplus.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.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_genius.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_incolor.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_oti037.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_ps1_svga.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_t1000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.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_tandysl.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-vid_wy700.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-wx-app.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.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-xi8088.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-808x.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2036.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acer386sx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ali1429.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-amstrad.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_486.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_686.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_pentium.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_winchip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-compaq.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-config.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_fdi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_img.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_sector.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc37c665.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdi2raw.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-headland.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430fx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430lx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430vx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide_atapi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel_flash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-io.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-jim.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_standard.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_sw_pad.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_tm_fcs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_amstrad.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_at.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_olim24.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_pcjr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_xt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-laserxt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mcr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem_bios.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_at.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-model.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_msystems.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_ps2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_serial.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ne2000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nmi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr_tc8521.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pci.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-piix.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ppi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_mca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ad1848.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlibgold.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_audiopci.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_cms.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_dbopl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_emu8k.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_gus.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_mpu401_uart.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_opl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pas16.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ps1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb_dsp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sn76489.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_speaker.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ssi2001.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_wss.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ym7128.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-timer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8669f.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8881f.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati18800.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati28800.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_eeprom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_mach64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cl5429.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_colorplus.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ega.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000w32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_genius.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_hercules.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_icd2061.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ics2595.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_mda.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_olivetti_m24.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti037.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti067.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_paradise.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1512.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1640.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc200.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pcjr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ps1_svga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3_virge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_sdac_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_stg_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga_render.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t1000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandysl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tgui9440.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tvga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_unk_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_vga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_wy700.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x86seg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x87.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xi8088.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -1260,19 +1481,33 @@ pcem-codegen.obj: codegen.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops.Tpo $(DEPDIR)/pcem-codegen_ops.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops.c' object='pcem-codegen_ops.o' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_backend.o: codegen_backend.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend.Tpo -c -o pcem-codegen_backend.o `test -f 'codegen_backend.c' || echo '$(srcdir)/'`codegen_backend.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend.Tpo $(DEPDIR)/pcem-codegen_backend.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend.c' object='pcem-codegen_backend.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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 +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend.o `test -f 'codegen_backend.c' || echo '$(srcdir)/'`codegen_backend.c -pcem-codegen_ops.obj: codegen_ops.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops.Tpo $(DEPDIR)/pcem-codegen_ops.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops.c' object='pcem-codegen_ops.obj' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_backend.obj: codegen_backend.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend.Tpo -c -o pcem-codegen_backend.obj `if test -f 'codegen_backend.c'; then $(CYGPATH_W) 'codegen_backend.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend.Tpo $(DEPDIR)/pcem-codegen_backend.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend.c' object='pcem-codegen_backend.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend.obj `if test -f 'codegen_backend.c'; then $(CYGPATH_W) 'codegen_backend.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend.c'; fi` + +pcem-codegen_ir.o: codegen_ir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ir.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ir.Tpo -c -o pcem-codegen_ir.o `test -f 'codegen_ir.c' || echo '$(srcdir)/'`codegen_ir.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ir.Tpo $(DEPDIR)/pcem-codegen_ir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ir.c' object='pcem-codegen_ir.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ir.o `test -f 'codegen_ir.c' || echo '$(srcdir)/'`codegen_ir.c + +pcem-codegen_ir.obj: codegen_ir.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ir.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ir.Tpo -c -o pcem-codegen_ir.obj `if test -f 'codegen_ir.c'; then $(CYGPATH_W) 'codegen_ir.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ir.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ir.Tpo $(DEPDIR)/pcem-codegen_ir.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ir.c' object='pcem-codegen_ir.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ir.obj `if test -f 'codegen_ir.c'; then $(CYGPATH_W) 'codegen_ir.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ir.c'; fi` pcem-codegen_timing_486.o: codegen_timing_486.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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 @@ -1988,6 +2223,20 @@ pcem-mem.obj: mem.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-mem_bios.o: mem_bios.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mem_bios.o -MD -MP -MF $(DEPDIR)/pcem-mem_bios.Tpo -c -o pcem-mem_bios.o `test -f 'mem_bios.c' || echo '$(srcdir)/'`mem_bios.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mem_bios.Tpo $(DEPDIR)/pcem-mem_bios.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mem_bios.c' object='pcem-mem_bios.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mem_bios.o `test -f 'mem_bios.c' || echo '$(srcdir)/'`mem_bios.c + +pcem-mem_bios.obj: mem_bios.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mem_bios.obj -MD -MP -MF $(DEPDIR)/pcem-mem_bios.Tpo -c -o pcem-mem_bios.obj `if test -f 'mem_bios.c'; then $(CYGPATH_W) 'mem_bios.c'; else $(CYGPATH_W) '$(srcdir)/mem_bios.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mem_bios.Tpo $(DEPDIR)/pcem-mem_bios.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mem_bios.c' object='pcem-mem_bios.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mem_bios.obj `if test -f 'mem_bios.c'; then $(CYGPATH_W) 'mem_bios.c'; else $(CYGPATH_W) '$(srcdir)/mem_bios.c'; fi` + pcem-mfm_at.o: mfm_at.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mfm_at.o -MD -MP -MF $(DEPDIR)/pcem-mfm_at.Tpo -c -o pcem-mfm_at.o `test -f 'mfm_at.c' || echo '$(srcdir)/'`mfm_at.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mfm_at.Tpo $(DEPDIR)/pcem-mfm_at.Po @@ -3864,33 +4113,117 @@ pcem-wx-sdl2-midi.obj: wx-sdl2-midi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-midi.obj `if test -f 'wx-sdl2-midi.c'; then $(CYGPATH_W) 'wx-sdl2-midi.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-midi.c'; fi` -pcem-codegen_x86.o: codegen_x86.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_x86.Tpo $(DEPDIR)/pcem-codegen_x86.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_x86.c' object='pcem-codegen_x86.o' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_backend_x86.o: codegen_backend_x86.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86.Tpo -c -o pcem-codegen_backend_x86.o `test -f 'codegen_backend_x86.c' || echo '$(srcdir)/'`codegen_backend_x86.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86.Tpo $(DEPDIR)/pcem-codegen_backend_x86.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86.c' object='pcem-codegen_backend_x86.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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 +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86.o `test -f 'codegen_backend_x86.c' || echo '$(srcdir)/'`codegen_backend_x86.c -pcem-codegen_x86.obj: codegen_x86.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_x86.Tpo $(DEPDIR)/pcem-codegen_x86.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_x86.c' object='pcem-codegen_x86.obj' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_backend_x86.obj: codegen_backend_x86.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86.Tpo -c -o pcem-codegen_backend_x86.obj `if test -f 'codegen_backend_x86.c'; then $(CYGPATH_W) 'codegen_backend_x86.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86.Tpo $(DEPDIR)/pcem-codegen_backend_x86.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86.c' object='pcem-codegen_backend_x86.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86.obj `if test -f 'codegen_backend_x86.c'; then $(CYGPATH_W) 'codegen_backend_x86.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86.c'; fi` -pcem-codegen_x86-64.o: codegen_x86-64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_x86-64.Tpo $(DEPDIR)/pcem-codegen_x86-64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_x86-64.c' object='pcem-codegen_x86-64.o' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_backend_x86_uops.o: codegen_backend_x86_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_uops.Tpo -c -o pcem-codegen_backend_x86_uops.o `test -f 'codegen_backend_x86_uops.c' || echo '$(srcdir)/'`codegen_backend_x86_uops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_uops.Tpo $(DEPDIR)/pcem-codegen_backend_x86_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_uops.c' object='pcem-codegen_backend_x86_uops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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 +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_uops.o `test -f 'codegen_backend_x86_uops.c' || echo '$(srcdir)/'`codegen_backend_x86_uops.c -pcem-codegen_x86-64.obj: codegen_x86-64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_x86-64.Tpo $(DEPDIR)/pcem-codegen_x86-64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_x86-64.c' object='pcem-codegen_x86-64.obj' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_backend_x86_uops.obj: codegen_backend_x86_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_uops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_uops.Tpo -c -o pcem-codegen_backend_x86_uops.obj `if test -f 'codegen_backend_x86_uops.c'; then $(CYGPATH_W) 'codegen_backend_x86_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_uops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_uops.Tpo $(DEPDIR)/pcem-codegen_backend_x86_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_uops.c' object='pcem-codegen_backend_x86_uops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_uops.obj `if test -f 'codegen_backend_x86_uops.c'; then $(CYGPATH_W) 'codegen_backend_x86_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_uops.c'; fi` + +pcem-codegen_backend_x86-64.o: codegen_backend_x86-64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64.Tpo -c -o pcem-codegen_backend_x86-64.o `test -f 'codegen_backend_x86-64.c' || echo '$(srcdir)/'`codegen_backend_x86-64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64.c' object='pcem-codegen_backend_x86-64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64.o `test -f 'codegen_backend_x86-64.c' || echo '$(srcdir)/'`codegen_backend_x86-64.c + +pcem-codegen_backend_x86-64.obj: codegen_backend_x86-64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64.Tpo -c -o pcem-codegen_backend_x86-64.obj `if test -f 'codegen_backend_x86-64.c'; then $(CYGPATH_W) 'codegen_backend_x86-64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64.c' object='pcem-codegen_backend_x86-64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64.obj `if test -f 'codegen_backend_x86-64.c'; then $(CYGPATH_W) 'codegen_backend_x86-64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64.c'; fi` + +pcem-codegen_backend_x86-64_uops.o: codegen_backend_x86-64_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Tpo -c -o pcem-codegen_backend_x86-64_uops.o `test -f 'codegen_backend_x86-64_uops.c' || echo '$(srcdir)/'`codegen_backend_x86-64_uops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64_uops.c' object='pcem-codegen_backend_x86-64_uops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64_uops.o `test -f 'codegen_backend_x86-64_uops.c' || echo '$(srcdir)/'`codegen_backend_x86-64_uops.c + +pcem-codegen_backend_x86-64_uops.obj: codegen_backend_x86-64_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_uops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Tpo -c -o pcem-codegen_backend_x86-64_uops.obj `if test -f 'codegen_backend_x86-64_uops.c'; then $(CYGPATH_W) 'codegen_backend_x86-64_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64_uops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64_uops.c' object='pcem-codegen_backend_x86-64_uops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64_uops.obj `if test -f 'codegen_backend_x86-64_uops.c'; then $(CYGPATH_W) 'codegen_backend_x86-64_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64_uops.c'; fi` + +pcem-codegen_backend_arm.o: codegen_backend_arm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm.Tpo -c -o pcem-codegen_backend_arm.o `test -f 'codegen_backend_arm.c' || echo '$(srcdir)/'`codegen_backend_arm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm.Tpo $(DEPDIR)/pcem-codegen_backend_arm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm.c' object='pcem-codegen_backend_arm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm.o `test -f 'codegen_backend_arm.c' || echo '$(srcdir)/'`codegen_backend_arm.c + +pcem-codegen_backend_arm.obj: codegen_backend_arm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm.Tpo -c -o pcem-codegen_backend_arm.obj `if test -f 'codegen_backend_arm.c'; then $(CYGPATH_W) 'codegen_backend_arm.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm.Tpo $(DEPDIR)/pcem-codegen_backend_arm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm.c' object='pcem-codegen_backend_arm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm.obj `if test -f 'codegen_backend_arm.c'; then $(CYGPATH_W) 'codegen_backend_arm.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm.c'; fi` + +pcem-codegen_backend_arm_uops.o: codegen_backend_arm_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm_uops.Tpo -c -o pcem-codegen_backend_arm_uops.o `test -f 'codegen_backend_arm_uops.c' || echo '$(srcdir)/'`codegen_backend_arm_uops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm_uops.Tpo $(DEPDIR)/pcem-codegen_backend_arm_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm_uops.c' object='pcem-codegen_backend_arm_uops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm_uops.o `test -f 'codegen_backend_arm_uops.c' || echo '$(srcdir)/'`codegen_backend_arm_uops.c + +pcem-codegen_backend_arm_uops.obj: codegen_backend_arm_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm_uops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm_uops.Tpo -c -o pcem-codegen_backend_arm_uops.obj `if test -f 'codegen_backend_arm_uops.c'; then $(CYGPATH_W) 'codegen_backend_arm_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm_uops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm_uops.Tpo $(DEPDIR)/pcem-codegen_backend_arm_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm_uops.c' object='pcem-codegen_backend_arm_uops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm_uops.obj `if test -f 'codegen_backend_arm_uops.c'; then $(CYGPATH_W) 'codegen_backend_arm_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm_uops.c'; fi` + +pcem-codegen_backend_arm64.o: codegen_backend_arm64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64.Tpo -c -o pcem-codegen_backend_arm64.o `test -f 'codegen_backend_arm64.c' || echo '$(srcdir)/'`codegen_backend_arm64.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64.Tpo $(DEPDIR)/pcem-codegen_backend_arm64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64.c' object='pcem-codegen_backend_arm64.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64.o `test -f 'codegen_backend_arm64.c' || echo '$(srcdir)/'`codegen_backend_arm64.c + +pcem-codegen_backend_arm64.obj: codegen_backend_arm64.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64.Tpo -c -o pcem-codegen_backend_arm64.obj `if test -f 'codegen_backend_arm64.c'; then $(CYGPATH_W) 'codegen_backend_arm64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64.Tpo $(DEPDIR)/pcem-codegen_backend_arm64.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64.c' object='pcem-codegen_backend_arm64.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64.obj `if test -f 'codegen_backend_arm64.c'; then $(CYGPATH_W) 'codegen_backend_arm64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64.c'; fi` + +pcem-codegen_backend_arm64_uops.o: codegen_backend_arm64_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_uops.Tpo -c -o pcem-codegen_backend_arm64_uops.o `test -f 'codegen_backend_arm64_uops.c' || echo '$(srcdir)/'`codegen_backend_arm64_uops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_uops.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64_uops.c' object='pcem-codegen_backend_arm64_uops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64_uops.o `test -f 'codegen_backend_arm64_uops.c' || echo '$(srcdir)/'`codegen_backend_arm64_uops.c + +pcem-codegen_backend_arm64_uops.obj: codegen_backend_arm64_uops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_uops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_uops.Tpo -c -o pcem-codegen_backend_arm64_uops.obj `if test -f 'codegen_backend_arm64_uops.c'; then $(CYGPATH_W) 'codegen_backend_arm64_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64_uops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_uops.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_uops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64_uops.c' object='pcem-codegen_backend_arm64_uops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64_uops.obj `if test -f 'codegen_backend_arm64_uops.c'; then $(CYGPATH_W) 'codegen_backend_arm64_uops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64_uops.c'; fi` pcem-ne2000.o: ne2000.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ne2000.o -MD -MP -MF $(DEPDIR)/pcem-ne2000.Tpo -c -o pcem-ne2000.o `test -f 'ne2000.c' || echo '$(srcdir)/'`ne2000.c @@ -4228,6 +4561,20 @@ pcem-wx-sdl2-display.obj: wx-sdl2-display.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wx-sdl2-display.obj `if test -f 'wx-sdl2-display.c'; then $(CYGPATH_W) 'wx-sdl2-display.c'; else $(CYGPATH_W) '$(srcdir)/wx-sdl2-display.c'; fi` +pcem-cdrom-ioctl-dummy.o: cdrom-ioctl-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-dummy.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-dummy.Tpo -c -o pcem-cdrom-ioctl-dummy.o `test -f 'cdrom-ioctl-dummy.c' || echo '$(srcdir)/'`cdrom-ioctl-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-dummy.Tpo $(DEPDIR)/pcem-cdrom-ioctl-dummy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-dummy.c' object='pcem-cdrom-ioctl-dummy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-dummy.o `test -f 'cdrom-ioctl-dummy.c' || echo '$(srcdir)/'`cdrom-ioctl-dummy.c + +pcem-cdrom-ioctl-dummy.obj: cdrom-ioctl-dummy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-dummy.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-dummy.Tpo -c -o pcem-cdrom-ioctl-dummy.obj `if test -f 'cdrom-ioctl-dummy.c'; then $(CYGPATH_W) 'cdrom-ioctl-dummy.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-dummy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-dummy.Tpo $(DEPDIR)/pcem-cdrom-ioctl-dummy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrom-ioctl-dummy.c' object='pcem-cdrom-ioctl-dummy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-dummy.obj `if test -f 'cdrom-ioctl-dummy.c'; then $(CYGPATH_W) 'cdrom-ioctl-dummy.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-dummy.c'; fi` + pcem-cdrom-ioctl-osx.o: cdrom-ioctl-osx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-osx.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo -c -o pcem-cdrom-ioctl-osx.o `test -f 'cdrom-ioctl-osx.c' || echo '$(srcdir)/'`cdrom-ioctl-osx.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-osx.Tpo $(DEPDIR)/pcem-cdrom-ioctl-osx.Po @@ -4816,7 +5163,10 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -4895,7 +5245,275 @@ clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) + -rm -f ./$(DEPDIR)/pcem-386.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec_ops.Po + -rm -f ./$(DEPDIR)/pcem-808x.Po + -rm -f ./$(DEPDIR)/pcem-acc2036.Po + -rm -f ./$(DEPDIR)/pcem-acer386sx.Po + -rm -f ./$(DEPDIR)/pcem-ali1429.Po + -rm -f ./$(DEPDIR)/pcem-amstrad.Po + -rm -f ./$(DEPDIR)/pcem-cbm_io.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-image.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-null.Po + -rm -f ./$(DEPDIR)/pcem-cmd640.Po + -rm -f ./$(DEPDIR)/pcem-codegen.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ir.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_486.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_686.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_common.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_pentium.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip.Po + -rm -f ./$(DEPDIR)/pcem-compaq.Po + -rm -f ./$(DEPDIR)/pcem-config.Po + -rm -f ./$(DEPDIR)/pcem-cpu.Po + -rm -f ./$(DEPDIR)/pcem-dells200.Po + -rm -f ./$(DEPDIR)/pcem-device.Po + -rm -f ./$(DEPDIR)/pcem-disc.Po + -rm -f ./$(DEPDIR)/pcem-disc_fdi.Po + -rm -f ./$(DEPDIR)/pcem-disc_img.Po + -rm -f ./$(DEPDIR)/pcem-disc_sector.Po + -rm -f ./$(DEPDIR)/pcem-dma.Po + -rm -f ./$(DEPDIR)/pcem-esdi_at.Po + -rm -f ./$(DEPDIR)/pcem-fdc.Po + -rm -f ./$(DEPDIR)/pcem-fdc37c665.Po + -rm -f ./$(DEPDIR)/pcem-fdd.Po + -rm -f ./$(DEPDIR)/pcem-fdi2raw.Po + -rm -f ./$(DEPDIR)/pcem-gameport.Po + -rm -f ./$(DEPDIR)/pcem-hdd.Po + -rm -f ./$(DEPDIR)/pcem-hdd_esdi.Po + -rm -f ./$(DEPDIR)/pcem-hdd_file.Po + -rm -f ./$(DEPDIR)/pcem-headland.Po + -rm -f ./$(DEPDIR)/pcem-i430fx.Po + -rm -f ./$(DEPDIR)/pcem-i430lx.Po + -rm -f ./$(DEPDIR)/pcem-i430vx.Po + -rm -f ./$(DEPDIR)/pcem-ide.Po + -rm -f ./$(DEPDIR)/pcem-ide_atapi.Po + -rm -f ./$(DEPDIR)/pcem-intel.Po + -rm -f ./$(DEPDIR)/pcem-intel_flash.Po + -rm -f ./$(DEPDIR)/pcem-io.Po + -rm -f ./$(DEPDIR)/pcem-jim.Po + -rm -f ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po + -rm -f ./$(DEPDIR)/pcem-joystick_standard.Po + -rm -f ./$(DEPDIR)/pcem-joystick_sw_pad.Po + -rm -f ./$(DEPDIR)/pcem-joystick_tm_fcs.Po + -rm -f ./$(DEPDIR)/pcem-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_amstrad.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_at.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_olim24.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_xt.Po + -rm -f ./$(DEPDIR)/pcem-laserxt.Po + -rm -f ./$(DEPDIR)/pcem-lpt.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dac.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dss.Po + -rm -f ./$(DEPDIR)/pcem-mca.Po + -rm -f ./$(DEPDIR)/pcem-mcr.Po + -rm -f ./$(DEPDIR)/pcem-mem.Po + -rm -f ./$(DEPDIR)/pcem-mem_bios.Po + -rm -f ./$(DEPDIR)/pcem-mfm_at.Po + -rm -f ./$(DEPDIR)/pcem-mfm_xebec.Po + -rm -f ./$(DEPDIR)/pcem-midi_alsa.Po + -rm -f ./$(DEPDIR)/pcem-model.Po + -rm -f ./$(DEPDIR)/pcem-mouse.Po + -rm -f ./$(DEPDIR)/pcem-mouse_msystems.Po + -rm -f ./$(DEPDIR)/pcem-mouse_ps2.Po + -rm -f ./$(DEPDIR)/pcem-mouse_serial.Po + -rm -f ./$(DEPDIR)/pcem-ne2000.Po + -rm -f ./$(DEPDIR)/pcem-neat.Po + -rm -f ./$(DEPDIR)/pcem-nethandler.Po + -rm -f ./$(DEPDIR)/pcem-nmi.Po + -rm -f ./$(DEPDIR)/pcem-nvr.Po + -rm -f ./$(DEPDIR)/pcem-nvr_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-opti495.Po + -rm -f ./$(DEPDIR)/pcem-paths.Po + -rm -f ./$(DEPDIR)/pcem-pc.Po + -rm -f ./$(DEPDIR)/pcem-pc87306.Po + -rm -f ./$(DEPDIR)/pcem-pci.Po + -rm -f ./$(DEPDIR)/pcem-pic.Po + -rm -f ./$(DEPDIR)/pcem-piix.Po + -rm -f ./$(DEPDIR)/pcem-pit.Po + -rm -f ./$(DEPDIR)/pcem-ppi.Po + -rm -f ./$(DEPDIR)/pcem-ps1.Po + -rm -f ./$(DEPDIR)/pcem-ps2.Po + -rm -f ./$(DEPDIR)/pcem-ps2_mca.Po + -rm -f ./$(DEPDIR)/pcem-ps2_nvr.Po + -rm -f ./$(DEPDIR)/pcem-rom.Po + -rm -f ./$(DEPDIR)/pcem-rtc.Po + -rm -f ./$(DEPDIR)/pcem-rtc_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-scat.Po + -rm -f ./$(DEPDIR)/pcem-scsi.Po + -rm -f ./$(DEPDIR)/pcem-scsi_53c400.Po + -rm -f ./$(DEPDIR)/pcem-scsi_aha1540.Po + -rm -f ./$(DEPDIR)/pcem-scsi_cd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_hd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_zip.Po + -rm -f ./$(DEPDIR)/pcem-serial.Po + -rm -f ./$(DEPDIR)/pcem-sio.Po + -rm -f ./$(DEPDIR)/pcem-sis496.Po + -rm -f ./$(DEPDIR)/pcem-sl82c460.Po + -rm -f ./$(DEPDIR)/pcem-sound.Po + -rm -f ./$(DEPDIR)/pcem-sound_ad1848.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlib.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlibgold.Po + -rm -f ./$(DEPDIR)/pcem-sound_audiopci.Po + -rm -f ./$(DEPDIR)/pcem-sound_cms.Po + -rm -f ./$(DEPDIR)/pcem-sound_dbopl.Po + -rm -f ./$(DEPDIR)/pcem-sound_emu8k.Po + -rm -f ./$(DEPDIR)/pcem-sound_gus.Po + -rm -f ./$(DEPDIR)/pcem-sound_mpu401_uart.Po + -rm -f ./$(DEPDIR)/pcem-sound_opl.Po + -rm -f ./$(DEPDIR)/pcem-sound_pas16.Po + -rm -f ./$(DEPDIR)/pcem-sound_ps1.Po + -rm -f ./$(DEPDIR)/pcem-sound_pssj.Po + -rm -f ./$(DEPDIR)/pcem-sound_resid.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb_dsp.Po + -rm -f ./$(DEPDIR)/pcem-sound_sn76489.Po + -rm -f ./$(DEPDIR)/pcem-sound_speaker.Po + -rm -f ./$(DEPDIR)/pcem-sound_ssi2001.Po + -rm -f ./$(DEPDIR)/pcem-sound_wss.Po + -rm -f ./$(DEPDIR)/pcem-sound_ym7128.Po + -rm -f ./$(DEPDIR)/pcem-soundopenal.Po + -rm -f ./$(DEPDIR)/pcem-t1000.Po + -rm -f ./$(DEPDIR)/pcem-t3100e.Po + -rm -f ./$(DEPDIR)/pcem-tandy_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-tandy_rom.Po + -rm -f ./$(DEPDIR)/pcem-timer.Po + -rm -f ./$(DEPDIR)/pcem-um8669f.Po + -rm -f ./$(DEPDIR)/pcem-um8881f.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati18800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati28800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_mach64.Po + -rm -f ./$(DEPDIR)/pcem-vid_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_cl5429.Po + -rm -f ./$(DEPDIR)/pcem-vid_colorplus.Po + -rm -f ./$(DEPDIR)/pcem-vid_compaq_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_ega.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000w32.Po + -rm -f ./$(DEPDIR)/pcem-vid_genius.Po + -rm -f ./$(DEPDIR)/pcem-vid_hercules.Po + -rm -f ./$(DEPDIR)/pcem-vid_icd2061.Po + -rm -f ./$(DEPDIR)/pcem-vid_ics2595.Po + -rm -f ./$(DEPDIR)/pcem-vid_incolor.Po + -rm -f ./$(DEPDIR)/pcem-vid_mda.Po + -rm -f ./$(DEPDIR)/pcem-vid_olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti037.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti067.Po + -rm -f ./$(DEPDIR)/pcem-vid_paradise.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1512.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1640.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc200.Po + -rm -f ./$(DEPDIR)/pcem-vid_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-vid_ps1_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3_virge.Po + -rm -f ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_stg_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga_render.Po + -rm -f ./$(DEPDIR)/pcem-vid_t1000.Po + -rm -f ./$(DEPDIR)/pcem-vid_t3100e.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandy.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandysl.Po + -rm -f ./$(DEPDIR)/pcem-vid_tgui9440.Po + -rm -f ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_tvga.Po + -rm -f ./$(DEPDIR)/pcem-vid_unk_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_vga.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo.Po + -rm -f ./$(DEPDIR)/pcem-vid_wy700.Po + -rm -f ./$(DEPDIR)/pcem-video.Po + -rm -f ./$(DEPDIR)/pcem-wd76c10.Po + -rm -f ./$(DEPDIR)/pcem-wx-app.Po + -rm -f ./$(DEPDIR)/pcem-wx-common.Po + -rm -f ./$(DEPDIR)/pcem-wx-config.Po + -rm -f ./$(DEPDIR)/pcem-wx-config_sel.Po + -rm -f ./$(DEPDIR)/pcem-wx-createdisc.Po + -rm -f ./$(DEPDIR)/pcem-wx-deviceconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-dialogbox.Po + -rm -f ./$(DEPDIR)/pcem-wx-glslp-parser.Po + -rm -f ./$(DEPDIR)/pcem-wx-hostconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-joystickconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-main.Po + -rm -f ./$(DEPDIR)/pcem-wx-resources.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-midi.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2.Po + -rm -f ./$(DEPDIR)/pcem-wx-shader_man.Po + -rm -f ./$(DEPDIR)/pcem-wx-shaderconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-thread.Po + -rm -f ./$(DEPDIR)/pcem-wx-utils.Po + -rm -f ./$(DEPDIR)/pcem-x86seg.Po + -rm -f ./$(DEPDIR)/pcem-x87.Po + -rm -f ./$(DEPDIR)/pcem-xi8088.Po + -rm -f ./$(DEPDIR)/pcem-xtide.Po + -rm -f dosbox/$(DEPDIR)/pcem-cdrom_image.Po + -rm -f dosbox/$(DEPDIR)/pcem-dbopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-nukedopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve-sse.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve.Po + -rm -f resid-fp/$(DEPDIR)/pcem-envelope.Po + -rm -f resid-fp/$(DEPDIR)/pcem-extfilt.Po + -rm -f resid-fp/$(DEPDIR)/pcem-filter.Po + -rm -f resid-fp/$(DEPDIR)/pcem-pot.Po + -rm -f resid-fp/$(DEPDIR)/pcem-sid.Po + -rm -f resid-fp/$(DEPDIR)/pcem-voice.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po + -rm -f slirp/$(DEPDIR)/pcem-bootp.Po + -rm -f slirp/$(DEPDIR)/pcem-cksum.Po + -rm -f slirp/$(DEPDIR)/pcem-debug.Po + -rm -f slirp/$(DEPDIR)/pcem-if.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_icmp.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_input.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_output.Po + -rm -f slirp/$(DEPDIR)/pcem-mbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-misc.Po + -rm -f slirp/$(DEPDIR)/pcem-queue.Po + -rm -f slirp/$(DEPDIR)/pcem-sbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-slirp.Po + -rm -f slirp/$(DEPDIR)/pcem-socket.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_input.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_output.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_subr.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_timer.Po + -rm -f slirp/$(DEPDIR)/pcem-tftp.Po + -rm -f slirp/$(DEPDIR)/pcem-udp.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -4941,7 +5559,275 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) + -rm -f ./$(DEPDIR)/pcem-386.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec_ops.Po + -rm -f ./$(DEPDIR)/pcem-808x.Po + -rm -f ./$(DEPDIR)/pcem-acc2036.Po + -rm -f ./$(DEPDIR)/pcem-acer386sx.Po + -rm -f ./$(DEPDIR)/pcem-ali1429.Po + -rm -f ./$(DEPDIR)/pcem-amstrad.Po + -rm -f ./$(DEPDIR)/pcem-cbm_io.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-image.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-null.Po + -rm -f ./$(DEPDIR)/pcem-cmd640.Po + -rm -f ./$(DEPDIR)/pcem-codegen.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ir.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_486.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_686.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_common.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_pentium.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip.Po + -rm -f ./$(DEPDIR)/pcem-compaq.Po + -rm -f ./$(DEPDIR)/pcem-config.Po + -rm -f ./$(DEPDIR)/pcem-cpu.Po + -rm -f ./$(DEPDIR)/pcem-dells200.Po + -rm -f ./$(DEPDIR)/pcem-device.Po + -rm -f ./$(DEPDIR)/pcem-disc.Po + -rm -f ./$(DEPDIR)/pcem-disc_fdi.Po + -rm -f ./$(DEPDIR)/pcem-disc_img.Po + -rm -f ./$(DEPDIR)/pcem-disc_sector.Po + -rm -f ./$(DEPDIR)/pcem-dma.Po + -rm -f ./$(DEPDIR)/pcem-esdi_at.Po + -rm -f ./$(DEPDIR)/pcem-fdc.Po + -rm -f ./$(DEPDIR)/pcem-fdc37c665.Po + -rm -f ./$(DEPDIR)/pcem-fdd.Po + -rm -f ./$(DEPDIR)/pcem-fdi2raw.Po + -rm -f ./$(DEPDIR)/pcem-gameport.Po + -rm -f ./$(DEPDIR)/pcem-hdd.Po + -rm -f ./$(DEPDIR)/pcem-hdd_esdi.Po + -rm -f ./$(DEPDIR)/pcem-hdd_file.Po + -rm -f ./$(DEPDIR)/pcem-headland.Po + -rm -f ./$(DEPDIR)/pcem-i430fx.Po + -rm -f ./$(DEPDIR)/pcem-i430lx.Po + -rm -f ./$(DEPDIR)/pcem-i430vx.Po + -rm -f ./$(DEPDIR)/pcem-ide.Po + -rm -f ./$(DEPDIR)/pcem-ide_atapi.Po + -rm -f ./$(DEPDIR)/pcem-intel.Po + -rm -f ./$(DEPDIR)/pcem-intel_flash.Po + -rm -f ./$(DEPDIR)/pcem-io.Po + -rm -f ./$(DEPDIR)/pcem-jim.Po + -rm -f ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po + -rm -f ./$(DEPDIR)/pcem-joystick_standard.Po + -rm -f ./$(DEPDIR)/pcem-joystick_sw_pad.Po + -rm -f ./$(DEPDIR)/pcem-joystick_tm_fcs.Po + -rm -f ./$(DEPDIR)/pcem-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_amstrad.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_at.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_olim24.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_xt.Po + -rm -f ./$(DEPDIR)/pcem-laserxt.Po + -rm -f ./$(DEPDIR)/pcem-lpt.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dac.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dss.Po + -rm -f ./$(DEPDIR)/pcem-mca.Po + -rm -f ./$(DEPDIR)/pcem-mcr.Po + -rm -f ./$(DEPDIR)/pcem-mem.Po + -rm -f ./$(DEPDIR)/pcem-mem_bios.Po + -rm -f ./$(DEPDIR)/pcem-mfm_at.Po + -rm -f ./$(DEPDIR)/pcem-mfm_xebec.Po + -rm -f ./$(DEPDIR)/pcem-midi_alsa.Po + -rm -f ./$(DEPDIR)/pcem-model.Po + -rm -f ./$(DEPDIR)/pcem-mouse.Po + -rm -f ./$(DEPDIR)/pcem-mouse_msystems.Po + -rm -f ./$(DEPDIR)/pcem-mouse_ps2.Po + -rm -f ./$(DEPDIR)/pcem-mouse_serial.Po + -rm -f ./$(DEPDIR)/pcem-ne2000.Po + -rm -f ./$(DEPDIR)/pcem-neat.Po + -rm -f ./$(DEPDIR)/pcem-nethandler.Po + -rm -f ./$(DEPDIR)/pcem-nmi.Po + -rm -f ./$(DEPDIR)/pcem-nvr.Po + -rm -f ./$(DEPDIR)/pcem-nvr_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-opti495.Po + -rm -f ./$(DEPDIR)/pcem-paths.Po + -rm -f ./$(DEPDIR)/pcem-pc.Po + -rm -f ./$(DEPDIR)/pcem-pc87306.Po + -rm -f ./$(DEPDIR)/pcem-pci.Po + -rm -f ./$(DEPDIR)/pcem-pic.Po + -rm -f ./$(DEPDIR)/pcem-piix.Po + -rm -f ./$(DEPDIR)/pcem-pit.Po + -rm -f ./$(DEPDIR)/pcem-ppi.Po + -rm -f ./$(DEPDIR)/pcem-ps1.Po + -rm -f ./$(DEPDIR)/pcem-ps2.Po + -rm -f ./$(DEPDIR)/pcem-ps2_mca.Po + -rm -f ./$(DEPDIR)/pcem-ps2_nvr.Po + -rm -f ./$(DEPDIR)/pcem-rom.Po + -rm -f ./$(DEPDIR)/pcem-rtc.Po + -rm -f ./$(DEPDIR)/pcem-rtc_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-scat.Po + -rm -f ./$(DEPDIR)/pcem-scsi.Po + -rm -f ./$(DEPDIR)/pcem-scsi_53c400.Po + -rm -f ./$(DEPDIR)/pcem-scsi_aha1540.Po + -rm -f ./$(DEPDIR)/pcem-scsi_cd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_hd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_zip.Po + -rm -f ./$(DEPDIR)/pcem-serial.Po + -rm -f ./$(DEPDIR)/pcem-sio.Po + -rm -f ./$(DEPDIR)/pcem-sis496.Po + -rm -f ./$(DEPDIR)/pcem-sl82c460.Po + -rm -f ./$(DEPDIR)/pcem-sound.Po + -rm -f ./$(DEPDIR)/pcem-sound_ad1848.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlib.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlibgold.Po + -rm -f ./$(DEPDIR)/pcem-sound_audiopci.Po + -rm -f ./$(DEPDIR)/pcem-sound_cms.Po + -rm -f ./$(DEPDIR)/pcem-sound_dbopl.Po + -rm -f ./$(DEPDIR)/pcem-sound_emu8k.Po + -rm -f ./$(DEPDIR)/pcem-sound_gus.Po + -rm -f ./$(DEPDIR)/pcem-sound_mpu401_uart.Po + -rm -f ./$(DEPDIR)/pcem-sound_opl.Po + -rm -f ./$(DEPDIR)/pcem-sound_pas16.Po + -rm -f ./$(DEPDIR)/pcem-sound_ps1.Po + -rm -f ./$(DEPDIR)/pcem-sound_pssj.Po + -rm -f ./$(DEPDIR)/pcem-sound_resid.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb_dsp.Po + -rm -f ./$(DEPDIR)/pcem-sound_sn76489.Po + -rm -f ./$(DEPDIR)/pcem-sound_speaker.Po + -rm -f ./$(DEPDIR)/pcem-sound_ssi2001.Po + -rm -f ./$(DEPDIR)/pcem-sound_wss.Po + -rm -f ./$(DEPDIR)/pcem-sound_ym7128.Po + -rm -f ./$(DEPDIR)/pcem-soundopenal.Po + -rm -f ./$(DEPDIR)/pcem-t1000.Po + -rm -f ./$(DEPDIR)/pcem-t3100e.Po + -rm -f ./$(DEPDIR)/pcem-tandy_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-tandy_rom.Po + -rm -f ./$(DEPDIR)/pcem-timer.Po + -rm -f ./$(DEPDIR)/pcem-um8669f.Po + -rm -f ./$(DEPDIR)/pcem-um8881f.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati18800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati28800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_mach64.Po + -rm -f ./$(DEPDIR)/pcem-vid_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_cl5429.Po + -rm -f ./$(DEPDIR)/pcem-vid_colorplus.Po + -rm -f ./$(DEPDIR)/pcem-vid_compaq_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_ega.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000w32.Po + -rm -f ./$(DEPDIR)/pcem-vid_genius.Po + -rm -f ./$(DEPDIR)/pcem-vid_hercules.Po + -rm -f ./$(DEPDIR)/pcem-vid_icd2061.Po + -rm -f ./$(DEPDIR)/pcem-vid_ics2595.Po + -rm -f ./$(DEPDIR)/pcem-vid_incolor.Po + -rm -f ./$(DEPDIR)/pcem-vid_mda.Po + -rm -f ./$(DEPDIR)/pcem-vid_olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti037.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti067.Po + -rm -f ./$(DEPDIR)/pcem-vid_paradise.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1512.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1640.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc200.Po + -rm -f ./$(DEPDIR)/pcem-vid_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-vid_ps1_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3_virge.Po + -rm -f ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_stg_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga_render.Po + -rm -f ./$(DEPDIR)/pcem-vid_t1000.Po + -rm -f ./$(DEPDIR)/pcem-vid_t3100e.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandy.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandysl.Po + -rm -f ./$(DEPDIR)/pcem-vid_tgui9440.Po + -rm -f ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_tvga.Po + -rm -f ./$(DEPDIR)/pcem-vid_unk_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_vga.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo.Po + -rm -f ./$(DEPDIR)/pcem-vid_wy700.Po + -rm -f ./$(DEPDIR)/pcem-video.Po + -rm -f ./$(DEPDIR)/pcem-wd76c10.Po + -rm -f ./$(DEPDIR)/pcem-wx-app.Po + -rm -f ./$(DEPDIR)/pcem-wx-common.Po + -rm -f ./$(DEPDIR)/pcem-wx-config.Po + -rm -f ./$(DEPDIR)/pcem-wx-config_sel.Po + -rm -f ./$(DEPDIR)/pcem-wx-createdisc.Po + -rm -f ./$(DEPDIR)/pcem-wx-deviceconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-dialogbox.Po + -rm -f ./$(DEPDIR)/pcem-wx-glslp-parser.Po + -rm -f ./$(DEPDIR)/pcem-wx-hostconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-joystickconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-main.Po + -rm -f ./$(DEPDIR)/pcem-wx-resources.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-midi.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2.Po + -rm -f ./$(DEPDIR)/pcem-wx-shader_man.Po + -rm -f ./$(DEPDIR)/pcem-wx-shaderconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-thread.Po + -rm -f ./$(DEPDIR)/pcem-wx-utils.Po + -rm -f ./$(DEPDIR)/pcem-x86seg.Po + -rm -f ./$(DEPDIR)/pcem-x87.Po + -rm -f ./$(DEPDIR)/pcem-xi8088.Po + -rm -f ./$(DEPDIR)/pcem-xtide.Po + -rm -f dosbox/$(DEPDIR)/pcem-cdrom_image.Po + -rm -f dosbox/$(DEPDIR)/pcem-dbopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-nukedopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve-sse.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve.Po + -rm -f resid-fp/$(DEPDIR)/pcem-envelope.Po + -rm -f resid-fp/$(DEPDIR)/pcem-extfilt.Po + -rm -f resid-fp/$(DEPDIR)/pcem-filter.Po + -rm -f resid-fp/$(DEPDIR)/pcem-pot.Po + -rm -f resid-fp/$(DEPDIR)/pcem-sid.Po + -rm -f resid-fp/$(DEPDIR)/pcem-voice.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po + -rm -f slirp/$(DEPDIR)/pcem-bootp.Po + -rm -f slirp/$(DEPDIR)/pcem-cksum.Po + -rm -f slirp/$(DEPDIR)/pcem-debug.Po + -rm -f slirp/$(DEPDIR)/pcem-if.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_icmp.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_input.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_output.Po + -rm -f slirp/$(DEPDIR)/pcem-mbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-misc.Po + -rm -f slirp/$(DEPDIR)/pcem-queue.Po + -rm -f slirp/$(DEPDIR)/pcem-sbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-slirp.Po + -rm -f slirp/$(DEPDIR)/pcem-socket.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_input.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_output.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_subr.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_timer.Po + -rm -f slirp/$(DEPDIR)/pcem-tftp.Po + -rm -f slirp/$(DEPDIR)/pcem-udp.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -4961,7 +5847,7 @@ uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ diff --git a/src/codegen.c b/src/codegen.c index 8256ab2..7e0dc9f 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2,6 +2,13 @@ #include "x86_ops.h" #include "mem.h" #include "codegen.h" +#include "x86.h" + +#include "codegen_backend.h" +#include "codegen_ir.h" + +codeblock_t *codeblock; +codeblock_t **codeblock_hash; void (*codegen_timing_start)(); void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); @@ -19,3 +26,39 @@ void codegen_timing_set(codegen_timing_t *timing) } int codegen_in_recompile; + + +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]; + ir_data_t *ir = codegen_get_ir_data(); + uint32_t op_pc = new_pc; + OpFn *op_table = x86_dynarec_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + uint32_t op_32 = use32; + + + //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + + uop_STORE_PTR_IMM(ir, &cpu_state.pc, op_pc); + uop_STORE_PTR_IMM(ir, &cpu_state.oldpc, old_pc); + uop_STORE_PTR_IMM(ir, &cpu_state.op32, op_32); + uop_STORE_PTR_IMM(ir, &cpu_state.ea_seg, (uintptr_t)&_ds); + uop_STORE_PTR_IMM_8(ir, &cpu_state.ssegs, 0); + uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); + uop_CALL_INSTRUCTION_FUNC(ir, op); + + //codegen_block_ins++; + + block->ins++; + + if (block->ins >= 50) + CPU_BLOCK_END(); + +// addbyte(0xE8); /*CALL*/ +// addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4]))); + + codegen_endpc = (cs + cpu_state.pc) + 8; +} diff --git a/src/codegen.h b/src/codegen.h index c5ad1ed..def016c 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -4,14 +4,6 @@ #include "mem.h" #include "x86_ops.h" -#ifdef __amd64__ -#include "codegen_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 -#include "codegen_x86.h" -#else -#error Dynamic recompiler not implemented on your platform -#endif - /*Handling self-modifying code (of which there is a lot on x86) : PCem tracks a 'dirty mask' for each physical page, in which each bit @@ -37,6 +29,9 @@ same page). */ +/*Hack until better memory management written*/ +#define BLOCK_DATA_SIZE 0x10000 + typedef struct codeblock_t { uint64_t page_mask, page_mask2; @@ -66,7 +61,7 @@ typedef struct codeblock_t uint32_t status; uint32_t flags; - uint8_t data[2048]; + uint8_t data[BLOCK_DATA_SIZE]; } codeblock_t; /*Code block uses FPU*/ @@ -311,45 +306,6 @@ extern int block_pos; #define CPU_BLOCK_END() cpu_block_end = 1 -static inline void addbyte(uint8_t val) -{ - codeblock[block_current].data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addword(uint16_t val) -{ - *(uint16_t *)(void *)&codeblock[block_current].data[block_pos] = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addlong(uint32_t val) -{ - *(uint32_t *)&codeblock[block_current].data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addquad(uint64_t val) -{ - *(uint64_t *)&codeblock[block_current].data[block_pos] = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - /*Current physical page of block being recompiled. -1 if no recompilation taking place */ extern uint32_t recomp_page; diff --git a/src/codegen_backend.c b/src/codegen_backend.c new file mode 100644 index 0000000..a6ece39 --- /dev/null +++ b/src/codegen_backend.c @@ -0,0 +1,416 @@ +#include +#include "ibm.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_backend.h" +#include "codegen_ir.h" + +int codegen_flat_ds, codegen_flat_ss; +int mmx_ebx_ecx_loaded; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_mmx_entered = 0; +int codegen_fpu_loaded_iq[8]; +x86seg *op_ea_seg; +int op_ssegs; +uint32_t op_old_pc; + +uint32_t recomp_page = -1; + +int block_current = 0; +static int block_num; +int block_pos; + +int cpu_recomp_flushes, cpu_recomp_flushes_latched; +int cpu_recomp_evicted, cpu_recomp_evicted_latched; +int cpu_recomp_reuse, cpu_recomp_reuse_latched; +int cpu_recomp_removed, cpu_recomp_removed_latched; + +uint32_t codegen_endpc; + +int codegen_block_cycles; +static int codegen_block_ins; +static int codegen_block_full_ins; + +static uint32_t last_op32; +static x86seg *last_ea_seg; +static int last_ssegs; + + +void codegen_init() +{ + codegen_backend_init(); +} + +void codegen_reset() +{ + int c; + + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + mem_reset_page_blocks(); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; +} + +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[(block->phys >> 10) & 3]; + + if (!block->page_mask) + fatal("add_to_block_list - mask = 0\n"); + + if (block_prev) + { + block->next = block_prev; + block_prev->prev = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } + else + { + block->next = NULL; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } + + if (block->next) + { + if (block->next->pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); + } + + if (block->page_mask2) + { + 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->phys_2 >> 10) & 3] = block; + } + else + { + block->next_2 = NULL; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + } + } +} + +static void remove_from_block_list(codeblock_t *block, uint32_t pc) +{ + if (!block->page_mask) + return; + + if (block->prev) + { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + else + { + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; + if (block->next) + block->next->prev = NULL; + else + mem_flush_write_page(block->phys, 0); + } + if (!block->page_mask2) + { + if (block->prev_2 || block->next_2) + fatal("Invalid block_2\n"); + return; + } + + if (block->prev_2) + { + block->prev_2->next_2 = block->next_2; + if (block->next_2) + block->next_2->prev_2 = block->prev_2; + } + 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; + else + mem_flush_write_page(block->phys_2, 0); + } +} + +static void delete_block(codeblock_t *block) +{ + uint32_t old_pc = block->pc; + + if (block == codeblock_hash[HASH(block->phys)]) + codeblock_hash[HASH(block->phys)] = NULL; + + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); + block->pc = BLOCK_PC_INVALID; + + codeblock_tree_delete(block); + remove_from_block_list(block, old_pc); +} + +void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +{ + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; + + while (block) + { + if (mask & block->page_mask) + { + delete_block(block); + cpu_recomp_evicted++; + } + if (block == block->next) + fatal("Broken 1\n"); + block = block->next; + } + + block = page->block_2[(phys_addr >> 10) & 3]; + + while (block) + { + if (mask & block->page_mask2) + { + delete_block(block); + cpu_recomp_evicted++; + } + if (block == block->next_2) + fatal("Broken 2\n"); + block = block->next_2; + } +} + +void codegen_block_init(uint32_t phys_addr) +{ + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; + + 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 != BLOCK_PC_INVALID) + { +// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); + delete_block(block); + cpu_recomp_reuse++; + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; + + block->ins = 0; + block->pc = cs + cpu_state.pc; + 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; + block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; + + block->was_recompiled = 0; + + recomp_page = block->phys & ~0xfff; + + codeblock_tree_add(block); +} + +static ir_data_t *ir_data; + +ir_data_t *codegen_get_ir_data() +{ + return ir_data; +} + +void codegen_block_start_recompile(codeblock_t *block) +{ + page_t *page = &pages[block->phys >> 12]; + + if (!page->block[(block->phys >> 10) & 3]) + mem_flush_write_page(block->phys, cs+cpu_state.pc); + + block_num = HASH(block->phys); + block_current = block->pnt; + + if (block->pc != cs + cpu_state.pc || block->was_recompiled) + fatal("Recompile to used block!\n"); + + block->status = cpu_cur_status; + + cpu_block_end = 0; + +// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); + + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; + + codegen_block_cycles = 0; + codegen_timing_block_start(); + + codegen_block_ins = 0; + codegen_block_full_ins = 0; + + recomp_page = block->phys & ~0xfff; + + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; + + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = + codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + + _ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1; + + block->TOP = cpu_state.TOP; + block->was_recompiled = 1; + + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + + ir_data = codegen_ir_init(); +} + + +void codegen_block_remove() +{ + codeblock_t *block = &codeblock[block_current]; + + delete_block(block); + cpu_recomp_removed++; + + recomp_page = -1; +} + +void codegen_block_generate_end_mask() +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + + block->endpc = codegen_endpc; + + block->page_mask = 0; + 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->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) & ~0x3ff) + { + block->phys_2 = get_phys_noabrt(block->endpc); + if (block->phys_2 != -1) + { + page_t *page_2 = &pages[block->phys_2 >> 12]; + + start_pc = 0; + 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[(block->phys_2 >> 10) & 3]) + mem_flush_write_page(block->phys_2, block->endpc); + + 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 == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %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; +} + +void codegen_block_end() +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + + remove_from_block_list(block, block->pc); + block->next = block->prev = NULL; + 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; + + codegen_ir_compile(ir_data, block); +} + +void codegen_flush() +{ + return; +} diff --git a/src/codegen_backend.h b/src/codegen_backend.h new file mode 100644 index 0000000..f281b75 --- /dev/null +++ b/src/codegen_backend.h @@ -0,0 +1,65 @@ +//#ifdef __amd64__ +//#include "codegen_x86-64.h" +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#include "codegen_backend_x86.h" +#elif defined __amd64__ +#include "codegen_backend_x86-64.h" +#elif defined __ARM_EABI__ +#include "codegen_backend_arm.h" +#elif defined __aarch64__ +#include "codegen_backend_arm64.h" +#else +#error Dynamic recompiler not implemented on your platform +#endif + +void codegen_backend_init(); +void codegen_backend_prologue(codeblock_t *block); +void codegen_backend_epilogue(codeblock_t *block); + +static inline void addbyte(uint8_t val) +{ + codeblock[block_current].data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addword(uint16_t val) +{ + *(uint16_t *)(void *)&codeblock[block_current].data[block_pos] = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addlong(uint32_t val) +{ + *(uint32_t *)&codeblock[block_current].data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +static inline void addquad(uint64_t val) +{ + *(uint64_t *)&codeblock[block_current].data[block_pos] = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + CPU_BLOCK_END(); + } +} + +struct ir_data_t; +struct uop_t; + +struct ir_data_t *codegen_get_ir_data(); + +typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop); + +extern const uOpFn uop_handlers[]; diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c new file mode 100644 index 0000000..9f0be91 --- /dev/null +++ b/src/codegen_backend_arm.c @@ -0,0 +1,101 @@ +#ifdef __ARM_EABI__ + +#include +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_arm_defs.h" +#include "x86.h" + +#if defined(__linux__) || defined(__APPLE__) +#include +#include +#endif +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#endif + +void codegen_backend_init() +{ + int c; +#if defined(__linux__) || defined(__APPLE__) + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); +#endif + +#if defined WIN32 || defined _WIN32 || defined _WIN32 + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); +#endif + if (!codeblock) + fatal("codeblock failed to alloc - %i\n", (BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + + memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; + +#if defined(__linux__) || defined(__APPLE__) + start = (void *)((long)codeblock & pagemask); + len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + { + perror("mprotect"); + exit(-1); + } +#endif +// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); +} + +/*R11 - literal pool + R10 - cpu_state*/ +void codegen_backend_prologue(codeblock_t *block) +{ + int offset; + + codegen_reset_literal_pool(block); + + block_pos = 0; + + block_pos = BLOCK_GPF_OFFSET; + host_arm_MOV_IMM(block, REG_R0, 0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_call(block, x86gpf); + while (block_pos != BLOCK_EXIT_OFFSET) + host_arm_nop(block); + + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10); + host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC); + while (block_pos != BLOCK_START) + host_arm_nop(block); + + /*Entry code*/ + + host_arm_STMDB_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_LR); + host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x10); + host_arm_ADD_IMM(block, REG_LITERAL, REG_PC, ARM_LITERAL_POOL_OFFSET); + host_arm_SUB_IMM(block, REG_LITERAL, REG_LITERAL, 16 + BLOCK_START); + offset = add_literal(block, (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_CPUSTATE, REG_R11, offset); +} + +void codegen_backend_epilogue(codeblock_t *block) +{ + host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10); + host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC); + + if (block_pos > ARM_LITERAL_POOL_OFFSET) + fatal("Over limit!\n"); + + + + __clear_cache(&block->data[0], &block->data[block_pos]); +} + +#endif diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h new file mode 100644 index 0000000..43b3fad --- /dev/null +++ b/src/codegen_backend_arm.h @@ -0,0 +1,33 @@ +#define BLOCK_SIZE 0x1000 +#define BLOCK_MASK 0x0fff +#define BLOCK_START 32 + +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff + +#define HASH(l) ((l) & 0x1ffff) + +/*Hack until better memory management written*/ +/*#define BLOCK_EXIT_OFFSET 0x7f0*/ + +#define BLOCK_GPF_OFFSET 0 +#define BLOCK_EXIT_OFFSET 16 + +#define ARM_LITERAL_POOL_OFFSET 0xf000 + +/*#define BLOCK_MAX 1720*/ +#define BLOCK_MAX 65208 + + +void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); +void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); +void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm); +void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); +void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); + +void host_arm_call(codeblock_t *block, void *dst_addr); +void host_arm_nop(codeblock_t *block); + +void codegen_reset_literal_pool(codeblock_t *block); +int add_literal(codeblock_t *block, uint32_t data); diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c new file mode 100644 index 0000000..5fb6115 --- /dev/null +++ b/src/codegen_backend_arm64.c @@ -0,0 +1,115 @@ +#ifdef __aarch64__ + +#include +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_arm64_defs.h" +#include "x86.h" + +#if defined(__linux__) || defined(__APPLE__) +#include +#include +#endif +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#endif + +void codegen_backend_init() +{ + int c; +#if defined(__linux__) || defined(__APPLE__) + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); +#endif + +#if defined WIN32 || defined _WIN32 || defined _WIN32 + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); +#endif + if (!codeblock) + fatal("codeblock failed to alloc - %i\n", (BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + + memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; + +#if defined(__linux__) || defined(__APPLE__) + start = (void *)((long)codeblock & pagemask); + len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + { + perror("mprotect"); + exit(-1); + } +#endif +// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); +} + +/*R11 - literal pool + R10 - cpu_state*/ +void codegen_backend_prologue(codeblock_t *block) +{ + int offset; + + codegen_reset_literal_pool(block); + + block_pos = 0; + + block_pos = BLOCK_GPF_OFFSET; + host_arm64_mov_imm(block, REG_ARG0, 0); + host_arm64_mov_imm(block, REG_ARG1, 0); + host_arm64_call(block, x86gpf); + while (block_pos != BLOCK_EXIT_OFFSET) + host_arm64_NOP(block); + + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_RET(block, REG_X30); + + while (block_pos != BLOCK_START) + host_arm64_NOP(block); + + /*Entry code*/ + + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -16); + + offset = add_literal_q(block, (uintptr_t)&cpu_state); + host_arm64_LDR_LITERAL_X(block, REG_CPUSTATE, offset); +} + +void codegen_backend_epilogue(codeblock_t *block) +{ + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_RET(block, REG_X30); + + if (block_pos > ARM_LITERAL_POOL_OFFSET) + fatal("Over limit!\n"); + + + + __clear_cache(&block->data[0], &block->data[block_pos]); +} + +#endif diff --git a/src/codegen_backend_arm64.h b/src/codegen_backend_arm64.h new file mode 100644 index 0000000..6943eb6 --- /dev/null +++ b/src/codegen_backend_arm64.h @@ -0,0 +1,40 @@ +#define BLOCK_SIZE 0x1000 +#define BLOCK_MASK 0x0fff +#define BLOCK_START 64 + +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff + +#define HASH(l) ((l) & 0x1ffff) + +/*Hack until better memory management written*/ +/*#define BLOCK_EXIT_OFFSET 0x7f0*/ + +#define BLOCK_GPF_OFFSET 0 +#define BLOCK_EXIT_OFFSET 32 + +#define ARM_LITERAL_POOL_OFFSET 0xf000 + +/*#define BLOCK_MAX 1720*/ +#define BLOCK_MAX 65208 + + +void host_arm64_BLR(codeblock_t *block, int addr_reg); +void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); +void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data); +void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data); +void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); +void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset); +void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset); +void host_arm64_NOP(codeblock_t *block); +void host_arm64_RET(codeblock_t *block, int reg); +void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); +void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_STRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); + +void host_arm64_call(codeblock_t *block, void *dst_addr); +void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); + +void codegen_reset_literal_pool(codeblock_t *block); +int add_literal(codeblock_t *block, uint32_t data); +int add_literal_q(codeblock_t *block, uint64_t data); diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h new file mode 100644 index 0000000..d70990a --- /dev/null +++ b/src/codegen_backend_arm64_defs.h @@ -0,0 +1,72 @@ +#define REG_W0 0 +#define REG_W1 1 +#define REG_W2 2 +#define REG_W3 3 +#define REG_W4 4 +#define REG_W5 5 +#define REG_W6 6 +#define REG_W7 7 +#define REG_W8 8 +#define REG_W9 9 +#define REG_W10 10 +#define REG_W11 11 +#define REG_W12 12 +#define REG_W13 13 +#define REG_W14 14 +#define REG_W15 15 +#define REG_W16 16 +#define REG_W17 17 +#define REG_W18 18 +#define REG_W19 19 +#define REG_W20 20 +#define REG_W21 21 +#define REG_W22 22 +#define REG_W23 23 +#define REG_W24 24 +#define REG_W25 25 +#define REG_W26 26 +#define REG_W27 27 +#define REG_W28 28 +#define REG_W29 29 +#define REG_W30 30 + +#define REG_X0 0 +#define REG_X1 1 +#define REG_X2 2 +#define REG_X3 3 +#define REG_X4 4 +#define REG_X5 5 +#define REG_X6 6 +#define REG_X7 7 +#define REG_X8 8 +#define REG_X9 9 +#define REG_X10 10 +#define REG_X11 11 +#define REG_X12 12 +#define REG_X13 13 +#define REG_X14 14 +#define REG_X15 15 +#define REG_X16 16 +#define REG_X17 17 +#define REG_X18 18 +#define REG_X19 19 +#define REG_X20 20 +#define REG_X21 21 +#define REG_X22 22 +#define REG_X23 23 +#define REG_X24 24 +#define REG_X25 25 +#define REG_X26 26 +#define REG_X27 27 +#define REG_X28 28 +#define REG_X29 29 +#define REG_X30 30 + +#define REG_SP 31 + +#define REG_ARG0 REG_X0 +#define REG_ARG1 REG_X1 +#define REG_ARG2 REG_X2 +#define REG_ARG3 REG_X3 + +#define REG_CPUSTATE REG_X29 \ No newline at end of file diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c new file mode 100644 index 0000000..ee29eb2 --- /dev/null +++ b/src/codegen_backend_arm64_uops.c @@ -0,0 +1,300 @@ +#ifdef __aarch64__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_arm64_defs.h" +#include "codegen_ir_defs.h" + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +#define Rt(x) (x) +#define Rd(x) (x) +#define Rn(x) ((x) << 5) +#define Rt2(x) ((x) << 10) + +#define DATA_OFFSET_UP (1 << 23) +#define DATA_OFFSET_DOWN (0 << 23) + +#define COND_SHIFT 28 +#define COND_NE (0x1 << COND_SHIFT) +#define COND_AL (0xe << COND_SHIFT) + +#define OPCODE_SHIFT 24 +#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) +#define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) +#define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) + +#define OPCODE_MOVK_W (0x0e5 << 23) +#define OPCODE_MOVZ_W (0x0a5 << 23) + +#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) +#define OPCODE_STP_PREIDX_X (0x2a6 << 22) +#define OPCODE_STR_IMM_W (0x2e4 << 22) +#define OPCODE_STRB_IMM (0x0e4 << 22) + +#define OPCODE_BLR (0xd63f0000) +#define OPCODE_NOP (0xd503201f) +#define OPCODE_RET (0xd65f0000) + +#define MOV_WIDE_HW(hw) (hw << 21) + +#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) +#define IMM16(imm_data) (imm_data << 5) + +#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) + +#define OFFSET12_B(offset) (offset << 10) +#define OFFSET12_W(offset) ((offset >> 2) << 10) + +static int literal_offset = 0; +void codegen_reset_literal_pool(codeblock_t *block) +{ + literal_offset = 0; +} + +/*Returns true if offset fits into 19 bits*/ +static int offset_is_19bit(int offset) +{ + if (offset >= (1 << (18+2))) + return 0; + if (offset < -(1 << (18+2))) + return 0; + return 1; +} + +#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) +#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) +#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) + +int add_literal(codeblock_t *block, uint32_t data) +{ + if (literal_offset >= 4096) + fatal("add_literal - literal pool full\n"); + + *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; + + literal_offset += 4; + + return literal_offset - 4; +} + +int add_literal_q(codeblock_t *block, uint64_t data) +{ + if (literal_offset & 4) + literal_offset += 4; + + if (literal_offset >= 4096-4) + fatal("add_literal - literal pool full\n"); + + *(uint64_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; + + literal_offset += 8; + + return literal_offset - 8; +} + +static inline int imm_is_imm16(uint32_t imm_data) +{ + if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) + return 1; + return 0; +} + + +void host_arm64_BLR(codeblock_t *block, int addr_reg) +{ + codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); +} + +void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) +{ + int offset = dest - (uintptr_t)&block->data[block_pos]; + if (!offset_is_19bit(offset)) + fatal("host_arm64_CBNZ - offset out of range %x\n", offset); + codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); +} + +void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +{ + if (!in_range7_x(offset)) + fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); +} + +void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset) +{ + int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; + + if (!offset_is_19bit(offset)) + fatal("host_arm64_CBNZ - offset out of range %x\n", offset); + + codegen_addlong(block, OPCODE_LDR_LITERAL_W | OFFSET19(offset) | Rt(dest_reg)); +} +void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset) +{ + int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; + + if (!offset_is_19bit(offset)) + fatal("host_arm64_CBNZ - offset out of range %x\n", offset); + + codegen_addlong(block, OPCODE_LDR_LITERAL_X | OFFSET19(offset) | Rt(dest_reg)); +} + +void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + int hw; + + if (!imm_is_imm16(imm_data)) + fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); + + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; + + codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); +} + +void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + int hw; + + if (!imm_is_imm16(imm_data)) + fatal("MOVK_IMM - imm not representable %08x\n", imm_data); + + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; + + codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); +} + +void host_arm64_NOP(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_NOP); +} + +void host_arm64_RET(codeblock_t *block, int reg) +{ + codegen_addlong(block, OPCODE_RET | Rn(reg)); +} + +void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +{ + if (!in_range7_x(offset)) + fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); +} + +void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_w(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_b(offset)) + fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); +} + + +void host_arm64_call(codeblock_t *block, void *dst_addr) +{ + int offset = add_literal_q(block, (uintptr_t)dst_addr); + host_arm64_LDR_LITERAL_X(block, REG_X16, offset); + host_arm64_BLR(block, REG_X16); +} + +void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) +{ + if (imm_is_imm16(imm_data)) + host_arm64_MOVZ_IMM(block, reg, imm_data); + else + { + host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); + } +} + + +static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm64_call(block, uop->p); + host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + + return 0; +} +static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + + return 0; +} +static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + + return 0; +} + +static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, REG_W16, uop->imm_data); + + if (in_range12_w((uintptr_t)uop->p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} +static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, REG_W16, uop->imm_data); + + if (in_range12_b((uintptr_t)uop->p - (uintptr_t)&cpu_state)) + host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = +{ + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 +}; + +#endif diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h new file mode 100644 index 0000000..a9253ab --- /dev/null +++ b/src/codegen_backend_arm_defs.h @@ -0,0 +1,44 @@ +#define REG_R0 0 +#define REG_R1 1 +#define REG_R2 2 +#define REG_R3 3 +#define REG_R4 4 +#define REG_R5 5 +#define REG_R6 6 +#define REG_R7 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_SP 13 +#define REG_LR 14 +#define REG_PC 15 + +#define REG_ARG0 REG_R0 +#define REG_ARG1 REG_R1 +#define REG_ARG2 REG_R2 +#define REG_ARG3 REG_R3 + +#define REG_CPUSTATE REG_R10 +#define REG_LITERAL REG_R11 + +#define REG_MASK_R0 (1 << REG_R0) +#define REG_MASK_R1 (1 << REG_R1) +#define REG_MASK_R2 (1 << REG_R2) +#define REG_MASK_R3 (1 << REG_R3) +#define REG_MASK_R4 (1 << REG_R4) +#define REG_MASK_R5 (1 << REG_R5) +#define REG_MASK_R6 (1 << REG_R6) +#define REG_MASK_R7 (1 << REG_R7) +#define REG_MASK_R8 (1 << REG_R8) +#define REG_MASK_R9 (1 << REG_R9) +#define REG_MASK_R10 (1 << REG_R10) +#define REG_MASK_R11 (1 << REG_R11) +#define REG_MASK_R12 (1 << REG_R12) +#define REG_MASK_SP (1 << REG_SP) +#define REG_MASK_LR (1 << REG_LR) +#define REG_MASK_PC (1 << REG_PC) + +#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ + REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c new file mode 100644 index 0000000..5152fe4 --- /dev/null +++ b/src/codegen_backend_arm_uops.c @@ -0,0 +1,314 @@ +#ifdef __ARM_EABI__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_arm_defs.h" +#include "codegen_ir_defs.h" + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +#define Rm(x) (x) +#define Rd(x) ((x) << 12) +#define Rn(x) ((x) << 16) + +#define DATA_OFFSET_UP (1 << 23) +#define DATA_OFFSET_DOWN (0 << 23) + +#define COND_SHIFT 28 +#define COND_NE (0x1 << COND_SHIFT) +#define COND_AL (0xe << COND_SHIFT) + +#define OPCODE_SHIFT 20 +#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) +#define OPCODE_B (0xa0 << OPCODE_SHIFT) +#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) +#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) +#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) +#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) +#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) +#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) +#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) +#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) + +#define OPCODE_BLX 0xe12fff30 + +#define B_OFFSET(x) (((x) >> 2) & 0xffffff) + +static int literal_offset = 0; +void codegen_reset_literal_pool(codeblock_t *block) +{ + literal_offset = 0; +} + +int add_literal(codeblock_t *block, uint32_t data) +{ + if (literal_offset >= 4096) + fatal("add_literal - literal pool full\n"); + + *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; + + literal_offset += 4; + + return literal_offset - 4; +} + + +static inline uint32_t arm_data_offset(int offset) +{ + if (offset < -0xffc || offset > 0xffc) + fatal("arm_data_offset out of range - %i\n", offset); + + if (offset >= 0) + return offset | DATA_OFFSET_UP; + return (-offset) | DATA_OFFSET_DOWN; +} + +static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) +{ + int shift = 0; +//pclog("get_arm_imm - imm_data=%08x\n", imm_data); + if (!(imm_data & 0xffff)) + { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) + { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) + { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) + { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ + return 0; +//pclog(" imm_data=%02x shift=%i\n", imm_data, shift); + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; +} + +static inline int in_range(void *addr, void *base) +{ + int diff = (uintptr_t)addr - (uintptr_t)base; + + if (diff < -4095 || diff > 4095) + return 0; + return 1; +} + +void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (!get_arm_imm(imm, &arm_imm)) + fatal("host_arm_ADD_IMM !check_arm_imm %08x\n", imm); + + codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); +} + +void host_arm_BLX(codeblock_t *block, int addr_reg) +{ + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); +} + +void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) +{ + uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); + + codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); +} + +void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +{ + codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); +} + +void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +} + +void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (!get_arm_imm(imm, &arm_imm)) + fatal("host_arm_MOV_IMM !check_arm_imm %08x\n", imm); + + codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); +} + +void host_arm_MOV_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg)); +} + +void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +{ + codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); +} + +void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +} + +void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +} + +void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (!get_arm_imm(imm, &arm_imm)) + fatal("host_arm_SUB_IMM !check_arm_imm %08x\n", imm); + + codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); +} + +void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) +{ + codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); +} + + +void host_arm_call(codeblock_t *block, void *dst_addr) +{ + int offset = add_literal(block, (uintptr_t)dst_addr); + host_arm_LDR_IMM(block, REG_R3, REG_LITERAL, offset); + host_arm_BLX(block, REG_R3); +} + +void host_arm_nop(codeblock_t *block) +{ + host_arm_MOV_REG(block, REG_R0, REG_R0); +} + +static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, REG_ARG0, REG_LITERAL, offset); + } + return 0; +} +static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, REG_ARG1, REG_LITERAL, offset); + } + return 0; +} +static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, REG_ARG2, REG_LITERAL, offset); + } + return 0; +} +static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, REG_ARG3, REG_LITERAL, offset); + } + return 0; +} + +static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, REG_R0, REG_LITERAL, offset); + } + if (in_range(uop->p, &cpu_state)) + host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} +static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + if (in_range(uop->p, &cpu_state)) + host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = +{ + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 +}; + +#endif diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c new file mode 100644 index 0000000..e123823 --- /dev/null +++ b/src/codegen_backend_x86-64.c @@ -0,0 +1,156 @@ +#ifdef __amd64__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "x86.h" + +#if defined(__linux__) || defined(__APPLE__) +#include +#include +#endif +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#endif + +static void *mem_abrt_rout; + +void codegen_backend_init() +{ + int c; +#if defined(__linux__) || defined(__APPLE__) + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); +#endif + +#if defined WIN32 || defined _WIN32 || defined _WIN32 + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); +#endif + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + + memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; + +#if defined(__linux__) || defined(__APPLE__) + start = (void *)((long)codeblock & pagemask); + len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + { + perror("mprotect"); + exit(-1); + } +#endif +// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); +} + +static inline void call(codeblock_t *block, uintptr_t func) +{ + uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; + + if (diff >= -0x80000000 && diff < 0x7fffffff) + { + addbyte(0xE8); /*CALL*/ + addlong((uint32_t)diff); + } + else + { + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); + } +} + +void codegen_backend_prologue(codeblock_t *block) +{ + block_pos = 0; /*Entry code*/ + addbyte(0x53); /*PUSH RBX*/ + addbyte(0x55); /*PUSH RBP*/ + addbyte(0x56); /*PUSH RSI*/ + addbyte(0x57); /*PUSH RDI*/ + addbyte(0x41); /*PUSH R12*/ + addbyte(0x54); + addbyte(0x41); /*PUSH R13*/ + addbyte(0x55); + addbyte(0x41); /*PUSH R14*/ + addbyte(0x56); + addbyte(0x41); /*PUSH R15*/ + addbyte(0x57); + addbyte(0x48); /*SUBL $40,%rsp*/ + addbyte(0x83); + addbyte(0xEC); + addbyte(0x28); + addbyte(0x48); /*MOVL RBP, &cpu_state*/ + addbyte(0xBD); + addquad(((uintptr_t)&cpu_state) + 128); +} + +void codegen_backend_epilogue(codeblock_t *block) +{ + addbyte(0x48); /*ADDL $40,%rsp*/ + addbyte(0x83); + addbyte(0xC4); + addbyte(0x28); + addbyte(0x41); /*POP R15*/ + addbyte(0x5f); + addbyte(0x41); /*POP R14*/ + addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); + addbyte(0x5f); /*POP RDI*/ + addbyte(0x5e); /*POP RSI*/ + addbyte(0x5d); /*POP RBP*/ + addbyte(0x5b); /*POP RDX*/ + addbyte(0xC3); /*RET*/ + + if (block_pos > BLOCK_GPF_OFFSET) + fatal("Over limit!\n"); + + block_pos = BLOCK_GPF_OFFSET; +#if WIN64 + addbyte(0x48); /*XOR RCX, RCX*/ + addbyte(0x31); + addbyte(0xc9); + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); +#else + addbyte(0x48); /*XOR RDI, RDI*/ + addbyte(0x31); + addbyte(0xff); + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); +#endif + call(block, (uintptr_t)x86gpf); + while (block_pos < BLOCK_EXIT_OFFSET) + addbyte(0x90); /*NOP*/ + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x48); /*ADDL $40,%rsp*/ + addbyte(0x83); + addbyte(0xC4); + addbyte(0x28); + addbyte(0x41); /*POP R15*/ + addbyte(0x5f); + addbyte(0x41); /*POP R14*/ + addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); + addbyte(0x5f); /*POP RDI*/ + addbyte(0x5e); /*POP RSI*/ + addbyte(0x5d); /*POP RBP*/ + addbyte(0x5b); /*POP RDX*/ + addbyte(0xC3); /*RET*/ +} + +#endif diff --git a/src/codegen_backend_x86-64.h b/src/codegen_backend_x86-64.h new file mode 100644 index 0000000..6c0cfca --- /dev/null +++ b/src/codegen_backend_x86-64.h @@ -0,0 +1,16 @@ +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 + +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff + +#define HASH(l) ((l) & 0x1ffff) + +/*Hack until better memory management written*/ +#define BLOCK_EXIT_OFFSET 0xffe0 +/*#define BLOCK_EXIT_OFFSET 0x7f0*/ +#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) + +/*#define BLOCK_MAX 1720*/ +#define BLOCK_MAX 65208 diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h new file mode 100644 index 0000000..dcb9a58 --- /dev/null +++ b/src/codegen_backend_x86-64_defs.h @@ -0,0 +1,8 @@ +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c new file mode 100644 index 0000000..f64636f --- /dev/null +++ b/src/codegen_backend_x86-64_uops.c @@ -0,0 +1,232 @@ +#ifdef __amd64__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_x86-64_defs.h" +#include "codegen_ir_defs.h" + +#define STACK_ARG0 (0) +#define STACK_ARG1 (4) +#define STACK_ARG2 (8) +#define STACK_ARG3 (12) + +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +{ + block->data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte over! %i\n", block_pos); +// CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + block->data[block_pos++] = vald; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addword(codeblock_t *block, uint16_t val) +{ + *(uint16_t *)&block->data[block_pos] = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addquad(codeblock_t *block, uint64_t val) +{ + *(uint64_t *)&block->data[block_pos] = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void call(codeblock_t *block, uintptr_t func) +{ + uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; + + if (diff >= -0x80000000 && diff < 0x7fffffff) + { + codegen_addbyte(block, 0xE8); /*CALL*/ + codegen_addlong(block, (uint32_t)diff); + } + else + { + codegen_addbyte2(block, 0x48, 0xb8); /*MOV RAX, func*/ + codegen_addquad(block, func); + codegen_addbyte2(block, 0xff, 0xd0); /*CALL RAX*/ + } +} + +static void host_x86_CALL(codeblock_t *block, void *p) +{ + call(block, (uintptr_t)p); +} + +static void host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + +static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addlong(block, imm_data); +} +static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addbyte(block, imm_data); +} + +static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + codegen_addbyte(block, 0xb8 | reg); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); +} + +static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +{ + if (!offset) + { + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else if (offset >= -80 || offset < 0x80) + { + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } +} + +#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) + +static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} + +static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +{ + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ +#if WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); +#else + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); +#endif + return 0; +} +static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ +#if WIN64 + host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); +#else + host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); +#endif + return 0; +} +static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); + return 0; +} +static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); + return 0; +} + +static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ + if (((uintptr_t)uop->p) >> 32) + fatal("STORE_PTR_IMM 64-bit addr\n"); + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ + if (((uintptr_t)uop->p) >> 32) + fatal("STORE_PTR_IMM_8 64-bit addr\n"); + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = +{ + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 +}; + +#endif diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c new file mode 100644 index 0000000..01a27b2 --- /dev/null +++ b/src/codegen_backend_x86.c @@ -0,0 +1,121 @@ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "x86.h" + +#if defined(__linux__) || defined(__APPLE__) +#include +#include +#endif +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#endif + +static void *mem_abrt_rout; + +void codegen_backend_init() +{ + int c; +#if defined(__linux__) || defined(__APPLE__) + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); +#endif + +#if defined WIN32 || defined _WIN32 || defined _WIN32 + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); +#endif + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + + memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; + +#if defined(__linux__) || defined(__APPLE__) + start = (void *)((long)codeblock & pagemask); + len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + { + perror("mprotect"); + exit(-1); + } +#endif +// 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]; + addbyte(0x83); /*ADDL $16+4,%esp*/ + addbyte(0xC4); + addbyte(0x10+4); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + + asm( + "fstcw %0\n" + : "=m" (cpu_state.old_npxc) + ); +} + +void codegen_backend_prologue(codeblock_t *block) +{ + block_pos = 0; /*Entry code*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0x55); /*PUSH EBP*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0x57); /*PUSH EDI*/ + addbyte(0x83); /*SUBL $16,%esp*/ + addbyte(0xEC); + addbyte(0x10); + addbyte(0xBD); /*MOVL EBP, &cpu_state*/ + addlong(((uintptr_t)&cpu_state) + 128); +} + +void codegen_backend_epilogue(codeblock_t *block) +{ + addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0xC4); + addbyte(0x10); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + + if (block_pos > BLOCK_GPF_OFFSET) + fatal("Over limit!\n"); + + block_pos = BLOCK_GPF_OFFSET; + addbyte(0xc7); /*MOV [ESP],0*/ + addbyte(0x04); + addbyte(0x24); + addlong(0); + addbyte(0xc7); /*MOV [ESP+4],0*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x04); + addlong(0); + addbyte(0xe8); /*CALL x86gpf*/ + addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0xC4); + addbyte(0x10); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ +} + +#endif diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h new file mode 100644 index 0000000..36361ec --- /dev/null +++ b/src/codegen_backend_x86.h @@ -0,0 +1,16 @@ +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 + +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff + +#define HASH(l) ((l) & 0x1ffff) + +/*Hack until better memory management written*/ +#define BLOCK_EXIT_OFFSET 0xfff0 +/*#define BLOCK_EXIT_OFFSET 0x7f0*/ +#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) + +/*#define BLOCK_MAX 1720*/ +#define BLOCK_MAX 65208 diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h new file mode 100644 index 0000000..dcb9a58 --- /dev/null +++ b/src/codegen_backend_x86_defs.h @@ -0,0 +1,8 @@ +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c new file mode 100644 index 0000000..365382b --- /dev/null +++ b/src/codegen_backend_x86_uops.c @@ -0,0 +1,195 @@ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_x86_defs.h" +#include "codegen_ir_defs.h" + +#define STACK_ARG0 (0) +#define STACK_ARG1 (4) +#define STACK_ARG2 (8) +#define STACK_ARG3 (12) + +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +{ + block->data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte over! %i\n", block_pos); +// CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + block->data[block_pos++] = vald; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addword(codeblock_t *block, uint16_t val) +{ + *(uint16_t *)&block->data[block_pos] = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addquad(codeblock_t *block, uint64_t val) +{ + *(uint64_t *)&block->data[block_pos] = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static void host_x86_CALL(codeblock_t *block, void *p) +{ + codegen_addbyte(block, 0xe8); /*CALL*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + +static void host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + +static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addlong(block, imm_data); +} +static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addbyte(block, imm_data); +} + +static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +{ + if (!offset) + { + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else if (offset >= -80 || offset < 0x80) + { + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } +} + +#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) + +static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} + +static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +{ + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); + return 0; +} +static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); + return 0; +} +static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); + return 0; +} +static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); + return 0; +} + +static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = +{ + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 +}; + +#endif diff --git a/src/codegen_ir.c b/src/codegen_ir.c new file mode 100644 index 0000000..4f8e1b4 --- /dev/null +++ b/src/codegen_ir.c @@ -0,0 +1,34 @@ +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_ir.h" + +static ir_data_t ir_block; + +ir_data_t *codegen_ir_init() +{ + ir_block.wr_pos = 0; + //pclog("codegen_ir_init\n"); + + return &ir_block; +} + +void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) +{ + int c; + + codegen_backend_prologue(block); + + for (c = 0; c < ir->wr_pos; c++) + { + uop_t *uop = &ir->uops[c]; + + //pclog("uOP %i : %08x\n", c, uop->type); + + uop_handlers[uop->type & UOP_MASK](block, uop); + } + + codegen_backend_epilogue(block); + +// fatal("IR compilation complete\n"); +} diff --git a/src/codegen_ir.h b/src/codegen_ir.h new file mode 100644 index 0000000..aafeca6 --- /dev/null +++ b/src/codegen_ir.h @@ -0,0 +1,5 @@ +#include "codegen_ir_defs.h" + +ir_data_t *codegen_ir_init(); + +void codegen_ir_compile(ir_data_t *ir, codeblock_t *block); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h new file mode 100644 index 0000000..9293447 --- /dev/null +++ b/src/codegen_ir_defs.h @@ -0,0 +1,152 @@ +#ifndef _CODEGEN_IR_DEFS_ +#define _CODEGEN_IR_DEFS_ + +#define IREG_L (0 << 6) +#define IREG_W (1 << 6) +#define IREG_B (2 << 6) +#define IREG_BH (3 << 6) + +enum +{ + ireg_EAX = 0, + ireg_ECX = 1, + ireg_EDX = 2, + ireg_EBX = 3, + ireg_ESP = 4, + ireg_EBP = 5, + ireg_ESI = 6, + ireg_EDI = 7, + + ireg_flags_op = 8, + ireg_flags_reg = 9, + ireg_flags_op1 = 10, + ireg_flags_op2 = 11, + + ireg_flags_pc = 12, + ireg_flags_oldpc = 13, + + ireg_eaaddr = 14, + + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + ireg_temp0 = 16, + ireg_temp1 = 17, + ireg_temp2 = 18, + ireg_temp3 = 19 +}; + +#define UOP_REG(reg, size, version) ((reg) | (size) | (version << 8)) + +#define UOP_REG_UNUSED 0xffff + +/*uOP is a barrier. All previous uOPs must have completed before this one executes. + All registers must have been written back or discarded*/ +#define UOP_TYPE_BARRIER (1 << 31) + +/*uOP uses source and dest registers*/ +#define UOP_TYPE_PARAMS_REGS (1 << 28) +/*uOP uses pointer*/ +#define UOP_TYPE_PARAMS_POINTER (1 << 29) +/*uOP uses immediate data*/ +#define UOP_TYPE_PARAMS_IMM (1 << 30) + + + +#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) +#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) +#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) +#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) +#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08) +#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09) +#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a) +#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b) +#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) +#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) +#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) +#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) + +#define UOP_MAX 0x14 + +#define UOP_MASK 0xffff + +typedef struct uop_t +{ + uint32_t type; + uint16_t dest_reg_a; + uint16_t src_reg_a; + uint16_t src_reg_b; + uint16_t src_reg_c; + uint32_t imm_data; + void *p; +} uop_t; + +#define UOP_NR_MAX 4096 + +typedef struct ir_data_t +{ + uop_t uops[UOP_NR_MAX]; + int wr_pos; +} ir_data_t; + +static inline uop_t *uop_alloc(ir_data_t *ir) +{ + uop_t *uop; + + if (ir->wr_pos >= UOP_NR_MAX) + fatal("Exceeded uOP max\n"); + + uop = &ir->uops[ir->wr_pos++]; + + uop->dest_reg_a = UOP_REG_UNUSED; + uop->src_reg_a = UOP_REG_UNUSED; + uop->src_reg_b = UOP_REG_UNUSED; + uop->src_reg_c = UOP_REG_UNUSED; + + return uop; +} + +static inline void uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int arg, uint16_t src_reg_a) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = src_reg_a; +} + +static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->imm_data = imm; +} + +static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->p = p; +} + +static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->p = p; + uop->imm_data = imm; +} + +#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) + +#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) + +#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) +#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) + +#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) +#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) + +#endif diff --git a/src/codegen_ops.c b/src/codegen_ops.c deleted file mode 100644 index 68da1ed..0000000 --- a/src/codegen_ops.c +++ /dev/null @@ -1,591 +0,0 @@ -#include "ibm.h" -#include "x86.h" -#include "x86_ops.h" -#include "x86_flags.h" -#include "x87.h" -#include "386_common.h" -#include "cpu.h" -#include "codegen.h" -#include "codegen_ops.h" - -#ifdef __amd64__ -#include "codegen_ops_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 -#include "codegen_ops_x86.h" -#endif - -#include "codegen_ops_arith.h" -#include "codegen_ops_fpu.h" -#include "codegen_ops_jump.h" -#include "codegen_ops_logic.h" -#include "codegen_ops_misc.h" -#include "codegen_ops_mmx.h" -#include "codegen_ops_mov.h" -#include "codegen_ops_shift.h" -#include "codegen_ops_stack.h" -#include "codegen_ops_xchg.h" - -RecompOpFn recomp_opcodes[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16, -/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, -/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, - -/*40*/ ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, -/*50*/ ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_b16,NULL, NULL, NULL, NULL, NULL, -/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE, - -/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_w, ropMOV_seg_w, NULL, -/*90*/ ropNOP, ropXCHG_AX_CX, ropXCHG_AX_DX, ropXCHG_AX_BX, ropXCHG_AX_SP, ropXCHG_AX_BP, ropXCHG_AX_SI, ropXCHG_AX_DI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_a, ropMOV_AX_a, ropMOV_a_AL, ropMOV_a_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, - -/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES, ropLDS, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_w, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_16, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32, -/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, -/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, - -/*40*/ ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, -/*50*/ ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_b32,NULL, NULL, NULL, NULL, NULL, -/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE, - -/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_w_seg, ropLEA_l, ropMOV_seg_w, NULL, -/*90*/ ropNOP, ropXCHG_EAX_ECX,ropXCHG_EAX_EDX,ropXCHG_EAX_EBX,ropXCHG_EAX_ESP,ropXCHG_EAX_EBP,ropXCHG_EAX_ESI,ropXCHG_EAX_EDI,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_a, ropMOV_EAX_a, ropMOV_a_AL, ropMOV_a_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, - -/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES, ropLDS, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32 -}; - -RecompOpFn recomp_opcodes_0f[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_mm_l, ropMOVQ_mm_q, -/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_l_mm, ropMOVQ_q_mm, - -/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, -/*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -/*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -}; - - -RecompOpFn recomp_opcodes_d8[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, -/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, -/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, -/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, - -/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, -/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, -}; - -RecompOpFn recomp_opcodes_d9[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, - -/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_da[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, -/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, -/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, -/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_db[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_dc[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, -/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, -/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, -/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, - -/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, -/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, -/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, -/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, -}; - -RecompOpFn recomp_opcodes_dd[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_de[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, -/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, -/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, -/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, -/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, - -/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, -/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, -}; - -RecompOpFn recomp_opcodes_df[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_REPE[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; - -RecompOpFn recomp_opcodes_REPNE[512] = -{ - /*16-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - /*32-bit data*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -}; diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h deleted file mode 100644 index 57c5e8e..0000000 --- a/src/codegen_ops_arith.h +++ /dev/null @@ -1,1028 +0,0 @@ -static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_W(opcode & 7); - - 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((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; - - return op_pc; -} -static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_L(opcode & 7); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); - 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; - - return op_pc; -} -static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_W(opcode & 7); - - 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((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; - - return op_pc; -} -static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - host_reg = LOAD_REG_L(opcode & 7); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); - 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; - - return op_pc; -} - -#define ROP_ARITH_RMW(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - 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((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((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - 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((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((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - 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((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((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } - -#define ROP_ARITH_RM(name, op, writeback) \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - 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((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); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - 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((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); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - 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((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); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } - -ROP_ARITH_RMW(ADD, ADD, 1) -ROP_ARITH_RMW(SUB, SUB, 1) -ROP_ARITH_RM(ADD, ADD, 1) -ROP_ARITH_RM(SUB, SUB, 1) - -static uint32_t ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - 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((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); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - 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((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); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - 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((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); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - dst_reg = 0; - } - - 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((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_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); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - dst_reg = 0; - } \ - - 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((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_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); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - dst_reg = 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - 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((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); - - codegen_flags_changed = 1; - return op_pc + 1; -} - - -static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - 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((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; - return op_pc + 1; -} -static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - 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((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; - return op_pc + 2; -} -static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - 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((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; - return op_pc + 4; -} - -static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - 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((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; - return op_pc + 1; -} -static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - 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((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; - return op_pc + 2; -} -static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - 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((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; - return op_pc + 4; -} - -static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - 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((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; - return op_pc + 1; -} -static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - 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((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; - return op_pc + 2; -} -static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - 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((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; - return op_pc + 4; -} - -static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - 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((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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x28: /*SUB*/ - 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((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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x38: /*CMP*/ - 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((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((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_B_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} - -static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadw(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - 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((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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - 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((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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - 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((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((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 3; -} -static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - } - imm = fastreadl(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - 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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - 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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - 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((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 5; -} - -static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - 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((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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - 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((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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - 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((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((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xffffff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - 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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - 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((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - 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((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} diff --git a/src/codegen_ops_fpu.h b/src/codegen_ops_fpu.h deleted file mode 100644 index 5065094..0000000 --- a/src/codegen_ops_fpu.h +++ /dev/null @@ -1,645 +0,0 @@ -static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FXCH(opcode & 7); - - return op_pc; -} - -static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FLD(opcode & 7); - - return op_pc; -} - -static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FST(opcode & 7); - - return op_pc; -} -static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - - FP_FST(opcode & 7); - FP_POP(); - - return op_pc; -} - - -static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_LOAD_S(); - - return op_pc + 1; -} -static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); - - FP_LOAD_D(); - - return op_pc + 1; -} - -static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - - FP_LOAD_IW(); - - return op_pc + 1; -} -static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_LOAD_IL(); - - return op_pc + 1; -} -static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); - - FP_LOAD_IQ(); - - codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1; - - return op_pc + 1; -} - -static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - host_reg = FP_LOAD_REG(0); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - - return op_pc + 1; -} -static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg1, host_reg2; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - FP_LOAD_REG_D(0, &host_reg1, &host_reg2); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); - - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - - return op_pc + 1; -} - -static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} -static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} - -#define ropFarith(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) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(FPU_ ## name); \ - \ - 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); - -#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) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(); \ - \ - return op_pc + 1; \ -} \ -static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \ - \ - FP_POP(); \ - \ - 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); - -/*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_ADD); - - return op_pc + 1; -} -static uint32_t ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_DIV); - - return op_pc + 1; -} -static uint32_t ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_MUL); - - return op_pc + 1; -} -static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - - FP_OP_S(FPU_SUB); - - return op_pc + 1; -}*/ - - -static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_ADD, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); - - return op_pc; -} -static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIV, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIVR, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_MUL, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUB, 0, opcode & 7); - - return op_pc; -} -static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUBR, 0, opcode & 7); - - return op_pc; -} - -static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); - - return op_pc; -} -static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); - - return op_pc; -} - -static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); - FP_POP(); - - return op_pc; -} -static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); - FP_POP(); - - return op_pc; -} -static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); - FP_POP(); - - return op_pc; -} - -static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_COMPARE_REG(0, 1); - FP_POP2(); - - return op_pc; -} - -static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - FP_ENTER(); - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); - - return op_pc; -} - - -static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - host_reg = FP_LOAD_REG_INT_W(0); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - - return op_pc + 1; -} -static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - host_reg = FP_LOAD_REG_INT(0); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - - return op_pc + 1; -} - -static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} -static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); - - FP_POP(); - - return new_pc; -} -static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg1, host_reg2; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - - FP_POP(); - - return op_pc + 1; -} - - -static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0); - UPDATE_NPXC(0); - - return op_pc + 1; -} -static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - x86seg *target_seg; - - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_WRITE(target_seg); - - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc); - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - - return op_pc + 1; -} - - -static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_FCHS(); - - return op_pc; -} - -#define opFLDimm(name, v) \ - 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; \ - \ - FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \ - \ - return op_pc; \ - } - -opFLDimm(1, 1.0) -opFLDimm(L2T, 3.3219280948873623) -opFLDimm(L2E, 1.4426950408889634); -opFLDimm(PI, 3.141592653589793); -opFLDimm(EG2, 0.3010299956639812); -opFLDimm(Z, 0.0) - -static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - FP_ENTER(); - FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); - - return op_pc; -} diff --git a/src/codegen_ops_jump.h b/src/codegen_ops_jump.h deleted file mode 100644 index d2271cf..0000000 --- a/src/codegen_ops_jump.h +++ /dev/null @@ -1,270 +0,0 @@ -static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fetchdat & 0xff; - - if (offset & 0x80) - offset |= 0xffffff00; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+1+offset); - - return -1; -} - -static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t offset = fetchdat & 0xffff; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); - - return -1; -} - -static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fastreadl(cs + op_pc); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); - - return -1; -} - - -static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fetchdat & 0xff; - - if (offset & 0x80) - offset |= 0xffffff00; - - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } - - return op_pc+1; -} - -static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fetchdat & 0xff; - - if (offset & 0x80) - offset |= 0xffffff00; - - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_L_RELEASE(host_reg); - TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_W_RELEASE(host_reg); - TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } - - return op_pc+1; -} - -static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)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 void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - int host_reg; - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - if (not) - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)ZF_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); - break; - } -} - -static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)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 void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)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 void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - int host_reg; - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x8000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80000000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; - - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)NF_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); - break; - } -} - - -#define ropBRANCH(name, func, not) \ -static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \ - uint32_t op_32, uint32_t op_pc, \ - codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xff; \ - \ - if (offset & 0x80) \ - offset |= 0xffffff00; \ - \ - func(1, op_pc, offset, not); \ - \ - return op_pc+1; \ -} \ -static uint32_t rop ## name ## _w(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xffff; \ - \ - if (offset & 0x8000) \ - offset |= 0xffff0000; \ - \ - func(2, op_pc, offset, not); \ - \ - return op_pc+2; \ -} \ -static uint32_t rop ## name ## _l(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - \ - func(4, op_pc, offset, not); \ - \ - return op_pc+4; \ -} - -ropBRANCH(JB, BRANCH_COND_B, 0) -ropBRANCH(JNB, BRANCH_COND_B, 1) -ropBRANCH(JE, BRANCH_COND_E, 0) -ropBRANCH(JNE, BRANCH_COND_E, 1) -ropBRANCH(JO, BRANCH_COND_O, 0) -ropBRANCH(JNO, BRANCH_COND_O, 1) -ropBRANCH(JP, BRANCH_COND_P, 0) -ropBRANCH(JNP, BRANCH_COND_P, 1) -ropBRANCH(JS, BRANCH_COND_S, 0) -ropBRANCH(JNS, BRANCH_COND_S, 1) -ropBRANCH(JL, BRANCH_COND_L, 0) -ropBRANCH(JNL, BRANCH_COND_L, 1) -ropBRANCH(JLE, BRANCH_COND_LE, 0) -ropBRANCH(JNLE, BRANCH_COND_LE, 1) -ropBRANCH(JBE, BRANCH_COND_BE, 0) -ropBRANCH(JNBE, BRANCH_COND_BE, 1) diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h deleted file mode 100644 index ca57fca..0000000 --- a/src/codegen_ops_logic.h +++ /dev/null @@ -1,564 +0,0 @@ -#define ROP_LOGIC(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - op ## _HOST_REG_B(dst_reg, src_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); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - op ## _HOST_REG_W(dst_reg, src_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); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - op ## _HOST_REG_L(dst_reg, src_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); \ - \ - return op_pc + 1; \ - } - -ROP_LOGIC(AND, AND, 1) -ROP_LOGIC(OR, OR, 1) -ROP_LOGIC(XOR, XOR, 1) - -static uint32_t ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - dst_reg = TEST_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - dst_reg = TEST_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } - - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - dst_reg = TEST_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - return op_pc + 1; -} - -static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - AND_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - OR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 2; -} -static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 4; -} - -static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - XOR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint8_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadb(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 2; - - case 0x10: /*NOT b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_B(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xff); - STORE_REG_B_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - host_reg = LOAD_REG_B(fetchdat & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_B(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_B_RELEASE(host_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint16_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST w,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadw(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 3; - - case 0x10: /*NOT w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_W(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffff); - STORE_REG_W_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - host_reg = LOAD_REG_W(fetchdat & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_W_RELEASE(host_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint32_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST l,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = fastreadl(cs + op_pc + 1); - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadl(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 5; - - case 0x10: /*NOT l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_L(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffffffff); - STORE_REG_L_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - host_reg = LOAD_REG_L(fetchdat & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_L(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_L_RELEASE(host_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h deleted file mode 100644 index 9eb9567..0000000 --- a/src/codegen_ops_misc.h +++ /dev/null @@ -1,269 +0,0 @@ -static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - return op_pc; -} - -static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - CLEAR_BITS((uintptr_t)&flags, D_FLAG); - return op_pc; -} -static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - SET_BITS((uintptr_t)&flags, D_FLAG); - return op_pc; -} - -static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - CLEAR_BITS((uintptr_t)&flags, I_FLAG); - return op_pc; -} -static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - SET_BITS((uintptr_t)&flags, I_FLAG); - return op_pc; -} - -static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int host_reg; - - if ((fetchdat & 0x30) != 0x00) - return 0; - - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_B(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - 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((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((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, 1); - 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; - } - - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_B_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - - return op_pc + 1; -} -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 = NULL; - int host_reg; - - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - 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((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 - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - 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((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 - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - return op_pc + 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 = NULL; - int host_reg; - - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_L(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); - 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 - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); - 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 - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - return op_pc + 1; - } - return 0; -} diff --git a/src/codegen_ops_mmx.h b/src/codegen_ops_mmx.h deleted file mode 100644 index 78239cb..0000000 --- a/src/codegen_ops_mmx.h +++ /dev/null @@ -1,277 +0,0 @@ -static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg1, host_reg2; - - MMX_ENTER(); - - LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); - - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - } - - return op_pc + 1; -} - -static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - MMX_ENTER(); - - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg1, host_reg2; - - LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2); - STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_Q(target_seg); - STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2); - } - - return op_pc + 1; -} - -static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - MMX_ENTER(); - - host_reg = LOAD_MMX_D((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - MMX_ENTER(); - - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_MMX_LQ((fetchdat >> 3) & 7, 0); - } - - return op_pc + 1; -} - -#define MMX_OP(name, func) \ -static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int src_reg1, src_reg2; \ - int xmm_src, xmm_dst; \ - \ - MMX_ENTER(); \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - \ - MEM_LOAD_ADDR_EA_Q(target_seg); \ - src_reg1 = LOAD_Q_REG_1; \ - src_reg2 = LOAD_Q_REG_2; \ - xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ - } \ - xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ - func(xmm_dst, xmm_src); \ - STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ - \ - return op_pc + 1; \ -} - -MMX_OP(ropPAND, MMX_AND) -MMX_OP(ropPANDN, MMX_ANDN) -MMX_OP(ropPOR, MMX_OR) -MMX_OP(ropPXOR, MMX_XOR) - -MMX_OP(ropPADDB, MMX_ADDB) -MMX_OP(ropPADDW, MMX_ADDW) -MMX_OP(ropPADDD, MMX_ADDD) -MMX_OP(ropPADDSB, MMX_ADDSB) -MMX_OP(ropPADDSW, MMX_ADDSW) -MMX_OP(ropPADDUSB, MMX_ADDUSB) -MMX_OP(ropPADDUSW, MMX_ADDUSW) - -MMX_OP(ropPSUBB, MMX_SUBB) -MMX_OP(ropPSUBW, MMX_SUBW) -MMX_OP(ropPSUBD, MMX_SUBD) -MMX_OP(ropPSUBSB, MMX_SUBSB) -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(ropPCMPEQB, MMX_PCMPEQB); -MMX_OP(ropPCMPEQW, MMX_PCMPEQW); -MMX_OP(ropPCMPEQD, MMX_PCMPEQD); - -MMX_OP(ropPSRLW, MMX_PSRLW) -MMX_OP(ropPSRLD, MMX_PSRLD) -MMX_OP(ropPSRLQ, MMX_PSRLQ) -MMX_OP(ropPSRAW, MMX_PSRAW) -MMX_OP(ropPSRAD, MMX_PSRAD) -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); - -static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLW*/ - MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAW*/ - MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLW*/ - MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLD*/ - MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAD*/ - MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLD*/ - MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLQ*/ - MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAQ*/ - MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLQ*/ - MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} - -static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - codegen_mmx_entered = 0; - - return 0; -} diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h deleted file mode 100644 index 61fcd0f..0000000 --- a/src/codegen_ops_mov.h +++ /dev/null @@ -1,656 +0,0 @@ -static uint32_t ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); - - return op_pc + 1; -} -static uint32_t ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); - - return op_pc + 2; -} -static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - fetchdat = fastreadl(cs + op_pc); - - STORE_IMM_REG_L(opcode & 7, fetchdat); - - return op_pc + 4; -} - - -static uint32_t ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 0); - - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - host_reg = LOAD_REG_L((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - - } - - return op_pc + 1; -} - -static uint32_t ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadb(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 2; -} -static uint32_t ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadw(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 3; -} -static uint32_t ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - uint32_t imm = fastreadl(cs + op_pc + 1); - - STORE_IMM_REG_L(fetchdat & 7, imm); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadl(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 5; -} - - -static uint32_t ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr); - STORE_REG_TARGET_B_RELEASE(0, REG_AL); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr); - STORE_REG_TARGET_W_RELEASE(0, REG_AX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr); - STORE_REG_TARGET_L_RELEASE(0, REG_EAX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -static uint32_t ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_B(REG_AL); - - MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg); - RELEASE_REG(host_reg); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_W(REG_AX); - - MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg); - RELEASE_REG(host_reg); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_L(REG_EAX); - - MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg); - RELEASE_REG(host_reg); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -static uint32_t ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int dest_reg = (fetchdat >> 3) & 7; - - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_REG_TARGET_W_RELEASE(0, dest_reg); - - return op_pc + 1; -} -static uint32_t ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int dest_reg = (fetchdat >> 3) & 7; - - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_REG_TARGET_L_RELEASE(0, dest_reg); - - return op_pc + 1; -} - -static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = ZERO_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - ZERO_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = SIGN_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - SIGN_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - host_reg = LOAD_VAR_WL((uintptr_t)&ES); - break; - case 0x08: /*CS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&CS); - break; - case 0x18: /*DS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&DS); - break; - case 0x10: /*SS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&SS); - break; - case 0x20: /*FS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&FS); - break; - case 0x28: /*GS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&GS); - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - if (op_32 & 0x100) - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - else - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - case 0x18: /*DS*/ - case 0x20: /*FS*/ - case 0x28: /*GS*/ - break; - case 0x10: /*SS*/ - default: - return 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - - host_reg = 0; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - LOAD_SEG(host_reg, &_es); - break; - case 0x18: /*DS*/ - LOAD_SEG(host_reg, &_ds); - break; - case 0x20: /*FS*/ - LOAD_SEG(host_reg, &_fs); - break; - case 0x28: /*GS*/ - LOAD_SEG(host_reg, &_gs); - break; - } - - return op_pc + 1; -} - -#define ropLseg(seg, rseg) \ -static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - SAVE_EA(); \ - \ - if (op_32 & 0x100) \ - { \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ - } \ - else \ - { \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ - } \ - LOAD_SEG(0, &rseg); \ - if (op_32 & 0x100) \ - { \ - \ - int host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \ - } \ - else \ - { \ - int host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \ - } \ - \ - if (&rseg == &_ss) \ - CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \ - return op_pc + 1; \ -} - -ropLseg(DS, _ds) -ropLseg(ES, _es) -ropLseg(FS, _fs) -ropLseg(GS, _gs) -ropLseg(SS, _ss) diff --git a/src/codegen_ops_shift.h b/src/codegen_ops_shift.h deleted file mode 100644 index 75d024f..0000000 --- a/src/codegen_ops_shift.h +++ /dev/null @@ -1,125 +0,0 @@ -#define SHIFT(size, size2, res_store, immediate) \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - reg = LOAD_REG_ ## size(fetchdat & 7); \ - if (immediate) count = (fetchdat >> 8) & 0x1f; \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_ ## size(target_seg); \ - reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \ - if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \ - \ - 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((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \ - break; \ - \ - case 0x28: /*SHR*/ \ - SHR_ ## size ## _IMM(reg, count); \ - 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((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \ - break; \ - } \ - \ - res_store((uintptr_t)&cpu_state.flags_res, reg); \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_ ## size ## _RELEASE(reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \ - } - -static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); - - return op_pc + 2; -} -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 = NULL; - int count; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); - - return op_pc + 2; -} -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 = NULL; - int count; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); - - return op_pc + 2; -} - -static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg = NULL; - int count = 1; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); - - return op_pc + 1; -} -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 = NULL; - int count = 1; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); - - return op_pc + 1; -} -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 = NULL; - int count = 1; - int reg; - - if ((fetchdat & 0x38) < 0x20) - return 0; - - SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); - - return op_pc + 1; -} diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h deleted file mode 100644 index 3ea27d3..0000000 --- a/src/codegen_ops_stack.h +++ /dev/null @@ -1,269 +0,0 @@ -static uint32_t ropPUSH_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(-2); - host_reg = LOAD_REG_W(opcode & 7); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - return op_pc; -} -static uint32_t ropPUSH_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(-4); - host_reg = LOAD_REG_L(opcode & 7); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - return op_pc; -} - -static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t imm = fetchdat & 0xffff; - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - return op_pc+2; -} -static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t imm = fastreadl(cs + op_pc); - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - return op_pc+4; -} - -static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint16_t imm = fetchdat & 0xff; - int host_reg; - - if (imm & 0x80) - imm |= 0xff00; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - - return op_pc+1; -} -static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t imm = fetchdat & 0xff; - int host_reg; - - if (imm & 0x80) - imm |= 0xffffff00; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - - return op_pc+1; -} - -static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - SP_MODIFY(2); - STORE_REG_TARGET_W_RELEASE(0, opcode & 7); - - return op_pc; -} -static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - SP_MODIFY(4); - STORE_REG_TARGET_L_RELEASE(0, opcode & 7); - - return op_pc; -} - -static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2); - - return -1; -} -static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4); - - return -1; -} - -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; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2+offset); - - return -1; -} -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; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4+offset); - - return -1; -} - -static uint32_t ropCALL_r16(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(-2); - host_reg = LOAD_REG_IMM(op_pc+2); - MEM_STORE_ADDR_EA_W(&_ss, host_reg); - SP_MODIFY(-2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); - - return -1; -} -static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t offset = fastreadl(cs + op_pc); - int host_reg; - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc+4); - MEM_STORE_ADDR_EA_L(&_ss, host_reg); - SP_MODIFY(-4); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); - - return -1; -} - -static uint32_t ropLEAVE_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_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&_ss); - host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ - ADD_HOST_REG_IMM_W(host_reg, 2); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); - STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/ - - return op_pc; -} -static uint32_t ropLEAVE_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_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&_ss); - host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ - ADD_HOST_REG_IMM(host_reg, 4); - STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); - STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/ - - return op_pc; -} - -#define ROP_PUSH_SEG(seg) \ -static uint32_t ropPUSH_ ## 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(-2); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_W(&_ss, host_reg); \ - SP_MODIFY(-2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPUSH_ ## 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(-4); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_L(&_ss, host_reg); \ - SP_MODIFY(-4); \ - \ - return op_pc; \ -} - -ROP_PUSH_SEG(CS) -ROP_PUSH_SEG(DS) -ROP_PUSH_SEG(ES) -ROP_PUSH_SEG(FS) -ROP_PUSH_SEG(GS) -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) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(4); \ - \ - return op_pc; \ -} - -ROP_POP_SEG(DS, _ds) -ROP_POP_SEG(ES, _es) -ROP_POP_SEG(FS, _fs) -ROP_POP_SEG(GS, _gs) diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h deleted file mode 100644 index f50eba2..0000000 --- a/src/codegen_ops_x86-64.h +++ /dev/null @@ -1,6213 +0,0 @@ -/*Register allocation : - R8-R15 - emulated registers -*/ -#include - -#define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 - -#define IS_32_ADDR(x) !(((uintptr_t)x) & 0xffffffff00000000) - -static inline int find_host_xmm_reg() -{ - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } - - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; -} -static inline void call(codeblock_t *block, uintptr_t func) -{ - uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; - - 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; - - if (diff >= -0x80000000 && diff < 0x7fffffff) - { - addbyte(0xE8); /*CALL*/ - addlong((uint32_t)diff); - } - else - { - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); - } -} - -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; - - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); -} - -static inline void load_param_1_32(codeblock_t *block, uint32_t param) -{ -#if WIN64 - addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ -#else - addbyte(0xbf); /*MOVL $fetchdat,%edi*/ -#endif - addlong(param); -} -static inline void load_param_1_reg_32(int reg) -{ -#if WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc0 | REG_ECX | (reg << 3)); -#else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc0 | REG_EDI | (reg << 3)); -#endif -} -#if 0 -static inline void load_param_1_64(codeblock_t *block, uint64_t param) -{ - addbyte(0x48); -#if WIN64 - addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ -#else - addbyte(0xbf); /*MOVL $fetchdat,%edi*/ -#endif - addquad(param); -} -#endif - -static inline void load_param_2_32(codeblock_t *block, uint32_t param) -{ -#if WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ -#else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ -#endif - addlong(param); -} -static inline void load_param_2_reg_32(int reg) -{ -#if WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDX, EAX*/ - addbyte(0xc0 | REG_EDX | (reg << 3)); -#else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ESI, EAX*/ - addbyte(0xc0 | REG_ESI | (reg << 3)); -#endif -} -static inline void load_param_2_64(codeblock_t *block, uint64_t param) -{ - addbyte(0x48); -#if WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ -#else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ -#endif - addquad(param); -} - -static inline void load_param_3_reg_32(int reg) -{ - if (reg & 8) - { -#if WIN64 - addbyte(0x45); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x44); /*MOV EDX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif - } - else - { -#if WIN64 - addbyte(0x41); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x90); - addbyte(0x89); /*MOV EDX, reg*/ - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif - } -} -static inline void load_param_3_reg_64(int reg) -{ - if (reg & 8) - { -#if WIN64 - addbyte(0x4d); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x4c); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } - else - { -#if WIN64 - addbyte(0x49); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x48); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } -} - -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; - - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); -} - -static inline void RELEASE_REG(int host_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]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[host_reg & 3].b)); - } - - codegen_reg_loaded[reg & 3] = 1; - - if (reg & 4) - return host_reg | 0x18; - - return host_reg | 8; -} -static inline int LOAD_REG_W(int reg) -{ - int host_reg = reg; -// host_reg_mapping[host_reg] = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} -static inline int LOAD_REG_L(int reg) -{ - int host_reg = reg; -// host_reg_mapping[host_reg] = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} - -static inline int LOAD_REG_IMM(uint32_t imm) -{ - int host_reg = REG_EBX; - - addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ - addlong(imm); - - return host_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; - - if (guest_reg & 4) - { - if (host_reg & 8) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - if (host_reg & 0x10) - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - else - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(0x08); - } - } - else - { - if (host_reg) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - } - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(0x08); - } - addbyte(0x66); /*AND dest_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | dest_reg); - addword(0x00ff); - addbyte(0x66); /*OR dest_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | dest_reg); - addbyte(0x66); /*MOVW regs[guest_reg].w, dest_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (dest_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].w)); - } - else - { - if (host_reg & 8) - { - if (host_reg & 0x10) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - addbyte(0x88); /*MOV AL, AH*/ - addbyte(0xe0); - addbyte(0x41); /*MOV dest_reg, AL*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7)); - addbyte(0x88); /*MOVB regs[reg].b, AH*/ - addbyte(0x65); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - else - { - addbyte(0x45); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x44); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x88); - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } - else - { - if (host_reg & 0x10) - { - addbyte(0xc1); /*SHR host_reg, 8*/ - addbyte(0xe8 | (host_reg & 7)); - addbyte(8); - } - addbyte(0x41); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x88); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } -} -static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; - - if (host_reg & 8) - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x45); - addbyte(0x89); - addbyte(0xc0 | dest_reg | ((host_reg & 7) << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } - else - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x41); - addbyte(0x89); - addbyte(0xc0 | dest_reg | (host_reg << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } -} -static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x44); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } - else - { - addbyte(0x41); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x89); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } -} - -static inline void STORE_REG_B_RELEASE(int host_reg) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].w)); - } - else - { - addbyte(0x44); /*MOVB [reg],host_reg*/ - addbyte(0x88); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].b)); - } -} -static inline void STORE_REG_W_RELEASE(int host_reg) -{ - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].w)); -} -static inline void STORE_REG_L_RELEASE(int host_reg) -{ - addbyte(0x44); /*MOVL [reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].l)); -} - -static inline void STORE_IMM_REG_B(int reg, uint8_t val) -{ - if (reg & 4) - { - int host_reg = LOAD_REG_W(reg & 3) & 7; - addbyte(0x66); /*AND host_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | host_reg); - addword(0x00ff); - addbyte(0x66); /*OR host_reg, val << 8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | host_reg); - addword(val << 8); - addbyte(0x66); /*MOVW host_reg, regs[host_reg].w*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 3].w)); - } - else - { - addbyte(0x41); /*MOVB reg, imm*/ - addbyte(0xb0 | reg); - addbyte(val); - addbyte(0x44); /*MOVB reg, regs[reg].b*/ - addbyte(0x88); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].b)); - } -} -static inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW reg, imm*/ - addbyte(0x41); - addbyte(0xb8 | reg); - addword(val); - addbyte(0x66); /*MOVW reg, regs[reg].w*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); -} -static inline void STORE_IMM_REG_L(int reg, uint32_t val) -{ - addbyte(0x41); /*MOVL reg, imm*/ - addbyte(0xb8 | reg); - addlong(val); - addbyte(0x44); /*MOVL reg, regs[reg].l*/ - addbyte(0x89); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); -} - -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) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uintptr_t)&cpu_state - 128); - addlong(val); - } - else if (addr < 0x100000000) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x04); - addbyte(0x25); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x48); /*MOV ESI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad(addr); - addbyte(0xc7); /*MOVL [ESI], val*/ - addbyte(0x00 | REG_ESI); - addlong(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) - { - addbyte(0xb8); /*MOVL EAX, imm*/ - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - int base_reg, index_reg; - - switch (rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; - } - if (!(rm & 4)) - { - if (rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); - } - base_reg &= 7; - index_reg &= 7; - - switch (mod) - { - case 0: - if (rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (mod || !(rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - 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) -{ - int mod = (fetchdat >> 6) & 3; -// int reg = (fetchdat >> 3) & 7; - int rm = fetchdat & 7; - uint32_t new_eaaddr; - - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; - - (*op_pc)++; - - if (mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - else - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - } - else - { - int base_reg; - - if (!mod && rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(rm) & 7; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - } - return op_ea_seg; -} - -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); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); -} - - - -static inline void CHECK_SEG_READ(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE BLOCK_GPF_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_WRITE(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE BLOCK_GPF_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ - addlong((uint32_t)(uintptr_t)seg); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)seg); - } - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_low - (uintptr_t)seg); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_high - (uintptr_t)seg); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemb386l); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -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 inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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(4+2); - addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} - -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 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 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 inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) -{ - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_32(host_reg); - call_long((uintptr_t)writememb386l); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_32(host_reg); - call_long((uintptr_t)writememwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_32(host_reg); - call_long((uintptr_t)writememll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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(4+2); - if (host_reg & 8) - { - addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - load_param_3_reg_64(host_reg); - call_long((uintptr_t)writememql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} - -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 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 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 inline void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 0x10) - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb7); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - addbyte(0xc1); /*SHR temp_reg, 8*/ - addbyte(0xe8 | temp_reg); - addbyte(8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb6); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - } - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static inline void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb7); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -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) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} -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) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} - -static inline void AND_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - addbyte(0x66); /*OR AX, 0x00ff*/ - addbyte(0x0d); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ANDB dst_reg, AL*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*OR src_reg, 0xff*/ - addbyte(0x81); - addbyte(0xc8 | src_reg); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x20); /*ANDB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void AND_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void AND_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } -} - -static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; - } - - AND_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; -} -static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((host_reg & 7) << 3)); - host_reg = REG_EDX | (host_reg & 0x10); - } - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } - - return host_reg; -} - -static inline void OR_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ORB dst_reg, AL*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x08); /*ORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void OR_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void OR_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x09); /*ORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } -// fatal("OR to bad register\n"); -} - -static inline void XOR_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*XORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*XORB dst_reg, AL*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x30); /*XORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static inline void XOR_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x31); /*XORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } -// fatal("XOR to bad register\n"); -} - -static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ADDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ADDB dst_reg, AL*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x00); /*ADDB dst_reg, AL*/ - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - fatal("!(dst_reg & src_reg & 8)\n"); -} -static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); -} -static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); -} - -static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*SUBW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*SUBB dst_reg, AL*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x28); /*SUBB dst_reg, 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 inline void SUB_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} - -static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; - } - - SUB_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; -} -static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} - -static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xC0 | (host_reg & 7)); - addword(imm << 8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*ADDB host_reg, imm*/ - addbyte(0xC0 | (host_reg & 7)); - addbyte(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) - addbyte(0x41); - addbyte(0x81); - addbyte(0xC0 | (host_reg & 7)); - addword(imm); -} -static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ADDL host_reg, imm*/ - addbyte(0xC0 | (host_reg & 7)); - addlong(imm); -} - -static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xE8 | (host_reg & 7)); - addword(imm << 8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*SUBB host_reg, imm*/ - addbyte(0xE8 | (host_reg & 7)); - addbyte(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) - addbyte(0x41); - addbyte(0x81); - addbyte(0xE8 | (host_reg & 7)); - addword(imm); -} -static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | (host_reg & 7)); - addlong(imm); -} - -static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = (host_reg & 0x10) | REG_EDX; - } - - SUB_HOST_REG_IMM_B(host_reg, imm); - - return host_reg;// & ~0x10; -} -static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM_W(host_reg, imm); - - return host_reg; -} -static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -static inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} -static inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_BP].l)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - -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) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -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) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static inline void 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*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - 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((uintptr_t)CF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - 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((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((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - 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 inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -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((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - 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((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - 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((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((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - 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 inline int LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x0f); /*MOVZX host_reg,[reg]*/ - addbyte(0xb7); - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/ - addbyte(0xb7); - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} -static inline int LOAD_VAR_WL(uintptr_t addr) -{ - return LOAD_VAR_W(addr); -} -static inline int LOAD_VAR_L(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x8b); /*MOVL host_reg, [host_reg]*/ - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} - -static inline int COPY_REG(int src_reg) -{ - if (src_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | REG_ECX | ((src_reg & 7) << 3)); - - return REG_ECX | (src_reg & 0x10); -} - -static inline int LOAD_HOST_REG(int host_reg) -{ - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3)); - - return REG_EBX | (host_reg & 0x10); -} - -static inline int ZERO_EXTEND_W_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int ZERO_EXTEND_L_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int ZERO_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regw*/ - addbyte(0xb7); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} - -static inline int SIGN_EXTEND_W_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int SIGN_EXTEND_L_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static inline int SIGN_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} - -static inline void SHL_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHL AH, count*/ - addbyte(0xe0 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); - } -} -static inline void SHL_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHL reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static inline void SHL_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static inline void SHR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHR AH, count*/ - addbyte(0xe8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); - } -} -static inline void SHR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static inline void SHR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static inline void SAR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SAR AH, count*/ - addbyte(0xf8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); - } -} -static inline void SAR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SAR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); -} -static inline void SAR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); -} - -static inline void NEG_HOST_REG_B(int reg) -{ - if (reg & 0x10) - { - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV BX, reg*/ - addbyte(0xc3 | ((reg & 7) << 3)); - addbyte(0xf6); /*NEG BH*/ - addbyte(0xdf); - if (reg & 8) - addbyte(0x41); - addbyte(0x89); /*MOV reg, BX*/ - addbyte(0xd8 | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xf6); - addbyte(0xd8 | (reg & 7)); - } -} -static inline void NEG_HOST_REG_W(int reg) -{ - addbyte(0x66); - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); -} -static inline void NEG_HOST_REG_L(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); -} - - -static inline void FP_ENTER() -{ - if (codegen_fpu_entered) - return; - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } - addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - codegen_fpu_entered = 1; -} - -static inline void FP_FXCH(int reg) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - - addbyte(0x48); /*MOV RDX, ST[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0x48); /*MOV RCX, ST[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - - addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - reg = reg; -} - - - -static inline void FP_FLD(int reg) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } - - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(0x07); - addbyte(0x48); /*MOV RDX, ST_i64[EAX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x48); /*MOV ST[EBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); -} - -static inline void FP_FST(int reg) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0x48); /*MOV ST[EAX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); -} - -static inline void FP_POP() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); -} -static inline void FP_POP2() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 2*/ - addbyte(0xc0); - addbyte(2); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); -} - -static inline void FP_LOAD_S() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf3); /*CVTSS2SD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_D() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} - -static inline void FP_LOAD_IW() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_IL() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static inline void FP_LOAD_IQ() -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SDQ XMM0, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x48); /*MOV [ST_i64+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - 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((uint8_t)cpu_state_offset(tag)); -} - -static inline void FP_LOAD_IMM_Q(uint64_t v) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(v ? 0 : 1); -} - -static inline void FP_FCHS() -{ - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf2); /*SUBSD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc0); - addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - 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((uint8_t)cpu_state_offset(ST)); -} - -static inline int FP_LOAD_REG(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x66); /*MOVD EBX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0 | REG_EBX); - - return REG_EBX; -} -static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x48); /*MOV RBX, ST[EBX*8]*/ - addbyte(0x8b); - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - *host_reg1 = REG_EBX; -} -static inline int64_t x87_fround(double b) -{ - int64_t a, c; - - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } - - return 0; -} -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((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); - - addbyte(0x93); /*XCHG EBX, EAX*/ - - return REG_EBX; -} -static inline int FP_LOAD_REG_INT(int reg) -{ - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); - - addbyte(0x93); /*XCHG EBX, EAX*/ - - return REG_EBX; -} -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((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ - addbyte(0x8b); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0x48); /*XCHG RBX, RAX*/ - addbyte(0x93); - - *host_reg1 = REG_EBX; - - return; - } - - addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_UINT64); - - addbyte(0x74); /*JZ +*/ - addbyte(5+2); - - addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ - addbyte(0x8b); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0xeb); /*JMP done*/ - addbyte(6+12); - - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); - - addbyte(0x48); /*XCHG RBX, RAX*/ - addbyte(0x93); - - *host_reg1 = REG_EBX; -} - -#define FPU_ADD 0 -#define FPU_DIV 4 -#define FPU_DIVR 5 -#define FPU_MUL 1 -#define FPU_SUB 2 -#define FPU_SUBR 3 - -static inline void FP_OP_REG(int op, int dst, int src) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (dst) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - if (src) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(src); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(~TAG_UINT64); - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - } - addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); -} - -static inline void FP_OP_MEM(int op) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(~TAG_UINT64); - - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0xc1); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc1); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc8); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0xc1); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc1); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc8); - break; - } - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} - -static inline void FP_OP_S(int op) -{ - addbyte(0x66); /*MOVD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_OP_MEM(op); -} -static inline void FP_OP_D(int op) -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*STMXCSR [ESP+8]*/ - addbyte(0xae); - addbyte(0x5c); - addbyte(0x24); - addbyte(0x08); - addbyte(0x8b); /*MOV EAX, [ESP+8]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x08); - addbyte(0x25); /*AND EAX, ~(3 << 13)*/ - addlong(~(3 << 10)); - addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/ - addlong((cpu_state.npxc & (3 << 10)) << 3); - addbyte(0x89); /*MOV [RSP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x0c); - addbyte(0x0f); /*LDMXCSR [RSP+12]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x0c); - } - FP_OP_MEM(op); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*LDMXCSR [RSP+8]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x08); - } -} -static inline void FP_OP_IW(int op) -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} -static inline void FP_OP_IL(int op) -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} - -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - -static inline void FP_COMPARE_REG(int dst, int src) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -// addbyte(0xdb); /*FCLEX*/ -// addbyte(0xe2); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} - -static inline void FP_COMPARE_MEM() -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -// addbyte(0xdb); /*FCLEX*/ -// addbyte(0xe2); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0x66); /*COMISD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0xc1); - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} -static inline void FP_COMPARE_S() -{ - addbyte(0x66); /*MOVD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_D() -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_IW() -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static inline void FP_COMPARE_IL() -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); -} - -static inline void UPDATE_NPXC(int reg) -{ -} - -static inline void SET_BITS(uintptr_t addr, uint32_t val) -{ - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addbyte(val); - } - } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*OR [RAX], val*/ - addbyte(0x08); - addlong(val); - } - else - { - addbyte(0x80); /*OR [RAX], val*/ - addbyte(0x08); - addbyte(val); - } - } -} - -static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) -{ - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } - } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*AND [RAX], val*/ - addbyte(0x20); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [RAX], val*/ - addbyte(0x20); - addbyte(~val); - } - } -} - -#define LOAD_Q_REG_1 REG_EAX -#define LOAD_Q_REG_2 REG_EDX - -static inline void MMX_ENTER() -{ - if (codegen_mmx_entered) - return; - - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } - addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); - - codegen_mmx_entered = 1; -} - -extern int mmx_ebx_ecx_loaded; - -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((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - - return host_reg; -} -static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) -{ - int host_reg = REG_EBX; - - if (host_reg & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x8b); /*MOV RBX, reg*/ - addbyte(0x44 | ((host_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); - - *host_reg1 = host_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; - - addbyte(0xf3); /*MOV XMMx, reg*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44 | ((dst_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); - - return dst_reg; -} - -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; - - addbyte(0x66); /*MOVQ host_reg, src_reg1*/ - if (src_reg1 & 8) - addbyte(0x49); - else - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | (src_reg1 & 7)); - - return dst_reg; -} - -static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) -{ - addbyte(0xC7); /*MOVL [reg],0*/ - addbyte(0x44); - addbyte(0x25); - 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((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); -} -static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) -{ - if (host_reg1 & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x89); /*MOV [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); -} -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((uint8_t)cpu_state_offset(MM[guest_reg].q)); -} - -#define MMX_x86_OP(name, opcode) \ -static inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} - -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) - -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) - -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -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(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(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); -MMX_x86_OP(PMADDWD, 0xf5); - -static inline void MMX_PACKSSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKUSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKSSDW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} - -static inline void MMX_PSRLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - - -static inline void SAVE_EA() -{ - addbyte(0x89); /*MOV [ESP+0x24], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); -} -static inline void LOAD_EA() -{ - addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); -} - -#define MEM_CHECK_WRITE_B MEM_CHECK_WRITE - -static inline void MEM_CHECK_WRITE(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3 = NULL; - - CHECK_SEG_WRITE(seg); - - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_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(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); -// addbyte(0xc3); /*RET*/ - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_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*/ - - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - /*slowpath:*/ - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - - - 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], (uintptr_t)mmutranslatereal); -// addbyte(0x48); /*ADD ESP, 8*/ -// addbyte(0x83); -// addbyte(0xc4); -// addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); -// addbyte(0xc3); /*RET*/ - *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 inline void MEM_CHECK_WRITE_W(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_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(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_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); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_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); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *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); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal); - addbyte(0x83); /*ADD EBX, 1*/ - addbyte(0xc3); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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] - ((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); - addlong(0xfff); - addbyte(0x74); /*JNE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static inline void MEM_CHECK_WRITE_L(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_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(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_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); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_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); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *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); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal); - addbyte(0x83); /*ADD EBX, 3*/ - addbyte(0xc3); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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] - ((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); - addlong(0xffc); - addbyte(0x74); /*JE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemb386l); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemwl); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)readmemll); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} - -static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) -{ - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12); - /*slowpath:*/ - load_param_3_reg_32(host_reg); - load_param_1_reg_32(REG_EBX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)writememb386l); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12); - /*slowpath:*/ - load_param_3_reg_32(host_reg); - load_param_1_reg_32(REG_EBX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)writememwl); - /*done:*/ -} -static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - 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) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12); - /*slowpath:*/ - load_param_3_reg_32(host_reg); - load_param_1_reg_32(REG_EBX); - load_param_2_reg_32(REG_EAX); - call_long((uintptr_t)writememll); - /*done:*/ -} - -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((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h deleted file mode 100644 index 4066482..0000000 --- a/src/codegen_ops_x86.h +++ /dev/null @@ -1,3995 +0,0 @@ -/*Register allocation : - EBX, ECX, EDX - emulated registers - EAX - work register, EA storage - ESI, EDI - work registers - EBP - points at emulated register array -*/ -#define HOST_REG_START 1 -#define HOST_REG_END 4 -#define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 -static inline int find_host_reg() -{ - int c; - for (c = HOST_REG_START; c < HOST_REG_END; c++) - { - if (host_reg_mapping[c] == -1) - break; - } - - if (c == NR_HOST_REGS) - fatal("Out of host regs!\n"); - return c; -} -static inline int find_host_xmm_reg() -{ - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } - - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; -} - -#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 inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x05); - addlong(addr); - addword(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) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uint32_t)&cpu_state - 128); - addlong(val); - } - else - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x05); - addlong(addr); - addlong(val); - } -} - -static inline void STORE_IMM_REG_B(int reg, uint8_t val) -{ - addbyte(0xC6); /*MOVB [addr],val*/ - addbyte(0x45); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - addbyte(val); -} -static inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - addword(val); -} -static inline void STORE_IMM_REG_L(int reg, uint32_t val) -{ - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); - addlong(val); -} - -static inline int LOAD_REG_B(int reg) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX B[reg],host_reg*/ - addbyte(0xb6); - addbyte(0x45 | (host_reg << 3)); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - - return host_reg; -} -static inline int LOAD_REG_W(int reg) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX W[reg],host_reg*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - - return host_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((uint8_t)cpu_state_offset(regs[reg & 7].l)); - - return host_reg; -} - -static inline int LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x66); /*MOVL host_reg,[reg]*/ - addbyte(0x8b); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); - - return host_reg; -} -static inline int LOAD_VAR_WL(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x0f); /*MOVZX host_reg, [addr]*/ - addbyte(0xb7); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); - - return host_reg; -} -static inline int LOAD_VAR_L(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); - - return host_reg; -} - -static inline int LOAD_REG_IMM(uint32_t imm) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0xc7); /*MOVL host_reg, imm*/ - addbyte(0xc0 | host_reg); - addlong(imm); - - return 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; - - addbyte(0x89); /*MOV new_host_reg, host_reg*/ - addbyte(0xc0 | (host_reg << 3) | new_host_reg); - - return new_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((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_W_RELEASE(int host_reg) -{ - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); - host_reg_mapping[host_reg] = -1; -} -static inline void STORE_REG_L_RELEASE(int host_reg) -{ - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); - host_reg_mapping[host_reg] = -1; -} - -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((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.l)); - host_reg_mapping[host_reg] = -1; -} -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((uint8_t)cpu_state_offset(regs[guest_reg & 7].w)); - host_reg_mapping[host_reg] = -1; -} -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((uint8_t)cpu_state_offset(regs[guest_reg & 7].l)); - host_reg_mapping[host_reg] = -1; -} - -static inline void RELEASE_REG(int host_reg) -{ - host_reg_mapping[host_reg] = -1; -} - -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) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x66); /*MOVL [reg],host_reg*/ - addbyte(0x89); - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } -} -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) - { - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } -} -#define STORE_HOST_REG_ADDR_BL STORE_HOST_REG_ADDR -#define STORE_HOST_REG_ADDR_WL STORE_HOST_REG_ADDR - -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 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 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 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 inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x83); - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x81); - addbyte(0xC0 | host_reg); - addword(imm); - } -} -static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addlong(imm); - } -} - -#define AND_HOST_REG_B AND_HOST_REG_L -#define AND_HOST_REG_W AND_HOST_REG_L -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 inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addlong(imm); - } -} -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 inline int TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_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 inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - AND_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -#define OR_HOST_REG_B OR_HOST_REG_L -#define OR_HOST_REG_W OR_HOST_REG_L -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 inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addlong(imm); - } -} - -static inline void NEG_HOST_REG_B(int reg) -{ - addbyte(0xf6); - addbyte(0xd8 | reg); -} -static inline void NEG_HOST_REG_W(int reg) -{ - addbyte(0x66); - addbyte(0xf7); - addbyte(0xd8 | reg); -} -static inline void NEG_HOST_REG_L(int reg) -{ - addbyte(0xf7); - addbyte(0xd8 | 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 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 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 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 inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x83); - addbyte(0xE8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x81); - addbyte(0xE8 | host_reg); - addword(imm); - } -} -static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addbyte(imm); - } - else - { - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addlong(imm); - } -} - -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 inline int CMP_HOST_REG_W(int dst_reg, int src_reg) -{ - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_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 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 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 inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) -{ - SUB_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -#define XOR_HOST_REG_B XOR_HOST_REG_L -#define XOR_HOST_REG_W XOR_HOST_REG_L -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 inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addlong(imm); - } -} - -static inline void CALL_FUNC(uintptr_t dest) -{ - addbyte(0xE8); /*CALL*/ - addlong(((uintptr_t)dest - (uintptr_t)(&codeblock[block_current].data[block_pos + 4]))); -} - -static inline void SHL_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(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 inline void SHL_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static inline void SHR_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(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 inline void SHR_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static inline void SAR_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(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 inline void SAR_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} - - -static inline void CHECK_SEG_READ(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_WRITE(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &_cs || seg == &_ss) - return; - if (seg->checked) - return; - if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; - - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_low); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_high); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - host_reg_mapping[0] = 8; -} -static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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); - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - - host_reg_mapping[0] = 8; -} -static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} - -static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); - - host_reg_mapping[0] = 8; -} - -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 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 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 inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ - addlong(mem_store_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - 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 inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ - addlong(mem_store_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - 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 inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ - addlong(mem_store_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - 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 inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if (host_reg != REG_EBX) - { - addbyte(0x89); /*MOV EBX, host_reg*/ - addbyte(0xc0 | REG_EBX | (host_reg << 3)); - } - if (host_reg2 != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg2*/ - addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); - } - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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])); -} - -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 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 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 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) - { - addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - switch (mod) - { - case 0: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - break; - case 1: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 8)); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff);// pc++; - addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL EAX, 0xffff*/ - addlong(0xffff); - - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - return op_ea_seg; -} - -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) - { - uint8_t sib = fetchdat >> 8; - (*op_pc)++; - - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr);// pc++; - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 16)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - if (stack_offset < 0x80 || stack_offset >= 0xffffff80) - { - addbyte(0x83); - addbyte(0xc0 | REG_EAX); - addbyte(stack_offset); - } - else - { - addbyte(0x05); /*ADDL EAX, stack_offset*/ - addlong(stack_offset); - } - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - 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((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((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; - } - } - } - else - { - if (!mod && rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[rm].l)); - cpu_state.eaaddr = cpu_state.regs[rm].l; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (mod == 1) - { - addbyte(0x83); /*ADD EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); /*ADD EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - } - return op_ea_seg; -} - -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); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); -} - - -static inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - - -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); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -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); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -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); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -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); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -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((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+2); - CALL_FUNC((uintptr_t)CF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -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((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - - default: - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -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((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+3+5+2+3+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+3+5+2+3+2+2); - - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - - -static inline void FP_ENTER() -{ - if (codegen_fpu_entered) - return; - - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - codegen_fpu_entered = 1; -} - -static inline void FP_FLD(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - 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((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((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x88); /*MOV tag[-1][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } - - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - 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((uint8_t)cpu_state_offset(MM)); - addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -static inline void FP_FST(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -static inline void FP_FXCH(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - 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((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((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[0][EBP], AH*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - - addbyte(0xdd); /*FLD [ST+EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - 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]*/ - addbyte(0x0c); - addbyte(0xc6); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ - addbyte(0x14); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ - addbyte(0x0c); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ - addbyte(0x14); - addbyte(0xc6); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ - addbyte(0x4c); - addbyte(0xc6); - addbyte(0x04); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ - addbyte(0x54); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ - addbyte(0x4c); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ - addbyte(0x54); - addbyte(0xc6); - addbyte(0x04); - } -} - - -static inline void FP_LOAD_S() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xd9); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_D() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x09); /*OR EAX, EDX*/ - addbyte(0xd0); - addbyte(0xdd); /*FLD [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IW() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0x66); /*TEST AX, AX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdf); /*FILDw [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IL() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x0f); /*SETE tag[reg][EBP]*/ - addbyte(0x94); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0xdb); /*FILDl [ESP]*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x83); /*CMP EAX, 0*/ - addbyte(0xf8); - addbyte(0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} -static inline void FP_LOAD_IQ() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ - addbyte(0x45); - 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((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((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((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - addbyte(0xdd); /*FSTP ST[reg][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ - addbyte(0x44); - addbyte(0xdd); - 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((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((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((uint8_t)cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -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((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((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((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(1); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(v ? 0 : 1); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -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((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - addbyte(0xd9); /*FSTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV EAX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(0x24); - - return REG_EBX; -} - -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((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - addbyte(0xdd); /*FSTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, [ESP+4]*/ - addbyte(0x44 | (REG_ECX << 3)); - addbyte(0x24); - addbyte(0x04); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; -} - -static inline int FP_LOAD_REG_INT_W(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - 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((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static inline int FP_LOAD_REG_INT(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - 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((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - - return; - } - - addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_UINT64); - addbyte(0x74); /*JZ +*/ - addbyte(4+4+2); - - addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+3+3+3+4); - - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - 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((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, 4[ESP]*/ - addbyte(0x4c); - addbyte(0x24); - addbyte(4); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; -} - -static inline void FP_POP() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 1) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 1*/ - addbyte(1); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} -static inline void FP_POP2() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB tag[1][EBP], 3*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 2) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 2*/ - addbyte(2); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -#define FPU_ADD 0x00 -#define FPU_DIV 0x30 -#define FPU_DIVR 0x38 -#define FPU_MUL 0x08 -#define FPU_SUB 0x20 -#define FPU_SUBR 0x28 - -static inline void FP_OP_S(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - 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((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -static inline void FP_OP_D(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - 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((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((uint8_t)cpu_state_offset(old_npxc)); - } - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - 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((uint8_t)cpu_state_offset(old_npxc)); - } - } -} -static inline void FP_OP_IW(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - 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((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -static inline void FP_OP_IL(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - 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((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } -} -#if 0 -static inline void FP_OP_IQ(int op) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - 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((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - 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 inline void FP_COMPARE_S() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} -static inline void FP_COMPARE_D() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} -static inline void FP_COMPARE_IW() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} -static inline void FP_COMPARE_IL() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - 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((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} - -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((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0xdc); /*FADD ST[src][EBP]*/ - addbyte(0x45 | op); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); - addbyte(~TAG_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD ST[EAX*8]*/ - addbyte(0x44 | op); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); - addbyte(0xdc); /*FADD ST[EBX*8]*/ - addbyte(0x44 | op); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - } -} - -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((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EAX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EBX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} - -static inline void FP_FCHS() -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - 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((uint8_t)cpu_state_offset(ST)); - } -} - -static inline void UPDATE_NPXC(int reg) -{ - addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/ - addbyte(0x81); - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addword(~0xc00); - if (reg) - { - addbyte(0x66); /*AND reg, 0xc00*/ - addbyte(0x81); - addbyte(0xe0 | reg); - addword(0xc00); - } - else - { - addbyte(0x66); /*AND AX, 0xc00*/ - addbyte(0x25); - addword(0xc00); - } - addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ - addbyte(0x09); - addbyte(0x45 | (reg << 3)); - addbyte((uint8_t)cpu_state_offset(new_npxc)); -} - -static inline int ZERO_EXTEND_W_B(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return 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 inline int ZERO_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regw*/ - addbyte(0xb7); - addbyte(0xc0 | reg | (reg << 3)); - return 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 inline int SIGN_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static inline int SIGN_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} - -static inline int COPY_REG(int src_reg) -{ - return src_reg; -} - -static inline void SET_BITS(uintptr_t addr, uint32_t val) -{ - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x0d); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); - addbyte(0x0d); - addlong(addr); - addbyte(val); - } -} -static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) -{ - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } -} - -#define LOAD_Q_REG_1 REG_EAX -#define LOAD_Q_REG_2 REG_EDX - -static inline void MMX_ENTER() -{ - if (codegen_mmx_entered) - return; - - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); - - codegen_mmx_entered = 1; -} - -extern int mmx_ebx_ecx_loaded; - -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((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - - return host_reg; -} -static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) -{ - if (!mmx_ebx_ecx_loaded) - { - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; - mmx_ebx_ecx_loaded = 1; - } - else - { - *host_reg1 = REG_EAX; - *host_reg2 = REG_EDX; - } - - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | ((*host_reg1) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x8b); /*MOV ECX, reg+4*/ - addbyte(0x45 | ((*host_reg2) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); -} -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; - - addbyte(0xf3); /*MOVQ dst_reg,[reg]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45 | (dst_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); - - return dst_reg; -} - -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; - - addbyte(0x66); /*MOVD dst_reg, src_reg1*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | src_reg1); - addbyte(0x66); /*MOVD XMM7, src_reg2*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (7 << 3) | src_reg2); - addbyte(0x66); /*PUNPCKLDQ dst_reg, XMM7*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | 7 | (dst_reg << 3)); - - return dst_reg; -} - -static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) -{ - addbyte(0xC7); /*MOVL [reg],0*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); -} -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((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg2 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); -} -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((uint8_t)cpu_state_offset(MM[guest_reg].q)); -} - -#define MMX_x86_OP(name, opcode) \ -static inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} - -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) - -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) - -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -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(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(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); -MMX_x86_OP(PMADDWD, 0xf5); - -static inline void MMX_PACKSSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKUSWB(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PACKSSDW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); -} -static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} -static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) -{ - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); -} - -static inline void MMX_PSRLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLW_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLD_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - -static inline void MMX_PSRLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); -} -static inline void MMX_PSRAQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); -} -static inline void MMX_PSLLQ_imm(int dst_reg, int amount) -{ - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); -} - - -static inline void SAVE_EA() -{ - addbyte(0x89); /*MOV [ESP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); -} -static inline void LOAD_EA() -{ - addbyte(0x8b); /*MOV EAX, [ESP+12]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); -} - -#define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static inline void MEM_CHECK_WRITE(x86seg *seg) -{ - CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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(); -} -static inline void MEM_CHECK_WRITE_W(x86seg *seg) -{ - CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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(); -} -static inline void MEM_CHECK_WRITE_L(x86seg *seg) -{ - CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - 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(); -} - -static inline void LOAD_SEG(int host_reg, void *seg) -{ - addbyte(0xc7); /*MOV [ESP+4], seg*/ - addbyte(0x44); - addbyte(0x24); - addbyte(4); - addlong((uint32_t)seg); - addbyte(0x89); /*MOV [ESP], host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x24); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} diff --git a/src/codegen_ops_xchg.h b/src/codegen_ops_xchg.h deleted file mode 100644 index 25ff4c7..0000000 --- a/src/codegen_ops_xchg.h +++ /dev/null @@ -1,93 +0,0 @@ -#define OP_XCHG_AX_(reg) \ - static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int ax_reg, host_reg, temp_reg; \ - \ - ax_reg = LOAD_REG_W(REG_AX); \ - host_reg = LOAD_REG_W(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \ - STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ - \ - return op_pc; \ - } - -OP_XCHG_AX_(BX) -OP_XCHG_AX_(CX) -OP_XCHG_AX_(DX) -OP_XCHG_AX_(SI) -OP_XCHG_AX_(DI) -OP_XCHG_AX_(SP) -OP_XCHG_AX_(BP) - -#define OP_XCHG_EAX_(reg) \ - static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int eax_reg, host_reg, temp_reg; \ - \ - eax_reg = LOAD_REG_L(REG_EAX); \ - host_reg = LOAD_REG_L(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \ - STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ - \ - return op_pc; \ - } - -OP_XCHG_EAX_(EBX) -OP_XCHG_EAX_(ECX) -OP_XCHG_EAX_(EDX) -OP_XCHG_EAX_(ESI) -OP_XCHG_EAX_(EDI) -OP_XCHG_EAX_(ESP) -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 - int src_reg, dst_reg, temp_reg; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - - dst_reg = LOAD_REG_B(fetchdat & 7); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); - - return op_pc + 1; -#endif -} -static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg, temp_reg; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - - dst_reg = LOAD_REG_W(fetchdat & 7); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7); - - return op_pc + 1; -} -static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg, temp_reg; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - - dst_reg = LOAD_REG_L(fetchdat & 7); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7); - - return op_pc + 1; -} diff --git a/src/codegen_x86.c b/src/codegen_x86.c deleted file mode 100644 index b61008c..0000000 --- a/src/codegen_x86.c +++ /dev/null @@ -1,2180 +0,0 @@ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 - -#include -#include "ibm.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.h" - -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif - -int codegen_flat_ds, codegen_flat_ss; -int mmx_ebx_ecx_loaded; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_mmx_entered = 0; -int codegen_fpu_loaded_iq[8]; -x86seg *op_ea_seg; -int op_ssegs; -uint32_t op_old_pc; - -uint32_t recomp_page = -1; - -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; -codeblock_t **codeblock_hash; - - -int block_current = 0; -static int block_num; -int block_pos; - -int cpu_recomp_flushes, cpu_recomp_flushes_latched; -int cpu_recomp_evicted, cpu_recomp_evicted_latched; -int cpu_recomp_reuse, cpu_recomp_reuse_latched; -int cpu_recomp_removed, cpu_recomp_removed_latched; - -uint32_t codegen_endpc; - -int codegen_block_cycles; -static int codegen_block_ins; -static int codegen_block_full_ins; - -static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; - -static uint32_t mem_abrt_rout; -uint32_t mem_load_addr_ea_b; -uint32_t mem_load_addr_ea_w; -uint32_t mem_load_addr_ea_l; -uint32_t mem_load_addr_ea_q; -uint32_t mem_store_addr_ea_b; -uint32_t mem_store_addr_ea_w; -uint32_t mem_store_addr_ea_l; -uint32_t mem_store_addr_ea_q; -uint32_t mem_load_addr_ea_b_no_abrt; -uint32_t mem_store_addr_ea_b_no_abrt; -uint32_t mem_load_addr_ea_w_no_abrt; -uint32_t mem_store_addr_ea_w_no_abrt; -uint32_t mem_load_addr_ea_l_no_abrt; -uint32_t mem_store_addr_ea_l_no_abrt; -uint32_t mem_check_write; -uint32_t mem_check_write_w; -uint32_t mem_check_write_l; - -static uint32_t gen_MEM_LOAD_ADDR_EA_B() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmembl*/ - addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*MOVZX EAX, AL*/ - addbyte(0xb6); - addbyte(0xc0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*MOVZX EAX, AX*/ - addbyte(0xb7); - addbyte(0xc0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x04); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_LOAD_ADDR_EA_Q() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+4+1); - addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x04); - addbyte(0x3a); - addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ - addbyte(0x54); - addbyte(0x3a); - addbyte(4); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemql*/ - addlong((uint32_t)readmemql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_B() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x88); /*MOV [EDI+ESI],CL*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememb386l*/ - addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - 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(4+1); - addbyte(0x66); /*MOV [EDI+ESI],CX*/ - addbyte(0x89); - addbyte(0x04 | (REG_CX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - 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(3+1); - addbyte(0x89); /*MOV [EDI+ESI],ECX*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_STORE_ADDR_EA_Q() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*dat = EBX/ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EDX, ESI*/ - addbyte(0xf2); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - 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(3+4+1); - addbyte(0x89); /*MOV [EDI+ESI],EBX*/ - addbyte(0x04 | (REG_EBX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ - addbyte(0x44 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(4); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x52); /*PUSH EDX*/ - addbyte(0xe8); /*CALL writememql*/ - addlong((uint32_t)writememql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 16*/ - addbyte(0xc4); - addbyte(16); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - 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]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX ECX, B[EDX+EDI]*/ - addbyte(0xb6); - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmembl*/ - addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); -#endif - addbyte(0x0f); /*MOVZX ECX, AL*/ - addbyte(0xb6); - addbyte(0xc8); -#ifndef RELEASE_BUILD - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - 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!*/ -#endif - 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]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ - addbyte(0xb7); - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemwl*/ - addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); -#endif - addbyte(0x0f); /*MOVZX ECX, AX*/ - addbyte(0xb7); - addbyte(0xc8); -#ifndef RELEASE_BUILD - addbyte(0x75); /*JNE mem_abrt_rout*/ - addbyte(1); -#endif - addbyte(0xc3); /*RET*/ -#ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - 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!*/ -#endif - 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]; - - addbyte(0x89); /*MOV ESI, EDX*/ - addbyte(0xd6); - addbyte(0x01); /*ADDL EDX, EAX*/ - addbyte(0xc2); - addbyte(0x89); /*MOV EDI, EDX*/ - addbyte(0xd7); - addbyte(0xc1); /*SHR EDX, 12*/ - addbyte(0xea); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ - addbyte(0x14); - addbyte(0x95); - addlong((uint32_t)readlookup2); - addbyte(0x75); /*JE slowpath*/ - addbyte(3+2+3+1); - addbyte(0x83); /*CMP EDX, -1*/ - addbyte(0xfa); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ - addbyte(0x0c); - addbyte(0x3a); - addbyte(0xc3); /*RET*/ - - addbyte(0x50); /*slowpath: PUSH EAX*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0xe8); /*CALL readmemll*/ - addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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(0x83); /*SUBL 4,%esp*/ - addbyte(0xEC); - addbyte(4); - addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - 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!*/ -#endif - 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]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+1); - addbyte(0x88); /*MOV [EDI+ESI],CL*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememb386l*/ - addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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_B_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - 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!*/ -#endif - 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]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - 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(4+1); - addbyte(0x66); /*MOV [EDI+ESI],CX*/ - addbyte(0x89); - addbyte(0x04 | (REG_CX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememwl*/ - addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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(0x04); - addbyte(0x24); - 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!*/ -#endif - 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]; - - /*dat = ECX, seg = ESI, addr = EAX*/ - addbyte(0x89); /*MOV EBX, ESI*/ - addbyte(0xf3); - addbyte(0x01); /*ADDL ESI, EAX*/ - addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ - addbyte(0x04 | (REG_ESI << 3)); - addbyte(0x85 | (REG_ESI << 3)); - addlong((uint32_t)writelookup2); - 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(3+1); - addbyte(0x89); /*MOV [EDI+ESI],ECX*/ - addbyte(0x04 | (REG_ECX << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xc3); /*RET*/ - - addbyte(0x51); /*slowpath: PUSH ECX*/ - addbyte(0x50); /*PUSH EAX*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0xe8); /*CALL writememll*/ - addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 12*/ - addbyte(0xc4); - addbyte(12); -#ifndef RELEASE_BUILD - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - 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_L_NO_ABRT_err*/ - addbyte(0x04); - addbyte(0x24); - 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!*/ -#endif - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal*/ - addlong((uint32_t)mmutranslatereal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x83); /*ADD ESP, 8*/ - addbyte(0xc4); - addbyte(8); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - addbyte(0xc3); /*RET*/ - - return addr; -} - -/*static void checkdebug(uint32_t a) -{ - pclog("checkdebug %08x\n", a); -}*/ - -static uint32_t gen_MEM_CHECK_WRITE_W() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x89); /*MOV EAX, EDI*/ - addbyte(0xf8); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ - addbyte(0x3c); - addbyte(0xb5); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc7); - /*slowpath_lp:*/ - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal*/ - addlong((uint32_t)mmutranslatereal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x83); /*ADD EDI, 1*/ - addbyte(0xc7); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_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, EDI*/ - addbyte(0xc7); - addlong(0xfff); - addbyte(0x74); /*JE slowpath_lp*/ - addbyte(-33); - addbyte(0xc3); /*RET*/ - - return addr; -} - -static uint32_t gen_MEM_CHECK_WRITE_L() -{ - uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; - - /*seg = ESI, addr = EAX*/ - - addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x3c); - addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3d); - addlong((uint32_t)&cr0); - addbyte(0); - addbyte(0x78); /*JS +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - addbyte(0x74); /*JE slowpath*/ - addbyte(11); - addbyte(0x89); /*MOV EAX, EDI*/ - addbyte(0xf8); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ - addbyte(0x3c); - addbyte(0xbd); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(11); - addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ - addbyte(0x3c); - addbyte(0xb5); - addlong((uint32_t)writelookup2); - addbyte(-1); - addbyte(0x74); /*JE +*/ - addbyte(1); - addbyte(0xc3); /*RET*/ - - /*slowpath:*/ - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc7); - /*slowpath_lp:*/ - addbyte(0x6a); /*PUSH 1*/ - addbyte(1); - addbyte(0x57); /*PUSH EDI*/ - addbyte(0xe8); /*CALL mmutranslatereal*/ - addlong((uint32_t)mmutranslatereal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x83); /*ADD ESP, 4*/ - addbyte(0xc4); - addbyte(4); - addbyte(0x83); /*ADD EDI, 3*/ - addbyte(0xc7); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong(mem_abrt_rout - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 2-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST EDI, FFC*/ - addbyte(0xc7); - addlong(0xffc); - addbyte(0x74); /*JE slowpath_lp*/ - addbyte(-33); - addbyte(0xc3); /*RET*/ - - return addr; -} - -void codegen_init() -{ - int c; -#if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif - -#if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; - -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - - block_current = BLOCK_SIZE; - block_pos = 0; - mem_abrt_rout = (uint32_t)&codeblock[block_current].data[block_pos]; - addbyte(0x83); /*ADDL $16+4,%esp*/ - addbyte(0xC4); - addbyte(0x10+4); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l = (uint32_t)gen_MEM_LOAD_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w = (uint32_t)gen_MEM_LOAD_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b = (uint32_t)gen_MEM_LOAD_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_q = (uint32_t)gen_MEM_LOAD_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l = (uint32_t)gen_MEM_STORE_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w = (uint32_t)gen_MEM_STORE_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b = (uint32_t)gen_MEM_STORE_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - 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 = (uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - 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 = (uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - 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 = (uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - 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 = (uint32_t)gen_MEM_CHECK_WRITE(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_w = (uint32_t)gen_MEM_CHECK_WRITE_W(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L(); - - asm( - "fstcw %0\n" - : "=m" (cpu_state.old_npxc) - ); -} - -void codegen_reset() -{ - int c; - - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); - - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; -} - -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[(block->phys >> 10) & 3]; - - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); - - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (block->next->pc == BLOCK_PC_INVALID) - fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - 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->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - } -} - -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - 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; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); - block->pc = BLOCK_PC_INVALID; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - cpu_recomp_evicted++; - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - cpu_recomp_evicted++; - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - 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 != BLOCK_PC_INVALID) - { -// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); - delete_block(block); - cpu_recomp_reuse++; - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->ins = 0; - block->pc = cs + cpu_state.pc; - 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; - block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; - addbyte(0xc7); /*MOV [ESP],0*/ - addbyte(0x04); - addbyte(0x24); - addlong(0); - addbyte(0xc7); /*MOV [ESP+4],0*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addlong(0); - addbyte(0xe8); /*CALL x86gpf*/ - addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x55); /*PUSH EBP*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $16,%esp*/ - addbyte(0xEC); - addbyte(0x10); - 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; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - _ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1; - - block->TOP = cpu_state.TOP; - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); -} - -void codegen_block_remove() -{ - codeblock_t *block = &codeblock[block_current]; - - delete_block(block); - cpu_recomp_removed++; - - recomp_page = -1; -} - -void codegen_block_generate_end_mask() -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - - block->endpc = codegen_endpc; - - block->page_mask = 0; - 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->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) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - 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[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - 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 == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %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; -} - -void codegen_block_end() -{ - codeblock_t *block = &codeblock[block_current]; - - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - 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((uint8_t)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(0x05); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - } -#endif - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - 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; -} - -void codegen_flush() -{ - return; -} - -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 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, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*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*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 1, 1, 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*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 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, 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*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug() -{ - if (output) - { - pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, cpu_state.pc, SS, ss, ESP, es,EAX, BX,ECX,BP, EDX,EDI); - } -} - -static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - if (!cpu_mod && cpu_rm == 6) - { - addbyte(0xC7); /*MOVL $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - switch (cpu_mod) - { - case 0: - addbyte(0xa1); /*MOVL *mod1add[0][cpu_rm], %eax*/ - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - break; - case 1: - addbyte(0xb8); /*MOVL ,%eax*/ - 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]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((fetchdat >> 8) & 0xffff);// pc++; - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &_ss; - } - return op_ea_seg; -} - -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; - - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; - (*op_pc)++; - - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL ,%eax*/ - addlong(new_eaaddr);// pc++; - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - 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((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((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; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - else - { - if (!cpu_mod && cpu_rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - 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((uint8_t)cpu_state_offset(regs[cpu_rm].l)); -// addbyte(0xa1); /*MOVL regs[cpu_rm].l, %eax*/ -// addlong((uint32_t)&cpu_state.regs[cpu_rm].l); - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &_ss; - if (cpu_mod == 1) - { - addbyte(0x05); - addlong((uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - return op_ea_seg; -} - -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]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - OpFn *op_table = x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; - - op_ea_seg = &_ds; - op_ssegs = 0; - op_old_pc = old_pc; - - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - mmx_ebx_ecx_loaded = 0; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) - { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - - op_pc++; - } - -generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32); - - if ((op_table == x86_dynarec_opcodes && - ((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 is likely to cause block to exit, update cycle count*/ - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(codegen_block_cycles); - codegen_block_cycles = 0; - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - codegen_block_ins = 0; - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x05); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - codegen_block_full_ins = 0; - } -#endif - } - - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } - - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); - - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; - - return; - } - } - - 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; - - addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_pc + pc_off); - } - - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - 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; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - - if (op_ea_seg != last_ea_seg) - { - last_ea_seg = op_ea_seg; - addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)op_ea_seg); - } - - addbyte(0xC7); /*MOVL pc,new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc + pc_off); - - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); - - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); - } - - addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ - addbyte(0x04); - addbyte(0x24); - addlong(fetchdat); - - addbyte(0xE8); /*CALL*/ - addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4]))); - - codegen_block_ins++; - - block->ins++; - - addbyte(0x09); /*OR %eax, %eax*/ - addbyte(0xc0); - 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]))); - - codegen_endpc = (cs + cpu_state.pc) + 8; -} - -#endif diff --git a/src/codegen_x86.h b/src/codegen_x86.h deleted file mode 100644 index c01608e..0000000 --- a/src/codegen_x86.h +++ /dev/null @@ -1,42 +0,0 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 - -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff - -#define HASH(l) ((l) & 0x1ffff) - -#define BLOCK_EXIT_OFFSET 0x7f0 -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) - -#define BLOCK_MAX 1720 - -enum -{ - OP_RET = 0xc3 -}; - -#define NR_HOST_REGS 4 -extern int host_reg_mapping[NR_HOST_REGS]; -#define NR_HOST_XMM_REGS 7 -extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; - -extern uint32_t mem_load_addr_ea_b; -extern uint32_t mem_load_addr_ea_w; -extern uint32_t mem_load_addr_ea_l; -extern uint32_t mem_load_addr_ea_q; -extern uint32_t mem_store_addr_ea_b; -extern uint32_t mem_store_addr_ea_w; -extern uint32_t mem_store_addr_ea_l; -extern uint32_t mem_store_addr_ea_q; - -extern uint32_t mem_load_addr_ea_b_no_abrt; -extern uint32_t mem_store_addr_ea_b_no_abrt; -extern uint32_t mem_load_addr_ea_w_no_abrt; -extern uint32_t mem_store_addr_ea_w_no_abrt; -extern uint32_t mem_load_addr_ea_l_no_abrt; -extern uint32_t mem_store_addr_ea_l_no_abrt; -extern uint32_t mem_check_write; -extern uint32_t mem_check_write_w; -extern uint32_t mem_check_write_l; diff --git a/src/wx-utils.cc b/src/wx-utils.cc index db4c624..561eeea 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "wx-dialogbox.h" #include "wx-app.h" From ee3f9210dc02e30f75f057ec48fa5bc8fdea5f10 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 23 Jun 2018 19:04:36 +0100 Subject: [PATCH 0472/1050] Implemented basic register allocation. Mainly handles 'virtual' registers at the moment (eg current and last PC values, segment override status, etc). --- src/Makefile.am | 2 +- src/codegen.c | 105 ++++++++++++++++++++-- src/codegen.h | 1 + src/codegen_backend.c | 3 + src/codegen_backend.h | 2 + src/codegen_backend_arm.c | 9 ++ src/codegen_backend_arm.h | 2 + src/codegen_backend_arm64.c | 9 ++ src/codegen_backend_arm64.h | 2 + src/codegen_backend_arm64_defs.h | 4 +- src/codegen_backend_arm64_uops.c | 52 ++++++++++- src/codegen_backend_arm_defs.h | 2 + src/codegen_backend_arm_uops.c | 51 ++++++++++- src/codegen_backend_x86-64.c | 7 ++ src/codegen_backend_x86-64_uops.c | 135 ++++++++++++++++++++++++++--- src/codegen_backend_x86.c | 7 ++ src/codegen_backend_x86.h | 2 + src/codegen_backend_x86_defs.h | 7 ++ src/codegen_backend_x86_uops.c | 119 ++++++++++++++++++++++--- src/codegen_ir.c | 14 ++- src/codegen_ir_defs.h | 87 +++++++++---------- src/codegen_reg.c | 139 ++++++++++++++++++++++++++++++ src/codegen_reg.h | 99 +++++++++++++++++++++ 23 files changed, 780 insertions(+), 80 deletions(-) create mode 100644 src/codegen_reg.c create mode 100644 src/codegen_reg.h diff --git a/src/Makefile.am b/src/Makefile.am index ff90dfa..c672b74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_backend.c codegen_ir.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_backend.c codegen_ir.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ diff --git a/src/codegen.c b/src/codegen.c index 7e0dc9f..238f4f6 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -4,6 +4,8 @@ #include "codegen.h" #include "x86.h" +#include "386_common.h" + #include "codegen_backend.h" #include "codegen_ir.h" @@ -27,6 +29,16 @@ void codegen_timing_set(codegen_timing_t *timing) int codegen_in_recompile; +static int last_op_ssegs; +static x86seg *last_op_ea_seg; +static uint32_t last_op_32; + +void codegen_generate_reset() +{ + last_op_ssegs = -1; + last_op_ea_seg = NULL; + last_op_32 = -1; +} void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) { @@ -37,19 +49,99 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t int opcode_shift = 0; int opcode_mask = 0x3ff; uint32_t op_32 = use32; + x86seg *op_ea_seg = &_ds; + int op_ssegs = 0; + int over = 0; + op_ea_seg = &_ds; + while (!over) + { + switch (opcode) + { + case 0x0f: + op_table = x86_dynarec_opcodes_0f; +// recomp_op_table = recomp_opcodes_0f; + over = 1; + break; + + case 0x26: /*ES:*/ + op_ea_seg = &_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &_gs; + op_ssegs = 1; + break; + + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; + + case 0xf0: /*LOCK*/ + break; + + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; +// recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; +// recomp_op_table = recomp_opcodes_REPE; + break; + + default: + goto generate_call; + } + fetchdat = fastreadl(cs + op_pc); +// codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; +// if (!pc_off) + fetchdat >>= 8; + + op_pc++; + } + +generate_call: //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - uop_STORE_PTR_IMM(ir, &cpu_state.pc, op_pc); - uop_STORE_PTR_IMM(ir, &cpu_state.oldpc, old_pc); - uop_STORE_PTR_IMM(ir, &cpu_state.op32, op_32); - uop_STORE_PTR_IMM(ir, &cpu_state.ea_seg, (uintptr_t)&_ds); - uop_STORE_PTR_IMM_8(ir, &cpu_state.ssegs, 0); + uop_MOV_IMM(ir, IREG_pc, op_pc); + uop_MOV_IMM(ir, IREG_oldpc, old_pc); + if (op_32 != last_op_32) + uop_MOV_IMM(ir, IREG_op32, op_32); +/*Lazy ea_seg/ssegs updating isn't safe until EA calculation is implemented*/ +// if (op_ea_seg != last_op_ea_seg) + uop_MOV_PTR(ir, IREG_ea_seg, (void *)op_ea_seg); +// if (op_ssegs != last_op_ssegs) + uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); uop_CALL_INSTRUCTION_FUNC(ir, op); + last_op_32 = op_32; + last_op_ea_seg = op_ea_seg; + last_op_ssegs = op_ssegs; //codegen_block_ins++; block->ins++; @@ -57,8 +149,5 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t if (block->ins >= 50) CPU_BLOCK_END(); -// addbyte(0xE8); /*CALL*/ -// addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4]))); - codegen_endpc = (cs + cpu_state.pc) + 8; } diff --git a/src/codegen.h b/src/codegen.h index def016c..8106c1c 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -325,4 +325,5 @@ extern int codegen_reg_loaded[8]; extern int codegen_in_recompile; +void codegen_generate_reset(); #endif diff --git a/src/codegen_backend.c b/src/codegen_backend.c index a6ece39..2754f5e 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -12,6 +12,7 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_ir.h" +#include "codegen_reg.h" int codegen_flat_ds, codegen_flat_ss; int mmx_ebx_ecx_loaded; @@ -308,6 +309,8 @@ void codegen_block_start_recompile(codeblock_t *block) codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); ir_data = codegen_ir_init(); + codegen_reg_reset(); + codegen_generate_reset(); } diff --git a/src/codegen_backend.h b/src/codegen_backend.h index f281b75..0f73290 100644 --- a/src/codegen_backend.h +++ b/src/codegen_backend.h @@ -63,3 +63,5 @@ struct ir_data_t *codegen_get_ir_data(); typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop); extern const uOpFn uop_handlers[]; + +extern int codegen_host_reg_list[CODEGEN_HOST_REGS]; diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 9f0be91..fa0b57c 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -15,6 +15,15 @@ #include #endif +int codegen_host_reg_list[CODEGEN_HOST_REGS] = +{ + REG_R4, + REG_R5, + REG_R6, +// REG_X22, +// REG_X23 +}; + void codegen_backend_init() { int c; diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h index 43b3fad..fd63315 100644 --- a/src/codegen_backend_arm.h +++ b/src/codegen_backend_arm.h @@ -1,3 +1,5 @@ +#include "codegen_backend_arm_defs.h" + #define BLOCK_SIZE 0x1000 #define BLOCK_MASK 0x0fff #define BLOCK_START 32 diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 5fb6115..e433f43 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -15,6 +15,15 @@ #include #endif +int codegen_host_reg_list[CODEGEN_HOST_REGS] = +{ + REG_X19, + REG_X20, + REG_X21, + REG_X22, + REG_X23 +}; + void codegen_backend_init() { int c; diff --git a/src/codegen_backend_arm64.h b/src/codegen_backend_arm64.h index 6943eb6..21bef6d 100644 --- a/src/codegen_backend_arm64.h +++ b/src/codegen_backend_arm64.h @@ -1,3 +1,5 @@ +#include "codegen_backend_arm64_defs.h" + #define BLOCK_SIZE 0x1000 #define BLOCK_MASK 0x0fff #define BLOCK_START 64 diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index d70990a..56deb25 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -69,4 +69,6 @@ #define REG_ARG2 REG_X2 #define REG_ARG3 REG_X3 -#define REG_CPUSTATE REG_X29 \ No newline at end of file +#define REG_CPUSTATE REG_X29 + +#define CODEGEN_HOST_REGS 5 \ No newline at end of file diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index ee29eb2..2da9964 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -40,6 +40,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) #define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22) +#define OPCODE_STR_IMM_Q (0x3e4 << 22) #define OPCODE_STRB_IMM (0x0e4 << 22) #define OPCODE_BLR (0xd63f0000) @@ -55,6 +56,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OFFSET12_B(offset) (offset << 10) #define OFFSET12_W(offset) ((offset >> 2) << 10) +#define OFFSET12_Q(offset) ((offset >> 3) << 10) static int literal_offset = 0; void codegen_reset_literal_pool(codeblock_t *block) @@ -75,6 +77,7 @@ static int offset_is_19bit(int offset) #define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) #define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) #define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) +#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) int add_literal(codeblock_t *block, uint32_t data) { @@ -201,6 +204,12 @@ void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int of fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } +void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_q(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +} void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { if (!in_range12_b(offset)) @@ -261,6 +270,20 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_mov_imm(block, uop->dest_reg_a_real, uop->imm_data); + + return 0; +} +static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + int offset = add_literal_q(block, (uintptr_t)uop->p); + host_arm64_LDR_LITERAL_X(block, uop->dest_reg_a_real, offset); + + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_W16, uop->imm_data); @@ -294,7 +317,34 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM }; +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); +} + +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); +} + +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); +} + #endif diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index a9253ab..f6fe556 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -42,3 +42,5 @@ #define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) + +#define CODEGEN_HOST_REGS 3 \ No newline at end of file diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 5152fe4..40d1409 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -269,6 +269,28 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, uop->dest_reg_a_real, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, uop->dest_reg_a_real, REG_LITERAL, offset); + } + + return 0; +} +static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + int offset = add_literal(block, (uintptr_t)uop->p); + host_arm_LDR_IMM(block, uop->dest_reg_a_real, REG_LITERAL, offset); + + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { uint32_t arm_imm; @@ -308,7 +330,34 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM }; +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +{ + if (in_range(p, &cpu_state)) + host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); +} + +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +{ + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); +} + +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +{ + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); +} + #endif diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index e123823..36b4567 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -13,6 +13,13 @@ #include #endif +int codegen_host_reg_list[CODEGEN_HOST_REGS] = +{ + REG_EAX, + REG_EBX, + REG_EDX +}; + static void *mem_abrt_rout; void codegen_backend_init() diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index f64636f..e5c231a 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -115,18 +115,95 @@ static void host_x86_JNZ(codeblock_t *block, void *p) codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); } -static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addlong(block, imm_data); -} static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addbyte(block, imm_data); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte(block, imm_data); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); + codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addbyte(block, imm_data); + } } +static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addlong(block, imm_data); + } +} + +static void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +static void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +static void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x48, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); + codegen_addbyte4(block, 0x48, 0x89, 0x04 | (src_reg << 3), 0x25); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} + + static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) { @@ -136,6 +213,15 @@ static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_dat codegen_addlong(block, imm_data); } +static void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV64_REG_IMM reg & 8\n"); + codegen_addbyte2(block, 0x48, 0xb8 | reg); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); +} + + static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { if (!offset) @@ -201,6 +287,17 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data); + return 0; +} +static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { if (((uintptr_t)uop->p) >> 32) @@ -226,7 +323,25 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM }; +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV8_ABS_REG(block, p, host_reg); +} + +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV32_ABS_REG(block, p, host_reg); +} + +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV64_ABS_REG(block, p, host_reg); +} + #endif diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 01a27b2..55430e0 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -13,6 +13,13 @@ #include #endif +int codegen_host_reg_list[CODEGEN_HOST_REGS] = +{ + REG_EAX, + REG_EBX, + REG_EDX +}; + static void *mem_abrt_rout; void codegen_backend_init() diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h index 36361ec..5face4e 100644 --- a/src/codegen_backend_x86.h +++ b/src/codegen_backend_x86.h @@ -1,3 +1,5 @@ +#include "codegen_backend_x86_defs.h" + #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff #define BLOCK_START 0 diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index dcb9a58..f28915e 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -1,3 +1,6 @@ +#ifndef _CODEGEN_BACKEND_X86_DEFS_H_ +#define _CODEGEN_BACKEND_X86_DEFS_H_ + #define REG_EAX 0 #define REG_ECX 1 #define REG_EDX 2 @@ -6,3 +9,7 @@ #define REG_EBP 5 #define REG_ESI 6 #define REG_EDI 7 + +#define CODEGEN_HOST_REGS 3 + +#endif diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 365382b..c19df3e 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -98,17 +98,81 @@ static void host_x86_JNZ(codeblock_t *block, void *p) codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); } -static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addlong(block, imm_data); -} static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addbyte(block, imm_data); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte(block, imm_data); + } + else + { + codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addbyte(block, imm_data); + } +} +static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addlong(block, imm_data); + } +} + +static void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} +static void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} + +static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (!imm_data) + { + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } + else + { + codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); + } } static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) @@ -138,11 +202,17 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_ho codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } +/*void codegen_debug() +{ + pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); +}*/ + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); +// host_x86_CALL(block, codegen_debug); return 0; } @@ -168,6 +238,17 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data); + return 0; +} +static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); @@ -189,7 +270,25 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8 + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM }; +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV8_ABS_REG(block, p, host_reg); +} + +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV32_ABS_REG(block, p, host_reg); +} + +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV32_ABS_REG(block, p, host_reg); +} + #endif diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 4f8e1b4..692b9b4 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -2,6 +2,7 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_ir.h" +#include "codegen_reg.h" static ir_data_t ir_block; @@ -25,10 +26,21 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) //pclog("uOP %i : %08x\n", c, uop->type); + if (uop->type & UOP_TYPE_PARAMS_REGS) + { + if (uop->dest_reg_a.reg != IREG_INVALID) + { + uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); + } + } + + if (uop->type & UOP_TYPE_BARRIER) + codegen_reg_flush(ir, block); + uop_handlers[uop->type & UOP_MASK](block, uop); } codegen_backend_epilogue(block); -// fatal("IR compilation complete\n"); + //fatal("IR compilation complete\n"); } diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 9293447..5bb310a 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -1,45 +1,10 @@ #ifndef _CODEGEN_IR_DEFS_ #define _CODEGEN_IR_DEFS_ -#define IREG_L (0 << 6) -#define IREG_W (1 << 6) -#define IREG_B (2 << 6) -#define IREG_BH (3 << 6) - -enum -{ - ireg_EAX = 0, - ireg_ECX = 1, - ireg_EDX = 2, - ireg_EBX = 3, - ireg_ESP = 4, - ireg_EBP = 5, - ireg_ESI = 6, - ireg_EDI = 7, - - ireg_flags_op = 8, - ireg_flags_reg = 9, - ireg_flags_op1 = 10, - ireg_flags_op2 = 11, - - ireg_flags_pc = 12, - ireg_flags_oldpc = 13, - - ireg_eaaddr = 14, - - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - ireg_temp0 = 16, - ireg_temp1 = 17, - ireg_temp2 = 18, - ireg_temp3 = 19 -}; +#include "codegen_reg.h" #define UOP_REG(reg, size, version) ((reg) | (size) | (version << 8)) -#define UOP_REG_UNUSED 0xffff - /*uOP is a barrier. All previous uOPs must have completed before this one executes. All registers must have been written back or discarded*/ #define UOP_TYPE_BARRIER (1 << 31) @@ -65,20 +30,23 @@ enum #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) #define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) #define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) +#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) +#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) -#define UOP_MAX 0x14 +#define UOP_MAX 0x22 #define UOP_MASK 0xffff typedef struct uop_t { uint32_t type; - uint16_t dest_reg_a; - uint16_t src_reg_a; - uint16_t src_reg_b; - uint16_t src_reg_c; + ir_reg_t dest_reg_a; + ir_reg_t src_reg_a; + ir_reg_t src_reg_b; + ir_reg_t src_reg_c; uint32_t imm_data; void *p; + ir_host_reg_t dest_reg_a_real; } uop_t; #define UOP_NR_MAX 4096 @@ -98,20 +66,38 @@ static inline uop_t *uop_alloc(ir_data_t *ir) uop = &ir->uops[ir->wr_pos++]; - uop->dest_reg_a = UOP_REG_UNUSED; - uop->src_reg_a = UOP_REG_UNUSED; - uop->src_reg_b = UOP_REG_UNUSED; - uop->src_reg_c = UOP_REG_UNUSED; + uop->dest_reg_a = invalid_ir_reg; + uop->src_reg_a = invalid_ir_reg; + uop->src_reg_b = invalid_ir_reg; + uop->src_reg_c = invalid_ir_reg; return uop; } -static inline void uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int arg, uint16_t src_reg_a) +static inline void uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) { uop_t *uop = uop_alloc(ir); uop->type = uop_type; - uop->src_reg_a = src_reg_a; + uop->src_reg_a = codegen_reg_read(src_reg_a); +} + +static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->imm_data = imm; +} + +static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->p = p; } static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) @@ -146,7 +132,14 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) +#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) + #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); + #endif diff --git a/src/codegen_reg.c b/src/codegen_reg.c new file mode 100644 index 0000000..f9e3e36 --- /dev/null +++ b/src/codegen_reg.c @@ -0,0 +1,139 @@ +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_ir_defs.h" +#include "codegen_reg.h" + +uint8_t reg_last_version[IREG_COUNT]; +uint8_t reg_version_refcount[IREG_COUNT][256]; + +ir_reg_t invalid_ir_reg = {IREG_INVALID}; + +ir_reg_t host_regs[CODEGEN_HOST_REGS]; + +enum +{ + REG_BYTE, + REG_WORD, + REG_DWORD, + REG_QWORD, + REG_POINTER +}; + +struct +{ + int native_size; + void *p; +} ireg_data[IREG_COUNT] = +{ + [IREG_EAX] = {REG_DWORD, &EAX}, + [IREG_ECX] = {REG_DWORD, &ECX}, + [IREG_EDX] = {REG_DWORD, &EDX}, + [IREG_EBX] = {REG_DWORD, &EBX}, + [IREG_ESP] = {REG_DWORD, &ESP}, + [IREG_EBP] = {REG_DWORD, &EBP}, + [IREG_ESI] = {REG_DWORD, &ESI}, + [IREG_EDI] = {REG_DWORD, &EDI}, + + [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op}, + [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res}, + [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1}, + [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2}, + + [IREG_pc] = {REG_DWORD, &cpu_state.pc}, + [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc}, + + [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr}, + [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg}, + + [IREG_op32] = {REG_DWORD, &cpu_state.op32}, + [IREG_ssegs] = {REG_BYTE, &cpu_state.ssegs}, + + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + [IREG_temp0] = {REG_DWORD, NULL}, + [IREG_temp1] = {REG_DWORD, NULL}, + [IREG_temp2] = {REG_DWORD, NULL}, + [IREG_temp3] = {REG_DWORD, NULL} +}; + +void codegen_reg_reset() +{ + int c; + + for (c = 0; c < IREG_COUNT; c++) + { + reg_last_version[c] = 0; + reg_version_refcount[c][0] = 0; + } + for (c = 0; c < CODEGEN_HOST_REGS; c++) + host_regs[c] = invalid_ir_reg; +} + +static inline int ir_reg_is_invalid(ir_reg_t ir_reg) +{ + return (ir_reg.reg == IREG_INVALID); +} + +static void codegen_reg_writeback(codeblock_t *block, int c) +{ + int ir_reg = host_regs[c].reg; + + switch (ireg_data[ir_reg].native_size) + { + case REG_BYTE: + codegen_direct_write_8(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]); + break; + + case REG_DWORD: + codegen_direct_write_32(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]); + break; + + case REG_POINTER: + codegen_direct_write_ptr(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]); + break; + + default: + fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); + } + + host_regs[c] = invalid_ir_reg; +} + +ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) +{ + int c; + + /*Search for unused registers*/ + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (ir_reg_is_invalid(host_regs[c])) + break; + } + + if (c == CODEGEN_HOST_REGS) + { + c = 0; + codegen_reg_writeback(block, c); +// fatal("codegen_reg_alloc_write_reg - out of registers\n"); + } + + host_regs[c].reg = ir_reg.reg; + host_regs[c].version = ir_reg.version; + + return codegen_host_reg_list[c]; +} + +void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) +{ + int c; + + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (!ir_reg_is_invalid(host_regs[c])) + { + codegen_reg_writeback(block, c); + } + } +} diff --git a/src/codegen_reg.h b/src/codegen_reg.h new file mode 100644 index 0000000..1b8bd06 --- /dev/null +++ b/src/codegen_reg.h @@ -0,0 +1,99 @@ +#ifndef _CODEGEN_REG_H_ +#define _CODEGEN_REG_H_ + +#define IREG_SIZE_L (0 << 6) +#define IREG_SIZE_W (1 << 6) +#define IREG_SIZE_B (2 << 6) +#define IREG_SIZE_BH (3 << 6) + +enum +{ + IREG_EAX = 0, + IREG_ECX = 1, + IREG_EDX = 2, + IREG_EBX = 3, + IREG_ESP = 4, + IREG_EBP = 5, + IREG_ESI = 6, + IREG_EDI = 7, + + IREG_flags_op = 8, + IREG_flags_res = 9, + IREG_flags_op1 = 10, + IREG_flags_op2 = 11, + + IREG_pc = 12, + IREG_oldpc = 13, + + IREG_eaaddr = 14, + IREG_ea_seg = 15, + IREG_op32 = 16, + IREG_ssegs = 17, + + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + IREG_temp0 = 20, + IREG_temp1 = 21, + IREG_temp2 = 22, + IREG_temp3 = 23, + + IREG_COUNT, + + IREG_INVALID = 255 +}; + +extern uint8_t reg_last_version[IREG_COUNT]; +extern uint8_t reg_version_refcount[IREG_COUNT][256]; + +typedef struct +{ + uint8_t reg; + uint8_t version; +} ir_reg_t; + +extern ir_reg_t invalid_ir_reg; + +typedef uint8_t ir_host_reg_t; + +static inline ir_reg_t codegen_reg_read(int reg) +{ + ir_reg_t ireg; + + if (reg == IREG_INVALID) + fatal("codegen_reg_read - IREG_INVALID\n"); + + ireg.reg = reg; + ireg.version = reg_last_version[reg]; + reg_version_refcount[ireg.reg][ireg.version]++; + if (!reg_version_refcount[ireg.reg][ireg.version]) + fatal("codegen_reg_read - refcount overflow\n"); + + return ireg; +} + +static inline ir_reg_t codegen_reg_write(int reg) +{ + ir_reg_t ireg; + + if (reg == IREG_INVALID) + fatal("codegen_reg_write - IREG_INVALID\n"); + + ireg.reg = reg; + ireg.version = reg_last_version[reg] + 1; + reg_last_version[reg]++; + if (!reg_last_version[reg]) + fatal("codegen_reg_write - version overflow\n"); + reg_version_refcount[reg][ireg.version] = 0; + + return ireg; +} + +struct ir_data_t; + +void codegen_reg_reset(); +void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block); + +ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); + +#endif From 94fea237b468b1fe1b4e51978d0b258b32092f64 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 28 Jun 2018 22:06:42 +0100 Subject: [PATCH 0473/1050] Implemented effective address compilation. --- src/386_dynarec_ops.c | 89 +---------- src/codegen.c | 245 +++++++++++++++++++++++++++++- src/codegen_backend_arm.c | 2 - src/codegen_backend_arm64_defs.h | 2 + src/codegen_backend_arm64_uops.c | 107 ++++++++++++- src/codegen_backend_arm_defs.h | 2 + src/codegen_backend_arm_uops.c | 122 +++++++++++++-- src/codegen_backend_x86-64_uops.c | 181 ++++++++++++++++++++-- src/codegen_backend_x86_uops.c | 137 ++++++++++++++++- src/codegen_ir.c | 17 ++- src/codegen_ir_defs.h | 59 ++++++- src/codegen_reg.c | 142 ++++++++++++++++- src/codegen_reg.h | 6 + 13 files changed, 978 insertions(+), 133 deletions(-) diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index 23c8036..5377a27 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -23,64 +23,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; ea_rseg = cpu_state.ea_seg->seg; - if (cpu_rm == 4) - { - uint8_t sib = rmdat >> 8; - - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - 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; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) - { - easeg = ss; - ea_rseg = SS; - cpu_state.ea_seg = &_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } - else - { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !cpu_state.ssegs) - { - easeg = ss; - ea_rseg = SS; - cpu_state.ea_seg = &_ss; - } - if (cpu_mod == 1) - { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } - else - { - cpu_state.eaaddr += getlong(); - } - } - else if (cpu_rm == 5) - { - cpu_state.eaaddr = getlong(); - } - } if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; @@ -96,33 +38,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat) eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; ea_rseg = cpu_state.ea_seg->seg; - if (!cpu_mod && cpu_rm == 6) - { - cpu_state.eaaddr = getword(); - } - else - { - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = 0; - break; - case 1: - cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; - break; - case 2: - cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) - { - easeg = ss; - ea_rseg = SS; - cpu_state.ea_seg = &_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; @@ -133,8 +48,8 @@ static inline void fetch_ea_16_long(uint32_t rmdat) } } -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 +#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) diff --git a/src/codegen.c b/src/codegen.c index 238f4f6..db29524 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -9,6 +9,8 @@ #include "codegen_backend.h" #include "codegen_ir.h" +int has_ea; + codeblock_t *codeblock; codeblock_t **codeblock_hash; @@ -38,8 +40,211 @@ void codegen_generate_reset() last_op_ssegs = -1; last_op_ea_seg = NULL; last_op_32 = -1; + has_ea = 0; } +static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ +// pclog("codegen - mod=%i rm=%i reg=%i fetchdat=%08x\n", cpu_mod, cpu_rm, cpu_reg, fetchdat); + if (!cpu_mod && cpu_rm == 6) + { + uint16_t addr = (fetchdat >> 8) & 0xffff; + uop_MOV_IMM(ir, IREG_eaaddr, addr); + (*op_pc) += 2; + } + else + { + int base_reg, index_reg, offset; + + switch (cpu_rm) + { + case 0: case 1: case 7: + base_reg = IREG_EBX; + break; + case 2: case 3: case 6: + base_reg = IREG_EBP; + break; + case 4: + base_reg = IREG_ESI; + break; + case 5: + base_reg = IREG_EDI; + break; + } + uop_MOV(ir, IREG_eaaddr, base_reg); + + if (!(cpu_rm & 4)) + { + if (!(cpu_rm & 1)) + index_reg = IREG_ESI; + else + index_reg = IREG_EDI; + + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); + } + + switch (cpu_mod) + { + case 1: + offset = (int)(int8_t)((fetchdat >> 8) & 0xff); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); + (*op_pc)++; + break; + case 2: + offset = (fetchdat >> 8) & 0xffff; + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); + (*op_pc) += 2; + break; + } + + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + + if (mod1seg[cpu_rm] == &ss && !op_ssegs) + { + op_ea_seg = &_ss; + } + } + + return op_ea_seg; +} + +static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + uint32_t new_eaaddr; + + if (cpu_rm == 4) + { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; + + switch (cpu_mod) + { + case 0: + if ((sib & 7) == 5) + { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + (*op_pc) += 4; + } + else + { + uop_MOV(ir, IREG_eaaddr, sib & 7); + } + break; + case 1: + new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + (*op_pc) += 4; + break; + } +// if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ +// { +// addbyte(0x05); +// addlong(stack_offset); +// } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &_ss; + if (((sib >> 3) & 7) != 4) + { + switch (sib >> 6) + { + case 0: + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); + break; + case 1: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); + break; + case 2: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); + break; + case 3: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); + break; + } + } + } + else + { + if (!cpu_mod && cpu_rm == 5) + { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + uop_MOV(ir, IREG_eaaddr, cpu_rm); + if (cpu_mod) + { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &_ss; + if (cpu_mod == 1) + { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); + (*op_pc)++; + } + else + { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); + (*op_pc) += 4; + } + } + } + return op_ea_seg; +} + +static uint8_t opcode_modrm[256] = +{ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 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, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*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*/ + + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ +}; +static uint8_t opcode_0f_modrm[256] = +{ + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 1, 1, 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*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + + 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, 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*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ +}; + 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]; @@ -52,6 +257,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t x86seg *op_ea_seg = &_ds; int op_ssegs = 0; int over = 0; + int test_modrm = 1; op_ea_seg = &_ds; @@ -127,14 +333,44 @@ generate_call: //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (!test_modrm || + (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || + (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) + { + //int stack_offset = 0; + +// if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ +// stack_offset = (op_32 & 0x100) ? 4 : 2; + + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; + + uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); + +// op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) + { + op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); +// has_ea = 1; + } + if (cpu_mod != 3 && (op_32 & 0x200)) + { + op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); +// has_ea = 1; + } +// op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); +// op_pc -= pc_off; + } + + uop_MOV_IMM(ir, IREG_pc, op_pc); uop_MOV_IMM(ir, IREG_oldpc, old_pc); if (op_32 != last_op_32) uop_MOV_IMM(ir, IREG_op32, op_32); -/*Lazy ea_seg/ssegs updating isn't safe until EA calculation is implemented*/ -// if (op_ea_seg != last_op_ea_seg) + if (op_ea_seg != last_op_ea_seg) uop_MOV_PTR(ir, IREG_ea_seg, (void *)op_ea_seg); -// if (op_ssegs != last_op_ssegs) + if (op_ssegs != last_op_ssegs) uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); uop_CALL_INSTRUCTION_FUNC(ir, op); @@ -150,4 +386,7 @@ generate_call: CPU_BLOCK_END(); codegen_endpc = (cs + cpu_state.pc) + 8; + +// if (has_ea) +// fatal("Has EA\n"); } diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index fa0b57c..41aeb71 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -20,8 +20,6 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_R4, REG_R5, REG_R6, -// REG_X22, -// REG_X23 }; void codegen_backend_init() diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index 56deb25..1c4de84 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -29,6 +29,7 @@ #define REG_W28 28 #define REG_W29 29 #define REG_W30 30 +#define REG_WZR 31 #define REG_X0 0 #define REG_X1 1 @@ -61,6 +62,7 @@ #define REG_X28 28 #define REG_X29 29 #define REG_X30 30 +#define REG_XZR 31 #define REG_SP 31 diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 2da9964..0845743 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -8,7 +8,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) { - *(uint32_t *)&block->data[block_pos] = val; + *(uint32_t *)&block->data[block_pos] = val; block_pos += 4; if (block_pos >= BLOCK_MAX) { @@ -21,6 +21,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define Rd(x) (x) #define Rn(x) ((x) << 5) #define Rt2(x) ((x) << 10) +#define Rm(x) ((x) << 16) + +#define shift_imm6(x) ((x) << 10) #define DATA_OFFSET_UP (1 << 23) #define DATA_OFFSET_DOWN (0 << 23) @@ -30,6 +33,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define COND_AL (0xe << COND_SHIFT) #define OPCODE_SHIFT 24 +#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) +#define OPCODE_AND_IMM (0x11 << OPCODE_SHIFT) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) @@ -37,20 +42,28 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_MOVK_W (0x0e5 << 23) #define OPCODE_MOVZ_W (0x0a5 << 23) +#define OPCODE_LDR_IMM_W (0x2e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) #define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22) #define OPCODE_STR_IMM_Q (0x3e4 << 22) #define OPCODE_STRB_IMM (0x0e4 << 22) +#define OPCODE_ADD_LSL (0x058 << 21) +#define OPCODE_AND_LSL (0x050 << 21) +#define OPCODE_ORR_LSL (0x150 << 21) + #define OPCODE_BLR (0xd63f0000) #define OPCODE_NOP (0xd503201f) #define OPCODE_RET (0xd65f0000) +#define DATPROC_SHIFT(sh) (sh << 10) +#define DATPROC_IMM_SHIFT(sh) (sh << 22) #define MOV_WIDE_HW(hw) (hw << 21) #define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) -#define IMM16(imm_data) (imm_data << 5) +#define IMM12(imm_data) ((imm_data) << 10) +#define IMM16(imm_data) ((imm_data) << 5) #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) @@ -112,7 +125,39 @@ static inline int imm_is_imm16(uint32_t imm_data) return 1; return 0; } +static inline int imm_is_imm12(uint32_t imm_data) +{ + if (!(imm_data & 0xfffff000) || !(imm_data & 0xff000fff)) + return 1; + return 0; +} +void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (!(imm_data & 0xff000000)) + { + if (imm_data & 0xfff) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else + { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); +} void host_arm64_BLR(codeblock_t *block, int addr_reg) { @@ -134,6 +179,13 @@ void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, in codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } +void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_w(offset)) + fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); +} + void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset) { int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; @@ -153,6 +205,11 @@ void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offs codegen_addlong(block, OPCODE_LDR_LITERAL_X | OFFSET19(offset) | Rt(dest_reg)); } +void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) { int hw; @@ -237,6 +294,30 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) } +static int codegen_ADD(codeblock_t *block, uop_t *uop) +{ + host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} + +static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +{ + host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; +} + +static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_arm64_call(block, uop->p); @@ -270,6 +351,12 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV(codeblock_t *block, uop_t *uop) +{ + host_arm64_MOV_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, 0); + + return 0; +} static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, uop->dest_reg_a_real, uop->imm_data); @@ -319,10 +406,24 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM }; +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); +} + void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index f6fe556..1fadfa1 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -23,6 +23,8 @@ #define REG_CPUSTATE REG_R10 #define REG_LITERAL REG_R11 +#define REG_TEMP REG_R3 + #define REG_MASK_R0 (1 << REG_R0) #define REG_MASK_R1 (1 << REG_R1) #define REG_MASK_R2 (1 << REG_R2) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 40d1409..a63e17a 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -30,6 +30,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SHIFT 20 #define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) +#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) +#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) +#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) #define OPCODE_B (0xa0 << OPCODE_SHIFT) #define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) #define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) @@ -45,6 +48,18 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define B_OFFSET(x) (((x) >> 2) & 0xffffff) +#define SHIFT_TYPE_SHIFT 5 +#define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) +#define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) +#define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) +#define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) + +#define SHIFT_TYPE_IMM (0 << 4) +#define SHIFT_TYPE_REG (1 << 4) + +#define SHIFT_IMM_SHIFT 7 +#define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) + static int literal_offset = 0; void codegen_reset_literal_pool(codeblock_t *block) { @@ -114,14 +129,49 @@ static inline int in_range(void *addr, void *base) return 1; } +void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { uint32_t arm_imm; - if (!get_arm_imm(imm, &arm_imm)) - fatal("host_arm_ADD_IMM !check_arm_imm %08x\n", imm); + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} - codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); +void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } void host_arm_BLX(codeblock_t *block, int addr_reg) @@ -153,15 +203,20 @@ void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) { uint32_t arm_imm; - if (!get_arm_imm(imm, &arm_imm)) - fatal("host_arm_MOV_IMM !check_arm_imm %08x\n", imm); - - codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, dst_reg, REG_LITERAL, offset); + } } -void host_arm_MOV_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) @@ -204,7 +259,31 @@ void host_arm_call(codeblock_t *block, void *dst_addr) void host_arm_nop(codeblock_t *block) { - host_arm_MOV_REG(block, REG_R0, REG_R0); + host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); +} + +static int codegen_ADD(codeblock_t *block, uop_t *uop) +{ + host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} + +static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +{ + host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; +} + +static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; } static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) @@ -269,6 +348,13 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, 0); + + return 0; +} + static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { uint32_t arm_imm; @@ -332,10 +418,24 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM }; +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +{ + if (in_range(p, &cpu_state)) + host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); +} + void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { if (in_range(p, &cpu_state)) diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index e5c231a..d0b3e00 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -87,6 +87,13 @@ static inline void codegen_addquad(codeblock_t *block, uint64_t val) } } +static int is_imm8(uint32_t imm_data) +{ + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; +} + static inline void call(codeblock_t *block, uintptr_t func) { uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; @@ -104,6 +111,62 @@ static inline void call(codeblock_t *block, uintptr_t func) } } +static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xe0 | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xe0 | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | (src_reg_b & 7)); /*ADD dst_reg, src_reg_b*/ +} + static void host_x86_CALL(codeblock_t *block, void *p) { call(block, (uintptr_t)p); @@ -115,13 +178,22 @@ static void host_x86_JNZ(codeblock_t *block, void *p) codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); } +static void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); + + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ + (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); +} + static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); if (offset >= -128 && offset < 127) { - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ codegen_addbyte(block, imm_data); } else @@ -139,7 +211,7 @@ static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_dat if (offset >= -128 && offset < 127) { - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ codegen_addlong(block, imm_data); } else @@ -156,16 +228,19 @@ static void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV8_ABS_REG - bad reg\n"); + if (offset >= -128 && offset < 127) { - codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ } else { if ((uintptr_t)p >> 32) fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); codegen_addlong(block, (uint32_t)(uintptr_t)p); } } @@ -173,16 +248,19 @@ static void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV32_ABS_REG - bad reg\n"); + if (offset >= -128 && offset < 127) { - codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ } else { if ((uintptr_t)p >> 32) fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); codegen_addlong(block, (uint32_t)(uintptr_t)p); } } @@ -190,26 +268,47 @@ static void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV64_ABS_REG - bad reg\n"); + if (offset >= -128 && offset < 127) { - codegen_addbyte4(block, 0x48, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ } else { if ((uintptr_t)p >> 32) fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); - codegen_addbyte4(block, 0x48, 0x89, 0x04 | (src_reg << 3), 0x25); /*MOV [p], src_reg*/ + codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ codegen_addlong(block, (uint32_t)(uintptr_t)p); } } +static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + if (dst_reg & 8) + fatal("host_x86_MOV32_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } + else + { + fatal("host_x86_MOV32_REG_ABS - out of range\n"); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) { if (reg & 8) fatal("host_x86_MOV32_REG_IMM reg & 8\n"); - codegen_addbyte(block, 0xb8 | reg); /*MOV reg, imm_data*/ + codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -217,10 +316,17 @@ static void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_dat { if (reg & 8) fatal("host_x86_MOV64_REG_IMM reg & 8\n"); - codegen_addbyte2(block, 0x48, 0xb8 | reg); /*MOVQ reg, imm_data*/ + codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ codegen_addquad(block, imm_data); } +static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV32_REG_REG - bad reg\n"); + + codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { @@ -244,9 +350,42 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) -static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) { - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_TEST32_REG - bad reg\n"); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ +} + + +static int codegen_ADD(codeblock_t *block, uop_t *uop) +{ + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} + +static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +{ + if (!uop->imm_data) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); + + return 0; +} + +static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; } static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) @@ -287,6 +426,11 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; +} static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data); @@ -325,10 +469,21 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM }; +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV32_REG_ABS(block, host_reg, p); +} + void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { host_x86_MOV8_ABS_REG(block, p, host_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c19df3e..b437185 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -86,6 +86,70 @@ static inline void codegen_addquad(codeblock_t *block, uint64_t val) CPU_BLOCK_END(); } } + +static int is_imm8(uint32_t imm_data) +{ + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; +} + +static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xe0 | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xe0 | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | src_reg_b); /*ADD dst_reg, src_reg_b*/ +} + static void host_x86_CALL(codeblock_t *block, void *p) { codegen_addbyte(block, 0xe8); /*CALL*/ @@ -98,6 +162,11 @@ static void host_x86_JNZ(codeblock_t *block, void *p) codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); } +static void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ +} + static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -162,6 +231,21 @@ static void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) } } +static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (!imm_data) @@ -175,6 +259,11 @@ static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm } } +static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); +} + static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { if (!offset) @@ -207,6 +296,36 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_ho pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); }*/ +static int codegen_ADD(codeblock_t *block, uop_t *uop) +{ + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} + +static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +{ + if (!uop->imm_data) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); + + return 0; +} + +static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -238,6 +357,11 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; +} static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data); @@ -272,10 +396,21 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM }; +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV32_REG_ABS(block, host_reg, p); +} + void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { host_x86_MOV8_ABS_REG(block, p, host_reg); diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 692b9b4..9099aea 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -4,12 +4,13 @@ #include "codegen_ir.h" #include "codegen_reg.h" +extern int has_ea; static ir_data_t ir_block; ir_data_t *codegen_ir_init() { ir_block.wr_pos = 0; - //pclog("codegen_ir_init\n"); +// pclog("codegen_ir_init %04x:%04x\n", CS,cpu_state.pc); return &ir_block; } @@ -24,10 +25,19 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) { uop_t *uop = &ir->uops[c]; - //pclog("uOP %i : %08x\n", c, uop->type); +// pclog("uOP %i : %08x\n", c, uop->type); if (uop->type & UOP_TYPE_PARAMS_REGS) { + codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b); + if (uop->src_reg_a.reg != IREG_INVALID) + { + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a); + } + if (uop->src_reg_b.reg != IREG_INVALID) + { + uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b); + } if (uop->dest_reg_a.reg != IREG_INVALID) { uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); @@ -42,5 +52,6 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) codegen_backend_epilogue(block); - //fatal("IR compilation complete\n"); +// if (has_ea) +// fatal("IR compilation complete\n"); } diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 5bb310a..d64e926 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -32,8 +32,13 @@ #define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) #define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) +#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) +#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) +#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) +#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) -#define UOP_MAX 0x22 +#define UOP_MAX 0x34 #define UOP_MASK 0xffff @@ -43,10 +48,10 @@ typedef struct uop_t ir_reg_t dest_reg_a; ir_reg_t src_reg_a; ir_reg_t src_reg_b; - ir_reg_t src_reg_c; uint32_t imm_data; void *p; ir_host_reg_t dest_reg_a_real; + ir_host_reg_t src_reg_a_real, src_reg_b_real; } uop_t; #define UOP_NR_MAX 4096 @@ -69,7 +74,7 @@ static inline uop_t *uop_alloc(ir_data_t *ir) uop->dest_reg_a = invalid_ir_reg; uop->src_reg_a = invalid_ir_reg; uop->src_reg_b = invalid_ir_reg; - uop->src_reg_c = invalid_ir_reg; +// uop->src_reg_c = invalid_ir_reg; return uop; } @@ -100,6 +105,46 @@ static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int uop->p = p; } +static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg); +} + +static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->dest_reg_a = codegen_reg_write(dest_reg); +} + +static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->imm_data = imm; +} + +static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->imm_data = imm; +} + static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { uop_t *uop = uop_alloc(ir); @@ -129,15 +174,23 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) +#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) + #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) #define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) #define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); + void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index f9e3e36..c2ca44d 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -10,6 +10,9 @@ uint8_t reg_version_refcount[IREG_COUNT][256]; ir_reg_t invalid_ir_reg = {IREG_INVALID}; ir_reg_t host_regs[CODEGEN_HOST_REGS]; +static uint8_t host_reg_dirty[CODEGEN_HOST_REGS]; + +static uint8_t host_regs_locked; enum { @@ -48,6 +51,8 @@ struct [IREG_op32] = {REG_DWORD, &cpu_state.op32}, [IREG_ssegs] = {REG_BYTE, &cpu_state.ssegs}, + + [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data}, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will @@ -76,6 +81,21 @@ static inline int ir_reg_is_invalid(ir_reg_t ir_reg) return (ir_reg.reg == IREG_INVALID); } +static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) +{ + switch (ireg_data[ir_reg.reg].native_size) + { + case REG_DWORD: + codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[ir_reg.reg].p); + break; + + default: + fatal("codegen_reg_load - native_size=%i\n", ireg_data[ir_reg.reg].native_size); + } + + host_regs[c] = ir_reg; +} + static void codegen_reg_writeback(codeblock_t *block, int c) { int ir_reg = host_regs[c].reg; @@ -101,27 +121,135 @@ static void codegen_reg_writeback(codeblock_t *block, int c) host_regs[c] = invalid_ir_reg; } +void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b) +{ + int c; + int dest_reference = 0; + + host_regs_locked = 0; + +/* pclog("alloc_register: dst=%i.%i src_a=%i.%i src_b=%i.%i\n", dest_reg_a.reg, dest_reg_a.version, + src_reg_a.reg, src_reg_a.version, + src_reg_b.reg, src_reg_b.version);*/ + + if (!ir_reg_is_invalid(dest_reg_a)) + { + if (!ir_reg_is_invalid(src_reg_a) && src_reg_a.reg == dest_reg_a.reg && src_reg_a.version == dest_reg_a.version-1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_b) && src_reg_b.reg == dest_reg_a.reg && src_reg_b.version == dest_reg_a.version-1) + dest_reference++; + } + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (!ir_reg_is_invalid(src_reg_a) && host_regs[c].reg == src_reg_a.reg) + { + if (host_regs[c].version != src_reg_a.version) + fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_a.version\n"); + host_regs_locked |= (1 << c); + } + if (!ir_reg_is_invalid(src_reg_b) && host_regs[c].reg == src_reg_b.reg) + { + if (host_regs[c].version != src_reg_b.version) + fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_b.version\n"); + host_regs_locked |= (1 << c); + } + if (!ir_reg_is_invalid(dest_reg_a) && host_regs[c].reg == dest_reg_a.reg) + { + if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[host_regs[c].reg][host_regs[c].version] == dest_reference)) + host_regs_locked |= (1 << c); + else + fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", host_regs[c].version, dest_reg_a.version, dest_reference); + } + } +} + +ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg) +{ + int c; + + /*Search for required register*/ + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg && host_regs[c].version == ir_reg.version) + break; + + if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg && reg_version_refcount[host_regs[c].reg][host_regs[c].version]) + fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); + } + + if (c == CODEGEN_HOST_REGS) + { + /*No unused registers. Search for an unlocked register*/ + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (!(host_regs_locked & (1 << c))) + break; + } + if (c == CODEGEN_HOST_REGS) + fatal("codegen_reg_alloc_read_reg - out of registers\n"); + if (host_reg_dirty[c]) + codegen_reg_writeback(block, c); + codegen_reg_load(block, c, ir_reg); + host_regs_locked |= (1 << c); +// fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); +// codegen_reg_writeback(block, c); + } + + reg_version_refcount[host_regs[c].reg][host_regs[c].version]--; + if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] < 0) + fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); + + host_reg_dirty[c] = 0; +// pclog(" codegen_reg_alloc_read_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); + return codegen_host_reg_list[c]; +} + ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { int c; - /*Search for unused registers*/ + /*Search for previous version in host register*/ for (c = 0; c < CODEGEN_HOST_REGS; c++) { - if (ir_reg_is_invalid(host_regs[c])) - break; + if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg) + { + if (host_regs[c].version == ir_reg.version-1) + { + if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); + break; + } + } } if (c == CODEGEN_HOST_REGS) { - c = 0; - codegen_reg_writeback(block, c); -// fatal("codegen_reg_alloc_write_reg - out of registers\n"); + /*Search for unused registers*/ + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (ir_reg_is_invalid(host_regs[c])) + break; + } + + if (c == CODEGEN_HOST_REGS) + { + /*No unused registers. Search for an unlocked register*/ + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (!(host_regs_locked & (1 << c))) + break; + } + if (c == CODEGEN_HOST_REGS) + fatal("codegen_reg_alloc_write_reg - out of registers\n"); + if (host_reg_dirty[c]) + codegen_reg_writeback(block, c); + } } host_regs[c].reg = ir_reg.reg; host_regs[c].version = ir_reg.version; - + host_reg_dirty[c] = 1; +// pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); return codegen_host_reg_list[c]; } diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 1b8bd06..d1d81a2 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -29,6 +29,8 @@ enum IREG_ea_seg = 15, IREG_op32 = 16, IREG_ssegs = 17, + + IREG_rm_mod_reg = 18, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will @@ -94,6 +96,10 @@ struct ir_data_t; void codegen_reg_reset(); void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block); +/*Register ir_reg usage for this uOP. This ensures that required registers aren't evicted*/ +void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b); + +ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); #endif From 93ec6b06927645d2c0a26212f3581b2e6dddf2a0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:50:32 +0100 Subject: [PATCH 0474/1050] Recompiler now handles FPU prefixes. --- src/codegen.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index db29524..eb7bd78 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -258,6 +258,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t int op_ssegs = 0; int over = 0; int test_modrm = 1; + int pc_off = 0; + + op_ea_seg = &_ds; op_ea_seg = &_ds; @@ -303,6 +306,81 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); break; + case 0xd8: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; +// recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; +// recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; +// recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; +// recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; +// recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; +// recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; +// recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; +// recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xf0: /*LOCK*/ break; @@ -323,7 +401,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t if (cpu_state.abrt) return; opcode = fetchdat & 0xff; -// if (!pc_off) + if (!pc_off) fetchdat >>= 8; op_pc++; @@ -348,7 +426,7 @@ generate_call: uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); -// op_pc += pc_off; + op_pc += pc_off; if (cpu_mod != 3 && !(op_32 & 0x200)) { op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); @@ -360,11 +438,11 @@ generate_call: // has_ea = 1; } // op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); -// op_pc -= pc_off; + op_pc -= pc_off; } - uop_MOV_IMM(ir, IREG_pc, op_pc); + uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); uop_MOV_IMM(ir, IREG_oldpc, old_pc); if (op_32 != last_op_32) uop_MOV_IMM(ir, IREG_op32, op_32); From 774f4201ee9239670577e2aaf78982fbbeb0a46c Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:51:22 +0100 Subject: [PATCH 0475/1050] Recompiler now handles instruction and cycle counting. --- src/386_dynarec_ops.c | 2 +- src/codegen.c | 18 +++++++++++++-- src/codegen_accumulate.c | 50 ++++++++++++++++++++++++++++++++++++++++ src/codegen_accumulate.h | 13 +++++++++++ src/codegen_backend.c | 3 +++ src/codegen_ir.c | 2 ++ src/codegen_reg.c | 7 ++++++ src/codegen_reg.h | 11 +++++---- 8 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 src/codegen_accumulate.c create mode 100644 src/codegen_accumulate.h diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index 5377a27..342e138 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -58,7 +58,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) #define OP_TABLE(name) dynarec_ops_ ## name /*Temporary*/ -#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES(c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #include "386_ops.h" diff --git a/src/codegen.c b/src/codegen.c index eb7bd78..87184da 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -6,6 +6,7 @@ #include "386_common.h" +#include "codegen_accumulate.h" #include "codegen_backend.h" #include "codegen_ir.h" @@ -262,7 +263,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t op_ea_seg = &_ds; - op_ea_seg = &_ds; + codegen_timing_start(); while (!over) { @@ -397,7 +398,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t goto generate_call; } fetchdat = fastreadl(cs + op_pc); -// codegen_timing_prefix(opcode, fetchdat); + codegen_timing_prefix(opcode, fetchdat); if (cpu_state.abrt) return; opcode = fetchdat & 0xff; @@ -408,6 +409,19 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t } generate_call: + codegen_timing_opcode(opcode, fetchdat, op_32); + + codegen_accumulate(ACCREG_ins, 1); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; + + if ((op_table == x86_dynarec_opcodes && + ((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))) + codegen_accumulate_flush(ir); + //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; diff --git a/src/codegen_accumulate.c b/src/codegen_accumulate.c new file mode 100644 index 0000000..968b7a5 --- /dev/null +++ b/src/codegen_accumulate.c @@ -0,0 +1,50 @@ +#include "ibm.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" + +static struct +{ + int count; + int dest_reg; +} acc_regs[] = +{ + [ACCREG_ins] = {0, IREG_ins}, + [ACCREG_cycles] = {0, IREG_cycles}, +}; + +void codegen_accumulate(int acc_reg, int delta) +{ + if (acc_reg == ACCREG_cycles) + { +// pclog("cycles %04x:%04x %i\n", CS, cpu_state.pc, delta); +// if (CS == 0x1000 && cpu_state.pc == 0x863) +// fatal("Here\n"); + } + acc_regs[acc_reg].count += delta; +} + +void codegen_accumulate_flush(ir_data_t *ir) +{ + int c; + + for (c = 0; c < ACCREG_COUNT; c++) + { + if (acc_regs[c].count) + { +// if (c == ACCREG_cycles) +// pclog("accumulate %i %i %i\n", c, acc_regs[c].dest_reg, acc_regs[c].count); + uop_ADD_IMM(ir, acc_regs[c].dest_reg, acc_regs[c].dest_reg, acc_regs[c].count); + } + + acc_regs[c].count = 0; + } +} + +void codegen_accumulate_reset() +{ + int c; + + for (c = 0; c < ACCREG_COUNT; c++) + acc_regs[c].count = 0; +} diff --git a/src/codegen_accumulate.h b/src/codegen_accumulate.h new file mode 100644 index 0000000..6c19499 --- /dev/null +++ b/src/codegen_accumulate.h @@ -0,0 +1,13 @@ +enum +{ + ACCREG_ins = 0, + ACCREG_cycles = 1, + + ACCREG_COUNT +}; + +struct ir_data_t; + +void codegen_accumulate(int acc_reg, int delta); +void codegen_accumulate_flush(struct ir_data_t *ir); +void codegen_accumulate_reset(); diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 2754f5e..afc6716 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -10,6 +10,7 @@ #include "386_common.h" #include "codegen.h" +#include "codegen_accumulate.h" #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_reg.h" @@ -310,6 +311,7 @@ void codegen_block_start_recompile(codeblock_t *block) ir_data = codegen_ir_init(); codegen_reg_reset(); + codegen_accumulate_reset(); codegen_generate_reset(); } @@ -410,6 +412,7 @@ void codegen_block_end_recompile(codeblock_t *block) if (!(block->flags & CODEBLOCK_HAS_FPU)) block->flags &= ~CODEBLOCK_STATIC_TOP; + codegen_accumulate_flush(ir_data); codegen_ir_compile(ir_data, block); } diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 9099aea..36bea69 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -50,6 +50,8 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) uop_handlers[uop->type & UOP_MASK](block, uop); } + codegen_reg_flush(ir, block); + codegen_backend_epilogue(block); // if (has_ea) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index c2ca44d..e8e1410 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -54,6 +54,9 @@ struct [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data}, + [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins}, + [IREG_cycles] = {REG_DWORD, &cpu_state._cycles}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ @@ -73,7 +76,10 @@ void codegen_reg_reset() reg_version_refcount[c][0] = 0; } for (c = 0; c < CODEGEN_HOST_REGS; c++) + { host_regs[c] = invalid_ir_reg; + host_reg_dirty[c] = 0; + } } static inline int ir_reg_is_invalid(ir_reg_t ir_reg) @@ -119,6 +125,7 @@ static void codegen_reg_writeback(codeblock_t *block, int c) } host_regs[c] = invalid_ir_reg; + host_reg_dirty[c] = 0; } void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b) diff --git a/src/codegen_reg.h b/src/codegen_reg.h index d1d81a2..e854fe1 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -31,14 +31,17 @@ enum IREG_ssegs = 17, IREG_rm_mod_reg = 18, + + IREG_ins = 19, + IREG_cycles = 20, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - IREG_temp0 = 20, - IREG_temp1 = 21, - IREG_temp2 = 22, - IREG_temp3 = 23, + IREG_temp0 = 21, + IREG_temp1 = 22, + IREG_temp2 = 23, + IREG_temp3 = 24, IREG_COUNT, From dc2afee95757a3f4d658d122a8d717fb0e29c1f4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:52:33 +0100 Subject: [PATCH 0476/1050] ARM UOP_ADD_IMM can now generate SUB instructions to better handle negative data. --- src/codegen_backend_arm_uops.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index a63e17a..a4611d0 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -42,6 +42,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) #define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) #define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) +#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) #define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) #define OPCODE_BLX 0xe12fff30 @@ -131,12 +132,17 @@ static inline int in_range(void *addr, void *base) void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) + if ((int32_t)imm < 0) + { + host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); + } + else if (get_arm_imm(imm, &arm_imm)) { codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); } @@ -238,10 +244,25 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm { uint32_t arm_imm; - if (!get_arm_imm(imm, &arm_imm)) - fatal("host_arm_SUB_IMM !check_arm_imm %08x\n", imm); + if ((int32_t)imm < 0) + { + host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); + } + else if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} - codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); +void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) From d666c0aeb964bd4b42a9ee02d115b152ec9ca8a8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:53:11 +0100 Subject: [PATCH 0477/1050] ARM64 UOP_ADD_IMM can now generate SUB instructions to better handle negative data. --- src/codegen_backend_arm64_uops.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 0845743..ea70050 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -38,6 +38,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) +#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_MOVK_W (0x0e5 << 23) #define OPCODE_MOVZ_W (0x0a5 << 23) @@ -52,6 +53,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ADD_LSL (0x058 << 21) #define OPCODE_AND_LSL (0x050 << 21) #define OPCODE_ORR_LSL (0x150 << 21) +#define OPCODE_SUB_LSL (0x258 << 21) #define OPCODE_BLR (0xd63f0000) #define OPCODE_NOP (0xd503201f) @@ -132,9 +134,15 @@ static inline int imm_is_imm12(uint32_t imm_data) return 0; } +void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); + void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (!(imm_data & 0xff000000)) + if ((int32_t)imm_data < 0) + { + host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); + } + else if (!(imm_data & 0xff000000)) { if (imm_data & 0xfff) codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); @@ -274,6 +282,26 @@ void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int off codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } +void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if ((int32_t)imm_data < 0) + { + host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); + } + else if (!(imm_data & 0xff000000)) + { + if (imm_data & 0xfff) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else + { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} void host_arm64_call(codeblock_t *block, void *dst_addr) { From ced37ac545cc36ccbc5e5886fbb92ac0697cdafa Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:53:58 +0100 Subject: [PATCH 0478/1050] Hacked in quick ARM64 UOP_AND_IMM handling of immediate 0xffff. --- src/codegen_backend_arm64_uops.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index ea70050..f52b465 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -34,12 +34,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SHIFT 24 #define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) -#define OPCODE_AND_IMM (0x11 << OPCODE_SHIFT) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) #define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) +#define OPCODE_AND_IMM (0x024 << 23) #define OPCODE_MOVK_W (0x0e5 << 23) #define OPCODE_MOVZ_W (0x0a5 << 23) @@ -67,6 +67,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define IMM12(imm_data) ((imm_data) << 10) #define IMM16(imm_data) ((imm_data) << 5) +#define IMMN(immn) ((immn) << 22) +#define IMMR(immr) ((immr) << 16) +#define IMMS(imms) ((imms) << 10) + #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) #define OFFSET12_B(offset) (offset << 10) @@ -163,8 +167,15 @@ void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } void host_arm64_BLR(codeblock_t *block, int addr_reg) From 67804322b6d97d9d9fe8ee94b584d8086e4d0d24 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:54:17 +0100 Subject: [PATCH 0479/1050] Add codegen_accumulate.c to Makefile.am. --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index c672b74..e0b6458 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_backend.c codegen_ir.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ From fc27be592cbf548168853b37ffc08c159ed72f8c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Jul 2018 16:36:11 +0100 Subject: [PATCH 0480/1050] Added recompiled versions of immediate->reg and reg->reg versions of MOV, ADD, SUB, CMP, AND, OR and XOR. --- src/Makefile.am | 2 +- src/codegen.c | 39 ++-- src/codegen_backend_arm64_uops.c | 116 +++++++++++- src/codegen_backend_arm_uops.c | 107 ++++++++++- src/codegen_backend_x86-64_uops.c | 175 +++++++++++++++++- src/codegen_backend_x86_uops.c | 218 ++++++++++++++++++++--- src/codegen_ir_defs.h | 25 ++- src/codegen_ops.c | 54 ++++++ src/codegen_ops.h | 10 +- src/codegen_ops_arith.c | 285 ++++++++++++++++++++++++++++++ src/codegen_ops_arith.h | 14 ++ src/codegen_ops_logic.c | 129 ++++++++++++++ src/codegen_ops_logic.h | 11 ++ src/codegen_ops_mov.c | 48 +++++ src/codegen_ops_mov.h | 3 + src/codegen_reg.c | 2 +- src/codegen_reg.h | 2 + 17 files changed, 1169 insertions(+), 71 deletions(-) create mode 100644 src/codegen_ops.c create mode 100644 src/codegen_ops_arith.c create mode 100644 src/codegen_ops_arith.h create mode 100644 src/codegen_ops_logic.c create mode 100644 src/codegen_ops_logic.h create mode 100644 src/codegen_ops_mov.c create mode 100644 src/codegen_ops_mov.h diff --git a/src/Makefile.am b/src/Makefile.am index e0b6458..ab44ff7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_arith.c codegen_ops_logic.c codegen_ops_mov.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ diff --git a/src/codegen.c b/src/codegen.c index 87184da..2255d85 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -9,6 +9,7 @@ #include "codegen_accumulate.h" #include "codegen_backend.h" #include "codegen_ir.h" +#include "codegen_ops.h" int has_ea; @@ -252,6 +253,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t ir_data_t *ir = codegen_get_ir_data(); uint32_t op_pc = new_pc; OpFn *op_table = x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; int opcode_shift = 0; int opcode_mask = 0x3ff; uint32_t op_32 = use32; @@ -271,7 +273,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t { case 0x0f: op_table = x86_dynarec_opcodes_0f; -// recomp_op_table = recomp_opcodes_0f; + recomp_op_table = NULL;//recomp_opcodes_0f; over = 1; break; @@ -309,7 +311,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xd8: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; -// recomp_op_table = recomp_opcodes_d8; + recomp_op_table = NULL;//recomp_opcodes_d8; opcode_shift = 3; opcode_mask = 0x1f; over = 1; @@ -319,7 +321,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xd9: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; -// recomp_op_table = recomp_opcodes_d9; + recomp_op_table = NULL;//recomp_opcodes_d9; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -328,7 +330,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xda: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; -// recomp_op_table = recomp_opcodes_da; + recomp_op_table = NULL;//recomp_opcodes_da; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -337,7 +339,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdb: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; -// recomp_op_table = recomp_opcodes_db; + recomp_op_table = NULL;//recomp_opcodes_db; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -346,7 +348,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdc: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; -// recomp_op_table = recomp_opcodes_dc; + recomp_op_table = NULL;//recomp_opcodes_dc; opcode_shift = 3; opcode_mask = 0x1f; over = 1; @@ -356,7 +358,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdd: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; -// recomp_op_table = recomp_opcodes_dd; + recomp_op_table = NULL;//recomp_opcodes_dd; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -365,7 +367,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xde: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; -// recomp_op_table = recomp_opcodes_de; + recomp_op_table = NULL;//recomp_opcodes_de; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -374,7 +376,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdf: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; -// recomp_op_table = recomp_opcodes_df; + recomp_op_table = NULL;//recomp_opcodes_df; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -387,11 +389,11 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xf2: /*REPNE*/ op_table = x86_dynarec_opcodes_REPNE; -// recomp_op_table = recomp_opcodes_REPNE; + recomp_op_table = NULL;//recomp_opcodes_REPNE; break; case 0xf3: /*REPE*/ op_table = x86_dynarec_opcodes_REPE; -// recomp_op_table = recomp_opcodes_REPE; + recomp_op_table = NULL;//recomp_opcodes_REPE; break; default: @@ -421,8 +423,21 @@ generate_call: (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) codegen_accumulate_flush(ir); +// pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) + { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](block, ir, opcode, fetchdat, op_32, op_pc); + if (new_pc) + { + if (new_pc != -1) + uop_MOV_IMM(ir, IREG_pc, new_pc); - //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + codegen_endpc = (cs + cpu_state.pc) + 8; + + return; + } + } + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; if (!test_modrm || diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index f52b465..e838e4f 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -40,8 +40,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_AND_IMM (0x024 << 23) +#define OPCODE_EOR_IMM (0x0a4 << 23) #define OPCODE_MOVK_W (0x0e5 << 23) #define OPCODE_MOVZ_W (0x0a5 << 23) +#define OPCODE_ORR_IMM (0x064 << 23) #define OPCODE_LDR_IMM_W (0x2e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) @@ -52,6 +54,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ADD_LSL (0x058 << 21) #define OPCODE_AND_LSL (0x050 << 21) +#define OPCODE_EOR_LSL (0x250 << 21) #define OPCODE_ORR_LSL (0x150 << 21) #define OPCODE_SUB_LSL (0x258 << 21) @@ -138,19 +141,26 @@ static inline int imm_is_imm12(uint32_t imm_data) return 0; } +void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0) + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) { host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); } else if (!(imm_data & 0xff000000)) { if (imm_data & 0xfff) + { codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); } else @@ -177,6 +187,10 @@ void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); } } +void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_BLR(codeblock_t *block, int addr_reg) { @@ -191,6 +205,23 @@ void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); } +void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) @@ -226,7 +257,8 @@ void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offs void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) @@ -262,6 +294,23 @@ void host_arm64_NOP(codeblock_t *block) codegen_addlong(block, OPCODE_NOP); } +void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_RET(codeblock_t *block, int reg) { codegen_addlong(block, OPCODE_RET | Rn(reg)); @@ -295,15 +344,21 @@ void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int off void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0) + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) { host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); } else if (!(imm_data & 0xff000000)) { if (imm_data & 0xfff) + { codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); } else @@ -313,6 +368,10 @@ void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); } } +void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_call(codeblock_t *block, void *dst_addr) { @@ -351,6 +410,11 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_arm64_AND_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_arm64_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -410,6 +474,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_arm64_ORR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_W16, uop->imm_data); @@ -433,6 +508,28 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + host_arm64_SUB_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_arm64_EOR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -452,7 +549,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index a4611d0..8215caa 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -34,10 +34,16 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) #define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) #define OPCODE_B (0xa0 << OPCODE_SHIFT) +#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) +#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) +#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) +#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) #define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) #define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) #define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) +#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) #define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) #define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) #define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) @@ -132,13 +138,15 @@ static inline int in_range(void *addr, void *base) void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { uint32_t arm_imm; - if ((int32_t)imm < 0) + if ((int32_t)imm < 0 && imm != 0x80000000) { host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); } @@ -167,6 +175,10 @@ void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm { codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); } + else if (get_arm_imm(~imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { int offset = add_literal(block, imm); @@ -195,6 +207,27 @@ void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); } +void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); @@ -225,6 +258,27 @@ void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } +void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_ORR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); @@ -244,7 +298,7 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm { uint32_t arm_imm; - if ((int32_t)imm < 0) + if ((int32_t)imm < 0 && imm != 0x80000000) { host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); } @@ -288,19 +342,22 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); return 0; } - static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); return 0; } - static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_arm_AND_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_arm_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -398,6 +455,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_arm_ORR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { uint32_t arm_imm; @@ -427,6 +495,28 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_arm_EOR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -446,7 +536,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d0b3e00..4e0d50c 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -11,6 +11,12 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) +#define RM_OP_ADD 0x00 +#define RM_OP_OR 0x08 +#define RM_OP_AND 0x20 +#define RM_OP_SUB 0x28 +#define RM_OP_XOR 0x30 + static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { block->data[block_pos++] = val; @@ -118,7 +124,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, if (is_imm8(imm_data)) { - codegen_addbyte3(block, 0x83, 0xc0 | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ } else { @@ -129,11 +135,18 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, } else { - codegen_addbyte2(block, 0x81, 0xc0 | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ codegen_addlong(block, imm_data); } } } +static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { @@ -142,7 +155,7 @@ static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, if (is_imm8(imm_data)) { - codegen_addbyte3(block, 0x83, 0xe0 | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ } else { @@ -153,18 +166,17 @@ static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, } else { - codegen_addbyte2(block, 0x81, 0xe0 | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ codegen_addlong(block, imm_data); } } } - -static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg_a\n"); - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | (src_reg_b & 7)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } static void host_x86_CALL(codeblock_t *block, void *p) @@ -348,6 +360,68 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ } } +static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} +static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} + +static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} +static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} + #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) @@ -357,6 +431,37 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ } +static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} +static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} + static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -382,6 +487,12 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} + static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -442,6 +553,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { if (((uintptr_t)uop->p) >> 32) @@ -457,6 +579,34 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -476,7 +626,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index b437185..9dac085 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -11,6 +11,12 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) +#define RM_OP_ADD 0x00 +#define RM_OP_OR 0x08 +#define RM_OP_AND 0x20 +#define RM_OP_SUB 0x28 +#define RM_OP_XOR 0x30 + static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { block->data[block_pos++] = val; @@ -101,7 +107,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, if (is_imm8(imm_data)) { - codegen_addbyte3(block, 0x83, 0xc0 | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ } else { @@ -112,31 +118,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, } else { - codegen_addbyte2(block, 0x81, 0xc0 | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } - } -} - -static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - { - codegen_addbyte3(block, 0x83, 0xe0 | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else - { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xe0 | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ codegen_addlong(block, imm_data); } } @@ -147,7 +129,39 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_ if (dst_reg != src_reg_a) fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | src_reg_b); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} + +static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ } static void host_x86_CALL(codeblock_t *block, void *p) @@ -284,13 +298,109 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ } } +static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} +static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} + static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } +static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} + +static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + + /*void codegen_debug() { pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); @@ -320,6 +430,12 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} + static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -373,6 +489,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); @@ -384,6 +511,34 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -403,7 +558,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index d64e926..bac0ab6 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -35,10 +35,17 @@ #define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) #define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) -#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) -#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) +#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) +#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) +#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) +#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) +#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) -#define UOP_MAX 0x34 +#define UOP_MAX 0x3b #define UOP_MASK 0xffff @@ -175,9 +182,16 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) #define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) #define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) @@ -189,6 +203,7 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) + void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); diff --git a/src/codegen_ops.c b/src/codegen_ops.c new file mode 100644 index 0000000..728c659 --- /dev/null +++ b/src/codegen_ops.c @@ -0,0 +1,54 @@ +#include "ibm.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_arith.h" +#include "codegen_ops_logic.h" +#include "codegen_ops_mov.h" + +RecompOpFn recomp_opcodes[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, ropADD_l_rmw, NULL, ropADD_l_rm, NULL, ropADD_EAX_imm, NULL, NULL, NULL, ropOR_l_rmw, NULL, ropOR_l_rm, NULL, ropOR_EAX_imm, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, ropAND_l_rmw, NULL, ropAND_l_rm, NULL, ropAND_EAX_imm, NULL, NULL, NULL, ropSUB_l_rmw, NULL, ropSUB_l_rm, NULL, ropSUB_EAX_imm, NULL, NULL, +/*30*/ NULL, ropXOR_l_rmw, NULL, ropXOR_l_rm, NULL, ropXOR_EAX_imm, NULL, NULL, NULL, ropCMP_l_rmw, NULL, ropCMP_l_rm, NULL, ropCMP_EAX_imm, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, rop81_l, NULL, rop83_l, NULL, NULL, NULL, NULL, NULL, ropMOV_l_r, NULL, ropMOV_r_l, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 7060238..1229ce4 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -3,10 +3,12 @@ #include "codegen.h" -typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block); +struct ir_data_t; + +typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); extern RecompOpFn recomp_opcodes[512]; -extern RecompOpFn recomp_opcodes_0f[512]; +/*extern RecompOpFn recomp_opcodes_0f[512]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; @@ -15,8 +17,8 @@ extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; extern RecompOpFn recomp_opcodes_df[512]; -RecompOpFn recomp_opcodes_REPE[512]; -RecompOpFn recomp_opcodes_REPNE[512]; +extern RecompOpFn recomp_opcodes_REPE[512]; +extern RecompOpFn recomp_opcodes_REPNE[512];*/ #define REG_EAX 0 #define REG_ECX 1 diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c new file mode 100644 index 0000000..d516152 --- /dev/null +++ b/src/codegen_ops_arith.c @@ -0,0 +1,285 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_arith.h" + +uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint32_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = fastreadl(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = fastreadl(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = fastreadl(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = fastreadl(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = fastreadl(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = fastreadl(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 5; +} +uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint32_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 2; +} diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h new file mode 100644 index 0000000..f219318 --- /dev/null +++ b/src/codegen_ops_arith.h @@ -0,0 +1,14 @@ +uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c new file mode 100644 index 0000000..c4aca26 --- /dev/null +++ b/src/codegen_ops_logic.c @@ -0,0 +1,129 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_logic.h" + +uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h new file mode 100644 index 0000000..127f4c1 --- /dev/null +++ b/src/codegen_ops_logic.h @@ -0,0 +1,11 @@ +uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c new file mode 100644 index 0000000..2266602 --- /dev/null +++ b/src/codegen_ops_mov.c @@ -0,0 +1,48 @@ +#include "ibm.h" + +#include "x86.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mov.h" + +uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); + + return op_pc + 4; +} + + + +uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = (fetchdat >> 3) & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + return 0; + + return op_pc + 1; +} +uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + return 0; + + return op_pc + 1; +} diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h new file mode 100644 index 0000000..c9bafdc --- /dev/null +++ b/src/codegen_ops_mov.h @@ -0,0 +1,3 @@ +uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index e8e1410..164a190 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -200,13 +200,13 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg) host_regs_locked |= (1 << c); // fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); // codegen_reg_writeback(block, c); + host_reg_dirty[c] = 0; } reg_version_refcount[host_regs[c].reg][host_regs[c].version]--; if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] < 0) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); - host_reg_dirty[c] = 0; // pclog(" codegen_reg_alloc_read_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); return codegen_host_reg_list[c]; } diff --git a/src/codegen_reg.h b/src/codegen_reg.h index e854fe1..e1b4965 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -48,6 +48,8 @@ enum IREG_INVALID = 255 }; +#define IREG_32(reg) ((reg) + IREG_EAX) + extern uint8_t reg_last_version[IREG_COUNT]; extern uint8_t reg_version_refcount[IREG_COUNT][256]; From e4e0f76d5c545faff67f2c51aa899989133f3512 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Jul 2018 16:36:26 +0100 Subject: [PATCH 0481/1050] De-duplicate ARM literal pools. --- src/codegen_backend_arm_uops.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 8215caa..372044b 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -75,9 +75,18 @@ void codegen_reset_literal_pool(codeblock_t *block) int add_literal(codeblock_t *block, uint32_t data) { + int c; + if (literal_offset >= 4096) fatal("add_literal - literal pool full\n"); + /*Search for pre-existing value*/ + for (c = 0; c < literal_offset; c += 4) + { + if (*(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + c] == data) + return c; + } + *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; literal_offset += 4; From 648aa0e3e83d2b2f081d13a61b4d4aefd5473369 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 17 Jul 2018 22:08:25 +0100 Subject: [PATCH 0482/1050] Added recompiled versions of 8 and 16 bit immediate->reg and reg->reg versions of MOV, ADD, SUB, CMP, AND, OR and XOR. --- src/codegen.c | 2 +- src/codegen_backend_arm64_defs.h | 2 + src/codegen_backend_arm64_uops.c | 483 +++++++++++++++++++++++- src/codegen_backend_arm_uops.c | 514 ++++++++++++++++++++++++- src/codegen_backend_x86-64_uops.c | 605 ++++++++++++++++++++++++++---- src/codegen_backend_x86_uops.c | 604 +++++++++++++++++++++++++---- src/codegen_ir.c | 4 +- src/codegen_ir_defs.h | 36 +- src/codegen_ops.c | 20 +- src/codegen_ops_arith.c | 484 ++++++++++++++++++++++++ src/codegen_ops_arith.h | 21 ++ src/codegen_ops_logic.c | 234 ++++++++++++ src/codegen_ops_logic.h | 18 + src/codegen_ops_mov.c | 72 ++++ src/codegen_ops_mov.h | 6 + src/codegen_reg.c | 70 ++-- src/codegen_reg.h | 62 ++- 17 files changed, 3006 insertions(+), 231 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 2255d85..512b4b3 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -58,7 +58,7 @@ static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uin { int base_reg, index_reg, offset; - switch (cpu_rm) + switch (cpu_rm & 7) { case 0: case 1: case 7: base_reg = IREG_EBX; diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index 1c4de84..7de61f0 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -73,4 +73,6 @@ #define REG_CPUSTATE REG_X29 +#define REG_TEMP REG_X7 + #define CODEGEN_HOST_REGS 5 \ No newline at end of file diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index e838e4f..b641a4b 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -45,18 +45,25 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_MOVZ_W (0x0a5 << 23) #define OPCODE_ORR_IMM (0x064 << 23) +#define OPCODE_BFI (0x0cc << 22) #define OPCODE_LDR_IMM_W (0x2e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) #define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22) #define OPCODE_STR_IMM_Q (0x3e4 << 22) #define OPCODE_STRB_IMM (0x0e4 << 22) +#define OPCODE_UBFX (0x14c << 22) #define OPCODE_ADD_LSL (0x058 << 21) +#define OPCODE_ADD_LSR (0x05a << 21) +#define OPCODE_AND_ASR (0x054 << 21) #define OPCODE_AND_LSL (0x050 << 21) +#define OPCODE_AND_ROR (0x056 << 21) #define OPCODE_EOR_LSL (0x250 << 21) #define OPCODE_ORR_LSL (0x150 << 21) +#define OPCODE_ORR_LSR (0x152 << 21) #define OPCODE_SUB_LSL (0x258 << 21) +#define OPCODE_SUB_LSR (0x25a << 21) #define OPCODE_BLR (0xd63f0000) #define OPCODE_NOP (0xd503201f) @@ -174,13 +181,33 @@ void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } - +void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +//12001c00 S=0 R=7 void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07)); + } + else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ { codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); } + else if (imm_data == 0xffffff00) + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); + } + else if (imm_data == 0xffff00ff) + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); + } + else if (imm_data == 0x0000ff00) + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07)); + } else { host_arm64_mov_imm(block, REG_W16, imm_data); @@ -191,6 +218,19 @@ void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); +} void host_arm64_BLR(codeblock_t *block, int addr_reg) { @@ -261,6 +301,11 @@ void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shif codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) { int hw; @@ -300,6 +345,18 @@ void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t { codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); } + else if (imm_data == 0xffff0000) + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x0f)); + } + else if (imm_data == 0xffffff00) + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); + } + else if (imm_data == 0xffff00ff) + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); + } else { host_arm64_mov_imm(block, REG_W16, imm_data); @@ -372,6 +429,15 @@ void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); +} void host_arm64_call(codeblock_t *block, void *dst_addr) { @@ -391,16 +457,83 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) } } +#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) + +#define REG_IS_L(size) (size == IREG_SIZE_L) +#define REG_IS_W(size) (size == IREG_SIZE_W) +#define REG_IS_B(size) (size == IREG_SIZE_B) +#define REG_IS_BH(size) (size == IREG_SIZE_BH) static int codegen_ADD(codeblock_t *block, uop_t *uop) { - host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); + host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -412,12 +545,67 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - host_arm64_AND_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } + else + fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -456,13 +644,65 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - host_arm64_MOV_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) + { + host_arm64_BFI(block, dest_reg, src_reg, 8, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, uop->dest_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_arm64_mov_imm(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size)) + { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size)) + { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("MOV_IMM %x\n", uop->dest_reg_a_real); return 0; } @@ -474,14 +714,92 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); + } + else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); + } + else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); + } + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { - host_arm64_ORR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } + else + fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -510,23 +828,157 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - host_arm64_SUB_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } static int codegen_XOR(codeblock_t *block, uop_t *uop) { - host_arm64_EOR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } + else + fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -545,7 +997,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 372044b..17fd823 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -41,9 +41,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) #define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) +#define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) #define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) #define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) #define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) +#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) #define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) #define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) #define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) @@ -51,7 +54,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) #define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) -#define OPCODE_BLX 0xe12fff30 +#define OPCODE_BFI 0xe7c00010 +#define OPCODE_BLX 0xe12fff30 +#define OPCODE_UADD8 0xe6500f90 +#define OPCODE_UADD16 0xe6500f10 +#define OPCODE_USUB8 0xe6500ff0 +#define OPCODE_USUB16 0xe6500f70 +#define OPCODE_UXTB 0xe6ef0070 +#define OPCODE_UXTH 0xe6ff0070 #define B_OFFSET(x) (((x) >> 2) & 0xffffff) @@ -66,6 +76,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define SHIFT_IMM_SHIFT 7 #define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +#define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) + +#define BFI_lsb(lsb) ((lsb) << 7) +#define BFI_msb(msb) ((msb) << 16) + +#define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) + +#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) static int literal_offset = 0; void codegen_reset_literal_pool(codeblock_t *block) @@ -201,6 +219,20 @@ void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } +void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); +} + +void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} +void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} + void host_arm_BLX(codeblock_t *block, int addr_reg) { codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); @@ -266,6 +298,20 @@ void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif { codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } +void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); +} + +void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +{ + codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); +} + +void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); +} void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { @@ -288,6 +334,11 @@ void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } +void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} + void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); @@ -327,12 +378,45 @@ void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr { codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } +void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) { codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); } +void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +{ + codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +} + +void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +{ + codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +} void host_arm_call(codeblock_t *block, void *dst_addr) { @@ -346,15 +430,85 @@ void host_arm_nop(codeblock_t *block) host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); } +#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf) + +#define REG_IS_L(size) (size == IREG_SIZE_L) +#define REG_IS_W(size) (size == IREG_SIZE_W) +#define REG_IS_B(size) (size == IREG_SIZE_B) +#define REG_IS_BH(size) (size == IREG_SIZE_BH) + static int codegen_ADD(codeblock_t *block, uop_t *uop) { - host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); + host_arm_UADD16(block, dest_reg, src_reg_a, REG_TEMP); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); +// host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); +// return 0; + + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && src_reg == dest_reg) + { + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_UADD16(block, dest_reg, src_reg, REG_TEMP); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && src_reg == dest_reg) + { + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) + { + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); + host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); + } + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; + } static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { @@ -364,12 +518,69 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - host_arm_AND_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - host_arm_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + { + host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -437,22 +648,75 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - host_arm_MOV_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) + { + host_arm_BFI(block, dest_reg, src_reg, 8, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - uint32_t arm_imm; + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, uop->dest_reg_a_real, uop->imm_data); - else + if (REG_IS_L(dest_size)) { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, uop->dest_reg_a_real, REG_LITERAL, offset); + uint32_t arm_imm; + + if (get_arm_imm(uop->imm_data, &arm_imm)) + host_arm_MOV_IMM(block, dest_reg, uop->imm_data); + else + { + int offset = add_literal(block, uop->imm_data); + host_arm_LDR_IMM(block, dest_reg, REG_LITERAL, offset); + } } + else if (REG_IS_W(dest_size)) + { + host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size)) + { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else if (REG_IS_BH(dest_size)) + { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); + } + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); return 0; } @@ -464,14 +728,92 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_arm_UXTB(block, dest_reg, src_reg, 0); + } + else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) + { + host_arm_UXTB(block, dest_reg, src_reg, 8); + } + else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_arm_UXTH(block, dest_reg, src_reg, 0); + } + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { - host_arm_ORR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - host_arm_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -506,23 +848,158 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; + +// host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); +// return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - host_arm_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) + { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } static int codegen_XOR(codeblock_t *block, uop_t *uop) { - host_arm_EOR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) + { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - host_arm_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -541,6 +1018,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 4e0d50c..ff1f31f 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -117,29 +117,66 @@ static inline void call(codeblock_t *block, uintptr_t func) } } +static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ +} +static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} +static void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) @@ -148,29 +185,66 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_ codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } +static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ +} +static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ +} +static void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ +} static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) @@ -316,6 +390,19 @@ static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) } } +static void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg >= 8) + fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); + codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ +} +static void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV16_REG_IMM reg & 8\n"); + codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); +} static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) { if (reg & 8) @@ -332,6 +419,20 @@ static void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_dat codegen_addquad(block, imm_data); } +static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV8_REG_REG - bad reg\n"); + + codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV16_REG_REG - bad reg\n"); + + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { if ((dst_reg & 8) || (src_reg & 8)) @@ -360,29 +461,79 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ } } +static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ +} +static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} +static void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) @@ -391,33 +542,70 @@ static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } +static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ +} +static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} +static void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } @@ -431,29 +619,66 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ } +static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ +} +static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} +static void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) @@ -462,16 +687,56 @@ static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_ codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ } +#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) + +#define REG_IS_L(size) (size == IREG_SIZE_L) +#define REG_IS_W(size) (size == IREG_SIZE_W) +#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) +#define REG_IS_BH(size) (size == IREG_SIZE_BH) static int codegen_ADD(codeblock_t *block, uop_t *uop) { - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -489,13 +754,47 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_AND32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -539,12 +838,46 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); + return 0; } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) @@ -552,15 +885,66 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); return 0; } +static int codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { - host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -581,29 +965,103 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + } + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real); return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data); return 0; } static int codegen_XOR(codeblock_t *block, uop_t *uop) { - host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -622,7 +1080,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 9dac085..0f68a25 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -100,30 +100,67 @@ static int is_imm8(uint32_t imm_data) return 0; } +static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ +} +static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg) fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} +static void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) @@ -132,30 +169,67 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_ codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } +static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ +} +static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg) fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ +} +static void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ +} static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) @@ -260,6 +334,23 @@ static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addlong(block, (uint32_t)p); } } + +static void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ +} +static void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (!imm_data) + { + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } + else + { + codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (!imm_data) @@ -273,6 +364,14 @@ static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm } } +static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); +} +static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); +} static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); @@ -298,6 +397,29 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ } } +static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +static void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} +static void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) @@ -305,60 +427,121 @@ static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ } + +static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ +} +static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg) fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ +} +static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg) fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } +static void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} +static void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) - fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } @@ -368,6 +551,20 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_ho codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } +static void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} +static void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) @@ -376,27 +573,50 @@ static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_ codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ } +static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ +} +static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { if (dst_reg != src_reg) fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) - { codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); } else { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); } } @@ -406,15 +626,61 @@ static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); }*/ +#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) +#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) +#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) +#define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4) + +#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) + +#define REG_IS_L(size) (size == IREG_SIZE_L) +#define REG_IS_W(size) (size == IREG_SIZE_W) +#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) +#define REG_IS_BH(size) (size == IREG_SIZE_BH) + static int codegen_ADD(codeblock_t *block, uop_t *uop) { - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -432,13 +698,47 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) static int codegen_AND(codeblock_t *block, uop_t *uop) { - host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_AND32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -475,12 +775,46 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) static int codegen_MOV(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); + return 0; } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) @@ -488,15 +822,66 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); return 0; } +static int codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { - host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -513,29 +898,103 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) static int codegen_SUB(codeblock_t *block, uop_t *uop) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + } + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real); return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + } + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data); return 0; } static int codegen_XOR(codeblock_t *block, uop_t *uop) { - host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; } @@ -554,6 +1013,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 36bea69..1d89807 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -32,11 +32,11 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b); if (uop->src_reg_a.reg != IREG_INVALID) { - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a); + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); } if (uop->src_reg_b.reg != IREG_INVALID) { - uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b); + uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); } if (uop->dest_reg_a.reg != IREG_INVALID) { diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index bac0ab6..04ee628 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -27,22 +27,40 @@ #define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a) #define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b) #define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) +/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/ #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) #define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) #define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) +/*UOP_MOV_PTR - dest_reg = p*/ #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) +/*UOP_MOV_IMM - dest_reg = imm_data*/ #define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) +/*UOP_MOV - dest_reg = src_reg_a*/ #define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) +/*UOP_MOVZX - dest_reg = zero_extend(src_reg_a)*/ +#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) +/*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) +/*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ #define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) +/*UOP_AND - dest_reg = src_reg_a & src_reg_b*/ #define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +/*UOP_AND_IMM - dest_reg = src_reg_a & immediate*/ #define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +/*UOP_ADD_LSHIFT - dest_reg = src_reg_a + (src_reg_b << imm_data) + Intended for EA calcluations, imm_data must be between 0 and 3*/ #define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) +/*UOP_OR - dest_reg = src_reg_a | src_reg_b*/ #define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) +/*UOP_OR_IMM - dest_reg = src_reg_a | immediate*/ #define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) +/*UOP_SUB - dest_reg = src_reg_a - src_reg_b*/ #define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +/*UOP_SUB_IMM - dest_reg = src_reg_a - immediate*/ #define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) +/*UOP_XOR - dest_reg = src_reg_a ^ src_reg_b*/ #define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) +/*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ #define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) #define UOP_MAX 0x3b @@ -81,7 +99,6 @@ static inline uop_t *uop_alloc(ir_data_t *ir) uop->dest_reg_a = invalid_ir_reg; uop->src_reg_a = invalid_ir_reg; uop->src_reg_b = invalid_ir_reg; -// uop->src_reg_c = invalid_ir_reg; return uop; } @@ -121,6 +138,16 @@ static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int de uop->dest_reg_a = codegen_reg_write(dest_reg); } +static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->imm_data = imm; +} + static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) { uop_t *uop = uop_alloc(ir); @@ -196,9 +223,10 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) -#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) -#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) -#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) +#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) +#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 728c659..caaf3ff 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -10,20 +10,20 @@ RecompOpFn recomp_opcodes[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, NULL, NULL, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, +/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -32,20 +32,20 @@ RecompOpFn recomp_opcodes[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, ropADD_l_rmw, NULL, ropADD_l_rm, NULL, ropADD_EAX_imm, NULL, NULL, NULL, ropOR_l_rmw, NULL, ropOR_l_rm, NULL, ropOR_EAX_imm, NULL, NULL, +/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, NULL, NULL, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, ropAND_l_rmw, NULL, ropAND_l_rm, NULL, ropAND_EAX_imm, NULL, NULL, NULL, ropSUB_l_rmw, NULL, ropSUB_l_rm, NULL, ropSUB_EAX_imm, NULL, NULL, -/*30*/ NULL, ropXOR_l_rmw, NULL, ropXOR_l_rm, NULL, ropXOR_EAX_imm, NULL, NULL, NULL, ropCMP_l_rmw, NULL, ropCMP_l_rm, NULL, ropCMP_EAX_imm, NULL, NULL, +/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, +/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ NULL, rop81_l, NULL, rop83_l, NULL, NULL, NULL, NULL, NULL, ropMOV_l_r, NULL, ropMOV_r_l, NULL, NULL, NULL, NULL, +/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, +/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index d516152..1e3f226 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -8,6 +8,32 @@ #include "codegen_ops.h" #include "codegen_ops_arith.h" +uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -21,6 +47,70 @@ uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 codegen_flags_changed = 1; return op_pc + 4; } +uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; @@ -54,6 +144,32 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 1; } +uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -66,6 +182,70 @@ uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 codegen_flags_changed = 1; return op_pc + 4; } +uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; @@ -97,6 +277,32 @@ uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 1; } +uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -110,6 +316,70 @@ uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 codegen_flags_changed = 1; return op_pc + 4; } +uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; @@ -143,6 +413,148 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 1; } +uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint8_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = fastreadb(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = fastreadb(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = fastreadb(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = fastreadb(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = fastreadb(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = fastreadb(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 2; +} +uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint16_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = fastreadw(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = fastreadw(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = fastreadw(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = fastreadw(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = fastreadw(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = fastreadw(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 3; +} uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -213,6 +625,78 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_flags_changed = 1; return op_pc + 5; } + +uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint16_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h index f219318..2faa55d 100644 --- a/src/codegen_ops_arith.h +++ b/src/codegen_ops_arith.h @@ -1,14 +1,35 @@ +uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c index c4aca26..ad74d7e 100644 --- a/src/codegen_ops_logic.c +++ b/src/codegen_ops_logic.c @@ -8,6 +8,28 @@ #include "codegen_ops.h" #include "codegen_ops_logic.h" +uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -19,6 +41,62 @@ uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 codegen_flags_changed = 1; return op_pc + 4; } +uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; @@ -48,6 +126,28 @@ uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 1; } +uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -59,6 +159,62 @@ uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 codegen_flags_changed = 1; return op_pc + 4; } +uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; @@ -88,6 +244,28 @@ uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc + 1; } +uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -99,6 +277,62 @@ uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 codegen_flags_changed = 1; return op_pc + 4; } +uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h index 127f4c1..cfb7af3 100644 --- a/src/codegen_ops_logic.h +++ b/src/codegen_ops_logic.h @@ -1,11 +1,29 @@ +uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index 2266602..b8bb8aa 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -7,6 +7,22 @@ #include "codegen_ops.h" #include "codegen_ops_mov.h" +uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm = fastreadb(cs + op_pc); + + uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); + + return op_pc + 1; +} +uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); + + return op_pc + 2; +} uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { fetchdat = fastreadl(cs + op_pc); @@ -18,6 +34,34 @@ uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 +uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = (fetchdat >> 3) & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } + else + return 0; + + return op_pc + 1; +} +uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = (fetchdat >> 3) & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } + else + return 0; + + return op_pc + 1; +} uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -32,6 +76,34 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc + 1; } +uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } + else + return 0; + + return op_pc + 1; +} +uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } + else + return 0; + + return op_pc + 1; +} uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h index c9bafdc..cf8b31f 100644 --- a/src/codegen_ops_mov.h +++ b/src/codegen_ops_mov.h @@ -1,3 +1,9 @@ +uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 164a190..43027f3 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -84,27 +84,28 @@ void codegen_reg_reset() static inline int ir_reg_is_invalid(ir_reg_t ir_reg) { - return (ir_reg.reg == IREG_INVALID); + return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) { - switch (ireg_data[ir_reg.reg].native_size) + switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { case REG_DWORD: - codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[ir_reg.reg].p); + codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; default: - fatal("codegen_reg_load - native_size=%i\n", ireg_data[ir_reg.reg].native_size); + fatal("codegen_reg_load - native_size=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size); } host_regs[c] = ir_reg; +//pclog(" codegen_reg_load: c=%i reg=%02x.%i\n", c, host_regs[c].reg,host_regs[c].version); } static void codegen_reg_writeback(codeblock_t *block, int c) { - int ir_reg = host_regs[c].reg; + int ir_reg = IREG_GET_REG(host_regs[c].reg); switch (ireg_data[ir_reg].native_size) { @@ -141,28 +142,28 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ if (!ir_reg_is_invalid(dest_reg_a)) { - if (!ir_reg_is_invalid(src_reg_a) && src_reg_a.reg == dest_reg_a.reg && src_reg_a.version == dest_reg_a.version-1) + if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version-1) dest_reference++; - if (!ir_reg_is_invalid(src_reg_b) && src_reg_b.reg == dest_reg_a.reg && src_reg_b.version == dest_reg_a.version-1) + if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version-1) dest_reference++; } for (c = 0; c < CODEGEN_HOST_REGS; c++) { - if (!ir_reg_is_invalid(src_reg_a) && host_regs[c].reg == src_reg_a.reg) + if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_a.reg)) { if (host_regs[c].version != src_reg_a.version) fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_a.version\n"); host_regs_locked |= (1 << c); } - if (!ir_reg_is_invalid(src_reg_b) && host_regs[c].reg == src_reg_b.reg) + if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_b.reg)) { if (host_regs[c].version != src_reg_b.version) fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_b.version\n"); host_regs_locked |= (1 << c); } - if (!ir_reg_is_invalid(dest_reg_a) && host_regs[c].reg == dest_reg_a.reg) + if (!ir_reg_is_invalid(dest_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(dest_reg_a.reg)) { - if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[host_regs[c].reg][host_regs[c].version] == dest_reference)) + if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] == dest_reference)) host_regs_locked |= (1 << c); else fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", host_regs[c].version, dest_reg_a.version, dest_reference); @@ -170,17 +171,17 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ } } -ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg) +ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) { int c; /*Search for required register*/ for (c = 0; c < CODEGEN_HOST_REGS; c++) { - if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg && host_regs[c].version == ir_reg.version) + if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg) && host_regs[c].version == ir_reg.version) break; - if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg && reg_version_refcount[host_regs[c].reg][host_regs[c].version]) + if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version]) fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); } @@ -196,33 +197,60 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg) fatal("codegen_reg_alloc_read_reg - out of registers\n"); if (host_reg_dirty[c]) codegen_reg_writeback(block, c); +// pclog(" load %i\n", c); codegen_reg_load(block, c, ir_reg); host_regs_locked |= (1 << c); // fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); // codegen_reg_writeback(block, c); host_reg_dirty[c] = 0; } +// else +// pclog(" already loaded %i\n", c); - reg_version_refcount[host_regs[c].reg][host_regs[c].version]--; - if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] < 0) + reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version]--; + if (reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] < 0) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); -// pclog(" codegen_reg_alloc_read_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return codegen_host_reg_list[c]; + if (host_reg_idx) + *host_reg_idx = c; +// pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], host_regs[c].reg,host_regs[c].version, c); + return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg); } ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { int c; + if (IREG_GET_SIZE(ir_reg.reg) != IREG_SIZE_L) + { + /*Read in parent register so we can do partial accesses to it*/ + ir_reg_t parent_reg; + + parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; + parent_reg.version = ir_reg.version - 1; + + codegen_reg_alloc_read_reg(block, parent_reg, &c); + + if (IREG_GET_REG(host_regs[c].reg) != IREG_GET_REG(ir_reg.reg) || host_regs[c].version != ir_reg.version-1) + fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, + host_regs[c].reg,host_regs[c].version, + ir_reg.reg,ir_reg.version); + + host_regs[c].reg = ir_reg.reg; + host_regs[c].version = ir_reg.version; + host_reg_dirty[c] = 1; +// pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); + return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + } + /*Search for previous version in host register*/ for (c = 0; c < CODEGEN_HOST_REGS; c++) { - if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg) + if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { if (host_regs[c].version == ir_reg.version-1) { - if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] != 0) + if (reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] != 0) fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); break; } @@ -257,7 +285,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) host_regs[c].version = ir_reg.version; host_reg_dirty[c] = 1; // pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return codegen_host_reg_list[c]; + return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg); } void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) diff --git a/src/codegen_reg.h b/src/codegen_reg.h index e1b4965..b8f4de5 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -1,10 +1,17 @@ #ifndef _CODEGEN_REG_H_ #define _CODEGEN_REG_H_ -#define IREG_SIZE_L (0 << 6) -#define IREG_SIZE_W (1 << 6) -#define IREG_SIZE_B (2 << 6) -#define IREG_SIZE_BH (3 << 6) +#define IREG_REG_MASK 0x3f +#define IREG_SIZE_SHIFT 6 +#define IREG_SIZE_MASK (3 << IREG_SIZE_SHIFT) + +#define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK) +#define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK) + +#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) +#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) +#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) +#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) enum { @@ -45,9 +52,34 @@ enum IREG_COUNT, - IREG_INVALID = 255 + IREG_INVALID = 63, + + IREG_AX = IREG_EAX + IREG_SIZE_W, + IREG_CX = IREG_ECX + IREG_SIZE_W, + IREG_DX = IREG_EDX + IREG_SIZE_W, + IREG_BX = IREG_EBX + IREG_SIZE_W, + IREG_SP = IREG_ESP + IREG_SIZE_W, + IREG_BP = IREG_EBP + IREG_SIZE_W, + IREG_SI = IREG_ESI + IREG_SIZE_W, + IREG_DI = IREG_EDI + IREG_SIZE_W, + + IREG_AL = IREG_EAX + IREG_SIZE_B, + IREG_CL = IREG_ECX + IREG_SIZE_B, + IREG_DL = IREG_EDX + IREG_SIZE_B, + IREG_BL = IREG_EBX + IREG_SIZE_B, + + IREG_AH = IREG_EAX + IREG_SIZE_BH, + IREG_CH = IREG_ECX + IREG_SIZE_BH, + IREG_DH = IREG_EDX + IREG_SIZE_BH, + IREG_BH = IREG_EBX + IREG_SIZE_BH, + + IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, + + IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B }; +#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) +#define IREG_16(reg) ((reg) + IREG_AX) #define IREG_32(reg) ((reg) + IREG_EAX) extern uint8_t reg_last_version[IREG_COUNT]; @@ -67,13 +99,13 @@ static inline ir_reg_t codegen_reg_read(int reg) { ir_reg_t ireg; - if (reg == IREG_INVALID) + if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_read - IREG_INVALID\n"); ireg.reg = reg; - ireg.version = reg_last_version[reg]; - reg_version_refcount[ireg.reg][ireg.version]++; - if (!reg_version_refcount[ireg.reg][ireg.version]) + ireg.version = reg_last_version[IREG_GET_REG(reg)]; + reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]++; + if (!reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]) fatal("codegen_reg_read - refcount overflow\n"); return ireg; @@ -83,15 +115,15 @@ static inline ir_reg_t codegen_reg_write(int reg) { ir_reg_t ireg; - if (reg == IREG_INVALID) + if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_write - IREG_INVALID\n"); ireg.reg = reg; - ireg.version = reg_last_version[reg] + 1; - reg_last_version[reg]++; - if (!reg_last_version[reg]) + ireg.version = reg_last_version[IREG_GET_REG(reg)] + 1; + reg_last_version[IREG_GET_REG(reg)]++; + if (!reg_last_version[IREG_GET_REG(reg)]) fatal("codegen_reg_write - version overflow\n"); - reg_version_refcount[reg][ireg.version] = 0; + reg_version_refcount[IREG_GET_REG(reg)][ireg.version] = 0; return ireg; } @@ -104,7 +136,7 @@ void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block); /*Register ir_reg usage for this uOP. This ensures that required registers aren't evicted*/ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b); -ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg); +ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); #endif From 0f0a1c3223ff35393fbe0b18252e40a47ecdadde Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Jul 2018 22:10:18 +0100 Subject: [PATCH 0483/1050] Perform NULL segment checks upfront in opcode handlers, rather than on every memory access. This removes the need to pass the segment to readmem*l()/writemem*l(). --- src/386_common.h | 54 +++++-- src/386_dynarec.c | 2 +- src/808x.c | 20 +-- src/ibm.h | 20 +-- src/mem.c | 340 +++++++++++++++++----------------------- src/x86_ops_arith.h | 106 +++++++++++-- src/x86_ops_atomic.h | 14 ++ src/x86_ops_bit.h | 28 +++- src/x86_ops_bitscan.h | 16 ++ src/x86_ops_call.h | 56 +++++++ src/x86_ops_inc_dec.h | 4 + src/x86_ops_misc.h | 39 +++++ src/x86_ops_mmx.h | 1 + src/x86_ops_mmx_arith.h | 6 +- src/x86_ops_mmx_mov.h | 12 +- src/x86_ops_mmx_pack.h | 4 +- src/x86_ops_mmx_shift.h | 1 + src/x86_ops_mov.h | 44 +++++- src/x86_ops_mov_seg.h | 34 +++- src/x86_ops_movx.h | 28 ++++ src/x86_ops_mul.h | 42 ++++- src/x86_ops_pmode.h | 35 ++++- src/x86_ops_rep.h | 71 +++++++-- src/x86_ops_set.h | 4 + src/x86_ops_shift.h | 44 ++++++ src/x86_ops_stack.h | 8 + src/x86_ops_string.h | 192 ++++++++++++++++++----- src/x86_ops_xchg.h | 18 +++ src/x87_ops_arith.h | 8 + src/x87_ops_loadstore.h | 34 ++++ src/x87_ops_misc.h | 14 ++ 31 files changed, 975 insertions(+), 324 deletions(-) diff --git a/src/386_common.h b/src/386_common.h index 3401257..906c09a 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -4,14 +4,14 @@ extern uint16_t ea_rseg; #undef writememb -#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)) & 7))?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?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)+(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 writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) 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)) & 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 +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((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)+(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)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v int checkio(int port); @@ -37,6 +37,26 @@ int checkio(int port); } \ } +#define SEG_CHECK_READ(seg) \ + do \ + { \ + if ((seg)->base == 0xffffffff) \ + { \ + x86gpf("Segment can't read", 0);\ + return 1; \ + } \ + } while (0) + +#define SEG_CHECK_WRITE(seg) \ + do \ + { \ + if ((seg)->base == 0xffffffff) \ + { \ + x86gpf("Segment can't write", 0);\ + return 1; \ + } \ + } while (0) + #define CHECK_READ(seg, low, high) \ if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((seg)->access & 10) == 8))) \ { \ @@ -156,7 +176,7 @@ static inline uint8_t geteab() return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l; if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg, cpu_state.eaaddr); + return readmemb(easeg,cpu_state.eaaddr); } static inline uint16_t geteaw() @@ -166,7 +186,7 @@ static inline uint16_t geteaw() // cycles-=3; if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg, cpu_state.eaaddr); + return readmemw(easeg,cpu_state.eaaddr); } static inline uint32_t geteal() @@ -176,12 +196,12 @@ static inline uint32_t geteal() // cycles-=3; if (eal_r) return *eal_r; - return readmeml(easeg, cpu_state.eaaddr); + return readmeml(easeg,cpu_state.eaaddr); } static inline uint64_t geteaq() { - return readmemq(easeg, cpu_state.eaaddr); + return readmemq(easeg,cpu_state.eaaddr); } static inline uint8_t geteab_mem() @@ -202,16 +222,16 @@ static inline uint32_t geteal_mem() static inline void seteaq(uint64_t v) { - writememql(easeg, cpu_state.eaaddr, v); + writememql(easeg+cpu_state.eaaddr, v); } -#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v -#define seteal(v) if (cpu_mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v +#define seteaw(v) if (cpu_mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v +#define seteal(v) if (cpu_mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v -#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); -#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v); -#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); +#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg+cpu_state.eaaddr,v); +#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); +#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); #define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ #define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 4dff9e7..7224d09 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -429,7 +429,7 @@ int checkio(int port) // 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 = readmemb386l(tr.base + t + (port >> 3)); // d=readmemb(tr.base,t+(port>>3)); cpl_override = 0; // pclog("%02X %02X\n",d,d&(1<<(port&7))); diff --git a/src/808x.c b/src/808x.c index e50a13c..082e0b0 100644 --- a/src/808x.c +++ b/src/808x.c @@ -38,13 +38,6 @@ int nopageerrors=0; void FETCHCOMPLETE(); -uint8_t readmembl(uint32_t addr); -void writemembl(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); - #undef readmemb #undef readmemw uint8_t readmemb(uint32_t a) @@ -63,7 +56,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[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) 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); } @@ -76,24 +69,21 @@ void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; } cpu_rm=rmdat&7; \ if (cpu_mod!=3) fetcheal(); } -void writemembl(uint32_t addr, uint8_t val); void writememb(uint32_t a, uint8_t v) { memcycs+=4; if (writelookup2[(a)>>12]==-1) writemembl(a,v); else *(uint8_t *)(writelookup2[a >> 12] + a) = v; } -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[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) 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[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) 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; } @@ -538,10 +528,10 @@ void dumpregs() fclose(f);*/ pclog("Dumping rram4.dmp\n"); f=fopen("rram4.dmp","wb"); - for (c=0;c<0x0050000;c++) + for (c=0;c<0x0050000;c++) { cpu_state.abrt = 0; - putc(readmemb386l(0,c+0x80000000),f); + putc(readmemb386l(c+0x80000000),f); } fclose(f); pclog("Dumping done\n"); diff --git a/src/ibm.h b/src/ibm.h index 549acc2..6177fef 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -31,8 +31,8 @@ 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)) & 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)))) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((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)+(a)) & 3))?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 @@ -43,14 +43,14 @@ extern int mmu_perm; //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); -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); +uint8_t readmemb386l(uint32_t addr); +void writememb386l(uint32_t addr, uint8_t val); +uint16_t readmemwl(uint32_t addr); +void writememwl(uint32_t addr, uint16_t val); +uint32_t readmemll(uint32_t addr); +void writememll(uint32_t addr, uint32_t val); +uint64_t readmemql(uint32_t addr); +void writememql(uint32_t addr, uint64_t val); uint8_t *getpccache(uint32_t a); diff --git a/src/mem.c b/src/mem.c index eabbcaa..6fa3a69 100644 --- a/src/mem.c +++ b/src/mem.c @@ -295,7 +295,6 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && ((CPL == 3 && !cpl_override) || 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,pc,SS,ESP,ins,CPL,rw); - // dumpregs(); // exit(-1); // if (addr == 0x815F6E90) output = 3; @@ -498,15 +497,9 @@ void writemembl(uint32_t addr, uint8_t val) // else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); } -uint8_t readmemb386l(uint32_t seg, uint32_t addr) +uint8_t readmemb386l(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; + mem_logical_addr = addr; /* if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF) { return ram[readlookup2[mem_logical_addr >> 12] + (mem_logical_addr & 0xFFF)]; @@ -525,16 +518,9 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr) return 0xFF; } -void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) +void writememb386l(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; - } - - mem_logical_addr = addr = addr + seg; + mem_logical_addr = addr; if (page_lookup[addr>>12]) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); @@ -555,352 +541,308 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) // else pclog("Bad writememb386l %08X %02X %04X:%08X\n", addr, val, CS, pc); } -uint16_t readmemwl(uint32_t seg, uint32_t addr) +uint16_t readmemwl(uint32_t addr) { - uint32_t addr2 = mem_logical_addr = seg + addr; + mem_logical_addr = addr; - if (seg==-1) + if (addr & 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 & 1) - { - if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFFE) + if ((addr & 0xFFF) > 0xFFE) { if (cr0 >> 31) { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; - if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr+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 (is386) return readmemb386l(addr)|(readmemb386l(addr+1)<<8); + else return readmembl(addr)|(readmembl(addr+1)<<8); } - else if (readlookup2[addr2 >> 12] != -1) - return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); + else if (readlookup2[addr >> 12] != -1) + return *(uint16_t *)(readlookup2[addr >> 12] + addr); } if (cr0>>31) { - addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return 0xFFFF; + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) return 0xFFFF; } - addr2 &= rammask; + addr &= rammask; - if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); + if (_mem_read_w[addr >> 14]) return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); - if (_mem_read_b[addr2 >> 14]) - { - 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); + if (_mem_read_b[addr >> 14]) + return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]) | (_mem_read_b[(addr + 1) >> 14](addr + 1, _mem_priv_r[addr >> 14]) << 8); + +// pclog("Bad readmemwl %08X\n", addr); return 0xffff; } -void writememwl(uint32_t seg, uint32_t addr, uint16_t val) +void writememwl(uint32_t addr, uint16_t val) { - uint32_t addr2 = mem_logical_addr = seg + addr; + mem_logical_addr = addr; - if (seg==-1) + if (addr & 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 & 1) - { - if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFFE) + if ((addr & 0xFFF) > 0xFFE) { if (cr0 >> 31) { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+1) == 0xffffffff) return; + if (mmutranslate_write(addr) == 0xffffffff) return; + if (mmutranslate_write(addr+1) == 0xffffffff) return; } if (is386) { - writememb386l(seg,addr,val); - writememb386l(seg,addr+1,val>>8); + writememb386l(addr,val); + writememb386l(addr+1,val>>8); } else { - writemembl(seg+addr,val); - writemembl(seg+addr+1,val>>8); + writemembl(addr,val); + writemembl(addr+1,val>>8); } return; } - else if (writelookup2[addr2 >> 12] != -1) + else if (writelookup2[addr >> 12] != -1) { - *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; + *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; return; } } - if (page_lookup[addr2>>12]) + if (page_lookup[addr>>12]) { - page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); + page_lookup[addr>>12]->write_w(addr, val, page_lookup[addr>>12]); return; } if (cr0>>31) { - addr2 = mmutranslate_write(addr2); - if (addr2==0xFFFFFFFF) return; + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) return; } - addr2 &= rammask; + addr &= rammask; -/* if (addr2 >= 0xa0000 && addr2 < 0xc0000) - pclog("writememwl %08X %02X\n", addr2, val);*/ - - if (_mem_write_w[addr2 >> 14]) + if (_mem_write_w[addr >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); return; } - if (_mem_write_b[addr2 >> 14]) + if (_mem_write_b[addr >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + _mem_write_b[(addr + 1) >> 14](addr + 1, val >> 8, _mem_priv_w[addr >> 14]); return; } -// pclog("Bad writememwl %08X %04X\n", addr2, val); +// pclog("Bad writememwl %08X %04X\n", addr, val); } -uint32_t readmemll(uint32_t seg, uint32_t addr) +uint32_t readmemll(uint32_t addr) { - uint32_t addr2 = mem_logical_addr = seg + addr; + mem_logical_addr = addr; - if (seg==-1) + if (addr & 3) { - x86gpf("NULL segment", 0); - printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); - return -1; - } - - if (addr2 & 3) - { - if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + if (!cpu_cyrix_alignment || (addr & 7) > 4) cycles -= timing_misaligned; - if ((addr2&0xFFF)>0xFFC) + if ((addr&0xFFF)>0xFFC) { if (cr0>>31) { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr+3) == 0xffffffff) return 0xffffffff; } - return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + return readmemwl(addr)|(readmemwl(addr+2)<<16); } - else if (readlookup2[addr2 >> 12] != -1) - return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); + else if (readlookup2[addr >> 12] != -1) + return *(uint32_t *)(readlookup2[addr >> 12] + addr); } if (cr0>>31) { - addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return 0xFFFFFFFF; + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) return 0xFFFFFFFF; } - addr2&=rammask; + addr&=rammask; - if (_mem_read_l[addr2 >> 14]) return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]); + if (_mem_read_l[addr >> 14]) return _mem_read_l[addr >> 14](addr, _mem_priv_r[addr >> 14]); - if (_mem_read_w[addr2 >> 14]) return _mem_read_w[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_w[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16); + if (_mem_read_w[addr >> 14]) return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]) | (_mem_read_w[addr >> 14](addr + 2, _mem_priv_r[addr >> 14]) << 16); - 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); + if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]) | (_mem_read_b[addr >> 14](addr + 1, _mem_priv_r[addr >> 14]) << 8) | (_mem_read_b[addr >> 14](addr + 2, _mem_priv_r[addr >> 14]) << 16) | (_mem_read_b[addr >> 14](addr + 3, _mem_priv_r[addr >> 14]) << 24); -// pclog("Bad readmemll %08X\n", addr2); +// pclog("Bad readmemll %08X\n", addr); return 0xffffffff; } -void writememll(uint32_t seg, uint32_t addr, uint32_t val) +void writememll(uint32_t addr, uint32_t val) { - uint32_t addr2 = mem_logical_addr = seg + addr; + mem_logical_addr = addr; - if (seg==-1) + if (addr & 3) { - x86gpf("NULL segment", 0); - printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); - return; - } - if (addr2 & 3) - { - if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + if (!cpu_cyrix_alignment || (addr & 7) > 4) cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFFC) + if ((addr & 0xFFF) > 0xFFC) { if (cr0>>31) { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+3) == 0xffffffff) return; + if (mmutranslate_write(addr) == 0xffffffff) return; + if (mmutranslate_write(addr+3) == 0xffffffff) return; } - writememwl(seg,addr,val); - writememwl(seg,addr+2,val>>16); + writememwl(addr,val); + writememwl(addr+2,val>>16); return; } - else if (writelookup2[addr2 >> 12] != -1) + else if (writelookup2[addr >> 12] != -1) { - *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; + *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; return; } } - if (page_lookup[addr2>>12]) + if (page_lookup[addr>>12]) { - page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); return; } if (cr0>>31) { - addr2 = mmutranslate_write(addr2); - if (addr2==0xFFFFFFFF) return; + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) return; } - addr2&=rammask; + addr&=rammask; /* if (addr >= 0xa0000 && addr < 0xc0000) pclog("writememll %08X %08X\n", addr, val);*/ - if (_mem_write_l[addr2 >> 14]) + if (_mem_write_l[addr >> 14]) { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_l[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); return; } - if (_mem_write_w[addr2 >> 14]) + if (_mem_write_w[addr >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + _mem_write_w[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); return; } - if (_mem_write_b[addr2 >> 14]) + if (_mem_write_b[addr >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 1, val >> 8, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 3, val >> 24, _mem_priv_w[addr >> 14]); return; } -// pclog("Bad writememll %08X %08X\n", addr2, val); +// pclog("Bad writememll %08X %08X\n", addr, val); } -uint64_t readmemql(uint32_t seg, uint32_t addr) +uint64_t readmemql(uint32_t addr) { - uint32_t addr2 = mem_logical_addr = seg + addr; + mem_logical_addr = 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; - } - - if (addr2 & 7) + if (addr & 7) { cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFF8) + if ((addr & 0xFFF) > 0xFF8) { if (cr0>>31) { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr+7) == 0xffffffff) return 0xffffffff; } - return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + return readmemll(addr)|((uint64_t)readmemll(addr+4)<<32); } - else if (readlookup2[addr2 >> 12] != -1) - return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); + else if (readlookup2[addr >> 12] != -1) + return *(uint64_t *)(readlookup2[addr >> 12] + addr); } if (cr0>>31) { - addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return 0xFFFFFFFF; + addr = mmutranslate_read(addr); + if (addr==0xFFFFFFFF) return 0xFFFFFFFF; } - addr2&=rammask; + addr&=rammask; - if (_mem_read_l[addr2 >> 14]) - return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | - ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32); + if (_mem_read_l[addr >> 14]) + return _mem_read_l[addr >> 14](addr, _mem_priv_r[addr >> 14]) | + ((uint64_t)_mem_read_l[addr >> 14](addr + 4, _mem_priv_r[addr >> 14]) << 32); - return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); + return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); } -void writememql(uint32_t seg, uint32_t addr, uint64_t val) +void writememql(uint32_t addr, uint64_t val) { - uint32_t addr2 = mem_logical_addr = seg + addr; + mem_logical_addr = addr; - 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 & 7) + if (addr & 7) { cycles -= timing_misaligned; - if ((addr2 & 0xFFF) > 0xFF8) + if ((addr & 0xFFF) > 0xFF8) { if (cr0>>31) { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+7) == 0xffffffff) return; + if (mmutranslate_write(addr) == 0xffffffff) return; + if (mmutranslate_write(addr+7) == 0xffffffff) return; } - writememll(seg, addr, val); - writememll(seg, addr+4, val >> 32); + writememll(addr, val); + writememll(addr+4, val >> 32); return; } - else if (writelookup2[addr2 >> 12] != -1) + else if (writelookup2[addr >> 12] != -1) { - *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; + *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; return; } } - if (page_lookup[addr2>>12]) + if (page_lookup[addr>>12]) { - page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); - page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]); + page_lookup[addr>>12]->write_l(addr, val, page_lookup[addr>>12]); + page_lookup[addr>>12]->write_l(addr + 4, val >> 32, page_lookup[addr>>12]); return; } if (cr0>>31) { - addr2 = mmutranslate_write(addr2); - if (addr2==0xFFFFFFFF) return; + addr = mmutranslate_write(addr); + if (addr==0xFFFFFFFF) return; } - addr2&=rammask; + addr&=rammask; - if (_mem_write_l[addr2 >> 14]) + if (_mem_write_l[addr >> 14]) { - _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]); + _mem_write_l[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + _mem_write_l[addr >> 14](addr+4, val >> 32, _mem_priv_w[addr >> 14]); return; } - if (_mem_write_w[addr2 >> 14]) + if (_mem_write_w[addr >> 14]) { - _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); - _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + _mem_write_w[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); + _mem_write_w[addr >> 14](addr + 4, val >> 32, _mem_priv_w[addr >> 14]); + _mem_write_w[addr >> 14](addr + 6, val >> 48, _mem_priv_w[addr >> 14]); return; } - if (_mem_write_b[addr2 >> 14]) + if (_mem_write_b[addr >> 14]) { - _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); - _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 1, val >> 8, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 3, val >> 24, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 4, val >> 32, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 5, val >> 40, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 6, val >> 48, _mem_priv_w[addr >> 14]); + _mem_write_b[addr >> 14](addr + 7, val >> 56, _mem_priv_w[addr >> 14]); return; } -// pclog("Bad writememql %08X %08X\n", addr2, val); +// pclog("Bad writememql %08X %08X\n", addr, val); } uint8_t mem_readb_phys(uint32_t addr) diff --git a/src/x86_ops_arith.h b/src/x86_ops_arith.h index 2417555..b9787e9 100644 --- a/src/x86_ops_arith.h +++ b/src/x86_ops_arith.h @@ -14,9 +14,11 @@ } \ else \ { \ - uint8_t dst = geteab(); if (cpu_state.abrt) return 1; \ + uint8_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); if (cpu_state.abrt) return 1; \ uint8_t src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ + seteab(operation); if (cpu_state.abrt) return 1; \ setflags ## 8 flagops; \ CLOCK_CYCLES(timing_mr); \ PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \ @@ -38,7 +40,9 @@ } \ else \ { \ - uint8_t dst = geteab(); if (cpu_state.abrt) return 1; \ + uint8_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); if (cpu_state.abrt) return 1; \ uint8_t src = getr8(cpu_reg); \ seteab(operation); if (cpu_state.abrt) return 1; \ setflags ## 8 flagops; \ @@ -63,7 +67,9 @@ } \ else \ { \ - uint16_t dst = geteaw(); if (cpu_state.abrt) return 1; \ + uint16_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); if (cpu_state.abrt) return 1; \ uint16_t src = cpu_state.regs[cpu_reg].w; \ seteaw(operation); if (cpu_state.abrt) return 1; \ setflags ## 16 flagops; \ @@ -87,7 +93,9 @@ } \ else \ { \ - uint16_t dst = geteaw(); if (cpu_state.abrt) return 1; \ + uint16_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); if (cpu_state.abrt) return 1; \ uint16_t src = cpu_state.regs[cpu_reg].w; \ seteaw(operation); if (cpu_state.abrt) return 1; \ setflags ## 16 flagops; \ @@ -112,7 +120,9 @@ } \ else \ { \ - uint32_t dst = geteal(); if (cpu_state.abrt) return 1; \ + uint32_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); if (cpu_state.abrt) return 1; \ uint32_t src = cpu_state.regs[cpu_reg].l; \ seteal(operation); if (cpu_state.abrt) return 1; \ setflags ## 32 flagops; \ @@ -136,7 +146,9 @@ } \ else \ { \ - uint32_t dst = geteal(); if (cpu_state.abrt) return 1; \ + uint32_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); if (cpu_state.abrt) return 1; \ uint32_t src = cpu_state.regs[cpu_reg].l; \ seteal(operation); if (cpu_state.abrt) return 1; \ setflags ## 32 flagops; \ @@ -151,6 +163,8 @@ uint8_t dst, src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ dst = getr8(cpu_reg); \ src = geteab(); if (cpu_state.abrt) return 1; \ setflags ## 8 flagops; \ @@ -164,6 +178,8 @@ uint8_t dst, src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ dst = getr8(cpu_reg); \ src = geteab(); if (cpu_state.abrt) return 1; \ setflags ## 8 flagops; \ @@ -178,6 +194,8 @@ uint16_t dst, src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ dst = cpu_state.regs[cpu_reg].w; \ src = geteaw(); if (cpu_state.abrt) return 1; \ setflags ## 16 flagops; \ @@ -191,6 +209,8 @@ uint16_t dst, src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ dst = cpu_state.regs[cpu_reg].w; \ src = geteaw(); if (cpu_state.abrt) return 1; \ setflags ## 16 flagops; \ @@ -205,6 +225,8 @@ uint32_t dst, src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ dst = cpu_state.regs[cpu_reg].l; \ src = geteal(); if (cpu_state.abrt) return 1; \ setflags ## 32 flagops; \ @@ -218,6 +240,8 @@ uint32_t dst, src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ dst = cpu_state.regs[cpu_reg].l; \ src = geteal(); if (cpu_state.abrt) return 1; \ setflags ## 32 flagops; \ @@ -275,6 +299,8 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat) { uint8_t dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; setsub8(dst, getr8(cpu_reg)); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -286,6 +312,8 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat) { uint8_t dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; setsub8(dst, getr8(cpu_reg)); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -298,6 +326,8 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat) { uint16_t dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; setsub16(dst, cpu_state.regs[cpu_reg].w); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -309,6 +339,8 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat) { uint16_t dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; setsub16(dst, cpu_state.regs[cpu_reg].w); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -321,6 +353,8 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat) { uint32_t dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; setsub32(dst, cpu_state.regs[cpu_reg].l); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -332,6 +366,8 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat) { uint32_t dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; setsub32(dst, cpu_state.regs[cpu_reg].l); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -344,7 +380,9 @@ static int opCMP_b_rm_a16(uint32_t fetchdat) { uint8_t src; fetch_ea_16(fetchdat); - src = geteab(); if (cpu_state.abrt) return 1; + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); if (cpu_state.abrt) return 1; setsub8(getr8(cpu_reg), src); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); @@ -354,7 +392,9 @@ static int opCMP_b_rm_a32(uint32_t fetchdat) { uint8_t src; fetch_ea_32(fetchdat); - src = geteab(); if (cpu_state.abrt) return 1; + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); if (cpu_state.abrt) return 1; setsub8(getr8(cpu_reg), src); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); @@ -365,7 +405,9 @@ static int opCMP_w_rm_a16(uint32_t fetchdat) { uint16_t src; fetch_ea_16(fetchdat); - src = geteaw(); if (cpu_state.abrt) return 1; + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); if (cpu_state.abrt) return 1; setsub16(cpu_state.regs[cpu_reg].w, src); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); @@ -375,7 +417,9 @@ static int opCMP_w_rm_a32(uint32_t fetchdat) { uint16_t src; fetch_ea_32(fetchdat); - src = geteaw(); if (cpu_state.abrt) return 1; + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); if (cpu_state.abrt) return 1; setsub16(cpu_state.regs[cpu_reg].w, src); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); @@ -386,7 +430,9 @@ static int opCMP_l_rm_a16(uint32_t fetchdat) { uint32_t src; fetch_ea_16(fetchdat); - src = geteal(); if (cpu_state.abrt) return 1; + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); if (cpu_state.abrt) return 1; setsub32(cpu_state.regs[cpu_reg].l, src); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); @@ -396,7 +442,9 @@ static int opCMP_l_rm_a32(uint32_t fetchdat) { uint32_t src; fetch_ea_32(fetchdat); - src = geteal(); if (cpu_state.abrt) return 1; + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); if (cpu_state.abrt) return 1; setsub32(cpu_state.regs[cpu_reg].l, src); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); @@ -434,6 +482,8 @@ static int opTEST_b_a16(uint32_t fetchdat) { uint8_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; temp2 = getr8(cpu_reg); setznp8(temp & temp2); @@ -446,6 +496,8 @@ static int opTEST_b_a32(uint32_t fetchdat) { uint8_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; temp2 = getr8(cpu_reg); setznp8(temp & temp2); @@ -459,6 +511,8 @@ static int opTEST_w_a16(uint32_t fetchdat) { uint16_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].w; setznp16(temp & temp2); @@ -471,6 +525,8 @@ static int opTEST_w_a32(uint32_t fetchdat) { uint16_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].w; setznp16(temp & temp2); @@ -484,6 +540,8 @@ static int opTEST_l_a16(uint32_t fetchdat) { uint32_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].l; setznp32(temp & temp2); @@ -496,6 +554,8 @@ static int opTEST_l_a32(uint32_t fetchdat) { uint32_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; temp2 = cpu_state.regs[cpu_reg].l; setznp32(temp & temp2); @@ -588,6 +648,8 @@ static int op80_a16(uint32_t fetchdat) uint8_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; ARITH_MULTI(b, 8); if ((rmdat & 0x38) == 0x38) @@ -602,6 +664,8 @@ static int op80_a32(uint32_t fetchdat) uint8_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; ARITH_MULTI(b, 8); if ((rmdat & 0x38) == 0x38) @@ -616,6 +680,8 @@ static int op81_w_a16(uint32_t fetchdat) uint16_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getword(); if (cpu_state.abrt) return 1; ARITH_MULTI(w, 16); if ((rmdat & 0x38) == 0x38) @@ -630,6 +696,8 @@ static int op81_w_a32(uint32_t fetchdat) uint16_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getword(); if (cpu_state.abrt) return 1; ARITH_MULTI(w, 16); if ((rmdat & 0x38) == 0x38) @@ -644,6 +712,8 @@ static int op81_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); if ((rmdat & 0x38) == 0x38) @@ -658,6 +728,8 @@ static int op81_l_a32(uint32_t fetchdat) uint32_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getlong(); if (cpu_state.abrt) return 1; ARITH_MULTI(l, 32); if ((rmdat & 0x38) == 0x38) @@ -673,6 +745,8 @@ static int op83_w_a16(uint32_t fetchdat) uint16_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); @@ -688,6 +762,8 @@ static int op83_w_a32(uint32_t fetchdat) uint16_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xff00; ARITH_MULTI(w, 16); @@ -704,6 +780,8 @@ static int op83_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); @@ -719,6 +797,8 @@ static int op83_l_a32(uint32_t fetchdat) uint32_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); src = getbyte(); if (cpu_state.abrt) return 1; if (src & 0x80) src |= 0xffffff00; ARITH_MULTI(l, 32); diff --git a/src/x86_ops_atomic.h b/src/x86_ops_atomic.h index 0e0069c..d74c30e 100644 --- a/src/x86_ops_atomic.h +++ b/src/x86_ops_atomic.h @@ -8,6 +8,7 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; if (AL == temp) seteab(getr8(cpu_reg)); else AL = temp; @@ -26,6 +27,7 @@ static int opCMPXCHG_b_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; if (AL == temp) seteab(getr8(cpu_reg)); else AL = temp; @@ -45,6 +47,7 @@ static int opCMPXCHG_w_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); else AX = temp; @@ -63,6 +66,7 @@ static int opCMPXCHG_w_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); else AX = temp; @@ -82,6 +86,7 @@ static int opCMPXCHG_l_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); else EAX = temp; @@ -100,6 +105,7 @@ static int opCMPXCHG_l_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); else EAX = temp; @@ -119,6 +125,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat) return 0; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; if (EAX == temp && EDX == temp_hi) @@ -150,6 +157,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) return 0; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; if (EAX == temp && EDX == temp_hi) @@ -182,6 +190,7 @@ static int opXADD_b_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; setadd8(temp, getr8(cpu_reg)); @@ -199,6 +208,7 @@ static int opXADD_b_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1; setadd8(temp, getr8(cpu_reg)); @@ -217,6 +227,7 @@ static int opXADD_w_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; setadd16(temp, cpu_state.regs[cpu_reg].w); @@ -234,6 +245,7 @@ static int opXADD_w_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; setadd16(temp, cpu_state.regs[cpu_reg].w); @@ -252,6 +264,7 @@ static int opXADD_l_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; setadd32(temp, cpu_state.regs[cpu_reg].l); @@ -269,6 +282,7 @@ static int opXADD_l_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; setadd32(temp, cpu_state.regs[cpu_reg].l); diff --git a/src/x86_ops_bit.h b/src/x86_ops_bit.h index 272d22b..74194f5 100644 --- a/src/x86_ops_bit.h +++ b/src/x86_ops_bit.h @@ -3,6 +3,7 @@ static int opBT_w_r_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -18,6 +19,7 @@ static int opBT_w_r_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -33,6 +35,7 @@ static int opBT_l_r_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -48,6 +51,7 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -66,6 +70,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint16_t temp; \ \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ temp = geteaw(); if (cpu_state.abrt) return 1; \ tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ @@ -85,6 +91,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint16_t temp; \ \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ temp = geteaw(); if (cpu_state.abrt) return 1; \ tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ @@ -104,6 +112,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint32_t temp; \ \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ temp = geteal(); if (cpu_state.abrt) return 1; \ tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ @@ -123,6 +133,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) uint32_t temp; \ \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ temp = geteal(); if (cpu_state.abrt) return 1; \ tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ @@ -147,7 +159,9 @@ static int opBA_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -189,7 +203,9 @@ static int opBA_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -232,7 +248,9 @@ static int opBA_l_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); @@ -274,7 +292,9 @@ static int opBA_l_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); count = getbyte(); if (cpu_state.abrt) return 1; tempc = temp & (1 << count); diff --git a/src/x86_ops_bitscan.h b/src/x86_ops_bitscan.h index 0c1ee04..4fcc79c 100644 --- a/src/x86_ops_bitscan.h +++ b/src/x86_ops_bitscan.h @@ -25,6 +25,8 @@ static int opBSF_w_a16(uint32_t fetchdat) int instr_cycles; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); @@ -40,6 +42,8 @@ static int opBSF_w_a32(uint32_t fetchdat) int instr_cycles; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); @@ -55,6 +59,8 @@ static int opBSF_l_a16(uint32_t fetchdat) int instr_cycles; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); @@ -70,6 +76,8 @@ static int opBSF_l_a32(uint32_t fetchdat) int instr_cycles; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); @@ -86,6 +94,8 @@ static int opBSR_w_a16(uint32_t fetchdat) int instr_cycles; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); @@ -101,6 +111,8 @@ static int opBSR_w_a32(uint32_t fetchdat) int instr_cycles; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); @@ -116,6 +128,8 @@ static int opBSR_l_a16(uint32_t fetchdat) int instr_cycles; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); @@ -131,6 +145,8 @@ static int opBSR_l_a32(uint32_t fetchdat) int instr_cycles; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); diff --git a/src/x86_ops_call.h b/src/x86_ops_call.h index bbb5dca..aa126c6 100644 --- a/src/x86_ops_call.h +++ b/src/x86_ops_call.h @@ -104,6 +104,8 @@ static int opFF_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + 1); if (cpu_state.abrt) return 1; setadd16nc(temp, 1); @@ -111,6 +113,8 @@ static int opFF_w_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); break; case 0x08: /*DEC w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp - 1); if (cpu_state.abrt) return 1; setsub16nc(temp, 1); @@ -118,6 +122,8 @@ static int opFF_w_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); break; case 0x10: /*CALL*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteaw(); if (cpu_state.abrt) return 1; PUSH_W(cpu_state.pc); cpu_state.pc = new_pc; @@ -128,6 +134,8 @@ static int opFF_w_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x18: /*CALL far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = readmemw(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; @@ -137,6 +145,8 @@ static int opFF_w_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x20: /*JMP*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteaw(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); @@ -146,6 +156,8 @@ static int opFF_w_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x28: /*JMP far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); oxpc = cpu_state.pc; new_pc = readmemw(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; @@ -156,6 +168,8 @@ static int opFF_w_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x30: /*PUSH w*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; PUSH_W(temp); CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); @@ -181,6 +195,8 @@ static int opFF_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp + 1); if (cpu_state.abrt) return 1; setadd16nc(temp, 1); @@ -188,6 +204,8 @@ static int opFF_w_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); break; case 0x08: /*DEC w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(temp - 1); if (cpu_state.abrt) return 1; setsub16nc(temp, 1); @@ -195,6 +213,8 @@ static int opFF_w_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); break; case 0x10: /*CALL*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteaw(); if (cpu_state.abrt) return 1; PUSH_W(cpu_state.pc); cpu_state.pc = new_pc; @@ -205,6 +225,8 @@ static int opFF_w_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x18: /*CALL far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = readmemw(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; @@ -214,6 +236,8 @@ static int opFF_w_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x20: /*JMP*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteaw(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); @@ -223,6 +247,8 @@ static int opFF_w_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x28: /*JMP far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); oxpc = cpu_state.pc; new_pc = readmemw(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; @@ -233,6 +259,8 @@ static int opFF_w_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x30: /*PUSH w*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; PUSH_W(temp); CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); @@ -259,6 +287,8 @@ static int opFF_l_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + 1); if (cpu_state.abrt) return 1; setadd32nc(temp, 1); @@ -266,6 +296,8 @@ static int opFF_l_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); break; case 0x08: /*DEC l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp - 1); if (cpu_state.abrt) return 1; setsub32nc(temp, 1); @@ -273,6 +305,8 @@ static int opFF_l_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); break; case 0x10: /*CALL*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteal(); if (cpu_state.abrt) return 1; PUSH_L(cpu_state.pc); cpu_state.pc = new_pc; @@ -283,6 +317,8 @@ static int opFF_l_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x18: /*CALL far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = readmeml(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; @@ -292,6 +328,8 @@ static int opFF_l_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x20: /*JMP*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteal(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); @@ -301,6 +339,8 @@ static int opFF_l_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x28: /*JMP far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); oxpc = cpu_state.pc; new_pc = readmeml(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; @@ -311,6 +351,8 @@ static int opFF_l_a16(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x30: /*PUSH l*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; PUSH_L(temp); CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); @@ -336,6 +378,8 @@ static int opFF_l_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*INC l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp + 1); if (cpu_state.abrt) return 1; setadd32nc(temp, 1); @@ -343,6 +387,8 @@ static int opFF_l_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); break; case 0x08: /*DEC l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(temp - 1); if (cpu_state.abrt) return 1; setsub32nc(temp, 1); @@ -350,6 +396,8 @@ static int opFF_l_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); break; case 0x10: /*CALL*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteal(); if (cpu_state.abrt) return 1; PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; @@ -360,6 +408,8 @@ static int opFF_l_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x18: /*CALL far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = readmeml(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; @@ -369,6 +419,8 @@ static int opFF_l_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x20: /*JMP*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_pc = geteal(); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; CPU_BLOCK_END(); @@ -378,6 +430,8 @@ static int opFF_l_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x28: /*JMP far*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); oxpc = cpu_state.pc; new_pc = readmeml(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; @@ -388,6 +442,8 @@ static int opFF_l_a32(uint32_t fetchdat) PREFETCH_FLUSH(); break; case 0x30: /*PUSH l*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; PUSH_L(temp); PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); diff --git a/src/x86_ops_inc_dec.h b/src/x86_ops_inc_dec.h index b13070c..8b9509b 100644 --- a/src/x86_ops_inc_dec.h +++ b/src/x86_ops_inc_dec.h @@ -50,6 +50,8 @@ static int opINCDEC_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp=geteab(); if (cpu_state.abrt) return 1; if (rmdat&0x38) @@ -71,6 +73,8 @@ static int opINCDEC_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp=geteab(); if (cpu_state.abrt) return 1; if (rmdat&0x38) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index 43c0d97..354059d 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -54,6 +54,7 @@ static int opF6_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); } dst = geteab(); if (cpu_state.abrt) return 1; @@ -68,11 +69,15 @@ static int opF6_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteab(~dst); if (cpu_state.abrt) return 1; CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); break; case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteab(0 - dst); if (cpu_state.abrt) return 1; setsub8(0, dst); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); @@ -156,6 +161,8 @@ static int opF6_a32(uint32_t fetchdat) int8_t temps; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteab(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) { @@ -168,11 +175,15 @@ static int opF6_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteab(~dst); if (cpu_state.abrt) return 1; CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); break; case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteab(0 - dst); if (cpu_state.abrt) return 1; setsub8(0, dst); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); @@ -259,6 +270,8 @@ static int opF7_w_a16(uint32_t fetchdat) uint16_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) { @@ -271,11 +284,15 @@ static int opF7_w_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(~dst); if (cpu_state.abrt) return 1; CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); break; case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(0 - dst); if (cpu_state.abrt) return 1; setsub16(0, dst); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); @@ -353,6 +370,8 @@ static int opF7_w_a32(uint32_t fetchdat) uint16_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteaw(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) { @@ -365,11 +384,15 @@ static int opF7_w_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(~dst); if (cpu_state.abrt) return 1; CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); break; case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(0 - dst); if (cpu_state.abrt) return 1; setsub16(0, dst); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); @@ -446,6 +469,8 @@ static int opF7_l_a16(uint32_t fetchdat) uint32_t src, dst; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) @@ -459,11 +484,15 @@ static int opF7_l_a16(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); break; case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(~dst); if (cpu_state.abrt) return 1; CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); break; case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(0 - dst); if (cpu_state.abrt) return 1; setsub32(0, dst); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); @@ -516,6 +545,8 @@ static int opF7_l_a32(uint32_t fetchdat) uint32_t src, dst; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); dst = geteal(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) @@ -529,11 +560,15 @@ static int opF7_l_a32(uint32_t fetchdat) PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); break; case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(~dst); if (cpu_state.abrt) return 1; CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); break; case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(0 - dst); if (cpu_state.abrt) return 1; setsub32(0, dst); CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); @@ -625,6 +660,7 @@ static int opBOUND_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); low = geteaw(); high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; @@ -644,6 +680,7 @@ static int opBOUND_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); low = geteaw(); high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; @@ -664,6 +701,7 @@ static int opBOUND_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); low = geteal(); high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; @@ -683,6 +721,7 @@ static int opBOUND_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); low = geteal(); high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; diff --git a/src/x86_ops_mmx.h b/src/x86_ops_mmx.h index 4397a39..4f361c6 100644 --- a/src/x86_ops_mmx.h +++ b/src/x86_ops_mmx.h @@ -11,6 +11,7 @@ } \ else \ { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ CLOCK_CYCLES(2); \ } diff --git a/src/x86_ops_mmx_arith.h b/src/x86_ops_mmx_arith.h index 0a66eea..231662c 100644 --- a/src/x86_ops_mmx_arith.h +++ b/src/x86_ops_mmx_arith.h @@ -293,7 +293,8 @@ static int opPMULLW_a16(uint32_t fetchdat) else { MMX_REG src; - + + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] *= src.w[0]; @@ -321,6 +322,7 @@ static int opPMULLW_a32(uint32_t fetchdat) { MMX_REG src; + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] *= src.w[0]; @@ -349,6 +351,7 @@ static int opPMULHW_a16(uint32_t fetchdat) { MMX_REG src; + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; @@ -376,6 +379,7 @@ static int opPMULHW_a32(uint32_t fetchdat) { MMX_REG src; + SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; diff --git a/src/x86_ops_mmx_mov.h b/src/x86_ops_mmx_mov.h index 37899b3..133d48d 100644 --- a/src/x86_ops_mmx_mov.h +++ b/src/x86_ops_mmx_mov.h @@ -12,7 +12,8 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat) else { uint32_t dst; - + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].l[0] = dst; cpu_state.MM[cpu_reg].l[1] = 0; @@ -35,7 +36,8 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat) else { uint32_t dst; - + + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].l[0] = dst; cpu_state.MM[cpu_reg].l[1] = 0; @@ -57,6 +59,7 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -75,6 +78,7 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -96,6 +100,7 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -116,6 +121,7 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) { uint64_t dst; + SEG_CHECK_READ(cpu_state.ea_seg); dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; cpu_state.MM[cpu_reg].q = dst; CLOCK_CYCLES(2); @@ -135,6 +141,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); @@ -153,6 +160,7 @@ static int opMOVQ_mm_q_a32(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; CLOCK_CYCLES(2); diff --git a/src/x86_ops_mmx_pack.h b/src/x86_ops_mmx_pack.h index cdba2a2..5b8b798 100644 --- a/src/x86_ops_mmx_pack.h +++ b/src/x86_ops_mmx_pack.h @@ -12,6 +12,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { uint32_t src; + SEG_CHECK_READ(cpu_state.ea_seg); src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].l[1] = src; @@ -32,7 +33,8 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat) else { uint32_t src; - + + SEG_CHECK_READ(cpu_state.ea_seg); src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; cpu_state.MM[cpu_reg].l[1] = src; diff --git a/src/x86_ops_mmx_shift.h b/src/x86_ops_mmx_shift.h index ad3fc16..d641279 100644 --- a/src/x86_ops_mmx_shift.h +++ b/src/x86_ops_mmx_shift.h @@ -6,6 +6,7 @@ } \ else \ { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ CLOCK_CYCLES(2); \ } diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index 64072bf..6a0a087 100644 --- a/src/x86_ops_mov.h +++ b/src/x86_ops_mov.h @@ -182,6 +182,7 @@ static int opMOV_b_imm_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); 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); @@ -194,6 +195,7 @@ static int opMOV_b_imm_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getbyte(); if (cpu_state.abrt) return 1; seteab(temp); CLOCK_CYCLES(timing_rr); @@ -206,6 +208,7 @@ static int opMOV_w_imm_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getword(); if (cpu_state.abrt) return 1; seteaw(temp); CLOCK_CYCLES(timing_rr); @@ -217,6 +220,7 @@ static int opMOV_w_imm_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getword(); if (cpu_state.abrt) return 1; seteaw(temp); CLOCK_CYCLES(timing_rr); @@ -228,6 +232,7 @@ static int opMOV_l_imm_a16(uint32_t fetchdat) uint32_t temp; fetch_ea_16(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getlong(); if (cpu_state.abrt) return 1; seteal(temp); CLOCK_CYCLES(timing_rr); @@ -239,6 +244,7 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) uint32_t temp; fetch_ea_32(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = getlong(); if (cpu_state.abrt) return 1; seteal(temp); CLOCK_CYCLES(timing_rr); @@ -251,6 +257,7 @@ static int opMOV_AL_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, addr, addr); temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AL = temp; @@ -262,6 +269,7 @@ static int opMOV_AL_a32(uint32_t fetchdat) { uint32_t addr = getlong(); uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, addr, addr); temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AL = temp; @@ -273,6 +281,7 @@ static int opMOV_AX_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); uint16_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, addr, addr+1); temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AX = temp; @@ -284,6 +293,7 @@ static int opMOV_AX_a32(uint32_t fetchdat) { uint32_t addr = getlong(); uint16_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, addr, addr+1); temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AX = temp; @@ -295,6 +305,7 @@ static int opMOV_EAX_a16(uint32_t fetchdat) { uint16_t addr = getwordf(); uint32_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, addr, addr+3); temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; EAX = temp; @@ -306,6 +317,7 @@ static int opMOV_EAX_a32(uint32_t fetchdat) { uint32_t addr = getlong(); uint32_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, addr, addr+3); temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; EAX = temp; @@ -317,6 +329,7 @@ static int opMOV_EAX_a32(uint32_t fetchdat) static int opMOV_a16_AL(uint32_t fetchdat) { uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); writememb(cpu_state.ea_seg->base, addr, AL); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -325,6 +338,7 @@ static int opMOV_a16_AL(uint32_t fetchdat) static int opMOV_a32_AL(uint32_t fetchdat) { uint32_t addr = getlong(); + SEG_CHECK_WRITE(cpu_state.ea_seg); writememb(cpu_state.ea_seg->base, addr, AL); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); @@ -333,6 +347,7 @@ static int opMOV_a32_AL(uint32_t fetchdat) static int opMOV_a16_AX(uint32_t fetchdat) { uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); @@ -341,6 +356,7 @@ static int opMOV_a16_AX(uint32_t fetchdat) static int opMOV_a32_AX(uint32_t fetchdat) { uint32_t addr = getlong(); if (cpu_state.abrt) return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); writememw(cpu_state.ea_seg->base, addr, AX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); @@ -349,6 +365,7 @@ static int opMOV_a32_AX(uint32_t fetchdat) static int opMOV_a16_EAX(uint32_t fetchdat) { uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); @@ -357,6 +374,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat) static int opMOV_a32_EAX(uint32_t fetchdat) { uint32_t addr = getlong(); if (cpu_state.abrt) return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); writememl(cpu_state.ea_seg->base, addr, EAX); CLOCK_CYCLES((is486) ? 1 : 2); PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); @@ -407,7 +425,10 @@ static int opLEA_l_a32(uint32_t fetchdat) static int opXLAT_a16(uint32_t fetchdat) { uint32_t addr = (BX + AL)&0xFFFF; - uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AL = temp; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); @@ -416,7 +437,10 @@ static int opXLAT_a16(uint32_t fetchdat) static int opXLAT_a32(uint32_t fetchdat) { uint32_t addr = EBX + AL; - uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AL = temp; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); @@ -434,6 +458,7 @@ static int opMOV_b_r_a16(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(getr8(cpu_reg)); CLOCK_CYCLES(is486 ? 1 : 2); @@ -452,6 +477,7 @@ static int opMOV_b_r_a32(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(getr8(cpu_reg)); CLOCK_CYCLES(is486 ? 1 : 2); @@ -470,6 +496,7 @@ static int opMOV_w_r_a16(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); seteaw(cpu_state.regs[cpu_reg].w); CLOCK_CYCLES(is486 ? 1 : 2); @@ -488,6 +515,7 @@ static int opMOV_w_r_a32(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); seteaw(cpu_state.regs[cpu_reg].w); CLOCK_CYCLES(is486 ? 1 : 2); @@ -506,6 +534,7 @@ static int opMOV_l_r_a16(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); seteal(cpu_state.regs[cpu_reg].l); CLOCK_CYCLES(is486 ? 1 : 2); @@ -524,6 +553,7 @@ static int opMOV_l_r_a32(uint32_t fetchdat) } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); seteal(cpu_state.regs[cpu_reg].l); CLOCK_CYCLES(is486 ? 1 : 2); @@ -544,6 +574,7 @@ static int opMOV_r_b_a16(uint32_t fetchdat) else { uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); temp = geteab(); if (cpu_state.abrt) return 1; setr8(cpu_reg, temp); @@ -564,6 +595,7 @@ static int opMOV_r_b_a32(uint32_t fetchdat) else { uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); temp = geteab(); if (cpu_state.abrt) return 1; setr8(cpu_reg, temp); @@ -584,6 +616,7 @@ static int opMOV_r_w_a16(uint32_t fetchdat) else { uint16_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = temp; @@ -604,6 +637,7 @@ static int opMOV_r_w_a32(uint32_t fetchdat) else { uint16_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = temp; @@ -624,6 +658,7 @@ static int opMOV_r_l_a16(uint32_t fetchdat) else { uint32_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); temp = geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp; @@ -644,6 +679,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) else { uint32_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); temp = geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp; @@ -664,6 +700,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) else \ { \ uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ temp = geteaw(); if (cpu_state.abrt) return 1; \ cpu_state.regs[cpu_reg].w = temp; \ @@ -682,6 +719,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) else \ { \ uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ temp = geteaw(); if (cpu_state.abrt) return 1; \ cpu_state.regs[cpu_reg].w = temp; \ @@ -700,6 +738,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) else \ { \ uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ temp = geteal(); if (cpu_state.abrt) return 1; \ cpu_state.regs[cpu_reg].l = temp; \ @@ -719,6 +758,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat) { \ uint32_t temp; \ CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ temp = geteal(); if (cpu_state.abrt) return 1; \ cpu_state.regs[cpu_reg].l = temp; \ } \ diff --git a/src/x86_ops_mov_seg.h b/src/x86_ops_mov_seg.h index 5153bb1..ecaeba1 100644 --- a/src/x86_ops_mov_seg.h +++ b/src/x86_ops_mov_seg.h @@ -1,7 +1,9 @@ static int opMOV_w_seg_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + switch (rmdat & 0x38) { case 0x00: /*ES*/ @@ -31,7 +33,9 @@ static int opMOV_w_seg_a16(uint32_t fetchdat) static int opMOV_w_seg_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + switch (rmdat & 0x38) { case 0x00: /*ES*/ @@ -62,7 +66,9 @@ static int opMOV_w_seg_a32(uint32_t fetchdat) static int opMOV_l_seg_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + switch (rmdat & 0x38) { case 0x00: /*ES*/ @@ -98,7 +104,9 @@ static int opMOV_l_seg_a16(uint32_t fetchdat) static int opMOV_l_seg_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + switch (rmdat & 0x38) { case 0x00: /*ES*/ @@ -137,7 +145,8 @@ static int opMOV_seg_w_a16(uint32_t fetchdat) uint16_t new_seg; fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_seg=geteaw(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) @@ -177,7 +186,8 @@ static int opMOV_seg_w_a32(uint32_t fetchdat) uint16_t new_seg; fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); new_seg=geteaw(); if (cpu_state.abrt) return 1; switch (rmdat & 0x38) @@ -220,6 +230,7 @@ static int opLDS_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; loadseg(seg, &_ds); if (cpu_state.abrt) return 1; @@ -235,6 +246,7 @@ static int opLDS_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; loadseg(seg, &_ds); if (cpu_state.abrt) return 1; @@ -251,6 +263,7 @@ static int opLDS_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; loadseg(seg, &_ds); if (cpu_state.abrt) return 1; @@ -267,6 +280,7 @@ static int opLDS_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; loadseg(seg, &_ds); if (cpu_state.abrt) return 1; @@ -283,6 +297,7 @@ static int opLSS_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; loadseg(seg, &_ss); if (cpu_state.abrt) return 1; @@ -298,6 +313,7 @@ static int opLSS_w_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; loadseg(seg, &_ss); if (cpu_state.abrt) return 1; @@ -314,6 +330,7 @@ static int opLSS_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; loadseg(seg, &_ss); if (cpu_state.abrt) return 1; @@ -330,6 +347,7 @@ static int opLSS_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; loadseg(seg, &_ss); if (cpu_state.abrt) return 1; @@ -346,6 +364,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t addr, seg; \ \ fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ ILLEGAL_ON(cpu_mod == 3); \ addr = readmemw(easeg, cpu_state.eaaddr); \ seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ @@ -362,6 +381,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t addr, seg; \ \ fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ ILLEGAL_ON(cpu_mod == 3); \ addr = readmemw(easeg, cpu_state.eaaddr); \ seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ @@ -379,6 +399,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t seg; \ \ fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ ILLEGAL_ON(cpu_mod == 3); \ addr = readmeml(easeg, cpu_state.eaaddr); \ seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ @@ -396,6 +417,7 @@ static int opLSS_l_a32(uint32_t fetchdat) uint16_t seg; \ \ fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ ILLEGAL_ON(cpu_mod == 3); \ addr = readmeml(easeg, cpu_state.eaaddr); \ seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ diff --git a/src/x86_ops_movx.h b/src/x86_ops_movx.h index 9dfced8..2f679b0 100644 --- a/src/x86_ops_movx.h +++ b/src/x86_ops_movx.h @@ -3,6 +3,8 @@ static int opMOVZX_w_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = (uint16_t)temp; @@ -15,6 +17,8 @@ static int opMOVZX_w_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = (uint16_t)temp; @@ -27,6 +31,8 @@ static int opMOVZX_l_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; @@ -39,6 +45,8 @@ static int opMOVZX_l_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; @@ -51,6 +59,8 @@ static int opMOVZX_w_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = temp; @@ -63,6 +73,8 @@ static int opMOVZX_w_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = temp; @@ -75,6 +87,8 @@ static int opMOVZX_l_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; @@ -87,6 +101,8 @@ static int opMOVZX_l_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; @@ -100,6 +116,8 @@ static int opMOVSX_w_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = (uint16_t)temp; if (temp & 0x80) @@ -114,6 +132,8 @@ static int opMOVSX_w_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = (uint16_t)temp; if (temp & 0x80) @@ -128,6 +148,8 @@ static int opMOVSX_l_b_a16(uint32_t fetchdat) uint8_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; if (temp & 0x80) @@ -142,6 +164,8 @@ static int opMOVSX_l_b_a32(uint32_t fetchdat) uint8_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; if (temp & 0x80) @@ -156,6 +180,8 @@ static int opMOVSX_l_w_a16(uint32_t fetchdat) uint16_t temp; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; if (temp & 0x8000) @@ -170,6 +196,8 @@ static int opMOVSX_l_w_a32(uint32_t fetchdat) uint16_t temp; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = (uint32_t)temp; if (temp & 0x8000) diff --git a/src/x86_ops_mul.h b/src/x86_ops_mul.h index 9a316b9..27778b0 100644 --- a/src/x86_ops_mul.h +++ b/src/x86_ops_mul.h @@ -4,7 +4,9 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) int16_t tempw, tempw2; fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getword(); if (cpu_state.abrt) return 1; @@ -24,7 +26,9 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) int16_t tempw, tempw2; fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getword(); if (cpu_state.abrt) return 1; @@ -45,7 +49,9 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) int32_t templ, templ2; fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getlong(); if (cpu_state.abrt) return 1; @@ -65,7 +71,9 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) int32_t templ, templ2; fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getlong(); if (cpu_state.abrt) return 1; @@ -86,7 +94,9 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) int16_t tempw, tempw2; fetch_ea_16(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getbyte(); if (cpu_state.abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; @@ -107,7 +117,9 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) int16_t tempw, tempw2; fetch_ea_32(fetchdat); - + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); if (cpu_state.abrt) return 1; tempw2 = getbyte(); if (cpu_state.abrt) return 1; if (tempw2 & 0x80) tempw2 |= 0xff00; @@ -129,6 +141,9 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) int32_t templ, templ2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getbyte(); if (cpu_state.abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; @@ -149,6 +164,9 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) int32_t templ, templ2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); if (cpu_state.abrt) return 1; templ2 = getbyte(); if (cpu_state.abrt) return 1; if (templ2 & 0x80) templ2 |= 0xffffff00; @@ -171,6 +189,9 @@ static int opIMUL_w_w_a16(uint32_t fetchdat) int32_t templ; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = templ & 0xFFFF; @@ -187,6 +208,9 @@ static int opIMUL_w_w_a32(uint32_t fetchdat) int32_t templ; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = templ & 0xFFFF; @@ -204,6 +228,9 @@ static int opIMUL_l_l_a16(uint32_t fetchdat) int64_t temp64; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; @@ -220,6 +247,9 @@ static int opIMUL_l_l_a32(uint32_t fetchdat) int64_t temp64; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index 288d1bb..a59340b 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -4,6 +4,8 @@ static int opARPL_a16(uint32_t fetchdat) NOTRM fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); pclog("ARPL_a16\n"); temp_seg = geteaw(); if (cpu_state.abrt) return 1; @@ -27,7 +29,9 @@ static int opARPL_a32(uint32_t fetchdat) NOTRM fetch_ea_32(fetchdat); - pclog("ARPL_a32\n"); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + pclog("ARPL_a32\n"); temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -53,6 +57,8 @@ static int opARPL_a32(uint32_t fetchdat) \ NOTRM \ fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ \ sel = geteaw(); if (cpu_state.abrt) return 1; \ \ @@ -103,6 +109,8 @@ opLAR(l_a32, fetch_ea_32, 1, 1) \ NOTRM \ fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ \ sel = geteaw(); if (cpu_state.abrt) return 1; \ flags_rebuild(); \ @@ -163,11 +171,15 @@ static int op0F00_common(uint32_t fetchdat, int ea32) switch (rmdat & 0x38) { case 0x00: /*SLDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(ldt.seg); CLOCK_CYCLES(4); PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; case 0x08: /*STR*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(tr.seg); CLOCK_CYCLES(4); PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); @@ -179,6 +191,8 @@ static int op0F00_common(uint32_t fetchdat, int ea32) x86gpf(NULL,0); return 1; } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); sel = geteaw(); if (cpu_state.abrt) return 1; addr = (sel & ~7) + gdt.base; limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); @@ -205,6 +219,8 @@ static int op0F00_common(uint32_t fetchdat, int ea32) x86gpf(NULL,0); break; } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); sel = geteaw(); if (cpu_state.abrt) return 1; addr = (sel & ~7) + gdt.base; limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); @@ -228,6 +244,8 @@ static int op0F00_common(uint32_t fetchdat, int ea32) PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); break; case 0x20: /*VERR*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); sel = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); flags &= ~Z_FLAG; @@ -248,6 +266,8 @@ static int op0F00_common(uint32_t fetchdat, int ea32) PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); break; case 0x28: /*VERW*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); sel = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); flags &= ~Z_FLAG; @@ -300,6 +320,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) switch (rmdat & 0x38) { case 0x00: /*SGDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(gdt.limit); base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); if (is286) @@ -309,6 +331,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); break; case 0x08: /*SIDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(idt.limit); base = idt.base; if (is286) @@ -324,6 +348,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) x86gpf(NULL,0); break; } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); // pclog("LGDT %08X:%08X\n", easeg, eaaddr); limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; @@ -341,6 +367,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) x86gpf(NULL,0); break; } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); // pclog("LIDT %08X:%08X\n", easeg, eaaddr); limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; @@ -353,6 +381,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) break; case 0x20: /*SMSW*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); if (is486) seteaw(msw); else if (is386) seteaw(msw | 0xFF00); else seteaw(msw | 0xFFF0); @@ -366,6 +396,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) x86gpf(NULL, 0); break; } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); tempw = geteaw(); if (cpu_state.abrt) return 1; if (msw & 1) tempw |= 1; if (is386) @@ -391,6 +423,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) x86gpf(NULL, 0); break; } + SEG_CHECK_READ(cpu_state.ea_seg); mmu_invalidate(ds + cpu_state.eaaddr); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index 66587ef..5b24beb 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -9,7 +9,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) { \ uint8_t temp; \ \ - check_io_perm(DX); \ + SEG_CHECK_WRITE(&_es); \ + check_io_perm(DX); \ temp = inb(DX); \ writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ @@ -36,6 +37,7 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) { \ uint16_t temp; \ \ + SEG_CHECK_WRITE(&_es); \ check_io_perm(DX); \ check_io_perm(DX+1); \ temp = inw(DX); \ @@ -64,6 +66,7 @@ static int opREP_INSL_ ## size(uint32_t fetchdat) { \ uint32_t temp; \ \ + SEG_CHECK_WRITE(&_es); \ check_io_perm(DX); \ check_io_perm(DX+1); \ check_io_perm(DX+2); \ @@ -93,7 +96,9 @@ static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ if (CNT_REG > 0) \ { \ - uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ outb(DX, temp); \ if (flags & D_FLAG) SRC_REG--; \ @@ -117,7 +122,9 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ if (CNT_REG > 0) \ { \ - uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ check_io_perm(DX+1); \ outw(DX, temp); \ @@ -142,7 +149,9 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ if (CNT_REG > 0) \ { \ - uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ check_io_perm(DX+1); \ check_io_perm(DX+2); \ @@ -170,6 +179,11 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&_es); \ + } \ while (CNT_REG > 0) \ { \ uint8_t temp; \ @@ -203,6 +217,11 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&_es); \ + } \ while (CNT_REG > 0) \ { \ uint16_t temp; \ @@ -236,6 +255,11 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&_es); \ + } \ while (CNT_REG > 0) \ { \ uint32_t temp; \ @@ -271,6 +295,8 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&_es); \ while (CNT_REG > 0) \ { \ CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ @@ -299,6 +325,8 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&_es); \ while (CNT_REG > 0) \ { \ CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \ @@ -327,6 +355,8 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&_es); \ while (CNT_REG > 0) \ { \ CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \ @@ -356,6 +386,8 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ @@ -383,6 +415,8 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ @@ -410,6 +444,8 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ while (CNT_REG > 0) \ { \ EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ @@ -441,8 +477,11 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ { \ - uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ - uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&_es); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ else { DEST_REG++; SRC_REG++; } \ @@ -468,8 +507,11 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ { \ - uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ - uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&_es); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ else { DEST_REG += 2; SRC_REG += 2; } \ @@ -495,8 +537,11 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat) tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ { \ - uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ - uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&_es); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ else { DEST_REG += 4; SRC_REG += 4; } \ @@ -523,6 +568,8 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat) if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ @@ -554,6 +601,8 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat) if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ @@ -585,6 +634,8 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat) if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ diff --git a/src/x86_ops_set.h b/src/x86_ops_set.h index 298f28c..5a3dfaa 100644 --- a/src/x86_ops_set.h +++ b/src/x86_ops_set.h @@ -2,6 +2,8 @@ static int opSET ## condition ## _a16(uint32_t fetchdat) \ { \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ seteab((cond_ ## condition) ? 1 : 0); \ CLOCK_CYCLES(4); \ return cpu_state.abrt; \ @@ -10,6 +12,8 @@ static int opSET ## condition ## _a32(uint32_t fetchdat) \ { \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ seteab((cond_ ## condition) ? 1 : 0); \ CLOCK_CYCLES(4); \ return cpu_state.abrt; \ diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index 5144d10..1fe2e89 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -281,6 +281,8 @@ static int opC0_a16(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; PREFETCH_PREFIX(); temp = geteab(); if (cpu_state.abrt) return 1; @@ -294,6 +296,8 @@ static int opC0_a32(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; PREFETCH_PREFIX(); temp = geteab(); if (cpu_state.abrt) return 1; @@ -307,6 +311,8 @@ static int opC1_w_a16(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; PREFETCH_PREFIX(); temp = geteaw(); if (cpu_state.abrt) return 1; @@ -320,6 +326,8 @@ static int opC1_w_a32(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; PREFETCH_PREFIX(); temp = geteaw(); if (cpu_state.abrt) return 1; @@ -333,6 +341,8 @@ static int opC1_l_a16(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; PREFETCH_PREFIX(); temp = geteal(); if (cpu_state.abrt) return 1; @@ -346,6 +356,8 @@ static int opC1_l_a32(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; PREFETCH_PREFIX(); temp = geteal(); if (cpu_state.abrt) return 1; @@ -360,6 +372,8 @@ static int opD0_a16(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; OP_SHIFT_b(c, 0); return 0; @@ -371,6 +385,8 @@ static int opD0_a32(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; OP_SHIFT_b(c, 1); return 0; @@ -382,6 +398,8 @@ static int opD1_w_a16(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; OP_SHIFT_w(c, 0); return 0; @@ -393,6 +411,8 @@ static int opD1_w_a32(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; OP_SHIFT_w(c, 1); return 0; @@ -404,6 +424,8 @@ static int opD1_l_a16(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; OP_SHIFT_l(c, 0); return 0; @@ -415,6 +437,8 @@ static int opD1_l_a32(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; OP_SHIFT_l(c, 1); return 0; @@ -427,6 +451,8 @@ static int opD2_a16(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = CL & 31; temp = geteab(); if (cpu_state.abrt) return 1; OP_SHIFT_b(c, 0); @@ -439,6 +465,8 @@ static int opD2_a32(uint32_t fetchdat) uint8_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = CL & 31; temp = geteab(); if (cpu_state.abrt) return 1; OP_SHIFT_b(c, 1); @@ -451,6 +479,8 @@ static int opD3_w_a16(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = CL & 31; temp = geteaw(); if (cpu_state.abrt) return 1; OP_SHIFT_w(c, 0); @@ -463,6 +493,8 @@ static int opD3_w_a32(uint32_t fetchdat) uint16_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = CL & 31; temp = geteaw(); if (cpu_state.abrt) return 1; OP_SHIFT_w(c, 1); @@ -475,6 +507,8 @@ static int opD3_l_a16(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = CL & 31; temp = geteal(); if (cpu_state.abrt) return 1; OP_SHIFT_l(c, 0); @@ -487,6 +521,8 @@ static int opD3_l_a32(uint32_t fetchdat) uint32_t temp, temp2; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); c = CL & 31; temp = geteal(); if (cpu_state.abrt) return 1; OP_SHIFT_l(c, 1); @@ -552,6 +588,8 @@ static int opD3_l_a32(uint32_t fetchdat) int count; \ \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = getbyte() & 31; \ operation(); \ \ @@ -564,6 +602,8 @@ static int opD3_l_a32(uint32_t fetchdat) int count; \ \ fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = CL & 31; \ operation(); \ \ @@ -576,6 +616,8 @@ static int opD3_l_a32(uint32_t fetchdat) int count; \ \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = getbyte() & 31; \ operation(); \ \ @@ -588,6 +630,8 @@ static int opD3_l_a32(uint32_t fetchdat) int count; \ \ fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ count = CL & 31; \ operation(); \ \ diff --git a/src/x86_ops_stack.h b/src/x86_ops_stack.h index 31f0908..dbe333f 100644 --- a/src/x86_ops_stack.h +++ b/src/x86_ops_stack.h @@ -236,6 +236,8 @@ static int opPOPW_a16(uint32_t fetchdat) temp = POP_W(); if (cpu_state.abrt) return 1; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(temp); if (cpu_state.abrt) { @@ -255,6 +257,8 @@ static int opPOPW_a32(uint32_t fetchdat) temp = POP_W(); if (cpu_state.abrt) return 1; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(temp); if (cpu_state.abrt) { @@ -275,6 +279,8 @@ static int opPOPL_a16(uint32_t fetchdat) temp = POP_L(); if (cpu_state.abrt) return 1; fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(temp); if (cpu_state.abrt) { @@ -294,6 +300,8 @@ static int opPOPL_a32(uint32_t fetchdat) temp = POP_L(); if (cpu_state.abrt) return 1; fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(temp); if (cpu_state.abrt) { diff --git a/src/x86_ops_string.h b/src/x86_ops_string.h index b08460b..d76b3f8 100644 --- a/src/x86_ops_string.h +++ b/src/x86_ops_string.h @@ -1,6 +1,10 @@ static int opMOVSB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&_es); + temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememb(es, DI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } @@ -10,7 +14,11 @@ static int opMOVSB_a16(uint32_t fetchdat) } static int opMOVSB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&_es); + temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememb(es, EDI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } @@ -21,7 +29,11 @@ static int opMOVSB_a32(uint32_t fetchdat) static int opMOVSW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&_es); + temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememw(es, DI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } @@ -31,7 +43,11 @@ static int opMOVSW_a16(uint32_t fetchdat) } static int opMOVSW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&_es); + temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememw(es, EDI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } @@ -42,7 +58,11 @@ static int opMOVSW_a32(uint32_t fetchdat) static int opMOVSL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&_es); + temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememl(es, DI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } @@ -52,7 +72,11 @@ static int opMOVSL_a16(uint32_t fetchdat) } static int opMOVSL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&_es); + temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememl(es, EDI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } @@ -64,8 +88,12 @@ static int opMOVSL_a32(uint32_t fetchdat) static int opCMPSB_a16(uint32_t fetchdat) { - uint8_t src = readmemb(cpu_state.ea_seg->base, SI); - uint8_t dst = readmemb(es, DI); if (cpu_state.abrt) return 1; + uint8_t src, dst; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&_es); + src = readmemb(cpu_state.ea_seg->base, SI); + dst = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(src, dst); if (flags & D_FLAG) { DI--; SI--; } else { DI++; SI++; } @@ -75,8 +103,12 @@ static int opCMPSB_a16(uint32_t fetchdat) } static int opCMPSB_a32(uint32_t fetchdat) { - uint8_t src = readmemb(cpu_state.ea_seg->base, ESI); - uint8_t dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; + uint8_t src, dst; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&_es); + src = readmemb(cpu_state.ea_seg->base, ESI); + dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(src, dst); if (flags & D_FLAG) { EDI--; ESI--; } else { EDI++; ESI++; } @@ -87,8 +119,12 @@ static int opCMPSB_a32(uint32_t fetchdat) static int opCMPSW_a16(uint32_t fetchdat) { - uint16_t src = readmemw(cpu_state.ea_seg->base, SI); - uint16_t dst = readmemw(es, DI); if (cpu_state.abrt) return 1; + uint16_t src, dst; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&_es); + src = readmemw(cpu_state.ea_seg->base, SI); + dst = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(src, dst); if (flags & D_FLAG) { DI -= 2; SI -= 2; } else { DI += 2; SI += 2; } @@ -98,8 +134,12 @@ static int opCMPSW_a16(uint32_t fetchdat) } static int opCMPSW_a32(uint32_t fetchdat) { - uint16_t src = readmemw(cpu_state.ea_seg->base, ESI); - uint16_t dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; + uint16_t src, dst; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&_es); + src = readmemw(cpu_state.ea_seg->base, ESI); + dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(src, dst); if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } else { EDI += 2; ESI += 2; } @@ -110,8 +150,12 @@ static int opCMPSW_a32(uint32_t fetchdat) static int opCMPSL_a16(uint32_t fetchdat) { - uint32_t src = readmeml(cpu_state.ea_seg->base, SI); - uint32_t dst = readmeml(es, DI); if (cpu_state.abrt) return 1; + uint32_t src, dst; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&_es); + src = readmeml(cpu_state.ea_seg->base, SI); + dst = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(src, dst); if (flags & D_FLAG) { DI -= 4; SI -= 4; } else { DI += 4; SI += 4; } @@ -121,8 +165,12 @@ static int opCMPSL_a16(uint32_t fetchdat) } static int opCMPSL_a32(uint32_t fetchdat) { - uint32_t src = readmeml(cpu_state.ea_seg->base, ESI); - uint32_t dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; + uint32_t src, dst; + + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&_es); + src = readmeml(cpu_state.ea_seg->base, ESI); + dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(src, dst); if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } else { EDI += 4; ESI += 4; } @@ -133,6 +181,7 @@ static int opCMPSL_a32(uint32_t fetchdat) static int opSTOSB_a16(uint32_t fetchdat) { + SEG_CHECK_WRITE(&_es); writememb(es, DI, AL); if (cpu_state.abrt) return 1; if (flags & D_FLAG) DI--; else DI++; @@ -142,6 +191,7 @@ static int opSTOSB_a16(uint32_t fetchdat) } static int opSTOSB_a32(uint32_t fetchdat) { + SEG_CHECK_WRITE(&_es); writememb(es, EDI, AL); if (cpu_state.abrt) return 1; if (flags & D_FLAG) EDI--; else EDI++; @@ -152,6 +202,7 @@ static int opSTOSB_a32(uint32_t fetchdat) static int opSTOSW_a16(uint32_t fetchdat) { + SEG_CHECK_WRITE(&_es); writememw(es, DI, AX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) DI -= 2; else DI += 2; @@ -161,6 +212,7 @@ static int opSTOSW_a16(uint32_t fetchdat) } static int opSTOSW_a32(uint32_t fetchdat) { + SEG_CHECK_WRITE(&_es); writememw(es, EDI, AX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) EDI -= 2; else EDI += 2; @@ -171,6 +223,7 @@ static int opSTOSW_a32(uint32_t fetchdat) static int opSTOSL_a16(uint32_t fetchdat) { + SEG_CHECK_WRITE(&_es); writememl(es, DI, EAX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) DI -= 4; else DI += 4; @@ -180,6 +233,7 @@ static int opSTOSL_a16(uint32_t fetchdat) } static int opSTOSL_a32(uint32_t fetchdat) { + SEG_CHECK_WRITE(&_es); writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) EDI -= 4; else EDI += 4; @@ -191,7 +245,10 @@ static int opSTOSL_a32(uint32_t fetchdat) static int opLODSB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AL = temp; if (flags & D_FLAG) SI--; else SI++; @@ -201,7 +258,10 @@ static int opLODSB_a16(uint32_t fetchdat) } static int opLODSB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AL = temp; if (flags & D_FLAG) ESI--; else ESI++; @@ -212,7 +272,10 @@ static int opLODSB_a32(uint32_t fetchdat) static int opLODSW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AX = temp; if (flags & D_FLAG) SI -= 2; else SI += 2; @@ -222,7 +285,10 @@ static int opLODSW_a16(uint32_t fetchdat) } static int opLODSW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AX = temp; if (flags & D_FLAG) ESI -= 2; else ESI += 2; @@ -233,7 +299,10 @@ static int opLODSW_a32(uint32_t fetchdat) static int opLODSL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; EAX = temp; if (flags & D_FLAG) SI -= 4; else SI += 4; @@ -243,7 +312,10 @@ static int opLODSL_a16(uint32_t fetchdat) } static int opLODSL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; EAX = temp; if (flags & D_FLAG) ESI -= 4; else ESI += 4; @@ -255,7 +327,10 @@ static int opLODSL_a32(uint32_t fetchdat) static int opSCASB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(es, DI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(&_es); + temp = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (flags & D_FLAG) DI--; else DI++; @@ -265,7 +340,10 @@ static int opSCASB_a16(uint32_t fetchdat) } static int opSCASB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(&_es); + temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (flags & D_FLAG) EDI--; else EDI++; @@ -276,7 +354,10 @@ static int opSCASB_a32(uint32_t fetchdat) static int opSCASW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(es, DI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(&_es); + temp = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (flags & D_FLAG) DI -= 2; else DI += 2; @@ -286,7 +367,10 @@ static int opSCASW_a16(uint32_t fetchdat) } static int opSCASW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(&_es); + temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (flags & D_FLAG) EDI -= 2; else EDI += 2; @@ -297,7 +381,10 @@ static int opSCASW_a32(uint32_t fetchdat) static int opSCASL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(es, DI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(&_es); + temp = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (flags & D_FLAG) DI -= 4; else DI += 4; @@ -307,7 +394,10 @@ static int opSCASL_a16(uint32_t fetchdat) } static int opSCASL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(&_es); + temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (flags & D_FLAG) EDI -= 4; else EDI += 4; @@ -319,6 +409,8 @@ static int opSCASL_a32(uint32_t fetchdat) static int opINSB_a16(uint32_t fetchdat) { uint8_t temp; + + SEG_CHECK_WRITE(&_es); check_io_perm(DX); temp = inb(DX); writememb(es, DI, temp); if (cpu_state.abrt) return 1; @@ -331,6 +423,8 @@ static int opINSB_a16(uint32_t fetchdat) static int opINSB_a32(uint32_t fetchdat) { uint8_t temp; + + SEG_CHECK_WRITE(&_es); check_io_perm(DX); temp = inb(DX); writememb(es, EDI, temp); if (cpu_state.abrt) return 1; @@ -344,6 +438,8 @@ static int opINSB_a32(uint32_t fetchdat) static int opINSW_a16(uint32_t fetchdat) { uint16_t temp; + + SEG_CHECK_WRITE(&_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); @@ -357,6 +453,8 @@ static int opINSW_a16(uint32_t fetchdat) static int opINSW_a32(uint32_t fetchdat) { uint16_t temp; + + SEG_CHECK_WRITE(&_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); @@ -371,6 +469,8 @@ static int opINSW_a32(uint32_t fetchdat) static int opINSL_a16(uint32_t fetchdat) { uint32_t temp; + + SEG_CHECK_WRITE(&_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -386,6 +486,8 @@ static int opINSL_a16(uint32_t fetchdat) static int opINSL_a32(uint32_t fetchdat) { uint32_t temp; + + SEG_CHECK_WRITE(&_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -401,7 +503,10 @@ static int opINSL_a32(uint32_t fetchdat) static int opOUTSB_a16(uint32_t fetchdat) { - uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); if (flags & D_FLAG) SI--; else SI++; @@ -412,7 +517,10 @@ static int opOUTSB_a16(uint32_t fetchdat) } static int opOUTSB_a32(uint32_t fetchdat) { - uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); if (flags & D_FLAG) ESI--; else ESI++; @@ -424,7 +532,10 @@ static int opOUTSB_a32(uint32_t fetchdat) static int opOUTSW_a16(uint32_t fetchdat) { - uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); if (flags & D_FLAG) SI -= 2; @@ -436,7 +547,10 @@ static int opOUTSW_a16(uint32_t fetchdat) } static int opOUTSW_a32(uint32_t fetchdat) { - uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint16_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); if (flags & D_FLAG) ESI -= 2; @@ -449,7 +563,10 @@ static int opOUTSW_a32(uint32_t fetchdat) static int opOUTSL_a16(uint32_t fetchdat) { - uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -463,7 +580,10 @@ static int opOUTSL_a16(uint32_t fetchdat) } static int opOUTSL_a32(uint32_t fetchdat) { - uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; + uint32_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); diff --git a/src/x86_ops_xchg.h b/src/x86_ops_xchg.h index 6e08933..ae8f69c 100644 --- a/src/x86_ops_xchg.h +++ b/src/x86_ops_xchg.h @@ -1,7 +1,10 @@ static int opXCHG_b_a16(uint32_t fetchdat) { uint8_t temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; setr8(cpu_reg, temp); @@ -12,7 +15,10 @@ static int opXCHG_b_a16(uint32_t fetchdat) static int opXCHG_b_a32(uint32_t fetchdat) { uint8_t temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteab(); if (cpu_state.abrt) return 1; seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; setr8(cpu_reg, temp); @@ -24,7 +30,10 @@ static int opXCHG_b_a32(uint32_t fetchdat) static int opXCHG_w_a16(uint32_t fetchdat) { uint16_t temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = temp; @@ -35,7 +44,10 @@ static int opXCHG_w_a16(uint32_t fetchdat) static int opXCHG_w_a32(uint32_t fetchdat) { uint16_t temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = temp; @@ -47,7 +59,10 @@ static int opXCHG_w_a32(uint32_t fetchdat) static int opXCHG_l_a16(uint32_t fetchdat) { uint32_t temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp; @@ -58,7 +73,10 @@ static int opXCHG_l_a16(uint32_t fetchdat) static int opXCHG_l_a32(uint32_t fetchdat) { uint32_t temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); temp = geteal(); if (cpu_state.abrt) return 1; seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp; diff --git a/src/x87_ops_arith.h b/src/x87_ops_arith.h index 6723bd1..45077c7 100644 --- a/src/x87_ops_arith.h +++ b/src/x87_ops_arith.h @@ -4,6 +4,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ @@ -19,6 +20,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ @@ -30,6 +32,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ @@ -42,6 +45,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ @@ -53,6 +57,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ @@ -64,6 +69,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ @@ -75,6 +81,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ @@ -86,6 +93,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ diff --git a/src/x87_ops_loadstore.h b/src/x87_ops_loadstore.h index 09bbf82..bf9fc1f 100644 --- a/src/x87_ops_loadstore.h +++ b/src/x87_ops_loadstore.h @@ -3,6 +3,7 @@ static int opFILDiw_a16(uint32_t fetchdat) int16_t temp; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr); temp = geteaw(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", (double)temp); @@ -15,6 +16,7 @@ static int opFILDiw_a32(uint32_t fetchdat) int16_t temp; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr); temp = geteaw(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", (double)temp); @@ -28,6 +30,7 @@ static int opFISTiw_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 32767 || temp64 < -32768) @@ -41,6 +44,7 @@ static int opFISTiw_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 32767 || temp64 < -32768) @@ -55,6 +59,7 @@ static int opFISTPiw_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 32767 || temp64 < -32768) @@ -69,6 +74,7 @@ static int opFISTPiw_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 32767 || temp64 < -32768) @@ -84,6 +90,7 @@ static int opFILDiq_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); @@ -99,6 +106,7 @@ static int opFILDiq_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); @@ -116,6 +124,7 @@ static int FBSTP_a16(uint32_t fetchdat) int c; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr); tempd = ST(0); if (tempd < 0.0) @@ -142,6 +151,7 @@ static int FBSTP_a32(uint32_t fetchdat) int c; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr); tempd = ST(0); if (tempd < 0.0) @@ -168,6 +178,7 @@ static int FISTPiq_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) temp64 = cpu_state.MM[cpu_state.TOP].q; @@ -183,6 +194,7 @@ static int FISTPiq_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) temp64 = cpu_state.MM[cpu_state.TOP].q; @@ -199,6 +211,7 @@ static int opFILDil_a16(uint32_t fetchdat) int32_t templ; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr); templ = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); @@ -211,6 +224,7 @@ static int opFILDil_a32(uint32_t fetchdat) int32_t templ; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr); templ = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); @@ -224,6 +238,7 @@ static int opFISTil_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 2147483647 || temp64 < -2147483647) @@ -237,6 +252,7 @@ static int opFISTil_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 2147483647 || temp64 < -2147483647) @@ -251,6 +267,7 @@ static int opFISTPil_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 2147483647 || temp64 < -2147483647) @@ -265,6 +282,7 @@ static int opFISTPil_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr); temp64 = x87_fround(ST(0)); /* if (temp64 > 2147483647 || temp64 < -2147483647) @@ -280,6 +298,7 @@ static int opFLDe_a16(uint32_t fetchdat) double t; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr); t=x87_ld80(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t); @@ -292,6 +311,7 @@ static int opFLDe_a32(uint32_t fetchdat) double t; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr); t=x87_ld80(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t); @@ -304,6 +324,7 @@ static int opFSTPe_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); @@ -314,6 +335,7 @@ static int opFSTPe_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); @@ -326,6 +348,7 @@ static int opFLDd_a16(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr); t.i = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t.d); @@ -338,6 +361,7 @@ static int opFLDd_a32(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr); t.i = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t.d); @@ -351,6 +375,7 @@ static int opFSTd_a16(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); t.d = ST(0); seteaq(t.i); @@ -362,6 +387,7 @@ static int opFSTd_a32(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); t.d = ST(0); seteaq(t.i); @@ -374,6 +400,7 @@ static int opFSTPd_a16(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); t.d = ST(0); @@ -387,6 +414,7 @@ static int opFSTPd_a32(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); t.d = ST(0); @@ -401,6 +429,7 @@ static int opFLDs_a16(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.i = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", ts.s); @@ -413,6 +442,7 @@ static int opFLDs_a32(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.i = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", ts.s); @@ -426,6 +456,7 @@ static int opFSTs_a16(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.s = (float)ST(0); seteal(ts.i); @@ -437,6 +468,7 @@ static int opFSTs_a32(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.s = (float)ST(0); seteal(ts.i); @@ -449,6 +481,7 @@ static int opFSTPs_a16(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; @@ -461,6 +494,7 @@ static int opFSTPs_a32(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 4305487..5f21a99 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -127,6 +127,7 @@ static int opFSTOR_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); FSTOR(); return cpu_state.abrt; } @@ -134,6 +135,7 @@ static int opFSTOR_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); FSTOR(); return cpu_state.abrt; } @@ -287,6 +289,7 @@ static int opFSAVE_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSAVE(); return cpu_state.abrt; } @@ -294,6 +297,7 @@ static int opFSAVE_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSAVE(); return cpu_state.abrt; } @@ -302,6 +306,7 @@ static int opFSTSW_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); CLOCK_CYCLES(3); @@ -311,6 +316,7 @@ static int opFSTSW_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); CLOCK_CYCLES(3); @@ -698,6 +704,7 @@ static int opFLDENV_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); FLDENV(); return cpu_state.abrt; } @@ -705,6 +712,7 @@ static int opFLDENV_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); FLDENV(); return cpu_state.abrt; } @@ -714,6 +722,7 @@ static int opFLDCW_a16(uint32_t fetchdat) uint16_t tempw; FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); tempw = geteaw(); if (cpu_state.abrt) return 1; @@ -727,6 +736,7 @@ static int opFLDCW_a32(uint32_t fetchdat) uint16_t tempw; FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); if (fplog) pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); tempw = geteaw(); if (cpu_state.abrt) return 1; @@ -784,6 +794,7 @@ static int opFSTENV_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSTENV(); return cpu_state.abrt; } @@ -791,6 +802,7 @@ static int opFSTENV_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); FSTENV(); return cpu_state.abrt; } @@ -799,6 +811,7 @@ static int opFSTCW_a16(uint32_t fetchdat) { FP_ENTER(); fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw(cpu_state.npxc); CLOCK_CYCLES(3); @@ -808,6 +821,7 @@ static int opFSTCW_a32(uint32_t fetchdat) { FP_ENTER(); fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw(cpu_state.npxc); CLOCK_CYCLES(3); From 4e7a13f45263dc3a6c883cff0e777f3100f0f7e1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Jul 2018 22:19:09 +0100 Subject: [PATCH 0484/1050] Corrected effective address for POP 0x8f. Windows 95 now works on recompiler. --- src/codegen.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 512b4b3..2ab186f 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -110,7 +110,7 @@ static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uin return op_ea_seg; } -static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { uint32_t new_eaaddr; @@ -146,11 +146,12 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin (*op_pc) += 4; break; } -// if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ -// { + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ + { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); // addbyte(0x05); // addlong(stack_offset); -// } + } if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) op_ea_seg = &_ss; if (((sib >> 3) & 7) != 4) @@ -444,10 +445,10 @@ generate_call: (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) { - //int stack_offset = 0; + int stack_offset = 0; -// if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ -// stack_offset = (op_32 & 0x100) ? 4 : 2; + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; cpu_mod = (fetchdat >> 6) & 3; cpu_reg = (fetchdat >> 3) & 7; @@ -463,7 +464,7 @@ generate_call: } if (cpu_mod != 3 && (op_32 & 0x200)) { - op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); + op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); // has_ea = 1; } // op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); From 91143d3c683a7c9c10ca03613ae49d9b659807ba Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Jul 2018 12:56:03 +0100 Subject: [PATCH 0485/1050] Move CPU segment structures into cpu_state structure. --- src/386.c | 8 +- src/386_dynarec.c | 12 +-- src/808x.c | 32 +++---- src/codegen.c | 23 +++-- src/codegen_backend.c | 2 +- src/ibm.h | 29 +++--- src/x86_ops_misc.h | 43 +++++---- src/x86_ops_mov_seg.h | 46 +++++----- src/x86_ops_prefix.h | 36 ++++---- src/x86_ops_rep.h | 42 ++++----- src/x86_ops_stack.h | 16 ++-- src/x86_ops_string.h | 60 ++++++------ src/x86seg.c | 206 +++++++++++++++++++++--------------------- 13 files changed, 279 insertions(+), 276 deletions(-) diff --git a/src/386.c b/src/386.c index cb78c4e..dc254d3 100644 --- a/src/386.c +++ b/src/386.c @@ -90,7 +90,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) { easeg = ss; ea_rseg = SS; - cpu_state.ea_seg = &_ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } if (((sib >> 3) & 7) != 4) cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); @@ -104,7 +104,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) { easeg = ss; ea_rseg = SS; - cpu_state.ea_seg = &_ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } if (cpu_mod == 1) { @@ -159,7 +159,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) { easeg = ss; ea_rseg = SS; - cpu_state.ea_seg = &_ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } cpu_state.eaaddr &= 0xFFFF; } @@ -244,7 +244,7 @@ void exec386(int cycs) dontprint=0; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; fetchdat = fastreadl(cs + cpu_state.pc); diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 7224d09..32cceb2 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -99,7 +99,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) { easeg = ss; ea_rseg = SS; - cpu_state.ea_seg = &_ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } if (((sib >> 3) & 7) != 4) cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); @@ -113,7 +113,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) { easeg = ss; ea_rseg = SS; - cpu_state.ea_seg = &_ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } if (cpu_mod == 1) { @@ -168,7 +168,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) { easeg = ss; ea_rseg = SS; - cpu_state.ea_seg = &_ss; + cpu_state.ea_seg = &cpu_state.seg_ss; } cpu_state.eaaddr &= 0xFFFF; } @@ -553,7 +553,7 @@ void exec386_dynarec(int cycs) oldcpl=CPL; cpu_state.op32 = use32; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; fetchdat = fastreadl(cs + cpu_state.pc); @@ -711,7 +711,7 @@ inrecomp=0; oldcpl=CPL; cpu_state.op32 = use32; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; fetchdat = fastreadl(cs + cpu_state.pc); @@ -793,7 +793,7 @@ inrecomp=0; oldcpl=CPL; cpu_state.op32 = use32; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; codegen_endpc = (cs + cpu_state.pc) + 8; diff --git a/src/808x.c b/src/808x.c index 082e0b0..9f66d45 100644 --- a/src/808x.c +++ b/src/808x.c @@ -577,15 +577,15 @@ void dumpregs() printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); else printf("In %s mode\n",(msw&1)?"protected":"real"); - printf("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high); - printf("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high); - printf("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high); + printf("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,cpu_state.seg_cs.limit,cpu_state.seg_cs.access, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high); + printf("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,cpu_state.seg_ds.limit,cpu_state.seg_ds.access, cpu_state.seg_ds.limit_low, cpu_state.seg_ds.limit_high); + printf("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,cpu_state.seg_es.limit,cpu_state.seg_es.access, cpu_state.seg_es.limit_low, cpu_state.seg_es.limit_high); if (is386) { - printf("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",seg_fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high); - printf("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high); + printf("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cpu_state.seg_fs.base,cpu_state.seg_fs.limit,cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); + printf("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,cpu_state.seg_gs.limit,cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); } - printf("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high); + printf("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,cpu_state.seg_ss.limit,cpu_state.seg_ss.access, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high); printf("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit); printf("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit); printf("IDT : base=%06X limit=%04X\n",idt.base,idt.limit); @@ -1195,7 +1195,7 @@ void execx86(int cycs) case 0x07: /*POP ES*/ if (cpu_state.ssegs) ss=oldss; tempw=readmemw(ss,SP); - loadseg(tempw,&_es); + loadseg(tempw,&cpu_state.seg_es); SP+=2; cycles-=12; break; @@ -1258,7 +1258,7 @@ void execx86(int cycs) case 0x0F: /*POP CS - 8088/8086 only*/ if (cpu_state.ssegs) ss=oldss; tempw=readmemw(ss,SP); - loadseg(tempw,&_cs); + loadseg(tempw,&cpu_state.seg_cs); SP+=2; cycles-=12; break; @@ -1317,7 +1317,7 @@ void execx86(int cycs) case 0x17: /*POP SS*/ if (cpu_state.ssegs) ss=oldss; tempw=readmemw(ss,SP); - loadseg(tempw,&_ss); + loadseg(tempw,&cpu_state.seg_ss); SP+=2; noint=1; cycles-=12; @@ -1382,7 +1382,7 @@ void execx86(int cycs) case 0x1F: /*POP DS*/ if (cpu_state.ssegs) ss=oldss; tempw=readmemw(ss,SP); - loadseg(tempw,&_ds); + loadseg(tempw,&cpu_state.seg_ds); if (cpu_state.ssegs) oldds=ds; SP+=2; cycles-=12; @@ -2088,20 +2088,20 @@ void execx86(int cycs) { case 0x00: /*ES*/ tempw=geteaw(); - loadseg(tempw,&_es); + loadseg(tempw,&cpu_state.seg_es); break; case 0x08: /*CS - 8088/8086 only*/ tempw=geteaw(); - loadseg(tempw,&_cs); + loadseg(tempw,&cpu_state.seg_cs); break; case 0x18: /*DS*/ tempw=geteaw(); - loadseg(tempw,&_ds); + loadseg(tempw,&cpu_state.seg_ds); if (cpu_state.ssegs) oldds=ds; break; case 0x10: /*SS*/ tempw=geteaw(); - loadseg(tempw,&_ss); + loadseg(tempw,&cpu_state.seg_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); @@ -2350,14 +2350,14 @@ void execx86(int cycs) fetchea(); cpu_state.regs[cpu_reg].w=readmemw(easeg,cpu_state.eaaddr); //geteaw(); tempw=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); //geteaw2(); - loadseg(tempw,&_es); + loadseg(tempw,&cpu_state.seg_es); cycles-=24; break; case 0xC5: /*LDS*/ fetchea(); cpu_state.regs[cpu_reg].w=readmemw(easeg,cpu_state.eaaddr); tempw=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); - loadseg(tempw,&_ds); + loadseg(tempw,&cpu_state.seg_ds); if (cpu_state.ssegs) oldds=ds; cycles-=24; break; diff --git a/src/codegen.c b/src/codegen.c index 2ab186f..96db8a6 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -103,7 +103,7 @@ static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uin if (mod1seg[cpu_rm] == &ss && !op_ssegs) { - op_ea_seg = &_ss; + op_ea_seg = &cpu_state.seg_ss; } } @@ -153,7 +153,7 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin // addlong(stack_offset); } if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &_ss; + op_ea_seg = &cpu_state.seg_ss; if (((sib >> 3) & 7) != 4) { switch (sib >> 6) @@ -186,7 +186,7 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin if (cpu_mod) { if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &_ss; + op_ea_seg = &cpu_state.seg_ss; if (cpu_mod == 1) { uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); @@ -258,13 +258,12 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t int opcode_shift = 0; int opcode_mask = 0x3ff; uint32_t op_32 = use32; - x86seg *op_ea_seg = &_ds; - int op_ssegs = 0; int over = 0; int test_modrm = 1; int pc_off = 0; - op_ea_seg = &_ds; + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; codegen_timing_start(); @@ -279,27 +278,27 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0x26: /*ES:*/ - op_ea_seg = &_es; + op_ea_seg = &cpu_state.seg_es; op_ssegs = 1; break; case 0x2e: /*CS:*/ - op_ea_seg = &_cs; + op_ea_seg = &cpu_state.seg_cs; op_ssegs = 1; break; case 0x36: /*SS:*/ - op_ea_seg = &_ss; + op_ea_seg = &cpu_state.seg_ss; op_ssegs = 1; break; case 0x3e: /*DS:*/ - op_ea_seg = &_ds; + op_ea_seg = &cpu_state.seg_ds; op_ssegs = 1; break; case 0x64: /*FS:*/ - op_ea_seg = &_fs; + op_ea_seg = &cpu_state.seg_fs; op_ssegs = 1; break; case 0x65: /*GS:*/ - op_ea_seg = &_gs; + op_ea_seg = &cpu_state.seg_gs; op_ssegs = 1; break; diff --git a/src/codegen_backend.c b/src/codegen_backend.c index afc6716..58c092e 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -301,7 +301,7 @@ void codegen_block_start_recompile(codeblock_t *block) codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - _ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1; + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; block->TOP = cpu_state.TOP; block->was_recompiled = 1; diff --git a/src/ibm.h b/src/ibm.h index 6177fef..70641c9 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -176,6 +176,8 @@ struct MMX_REG MM[8]; uint16_t old_npxc, new_npxc; + + x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; } cpu_state; #define cycles cpu_state._cycles @@ -209,7 +211,6 @@ extern int ins,output; extern int cycdiff; x86seg gdt,ldt,idt,tr; -x86seg _cs,_ds,_es,_ss,_fs,_gs; x86seg _oldds; uint32_t pccache; @@ -218,20 +219,20 @@ uint8_t *pccache2; _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data cs,ds,es,ss are defines to the bases*/ -#define CS _cs.seg -#define DS _ds.seg -#define ES _es.seg -#define SS _ss.seg -#define FS _fs.seg -#define GS _gs.seg -#define cs _cs.base -#define ds _ds.base -#define es _es.base -#define ss _ss.base -#define seg_fs _fs.base -#define gs _gs.base +#define CS cpu_state.seg_cs.seg +#define DS cpu_state.seg_ds.seg +#define ES cpu_state.seg_es.seg +#define SS cpu_state.seg_ss.seg +#define FS cpu_state.seg_fs.seg +#define GS cpu_state.seg_gs.seg +#define cs cpu_state.seg_cs.base +#define ds cpu_state.seg_ds.base +#define es cpu_state.seg_es.base +#define ss cpu_state.seg_ss.base +//#define seg_fs _fs.base +#define gs cpu_state.seg_gs.base -#define CPL ((_cs.access>>5)&3) +#define CPL ((cpu_state.seg_cs.access>>5)&3) void loadseg(uint16_t seg, x86seg *s); void loadcs(uint16_t seg); diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index 354059d..7c220a0 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -800,22 +800,22 @@ 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); + cpu_state.seg_es.access = readmemb(0, 0x839); + cpu_state.seg_es.limit = readmemw(0, 0x83A); cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); - _cs.access = readmemb(0, 0x83F); - _cs.limit = readmemw(0, 0x840); + cpu_state.seg_cs.access = readmemb(0, 0x83F); + cpu_state.seg_cs.limit = readmemw(0, 0x840); 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_state.seg_ss.access = readmemb(0, 0x845); + cpu_state.seg_ss.limit = readmemw(0, 0x846); + if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; else cpu_cur_status |= CPU_STATUS_NOTFLATSS; 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_state.seg_ds.access = readmemb(0, 0x84B); + cpu_state.seg_ds.limit = readmemw(0, 0x84C); + if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else cpu_cur_status |= CPU_STATUS_NOTFLATDS; @@ -856,8 +856,11 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) s->base = readmeml(0, addr + 4); s->limit = readmeml(0, addr + 8); - if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0; - if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0; + if (s == &cpu_state.seg_cs) + use32 = (segdat3 & 0x40) ? 0x300 : 0; + if (s == &cpu_state.seg_ss) + stack32 = (segdat3 & 0x40) ? 1 : 0; + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); if (use32) cpu_cur_status |= CPU_STATUS_USE32; @@ -866,14 +869,14 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) set_segment_limit(s, segdat3); - if (s == &_ds) + if (s == &cpu_state.seg_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else cpu_cur_status |= CPU_STATUS_NOTFLATDS; } - if (s == &_ss) + if (s == &cpu_state.seg_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -914,12 +917,12 @@ static int opLOADALL386(uint32_t fetchdat) loadall_load_segment(la_addr + 0x60, &idt); loadall_load_segment(la_addr + 0x6c, &gdt); loadall_load_segment(la_addr + 0x78, &ldt); - loadall_load_segment(la_addr + 0x84, &_gs); - loadall_load_segment(la_addr + 0x90, &_fs); - loadall_load_segment(la_addr + 0x9c, &_ds); - loadall_load_segment(la_addr + 0xa8, &_ss); - loadall_load_segment(la_addr + 0xb4, &_cs); - loadall_load_segment(la_addr + 0xc0, &_es); + loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); + loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); + loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); + loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); + loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); + loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); diff --git a/src/x86_ops_mov_seg.h b/src/x86_ops_mov_seg.h index ecaeba1..54a30cb 100644 --- a/src/x86_ops_mov_seg.h +++ b/src/x86_ops_mov_seg.h @@ -152,28 +152,28 @@ static int opMOV_seg_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*ES*/ - loadseg(new_seg, &_es); + loadseg(new_seg, &cpu_state.seg_es); break; case 0x18: /*DS*/ - loadseg(new_seg, &_ds); + loadseg(new_seg, &cpu_state.seg_ds); break; case 0x10: /*SS*/ - loadseg(new_seg, &_ss); + loadseg(new_seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; fetchdat = fastreadl(cs + cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); return 1; case 0x20: /*FS*/ - loadseg(new_seg, &_fs); + loadseg(new_seg, &cpu_state.seg_fs); break; case 0x28: /*GS*/ - loadseg(new_seg, &_gs); + loadseg(new_seg, &cpu_state.seg_gs); break; } @@ -193,28 +193,28 @@ static int opMOV_seg_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*ES*/ - loadseg(new_seg, &_es); + loadseg(new_seg, &cpu_state.seg_es); break; case 0x18: /*DS*/ - loadseg(new_seg, &_ds); + loadseg(new_seg, &cpu_state.seg_ds); break; case 0x10: /*SS*/ - loadseg(new_seg, &_ss); + loadseg(new_seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; fetchdat = fastreadl(cs + cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); return 1; case 0x20: /*FS*/ - loadseg(new_seg, &_fs); + loadseg(new_seg, &cpu_state.seg_fs); break; case 0x28: /*GS*/ - loadseg(new_seg, &_gs); + loadseg(new_seg, &cpu_state.seg_gs); break; } @@ -233,7 +233,7 @@ static int opLDS_w_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; CLOCK_CYCLES(7); @@ -249,7 +249,7 @@ static int opLDS_w_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; CLOCK_CYCLES(7); @@ -266,7 +266,7 @@ static int opLDS_l_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; CLOCK_CYCLES(7); @@ -283,7 +283,7 @@ static int opLDS_l_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ds); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; CLOCK_CYCLES(7); @@ -300,7 +300,7 @@ static int opLSS_w_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; CLOCK_CYCLES(7); @@ -316,7 +316,7 @@ static int opLSS_w_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmemw(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = addr; CLOCK_CYCLES(7); @@ -333,7 +333,7 @@ static int opLSS_l_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; CLOCK_CYCLES(7); @@ -350,7 +350,7 @@ static int opLSS_l_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); addr = readmeml(easeg, cpu_state.eaaddr); seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &_ss); if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = addr; CLOCK_CYCLES(7); @@ -429,6 +429,6 @@ static int opLSS_l_a32(uint32_t fetchdat) return 0; \ } -opLsel(ES, _es) -opLsel(FS, _fs) -opLsel(GS, _gs) +opLsel(ES, cpu_state.seg_es) +opLsel(FS, cpu_state.seg_fs) +opLsel(GS, cpu_state.seg_gs) diff --git a/src/x86_ops_prefix.h b/src/x86_ops_prefix.h index 48147c7..8cfe95e 100644 --- a/src/x86_ops_prefix.h +++ b/src/x86_ops_prefix.h @@ -63,26 +63,26 @@ static int op ## name ## _l_a32(uint32_t fetchdat) \ return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ } -op_seg(CS, _cs, x86_opcodes, x86_opcodes) -op_seg(DS, _ds, x86_opcodes, x86_opcodes) -op_seg(ES, _es, x86_opcodes, x86_opcodes) -op_seg(FS, _fs, x86_opcodes, x86_opcodes) -op_seg(GS, _gs, x86_opcodes, x86_opcodes) -op_seg(SS, _ss, x86_opcodes, x86_opcodes) +op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) +op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) +op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes) +op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes) +op_seg(GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes) +op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes) -op_seg(CS_REPE, _cs, x86_opcodes_REPE, x86_opcodes) -op_seg(DS_REPE, _ds, x86_opcodes_REPE, x86_opcodes) -op_seg(ES_REPE, _es, x86_opcodes_REPE, x86_opcodes) -op_seg(FS_REPE, _fs, x86_opcodes_REPE, x86_opcodes) -op_seg(GS_REPE, _gs, x86_opcodes_REPE, x86_opcodes) -op_seg(SS_REPE, _ss, x86_opcodes_REPE, x86_opcodes) +op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE, x86_opcodes) +op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE, x86_opcodes) +op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes) +op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE, x86_opcodes) +op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE, x86_opcodes) +op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes) -op_seg(CS_REPNE, _cs, x86_opcodes_REPNE, x86_opcodes) -op_seg(DS_REPNE, _ds, x86_opcodes_REPNE, x86_opcodes) -op_seg(ES_REPNE, _es, x86_opcodes_REPNE, x86_opcodes) -op_seg(FS_REPNE, _fs, x86_opcodes_REPNE, x86_opcodes) -op_seg(GS_REPNE, _gs, x86_opcodes_REPNE, x86_opcodes) -op_seg(SS_REPNE, _ss, x86_opcodes_REPNE, x86_opcodes) +op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE, x86_opcodes) +op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes) +op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) +op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) +op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) +op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) static int op_66(uint32_t fetchdat) /*Data size select*/ { diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index 5b24beb..bd95991 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -9,7 +9,7 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) { \ uint8_t temp; \ \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ temp = inb(DX); \ writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ @@ -37,7 +37,7 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) { \ uint16_t temp; \ \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ check_io_perm(DX+1); \ temp = inw(DX); \ @@ -66,7 +66,7 @@ static int opREP_INSL_ ## size(uint32_t fetchdat) { \ uint32_t temp; \ \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ check_io_perm(DX); \ check_io_perm(DX+1); \ check_io_perm(DX+2); \ @@ -182,13 +182,13 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat) if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ } \ while (CNT_REG > 0) \ { \ uint8_t temp; \ \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ @@ -220,13 +220,13 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat) if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ } \ while (CNT_REG > 0) \ { \ uint16_t temp; \ \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ @@ -258,13 +258,13 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat) if (CNT_REG > 0) \ { \ SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ } \ while (CNT_REG > 0) \ { \ uint32_t temp; \ \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ @@ -296,10 +296,10 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat) if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ if (flags & D_FLAG) DEST_REG--; \ else DEST_REG++; \ @@ -326,10 +326,10 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat) if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG+1); \ writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ if (flags & D_FLAG) DEST_REG -= 2; \ else DEST_REG += 2; \ @@ -356,10 +356,10 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat) if (trap) \ cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&_es); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ while (CNT_REG > 0) \ { \ - CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG+3); \ writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ if (flags & D_FLAG) DEST_REG -= 4; \ else DEST_REG += 4; \ @@ -479,7 +479,7 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) { \ uint8_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&_es); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ @@ -509,7 +509,7 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) { \ uint16_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&_es); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ @@ -539,7 +539,7 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat) { \ uint32_t temp, temp2; \ SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&_es); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ @@ -569,7 +569,7 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat) cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&_es); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ @@ -602,7 +602,7 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat) cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&_es); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ @@ -635,7 +635,7 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat) cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ tempz = FV; \ if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&_es); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ while ((CNT_REG > 0) && (FV == tempz)) \ { \ uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ diff --git a/src/x86_ops_stack.h b/src/x86_ops_stack.h index dbe333f..b7e827b 100644 --- a/src/x86_ops_stack.h +++ b/src/x86_ops_stack.h @@ -470,10 +470,10 @@ 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, &cpu_state.seg_ds); +POP_SEG_OPS(ES, &cpu_state.seg_es); +POP_SEG_OPS(FS, &cpu_state.seg_fs); +POP_SEG_OPS(GS, &cpu_state.seg_gs); static int opPOP_SS_w(uint32_t fetchdat) @@ -481,14 +481,14 @@ static int opPOP_SS_w(uint32_t fetchdat) uint16_t temp_seg; uint32_t temp_esp = ESP; temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } CLOCK_CYCLES(is486 ? 3 : 7); PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; fetchdat = fastreadl(cs + cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; @@ -501,14 +501,14 @@ static int opPOP_SS_l(uint32_t fetchdat) uint32_t temp_seg; uint32_t temp_esp = ESP; temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } CLOCK_CYCLES(is486 ? 3 : 7); PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; cpu_state.ssegs = 0; - cpu_state.ea_seg = &_ds; + cpu_state.ea_seg = &cpu_state.seg_ds; fetchdat = fastreadl(cs + cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; diff --git a/src/x86_ops_string.h b/src/x86_ops_string.h index d76b3f8..3bdeace 100644 --- a/src/x86_ops_string.h +++ b/src/x86_ops_string.h @@ -3,7 +3,7 @@ static int opMOVSB_a16(uint32_t fetchdat) uint8_t temp; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememb(es, DI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { DI--; SI--; } @@ -17,7 +17,7 @@ static int opMOVSB_a32(uint32_t fetchdat) uint8_t temp; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememb(es, EDI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { EDI--; ESI--; } @@ -32,7 +32,7 @@ static int opMOVSW_a16(uint32_t fetchdat) uint16_t temp; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememw(es, DI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { DI -= 2; SI -= 2; } @@ -46,7 +46,7 @@ static int opMOVSW_a32(uint32_t fetchdat) uint16_t temp; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememw(es, EDI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } @@ -61,7 +61,7 @@ static int opMOVSL_a16(uint32_t fetchdat) uint32_t temp; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememl(es, DI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { DI -= 4; SI -= 4; } @@ -75,7 +75,7 @@ static int opMOVSL_a32(uint32_t fetchdat) uint32_t temp; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememl(es, EDI, temp); if (cpu_state.abrt) return 1; if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } @@ -91,7 +91,7 @@ static int opCMPSB_a16(uint32_t fetchdat) uint8_t src, dst; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); src = readmemb(cpu_state.ea_seg->base, SI); dst = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(src, dst); @@ -106,7 +106,7 @@ static int opCMPSB_a32(uint32_t fetchdat) uint8_t src, dst; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); src = readmemb(cpu_state.ea_seg->base, ESI); dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(src, dst); @@ -122,7 +122,7 @@ static int opCMPSW_a16(uint32_t fetchdat) uint16_t src, dst; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); src = readmemw(cpu_state.ea_seg->base, SI); dst = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(src, dst); @@ -137,7 +137,7 @@ static int opCMPSW_a32(uint32_t fetchdat) uint16_t src, dst; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); src = readmemw(cpu_state.ea_seg->base, ESI); dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(src, dst); @@ -153,7 +153,7 @@ static int opCMPSL_a16(uint32_t fetchdat) uint32_t src, dst; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); src = readmeml(cpu_state.ea_seg->base, SI); dst = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(src, dst); @@ -168,7 +168,7 @@ static int opCMPSL_a32(uint32_t fetchdat) uint32_t src, dst; SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); src = readmeml(cpu_state.ea_seg->base, ESI); dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(src, dst); @@ -181,7 +181,7 @@ static int opCMPSL_a32(uint32_t fetchdat) static int opSTOSB_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, DI, AL); if (cpu_state.abrt) return 1; if (flags & D_FLAG) DI--; else DI++; @@ -191,7 +191,7 @@ static int opSTOSB_a16(uint32_t fetchdat) } static int opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, EDI, AL); if (cpu_state.abrt) return 1; if (flags & D_FLAG) EDI--; else EDI++; @@ -202,7 +202,7 @@ static int opSTOSB_a32(uint32_t fetchdat) static int opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, DI, AX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) DI -= 2; else DI += 2; @@ -212,7 +212,7 @@ static int opSTOSW_a16(uint32_t fetchdat) } static int opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, EDI, AX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) EDI -= 2; else EDI += 2; @@ -223,7 +223,7 @@ static int opSTOSW_a32(uint32_t fetchdat) static int opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, DI, EAX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) DI -= 4; else DI += 4; @@ -233,7 +233,7 @@ static int opSTOSL_a16(uint32_t fetchdat) } static int opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; if (flags & D_FLAG) EDI -= 4; else EDI += 4; @@ -329,7 +329,7 @@ static int opSCASB_a16(uint32_t fetchdat) { uint8_t temp; - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (flags & D_FLAG) DI--; @@ -342,7 +342,7 @@ static int opSCASB_a32(uint32_t fetchdat) { uint8_t temp; - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(AL, temp); if (flags & D_FLAG) EDI--; @@ -356,7 +356,7 @@ static int opSCASW_a16(uint32_t fetchdat) { uint16_t temp; - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (flags & D_FLAG) DI -= 2; @@ -369,7 +369,7 @@ static int opSCASW_a32(uint32_t fetchdat) { uint16_t temp; - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(AX, temp); if (flags & D_FLAG) EDI -= 2; @@ -383,7 +383,7 @@ static int opSCASL_a16(uint32_t fetchdat) { uint32_t temp; - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); temp = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (flags & D_FLAG) DI -= 4; @@ -396,7 +396,7 @@ static int opSCASL_a32(uint32_t fetchdat) { uint32_t temp; - SEG_CHECK_READ(&_es); + SEG_CHECK_READ(&cpu_state.seg_es); temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); if (flags & D_FLAG) EDI -= 4; @@ -410,7 +410,7 @@ static int opINSB_a16(uint32_t fetchdat) { uint8_t temp; - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); temp = inb(DX); writememb(es, DI, temp); if (cpu_state.abrt) return 1; @@ -424,7 +424,7 @@ static int opINSB_a32(uint32_t fetchdat) { uint8_t temp; - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); temp = inb(DX); writememb(es, EDI, temp); if (cpu_state.abrt) return 1; @@ -439,7 +439,7 @@ static int opINSW_a16(uint32_t fetchdat) { uint16_t temp; - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); @@ -454,7 +454,7 @@ static int opINSW_a32(uint32_t fetchdat) { uint16_t temp; - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); temp = inw(DX); @@ -470,7 +470,7 @@ static int opINSL_a16(uint32_t fetchdat) { uint32_t temp; - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); @@ -487,7 +487,7 @@ static int opINSL_a32(uint32_t fetchdat) { uint32_t temp; - SEG_CHECK_WRITE(&_es); + SEG_CHECK_WRITE(&cpu_state.seg_es); check_io_perm(DX); check_io_perm(DX + 1); check_io_perm(DX + 2); diff --git a/src/x86seg.c b/src/x86seg.c index 9840c0b..68b0d49 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -68,7 +68,7 @@ static void seg_reset(x86seg *s) s->limit = 0xFFFF; s->limit_low = 0; s->limit_high = 0xffff; - if (s == &_cs) + if (s == &cpu_state.seg_cs) { // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. //s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; @@ -84,12 +84,12 @@ static void seg_reset(x86seg *s) void x86seg_reset() { - seg_reset(&_cs); - seg_reset(&_ds); - seg_reset(&_es); - seg_reset(&_fs); - seg_reset(&_gs); - seg_reset(&_ss); + seg_reset(&cpu_state.seg_cs); + seg_reset(&cpu_state.seg_ds); + seg_reset(&cpu_state.seg_es); + seg_reset(&cpu_state.seg_fs); + seg_reset(&cpu_state.seg_gs); + seg_reset(&cpu_state.seg_ss); } void x86_doabrt(int x86_abrt) @@ -97,7 +97,7 @@ void x86_doabrt(int x86_abrt) // ingpf = 1; CS = oldcs; cpu_state.pc = cpu_state.oldpc; - _cs.access = oldcpl << 5; + cpu_state.seg_cs.access = oldcpl << 5; // pclog("x86_doabrt - %02X %08X %04X:%08X %i\n", x86_abrt, abrt_error, CS, pc, ins); /* if (CS == 0x3433 && pc == 0x000006B0) @@ -238,14 +238,14 @@ static void do_seg_load(x86seg *s, uint16_t *segdat) } // if (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, s->limit_high); - if (s == &_ds) + if (s == &cpu_state.seg_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else cpu_cur_status |= CPU_STATUS_NOTFLATDS; } - if (s == &_ss) + if (s == &cpu_state.seg_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -320,7 +320,7 @@ void loadseg(uint16_t seg, x86seg *s) // intcount++; if (!(seg&~3)) { - if (s==&_ss) + if (s==&cpu_state.seg_ss) { pclog("SS selector = NULL!\n"); x86ss(NULL,0); @@ -332,7 +332,7 @@ void loadseg(uint16_t seg, x86seg *s) s->seg=0; s->access = 0; s->base=-1; - if (s == &_ds) + if (s == &cpu_state.seg_ds) cpu_cur_status |= CPU_STATUS_NOTFLATDS; // 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,pc); return; @@ -371,7 +371,7 @@ void loadseg(uint16_t seg, x86seg *s) segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; dpl=(segdat[2]>>13)&3; - if (s==&_ss) + if (s==&cpu_state.seg_ss) { if (!(seg&~3)) { @@ -405,7 +405,7 @@ void loadseg(uint16_t seg, x86seg *s) set_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) + else if (s!=&cpu_state.seg_cs) { if (output) pclog("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); if (output) pclog("Seg type %03X\n",segdat[2]&0x1F00); @@ -453,9 +453,9 @@ void loadseg(uint16_t seg, x86seg *s) } #endif s->checked = 0; - if (s == &_ds) + if (s == &cpu_state.seg_ds) codegen_flat_ds = 0; - if (s == &_ss) + if (s == &cpu_state.seg_ss) codegen_flat_ss = 0; } else @@ -463,23 +463,23 @@ void loadseg(uint16_t seg, x86seg *s) s->access = (3 << 5) | 2; s->base = seg << 4; s->seg = seg; - if (s == &_ss) + if (s == &cpu_state.seg_ss) set_stack32(0); s->checked = 1; - if (s == &_ds) + if (s == &cpu_state.seg_ds) codegen_flat_ds = 0; - if (s == &_ss) + if (s == &cpu_state.seg_ss) codegen_flat_ss = 0; } - if (s == &_ds) + if (s == &cpu_state.seg_ds) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else cpu_cur_status |= CPU_STATUS_NOTFLATDS; } - if (s == &_ss) + if (s == &cpu_state.seg_ss) { if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; @@ -568,7 +568,7 @@ void loadcs(uint16_t seg) } set_use32(segdat[3] & 0x40); CS=(seg&~3)|CPL; - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); @@ -601,13 +601,13 @@ void loadcs(uint16_t seg) } else { - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; + cpu_state.seg_cs.base=seg<<4; + cpu_state.seg_cs.limit=0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - if (eflags&VM_FLAG) _cs.access=(3<<5) | 2; - else _cs.access=(0<<5) | 2; + if (eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; + else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); } } @@ -693,7 +693,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) CS = (seg & ~3) | CPL; segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); /* if (segdat[3]&0x40) { @@ -797,7 +797,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) } case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ CS=seg2; - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -846,13 +846,13 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) } else { - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; + cpu_state.seg_cs.base=seg<<4; + cpu_state.seg_cs.limit=0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - if (eflags&VM_FLAG) _cs.access=(3<<5) | 2; - else _cs.access=(0<<5) | 2; + if (eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; + else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); cycles -= timing_jmp_rm; } @@ -1028,7 +1028,7 @@ void loadcscall(uint16_t seg) else /*On non-conforming segments, set RPL = CPL*/ seg = (seg & ~3) | CPL; CS=seg; - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); /* if (segdat[3]&0x40) { @@ -1205,7 +1205,7 @@ void loadcscall(uint16_t seg) if (stack32) ESP=newsp; else SP=newsp; - do_seg_load(&_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); if (output) pclog("Set access 1\n"); @@ -1216,7 +1216,7 @@ void loadcscall(uint16_t seg) #endif CS=seg2; - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -1320,7 +1320,7 @@ void loadcscall(uint16_t seg) PUSHW(oldpc); if (cpu_state.abrt) return; }*/ CS=seg2; - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -1363,13 +1363,13 @@ void loadcscall(uint16_t seg) } else { - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; + cpu_state.seg_cs.base=seg<<4; + cpu_state.seg_cs.limit=0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - if (eflags&VM_FLAG) _cs.access=(3<<5) | 2; - else _cs.access=(0<<5) | 2; + if (eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; + else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); } } @@ -1495,8 +1495,8 @@ void pmoderetf(int is32, uint16_t off) if (segdat[2] & 0x400) segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); CS = seg; - do_seg_load(&_cs, segdat); - _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3] & 0x40); @@ -1630,7 +1630,7 @@ void pmoderetf(int is32, uint16_t off) set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; - do_seg_load(&_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); #ifdef SEL_ACCESSED cpl_override = 1; @@ -1647,17 +1647,17 @@ void pmoderetf(int is32, uint16_t off) cpu_state.pc=newpc; CS=seg; - do_seg_load(&_cs, segdat); + do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3] & 0x40); if (stack32) ESP+=off; else SP+=off; - check_seg_valid(&_ds); - check_seg_valid(&_es); - check_seg_valid(&_fs); - check_seg_valid(&_gs); + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); // pclog("CPL0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); @@ -2086,10 +2086,10 @@ void pmodeiret(int is32) tempflags=POPW(); if (cpu_state.abrt) return; } cpu_state.pc=newpc; - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; + cpu_state.seg_cs.base=seg<<4; + cpu_state.seg_cs.limit=0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; CS=seg; flags=(flags&0x3000)|(tempflags&0xCFD5)|2; cycles -= timing_iret_rm; @@ -2155,31 +2155,31 @@ void pmodeiret(int is32) // pclog("Pop stack %04X:%04X\n",newss,newsp); eflags=tempflags>>16; cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0],&_es); - do_seg_v86_init(&_es); - loadseg(segs[1],&_ds); - do_seg_v86_init(&_ds); + loadseg(segs[0],&cpu_state.seg_es); + do_seg_v86_init(&cpu_state.seg_es); + loadseg(segs[1],&cpu_state.seg_ds); + do_seg_v86_init(&cpu_state.seg_ds); cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2],&_fs); - do_seg_v86_init(&_fs); - loadseg(segs[3],&_gs); - do_seg_v86_init(&_gs); + loadseg(segs[2],&cpu_state.seg_fs); + do_seg_v86_init(&cpu_state.seg_fs); + loadseg(segs[3],&cpu_state.seg_gs); + do_seg_v86_init(&cpu_state.seg_gs); // pclog("V86 IRET %04X:%08X\n",SS,ESP); // output=3; cpu_state.pc=newpc; - _cs.base=seg<<4; - _cs.limit=0xFFFF; - _cs.limit_low = 0; - _cs.limit_high = 0xffff; + cpu_state.seg_cs.base=seg<<4; + cpu_state.seg_cs.limit=0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - _cs.access=(3<<5) | 2; + cpu_state.seg_cs.access=(3<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); ESP=newsp; - loadseg(newss,&_ss); - do_seg_v86_init(&_ss); + loadseg(newss,&cpu_state.seg_ss); + do_seg_v86_init(&cpu_state.seg_ss); cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32=0; cpu_cur_status &= ~CPU_STATUS_USE32; @@ -2292,8 +2292,8 @@ void pmodeiret(int is32) { // pclog("Same level\n"); CS=seg; - do_seg_load(&_cs, segdat); - _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3]&0x40); @@ -2392,7 +2392,7 @@ void pmodeiret(int is32) set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; - do_seg_load(&_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); #ifdef SEL_ACCESSED cpl_override = 1; @@ -2408,15 +2408,15 @@ void pmodeiret(int is32) segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8)); CS=seg; - do_seg_load(&_cs, segdat); - _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat[3] & 0x40); - check_seg_valid(&_ds); - check_seg_valid(&_es); - check_seg_valid(&_fs); - check_seg_valid(&_gs); + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); cycles -= timing_iret_pm_outer; } cpu_state.pc=newpc; @@ -2643,7 +2643,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) // if (output) pclog("new_cs %04X\n",new_cs); CS=new_cs; - do_seg_load(&_cs, segdat2); + do_seg_load(&cpu_state.seg_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(segdat2[3] & 0x40); cpu_cur_status &= ~CPU_STATUS_V86; @@ -2659,15 +2659,15 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) EDI=new_edi; if (output) pclog("Load ES %04X\n",new_es); - loadseg(new_es,&_es); + loadseg(new_es,&cpu_state.seg_es); if (output) pclog("Load SS %04X\n",new_ss); - loadseg(new_ss,&_ss); + loadseg(new_ss,&cpu_state.seg_ss); if (output) pclog("Load DS %04X\n",new_ds); - loadseg(new_ds,&_ds); + loadseg(new_ds,&cpu_state.seg_ds); if (output) pclog("Load FS %04X\n",new_fs); - loadseg(new_fs,&_fs); + loadseg(new_fs,&cpu_state.seg_fs); if (output) pclog("Load GS %04X\n",new_gs); - loadseg(new_gs,&_gs); + loadseg(new_gs,&cpu_state.seg_gs); if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc); } @@ -2842,7 +2842,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) // if (output) pclog("new_cs %04X\n",new_cs); CS=new_cs; - do_seg_load(&_cs, segdat2); + do_seg_load(&cpu_state.seg_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); set_use32(0); @@ -2856,15 +2856,15 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) EDI=new_edi | 0xFFFF0000; if (output) pclog("Load ES %04X\n",new_es); - loadseg(new_es,&_es); + loadseg(new_es,&cpu_state.seg_es); if (output) pclog("Load SS %04X\n",new_ss); - loadseg(new_ss,&_ss); + loadseg(new_ss,&cpu_state.seg_ss); if (output) pclog("Load DS %04X\n",new_ds); - loadseg(new_ds,&_ds); + loadseg(new_ds,&cpu_state.seg_ds); if (is386) { - loadseg(0,&_fs); - loadseg(0,&_gs); + loadseg(0,&cpu_state.seg_fs); + loadseg(0,&cpu_state.seg_gs); } if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc); From f27b7f757a841d4878a6d5ff4cf90fb869dddc44 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 25 Jul 2018 20:16:58 +0100 Subject: [PATCH 0486/1050] Add recompiled versions of mem->reg, reg->mem and imm->mem versions of MOV. --- src/Makefile.am | 8 +- src/codegen.c | 47 ++ src/codegen.h | 4 + src/codegen_backend_arm.c | 144 +++++ src/codegen_backend_arm64.c | 153 +++++ src/codegen_backend_arm64_defs.h | 10 +- src/codegen_backend_arm64_ops.c | 613 +++++++++++++++++++++ src/codegen_backend_arm64_ops.h | 92 ++++ src/codegen_backend_arm64_uops.c | 675 ++++++++--------------- src/codegen_backend_arm_defs.h | 10 +- src/codegen_backend_arm_ops.c | 587 ++++++++++++++++++++ src/codegen_backend_arm_ops.h | 84 +++ src/codegen_backend_arm_uops.c | 588 +++++++------------- src/codegen_backend_x86-64.c | 192 +++++++ src/codegen_backend_x86-64_defs.h | 17 + src/codegen_backend_x86-64_ops.c | 888 ++++++++++++++++++++++++++++++ src/codegen_backend_x86-64_ops.h | 104 ++++ src/codegen_backend_x86-64_uops.c | 877 +++++++---------------------- src/codegen_backend_x86.c | 172 ++++++ src/codegen_backend_x86_defs.h | 8 + src/codegen_backend_x86_ops.c | 779 ++++++++++++++++++++++++++ src/codegen_backend_x86_ops.h | 100 ++++ src/codegen_backend_x86_uops.c | 810 +++++++-------------------- src/codegen_ir.c | 18 +- src/codegen_ir_defs.h | 74 ++- src/codegen_ops.c | 8 +- src/codegen_ops_mov.c | 229 +++++++- src/codegen_ops_mov.h | 13 + src/codegen_reg.c | 43 +- src/codegen_reg.h | 38 +- 30 files changed, 5225 insertions(+), 2160 deletions(-) create mode 100644 src/codegen_backend_arm64_ops.c create mode 100644 src/codegen_backend_arm64_ops.h create mode 100644 src/codegen_backend_arm_ops.c create mode 100644 src/codegen_backend_arm_ops.h create mode 100644 src/codegen_backend_x86-64_ops.c create mode 100644 src/codegen_backend_x86-64_ops.h create mode 100644 src/codegen_backend_x86_ops.c create mode 100644 src/codegen_backend_x86_ops.h diff --git a/src/Makefile.am b/src/Makefile.am index ab44ff7..18da9e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,20 +70,20 @@ pcem_SOURCES += wx-sdl2-midi.c endif if CPU_I386 -pcem_SOURCES += codegen_backend_x86.c codegen_backend_x86_uops.c +pcem_SOURCES += codegen_backend_x86.c codegen_backend_x86_ops.c codegen_backend_x86_uops.c pcem_CFLAGS += -msse2 endif if CPU_X86_64 -pcem_SOURCES += codegen_backend_x86-64.c codegen_backend_x86-64_uops.c +pcem_SOURCES += codegen_backend_x86-64.c codegen_backend_x86-64_ops.c codegen_backend_x86-64_uops.c endif if CPU_ARM -pcem_SOURCES += codegen_backend_arm.c codegen_backend_arm_uops.c +pcem_SOURCES += codegen_backend_arm.c codegen_backend_arm_ops.c codegen_backend_arm_uops.c endif if CPU_ARM64 -pcem_SOURCES += codegen_backend_arm64.c codegen_backend_arm64_uops.c +pcem_SOURCES += codegen_backend_arm64.c codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c endif if USE_NETWORKING diff --git a/src/codegen.c b/src/codegen.c index 96db8a6..5bd88bb 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -45,6 +45,41 @@ void codegen_generate_reset() has_ea = 0; } +void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) +{ + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; + + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, &block->data[BLOCK_GPF_OFFSET]); + + seg->checked = 1; +} +void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) +{ + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; + + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, &block->data[BLOCK_GPF_OFFSET]); + + seg->checked = 1; +} + static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { // pclog("codegen - mod=%i rm=%i reg=%i fetchdat=%08x\n", cpu_mod, cpu_rm, cpu_reg, fetchdat); @@ -203,6 +238,18 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin return op_ea_seg; } +x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +{ + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; + + if (op_32 & 0x200) + return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, 0); + + return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); +} + static uint8_t opcode_modrm[256] = { 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ diff --git a/src/codegen.h b/src/codegen.h index 8106c1c..9503b25 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -263,6 +263,10 @@ void codegen_generate_seg_restore(); void codegen_set_op32(); void codegen_flush(); void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); +struct ir_data_t; +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32); +void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); extern int cpu_block_end; extern uint32_t codegen_endpc; diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 41aeb71..09630ed 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -5,6 +5,7 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" +#include "codegen_backend_arm_ops.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -15,6 +16,14 @@ #include #endif +void *codegen_mem_load_byte; +void *codegen_mem_load_word; +void *codegen_mem_load_long; + +void *codegen_mem_store_byte; +void *codegen_mem_store_word; +void *codegen_mem_store_long; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_R4, @@ -22,6 +31,137 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_R6, }; +static void build_load_routine(codeblock_t *block, int size) +{ + uint32_t *branch_offset; + uint8_t *misaligned_offset; + + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmemb386l + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2); + host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); + if (size != 1) + { + host_arm_TST_IMM(block, REG_R0, size-1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R1, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1) + host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 2) + host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4) + host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); + + *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_SP, -4); + if (size == 1) + host_arm_BL(block, (uintptr_t)readmemb386l); + else if (size == 2) + host_arm_BL(block, (uintptr_t)readmemwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t)readmemll); + else + fatal("build_load_routine - unknown size %i\n", size); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_SP, 4); + + block_pos = (block_pos + 63) & ~63; +} + +static void build_store_routine(codeblock_t *block, int size) +{ + uint8_t *branch_offset; + uint8_t *misaligned_offset; + + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmemb386l + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2); + host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); + if (size != 1) + { + host_arm_TST_IMM(block, REG_R0, size-1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R2, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1) + host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 2) + host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4) + host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); + + *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_SP, -4); + if (size == 1) + host_arm_BL(block, (uintptr_t)writememb386l); + else if (size == 2) + host_arm_BL(block, (uintptr_t)writememwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t)writememll); + else + fatal("build_store_routine - unknown size %i\n", size); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_SP, 4); + + block_pos = (block_pos + 63) & ~63; +} + +static void build_loadstore_routines(codeblock_t *block) +{ + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4); + + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4); +} + void codegen_backend_init() { int c; @@ -57,6 +197,10 @@ void codegen_backend_init() } #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + + block_current = BLOCK_SIZE; + block_pos = 0; + build_loadstore_routines(&codeblock[block_current]); } /*R11 - literal pool diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index e433f43..9df86f9 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -5,6 +5,7 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_arm64_defs.h" +#include "codegen_backend_arm64_ops.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -15,6 +16,14 @@ #include #endif +void *codegen_mem_load_byte; +void *codegen_mem_load_word; +void *codegen_mem_load_long; + +void *codegen_mem_store_byte; +void *codegen_mem_store_word; +void *codegen_mem_store_long; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_X19, @@ -24,6 +33,145 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_X23 }; +static void build_load_routine(codeblock_t *block, int size) +{ + uint32_t *branch_offset; + uint8_t *misaligned_offset; + int offset; + + /*In - W0 = address + Out - W0 = data, W1 = abrt*/ + /*MOV W1, W0, LSR #12 + MOV X2, #readlookup2 + LDR X1, [X2, X1, LSL #3] + CMP X1, #-1 + BEQ + + LDRB W0, [X1, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL readmemb386l + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); + offset = add_literal_q(block, (uintptr_t)readlookup2); + host_arm64_LDR_LITERAL_X(block, REG_X2, offset); + host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); + if (size != 1) + { + host_arm64_TST_IMM(block, REG_W0, size-1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X1, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1) + host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 2) + host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4) + host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); + host_arm64_MOVZ_IMM(block, REG_W1, 0); + host_arm64_RET(block, REG_X30); + + host_arm64_branch_set_offset(branch_offset, &block->data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block->data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); + if (size == 1) + host_arm64_call(block, (uintptr_t)readmemb386l); + else if (size == 2) + host_arm64_call(block, (uintptr_t)readmemwl); + else if (size == 4) + host_arm64_call(block, (uintptr_t)readmemll); + else + fatal("build_load_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_RET(block, REG_X30); + + block_pos = (block_pos + 63) & ~63; +} + +static void build_store_routine(codeblock_t *block, int size) +{ + uint8_t *branch_offset; + uint8_t *misaligned_offset; + int offset; + + /*In - R0 = address, R1 = data + Out - R1 = abrt*/ + /*MOV W2, W0, LSR #12 + MOV X3, #writelookup2 + LDR X2, [X3, X2, LSL #3] + CMP X2, #-1 + BEQ + + STRB W1, [X2, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL writememb386l + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); + offset = add_literal_q(block, (uintptr_t)writelookup2); + host_arm64_LDR_LITERAL_X(block, REG_X3, offset); + host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); + if (size != 1) + { + host_arm64_TST_IMM(block, REG_W0, size-1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X2, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1) + host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 2) + host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4) + host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); + host_arm64_MOVZ_IMM(block, REG_X1, 0); + host_arm64_RET(block, REG_X30); + + host_arm64_branch_set_offset(branch_offset, &block->data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block->data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); + if (size == 1) + host_arm64_call(block, (uintptr_t)writememb386l); + else if (size == 2) + host_arm64_call(block, (uintptr_t)writememwl); + else if (size == 4) + host_arm64_call(block, (uintptr_t)writememll); + else + fatal("build_store_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_RET(block, REG_X30); + + block_pos = (block_pos + 63) & ~63; +} + +static void build_loadstore_routines(codeblock_t *block) +{ + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4); + + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4); +} + void codegen_backend_init() { int c; @@ -59,6 +207,11 @@ void codegen_backend_init() } #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + + block_current = BLOCK_SIZE; + block_pos = 0; + codegen_reset_literal_pool(&codeblock[block_current]); + build_loadstore_routines(&codeblock[block_current]); } /*R11 - literal pool diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index 7de61f0..48e58ec 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -75,4 +75,12 @@ #define REG_TEMP REG_X7 -#define CODEGEN_HOST_REGS 5 \ No newline at end of file +#define CODEGEN_HOST_REGS 5 + +extern void *codegen_mem_load_byte; +extern void *codegen_mem_load_word; +extern void *codegen_mem_load_long; + +extern void *codegen_mem_store_byte; +extern void *codegen_mem_store_word; +extern void *codegen_mem_store_long; \ No newline at end of file diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c new file mode 100644 index 0000000..4effa1a --- /dev/null +++ b/src/codegen_backend_arm64_ops.c @@ -0,0 +1,613 @@ +#ifdef __aarch64__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_arm64_defs.h" +#include "codegen_backend_arm64_ops.h" + + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +#define Rt(x) (x) +#define Rd(x) (x) +#define Rn(x) ((x) << 5) +#define Rt2(x) ((x) << 10) +#define Rm(x) ((x) << 16) + +#define shift_imm6(x) ((x) << 10) + +#define DATA_OFFSET_UP (1 << 23) +#define DATA_OFFSET_DOWN (0 << 23) + +#define COND_EQ (0x0) +#define COND_NE (0x1) + +#define OPCODE_SHIFT 24 +#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) +#define OPCODE_BCOND (0x54 << OPCODE_SHIFT) +#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) +#define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) +#define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) +#define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) +#define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) +#define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) +#define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) +#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) + +#define OPCODE_AND_IMM (0x024 << 23) +#define OPCODE_ANDS_IMM (0x0e4 << 23) +#define OPCODE_EOR_IMM (0x0a4 << 23) +#define OPCODE_MOVK_W (0x0e5 << 23) +#define OPCODE_MOVZ_W (0x0a5 << 23) +#define OPCODE_ORR_IMM (0x064 << 23) + +#define OPCODE_BFI (0x0cc << 22) +#define OPCODE_LDR_IMM_W (0x2e5 << 22) +#define OPCODE_LDRB_IMM_W (0x0e5 << 22) +#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) +#define OPCODE_STP_PREIDX_X (0x2a6 << 22) +#define OPCODE_STR_IMM_W (0x2e4 << 22) +#define OPCODE_STR_IMM_Q (0x3e4 << 22) +#define OPCODE_STRB_IMM (0x0e4 << 22) +#define OPCODE_UBFX (0x14c << 22) + +#define OPCODE_ADD_LSL (0x058 << 21) +#define OPCODE_ADD_LSR (0x05a << 21) +#define OPCODE_AND_ASR (0x054 << 21) +#define OPCODE_AND_LSL (0x050 << 21) +#define OPCODE_AND_ROR (0x056 << 21) +#define OPCODE_ANDS_LSL (0x350 << 21) +#define OPCODE_EOR_LSL (0x250 << 21) +#define OPCODE_ORR_LSL (0x150 << 21) +#define OPCODE_ORR_LSR (0x152 << 21) +#define OPCODE_SUB_LSL (0x258 << 21) +#define OPCODE_SUB_LSR (0x25a << 21) + +#define OPCODE_BLR (0xd63f0000) +#define OPCODE_LDR_REG (0xb8606800) +#define OPCODE_LDRB_REG (0x38606800) +#define OPCODE_LDRH_REG (0x78606800) +#define OPCODE_LDRX_REG_LSL3 (0xf8607800) +#define OPCODE_NOP (0xd503201f) +#define OPCODE_RET (0xd65f0000) +#define OPCODE_STR_REG (0xb8206800) +#define OPCODE_STRB_REG (0x38206800) +#define OPCODE_STRH_REG (0x78206800) + +#define DATPROC_SHIFT(sh) (sh << 10) +#define DATPROC_IMM_SHIFT(sh) (sh << 22) +#define MOV_WIDE_HW(hw) (hw << 21) + +#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) +#define IMM12(imm_data) ((imm_data) << 10) +#define IMM16(imm_data) ((imm_data) << 5) + +#define IMMN(immn) ((immn) << 22) +#define IMMR(immr) ((immr) << 16) +#define IMMS(imms) ((imms) << 10) + +#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) + +#define OFFSET12_B(offset) (offset << 10) +#define OFFSET12_W(offset) ((offset >> 2) << 10) +#define OFFSET12_Q(offset) ((offset >> 3) << 10) + +static int literal_offset = 0; +void codegen_reset_literal_pool(codeblock_t *block) +{ + literal_offset = 0; +} + +/*Returns true if offset fits into 19 bits*/ +static int offset_is_19bit(int offset) +{ + if (offset >= (1 << (18+2))) + return 0; + if (offset < -(1 << (18+2))) + return 0; + return 1; +} + +int add_literal(codeblock_t *block, uint32_t data) +{ + if (literal_offset >= 4096) + fatal("add_literal - literal pool full\n"); + + *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; + + literal_offset += 4; + + return literal_offset - 4; +} + +int add_literal_q(codeblock_t *block, uint64_t data) +{ + if (literal_offset & 4) + literal_offset += 4; + + if (literal_offset >= 4096-4) + fatal("add_literal - literal pool full\n"); + + *(uint64_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; + + literal_offset += 8; + + return literal_offset - 8; +} + +static inline int imm_is_imm16(uint32_t imm_data) +{ + if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) + return 1; + return 0; +} +static inline int imm_is_imm12(uint32_t imm_data) +{ + if (!(imm_data & 0xfffff000) || !(imm_data & 0xff000fff)) + return 1; + return 0; +} + +void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) + { + host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); + } + else if (!(imm_data & 0xff000000)) + { + if (imm_data & 0xfff) + { + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else + { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07)); + } + else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else if (imm_data == 0xffffff00) + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); + } + else if (imm_data == 0xffff00ff) + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); + } + else if (imm_data == 0x0000ff00) + { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07)); + } + else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else if (imm_data == 0xffffff00) + { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); + } + else if (imm_data == 0xffff00ff) + { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); + } + else if (imm_data == 0x0000ff00) + { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} + +void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); +} + +void host_arm64_BLR(codeblock_t *block, int addr_reg) +{ + codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); +} + +uint32_t *host_arm64_BEQ_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_EQ); + return &block->data[block_pos-4]; +} +uint32_t *host_arm64_BNE_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_NE); + return &block->data[block_pos-4]; +} + +void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) +{ + int offset = (uintptr_t)dest - (uintptr_t)opcode; + *opcode |= OFFSET19(offset); +} + +void host_arm64_BEQ(codeblock_t *block, void *dest) +{ + uint32_t *opcode = host_arm64_BEQ_(block); + host_arm64_branch_set_offset(opcode, dest); +} + +void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) +{ + int offset = dest - (uintptr_t)&block->data[block_pos]; + if (!offset_is_19bit(offset)) + fatal("host_arm64_CBNZ - offset out of range %x\n", offset); + codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); +} + +void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) +{ + if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) + { + host_arm64_CMP_IMM(block, src_n_reg, -(int32_t)imm_data); + } + else if (!(imm_data & 0xfffff000)) + { + codegen_addlong(block, OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } + else + fatal("CMN_IMM %08x\n", imm_data); +} +void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) +{ + if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) + { + host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t)imm_data); + } + else if (!(imm_data & 0xfffffffffffff000ull)) + { + codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } + else + fatal("CMNX_IMM %08x\n", imm_data); +} + +void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) +{ + if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) + { + host_arm64_CMN_IMM(block, src_n_reg, -(int32_t)imm_data); + } + else if (!(imm_data & 0xfffff000)) + { + codegen_addlong(block, OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } + else + fatal("CMP_IMM %08x\n", imm_data); +} +void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) +{ + if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) + { + host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t)imm_data); + } + else if (!(imm_data & 0xfffffffffffff000ull)) + { + codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } + else + fatal("CMPX_IMM %08x\n", imm_data); +} + +void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +{ + if (!in_range7_x(offset)) + fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); +} + +void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_w(offset)) + fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); +} + +void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset) +{ + int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; + + if (!offset_is_19bit(offset)) + fatal("host_arm64_CBNZ - offset out of range %x\n", offset); + + codegen_addlong(block, OPCODE_LDR_LITERAL_W | OFFSET19(offset) | Rt(dest_reg)); +} +void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset) +{ + int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; + + if (!offset_is_19bit(offset)) + fatal("host_arm64_CBNZ - offset out of range %x\n", offset); + + codegen_addlong(block, OPCODE_LDR_LITERAL_X | OFFSET19(offset) | Rt(dest_reg)); +} +void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} + +void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_b(offset)) + fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} + +void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} + +void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} + +void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + int hw; + + if (!imm_is_imm16(imm_data)) + fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); + + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; + + codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); +} + +void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + int hw; + + if (!imm_is_imm16(imm_data)) + fatal("MOVK_IMM - imm not representable %08x\n", imm_data); + + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; + + codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); +} + +void host_arm64_NOP(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_NOP); +} + +void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else if (imm_data == 0xffff0000) + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x0f)); + } + else if (imm_data == 0xffffff00) + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); + } + else if (imm_data == 0xffff00ff) + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_RET(codeblock_t *block, int reg) +{ + codegen_addlong(block, OPCODE_RET | Rn(reg)); +} + +void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +{ + if (!in_range7_x(offset)) + fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); +} + +void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_w(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_q(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} + +void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_b(offset)) + fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} + +void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} + +void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) + { + host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); + } + else if (!(imm_data & 0xff000000)) + { + if (imm_data & 0xfff) + { + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else + { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + +void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); +} + + +void host_arm64_call(codeblock_t *block, void *dst_addr) +{ + int offset = add_literal_q(block, (uintptr_t)dst_addr); + host_arm64_LDR_LITERAL_X(block, REG_X16, offset); + host_arm64_BLR(block, REG_X16); +} + +void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) +{ + if (imm_is_imm16(imm_data)) + host_arm64_MOVZ_IMM(block, reg, imm_data); + else + { + host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); + } +} + +#endif \ No newline at end of file diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h new file mode 100644 index 0000000..6178c6b --- /dev/null +++ b/src/codegen_backend_arm64_ops.h @@ -0,0 +1,92 @@ +void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); +void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + +void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); +void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + +void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); + +void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); + +void host_arm64_BLR(codeblock_t *block, int addr_reg); + +void host_arm64_BEQ(codeblock_t *block, void *dest); + +uint32_t *host_arm64_BEQ_(codeblock_t *block); +uint32_t *host_arm64_BNE_(codeblock_t *block); + +void host_arm64_branch_set_offset(uint32_t *opcode, void *dest); + +void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); + +void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); +void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data); + +void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); +void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data); + +void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); +void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + +void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); + +void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset); +void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset); +void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); + +void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); + +void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); + +void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); + +void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); +void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); + +void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data); +void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data); + +void host_arm64_NOP(codeblock_t *block); + +void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); +void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + +void host_arm64_RET(codeblock_t *block, int reg); + +void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); + +void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); + +void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); + +void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); + +void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); +void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + +#define host_arm64_TST_IMM(block, src_n_reg, imm_data) host_arm64_ANDS_IMM(block, REG_XZR, src_n_reg, imm_data) + +void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); + +void host_arm64_call(codeblock_t *block, void *dst_addr); +void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); + + +#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) +#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) +#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) +#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) + + +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); + +int add_literal_q(codeblock_t *block, uint64_t data); \ No newline at end of file diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index b641a4b..8b5aad0 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -4,459 +4,9 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_arm64_defs.h" +#include "codegen_backend_arm64_ops.h" #include "codegen_ir_defs.h" -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -#define Rt(x) (x) -#define Rd(x) (x) -#define Rn(x) ((x) << 5) -#define Rt2(x) ((x) << 10) -#define Rm(x) ((x) << 16) - -#define shift_imm6(x) ((x) << 10) - -#define DATA_OFFSET_UP (1 << 23) -#define DATA_OFFSET_DOWN (0 << 23) - -#define COND_SHIFT 28 -#define COND_NE (0x1 << COND_SHIFT) -#define COND_AL (0xe << COND_SHIFT) - -#define OPCODE_SHIFT 24 -#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) -#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) -#define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) -#define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) - -#define OPCODE_AND_IMM (0x024 << 23) -#define OPCODE_EOR_IMM (0x0a4 << 23) -#define OPCODE_MOVK_W (0x0e5 << 23) -#define OPCODE_MOVZ_W (0x0a5 << 23) -#define OPCODE_ORR_IMM (0x064 << 23) - -#define OPCODE_BFI (0x0cc << 22) -#define OPCODE_LDR_IMM_W (0x2e5 << 22) -#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) -#define OPCODE_STP_PREIDX_X (0x2a6 << 22) -#define OPCODE_STR_IMM_W (0x2e4 << 22) -#define OPCODE_STR_IMM_Q (0x3e4 << 22) -#define OPCODE_STRB_IMM (0x0e4 << 22) -#define OPCODE_UBFX (0x14c << 22) - -#define OPCODE_ADD_LSL (0x058 << 21) -#define OPCODE_ADD_LSR (0x05a << 21) -#define OPCODE_AND_ASR (0x054 << 21) -#define OPCODE_AND_LSL (0x050 << 21) -#define OPCODE_AND_ROR (0x056 << 21) -#define OPCODE_EOR_LSL (0x250 << 21) -#define OPCODE_ORR_LSL (0x150 << 21) -#define OPCODE_ORR_LSR (0x152 << 21) -#define OPCODE_SUB_LSL (0x258 << 21) -#define OPCODE_SUB_LSR (0x25a << 21) - -#define OPCODE_BLR (0xd63f0000) -#define OPCODE_NOP (0xd503201f) -#define OPCODE_RET (0xd65f0000) - -#define DATPROC_SHIFT(sh) (sh << 10) -#define DATPROC_IMM_SHIFT(sh) (sh << 22) -#define MOV_WIDE_HW(hw) (hw << 21) - -#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) -#define IMM12(imm_data) ((imm_data) << 10) -#define IMM16(imm_data) ((imm_data) << 5) - -#define IMMN(immn) ((immn) << 22) -#define IMMR(immr) ((immr) << 16) -#define IMMS(imms) ((imms) << 10) - -#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) - -#define OFFSET12_B(offset) (offset << 10) -#define OFFSET12_W(offset) ((offset >> 2) << 10) -#define OFFSET12_Q(offset) ((offset >> 3) << 10) - -static int literal_offset = 0; -void codegen_reset_literal_pool(codeblock_t *block) -{ - literal_offset = 0; -} - -/*Returns true if offset fits into 19 bits*/ -static int offset_is_19bit(int offset) -{ - if (offset >= (1 << (18+2))) - return 0; - if (offset < -(1 << (18+2))) - return 0; - return 1; -} - -#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) -#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) -#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) -#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) - -int add_literal(codeblock_t *block, uint32_t data) -{ - if (literal_offset >= 4096) - fatal("add_literal - literal pool full\n"); - - *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; - - literal_offset += 4; - - return literal_offset - 4; -} - -int add_literal_q(codeblock_t *block, uint64_t data) -{ - if (literal_offset & 4) - literal_offset += 4; - - if (literal_offset >= 4096-4) - fatal("add_literal - literal pool full\n"); - - *(uint64_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; - - literal_offset += 8; - - return literal_offset - 8; -} - -static inline int imm_is_imm16(uint32_t imm_data) -{ - if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) - return 1; - return 0; -} -static inline int imm_is_imm12(uint32_t imm_data) -{ - if (!(imm_data & 0xfffff000) || !(imm_data & 0xff000fff)) - return 1; - return 0; -} - -void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); -void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); - -void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -//12001c00 S=0 R=7 -void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07)); - } - else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else if (imm_data == 0xffffff00) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); - } - else if (imm_data == 0xffff00ff) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); - } - else if (imm_data == 0x0000ff00) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); -} - -void host_arm64_BLR(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); -} - -void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) -{ - int offset = dest - (uintptr_t)&block->data[block_pos]; - if (!offset_is_19bit(offset)) - fatal("host_arm64_CBNZ - offset out of range %x\n", offset); - codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); -} - -void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) -{ - if (!in_range7_x(offset)) - fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); -} - -void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_w(offset)) - fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); -} - -void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset) -{ - int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; - - if (!offset_is_19bit(offset)) - fatal("host_arm64_CBNZ - offset out of range %x\n", offset); - - codegen_addlong(block, OPCODE_LDR_LITERAL_W | OFFSET19(offset) | Rt(dest_reg)); -} -void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset) -{ - int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; - - if (!offset_is_19bit(offset)) - fatal("host_arm64_CBNZ - offset out of range %x\n", offset); - - codegen_addlong(block, OPCODE_LDR_LITERAL_X | OFFSET19(offset) | Rt(dest_reg)); -} - -void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - if (dst_reg != src_m_reg) - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - int hw; - - if (!imm_is_imm16(imm_data)) - fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); - - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; - - codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); -} - -void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - int hw; - - if (!imm_is_imm16(imm_data)) - fatal("MOVK_IMM - imm not representable %08x\n", imm_data); - - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; - - codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); -} - -void host_arm64_NOP(codeblock_t *block) -{ - codegen_addlong(block, OPCODE_NOP); -} - -void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else if (imm_data == 0xffff0000) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x0f)); - } - else if (imm_data == 0xffffff00) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); - } - else if (imm_data == 0xffff00ff) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_RET(codeblock_t *block, int reg) -{ - codegen_addlong(block, OPCODE_RET | Rn(reg)); -} - -void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) -{ - if (!in_range7_x(offset)) - fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); -} - -void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_w(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); -} -void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_q(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); -} -void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_b(offset)) - fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); -} - -void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); -} - -void host_arm64_call(codeblock_t *block, void *dst_addr) -{ - int offset = add_literal_q(block, (uintptr_t)dst_addr); - host_arm64_LDR_LITERAL_X(block, REG_X16, offset); - host_arm64_BLR(block, REG_X16); -} - -void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) -{ - if (imm_is_imm16(imm_data)) - host_arm64_MOVZ_IMM(block, reg, imm_data); - else - { - host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); - } -} - #define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) #define REG_IS_L(size) (size == IREG_SIZE_L) @@ -605,7 +155,7 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) } else fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - + return 0; } @@ -617,6 +167,22 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm64_BEQ(block, uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); @@ -642,6 +208,186 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) + { + host_arm64_call(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_call(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_arm64_call(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } + else if (REG_IS_BH(dest_size)) + { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } + else if (REG_IS_L(dest_size)) + { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } + + return 0; +} +static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) + { + host_arm64_call(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_call(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_arm64_call(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } + else if (REG_IS_BH(dest_size)) + { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } + else if (REG_IS_L(dest_size)) + { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } + + return 0; +} + +static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); + host_arm64_call(block, codegen_mem_store_byte); + } + else if (REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); + host_arm64_call(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); + host_arm64_call(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); + host_arm64_call(block, codegen_mem_store_byte); + } + else if (REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); + host_arm64_call(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); + host_arm64_call(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_byte); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_word); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_long); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -799,7 +545,7 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) } else fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - + return 0; } @@ -978,7 +724,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) } else fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - + return 0; } @@ -994,6 +740,15 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, @@ -1009,9 +764,19 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SUB & UOP_MASK] = codegen_SUB, [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); +} + void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 1fadfa1..3ec520b 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -45,4 +45,12 @@ #define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) -#define CODEGEN_HOST_REGS 3 \ No newline at end of file +#define CODEGEN_HOST_REGS 3 + +extern void *codegen_mem_load_byte; +extern void *codegen_mem_load_word; +extern void *codegen_mem_load_long; + +extern void *codegen_mem_store_byte; +extern void *codegen_mem_store_word; +extern void *codegen_mem_store_long; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c new file mode 100644 index 0000000..f7772ae --- /dev/null +++ b/src/codegen_backend_arm_ops.c @@ -0,0 +1,587 @@ +#ifdef __ARM_EABI__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_arm_defs.h" +#include "codegen_backend_arm_ops.h" + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +#define Rm(x) (x) +#define Rd(x) ((x) << 12) +#define Rn(x) ((x) << 16) + +#define DATA_OFFSET_UP (1 << 23) +#define DATA_OFFSET_DOWN (0 << 23) + +#define COND_SHIFT 28 +#define COND_EQ (0x0 << COND_SHIFT) +#define COND_NE (0x1 << COND_SHIFT) +#define COND_AL (0xe << COND_SHIFT) + +#define OPCODE_SHIFT 20 +#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) +#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) +#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) +#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) +#define OPCODE_B (0xa0 << OPCODE_SHIFT) +#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) +#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) +#define OPCODE_BL (0xb0 << OPCODE_SHIFT) +#define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) +#define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) +#define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) +#define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) +#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) +#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) +#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) +#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) +#define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) +#define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) +#define OPCODE_LDRB_IMM (0x55 << OPCODE_SHIFT) +#define OPCODE_LDRB_REG (0x7d << OPCODE_SHIFT) +#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) +#define OPCODE_MOVT_IMM (0x34 << OPCODE_SHIFT) +#define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) +#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) +#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) +#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) +#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) +#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) +#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) +#define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) +#define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) +#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) +#define OPCODE_STRB_REG (0x7c << OPCODE_SHIFT) +#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) +#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) +#define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) +#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) + +#define OPCODE_BFI 0xe7c00010 +#define OPCODE_BLX 0xe12fff30 +#define OPCODE_LDRH_REG 0xe19000b0 +#define OPCODE_STRH_REG 0xe18000b0 +#define OPCODE_UADD8 0xe6500f90 +#define OPCODE_UADD16 0xe6500f10 +#define OPCODE_USUB8 0xe6500ff0 +#define OPCODE_USUB16 0xe6500f70 +#define OPCODE_UXTB 0xe6ef0070 +#define OPCODE_UXTH 0xe6ff0070 + +#define B_OFFSET(x) (((x) >> 2) & 0xffffff) + +#define SHIFT_TYPE_SHIFT 5 +#define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) +#define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) +#define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) +#define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) + +#define SHIFT_TYPE_IMM (0 << 4) +#define SHIFT_TYPE_REG (1 << 4) + +#define SHIFT_IMM_SHIFT 7 +#define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +#define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) + +#define BFI_lsb(lsb) ((lsb) << 7) +#define BFI_msb(msb) ((msb) << 16) + +#define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) + +#define MOVT_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) +#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) + +static int literal_offset = 0; +void codegen_reset_literal_pool(codeblock_t *block) +{ + literal_offset = 0; +} + +int add_literal(codeblock_t *block, uint32_t data) +{ + int c; + + if (literal_offset >= 4096) + fatal("add_literal - literal pool full\n"); + + /*Search for pre-existing value*/ + for (c = 0; c < literal_offset; c += 4) + { + if (*(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + c] == data) + return c; + } + + *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; + + literal_offset += 4; + + return literal_offset - 4; +} + + +static inline uint32_t arm_data_offset(int offset) +{ + if (offset < -0xffc || offset > 0xffc) + fatal("arm_data_offset out of range - %i\n", offset); + + if (offset >= 0) + return offset | DATA_OFFSET_UP; + return (-offset) | DATA_OFFSET_DOWN; +} + +static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) +{ + int shift = 0; +//pclog("get_arm_imm - imm_data=%08x\n", imm_data); + if (!(imm_data & 0xffff)) + { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) + { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) + { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) + { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ + return 0; +//pclog(" imm_data=%02x shift=%i\n", imm_data, shift); + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; +} + +static inline int in_range(void *addr, void *base) +{ + int diff = (uintptr_t)addr - (uintptr_t)base; + + if (diff < -4095 || diff > 4095) + return 0; + return 1; +} + +void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if ((int32_t)imm < 0 && imm != 0x80000000) + { + host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); + } + else if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else if (get_arm_imm(~imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); +} + +void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} +void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} + +void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) +{ + uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BLX(block, REG_R3); + } + else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); +} +void host_arm_BLX(codeblock_t *block, int addr_reg) +{ + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); +} + +uint32_t *host_arm_BEQ_(codeblock_t *block) +{ + codegen_addlong(block, COND_EQ | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BNE_(codeblock_t *block) +{ + codegen_addlong(block, COND_NE | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} + +void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) +{ + uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); + + codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); +} +void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) +{ + uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); + + codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); +} + +void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if ((int32_t)imm < 0 && imm != 0x80000000) + { + host_arm_CMP_IMM(block, src_reg, -(int32_t)imm); + } + else if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); + } +} +void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if ((int32_t)imm < 0 && imm != 0x80000000) + { + host_arm_CMN_IMM(block, src_reg, -(int32_t)imm); + } + else if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); + } +} +void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +{ + codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); +} + +void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +} +void host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +} +void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) +{ + if (in_range(p, &cpu_state)) + host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("LDRB_ABS - not in range\n"); +} +void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +} +void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); +} + +void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); + } + else + { + host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); + if (imm >> 16) + host_arm_MOVT_IMM(block, dst_reg, imm >> 16); + } +} + +void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); +} +void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); +} + +void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +{ + codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); +} +void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +{ + codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); +} + +void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_ORR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} + +void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +{ + codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); +} + +void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +} +void host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +} +void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +} +void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); +} + +void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if ((int32_t)imm < 0 && imm != 0x80000000) + { + host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); + } + else if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} +void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} + +void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_TST_REG(block, src_reg, REG_TEMP); + } +} +void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) +{ + codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); +} + +void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +} + +void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +{ + codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +} + +void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +{ + codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +} + +#endif \ No newline at end of file diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h new file mode 100644 index 0000000..31aee46 --- /dev/null +++ b/src/codegen_backend_arm_ops.h @@ -0,0 +1,84 @@ +void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +#define host_arm_ADD_REG(block, dst_reg, src_reg_n, src_reg_m) host_arm_ADD_REG_LSL(block, dst_reg, src_reg_n, src_reg_m, 0) +void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); + +void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_BL(codeblock_t *block, uintptr_t dest_addr); +void host_arm_BLX(codeblock_t *block, int addr_reg); +uint32_t *host_arm_BEQ_(codeblock_t *block); +uint32_t *host_arm_BNE_(codeblock_t *block); +void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr); +void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr); + +void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm); +void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift); + +void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm); +void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift); + +void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); + +void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); +void host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset); +#define host_arm_LDR_REG(block, dst_reg, addr_reg, offset_reg) host_arm_LDR_REG_LSL(block, dst_reg, addr_reg, offset_reg, 0) +void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift); + +void host_arm_LDRB_ABS(codeblock_t *block, int dst, void *p); +void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); +#define host_arm_LDRB_REG(block, dst_reg, addr_reg, offset_reg) host_arm_LDRB_REG_LSL(block, dst_reg, addr_reg, offset_reg, 0) +void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift); + +void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg); + +void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm); +#define host_arm_MOV_REG(block, dst_reg, src_reg) host_arm_MOV_REG_LSL(block, dst_reg, src_reg, 0) +void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm); +void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm); + +void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift); + +void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); + +void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset); +void host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset); +#define host_arm_STR_REG(block, src_reg, addr_reg, offset_reg) host_arm_STR_REG_LSL(block, src_reg, addr_reg, offset_reg, 0) +void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift); + +void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset); +#define host_arm_STRB_REG(block, src_reg, addr_reg, offset_reg) host_arm_STRB_REG_LSL(block, src_reg, addr_reg, offset_reg, 0) +void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift); + +void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg); + +void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +void host_arm_TST_IMM(codeblock_t *block, int src_reg1, uint32_t imm); +void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2); + +void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); +void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 17fd823..b6f5f41 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -4,125 +4,9 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" +#include "codegen_backend_arm_ops.h" #include "codegen_ir_defs.h" -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -#define Rm(x) (x) -#define Rd(x) ((x) << 12) -#define Rn(x) ((x) << 16) - -#define DATA_OFFSET_UP (1 << 23) -#define DATA_OFFSET_DOWN (0 << 23) - -#define COND_SHIFT 28 -#define COND_NE (0x1 << COND_SHIFT) -#define COND_AL (0xe << COND_SHIFT) - -#define OPCODE_SHIFT 20 -#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) -#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) -#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) -#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) -#define OPCODE_B (0xa0 << OPCODE_SHIFT) -#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) -#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) -#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) -#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) -#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) -#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) -#define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) -#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) -#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) -#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) -#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) -#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) -#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) -#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) -#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) -#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) -#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) - -#define OPCODE_BFI 0xe7c00010 -#define OPCODE_BLX 0xe12fff30 -#define OPCODE_UADD8 0xe6500f90 -#define OPCODE_UADD16 0xe6500f10 -#define OPCODE_USUB8 0xe6500ff0 -#define OPCODE_USUB16 0xe6500f70 -#define OPCODE_UXTB 0xe6ef0070 -#define OPCODE_UXTH 0xe6ff0070 - -#define B_OFFSET(x) (((x) >> 2) & 0xffffff) - -#define SHIFT_TYPE_SHIFT 5 -#define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) - -#define SHIFT_TYPE_IMM (0 << 4) -#define SHIFT_TYPE_REG (1 << 4) - -#define SHIFT_IMM_SHIFT 7 -#define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) - -#define BFI_lsb(lsb) ((lsb) << 7) -#define BFI_msb(msb) ((msb) << 16) - -#define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) - -#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) - -static int literal_offset = 0; -void codegen_reset_literal_pool(codeblock_t *block) -{ - literal_offset = 0; -} - -int add_literal(codeblock_t *block, uint32_t data) -{ - int c; - - if (literal_offset >= 4096) - fatal("add_literal - literal pool full\n"); - - /*Search for pre-existing value*/ - for (c = 0; c < literal_offset; c += 4) - { - if (*(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + c] == data) - return c; - } - - *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; - - literal_offset += 4; - - return literal_offset - 4; -} - - -static inline uint32_t arm_data_offset(int offset) -{ - if (offset < -0xffc || offset > 0xffc) - fatal("arm_data_offset out of range - %i\n", offset); - - if (offset >= 0) - return offset | DATA_OFFSET_UP; - return (-offset) | DATA_OFFSET_DOWN; -} - static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { int shift = 0; @@ -163,261 +47,6 @@ static inline int in_range(void *addr, void *base) return 1; } -void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); - -void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); - host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} - -void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); - host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} - -void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); -} - -void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} -void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); -} - -void host_arm_BLX(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); -} - -void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; - - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); - - codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); -} - -void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); - host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} - -void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) -{ - codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); -} - -void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); -} - -void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); - } - else - { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, dst_reg, REG_LITERAL, offset); - } -} - -void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); -} -void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); -} - -void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) -{ - codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); -} - -void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); -} - -void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); - host_arm_ORR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} - -void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); -} - -void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) -{ - codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); -} - -void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); -} - -void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); -} - -void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); - host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} -void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); -} - -void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) -{ - codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); -} - -void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); -} - -void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); -} - -void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); -} - -void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); -} - -void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) -{ - codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); -} - -void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) -{ - codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); -} - void host_arm_call(codeblock_t *block, void *dst_addr) { int offset = add_literal(block, (uintptr_t)dst_addr); @@ -593,6 +222,22 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm_BEQ(block, uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { uint32_t arm_imm; @@ -646,6 +291,190 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) + { + host_arm_BL(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_arm_BL(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_arm_BL(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } + else if (REG_IS_BH(dest_size)) + { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } + else if (REG_IS_W(dest_size)) + { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } + else if (REG_IS_L(dest_size)) + { + host_arm_MOV_REG(block, dest_reg, REG_R0); + } + + return 0; +} + +static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) + { + host_arm_BL(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_arm_BL(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_arm_BL(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } + else if (REG_IS_BH(dest_size)) + { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } + else if (REG_IS_W(dest_size)) + { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } + else if (REG_IS_L(dest_size)) + { + host_arm_MOV_REG(block, dest_reg, REG_R0); + } + + return 0; +} + +static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) + { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (REG_IS_B(src_size)) + { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, codegen_mem_store_byte); + } + else if (REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); + host_arm_BL(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, codegen_mem_store_byte); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, codegen_mem_store_word); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, codegen_mem_store_long); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1015,11 +844,20 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - + [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, @@ -1030,7 +868,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SUB & UOP_MASK] = codegen_SUB, [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 36b4567..deda8ef 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -3,6 +3,8 @@ #include "ibm.h" #include "codegen.h" #include "codegen_backend.h" +#include "codegen_backend_x86-64_defs.h" +#include "codegen_backend_x86-64_ops.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -13,6 +15,14 @@ #include #endif +void *codegen_mem_load_byte; +void *codegen_mem_load_word; +void *codegen_mem_load_long; + +void *codegen_mem_store_byte; +void *codegen_mem_store_word; +void *codegen_mem_store_long; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_EAX, @@ -22,6 +32,183 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = static void *mem_abrt_rout; +static void build_load_routine(codeblock_t *block, int size) +{ + uint8_t *branch_offset; + uint8_t *misaligned_offset; + + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV RSI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[RSI+RCX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmemb386l + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t)(uintptr_t)readlookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); + if (size != 1) + { + host_x86_TEST32_REG_IMM(block, REG_ECX, size-1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 2) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_RET(block); + + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); +#if WIN64 + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); + //host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); +#else + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); +#endif + if (size == 1) + { + host_x86_CALL(block, (void *)readmemb386l); + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + } + else if (size == 2) + { + host_x86_CALL(block, (void *)readmemwl); + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + } + else if (size == 4) + { + host_x86_CALL(block, (void *)readmemll); + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + } +#if WIN64 + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); +#endif + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; +} + +static void build_store_routine(codeblock_t *block, int size) +{ + uint8_t *branch_offset; + uint8_t *misaligned_offset; + + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [RSI+RDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writememb386l + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t)(uintptr_t)writelookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); + if (size != 1) + { + host_x86_TEST32_REG_IMM(block, REG_EDI, size-1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1) + host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 2) + host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4) + host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else + fatal("build_store_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_RET(block); + + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); +#if WIN64 + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); + host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address +#else + //host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address + host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data +#endif + if (size == 1) + host_x86_CALL(block, (void *)writememb386l); + else if (size == 2) + host_x86_CALL(block, (void *)writememwl); + else if (size == 4) + host_x86_CALL(block, (void *)writememll); +#if WIN64 + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); +#endif + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; +} + +static void build_loadstore_routines(codeblock_t *block) +{ + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4); + + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4); +} + void codegen_backend_init() { int c; @@ -55,6 +242,11 @@ void codegen_backend_init() } #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + + block_current = BLOCK_SIZE; + block_pos = 0; + build_loadstore_routines(&codeblock[block_current]); +// fatal("Here\n"); } static inline void call(codeblock_t *block, uintptr_t func) diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index dcb9a58..706c70d 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -6,3 +6,20 @@ #define REG_EBP 5 #define REG_ESI 6 #define REG_EDI 7 + +#define REG_RAX 0 +#define REG_RCX 1 +#define REG_RDX 2 +#define REG_RBX 3 +#define REG_RSP 4 +#define REG_RBP 5 +#define REG_RSI 6 +#define REG_RDI 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_R13 13 +#define REG_R14 14 +#define REG_R15 15 diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c new file mode 100644 index 0000000..f508e8a --- /dev/null +++ b/src/codegen_backend_x86-64_ops.c @@ -0,0 +1,888 @@ +#ifdef __amd64__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_x86-64_defs.h" +#include "codegen_backend_x86-64_ops.h" + +#define RM_OP_ADD 0x00 +#define RM_OP_OR 0x08 +#define RM_OP_AND 0x20 +#define RM_OP_SUB 0x28 +#define RM_OP_XOR 0x30 +#define RM_OP_CMP 0x38 + +#define RM_OP_SHR 0x28 + +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +{ + block->data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte over! %i\n", block_pos); +// CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + block->data[block_pos++] = vald; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addword(codeblock_t *block, uint16_t val) +{ + *(uint16_t *)&block->data[block_pos] = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addquad(codeblock_t *block, uint64_t val) +{ + *(uint64_t *)&block->data[block_pos] = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static int is_imm8(uint32_t imm_data) +{ + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; +} + +static inline void call(codeblock_t *block, uintptr_t func) +{ + uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; + + if (diff >= -0x80000000 && diff < 0x7fffffff) + { + codegen_addbyte(block, 0xE8); /*CALL*/ + codegen_addlong(block, (uint32_t)diff); + } + else + { + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ + } +} + +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ +} +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else + fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); +} +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} + +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ +} +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ +} +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ +} +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ +} + +void host_x86_CALL(codeblock_t *block, void *p) +{ + call(block, (uintptr_t)p); +} + +void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + else + fatal("CMP64_REG_IMM not 8-bit imm\n"); +} + +void host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} +void host_x86_JZ(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + +uint8_t *host_x86_JNZ_short(codeblock_t *block) +{ + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block->data[block_pos-1]; +} +uint8_t *host_x86_JZ_short(codeblock_t *block) +{ + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block->data[block_pos-1]; +} + +void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) +{ + if (offset) + { + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } + else + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ +} +void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG - bad reg\n"); + + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ + ((src_reg_b & 7) << 3) | (src_reg_a & 7)); +} +void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); + + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ + (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); +} + +void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ + codegen_addbyte(block, imm_data); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); + codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addbyte(block, imm_data); + } +} +void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addlong(block, imm_data); + } +} + +void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOV8_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOV32_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOV64_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); + codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} + +void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ +} +void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ +} +void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ +} + +void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOV32_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } + else + { + fatal("host_x86_MOV32_REG_ABS - out of range\n"); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} + +void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ +} + +void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) +{ + if ((dst_reg & 8) || (index_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + if (base_reg & 8) + codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ + else + codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ +} + +void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg >= 8) + fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); + codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ +} +void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV16_REG_IMM reg & 8\n"); + codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); +} +void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); +} + +void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) +{ + if (reg & 8) + { + codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } +} + +void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV8_REG_REG - bad reg\n"); + + codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV16_REG_REG - bad reg\n"); + + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV32_REG_REG - bad reg\n"); + + codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} + +void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +{ + if (!offset) + { + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else if (offset >= -80 || offset < 0x80) + { + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } +} + +void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); +} +void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); +} + +void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + +// if (dst_reg & 8) +// fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + if (dst_reg & 8) + codegen_addbyte(block, 0x44); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + else + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); +} + +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ +} +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} + +void host_x86_POP(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("POP reg & 8\n"); + codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ +} + +void host_x86_PUSH(codeblock_t *block, int src_reg) +{ + if (src_reg & 8) + fatal("PUSH reg & 8\n"); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ +} + +void host_x86_RET(codeblock_t *block) +{ + codegen_addbyte(block, 0xc3); /*RET*/ +} + +void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR32_IMM reg & 8\n"); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ +} +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else + fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); +} +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} + +#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) + +void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_TEST32_REG - bad reg\n"); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("TEST32_REG_IMM reg & 8\n"); + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ +} +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} + +#endif diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h new file mode 100644 index 0000000..6070054 --- /dev/null +++ b/src/codegen_backend_x86-64_ops.h @@ -0,0 +1,104 @@ +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data); + +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_CALL(codeblock_t *block, void *p); + +void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); +void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data); + +void host_x86_JNZ(codeblock_t *block, void *p); +void host_x86_JZ(codeblock_t *block, void *p); + +uint8_t *host_x86_JNZ_short(codeblock_t *block); +uint8_t *host_x86_JZ_short(codeblock_t *block); + +void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset); +void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); + +void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); +void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); + +void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg); + +void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); + +void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); + +void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg); + +void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale); + +void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data); +void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data); +void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data); + +void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data); + +void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); + +void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg); + +void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); + +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_POP(codeblock_t *block, int src_reg); + +void host_x86_PUSH(codeblock_t *block, int src_reg); + +void host_x86_RET(codeblock_t *block); + +void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data); + +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg); +void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); + +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index ff1f31f..3e56105 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -4,6 +4,7 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" +#include "codegen_backend_x86-64_ops.h" #include "codegen_ir_defs.h" #define STACK_ARG0 (0) @@ -11,682 +12,6 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) -#define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 -#define RM_OP_AND 0x20 -#define RM_OP_SUB 0x28 -#define RM_OP_XOR 0x30 - -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) -{ - block->data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); - } -} -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) -{ - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte2 over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) -{ - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte3 over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) -{ - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - block->data[block_pos++] = vald; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte4 over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static inline void codegen_addword(codeblock_t *block, uint16_t val) -{ - *(uint16_t *)&block->data[block_pos] = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addword over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static inline void codegen_addquad(codeblock_t *block, uint64_t val) -{ - *(uint64_t *)&block->data[block_pos] = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addquad over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static int is_imm8(uint32_t imm_data) -{ - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; -} - -static inline void call(codeblock_t *block, uintptr_t func) -{ - uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; - - if (diff >= -0x80000000 && diff < 0x7fffffff) - { - codegen_addbyte(block, 0xE8); /*CALL*/ - codegen_addlong(block, (uint32_t)diff); - } - else - { - codegen_addbyte2(block, 0x48, 0xb8); /*MOV RAX, func*/ - codegen_addquad(block, func); - codegen_addbyte2(block, 0xff, 0xd0); /*CALL RAX*/ - } -} - -static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ -} -static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -static void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ -} -static void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ -} -static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ -} - -static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ -} -static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -static void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ -} -static void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ -} -static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ -} - -static void host_x86_CALL(codeblock_t *block, void *p) -{ - call(block, (uintptr_t)p); -} - -static void host_x86_JNZ(codeblock_t *block, void *p) -{ - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); -} - -static void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); - - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ - (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); -} - -static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ - codegen_addbyte(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); - codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addbyte(block, imm_data); - } -} -static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addlong(block, imm_data); - } -} - -static void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV8_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -static void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV32_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -static void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV64_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); - codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} - -static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (dst_reg & 8) - fatal("host_x86_MOV32_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else - { - fatal("host_x86_MOV32_REG_ABS - out of range\n"); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} - -static void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) -{ - if (reg >= 8) - fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); - codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ -} -static void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV16_REG_IMM reg & 8\n"); - codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ - codegen_addword(block, imm_data); -} -static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV32_REG_IMM reg & 8\n"); - codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ - codegen_addlong(block, imm_data); -} - -static void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV64_REG_IMM reg & 8\n"); - codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); -} - -static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV8_REG_REG - bad reg\n"); - - codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); -} -static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV16_REG_REG - bad reg\n"); - - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); -} -static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV32_REG_REG - bad reg\n"); - - codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); -} - -static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) -{ - if (!offset) - { - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else if (offset >= -80 || offset < 0x80) - { - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } -} - -static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} - -static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ -} -static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -static void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ -} -static void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ -} -static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ -} - -static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ -} -static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -static void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ -} -static void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ -} -static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ -} - -#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) - -static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_TEST32_REG - bad reg\n"); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ -} - -static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ -} -static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -static void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ -} -static void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ -} -static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ -} - #define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) #define REG_IS_L(size) (size == IREG_SIZE_L) @@ -807,6 +132,22 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_x86_JZ(block, uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { #if WIN64 @@ -836,6 +177,177 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} +static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (REG_IS_B(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); +// fatal("Here\n"); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} + +static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) + { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (REG_IS_B(src_size)) + { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1077,6 +589,15 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, @@ -1092,7 +613,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SUB & UOP_MASK] = codegen_SUB, [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 55430e0..b81bfce 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -3,6 +3,8 @@ #include "ibm.h" #include "codegen.h" #include "codegen_backend.h" +#include "codegen_backend_x86_defs.h" +#include "codegen_backend_x86_ops.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -13,6 +15,14 @@ #include #endif +void *codegen_mem_load_byte; +void *codegen_mem_load_word; +void *codegen_mem_load_long; + +void *codegen_mem_store_byte; +void *codegen_mem_store_word; +void *codegen_mem_store_long; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_EAX, @@ -22,6 +32,164 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = static void *mem_abrt_rout; +static void build_load_routine(codeblock_t *block, int size) +{ + uint8_t *branch_offset; + uint8_t *misaligned_offset; + + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV ESI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[ESI+ECX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmemb386l + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); + if (size != 1) + { + host_x86_TEST32_REG_IMM(block, REG_ECX, size-1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 2) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_RET(block); + + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 1) + host_x86_CALL(block, (void *)readmemb386l); + else if (size == 2) + host_x86_CALL(block, (void *)readmemwl); + else if (size == 4) + host_x86_CALL(block, (void *)readmemll); + host_x86_POP(block, REG_ECX); + if (size == 1) + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + else if (size == 2) + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + else if (size == 4) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; +} + +static void build_store_routine(codeblock_t *block, int size) +{ + uint8_t *branch_offset; + uint8_t *misaligned_offset; + + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [ESI+EDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writememb386l + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); + if (size != 1) + { + host_x86_TEST32_REG_IMM(block, REG_EDI, size-1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1) + host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 2) + host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4) + host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else + fatal("build_store_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_RET(block); + + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + host_x86_PUSH(block, REG_EDI); + if (size == 1) + host_x86_CALL(block, (void *)writememb386l); + else if (size == 2) + host_x86_CALL(block, (void *)writememwl); + else if (size == 4) + host_x86_CALL(block, (void *)writememll); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ECX); + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; +} + +static void build_loadstore_routines(codeblock_t *block) +{ + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4); + + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4); +} + void codegen_backend_init() { int c; @@ -67,6 +235,10 @@ void codegen_backend_init() addbyte(0x5d); /*POP EBP*/ addbyte(0x5b); /*POP EDX*/ addbyte(0xC3); /*RET*/ + + block_pos = 64; + build_loadstore_routines(&codeblock[block_current]); + //fatal("Here\n"); asm( "fstcw %0\n" diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index f28915e..37e4160 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -12,4 +12,12 @@ #define CODEGEN_HOST_REGS 3 +extern void *codegen_mem_load_byte; +extern void *codegen_mem_load_word; +extern void *codegen_mem_load_long; + +extern void *codegen_mem_store_byte; +extern void *codegen_mem_store_word; +extern void *codegen_mem_store_long; + #endif diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c new file mode 100644 index 0000000..1447338 --- /dev/null +++ b/src/codegen_backend_x86_ops.c @@ -0,0 +1,779 @@ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + +#include "ibm.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_backend_x86_defs.h" +#include "codegen_backend_x86_ops.h" + +#define RM_OP_ADD 0x00 +#define RM_OP_OR 0x08 +#define RM_OP_AND 0x20 +#define RM_OP_SUB 0x28 +#define RM_OP_XOR 0x30 +#define RM_OP_CMP 0x38 + +#define RM_OP_SHR 0x28 + +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +{ + block->data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte over! %i\n", block_pos); +// CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +{ + block->data[block_pos++] = vala; + block->data[block_pos++] = valb; + block->data[block_pos++] = valc; + block->data[block_pos++] = vald; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addword(codeblock_t *block, uint16_t val) +{ + *(uint16_t *)&block->data[block_pos] = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + *(uint32_t *)&block->data[block_pos] = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static inline void codegen_addquad(codeblock_t *block, uint64_t val) +{ + *(uint64_t *)&block->data[block_pos] = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } +} + +static int is_imm8(uint32_t imm_data) +{ + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; +} + +void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, int src_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} + +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ +} +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} + +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ +} +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ +} +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ +} +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ +} + +void host_x86_CALL(codeblock_t *block, void *p) +{ + codegen_addbyte(block, 0xe8); /*CALL*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + +void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} +void host_x86_JZ(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + +uint8_t *host_x86_JNZ_short(codeblock_t *block) +{ + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block->data[block_pos-1]; +} +uint8_t *host_x86_JZ_short(codeblock_t *block) +{ + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block->data[block_pos-1]; +} + +void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) +{ + if (offset) + { + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } + else + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ +} + +void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ +} +void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ +} + +void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte(block, imm_data); + } + else + { + codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addbyte(block, imm_data); + } +} +void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addlong(block, imm_data); + } +} + +void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} +void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} + +void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ +} +void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ +} +void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ +} + +void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} + +void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) +{ + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ + codegen_addlong(block, (uint32_t)p); +} + +void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ +} + +void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ +} +void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (!imm_data) + { + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } + else + { + codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (!imm_data) + { + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } + else + { + codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); +} + +void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +{ + if (!offset) + { + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else if (offset >= -80 || offset < 0x80) + { + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } +} + +void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } + else + { + codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } + else + { + codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} + +void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ +} +void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ +} + +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} + +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ +} +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_POP(codeblock_t *block, int src_reg) +{ + codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ +} + +void host_x86_PUSH(codeblock_t *block, int src_reg) +{ + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ +} + +void host_x86_RET(codeblock_t *block) +{ + codegen_addbyte(block, 0xc3); /*RET*/ +} + +#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) + +void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ +} +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} + +void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR8_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR16_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} + +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); + + if (dst_reg == REG_EAX) + codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ + else + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ +} +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +#endif diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h new file mode 100644 index 0000000..cf4a793 --- /dev/null +++ b/src/codegen_backend_x86_ops.h @@ -0,0 +1,100 @@ +void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, int src_reg, void *p); + +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_CALL(codeblock_t *block, void *p); + +void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); + +void host_x86_JNZ(codeblock_t *block, void *p); +void host_x86_JZ(codeblock_t *block, void *p); + +uint8_t *host_x86_JNZ_short(codeblock_t *block); +uint8_t *host_x86_JZ_short(codeblock_t *block); + +void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32_t offset); +void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); + +void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); +void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); + +void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg); + +void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); + +void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); + +void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift); + +void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + +void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); + +void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); + +void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); + +void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_POP(codeblock_t *block, int src_reg); + +void host_x86_PUSH(codeblock_t *block, int src_reg); + +void host_x86_RET(codeblock_t *block); + +void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); +void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_data); + +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); + +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 0f68a25..e043cc9 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -4,6 +4,7 @@ #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" +#include "codegen_backend_x86_ops.h" #include "codegen_ir_defs.h" #define STACK_ARG0 (0) @@ -11,616 +12,6 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) -#define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 -#define RM_OP_AND 0x20 -#define RM_OP_SUB 0x28 -#define RM_OP_XOR 0x30 - -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) -{ - block->data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); - } -} -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) -{ - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte2 over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) -{ - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte3 over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) -{ - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - block->data[block_pos++] = vald; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte4 over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static inline void codegen_addword(codeblock_t *block, uint16_t val) -{ - *(uint16_t *)&block->data[block_pos] = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addword over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static inline void codegen_addquad(codeblock_t *block, uint64_t val) -{ - *(uint64_t *)&block->data[block_pos] = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addquad over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - -static int is_imm8(uint32_t imm_data) -{ - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; -} - -static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ -} -static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -static void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ -} -static void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ -} -static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ -} - -static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ -} -static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -static void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ -} -static void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ -} -static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ -} - -static void host_x86_CALL(codeblock_t *block, void *p) -{ - codegen_addbyte(block, 0xe8); /*CALL*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); -} - -static void host_x86_JNZ(codeblock_t *block, void *p) -{ - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); -} - -static void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) -{ - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ -} - -static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ - codegen_addbyte(block, imm_data); - } - else - { - codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addbyte(block, imm_data); - } -} -static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addlong(block, imm_data); - } -} - -static void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ - } - else - { - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} -static void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} - -static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} - -static void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ -} -static void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (!imm_data) - { - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } - else - { - codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (!imm_data) - { - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } - else - { - codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); -} -static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); -} -static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); -} - -static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) -{ - if (!offset) - { - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else if (offset >= -80 || offset < 0x80) - { - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } -} - -static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} - -static void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_OR8_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ -} -static void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_OR16_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ -} -static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ -} - -static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ -} -static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) - -static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ -} -static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -static void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ -} -static void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ -} -static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ -} - -static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} - -static void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_XOR8_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ -} -static void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_XOR16_REG_REG - dst_reg != src_reg_a\n"); - - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ -} -static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if (dst_reg != src_reg_a) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); - - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ -} - -static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); - - if (dst_reg == REG_EAX) - codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ - else - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ -} -static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - else if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - - /*void codegen_debug() { pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); @@ -752,6 +143,22 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_x86_JZ(block, uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); @@ -773,6 +180,176 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} +static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (REG_IS_B(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_byte); + } + else if (REG_IS_W(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_word); + } + else if (REG_IS_L(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_long); + } + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } + else if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} + +static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) + { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (REG_IS_B(src_size)) + { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } + else if (REG_IS_W(src_size)) + { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } + else if (REG_IS_L(src_size)) + { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + +static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1010,6 +587,15 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, @@ -1025,7 +611,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SUB & UOP_MASK] = codegen_SUB, [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 1d89807..8d81db8 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -27,9 +27,14 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) // pclog("uOP %i : %08x\n", c, uop->type); + if (uop->type & UOP_TYPE_BARRIER) + codegen_reg_flush_invalidate(ir, block); + else if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); + if (uop->type & UOP_TYPE_PARAMS_REGS) { - codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b); + codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); if (uop->src_reg_a.reg != IREG_INVALID) { uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); @@ -38,19 +43,22 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) { uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); } + if (uop->src_reg_c.reg != IREG_INVALID) + { + uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); + } if (uop->dest_reg_a.reg != IREG_INVALID) { uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); } } - if (uop->type & UOP_TYPE_BARRIER) - codegen_reg_flush(ir, block); - + if (!uop_handlers[uop->type & UOP_MASK]) + fatal("!uop_handlers[uop->type & UOP_MASK]\n"); uop_handlers[uop->type & UOP_MASK](block, uop); } - codegen_reg_flush(ir, block); + codegen_reg_flush_invalidate(ir, block); codegen_backend_epilogue(block); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 04ee628..7a1d947 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -6,9 +6,17 @@ #define UOP_REG(reg, size, version) ((reg) | (size) | (version << 8)) /*uOP is a barrier. All previous uOPs must have completed before this one executes. - All registers must have been written back or discarded*/ + All registers must have been written back or discarded. + This should be used when calling external functions that may change any emulated + registers.*/ #define UOP_TYPE_BARRIER (1 << 31) +/*uOP is a barrier. All previous uOPs must have completed before this one executes. + All registers must have been written back, but do not have to be discarded. + This should be used when calling functions that preserve registers, but can cause + the code block to exit (eg memory load/store functions).*/ +#define UOP_TYPE_ORDER_BARRIER (1 << 27) + /*uOP uses source and dest registers*/ #define UOP_TYPE_PARAMS_REGS (1 << 28) /*uOP uses pointer*/ @@ -62,8 +70,24 @@ #define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) /*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ #define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) +/*UOP_MEM_LOAD_ABS - dest_reg = src_reg_a:[immediate]*/ +#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_LOAD_REG - dest_reg = src_reg_a:[src_reg_b]*/ +#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_ABS - src_reg_a:[immediate] = src_reg_b*/ +#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_REG - src_reg_a:[src_reg_b] = src_reg_c*/ +#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_IMM_8 - byte src_reg_a:[src_reg_b] = imm_data*/ +#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_IMM_16 - word src_reg_a:[src_reg_b] = imm_data*/ +#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/ +#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) +/*UOP_CMP_JZ - if (src_reg_a == imm_data) then jump to ptr*/ +#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) -#define UOP_MAX 0x3b +#define UOP_MAX 0x49 #define UOP_MASK 0xffff @@ -73,10 +97,11 @@ typedef struct uop_t ir_reg_t dest_reg_a; ir_reg_t src_reg_a; ir_reg_t src_reg_b; + ir_reg_t src_reg_c; uint32_t imm_data; void *p; ir_host_reg_t dest_reg_a_real; - ir_host_reg_t src_reg_a_real, src_reg_b_real; + ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; } uop_t; #define UOP_NR_MAX 4096 @@ -99,7 +124,8 @@ static inline uop_t *uop_alloc(ir_data_t *ir) uop->dest_reg_a = invalid_ir_reg; uop->src_reg_a = invalid_ir_reg; uop->src_reg_b = invalid_ir_reg; - + uop->src_reg_c = invalid_ir_reg; + return uop; } @@ -179,6 +205,26 @@ static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int uop->imm_data = imm; } +static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->imm_data = imm; +} + +static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); +} + static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { uop_t *uop = uop_alloc(ir); @@ -204,6 +250,16 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p uop->imm_data = imm; } +static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->p = p; + uop->imm_data = imm; +} + #define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) @@ -223,6 +279,16 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) + +#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) +#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg) +#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) +#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg) +#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) + #define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) #define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) #define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index caaf3ff..6fc74b4 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -22,10 +22,10 @@ RecompOpFn recomp_opcodes[512] = /*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -44,10 +44,10 @@ RecompOpFn recomp_opcodes[512] = /*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index b8bb8aa..c7d906d 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -36,43 +36,64 @@ uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = fetchdat & 7; uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); } else - return 0; + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); + } return op_pc + 1; } uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = fetchdat & 7; uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); } else - return 0; + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); + } return op_pc + 1; } uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = fetchdat & 7; uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); } else - return 0; + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); + } return op_pc + 1; } @@ -86,7 +107,15 @@ uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); } else - return 0; + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + CPU_BLOCK_END(); + } return op_pc + 1; } @@ -100,7 +129,14 @@ uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); } else - return 0; + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } return op_pc + 1; } @@ -114,7 +150,176 @@ uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); } else - return 0; + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } return op_pc + 1; } + +uint32_t ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +uint32_t ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} + +uint32_t ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} + +uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint8_t imm; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + imm = fastreadb(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_8(dest_reg), imm); + } + else + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + return op_pc + 2; +} +uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint16_t imm; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + imm = fastreadw(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_16(dest_reg), imm); + } + else + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + return op_pc + 3; +} +uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint32_t imm; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + imm = fastreadl(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_32(dest_reg), imm); + } + else + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + return op_pc + 5; +} diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h index cf8b31f..78442b4 100644 --- a/src/codegen_ops_mov.h +++ b/src/codegen_ops_mov.h @@ -1,9 +1,22 @@ uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 43027f3..28a08be 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -56,6 +56,13 @@ struct [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins}, [IREG_cycles] = {REG_DWORD, &cpu_state._cycles}, + + [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base}, + [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base}, + [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base}, + [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base}, + [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base}, + [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base}, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will @@ -63,7 +70,7 @@ struct [IREG_temp0] = {REG_DWORD, NULL}, [IREG_temp1] = {REG_DWORD, NULL}, [IREG_temp2] = {REG_DWORD, NULL}, - [IREG_temp3] = {REG_DWORD, NULL} + [IREG_temp3] = {REG_DWORD, NULL}, }; void codegen_reg_reset() @@ -103,7 +110,7 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) //pclog(" codegen_reg_load: c=%i reg=%02x.%i\n", c, host_regs[c].reg,host_regs[c].version); } -static void codegen_reg_writeback(codeblock_t *block, int c) +static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate) { int ir_reg = IREG_GET_REG(host_regs[c].reg); @@ -125,11 +132,12 @@ static void codegen_reg_writeback(codeblock_t *block, int c) fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); } - host_regs[c] = invalid_ir_reg; + if (invalidate) + host_regs[c] = invalid_ir_reg; host_reg_dirty[c] = 0; } -void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b) +void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) { int c; int dest_reference = 0; @@ -146,6 +154,8 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ dest_reference++; if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version-1) dest_reference++; + if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version-1) + dest_reference++; } for (c = 0; c < CODEGEN_HOST_REGS; c++) { @@ -161,6 +171,12 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_b.version\n"); host_regs_locked |= (1 << c); } + if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_c.reg)) + { + if (host_regs[c].version != src_reg_c.version) + fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_c.version\n"); + host_regs_locked |= (1 << c); + } if (!ir_reg_is_invalid(dest_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(dest_reg_a.reg)) { if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] == dest_reference)) @@ -196,7 +212,7 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in if (c == CODEGEN_HOST_REGS) fatal("codegen_reg_alloc_read_reg - out of registers\n"); if (host_reg_dirty[c]) - codegen_reg_writeback(block, c); + codegen_reg_writeback(block, c, 1); // pclog(" load %i\n", c); codegen_reg_load(block, c, ir_reg); host_regs_locked |= (1 << c); @@ -277,7 +293,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) if (c == CODEGEN_HOST_REGS) fatal("codegen_reg_alloc_write_reg - out of registers\n"); if (host_reg_dirty[c]) - codegen_reg_writeback(block, c); + codegen_reg_writeback(block, c, 1); } } @@ -289,6 +305,19 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) } void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) +{ + int c; + + for (c = 0; c < CODEGEN_HOST_REGS; c++) + { + if (!ir_reg_is_invalid(host_regs[c]) && host_reg_dirty[c]) + { + codegen_reg_writeback(block, c, 0); + } + } +} + +void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) { int c; @@ -296,7 +325,7 @@ void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { if (!ir_reg_is_invalid(host_regs[c])) { - codegen_reg_writeback(block, c); + codegen_reg_writeback(block, c, 1); } } } diff --git a/src/codegen_reg.h b/src/codegen_reg.h index b8f4de5..1e3d339 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -42,13 +42,20 @@ enum IREG_ins = 19, IREG_cycles = 20, + IREG_CS_base = 21, + IREG_DS_base = 22, + IREG_ES_base = 23, + IREG_FS_base = 24, + IREG_GS_base = 25, + IREG_SS_base = 26, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - IREG_temp0 = 21, - IREG_temp1 = 22, - IREG_temp2 = 23, - IREG_temp3 = 24, + IREG_temp0 = 27, + IREG_temp1 = 28, + IREG_temp2 = 29, + IREG_temp3 = 30, IREG_COUNT, @@ -82,6 +89,24 @@ enum #define IREG_16(reg) ((reg) + IREG_AX) #define IREG_32(reg) ((reg) + IREG_EAX) +static inline int ireg_seg_base(x86seg *seg) +{ + if (seg == &cpu_state.seg_cs) + return IREG_CS_base; + if (seg == &cpu_state.seg_ds) + return IREG_DS_base; + if (seg == &cpu_state.seg_es) + return IREG_ES_base; + if (seg == &cpu_state.seg_fs) + return IREG_FS_base; + if (seg == &cpu_state.seg_gs) + return IREG_GS_base; + if (seg == &cpu_state.seg_ss) + return IREG_SS_base; + fatal("ireg_seg_base : unknown segment\n"); + return 0; +} + extern uint8_t reg_last_version[IREG_COUNT]; extern uint8_t reg_version_refcount[IREG_COUNT][256]; @@ -131,10 +156,13 @@ static inline ir_reg_t codegen_reg_write(int reg) struct ir_data_t; void codegen_reg_reset(); +/*Write back all dirty registers*/ void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block); +/*Write back and evict all registers*/ +void codegen_reg_flush_invalidate(struct ir_data_t *ir, codeblock_t *block); /*Register ir_reg usage for this uOP. This ensures that required registers aren't evicted*/ -void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b); +void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c); ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); From 5ca2533f3cf83c456f736bb5064381c9e8696bd4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 25 Jul 2018 20:17:42 +0100 Subject: [PATCH 0487/1050] Increase ARM64 work registers from 5 to 10. --- src/codegen_backend_arm64.c | 7 ++++++- src/codegen_backend_arm64_defs.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 9df86f9..99e1c23 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -30,7 +30,12 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_X20, REG_X21, REG_X22, - REG_X23 + REG_X23, + REG_X24, + REG_X25, + REG_X26, + REG_X27, + REG_X28 }; static void build_load_routine(codeblock_t *block, int size) diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index 48e58ec..c818d89 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -75,7 +75,7 @@ #define REG_TEMP REG_X7 -#define CODEGEN_HOST_REGS 5 +#define CODEGEN_HOST_REGS 10 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; From cf508b050f6b2f7c85281e7473a43cc57aa15a4c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 25 Jul 2018 20:18:03 +0100 Subject: [PATCH 0488/1050] End block when register version hits a maximum count. --- src/codegen_reg.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 1e3d339..4fd0dd8 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -120,6 +120,8 @@ extern ir_reg_t invalid_ir_reg; typedef uint8_t ir_host_reg_t; +#define REG_VERSION_MAX 250 + static inline ir_reg_t codegen_reg_read(int reg) { ir_reg_t ireg; @@ -132,6 +134,8 @@ static inline ir_reg_t codegen_reg_read(int reg) reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]++; if (!reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]) fatal("codegen_reg_read - refcount overflow\n"); + else if (reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version] > REG_VERSION_MAX) + CPU_BLOCK_END(); return ireg; } @@ -148,6 +152,8 @@ static inline ir_reg_t codegen_reg_write(int reg) reg_last_version[IREG_GET_REG(reg)]++; if (!reg_last_version[IREG_GET_REG(reg)]) fatal("codegen_reg_write - version overflow\n"); + else if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) + CPU_BLOCK_END(); reg_version_refcount[IREG_GET_REG(reg)][ireg.version] = 0; return ireg; From e64271f5bb5ed718d7f763838b9ba3a66b0283fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 27 Jul 2018 22:24:34 +0100 Subject: [PATCH 0489/1050] Added recompiled versions of mem->reg, reg->mem and imm->mem versions of ADD, AND, CMP, OR, SUB and XOR. --- src/codegen_backend_arm.c | 6 +- src/codegen_backend_arm64.c | 6 +- src/codegen_backend_arm64_ops.c | 11 + src/codegen_backend_arm64_ops.h | 2 + src/codegen_backend_arm64_uops.c | 22 +- src/codegen_backend_arm_uops.c | 40 +- src/codegen_backend_x86-64_ops.c | 42 +- src/codegen_backend_x86-64_ops.h | 4 + src/codegen_backend_x86-64_uops.c | 36 +- src/codegen_backend_x86.c | 12 +- src/codegen_backend_x86_ops.c | 36 +- src/codegen_backend_x86_ops.h | 4 + src/codegen_backend_x86_uops.c | 36 +- src/codegen_ir_defs.h | 4 + src/codegen_ops_arith.c | 1313 +++++++++++++++++++++-------- src/codegen_ops_logic.c | 427 ++++++++-- src/codegen_reg.c | 27 +- src/codegen_reg.h | 8 +- 18 files changed, 1524 insertions(+), 512 deletions(-) diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 09630ed..908c5e1 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -221,7 +221,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm_nop(block); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10); + host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x20); host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC); while (block_pos != BLOCK_START) host_arm_nop(block); @@ -229,7 +229,7 @@ void codegen_backend_prologue(codeblock_t *block) /*Entry code*/ host_arm_STMDB_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_LR); - host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x10); + host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x20); host_arm_ADD_IMM(block, REG_LITERAL, REG_PC, ARM_LITERAL_POOL_OFFSET); host_arm_SUB_IMM(block, REG_LITERAL, REG_LITERAL, 16 + BLOCK_START); offset = add_literal(block, (uintptr_t)&cpu_state); @@ -238,7 +238,7 @@ void codegen_backend_prologue(codeblock_t *block) void codegen_backend_epilogue(codeblock_t *block) { - host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10); + host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x20); host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC); if (block_pos > ARM_LITERAL_POOL_OFFSET) diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 99e1c23..4ae98f0 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -237,7 +237,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm64_NOP(block); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 48); host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); @@ -255,7 +255,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_SP, -16); host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_SP, -16); host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -48); offset = add_literal_q(block, (uintptr_t)&cpu_state); host_arm64_LDR_LITERAL_X(block, REG_CPUSTATE, offset); @@ -263,7 +263,7 @@ void codegen_backend_prologue(codeblock_t *block) void codegen_backend_epilogue(codeblock_t *block) { - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 48); host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 4effa1a..0a6b8f8 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -34,6 +34,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SHIFT 24 #define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) +#define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) #define OPCODE_BCOND (0x54 << OPCODE_SHIFT) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) #define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) @@ -43,6 +44,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) #define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) #define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) +#define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) #define OPCODE_AND_IMM (0x024 << 23) #define OPCODE_ANDS_IMM (0x0e4 << 23) @@ -63,6 +65,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ADD_LSL (0x058 << 21) #define OPCODE_ADD_LSR (0x05a << 21) +#define OPCODE_ADDX_LSL (0x458 << 21) #define OPCODE_AND_ASR (0x054 << 21) #define OPCODE_AND_LSL (0x050 << 21) #define OPCODE_AND_ROR (0x056 << 21) @@ -70,8 +73,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_EOR_LSL (0x250 << 21) #define OPCODE_ORR_LSL (0x150 << 21) #define OPCODE_ORR_LSR (0x152 << 21) +#define OPCODE_ORRX_LSL (0x550 << 21) #define OPCODE_SUB_LSL (0x258 << 21) #define OPCODE_SUB_LSR (0x25a << 21) +#define OPCODE_SUBX_LSL (0x658 << 21) #define OPCODE_BLR (0xd63f0000) #define OPCODE_LDR_REG (0xb8606800) @@ -444,6 +449,12 @@ void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) { int hw; diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 6178c6b..9fc993d 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -48,6 +48,8 @@ void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, in void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); +void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); + void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data); void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 8b5aad0..cd9f180 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -65,17 +65,17 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); @@ -809,4 +809,20 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) fatal("codegen_direct_write_ptr - not in range\n"); } +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + if (in_range12_w(stack_offset)) + host_arm64_LDR_IMM_W(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); +} + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + if (in_range12_w(stack_offset)) + host_arm64_STR_IMM_W(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_write_32_stack - not in range\n"); +} + #endif diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index b6f5f41..0ec4c75 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -75,15 +75,15 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) { host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); - host_arm_UADD16(block, dest_reg, src_reg_a, REG_TEMP); + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { @@ -118,15 +118,15 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && src_reg == dest_reg) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_UADD16(block, dest_reg, src_reg, REG_TEMP); + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && src_reg == dest_reg) + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) { @@ -905,4 +905,20 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) fatal("codegen_direct_write_ptr - not in range\n"); } +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_LDR_IMM(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); +} + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_STR_IMM(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_write_32 - not in range\n"); +} + #endif diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index f508e8a..9262541 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -174,21 +174,21 @@ void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } @@ -501,6 +501,42 @@ void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int ba codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ } +void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } + else + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} + +void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } + else + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); +} + void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { if (reg >= 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 6070054..4b67841 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -62,11 +62,15 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); + void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); + void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 3e56105..d0efa31 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -26,15 +26,22 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + else + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -49,15 +56,22 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (dest_reg != src_reg) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + else + host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -638,4 +652,14 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) host_x86_MOV64_ABS_REG(block, p, host_reg); } +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); +} + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); +} + #endif diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index b81bfce..17f588f 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -253,18 +253,18 @@ void codegen_backend_prologue(codeblock_t *block) addbyte(0x55); /*PUSH EBP*/ addbyte(0x56); /*PUSH ESI*/ addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $16,%esp*/ + addbyte(0x83); /*SUBL $32,%esp*/ addbyte(0xEC); - addbyte(0x10); + addbyte(0x20); addbyte(0xBD); /*MOVL EBP, &cpu_state*/ addlong(((uintptr_t)&cpu_state) + 128); } void codegen_backend_epilogue(codeblock_t *block) { - addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0x83); /*ADDL $32,%esp*/ addbyte(0xC4); - addbyte(0x10); + addbyte(0x20); addbyte(0x5f); /*POP EDI*/ addbyte(0x5e); /*POP ESI*/ addbyte(0x5d); /*POP EBP*/ @@ -287,9 +287,9 @@ void codegen_backend_epilogue(codeblock_t *block) addbyte(0xe8); /*CALL x86gpf*/ addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0x83); /*ADDL $32,%esp*/ addbyte(0xC4); - addbyte(0x10); + addbyte(0x20); addbyte(0x5f); /*POP EDI*/ addbyte(0x5e); /*POP ESI*/ addbyte(0x5d); /*POP EBP*/ diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 1447338..bcc16ef 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -164,21 +164,21 @@ void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) - fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } @@ -420,6 +420,36 @@ void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ } +void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } + else + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} + +void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } + else + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); +} + void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index cf4a793..8d3df16 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -40,12 +40,16 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); + void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift); void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); + void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index e043cc9..c5f3f80 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -36,15 +36,22 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + else + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -59,15 +66,22 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + else + host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -636,4 +650,14 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); +} + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); +} + #endif diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 7a1d947..a864468 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -304,4 +304,8 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); + #endif diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 1e3f226..9e7fb43 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -49,14 +49,29 @@ uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 } uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); @@ -65,30 +80,61 @@ uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); @@ -97,30 +143,60 @@ uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); @@ -129,16 +205,32 @@ uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; @@ -184,14 +276,29 @@ uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 } uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); @@ -200,14 +307,29 @@ uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); @@ -216,14 +338,29 @@ uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ } uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); @@ -232,14 +369,29 @@ uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); @@ -248,14 +400,29 @@ uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ } uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); codegen_flags_changed = 1; @@ -263,14 +430,29 @@ uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); + } - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); codegen_flags_changed = 1; @@ -318,14 +500,29 @@ uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 } uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); @@ -334,30 +531,61 @@ uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); @@ -366,30 +594,60 @@ uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); @@ -398,16 +656,32 @@ uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; @@ -415,70 +689,128 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; - uint8_t imm; - - if ((fetchdat & 0xc0) != 0xc0) + if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ return 0; - switch (fetchdat & 0x38) + if ((fetchdat & 0xc0) == 0xc0) { - case 0x00: /*ADD*/ + int dest_reg = fetchdat & 7; + uint8_t imm = fastreadb(cs + op_pc + 1); + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + uint8_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); imm = fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x08: /*OR*/ - imm = fastreadb(cs + op_pc + 1); + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; - uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; - case 0x20: /*AND*/ - imm = fastreadb(cs + op_pc + 1); + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; - case 0x28: /*SUB*/ - imm = fastreadb(cs + op_pc + 1); + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x30: /*XOR*/ - imm = fastreadb(cs + op_pc + 1); - - uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x38: /*CMP*/ - imm = fastreadb(cs + op_pc + 1); - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; - - default: - return 0; + default: + return 0; + } } codegen_flags_changed = 1; @@ -486,70 +818,128 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; - uint16_t imm; - - if ((fetchdat & 0xc0) != 0xc0) + if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ return 0; - switch (fetchdat & 0x38) + if ((fetchdat & 0xc0) == 0xc0) { - case 0x00: /*ADD*/ + int dest_reg = fetchdat & 7; + uint16_t imm = fastreadw(cs + op_pc + 1); + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + uint16_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); imm = fastreadw(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x08: /*OR*/ - imm = fastreadw(cs + op_pc + 1); + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x20: /*AND*/ - imm = fastreadw(cs + op_pc + 1); + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x28: /*SUB*/ - imm = fastreadw(cs + op_pc + 1); + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x30: /*XOR*/ - imm = fastreadw(cs + op_pc + 1); - - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*CMP*/ - imm = fastreadw(cs + op_pc + 1); - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; + default: + return 0; + } } codegen_flags_changed = 1; @@ -557,69 +947,126 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; - uint32_t imm; - - if ((fetchdat & 0xc0) != 0xc0) + if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ return 0; - switch (fetchdat & 0x38) + if ((fetchdat & 0xc0) == 0xc0) { - case 0x00: /*ADD*/ + int dest_reg = fetchdat & 7; + uint32_t imm = fastreadl(cs + op_pc + 1); + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + uint32_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); imm = fastreadl(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x08: /*OR*/ - imm = fastreadl(cs + op_pc + 1); + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x20: /*AND*/ - imm = fastreadl(cs + op_pc + 1); + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x28: /*SUB*/ - imm = fastreadl(cs + op_pc + 1); + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x30: /*XOR*/ - imm = fastreadl(cs + op_pc + 1); - - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*CMP*/ - imm = fastreadl(cs + op_pc + 1); - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; + default: + return 0; + } } codegen_flags_changed = 1; @@ -628,70 +1075,128 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; - uint16_t imm; - - if ((fetchdat & 0xc0) != 0xc0) + if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ return 0; - switch (fetchdat & 0x38) + if ((fetchdat & 0xc0) == 0xc0) { - case 0x00: /*ADD*/ + int dest_reg = fetchdat & 7; + uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + uint16_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x08: /*OR*/ - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x20: /*AND*/ - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x28: /*SUB*/ - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x30: /*XOR*/ - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*CMP*/ - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; + default: + return 0; + } } codegen_flags_changed = 1; @@ -699,69 +1204,127 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; uint32_t imm; - if ((fetchdat & 0xc0) != 0xc0) + if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ return 0; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*OR*/ - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: /*AND*/ - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SUB*/ - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x30: /*XOR*/ - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - case 0x38: /*CMP*/ + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - default: - return 0; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } } codegen_flags_changed = 1; diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c index ad74d7e..df4a3de 100644 --- a/src/codegen_ops_logic.c +++ b/src/codegen_ops_logic.c @@ -43,12 +43,25 @@ uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 } uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); @@ -57,26 +70,55 @@ uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); @@ -85,26 +127,55 @@ uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); @@ -113,14 +184,30 @@ uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; @@ -161,12 +248,25 @@ uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 } uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); @@ -175,26 +275,55 @@ uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); @@ -203,42 +332,87 @@ uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_res, dest_reg); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; @@ -279,12 +453,25 @@ uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 } uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); @@ -293,26 +480,55 @@ uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); @@ -321,42 +537,87 @@ uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_res, dest_reg); codegen_flags_changed = 1; return op_pc + 1; } uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + int src_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); codegen_flags_changed = 1; return op_pc + 1; diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 28a08be..8bbf3ca 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -67,10 +67,10 @@ struct /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - [IREG_temp0] = {REG_DWORD, NULL}, - [IREG_temp1] = {REG_DWORD, NULL}, - [IREG_temp2] = {REG_DWORD, NULL}, - [IREG_temp3] = {REG_DWORD, NULL}, + [IREG_temp0] = {REG_DWORD, (void *)16}, + [IREG_temp1] = {REG_DWORD, (void *)20}, + [IREG_temp2] = {REG_DWORD, (void *)24}, + [IREG_temp3] = {REG_DWORD, (void *)28}, }; void codegen_reg_reset() @@ -99,7 +99,10 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { case REG_DWORD: - codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_32_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; default: @@ -113,19 +116,27 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate) { int ir_reg = IREG_GET_REG(host_regs[c].reg); + void *p = ireg_data[ir_reg].p; switch (ireg_data[ir_reg].native_size) { case REG_BYTE: - codegen_direct_write_8(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]); + if ((uintptr_t)p < 256) + fatal("codegen_reg_writeback - REG_BYTE %p\n", p); + codegen_direct_write_8(block, p, codegen_host_reg_list[c]); break; case REG_DWORD: - codegen_direct_write_32(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]); + if ((uintptr_t)p < 256) + codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]); + else + codegen_direct_write_32(block, p, codegen_host_reg_list[c]); break; case REG_POINTER: - codegen_direct_write_ptr(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]); + if ((uintptr_t)p < 256) + fatal("codegen_reg_writeback - REG_POINTER %p\n", p); + codegen_direct_write_ptr(block, p, codegen_host_reg_list[c]); break; default: diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 4fd0dd8..c57a0e5 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -82,7 +82,13 @@ enum IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, - IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B + IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, + + IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, + IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, + + IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, + IREG_temp1_B = IREG_temp1 + IREG_SIZE_B }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) From ab359ca9c5bbdea55e2f26dcf9878947083b212f Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 27 Jul 2018 22:25:03 +0100 Subject: [PATCH 0490/1050] Removed rogue CPU_BLOCK_END() from ropMOV_r_b() --- src/codegen_ops_mov.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index c7d906d..7073578 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -114,7 +114,6 @@ uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - CPU_BLOCK_END(); } return op_pc + 1; From a7d006b637c62331595a0f7bc4dac7a06fffc059 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 2 Aug 2018 22:06:10 +0100 Subject: [PATCH 0491/1050] Rewrote timer code. The new code is based on timestamps, rather than delays. This eliminates the need to update every timer in timer_process(), which cost a non-trivial amount of CPU time on low-end machines. This involved changes to every user of the timer code, so this change almost certainly introduces bugs. --- src/386.c | 9 +- src/386_dynarec.c | 4 +- src/808x.c | 18 +++- src/cpu.h | 2 +- src/disc.c | 18 ++-- src/disc.h | 6 +- src/esdi_at.c | 60 ++++-------- src/fdc.c | 123 +++++++++---------------- src/fdd.c | 9 +- src/fdd.h | 2 +- src/gameport.c | 23 ++--- src/hdd_esdi.c | 46 +++++---- src/ibm.h | 13 +-- src/ide.c | 76 +++++---------- src/ide.h | 3 +- src/ide_atapi.c | 42 ++++----- src/intel.c | 14 +-- src/joystick_sw_pad.c | 53 ++++------- src/keyboard_amstrad.c | 7 +- src/keyboard_at.c | 15 ++- src/keyboard_olim24.c | 7 +- src/keyboard_pcjr.c | 8 +- src/keyboard_xt.c | 11 ++- src/lpt_dac.c | 2 - src/lpt_dss.c | 8 +- src/mfm_at.c | 50 +++------- src/mfm_xebec.c | 38 ++++---- src/mouse_serial.c | 8 +- src/nethandler.c | 6 +- src/nvr.c | 34 ++++--- src/nvr_tc8521.c | 7 +- src/pit.c | 194 ++++++++++++++++++++------------------ src/pit.h | 2 +- src/scsi_53c400.c | 31 ++++--- src/scsi_aha1540.c | 8 +- src/scsi_cd.c | 47 ++++------ src/scsi_hd.c | 14 ++- src/scsi_zip.c | 14 ++- src/serial.c | 12 +-- src/serial.h | 4 +- src/sound.c | 9 +- src/sound_ad1848.c | 18 +++- src/sound_ad1848.h | 3 +- src/sound_adlibgold.c | 13 +-- src/sound_audiopci.c | 7 +- src/sound_gus.c | 27 +++--- src/sound_opl.c | 45 ++++----- src/sound_opl.h | 3 +- src/sound_pas16.c | 44 +++++---- src/sound_ps1.c | 13 ++- src/sound_pssj.c | 12 ++- src/sound_sb_dsp.c | 104 ++++++++++++--------- src/sound_sb_dsp.h | 7 +- src/timer.c | 205 ++++++++++++++++++++++------------------- src/timer.h | 166 ++++++++++++++++++++++++--------- src/vid_cga.c | 22 +++-- src/vid_cga.h | 4 +- src/vid_colorplus.c | 6 +- src/vid_compaq_cga.c | 10 +- src/vid_ega.c | 16 ++-- src/vid_ega.h | 4 +- src/vid_genius.c | 14 +-- src/vid_hercules.c | 14 +-- src/vid_incolor.c | 14 +-- src/vid_mda.c | 14 +-- src/vid_olivetti_m24.c | 19 ++-- src/vid_pc1512.c | 13 +-- src/vid_pc1640.c | 71 +++++++------- src/vid_pc200.c | 1 - src/vid_pcjr.c | 13 +-- src/vid_s3.c | 2 +- src/vid_svga.c | 14 +-- src/vid_svga.h | 4 +- src/vid_t1000.c | 16 ++-- src/vid_t3100e.c | 16 ++-- src/vid_tandy.c | 13 +-- src/vid_tandysl.c | 13 +-- src/vid_voodoo.c | 28 +++--- src/vid_wy700.c | 14 +-- 79 files changed, 1048 insertions(+), 1031 deletions(-) diff --git a/src/386.c b/src/386.c index dc254d3..25bb653 100644 --- a/src/386.c +++ b/src/386.c @@ -222,12 +222,11 @@ void exec386(int cycs) // output=3; while (cycles>0) { - int cycle_period = (timer_count >> TIMER_SHIFT) + 1; + int cycle_period = (timer_target - (uint32_t)tsc) + 1; x86_was_reset = 0; cycdiff=0; oldcyc=cycles; - timer_start_period(cycles << TIMER_SHIFT); // pclog("%i %02X\n", ins, ram[8]); while (cycdiff < cycle_period) { @@ -257,7 +256,7 @@ dontprint=0; 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 %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,cpu_state.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[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]); + 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\n",CS,cs,cpu_state.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); } cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -381,7 +380,7 @@ dontprint=0; } tsc += cycdiff; - - timer_end_period(cycles << TIMER_SHIFT); + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); } } diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 32cceb2..3f905bd 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -528,7 +528,6 @@ void exec386_dynarec(int cycs) cycles += cyc_period; cycles_start = cycles; - timer_start_period(cycles << TIMER_SHIFT); // output=3; while (cycles>0) { @@ -945,7 +944,8 @@ inrecomp=0; } } } - timer_end_period(cycles << TIMER_SHIFT); + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); cycles_main -= (cycles_start - cycles); } } diff --git a/src/808x.c b/src/808x.c index 9f66d45..eaeffa6 100644 --- a/src/808x.c +++ b/src/808x.c @@ -25,7 +25,7 @@ #include "x87.h" #include "paths.h" -int xt_cpu_multi; +uint64_t xt_cpu_multi; int nmi = 0; int nmi_auto_clear = 0; @@ -821,13 +821,24 @@ static void setsbc16(uint16_t a, uint16_t b) } int current_diff = 0; + +/*XT systems use the XT master oscillator (14.318 MHz) rather than the CPU clock + at the base timer frequency. Because there isn't an integer relationship + between the two frequencies, use fixed point arithmetic when updating TSC.*/ +static uint64_t tsc_frac = 0; + void clockhardware() { int diff = cycdiff - cycles - current_diff; current_diff += diff; - - timer_end_period(cycles*xt_cpu_multi); + + tsc_frac += (uint64_t)diff * xt_cpu_multi; + + tsc += (tsc_frac >> 32); + tsc_frac &= 0xffffffff; + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); } static int takeint = 0; @@ -1104,7 +1115,6 @@ void execx86(int cycs) // 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); diff --git a/src/cpu.h b/src/cpu.h index ef21835..ca6242f 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -140,7 +140,7 @@ void cpu_WRMSR(); extern int cpu_use_dynarec; -extern int xt_cpu_multi; +extern uint64_t xt_cpu_multi; extern int isa_cycles; #define ISA_CYCLES(x) (x * isa_cycles) diff --git a/src/disc.c b/src/disc.c index d4fa316..b2e0a0c 100644 --- a/src/disc.c +++ b/src/disc.c @@ -9,7 +9,7 @@ #include "timer.h" int disc_drivesel = 0; -int disc_poll_time = 16; +pc_timer_t disc_poll_timer; int disc_track[2]; int writeprot[2], fwriteprot[2]; @@ -22,9 +22,6 @@ int curdrive = 0; //char discfns[2][260] = {"", ""}; int defaultwriteprot = 0; -int fdc_time; -int disc_time; - int fdc_ready; int drive_empty[2] = {1, 1}; @@ -137,7 +134,7 @@ int disc_hole(int drive) void disc_poll() { - disc_poll_time += disc_period * TIMER_USEC; + timer_advance_u64(&disc_poll_timer, disc_period * TIMER_USEC); if (disc_drivesel < 2 && drives[disc_drivesel].poll) drives[disc_drivesel].poll(); @@ -209,7 +206,7 @@ void disc_reset() curdrive = 0; disc_period = 32; - timer_add(disc_poll, &disc_poll_time, &motoron, NULL); + timer_add(&disc_poll_timer, disc_poll, NULL, 0); for (drive = 0; drive < 2; drive++) { @@ -295,3 +292,12 @@ void disc_set_drivesel(int drive) disc_drivesel = drive; } + +void disc_set_motor_enable(int motor_enable) +{ + if (motor_enable && !motoron) + timer_set_delay_u64(&disc_poll_timer, disc_period * TIMER_USEC); + else if (!motor_enable) + timer_disable(&disc_poll_timer); + motoron = motor_enable; +} diff --git a/src/disc.h b/src/disc.h index a0214e4..d8e33a5 100644 --- a/src/disc.h +++ b/src/disc.h @@ -30,8 +30,7 @@ void disc_stop(int drive); int disc_empty(int drive); void disc_set_rate(int drive, int drvden, int rate); void disc_set_drivesel(int drive); -extern int disc_time; -extern int disc_poll_time; +void disc_set_motor_enable(int motor_enable); extern int disc_drivesel; void fdc_callback(); @@ -45,8 +44,7 @@ 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_ready; extern int fdc_indexcount;*/ extern int motorspin; diff --git a/src/esdi_at.c b/src/esdi_at.c index ae8d81e..c14ab7a 100644 --- a/src/esdi_at.c +++ b/src/esdi_at.c @@ -74,7 +74,7 @@ typedef struct esdi_t uint16_t buffer[256]; int irqstat; - int callback; + pc_timer_t callback_timer; esdi_drive_t drives[2]; @@ -224,18 +224,14 @@ void esdi_write(uint16_t port, uint8_t val, void *p) // pclog("Restore\n"); esdi->command &= ~0x0f; /*Mask off step rate*/ esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; case CMD_SEEK: // pclog("Seek to cylinder %i\n", esdi->cylinder); esdi->command &= ~0x0f; /*Mask off step rate*/ esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; default: @@ -243,9 +239,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) { case CMD_NOP: esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; case CMD_READ: case CMD_READ+1: @@ -256,9 +250,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) fatal("Read with ECC\n"); case 0xa0: esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; case CMD_WRITE: case CMD_WRITE+1: @@ -275,9 +267,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) // pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); esdi->command &= ~1; esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200 * IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); break; case CMD_FORMAT: @@ -288,33 +278,25 @@ void esdi_write(uint16_t port, uint8_t val, void *p) case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 30*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 30*IDE_TIME); break; case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; case 0xe0: /*???*/ case CMD_READ_PARAMETERS: esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; default: pclog("Bad esdi command %02X\n", val); case 0xe8: /*???*/ esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 200*IDE_TIME); break; } } @@ -323,9 +305,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) case 0x3F6: /* Device control */ if ((esdi->fdisk & 4) && !(val & 4)) { - timer_clock(); - esdi->callback = 500*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 500*IDE_TIME); esdi->reset = 1; esdi->status = STAT_BUSY; // pclog("esdi Reset\n"); @@ -333,9 +313,7 @@ void esdi_write(uint16_t port, uint8_t val, void *p) if (val & 4) { /*Drive held in reset*/ - timer_clock(); - esdi->callback = 0; - timer_update_outstanding(); + timer_disable(&esdi->callback_timer); esdi->status = STAT_BUSY; } esdi->fdisk = val; @@ -357,9 +335,7 @@ void esdi_writew(uint16_t port, uint16_t val, void *p) { esdi->pos = 0; esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 6*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 6*IDE_TIME); } } @@ -428,9 +404,7 @@ uint16_t esdi_readw(uint16_t port, void *p) { esdi_next_sector(esdi); esdi->status = STAT_BUSY; - timer_clock(); - esdi->callback = 6*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&esdi->callback_timer, 6*IDE_TIME); } } } @@ -446,7 +420,7 @@ void esdi_callback(void *p) off64_t addr; // pclog("esdi_callback: command=%02x reset=%i\n", esdi->command, esdi->reset); - esdi->callback = 0; + if (esdi->reset) { esdi->status = STAT_READY | STAT_DSC; @@ -586,7 +560,7 @@ void esdi_callback(void *p) esdi_next_sector(esdi); esdi->secount = (esdi->secount - 1) & 0xff; if (esdi->secount) - esdi->callback = 6*IDE_TIME; + timer_set_delay_u64(&esdi->callback_timer, 6*IDE_TIME); else { esdi->pos = 0; @@ -804,7 +778,7 @@ void *wd1007vse1_init() io_sethandler(0x01f1, 0x0007, esdi_read, NULL, NULL, esdi_write, NULL, NULL, esdi); io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi); - timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); + timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); return esdi; } diff --git a/src/fdc.c b/src/fdc.c index bec48bc..883cf01 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -10,8 +10,6 @@ #include "pic.h" #include "timer.h" -extern int motoron; - static int fdc_reset_stat = 0; /*FDC*/ typedef struct FDC @@ -39,7 +37,7 @@ typedef struct FDC int pcjr, ps1; - int watchdog_timer; + pc_timer_t watchdog_timer; int watchdog_count; int data_ready; @@ -65,6 +63,8 @@ typedef struct FDC uint8_t fifobuf[16]; int int_pending; + + pc_timer_t timer; } FDC; static FDC fdc; @@ -151,12 +151,11 @@ static void fdc_watchdog_poll(void *p) fdc->watchdog_count--; if (fdc->watchdog_count) - fdc->watchdog_timer += 1000 * TIMER_USEC; + timer_advance_u64(&fdc->watchdog_timer, 1000 * TIMER_USEC); else { // pclog("Watchdog timed out\n"); - fdc->watchdog_timer = 0; if (fdc->dor & 0x20) picint(1 << 6); } @@ -332,25 +331,19 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) { if ((fdc.dor & 0x40) && !(val & 0x40)) { - fdc.watchdog_timer = 1000 * TIMER_USEC; + timer_set_delay_u64(&fdc.watchdog_timer, 1000 * TIMER_USEC); fdc.watchdog_count = 1000; picintc(1 << 6); // pclog("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC); } if ((val & 0x80) && !(fdc.dor & 0x80)) { - timer_process(); - disctime = 128 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); discint=-1; fdc_reset(); } - motoron = val & 0x01; + disc_set_motor_enable(val & 0x01); fdc.drive = 0; -/* if (motoron) - output = 3; - else - output = 0;*/ } else { @@ -361,15 +354,11 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) } if ((val&4) && !(fdc.dor&4)) { - timer_process(); - disctime = 128 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); discint=-1; fdc_reset(); } - timer_process(); - motoron = (val & 0xf0) ? 1 : 0; - timer_update_outstanding(); + disc_set_motor_enable((val & 0xf0) ? 1 : 0); fdc.drive = val & 3; } fdc.dor=val; @@ -386,9 +375,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) case 4: if (val & 0x80) { - timer_process(); - disctime = 128 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); discint=-1; fdc_reset(); } @@ -471,7 +458,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) // 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(); @@ -480,9 +466,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) { fdc.stat=0x10; discint=0xfc; - timer_process(); - disctime = 200 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); } break; case 10: /*Read sector ID*/ @@ -553,9 +537,7 @@ bad_command: // exit(-1); fdc.stat=0x10; discint=0xfc; - timer_process(); - disctime = 200 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); break; } } @@ -564,12 +546,12 @@ bad_command: fdc.params[fdc.pnum++]=val; if (fdc.pnum==fdc.ptot) { + uint64_t time; + // pclog("Got all params %02X\n", fdc.command); fdc.stat=0x30; discint=fdc.command&0x1F; - timer_process(); - disctime = 1024 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); // fdc.drive = fdc.params[0] & 3; disc_drivesel = fdc.drive & 1; fdc_reset_stat = 0; @@ -587,7 +569,7 @@ bad_command: fdc.track[fdc.drive]=fdc.params[1]; // pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]); disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); - disctime = 0; + timer_disable(&fdc.timer); readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; @@ -597,7 +579,7 @@ bad_command: fdc.specify[0] = fdc.params[0]; fdc.specify[1] = fdc.params[1]; fdc.dma = (fdc.specify[1] & 1) ^ 1; - disctime = 0; + timer_disable(&fdc.timer); break; case 5: /*Write data*/ @@ -612,7 +594,7 @@ bad_command: fdc.rw_track = fdc.params[1]; disc_writesector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); - disctime = 0; + timer_disable(&fdc.timer); fdc.written = 0; readflash_set(READFLASH_FDC, fdc.drive); fdc.pos = 0; @@ -633,15 +615,17 @@ bad_command: fdc.rw_track = fdc.params[1]; disc_readsector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); - disctime = 0; + timer_disable(&fdc.timer); readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; case 7: /*Recalibrate*/ fdc.stat = 1 << fdc.drive; - disctime = 0; - fdd_seek(fdc.drive, SEEK_RECALIBRATE); + timer_disable(&fdc.timer); + time = fdd_seek(fdc.drive, SEEK_RECALIBRATE); + if (time) + timer_set_delay_u64(&fdc.timer, time); break; case 0x0d: /*Format*/ @@ -655,14 +639,16 @@ bad_command: case 0xf: /*Seek*/ fdc.stat = 1 << fdc.drive; fdc.head = (fdc.params[0] & 4) ? 1 : 0; - disctime = 0; - fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); + timer_disable(&fdc.timer); + time = fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); + if (time) + timer_set_delay_u64(&fdc.timer, time); // pclog("Seek to %i\n", fdc.params[1]); break; case 10: /*Read sector ID*/ fdc_rate(fdc.drive); - disctime = 0; + timer_disable(&fdc.timer); fdc.head = (fdc.params[0] & 4) ? 1 : 0; // pclog("Read sector ID %i %i\n", fdc.rate, fdc.drive); disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate); @@ -771,9 +757,7 @@ uint8_t fdc_read(uint16_t addr, void *priv) } if (discint==0xA) { - timer_process(); - disctime = 1024 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); } fdc.stat &= 0xf0; break; @@ -805,8 +789,7 @@ void fdc_callback() int doseek = 0; int drive; - disctime = 0; -// pclog("fdc_callback %i %i\n", discint, disctime); +// pclog("fdc_callback %i\n", discint); // if (fdc.inread) // rpclog("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins); switch (discint) @@ -870,7 +853,6 @@ void fdc_callback() fdc.stat = (fdc.stat & 0xf) | 0xd0; paramstogo = 1; discint = 0; - disctime = 0; return; case 5: /*Write data*/ if (!fdc.in_seek_mt) @@ -983,9 +965,7 @@ void fdc_callback() fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head?4:0); fdc.int_pending = 1; discint=-3; - timer_process(); - disctime = 2048 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 2048 * TIMER_USEC); // printf("Recalibrate complete!\n"); fdc.stat = 0x80 | (1 << fdc.drive); return; @@ -1006,7 +986,6 @@ void fdc_callback() paramstogo = 2; discint = 0; - disctime = 0; return; case 0x0d: /*Format track*/ @@ -1015,26 +994,20 @@ void fdc_callback() { // ioc_fiq(IOC_FIQ_DISC_DATA); fdc.format_state = 2; - timer_process(); - disctime = 128 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); } else if (fdc.format_state == 2) { temp = fdc_getdata(fdc.pos == ((fdc.params[2] * 4) - 1)); if (temp == -1) { - timer_process(); - disctime = 128 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); return; } fdc.format_dat[fdc.pos++] = temp; if (fdc.pos == (fdc.params[2] * 4)) fdc.format_state = 3; - timer_process(); - disctime = 128 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); } else if (fdc.format_state == 3) { @@ -1070,9 +1043,7 @@ void fdc_callback() fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head?4:0); fdc.int_pending = 1; discint=-3; - timer_process(); - disctime = 2048 * (1 << TIMER_SHIFT); - timer_update_outstanding(); + timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); fdc.stat = 0x80 | (1 << fdc.drive); // pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); return; @@ -1088,7 +1059,6 @@ void fdc_callback() fdc.res[10] = (fdc.perp & 0x7f) | ((fdc.lock) ? 0x80 : 0); paramstogo=10; discint=0; - disctime = 0; return; case 0x10: /*Version*/ @@ -1096,13 +1066,11 @@ void fdc_callback() fdc.res[10] = 0x90; paramstogo=1; discint=0; - disctime = 0; return; case 0x12: fdc.perp = fdc.params[0]; fdc.stat = 0x80; - disctime = 0; // picint(0x40); return; case 0x13: /*Configure*/ @@ -1112,7 +1080,6 @@ void fdc_callback() fdc.tfifo = (fdc.params[1] & 0xF) + 1; pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo); fdc.stat = 0x80; - disctime = 0; // picint(0x40); return; case 0x14: /*Unlock*/ @@ -1121,7 +1088,6 @@ void fdc_callback() fdc.res[10] = 0; paramstogo=1; discint=0; - disctime = 0; return; case 0x94: /*Lock*/ fdc.lock = 1; @@ -1129,7 +1095,6 @@ void fdc_callback() fdc.res[10] = 0x10; paramstogo=1; discint=0; - disctime = 0; return; case 0x18: /*NSC*/ @@ -1137,7 +1102,6 @@ void fdc_callback() fdc.res[10] = 0x73; paramstogo=1; discint=0; - disctime = 0; return; case 0xfc: /*Invalid*/ @@ -1149,7 +1113,6 @@ void fdc_callback() fdc.res[10] = fdc.st0; paramstogo=1; discint=0; - disctime = 0; return; } // printf("Bad FDC disc int %i\n",discint); @@ -1160,7 +1123,7 @@ void fdc_callback() void fdc_overrun() { disc_sector_stop(); - disctime = 0; + timer_disable(&fdc.timer); fdc_int(); fdc.stat=0xD0; @@ -1234,13 +1197,13 @@ int fdc_data(uint8_t data) void fdc_finishread() { fdc.inread = 0; - disctime = 200 * TIMER_USEC; + timer_set_delay_u64(&fdc.timer, 200 * TIMER_USEC); // rpclog("fdc_finishread\n"); } void fdc_notfound() { - disctime = 0; + timer_disable(&fdc.timer); fdc_int(); fdc.stat=0xD0; @@ -1257,7 +1220,7 @@ void fdc_notfound() void fdc_datacrcerror() { - disctime = 0; + timer_disable(&fdc.timer); fdc_int(); fdc.stat=0xD0; @@ -1274,7 +1237,7 @@ void fdc_datacrcerror() void fdc_headercrcerror() { - disctime = 0; + timer_disable(&fdc.timer); fdc_int(); fdc.stat=0xD0; @@ -1291,7 +1254,7 @@ void fdc_headercrcerror() void fdc_writeprotect() { - disctime = 0; + timer_disable(&fdc.timer); fdc_int(); fdc.stat=0xD0; @@ -1380,7 +1343,7 @@ void fdc_indexpulse() void fdc_init() { - timer_add(fdc_callback, &disctime, &disctime, NULL); + timer_add(&fdc.timer, fdc_callback, NULL, 0); fdc.dskchg_activelow = 0; fdc.enable_3f1 = 1; @@ -1404,7 +1367,7 @@ void fdc_add() void fdc_add_pcjr() { io_sethandler(0x00f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); - timer_add(fdc_watchdog_poll, &fdc.watchdog_timer, &fdc.watchdog_timer, &fdc); + timer_add(&fdc.watchdog_timer, fdc_watchdog_poll, &fdc, 0); fdc.pcjr = 1; fdc.ps1 = 0; } diff --git a/src/fdd.c b/src/fdd.c index 69a196f..9c2c3fa 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -76,15 +76,12 @@ static struct int fdd_swap = 0; -void fdd_seek(int drive, int track_diff) +uint64_t fdd_seek(int drive, int track_diff) { drive ^= fdd_swap; if (drive >= 2) - { - disctime = 5000; - return; - } + return 1000 * TIMER_USEC; fdd[drive].track += track_diff; @@ -99,7 +96,7 @@ void fdd_seek(int drive, int track_diff) fdc_discchange_clear(drive); disc_seek(drive, fdd[drive].track); - disctime = 5000; + return 1000 * TIMER_USEC; } void fdd_disc_changed(int drive) diff --git a/src/fdd.h b/src/fdd.h index 5581b73..76071a1 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -1,5 +1,5 @@ #define SEEK_RECALIBRATE -999 -void fdd_seek(int drive, int track_diff); +uint64_t fdd_seek(int drive, int track_diff); int fdd_track0(int drive); int fdd_getrpm(int drive); void fdd_set_densel(int densel); diff --git a/src/gameport.c b/src/gameport.c index 5d16123..fbf142a 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -69,7 +69,7 @@ char *joystick_get_pov_name(int joystick, int id) typedef struct gameport_axis_t { - int count; + pc_timer_t timer; int axis_nr; struct gameport_t *gameport; } gameport_axis_t; @@ -86,7 +86,7 @@ typedef struct gameport_t static gameport_t *gameport_global = NULL; -static int gameport_time(int axis) +static uint64_t gameport_time(int axis) { if (axis == AXIS_NOT_PRESENT) return 0; @@ -101,14 +101,13 @@ void gameport_write(uint16_t addr, uint8_t val, void *p) { gameport_t *gameport = (gameport_t *)p; - timer_clock(); gameport->state |= 0x0f; // 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)); - gameport->axis[2].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2)); - gameport->axis[3].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3)); + timer_set_delay_u64(&gameport->axis[0].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0))); + timer_set_delay_u64(&gameport->axis[1].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1))); + timer_set_delay_u64(&gameport->axis[2].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2))); + timer_set_delay_u64(&gameport->axis[3].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3))); gameport->joystick->write(gameport->joystick_dat); @@ -120,7 +119,6 @@ uint8_t gameport_read(uint16_t addr, void *p) gameport_t *gameport = (gameport_t *)p; uint8_t ret; - timer_clock(); // if (joysticks_present) ret = gameport->state | gameport->joystick->read(gameport->joystick_dat);//0xf0; // else @@ -139,7 +137,6 @@ void gameport_timer_over(void *p) gameport_t *gameport = axis->gameport; gameport->state &= ~(1 << axis->axis_nr); - axis->count = 0; if (axis == &gameport->axis[0]) gameport->joystick->a0_over(gameport->joystick_dat); @@ -161,10 +158,10 @@ void *gameport_init_common() gameport->axis[2].axis_nr = 2; gameport->axis[3].axis_nr = 3; - timer_add(gameport_timer_over, &gameport->axis[0].count, &gameport->axis[0].count, &gameport->axis[0]); - timer_add(gameport_timer_over, &gameport->axis[1].count, &gameport->axis[1].count, &gameport->axis[1]); - timer_add(gameport_timer_over, &gameport->axis[2].count, &gameport->axis[2].count, &gameport->axis[2]); - timer_add(gameport_timer_over, &gameport->axis[3].count, &gameport->axis[3].count, &gameport->axis[3]); + timer_add(&gameport->axis[0].timer, gameport_timer_over, &gameport->axis[0], 0); + timer_add(&gameport->axis[1].timer, gameport_timer_over, &gameport->axis[1], 0); + timer_add(&gameport->axis[2].timer, gameport_timer_over, &gameport->axis[2], 0); + timer_add(&gameport->axis[3].timer, gameport_timer_over, &gameport->axis[3], 0); gameport->joystick = joystick_list[joystick_type]; gameport->joystick_dat = gameport->joystick->init(); diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 23e1f75..9465af1 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -58,7 +58,7 @@ typedef struct esdi_t int cmd_state; int in_reset; - int callback; + pc_timer_t callback_timer; uint32_t rba; @@ -163,7 +163,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p) { // pclog("ESDI reset\n"); esdi->in_reset = 1; - esdi->callback = ESDI_TIME * 50; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); esdi->status = STATUS_BUSY; } esdi->basic_ctrl = val; @@ -195,7 +195,7 @@ static void esdi_write(uint16_t port, uint8_t val, void *p) case ATTN_RESET: // pclog("ESDI reset\n"); esdi->in_reset = 1; - esdi->callback = ESDI_TIME * 50; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); esdi->status = STATUS_BUSY; break; @@ -311,7 +311,7 @@ static void esdi_writew(uint16_t port, uint16_t val, void *p) 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; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); esdi->status = STATUS_BUSY; esdi->data_pos = 0; } @@ -421,8 +421,6 @@ static void esdi_callback(void *p) esdi_t *esdi = (esdi_t *)p; hdd_file_t *hdd_file; - esdi->callback = 0; - // pclog("esdi_callback: in_reset=%i command=%x\n", esdi->in_reset, esdi->command); if (esdi->in_reset) { @@ -464,7 +462,7 @@ static void esdi_callback(void *p) esdi_set_irq(esdi); esdi->cmd_state = 1; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); esdi->data_pos = 0; break; @@ -472,7 +470,7 @@ static void esdi_callback(void *p) if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { // pclog("DMA not enabled\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } while (esdi->sector_pos < esdi->sector_count) @@ -492,7 +490,7 @@ static void esdi_callback(void *p) if (val == DMA_NODATA) { // pclog("DMA out of data\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } @@ -506,7 +504,7 @@ static void esdi_callback(void *p) esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); break; case 2: @@ -551,7 +549,7 @@ static void esdi_callback(void *p) esdi_set_irq(esdi); esdi->cmd_state = 1; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); esdi->data_pos = 0; break; @@ -559,7 +557,7 @@ static void esdi_callback(void *p) if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { // pclog("DMA not enabled\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } while (esdi->sector_pos < esdi->sector_count) @@ -572,7 +570,7 @@ static void esdi_callback(void *p) if (val == DMA_NODATA) { // pclog("DMA out of data\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } @@ -591,7 +589,7 @@ static void esdi_callback(void *p) esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); break; case 2: @@ -739,7 +737,7 @@ static void esdi_callback(void *p) esdi_set_irq(esdi); esdi->cmd_state = 1; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); esdi->data_pos = 0; break; @@ -747,7 +745,7 @@ static void esdi_callback(void *p) if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { // pclog("DMA not enabled\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } while (esdi->sector_pos < esdi->sector_count) @@ -762,7 +760,7 @@ static void esdi_callback(void *p) if (val == DMA_NODATA) { // pclog("DMA out of data\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } @@ -774,7 +772,7 @@ static void esdi_callback(void *p) esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); break; case 2: @@ -803,7 +801,7 @@ static void esdi_callback(void *p) esdi_set_irq(esdi); esdi->cmd_state = 1; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); esdi->data_pos = 0; break; @@ -811,7 +809,7 @@ static void esdi_callback(void *p) if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { // pclog("DMA not enabled\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } while (esdi->sector_pos < esdi->sector_count) @@ -824,7 +822,7 @@ static void esdi_callback(void *p) if (val == DMA_NODATA) { // pclog("DMA out of data\n"); - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); return; } @@ -837,7 +835,7 @@ static void esdi_callback(void *p) esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; - esdi->callback = ESDI_TIME; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); break; case 2: @@ -917,7 +915,7 @@ static void *esdi_init() hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]); hdd_load(&esdi->hdd_file[1], 1, ide_fn[1]); - timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); + timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); mca_add(esdi_mca_read, esdi_mca_write, esdi); @@ -925,7 +923,7 @@ static void *esdi_init() esdi->pos_regs[1] = 0xdd; esdi->in_reset = 1; - esdi->callback = ESDI_TIME * 50; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); esdi->status = STATUS_BUSY; return esdi; diff --git a/src/ibm.h b/src/ibm.h index 70641c9..e852ac1 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -2,6 +2,8 @@ #include #include +#include "timer.h" + #ifdef ABS #undef ABS #endif @@ -296,7 +298,7 @@ typedef struct PIT_nr typedef struct PIT { uint32_t l[3]; - int c[3]; + pc_timer_t timer[3]; uint8_t m[3]; uint8_t ctrl,ctrls[3]; int wp,rm[3],wm[3]; @@ -378,7 +380,6 @@ PIC pic,pic2; extern int pic_intpending; -int disctime; char discfns[2][256]; int driveempty[2]; @@ -527,10 +528,10 @@ extern int changeframecount; /*Sound*/ int ppispeakon; -float CGACONST; -float MDACONST; -float VGACONST1,VGACONST2; -float RTCCONST; +extern uint64_t CGACONST; +extern uint64_t MDACONST; +extern uint64_t VGACONST1,VGACONST2; +extern uint64_t RTCCONST; int gated,speakval,speakon; diff --git a/src/ide.c b/src/ide.c index 5d1a29b..44e74a7 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1,4 +1,4 @@ -#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) +#define IDE_TIME (10 * TIMER_USEC) #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE @@ -98,7 +98,7 @@ int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size); int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size); void (*ide_bus_master_set_irq)(int channel); -int idecallback[2] = {0, 0}; +pc_timer_t ide_timer[2]; int cur_ide[2]; @@ -268,7 +268,6 @@ void resetide(void) ide_drives[d].board = (d & 2) ? 1 : 0; } - idecallback[0]=idecallback[1]=0; if (hdd_controller_current_is_ide()) { for (d = 0; d < 4; d++) @@ -324,12 +323,10 @@ void writeidew(int ide_board, uint16_t val) { 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(); + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); } } } @@ -428,8 +425,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (IDE_DRIVE_IS_CDROM(ide_other)) ide_other->cylinder=0xEB14; - idecallback[ide_board] = 0; - timer_update_outstanding(); + timer_disable(&ide_timer[ide_board]); return; } @@ -460,18 +456,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SRST: /* ATAPI Device Reset */ if (IDE_DRIVE_IS_CDROM(ide)) ide->atastat = BUSY_STAT; else ide->atastat = READY_STAT; - timer_process(); - idecallback[ide_board]=100*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 100*IDE_TIME); return; case WIN_RESTORE: case WIN_SEEK: // pclog("WIN_RESTORE start\n"); ide->atastat = READY_STAT; - timer_process(); - idecallback[ide_board]=100*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 100*IDE_TIME); return; case WIN_READ_MULTIPLE: @@ -495,9 +487,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins); #endif ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME); ide->do_initial_read = 1; return; @@ -530,9 +520,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else pclog("Write %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); #endif ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME); return; case WIN_VERIFY: @@ -542,9 +530,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) else pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); #endif ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME); return; case WIN_FORMAT: @@ -556,18 +542,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SPECIFY: /* Initialize Drive Parameters */ ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=30*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 30*IDE_TIME); // pclog("SPECIFY\n"); // output=1; return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME); return; case WIN_PIDENTIFY: /* Identify Packet Device */ @@ -576,10 +558,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SETIDLE1: /* Idle */ case WIN_CHECK_POWER_MODE: ide->atastat = BUSY_STAT; - timer_process(); callbackide(ide_board); // idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); return; case WIN_IDENTIFY: /* Identify Device */ @@ -587,9 +567,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) // output=3; // timetolive=500; ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 200*IDE_TIME); return; case WIN_PACKETCMD: /* ATAPI Packet */ @@ -597,9 +575,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) atapi_command_start(&ide->atapi, ide->cylprecomp); ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board] = IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], IDE_TIME); ide->atapi.bus_state = 0; return; @@ -618,9 +594,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case 0x3F6: /* Device control */ if ((ide->fdisk&4) && !(val&4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { - timer_process(); - idecallback[ide_board]=500*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&ide_timer[ide_board], 500*IDE_TIME); ide->reset = ide_other->reset = 1; ide->atastat = ide_other->atastat = BUSY_STAT; // pclog("IDE Reset %i\n", ide_board); @@ -628,9 +602,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if (val & 4) { /*Drive held in reset*/ - timer_process(); - idecallback[ide_board] = 0; - timer_update_outstanding(); + timer_disable(&ide_timer[ide_board]); ide->atastat = ide_other->atastat = BUSY_STAT; } ide->fdisk = ide_other->fdisk = val; @@ -794,12 +766,10 @@ uint16_t readidew(int ide_board) { 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(); + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); // pclog("set idecallback\n"); // callbackide(ide_board); } @@ -936,7 +906,7 @@ void callbackide(int ide_board) if (ide_bus_master_read_data) { if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512)) - idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ + timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); /*DMA not performed, try again later*/ else { /*DMA successful*/ @@ -948,7 +918,7 @@ void callbackide(int ide_board) { ide_next_sector(ide); ide->atastat = BUSY_STAT; - idecallback[ide_board]=6*IDE_TIME; + timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); } else { @@ -1014,7 +984,7 @@ void callbackide(int ide_board) if (ide_bus_master_write_data) { if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512)) - idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ + timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); /*DMA not performed, try again later*/ else { /*DMA successful*/ @@ -1027,7 +997,7 @@ void callbackide(int ide_board) { ide_next_sector(ide); ide->atastat = BUSY_STAT; - idecallback[ide_board]=6*IDE_TIME; + timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); } else { @@ -1201,13 +1171,11 @@ abort_cmd: void ide_callback_pri() { - idecallback[0] = 0; callbackide(0); } void ide_callback_sec() { - idecallback[1] = 0; callbackide(1); } @@ -1292,8 +1260,8 @@ static void *ide_init() ide_pri_enable(); ide_sec_enable(); - timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); - timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); + timer_add(&ide_timer[0], ide_callback_pri, NULL, 0); + timer_add(&ide_timer[1], ide_callback_sec, NULL, 0); return (void *)-1; } diff --git a/src/ide.h b/src/ide.h index cb497ea..aed1200 100644 --- a/src/ide.h +++ b/src/ide.h @@ -2,6 +2,7 @@ #define __IDE__ #include "device.h" +#include "timer.h" struct IDE; @@ -26,7 +27,7 @@ extern void (*ide_bus_master_set_irq)(int channel); extern int ideboard; -extern int idecallback[2]; +extern pc_timer_t ide_timer[2]; extern char ide_fn[7][512]; diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 1760a43..ab4330e 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -4,7 +4,7 @@ #include "scsi.h" #include "timer.h" -#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) +#define IDE_TIME (100 * TIMER_USEC) #define ATAPI_STATE_IDLE 0 #define ATAPI_STATE_COMMAND 1 @@ -35,7 +35,7 @@ void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val) if (atapi_dev->command_pos >= 12) { atapi_dev->state = ATAPI_STATE_GOT_COMMAND; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } break; @@ -47,7 +47,7 @@ void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val) { atapi_dev->bus_state = 0; atapi_dev->state = ATAPI_STATE_WRITE_DATA; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } break; } @@ -73,7 +73,7 @@ uint16_t atapi_data_read(atapi_device_t *atapi_dev) if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) { atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 6*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6*IDE_TIME); } break; } @@ -199,7 +199,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { // pclog("SEND_COMMAND timed out %x\n", scsi_bus_read(&atapi_dev->bus)); atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); break; } @@ -209,7 +209,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { // pclog("SEND_COMMAND - bus state changed %x\n", bus_state); atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); break; } @@ -261,20 +261,20 @@ void atapi_process_packet(atapi_device_t *atapi_dev) if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos)) { atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } else { atapi_dev->data_write_pos = atapi_dev->data_read_pos; atapi_dev->bus_state = 0; atapi_dev->state = ATAPI_STATE_WRITE_DATA; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } } else { atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } } else @@ -312,7 +312,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) break; } } - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } break; @@ -344,7 +344,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) break; } } - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } break; @@ -387,7 +387,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) break; } } - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } break; @@ -433,18 +433,18 @@ void atapi_process_packet(atapi_device_t *atapi_dev) if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos)) { atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } else { atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } } else { atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } } else @@ -490,7 +490,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) } atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 1 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); } break; @@ -529,7 +529,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) ide_irq_raise(atapi_dev->ide); } else - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } break; @@ -537,12 +537,12 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos)) { - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } else { atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - idecallback[atapi_dev->board] = 6*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6*IDE_TIME); } } break; @@ -551,13 +551,13 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos)) { - idecallback[atapi_dev->board] = 1*IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } else { atapi_dev->bus_state = 0; atapi_dev->state = ATAPI_STATE_WRITE_DATA; - idecallback[atapi_dev->board] = 6 * IDE_TIME; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); } } break; diff --git a/src/intel.c b/src/intel.c index 21e91b1..85ebcbf 100644 --- a/src/intel.c +++ b/src/intel.c @@ -45,11 +45,10 @@ void batman_brdconfig_write(uint16_t port, uint8_t val, void *p) } static uint16_t batman_timer_latch; -static int batman_timer = 0; +static pc_timer_t batman_timer; static void batman_timer_over(void *p) { - batman_timer = 0; } static void batman_timer_write(uint16_t addr, uint8_t val, void *p) @@ -58,7 +57,7 @@ static void batman_timer_write(uint16_t addr, uint8_t val, void *p) batman_timer_latch = (batman_timer_latch & 0xff) | (val << 8); else batman_timer_latch = (batman_timer_latch & 0xff00) | val; - batman_timer = batman_timer_latch * TIMER_USEC; + timer_set_delay_u64(&batman_timer, batman_timer_latch * TIMER_USEC); } static uint8_t batman_timer_read(uint16_t addr, void *p) @@ -67,12 +66,7 @@ static uint8_t batman_timer_read(uint16_t addr, void *p) cycles -= (int)PITCONST; - timer_clock(); - - if (batman_timer < 0) - return 0; - - batman_timer_latch = batman_timer / TIMER_USEC; + batman_timer_latch = timer_get_remaining_us(&batman_timer); if (addr & 1) return batman_timer_latch >> 8; @@ -87,7 +81,7 @@ void intel_batman_init() io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, batman_brdconfig, NULL, NULL, batman_brdconfig_write, NULL, NULL, NULL); batman_port_92 = 0; - timer_add(batman_timer_over, &batman_timer, &batman_timer, NULL); + timer_add(&batman_timer, batman_timer_over, NULL, 0); } diff --git a/src/joystick_sw_pad.c b/src/joystick_sw_pad.c index c0d0e8b..b5aab34 100644 --- a/src/joystick_sw_pad.c +++ b/src/joystick_sw_pad.c @@ -30,13 +30,13 @@ typedef struct { - int poll_time; + pc_timer_t poll_timer; int poll_left; int poll_clock; uint64_t poll_data; int poll_mode; - int trigger_time; + pc_timer_t trigger_timer; int data_mode; } sw_data; @@ -44,33 +44,22 @@ static void sw_timer_over(void *p) { sw_data *sw = (sw_data *)p; - while (sw->poll_time <= 0 && sw->poll_left) - { - sw->poll_clock = !sw->poll_clock; + sw->poll_clock = !sw->poll_clock; - if (sw->poll_clock) - { - sw->poll_data >>= (sw->poll_mode ? 3 : 1); - sw->poll_left--; - } - - if (sw->poll_left == 1 && !sw->poll_clock) - sw->poll_time += TIMER_USEC * 160; - else if (sw->poll_left) - sw->poll_time += TIMER_USEC * 5; - else - sw->poll_time = 0; + if (sw->poll_clock) + { + sw->poll_data >>= (sw->poll_mode ? 3 : 1); + sw->poll_left--; } - - if (!sw->poll_left) - sw->poll_time = 0; + + if (sw->poll_left == 1 && !sw->poll_clock) + timer_advance_u64(&sw->poll_timer, TIMER_USEC * 160); + else if (sw->poll_left) + timer_advance_u64(&sw->poll_timer, TIMER_USEC * 5); } static void sw_trigger_timer_over(void *p) { - sw_data *sw = (sw_data *)p; - - sw->trigger_time = 0; } static int sw_parity(uint16_t data) @@ -91,8 +80,8 @@ static void *sw_init() sw_data *sw = (sw_data *)malloc(sizeof(sw_data)); memset(sw, 0, sizeof(sw_data)); - timer_add(sw_timer_over, &sw->poll_time, &sw->poll_time, sw); - timer_add(sw_trigger_timer_over, &sw->trigger_time, &sw->trigger_time, sw); + timer_add(&sw->poll_timer, sw_timer_over, sw, 0); + timer_add(&sw->trigger_timer, sw_trigger_timer_over, sw, 0); return sw; } @@ -112,7 +101,7 @@ static uint8_t sw_read(void *p) if (!JOYSTICK_PRESENT(0)) return 0xff; - if (sw->poll_time) + if (timer_is_enabled(&sw->poll_timer)) { if (sw->poll_clock) temp |= 0x10; @@ -135,7 +124,7 @@ static uint8_t sw_read(void *p) static void sw_write(void *p) { sw_data *sw = (sw_data *)p; - int time_since_last = sw->trigger_time / TIMER_USEC; + int time_since_last = timer_get_remaining_us(&sw->trigger_timer); if (!JOYSTICK_PRESENT(0)) return; @@ -145,7 +134,7 @@ static void sw_write(void *p) if (!sw->poll_left) { sw->poll_clock = 1; - sw->poll_time = TIMER_USEC * 50; + timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 50); if (time_since_last > 9900 && time_since_last < 9940) { @@ -213,10 +202,8 @@ static void sw_write(void *p) } } } - - sw->trigger_time = 0; - - timer_update_outstanding(); + + timer_disable(&sw->trigger_timer); } static int sw_read_axis(void *p, int axis) @@ -231,7 +218,7 @@ static void sw_a0_over(void *p) { sw_data *sw = (sw_data *)p; - sw->trigger_time = TIMER_USEC * 10000; + timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); } joystick_if_t joystick_sw_pad = diff --git a/src/keyboard_amstrad.c b/src/keyboard_amstrad.c index e7647f4..31b0eb4 100644 --- a/src/keyboard_amstrad.c +++ b/src/keyboard_amstrad.c @@ -26,6 +26,8 @@ struct uint8_t key_waiting; uint8_t pa; uint8_t pb; + + pc_timer_t send_delay_timer; } keyboard_amstrad; static uint8_t key_queue[16]; @@ -35,7 +37,7 @@ static uint8_t amstrad_systemstat_1, amstrad_systemstat_2; void keyboard_amstrad_poll() { - keybsenddelay += (1000 * TIMER_USEC); + timer_advance_u64(&keyboard_amstrad.send_delay_timer, (1000 * TIMER_USEC)); if (keyboard_amstrad.wantirq) { keyboard_amstrad.wantirq = 0; @@ -77,7 +79,6 @@ void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv) ppi.pb = val; timer_process(); - timer_update_outstanding(); speaker_update(); speaker_gated = val & 1; @@ -174,5 +175,5 @@ void keyboard_amstrad_init() keyboard_send = keyboard_amstrad_adddata; keyboard_poll = keyboard_amstrad_poll; - timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_amstrad.send_delay_timer, keyboard_amstrad_poll, NULL, 1); } diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 17d9af5..2f06842 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -48,10 +48,12 @@ struct void (*mouse_write)(uint8_t val, void *p); void *mouse_p; - int refresh_time; + pc_timer_t refresh_timer; int refresh; int is_ps2; + + pc_timer_t send_delay_timer; } keyboard_at; static uint8_t key_ctrl_queue[16]; @@ -65,7 +67,7 @@ int mouse_queue_start = 0, mouse_queue_end = 0; void keyboard_at_poll() { - keybsenddelay += (100 * TIMER_USEC); + timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC)); if (keyboard_at.out_new != -1 && !keyboard_at.last_irq) { @@ -336,9 +338,6 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0x61: ppi.pb = val; - timer_process(); - timer_update_outstanding(); - speaker_update(); speaker_gated = val & 1; speaker_enable = val & 2; @@ -626,7 +625,7 @@ void keyboard_at_reset() static void at_refresh(void *p) { keyboard_at.refresh = !keyboard_at.refresh; - keyboard_at.refresh_time += PS2_REFRESH_TIME; + timer_advance_u64(&keyboard_at.refresh_timer, PS2_REFRESH_TIME); } void keyboard_at_init() @@ -641,7 +640,7 @@ void keyboard_at_init() keyboard_at.mouse_p = NULL; keyboard_at.is_ps2 = 0; - timer_add(keyboard_at_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1); } void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) @@ -652,6 +651,6 @@ void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) void keyboard_at_init_ps2() { - timer_add(at_refresh, &keyboard_at.refresh_time, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_at.refresh_timer, at_refresh, NULL, 1); keyboard_at.is_ps2 = 1; } diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index e86241d..a34d830 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -34,6 +34,8 @@ struct uint8_t params[16]; int mouse_mode; + + pc_timer_t send_delay_timer; } keyboard_olim24; static uint8_t key_queue[16]; @@ -43,7 +45,7 @@ static uint8_t mouse_scancodes[7]; void keyboard_olim24_poll() { - keybsenddelay += (1000 * TIMER_USEC); + timer_advance_u64(&keyboard_olim24.send_delay_timer, (1000 * TIMER_USEC)); //pclog("poll %i\n", keyboard_olim24.wantirq); if (keyboard_olim24.wantirq) { @@ -147,7 +149,6 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) ppi.pb = val; timer_process(); - timer_update_outstanding(); speaker_update(); speaker_gated = val & 1; @@ -345,5 +346,5 @@ void keyboard_olim24_init() keyboard_send = keyboard_olim24_adddata; keyboard_poll = keyboard_olim24_poll; - timer_add(keyboard_olim24_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_olim24.send_delay_timer, keyboard_olim24_poll, NULL, 1); } diff --git a/src/keyboard_pcjr.c b/src/keyboard_pcjr.c index 13f443b..c7119c2 100644 --- a/src/keyboard_pcjr.c +++ b/src/keyboard_pcjr.c @@ -32,6 +32,8 @@ struct uint8_t pa; uint8_t pb; + + pc_timer_t send_delay_timer; } keyboard_pcjr; static uint8_t key_queue[16]; @@ -39,8 +41,7 @@ static int key_queue_start = 0, key_queue_end = 0; void keyboard_pcjr_poll() { - keybsenddelay += (220 * TIMER_USEC); - + timer_advance_u64(&keyboard_pcjr.send_delay_timer, (220 * TIMER_USEC)); if (key_queue_start != key_queue_end && !keyboard_pcjr.serial_pos && !keyboard_pcjr.latched) { @@ -127,7 +128,6 @@ void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) keyboard_pcjr.pb = val; timer_process(); - timer_update_outstanding(); speaker_update(); speaker_gated = val & 1; @@ -205,5 +205,5 @@ void keyboard_pcjr_init() keyboard_send = keyboard_pcjr_adddata; keyboard_poll = keyboard_pcjr_poll; - timer_add(keyboard_pcjr_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_pcjr.send_delay_timer, keyboard_pcjr_poll, NULL, 1); } diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index a36e707..d2bef2e 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -36,6 +36,8 @@ struct int tandy; int pb2_turbo; + + pc_timer_t send_delay_timer; } keyboard_xt; static uint8_t key_queue[16]; @@ -43,7 +45,7 @@ static int key_queue_start = 0, key_queue_end = 0; void keyboard_xt_poll() { - keybsenddelay += (1000 * TIMER_USEC); + timer_advance_u64(&keyboard_xt.send_delay_timer, (1000 * TIMER_USEC)); if (!(keyboard_xt.pb & 0x40) && romset != ROM_TANDY) return; if (keyboard_xt.wantirq) @@ -124,8 +126,7 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) ppi.pb = val; timer_process(); - timer_update_outstanding(); - + if (keyboard_xt.pb2_turbo) cpu_set_turbo((val & 4) ? 0 : 1); @@ -236,7 +237,7 @@ void keyboard_xt_init() keyboard_xt.tandy = 0; keyboard_xt.pb2_turbo = (romset == ROM_GENXT || romset == ROM_DTKXT || romset == ROM_AMIXT || romset == ROM_PXXT) ? 1 : 0; - timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1); } void keyboard_tandy_init() @@ -248,5 +249,5 @@ void keyboard_tandy_init() keyboard_poll = keyboard_xt_poll; keyboard_xt.tandy = (romset != ROM_TANDY) ? 1 : 0; - timer_add(keyboard_xt_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1); } diff --git a/src/lpt_dac.c b/src/lpt_dac.c index d12f249..7a6fe82 100644 --- a/src/lpt_dac.c +++ b/src/lpt_dac.c @@ -30,8 +30,6 @@ static void dac_write_data(uint8_t val, void *p) { lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - timer_clock(); - if (lpt_dac->is_stereo) { if (lpt_dac->channel) diff --git a/src/lpt_dss.c b/src/lpt_dss.c index 0f53edd..767658a 100644 --- a/src/lpt_dss.c +++ b/src/lpt_dss.c @@ -12,7 +12,7 @@ typedef struct dss_t uint8_t dac_val; - int time; + pc_timer_t timer; int16_t buffer[MAXSOUNDBUFLEN]; int pos; @@ -29,8 +29,6 @@ static void dss_write_data(uint8_t val, void *p) { dss_t *dss = (dss_t *)p; - timer_clock(); - if ((dss->write_idx - dss->read_idx) < 16) { dss->fifo[dss->write_idx & 15] = val; @@ -82,7 +80,7 @@ static void dss_callback(void *p) dss->read_idx++; } - dss->time += (TIMER_USEC * (1000000.0 / 7000.0)); + timer_advance_u64(&dss->timer, (TIMER_USEC * (1000000.0 / 7000.0))); } static void *dss_init() @@ -91,7 +89,7 @@ static void *dss_init() memset(dss, 0, sizeof(dss_t)); sound_add_handler(dss_get_buffer, dss); - timer_add(dss_callback, &dss->time, TIMER_ALWAYS_ENABLED, dss); + timer_add(&dss->timer, dss_callback, dss, 1); return dss; } diff --git a/src/mfm_at.c b/src/mfm_at.c index 1084229..e3ad873 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -70,7 +70,7 @@ typedef struct mfm_t uint16_t buffer[256]; int irqstat; - int callback; + pc_timer_t callback_timer; mfm_drive_t drives[2]; } mfm_t; @@ -215,18 +215,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p) // pclog("Restore\n"); mfm->command &= ~0x0f; /*Mask off step rate*/ mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME); break; case CMD_SEEK: // pclog("Seek to cylinder %i\n", mfm->cylinder); mfm->command &= ~0x0f; /*Mask off step rate*/ mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME); break; default: @@ -239,9 +235,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) if (val & 2) fatal("Read with ECC\n"); mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME); break; case CMD_WRITE: case CMD_WRITE+1: @@ -258,9 +252,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) // 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_clock(); - mfm->callback = 200 * IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); break; case CMD_FORMAT: @@ -271,24 +263,18 @@ void mfm_write(uint16_t port, uint8_t val, void *p) case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 30*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 30*IDE_TIME); break; case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME); break; default: pclog("Bad MFM command %02X\n", val); mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 200*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 200*IDE_TIME); break; } } @@ -297,9 +283,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) case 0x3F6: /* Device control */ if ((mfm->fdisk & 4) && !(val & 4)) { - timer_clock(); - mfm->callback = 500*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 500*IDE_TIME); mfm->reset = 1; mfm->status = STAT_BUSY; // pclog("MFM Reset\n"); @@ -307,9 +291,7 @@ void mfm_write(uint16_t port, uint8_t val, void *p) if (val & 4) { /*Drive held in reset*/ - timer_clock(); - mfm->callback = 0; - timer_update_outstanding(); + timer_disable(&mfm->callback_timer); mfm->status = STAT_BUSY; } mfm->fdisk = val; @@ -331,9 +313,7 @@ void mfm_writew(uint16_t port, uint16_t val, void *p) { mfm->pos = 0; mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 6*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME); } } @@ -402,9 +382,7 @@ uint16_t mfm_readw(uint16_t port, void *p) { mfm_next_sector(mfm); mfm->status = STAT_BUSY; - timer_clock(); - mfm->callback = 6*IDE_TIME; - timer_update_outstanding(); + timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME); } } } @@ -430,7 +408,7 @@ void mfm_callback(void *p) off64_t addr; // pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); - mfm->callback = 0; + if (mfm->reset) { mfm->status = STAT_READY | STAT_DSC; @@ -562,7 +540,7 @@ void *mfm_init() 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); + timer_add(&mfm->callback_timer, mfm_callback, mfm, 0); return mfm; } diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index 7c185f2..a60651e 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -51,7 +51,7 @@ typedef struct xebec_t { rom_t bios_rom; - int callback; + pc_timer_t callback_timer; int state; @@ -143,7 +143,7 @@ static uint8_t xebec_read(uint16_t port, void *p) // pclog("Read all data\n"); xebec->status = STAT_BSY; xebec->state = STATE_SENT_DATA; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); } break; @@ -190,7 +190,7 @@ static void xebec_write(uint16_t port, uint8_t val, void *p) { xebec->status = STAT_BSY; xebec->state = STATE_START_COMMAND; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); // pclog("Command %02x\n", xebec->command[0]); } break; @@ -207,7 +207,7 @@ static void xebec_write(uint16_t port, uint8_t val, void *p) // pclog("Got data\n"); xebec->status = STAT_BSY; xebec->state = STATE_RECEIVED_DATA; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); } break; @@ -314,13 +314,11 @@ 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: @@ -448,7 +446,7 @@ static void xebec_callback(void *p) readflash_set(READFLASH_HDC, xebec->drive_sel); } if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); else { xebec->status = STAT_BSY | STAT_IO | STAT_REQ; @@ -468,12 +466,12 @@ static void xebec_callback(void *p) { pclog("CMD_READ_SECTORS out of data!\n"); xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); return; } } xebec->state = STATE_SENT_DATA; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); } else fatal("Read sectors no DMA! - shouldn't get here\n"); @@ -505,7 +503,7 @@ static void xebec_callback(void *p) xebec->state = STATE_SEND_DATA; if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); else { xebec->status = STAT_BSY | STAT_IO | STAT_REQ; @@ -535,7 +533,7 @@ static void xebec_callback(void *p) xebec->data_pos = 0; xebec->data_len = 512; if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); else xebec->status = STAT_BSY | STAT_REQ; break; @@ -552,7 +550,7 @@ static void xebec_callback(void *p) { pclog("CMD_WRITE_SECTORS out of data!\n"); xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); return; } @@ -560,7 +558,7 @@ static void xebec_callback(void *p) } xebec->state = STATE_RECEIVED_DATA; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); } else fatal("Write sectors no DMA! - should never get here\n"); @@ -595,7 +593,7 @@ static void xebec_callback(void *p) { xebec->state = STATE_RECEIVE_DATA; if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); else xebec->status = STAT_BSY | STAT_REQ; } @@ -653,7 +651,7 @@ static void xebec_callback(void *p) xebec->data_pos = 0; xebec->data_len = 512; if (xebec->irq_dma_mask & DMA_ENA) - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); else xebec->status = STAT_BSY | STAT_REQ; break; @@ -671,7 +669,7 @@ static void xebec_callback(void *p) { pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n"); xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); return; } @@ -679,7 +677,7 @@ static void xebec_callback(void *p) } xebec->state = STATE_RECEIVED_DATA; - xebec->callback = XEBEC_TIME; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); } else fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); @@ -829,7 +827,7 @@ static void *xebec_init() io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); - timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec); + timer_add(&xebec->callback_timer, xebec_callback, xebec, 0); return xebec; } @@ -880,7 +878,7 @@ static void *dtc_5150x_init() io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); - timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec); + timer_add(&xebec->callback_timer, xebec_callback, xebec, 0); return xebec; } diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 9964153..b8bd187 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -7,7 +7,8 @@ typedef struct mouse_serial_t { - int mousepos, mousedelay; + int mousepos; + pc_timer_t mousedelay_timer; int oldb; SERIAL *serial; } mouse_serial_t; @@ -52,14 +53,13 @@ void mouse_serial_rcr(struct SERIAL *serial, void *p) mouse_serial_t *mouse = (mouse_serial_t *)p; mouse->mousepos = -1; - mouse->mousedelay = 5000 * (1 << TIMER_SHIFT); + timer_set_delay_u64(&mouse->mousedelay_timer, TIMER_USEC * 5000); } void mousecallback(void *p) { mouse_serial_t *mouse = (mouse_serial_t *)p; - mouse->mousedelay = 0; if (mouse->mousepos == -1) { mouse->mousepos = 0; @@ -75,7 +75,7 @@ void *mouse_serial_init() mouse->serial = &serial1; serial1.rcr_callback = mouse_serial_rcr; serial1.rcr_callback_p = mouse; - timer_add(mousecallback, &mouse->mousedelay, &mouse->mousedelay, mouse); + timer_add(&mouse->mousedelay_timer, mousecallback, mouse, 0); return mouse; } diff --git a/src/nethandler.c b/src/nethandler.c index dec5c8a..f06ef46 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -91,7 +91,7 @@ static struct static int vlan_handlers_num; -static int vlan_poller_time = 0; +static pc_timer_t vlan_poller_timer; 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) @@ -106,7 +106,7 @@ void vlan_poller(void *priv) { int c; - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0)); + timer_advance_u64(&vlan_poller_timer, (uint64_t)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0))); for (c = 0; c < vlan_handlers_num; c++) vlan_handlers[c].poller(vlan_handlers[c].priv); @@ -114,7 +114,7 @@ void vlan_poller(void *priv) void vlan_reset() { - timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&vlan_poller_timer, vlan_poller, NULL, 1); vlan_handlers_num = 0; } diff --git a/src/nvr.c b/src/nvr.c index 32510aa..fa8c1f4 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -19,9 +19,10 @@ int nvraddr; int nvr_dosave = 0; -static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; +static pc_timer_t nvr_onesec_timer; +static int nvr_onesec_cnt = 0; -static int rtctime; +static pc_timer_t rtc_timer; FILE *nvrfopen(char *fn, char *mode) { @@ -62,10 +63,9 @@ void getnvrtime() void nvr_recalc() { int c; - int newrtctime; + c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - newrtctime=(int)(RTCCONST * c * (1 << TIMER_SHIFT)); - if (rtctime>newrtctime) rtctime=newrtctime; + timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); } void nvr_rtc(void *p) @@ -73,11 +73,11 @@ void nvr_rtc(void *p) int c; if (!(nvrram[RTC_REGA] & RTC_RS)) { - rtctime=0x7fffffff; + timer_disable(&rtc_timer); return; } c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); + timer_advance_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); // pclog("RTCtime now %f\n",rtctime); nvrram[RTC_REGC] |= RTC_PF; if (nvrram[RTC_REGB] & RTC_PIE) @@ -98,7 +98,7 @@ int nvr_check_alarm(int nvraddr) return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE); } -int nvr_update_end_count = 0; +pc_timer_t nvr_update_end_timer; void nvr_update_end(void *p) { @@ -130,8 +130,6 @@ void nvr_update_end(void *p) } // pclog("RTC onesec\n"); - - nvr_update_end_count = 0; } void nvr_onesec(void *p) @@ -144,11 +142,11 @@ void nvr_onesec(void *p) nvr_update_status = RTC_UIP; rtc_tick(); - nvr_update_end_count = (int)((244.0 + 1984.0) * TIMER_USEC); + timer_set_delay_u64(&nvr_update_end_timer, (uint64_t)((244.0 + 1984.0) * TIMER_USEC)); } nvr_onesec_cnt = 0; } - nvr_onesec_time += (int)(10000 * TIMER_USEC); + timer_advance_u64(&nvr_onesec_timer, (uint64_t)(10000 * TIMER_USEC)); } void writenvr(uint16_t addr, uint8_t val, void *priv) @@ -174,10 +172,10 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) if (val & RTC_RS) { c = 1 << ((val & RTC_RS) - 1); - rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); + timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); } else - rtctime = 0x7fffffff; + timer_disable(&rtc_timer); } else { @@ -333,7 +331,7 @@ void loadnvr() nvrram[RTC_REGA] = 6; nvrram[RTC_REGB] = RTC_2412; c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); + timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); } void savenvr() { @@ -408,8 +406,8 @@ void savenvr() void nvr_init() { io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL); - timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL); - timer_add(nvr_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL); - timer_add(nvr_update_end, &nvr_update_end_count, &nvr_update_end_count, NULL); + timer_add(&rtc_timer, nvr_rtc, NULL, 1); + timer_add(&nvr_onesec_timer, nvr_onesec, NULL, 1); + timer_add(&nvr_update_end_timer, nvr_update_end, NULL, 0); } diff --git a/src/nvr_tc8521.c b/src/nvr_tc8521.c index f221c00..6396d30 100644 --- a/src/nvr_tc8521.c +++ b/src/nvr_tc8521.c @@ -11,7 +11,8 @@ #include "config.h" #include "nmi.h" -static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; +static pc_timer_t nvr_onesec_timer; +static int nvr_onesec_cnt = 0; static void tc8521_onesec(void *p) { @@ -21,7 +22,7 @@ static void tc8521_onesec(void *p) tc8521_tick(); nvr_onesec_cnt = 0; } - nvr_onesec_time += (int)(10000 * TIMER_USEC); + timer_advance_u64(&nvr_onesec_timer, 10000 * TIMER_USEC); } void write_tc8521(uint16_t addr, uint8_t val, void *priv) @@ -96,5 +97,5 @@ void tc8521_savenvr() void nvr_tc8521_init() { io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL); - timer_add(tc8521_onesec, &nvr_onesec_time, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&nvr_onesec_timer, tc8521_onesec, NULL, 1); } diff --git a/src/pit.c b/src/pit.c index dd27729..11a9829 100644 --- a/src/pit.c +++ b/src/pit.c @@ -21,7 +21,12 @@ //Tyrian writes 4300 or 17512 int displine; -double PITCONST; +uint64_t PITCONST; +uint64_t CGACONST; +uint64_t MDACONST; +uint64_t VGACONST1, VGACONST2; +uint64_t RTCCONST; + float cpuclock; float isa_timing, bus_timing; @@ -30,23 +35,23 @@ void setpitclock(float clock) { // printf("PIT clock %f\n",clock); cpuclock=clock; - PITCONST=clock/1193182.0; - CGACONST=(clock/(19687503.0/11.0)); - MDACONST=(clock/2032125.0); - VGACONST1=(clock/25175000.0); - VGACONST2=(clock/28322000.0); + PITCONST = (uint64_t)(clock / 1193182.0 * (float)(1ull << 32)); + CGACONST = (uint64_t)((clock / (19687503.0/11.0)) * (float)(1ull << 32)); + MDACONST = (uint64_t)((clock / 2032125.0) * (float)(1ull << 32)); + VGACONST1 = (uint64_t)((clock / 25175000.0) * (float)(1ull << 32)); + VGACONST2 = (uint64_t)((clock / 28322000.0) * (float)(1ull << 32)); 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)cpu_get_speed()); + xt_cpu_multi = (uint64_t)((14318184.0*(double)(1ull << 32)) / (double)cpu_get_speed()); // 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)); + RTCCONST = (uint64_t)((clock / 32768.0) * (float)(1ull << 32)); + TIMER_USEC = (uint64_t)((clock / 1000000.0) * (float)(1ull << 32)); device_speed_changed(); } @@ -55,9 +60,9 @@ void setpitclock(float clock) 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->l[0] = 0xFFFF; + pit->l[1] = 0xFFFF; + pit->l[2] = 0xFFFF; pit->m[0] = pit->m[1] = pit->m[2] = 0; pit->ctrls[0] = pit->ctrls[1] = pit->ctrls[2] = 0; pit->thit[0]=1; @@ -66,11 +71,6 @@ void pit_reset(PIT *pit) pit->using_timer[0] = pit->using_timer[1] = pit->using_timer[2] = 1; } -void clearpit() -{ - pit.c[0]=(pit.l[0]<<2); -} - float pit_timer0_freq() { if (pit.l[0]) @@ -85,18 +85,52 @@ static void pit_set_out(PIT *pit, int t, int out) pit->out[t] = out; } +static int pit_read_timer(PIT *pit, int t) +{ +// pclog("pit_read_timer: t=%i using_timer=%i m=%i enabled=%i\n", t, pit->using_timer[t], pit->m[t], timer_is_enabled(&pit->timer[t])); + if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t]) && timer_is_enabled(&pit->timer[t])) + { + int read = (int)((timer_get_remaining_u64(&pit->timer[t])) / PITCONST); +// pclog(" read %i %08x %016llx\n", t, read, timer_get_remaining_u64(&pit->timer[t])); + if (pit->m[t] == 2) + read++; + if (read < 0) + read = 0; + if (read > 0x10000) + read = 0x10000; + if (pit->m[t] == 3) + read <<= 1; + return read; + } + if (pit->m[t] == 2) + return pit->count[t] + 1; + return pit->count[t]; +} + +/*Dump timer count back to pit->count[], and disable timer. This should be used + when stopping a PIT timer, to ensure the correct value can be read back.*/ +static void pit_dump_and_disable_timer(PIT *pit, int t) +{ + if (pit->using_timer[t] && timer_is_enabled(&pit->timer[t])) + { + pit->count[t] = pit_read_timer(pit, t); + timer_disable(&pit->timer[t]); + } +} + static void pit_load(PIT *pit, int t) { int l = pit->l[t] ? pit->l[t] : 0x10000; - timer_clock(); + pit->newcount[t] = 0; pit->disabled[t] = 0; -// pclog("pit_load: t=%i l=%x\n", t, l); +// pclog("pit_load: t=%i l=%x m=%i %016llx\n", t, l, pit->m[t], PITCONST); switch (pit->m[t]) { case 0: /*Interrupt on terminal count*/ pit->count[t] = l; - pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); pit_set_out(pit, t, 0); pit->thit[t] = 0; pit->enabled[t] = pit->gate[t]; @@ -108,7 +142,8 @@ static void pit_load(PIT *pit, int t) if (pit->initial[t]) { pit->count[t] = l - 1; - pit->c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)((l - 1) * PITCONST)); pit_set_out(pit, t, 1); pit->thit[t] = 0; } @@ -118,12 +153,13 @@ static void pit_load(PIT *pit, int t) if (pit->initial[t]) { pit->count[t] = l; - pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * 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]); +// pclog("pit_load: square wave mode c=%x\n", ); break; case 4: /*Software triggered stobe*/ if (!pit->thit[t] && !pit->initial[t]) @@ -131,7 +167,8 @@ static void pit_load(PIT *pit, int t) else { pit->count[t] = l; - pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); pit_set_out(pit, t, 0); pit->thit[t] = 0; } @@ -143,7 +180,9 @@ static void pit_load(PIT *pit, int t) } pit->initial[t] = 0; pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; - timer_update_outstanding(); + if (pit->using_timer[t] && !pit->running[t]) + pit_dump_and_disable_timer(pit, t); + // 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]); } @@ -161,6 +200,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate) { case 0: /*Interrupt on terminal count*/ case 4: /*Software triggered stobe*/ + if (pit->using_timer[t] && !pit->running[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); pit->enabled[t] = gate; break; case 1: /*Hardware retriggerable one-shot*/ @@ -168,7 +209,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate) if (gate && !pit->gate[t]) { pit->count[t] = l; - pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); pit_set_out(pit, t, 0); pit->thit[t] = 0; pit->enabled[t] = 1; @@ -178,7 +220,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate) if (gate && !pit->gate[t]) { pit->count[t] = l - 1; - pit->c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); pit_set_out(pit, t, 1); pit->thit[t] = 0; } @@ -188,7 +231,8 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate) if (gate && !pit->gate[t]) { pit->count[t] = l; - pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST)); pit_set_out(pit, t, 1); pit->thit[t] = 0; } @@ -197,23 +241,21 @@ void pit_set_gate_no_timer(PIT *pit, int t, int gate) } pit->gate[t] = gate; pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; + if (pit->using_timer[t] && !pit->running[t]) + pit_dump_and_disable_timer(pit, t); // pclog("pit_set_gate: t=%i gate=%i\n", t, gate); } void pit_set_gate(PIT *pit, int t, int gate) { +// pclog("pit_set_gate: t=%i gate=%i\n", t, gate); if (pit->disabled[t]) { pit->gate[t] = gate; return; } - timer_process(); - pit_set_gate_no_timer(pit, t, gate); - - timer_update_outstanding(); -// pclog("pit_set_gate: t=%i gate=%i\n", t, gate); } static void pit_over(PIT *pit, int t) @@ -222,11 +264,12 @@ static void pit_over(PIT *pit, int t) if (pit->disabled[t]) { pit->count[t] += 0xffff; - pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); 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]); +// if (t == 2) pclog("pit_over: t=%i l=%x c=%llx hit=%i %016llx\n", t, pit->l[t], timer_get_remaining_u64(&pit->timer[t]), pit->thit[t], tsc); switch (pit->m[t]) { case 0: /*Interrupt on terminal count*/ @@ -235,11 +278,13 @@ static void pit_over(PIT *pit, int t) pit_set_out(pit, t, 1); pit->thit[t] = 1; pit->count[t] += 0xffff; - pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); break; case 2: /*Rate generator*/ pit->count[t] += l; - pit->c[t] += (int)((l << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); pit_set_out(pit, t, 0); pit_set_out(pit, t, 1); break; @@ -248,13 +293,15 @@ static void pit_over(PIT *pit, int t) { pit_set_out(pit, t, 0); pit->count[t] += (l >> 1); - pit->c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)((l >> 1) * PITCONST)); } else { pit_set_out(pit, t, 1); pit->count[t] += ((l + 1) >> 1); - pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST)); } // if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); break; @@ -268,13 +315,15 @@ static void pit_over(PIT *pit, int t) { pit->newcount[t] = 0; pit->count[t] += l; - pit->c[t] += (int)((l << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); } else { pit->thit[t] = 1; pit->count[t] += 0xffff; - pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); } break; case 5: /*Hardware triggered strove*/ @@ -285,54 +334,20 @@ static void pit_over(PIT *pit, int t) } pit->thit[t] = 1; pit->count[t] += 0xffff; - pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); break; } 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) - read = 0; - if (read > 0x10000) - read = 0x10000; - if (pit.m[0] == 3) - read <<= 1; - return read; -} - -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] && !(pit->m[t] == 3 && !pit->gate[t])) - { - 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) - read <<= 1; - return read; - } - if (pit->m[t] == 2) - return pit->count[t] + 1; - return pit->count[t]; + if (pit->using_timer[t] && !pit->running[t]) + pit_dump_and_disable_timer(pit, t); } void pit_write(uint16_t addr, uint8_t val, void *p) { PIT *pit = (PIT *)p; int t; -// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit->gate[0]); +// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,cpu_state.pc,ins, pit->gate[0]); switch (addr&3) { @@ -456,7 +471,7 @@ uint8_t pit_read(uint16_t addr, void *p) PIT *pit = (PIT *)p; int t; uint8_t temp = 0xff; -// printf("Read PIT %04X ",addr); +// printf("Read PIT %04X\n",addr); switch (addr&3) { case 0: case 1: case 2: /*Timers*/ @@ -537,11 +552,12 @@ void pit_set_using_timer(PIT *pit, int t, int using_timer) timer_process(); 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->running[t] = pit->enabled[t] && using_timer && !pit->disabled[t]; + if (!pit->using_timer[t] && using_timer && pit->running[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(pit->count[t] * PITCONST)); + else if (!pit->running[t]) + timer_disable(&pit->timer[t]); 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(PIT *pit, int t, void (*func)(int new_out, int old_out)) @@ -633,9 +649,9 @@ void pit_init() 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 *)&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]); + timer_add(&pit.timer[0], pit_timer_over, (void *)&pit.pit_nr[0], 0); + timer_add(&pit.timer[1], pit_timer_over, (void *)&pit.pit_nr[1], 0); + timer_add(&pit.timer[2], pit_timer_over, (void *)&pit.pit_nr[2], 0); pit_set_out_func(&pit, 0, pit_irq0_timer); pit_set_out_func(&pit, 1, pit_null_timer); @@ -656,7 +672,7 @@ void pit_ps2_init() 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]); + timer_add(&pit2.timer[0], pit_timer_over, (void *)&pit2.pit_nr[0], 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 2bed738..b314a93 100644 --- a/src/pit.h +++ b/src/pit.h @@ -1,4 +1,4 @@ -extern double PITCONST; +extern uint64_t PITCONST; void pit_init(); void pit_ps2_init(); void pit_reset(); diff --git a/src/scsi_53c400.c b/src/scsi_53c400.c index ffc3a59..03629eb 100644 --- a/src/scsi_53c400.c +++ b/src/scsi_53c400.c @@ -8,9 +8,8 @@ #include "scsi_53c400.h" #include "timer.h" -#define POLL_TIME_US 10 +#define POLL_TIME_US 1 #define MAX_BYTES_TRANSFERRED_PER_POLL 50 -/*10us poll period with 50 bytes transferred per poll = 5MB/sec*/ typedef struct ncr5380_t { @@ -57,8 +56,7 @@ typedef struct lcs6821n_t int ncr5380_dma_enabled; - int dma_callback; - int dma_enabled; + pc_timer_t dma_timer; int ncr_busy; } lcs6821n_t; @@ -96,13 +94,24 @@ enum DMA_INITIATOR_RECEIVE }; +static void set_dma_enable(lcs6821n_t *scsi, int enable) +{ + if (enable) + { + if (!timer_is_enabled(&scsi->dma_timer)) + timer_set_delay_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US); + } + else + timer_disable(&scsi->dma_timer); +} + static void ncr53c400_dma_changed(ncr5380_t *ncr, int mode, int enable) { lcs6821n_t *scsi = (lcs6821n_t *)ncr->p; scsi->ncr5380_dma_enabled = (mode && enable); - scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded); + set_dma_enable(scsi, scsi->ncr5380_dma_enabled && scsi->block_count_loaded); } void ncr5380_reset(ncr5380_t *ncr) @@ -424,7 +433,7 @@ static void lcs6821n_write(uint32_t addr, uint8_t val, void *p) case 0x3981: /*Block counter register*/ scsi->block_count = val; scsi->block_count_loaded = 1; - scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded); + set_dma_enable(scsi, scsi->ncr5380_dma_enabled && scsi->block_count_loaded); if (scsi->status_ctrl & CTRL_DATA_DIR) { scsi->buffer_host_pos = 128; @@ -533,7 +542,7 @@ static void ncr53c400_dma_callback(void *p) int bytes_transferred = 0; //pclog("dma_Callback poll\n"); - scsi->dma_callback += POLL_TIME_US; + timer_advance_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US); switch (scsi->ncr.dma_mode) { @@ -600,7 +609,7 @@ static void ncr53c400_dma_callback(void *p) if (!scsi->block_count) { scsi->block_count_loaded = 0; - scsi->dma_enabled = 0; + set_dma_enable(scsi, 0); // scsi->buffer_host_pos = 128; // scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -665,7 +674,7 @@ static void ncr53c400_dma_callback(void *p) if (!scsi->block_count) { scsi->block_count_loaded = 0; - scsi->dma_enabled = 0; + set_dma_enable(scsi, 0); // output=3; ncr->isr |= STATUS_END_OF_DMA; @@ -717,7 +726,7 @@ static void *scsi_53c400_init(char *bios_fn) scsi_bus_init(&scsi->ncr.bus); - timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi); + timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0); return scsi; } @@ -757,7 +766,7 @@ static void *scsi_t130b_init(char *bios_fn) scsi_bus_init(&scsi->ncr.bus); - timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi); + timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0); return scsi; } diff --git a/src/scsi_aha1540.c b/src/scsi_aha1540.c index 9174ffc..f3bb9b6 100644 --- a/src/scsi_aha1540.c +++ b/src/scsi_aha1540.c @@ -126,7 +126,7 @@ typedef struct aha154x_t int bios_cmd_state; - int timer; + pc_timer_t timer; int current_mbo; int current_mbo_is_bios; @@ -2165,7 +2165,7 @@ static void aha154x_callback(void *p) { aha154x_t *scsi = (aha154x_t *)p; - scsi->timer += TIMER_USEC * POLL_TIME_US; + timer_advance_u64(&scsi->timer, TIMER_USEC * POLL_TIME_US); // pclog("poll %i\n", scsi->cmd_state); process_cmd(scsi); @@ -2253,7 +2253,7 @@ static void *scsi_aha1542c_init(char *bios_fn) scsi->ccb_state = CCB_STATE_IDLE; scsi->scsi_state = SCSI_STATE_IDLE; - timer_add(aha154x_callback, &scsi->timer, TIMER_ALWAYS_ENABLED, scsi); + timer_add(&scsi->timer, aha154x_callback, scsi, 1); addr = device_get_config_int("addr"); io_sethandler(addr, 0x0004, @@ -2298,7 +2298,7 @@ static void *scsi_bt545s_init(char *bios_fn) scsi->ccb_state = CCB_STATE_IDLE; scsi->scsi_state = SCSI_STATE_IDLE; - timer_add(aha154x_callback, &scsi->timer, TIMER_ALWAYS_ENABLED, scsi); + timer_add(&scsi->timer, aha154x_callback, scsi, 1); addr = device_get_config_int("addr"); io_sethandler(addr, 0x0004, diff --git a/src/scsi_cd.c b/src/scsi_cd.c index de2363e..5abe1f3 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -164,7 +164,7 @@ typedef struct scsi_cd_data_t int blocks; int cmd_pos, new_cmd_pos; - int callback; + pc_timer_t callback_timer; int wait_time; scsi_bus_t *bus; @@ -269,21 +269,18 @@ void cd_set_speed(int speed) static void scsi_cd_callback(void *p) { scsi_cd_data_t *data = p; - + if (data->cmd_pos == CMD_POS_WAIT) { data->wait_time--; if (!data->wait_time) { - data->callback = 0; data->cmd_pos = data->new_cmd_pos; scsi_bus_kick(data->bus); } else - data->callback = 1000 * TIMER_USEC; + timer_advance_u64(&data->callback_timer, 1000 * TIMER_USEC); } - else - data->callback = 0; } //#define SECTOR_TIME 13333 /*Time between sectors on 1x drive*/ @@ -397,7 +394,7 @@ static void *scsi_cd_init(scsi_bus_t *bus, int id) memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; - timer_add(scsi_cd_callback, &data->callback, &data->callback, data); + timer_add(&data->callback_timer, scsi_cd_callback, data, 0); cd_data = data; cd_set_speed(cd_speed); @@ -697,7 +694,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_COMPLETE; data->wait_time = seek_time; - data->callback = 1000 * TIMER_USEC; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); return SCSI_PHASE_COMMAND; } } @@ -761,7 +758,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_COMPLETE; data->wait_time = seek_time; - data->callback = 1000 * TIMER_USEC; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); return SCSI_PHASE_COMMAND; } } @@ -862,7 +859,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_START_SECTOR; data->wait_time = seek_time; - data->callback = 1000 * TIMER_USEC; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); return SCSI_PHASE_COMMAND; } } @@ -875,23 +872,21 @@ static int scsi_cd_command(uint8_t *cdb, void *p) } if (data->cmd_pos == CMD_POS_START_SECTOR) { - uint64_t time = (((uint64_t)SECTOR_TIME * (uint64_t)TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; + uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_TRANSFER; - - if (time > 0x7fffffffull) + + if (time > (TIMER_USEC * 1000ull)) { - data->wait_time = (int)(time / ((uint64_t)TIMER_USEC * 1000ull)); - data->callback = (int)(time % ((uint64_t)TIMER_USEC * 1000ull));; + data->wait_time = (int)(time / (TIMER_USEC * 1000ull)); + timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull)); } else { - data->callback = time; + timer_set_delay_u64(&data->callback_timer, time); data->wait_time = 1; } - if (data->callback == 0) - data->callback = 1; return SCSI_PHASE_COMMAND; } @@ -969,7 +964,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_START_SECTOR; data->wait_time = seek_time; - data->callback = 1000 * TIMER_USEC; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); return SCSI_PHASE_COMMAND; } } @@ -982,23 +977,21 @@ static int scsi_cd_command(uint8_t *cdb, void *p) } if (data->cmd_pos == CMD_POS_START_SECTOR) { - uint64_t time = (((uint64_t)SECTOR_TIME * (uint64_t)TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; + uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_TRANSFER; - if (time > 0x7fffffffull) + if (time > (TIMER_USEC * 1000ull)) { - data->wait_time = (int)(time / ((uint64_t)TIMER_USEC * 1000ull)); - data->callback = (int)(time % ((uint64_t)TIMER_USEC * 1000ull));; + data->wait_time = (int)(time / (TIMER_USEC * 1000ull)); + timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull)); } else { - data->callback = time; + timer_set_delay_u64(&data->callback_timer, time); data->wait_time = 1; } - if (data->callback == 0) - data->callback = 1; return SCSI_PHASE_COMMAND; } @@ -1372,7 +1365,7 @@ atapi_out: data->cmd_pos = CMD_POS_WAIT; data->new_cmd_pos = CMD_POS_COMPLETE; data->wait_time = seek_time; - data->callback = 1000 * TIMER_USEC; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); return SCSI_PHASE_COMMAND; } } diff --git a/src/scsi_hd.c b/src/scsi_hd.c index f314ebf..074bdba 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -47,7 +47,7 @@ typedef struct scsi_hd_data int hd_id; - int callback; + pc_timer_t callback_timer; scsi_bus_t *bus; } scsi_hd_data; @@ -56,8 +56,6 @@ static void scsi_hd_callback(void *p) { scsi_hd_data *data = p; - data->callback = 0; - if (data->cmd_pos == CMD_POS_WAIT) { data->cmd_pos = data->new_cmd_pos; @@ -80,7 +78,7 @@ static void *scsi_hd_init(scsi_bus_t *bus, int id) data->hd_id = id; data->bus = bus; - timer_add(scsi_hd_callback, &data->callback, &data->callback, data); + timer_add(&data->callback_timer, scsi_hd_callback, data, 0); return data; } @@ -464,7 +462,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p) // pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_START_SECTOR; data->sector_pos = 0; @@ -524,7 +522,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p) // pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_START_SECTOR; data->sector_pos = 0; @@ -585,7 +583,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p) data->bytes_required = data->len * 512; data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_TRANSFER; data->sector_pos = 0; @@ -644,7 +642,7 @@ static int scsi_hd_command(uint8_t *cdb, void *p) data->bytes_required = data->len * 512; data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_TRANSFER; data->sector_pos = 0; diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 91956e2..8f81700 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -68,7 +68,7 @@ typedef struct scsi_zip_data int hd_id; - int callback; + pc_timer_t callback_timer; scsi_bus_t *bus; @@ -176,8 +176,6 @@ static void scsi_zip_callback(void *p) { scsi_zip_data *data = p; - data->callback = 0; - if (data->cmd_pos == CMD_POS_WAIT) { data->cmd_pos = data->new_cmd_pos; @@ -194,7 +192,7 @@ static void *scsi_zip_init(scsi_bus_t *bus, int id) data->hd_id = id; data->bus = bus; - timer_add(scsi_zip_callback, &data->callback, &data->callback, data); + timer_add(&data->callback_timer, scsi_zip_callback, data, 0); zip_data = data; return data; @@ -689,7 +687,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) // pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_START_SECTOR; data->sector_pos = 0; @@ -750,7 +748,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) // pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_START_SECTOR; data->sector_pos = 0; @@ -819,7 +817,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->bytes_required = data->len * 512; data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_TRANSFER; data->sector_pos = 0; @@ -887,7 +885,7 @@ static int scsi_zip_command(uint8_t *cdb, void *p) data->bytes_required = data->len * 512; data->cmd_pos = CMD_POS_WAIT; - data->callback = RW_DELAY; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); data->new_cmd_pos = CMD_POS_TRANSFER; data->sector_pos = 0; diff --git a/src/serial.c b/src/serial.c index f638e22..2866f7c 100644 --- a/src/serial.c +++ b/src/serial.c @@ -35,7 +35,7 @@ void serial_update_ints(SERIAL *serial) stat = 1; serial->iir = 6; } - else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ + else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Received data available*/ { stat = 1; serial->iir = 4; @@ -185,7 +185,7 @@ uint8_t serial_read(uint16_t addr, void *p) serial_update_ints(serial); temp = serial_read_fifo(serial); if (serial->fifo_read != serial->fifo_write) - serial->recieve_delay = 1000 * TIMER_USEC; + timer_set_delay_u64(&serial->receive_timer, 1000 * TIMER_USEC); break; case 1: if (serial->lcr & 0x80) @@ -234,12 +234,10 @@ uint8_t serial_read(uint16_t addr, void *p) return temp; } -void serial_recieve_callback(void *p) +void serial_receive_callback(void *p) { SERIAL *serial = (SERIAL *)p; - serial->recieve_delay = 0; - if (serial->fifo_read != serial->fifo_write) { serial->lsr |= 1; @@ -256,7 +254,7 @@ void serial1_init(uint16_t addr, int irq) serial1.irq = irq; serial1.addr = addr; serial1.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); + timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0); } void serial1_set(uint16_t addr, int irq) { @@ -277,7 +275,7 @@ void serial2_init(uint16_t addr, int irq) serial2.irq = irq; serial2.addr = addr; serial2.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + timer_add(&serial2.receive_timer, serial_receive_callback, &serial2, 0); } void serial2_set(uint16_t addr, int irq) { diff --git a/src/serial.h b/src/serial.h index 930292a..453acbf 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,3 +1,5 @@ +#include "timer.h" + void serial1_init(uint16_t addr, int irq); void serial2_init(uint16_t addr, int irq); void serial1_set(uint16_t addr, int irq); @@ -25,7 +27,7 @@ typedef struct uint8_t fifo[256]; int fifo_read, fifo_write; - int recieve_delay; + pc_timer_t receive_timer; } SERIAL; void serial_write_fifo(SERIAL *serial, uint8_t dat); diff --git a/src/sound.c b/src/sound.c index cb5820d..a5e7320 100644 --- a/src/sound.c +++ b/src/sound.c @@ -114,7 +114,8 @@ static struct static int sound_handlers_num; -static int sound_poll_time = 0, sound_poll_latch; +static pc_timer_t sound_poll_timer; +static uint64_t sound_poll_latch; int sound_pos_global = 0; int soundon = 1; @@ -226,7 +227,7 @@ void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), vo static int cd_pos = 0; void sound_poll(void *priv) { - sound_poll_time += sound_poll_latch; + timer_advance_u64(&sound_poll_timer, sound_poll_latch); cd_pos++; if (cd_pos == (CD_BUFLEN * 48000) / CD_FREQ) @@ -269,12 +270,12 @@ void sound_poll(void *priv) void sound_speed_changed() { - sound_poll_latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); + sound_poll_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); } void sound_reset() { - timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL); + timer_add(&sound_poll_timer, sound_poll, NULL, 1); sound_handlers_num = 0; diff --git a/src/sound_ad1848.c b/src/sound_ad1848.c index 1e9f99a..abbbc96 100644 --- a/src/sound_ad1848.c +++ b/src/sound_ad1848.c @@ -71,9 +71,19 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p) break; case 9: + if (!ad1848->enable && (val & 0x41) == 0x01) + { + if (ad1848->timer_latch) + timer_advance_u64(&ad1848->timer, ad1848->timer_latch); + else + timer_advance_u64(&ad1848->timer, TIMER_USEC); + } ad1848->enable = ((val & 0x41) == 0x01); if (!ad1848->enable) + { + timer_disable(&ad1848->timer); ad1848->out_l = ad1848->out_r = 0; + } break; case 12: @@ -93,7 +103,7 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p) void ad1848_speed_changed(ad1848_t *ad1848) { - ad1848->timer_latch = (int)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); + ad1848->timer_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); } void ad1848_update(ad1848_t *ad1848) @@ -110,9 +120,9 @@ static void ad1848_poll(void *p) ad1848_t *ad1848 = (ad1848_t *)p; if (ad1848->timer_latch) - ad1848->timer_count += ad1848->timer_latch; + timer_advance_u64(&ad1848->timer, ad1848->timer_latch); else - ad1848->timer_count = TIMER_USEC; + timer_advance_u64(&ad1848->timer, TIMER_USEC); ad1848_update(ad1848); @@ -214,5 +224,5 @@ void ad1848_init(ad1848_t *ad1848) // pclog("ad1848_vols %i = %f %i\n", c, attenuation, ad1848_vols[c]); } - timer_add(ad1848_poll, &ad1848->timer_count, &ad1848->enable, ad1848); + timer_add(&ad1848->timer, ad1848_poll, ad1848, 0); } diff --git a/src/sound_ad1848.h b/src/sound_ad1848.h index 34b707a..a0c436d 100644 --- a/src/sound_ad1848.h +++ b/src/sound_ad1848.h @@ -19,7 +19,8 @@ typedef struct ad1848_t int freq; - int timer_count, timer_latch; + pc_timer_t timer; + uint64_t timer_latch; int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index 507751c..a8ce40b 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -36,7 +36,7 @@ typedef struct adgold_t int16_t adgold_mma_out[2]; int adgold_mma_intpos[2]; - int adgold_mma_timer_count; + pc_timer_t adgold_mma_timer; struct { @@ -586,9 +586,10 @@ void adgold_timer_poll(void *p) { adgold_t *adgold = (adgold_t *)p; - while (adgold->adgold_mma_timer_count <= 0) - { - adgold->adgold_mma_timer_count += (int)((double)TIMER_USEC * 1.88964); + timer_advance_u64(&adgold->adgold_mma_timer, (uint64_t)((double)TIMER_USEC * 1.88964)); +// while (adgold->adgold_mma_timer_count <= 0) +// { +// adgold->adgold_mma_timer_count += (int)((double)TIMER_USEC * 1.88964); if (adgold->adgold_mma_regs[0][8] & 0x01) /*Timer 0*/ { adgold->adgold_mma.timer0_count--; @@ -649,7 +650,7 @@ void adgold_timer_poll(void *p) adgold_mma_poll(adgold, 1); } } - } +// } } static void adgold_get_buffer(int32_t *buffer, int len, void *p) @@ -817,7 +818,7 @@ void *adgold_init() /*388/389 are handled by adlib_init*/ io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); - timer_add(adgold_timer_poll, &adgold->adgold_mma_timer_count, TIMER_ALWAYS_ENABLED, adgold); + timer_add(&adgold->adgold_mma_timer, adgold_timer_poll, adgold, 1); sound_add_handler(adgold_get_buffer, adgold); diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index 61e1b33..e9d4ef7 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -49,7 +49,8 @@ typedef struct es1371_t uint16_t samp_ct, curr_samp_ct; - int time, latch; + pc_timer_t timer; + uint64_t latch; uint32_t vf, ac; @@ -1077,7 +1078,7 @@ static void es1371_poll(void *p) { es1371_t *es1371 = (es1371_t *)p; - es1371->dac[1].time += es1371->dac[1].latch; + timer_advance_u64(&es1371->dac[1].timer, es1371->dac[1].latch); es1371_update(es1371); @@ -1205,7 +1206,7 @@ static void *es1371_init() es1371->card = pci_add(es1371_pci_read, es1371_pci_write, es1371); - timer_add(es1371_poll, &es1371->dac[1].time, TIMER_ALWAYS_ENABLED, es1371); + timer_add(&es1371->dac[1].timer, es1371_poll, es1371, 1); generate_es1371_filter(); diff --git a/src/sound_gus.c b/src/sound_gus.c index 08b3e5d..20df0c3 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -42,13 +42,14 @@ typedef struct gus_t int16_t buffer[2][MAXSOUNDBUFLEN]; int pos; - int samp_timer, samp_latch; + pc_timer_t samp_timer; + uint64_t samp_latch; uint8_t *ram; int irqnext; - int timer_1, timer_2; + pc_timer_t timer_1, timer_2; int irq, dma, irq_midi; int latch_enable; @@ -365,9 +366,9 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); gus->global=val; // printf("GUS voices %i\n",val&31); if (gus->voices < 14) - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); else - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); break; case 0x41: /*DMA*/ @@ -824,7 +825,7 @@ void gus_poll_timer_1(void *p) { gus_t *gus = (gus_t *)p; - gus->timer_1 += (TIMER_USEC * 80); + timer_advance_u64(&gus->timer_1, (uint64_t)(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) { @@ -859,7 +860,7 @@ void gus_poll_timer_2(void *p) { gus_t *gus = (gus_t *)p; - gus->timer_2 += (TIMER_USEC * 320); + timer_advance_u64(&gus->timer_2, (uint64_t)(TIMER_USEC * 320)); // pclog("pollgus2 %i %i %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl); if (gus->t2on) { @@ -919,7 +920,7 @@ void gus_poll_wave(void *p) gus_update(gus); - gus->samp_timer += gus->samp_latch; + timer_advance_u64(&gus->samp_timer, gus->samp_latch); gus->out_l = gus->out_r = 0; @@ -1120,7 +1121,7 @@ void *gus_init() printf("Top volume %f %f %f %f\n",vol16bit[4095],vol16bit[3800],vol16bit[3000],vol16bit[2048]); gus->voices=14; - gus->samp_timer = gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); gus->t1l = gus->t2l = 0xff; @@ -1128,9 +1129,9 @@ void *gus_init() io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); io_sethandler(0x0746, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); - timer_add(gus_poll_wave, &gus->samp_timer, TIMER_ALWAYS_ENABLED, gus); - timer_add(gus_poll_timer_1, &gus->timer_1, TIMER_ALWAYS_ENABLED, gus); - timer_add(gus_poll_timer_2, &gus->timer_2, TIMER_ALWAYS_ENABLED, gus); + timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); + timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); + timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1); sound_add_handler(gus_get_buffer, gus); @@ -1150,9 +1151,9 @@ void gus_speed_changed(void *p) gus_t *gus = (gus_t *)p; if (gus->voices < 14) - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); else - gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); } device_t gus_device = diff --git a/src/sound_opl.c b/src/sound_opl.c index 2a59460..33f6fd9 100644 --- a/src/sound_opl.c +++ b/src/sound_opl.c @@ -106,54 +106,45 @@ void ym3812_timer_set_0(void *param, int timer, int64_t period) { opl_t *opl = (opl_t *)param; - opl->timers[0][timer] = period * TIMER_USEC * 20; - if (!opl->timers[0][timer]) opl->timers[0][timer] = 1; - opl->timers_enable[0][timer] = period ? 1 : 0; + if (period) + timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20); + else + timer_disable(&opl->timers[0][timer]); } void ym3812_timer_set_1(void *param, int timer, int64_t period) { opl_t *opl = (opl_t *)param; - opl->timers[1][timer] = period * TIMER_USEC * 20; - if (!opl->timers[1][timer]) opl->timers[1][timer] = 1; - opl->timers_enable[1][timer] = period ? 1 : 0; + if (period) + timer_set_delay_u64(&opl->timers[1][timer], period * TIMER_USEC * 20); + else + timer_disable(&opl->timers[1][timer]); } void ymf262_timer_set(void *param, int timer, int64_t period) { opl_t *opl = (opl_t *)param; - opl->timers[0][timer] = period * TIMER_USEC * 20; - if (!opl->timers[0][timer]) opl->timers[0][timer] = 1; - opl->timers_enable[0][timer] = period ? 1 : 0; + if (period) + timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20); + else + timer_disable(&opl->timers[0][timer]); } static void opl_timer_callback00(void *p) { - opl_t *opl = (opl_t *)p; - - opl->timers_enable[0][0] = 0; opl_timer_over(0, 0); } static void opl_timer_callback01(void *p) { - opl_t *opl = (opl_t *)p; - - opl->timers_enable[0][1] = 0; opl_timer_over(0, 1); } static void opl_timer_callback10(void *p) { - opl_t *opl = (opl_t *)p; - - opl->timers_enable[1][0] = 0; opl_timer_over(1, 0); } static void opl_timer_callback11(void *p) { - opl_t *opl = (opl_t *)p; - - opl->timers_enable[1][1] = 0; opl_timer_over(1, 1); } @@ -161,16 +152,16 @@ void opl2_init(opl_t *opl) { opl_init(ym3812_timer_set_0, opl, 0, 0, 0); opl_init(ym3812_timer_set_1, opl, 1, 0, 0); - timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); - timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); - timer_add(opl_timer_callback10, &opl->timers[1][0], &opl->timers_enable[1][0], (void *)opl); - timer_add(opl_timer_callback11, &opl->timers[1][1], &opl->timers_enable[1][1], (void *)opl); + timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0); + timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0); + timer_add(&opl->timers[1][0], opl_timer_callback10, (void *)opl, 0); + timer_add(&opl->timers[1][1], opl_timer_callback11, (void *)opl, 0); } void opl3_init(opl_t *opl, int opl_emu) { opl_init(ymf262_timer_set, opl, 0, 1, opl_emu); - timer_add(opl_timer_callback00, &opl->timers[0][0], &opl->timers_enable[0][0], (void *)opl); - timer_add(opl_timer_callback01, &opl->timers[0][1], &opl->timers_enable[0][1], (void *)opl); + timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0); + timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0); } diff --git a/src/sound_opl.h b/src/sound_opl.h index 0728d67..06f5cd7 100644 --- a/src/sound_opl.h +++ b/src/sound_opl.h @@ -4,8 +4,7 @@ typedef struct opl_t { int chip_nr[2]; - int timers[2][2]; - int timers_enable[2][2]; + pc_timer_t timers[2][2]; int16_t filtbuf[2]; diff --git a/src/sound_pas16.c b/src/sound_pas16.c index c736611..7f44fe7 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -118,7 +118,8 @@ typedef struct pas16_t struct { uint32_t l[3]; - int c[3]; + int c[3]; + pc_timer_t timer[3]; uint8_t m[3]; uint8_t ctrl, ctrls[2]; int wp, rm[3], wm[3]; @@ -398,7 +399,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) { if (!(val & 0x20)) { - if (val & 2) pas16->pit.rl[0] = pas16->pit.c[0] / (PITCONST * (1 << TIMER_SHIFT)); + if (val & 2) pas16->pit.rl[0] = timer_get_remaining_u64(&pit.timer[0]) / PITCONST;; if (val & 4) pas16->pit.rl[1] = pas16->pit.c[1]; if (val & 8) pas16->pit.rl[2] = pas16->pit.c[2]; } @@ -413,11 +414,14 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) } if (!(pas16->pit.ctrl & 0x30)) { - pas16->pit.rl[t] = pas16->pit.c[t]; - if (!t) - pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT)); - if (pas16->pit.c[t] < 0) - pas16->pit.rl[t] = 0; + if (!t) + pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; + else + { + pas16->pit.rl[t] = pas16->pit.c[t]; + if (pas16->pit.c[t] < 0) + pas16->pit.rl[t] = 0; + } pas16->pit.ctrl |= 0x30; pas16->pit.rereadlatch[t] = 0; pas16->pit.rm[t] = 3; @@ -431,9 +435,10 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) if (!pas16->pit.rm[t]) { pas16->pit.rm[t] = 3; - pas16->pit.rl[t] = pit.c[t]; - if (!t) - pas16->pit.rl[t] /= (PITCONST * (1 << TIMER_SHIFT)); + if (!t) + pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; + else + pas16->pit.rl[t] = pas16->pit.c[t]; } pas16->pit.rereadlatch[t] = 1; } @@ -449,7 +454,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) pas16->pit.thit[t] = 0; pas16->pit.c[t] = pas16->pit.l[t]; if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); pas16->pit.enable[t] = 1; break; case 2: @@ -457,7 +462,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) pas16->pit.thit[t] = 0; pas16->pit.c[t] = pas16->pit.l[t]; if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); pas16->pit.enable[t] = 1; break; case 0: @@ -465,7 +470,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) pas16->pit.l[t] |= (val << 8); pas16->pit.c[t] = pas16->pit.l[t]; if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); pas16->pit.thit[t] = 0; pas16->pit.wm[t] = 3; pas16->pit.enable[t] = 1; @@ -481,7 +486,7 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) pas16->pit.l[t] |= 0x10000; pas16->pit.c[t] = pas16->pit.l[t]; if (!t) - pas16->pit.c[t] *= PITCONST * (1 << TIMER_SHIFT); + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); } break; } @@ -501,8 +506,8 @@ static uint8_t pas16_pit_in(uint16_t port, void *p) pas16->pit.rereadlatch[t] = 0; if (!t) { - pas16->pit.rl[t] = pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT)); - if ((pas16->pit.c[t] / (PITCONST * (1 << TIMER_SHIFT))) > 65536) + pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; + if ((timer_get_remaining_u64(&pit.timer[t]) / PITCONST) > 65536) pas16->pit.rl[t] = 0xFFFF; } else @@ -557,13 +562,12 @@ static void pas16_pcm_poll(void *p) if (pas16->pit.m[0] & 2) { if (pas16->pit.l[0]) - pas16->pit.c[0] += (pas16->pit.l[0] * PITCONST * (1 << TIMER_SHIFT)); + timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); else - pas16->pit.c[0] += (0x10000 * PITCONST * (1 << TIMER_SHIFT)); + timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); } else { - pas16->pit.c[0] = -1; pas16->pit.enable[0] = 0; } // if (pas16->pcm_ctrl & PAS16_PCM_ENA) @@ -736,7 +740,7 @@ void *pas16_init() io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - timer_add(pas16_pcm_poll, &pas16->pit.c[0], &pas16->pit.enable[0], pas16); + timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); sound_add_handler(pas16_get_buffer, pas16); diff --git a/src/sound_ps1.c b/src/sound_ps1.c index fb8a9a5..27c5767 100644 --- a/src/sound_ps1.c +++ b/src/sound_ps1.c @@ -13,7 +13,8 @@ typedef struct ps1_audio_t uint8_t status, ctrl; - int timer_latch, timer_count, timer_enable; + uint64_t timer_latch; + pc_timer_t timer; uint8_t fifo[2048]; int fifo_read_idx, fifo_write_idx; @@ -89,8 +90,10 @@ static void ps1_audio_write(uint16_t port, uint8_t val, void *p) break; case 3: /*Timer reload value*/ ps1->timer_latch = val; - ps1->timer_count = (0xff-val) * TIMER_USEC; - ps1->timer_enable = (val != 0); + if (val) + timer_set_delay_u64(&ps1->timer, (0xff-val) * TIMER_USEC); + else + timer_disable(&ps1->timer); break; case 4: /*Almost empty*/ ps1->fifo_threshold = val * 4; @@ -124,7 +127,7 @@ static void ps1_audio_callback(void *p) ps1->status |= 0x10; /*ADC data ready*/ ps1_update_irq_status(ps1); - ps1->timer_count += ps1->timer_latch * TIMER_USEC; + timer_advance_u64(&ps1->timer, ps1->timer_latch * TIMER_USEC); } static void ps1_audio_get_buffer(int32_t *buffer, int len, void *p) @@ -149,7 +152,7 @@ static void *ps1_audio_init() io_sethandler(0x0200, 0x0001, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1); io_sethandler(0x0202, 0x0006, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1); - timer_add(ps1_audio_callback, &ps1->timer_count, &ps1->timer_enable, ps1); + timer_add(&ps1->timer, ps1_audio_callback, ps1, 0); sound_add_handler(ps1_audio_get_buffer, ps1); return ps1; diff --git a/src/sound_pssj.c b/src/sound_pssj.c index d692f33..4169c4a 100644 --- a/src/sound_pssj.c +++ b/src/sound_pssj.c @@ -21,7 +21,7 @@ typedef struct pssj_t int amplitude; int irq; - int timer_count; + pc_timer_t timer; int enable; int wave_pos; @@ -46,7 +46,13 @@ static void pssj_write(uint16_t port, uint8_t val, void *p) { case 0: pssj->ctrl = val; + + if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3))) + timer_set_delay_u64(&pssj->timer, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); pssj->enable = (val & 4) && (pssj->ctrl & 3); + if (!pssj->enable) + timer_disable(&pssj->timer); + sn74689_set_extra_divide(&pssj->sn76489, val & 0x40); if (!(val & 8)) pssj->irq = 0; @@ -166,7 +172,7 @@ static void pssj_callback(void *p) pssj->wave_pos = (pssj->wave_pos + 1) & 31; } - pssj->timer_count += (int)(TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400)); + timer_advance_u64(&pssj->timer, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); } static void pssj_get_buffer(int32_t *buffer, int len, void *p) @@ -190,7 +196,7 @@ void *pssj_init() sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); - timer_add(pssj_callback, &pssj->timer_count, &pssj->enable, pssj); + timer_add(&pssj->timer, pssj_callback, pssj, 0); sound_add_handler(pssj_get_buffer, pssj); return pssj; diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index df6954a..25de3ee 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -164,7 +164,9 @@ void sb_irqc(sb_dsp_t *dsp, int irq8) void sb_dsp_reset(sb_dsp_t *dsp) { - dsp->sbenable = dsp->sb_enable_i = 0; + timer_disable(&dsp->output_timer); + timer_disable(&dsp->input_timer); + dsp->sb_command = 0; dsp->sb_8_length = 0xffff; @@ -181,7 +183,6 @@ void sb_dsp_reset(sb_dsp_t *dsp) dsp->sbe2count = 0; dsp->sbreset = 0; - dsp->sbenable = dsp->sb_enable_i = dsp->sb_count_i = 0; dsp->record_pos_read=0; dsp->record_pos_write=SB_DSP_REC_SAFEFTY_MARGIN; @@ -219,12 +220,12 @@ void sb_dsp_speed_changed(sb_dsp_t *dsp) if (dsp->sb_timeo < 256) dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); else - dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); + dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); if (dsp->sb_timei < 256) dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); else - dsp->sblatchi = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); + dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); } void sb_add_data(sb_dsp_t *dsp, uint8_t v) @@ -249,9 +250,8 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len dsp->sb_8_enable = 1; if (dsp->sb_16_enable && dsp->sb_16_output) dsp->sb_16_enable = 0; dsp->sb_8_output = 1; - timer_process(); - dsp->sbenable = dsp->sb_8_enable; - timer_update_outstanding(); + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); dsp->sbleftright = 0; dsp->sbdacpos = 0; // pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); @@ -265,9 +265,8 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len dsp->sb_16_enable = 1; if (dsp->sb_8_enable && dsp->sb_8_output) dsp->sb_8_enable = 0; dsp->sb_16_output = 1; - timer_process(); - dsp->sbenable = dsp->sb_16_enable; - timer_update_outstanding(); + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); // pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len); } } @@ -290,9 +289,8 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l dsp->sb_8_enable = 1; if (dsp->sb_16_enable && !dsp->sb_16_output) dsp->sb_16_enable = 0; dsp->sb_8_output = 0; - timer_process(); - dsp->sb_enable_i = dsp->sb_8_enable; - timer_update_outstanding(); + if (!timer_is_enabled(&dsp->input_timer)) + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); // pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); } else @@ -311,9 +309,8 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l dsp->sb_16_enable = 1; if (dsp->sb_8_enable && !dsp->sb_8_output) dsp->sb_8_enable = 0; dsp->sb_16_output = 0; - timer_process(); - dsp->sb_enable_i = dsp->sb_16_enable; - timer_update_outstanding(); + if (!timer_is_enabled(&dsp->input_timer)) + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); // pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); } memset(dsp->record_buffer,0,sizeof(dsp->record_buffer)); @@ -413,15 +410,13 @@ void sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); /*Due to the current implementation, I need to emulate a samplerate, even if this * mode does not imply such samplerate. Position is increased in sb_poll_i*/ - if (dsp->sb_enable_i==0) + if (!timer_is_enabled(&dsp->input_timer)) { dsp->sb_timei = 256 - 22; dsp->sblatchi = TIMER_USEC * 22; temp = 1000000 / 22; dsp->sb_freq = temp; - timer_process(); - dsp->sb_enable_i = 1; - timer_update_outstanding(); + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); } break; case 0x24: /*8-bit single cycle DMA input*/ @@ -444,7 +439,7 @@ void sb_exec_command(sb_dsp_t *dsp) 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)))); + dsp->sblatcho = (uint64_t)(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); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); @@ -494,9 +489,8 @@ void sb_exec_command(sb_dsp_t *dsp) 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(); + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); break; case 0x90: /*High speed 8-bit autoinit DMA output*/ if (dsp->sb_type < SB2) break; @@ -686,10 +680,7 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; return; case 0xC: /*Command/data write*/ - timer_process(); - dsp->wb_time = TIMER_USEC * 1; - dsp->wb_full = 1; - timer_update_outstanding(); + timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); if (dsp->asp_data_len) { // pclog("ASP data %i\n", dsp->asp_data_len); @@ -740,7 +731,7 @@ uint8_t sb_read(uint16_t a, void *priv) dsp->busy_count = 0; if (dsp->wb_full || (dsp->busy_count & 2)) { - dsp->wb_full = dsp->wb_time; + dsp->wb_full = timer_is_enabled(&dsp->wb_timer); return 0xff; } return 0x7f; @@ -758,9 +749,6 @@ uint8_t sb_read(uint16_t a, void *priv) static void sb_wb_clear(void *p) { - sb_dsp_t *dsp = (sb_dsp_t *)p; - - dsp->wb_time = 0; } void sb_dsp_init(sb_dsp_t *dsp, int type) @@ -774,9 +762,9 @@ void sb_dsp_init(sb_dsp_t *dsp, int type) sb_doreset(dsp); - timer_add(pollsb, &dsp->sbcount, &dsp->sbenable, dsp); - timer_add(sb_poll_i, &dsp->sb_count_i, &dsp->sb_enable_i, dsp); - timer_add(sb_wb_clear, &dsp->wb_time, &dsp->wb_time, dsp); + timer_add(&dsp->output_timer, pollsb, dsp, 0); + timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); + timer_add(&dsp->wb_timer, sb_wb_clear, dsp, 0); /*Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when a set frequency command is sent.*/ @@ -806,7 +794,8 @@ void pollsb(void *p) sb_dsp_t *dsp = (sb_dsp_t *)p; int tempi,ref; - dsp->sbcount += dsp->sblatcho; + timer_advance_u64(&dsp->output_timer, 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) { @@ -970,8 +959,13 @@ void pollsb(void *p) if (dsp->sb_8_length < 0) { - if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen; - else dsp->sb_8_enable = dsp->sbenable=0; + if (dsp->sb_8_autoinit) + dsp->sb_8_length = dsp->sb_8_autolen; + else + { + dsp->sb_8_enable = 0; + timer_disable(&dsp->output_timer); + } sb_irq(dsp, 1); } } @@ -1022,8 +1016,13 @@ void pollsb(void *p) 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; + if (dsp->sb_16_autoinit) + dsp->sb_16_length = dsp->sb_16_autolen; + else + { + dsp->sb_16_enable = 0; + timer_disable(&dsp->output_timer); + } sb_irq(dsp, 0); } } @@ -1033,7 +1032,8 @@ void pollsb(void *p) if (dsp->sb_pausetime < 0) { sb_irq(dsp, 1); - dsp->sbenable = dsp->sb_8_enable; + if (!dsp->sb_8_enable) + timer_disable(&dsp->output_timer); // pclog("SB pause over\n"); } } @@ -1043,7 +1043,9 @@ void sb_poll_i(void *p) { sb_dsp_t *dsp = (sb_dsp_t *)p; int processed=0; - dsp->sb_count_i += dsp->sblatchi; + + timer_advance_u64(&dsp->input_timer, 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) { @@ -1100,8 +1102,13 @@ void sb_poll_i(void *p) 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->sb_enable_i = 0; + if (dsp->sb_8_autoinit) + dsp->sb_8_length = dsp->sb_8_autolen; + else + { + dsp->sb_8_enable = 0; + timer_disable(&dsp->input_timer); + } sb_irq(dsp, 1); } processed=1; @@ -1167,8 +1174,13 @@ void sb_poll_i(void *p) 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->sb_enable_i = 0; + if (dsp->sb_16_autoinit) + dsp->sb_16_length = dsp->sb_16_autolen; + else + { + dsp->sb_16_enable = 0; + timer_disable(&dsp->input_timer); + } sb_irq(dsp, 0); } processed=1; diff --git a/src/sound_sb_dsp.h b/src/sound_sb_dsp.h index 68f260a..cb14af5 100644 --- a/src/sound_sb_dsp.h +++ b/src/sound_sb_dsp.h @@ -47,9 +47,9 @@ typedef struct sb_dsp_t int sbenable, sb_enable_i; - int sbcount, sb_count_i; + pc_timer_t output_timer, input_timer; - int sblatcho, sblatchi; + uint64_t sblatcho, sblatchi; uint16_t sb_addr; @@ -57,7 +57,8 @@ typedef struct sb_dsp_t int asp_data_len; - int wb_time, wb_full; + pc_timer_t wb_timer; + int wb_full; int busy_count; diff --git a/src/timer.c b/src/timer.c index 381562e..a999d4f 100644 --- a/src/timer.c +++ b/src/timer.c @@ -1,117 +1,134 @@ #include "ibm.h" -/*#include "sound_opl.h" -#include "adlibgold.h" -#include "sound_pas16.h" -#include "sound_sb.h" -#include "sound_sb_dsp.h" -#include "sound_wss.h"*/ #include "timer.h" -#define TIMERS_MAX 32 +uint64_t TIMER_USEC; +uint32_t timer_target; -int TIMER_USEC; +/*Enabled timers are stored in a linked list, with the first timer to expire at + the head.*/ +static pc_timer_t *timer_head = NULL; -static struct +void timer_enable(pc_timer_t *timer) { - int present; - void (*callback)(void *priv); - void *priv; - int *enable; - int *count; -} timers[TIMERS_MAX]; + pc_timer_t *timer_node = timer_head; -int timers_present = 0; -int timer_one = 1; - -int timer_count = 0, timer_latch = 0; -int timer_start = 0; +// pclog("timer->enable %p %i\n", timer, timer->enabled); + if (timer->enabled) + timer_disable(timer); + + if (timer->next || timer->prev) + fatal("timer_enable - timer->next\n"); + + timer->enabled = 1; + + /*List currently empty - add to head*/ + if (!timer_head) + { + timer_head = timer; + timer->next = timer->prev = NULL; + timer_target = timer_head->ts_integer; + return; + } + + timer_node = timer_head; + + while (1) + { + /*Timer expires before timer_node. Add to list in front of timer_node*/ + if (TIMER_LESS_THAN(timer, timer_node)) + { + timer->next = timer_node; + timer->prev = timer_node->prev; + timer_node->prev = timer; + if (timer->prev) + timer->prev->next = timer; + else + { + timer_head = timer; + timer_target = timer_head->ts_integer; + } + return; + } + + /*timer_node is last in the list. Add timer to end of list*/ + if (!timer_node->next) + { + timer_node->next = timer; + timer->prev = timer_node; + return; + } + + timer_node = timer_node->next; + } +} +void timer_disable(pc_timer_t *timer) +{ +// pclog("timer->disable %p\n", timer); + if (!timer->enabled) + return; + + if (!timer->next && !timer->prev && timer != timer_head) + fatal("timer_disable - !timer->next\n"); + + timer->enabled = 0; + + if (timer->prev) + timer->prev->next = timer->next; + else + timer_head = timer->next; + if (timer->next) + timer->next->prev = timer->prev; + timer->prev = timer->next = NULL; +} +static void timer_remove_head() +{ + if (timer_head) + { + pc_timer_t *timer = timer_head; +// pclog("timer_remove_head %p %p\n", timer_head, timer_head->next); + timer_head = timer->next; + timer_head->prev = NULL; + timer->next = timer->prev = NULL; + timer->enabled = 0; + } +} void timer_process() { - int c; - int process = 0; - /*Get actual elapsed time*/ - int diff = timer_latch - timer_count; - int enable[TIMERS_MAX]; + if (!timer_head) + return; - timer_latch = 0; - - for (c = 0; c < timers_present; c++) - { - enable[c] = *timers[c].enable; - if (*timers[c].enable) - { - *timers[c].count = *timers[c].count - diff; - if (*timers[c].count <= 0) - process = 1; - } - } - - if (!process) - return; - - while (1) - { - int lowest = 1, lowest_c; - - for (c = 0; c < timers_present; c++) - { - if (enable[c]) - { - if (*timers[c].count < lowest) - { - lowest = *timers[c].count; - lowest_c = c; - } - } - } - - if (lowest > 0) - break; - - timers[lowest_c].callback(timers[lowest_c].priv); - enable[lowest_c] = *timers[lowest_c].enable; - } -} - -void timer_update_outstanding() -{ - int c; - timer_latch = 0x7fffffff; - for (c = 0; c < timers_present; c++) + while (1) { - if (*timers[c].enable && *timers[c].count < timer_latch) - timer_latch = *timers[c].count; + pc_timer_t *timer = timer_head; + + if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) + break; + + timer_remove_head(); + timer->callback(timer->p); } - timer_count = timer_latch = (timer_latch + ((1 << TIMER_SHIFT) - 1)); + + timer_target = timer_head->ts_integer; } void timer_reset() { pclog("timer_reset\n"); - timers_present = 0; - timer_latch = timer_count = 0; -// timer_process(); + timer_target = 0; + tsc = 0; + timer_head = NULL; } -int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv) +void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer) { - if (timers_present < TIMERS_MAX) - { -// pclog("timer_add : adding timer %i\n", timers_present); - timers[timers_present].present = 1; - timers[timers_present].callback = callback; - timers[timers_present].priv = priv; - timers[timers_present].count = count; - timers[timers_present].enable = enable; - timers_present++; - return timers_present - 1; - } - return -1; -} - -void timer_set_callback(int timer, void (*callback)(void *priv)) -{ - timers[timer].callback = callback; + memset(timer, 0, sizeof(pc_timer_t)); + + timer->callback = callback; + timer->p = p; + timer->enabled = 0; + timer->prev = timer->next = NULL; + if (start_timer) + timer_set_delay_u64(timer, 0); } diff --git a/src/timer.h b/src/timer.h index 43722d8..181c1ce 100644 --- a/src/timer.h +++ b/src/timer.h @@ -3,56 +3,140 @@ #include "cpu.h" -extern int timer_start; +/*Timers are based on the CPU Time Stamp Counter. Timer timestamps are in a + 32:32 fixed point format, with the integer part compared against the TSC. The + fractional part is used when advancing the timestamp to ensure a more accurate + period. + + As the timer only stores 32 bits of integer timestamp, and the TSC is 64 bits, + the timer period can only be at most 0x7fffffff CPU cycles. To allow room for + (optimistic) CPU frequency growth, timer period must be at most 1 second. -#define timer_start_period(cycles) \ - timer_start = cycles; + When a timer callback is called, the timer has been disabled. If the timer is + to repeat, the callback must call timer_advance_u64(). This is a change from + the old timer API.*/ +typedef struct pc_timer_t +{ + uint32_t ts_integer; + uint32_t ts_frac; + int enabled; -#define timer_end_period(cycles) \ - do \ - { \ - int diff = timer_start - (cycles); \ - timer_count -= diff; \ - timer_start = cycles; \ - if (timer_count <= 0) \ - { \ - timer_process(); \ - timer_update_outstanding(); \ - } \ - } while (0) + void (*callback)(void *p); + void *p; -#define timer_clock() \ - do \ - { \ - int diff; \ - if (AT) \ - { \ - diff = timer_start - (cycles << TIMER_SHIFT); \ - timer_start = cycles << TIMER_SHIFT; \ - } \ - else \ - { \ - diff = timer_start - (cycles * xt_cpu_multi); \ - timer_start = cycles * xt_cpu_multi; \ - } \ - timer_count -= diff; \ - timer_process(); \ - timer_update_outstanding(); \ - } while (0) + struct pc_timer_t *prev, *next; +} pc_timer_t; +/*Timestamp of nearest enabled timer. CPU emulation must call timer_process() + when TSC matches or exceeds this.*/ +extern uint32_t timer_target; + +/*Enable timer, without updating timestamp*/ +void timer_enable(pc_timer_t *timer); +/*Disable timer*/ +void timer_disable(pc_timer_t *timer); + +/*Process any pending timers*/ void timer_process(); -void timer_update_outstanding(); + +/*Reset timer system*/ 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)); -#define TIMER_ALWAYS_ENABLED &timer_one +/*Add new timer. If start_timer is set, timer will be enabled with a zero + timestamp - this is useful for permanently enabled timers*/ +void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer); -extern int timer_count; -extern int timer_one; +/*1us in 32:32 format*/ +extern uint64_t TIMER_USEC; -#define TIMER_SHIFT 6 +/*True if timer a expires before timer b*/ +#define TIMER_LESS_THAN(a, b) ((int32_t)((a)->ts_integer - (b)->ts_integer) <= 0) +/*True if timer a expires before 32 bit integer timestamp b*/ +#define TIMER_LESS_THAN_VAL(a, b) ((int32_t)((a)->ts_integer - (b)) <= 0) +/*True if 32 bit integer timestamp a expires before 32 bit integer timestamp b*/ +#define TIMER_VAL_LESS_THAN_VAL(a, b) ((int32_t)((a) - (b)) <= 0) -extern int TIMER_USEC; +/*Advance timer by delay, specified in 32:32 format. This should be used to + resume a recurring timer in a callback routine*/ +static inline void timer_advance_u64(pc_timer_t *timer, uint64_t delay) +{ + uint32_t int_delay = delay >> 32; + uint32_t frac_delay = delay & 0xffffffff; + + if ((frac_delay + timer->ts_frac) < frac_delay) + timer->ts_integer++; + timer->ts_frac += frac_delay; + timer->ts_integer += int_delay; + + timer_enable(timer); +} + +/*Set a timer to the given delay, specified in 32:32 format. This should be used + when starting a timer*/ +static inline void timer_set_delay_u64(pc_timer_t *timer, uint64_t delay) +{ + uint32_t int_delay = delay >> 32; + uint32_t frac_delay = delay & 0xffffffff; + + timer->ts_frac = frac_delay; + timer->ts_integer = int_delay + (uint32_t)tsc; + + timer_enable(timer); +} + +/*True if timer currently enabled*/ +static inline int timer_is_enabled(pc_timer_t *timer) +{ + return timer->enabled; +} + +/*Return integer timestamp of timer*/ +static inline uint32_t timer_get_ts_int(pc_timer_t *timer) +{ + return timer->ts_integer; +} + +/*Return remaining time before timer expires, in us. If the timer has already + expired then return 0*/ +static inline uint32_t timer_get_remaining_us(pc_timer_t *timer) +{ + if (timer->enabled) + { + int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32); + + if (remaining < 0) + return 0; + return remaining / TIMER_USEC; + } + + return 0; +} + +/*Return remaining time before timer expires, in 32:32 timestamp format. If the + timer has already expired then return 0*/ +static inline uint64_t timer_get_remaining_u64(pc_timer_t *timer) +{ + if (timer->enabled) + { + int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32); + + if (remaining < 0) + return 0; + return remaining; + } + + return 0; +} + +/*Set timer callback function*/ +static inline void timer_set_callback(pc_timer_t *timer, void (*callback)(void *p)) +{ + timer->callback = callback; +} +/*Set timer private data*/ +static inline void timer_set_p(pc_timer_t *timer, void *p) +{ + timer->p = p; +} #endif /*_TIMER_H_*/ diff --git a/src/vid_cga.c b/src/vid_cga.c index 7b616fc..29f6ecb 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -80,8 +80,9 @@ void cga_write(uint32_t addr, uint8_t val, void *p) cga->vram[addr & 0x3fff] = val; if (cga->snow_enabled) { - cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = val; - cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = val; + int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; + cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; } egawrites++; cycles -= 4; @@ -93,8 +94,9 @@ uint8_t cga_read(uint32_t addr, void *p) cycles -= 4; if (cga->snow_enabled) { - cga->charbuffer[ ((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc] = cga->vram[addr & 0x3fff]; - cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff]; + int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; + cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; } egareads++; // pclog("CGA_READ %04X\n", addr); @@ -121,8 +123,8 @@ void cga_recalctimings(cga_t *cga) _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)); + cga->dispontime = (uint64_t)_dispontime; + cga->dispofftime = (uint64_t)_dispofftime; } void cga_poll(void *p) @@ -140,7 +142,7 @@ void cga_poll(void *p) if (!cga->linepos) { - cga->vidtime += cga->dispofftime; + timer_advance_u64(&cga->timer, cga->dispofftime); cga->cgastat |= 1; cga->linepos = 1; oldsc = cga->sc; @@ -313,7 +315,7 @@ void cga_poll(void *p) } else { - cga->vidtime += cga->dispontime; + timer_advance_u64(&cga->timer, cga->dispontime); cga->linepos = 0; if (cga->vsynctime) { @@ -434,6 +436,7 @@ void cga_poll(void *p) void cga_init(cga_t *cga) { + timer_add(&cga->timer, cga_poll, cga, 1); cga->composite = 0; } @@ -452,7 +455,8 @@ void *cga_standalone_init() cga->vram = malloc(0x4000); cga_comp_init(cga->revision); - timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); + + timer_add(&cga->timer, cga_poll, cga, 1); 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); diff --git a/src/vid_cga.h b/src/vid_cga.h index 7594bf1..b8b73c9 100644 --- a/src/vid_cga.h +++ b/src/vid_cga.h @@ -18,8 +18,8 @@ typedef struct cga_t uint16_t ma, maback; int oddeven; - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; diff --git a/src/vid_colorplus.c b/src/vid_colorplus.c index 6a28a23..298cee2 100644 --- a/src/vid_colorplus.c +++ b/src/vid_colorplus.c @@ -119,7 +119,7 @@ void colorplus_poll(void *p) if (!colorplus->cga.linepos) { - colorplus->cga.vidtime += colorplus->cga.dispofftime; + timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime); colorplus->cga.cgastat |= 1; colorplus->cga.linepos = 1; oldsc = colorplus->cga.sc; @@ -215,7 +215,7 @@ void colorplus_poll(void *p) } else { - colorplus->cga.vidtime += colorplus->cga.dispontime; + timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime); colorplus->cga.linepos = 0; if (colorplus->cga.vsynctime) { @@ -346,7 +346,7 @@ void *colorplus_init() display_type = device_get_config_int("display_type"); contrast = device_get_config_int("contrast"); - timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus); + timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1); 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); diff --git a/src/vid_compaq_cga.c b/src/vid_compaq_cga.c index d25cc24..f92bd84 100644 --- a/src/vid_compaq_cga.c +++ b/src/vid_compaq_cga.c @@ -25,8 +25,8 @@ void compaq_cga_recalctimings(compaq_cga_t *self) _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - self->cga.dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - self->cga.dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + self->cga.dispontime = (uint64_t)_dispontime; + self->cga.dispofftime = (uint64_t)_dispofftime; } void compaq_cga_poll(void *p) @@ -52,7 +52,7 @@ void compaq_cga_poll(void *p) /* We are in Compaq 350-line CGA territory */ if (!self->cga.linepos) { - self->cga.vidtime += self->cga.dispofftime; + timer_advance_u64(&self->cga.timer, self->cga.dispofftime); self->cga.cgastat |= 1; self->cga.linepos = 1; oldsc = self->cga.sc; @@ -194,7 +194,7 @@ void compaq_cga_poll(void *p) } else { - self->cga.vidtime += self->cga.dispontime; + timer_advance_u64(&self->cga.timer, self->cga.dispontime); self->cga.linepos = 0; if (self->cga.vsynctime) { @@ -325,7 +325,7 @@ void *compaq_cga_init() self->cga.vram = malloc(0x4000); - timer_add(compaq_cga_poll, &self->cga.vidtime, TIMER_ALWAYS_ENABLED, self); + timer_add(&self->cga.timer, compaq_cga_poll, self, 1); mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, self); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); diff --git a/src/vid_ega.c b/src/vid_ega.c index 8444382..1c134be 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -241,10 +241,10 @@ void ega_recalctimings(ega_t *ega) _dispontime *= crtcconst; _dispofftime *= crtcconst; - 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)); + ega->dispontime = (uint64_t)_dispontime; + ega->dispofftime = (uint64_t)_dispofftime; + pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime, + ega->dispofftime, (float)ega->dispofftime); // 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]); @@ -500,7 +500,7 @@ void ega_poll(void *p) if (!ega->linepos) { - ega->vidtime += ega->dispofftime; + timer_advance_u64(&ega->timer, ega->dispofftime); ega->stat |= 1; ega->linepos = 1; @@ -567,7 +567,7 @@ void ega_poll(void *p) } else { - ega->vidtime += ega->dispontime; + timer_advance_u64(&ega->timer, ega->dispontime); // if (output) printf("Display on %f\n",vidtime); if (ega->dispon) ega->stat &= ~1; @@ -983,6 +983,8 @@ void ega_init(ega_t *ega, int monitor_type, int is_mono) egaswitches = monitor_type & 0xf; ega->vram_limit = 256 * 1024; ega->vrammask = ega->vram_limit-1; + + timer_add(&ega->timer, ega_poll, ega, 1); } void *ega_standalone_init() @@ -1013,8 +1015,8 @@ void *ega_standalone_init() ega->vrammask = ega->vram_limit-1; mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); - timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + return ega; } diff --git a/src/vid_ega.h b/src/vid_ega.h index 4d50622..c955509 100644 --- a/src/vid_ega.h +++ b/src/vid_ega.h @@ -39,8 +39,8 @@ typedef struct ega_t int vres; - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; uint8_t scrblank; diff --git a/src/vid_genius.c b/src/vid_genius.c index 088cdf2..50f2e1d 100644 --- a/src/vid_genius.c +++ b/src/vid_genius.c @@ -98,8 +98,8 @@ typedef struct genius_t int enabled; /* Display enabled, 0 or 1 */ int detach; /* Detach cursor, 0 or 1 */ - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int linepos, displine; int vc; @@ -246,8 +246,8 @@ void genius_recalctimings(genius_t *genius) _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - genius->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - genius->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + genius->dispontime = (uint64_t)_dispontime; + genius->dispofftime = (uint64_t)_dispofftime; } @@ -462,7 +462,7 @@ void genius_poll(void *p) if (!genius->linepos) { - genius->vidtime += genius->dispofftime; + timer_advance_u64(&genius->timer, genius->dispofftime); genius->cga_stat |= 1; genius->mda_stat |= 1; genius->linepos = 1; @@ -526,7 +526,7 @@ void genius_poll(void *p) genius->cga_stat &= ~1; genius->mda_stat &= ~1; } - genius->vidtime += genius->dispontime; + timer_advance_u64(&genius->timer, genius->dispontime); genius->linepos = 0; if (genius->displine == 1008) @@ -561,7 +561,7 @@ void *genius_init() /* 160k video RAM */ genius->vram = malloc(0x28000); - timer_add(genius_poll, &genius->vidtime, TIMER_ALWAYS_ENABLED, genius); + timer_add(&genius->timer, genius_poll, genius, 1); /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 899de86..0363cce 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -17,8 +17,8 @@ typedef struct hercules_t uint8_t ctrl, ctrl2, stat; - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; @@ -110,8 +110,8 @@ void hercules_recalctimings(hercules_t *hercules) _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - hercules->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - hercules->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + hercules->dispontime = (uint64_t)_dispontime; + hercules->dispofftime = (uint64_t)_dispofftime; } void hercules_poll(void *p) @@ -128,7 +128,7 @@ void hercules_poll(void *p) if (!hercules->linepos) { //pclog("Poll %i %i\n",vc,sc); - hercules->vidtime += hercules->dispofftime; + timer_advance_u64(&hercules->timer, hercules->dispofftime); hercules->stat |= 1; hercules->linepos = 1; oldsc = hercules->sc; @@ -199,7 +199,7 @@ void hercules_poll(void *p) } else { - hercules->vidtime += hercules->dispontime; + timer_advance_u64(&hercules->timer, hercules->dispontime); if (hercules->dispon) hercules->stat &= ~1; hercules->linepos = 0; @@ -314,7 +314,7 @@ void *hercules_init() hercules->vram = malloc(0x10000); - timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); + timer_add(&hercules->timer, hercules_poll, hercules, 1); 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); diff --git a/src/vid_incolor.c b/src/vid_incolor.c index a393d3e..76fa405 100644 --- a/src/vid_incolor.c +++ b/src/vid_incolor.c @@ -148,8 +148,8 @@ typedef struct incolor_t uint8_t ctrl, ctrl2, stat; - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; @@ -358,8 +358,8 @@ void incolor_recalctimings(incolor_t *incolor) _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - incolor->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - incolor->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + incolor->dispontime = (uint64_t)_dispontime; + incolor->dispofftime = (uint64_t)_dispofftime; } @@ -851,7 +851,7 @@ void incolor_poll(void *p) if (!incolor->linepos) { // pclog("InColor poll %i %i\n", incolor->vc, incolor->sc); - incolor->vidtime += incolor->dispofftime; + timer_advance_u64(&incolor->timer, incolor->dispofftime); incolor->stat |= 1; incolor->linepos = 1; oldsc = incolor->sc; @@ -886,7 +886,7 @@ void incolor_poll(void *p) } else { - incolor->vidtime += incolor->dispontime; + timer_advance_u64(&incolor->timer, incolor->dispontime); if (incolor->dispon) incolor->stat &= ~1; incolor->linepos = 0; @@ -1006,7 +1006,7 @@ void *incolor_init() incolor->vram = malloc(0x40000); /* 4 planes of 64k */ - timer_add(incolor_poll, &incolor->vidtime, TIMER_ALWAYS_ENABLED, incolor); + timer_add(&incolor->timer, incolor_poll, incolor, 1); 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); diff --git a/src/vid_mda.c b/src/vid_mda.c index fdb549e..c54aa85 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -17,8 +17,8 @@ typedef struct mda_t uint8_t ctrl, stat; - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; @@ -96,8 +96,8 @@ void mda_recalctimings(mda_t *mda) _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - mda->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - mda->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + mda->dispontime = (uint64_t)_dispontime; + mda->dispofftime = (uint64_t)_dispofftime; } void mda_poll(void *p) @@ -112,7 +112,7 @@ void mda_poll(void *p) int blink; if (!mda->linepos) { - mda->vidtime += mda->dispofftime; + timer_advance_u64(&mda->timer, mda->dispofftime); mda->stat |= 1; mda->linepos = 1; oldsc = mda->sc; @@ -166,7 +166,7 @@ void mda_poll(void *p) } else { - mda->vidtime += mda->dispontime; + timer_advance_u64(&mda->timer, mda->dispontime); if (mda->dispon) mda->stat&=~1; mda->linepos=0; if (mda->vsynctime) @@ -270,7 +270,7 @@ void *mda_init() mda->vram = malloc(0x1000); - timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); + timer_add(&mda->timer, mda_poll, mda, 1); 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); diff --git a/src/vid_olivetti_m24.c b/src/vid_olivetti_m24.c index 9e04c0d..dc8a2e3 100644 --- a/src/vid_olivetti_m24.c +++ b/src/vid_olivetti_m24.c @@ -33,7 +33,8 @@ typedef struct m24_t uint16_t ma, maback; int dispon; - int dispontime, dispofftime, vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; } m24_t; @@ -100,9 +101,11 @@ uint8_t m24_in(uint16_t addr, void *p) void m24_write(uint32_t addr, uint8_t val, void *p) { m24_t *m24 = (m24_t *)p; + int offset = ((timer_get_remaining_u64(&m24->timer) / CGACONST) * 4) & 0xfc; + m24->vram[addr & 0x7FFF]=val; - m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val; - m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val; + m24->charbuffer[offset] = val; + m24->charbuffer[offset | 1] = val; } uint8_t m24_read(uint32_t addr, void *p) @@ -129,8 +132,8 @@ void m24_recalctimings(m24_t *m24) _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)); + m24->dispontime = (uint64_t)_dispontime; + m24->dispofftime = (uint64_t)_dispofftime; } void m24_poll(void *p) @@ -148,7 +151,7 @@ void m24_poll(void *p) 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; + timer_advance_u64(&m24->timer, m24->dispofftime); m24->stat |= 1; m24->linepos = 1; oldsc = m24->sc; @@ -324,7 +327,7 @@ void m24_poll(void *p) else { // pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj); - m24->vidtime += m24->dispontime; + timer_advance_u64(&m24->timer, m24->dispontime); if (m24->dispon) m24->stat &= ~1; m24->linepos = 0; m24->lineff ^= 1; @@ -456,7 +459,7 @@ void *m24_init() m24->vram = malloc(0x8000); - timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24); + timer_add(&m24->timer, m24_poll, m24, 1); mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL, 0, m24); io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24); return m24; diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 0b5f89a..4c94a5a 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -35,7 +35,8 @@ typedef struct pc1512_t int dispon; int blink; - int dispontime, dispofftime, vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; uint8_t *vram; @@ -153,8 +154,8 @@ static void pc1512_recalctimings(pc1512_t *pc1512) _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)); + pc1512->dispontime = (uint64_t)_dispontime; + pc1512->dispofftime = (uint64_t)_dispofftime; } static void pc1512_poll(void *p) @@ -171,7 +172,7 @@ static void pc1512_poll(void *p) if (!pc1512->linepos) { - pc1512->vidtime += pc1512->dispofftime; + timer_advance_u64(&pc1512->timer, pc1512->dispofftime); pc1512->stat |= 1; pc1512->linepos = 1; oldsc = pc1512->sc; @@ -337,7 +338,7 @@ static void pc1512_poll(void *p) } else { - pc1512->vidtime += pc1512->dispontime; + timer_advance_u64(&pc1512->timer, pc1512->dispontime); if ((pc1512->lastline - pc1512->firstline) == 199) pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ if (pc1512->dispon) @@ -459,7 +460,7 @@ static void *pc1512_init() pc1512->cgacol = 7; pc1512->cgamode = 0x12; - timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512); + timer_add(&pc1512->timer, pc1512_poll, pc1512, 1); mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL, 0, pc1512); io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512); return pc1512; diff --git a/src/vid_pc1640.c b/src/vid_pc1640.c index c01dab3..dd92d57 100644 --- a/src/vid_pc1640.c +++ b/src/vid_pc1640.c @@ -23,7 +23,8 @@ typedef struct pc1640_t rom_t bios_rom; int cga_enabled; - int dispontime, dispofftime, vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; } pc1640_t; void pc1640_out(uint16_t addr, uint8_t val, void *p) @@ -33,29 +34,36 @@ void pc1640_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3db: - pc1640->cga_enabled = val & 0x40; - if (pc1640->cga_enabled) + if (pc1640->cga_enabled != (val & 0x40)) { - mem_mapping_enable(&pc1640->cga_mapping); - mem_mapping_disable(&pc1640->ega_mapping); - } - else - { - mem_mapping_disable(&pc1640->cga_mapping); - switch (pc1640->ega.gdcreg[6] & 0xc) + pc1640->cga_enabled = val & 0x40; + if (pc1640->cga_enabled) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x20000); - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x10000); - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xb0000, 0x08000); - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xb8000, 0x08000); - break; + timer_disable(&pc1640->ega.timer); + timer_set_delay_u64(&pc1640->cga.timer, 0); + mem_mapping_enable(&pc1640->cga_mapping); + mem_mapping_disable(&pc1640->ega_mapping); + } + else + { + timer_disable(&pc1640->cga.timer); + timer_set_delay_u64(&pc1640->ega.timer, 0); + mem_mapping_disable(&pc1640->cga_mapping); + switch (pc1640->ega.gdcreg[6] & 0xc) + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x20000); + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x10000); + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xb0000, 0x08000); + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xb8000, 0x08000); + break; + } } } pclog("3DB write %02X\n", val); @@ -93,23 +101,6 @@ void pc1640_recalctimings(pc1640_t *pc1640) } } -void pc1640_poll(void *p) -{ - pc1640_t *pc1640 = (pc1640_t *)p; - if (pc1640->cga_enabled) - { - pc1640->cga.vidtime = pc1640->vidtime; - cga_poll(&pc1640->cga); - pc1640->vidtime = pc1640->cga.vidtime; - } - else - { - pc1640->ega.vidtime = pc1640->vidtime; - ega_poll(&pc1640->ega); - pc1640->vidtime = pc1640->ega.vidtime; - } -} - void *pc1640_init() { pc1640_t *pc1640 = malloc(sizeof(pc1640_t)); @@ -123,8 +114,8 @@ void *pc1640_init() pc1640->cga.vram = pc1640->ega.vram; pc1640->cga_enabled = 1; cga_init(&pc1640->cga); + timer_disable(&pc1640->ega.timer); - timer_add(pc1640_poll, &pc1640->vidtime, TIMER_ALWAYS_ENABLED, pc1640); mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); mem_mapping_add(&pc1640->ega_mapping, 0, 0, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640); diff --git a/src/vid_pc200.c b/src/vid_pc200.c index 06f511d..8f59dfc 100644 --- a/src/vid_pc200.c +++ b/src/vid_pc200.c @@ -111,7 +111,6 @@ void *pc200_init() pc200->cga.vram = malloc(0x4000); cga_init(&pc200->cga); - timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); return pc200; diff --git a/src/vid_pcjr.c b/src/vid_pcjr.c index fb3643c..5a8fb7c 100644 --- a/src/vid_pcjr.c +++ b/src/vid_pcjr.c @@ -36,7 +36,8 @@ typedef struct pcjr_t int vsynctime, vadj; uint16_t ma, maback; - int dispontime, dispofftime, vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; int composite; @@ -168,8 +169,8 @@ void pcjr_recalctimings(pcjr_t *pcjr) _dispofftime = disptime - _dispontime; _dispontime *= CGACONST; _dispofftime *= CGACONST; - pcjr->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - pcjr->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + pcjr->dispontime = (uint64_t)_dispontime; + pcjr->dispofftime = (uint64_t)_dispofftime; } void pcjr_poll(void *p) @@ -189,7 +190,7 @@ void pcjr_poll(void *p) { // cgapal[0]=pcjr->col&15; // printf("Firstline %i Lastline %i pcjr->displine %i\n",firstline,lastline,pcjr->displine); - pcjr->vidtime += pcjr->dispofftime; + timer_advance_u64(&pcjr->timer, pcjr->dispofftime); pcjr->stat &= ~1; pcjr->linepos = 1; oldsc = pcjr->sc; @@ -435,7 +436,7 @@ void pcjr_poll(void *p) } else { - pcjr->vidtime += pcjr->dispontime; + timer_advance_u64(&pcjr->timer, pcjr->dispontime); if (pcjr->dispon) pcjr->stat |= 1; pcjr->linepos = 0; @@ -552,7 +553,7 @@ static void *pcjr_video_init() pcjr->memctrl = -1; - timer_add(pcjr_poll, &pcjr->vidtime, TIMER_ALWAYS_ENABLED, pcjr); + timer_add(&pcjr->timer, pcjr_poll, pcjr, 1); mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr); io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr); return pcjr; diff --git a/src/vid_s3.c b/src/vid_s3.c index 723cb47..e22e6cd 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1206,7 +1206,7 @@ void s3_recalctimings(svga_t *svga) else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; svga->interlace = svga->crtc[0x42] & 0x20; - svga->clock = cpuclock / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p); + svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p); switch (svga->crtc[0x67] >> 4) { diff --git a/src/vid_svga.c b/src/vid_svga.c index d94606f..8f774cf 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -433,8 +433,8 @@ void svga_recalctimings(svga_t *svga) _dispontime *= crtcconst; _dispofftime *= crtcconst; - svga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - svga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + svga->dispontime = (uint64_t)_dispontime; + svga->dispofftime = (uint64_t)_dispofftime; /* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); @@ -478,7 +478,7 @@ void svga_poll(void *p) svga->overlay_oddeven = 1; } - svga->vidtime += svga->dispofftime; + timer_advance_u64(&svga->timer, svga->dispofftime); // if (output) printf("Display off %f\n",vidtime); svga->cgastat |= 1; svga->linepos = 1; @@ -540,7 +540,7 @@ void svga_poll(void *p) else { // pclog("VC %i ma %05X\n", svga->vc, svga->ma); - svga->vidtime += svga->dispontime; + timer_advance_u64(&svga->timer, svga->dispontime); // if (output) printf("Display on %f\n",vidtime); if (svga->dispon) @@ -730,8 +730,8 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->crtc[0] = 63; svga->crtc[6] = 255; - svga->dispontime = 1000 * (1 << TIMER_SHIFT); - svga->dispofftime = 1000 * (1 << TIMER_SHIFT); + svga->dispontime = 1000ull << 32; + svga->dispofftime = 1000ull << 32; svga->bpp = 8; svga->vram = malloc(memsize); svga->vram_max = memsize; @@ -749,7 +749,7 @@ 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, MEM_MAPPING_EXTERNAL, svga); - timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); + timer_add(&svga->timer, svga_poll, svga, 1); svga_pri = svga; diff --git a/src/vid_svga.h b/src/vid_svga.h index db5f817..0c44fff 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -63,8 +63,8 @@ typedef struct svga_t uint32_t ma_latch; int bpp; - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; uint8_t scrblank; diff --git a/src/vid_t1000.c b/src/vid_t1000.c index def3eff..b97e092 100644 --- a/src/vid_t1000.c +++ b/src/vid_t1000.c @@ -13,6 +13,9 @@ #define T1000_XSIZE 640 #define T1000_YSIZE 200 +/*Very rough estimate*/ +#define VID_CLOCK (double)(651 * 216 * 60) + /* Mapping of attributes to colours */ static uint32_t blue, grey; static uint8_t boldcols[256]; /* Which attributes use the bold font */ @@ -65,7 +68,7 @@ typedef struct t1000_t int internal; /* Using internal display? */ uint8_t attrmap; /* Attribute mapping register */ - int dispontime, dispofftime; + uint64_t dispontime, dispofftime; int linepos, displine; int vc; @@ -176,8 +179,8 @@ static void t1000_recalctimings(t1000_t *t1000) disptime = 651; _dispontime = 640; _dispofftime = disptime - _dispontime; - t1000->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - t1000->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + t1000->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); + t1000->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); } /* Draw a row of text in 80-column mode */ @@ -446,7 +449,7 @@ static void t1000_poll(void *p) if (!t1000->linepos) { - t1000->cga.vidtime += t1000->dispofftime; + timer_advance_u64(&t1000->cga.timer, t1000->dispofftime); t1000->cga.cgastat |= 1; t1000->linepos = 1; if (t1000->dispon) @@ -493,7 +496,7 @@ static void t1000_poll(void *p) { t1000->cga.cgastat &= ~1; } - t1000->cga.vidtime += t1000->dispontime; + timer_advance_u64(&t1000->cga.timer, t1000->dispontime); t1000->linepos = 0; if (t1000->displine == 200) @@ -635,7 +638,8 @@ static void *t1000_init() /* 16k video RAM */ t1000->vram = malloc(0x4000); - timer_add(t1000_poll, &t1000->cga.vidtime, TIMER_ALWAYS_ENABLED, t1000); + timer_set_callback(&t1000->cga.timer, t1000_poll); + timer_set_p(&t1000->cga.timer, t1000); /* Occupy memory between 0xB8000 and 0xBFFFF */ mem_mapping_add(&t1000->mapping, 0xb8000, 0x8000, t1000_read, NULL, NULL, t1000_write, NULL, NULL, NULL, 0, t1000); diff --git a/src/vid_t3100e.c b/src/vid_t3100e.c index c1195b6..8a48450 100644 --- a/src/vid_t3100e.c +++ b/src/vid_t3100e.c @@ -13,6 +13,9 @@ #define T3100E_XSIZE 640 #define T3100E_YSIZE 400 +/*Very rough estimate*/ +#define VID_CLOCK (double)(651 * 416 * 60) + /* T3100e CRTC regs (from the ROM): * * Selecting a character height of 3 seems to be sufficient to convert the @@ -73,7 +76,7 @@ typedef struct t3100e_t int internal; /* Using internal display? */ uint8_t attrmap; /* Attribute mapping register */ - int dispontime, dispofftime; + uint64_t dispontime, dispofftime; int linepos, displine; int vc; @@ -186,8 +189,8 @@ void t3100e_recalctimings(t3100e_t *t3100e) disptime = 651; _dispontime = 640; _dispofftime = disptime - _dispontime; - t3100e->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - t3100e->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + t3100e->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); + t3100e->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); } @@ -481,7 +484,7 @@ void t3100e_poll(void *p) if (!t3100e->linepos) { - t3100e->cga.vidtime += t3100e->dispofftime; + timer_advance_u64(&t3100e->cga.timer, t3100e->dispofftime); t3100e->cga.cgastat |= 1; t3100e->linepos = 1; if (t3100e->dispon) @@ -528,7 +531,7 @@ void t3100e_poll(void *p) { t3100e->cga.cgastat &= ~1; } - t3100e->cga.vidtime += t3100e->dispontime; + timer_advance_u64(&t3100e->cga.timer, t3100e->dispontime); t3100e->linepos = 0; if (t3100e->displine == 400) @@ -672,7 +675,8 @@ void *t3100e_init() /* 32k video RAM */ t3100e->vram = malloc(0x8000); - timer_add(t3100e_poll, &t3100e->cga.vidtime, TIMER_ALWAYS_ENABLED, t3100e); + timer_set_callback(&t3100e->cga.timer, t3100e_poll); + timer_set_p(&t3100e->cga.timer, t3100e); /* Occupy memory between 0xB8000 and 0xBFFFF */ mem_mapping_add(&t3100e->mapping, 0xb8000, 0x8000, t3100e_read, NULL, NULL, t3100e_write, NULL, NULL, NULL, 0, t3100e); diff --git a/src/vid_tandy.c b/src/vid_tandy.c index 40a6034..d2cd49a 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -37,7 +37,8 @@ typedef struct tandy_t int vsynctime, vadj; uint16_t ma, maback; - int dispontime, dispofftime, vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; int composite; @@ -186,8 +187,8 @@ void tandy_recalctimings(tandy_t *tandy) _dispofftime = disptime - _dispontime; _dispontime *= CGACONST; _dispofftime *= CGACONST; - tandy->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - tandy->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + tandy->dispontime = (uint64_t)_dispontime; + tandy->dispofftime = (uint64_t)_dispofftime; } @@ -208,7 +209,7 @@ void tandy_poll(void *p) { // cgapal[0]=tandy->col&15; // printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); - tandy->vidtime += tandy->dispofftime; + timer_advance_u64(&tandy->timer, tandy->dispofftime); tandy->stat |= 1; tandy->linepos = 1; oldsc = tandy->sc; @@ -476,7 +477,7 @@ void tandy_poll(void *p) } else { - tandy->vidtime += tandy->dispontime; + timer_advance_u64(&tandy->timer, tandy->dispontime); if (tandy->dispon) tandy->stat &= ~1; tandy->linepos = 0; @@ -624,7 +625,7 @@ void *tandy_init() tandy->memctrl = -1; tandy->base = (mem_size - 128) * 1024; - timer_add(tandy_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy); + timer_add(&tandy->timer, tandy_poll, tandy, 1); mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, tandy); mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandy_ram_read, NULL, NULL, tandy_ram_write, NULL, NULL, NULL, 0, tandy); /*Base 128k mapping is controlled via port 0xA0, so we remove it from the main mapping*/ diff --git a/src/vid_tandysl.c b/src/vid_tandysl.c index 183fa5a..2a521b0 100644 --- a/src/vid_tandysl.c +++ b/src/vid_tandysl.c @@ -35,7 +35,8 @@ typedef struct tandysl_t int vsynctime, vadj; uint16_t ma, maback; - int dispontime, dispofftime, vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int firstline, lastline; } tandysl_t; @@ -249,8 +250,8 @@ static void tandysl_recalctimings(tandysl_t *tandy) _dispofftime = disptime - _dispontime; _dispontime *= CGACONST; _dispofftime *= CGACONST; - tandy->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - tandy->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + tandy->dispontime = (uint64_t)_dispontime; + tandy->dispofftime = (uint64_t)_dispofftime; } @@ -272,7 +273,7 @@ static void tandysl_poll(void *p) // 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; + timer_advance_u64(&tandy->timer, tandy->dispofftime); tandy->stat |= 1; tandy->linepos = 1; oldsc = tandy->sc; @@ -537,7 +538,7 @@ static void tandysl_poll(void *p) } else { - tandy->vidtime += tandy->dispontime; + timer_advance_u64(&tandy->timer, tandy->dispontime); if (tandy->dispon) tandy->stat &= ~1; tandy->linepos = 0; @@ -694,7 +695,7 @@ static void *tandysl_init() tandy->b8000_limit = 0x8000; tandy->planar_ctrl = 4; - timer_add(tandysl_poll, &tandy->vidtime, TIMER_ALWAYS_ENABLED, tandy); + timer_add(&tandy->timer, tandysl_poll, tandy, 1); mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandysl_read, NULL, NULL, tandysl_write, NULL, NULL, NULL, 0, tandy); mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandysl_ram_read, NULL, NULL, tandysl_ram_write, NULL, NULL, NULL, 0, tandy); /*Base 128k mapping is controlled via port 0xffe8, so we remove it from the main mapping*/ diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index e40cfa1..bbc5653 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -214,7 +214,7 @@ typedef struct voodoo_t uint16_t dac_pll_regs[16]; float pixel_clock; - int line_time; + uint64_t line_time; voodoo_params_t params; @@ -248,7 +248,7 @@ typedef struct voodoo_t int swap_count; int disp_buffer, draw_buffer; - int timer_count; + pc_timer_t timer; int line; svga_t *svga; @@ -386,7 +386,7 @@ typedef struct voodoo_t int read_time, write_time, burst_time; - int wake_timer; + pc_timer_t wake_timer; uint8_t thefilter[256][256]; // pixel filter, feeding from one or two uint8_t thefilterg[256][256]; // for green @@ -5860,15 +5860,13 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) #define WAKE_DELAY (TIMER_USEC * 100) static inline void wake_fifo_thread(voodoo_t *voodoo) { - if (!voodoo->wake_timer) + if (!timer_is_enabled(&voodoo->wake_timer)) { /*Don't wake FIFO thread immediately - if we do that it will probably process one word and go back to sleep, requiring it to be woken on almost every write. Instead, wait a short while so that the CPU emulation writes more data so we have more batched-up work.*/ - timer_process(); - voodoo->wake_timer = WAKE_DELAY; - timer_update_outstanding(); + timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); } } @@ -5881,8 +5879,6 @@ static void voodoo_wake_timer(void *p) { voodoo_t *voodoo = (voodoo_t *)p; - voodoo->wake_timer = 0; - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -6126,13 +6122,11 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) break; case SST_vRetrace: - timer_clock(); temp = voodoo->line & 0x1fff; break; case SST_hvRetrace: - timer_clock(); temp = voodoo->line & 0x1fff; - temp |= ((((voodoo->line_time - voodoo->timer_count) * voodoo->h_total) / voodoo->timer_count) << 16) & 0x7ff0000; + temp |= ((((tsc - timer_get_ts_int(&voodoo->timer)) * voodoo->h_total) / (voodoo->line_time >> 32)) << 16) & 0x7ff0000; break; case SST_fbiInit5: @@ -6208,7 +6202,7 @@ static void voodoo_pixelclock_update(voodoo_t *voodoo) voodoo->pixel_clock = t; clock_const = cpuclock / t; - voodoo->line_time = (int)((double)line_length * clock_const * (double)(1 << TIMER_SHIFT)); + voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32)); } static void voodoo_writel(uint32_t addr, uint32_t val, void *p) @@ -7440,9 +7434,9 @@ skip_draw: voodoo->v_retrace = 0; } if (voodoo->line_time) - voodoo->timer_count += voodoo->line_time; + timer_advance_u64(&voodoo->timer, voodoo->line_time); else - voodoo->timer_count += TIMER_USEC * 32; + timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); } static void voodoo_add_status_info(char *s, int max_len, void *p) @@ -7610,7 +7604,7 @@ void *voodoo_card_init() } } - timer_add(voodoo_callback, &voodoo->timer_count, TIMER_ALWAYS_ENABLED, voodoo); + timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); voodoo->svga = svga_get_pri(); voodoo->fbiInit0 = 0; @@ -7627,7 +7621,7 @@ void *voodoo_card_init() if (voodoo->render_threads == 2) voodoo->render_thread[1] = thread_create(render_thread_2, voodoo); - timer_add(voodoo_wake_timer, &voodoo->wake_timer, &voodoo->wake_timer, (void *)voodoo); + timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); for (c = 0; c < 0x100; c++) { diff --git a/src/vid_wy700.c b/src/vid_wy700.c index 107b134..a19f664 100644 --- a/src/vid_wy700.c +++ b/src/vid_wy700.c @@ -190,8 +190,8 @@ typedef struct wy700_t int enabled; /* Display enabled, 0 or 1 */ int detach; /* Detach cursor, 0 or 1 */ - int dispontime, dispofftime; - int vidtime; + uint64_t dispontime, dispofftime; + pc_timer_t timer; int linepos, displine; int vc; @@ -490,8 +490,8 @@ void wy700_recalctimings(wy700_t *wy700) _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - wy700->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); - wy700->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); + wy700->dispontime = (uint64_t)_dispontime; + wy700->dispofftime = (uint64_t)_dispofftime; } @@ -759,7 +759,7 @@ void wy700_poll(void *p) if (!wy700->linepos) { - wy700->vidtime += wy700->dispofftime; + timer_advance_u64(&wy700->timer, wy700->dispofftime); wy700->cga_stat |= 1; wy700->mda_stat |= 1; wy700->linepos = 1; @@ -820,7 +820,7 @@ void wy700_poll(void *p) wy700->cga_stat &= ~1; wy700->mda_stat &= ~1; } - wy700->vidtime += wy700->dispontime; + timer_advance_u64(&wy700->timer, wy700->dispontime); wy700->linepos = 0; if (wy700->displine == 800) @@ -868,7 +868,7 @@ void *wy700_init() /* 128k video RAM */ wy700->vram = malloc(0x20000); - timer_add(wy700_poll, &wy700->vidtime, TIMER_ALWAYS_ENABLED, wy700); + timer_add(&wy700->timer, wy700_poll, wy700, 1); /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ From 42d62925c3dde8fdc9e163afcc8fd67758def03c Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 2 Aug 2018 22:09:18 +0100 Subject: [PATCH 0492/1050] Fix compiler warnings on ARM builds. --- src/cdrom-ioctl-linux.c | 15 ++-------- src/codegen_backend_arm.c | 26 ++++++++--------- src/codegen_backend_arm_defs.h | 4 +-- src/codegen_backend_arm_uops.c | 52 +++++++++++++++++----------------- src/fdi2raw.c | 8 +++--- src/vid_voodoo.c | 2 ++ 6 files changed, 50 insertions(+), 57 deletions(-) diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c index 5876eca..f5299ff 100644 --- a/src/cdrom-ioctl-linux.c +++ b/src/cdrom-ioctl-linux.c @@ -14,7 +14,6 @@ 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[256]; static int toc_tracks; @@ -209,7 +208,7 @@ static int read_toc(int fd, struct cdrom_tocentry *btoc) 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(btoc)); + memset(btoc, 0, sizeof(struct cdrom_tocentry)); c = 0; for (track = 0; track < 256; track++) @@ -233,8 +232,6 @@ static int read_toc(int fd, struct cdrom_tocentry *btoc) static int ioctl_ready(void) { - long size; - int temp; struct cdrom_tochdr toc_hdr; struct cdrom_tocentry toc_entry; int err; @@ -266,7 +263,6 @@ static int ioctl_ready(void) (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(ioctl_fd, toc); @@ -306,8 +302,6 @@ static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, i static int ioctl_medium_changed(void) { - long size; - int temp; struct cdrom_tochdr toc_hdr; struct cdrom_tocentry toc_entry; int err; @@ -338,15 +332,12 @@ static int ioctl_medium_changed(void) 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) @@ -460,7 +451,6 @@ static void ioctl_readsector_raw(uint8_t *b, int sector) 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; uint32_t last_address = 0; @@ -644,7 +634,7 @@ static uint32_t ioctl_size() static int ioctl_status() { - if (!(ioctl_ready) && (cdrom_drive <= 0)) return CD_STATUS_EMPTY; + if (!ioctl_ready() && (cdrom_drive <= 0)) return CD_STATUS_EMPTY; switch(ioctl_cd_state) { @@ -653,6 +643,7 @@ static int ioctl_status() case CD_PAUSED: return CD_STATUS_PAUSED; case CD_STOPPED: + default: return CD_STATUS_STOPPED; } } diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 908c5e1..8b117d5 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -34,7 +34,7 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = static void build_load_routine(codeblock_t *block, int size) { uint32_t *branch_offset; - uint8_t *misaligned_offset; + uint32_t *misaligned_offset; /*In - R0 = address Out - R0 = data, R1 = abrt*/ @@ -73,7 +73,7 @@ static void build_load_routine(codeblock_t *block, int size) *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; if (size != 1) *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_SP, -4); + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); if (size == 1) host_arm_BL(block, (uintptr_t)readmemb386l); else if (size == 2) @@ -83,15 +83,15 @@ static void build_load_routine(codeblock_t *block, int size) else fatal("build_load_routine - unknown size %i\n", size); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_SP, 4); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); block_pos = (block_pos + 63) & ~63; } static void build_store_routine(codeblock_t *block, int size) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; /*In - R0 = address Out - R0 = data, R1 = abrt*/ @@ -130,7 +130,7 @@ static void build_store_routine(codeblock_t *block, int size) *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; if (size != 1) *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_SP, -4); + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); if (size == 1) host_arm_BL(block, (uintptr_t)writememb386l); else if (size == 2) @@ -140,7 +140,7 @@ static void build_store_routine(codeblock_t *block, int size) else fatal("build_store_routine - unknown size %i\n", size); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_SP, 4); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); block_pos = (block_pos + 63) & ~63; } @@ -221,15 +221,15 @@ void codegen_backend_prologue(codeblock_t *block) host_arm_nop(block); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x20); - host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC); + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); while (block_pos != BLOCK_START) host_arm_nop(block); /*Entry code*/ - host_arm_STMDB_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_LR); - host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x20); + host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); + host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); host_arm_ADD_IMM(block, REG_LITERAL, REG_PC, ARM_LITERAL_POOL_OFFSET); host_arm_SUB_IMM(block, REG_LITERAL, REG_LITERAL, 16 + BLOCK_START); offset = add_literal(block, (uintptr_t)&cpu_state); @@ -238,8 +238,8 @@ void codegen_backend_prologue(codeblock_t *block) void codegen_backend_epilogue(codeblock_t *block) { - host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x20); - host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC); + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); if (block_pos > ARM_LITERAL_POOL_OFFSET) fatal("Over limit!\n"); diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 3ec520b..8fb0215 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -11,7 +11,7 @@ #define REG_R10 10 #define REG_R11 11 #define REG_R12 12 -#define REG_SP 13 +#define REG_HOST_SP 13 #define REG_LR 14 #define REG_PC 15 @@ -38,7 +38,7 @@ #define REG_MASK_R10 (1 << REG_R10) #define REG_MASK_R11 (1 << REG_R11) #define REG_MASK_R12 (1 << REG_R12) -#define REG_MASK_SP (1 << REG_SP) +#define REG_MASK_SP (1 << REG_HOST_SP) #define REG_MASK_LR (1 << REG_LR) #define REG_MASK_PC (1 << REG_PC) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 0ec4c75..2e4ed9d 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -233,7 +233,7 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) } else fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm_BEQ(block, uop->p); + host_arm_BEQ(block, (uintptr_t)uop->p); return 0; } @@ -299,20 +299,20 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { - host_arm_BL(block, codegen_mem_load_byte); + host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); } else if (REG_IS_W(dest_size)) { - host_arm_BL(block, codegen_mem_load_word); + host_arm_BL(block, (uintptr_t)codegen_mem_load_word); } else if (REG_IS_L(dest_size)) { - host_arm_BL(block, codegen_mem_load_long); + host_arm_BL(block, (uintptr_t)codegen_mem_load_long); } else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); if (REG_IS_B(dest_size)) { host_arm_BFI(block, dest_reg, REG_R0, 0, 8); @@ -341,20 +341,20 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { - host_arm_BL(block, codegen_mem_load_byte); + host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); } else if (REG_IS_W(dest_size)) { - host_arm_BL(block, codegen_mem_load_word); + host_arm_BL(block, (uintptr_t)codegen_mem_load_word); } else if (REG_IS_L(dest_size)) { - host_arm_BL(block, codegen_mem_load_long); + host_arm_BL(block, (uintptr_t)codegen_mem_load_long); } else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); if (REG_IS_B(dest_size)) { host_arm_BFI(block, dest_reg, REG_R0, 0, 8); @@ -384,22 +384,22 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) if (REG_IS_B(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, codegen_mem_store_byte); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); } else if (REG_IS_W(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, codegen_mem_store_word); + host_arm_BL(block, (uintptr_t)codegen_mem_store_word); } else if (REG_IS_L(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, codegen_mem_store_long); + host_arm_BL(block, (uintptr_t)codegen_mem_store_long); } else fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); return 0; } @@ -413,27 +413,27 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) if (REG_IS_B(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, codegen_mem_store_byte); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); } else if (REG_IS_BH(src_size)) { host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); - host_arm_BL(block, codegen_mem_store_byte); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); } else if (REG_IS_W(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, codegen_mem_store_word); + host_arm_BL(block, (uintptr_t)codegen_mem_store_word); } else if (REG_IS_L(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, codegen_mem_store_long); + host_arm_BL(block, (uintptr_t)codegen_mem_store_long); } else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); return 0; } @@ -444,9 +444,9 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, codegen_mem_store_byte); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); return 0; } @@ -456,9 +456,9 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, codegen_mem_store_word); + host_arm_BL(block, (uintptr_t)codegen_mem_store_word); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); return 0; } @@ -468,9 +468,9 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, codegen_mem_store_long); + host_arm_BL(block, (uintptr_t)codegen_mem_store_long); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); return 0; } @@ -908,7 +908,7 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { if (stack_offset >= 0 && stack_offset < 4096) - host_arm_LDR_IMM(block, host_reg, REG_SP, stack_offset); + host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); else fatal("codegen_direct_read_32 - not in range\n"); } @@ -916,7 +916,7 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { if (stack_offset >= 0 && stack_offset < 4096) - host_arm_STR_IMM(block, host_reg, REG_SP, stack_offset); + host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); else fatal("codegen_direct_write_32 - not in range\n"); } diff --git a/src/fdi2raw.c b/src/fdi2raw.c index 8dfd819..8573f7e 100644 --- a/src/fdi2raw.c +++ b/src/fdi2raw.c @@ -1628,7 +1628,7 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi randval = rand(); if (randval < (RAND_MAX / 2)) { if (randval > (RAND_MAX / 4)) { - if (randval <= (3 * RAND_MAX / 8)) + if (randval <= (3 * (int64_t)RAND_MAX / 8)) randval = (2 * randval) - (RAND_MAX /4); else randval = (4 * randval) - RAND_MAX; @@ -1637,7 +1637,7 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi } else { randval -= RAND_MAX / 2; if (randval > (RAND_MAX / 4)) { - if (randval <= (3 * RAND_MAX / 8)) + if (randval <= (3 * (int64_t)RAND_MAX / 8)) randval = (2 * randval) - (RAND_MAX /4); else randval = (4 * randval) - RAND_MAX; @@ -1663,7 +1663,7 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi randval = rand(); if (randval < (RAND_MAX / 2)) { if (randval > (RAND_MAX / 4)) { - if (randval <= (3 * RAND_MAX / 8)) + if (randval <= (3 * (int64_t)RAND_MAX / 8)) randval = (2 * randval) - (RAND_MAX /4); else randval = (4 * randval) - RAND_MAX; @@ -1672,7 +1672,7 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi } else { randval -= RAND_MAX / 2; if (randval > (RAND_MAX / 4)) { - if (randval <= (3 * RAND_MAX / 8)) + if (randval <= (3 * (int64_t)RAND_MAX / 8)) randval = (2 * randval) - (RAND_MAX /4); else randval = (4 * randval) - RAND_MAX; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index bbc5653..8a1d76c 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -2659,7 +2659,9 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood int dither = params->fbzMode & FBZ_DITHER;*/ int texels; int c; +#ifndef NO_CODEGEN uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); +#endif int y_diff = SLI_ENABLED ? 2 : 1; if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || From a9d46d95ec573c7534b3fb44331d25e41f79905a Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 2 Aug 2018 22:09:57 +0100 Subject: [PATCH 0493/1050] Use MOVW/MOVT to load immediates on ARM instead of a literal pool. --- src/codegen_backend_arm.h | 4 +-- src/codegen_backend_arm_ops.c | 24 +++++-------- src/codegen_backend_arm_uops.c | 65 +++++----------------------------- 3 files changed, 19 insertions(+), 74 deletions(-) diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h index fd63315..1446594 100644 --- a/src/codegen_backend_arm.h +++ b/src/codegen_backend_arm.h @@ -2,7 +2,7 @@ #define BLOCK_SIZE 0x1000 #define BLOCK_MASK 0x0fff -#define BLOCK_START 32 +#define BLOCK_START 64 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff @@ -13,7 +13,7 @@ /*#define BLOCK_EXIT_OFFSET 0x7f0*/ #define BLOCK_GPF_OFFSET 0 -#define BLOCK_EXIT_OFFSET 16 +#define BLOCK_EXIT_OFFSET 32 #define ARM_LITERAL_POOL_OFFSET 0xf000 diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index f7772ae..b32556e 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -201,8 +201,7 @@ void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); } } @@ -226,8 +225,7 @@ void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); } } @@ -314,8 +312,7 @@ void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); } } @@ -338,8 +335,7 @@ void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); } } @@ -358,8 +354,7 @@ void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); } } @@ -457,8 +452,7 @@ void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_ORR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); } } @@ -519,8 +513,7 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); } } @@ -544,8 +537,7 @@ void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) } else { - int offset = add_literal(block, imm); - host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_TEMP, imm); host_arm_TST_REG(block, src_reg, REG_TEMP); } } diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 2e4ed9d..17f216b 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -49,8 +49,7 @@ static inline int in_range(void *addr, void *base) void host_arm_call(codeblock_t *block, void *dst_addr) { - int offset = add_literal(block, (uintptr_t)dst_addr); - host_arm_LDR_IMM(block, REG_R3, REG_LITERAL, offset); + host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr); host_arm_BLX(block, REG_R3); } @@ -240,54 +239,22 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - uint32_t arm_imm; - - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); - else - { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, REG_ARG0, REG_LITERAL, offset); - } + host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - uint32_t arm_imm; - - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); - else - { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, REG_ARG1, REG_LITERAL, offset); - } + host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - uint32_t arm_imm; - - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); - else - { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, REG_ARG2, REG_LITERAL, offset); - } + host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - uint32_t arm_imm; - - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); - else - { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, REG_ARG3, REG_LITERAL, offset); - } + host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); return 0; } @@ -519,15 +486,7 @@ static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size)) { - uint32_t arm_imm; - - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, dest_reg, uop->imm_data); - else - { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, dest_reg, REG_LITERAL, offset); - } + host_arm_MOV_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size)) { @@ -551,8 +510,7 @@ static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { - int offset = add_literal(block, (uintptr_t)uop->p); - host_arm_LDR_IMM(block, uop->dest_reg_a_real, REG_LITERAL, offset); + host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t)uop->p); return 0; } @@ -650,13 +608,8 @@ static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { uint32_t arm_imm; - if (get_arm_imm(uop->imm_data, &arm_imm)) - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - else - { - int offset = add_literal(block, uop->imm_data); - host_arm_LDR_IMM(block, REG_R0, REG_LITERAL, offset); - } + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + if (in_range(uop->p, &cpu_state)) host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); else From 4ada3382b41d881ef737db06d83cd7eecaf13590 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 3 Aug 2018 19:44:35 +0100 Subject: [PATCH 0494/1050] Fix inconsistent size of ide_fn array. --- src/esdi_at.c | 2 +- src/hdd_esdi.c | 2 +- src/mfm_at.c | 2 +- src/mfm_xebec.c | 2 +- src/scsi_hd.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/esdi_at.c b/src/esdi_at.c index c14ab7a..9002502 100644 --- a/src/esdi_at.c +++ b/src/esdi_at.c @@ -50,7 +50,7 @@ #define CMD_SET_PARAMETERS 0x91 #define CMD_READ_PARAMETERS 0xec -extern char ide_fn[4][512]; +extern char ide_fn[7][512]; typedef struct esdi_drive_t { diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 9465af1..6eb239a 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -26,7 +26,7 @@ #define CMD_ADAPTER 0 -extern char ide_fn[4][512]; +extern char ide_fn[7][512]; typedef struct esdi_t { diff --git a/src/mfm_at.c b/src/mfm_at.c index e3ad873..83fee43 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -46,7 +46,7 @@ #define CMD_DIAGNOSE 0x90 #define CMD_SET_PARAMETERS 0x91 -extern char ide_fn[4][512]; +extern char ide_fn[7][512]; typedef struct mfm_drive_t { diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index a60651e..51cec9e 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -23,7 +23,7 @@ #define XEBEC_TIME (2000 * TIMER_USEC) -extern char ide_fn[4][512]; +extern char ide_fn[7][512]; enum { diff --git a/src/scsi_hd.c b/src/scsi_hd.c index 074bdba..bf6412e 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -8,7 +8,7 @@ #include "scsi_hd.h" #include "timer.h" -extern char ide_fn[4][512]; +extern char ide_fn[7][512]; #define BUFFER_SIZE (256*1024) From f1df9be8f693eb90834b23389572391263a27aa9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 Aug 2018 16:24:15 +0100 Subject: [PATCH 0495/1050] Added recompiled versions of JMP, CALL, RET, PUSH and POP. --- src/Makefile.am | 3 +- src/codegen.c | 6 +- src/codegen.h | 2 +- src/codegen_backend_arm64_ops.c | 15 +++ src/codegen_backend_arm64_ops.h | 3 + src/codegen_backend_arm64_uops.c | 41 +++++- src/codegen_backend_arm_ops.c | 14 ++ src/codegen_backend_arm_ops.h | 3 + src/codegen_backend_arm_uops.c | 66 +++++++++- src/codegen_backend_x86-64_defs.h | 9 ++ src/codegen_backend_x86-64_ops.c | 63 ++++++++- src/codegen_backend_x86-64_ops.h | 7 +- src/codegen_backend_x86-64_uops.c | 36 +++++- src/codegen_backend_x86_ops.c | 58 +++++++++ src/codegen_backend_x86_ops.h | 6 + src/codegen_backend_x86_uops.c | 31 ++++- src/codegen_ir_defs.h | 17 ++- src/codegen_ops.c | 79 ++++++++++-- src/codegen_ops.h | 4 +- src/codegen_ops_arith.c | 46 +++---- src/codegen_ops_helpers.h | 43 +++++++ src/codegen_ops_jump.c | 130 +++++++++++++++++++ src/codegen_ops_jump.h | 12 ++ src/codegen_ops_logic.c | 36 +++--- src/codegen_ops_misc.c | 101 +++++++++++++++ src/codegen_ops_misc.h | 2 + src/codegen_ops_mov.c | 18 +-- src/codegen_ops_stack.c | 207 ++++++++++++++++++++++++++++++ src/codegen_ops_stack.h | 32 +++++ src/codegen_reg.c | 20 +++ src/codegen_reg.h | 26 +++- src/ibm.h | 2 +- src/x86seg.c | 28 ++-- 33 files changed, 1063 insertions(+), 103 deletions(-) create mode 100644 src/codegen_ops_helpers.h create mode 100644 src/codegen_ops_jump.c create mode 100644 src/codegen_ops_jump.h create mode 100644 src/codegen_ops_misc.c create mode 100644 src/codegen_ops_misc.h create mode 100644 src/codegen_ops_stack.c create mode 100644 src/codegen_ops_stack.h diff --git a/src/Makefile.am b/src/Makefile.am index 18da9e0..d465e30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,8 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_arith.c codegen_ops_logic.c codegen_ops_mov.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_arith.c codegen_ops_jump.c codegen_ops_logic.c \ +codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ diff --git a/src/codegen.c b/src/codegen.c index 5bd88bb..8a06538 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -238,14 +238,14 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin return op_ea_seg; } -x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset) { cpu_mod = (fetchdat >> 6) & 3; cpu_reg = (fetchdat >> 3) & 7; cpu_rm = fetchdat & 7; if (op_32 & 0x200) - return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, 0); + return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); } @@ -320,7 +320,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t { case 0x0f: op_table = x86_dynarec_opcodes_0f; - recomp_op_table = NULL;//recomp_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; over = 1; break; diff --git a/src/codegen.h b/src/codegen.h index 9503b25..7136330 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -264,7 +264,7 @@ void codegen_set_op32(); void codegen_flush(); void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); struct ir_data_t; -x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32); +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset); void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 0a6b8f8..cd57fd7 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -56,11 +56,13 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BFI (0x0cc << 22) #define OPCODE_LDR_IMM_W (0x2e5 << 22) #define OPCODE_LDRB_IMM_W (0x0e5 << 22) +#define OPCODE_LDRH_IMM (0x1e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) #define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22) #define OPCODE_STR_IMM_Q (0x3e4 << 22) #define OPCODE_STRB_IMM (0x0e4 << 22) +#define OPCODE_STRH_IMM (0x1e4 << 22) #define OPCODE_UBFX (0x14c << 22) #define OPCODE_ADD_LSL (0x058 << 21) @@ -104,6 +106,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) #define OFFSET12_B(offset) (offset << 10) +#define OFFSET12_H(offset) ((offset >> 1) << 10) #define OFFSET12_W(offset) ((offset >> 2) << 10) #define OFFSET12_Q(offset) ((offset >> 3) << 10) @@ -428,6 +431,12 @@ void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int off codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } +void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_h(offset)) + fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); +} void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); @@ -557,6 +566,12 @@ void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offs codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } +void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_h(offset)) + fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); +} void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 9fc993d..0bdbcb4 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -41,6 +41,7 @@ void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offs void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); +void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); @@ -69,6 +70,7 @@ void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offse void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); +void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); @@ -85,6 +87,7 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); #define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) #define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) +#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) & 1)) #define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) #define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index cd9f180..7b2ead8 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -208,6 +208,23 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int offset = add_literal_q(block, (uintptr_t)uop->p); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + + host_arm64_LDR_LITERAL_X(block, REG_ARG1, offset); + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + host_arm64_call(block, (void *)loadseg); + host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -731,6 +748,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, @@ -776,7 +794,13 @@ void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_8 - not in range\n"); } - +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_16 - not in range\n"); +} void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) @@ -792,7 +816,13 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) else fatal("codegen_direct_write_8 - not in range\n"); } - +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_16 - not in range\n"); +} void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) @@ -809,6 +839,13 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) fatal("codegen_direct_write_ptr - not in range\n"); } +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + if (in_range12_h(stack_offset)) + host_arm64_LDRH_IMM(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); +} void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { if (in_range12_w(stack_offset)) diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index b32556e..83817a7 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -71,7 +71,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BFI 0xe7c00010 #define OPCODE_BLX 0xe12fff30 +#define OPCODE_LDRH_IMM 0xe1d000b0 #define OPCODE_LDRH_REG 0xe19000b0 +#define OPCODE_STRH_IMM 0xe1c000b0 #define OPCODE_STRH_REG 0xe18000b0 #define OPCODE_UADD8 0xe6500f90 #define OPCODE_UADD16 0xe6500f10 @@ -210,6 +212,10 @@ void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr { codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } +void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { @@ -398,6 +404,10 @@ void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int of codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } +void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); +} void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) { codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); @@ -494,6 +504,10 @@ void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int of codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } +void host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +{ + codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); +} void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) { codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 31aee46..dd74e0d 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -1,6 +1,7 @@ void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); #define host_arm_ADD_REG(block, dst_reg, src_reg_n, src_reg_m) host_arm_ADD_REG_LSL(block, dst_reg, src_reg_n, src_reg_m, 0) void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); @@ -38,6 +39,7 @@ void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset #define host_arm_LDRB_REG(block, dst_reg, addr_reg, offset_reg) host_arm_LDRB_REG_LSL(block, dst_reg, addr_reg, offset_reg, 0) void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift); +void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg); void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm); @@ -65,6 +67,7 @@ void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset #define host_arm_STRB_REG(block, src_reg, addr_reg, offset_reg) host_arm_STRB_REG_LSL(block, src_reg, addr_reg, offset_reg, 0) void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift); +void host_arm_STRH_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset); void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg); void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 17f216b..7a98bf1 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -47,6 +47,15 @@ static inline int in_range(void *addr, void *base) return 1; } +static inline int in_range_h(void *addr, void *base) +{ + int diff = (uintptr_t)addr - (uintptr_t)base; + + if (diff < 0 || diff > 255) + return 0; + return 1; +} + void host_arm_call(codeblock_t *block, void *dst_addr) { host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr); @@ -89,6 +98,11 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); @@ -258,6 +272,22 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p); + host_arm_call(block, loadseg); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -606,8 +636,6 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { - uint32_t arm_imm; - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); if (in_range(uop->p, &cpu_state)) @@ -670,8 +698,8 @@ static int codegen_SUB(codeblock_t *block, uop_t *uop) } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); } else @@ -789,6 +817,8 @@ const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, @@ -826,6 +856,16 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +{ + if (in_range_h(p, &cpu_state)) + host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } +} void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { if (in_range(p, &cpu_state)) @@ -841,7 +881,16 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) else fatal("codegen_direct_write_8 - not in range\n"); } - +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +{ + if (in_range_h(p, &cpu_state)) + host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } +} void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { if (in_range(p, &cpu_state)) @@ -858,6 +907,13 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) fatal("codegen_direct_write_ptr - not in range\n"); } +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + if (stack_offset >= 0 && stack_offset < 256) + host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); +} void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { if (stack_offset >= 0 && stack_offset < 4096) diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index 706c70d..ee6df65 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -1,3 +1,12 @@ +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 + #define REG_EAX 0 #define REG_ECX 1 #define REG_EDX 2 diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 9262541..bbd80ff 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -395,6 +395,28 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) codegen_addlong(block, (uint32_t)(uintptr_t)p); } } +void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOV16_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + } +} void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -459,6 +481,27 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_r codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ } +void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOV16_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } + else + { + fatal("host_x86_MOV16_REG_ABS - out of range\n"); + } +} void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -501,10 +544,28 @@ void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int ba codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ } +void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); +} void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); if (offset >= -128 && offset < 127) { diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 4b67841..9bf56c5 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -34,6 +34,7 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg); @@ -41,12 +42,16 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale); +void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); +void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); + void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data); void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data); void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data); @@ -69,8 +74,6 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); - void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d0efa31..a0e1c1f 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -191,6 +191,27 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +#if WIN64 + host_x86_MOV16_REG_REG(block, REG_CX, src_reg); + host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p); +#else + host_x86_MOV16_REG_REG(block, REG_DI, src_reg); + host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t)uop->p); +#endif + host_x86_CALL(block, (void *)loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -595,6 +616,8 @@ const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, @@ -632,6 +655,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV16_REG_ABS(block, host_reg, p); +} void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); @@ -641,7 +668,10 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { host_x86_MOV8_ABS_REG(block, p, host_reg); } - +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV16_ABS_REG(block, p, host_reg); +} void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); @@ -652,6 +682,10 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) host_x86_MOV64_ABS_REG(block, p, host_reg); } +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); +} void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index bcc16ef..49ca53b 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -364,6 +364,20 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) codegen_addlong(block, (uint32_t)p); } } +void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } +} void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -393,6 +407,20 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ } +void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } +} void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -420,6 +448,21 @@ void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ } +void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); +} void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { if (offset >= -128 && offset < 127) @@ -435,6 +478,21 @@ void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); } +void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + else + fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); +} void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { if (offset >= -128 && offset < 127) diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 8d3df16..d4f4d66 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -34,20 +34,24 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); +void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift); void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); @@ -58,6 +62,8 @@ void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +#define host_x86_MOV16_STACK_REG(block, offset, src_reg) host_x86_MOV16_BASE_OFFSET_REG(block, REG_ESP, offset, src_reg) + void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c5f3f80..e88f81d 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -194,6 +194,22 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); + host_x86_CALL(block, loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -593,6 +609,8 @@ const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, @@ -630,6 +648,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV16_REG_ABS(block, host_reg, p); +} void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); @@ -639,7 +661,10 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { host_x86_MOV8_ABS_REG(block, p, host_reg); } - +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV16_ABS_REG(block, p, host_reg); +} void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); @@ -650,6 +675,10 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); +} void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index a864468..dc92a77 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -39,6 +39,8 @@ #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) #define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) #define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) +/*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/ +#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) /*UOP_MOV_PTR - dest_reg = p*/ #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ @@ -250,6 +252,15 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p uop->imm_data = imm; } +static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->p = p; +} + static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) { uop_t *uop = uop_alloc(ir); @@ -281,6 +292,8 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) +#define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) + #define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) #define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg) #define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) @@ -297,13 +310,15 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) - +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 6fc74b4..867108f 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -3,52 +3,103 @@ #include "codegen_ir.h" #include "codegen_ops.h" #include "codegen_ops_arith.h" +#include "codegen_ops_jump.h" #include "codegen_ops_logic.h" +#include "codegen_ops_misc.h" #include "codegen_ops_mov.h" +#include "codegen_ops_stack.h" RecompOpFn recomp_opcodes[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, NULL, NULL, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16, /*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, ropPOP_W, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, + +/*c0*/ NULL, NULL, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32, +/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, +/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, ropPOP_L, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, + +/*c0*/ NULL, NULL, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 +}; + + +RecompOpFn recomp_opcodes_0f[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL, +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, +/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, NULL, NULL, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, NULL, NULL, +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, -/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL, +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, +/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 1229ce4..1534a38 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -8,8 +8,8 @@ struct ir_data_t; typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); extern RecompOpFn recomp_opcodes[512]; -/*extern RecompOpFn recomp_opcodes_0f[512]; -extern RecompOpFn recomp_opcodes_d8[512]; +extern RecompOpFn recomp_opcodes_0f[512]; +/*extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; extern RecompOpFn recomp_opcodes_db[512]; diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 9e7fb43..7331afc 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -64,7 +64,7 @@ uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); @@ -95,7 +95,7 @@ uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); @@ -127,7 +127,7 @@ uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); @@ -158,7 +158,7 @@ uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); @@ -190,7 +190,7 @@ uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); @@ -220,7 +220,7 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); @@ -291,7 +291,7 @@ uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); @@ -322,7 +322,7 @@ uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); @@ -353,7 +353,7 @@ uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); @@ -384,7 +384,7 @@ uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); @@ -415,7 +415,7 @@ uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); @@ -445,7 +445,7 @@ uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV(ir, IREG_flags_op1, IREG_temp0); @@ -515,7 +515,7 @@ uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); @@ -546,7 +546,7 @@ uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); @@ -578,7 +578,7 @@ uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); @@ -609,7 +609,7 @@ uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); @@ -641,7 +641,7 @@ uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); @@ -671,7 +671,7 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); @@ -751,7 +751,7 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch uint8_t imm; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); if ((fetchdat & 0x38) == 0x38) /*CMP*/ codegen_check_seg_read(block, ir, target_seg); else @@ -880,7 +880,7 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint16_t imm; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); if ((fetchdat & 0x38) == 0x38) /*CMP*/ codegen_check_seg_read(block, ir, target_seg); else @@ -1008,7 +1008,7 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t imm; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); if ((fetchdat & 0x38) == 0x38) /*CMP*/ codegen_check_seg_read(block, ir, target_seg); else @@ -1137,7 +1137,7 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint16_t imm; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); if ((fetchdat & 0x38) == 0x38) /*CMP*/ codegen_check_seg_read(block, ir, target_seg); else @@ -1266,7 +1266,7 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); if ((fetchdat & 0x38) == 0x38) /*CMP*/ codegen_check_seg_read(block, ir, target_seg); else diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h new file mode 100644 index 0000000..55cb99a --- /dev/null +++ b/src/codegen_ops_helpers.h @@ -0,0 +1,43 @@ +static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) +{ + if (stack32) + { + if (offset) + { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset); + return IREG_eaaddr; + } + else + return IREG_ESP; + } + else + { + if (offset) + { + uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset); + uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W); + return IREG_eaaddr; + } + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + return IREG_eaaddr; + } + } + +} + +static inline void ADD_SP(ir_data_t *ir, int offset) +{ + if (stack32) + uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset); + else + uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset); +} +static inline void SUB_SP(ir_data_t *ir, int offset) +{ + if (stack32) + uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset); + else + uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); +} diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c new file mode 100644 index 0000000..8ae6816 --- /dev/null +++ b/src/codegen_ops_jump.c @@ -0,0 +1,130 @@ +#include "ibm.h" + +#include "x86.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_helpers.h" +#include "codegen_ops_mov.h" + +uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + + uop_MOV_IMM(ir, IREG_pc, op_pc+1+offset); + return -1; +} +uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_pc, op_pc+2+offset); + return -1; +} +uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = fastreadl(cs + op_pc); + + uop_MOV_IMM(ir, IREG_pc, op_pc+4+offset); + return -1; +} + +uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); + uint16_t ret_addr = op_pc + 2; + uint16_t dest_addr = ret_addr + offset; + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + + return -1; +} +uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = fastreadl(cs + op_pc); + uint32_t ret_addr = op_pc + 4; + uint32_t dest_addr = ret_addr + offset; + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + + return -1; +} + +uint32_t ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + + return -1; +} +uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4); + + return -1; +} + +uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t offset = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2+offset); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + + return -1; +} +uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t offset = fastreadw(cs + op_pc); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4+offset); + + return -1; +} diff --git a/src/codegen_ops_jump.h b/src/codegen_ops_jump.h new file mode 100644 index 0000000..ee6a591 --- /dev/null +++ b/src/codegen_ops_jump.h @@ -0,0 +1,12 @@ +uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c index df4a3de..a9f2021 100644 --- a/src/codegen_ops_logic.c +++ b/src/codegen_ops_logic.c @@ -56,7 +56,7 @@ uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); @@ -84,7 +84,7 @@ uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); @@ -113,7 +113,7 @@ uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); @@ -141,7 +141,7 @@ uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); @@ -170,7 +170,7 @@ uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); @@ -198,7 +198,7 @@ uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); @@ -261,7 +261,7 @@ uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); @@ -289,7 +289,7 @@ uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); @@ -318,7 +318,7 @@ uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); @@ -346,7 +346,7 @@ uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); @@ -375,7 +375,7 @@ uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); @@ -403,7 +403,7 @@ uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); @@ -466,7 +466,7 @@ uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); @@ -494,7 +494,7 @@ uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); @@ -523,7 +523,7 @@ uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); @@ -551,7 +551,7 @@ uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); @@ -580,7 +580,7 @@ uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); @@ -608,7 +608,7 @@ uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c new file mode 100644 index 0000000..524fc71 --- /dev/null +++ b/src/codegen_ops_misc.c @@ -0,0 +1,101 @@ +#include "ibm.h" + +#include "x86.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_helpers.h" +#include "codegen_ops_misc.h" + +uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg, sp_reg; + + if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + return 0; + + if ((fetchdat & 0xc0) == 0xc0) + src_reg = IREG_16(fetchdat & 7); + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } + + switch (fetchdat & 0x38) + { + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; + + case 0x20: /*JMP*/ + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; + + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 2); + return -1; + } + return 0; +} + +uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg, sp_reg; + + if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + return 0; + + if ((fetchdat & 0xc0) == 0xc0) + src_reg = IREG_32(fetchdat & 7); + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0; + } + + switch (fetchdat & 0x38) + { + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 4); + uop_MOV(ir, IREG_pc, src_reg); + return -1; + + case 0x20: /*JMP*/ + uop_MOV(ir, IREG_pc, src_reg); + return -1; + + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 4); + return -1; + } + return 0; +} diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h new file mode 100644 index 0000000..b86c246 --- /dev/null +++ b/src/codegen_ops_misc.h @@ -0,0 +1,2 @@ +uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index 7073578..69fa5f7 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -48,7 +48,7 @@ uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); } @@ -69,7 +69,7 @@ uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); } @@ -90,7 +90,7 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); } @@ -111,7 +111,7 @@ uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } @@ -132,7 +132,7 @@ uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } @@ -153,7 +153,7 @@ uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t x86seg *target_seg; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } @@ -268,7 +268,7 @@ uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ else { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); imm = fastreadb(cs + op_pc + 1); uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); @@ -291,7 +291,7 @@ uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ else { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); imm = fastreadw(cs + op_pc + 1); uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); @@ -314,7 +314,7 @@ uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ else { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); imm = fastreadl(cs + op_pc + 1); uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c new file mode 100644 index 0000000..06391c4 --- /dev/null +++ b/src/codegen_ops_stack.c @@ -0,0 +1,207 @@ +#include "ibm.h" + +#include "x86.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_helpers.h" +#include "codegen_ops_misc.h" + +uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); + SUB_SP(ir, 2); + + return op_pc; +} +uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); + SUB_SP(ir, 4); + + return op_pc; +} + +uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_SP) + ADD_SP(ir, 2); + + return op_pc; +} +uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_ESP) + ADD_SP(ir, 4); + + return op_pc; +} + +uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if ((fetchdat & 0xc0) == 0xc0) + { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } + else + { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); + codegen_check_seg_write(block, ir, target_seg); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); + } + + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + } + + if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) + ADD_SP(ir, 2); + + return op_pc + 1; +} +uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if ((fetchdat & 0xc0) == 0xc0) + { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } + else + { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); + codegen_check_seg_write(block, ir, target_seg); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + else + { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); + } + + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } + + if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) + ADD_SP(ir, 4); + + return op_pc + 1; +} + +#define ROP_PUSH_SEG(seg) \ +uint32_t ropPUSH_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_ ## seg ## _seg_W); \ + SUB_SP(ir, 2); \ + \ + return op_pc; \ +} \ +uint32_t ropPUSH_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ + uop_MOVZX(ir, IREG_temp0, IREG_ ## seg ## _seg_W); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ + SUB_SP(ir, 4); \ + \ + return op_pc; \ +} + +#define ROP_POP_SEG(seg, rseg) \ +uint32_t ropPOP_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else \ + { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 2); \ + \ + return op_pc; \ +} \ +uint32_t ropPOP_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else \ + { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 4); \ + \ + return op_pc; \ +} + + +ROP_PUSH_SEG(CS) +ROP_PUSH_SEG(DS) +ROP_PUSH_SEG(ES) +ROP_PUSH_SEG(FS) +ROP_PUSH_SEG(GS) +ROP_PUSH_SEG(SS) +ROP_POP_SEG(DS, cpu_state.seg_ds) +ROP_POP_SEG(ES, cpu_state.seg_es) +ROP_POP_SEG(FS, cpu_state.seg_fs) +ROP_POP_SEG(GS, cpu_state.seg_gs) diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h new file mode 100644 index 0000000..319fb17 --- /dev/null +++ b/src/codegen_ops_stack.h @@ -0,0 +1,32 @@ +uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPUSH_CS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_DS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_ES_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_FS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_GS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_SS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPUSH_CS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_DS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_ES_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_FS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_GS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_SS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPOP_DS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_ES_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_FS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_GS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPOP_DS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_ES_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_FS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOP_GS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 8bbf3ca..36b5ad8 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -64,6 +64,13 @@ struct [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base}, [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base}, + [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg}, + [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg}, + [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg}, + [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg}, + [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg}, + [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ @@ -98,6 +105,13 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) { switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { + case REG_WORD: + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_16_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_16(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; + case REG_DWORD: if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) codegen_direct_read_32_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); @@ -126,6 +140,12 @@ static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate) codegen_direct_write_8(block, p, codegen_host_reg_list[c]); break; + case REG_WORD: + if ((uintptr_t)p < 256) + fatal("codegen_reg_writeback - REG_WORD %p\n", p); + codegen_direct_write_16(block, p, codegen_host_reg_list[c]); + break; + case REG_DWORD: if ((uintptr_t)p < 256) codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index c57a0e5..e55d73a 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -49,13 +49,20 @@ enum IREG_GS_base = 25, IREG_SS_base = 26, + IREG_CS_seg = 27, + IREG_DS_seg = 28, + IREG_ES_seg = 29, + IREG_FS_seg = 30, + IREG_GS_seg = 31, + IREG_SS_seg = 32, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - IREG_temp0 = 27, - IREG_temp1 = 28, - IREG_temp2 = 29, - IREG_temp3 = 30, + IREG_temp0 = 33, + IREG_temp1 = 34, + IREG_temp2 = 35, + IREG_temp3 = 36, IREG_COUNT, @@ -88,7 +95,16 @@ enum IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, - IREG_temp1_B = IREG_temp1 + IREG_SIZE_B + IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, + + IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, + + IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, + IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W, + IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, + IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, + IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, + IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) diff --git a/src/ibm.h b/src/ibm.h index e852ac1..de79af6 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -236,7 +236,7 @@ uint8_t *pccache2; #define CPL ((cpu_state.seg_cs.access>>5)&3) -void loadseg(uint16_t seg, x86seg *s); +int loadseg(uint16_t seg, x86seg *s); void loadcs(uint16_t seg); union diff --git a/src/x86seg.c b/src/x86seg.c index 68b0d49..b508b87 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -309,7 +309,7 @@ static void check_seg_valid(x86seg *s) loadseg(0, s); } -void loadseg(uint16_t seg, x86seg *s) +int loadseg(uint16_t seg, x86seg *s) { uint16_t segdat[4]; uint32_t addr; @@ -324,7 +324,7 @@ void loadseg(uint16_t seg, x86seg *s) { pclog("SS selector = NULL!\n"); x86ss(NULL,0); - return; + return 1; // dumpregs(); // exit(-1); } @@ -335,7 +335,7 @@ void loadseg(uint16_t seg, x86seg *s) if (s == &cpu_state.seg_ds) cpu_cur_status |= CPU_STATUS_NOTFLATDS; // 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,pc); - return; + return 0; } // if (s==&_ss) pclog("Load SS %04X\n",seg); // pclog("Protected mode seg load!\n"); @@ -349,7 +349,7 @@ void loadseg(uint16_t seg, x86seg *s) // dumpregs(); // exit(-1); x86gpf(NULL,seg&~3); - return; + return 1; } addr+=ldt.base; } @@ -361,7 +361,7 @@ void loadseg(uint16_t seg, x86seg *s) // dumpregs(); // exit(-1); x86gpf(NULL,seg&~3); - return; + return 1; } addr+=gdt.base; } @@ -369,7 +369,7 @@ void loadseg(uint16_t seg, x86seg *s) segdat[0]=readmemw(0,addr); 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; + segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return 1; dpl=(segdat[2]>>13)&3; if (s==&cpu_state.seg_ss) { @@ -377,14 +377,14 @@ void loadseg(uint16_t seg, x86seg *s) { pclog("Load SS null selector\n"); x86gpf(NULL,seg&~3); - return; + return 1; } 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; + return 1; } switch ((segdat[2]>>8)&0x1F) { @@ -394,13 +394,13 @@ void loadseg(uint16_t seg, x86seg *s) pclog("Invalid SS type\n"); x86gpf(NULL,seg&~3); // x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC); - return; + return 1; } if (!(segdat[2]&0x8000)) { pclog("Load SS not present!\n"); x86ss(NULL,seg&~3); - return; + return 1; } set_stack32((segdat[3] & 0x40) ? 1 : 0); // pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]); @@ -420,7 +420,7 @@ void loadseg(uint16_t seg, x86seg *s) 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; + return 1; } break; case 0x1E: case 0x1F: /*Readable conforming code*/ @@ -428,14 +428,14 @@ void loadseg(uint16_t seg, x86seg *s) default: pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]); x86gpf(NULL,seg&~3); - return; + return 1; } } if (!(segdat[2] & 0x8000)) { x86np("Load data seg not present", seg & 0xfffc); - return; + return 1; } s->seg = seg; do_seg_load(s, segdat); @@ -486,6 +486,8 @@ void loadseg(uint16_t seg, x86seg *s) else cpu_cur_status |= CPU_STATUS_NOTFLATSS; } + + return cpu_state.abrt; } #define DPL ((segdat[2]>>13)&3) From 57e5549f48b91acc8cec86e3805745dce710a42f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 Aug 2018 16:24:48 +0100 Subject: [PATCH 0496/1050] Remove final remnants of ARM literal pool, and expand work register set to 7 registers. --- src/codegen_backend_arm.c | 18 ++++++------------ src/codegen_backend_arm.h | 2 +- src/codegen_backend_arm_defs.h | 3 +-- src/codegen_backend_arm_ops.c | 28 ++-------------------------- 4 files changed, 10 insertions(+), 41 deletions(-) diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 8b117d5..fb2d6f2 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -29,6 +29,10 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_R4, REG_R5, REG_R6, + REG_R7, + REG_R8, + REG_R9, + REG_R11, }; static void build_load_routine(codeblock_t *block, int size) @@ -203,14 +207,9 @@ void codegen_backend_init() build_loadstore_routines(&codeblock[block_current]); } -/*R11 - literal pool - R10 - cpu_state*/ +/*R10 - cpu_state*/ void codegen_backend_prologue(codeblock_t *block) { - int offset; - - codegen_reset_literal_pool(block); - block_pos = 0; block_pos = BLOCK_GPF_OFFSET; @@ -230,10 +229,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); - host_arm_ADD_IMM(block, REG_LITERAL, REG_PC, ARM_LITERAL_POOL_OFFSET); - host_arm_SUB_IMM(block, REG_LITERAL, REG_LITERAL, 16 + BLOCK_START); - offset = add_literal(block, (uintptr_t)&cpu_state); - host_arm_LDR_IMM(block, REG_CPUSTATE, REG_R11, offset); + host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t)&cpu_state); } void codegen_backend_epilogue(codeblock_t *block) @@ -244,8 +240,6 @@ void codegen_backend_epilogue(codeblock_t *block) if (block_pos > ARM_LITERAL_POOL_OFFSET) fatal("Over limit!\n"); - - __clear_cache(&block->data[0], &block->data[block_pos]); } diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h index 1446594..67d18e6 100644 --- a/src/codegen_backend_arm.h +++ b/src/codegen_backend_arm.h @@ -15,7 +15,7 @@ #define BLOCK_GPF_OFFSET 0 #define BLOCK_EXIT_OFFSET 32 -#define ARM_LITERAL_POOL_OFFSET 0xf000 +#define ARM_LITERAL_POOL_OFFSET 0x10000 /*#define BLOCK_MAX 1720*/ #define BLOCK_MAX 65208 diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 8fb0215..e094838 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -21,7 +21,6 @@ #define REG_ARG3 REG_R3 #define REG_CPUSTATE REG_R10 -#define REG_LITERAL REG_R11 #define REG_TEMP REG_R3 @@ -45,7 +44,7 @@ #define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) -#define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_REGS 7 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 83817a7..ae4e0d2 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -105,32 +105,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define MOVT_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) #define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) -static int literal_offset = 0; -void codegen_reset_literal_pool(codeblock_t *block) -{ - literal_offset = 0; -} - -int add_literal(codeblock_t *block, uint32_t data) -{ - int c; - - if (literal_offset >= 4096) - fatal("add_literal - literal pool full\n"); - - /*Search for pre-existing value*/ - for (c = 0; c < literal_offset; c += 4) - { - if (*(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + c] == data) - return c; - } - - *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; - - literal_offset += 4; - - return literal_offset - 4; -} +#define LDRH_IMM(imm) (((imm) & 0xf) | (((imm) & 0xf0) << 4)) +#define STRH_IMM(imm) LDRH_IMM(imm) static inline uint32_t arm_data_offset(int offset) From 9bba93e0bed65b0c06defe1de36d2180fa95ac45 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 8 Aug 2018 22:14:22 +0100 Subject: [PATCH 0497/1050] Added recompiled versions of LEA, MOV seg, MOVZX, NEG, NOP, NOT, PUSH imm, TEST and XCHG. --- src/codegen_backend_arm64_uops.c | 44 +++++ src/codegen_backend_arm_ops.c | 22 +++ src/codegen_backend_arm_ops.h | 2 + src/codegen_backend_arm_uops.c | 58 ++++++ src/codegen_backend_x86-64_ops.c | 12 +- src/codegen_backend_x86-64_ops.h | 1 + src/codegen_backend_x86-64_uops.c | 28 ++- src/codegen_backend_x86_ops.c | 4 + src/codegen_backend_x86_ops.h | 1 + src/codegen_backend_x86_uops.c | 28 ++- src/codegen_ops.c | 24 +-- src/codegen_ops_logic.c | 111 +++++++++++ src/codegen_ops_logic.h | 7 + src/codegen_ops_misc.c | 239 ++++++++++++++++++++++- src/codegen_ops_misc.h | 9 + src/codegen_ops_mov.c | 307 ++++++++++++++++++++++++++++++ src/codegen_ops_mov.h | 15 ++ src/codegen_ops_stack.c | 50 +++++ src/codegen_ops_stack.h | 5 + 19 files changed, 938 insertions(+), 29 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 7b2ead8..620cdd2 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -127,6 +127,34 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -149,6 +177,12 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); @@ -494,6 +528,16 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index ae4e0d2..801b99a 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -216,12 +216,34 @@ void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr { codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } +void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); } +void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else if (get_arm_imm(~imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index dd74e0d..43df4d1 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -5,9 +5,11 @@ void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int sr void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); +void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 7a98bf1..efc987f 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -194,6 +194,32 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) + { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -220,6 +246,22 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -562,6 +604,22 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { host_arm_UXTH(block, dest_reg, src_reg, 0); } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + if (src_reg == dest_reg) + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + else + { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } + else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index bbd80ff..490e100 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -242,21 +242,21 @@ void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } @@ -688,6 +688,12 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); } +void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { if ((dst_reg & 8) || (src_reg & 8)) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 9bf56c5..dc95269 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -69,6 +69,7 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); +void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index a0e1c1f..fb1256f 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -98,15 +98,21 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_AND32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -121,15 +127,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -445,6 +457,10 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } else fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 49ca53b..e0ffc0f 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -599,6 +599,10 @@ void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) } } +void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index d4f4d66..2d7e53d 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -66,6 +66,7 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); +void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index e88f81d..b46fcb8 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -108,15 +108,21 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_AND32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -131,15 +137,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } else fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -442,6 +454,10 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } else fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); return 0; diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 867108f..0315251 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -20,18 +20,18 @@ RecompOpFn recomp_opcodes[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8,NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, ropPOP_W, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, +/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, /*c0*/ NULL, NULL, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -42,18 +42,18 @@ RecompOpFn recomp_opcodes[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8,NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, ropPOP_L, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, +/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, /*c0*/ NULL, NULL, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 }; @@ -74,7 +74,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -96,7 +96,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c index a9f2021..8f402f1 100644 --- a/src/codegen_ops_logic.c +++ b/src/codegen_ops_logic.c @@ -418,6 +418,117 @@ uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc + 1; } +uint32_t ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 2; +} +uint32_t ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h index cfb7af3..d86fbb4 100644 --- a/src/codegen_ops_logic.h +++ b/src/codegen_ops_logic.h @@ -18,6 +18,13 @@ uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 524fc71..01c404f 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -1,6 +1,7 @@ #include "ibm.h" #include "x86.h" +#include "x86_flags.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -8,6 +9,235 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_misc.h" +uint32_t ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + return 0; + + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); + + return op_pc + 1; +} +uint32_t ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + return 0; + + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); + + return op_pc + 1; +} + +uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm_data; + int reg; + + if (fetchdat & 0x20) + return 0; + + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_8(fetchdat & 7); + else + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_B; + } + + switch (fetchdat & 0x38) + { + case 0x00: case 0x08: /*TEST*/ + imm_data = fastreadb(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc+2; + + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + + codegen_flags_changed = 1; + return op_pc+1; + + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_B, 0); + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV(ir, reg, IREG_temp1_B); + } + else + { + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOV_IMM(ir, IREG_flags_op1, 0); + + codegen_flags_changed = 1; + return op_pc+1; + } + return 0; +} +uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint16_t imm_data; + int reg; + + if (fetchdat & 0x20) + return 0; + + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_16(fetchdat & 7); + else + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_W; + } + + switch (fetchdat & 0x38) + { + case 0x00: case 0x08: /*TEST*/ + imm_data = fastreadw(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc+3; + + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + + codegen_flags_changed = 1; + return op_pc+1; + + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_W, 0); + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV(ir, reg, IREG_temp1_W); + } + else + { + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOV_IMM(ir, IREG_flags_op1, 0); + + codegen_flags_changed = 1; + return op_pc+1; + } + return 0; +} +uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint32_t imm_data; + int reg; + + if (fetchdat & 0x20) + return 0; + + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_32(fetchdat & 7); + else + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0; + } + + switch (fetchdat & 0x38) + { + case 0x00: case 0x08: /*TEST*/ + imm_data = fastreadl(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + return op_pc+5; + + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffffffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + + codegen_flags_changed = 1; + return op_pc+1; + + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1, 0); + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOV(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV(ir, reg, IREG_temp1); + } + else + { + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op1, 0); + + codegen_flags_changed = 1; + return op_pc+1; + } + return 0; +} + uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg, sp_reg; @@ -49,7 +279,7 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); SUB_SP(ir, 2); - return -1; + return op_pc+1; } return 0; } @@ -95,7 +325,12 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); SUB_SP(ir, 4); - return -1; + return op_pc+1; } return 0; } + +uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + return op_pc; +} diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index b86c246..832c747 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -1,2 +1,11 @@ +uint32_t ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index 69fa5f7..274adcd 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -322,3 +322,310 @@ uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 5; } + +uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + + switch (fetchdat & 0x38) + { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), src_reg); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } + + return op_pc + 1; +} +uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + + switch (fetchdat & 0x38) + { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), src_reg); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } + + return op_pc + 1; +} + +uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + x86seg *rseg; + + switch (fetchdat & 0x38) + { + case 0x00: /*ES*/ + rseg = &cpu_state.seg_es; + break; + case 0x18: /*DS*/ + rseg = &cpu_state.seg_ds; + break; + case 0x20: /*FS*/ + rseg = &cpu_state.seg_fs; + break; + case 0x28: /*GS*/ + rseg = &cpu_state.seg_gs; + break; + default: + return 0; + } + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); + src_reg = IREG_temp0_W; + } + else + { + x86seg *target_seg; + + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } + + uop_LOAD_SEG(ir, rseg, src_reg); + + return op_pc + 1; +} + +uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); + } + + return op_pc + 1; +} + + +uint32_t ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg2 = IREG_16(opcode & 7); + + uop_MOV(ir, IREG_temp0_W, IREG_AX); + uop_MOV(ir, IREG_AX, reg2); + uop_MOV(ir, reg2, IREG_temp0_W); + + return op_pc; +} +uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg2 = IREG_32(opcode & 7); + + uop_MOV(ir, IREG_temp0, IREG_EAX); + uop_MOV(ir, IREG_EAX, reg2); + uop_MOV(ir, reg2, IREG_temp0); + + return op_pc; +} + +uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_8((fetchdat >> 3) & 7); + + if ((fetchdat & 0xc0) == 0xc0) + { + int reg2 = IREG_8(fetchdat & 7); + + uop_MOV(ir, IREG_temp0_B, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0_B); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_16((fetchdat >> 3) & 7); + + if ((fetchdat & 0xc0) == 0xc0) + { + int reg2 = IREG_16(fetchdat & 7); + + uop_MOV(ir, IREG_temp0_W, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0_W); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_W); + } + + return op_pc + 1; +} +uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_32((fetchdat >> 3) & 7); + + if ((fetchdat & 0xc0) == 0xc0) + { + int reg2 = IREG_32(fetchdat & 7); + + uop_MOV(ir, IREG_temp0, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0); + } + + return op_pc + 1; +} diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h index 78442b4..c6c418d 100644 --- a/src/codegen_ops_mov.h +++ b/src/codegen_ops_mov.h @@ -20,3 +20,18 @@ uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c index 06391c4..befeb4e 100644 --- a/src/codegen_ops_stack.c +++ b/src/codegen_ops_stack.c @@ -64,6 +64,56 @@ uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc; } +uint32_t ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = fastreadw(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); + + return op_pc + 2; +} +uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t imm = fastreadl(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); + + return op_pc + 4; +} + +uint32_t ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); + + return op_pc + 1; +} +uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); + + return op_pc + 1; +} + uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h index 319fb17..240cc1f 100644 --- a/src/codegen_ops_stack.h +++ b/src/codegen_ops_stack.h @@ -4,6 +4,11 @@ uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 48466169242df0530de579787ac6dc030585860d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 8 Aug 2018 22:14:52 +0100 Subject: [PATCH 0498/1050] Handle REP prefixed instructions without a dedicated REP instruction handler properly in the recompiler. Fixes Windows XP setup. --- src/codegen.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/codegen.c b/src/codegen.c index 8a06538..a43a728 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -485,6 +485,12 @@ generate_call: } } + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) + { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; if (!test_modrm || From 2783471daa739cff1dfdad7435503d4e741660d0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 8 Aug 2018 22:15:21 +0100 Subject: [PATCH 0499/1050] Clamp SVGA display on/off timings to a minimum of 1 usec. Fixes hang on Windows XP boot with ViRGE/DX. --- src/vid_svga.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vid_svga.c b/src/vid_svga.c index 8f774cf..40e0e78 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -435,6 +435,10 @@ void svga_recalctimings(svga_t *svga) svga->dispontime = (uint64_t)_dispontime; svga->dispofftime = (uint64_t)_dispofftime; + if (svga->dispontime < TIMER_USEC) + svga->dispontime = TIMER_USEC; + if (svga->dispofftime < TIMER_USEC) + svga->dispofftime = TIMER_USEC; /* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); From 872a2da788c429c0ddf946158d953e3beffa3f2c Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 Aug 2018 21:44:41 +0100 Subject: [PATCH 0500/1050] Added recompiled versions of SHL, SHR, SAR, SHLD and SHRD. --- src/codegen.c | 2 + src/codegen_backend_arm64_ops.c | 26 +- src/codegen_backend_arm64_ops.h | 6 + src/codegen_backend_arm64_uops.c | 208 +++++++- src/codegen_backend_arm_ops.c | 22 + src/codegen_backend_arm_ops.h | 4 + src/codegen_backend_arm_uops.c | 208 +++++++- src/codegen_backend_x86-64_ops.c | 111 +++- src/codegen_backend_x86-64_ops.h | 22 + src/codegen_backend_x86-64_uops.c | 187 ++++++- src/codegen_backend_x86_ops.c | 75 +++ src/codegen_backend_x86_ops.h | 22 + src/codegen_backend_x86_uops.c | 189 ++++++- src/codegen_ir_defs.h | 22 +- src/codegen_ops.c | 13 +- src/codegen_ops_shift.c | 809 ++++++++++++++++++++++++++++++ src/codegen_ops_shift.h | 16 + src/codegen_reg.h | 1 + 18 files changed, 1923 insertions(+), 20 deletions(-) create mode 100644 src/codegen_ops_shift.c create mode 100644 src/codegen_ops_shift.h diff --git a/src/codegen.c b/src/codegen.c index a43a728..ee782d1 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -244,6 +244,8 @@ x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, cpu_reg = (fetchdat >> 3) & 7; cpu_rm = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) + return NULL; if (op_32 & 0x200) return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index cd57fd7..895941e 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -73,6 +73,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_AND_ROR (0x056 << 21) #define OPCODE_ANDS_LSL (0x350 << 21) #define OPCODE_EOR_LSL (0x250 << 21) +#define OPCODE_ORR_ASR (0x154 << 21) #define OPCODE_ORR_LSL (0x150 << 21) #define OPCODE_ORR_LSR (0x152 << 21) #define OPCODE_ORRX_LSL (0x550 << 21) @@ -80,11 +81,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_LSR (0x25a << 21) #define OPCODE_SUBX_LSL (0x658 << 21) +#define OPCODE_ASR (0x1ac02800) #define OPCODE_BLR (0xd63f0000) #define OPCODE_LDR_REG (0xb8606800) #define OPCODE_LDRB_REG (0x38606800) #define OPCODE_LDRH_REG (0x78606800) #define OPCODE_LDRX_REG_LSL3 (0xf8607800) +#define OPCODE_LSL (0x1ac02000) +#define OPCODE_LSR (0x1ac02400) #define OPCODE_NOP (0xd503201f) #define OPCODE_RET (0xd65f0000) #define OPCODE_STR_REG (0xb8206800) @@ -271,6 +275,11 @@ void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_ } } +void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +{ + codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +} + void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); @@ -447,9 +456,24 @@ void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, in codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } +void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +{ + codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +} + +void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +{ + codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +} + +void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - if (dst_reg != src_m_reg) + if (dst_reg != src_m_reg || shift) codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 0bdbcb4..348355a 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -9,6 +9,8 @@ void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); +void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg); + void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); void host_arm64_BLR(codeblock_t *block, int addr_reg); @@ -46,6 +48,10 @@ void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int off void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); +void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg); +void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg); + +void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 620cdd2..3253609 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -553,10 +553,10 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) { host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { @@ -610,6 +610,201 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_ASR(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_LSL(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_LSR(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_W16, uop->imm_data); @@ -828,6 +1023,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_XOR & UOP_MASK] = codegen_XOR, [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 801b99a..2811a37 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -18,6 +18,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) } #define Rm(x) (x) +#define Rs(x) ((x) << 8) #define Rd(x) ((x) << 12) #define Rn(x) ((x) << 16) @@ -94,9 +95,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define SHIFT_TYPE_REG (1 << 4) #define SHIFT_IMM_SHIFT 7 +#define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) #define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) #define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +#define SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x)) +#define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x)) +#define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x)) + #define BFI_lsb(lsb) ((lsb) << 7) #define BFI_msb(msb) ((msb) << 16) @@ -427,14 +433,30 @@ void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) } } +void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); +} +void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); +} void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } +void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); +} void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) { codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); } +void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); +} void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 43df4d1..14690ba 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -46,8 +46,12 @@ void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm); #define host_arm_MOV_REG(block, dst_reg, src_reg) host_arm_MOV_REG_LSL(block, dst_reg, src_reg, 0) +void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm); void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index efc987f..2ab020d 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -635,10 +635,10 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) { host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { @@ -692,6 +692,201 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_arm_MOV_IMM(block, REG_R0, uop->imm_data); @@ -911,6 +1106,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_XOR & UOP_MASK] = codegen_XOR, [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 490e100..c10af3b 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -13,7 +13,9 @@ #define RM_OP_XOR 0x30 #define RM_OP_CMP 0x38 +#define RM_OP_SHL 0x20 #define RM_OP_SHR 0x28 +#define RM_OP_SAR 0x38 static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { @@ -811,10 +813,117 @@ void host_x86_RET(codeblock_t *block) codegen_addbyte(block, 0xc3); /*RET*/ } +void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR8 CL & 8\n"); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR16 CL & 8\n"); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR32 CL & 8\n"); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} + +void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR8 imm & 8\n"); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR16 imm & 8\n"); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR32 imm & 8\n"); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} + +void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL8 CL & 8\n"); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL16 CL & 8\n"); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL32 CL & 8\n"); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} + +void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL8 imm & 8\n"); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL16 imm & 8\n"); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL32 imm & 8\n"); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR8 CL & 8\n"); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR16 CL & 8\n"); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR32 CL & 8\n"); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} + +void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR8 imm & 8\n"); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR16 imm & 8\n"); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) - fatal("SHR32_IMM reg & 8\n"); + fatal("SHR32 imm & 8\n"); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index dc95269..3732f18 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -89,6 +89,28 @@ void host_x86_PUSH(codeblock_t *block, int src_reg); void host_x86_RET(codeblock_t *block); +void host_x86_SAR8_CL(codeblock_t *block, int dst_reg); +void host_x86_SAR16_CL(codeblock_t *block, int dst_reg); +void host_x86_SAR32_CL(codeblock_t *block, int dst_reg); + +void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_SHL8_CL(codeblock_t *block, int dst_reg); +void host_x86_SHL16_CL(codeblock_t *block, int dst_reg); +void host_x86_SHL32_CL(codeblock_t *block, int dst_reg); + +void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_SHR8_CL(codeblock_t *block, int dst_reg); +void host_x86_SHR16_CL(codeblock_t *block, int dst_reg); +void host_x86_SHR32_CL(codeblock_t *block, int dst_reg); + +void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index fb1256f..f251ffe 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -473,11 +473,15 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { @@ -511,6 +515,178 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { if (((uintptr_t)uop->p) >> 32) @@ -668,6 +844,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_XOR & UOP_MASK] = codegen_XOR, [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index e0ffc0f..0a7595f 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -13,7 +13,9 @@ #define RM_OP_XOR 0x30 #define RM_OP_CMP 0x38 +#define RM_OP_SHL 0x20 #define RM_OP_SHR 0x28 +#define RM_OP_SAR 0x38 static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { @@ -707,6 +709,79 @@ void host_x86_RET(codeblock_t *block) #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} + +void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} + +void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} + +void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} + +void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 2d7e53d..ca6b0e8 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -89,6 +89,28 @@ void host_x86_PUSH(codeblock_t *block, int src_reg); void host_x86_RET(codeblock_t *block); +void host_x86_SAR8_CL(codeblock_t *block, int dst_reg); +void host_x86_SAR16_CL(codeblock_t *block, int dst_reg); +void host_x86_SAR32_CL(codeblock_t *block, int dst_reg); + +void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_SHL8_CL(codeblock_t *block, int dst_reg); +void host_x86_SHL16_CL(codeblock_t *block, int dst_reg); +void host_x86_SHL32_CL(codeblock_t *block, int dst_reg); + +void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_SHR8_CL(codeblock_t *block, int dst_reg); +void host_x86_SHR16_CL(codeblock_t *block, int dst_reg); +void host_x86_SHR32_CL(codeblock_t *block, int dst_reg); + +void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index b46fcb8..32aa1c9 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -470,11 +470,15 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { @@ -508,6 +512,178 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); @@ -660,7 +836,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, [UOP_XOR & UOP_MASK] = codegen_XOR, [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - + + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ }; diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index dc92a77..d178898 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -89,7 +89,20 @@ /*UOP_CMP_JZ - if (src_reg_a == imm_data) then jump to ptr*/ #define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) -#define UOP_MAX 0x49 +/*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ +#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) +/*UOP_SAR_IMM - dest_reg = src_reg_a >> immediate*/ +#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) +/*UOP_SHL - dest_reg = src_reg_a << src_reg_b*/ +#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) +/*UOP_SHL_IMM - dest_reg = src_reg_a << immediate*/ +#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) +/*UOP_SHR - dest_reg = src_reg_a >> src_reg_b*/ +#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) +/*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/ +#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) + +#define UOP_MAX 0x56 #define UOP_MASK 0xffff @@ -287,6 +300,13 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) #define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) +#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) +#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) +#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) + #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 0315251..9d2ca5e 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -7,6 +7,7 @@ #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" #include "codegen_ops_mov.h" +#include "codegen_ops_shift.h" #include "codegen_ops_stack.h" RecompOpFn recomp_opcodes[512] = @@ -28,8 +29,8 @@ RecompOpFn recomp_opcodes[512] = /*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, -/*c0*/ NULL, NULL, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, @@ -50,8 +51,8 @@ RecompOpFn recomp_opcodes[512] = /*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, -/*c0*/ NULL, NULL, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 }; @@ -73,7 +74,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -95,7 +96,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_shift.c b/src/codegen_ops_shift.c new file mode 100644 index 0000000..90547d1 --- /dev/null +++ b/src/codegen_ops_shift.c @@ -0,0 +1,809 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_shift.h" + +static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) +{ + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + default: + return 0; + } + } + else + { + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) +{ + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + default: + return 0; + } + } + else + { + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) +{ + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } + else + { + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + + +uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (imm) + return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc+1; +} +uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (imm) + return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc+1; +} +uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (imm) + return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc+1; +} + +uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); +} +uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); +} +uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); +} + +uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]); + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]); + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]); + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (!imm) + return op_pc+2; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + } + return op_pc+2; +} +uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (!imm) + return op_pc+2; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + } + return op_pc+2; +} +uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (!imm) + return op_pc+2; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + } + return op_pc+2; +} +uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + + if (!imm) + return op_pc+2; + + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + } + return op_pc+2; +} diff --git a/src/codegen_ops_shift.h b/src/codegen_ops_shift.h new file mode 100644 index 0000000..f109b0d --- /dev/null +++ b/src/codegen_ops_shift.h @@ -0,0 +1,16 @@ +uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index e55d73a..aa52e03 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -93,6 +93,7 @@ enum IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, + IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, From 33328978867c7a70df3afb3fe4db429986170bf6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 30 Aug 2018 22:26:33 +0100 Subject: [PATCH 0501/1050] Added recompiled versions of Jcc, JCXZ, LOOP, LOOPE and LOOPNE. --- src/codegen_backend_arm64_ops.c | 96 ++++- src/codegen_backend_arm64_ops.h | 17 + src/codegen_backend_arm64_uops.c | 458 ++++++++++++++++++++- src/codegen_backend_arm_ops.c | 103 +++++ src/codegen_backend_arm_ops.h | 19 + src/codegen_backend_arm_uops.c | 453 +++++++++++++++++++- src/codegen_backend_x86-64_ops.c | 143 +++++++ src/codegen_backend_x86-64_ops.h | 24 ++ src/codegen_backend_x86-64_uops.c | 428 ++++++++++++++++++- src/codegen_backend_x86_ops.c | 127 ++++++ src/codegen_backend_x86_ops.h | 25 ++ src/codegen_backend_x86_uops.c | 428 ++++++++++++++++++- src/codegen_ir.c | 55 ++- src/codegen_ir_defs.h | 127 +++++- src/codegen_ops.c | 13 +- src/codegen_ops_branch.c | 662 ++++++++++++++++++++++++++++++ src/codegen_ops_branch.h | 69 ++++ src/codegen_reg.h | 8 +- 18 files changed, 3234 insertions(+), 21 deletions(-) create mode 100644 src/codegen_ops_branch.c create mode 100644 src/codegen_ops_branch.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 895941e..91e49e0 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -31,6 +31,19 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define COND_EQ (0x0) #define COND_NE (0x1) +#define COND_CS (0x2) +#define COND_CC (0x3) +#define COND_MI (0x4) +#define COND_PL (0x5) +#define COND_VS (0x6) +#define COND_VC (0x7) +#define COND_HI (0x8) +#define COND_LS (0x9) +#define COND_GE (0xa) +#define COND_LT (0xb) +#define COND_GT (0xc) +#define COND_LE (0xd) + #define OPCODE_SHIFT 24 #define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) @@ -72,6 +85,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_AND_LSL (0x050 << 21) #define OPCODE_AND_ROR (0x056 << 21) #define OPCODE_ANDS_LSL (0x350 << 21) +#define OPCODE_CMP_LSL (0x358 << 21) #define OPCODE_EOR_LSL (0x250 << 21) #define OPCODE_ORR_ASR (0x154 << 21) #define OPCODE_ORR_LSL (0x150 << 21) @@ -83,6 +97,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ASR (0x1ac02800) #define OPCODE_BLR (0xd63f0000) +#define OPCODE_BR (0xd61f0000) #define OPCODE_LDR_REG (0xb8606800) #define OPCODE_LDRB_REG (0x38606800) #define OPCODE_LDRH_REG (0x78606800) @@ -290,15 +305,75 @@ void host_arm64_BLR(codeblock_t *block, int addr_reg) codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); } +uint32_t *host_arm64_BCC_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_CC); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BCS_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_CS); + return (uint32_t *)&block->data[block_pos-4]; +} uint32_t *host_arm64_BEQ_(codeblock_t *block) { codegen_addlong(block, OPCODE_BCOND | COND_EQ); - return &block->data[block_pos-4]; + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BGE_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_GE); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BGT_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_GT); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BHI_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_HI); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BLE_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_LE); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BLS_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_LS); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BLT_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_LT); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BMI_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_MI); + return (uint32_t *)&block->data[block_pos-4]; } uint32_t *host_arm64_BNE_(codeblock_t *block) { codegen_addlong(block, OPCODE_BCOND | COND_NE); - return &block->data[block_pos-4]; + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BPL_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_PL); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BVC_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_VC); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_arm64_BVS_(codeblock_t *block) +{ + codegen_addlong(block, OPCODE_BCOND | COND_VS); + return (uint32_t *)&block->data[block_pos-4]; } void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) @@ -307,6 +382,11 @@ void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) *opcode |= OFFSET19(offset); } +void host_arm64_BR(codeblock_t *block, int addr_reg) +{ + codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); +} + void host_arm64_BEQ(codeblock_t *block, void *dest) { uint32_t *opcode = host_arm64_BEQ_(block); @@ -375,6 +455,11 @@ void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) fatal("CMPX_IMM %08x\n", imm_data); } +void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ @@ -649,6 +734,13 @@ void host_arm64_call(codeblock_t *block, void *dst_addr) host_arm64_BLR(block, REG_X16); } +void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) +{ + int offset = add_literal_q(block, (uintptr_t)dst_addr); + host_arm64_LDR_LITERAL_X(block, REG_X16, offset); + host_arm64_BR(block, REG_X16); +} + void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) { if (imm_is_imm16(imm_data)) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 348355a..35d5044 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -17,11 +17,25 @@ void host_arm64_BLR(codeblock_t *block, int addr_reg); void host_arm64_BEQ(codeblock_t *block, void *dest); +uint32_t *host_arm64_BCC_(codeblock_t *block); +uint32_t *host_arm64_BCS_(codeblock_t *block); uint32_t *host_arm64_BEQ_(codeblock_t *block); +uint32_t *host_arm64_BGE_(codeblock_t *block); +uint32_t *host_arm64_BGT_(codeblock_t *block); +uint32_t *host_arm64_BHI_(codeblock_t *block); +uint32_t *host_arm64_BLE_(codeblock_t *block); +uint32_t *host_arm64_BLS_(codeblock_t *block); +uint32_t *host_arm64_BLT_(codeblock_t *block); +uint32_t *host_arm64_BMI_(codeblock_t *block); uint32_t *host_arm64_BNE_(codeblock_t *block); +uint32_t *host_arm64_BPL_(codeblock_t *block); +uint32_t *host_arm64_BVC_(codeblock_t *block); +uint32_t *host_arm64_BVS_(codeblock_t *block); void host_arm64_branch_set_offset(uint32_t *opcode, void *dest); +void host_arm64_BR(codeblock_t *block, int addr_reg); + void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); @@ -30,6 +44,8 @@ void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data); void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data); +#define host_arm64_CMP_REG(block, src_n_reg, src_m_reg) host_arm64_CMP_REG_LSL(block, src_n_reg, src_m_reg, 0) +void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift); void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); @@ -88,6 +104,7 @@ void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); void host_arm64_call(codeblock_t *block, void *dst_addr); +void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 3253609..ebef0fc 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -7,6 +7,8 @@ #include "codegen_backend_arm64_ops.h" #include "codegen_ir_defs.h" +#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) + #define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) #define REG_IS_L(size) (size == IREG_SIZE_L) @@ -193,6 +195,19 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm64_call(block, uop->p); + host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); + + return 0; +} + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_arm64_call(block, uop->p); @@ -217,6 +232,369 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BNE_(block); + + return 0; +} +static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BEQ_(block); + + return 0; +} + +static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BCS_(block); + + return 0; +} +static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BHI_(block); + + return 0; +} +static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BGE_(block); + + return 0; +} +static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BGT_(block); + + return 0; +} +static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BVC_(block); + + return 0; +} +static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BNE_(block); + + return 0; +} +static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BCC_(block); + + return 0; +} +static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BLS_(block); + + return 0; +} +static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BLT_(block); + + return 0; +} +static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BLE_(block); + + return 0; +} +static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BVS_(block); + + return 0; +} +static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BEQ_(block); + + return 0; +} + +static int codegen_JMP(codeblock_t *block, uop_t *uop) +{ + host_arm64_jump(block, (uintptr_t)uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); @@ -918,6 +1296,55 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } + else if (REG_IS_W(src_size)) + { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } + else if (REG_IS_B(src_size)) + { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BEQ_(block); + + return 0; +} +static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } + else if (REG_IS_W(src_size)) + { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } + else if (REG_IS_B(src_size)) + { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BNE_(block); + + return 0; +} + static int codegen_XOR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -986,7 +1413,11 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, @@ -1030,7 +1461,26 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) @@ -1108,4 +1558,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos fatal("codegen_direct_write_32_stack - not in range\n"); } +void codegen_set_jump_dest(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)&block->data[block_pos] - (uintptr_t)p; + + *(uint32_t *)p |= OFFSET19(offset); +} #endif diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 2811a37..66941ce 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -28,6 +28,18 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define COND_SHIFT 28 #define COND_EQ (0x0 << COND_SHIFT) #define COND_NE (0x1 << COND_SHIFT) +#define COND_CS (0x2 << COND_SHIFT) +#define COND_CC (0x3 << COND_SHIFT) +#define COND_MI (0x4 << COND_SHIFT) +#define COND_PL (0x5 << COND_SHIFT) +#define COND_VS (0x6 << COND_SHIFT) +#define COND_VC (0x7 << COND_SHIFT) +#define COND_HI (0x8 << COND_SHIFT) +#define COND_LS (0x9 << COND_SHIFT) +#define COND_GE (0xa << COND_SHIFT) +#define COND_LT (0xb << COND_SHIFT) +#define COND_GT (0xc << COND_SHIFT) +#define COND_LE (0xd << COND_SHIFT) #define COND_AL (0xe << COND_SHIFT) #define OPCODE_SHIFT 20 @@ -72,6 +84,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BFI 0xe7c00010 #define OPCODE_BLX 0xe12fff30 +#define OPCODE_BX 0xe12fff10 #define OPCODE_LDRH_IMM 0xe1d000b0 #define OPCODE_LDRH_REG 0xe19000b0 #define OPCODE_STRH_IMM 0xe1c000b0 @@ -227,6 +240,19 @@ void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int sr codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } +void host_arm_B(codeblock_t *block, uintptr_t dest_addr) +{ + uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BX(block, REG_R3); + } + else + codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); +} + void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); @@ -276,18 +302,90 @@ void host_arm_BLX(codeblock_t *block, int addr_reg) codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } +uint32_t *host_arm_BCC_(codeblock_t *block) +{ + codegen_addlong(block, COND_CC | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BCS_(codeblock_t *block) +{ + codegen_addlong(block, COND_CS | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} uint32_t *host_arm_BEQ_(codeblock_t *block) { codegen_addlong(block, COND_EQ | OPCODE_B); return (uint32_t *)&block->data[block_pos - 4]; } +uint32_t *host_arm_BGE_(codeblock_t *block) +{ + codegen_addlong(block, COND_GE | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BGT_(codeblock_t *block) +{ + codegen_addlong(block, COND_GT | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BHI_(codeblock_t *block) +{ + codegen_addlong(block, COND_HI | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BLE_(codeblock_t *block) +{ + codegen_addlong(block, COND_LE | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BLS_(codeblock_t *block) +{ + codegen_addlong(block, COND_LS | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BLT_(codeblock_t *block) +{ + codegen_addlong(block, COND_LT | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BMI_(codeblock_t *block) +{ + codegen_addlong(block, COND_MI | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} uint32_t *host_arm_BNE_(codeblock_t *block) { codegen_addlong(block, COND_NE | OPCODE_B); return (uint32_t *)&block->data[block_pos - 4]; } +uint32_t *host_arm_BPL_(codeblock_t *block) +{ + codegen_addlong(block, COND_PL | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BVC_(codeblock_t *block) +{ + codegen_addlong(block, COND_VC | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} +uint32_t *host_arm_BVS_(codeblock_t *block) +{ + codegen_addlong(block, COND_VS | OPCODE_B); + + return (uint32_t *)&block->data[block_pos - 4]; +} void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) { @@ -308,6 +406,11 @@ void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); } +void host_arm_BX(codeblock_t *block, int addr_reg) +{ + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); +} + void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) { uint32_t arm_imm; diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 14690ba..6dcb29e 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -7,6 +7,8 @@ void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_B(codeblock_t *block, uintptr_t dest_addr); + void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); @@ -15,15 +17,32 @@ void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int sr void host_arm_BL(codeblock_t *block, uintptr_t dest_addr); void host_arm_BLX(codeblock_t *block, int addr_reg); + +uint32_t *host_arm_BCC_(codeblock_t *block); +uint32_t *host_arm_BCS_(codeblock_t *block); uint32_t *host_arm_BEQ_(codeblock_t *block); +uint32_t *host_arm_BGE_(codeblock_t *block); +uint32_t *host_arm_BGT_(codeblock_t *block); +uint32_t *host_arm_BHI_(codeblock_t *block); +uint32_t *host_arm_BLE_(codeblock_t *block); +uint32_t *host_arm_BLS_(codeblock_t *block); +uint32_t *host_arm_BLT_(codeblock_t *block); +uint32_t *host_arm_BMI_(codeblock_t *block); uint32_t *host_arm_BNE_(codeblock_t *block); +uint32_t *host_arm_BPL_(codeblock_t *block); +uint32_t *host_arm_BVC_(codeblock_t *block); +uint32_t *host_arm_BVS_(codeblock_t *block); + void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr); void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr); +void host_arm_BX(codeblock_t *block, int addr_reg); + void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm); void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift); void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm); +#define host_arm_CMP_REG(block, src_reg_n, src_reg_m) host_arm_CMP_REG_LSL(block, src_reg_n, src_reg_m, 0) void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift); void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 2ab020d..427da2e 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -268,6 +268,19 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm_call(block, uop->p); + host_arm_MOV_REG(block, dest_reg, REG_R0); + + return 0; +} + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_arm_call(block, uop->p); @@ -293,6 +306,369 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCS_(block); + + return 0; +} +static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BHI_(block); + + return 0; +} +static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGE_(block); + + return 0; +} +static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGT_(block); + + return 0; +} +static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVC_(block); + + return 0; +} +static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCC_(block); + + return 0; +} +static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLS_(block); + + return 0; +} +static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLT_(block); + + return 0; +} +static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLE_(block); + + return 0; +} +static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVS_(block); + + return 0; +} +static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int codegen_JMP(codeblock_t *block, uop_t *uop) +{ + host_arm_B(block, (uintptr_t)uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); @@ -1000,6 +1376,55 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } + else if (REG_IS_W(src_size)) + { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } + else if (REG_IS_B(src_size)) + { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} +static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } + else if (REG_IS_W(src_size)) + { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } + else if (REG_IS_B(src_size)) + { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} + static int codegen_XOR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1068,8 +1493,11 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, @@ -1113,7 +1541,26 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, }; void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) @@ -1190,4 +1637,8 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_set_jump_dest(codeblock_t *block, void *p) +{ + *(uint32_t *)p |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; +} #endif diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index c10af3b..6de5334 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -117,6 +117,23 @@ static inline void call(codeblock_t *block, uintptr_t func) } } +static inline void jmp(codeblock_t *block, uintptr_t func) +{ + uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; + + if (diff >= -0x80000000 && diff < 0x7fffffff) + { + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uint32_t)diff); + } + else + { + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ + } +} + void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) @@ -268,6 +285,21 @@ void host_x86_CALL(codeblock_t *block, void *p) call(block, (uintptr_t)p); } +void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (is_imm8(imm_data)) @@ -291,6 +323,24 @@ void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) fatal("CMP64_REG_IMM not 8-bit imm\n"); } +void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} + +void host_x86_JMP(codeblock_t *block, void *p) +{ + jmp(block, (uintptr_t)p); +} + void host_x86_JNZ(codeblock_t *block, void *p) { codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ @@ -313,6 +363,91 @@ uint8_t *host_x86_JZ_short(codeblock_t *block) return &block->data[block_pos-1]; } +uint32_t *host_x86_JNB_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNBE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNL_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNLE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNO_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNS_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNZ_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JB_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JBE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JL_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JLE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JO_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JS_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JZ_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { if (offset) @@ -1007,6 +1142,14 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) { if ((dst_reg & 8) || (src_reg & 8)) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 3732f18..2bef40c 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -17,15 +17,37 @@ void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int void host_x86_CALL(codeblock_t *block, void *p); +void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data); +void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); + +void host_x86_JMP(codeblock_t *block, void *p); + void host_x86_JNZ(codeblock_t *block, void *p); void host_x86_JZ(codeblock_t *block, void *p); uint8_t *host_x86_JNZ_short(codeblock_t *block); uint8_t *host_x86_JZ_short(codeblock_t *block); +uint32_t *host_x86_JNB_long(codeblock_t *block); +uint32_t *host_x86_JNBE_long(codeblock_t *block); +uint32_t *host_x86_JNL_long(codeblock_t *block); +uint32_t *host_x86_JNLE_long(codeblock_t *block); +uint32_t *host_x86_JNO_long(codeblock_t *block); +uint32_t *host_x86_JNS_long(codeblock_t *block); +uint32_t *host_x86_JNZ_long(codeblock_t *block); +uint32_t *host_x86_JB_long(codeblock_t *block); +uint32_t *host_x86_JBE_long(codeblock_t *block); +uint32_t *host_x86_JL_long(codeblock_t *block); +uint32_t *host_x86_JLE_long(codeblock_t *block); +uint32_t *host_x86_JO_long(codeblock_t *block); +uint32_t *host_x86_JS_long(codeblock_t *block); +uint32_t *host_x86_JZ_long(codeblock_t *block); + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset); void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); @@ -122,6 +144,8 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); +void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg); void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index f251ffe..59f78b3 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -149,6 +149,19 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); + + return 0; +} + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -174,6 +187,343 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNZ_long(block); + + return 0; +} +static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JZ_long(block); + + return 0; +} + +static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNB_long(block); + + return 0; +} +static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNBE_long(block); + + return 0; +} +static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNL_long(block); + + return 0; +} +static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNLE_long(block); + + return 0; +} +static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNO_long(block); + + return 0; +} +static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNZ_long(block); + + return 0; +} +static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JB_long(block); + + return 0; +} +static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JBE_long(block); + + return 0; +} +static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JL_long(block); + + return 0; +} +static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JLE_long(block); + + return 0; +} +static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JO_long(block); + + return 0; +} +static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JZ_long(block); + + return 0; +} + +static int codegen_JMP(codeblock_t *block, uop_t *uop) +{ + host_x86_JMP(block, uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { #if WIN64 @@ -759,6 +1109,55 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_TEST32_REG(block, src_reg, src_reg); + } + else if (REG_IS_W(src_size)) + { + host_x86_TEST16_REG(block, src_reg, src_reg); + } + else if (REG_IS_B(src_size)) + { + host_x86_TEST8_REG(block, src_reg, src_reg); + } + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNS_long(block); + + return 0; +} +static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_TEST32_REG(block, src_reg, src_reg); + } + else if (REG_IS_W(src_size)) + { + host_x86_TEST16_REG(block, src_reg, src_reg); + } + else if (REG_IS_B(src_size)) + { + host_x86_TEST8_REG(block, src_reg, src_reg); + } + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JS_long(block); + + return 0; +} + static int codegen_XOR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -806,8 +1205,11 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, @@ -851,7 +1253,26 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, }; void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) @@ -895,4 +1316,9 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } +void codegen_set_jump_dest(codeblock_t *block, void *p) +{ + *(uint32_t *)p = (uintptr_t)&block->data[block_pos] - ((uintptr_t)p + 4); +} + #endif diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 0a7595f..b61abd1 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -260,6 +260,21 @@ void host_x86_CALL(codeblock_t *block, void *p) codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); } +void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + else if (dst_reg == REG_EAX) + { + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (is_imm8(imm_data)) @@ -276,6 +291,25 @@ void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } +void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} + +void host_x86_JMP(codeblock_t *block, void *p) +{ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); +} + void host_x86_JNZ(codeblock_t *block, void *p) { codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ @@ -298,6 +332,91 @@ uint8_t *host_x86_JZ_short(codeblock_t *block) return &block->data[block_pos-1]; } +uint32_t *host_x86_JNB_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNBE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNL_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNLE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNO_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNS_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JNZ_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JB_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JBE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JL_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JLE_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JO_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JS_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} +uint32_t *host_x86_JZ_long(codeblock_t *block) +{ + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { if (offset) @@ -856,6 +975,14 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } +void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index ca6b0e8..6fa0a97 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -18,14 +18,36 @@ void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int void host_x86_CALL(codeblock_t *block, void *p); +void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); +void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); + +void host_x86_JMP(codeblock_t *block, void *p); + void host_x86_JNZ(codeblock_t *block, void *p); void host_x86_JZ(codeblock_t *block, void *p); uint8_t *host_x86_JNZ_short(codeblock_t *block); uint8_t *host_x86_JZ_short(codeblock_t *block); +uint32_t *host_x86_JNB_long(codeblock_t *block); +uint32_t *host_x86_JNBE_long(codeblock_t *block); +uint32_t *host_x86_JNL_long(codeblock_t *block); +uint32_t *host_x86_JNLE_long(codeblock_t *block); +uint32_t *host_x86_JNO_long(codeblock_t *block); +uint32_t *host_x86_JNS_long(codeblock_t *block); +uint32_t *host_x86_JNZ_long(codeblock_t *block); +uint32_t *host_x86_JB_long(codeblock_t *block); +uint32_t *host_x86_JBE_long(codeblock_t *block); +uint32_t *host_x86_JL_long(codeblock_t *block); +uint32_t *host_x86_JLE_long(codeblock_t *block); +uint32_t *host_x86_JO_long(codeblock_t *block); +uint32_t *host_x86_JS_long(codeblock_t *block); +uint32_t *host_x86_JZ_long(codeblock_t *block); + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32_t offset); void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); @@ -121,7 +143,10 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); +void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); + void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_data); void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 32aa1c9..4f1ceb8 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -159,6 +159,19 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); + + return 0; +} + static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -181,10 +194,347 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) else fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); host_x86_JZ(block, uop->p); + + return 0; +} + +static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNZ_long(block); + + return 0; +} +static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } + else if (REG_IS_W(src_size)) + { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JZ_long(block); return 0; } +static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNB_long(block); + + return 0; +} +static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNBE_long(block); + + return 0; +} +static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNL_long(block); + + return 0; +} +static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNLE_long(block); + + return 0; +} +static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNO_long(block); + + return 0; +} +static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNZ_long(block); + + return 0; +} +static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JB_long(block); + + return 0; +} +static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JBE_long(block); + + return 0; +} +static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JL_long(block); + + return 0; +} +static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JLE_long(block); + + return 0; +} +static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JO_long(block); + + return 0; +} +static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } + else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JZ_long(block); + + return 0; +} + +static int codegen_JMP(codeblock_t *block, uop_t *uop) +{ + host_x86_JMP(block, uop->p); + + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); @@ -752,6 +1102,55 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_TEST32_REG(block, src_reg, src_reg); + } + else if (REG_IS_W(src_size)) + { + host_x86_TEST16_REG(block, src_reg, src_reg); + } + else if (REG_IS_B(src_size)) + { + host_x86_TEST8_REG(block, src_reg, src_reg); + } + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JNS_long(block); + + return 0; +} +static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) + { + host_x86_TEST32_REG(block, src_reg, src_reg); + } + else if (REG_IS_W(src_size)) + { + host_x86_TEST16_REG(block, src_reg, src_reg); + } + else if (REG_IS_B(src_size)) + { + host_x86_TEST8_REG(block, src_reg, src_reg); + } + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_x86_JS_long(block); + + return 0; +} + static int codegen_XOR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -799,8 +1198,11 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, @@ -844,7 +1246,26 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, }; void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) @@ -888,4 +1309,9 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); } +void codegen_set_jump_dest(codeblock_t *block, void *p) +{ + *(uint32_t *)p = (uintptr_t)&block->data[block_pos] - ((uintptr_t)p + 4); +} + #endif diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 8d81db8..c179632 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -17,6 +17,7 @@ ir_data_t *codegen_ir_init() void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) { + int jump_target_at_end = -1; int c; codegen_backend_prologue(block); @@ -26,12 +27,23 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) uop_t *uop = &ir->uops[c]; // pclog("uOP %i : %08x\n", c, uop->type); - + if (uop->type & UOP_TYPE_BARRIER) codegen_reg_flush_invalidate(ir, block); else if (uop->type & UOP_TYPE_ORDER_BARRIER) codegen_reg_flush(ir, block); + if (uop->type & UOP_TYPE_JUMP_DEST) + { + uop_t *uop_dest = uop; + + while (uop_dest->jump_list_next != -1) + { + uop_dest = &ir->uops[uop_dest->jump_list_next]; + codegen_set_jump_dest(block, uop_dest->p); + } + } + if (uop->type & UOP_TYPE_PARAMS_REGS) { codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); @@ -56,10 +68,51 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) if (!uop_handlers[uop->type & UOP_MASK]) fatal("!uop_handlers[uop->type & UOP_MASK]\n"); uop_handlers[uop->type & UOP_MASK](block, uop); + + if (uop->type & UOP_TYPE_JUMP) + { + if (uop->jump_dest_uop == ir->wr_pos) + { + if (jump_target_at_end == -1) + jump_target_at_end = c; + else + { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; + + while (uop_dest->jump_list_next != -1) + uop_dest = &ir->uops[uop_dest->jump_list_next]; + + uop_dest->jump_list_next = c; + } + } + else + { + uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; + + while (uop_dest->jump_list_next != -1) + uop_dest = &ir->uops[uop_dest->jump_list_next]; + + uop_dest->jump_list_next = c; + ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; + } + } } codegen_reg_flush_invalidate(ir, block); + if (jump_target_at_end != -1) + { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; + + while (1) + { + codegen_set_jump_dest(block, uop_dest->p); + if (uop_dest->jump_list_next == -1) + break; + uop_dest = &ir->uops[uop_dest->jump_list_next]; + } + } + codegen_backend_epilogue(block); // if (has_ea) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index d178898..22b1e70 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -24,6 +24,13 @@ /*uOP uses immediate data*/ #define UOP_TYPE_PARAMS_IMM (1 << 30) +/*uOP is a jump, with the destination uOP in uop->jump_dest_uop. The compiler must + set jump_dest in the destination uOP to the address of the branch offset to be + written when known.*/ +#define UOP_TYPE_JUMP (1 << 26) +/*uOP is the destination of a jump, and must set the destination offset of the jump + at compile time.*/ +#define UOP_TYPE_JUMP_DEST (1 << 25) #define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) @@ -41,6 +48,10 @@ #define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) /*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/ #define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) +/*UOP_JMP - jump to ptr*/ +#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) +/*UOP_CALL_FUNC - call instruction handler at p, dest_reg = return value*/ +#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_MOV_PTR - dest_reg = p*/ #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ @@ -86,7 +97,7 @@ #define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/ #define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) -/*UOP_CMP_JZ - if (src_reg_a == imm_data) then jump to ptr*/ +/*UOP_CMP_IMM_JZ - if (src_reg_a == imm_data) then jump to ptr*/ #define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ @@ -102,7 +113,43 @@ /*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/ #define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) -#define UOP_MAX 0x56 +/*UOP_CMP_IMM_JZ_DEST - if (src_reg_a == imm_data) then jump to ptr*/ +#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_IMM_JNZ_DEST - if (src_reg_a != imm_data) then jump to ptr*/ +#define UOP_CMP_IMM_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) + +/*UOP_CMP_JB_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ +#define UOP_CMP_JB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JNB_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JO_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ +#define UOP_CMP_JO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JNO_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JZ_DEST - if (src_reg_a == src_reg_b) then jump to ptr*/ +#define UOP_CMP_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JNZ_DEST - if (src_reg_a != src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JL_DEST - if (signed)(src_reg_a < src_reg_b) then jump to ptr*/ +#define UOP_CMP_JL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JNL_DEST - if (signed)(src_reg_a >= src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JBE_DEST - if (src_reg_a <= src_reg_b) then jump to ptr*/ +#define UOP_CMP_JBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JNBE_DEST - if (src_reg_a > src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JLE_DEST - if (signed)(src_reg_a <= src_reg_b) then jump to ptr*/ +#define UOP_CMP_JLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_CMP_JNLE_DEST - if (signed)(src_reg_a > src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) + + +/*UOP_TEST_JNS_DEST - if (src_reg_a positive) then jump to ptr*/ +#define UOP_TEST_JNS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +/*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/ +#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) + +#define UOP_MAX 0x72 #define UOP_MASK 0xffff @@ -117,6 +164,9 @@ typedef struct uop_t void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; + int jump_dest_uop; + int jump_list_next; + void *jump_dest; } uop_t; #define UOP_NR_MAX 4096 @@ -141,15 +191,45 @@ static inline uop_t *uop_alloc(ir_data_t *ir) uop->src_reg_b = invalid_ir_reg; uop->src_reg_c = invalid_ir_reg; + uop->jump_list_next = -1; + return uop; } -static inline void uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) +static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) +{ + uop_t *uop = &ir->uops[jump_uop]; + + uop->jump_dest_uop = ir->wr_pos; +} + +static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) { uop_t *uop = uop_alloc(ir); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); + + return ir->wr_pos-1; +} + +static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); +} + +static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->imm_data = imm; + + return ir->wr_pos-1; } static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) @@ -220,6 +300,17 @@ static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int uop->imm_data = imm; } +static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + + return ir->wr_pos-1; +} + static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) { uop_t *uop = uop_alloc(ir); @@ -284,7 +375,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, uop->imm_data = imm; } -#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) +#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1_arg(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) @@ -307,11 +398,30 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) #define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) -#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) -#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) +#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) +#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) #define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) +#define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) +#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) + +#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) + +#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) + #define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) #define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) @@ -330,6 +440,9 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) +#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) + void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); @@ -343,4 +456,6 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); +void codegen_set_jump_dest(codeblock_t *block, void *p); + #endif diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 9d2ca5e..ff7df3d 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -3,6 +3,7 @@ #include "codegen_ir.h" #include "codegen_ops.h" #include "codegen_ops_arith.h" +#include "codegen_ops_branch.h" #include "codegen_ops_jump.h" #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" @@ -22,7 +23,7 @@ RecompOpFn recomp_opcodes[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8,NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, /*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -31,7 +32,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, +/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, /*32-bit data*/ @@ -44,7 +45,7 @@ RecompOpFn recomp_opcodes[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8,NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, /*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -53,7 +54,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, +/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 }; @@ -72,7 +73,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -94,7 +95,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c new file mode 100644 index 0000000..d62e1e5 --- /dev/null +++ b/src/codegen_ops_branch.c @@ -0,0 +1,662 @@ +#include "ibm.h" + +#include "x86.h" +#include "386_common.h" +#include "x86_flags.h" +#include "codegen.h" +#include "codegen_backend.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_helpers.h" +#include "codegen_ops_mov.h" + +static int NF_SET_01() +{ + return NF_SET() ? 1 : 0; +} +static int VF_SET_01() +{ + return VF_SET() ? 1 : 0; +} + +static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + /*Overflow is always zero*/ + return; + + case FLAGS_SUB8: case FLAGS_DEC8: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: case FLAGS_DEC16: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: case FLAGS_DEC32: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + /*Overflow is always zero*/ + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + return; + + case FLAGS_SUB8: case FLAGS_DEC8: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: case FLAGS_DEC16: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: case FLAGS_DEC32: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} + +static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + /*Carry is always zero*/ + return; + + case FLAGS_SUB8: + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + /*Carry is always zero*/ + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + return; + + case FLAGS_SUB8: + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} + +static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} + +static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop, jump_uop2 = -1; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + break; + + case FLAGS_SUB8: + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop, jump_uop2 = -1; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + break; + + case FLAGS_SUB8: + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); +} + +static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} + +static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} + +static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_SUB8: case FLAGS_DEC8: + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: case FLAGS_DEC16: + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: case FLAGS_DEC32: + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_SUB8: case FLAGS_DEC8: + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: case FLAGS_DEC16: + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: case FLAGS_DEC32: + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} + +static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop, jump_uop2 = -1; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_SUB8: case FLAGS_DEC8: + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: case FLAGS_DEC16: + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: case FLAGS_DEC32: + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); +} +static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +{ + int jump_uop, jump_uop2 = -1; + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) + { + case FLAGS_SUB8: case FLAGS_DEC8: + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: case FLAGS_DEC16: + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: case FLAGS_DEC32: + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); +} + +#define ropJ(cond) \ +uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ + ropJ ## cond ## _common(block, ir, op_pc+1, offset); \ + \ + return op_pc+1; \ +} \ +uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ + ropJ ## cond ## _common(block, ir, op_pc+2, offset); \ + \ + return op_pc+2; \ +} \ +uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + uint32_t offset = fastreadl(cs + op_pc); \ + ropJ ## cond ## _common(block, ir, op_pc+4, offset); \ + \ + return op_pc+4; \ +} + +ropJ(O) +ropJ(NO) +ropJ(B) +ropJ(NB) +ropJ(E) +ropJ(NE) +ropJ(BE) +ropJ(NBE) +ropJ(S) +ropJ(NS) +ropJ(P) +ropJ(NP) +ropJ(L) +ropJ(NL) +ropJ(LE) +ropJ(NLE) + + +uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + int jump_uop; + + if (op_32 & 0x200) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); + + return op_pc+1; +} + +uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + int jump_uop; + + if (op_32 & 0x200) + { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } + else + { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); + + return op_pc+1; +} + +uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + int jump_uop, jump_uop2; + + if (op_32 & 0x200) + { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } + else + { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); + + return op_pc+1; +} +uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + int jump_uop, jump_uop2; + + if (op_32 & 0x200) + { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } + else + { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); + + return op_pc+1; +} diff --git a/src/codegen_ops_branch.h b/src/codegen_ops_branch.h new file mode 100644 index 0000000..a67a2b5 --- /dev/null +++ b/src/codegen_ops_branch.h @@ -0,0 +1,69 @@ +uint32_t ropJB_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJB_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJB_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNB_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNB_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNB_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJBE_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJBE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJBE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNBE_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNBE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNBE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJE_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNE_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJL_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJL_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJL_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNL_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNL_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNL_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJLE_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJLE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJLE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNLE_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNLE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNLE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJO_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJO_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJO_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNO_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNO_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNO_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJP_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJP_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJP_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNP_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNP_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNP_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJS_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJNS_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJNS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index aa52e03..26422d8 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -88,9 +88,13 @@ enum IREG_BH = IREG_EBX + IREG_SIZE_BH, IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, - + IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, + IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, + IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, - + IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, + IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, + IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, From ad50530ded838719086fe091b45bbec35385462d Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 31 Aug 2018 08:41:25 +0100 Subject: [PATCH 0502/1050] Force display redraw on writes to EGA/VGA attribute register 0x13 (soft panning). --- src/vid_svga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_svga.c b/src/vid_svga.c index d94606f..9a3db62 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -53,6 +53,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) } else { + if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) + svga->fullchange = changeframecount; svga->attrregs[svga->attraddr & 31] = val; if (svga->attraddr < 16) svga->fullchange = changeframecount; From 0d687a4f6cba905d8feaa77f7d4a2e903d09926f Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 31 Aug 2018 08:44:00 +0100 Subject: [PATCH 0503/1050] Implement horizontal soft panning on EGA/VGA text modes. --- src/vid_svga_render.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 1deb874..6df365e 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -40,7 +40,8 @@ void svga_render_text_40(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[32]; + int offset = ((8 - svga->scrollcache) << 1) + 16; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; int x, xx; int drawcursor; uint8_t chr, attr, dat; @@ -103,7 +104,8 @@ void svga_render_text_80(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[32]; + int offset = (8 - svga->scrollcache) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; int x, xx; int drawcursor; uint8_t chr, attr, dat; @@ -166,7 +168,8 @@ void svga_render_text_80_ksc5601(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[32]; + int offset = (8 - svga->scrollcache) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; int x, xx; int drawcursor; uint8_t chr, attr, dat, nextchr; From 787aad9598d2b351a032cca7ba763f183a2bbce1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 31 Aug 2018 08:46:38 +0100 Subject: [PATCH 0504/1050] Reset EGA/VGA character scanline counter when hitting split screen start line. --- src/vid_svga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vid_svga.c b/src/vid_svga.c index 9a3db62..b98d0fe 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -585,6 +585,7 @@ void svga_poll(void *p) { // pclog("VC split\n"); svga->ma = svga->maback = 0; + svga->sc = 0; if (svga->attrregs[0x10] & 0x20) svga->scrollcache = 0; } From 8a19e5634035a9818c7a31572eb2be2f09fc5da0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Sep 2018 20:16:27 +0100 Subject: [PATCH 0505/1050] Added recompiled versions of INC and DEC. --- src/codegen_backend_arm64_uops.c | 8 ++ src/codegen_backend_arm_uops.c | 8 ++ src/codegen_backend_x86-64_uops.c | 8 ++ src/codegen_backend_x86_uops.c | 8 ++ src/codegen_ops.c | 8 +- src/codegen_ops_arith.c | 127 ++++++++++++++++++++++++++++ src/codegen_ops_arith.h | 9 ++ src/codegen_ops_misc.c | 135 ++++++++++++++++++++++++++++-- 8 files changed, 298 insertions(+), 13 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index ebef0fc..1c29270 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -195,6 +195,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm64_call(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1413,6 +1420,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 427da2e..6a65d3b 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -268,6 +268,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1493,6 +1500,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 59f78b3..9e14a0b 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -149,6 +149,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_x86_CALL(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1205,6 +1212,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 4f1ceb8..5bca500 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -159,6 +159,13 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_x86_CALL(block, uop->p); + + return 0; +} + static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -1198,6 +1205,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, diff --git a/src/codegen_ops.c b/src/codegen_ops.c index ff7df3d..d4bfd76 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -20,7 +20,7 @@ RecompOpFn recomp_opcodes[512] = /*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, /*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8,NULL, NULL, NULL, NULL, NULL, /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, @@ -33,7 +33,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_16, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -42,7 +42,7 @@ RecompOpFn recomp_opcodes[512] = /*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, /*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8,NULL, NULL, NULL, NULL, NULL, /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, @@ -55,7 +55,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_32 }; diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 7331afc..1a9c8d1 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -1330,3 +1330,130 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_flags_changed = 1; return op_pc + 2; } + +static void rebuild_c(ir_data_t *ir) +{ + int needs_rebuild = 1; + + if (codegen_flags_changed) + { + switch (cpu_state.flags_op) + { + case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: + case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) + { + uop_CALL_FUNC(ir, flags_rebuild_c); + } +} + +uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); + if (fetchdat & 0x38) + { + uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } + else + { + uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + + if (fetchdat & 0x38) + { + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } + else + { + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) + { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } + else + { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + } + + return op_pc+1; +} diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h index 2faa55d..75a70b2 100644 --- a/src/codegen_ops_arith.h +++ b/src/codegen_ops_arith.h @@ -33,3 +33,12 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + + +uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 01c404f..999e17c 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -238,28 +238,97 @@ uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return 0; } +static void rebuild_c(ir_data_t *ir) +{ + int needs_rebuild = 1; + + if (codegen_flags_changed) + { + switch (cpu_state.flags_op) + { + case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: + case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) + { + uop_CALL_FUNC(ir, flags_rebuild_c); + } +} + uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + x86seg *target_seg = NULL; int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) return 0; - + if ((fetchdat & 0xc0) == 0xc0) src_reg = IREG_16(fetchdat & 7); else { - x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); src_reg = IREG_temp0_W; } switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + else + { + uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + return op_pc+1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + else + { + uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + return op_pc+1; + case 0x10: /*CALL*/ if ((fetchdat & 0xc0) == 0xc0) uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -286,26 +355,74 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + x86seg *target_seg = NULL; int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) return 0; if ((fetchdat & 0xc0) == 0xc0) src_reg = IREG_32(fetchdat & 7); else { - x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); src_reg = IREG_temp0; } switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + else + { + uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + return op_pc+1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) + { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + else + { + uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + return op_pc+1; + case 0x10: /*CALL*/ if ((fetchdat & 0xc0) == 0xc0) uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); From 1aadfd436d69d35a1ff641527c75448da842ef57 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 23 Sep 2018 21:45:12 +0100 Subject: [PATCH 0506/1050] Added recompiled versions of CBW, CDQ, CWD, CWDE and MOVSX. --- src/codegen_backend_arm64_ops.c | 6 +++ src/codegen_backend_arm64_ops.h | 2 + src/codegen_backend_arm64_uops.c | 33 +++++++++++++++ src/codegen_backend_arm_ops.c | 11 +++++ src/codegen_backend_arm_ops.h | 3 ++ src/codegen_backend_arm_uops.c | 33 +++++++++++++++ src/codegen_backend_x86-64_ops.c | 13 ++++++ src/codegen_backend_x86-64_ops.h | 4 ++ src/codegen_backend_x86-64_uops.c | 22 ++++++++++ src/codegen_backend_x86_ops.c | 13 ++++++ src/codegen_backend_x86_ops.h | 4 ++ src/codegen_backend_x86_uops.c | 22 ++++++++++ src/codegen_ir_defs.h | 3 ++ src/codegen_ops.c | 8 ++-- src/codegen_ops_misc.c | 25 ++++++++++++ src/codegen_ops_misc.h | 5 +++ src/codegen_ops_mov.c | 67 +++++++++++++++++++++++++++++++ src/codegen_ops_mov.h | 4 ++ 18 files changed, 274 insertions(+), 4 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 91e49e0..cab45ac 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -71,6 +71,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDRB_IMM_W (0x0e5 << 22) #define OPCODE_LDRH_IMM (0x1e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) +#define OPCODE_SBFX (0x04c << 22) #define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22) #define OPCODE_STR_IMM_Q (0x3e4 << 22) @@ -640,6 +641,11 @@ void host_arm64_RET(codeblock_t *block, int reg) codegen_addlong(block, OPCODE_RET | Rn(reg)); } +void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +{ + codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); +} + void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 35d5044..2c47509 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -83,6 +83,8 @@ void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_RET(codeblock_t *block, int reg); +void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); + void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 1c29270..b98084e 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -896,6 +896,38 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); + } + else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); + } + else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); + } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1448,6 +1480,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_ADD & UOP_MASK] = codegen_ADD, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 66941ce..110ddd5 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -89,6 +89,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDRH_REG 0xe19000b0 #define OPCODE_STRH_IMM 0xe1c000b0 #define OPCODE_STRH_REG 0xe18000b0 +#define OPCODE_SXTB 0xe6af0070 +#define OPCODE_SXTH 0xe6bf0070 #define OPCODE_UADD8 0xe6500f90 #define OPCODE_UADD16 0xe6500f10 #define OPCODE_USUB8 0xe6500ff0 @@ -664,6 +666,15 @@ void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int sr codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } +void host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +{ + codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +} +void host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +{ + codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +} + void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) { uint32_t arm_imm; diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 6dcb29e..7df158b 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -99,6 +99,9 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); +void host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); + void host_arm_TST_IMM(codeblock_t *block, int src_reg1, uint32_t imm); void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 6a65d3b..5d87692 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -970,6 +970,38 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_arm_SXTB(block, dest_reg, src_reg, 0); + } + else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) + { + host_arm_SXTB(block, dest_reg, src_reg, 8); + } + else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_arm_SXTH(block, dest_reg, src_reg, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_arm_SXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) + { + host_arm_SXTB(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1528,6 +1560,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_ADD & UOP_MASK] = codegen_ADD, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 6de5334..45fde94 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -812,6 +812,19 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } +void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} + void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 2bef40c..85ec419 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -86,6 +86,10 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); +void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 9e14a0b..773349d 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -801,6 +801,27 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); return 0; } +static int codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; +} static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1240,6 +1261,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_ADD & UOP_MASK] = codegen_ADD, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index b61abd1..355b8f8 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -691,6 +691,19 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } +void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} + void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 6fa0a97..7bf81ed 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -88,6 +88,10 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); +void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 5bca500..e2d64ed 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -798,6 +798,27 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); return 0; } +static int codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) + { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + return 0; +} static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1233,6 +1254,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_ADD & UOP_MASK] = codegen_ADD, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 22b1e70..591a6df 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -60,6 +60,8 @@ #define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) /*UOP_MOVZX - dest_reg = zero_extend(src_reg_a)*/ #define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) +/*UOP_MOVSX - dest_reg = sign_extend(src_reg_a)*/ +#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ @@ -435,6 +437,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) #define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) #define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) #define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index d4bfd76..a33b4ba 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -26,7 +26,7 @@ RecompOpFn recomp_opcodes[512] = /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, -/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, @@ -48,7 +48,7 @@ RecompOpFn recomp_opcodes[512] = /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, -/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, @@ -76,7 +76,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -98,7 +98,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 999e17c..c0bb217 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -451,3 +451,28 @@ uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc { return op_pc; } + +uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOVSX(ir, IREG_AX, IREG_AL); + + return op_pc; +} +uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); + + return op_pc; +} +uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); + + return op_pc; +} +uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOVSX(ir, IREG_EAX, IREG_AX); + + return op_pc; +} diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index 832c747..c20df48 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -9,3 +9,8 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index 274adcd..26ee1a1 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -459,6 +459,73 @@ uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 1; } +uint32_t ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); + } + + return op_pc + 1; +} + uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h index c6c418d..90c6eb8 100644 --- a/src/codegen_ops_mov.h +++ b/src/codegen_ops_mov.h @@ -25,6 +25,10 @@ uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 592b07be638bac354547929accdd1c77174f8522 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 Sep 2018 17:42:44 +0100 Subject: [PATCH 0507/1050] Added recompiled versions of JMP indirect, JMP far, RETF, LxS, XLAT and LEAVE. --- src/codegen_backend_arm64_uops.c | 39 +++++++++ src/codegen_backend_arm_uops.c | 39 +++++++++ src/codegen_backend_x86-64_uops.c | 43 ++++++++++ src/codegen_backend_x86_uops.c | 39 +++++++++ src/codegen_ir_defs.h | 27 ++++-- src/codegen_ops.c | 16 ++-- src/codegen_ops_jump.c | 136 ++++++++++++++++++++++++++++++ src/codegen_ops_jump.h | 9 ++ src/codegen_ops_misc.c | 83 +++++++++++++++++- src/codegen_ops_misc.h | 11 +++ src/codegen_ops_mov.c | 14 +++ src/codegen_ops_mov.h | 2 + src/codegen_ops_stack.c | 33 ++++++++ src/codegen_ops_stack.h | 3 + 14 files changed, 475 insertions(+), 19 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index b98084e..1e8ffb3 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -602,6 +602,36 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) + { + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + } + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); @@ -690,6 +720,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { host_arm64_call(block, codegen_mem_load_byte); @@ -763,6 +795,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); if (REG_IS_B(src_size)) { host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); @@ -1460,6 +1494,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 5d87692..9b21d04 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -676,6 +676,36 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + } + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); @@ -761,6 +791,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); @@ -832,6 +864,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); if (REG_IS_B(src_size)) { host_arm_MOV_REG(block, REG_R1, src_reg); @@ -1540,6 +1574,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 773349d..bef4bcb 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -531,6 +531,40 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) + { +#if WIN64 + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); +#else + host_x86_MOV16_REG_REG(block, REG_EDI, src_reg); +#endif + } + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { #if WIN64 @@ -624,6 +658,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); if (REG_IS_B(dest_size)) { host_x86_CALL(block, codegen_mem_load_byte); @@ -729,6 +765,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); if (REG_IS_B(src_size)) { host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); @@ -1241,6 +1279,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index e2d64ed..235176d 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -542,6 +542,36 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) + { + host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); + } + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); @@ -622,6 +652,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); if (REG_IS_B(dest_size)) { host_x86_CALL(block, codegen_mem_load_byte); @@ -689,6 +721,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) int src_size = IREG_GET_SIZE(uop->src_reg_c_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); if (REG_IS_B(src_size)) { host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); @@ -1234,6 +1268,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 591a6df..c0b23c2 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -37,10 +37,10 @@ #define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) #define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) #define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) -#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08) -#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09) -#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a) -#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b) +#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) #define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) /*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/ #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) @@ -333,6 +333,17 @@ static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_re uop->src_reg_c = codegen_reg_read(src_reg_c); } +static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->imm_data = imm; +} + static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { uop_t *uop = uop_alloc(ir); @@ -377,7 +388,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, uop->imm_data = imm; } -#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1_arg(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) +#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) @@ -427,9 +438,11 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) #define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) -#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg) +#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) #define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) -#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg) +#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset) #define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) #define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) #define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index a33b4ba..188e284 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -30,9 +30,9 @@ RecompOpFn recomp_opcodes[512] = /*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, -/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, +/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES_16, ropLDS_16, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, ropRETF_imm_16, ropRETF_16, NULL, NULL, NULL, NULL, +/*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, ropJMP_far_16, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_16, /*32-bit data*/ @@ -52,9 +52,9 @@ RecompOpFn recomp_opcodes[512] = /*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, -/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, +/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES_32, ropLDS_32, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, ropRETF_imm_32, ropRETF_32, NULL, NULL, NULL, NULL, +/*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_32 }; @@ -76,7 +76,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, +/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -98,7 +98,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, +/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c index 8ae6816..1d677d2 100644 --- a/src/codegen_ops_jump.c +++ b/src/codegen_ops_jump.c @@ -2,6 +2,7 @@ #include "x86.h" #include "386_common.h" +#include "386.h" #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" @@ -30,6 +31,33 @@ uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return -1; } +uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t new_pc = fastreadw(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 2); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); + + return -1; +} +uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t new_pc = fastreadl(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 4); + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); + + return -1; +} + uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); @@ -128,3 +156,111 @@ uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 return -1; } + +uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((msw&1) && !(eflags&VM_FLAG)) + return 0; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4); + + return -1; +} +uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((msw&1) && !(eflags&VM_FLAG)) + return 0; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8); + + return -1; +} + +uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t offset; + + if ((msw&1) && !(eflags&VM_FLAG)) + return 0; + + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4+offset); + + return -1; +} +uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t offset; + + if ((msw&1) && !(eflags&VM_FLAG)) + return 0; + + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8+offset); + + return -1; +} diff --git a/src/codegen_ops_jump.h b/src/codegen_ops_jump.h index ee6a591..db4c95c 100644 --- a/src/codegen_ops_jump.h +++ b/src/codegen_ops_jump.h @@ -2,6 +2,9 @@ uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); @@ -10,3 +13,9 @@ uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index c0bb217..e3635e3 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -3,6 +3,7 @@ #include "x86.h" #include "x86_flags.h" #include "386_common.h" +#include "386.h" #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" @@ -263,12 +264,16 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe { x86seg *target_seg = NULL; int src_reg, sp_reg; - - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) return 0; if ((fetchdat & 0xc0) == 0xc0) + { + if ((fetchdat & 0x38) == 0x28) + return 0; src_reg = IREG_16(fetchdat & 7); + } else { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -337,10 +342,18 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe SUB_SP(ir, 2); uop_MOVZX(ir, IREG_pc, src_reg); return -1; - + case 0x20: /*JMP*/ uop_MOVZX(ir, IREG_pc, src_reg); return -1; + + case 0x28: /*JMP far*/ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc); + uop_CALL_FUNC(ir, loadcsjmp); + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; case 0x30: /*PUSH*/ if ((fetchdat & 0xc0) == 0xc0) @@ -358,11 +371,15 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe x86seg *target_seg = NULL; int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30) + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) return 0; if ((fetchdat & 0xc0) == 0xc0) + { + if ((fetchdat & 0x38) == 0x28) + return 0; src_reg = IREG_32(fetchdat & 7); + } else { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -436,6 +453,14 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MOV(ir, IREG_pc, src_reg); return -1; + case 0x28: /*JMP far*/ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc); + uop_CALL_FUNC(ir, loadcsjmp); + uop_MOV(ir, IREG_pc, src_reg); + return -1; + case 0x30: /*PUSH*/ if ((fetchdat & 0xc0) == 0xc0) uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -476,3 +501,53 @@ uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet return op_pc; } + +#define ropLxS(name, seg) \ +uint32_t rop ## name ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ +} \ +uint32_t rop ## name ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ +} + +ropLxS(LDS, &cpu_state.seg_ds) +ropLxS(LES, &cpu_state.seg_es) +ropLxS(LFS, &cpu_state.seg_fs) +ropLxS(LGS, &cpu_state.seg_gs) +ropLxS(LSS, &cpu_state.seg_ss) diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index c20df48..20f115d 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -14,3 +14,14 @@ uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropLDS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLDS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLES_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLES_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLFS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLFS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLGS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLGS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLSS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLSS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index 26ee1a1..c33271f 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -696,3 +696,17 @@ uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc + 1; } + +uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + uop_MOVZX(ir, IREG_eaaddr, IREG_AL); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); + if (!(op_32 & 0x200)) + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + + uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); + + return op_pc; +} diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h index 90c6eb8..03a9cb8 100644 --- a/src/codegen_ops_mov.h +++ b/src/codegen_ops_mov.h @@ -39,3 +39,5 @@ uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c index befeb4e..fb63e1d 100644 --- a/src/codegen_ops_stack.c +++ b/src/codegen_ops_stack.c @@ -255,3 +255,36 @@ ROP_POP_SEG(DS, cpu_state.seg_ds) ROP_POP_SEG(ES, cpu_state.seg_es) ROP_POP_SEG(FS, cpu_state.seg_fs) ROP_POP_SEG(GS, cpu_state.seg_gs) + +uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); + uop_MOV(ir, IREG_BP, IREG_temp0_W); + + return op_pc; +} +uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); + else + { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); + uop_MOV(ir, IREG_EBP, IREG_temp0); + + return op_pc; +} diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h index 240cc1f..9af5d60 100644 --- a/src/codegen_ops_stack.h +++ b/src/codegen_ops_stack.h @@ -35,3 +35,6 @@ uint32_t ropPOP_DS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t ropPOP_ES_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPOP_FS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPOP_GS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 94fe85b17e262c653f9b65240f78f7706f2cbd5c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 Sep 2018 17:43:02 +0100 Subject: [PATCH 0508/1050] Fixed video clock on Cirrus Logic cards. --- src/vid_cl5429.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index f2e5b05..c9a20d5 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -555,7 +555,7 @@ void gd5429_recalctimings(svga_t *svga) vclk /= 3.0; break; } - svga->clock = cpuclock / vclk; + svga->clock = (cpuclock * (float)(1ull << 32)) / vclk; svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd5429->vram_mask : 0x3ffff; } From e9ff110021d5078c840468fd33cd803bc66ae4ff Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 30 Sep 2018 17:30:28 +0100 Subject: [PATCH 0509/1050] Fixed flags on register->register ADD/SUB opcode 00/01/28/29. Fixes rendering in Need For Speed II. --- src/codegen_ops_arith.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 1a9c8d1..f4e4152 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -87,6 +87,7 @@ uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int dest_reg = fetchdat & 7; uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); } @@ -102,9 +103,9 @@ uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); } - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); codegen_flags_changed = 1; @@ -150,6 +151,7 @@ uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int dest_reg = fetchdat & 7; uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); } @@ -165,9 +167,9 @@ uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); } - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); codegen_flags_changed = 1; @@ -212,6 +214,7 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int dest_reg = fetchdat & 7; uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); } @@ -227,9 +230,9 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_temp1); } - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); codegen_flags_changed = 1; @@ -538,6 +541,7 @@ uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int dest_reg = fetchdat & 7; uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); } @@ -553,9 +557,9 @@ uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); } - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); codegen_flags_changed = 1; @@ -601,6 +605,7 @@ uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int dest_reg = fetchdat & 7; uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); } @@ -616,9 +621,10 @@ uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); } - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); codegen_flags_changed = 1; @@ -663,6 +669,7 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int dest_reg = fetchdat & 7; uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); } @@ -678,9 +685,10 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_temp1); } - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); codegen_flags_changed = 1; From dbb01ef9e22263b6e26a9db929e5024aab1c85df Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 1 Oct 2018 21:02:40 +0100 Subject: [PATCH 0510/1050] Cleaned up x87 tag register handling. --- src/x87.c | 34 ++++++++++++++++++++--------- src/x87.h | 7 ++++-- src/x87_ops.h | 12 ++++++----- src/x87_ops_arith.h | 48 ++++++++++++++++++++--------------------- src/x87_ops_loadstore.h | 4 ++-- src/x87_ops_misc.h | 40 +++++++++++++++++----------------- 6 files changed, 82 insertions(+), 63 deletions(-) diff --git a/src/x87.c b/src/x87.c index 25ce726..625e56e 100644 --- a/src/x87.c +++ b/src/x87.c @@ -19,6 +19,11 @@ #include "x87.h" #include "386_common.h" +#define X87_TAG_VALID 0 +#define X87_TAG_ZERO 1 +#define X87_TAG_INVALID 2 +#define X87_TAG_EMPTY 3 + uint16_t x87_gettag() { uint16_t ret = 0; @@ -26,10 +31,14 @@ uint16_t x87_gettag() for (c = 0; c < 8; c++) { - if (cpu_state.tag[c] & TAG_UINT64) + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) ret |= 2 << (c*2); + else if (cpu_state.ST[c] == 0.0) + ret |= X87_TAG_ZERO << (c * 2); else - ret |= (cpu_state.tag[c] << (c*2)); + ret |= X87_TAG_VALID << (c * 2); } return ret; @@ -37,14 +46,19 @@ uint16_t x87_gettag() void x87_settag(uint16_t new_tag) { - cpu_state.tag[0] = new_tag & 3; - cpu_state.tag[1] = (new_tag >> 2) & 3; - cpu_state.tag[2] = (new_tag >> 4) & 3; - cpu_state.tag[3] = (new_tag >> 6) & 3; - cpu_state.tag[4] = (new_tag >> 8) & 3; - cpu_state.tag[5] = (new_tag >> 10) & 3; - cpu_state.tag[6] = (new_tag >> 12) & 3; - cpu_state.tag[7] = (new_tag >> 14) & 3; + int c; + + for (c = 0; c < 8; c++) + { + int tag = (new_tag >> (c * 2)) & 3; + + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } } void x87_dumpregs() diff --git a/src/x87.h b/src/x87.h index 790b6eb..cd4ccbb 100644 --- a/src/x87.h +++ b/src/x87.h @@ -10,7 +10,7 @@ static inline void x87_set_mmx() static inline void x87_emms() { - *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + *(uint64_t *)cpu_state.tag = 0; cpu_state.ismmx = 0; } @@ -19,5 +19,8 @@ void x87_settag(uint16_t new_tag); void x87_dumpregs(); void x87_reset(); +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ -#define TAG_UINT64 (1 << 2) +#define TAG_UINT64 (1 << 7) + diff --git a/src/x87_ops.h b/src/x87_ops.h index dc15866..3756c19 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -40,7 +40,7 @@ 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; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; } static inline void x87_push_u64(uint64_t i) @@ -55,13 +55,13 @@ static inline void x87_push_u64(uint64_t i) cpu_state.TOP=(cpu_state.TOP-1)&7; cpu_state.ST[cpu_state.TOP] = td.d; - cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; } static inline double x87_pop() { double t = cpu_state.ST[cpu_state.TOP]; - cpu_state.tag[cpu_state.TOP&7] = 3; + cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; cpu_state.TOP=(cpu_state.TOP+1)&7; return t; } @@ -186,13 +186,15 @@ static inline void x87_ld_frstor(int reg) cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); - if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) { - cpu_state.tag[reg] = TAG_UINT64; cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; } else + { + cpu_state.tag[reg] = TAG_VALID; cpu_state.ST[reg] = x87_ld80(); + } } static inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) diff --git a/src/x87_ops_arith.h b/src/x87_ops_arith.h index 45077c7..4561c82 100644 --- a/src/x87_ops_arith.h +++ b/src/x87_ops_arith.h @@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ ST(0) += use_var; \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ CLOCK_CYCLES(11); \ return 0; \ } \ @@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \ + cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } @@ -121,7 +121,7 @@ static int opFADD(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FADD\n"); ST(0) = ST(0) + ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -131,7 +131,7 @@ static int opFADDr(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FADD\n"); ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -141,7 +141,7 @@ static int opFADDP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FADDP\n"); ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(8); return 0; @@ -232,7 +232,7 @@ static int opFDIV(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIV\n"); x87_div(ST(0), ST(0), ST(fetchdat & 7)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -242,7 +242,7 @@ static int opFDIVr(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIV\n"); x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -252,7 +252,7 @@ static int opFDIVP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIVP\n"); x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(73); return 0; @@ -264,7 +264,7 @@ static int opFDIVR(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIVR\n"); x87_div(ST(0), ST(fetchdat&7), ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -274,7 +274,7 @@ static int opFDIVRr(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIVR\n"); x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -284,7 +284,7 @@ static int opFDIVRP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIVR\n"); x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(73); return 0; @@ -296,7 +296,7 @@ static int opFMUL(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FMUL\n"); ST(0) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(16); return 0; } @@ -306,7 +306,7 @@ static int opFMULr(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FMUL\n"); ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(16); return 0; } @@ -316,7 +316,7 @@ static int opFMULP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FMULP\n"); ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(16); return 0; @@ -328,7 +328,7 @@ static int opFSUB(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUB\n"); ST(0) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -338,7 +338,7 @@ static int opFSUBr(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUB\n"); ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -348,7 +348,7 @@ static int opFSUBP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUBP\n"); ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(8); return 0; @@ -360,7 +360,7 @@ static int opFSUBR(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUBR\n"); ST(0) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -370,7 +370,7 @@ static int opFSUBRr(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUBR\n"); ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -380,7 +380,7 @@ static int opFSUBRP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUBRP\n"); ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(8); return 0; diff --git a/src/x87_ops_loadstore.h b/src/x87_ops_loadstore.h index bf9fc1f..7a0b938 100644 --- a/src/x87_ops_loadstore.h +++ b/src/x87_ops_loadstore.h @@ -96,7 +96,7 @@ static int opFILDiq_a16(uint32_t fetchdat) if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); x87_push((double)temp64); cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID | TAG_UINT64; CLOCK_CYCLES(10); return 0; @@ -112,7 +112,7 @@ static int opFILDiq_a32(uint32_t fetchdat) if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); x87_push((double)temp64); cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID | TAG_UINT64; CLOCK_CYCLES(10); return 0; diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 5f21a99..34a28d0 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -34,7 +34,7 @@ static int opFINIT(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; + *(uint64_t *)cpu_state.tag = 0; cpu_state.TOP = 0; cpu_state.ismmx = 0; CLOCK_CYCLES(17); @@ -47,7 +47,7 @@ static int opFFREE(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; if (fplog) pclog("FFREE\n"); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; CLOCK_CYCLES(3); return 0; } @@ -278,7 +278,7 @@ 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; + *(uint64_t *)cpu_state.tag = 0; cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -369,7 +369,7 @@ static int opFCHS(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FCHS\n"); ST(0) = -ST(0); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(6); return 0; } @@ -380,7 +380,7 @@ static int opFABS(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FABS %f\n", ST(0)); ST(0) = fabs(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(3); return 0; } @@ -403,7 +403,7 @@ static int opFXAM(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FXAM %i %f\n", cpu_state.tag[cpu_state.TOP&7], ST(0)); cpu_state.npxs &= ~(C0|C1|C2|C3); - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); + if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3); else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; @@ -477,7 +477,7 @@ static int opFLDZ(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLDZ\n"); x87_push(0.0); - cpu_state.tag[cpu_state.TOP&7] = 1; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(4); return 0; } @@ -488,7 +488,7 @@ static int opF2XM1(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("F2XM1\n"); ST(0) = pow(2.0, ST(0)) - 1.0; - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(200); return 0; } @@ -499,7 +499,7 @@ static int opFYL2X(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FYL2X\n"); ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(250); return 0; @@ -511,7 +511,7 @@ static int opFYL2XP1(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FYL2XP1\n"); ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(250); return 0; @@ -523,7 +523,7 @@ static int opFPTAN(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FPTAN\n"); ST(0) = tan(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; CLOCK_CYCLES(235); @@ -536,7 +536,7 @@ static int opFPATAN(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FPATAN\n"); ST(1) = atan2(ST(1), ST(0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(250); return 0; @@ -570,7 +570,7 @@ static int opFPREM(uint32_t fetchdat) if (fplog) pclog("FPREM %f %f ", ST(0), ST(1)); temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; if (fplog) pclog("%f\n", ST(0)); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; @@ -587,7 +587,7 @@ static int opFPREM1(uint32_t fetchdat) if (fplog) pclog("FPREM1 %f %f ", ST(0), ST(1)); temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; if (fplog) pclog("%f\n", ST(0)); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; @@ -603,7 +603,7 @@ static int opFSQRT(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSQRT\n"); ST(0) = sqrt(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(83); return 0; } @@ -616,7 +616,7 @@ static int opFSINCOS(uint32_t fetchdat) if (fplog) pclog("FSINCOS\n"); td = ST(0); ST(0) = sin(td); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; CLOCK_CYCLES(330); @@ -629,7 +629,7 @@ static int opFRNDINT(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FRNDINT %g ", ST(0)); ST(0) = (double)x87_fround(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; if (fplog) pclog("%g\n", ST(0)); CLOCK_CYCLES(21); return 0; @@ -643,7 +643,7 @@ static int opFSCALE(uint32_t fetchdat) if (fplog) pclog("FSCALE\n"); temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; CLOCK_CYCLES(30); return 0; } @@ -654,7 +654,7 @@ static int opFSIN(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSIN\n"); ST(0) = sin(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -666,7 +666,7 @@ static int opFCOS(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FCOS\n"); ST(0) = cos(ST(0)); - cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; + cpu_state.tag[cpu_state.TOP] = TAG_VALID; cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; From 78996b3e5c0175a48c51398552d0151eeedefea2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 7 Oct 2018 22:02:31 +0100 Subject: [PATCH 0511/1050] Added recompiled register versions of FADD, FDIV, FDIVR, FMUL, FSUB and FSUBR. --- src/codegen.c | 4 +- src/codegen_backend.h | 7 +- src/codegen_backend_arm.c | 25 +- src/codegen_backend_arm64.c | 26 ++- src/codegen_backend_arm64_defs.h | 37 ++- src/codegen_backend_arm64_ops.c | 67 ++++++ src/codegen_backend_arm64_ops.h | 13 ++ src/codegen_backend_arm64_uops.c | 127 +++++++++++ src/codegen_backend_arm_defs.h | 18 ++ src/codegen_backend_arm_ops.c | 35 +++ src/codegen_backend_arm_ops.h | 7 + src/codegen_backend_arm_uops.c | 121 ++++++++++ src/codegen_backend_x86-64.c | 24 +- src/codegen_backend_x86-64.h | 2 + src/codegen_backend_x86-64_defs.h | 22 ++ src/codegen_backend_x86-64_ops.c | 115 ++++++++++ src/codegen_backend_x86-64_ops.h | 17 ++ src/codegen_backend_x86-64_uops.c | 134 +++++++++++ src/codegen_backend_x86.c | 34 ++- src/codegen_backend_x86_defs.h | 12 + src/codegen_backend_x86_ops.c | 95 ++++++++ src/codegen_backend_x86_ops.h | 17 ++ src/codegen_backend_x86_uops.c | 130 +++++++++++ src/codegen_ir_defs.h | 36 ++- src/codegen_ops.c | 95 ++++++++ src/codegen_ops.h | 8 +- src/codegen_ops_fpu_arith.c | 134 +++++++++++ src/codegen_ops_fpu_arith.h | 12 + src/codegen_reg.c | 364 ++++++++++++++++++++---------- src/codegen_reg.h | 46 +++- src/ibm.h | 16 +- 31 files changed, 1638 insertions(+), 162 deletions(-) create mode 100644 src/codegen_ops_fpu_arith.c create mode 100644 src/codegen_ops_fpu_arith.h diff --git a/src/codegen.c b/src/codegen.c index ee782d1..409221f 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -360,7 +360,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xd8: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = NULL;//recomp_opcodes_d8; + recomp_op_table = recomp_opcodes_d8; opcode_shift = 3; opcode_mask = 0x1f; over = 1; @@ -397,7 +397,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdc: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = NULL;//recomp_opcodes_dc; + recomp_op_table = recomp_opcodes_dc; opcode_shift = 3; opcode_mask = 0x1f; over = 1; diff --git a/src/codegen_backend.h b/src/codegen_backend.h index 0f73290..df6fcea 100644 --- a/src/codegen_backend.h +++ b/src/codegen_backend.h @@ -1,9 +1,9 @@ //#ifdef __amd64__ //#include "codegen_x86-64.h" -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 -#include "codegen_backend_x86.h" -#elif defined __amd64__ +#if defined __amd64__ #include "codegen_backend_x86-64.h" +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#include "codegen_backend_x86.h" #elif defined __ARM_EABI__ #include "codegen_backend_arm.h" #elif defined __aarch64__ @@ -65,3 +65,4 @@ typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop); extern const uOpFn uop_handlers[]; extern int codegen_host_reg_list[CODEGEN_HOST_REGS]; +extern int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS]; diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index fb2d6f2..3b9c5fe 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -6,6 +6,7 @@ #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" #include "codegen_backend_arm_ops.h" +#include "codegen_reg.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -35,6 +36,18 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_R11, }; +int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +{ + REG_D8, + REG_D9, + REG_D10, + REG_D11, + REG_D12, + REG_D13, + REG_D14, + REG_D15 +}; + static void build_load_routine(codeblock_t *block, int size) { uint32_t *branch_offset; @@ -220,7 +233,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm_nop(block); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); while (block_pos != BLOCK_START) host_arm_nop(block); @@ -228,13 +241,19 @@ void codegen_backend_prologue(codeblock_t *block) /*Entry code*/ host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); - host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); + host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t)&cpu_state); + if (block->flags & CODEBLOCK_HAS_FPU) + { + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + } } void codegen_backend_epilogue(codeblock_t *block) { - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x20); + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); if (block_pos > ARM_LITERAL_POOL_OFFSET) diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 4ae98f0..57eb10b 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -6,6 +6,7 @@ #include "codegen_backend.h" #include "codegen_backend_arm64_defs.h" #include "codegen_backend_arm64_ops.h" +#include "codegen_reg.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -38,6 +39,18 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_X28 }; +int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +{ + REG_V8, + REG_V9, + REG_V10, + REG_V11, + REG_V12, + REG_V13, + REG_V14, + REG_V15 +}; + static void build_load_routine(codeblock_t *block, int size) { uint32_t *branch_offset; @@ -237,7 +250,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm64_NOP(block); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 48); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64); host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); @@ -255,15 +268,22 @@ void codegen_backend_prologue(codeblock_t *block) host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_SP, -16); host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_SP, -16); host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -48); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -64); offset = add_literal_q(block, (uintptr_t)&cpu_state); host_arm64_LDR_LITERAL_X(block, REG_CPUSTATE, offset); + + if (block->flags & CODEBLOCK_HAS_FPU) + { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + } } void codegen_backend_epilogue(codeblock_t *block) { - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 48); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64); host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index c818d89..207fd80 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -64,6 +64,39 @@ #define REG_X30 30 #define REG_XZR 31 +#define REG_V0 0 +#define REG_V1 1 +#define REG_V2 2 +#define REG_V3 3 +#define REG_V4 4 +#define REG_V5 5 +#define REG_V6 6 +#define REG_V7 7 +#define REG_V8 8 +#define REG_V9 9 +#define REG_V10 10 +#define REG_V11 11 +#define REG_V12 12 +#define REG_V13 13 +#define REG_V14 14 +#define REG_V15 15 +#define REG_V16 16 +#define REG_V17 17 +#define REG_V18 18 +#define REG_V19 19 +#define REG_V20 20 +#define REG_V21 21 +#define REG_V22 22 +#define REG_V23 23 +#define REG_V24 24 +#define REG_V25 25 +#define REG_V26 26 +#define REG_V27 27 +#define REG_V28 28 +#define REG_V29 29 +#define REG_V30 30 +#define REG_V31 31 + #define REG_SP 31 #define REG_ARG0 REG_X0 @@ -73,9 +106,11 @@ #define REG_CPUSTATE REG_X29 -#define REG_TEMP REG_X7 +#define REG_TEMP REG_X7 +#define REG_TEMP2 REG_X6 #define CODEGEN_HOST_REGS 10 +#define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index cab45ac..a7a3cd6 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -48,6 +48,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SHIFT 24 #define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) #define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) +#define OPCODE_B (0x14 << OPCODE_SHIFT) #define OPCODE_BCOND (0x54 << OPCODE_SHIFT) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) #define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) @@ -68,6 +69,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BFI (0x0cc << 22) #define OPCODE_LDR_IMM_W (0x2e5 << 22) +#define OPCODE_LDR_IMM_F64 (0x3f5 << 22) #define OPCODE_LDRB_IMM_W (0x0e5 << 22) #define OPCODE_LDRH_IMM (0x1e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) @@ -75,6 +77,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22) #define OPCODE_STR_IMM_Q (0x3e4 << 22) +#define OPCODE_STR_IMM_F64 (0x3f4 << 22) #define OPCODE_STRB_IMM (0x0e4 << 22) #define OPCODE_STRH_IMM (0x1e4 << 22) #define OPCODE_UBFX (0x14c << 22) @@ -99,10 +102,15 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ASR (0x1ac02800) #define OPCODE_BLR (0xd63f0000) #define OPCODE_BR (0xd61f0000) +#define OPCODE_FADD_D (0x1e602800) +#define OPCODE_FDIV_D (0x1e601800) +#define OPCODE_FMUL_D (0x1e600800) +#define OPCODE_FSUB_D (0x1e603800) #define OPCODE_LDR_REG (0xb8606800) #define OPCODE_LDRB_REG (0x38606800) #define OPCODE_LDRH_REG (0x78606800) #define OPCODE_LDRX_REG_LSL3 (0xf8607800) +#define OPCODE_LDR_REG_F64_S (0xfc607800) #define OPCODE_LSL (0x1ac02000) #define OPCODE_LSR (0x1ac02400) #define OPCODE_NOP (0xd503201f) @@ -110,6 +118,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_STR_REG (0xb8206800) #define OPCODE_STRB_REG (0x38206800) #define OPCODE_STRH_REG (0x78206800) +#define OPCODE_STR_REG_F64_S (0xfc207800) #define DATPROC_SHIFT(sh) (sh << 10) #define DATPROC_IMM_SHIFT(sh) (sh << 22) @@ -124,6 +133,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define IMMS(imms) ((imms) << 10) #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) +#define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) #define OFFSET12_B(offset) (offset << 10) #define OFFSET12_H(offset) ((offset >> 1) << 10) @@ -146,6 +156,16 @@ static int offset_is_19bit(int offset) return 1; } +/*Returns true if offset fits into 26 bits*/ +static int offset_is_26bit(int offset) +{ + if (offset >= (1 << (25+2))) + return 0; + if (offset < -(1 << (25+2))) + return 0; + return 1; +} + int add_literal(codeblock_t *block, uint32_t data) { if (literal_offset >= 4096) @@ -296,6 +316,15 @@ void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_re codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } +void host_arm64_B(codeblock_t *block, void *dest) +{ + int offset = (uintptr_t)dest - (uintptr_t)&block->data[block_pos]; + + if (!offset_is_26bit(offset)) + fatal("host_arm64_B - offset out of range %x\n", offset); + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); +} + void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); @@ -461,6 +490,26 @@ void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, in codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ @@ -515,6 +564,15 @@ void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offs codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } +void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} + void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { if (!in_range12_b(offset)) @@ -670,6 +728,15 @@ void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offse codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } +void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) +{ + codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); +} +void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} + void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { if (!in_range12_b(offset)) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 2c47509..da83275 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -11,6 +11,8 @@ void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_ void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg); +void host_arm64_B(codeblock_t *block, void *dest); + void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); void host_arm64_BLR(codeblock_t *block, int addr_reg); @@ -49,6 +51,11 @@ void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, in void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -56,6 +63,9 @@ void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offs void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset); void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); +void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); + void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); @@ -91,6 +101,9 @@ void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int of void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); +void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset); +void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg); + void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 1e8ffb3..cb8e7cc 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1,6 +1,8 @@ #ifdef __aarch64__ #include "ibm.h" +#include "x86.h" +#include "386_common.h" #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_arm64_defs.h" @@ -15,6 +17,7 @@ #define REG_IS_W(size) (size == IREG_SIZE_W) #define REG_IS_B(size) (size == IREG_SIZE_B) #define REG_IS_BH(size) (size == IREG_SIZE_BH) +#define REG_IS_D(size) (size == IREG_SIZE_D) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -595,6 +598,85 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FDIV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); + + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); + + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]); + + host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); + + return 0; +} + static int codegen_JMP(codeblock_t *block, uop_t *uop) { host_arm64_jump(block, (uintptr_t)uop->p); @@ -1561,6 +1643,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) @@ -1584,6 +1673,21 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); +} +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { @@ -1606,6 +1710,29 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) else fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); +} +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index e094838..0a246fa 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -24,6 +24,23 @@ #define REG_TEMP REG_R3 +#define REG_D0 0 +#define REG_D1 1 +#define REG_D2 2 +#define REG_D3 3 +#define REG_D4 4 +#define REG_D5 5 +#define REG_D6 6 +#define REG_D7 7 +#define REG_D8 8 +#define REG_D9 9 +#define REG_D10 10 +#define REG_D11 11 +#define REG_D12 12 +#define REG_D13 13 +#define REG_D14 14 +#define REG_D15 15 + #define REG_MASK_R0 (1 << REG_R0) #define REG_MASK_R1 (1 << REG_R1) #define REG_MASK_R2 (1 << REG_R2) @@ -45,6 +62,7 @@ REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) #define CODEGEN_HOST_REGS 7 +#define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 110ddd5..2146efe 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -97,6 +97,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_USUB16 0xe6500f70 #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 +#define OPCODE_VADD 0xee300b00 +#define OPCODE_VDIV 0xee800b00 +#define OPCODE_VLDR 0xed900b00 +#define OPCODE_VMUL 0xee200b00 +#define OPCODE_VSTR 0xed800b00 +#define OPCODE_VSUB 0xee300b40 #define B_OFFSET(x) (((x) >> 2) & 0xffffff) @@ -724,4 +730,33 @@ void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } +void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if ((offset > 1020) || (offset & 3)) + fatal("VLDR bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) +{ + if ((offset > 1020) || (offset & 3)) + fatal("VSTR bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} + #endif \ No newline at end of file diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 7df158b..a446bf1 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -113,3 +113,10 @@ void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); + +void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); +void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 9b21d04..d09f0e3 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1,6 +1,8 @@ #ifdef __ARM_EABI__ #include "ibm.h" +#include "x86.h" +#include "386_common.h" #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" @@ -73,6 +75,7 @@ void host_arm_nop(codeblock_t *block) #define REG_IS_W(size) (size == IREG_SIZE_W) #define REG_IS_B(size) (size == IREG_SIZE_B) #define REG_IS_BH(size) (size == IREG_SIZE_BH) +#define REG_IS_D(size) (size == IREG_SIZE_D) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -669,6 +672,85 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FDIV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + *branch_ptr |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; + + return 0; +} + static int codegen_JMP(codeblock_t *block, uop_t *uop) { host_arm_B(block, (uintptr_t)uop->p); @@ -1641,6 +1723,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB }; void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) @@ -1660,6 +1749,18 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +{ + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { @@ -1685,6 +1786,26 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) else fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index deda8ef..4fb6fe0 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -5,6 +5,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" #include "codegen_backend_x86-64_ops.h" +#include "codegen_reg.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -30,6 +31,17 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_EDX }; +int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +{ + REG_XMM0, + REG_XMM1, + REG_XMM2, + REG_XMM3, + REG_XMM4, + REG_XMM5, + REG_XMM6 +}; + static void *mem_abrt_rout; static void build_load_routine(codeblock_t *block, int size) @@ -286,10 +298,16 @@ void codegen_backend_prologue(codeblock_t *block) addbyte(0x48); /*SUBL $40,%rsp*/ addbyte(0x83); addbyte(0xEC); - addbyte(0x28); + addbyte(0x38); addbyte(0x48); /*MOVL RBP, &cpu_state*/ addbyte(0xBD); addquad(((uintptr_t)&cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) + { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); + } } void codegen_backend_epilogue(codeblock_t *block) @@ -297,7 +315,7 @@ void codegen_backend_epilogue(codeblock_t *block) addbyte(0x48); /*ADDL $40,%rsp*/ addbyte(0x83); addbyte(0xC4); - addbyte(0x28); + addbyte(0x38); addbyte(0x41); /*POP R15*/ addbyte(0x5f); addbyte(0x41); /*POP R14*/ @@ -336,7 +354,7 @@ void codegen_backend_epilogue(codeblock_t *block) addbyte(0x48); /*ADDL $40,%rsp*/ addbyte(0x83); addbyte(0xC4); - addbyte(0x28); + addbyte(0x38); addbyte(0x41); /*POP R15*/ addbyte(0x5f); addbyte(0x41); /*POP R14*/ diff --git a/src/codegen_backend_x86-64.h b/src/codegen_backend_x86-64.h index 6c0cfca..50797ef 100644 --- a/src/codegen_backend_x86-64.h +++ b/src/codegen_backend_x86-64.h @@ -1,3 +1,5 @@ +#include "codegen_backend_x86-64_defs.h" + #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff #define BLOCK_START 0 diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index ee6df65..8334b74 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -32,3 +32,25 @@ #define REG_R13 13 #define REG_R14 14 #define REG_R15 15 + +#define REG_XMM0 0 +#define REG_XMM1 1 +#define REG_XMM2 2 +#define REG_XMM3 3 +#define REG_XMM4 4 +#define REG_XMM5 5 +#define REG_XMM6 6 +#define REG_XMM7 7 + +#define REG_XMM_TEMP REG_XMM7 + +#define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_FP_REGS 7 + +extern void *codegen_mem_load_byte; +extern void *codegen_mem_load_word; +extern void *codegen_mem_load_long; + +extern void *codegen_mem_store_byte; +extern void *codegen_mem_store_word; +extern void *codegen_mem_store_long; diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 45fde94..1fe0e58 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -212,6 +212,11 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } +void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) @@ -336,6 +341,11 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_JMP(codeblock_t *block, void *p) { jmp(block, (uintptr_t)p); @@ -599,6 +609,21 @@ void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) } } +void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } + else + { + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) @@ -812,6 +837,86 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } +void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) +{ + if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); + + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} + +void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); + + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ +} + void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ @@ -874,6 +979,11 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); } +void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) @@ -1153,6 +1263,11 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } +void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 85ec419..5b16a0e 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -7,6 +7,8 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); @@ -25,6 +27,8 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_JMP(codeblock_t *block, void *p); void host_x86_JNZ(codeblock_t *block, void *p); @@ -60,6 +64,8 @@ void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg); + void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); @@ -86,6 +92,13 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); +void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); + void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); @@ -101,6 +114,8 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); +void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); @@ -148,6 +163,8 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index bef4bcb..534bb91 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1,6 +1,8 @@ #ifdef __amd64__ #include "ibm.h" +#include "x86.h" +#include "386_common.h" #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" @@ -18,6 +20,7 @@ #define REG_IS_W(size) (size == IREG_SIZE_W) #define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH) +#define REG_IS_D(size) (size == IREG_SIZE_D) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -524,6 +527,95 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_ADDSD_REG_REG(block, dest_reg, src_reg_b); + } + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FDIV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_DIVSD_REG_REG(block, dest_reg, src_reg_b); + } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_MULSD_REG_REG(block, dest_reg, src_reg_b); + } + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_SUBSD_REG_REG(block, dest_reg, src_reg_b); + } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +{ + uint8_t *branch_offset; + + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_short(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); +#if WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); +#else + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); +#endif + host_x86_CALL(block, x86_int); + host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + + return 0; +} + static int codegen_JMP(codeblock_t *block, uop_t *uop) { host_x86_JMP(block, uop->p); @@ -1346,6 +1438,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB }; void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) @@ -1356,6 +1455,19 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOVQ_REG_ABS(block, host_reg, p); +} +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); +} void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { @@ -1369,6 +1481,28 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOVQ_ABS_REG(block, p, host_reg); +} +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 3, host_reg); +} void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 17f588f..d09bb21 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -5,6 +5,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" +#include "codegen_reg.h" #include "x86.h" #if defined(__linux__) || defined(__APPLE__) @@ -30,12 +31,23 @@ int codegen_host_reg_list[CODEGEN_HOST_REGS] = REG_EDX }; +int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +{ + REG_XMM0, + REG_XMM1, + REG_XMM2, + REG_XMM3, + REG_XMM4, + REG_XMM5, + REG_XMM6 +}; + static void *mem_abrt_rout; static void build_load_routine(codeblock_t *block, int size) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ESI = address Out - ECX = data, ESI = abrt*/ @@ -107,7 +119,7 @@ static void build_load_routine(codeblock_t *block, int size) static void build_store_routine(codeblock_t *block, int size) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ECX = data, ESI = address Out - ESI = abrt @@ -253,18 +265,24 @@ void codegen_backend_prologue(codeblock_t *block) addbyte(0x55); /*PUSH EBP*/ addbyte(0x56); /*PUSH ESI*/ addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $32,%esp*/ + addbyte(0x83); /*SUBL $64,%esp*/ addbyte(0xEC); - addbyte(0x20); + addbyte(0x40); addbyte(0xBD); /*MOVL EBP, &cpu_state*/ addlong(((uintptr_t)&cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) + { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); + } } void codegen_backend_epilogue(codeblock_t *block) { - addbyte(0x83); /*ADDL $32,%esp*/ + addbyte(0x83); /*ADDL $64,%esp*/ addbyte(0xC4); - addbyte(0x20); + addbyte(0x40); addbyte(0x5f); /*POP EDI*/ addbyte(0x5e); /*POP ESI*/ addbyte(0x5d); /*POP EBP*/ @@ -287,9 +305,9 @@ void codegen_backend_epilogue(codeblock_t *block) addbyte(0xe8); /*CALL x86gpf*/ addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $32,%esp*/ + addbyte(0x83); /*ADDL $64,%esp*/ addbyte(0xC4); - addbyte(0x20); + addbyte(0x40); addbyte(0x5f); /*POP EDI*/ addbyte(0x5e); /*POP ESI*/ addbyte(0x5d); /*POP EBP*/ diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index 37e4160..93d6569 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -10,7 +10,19 @@ #define REG_ESI 6 #define REG_EDI 7 +#define REG_XMM0 0 +#define REG_XMM1 1 +#define REG_XMM2 2 +#define REG_XMM3 3 +#define REG_XMM4 4 +#define REG_XMM5 5 +#define REG_XMM6 6 +#define REG_XMM7 7 + +#define REG_XMM_TEMP REG_XMM7 + #define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_FP_REGS 7 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 355b8f8..3dad4db 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -185,6 +185,11 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } +void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg) @@ -304,6 +309,11 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_JMP(codeblock_t *block, void *p) { codegen_addbyte(block, 0xe9); /*JMP*/ @@ -515,6 +525,19 @@ void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) } } +void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg) +{ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } + else + { + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ @@ -691,6 +714,68 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } +void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) +{ + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} + +void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ +} + void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ @@ -755,6 +840,11 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ } +void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) @@ -988,6 +1078,11 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } +void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 7bf81ed..d6ff697 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -8,6 +8,8 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); @@ -25,6 +27,8 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_JMP(codeblock_t *block, void *p); void host_x86_JNZ(codeblock_t *block, void *p); @@ -59,6 +63,8 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg); + void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); @@ -88,6 +94,13 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); +void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); + void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); @@ -101,6 +114,8 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); @@ -147,6 +162,8 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 235176d..b153804 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1,6 +1,8 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 #include "ibm.h" +#include "x86.h" +#include "386_common.h" #include "codegen.h" #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" @@ -28,6 +30,7 @@ #define REG_IS_W(size) (size == IREG_SIZE_W) #define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH) +#define REG_IS_D(size) (size == IREG_SIZE_D) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -535,6 +538,91 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_ADDSD_REG_REG(block, dest_reg, src_reg_b); + } + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FDIV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_DIVSD_REG_REG(block, dest_reg, src_reg_b); + } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_MULSD_REG_REG(block, dest_reg, src_reg_b); + } + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) + { + host_x86_SUBSD_REG_REG(block, dest_reg, src_reg_b); + } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +{ + uint8_t *branch_offset; + + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_short(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + + return 0; +} + static int codegen_JMP(codeblock_t *block, uop_t *uop) { host_x86_JMP(block, uop->p); @@ -1335,6 +1423,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB }; void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) @@ -1345,6 +1440,19 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOVQ_REG_ABS(block, host_reg, p); +} +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); +} void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { @@ -1358,6 +1466,28 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOVQ_ABS_REG(block, p, host_reg); +} +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 3, host_reg); +} void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index c0b23c2..e949bdf 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -78,7 +78,7 @@ /*UOP_OR_IMM - dest_reg = src_reg_a | immediate*/ #define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) /*UOP_SUB - dest_reg = src_reg_a - src_reg_b*/ -#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) /*UOP_SUB_IMM - dest_reg = src_reg_a - immediate*/ #define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) /*UOP_XOR - dest_reg = src_reg_a ^ src_reg_b*/ @@ -151,7 +151,18 @@ /*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/ #define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) -#define UOP_MAX 0x72 +/*UOP_FP_ENTER - */ +#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) +/*UOP_FADD - (floating point) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) +/*UOP_FSUB - (floating point) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) +/*UOP_FMUL - (floating point) dest_reg = src_reg_a * src_reg_b*/ +#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) +/*UOP_FDIV - (floating point) dest_reg = src_reg_a / src_reg_b*/ +#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) + +#define UOP_MAX 0x85 #define UOP_MASK 0xffff @@ -205,6 +216,15 @@ static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) uop->jump_dest_uop = ir->wr_pos; } +static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + + return ir->wr_pos-1; +} + static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) { uop_t *uop = uop_alloc(ir); @@ -433,6 +453,13 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FDIV(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FDIV, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) + +#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; } while (0) + #define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) #define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) @@ -461,11 +488,16 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p); +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx); void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg); +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg); void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 188e284..55916ee 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -4,6 +4,7 @@ #include "codegen_ops.h" #include "codegen_ops_arith.h" #include "codegen_ops_branch.h" +#include "codegen_ops_fpu_arith.h" #include "codegen_ops_jump.h" #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" @@ -105,3 +106,97 @@ RecompOpFn recomp_opcodes_0f[512] = /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; + +RecompOpFn recomp_opcodes_d8[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, +/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, +/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, +}; + +RecompOpFn recomp_opcodes_dc[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, +/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, +/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, +}; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 1534a38..fbbaed4 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -9,12 +9,12 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; -/*extern RecompOpFn recomp_opcodes_d8[512]; -extern RecompOpFn recomp_opcodes_d9[512]; +extern RecompOpFn recomp_opcodes_d8[512]; +/*extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; -extern RecompOpFn recomp_opcodes_db[512]; +extern RecompOpFn recomp_opcodes_db[512];*/ extern RecompOpFn recomp_opcodes_dc[512]; -extern RecompOpFn recomp_opcodes_dd[512]; +/*extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; extern RecompOpFn recomp_opcodes_df[512]; extern RecompOpFn recomp_opcodes_REPE[512]; diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c new file mode 100644 index 0000000..4d2237b --- /dev/null +++ b/src/codegen_ops_fpu_arith.c @@ -0,0 +1,134 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "x87.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_fpu_arith.h" + +uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + + return op_pc; +} + +uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + + return op_pc; +} +uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + + return op_pc; +} + +uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + + return op_pc; +} + +uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + + return op_pc; +} +uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + + return op_pc; +} diff --git a/src/codegen_ops_fpu_arith.h b/src/codegen_ops_fpu_arith.h new file mode 100644 index 0000000..063f614 --- /dev/null +++ b/src/codegen_ops_fpu_arith.h @@ -0,0 +1,12 @@ +uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 36b5ad8..556dbbf 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -9,10 +9,22 @@ uint8_t reg_version_refcount[IREG_COUNT][256]; ir_reg_t invalid_ir_reg = {IREG_INVALID}; -ir_reg_t host_regs[CODEGEN_HOST_REGS]; -static uint8_t host_reg_dirty[CODEGEN_HOST_REGS]; +ir_reg_t _host_regs[CODEGEN_HOST_REGS]; +static uint8_t _host_reg_dirty[CODEGEN_HOST_REGS]; -static uint8_t host_regs_locked; +ir_reg_t host_fp_regs[CODEGEN_HOST_FP_REGS]; +static uint8_t host_fp_reg_dirty[CODEGEN_HOST_FP_REGS]; + +typedef struct host_reg_set_t +{ + ir_reg_t *regs; + uint8_t *dirty; + int *reg_list; + uint16_t locked; + int nr_regs; +} host_reg_set_t; + +static host_reg_set_t host_reg_set, host_fp_reg_set; enum { @@ -20,70 +32,110 @@ enum REG_WORD, REG_DWORD, REG_QWORD, - REG_POINTER + REG_POINTER, + REG_FPU_ST_BYTE, + REG_FPU_ST_DOUBLE +}; + +enum +{ + REG_INTEGER, + REG_FP }; struct { int native_size; void *p; + int type; } ireg_data[IREG_COUNT] = { - [IREG_EAX] = {REG_DWORD, &EAX}, - [IREG_ECX] = {REG_DWORD, &ECX}, - [IREG_EDX] = {REG_DWORD, &EDX}, - [IREG_EBX] = {REG_DWORD, &EBX}, - [IREG_ESP] = {REG_DWORD, &ESP}, - [IREG_EBP] = {REG_DWORD, &EBP}, - [IREG_ESI] = {REG_DWORD, &ESI}, - [IREG_EDI] = {REG_DWORD, &EDI}, + [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER}, + [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER}, + [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER}, + [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER}, + [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER}, + [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER}, + [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER}, + [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER}, - [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op}, - [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res}, - [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1}, - [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2}, + [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER}, + [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER}, + [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER}, + [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER}, - [IREG_pc] = {REG_DWORD, &cpu_state.pc}, - [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc}, + [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER}, + [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER}, - [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr}, - [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg}, + [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER}, + [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER}, - [IREG_op32] = {REG_DWORD, &cpu_state.op32}, - [IREG_ssegs] = {REG_BYTE, &cpu_state.ssegs}, + [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER}, + [IREG_ssegs] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER}, - [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data}, + [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER}, - [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins}, - [IREG_cycles] = {REG_DWORD, &cpu_state._cycles}, + [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER}, + [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER}, - [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base}, - [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base}, - [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base}, - [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base}, - [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base}, - [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base}, + [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER}, + [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER}, + [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER}, + [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER}, + [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER}, + [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER}, - [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg}, - [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg}, - [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg}, - [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg}, - [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg}, - [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg}, + [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER}, + [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER}, + [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER}, + [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER}, + [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER}, + [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER}, + + [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER}, + + [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + + [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - [IREG_temp0] = {REG_DWORD, (void *)16}, - [IREG_temp1] = {REG_DWORD, (void *)20}, - [IREG_temp2] = {REG_DWORD, (void *)24}, - [IREG_temp3] = {REG_DWORD, (void *)28}, + [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER}, + [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER}, + [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER}, + [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER}, }; void codegen_reg_reset() { int c; - + + host_reg_set.regs = _host_regs; + host_reg_set.dirty = _host_reg_dirty; + host_reg_set.reg_list = codegen_host_reg_list; + host_reg_set.locked = 0; + host_reg_set.nr_regs = CODEGEN_HOST_REGS; + host_fp_reg_set.regs = host_fp_regs; + host_fp_reg_set.dirty = host_fp_reg_dirty; + host_fp_reg_set.reg_list = codegen_host_fp_reg_list; + host_fp_reg_set.locked = 0; + host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; + for (c = 0; c < IREG_COUNT; c++) { reg_last_version[c] = 0; @@ -91,8 +143,13 @@ void codegen_reg_reset() } for (c = 0; c < CODEGEN_HOST_REGS; c++) { - host_regs[c] = invalid_ir_reg; - host_reg_dirty[c] = 0; + host_reg_set.regs[c] = invalid_ir_reg; + host_reg_set.dirty[c] = 0; + } + for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) + { + host_fp_reg_set.regs[c] = invalid_ir_reg; + host_fp_reg_set.dirty[c] = 0; } } @@ -101,62 +158,104 @@ static inline int ir_reg_is_invalid(ir_reg_t ir_reg) return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } -static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg) +static inline host_reg_set_t *get_reg_set(ir_reg_t ir_reg) +{ + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) + return &host_reg_set; + else + return &host_fp_reg_set; +} + +static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, ir_reg_t ir_reg) { switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { case REG_WORD: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_16_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_16_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_16(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_16(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; case REG_DWORD: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_32_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_32_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_32(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; + + case REG_FPU_ST_DOUBLE: + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]); + else + codegen_direct_read_st_double(block, reg_set->reg_list[c], &cpu_state.ST[0], ir_reg.reg & 7); break; default: fatal("codegen_reg_load - native_size=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size); } - host_regs[c] = ir_reg; + reg_set->regs[c] = ir_reg; + //pclog(" codegen_reg_load: c=%i reg=%02x.%i\n", c, host_regs[c].reg,host_regs[c].version); } -static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate) +static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, int c, int invalidate) { - int ir_reg = IREG_GET_REG(host_regs[c].reg); + int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); void *p = ireg_data[ir_reg].p; switch (ireg_data[ir_reg].native_size) { case REG_BYTE: + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_BYTE %p\n", p); - codegen_direct_write_8(block, p, codegen_host_reg_list[c]); + codegen_direct_write_8(block, p, reg_set->reg_list[c]); break; case REG_WORD: + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_WORD %p\n", p); - codegen_direct_write_16(block, p, codegen_host_reg_list[c]); + codegen_direct_write_16(block, p, reg_set->reg_list[c]); break; case REG_DWORD: + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); if ((uintptr_t)p < 256) - codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]); + codegen_direct_write_32_stack(block, (int)p, reg_set->reg_list[c]); else - codegen_direct_write_32(block, p, codegen_host_reg_list[c]); + codegen_direct_write_32(block, p, reg_set->reg_list[c]); break; case REG_POINTER: + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_POINTER %p\n", p); - codegen_direct_write_ptr(block, p, codegen_host_reg_list[c]); + codegen_direct_write_ptr(block, p, reg_set->reg_list[c]); + break; + + case REG_FPU_ST_BYTE: + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); + else + codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); + break; + + case REG_FPU_ST_DOUBLE: + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); + else + codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); break; default: @@ -164,8 +263,8 @@ static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate) } if (invalidate) - host_regs[c] = invalid_ir_reg; - host_reg_dirty[c] = 0; + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) @@ -173,7 +272,8 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ int c; int dest_reference = 0; - host_regs_locked = 0; + host_reg_set.locked = 0; + host_fp_reg_set.locked = 0; /* pclog("alloc_register: dst=%i.%i src_a=%i.%i src_b=%i.%i\n", dest_reg_a.reg, dest_reg_a.version, src_reg_a.reg, src_reg_a.version, @@ -190,82 +290,88 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ } for (c = 0; c < CODEGEN_HOST_REGS; c++) { - if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_a.reg)) + host_reg_set_t *reg_set = get_reg_set(src_reg_a); + if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src_reg_a.reg)) { - if (host_regs[c].version != src_reg_a.version) + if (reg_set->regs[c].version != src_reg_a.version) fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_a.version\n"); - host_regs_locked |= (1 << c); + reg_set->locked |= (1 << c); } - if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_b.reg)) + reg_set = get_reg_set(src_reg_b); + if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src_reg_b.reg)) { - if (host_regs[c].version != src_reg_b.version) + if (reg_set->regs[c].version != src_reg_b.version) fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_b.version\n"); - host_regs_locked |= (1 << c); + reg_set->locked |= (1 << c); } - if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_c.reg)) + reg_set = get_reg_set(src_reg_c); + if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src_reg_c.reg)) { - if (host_regs[c].version != src_reg_c.version) + if (reg_set->regs[c].version != src_reg_c.version) fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_c.version\n"); - host_regs_locked |= (1 << c); + reg_set->locked |= (1 << c); } - if (!ir_reg_is_invalid(dest_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(dest_reg_a.reg)) + reg_set = get_reg_set(dest_reg_a); + if (!ir_reg_is_invalid(dest_reg_a) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dest_reg_a.reg)) { - if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] == dest_reference)) - host_regs_locked |= (1 << c); + if (reg_set->regs[c].version == dest_reg_a.version || (reg_set->regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] == dest_reference)) + reg_set->locked |= (1 << c); else - fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", host_regs[c].version, dest_reg_a.version, dest_reference); + fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, dest_reg_a.version, dest_reference); } } } ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) { + host_reg_set_t *reg_set = get_reg_set(ir_reg); int c; /*Search for required register*/ - for (c = 0; c < CODEGEN_HOST_REGS; c++) + for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg) && host_regs[c].version == ir_reg.version) + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) break; - if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version]) + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version]) fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); } - if (c == CODEGEN_HOST_REGS) + if (c == reg_set->nr_regs) { /*No unused registers. Search for an unlocked register*/ - for (c = 0; c < CODEGEN_HOST_REGS; c++) + for (c = 0; c < reg_set->nr_regs; c++) { - if (!(host_regs_locked & (1 << c))) + if (!(reg_set->locked & (1 << c))) break; } - if (c == CODEGEN_HOST_REGS) + if (c == reg_set->nr_regs) fatal("codegen_reg_alloc_read_reg - out of registers\n"); - if (host_reg_dirty[c]) - codegen_reg_writeback(block, c, 1); + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); // pclog(" load %i\n", c); - codegen_reg_load(block, c, ir_reg); - host_regs_locked |= (1 << c); + codegen_reg_load(reg_set, block, c, ir_reg); + reg_set->locked |= (1 << c); // fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); // codegen_reg_writeback(block, c); - host_reg_dirty[c] = 0; + reg_set->dirty[c] = 0; } // else // pclog(" already loaded %i\n", c); - reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version]--; - if (reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] < 0) + reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version]--; + if (reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] < 0) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); if (host_reg_idx) *host_reg_idx = c; // pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], host_regs[c].reg,host_regs[c].version, c); - return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); } ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { + host_reg_set_t *reg_set = get_reg_set(ir_reg); int c; if (IREG_GET_SIZE(ir_reg.reg) != IREG_SIZE_L) @@ -278,85 +384,107 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) codegen_reg_alloc_read_reg(block, parent_reg, &c); - if (IREG_GET_REG(host_regs[c].reg) != IREG_GET_REG(ir_reg.reg) || host_regs[c].version != ir_reg.version-1) + if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version != ir_reg.version-1) fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, - host_regs[c].reg,host_regs[c].version, + reg_set->regs[c].reg,reg_set->regs[c].version, ir_reg.reg,ir_reg.version); - host_regs[c].reg = ir_reg.reg; - host_regs[c].version = ir_reg.version; - host_reg_dirty[c] = 1; + reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].version = ir_reg.version; + reg_set->dirty[c] = 1; // pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); } /*Search for previous version in host register*/ - for (c = 0; c < CODEGEN_HOST_REGS; c++) + for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg)) + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { - if (host_regs[c].version == ir_reg.version-1) + if (reg_set->regs[c].version == ir_reg.version-1) { - if (reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] != 0) + if (reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] != 0) fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); break; } } } - if (c == CODEGEN_HOST_REGS) + if (c == reg_set->nr_regs) { /*Search for unused registers*/ - for (c = 0; c < CODEGEN_HOST_REGS; c++) + for (c = 0; c < reg_set->nr_regs; c++) { - if (ir_reg_is_invalid(host_regs[c])) + if (ir_reg_is_invalid(reg_set->regs[c])) break; } - if (c == CODEGEN_HOST_REGS) + if (c == reg_set->nr_regs) { /*No unused registers. Search for an unlocked register*/ - for (c = 0; c < CODEGEN_HOST_REGS; c++) + for (c = 0; c < reg_set->nr_regs; c++) { - if (!(host_regs_locked & (1 << c))) + if (!(reg_set->locked & (1 << c))) break; } - if (c == CODEGEN_HOST_REGS) + if (c == reg_set->nr_regs) fatal("codegen_reg_alloc_write_reg - out of registers\n"); - if (host_reg_dirty[c]) - codegen_reg_writeback(block, c, 1); + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); } } - host_regs[c].reg = ir_reg.reg; - host_regs[c].version = ir_reg.version; - host_reg_dirty[c] = 1; + reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].version = ir_reg.version; + reg_set->dirty[c] = 1; // pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); } void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { + host_reg_set_t *reg_set; int c; - - for (c = 0; c < CODEGEN_HOST_REGS; c++) + + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(host_regs[c]) && host_reg_dirty[c]) + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { - codegen_reg_writeback(block, c, 0); + codegen_reg_writeback(reg_set, block, c, 0); + } + } + + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) + { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) + { + codegen_reg_writeback(reg_set, block, c, 0); } } } void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) { + host_reg_set_t *reg_set; int c; - for (c = 0; c < CODEGEN_HOST_REGS; c++) + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(host_regs[c])) + if (!ir_reg_is_invalid(reg_set->regs[c])) { - codegen_reg_writeback(block, c, 1); + codegen_reg_writeback(reg_set, block, c, 1); + } + } + + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) + { + if (!ir_reg_is_invalid(reg_set->regs[c])) + { + codegen_reg_writeback(reg_set, block, c, 1); } } } diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 26422d8..986f0aa 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -1,9 +1,9 @@ #ifndef _CODEGEN_REG_H_ #define _CODEGEN_REG_H_ -#define IREG_REG_MASK 0x3f -#define IREG_SIZE_SHIFT 6 -#define IREG_SIZE_MASK (3 << IREG_SIZE_SHIFT) +#define IREG_REG_MASK 0xff +#define IREG_SIZE_SHIFT 8 +#define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT) #define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK) #define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK) @@ -12,6 +12,7 @@ #define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) #define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) #define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) +#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) enum { @@ -64,7 +65,33 @@ enum IREG_temp2 = 35, IREG_temp3 = 36, - IREG_COUNT, + IREG_FPU_TOP = 37, + + /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() + to access. + When CODEBLOCK_STATIC_TOP is set, the physical register number will be + used directly to index the stack. When it is clear, the difference + between the current value of TOP and the value when the block was + first compiled will be added to adjust for any changes in TOP.*/ + IREG_ST0 = 40, + IREG_ST1 = 41, + IREG_ST2 = 42, + IREG_ST3 = 43, + IREG_ST4 = 44, + IREG_ST5 = 45, + IREG_ST6 = 46, + IREG_ST7 = 47, + + IREG_tag0 = 48, + IREG_tag1 = 49, + IREG_tag2 = 50, + IREG_tag3 = 51, + IREG_tag4 = 52, + IREG_tag5 = 53, + IREG_tag6 = 54, + IREG_tag7 = 55, + + IREG_COUNT = 56, IREG_INVALID = 63, @@ -116,6 +143,11 @@ enum #define IREG_16(reg) ((reg) + IREG_AX) #define IREG_32(reg) ((reg) + IREG_EAX) +#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) +#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) + +#define IREG_TOP_diff_stack_offset 32 + static inline int ireg_seg_base(x86seg *seg) { if (seg == &cpu_state.seg_cs) @@ -139,13 +171,13 @@ extern uint8_t reg_version_refcount[IREG_COUNT][256]; typedef struct { - uint8_t reg; - uint8_t version; + uint16_t reg; + uint16_t version; } ir_reg_t; extern ir_reg_t invalid_ir_reg; -typedef uint8_t ir_host_reg_t; +typedef uint16_t ir_host_reg_t; #define REG_VERSION_MAX 250 diff --git a/src/ibm.h b/src/ibm.h index de79af6..6503b67 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -180,6 +180,12 @@ struct uint16_t old_npxc, new_npxc; x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; + + union + { + uint32_t l; + uint16_t w; + } CR0; } cpu_state; #define cycles cpu_state._cycles @@ -239,14 +245,8 @@ uint8_t *pccache2; int loadseg(uint16_t seg, x86seg *s); void loadcs(uint16_t seg); -union -{ - uint32_t l; - uint16_t w; -} CR0; - -#define cr0 CR0.l -#define msw CR0.w +#define cr0 cpu_state.CR0.l +#define msw cpu_state.CR0.w uint32_t cr2, cr3, cr4; uint32_t dr[8]; From 305b6cc4fdd130989f0c1cf00350e9f8c7c16fb0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Oct 2018 21:44:30 +0100 Subject: [PATCH 0512/1050] Added recompiled register versions of FADDP, FDIVP, FDIVRP, FMULP, FSUBP and FSUBRP. --- src/codegen.c | 2 +- src/codegen_ops.c | 47 +++++++++++++++ src/codegen_ops.h | 4 +- src/codegen_ops_fpu_arith.c | 112 +++++++++++++++++++++++++++++------- src/codegen_ops_fpu_arith.h | 10 +++- src/x87.c | 2 +- src/x87_ops.h | 12 ++-- src/x87_ops_arith.h | 24 ++++---- src/x87_ops_loadstore.h | 16 +++--- src/x87_ops_misc.h | 44 +++++++------- 10 files changed, 199 insertions(+), 74 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 409221f..2f36a42 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -416,7 +416,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xde: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = NULL;//recomp_opcodes_de; + recomp_op_table = recomp_opcodes_de; opcode_mask = 0xff; over = 1; pc_off = -1; diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 55916ee..6fe6799 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -200,3 +200,50 @@ RecompOpFn recomp_opcodes_dc[512] = /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, }; + +RecompOpFn recomp_opcodes_de[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, +/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, +/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, +}; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index fbbaed4..432652d 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -14,9 +14,9 @@ extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_da[512]; extern RecompOpFn recomp_opcodes_db[512];*/ extern RecompOpFn recomp_opcodes_dc[512]; -/*extern RecompOpFn recomp_opcodes_dd[512]; +/*extern RecompOpFn recomp_opcodes_dd[512];*/ extern RecompOpFn recomp_opcodes_de[512]; -extern RecompOpFn recomp_opcodes_df[512]; +/*extern RecompOpFn recomp_opcodes_df[512]; extern RecompOpFn recomp_opcodes_REPE[512]; extern RecompOpFn recomp_opcodes_REPNE[512];*/ diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index 4d2237b..507f937 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -5,10 +5,16 @@ #include "386_common.h" #include "x87.h" #include "codegen.h" +#include "codegen_accumulate.h" #include "codegen_ir.h" #include "codegen_ops.h" #include "codegen_ops_fpu_arith.h" +static void fpu_POP(ir_data_t *ir) +{ + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); +} + uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -29,6 +35,17 @@ uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc; } +uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(ir); + + return op_pc; +} uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -40,6 +57,16 @@ uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet return op_pc; } +uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -50,16 +77,6 @@ uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc; } -uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = fetchdat & 7; - - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - - return op_pc; -} uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -70,6 +87,28 @@ uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } +uint32_t ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(ir); + + return op_pc; +} +uint32_t ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(ir); + + return op_pc; +} uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -91,6 +130,17 @@ uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc; } +uint32_t ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(ir); + + return op_pc; +} uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -102,6 +152,16 @@ uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet return op_pc; } +uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -112,16 +172,6 @@ uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc; } -uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = fetchdat & 7; - - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - - return op_pc; -} uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = fetchdat & 7; @@ -132,3 +182,25 @@ uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } +uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(ir); + + return op_pc; +} +uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(ir); + + return op_pc; +} diff --git a/src/codegen_ops_fpu_arith.h b/src/codegen_ops_fpu_arith.h index 063f614..4e60233 100644 --- a/src/codegen_ops_fpu_arith.h +++ b/src/codegen_ops_fpu_arith.h @@ -1,12 +1,18 @@ uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); -uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); -uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/x87.c b/src/x87.c index 625e56e..44f22e0 100644 --- a/src/x87.c +++ b/src/x87.c @@ -70,7 +70,7 @@ void x87_dumpregs() } else { - pclog("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); + pclog("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP&7],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]); } pclog("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); diff --git a/src/x87_ops.h b/src/x87_ops.h index 3756c19..dd46f91 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -38,8 +38,8 @@ static inline void x87_checkexceptions() static inline void x87_push(double i) { - cpu_state.TOP=(cpu_state.TOP-1)&7; - cpu_state.ST[cpu_state.TOP] = i; + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = i; cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; } @@ -53,16 +53,16 @@ static inline void x87_push_u64(uint64_t i) td.ll = i; - cpu_state.TOP=(cpu_state.TOP-1)&7; - cpu_state.ST[cpu_state.TOP] = td.d; + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP&7] = td.d; cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; } static inline double x87_pop() { - double t = cpu_state.ST[cpu_state.TOP]; + double t = cpu_state.ST[cpu_state.TOP&7]; cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; - cpu_state.TOP=(cpu_state.TOP+1)&7; + cpu_state.TOP++; return t; } diff --git a/src/x87_ops_arith.h b/src/x87_ops_arith.h index 4561c82..d5810c6 100644 --- a/src/x87_ops_arith.h +++ b/src/x87_ops_arith.h @@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ ST(0) += use_var; \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ - cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ - cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ - cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ - cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(11); \ return 0; \ } \ @@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ - cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ - cpu_state.tag[cpu_state.TOP] = TAG_VALID; \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } @@ -121,7 +121,7 @@ static int opFADD(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FADD\n"); ST(0) = ST(0) + ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -232,7 +232,7 @@ static int opFDIV(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIV\n"); x87_div(ST(0), ST(0), ST(fetchdat & 7)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -264,7 +264,7 @@ static int opFDIVR(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDIVR\n"); x87_div(ST(0), ST(fetchdat&7), ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -296,7 +296,7 @@ static int opFMUL(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FMUL\n"); ST(0) = ST(0) * ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(16); return 0; } @@ -328,7 +328,7 @@ static int opFSUB(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUB\n"); ST(0) = ST(0) - ST(fetchdat & 7); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -360,7 +360,7 @@ static int opFSUBR(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSUBR\n"); ST(0) = ST(fetchdat & 7) - ST(0); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } diff --git a/src/x87_ops_loadstore.h b/src/x87_ops_loadstore.h index 7a0b938..96c18e6 100644 --- a/src/x87_ops_loadstore.h +++ b/src/x87_ops_loadstore.h @@ -95,8 +95,8 @@ static int opFILDiq_a16(uint32_t fetchdat) temp64 = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] = TAG_VALID | TAG_UINT64; + cpu_state.MM[cpu_state.TOP&7].q = temp64; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; CLOCK_CYCLES(10); return 0; @@ -111,8 +111,8 @@ static int opFILDiq_a32(uint32_t fetchdat) temp64 = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4)); x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP].q = temp64; - cpu_state.tag[cpu_state.TOP] = TAG_VALID | TAG_UINT64; + cpu_state.MM[cpu_state.TOP&7].q = temp64; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; CLOCK_CYCLES(10); return 0; @@ -180,8 +180,8 @@ static int FISTPiq_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); - if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; @@ -196,8 +196,8 @@ static int FISTPiq_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); - if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP].q; + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 34a28d0..5ca534c 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -335,8 +335,8 @@ static int opFLD(uint32_t fetchdat) old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; x87_push(ST(fetchdat&7)); - cpu_state.tag[cpu_state.TOP] = old_tag; - cpu_state.MM[cpu_state.TOP].q = old_i64; + cpu_state.tag[cpu_state.TOP&7] = old_tag; + cpu_state.MM[cpu_state.TOP&7].q = old_i64; CLOCK_CYCLES(4); return 0; } @@ -352,11 +352,11 @@ static int opFXCH(uint32_t fetchdat) td = ST(0); ST(0) = ST(fetchdat&7); ST(fetchdat&7) = td; - old_tag = cpu_state.tag[cpu_state.TOP]; - cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_tag = cpu_state.tag[cpu_state.TOP&7]; + cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[cpu_state.TOP].q; - cpu_state.MM[cpu_state.TOP].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + old_i64 = cpu_state.MM[cpu_state.TOP&7].q; + cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; CLOCK_CYCLES(4); @@ -369,7 +369,7 @@ static int opFCHS(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FCHS\n"); ST(0) = -ST(0); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(6); return 0; } @@ -380,7 +380,7 @@ static int opFABS(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FABS %f\n", ST(0)); ST(0) = fabs(ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(3); return 0; } @@ -488,7 +488,7 @@ static int opF2XM1(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("F2XM1\n"); ST(0) = pow(2.0, ST(0)) - 1.0; - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(200); return 0; } @@ -523,7 +523,7 @@ static int opFPTAN(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FPTAN\n"); ST(0) = tan(ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; CLOCK_CYCLES(235); @@ -547,7 +547,7 @@ static int opFDECSTP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; if (fplog) pclog("FDECSTP\n"); - cpu_state.TOP = (cpu_state.TOP - 1) & 7; + cpu_state.TOP--; CLOCK_CYCLES(4); return 0; } @@ -557,7 +557,7 @@ static int opFINCSTP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; if (fplog) pclog("FDECSTP\n"); - cpu_state.TOP = (cpu_state.TOP + 1) & 7; + cpu_state.TOP++; CLOCK_CYCLES(4); return 0; } @@ -570,7 +570,7 @@ static int opFPREM(uint32_t fetchdat) if (fplog) pclog("FPREM %f %f ", ST(0), ST(1)); temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; if (fplog) pclog("%f\n", ST(0)); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; @@ -587,7 +587,7 @@ static int opFPREM1(uint32_t fetchdat) if (fplog) pclog("FPREM1 %f %f ", ST(0), ST(1)); temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; if (fplog) pclog("%f\n", ST(0)); cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; @@ -603,7 +603,7 @@ static int opFSQRT(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSQRT\n"); ST(0) = sqrt(ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(83); return 0; } @@ -616,7 +616,7 @@ static int opFSINCOS(uint32_t fetchdat) if (fplog) pclog("FSINCOS\n"); td = ST(0); ST(0) = sin(td); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; CLOCK_CYCLES(330); @@ -629,7 +629,7 @@ static int opFRNDINT(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FRNDINT %g ", ST(0)); ST(0) = (double)x87_fround(ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; if (fplog) pclog("%g\n", ST(0)); CLOCK_CYCLES(21); return 0; @@ -643,7 +643,7 @@ static int opFSCALE(uint32_t fetchdat) if (fplog) pclog("FSCALE\n"); temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(30); return 0; } @@ -654,7 +654,7 @@ static int opFSIN(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSIN\n"); ST(0) = sin(ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -666,7 +666,7 @@ static int opFCOS(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FCOS\n"); ST(0) = cos(ST(0)); - cpu_state.tag[cpu_state.TOP] = TAG_VALID; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -836,8 +836,8 @@ static int opFSTCW_a32(uint32_t fetchdat) if (fplog) pclog("FCMOV %f\n", ST(fetchdat & 7)); \ if (cond_ ## condition) \ { \ - cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ ST(0) = ST(fetchdat & 7); \ } \ CLOCK_CYCLES(4); \ From d9e38fe37c007bba29490fc3806eb3b710de4f56 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 9 Oct 2018 13:51:05 +0100 Subject: [PATCH 0513/1050] Fix masking of FPU top-of-stack in several places. Fixes DOS Quake. --- src/386_dynarec.c | 2 +- src/codegen_backend.c | 2 +- src/x87_ops_misc.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 3f905bd..91a2b55 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -663,7 +663,7 @@ void exec386_dynarec(int cycs) valid_block = 0; } } - if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) { /*FPU top-of-stack does not match the value this block was compiled with, re-compile using dynamic top-of-stack*/ diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 58c092e..7d96ec3 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -303,7 +303,7 @@ void codegen_block_start_recompile(codeblock_t *block) cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - block->TOP = cpu_state.TOP; + block->TOP = cpu_state.TOP & 7; block->was_recompiled = 1; codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 5ca534c..eb9fffb 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -144,7 +144,7 @@ static int FSAVE() { 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); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { @@ -308,7 +308,7 @@ static int opFSTSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -318,7 +318,7 @@ static int opFSTSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11)); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } From 829c74f2d548afda844fc7de07cc387ce80622a6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 9 Oct 2018 14:07:49 +0100 Subject: [PATCH 0514/1050] Don't write back unchanged registers on flush + invalidate. --- src/codegen_reg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 556dbbf..fc97b20 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -473,18 +473,22 @@ void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) reg_set = &host_reg_set; for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c])) + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { codegen_reg_writeback(reg_set, block, c, 1); } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } reg_set = &host_fp_reg_set; for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c])) + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { codegen_reg_writeback(reg_set, block, c, 1); } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } } From e17a94a409970a457ec4448ccbc2347cda014f4d Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 9 Oct 2018 22:10:29 +0100 Subject: [PATCH 0515/1050] FDIVP/FDIVRP should pop the stack when a divide by zero occurs and the exception is masked. Fixes software rendering on Need for Speed III. --- src/x87_ops.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/x87_ops.h b/src/x87_ops.h index dd46f91..b1cc843 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -18,15 +18,15 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ { \ if (((double)src2) == 0.0) \ { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ dst = src1 / (double)src2; \ else \ { \ pclog("FPU : divide by zero\n"); \ picint(1 << 13); \ + return 1; \ } \ - return 1; \ } \ else \ dst = src1 / (double)src2; \ From 8a516df476a6f66599b69bf21e2171dcec00201c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Oct 2018 19:47:04 +0100 Subject: [PATCH 0516/1050] Added recompiled versions of FLD, FILD, FST and FSTP. --- src/codegen.c | 8 +- src/codegen_backend_arm.c | 72 +++++++++--- src/codegen_backend_arm64.c | 60 +++++++--- src/codegen_backend_arm64_defs.h | 8 +- src/codegen_backend_arm64_ops.c | 87 ++++++++++++-- src/codegen_backend_arm64_ops.h | 15 +++ src/codegen_backend_arm64_uops.c | 94 +++++++++++++++ src/codegen_backend_arm_defs.h | 6 + src/codegen_backend_arm_ops.c | 92 +++++++++++++-- src/codegen_backend_arm_ops.h | 11 ++ src/codegen_backend_arm_uops.c | 98 ++++++++++++++++ src/codegen_backend_x86-64.c | 74 +++++++++--- src/codegen_backend_x86-64_defs.h | 4 + src/codegen_backend_x86-64_ops.c | 62 ++++++++++ src/codegen_backend_x86-64_ops.h | 16 +++ src/codegen_backend_x86-64_uops.c | 99 +++++++++++++++- src/codegen_backend_x86.c | 83 +++++++++---- src/codegen_backend_x86_defs.h | 9 +- src/codegen_backend_x86_ops.c | 92 +++++++++++++-- src/codegen_backend_x86_ops.h | 35 ++++-- src/codegen_backend_x86_uops.c | 141 ++++++++++++++++++---- src/codegen_ir_defs.h | 25 +++- src/codegen_ops.c | 189 ++++++++++++++++++++++++++++++ src/codegen_ops.h | 12 +- src/codegen_ops_fpu_arith.c | 6 +- src/codegen_ops_fpu_loadstore.c | 134 +++++++++++++++++++++ src/codegen_ops_fpu_loadstore.h | 10 ++ src/codegen_ops_helpers.h | 9 ++ 28 files changed, 1400 insertions(+), 151 deletions(-) create mode 100644 src/codegen_ops_fpu_loadstore.c create mode 100644 src/codegen_ops_fpu_loadstore.h diff --git a/src/codegen.c b/src/codegen.c index 2f36a42..88cb01f 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -370,7 +370,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xd9: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = NULL;//recomp_opcodes_d9; + recomp_op_table = recomp_opcodes_d9; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -388,7 +388,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdb: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = NULL;//recomp_opcodes_db; + recomp_op_table = recomp_opcodes_db; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -407,7 +407,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdd: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = NULL;//recomp_opcodes_dd; + recomp_op_table = recomp_opcodes_dd; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -425,7 +425,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdf: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = NULL;//recomp_opcodes_df; + recomp_op_table = recomp_opcodes_df; opcode_mask = 0xff; over = 1; pc_off = -1; diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 3b9c5fe..67711e6 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -20,10 +20,14 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_single; +void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_single; +void *codegen_mem_store_double; int codegen_host_reg_list[CODEGEN_HOST_REGS] = { @@ -48,7 +52,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = REG_D15 }; -static void build_load_routine(codeblock_t *block, int size) +static void build_load_routine(codeblock_t *block, int size, int is_float) { uint32_t *branch_offset; uint32_t *misaligned_offset; @@ -78,12 +82,22 @@ static void build_load_routine(codeblock_t *block, int size) } host_arm_CMP_IMM(block, REG_R1, -1); branch_offset = host_arm_BEQ_(block); - if (size == 1) + if (size == 1 && !is_float) host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 2) + else if (size == 2 && !is_float) host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4) + else if (size == 4 && !is_float) host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && is_float) + { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); + } + else if (size == 8 && is_float) + { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); + } host_arm_MOV_IMM(block, REG_R1, 0); host_arm_MOV_REG(block, REG_PC, REG_LR); @@ -97,15 +111,21 @@ static void build_load_routine(codeblock_t *block, int size) host_arm_BL(block, (uintptr_t)readmemwl); else if (size == 4) host_arm_BL(block, (uintptr_t)readmemll); + else if (size == 8) + host_arm_BL(block, (uintptr_t)readmemql); else fatal("build_load_routine - unknown size %i\n", size); + if (size == 4 && is_float) + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); + else if (size == 8 && is_float) + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); block_pos = (block_pos + 63) & ~63; } -static void build_store_routine(codeblock_t *block, int size) +static void build_store_routine(codeblock_t *block, int size, int is_float) { uint32_t *branch_offset; uint32_t *misaligned_offset; @@ -135,12 +155,22 @@ static void build_store_routine(codeblock_t *block, int size) } host_arm_CMP_IMM(block, REG_R2, -1); branch_offset = host_arm_BEQ_(block); - if (size == 1) + if (size == 1 && !is_float) host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 2) + else if (size == 2 && !is_float) host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4) + else if (size == 4 && !is_float) host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && is_float) + { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); + } + else if (size == 8 && is_float) + { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); + } host_arm_MOV_IMM(block, REG_R1, 0); host_arm_MOV_REG(block, REG_PC, REG_LR); @@ -148,12 +178,18 @@ static void build_store_routine(codeblock_t *block, int size) if (size != 1) *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 4 && is_float) + host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); + else if (size == 8 && is_float) + host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); if (size == 1) host_arm_BL(block, (uintptr_t)writememb386l); else if (size == 2) host_arm_BL(block, (uintptr_t)writememwl); else if (size == 4) host_arm_BL(block, (uintptr_t)writememll); + else if (size == 8) + host_arm_BL_r1(block, (uintptr_t)writememql); else fatal("build_store_routine - unknown size %i\n", size); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); @@ -165,18 +201,26 @@ static void build_store_routine(codeblock_t *block, int size) static void build_loadstore_routines(codeblock_t *block) { codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1); + build_load_routine(block, 1, 0); codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2); + build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4); + build_load_routine(block, 4, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1); + build_store_routine(block, 1, 0); codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2); + build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4); + build_store_routine(block, 4, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } void codegen_backend_init() diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 57eb10b..638c65a 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -20,10 +20,14 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_single; +void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_single; +void *codegen_mem_store_double; int codegen_host_reg_list[CODEGEN_HOST_REGS] = { @@ -51,7 +55,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = REG_V15 }; -static void build_load_routine(codeblock_t *block, int size) +static void build_load_routine(codeblock_t *block, int size, int is_float) { uint32_t *branch_offset; uint8_t *misaligned_offset; @@ -84,12 +88,16 @@ static void build_load_routine(codeblock_t *block, int size) } host_arm64_CMPX_IMM(block, REG_X1, -1); branch_offset = host_arm64_BEQ_(block); - if (size == 1) + if (size == 1 && !is_float) host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 2) + else if (size == 2 && !is_float) host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4) + else if (size == 4 && !is_float) host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && is_float) + host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); + else if (size == 8 && is_float) + host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); host_arm64_MOVZ_IMM(block, REG_W1, 0); host_arm64_RET(block, REG_X30); @@ -103,16 +111,22 @@ static void build_load_routine(codeblock_t *block, int size) host_arm64_call(block, (uintptr_t)readmemwl); else if (size == 4) host_arm64_call(block, (uintptr_t)readmemll); + else if (size == 8) + host_arm64_call(block, (uintptr_t)readmemql); else fatal("build_load_routine - unknown size %i\n", size); codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + if (size == 4 && is_float) + host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); + else if (size == 8 && is_float) + host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); host_arm64_RET(block, REG_X30); block_pos = (block_pos + 63) & ~63; } -static void build_store_routine(codeblock_t *block, int size) +static void build_store_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; uint8_t *misaligned_offset; @@ -145,12 +159,16 @@ static void build_store_routine(codeblock_t *block, int size) } host_arm64_CMPX_IMM(block, REG_X2, -1); branch_offset = host_arm64_BEQ_(block); - if (size == 1) + if (size == 1 && !is_float) host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 2) + else if (size == 2 && !is_float) host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4) + else if (size == 4 && !is_float) host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && is_float) + host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); + else if (size == 8 && is_float) + host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); host_arm64_MOVZ_IMM(block, REG_X1, 0); host_arm64_RET(block, REG_X30); @@ -158,12 +176,18 @@ static void build_store_routine(codeblock_t *block, int size) if (size != 1) host_arm64_branch_set_offset(misaligned_offset, &block->data[block_pos]); host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); + if (size == 4 && is_float) + host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); + else if (size == 8 && is_float) + host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); if (size == 1) host_arm64_call(block, (uintptr_t)writememb386l); else if (size == 2) host_arm64_call(block, (uintptr_t)writememwl); else if (size == 4) host_arm64_call(block, (uintptr_t)writememll); + else if (size == 8) + host_arm64_call(block, (uintptr_t)writememql); else fatal("build_store_routine - unknown size %i\n", size); codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); @@ -176,18 +200,26 @@ static void build_store_routine(codeblock_t *block, int size) static void build_loadstore_routines(codeblock_t *block) { codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1); + build_load_routine(block, 1, 0); codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2); + build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4); + build_load_routine(block, 4, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1); + build_store_routine(block, 1, 0); codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2); + build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4); + build_store_routine(block, 4, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } void codegen_backend_init() diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index 207fd80..f992759 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -109,13 +109,19 @@ #define REG_TEMP REG_X7 #define REG_TEMP2 REG_X6 +#define REG_V_TEMP REG_V0 + #define CODEGEN_HOST_REGS 10 #define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_single; +extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; -extern void *codegen_mem_store_long; \ No newline at end of file +extern void *codegen_mem_store_long; +extern void *codegen_mem_store_single; +extern void *codegen_mem_store_double; \ No newline at end of file diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index a7a3cd6..1c6da2f 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -103,21 +103,33 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BLR (0xd63f0000) #define OPCODE_BR (0xd61f0000) #define OPCODE_FADD_D (0x1e602800) +#define OPCODE_FCVT_D_S (0x1e22c000) +#define OPCODE_FCVT_S_D (0x1e624000) #define OPCODE_FDIV_D (0x1e601800) +#define OPCODE_FMOV_D_D (0x1e604000) +#define OPCODE_FMOV_D_Q (0x9e670000) +#define OPCODE_FMOV_Q_D (0x9e660000) +#define OPCODE_FMOV_S_W (0x1e270000) +#define OPCODE_FMOV_W_S (0x1e260000) #define OPCODE_FMUL_D (0x1e600800) #define OPCODE_FSUB_D (0x1e603800) #define OPCODE_LDR_REG (0xb8606800) #define OPCODE_LDRB_REG (0x38606800) #define OPCODE_LDRH_REG (0x78606800) #define OPCODE_LDRX_REG_LSL3 (0xf8607800) +#define OPCODE_LDR_REG_F32 (0xbc606800) +#define OPCODE_LDR_REG_F64 (0xfc606800) #define OPCODE_LDR_REG_F64_S (0xfc607800) #define OPCODE_LSL (0x1ac02000) #define OPCODE_LSR (0x1ac02400) #define OPCODE_NOP (0xd503201f) #define OPCODE_RET (0xd65f0000) +#define OPCODE_SCVTF_D_W (0x1e620000) #define OPCODE_STR_REG (0xb8206800) #define OPCODE_STRB_REG (0x38206800) #define OPCODE_STRH_REG (0x78206800) +#define OPCODE_STR_REG_F32 (0xbc206800) +#define OPCODE_STR_REG_F64 (0xfc206800) #define OPCODE_STR_REG_F64_S (0xfc207800) #define DATPROC_SHIFT(sh) (sh << 10) @@ -490,11 +502,37 @@ void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, in codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); @@ -510,21 +548,25 @@ void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) { - if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) @@ -564,10 +606,18 @@ void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offs codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } +void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) { codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } +void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); @@ -704,6 +754,11 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); } +void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) @@ -728,10 +783,18 @@ void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offse codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } +void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) { codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); } +void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index da83275..fb83b83 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -56,6 +56,15 @@ void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg); + +void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -63,7 +72,9 @@ void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offs void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset); void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); +void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -95,13 +106,17 @@ void host_arm64_RET(codeblock_t *block, int reg); void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); +void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg); +void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg); void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset); +void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg); void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg); void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index cb8e7cc..ad15f07 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -838,6 +838,40 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + + return 0; +} +static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); + + return 0; +} static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { @@ -940,6 +974,41 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1077,6 +1146,26 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) + { + host_arm64_SCVTF_D_W(block, dest_reg, src_reg); + } + else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) + { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); + } + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1591,18 +1680,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 0a246fa..6473fd5 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -41,6 +41,8 @@ #define REG_D14 14 #define REG_D15 15 +#define REG_D_TEMP REG_D0 + #define REG_MASK_R0 (1 << REG_R0) #define REG_MASK_R1 (1 << REG_R1) #define REG_MASK_R2 (1 << REG_R2) @@ -67,7 +69,11 @@ extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_single; +extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_single; +extern void *codegen_mem_store_double; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 2146efe..06841ea 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -17,10 +17,16 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) } } -#define Rm(x) (x) -#define Rs(x) ((x) << 8) -#define Rd(x) ((x) << 12) -#define Rn(x) ((x) << 16) +#define Rm(x) (x) +#define Rs(x) ((x) << 8) +#define Rd(x) ((x) << 12) +#define Rt(x) ((x) << 12) +#define Rn(x) ((x) << 16) +#define Rt2(x) ((x) << 16) + +#define Vm(x) (x) +#define Vd(x) ((x) << 12) +#define Vn(x) ((x) << 16) #define DATA_OFFSET_UP (1 << 23) #define DATA_OFFSET_DOWN (0 << 23) @@ -98,10 +104,20 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VADD 0xee300b00 +#define OPCODE_VCVT_D_IS 0xeeb80bc0 +#define OPCODE_VCVT_D_S 0xeeb70ac0 +#define OPCODE_VCVT_S_D 0xeeb70bc0 #define OPCODE_VDIV 0xee800b00 -#define OPCODE_VLDR 0xed900b00 +#define OPCODE_VLDR_D 0xed900b00 +#define OPCODE_VLDR_S 0xed900a00 +#define OPCODE_VMOV_32_S 0xee100a10 +#define OPCODE_VMOV_64_D 0xec500b10 +#define OPCODE_VMOV_D_64 0xec400b10 +#define OPCODE_VMOV_S_32 0xee000a10 +#define OPCODE_VMOV_D_D 0xeeb00b40 #define OPCODE_VMUL 0xee200b00 -#define OPCODE_VSTR 0xed800b00 +#define OPCODE_VSTR_D 0xed800b00 +#define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 #define B_OFFSET(x) (((x) >> 2) & 0xffffff) @@ -305,6 +321,18 @@ void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) else codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } +void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) +{ + uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + { + host_arm_MOV_IMM(block, REG_R1, dest_addr); + host_arm_BLX(block, REG_R1); + } + else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); +} void host_arm_BLX(codeblock_t *block, int addr_reg) { codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); @@ -734,6 +762,18 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); +} +void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); +} +void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -741,8 +781,34 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) - fatal("VLDR bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); + fatal("VLDR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); +} +void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); +} +void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) +{ + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); +} +void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); +} +void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); } void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { @@ -751,8 +817,14 @@ void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) - fatal("VSTR bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); + fatal("VSTR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) +{ + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); } void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index a446bf1..6e2218e 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -16,6 +16,7 @@ void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_BL(codeblock_t *block, uintptr_t dest_addr); +void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr); void host_arm_BLX(codeblock_t *block, int addr_reg); uint32_t *host_arm_BCC_(codeblock_t *block); @@ -115,8 +116,18 @@ void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg); +void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high); +void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); +void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index d09f0e3..7574234 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -910,6 +910,42 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_load_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); + + return 0; +} +static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_load_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + + return 0; +} static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { @@ -1012,6 +1048,42 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} static int codegen_MOV(codeblock_t *block, uop_t *uop) { @@ -1156,6 +1228,27 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) + { + host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } + else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) + { + host_arm_SXTH(block, REG_TEMP, src_reg, 0); + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -1671,18 +1764,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 4fb6fe0..dc43a39 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -19,10 +19,14 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_single; +void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_single; +void *codegen_mem_store_double; int codegen_host_reg_list[CODEGEN_HOST_REGS] = { @@ -44,7 +48,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = static void *mem_abrt_rout; -static void build_load_routine(codeblock_t *block, int size) +static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; uint8_t *misaligned_offset; @@ -80,12 +84,16 @@ static void build_load_routine(codeblock_t *block, int size) } host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); branch_offset = host_x86_JZ_short(block); - if (size == 1) + if (size == 1 && !is_float) host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 2) + else if (size == 2 && !is_float) host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4) + else if (size == 4 && !is_float) host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else if (size == 8 && is_float) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); else fatal("build_load_routine: size=%i\n", size); host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); @@ -102,21 +110,32 @@ static void build_load_routine(codeblock_t *block, int size) #else host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); #endif - if (size == 1) + if (size == 1 && !is_float) { host_x86_CALL(block, (void *)readmemb386l); host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); } - else if (size == 2) + else if (size == 2 && !is_float) { host_x86_CALL(block, (void *)readmemwl); host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); } - else if (size == 4) + else if (size == 4 && !is_float) { host_x86_CALL(block, (void *)readmemll); host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); } + else if (size == 4 && is_float) + { + host_x86_CALL(block, (void *)readmemll); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } + else if (size == 8 && is_float) + { + host_x86_CALL(block, (void *)readmemql); + host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); + } #if WIN64 host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); #endif @@ -127,7 +146,7 @@ static void build_load_routine(codeblock_t *block, int size) block_pos = (block_pos + 63) & ~63; } -static void build_store_routine(codeblock_t *block, int size) +static void build_store_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; uint8_t *misaligned_offset; @@ -164,12 +183,16 @@ static void build_store_routine(codeblock_t *block, int size) } host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); branch_offset = host_x86_JZ_short(block); - if (size == 1) + if (size == 1 && !is_float) host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 2) + else if (size == 2 && !is_float) host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4) + else if (size == 4 && !is_float) host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else if (size == 8 && is_float) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); else fatal("build_store_routine: size=%i\n", size); host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); @@ -182,7 +205,12 @@ static void build_store_routine(codeblock_t *block, int size) host_x86_PUSH(block, REG_RDX); #if WIN64 host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); - host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data + else if (size == 8 && is_float) + host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); //data + else + host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address #else //host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address @@ -194,6 +222,8 @@ static void build_store_routine(codeblock_t *block, int size) host_x86_CALL(block, (void *)writememwl); else if (size == 4) host_x86_CALL(block, (void *)writememll); + else if (size == 8) + host_x86_CALL(block, (void *)writememql); #if WIN64 host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); #endif @@ -207,18 +237,26 @@ static void build_store_routine(codeblock_t *block, int size) static void build_loadstore_routines(codeblock_t *block) { codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1); + build_load_routine(block, 1, 0); codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2); + build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4); + build_load_routine(block, 4, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1); + build_store_routine(block, 1, 0); codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2); + build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4); + build_store_routine(block, 4, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } void codegen_backend_init() diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index 8334b74..01c0c26 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -50,7 +50,11 @@ extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_single; +extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_single; +extern void *codegen_mem_store_double; diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 1fe0e58..21dd087 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -341,6 +341,26 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); @@ -837,6 +857,25 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -875,6 +914,12 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int } } +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -912,11 +957,28 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 codegen_addlong(block, addr); } } + +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } +void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 5b16a0e..08b6892 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -27,6 +27,11 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_JMP(codeblock_t *block, void *p); @@ -92,6 +97,14 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p); @@ -99,6 +112,9 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg); void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 534bb91..15d904a 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -771,7 +771,6 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) if (REG_IS_B(dest_size)) { host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); -// fatal("Here\n"); } else if (REG_IS_W(dest_size)) { @@ -784,6 +783,42 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} +static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { @@ -882,6 +917,43 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -974,6 +1046,26 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) + { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1386,18 +1478,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, [UOP_MOV & UOP_MASK] = codegen_MOV, [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index d09bb21..ab6a3be 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -19,10 +19,14 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_single; +void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_single; +void *codegen_mem_store_double; int codegen_host_reg_list[CODEGEN_HOST_REGS] = { @@ -38,13 +42,12 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = REG_XMM2, REG_XMM3, REG_XMM4, - REG_XMM5, - REG_XMM6 + REG_XMM5 }; static void *mem_abrt_rout; -static void build_load_routine(codeblock_t *block, int size) +static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; uint8_t *misaligned_offset = NULL; @@ -79,12 +82,16 @@ static void build_load_routine(codeblock_t *block, int size) } host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); branch_offset = host_x86_JZ_short(block); - if (size == 1) + if (size == 1 && !is_float) host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 2) + else if (size == 2 && !is_float) host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4) + else if (size == 4 && !is_float) host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else if (size == 8 && is_float) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); else fatal("build_load_routine: size=%i\n", size); host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); @@ -102,13 +109,26 @@ static void build_load_routine(codeblock_t *block, int size) host_x86_CALL(block, (void *)readmemwl); else if (size == 4) host_x86_CALL(block, (void *)readmemll); + else if (size == 8) + host_x86_CALL(block, (void *)readmemql); host_x86_POP(block, REG_ECX); - if (size == 1) + if (size == 1 && !is_float) host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - else if (size == 2) + else if (size == 2 && !is_float) host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - else if (size == 4) + else if (size == 4 && !is_float) host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + else if (size == 4 && is_float) + { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } + else if (size == 8 && is_float) + { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); + host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); + } host_x86_POP(block, REG_EDX); host_x86_POP(block, REG_EAX); host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); @@ -116,7 +136,7 @@ static void build_load_routine(codeblock_t *block, int size) block_pos = (block_pos + 63) & ~63; } -static void build_store_routine(codeblock_t *block, int size) +static void build_store_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; uint8_t *misaligned_offset = NULL; @@ -152,23 +172,34 @@ static void build_store_routine(codeblock_t *block, int size) } host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); branch_offset = host_x86_JZ_short(block); - if (size == 1) + if (size == 1 && !is_float) host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 2) + else if (size == 2 && !is_float) host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4) + else if (size == 4 && !is_float) host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else if (size == 8 && is_float) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); else - fatal("build_store_routine: size=%i\n", size); + fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); host_x86_RET(block); *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; if (size != 1) *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); host_x86_PUSH(block, REG_EAX); host_x86_PUSH(block, REG_EDX); host_x86_PUSH(block, REG_ECX); + if (size == 8 && is_float) + { + host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); + host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 8); + } host_x86_PUSH(block, REG_EDI); if (size == 1) host_x86_CALL(block, (void *)writememb386l); @@ -176,7 +207,11 @@ static void build_store_routine(codeblock_t *block, int size) host_x86_CALL(block, (void *)writememwl); else if (size == 4) host_x86_CALL(block, (void *)writememll); + else if (size == 8) + host_x86_CALL(block, (void *)writememql); host_x86_POP(block, REG_EDI); + if (size == 8 && is_float) + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 8); host_x86_POP(block, REG_ECX); host_x86_POP(block, REG_EDX); host_x86_POP(block, REG_EAX); @@ -188,18 +223,26 @@ static void build_store_routine(codeblock_t *block, int size) static void build_loadstore_routines(codeblock_t *block) { codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1); + build_load_routine(block, 1, 0); codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2); + build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4); + build_load_routine(block, 4, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1); + build_store_routine(block, 1, 0); codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2); + build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4); + build_store_routine(block, 4, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } void codegen_backend_init() diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index 93d6569..5a5ea69 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -19,17 +19,22 @@ #define REG_XMM6 6 #define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM7 +#define REG_XMM_TEMP REG_XMM7 +#define REG_XMM_TEMP2 REG_XMM6 #define CODEGEN_HOST_REGS 3 -#define CODEGEN_HOST_FP_REGS 7 +#define CODEGEN_HOST_FP_REGS 6 extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_single; +extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_single; +extern void *codegen_mem_store_double; #endif diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 3dad4db..ae601b7 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -185,7 +185,7 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } -void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } @@ -309,7 +309,27 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } -void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } @@ -714,7 +734,26 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } -void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -729,7 +768,7 @@ void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) codegen_addlong(block, (uint32_t)p); } } -void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ if (addr < 0x80 || addr >= 0xffffff80) @@ -742,8 +781,33 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int codegen_addlong(block, addr); } } +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) +{ + if (!offset) + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ + codegen_addbyte(block, 0x24); + } + else if (offset >= -80 || offset < 0x80) + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte2(block, 0x24, offset & 0xff); + } + else + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, offset); + } -void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) +} + +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -758,7 +822,7 @@ void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addlong(block, (uint32_t)p); } } -void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) { codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ if (addr < 0x80 || addr >= 0xffffff80) @@ -771,7 +835,12 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 codegen_addlong(block, addr); } } -void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } @@ -840,7 +909,7 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ } -void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1078,7 +1147,7 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } -void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1109,6 +1178,11 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a) diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index d6ff697..19ef66a 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -8,7 +8,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); @@ -27,7 +27,14 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); -void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg); + +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dest_reg, int src_reg); +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_JMP(codeblock_t *block, void *p); @@ -94,12 +101,20 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); -void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); -void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg); + +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); @@ -114,7 +129,7 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); @@ -162,7 +177,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); @@ -170,6 +185,8 @@ void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_data); +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index b153804..04803d7 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -545,7 +545,7 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_ADDSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); } else fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -559,13 +559,13 @@ static int codegen_FDIV(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_DIVSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } else fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -579,7 +579,7 @@ static int codegen_FMUL(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_MULSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); } else fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -593,13 +593,13 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_SUBSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } else fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -773,6 +773,43 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} + +static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { @@ -871,6 +908,43 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} +static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + + return 0; +} + static int codegen_MOV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -963,6 +1037,26 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) + { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) + { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1369,20 +1463,25 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV & UOP_MASK] = codegen_MOV, + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, @@ -1442,7 +1541,7 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) } void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_REG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { @@ -1451,7 +1550,7 @@ void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); - host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) @@ -1477,7 +1576,7 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int } void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_REG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { @@ -1486,7 +1585,7 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index e949bdf..c935d0c 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -62,6 +62,8 @@ #define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) /*UOP_MOVSX - dest_reg = sign_extend(src_reg_a)*/ #define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) +/*UOP_MOV_DOUBLE_INT - dest_reg = (double)src_reg_a*/ +#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ @@ -99,8 +101,16 @@ #define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/ #define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_LOAD_SINGLE - dest_reg = (float)src_reg_a:[src_reg_b]*/ +#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_IMM_JZ - if (src_reg_a == imm_data) then jump to ptr*/ #define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_LOAD_DOUBLE - dest_reg = (double)src_reg_a:[src_reg_b]*/ +#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_SINGLE - src_reg_a:[src_reg_b] = src_reg_c*/ +#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) +/*UOP_MEM_STORE_DOUBLE - src_reg_a:[src_reg_b] = src_reg_c*/ +#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ #define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) @@ -467,18 +477,23 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) #define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) #define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) +#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) #define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) #define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) #define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset) #define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) #define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) #define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) -#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) -#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) -#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) -#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) +#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) +#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) +#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) +#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) +#define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 6fe6799..547b627 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -5,6 +5,7 @@ #include "codegen_ops_arith.h" #include "codegen_ops_branch.h" #include "codegen_ops_fpu_arith.h" +#include "codegen_ops_fpu_loadstore.h" #include "codegen_ops_jump.h" #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" @@ -154,6 +155,100 @@ RecompOpFn recomp_opcodes_d8[512] = /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, }; +RecompOpFn recomp_opcodes_d9[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +RecompOpFn recomp_opcodes_db[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + RecompOpFn recomp_opcodes_dc[512] = { /*16-bit data*/ @@ -201,6 +296,53 @@ RecompOpFn recomp_opcodes_dc[512] = /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, }; +RecompOpFn recomp_opcodes_dd[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + RecompOpFn recomp_opcodes_de[512] = { /*16-bit data*/ @@ -247,3 +389,50 @@ RecompOpFn recomp_opcodes_de[512] = /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, }; + +RecompOpFn recomp_opcodes_df[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 432652d..7231e0e 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -10,14 +10,14 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; extern RecompOpFn recomp_opcodes_d8[512]; -/*extern RecompOpFn recomp_opcodes_d9[512]; -extern RecompOpFn recomp_opcodes_da[512]; -extern RecompOpFn recomp_opcodes_db[512];*/ +extern RecompOpFn recomp_opcodes_d9[512]; +/*extern RecompOpFn recomp_opcodes_da[512];*/ +extern RecompOpFn recomp_opcodes_db[512]; extern RecompOpFn recomp_opcodes_dc[512]; -/*extern RecompOpFn recomp_opcodes_dd[512];*/ +extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; -/*extern RecompOpFn recomp_opcodes_df[512]; -extern RecompOpFn recomp_opcodes_REPE[512]; +extern RecompOpFn recomp_opcodes_df[512]; +/*extern RecompOpFn recomp_opcodes_REPE[512]; extern RecompOpFn recomp_opcodes_REPNE[512];*/ #define REG_EAX 0 diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index 507f937..6746d0d 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -9,11 +9,7 @@ #include "codegen_ir.h" #include "codegen_ops.h" #include "codegen_ops_fpu_arith.h" - -static void fpu_POP(ir_data_t *ir) -{ - uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); -} +#include "codegen_ops_helpers.h" uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { diff --git a/src/codegen_ops_fpu_loadstore.c b/src/codegen_ops_fpu_loadstore.c new file mode 100644 index 0000000..cfee360 --- /dev/null +++ b/src/codegen_ops_fpu_loadstore.c @@ -0,0 +1,134 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "x87.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_fpu_arith.h" +#include "codegen_ops_helpers.h" + +uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(ir); + + return op_pc+1; +} +uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(ir); + + return op_pc+1; +} + +uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + + return op_pc+1; +} +uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(ir); + + return op_pc+1; +} +uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + + return op_pc+1; +} +uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(ir); + + return op_pc+1; +} + + +uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(ir); + + return op_pc+1; +} +uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(ir); + + return op_pc+1; +} diff --git a/src/codegen_ops_fpu_loadstore.h b/src/codegen_ops_fpu_loadstore.h new file mode 100644 index 0000000..727f715 --- /dev/null +++ b/src/codegen_ops_fpu_loadstore.h @@ -0,0 +1,10 @@ +uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h index 55cb99a..8d9d911 100644 --- a/src/codegen_ops_helpers.h +++ b/src/codegen_ops_helpers.h @@ -41,3 +41,12 @@ static inline void SUB_SP(ir_data_t *ir, int offset) else uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); } + +static inline void fpu_POP(ir_data_t *ir) +{ + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); +} +static inline void fpu_PUSH(ir_data_t *ir) +{ + uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); +} From 6d8af5df4a9acbbfea1b6a4823bbab4521af3f05 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 20 Oct 2018 20:03:28 +0100 Subject: [PATCH 0517/1050] Added recompiled versions of memory variants of F[I]ADD, F[I]DIV, F[I]DIVR, F[I]MUL, F[I]SUB and F[I]SUBR. --- src/codegen.c | 2 +- src/codegen_backend_arm64_uops.c | 8 ++ src/codegen_backend_arm_uops.c | 8 ++ src/codegen_backend_x86-64_ops.c | 56 +++++++-- src/codegen_backend_x86-64_ops.h | 18 +-- src/codegen_backend_x86-64_uops.c | 42 ++++--- src/codegen_backend_x86_ops.c | 38 +++++- src/codegen_backend_x86_ops.h | 2 + src/codegen_backend_x86_uops.c | 8 ++ src/codegen_ir_defs.h | 2 + src/codegen_ops.c | 155 +++++++++++++++-------- src/codegen_ops.h | 2 +- src/codegen_ops_fpu_arith.c | 196 ++++++++++++++++++++++++++++++ src/codegen_ops_fpu_arith.h | 26 ++++ src/codegen_reg.c | 21 ++++ src/codegen_reg.h | 4 + 16 files changed, 495 insertions(+), 93 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 88cb01f..d06438c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -379,7 +379,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xda: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = NULL;//recomp_opcodes_da; + recomp_op_table = recomp_opcodes_da; opcode_mask = 0xff; over = 1; pc_off = -1; diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index ad15f07..193d7dd 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1850,6 +1850,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32_stack - not in range\n"); } +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); +} void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { @@ -1858,6 +1862,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos else fatal("codegen_direct_write_32_stack - not in range\n"); } +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_arm64_STR_IMM_F64(block, host_reg, REG_SP, stack_offset); +} void codegen_set_jump_dest(codeblock_t *block, void *p) { diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 7574234..b09b005 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1927,6 +1927,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); +} void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { @@ -1935,6 +1939,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos else fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); +} void codegen_set_jump_dest(codeblock_t *block, void *p) { diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 21dd087..7eb7f20 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -212,7 +212,7 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } -void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } @@ -361,7 +361,7 @@ void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base codegen_addbyte(block, base_reg | (idx_reg << 3)); } -void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } @@ -876,7 +876,7 @@ void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -897,7 +897,7 @@ void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg) codegen_addlong(block, (uint32_t)(uintptr_t)p); } } -void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); @@ -919,8 +919,26 @@ void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} -void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -941,7 +959,7 @@ void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addlong(block, (uint32_t)(uintptr_t)p); } } -void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) { if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); @@ -957,13 +975,31 @@ void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 codegen_addlong(block, addr); } } - void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } -void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); +} + +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } @@ -1041,7 +1077,7 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); } -void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1325,7 +1361,7 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } -void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); } diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 08b6892..4fbffdb 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -7,7 +7,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_ADDSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); @@ -32,7 +32,7 @@ void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_DIVSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_JMP(codeblock_t *block, void *p); @@ -105,12 +105,12 @@ void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVQ_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVQ_REG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); -void host_x86_MOVQ_ABS_REG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); @@ -130,7 +130,7 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); -void host_x86_MULSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); @@ -179,7 +179,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_SUBSD_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 15d904a..2a76566 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -534,7 +534,7 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_ADDSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); } else fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -548,13 +548,13 @@ static int codegen_FDIV(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_DIVSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } else fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -568,7 +568,7 @@ static int codegen_FMUL(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_MULSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); } else fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -582,13 +582,13 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop) if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_SUBSD_REG_REG(block, dest_reg, src_reg_b); + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_REG_REG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } else fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -797,7 +797,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) host_x86_CALL(block, codegen_mem_load_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); - host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); return 0; } @@ -815,7 +815,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_CALL(block, codegen_mem_load_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); - host_x86_MOVQ_REG_REG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); return 0; } @@ -946,7 +946,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); - host_x86_MOVQ_REG_REG(block, REG_XMM_TEMP, src_reg); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); @@ -1554,7 +1554,7 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) } void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_REG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { @@ -1563,7 +1563,7 @@ void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); - host_x86_MOVQ_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) @@ -1589,7 +1589,7 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int } void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_REG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { @@ -1598,7 +1598,7 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) @@ -1614,11 +1614,19 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); +} void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); +} void codegen_set_jump_dest(codeblock_t *block, void *p) { diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index ae601b7..7db67b9 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -783,9 +783,27 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int } void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) { if (!offset) @@ -840,6 +858,24 @@ void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); +} void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 19ef66a..fba62f9 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -109,11 +109,13 @@ void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg); void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 04803d7..003b4ae 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1601,11 +1601,19 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); +} void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); } +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); +} void codegen_set_jump_dest(codeblock_t *block, void *p) { diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index c935d0c..41bacd7 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -516,8 +516,10 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_set_jump_dest(codeblock_t *block, void *p); diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 547b627..b9285dd 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -112,20 +112,20 @@ RecompOpFn recomp_opcodes_d8[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -134,20 +134,20 @@ RecompOpFn recomp_opcodes_d8[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -202,6 +202,53 @@ RecompOpFn recomp_opcodes_d9[512] = /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; +RecompOpFn recomp_opcodes_da[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, +/*30*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, + +/*40*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, +/*70*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, + +/*80*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, +/*b0*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, +/*30*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, + +/*40*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, +/*70*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, + +/*80*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, +/*b0*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + RecompOpFn recomp_opcodes_db[512] = { /*16-bit data*/ @@ -253,20 +300,20 @@ RecompOpFn recomp_opcodes_dc[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -275,20 +322,20 @@ RecompOpFn recomp_opcodes_dc[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -347,20 +394,20 @@ RecompOpFn recomp_opcodes_de[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, +/*30*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, +/*70*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, +/*b0*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -369,20 +416,20 @@ RecompOpFn recomp_opcodes_de[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, +/*30*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, +/*70*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, +/*b0*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 7231e0e..6e86be6 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -11,7 +11,7 @@ extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; -/*extern RecompOpFn recomp_opcodes_da[512];*/ +extern RecompOpFn recomp_opcodes_da[512]; extern RecompOpFn recomp_opcodes_db[512]; extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index 6746d0d..ae62746 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -200,3 +200,199 @@ uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } + +#define ropF_arith_mem(name, load_uop) \ +uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFSUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFSUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} + +ropF_arith_mem(s, uop_MEM_LOAD_SINGLE) +ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) + +#define ropFI_arith_mem(name, temp_reg) \ +uint32_t ropFIADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFIDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFIDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFIMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFISUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFISUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc+1; \ +} + +ropFI_arith_mem(l, IREG_temp0) +ropFI_arith_mem(w, IREG_temp0_W) diff --git a/src/codegen_ops_fpu_arith.h b/src/codegen_ops_fpu_arith.h index 4e60233..2cbafb7 100644 --- a/src/codegen_ops_fpu_arith.h +++ b/src/codegen_ops_fpu_arith.h @@ -16,3 +16,29 @@ uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFADDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFADDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVRs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFDIVRd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFMULs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFMULd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBRs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSUBRd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFIADDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIADDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIDIVl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIDIVw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIDIVRl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIDIVRw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIMULl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFIMULw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISUBl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISUBw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISUBRl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISUBRw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index fc97b20..991c8c5 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -33,6 +33,7 @@ enum REG_DWORD, REG_QWORD, REG_POINTER, + REG_DOUBLE, REG_FPU_ST_BYTE, REG_FPU_ST_DOUBLE }; @@ -119,6 +120,8 @@ struct [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER}, [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER}, [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER}, + + [IREG_temp0d] = {REG_DOUBLE, (void *)48, REG_FP} }; void codegen_reg_reset() @@ -188,6 +191,15 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, codegen_direct_read_32(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; + case REG_DOUBLE: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_double_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_double(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; + case REG_FPU_ST_DOUBLE: if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]); @@ -244,6 +256,15 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i codegen_direct_write_ptr(block, p, reg_set->reg_list[c]); break; + case REG_DOUBLE: + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); + if ((uintptr_t)p < 256) + codegen_direct_write_double_stack(block, (int)p, reg_set->reg_list[c]); + else + codegen_direct_write_double(block, p, reg_set->reg_list[c]); + break; + case REG_FPU_ST_BYTE: if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 986f0aa..358d6a8 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -67,6 +67,8 @@ enum IREG_FPU_TOP = 37, + IREG_temp0d = 39, + /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() to access. When CODEBLOCK_STATIC_TOP is set, the physical register number will be @@ -129,6 +131,8 @@ enum IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, + IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, + IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, From bce9ad4f3dcf617de6f54861d8329d837d60aefe Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 21 Oct 2018 16:22:20 +0100 Subject: [PATCH 0518/1050] Added recompiled versions of FFREE, FLD, FST, FSTP and FXCH. --- src/codegen_backend_arm64_uops.c | 57 ++++++++++++++++++++++++++--- src/codegen_backend_arm_uops.c | 52 +++++++++++++++++++++++++-- src/codegen_backend_x86-64_ops.c | 36 +++++++++++++++++++ src/codegen_backend_x86-64_ops.h | 3 ++ src/codegen_backend_x86-64_uops.c | 52 +++++++++++++++++++++++++-- src/codegen_backend_x86_ops.c | 28 +++++++++++++++ src/codegen_backend_x86_ops.h | 3 ++ src/codegen_backend_x86_uops.c | 60 +++++++++++++++++++++++++++++-- src/codegen_ir_defs.h | 9 ++++- src/codegen_ops.c | 17 ++++----- src/codegen_reg.c | 48 +++++++++++++++++++++++-- src/codegen_reg.h | 26 +++++++++++--- 12 files changed, 364 insertions(+), 27 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 193d7dd..7ec43dc 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -18,6 +18,7 @@ #define REG_IS_B(size) (size == IREG_SIZE_B) #define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_D(size) (size == IREG_SIZE_D) +#define REG_IS_Q(size) (size == IREG_SIZE_Q) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -1040,6 +1041,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop) host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) + { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } + else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -1767,6 +1776,13 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) @@ -1774,6 +1790,22 @@ void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_double - not in range\n"); } +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); +} +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); @@ -1804,6 +1836,20 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) else fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); +} void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); @@ -1812,12 +1858,13 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index b09b005..22e546d 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -76,6 +76,7 @@ void host_arm_nop(codeblock_t *block) #define REG_IS_B(size) (size == IREG_SIZE_B) #define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_D(size) (size == IREG_SIZE_D) +#define REG_IS_Q(size) (size == IREG_SIZE_Q) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -1116,6 +1117,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop) host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) + { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } + else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -1830,6 +1839,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FSUB & UOP_MASK] = codegen_FSUB }; +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +{ + if (in_range_h(p, &cpu_state)) + host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); +} void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { if (in_range_h(p, &cpu_state)) @@ -1847,10 +1863,30 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +{ + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); } +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); @@ -1884,6 +1920,14 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) else fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +{ + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); @@ -1892,9 +1936,13 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 7eb7f20..38cf727 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -663,6 +663,27 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_r codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ } +void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOV8_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } + else + { + fatal("host_x86_MOV8_REG_ABS - out of range\n"); + } +} void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -709,6 +730,21 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) } } +void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } + else + { + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 4fbffdb..6d8a8f0 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -75,9 +75,12 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift); + void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 2a76566..367f36e 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -21,6 +21,7 @@ #define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_D(size) (size == IREG_SIZE_D) +#define REG_IS_Q(size) (size == IREG_SIZE_Q) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -971,6 +972,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop) { host_x86_MOV8_REG_REG(block, dest_reg, src_reg); } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) + { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } + else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -1544,6 +1553,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FSUB & UOP_MASK] = codegen_FSUB }; +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV8_REG_ABS(block, host_reg, p); +} void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { host_x86_MOV16_REG_ABS(block, host_reg, p); @@ -1552,10 +1565,32 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOVQ_XREG_ABS(block, host_reg, p); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); +} +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); +} void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); @@ -1578,6 +1613,14 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOVQ_ABS_XREG(block, p, host_reg); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOVQ_ABS_XREG(block, p, host_reg); +} void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); @@ -1587,9 +1630,14 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 7db67b9..6d5521a 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -571,6 +571,21 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ } +void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } + else + { + codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } +} void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -607,6 +622,19 @@ void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p codegen_addlong(block, (uint32_t)p); } +void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift) +{ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } + else + { + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index fba62f9..102639a 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -79,11 +79,14 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); +void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift); +void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_addr, uint32_t addr, int base_reg, int idx_reg, int shift); + void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 003b4ae..d060bdd 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -31,6 +31,7 @@ #define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_D(size) (size == IREG_SIZE_D) +#define REG_IS_Q(size) (size == IREG_SIZE_Q) static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -962,6 +963,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop) { host_x86_MOV8_REG_REG(block, dest_reg, src_reg); } + else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) + { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } + else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -1531,6 +1540,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FSUB & UOP_MASK] = codegen_FSUB }; +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV8_REG_ABS(block, host_reg, p); +} void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { host_x86_MOV16_REG_ABS(block, host_reg, p); @@ -1539,10 +1552,32 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOVQ_XREG_ABS(block, host_reg, p); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); +} +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +{ + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); +} void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); @@ -1565,6 +1600,14 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOVQ_ABS_XREG(block, p, host_reg); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOVQ_ABS_XREG(block, p, host_reg); +} void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); @@ -1574,9 +1617,14 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { @@ -1601,6 +1649,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); +} void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); @@ -1610,6 +1662,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos { host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); } +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); +} void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 41bacd7..036493e 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -501,21 +501,28 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) #define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p); +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx); +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx); void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx); void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg); void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg); +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg); void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg); void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); diff --git a/src/codegen_ops.c b/src/codegen_ops.c index b9285dd..56fff16 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -6,6 +6,7 @@ #include "codegen_ops_branch.h" #include "codegen_ops_fpu_arith.h" #include "codegen_ops_fpu_loadstore.h" +#include "codegen_ops_fpu_misc.h" #include "codegen_ops_jump.h" #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" @@ -174,8 +175,8 @@ RecompOpFn recomp_opcodes_d9[512] = /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -196,8 +197,8 @@ RecompOpFn recomp_opcodes_d9[512] = /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; @@ -362,8 +363,8 @@ RecompOpFn recomp_opcodes_dd[512] = /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -384,8 +385,8 @@ RecompOpFn recomp_opcodes_dd[512] = /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 991c8c5..ac1e417 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -35,7 +35,8 @@ enum REG_POINTER, REG_DOUBLE, REG_FPU_ST_BYTE, - REG_FPU_ST_DOUBLE + REG_FPU_ST_DOUBLE, + REG_FPU_ST_QWORD }; enum @@ -113,6 +114,15 @@ struct [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_MM0] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM1] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM2] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM3] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM4] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM5] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM6] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM7] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ @@ -121,7 +131,8 @@ struct [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER}, [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER}, - [IREG_temp0d] = {REG_DOUBLE, (void *)48, REG_FP} + [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP}, + [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP}, }; void codegen_reg_reset() @@ -200,7 +211,27 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, codegen_direct_read_double(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; + case REG_FPU_ST_BYTE: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_8(block, reg_set->reg_list[c], &cpu_state.tag[ir_reg.reg & 7]); + else + codegen_direct_read_st_8(block, reg_set->reg_list[c], &cpu_state.tag[0], ir_reg.reg & 7); + break; + + case REG_FPU_ST_QWORD: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_64(block, reg_set->reg_list[c], &cpu_state.MM[ir_reg.reg & 7]); + else + codegen_direct_read_st_64(block, reg_set->reg_list[c], &cpu_state.MM[0], ir_reg.reg & 7); + break; + case REG_FPU_ST_DOUBLE: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]); else @@ -266,13 +297,26 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i break; case REG_FPU_ST_BYTE: + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); else codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); break; + case REG_FPU_ST_QWORD: + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); + else + codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); + break; + case REG_FPU_ST_DOUBLE: + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); else diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 358d6a8..2830d40 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -13,6 +13,7 @@ #define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) #define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) #define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) +#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) enum { @@ -67,7 +68,8 @@ enum IREG_FPU_TOP = 37, - IREG_temp0d = 39, + IREG_temp0d = 38, + IREG_temp1d = 39, /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() to access. @@ -93,9 +95,18 @@ enum IREG_tag6 = 54, IREG_tag7 = 55, - IREG_COUNT = 56, + IREG_MM0 = 56, + IREG_MM1 = 57, + IREG_MM2 = 58, + IREG_MM3 = 59, + IREG_MM4 = 60, + IREG_MM5 = 61, + IREG_MM6 = 62, + IREG_MM7 = 63, + + IREG_COUNT = 64, - IREG_INVALID = 63, + IREG_INVALID = 255, IREG_AX = IREG_EAX + IREG_SIZE_W, IREG_CX = IREG_ECX + IREG_SIZE_W, @@ -130,9 +141,13 @@ enum IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, - + IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, - + IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, + + IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, + IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, + IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, @@ -148,6 +163,7 @@ enum #define IREG_32(reg) ((reg) + IREG_EAX) #define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) +#define IREG_MM(r) (IREG_MM0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) #define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) #define IREG_TOP_diff_stack_offset 32 From 589f50e479f5a50fc5cf563b79d26402d18404dc Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 22 Oct 2018 21:23:09 +0100 Subject: [PATCH 0519/1050] Added recompiled version of FILDq. --- src/codegen_backend_arm.c | 7 +++++-- src/codegen_backend_arm64.c | 7 +++++-- src/codegen_backend_arm64_defs.h | 1 + src/codegen_backend_arm64_ops.c | 5 +++++ src/codegen_backend_arm64_ops.h | 1 + src/codegen_backend_arm64_uops.c | 15 ++++++++++++++- src/codegen_backend_arm_defs.h | 1 + src/codegen_backend_arm_uops.c | 20 ++++++++++++++++++++ src/codegen_backend_x86-64.c | 7 +++++-- src/codegen_backend_x86-64_defs.h | 1 + src/codegen_backend_x86-64_ops.c | 7 ++++++- src/codegen_backend_x86-64_ops.h | 18 +++++++++--------- src/codegen_backend_x86-64_uops.c | 13 +++++++++++++ src/codegen_backend_x86.c | 7 +++++-- src/codegen_backend_x86_defs.h | 1 + src/codegen_backend_x86_ops.c | 16 ++++++++++++++++ src/codegen_backend_x86_ops.h | 3 +++ src/codegen_backend_x86_uops.c | 17 +++++++++++++++++ src/codegen_ops.c | 12 ++++++------ src/codegen_ops_fpu_loadstore.c | 16 ++++++++++++++++ src/codegen_ops_fpu_loadstore.h | 1 + 21 files changed, 151 insertions(+), 25 deletions(-) diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 67711e6..7e46a7b 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -20,6 +20,7 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_quad; void *codegen_mem_load_single; void *codegen_mem_load_double; @@ -93,7 +94,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); } - else if (size == 8 && is_float) + else if (size == 8) { host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); @@ -117,7 +118,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) fatal("build_load_routine - unknown size %i\n", size); if (size == 4 && is_float) host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); - else if (size == 8 && is_float) + else if (size == 8) host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); @@ -206,6 +207,8 @@ static void build_loadstore_routines(codeblock_t *block) build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); codegen_mem_load_single = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 1); codegen_mem_load_double = &codeblock[block_current].data[block_pos]; diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 638c65a..be5a474 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -20,6 +20,7 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_quad; void *codegen_mem_load_single; void *codegen_mem_load_double; @@ -96,7 +97,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); else if (size == 4 && is_float) host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); - else if (size == 8 && is_float) + else if (size == 8) host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); host_arm64_MOVZ_IMM(block, REG_W1, 0); host_arm64_RET(block, REG_X30); @@ -118,7 +119,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); if (size == 4 && is_float) host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); - else if (size == 8 && is_float) + else if (size == 8) host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); host_arm64_RET(block, REG_X30); @@ -205,6 +206,8 @@ static void build_loadstore_routines(codeblock_t *block) build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); codegen_mem_load_single = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 1); codegen_mem_load_double = &codeblock[block_current].data[block_pos]; diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index f992759..1a91768 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -117,6 +117,7 @@ extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_quad; extern void *codegen_mem_load_single; extern void *codegen_mem_load_double; diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 1c6da2f..9603132 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -124,6 +124,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LSR (0x1ac02400) #define OPCODE_NOP (0xd503201f) #define OPCODE_RET (0xd65f0000) +#define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) #define OPCODE_STR_REG (0xb8206800) #define OPCODE_STRB_REG (0x38206800) @@ -754,6 +755,10 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); } +void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); +} void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index fb83b83..ad759ea 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -106,6 +106,7 @@ void host_arm64_RET(codeblock_t *block, int reg); void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); +void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 7ec43dc..b3aa3c6 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -817,8 +817,12 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_arm64_call(block, codegen_mem_load_long); } + else if (REG_IS_Q(dest_size)) + { + host_arm64_call(block, codegen_mem_load_quad); + } else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); if (REG_IS_B(dest_size)) { @@ -836,6 +840,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); } + else if (REG_IS_Q(dest_size)) + { + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + } return 0; } @@ -1169,6 +1177,11 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); } + else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) + { + host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); + host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); + } else fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 6473fd5..9901b29 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -69,6 +69,7 @@ extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_quad; extern void *codegen_mem_load_single; extern void *codegen_mem_load_double; diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 22e546d..b60f792 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -888,6 +888,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_arm_BL(block, (uintptr_t)codegen_mem_load_long); } + else if (REG_IS_Q(dest_size)) + { + host_arm_BL(block, (uintptr_t)codegen_mem_load_quad); + } else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_arm_TST_REG(block, REG_R1, REG_R1); @@ -908,6 +912,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_arm_MOV_REG(block, dest_reg, REG_R0); } + else if (REG_IS_Q(dest_size)) + { + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } return 0; } @@ -1237,6 +1245,10 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) return 0; } +static double int64_to_double(int64_t a) +{ + return (double)a; +} static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -1253,6 +1265,14 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); } + else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) + { + /*ARMv7 has no instructions to convert a 64-bit integer to a double. + For simplicity, call a C function and let the compiler do it.*/ + host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)int64_to_double); /*Input - R0/R1, Output - D0*/ + host_arm_VMOV_D_D(block, dest_reg, REG_D0); + } else fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index dc43a39..6306741 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -19,6 +19,7 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_quad; void *codegen_mem_load_single; void *codegen_mem_load_double; @@ -92,7 +93,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); else if (size == 4 && is_float) host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else if (size == 8 && is_float) + else if (size == 8) host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); else fatal("build_load_routine: size=%i\n", size); @@ -131,7 +132,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); } - else if (size == 8 && is_float) + else if (size == 8) { host_x86_CALL(block, (void *)readmemql); host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); @@ -242,6 +243,8 @@ static void build_loadstore_routines(codeblock_t *block) build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); codegen_mem_load_single = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 1); codegen_mem_load_double = &codeblock[block_current].data[block_pos]; diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index 01c0c26..4f7fe4f 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -50,6 +50,7 @@ extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_quad; extern void *codegen_mem_load_single; extern void *codegen_mem_load_double; diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 38cf727..3c3d6c1 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -348,7 +348,12 @@ void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 6d8a8f0..5286d2b 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -29,6 +29,7 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); @@ -75,6 +76,8 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); +void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); + void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); @@ -105,18 +108,17 @@ void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); - -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); @@ -125,8 +127,6 @@ void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg); -void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); - void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 367f36e..15060cf 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -765,6 +765,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, codegen_mem_load_long); } + else if (REG_IS_Q(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_quad); + } else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); @@ -781,6 +785,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); } + else if (REG_IS_Q(dest_size)) + { + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } return 0; } @@ -1069,6 +1077,11 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); } + else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) + { + host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); + host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); + } else fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index ab6a3be..71a5d0c 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -19,6 +19,7 @@ void *codegen_mem_load_byte; void *codegen_mem_load_word; void *codegen_mem_load_long; +void *codegen_mem_load_quad; void *codegen_mem_load_single; void *codegen_mem_load_double; @@ -90,7 +91,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); else if (size == 4 && is_float) host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else if (size == 8 && is_float) + else if (size == 8/* && is_float*/) host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); else fatal("build_load_routine: size=%i\n", size); @@ -123,7 +124,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); } - else if (size == 8 && is_float) + else if (size == 8)// && is_float) { host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); @@ -228,6 +229,8 @@ static void build_loadstore_routines(codeblock_t *block) build_load_routine(block, 2, 0); codegen_mem_load_long = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); codegen_mem_load_single = &codeblock[block_current].data[block_pos]; build_load_routine(block, 4, 1); codegen_mem_load_double = &codeblock[block_current].data[block_pos]; diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index 5a5ea69..e2ca668 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -28,6 +28,7 @@ extern void *codegen_mem_load_byte; extern void *codegen_mem_load_word; extern void *codegen_mem_load_long; +extern void *codegen_mem_load_quad; extern void *codegen_mem_load_single; extern void *codegen_mem_load_double; diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 6d5521a..360c1a3 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1316,4 +1316,20 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 } } +void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ + else + codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ +} + +void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ + else + codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ +} + #endif diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 102639a..1ebffeb 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -199,3 +199,6 @@ void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); + +void host_x87_FILDq_BASE(codeblock_t *block, int base_reg); +void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index d060bdd..ef9496f 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -755,6 +755,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, codegen_mem_load_long); } + else if (REG_IS_Q(dest_size)) + { + host_x86_CALL(block, codegen_mem_load_quad); + } else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); @@ -771,6 +775,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); } + else if (REG_IS_Q(dest_size)) + { + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } return 0; } @@ -1060,6 +1068,15 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); } + else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) + { + /*There is no SSE instruction to convert a 64-bit integer to a floating point value. + Instead we have to bounce the integer through memory via x87.*/ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FILDq_BASE(block, REG_ESP); + host_x87_FSTPd_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + } else fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 56fff16..2a4191b 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -444,17 +444,17 @@ RecompOpFn recomp_opcodes_df[512] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -466,17 +466,17 @@ RecompOpFn recomp_opcodes_df[512] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_fpu_loadstore.c b/src/codegen_ops_fpu_loadstore.c index cfee360..90682e2 100644 --- a/src/codegen_ops_fpu_loadstore.c +++ b/src/codegen_ops_fpu_loadstore.c @@ -132,3 +132,19 @@ uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc+1; } +uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_MM(-1)); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); + fpu_PUSH(ir); + + return op_pc+1; +} diff --git a/src/codegen_ops_fpu_loadstore.h b/src/codegen_ops_fpu_loadstore.h index 727f715..58d4121 100644 --- a/src/codegen_ops_fpu_loadstore.h +++ b/src/codegen_ops_fpu_loadstore.h @@ -8,3 +8,4 @@ uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 87191dde55a64add6258db3b9d05a603da5b2cbb Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 Oct 2018 20:54:33 +0100 Subject: [PATCH 0520/1050] Added recompiled versions of FIST and FISTP. --- src/codegen_backend_arm.c | 77 +++++++++++++++++++++++++++- src/codegen_backend_arm64.c | 73 ++++++++++++++++++++++++++- src/codegen_backend_arm64_defs.h | 6 ++- src/codegen_backend_arm64_ops.c | 81 +++++++++++++++++++++++++++++ src/codegen_backend_arm64_ops.h | 19 +++++++ src/codegen_backend_arm64_uops.c | 55 +++++++++++++++++++- src/codegen_backend_arm_defs.h | 6 ++- src/codegen_backend_arm_ops.c | 21 ++++++-- src/codegen_backend_arm_ops.h | 3 ++ src/codegen_backend_arm_uops.c | 84 +++++++++++++++++++++++++++++++ src/codegen_backend_x86-64.c | 17 ++++++- src/codegen_backend_x86-64_defs.h | 1 + src/codegen_backend_x86-64_ops.c | 28 +++++++++++ src/codegen_backend_x86-64_ops.h | 6 +++ src/codegen_backend_x86-64_uops.c | 58 ++++++++++++++++++++- src/codegen_backend_x86.c | 26 +++++++--- src/codegen_backend_x86_defs.h | 1 + src/codegen_backend_x86_ops.c | 61 +++++++++++++++++++++- src/codegen_backend_x86_ops.h | 9 ++++ src/codegen_backend_x86_uops.c | 82 +++++++++++++++++++++++++++--- src/codegen_ir.c | 2 +- src/codegen_ir_defs.h | 20 ++++++++ src/codegen_ops.c | 36 ++++++------- src/codegen_ops_fpu_loadstore.c | 79 +++++++++++++++++++++++++++++ src/codegen_ops_fpu_loadstore.h | 6 +++ src/codegen_reg.h | 1 + src/ibm.h | 6 ++- src/x87.h | 6 +++ src/x87_ops_misc.h | 16 +++--- 29 files changed, 829 insertions(+), 57 deletions(-) diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 7e46a7b..5852294 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -8,6 +8,7 @@ #include "codegen_backend_arm_ops.h" #include "codegen_reg.h" #include "x86.h" +#include "x87.h" #if defined(__linux__) || defined(__APPLE__) #include @@ -27,9 +28,12 @@ void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_quad; void *codegen_mem_store_single; void *codegen_mem_store_double; +void *codegen_fp_round; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_R4, @@ -167,7 +171,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); } - else if (size == 8 && is_float) + else if (size == 8) { host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); @@ -181,7 +185,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); if (size == 4 && is_float) host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); - else if (size == 8 && is_float) + else if (size == 8) host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); if (size == 1) host_arm_BL(block, (uintptr_t)writememb386l); @@ -220,12 +224,65 @@ static void build_loadstore_routines(codeblock_t *block) build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); codegen_mem_store_single = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 1); codegen_mem_store_double = &codeblock[block_current].data[block_pos]; build_store_routine(block, 8, 1); } +/*VFP has a specific round-to-zero instruction, and the default rounding mode + is nearest. For round up/down, temporarily change the rounding mode in FPCSR*/ +#define FPCSR_ROUNDING_MASK (3 << 22) +#define FPCSR_ROUNDING_UP (1 << 22) +#define FPCSR_ROUNDING_DOWN (2 << 22) + +static void build_fp_round_routine(codeblock_t *block) +{ + uint32_t *jump_table; + + host_arm_MOV_REG(block, REG_TEMP2, REG_LR); + host_arm_MOV_REG(block, REG_LR, REG_TEMP2); + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); + host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); + addlong(0); + + jump_table = (uint32_t *)&block->data[block_pos]; + addlong(0); + addlong(0); + addlong(0); + addlong(0); + + jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block->data[block_pos]; //tie even + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); + + jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //pos inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); + + jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block->data[block_pos]; //neg inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); + + jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //zero + host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); + + block_pos = (block_pos + 63) & ~63; +} + void codegen_backend_init() { int c; @@ -265,6 +322,22 @@ void codegen_backend_init() block_current = BLOCK_SIZE; block_pos = 0; build_loadstore_routines(&codeblock[block_current]); + + codegen_fp_round = &codeblock[block_current].data[block_pos]; + build_fp_round_routine(&codeblock[block_current]); + + asm("vmrs %0, fpscr\n" + : "=r" (cpu_state.old_fp_control) + ); + if ((cpu_state.old_fp_control >> 22) & 3) + fatal("VFP not in nearest rounding mode\n"); +} + +void codegen_set_rounding_mode(int mode) +{ + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 2; } /*R10 - cpu_state*/ diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index be5a474..f201c4b 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -8,6 +8,7 @@ #include "codegen_backend_arm64_ops.h" #include "codegen_reg.h" #include "x86.h" +#include "x87.h" #if defined(__linux__) || defined(__APPLE__) #include @@ -27,9 +28,13 @@ void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_quad; void *codegen_mem_store_single; void *codegen_mem_store_double; +void *codegen_fp_round; +void *codegen_fp_round_quad; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_X19, @@ -168,7 +173,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); else if (size == 4 && is_float) host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); - else if (size == 8 && is_float) + else if (size == 8) host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); host_arm64_MOVZ_IMM(block, REG_X1, 0); host_arm64_RET(block, REG_X30); @@ -179,7 +184,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); if (size == 4 && is_float) host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); - else if (size == 8 && is_float) + else if (size == 8) host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); if (size == 1) host_arm64_call(block, (uintptr_t)writememb386l); @@ -219,12 +224,60 @@ static void build_loadstore_routines(codeblock_t *block) build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); codegen_mem_store_single = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 1); codegen_mem_store_double = &codeblock[block_current].data[block_pos]; build_store_routine(block, 8, 1); } +static void build_fp_round_routine(codeblock_t *block, int is_quad) +{ + uint64_t *jump_table; + + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); + host_arm64_ADR(block, REG_TEMP2, 12); + host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); + host_arm64_BR(block, REG_TEMP2); + + jump_table = &block->data[block_pos]; + addquad(0); + addquad(0); + addquad(0); + addquad(0); + + jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block->data[block_pos]; //tie even + if (is_quad) + host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); + + jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //pos inf + if (is_quad) + host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); + + jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block->data[block_pos]; //neg inf + if (is_quad) + host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); + + jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //zero + if (is_quad) + host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); + + block_pos = (block_pos + 63) & ~63; +} + void codegen_backend_init() { int c; @@ -265,6 +318,22 @@ void codegen_backend_init() block_pos = 0; codegen_reset_literal_pool(&codeblock[block_current]); build_loadstore_routines(&codeblock[block_current]); + + codegen_fp_round = &codeblock[block_current].data[block_pos]; + build_fp_round_routine(&codeblock[block_current], 0); + codegen_fp_round_quad = &codeblock[block_current].data[block_pos]; + build_fp_round_routine(&codeblock[block_current], 1); + + asm("mrs %0, fpcr\n" + : "=r" (cpu_state.old_fp_control) + ); +} + +void codegen_set_rounding_mode(int mode) +{ + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 3; } /*R11 - literal pool diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index 1a91768..cd771cb 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -124,5 +124,9 @@ extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; -extern void *codegen_mem_store_double; \ No newline at end of file +extern void *codegen_mem_store_double; + +extern void *codegen_fp_round; +extern void *codegen_fp_round_quad; \ No newline at end of file diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 9603132..d3d62c2 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -48,6 +48,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SHIFT 24 #define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) #define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) +#define OPCODE_ADR (0x10 << OPCODE_SHIFT) #define OPCODE_B (0x14 << OPCODE_SHIFT) #define OPCODE_BCOND (0x54 << OPCODE_SHIFT) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) @@ -59,6 +60,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) #define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) +#define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) #define OPCODE_AND_IMM (0x024 << 23) #define OPCODE_ANDS_IMM (0x0e4 << 23) @@ -69,6 +71,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BFI (0x0cc << 22) #define OPCODE_LDR_IMM_W (0x2e5 << 22) +#define OPCODE_LDR_IMM_X (0x3e5 << 22) #define OPCODE_LDR_IMM_F64 (0x3f5 << 22) #define OPCODE_LDRB_IMM_W (0x0e5 << 22) #define OPCODE_LDRH_IMM (0x1e5 << 22) @@ -105,6 +108,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_FADD_D (0x1e602800) #define OPCODE_FCVT_D_S (0x1e22c000) #define OPCODE_FCVT_S_D (0x1e624000) +#define OPCODE_FCVTMS_W_D (0x1e700000) +#define OPCODE_FCVTMS_X_D (0x9e700000) +#define OPCODE_FCVTNS_W_D (0x1e600000) +#define OPCODE_FCVTNS_X_D (0x9e600000) +#define OPCODE_FCVTPS_W_D (0x1e680000) +#define OPCODE_FCVTPS_X_D (0x9e680000) +#define OPCODE_FCVTZS_W_D (0x1e780000) +#define OPCODE_FCVTZS_X_D (0x9e780000) #define OPCODE_FDIV_D (0x1e601800) #define OPCODE_FMOV_D_D (0x1e604000) #define OPCODE_FMOV_D_Q (0x9e670000) @@ -112,8 +123,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_FMOV_S_W (0x1e270000) #define OPCODE_FMOV_W_S (0x1e260000) #define OPCODE_FMUL_D (0x1e600800) +#define OPCODE_FRINTX_D (0x1e674000) #define OPCODE_FSUB_D (0x1e603800) #define OPCODE_LDR_REG (0xb8606800) +#define OPCODE_LDRX_REG (0xf8606800) #define OPCODE_LDRB_REG (0x38606800) #define OPCODE_LDRH_REG (0x78606800) #define OPCODE_LDRX_REG_LSL3 (0xf8607800) @@ -122,6 +135,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LDR_REG_F64_S (0xfc607800) #define OPCODE_LSL (0x1ac02000) #define OPCODE_LSR (0x1ac02400) +#define OPCODE_MSR_FPCR (0xd51b4400) #define OPCODE_NOP (0xd503201f) #define OPCODE_RET (0xd65f0000) #define OPCODE_SCVTF_D_Q (0x9e620000) @@ -145,7 +159,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define IMMR(immr) ((immr) << 16) #define IMMS(imms) ((imms) << 10) +#define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) + #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) +#define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) #define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) #define OFFSET12_B(offset) (offset << 10) @@ -254,6 +271,11 @@ void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) +{ + codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); +} + void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ @@ -534,6 +556,39 @@ void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); @@ -570,6 +625,11 @@ void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) @@ -583,6 +643,12 @@ void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int of fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } +void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) +{ + if (!in_range12_q(offset)) + fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +} void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset) { @@ -606,6 +672,10 @@ void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offs { codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } +void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +{ + codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +} void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { @@ -711,6 +781,11 @@ void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } +void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) +{ + codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); +} + void host_arm64_NOP(codeblock_t *block) { codegen_addlong(block, OPCODE_NOP); @@ -862,6 +937,12 @@ void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) +{ + codegen_addlong(block, OPCODE_TBNZ | Rt(reg) | BIT_TBxZ(bit)); + return (uint32_t *)&block->data[block_pos-4]; +} + void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index ad759ea..3409335 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -2,6 +2,8 @@ void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset); + void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); @@ -59,18 +61,31 @@ void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); +void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset); void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset); void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); +void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -97,6 +112,8 @@ void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shi void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data); void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data); +void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg); + void host_arm64_NOP(codeblock_t *block); void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); @@ -130,6 +147,8 @@ void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit); + #define host_arm64_TST_IMM(block, src_n_reg, imm_data) host_arm64_ANDS_IMM(block, REG_XZR, src_n_reg, imm_data) void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index b3aa3c6..649c72f 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -942,8 +942,13 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_arm64_MOV_REG(block, REG_W1, src_reg, 0); host_arm64_call(block, codegen_mem_store_long); } + else if (REG_IS_Q(src_size)) + { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_quad); + } else - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); return 0; @@ -1187,6 +1192,52 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) + { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); + } + else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) + { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) + { + uint8_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); + branch_offset = host_arm64_TBNZ(block, tag_reg, 7); + + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round_quad); + host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); + + host_arm64_branch_set_offset(branch_offset, &block->data[block_pos]); + } + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -1719,6 +1770,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 9901b29..7deb72f 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -22,7 +22,8 @@ #define REG_CPUSTATE REG_R10 -#define REG_TEMP REG_R3 +#define REG_TEMP REG_R3 +#define REG_TEMP2 REG_R2 #define REG_D0 0 #define REG_D1 1 @@ -76,5 +77,8 @@ extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; + +extern void *codegen_fp_round; \ No newline at end of file diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 06841ea..98653e7 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -104,9 +104,11 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VADD 0xee300b00 -#define OPCODE_VCVT_D_IS 0xeeb80bc0 -#define OPCODE_VCVT_D_S 0xeeb70ac0 -#define OPCODE_VCVT_S_D 0xeeb70bc0 +#define OPCODE_VCVT_D_IS 0xeeb80bc0 +#define OPCODE_VCVT_D_S 0xeeb70ac0 +#define OPCODE_VCVT_IS_D 0xeebd0bc0 +#define OPCODE_VCVT_S_D 0xeeb70bc0 +#define OPCODE_VCVTR_IS_D 0xeebd0b40 #define OPCODE_VDIV 0xee800b00 #define OPCODE_VLDR_D 0xed900b00 #define OPCODE_VLDR_S 0xed900a00 @@ -115,6 +117,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMOV_D_64 0xec400b10 #define OPCODE_VMOV_S_32 0xee000a10 #define OPCODE_VMOV_D_D 0xeeb00b40 +#define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 @@ -770,10 +773,18 @@ void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -810,6 +821,10 @@ void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); +} void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 6e2218e..478d232 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -118,7 +118,9 @@ void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -127,6 +129,7 @@ void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high); void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index b60f792..5b00a61 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1,7 +1,9 @@ #ifdef __ARM_EABI__ +#include #include "ibm.h" #include "x86.h" +#include "x87.h" #include "386_common.h" #include "codegen.h" #include "codegen_backend.h" @@ -1013,6 +1015,11 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_arm_MOV_REG(block, REG_R1, src_reg); host_arm_BL(block, (uintptr_t)codegen_mem_store_long); } + else if (REG_IS_Q(src_size)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_quad); + } else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); host_arm_TST_REG(block, REG_R1, REG_R1); @@ -1278,6 +1285,81 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_fp_round); + host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); + } + else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_fp_round); + host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int64_t x87_fround64(double b) +{ + int64_t a, c; + + switch ((cpu_state.npxc >> 10) & 3) + { + case 0: /*Nearest*/ + a = (int64_t)floor(b); + c = (int64_t)floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t)floor(b); + case 2: /*Up*/ + return (int64_t)ceil(b); + case 3: /*Chop*/ + return (int64_t)b; + } + + return 0; +} +static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) + { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm_VMOV_D_D(block, dest_reg, src_64_reg); + host_arm_TST_IMM(block, tag_reg, TAG_UINT64); + branch_offset = host_arm_BNE_(block); + + /*VFP/NEON has no instructions to convert a float to 64-bit integer, + so call out to C.*/ + host_arm_VMOV_D_D(block, REG_D0, src_reg); + host_arm_call(block, x87_fround64); + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + + *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + } + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -1810,6 +1892,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 6306741..bb92241 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -26,6 +26,7 @@ void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_quad; void *codegen_mem_store_single; void *codegen_mem_store_double; @@ -192,7 +193,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); else if (size == 4 && is_float) host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else if (size == 8 && is_float) + else if (size == 8) host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); else fatal("build_store_routine: size=%i\n", size); @@ -208,7 +209,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); if (size == 4 && is_float) host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data - else if (size == 8 && is_float) + else if (size == 8) host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); //data else host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data @@ -256,6 +257,8 @@ static void build_loadstore_routines(codeblock_t *block) build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); codegen_mem_store_single = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 1); codegen_mem_store_double = &codeblock[block_current].data[block_pos]; @@ -300,6 +303,16 @@ void codegen_backend_init() block_pos = 0; build_loadstore_routines(&codeblock[block_current]); // fatal("Here\n"); + + asm( + "stmxcsr %0\n" + : "=m" (cpu_state.old_fp_control) + ); +} + +void codegen_set_rounding_mode(int mode) +{ + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); } static inline void call(codeblock_t *block, uintptr_t func) diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index 4f7fe4f..7f93633 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -57,5 +57,6 @@ extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 3c3d6c1..bfa71d1 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -341,6 +341,15 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ +} +void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); @@ -392,6 +401,11 @@ uint8_t *host_x86_JNZ_short(codeblock_t *block) codegen_addbyte2(block, 0x75, 0); /*JNZ*/ return &block->data[block_pos-1]; } +uint8_t *host_x86_JS_short(codeblock_t *block) +{ + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block->data[block_pos-1]; +} uint8_t *host_x86_JZ_short(codeblock_t *block) { codegen_addbyte2(block, 0x74, 0); /*JZ*/ @@ -483,6 +497,20 @@ uint32_t *host_x86_JZ_long(codeblock_t *block) return (uint32_t *)&block->data[block_pos-4]; } +void host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } + else + { + fatal("host_x86_LDMXCSR - out of range %p\n", p); + } +} + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { if (offset) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 5286d2b..5c9e298 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -27,6 +27,8 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg); @@ -41,6 +43,7 @@ void host_x86_JNZ(codeblock_t *block, void *p); void host_x86_JZ(codeblock_t *block, void *p); uint8_t *host_x86_JNZ_short(codeblock_t *block); +uint8_t *host_x86_JS_short(codeblock_t *block); uint8_t *host_x86_JZ_short(codeblock_t *block); uint32_t *host_x86_JNB_long(codeblock_t *block); @@ -58,6 +61,8 @@ uint32_t *host_x86_JO_long(codeblock_t *block); uint32_t *host_x86_JS_long(codeblock_t *block); uint32_t *host_x86_JZ_long(codeblock_t *block); +void host_x86_LDMXCSR(codeblock_t *block, void *p); + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset); void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); @@ -111,6 +116,7 @@ void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 15060cf..5c54d8a 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -918,8 +918,13 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); } + else if (REG_IS_Q(src_size)) + { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_quad); + } else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); @@ -1087,6 +1092,55 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) + { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } + else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) + { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) + { + uint8_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_short(block); + + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); + + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + } + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -1517,6 +1571,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 71a5d0c..daeff4d 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -26,6 +26,7 @@ void *codegen_mem_load_double; void *codegen_mem_store_byte; void *codegen_mem_store_word; void *codegen_mem_store_long; +void *codegen_mem_store_quad; void *codegen_mem_store_single; void *codegen_mem_store_double; @@ -91,7 +92,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); else if (size == 4 && is_float) host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else if (size == 8/* && is_float*/) + else if (size == 8) host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); else fatal("build_load_routine: size=%i\n", size); @@ -124,7 +125,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); } - else if (size == 8)// && is_float) + else if (size == 8) { host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); @@ -181,7 +182,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); else if (size == 4 && is_float) host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else if (size == 8 && is_float) + else if (size == 8) host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); else fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); @@ -196,7 +197,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_PUSH(block, REG_EAX); host_x86_PUSH(block, REG_EDX); host_x86_PUSH(block, REG_ECX); - if (size == 8 && is_float) + if (size == 8) { host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 8); @@ -211,7 +212,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) else if (size == 8) host_x86_CALL(block, (void *)writememql); host_x86_POP(block, REG_EDI); - if (size == 8 && is_float) + if (size == 8) host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 8); host_x86_POP(block, REG_ECX); host_x86_POP(block, REG_EDX); @@ -242,6 +243,8 @@ static void build_loadstore_routines(codeblock_t *block) build_store_routine(block, 2, 0); codegen_mem_store_long = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); codegen_mem_store_single = &codeblock[block_current].data[block_pos]; build_store_routine(block, 4, 1); codegen_mem_store_double = &codeblock[block_current].data[block_pos]; @@ -298,12 +301,23 @@ void codegen_backend_init() build_loadstore_routines(&codeblock[block_current]); //fatal("Here\n"); + cpu_state.old_fp_control = 0; asm( "fstcw %0\n" - : "=m" (cpu_state.old_npxc) + "stmxcsr %1\n" + : "=m" (cpu_state.old_fp_control2), + "=m" (cpu_state.old_fp_control) ); } +void codegen_set_rounding_mode(int mode) +{ + /*SSE*/ + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); + /*x87 - used for double -> i64 conversions*/ + cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); +} + void codegen_backend_prologue(codeblock_t *block) { block_pos = 0; /*Entry code*/ diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index e2ca668..03b2a2e 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -35,6 +35,7 @@ extern void *codegen_mem_load_double; extern void *codegen_mem_store_byte; extern void *codegen_mem_store_word; extern void *codegen_mem_store_long; +extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 360c1a3..d68f203 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -309,14 +309,18 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ +} void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ } void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) @@ -339,6 +343,12 @@ void host_x86_JMP(codeblock_t *block, void *p) codegen_addbyte(block, 0xe9); /*JMP*/ codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); } +uint32_t *host_x86_JMP_long(codeblock_t *block) +{ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, 0); + return (uint32_t *)&block->data[block_pos-4]; +} void host_x86_JNZ(codeblock_t *block, void *p) { @@ -356,6 +366,11 @@ uint8_t *host_x86_JNZ_short(codeblock_t *block) codegen_addbyte2(block, 0x75, 0); /*JNZ*/ return &block->data[block_pos-1]; } +uint8_t *host_x86_JS_short(codeblock_t *block) +{ + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block->data[block_pos-1]; +} uint8_t *host_x86_JZ_short(codeblock_t *block) { codegen_addbyte2(block, 0x74, 0); /*JZ*/ @@ -447,6 +462,21 @@ uint32_t *host_x86_JZ_long(codeblock_t *block) return (uint32_t *)&block->data[block_pos-4]; } +void host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } + else + { + codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { if (offset) @@ -1323,7 +1353,34 @@ void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) else codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ } +void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ + else + codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ +} +void host_x87_FLDCW(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + if (offset >= -128 && offset < 127) + { + codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ + } + else + { + codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ + else + codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ +} void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) { if (base_reg == REG_ESP) diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 1ebffeb..943ba40 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -27,6 +27,7 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg); @@ -37,11 +38,14 @@ void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_JMP(codeblock_t *block, void *p); +uint32_t *host_x86_JMP_short(codeblock_t *block); +uint32_t *host_x86_JMP_long(codeblock_t *block); void host_x86_JNZ(codeblock_t *block, void *p); void host_x86_JZ(codeblock_t *block, void *p); uint8_t *host_x86_JNZ_short(codeblock_t *block); +uint8_t *host_x86_JS_short(codeblock_t *block); uint8_t *host_x86_JZ_short(codeblock_t *block); uint32_t *host_x86_JNB_long(codeblock_t *block); @@ -59,6 +63,8 @@ uint32_t *host_x86_JO_long(codeblock_t *block); uint32_t *host_x86_JS_long(codeblock_t *block); uint32_t *host_x86_JZ_long(codeblock_t *block); +void host_x86_LDMXCSR(codeblock_t *block, void *p); + void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32_t offset); void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); @@ -201,4 +207,7 @@ void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); void host_x87_FILDq_BASE(codeblock_t *block, int base_reg); +void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg); +void host_x87_FLDCW(codeblock_t *block, void *p); +void host_x87_FLDd_BASE(codeblock_t *block, int base_reg); void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index ef9496f..8537c3d 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -630,6 +630,12 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_JMP_DEST(codeblock_t *block, uop_t *uop) +{ + uop->p = host_x86_JMP_long(block); + + return 0; +} static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { @@ -872,8 +878,13 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); } + else if (REG_IS_Q(src_size)) + { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_quad); + } else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); @@ -1082,6 +1093,60 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) + { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } + else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) + { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) + { + uint8_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_short(block); + + /*There is no SSE instruction to convert a floating point value to a 64-bit integer. + Instead we have to bounce through memory via x87.*/ + host_x87_FLDCW(block, &cpu_state.new_fp_control2); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FLDd_BASE(block, REG_ESP); + host_x87_FISTPq_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + host_x87_FLDCW(block, &cpu_state.old_fp_control2); + + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + } + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -1473,6 +1538,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP_DEST & UOP_MASK] = codegen_JMP_DEST, [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, @@ -1502,12 +1568,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV & UOP_MASK] = codegen_MOV, + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_ir.c b/src/codegen_ir.c index c179632..bd0e541 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -66,7 +66,7 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) } if (!uop_handlers[uop->type & UOP_MASK]) - fatal("!uop_handlers[uop->type & UOP_MASK]\n"); + fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); uop_handlers[uop->type & UOP_MASK](block, uop); if (uop->type & UOP_TYPE_JUMP) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 036493e..d893067 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -52,6 +52,8 @@ #define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) /*UOP_CALL_FUNC - call instruction handler at p, dest_reg = return value*/ #define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) +/*UOP_JMP_DEST - jump to ptr*/ +#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_MOV_PTR - dest_reg = p*/ #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ @@ -64,6 +66,10 @@ #define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) /*UOP_MOV_DOUBLE_INT - dest_reg = (double)src_reg_a*/ #define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) +/*UOP_MOV_INT_DOUBLE - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ +#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) +/*UOP_MOV_INT_DOUBLE_64 - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ +#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ @@ -322,6 +328,17 @@ static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, in uop->imm_data = imm; } +static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->dest_reg_a = codegen_reg_write(dest_reg); +} + static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) { uop_t *uop = uop_alloc(ir); @@ -471,6 +488,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; } while (0) #define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) +#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) #define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) @@ -494,6 +512,8 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) #define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) #define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) +#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) +#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 2a4191b..4a6d0a2 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -255,17 +255,17 @@ RecompOpFn recomp_opcodes_db[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -277,17 +277,17 @@ RecompOpFn recomp_opcodes_db[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -443,19 +443,19 @@ RecompOpFn recomp_opcodes_df[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -465,19 +465,19 @@ RecompOpFn recomp_opcodes_df[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_fpu_loadstore.c b/src/codegen_ops_fpu_loadstore.c index 90682e2..8be00d2 100644 --- a/src/codegen_ops_fpu_loadstore.c +++ b/src/codegen_ops_fpu_loadstore.c @@ -148,3 +148,82 @@ uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc+1; } + +uint32_t ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + + return op_pc+1; +} +uint32_t ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(ir); + + return op_pc+1; +} +uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + + return op_pc+1; +} +uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(ir); + + return op_pc+1; +} +uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_MM(0), IREG_tag(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(ir); + + return op_pc+1; +} diff --git a/src/codegen_ops_fpu_loadstore.h b/src/codegen_ops_fpu_loadstore.h index 58d4121..b206f96 100644 --- a/src/codegen_ops_fpu_loadstore.h +++ b/src/codegen_ops_fpu_loadstore.h @@ -9,3 +9,9 @@ uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 2830d40..ad890ae 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -165,6 +165,7 @@ enum #define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) #define IREG_MM(r) (IREG_MM0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) #define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) +#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) #define IREG_TOP_diff_stack_offset 32 diff --git a/src/ibm.h b/src/ibm.h index 6503b67..c829b51 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -177,8 +177,10 @@ struct MMX_REG MM[8]; - uint16_t old_npxc, new_npxc; - + uint32_t old_fp_control, new_fp_control; +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ + uint16_t old_fp_control2, new_fp_control2; +#endif x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; union diff --git a/src/x87.h b/src/x87.h index cd4ccbb..3960efa 100644 --- a/src/x87.h +++ b/src/x87.h @@ -24,3 +24,9 @@ void x87_reset(); /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ #define TAG_UINT64 (1 << 7) +#define X87_ROUNDING_NEAREST 0 +#define X87_ROUNDING_DOWN 1 +#define X87_ROUNDING_UP 2 +#define X87_ROUNDING_CHOP 3 + +void codegen_set_rounding_mode(int mode); diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index eb9fffb..4354cb2 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -32,7 +32,7 @@ static int opFINIT(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); cpu_state.npxs = 0; *(uint64_t *)cpu_state.tag = 0; cpu_state.TOP = 0; @@ -86,7 +86,7 @@ static int FSTOR() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -95,7 +95,7 @@ static int FSTOR() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -276,7 +276,7 @@ static int FSAVE() } cpu_state.npxc = 0x37F; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); cpu_state.npxs = 0; *(uint64_t *)cpu_state.tag = 0; cpu_state.TOP = 0; @@ -682,7 +682,7 @@ static int FLDENV() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -690,7 +690,7 @@ static int FLDENV() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -727,7 +727,7 @@ static int opFLDCW_a16(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); CLOCK_CYCLES(4); return 0; } @@ -741,7 +741,7 @@ static int opFLDCW_a32(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); CLOCK_CYCLES(4); return 0; } From b814bcc80dd272fd86bff0cc8426c443fcd8e20d Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 Oct 2018 21:43:32 +0100 Subject: [PATCH 0521/1050] Added recompiled versions of FSTCW and FSTSW. --- src/codegen_ops.c | 29 +++++----- src/codegen_ops_fpu_misc.c | 111 +++++++++++++++++++++++++++++++++++++ src/codegen_ops_fpu_misc.h | 12 ++++ src/codegen_reg.c | 3 + src/codegen_reg.h | 10 +++- 5 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 src/codegen_ops_fpu_misc.c create mode 100644 src/codegen_ops_fpu_misc.h diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 4a6d0a2..a36bd40 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -5,6 +5,7 @@ #include "codegen_ops_arith.h" #include "codegen_ops_branch.h" #include "codegen_ops_fpu_arith.h" +#include "codegen_ops_fpu_constant.h" #include "codegen_ops_fpu_loadstore.h" #include "codegen_ops_fpu_misc.h" #include "codegen_ops_jump.h" @@ -163,17 +164,17 @@ RecompOpFn recomp_opcodes_d9[512] = /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, @@ -185,17 +186,17 @@ RecompOpFn recomp_opcodes_d9[512] = /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, @@ -351,17 +352,17 @@ RecompOpFn recomp_opcodes_dd[512] = /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, /*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, /*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, /*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, @@ -373,17 +374,17 @@ RecompOpFn recomp_opcodes_dd[512] = /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, /*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, /*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, /*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, @@ -459,7 +460,7 @@ RecompOpFn recomp_opcodes_df[512] = /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ @@ -481,6 +482,6 @@ RecompOpFn recomp_opcodes_df[512] = /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; diff --git a/src/codegen_ops_fpu_misc.c b/src/codegen_ops_fpu_misc.c new file mode 100644 index 0000000..2509cc7 --- /dev/null +++ b/src/codegen_ops_fpu_misc.c @@ -0,0 +1,111 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "x87.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_fpu_misc.h" +#include "codegen_ops_helpers.h" + +uint32_t ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); + + return op_pc; +} + +uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); + uop_MOV(ir, IREG_MM(-1), IREG_MM(src_reg)); + uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); + fpu_PUSH(ir); + + return op_pc; +} + +uint32_t ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + + return op_pc; +} +uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + fpu_POP(ir); + + return op_pc; +} + +uint32_t ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); + + return op_pc; +} +uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); + + return op_pc; +} +uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_AX, IREG_NPXS); + + return op_pc; +} + +uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); + uop_MOV(ir, IREG_temp1_Q, IREG_MM(0)); + uop_MOV(ir, IREG_temp2, IREG_tag(0)); + uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV(ir, IREG_MM(0), IREG_MM(dest_reg)); + uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); + uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); + uop_MOV(ir, IREG_MM(dest_reg), IREG_temp1_Q); + uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); + + return op_pc; +} diff --git a/src/codegen_ops_fpu_misc.h b/src/codegen_ops_fpu_misc.h new file mode 100644 index 0000000..257aa7a --- /dev/null +++ b/src/codegen_ops_fpu_misc.h @@ -0,0 +1,12 @@ +uint32_t ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index ac1e417..2e76874 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -123,6 +123,9 @@ struct [IREG_MM6] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, [IREG_MM7] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER}, + [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ diff --git a/src/codegen_reg.h b/src/codegen_reg.h index ad890ae..3bb69b2 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -103,8 +103,11 @@ enum IREG_MM5 = 61, IREG_MM6 = 62, IREG_MM7 = 63, + + IREG_NPXCx = 64, + IREG_NPXSx = 65, - IREG_COUNT = 64, + IREG_COUNT = 66, IREG_INVALID = 255, @@ -155,7 +158,10 @@ enum IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, - IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W + IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, + + IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, + IREG_NPXS = IREG_NPXSx + IREG_SIZE_W }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) From 8dc7b2ef36899185ac712d79f7785395608903b7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Nov 2018 20:16:32 +0000 Subject: [PATCH 0522/1050] SCAT chipset improvements : - Implemented ROMCS enable feature. - Fixed RAM write protect register setting wasn't properly applied. - Implemented Encoded RAS mode emulation on 82C235 revision A and 82C386 chipset. - Implemented of experimental memory bank interleaved addressing emulation on 82C836 chipset and removed hardcoded memory configuration setting. KMX-C-02's BIOS now automatically detects DRAM configuration and set DRAM configuration register value correctly. - Improved accuracy of 82C235 chipset's memory bank addressing. GW-286CT GEAR BIOS now set DRAM configuration register correctly when Dynamic Memory Resizing is enabled. - Changed Award286 clone and Samsung SPC-4200P's chipset revision to rev A. - SCAT revision D chipset now set high ROM mapping size to 128KB. Patch from Greatpsycho --- src/scat.c | 1186 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 1029 insertions(+), 157 deletions(-) diff --git a/src/scat.c b/src/scat.c index 966814f..eb1a953 100644 --- a/src/scat.c +++ b/src/scat.c @@ -11,47 +11,76 @@ 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_low_mapping[32]; +static mem_mapping_t scat_ems_mapping[32]; static mem_mapping_t scat_high_mapping[16]; static scat_t scat_stat[32]; static uint32_t scat_xms_bound; -static mem_mapping_t scat_shadowram_mapping[6]; -static mem_mapping_t scat_4000_9FFF_mapping[24]; -static mem_mapping_t scat_A000_BFFF_mapping; +static mem_mapping_t scat_remap_mapping[6]; +static mem_mapping_t scat_4000_EFFF_mapping[44]; +static mem_mapping_t scat_low_ROMCS_mapping[8]; -// TODO - 82C836 chipset's memory address mapping isn't fully implemented yet, so memory configuration is hardcoded now. -static int scatsx_mem_conf_val[33] = { 0x00, 0x01, 0x03, 0x04, 0x05, 0x08, 0x06, 0x06, - 0x0c, 0x09, 0x07, 0x07, 0x0d, 0x0a, 0x0f, 0x0f, - 0x0e, 0x0e, 0x10, 0x10, 0x13, 0x13, 0x11, 0x11, - 0x14, 0x14, 0x12, 0x12, 0x15, 0x15, 0x15, 0x15, - 0x16 }; +static int scat_max_map[32] = { 0, 1, 1, 1, 2, 3, 4, 8, + 4, 8, 12, 16, 20, 24, 28, 32, + 0, 5, 9, 13, 6, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; +static int scatsx_max_map[32] = { 0, 1, 2, 1, 3, 4, 6, 10, + 5, 9, 13, 4, 8, 12, 16, 14, + 18, 22, 26, 20, 24, 28, 32, 18, + 20, 32, 0, 0, 0, 0, 0, 0 }; + +static int external_is_RAS = 0; + +static int scatsx_external_is_RAS[33] = { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0 }; uint8_t scat_read(uint16_t port, void *priv); void scat_write(uint16_t port, uint8_t val, void *priv); +void scat_romcs_state_update(uint8_t val) +{ + int i; + for(i = 0; i < 4; i++) + { + if (val & 1) + { + mem_mapping_enable(&scat_low_ROMCS_mapping[i << 1]); + mem_mapping_enable(&scat_low_ROMCS_mapping[(i << 1) + 1]); + } + else + { + mem_mapping_disable(&scat_low_ROMCS_mapping[i << 1]); + mem_mapping_disable(&scat_low_ROMCS_mapping[(i << 1) + 1]); + } + val >>= 1; + } + + for(i = 0; i < 4; i++) + { + if (val & 1) + { + mem_mapping_enable(&bios_mapping[i << 1]); + mem_mapping_enable(&bios_mapping[(i << 1) + 1]); + } + else + { + mem_mapping_disable(&bios_mapping[i << 1]); + mem_mapping_disable(&bios_mapping[(i << 1) + 1]); + } + val >>= 1; + } +} + void scat_shadow_state_update() { int i, val; - // TODO - ROMCS enable features should be implemented later. 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 (i < 8) - { - val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; - } - else - { - if ((scat_regs[SCAT_RAM_WRITE_PROTECT] >> ((i - 8) >> 1)) & 1) - { - val |= MEM_WRITE_DISABLED; - } - else - { - val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; - } - } + val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL | MEM_WRITE_INTERNAL : MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; mem_set_mem_state((i + 40) << 14, 0x4000, val); } @@ -60,8 +89,7 @@ void scat_shadow_state_update() void scat_set_xms_bound(uint8_t val) { - uint32_t max_xms_size = (mem_size >= 16128) ? (((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) ? 0xFE0000 : 0xFC0000) : mem_size << 10; - int i; + uint32_t max_xms_size = ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) || (scat_regs[SCAT_VERSION] >= 4) ? 0xFE0000 : 0xFC0000; switch (val & 0x0F) { @@ -117,21 +145,9 @@ void scat_set_xms_bound(uint8_t val) if ((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) { - if (val != 1) - { - if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); - for(i=0;i<6;i++) - mem_mapping_enable(&scat_shadowram_mapping[i]); - if ((val & 0x0F) == 0) - scat_xms_bound = 0x160000; - } - else - { - for(i=0;i<6;i++) - mem_mapping_disable(&scat_shadowram_mapping[i]); - if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); - } - pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); + if((val & 0x0F) == 0 || scat_xms_bound > 0x160000) + scat_xms_bound = 0x160000; +// pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); if (scat_xms_bound < 0x160000) @@ -139,68 +155,721 @@ void scat_set_xms_bound(uint8_t val) } else { - for(i=0;i<6;i++) - mem_mapping_disable(&scat_shadowram_mapping[i]); - if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); - if (scat_xms_bound > max_xms_size) scat_xms_bound = max_xms_size; - pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); +// pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); if (scat_xms_bound > 0x100000) mem_set_mem_state(0x100000, scat_xms_bound - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); if (scat_xms_bound < (mem_size << 10)) mem_set_mem_state(scat_xms_bound, (mem_size << 10) - scat_xms_bound, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } + + mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && ((val & 0x10) != 0)) || (scat_regs[SCAT_VERSION] >= 4) ? 0x60000 : 0x40000); + if(scat_regs[SCAT_VERSION] & 0xF0) + { + int i; + for(i=0;i<8;i++) + { + if(val & 0x10) + mem_mapping_disable(&scat_high_mapping[i]); + else + mem_mapping_enable(&scat_high_mapping[i]); + } + } } uint32_t get_scat_addr(uint32_t addr, scat_t *p) { + int nbank; + if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - if (mem_size < 2048 && ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 7 || (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) != 0)) - addr = (addr & ~0x780000) | ((addr & 0x600000) >> 2); - else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) + switch((scat_regs[SCAT_EXTENDED_BOUNDARY] & ((scat_regs[SCAT_VERSION] & 0x0F) > 3 ? 0x40 : 0)) | (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F)) { - addr &= ~0x600000; - if(mem_size > 2048 || (mem_size == 2048 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 6)) - addr |= (addr & 0x180000) << 2; + case 0x41: + nbank = addr >> 19; + if(nbank < 4) + nbank = 1; + else if(nbank == 4) + nbank = 0; + else + nbank -= 3; + break; + case 0x42: + nbank = addr >> 19; + if(nbank < 8) + nbank = 1 + (nbank >> 2); + else if(nbank == 8) + nbank = 0; + else + nbank -= 6; + break; + case 0x43: + nbank = addr >> 19; + if(nbank < 12) + nbank = 1 + (nbank >> 2); + else if(nbank == 12) + nbank = 0; + else + nbank -= 9; + break; + case 0x44: + nbank = addr >> 19; + if(nbank < 4) + nbank = 2; + else if(nbank < 6) + nbank -= 4; + else + nbank -= 3; + break; + case 0x45: + nbank = addr >> 19; + if(nbank < 8) + nbank = 2 + (nbank >> 2); + else if(nbank < 10) + nbank -= 8; + else + nbank -= 6; + break; + default: + nbank = addr >> (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8 && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) ? 19 : 21); + break; + } + nbank &= (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; + if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && nbank == 2 && (addr & 0x7FFFF) < 0x60000 && mem_size > 640) + { + nbank = 1; + addr ^= 0x70000; } - if ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) - addr ^= mem_size < 2048 ? 0x1F0000 : 0x670000; + if(external_is_RAS && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) + { + if(nbank == 3) + nbank = 7; + else + return 0xFFFFFFFF; + } + else if(!external_is_RAS && scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) + { + switch(nbank) + { + case 7: + nbank = 3; + break; + // Note - In the following cases, the chipset accesses multiple memory banks at the same time, so it's impossible to predict which memory bank is actually accessed. + case 5: + case 1: + nbank = 1; + break; + case 3: + nbank = 2; + break; + default: + nbank = 0; + break; + } + } + + if((scat_regs[SCAT_VERSION] & 0x0F) > 3 && (mem_size > 2048) && (mem_size & 1536)) + { + if((mem_size & 1536) == 512) + { + if(nbank == 0) + addr &= 0x7FFFF; + else + addr = 0x80000 + ((addr & 0x1FFFFF) | ((nbank - 1) << 21)); + } + else + { + if(nbank < 2) + addr = (addr & 0x7FFFF) | (nbank << 19); + else + addr = 0x100000 + ((addr & 0x1FFFFF) | ((nbank - 2) << 21)); + } + } + else + { + int nbanks_2048k, nbanks_512k; + if (mem_size <= ((scat_regs[SCAT_VERSION] & 0x0F) > 3 ? 2048 : 4096) && (((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) < 8) || external_is_RAS)) + { + nbanks_2048k = 0; + nbanks_512k = mem_size >> 9; + } + else + { + nbanks_2048k = mem_size >> 11; + nbanks_512k = (mem_size & 1536) >> 9; + } + if(nbank < nbanks_2048k || (nbanks_2048k > 0 && nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7))) + { + addr &= 0x1FFFFF; + addr |= (nbank << 21); + } + else if(nbank < nbanks_2048k + nbanks_512k || nbank >= nbanks_2048k + nbanks_512k + ((mem_size & 511) >> 7)) + { + addr &= 0x7FFFF; + addr |= (nbanks_2048k << 21) | ((nbank - nbanks_2048k) << 19); + } + else + { + addr &= 0x1FFFF; + addr |= (nbanks_2048k << 21) | (nbanks_512k << 19) | ((nbank - nbanks_2048k - nbanks_512k) << 17); + } + } } else { - if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3 && (addr & ~0x600000) >= 0x100000 && (addr & ~0x600000) < 0x160000) - addr ^= 0x1F0000; + uint32_t addr2; + switch(scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) + { + case 2: + case 4: + nbank = addr >> 19; + if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else + addr2 = addr >> 10; + break; + case 3: + nbank = addr >> 19; + if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) == 2 && (addr & 0x7FFFF) < 0x60000) + { + addr ^= 0x1F0000; + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else + addr2 = addr >> 10; + break; + case 5: + nbank = addr >> 19; + if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) + { + nbank = (addr >> 10) & 3; + addr2 = addr >> 12; + } + else + addr2 = addr >> 10; + break; + case 6: + nbank = addr >> 19; + if(nbank < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else + { + nbank = 2 + ((addr - 0x100000) >> 21); + addr2 = (addr - 0x100000) >> 11; + } + break; + case 7: + case 0x0F: + nbank = addr >> 19; + if(nbank < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else if(nbank < 10) + { + nbank = 2 + (((addr - 0x100000) >> 11) & 1); + addr2 = (addr - 0x100000) >> 12; + } + else + { + nbank = 4 + ((addr - 0x500000) >> 21); + addr2 = (addr - 0x500000) >> 11; + } + break; + case 8: + nbank = addr >> 19; + if(nbank < 4) + { + nbank = 1; + addr2 = addr >> 11; + } + else if(nbank == 4) + { + nbank = 0; + addr2 = addr >> 10; + } + else + { + nbank -= 3; + addr2 = addr >> 10; + } + break; + case 9: + nbank = addr >> 19; + if(nbank < 8) + { + nbank = 1 + ((addr >> 11) & 1); + addr2 = addr >> 12; + } + else if(nbank == 8) + { + nbank = 0; + addr2 = addr >> 10; + } + else + { + nbank -= 6; + addr2 = addr >> 10; + } + break; + case 0x0A: + nbank = addr >> 19; + if(nbank < 8) + { + nbank = 1 + ((addr >> 11) & 1); + addr2 = addr >> 12; + } + else if(nbank < 12) + { + nbank = 3; + addr2 = addr >> 11; + } + else if(nbank == 12) + { + nbank = 0; + addr2 = addr >> 10; + } + else + { + nbank -= 9; + addr2 = addr >> 10; + } + break; + case 0x0B: + nbank = addr >> 21; + addr2 = addr >> 11; + break; + case 0x0C: + case 0x0D: + nbank = addr >> 21; + if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 2) + { + nbank = (addr >> 11) & 1; + addr2 = addr >> 12; + } + else + addr2 = addr >> 11; + break; + case 0x0E: + case 0x13: + nbank = addr >> 21; + if((nbank & (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80 ? 7 : 3)) < 4) + { + nbank = (addr >> 11) & 3; + addr2 = addr >> 13; + } + else + addr2 = addr >> 11; + break; + case 0x10: + case 0x11: + nbank = addr >> 19; + if(nbank < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else if(nbank < 10) + { + nbank = 2 + (((addr - 0x100000) >> 11) & 1); + addr2 = (addr - 0x100000) >> 12; + } + else if(nbank < 18) + { + nbank = 4 + (((addr - 0x500000) >> 11) & 1); + addr2 = (addr - 0x500000) >> 12; + } + else + { + nbank = 6 + ((addr - 0x900000) >> 21); + addr2 = (addr - 0x900000) >> 11; + } + break; + case 0x12: + nbank = addr >> 19; + if(nbank < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else if(nbank < 10) + { + nbank = 2 + (((addr - 0x100000) >> 11) & 1); + addr2 = (addr - 0x100000) >> 12; + } + else + { + nbank = 4 + (((addr - 0x500000) >> 11) & 3); + addr2 = (addr - 0x500000) >> 13; + } + break; + case 0x14: + case 0x15: + nbank = addr >> 21; + if((nbank & 7) < 4) + { + nbank = (addr >> 11) & 3; + addr2 = addr >> 13; + } + else if((nbank & 7) < 6) + { + nbank = 4 + (((addr - 0x800000) >> 11) & 1); + addr2 = (addr - 0x800000) >> 12; + } + else + { + nbank = 6 + (((addr - 0xC00000) >> 11) & 3); + addr2 = (addr - 0xC00000) >> 13; + } + break; + case 0x16: + nbank = ((addr >> 21) & 4) | ((addr >> 11) & 3); + addr2 = addr >> 13; + break; + case 0x17: + if(external_is_RAS && (addr & 0x800) == 0) + return 0xFFFFFFFF; + nbank = addr >> 19; + if(nbank < 2) + { + nbank = (addr >> 10) & 1; + addr2 = addr >> 11; + } + else + { + nbank = 2 + ((addr - 0x100000) >> 23); + addr2 = (addr - 0x100000) >> 12; + } + break; + case 0x18: + if(external_is_RAS && (addr & 0x800) == 0) + return 0xFFFFFFFF; + nbank = addr >> 21; + if(nbank < 4) + { + nbank = 1; + addr2 = addr >> 12; + } + else if(nbank == 4) + { + nbank = 0; + addr2 = addr >> 11; + } + else + { + nbank -= 3; + addr2 = addr >> 11; + } + break; + case 0x19: + if(external_is_RAS && (addr & 0x800) == 0) + return 0xFFFFFFFF; + nbank = addr >> 23; + if((nbank & 3) < 2) + { + nbank = (addr >> 12) & 1; + addr2 = addr >> 13; + } + else + addr2 = addr >> 12; + break; + default: + if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 6) + { + nbank = addr >> 19; + addr2 = (addr >> 10) & 0x1FF; + } + else if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 0x17) + { + nbank = addr >> 21; + addr2 = (addr >> 11) & 0x3FF; + } + else + { + nbank = addr >> 23; + addr2 = (addr >> 12) & 0x7FF; + } + break; + } + + nbank &= (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) ? 7 : 3; + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) > 0x16 && nbank == 3) + return 0xFFFFFFFF; + + if(external_is_RAS && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) == 0) + { + if(nbank == 3) + nbank = 7; + else + return 0xFFFFFFFF; + } + else if(!external_is_RAS && scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x80) + { + switch(nbank) + { + case 7: + nbank = 3; + break; + // Note - In the following cases, the chipset accesses multiple memory banks at the same time, so it's impossible to predict which memory bank is actually accessed. + case 5: + case 1: + nbank = 1; + break; + case 3: + nbank = 2; + break; + default: + nbank = 0; + break; + } + } + + switch(mem_size & ~511) + { + case 1024: + case 1536: + addr &= 0x3FF; + if(nbank < 2) + addr |= (nbank << 10) | ((addr2 & 0x1FF) << 11); + else + addr |= ((addr2 & 0x1FF) << 10) | (nbank << 19); + break; + case 2048: + if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 5) + { + addr &= 0x3FF; + if(nbank < 4) + addr |= (nbank << 10) | ((addr2 & 0x1FF) << 12); + else + addr |= ((addr2 & 0x1FF) << 10) | (nbank << 19); + } + else + { + addr &= 0x7FF; + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + } + break; + case 2560: + if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else + { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); + } + break; + case 3072: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + break; + case 4096: + case 6144: + addr &= 0x7FF; + if(nbank < 2) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 12); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + break; + case 4608: + if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) >= 8 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) <= 0x0A) || ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 0x18)) + { + if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else if(nbank < 3) + addr = 0x80000 + ((addr & 0x7FF) | ((nbank - 1) << 11) | ((addr2 & 0x3FF) << 12)); + else + addr = 0x480000 + ((addr & 0x3FF) | ((addr2 & 0x1FF) << 10) | ((nbank - 3) << 19)); + } + else if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else + { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x80000 + ((addr2 << 11) | ((nbank - 1) << 21)); + } + break; + case 5120: + case 7168: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(nbank < 4) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + break; + case 6656: + if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) >= 8 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) <= 0x0A) || ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 0x18)) + { + if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else if(nbank < 3) + addr = 0x80000 + ((addr & 0x7FF) | ((nbank - 1) << 11) | ((addr2 & 0x3FF) << 12)); + else if(nbank == 3) + addr = 0x480000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11)); + else + addr = 0x680000 + ((addr & 0x3FF) | ((addr2 & 0x1FF) << 10) | ((nbank - 4) << 19)); + } + else if(nbank == 0) + addr = (addr & 0x3FF) | ((addr2 & 0x1FF) << 10); + else if(nbank == 1) + { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x80000 + (addr2 << 11); + } + else + { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr = addr + 0x280000 + ((addr2 << 12) | ((nbank & 1) << 11) | (((nbank - 2) & 6) << 21)); + } + break; + case 8192: + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + break; + case 9216: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(external_is_RAS) + { + if(nbank < 6) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + } + else + addr = 0x100000 + ((addr & 0xFFF) | ((addr2 & 0x7FF) << 12) | ((nbank - 2) << 23)); + break; + case 10240: + if(external_is_RAS) + { + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + } + else if(nbank == 0) + addr = (addr & 0x7FF) | ((addr2 & 0x3FF) << 11); + else + { + addr &= 0xFFF; + addr2 &= 0x7FF; + addr = addr + 0x200000 + ((addr2 << 12) | ((nbank - 1) << 23)); + } + break; + case 11264: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(nbank < 6) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 11) | ((nbank - 2) << 21)); + break; + case 12288: + if(external_is_RAS) + { + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else if(nbank < 6) + addr |= ((nbank & 1) << 11) | ((addr2 & 0x3FF) << 12) | ((nbank & 4) << 21); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + } + else + { + if(nbank < 2) + addr = (addr & 0x7FF) | (nbank << 11) | ((addr2 & 0x3FF) << 12); + else + addr = 0x400000 + ((addr & 0xFFF) | ((addr2 & 0x7FF) << 12) | ((nbank - 2) << 23)); + } + break; + case 13312: + if(nbank < 2) + addr = (addr & 0x3FF) | (nbank << 10) | ((addr2 & 0x1FF) << 11); + else if(nbank < 4) + addr = 0x100000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 12) | ((nbank & 1) << 11)); + else + addr = 0x500000 + ((addr & 0x7FF) | ((addr2 & 0x3FF) << 13) | ((nbank & 3) << 11)); + break; + case 14336: + addr &= 0x7FF; + if(nbank < 4) + addr |= (nbank << 11) | ((addr2 & 0x3FF) << 13); + else if(nbank < 6) + addr |= ((nbank & 1) << 11) | ((addr2 & 0x3FF) << 12) | ((nbank & 4) << 21); + else + addr |= ((addr2 & 0x3FF) << 11) | (nbank << 21); + break; + case 16384: + if(external_is_RAS) + { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr |= ((nbank & 3) << 11) | (addr2 << 13) | ((nbank & 4) << 21); + } + else + { + addr &= 0xFFF; + addr2 &= 0x7FF; + if(nbank < 2) + addr |= (addr2 << 13) | (nbank << 12); + else + addr |= (addr2 << 12) | (nbank << 23); + } + break; + default: + if(mem_size < 2048 || ((mem_size & 1536) == 512) || (mem_size == 2048 && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 6)) + { + addr &= 0x3FF; + addr2 &= 0x1FF; + addr |= (addr2 << 10) | (nbank << 19); + } + else if(mem_size < 8192 || (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 0x17) + { + addr &= 0x7FF; + addr2 &= 0x3FF; + addr |= (addr2 << 11) | (nbank << 21); + } + else + { + addr &= 0xFFF; + addr2 &= 0x7FF; + addr |= (addr2 << 12) | (nbank << 23); + } + break; + } } return addr; } -void scat_memmap_state_update() -{ - int i; - uint32_t addr; - - for(i=16;i<24;i++) - { - addr = get_scat_addr(0x40000 + (i << 14), NULL); - mem_mapping_set_exec(&scat_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); - } - addr = get_scat_addr(0xA0000, NULL); - mem_mapping_set_exec(&scat_A000_BFFF_mapping, addr < (mem_size << 10) ? ram + addr : NULL); - for(i=0;i<6;i++) - { - addr = get_scat_addr(0x100000 + (i << 16), NULL); - mem_mapping_set_exec(&scat_shadowram_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); - } - - flushmmucache(); -} - void scat_set_global_EMS_state(int state) { int i; @@ -214,21 +883,118 @@ void scat_set_global_EMS_state(int state) if(state && (scat_stat[i].regs_2x9 & 0x80)) { virt_addr = get_scat_addr(base_addr, &scat_stat[i]); - if(i < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[i]); - mem_mapping_enable(&scat_mapping[i]); - if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[i], ram + virt_addr); - else mem_mapping_set_exec(&scat_mapping[i], NULL); + if(i < 24) mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + else mem_mapping_disable(&scat_4000_EFFF_mapping[i + 12]); + mem_mapping_enable(&scat_ems_mapping[i]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[i], ram + virt_addr); + else mem_mapping_set_exec(&scat_ems_mapping[i], NULL); } else { - mem_mapping_set_exec(&scat_mapping[i], ram + base_addr); - mem_mapping_disable(&scat_mapping[i]); - if(i < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + mem_mapping_set_exec(&scat_ems_mapping[i], ram + base_addr); + mem_mapping_disable(&scat_ems_mapping[i]); + + int conf = (scat_regs[SCAT_VERSION] & 0xF0) ? (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) : (scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2); + if(i < 24) + { + if(conf > 1 || (conf == 1 && i < 16)) + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + else + mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + } + else if(conf > 3 || ((scat_regs[SCAT_VERSION] & 0xF0) != 0 && conf == 2)) + mem_mapping_enable(&scat_4000_EFFF_mapping[i + 12]); + else + mem_mapping_disable(&scat_4000_EFFF_mapping[i + 12]); } } flushmmucache(); } +void scat_memmap_state_update() +{ + int i; + uint32_t addr; + + for(i=(((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? 0 : 16);i<44;i++) + { + addr = get_scat_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&scat_4000_EFFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); +// pclog("scat_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); + } + addr = get_scat_addr(0, NULL); +// pclog("scat_memmap_state_update : Address 000000 to %06X\n", addr); + mem_mapping_set_exec(&scat_low_mapping[0], addr < (mem_size << 10) ? ram + addr : NULL); + addr = get_scat_addr(0xF0000, NULL); +// pclog("scat_memmap_state_update : Address 0F0000 to %06X\n", addr); + mem_mapping_set_exec(&scat_low_mapping[1], addr < (mem_size << 10) ? ram + addr : NULL); + for(i=2;i<32;i++) + { + addr = get_scat_addr(i << 19, NULL); + mem_mapping_set_exec(&scat_low_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); +// pclog("scat_memmap_state_update : Address %06X to %06X\n", i << 19, addr); + } + + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) + { + for(i=0;i < scat_max_map[(scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | ((scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) >> 2)];i++) + mem_mapping_enable(&scat_low_mapping[i]); + for(;i<32;i++) mem_mapping_disable(&scat_low_mapping[i]); + + for(i=24;i<36;i++) + { + if(((scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) | (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40)) < 4) + mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + else + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + } + } + else + { + for(i=0;i < scatsx_max_map[scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F];i++) + mem_mapping_enable(&scat_low_mapping[i]); + for(;i<32;i++) mem_mapping_disable(&scat_low_mapping[i]); + + for(i=24;i<36;i++) + { + if((scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) < 2 || (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3) + mem_mapping_disable(&scat_4000_EFFF_mapping[i]); + else + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + } + } + + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((scat_regs[SCAT_VERSION] & 0xF0) != 0)) + { + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) == 3)) + { + mem_mapping_disable(&scat_low_mapping[2]); + for(i=0;i<6;i++) + { + addr = get_scat_addr(0x100000 + (i << 16), NULL); + mem_mapping_set_exec(&scat_remap_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + mem_mapping_enable(&scat_remap_mapping[i]); +// pclog("scat_memmap_state_update : Address %06X to %06X\n", 0x100000 + (i << 16), addr); + } + } + else + { + for(i=0;i<6;i++) + mem_mapping_disable(&scat_remap_mapping[i]); + if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x0F) > 4) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (scat_regs[SCAT_DRAM_CONFIGURATION] & 0x1F) > 3)) + mem_mapping_enable(&scat_low_mapping[2]); + } + } + else + { + for(i=0;i<6;i++) + mem_mapping_disable(&scat_remap_mapping[i]); + mem_mapping_enable(&scat_low_mapping[2]); + } + + scat_set_global_EMS_state(scat_regs[SCAT_EMS_CONTROL] & 0x80); +} + void scat_write(uint16_t port, uint8_t val, void *priv) { uint8_t scat_reg_valid = 0, scat_shadow_update = 0, scat_map_update = 0, index; @@ -276,27 +1042,6 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: - if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (scat_regs[SCAT_EXTENDED_BOUNDARY] & 0x40) == 0) || ((scat_regs[SCAT_VERSION] & 0xF0) != 0)) - { - if((((scat_regs[SCAT_VERSION] & 0xF0) == 0) && (val & 0x0F) == 3) || (((scat_regs[SCAT_VERSION] & 0xF0) != 0) && (val & 0x1F) == 3)) - { - if(mem_size > 1024) mem_mapping_disable(&ram_high_mapping); - for(index=0;index<6;index++) - mem_mapping_enable(&scat_shadowram_mapping[index]); - } - else - { - for(index=0;index<6;index++) - mem_mapping_disable(&scat_shadowram_mapping[index]); - if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); - } - } - else - { - for(index=0;index<6;index++) - mem_mapping_disable(&scat_shadowram_mapping[index]); - if(mem_size > 1024) mem_mapping_enable(&ram_high_mapping); - } scat_map_update = 1; if((scat_regs[SCAT_VERSION] & 0xF0) == 0) @@ -304,22 +1049,37 @@ void scat_write(uint16_t port, uint8_t val, void *priv) cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; cpu_update_waitstates(); } - else - { - if(mem_size != 1024 || ((val & 0x1F) != 2 && (val & 0x1F) != 3)) - val = (val & 0xe0) | scatsx_mem_conf_val[mem_size >> 9]; - } scat_reg_valid = 1; break; case SCAT_EXTENDED_BOUNDARY: - scat_set_xms_bound(val & ((scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x4f : 0x1f)); + if((scat_regs[SCAT_VERSION] & 0xF0) == 0) + { + if(scat_regs[SCAT_VERSION] < 4) + { + val &= 0xBF; + scat_set_xms_bound(val & 0x0f); + } + else + { + val = (val & 0x7F) | 0x80; + scat_set_xms_bound(val & 0x4f); + } + } + else + scat_set_xms_bound(val & 0x1f); mem_set_mem_state(0x40000, 0x60000, (val & 0x20) ? MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL : MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0x40) scat_map_update = 1; + if((val ^ scat_regs[SCAT_EXTENDED_BOUNDARY]) & 0xC0) scat_map_update = 1; scat_reg_valid = 1; break; case SCAT_ROM_ENABLE: + scat_reg_valid = 1; + scat_romcs_state_update(val); + break; case SCAT_RAM_WRITE_PROTECT: + scat_reg_valid = 1; + flushmmucache_cr3(); + break; case SCAT_SHADOW_RAM_ENABLE_1: case SCAT_SHADOW_RAM_ENABLE_2: case SCAT_SHADOW_RAM_ENABLE_3: @@ -344,7 +1104,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } if (scat_reg_valid) scat_regs[scat_index] = val; - else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); + else pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.oldpc); if (scat_shadow_update) scat_shadow_state_update(); if (scat_map_update) @@ -381,8 +1141,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if((scat_regs[SCAT_EMS_CONTROL] & 0x80) && (scat_stat[index].regs_2x9 & 0x80)) { virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - else mem_mapping_set_exec(&scat_mapping[index], NULL); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_ems_mapping[index], NULL); flushmmucache(); } } @@ -404,18 +1164,20 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if (val & 0x80) { virt_addr = get_scat_addr(base_addr, &scat_stat[index]); - if(index < 24) mem_mapping_disable(&scat_4000_9FFF_mapping[index]); - if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_mapping[index], ram + virt_addr); - else mem_mapping_set_exec(&scat_mapping[index], NULL); - mem_mapping_enable(&scat_mapping[index]); -// pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + if(index < 24) mem_mapping_disable(&scat_4000_EFFF_mapping[index]); + else mem_mapping_disable(&scat_4000_EFFF_mapping[index + 12]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&scat_ems_mapping[index], ram + virt_addr); + else mem_mapping_set_exec(&scat_ems_mapping[index], NULL); + mem_mapping_enable(&scat_ems_mapping[index]); +// pclog("Map page %d(address %05X) to address %06X\n", index, base_addr, virt_addr); } else { - mem_mapping_set_exec(&scat_mapping[index], ram + base_addr); - mem_mapping_disable(&scat_mapping[index]); - if(index < 24) mem_mapping_enable(&scat_4000_9FFF_mapping[index]); -// pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); + mem_mapping_set_exec(&scat_ems_mapping[index], ram + base_addr); + mem_mapping_disable(&scat_ems_mapping[index]); + if(index < 24) mem_mapping_enable(&scat_4000_EFFF_mapping[index]); + else mem_mapping_enable(&scat_4000_EFFF_mapping[index + 12]); +// pclog("Unmap page %d(address %06X)\n", index, base_addr); } flushmmucache(); } @@ -450,9 +1212,18 @@ uint8_t scat_read(uint16_t port, void *priv) break; case SCAT_DRAM_CONFIGURATION: if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); - else if(mem_size != 1024) val = (scat_regs[scat_index] & 0xe0) | scatsx_mem_conf_val[mem_size >> 9]; else val = scat_regs[scat_index]; break; + case SCAT_EXTENDED_BOUNDARY: + val = scat_regs[scat_index]; + if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) + { + if((scat_regs[SCAT_VERSION] & 0x0F) >= 4) + val |= 0x80; + else + val &= 0xAF; + } + break; default: val = scat_regs[scat_index]; break; @@ -496,25 +1267,89 @@ uint8_t scat_read(uint16_t port, void *priv) return val; } -uint8_t mem_read_scatems(uint32_t addr, void *priv) +uint8_t mem_read_scatb(uint32_t addr, void *priv) { uint8_t val = 0xff; scat_t *stat = (scat_t *)priv; addr = get_scat_addr(addr, stat); if (addr < (mem_size << 10)) - val = mem_read_ram(addr, priv); + val = ram[addr]; return val; } -void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) +void mem_write_scatb(uint32_t addr, uint8_t val, void *priv) { scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; addr = get_scat_addr(addr, stat); + chkaddr = stat ? addr : oldaddr; + if (chkaddr >= 0xC0000 && chkaddr < 0x100000) + { + if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; + } if (addr < (mem_size << 10)) - mem_write_ram(addr, val, priv); + ram[addr] = val; +} + +uint16_t mem_read_scatw(uint32_t addr, void *priv) +{ + uint16_t val = 0xffff; + scat_t *stat = (scat_t *)priv; + + if((addr & 0x3FFF) == 0x3FFF) pclog("mem_read_scatw(%08X, %p) called.\n", addr, priv); + addr = get_scat_addr(addr, stat); + if (addr < (mem_size << 10)) + val = *(uint16_t *)&ram[addr]; + + return val; +} + +void mem_write_scatw(uint32_t addr, uint16_t val, void *priv) +{ + scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; + + if((addr & 0x3FFF) == 0x3FFF) pclog("mem_write_scatw(%08X, %04X, %p) called.\n", addr, val, priv); + addr = get_scat_addr(addr, stat); + chkaddr = stat ? addr : oldaddr; + if (chkaddr >= 0xC0000 && chkaddr < 0x100000) + { + if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; + } + if (addr < (mem_size << 10)) + *(uint16_t *)&ram[addr] = val; +} + +uint32_t mem_read_scatl(uint32_t addr, void *priv) +{ + uint32_t val = 0xffffffff; + scat_t *stat = (scat_t *)priv; + + if((addr & 0x3FFF) > 0x3FFC) pclog("mem_read_scatl(%08X, %p) called.\n", addr, priv); + addr = get_scat_addr(addr, stat); + if (addr < (mem_size << 10)) + val = *(uint32_t *)&ram[addr]; + + return val; +} + +void mem_write_scatl(uint32_t addr, uint32_t val, void *priv) +{ + scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; + + if((addr & 0x3FFF) > 0x3FFC) pclog("mem_write_scatl(%08X, %08X, %p) called.\n", addr, val, priv); + addr = get_scat_addr(addr, stat); + chkaddr = stat ? addr : oldaddr; + if (chkaddr >= 0xC0000 && chkaddr < 0x100000) + { + if(scat_regs[SCAT_RAM_WRITE_PROTECT] & (1 << ((chkaddr - 0xC0000) >> 15))) return; + } + if (addr < (mem_size << 10)) + *(uint32_t *)&ram[addr] = val; } void scat_init() @@ -530,7 +1365,16 @@ void scat_init() } scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; - scat_regs[SCAT_VERSION] = 4; + switch(romset) + { + case ROM_GW286CT: + case ROM_SPC4216P: + scat_regs[SCAT_VERSION] = 4; + break; + default: + scat_regs[SCAT_VERSION] = 1; + break; + } scat_regs[SCAT_CLOCK_CONTROL] = 2; scat_regs[SCAT_PERIPHERAL_CONTROL] = 0x80; scat_regs[SCAT_MISCELLANEOUS_STATUS] = 0x37; @@ -545,37 +1389,49 @@ void scat_init() scat_regs[SCAT_EMS_CONTROL] = 0; scat_port_92 = 0; - mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); - - for (i = 0; i < 24; i++) + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + for (i = 0; i < 4; i++) + mem_mapping_disable(&bios_mapping[i]); + mem_mapping_add(&scat_low_mapping[0], 0, 0x40000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_low_mapping[1], 0xF0000, 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xF0000, MEM_MAPPING_INTERNAL, NULL); + for(i=2;i<32;i++) { - mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + mem_mapping_add(&scat_low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + (i << 19), MEM_MAPPING_INTERNAL, NULL); } + mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, scat_regs[SCAT_VERSION] < 4 ? 0x40000 : 0x60000); - mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_A000_BFFF_mapping); + for (i = 0; i < 44; i++) + mem_mapping_add(&scat_4000_EFFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + for (i = 0; i < 8; i++) + { + mem_mapping_add(&scat_low_ROMCS_mapping[i], 0xC0000 + (i << 14), 0x4000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); + mem_mapping_disable(&scat_low_ROMCS_mapping[i]); + } for (i = 0; i < 32; i++) { 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, NULL, NULL, mem_write_scatems, NULL, NULL, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); - mem_mapping_disable(&scat_mapping[i]); + mem_mapping_add(&scat_ems_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); } for(i=4;i<10;i++) isram[i] = 0; - // 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++) + for (i = (scat_regs[SCAT_VERSION] < 4 ? 0 : 8); 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) & biosmask), 0, NULL); + mem_mapping_enable(&scat_high_mapping[i]); } for(i=0;i<6;i++) - mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + + external_is_RAS = (scat_regs[SCAT_VERSION] > 3) || (((mem_size & ~2047) >> 11) + ((mem_size & 1536) >> 9) + ((mem_size & 511) >> 7)) > 4; scat_set_xms_bound(0); + scat_memmap_state_update(); scat_shadow_state_update(); } @@ -612,34 +1468,50 @@ void scatsx_init() scat_regs[SCATSX_CAS_TIMING_FOR_DMA] = 3; scat_port_92 = 0; - mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); - - for (i = 16; i < 24; i++) + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + for (i = 0; i < 4; i++) + mem_mapping_disable(&bios_mapping[i]); + mem_mapping_add(&scat_low_mapping[0], 0, 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_low_mapping[1], 0xF0000, 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + 0xF0000, MEM_MAPPING_INTERNAL, NULL); + for(i=2;i<32;i++) { - mem_mapping_add(&scat_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_4000_9FFF_mapping[i]); + mem_mapping_add(&scat_low_mapping[i], (i << 19), 0x80000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + (i << 19), MEM_MAPPING_INTERNAL, NULL); } + mem_mapping_set_addr(&scat_low_mapping[31], 0xF80000, 0x40000); - mem_mapping_add(&scat_A000_BFFF_mapping, 0xA0000, 0x20000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_enable(&scat_A000_BFFF_mapping); + for (i = 16; i < 44; i++) + { + mem_mapping_add(&scat_4000_EFFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&scat_4000_EFFF_mapping[i]); + } + for (i = 0; i < 8; i++) + { + mem_mapping_add(&scat_low_ROMCS_mapping[i], 0xC0000 + (i << 14), 0x4000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + ((i << 14) & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, NULL); + mem_mapping_disable(&scat_low_ROMCS_mapping[i]); + } for (i = 24; i < 32; i++) { scat_stat[i].regs_2x8 = 0xff; scat_stat[i].regs_2x9 = 0x03; - mem_mapping_add(&scat_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, ram + ((i + 28) << 14), 0, &scat_stat[i]); - mem_mapping_disable(&scat_mapping[i]); + mem_mapping_add(&scat_ems_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + 28) << 14), 0, &scat_stat[i]); + mem_mapping_disable(&scat_ems_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. - for (i = 12; i < 16; i++) + for (i = 0; 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) & biosmask), 0, NULL); + mem_mapping_enable(&scat_high_mapping[i]); } for(i=0;i<6;i++) - mem_mapping_add(&scat_shadowram_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatems, NULL, NULL, mem_write_scatems, NULL, NULL, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&scat_remap_mapping[i], 0x100000 + (i << 16), 0x10000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, mem_size >= 1024 ? ram + get_scat_addr(0x100000 + (i << 16), NULL) : NULL, MEM_MAPPING_INTERNAL, NULL); + + external_is_RAS = scatsx_external_is_RAS[mem_size >> 9]; scat_set_xms_bound(0); + scat_memmap_state_update(); scat_shadow_state_update(); } From 461cb221cabd36ec4819001f209787b59c365de5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Nov 2018 20:32:53 +0000 Subject: [PATCH 0523/1050] Implemented experimental Headland HT102 chipset based EMS support. Added Trigem 266M and AMA-932J machines. Patch from Greatpsycho. --- src/headland.c | 504 ++++++++++++++++++++++++++++++++++++++++++++++- src/ibm.h | 2 + src/mem_bios.c | 19 ++ src/model.c | 2 + src/nvr.c | 4 + src/vid_oti067.c | 26 ++- src/vid_oti067.h | 1 + src/video.c | 13 ++ 8 files changed, 560 insertions(+), 11 deletions(-) diff --git a/src/headland.c b/src/headland.c index b3bc4d0..8af4a5d 100644 --- a/src/headland.c +++ b/src/headland.c @@ -8,16 +8,173 @@ static int headland_index; static uint8_t headland_regs[256]; +static uint8_t headland_port_92 = 0xFC, headland_ems_mar = 0, headland_cri = 0; +static uint8_t headland_regs_cr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static uint16_t headland_ems_mr[64]; + +static mem_mapping_t headland_low_mapping; +static mem_mapping_t headland_ems_mapping[64]; +static mem_mapping_t headland_mid_mapping; +static mem_mapping_t headland_high_mapping; +static mem_mapping_t headland_4000_9FFF_mapping[24]; + +// TODO - Headland chipset's memory address mapping emulation isn't fully implemented yet, so memory configuration is hardcoded now. +static int headland_mem_conf_cr0[41] = { 0x00, 0x00, 0x20, 0x40, 0x60, 0xA0, 0x40, 0xE0, + 0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, 0xE0, 0xE0, + 0xE0, 0x20, 0x40, 0x40, 0xA0, 0xC0, 0xE0, 0xE0, + 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, + 0x20, 0x40, 0x60, 0x60, 0xC0, 0xE0, 0xE0, 0xE0, + 0xE0 }; +static int headland_mem_conf_cr1[41] = { 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, + 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x40 }; + +uint32_t get_headland_addr(uint32_t addr, uint16_t *mr) +{ + if (mr && (headland_regs_cr[0] & 2) && (*mr & 0x200)) + { + addr = (addr & 0x3fff) | ((*mr & 0x1F) << 14); + + if(headland_regs_cr[1] & 0x40) + { + if((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) + { + if(headland_regs_cr[0] & 0x80) + { + addr |= (*mr & 0x60) << 14; + if(*mr & 0x100) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x80) << 15); + else + addr += (*mr & 0x80) << 14; + } + else if(*mr & 0x100) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x20) << 15); + else + addr += (*mr & 0x80) << 12; + } + else if(headland_regs_cr[0] & 0x80) + addr |= (*mr & 0x100) ? ((*mr & 0x80) + 0x400) << 12 : (*mr & 0xE0) << 14; + else + addr |= (*mr & 0x100) ? ((*mr & 0xE0) + 0x40) << 14 : (*mr & 0x80) << 12; + } + else + { + if((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) + { + if(headland_regs_cr[0] & 0x80) + { + addr |= ((*mr & 0x60) << 14); + if(*mr & 0x180) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x180) - 0x60) << 16); + } + else + addr |= ((*mr & 0x60) << 14) | ((*mr & 0x180) << 16) | ((*mr & 0xC00) << 13); + } + else if(headland_regs_cr[0] & 0x80) + addr |= (*mr & 0x1E0) << 14; + else + addr |= (*mr & 0x180) << 12; + } + } + else if(mr == NULL && (headland_regs_cr[0] & 4) == 0 && mem_size >= 1024 && addr >= 0x100000) + addr -= 0x60000; + + return addr; +} + +void headland_set_global_EMS_state(int state) +{ + int i; + uint32_t base_addr, virt_addr; + + for(i=0; i<32; i++) + { + base_addr = (i + 16) << 14; + if(i >= 24) + base_addr += 0x20000; + if((state & 2) && (headland_ems_mr[((state & 1) << 5) | i] & 0x200)) + { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[((state & 1) << 5) | i]); + if(i < 24) mem_mapping_disable(&headland_4000_9FFF_mapping[i]); + mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); + mem_mapping_enable(&headland_ems_mapping[((state & 1) << 5) | i]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + virt_addr); + else mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], NULL); + } + else + { + mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + base_addr); + mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); + mem_mapping_disable(&headland_ems_mapping[((state & 1) << 5) | i]); + + if(i < 24) + mem_mapping_enable(&headland_4000_9FFF_mapping[i]); + } + } + flushmmucache(); +} + +void headland_memmap_state_update() +{ + int i; + uint32_t addr; + + for(i=0;i<24;i++) + { + addr = get_headland_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&headland_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + //pclog("headland_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); + } + + mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + if (mem_size > 640) + { + if ((headland_regs_cr[0] & 4) == 0) + { + mem_mapping_set_addr(&headland_mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); + mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); + if (mem_size > 1024) + { + mem_mapping_set_addr(&headland_high_mapping, 0x160000, (mem_size - 1024) << 10); + mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); + } + } + else + { + mem_mapping_set_addr(&headland_mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); + mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); + if (mem_size > 1024) + { + mem_mapping_set_addr(&headland_high_mapping, 0x100000, (mem_size - 1024) << 10); + mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); + } + } + } + + headland_set_global_EMS_state(headland_regs_cr[0] & 3); +} void headland_write(uint16_t addr, uint8_t val, void *priv) { - if (addr & 1) + uint8_t old_val, index; + uint32_t base_addr, virt_addr; + + switch(addr) { - uint8_t old_val = headland_regs[headland_index]; + case 0x22: + headland_index = val; + break; + + case 0x23: + old_val = headland_regs[headland_index]; if (headland_index == 0xc1 && !is486) val = 0; headland_regs[headland_index] = val; - pclog("Headland write %02X %02X\n",headland_index,val); + //pclog("Headland write %02X %02X at %04X:%04X\n",headland_index,val,CS,cpu_state.oldpc); if (headland_index == 0x82) { shadowbios = val & 0x10; @@ -32,23 +189,350 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) if ((val & 1) && !(old_val & 1)) softresetx86(); } + break; + + case 0x92: + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~headland_port_92 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + headland_port_92 = val | 0xFC; + break; + + case 0x1EC: + //pclog("Set EMS Map Register to %02X(actually FF%02X) at %04X:%04X\n", val, val, CS, cpu_state.oldpc); + headland_ems_mr[headland_ems_mar & 0x3F] = val | 0xFF00; + index = headland_ems_mar & 0x1F; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x20000; + if((headland_regs_cr[0] & 2) && ((headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5))) + { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); + if(index < 24) mem_mapping_disable(&headland_4000_9FFF_mapping[index]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); + else mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); + mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + pclog("Map page %d(address %05X) to address %06X\n", index, base_addr, virt_addr); + flushmmucache(); + } + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + case 0x1ED: + //pclog("Set Control Register Index to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_cri = val; + break; + + case 0x1EE: + //pclog("Set EMS Map Address Register to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_ems_mar = val; + break; + + case 0x1EF: + //pclog("Set Control Register %1X to %02X at %04X:%04X\n", headland_cri, val, CS, cpu_state.oldpc); + old_val = headland_regs_cr[headland_cri]; + switch(headland_cri) + { + case 0: + headland_regs_cr[0] = (val & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + mem_set_mem_state(0xE0000, 0x10000, (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); + mem_set_mem_state(0xF0000, 0x10000, (val & 0x10 ? MEM_READ_INTERNAL: MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); + headland_memmap_state_update(); + break; + case 1: + headland_regs_cr[1] = (val & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + headland_memmap_state_update(); + break; + case 2: + case 3: + case 5: + headland_regs_cr[headland_cri] = val; + headland_memmap_state_update(); + break; + case 4: + headland_regs_cr[4] = (headland_regs_cr[4] & 0xF0) | (val & 0x0F); + if(val & 1) + { + mem_mapping_disable(&bios_mapping[0]); + mem_mapping_disable(&bios_mapping[1]); + mem_mapping_disable(&bios_mapping[2]); + mem_mapping_disable(&bios_mapping[3]); + } + else + { + mem_mapping_enable(&bios_mapping[0]); + mem_mapping_enable(&bios_mapping[1]); + mem_mapping_enable(&bios_mapping[2]); + mem_mapping_enable(&bios_mapping[3]); + } + break; + case 6: + if(headland_regs_cr[4] & 0x80) + { + headland_regs_cr[headland_cri] = (val & 0xFE) | (mem_size > 8192 ? 1 : 0); + headland_memmap_state_update(); + } + break; + default: + break; + } + break; + + default: + break; + } +} + +void headland_writew(uint16_t addr, uint16_t val, void *priv) +{ + uint8_t index; + uint32_t base_addr, virt_addr; + + switch(addr) + { + case 0x1EC: + //pclog("Set EMS Map Register to %04X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_ems_mr[headland_ems_mar & 0x3F] = val; + index = headland_ems_mar & 0x1F; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x20000; + if((headland_regs_cr[0] & 2) && (headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5)) + { + if(val & 0x200) + { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); + if(index < 24) mem_mapping_disable(&headland_4000_9FFF_mapping[index]); + if(virt_addr < (mem_size << 10)) mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); + else mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); + mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + //pclog("Map page %d(address %05X) to address %07X(val=%04X)\n", index, base_addr, virt_addr, val); + } + else + { + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + base_addr); + mem_mapping_disable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + if(index < 24) mem_mapping_enable(&headland_4000_9FFF_mapping[index]); + //pclog("Unmap page %d(address %05X)\n", index, base_addr); + } + flushmmucache(); + } + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + default: + break; } - else - headland_index = val; } uint8_t headland_read(uint16_t addr, void *priv) { - if (addr & 1) + uint8_t val; + + switch(addr) { + case 0x22: + val = headland_index; + break; + + case 0x23: if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) - return 0xff; /*Don't conflict with Cyrix config registers*/ - return headland_regs[headland_index]; + val = 0xff; /*Don't conflict with Cyrix config registers*/ + else + val = headland_regs[headland_index]; + break; + + case 0x92: + val = headland_port_92 | 0xFC; + break; + + case 0x1EC: + val = headland_ems_mr[headland_ems_mar & 0x3F]; + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + case 0x1ED: + val = headland_cri; + break; + + case 0x1EE: + val = headland_ems_mar; + break; + + case 0x1EF: + switch(headland_cri) + { + case 0: + val = (headland_regs_cr[0] & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + break; + case 1: + val = (headland_regs_cr[1] & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + break; + case 6: + if(headland_regs_cr[4] & 0x80) + val = (headland_regs_cr[6] & 0xFE) | (mem_size > 8192 ? 1 : 0); + else + val = 0; + break; + default: + val = headland_regs_cr[headland_cri]; + break; + } + break; + + default: + val = 0xFF; + break; } - return headland_index; + + return val; +} + +uint16_t headland_readw(uint16_t addr, void *priv) +{ + uint16_t val; + + switch(addr) + { + case 0x1EC: + val = headland_ems_mr[headland_ems_mar & 0x3F] | ((headland_regs_cr[4] & 0x80) ? 0xF000 : 0xFC00); + if(headland_ems_mar & 0x80) headland_ems_mar++; + break; + + default: + val = 0xFFFF; + break; + } + + return val; +} + +uint8_t mem_read_headlandb(uint32_t addr, void *priv) +{ + uint8_t val = 0xff; + + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = ram[addr]; + + return val; +} + +void mem_write_headlandb(uint32_t addr, uint8_t val, void *priv) +{ + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +uint16_t mem_read_headlandw(uint32_t addr, void *priv) +{ + uint16_t val = 0xffff; + + if((addr & 0x3FFF) == 0x3FFF) pclog("mem_read_headlandw(%08X, %p) called.\n", addr, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = *(uint16_t *)&ram[addr]; + + return val; +} + +void mem_write_headlandw(uint32_t addr, uint16_t val, void *priv) +{ + if((addr & 0x3FFF) == 0x3FFF) pclog("mem_write_headlandw(%08X, %04X, %p) called.\n", addr, val, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + *(uint16_t *)&ram[addr] = val; +} + +uint32_t mem_read_headlandl(uint32_t addr, void *priv) +{ + uint32_t val = 0xffffffff; + + if((addr & 0x3FFF) > 0x3FFC) pclog("mem_read_headlandl(%08X, %p) called.\n", addr, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = *(uint32_t *)&ram[addr]; + + return val; +} + +void mem_write_headlandl(uint32_t addr, uint32_t val, void *priv) +{ + if((addr & 0x3FFF) > 0x3FFC) pclog("mem_write_headland(%08X, %08X, %p) called.\n", addr, val, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + *(uint32_t *)&ram[addr] = val; } void headland_init() { - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + int i; + + for(i=0; i<8; i++) + headland_regs_cr[i] = 0; + headland_regs_cr[0] = 4; + + switch(romset) + { + case ROM_AMI386SX: + // Remark - Previously distributed AMI386 BIOS doesn't seem to be for the Headland chipset. + io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + break; + case ROM_AMA932J: + headland_regs_cr[4] = 0x20; + io_sethandler(0x0092, 0x0001, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + break; + default: + headland_regs_cr[4] = 0; + break; + } + + io_sethandler(0x01EC, 0x0001, headland_read, headland_readw, NULL, headland_write, headland_writew, NULL, NULL); + io_sethandler(0x01ED, 0x0003, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + + for(i=0; i<64; i++) + headland_ems_mr[i] = 0; + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + + mem_mapping_add(&headland_low_mapping, 0, 0x40000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram, MEM_MAPPING_INTERNAL, NULL); + + if(mem_size > 640) + { + mem_mapping_add(&headland_mid_mapping, 0xA0000, 0x60000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_mid_mapping); + } + + if(mem_size > 1024) + { + mem_mapping_add(&headland_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_high_mapping); + } + + for (i = 0; i < 24; i++) + { + mem_mapping_add(&headland_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_4000_9FFF_mapping[i]); + } + + for (i = 0; i < 64; i++) + { + headland_ems_mr[i] = 0; + mem_mapping_add(&headland_ems_mapping[i], ((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14), 0, &headland_ems_mr[i]); + mem_mapping_disable(&headland_ems_mapping[i]); + } + + for(i=4;i<10;i++) isram[i] = 0; + + headland_memmap_state_update(); } diff --git a/src/ibm.h b/src/ibm.h index 549acc2..ccddb88 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -413,6 +413,7 @@ enum ROM_IBMAT, ROM_CMDPC30, ROM_AMI286, + ROM_TG286M, ROM_AWARD286, ROM_GW286CT, ROM_SPC4200P, @@ -423,6 +424,7 @@ enum ROM_ACER386, ROM_KMXC02, ROM_MEGAPC, + ROM_AMA932J, ROM_AMI386SX, ROM_AMI486, ROM_WIN486, diff --git a/src/mem_bios.c b/src/mem_bios.c index dc5a904..26603e2 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -284,6 +284,17 @@ int loadbios() romfread(rom,65536,1,f); fclose(f); return 1;*/ + case ROM_AMA932J: +// f=romfopen("at386/at386.bin","rb"); + f=romfopen("ama932j/ami.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + f=romfopen("ama932j/oti067.bin","rb"); + if (!f) break; + fclose(f); + return 1; + case ROM_AMI386SX: // f=romfopen("at386/at386.bin","rb"); f=romfopen("ami386/ami386.bin","rb"); @@ -332,6 +343,14 @@ int loadbios() // memset(romext,0x63,0x8000); return 1; + case ROM_TG286M: + f=romfopen("tg286m/ami.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); +// memset(romext,0x63,0x8000); + return 1; + case ROM_AWARD286: f=romfopen("award286/award.bin","rb"); if (!f) break; diff --git a/src/model.c b/src/model.c index 55be58b..3546d2d 100644 --- a/src/model.c +++ b/src/model.c @@ -157,8 +157,10 @@ MODEL models[] = {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL}, {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, {"[286] Toshiba T3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}, + {"[286] Trigem 286M", ROM_TG286M, "tg286m", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, + {"[386SX] AMA-932J", ROM_AMA932J, "ama932j", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 32510aa..045f373 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -265,6 +265,7 @@ void loadnvr() case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "rb"); break; case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "rb"); nvrmask = 127; break; case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); nvrmask = 127; break; + case ROM_TG286M: f = nvrfopen("tg286m.nvr", "rb"); nvrmask = 127; break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break; case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; @@ -275,6 +276,7 @@ void loadnvr() case ROM_ACER386: f = nvrfopen("acer386.nvr", "rb"); nvrmask = 127; break; case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "rb"); nvrmask = 127; break; case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "rb"); nvrmask = 127; break; + case ROM_AMA932J: f = nvrfopen("ama932j.nvr", "rb"); nvrmask = 127; break; case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "rb"); nvrmask = 127; break; case ROM_AMI486: f = nvrfopen("ami486.nvr", "rb"); nvrmask = 127; break; case ROM_WIN486: f = nvrfopen("win486.nvr", "rb"); nvrmask = 127; break; @@ -355,6 +357,7 @@ void savenvr() case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "wb"); break; case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "wb"); break; case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); break; + case ROM_TG286M: f = nvrfopen("tg286m.nvr", "wb"); break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break; case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; @@ -365,6 +368,7 @@ void savenvr() case ROM_ACER386: f = nvrfopen("acer386.nvr", "wb"); break; case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "wb"); break; case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "wb"); break; + case ROM_AMA932J: f = nvrfopen("ama932j.nvr", "wb"); break; case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "wb"); break; case ROM_AMI486: f = nvrfopen("ami486.nvr", "wb"); break; case ROM_WIN486: f = nvrfopen("win486.nvr", "wb"); break; diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 1b7c20d..400fcf2 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -20,11 +20,14 @@ typedef struct oti067_t uint8_t regs[32]; uint8_t pos; + uint8_t dipswitch_val; uint32_t vram_size; uint32_t vram_mask; } oti067_t; +static uint8_t oti067_dipswitch_val = 0x18; + void oti067_out(uint16_t addr, uint8_t val, void *p) { oti067_t *oti067 = (oti067_t *)p; @@ -111,7 +114,7 @@ uint8_t oti067_in(uint16_t addr, void *p) temp = oti067->index | (2 << 5); break; case 0x3DF: - if (oti067->index==0x10) temp = 0x18; + if (oti067->index==0x10) temp = oti067_dipswitch_val; else temp = oti067->regs[oti067->index]; break; @@ -192,6 +195,8 @@ void oti067_enable_disable(void *p, int enable) io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); mem_mapping_enable(&oti067->svga.mapping); } + + oti067->dipswitch_val = 0x18; } void *oti067_init() @@ -209,6 +214,14 @@ void *oti067_acer386_init() return oti067; } +void *oti067_ama932j_init() +{ + oti067_t *oti067 = oti067_common_init("ama932j/oti067.bin", 512); + + oti067->dipswitch_val |= 0x20; + return oti067; +} + static int oti067_available() { return rom_present("oti067/bios.bin"); @@ -294,3 +307,14 @@ device_t oti067_acer386_device = oti067_force_redraw, oti067_add_status_info }; +device_t oti067_ama932j_device = +{ + "Oak OTI-067 (AMA-932J)", + 0, + oti067_ama932j_init, + oti067_close, + oti067_available, + oti067_speed_changed, + oti067_force_redraw, + oti067_add_status_info +}; diff --git a/src/vid_oti067.h b/src/vid_oti067.h index cf1fa1b..8376b38 100644 --- a/src/vid_oti067.h +++ b/src/vid_oti067.h @@ -1,4 +1,5 @@ extern device_t oti067_device; extern device_t oti067_acer386_device; +extern device_t oti067_ama932j_device; void oti067_enable_disable(void *p, int enable); diff --git a/src/video.c b/src/video.c index ab0ff7f..49c8ea0 100644 --- a/src/video.c +++ b/src/video.c @@ -191,6 +191,9 @@ device_t *video_card_getdevice(int card) case ROM_ACER386: return &oti067_acer386_device; + + case ROM_AMA932J: + return &oti067_ama932j_device; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: @@ -391,6 +394,7 @@ int video_is_ega_vga() case ROM_PC3086: case ROM_MEGAPC: case ROM_ACER386: + case ROM_AMA932J: case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: case ROM_IBMPS2_M50: @@ -522,6 +526,11 @@ void video_updatetiming() if (gfxcard == GFX_BUILTIN) timing = &timing_oti067; break; + + case ROM_AMA932J: + if (gfxcard == GFX_BUILTIN) + timing = &timing_oti067; + break; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: @@ -689,6 +698,10 @@ void video_init() break; } return; + + case ROM_AMA932J: + device_add(&oti067_ama932j_device); + return; case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: From 5167ba5b2dc4301e9d797f3ef57214d421313a2f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Nov 2018 21:05:40 +0000 Subject: [PATCH 0524/1050] Added Tulip AT Compact. Patch from dns2kv2. --- src/ibm.h | 1 + src/mem_bios.c | 15 +++++++++++++++ src/model.c | 1 + src/nvr.c | 2 ++ 4 files changed, 19 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index ccddb88..e24fe4a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -462,6 +462,7 @@ enum ROM_XI8088, ROM_IBMPS2_M70_TYPE3, ROM_IBMPS2_M70_TYPE4, + ROM_TULIP_TC7, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 26603e2..5e92146 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -919,6 +919,21 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_TULIP_TC7: + f = romfopen("tulip_tc7/tc7be.bin", "rb"); + ff = romfopen("tulip_tc7/tc7bo.bin", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x8000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 3546d2d..36781a3 100644 --- a/src/model.c +++ b/src/model.c @@ -158,6 +158,7 @@ MODEL models[] = {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, {"[286] Toshiba T3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}, {"[286] Trigem 286M", ROM_TG286M, "tg286m", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, + {"[286] Tulip AT Compact", ROM_TULIP_TC7, "tulip_tc7", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 640,15872, 128, ibm_at_init, NULL}, {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", { {"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, NULL}, {"[386SX] AMA-932J", ROM_AMA932J, "ama932j", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 045f373..843096f 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -310,6 +310,7 @@ void loadnvr() case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break; case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break; + case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "rb"); break; default: return; } @@ -402,6 +403,7 @@ void savenvr() case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); break; case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break; case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break; + case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "wb"); break; default: return; } From 4155b283abe1db1b4765b9e63aafaabdcfc02021 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 13 Nov 2018 18:53:55 +0000 Subject: [PATCH 0525/1050] Added Sigma Designs Color 400 emulation. Patch from John Elliott. --- src/Makefile.am | 2 +- src/ibm.h | 1 + src/vid_sigma.c | 980 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vid_sigma.h | 2 + src/video.c | 16 +- 5 files changed, 999 insertions(+), 2 deletions(-) create mode 100644 src/vid_sigma.c create mode 100644 src/vid_sigma.h diff --git a/src/Makefile.am b/src/Makefile.am index 56741ab..5b62127 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,7 @@ t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.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_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c \ x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc diff --git a/src/ibm.h b/src/ibm.h index e24fe4a..4bab0e3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -507,6 +507,7 @@ enum GFX_CL_GD5434, /*Cirrus Logic CL-GD5434*/ GFX_OTI037, /*Oak OTI-037*/ GFX_COMPAQ_CGA, /*Compaq CGA*/ + GFX_SIGMA400, /*Sigma Designs Color 400 */ GFX_MAX }; diff --git a/src/vid_sigma.c b/src/vid_sigma.c new file mode 100644 index 0000000..6519c81 --- /dev/null +++ b/src/vid_sigma.c @@ -0,0 +1,980 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "video.h" +#include "vid_sigma.h" + +extern void loadfont(char *s, int format); + +/* The Sigma Designs Color 400 is a video card from 1985, presumably intended + * as an EGA competitor. + * + * The hardware seems to have gone through various iterations; I've seen + * pictures of full-length and half-length versions. + * TH99 describes the jumpers / switches: + * + * + * The card is CGA-compatible at BIOS level, but to improve compatibility + * attempts to write to the CGA I/O ports at 0x3D0-0x3DF trigger an NMI. The + * card's BIOS handles the NMI and translates the CGA writes into commands + * to its own hardware at 0x2D0-0x2DF. (DIP switches on the card allow the + * base address to be changed, but since the BIOS dump I have doesn't support + * this I haven't emulated it. Likewise the BIOS ROM address can be changed, + * but I'm going with the default of 0xC0000). + * + * The BIOS still functions if the NMI system isn't operational. There + * doesn't seem to be a jumper or DIP switch to lock it out, but at startup + * the BIOS tests for its presence and configures itself to work or not + * as required. I've therefore added a configuration option to handle this. + * + * The card's real CRTC at 0x2D0/0x2D1 appears to be a 6845. One oddity is + * that all its horizontal counts are halved compared to what a real CGA + * uses; 40-column modes have a width of 20, and 80-column modes have a + * width of 40. This means that the CRTC cursor position (registers 14/15) can + * only address even-numbered columns, so the top bit of the control + * register at 0x2D9 is used to adjust the position. + * + * Apart from the CRTC, registers are: + * + * 0x2D8: Mode register. Values written by the card BIOS are: + * Text 40x25: 0xA8 + * Text 80x25: 0xB9 + * Text 80x30: 0xB9 + * Text 80x50: 0x79 + * Graphics 320x200: 0x0F + * Graphics 640x200: 0x1F + * Graphics 640x400: 0x7F + * + * I have assumed this is a bitmap with the following meaning: */ +#define MODE_80COLS 0x01 /* For text modes, 80 columns across */ +#define MODE_GRAPHICS 0x02 /* Graphics mode */ +#define MODE_NOBLINK 0x04 /* Disable blink? */ +#define MODE_ENABLE 0x08 /* Enable display */ +#define MODE_HRGFX 0x10 /* For graphics modes, 640 pixels across */ +#define MODE_640x400 0x40 /* 400-line graphics mode */ +#define MODE_FONT16 0x80 /* Use 16-pixel high font */ +/* + * 0x2D9: Control register, with the following bits: */ +#define CTL_CURSOR 0x80 /* Low bit of cursor position */ +#define CTL_NMI 0x20 /* Writes to 0x3D0-0x3DF trigger NMI */ +#define CTL_CLEAR_LPEN 0x08 /* Strobe 0 to clear lightpen latch */ +#define CTL_SET_LPEN 0x04 /* Strobe 0 to set lightpen latch */ +#define CTL_PALETTE 0x01 /* 0x2DE writes to palette (1) or plane (0) */ +/* + * The card BIOS seems to support two variants of the hardware: One where + * bits 2 and 3 are normally 1 and are set to 0 to set/clear the latch, and + * one where they are normally 0 and are set to 1. Behaviour is selected by + * whether the byte at C000:17FFh is greater than 2Fh. + * + * 0x2DA: Status register. + */ +#define STATUS_CURSOR 0x80 /* Last value written to bit 7 of 0x2D9 */ +#define STATUS_NMI 0x20 /* Last value written to bit 5 of 0x2D9 */ +#define STATUS_RETR_V 0x10 /* Vertical retrace */ +#define STATUS_LPEN_T 0x04 /* Lightpen switch is off */ +#define STATUS_LPEN_A 0x02 /* Edge from lightpen has set trigger */ +#define STATUS_RETR_H 0x01 /* Horizontal retrace */ +/* + * 0x2DB: On read: Byte written to the card that triggered NMI + * 0x2DB: On write: Resets the 'card raised NMI' flag. + * 0x2DC: On read: Bit 7 set if the card raised NMI. If so, bits 0-3 + * give the low 4 bits of the I/O port address. + * 0x2DC: On write: Resets the NMI. + * 0x2DD: Memory paging. The memory from 0xC1800 to 0xC1FFF can be either: + * + * > ROM: A 128 character 8x16 font for use in graphics modes + * > RAM: Use by the video BIOS to hold its settings. + * + * Reading port 2DD switches to ROM. Bit 7 of the value read gives the + * previous paging state: bit 7 set if ROM was paged, clear if RAM was + * paged. + * + * Writing port 2DD switches to RAM. + * + * 0x2DE: Meaning depends on bottom bit of value written to port 0x2D9. + * Bit 0 set: Write to palette. High 4 bits of value = register, + * low 4 bits = RGBI values (active low) + * Bit 0 clear: Write to plane select. Low 2 bits of value select + * plane 0-3 + */ + + +typedef struct sigma_t +{ + mem_mapping_t mapping; + mem_mapping_t bios_ram; + rom_t bios_rom; + + uint8_t lastport; /* Last I/O port written */ + uint8_t lastwrite; /* Value written to that port */ + uint8_t sigma_ctl; /* Controls register: + * Bit 7 is low bit of cursor position + * Bit 5 set if writes to CGA ports trigger NMI + * Bit 3 clears lightpen latch + * Bit 2 sets lightpen latch + * Bit 1 controls meaning of port 2DE + */ + uint8_t enable_nmi; /* Enable the NMI mechanism for CGA emulation?*/ + uint8_t rom_paged; /* Is ROM paged in at 0xC1800? */ + + uint8_t crtc_value; /* Value to return from a CRTC register read */ + + int crtcreg; /* CRTC: Real selected register */ + uint8_t crtc[32]; /* CRTC: Real values */ + + uint8_t sigmastat; /* Status register [0x2DA] */ + + uint8_t sigmamode; /* Mode control register [0x2D8] */ + + int linepos, displine; + int sc, vc; + int cgadispon; + int con, coff, cursoron, cgablink; + int vsynctime, vadj; + uint16_t ma, maback; + int oddeven; + + int dispontime, dispofftime; + int vidtime; + + int firstline, lastline; + + int drawcursor; + + uint8_t *vram; + uint8_t bram[2048]; + + uint8_t palette[16]; + + int plane; + int revision; +} sigma_t; + +#define COMPOSITE_OLD 0 +#define COMPOSITE_NEW 1 + +static uint8_t crtcmask[32] = +{ + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void sigma_recalctimings(sigma_t *cga); + +void sigma_out(uint16_t addr, uint8_t val, void *p) +{ + sigma_t *sigma = (sigma_t *)p; + uint8_t old; + +// pclog("SIGMA_OUT %04X %02X\n", addr, val); + +// if (addr == 0x3D8 && (val & 0x80)) output = 3; + + if (addr >= 0x3D0 && addr < 0x3E0) + { + sigma->lastport = addr & 0x0F; + sigma->lastwrite = val; + /* If set to NMI on video I/O... */ + if (sigma->enable_nmi && (sigma->sigma_ctl & CTL_NMI)) + { + sigma->lastport |= 0x80; /* Card raised NMI */ + nmi = 1; +// pclog("Sigma: Raise NMI\n"); + } + /* For CRTC emulation, the card BIOS sets the value to be + * read from port 0x3D1 like this */ + if (addr == 0x3D1) + sigma->crtc_value = val; + } + else switch (addr) + { + case 0x2D0: + case 0x2D2: + case 0x2D4: + case 0x2D6: + sigma->crtcreg = val & 31; + return; + + case 0x2D1: + case 0x2D3: + case 0x2D5: + case 0x2D7: + old = sigma->crtc[sigma->crtcreg]; + sigma->crtc[sigma->crtcreg] = val & crtcmask[sigma->crtcreg]; +// pclog("Sigma: CRTC[0x%02x] := 0x%02x\n", +// sigma->crtcreg, val); + if (old != val) + { + if (sigma->crtcreg < 0xe || sigma->crtcreg > 0x10) + { + fullchange = changeframecount; + sigma_recalctimings(sigma); + } + } + return; + + case 0x2D8: +// pclog("Sigma mode := %02x\n", val); + sigma->sigmamode = val; + return; + case 0x2D9: +// pclog("Sigma control := %02x\n", val); + sigma->sigma_ctl = val; + return; + case 0x2DB: + sigma->lastport &= 0x7F; + return; + case 0x2DC: /* Reset NMI */ + nmi = 0; + sigma->lastport &= 0x7F; +// pclog("Sigma: Reset NMI\n"); + return; + case 0x2DD: /* Page in RAM at 0xC1800 */ + if (sigma->rom_paged != 0) + mmu_invalidate(0xC0000); + sigma->rom_paged = 0; +// pclog("Sigma: page RAM at C1800\n"); + return; + + case 0x2DE: + if (sigma->sigma_ctl & CTL_PALETTE) + { +// pclog("Sigma: Write palette %x := %x\n", +// val >> 4, val & 0x0F); + sigma->palette[val >> 4] = (val & 0x0F) ^ 0x0F; + } + else + { +// pclog("Sigma: Set plane to %d\n", val & 3); + sigma->plane = val & 3; + } + return; + } +} + +uint8_t sigma_in(uint16_t addr, void *p) +{ + uint8_t result = 0xFF; + sigma_t *sigma = (sigma_t *)p; + + switch (addr) + { + case 0x2D0: + case 0x2D2: + case 0x2D4: + case 0x2D6: + result = sigma->crtcreg; + break; + + case 0x2D1: + case 0x2D3: + case 0x2D5: + case 0x2D7: + result = sigma->crtc[sigma->crtcreg & 0x1F]; + break; + + case 0x2DA: + result = (sigma->sigma_ctl & 0xE0) | + (sigma->sigmastat & 0x1F); + break; + + case 0x2DB: + result = sigma->lastwrite; /* Value that triggered NMI */ + break; + case 0x2DC: + result = sigma->lastport; /* Port that triggered NMI */ + break; + case 0x2DD: /* Page in ROM at 0xC1800 */ +// pclog("Sigma: page ROM at C1800\n"); + result = (sigma->rom_paged ? 0x80 : 0); + if (sigma->rom_paged != 0x80) + mmu_invalidate(0xC0000); + sigma->rom_paged = 0x80; + break; + + case 0x3D1: + case 0x3D3: + case 0x3D5: + case 0x3D7: + result = sigma->crtc_value; + break; + +/* For CGA compatibility we have to return something palatable on this port. + * On a real card this functionality can be turned on or off with SW1/6 */ + case 0x3DA: + result = sigma->sigmastat & 7; + if (sigma->sigmastat & STATUS_RETR_V) result |= 8; + break; + } +// pclog("SIGMA_IN %04X = %02x\n", addr, result); + return result; +} + +void sigma_write(uint32_t addr, uint8_t val, void *p) +{ + sigma_t *sigma = (sigma_t *)p; + +// pclog("CGA_WRITE %04X %02X\n", addr, val); + sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val; + egawrites++; + cycles -= 4; +} + +uint8_t sigma_read(uint32_t addr, void *p) +{ + sigma_t *sigma = (sigma_t *)p; + + cycles -= 4; + egareads++; +// pclog("CGA_READ %04X\n", addr); + return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)]; +} + +void sigma_bwrite(uint32_t addr, uint8_t val, void *p) +{ + sigma_t *sigma = (sigma_t *)p; + + addr &= 0x3FFF; + if (addr < 0x1800 || sigma->rom_paged || addr >= 0x2000) + { +// pclog("sigma_bwrite(0x%05x) := [ROM] %02x\n", addr, val); + } + else + { +// pclog("sigma_bwrite(0x%05x) := [RAM] %02x\n", addr, val); + sigma->bram[addr & 0x7FF] = val; + } +} + +uint8_t sigma_bread(uint32_t addr, void *p) +{ + sigma_t *sigma = (sigma_t *)p; + uint8_t result; + + addr &= 0x3FFF; + if (addr >= 0x2000) + { +// if (output == 3) pclog("sigma_bread(0x%05x) = [NIL] %02x\n", +// addr, 0xFF); + return 0xFF; + } + if (addr < 0x1800 || sigma->rom_paged) + { + result = sigma->bios_rom.rom[addr & 0x1FFF]; +// if (output == 3) pclog("sigma_bread(0x%05x) = [ROM] %02x\n", addr, result); + } + else + { + result = sigma->bram[addr & 0x7FF]; +// if (output == 3) pclog("sigma_bread(0x%05x) = [RAM] %02x\n", addr, result); + } + return result; +} + + + +void sigma_recalctimings(sigma_t *sigma) +{ + double disptime; + double _dispontime, _dispofftime; +// pclog("Sigma_recalctimings - total=%i displayed=%i hi-res=%i\n", +// sigma->crtc[0], sigma->crtc[1], sigma->sigmamode & MODE_80COLS); + if (sigma->sigmamode & MODE_80COLS) + { + disptime = (sigma->crtc[0] + 1) << 1; + _dispontime = (sigma->crtc[1]) << 1; + } + else + { + disptime = (sigma->crtc[0] + 1) << 2; + _dispontime = sigma->crtc[1] << 2; + } + _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); + sigma->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + sigma->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +} + + + + +/* Render a line in 80-column text mode */ +void sigma_text80(sigma_t *sigma) +{ + int x, c; + uint8_t chr, attr; + uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + int drawcursor; + uint32_t cols[4]; + uint8_t *vram = sigma->vram + (ma << 1); + + ca = ca << 1; + if (sigma->sigma_ctl & CTL_CURSOR) ++ca; + ca &= 0x3fff; +// pclog("sigma_text80: displine=%d sc=%d Width=%d\n", +// sigma->displine, sigma->sc, sigma->crtc[1]); + + /* The Sigma 400 seems to use screen widths stated in words + * (40 for 80-column, 20 for 40-column) */ + for (x = 0; x < (sigma->crtc[1] << 1); x++) + { + chr = vram[x << 1]; + attr = vram[(x << 1) + 1]; + drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + + if (!(sigma->sigmamode & MODE_NOBLINK)) + { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) + cols[1] = cols[0]; + } + else /* No blink */ + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } +// if (chr != ' ') +// { +// pclog("[%x:%x]%c", cols[1], cols[0], chr); +// } + if (drawcursor) + { + for (c = 0; c < 8; c++) + { + if (sigma->sigmamode & MODE_FONT16) + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + else ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + } + else + { + for (c = 0; c < 8; c++) + { + if (sigma->sigmamode & MODE_FONT16) + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + else ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ++ma; + } + sigma->ma += sigma->crtc[1]; + //pclog("\n"); +} + + +/* Render a line in 40-column text mode */ +void sigma_text40(sigma_t *sigma) +{ + int x, c; + uint8_t chr, attr; + uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + int drawcursor; + uint32_t cols[4]; + uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); + + ca = ca << 1; + if (sigma->sigma_ctl & CTL_CURSOR) ++ca; + ca &= 0x3fff; + /* The Sigma 400 seems to use screen widths stated in words + * (40 for 80-column, 20 for 40-column) */ + for (x = 0; x < (sigma->crtc[1] << 1); x++) + { + chr = vram[x << 1]; + attr = vram[(x << 1) + 1]; + drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + + if (!(sigma->sigmamode & MODE_NOBLINK)) + { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) + cols[1] = cols[0]; + } + else /* No blink */ + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } +// if (chr != ' ') +// { +// pclog("[%x:%x]%c", cols[1], cols[0], chr); +// } + if (drawcursor) + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2*c + 8] = + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2*c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + } + else + { + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2*c + 8] = + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2*c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ma++; + } + sigma->ma += sigma->crtc[1]; + //pclog("\n"); +} + + + + +/* Draw a line in the 640x400 graphics mode */ +void sigma_gfx400(sigma_t *sigma) +{ + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + + (sigma->sc & 3) * 0x2000]; + uint8_t plane[4]; + uint8_t mask, col, c; + + for (x = 0; x < (sigma->crtc[1] << 1); x++) + { + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; + + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) + { + col = ((plane[3] & mask) ? 8 : 0) | + ((plane[2] & mask) ? 4 : 0) | + ((plane[1] & mask) ? 2 : 0) | + ((plane[0] & mask) ? 1 : 0); + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = col; + } + if (x & 1) ++sigma->ma; + } +} + + +/* Draw a line in the 640x200 graphics mode. + * This is actually a 640x200x16 mode; on startup, the BIOS selects plane 2, + * blanks the other planes, and sets palette ink 4 to white. Pixels plotted + * in plane 2 come out in white, others black; but by programming the palette + * and plane registers manually you can get the full resolution. */ +void sigma_gfx200(sigma_t *sigma) +{ + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + + (sigma->sc & 2) * 0x1000]; + uint8_t plane[4]; + uint8_t mask, col, c; + + for (x = 0; x < (sigma->crtc[1] << 1); x++) + { + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; + + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) + { + col = ((plane[3] & mask) ? 8 : 0) | + ((plane[2] & mask) ? 4 : 0) | + ((plane[1] & mask) ? 2 : 0) | + ((plane[0] & mask) ? 1 : 0); + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = col; + } + if (x & 1) ++sigma->ma; + } +} + + + + + +/* Draw a line in the 320x200 graphics mode */ +void sigma_gfx4col(sigma_t *sigma) +{ + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + + (sigma->sc & 2) * 0x1000]; + uint8_t plane[4]; + uint8_t mask, col, c; + + for (x = 0; x < (sigma->crtc[1] << 1); x++) + { + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; + + mask = 0x80; + for (c = 0; c < 4; c++) + { + col = ((plane[3] & mask) ? 2 : 0) | + ((plane[2] & mask) ? 1 : 0); + mask = mask >> 1; + col |= ((plane[3] & mask) ? 8 : 0) | + ((plane[2] & mask) ? 4 : 0); + mask = mask >> 1; + + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + (c << 1) + 9] = col; + } + if (x & 1) ++sigma->ma; + } +} + + + + +void sigma_poll(void *p) +{ + sigma_t *sigma = (sigma_t *)p; + int x, c; + int oldvc; + uint32_t cols[4]; + int oldsc; + + if (!sigma->linepos) + { + sigma->vidtime += sigma->dispofftime; + sigma->sigmastat |= STATUS_RETR_H; + sigma->linepos = 1; + oldsc = sigma->sc; + if ((sigma->crtc[8] & 3) == 3) + sigma->sc = ((sigma->sc << 1) + sigma->oddeven) & 7; + if (sigma->cgadispon) + { + if (sigma->displine < sigma->firstline) + { + sigma->firstline = sigma->displine; + video_wait_for_buffer(); +// printf("Firstline %i\n",firstline); + } + sigma->lastline = sigma->displine; + + cols[0] = 0; + // Left overscan + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[sigma->displine])[c] = cols[0]; + if (sigma->sigmamode & MODE_80COLS) + ((uint32_t *)buffer32->line[sigma->displine])[c + (sigma->crtc[1] << 4) + 8] = cols[0]; + else + ((uint32_t *)buffer32->line[sigma->displine])[c + (sigma->crtc[1] << 5) + 8] = cols[0]; + } + if (sigma->sigmamode & MODE_GRAPHICS) + { + if (sigma->sigmamode & MODE_640x400) + { + sigma_gfx400(sigma); + } + else if (sigma->sigmamode & MODE_HRGFX) + { + sigma_gfx200(sigma); + } + else sigma_gfx4col(sigma); + + } + else /* Text modes */ + { + if (sigma->sigmamode & MODE_80COLS) + { + sigma_text80(sigma); + } + else + { + sigma_text40(sigma); + } + } + } + else + { + cols[0] = 0; + if (sigma->sigmamode & MODE_80COLS) + hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 4) + 16, cols[0]); + else hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 5) + 16, cols[0]); + } + + if (sigma->sigmamode & MODE_80COLS) + { + x = (sigma->crtc[1] << 4) + 16; + } + else + { + x = (sigma->crtc[1] << 5) + 16; + } + + for (c = 0; c < x; c++) + { + ((uint32_t *)buffer32->line[sigma->displine])[c] = cgapal[sigma->palette[((uint32_t *)buffer32->line[sigma->displine])[c] & 0xf]]; + } + + sigma->sc = oldsc; + if (sigma->vc == sigma->crtc[7] && !sigma->sc) + sigma->sigmastat |= STATUS_RETR_V; + sigma->displine++; + if (sigma->displine >= 560) + sigma->displine = 0; + } + else + { + sigma->vidtime += sigma->dispontime; + sigma->linepos = 0; + if (sigma->vsynctime) + { + sigma->vsynctime--; + if (!sigma->vsynctime) + sigma->sigmastat &= ~STATUS_RETR_V; + } + if (sigma->sc == (sigma->crtc[11] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) + { + sigma->con = 0; + sigma->coff = 1; + } + if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1)) + sigma->maback = sigma->ma; + if (sigma->vadj) + { + sigma->sc++; + sigma->sc &= 31; + sigma->ma = sigma->maback; + sigma->vadj--; + if (!sigma->vadj) + { + sigma->cgadispon = 1; + sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + sigma->sc = 0; + } + } + else if (sigma->sc == sigma->crtc[9]) + { + sigma->maback = sigma->ma; + sigma->sc = 0; + oldvc = sigma->vc; + sigma->vc++; + sigma->vc &= 127; + + if (sigma->vc == sigma->crtc[6]) + sigma->cgadispon = 0; + + if (oldvc == sigma->crtc[4]) + { + sigma->vc = 0; + sigma->vadj = sigma->crtc[5]; + if (!sigma->vadj) sigma->cgadispon = 1; + if (!sigma->vadj) sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + if ((sigma->crtc[10] & 0x60) == 0x20) sigma->cursoron = 0; + else sigma->cursoron = sigma->cgablink & 8; + } + + if (sigma->vc == sigma->crtc[7]) + { + sigma->cgadispon = 0; + sigma->displine = 0; + sigma->vsynctime = 16; + if (sigma->crtc[7]) + { + if (sigma->sigmamode & MODE_80COLS) + x = (sigma->crtc[1] << 4) + 16; + else + x = (sigma->crtc[1] << 5) + 16; + sigma->lastline++; + if (x != xsize || (sigma->lastline - sigma->firstline) != ysize) + { + xsize = x; + ysize = sigma->lastline - sigma->firstline; +// pclog("sigma: xsize := %d ysize := %d\n", xsize, ysize); + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize + 8); + } + + video_blit_memtoscreen(0, sigma->firstline - 4, 0, (sigma->lastline - sigma->firstline) + 8, xsize, (sigma->lastline - sigma->firstline) + 8); + frames++; + + video_res_x = xsize - 16; + video_res_y = ysize; + if (sigma->sigmamode & MODE_GRAPHICS) + { + if (sigma->sigmamode & (MODE_HRGFX | MODE_640x400)) + { + video_bpp = 1; + } + else + { + video_res_x /= 2; + video_bpp = 2; + } + } + else if (sigma->sigmamode & MODE_80COLS) + { +/* 80-column text */ + video_res_x /= 8; + video_res_y /= sigma->crtc[9] + 1; + video_bpp = 0; + } + else + { +/* 40-column text */ + video_res_x /= 16; + video_res_y /= sigma->crtc[9] + 1; + video_bpp = 0; + } + } + sigma->firstline = 1000; + sigma->lastline = 0; + sigma->cgablink++; + sigma->oddeven ^= 1; + } + } + else + { + sigma->sc++; + sigma->sc &= 31; + sigma->ma = sigma->maback; + } + if (sigma->cgadispon) + sigma->sigmastat &= ~STATUS_RETR_H; + if ((sigma->sc == (sigma->crtc[10] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[10] & 31) >> 1)))) + sigma->con = 1; + } +} + + + + +void *sigma_init() +{ + int display_type, contrast; + sigma_t *sigma = malloc(sizeof(sigma_t)); + memset(sigma, 0, sizeof(sigma_t)); + + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); + sigma->enable_nmi = device_get_config_int("enable_nmi"); + + loadfont("sigma400_font.rom", 7); + rom_init(&sigma->bios_rom, "sigma400_bios.rom", 0xC0000, 0x2000, + 0x1FFF, 0, MEM_MAPPING_EXTERNAL); + /* The BIOS ROM is overlaid by RAM, so remove its default mapping + * and access it through sigma_bread() / sigma_bwrite() below */ + mem_mapping_disable(&sigma->bios_rom.mapping); + + sigma->vram = malloc(0x8000 * 4); + + timer_add(sigma_poll, &sigma->vidtime, TIMER_ALWAYS_ENABLED, sigma); + mem_mapping_add(&sigma->mapping, 0xb8000, 0x08000, + sigma_read, NULL, NULL, + sigma_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, sigma); + mem_mapping_add(&sigma->bios_ram, 0xC1800, 0x0800, + sigma_bread, NULL, NULL, + sigma_bwrite, NULL, NULL, + sigma->bios_rom.rom, MEM_MAPPING_EXTERNAL, sigma); + io_sethandler(0x03d0, 0x0010, + sigma_in, NULL, NULL, + sigma_out, NULL, NULL, sigma); + io_sethandler(0x02d0, 0x0010, + sigma_in, NULL, NULL, + sigma_out, NULL, NULL, sigma); + + /* Start with ROM paged in, BIOS RAM paged out */ + sigma->rom_paged = 0x80; + + cgapal_rebuild(display_type, contrast); + + if (sigma->enable_nmi) + { + sigma->sigmastat = STATUS_LPEN_T; + } + return sigma; +} + +void sigma_close(void *p) +{ + sigma_t *sigma = (sigma_t *)p; + + free(sigma->vram); + free(sigma); +} + +void sigma_speed_changed(void *p) +{ + sigma_t *sigma = (sigma_t *)p; + + sigma_recalctimings(sigma); +} + +device_config_t sigma_config[] = +{ + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "RGB", + .value = DISPLAY_RGB + }, + { + .description = "RGB (no brown)", + .value = DISPLAY_RGB_NO_BROWN + }, + { + .description = "Green Monochrome", + .value = DISPLAY_GREEN + }, + { + .description = "Amber Monochrome", + .value = DISPLAY_AMBER + }, + { + .description = "White Monochrome", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + }, + .default_int = DISPLAY_RGB + }, + { + .name = "enable_nmi", + .description = "Enable NMI for CGA emulation", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "contrast", + .description = "Alternate monochrome contrast", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .type = -1 + } +}; + +device_t sigma_device = +{ + "Sigma Color 400", + 0, + sigma_init, + sigma_close, + NULL, + sigma_speed_changed, + NULL, + NULL, + sigma_config +}; diff --git a/src/vid_sigma.h b/src/vid_sigma.h new file mode 100644 index 0000000..f59088e --- /dev/null +++ b/src/vid_sigma.h @@ -0,0 +1,2 @@ +extern device_t sigma_device; + diff --git a/src/video.c b/src/video.c index 49c8ea0..b004e7e 100644 --- a/src/video.c +++ b/src/video.c @@ -37,6 +37,7 @@ #include "vid_ps1_svga.h" #include "vid_s3.h" #include "vid_s3_virge.h" +#include "vid_sigma.h" #include "vid_tandy.h" #include "vid_tandysl.h" #include "vid_tgui9440.h" @@ -103,6 +104,7 @@ static VIDEO_CARD video_cards[] = {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, + {"Sigma Color 400", "sigma400", &sigma_device, GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, @@ -891,7 +893,19 @@ void loadfont(char *s, int format) } } break; - + case 7: /* Sigma Color 400 */ + /* The first 4k of the character ROM holds an 8x8 font */ + for (c = 0; c < 256; c++) + { + fread(&fontdat[c][0], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + /* The second 4k holds an 8x16 font */ + for (c = 0; c < 256; c++) + { + fread(&fontdatm[c][0], 1, 16, f); + } + break; } fclose(f); } From 0055238ade02112d56526be97f0796bc710360c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 14 Nov 2018 21:42:20 +0000 Subject: [PATCH 0526/1050] Added recompiled versions of FCOM, FCOMP, FCOMPP, FICOM, FICOM, FUCOM, FUCOMP and FUCOMPP. --- src/codegen_backend_arm64_ops.c | 21 +++++ src/codegen_backend_arm64_ops.h | 6 ++ src/codegen_backend_arm64_uops.c | 23 +++++ src/codegen_backend_arm_ops.c | 39 ++++----- src/codegen_backend_arm_ops.h | 30 ++++++- src/codegen_backend_arm_uops.c | 20 +++++ src/codegen_backend_x86-64_ops.c | 10 +++ src/codegen_backend_x86-64_ops.h | 4 + src/codegen_backend_x86-64_uops.c | 26 ++++++ src/codegen_backend_x86_ops.c | 10 +++ src/codegen_backend_x86_ops.h | 4 + src/codegen_backend_x86_uops.c | 28 +++++- src/codegen_ir_defs.h | 5 +- src/codegen_ops.c | 68 +++++++-------- src/codegen_ops_fpu_arith.c | 138 ++++++++++++++++++++++++++++++ src/codegen_ops_fpu_arith.h | 14 +++ src/x87.h | 5 ++ src/x87_ops.h | 5 -- 18 files changed, 390 insertions(+), 66 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index d3d62c2..724ea8b 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -44,6 +44,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define COND_GT (0xc) #define COND_LE (0xd) +#define CSEL_COND(cond) ((cond) << 12) #define OPCODE_SHIFT 24 #define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) @@ -93,6 +94,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_AND_ROR (0x056 << 21) #define OPCODE_ANDS_LSL (0x350 << 21) #define OPCODE_CMP_LSL (0x358 << 21) +#define OPCODE_CSEL (0x0d4 << 21) #define OPCODE_EOR_LSL (0x250 << 21) #define OPCODE_ORR_ASR (0x154 << 21) #define OPCODE_ORR_LSL (0x150 << 21) @@ -106,6 +108,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BLR (0xd63f0000) #define OPCODE_BR (0xd61f0000) #define OPCODE_FADD_D (0x1e602800) +#define OPCODE_FCMP_D (0x1e602000) #define OPCODE_FCVT_D_S (0x1e22c000) #define OPCODE_FCVT_S_D (0x1e624000) #define OPCODE_FCVTMS_W_D (0x1e700000) @@ -525,6 +528,19 @@ void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, in codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ @@ -547,6 +563,11 @@ void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 3409335..ccccae6 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -50,10 +50,16 @@ void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data); #define host_arm64_CMP_REG(block, src_n_reg, src_m_reg) host_arm64_CMP_REG_LSL(block, src_n_reg, src_m_reg, 0) void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift); + +void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg); void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 649c72f..1d8aec5 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "x86.h" +#include "x87.h" #include "386_common.h" #include "codegen.h" #include "codegen_backend.h" @@ -613,6 +614,27 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, src_reg_b); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} static int codegen_FDIV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1816,6 +1838,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 98653e7..85d3646 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -31,23 +31,6 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define DATA_OFFSET_UP (1 << 23) #define DATA_OFFSET_DOWN (0 << 23) -#define COND_SHIFT 28 -#define COND_EQ (0x0 << COND_SHIFT) -#define COND_NE (0x1 << COND_SHIFT) -#define COND_CS (0x2 << COND_SHIFT) -#define COND_CC (0x3 << COND_SHIFT) -#define COND_MI (0x4 << COND_SHIFT) -#define COND_PL (0x5 << COND_SHIFT) -#define COND_VS (0x6 << COND_SHIFT) -#define COND_VC (0x7 << COND_SHIFT) -#define COND_HI (0x8 << COND_SHIFT) -#define COND_LS (0x9 << COND_SHIFT) -#define COND_GE (0xa << COND_SHIFT) -#define COND_LT (0xb << COND_SHIFT) -#define COND_GT (0xc << COND_SHIFT) -#define COND_LE (0xd << COND_SHIFT) -#define COND_AL (0xe << COND_SHIFT) - #define OPCODE_SHIFT 20 #define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) #define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) @@ -104,6 +87,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VADD 0xee300b00 +#define OPCODE_VCMP_D 0xeeb40b40 #define OPCODE_VCVT_D_IS 0xeeb80bc0 #define OPCODE_VCVT_D_S 0xeeb70ac0 #define OPCODE_VCVT_IS_D 0xeebd0bc0 @@ -117,6 +101,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMOV_D_64 0xec400b10 #define OPCODE_VMOV_S_32 0xee000a10 #define OPCODE_VMOV_D_D 0xeeb00b40 +#define OPCODE_VMRS_APSR 0xeef1fa10 #define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 #define OPCODE_VSTR_D 0xed800b00 @@ -208,7 +193,7 @@ static inline int in_range(void *addr, void *base) void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +//void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) @@ -614,24 +599,24 @@ void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) { uint32_t arm_imm; if (get_arm_imm(imm, &arm_imm)) { - codegen_addlong(block, COND_AL | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); } else { host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ORR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); } } -void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) @@ -765,6 +750,10 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); +} void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); @@ -825,6 +814,10 @@ void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); } +void host_arm_VMRS_APSR(codeblock_t *block) +{ + codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); +} void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 478d232..1fdd609 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -1,3 +1,20 @@ +#define COND_SHIFT 28 +#define COND_EQ (0x0 << COND_SHIFT) +#define COND_NE (0x1 << COND_SHIFT) +#define COND_CS (0x2 << COND_SHIFT) +#define COND_CC (0x3 << COND_SHIFT) +#define COND_MI (0x4 << COND_SHIFT) +#define COND_PL (0x5 << COND_SHIFT) +#define COND_VS (0x6 << COND_SHIFT) +#define COND_VC (0x7 << COND_SHIFT) +#define COND_HI (0x8 << COND_SHIFT) +#define COND_LS (0x9 << COND_SHIFT) +#define COND_GE (0xa << COND_SHIFT) +#define COND_LT (0xb << COND_SHIFT) +#define COND_GT (0xc << COND_SHIFT) +#define COND_LE (0xd << COND_SHIFT) +#define COND_AL (0xe << COND_SHIFT) + void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); #define host_arm_ADD_REG(block, dst_reg, src_reg_n, src_reg_m) host_arm_ADD_REG_LSL(block, dst_reg, src_reg_n, src_reg_m, 0) void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); @@ -77,8 +94,15 @@ void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm); void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift); -void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); -void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm); +void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift); + +#define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm) +#define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift) + +#define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm) +#define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) +#define host_arm_ORRVS_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_VS, dst_reg, src_reg, imm) void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); @@ -116,6 +140,7 @@ void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m); void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); @@ -129,6 +154,7 @@ void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high); void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VMRS_APSR(codeblock_t *block); void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 5b00a61..08ae666 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -689,6 +689,25 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + host_arm_VCMP_D(block, src_reg_a, src_reg_b); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); + } + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} static int codegen_FDIV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1938,6 +1957,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index bfa71d1..c3f1b90 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -341,6 +341,11 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); +} + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ @@ -497,6 +502,11 @@ uint32_t *host_x86_JZ_long(codeblock_t *block) return (uint32_t *)&block->data[block_pos-4]; } +void host_x86_LAHF(codeblock_t *block) +{ + codegen_addbyte(block, 0x9f); /*LAHF*/ +} + void host_x86_LDMXCSR(codeblock_t *block, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 5c9e298..ee7a82e 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -27,6 +27,8 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -61,6 +63,8 @@ uint32_t *host_x86_JO_long(codeblock_t *block); uint32_t *host_x86_JS_long(codeblock_t *block); uint32_t *host_x86_JZ_long(codeblock_t *block); +void host_x86_LAHF(codeblock_t *block); + void host_x86_LDMXCSR(codeblock_t *block, void *p); void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 5c54d8a..4fd1768 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "x86.h" +#include "x87.h" #include "386_common.h" #include "codegen.h" #include "codegen_backend.h" @@ -542,6 +543,30 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + if (dest_reg != REG_EAX) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} static int codegen_FDIV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1617,6 +1642,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index d68f203..0dace79 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -309,6 +309,11 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); +} + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ @@ -462,6 +467,11 @@ uint32_t *host_x86_JZ_long(codeblock_t *block) return (uint32_t *)&block->data[block_pos-4]; } +void host_x86_LAHF(codeblock_t *block) +{ + codegen_addbyte(block, 0x9f); /*LAHF*/ +} + void host_x86_LDMXCSR(codeblock_t *block, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 943ba40..96ace96 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -27,6 +27,8 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -63,6 +65,8 @@ uint32_t *host_x86_JO_long(codeblock_t *block); uint32_t *host_x86_JS_long(codeblock_t *block); uint32_t *host_x86_JZ_long(codeblock_t *block); +void host_x86_LAHF(codeblock_t *block); + void host_x86_LDMXCSR(codeblock_t *block, void *p); void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32_t offset); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 8537c3d..9ef533e 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "x86.h" +#include "x87.h" #include "386_common.h" #include "codegen.h" #include "codegen_backend.h" @@ -553,6 +554,30 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) + { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + if (dest_reg != REG_EAX) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} static int codegen_FDIV(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1622,7 +1647,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FADD & UOP_MASK] = codegen_FADD, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FCOM & UOP_MASK] = codegen_FCOM }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index d893067..998017b 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -177,8 +177,10 @@ #define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) /*UOP_FDIV - (floating point) dest_reg = src_reg_a / src_reg_b*/ #define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) +/*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/ +#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) -#define UOP_MAX 0x85 +#define UOP_MAX 0x86 #define UOP_MASK 0xffff @@ -481,6 +483,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) #define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FCOM(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FCOM, ir, dst_reg, src_reg_a, src_reg_b) #define uop_FDIV(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FDIV, ir, dst_reg, src_reg_a, src_reg_b) #define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) #define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index a36bd40..347a32e 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -115,44 +115,44 @@ RecompOpFn recomp_opcodes_d8[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, /*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, /*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, /*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, /*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, /*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, /*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, /*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, /*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, /*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, /*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, /*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, /*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, }; @@ -209,44 +209,44 @@ RecompOpFn recomp_opcodes_da[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, /*20*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, /*30*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, /*40*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, /*60*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, /*70*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, /*80*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, /*a0*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, /*b0*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFUCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, /*20*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, /*30*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, /*40*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, /*60*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, /*70*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, /*80*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, /*a0*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, /*b0*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFUCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; @@ -303,44 +303,44 @@ RecompOpFn recomp_opcodes_dc[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, /*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, /*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, /*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, /*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, /*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, /*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, /*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, /*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, /*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, /*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, /*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, /*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, }; @@ -366,7 +366,7 @@ RecompOpFn recomp_opcodes_dd[512] = /*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ @@ -388,7 +388,7 @@ RecompOpFn recomp_opcodes_dd[512] = /*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; @@ -397,44 +397,44 @@ RecompOpFn recomp_opcodes_de[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, /*20*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, /*30*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*40*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, /*60*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, /*70*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*80*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, /*a0*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, /*b0*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, /*20*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, /*30*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*40*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, /*60*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, /*70*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*80*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, /*a0*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, /*b0*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, /*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, }; diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index ae62746..d903959 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -43,6 +43,41 @@ uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return op_pc; } +uint32_t ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + + return op_pc; +} +uint32_t ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(ir); + + return op_pc; +} +uint32_t ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(ir); + fpu_POP(ir); + + return op_pc; +} + uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = fetchdat & 7; @@ -201,6 +236,41 @@ uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } +uint32_t ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + + return op_pc; +} +uint32_t ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7; + + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(ir); + + return op_pc; +} +uint32_t ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(ir); + fpu_POP(ir); + + return op_pc; +} + #define ropF_arith_mem(name, load_uop) \ uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ @@ -217,6 +287,39 @@ uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint \ return op_pc+1; \ } \ +uint32_t ropFCOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFCOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(ir); \ + \ + return op_pc+1; \ +} \ uint32_t ropFDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ x86seg *target_seg; \ @@ -313,6 +416,41 @@ uint32_t ropFIADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uin \ return op_pc+1; \ } \ +uint32_t ropFICOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc+1; \ +} \ +uint32_t ropFICOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(ir); \ + \ + return op_pc+1; \ +} \ uint32_t ropFIDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ x86seg *target_seg; \ diff --git a/src/codegen_ops_fpu_arith.h b/src/codegen_ops_fpu_arith.h index 2cbafb7..e61d4ae 100644 --- a/src/codegen_ops_fpu_arith.h +++ b/src/codegen_ops_fpu_arith.h @@ -1,6 +1,9 @@ uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); @@ -16,9 +19,16 @@ uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFADDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFADDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOMs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOMd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOMPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCOMPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFDIVRs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); @@ -32,6 +42,10 @@ uint32_t ropFSUBRd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropFIADDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFIADDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFICOMl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFICOMw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFICOMPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFICOMPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFIDIVl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFIDIVw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFIDIVRl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/x87.h b/src/x87.h index 3960efa..2ec4405 100644 --- a/src/x87.h +++ b/src/x87.h @@ -1,3 +1,8 @@ +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + uint32_t x87_pc_off,x87_op_off; uint16_t x87_pc_seg,x87_op_seg; diff --git a/src/x87_ops.h b/src/x87_ops.h index b1cc843..1208854 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -7,11 +7,6 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ #define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) - #define STATUS_ZERODIVIDE 4 #define x87_div(dst, src1, src2) do \ From 964b20e8202287b34e174ca1f588a01afa68c279 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 14 Nov 2018 21:43:22 +0000 Subject: [PATCH 0527/1050] Added recompiled versions of FLD1 and FLDZ. --- src/codegen_ops.c | 4 ++-- src/codegen_ops_fpu_constant.c | 33 +++++++++++++++++++++++++++++++++ src/codegen_ops_fpu_constant.h | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/codegen_ops_fpu_constant.c create mode 100644 src/codegen_ops_fpu_constant.h diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 347a32e..a2d6fb1 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -178,7 +178,7 @@ RecompOpFn recomp_opcodes_d9[512] = /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ @@ -200,7 +200,7 @@ RecompOpFn recomp_opcodes_d9[512] = /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; diff --git a/src/codegen_ops_fpu_constant.c b/src/codegen_ops_fpu_constant.c new file mode 100644 index 0000000..187850c --- /dev/null +++ b/src/codegen_ops_fpu_constant.c @@ -0,0 +1,33 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "x87.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_fpu_constant.h" +#include "codegen_ops_helpers.h" + +uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 1); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(ir); + + return op_pc; +} +uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 0); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(ir); + + return op_pc; +} diff --git a/src/codegen_ops_fpu_constant.h b/src/codegen_ops_fpu_constant.h new file mode 100644 index 0000000..29384b5 --- /dev/null +++ b/src/codegen_ops_fpu_constant.h @@ -0,0 +1,2 @@ +uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From fa4ccece48e4951abd001fbb0ab162d8b97d9175 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Nov 2018 09:40:54 +0000 Subject: [PATCH 0528/1050] Fixed pixel clock on S3 ViRGE. --- src/vid_s3_virge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 7f2b72e..a7059e0 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -643,7 +643,7 @@ static void s3_virge_recalctimings(svga_t *svga) int m = svga->seqregs[0x13] & 0x7f; double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; - svga->clock = cpuclock / freq; + svga->clock = (cpuclock * (float)(1ull << 32)) / freq; } } From e557bda696228970906563da85ae43f4810f17b1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Nov 2018 10:40:38 +0000 Subject: [PATCH 0529/1050] Fixed DIP switch value for AMA932J's built-in OTI067. Fixes colour/black and white switch. Patch from Greatpsycho. --- src/vid_oti067.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 400fcf2..8494e6d 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -26,8 +26,6 @@ typedef struct oti067_t uint32_t vram_mask; } oti067_t; -static uint8_t oti067_dipswitch_val = 0x18; - void oti067_out(uint16_t addr, uint8_t val, void *p) { oti067_t *oti067 = (oti067_t *)p; @@ -114,7 +112,7 @@ uint8_t oti067_in(uint16_t addr, void *p) temp = oti067->index | (2 << 5); break; case 0x3DF: - if (oti067->index==0x10) temp = oti067_dipswitch_val; + if (oti067->index==0x10) temp = oti067->dipswitch_val; else temp = oti067->regs[oti067->index]; break; @@ -177,6 +175,8 @@ void *oti067_common_init(char *bios_fn, int vram_size) io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); oti067->svga.miscout = 1; + + oti067->dipswitch_val = 0x18; return oti067; } @@ -195,8 +195,6 @@ void oti067_enable_disable(void *p, int enable) io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); mem_mapping_enable(&oti067->svga.mapping); } - - oti067->dipswitch_val = 0x18; } void *oti067_init() From e0fd70b4a2e9c7c5d02a06c6d8a3785127756914 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Nov 2018 10:44:38 +0000 Subject: [PATCH 0530/1050] Correct keyboard scancode set used for key repeat. Patch from Tale. --- src/keyboard.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index 2d3135f..cb00df5 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -283,13 +283,13 @@ void keyboard_process() if (keydelay[c] >= 30) { keydelay[c] -= 10; - if (scancode_set1[c].scancodes_make[0] == -1) + if (scancodes[c].scancodes_make[0] == -1) continue; d = 0; - while (scancode_set1[c].scancodes_make[d] != -1) - keyboard_send(scancode_set1[c].scancodes_make[d++]); + while (scancodes[c].scancodes_make[d] != -1) + keyboard_send(scancodes[c].scancodes_make[d++]); } } } From 59d5ce4a507de2306501bf6ad18474c115ef6a68 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 20 Nov 2018 10:50:21 +0000 Subject: [PATCH 0531/1050] Reduce keyboard scancode and state arrays from int to uint8_t. Patch from Tale. --- src/keyboard.c | 428 ++++++++++++++++++++--------------------- src/keyboard.h | 2 +- src/plat-keyboard.h | 4 +- src/wx-sdl2-keyboard.c | 2 +- 4 files changed, 219 insertions(+), 217 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index cb00df5..27213d0 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6,233 +6,233 @@ int keybsendcallback = 0; typedef struct { - int scancodes_make[8]; - int scancodes_break[8]; + uint8_t scancodes_make[8]; + uint8_t scancodes_break[8]; } scancode; /*272 = 256 + 16 fake interim scancodes for disambiguation purposes.*/ static scancode scancode_set1[272] = { - { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, - { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, { {0x06, -1}, {0x86, -1} }, { {0x07, -1}, {0x87, -1} }, - { {0x08, -1}, {0x88, -1} }, { {0x09, -1}, {0x89, -1} }, { {0x0a, -1}, {0x8a, -1} }, { {0x0b, -1}, {0x8b, -1} }, - { {0x0c, -1}, {0x8c, -1} }, { {0x0d, -1}, {0x8d, -1} }, { {0x0e, -1}, {0x8e, -1} }, { {0x0f, -1}, {0x8f, -1} }, - { {0x10, -1}, {0x90, -1} }, { {0x11, -1}, {0x91, -1} }, { {0x12, -1}, {0x92, -1} }, { {0x13, -1}, {0x93, -1} }, - { {0x14, -1}, {0x94, -1} }, { {0x15, -1}, {0x95, -1} }, { {0x16, -1}, {0x96, -1} }, { {0x17, -1}, {0x97, -1} }, - { {0x18, -1}, {0x98, -1} }, { {0x19, -1}, {0x99, -1} }, { {0x1a, -1}, {0x9a, -1} }, { {0x1b, -1}, {0x9b, -1} }, - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, { {0x1e, -1}, {0x9e, -1} }, { {0x1f, -1}, {0x9f, -1} }, - { {0x20, -1}, {0xa0, -1} }, { {0x21, -1}, {0xa1, -1} }, { {0x22, -1}, {0xa2, -1} }, { {0x23, -1}, {0xa3, -1} }, - { {0x24, -1}, {0xa4, -1} }, { {0x25, -1}, {0xa5, -1} }, { {0x26, -1}, {0xa6, -1} }, { {0x27, -1}, {0xa7, -1} }, - { {0x28, -1}, {0xa8, -1} }, { {0x29, -1}, {0xa9, -1} }, { {0x2a, -1}, {0xaa, -1} }, { {0x2b, -1}, {0xab, -1} }, - { {0x2c, -1}, {0xac, -1} }, { {0x2d, -1}, {0xad, -1} }, { {0x2e, -1}, {0xae, -1} }, { {0x2f, -1}, {0xaf, -1} }, - { {0x30, -1}, {0xb0, -1} }, { {0x31, -1}, {0xb1, -1} }, { {0x32, -1}, {0xb2, -1} }, { {0x33, -1}, {0xb3, -1} }, - { {0x34, -1}, {0xb4, -1} }, { {0x35, -1}, {0xb5, -1} }, { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, - { {0x38, -1}, {0xb8, -1} }, { {0x39, -1}, {0xb9, -1} }, { {0x3a, -1}, {0xba, -1} }, { {0x3b, -1}, {0xbb, -1} }, - { {0x3c, -1}, {0xbc, -1} }, { {0x3d, -1}, {0xbd, -1} }, { {0x3e, -1}, {0xbe, -1} }, { {0x3f, -1}, {0xbf, -1} }, - { {0x40, -1}, {0xc0, -1} }, { {0x41, -1}, {0xc1, -1} }, { {0x42, -1}, {0xc2, -1} }, { {0x43, -1}, {0xc3, -1} }, - { {0x44, -1}, {0xc4, -1} }, { {0x45, -1}, {0xc5, -1} }, { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, { {0x4a, -1}, {0xca, -1} }, { {0x4b, -1}, {0xcb, -1} }, - { {0x4c, -1}, {0xcc, -1} }, { {0x4d, -1}, {0xcd, -1} }, { {0x4e, -1}, {0xce, -1} }, { {0x4f, -1}, {0xcf, -1} }, - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, - { {0x54, -1}, {0xd4, -1} }, { {0x55, -1}, {0xd5, -1} }, { {0x56, -1}, {0xd6, -1} }, { {0x57, -1}, {0xd7, -1} }, - { {0x58, -1}, {0xd8, -1} }, { {0x59, -1}, {0xd9, -1} }, { {0x5a, -1}, {0xda, -1} }, { {0x5b, -1}, {0xdb, -1} }, - { {0x5c, -1}, {0xdc, -1} }, { {0x5d, -1}, {0xdd, -1} }, { {0x5e, -1}, {0xde, -1} }, { {0x5f, -1}, {0xdf, -1} }, - { {0x60, -1}, {0xe0, -1} }, { {0x61, -1}, {0xe1, -1} }, { {0x62, -1}, {0xe2, -1} }, { {0x63, -1}, {0xe3, -1} }, - { {0x64, -1}, {0xe4, -1} }, { {0x65, -1}, {0xe5, -1} }, { {0x66, -1}, {0xe6, -1} }, { {0x67, -1}, {0xe7, -1} }, - { {0x68, -1}, {0xe8, -1} }, { {0x69, -1}, {0xe9, -1} }, { {0x6a, -1}, {0xea, -1} }, { {0x6b, -1}, {0xeb, -1} }, - { {0x6c, -1}, {0xec, -1} }, { {0x6d, -1}, {0xed, -1} }, { {0x6e, -1}, {0xee, -1} }, { {0x6f, -1}, {0xef, -1} }, - { {0x70, -1}, {0xf0, -1} }, { {0x71, -1}, {0xf1, -1} }, { {0x72, -1}, {0xf2, -1} }, { {0x73, -1}, {0xf3, -1} }, - { {0x74, -1}, {0xf4, -1} }, { {0x75, -1}, {0xf5, -1} }, { {0x76, -1}, {0xf6, -1} }, { {0x77, -1}, {0xf7, -1} }, - { {0x78, -1}, {0xf8, -1} }, { {0x79, -1}, {0xf9, -1} }, { {0x7a, -1}, {0xfa, -1} }, { {0x7b, -1}, {0xfb, -1} }, - { {0x7c, -1}, {0xfc, -1} }, { {0x7d, -1}, {0xfd, -1} }, { {0x7e, -1}, {0xfe, -1} }, { {0x7f, -1}, {0xff, -1} }, + { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, + { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, + { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, + { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, + { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, + { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, + { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, + { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, + { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, + { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, + { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, + { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, + { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, + { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, + { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, + { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, + { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, + { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, + { {0x54, 0}, {0xd4, 0} }, { {0x55, 0}, {0xd5, 0} }, { {0x56, 0}, {0xd6, 0} }, { {0x57, 0}, {0xd7, 0} }, + { {0x58, 0}, {0xd8, 0} }, { {0x59, 0}, {0xd9, 0} }, { {0x5a, 0}, {0xda, 0} }, { {0x5b, 0}, {0xdb, 0} }, + { {0x5c, 0}, {0xdc, 0} }, { {0x5d, 0}, {0xdd, 0} }, { {0x5e, 0}, {0xde, 0} }, { {0x5f, 0}, {0xdf, 0} }, + { {0x60, 0}, {0xe0, 0} }, { {0x61, 0}, {0xe1, 0} }, { {0x62, 0}, {0xe2, 0} }, { {0x63, 0}, {0xe3, 0} }, + { {0x64, 0}, {0xe4, 0} }, { {0x65, 0}, {0xe5, 0} }, { {0x66, 0}, {0xe6, 0} }, { {0x67, 0}, {0xe7, 0} }, + { {0x68, 0}, {0xe8, 0} }, { {0x69, 0}, {0xe9, 0} }, { {0x6a, 0}, {0xea, 0} }, { {0x6b, 0}, {0xeb, 0} }, + { {0x6c, 0}, {0xec, 0} }, { {0x6d, 0}, {0xed, 0} }, { {0x6e, 0}, {0xee, 0} }, { {0x6f, 0}, {0xef, 0} }, + { {0x70, 0}, {0xf0, 0} }, { {0x71, 0}, {0xf1, 0} }, { {0x72, 0}, {0xf2, 0} }, { {0x73, 0}, {0xf3, 0} }, + { {0x74, 0}, {0xf4, 0} }, { {0x75, 0}, {0xf5, 0} }, { {0x76, 0}, {0xf6, 0} }, { {0x77, 0}, {0xf7, 0} }, + { {0x78, 0}, {0xf8, 0} }, { {0x79, 0}, {0xf9, 0} }, { {0x7a, 0}, {0xfa, 0} }, { {0x7b, 0}, {0xfb, 0} }, + { {0x7c, 0}, {0xfc, 0} }, { {0x7d, 0}, {0xfd, 0} }, { {0x7e, 0}, {0xfe, 0} }, { {0x7f, 0}, {0xff, 0} }, - { {0x80, -1}, {-1} }, { {0x81, -1}, {-1} }, { {0x82, -1}, {-1} }, { {0xe0, 0x03, -1}, {0xe0, 0x83, -1} }, /*80*/ - { {0xe0, 0x04, -1}, {0xe0, 0x84, -1} }, { {0x85, -1}, {-1} }, { {0x86, -1}, {-1} }, { {0x87, -1}, {-1} }, /*84*/ - { {0xe0, 0x08, -1}, {0xe0, 0x88, -1} }, { {0xe0, 0x09, -1}, {0xe0, 0x89, -1} }, { {0xe0, 0x0a, -1}, {0xe0, 0x8a, -1} }, { {0xe0, 0x0b, -1}, {0xe0, 0x8b, -1} }, /*88*/ - { {0xe0, 0x0c, -1}, {0xe0, 0x8c, -1} }, { {-1}, {-1} }, { {0xe0, 0x0e, -1}, {0xe0, 0x8e, -1} }, { {0xe0, 0x0f, -1}, {0xe0, 0x8f, -1} }, /*8c*/ - { {0xe0, 0x10, -1}, {0xe0, 0x90, -1} }, { {0xe0, 0x11, -1}, {0xe0, 0x91, -1} }, { {0xe0, 0x12, -1}, {0xe0, 0x92, -1} }, { {0xe0, 0x13, -1}, {0xe0, 0x93, -1} }, /*90*/ - { {0xe0, 0x14, -1}, {0xe0, 0x94, -1} }, { {0xe0, 0x15, -1}, {0xe0, 0x95, -1} }, { {0xe0, 0x16, -1}, {0xe0, 0x96, -1} }, { {0xe0, 0x17, -1}, {0xe0, 0x97, -1} }, /*94*/ - { {0xe0, 0x18, -1}, {0xe0, 0x98, -1} }, { {0xe0, 0x19, -1}, {0xe0, 0x99, -1} }, { {0xe0, 0x1a, -1}, {0xe0, 0x9a, -1} }, { {0xe0, 0x1b, -1}, {0xe0, 0x9b, -1} }, /*98*/ - { {0xe0, 0x1c, -1}, {0xe0, 0x9c, -1} }, { {0xe0, 0x1d, -1}, {0xe0, 0x9d, -1} }, { {0xe0, 0x1e, -1}, {0xe0, 0x9e, -1} }, { {0xe0, 0x1f, -1}, {0xe0, 0x9f, -1} }, /*9c*/ - { {0xe0, 0x20, -1}, {0xe0, 0xa0, -1} }, { {0xe0, 0x21, -1}, {0xe0, 0xa1, -1} }, { {0xe0, 0x22, -1}, {0xe0, 0xa2, -1} }, { {0xe0, 0x23, -1}, {0xe0, 0xa3, -1} }, /*a0*/ - { {0xe0, 0x24, -1}, {0xe0, 0xa4, -1} }, { {0xe0, 0x25, -1}, {0xe0, 0xa5, -1} }, { {0xe0, 0x26, -1}, {0xe0, 0xa6, -1} }, { {-1}, {-1} }, /*a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {0xe0, 0x2a, -1}, {0xe0, 0xaa, -1} }, { {-1}, {-1} }, /*a8*/ - { {0xe0, 0x2c, -1}, {0xe0, 0xac, -1} }, { {0xe0, 0x2d, -1}, {0xe0, 0xad, -1} }, { {0xe0, 0x2e, -1}, {0xe0, 0xae, -1} }, { {0xe0, 0x2f, -1}, {0xe0, 0xaf, -1} }, /*ac*/ - { {0xe0, 0x30, -1}, {0xe0, 0xb0, -1} }, { {0xe0, 0x31, -1}, {0xe0, 0xb1, -1} }, { {0xe0, 0x32, -1}, {0xe0, 0xb2, -1} }, { {-1}, {-1} }, /*b0*/ - { {0xe0, 0x34, -1}, {0xe0, 0xb4, -1} }, { {0xe0, 0x35, -1}, {0xe0, 0xb5, -1} }, { {0xe0, 0x36, -1}, {0xe0, 0xb6, -1} }, { {0xe0, 0x37, -1}, {0xe0, 0xb7, -1} }, /*b4*/ - { {0xe0, 0x38, -1}, {0xe0, 0xb8, -1} }, { {-1}, {-1} }, { {0xe0, 0x3a, -1}, {0xe0, 0xba, -1} }, { {0xe0, 0x3b, -1}, {0xe0, 0xbb, -1} }, /*b8*/ - { {0xe0, 0x3c, -1}, {0xe0, 0xbc, -1} }, { {0xe0, 0x3d, -1}, {0xe0, 0xbd, -1} }, { {0xe0, 0x3e, -1}, {0xe0, 0xbe, -1} }, { {0xe0, 0x3f, -1}, {0xe0, 0xbf, -1} }, /*bc*/ - { {0xe0, 0x40, -1}, {0xe0, 0xc0, -1} }, { {0xe0, 0x41, -1}, {0xe0, 0xc1, -1} }, { {0xe0, 0x42, -1}, {0xe0, 0xc2, -1} }, { {0xe0, 0x43, -1}, {0xe0, 0xc3, -1} }, /*c0*/ - { {0xe0, 0x44, -1}, {0xe0, 0xc4, -1} }, { {-1}, {-1} }, { {0xe0, 0x46, -1}, {0xe0, 0xc6, -1} }, { {0xe0, 0x47, -1}, {0xe0, 0xc7, -1} }, /*c4*/ - { {0xe0, 0x48, -1}, {0xe0, 0xc8, -1} }, { {0xe0, 0x49, -1}, {0xe0, 0xc9, -1} }, { {-1}, {-1} }, { {0xe0, 0x4b, -1}, {0xe0, 0xcb, -1} }, /*c8*/ - { {0xe0, 0x4c, -1}, {0xe0, 0xcc, -1} }, { {0xe0, 0x4d, -1}, {0xe0, 0xcd, -1} }, { {0xe0, 0x4e, -1}, {0xe0, 0xce, -1} }, { {0xe0, 0x4f, -1}, {0xe0, 0xcf, -1} }, /*cc*/ - { {0xe0, 0x50, -1}, {0xe0, 0xd0, -1} }, { {0xe0, 0x51, -1}, {0xe0, 0xd1, -1} }, { {0xe0, 0x52, -1}, {0xe0, 0xd2, -1} }, { {0xe0, 0x53, -1}, {0xe0, 0xd3, -1} }, /*d0*/ - { {0xd4, -1}, {-1} }, { {0xe0, 0x55, -1}, {0xe0, 0xd5, -1} }, { {-1}, {-1} }, { {0xe0, 0x57, -1}, {0xe0, 0xd7, -1} }, /*d4*/ - { {0xe0, 0x58, -1}, {0xe0, 0xd8, -1} }, { {0xe0, 0x59, -1}, {0xe0, 0xd9, -1} }, { {0xe0, 0x5a, -1}, {0xe0, 0xaa, -1} }, { {0xe0, 0x5b, -1}, {0xe0, 0xdb, -1} }, /*d8*/ - { {0xe0, 0x5c, -1}, {0xe0, 0xdc, -1} }, { {0xe0, 0x5d, -1}, {0xe0, 0xdd, -1} }, { {0xe0, 0x5e, -1}, {0xe0, 0xee, -1} }, { {0xe0, 0x5f, -1}, {0xe0, 0xdf, -1} }, /*dc*/ - { {-1}, {-1} }, { {0xe0, 0x61, -1}, {0xe0, 0xe1, -1} }, { {0xe0, 0x62, -1}, {0xe0, 0xe2, -1} }, { {0xe0, 0x63, -1}, {0xe0, 0xe3, -1} }, /*e0*/ - { {0xe0, 0x64, -1}, {0xe0, 0xe4, -1} }, { {0xe0, 0x65, -1}, {0xe0, 0xe5, -1} }, { {0xe0, 0x66, -1}, {0xe0, 0xe6, -1} }, { {0xe0, 0x67, -1}, {0xe0, 0xe7, -1} }, /*e4*/ - { {0xe0, 0x68, -1}, {0xe0, 0xe8, -1} }, { {0xe0, 0x69, -1}, {0xe0, 0xe9, -1} }, { {0xe0, 0x6a, -1}, {0xe0, 0xea, -1} }, { {0xe0, 0x6b, -1}, {0xe0, 0xeb, -1} }, /*e8*/ - { {0xe0, 0x6c, -1}, {0xe0, 0xec, -1} }, { {0xe0, 0x6d, -1}, {0xe0, 0xed, -1} }, { {0xe0, 0x6e, -1}, {0xe0, 0xee, -1} }, { {-1}, {-1} }, /*ec*/ - { {0xe0, 0x70, -1}, {0xe0, 0xf0, -1} }, { {0xf1, -1}, {-1} }, { {0xf2, -1}, {-1} }, { {0xe0, 0x73, -1}, {0xe0, 0xf3, -1} }, /*f0*/ - { {0xe0, 0x74, -1}, {0xe0, 0xf4, -1} }, { {0xe0, 0x75, -1}, {0xe0, 0xf5, -1} }, { {-1}, {-1} }, { {0xe0, 0x77, -1}, {0xe0, 0xf7, -1} }, /*f4*/ - { {0xe0, 0x78, -1}, {0xe0, 0xf8, -1} }, { {0xe0, 0x79, -1}, {0xe0, 0xf9, -1} }, { {0xe0, 0x7a, -1}, {0xe0, 0xfa, -1} }, { {0xe0, 0x7b, -1}, {0xe0, 0xfb, -1} }, /*f8*/ - { {0xe0, 0x7c, -1}, {0xe0, 0xfc, -1} }, { {0xe0, 0x7d, -1}, {0xe0, 0xfd, -1} }, { {0xe0, 0x7e, -1}, {0xe0, 0xfe, -1} }, { {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5, -1}, {-1} }, /*fc*/ - { {-1}, {-1} }, { {0xe0, 0x01, -1}, {0xe0, 0x81, -1} }, { {0xe0, 0x02, -1}, {0xe0, 0x82, -1} }, { {-1}, {-1} }, /*100*/ - { {-1}, {-1} }, { {0xe0, 0x05, -1}, {0xe0, 0x85, -1} }, { {0xe0, 0x06, -1}, {0xe0, 0x86, -1} }, { {0xe0, 0x07, -1}, {0xe0, 0x87, -1} }, /*104*/ - { {0xe0, 0x71, -1}, {0xe0, 0xf1, -1} }, { {0xe0, 0x72, -1}, {0xe0, 0xf2, -1} }, { {0xe0, 0x7f, -1}, {0xe0, 0xff, -1} }, { {0xe0, 0xe1, -1}, {-1} }, /*108*/ - { {0xe0, 0xee, -1}, {-1} }, { {0xe0, 0xf1, -1}, {-1} }, { {0xe0, 0xfe, -1}, {-1} }, { {0xe0, 0xff, -1}, {-1} } /*10c*/ + { {0x80, 0}, {0} }, { {0x81, 0}, {0} }, { {0x82, 0}, {0} }, { {0xe0, 0x03, 0}, {0xe0, 0x83, 0} }, /*80*/ + { {0xe0, 0x04, 0}, {0xe0, 0x84, 0} }, { {0x85, 0}, {0} }, { {0x86, 0}, {0} }, { {0x87, 0}, {0} }, /*84*/ + { {0xe0, 0x08, 0}, {0xe0, 0x88, 0} }, { {0xe0, 0x09, 0}, {0xe0, 0x89, 0} }, { {0xe0, 0x0a, 0}, {0xe0, 0x8a, 0} }, { {0xe0, 0x0b, 0}, {0xe0, 0x8b, 0} }, /*88*/ + { {0xe0, 0x0c, 0}, {0xe0, 0x8c, 0} }, { {0}, {0} }, { {0xe0, 0x0e, 0}, {0xe0, 0x8e, 0} }, { {0xe0, 0x0f, 0}, {0xe0, 0x8f, 0} }, /*8c*/ + { {0xe0, 0x10, 0}, {0xe0, 0x90, 0} }, { {0xe0, 0x11, 0}, {0xe0, 0x91, 0} }, { {0xe0, 0x12, 0}, {0xe0, 0x92, 0} }, { {0xe0, 0x13, 0}, {0xe0, 0x93, 0} }, /*90*/ + { {0xe0, 0x14, 0}, {0xe0, 0x94, 0} }, { {0xe0, 0x15, 0}, {0xe0, 0x95, 0} }, { {0xe0, 0x16, 0}, {0xe0, 0x96, 0} }, { {0xe0, 0x17, 0}, {0xe0, 0x97, 0} }, /*94*/ + { {0xe0, 0x18, 0}, {0xe0, 0x98, 0} }, { {0xe0, 0x19, 0}, {0xe0, 0x99, 0} }, { {0xe0, 0x1a, 0}, {0xe0, 0x9a, 0} }, { {0xe0, 0x1b, 0}, {0xe0, 0x9b, 0} }, /*98*/ + { {0xe0, 0x1c, 0}, {0xe0, 0x9c, 0} }, { {0xe0, 0x1d, 0}, {0xe0, 0x9d, 0} }, { {0xe0, 0x1e, 0}, {0xe0, 0x9e, 0} }, { {0xe0, 0x1f, 0}, {0xe0, 0x9f, 0} }, /*9c*/ + { {0xe0, 0x20, 0}, {0xe0, 0xa0, 0} }, { {0xe0, 0x21, 0}, {0xe0, 0xa1, 0} }, { {0xe0, 0x22, 0}, {0xe0, 0xa2, 0} }, { {0xe0, 0x23, 0}, {0xe0, 0xa3, 0} }, /*a0*/ + { {0xe0, 0x24, 0}, {0xe0, 0xa4, 0} }, { {0xe0, 0x25, 0}, {0xe0, 0xa5, 0} }, { {0xe0, 0x26, 0}, {0xe0, 0xa6, 0} }, { {0}, {0} }, /*a4*/ + { {0}, {0} }, { {0}, {0} }, { {0xe0, 0x2a, 0}, {0xe0, 0xaa, 0} }, { {0}, {0} }, /*a8*/ + { {0xe0, 0x2c, 0}, {0xe0, 0xac, 0} }, { {0xe0, 0x2d, 0}, {0xe0, 0xad, 0} }, { {0xe0, 0x2e, 0}, {0xe0, 0xae, 0} }, { {0xe0, 0x2f, 0}, {0xe0, 0xaf, 0} }, /*ac*/ + { {0xe0, 0x30, 0}, {0xe0, 0xb0, 0} }, { {0xe0, 0x31, 0}, {0xe0, 0xb1, 0} }, { {0xe0, 0x32, 0}, {0xe0, 0xb2, 0} }, { {0}, {0} }, /*b0*/ + { {0xe0, 0x34, 0}, {0xe0, 0xb4, 0} }, { {0xe0, 0x35, 0}, {0xe0, 0xb5, 0} }, { {0xe0, 0x36, 0}, {0xe0, 0xb6, 0} }, { {0xe0, 0x37, 0}, {0xe0, 0xb7, 0} }, /*b4*/ + { {0xe0, 0x38, 0}, {0xe0, 0xb8, 0} }, { {0}, {0} }, { {0xe0, 0x3a, 0}, {0xe0, 0xba, 0} }, { {0xe0, 0x3b, 0}, {0xe0, 0xbb, 0} }, /*b8*/ + { {0xe0, 0x3c, 0}, {0xe0, 0xbc, 0} }, { {0xe0, 0x3d, 0}, {0xe0, 0xbd, 0} }, { {0xe0, 0x3e, 0}, {0xe0, 0xbe, 0} }, { {0xe0, 0x3f, 0}, {0xe0, 0xbf, 0} }, /*bc*/ + { {0xe0, 0x40, 0}, {0xe0, 0xc0, 0} }, { {0xe0, 0x41, 0}, {0xe0, 0xc1, 0} }, { {0xe0, 0x42, 0}, {0xe0, 0xc2, 0} }, { {0xe0, 0x43, 0}, {0xe0, 0xc3, 0} }, /*c0*/ + { {0xe0, 0x44, 0}, {0xe0, 0xc4, 0} }, { {0}, {0} }, { {0xe0, 0x46, 0}, {0xe0, 0xc6, 0} }, { {0xe0, 0x47, 0}, {0xe0, 0xc7, 0} }, /*c4*/ + { {0xe0, 0x48, 0}, {0xe0, 0xc8, 0} }, { {0xe0, 0x49, 0}, {0xe0, 0xc9, 0} }, { {0}, {0} }, { {0xe0, 0x4b, 0}, {0xe0, 0xcb, 0} }, /*c8*/ + { {0xe0, 0x4c, 0}, {0xe0, 0xcc, 0} }, { {0xe0, 0x4d, 0}, {0xe0, 0xcd, 0} }, { {0xe0, 0x4e, 0}, {0xe0, 0xce, 0} }, { {0xe0, 0x4f, 0}, {0xe0, 0xcf, 0} }, /*cc*/ + { {0xe0, 0x50, 0}, {0xe0, 0xd0, 0} }, { {0xe0, 0x51, 0}, {0xe0, 0xd1, 0} }, { {0xe0, 0x52, 0}, {0xe0, 0xd2, 0} }, { {0xe0, 0x53, 0}, {0xe0, 0xd3, 0} }, /*d0*/ + { {0xd4, 0}, {0} }, { {0xe0, 0x55, 0}, {0xe0, 0xd5, 0} }, { {0}, {0} }, { {0xe0, 0x57, 0}, {0xe0, 0xd7, 0} }, /*d4*/ + { {0xe0, 0x58, 0}, {0xe0, 0xd8, 0} }, { {0xe0, 0x59, 0}, {0xe0, 0xd9, 0} }, { {0xe0, 0x5a, 0}, {0xe0, 0xaa, 0} }, { {0xe0, 0x5b, 0}, {0xe0, 0xdb, 0} }, /*d8*/ + { {0xe0, 0x5c, 0}, {0xe0, 0xdc, 0} }, { {0xe0, 0x5d, 0}, {0xe0, 0xdd, 0} }, { {0xe0, 0x5e, 0}, {0xe0, 0xee, 0} }, { {0xe0, 0x5f, 0}, {0xe0, 0xdf, 0} }, /*dc*/ + { {0}, {0} }, { {0xe0, 0x61, 0}, {0xe0, 0xe1, 0} }, { {0xe0, 0x62, 0}, {0xe0, 0xe2, 0} }, { {0xe0, 0x63, 0}, {0xe0, 0xe3, 0} }, /*e0*/ + { {0xe0, 0x64, 0}, {0xe0, 0xe4, 0} }, { {0xe0, 0x65, 0}, {0xe0, 0xe5, 0} }, { {0xe0, 0x66, 0}, {0xe0, 0xe6, 0} }, { {0xe0, 0x67, 0}, {0xe0, 0xe7, 0} }, /*e4*/ + { {0xe0, 0x68, 0}, {0xe0, 0xe8, 0} }, { {0xe0, 0x69, 0}, {0xe0, 0xe9, 0} }, { {0xe0, 0x6a, 0}, {0xe0, 0xea, 0} }, { {0xe0, 0x6b, 0}, {0xe0, 0xeb, 0} }, /*e8*/ + { {0xe0, 0x6c, 0}, {0xe0, 0xec, 0} }, { {0xe0, 0x6d, 0}, {0xe0, 0xed, 0} }, { {0xe0, 0x6e, 0}, {0xe0, 0xee, 0} }, { {0}, {0} }, /*ec*/ + { {0xe0, 0x70, 0}, {0xe0, 0xf0, 0} }, { {0xf1, 0}, {0} }, { {0xf2, 0}, {0} }, { {0xe0, 0x73, 0}, {0xe0, 0xf3, 0} }, /*f0*/ + { {0xe0, 0x74, 0}, {0xe0, 0xf4, 0} }, { {0xe0, 0x75, 0}, {0xe0, 0xf5, 0} }, { {0}, {0} }, { {0xe0, 0x77, 0}, {0xe0, 0xf7, 0} }, /*f4*/ + { {0xe0, 0x78, 0}, {0xe0, 0xf8, 0} }, { {0xe0, 0x79, 0}, {0xe0, 0xf9, 0} }, { {0xe0, 0x7a, 0}, {0xe0, 0xfa, 0} }, { {0xe0, 0x7b, 0}, {0xe0, 0xfb, 0} }, /*f8*/ + { {0xe0, 0x7c, 0}, {0xe0, 0xfc, 0} }, { {0xe0, 0x7d, 0}, {0xe0, 0xfd, 0} }, { {0xe0, 0x7e, 0}, {0xe0, 0xfe, 0} }, { {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5, 0}, {0} }, /*fc*/ + { {0}, {0} }, { {0xe0, 0x01, 0}, {0xe0, 0x81, 0} }, { {0xe0, 0x02, 0}, {0xe0, 0x82, 0} }, { {0}, {0} }, /*100*/ + { {0}, {0} }, { {0xe0, 0x05, 0}, {0xe0, 0x85, 0} }, { {0xe0, 0x06, 0}, {0xe0, 0x86, 0} }, { {0xe0, 0x07, 0}, {0xe0, 0x87, 0} }, /*104*/ + { {0xe0, 0x71, 0}, {0xe0, 0xf1, 0} }, { {0xe0, 0x72, 0}, {0xe0, 0xf2, 0} }, { {0xe0, 0x7f, 0}, {0xe0, 0xff, 0} }, { {0xe0, 0xe1, 0}, {0} }, /*108*/ + { {0xe0, 0xee, 0}, {0} }, { {0xe0, 0xf1, 0}, {0} }, { {0xe0, 0xfe, 0}, {0} }, { {0xe0, 0xff, 0}, {0} } /*10c*/ }; /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ static scancode scancode_xt[272] = { - { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, - { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, { {0x06, -1}, {0x86, -1} }, { {0x07, -1}, {0x87, -1} }, - { {0x08, -1}, {0x88, -1} }, { {0x09, -1}, {0x89, -1} }, { {0x0a, -1}, {0x8a, -1} }, { {0x0b, -1}, {0x8b, -1} }, - { {0x0c, -1}, {0x8c, -1} }, { {0x0d, -1}, {0x8d, -1} }, { {0x0e, -1}, {0x8e, -1} }, { {0x0f, -1}, {0x8f, -1} }, - { {0x10, -1}, {0x90, -1} }, { {0x11, -1}, {0x91, -1} }, { {0x12, -1}, {0x92, -1} }, { {0x13, -1}, {0x93, -1} }, - { {0x14, -1}, {0x94, -1} }, { {0x15, -1}, {0x95, -1} }, { {0x16, -1}, {0x96, -1} }, { {0x17, -1}, {0x97, -1} }, - { {0x18, -1}, {0x98, -1} }, { {0x19, -1}, {0x99, -1} }, { {0x1a, -1}, {0x9a, -1} }, { {0x1b, -1}, {0x9b, -1} }, - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, { {0x1e, -1}, {0x9e, -1} }, { {0x1f, -1}, {0x9f, -1} }, - { {0x20, -1}, {0xa0, -1} }, { {0x21, -1}, {0xa1, -1} }, { {0x22, -1}, {0xa2, -1} }, { {0x23, -1}, {0xa3, -1} }, - { {0x24, -1}, {0xa4, -1} }, { {0x25, -1}, {0xa5, -1} }, { {0x26, -1}, {0xa6, -1} }, { {0x27, -1}, {0xa7, -1} }, - { {0x28, -1}, {0xa8, -1} }, { {0x29, -1}, {0xa9, -1} }, { {0x2a, -1}, {0xaa, -1} }, { {0x2b, -1}, {0xab, -1} }, - { {0x2c, -1}, {0xac, -1} }, { {0x2d, -1}, {0xad, -1} }, { {0x2e, -1}, {0xae, -1} }, { {0x2f, -1}, {0xaf, -1} }, - { {0x30, -1}, {0xb0, -1} }, { {0x31, -1}, {0xb1, -1} }, { {0x32, -1}, {0xb2, -1} }, { {0x33, -1}, {0xb3, -1} }, - { {0x34, -1}, {0xb4, -1} }, { {0x35, -1}, {0xb5, -1} }, { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, - { {0x38, -1}, {0xb8, -1} }, { {0x39, -1}, {0xb9, -1} }, { {0x3a, -1}, {0xba, -1} }, { {0x3b, -1}, {0xbb, -1} }, - { {0x3c, -1}, {0xbc, -1} }, { {0x3d, -1}, {0xbd, -1} }, { {0x3e, -1}, {0xbe, -1} }, { {0x3f, -1}, {0xbf, -1} }, - { {0x40, -1}, {0xc0, -1} }, { {0x41, -1}, {0xc1, -1} }, { {0x42, -1}, {0xc2, -1} }, { {0x43, -1}, {0xc3, -1} }, - { {0x44, -1}, {0xc4, -1} }, { {0x45, -1}, {0xc5, -1} }, { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, { {0x4a, -1}, {0xca, -1} }, { {0x4b, -1}, {0xcb, -1} }, - { {0x4c, -1}, {0xcc, -1} }, { {0x4d, -1}, {0xcd, -1} }, { {0x4e, -1}, {0xce, -1} }, { {0x4f, -1}, {0xcf, -1} }, - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*54*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*58*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*5c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*60*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*64*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*68*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*6c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*70*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*74*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*78*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*7c*/ + { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, + { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, + { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, + { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, + { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, + { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, + { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, + { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, + { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, + { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, { {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} }, + { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, + { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, + { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, + { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, + { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, + { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, + { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, + { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*54*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*58*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*5c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*60*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*64*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*68*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*6c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*70*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*74*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*78*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*7c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*80*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*84*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*88*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*8c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*90*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*94*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*98*/ - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*9c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*a0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {0x2a, -1}, {0xaa, -1} }, { {-1}, {-1} }, /*a8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*ac*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*b0*/ - { {-1}, {-1} }, { {0x35, -1}, {0xb5, -1} }, { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, /*b4*/ - { {0x38, -1}, {0xb8, -1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*b8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*bc*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*c0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, /*c4*/ - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, { {-1}, {-1} }, { {0x4b, -1}, {0xcb, -1} }, /*c8*/ - { {-1}, {-1} }, { {0x4d, -1}, {0xcd, -1} }, { {-1}, {-1} }, { {0x4f, -1}, {0xcf, -1} }, /*cc*/ - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, /*d0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*d4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*d8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*dc*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*e0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*e4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*e8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*ec*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*f0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*f4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*f8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*fc*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*100*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*104*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*108*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*10c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*80*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*84*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*88*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*8c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*90*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*94*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*98*/ + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, { {0}, {0} }, { {0}, {0} }, /*9c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*a0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*a4*/ + { {0}, {0} }, { {0}, {0} }, { {0x2a, 0}, {0xaa, 0} }, { {0}, {0} }, /*a8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*ac*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*b0*/ + { {0}, {0} }, { {0x35, 0}, {0xb5, 0} }, { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, /*b4*/ + { {0x38, 0}, {0xb8, 0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*b8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*bc*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*c0*/ + { {0}, {0} }, { {0}, {0} }, { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*c4*/ + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, { {0}, {0} }, { {0x4b, 0}, {0xcb, 0} }, /*c8*/ + { {0}, {0} }, { {0x4d, 0}, {0xcd, 0} }, { {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*cc*/ + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*d0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*d4*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*d8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*dc*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*e0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*e4*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*e8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*ec*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*f0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*f4*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*f8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*fc*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*100*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*104*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*108*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*10c*/ }; /*Tandy keyboard has slightly different scancodes to XT*/ static scancode scancode_tandy[272] = { - { {-1}, {-1} }, { {0x01, -1}, {0x81, -1} }, { {0x02, -1}, {0x82, -1} }, { {0x03, -1}, {0x83, -1} }, - { {0x04, -1}, {0x84, -1} }, { {0x05, -1}, {0x85, -1} }, { {0x06, -1}, {0x86, -1} }, { {0x07, -1}, {0x87, -1} }, - { {0x08, -1}, {0x88, -1} }, { {0x09, -1}, {0x89, -1} }, { {0x0a, -1}, {0x8a, -1} }, { {0x0b, -1}, {0x8b, -1} }, - { {0x0c, -1}, {0x8c, -1} }, { {0x0d, -1}, {0x8d, -1} }, { {0x0e, -1}, {0x8e, -1} }, { {0x0f, -1}, {0x8f, -1} }, - { {0x10, -1}, {0x90, -1} }, { {0x11, -1}, {0x91, -1} }, { {0x12, -1}, {0x92, -1} }, { {0x13, -1}, {0x93, -1} }, - { {0x14, -1}, {0x94, -1} }, { {0x15, -1}, {0x95, -1} }, { {0x16, -1}, {0x96, -1} }, { {0x17, -1}, {0x97, -1} }, - { {0x18, -1}, {0x98, -1} }, { {0x19, -1}, {0x99, -1} }, { {0x1a, -1}, {0x9a, -1} }, { {0x1b, -1}, {0x9b, -1} }, - { {0x1c, -1}, {0x9c, -1} }, { {0x1d, -1}, {0x9d, -1} }, { {0x1e, -1}, {0x9e, -1} }, { {0x1f, -1}, {0x9f, -1} }, - { {0x20, -1}, {0xa0, -1} }, { {0x21, -1}, {0xa1, -1} }, { {0x22, -1}, {0xa2, -1} }, { {0x23, -1}, {0xa3, -1} }, - { {0x24, -1}, {0xa4, -1} }, { {0x25, -1}, {0xa5, -1} }, { {0x26, -1}, {0xa6, -1} }, { {0x27, -1}, {0xa7, -1} }, - { {0x28, -1}, {0xa8, -1} }, { {0x29, -1}, {0xa9, -1} }, { {0x2a, -1}, {0xaa, -1} }, { {0x47, -1}, {0xc7, -1} }, - { {0x2c, -1}, {0xac, -1} }, { {0x2d, -1}, {0xad, -1} }, { {0x2e, -1}, {0xae, -1} }, { {0x2f, -1}, {0xaf, -1} }, - { {0x30, -1}, {0xb0, -1} }, { {0x31, -1}, {0xb1, -1} }, { {0x32, -1}, {0xb2, -1} }, { {0x33, -1}, {0xb3, -1} }, - { {0x34, -1}, {0xb4, -1} }, { {0x35, -1}, {0xb5, -1} }, { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, - { {0x38, -1}, {0xb8, -1} }, { {0x39, -1}, {0xb9, -1} }, { {0x3a, -1}, {0xba, -1} }, { {0x3b, -1}, {0xbb, -1} }, - { {0x3c, -1}, {0xbc, -1} }, { {0x3d, -1}, {0xbd, -1} }, { {0x3e, -1}, {0xbe, -1} }, { {0x3f, -1}, {0xbf, -1} }, - { {0x40, -1}, {0xc0, -1} }, { {0x41, -1}, {0xc1, -1} }, { {0x42, -1}, {0xc2, -1} }, { {0x43, -1}, {0xc3, -1} }, - { {0x44, -1}, {0xc4, -1} }, { {0x45, -1}, {0xc5, -1} }, { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, - { {0x48, -1}, {0xc8, -1} }, { {0x49, -1}, {0xc9, -1} }, { {0x4a, -1}, {0xca, -1} }, { {0x4b, -1}, {0xcb, -1} }, - { {0x4c, -1}, {0xcc, -1} }, { {0x4d, -1}, {0xcd, -1} }, { {0x4e, -1}, {0xce, -1} }, { {0x4f, -1}, {0xcf, -1} }, - { {0x50, -1}, {0xd0, -1} }, { {0x51, -1}, {0xd1, -1} }, { {0x52, -1}, {0xd2, -1} }, { {0x56, -1}, {0xd6, -1} }, - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*54*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*58*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*5c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*60*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*64*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*68*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*6c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*70*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*74*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*78*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*7c*/ + { {0}, {0} }, { {0x01, 0}, {0x81, 0} }, { {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} }, + { {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} }, { {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} }, + { {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} }, { {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} }, + { {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} }, { {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} }, + { {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} }, { {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} }, + { {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} }, { {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} }, + { {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} }, { {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} }, + { {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} }, { {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} }, + { {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} }, { {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} }, + { {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} }, { {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} }, + { {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} }, { {0x2a, 0}, {0xaa, 0} }, { {0x47, 0}, {0xc7, 0} }, + { {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} }, { {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} }, + { {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} }, { {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} }, + { {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} }, { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, + { {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} }, { {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} }, + { {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} }, { {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} }, + { {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} }, { {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} }, + { {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} }, { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, + { {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} }, { {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} }, + { {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} }, { {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} }, + { {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} }, { {0x52, 0}, {0xd2, 0} }, { {0x56, 0}, {0xd6, 0} }, + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*54*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*58*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*5c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*60*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*64*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*68*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*6c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*70*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*74*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*78*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*7c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*80*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*84*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*88*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*8c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*90*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*94*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*98*/ - { {0x57, -1}, {0xd7, -1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*9c*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*a0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*a4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {0x2a, -1}, {0xaa, -1} }, { {-1}, {-1} }, /*a8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*ac*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*b0*/ - { {-1}, {-1} }, { {0x35, -1}, {0xb5, -1} }, { {0x36, -1}, {0xb6, -1} }, { {0x37, -1}, {0xb7, -1} }, /*b4*/ - { {0x38, -1}, {0xb8, -1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*b8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*bc*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*c0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {0x46, -1}, {0xc6, -1} }, { {0x47, -1}, {0xc7, -1} }, /*c4*/ - { {0x29, -1}, {0xa9, -1} }, { {0x49, -1}, {0xc9, -1} }, { {-1}, {-1} }, { {0x2b, -1}, {0xab, -1} }, /*c8*/ - { {-1}, {-1} }, { {0x4e, -1}, {0xce, -1} }, { {-1}, {-1} }, { {0x4f, -1}, {0xcf, -1} }, /*cc*/ - { {0x4a, -1}, {0xca, -1} }, { {0x51, -1}, {0xd1, -1} }, { {0x52, -1}, {0xd2, -1} }, { {0x53, -1}, {0xd3, -1} }, /*d0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*d4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*d8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*dc*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*e0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*e4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*e8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*ec*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*f0*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*f4*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*f8*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*fc*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*100*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*104*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*108*/ - { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, { {-1}, {-1} }, /*10c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*80*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*84*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*88*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*8c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*90*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*94*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*98*/ + { {0x57, 0}, {0xd7, 0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*9c*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*a0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*a4*/ + { {0}, {0} }, { {0}, {0} }, { {0x2a, 0}, {0xaa, 0} }, { {0}, {0} }, /*a8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*ac*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*b0*/ + { {0}, {0} }, { {0x35, 0}, {0xb5, 0} }, { {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} }, /*b4*/ + { {0x38, 0}, {0xb8, 0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*b8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*bc*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*c0*/ + { {0}, {0} }, { {0}, {0} }, { {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*c4*/ + { {0x29, 0}, {0xa9, 0} }, { {0x49, 0}, {0xc9, 0} }, { {0}, {0} }, { {0x2b, 0}, {0xab, 0} }, /*c8*/ + { {0}, {0} }, { {0x4e, 0}, {0xce, 0} }, { {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*cc*/ + { {0x4a, 0}, {0xca, 0} }, { {0x51, 0}, {0xd1, 0} }, { {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*d0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*d4*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*d8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*dc*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*e0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*e4*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*e8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*ec*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*f0*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*f4*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*f8*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*fc*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*100*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*104*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*108*/ + { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, { {0}, {0} }, /*10c*/ }; -static int oldkey[272]; -static int keydelay[272]; +static uint8_t oldkey[272]; +static uint8_t keydelay[272]; void (*keyboard_send)(uint8_t val); void (*keyboard_poll)(); @@ -259,20 +259,20 @@ void keyboard_process() if (pcem_key[c] != oldkey[c]) { oldkey[c] = pcem_key[c]; - if ( pcem_key[c] && scancodes[c].scancodes_make[0] == -1) + if ( pcem_key[c] && scancodes[c].scancodes_make[0] == 0) continue; - if (!pcem_key[c] && scancodes[c].scancodes_break[0] == -1) + if (!pcem_key[c] && scancodes[c].scancodes_break[0] == 0) continue; // pclog("Key %02X start\n", c); d = 0; if (pcem_key[c]) { - while (scancodes[c].scancodes_make[d] != -1) + while (scancodes[c].scancodes_make[d] != 0) keyboard_send(scancodes[c].scancodes_make[d++]); } else { - while (scancodes[c].scancodes_break[d] != -1) + while (scancodes[c].scancodes_break[d] != 0) keyboard_send(scancodes[c].scancodes_break[d++]); } } @@ -283,12 +283,12 @@ void keyboard_process() if (keydelay[c] >= 30) { keydelay[c] -= 10; - if (scancodes[c].scancodes_make[0] == -1) + if (scancodes[c].scancodes_make[0] == 0) continue; d = 0; - while (scancodes[c].scancodes_make[d] != -1) + while (scancodes[c].scancodes_make[d] != 0) keyboard_send(scancodes[c].scancodes_make[d++]); } } diff --git a/src/keyboard.h b/src/keyboard.h index 5d5283c..6f6bc59 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -3,4 +3,4 @@ extern void (*keyboard_poll)(); void keyboard_process(); extern int keyboard_scan; -extern int pcem_key[272]; +extern uint8_t pcem_key[272]; diff --git a/src/plat-keyboard.h b/src/plat-keyboard.h index 4b5ea03..ab8b922 100644 --- a/src/plat-keyboard.h +++ b/src/plat-keyboard.h @@ -1,10 +1,12 @@ #ifdef __cplusplus extern "C" { #endif + #include + void keyboard_init(); void keyboard_close(); void keyboard_poll_host(); - extern int pcem_key[272]; + extern uint8_t pcem_key[272]; extern int rawinputkey[272]; #ifndef __unix diff --git a/src/wx-sdl2-keyboard.c b/src/wx-sdl2-keyboard.c index 12eb626..adf8e8a 100644 --- a/src/wx-sdl2-keyboard.c +++ b/src/wx-sdl2-keyboard.c @@ -1,7 +1,7 @@ #include "plat-keyboard.h" #include -int pcem_key[272]; +uint8_t pcem_key[272]; int rawinputkey[272]; void keyboard_init() From f545d9d57f681c5d6606378eef0b36935a478382 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Nov 2018 12:44:47 +0000 Subject: [PATCH 0532/1050] Rename FPU stack-based integer mirror registers, to avoid confusion with non-stack-based MMX registers. --- src/codegen_ops_fpu_loadstore.c | 6 +++--- src/codegen_ops_fpu_misc.c | 12 ++++++------ src/codegen_reg.c | 16 ++++++++-------- src/codegen_reg.h | 20 ++++++++++---------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/codegen_ops_fpu_loadstore.c b/src/codegen_ops_fpu_loadstore.c index 8be00d2..04ee62a 100644 --- a/src/codegen_ops_fpu_loadstore.c +++ b/src/codegen_ops_fpu_loadstore.c @@ -141,8 +141,8 @@ uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe op_pc--; target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_MM(-1)); + uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); fpu_PUSH(ir); @@ -220,7 +220,7 @@ uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f op_pc--; target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_MM(0), IREG_tag(0)); + uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); fpu_POP(ir); diff --git a/src/codegen_ops_fpu_misc.c b/src/codegen_ops_fpu_misc.c index 2509cc7..18d6f88 100644 --- a/src/codegen_ops_fpu_misc.c +++ b/src/codegen_ops_fpu_misc.c @@ -27,7 +27,7 @@ uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc uop_FP_ENTER(ir); uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); - uop_MOV(ir, IREG_MM(-1), IREG_MM(src_reg)); + uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); fpu_PUSH(ir); @@ -40,7 +40,7 @@ uint32_t ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc uop_FP_ENTER(ir); uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); return op_pc; @@ -51,7 +51,7 @@ uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_FP_ENTER(ir); uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); fpu_POP(ir); @@ -98,13 +98,13 @@ uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_FP_ENTER(ir); uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); - uop_MOV(ir, IREG_temp1_Q, IREG_MM(0)); + uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); uop_MOV(ir, IREG_temp2, IREG_tag(0)); uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV(ir, IREG_MM(0), IREG_MM(dest_reg)); + uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); - uop_MOV(ir, IREG_MM(dest_reg), IREG_temp1_Q); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); return op_pc; diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 2e76874..6e51f7d 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -114,14 +114,14 @@ struct [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_MM0] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM1] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM2] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM3] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM4] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM5] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM6] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM7] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER}, [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 3bb69b2..4568382 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -95,14 +95,14 @@ enum IREG_tag6 = 54, IREG_tag7 = 55, - IREG_MM0 = 56, - IREG_MM1 = 57, - IREG_MM2 = 58, - IREG_MM3 = 59, - IREG_MM4 = 60, - IREG_MM5 = 61, - IREG_MM6 = 62, - IREG_MM7 = 63, + IREG_ST0_i64 = 56, + IREG_ST1_i64 = 57, + IREG_ST2_i64 = 58, + IREG_ST3_i64 = 59, + IREG_ST4_i64 = 60, + IREG_ST5_i64 = 61, + IREG_ST6_i64 = 62, + IREG_ST7_i64 = 63, IREG_NPXCx = 64, IREG_NPXSx = 65, @@ -168,8 +168,8 @@ enum #define IREG_16(reg) ((reg) + IREG_AX) #define IREG_32(reg) ((reg) + IREG_EAX) -#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) -#define IREG_MM(r) (IREG_MM0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) +#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) +#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) #define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) #define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) From 76115568f2282d7db9aff21341f380b236481ace Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Nov 2018 17:02:20 +0000 Subject: [PATCH 0533/1050] Added recompiled versions of MOVD and MOVQ. --- src/codegen_backend_arm64_uops.c | 37 ++++++++++- src/codegen_backend_arm_uops.c | 39 ++++++++++- src/codegen_backend_x86-64_uops.c | 42 +++++++++++- src/codegen_backend_x86_uops.c | 33 +++++++++- src/codegen_ir_defs.h | 11 +++- src/codegen_ops.c | 9 +-- src/codegen_ops_mmx_loadstore.c | 106 ++++++++++++++++++++++++++++++ src/codegen_ops_mmx_loadstore.h | 5 ++ src/codegen_reg.c | 27 ++++++++ src/codegen_reg.h | 26 +++++++- 10 files changed, 320 insertions(+), 15 deletions(-) create mode 100644 src/codegen_ops_mmx_loadstore.c create mode 100644 src/codegen_ops_mmx_loadstore.h diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 1d8aec5..5464148 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -699,6 +699,32 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); + + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); + + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]); + + host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); + + host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); + host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); + + return 0; +} static int codegen_JMP(codeblock_t *block, uop_t *uop) { @@ -1162,7 +1188,15 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) + { + host_arm64_FMOV_D_Q(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) + { + host_arm64_FMOV_W_S(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); } @@ -1836,6 +1870,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, [UOP_FCOM & UOP_MASK] = codegen_FCOM, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 08ae666..1f132de 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -772,6 +772,33 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + + *branch_ptr |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; + + host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); + + return 0; +} static int codegen_JMP(codeblock_t *block, uop_t *uop) { @@ -1238,7 +1265,16 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); + } + else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) + { + host_arm_VMOV_32_S(block, dest_reg, src_reg, REG_TEMP); + } + else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { host_arm_UXTB(block, dest_reg, src_reg, 0); } @@ -1955,6 +1991,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, [UOP_FCOM & UOP_MASK] = codegen_FCOM, diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 4fd1768..d27edae 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -641,6 +641,29 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint8_t *branch_offset; + + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_short(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); +#if WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); +#else + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); +#endif + host_x86_CALL(block, x86_int); + host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + + return 0; +} static int codegen_JMP(codeblock_t *block, uop_t *uop) { @@ -1076,7 +1099,15 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) + { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) + { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); } @@ -1640,6 +1671,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, [UOP_FCOM & UOP_MASK] = codegen_FCOM, @@ -1757,6 +1789,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); +} void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); @@ -1766,6 +1802,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos { host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); +} void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 9ef533e..a61592a 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -649,6 +649,26 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint8_t *branch_offset; + + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_short(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + + return 0; +} + static int codegen_JMP(codeblock_t *block, uop_t *uop) { host_x86_JMP(block, uop->p); @@ -1073,7 +1093,15 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) + { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) + { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } + else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); } @@ -1642,7 +1670,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, [UOP_FADD & UOP_MASK] = codegen_FADD, [UOP_FDIV & UOP_MASK] = codegen_FDIV, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 998017b..5c5d290 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -167,7 +167,7 @@ /*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/ #define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) -/*UOP_FP_ENTER - */ +/*UOP_FP_ENTER - must be called before any FPU register accessed*/ #define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) /*UOP_FADD - (floating point) dest_reg = src_reg_a + src_reg_b*/ #define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) @@ -180,7 +180,10 @@ /*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/ #define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) -#define UOP_MAX 0x86 +/*UOP_MMX_ENTER - must be called before any MMX registers accessed*/ +#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) + +#define UOP_MAX 0x91 #define UOP_MASK 0xffff @@ -488,7 +491,8 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) #define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; } while (0) +#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0) +#define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0) #define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) #define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) @@ -549,6 +553,7 @@ void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_of void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_set_jump_dest(codeblock_t *block, void *p); diff --git a/src/codegen_ops.c b/src/codegen_ops.c index a2d6fb1..28dc422 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -11,6 +11,7 @@ #include "codegen_ops_jump.h" #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" +#include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_mov.h" #include "codegen_ops_shift.h" #include "codegen_ops_stack.h" @@ -74,8 +75,8 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -96,8 +97,8 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_mmx_loadstore.c b/src/codegen_ops_mmx_loadstore.c new file mode 100644 index 0000000..e0ea5f7 --- /dev/null +++ b/src/codegen_ops_mmx_loadstore.c @@ -0,0 +1,106 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_loadstore.h" +#include "codegen_ops_helpers.h" + +uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); + } + + return op_pc + 1; + +} +uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } + + return op_pc + 1; +} + +uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; + +} + +uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); + } + + return op_pc + 1; +} diff --git a/src/codegen_ops_mmx_loadstore.h b/src/codegen_ops_mmx_loadstore.h new file mode 100644 index 0000000..4b473ad --- /dev/null +++ b/src/codegen_ops_mmx_loadstore.h @@ -0,0 +1,5 @@ +uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 6e51f7d..3e801a9 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -123,6 +123,15 @@ struct [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP}, + [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP}, + [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP}, + [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP}, + [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP}, + [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP}, + [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP}, + [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER}, [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, @@ -204,6 +213,15 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, else codegen_direct_read_32(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; + + case REG_QWORD: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_64_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_64(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; case REG_DOUBLE: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) @@ -282,6 +300,15 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i codegen_direct_write_32(block, p, reg_set->reg_list[c]); break; + case REG_QWORD: + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); + if ((uintptr_t)p < 256) + codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c]); + else + codegen_direct_write_64(block, p, reg_set->reg_list[c]); + break; + case REG_POINTER: if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 4568382..8474ef9 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -104,10 +104,19 @@ enum IREG_ST6_i64 = 62, IREG_ST7_i64 = 63, - IREG_NPXCx = 64, - IREG_NPXSx = 65, + IREG_MM0x = 64, + IREG_MM1x = 65, + IREG_MM2x = 66, + IREG_MM3x = 67, + IREG_MM4x = 68, + IREG_MM5x = 69, + IREG_MM6x = 70, + IREG_MM7x = 71, + + IREG_NPXCx = 72, + IREG_NPXSx = 73, - IREG_COUNT = 66, + IREG_COUNT = 74, IREG_INVALID = 255, @@ -160,6 +169,15 @@ enum IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, + IREG_MM0 = IREG_MM0x + IREG_SIZE_Q, + IREG_MM1 = IREG_MM1x + IREG_SIZE_Q, + IREG_MM2 = IREG_MM2x + IREG_SIZE_Q, + IREG_MM3 = IREG_MM3x + IREG_SIZE_Q, + IREG_MM4 = IREG_MM4x + IREG_SIZE_Q, + IREG_MM5 = IREG_MM5x + IREG_SIZE_Q, + IREG_MM6 = IREG_MM6x + IREG_SIZE_Q, + IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, + IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, IREG_NPXS = IREG_NPXSx + IREG_SIZE_W }; @@ -173,6 +191,8 @@ enum #define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) #define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) +#define IREG_MM(reg) ((reg) + IREG_MM0) + #define IREG_TOP_diff_stack_offset 32 static inline int ireg_seg_base(x86seg *seg) From 78c604c73136420ea179f8377915414731d1108f Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Nov 2018 20:51:34 +0000 Subject: [PATCH 0534/1050] Added recompiled versions of PAND, PANDN, POR and PXOR --- src/codegen_backend_arm64_ops.c | 23 ++++++- src/codegen_backend_arm64_ops.h | 7 +- src/codegen_backend_arm64_uops.c | 34 +++++++++- src/codegen_backend_arm_ops.c | 22 +++++- src/codegen_backend_arm_ops.h | 4 ++ src/codegen_backend_arm_uops.c | 33 ++++++++- src/codegen_backend_x86-64_ops.c | 17 +++++ src/codegen_backend_x86-64_ops.h | 5 ++ src/codegen_backend_x86-64_uops.c | 34 +++++++++- src/codegen_backend_x86_ops.c | 17 +++++ src/codegen_backend_x86_ops.h | 5 ++ src/codegen_backend_x86_uops.c | 36 ++++++++-- src/codegen_ir_defs.h | 23 ++++--- src/codegen_ops.c | 9 +-- src/codegen_ops_mmx_logic.c | 108 ++++++++++++++++++++++++++++++ src/codegen_ops_mmx_logic.h | 4 ++ 16 files changed, 351 insertions(+), 30 deletions(-) create mode 100644 src/codegen_ops_mmx_logic.c create mode 100644 src/codegen_ops_mmx_logic.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 724ea8b..d4e975c 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -104,9 +104,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_LSR (0x25a << 21) #define OPCODE_SUBX_LSL (0x658 << 21) +#define OPCODE_AND_V (0x0e201c00) #define OPCODE_ASR (0x1ac02800) +#define OPCODE_BIC_V (0x0e601c00) #define OPCODE_BLR (0xd63f0000) #define OPCODE_BR (0xd61f0000) +#define OPCODE_EOR_V (0x2e201c00) #define OPCODE_FADD_D (0x1e602800) #define OPCODE_FCMP_D (0x1e602000) #define OPCODE_FCVT_D_S (0x1e22c000) @@ -140,6 +143,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LSR (0x1ac02400) #define OPCODE_MSR_FPCR (0xd51b4400) #define OPCODE_NOP (0xd503201f) +#define OPCODE_ORR_V (0x0ea01c00) #define OPCODE_RET (0xd65f0000) #define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) @@ -319,6 +323,10 @@ void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int { codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { @@ -461,6 +469,11 @@ void host_arm64_BEQ(codeblock_t *block, void *dest) host_arm64_branch_set_offset(opcode, dest); } +void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { int offset = dest - (uintptr_t)&block->data[block_pos]; @@ -557,6 +570,10 @@ void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { @@ -840,6 +857,10 @@ void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_RET(codeblock_t *block, int reg) { @@ -995,4 +1016,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) } } -#endif \ No newline at end of file +#endif diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index ccccae6..724f939 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -8,6 +8,7 @@ void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); @@ -40,6 +41,8 @@ void host_arm64_branch_set_offset(uint32_t *opcode, void *dest); void host_arm64_BR(codeblock_t *block, int addr_reg); +void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); @@ -57,6 +60,7 @@ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg); @@ -124,6 +128,7 @@ void host_arm64_NOP(codeblock_t *block); void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_RET(codeblock_t *block, int reg); @@ -173,4 +178,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); -int add_literal_q(codeblock_t *block, uint64_t data); \ No newline at end of file +int add_literal_q(codeblock_t *block, uint64_t data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 5464148..baa12fb 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -105,7 +105,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -200,6 +204,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { host_arm64_call(block, uop->p); @@ -1300,7 +1319,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1723,7 +1746,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1834,6 +1861,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, [UOP_SUB & UOP_MASK] = codegen_SUB, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 85d3646..4e34980 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -87,6 +87,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VADD 0xee300b00 +#define OPCODE_VAND_D 0xf2000110 +#define OPCODE_VBIC_D 0xf2100110 #define OPCODE_VCMP_D 0xeeb40b40 #define OPCODE_VCVT_D_IS 0xeeb80bc0 #define OPCODE_VCVT_D_S 0xeeb70ac0 @@ -94,6 +96,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VCVT_S_D 0xeeb70bc0 #define OPCODE_VCVTR_IS_D 0xeebd0b40 #define OPCODE_VDIV 0xee800b00 +#define OPCODE_VEOR_D 0xf3000110 #define OPCODE_VLDR_D 0xed900b00 #define OPCODE_VLDR_S 0xed900a00 #define OPCODE_VMOV_32_S 0xee100a10 @@ -104,6 +107,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMRS_APSR 0xeef1fa10 #define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 +#define OPCODE_VORR_D 0xf2200110 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 @@ -750,6 +754,14 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); @@ -778,6 +790,10 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) @@ -822,6 +838,10 @@ void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) @@ -839,4 +859,4 @@ void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -#endif \ No newline at end of file +#endif diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 1fdd609..9530e72 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -140,6 +140,8 @@ void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m); void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); @@ -147,6 +149,7 @@ void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg); @@ -157,6 +160,7 @@ void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMRS_APSR(codeblock_t *block); void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 1f132de..c5f8b0a 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -169,7 +169,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -273,6 +277,20 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { @@ -1421,7 +1439,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1844,7 +1866,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1955,6 +1981,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, [UOP_SUB & UOP_MASK] = codegen_SUB, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index c3f1b90..736c8b2 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1229,6 +1229,23 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + void host_x86_POP(codeblock_t *block, int dst_reg) { if (dst_reg & 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index ee7a82e..d05ecb6 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -153,6 +153,11 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d27edae..1c8e8bc 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -101,7 +101,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -154,6 +158,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -1203,7 +1222,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -1545,7 +1568,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } @@ -1634,6 +1661,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 0dace79..ca24075 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1087,6 +1087,23 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ } } +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + void host_x86_POP(codeblock_t *block, int src_reg) { codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 96ace96..0f0b469 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -154,6 +154,11 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index a61592a..84ec52f 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -111,7 +111,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -164,6 +168,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -1206,7 +1225,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -1544,7 +1567,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } @@ -1557,7 +1584,7 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); return 0; } @@ -1635,6 +1662,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, [UOP_SUB & UOP_MASK] = codegen_SUB, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 5c5d290..e2cd008 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -93,6 +93,8 @@ #define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) /*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ #define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) +/*UOP_ANDN - dest_reg = ~src_reg_a & src_reg_b*/ +#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) /*UOP_MEM_LOAD_ABS - dest_reg = src_reg_a:[immediate]*/ #define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_REG - dest_reg = src_reg_a:[src_reg_b]*/ @@ -444,17 +446,18 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) -#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) #define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) -#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) -#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) #define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) #define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 28dc422..6531dfc 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -12,6 +12,7 @@ #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" #include "codegen_ops_mmx_loadstore.h" +#include "codegen_ops_mmx_logic.h" #include "codegen_ops_mov.h" #include "codegen_ops_shift.h" #include "codegen_ops_stack.h" @@ -84,8 +85,8 @@ RecompOpFn recomp_opcodes_0f[512] = /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPAND, NULL, NULL, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPOR, NULL, NULL, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ @@ -106,8 +107,8 @@ RecompOpFn recomp_opcodes_0f[512] = /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPAND, NULL, NULL, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPOR, NULL, NULL, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; diff --git a/src/codegen_ops_mmx_logic.c b/src/codegen_ops_mmx_logic.c new file mode 100644 index 0000000..428a591 --- /dev/null +++ b/src/codegen_ops_mmx_logic.c @@ -0,0 +1,108 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_logic.h" +#include "codegen_ops_helpers.h" + +uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} +uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} +uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} +uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} diff --git a/src/codegen_ops_mmx_logic.h b/src/codegen_ops_mmx_logic.h new file mode 100644 index 0000000..f8f3009 --- /dev/null +++ b/src/codegen_ops_mmx_logic.h @@ -0,0 +1,4 @@ +uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 35b9e0811bca2933b736a2c0a86a293a8ae6fc12 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 22 Nov 2018 15:57:44 +0000 Subject: [PATCH 0535/1050] Added recompiled versions of PADD* and PSUB*. --- src/codegen_backend_arm64_ops.c | 71 ++++++++++ src/codegen_backend_arm64_ops.h | 16 +++ src/codegen_backend_arm64_uops.c | 219 +++++++++++++++++++++++++++++- src/codegen_backend_arm_ops.c | 70 ++++++++++ src/codegen_backend_arm_ops.h | 14 ++ src/codegen_backend_arm_uops.c | 219 +++++++++++++++++++++++++++++- src/codegen_backend_x86-64_ops.c | 56 ++++++++ src/codegen_backend_x86-64_ops.h | 14 ++ src/codegen_backend_x86-64_uops.c | 216 ++++++++++++++++++++++++++++- src/codegen_backend_x86_ops.c | 56 ++++++++ src/codegen_backend_x86_ops.h | 14 ++ src/codegen_backend_x86_uops.c | 216 ++++++++++++++++++++++++++++- src/codegen_ir_defs.h | 46 ++++++- src/codegen_ops.c | 13 +- src/codegen_ops_mmx_arith.c | 52 +++++++ src/codegen_ops_mmx_arith.h | 15 ++ 16 files changed, 1296 insertions(+), 11 deletions(-) create mode 100644 src/codegen_ops_mmx_arith.c create mode 100644 src/codegen_ops_mmx_arith.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index d4e975c..8a372f0 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -104,6 +104,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_LSR (0x25a << 21) #define OPCODE_SUBX_LSL (0x658 << 21) +#define OPCODE_ADD_V8B (0x0e208400) +#define OPCODE_ADD_V4H (0x0e608400) +#define OPCODE_ADD_V2S (0x0ea08400) #define OPCODE_AND_V (0x0e201c00) #define OPCODE_ASR (0x1ac02800) #define OPCODE_BIC_V (0x0e601c00) @@ -147,12 +150,23 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_RET (0xd65f0000) #define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) +#define OPCODE_SQADD_V8B (0x0e200c00) +#define OPCODE_SQADD_V4H (0x0e600c00) +#define OPCODE_SQSUB_V8B (0x0e202c00) +#define OPCODE_SQSUB_V4H (0x0e602c00) #define OPCODE_STR_REG (0xb8206800) #define OPCODE_STRB_REG (0x38206800) #define OPCODE_STRH_REG (0x78206800) #define OPCODE_STR_REG_F32 (0xbc206800) #define OPCODE_STR_REG_F64 (0xfc206800) #define OPCODE_STR_REG_F64_S (0xfc207800) +#define OPCODE_SUB_V8B (0x2e208400) +#define OPCODE_SUB_V4H (0x2e608400) +#define OPCODE_SUB_V2S (0x2ea08400) +#define OPCODE_UQADD_V8B (0x2e200c00) +#define OPCODE_UQADD_V4H (0x2e600c00) +#define OPCODE_UQSUB_V8B (0x2e202c00) +#define OPCODE_UQSUB_V4H (0x2e602c00) #define DATPROC_SHIFT(sh) (sh << 10) #define DATPROC_IMM_SHIFT(sh) (sh << 22) @@ -277,6 +291,18 @@ void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int { codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) { @@ -881,6 +907,23 @@ void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) @@ -978,6 +1021,18 @@ void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int { codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) { @@ -990,6 +1045,22 @@ void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); } +void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_call(codeblock_t *block, void *dst_addr) { diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 724f939..a1a1910 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -1,6 +1,9 @@ void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset); @@ -137,6 +140,11 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -157,6 +165,9 @@ void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offs void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit); @@ -164,6 +175,11 @@ uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit); void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); +void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index baa12fb..ae5dc5a 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1384,6 +1384,207 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_UQADD_V8H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -1904,7 +2105,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FCOM & UOP_MASK] = codegen_FCOM, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 4e34980..2818e55 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -87,6 +87,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VADD 0xee300b00 +#define OPCODE_VADD_I8 0xf2000800 +#define OPCODE_VADD_I16 0xf2100800 +#define OPCODE_VADD_I32 0xf2200800 #define OPCODE_VAND_D 0xf2000110 #define OPCODE_VBIC_D 0xf2100110 #define OPCODE_VCMP_D 0xeeb40b40 @@ -108,9 +111,20 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 #define OPCODE_VORR_D 0xf2200110 +#define OPCODE_VQADD_S8 0xf2000010 +#define OPCODE_VQADD_S16 0xf2100010 +#define OPCODE_VQADD_U8 0xf3000010 +#define OPCODE_VQADD_U16 0xf3100010 +#define OPCODE_VQSUB_S8 0xf2000210 +#define OPCODE_VQSUB_S16 0xf2100210 +#define OPCODE_VQSUB_U8 0xf3000210 +#define OPCODE_VQSUB_U16 0xf3100210 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 +#define OPCODE_VSUB_I8 0xf3000800 +#define OPCODE_VSUB_I16 0xf3100800 +#define OPCODE_VSUB_I32 0xf3200800 #define B_OFFSET(x) (((x) >> 2) & 0xffffff) @@ -754,6 +768,18 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -842,6 +868,38 @@ void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) @@ -858,5 +916,17 @@ void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} #endif diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 9530e72..166656c 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -140,6 +140,9 @@ void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m); @@ -161,6 +164,17 @@ void host_arm_VMRS_APSR(codeblock_t *block); void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index c5f8b0a..329459e 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1504,6 +1504,207 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2024,7 +2225,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FCOM & UOP_MASK] = codegen_FCOM, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 736c8b2..efc7e3d 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1229,6 +1229,34 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ +} void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ @@ -1241,6 +1269,34 @@ void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ +} void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index d05ecb6..5f16760 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -153,9 +153,23 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POP(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 1c8e8bc..0eddc13 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1270,6 +1270,204 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -1705,7 +1903,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FCOM & UOP_MASK] = codegen_FCOM, [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index ca24075..2d4fb79 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1087,6 +1087,34 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ } } +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ +} void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ @@ -1099,6 +1127,34 @@ void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ +} void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 0f0b469..ca5f3ff 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -154,9 +154,23 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POP(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 84ec52f..d84c0c2 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1273,6 +1273,204 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -1705,7 +1903,23 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FDIV & UOP_MASK] = codegen_FDIV, [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, - [UOP_FCOM & UOP_MASK] = codegen_FCOM + [UOP_FCOM & UOP_MASK] = codegen_FCOM, + + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index e2cd008..7c7bb39 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -184,8 +184,36 @@ /*UOP_MMX_ENTER - must be called before any MMX registers accessed*/ #define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) +/*UOP_PADDB - (packed byte) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) +/*UOP_PADDW - (packed word) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) +/*UOP_PADDD - (packed long) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) +/*UOP_PADDSB - (packed byte with signed saturation) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) +/*UOP_PADDSW - (packed word with signed saturation) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) +/*UOP_PADDUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) +/*UOP_PADDUSW - (packed word with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) +/*UOP_PSUBB - (packed byte) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) +/*UOP_PSUBW - (packed word) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) +/*UOP_PSUBD - (packed long) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) +/*UOP_PSUBSB - (packed byte with signed saturation) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) +/*UOP_PSUBSW - (packed word with signed saturation) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) +/*UOP_PSUBUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) +/*UOP_PSUBUSW - (packed word with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) -#define UOP_MAX 0x91 +#define UOP_MAX 0x9f #define UOP_MASK 0xffff @@ -525,6 +553,22 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) #define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) +#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) + +#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) + #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 6531dfc..4b17b81 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -11,6 +11,7 @@ #include "codegen_ops_jump.h" #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" +#include "codegen_ops_mmx_arith.h" #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_mmx_logic.h" #include "codegen_ops_mov.h" @@ -85,9 +86,9 @@ RecompOpFn recomp_opcodes_0f[512] = /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPAND, NULL, NULL, NULL, ropPANDN, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPOR, NULL, NULL, NULL, ropPXOR, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -107,9 +108,9 @@ RecompOpFn recomp_opcodes_0f[512] = /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPAND, NULL, NULL, NULL, ropPANDN, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPOR, NULL, NULL, NULL, ropPXOR, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, }; RecompOpFn recomp_opcodes_d8[512] = diff --git a/src/codegen_ops_mmx_arith.c b/src/codegen_ops_mmx_arith.c new file mode 100644 index 0000000..848c046 --- /dev/null +++ b/src/codegen_ops_mmx_arith.c @@ -0,0 +1,52 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_arith.h" +#include "codegen_ops_helpers.h" + +#define ropParith(func) \ +uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + if ((fetchdat & 0xc0) == 0xc0) \ + { \ + int src_reg = fetchdat & 7; \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } \ + else \ + { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ +} + +ropParith(PADDB) +ropParith(PADDW) +ropParith(PADDD) +ropParith(PADDSB) +ropParith(PADDSW) +ropParith(PADDUSB) +ropParith(PADDUSW) + +ropParith(PSUBB) +ropParith(PSUBW) +ropParith(PSUBD) +ropParith(PSUBSB) +ropParith(PSUBSW) +ropParith(PSUBUSB) +ropParith(PSUBUSW) diff --git a/src/codegen_ops_mmx_arith.h b/src/codegen_ops_mmx_arith.h new file mode 100644 index 0000000..e848c8d --- /dev/null +++ b/src/codegen_ops_mmx_arith.h @@ -0,0 +1,15 @@ +uint32_t ropPADDB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPADDW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPADDD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPADDSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPADDSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPADDUSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPADDUSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPSUBB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSUBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSUBD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSUBSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSUBSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSUBUSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSUBUSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From e43a2a6be04d2fa15f53742af44a4d8837c20182 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 22 Nov 2018 18:43:36 +0000 Subject: [PATCH 0536/1050] Added recompiled versions of PSLL*, PSLR* and PSAR* with immediate shifts. --- src/codegen_backend_arm64_ops.c | 105 ++++++++++++++----- src/codegen_backend_arm64_ops.h | 32 ++++-- src/codegen_backend_arm64_uops.c | 164 ++++++++++++++++++++++++++++++ src/codegen_backend_arm_ops.c | 67 ++++++++++++ src/codegen_backend_arm_ops.h | 11 ++ src/codegen_backend_arm_uops.c | 164 ++++++++++++++++++++++++++++++ src/codegen_backend_x86-64_ops.c | 49 +++++++++ src/codegen_backend_x86-64_ops.h | 13 +++ src/codegen_backend_x86-64_uops.c | 137 +++++++++++++++++++++++++ src/codegen_backend_x86_ops.c | 49 +++++++++ src/codegen_backend_x86_ops.h | 13 +++ src/codegen_backend_x86_uops.c | 137 +++++++++++++++++++++++++ src/codegen_ir_defs.h | 30 +++++- src/codegen_ops.c | 5 +- src/codegen_ops_mmx_shift.c | 87 ++++++++++++++++ src/codegen_ops_mmx_shift.h | 7 ++ 16 files changed, 1029 insertions(+), 41 deletions(-) create mode 100644 src/codegen_ops_mmx_shift.c create mode 100644 src/codegen_ops_mmx_shift.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 8a372f0..06d431e 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -154,6 +154,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SQADD_V4H (0x0e600c00) #define OPCODE_SQSUB_V8B (0x0e202c00) #define OPCODE_SQSUB_V4H (0x0e602c00) +#define OPCODE_SHL_VD (0x0e005400) +#define OPCODE_SHL_VQ (0x4e005400) +#define OPCODE_SSHR_VD (0x0e004400) +#define OPCODE_SSHR_VQ (0x4e004400) #define OPCODE_STR_REG (0xb8206800) #define OPCODE_STRB_REG (0x38206800) #define OPCODE_STRH_REG (0x78206800) @@ -167,6 +171,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UQADD_V4H (0x2e600c00) #define OPCODE_UQSUB_V8B (0x2e202c00) #define OPCODE_UQSUB_V4H (0x2e602c00) +#define OPCODE_USHR_VD (0x2e004400) +#define OPCODE_USHR_VQ (0x6e004400) #define DATPROC_SHIFT(sh) (sh << 10) #define DATPROC_IMM_SHIFT(sh) (sh << 22) @@ -191,6 +197,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OFFSET12_W(offset) ((offset >> 2) << 10) #define OFFSET12_Q(offset) ((offset >> 3) << 10) +#define SHIFT_IMM_V4H(shift) (((shift) | 0x10) << 16) +#define SHIFT_IMM_V2S(shift) (((shift) | 0x20) << 16) +#define SHIFT_IMM_V2D(shift) (((shift) | 0x40) << 16) + static int literal_offset = 0; void codegen_reset_literal_pool(codeblock_t *block) { @@ -291,17 +301,17 @@ void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int { codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) @@ -907,21 +917,47 @@ void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); +} +void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); +} +void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); +} + +void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); +} +void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); +} +void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) @@ -1021,17 +1057,17 @@ void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int { codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) @@ -1045,21 +1081,34 @@ void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); } -void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); +} +void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); +} +void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) +{ + codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } void host_arm64_call(codeblock_t *block, void *dst_addr) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index a1a1910..699988d 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -1,9 +1,9 @@ void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset); @@ -140,10 +140,18 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg); -void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + +void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); + +void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); @@ -165,9 +173,9 @@ void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offs void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit); @@ -180,6 +188,10 @@ void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); + void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index ae5dc5a..f19d6b8 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1483,6 +1483,160 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 15) + host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); + else + host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 31) + host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); + else + host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 63) + host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); + else + host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2115,6 +2269,16 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 2818e55..17c29f9 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -119,6 +119,15 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VQSUB_S16 0xf2100210 #define OPCODE_VQSUB_U8 0xf3000210 #define OPCODE_VQSUB_U16 0xf3100210 +#define OPCODE_VSHL_D_IMM_16 0xf2900510 +#define OPCODE_VSHL_D_IMM_32 0xf2a00510 +#define OPCODE_VSHL_D_IMM_64 0xf2800590 +#define OPCODE_VSHR_D_S16 0xf2900010 +#define OPCODE_VSHR_D_S32 0xf2a00010 +#define OPCODE_VSHR_D_S64 0xf2800090 +#define OPCODE_VSHR_D_U16 0xf3900010 +#define OPCODE_VSHR_D_U32 0xf3a00010 +#define OPCODE_VSHR_D_U64 0xf3800090 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 @@ -157,6 +166,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define LDRH_IMM(imm) (((imm) & 0xf) | (((imm) & 0xf0) << 4)) #define STRH_IMM(imm) LDRH_IMM(imm) +#define VSHIFT_IMM(shift) ((shift) << 16) static inline uint32_t arm_data_offset(int offset) { @@ -868,6 +878,7 @@ void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } + void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -900,6 +911,62 @@ void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_ { codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } + +void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 15) + fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 31) + fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 63) + fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_SD_16(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 15) + fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_SD_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_SD_32(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 31) + fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_SD_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_SD_64(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 63) + fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_SD_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_UD_16(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 15) + fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_UD_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_UD_32(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 31) + fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_UD_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_UD_64(codeblock_t *block, int dest_reg, int src_reg, int shift) +{ + if (shift > 63) + fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_UD_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} + void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 166656c..5a1f792 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -172,6 +172,17 @@ void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_r void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); + +void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHR_D_S16(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHR_D_S32(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHR_D_S64(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHR_D_U16(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHR_D_U32(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shift); + void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 329459e..75d01b0 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1603,6 +1603,160 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 15) + host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); + else + host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 31) + host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); + else + host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 63) + host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); + else + host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) + { + if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); + } + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2235,6 +2389,16 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index efc7e3d..97bab1f 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1257,6 +1257,7 @@ void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } + void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ @@ -1269,6 +1270,53 @@ void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} + void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ @@ -1297,6 +1345,7 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } + void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 5f16760..119f854 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -160,9 +160,21 @@ void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); + void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -170,6 +182,7 @@ void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POP(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 0eddc13..331a12f 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1369,6 +1369,133 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1913,6 +2040,16 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 2d4fb79..1dbee0b 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1115,6 +1115,7 @@ void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } + void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ @@ -1127,6 +1128,53 @@ void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} + void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ @@ -1155,6 +1203,7 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } + void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index ca5f3ff..f7483c2 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -161,9 +161,21 @@ void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); + void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -171,6 +183,7 @@ void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POP(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index d84c0c2..7b5a8de 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1372,6 +1372,133 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1913,6 +2040,16 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 7c7bb39..1fdd3a8 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -212,8 +212,26 @@ #define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) /*UOP_PSUBUSW - (packed word with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ #define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) +/*UOP_PSLLW_IMM - (packed word) dest_reg = src_reg_a << immediate*/ +#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) +/*UOP_PSLLD_IMM - (packed long) dest_reg = src_reg_a << immediate*/ +#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) +/*UOP_PSLLQ_IMM - (packed quad) dest_reg = src_reg_a << immediate*/ +#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) +/*UOP_PSRAW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ +#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) +/*UOP_PSRAD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ +#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) +/*UOP_PSRAQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ +#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) +/*UOP_PSRLW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ +#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) +/*UOP_PSRLD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ +#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) +/*UOP_PSRLQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ +#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) -#define UOP_MAX 0x9f +#define UOP_MAX 0xb0 #define UOP_MASK 0xffff @@ -561,6 +579,16 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) + #define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 4b17b81..fa7f769 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -14,6 +14,7 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_mmx_logic.h" +#include "codegen_ops_mmx_shift.h" #include "codegen_ops_mov.h" #include "codegen_ops_shift.h" #include "codegen_ops_stack.h" @@ -78,7 +79,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, +/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -100,7 +101,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, +/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_mmx_shift.c b/src/codegen_ops_mmx_shift.c new file mode 100644 index 0000000..ad0f597 --- /dev/null +++ b/src/codegen_ops_mmx_shift.c @@ -0,0 +1,87 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_shift.h" +#include "codegen_ops_helpers.h" + +uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); + + uop_MMX_ENTER(ir); + switch (op) + { + case 0x10: /*PSRLW*/ + uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAW*/ + uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLW*/ + uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + + } + + return op_pc + 2; +} +uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); + + uop_MMX_ENTER(ir); + switch (op) + { + case 0x10: /*PSRLD*/ + uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAD*/ + uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLD*/ + uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + + } + + return op_pc + 2; +} +uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); + + uop_MMX_ENTER(ir); + switch (op) + { + case 0x10: /*PSRLQ*/ + uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAQ*/ + uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLQ*/ + uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + + } + + return op_pc + 2; +} diff --git a/src/codegen_ops_mmx_shift.h b/src/codegen_ops_mmx_shift.h new file mode 100644 index 0000000..3a3b712 --- /dev/null +++ b/src/codegen_ops_mmx_shift.h @@ -0,0 +1,7 @@ +uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPSLLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSLLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPSLLQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From a991bc3249fd054b492334221d1483d7b4d46079 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 23 Nov 2018 15:17:21 +0000 Subject: [PATCH 0537/1050] Added recompiled versions of PCMP* --- src/codegen_backend_arm64_ops.c | 31 +++++++++++ src/codegen_backend_arm64_ops.h | 7 +++ src/codegen_backend_arm64_uops.c | 92 +++++++++++++++++++++++++++++++ src/codegen_backend_arm_ops.c | 32 +++++++++++ src/codegen_backend_arm_ops.h | 8 +++ src/codegen_backend_arm_uops.c | 92 +++++++++++++++++++++++++++++++ src/codegen_backend_x86-64_ops.c | 34 ++++++++++-- src/codegen_backend_x86-64_ops.h | 10 +++- src/codegen_backend_x86-64_uops.c | 92 +++++++++++++++++++++++++++++++ src/codegen_backend_x86_ops.c | 34 ++++++++++-- src/codegen_backend_x86_ops.h | 10 +++- src/codegen_backend_x86_uops.c | 92 +++++++++++++++++++++++++++++++ src/codegen_ir_defs.h | 19 +++++++ src/codegen_ops.c | 9 +-- src/codegen_ops_mmx_cmp.c | 43 +++++++++++++++ src/codegen_ops_mmx_cmp.h | 6 ++ 16 files changed, 593 insertions(+), 18 deletions(-) create mode 100644 src/codegen_ops_mmx_cmp.c create mode 100644 src/codegen_ops_mmx_cmp.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 06d431e..576b12f 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -112,6 +112,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_BIC_V (0x0e601c00) #define OPCODE_BLR (0xd63f0000) #define OPCODE_BR (0xd61f0000) +#define OPCODE_CMEQ_V8B (0x2e208c00) +#define OPCODE_CMEQ_V4H (0x2e608c00) +#define OPCODE_CMEQ_V2S (0x2ea08c00) +#define OPCODE_CMGT_V8B (0x0e203400) +#define OPCODE_CMGT_V4H (0x0e603400) +#define OPCODE_CMGT_V2S (0x0ea03400) #define OPCODE_EOR_V (0x2e201c00) #define OPCODE_FADD_D (0x1e602800) #define OPCODE_FCMP_D (0x1e602000) @@ -518,6 +524,31 @@ void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); } +void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 699988d..4dba688 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -48,6 +48,13 @@ void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); +void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index f19d6b8..4600f21 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1483,6 +1483,91 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -2269,6 +2354,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 17c29f9..b604f7e 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -92,6 +92,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VADD_I32 0xf2200800 #define OPCODE_VAND_D 0xf2000110 #define OPCODE_VBIC_D 0xf2100110 +#define OPCODE_VCEQ_I8 0xf3000810 +#define OPCODE_VCEQ_I16 0xf3100810 +#define OPCODE_VCEQ_I32 0xf3200810 +#define OPCODE_VCGT_S8 0xf2000300 +#define OPCODE_VCGT_S16 0xf2100300 +#define OPCODE_VCGT_S32 0xf2200300 #define OPCODE_VCMP_D 0xeeb40b40 #define OPCODE_VCVT_D_IS 0xeeb80bc0 #define OPCODE_VCVT_D_S 0xeeb70ac0 @@ -802,6 +808,32 @@ void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); } + +void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} + void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 5a1f792..6c7081a 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -146,6 +146,14 @@ void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_r void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m); + +void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); + void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 75d01b0..9f57130 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1603,6 +1603,91 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -2389,6 +2474,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 97bab1f..83a24fd 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1270,6 +1270,35 @@ void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ +} +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ +} +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ +} +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ +} +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ +} +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ +} void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { @@ -1346,11 +1375,6 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ -} - void host_x86_POP(codeblock_t *block, int dst_reg) { if (dst_reg & 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 119f854..ba2c0a5 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -164,6 +164,14 @@ void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); @@ -183,8 +191,6 @@ void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 331a12f..4bd8b0e 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1369,6 +1369,91 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -2040,6 +2125,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 1dbee0b..a3e63b7 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1128,6 +1128,35 @@ void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ +} +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ +} +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ +} +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ +} +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ +} +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ +} void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { @@ -1204,11 +1233,6 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ -} - void host_x86_POP(codeblock_t *block, int src_reg) { codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index f7483c2..bf1e492 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -165,6 +165,14 @@ void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); @@ -184,8 +192,6 @@ void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 7b5a8de..e8b11b9 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1372,6 +1372,91 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -2040,6 +2125,13 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 1fdd3a8..694b585 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -230,6 +230,18 @@ #define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) /*UOP_PSRLQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ #define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) +/*UOP_PCMPEQB - (packed byte) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ +#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) +/*UOP_PCMPEQW - (packed word) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ +#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) +/*UOP_PCMPEQD - (packed long) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ +#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) +/*UOP_PCMPGTB - (packed signed byte) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ +#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) +/*UOP_PCMPGTW - (packed signed word) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ +#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) +/*UOP_PCMPGTD - (packed signed long) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ +#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) #define UOP_MAX 0xb0 @@ -579,6 +591,13 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) + #define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) #define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) #define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index fa7f769..0ec4059 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -12,6 +12,7 @@ #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" #include "codegen_ops_mmx_arith.h" +#include "codegen_ops_mmx_cmp.h" #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_mmx_logic.h" #include "codegen_ops_mmx_shift.h" @@ -78,8 +79,8 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, -/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, +/*60*/ NULL, NULL, NULL, NULL, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, +/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -100,8 +101,8 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, -/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, +/*60*/ NULL, NULL, NULL, NULL, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, +/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops_mmx_cmp.c b/src/codegen_ops_mmx_cmp.c new file mode 100644 index 0000000..f56f413 --- /dev/null +++ b/src/codegen_ops_mmx_cmp.c @@ -0,0 +1,43 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_cmp.h" +#include "codegen_ops_helpers.h" + +#define ropPcmp(func) \ +uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + if ((fetchdat & 0xc0) == 0xc0) \ + { \ + int src_reg = fetchdat & 7; \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } \ + else \ + { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ +} + +ropPcmp(PCMPEQB) +ropPcmp(PCMPEQW) +ropPcmp(PCMPEQD) +ropPcmp(PCMPGTB) +ropPcmp(PCMPGTW) +ropPcmp(PCMPGTD) diff --git a/src/codegen_ops_mmx_cmp.h b/src/codegen_ops_mmx_cmp.h new file mode 100644 index 0000000..6069ad1 --- /dev/null +++ b/src/codegen_ops_mmx_cmp.h @@ -0,0 +1,6 @@ +uint32_t ropPCMPEQB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPCMPEQW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPCMPEQD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPCMPGTB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPCMPGTW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPCMPGTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 77af266ab2a389316d50d519a47186ba76023cc8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 23 Nov 2018 18:34:30 +0000 Subject: [PATCH 0538/1050] Added recompiled versions of PACK* and PUNPCK * --- src/codegen_backend_arm64_ops.c | 48 +++++++++ src/codegen_backend_arm64_ops.h | 12 +++ src/codegen_backend_arm64_uops.c | 147 +++++++++++++++++++++++++- src/codegen_backend_arm_ops.c | 27 +++++ src/codegen_backend_arm_ops.h | 7 ++ src/codegen_backend_arm_uops.c | 168 +++++++++++++++++++++++++++++- src/codegen_backend_x86-64_ops.c | 50 +++++++++ src/codegen_backend_x86-64_ops.h | 11 ++ src/codegen_backend_x86-64_uops.c | 141 ++++++++++++++++++++++++- src/codegen_backend_x86_ops.c | 50 +++++++++ src/codegen_backend_x86_ops.h | 11 ++ src/codegen_backend_x86_uops.c | 143 ++++++++++++++++++++++++- src/codegen_ir_defs.h | 31 +++++- src/codegen_ops.c | 5 +- src/codegen_ops_mmx_pack.c | 46 ++++++++ src/codegen_ops_mmx_pack.h | 9 ++ 16 files changed, 898 insertions(+), 8 deletions(-) create mode 100644 src/codegen_ops_mmx_pack.c create mode 100644 src/codegen_ops_mmx_pack.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 576b12f..c5e7fb0 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -160,6 +160,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SQADD_V4H (0x0e600c00) #define OPCODE_SQSUB_V8B (0x0e202c00) #define OPCODE_SQSUB_V4H (0x0e602c00) +#define OPCODE_SQXTN_V8B_8H (0x0e214800) +#define OPCODE_SQXTN_V4H_4S (0x0e614800) #define OPCODE_SHL_VD (0x0e005400) #define OPCODE_SHL_VQ (0x4e005400) #define OPCODE_SSHR_VD (0x0e004400) @@ -177,8 +179,15 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UQADD_V4H (0x2e600c00) #define OPCODE_UQSUB_V8B (0x2e202c00) #define OPCODE_UQSUB_V4H (0x2e602c00) +#define OPCODE_UQXTN_V8B_8H (0x2e214800) #define OPCODE_USHR_VD (0x2e004400) #define OPCODE_USHR_VQ (0x6e004400) +#define OPCODE_ZIP1_V8B (0x0e003800) +#define OPCODE_ZIP1_V4H (0x0e403800) +#define OPCODE_ZIP1_V2S (0x0e803800) +#define OPCODE_ZIP2_V8B (0x0e007800) +#define OPCODE_ZIP2_V4H (0x0e407800) +#define OPCODE_ZIP2_V2S (0x0e807800) #define DATPROC_SHIFT(sh) (sh << 10) #define DATPROC_IMM_SHIFT(sh) (sh << 22) @@ -965,6 +974,15 @@ void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int sr codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_SQXTN_V4B_4H(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SQXTN_V4B_4H | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) { codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); @@ -1129,6 +1147,11 @@ void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int sr codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) { codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); @@ -1142,6 +1165,31 @@ void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } +void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_call(codeblock_t *block, void *dst_addr) { int offset = add_literal_q(block, (uintptr_t)dst_addr); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 4dba688..77c02c7 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -152,6 +152,9 @@ void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SQXTN_V4H_4D(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); @@ -195,10 +198,19 @@ void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 4600f21..68f1122 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1384,6 +1384,55 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_VZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm64_UQXTN_V4H_4D(block, dest_reg, dest_reg); + host_arm64_UQXTN_V4H_4D(block, REG_V_TEMP, src_reg_b); + host_arm64_VZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_VZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PADDB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1824,6 +1873,91 @@ static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_VZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_VZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_VZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_VZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_VZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_VZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2346,6 +2480,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PADDB & UOP_MASK] = codegen_PADDB, [UOP_PADDW & UOP_MASK] = codegen_PADDW, [UOP_PADDD & UOP_MASK] = codegen_PADDD, @@ -2377,7 +2515,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index b604f7e..815c894 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -121,6 +121,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VQADD_S16 0xf2100010 #define OPCODE_VQADD_U8 0xf3000010 #define OPCODE_VQADD_U16 0xf3100010 +#define OPCODE_VQMOVN_S16 0xf3b20280 +#define OPCODE_VQMOVN_S32 0xf3b60280 +#define OPCODE_VQMOVN_U16 0xf3b202c0 #define OPCODE_VQSUB_S8 0xf2000210 #define OPCODE_VQSUB_S16 0xf2100210 #define OPCODE_VQSUB_U8 0xf3000210 @@ -140,6 +143,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VSUB_I8 0xf3000800 #define OPCODE_VSUB_I16 0xf3100800 #define OPCODE_VSUB_I32 0xf3200800 +#define OPCODE_VZIP_D16 0xf3b60180 +#define OPCODE_VZIP_D32 0xf3ba0180 #define B_OFFSET(x) (((x) >> 2) & 0xffffff) @@ -944,6 +949,19 @@ void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_ codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); +} +void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); +} +void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); +} + void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift) { if (shift > 15) @@ -1028,4 +1046,13 @@ void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_r codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) +{ + codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); +} +void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) +{ + codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); +} + #endif diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 6c7081a..28c3299 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -181,6 +181,10 @@ void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_r void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg); +void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg); +void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg); + void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dest_reg, int src_reg, int shift); @@ -197,3 +201,6 @@ void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); + +void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg); +void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 9f57130..7e9b6f8 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1504,6 +1504,55 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VQMOVN_S16(block, dest_reg, dest_reg); + host_arm_VQMOVN_S16(block, REG_D_TEMP, src_reg_b); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm_VQMOVN_S32(block, dest_reg, dest_reg); + host_arm_VQMOVN_S32(block, REG_D_TEMP, src_reg_b); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm_VQMOVN_U16(block, dest_reg, dest_reg); + host_arm_VQMOVN_U16(block, REG_D_TEMP, src_reg_b); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PADDB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1944,6 +1993,112 @@ static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + } + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + } + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2466,6 +2621,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PADDB & UOP_MASK] = codegen_PADDB, [UOP_PADDW & UOP_MASK] = codegen_PADDW, [UOP_PADDD & UOP_MASK] = codegen_PADDD, @@ -2497,7 +2656,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 83a24fd..9aabc0e 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1229,6 +1229,25 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} + void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ @@ -1375,6 +1394,37 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + void host_x86_POP(codeblock_t *block, int dst_reg) { if (dst_reg & 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index ba2c0a5..67bccb7 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -153,6 +153,10 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -191,6 +195,13 @@ void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 4bd8b0e..d960dca 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1270,6 +1270,49 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PADDB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1680,6 +1723,91 @@ static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2117,6 +2245,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PADDB & UOP_MASK] = codegen_PADDB, [UOP_PADDW & UOP_MASK] = codegen_PADDW, [UOP_PADDD & UOP_MASK] = codegen_PADDD, @@ -2148,7 +2280,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index a3e63b7..8376908 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1087,6 +1087,25 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ } } +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} + void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ @@ -1233,6 +1252,37 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + void host_x86_POP(codeblock_t *block, int src_reg) { codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index bf1e492..491c719 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -154,6 +154,10 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -192,6 +196,13 @@ void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index e8b11b9..654843b 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1273,6 +1273,49 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PADDB(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -1683,6 +1726,91 @@ static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2116,7 +2244,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, [UOP_FCOM & UOP_MASK] = codegen_FCOM, - + + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PADDB & UOP_MASK] = codegen_PADDB, [UOP_PADDW & UOP_MASK] = codegen_PADDW, [UOP_PADDD & UOP_MASK] = codegen_PADDD, @@ -2148,7 +2280,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 694b585..4029c2c 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -242,8 +242,26 @@ #define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) /*UOP_PCMPGTD - (packed signed long) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ #define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) +/*UOP_PUNPCKLBW - (packed byte) dest_reg = interleave low src_reg_a/src_reg_b*/ +#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) +/*UOP_PUNPCKLWD - (packed word) dest_reg = interleave low src_reg_a/src_reg_b*/ +#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) +/*UOP_PUNPCKLDQ - (packed long) dest_reg = interleave low src_reg_a/src_reg_b*/ +#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) +/*UOP_PUNPCKHBW - (packed byte) dest_reg = interleave high src_reg_a/src_reg_b*/ +#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) +/*UOP_PUNPCKHWD - (packed word) dest_reg = interleave high src_reg_a/src_reg_b*/ +#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) +/*UOP_PUNPCKHDQ - (packed long) dest_reg = interleave high src_reg_a/src_reg_b*/ +#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) +/*UOP_PACKSSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with signed saturation*/ +#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) +/*UOP_PACKSSDW - dest_reg = interleave src_reg_a/src_reg_b, converting longs to words with signed saturation*/ +#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) +/*UOP_PACKUSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with unsigned saturation*/ +#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) -#define UOP_MAX 0xb0 +#define UOP_MAX 0xb7 #define UOP_MASK 0xffff @@ -583,6 +601,10 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) #define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) +#define uop_PACKSSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSWB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) + #define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) @@ -616,6 +638,13 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHDQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLDQ, ir, dst_reg, src_reg_a, src_reg_b) + #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 0ec4059..71a2e86 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -15,6 +15,7 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_mmx_logic.h" +#include "codegen_ops_mmx_pack.h" #include "codegen_ops_mmx_shift.h" #include "codegen_ops_mov.h" #include "codegen_ops_shift.h" @@ -79,7 +80,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, +/*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, @@ -101,7 +102,7 @@ RecompOpFn recomp_opcodes_0f[512] = /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, +/*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, diff --git a/src/codegen_ops_mmx_pack.c b/src/codegen_ops_mmx_pack.c new file mode 100644 index 0000000..7bf1941 --- /dev/null +++ b/src/codegen_ops_mmx_pack.c @@ -0,0 +1,46 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_pack.h" +#include "codegen_ops_helpers.h" + +#define ropPpack(func) \ +uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + if ((fetchdat & 0xc0) == 0xc0) \ + { \ + int src_reg = fetchdat & 7; \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } \ + else \ + { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ +} + +ropPpack(PACKSSWB) +ropPpack(PACKSSDW) +ropPpack(PACKUSWB) +ropPpack(PUNPCKLBW) +ropPpack(PUNPCKLWD) +ropPpack(PUNPCKLDQ) +ropPpack(PUNPCKHBW) +ropPpack(PUNPCKHWD) +ropPpack(PUNPCKHDQ) diff --git a/src/codegen_ops_mmx_pack.h b/src/codegen_ops_mmx_pack.h new file mode 100644 index 0000000..f46eea6 --- /dev/null +++ b/src/codegen_ops_mmx_pack.h @@ -0,0 +1,9 @@ +uint32_t ropPACKSSWB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPACKSSDW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPACKUSWB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUNPCKLBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUNPCKLWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUNPCKLDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUNPCKHBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUNPCKHWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUNPCKHDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 086422b79fec0a1bcad6b39cb1e88f63187e6438 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Nov 2018 12:52:08 +0000 Subject: [PATCH 0539/1050] Added recompiled versions of PMULLW, PMULHW and PMADDWD. --- src/codegen_backend_arm64_ops.c | 36 +++++++++++++++++++---- src/codegen_backend_arm64_ops.h | 8 +++++ src/codegen_backend_arm64_uops.c | 49 +++++++++++++++++++++++++++++++ src/codegen_backend_arm_ops.c | 18 ++++++++++++ src/codegen_backend_arm_ops.h | 7 +++++ src/codegen_backend_arm_uops.c | 49 +++++++++++++++++++++++++++++++ src/codegen_backend_x86-64_ops.c | 13 ++++++++ src/codegen_backend_x86-64_ops.h | 4 +++ src/codegen_backend_x86-64_uops.c | 47 +++++++++++++++++++++++++++++ src/codegen_backend_x86_ops.c | 13 ++++++++ src/codegen_backend_x86_ops.h | 4 +++ src/codegen_backend_x86_uops.c | 47 +++++++++++++++++++++++++++++ src/codegen_ir_defs.h | 12 +++++++- src/codegen_ops.c | 12 ++++---- src/codegen_ops_mmx_arith.c | 4 +++ src/codegen_ops_mmx_arith.h | 4 +++ 16 files changed, 314 insertions(+), 13 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index c5e7fb0..1ae57d9 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -151,9 +151,11 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LSL (0x1ac02000) #define OPCODE_LSR (0x1ac02400) #define OPCODE_MSR_FPCR (0xd51b4400) +#define OPCODE_MUL_V4H (0x0e609c00) #define OPCODE_NOP (0xd503201f) #define OPCODE_ORR_V (0x0ea01c00) #define OPCODE_RET (0xd65f0000) +#define OPCODE_SADDLP_V2S_4H (0x0e602800) #define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) #define OPCODE_SQADD_V8B (0x0e200c00) @@ -164,6 +166,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SQXTN_V4H_4S (0x0e614800) #define OPCODE_SHL_VD (0x0e005400) #define OPCODE_SHL_VQ (0x4e005400) +#define OPCODE_SHRN (0x0f008400) +#define OPCODE_SMULL_V4S_4H (0x0e60c000) #define OPCODE_SSHR_VD (0x0e004400) #define OPCODE_SSHR_VQ (0x4e004400) #define OPCODE_STR_REG (0xb8206800) @@ -900,6 +904,11 @@ void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); } +void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_NOP(codeblock_t *block) { codegen_addlong(block, OPCODE_NOP); @@ -943,6 +952,11 @@ void host_arm64_RET(codeblock_t *block, int reg) codegen_addlong(block, OPCODE_RET | Rn(reg)); } +void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) +{ + codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); +} + void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); @@ -957,6 +971,16 @@ void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_SHRN_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | SHIFT_IMM_V2S(shift)); +} + +void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); @@ -983,28 +1007,28 @@ void host_arm64_SQXTN_V4B_4H(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SQXTN_V4B_4H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); } -void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); } -void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } -void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); } -void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); } -void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 77c02c7..01dd50c 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -134,6 +134,8 @@ void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data); void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg); +void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_NOP(codeblock_t *block); void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); @@ -142,6 +144,8 @@ void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_RET(codeblock_t *block, int reg); +void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg); + void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg); @@ -159,6 +163,10 @@ void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift) void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); + +void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 68f1122..18b1d48 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1617,6 +1617,51 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_SADDLP_V2S_4H(block, dest_reg, dest_reg); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -2499,6 +2544,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 815c894..c0a5a6a 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -116,7 +116,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMRS_APSR 0xeef1fa10 #define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 +#define OPCODE_VMUL_S16 0xf2100510 +#define OPCODE_VMULL_S16 0xf2900c00 #define OPCODE_VORR_D 0xf2200110 +#define OPCODE_VPADDL_S16 0xf3b40200 #define OPCODE_VQADD_S8 0xf2000010 #define OPCODE_VQADD_S16 0xf2100010 #define OPCODE_VQADD_U8 0xf3000010 @@ -907,15 +910,30 @@ void host_arm_VMRS_APSR(codeblock_t *block) { codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); } + void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} + void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); +} + void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 28c3299..946d7d5 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -170,8 +170,15 @@ void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMRS_APSR(codeblock_t *block); void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); + void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VMUL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); +void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); + void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); + +void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg); + void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 7e9b6f8..11e9f8f 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1737,6 +1737,51 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); + host_arm_VPADDL_S16(block, dest_reg, dest_reg); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm_VMULL_S16(block, dest_reg, src_reg_a, src_reg_b); + host_arm_VSHRN_16(block, dest_reg, dest_reg, 16); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -2640,6 +2685,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 9aabc0e..ed57f2a 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1319,6 +1319,19 @@ void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} + void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 67bccb7..35510d0 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -177,6 +177,10 @@ void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d960dca..faf5c33 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1497,6 +1497,49 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -2264,6 +2307,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 8376908..e477122 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1177,6 +1177,19 @@ void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} + void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 491c719..cd9eb4e 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -178,6 +178,10 @@ void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 654843b..c977bae 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1500,6 +1500,49 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); @@ -2264,6 +2307,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 4029c2c..eea588f 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -260,8 +260,14 @@ #define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) /*UOP_PACKUSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with unsigned saturation*/ #define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) +/*UOP_PMULLW - (packed word) dest_reg = (src_reg_a * src_reg_b) & 0xffff*/ +#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) +/*UOP_PMULHW - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ +#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) +/*UOP_PMADDWD - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ +#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) -#define UOP_MAX 0xb7 +#define UOP_MAX 0xba #define UOP_MASK 0xffff @@ -620,6 +626,10 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) + #define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) #define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) #define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 71a2e86..00e4018 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -89,9 +89,9 @@ RecompOpFn recomp_opcodes_0f[512] = /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +/*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -111,9 +111,9 @@ RecompOpFn recomp_opcodes_0f[512] = /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +/*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, }; RecompOpFn recomp_opcodes_d8[512] = diff --git a/src/codegen_ops_mmx_arith.c b/src/codegen_ops_mmx_arith.c index 848c046..cd23e3c 100644 --- a/src/codegen_ops_mmx_arith.c +++ b/src/codegen_ops_mmx_arith.c @@ -50,3 +50,7 @@ ropParith(PSUBSB) ropParith(PSUBSW) ropParith(PSUBUSB) ropParith(PSUBUSW) + +ropParith(PMADDWD) +ropParith(PMULHW) +ropParith(PMULLW) diff --git a/src/codegen_ops_mmx_arith.h b/src/codegen_ops_mmx_arith.h index e848c8d..5f67f0a 100644 --- a/src/codegen_ops_mmx_arith.h +++ b/src/codegen_ops_mmx_arith.h @@ -13,3 +13,7 @@ uint32_t ropPSUBSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropPSUBSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPSUBUSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPSUBUSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPMADDWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPMULHW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPMULLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 2a19183d836bfa415733cfeca2e25e8abb3db9a4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Nov 2018 20:16:52 +0000 Subject: [PATCH 0540/1050] Added debug code to log execution rate of non-recompiled instructions. --- src/codegen.c | 40 +++++++++++++++++++++++++++++++++- src/codegen.h | 7 ++++++ src/codegen_backend.c | 35 +++++++++++++++++++++++++++++ src/codegen_backend_x86_ops.c | 6 +++++ src/codegen_backend_x86_ops.h | 2 ++ src/codegen_backend_x86_uops.c | 16 +++++++++++++- src/codegen_ir_defs.h | 10 +++++++++ src/pc.c | 1 + 8 files changed, 115 insertions(+), 2 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index d06438c..dfa9ea4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -310,7 +310,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t int over = 0; int test_modrm = 1; int pc_off = 0; - +#ifdef DEBUG_EXTRA + uint8_t last_prefix = 0; +#endif op_ea_seg = &cpu_state.seg_ds; op_ssegs = 0; @@ -321,6 +323,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t switch (opcode) { case 0x0f: +#ifdef DEBUG_EXTRA + last_prefix = 0x0f; +#endif op_table = x86_dynarec_opcodes_0f; recomp_op_table = recomp_opcodes_0f; over = 1; @@ -359,6 +364,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xd8: +#ifdef DEBUG_EXTRA + last_prefix = 0xd8; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; recomp_op_table = recomp_opcodes_d8; opcode_shift = 3; @@ -369,6 +377,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xd9: +#ifdef DEBUG_EXTRA + last_prefix = 0xd9; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; recomp_op_table = recomp_opcodes_d9; opcode_mask = 0xff; @@ -378,6 +389,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xda: +#ifdef DEBUG_EXTRA + last_prefix = 0xda; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; recomp_op_table = recomp_opcodes_da; opcode_mask = 0xff; @@ -387,6 +401,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdb: +#ifdef DEBUG_EXTRA + last_prefix = 0xdb; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; recomp_op_table = recomp_opcodes_db; opcode_mask = 0xff; @@ -396,6 +413,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdc: +#ifdef DEBUG_EXTRA + last_prefix = 0xdc; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; recomp_op_table = recomp_opcodes_dc; opcode_shift = 3; @@ -406,6 +426,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdd: +#ifdef DEBUG_EXTRA + last_prefix = 0xdd; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; recomp_op_table = recomp_opcodes_dd; opcode_mask = 0xff; @@ -415,6 +438,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xde: +#ifdef DEBUG_EXTRA + last_prefix = 0xde; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; recomp_op_table = recomp_opcodes_de; opcode_mask = 0xff; @@ -424,6 +450,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdf: +#ifdef DEBUG_EXTRA + last_prefix = 0xdf; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; recomp_op_table = recomp_opcodes_df; opcode_mask = 0xff; @@ -437,10 +466,16 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xf2: /*REPNE*/ +#ifdef DEBUG_EXTRA + last_prefix = 0xf2; +#endif op_table = x86_dynarec_opcodes_REPNE; recomp_op_table = NULL;//recomp_opcodes_REPNE; break; case 0xf3: /*REPE*/ +#ifdef DEBUG_EXTRA + last_prefix = 0xf3; +#endif op_table = x86_dynarec_opcodes_REPE; recomp_op_table = NULL;//recomp_opcodes_REPE; break; @@ -525,6 +560,9 @@ generate_call: op_pc -= pc_off; } +#ifdef DEBUG_EXTRA + uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); +#endif uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); uop_MOV_IMM(ir, IREG_oldpc, old_pc); diff --git a/src/codegen.h b/src/codegen.h index 7136330..dcca68b 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -252,6 +252,7 @@ extern codeblock_t *codeblock; extern codeblock_t **codeblock_hash; void codegen_init(); +void codegen_close(); void codegen_reset(); void codegen_block_init(uint32_t phys_addr); void codegen_block_remove(); @@ -330,4 +331,10 @@ extern int codegen_reg_loaded[8]; extern int codegen_in_recompile; void codegen_generate_reset(); + + +#ifdef DEBUG_EXTRA +extern uint32_t instr_counts[256*256]; +#endif + #endif diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 7d96ec3..fa01aa8 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -46,10 +46,45 @@ static uint32_t last_op32; static x86seg *last_ea_seg; static int last_ssegs; +#ifdef DEBUG_EXTRA +uint32_t instr_counts[256*256]; +#endif void codegen_init() { codegen_backend_init(); +#ifdef DEBUG_EXTRA + memset(instr_counts, 0, sizeof(instr_counts)); +#endif +} + +void codegen_close() +{ +#ifdef DEBUG_EXTRA + pclog("Instruction counts :\n"); + while (1) + { + int c; + uint32_t highest_num = 0, highest_idx = 0; + + for (c = 0; c < 256*256; c++) + { + if (instr_counts[c] > highest_num) + { + highest_num = instr_counts[c]; + highest_idx = c; + } + } + if (!highest_num) + break; + + instr_counts[highest_idx] = 0; + if (highest_idx > 256) + pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); + else + pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + } +#endif } void codegen_reset() diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index e477122..33dc124 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -343,6 +343,12 @@ void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } +void host_x86_INC32_ABS(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ + codegen_addlong(block, (uint32_t)p); +} + void host_x86_JMP(codeblock_t *block, void *p) { codegen_addbyte(block, 0xe9); /*JMP*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index cd9eb4e..5084c5e 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -39,6 +39,8 @@ void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_INC32_ABS(codeblock_t *block, void *p); + void host_x86_JMP(codeblock_t *block, void *p); uint32_t *host_x86_JMP_short(codeblock_t *block); uint32_t *host_x86_JMP_long(codeblock_t *block); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c977bae..a5ff9d9 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2192,6 +2192,16 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) return 0; } +#ifdef DEBUG_EXTRA +static int codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) +{ + if (uop->imm_data > 256*256) + fatal("LOG_INSTR %08x\n", uop->imm_data); + host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); + return 0; +} +#endif + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, @@ -2334,7 +2344,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + +#ifdef DEBUG_EXTRA + [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR +#endif }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index eea588f..4a32aa7 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -54,6 +54,12 @@ #define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_JMP_DEST - jump to ptr*/ #define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) + +#ifdef DEBUG_EXTRA +/*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ +#define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) +#endif + /*UOP_MOV_PTR - dest_reg = p*/ #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ @@ -661,6 +667,10 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) #define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) +#ifdef DEBUG_EXTRA +#define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) +#endif + void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); diff --git a/src/pc.c b/src/pc.c index faeaa1a..ea77535 100644 --- a/src/pc.c +++ b/src/pc.c @@ -624,6 +624,7 @@ void speedchanged() void closepc() { + codegen_close(); atapi->exit(); // ioctl_close(); dumppic(); From 6341caf318289e7753360c04081dc988ed417616 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 24 Nov 2018 20:35:33 +0000 Subject: [PATCH 0541/1050] ARM MMX fixes --- src/codegen_backend_arm_defs.h | 2 + src/codegen_backend_arm_ops.c | 68 +++++++++++++++------ src/codegen_backend_arm_ops.h | 8 +++ src/codegen_backend_arm_uops.c | 106 +++++++++++++++++++++------------ 4 files changed, 129 insertions(+), 55 deletions(-) diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index 7deb72f..def8970 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -43,6 +43,8 @@ #define REG_D15 15 #define REG_D_TEMP REG_D0 +#define REG_Q_TEMP REG_D0 +#define REG_Q_TEMP_2 REG_D2 #define REG_MASK_R0 (1 << REG_R0) #define REG_MASK_R1 (1 << REG_R1) diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index c0a5a6a..b6692a7 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -113,13 +113,17 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMOV_D_64 0xec400b10 #define OPCODE_VMOV_S_32 0xee000a10 #define OPCODE_VMOV_D_D 0xeeb00b40 +#define OPCODE_VMOVN_I32 0xf3b60200 +#define OPCODE_VMOVN_I64 0xf3ba0200 #define OPCODE_VMRS_APSR 0xeef1fa10 #define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 -#define OPCODE_VMUL_S16 0xf2100510 +#define OPCODE_VMUL_S16 0xf2100910 #define OPCODE_VMULL_S16 0xf2900c00 #define OPCODE_VORR_D 0xf2200110 #define OPCODE_VPADDL_S16 0xf3b40200 +#define OPCODE_VPADDL_S32 0xf3b80200 +#define OPCODE_VPADDL_Q_S32 0xf3b80240 #define OPCODE_VQADD_S8 0xf2000010 #define OPCODE_VQADD_S16 0xf2100010 #define OPCODE_VQADD_U8 0xf3000010 @@ -140,14 +144,16 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VSHR_D_U16 0xf3900010 #define OPCODE_VSHR_D_U32 0xf3a00010 #define OPCODE_VSHR_D_U64 0xf3800090 +#define OPCODE_VSHRN 0xf2800810 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 #define OPCODE_VSUB_I8 0xf3000800 #define OPCODE_VSUB_I16 0xf3100800 #define OPCODE_VSUB_I32 0xf3200800 +#define OPCODE_VZIP_D8 0xf3b20180 #define OPCODE_VZIP_D16 0xf3b60180 -#define OPCODE_VZIP_D32 0xf3ba0180 +#define OPCODE_VZIP_D32 0xf3ba0080 #define B_OFFSET(x) (((x) >> 2) & 0xffffff) @@ -182,6 +188,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define VSHIFT_IMM(shift) ((shift) << 16) +#define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) + static inline uint32_t arm_data_offset(int offset) { if (offset < -0xffc || offset > 0xffc) @@ -902,6 +910,14 @@ void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); +} +void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); @@ -933,6 +949,14 @@ void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); } +void host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); +} +void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); +} void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { @@ -980,59 +1004,65 @@ void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 15) fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 31) fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 63) fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHR_SD_16(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 15) fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_SD_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); } -void host_arm_VSHR_SD_32(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 31) fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_SD_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); } -void host_arm_VSHR_SD_64(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 63) fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_SD_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); } -void host_arm_VSHR_UD_16(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 15) fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_UD_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); } -void host_arm_VSHR_UD_32(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 31) fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_UD_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); } -void host_arm_VSHR_UD_64(codeblock_t *block, int dest_reg, int src_reg, int shift) +void host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) { if (shift > 63) fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_UD_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); +} +void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + if (shift > 16) + fatal("host_arm_VSHRN_32 : shift > 16\n"); + codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift)); } void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) @@ -1064,6 +1094,10 @@ void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_r codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) +{ + codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); +} void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) { codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 946d7d5..edfbbc1 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -163,11 +163,15 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset); + void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg); void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high); void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg); + void host_arm_VMRS_APSR(codeblock_t *block); void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); @@ -178,6 +182,8 @@ void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg); +void host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg); +void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg); void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); @@ -201,6 +207,7 @@ void host_arm_VSHR_D_S64(codeblock_t *block, int dest_reg, int src_reg, int shif void host_arm_VSHR_D_U16(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSHR_D_U32(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSHRN_32(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); @@ -209,5 +216,6 @@ void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_re void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg); void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg); void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 11e9f8f..c63a370 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1290,7 +1290,7 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { - host_arm_VMOV_32_S(block, dest_reg, src_reg, REG_TEMP); + host_arm_VMOV_32_S(block, dest_reg, src_reg); } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { @@ -1511,8 +1511,10 @@ static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_VQMOVN_S16(block, dest_reg, dest_reg); - host_arm_VQMOVN_S16(block, REG_D_TEMP, src_reg_b); + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); } else @@ -1522,13 +1524,15 @@ static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) } static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_VQMOVN_S32(block, dest_reg, dest_reg); - host_arm_VQMOVN_S32(block, REG_D_TEMP, src_reg_b); + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); } else @@ -1538,13 +1542,15 @@ static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) } static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_VQMOVN_U16(block, dest_reg, dest_reg); - host_arm_VQMOVN_U16(block, REG_D_TEMP, src_reg_b); + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); } else @@ -1739,13 +1745,14 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); - host_arm_VPADDL_S16(block, dest_reg, dest_reg); + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); + host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); } else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1754,13 +1761,13 @@ static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) } static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_VMULL_S16(block, dest_reg, src_reg_a, src_reg_b); - host_arm_VSHRN_16(block, dest_reg, dest_reg, 16); + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); } else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1769,10 +1776,10 @@ static int codegen_PMULHW(codeblock_t *block, uop_t *uop) } static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); } @@ -1789,7 +1796,9 @@ static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 15) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); @@ -1806,7 +1815,9 @@ static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 31) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); @@ -1823,7 +1834,9 @@ static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 63) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); @@ -1840,7 +1853,9 @@ static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 15) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); else host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); @@ -1857,7 +1872,9 @@ static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 31) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); else host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); @@ -1874,7 +1891,9 @@ static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 63) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); else host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); @@ -1891,7 +1910,9 @@ static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 15) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); @@ -1908,7 +1929,9 @@ static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 31) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); @@ -1925,7 +1948,9 @@ static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 63) + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); @@ -1966,9 +1991,6 @@ static int codegen_PSUBW(codeblock_t *block, uop_t *uop) } static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -2851,6 +2873,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); +} void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); @@ -2863,6 +2889,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos else fatal("codegen_direct_write_32 - not in range\n"); } +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); +} void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); From 856f0b447196a3dc1c419341724ec84b862a92b4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 25 Nov 2018 17:59:38 +0000 Subject: [PATCH 0542/1050] ARM64 MMX fixes --- src/codegen_backend_arm64_ops.c | 81 +++++++++++++++----- src/codegen_backend_arm64_ops.h | 16 ++-- src/codegen_backend_arm64_uops.c | 125 ++++++++++++++++++------------- 3 files changed, 146 insertions(+), 76 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 1ae57d9..9dabfe4 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -107,6 +107,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ADD_V8B (0x0e208400) #define OPCODE_ADD_V4H (0x0e608400) #define OPCODE_ADD_V2S (0x0ea08400) +#define OPCODE_ADDP_V4S (0x4ea0bc00) #define OPCODE_AND_V (0x0e201c00) #define OPCODE_ASR (0x1ac02800) #define OPCODE_BIC_V (0x0e601c00) @@ -164,12 +165,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SQSUB_V4H (0x0e602c00) #define OPCODE_SQXTN_V8B_8H (0x0e214800) #define OPCODE_SQXTN_V4H_4S (0x0e614800) -#define OPCODE_SHL_VD (0x0e005400) -#define OPCODE_SHL_VQ (0x4e005400) +#define OPCODE_SHL_VD (0x0f005400) +#define OPCODE_SHL_VQ (0x4f005400) #define OPCODE_SHRN (0x0f008400) #define OPCODE_SMULL_V4S_4H (0x0e60c000) -#define OPCODE_SSHR_VD (0x0e004400) -#define OPCODE_SSHR_VQ (0x4e004400) +#define OPCODE_SSHR_VD (0x0f000400) +#define OPCODE_SSHR_VQ (0x4f000400) #define OPCODE_STR_REG (0xb8206800) #define OPCODE_STRB_REG (0x38206800) #define OPCODE_STRH_REG (0x78206800) @@ -184,8 +185,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UQSUB_V8B (0x2e202c00) #define OPCODE_UQSUB_V4H (0x2e602c00) #define OPCODE_UQXTN_V8B_8H (0x2e214800) -#define OPCODE_USHR_VD (0x2e004400) -#define OPCODE_USHR_VQ (0x6e004400) +#define OPCODE_UQXTN_V4H_4S (0x2e614800) +#define OPCODE_USHR_VD (0x2f000400) +#define OPCODE_USHR_VQ (0x6f000400) #define OPCODE_ZIP1_V8B (0x0e003800) #define OPCODE_ZIP1_V4H (0x0e403800) #define OPCODE_ZIP1_V2S (0x0e803800) @@ -220,6 +222,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define SHIFT_IMM_V2S(shift) (((shift) | 0x20) << 16) #define SHIFT_IMM_V2D(shift) (((shift) | 0x40) << 16) +#define SHRN_SHIFT_IMM_V4S(shift) (((shift) | 0x10) << 16) + static int literal_offset = 0; void codegen_reset_literal_pool(codeblock_t *block) { @@ -312,6 +316,22 @@ void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); } } +void host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) +{ + if (!(imm_data & ~0xffffffull)) + { + if (imm_data & 0xfff) + { + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else + fatal("ADD_IMM_X %016llx\n", imm_data); +} void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); @@ -333,6 +353,11 @@ void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_ codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) { codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); @@ -971,9 +996,11 @@ void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHRN_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | SHIFT_IMM_V2S(shift)); + if (shift > 16) + fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); + codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16-shift)); } void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) @@ -1002,9 +1029,9 @@ void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SQXTN_V4B_4H(codeblock_t *block, int dst_reg, int src_reg) +void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SQXTN_V4B_4H | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) @@ -1022,15 +1049,21 @@ void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shif void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); } void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); + if (shift > 32) + fatal("host_arm_SSHR_V2S : shift > 32\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); } void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); + if (shift > 64) + fatal("host_arm_SSHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); } void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) @@ -1175,18 +1208,28 @@ void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); +} -void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); } -void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); + if (shift > 32) + fatal("host_arm_USHR_V4S : shift > 32\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); } -void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift) +void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); + if (shift > 64) + fatal("host_arm_USHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); } void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 01dd50c..179c5af 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -4,6 +4,9 @@ void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data); + +void host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset); @@ -157,13 +160,13 @@ void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); -void host_arm64_SQXTN_V4H_4D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift); -void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift); void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); @@ -201,12 +204,13 @@ uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit); void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); -void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); -void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 18b1d48..4f34ea3 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1386,14 +1386,14 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_VZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1407,9 +1407,9 @@ static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_UQXTN_V4H_4D(block, dest_reg, dest_reg); - host_arm64_UQXTN_V4H_4D(block, REG_V_TEMP, src_reg_b); - host_arm64_VZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1423,9 +1423,9 @@ static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_VZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1510,7 +1510,7 @@ static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_UQADD_V8H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1553,7 +1553,7 @@ static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1567,7 +1567,7 @@ static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1581,7 +1581,7 @@ static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1595,7 +1595,7 @@ static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1609,7 +1609,7 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1619,13 +1619,13 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); - host_arm64_SADDLP_V2S_4H(block, dest_reg, dest_reg); + host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); + host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); } else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1634,10 +1634,10 @@ static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) } static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); @@ -1649,10 +1649,10 @@ static int codegen_PMULHW(codeblock_t *block, uop_t *uop) } static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); } @@ -1669,7 +1669,9 @@ static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 15) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); @@ -1686,7 +1688,9 @@ static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 31) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); @@ -1703,7 +1707,9 @@ static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 63) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); @@ -1720,7 +1726,9 @@ static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 15) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); else host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); @@ -1737,7 +1745,9 @@ static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 31) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); else host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); @@ -1754,7 +1764,9 @@ static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 63) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); else host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); @@ -1771,7 +1783,9 @@ static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 15) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); @@ -1788,7 +1802,9 @@ static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 31) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); @@ -1805,7 +1821,9 @@ static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - if (uop->imm_data > 63) + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); @@ -1846,9 +1864,6 @@ static int codegen_PSUBW(codeblock_t *block, uop_t *uop) } static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); @@ -1925,7 +1940,7 @@ static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_VZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1939,7 +1954,7 @@ static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_VZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1953,7 +1968,7 @@ static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_VZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1967,7 +1982,7 @@ static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_VZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1981,7 +1996,7 @@ static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_VZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1995,7 +2010,7 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm64_VZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -2613,7 +2628,7 @@ void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } @@ -2621,7 +2636,7 @@ void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } @@ -2629,7 +2644,7 @@ void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } @@ -2673,7 +2688,7 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } @@ -2681,7 +2696,7 @@ void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } @@ -2689,7 +2704,7 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } @@ -2716,6 +2731,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32_stack - not in range\n"); } +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); +} void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); @@ -2728,6 +2747,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos else fatal("codegen_direct_write_32_stack - not in range\n"); } +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_arm64_STR_IMM_F64(block, host_reg, REG_SP, stack_offset); +} void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { host_arm64_STR_IMM_F64(block, host_reg, REG_SP, stack_offset); From 07035c97c850cce90e8e75cee7e929b25fa2498b Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Nov 2018 17:00:00 +0000 Subject: [PATCH 0543/1050] Added recompiled versions of FABS, FCHS, FSQRT and FTST. --- src/codegen_backend_arm64_ops.c | 18 ++++++++ src/codegen_backend_arm64_ops.h | 4 ++ src/codegen_backend_arm64_uops.c | 70 ++++++++++++++++++++++++++++ src/codegen_backend_arm_ops.c | 18 ++++++++ src/codegen_backend_arm_ops.h | 6 +++ src/codegen_backend_arm_uops.c | 68 +++++++++++++++++++++++++++ src/codegen_backend_x86-64_ops.c | 10 ++++ src/codegen_backend_x86-64_ops.h | 4 ++ src/codegen_backend_x86-64_uops.c | 77 +++++++++++++++++++++++++++++++ src/codegen_backend_x86_ops.c | 10 ++++ src/codegen_backend_x86_ops.h | 4 ++ src/codegen_backend_x86_uops.c | 77 +++++++++++++++++++++++++++++++ src/codegen_ir_defs.h | 13 ++++++ src/codegen_ops.c | 8 ++-- src/codegen_ops_fpu_arith.c | 36 +++++++++++++++ src/codegen_ops_fpu_arith.h | 5 ++ 16 files changed, 424 insertions(+), 4 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 9dabfe4..ee2c0b6 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -120,6 +120,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_CMGT_V4H (0x0e603400) #define OPCODE_CMGT_V2S (0x0ea03400) #define OPCODE_EOR_V (0x2e201c00) +#define OPCODE_FABS_D (0x1e60c000) #define OPCODE_FADD_D (0x1e602800) #define OPCODE_FCMP_D (0x1e602000) #define OPCODE_FCVT_D_S (0x1e22c000) @@ -139,7 +140,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_FMOV_S_W (0x1e270000) #define OPCODE_FMOV_W_S (0x1e260000) #define OPCODE_FMUL_D (0x1e600800) +#define OPCODE_FNEG_D (0x1e614000) #define OPCODE_FRINTX_D (0x1e674000) +#define OPCODE_FSQRT_D (0x1e61c000) #define OPCODE_FSUB_D (0x1e603800) #define OPCODE_LDR_REG (0xb8606800) #define OPCODE_LDRX_REG (0xf8606800) @@ -680,6 +683,11 @@ void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); @@ -768,11 +776,21 @@ void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 179c5af..048c354 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -75,6 +75,8 @@ void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg); void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); @@ -101,6 +103,8 @@ void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 4f34ea3..0ee74dc 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -619,6 +619,71 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_arm64_FABS_D(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_arm64_FNEG_D(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_arm64_FSQRT_D(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) + { + host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_FADD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2540,6 +2605,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index b6692a7..12e9c68 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -86,6 +86,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_USUB16 0xe6500f70 #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 +#define OPCODE_VABS_D 0xeeb00bc0 #define OPCODE_VADD 0xee300b00 #define OPCODE_VADD_I8 0xf2000800 #define OPCODE_VADD_I16 0xf2100800 @@ -120,6 +121,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMUL 0xee200b00 #define OPCODE_VMUL_S16 0xf2100910 #define OPCODE_VMULL_S16 0xf2900c00 +#define OPCODE_VNEG_D 0xeeb10b40 #define OPCODE_VORR_D 0xf2200110 #define OPCODE_VPADDL_S16 0xf3b40200 #define OPCODE_VPADDL_S32 0xf3b80200 @@ -145,6 +147,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VSHR_D_U32 0xf3a00010 #define OPCODE_VSHR_D_U64 0xf3800090 #define OPCODE_VSHRN 0xf2800810 +#define OPCODE_VSQRT_D 0xeeb10bc0 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 @@ -796,6 +799,11 @@ void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } +void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); +} + void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -940,6 +948,11 @@ void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_ codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); +} + void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -1065,6 +1078,11 @@ void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift)); } +void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); +} + void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index edfbbc1..542dc2a 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -139,6 +139,8 @@ void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); +void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg); + void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); @@ -154,6 +156,8 @@ void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_re void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCHS_D(codeblock_t *block, int dest_reg, int src_reg); + void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); @@ -179,6 +183,8 @@ void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg void host_arm_VMUL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); +void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg); + void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index c63a370..a9ce03e 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -693,6 +693,69 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_arm_VABS_D(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_arm_VNEG_D(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_arm_VSQRT_D(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) + { + host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); + host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); + } + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_FADD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2688,6 +2751,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index ed57f2a..4ec3fd4 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -548,6 +548,11 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ +} + void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -1571,6 +1576,11 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} + void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 35510d0..10fe26a 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -71,6 +71,8 @@ void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); @@ -236,6 +238,8 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index faf5c33..dc87d53 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -548,6 +548,78 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) + { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) + { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + if (dest_reg != REG_EAX) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_FADD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2288,6 +2360,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 33dc124..a861d14 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -513,6 +513,11 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ } +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ +} + void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -1397,6 +1402,11 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} + void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg) diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 5084c5e..d07b0d9 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -75,6 +75,8 @@ void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32 void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); @@ -239,6 +241,8 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index a5ff9d9..20f39a7 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -559,6 +559,78 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_FABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) + { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) + { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) + { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + if (dest_reg != REG_EAX) + { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_FADD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2297,6 +2369,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_FMUL & UOP_MASK] = codegen_FMUL, [UOP_FSUB & UOP_MASK] = codegen_FSUB, [UOP_FCOM & UOP_MASK] = codegen_FCOM, + + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 4a32aa7..15b3014 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -187,6 +187,14 @@ #define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) /*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/ #define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) +/*UOP_FABS - dest_reg = fabs(src_reg_a)*/ +#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) +/*UOP_FCHS - dest_reg = fabs(src_reg_a)*/ +#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) +/*UOP_FTST - dest_reg = flags from compare(src_reg_a, 0)*/ +#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) +/*UOP_FSQRT - dest_reg = fsqrt(src_reg_a)*/ +#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) /*UOP_MMX_ENTER - must be called before any MMX registers accessed*/ #define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) @@ -582,6 +590,11 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) #define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FABS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FABS, ir, dst_reg, src_reg) +#define uop_FCHS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FCHS, ir, dst_reg, src_reg) +#define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) +#define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) + #define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0) #define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 00e4018..8dc433a 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -184,8 +184,8 @@ RecompOpFn recomp_opcodes_d9[512] = /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -206,8 +206,8 @@ RecompOpFn recomp_opcodes_d9[512] = /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL, }; RecompOpFn recomp_opcodes_da[512] = diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index d903959..9d4259c 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -534,3 +534,39 @@ uint32_t ropFISUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, ui ropFI_arith_mem(l, IREG_temp0) ropFI_arith_mem(w, IREG_temp0_W) + + +uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_FABS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} + +uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + + return op_pc; +} +uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_FP_ENTER(ir); + uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + + return op_pc; +} diff --git a/src/codegen_ops_fpu_arith.h b/src/codegen_ops_fpu_arith.h index e61d4ae..60ae273 100644 --- a/src/codegen_ops_fpu_arith.h +++ b/src/codegen_ops_fpu_arith.h @@ -56,3 +56,8 @@ uint32_t ropFISUBl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropFISUBw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFISUBRl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFISUBRw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From c034381797a30a0b3d6a47e931e2723213fa64d8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Nov 2018 17:36:47 +0000 Subject: [PATCH 0544/1050] Added Trigem Korean VGA emulation. Patch from Greatpsycho. --- src/ibm.h | 1 + src/vid_ati28800.c | 1 + src/vid_et4000.c | 172 ++++++++++++++++++++++++++++++++++++++++++ src/vid_et4000.h | 1 + src/vid_svga.h | 2 + src/vid_svga_render.c | 12 ++- src/video.c | 1 + 7 files changed, 186 insertions(+), 4 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 4bab0e3..50f59b8 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -481,6 +481,7 @@ enum GFX_EGA, /*Using IBM EGA BIOS*/ GFX_TVGA, /*Using Trident TVGA8900D BIOS*/ GFX_ET4000, /*Tseng ET4000*/ + GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/ GFX_ET4000W32, /*Tseng ET4000/W32p (Diamond Stealth 32)*/ GFX_BAHAMAS64, /*S3 Vision864 (Paradise Bahamas 64)*/ GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/ diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 275432d..845b0ee 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -376,6 +376,7 @@ void *ati28800k_init() io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); ati28800->svga.miscout = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0); diff --git a/src/vid_et4000.c b/src/vid_et4000.c index f24acbc..174fbdd 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -7,6 +7,7 @@ #include "rom.h" #include "video.h" #include "vid_svga.h" +#include "vid_svga_render.h" #include "vid_unk_ramdac.h" #include "vid_et4000.h" @@ -19,6 +20,11 @@ typedef struct et4000_t rom_t bios_rom; uint8_t banking; + uint8_t port_22cb_val; + uint8_t port_32cb_val; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; } et4000_t; static uint8_t crtc_mask[0x40] = @@ -81,6 +87,59 @@ void et4000_out(uint16_t addr, uint8_t val, void *p) svga_out(addr, val, svga); } +void et4000k_out(uint16_t addr, uint8_t val, void *p) +{ + et4000_t *et4000 = (et4000_t *)p; + +// pclog("ET4000k out %04X %02X\n", addr, val); + + switch (addr) + { + case 0x22CB: + et4000->port_22cb_val = (et4000->port_22cb_val & 0xF0) | (val & 0x0F); + et4000->get_korean_font_enabled = val & 7; + if (et4000->get_korean_font_enabled == 3) + et4000->get_korean_font_index = 0; + break; + case 0x22CF: + switch (et4000->get_korean_font_enabled) + { + case 1: + et4000->get_korean_font_base = ((val & 0x7F) << 7) | (et4000->get_korean_font_base & 0x7F); + break; + case 2: + et4000->get_korean_font_base = (et4000->get_korean_font_base & 0x3F80) | (val & 0x7F) | (((val ^ 0x80) & 0x80) << 8); + break; + case 3: + if ((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) + { + switch (et4000->get_korean_font_base & 0x3F80) + { + case 0x2480: + if (et4000->get_korean_font_index < 16) + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = val; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8] = val; + break; + case 0x3F00: + if (et4000->get_korean_font_index < 16) + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = val; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8] = val; + break; + } + et4000->get_korean_font_index++; + } + break; + } + break; + case 0x32CB: + et4000->port_32cb_val = val; + svga_recalctimings(&et4000->svga); + break; + } +} + uint8_t et4000_in(uint16_t addr, void *p) { et4000_t *et4000 = (et4000_t *)p; @@ -110,6 +169,60 @@ uint8_t et4000_in(uint16_t addr, void *p) return svga_in(addr, svga); } +uint8_t et4000k_in(uint16_t addr, void *p) +{ + uint8_t val = 0xFF; + et4000_t *et4000 = (et4000_t *)p; + +// if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); + + switch (addr) + { + case 0x22CB: + return et4000->port_22cb_val; + case 0x22CF: + val = 0; + switch (et4000->get_korean_font_enabled) + { + case 3: + if ((et4000->port_32cb_val & 0x30) == 0x30) + { + val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index++]; + et4000->get_korean_font_index &= 0x1F; + } + else if ((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) + { + switch (et4000->get_korean_font_base & 0x3F80) + { + case 0x2480: + if (et4000->get_korean_font_index < 16) + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8]; + break; + case 0x3F00: + if (et4000->get_korean_font_index < 16) + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8]; + break; + } + et4000->get_korean_font_index++; + et4000->get_korean_font_index %= 72; + } + break; + case 4: + val = 0x0F; + break; + } + return val; + case 0x32CB: + return et4000->port_32cb_val; + } + + return 0xff; +} + void et4000_recalctimings(svga_t *svga) { svga->ma_latch |= (svga->crtc[0x33]&3)<<16; @@ -143,6 +256,21 @@ void et4000_recalctimings(svga_t *svga) } } +void et4000k_recalctimings(svga_t *svga) +{ + et4000_t *et4000 = (et4000_t *)svga->p; + + et4000_recalctimings(svga); + + if (svga->render == svga_render_text_80 && ((svga->crtc[0x37] & 0x0A) == 0x0A)) + { + if((et4000->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) + { + svga->render = svga_render_text_80_ksc5601; + } + } +} + void *et4000_init() { et4000_t *et4000 = malloc(sizeof(et4000_t)); @@ -161,11 +289,43 @@ void *et4000_init() return et4000; } +void *et4000k_init() +{ + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); + + rom_init(&et4000->bios_rom, "tgkorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("tg_ksc5601.rom", 6); + + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); + + io_sethandler(0x22cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); + io_sethandler(0x22cf, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); + io_sethandler(0x32cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); + et4000->port_22cb_val = 0x60; + et4000->port_32cb_val = 0; + + svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + et4000k_recalctimings, + et4000k_in, et4000k_out, + NULL, + NULL); + + et4000->svga.ksc5601_sbyte_mask = 0x80; + + return et4000; +} + static int et4000_available() { return rom_present("et4000.bin"); } +static int et4000k_available() +{ + return rom_present("tgkorvga.bin") && rom_present("tg_ksc5601.rom");; +} + void et4000_close(void *p) { et4000_t *et4000 = (et4000_t *)p; @@ -207,3 +367,15 @@ device_t et4000_device = et4000_force_redraw, et4000_add_status_info }; + +device_t et4000k_device = +{ + "Trigem Korean VGA(Tseng Labs ET4000AX)", + 0, + et4000k_init, + et4000_close, + et4000k_available, + et4000_speed_changed, + et4000_force_redraw, + et4000_add_status_info +}; diff --git a/src/vid_et4000.h b/src/vid_et4000.h index cc7e161..b5b0170 100644 --- a/src/vid_et4000.h +++ b/src/vid_et4000.h @@ -1 +1,2 @@ extern device_t et4000_device; +extern device_t et4000k_device; diff --git a/src/vid_svga.h b/src/vid_svga.h index db5f817..852010f 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -127,6 +127,8 @@ typedef struct svga_t card should not attempt to display anything */ int override; void *p; + + uint8_t ksc5601_sbyte_mask; } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize, diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 6df365e..92d177c 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -201,12 +201,14 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) + if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc]; - else + else if(nextchr & 0x80) dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; + else + dat = 0xFF; } else { @@ -232,7 +234,7 @@ void svga_render_text_80_ksc5601(svga_t *svga) svga->ma += 4; p += xinc; - if(x + xinc < svga->hdisp && (chr & nextchr & 0x80)) + if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; @@ -255,8 +257,10 @@ void svga_render_text_80_ksc5601(svga_t *svga) if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16]; - else + else if(nextchr & 0x80) dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; + else + dat = 0xFF; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) diff --git a/src/video.c b/src/video.c index b004e7e..dfe8e68 100644 --- a/src/video.c +++ b/src/video.c @@ -106,6 +106,7 @@ static VIDEO_CARD video_cards[] = {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"Sigma Color 400", "sigma400", &sigma_device, GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, From e7d33dd76af19667d4ccfc405a66e56fb0056e43 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 27 Nov 2018 09:39:06 +0000 Subject: [PATCH 0545/1050] Fixed Makefiles broken by rev 1197. --- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 861ec27..3656f1c 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -17,7 +17,7 @@ sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 4b2e9e3..c4b6f3a 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -17,7 +17,7 @@ sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 3bfb669..91c1a7c 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 20bc8bd..b4421f8 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 2549db1..3587ce3 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -16,7 +16,7 @@ sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ From 92ab0ee8ef020a299e885835c76fbea204ee99fa Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 27 Nov 2018 10:15:18 +0000 Subject: [PATCH 0546/1050] Fix flags on 8-bit memory INC/DEC. --- src/codegen_ops_arith.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index f4e4152..4c7c43d 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -1416,6 +1416,8 @@ uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + rebuild_c(ir); + if ((fetchdat & 0xc0) == 0xc0) { uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); From c1565eb42fdc00593a354b7d1a916b1558899593 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 27 Nov 2018 19:43:01 +0000 Subject: [PATCH 0547/1050] Fix partial register handling - removes pointless loads when writing to non-32-bit registers (eg FPU or MMX). --- src/codegen_reg.c | 33 ++++++++++++++++++++++++++++++--- src/codegen_reg.h | 6 ++++-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 3e801a9..9c19d10 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -73,7 +73,7 @@ struct [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER}, [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER}, - [IREG_ssegs] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER}, + [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER}, [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER}, @@ -147,6 +147,33 @@ struct [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP}, }; +static int reg_is_native_size(ir_reg_t ir_reg) +{ + int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; + int requested_size = IREG_GET_SIZE(ir_reg.reg); + + switch (native_size) + { + case REG_BYTE: case REG_FPU_ST_BYTE: + return (requested_size == IREG_SIZE_B); + case REG_WORD: + return (requested_size == IREG_SIZE_W); + case REG_DWORD: + return (requested_size == IREG_SIZE_L); + case REG_QWORD: case REG_FPU_ST_QWORD: case REG_DOUBLE: case REG_FPU_ST_DOUBLE: + return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); + case REG_POINTER: + if (sizeof(void *) == 4) + return (requested_size == IREG_SIZE_L); + return (requested_size == IREG_SIZE_Q); + + default: + fatal("get_reg_is_native_size: unknown native size %i\n", native_size); + } + + return 0; +} + void codegen_reg_reset() { int c; @@ -260,7 +287,7 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; default: - fatal("codegen_reg_load - native_size=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size); + fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, IREG_GET_REG(ir_reg.reg)); } reg_set->regs[c] = ir_reg; @@ -469,7 +496,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) host_reg_set_t *reg_set = get_reg_set(ir_reg); int c; - if (IREG_GET_SIZE(ir_reg.reg) != IREG_SIZE_L) + if (!reg_is_native_size(ir_reg)) { /*Read in parent register so we can do partial accesses to it*/ ir_reg_t parent_reg; diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 8474ef9..63a0b6d 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -37,7 +37,7 @@ enum IREG_eaaddr = 14, IREG_ea_seg = 15, IREG_op32 = 16, - IREG_ssegs = 17, + IREG_ssegsx = 17, IREG_rm_mod_reg = 18, @@ -179,7 +179,9 @@ enum IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, - IREG_NPXS = IREG_NPXSx + IREG_SIZE_W + IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, + + IREG_ssegs = IREG_ssegsx + IREG_SIZE_B }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) From a4d3aa1912a9ccf43727cc5bc0ef167c8e496f2e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 09:42:04 +0000 Subject: [PATCH 0548/1050] Move flags and eflags variables into cpu_struct. --- src/386.c | 18 +- src/386_common.h | 10 +- src/386_dynarec.c | 44 +-- src/808x.c | 877 +++++++++++++++++++++-------------------- src/codegen.c | 4 +- src/codegen_ops_jump.c | 8 +- src/ibm.h | 5 +- src/x86.h | 2 +- src/x86_flags.h | 114 +++--- src/x86_ops_atomic.h | 8 +- src/x86_ops_bcd.h | 40 +- src/x86_ops_bit.h | 64 +-- src/x86_ops_bitscan.h | 4 +- src/x86_ops_flag.h | 94 ++--- src/x86_ops_int.h | 8 +- src/x86_ops_misc.h | 76 ++-- src/x86_ops_mov_ctrl.h | 24 +- src/x86_ops_mul.h | 48 +-- src/x86_ops_pmode.h | 38 +- src/x86_ops_rep.h | 84 ++-- src/x86_ops_ret.h | 34 +- src/x86_ops_shift.h | 90 ++--- src/x86_ops_string.h | 168 ++++---- src/x86seg.c | 85 ++-- src/x87_ops_arith.h | 24 +- 25 files changed, 1013 insertions(+), 958 deletions(-) diff --git a/src/386.c b/src/386.c index 25bb653..e7032d1 100644 --- a/src/386.c +++ b/src/386.c @@ -250,13 +250,13 @@ dontprint=0; if (!cpu_state.abrt) { - trap = flags & T_FLAG; + trap = cpu_state.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\n",CS,cs,cpu_state.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); + 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\n",CS,cs,cpu_state.pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,cpu_state.flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask); } cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -312,13 +312,13 @@ dontprint=0; } else { - writememw(ss,(SP-2)&0xFFFF,flags); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr = (1 << 2) + idt.base; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } @@ -336,7 +336,7 @@ dontprint=0; nmi = 0; } } - else if ((flags&I_FLAG) && pic_intpending) + else if ((cpu_state.flags & I_FLAG) && pic_intpending) { temp=picinterrupt(); if (temp!=0xFF) @@ -352,13 +352,13 @@ dontprint=0; } else { - writememw(ss,(SP-2)&0xFFFF,flags); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr = (temp << 2) + idt.base; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); diff --git a/src/386_common.h b/src/386_common.h index 906c09a..91bf3c1 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -15,7 +15,7 @@ extern uint16_t ea_rseg; int checkio(int port); -#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ +#define check_io_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \ { \ int tempi = checkio(port); \ if (cpu_state.abrt) return 1; \ @@ -26,7 +26,7 @@ int checkio(int port); } \ } -#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ +#define checkio_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \ { \ int tempi = checkio(port); \ if (cpu_state.abrt) break; \ @@ -58,14 +58,14 @@ int checkio(int port); } while (0) #define CHECK_READ(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((seg)->access & 10) == 8))) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((seg)->access & 10) == 8))) \ { \ x86gpf("Limit check", 0); \ return 1; \ } #define CHECK_WRITE(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((seg)->access & 8))) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((seg)->access & 8))) \ { \ x86gpf("Limit check", 0); \ return 1; \ @@ -79,7 +79,7 @@ int checkio(int port); } -#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ +#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ { \ x86_int(6); \ return 1; \ diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 91a2b55..bdb1aa7 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -217,21 +217,21 @@ void x86_int(int num) { if (stack32) { - writememw(ss,ESP-2,flags); + writememw(ss,ESP-2,cpu_state.flags); writememw(ss,ESP-4,CS); writememw(ss,ESP-6,cpu_state.pc); ESP-=6; } else { - writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); writememw(ss,((SP-4)&0xFFFF),CS); writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); SP-=6; } - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); @@ -264,21 +264,21 @@ void x86_int_sw(int num) { if (stack32) { - writememw(ss,ESP-2,flags); + writememw(ss,ESP-2,cpu_state.flags); writememw(ss,ESP-4,CS); writememw(ss,ESP-6,cpu_state.pc); ESP-=6; } else { - writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); writememw(ss,((SP-4)&0xFFFF),CS); writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); SP-=6; } - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); @@ -303,13 +303,13 @@ int x86_int_sw_rm(int num) if (cpu_state.abrt) return 1; - writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; } + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; } writememw(ss,((SP-4)&0xFFFF),CS); writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; } SP-=6; - eflags &= ~VIF_FLAG; - flags &= ~T_FLAG; + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; loadcs(new_cs); oxpc=cpu_state.pc; @@ -507,7 +507,7 @@ int dontprint=0; #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG)) +#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(cpu_state.flags & T_FLAG)) //#define CACHE_ON() 0 static int cycles_main = 0; @@ -560,7 +560,7 @@ void exec386_dynarec(int cycs) // fatal("Dead with cache off\n"); if (!cpu_state.abrt) { - trap = flags & T_FLAG; + trap = cpu_state.flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; @@ -720,7 +720,7 @@ inrecomp=0; // fatal("Dead\n"); if (!cpu_state.abrt) { - trap = flags & T_FLAG; + trap = cpu_state.flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; @@ -800,7 +800,7 @@ inrecomp=0; if (!cpu_state.abrt) { - trap = flags & T_FLAG; + trap = cpu_state.flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; @@ -892,13 +892,13 @@ inrecomp=0; } else { - writememw(ss,(SP-2)&0xFFFF,flags); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr = (1 << 2) + idt.base; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } @@ -916,7 +916,7 @@ inrecomp=0; nmi = 0; } } - else if ((flags&I_FLAG) && pic_intpending) + else if ((cpu_state.flags & I_FLAG) && pic_intpending) { temp=picinterrupt(); if (temp!=0xFF) @@ -930,13 +930,13 @@ inrecomp=0; } else { - writememw(ss,(SP-2)&0xFFFF,flags); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr=temp<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); diff --git a/src/808x.c b/src/808x.c index eaeffa6..7368a4e 100644 --- a/src/808x.c +++ b/src/808x.c @@ -570,11 +570,11 @@ void dumpregs() 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); else printf("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP); - printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,flags); + printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,cpu_state.flags); printf("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2); printf("%i ins\n",ins); if (is386) - printf("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real"); + printf("In %s mode\n",(msw&1)?((cpu_state.eflags&VM_FLAG)?"V86":"protected"):"real"); else printf("In %s mode\n",(msw&1)?"protected":"real"); printf("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,cpu_state.seg_cs.limit,cpu_state.seg_cs.access, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high); @@ -627,7 +627,7 @@ void resetx86() cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; - eflags=0; + cpu_state.eflags=0; cgate32=0; if (AT) { @@ -643,7 +643,7 @@ void resetx86() } idt.base = 0; idt.limit = is386 ? 0x03FF : 0xFFFF; - flags=2; + cpu_state.flags=2; makeznptable(); resetreadlookup(); makemod1table(); @@ -676,7 +676,7 @@ void softresetx86() cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; - eflags=0; + cpu_state.eflags=0; cgate32=0; cpu_hasCX8 = 0; if (AT) @@ -692,7 +692,7 @@ void softresetx86() rammask = 0xfffff; } //rammask=0xFFFFFFFF; - flags=2; + cpu_state.flags=2; idt.base = 0; idt.limit = is386 ? 0x03FF : 0xFFFF; x86seg_reset(); @@ -701,123 +701,154 @@ void softresetx86() static void setznp8(uint8_t val) { - flags&=~0xC4; - flags|=znptable8[val]; + cpu_state.flags &= ~0xC4; + cpu_state.flags |= znptable8[val]; } static void setznp16(uint16_t val) { - flags&=~0xC4; - flags|=znptable16[val]; + cpu_state.flags &= ~0xC4; + cpu_state.flags |= znptable16[val]; } static void setadd8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + uint16_t c = (uint16_t)a + (uint16_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c&0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadd8nc(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b; - flags&=~0x8D4; - flags|=znptable8[c&0xFF]; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + uint16_t c = (uint16_t)a + (uint16_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= znptable8[c&0xFF]; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + uint16_t c = (uint16_t)a + (uint16_t)b+tempc; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c&0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadd16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + uint32_t c = (uint32_t)a + (uint32_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c&0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadd16nc(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b; - flags&=~0x8D4; - flags|=znptable16[c&0xFFFF]; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + uint32_t c = (uint32_t)a + (uint32_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= znptable16[c&0xFFFF]; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + uint32_t c = (uint32_t)a + (uint32_t)b+tempc; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c&0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a-(uint16_t)b; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + uint16_t c = (uint16_t)a - (uint16_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c&0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub8nc(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a-(uint16_t)b; - flags&=~0x8D4; - flags|=znptable8[c&0xFF]; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + uint16_t c = (uint16_t)a - (uint16_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= znptable8[c&0xFF]; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsbc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + uint16_t c = (uint16_t)a - (((uint16_t)b) + tempc); + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c&0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a-(uint32_t)b; - flags&=~0x8D5; - 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; + uint32_t c = (uint32_t)a - (uint32_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c&0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub16nc(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a-(uint32_t)b; - flags&=~0x8D4; - flags|=(znptable16[c&0xFFFF]&~4); - flags|=(znptable8[c&0xFF]&4); - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + uint32_t c = (uint32_t)a - (uint32_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= (znptable16[c&0xFFFF]&~4); + cpu_state.flags |= (znptable8[c&0xFF]&4); + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsbc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); - flags&=~0x8D5; - flags|=(znptable16[c&0xFFFF]&~4); - flags|=(znptable8[c&0xFF]&4); - if (c&0x10000) flags|=C_FLAG; - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + uint32_t c = (uint32_t)a - (((uint32_t)b) + tempc); + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= (znptable16[c&0xFFFF]&~4); + cpu_state.flags |= (znptable8[c&0xFF]&4); + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } int current_diff = 0; @@ -893,8 +924,8 @@ void rep(int fv) { temp2=readmemb(ds+SI); outb(DX,temp2); - if (flags&D_FLAG) SI--; - else SI++; + if (cpu_state.flags & D_FLAG) SI--; + else SI++; c--; cycles-=5; } @@ -907,8 +938,8 @@ 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++; } + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } c--; cycles-=17; clockhardware(); @@ -925,8 +956,8 @@ void rep(int fv) memcycs=0; tempw=readmemw(ds,SI); writememw(es,DI,tempw); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } + if (cpu_state.flags & D_FLAG) { DI-=2; SI-=2; } + else { DI+=2; SI+=2; } c--; cycles-=17; clockhardware(); @@ -938,43 +969,43 @@ void rep(int fv) // } break; case 0xA6: /*REP CMPSB*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) + if (fv) cpu_state.flags |= Z_FLAG; + else cpu_state.flags &= ~Z_FLAG; + while ((c>0) && (fv==((cpu_state.flags & Z_FLAG)?1:0)) && !IRQTEST) { 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++; } + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } c--; cycles -= 30; setsub8(temp,temp2); clockhardware(); FETCHADD(30 - memcycs); } - if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) cpu_state.pc=ipc; + if (IRQTEST && c>0 && (fv==((cpu_state.flags & Z_FLAG)?1:0))) cpu_state.pc=ipc; // if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } // else firstrepcycle=1; break; case 0xA7: /*REP CMPSW*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - while ((c>0) && (fv==((flags&Z_FLAG)?1:0)) && !IRQTEST) + if (fv) cpu_state.flags |= Z_FLAG; + else cpu_state.flags &= ~Z_FLAG; + while ((c>0) && (fv==((cpu_state.flags & Z_FLAG)?1:0)) && !IRQTEST) { memcycs=0; tempw=readmemw(ds,SI); tempw2=readmemw(es,DI); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } + if (cpu_state.flags & D_FLAG) { DI-=2; SI-=2; } + else { DI+=2; SI+=2; } c--; cycles -= 30; setsub16(tempw,tempw2); clockhardware(); FETCHADD(30 - memcycs); } - if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) cpu_state.pc=ipc; + if (IRQTEST && c>0 && (fv==((cpu_state.flags & Z_FLAG)?1:0))) cpu_state.pc=ipc; // if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } // else firstrepcycle=1; // if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2); @@ -984,8 +1015,8 @@ void rep(int fv) { memcycs=0; writememb(es+DI,AL); - if (flags&D_FLAG) DI--; - else DI++; + if (cpu_state.flags & D_FLAG) DI--; + else DI++; c--; cycles -= 10; clockhardware(); @@ -1000,8 +1031,8 @@ void rep(int fv) { memcycs=0; writememw(es,DI,AX); - if (flags&D_FLAG) DI-=2; - else DI+=2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; c--; cycles -= 10; clockhardware(); @@ -1015,8 +1046,8 @@ void rep(int fv) if (c>0) { temp2=readmemb(ds+SI); - if (flags&D_FLAG) SI--; - else SI++; + if (cpu_state.flags & D_FLAG) SI--; + else SI++; c--; cycles-=4; } @@ -1027,8 +1058,8 @@ void rep(int fv) if (c>0) { tempw2=readmemw(ds,SI); - if (flags&D_FLAG) SI-=2; - else SI+=2; + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; c--; cycles-=4; } @@ -1036,37 +1067,37 @@ void rep(int fv) else firstrepcycle=1; break; case 0xAE: /*REP SCASB*/ - if (fv) flags|=Z_FLAG; - else flags&=~Z_FLAG; - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) + if (fv) cpu_state.flags |= Z_FLAG; + else cpu_state.flags &= ~Z_FLAG; + if ((c>0) && (fv==((cpu_state.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++; + if (cpu_state.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(); } + if ((c>0) && (fv==((cpu_state.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; - else flags&=~Z_FLAG; - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) + if (fv) cpu_state.flags |= Z_FLAG; + else cpu_state.flags &= ~Z_FLAG; + if ((c>0) && (fv==((cpu_state.flags & Z_FLAG)?1:0))) { tempw=readmemw(es,DI); setsub16(AX,tempw); - if (flags&D_FLAG) DI-=2; - else DI+=2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; c--; cycles -= 15; } - if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { cpu_state.pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } + if ((c>0) && (fv==((cpu_state.flags & Z_FLAG)?1:0))) { cpu_state.pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } else firstrepcycle=1; break; default: @@ -1125,8 +1156,8 @@ void execx86(int cycs) cpu_state.oldpc = cpu_state.pc; opcodestart: opcode=FETCH(); - tempc=flags&C_FLAG; - trap=flags&T_FLAG; + tempc = cpu_state.flags & C_FLAG; + trap = cpu_state.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); @@ -1135,7 +1166,7 @@ void execx86(int cycs) { // 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]); + 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,cpu_state.flags, ins, ram, ram[0x1a925]); skipnextprint=0; // ins++; // } @@ -1215,7 +1246,7 @@ void execx86(int cycs) temp=geteab(); temp|=getr8(cpu_reg); setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteab(temp); cycles-=((cpu_mod==3)?3:24); break; @@ -1224,7 +1255,7 @@ void execx86(int cycs) tempw=geteaw(); tempw|=cpu_state.regs[cpu_reg].w; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteaw(tempw); cycles-=((cpu_mod==3)?3:24); break; @@ -1233,7 +1264,7 @@ void execx86(int cycs) temp=geteab(); temp|=getr8(cpu_reg); setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); setr8(cpu_reg,temp); cycles-=((cpu_mod==3)?3:13); break; @@ -1242,20 +1273,20 @@ void execx86(int cycs) tempw=geteaw(); tempw|=cpu_state.regs[cpu_reg].w; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cpu_state.regs[cpu_reg].w=tempw; cycles-=((cpu_mod==3)?3:13); break; case 0x0C: /*OR AL,#8*/ AL|=FETCH(); setznp8(AL); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=4; break; case 0x0D: /*OR AX,#16*/ AX|=getword(); setznp16(AX); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=4; break; @@ -1403,7 +1434,7 @@ void execx86(int cycs) temp=geteab(); temp&=getr8(cpu_reg); setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteab(temp); cycles-=((cpu_mod==3)?3:24); break; @@ -1412,7 +1443,7 @@ void execx86(int cycs) tempw=geteaw(); tempw&=cpu_state.regs[cpu_reg].w; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteaw(tempw); cycles-=((cpu_mod==3)?3:24); break; @@ -1421,7 +1452,7 @@ void execx86(int cycs) temp=geteab(); temp&=getr8(cpu_reg); setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); setr8(cpu_reg,temp); cycles-=((cpu_mod==3)?3:13); break; @@ -1430,20 +1461,20 @@ void execx86(int cycs) tempw=geteaw(); tempw&=cpu_state.regs[cpu_reg].w; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cpu_state.regs[cpu_reg].w=tempw; cycles-=((cpu_mod==3)?3:13); break; case 0x24: /*AND AL,#8*/ AL&=FETCH(); setznp8(AL); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=4; break; case 0x25: /*AND AX,#16*/ AX&=getword(); setznp16(AX); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=4; break; @@ -1457,19 +1488,20 @@ void execx86(int cycs) // break; case 0x27: /*DAA*/ - if ((flags&A_FLAG) || ((AL&0xF)>9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - tempi=((uint16_t)AL)+6; - AL+=6; - flags|=A_FLAG; - if (tempi&0x100) flags|=C_FLAG; + tempi = ((uint16_t)AL) + 6; + AL += 6; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) + cpu_state.flags |= C_FLAG; } // else // flags&=~A_FLAG; - if ((flags&C_FLAG) || (AL>0x9F)) + if ((cpu_state.flags & C_FLAG) || (AL > 0x9F)) { - AL+=0x60; - flags|=C_FLAG; + AL += 0x60; + cpu_state.flags |= C_FLAG; } // else // flags&=~C_FLAG; @@ -1531,19 +1563,20 @@ void execx86(int cycs) cycles-=4; goto opcodestart; case 0x2F: /*DAS*/ - if ((flags&A_FLAG)||((AL&0xF)>9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - tempi=((uint16_t)AL)-6; - AL-=6; - flags|=A_FLAG; - if (tempi&0x100) flags|=C_FLAG; + tempi = ((uint16_t)AL) - 6; + AL -= 6; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) + cpu_state.flags |= C_FLAG; } // else // flags&=~A_FLAG; - if ((flags&C_FLAG)||(AL>0x9F)) + if ((cpu_state.flags & C_FLAG) || (AL > 0x9F)) { - AL-=0x60; - flags|=C_FLAG; + AL -= 0x60; + cpu_state.flags |= C_FLAG; } // else // flags&=~C_FLAG; @@ -1555,7 +1588,7 @@ void execx86(int cycs) temp=geteab(); temp^=getr8(cpu_reg); setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteab(temp); cycles-=((cpu_mod==3)?3:24); break; @@ -1564,7 +1597,7 @@ void execx86(int cycs) tempw=geteaw(); tempw^=cpu_state.regs[cpu_reg].w; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteaw(tempw); cycles-=((cpu_mod==3)?3:24); break; @@ -1573,7 +1606,7 @@ void execx86(int cycs) temp=geteab(); temp^=getr8(cpu_reg); setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); setr8(cpu_reg,temp); cycles-=((cpu_mod==3)?3:13); break; @@ -1582,20 +1615,20 @@ void execx86(int cycs) tempw=geteaw(); tempw^=cpu_state.regs[cpu_reg].w; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cpu_state.regs[cpu_reg].w=tempw; cycles-=((cpu_mod==3)?3:13); break; case 0x34: /*XOR AL,#8*/ AL^=FETCH(); setznp8(AL); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=4; break; case 0x35: /*XOR AX,#16*/ AX^=getword(); setznp16(AX); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=4; break; @@ -1609,16 +1642,16 @@ void execx86(int cycs) // break; case 0x37: /*AAA*/ - if ((flags&A_FLAG)||((AL&0xF)>9)) + if ((cpu_state.flags & A_FLAG)||((AL & 0xF) > 9)) { - AL+=6; + AL += 6; AH++; - flags|=(A_FLAG|C_FLAG); + cpu_state.flags |= (A_FLAG|C_FLAG); } else - flags&=~(A_FLAG|C_FLAG); - AL&=0xF; - cycles-=8; + cpu_state.flags &= ~(A_FLAG|C_FLAG); + AL &= 0xF; + cycles -= 8; break; case 0x38: /*CMP 8,reg*/ @@ -1670,16 +1703,16 @@ void execx86(int cycs) // break; case 0x3F: /*AAS*/ - if ((flags&A_FLAG)||((AL&0xF)>9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL-=6; + AL -= 6; AH--; - flags|=(A_FLAG|C_FLAG); + cpu_state.flags |= (A_FLAG|C_FLAG); } else - flags&=~(A_FLAG|C_FLAG); - AL&=0xF; - cycles-=8; + cpu_state.flags &= ~(A_FLAG|C_FLAG); + AL &= 0xF; + cycles -= 8; break; case 0x40: case 0x41: case 0x42: case 0x43: /*INC r16*/ @@ -1714,105 +1747,105 @@ void execx86(int cycs) case 0x60: /*JO alias*/ case 0x70: /*JO*/ offset=(int8_t)FETCH(); - if (flags&V_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (cpu_state.flags & V_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x61: /*JNO alias*/ case 0x71: /*JNO*/ offset=(int8_t)FETCH(); - if (!(flags&V_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (!(cpu_state.flags & V_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x62: /*JB alias*/ case 0x72: /*JB*/ offset=(int8_t)FETCH(); - if (flags&C_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (cpu_state.flags & C_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x63: /*JNB alias*/ case 0x73: /*JNB*/ offset=(int8_t)FETCH(); - if (!(flags&C_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (!(cpu_state.flags & C_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x64: /*JE alias*/ case 0x74: /*JE*/ offset=(int8_t)FETCH(); - if (flags&Z_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (cpu_state.flags & Z_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x65: /*JNE alias*/ case 0x75: /*JNE*/ offset=(int8_t)FETCH(); cycles-=4; - if (!(flags&Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (!(cpu_state.flags & Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } break; case 0x66: /*JBE alias*/ case 0x76: /*JBE*/ offset=(int8_t)FETCH(); - if (flags&(C_FLAG|Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (cpu_state.flags & (C_FLAG|Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x67: /*JNBE alias*/ case 0x77: /*JNBE*/ offset=(int8_t)FETCH(); - if (!(flags&(C_FLAG|Z_FLAG))) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (!(cpu_state.flags & (C_FLAG|Z_FLAG))) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x68: /*JS alias*/ case 0x78: /*JS*/ offset=(int8_t)FETCH(); - if (flags&N_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (cpu_state.flags & N_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x69: /*JNS alias*/ case 0x79: /*JNS*/ offset=(int8_t)FETCH(); - if (!(flags&N_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (!(cpu_state.flags & N_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x6A: /*JP alias*/ case 0x7A: /*JP*/ offset=(int8_t)FETCH(); - if (flags&P_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (cpu_state.flags & P_FLAG) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x6B: /*JNP alias*/ case 0x7B: /*JNP*/ offset=(int8_t)FETCH(); - if (!(flags&P_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (!(cpu_state.flags & P_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x6C: /*JL alias*/ case 0x7C: /*JL*/ offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; + temp=(cpu_state.flags & N_FLAG)?1:0; + temp2=(cpu_state.flags & V_FLAG)?1:0; if (temp!=temp2) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x6D: /*JNL alias*/ case 0x7D: /*JNL*/ offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; + temp=(cpu_state.flags & N_FLAG)?1:0; + temp2=(cpu_state.flags & V_FLAG)?1:0; if (temp==temp2) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x6E: /*JLE alias*/ case 0x7E: /*JLE*/ offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; - if ((flags&Z_FLAG) || (temp!=temp2)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + temp=(cpu_state.flags & N_FLAG)?1:0; + temp2=(cpu_state.flags & V_FLAG)?1:0; + if ((cpu_state.flags & Z_FLAG) || (temp!=temp2)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; case 0x6F: /*JNLE alias*/ case 0x7F: /*JNLE*/ offset=(int8_t)FETCH(); - temp=(flags&N_FLAG)?1:0; - temp2=(flags&V_FLAG)?1:0; - if (!((flags&Z_FLAG) || (temp!=temp2))) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + temp=(cpu_state.flags & N_FLAG)?1:0; + temp2=(cpu_state.flags & V_FLAG)?1:0; + if (!((cpu_state.flags & Z_FLAG) || (temp!=temp2))) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=4; break; @@ -1830,7 +1863,7 @@ void execx86(int cycs) case 0x08: /*OR b,#8*/ temp|=temp2; setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteab(temp); cycles-=((cpu_mod==3)?4:23); break; @@ -1849,7 +1882,7 @@ void execx86(int cycs) case 0x20: /*AND b,#8*/ temp&=temp2; setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteab(temp); cycles-=((cpu_mod==3)?4:23); break; @@ -1861,7 +1894,7 @@ void execx86(int cycs) case 0x30: /*XOR b,#8*/ temp^=temp2; setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteab(temp); cycles-=((cpu_mod==3)?4:23); break; @@ -1892,7 +1925,7 @@ void execx86(int cycs) case 0x08: /*OR w,#16*/ tempw|=tempw2; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteaw(tempw); cycles-=((cpu_mod==3)?4:23); break; @@ -1906,7 +1939,7 @@ void execx86(int cycs) case 0x20: /*AND w,#16*/ tempw&=tempw2; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteaw(tempw); cycles-=((cpu_mod==3)?4:23); break; @@ -1925,7 +1958,7 @@ void execx86(int cycs) case 0x30: /*XOR w,#16*/ tempw^=tempw2; setznp16(tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); seteaw(tempw); cycles-=((cpu_mod==3)?4:23); break; @@ -1959,7 +1992,7 @@ void execx86(int cycs) tempw|=tempw2; setznp16(tempw); seteaw(tempw); - flags&=~(C_FLAG|A_FLAG|V_FLAG); + cpu_state.flags &= ~(C_FLAG|A_FLAG|V_FLAG); cycles-=((cpu_mod==3)?4:23); break; case 0x10: /*ADC w,#8*/ @@ -1981,7 +2014,7 @@ void execx86(int cycs) setznp16(tempw); seteaw(tempw); cycles-=((cpu_mod==3)?4:23); - flags&=~(C_FLAG|A_FLAG|V_FLAG); + cpu_state.flags &= ~(C_FLAG|A_FLAG|V_FLAG); break; case 0x28: /*SUB w,#8*/ setsub16(tempw,tempw2); @@ -1994,7 +2027,7 @@ void execx86(int cycs) setznp16(tempw); seteaw(tempw); cycles-=((cpu_mod==3)?4:23); - flags&=~(C_FLAG|A_FLAG|V_FLAG); + cpu_state.flags &= ~(C_FLAG|A_FLAG|V_FLAG); break; case 0x38: /*CMP w,#8*/ setsub16(tempw,tempw2); @@ -2013,7 +2046,7 @@ void execx86(int cycs) temp=geteab(); temp2=getr8(cpu_reg); setznp8(temp&temp2); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=((cpu_mod==3)?3:13); break; case 0x85: /*TEST w,reg*/ @@ -2021,7 +2054,7 @@ void execx86(int cycs) tempw=geteaw(); tempw2=cpu_state.regs[cpu_reg].w; setznp16(tempw&tempw2); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=((cpu_mod==3)?3:13); break; case 0x86: /*XCHG b,reg*/ @@ -2171,22 +2204,22 @@ void execx86(int cycs) break; case 0x9C: /*PUSHF*/ if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); + writememw(ss, ((SP-2)&0xFFFF), cpu_state.flags | 0xF000); SP-=2; cycles-=14; break; case 0x9D: /*POPF*/ if (cpu_state.ssegs) ss=oldss; - flags=readmemw(ss,SP)&0xFFF; + cpu_state.flags = readmemw(ss,SP) & 0xFFF; SP+=2; cycles-=12; break; case 0x9E: /*SAHF*/ - flags=(flags&0xFF00)|AH; + cpu_state.flags = (cpu_state.flags & 0xFF00) | AH; cycles-=4; break; case 0x9F: /*LAHF*/ - AH=flags&0xFF; + AH = cpu_state.flags & 0xFF; cycles-=4; break; @@ -2216,23 +2249,23 @@ void execx86(int cycs) case 0xA4: /*MOVSB*/ temp=readmemb(ds+SI); writememb(es+DI,temp); - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } cycles-=18; break; case 0xA5: /*MOVSW*/ tempw=readmemw(ds,SI); writememw(es,DI,tempw); - if (flags&D_FLAG) { DI-=2; SI-=2; } - else { DI+=2; SI+=2; } + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } cycles-=18; break; case 0xA6: /*CMPSB*/ temp =readmemb(ds+SI); temp2=readmemb(es+DI); setsub8(temp,temp2); - if (flags&D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } cycles-=30; break; case 0xA7: /*CMPSW*/ @@ -2240,60 +2273,60 @@ void execx86(int cycs) 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; } + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } cycles-=30; break; case 0xA8: /*TEST AL,#8*/ temp=FETCH(); setznp8(AL&temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=5; break; case 0xA9: /*TEST AX,#16*/ tempw=getword(); setznp16(AX&tempw); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=5; break; case 0xAA: /*STOSB*/ writememb(es+DI,AL); - if (flags&D_FLAG) DI--; - else DI++; + if (cpu_state.flags & D_FLAG) DI--; + else DI++; cycles-=11; break; case 0xAB: /*STOSW*/ writememw(es,DI,AX); - if (flags&D_FLAG) DI-=2; - else DI+=2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; cycles-=11; 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++; + if (cpu_state.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; + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; cycles-=16; break; case 0xAE: /*SCASB*/ temp=readmemb(es+DI); setsub8(AL,temp); - if (flags&D_FLAG) DI--; - else DI++; + if (cpu_state.flags & D_FLAG) DI--; + else DI++; cycles-=19; break; case 0xAF: /*SCASW*/ tempw=readmemw(es,DI); setsub16(AX,tempw); - if (flags&D_FLAG) DI-=2; - else DI+=2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; cycles-=19; break; @@ -2408,13 +2441,13 @@ void execx86(int cycs) break; case 0xCC: /*INT 3*/ if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + writememw(ss, ((SP-2)&0xFFFF), cpu_state.flags | 0xF000); + writememw(ss, ((SP-4)&0xFFFF), CS); + writememw(ss, ((SP-6)&0xFFFF), cpu_state.pc); SP-=6; addr=3<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; // printf("CC %04X:%04X ",CS,pc); cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); @@ -2428,10 +2461,10 @@ void execx86(int cycs) temp=FETCH(); if (cpu_state.ssegs) ss=oldss; - writememw(ss,((SP-2)&0xFFFF),flags|0xF000); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - flags&=~T_FLAG; + writememw(ss, ((SP-2)&0xFFFF), cpu_state.flags | 0xF000); + writememw(ss, ((SP-4)&0xFFFF), CS); + writememw(ss, ((SP-6)&0xFFFF), cpu_state.pc); + cpu_state.flags &= ~T_FLAG; SP-=6; addr=temp<<2; cpu_state.pc=readmemw(0,addr); @@ -2448,7 +2481,7 @@ void execx86(int cycs) cpu_state.pc=readmemw(ss,SP); // printf("CF\n"); loadcs(readmemw(ss,((SP+2)&0xFFFF))); - flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF; + cpu_state.flags = readmemw(ss,((SP+4)&0xFFFF))&0xFFF; SP+=6; cycles-=44; FETCHCLEAR(); @@ -2460,83 +2493,85 @@ void execx86(int cycs) switch (rmdat&0x38) { case 0x00: /*ROL b,1*/ - if (temp&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp&0x80) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp<<=1; - if (flags&C_FLAG) temp|=1; + if (cpu_state.flags & C_FLAG) + temp |= 1; seteab(temp); // setznp8(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags&C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x08: /*ROR b,1*/ - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp>>=1; - if (flags&C_FLAG) temp|=0x80; + if (cpu_state.flags & C_FLAG) + temp |= 0x80; seteab(temp); // setznp8(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((temp^(temp>>1))&0x40) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x10: /*RCL b,1*/ - temp2=flags&C_FLAG; - if (temp&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; + temp2 = cpu_state.flags & C_FLAG; + if (temp&0x80) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp<<=1; if (temp2) temp|=1; seteab(temp); // setznp8(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(temp>>7)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x18: /*RCR b,1*/ - temp2=flags&C_FLAG; - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; + temp2 = cpu_state.flags & C_FLAG; + if (temp&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp>>=1; if (temp2) temp|=0x80; seteab(temp); // setznp8(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((temp^(temp>>1))&0x40) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x20: case 0x30: /*SHL b,1*/ - if (temp&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; - if ((temp^(temp<<1))&0x80) flags|=V_FLAG; - else flags&=~V_FLAG; + if (temp&0x80) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + if ((temp^(temp<<1))&0x80) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; temp<<=1; seteab(temp); setznp8(temp); cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x28: /*SHR b,1*/ - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; - if (temp&0x80) flags|=V_FLAG; - else flags&=~V_FLAG; + if (temp&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + if (temp&0x80) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; temp>>=1; seteab(temp); setznp8(temp); cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x38: /*SAR b,1*/ - if (temp&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp>>=1; if (temp&0x40) temp|=0x80; seteab(temp); setznp8(temp); cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - flags&=~V_FLAG; + cpu_state.flags |= A_FLAG; + cpu_state.flags &= ~V_FLAG; break; // default: @@ -2552,83 +2587,83 @@ void execx86(int cycs) switch (rmdat&0x38) { case 0x00: /*ROL w,1*/ - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; + if (tempw&0x8000) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw<<=1; - if (flags&C_FLAG) tempw|=1; + if (cpu_state.flags & C_FLAG) tempw|=1; seteaw(tempw); // setznp16(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(tempw>>15)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x08: /*ROR w,1*/ - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if (tempw&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw>>=1; - if (flags&C_FLAG) tempw|=0x8000; + if (cpu_state.flags & C_FLAG) tempw|=0x8000; seteaw(tempw); // setznp16(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((tempw^(tempw>>1))&0x4000) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x10: /*RCL w,1*/ - temp2=flags&C_FLAG; - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; + temp2 = cpu_state.flags & C_FLAG; + if (tempw&0x8000) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw<<=1; if (temp2) tempw|=1; seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(tempw>>15)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x18: /*RCR w,1*/ - temp2=flags&C_FLAG; - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; + temp2 = cpu_state.flags & C_FLAG; + if (tempw&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw>>=1; if (temp2) tempw|=0x8000; seteaw(tempw); // setznp16(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((tempw^(tempw>>1))&0x4000) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?2:23); break; case 0x20: case 0x30: /*SHL w,1*/ - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; - if ((tempw^(tempw<<1))&0x8000) flags|=V_FLAG; - else flags&=~V_FLAG; + if (tempw&0x8000) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + if ((tempw^(tempw<<1))&0x8000) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; tempw<<=1; seteaw(tempw); setznp16(tempw); cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x28: /*SHR w,1*/ - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; - if (tempw&0x8000) flags|=V_FLAG; - else flags&=~V_FLAG; + if (tempw&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; + if (tempw&0x8000) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; tempw>>=1; seteaw(tempw); setznp16(tempw); cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x38: /*SAR w,1*/ - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if (tempw&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw>>=1; if (tempw&0x4000) tempw|=0x8000; seteaw(tempw); setznp16(tempw); cycles-=((cpu_mod==3)?2:23); - flags|=A_FLAG; - flags&=~V_FLAG; + cpu_state.flags |= A_FLAG; + cpu_state.flags &= ~V_FLAG; break; // default: @@ -2655,12 +2690,12 @@ void execx86(int cycs) c--; cycles-=4; } - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp2) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; seteab(temp); // setznp8(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(temp>>7)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; case 0x08: /*ROR b,CL*/ @@ -2672,40 +2707,40 @@ void execx86(int cycs) c--; cycles-=4; } - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp2) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; seteab(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((temp^(temp>>1))&0x40) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; 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; + templ=cpu_state.flags & C_FLAG; temp2=temp&0x80; temp<<=1; - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp2) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; if (templ) temp|=1; c--; cycles-=4; } // printf("Now %02X\n",temp); seteab(temp); - if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(temp>>7)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; case 0x18: /*RCR b,CL*/ while (c>0) { - templ=flags&C_FLAG; + templ=cpu_state.flags & C_FLAG; temp2=temp&1; temp>>=1; - if (temp2) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp2) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; if (templ) temp|=0x80; c--; cycles-=4; @@ -2713,49 +2748,49 @@ void execx86(int cycs) // if (temp2) flags|=C_FLAG; // else flags&=~C_FLAG; seteab(temp); - if ((temp^(temp>>1))&0x40) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((temp^(temp>>1))&0x40) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; case 0x20: case 0x30: /*SHL b,CL*/ if (c > 8) { temp = 0; - flags &= ~C_FLAG; + cpu_state.flags &= ~C_FLAG; } else { - if ((temp<<(c-1))&0x80) flags|=C_FLAG; - else flags&=~C_FLAG; + if ((temp<<(c-1))&0x80) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp<<=c; } seteab(temp); setznp8(temp); cycles-=(c*4); cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x28: /*SHR b,CL*/ if (c > 8) { temp = 0; - flags &= ~C_FLAG; + cpu_state.flags &= ~C_FLAG; } else { - if ((temp>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if ((temp>>(c-1))&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; temp>>=c; } seteab(temp); setznp8(temp); cycles-=(c*4); cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x38: /*SAR b,CL*/ - if ((temp>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if ((temp>>(c-1))&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; while (c>0) { temp>>=1; @@ -2766,7 +2801,7 @@ void execx86(int cycs) seteab(temp); setznp8(temp); cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; // default: @@ -2793,11 +2828,11 @@ void execx86(int cycs) c--; cycles-=4; } - if (temp) flags|=C_FLAG; - else flags&=~C_FLAG; + if (temp) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(tempw>>15)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; case 0x08: /*ROR w,CL*/ @@ -2808,46 +2843,46 @@ void execx86(int cycs) c--; cycles-=4; } - if (tempw2) flags|=C_FLAG; - else flags&=~C_FLAG; + if (tempw2) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; seteaw(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((tempw^(tempw>>1))&0x4000) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; case 0x10: /*RCL w,CL*/ while (c>0) { - templ=flags&C_FLAG; - if (tempw&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; + templ = cpu_state.flags & C_FLAG; + if (tempw&0x8000) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw=(tempw<<1)|templ; c--; cycles-=4; } - if (templ) flags|=C_FLAG; - else flags&=~C_FLAG; + if (templ) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; seteaw(tempw); - if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((cpu_state.flags & C_FLAG)^(tempw>>15)) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; case 0x18: /*RCR w,CL*/ while (c>0) { - templ=flags&C_FLAG; + templ = cpu_state.flags & C_FLAG; tempw2=(templ&1)?0x8000:0; - if (tempw&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if (tempw&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw=(tempw>>1)|tempw2; c--; cycles-=4; } - if (tempw2) flags|=C_FLAG; - else flags&=~C_FLAG; + if (tempw2) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; seteaw(tempw); - if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; - else flags&=~V_FLAG; + if ((tempw^(tempw>>1))&0x4000) cpu_state.flags |= V_FLAG; + else cpu_state.flags &= ~V_FLAG; cycles-=((cpu_mod==3)?8:28); break; @@ -2855,44 +2890,44 @@ void execx86(int cycs) if (c>16) { tempw=0; - flags&=~C_FLAG; + cpu_state.flags &= ~C_FLAG; } else { - if ((tempw<<(c-1))&0x8000) flags|=C_FLAG; - else flags&=~C_FLAG; + if ((tempw<<(c-1))&0x8000) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw<<=c; } seteaw(tempw); setznp16(tempw); cycles-=(c*4); cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x28: /*SHR w,CL*/ if (c > 16) { tempw = 0; - flags &= ~C_FLAG; + cpu_state.flags &= ~C_FLAG; } else { - if ((tempw>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if ((tempw>>(c-1))&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; tempw>>=c; } seteaw(tempw); setznp16(tempw); cycles-=(c*4); cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; case 0x38: /*SAR w,CL*/ tempw2=tempw&0x8000; - if ((tempw>>(c-1))&1) flags|=C_FLAG; - else flags&=~C_FLAG; + if ((tempw>>(c-1))&1) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; while (c>0) { tempw=(tempw>>1)|tempw2; @@ -2902,7 +2937,7 @@ void execx86(int cycs) seteaw(tempw); setznp16(tempw); cycles-=((cpu_mod==3)?8:28); - flags|=A_FLAG; + cpu_state.flags |= A_FLAG; break; // default: @@ -2927,7 +2962,7 @@ void execx86(int cycs) cycles-=60; break; case 0xD6: /*SETALC*/ - AL = (flags & C_FLAG) ? 0xff : 0; + AL = (cpu_state.flags & C_FLAG) ? 0xff : 0; cycles -= 4; break; case 0xD7: /*XLAT*/ @@ -2944,13 +2979,13 @@ void execx86(int cycs) case 0xE0: /*LOOPNE*/ offset=(int8_t)FETCH(); CX--; - if (CX && !(flags&Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (CX && !(cpu_state.flags & Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=6; break; case 0xE1: /*LOOPE*/ offset=(int8_t)FETCH(); CX--; - if (CX && (flags&Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } + if (CX && (cpu_state.flags & Z_FLAG)) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=6; break; case 0xE2: /*LOOP*/ @@ -3070,7 +3105,7 @@ void execx86(int cycs) cycles-=2; break; case 0xF5: /*CMC*/ - flags^=C_FLAG; + cpu_state.flags ^= C_FLAG; cycles-=2; break; @@ -3084,7 +3119,7 @@ void execx86(int cycs) temp2=FETCH(); temp&=temp2; setznp8(temp); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=((cpu_mod==3)?5:11); break; case 0x10: /*NOT b*/ @@ -3101,20 +3136,20 @@ void execx86(int cycs) case 0x20: /*MUL AL,b*/ setznp8(AL); AX=AL*temp; - if (AX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - if (AH) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); + if (AX) cpu_state.flags &= ~Z_FLAG; + else cpu_state.flags |= Z_FLAG; + if (AH) cpu_state.flags |= (C_FLAG|V_FLAG); + else cpu_state.flags &= ~(C_FLAG|V_FLAG); cycles-=70; break; case 0x28: /*IMUL AL,b*/ setznp8(AL); tempws=(int)((int8_t)AL)*(int)((int8_t)temp); AX=tempws&0xFFFF; - if (AX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - if (AH) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); + if (AX) cpu_state.flags &= ~Z_FLAG; + else cpu_state.flags |= Z_FLAG; + if (AH) cpu_state.flags |= (C_FLAG|V_FLAG); + else cpu_state.flags &= ~(C_FLAG|V_FLAG); cycles-=80; break; case 0x30: /*DIV AL,b*/ @@ -3145,12 +3180,12 @@ void execx86(int cycs) else { printf("DIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,0); // printf("F6 30\n"); loadcs(readmemw(0,2)); @@ -3189,12 +3224,12 @@ void execx86(int cycs) else { printf("IDIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,0); // printf("F6 38\n"); loadcs(readmemw(0,2)); @@ -3222,7 +3257,7 @@ void execx86(int cycs) case 0x08: tempw2=getword(); setznp16(tempw&tempw2); - flags&=~(C_FLAG|V_FLAG|A_FLAG); + cpu_state.flags &= ~(C_FLAG|V_FLAG|A_FLAG); cycles-=((cpu_mod==3)?5:11); break; case 0x10: /*NOT w*/ @@ -3241,18 +3276,18 @@ void execx86(int cycs) // if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ); AX=templ&0xFFFF; DX=templ>>16; - if (AX|DX) flags&=~Z_FLAG; - else flags|=Z_FLAG; - if (DX) flags|=(C_FLAG|V_FLAG); - else flags&=~(C_FLAG|V_FLAG); + if (AX|DX) cpu_state.flags &= ~Z_FLAG; + else cpu_state.flags |= Z_FLAG; + if (DX) cpu_state.flags |= (C_FLAG|V_FLAG); + else cpu_state.flags &= ~(C_FLAG|V_FLAG); cycles-=118; 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); + if ((tempws>>15) && ((tempws>>15)!=-1)) cpu_state.flags |= (C_FLAG|V_FLAG); + else cpu_state.flags &= ~(C_FLAG|V_FLAG); // printf("%i ",tempws); AX=tempws&0xFFFF; tempws=(uint16_t)(tempws>>16); @@ -3260,8 +3295,8 @@ void execx86(int cycs) // printf("%04X %04X\n",AX,DX); // dumpregs(); // exit(-1); - if (AX|DX) flags&=~Z_FLAG; - else flags|=Z_FLAG; + if (AX|DX) cpu_state.flags &= ~Z_FLAG; + else cpu_state.flags |= Z_FLAG; cycles-=128; break; case 0x30: /*DIV AX,w*/ @@ -3277,12 +3312,12 @@ void execx86(int cycs) else { printf("DIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,0); // printf("F7 30\n"); loadcs(readmemw(0,2)); @@ -3304,12 +3339,12 @@ void execx86(int cycs) else { printf("IDIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,0); // printf("F7 38\n"); loadcs(readmemw(0,2)); @@ -3326,48 +3361,48 @@ void execx86(int cycs) break; case 0xF8: /*CLC*/ - flags&=~C_FLAG; + cpu_state.flags &= ~C_FLAG; cycles-=2; break; case 0xF9: /*STC*/ // printf("STC %04X\n",pc); - flags|=C_FLAG; + cpu_state.flags |= C_FLAG; cycles-=2; break; case 0xFA: /*CLI*/ - flags&=~I_FLAG; + cpu_state.flags &= ~I_FLAG; // printf("CLI at %04X:%04X\n",cs>>4,pc); cycles-=3; break; case 0xFB: /*STI*/ - flags|=I_FLAG; + cpu_state.flags |= I_FLAG; // printf("STI at %04X:%04X\n",cs>>4,pc); cycles-=2; break; case 0xFC: /*CLD*/ - flags&=~D_FLAG; + cpu_state.flags &= ~D_FLAG; cycles-=2; break; case 0xFD: /*STD*/ - flags|=D_FLAG; + cpu_state.flags |= D_FLAG; cycles-=2; break; case 0xFE: /*INC/DEC b*/ fetchea(); temp=geteab(); - flags&=~V_FLAG; + cpu_state.flags &= ~V_FLAG; if (rmdat&0x38) { setsub8nc(temp,1); temp2=temp-1; - if ((temp&0x80) && !(temp2&0x80)) flags|=V_FLAG; + if ((temp&0x80) && !(temp2&0x80)) cpu_state.flags |= V_FLAG; } else { setadd8nc(temp,1); temp2=temp+1; - if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; + if ((temp2&0x80) && !(temp&0x80)) cpu_state.flags |= V_FLAG; } // setznp8(temp2); seteab(temp2); @@ -3499,16 +3534,16 @@ void execx86(int cycs) clockhardware(); - if (trap && (flags&T_FLAG) && !noint) + if (trap && (cpu_state.flags & T_FLAG) && !noint) { // printf("TRAP!!! %04X:%04X\n",CS,pc); - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr=1<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); FETCHCLEAR(); @@ -3516,13 +3551,13 @@ void execx86(int cycs) else if (nmi && nmi_enable && nmi_mask) { // output = 3; - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr=2<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); FETCHCLEAR(); @@ -3534,13 +3569,13 @@ void execx86(int cycs) if (temp!=0xFF) { if (inhlt) cpu_state.pc++; - writememw(ss,(SP-2)&0xFFFF,flags|0xF000); + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags | 0xF000); writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; addr=temp<<2; - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; cpu_state.pc=readmemw(0,addr); // printf("INT INT INT\n"); loadcs(readmemw(0,addr+2)); @@ -3548,7 +3583,7 @@ void execx86(int cycs) // printf("INTERRUPT\n"); } } - takeint = (flags&I_FLAG) && (pic.pend&~pic.mask); + takeint = (cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask); if (noint) noint=0; ins++; diff --git a/src/codegen.c b/src/codegen.c index dfa9ea4..ba9c06a 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -48,7 +48,7 @@ void codegen_generate_reset() void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) { /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) return; /*CS and SS must always be valid*/ if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) @@ -65,7 +65,7 @@ void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) { /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (eflags & VM_FLAG)) + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) return; /*CS and SS must always be valid*/ if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c index 1d677d2..c5209c1 100644 --- a/src/codegen_ops_jump.c +++ b/src/codegen_ops_jump.c @@ -159,7 +159,7 @@ uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw&1) && !(eflags&VM_FLAG)) + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) return 0; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -184,7 +184,7 @@ uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw&1) && !(eflags&VM_FLAG)) + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) return 0; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -212,7 +212,7 @@ uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 { uint16_t offset; - if ((msw&1) && !(eflags&VM_FLAG)) + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) return 0; offset = fastreadw(cs + op_pc); @@ -240,7 +240,7 @@ uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 { uint16_t offset; - if ((msw&1) && !(eflags&VM_FLAG)) + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) return 0; offset = fastreadw(cs + op_pc); diff --git a/src/ibm.h b/src/ibm.h index c829b51..e6488e4 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -188,6 +188,8 @@ struct uint32_t l; uint16_t w; } CR0; + + uint16_t flags, eflags; } cpu_state; #define cycles cpu_state._cycles @@ -214,7 +216,6 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) -uint16_t flags,eflags; uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; extern int ins,output; @@ -273,7 +274,7 @@ uint32_t dr[8]; #define CR4_PVI (1 << 1) #define CR4_PSE (1 << 4) -#define IOPL ((flags>>12)&3) +#define IOPL ((cpu_state.flags >> 12) & 3) #define IOPLp ((!(msw&1)) || (CPL<=IOPL)) //#define IOPLp 1 diff --git a/src/x86.h b/src/x86.h index 1c15e1f..195f52a 100644 --- a/src/x86.h +++ b/src/x86.h @@ -55,7 +55,7 @@ extern uint16_t *mod1add[2][8]; extern uint32_t *mod1seg[8]; -#define IRQTEST ((flags&I_FLAG) && (pic.pend&~pic.mask) && !noint) +#define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) extern int cgate32; diff --git a/src/x86_flags.h b/src/x86_flags.h index 3fa9cc5..e7c2cc2 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -66,7 +66,7 @@ static inline int ZF_SET() return !cpu_state.flags_res; case FLAGS_UNKNOWN: - return flags & Z_FLAG; + return cpu_state.flags & Z_FLAG; } return 0; } @@ -106,7 +106,7 @@ static inline int NF_SET() return cpu_state.flags_res & 0x80000000; case FLAGS_UNKNOWN: - return flags & N_FLAG; + return cpu_state.flags & N_FLAG; } return 0; } @@ -142,7 +142,7 @@ static inline int PF_SET() return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; case FLAGS_UNKNOWN: - return flags & P_FLAG; + return cpu_state.flags & P_FLAG; } return 0; } @@ -194,7 +194,7 @@ static inline int VF_SET() return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); case FLAGS_UNKNOWN: - return flags & V_FLAG; + return cpu_state.flags & V_FLAG; } return 0; } @@ -234,7 +234,7 @@ static inline int AF_SET() return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; case FLAGS_UNKNOWN: - return flags & A_FLAG; + return cpu_state.flags & A_FLAG; } return 0; } @@ -286,7 +286,7 @@ static inline int CF_SET() case FLAGS_INC16: case FLAGS_INC32: case FLAGS_UNKNOWN: - return flags & C_FLAG; + return cpu_state.flags & C_FLAG; } return 0; } @@ -309,7 +309,7 @@ static inline void flags_rebuild() if (ZF_SET()) tempf |= Z_FLAG; if (NF_SET()) tempf |= N_FLAG; if (VF_SET()) tempf |= V_FLAG; - flags = (flags & ~0x8d5) | tempf; + cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; cpu_state.flags_op = FLAGS_UNKNOWN; } } @@ -324,9 +324,9 @@ static inline void flags_rebuild_c() if (cpu_state.flags_op != FLAGS_UNKNOWN) { if (CF_SET()) - flags |= C_FLAG; + cpu_state.flags |= C_FLAG; else - flags &= ~C_FLAG; + cpu_state.flags &= ~C_FLAG; } } @@ -447,67 +447,85 @@ static inline void setsub32nc(uint32_t a, uint32_t b) static inline void setadc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; + uint16_t c = (uint16_t)a + (uint16_t)b + tempc; cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c&0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static inline void setadc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; + uint32_t c = (uint32_t)a + (uint32_t)b + tempc; cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=znptable16[c&0xFFFF]; - if (c&0x10000) flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c&0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static inline void setsbc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); + uint16_t c = (uint16_t)a - (((uint16_t)b) + tempc); cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=znptable8[c&0xFF]; - if (c&0x100) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c&0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static inline void setsbc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); + uint32_t c = (uint32_t)a - (((uint32_t)b) + tempc); cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=(znptable16[c&0xFFFF]&~4); - flags|=(znptable8[c&0xFF]&4); - if (c&0x10000) flags|=C_FLAG; - if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; - if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= (znptable16[c&0xFFFF] & ~4); + cpu_state.flags |= (znptable8[c&0xFF] & 4); + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static inline void setadc32(uint32_t a, uint32_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; + uint32_t c = (uint32_t)a + (uint32_t)b + tempc; cpu_state.flags_op = FLAGS_UNKNOWN; - flags&=~0x8D5; - flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= ((c & 0x80000000) ? N_FLAG : ((!c) ? Z_FLAG : 0)); + cpu_state.flags |= (znptable8[c&0xFF] & P_FLAG); + if ((c > a) || (c == a && tempc)) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80000000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) + cpu_state.flags |= A_FLAG; } diff --git a/src/x86_ops_atomic.h b/src/x86_ops_atomic.h index d74c30e..06a33e2 100644 --- a/src/x86_ops_atomic.h +++ b/src/x86_ops_atomic.h @@ -141,9 +141,9 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat) if (cpu_state.abrt) return 0; flags_rebuild(); if (temp == temp2 && temp_hi == temp2_hi) - flags |= Z_FLAG; + cpu_state.flags |= Z_FLAG; else - flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } @@ -173,9 +173,9 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat) if (cpu_state.abrt) return 0; flags_rebuild(); if (temp == temp2 && temp_hi == temp2_hi) - flags |= Z_FLAG; + cpu_state.flags |= Z_FLAG; else - flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; cycles -= (cpu_mod == 3) ? 6 : 10; return 0; } diff --git a/src/x86_ops_bcd.h b/src/x86_ops_bcd.h index a7eaf03..2b41394 100644 --- a/src/x86_ops_bcd.h +++ b/src/x86_ops_bcd.h @@ -1,14 +1,14 @@ static int opAAA(uint32_t fetchdat) { flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xF) > 9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { AL += 6; AH++; - flags |= (A_FLAG | C_FLAG); + cpu_state.flags |= (A_FLAG | C_FLAG); } else - flags &= ~(A_FLAG | C_FLAG); + cpu_state.flags &= ~(A_FLAG | C_FLAG); AL &= 0xF; CLOCK_CYCLES(is486 ? 3 : 4); PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); @@ -42,14 +42,14 @@ static int opAAM(uint32_t fetchdat) static int opAAS(uint32_t fetchdat) { flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xF) > 9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { AL -= 6; AH--; - flags |= (A_FLAG | C_FLAG); + cpu_state.flags |= (A_FLAG | C_FLAG); } else - flags &= ~(A_FLAG | C_FLAG); + cpu_state.flags &= ~(A_FLAG | C_FLAG); AL &= 0xF; CLOCK_CYCLES(is486 ? 3 : 4); PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); @@ -61,23 +61,23 @@ static int opDAA(uint32_t fetchdat) uint16_t tempw; flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { int tempi = ((uint16_t)AL) + 6; AL += 6; - flags |= A_FLAG; - if (tempi & 0x100) flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) cpu_state.flags |= C_FLAG; } - if ((flags & C_FLAG) || (AL > 0x9f)) + if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) { AL += 0x60; - flags |= C_FLAG; + cpu_state.flags |= C_FLAG; } - tempw = flags & (C_FLAG | A_FLAG); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); setznp8(AL); flags_rebuild(); - flags |= tempw; + cpu_state.flags |= tempw; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); @@ -89,23 +89,23 @@ static int opDAS(uint32_t fetchdat) uint16_t tempw; flags_rebuild(); - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { int tempi = ((uint16_t)AL) - 6; AL -= 6; - flags |= A_FLAG; - if (tempi & 0x100) flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) cpu_state.flags |= C_FLAG; } - if ((flags & C_FLAG) || (AL > 0x9f)) + if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) { AL -= 0x60; - flags |= C_FLAG; + cpu_state.flags |= C_FLAG; } - tempw = flags & (C_FLAG | A_FLAG); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); setznp8(AL); flags_rebuild(); - flags |= tempw; + cpu_state.flags |= tempw; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); diff --git a/src/x86_ops_bit.h b/src/x86_ops_bit.h index 74194f5..7261fef 100644 --- a/src/x86_ops_bit.h +++ b/src/x86_ops_bit.h @@ -7,8 +7,8 @@ static int opBT_w_r_a16(uint32_t fetchdat) cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); @@ -23,8 +23,8 @@ static int opBT_w_r_a32(uint32_t fetchdat) cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; temp = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); @@ -39,8 +39,8 @@ static int opBT_l_r_a16(uint32_t fetchdat) cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); @@ -55,8 +55,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; temp = geteal(); if (cpu_state.abrt) return 1; flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); @@ -78,8 +78,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ seteaw(temp); if (cpu_state.abrt) return 1; \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ + else cpu_state.flags &= ~C_FLAG; \ \ CLOCK_CYCLES(6); \ PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \ @@ -99,8 +99,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ seteaw(temp); if (cpu_state.abrt) return 1; \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ + else cpu_state.flags &= ~C_FLAG; \ \ CLOCK_CYCLES(6); \ PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \ @@ -120,8 +120,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ seteal(temp); if (cpu_state.abrt) return 1; \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ + else cpu_state.flags &= ~C_FLAG; \ \ CLOCK_CYCLES(6); \ PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \ @@ -141,8 +141,8 @@ static int opBT_l_r_a32(uint32_t fetchdat) temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ seteal(temp); if (cpu_state.abrt) return 1; \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ - else flags &= ~C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ + else cpu_state.flags &= ~C_FLAG; \ \ CLOCK_CYCLES(6); \ PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \ @@ -169,8 +169,8 @@ static int opBA_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); return 0; @@ -191,8 +191,8 @@ static int opBA_w_a16(uint32_t fetchdat) break; } seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(6); PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); return 0; @@ -213,8 +213,8 @@ static int opBA_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); return 0; @@ -235,8 +235,8 @@ static int opBA_w_a32(uint32_t fetchdat) break; } seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(6); PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); return 0; @@ -258,8 +258,8 @@ static int opBA_l_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); return 0; @@ -280,8 +280,8 @@ static int opBA_l_a16(uint32_t fetchdat) break; } seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(6); PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); return 0; @@ -302,8 +302,8 @@ static int opBA_l_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x20: /*BT w,imm*/ - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); return 0; @@ -324,8 +324,8 @@ static int opBA_l_a32(uint32_t fetchdat) break; } seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) flags |= C_FLAG; - else flags &= ~C_FLAG; + if (tempc) cpu_state.flags |= C_FLAG; + else cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(6); PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); return 0; diff --git a/src/x86_ops_bitscan.h b/src/x86_ops_bitscan.h index 4fcc79c..98349da 100644 --- a/src/x86_ops_bitscan.h +++ b/src/x86_ops_bitscan.h @@ -4,7 +4,7 @@ if (temp) \ { \ int c; \ - flags &= ~Z_FLAG; \ + cpu_state.flags &= ~Z_FLAG; \ for (c = start; c != end; c += dir) \ { \ CLOCK_CYCLES(time); \ @@ -17,7 +17,7 @@ } \ } \ else \ - flags |= Z_FLAG; + cpu_state.flags |= Z_FLAG; static int opBSF_w_a16(uint32_t fetchdat) { diff --git a/src/x86_ops_flag.h b/src/x86_ops_flag.h index 9d3c0d7..db1dc20 100644 --- a/src/x86_ops_flag.h +++ b/src/x86_ops_flag.h @@ -1,7 +1,7 @@ static int opCMC(uint32_t fetchdat) { flags_rebuild(); - flags ^= C_FLAG; + cpu_state.flags ^= C_FLAG; CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); return 0; @@ -11,14 +11,14 @@ static int opCMC(uint32_t fetchdat) static int opCLC(uint32_t fetchdat) { flags_rebuild(); - flags &= ~C_FLAG; + cpu_state.flags &= ~C_FLAG; CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); return 0; } static int opCLD(uint32_t fetchdat) { - flags &= ~D_FLAG; + cpu_state.flags &= ~D_FLAG; CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); return 0; @@ -27,10 +27,10 @@ static int opCLI(uint32_t fetchdat) { if (!IOPLp) { - if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((eflags & VM_FLAG) && (cr4 & CR4_VME))) + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { - eflags &= ~VIF_FLAG; + cpu_state.eflags &= ~VIF_FLAG; } else { @@ -39,7 +39,7 @@ static int opCLI(uint32_t fetchdat) } } else - flags &= ~I_FLAG; + cpu_state.flags &= ~I_FLAG; CLOCK_CYCLES(3); PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); @@ -49,14 +49,14 @@ static int opCLI(uint32_t fetchdat) static int opSTC(uint32_t fetchdat) { flags_rebuild(); - flags |= C_FLAG; + cpu_state.flags |= C_FLAG; CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); return 0; } static int opSTD(uint32_t fetchdat) { - flags |= D_FLAG; + cpu_state.flags |= D_FLAG; CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); return 0; @@ -65,16 +65,16 @@ static int opSTI(uint32_t fetchdat) { if (!IOPLp) { - if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((eflags & VM_FLAG) && (cr4 & CR4_VME))) + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || + ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { - if (eflags & VIP_FLAG) + if (cpu_state.eflags & VIP_FLAG) { x86gpf(NULL,0); return 1; } else - eflags |= VIF_FLAG; + cpu_state.eflags |= VIF_FLAG; } else { @@ -83,7 +83,7 @@ static int opSTI(uint32_t fetchdat) } } else - flags |= I_FLAG; + cpu_state.flags |= I_FLAG; CPU_BLOCK_END(); @@ -95,7 +95,7 @@ static int opSTI(uint32_t fetchdat) static int opSAHF(uint32_t fetchdat) { flags_rebuild(); - flags = (flags & 0xff00) | (AH & 0xd5) | 2; + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; CLOCK_CYCLES(3); PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); @@ -106,7 +106,7 @@ static int opSAHF(uint32_t fetchdat) static int opLAHF(uint32_t fetchdat) { flags_rebuild(); - AH = flags & 0xff; + AH = cpu_state.flags & 0xff; CLOCK_CYCLES(3); PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); return 0; @@ -114,15 +114,15 @@ static int opLAHF(uint32_t fetchdat) static int opPUSHF(uint32_t fetchdat) { - if ((eflags & VM_FLAG) && (IOPL < 3)) + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { if (cr4 & CR4_VME) { uint16_t temp; flags_rebuild(); - temp = (flags & ~I_FLAG) | 0x3000; - if (eflags & VIF_FLAG) + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) temp |= I_FLAG; PUSH_W(temp); } @@ -135,7 +135,7 @@ static int opPUSHF(uint32_t fetchdat) else { flags_rebuild(); - PUSH_W(flags); + PUSH_W(cpu_state.flags); } CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); @@ -144,16 +144,16 @@ static int opPUSHF(uint32_t fetchdat) static int opPUSHFD(uint32_t fetchdat) { uint16_t tempw; - if ((eflags & VM_FLAG) && (IOPL < 3)) + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); return 1; } - if (cpu_CR4_mask & CR4_VME) tempw = eflags & 0x3c; - else if (CPUID) tempw = eflags & 0x24; - else tempw = eflags & 4; + if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c; + else if (CPUID) tempw = cpu_state.eflags & 0x24; + else tempw = cpu_state.eflags & 4; flags_rebuild(); - PUSH_L(flags | (tempw << 16)); + PUSH_L(cpu_state.flags | (tempw << 16)); CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); return cpu_state.abrt; @@ -163,7 +163,7 @@ static int opPOPF_286(uint32_t fetchdat) { uint16_t tempw; - if ((eflags & VM_FLAG) && (IOPL < 3)) + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); return 1; @@ -171,10 +171,10 @@ static int opPOPF_286(uint32_t fetchdat) tempw = POP_W(); if (cpu_state.abrt) return 1; - if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; - else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; + if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; flags_extract(); CLOCK_CYCLES(5); @@ -188,7 +188,7 @@ static int opPOPF(uint32_t fetchdat) { uint16_t tempw; - if ((eflags & VM_FLAG) && (IOPL < 3)) + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { if (cr4 & CR4_VME) { @@ -201,17 +201,17 @@ static int opPOPF(uint32_t fetchdat) return 1; } - if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (eflags & VIP_FLAG))) + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { ESP = old_esp; x86gpf(NULL, 0); return 1; } if (tempw & I_FLAG) - eflags |= VIF_FLAG; + cpu_state.eflags |= VIF_FLAG; else - eflags &= ~VIF_FLAG; - flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; } else { @@ -226,11 +226,11 @@ static int opPOPF(uint32_t fetchdat) return 1; if (!(CPL) || !(msw & 1)) - flags = (tempw & 0x7fd5) | 2; + cpu_state.flags = (tempw & 0x7fd5) | 2; else if (IOPLp) - flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; else - flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; } flags_extract(); @@ -245,7 +245,7 @@ static int opPOPFD(uint32_t fetchdat) { uint32_t templ; - if ((eflags & VM_FLAG) && (IOPL < 3)) + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { x86gpf(NULL, 0); return 1; @@ -253,16 +253,16 @@ static int opPOPFD(uint32_t fetchdat) templ = POP_L(); if (cpu_state.abrt) return 1; - if (!(CPL) || !(msw & 1)) flags = (templ & 0x7fd5) | 2; - else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2; - else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2; + if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; templ &= is486 ? 0x3c0000 : 0; - templ |= ((eflags&3) << 16); - if (cpu_CR4_mask & CR4_VME) eflags = (templ >> 16) & 0x3f; - else if (CPUID) eflags = (templ >> 16) & 0x27; - else if (is486) eflags = (templ >> 16) & 7; - else eflags = (templ >> 16) & 3; + templ |= ((cpu_state.eflags&3) << 16); + if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486) cpu_state.eflags = (templ >> 16) & 7; + else cpu_state.eflags = (templ >> 16) & 3; flags_extract(); diff --git a/src/x86_ops_int.h b/src/x86_ops_int.h index ce85225..efb2a5d 100644 --- a/src/x86_ops_int.h +++ b/src/x86_ops_int.h @@ -1,7 +1,7 @@ static int opINT3(uint32_t fetchdat) { int cycles_old = cycles; UNUSED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); return 1; @@ -15,7 +15,7 @@ static int opINT3(uint32_t fetchdat) static int opINT1(uint32_t fetchdat) { int cycles_old = cycles; UNUSED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); return 1; @@ -31,7 +31,7 @@ static int opINT(uint32_t fetchdat) int cycles_old = cycles; UNUSED(cycles_old); uint8_t temp = getbytef(); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { if (cr4 & CR4_VME) { @@ -104,7 +104,7 @@ static int opINTO(uint32_t fetchdat) { int cycles_old = cycles; UNUSED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); return 1; diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index 7c220a0..ee6c632 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -86,8 +86,8 @@ static int opF6_a16(uint32_t fetchdat) case 0x20: /*MUL AL,b*/ AX = AL * dst; flags_rebuild(); - if (AH) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(13); PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; @@ -95,8 +95,8 @@ static int opF6_a16(uint32_t fetchdat) tempws = (int)((int8_t)AL) * (int)((int8_t)dst); AX = tempws & 0xffff; flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(14); PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; @@ -110,8 +110,8 @@ static int opF6_a16(uint32_t fetchdat) if (!cpu_iscyrix) { flags_rebuild(); - flags |= 0x8D5; /*Not a Cyrix*/ - flags &= ~1; + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; } } else @@ -133,8 +133,8 @@ static int opF6_a16(uint32_t fetchdat) if (!cpu_iscyrix) { flags_rebuild(); - flags|=0x8D5; /*Not a Cyrix*/ - flags &= ~1; + cpu_state.flags|=0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; } } else @@ -192,8 +192,8 @@ static int opF6_a32(uint32_t fetchdat) case 0x20: /*MUL AL,b*/ AX = AL * dst; flags_rebuild(); - if (AH) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(13); PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; @@ -201,8 +201,8 @@ static int opF6_a32(uint32_t fetchdat) tempws = (int)((int8_t)AL) * (int)((int8_t)dst); AX = tempws & 0xffff; flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(14); PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; @@ -216,8 +216,8 @@ static int opF6_a32(uint32_t fetchdat) if (!cpu_iscyrix) { flags_rebuild(); - flags |= 0x8D5; /*Not a Cyrix*/ - flags &= ~1; + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; } } else @@ -239,8 +239,8 @@ static int opF6_a32(uint32_t fetchdat) if (!cpu_iscyrix) { flags_rebuild(); - flags|=0x8D5; /*Not a Cyrix*/ - flags &= ~1; + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; } } else @@ -303,8 +303,8 @@ static int opF7_w_a16(uint32_t fetchdat) AX = templ & 0xFFFF; DX = templ >> 16; flags_rebuild(); - if (DX) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(21); PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; @@ -313,8 +313,8 @@ static int opF7_w_a16(uint32_t fetchdat) AX = templ & 0xFFFF; DX = templ >> 16; flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(22); PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); break; @@ -403,8 +403,8 @@ static int opF7_w_a32(uint32_t fetchdat) AX = templ & 0xFFFF; DX = templ >> 16; flags_rebuild(); - if (DX) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(21); PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; @@ -413,8 +413,8 @@ static int opF7_w_a32(uint32_t fetchdat) AX = templ & 0xFFFF; DX = templ >> 16; flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(22); PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); break; @@ -503,8 +503,8 @@ static int opF7_l_a16(uint32_t fetchdat) EAX = temp64 & 0xffffffff; EDX = temp64 >> 32; flags_rebuild(); - if (EDX) flags |= (C_FLAG|V_FLAG); - else flags &= ~(C_FLAG|V_FLAG); + if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); + else cpu_state.flags &= ~(C_FLAG|V_FLAG); CLOCK_CYCLES(21); PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); break; @@ -513,8 +513,8 @@ static int opF7_l_a16(uint32_t fetchdat) EAX = temp64 & 0xffffffff; EDX = temp64 >> 32; flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(38); PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); break; @@ -579,8 +579,8 @@ static int opF7_l_a32(uint32_t fetchdat) EAX = temp64 & 0xffffffff; EDX = temp64 >> 32; flags_rebuild(); - if (EDX) flags |= (C_FLAG|V_FLAG); - else flags &= ~(C_FLAG|V_FLAG); + if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); + else cpu_state.flags &= ~(C_FLAG|V_FLAG); CLOCK_CYCLES(21); PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); break; @@ -589,8 +589,8 @@ static int opF7_l_a32(uint32_t fetchdat) EAX = temp64 & 0xffffffff; EDX = temp64 >> 32; flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG); - else flags &= ~(C_FLAG | V_FLAG); + if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(38); PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); break; @@ -619,12 +619,12 @@ static int opF7_l_a32(uint32_t fetchdat) static int opHLT(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { x86gpf(NULL,0); return 1; } - if (!((flags&I_FLAG) && pic_intpending)) + if (!((cpu_state.flags & I_FLAG) && pic_intpending)) { CLOCK_CYCLES_ALWAYS(100); cpu_state.pc--; @@ -739,7 +739,7 @@ static int opBOUND_l_a32(uint32_t fetchdat) static int opCLTS(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't CLTS\n"); x86gpf(NULL,0); @@ -782,7 +782,7 @@ static int opLOADALL(uint32_t fetchdat) return 1; } msw = (msw & 1) | readmemw(0, 0x806); - flags = (readmemw(0, 0x818) & 0xffd5) | 2; + cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; flags_extract(); tr.seg = readmemw(0, 0x816); cpu_state.pc = readmemw(0, 0x81A); @@ -890,8 +890,8 @@ static int opLOADALL386(uint32_t fetchdat) uint32_t la_addr = es + EDI; cr0 = readmeml(0, la_addr); - flags = readmemw(0, la_addr + 4); - eflags = readmemw(0, la_addr + 6); + cpu_state.flags = readmemw(0, la_addr + 4); + cpu_state.eflags = readmemw(0, la_addr + 6); flags_extract(); cpu_state.pc = readmeml(0, la_addr + 8); EDI = readmeml(0, la_addr + 0xC); diff --git a/src/x86_ops_mov_ctrl.h b/src/x86_ops_mov_ctrl.h index 7b21bf7..190dfdc 100644 --- a/src/x86_ops_mov_ctrl.h +++ b/src/x86_ops_mov_ctrl.h @@ -1,6 +1,6 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load from CRx\n"); x86gpf(NULL, 0); @@ -38,7 +38,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) } static int opMOV_r_CRx_a32(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load from CRx\n"); x86gpf(NULL, 0); @@ -77,7 +77,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) static int opMOV_r_DRx_a16(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load from DRx\n"); x86gpf(NULL, 0); @@ -91,7 +91,7 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat) } static int opMOV_r_DRx_a32(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load from DRx\n"); x86gpf(NULL, 0); @@ -108,7 +108,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) { uint32_t old_cr0 = cr0; - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load CRx\n"); x86gpf(NULL,0); @@ -164,7 +164,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) { uint32_t old_cr0 = cr0; - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load CRx\n"); x86gpf(NULL,0); @@ -219,7 +219,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) static int opMOV_DRx_r_a16(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load DRx\n"); x86gpf(NULL, 0); @@ -233,7 +233,7 @@ static int opMOV_DRx_r_a16(uint32_t fetchdat) } static int opMOV_DRx_r_a32(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load DRx\n"); x86gpf(NULL, 0); @@ -248,7 +248,7 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat) static int opMOV_r_TRx_a16(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load from TRx\n"); x86gpf(NULL, 0); @@ -262,7 +262,7 @@ static int opMOV_r_TRx_a16(uint32_t fetchdat) } static int opMOV_r_TRx_a32(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load from TRx\n"); x86gpf(NULL, 0); @@ -277,7 +277,7 @@ static int opMOV_r_TRx_a32(uint32_t fetchdat) static int opMOV_TRx_r_a16(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load TRx\n"); x86gpf(NULL, 0); @@ -290,7 +290,7 @@ static int opMOV_TRx_r_a16(uint32_t fetchdat) } static int opMOV_TRx_r_a32(uint32_t fetchdat) { - if ((CPL || (eflags&VM_FLAG)) && (cr0&1)) + if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) { pclog("Can't load TRx\n"); x86gpf(NULL, 0); diff --git a/src/x86_ops_mul.h b/src/x86_ops_mul.h index 27778b0..5971140 100644 --- a/src/x86_ops_mul.h +++ b/src/x86_ops_mul.h @@ -12,8 +12,8 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat) templ = ((int)tempw) * ((int)tempw2); flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].w = templ & 0xffff; CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); @@ -34,8 +34,8 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat) templ = ((int)tempw) * ((int)tempw2); flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].w = templ & 0xffff; CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); @@ -57,8 +57,8 @@ static int opIMUL_l_il_a16(uint32_t fetchdat) temp64 = ((int64_t)templ) * ((int64_t)templ2); flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; CLOCK_CYCLES(25); @@ -79,8 +79,8 @@ static int opIMUL_l_il_a32(uint32_t fetchdat) temp64 = ((int64_t)templ) * ((int64_t)templ2); flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; CLOCK_CYCLES(25); @@ -103,8 +103,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat) templ = ((int)tempw) * ((int)tempw2); flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].w = templ & 0xffff; CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); @@ -126,8 +126,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat) templ = ((int)tempw) * ((int)tempw2); flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].w = templ & 0xffff; CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); @@ -150,8 +150,8 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat) temp64 = ((int64_t)templ)*((int64_t)templ2); flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; CLOCK_CYCLES(20); @@ -173,8 +173,8 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat) temp64 = ((int64_t)templ)*((int64_t)templ2); flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; CLOCK_CYCLES(20); @@ -196,8 +196,8 @@ static int opIMUL_w_w_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = templ & 0xFFFF; flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(18); PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0); @@ -215,8 +215,8 @@ static int opIMUL_w_w_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].w = templ & 0xFFFF; flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(18); PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1); @@ -235,8 +235,8 @@ static int opIMUL_l_l_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(30); PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0); @@ -254,8 +254,8 @@ static int opIMUL_l_l_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG; - else flags &= ~(C_FLAG | V_FLAG); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; + else cpu_state.flags &= ~(C_FLAG | V_FLAG); CLOCK_CYCLES(30); PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1); diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index a59340b..5301ef3 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -14,10 +14,10 @@ static int opARPL_a16(uint32_t fetchdat) { temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); seteaw(temp_seg); if (cpu_state.abrt) return 1; - flags |= Z_FLAG; + cpu_state.flags |= Z_FLAG; } else - flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; CLOCK_CYCLES(is486 ? 9 : 20); PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0); @@ -39,10 +39,10 @@ static int opARPL_a32(uint32_t fetchdat) { temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); seteaw(temp_seg); if (cpu_state.abrt) return 1; - flags |= Z_FLAG; + cpu_state.flags |= Z_FLAG; } else - flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; CLOCK_CYCLES(is486 ? 9 : 20); PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1); @@ -63,7 +63,7 @@ static int opARPL_a32(uint32_t fetchdat) sel = geteaw(); if (cpu_state.abrt) return 1; \ \ flags_rebuild(); \ - if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ + if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ if (valid) \ { \ @@ -71,7 +71,7 @@ static int opARPL_a32(uint32_t fetchdat) desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ cpl_override = 0; if (cpu_state.abrt) return 1; \ } \ - flags &= ~Z_FLAG; \ + cpu_state.flags &= ~Z_FLAG; \ if ((desc & 0x1f00) == 0x000) valid = 0; \ if ((desc & 0x1f00) == 0x800) valid = 0; \ if ((desc & 0x1f00) == 0xa00) valid = 0; \ @@ -83,7 +83,7 @@ static int opARPL_a32(uint32_t fetchdat) } \ if (valid) \ { \ - flags |= Z_FLAG; \ + cpu_state.flags |= Z_FLAG; \ cpl_override = 1; \ if (is32) \ cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ @@ -114,7 +114,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1) \ sel = geteaw(); if (cpu_state.abrt) return 1; \ flags_rebuild(); \ - flags &= ~Z_FLAG; \ + cpu_state.flags &= ~Z_FLAG; \ if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ if (valid) \ @@ -133,7 +133,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1) } \ if (valid) \ { \ - flags |= Z_FLAG; \ + cpu_state.flags |= Z_FLAG; \ cpl_override = 1; \ if (is32) \ { \ @@ -185,7 +185,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; case 0x10: /*LLDT*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) + if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { pclog("Invalid LLDT!\n"); x86gpf(NULL,0); @@ -213,7 +213,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); break; case 0x18: /*LTR*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) + if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { pclog("Invalid LTR!\n"); x86gpf(NULL,0); @@ -248,7 +248,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) SEG_CHECK_READ(cpu_state.ea_seg); sel = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); - flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; if (!(sel & 0xfffc)) return 0; /*Null selector*/ cpl_override = 1; valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); @@ -261,7 +261,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) if (dpl < CPL || dpl < (sel & 3)) valid = 0; } if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/ - if (valid) flags |= Z_FLAG; + if (valid) cpu_state.flags |= Z_FLAG; CLOCK_CYCLES(20); PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); break; @@ -270,7 +270,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) SEG_CHECK_READ(cpu_state.ea_seg); sel = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); - flags &= ~Z_FLAG; + cpu_state.flags &= ~Z_FLAG; if (!(sel & 0xfffc)) return 0; /*Null selector*/ cpl_override = 1; valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); @@ -281,7 +281,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) if (dpl < CPL || dpl < (sel & 3)) valid = 0; if (desc & 0x0800) valid = 0; /*Code*/ if (!(desc & 0x0200)) valid = 0; /*Read-only data*/ - if (valid) flags |= Z_FLAG; + if (valid) cpu_state.flags |= Z_FLAG; CLOCK_CYCLES(20); PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); break; @@ -342,7 +342,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); break; case 0x10: /*LGDT*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) + if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { pclog("Invalid LGDT!\n"); x86gpf(NULL,0); @@ -361,7 +361,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); break; case 0x18: /*LIDT*/ - if ((CPL || eflags&VM_FLAG) && (cr0&1)) + if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { pclog("Invalid LIDT!\n"); x86gpf(NULL,0); @@ -390,7 +390,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; case 0x30: /*LMSW*/ - if ((CPL || eflags&VM_FLAG) && (msw&1)) + if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1)) { pclog("LMSW - ring not zero!\n"); x86gpf(NULL, 0); @@ -417,7 +417,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) case 0x38: /*INVLPG*/ if (is486) { - if ((CPL || eflags&VM_FLAG) && (cr0&1)) + if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) { pclog("Invalid INVLPG!\n"); x86gpf(NULL, 0); diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index bd95991..4adfcb1 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -14,8 +14,8 @@ static int opREP_INSB_ ## size(uint32_t fetchdat) temp = inb(DX); \ writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ + if (cpu_state.flags & D_FLAG) DEST_REG--; \ + else DEST_REG++; \ CNT_REG--; \ cycles -= 15; \ reads++; writes++; total_cycles += 15; \ @@ -43,8 +43,8 @@ static int opREP_INSW_ ## size(uint32_t fetchdat) temp = inw(DX); \ writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ + if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ + else DEST_REG += 2; \ CNT_REG--; \ cycles -= 15; \ reads++; writes++; total_cycles += 15; \ @@ -74,8 +74,8 @@ static int opREP_INSL_ ## size(uint32_t fetchdat) temp = inl(DX); \ writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ + if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ + else DEST_REG += 4; \ CNT_REG--; \ cycles -= 15; \ reads++; writes++; total_cycles += 15; \ @@ -101,8 +101,8 @@ static int opREP_OUTSB_ ## size(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ check_io_perm(DX); \ outb(DX, temp); \ - if (flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ + if (cpu_state.flags & D_FLAG) SRC_REG--; \ + else SRC_REG++; \ CNT_REG--; \ cycles -= 14; \ reads++; writes++; total_cycles += 14; \ @@ -128,8 +128,8 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat) check_io_perm(DX); \ check_io_perm(DX+1); \ outw(DX, temp); \ - if (flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ + if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ + else SRC_REG += 2; \ CNT_REG--; \ cycles -= 14; \ reads++; writes++; total_cycles += 14; \ @@ -157,8 +157,8 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat) check_io_perm(DX+2); \ check_io_perm(DX+3); \ outl(DX, temp); \ - if (flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ + if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ + else SRC_REG += 4; \ CNT_REG--; \ cycles -= 14; \ reads++; writes++; total_cycles += 14; \ @@ -192,8 +192,8 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ + if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ + else { DEST_REG++; SRC_REG++; } \ CNT_REG--; \ cycles -= is486 ? 3 : 4; \ ins++; \ @@ -230,8 +230,8 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ + if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ + else { DEST_REG += 2; SRC_REG += 2; } \ CNT_REG--; \ cycles -= is486 ? 3 : 4; \ ins++; \ @@ -268,8 +268,8 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ + if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ + else { DEST_REG += 4; SRC_REG += 4; } \ CNT_REG--; \ cycles -= is486 ? 3 : 4; \ ins++; \ @@ -301,8 +301,8 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat) { \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ + if (cpu_state.flags & D_FLAG) DEST_REG--; \ + else DEST_REG++; \ CNT_REG--; \ cycles -= is486 ? 4 : 5; \ writes++; total_cycles += is486 ? 4 : 5; \ @@ -331,8 +331,8 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat) { \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG+1); \ writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ + if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ + else DEST_REG += 2; \ CNT_REG--; \ cycles -= is486 ? 4 : 5; \ writes++; total_cycles += is486 ? 4 : 5; \ @@ -361,8 +361,8 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat) { \ CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG+3); \ writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ + if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ + else DEST_REG += 4; \ CNT_REG--; \ cycles -= is486 ? 4 : 5; \ writes++; total_cycles += is486 ? 4 : 5; \ @@ -391,8 +391,8 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat) while (CNT_REG > 0) \ { \ AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ + if (cpu_state.flags & D_FLAG) SRC_REG--; \ + else SRC_REG++; \ CNT_REG--; \ cycles -= is486 ? 4 : 5; \ reads++; total_cycles += is486 ? 4 : 5; \ @@ -420,8 +420,8 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat) while (CNT_REG > 0) \ { \ AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ + if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ + else SRC_REG += 2; \ CNT_REG--; \ cycles -= is486 ? 4 : 5; \ reads++; total_cycles += is486 ? 4 : 5; \ @@ -449,8 +449,8 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat) while (CNT_REG > 0) \ { \ EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ + if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ + else SRC_REG += 4; \ CNT_REG--; \ cycles -= is486 ? 4 : 5; \ reads++; total_cycles += is486 ? 4 : 5; \ @@ -483,8 +483,8 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat) temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ + if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ + else { DEST_REG++; SRC_REG++; } \ CNT_REG--; \ cycles -= is486 ? 7 : 9; \ reads += 2; total_cycles += is486 ? 7 : 9; \ @@ -513,8 +513,8 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ + if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ + else { DEST_REG += 2; SRC_REG += 2; } \ CNT_REG--; \ cycles -= is486 ? 7 : 9; \ reads += 2; total_cycles += is486 ? 7 : 9; \ @@ -543,8 +543,8 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat) temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ \ - if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ + if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ + else { DEST_REG += 4; SRC_REG += 4; } \ CNT_REG--; \ cycles -= is486 ? 7 : 9; \ reads += 2; total_cycles += is486 ? 7 : 9; \ @@ -575,8 +575,8 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat) uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ setsub8(AL, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ - if (flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ + if (cpu_state.flags & D_FLAG) DEST_REG--; \ + else DEST_REG++; \ CNT_REG--; \ cycles -= is486 ? 5 : 8; \ reads++; total_cycles += is486 ? 5 : 8; \ @@ -608,8 +608,8 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat) uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ setsub16(AX, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ - if (flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ + if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ + else DEST_REG += 2; \ CNT_REG--; \ cycles -= is486 ? 5 : 8; \ reads++; total_cycles += is486 ? 5 : 8; \ @@ -641,8 +641,8 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat) uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ setsub32(EAX, temp); \ tempz = (ZF_SET()) ? 1 : 0; \ - if (flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ + if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ + else DEST_REG += 4; \ CNT_REG--; \ cycles -= is486 ? 5 : 8; \ reads++; total_cycles += is486 ? 5 : 8; \ diff --git a/src/x86_ops_ret.h b/src/x86_ops_ret.h index d9db8ba..b69180c 100644 --- a/src/x86_ops_ret.h +++ b/src/x86_ops_ret.h @@ -1,5 +1,5 @@ #define RETF_a16(stack_offset) \ - if ((msw&1) && !(eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(0, stack_offset); \ return 1; \ @@ -21,7 +21,7 @@ cycles -= timing_retf_rm; #define RETF_a32(stack_offset) \ - if ((msw&1) && !(eflags&VM_FLAG)) \ + if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ { \ pmoderetf(1, stack_offset); \ return 1; \ @@ -94,7 +94,7 @@ static int opIRET_286(uint32_t fetchdat) { int cycles_old = cycles; UNUSED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); return 1; @@ -113,14 +113,14 @@ static int opIRET_286(uint32_t fetchdat) { cpu_state.pc = readmemw(ss, ESP); new_cs = readmemw(ss, ESP + 2); - flags = (flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; ESP += 6; } else { cpu_state.pc = readmemw(ss, SP); new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - flags = (flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; SP += 6; } loadcs(new_cs); @@ -139,7 +139,7 @@ static int opIRET(uint32_t fetchdat) { int cycles_old = cycles; UNUSED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { if (cr4 & CR4_VME) { @@ -151,17 +151,17 @@ static int opIRET(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (eflags & VIP_FLAG))) + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { x86gpf(NULL, 0); return 1; } SP += 6; if (new_flags & I_FLAG) - eflags |= VIF_FLAG; + cpu_state.eflags |= VIF_FLAG; else - eflags &= ~VIF_FLAG; - flags = (flags & 0x3300) | (new_flags & 0x4cd5) | 2; + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; loadcs(new_cs); cpu_state.pc = new_pc; @@ -189,14 +189,14 @@ static int opIRET(uint32_t fetchdat) { cpu_state.pc = readmemw(ss, ESP); new_cs = readmemw(ss, ESP + 2); - flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; ESP += 6; } else { cpu_state.pc = readmemw(ss, SP); new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; SP += 6; } loadcs(new_cs); @@ -216,7 +216,7 @@ static int opIRETD(uint32_t fetchdat) { int cycles_old = cycles; UNUSED(cycles_old); - if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); return 1; @@ -235,16 +235,16 @@ static int opIRETD(uint32_t fetchdat) { cpu_state.pc = readmeml(ss, ESP); new_cs = readmemw(ss, ESP + 4); - flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; - eflags = readmemw(ss, ESP + 10); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); ESP += 12; } else { cpu_state.pc = readmeml(ss, SP); new_cs = readmemw(ss, ((SP + 4) & 0xffff)); - flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; - eflags = readmemw(ss, (SP + 10) & 0xffff); + cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); SP += 12; } loadcs(new_cs); diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index 1fe2e89..1a31316 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -13,9 +13,9 @@ c--; \ } \ seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -28,14 +28,14 @@ c--; \ } \ seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x10: /*RCL b,CL*/ \ - temp2 = flags & C_FLAG; \ + temp2 = cpu_state.flags & C_FLAG; \ if (is486) CLOCK_CYCLES_ALWAYS(c); \ while (c > 0) \ { \ @@ -45,14 +45,14 @@ c--; \ } \ seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x18: /*RCR b,CL*/ \ - temp2 = flags & C_FLAG; \ + temp2 = cpu_state.flags & C_FLAG; \ if (is486) CLOCK_CYCLES_ALWAYS(c); \ while (c > 0) \ { \ @@ -62,9 +62,9 @@ c--; \ } \ seteab(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -105,9 +105,9 @@ c--; \ } \ seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -120,14 +120,14 @@ c--; \ } \ seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x10: /*RCL w, c*/ \ - temp2 = flags & C_FLAG; \ + temp2 = cpu_state.flags & C_FLAG; \ if (is486) CLOCK_CYCLES_ALWAYS(c); \ while (c > 0) \ { \ @@ -137,14 +137,14 @@ c--; \ } \ seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x18: /*RCR w, c*/ \ - temp2 = flags & C_FLAG; \ + temp2 = cpu_state.flags & C_FLAG; \ if (is486) CLOCK_CYCLES_ALWAYS(c); \ while (c > 0) \ { \ @@ -154,9 +154,9 @@ c--; \ } \ seteaw(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -197,9 +197,9 @@ c--; \ } \ seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ break; \ @@ -212,9 +212,9 @@ c--; \ } \ seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ break; \ @@ -229,14 +229,14 @@ c--; \ } \ seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ break; \ case 0x18: /*RCR l, c*/ \ - temp2 = flags & C_FLAG; \ + temp2 = cpu_state.flags & C_FLAG; \ if (is486) CLOCK_CYCLES_ALWAYS(c); \ while (c > 0) \ { \ @@ -246,9 +246,9 @@ c--; \ } \ seteal(temp); if (cpu_state.abrt) return 1; \ - flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ break; \ @@ -541,7 +541,7 @@ static int opD3_l_a32(uint32_t fetchdat) seteaw(tempw); if (cpu_state.abrt) return 1; \ setznp16(tempw); \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ } #define SHLD_l() \ @@ -553,7 +553,7 @@ static int opD3_l_a32(uint32_t fetchdat) seteal(templ); if (cpu_state.abrt) return 1; \ setznp32(templ); \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ } @@ -567,7 +567,7 @@ static int opD3_l_a32(uint32_t fetchdat) seteaw(tempw); if (cpu_state.abrt) return 1; \ setznp16(tempw); \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ } #define SHRD_l() \ @@ -579,7 +579,7 @@ static int opD3_l_a32(uint32_t fetchdat) seteal(templ); if (cpu_state.abrt) return 1; \ setznp32(templ); \ flags_rebuild(); \ - if (tempc) flags |= C_FLAG; \ + if (tempc) cpu_state.flags |= C_FLAG; \ } #define opSHxD(operation) \ diff --git a/src/x86_ops_string.h b/src/x86_ops_string.h index 3bdeace..433d683 100644 --- a/src/x86_ops_string.h +++ b/src/x86_ops_string.h @@ -6,8 +6,8 @@ static int opMOVSB_a16(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememb(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); return 0; @@ -20,8 +20,8 @@ static int opMOVSB_a32(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememb(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); return 0; @@ -35,8 +35,8 @@ static int opMOVSW_a16(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememw(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); return 0; @@ -49,8 +49,8 @@ static int opMOVSW_a32(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememw(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); return 0; @@ -64,8 +64,8 @@ static int opMOVSL_a16(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; writememl(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); return 0; @@ -78,8 +78,8 @@ static int opMOVSL_a32(uint32_t fetchdat) SEG_CHECK_WRITE(&cpu_state.seg_es); temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; writememl(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); return 0; @@ -95,8 +95,8 @@ static int opCMPSB_a16(uint32_t fetchdat) src = readmemb(cpu_state.ea_seg->base, SI); dst = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(src, dst); - if (flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } + if (cpu_state.flags & D_FLAG) { DI--; SI--; } + else { DI++; SI++; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); return 0; @@ -110,8 +110,8 @@ static int opCMPSB_a32(uint32_t fetchdat) src = readmemb(cpu_state.ea_seg->base, ESI); dst = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(src, dst); - if (flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } + if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } + else { EDI++; ESI++; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); return 0; @@ -126,8 +126,8 @@ static int opCMPSW_a16(uint32_t fetchdat) src = readmemw(cpu_state.ea_seg->base, SI); dst = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(src, dst); - if (flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } + if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } + else { DI += 2; SI += 2; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); return 0; @@ -141,8 +141,8 @@ static int opCMPSW_a32(uint32_t fetchdat) src = readmemw(cpu_state.ea_seg->base, ESI); dst = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(src, dst); - if (flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } + if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } + else { EDI += 2; ESI += 2; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); return 0; @@ -157,8 +157,8 @@ static int opCMPSL_a16(uint32_t fetchdat) src = readmeml(cpu_state.ea_seg->base, SI); dst = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(src, dst); - if (flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } + if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } + else { DI += 4; SI += 4; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0); return 0; @@ -172,8 +172,8 @@ static int opCMPSL_a32(uint32_t fetchdat) src = readmeml(cpu_state.ea_seg->base, ESI); dst = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(src, dst); - if (flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } + if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } + else { EDI += 4; ESI += 4; } CLOCK_CYCLES((is486) ? 8 : 10); PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1); return 0; @@ -183,8 +183,8 @@ static int opSTOSB_a16(uint32_t fetchdat) { SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, DI, AL); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI--; - else DI++; + if (cpu_state.flags & D_FLAG) DI--; + else DI++; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return 0; @@ -193,8 +193,8 @@ static int opSTOSB_a32(uint32_t fetchdat) { SEG_CHECK_WRITE(&cpu_state.seg_es); writememb(es, EDI, AL); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI--; - else EDI++; + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); return 0; @@ -204,8 +204,8 @@ static int opSTOSW_a16(uint32_t fetchdat) { SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, DI, AX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI -= 2; - else DI += 2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); return 0; @@ -214,8 +214,8 @@ static int opSTOSW_a32(uint32_t fetchdat) { SEG_CHECK_WRITE(&cpu_state.seg_es); writememw(es, EDI, AX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 2; - else EDI += 2; + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); return 0; @@ -225,8 +225,8 @@ static int opSTOSL_a16(uint32_t fetchdat) { SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, DI, EAX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI -= 4; - else DI += 4; + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); return 0; @@ -235,8 +235,8 @@ static int opSTOSL_a32(uint32_t fetchdat) { SEG_CHECK_WRITE(&cpu_state.seg_es); writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 4; - else EDI += 4; + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); return 0; @@ -250,8 +250,8 @@ static int opLODSB_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AL = temp; - if (flags & D_FLAG) SI--; - else SI++; + if (cpu_state.flags & D_FLAG) SI--; + else SI++; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); return 0; @@ -263,8 +263,8 @@ static int opLODSB_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AL = temp; - if (flags & D_FLAG) ESI--; - else ESI++; + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); return 0; @@ -277,8 +277,8 @@ static int opLODSW_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; AX = temp; - if (flags & D_FLAG) SI -= 2; - else SI += 2; + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); return 0; @@ -290,8 +290,8 @@ static int opLODSW_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; AX = temp; - if (flags & D_FLAG) ESI -= 2; - else ESI += 2; + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); return 0; @@ -304,8 +304,8 @@ static int opLODSL_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; EAX = temp; - if (flags & D_FLAG) SI -= 4; - else SI += 4; + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); return 0; @@ -317,8 +317,8 @@ static int opLODSL_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; EAX = temp; - if (flags & D_FLAG) ESI -= 4; - else ESI += 4; + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; CLOCK_CYCLES(5); PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); return 0; @@ -332,8 +332,8 @@ static int opSCASB_a16(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemb(es, DI); if (cpu_state.abrt) return 1; setsub8(AL, temp); - if (flags & D_FLAG) DI--; - else DI++; + if (cpu_state.flags & D_FLAG) DI--; + else DI++; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); return 0; @@ -345,8 +345,8 @@ static int opSCASB_a32(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; setsub8(AL, temp); - if (flags & D_FLAG) EDI--; - else EDI++; + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); return 0; @@ -359,8 +359,8 @@ static int opSCASW_a16(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemw(es, DI); if (cpu_state.abrt) return 1; setsub16(AX, temp); - if (flags & D_FLAG) DI -= 2; - else DI += 2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); return 0; @@ -372,8 +372,8 @@ static int opSCASW_a32(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; setsub16(AX, temp); - if (flags & D_FLAG) EDI -= 2; - else EDI += 2; + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); return 0; @@ -386,8 +386,8 @@ static int opSCASL_a16(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); temp = readmeml(es, DI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); - if (flags & D_FLAG) DI -= 4; - else DI += 4; + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); return 0; @@ -399,8 +399,8 @@ static int opSCASL_a32(uint32_t fetchdat) SEG_CHECK_READ(&cpu_state.seg_es); temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; setsub32(EAX, temp); - if (flags & D_FLAG) EDI -= 4; - else EDI += 4; + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; CLOCK_CYCLES(7); PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); return 0; @@ -414,8 +414,8 @@ static int opINSB_a16(uint32_t fetchdat) check_io_perm(DX); temp = inb(DX); writememb(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI--; - else DI++; + if (cpu_state.flags & D_FLAG) DI--; + else DI++; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); return 0; @@ -428,8 +428,8 @@ static int opINSB_a32(uint32_t fetchdat) check_io_perm(DX); temp = inb(DX); writememb(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI--; - else EDI++; + if (cpu_state.flags & D_FLAG) EDI--; + else EDI++; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); return 0; @@ -444,8 +444,8 @@ static int opINSW_a16(uint32_t fetchdat) check_io_perm(DX + 1); temp = inw(DX); writememw(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI -= 2; - else DI += 2; + if (cpu_state.flags & D_FLAG) DI -= 2; + else DI += 2; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); return 0; @@ -459,8 +459,8 @@ static int opINSW_a32(uint32_t fetchdat) check_io_perm(DX + 1); temp = inw(DX); writememw(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 2; - else EDI += 2; + if (cpu_state.flags & D_FLAG) EDI -= 2; + else EDI += 2; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); return 0; @@ -477,8 +477,8 @@ static int opINSL_a16(uint32_t fetchdat) check_io_perm(DX + 3); temp = inl(DX); writememl(es, DI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) DI -= 4; - else DI += 4; + if (cpu_state.flags & D_FLAG) DI -= 4; + else DI += 4; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); return 0; @@ -494,8 +494,8 @@ static int opINSL_a32(uint32_t fetchdat) check_io_perm(DX + 3); temp = inl(DX); writememl(es, EDI, temp); if (cpu_state.abrt) return 1; - if (flags & D_FLAG) EDI -= 4; - else EDI += 4; + if (cpu_state.flags & D_FLAG) EDI -= 4; + else EDI += 4; CLOCK_CYCLES(15); PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); return 0; @@ -508,8 +508,8 @@ static int opOUTSB_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); - if (flags & D_FLAG) SI--; - else SI++; + if (cpu_state.flags & D_FLAG) SI--; + else SI++; outb(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); @@ -522,8 +522,8 @@ static int opOUTSB_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); - if (flags & D_FLAG) ESI--; - else ESI++; + if (cpu_state.flags & D_FLAG) ESI--; + else ESI++; outb(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); @@ -538,8 +538,8 @@ static int opOUTSW_a16(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); - if (flags & D_FLAG) SI -= 2; - else SI += 2; + if (cpu_state.flags & D_FLAG) SI -= 2; + else SI += 2; outw(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); @@ -553,8 +553,8 @@ static int opOUTSW_a32(uint32_t fetchdat) temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; check_io_perm(DX); check_io_perm(DX + 1); - if (flags & D_FLAG) ESI -= 2; - else ESI += 2; + if (cpu_state.flags & D_FLAG) ESI -= 2; + else ESI += 2; outw(DX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); @@ -571,8 +571,8 @@ static int opOUTSL_a16(uint32_t fetchdat) check_io_perm(DX + 1); check_io_perm(DX + 2); check_io_perm(DX + 3); - if (flags & D_FLAG) SI -= 4; - else SI += 4; + if (cpu_state.flags & D_FLAG) SI -= 4; + else SI += 4; outl(EDX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); @@ -588,8 +588,8 @@ static int opOUTSL_a32(uint32_t fetchdat) check_io_perm(DX + 1); check_io_perm(DX + 2); check_io_perm(DX + 3); - if (flags & D_FLAG) ESI -= 4; - else ESI += 4; + if (cpu_state.flags & D_FLAG) ESI -= 4; + else ESI += 4; outl(EDX, temp); CLOCK_CYCLES(14); PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); diff --git a/src/x86seg.c b/src/x86seg.c index b508b87..547ed1b 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -115,21 +115,21 @@ void x86_doabrt(int x86_abrt) uint32_t addr = (x86_abrt << 2) + idt.base; if (stack32) { - writememw(ss,ESP-2,flags); + writememw(ss,ESP-2,cpu_state.flags); writememw(ss,ESP-4,CS); writememw(ss,ESP-6,cpu_state.pc); ESP-=6; } else { - writememw(ss,((SP-2)&0xFFFF),flags); + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); writememw(ss,((SP-4)&0xFFFF),CS); writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); SP-=6; } - flags&=~I_FLAG; - flags&=~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); @@ -315,7 +315,7 @@ int loadseg(uint16_t seg, x86seg *s) uint32_t addr; int dpl; - if (msw&1 && !(eflags&VM_FLAG)) + if (msw&1 && !(cpu_state.eflags&VM_FLAG)) { // intcount++; if (!(seg&~3)) @@ -499,7 +499,7 @@ void loadcs(uint16_t seg) uint16_t segdat[4]; uint32_t addr; if (output) pclog("Load CS %04X\n",seg); - if (msw&1 && !(eflags&VM_FLAG)) + if (msw&1 && !(cpu_state.eflags&VM_FLAG)) { // intcount++; // flushmmucache(); @@ -608,8 +608,8 @@ void loadcs(uint16_t seg) cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - if (eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; - else cpu_state.seg_cs.access=(0<<5) | 2; + if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; + else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); } } @@ -621,7 +621,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) uint16_t type,seg2; uint32_t newpc; // pclog("Load CS JMP %04X\n",seg); - if (msw&1 && !(eflags&VM_FLAG)) + if (msw&1 && !(cpu_state.eflags&VM_FLAG)) { if (!(seg&~3)) { @@ -827,7 +827,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) optype=JMP; cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); - flags &= ~NT_FLAG; + cpu_state.flags &= ~NT_FLAG; cpl_override=0; // case 0xB00: /*386 Busy task gate*/ // if (optype==JMP) pclog("Task switch!\n"); @@ -853,8 +853,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - if (eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; - else cpu_state.seg_cs.access=(0<<5) | 2; + if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; + else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); cycles -= timing_jmp_rm; } @@ -941,7 +941,7 @@ void loadcscall(uint16_t seg) int csout = output; - if (msw&1 && !(eflags&VM_FLAG)) + if (msw&1 && !(cpu_state.eflags&VM_FLAG)) { //flushmmucache(); if (csout) pclog("Protected mode CS load! %04X\n",seg); @@ -1370,8 +1370,8 @@ void loadcscall(uint16_t seg) cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - if (eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; - else cpu_state.seg_cs.access=(0<<5) | 2; + if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; + else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); } } @@ -1383,7 +1383,7 @@ void pmoderetf(int is32, uint16_t off) uint32_t addr, oaddr; uint16_t segdat[4],segdat2[4],seg,newss; uint32_t oldsp=ESP; - if (output) pclog("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags); + if (output) pclog("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,cpu_state.eflags); if (is32) { newpc=POPL(); @@ -1683,7 +1683,7 @@ void pmodeint(int num, int soft) // if (!num) pclog("Pmode int 0 at %04X(%06X):%08X\n",CS,cs,pc); // pclog("Pmode int %02X %i %04X:%08X %04X:%08X %i\n",num,soft,CS,pc, SS, ESP, abrt); - if (eflags&VM_FLAG && IOPL!=3 && soft) + if (cpu_state.eflags&VM_FLAG && IOPL!=3 && soft) { if (output) pclog("V86 banned int\n"); pclog("V86 banned int!\n"); @@ -1806,7 +1806,7 @@ void pmodeint(int num, int soft) x86np("Int gate CS not present\n", segdat[1] & 0xfffc); return; } - if ((eflags&VM_FLAG) && DPL2) + if ((cpu_state.eflags & VM_FLAG) && DPL2) { pclog("V86 calling int gate, DPL != 0\n"); x86gpf(NULL,segdat[1]&0xFFFC); @@ -1896,7 +1896,7 @@ void pmodeint(int num, int soft) if (type>=0x800) { // if (output) pclog("Push 32 %i\n",eflags&VM_FLAG); - if (eflags & VM_FLAG) + if (cpu_state.eflags & VM_FLAG) { PUSHL(GS); PUSHL(FS); @@ -1909,7 +1909,7 @@ void pmodeint(int num, int soft) } PUSHL(oldss); PUSHL(oldsp); - PUSHL(flags|(eflags<<16)); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); // if (soft) pclog("Pushl CS %08X\n", CS); PUSHL(CS); // if (soft) pclog("Pushl PC %08X\n", pc); @@ -1921,7 +1921,7 @@ void pmodeint(int num, int soft) // if (output) pclog("Push 16\n"); PUSHW(oldss); PUSHW(oldsp); - PUSHW(flags); + PUSHW(cpu_state.flags); // if (soft) pclog("Pushw CS %04X\n", CS); PUSHW(CS); // if (soft) pclog("Pushw pc %04X\n", pc); @@ -1947,7 +1947,7 @@ void pmodeint(int num, int soft) x86np("Int gate CS not present\n", segdat[1] & 0xfffc); return; } - if ((eflags & VM_FLAG) && DPL20x800) { - PUSHL(flags|(eflags<<16)); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); // if (soft) pclog("Pushlc CS %08X\n", CS); PUSHL(CS); // if (soft) pclog("Pushlc PC %08X\n", pc); @@ -1964,7 +1964,7 @@ void pmodeint(int num, int soft) } else { - PUSHW(flags); + PUSHW(cpu_state.flags); // if (soft) pclog("Pushwc CS %04X\n", CS); PUSHW(CS); // if (soft) pclog("Pushwc PC %04X\n", pc); @@ -1993,14 +1993,14 @@ void pmodeint(int num, int soft) cpl_override = 0; #endif - eflags&=~VM_FLAG; + cpu_state.eflags &= ~VM_FLAG; cpu_cur_status &= ~CPU_STATUS_V86; if (!(type&0x100)) { - flags&=~I_FLAG; + cpu_state.flags &= ~I_FLAG; // pclog("INT %02X disabling interrupts %i\n",num,soft); } - flags&=~(T_FLAG|NT_FLAG); + cpu_state.flags &= ~(T_FLAG|NT_FLAG); // if (output) pclog("Final Stack %04X:%08X\n",SS,ESP); cycles -= timing_int_pm; break; @@ -2065,7 +2065,7 @@ void pmodeiret(int is32) uint16_t seg = 0; uint32_t addr, oaddr; uint32_t oldsp=ESP; - if (is386 && (eflags&VM_FLAG)) + if (is386 && (cpu_state.eflags & VM_FLAG)) { // if (output) pclog("V86 IRET\n"); if (IOPL!=3) @@ -2093,7 +2093,7 @@ void pmodeiret(int is32) cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffff; CS=seg; - flags=(flags&0x3000)|(tempflags&0xCFD5)|2; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2; cycles -= timing_iret_rm; return; } @@ -2102,7 +2102,7 @@ void pmodeiret(int is32) //flushmmucache(); // if (output) pclog("Pmode IRET %04X:%04X ",CS,pc); - if (flags&NT_FLAG) + if (cpu_state.flags & NT_FLAG) { // pclog("NT IRET\n"); seg=readmemw(tr.base,0); @@ -2155,7 +2155,7 @@ void pmodeiret(int is32) segs[2]=POPL(); segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } // pclog("Pop stack %04X:%04X\n",newss,newsp); - eflags=tempflags>>16; + cpu_state.eflags = tempflags>>16; cpu_cur_status |= CPU_STATUS_V86; loadseg(segs[0],&cpu_state.seg_es); do_seg_v86_init(&cpu_state.seg_es); @@ -2185,7 +2185,7 @@ void pmodeiret(int is32) cpu_cur_status |= CPU_STATUS_NOTFLATSS; use32=0; cpu_cur_status &= ~CPU_STATUS_USE32; - flags=(tempflags&0xFFD5)|2; + cpu_state.flags = (tempflags&0xFFD5)|2; cycles -= timing_iret_v86; // pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X %i\n",CS,pc,SS,SP,DS,ES,FS,GS,abrt); // if (CS==0xFFFF && pc==0xFFFFFFFF) timetolive=12; @@ -2422,8 +2422,8 @@ void pmodeiret(int is32) cycles -= timing_iret_pm_outer; } cpu_state.pc=newpc; - flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2; - if (is32) eflags=tempflags>>16; + cpu_state.flags = (cpu_state.flags&~flagmask) | (tempflags&flagmask&0xFFD5)|2; + if (is32) cpu_state.eflags = tempflags>>16; // pclog("done\n"); } @@ -2477,13 +2477,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } if (cpu_state.abrt) return; - if (optype==IRET) flags&=~NT_FLAG; + if (optype==IRET) cpu_state.flags&=~NT_FLAG; // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); cpu_386_flags_rebuild(); writememl(tr.base,0x1C,cr3); writememl(tr.base,0x20,cpu_state.pc); - writememl(tr.base,0x24,flags|(eflags<<16)); + writememl(tr.base,0x24,cpu_state.flags | (cpu_state.eflags<<16)); writememl(tr.base,0x28,EAX); writememl(tr.base,0x2C,ECX); @@ -2556,8 +2556,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) cpu_state.pc=new_pc; // if (output) pclog("New pc %08X\n",new_pc); - flags=new_flags; - eflags=new_flags>>16; + cpu_state.flags = new_flags; + cpu_state.eflags = new_flags>>16; cpu_386_flags_extract(); // if (output) pclog("Load LDT %04X\n",new_ldt); @@ -2574,7 +2574,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) // if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); - if (eflags & VM_FLAG) + if (cpu_state.eflags & VM_FLAG) { loadcs(new_cs); set_use32(0); @@ -2695,12 +2695,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } if (cpu_state.abrt) return; - if (optype==IRET) flags&=~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); cpu_386_flags_rebuild(); writememw(tr.base,0x0E,cpu_state.pc); - writememw(tr.base,0x10,flags); + writememw(tr.base,0x10,cpu_state.flags); writememw(tr.base,0x12,AX); writememw(tr.base,0x14,CX); @@ -2760,7 +2761,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) cpu_state.pc=new_pc; // if (output) pclog("New pc %08X\n",new_pc); - flags=new_flags; + cpu_state.flags = new_flags; cpu_386_flags_extract(); // if (output) pclog("Load LDT %04X\n",new_ldt); diff --git a/src/x87_ops_arith.h b/src/x87_ops_arith.h index d5810c6..f52abe8 100644 --- a/src/x87_ops_arith.h +++ b/src/x87_ops_arith.h @@ -206,9 +206,9 @@ static int opFCOMI(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FICOM\n"); flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; CLOCK_CYCLES(4); return 0; } @@ -218,9 +218,9 @@ static int opFCOMIP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FICOMP\n"); flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); CLOCK_CYCLES(4); return 0; @@ -415,9 +415,9 @@ static int opFUCOMI(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FUCOMI\n"); flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; CLOCK_CYCLES(4); return 0; } @@ -427,9 +427,9 @@ static int opFUCOMIP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FUCOMIP\n"); flags_rebuild(); - flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG; + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); CLOCK_CYCLES(4); return 0; From e012420f90a563f752c6df5622c7ce623d9f1116 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 09:58:50 +0000 Subject: [PATCH 0549/1050] Added recompiled versions of CLC, CLD, CLI, CMC, STC, STD and STI. --- src/codegen_ops.c | 4 ++-- src/codegen_ops_misc.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/codegen_ops_misc.h | 10 +++++++++ src/codegen_reg.c | 2 ++ src/codegen_reg.h | 8 +++++-- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 8dc433a..3093ee5 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -43,7 +43,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES_16, ropLDS_16, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, ropRETF_imm_16, ropRETF_16, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, ropJMP_far_16, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_16, +/*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_16, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_16, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -65,7 +65,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES_32, ropLDS_32, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, ropRETF_imm_32, ropRETF_32, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_32 +/*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_32 }; diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index e3635e3..8afb20a 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -551,3 +551,50 @@ ropLxS(LES, &cpu_state.seg_es) ropLxS(LFS, &cpu_state.seg_fs) ropLxS(LGS, &cpu_state.seg_gs) ropLxS(LSS, &cpu_state.seg_ss) + +uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_CALL_FUNC(ir, flags_rebuild); + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); + return op_pc; +} +uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_CALL_FUNC(ir, flags_rebuild); + uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; +} +uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_CALL_FUNC(ir, flags_rebuild); + uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; +} + +uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); + return op_pc; +} +uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); + return op_pc; +} + +uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); + return op_pc; +} +uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + + uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); + return op_pc; +} diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index 20f115d..8f2fd76 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -25,3 +25,13 @@ uint32_t ropLGS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropLGS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropLSS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropLSS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 9c19d10..7fa5ff2 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -134,6 +134,8 @@ struct [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER}, [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, + + [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER}, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 63a0b6d..aa35ab5 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -115,8 +115,10 @@ enum IREG_NPXCx = 72, IREG_NPXSx = 73, + + IREG_flagsx = 74, - IREG_COUNT = 74, + IREG_COUNT = 75, IREG_INVALID = 255, @@ -181,7 +183,9 @@ enum IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, - IREG_ssegs = IREG_ssegsx + IREG_SIZE_B + IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, + + IREG_flags = IREG_flagsx + IREG_SIZE_W }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) From 5df3f6caef29bc2da122203e3aace55b7939161c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 11:50:24 +0000 Subject: [PATCH 0550/1050] Added recompiled versions of PUSHA and POPA. --- src/codegen_ops.c | 4 +-- src/codegen_ops_helpers.h | 4 +++ src/codegen_ops_stack.c | 73 +++++++++++++++++++++++++++++++++++++++ src/codegen_ops_stack.h | 6 ++++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 3093ee5..29a9d39 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -32,7 +32,7 @@ RecompOpFn recomp_opcodes[512] = /*40*/ ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, /*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8,NULL, NULL, NULL, NULL, NULL, +/*60*/ ropPUSHA_16, ropPOPA_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8,NULL, NULL, NULL, NULL, NULL, /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, @@ -54,7 +54,7 @@ RecompOpFn recomp_opcodes[512] = /*40*/ ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, /*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8,NULL, NULL, NULL, NULL, NULL, +/*60*/ ropPUSHA_32, ropPOPA_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8,NULL, NULL, NULL, NULL, NULL, /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h index 8d9d911..1b4cf30 100644 --- a/src/codegen_ops_helpers.h +++ b/src/codegen_ops_helpers.h @@ -24,7 +24,11 @@ static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) return IREG_eaaddr; } } +} +static inline int LOAD_SP(ir_data_t *ir) +{ + return LOAD_SP_WITH_OFFSET(ir, 0); } static inline void ADD_SP(ir_data_t *ir, int offset) diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c index fb63e1d..09485b2 100644 --- a/src/codegen_ops_stack.c +++ b/src/codegen_ops_stack.c @@ -288,3 +288,76 @@ uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc; } + + +uint32_t ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); + SUB_SP(ir, 16); + + return op_pc; +} +uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); + SUB_SP(ir, 32); + + return op_pc; +} + +uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); + ADD_SP(ir, 16); + + return op_pc; +} +uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); + ADD_SP(ir, 32); + + return op_pc; +} diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h index 9af5d60..085c637 100644 --- a/src/codegen_ops_stack.h +++ b/src/codegen_ops_stack.h @@ -38,3 +38,9 @@ uint32_t ropPOP_GS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From 335cea3ee1a619f3826e198a5c8b1077ef6b27bd Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 15:19:21 +0000 Subject: [PATCH 0551/1050] Added recompiled versions of PUSHF and PUSHFD. --- src/codegen_ops.c | 4 ++-- src/codegen_ops_stack.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/codegen_ops_stack.h | 3 +++ src/codegen_reg.c | 3 ++- src/codegen_reg.h | 8 +++++--- 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 29a9d39..10b19d2 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -36,7 +36,7 @@ RecompOpFn recomp_opcodes[512] = /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, -/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, NULL, ropPUSHF, NULL, NULL, NULL, /*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, @@ -58,7 +58,7 @@ RecompOpFn recomp_opcodes[512] = /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, -/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, NULL, NULL, ropPUSHFD, NULL, NULL, NULL, /*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c index 09485b2..29d2bda 100644 --- a/src/codegen_ops_stack.c +++ b/src/codegen_ops_stack.c @@ -1,6 +1,7 @@ #include "ibm.h" #include "x86.h" +#include "x86_flags.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -361,3 +362,42 @@ uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc; } + +uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + SUB_SP(ir, 2); + + return op_pc; +} +uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + + if (cpu_CR4_mask & CR4_VME) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); + else if (CPUID) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); + SUB_SP(ir, 4); + + return op_pc; +} diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h index 085c637..6b9ac57 100644 --- a/src/codegen_ops_stack.h +++ b/src/codegen_ops_stack.h @@ -44,3 +44,6 @@ uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 7fa5ff2..1e2fbb6 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -136,7 +136,8 @@ struct [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER}, - + [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ diff --git a/src/codegen_reg.h b/src/codegen_reg.h index aa35ab5..2e76936 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -117,8 +117,9 @@ enum IREG_NPXSx = 73, IREG_flagsx = 74, - - IREG_COUNT = 75, + IREG_eflagsx = 75, + + IREG_COUNT = 76, IREG_INVALID = 255, @@ -185,7 +186,8 @@ enum IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, - IREG_flags = IREG_flagsx + IREG_SIZE_W + IREG_flags = IREG_flagsx + IREG_SIZE_W, + IREG_eflags = IREG_eflagsx + IREG_SIZE_W }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) From 356f406b229fd1386fb6d1d4586bfc3c4e8a5df4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 18:41:53 +0000 Subject: [PATCH 0552/1050] Fix codegen pointer register reads. --- src/codegen_backend_arm64_uops.c | 14 ++++++++ src/codegen_backend_arm_ops.h | 2 ++ src/codegen_backend_arm_uops.c | 8 +++++ src/codegen_backend_x86-64_ops.c | 57 ++++++++++++++++++++++++++++++- src/codegen_backend_x86-64_ops.h | 1 + src/codegen_backend_x86-64_uops.c | 16 +++++++++ src/codegen_backend_x86_uops.c | 8 +++++ src/codegen_ir_defs.h | 4 +++ src/codegen_reg.c | 9 +++++ 9 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 0ee74dc..c7729af 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -2687,6 +2687,13 @@ void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_double - not in range\n"); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_pointer - not in range\n"); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) @@ -2801,6 +2808,13 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32_stack - not in range\n"); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + if (in_range12_q(stack_offset)) + host_arm64_LDR_IMM_X(block, host_reg, REG_SP, stack_offset); + else + fatal("codegen_direct_read_pointer_stack - not in range\n"); +} void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 542dc2a..b7877df 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -215,6 +215,8 @@ void host_arm_VSHR_D_U32(codeblock_t *block, int dest_reg, int src_reg, int shif void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSHRN_32(codeblock_t *block, int dest_reg, int src_reg, int shift); +void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg); + void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index a9ce03e..8ceebbc 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -2829,6 +2829,10 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + codegen_direct_read_32(block, host_reg, p); +} void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); @@ -2941,6 +2945,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of else fatal("codegen_direct_read_32 - not in range\n"); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + codegen_direct_read_32_stack(block, host_reg, stack_offset); +} void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 4ec3fd4..04d0080 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -777,6 +777,25 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addlong(block, (uint32_t)(uintptr_t)p); } } +void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOV64_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } + else if (offset < (1ull << 32)) + { + codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } + else + fatal("host_x86_MOV64_REG_ABS - out of range\n"); +} void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) { @@ -845,11 +864,29 @@ void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re else fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); } +void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); if (offset >= -128 && offset < 127) { @@ -863,6 +900,24 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset else fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); } +void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } + else + codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + else + fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); +} void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 10fe26a..a86e3ed 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -92,6 +92,7 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index dc87d53..4955609 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -2430,6 +2430,10 @@ void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + host_x86_MOV64_REG_ABS(block, host_reg, p); +} void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); @@ -2478,6 +2482,10 @@ void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); } +void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) +{ + host_x86_MOV64_ABS_REG(block, p, host_reg); +} void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); @@ -2527,6 +2535,10 @@ void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); +} void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); @@ -2540,6 +2552,10 @@ void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int hos { host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } +void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) +{ + host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); +} void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 20f39a7..67f28d4 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2440,6 +2440,10 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +{ + codegen_direct_read_32(block, host_reg, p); +} void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); @@ -2537,6 +2541,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of { host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +{ + codegen_direct_read_32_stack(block, host_reg, stack_offset); +} void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 15b3014..2a2733e 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -688,6 +688,7 @@ void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p); +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx); void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx); @@ -697,6 +698,7 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg); +void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg); @@ -706,10 +708,12 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset); +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg); +void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg); void codegen_set_jump_dest(codeblock_t *block, void *p); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 1e2fbb6..7d993fd 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -253,6 +253,15 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, codegen_direct_read_64(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; + case REG_POINTER: + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_pointer(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; + case REG_DOUBLE: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); From d63176e4726964cbb4e0874d8caab47bababf66d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 18:43:40 +0000 Subject: [PATCH 0553/1050] Move dynarec code memory out of codeblock structure. --- src/codegen.h | 9 +++++++-- src/codegen_backend.c | 3 +++ src/codegen_backend_arm.c | 18 +++++++++++------- src/codegen_backend_arm64.c | 18 +++++++++++------- src/codegen_backend_x86-64.c | 10 +++++++--- src/codegen_backend_x86-64.h | 2 +- src/codegen_backend_x86.c | 16 ++++++++++------ src/codegen_backend_x86.h | 3 ++- 8 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/codegen.h b/src/codegen.h index dcca68b..b212cbe 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -30,7 +30,10 @@ */ /*Hack until better memory management written*/ -#define BLOCK_DATA_SIZE 0x10000 +/*This is deliberately _not_ a power of two, to avoid cache aliasing problems. + Try changing this to a power of two, and watch the performance plummet :) + It's probably best for this to be a multiple of the cache line size though*/ +#define BLOCK_DATA_SIZE 0xff80 typedef struct codeblock_t { @@ -61,9 +64,11 @@ typedef struct codeblock_t uint32_t status; uint32_t flags; - uint8_t data[BLOCK_DATA_SIZE]; + uint8_t *data; } codeblock_t; +uint8_t *codeblock_data; + /*Code block uses FPU*/ #define CODEBLOCK_HAS_FPU 1 /*Code block is always entered with the same FPU top-of-stack*/ diff --git a/src/codegen_backend.c b/src/codegen_backend.c index fa01aa8..482e1e9 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -96,7 +96,10 @@ void codegen_reset() mem_reset_page_blocks(); for (c = 0; c < BLOCK_SIZE; c++) + { codeblock[c].pc = BLOCK_PC_INVALID; + codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; + } } void dump_block() diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 5852294..00c2a17 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -294,23 +294,27 @@ void codegen_backend_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE); #endif - if (!codeblock) - fatal("codeblock failed to alloc - %i\n", (BLOCK_SIZE+1) * sizeof(codeblock_t)); + if (!codeblock_data) + fatal("codeblock_data failed to alloc - %i\n", (BLOCK_SIZE+1) * BLOCK_DATA_SIZE); + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) + for (c = 0; c < BLOCK_SIZE+1; c++) + { codeblock[c].pc = BLOCK_PC_INVALID; + codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; + } #if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + start = (void *)((long)codeblock_data & pagemask); + len = (((BLOCK_SIZE+1) * BLOCK_DATA_SIZE) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index f201c4b..839f37e 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -289,23 +289,27 @@ void codegen_backend_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE); #endif - if (!codeblock) - fatal("codeblock failed to alloc - %i\n", (BLOCK_SIZE+1) * sizeof(codeblock_t)); + if (!codeblock_data) + fatal("codeblock_data failed to alloc - %i\n", (BLOCK_SIZE+1) * BLOCK_DATA_SIZE); + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) + for (c = 0; c < BLOCK_SIZE+1; c++) + { codeblock[c].pc = BLOCK_PC_INVALID; + codeblock[c].data = &codeblock_data[c * BLOCK_SIZE]; + } #if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + start = (void *)((long)codeblock_data & pagemask); + len = (((BLOCK_SIZE+1) * BLOCK_DATA_SIZE) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index bb92241..c509c04 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -276,17 +276,21 @@ void codegen_backend_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE); #endif + codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) + for (c = 0; c < BLOCK_SIZE+1; c++) + { + codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; + } #if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock & pagemask); diff --git a/src/codegen_backend_x86-64.h b/src/codegen_backend_x86-64.h index 50797ef..4e9ec51 100644 --- a/src/codegen_backend_x86-64.h +++ b/src/codegen_backend_x86-64.h @@ -10,7 +10,7 @@ #define HASH(l) ((l) & 0x1ffff) /*Hack until better memory management written*/ -#define BLOCK_EXIT_OFFSET 0xffe0 +#define BLOCK_EXIT_OFFSET (BLOCK_DATA_SIZE - 32) /*#define BLOCK_EXIT_OFFSET 0x7f0*/ #define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index daeff4d..675d9fe 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -261,22 +261,26 @@ void codegen_backend_init() long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); +#if defined WIN32 || defined _WIN32 || defined _WIN32 + codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE; #endif codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) + for (c = 0; c < BLOCK_SIZE + 1; c++) + { + codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; + } #if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + start = (void *)((long)codeblock_data & pagemask); + len = (((BLOCK_SIZE+1) * BLOCK_DATA_SIZE) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h index 5face4e..13ccfab 100644 --- a/src/codegen_backend_x86.h +++ b/src/codegen_backend_x86.h @@ -10,7 +10,8 @@ #define HASH(l) ((l) & 0x1ffff) /*Hack until better memory management written*/ -#define BLOCK_EXIT_OFFSET 0xfff0 +#define BLOCK_EXIT_OFFSET (BLOCK_DATA_SIZE - 16) +//#define BLOCK_EXIT_OFFSET 0xfff0 /*#define BLOCK_EXIT_OFFSET 0x7f0*/ #define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) From 2007c25177e0bbc5488f949caa4940da3a155206 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 20:29:48 +0000 Subject: [PATCH 0554/1050] Start reducing size of codeblock_t structure. Re-arrange all variables needed to run a block to fit in a single cache line. --- src/386_dynarec.c | 9 ++++---- src/codegen.h | 45 +++++++++++++++++++-------------------- src/codegen_backend.c | 14 ++++++------ src/codegen_backend_x86.c | 24 ++++++++++++++++++++- src/ibm.h | 10 ++++----- 5 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index bdb1aa7..eb727b0 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -19,7 +19,7 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -uint32_t cpu_cur_status = 0; +uint16_t cpu_cur_status = 0; int cpu_reps, cpu_reps_latched; int cpu_notreps, cpu_notreps_latched; @@ -663,16 +663,15 @@ void exec386_dynarec(int cycs) valid_block = 0; } } - if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) { /*FPU top-of-stack does not match the value this block was compiled with, re-compile using dynamic top-of-stack*/ - block->flags &= ~CODEBLOCK_STATIC_TOP; - block->was_recompiled = 0; + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); } } - if (valid_block && block->was_recompiled) + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) { void (*code)() = (void *)&block->data[BLOCK_START]; diff --git a/src/codegen.h b/src/codegen.h index b212cbe..f9d357c 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -37,10 +37,19 @@ typedef struct codeblock_t { + uint32_t pc; + uint32_t _cs; + uint32_t phys, phys_2; + uint16_t status; + uint16_t flags; + uint16_t ins; + uint8_t TOP; + uint32_t endpc; + uint8_t *data; + 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 each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ @@ -50,21 +59,6 @@ typedef struct codeblock_t /*Pointers for codeblock tree, used to search for blocks when hash lookup 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 flags; - - uint8_t *data; } codeblock_t; uint8_t *codeblock_data; @@ -73,6 +67,8 @@ uint8_t *codeblock_data; #define CODEBLOCK_HAS_FPU 1 /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 +/*Code block has been compiled*/ +#define CODEBLOCK_WAS_RECOMPILED 4 #define BLOCK_PC_INVALID 0xffffffff @@ -83,13 +79,14 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) while (block) { - if (a == block->cmp) + uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); + if (a == block_cmp) { if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) break; } - if (a < block->cmp) + if (a < block_cmp) block = block->left; else block = block->right; @@ -102,8 +99,7 @@ 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); - new_block->cmp = a; - + if (!block) { pages[new_block->phys >> 12].head = new_block; @@ -112,17 +108,20 @@ static inline void codeblock_tree_add(codeblock_t *new_block) else { codeblock_t *old_block = NULL; + uint64_t old_block_cmp; while (block) { old_block = block; - if (a < old_block->cmp) + old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); + + if (a < old_block_cmp) block = block->left; else block = block->right; } - if (a < old_block->cmp) + if (a < old_block_cmp) old_block->left = new_block; else old_block->right = new_block; diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 482e1e9..a24b7a5 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -277,7 +277,6 @@ void codegen_block_init(uint32_t phys_addr) block->ins = 0; block->pc = cs + cpu_state.pc; 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; @@ -287,8 +286,6 @@ void codegen_block_init(uint32_t phys_addr) block->flags = CODEBLOCK_STATIC_TOP; block->status = cpu_cur_status; - block->was_recompiled = 0; - recomp_page = block->phys & ~0xfff; codeblock_tree_add(block); @@ -301,6 +298,11 @@ ir_data_t *codegen_get_ir_data() return ir_data; } +static int get_block_nr(codeblock_t *block) +{ + return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); +} + void codegen_block_start_recompile(codeblock_t *block) { page_t *page = &pages[block->phys >> 12]; @@ -309,9 +311,9 @@ void codegen_block_start_recompile(codeblock_t *block) mem_flush_write_page(block->phys, cs+cpu_state.pc); block_num = HASH(block->phys); - block_current = block->pnt; + block_current = get_block_nr(block);//block->pnt; - if (block->pc != cs + cpu_state.pc || block->was_recompiled) + if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) fatal("Recompile to used block!\n"); block->status = cpu_cur_status; @@ -342,7 +344,7 @@ void codegen_block_start_recompile(codeblock_t *block) cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; block->TOP = cpu_state.TOP & 7; - block->was_recompiled = 1; + block->flags |= CODEBLOCK_WAS_RECOMPILED; codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 675d9fe..0fd6104 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -1,5 +1,6 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#include #include "ibm.h" #include "codegen.h" #include "codegen_backend.h" @@ -260,7 +261,28 @@ void codegen_backend_init() long pagesize = sysconf(_SC_PAGESIZE); long pagemask = ~(pagesize - 1); #endif - +pclog("sizeof(codeblock_t)=%i\n", sizeof(codeblock_t)); +pclog(" offsetof(codeblock_t, pc)=%i\n", offsetof(codeblock_t, pc)); +pclog(" offsetof(codeblock_t, _cs)=%i\n", offsetof(codeblock_t, _cs)); +pclog(" offsetof(codeblock_t, phys)=%i\n", offsetof(codeblock_t, phys)); +pclog(" offsetof(codeblock_t, phys_2)=%i\n", offsetof(codeblock_t, phys_2)); +pclog(" offsetof(codeblock_t, status)=%i\n", offsetof(codeblock_t, status)); +pclog(" offsetof(codeblock_t, flags)=%i\n", offsetof(codeblock_t, flags)); +pclog(" offsetof(codeblock_t, ins)=%i\n", offsetof(codeblock_t, ins)); +pclog(" offsetof(codeblock_t, TOP)=%i\n", offsetof(codeblock_t, TOP)); +pclog(" offsetof(codeblock_t, endpc)=%i\n", offsetof(codeblock_t, endpc)); +pclog(" offsetof(codeblock_t, data)=%i\n", offsetof(codeblock_t, data)); +pclog(" offsetof(codeblock_t, page_mask=%i\n", offsetof(codeblock_t, page_mask)); +pclog(" offsetof(codeblock_t, page_mask2=%i\n", offsetof(codeblock_t, page_mask2)); +pclog(" offsetof(codeblock_t, dirty_mask=%i\n", offsetof(codeblock_t, dirty_mask)); +pclog(" offsetof(codeblock_t, dirty_mask2=%i\n", offsetof(codeblock_t, dirty_mask2)); +pclog(" offsetof(codeblock_t, prev=%i\n", offsetof(codeblock_t, prev)); +pclog(" offsetof(codeblock_t, next=%i\n", offsetof(codeblock_t, next)); +pclog(" offsetof(codeblock_t, prev_2=%i\n", offsetof(codeblock_t, prev_2)); +pclog(" offsetof(codeblock_t, next_2=%i\n", offsetof(codeblock_t, next_2)); +pclog(" offsetof(codeblock_t, parent=%i\n", offsetof(codeblock_t, parent)); +pclog(" offsetof(codeblock_t, left=%i\n", offsetof(codeblock_t, left)); +pclog(" offsetof(codeblock_t, right=%i\n", offsetof(codeblock_t, right)); codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); #if defined WIN32 || defined _WIN32 || defined _WIN32 codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); diff --git a/src/ibm.h b/src/ibm.h index e6488e4..2221e8c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -194,7 +194,7 @@ struct #define cycles cpu_state._cycles -extern uint32_t cpu_cur_status; +extern uint16_t cpu_cur_status; /*The flags below must match in both cpu_cur_status and block->status for a block to be valid*/ @@ -202,13 +202,13 @@ extern uint32_t cpu_cur_status; #define CPU_STATUS_STACK32 (1 << 1) #define CPU_STATUS_PMODE (1 << 2) #define CPU_STATUS_V86 (1 << 3) -#define CPU_STATUS_FLAGS 0xffff +#define CPU_STATUS_FLAGS 0xff /*If the flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ -#define CPU_STATUS_NOTFLATDS (1 << 16) -#define CPU_STATUS_NOTFLATSS (1 << 17) -#define CPU_STATUS_MASK 0xffff0000 +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_MASK 0xff00 #define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; From 9ff1c7f409facd27148d798ce1cb205558fc594c Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 29 Nov 2018 20:05:12 +0000 Subject: [PATCH 0555/1050] Further reductions to codeblock_t size - replace link pointers with uint16_t block indicies, shrink ins to uint8_t, remove endpc. codeblock_t now fits in a 64-byte cacheline on 32-bit platforms. --- src/386_dynarec.c | 2 +- src/codegen.h | 155 ++++++++++++++++++++--------------- src/codegen_backend.c | 102 +++++++++++------------ src/codegen_backend_arm.c | 14 ++-- src/codegen_backend_arm64.c | 14 ++-- src/codegen_backend_x86-64.c | 14 ++-- src/codegen_backend_x86.c | 37 ++++----- src/mem.c | 4 +- src/mem.h | 4 +- 9 files changed, 186 insertions(+), 160 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index eb727b0..8954538 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -651,7 +651,7 @@ 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); + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + 0x400); page_t *page_2 = &pages[phys_addr_2 >> 12]; if ((block->phys_2 ^ phys_addr_2) & ~0xfff) valid_block = 0; diff --git a/src/codegen.h b/src/codegen.h index f9d357c..72a3820 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -42,9 +42,13 @@ typedef struct codeblock_t uint32_t phys, phys_2; uint16_t status; uint16_t flags; - uint16_t ins; + uint8_t ins; uint8_t TOP; - uint32_t endpc; + + /*Pointers for codeblock tree, used to search for blocks when hash lookup + fails.*/ + uint16_t parent, left, right; + uint8_t *data; uint64_t page_mask, page_mask2; @@ -53,16 +57,16 @@ typedef struct codeblock_t /*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.*/ - struct codeblock_t *prev, *next; - struct codeblock_t *prev_2, *next_2; - - /*Pointers for codeblock tree, used to search for blocks when hash lookup - fails.*/ - struct codeblock_t *parent, *left, *right; + uint16_t prev, next; + uint16_t prev_2, next_2; } codeblock_t; uint8_t *codeblock_data; +extern codeblock_t *codeblock; + +extern codeblock_t **codeblock_hash; + /*Code block uses FPU*/ #define CODEBLOCK_HAS_FPU 1 /*Code block is always entered with the same FPU top-of-stack*/ @@ -72,11 +76,22 @@ uint8_t *codeblock_data; #define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_INVALID 0 + +static inline int get_block_nr(codeblock_t *block) +{ + return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); +} + static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) { - codeblock_t *block = pages[phys >> 12].head; + codeblock_t *block; uint64_t a = _cs | ((uint64_t)phys << 32); + if (!pages[phys >> 12].head) + return NULL; + + block = &codeblock[pages[phys >> 12].head]; while (block) { uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); @@ -87,9 +102,9 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) break; } if (a < block_cmp) - block = block->left; + block = block->left ? &codeblock[block->left] : NULL; else - block = block->right; + block = block->right ? &codeblock[block->right] : NULL; } return block; @@ -97,18 +112,18 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) static inline void codeblock_tree_add(codeblock_t *new_block) { - codeblock_t *block = pages[new_block->phys >> 12].head; + codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - if (!block) + if (!pages[new_block->phys >> 12].head) { - pages[new_block->phys >> 12].head = new_block; - new_block->parent = new_block->left = new_block->right = NULL; + pages[new_block->phys >> 12].head = get_block_nr(new_block); + new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; } else { codeblock_t *old_block = NULL; - uint64_t old_block_cmp; + uint64_t old_block_cmp = 0; while (block) { @@ -116,58 +131,68 @@ static inline void codeblock_tree_add(codeblock_t *new_block) old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); if (a < old_block_cmp) - block = block->left; + block = block->left ? &codeblock[block->left] : NULL; else - block = block->right; + block = block->right ? &codeblock[block->right] : NULL; } if (a < old_block_cmp) - old_block->left = new_block; + old_block->left = get_block_nr(new_block); else - old_block->right = new_block; + old_block->right = get_block_nr(new_block); - new_block->parent = old_block; - new_block->left = new_block->right = NULL; + new_block->parent = get_block_nr(old_block); + new_block->left = new_block->right = BLOCK_INVALID; } } static inline void codeblock_tree_delete(codeblock_t *block) { - codeblock_t *parent = block->parent; + uint16_t parent_nr = block->parent; + codeblock_t *parent; + + if (block->parent) + parent = &codeblock[block->parent]; + else + parent = NULL; if (!block->left && !block->right) { /*Easy case - remove from parent*/ if (!parent) - pages[block->phys >> 12].head = NULL; + pages[block->phys >> 12].head = BLOCK_INVALID; else { - if (parent->left == block) - parent->left = NULL; - if (parent->right == block) - parent->right = NULL; + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = BLOCK_INVALID; + if (parent->right == block_nr) + parent->right = BLOCK_INVALID; } return; } else if (!block->left) { /*Only right node*/ - if (!parent) + if (!parent_nr) { pages[block->phys >> 12].head = block->right; - pages[block->phys >> 12].head->parent = NULL; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; } else { - if (parent->left == block) + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) { parent->left = block->right; - parent->left->parent = parent; + codeblock[parent->left].parent = parent_nr; } - if (parent->right == block) + if (parent->right == block_nr) { parent->right = block->right; - parent->right->parent = parent; + codeblock[parent->right].parent = parent_nr; } } return; @@ -175,22 +200,24 @@ static inline void codeblock_tree_delete(codeblock_t *block) else if (!block->right) { /*Only left node*/ - if (!parent) + if (!parent_nr) { pages[block->phys >> 12].head = block->left; - pages[block->phys >> 12].head->parent = NULL; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; } else { - if (parent->left == block) + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) { parent->left = block->left; - parent->left->parent = parent; + codeblock[parent->left].parent = parent_nr; } - if (parent->right == block) + if (parent->right == block_nr) { parent->right = block->left; - parent->right->parent = parent; + codeblock[parent->right].parent = parent_nr; } } return; @@ -198,50 +225,54 @@ static inline void codeblock_tree_delete(codeblock_t *block) else { /*Difficult case - node has two children. Walk right child to find lowest node*/ - codeblock_t *lowest = block->right, *highest; + codeblock_t *lowest = &codeblock[block->right], *highest; codeblock_t *old_parent; + uint16_t lowest_nr; while (lowest->left) - lowest = lowest->left; - - old_parent = lowest->parent; + lowest = &codeblock[lowest->left]; + lowest_nr = get_block_nr(lowest); + + old_parent = &codeblock[lowest->parent]; /*Replace deleted node with lowest node*/ - if (!parent) - pages[block->phys >> 12].head = lowest; + if (!parent_nr) + pages[block->phys >> 12].head = lowest_nr; else { - if (parent->left == block) - parent->left = lowest; - if (parent->right == block) - parent->right = lowest; + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = lowest_nr; + if (parent->right == block_nr) + parent->right = lowest_nr; } - lowest->parent = parent; + lowest->parent = parent_nr; lowest->left = block->left; if (lowest->left) - lowest->left->parent = lowest; + codeblock[lowest->left].parent = lowest_nr; - old_parent->left = NULL; + old_parent->left = BLOCK_INVALID; - highest = lowest->right; - if (!highest) + highest = &codeblock[lowest->right]; + if (!lowest->right) { - if (lowest != block->right) + if (lowest_nr != block->right) { lowest->right = block->right; - block->right->parent = lowest; + codeblock[block->right].parent = lowest_nr; } return; } while (highest->right) - highest = highest->right; + highest = &codeblock[highest->right]; - if (block->right && block->right != lowest) + if (block->right && block->right != lowest_nr) { highest->right = block->right; - block->right->parent = highest; + codeblock[block->right].parent = get_block_nr(highest); } } } @@ -251,10 +282,6 @@ static inline void codeblock_tree_delete(codeblock_t *block) #define PAGE_MASK_MASK 63 #define PAGE_MASK_SHIFT 4 -extern codeblock_t *codeblock; - -extern codeblock_t **codeblock_hash; - void codegen_init(); void codegen_close(); void codegen_reset(); diff --git a/src/codegen_backend.c b/src/codegen_backend.c index a24b7a5..de292e3 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -122,43 +122,44 @@ void dump_block() static void add_to_block_list(codeblock_t *block) { - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + uint16_t block_prev_nr = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + uint16_t block_nr = get_block_nr(block); if (!block->page_mask) fatal("add_to_block_list - mask = 0\n"); - if (block_prev) + if (block_prev_nr) { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + block->next = block_prev_nr; + codeblock[block_prev_nr].prev = block_nr; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block_nr; } else { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + block->next = BLOCK_INVALID; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block_nr; } if (block->next) { - if (block->next->pc == BLOCK_PC_INVALID) - fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); + if (codeblock[block->next].pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], (void *)codeblock, block_current, block_pos); } if (block->page_mask2) { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; + block_prev_nr = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - if (block_prev) + if (block_prev_nr) { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + block->next_2 = block_prev_nr; + codeblock[block_prev_nr].prev_2 = block_nr; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block_nr; } else { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + block->next_2 = BLOCK_INVALID; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block_nr; } } } @@ -170,15 +171,15 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) if (block->prev) { - block->prev->next = block->next; + codeblock[block->prev].next = block->next; if (block->next) - block->next->prev = block->prev; + codeblock[block->next].prev = block->prev; } else { pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; if (block->next) - block->next->prev = NULL; + codeblock[block->next].prev = BLOCK_INVALID; else mem_flush_write_page(block->phys, 0); } @@ -191,16 +192,16 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) if (block->prev_2) { - block->prev_2->next_2 = block->next_2; + codeblock[block->prev_2].next_2 = block->next_2; if (block->next_2) - block->next_2->prev_2 = block->prev_2; + codeblock[block->next_2].prev_2 = block->prev_2; } 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; + codeblock[block->next_2].prev_2 = BLOCK_INVALID; else mem_flush_write_page(block->phys_2, 0); } @@ -223,32 +224,36 @@ 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[(phys_addr >> 10) & 3]; + uint16_t block_nr = page->block[(phys_addr >> 10) & 3]; - while (block) + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + if (mask & block->page_mask) { delete_block(block); cpu_recomp_evicted++; } - if (block == block->next) + if (block == &codeblock[block->next]) fatal("Broken 1\n"); - block = block->next; + block_nr = block->next; } - block = page->block_2[(phys_addr >> 10) & 3]; + block_nr = page->block_2[(phys_addr >> 10) & 3]; - while (block) + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + if (mask & block->page_mask2) { delete_block(block); cpu_recomp_evicted++; } - if (block == block->next_2) + if (block == &codeblock[block->next_2]) fatal("Broken 2\n"); - block = block->next_2; + block_nr = block->next_2; } } @@ -261,6 +266,8 @@ void codegen_block_init(uint32_t phys_addr) mem_flush_write_page(phys_addr, cs+cpu_state.pc); block_current = (block_current + 1) & BLOCK_MASK; + if (!block_current) + block_current++; block = &codeblock[block_current]; // if (block->pc == 0xb00b4ff5) @@ -280,8 +287,8 @@ void codegen_block_init(uint32_t phys_addr) 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->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; block->page_mask = 0; block->flags = CODEBLOCK_STATIC_TOP; block->status = cpu_cur_status; @@ -298,11 +305,6 @@ ir_data_t *codegen_get_ir_data() return ir_data; } -static int get_block_nr(codeblock_t *block) -{ - return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); -} - void codegen_block_start_recompile(codeblock_t *block) { page_t *page = &pages[block->phys >> 12]; @@ -372,14 +374,12 @@ void codegen_block_generate_end_mask() uint32_t start_pc; uint32_t end_pc; - block->endpc = codegen_endpc; - block->page_mask = 0; start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) + if ((block->pc ^ codegen_endpc) & ~0x3ff) end_pc = 0x3ff & ~15; else - end_pc = (block->endpc & 0x3ff) & ~15; + end_pc = (codegen_endpc & 0x3ff) & ~15; if (end_pc < start_pc) end_pc = 0x3ff; start_pc >>= PAGE_MASK_SHIFT; @@ -396,37 +396,37 @@ void codegen_block_generate_end_mask() block->phys_2 = -1; block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) + block->next_2 = block->prev_2 = BLOCK_INVALID; + if ((block->pc ^ codegen_endpc) & ~0x3ff) { - block->phys_2 = get_phys_noabrt(block->endpc); + block->phys_2 = get_phys_noabrt(codegen_endpc); if (block->phys_2 != -1) { page_t *page_2 = &pages[block->phys_2 >> 12]; start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; + end_pc = (codegen_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[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); + mem_flush_write_page(block->phys_2, codegen_endpc); 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 == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)block->next_2); + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[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); +// pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); recomp_page = -1; } @@ -443,8 +443,8 @@ void codegen_block_end_recompile(codeblock_t *block) codegen_timing_block_end(); remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; codegen_block_generate_end_mask(); add_to_block_list(block); // pclog("End block %i\n", block_num); diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 00c2a17..d2b0fe4 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -294,19 +294,19 @@ void codegen_backend_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE); + codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE); #endif if (!codeblock_data) fatal("codeblock_data failed to alloc - %i\n", (BLOCK_SIZE+1) * BLOCK_DATA_SIZE); - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE+1; c++) + for (c = 0; c < BLOCK_SIZE; c++) { codeblock[c].pc = BLOCK_PC_INVALID; codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; @@ -314,7 +314,7 @@ void codegen_backend_init() #if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock_data & pagemask); - len = (((BLOCK_SIZE+1) * BLOCK_DATA_SIZE) + pagesize) & pagemask; + len = ((BLOCK_SIZE * BLOCK_DATA_SIZE) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); @@ -323,7 +323,7 @@ void codegen_backend_init() #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = BLOCK_SIZE; + block_current = 0; block_pos = 0; build_loadstore_routines(&codeblock[block_current]); diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 839f37e..534df5c 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -289,19 +289,19 @@ void codegen_backend_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE); + codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE); #endif if (!codeblock_data) fatal("codeblock_data failed to alloc - %i\n", (BLOCK_SIZE+1) * BLOCK_DATA_SIZE); - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE+1; c++) + for (c = 0; c < BLOCK_SIZE; c++) { codeblock[c].pc = BLOCK_PC_INVALID; codeblock[c].data = &codeblock_data[c * BLOCK_SIZE]; @@ -309,7 +309,7 @@ void codegen_backend_init() #if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock_data & pagemask); - len = (((BLOCK_SIZE+1) * BLOCK_DATA_SIZE) + pagesize) & pagemask; + len = ((BLOCK_SIZE * BLOCK_DATA_SIZE) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); @@ -318,7 +318,7 @@ void codegen_backend_init() #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = BLOCK_SIZE; + block_current = 0; block_pos = 0; codegen_reset_literal_pool(&codeblock[block_current]); build_loadstore_routines(&codeblock[block_current]); diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index c509c04..631402a 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -276,17 +276,17 @@ void codegen_backend_init() #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE); + codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE); #endif - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE+1; c++) + for (c = 0; c < BLOCK_SIZE; c++) { codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; @@ -294,7 +294,7 @@ void codegen_backend_init() #if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock & pagemask); - len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask; + len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); @@ -303,7 +303,7 @@ void codegen_backend_init() #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = BLOCK_SIZE; + block_current = 0; block_pos = 0; build_loadstore_routines(&codeblock[block_current]); // fatal("Here\n"); diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 0fd6104..4a43ff0 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -270,31 +270,30 @@ pclog(" offsetof(codeblock_t, status)=%i\n", offsetof(codeblock_t, status)); pclog(" offsetof(codeblock_t, flags)=%i\n", offsetof(codeblock_t, flags)); pclog(" offsetof(codeblock_t, ins)=%i\n", offsetof(codeblock_t, ins)); pclog(" offsetof(codeblock_t, TOP)=%i\n", offsetof(codeblock_t, TOP)); -pclog(" offsetof(codeblock_t, endpc)=%i\n", offsetof(codeblock_t, endpc)); +pclog(" offsetof(codeblock_t, parent)=%i\n", offsetof(codeblock_t, parent)); +pclog(" offsetof(codeblock_t, left)=%i\n", offsetof(codeblock_t, left)); +pclog(" offsetof(codeblock_t, right)=%i\n", offsetof(codeblock_t, right)); pclog(" offsetof(codeblock_t, data)=%i\n", offsetof(codeblock_t, data)); -pclog(" offsetof(codeblock_t, page_mask=%i\n", offsetof(codeblock_t, page_mask)); -pclog(" offsetof(codeblock_t, page_mask2=%i\n", offsetof(codeblock_t, page_mask2)); -pclog(" offsetof(codeblock_t, dirty_mask=%i\n", offsetof(codeblock_t, dirty_mask)); -pclog(" offsetof(codeblock_t, dirty_mask2=%i\n", offsetof(codeblock_t, dirty_mask2)); -pclog(" offsetof(codeblock_t, prev=%i\n", offsetof(codeblock_t, prev)); -pclog(" offsetof(codeblock_t, next=%i\n", offsetof(codeblock_t, next)); -pclog(" offsetof(codeblock_t, prev_2=%i\n", offsetof(codeblock_t, prev_2)); -pclog(" offsetof(codeblock_t, next_2=%i\n", offsetof(codeblock_t, next_2)); -pclog(" offsetof(codeblock_t, parent=%i\n", offsetof(codeblock_t, parent)); -pclog(" offsetof(codeblock_t, left=%i\n", offsetof(codeblock_t, left)); -pclog(" offsetof(codeblock_t, right=%i\n", offsetof(codeblock_t, right)); - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); +pclog(" offsetof(codeblock_t, page_mask)=%i\n", offsetof(codeblock_t, page_mask)); +pclog(" offsetof(codeblock_t, page_mask2)=%i\n", offsetof(codeblock_t, page_mask2)); +pclog(" offsetof(codeblock_t, dirty_mask)=%i\n", offsetof(codeblock_t, dirty_mask)); +pclog(" offsetof(codeblock_t, dirty_mask2)=%i\n", offsetof(codeblock_t, dirty_mask2)); +pclog(" offsetof(codeblock_t, prev)=%i\n", offsetof(codeblock_t, prev)); +pclog(" offsetof(codeblock_t, next)=%i\n", offsetof(codeblock_t, next)); +pclog(" offsetof(codeblock_t, prev_2)=%i\n", offsetof(codeblock_t, prev_2)); +pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); #if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock_data = malloc((BLOCK_SIZE+1) * BLOCK_DATA_SIZE; + codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE; #endif codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE + 1; c++) + for (c = 0; c < BLOCK_SIZE; c++) { codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; @@ -302,7 +301,7 @@ pclog(" offsetof(codeblock_t, right=%i\n", offsetof(codeblock_t, right)); #if defined(__linux__) || defined(__APPLE__) start = (void *)((long)codeblock_data & pagemask); - len = (((BLOCK_SIZE+1) * BLOCK_DATA_SIZE) + pagesize) & pagemask; + len = ((BLOCK_SIZE * BLOCK_DATA_SIZE) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); @@ -311,7 +310,7 @@ pclog(" offsetof(codeblock_t, right=%i\n", offsetof(codeblock_t, right)); #endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = BLOCK_SIZE; + block_current = 0; block_pos = 0; mem_abrt_rout = &codeblock[block_current].data[block_pos]; addbyte(0x83); /*ADDL $16+4,%esp*/ diff --git a/src/mem.c b/src/mem.c index 6fa3a69..ad095a3 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1499,8 +1499,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[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; + pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = BLOCK_INVALID; + pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = BLOCK_INVALID; } } diff --git a/src/mem.h b/src/mem.h index 2aabde9..a015acc 100644 --- a/src/mem.h +++ b/src/mem.h @@ -119,10 +119,10 @@ typedef struct page_t uint8_t *mem; - struct codeblock_t *block[4], *block_2[4]; + uint16_t block[4], block_2[4]; /*Head of codeblock tree associated with this page*/ - struct codeblock_t *head; + uint16_t head; uint64_t code_present_mask[4], dirty_mask[4]; } page_t; From 43b5b836448eadff7283c6a0bd1da9fcfdc02429 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 30 Nov 2018 13:18:56 +0000 Subject: [PATCH 0556/1050] Reduce codeblock_hash table to uint16_t. --- src/386_dynarec.c | 6 ++++-- src/codegen.c | 2 +- src/codegen.h | 2 +- src/codegen_backend.c | 8 ++++---- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 8954538..1238cc0 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -602,7 +602,7 @@ void exec386_dynarec(int cycs) { uint32_t phys_addr = get_phys(cs+cpu_state.pc); int hash = HASH(phys_addr); - codeblock_t *block = codeblock_hash[hash]; + codeblock_t *block = &codeblock[codeblock_hash[hash]]; int valid_block = 0; trap = 0; @@ -630,7 +630,10 @@ void exec386_dynarec(int cycs) (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); if (valid_block) + { block = new_block; + codeblock_hash[hash] = get_block_nr(block); + } } } } @@ -675,7 +678,6 @@ 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; diff --git a/src/codegen.c b/src/codegen.c index ba9c06a..7a74756 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -14,7 +14,7 @@ int has_ea; codeblock_t *codeblock; -codeblock_t **codeblock_hash; +uint16_t *codeblock_hash; void (*codegen_timing_start)(); void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); diff --git a/src/codegen.h b/src/codegen.h index 72a3820..93657a1 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -65,7 +65,7 @@ uint8_t *codeblock_data; extern codeblock_t *codeblock; -extern codeblock_t **codeblock_hash; +extern uint16_t *codeblock_hash; /*Code block uses FPU*/ #define CODEBLOCK_HAS_FPU 1 diff --git a/src/codegen_backend.c b/src/codegen_backend.c index de292e3..500230d 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -92,7 +92,7 @@ void codegen_reset() int c; memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); mem_reset_page_blocks(); for (c = 0; c < BLOCK_SIZE; c++) @@ -211,8 +211,8 @@ static void delete_block(codeblock_t *block) { uint32_t old_pc = block->pc; - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; if (block->pc == BLOCK_PC_INVALID) fatal("Deleting deleted block\n"); @@ -279,7 +279,7 @@ void codegen_block_init(uint32_t phys_addr) cpu_recomp_reuse++; } block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; + codeblock_hash[block_num] = block_current; block->ins = 0; block->pc = cs + cpu_state.pc; From d5f07a8594402e0b883d08326e2aa9101707f81c Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 30 Nov 2018 13:19:16 +0000 Subject: [PATCH 0557/1050] Fix bad use of flags variable in wx-sdl2-display.c. --- src/wx-sdl2-display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index 18bbc9e..0de48c5 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -639,6 +639,8 @@ int render() if (win_doresize) { + int flags = SDL_GetWindowFlags(window); + win_doresize = 0; if (!vid_resize || (flags&SDL_WINDOW_FULLSCREEN)) { SDL_GetWindowSize(window, &rect.w, &rect.h); From 99ca11d148793c3b13f8be51a80d75e4f12ca836 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 2 Dec 2018 12:38:31 +0000 Subject: [PATCH 0558/1050] Added initial emulation of FIC VA-503+ (Super 7). This includes preliminary emulation of the VIA MVP3 northbridge, VT82C586B 'PIPC' southbridge, and Winbond W83877TF SuperIO chip. --- src/ibm.h | 1 + src/mem_bios.c | 8 ++ src/model.c | 18 +++ src/mvp3.c | 219 ++++++++++++++++++++++++++++++++++ src/mvp3.h | 1 + src/nvr.c | 6 +- src/vt82c586b.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vt82c586b.h | 1 + src/w83877tf.c | 202 +++++++++++++++++++++++++++++++ src/w83877tf.h | 1 + 10 files changed, 765 insertions(+), 2 deletions(-) create mode 100644 src/mvp3.c create mode 100644 src/mvp3.h create mode 100644 src/vt82c586b.c create mode 100644 src/vt82c586b.h create mode 100644 src/w83877tf.c create mode 100644 src/w83877tf.h diff --git a/src/ibm.h b/src/ibm.h index 2221e8c..fb7865c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -465,6 +465,7 @@ enum ROM_XI8088, ROM_IBMPS2_M70_TYPE3, ROM_IBMPS2_M70_TYPE4, + ROM_FIC_VA503P, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index dc5a904..c4229c5 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -900,6 +900,14 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_FIC_VA503P: + f = romfopen("fic_va503p/je4333.bin","rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 55be58b..5fe572d 100644 --- a/src/model.c +++ b/src/model.c @@ -34,6 +34,7 @@ #include "lpt.h" #include "mem.h" #include "mouse_ps2.h" +#include "mvp3.h" #include "neat.h" #include "nmi.h" #include "nvr.h" @@ -61,6 +62,8 @@ #include "vid_pcjr.h" #include "vid_tandy.h" #include "vid_t1000.h" +#include "vt82c586b.h" +#include "w83877tf.h" #include "wd76c10.h" #include "xi8088.h" @@ -106,6 +109,7 @@ void at_pb520r_init(); void at_pb570_init(); void compaq_pip_init(); void xt_xi8088_init(); +void at_mvp3_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -189,6 +193,8 @@ MODEL models[] = {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, + {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; @@ -659,6 +665,18 @@ void at_i430vx_init() device_add(&intel_flash_bxt_device); } +void at_mvp3_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(8); + pci_slot(9); + pci_slot(10); + mvp3_init(); + vt82c586b_init(7, 8, 9, 10, 0); + w83877tf_init(); +} + void model_init() { pclog("Initting as %s\n", model_getname()); diff --git a/src/mvp3.c b/src/mvp3.c new file mode 100644 index 0000000..2760d99 --- /dev/null +++ b/src/mvp3.c @@ -0,0 +1,219 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "pci.h" + +#include "mvp3.h" + +static struct +{ + uint8_t host_bridge_regs[256]; + uint8_t pci_bridge_regs[256]; +} mvp3; + +static void mvp3_map(uint32_t addr, uint32_t size, int state) +{ + pclog("mvp3_map: addr=%08x size=%08x state=%i\n", addr, size, state); + switch (state & 3) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +static uint8_t mvp3_read(int func, int addr, void *priv) +{ + switch (func) + { + case 0: + return mvp3.host_bridge_regs[addr]; + + case 1: + return mvp3.pci_bridge_regs[addr]; + + default: + return 0xff; + } +} + + +static void mvp3_host_bridge_write(int addr, uint8_t val) +{ + /*Read-only addresses*/ + if ((addr < 4) || (addr >= 5 && addr < 7) + || (addr >= 8 && addr < 0xd) + || (addr >= 0xe && addr < 0x12) + || (addr >= 0x14 && addr < 0x50) + || (addr >= 0x79 && addr < 0x7e) + || (addr >= 0x85 && addr < 0x88) + || (addr >= 0x8c && addr < 0xa8) + || (addr >= 0xad && addr < 0xfd)) + return; + + switch (addr) + { + case 0x04: /*Command*/ + mvp3.host_bridge_regs[0x04] = (mvp3.host_bridge_regs[0x04] & ~0x40) | (val & 0x40); + break; + case 0x07: /*Status*/ + mvp3.host_bridge_regs[0x07] &= ~(val & 0xb0); + break; + + case 0x12: /*Graphics Aperture Base*/ + mvp3.host_bridge_regs[0x12] = (val & 0xf0); + break; + case 0x13: /*Graphics Aperture Base*/ + mvp3.host_bridge_regs[0x13] = val; + break; + + case 0x61: /*Shadow RAM Control 1*/ + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x03) + mvp3_map(0xc0000, 0x04000, val & 0x03); + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x0c) + mvp3_map(0xc4000, 0x04000, (val & 0x0c) >> 2); + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x30) + mvp3_map(0xc8000, 0x04000, (val & 0x30) >> 4); + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0xc0) + mvp3_map(0xcc000, 0x04000, (val & 0xc0) >> 6); + mvp3.host_bridge_regs[0x61] = val; + return; + case 0x62: /*Shadow RAM Control 2*/ + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x03) + mvp3_map(0xd0000, 0x04000, val & 0x03); + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x0c) + mvp3_map(0xd4000, 0x04000, (val & 0x0c) >> 2); + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x30) + mvp3_map(0xd8000, 0x04000, (val & 0x30) >> 4); + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0xc0) + mvp3_map(0xdc000, 0x04000, (val & 0xc0) >> 6); + mvp3.host_bridge_regs[0x62] = val; + return; + case 0x63: /*Shadow RAM Control 3*/ + if ((mvp3.host_bridge_regs[0x63] ^ val) & 0x30) + mvp3_map(0xf0000, 0x10000, (val & 0x30) >> 4); + if ((mvp3.host_bridge_regs[0x63] ^ val) & 0xc0) + mvp3_map(0xe0000, 0x10000, (val & 0xc0) >> 6); + mvp3.host_bridge_regs[0x63] = val; +// if (val == 0xb0) +// output = 3; + return; + + default: + mvp3.host_bridge_regs[addr] = val; + break; + } +} +static void mvp3_pci_bridge_write(int addr, uint8_t val) +{ + /*Read-only addresses*/ + if ((addr < 4) || (addr >= 5 && addr < 7) + || (addr >= 8 && addr < 0x18) + || (addr == 0x1b) + || (addr >= 0x1e && addr < 0x20) + || (addr >= 0x28 && addr < 0x3e) + || (addr >= 0x43)) + return; + + switch (addr) + { + case 0x04: /*Command*/ + mvp3.pci_bridge_regs[0x04] = (mvp3.pci_bridge_regs[0x04] & ~0x47) | (val & 0x47); + break; + case 0x07: /*Status*/ + mvp3.pci_bridge_regs[0x07] &= ~(val & 0x30); + break; + + case 0x20: /*Memory Base*/ + mvp3.pci_bridge_regs[0x20] = val & 0xf0; + break; + case 0x22: /*Memory Limit*/ + mvp3.pci_bridge_regs[0x22] = val & 0xf0; + break; + case 0x24: /*Prefetchable Memory Base*/ + mvp3.pci_bridge_regs[0x24] = val & 0xf0; + break; + case 0x26: /*Prefetchable Memory Limit*/ + mvp3.pci_bridge_regs[0x26] = val & 0xf0; + break; + + default: + mvp3.pci_bridge_regs[addr] = val; + break; + } +} + +static void mvp3_write(int func, int addr, uint8_t val, void *priv) +{ + switch (func) + { + case 0: + mvp3_host_bridge_write(addr, val); + break; + + case 1: + mvp3_pci_bridge_write(addr, val); + break; + } +} + +void mvp3_init() +{ + pci_add_specific(0, mvp3_read, mvp3_write, NULL); + + memset(&mvp3, 0, sizeof(mvp3)); + mvp3.host_bridge_regs[0x00] = 0x06; mvp3.host_bridge_regs[0x01] = 0x11; /*VIA*/ + mvp3.host_bridge_regs[0x02] = 0x98; mvp3.host_bridge_regs[0x03] = 0x05; /*VT82C598MVP*/ + mvp3.host_bridge_regs[0x04] = 0x06; mvp3.host_bridge_regs[0x05] = 0x00; + mvp3.host_bridge_regs[0x06] = 0x90; mvp3.host_bridge_regs[0x07] = 0x02; + mvp3.host_bridge_regs[0x0b] = 0x06; + mvp3.host_bridge_regs[0x10] = 0x08; + mvp3.host_bridge_regs[0x34] = 0xa0; + + mvp3.host_bridge_regs[0x5a] = 0x01; + mvp3.host_bridge_regs[0x5b] = 0x01; + mvp3.host_bridge_regs[0x5c] = 0x01; + mvp3.host_bridge_regs[0x5d] = 0x01; + mvp3.host_bridge_regs[0x5e] = 0x01; + mvp3.host_bridge_regs[0x5f] = 0x01; + + mvp3.host_bridge_regs[0x64] = 0xec; + mvp3.host_bridge_regs[0x65] = 0xec; + mvp3.host_bridge_regs[0x66] = 0xec; + mvp3.host_bridge_regs[0x6b] = 0x01; + + mvp3.host_bridge_regs[0xa0] = 0x02; + mvp3.host_bridge_regs[0xa2] = 0x10; + mvp3.host_bridge_regs[0xa4] = 0x03; + mvp3.host_bridge_regs[0xa5] = 0x02; + mvp3.host_bridge_regs[0xa6] = 0x00; + mvp3.host_bridge_regs[0xa7] = 0x07; + + mvp3.pci_bridge_regs[0x00] = 0x06; mvp3.pci_bridge_regs[0x01] = 0x11; /*VIA*/ + mvp3.pci_bridge_regs[0x02] = 0x98; mvp3.pci_bridge_regs[0x03] = 0x85; /*VT82C598MVP*/ + mvp3.pci_bridge_regs[0x04] = 0x07; mvp3.pci_bridge_regs[0x05] = 0x00; + mvp3.pci_bridge_regs[0x06] = 0x20; mvp3.pci_bridge_regs[0x07] = 0x02; + mvp3.pci_bridge_regs[0x0a] = 0x04; + mvp3.pci_bridge_regs[0x0b] = 0x06; + mvp3.pci_bridge_regs[0x0e] = 0x01; + + mvp3.pci_bridge_regs[0x1c] = 0xf0; + + mvp3.pci_bridge_regs[0x20] = 0xf0; + mvp3.pci_bridge_regs[0x21] = 0xff; + + mvp3.pci_bridge_regs[0x24] = 0xf0; + mvp3.pci_bridge_regs[0x25] = 0xff; +} diff --git a/src/mvp3.h b/src/mvp3.h new file mode 100644 index 0000000..69dac83 --- /dev/null +++ b/src/mvp3.h @@ -0,0 +1 @@ +void mvp3_init(); diff --git a/src/nvr.c b/src/nvr.c index fa8c1f4..edabac9 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -306,7 +306,8 @@ void loadnvr() case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break; case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break; - + case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break; + default: return; } if (!f) @@ -396,7 +397,8 @@ void savenvr() case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); break; case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break; case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break; - + case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break; + default: return; } fwrite(nvrram,128,1,f); diff --git a/src/vt82c586b.c b/src/vt82c586b.c new file mode 100644 index 0000000..fd67002 --- /dev/null +++ b/src/vt82c586b.c @@ -0,0 +1,310 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "pci.h" +#include "x86.h" + +#include "vt82c586b.h" + +static struct +{ + uint8_t pci_isa_bridge_regs[256]; + uint8_t ide_regs[256]; + uint8_t usb_regs[256]; + uint8_t power_regs[256]; + + uint8_t sysctrl; +} vt82c586b; + +static uint8_t vt82c586b_read(int func, int addr, void *priv) +{ + switch (func) + { + case 0: + return vt82c586b.pci_isa_bridge_regs[addr]; + + case 1: + return vt82c586b.ide_regs[addr]; + + case 2: + return vt82c586b.usb_regs[addr]; + + case 3: + return vt82c586b.power_regs[addr]; + + default: + return 0xff; + } +} + +static void vt82c586b_pci_isa_bridge_write(int addr, uint8_t val) +{ + /*Read-only addresses*/ + if ((addr < 4) || (addr == 5) || (addr == 6) + || (addr >= 8 && addr < 0x40) + || (addr == 0x49) + || (addr == 0x4b) + || (addr >= 0x51 && addr < 0x54) + || (addr >= 0x5d && addr < 0x60) + || (addr >= 0x68 && addr < 0x6a) + || (addr >= 0x71)) + return; + + switch (addr) + { + case 4: + vt82c586b.pci_isa_bridge_regs[4] = (val & 8) | 7; + break; + case 6: + vt82c586b.pci_isa_bridge_regs[6] &= ~(val & 0xb0); + break; + + case 0x47: + if ((val & 0x81) == 0x81) + resetx86(); + vt82c586b.pci_isa_bridge_regs[0x47] = val & 0xfe; + break; + + case 0x55: + if (!(val & 0xf0)) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val >> 4); + vt82c586b.pci_isa_bridge_regs[0x55] = val; + break; + case 0x56: + if (!(val & 0xf0)) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val >> 4); + if (!(val & 0x0f)) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + vt82c586b.pci_isa_bridge_regs[0x56] = val; + break; + case 0x57: + if (!(val & 0xf0)) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val >> 4); + vt82c586b.pci_isa_bridge_regs[0x57] = val; + break; + + default: + vt82c586b.pci_isa_bridge_regs[addr] = val; + break; + } +} +static void vt82c586b_ide_write(int addr, uint8_t val) +{ + /*Read-only addresses*/ + if ((addr < 6) || (addr == 8) + || (addr >= 0xa && addr < 0x0d) + || (addr >= 0x0e && addr < 0x20) + || (addr >= 0x22 && addr < 0x3c) + || (addr >= 0x3d && addr < 0x40) + || (addr >= 0x54 && addr < 0x60) + || (addr >= 0x52 && addr < 0x68) + || (addr >= 0x62)) + return; + + switch (addr) + { + case 4: + vt82c586b.ide_regs[4] = (val & 8) | 7; + break; + case 6: + vt82c586b.ide_regs[6] &= ~(val & 0xb0); + break; + + case 9: + vt82c586b.ide_regs[9] = (vt82c586b.pci_isa_bridge_regs[9] & ~0x70) | 0x8a; + break; + + case 0x20: + vt82c586b.ide_regs[0x20] = (val & ~0xf) | 1; + break; + + default: + vt82c586b.ide_regs[addr] = val; + break; + } +} +static void vt82c586b_usb_write(int addr, uint8_t val) +{ + /*Read-only addresses*/ + if ((addr < 7) || (addr >= 8 && addr < 0xd) + || (addr >= 0xe && addr < 0x20) + || (addr >= 0x22 && addr < 0x3c) + || (addr >= 0x3e && addr < 0x40) + || (addr >= 0x42 && addr < 0x44) + || (addr >= 0x46 && addr < 0xc0) + || (addr >= 0xc2)) + return; + + switch (addr) + { + case 7: + vt82c586b.usb_regs[7] = val & 0x7f; + break; + + case 0x20: + vt82c586b.usb_regs[0x20] = (val & ~0x1f) | 1; + break; + + default: + vt82c586b.usb_regs[addr] = val; + break; + } +} +static void vt82c586b_power_write(int addr, uint8_t val) +{ + /*Read-only addresses*/ + if ((addr < 0xd) || (addr >= 0xe && addr < 0x40) + || (addr == 0x43) + || (addr == 0x48) + || (addr >= 0x4a && addr < 0x50) + || (addr >= 0x54)) + return; + + switch (addr) + { + default: + vt82c586b.power_regs[addr] = val; + break; + } +} + +static void vt82c586b_write(int func, int addr, uint8_t val, void *priv) +{ + switch (func) + { + case 0: + vt82c586b_pci_isa_bridge_write(addr, val); + break; + + case 1: + vt82c586b_ide_write(addr, val); + break; + + case 2: + vt82c586b_usb_write(addr, val); + break; + + case 3: + vt82c586b_power_write(addr, val); + break; + } +} + +uint8_t vt82c586b_read_sysctrl(uint16_t port, void *p) +{ + return vt82c586b.sysctrl; +} + +void vt82c586b_write_sysctrl(uint16_t port, uint8_t val, void *p) +{ + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~vt82c586b.sysctrl & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + vt82c586b.sysctrl = val; +} + +void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) +{ + pci_add_specific(card, vt82c586b_read, vt82c586b_write, NULL); + io_sethandler(0x0092, 0x0001, vt82c586b_read_sysctrl, NULL, NULL, vt82c586b_write_sysctrl, NULL, NULL, NULL); + + memset(&vt82c586b, 0, sizeof(vt82c586b)); + vt82c586b.pci_isa_bridge_regs[0x00] = 0x06; vt82c586b.pci_isa_bridge_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.pci_isa_bridge_regs[0x02] = 0x86; vt82c586b.pci_isa_bridge_regs[0x03] = 0x05; /*VT82C586B*/ + vt82c586b.pci_isa_bridge_regs[0x04] = 0x0f; vt82c586b.pci_isa_bridge_regs[0x05] = 0x00; + vt82c586b.pci_isa_bridge_regs[0x06] = 0x00; vt82c586b.pci_isa_bridge_regs[0x07] = 0x02; + vt82c586b.pci_isa_bridge_regs[0x0a] = 0x01; + vt82c586b.pci_isa_bridge_regs[0x0b] = 0x06; + vt82c586b.pci_isa_bridge_regs[0x0e] = 0x80; + + /*ISA bus control*/ + vt82c586b.pci_isa_bridge_regs[0x48] = 0x01; + vt82c586b.pci_isa_bridge_regs[0x4a] = 0x04; + vt82c586b.pci_isa_bridge_regs[0x4f] = 0x03; + + /*Plug and Play control*/ + vt82c586b.pci_isa_bridge_regs[0x50] = 0x24; + vt82c586b.pci_isa_bridge_regs[0x59] = 0x04; + + vt82c586b.ide_regs[0x00] = 0x06; vt82c586b.ide_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.ide_regs[0x02] = 0x71; vt82c586b.ide_regs[0x03] = 0x05; + vt82c586b.ide_regs[0x04] = 0x80; vt82c586b.ide_regs[0x05] = 0x00; + vt82c586b.ide_regs[0x06] = 0x80; vt82c586b.ide_regs[0x07] = 0x02; + vt82c586b.ide_regs[0x09] = 0x85; + vt82c586b.ide_regs[0x0a] = 0x01; + vt82c586b.ide_regs[0x0b] = 0x01; + + vt82c586b.ide_regs[0x10] = 0xf1; vt82c586b.ide_regs[0x11] = 0x01; + vt82c586b.ide_regs[0x14] = 0xf5; vt82c586b.ide_regs[0x15] = 0x03; + vt82c586b.ide_regs[0x18] = 0x71; vt82c586b.ide_regs[0x19] = 0x01; + vt82c586b.ide_regs[0x1c] = 0x75; vt82c586b.ide_regs[0x1d] = 0x03; + vt82c586b.ide_regs[0x20] = 0x01; vt82c586b.ide_regs[0x21] = 0xcc; + vt82c586b.ide_regs[0x3c] = 0x0e; + + vt82c586b.ide_regs[0x40] = 0x08; + vt82c586b.ide_regs[0x41] = 0x02; + vt82c586b.ide_regs[0x42] = 0x09; + vt82c586b.ide_regs[0x43] = 0x3a; + vt82c586b.ide_regs[0x44] = 0x68; + vt82c586b.ide_regs[0x46] = 0xc0; + vt82c586b.ide_regs[0x48] = 0xa8; + vt82c586b.ide_regs[0x49] = 0xa8; + vt82c586b.ide_regs[0x4a] = 0xa8; + vt82c586b.ide_regs[0x4b] = 0xa8; + vt82c586b.ide_regs[0x4c] = 0xff; + vt82c586b.ide_regs[0x4e] = 0xff; + vt82c586b.ide_regs[0x4f] = 0xff; + vt82c586b.ide_regs[0x50] = 0x03; + vt82c586b.ide_regs[0x51] = 0x03; + vt82c586b.ide_regs[0x52] = 0x03; + vt82c586b.ide_regs[0x53] = 0x03; + vt82c586b.ide_regs[0x61] = 0x02; + vt82c586b.ide_regs[0x68] = 0x02; + + vt82c586b.usb_regs[0x00] = 0x06; vt82c586b.usb_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.usb_regs[0x02] = 0x38; vt82c586b.usb_regs[0x03] = 0x30; + vt82c586b.usb_regs[0x04] = 0x00; vt82c586b.usb_regs[0x05] = 0x00; + vt82c586b.usb_regs[0x06] = 0x00; vt82c586b.usb_regs[0x07] = 0x02; + vt82c586b.usb_regs[0x0a] = 0x03; + vt82c586b.usb_regs[0x0b] = 0x0c; + vt82c586b.usb_regs[0x0d] = 0x16; + vt82c586b.usb_regs[0x20] = 0x01; + vt82c586b.usb_regs[0x21] = 0x03; + vt82c586b.usb_regs[0x3d] = 0x04; + + vt82c586b.usb_regs[0x60] = 0x10; + vt82c586b.usb_regs[0xc1] = 0x20; + + vt82c586b.power_regs[0x00] = 0x06; vt82c586b.power_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.power_regs[0x02] = 0x40; vt82c586b.power_regs[0x03] = 0x30; + vt82c586b.power_regs[0x04] = 0x00; vt82c586b.power_regs[0x05] = 0x00; + vt82c586b.power_regs[0x06] = 0x80; vt82c586b.power_regs[0x07] = 0x02; + vt82c586b.power_regs[0x08] = 0x10; /*Production version (3041)*/ + vt82c586b.power_regs[0x48] = 0x01; + + 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/vt82c586b.h b/src/vt82c586b.h new file mode 100644 index 0000000..0f6981f --- /dev/null +++ b/src/vt82c586b.h @@ -0,0 +1 @@ +void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); diff --git a/src/w83877tf.c b/src/w83877tf.c new file mode 100644 index 0000000..78c2a63 --- /dev/null +++ b/src/w83877tf.c @@ -0,0 +1,202 @@ +#include "ibm.h" + +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "w83877tf.h" + +typedef struct w83877tf_t +{ + int enable_regs; + uint8_t key[2]; + int index; + uint8_t regs[256]; +} w83877tf_t; + +static w83877tf_t w83877tf_global; + +static void w83877tf_write_25x(uint16_t port, uint8_t val, void *p); +static uint8_t w83877tf_read_25x(uint16_t port, void *p); +static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p); +static uint8_t w83877tf_read_3fx(uint16_t port, void *p); + +static void w83877tf_write_reg(w83877tf_t *w83877tf, int index, uint8_t val) +{ +// pclog("w83877tf_write: index=%02x val=%02x\n", index, val); + switch (index) + { + case 0x16: + if (val == 2) /*Written by VA-503+ BIOS. Apparently should not change IO mapping*/ + return; + + io_removehandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + io_removehandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); + if (val & 0x01) + io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); + else + io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + + if ((w83877tf->regs[0x16] & 4) && !(val & 4)) + { + w83877tf->regs[0x20] = 0; + w83877tf->regs[0x23] = 0; + w83877tf->regs[0x24] = 0; + w83877tf->regs[0x25] = 0; + w83877tf->regs[0x26] = 0; + w83877tf->regs[0x27] = 0; + w83877tf->regs[0x28] = 0; + w83877tf->regs[0x29] = 0; + } + break; + } + + w83877tf->regs[index] = val; + + + fdc_remove(); + if (w83877tf->regs[0x20] >= 0x40) + fdc_add(); + + lpt1_remove(); + lpt2_remove(); + if (w83877tf->regs[0x23] >= 0x40) + lpt1_init(w83877tf->regs[0x23] << 2); + + serial1_remove(); + if (w83877tf->regs[0x24] >= 0x40) + serial1_set((w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4); + + serial2_remove(); + if (w83877tf->regs[0x25] >= 0x40) + serial2_set((w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf); + +// pclog("LPT at %04x\n", w83877tf->regs[0x23] << 2); +// pclog("Serial1 at %04x %i\n", (w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4); +// pclog("Serial2 at %04x %i\n", (w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf); +} + +static uint8_t w83877tf_read_reg(w83877tf_t *w83877tf, int index) +{ + switch (w83877tf->index) + { + case 0x09: + return 0x0c; /*W83877TF ID*/ + } + return w83877tf->regs[index]; +} + +static void w83877tf_write_25x(uint16_t port, uint8_t val, void *p) +{ + w83877tf_t *w83877tf = (w83877tf_t *)p; + +// pclog("w83877tf_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0x250: /*Enable register*/ + w83877tf->enable_regs = (val == 0x89) ? 1 : 0; + break; + case 0x251: /*Index*/ + if (w83877tf->enable_regs) + w83877tf->index = val; + break; + case 0x252: /*Data*/ + if (w83877tf->enable_regs) + w83877tf_write_reg(w83877tf, w83877tf->index, val); + break; + } +} + +static uint8_t w83877tf_read_25x(uint16_t port, void *p) +{ + w83877tf_t *w83877tf = (w83877tf_t *)p; + + switch (port) + { + case 0x251: /*Index*/ + if (w83877tf->enable_regs) + return w83877tf->index; + break; + + case 0x252: /*Data*/ + if (w83877tf->enable_regs) + return w83877tf_read_reg(w83877tf, w83877tf->index); + break; + } + + return 0xff; +} + +static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p) +{ + w83877tf_t *w83877tf = (w83877tf_t *)p; + +// pclog("w83877tf_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0x3f0: /*Enable/index register*/ + if (val == 0xaa) + w83877tf->enable_regs = 0; + else if (!w83877tf->enable_regs) + { + w83877tf->key[1] = w83877tf->key[0]; + w83877tf->key[0] = val; + w83877tf->enable_regs = (w83877tf->key[0] == 0x87 && w83877tf->key[1] == 0x87); + } + else + w83877tf->index = val; + break; + case 0x3f1: /*Data*/ + if (w83877tf->enable_regs) + w83877tf_write_reg(w83877tf, w83877tf->index, val); + break; + } +} + +static uint8_t w83877tf_read_3fx(uint16_t port, void *p) +{ + w83877tf_t *w83877tf = (w83877tf_t *)p; + uint8_t ret = 0xff; + + switch (port) + { + case 0x3f0: /*Index*/ + if (w83877tf->enable_regs) + ret = w83877tf->index; + break; + + case 0x3f1: /*Data*/ + if (w83877tf->enable_regs) + ret = w83877tf_read_reg(w83877tf, w83877tf->index); + break; + } + +// pclog("w83877tf_read: port=%04x val=%02x\n", port, ret); + + return ret; +} + +void w83877tf_init() +{ + memset(&w83877tf_global, 0, sizeof(w83877tf_t)); + + io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + + /*Defaults*/ + w83877tf_global.regs[0x03] = 0x30; + w83877tf_global.regs[0x09] = 0x0c; + w83877tf_global.regs[0x0b] = 0x0c; + w83877tf_global.regs[0x0c] = 0x28; + w83877tf_global.regs[0x0d] = 0xa3; + w83877tf_global.regs[0x16] = 0x04; + w83877tf_global.regs[0x20] = 0xfc; + w83877tf_global.regs[0x23] = 0xde; + w83877tf_global.regs[0x24] = 0xfe; + w83877tf_global.regs[0x25] = 0xbe; + w83877tf_global.regs[0x26] = 0x23; + w83877tf_global.regs[0x27] = 0x05; + w83877tf_global.regs[0x28] = 0x43; + w83877tf_global.regs[0x29] = 0x60; +} diff --git a/src/w83877tf.h b/src/w83877tf.h new file mode 100644 index 0000000..dcfb853 --- /dev/null +++ b/src/w83877tf.h @@ -0,0 +1 @@ +void w83877tf_init(); From 5043cff3f9527b8af4946b6ad3960c465f048ff9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 2 Dec 2018 15:46:28 +0000 Subject: [PATCH 0559/1050] Move SFF-8038i IDE bus mastering code out of PIIX files. Add bus mastering to VT82C586B emulation. --- src/ide.c | 16 ++-- src/ide.h | 9 +- src/ide_atapi.c | 8 +- src/ide_sff8038i.c | 208 +++++++++++++++++++++++++++++++++++++++++++ src/ide_sff8038i.h | 13 +++ src/model.c | 2 +- src/piix.c | 213 ++------------------------------------------- src/vt82c586b.c | 39 ++++++++- 8 files changed, 282 insertions(+), 226 deletions(-) create mode 100644 src/ide_sff8038i.c create mode 100644 src/ide_sff8038i.h diff --git a/src/ide.c b/src/ide.c index 44e74a7..0cbad14 100644 --- a/src/ide.c +++ b/src/ide.c @@ -94,9 +94,10 @@ IDE *ext_ide; char ide_fn[7][512]; -int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size); -int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size); -void (*ide_bus_master_set_irq)(int channel); +int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size, void *p); +int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size, void *p); +void (*ide_bus_master_set_irq)(int channel, void *p); +void *ide_bus_master_p; pc_timer_t ide_timer[2]; @@ -111,7 +112,7 @@ void ide_irq_raise(IDE *ide) // if (ide->board && !ide->irqstat) pclog("IDE_IRQ_RAISE\n"); picint((ide->board)?(1<<15):(1<<14)); if (ide_bus_master_set_irq) - ide_bus_master_set_irq(ide->board); + ide_bus_master_set_irq(ide->board, ide_bus_master_p); } ide->irqstat=1; ide->service=1; @@ -905,7 +906,7 @@ void callbackide(int ide_board) if (ide_bus_master_read_data) { - if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512)) + if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512, ide_bus_master_p)) timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); /*DMA not performed, try again later*/ else { @@ -983,7 +984,7 @@ void callbackide(int ide_board) if (ide_bus_master_write_data) { - if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512)) + if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512, ide_bus_master_p)) timer_set_delay_u64(&ide_timer[ide_board], 6*IDE_TIME); /*DMA not performed, try again later*/ else { @@ -1270,11 +1271,12 @@ static void ide_close(void *p) { } -void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size), int (*write_data)(int channel, uint8_t *data, int size), void (*set_irq)(int channel)) +void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), int (*write_data)(int channel, uint8_t *data, int size, void *p), void (*set_irq)(int channel, void *p), void *p) { ide_bus_master_read_data = read_data; ide_bus_master_write_data = write_data; ide_bus_master_set_irq = set_irq; + ide_bus_master_p = p; } device_t ide_device = diff --git a/src/ide.h b/src/ide.h index aed1200..0c2ce0b 100644 --- a/src/ide.h +++ b/src/ide.h @@ -16,12 +16,13 @@ extern void ide_pri_enable(); extern void ide_sec_enable(); extern void ide_pri_disable(); extern void ide_sec_disable(); -extern void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size), int (*write_data)(int channel, uint8_t *data, int size), void (*set_irq)(int channel)); +extern void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), int (*write_data)(int channel, uint8_t *data, int size, void *p), void (*set_irq)(int channel, void *p), void *p); void ide_irq_raise(struct IDE *ide); -extern int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size); -extern int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size); -extern void (*ide_bus_master_set_irq)(int channel); +extern int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size, void *p); +extern int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size, void *p); +extern void (*ide_bus_master_set_irq)(int channel, void *p); +extern void *ide_bus_master_p; #include "ide_atapi.h" diff --git a/src/ide_atapi.c b/src/ide_atapi.c index ab4330e..78a648b 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -258,7 +258,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { if (ide_bus_master_write_data) { - if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos)) + if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos, ide_bus_master_p)) { atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); @@ -430,7 +430,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) { if (ide_bus_master_read_data) { - if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos)) + if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos, ide_bus_master_p)) { atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); @@ -535,7 +535,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) case ATAPI_STATE_RETRY_READ_DMA: { - if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos)) + if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos, ide_bus_master_p)) { timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } @@ -549,7 +549,7 @@ void atapi_process_packet(atapi_device_t *atapi_dev) case ATAPI_STATE_RETRY_WRITE_DMA: { - if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos)) + if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos, ide_bus_master_p)) { timer_set_delay_u64(&ide_timer[atapi_dev->board], 1*IDE_TIME); } diff --git a/src/ide_sff8038i.c b/src/ide_sff8038i.c new file mode 100644 index 0000000..79eda27 --- /dev/null +++ b/src/ide_sff8038i.c @@ -0,0 +1,208 @@ +/*Emulation of SFF-8038i IDE bus mastering interface. + Used by PIIX and VT82C586B IDE controllers*/ +#include "ibm.h" +#include "ide.h" +#include "ide_sff8038i.h" +#include "mem.h" + +static void sff_bus_master_next_addr(sff_busmaster_t *busmaster, int channel) +{ + busmaster[channel].addr = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur])) & ~1; + busmaster[channel].count = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur + 4])) & 0xfffe; + if (!busmaster[channel].count) + busmaster[channel].count = 0x10000; + busmaster[channel].eot = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur + 4])) >> 31; + 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 sff_bus_master_write(uint16_t port, uint8_t val, void *p) +{ + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + 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: + if ((val & 1) && !(busmaster[channel].command & 1)) /*Start*/ + { + busmaster[channel].ptr_cur = busmaster[channel].ptr; + sff_bus_master_next_addr(busmaster, channel); + busmaster[channel].status |= 1; + } + if (!(val & 1) && (busmaster[channel].command & 1)) /*Stop*/ + busmaster[channel].status &= ~1; + + busmaster[channel].command = val; + break; + case 2: + busmaster[channel].status = (val & 0x60) | ((busmaster[channel].status & ~val) & 6) | (busmaster[channel].status & 1); + break; + case 4: + busmaster[channel].ptr = (busmaster[channel].ptr & 0xffffff00) | val; + break; + case 5: + busmaster[channel].ptr = (busmaster[channel].ptr & 0xffff00ff) | (val << 8); + break; + case 6: + busmaster[channel].ptr = (busmaster[channel].ptr & 0xff00ffff) | (val << 16); + break; + case 7: + busmaster[channel].ptr = (busmaster[channel].ptr & 0x00ffffff) | (val << 24); + break; + } +} + +uint8_t sff_bus_master_read(uint16_t port, void *p) +{ + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int channel = (port & 8) ? 1 : 0; +// pclog("PIIX Bus Master read %04X %04x:%08x\n", port, CS, pc); + switch (port & 7) + { + case 0: + return busmaster[channel].command; + case 2: + return busmaster[channel].status; + case 4: + return busmaster[channel].ptr; + case 5: + return busmaster[channel].ptr >> 8; + case 6: + return busmaster[channel].ptr >> 16; + case 7: + return busmaster[channel].ptr >> 24; + } + return 0xff; +} + +static int sff_bus_master_data_read(int channel, uint8_t *data, int size, void *p) +{ + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int transferred = 0; + + if (!(busmaster[channel].status & 1)) + return 1; /*DMA disabled*/ + + while (transferred < size) + { + if (busmaster[channel].count < (size - transferred) && busmaster[channel].eot) + fatal("DMA on channel %i - Read count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, busmaster[channel].addr, busmaster[channel].count, busmaster[channel].eot, size); + + mem_invalidate_range(busmaster[channel].addr, busmaster[channel].addr+(size-1)); + + if (busmaster[channel].count < (size - transferred)) + { +// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); + if (busmaster[channel].addr < (mem_size * 1024)) + { + int count = busmaster[channel].count; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(&ram[busmaster[channel].addr], data + transferred, count); + } + transferred += busmaster[channel].count; + busmaster[channel].addr += busmaster[channel].count; + busmaster[channel].count = 0; + } + else + { +// pclog("Transferring larger - %i bytes\n", size - transferred); + if (busmaster[channel].addr < (mem_size * 1024)) + { + int count = size - transferred; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(&ram[busmaster[channel].addr], data + transferred, count); + } + busmaster[channel].addr += (size - transferred); + busmaster[channel].count -= (size - transferred); + transferred += (size - 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 (!busmaster[channel].count) + { +// pclog("DMA on channel %i - block over\n", channel); + if (busmaster[channel].eot) /*End of transfer?*/ + { +// pclog("DMA on channel %i - transfer over\n", channel); + busmaster[channel].status &= ~1; + } + else + sff_bus_master_next_addr(busmaster, channel); + } + } + return 0; +} +static int sff_bus_master_data_write(int channel, uint8_t *data, int size, void *p) +{ + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int transferred = 0; + + if (!(busmaster[channel].status & 1)) + return 1; /*DMA disabled*/ + + while (transferred < size) + { + if (busmaster[channel].count < (size - transferred) && busmaster[channel].eot) + fatal("DMA on channel %i - Write count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, busmaster[channel].addr, busmaster[channel].count, busmaster[channel].eot, size); + + if (busmaster[channel].count < (size - transferred)) + { +// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); + if (busmaster[channel].addr < (mem_size * 1024)) + { + int count = busmaster[channel].count; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(data + transferred, &ram[busmaster[channel].addr], count); + } + transferred += busmaster[channel].count; + busmaster[channel].addr += busmaster[channel].count; + busmaster[channel].count = 0; + } + else + { +// pclog("Transferring larger - %i bytes\n", size - transferred); + if (busmaster[channel].addr < (mem_size * 1024)) + { + int count = size - transferred; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(data + transferred, &ram[busmaster[channel].addr], count); + } + busmaster[channel].addr += (size - transferred); + busmaster[channel].count -= (size - transferred); + transferred += (size - 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 (!busmaster[channel].count) + { +// pclog("DMA on channel %i - block over\n", channel); + if (busmaster[channel].eot) /*End of transfer?*/ + { +// pclog("DMA on channel %i - transfer over\n", channel); + busmaster[channel].status &= ~1; + } + else + sff_bus_master_next_addr(busmaster, channel); + } + } + return 0; +} + +static void sff_bus_master_set_irq(int channel, void *p) +{ + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + + busmaster[channel].status |= 4; +} + +void sff_bus_master_init(sff_busmaster_t *busmaster) +{ + ide_set_bus_master(sff_bus_master_data_read, sff_bus_master_data_write, sff_bus_master_set_irq, busmaster); +} diff --git a/src/ide_sff8038i.h b/src/ide_sff8038i.h new file mode 100644 index 0000000..9ade5ad --- /dev/null +++ b/src/ide_sff8038i.h @@ -0,0 +1,13 @@ +typedef struct sff_busmaster_t +{ + uint8_t command; + uint8_t status; + uint32_t ptr, ptr_cur; + int count; + uint32_t addr; + int eot; +} sff_busmaster_t; + +uint8_t sff_bus_master_read(uint16_t port, void *p); +void sff_bus_master_write(uint16_t port, uint8_t val, void *p); +void sff_bus_master_init(sff_busmaster_t *busmaster); diff --git a/src/model.c b/src/model.c index 5fe572d..7d3a540 100644 --- a/src/model.c +++ b/src/model.c @@ -681,7 +681,7 @@ void model_init() { pclog("Initting as %s\n", model_getname()); AMSTRAD = AT = PCI = TANDY = 0; - ide_set_bus_master(NULL, NULL, NULL); + ide_set_bus_master(NULL, NULL, NULL, NULL); models[model].init(); if (models[model].device) diff --git a/src/piix.c b/src/piix.c index d8a2a18..73676cf 100644 --- a/src/piix.c +++ b/src/piix.c @@ -7,6 +7,7 @@ #include "ibm.h" #include "ide.h" +#include "ide_sff8038i.h" #include "io.h" #include "mem.h" #include "pci.h" @@ -14,10 +15,8 @@ #include "piix.h" -uint8_t piix_bus_master_read(uint16_t port, void *priv); -void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); - static uint8_t card_piix[256], card_piix_ide[256]; +static sff_busmaster_t piix_busmaster[2]; void piix_write(int func, int addr, uint8_t val, void *priv) { @@ -62,9 +61,9 @@ 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(0, 0x10000, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, piix_busmaster); 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, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, piix_busmaster); } if (addr == 4 || addr == 0x41 || addr == 0x43) { @@ -140,206 +139,6 @@ uint8_t piix_read(int func, int addr, void *priv) return card_piix[addr]; } -struct -{ - uint8_t command; - uint8_t status; - uint32_t ptr, ptr_cur; - int count; - uint32_t addr; - int eot; -} piix_busmaster[2]; - -static void piix_bus_master_next_addr(int channel) -{ - piix_busmaster[channel].addr = (*(uint32_t *)(&ram[piix_busmaster[channel].ptr_cur])) & ~1; - piix_busmaster[channel].count = (*(uint32_t *)(&ram[piix_busmaster[channel].ptr_cur + 4])) & 0xfffe; - if (!piix_busmaster[channel].count) - piix_busmaster[channel].count = 0x10000; - 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: - if ((val & 1) && !(piix_busmaster[channel].command & 1)) /*Start*/ - { - piix_busmaster[channel].ptr_cur = piix_busmaster[channel].ptr; - piix_bus_master_next_addr(channel); - piix_busmaster[channel].status |= 1; - } - if (!(val & 1) && (piix_busmaster[channel].command & 1)) /*Stop*/ - piix_busmaster[channel].status &= ~1; - - piix_busmaster[channel].command = val; - break; - case 2: - piix_busmaster[channel].status = (val & 0x60) | ((piix_busmaster[channel].status & ~val) & 6) | (piix_busmaster[channel].status & 1); - break; - case 4: - piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffffff00) | val; - break; - case 5: - piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffff00ff) | (val << 8); - break; - case 6: - piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xff00ffff) | (val << 16); - break; - case 7: - piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0x00ffffff) | (val << 24); - break; - } -} - -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: - return piix_busmaster[channel].command; - case 2: - return piix_busmaster[channel].status; - case 4: - return piix_busmaster[channel].ptr; - case 5: - return piix_busmaster[channel].ptr >> 8; - case 6: - return piix_busmaster[channel].ptr >> 16; - case 7: - return piix_busmaster[channel].ptr >> 24; - } - return 0xff; -} - -int piix_bus_master_data_read(int channel, uint8_t *data, int size) -{ - int transferred = 0; - - if (!(piix_busmaster[channel].status & 1)) - return 1; /*DMA disabled*/ - - while (transferred < size) - { - if (piix_busmaster[channel].count < (size - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Read count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot, size); - - mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+(size-1)); - - if (piix_busmaster[channel].count < (size - transferred)) - { -// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); - if (piix_busmaster[channel].addr < (mem_size * 1024)) - { - int count = piix_busmaster[channel].count; - if ((piix_busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - piix_busmaster[channel].addr; - memcpy(&ram[piix_busmaster[channel].addr], data + transferred, count); - } - transferred += piix_busmaster[channel].count; - piix_busmaster[channel].addr += piix_busmaster[channel].count; - piix_busmaster[channel].count = 0; - } - else - { -// pclog("Transferring larger - %i bytes\n", size - transferred); - if (piix_busmaster[channel].addr < (mem_size * 1024)) - { - int count = size - transferred; - if ((piix_busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - piix_busmaster[channel].addr; - memcpy(&ram[piix_busmaster[channel].addr], data + transferred, count); - } - piix_busmaster[channel].addr += (size - transferred); - piix_busmaster[channel].count -= (size - transferred); - transferred += (size - 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 - piix_bus_master_next_addr(channel); - } - } - return 0; -} -int piix_bus_master_data_write(int channel, uint8_t *data, int size) -{ - int transferred = 0; - - if (!(piix_busmaster[channel].status & 1)) - return 1; /*DMA disabled*/ - - while (transferred < size) - { - if (piix_busmaster[channel].count < (size - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Write count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot, size); - - if (piix_busmaster[channel].count < (size - transferred)) - { -// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); - if (piix_busmaster[channel].addr < (mem_size * 1024)) - { - int count = piix_busmaster[channel].count; - if ((piix_busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - piix_busmaster[channel].addr; - memcpy(data + transferred, &ram[piix_busmaster[channel].addr], count); - } - transferred += piix_busmaster[channel].count; - piix_busmaster[channel].addr += piix_busmaster[channel].count; - piix_busmaster[channel].count = 0; - } - else - { -// pclog("Transferring larger - %i bytes\n", size - transferred); - if (piix_busmaster[channel].addr < (mem_size * 1024)) - { - int count = size - transferred; - if ((piix_busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - piix_busmaster[channel].addr; - memcpy(data + transferred, &ram[piix_busmaster[channel].addr], count); - } - piix_busmaster[channel].addr += (size - transferred); - piix_busmaster[channel].count -= (size - transferred); - transferred += (size - 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 - piix_bus_master_next_addr(channel); - } - } - return 0; -} - -void piix_bus_master_set_irq(int channel) -{ - piix_busmaster[channel].status |= 4; -} void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { @@ -379,8 +178,8 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) 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[0x40] = card_piix_ide[0x41] = 0x00; card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; - - ide_set_bus_master(piix_bus_master_data_read, piix_bus_master_data_write, piix_bus_master_set_irq); + + sff_bus_master_init(piix_busmaster); pci_set_card_routing(pci_a, PCI_INTA); pci_set_card_routing(pci_b, PCI_INTB); diff --git a/src/vt82c586b.c b/src/vt82c586b.c index fd67002..34a064b 100644 --- a/src/vt82c586b.c +++ b/src/vt82c586b.c @@ -1,6 +1,8 @@ #include #include "ibm.h" +#include "ide.h" +#include "ide_sff8038i.h" #include "io.h" #include "mem.h" #include "pci.h" @@ -16,6 +18,8 @@ static struct uint8_t power_regs[256]; uint8_t sysctrl; + + sff_busmaster_t busmaster[2]; } vt82c586b; static uint8_t vt82c586b_read(int func, int addr, void *priv) @@ -101,7 +105,7 @@ static void vt82c586b_pci_isa_bridge_write(int addr, uint8_t val) static void vt82c586b_ide_write(int addr, uint8_t val) { /*Read-only addresses*/ - if ((addr < 6) || (addr == 8) + if ((addr < 4) || (addr == 5) || (addr == 8) || (addr >= 0xa && addr < 0x0d) || (addr >= 0x0e && addr < 0x20) || (addr >= 0x22 && addr < 0x3c) @@ -114,7 +118,7 @@ static void vt82c586b_ide_write(int addr, uint8_t val) switch (addr) { case 4: - vt82c586b.ide_regs[4] = (val & 8) | 7; + vt82c586b.ide_regs[4] = val & 0x85; break; case 6: vt82c586b.ide_regs[6] &= ~(val & 0xb0); @@ -132,11 +136,32 @@ static void vt82c586b_ide_write(int addr, uint8_t val) vt82c586b.ide_regs[addr] = val; break; } + + if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ + { + uint16_t base = (vt82c586b.ide_regs[0x20] & 0xf0) | (vt82c586b.ide_regs[0x21] << 8); + io_removehandler(0, 0x10000, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, vt82c586b.busmaster); + if (vt82c586b.ide_regs[0x04] & 1) + io_sethandler(base, 0x10, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, vt82c586b.busmaster); + } + if (addr == 4 || addr == 0x40) + { + ide_pri_disable(); + ide_sec_disable(); + if (vt82c586b.ide_regs[0x04] & 1) + { + if (vt82c586b.ide_regs[0x40] & 0x02) + ide_pri_enable(); + if (vt82c586b.ide_regs[0x40] & 0x01) + ide_sec_enable(); + } + } } static void vt82c586b_usb_write(int addr, uint8_t val) { /*Read-only addresses*/ - if ((addr < 7) || (addr >= 8 && addr < 0xd) + if ((addr < 4) || (addr == 5) || (addr == 6) + || (addr >= 8 && addr < 0xd) || (addr >= 0xe && addr < 0x20) || (addr >= 0x22 && addr < 0x3c) || (addr >= 0x3e && addr < 0x40) @@ -147,6 +172,9 @@ static void vt82c586b_usb_write(int addr, uint8_t val) switch (addr) { + case 4: + vt82c586b.usb_regs[4] = val & 0x97; + break; case 7: vt82c586b.usb_regs[7] = val & 0x7f; break; @@ -307,4 +335,9 @@ void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) pci_set_card_routing(pci_c, PCI_INTC); if (pci_d) pci_set_card_routing(pci_d, PCI_INTD); + + sff_bus_master_init(vt82c586b.busmaster); + + ide_pri_disable(); + ide_sec_disable(); } From da2d819ed4d5d9fdd7aa85b6f28995043fc20e60 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 3 Dec 2018 21:59:41 +0000 Subject: [PATCH 0560/1050] Added WinChip 2 emulation, along with (currently non-recompiled) 3DNow! instruction emulation. --- src/386_ops.h | 112 ++++++++++++-- src/codegen.c | 2 +- src/cpu.c | 146 ++++++++++++++++++- src/cpu.h | 15 +- src/ibm.h | 1 + src/model.c | 2 +- src/x86_ops.h | 8 + src/x86_ops_3dnow.h | 346 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 607 insertions(+), 25 deletions(-) create mode 100644 src/x86_ops_3dnow.h diff --git a/src/386_ops.h b/src/386_ops.h index f091c93..2ad1789 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -104,6 +104,15 @@ static inline uint32_t POP_L_seg(uint32_t seg) return ret; } +static int ILLEGAL(uint32_t fetchdat) +{ + cpu_state.pc = cpu_state.oldpc; + +// fatal("Illegal instruction %08X\n", fetchdat); + x86illegal(); + return 0; +} + #include "x86_ops_arith.h" #include "x86_ops_atomic.h" #include "x86_ops_bcd.h" @@ -118,6 +127,7 @@ static inline uint32_t POP_L_seg(uint32_t seg) #include "x86_ops_jump.h" #include "x86_ops_misc.h" #include "x86_ops_mmx.h" +#include "x86_ops_3dnow.h" #include "x86_ops_mmx_arith.h" #include "x86_ops_mmx_cmp.h" #include "x86_ops_mmx_logic.h" @@ -140,15 +150,6 @@ static inline uint32_t POP_L_seg(uint32_t seg) #include "x86_ops_string.h" #include "x86_ops_xchg.h" -static int ILLEGAL(uint32_t fetchdat) -{ - cpu_state.pc = cpu_state.oldpc; - -// fatal("Illegal instruction %08X\n", fetchdat); - x86illegal(); - return 0; -} - static int op0F_w_a16(uint32_t fetchdat) { int opcode = fetchdat & 0xff; @@ -455,7 +456,98 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -OpFn OP_TABLE(pentium_0f)[1024] = +OpFn OP_TABLE(winchip2_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; + +OpFn OP_TABLE(pentium_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ diff --git a/src/codegen.c b/src/codegen.c index 7a74756..f0f1873 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -276,7 +276,7 @@ static uint8_t opcode_modrm[256] = }; static uint8_t opcode_0f_modrm[256] = { - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ 1, 1, 1, 1, 1, 1, 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*/ diff --git a/src/cpu.c b/src/cpu.c index c5958c5..c265d26 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -34,6 +34,7 @@ OpFn *x86_dynarec_opcodes_df_a16; OpFn *x86_dynarec_opcodes_df_a32; OpFn *x86_dynarec_opcodes_REPE; OpFn *x86_dynarec_opcodes_REPNE; +OpFn *x86_dynarec_opcodes_3DNOW; OpFn *x86_opcodes; OpFn *x86_opcodes_0f; @@ -55,6 +56,7 @@ OpFn *x86_opcodes_df_a16; OpFn *x86_opcodes_df_a32; OpFn *x86_opcodes_REPE; OpFn *x86_opcodes_REPNE; +OpFn *x86_opcodes_3DNOW; enum { @@ -68,6 +70,12 @@ enum CPUID_MMX = (1 << 23) }; +/*Addition flags returned by CPUID function 0x80000001*/ +enum +{ + CPUID_3DNOW = (1 << 31) +}; + int cpu = 3, cpu_manufacturer = 0; CPU *cpu_s; int cpu_multi; @@ -79,6 +87,7 @@ int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_hasCX8; int cpu_hasVME; +int cpu_has3DNOW; int cpu_use_dynarec; int cpu_cyrix_alignment; @@ -402,8 +411,22 @@ CPU cpus_WinChip[] = {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2}, {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7}, {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_WinChip_SS7[] = +{ + /*IDT WinChip (Super Socket 7)*/ + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, {"", -1, 0, 0, 0} }; @@ -505,6 +528,7 @@ void cpu_set() cpu_hasMSR = 0; cpu_hasCR4 = 0; cpu_hasCX8 = 0; + cpu_has3DNOW = 0; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); @@ -548,8 +572,10 @@ void cpu_set() x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; + x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; if (hasfpu) { @@ -950,7 +976,7 @@ void cpu_set() timing_bt = 3-1; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ cpu_hasrdtsc = 1; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msr.fcr = (1 << 8) | (1 << 16); cpu_hasMMX = cpu_hasMSR = 1; cpu_hasCR4 = 1; cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; @@ -978,6 +1004,46 @@ void cpu_set() codegen_timing_set(&codegen_timing_winchip); break; + case CPU_WINCHIP2: + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 2; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 2; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3-1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_hasrdtsc = 1; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_hasMMX = cpu_hasMSR = cpu_has3DNOW = 1; + cpu_hasCR4 = 1; + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; + codegen_timing_set(&codegen_timing_winchip); + break; + case CPU_PENTIUM: x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); timing_rr = 1; /*register dest - register src*/ @@ -1308,7 +1374,7 @@ void cpu_CPUID() else { EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; + ECX = 0x736c7561; EDX = 0x48727561; } } @@ -1317,14 +1383,74 @@ void cpu_CPUID() EAX = 0x540; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_hasCX8) - EDX |= CPUID_CMPXCHG8B; + if (cpu_hasCX8) + EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) EDX |= CPUID_MMX; } else EAX = EBX = ECX = EDX = 0; break; + + case CPU_WINCHIP2: + switch (EAX) + { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) + { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } + else + { + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = 0x580; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_hasCX8) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = 0x580; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_hasCX8) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has3DNOW) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x20544449; /*IDT WinChip 2-3D*/ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; case CPU_PENTIUM: if (!EAX) @@ -1447,6 +1573,7 @@ void cpu_RDMSR() switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type) { case CPU_WINCHIP: + case CPU_WINCHIP2: EAX = EDX = 0; switch (ECX) { @@ -1507,6 +1634,7 @@ void cpu_WRMSR() switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type) { case CPU_WINCHIP: + case CPU_WINCHIP2: switch (ECX) { case 0x02: @@ -1525,9 +1653,13 @@ void cpu_WRMSR() msr.fcr = EAX; cpu_hasMMX = EAX & (1 << 9); if (EAX & (1 << 1)) - cpu_hasCX8 = 1; + cpu_hasCX8 = 1; else - cpu_hasCX8 = 0; + cpu_hasCX8 = 0; + if ((EAX & (1 << 20)) && models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) + cpu_has3DNOW = 1; + else + cpu_has3DNOW = 0; if (EAX & (1 << 29)) CPUID = 0; else diff --git a/src/cpu.h b/src/cpu.h index ca6242f..acde362 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -28,12 +28,13 @@ extern int cpu, cpu_manufacturer; /*586 class CPUs*/ #define CPU_WINCHIP 15 -#define CPU_PENTIUM 16 -#define CPU_PENTIUMMMX 17 -#define CPU_Cx6x86 18 -#define CPU_Cx6x86MX 19 -#define CPU_Cx6x86L 20 -#define CPU_CxGX1 21 +#define CPU_WINCHIP2 16 +#define CPU_PENTIUM 17 +#define CPU_PENTIUMMMX 18 +#define CPU_Cx6x86 19 +#define CPU_Cx6x86MX 20 +#define CPU_Cx6x86L 21 +#define CPU_CxGX1 22 #define MANU_INTEL 0 #define MANU_AMD 1 @@ -84,6 +85,7 @@ extern CPU cpus_i486[]; extern CPU cpus_Am486[]; extern CPU cpus_Cx486[]; extern CPU cpus_WinChip[]; +extern CPU cpus_WinChip_SS7[]; extern CPU cpus_Pentium5V[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium[]; @@ -111,6 +113,7 @@ extern int cpu_hasMMX; extern int cpu_hasCR4; extern int cpu_hasVME; extern int cpu_hasCX8; +extern int cpu_has3DNOW; #define CR4_TSD (1 << 2) #define CR4_DE (1 << 3) diff --git a/src/ibm.h b/src/ibm.h index fb7865c..e99c232 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -132,6 +132,7 @@ typedef union MMX_REG int16_t sw[4]; uint8_t b[8]; int8_t sb[8]; + float f[2]; } MMX_REG; struct diff --git a/src/model.c b/src/model.c index 7d3a540..015eb48 100644 --- a/src/model.c +++ b/src/model.c @@ -193,7 +193,7 @@ MODEL models[] = {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, - {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, + {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; diff --git a/src/x86_ops.h b/src/x86_ops.h index 7919ec4..73a0b6f 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -25,6 +25,7 @@ extern OpFn *x86_dynarec_opcodes_df_a16; extern OpFn *x86_dynarec_opcodes_df_a32; extern OpFn *x86_dynarec_opcodes_REPE; extern OpFn *x86_dynarec_opcodes_REPNE; +extern OpFn *x86_dynarec_opcodes_3DNOW; extern OpFn dynarec_ops_286[1024]; extern OpFn dynarec_ops_286_0f[1024]; @@ -33,6 +34,7 @@ extern OpFn dynarec_ops_386[1024]; extern OpFn dynarec_ops_386_0f[1024]; extern OpFn dynarec_ops_winchip_0f[1024]; +extern OpFn dynarec_ops_winchip2_0f[1024]; extern OpFn dynarec_ops_pentium_0f[1024]; extern OpFn dynarec_ops_pentiummmx_0f[1024]; @@ -67,6 +69,8 @@ extern OpFn dynarec_ops_fpu_686_df_a32[256]; extern OpFn dynarec_ops_REPE[1024]; extern OpFn dynarec_ops_REPNE[1024]; +extern OpFn dynarec_ops_3DNOW[256]; + extern OpFn *x86_opcodes; extern OpFn *x86_opcodes_0f; extern OpFn *x86_opcodes_d8_a16; @@ -87,6 +91,7 @@ extern OpFn *x86_opcodes_df_a16; extern OpFn *x86_opcodes_df_a32; extern OpFn *x86_opcodes_REPE; extern OpFn *x86_opcodes_REPNE; +extern OpFn *x86_opcodes_3DNOW; extern OpFn ops_286[1024]; extern OpFn ops_286_0f[1024]; @@ -95,6 +100,7 @@ extern OpFn ops_386[1024]; extern OpFn ops_386_0f[1024]; extern OpFn ops_winchip_0f[1024]; +extern OpFn ops_winchip2_0f[1024]; extern OpFn ops_pentium_0f[1024]; extern OpFn ops_pentiummmx_0f[1024]; @@ -130,4 +136,6 @@ extern OpFn ops_fpu_686_df_a32[256]; extern OpFn ops_REPE[1024]; extern OpFn ops_REPNE[1024]; +extern OpFn ops_3DNOW[256]; + #endif /*_X86_OPS_H*/ diff --git a/src/x86_ops_3dnow.h b/src/x86_ops_3dnow.h new file mode 100644 index 0000000..d57a3a3 --- /dev/null +++ b/src/x86_ops_3dnow.h @@ -0,0 +1,346 @@ +#include + +static int opPREFETCH_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} +static int opPREFETCH_a32(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} + +static int opFEMMS(uint32_t fetchdat) +{ + ILLEGAL_ON(!cpu_hasMMX); + if (cr0 & 4) + { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; +} + +static int opPAVGUSB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + + return 0; +} +static int opPF2ID(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; + + return 0; +} +static int opPFACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int opPFADD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; + + return 0; +} +static int opPFCMPEQ(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFCMPGE(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFCMPGT(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int opPFMAX(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFMIN(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFMUL(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + + return 0; +} +static int opPFRCP(uint32_t fetchdat) +{ + union + { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) + { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + + cpu_state.MM[cpu_reg].f[0] = 1.0/src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + + return 0; +} +/*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ +static int opPFRCPIT1(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFRCPIT2(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int opPFRSQRT(uint32_t fetchdat) +{ + union + { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) + { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + + cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + + return 0; +} +/*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ +static int opPFRSQIT1(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + UNUSED(src); + + return 0; +} +static int opPFSUB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + + return 0; +} +static int opPFSUBR(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + + return 0; +} +static int opPI2FD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; + + return 0; +} +static int opPMULHRW(uint32_t fetchdat) +{ + if (cpu_mod == 3) + { + cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } + else + { + MMX_REG src; + + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; +} + +OpFn OP_TABLE(3DNOW)[256] = +{ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, +/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL, +/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL, +/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB, + +/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +static int op3DNOW_a16(uint32_t fetchdat) +{ + uint8_t opcode; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + return x86_opcodes_3DNOW[opcode](0); +} +static int op3DNOW_a32(uint32_t fetchdat) +{ + uint8_t opcode; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) return 1; + cpu_state.pc++; + + return x86_opcodes_3DNOW[opcode](0); +} From ca39b51803e9b263f0e06c95e0c8776423450eb6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 4 Dec 2018 21:35:26 +0000 Subject: [PATCH 0561/1050] Fix address calculation on PCMPEQD and PCMPGTD. --- src/x86_ops_mmx_cmp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/x86_ops_mmx_cmp.h b/src/x86_ops_mmx_cmp.h index ea090f5..b61ac67 100644 --- a/src/x86_ops_mmx_cmp.h +++ b/src/x86_ops_mmx_cmp.h @@ -166,7 +166,7 @@ static int opPCMPEQD_a32(uint32_t fetchdat) MMX_ENTER(); - fetch_ea_16(fetchdat); + fetch_ea_32(fetchdat); MMX_GETSRC(); cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; @@ -195,7 +195,7 @@ static int opPCMPGTD_a32(uint32_t fetchdat) MMX_ENTER(); - fetch_ea_16(fetchdat); + fetch_ea_32(fetchdat); MMX_GETSRC(); cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; From 9b8b6c2c706df7c37c4bfd481f115906e927112e Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 4 Dec 2018 21:35:51 +0000 Subject: [PATCH 0562/1050] Add Winchip 2A CPUs. --- src/cpu.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index c265d26..750f473 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -414,19 +414,25 @@ CPU cpus_WinChip[] = {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, {"", -1, 0, 0, 0} }; CPU cpus_WinChip_SS7[] = { /*IDT WinChip (Super Socket 7)*/ - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 2A/266", CPU_WINCHIP2, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2A/300", CPU_WINCHIP2, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, {"", -1, 0, 0, 0} }; From 7ec6f1e4ce9e7c4b875845939111c31bc1040745 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 5 Dec 2018 20:54:56 +0000 Subject: [PATCH 0563/1050] Added Winchip 2 timing model. --- src/codegen.h | 1 + src/codegen_timing_common.c | 4 +- src/codegen_timing_winchip2.c | 753 ++++++++++++++++++++++++++++++++++ src/cpu.c | 2 +- 4 files changed, 757 insertions(+), 3 deletions(-) create mode 100644 src/codegen_timing_winchip2.c diff --git a/src/codegen.h b/src/codegen.h index 93657a1..8e40af1 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -334,6 +334,7 @@ extern codegen_timing_t codegen_timing_pentium; extern codegen_timing_t codegen_timing_686; extern codegen_timing_t codegen_timing_486; extern codegen_timing_t codegen_timing_winchip; +extern codegen_timing_t codegen_timing_winchip2; void codegen_timing_set(codegen_timing_t *timing); diff --git a/src/codegen_timing_common.c b/src/codegen_timing_common.c index b56335a..43aa4b8 100644 --- a/src/codegen_timing_common.c +++ b/src/codegen_timing_common.c @@ -274,7 +274,7 @@ uint64_t opcode_deps_0f[256] = /*00*/ MODRM, MODRM, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, + 0, MODRM, 0, MODRM, /*10*/ 0, 0, 0, 0, 0, 0, 0, 0, @@ -356,7 +356,7 @@ uint64_t opcode_deps_0f_mod3[256] = /*00*/ MODRM, MODRM, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, + 0, MODRM, 0, MODRM, /*10*/ 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/codegen_timing_winchip2.c b/src/codegen_timing_winchip2.c new file mode 100644 index 0000000..0644298 --- /dev/null +++ b/src/codegen_timing_winchip2.c @@ -0,0 +1,753 @@ +/*Since IDT/Centaur didn't document cycle timings in the WinChip datasheets, and + I don't currently own a WinChip 2 to test against, most of the timing here is + a guess. This code makes the current (probably wrong) assumptions : + - FPU uses same timings as a Pentium, except for FXCH (which doesn't pair) + - 3DNow! instructions perfectly pair + - MMX follows mostly Pentium rules - one pipeline has shift/pack, one has + multiply, and other instructions can execute in either pipeline + - Instructions with prefixes can pair if both instructions are fully decoded + when the first instruction starts execution.*/ +#include "ibm.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "mem.h" +#include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" + +/*Instruction has different execution time for 16 and 32 bit data. Does not pair */ +#define CYCLES_HAS_MULTI (1 << 31) + +#define CYCLES_FPU (1 << 30) + +#define CYCLES_IS_MMX_MUL (1 << 29) +#define CYCLES_IS_MMX_SHIFT (1 << 28) +#define CYCLES_IS_MMX_ANY (1 << 27) +#define CYCLES_IS_3DNOW (1 << 26) + +#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) +#define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c) +#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) +#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) + +#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) + +#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX)) + +#define CYCLES(c) c +#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) + +/*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) (comp_time) | (i_overlap << 8) | (f_overlap << 16) | CYCLES_FPU + +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 16) & 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 >> 8) & 0xff) + +#define INVALID 0 + +static uint32_t opcode_timings[256] = +{ +/*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, +/*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), +/*20*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), +/*30*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + +/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), +/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*80*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), +/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), +/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), +/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), +/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), +/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID +}; + +static uint32_t opcode_timings_mod3[256] = +{ +/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, +/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), +/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), +/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + +/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), +/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), +/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), +/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), +/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*c0*/ CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), +/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), +/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, +}; + +static uint32_t opcode_timings_0f[256] = +{ +/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), +/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*60*/ CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), +/*70*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), +/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30), +/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + +/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*d0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), +/*e0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), +/*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, +}; +static uint32_t opcode_timings_0f_mod3[256] = +{ +/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), +/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*60*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), +/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), +/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30), +/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + +/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), +/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), +/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, +}; + +static uint32_t opcode_timings_shift[8] = +{ + CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) +}; +static uint32_t opcode_timings_shift_mod3[8] = +{ + CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) +}; + +static uint32_t opcode_timings_f6[8] = +{ + CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) +}; +static uint32_t opcode_timings_f6_mod3[8] = +{ + CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) +}; +static uint32_t opcode_timings_f7[8] = +{ + CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) +}; +static uint32_t opcode_timings_f7_mod3[8] = +{ + CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) +}; +static uint32_t opcode_timings_ff[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID +}; +static uint32_t opcode_timings_ff_mod3[8] = +{ + CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID +}; + +static uint32_t opcode_timings_d8[8] = +{ +/* FADDs FMULs FCOMs FCOMPs*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), +/* FSUBs FSUBRs FDIVs FDIVRs*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; +static uint32_t opcode_timings_d8_mod3[8] = +{ +/* FADD FMUL FCOM FCOMP*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), +/* FSUB FSUBR FDIV FDIVR*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; + +static uint32_t opcode_timings_d9[8] = +{ +/* FLDs FSTs FSTPs*/ + FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FLDENV FLDCW FSTENV FSTCW*/ + FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0) +}; +static uint32_t opcode_timings_d9_mod3[64] = +{ + /*FLD*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), + /*FXCH*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), + /*FNOP*/ + FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), +/* opFCHS opFABS*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), INVALID, INVALID, +/* opFTST opFXAM*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(21,4,0), INVALID, INVALID, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), +/* opFLDEG2 opFLDLN2 opFLDZ*/ + FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(2,0,0), INVALID, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + FPU_CYCLES(53,2,2), FPU_CYCLES(103,2,2),FPU_CYCLES(120,36,0),FPU_CYCLES(112,2,2), +/* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* opFPREM opFSQRT opFSINCOS*/ + FPU_CYCLES(64,2,2), INVALID, FPU_CYCLES(70,69,2),FPU_CYCLES(89,2,2), +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + FPU_CYCLES(9,0,0), FPU_CYCLES(20,5,0), FPU_CYCLES(65,2,2), FPU_CYCLES(65,2,2) +}; + +static uint32_t opcode_timings_da[8] = +{ +/* FIADDl FIMULl FICOMl FICOMPl*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) +}; +static uint32_t opcode_timings_da_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FCOMPP*/ + INVALID, FPU_CYCLES(1,0,0), INVALID, INVALID +}; + + +static uint32_t opcode_timings_db[8] = +{ +/* FLDil FSTil FSTPil*/ + FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), +/* FLDe FSTPe*/ + INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0) +}; +static uint32_t opcode_timings_db_mod3[64] = +{ + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/* opFNOP opFCLEX opFINIT*/ + INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(7,0,0), FPU_CYCLES(17,0,0), +/* opFNOP opFNOP*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +}; + +static uint32_t opcode_timings_dc[8] = +{ +/* FADDd FMULd FCOMd FCOMPd*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), +/* FSUBd FSUBRd FDIVd FDIVRd*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; +static uint32_t opcode_timings_dc_mod3[8] = +{ +/* opFADDr opFMULr*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; + +static uint32_t opcode_timings_dd[8] = +{ +/* FLDd FSTd FSTPd*/ + FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FRSTOR FSAVE FSTSW*/ + FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0) +}; +static uint32_t opcode_timings_dd_mod3[8] = +{ +/* FFFREE FST FSTP*/ + FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), +/* FUCOM FUCOMP*/ + FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),INVALID, INVALID +}; + +static uint32_t opcode_timings_de[8] = +{ +/* FIADDw FIMULw FICOMw FICOMPw*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) +}; +static uint32_t opcode_timings_de_mod3[8] = +{ +/* FADDP FMULP FCOMPP*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0), +/* FSUBP FSUBRP FDIVP FDIVRP*/ + FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; + +static uint32_t opcode_timings_df[8] = +{ +/* FILDiw FISTiw FISTPiw*/ + FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), +/* FILDiq FBSTP FISTPiq*/ + INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0) +}; +static uint32_t opcode_timings_df_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FSTSW AX*/ + FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID +}; + +static uint32_t opcode_timings_8x[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; +static uint32_t opcode_timings_8x_mod3[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; +static uint32_t opcode_timings_81[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; +static uint32_t opcode_timings_81_mod3[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; + +static int timing_count; +static uint8_t last_prefix; +static uint32_t regmask_modified; +static int decode_delay, decode_delay_offset; +static int fpu_latency; +static int fpu_st_latency[8]; + +static int u_pipe_full; +static uint32_t u_pipe_opcode; +static uint32_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 uint64_t *u_pipe_deps; + +int can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b) +{ + /*Only MMX/3DNow instructions can pair*/ + if (!(timing_b & CYCLES_IS_MMX)) + return 0; + /*Only one MMX multiply per cycle*/ + if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) + return 0; + /*Only one MMX shift/pack per cycle*/ + if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) + return 0; + /*Second instruction can not access registers written by first*/ + if (u_pipe_regmask & regmask_b) + return 0; + /*Must have had enough time to decode prefixes*/ + if ((decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) > 0) + return 0; + + return 1; +} + +static inline int COUNT(uint32_t c, int op_32) +{ + if (c & CYCLES_FPU) + return FPU_I_LATENCY(c); + if (c & CYCLES_HAS_MULTI) + { + if (op_32 & 0x100) + return (c >> 8) & 0xff; + return c & 0xff; + } + return GET_CYCLES(c); +} + +static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +{ + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); + + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; +} + +static int codegen_fpu_latencies(uint64_t deps, int reg) +{ + int latency = fpu_latency; + + if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((deps & 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 void codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) +{ + int instr_cycles, latency = 0; + + if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[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); + instr_cycles += exec_delay; + 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 (deps[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 (deps[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] & CYCLES_FPU) + { + /* if (fpu_latency) + fatal("Bad latency FPU\n");*/ + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (deps[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 (deps[opcode] & FPU_WRITE_ST0) + { +/* if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_ST1) + { +/* if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_STREG) + { + int reg = fetchdat & 7; + if (deps[opcode] & FPU_POP) + reg--; + if (reg >= 0 && + !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && + !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) + { +/* if (fpu_st_latency[reg]) + fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); + } + } +} + +static void codegen_timing_winchip2_block_start() +{ + regmask_modified = 0; + decode_delay = decode_delay_offset = 0; + u_pipe_full = 0; +} + +static void codegen_timing_winchip2_start() +{ + timing_count = 0; + last_prefix = 0; +} + +static void codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) +{ + if (prefix == 0x0f) + { + /*0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; +} + +static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +{ + uint32_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + int agi_stall = 0; + + switch (last_prefix) + { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; +// pclog("timings 0f\n"); + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; +// pclog("timings d8\n"); + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings d9\n"); + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; +// pclog("timings da\n"); + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings db\n"); + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; +// pclog("timings dc\n"); + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; +// pclog("timings dd\n"); + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; +// pclog("timings de\n"); + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; +// pclog("timings df\n"); + break; + + default: + switch (opcode) + { + case 0x80: case 0x82: case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; + opcode = (fetchdat >> 3) & 7; +// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + 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; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; +// pclog("timings c0\n"); + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f6\n"); + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f7\n"); + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; +// pclog("timings ff\n"); + break; + + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; +// pclog("timings normal\n"); + break; + } + } + + if (u_pipe_full) + { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); + + if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) + { + int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; + int cycles_b = timings[opcode] & 0xff; + uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; + uint64_t temp_deps = 0; + + if (check_agi(deps, opcode, fetchdat, op_32) || check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + + codegen_instruction(&timing, &temp_deps, 0, 0, 0, 0, agi_stall); + u_pipe_full = 0; + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | u_pipe_regmask; + return; + } + else + { + /*No pairing, run first instruction now*/ + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + regmask_modified = u_pipe_regmask; + } + } + if (timings[opcode] & CYCLES_IS_MMX) + { + /*Might pair with next instruction*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8); + u_pipe_fetchdat = fetchdat; + u_pipe_decode_delay_offset = decode_delay_offset; + u_pipe_deps = deps; + decode_delay_offset = 0; + return; + } + + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); +} + +static void codegen_timing_winchip2_block_end() +{ + if (u_pipe_full) + { + int agi_stall = 0; + + if (check_agi(u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_op_32)) + agi_stall = 1; + codegen_instruction(u_pipe_timings, u_pipe_deps, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32, agi_stall); + u_pipe_full = 0; + } +} + +codegen_timing_t codegen_timing_winchip2 = +{ + codegen_timing_winchip2_start, + codegen_timing_winchip2_prefix, + codegen_timing_winchip2_opcode, + codegen_timing_winchip2_block_start, + codegen_timing_winchip2_block_end +}; diff --git a/src/cpu.c b/src/cpu.c index 750f473..59cc22c 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1047,7 +1047,7 @@ void cpu_set() timing_jmp_pm_gate = 17; timing_misaligned = 2; cpu_cyrix_alignment = 1; - codegen_timing_set(&codegen_timing_winchip); + codegen_timing_set(&codegen_timing_winchip2); break; case CPU_PENTIUM: From a9541dadeac6f2c30c0ab12e2cb4023bb6868bf9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 6 Dec 2018 20:02:35 +0000 Subject: [PATCH 0564/1050] Added preliminary emulation of AMD K6 CPUs. --- src/cpu.c | 374 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cpu.h | 7 + src/model.c | 4 +- 3 files changed, 383 insertions(+), 2 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 59cc22c..eca0d0d 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -500,6 +500,55 @@ CPU cpus_Pentium[] = {"", -1, 0, 0, 0} }; +CPU cpus_K6_S7[] = +{ + /*AMD K6*/ + {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_K6_SS7[] = +{ + /*AMD K6*/ + {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6-2/300", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/333", CPU_K6_2, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"K6-2/350", CPU_K6_2, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 42}, + {"K6-2/366", CPU_K6_2, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 44}, + {"K6-2/380", CPU_K6_2, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 46}, + {"K6-2/400", CPU_K6_2, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-2/450", CPU_K6_2, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-2/475", CPU_K6_2, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-2/500", CPU_K6_2, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6-2/533", CPU_K6_2, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, + {"K6-2/550", CPU_K6_2, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, + {"K6-2+/450", CPU_K6_2P, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-2+/475", CPU_K6_2P, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-2+/500", CPU_K6_2P, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6-2+/533", CPU_K6_2P, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, + {"K6-2+/550", CPU_K6_2P, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, + {"K6-III/400", CPU_K6_3, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-III/450", CPU_K6_3, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-III+/400", CPU_K6_3P, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-III+/450", CPU_K6_3P, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-III+/475", CPU_K6_3P, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-III+/500", CPU_K6_3P, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"", -1, 0, 0, 0} +}; + void cpu_set_edx() { EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset; @@ -1287,6 +1336,91 @@ void cpu_set() ccr4 = 0x80; break; + case CPU_K6: + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + 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; + cpu_hasMSR = 1; + cpu_hasCR4 = 1; + cpu_hasVME = 1; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + codegen_timing_set(&codegen_timing_pentium); + break; + + case CPU_K6_2: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + 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; + cpu_hasMSR = 1; + cpu_hasCR4 = 1; + cpu_hasVME = 1; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + codegen_timing_set(&codegen_timing_pentium); + break; + default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } @@ -1571,6 +1705,220 @@ void cpu_CPUID() EAX = EBX = ECX = EDX = 0; break; + case CPU_K6: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6tm w/ mult*/ + EBX = 0x6d74364b; + ECX = 0x202f7720; + EDX = 0x746c756d; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x64656d69; /*imedia extension*/ + EBX = 0x65206169; + ECX = 0x6e657478; + EDX = 0x6e6f6973; + break; + + case 0x80000004: /*Processor name string*/ + EAX = 0x00000073; /*s*/ + EBX = 0x00000000; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_2: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x7365636f; /*ocessor*/ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_3: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + ECX = 0x01004220; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + break; + case 0x80000001: + EAX = CPUID+0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; + + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; + + case 0x80000007: /*PowerNow information*/ + EDX = 7; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; } } @@ -1632,6 +1980,20 @@ void cpu_RDMSR() break; } break; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) + { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + break; } } @@ -1700,6 +2062,18 @@ void cpu_WRMSR() break; } break; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) + { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + } + break; } } diff --git a/src/cpu.h b/src/cpu.h index acde362..02a1340 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -35,6 +35,11 @@ extern int cpu, cpu_manufacturer; #define CPU_Cx6x86MX 20 #define CPU_Cx6x86L 21 #define CPU_CxGX1 22 +#define CPU_K6 23 +#define CPU_K6_2 24 +#define CPU_K6_3 25 +#define CPU_K6_2P 26 +#define CPU_K6_3P 27 #define MANU_INTEL 0 #define MANU_AMD 1 @@ -90,6 +95,8 @@ extern CPU cpus_Pentium5V[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium[]; extern CPU cpus_6x86[]; +extern CPU cpus_K6_S7[]; +extern CPU cpus_K6_SS7[]; extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; diff --git a/src/model.c b/src/model.c index 015eb48..d060d67 100644 --- a/src/model.c +++ b/src/model.c @@ -191,9 +191,9 @@ MODEL models[] = {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, - {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_i430vx_init, NULL}, - {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, + {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; From fd10fdd3727dac73bc15ec9bf07ea632be0d48dd Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 6 Dec 2018 20:02:51 +0000 Subject: [PATCH 0565/1050] Fix ATCLK timings on Winchip 2 CPUs. --- src/cpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index eca0d0d..1b2e0ef 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -413,9 +413,9 @@ CPU cpus_WinChip[] = {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, (7*8)/2}, {"", -1, 0, 0, 0} }; @@ -427,12 +427,12 @@ CPU cpus_WinChip_SS7[] = {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 2A/266", CPU_WINCHIP2, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2A/300", CPU_WINCHIP2, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 28}, + {"WinChip 2A/266", CPU_WINCHIP2, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, {"", -1, 0, 0, 0} }; From cfd4ac3a4ff3065e1157f2b3fd03781116b560b1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Dec 2018 22:17:11 +0000 Subject: [PATCH 0566/1050] Added initial timing model for K6 CPUs. --- src/codegen.c | 4 +- src/codegen.h | 5 +- src/codegen_timing_486.c | 2 +- src/codegen_timing_686.c | 2 +- src/codegen_timing_common.c | 165 +++ src/codegen_timing_common.h | 2 + src/codegen_timing_k6.c | 2288 +++++++++++++++++++++++++++++++++ src/codegen_timing_pentium.c | 2 +- src/codegen_timing_winchip.c | 2 +- src/codegen_timing_winchip2.c | 2 +- src/cpu.c | 4 +- 11 files changed, 2467 insertions(+), 11 deletions(-) create mode 100644 src/codegen_timing_k6.c diff --git a/src/codegen.c b/src/codegen.c index f0f1873..f42f22c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -18,7 +18,7 @@ uint16_t *codeblock_hash; void (*codegen_timing_start)(); void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); -void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); +void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); void (*codegen_timing_block_start)(); void (*codegen_timing_block_end)(); @@ -495,7 +495,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t } generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); codegen_accumulate(ACCREG_ins, 1); codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); diff --git a/src/codegen.h b/src/codegen.h index 8e40af1..e82b904 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -317,7 +317,7 @@ extern int codegen_block_cycles; extern void (*codegen_timing_start)(); extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); -extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); +extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); extern void (*codegen_timing_block_start)(); extern void (*codegen_timing_block_end)(); @@ -325,7 +325,7 @@ typedef struct codegen_timing_t { void (*start)(); void (*prefix)(uint8_t prefix, uint32_t fetchdat); - void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); void (*block_start)(); void (*block_end)(); } codegen_timing_t; @@ -335,6 +335,7 @@ extern codegen_timing_t codegen_timing_686; extern codegen_timing_t codegen_timing_486; extern codegen_timing_t codegen_timing_winchip; extern codegen_timing_t codegen_timing_winchip2; +extern codegen_timing_t codegen_timing_k6; void codegen_timing_set(codegen_timing_t *timing); diff --git a/src/codegen_timing_486.c b/src/codegen_timing_486.c index 4e05e24..cda0436 100644 --- a/src/codegen_timing_486.c +++ b/src/codegen_timing_486.c @@ -296,7 +296,7 @@ void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; } -void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { int **timings; uint64_t *deps; diff --git a/src/codegen_timing_686.c b/src/codegen_timing_686.c index 9559e03..dab2b10 100644 --- a/src/codegen_timing_686.c +++ b/src/codegen_timing_686.c @@ -823,7 +823,7 @@ static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_3 return 0; } -void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { uint32_t *timings; uint64_t *deps; diff --git a/src/codegen_timing_common.c b/src/codegen_timing_common.c index 43aa4b8..33ac5cf 100644 --- a/src/codegen_timing_common.c +++ b/src/codegen_timing_common.c @@ -434,6 +434,171 @@ uint64_t opcode_deps_0f_mod3[256] = MODRM, MODRM, MODRM, 0, }; +uint64_t opcode_deps_0f0f[256] = +{ +/*00*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, MODRM, 0, 0, + +/*10*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, MODRM, 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*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*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*/ MODRM, 0, 0, 0, + MODRM, 0, MODRM, MODRM, + 0, 0, MODRM, 0, + 0, 0, MODRM, 0, + +/*a0*/ MODRM, 0, 0, 0, + MODRM, 0, MODRM, MODRM, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*b0*/ MODRM, 0, 0, 0, + MODRM, 0, MODRM, MODRM, + 0, 0, 0, 0, + 0, 0, 0, MODRM, + +/*c0*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*d0*/ 0, 0, 0, 0, + 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*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +}; +uint64_t opcode_deps_0f0f_mod3[256] = +{ +/*00*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, MODRM, 0, 0, + +/*10*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, MODRM, 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*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*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*/ MODRM, 0, 0, 0, + MODRM, 0, MODRM, MODRM, + 0, 0, MODRM, 0, + 0, 0, MODRM, 0, + +/*a0*/ MODRM, 0, 0, 0, + MODRM, 0, MODRM, MODRM, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*b0*/ MODRM, 0, 0, 0, + MODRM, 0, MODRM, MODRM, + 0, 0, 0, 0, + 0, 0, 0, MODRM, + +/*c0*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + +/*d0*/ 0, 0, 0, 0, + 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*/ 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +}; + uint64_t opcode_deps_shift[8] = { MODRM, MODRM, MODRM, MODRM, diff --git a/src/codegen_timing_common.h b/src/codegen_timing_common.h index ac7bd2a..b185270 100644 --- a/src/codegen_timing_common.h +++ b/src/codegen_timing_common.h @@ -82,6 +82,8 @@ extern uint64_t opcode_deps[256]; extern uint64_t opcode_deps_mod3[256]; extern uint64_t opcode_deps_0f[256]; extern uint64_t opcode_deps_0f_mod3[256]; +extern uint64_t opcode_deps_0f0f[256]; +extern uint64_t opcode_deps_0f0f_mod3[256]; extern uint64_t opcode_deps_shift[8]; extern uint64_t opcode_deps_shift_mod3[8]; extern uint64_t opcode_deps_shift_cl[8]; diff --git a/src/codegen_timing_k6.c b/src/codegen_timing_k6.c new file mode 100644 index 0000000..a5d0cde --- /dev/null +++ b/src/codegen_timing_k6.c @@ -0,0 +1,2288 @@ +/*Most of the vector instructions here are a total guess. + Some of the timings are based on http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/ +#include "ibm.h" +#include "cpu.h" +#include "model.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "386_common.h" +#include "mem.h" +#include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" + +typedef enum uop_type_t +{ + UOP_ALU = 0, /*Executes in Integer X or Y units*/ + UOP_ALUX, /*Executes in Integer X unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORE, /*Executes in Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORE, /*Executes in Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORE, /*Executes in Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MEU, /*Executes in Multimedia unit*/ + UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ + UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ + UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_LIMM /*Does not require an execution unit*/ +} uop_type_t; + +typedef enum decode_type_t +{ + DECODE_SHORT, + DECODE_LONG, + DECODE_VECTOR +} decode_type_t; + +#define MAX_UOPS 10 + +typedef struct risc86_uop_t +{ + uop_type_t type; + int throughput; + int latency; +} risc86_uop_t; + +typedef struct risc86_instruction_t +{ + int nr_uops; + decode_type_t decode_type; + risc86_uop_t uop[MAX_UOPS]; +} risc86_instruction_t; + +static const risc86_instruction_t alu_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alux_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_alu_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_alux_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alu_store_op = +{ + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alux_store_op = +{ + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t branch_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t limm_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t load_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t store_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; + + +static const risc86_instruction_t bswap_op = +{ + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t leave_op = +{ + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t lods_op = +{ + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t loop_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mov_reg_seg_op = +{ + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t movs_op = +{ + .nr_uops = 4, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pop_reg_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pop_mem_op = +{ + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t push_imm_op = +{ + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t push_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t push_seg_op = +{ + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t stos_op = +{ + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_reg_op = +{ + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_reg_b_op = +{ + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_mem_imm_op = +{ + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_mem_imm_b_op = +{ + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t xchg_op = +{ + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t m3dn_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mmx_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mmx_mul_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t mmx_shift_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_3dn_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_mmx_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_mmx_mul_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t load_mmx_shift_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mload_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t mstore_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pmul_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t pmul_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t float_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t load_float_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t fstore_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t fdiv_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} +}; +static const risc86_instruction_t fdiv_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} +}; +static const risc86_instruction_t fsin_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} +}; +static const risc86_instruction_t fsqrt_op = +{ + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} +}; + +static const risc86_instruction_t vector_fldcw_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} +}; +static const risc86_instruction_t vector_float_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t vector_float_l_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} +}; +static const risc86_instruction_t vector_flde_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t vector_fste_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, + .uop[1] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t vector_alu1_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu2_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu3_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu6_op = +{ + .nr_uops = 6, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux1_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux3_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux6_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu_store_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux_store_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_arpl_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_bound_op = +{ + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_bsx_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_call_far_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cli_sti_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} +}; +static const risc86_instruction_t vector_cmps_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cmpsb_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cmpxchg_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cmpxchg_b_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cpuid_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} +}; +static const risc86_instruction_t vector_div16_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_div16_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_div32_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} +}; +static const risc86_instruction_t vector_div32_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} +}; +static const risc86_instruction_t vector_emms_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} +}; +static const risc86_instruction_t vector_enter_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_femms_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} +}; +static const risc86_instruction_t vector_in_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} +}; +static const risc86_instruction_t vector_ins_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_int_op = +{ + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_iret_op = +{ + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_invd_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} +}; +static const risc86_instruction_t vector_jmp_far_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_load_alu_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_load_alux_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_loop_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_lss_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mov_mem_seg_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mov_seg_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mov_seg_reg_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mul_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul_mem_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul64_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul64_mem_op = +{ + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_out_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_outs_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 10, .latency = 10}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_pusha_op = +{ + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_popa_op = +{ + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_popf_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 17, .latency = 17} +}; +static const risc86_instruction_t vector_push_mem_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_pushf_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_ret_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_retf_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_scas_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_scasb_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_setcc_mem_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_setcc_reg_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_test_mem_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_test_mem_b_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_xchg_mem_op = +{ + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_xlat_op = +{ + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t vector_wbinvd_op = +{ + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} +}; + +#define INVALID NULL + +static const risc86_instruction_t *opcode_timings[256] = +{ +/* ADD ADD ADD ADD*/ +/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* ADD ADD PUSH ES POP ES*/ + &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, +/* OR OR OR OR*/ + &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* OR OR PUSH CS */ + &alux_op, &alu_op, &push_seg_op, INVALID, + +/* ADC ADC ADC ADC*/ +/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, +/* ADC ADC PUSH SS POP SS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, +/* SBB SBB SBB SBB*/ +/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, +/* SBB SBB PUSH DS POP DS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + +/* AND AND AND AND*/ +/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* AND AND DAA*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, +/* SUB SUB SUB SUB*/ + &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* SUB SUB DAS*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + +/* XOR XOR XOR XOR*/ +/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* XOR XOR AAA*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, +/* CMP CMP CMP CMP*/ + &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, +/* CMP CMP AAS*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ &store_op, &store_op, &store_op, &store_op, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, +/* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, +/* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, +/* INSB INSW OUTSB OUTSW*/ + &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, + +/* Jxx*/ +/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + &vector_test_mem_b_op, &vector_test_mem_op, &vector_xchg_mem_op, &vector_xchg_mem_op, +/* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, +/* MOV from seg LEA MOV to seg POP*/ + &vector_mov_mem_seg_op, &store_op, &vector_mov_seg_mem_op, &pop_mem_op, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, +/* CBW CWD CALL far WAIT*/ + &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, +/* PUSHF POPF SAHF LAHF*/ + &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, + +/* MOV MOV MOV MOV*/ +/*a0*/ &load_op, &load_op, &store_op, &store_op, +/* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, +/* TEST TEST STOSB STOSW*/ + &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, +/* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, + +/* MOV*/ +/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + +/* RET imm RET*/ +/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, +/* LES LDS MOV MOV*/ + &vector_lss_op, &vector_lss_op, &store_op, &store_op, +/* ENTER LEAVE RETF RETF*/ + &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, +/* INT3 INT INTO IRET*/ + &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, + + +/*d0*/ INVALID, INVALID, INVALID, INVALID, +/* AAM AAD SETALC XLAT*/ + &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, +/* CALL JMP JMP JMP*/ + &store_op, &branch_op, &vector_jmp_far_op, &branch_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + +/* REPNE REPE*/ +/*f0*/ INVALID, INVALID, INVALID, INVALID, +/* HLT CMC*/ + &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, +/* CLC STC CLI STI*/ + &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, +/* CLD STD INCDEC*/ + &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID +}; + +static const risc86_instruction_t *opcode_timings_mod3[256] = +{ +/* ADD ADD ADD ADD*/ +/*00*/ &alux_op, &alu_op, &alux_op, &alu_op, +/* ADD ADD PUSH ES POP ES*/ + &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, +/* OR OR OR OR*/ + &alux_op, &alu_op, &alux_op, &alu_op, +/* OR OR PUSH CS */ + &alux_op, &alu_op, &push_seg_op, INVALID, + +/* ADC ADC ADC ADC*/ +/*10*/ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, +/* ADC ADC PUSH SS POP SS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, +/* SBB SBB SBB SBB*/ + &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, +/* SBB SBB PUSH DS POP DS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + +/* AND AND AND AND*/ +/*20*/ &alux_op, &alu_op, &alux_op, &alu_op, +/* AND AND DAA*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, +/* SUB SUB SUB SUB*/ + &alux_op, &alu_op, &alux_op, &alu_op, +/* SUB SUB DAS*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + +/* XOR XOR XOR XOR*/ +/*30*/ &alux_op, &alu_op, &alux_op, &alu_op, +/* XOR XOR AAA*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, +/* CMP CMP CMP CMP*/ + &alux_op, &alu_op, &alux_op, &alu_op, +/* CMP CMP AAS*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ &store_op, &store_op, &store_op, &store_op, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, +/* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, +/* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, +/* INSB INSW OUTSB OUTSW*/ + &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, + +/* Jxx*/ +/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + &vector_alu1_op, &vector_alu1_op, &vector_alu3_op, &vector_alu3_op, +/* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, +/* MOV from seg LEA MOV to seg POP*/ + &mov_reg_seg_op, &store_op, &vector_mov_seg_reg_op, &pop_reg_op, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, +/* CBW CWD CALL far WAIT*/ + &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, +/* PUSHF POPF SAHF LAHF*/ + &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, + +/* MOV MOV MOV MOV*/ +/*a0*/ &load_op, &load_op, &store_op, &store_op, +/* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, +/* TEST TEST STOSB STOSW*/ + &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, +/* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, + +/* MOV*/ +/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + +/* RET imm RET*/ +/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, +/* LES LDS MOV MOV*/ + &vector_lss_op, &vector_lss_op, &store_op, &store_op, +/* ENTER LEAVE RETF RETF*/ + &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, +/* INT3 INT INTO IRET*/ + &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, + + +/*d0*/ INVALID, INVALID, INVALID, INVALID, +/* AAM AAD SETALC XLAT*/ + &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, +/* CALL JMP JMP JMP*/ + &store_op, &branch_op, &vector_jmp_far_op, &branch_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + +/* REPNE REPE*/ +/*f0*/ INVALID, INVALID, INVALID, INVALID, +/* HLT CMC*/ + &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, +/* CLC STC CLI STI*/ + &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, +/* CLD STD INCDEC*/ + &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID +}; + +static const risc86_instruction_t *opcode_timings_0f[256] = +{ +/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, + &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, + INVALID, &load_op, &vector_femms_op, &load_3dn_op, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + INVALID, INVALID, &mload_op, &mload_op, + +/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &vector_emms_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, &mstore_op, &mstore_op, + +/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*90*/ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + +/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_load_alu_op, + &vector_alu_store_op, &vector_alu_store_op, INVALID, INVALID, + &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_load_alu_op, + &vector_alu_store_op, &vector_alu_store_op, INVALID, &vector_mul_op, + +/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_load_alu_op, + &vector_lss_op, &vector_lss_op, &load_alux_op, &load_alu_op, + INVALID, INVALID, &vector_load_alu_op, &vector_load_alu_op, + &vector_bsx_op, &vector_bsx_op, &load_alux_op, &load_alu_op, + +/*c0*/ &vector_alux_store_op, &vector_alu_store_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + +/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + INVALID, &load_mmx_mul_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + +/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, + INVALID, &pmul_mem_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + +/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + INVALID, &pmul_mem_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, +}; +static const risc86_instruction_t *opcode_timings_0f_mod3[256] = +{ +/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, + &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, + INVALID, INVALID, &vector_femms_op, &m3dn_op, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, + &mmx_op, &mmx_op, &mmx_op, &mmx_op, + &mmx_op, &mmx_op, &mmx_op, &mmx_op, + INVALID, INVALID, &mmx_op, &mmx_op, + +/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + &mmx_op, &mmx_op, &mmx_op, &vector_emms_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, &mmx_op, &mmx_op, + +/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*90*/ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + +/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_alu1_op, + &vector_alu1_op, &vector_alu1_op, INVALID, INVALID, + &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_alu1_op, + &vector_alu1_op, &vector_alu1_op, INVALID, &vector_mul_op, + +/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_alu1_op, + &vector_lss_op, &vector_lss_op, &alux_op, &alu_op, + INVALID, INVALID, &vector_alu1_op, &vector_alu1_op, + &vector_bsx_op, &vector_bsx_op, &alux_op, &alu_op, + +/*c0*/ &vector_alux1_op, &vector_alu1_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + +/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + INVALID, &mmx_mul_op, INVALID, INVALID, + &mmx_op, &mmx_op, INVALID, &mmx_op, + &mmx_op, &mmx_op, INVALID, &mmx_op, + +/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, + INVALID, &pmul_op, INVALID, INVALID, + &mmx_op, &mmx_op, INVALID, &mmx_op, + &mmx_op, &mmx_op, INVALID, &mmx_op, + +/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + INVALID, &pmul_op, INVALID, INVALID, + &mmx_op, &mmx_op, &mmx_op, INVALID, + &mmx_op, &mmx_op, &mmx_op, INVALID, +}; + +static const risc86_instruction_t *opcode_timings_0f0f[256] = +{ +/*00*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &load_3dn_op, INVALID, INVALID, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &load_3dn_op, INVALID, INVALID, + +/*20*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*70*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*80*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*90*/ &load_3dn_op, INVALID, INVALID, INVALID, + &load_3dn_op, INVALID, &load_3dn_op, &load_3dn_op, + INVALID, INVALID, &load_3dn_op, INVALID, + INVALID, INVALID, &load_3dn_op, INVALID, + +/*a0*/ &load_3dn_op, INVALID, INVALID, INVALID, + &load_3dn_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, + INVALID, INVALID, &load_3dn_op, INVALID, + INVALID, INVALID, &load_3dn_op, INVALID, + +/*b0*/ &load_3dn_op, INVALID, INVALID, INVALID, + &load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, &load_mmx_op, + +/*c0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*d0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*e0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*f0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +}; +static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = +{ +/*00*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &m3dn_op, INVALID, INVALID, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &m3dn_op, INVALID, INVALID, + +/*20*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*70*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*80*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*90*/ &m3dn_op, INVALID, INVALID, INVALID, + &m3dn_op, INVALID, &m3dn_op, &m3dn_op, + INVALID, INVALID, &m3dn_op, INVALID, + INVALID, INVALID, &m3dn_op, INVALID, + +/*a0*/ &m3dn_op, INVALID, INVALID, INVALID, + &m3dn_op, INVALID, &mmx_mul_op, &mmx_mul_op, + INVALID, INVALID, &m3dn_op, INVALID, + INVALID, INVALID, &m3dn_op, INVALID, + +/*b0*/ &m3dn_op, INVALID, INVALID, INVALID, + &mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, &mmx_op, + +/*c0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*d0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*e0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*f0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +}; + +static const risc86_instruction_t *opcode_timings_shift[8] = +{ + &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op +}; +static const risc86_instruction_t *opcode_timings_shift_b[8] = +{ + &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, + &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op +}; +static const risc86_instruction_t *opcode_timings_shift_mod3[8] = +{ + &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, + &alu_op, &alu_op, &alu_op, &alu_op +}; +static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = +{ + &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, + &alux_op, &alux_op, &alux_op, &alux_op +}; + +static const risc86_instruction_t *opcode_timings_80[8] = +{ + &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, + &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, +}; +static const risc86_instruction_t *opcode_timings_80_mod3[8] = +{ + &alux_op, &alux_op, &alux_store_op, &alux_store_op, + &alux_op, &alux_op, &alux_op, &alux_op, +}; +static const risc86_instruction_t *opcode_timings_8x[8] = +{ + &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, +}; +static const risc86_instruction_t *opcode_timings_8x_mod3[8] = +{ + &alu_op, &alu_op, &alu_store_op, &alu_store_op, + &alu_op, &alu_op, &alu_op, &alu_op, +}; + +static const risc86_instruction_t *opcode_timings_f6[8] = +{ +/* TST NOT NEG*/ + &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op, +}; +static const risc86_instruction_t *opcode_timings_f6_mod3[8] = +{ +/* TST NOT NEG*/ + &test_reg_b_op, INVALID, &alux_op, &alux_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op, +}; +static const risc86_instruction_t *opcode_timings_f7[8] = +{ +/* TST NOT NEG*/ + &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op, +}; +static const risc86_instruction_t *opcode_timings_f7_mod3[8] = +{ +/* TST NOT NEG*/ + &test_reg_op, INVALID, &alu_op, &alu_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op, +}; +static const risc86_instruction_t *opcode_timings_ff[8] = +{ +/* INC DEC CALL CALL far*/ + &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, +/* JMP JMP far PUSH*/ + &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID +}; +static const risc86_instruction_t *opcode_timings_ff_mod3[8] = +{ +/* INC DEC CALL CALL far*/ + &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, +/* JMP JMP far PUSH*/ + &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID +}; + +static const risc86_instruction_t *opcode_timings_d8[8] = +{ +/* FADDs FMULs FCOMs FCOMPs*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FSUBs FSUBRs FDIVs FDIVRs*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_d8_mod3[8] = +{ +/* FADD FMUL FCOM FCOMP*/ + &float_op, &float_op, &float_op, &float_op, +/* FSUB FSUBR FDIV FDIVR*/ + &float_op, &float_op, &fdiv_op, &fdiv_op, +}; + +static const risc86_instruction_t *opcode_timings_d9[8] = +{ +/* FLDs FSTs FSTPs*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FLDENV FLDCW FSTENV FSTCW*/ + &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op +}; +static const risc86_instruction_t *opcode_timings_d9_mod3[64] = +{ + /*FLD*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, + /*FXCH*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, + /*FNOP*/ + &float_op, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, +/* opFCHS opFABS*/ + &float_op, &float_op, INVALID, INVALID, +/* opFTST opFXAM*/ + &float_op, &float_op, INVALID, INVALID, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + &float_op, &float_op, &float_op, &float_op, +/* opFLDEG2 opFLDLN2 opFLDZ*/ + &float_op, &float_op, &float_op, INVALID, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + &fsin_op, &fsin_op, &fsin_op, &fsin_op, +/* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, &float_op, &float_op, +/* opFPREM opFSQRT opFSINCOS*/ + &fdiv_op, INVALID, &fsqrt_op, &fsin_op, +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + &float_op, &fdiv_op, &fsin_op, &fsin_op +}; + +static const risc86_instruction_t *opcode_timings_da[8] = +{ +/* FIADDl FIMULl FICOMl FICOMPl*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_da_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FCOMPP*/ + INVALID, &float_op, INVALID, INVALID +}; + +static const risc86_instruction_t *opcode_timings_db[8] = +{ +/* FLDil FSTil FSTPil*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FLDe FSTPe*/ + INVALID, &vector_flde_op, INVALID, &vector_fste_op +}; +static const risc86_instruction_t *opcode_timings_db_mod3[64] = +{ + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/* opFNOP opFCLEX opFINIT*/ + INVALID, &float_op, &float_op, &float_op, +/* opFNOP opFNOP*/ + &float_op, &float_op, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +}; + +static const risc86_instruction_t *opcode_timings_dc[8] = +{ +/* FADDd FMULd FCOMd FCOMPd*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FSUBd FSUBRd FDIVd FDIVRd*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_dc_mod3[8] = +{ +/* opFADDr opFMULr*/ + &float_op, &float_op, INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + &float_op, &float_op, &fdiv_op, &fdiv_op +}; + +static const risc86_instruction_t *opcode_timings_dd[8] = +{ +/* FLDd FSTd FSTPd*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FRSTOR FSAVE FSTSW*/ + &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op +}; +static const risc86_instruction_t *opcode_timings_dd_mod3[8] = +{ +/* FFFREE FST FSTP*/ + &float_op, INVALID, &float_op, &float_op, +/* FUCOM FUCOMP*/ + &float_op, &float_op, INVALID, INVALID +}; + +static const risc86_instruction_t *opcode_timings_de[8] = +{ +/* FIADDw FIMULw FICOMw FICOMPw*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_de_mod3[8] = +{ +/* FADDP FMULP FCOMPP*/ + &float_op, &float_op, INVALID, &float_op, +/* FSUBP FSUBRP FDIVP FDIVRP*/ + &float_op, &float_op, &fdiv_op, &fdiv_op, +}; + +static const risc86_instruction_t *opcode_timings_df[8] = +{ +/* FILDiw FISTiw FISTPiw*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FILDiq FBSTP FISTPiq*/ + INVALID, &load_float_op, &vector_float_l_op, &fstore_op, +}; +static const risc86_instruction_t *opcode_timings_df_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FSTSW AX*/ + &float_op, INVALID, INVALID, INVALID +}; + + +static uint8_t last_prefix; + +static int decode_timestamp; +static int last_complete_timestamp; + +typedef struct k6_unit_t +{ + uint32_t uop_mask; + int first_available_cycle; +} k6_unit_t; + +static int nr_units; +static k6_unit_t *units; + +/*K6 has dedicated MMX unit*/ +static k6_unit_t k6_units[] = +{ + {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX)}, /*Integer X*/ + {.uop_mask = (1 << UOP_ALU)}, /*Integer Y*/ + {.uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL)}, /*Multimedia*/ + {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ + {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ + {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ + {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +}; +#define NR_K6_UNITS (sizeof(k6_units) / sizeof(k6_unit_t)) + +/*K6-2 and later integrate MMX into ALU X & Y, sharing multiplier, shifter and + 3DNow ALU between two execution units*/ +static k6_unit_t k6_2_units[] = +{ + {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, + {.uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, + {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ + {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ + {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ + {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +}; +#define NR_K6_2_UNITS (sizeof(k6_2_units) / sizeof(k6_unit_t)) + +/*First available cycles of shared execution units. Each of these can be submitted + to by ALU X and Y*/ +static int mul_first_available_cycle; +static int shift_first_available_cycle; +static int m3dnow_first_available_cycle; + +static int uop_run(const risc86_uop_t *uop, int decode_time) +{ + int c; + k6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; + + /*UOP_LIMM does not require execution*/ + if (uop->type == UOP_LIMM) + return decode_time; + + /*Handle shared units on K6-2 and later*/ + if (units == k6_2_units) + { + if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) + decode_time = mul_first_available_cycle; + else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) + decode_time = shift_first_available_cycle; + else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) + decode_time = m3dnow_first_available_cycle; + } + + /*Find execution unit for this uOP*/ + for (c = 0; c < nr_units; c++) + { + if (units[c].uop_mask & (1 << uop->type)) + { + if (units[c].first_available_cycle < best_start_cycle) + { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } + } + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); + + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; + + if (units == k6_2_units) + { + if (uop->type == UOP_MEU_MUL) + mul_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_SHIFT) + shift_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_3DN) + m3dnow_first_available_cycle = best_start_cycle + uop->throughput; + } + + return best_start_cycle + uop->throughput; +} + +/*The K6 decoder can decode, per clock : + - 1 or 2 'short' instructions, each up to 2 uOPs and 7 bytes long + - 1 'long' instruction, up to 4 uOPs + - 1 'vector' instruction, up to 4 uOPs per cycle, plus (I think) 1 cycle startup delay) +*/ +static struct +{ + int nr_uops; + const risc86_uop_t *uops[4]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[4]; +} decode_buffer; + +#define NR_OPQUADS 6 +/*Timestamps of when the last six opquads completed. The K6 scheduler retires + opquads in order, so this is needed to determine when the next can be scheduled*/ +static int opquad_completion_timestamp[NR_OPQUADS]; +static int next_opquad = 0; + +#define NR_REGS 8 +/*Timestamp of when last operation on an integer register completed*/ +static int reg_available_timestamp[NR_REGS]; +/*Timestamp of when last operation on an FPU register completed*/ +static int fpu_st_timestamp[8]; +/*Completion time of the last uop to be processed. Used to calculate timing of + dependent uop chains*/ +static int last_uop_timestamp = 0; + +void decode_flush() +{ + int c; + int uop_timestamp = 0; + + /*Decoded opquad can not be submitted if there are no free spaces in the + opquad buffer*/ + if (decode_timestamp < opquad_completion_timestamp[next_opquad]) + decode_timestamp = opquad_completion_timestamp[next_opquad]; + + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; + + /*Submit uops to execution units, and determine the latest completion time*/ + for (c = 0; c < decode_buffer.nr_uops; c++) + { + int start_timestamp; + + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; + else + start_timestamp = decode_buffer.earliest_start[c]; + + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } + + /*Calculate opquad completion time. Since opquads complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + /*Advance to next opquad in buffer*/ + opquad_completion_timestamp[next_opquad] = last_complete_timestamp; + next_opquad++; + if (next_opquad == NR_OPQUADS) + next_opquad = 0; + + decode_timestamp++; + decode_buffer.nr_uops = 0; +} + +static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +{ + uint32_t regmask_required; + uint32_t regmask_modified; + int c, d; + int earliest_start = 0; + + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) + { + if (regmask_required & (1 << c)) + { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; + } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if ((deps & FPU_RW_STREG)) + { + int reg = fetchdat & 7; + + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } + + switch (ins->decode_type) + { + case DECODE_SHORT: + if (decode_buffer.nr_uops) + { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + if (ins->nr_uops > 1) + { + decode_buffer.uops[decode_buffer.nr_uops+1] = &ins->uop[1]; + decode_buffer.earliest_start[decode_buffer.nr_uops+1] = -1; + } + decode_buffer.nr_uops += ins->nr_uops; + + decode_flush(); + } + else + { + decode_buffer.nr_uops = ins->nr_uops; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + if (ins->nr_uops > 1) + { + decode_buffer.uops[1] = &ins->uop[1]; + decode_buffer.earliest_start[1] = -1; + } + } + break; + + case DECODE_LONG: + if (decode_buffer.nr_uops) + decode_flush(); + + decode_buffer.nr_uops = ins->nr_uops; + for (c = 0; c < ins->nr_uops; c++) + { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; + else + decode_buffer.earliest_start[c] = -1; + } + decode_flush(); + break; + + case DECODE_VECTOR: + if (decode_buffer.nr_uops) + decode_flush(); + + decode_timestamp++; + d = 0; + + for (c = 0; c < ins->nr_uops; c++) + { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; + + if (d == 4) + { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush(); + } + } + if (d) + { + decode_buffer.nr_uops = d; + decode_flush(); + } + break; + } + + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) + { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) + { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c+1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) + { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c+2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) + { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c+1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) + { + int reg = fetchdat & 7; + if (deps & FPU_POP) + reg--; + if (reg >= 0 && + !(reg == 0 && (deps & FPU_WRITE_ST0)) && + !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } +} + +void codegen_timing_k6_block_start() +{ + int c; + + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; + + mul_first_available_cycle = 0; + shift_first_available_cycle = 0; + m3dnow_first_available_cycle = 0; + + decode_timestamp = 0; + last_complete_timestamp = 0; + + for (c = 0; c < NR_OPQUADS; c++) + opquad_completion_timestamp[c] = 0; + next_opquad = 0; + + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; +} + +void codegen_timing_k6_start() +{ + if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6) + { + units = k6_units; + nr_units = NR_K6_UNITS; + } + else + { + units = k6_2_units; + nr_units = NR_K6_2_UNITS; + } + last_prefix = 0; +} + +void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) +{ + if (prefix != 0x0f) + decode_timestamp++; + + last_prefix = prefix; +} + +void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +{ + const risc86_instruction_t **ins_table; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); + + switch (last_prefix) + { + case 0x0f: + if (opcode == 0x0f) + { + /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ + uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + + if ((modrm & 0xc0) != 0xc0) + { + if (op_32 & 0x200) + { + if ((modrm & 7) == 4) + { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } + else + { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } + else + { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } + + opcode = fastreadb(cs + opcode_pc); + + ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; + deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; + } + else + { + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + } +// pclog("timings 0f\n"); + break; + + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; +// pclog("timings d8\n"); + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings d9\n"); + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; +// pclog("timings da\n"); + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings db\n"); + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; +// pclog("timings dc\n"); + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; +// pclog("timings dd\n"); + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; +// pclog("timings de\n"); + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; +// pclog("timings df\n"); + break; + + default: + switch (opcode) + { + case 0x80: case 0x82: + ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; +// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); + break; + case 0x81: case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + 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 0xd0: case 0xd2: + ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; +// pclog("timings c0\n"); + break; + + case 0xc1: case 0xd1: case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; +// pclog("timings c1\n"); + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f6\n"); + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f7\n"); + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; +// pclog("timings ff\n"); + break; + + default: + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; +// pclog("timings normal\n"); + break; + } + } + + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); +} + +void codegen_timing_k6_block_end() +{ + if (decode_buffer.nr_uops) + decode_flush(); +} + +codegen_timing_t codegen_timing_k6 = +{ + codegen_timing_k6_start, + codegen_timing_k6_prefix, + codegen_timing_k6_opcode, + codegen_timing_k6_block_start, + codegen_timing_k6_block_end +}; diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index 4194e3a..24748cb 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -1075,7 +1075,7 @@ static void codegen_instruction(uint64_t *timings, uint64_t *deps, uint8_t opcod } } -void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { uint64_t *timings; uint64_t *deps; diff --git a/src/codegen_timing_winchip.c b/src/codegen_timing_winchip.c index bdf499e..56ee3af 100644 --- a/src/codegen_timing_winchip.c +++ b/src/codegen_timing_winchip.c @@ -296,7 +296,7 @@ void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; } -void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { int **timings; uint64_t *deps; diff --git a/src/codegen_timing_winchip2.c b/src/codegen_timing_winchip2.c index 0644298..ec47099 100644 --- a/src/codegen_timing_winchip2.c +++ b/src/codegen_timing_winchip2.c @@ -563,7 +563,7 @@ static void codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; } -static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) +static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { uint32_t *timings; uint64_t *deps; diff --git a/src/cpu.c b/src/cpu.c index 1b2e0ef..accff09 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1374,7 +1374,7 @@ void cpu_set() cpu_hasCR4 = 1; cpu_hasVME = 1; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; - codegen_timing_set(&codegen_timing_pentium); + codegen_timing_set(&codegen_timing_k6); break; case CPU_K6_2: @@ -1418,7 +1418,7 @@ void cpu_set() cpu_hasCR4 = 1; cpu_hasVME = 1; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; - codegen_timing_set(&codegen_timing_pentium); + codegen_timing_set(&codegen_timing_k6); break; default: From e26abe7a1f0c970ecdb51f35a6789eed1ec80b0e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 14 Dec 2018 21:59:03 +0000 Subject: [PATCH 0567/1050] Added recompiled versions of 3DNow instructions - PF2ID, PFADD, PFCMPEQ, PFCMPGE, PFCMPGT, PFMAX, PFMIN, PFMUL, PFRCP, PFRCPIT1, PFRCPIT2, PFRSQRT, PFRSQIT1, PFSUB, PFSUBR and PI2FD. --- src/codegen.c | 74 ++++++++++- src/codegen_backend_arm64_ops.c | 69 +++++++++++ src/codegen_backend_arm64_ops.h | 12 ++ src/codegen_backend_arm64_uops.c | 189 ++++++++++++++++++++++++++++ src/codegen_backend_arm_ops.c | 63 ++++++++++ src/codegen_backend_arm_ops.h | 14 +++ src/codegen_backend_arm_uops.c | 189 ++++++++++++++++++++++++++++ src/codegen_backend_x86-64.c | 4 +- src/codegen_backend_x86-64_ops.c | 52 ++++++++ src/codegen_backend_x86-64_ops.h | 19 +++ src/codegen_backend_x86-64_uops.c | 198 ++++++++++++++++++++++++++++++ src/codegen_backend_x86_ops.c | 49 +++++++- src/codegen_backend_x86_ops.h | 17 +++ src/codegen_backend_x86_uops.c | 198 ++++++++++++++++++++++++++++++ src/codegen_ir_defs.h | 40 +++++- src/codegen_ops.c | 25 ++++ src/codegen_ops.h | 1 + src/codegen_ops_3dnow.c | 193 +++++++++++++++++++++++++++++ src/codegen_ops_3dnow.h | 15 +++ 19 files changed, 1412 insertions(+), 9 deletions(-) create mode 100644 src/codegen_ops_3dnow.c create mode 100644 src/codegen_ops_3dnow.h diff --git a/src/codegen.c b/src/codegen.c index f42f22c..a278cfe 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -306,10 +306,12 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t RecompOpFn *recomp_op_table = recomp_opcodes; int opcode_shift = 0; int opcode_mask = 0x3ff; + uint32_t recomp_opcode_mask = 0x1ff; uint32_t op_32 = use32; int over = 0; int test_modrm = 1; int pc_off = 0; + uint32_t next_pc = 0; #ifdef DEBUG_EXTRA uint8_t last_prefix = 0; #endif @@ -507,10 +509,68 @@ generate_call: (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) codegen_accumulate_flush(ir); -// pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) + + if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](block, ir, opcode, fetchdat, op_32, op_pc); + /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + uint32_t opcode_pc = op_pc + 1; + uint8_t opcode_3dnow; + + if ((modrm & 0xc0) != 0xc0) + { + if (op_32 & 0x200) + { + if ((modrm & 7) == 4) + { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } + else + { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } + else + { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } + + opcode_3dnow = fastreadb(cs + opcode_pc); +// pclog("recomp_opcodes_3DNOW[%02x]=%p\n", opcode, recomp_opcodes_3DNOW[opcode]); + if (recomp_opcodes_3DNOW[opcode_3dnow]) + { + next_pc = opcode_pc + 1; + + op_table = x86_dynarec_opcodes_3DNOW; + recomp_op_table = recomp_opcodes_3DNOW; + opcode = opcode_3dnow; + recomp_opcode_mask = 0xff; + opcode_mask = 0xff; + } + } +// pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) + { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); if (new_pc) { if (new_pc != -1) @@ -532,7 +592,8 @@ generate_call: if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) + (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || + (op_table == x86_dynarec_opcodes_3DNOW)) { int stack_offset = 0; @@ -564,7 +625,10 @@ generate_call: uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); #endif - uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); + if (op_table == x86_dynarec_opcodes_3DNOW) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); uop_MOV_IMM(ir, IREG_oldpc, old_pc); if (op_32 != last_op_32) uop_MOV_IMM(ir, IREG_op32, op_32); diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index ee2c0b6..7d71d31 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -119,9 +119,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_CMGT_V8B (0x0e203400) #define OPCODE_CMGT_V4H (0x0e603400) #define OPCODE_CMGT_V2S (0x0ea03400) +#define OPCODE_DUP_V2S (0x0e040400) #define OPCODE_EOR_V (0x2e201c00) #define OPCODE_FABS_D (0x1e60c000) #define OPCODE_FADD_D (0x1e602800) +#define OPCODE_FADD_V2S (0x0e20d400) +#define OPCODE_FCMEQ_V2S (0x0e20e400) +#define OPCODE_FCMGE_V2S (0x2e20e400) +#define OPCODE_FCMGT_V2S (0x2ea0e400) #define OPCODE_FCMP_D (0x1e602000) #define OPCODE_FCVT_D_S (0x1e22c000) #define OPCODE_FCVT_S_D (0x1e624000) @@ -133,17 +138,25 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_FCVTPS_X_D (0x9e680000) #define OPCODE_FCVTZS_W_D (0x1e780000) #define OPCODE_FCVTZS_X_D (0x9e780000) +#define OPCODE_FCVTZS_V2S (0x0ea1b800) #define OPCODE_FDIV_D (0x1e601800) +#define OPCODE_FDIV_S (0x1e201800) +#define OPCODE_FMAX_V2S (0x0e20f400) +#define OPCODE_FMIN_V2S (0x0ea0f400) #define OPCODE_FMOV_D_D (0x1e604000) #define OPCODE_FMOV_D_Q (0x9e670000) #define OPCODE_FMOV_Q_D (0x9e660000) #define OPCODE_FMOV_S_W (0x1e270000) #define OPCODE_FMOV_W_S (0x1e260000) +#define OPCODE_FMOV_S_ONE (0x1e2e1000) #define OPCODE_FMUL_D (0x1e600800) +#define OPCODE_FMUL_V2S (0x2e20dc00) #define OPCODE_FNEG_D (0x1e614000) #define OPCODE_FRINTX_D (0x1e674000) #define OPCODE_FSQRT_D (0x1e61c000) +#define OPCODE_FSQRT_S (0x1e21c000) #define OPCODE_FSUB_D (0x1e603800) +#define OPCODE_FSUB_V2S (0x0ea0d400) #define OPCODE_LDR_REG (0xb8606800) #define OPCODE_LDRX_REG (0xf8606800) #define OPCODE_LDRB_REG (0x38606800) @@ -227,6 +240,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define SHRN_SHIFT_IMM_V4S(shift) (((shift) | 0x10) << 16) +#define DUP_ELEMENT(element) ((element) << 19) + static int literal_offset = 0; void codegen_reset_literal_pool(codeblock_t *block) { @@ -662,6 +677,11 @@ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_ codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) +{ + codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ @@ -692,6 +712,22 @@ void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m { codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) { @@ -739,21 +775,46 @@ void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); +} void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } +void host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) { @@ -775,6 +836,10 @@ void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) +{ + codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); +} void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) { @@ -790,6 +855,10 @@ void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); +} void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 048c354..a8c3fc2 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -71,6 +71,8 @@ void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element); + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); @@ -78,10 +80,17 @@ void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg); void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg); @@ -94,16 +103,19 @@ void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg); void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index c7729af..703a7e5 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1682,6 +1682,182 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); + } + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm_FMOV_S_ONE(block, REG_D_TEMP); + host_arm_FDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); + host_arm_DUP_V2S(block, dest_reg, dest_reg, 0); + } + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm_FSQRT_S(block, REG_D_TEMP, src_reg_a); + host_arm_FMOV_S_ONE(block, REG_D_TEMP); + host_arm_FDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); + host_arm_DUP_V2S(block, dest_reg, dest_reg, 0); + } + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); + } + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2629,6 +2805,19 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 12e9c68..85ffd9d 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -91,11 +91,15 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VADD_I8 0xf2000800 #define OPCODE_VADD_I16 0xf2100800 #define OPCODE_VADD_I32 0xf2200800 +#define OPCODE_VADD_F32 0xf2000d00 #define OPCODE_VAND_D 0xf2000110 #define OPCODE_VBIC_D 0xf2100110 +#define OPCODE_VCEQ_F32 0xf2000e00 #define OPCODE_VCEQ_I8 0xf3000810 #define OPCODE_VCEQ_I16 0xf3100810 #define OPCODE_VCEQ_I32 0xf3200810 +#define OPCODE_VCGE_F32 0xf3000e00 +#define OPCODE_VCGT_F32 0xf3200e00 #define OPCODE_VCGT_S8 0xf2000300 #define OPCODE_VCGT_S16 0xf2100300 #define OPCODE_VCGT_S32 0xf2200300 @@ -103,12 +107,17 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VCVT_D_IS 0xeeb80bc0 #define OPCODE_VCVT_D_S 0xeeb70ac0 #define OPCODE_VCVT_IS_D 0xeebd0bc0 +#define OPCODE_VCVT_S32_F32 0xf3bb0680 #define OPCODE_VCVT_S_D 0xeeb70bc0 #define OPCODE_VCVTR_IS_D 0xeebd0b40 #define OPCODE_VDIV 0xee800b00 +#define OPCODE_VDIV_S 0xee800a00 +#define OPCODE_VDUP_32 0xf3b40c00 #define OPCODE_VEOR_D 0xf3000110 #define OPCODE_VLDR_D 0xed900b00 #define OPCODE_VLDR_S 0xed900a00 +#define OPCODE_VMAX_F32 0xf200f00 +#define OPCODE_VMIN_F32 0xf220f00 #define OPCODE_VMOV_32_S 0xee100a10 #define OPCODE_VMOV_64_D 0xec500b10 #define OPCODE_VMOV_D_64 0xec400b10 @@ -116,9 +125,11 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VMOV_D_D 0xeeb00b40 #define OPCODE_VMOVN_I32 0xf3b60200 #define OPCODE_VMOVN_I64 0xf3ba0200 +#define OPCODE_VMOV_F32_ONE 0xf2870f10 #define OPCODE_VMRS_APSR 0xeef1fa10 #define OPCODE_VMSR_FPSCR 0xeee10a10 #define OPCODE_VMUL 0xee200b00 +#define OPCODE_VMUL_F32 0xf3000d10 #define OPCODE_VMUL_S16 0xf2100910 #define OPCODE_VMULL_S16 0xf2900c00 #define OPCODE_VNEG_D 0xeeb10b40 @@ -148,6 +159,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VSHR_D_U64 0xf3800090 #define OPCODE_VSHRN 0xf2800810 #define OPCODE_VSQRT_D 0xeeb10bc0 +#define OPCODE_VSQRT_S 0xeeb10ac0 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 @@ -193,6 +205,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) +#define VDUP_32_IMM(imm) ((imm) << 19) + static inline uint32_t arm_data_offset(int offset) { if (offset < -0xffc || offset > 0xffc) @@ -808,6 +822,10 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -833,6 +851,10 @@ void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); } +void host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -845,6 +867,14 @@ void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_r { codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -870,6 +900,10 @@ void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); @@ -882,6 +916,14 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) +{ + codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); +} void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -926,6 +968,10 @@ void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(src_reg)); +} void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); @@ -935,10 +981,23 @@ void host_arm_VMRS_APSR(codeblock_t *block) codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); } +void host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} + void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); @@ -1082,6 +1141,10 @@ void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index b7877df..3c2ae77 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -145,13 +145,17 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m); +void host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); @@ -161,9 +165,11 @@ void host_arm_VCHS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -179,7 +185,13 @@ void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VMRS_APSR(codeblock_t *block); void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); +void host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); + +void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg); + void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VMUL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); @@ -216,10 +228,12 @@ void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shif void host_arm_VSHRN_32(codeblock_t *block, int dest_reg, int src_reg, int shift); void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VSUB_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 8ceebbc..1a5d4e2 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1806,6 +1806,182 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); + } + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); + } + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_arm_VCVT_Q_F32_IS(block, dest_reg, src_reg_a); + } + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2775,6 +2951,19 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 631402a..4cdf2b4 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -206,7 +206,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_PUSH(block, REG_RAX); host_x86_PUSH(block, REG_RDX); #if WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); if (size == 4 && is_float) host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data else if (size == 8) @@ -227,7 +227,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) else if (size == 8) host_x86_CALL(block, (void *)writememql); #if WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); #endif host_x86_POP(block, REG_RDX); host_x86_POP(block, REG_RAX); diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 04d0080..f077960 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -212,6 +212,10 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ +} void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); @@ -341,11 +345,25 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +{ + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ +} + void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ +} +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ +} + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ @@ -364,6 +382,10 @@ void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ @@ -384,6 +406,10 @@ void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} void host_x86_JMP(codeblock_t *block, void *p) { @@ -1216,6 +1242,19 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); } +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ +} +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ +} + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ +} void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); @@ -1635,6 +1674,10 @@ void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ } +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { @@ -1714,6 +1757,10 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); @@ -1751,6 +1798,11 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); +} + void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index a86e3ed..ea2eede 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -7,6 +7,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); @@ -27,17 +28,27 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +#define CMPPS_EQ 0 +#define CMPPS_NLT 5 +#define CMPPS_NLE 6 +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); + void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_JMP(codeblock_t *block, void *p); @@ -146,7 +157,11 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); @@ -240,6 +255,7 @@ void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); @@ -250,6 +266,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); @@ -257,6 +274,8 @@ void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg); void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 4955609..ad11134 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1569,6 +1569,191 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + } + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2384,6 +2569,19 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index a861d14..97ba65f 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -185,6 +185,10 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ +} void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); @@ -309,11 +313,25 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +{ + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ +} + void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ +} +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ +} + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ @@ -327,6 +345,10 @@ void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { @@ -340,7 +362,11 @@ void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ +} +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ } void host_x86_INC32_ABS(codeblock_t *block, void *p) @@ -1024,6 +1050,19 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ } +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ +} +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ +} + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ +} void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); @@ -1406,6 +1445,10 @@ void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ } +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { @@ -1476,6 +1519,10 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index d07b0d9..22a8746 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -8,6 +8,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); @@ -27,17 +28,27 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); +#define CMPPS_EQ 0 +#define CMPPS_NLT 5 +#define CMPPS_NLE 6 +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); + void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg); +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dest_reg, int src_reg); void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_INC32_ABS(codeblock_t *block, void *p); @@ -148,6 +159,10 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); @@ -242,6 +257,7 @@ void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); @@ -251,6 +267,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 67f28d4..e53b91d 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1572,6 +1572,191 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + } + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) + { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2394,6 +2579,19 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 2a2733e..aa95c06 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -281,7 +281,32 @@ /*UOP_PMADDWD - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ #define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) -#define UOP_MAX 0xba +/*UOP_PFADD - (packed float) dest_reg = src_reg_a + src_reg_b*/ +#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) +/*UOP_PFSUB - (packed float) dest_reg = src_reg_a - src_reg_b*/ +#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) +/*UOP_PFMUL - (packed float) dest_reg = src_reg_a * src_reg_b*/ +#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) +/*UOP_PFMAX - (packed float) dest_reg = MAX(src_reg_a, src_reg_b)*/ +#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) +/*UOP_PFMIN - (packed float) dest_reg = MIN(src_reg_a, src_reg_b)*/ +#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) +/*UOP_PFCMPEQ - (packed float) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ +#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) +/*UOP_PFCMPGE - (packed float) dest_reg = (src_reg_a >= src_reg_b) ? ~0 : 0*/ +#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) +/*UOP_PFCMPGT - (packed float) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ +#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) +/*UOP_PF2ID - (packed long)dest_reg = (packed float)src_reg_a*/ +#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) +/*UOP_PI2FD - (packed float)dest_reg = (packed long)src_reg_a*/ +#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) +/*UOP_PFRCP - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / src_reg[0]*/ +#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) +/*UOP_PFRSQRT - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / sqrt(src_reg[0])*/ +#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) + +#define UOP_MAX 0xc6 #define UOP_MASK 0xffff @@ -645,6 +670,19 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) +#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPEQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPEQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPGE(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGE, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPGT(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGT, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) +#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) +#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) + #define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 10b19d2..a339224 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -2,6 +2,7 @@ #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" +#include "codegen_ops_3dnow.h" #include "codegen_ops_arith.h" #include "codegen_ops_branch.h" #include "codegen_ops_fpu_arith.h" @@ -116,6 +117,30 @@ RecompOpFn recomp_opcodes_0f[512] = /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, }; +RecompOpFn recomp_opcodes_3DNOW[256] = +{ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPI2FD, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPF2ID, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropPFCMPGE, NULL, NULL, NULL, ropPFMIN, NULL, ropPFRCP, ropPFRSQRT, NULL, NULL, ropPFSUB, NULL, NULL, NULL, ropPFADD, NULL, +/*a0*/ ropPFCMPGT, NULL, NULL, NULL, ropPFMAX, NULL, ropPFRCPIT, ropPFRSQIT1, NULL, NULL, ropPFSUBR, NULL, NULL, NULL, NULL, NULL, +/*b0*/ ropPFCMPEQ, NULL, NULL, NULL, ropPFMUL, NULL, ropPFRCPIT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + RecompOpFn recomp_opcodes_d8[512] = { /*16-bit data*/ diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 6e86be6..64f3547 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -9,6 +9,7 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; +extern RecompOpFn recomp_opcodes_3DNOW[256]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; diff --git a/src/codegen_ops_3dnow.c b/src/codegen_ops_3dnow.c new file mode 100644 index 0000000..ad846e4 --- /dev/null +++ b/src/codegen_ops_3dnow.c @@ -0,0 +1,193 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_3dnow.h" +#include "codegen_ops_helpers.h" + +#define ropParith(func) \ +uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ +{ \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + if ((fetchdat & 0xc0) == 0xc0) \ + { \ + int src_reg = fetchdat & 7; \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } \ + else \ + { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 2; \ +} + +ropParith(PFADD) +ropParith(PFCMPEQ) +ropParith(PFCMPGE) +ropParith(PFCMPGT) +ropParith(PFMAX) +ropParith(PFMIN) +ropParith(PFMUL) +ropParith(PFSUB) + +uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 2; +} + +uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); + } + + return op_pc + 2; +} + +uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 2; +} + +uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 2; +} +uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 2; +} +uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 2; +} + +uint32_t ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MMX_ENTER(ir); + + return op_pc + 2; +} diff --git a/src/codegen_ops_3dnow.h b/src/codegen_ops_3dnow.h new file mode 100644 index 0000000..3b124ae --- /dev/null +++ b/src/codegen_ops_3dnow.h @@ -0,0 +1,15 @@ +uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFCMPEQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFCMPGE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFCMPGT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFMAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFMIN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); From e8483acea54e98a76a87cabee330e5dc4a8be016 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Dec 2018 19:36:54 +0000 Subject: [PATCH 0568/1050] Search through all host integer and FP registers when allocating registers. --- src/codegen_reg.c | 83 ++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 7d993fd..255fde7 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -214,6 +214,11 @@ static inline int ir_reg_is_invalid(ir_reg_t ir_reg) return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } +static inline int ir_get_get_refcount(ir_reg_t ir_reg) +{ + return reg_version_refcount[IREG_GET_REG(ir_reg.reg)][ir_reg.version]; +} + static inline host_reg_set_t *get_reg_set(ir_reg_t ir_reg) { if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) @@ -401,9 +406,45 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i reg_set->dirty[c] = 0; } +static void alloc_reg(ir_reg_t ir_reg) +{ + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; + + for (c = 0; c < nr_regs; c++) + { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) + { + if (reg_set->regs[c].version != ir_reg.version) + fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); + reg_set->locked |= (1 << c); + return; + } + } +} + +static void alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) +{ + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; + + for (c = 0; c < nr_regs; c++) + { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) + { + if (reg_set->regs[c].version == ir_reg.version || (reg_set->regs[c].version == (ir_reg.version-1) && reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] == dest_reference)) + reg_set->locked |= (1 << c); + else + fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); + return; + } + } +} + void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) { - int c; int dest_reference = 0; host_reg_set.locked = 0; @@ -422,38 +463,14 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version-1) dest_reference++; } - for (c = 0; c < CODEGEN_HOST_REGS; c++) - { - host_reg_set_t *reg_set = get_reg_set(src_reg_a); - if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src_reg_a.reg)) - { - if (reg_set->regs[c].version != src_reg_a.version) - fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_a.version\n"); - reg_set->locked |= (1 << c); - } - reg_set = get_reg_set(src_reg_b); - if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src_reg_b.reg)) - { - if (reg_set->regs[c].version != src_reg_b.version) - fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_b.version\n"); - reg_set->locked |= (1 << c); - } - reg_set = get_reg_set(src_reg_c); - if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src_reg_c.reg)) - { - if (reg_set->regs[c].version != src_reg_c.version) - fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_c.version\n"); - reg_set->locked |= (1 << c); - } - reg_set = get_reg_set(dest_reg_a); - if (!ir_reg_is_invalid(dest_reg_a) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dest_reg_a.reg)) - { - if (reg_set->regs[c].version == dest_reg_a.version || (reg_set->regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] == dest_reference)) - reg_set->locked |= (1 << c); - else - fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, dest_reg_a.version, dest_reference); - } - } + if (!ir_reg_is_invalid(src_reg_a)) + alloc_reg(src_reg_a); + if (!ir_reg_is_invalid(src_reg_b)) + alloc_reg(src_reg_b); + if (!ir_reg_is_invalid(src_reg_c)) + alloc_reg(src_reg_c); + if (!ir_reg_is_invalid(dest_reg_a)) + alloc_dest_reg(dest_reg_a, dest_reference); } ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) From b26432caa8ea399d81a5f88835293d012d4f2010 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Dec 2018 19:40:09 +0000 Subject: [PATCH 0569/1050] When allocating a read register, prioritise registers that will not be used again. --- src/codegen_reg.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 255fde7..c222d04 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -490,20 +490,29 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in if (c == reg_set->nr_regs) { - /*No unused registers. Search for an unlocked register*/ + /*No unused registers. Search for an unlocked register with no pending reads*/ for (c = 0; c < reg_set->nr_regs; c++) { - if (!(reg_set->locked & (1 << c))) + if (!(reg_set->locked & (1 << c)) && !ir_get_get_refcount(reg_set->regs[c])) break; } if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_read_reg - out of registers\n"); + { + /*Search for any unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) + { + if (!(reg_set->locked & (1 << c))) + break; + } + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_read_reg - out of registers\n"); + } if (reg_set->dirty[c]) codegen_reg_writeback(reg_set, block, c, 1); // pclog(" load %i\n", c); codegen_reg_load(reg_set, block, c, ir_reg); - reg_set->locked |= (1 << c); // fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); + reg_set->locked |= (1 << c); // codegen_reg_writeback(block, c); reg_set->dirty[c] = 0; } From 93a5925f027ce5a4bd94f6411302df0041c24b44 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Dec 2018 22:23:59 +0000 Subject: [PATCH 0570/1050] Use MOVZX on x86-64 when loading a word sized function parameter. Fixes issues when built with LLVM and -O3. --- src/codegen_backend_x86-64_uops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index ad11134..049c626 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -771,9 +771,9 @@ static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) if (REG_IS_W(src_size)) { #if WIN64 - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); #else - host_x86_MOV16_REG_REG(block, REG_EDI, src_reg); + host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); #endif } else From c86b919ed85c67336cf1bec3d2f2fc3a8abde7ab Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Dec 2018 22:24:40 +0000 Subject: [PATCH 0571/1050] Fix writemem functions on x86-64 when !WIN64. --- src/codegen_backend_x86-64.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 4cdf2b4..22385dd 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -215,8 +215,14 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address #else + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); //host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address - host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); //data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); //data + else + host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data #endif if (size == 1) host_x86_CALL(block, (void *)writememb386l); @@ -228,6 +234,8 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_CALL(block, (void *)writememql); #if WIN64 host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); +#else + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); #endif host_x86_POP(block, REG_RDX); host_x86_POP(block, REG_RAX); From 1953f4afb9388b02a7eb41699589b87756b8ff43 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 19 Dec 2018 22:25:47 +0000 Subject: [PATCH 0572/1050] Use mmap() to allocate codeblock memory on x86-64 when not running on Windows. --- src/codegen_backend_x86-64.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 22385dd..5de8f75 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -286,7 +286,7 @@ void codegen_backend_init() #if defined WIN32 || defined _WIN32 || defined _WIN32 codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE); + codeblock_data = mmap(0, BLOCK_SIZE * BLOCK_DATA_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); #endif codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -299,16 +299,6 @@ void codegen_backend_init() codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; } - -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock & pagemask); - len = ((BLOCK_SIZE * sizeof(codeblock_t)) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); block_current = 0; From 3c7d1b1204fe3e2e692ec7c2586725c4829c83a5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 6 Jan 2019 13:46:17 +0000 Subject: [PATCH 0573/1050] Ensure that taken jump/branch instructions do not count as 0 cycles. Fixes Windows 95 hang with K6. --- src/codegen.c | 15 +++++++++++++++ src/codegen.h | 2 ++ src/codegen_timing_486.c | 8 +++++++- src/codegen_timing_686.c | 8 +++++++- src/codegen_timing_k6.c | 10 +++++++++- src/codegen_timing_pentium.c | 8 +++++++- src/codegen_timing_winchip.c | 8 +++++++- src/codegen_timing_winchip2.c | 8 +++++++- 8 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index a278cfe..653834c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -21,6 +21,7 @@ void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); void (*codegen_timing_block_start)(); void (*codegen_timing_block_end)(); +int (*codegen_timing_jump_cycles)(); void codegen_timing_set(codegen_timing_t *timing) { @@ -29,6 +30,7 @@ void codegen_timing_set(codegen_timing_t *timing) codegen_timing_opcode = timing->opcode; codegen_timing_block_start = timing->block_start; codegen_timing_block_end = timing->block_end; + codegen_timing_jump_cycles = timing->jump_cycles; } int codegen_in_recompile; @@ -508,7 +510,20 @@ generate_call: (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))) + { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = codegen_timing_jump_cycles(); + + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, -jump_cycles); codegen_accumulate_flush(ir); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, jump_cycles); + } if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) { diff --git a/src/codegen.h b/src/codegen.h index e82b904..e0e8760 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -320,6 +320,7 @@ extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); extern void (*codegen_timing_block_start)(); extern void (*codegen_timing_block_end)(); +extern int (*codegen_timing_jump_cycles)(); typedef struct codegen_timing_t { @@ -328,6 +329,7 @@ typedef struct codegen_timing_t void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); void (*block_start)(); void (*block_end)(); + int (*jump_cycles)(); } codegen_timing_t; extern codegen_timing_t codegen_timing_pentium; diff --git a/src/codegen_timing_486.c b/src/codegen_timing_486.c index cda0436..6f9e3af 100644 --- a/src/codegen_timing_486.c +++ b/src/codegen_timing_486.c @@ -422,11 +422,17 @@ void codegen_timing_486_block_end() { } +int codegen_timing_486_jump_cycles() +{ + return 0; +} + codegen_timing_t codegen_timing_486 = { codegen_timing_486_start, codegen_timing_486_prefix, codegen_timing_486_opcode, codegen_timing_486_block_start, - codegen_timing_486_block_end + codegen_timing_486_block_end, + codegen_timing_486_jump_cycles }; diff --git a/src/codegen_timing_686.c b/src/codegen_timing_686.c index dab2b10..cc1e119 100644 --- a/src/codegen_timing_686.c +++ b/src/codegen_timing_686.c @@ -1067,11 +1067,17 @@ void codegen_timing_686_block_end() } } +int codegen_timing_686_jump_cycles() +{ + return 0; +} + codegen_timing_t codegen_timing_686 = { codegen_timing_686_start, codegen_timing_686_prefix, codegen_timing_686_opcode, codegen_timing_686_block_start, - codegen_timing_686_block_end + codegen_timing_686_block_end, + codegen_timing_686_jump_cycles }; diff --git a/src/codegen_timing_k6.c b/src/codegen_timing_k6.c index a5d0cde..78d9678 100644 --- a/src/codegen_timing_k6.c +++ b/src/codegen_timing_k6.c @@ -2278,11 +2278,19 @@ void codegen_timing_k6_block_end() decode_flush(); } +int codegen_timing_k6_jump_cycles() +{ + if (decode_buffer.nr_uops) + return 1; + return 0; +} + codegen_timing_t codegen_timing_k6 = { codegen_timing_k6_start, codegen_timing_k6_prefix, codegen_timing_k6_opcode, codegen_timing_k6_block_start, - codegen_timing_k6_block_end + codegen_timing_k6_block_end, + codegen_timing_k6_jump_cycles }; diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index 24748cb..f21a70f 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -1328,11 +1328,17 @@ void codegen_timing_pentium_block_end() } } +int codegen_timing_pentium_jump_cycles() +{ + return 0; +} + codegen_timing_t codegen_timing_pentium = { codegen_timing_pentium_start, codegen_timing_pentium_prefix, codegen_timing_pentium_opcode, codegen_timing_pentium_block_start, - codegen_timing_pentium_block_end + codegen_timing_pentium_block_end, + codegen_timing_pentium_jump_cycles }; diff --git a/src/codegen_timing_winchip.c b/src/codegen_timing_winchip.c index 56ee3af..c23b30b 100644 --- a/src/codegen_timing_winchip.c +++ b/src/codegen_timing_winchip.c @@ -422,11 +422,17 @@ void codegen_timing_winchip_block_end() { } +int codegen_timing_winchip_jump_cycles() +{ + return 0; +} + codegen_timing_t codegen_timing_winchip = { codegen_timing_winchip_start, codegen_timing_winchip_prefix, codegen_timing_winchip_opcode, codegen_timing_winchip_block_start, - codegen_timing_winchip_block_end + codegen_timing_winchip_block_end, + codegen_timing_winchip_jump_cycles }; diff --git a/src/codegen_timing_winchip2.c b/src/codegen_timing_winchip2.c index ec47099..c85a0e9 100644 --- a/src/codegen_timing_winchip2.c +++ b/src/codegen_timing_winchip2.c @@ -743,11 +743,17 @@ static void codegen_timing_winchip2_block_end() } } +int codegen_timing_winchip2_jump_cycles() +{ + return 0; +} + codegen_timing_t codegen_timing_winchip2 = { codegen_timing_winchip2_start, codegen_timing_winchip2_prefix, codegen_timing_winchip2_opcode, codegen_timing_winchip2_block_start, - codegen_timing_winchip2_block_end + codegen_timing_winchip2_block_end, + codegen_timing_winchip2_jump_cycles }; From 8ee9b07ab227055eb805ada0452e9f14873ce65b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 6 Jan 2019 14:23:23 +0000 Subject: [PATCH 0574/1050] Added decoder length limitations to K6 timing model --- src/codegen_timing_common.c | 16 ++++----- src/codegen_timing_common.h | 3 ++ src/codegen_timing_k6.c | 66 +++++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/codegen_timing_common.c b/src/codegen_timing_common.c index 33ac5cf..c29f24f 100644 --- a/src/codegen_timing_common.c +++ b/src/codegen_timing_common.c @@ -823,21 +823,21 @@ uint64_t opcode_deps_df_mod3[8] = uint64_t opcode_deps_81[8] = { - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM + MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, + MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632 }; uint64_t opcode_deps_81_mod3[8] = { - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632 }; uint64_t opcode_deps_8x[8] = { - MODRM, MODRM, MODRM, MODRM, - MODRM, MODRM, MODRM, MODRM + MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, + MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8 }; uint64_t opcode_deps_8x_mod3[8] = { - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, - SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8 }; diff --git a/src/codegen_timing_common.h b/src/codegen_timing_common.h index b185270..533a135 100644 --- a/src/codegen_timing_common.h +++ b/src/codegen_timing_common.h @@ -72,6 +72,9 @@ #define FPU_FXCH (1ull << 33) +#define HAS_IMM8 (1ull << 34) +#define HAS_IMM1632 (1ull << 35) + #define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) diff --git a/src/codegen_timing_k6.c b/src/codegen_timing_k6.c index 78d9678..590e605 100644 --- a/src/codegen_timing_k6.c +++ b/src/codegen_timing_k6.c @@ -1723,6 +1723,7 @@ static const risc86_instruction_t *opcode_timings_df_mod3[8] = static uint8_t last_prefix; +static int prefixes; static int decode_timestamp; static int last_complete_timestamp; @@ -1899,12 +1900,64 @@ void decode_flush() decode_buffer.nr_uops = 0; } +/*The instruction is only of interest here if it's longer than 7 bytes, as that's the + limit on K6 short decoding*/ +static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +{ + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) + { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_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; +} + static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) { uint32_t regmask_required; uint32_t regmask_modified; int c, d; int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); /*Generate input register mask, and determine the earliest time this instruction can start. This is not accurate, as this is calculated per @@ -1931,7 +1984,14 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u earliest_start = fpu_st_timestamp[reg]; } - switch (ins->decode_type) + /*Short decoders are limited to 7 bytes*/ + if (decode_type == DECODE_SHORT && instr_length > 7) + decode_type = DECODE_LONG; + /*Long decoder is limited to 11 bytes*/ + else if (instr_length > 11) + decode_type = DECODE_VECTOR; + + switch (decode_type) { case DECODE_SHORT: if (decode_buffer.nr_uops) @@ -2051,7 +2111,7 @@ static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, u void codegen_timing_k6_block_start() { int c; - + for (c = 0; c < nr_units; c++) units[c].first_available_cycle = 0; @@ -2085,6 +2145,7 @@ void codegen_timing_k6_start() nr_units = NR_K6_2_UNITS; } last_prefix = 0; + prefixes = 0; } void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) @@ -2093,6 +2154,7 @@ void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) decode_timestamp++; last_prefix = prefix; + prefixes++; } void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) From 56a4d5cf83a046febd60c2932bdfcffc191f032f Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 10 Jan 2019 21:33:29 +0000 Subject: [PATCH 0575/1050] Use correct rounding mode on x86 and x86-64 recompiled versions of PF2ID. Fixes rendering errors on Unreal 3DNow! software renderer --- src/codegen_backend_x86-64.c | 1 + src/codegen_backend_x86-64_ops.c | 5 +++++ src/codegen_backend_x86-64_uops.c | 2 ++ src/codegen_backend_x86.c | 1 + src/codegen_backend_x86_uops.c | 2 ++ src/ibm.h | 3 +++ 6 files changed, 14 insertions(+) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 5de8f75..29ca83a 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -310,6 +310,7 @@ void codegen_backend_init() "stmxcsr %0\n" : "=m" (cpu_state.old_fp_control) ); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } void codegen_set_rounding_mode(int mode) diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index f077960..0992683 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -541,6 +541,11 @@ void host_x86_LDMXCSR(codeblock_t *block, void *p) { codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ } + else if (offset < (1ull << 32)) + { + codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ + codegen_addlong(block, offset); + } else { fatal("host_x86_LDMXCSR - out of range %p\n", p); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 049c626..dd164d6 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1576,7 +1576,9 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); } else fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 4a43ff0..82c1d87 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -333,6 +333,7 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); : "=m" (cpu_state.old_fp_control2), "=m" (cpu_state.old_fp_control) ); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } void codegen_set_rounding_mode(int mode) diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index e53b91d..aa1c885 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1579,7 +1579,9 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); } else fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); diff --git a/src/ibm.h b/src/ibm.h index e99c232..b587e62 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -181,6 +181,9 @@ struct uint32_t old_fp_control, new_fp_control; #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ uint16_t old_fp_control2, new_fp_control2; +#endif +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ + uint32_t trunc_fp_control; #endif x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; From 66fba50e063f2b6ca4eaf19c12a161aa53cee448 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 15:15:43 +0000 Subject: [PATCH 0576/1050] Add new codegen memory allocator. This allows the recompiler to allocate memory from a central pool as required. This central pool is by default 64 MB on x86, x86-64 and ARMv8, and 32 MB on ARMv7. The current design does not allow for ARMv8 literal pools, therefore these have been removed. --- src/codegen.c | 1 + src/codegen.h | 12 +- src/codegen_backend.c | 32 +- src/codegen_backend.h | 39 --- src/codegen_backend_arm.c | 49 +-- src/codegen_backend_arm.h | 12 +- src/codegen_backend_arm64.c | 113 +++---- src/codegen_backend_arm64.h | 12 +- src/codegen_backend_arm64_ops.c | 230 ++++++++------ src/codegen_backend_arm64_ops.h | 7 +- src/codegen_backend_arm64_uops.c | 14 +- src/codegen_backend_arm_ops.c | 96 ++++-- src/codegen_backend_arm_ops.h | 2 + src/codegen_backend_arm_uops.c | 9 +- src/codegen_backend_x86-64.c | 169 ++++------ src/codegen_backend_x86-64.h | 11 +- src/codegen_backend_x86-64_ops.c | 512 +++++++++++++++++++++++++++--- src/codegen_backend_x86-64_ops.h | 2 + src/codegen_backend_x86-64_uops.c | 20 +- src/codegen_backend_x86.c | 121 +++---- src/codegen_backend_x86.h | 12 +- src/codegen_backend_x86_defs.h | 5 + src/codegen_backend_x86_ops.c | 488 ++++++++++++++++++++++++---- src/codegen_backend_x86_uops.c | 26 +- src/codegen_ir.c | 5 +- src/wx-sdl2-status.c | 7 +- 26 files changed, 1339 insertions(+), 667 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 653834c..5e3bc13 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -7,6 +7,7 @@ #include "386_common.h" #include "codegen_accumulate.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_ops.h" diff --git a/src/codegen.h b/src/codegen.h index e0e8760..e76391b 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -59,14 +59,18 @@ typedef struct codeblock_t present in two pages.*/ uint16_t prev, next; uint16_t prev_2, next_2; + + /*First mem_block_t used by this block. Any subsequent mem_block_ts + will be in the list starting at head_mem_block->next.*/ + struct mem_block_t *head_mem_block; } codeblock_t; -uint8_t *codeblock_data; - extern codeblock_t *codeblock; extern uint16_t *codeblock_hash; +extern uint8_t *block_write_data; + /*Code block uses FPU*/ #define CODEBLOCK_HAS_FPU 1 /*Code block is always entered with the same FPU top-of-stack*/ @@ -300,6 +304,10 @@ x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fe void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +/*Delete a random code block to free memory. This is obviously quite expensive, and + will only be called when the allocator is out of memory*/ +void codegen_delete_random_block(); + extern int cpu_block_end; extern uint32_t codegen_endpc; diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 500230d..db786b2 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -11,10 +11,13 @@ #include "codegen.h" #include "codegen_accumulate.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_reg.h" +uint8_t *block_write_data = NULL; + int codegen_flat_ds, codegen_flat_ss; int mmx_ebx_ecx_loaded; int codegen_flags_changed = 0; @@ -52,6 +55,7 @@ uint32_t instr_counts[256*256]; void codegen_init() { + codegen_allocator_init(); codegen_backend_init(); #ifdef DEBUG_EXTRA memset(instr_counts, 0, sizeof(instr_counts)); @@ -96,10 +100,7 @@ void codegen_reset() mem_reset_page_blocks(); for (c = 0; c < BLOCK_SIZE; c++) - { codeblock[c].pc = BLOCK_PC_INVALID; - codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; - } } void dump_block() @@ -220,6 +221,28 @@ static void delete_block(codeblock_t *block) codeblock_tree_delete(block); remove_from_block_list(block, old_pc); + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; +} + +void codegen_delete_random_block() +{ + while (1) + { + int block_nr = rand() & BLOCK_MASK; + + if (block_nr && block_nr != block_current) + { + codeblock_t *block = &codeblock[block_nr]; + + if (block->pc != BLOCK_PC_INVALID && block->head_mem_block) + { + delete_block(block); + return; + } + } + } } void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) @@ -318,6 +341,9 @@ void codegen_block_start_recompile(codeblock_t *block) if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) fatal("Recompile to used block!\n"); + block->head_mem_block = codegen_allocator_allocate(NULL); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block->status = cpu_cur_status; cpu_block_end = 0; diff --git a/src/codegen_backend.h b/src/codegen_backend.h index df6fcea..7a5c5c0 100644 --- a/src/codegen_backend.h +++ b/src/codegen_backend.h @@ -16,45 +16,6 @@ void codegen_backend_init(); void codegen_backend_prologue(codeblock_t *block); void codegen_backend_epilogue(codeblock_t *block); -static inline void addbyte(uint8_t val) -{ - codeblock[block_current].data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addword(uint16_t val) -{ - *(uint16_t *)(void *)&codeblock[block_current].data[block_pos] = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addlong(uint32_t val) -{ - *(uint32_t *)&codeblock[block_current].data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - -static inline void addquad(uint64_t val) -{ - *(uint64_t *)&codeblock[block_current].data[block_pos] = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } -} - struct ir_data_t; struct uop_t; diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index d2b0fe4..bb861ae 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -3,6 +3,7 @@ #include #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" #include "codegen_backend_arm_ops.h" @@ -126,8 +127,6 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); - - block_pos = (block_pos + 63) & ~63; } static void build_store_routine(codeblock_t *block, int size, int is_float) @@ -199,8 +198,6 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) fatal("build_store_routine - unknown size %i\n", size); host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); - - block_pos = (block_pos + 63) & ~63; } static void build_loadstore_routines(codeblock_t *block) @@ -246,13 +243,13 @@ static void build_fp_round_routine(codeblock_t *block) host_arm_MOV_REG(block, REG_LR, REG_TEMP2); host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); - addlong(0); + host_arm_NOP(block); jump_table = (uint32_t *)&block->data[block_pos]; - addlong(0); - addlong(0); - addlong(0); - addlong(0); + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block->data[block_pos]; //tie even host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); @@ -279,12 +276,11 @@ static void build_fp_round_routine(codeblock_t *block) jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //zero host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); host_arm_MOV_REG(block, REG_PC, REG_LR); - - block_pos = (block_pos + 63) & ~63; } void codegen_backend_init() { + codeblock_t *block; int c; #if defined(__linux__) || defined(__APPLE__) void *start; @@ -293,13 +289,6 @@ void codegen_backend_init() long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE); -#endif - if (!codeblock_data) - fatal("codeblock_data failed to alloc - %i\n", (BLOCK_SIZE+1) * BLOCK_DATA_SIZE); codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -307,29 +296,24 @@ void codegen_backend_init() memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); for (c = 0; c < BLOCK_SIZE; c++) - { codeblock[c].pc = BLOCK_PC_INVALID; - codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; - } -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock_data & pagemask); - len = ((BLOCK_SIZE * BLOCK_DATA_SIZE) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); block_current = 0; block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; build_loadstore_routines(&codeblock[block_current]); +printf("block_pos=%i\n", block_pos); codegen_fp_round = &codeblock[block_current].data[block_pos]; build_fp_round_routine(&codeblock[block_current]); + block_write_data = NULL; + asm("vmrs %0, fpscr\n" : "=r" (cpu_state.old_fp_control) ); @@ -380,10 +364,7 @@ void codegen_backend_epilogue(codeblock_t *block) host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - if (block_pos > ARM_LITERAL_POOL_OFFSET) - fatal("Over limit!\n"); - - __clear_cache(&block->data[0], &block->data[block_pos]); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h index 67d18e6..f8b330b 100644 --- a/src/codegen_backend_arm.h +++ b/src/codegen_backend_arm.h @@ -9,17 +9,10 @@ #define HASH(l) ((l) & 0x1ffff) -/*Hack until better memory management written*/ -/*#define BLOCK_EXIT_OFFSET 0x7f0*/ - #define BLOCK_GPF_OFFSET 0 #define BLOCK_EXIT_OFFSET 32 -#define ARM_LITERAL_POOL_OFFSET 0x10000 - -/*#define BLOCK_MAX 1720*/ -#define BLOCK_MAX 65208 - +#define BLOCK_MAX 0x3c0 void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); @@ -30,6 +23,3 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm void host_arm_call(codeblock_t *block, void *dst_addr); void host_arm_nop(codeblock_t *block); - -void codegen_reset_literal_pool(codeblock_t *block); -int add_literal(codeblock_t *block, uint32_t data); diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 534df5c..ba08ca8 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -3,6 +3,7 @@ #include #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_arm64_defs.h" #include "codegen_backend_arm64_ops.h" @@ -83,9 +84,9 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) LDP X29, X30, [SP, #-16] RET */ + codegen_alloc(block, 80); host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); - offset = add_literal_q(block, (uintptr_t)readlookup2); - host_arm64_LDR_LITERAL_X(block, REG_X2, offset); + host_arm64_MOVX_IMM(block, REG_X2, (uint64_t)readlookup2); host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); if (size != 1) { @@ -107,9 +108,9 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_MOVZ_IMM(block, REG_W1, 0); host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block->data[block_pos]); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block->data[block_pos]); + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); if (size == 1) host_arm64_call(block, (uintptr_t)readmemb386l); @@ -128,8 +129,6 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); host_arm64_RET(block, REG_X30); - - block_pos = (block_pos + 63) & ~63; } static void build_store_routine(codeblock_t *block, int size, int is_float) @@ -154,9 +153,9 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) LDP X29, X30, [SP, #-16] RET */ + codegen_alloc(block, 80); host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); - offset = add_literal_q(block, (uintptr_t)writelookup2); - host_arm64_LDR_LITERAL_X(block, REG_X3, offset); + host_arm64_MOVX_IMM(block, REG_X3, (uint64_t)writelookup2); host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); if (size != 1) { @@ -178,9 +177,9 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm64_MOVZ_IMM(block, REG_X1, 0); host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block->data[block_pos]); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block->data[block_pos]); + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); if (size == 4 && is_float) host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); @@ -199,36 +198,34 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); host_arm64_RET(block, REG_X30); - - block_pos = (block_pos + 63) & ~63; } static void build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + codegen_mem_load_byte = &block_write_data[block_pos]; build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + codegen_mem_load_word = &block_write_data[block_pos]; build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + codegen_mem_load_long = &block_write_data[block_pos]; build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + codegen_mem_load_quad = &block_write_data[block_pos]; build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + codegen_mem_load_single = &block_write_data[block_pos]; build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + codegen_mem_load_double = &block_write_data[block_pos]; build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + codegen_mem_store_byte = &block_write_data[block_pos]; build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + codegen_mem_store_word = &block_write_data[block_pos]; build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + codegen_mem_store_long = &block_write_data[block_pos]; build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + codegen_mem_store_quad = &block_write_data[block_pos]; build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + codegen_mem_store_single = &block_write_data[block_pos]; build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + codegen_mem_store_double = &block_write_data[block_pos]; build_store_routine(block, 8, 1); } @@ -236,50 +233,47 @@ static void build_fp_round_routine(codeblock_t *block, int is_quad) { uint64_t *jump_table; + codegen_alloc(block, 80); host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); host_arm64_ADR(block, REG_TEMP2, 12); host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); host_arm64_BR(block, REG_TEMP2); - jump_table = &block->data[block_pos]; - addquad(0); - addquad(0); - addquad(0); - addquad(0); + jump_table = &block_write_data[block_pos]; + block_pos += 4*8; - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block->data[block_pos]; //tie even + jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even if (is_quad) host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); else host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //pos inf + jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf if (is_quad) host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); else host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block->data[block_pos]; //neg inf + jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf if (is_quad) host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); else host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //zero + jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero if (is_quad) host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); else host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); host_arm64_RET(block, REG_X30); - - block_pos = (block_pos + 63) & ~63; } void codegen_backend_init() { + codeblock_t *block; int c; #if defined(__linux__) || defined(__APPLE__) void *start; @@ -288,13 +282,6 @@ void codegen_backend_init() long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE); -#endif - if (!codeblock_data) - fatal("codeblock_data failed to alloc - %i\n", (BLOCK_SIZE+1) * BLOCK_DATA_SIZE); codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -304,29 +291,24 @@ void codegen_backend_init() for (c = 0; c < BLOCK_SIZE; c++) { codeblock[c].pc = BLOCK_PC_INVALID; - codeblock[c].data = &codeblock_data[c * BLOCK_SIZE]; } -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock_data & pagemask); - len = ((BLOCK_SIZE * BLOCK_DATA_SIZE) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); block_current = 0; block_pos = 0; - codegen_reset_literal_pool(&codeblock[block_current]); - build_loadstore_routines(&codeblock[block_current]); + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_fp_round = &codeblock[block_current].data[block_pos]; - build_fp_round_routine(&codeblock[block_current], 0); - codegen_fp_round_quad = &codeblock[block_current].data[block_pos]; - build_fp_round_routine(&codeblock[block_current], 1); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(block, 0); + codegen_fp_round_quad = &block_write_data[block_pos]; + build_fp_round_routine(block, 1); + + block_write_data = NULL; asm("mrs %0, fpcr\n" : "=r" (cpu_state.old_fp_control) @@ -340,14 +322,11 @@ void codegen_set_rounding_mode(int mode) cpu_state.new_fp_control = mode << 3; } -/*R11 - literal pool - R10 - cpu_state*/ +/*R10 - cpu_state*/ void codegen_backend_prologue(codeblock_t *block) { int offset; - codegen_reset_literal_pool(block); - block_pos = 0; block_pos = BLOCK_GPF_OFFSET; @@ -378,8 +357,7 @@ void codegen_backend_prologue(codeblock_t *block) host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16); host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -64); - offset = add_literal_q(block, (uintptr_t)&cpu_state); - host_arm64_LDR_LITERAL_X(block, REG_CPUSTATE, offset); + host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t)&cpu_state); if (block->flags & CODEBLOCK_HAS_FPU) { @@ -399,12 +377,7 @@ void codegen_backend_epilogue(codeblock_t *block) host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); host_arm64_RET(block, REG_X30); - if (block_pos > ARM_LITERAL_POOL_OFFSET) - fatal("Over limit!\n"); - - - - __clear_cache(&block->data[0], &block->data[block_pos]); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen_backend_arm64.h b/src/codegen_backend_arm64.h index 21bef6d..74586fb 100644 --- a/src/codegen_backend_arm64.h +++ b/src/codegen_backend_arm64.h @@ -9,16 +9,10 @@ #define HASH(l) ((l) & 0x1ffff) -/*Hack until better memory management written*/ -/*#define BLOCK_EXIT_OFFSET 0x7f0*/ - #define BLOCK_GPF_OFFSET 0 #define BLOCK_EXIT_OFFSET 32 -#define ARM_LITERAL_POOL_OFFSET 0xf000 - -/*#define BLOCK_MAX 1720*/ -#define BLOCK_MAX 65208 +#define BLOCK_MAX 0x3c0 void host_arm64_BLR(codeblock_t *block, int addr_reg); @@ -36,7 +30,3 @@ void host_arm64_STRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int o void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); - -void codegen_reset_literal_pool(codeblock_t *block); -int add_literal(codeblock_t *block, uint32_t data); -int add_literal_q(codeblock_t *block, uint64_t data); diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 7d71d31..1184a0a 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -2,22 +2,12 @@ #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_arm64_defs.h" #include "codegen_backend_arm64_ops.h" -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - #define Rt(x) (x) #define Rd(x) (x) #define Rn(x) ((x) << 5) @@ -53,21 +43,23 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_B (0x14 << OPCODE_SHIFT) #define OPCODE_BCOND (0x54 << OPCODE_SHIFT) #define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) +#define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) #define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) #define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) #define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) #define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) -#define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT) -#define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT) #define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) #define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) +#define OPCODE_TBZ (0x36 << OPCODE_SHIFT) #define OPCODE_AND_IMM (0x024 << 23) #define OPCODE_ANDS_IMM (0x0e4 << 23) #define OPCODE_EOR_IMM (0x0a4 << 23) #define OPCODE_MOVK_W (0x0e5 << 23) +#define OPCODE_MOVK_X (0x1e5 << 23) #define OPCODE_MOVZ_W (0x0a5 << 23) +#define OPCODE_MOVZ_X (0x1a5 << 23) #define OPCODE_ORR_IMM (0x064 << 23) #define OPCODE_BFI (0x0cc << 22) @@ -225,6 +217,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) +#define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) #define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) #define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) @@ -242,12 +235,6 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define DUP_ELEMENT(element) ((element) << 19) -static int literal_offset = 0; -void codegen_reset_literal_pool(codeblock_t *block) -{ - literal_offset = 0; -} - /*Returns true if offset fits into 19 bits*/ static int offset_is_19bit(int offset) { @@ -268,33 +255,6 @@ static int offset_is_26bit(int offset) return 1; } -int add_literal(codeblock_t *block, uint32_t data) -{ - if (literal_offset >= 4096) - fatal("add_literal - literal pool full\n"); - - *(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; - - literal_offset += 4; - - return literal_offset - 4; -} - -int add_literal_q(codeblock_t *block, uint64_t data) -{ - if (literal_offset & 4) - literal_offset += 4; - - if (literal_offset >= 4096-4) - fatal("add_literal - literal pool full\n"); - - *(uint64_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data; - - literal_offset += 8; - - return literal_offset - 8; -} - static inline int imm_is_imm16(uint32_t imm_data) { if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) @@ -308,6 +268,39 @@ static inline int imm_is_imm12(uint32_t imm_data) return 0; } +static void codegen_allocate_new_block(codeblock_t *block); + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + if (block_pos >= (BLOCK_MAX-4)) + codegen_allocate_new_block(block); + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; +} + +static void codegen_allocate_new_block(codeblock_t *block) +{ + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]; + + if (!offset_is_26bit(offset)) + fatal("codegen_allocate_new_block - offset out of range %x\n", offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *)&block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; +} + +void codegen_alloc(codeblock_t *block, int size) +{ + if (block_pos >= (BLOCK_MAX-size)) + codegen_allocate_new_block(block); +} + void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { if (!imm_data) @@ -462,7 +455,10 @@ void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_re void host_arm64_B(codeblock_t *block, void *dest) { - int offset = (uintptr_t)dest - (uintptr_t)&block->data[block_pos]; + int offset; + + codegen_alloc(block, 4); + offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; if (!offset_is_26bit(offset)) fatal("host_arm64_B - offset out of range %x\n", offset); @@ -481,79 +477,107 @@ void host_arm64_BLR(codeblock_t *block, int addr_reg) uint32_t *host_arm64_BCC_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_CC); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BCS_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_CS); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BEQ_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_EQ); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BGE_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_GE); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BGT_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_GT); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BHI_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_HI); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BLE_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_LE); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BLS_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_LS); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BLT_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_LT); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BMI_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_MI); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BNE_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_NE); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BPL_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_PL); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BVC_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_VC); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_arm64_BVS_(codeblock_t *block) { - codegen_addlong(block, OPCODE_BCOND | COND_VS); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) { int offset = (uintptr_t)dest - (uintptr_t)opcode; - *opcode |= OFFSET19(offset); + *opcode |= OFFSET26(offset); } void host_arm64_BR(codeblock_t *block, int addr_reg) @@ -574,10 +598,16 @@ void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { - int offset = dest - (uintptr_t)&block->data[block_pos]; - if (!offset_is_19bit(offset)) - fatal("host_arm64_CBNZ - offset out of range %x\n", offset); - codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); + int offset = dest - (uintptr_t)&block_write_data[block_pos]; + if (offset_is_19bit(offset)) + codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); + else + { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); + offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); + } } void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) @@ -880,24 +910,6 @@ void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int of codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset) -{ - int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; - - if (!offset_is_19bit(offset)) - fatal("host_arm64_CBNZ - offset out of range %x\n", offset); - - codegen_addlong(block, OPCODE_LDR_LITERAL_W | OFFSET19(offset) | Rt(dest_reg)); -} -void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset) -{ - int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos; - - if (!offset_is_19bit(offset)) - fatal("host_arm64_CBNZ - offset out of range %x\n", offset); - - codegen_addlong(block, OPCODE_LDR_LITERAL_X | OFFSET19(offset) | Rt(dest_reg)); -} void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); @@ -977,6 +989,16 @@ void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) +{ + codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); + if ((imm_data >> 16) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); + if ((imm_data >> 32) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); + if ((imm_data >> 48) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); +} void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { if (dst_reg != src_m_reg) @@ -1265,8 +1287,10 @@ void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_ uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) { - codegen_addlong(block, OPCODE_TBNZ | Rt(reg) | BIT_TBxZ(bit)); - return (uint32_t *)&block->data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos-4]; } void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) @@ -1346,15 +1370,13 @@ void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src void host_arm64_call(codeblock_t *block, void *dst_addr) { - int offset = add_literal_q(block, (uintptr_t)dst_addr); - host_arm64_LDR_LITERAL_X(block, REG_X16, offset); + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); host_arm64_BLR(block, REG_X16); } void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) { - int offset = add_literal_q(block, (uintptr_t)dst_addr); - host_arm64_LDR_LITERAL_X(block, REG_X16, offset); + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); host_arm64_BR(block, REG_X16); } diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index a8c3fc2..42760dd 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -121,8 +121,6 @@ void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, in void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset); -void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset); -void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset); void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg); @@ -146,6 +144,7 @@ void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); +void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data); void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data); @@ -170,6 +169,8 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); @@ -253,4 +254,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); -int add_literal_q(codeblock_t *block, uint64_t data); +void codegen_alloc(codeblock_t *block, int size); \ No newline at end of file diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 703a7e5..c2c5033 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -779,7 +779,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) host_arm64_call(block, x86_int); host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]); - host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); + host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); return 0; } @@ -876,12 +876,11 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { int src_reg = HOST_REG_GET(uop->src_reg_a_real); int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - int offset = add_literal_q(block, (uintptr_t)uop->p); if (!REG_IS_W(src_size)) fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - host_arm64_LDR_LITERAL_X(block, REG_ARG1, offset); + host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p); host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); host_arm64_call(block, (void *)loadseg); host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); @@ -1229,8 +1228,7 @@ static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { - int offset = add_literal_q(block, (uintptr_t)uop->p); - host_arm64_LDR_LITERAL_X(block, uop->dest_reg_a_real, offset); + host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); return 0; } @@ -1371,7 +1369,7 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) host_arm64_call(block, codegen_fp_round_quad); host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); - host_arm64_branch_set_offset(branch_offset, &block->data[block_pos]); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); } else fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -3031,8 +3029,6 @@ void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int void codegen_set_jump_dest(codeblock_t *block, void *p) { - int offset = (uintptr_t)&block->data[block_pos] - (uintptr_t)p; - - *(uint32_t *)p |= OFFSET19(offset); + host_arm64_branch_set_offset(p, &block_write_data[block_pos]); } #endif diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 85ffd9d..3e17433 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -2,21 +2,11 @@ #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" #include "codegen_backend_arm_ops.h" -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } -} - #define Rm(x) (x) #define Rs(x) ((x) << 8) #define Rd(x) ((x) << 12) @@ -207,6 +197,37 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define VDUP_32_IMM(imm) ((imm) << 19) +static void codegen_allocate_new_block(codeblock_t *block); + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + if (block_pos >= (BLOCK_MAX-4)) + codegen_allocate_new_block(block); + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; +} + +static void codegen_allocate_new_block(codeblock_t *block) +{ + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = ((uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]) - 8; + + /*Add a jump instruction to the new block*/ + *(uint32_t *)&block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; +} + +static inline void codegen_alloc_4(codeblock_t *block) +{ + if (block_pos >= (BLOCK_MAX-4)) + codegen_allocate_new_block(block); +} + static inline uint32_t arm_data_offset(int offset) { if (offset < -0xffc || offset > 0xffc) @@ -321,7 +342,10 @@ void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int sr void host_arm_B(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { @@ -366,7 +390,10 @@ void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int sr void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { @@ -378,7 +405,10 @@ void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) } void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { @@ -397,90 +427,93 @@ uint32_t *host_arm_BCC_(codeblock_t *block) { codegen_addlong(block, COND_CC | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BCS_(codeblock_t *block) { codegen_addlong(block, COND_CS | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BEQ_(codeblock_t *block) { codegen_addlong(block, COND_EQ | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BGE_(codeblock_t *block) { codegen_addlong(block, COND_GE | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BGT_(codeblock_t *block) { codegen_addlong(block, COND_GT | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BHI_(codeblock_t *block) { codegen_addlong(block, COND_HI | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BLE_(codeblock_t *block) { codegen_addlong(block, COND_LE | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BLS_(codeblock_t *block) { codegen_addlong(block, COND_LS | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BLT_(codeblock_t *block) { codegen_addlong(block, COND_LT | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BMI_(codeblock_t *block) { codegen_addlong(block, COND_MI | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BNE_(codeblock_t *block) { codegen_addlong(block, COND_NE | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BPL_(codeblock_t *block) { codegen_addlong(block, COND_PL | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BVC_(codeblock_t *block) { codegen_addlong(block, COND_VC | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_arm_BVS_(codeblock_t *block) { codegen_addlong(block, COND_VS | OPCODE_B); - return (uint32_t *)&block->data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); @@ -489,7 +522,10 @@ void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) } void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8; + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 3c2ae77..94d9a9b 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -94,6 +94,8 @@ void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm); void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift); +#define host_arm_NOP(block) host_arm_MOV_REG(block, REG_R0, REG_R0) + void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm); void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 1a5d4e2..e65816f 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -6,6 +6,7 @@ #include "x87.h" #include "386_common.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_arm_defs.h" #include "codegen_backend_arm_ops.h" @@ -849,7 +850,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) host_arm_call(block, x86_int); host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); - *branch_ptr |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; + *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; return 0; } @@ -870,7 +871,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm_call(block, x86_int); host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); - *branch_ptr |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; + *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; host_arm_MOV_IMM(block, REG_TEMP, 0); host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); @@ -1489,7 +1490,7 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) host_arm_call(block, x87_fround64); host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; } else fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -3165,6 +3166,6 @@ void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int void codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; + *(uint32_t *)p |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; } #endif diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 29ca83a..86ed609 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" #include "codegen_backend_x86-64_ops.h" @@ -101,9 +102,9 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; host_x86_PUSH(block, REG_RAX); host_x86_PUSH(block, REG_RDX); #if WIN64 @@ -145,7 +146,6 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_POP(block, REG_RAX); host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; } static void build_store_routine(codeblock_t *block, int size, int is_float) @@ -200,9 +200,9 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; host_x86_PUSH(block, REG_RAX); host_x86_PUSH(block, REG_RDX); #if WIN64 @@ -241,7 +241,6 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_POP(block, REG_RAX); host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; } static void build_loadstore_routines(codeblock_t *block) @@ -283,11 +282,6 @@ void codegen_backend_init() long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock_data = mmap(0, BLOCK_SIZE * BLOCK_DATA_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); -#endif codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -295,16 +289,17 @@ void codegen_backend_init() memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); for (c = 0; c < BLOCK_SIZE; c++) - { - codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; - } + // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); block_current = 0; block_pos = 0; + codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL); + codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); + block_write_data = codeblock[block_current].data; build_loadstore_routines(&codeblock[block_current]); -// fatal("Here\n"); + block_write_data = NULL; asm( "stmxcsr %0\n" @@ -318,47 +313,46 @@ void codegen_set_rounding_mode(int mode) cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); } -static inline void call(codeblock_t *block, uintptr_t func) -{ - uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; - - if (diff >= -0x80000000 && diff < 0x7fffffff) - { - addbyte(0xE8); /*CALL*/ - addlong((uint32_t)diff); - } - else - { - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); - } -} - void codegen_backend_prologue(codeblock_t *block) { - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH RBX*/ - addbyte(0x55); /*PUSH RBP*/ - addbyte(0x56); /*PUSH RSI*/ - addbyte(0x57); /*PUSH RDI*/ - addbyte(0x41); /*PUSH R12*/ - addbyte(0x54); - addbyte(0x41); /*PUSH R13*/ - addbyte(0x55); - addbyte(0x41); /*PUSH R14*/ - addbyte(0x56); - addbyte(0x41); /*PUSH R15*/ - addbyte(0x57); - addbyte(0x48); /*SUBL $40,%rsp*/ - addbyte(0x83); - addbyte(0xEC); - addbyte(0x38); - addbyte(0x48); /*MOVL RBP, &cpu_state*/ - addbyte(0xBD); - addquad(((uintptr_t)&cpu_state) + 128); + block_pos = BLOCK_GPF_OFFSET; +#if WIN64 + host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX, REG_ECX); + host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX, REG_EDX); +#else + host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI, REG_EDI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); +#endif + host_x86_CALL(block, (uintptr_t)x86gpf); + while (block_pos < BLOCK_EXIT_OFFSET) + host_x86_NOP(block); + if (block_pos > BLOCK_EXIT_OFFSET) + fatal("block_pos > BLOCK_EXIT_OFFSET\n"); + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); + if (block_pos > BLOCK_START) + fatal("block_pos > BLOCK_START\n"); + + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_RBX); + host_x86_PUSH(block, REG_RBP); + host_x86_PUSH(block, REG_RSI); + host_x86_PUSH(block, REG_RDI); + host_x86_PUSH(block, REG_R12); + host_x86_PUSH(block, REG_R13); + host_x86_PUSH(block, REG_R14); + host_x86_PUSH(block, REG_R15); + host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t)&cpu_state) + 128); if (block->flags & CODEBLOCK_HAS_FPU) { host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); @@ -369,62 +363,15 @@ void codegen_backend_prologue(codeblock_t *block) void codegen_backend_epilogue(codeblock_t *block) { - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x38); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - block_pos = BLOCK_GPF_OFFSET; -#if WIN64 - addbyte(0x48); /*XOR RCX, RCX*/ - addbyte(0x31); - addbyte(0xc9); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); -#else - addbyte(0x48); /*XOR RDI, RDI*/ - addbyte(0x31); - addbyte(0xff); - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); -#endif - call(block, (uintptr_t)x86gpf); - while (block_pos < BLOCK_EXIT_OFFSET) - addbyte(0x90); /*NOP*/ - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x38); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); } - #endif diff --git a/src/codegen_backend_x86-64.h b/src/codegen_backend_x86-64.h index 4e9ec51..de52c3c 100644 --- a/src/codegen_backend_x86-64.h +++ b/src/codegen_backend_x86-64.h @@ -2,17 +2,14 @@ #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff -#define BLOCK_START 0 +#define BLOCK_START 40 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff #define HASH(l) ((l) & 0x1ffff) -/*Hack until better memory management written*/ -#define BLOCK_EXIT_OFFSET (BLOCK_DATA_SIZE - 32) -/*#define BLOCK_EXIT_OFFSET 0x7f0*/ -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +#define BLOCK_EXIT_OFFSET 20 +#define BLOCK_GPF_OFFSET 0 -/*#define BLOCK_MAX 1720*/ -#define BLOCK_MAX 65208 +#define BLOCK_MAX 0x3c0 diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 0992683..956f4eb 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" #include "codegen_backend_x86-64_ops.h" @@ -17,80 +18,100 @@ #define RM_OP_SHR 0x28 #define RM_OP_SAR 0x38 +#define JMP_LEN_BYTES 5 + static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { - block->data[block_pos++] = val; if (block_pos >= BLOCK_MAX) { fatal("codegen_addbyte over! %i\n", block_pos); // CPU_BLOCK_END(); } + block_write_data[block_pos++] = val; } static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - if (block_pos >= BLOCK_MAX) + if (block_pos > (BLOCK_MAX-2)) { fatal("codegen_addbyte2 over! %i\n", block_pos); CPU_BLOCK_END(); } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; } static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - if (block_pos >= BLOCK_MAX) + if (block_pos > (BLOCK_MAX-3)) { fatal("codegen_addbyte3 over! %i\n", block_pos); CPU_BLOCK_END(); } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; } static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - block->data[block_pos++] = vald; - if (block_pos >= BLOCK_MAX) + if (block_pos > (BLOCK_MAX-4)) { fatal("codegen_addbyte4 over! %i\n", block_pos); CPU_BLOCK_END(); } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; } static inline void codegen_addword(codeblock_t *block, uint16_t val) { - *(uint16_t *)&block->data[block_pos] = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) + if (block_pos > (BLOCK_MAX-2)) { fatal("codegen_addword over! %i\n", block_pos); CPU_BLOCK_END(); } + *(uint16_t *)&block_write_data[block_pos] = val; + block_pos += 2; } static inline void codegen_addlong(codeblock_t *block, uint32_t val) { - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) + if (block_pos > (BLOCK_MAX-4)) { fatal("codegen_addlong over! %i\n", block_pos); CPU_BLOCK_END(); } + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; } static inline void codegen_addquad(codeblock_t *block, uint64_t val) { - *(uint64_t *)&block->data[block_pos] = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) + if (block_pos > (BLOCK_MAX-8)) { fatal("codegen_addquad over! %i\n", block_pos); CPU_BLOCK_END(); } + *(uint64_t *)&block_write_data[block_pos] = val; + block_pos += 8; +} + +static inline void codegen_alloc_bytes(codeblock_t *block, int size) +{ + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) + { + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; + } } static int is_imm8(uint32_t imm_data) @@ -102,7 +123,10 @@ static int is_imm8(uint32_t imm_data) static inline void call(codeblock_t *block, uintptr_t func) { - uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; + uintptr_t diff; + + codegen_alloc_bytes(block, 5); + diff = func - (uintptr_t)&block_write_data[block_pos + 5]; if (diff >= -0x80000000 && diff < 0x7fffffff) { @@ -111,6 +135,7 @@ static inline void call(codeblock_t *block, uintptr_t func) } else { + codegen_alloc_bytes(block, 13); codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ codegen_addquad(block, func); codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ @@ -119,7 +144,10 @@ static inline void call(codeblock_t *block, uintptr_t func) static inline void jmp(codeblock_t *block, uintptr_t func) { - uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; + uintptr_t diff; + + codegen_alloc_bytes(block, 5); + diff = func - (uintptr_t)&block_write_data[block_pos + 5]; if (diff >= -0x80000000 && diff < 0x7fffffff) { @@ -128,6 +156,7 @@ static inline void jmp(codeblock_t *block, uintptr_t func) } else { + codegen_alloc_bytes(block, 13); codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ codegen_addquad(block, func); codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ @@ -140,9 +169,15 @@ void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ + } } void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -150,14 +185,19 @@ void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -168,14 +208,19 @@ void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -186,7 +231,10 @@ void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); } @@ -195,6 +243,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -202,6 +251,7 @@ void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -209,15 +259,18 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } @@ -227,9 +280,15 @@ void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ + } } void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -237,14 +296,19 @@ void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -255,14 +319,19 @@ void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -272,6 +341,7 @@ void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -279,6 +349,7 @@ void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -286,6 +357,7 @@ void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } @@ -297,14 +369,19 @@ void host_x86_CALL(codeblock_t *block, void *p) void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -312,14 +389,19 @@ void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -327,87 +409,107 @@ void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else fatal("CMP64_REG_IMM not 8-bit imm\n"); } void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ } void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ } void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ } void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ } void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ } @@ -418,118 +520,138 @@ void host_x86_JMP(codeblock_t *block, void *p) void host_x86_JNZ(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } void host_x86_JZ(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } uint8_t *host_x86_JNZ_short(codeblock_t *block) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block->data[block_pos-1]; + return &block_write_data[block_pos-1]; } uint8_t *host_x86_JS_short(codeblock_t *block) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block->data[block_pos-1]; + return &block_write_data[block_pos-1]; } uint8_t *host_x86_JZ_short(codeblock_t *block) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block->data[block_pos-1]; + return &block_write_data[block_pos-1]; } uint32_t *host_x86_JNB_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNBE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNL_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNLE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNO_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNS_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNZ_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JB_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JBE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JL_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JLE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JO_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JS_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JZ_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } void host_x86_LAHF(codeblock_t *block) { + codegen_alloc_bytes(block, 1); codegen_addbyte(block, 0x9f); /*LAHF*/ } @@ -539,10 +661,12 @@ void host_x86_LDMXCSR(codeblock_t *block, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ codegen_addlong(block, offset); } @@ -556,17 +680,22 @@ void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t { if (offset) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ codegen_addlong(block, offset); } else + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } } void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_LEA_REG_REG - bad reg\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } @@ -575,12 +704,14 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ } @@ -590,6 +721,7 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ codegen_addbyte(block, imm_data); } @@ -597,6 +729,7 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { if ((uintptr_t)p >> 32) fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 8); codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ codegen_addlong(block, (uint32_t)(uintptr_t)p); codegen_addbyte(block, imm_data); @@ -608,6 +741,7 @@ void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ codegen_addlong(block, imm_data); } @@ -615,6 +749,7 @@ void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { if ((uintptr_t)p >> 32) fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 11); codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ codegen_addlong(block, (uint32_t)(uintptr_t)p); codegen_addlong(block, imm_data); @@ -630,12 +765,14 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ } else { if ((uintptr_t)p >> 32) fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); codegen_addlong(block, (uint32_t)(uintptr_t)p); @@ -650,10 +787,12 @@ void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ codegen_addlong(block, offset); } @@ -672,10 +811,12 @@ void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ codegen_addlong(block, offset); } @@ -683,6 +824,7 @@ void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { if ((uintptr_t)p >> 32) fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); codegen_addlong(block, (uint32_t)(uintptr_t)p); @@ -697,12 +839,14 @@ void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ } else { if ((uintptr_t)p >> 32) fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ codegen_addlong(block, (uint32_t)(uintptr_t)p); } @@ -714,10 +858,12 @@ void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ codegen_addlong(block, addr); } @@ -727,18 +873,21 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_re { if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ } void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ } void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ } @@ -751,10 +900,12 @@ void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } @@ -772,10 +923,12 @@ void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } @@ -793,16 +946,19 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } else { fatal("host_x86_MOV32_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); codegen_addlong(block, (uint32_t)(uintptr_t)p); @@ -817,10 +973,12 @@ void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } @@ -834,10 +992,12 @@ void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ codegen_addlong(block, addr); } @@ -847,6 +1007,7 @@ void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg { if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ } @@ -854,6 +1015,7 @@ void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int ba { if ((dst_reg & 8) || (index_reg & 8)) fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + codegen_alloc_bytes(block, 4); if (base_reg & 8) codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ else @@ -869,11 +1031,15 @@ void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x66); codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } } else fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); @@ -887,10 +1053,14 @@ void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } } else fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); @@ -904,11 +1074,15 @@ void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x48); codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } } else fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); @@ -923,10 +1097,14 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset { if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } } else fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); @@ -940,11 +1118,15 @@ void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset { if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x48); codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } } else fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); @@ -954,12 +1136,14 @@ void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { if (reg >= 8) fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ } void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { if (reg & 8) fatal("host_x86_MOV16_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ codegen_addword(block, imm_data); } @@ -967,6 +1151,7 @@ void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) { if (reg & 8) fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -975,11 +1160,13 @@ void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) { if (reg & 8) { + codegen_alloc_bytes(block, 10); codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ codegen_addquad(block, imm_data); } else { + codegen_alloc_bytes(block, 10); codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ codegen_addquad(block, imm_data); } @@ -990,6 +1177,7 @@ void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOV8_REG_REG - bad reg\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) @@ -997,6 +1185,7 @@ void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOV16_REG_REG - bad reg\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) @@ -1004,6 +1193,7 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOV32_REG_REG - bad reg\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } @@ -1011,16 +1201,19 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d { if (!offset) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ codegen_addlong(block, imm_data); } else if (offset >= -80 || offset < 0x80) { + codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 11); codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ codegen_addlong(block, offset); codegen_addlong(block, imm_data); @@ -1029,20 +1222,24 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1055,6 +1252,7 @@ void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ codegen_addbyte(block, offset); } @@ -1062,6 +1260,7 @@ void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { if ((uintptr_t)p >> 32) fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ codegen_addbyte(block, 0x25); codegen_addlong(block, (uint32_t)(uintptr_t)p); @@ -1072,13 +1271,16 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); codegen_addlong(block, addr); } @@ -1086,6 +1288,7 @@ void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } @@ -1095,11 +1298,13 @@ void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset { if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 6); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ codegen_addbyte2(block, 0x24, offset); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ codegen_addbyte(block, offset); } @@ -1117,6 +1322,7 @@ void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ codegen_addbyte(block, offset); } @@ -1124,6 +1330,7 @@ void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { if ((uintptr_t)p >> 32) fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ codegen_addbyte(block, 0x25); codegen_addlong(block, (uint32_t)(uintptr_t)p); @@ -1134,19 +1341,23 @@ void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint3 if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); codegen_addlong(block, addr); } } void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } @@ -1156,11 +1367,13 @@ void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ codegen_addbyte2(block, 0x24, offset); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ codegen_addbyte(block, offset); } @@ -1171,30 +1384,36 @@ void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } @@ -1202,12 +1421,16 @@ void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_re { if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); } void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); } @@ -1215,18 +1438,24 @@ void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } @@ -1240,8 +1469,16 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { if (dst_reg & 8) + { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x44); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + else + { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } } else fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); @@ -1249,31 +1486,47 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ } void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ } void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ } void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } +void host_x86_NOP(codeblock_t *block) +{ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x90); /*NOP*/ +} + void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) { if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ + } } void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -1281,14 +1534,19 @@ void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_ fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -1299,14 +1557,19 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1316,6 +1579,7 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1323,6 +1587,7 @@ void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1330,23 +1595,27 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ codegen_addbyte(block, 0x88); } void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ codegen_addbyte(block, 0x88); } void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ codegen_addbyte(block, 0x88); @@ -1354,210 +1623,267 @@ void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ } void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ } void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ } void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ } void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ } void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ } void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ } void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ } void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ } void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ } void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ } void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ } void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ } void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ } void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ codegen_addbyte(block, 0xee); } void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ codegen_addbyte(block, 0xee); } void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ codegen_addbyte(block, 0xee); } void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ } void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ } void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ } void host_x86_POP(codeblock_t *block, int dst_reg) { if (dst_reg & 8) - fatal("POP reg & 8\n"); - codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ + { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ + } + else + { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ + } } void host_x86_PUSH(codeblock_t *block, int src_reg) { if (src_reg & 8) - fatal("PUSH reg & 8\n"); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ + } + else + { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + } } void host_x86_RET(codeblock_t *block) { + codegen_alloc_bytes(block, 1); codegen_addbyte(block, 0xc3); /*RET*/ } @@ -1565,18 +1891,24 @@ void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SAR8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SAR16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SAR32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } @@ -1584,18 +1916,23 @@ void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SAR8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SAR16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SAR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } @@ -1603,18 +1940,24 @@ void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SHL8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SHL16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SHL32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } @@ -1622,18 +1965,24 @@ void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SHL8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SHL16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SHL32 imm & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } @@ -1641,18 +1990,24 @@ void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SHR8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SHR16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) fatal("SHR32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } @@ -1660,27 +2015,34 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SHR8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SHR16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { if (dst_reg & 8) fatal("SHR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ } void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ } @@ -1690,9 +2052,15 @@ void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ + } } void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -1700,14 +2068,19 @@ void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -1718,14 +2091,19 @@ void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1736,7 +2114,10 @@ void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); } @@ -1745,6 +2126,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1752,6 +2134,7 @@ void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1759,15 +2142,18 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ } void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ } void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1775,16 +2161,20 @@ void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) { if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_TEST32_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) @@ -1793,11 +2183,13 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) fatal("TEST32_REG_IMM reg & 8\n"); if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1805,6 +2197,7 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1814,9 +2207,15 @@ void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ + } } void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -1824,14 +2223,19 @@ void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -1842,14 +2246,19 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1859,6 +2268,7 @@ void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ } void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1866,6 +2276,7 @@ void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ } void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1873,6 +2284,7 @@ void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ } diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index ea2eede..209e270 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -163,6 +163,8 @@ void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_NOP(codeblock_t *block); + void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index dd164d6..e49fe7f 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -715,11 +715,11 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop) static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - uint8_t *branch_offset; + uint32_t *branch_offset; host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_short(block); + branch_offset = host_x86_JZ_long(block); host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); #if WIN64 host_x86_MOV32_REG_IMM(block, REG_ECX, 7); @@ -728,17 +728,17 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) #endif host_x86_CALL(block, x86_int); host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; return 0; } static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint8_t *branch_offset; + uint32_t *branch_offset; host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_short(block); + branch_offset = host_x86_JZ_long(block); host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); #if WIN64 host_x86_MOV32_REG_IMM(block, REG_ECX, 7); @@ -747,7 +747,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) #endif host_x86_CALL(block, x86_int); host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); @@ -1269,19 +1269,19 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { - uint8_t *branch_offset; + uint32_t *branch_offset; /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_short(block); + branch_offset = host_x86_JS_long(block); host_x86_LDMXCSR(block, &cpu_state.new_fp_control); host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); host_x86_LDMXCSR(block, &cpu_state.old_fp_control); host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; } else fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -2763,7 +2763,7 @@ void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int void codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block->data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); } #endif diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 82c1d87..68d9a36 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -3,6 +3,7 @@ #include #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" @@ -100,9 +101,9 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; host_x86_PUSH(block, REG_EAX); host_x86_PUSH(block, REG_EDX); host_x86_PUSH(block, REG_ECX); @@ -190,9 +191,9 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 1; + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; if (size == 4 && is_float) host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); host_x86_PUSH(block, REG_EAX); @@ -254,6 +255,7 @@ static void build_loadstore_routines(codeblock_t *block) void codegen_backend_init() { + codeblock_t *block; int c; #if defined(__linux__) || defined(__APPLE__) void *start; @@ -283,48 +285,33 @@ pclog(" offsetof(codeblock_t, next)=%i\n", offsetof(codeblock_t, next)); pclog(" offsetof(codeblock_t, prev_2)=%i\n", offsetof(codeblock_t, prev_2)); pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); -#if defined WIN32 || defined _WIN32 || defined _WIN32 - codeblock_data = VirtualAlloc(NULL, BLOCK_SIZE * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#else - codeblock_data = malloc(BLOCK_SIZE * BLOCK_DATA_SIZE; -#endif codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); for (c = 0; c < BLOCK_SIZE; c++) - { - codeblock[c].data = &codeblock_data[c * BLOCK_DATA_SIZE]; codeblock[c].pc = BLOCK_PC_INVALID; - } -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)codeblock_data & pagemask); - len = ((BLOCK_SIZE * BLOCK_DATA_SIZE) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } -#endif // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); block_current = 0; block_pos = 0; - mem_abrt_rout = &codeblock[block_current].data[block_pos]; - addbyte(0x83); /*ADDL $16+4,%esp*/ - addbyte(0xC4); - addbyte(0x10+4); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + mem_abrt_rout = &block->data[block_pos]; + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x10+4); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); + block_pos = 64; - build_loadstore_routines(&codeblock[block_current]); - //fatal("Here\n"); + build_loadstore_routines(block); + block_write_data = NULL; cpu_state.old_fp_control = 0; asm( @@ -346,16 +333,25 @@ void codegen_set_rounding_mode(int mode) void codegen_backend_prologue(codeblock_t *block) { - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x55); /*PUSH EBP*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $64,%esp*/ - addbyte(0xEC); - addbyte(0x40); - addbyte(0xBD); /*MOVL EBP, &cpu_state*/ - addlong(((uintptr_t)&cpu_state) + 128); + block_pos = BLOCK_GPF_OFFSET; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); + host_x86_CALL(block, (void *)x86gpf); + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); + + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_EBX); + host_x86_PUSH(block, REG_EBP); + host_x86_PUSH(block, REG_ESI); + host_x86_PUSH(block, REG_EDI); + host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 64); + host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t)&cpu_state) + 128); if (block->flags & CODEBLOCK_HAS_FPU) { host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); @@ -366,39 +362,12 @@ void codegen_backend_prologue(codeblock_t *block) void codegen_backend_epilogue(codeblock_t *block) { - addbyte(0x83); /*ADDL $64,%esp*/ - addbyte(0xC4); - addbyte(0x40); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - block_pos = BLOCK_GPF_OFFSET; - addbyte(0xc7); /*MOV [ESP],0*/ - addbyte(0x04); - addbyte(0x24); - addlong(0); - addbyte(0xc7); /*MOV [ESP+4],0*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addlong(0); - addbyte(0xe8); /*CALL x86gpf*/ - addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $64,%esp*/ - addbyte(0xC4); - addbyte(0x40); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); } #endif diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h index 13ccfab..52df734 100644 --- a/src/codegen_backend_x86.h +++ b/src/codegen_backend_x86.h @@ -2,18 +2,14 @@ #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff -#define BLOCK_START 0 +#define BLOCK_START 32 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff #define HASH(l) ((l) & 0x1ffff) -/*Hack until better memory management written*/ -#define BLOCK_EXIT_OFFSET (BLOCK_DATA_SIZE - 16) -//#define BLOCK_EXIT_OFFSET 0xfff0 -/*#define BLOCK_EXIT_OFFSET 0x7f0*/ -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +#define BLOCK_EXIT_OFFSET 20 +#define BLOCK_GPF_OFFSET 0 -/*#define BLOCK_MAX 1720*/ -#define BLOCK_MAX 65208 +#define BLOCK_MAX 0x3c0 diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index 03b2a2e..0c9eb1d 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -39,4 +39,9 @@ extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; +#define STACK_ARG0 (0) +#define STACK_ARG1 (4) +#define STACK_ARG2 (8) +#define STACK_ARG3 (12) + #endif diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 97ba65f..56bd27a 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" @@ -17,80 +18,82 @@ #define RM_OP_SHR 0x28 #define RM_OP_SAR 0x38 +#define JMP_LEN_BYTES 5 + static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { - block->data[block_pos++] = val; if (block_pos >= BLOCK_MAX) - { fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); - } + block_write_data[block_pos++] = val; } static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - if (block_pos >= BLOCK_MAX) - { + if (block_pos > (BLOCK_MAX-2)) fatal("codegen_addbyte2 over! %i\n", block_pos); - CPU_BLOCK_END(); - } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; } static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - if (block_pos >= BLOCK_MAX) - { + if (block_pos > (BLOCK_MAX-3)) fatal("codegen_addbyte3 over! %i\n", block_pos); - CPU_BLOCK_END(); - } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; } static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { - block->data[block_pos++] = vala; - block->data[block_pos++] = valb; - block->data[block_pos++] = valc; - block->data[block_pos++] = vald; - if (block_pos >= BLOCK_MAX) - { + if (block_pos > (BLOCK_MAX-4)) fatal("codegen_addbyte4 over! %i\n", block_pos); - CPU_BLOCK_END(); - } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; } static inline void codegen_addword(codeblock_t *block, uint16_t val) { - *(uint16_t *)&block->data[block_pos] = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { + if (block_pos > (BLOCK_MAX-2)) fatal("codegen_addword over! %i\n", block_pos); - CPU_BLOCK_END(); - } + *(uint16_t *)&block_write_data[block_pos] = val; + block_pos += 2; } static inline void codegen_addlong(codeblock_t *block, uint32_t val) { - *(uint32_t *)&block->data[block_pos] = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { + if (block_pos > (BLOCK_MAX-4)) fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; } static inline void codegen_addquad(codeblock_t *block, uint64_t val) { - *(uint64_t *)&block->data[block_pos] = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { + if (block_pos > (BLOCK_MAX-8)) fatal("codegen_addquad over! %i\n", block_pos); - CPU_BLOCK_END(); - } + *(uint64_t *)&block_write_data[block_pos] = val; + block_pos += 8; +} + +static void codegen_allocate_new_block(codeblock_t *block) +{ + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; +} + +static inline void codegen_alloc_bytes(codeblock_t *block, int size) +{ + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) + codegen_allocate_new_block(block); } static int is_imm8(uint32_t imm_data) @@ -106,10 +109,12 @@ void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, int src_reg, void * if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | (dst_reg << 3)); codegen_addlong(block, (uint32_t)p); @@ -122,9 +127,15 @@ void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ + } } void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -132,14 +143,19 @@ void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -150,14 +166,19 @@ void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -168,6 +189,7 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a) fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -175,6 +197,7 @@ void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -182,15 +205,18 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ } void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } @@ -200,9 +226,15 @@ void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ + } } void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -210,14 +242,19 @@ void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -228,14 +265,19 @@ void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -246,6 +288,7 @@ void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a) fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -253,6 +296,7 @@ void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -260,26 +304,33 @@ void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_CALL(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xe8); /*CALL*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -287,14 +338,19 @@ void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -302,205 +358,243 @@ void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ } void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ } void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ } void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ } void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ } void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ } void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ } void host_x86_INC32_ABS(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ codegen_addlong(block, (uint32_t)p); } void host_x86_JMP(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } uint32_t *host_x86_JMP_long(codeblock_t *block) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xe9); /*JMP*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } void host_x86_JNZ(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } void host_x86_JZ(codeblock_t *block, void *p) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]); + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } uint8_t *host_x86_JNZ_short(codeblock_t *block) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block->data[block_pos-1]; + return &block_write_data[block_pos-1]; } uint8_t *host_x86_JS_short(codeblock_t *block) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block->data[block_pos-1]; + return &block_write_data[block_pos-1]; } uint8_t *host_x86_JZ_short(codeblock_t *block) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block->data[block_pos-1]; + return &block_write_data[block_pos-1]; } uint32_t *host_x86_JNB_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNBE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNL_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNLE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNO_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNS_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JNZ_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JB_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JBE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JL_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JLE_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JO_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JS_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } uint32_t *host_x86_JZ_long(codeblock_t *block) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ codegen_addlong(block, 0); - return (uint32_t *)&block->data[block_pos-4]; + return (uint32_t *)&block_write_data[block_pos-4]; } void host_x86_LAHF(codeblock_t *block) { + codegen_alloc_bytes(block, 1); codegen_addbyte(block, 0x9f); /*LAHF*/ } @@ -510,10 +604,12 @@ void host_x86_LDMXCSR(codeblock_t *block, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ codegen_addlong(block, (uint32_t)p); } @@ -523,24 +619,31 @@ void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t { if (offset) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ codegen_addlong(block, offset); } else + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } } void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ } void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ } void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ } @@ -550,11 +653,13 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ codegen_addbyte(block, imm_data); } else { + codegen_alloc_bytes(block, 7); codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ codegen_addlong(block, (uint32_t)p); codegen_addbyte(block, imm_data); @@ -566,11 +671,13 @@ void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 10); codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ codegen_addlong(block, (uint32_t)p); codegen_addlong(block, imm_data); @@ -583,10 +690,12 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ codegen_addbyte(block, 0x05 | (src_reg << 3)); codegen_addlong(block, (uint32_t)p); @@ -598,10 +707,12 @@ void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ codegen_addlong(block, (uint32_t)p); } @@ -612,10 +723,12 @@ void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | (src_reg << 3)); codegen_addlong(block, (uint32_t)p); @@ -626,10 +739,12 @@ void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int { if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ codegen_addlong(block, addr); } @@ -637,14 +752,17 @@ void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ } void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ } void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ } @@ -654,10 +772,12 @@ void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | (dst_reg << 3)); codegen_addlong(block, (uint32_t)p); @@ -669,10 +789,12 @@ void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ codegen_addlong(block, (uint32_t)p); } @@ -683,10 +805,12 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | (dst_reg << 3)); codegen_addlong(block, (uint32_t)p); @@ -695,6 +819,7 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ codegen_addlong(block, (uint32_t)p); } @@ -703,10 +828,12 @@ void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 { if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ codegen_addlong(block, addr); } @@ -714,6 +841,7 @@ void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32 void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ } @@ -723,11 +851,15 @@ void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x66); codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } } else fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); @@ -738,10 +870,14 @@ void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } } else fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); @@ -753,11 +889,15 @@ void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x66); codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } } else fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); @@ -768,10 +908,14 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } } else fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); @@ -779,16 +923,19 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ } void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { if (!imm_data) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ codegen_addword(block, imm_data); } @@ -797,10 +944,12 @@ void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (!imm_data) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ } else { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -808,14 +957,17 @@ void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } @@ -823,16 +975,19 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d { if (!offset) { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ codegen_addlong(block, imm_data); } else if (offset >= -80 || offset < 0x80) { + codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 11); codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ codegen_addlong(block, offset); codegen_addlong(block, imm_data); @@ -841,20 +996,24 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } @@ -864,30 +1023,36 @@ void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ codegen_addbyte(block, offset); } else { + codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ codegen_addlong(block, (uint32_t)p); } } void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); codegen_addlong(block, addr); } } void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } @@ -897,11 +1062,13 @@ void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ codegen_addbyte2(block, 0x24, offset); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ codegen_addbyte(block, offset); } @@ -913,16 +1080,19 @@ void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg { if (!offset) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ codegen_addbyte(block, 0x24); } else if (offset >= -80 || offset < 0x80) { + codegen_alloc_bytes(block, 6); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ codegen_addbyte2(block, 0x24, offset & 0xff); } else { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ codegen_addbyte(block, 0x24); codegen_addlong(block, offset); @@ -936,30 +1106,36 @@ void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ codegen_addbyte(block, offset); } else { + codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ codegen_addlong(block, (uint32_t)p); } } void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) { - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); codegen_addlong(block, addr); } } void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ codegen_addbyte(block, base_reg | (idx_reg << 3)); } @@ -969,11 +1145,13 @@ void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re { if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ codegen_addbyte2(block, 0x24, offset); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ codegen_addbyte(block, offset); } @@ -983,19 +1161,23 @@ void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re } void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } @@ -1005,10 +1187,12 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ codegen_addlong(block, (uint32_t)p); } @@ -1019,10 +1203,12 @@ void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ codegen_addlong(block, (uint32_t)p); } @@ -1030,41 +1216,50 @@ void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ } void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ } void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ } void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ } void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ } void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1073,6 +1268,7 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr if (dst_reg != src_reg_a) fatal("host_x86_OR8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1080,6 +1276,7 @@ void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a) fatal("host_x86_OR16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1087,6 +1284,7 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a) fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ } @@ -1096,9 +1294,15 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ + } } void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -1106,14 +1310,19 @@ void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_ fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 7); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -1124,14 +1333,19 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1139,18 +1353,21 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ codegen_addbyte(block, 0x88); } void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ codegen_addbyte(block, 0x88); } void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ codegen_addbyte(block, 0x88); @@ -1158,206 +1375,251 @@ void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ } void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ } void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ } void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ } void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ } void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ } void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ } void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ } void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ } void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ } void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ } void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 5); codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ codegen_addbyte(block, shift); } void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ } void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ } void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ } void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ codegen_addbyte(block, 0xee); } void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ codegen_addbyte(block, 0xee); } void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 9); codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ codegen_addbyte(block, 0xee); } void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ } void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ } void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ } void host_x86_POP(codeblock_t *block, int src_reg) { + codegen_alloc_bytes(block, 1); codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ } void host_x86_PUSH(codeblock_t *block, int src_reg) { + codegen_alloc_bytes(block, 1); codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ } void host_x86_RET(codeblock_t *block) { + codegen_alloc_bytes(block, 1); codegen_addbyte(block, 0xc3); /*RET*/ } @@ -1365,88 +1627,108 @@ void host_x86_RET(codeblock_t *block) void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ } void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ } @@ -1456,9 +1738,15 @@ void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ + } } void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -1466,14 +1754,19 @@ void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -1484,14 +1777,19 @@ void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1502,6 +1800,7 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a) fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1509,6 +1808,7 @@ void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1516,39 +1816,47 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ } void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ } void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1556,6 +1864,7 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } @@ -1564,6 +1873,7 @@ void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s if (dst_reg != src_reg_a) fatal("host_x86_XOR8_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ } void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1571,6 +1881,7 @@ void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_XOR16_REG_REG - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ } void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) @@ -1578,6 +1889,7 @@ void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int if (dst_reg != src_reg_a) fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ } @@ -1587,9 +1899,15 @@ void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); if (dst_reg == REG_EAX) + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ + } else + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ + } } void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) { @@ -1597,14 +1915,19 @@ void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ codegen_addword(block, imm_data); } else { + codegen_alloc_bytes(block, 5); codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ codegen_addword(block, imm_data); } @@ -1615,14 +1938,19 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); if (is_imm8(imm_data)) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ codegen_addlong(block, imm_data); } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ codegen_addlong(block, imm_data); } @@ -1631,16 +1959,28 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) { if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ + } else + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ + } } void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) { if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ + } else + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ + } } void host_x87_FLDCW(codeblock_t *block, void *p) { @@ -1648,10 +1988,12 @@ void host_x87_FLDCW(codeblock_t *block, void *p) if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ } else { + codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ codegen_addlong(block, (uint32_t)p); } @@ -1659,16 +2001,28 @@ void host_x87_FLDCW(codeblock_t *block, void *p) void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) { if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ + } else + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ + } } void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) { if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ + } else + { + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ + } } #endif diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index aa1c885..b0a54af 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -5,16 +5,12 @@ #include "x87.h" #include "386_common.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" #include "codegen_ir_defs.h" -#define STACK_ARG0 (0) -#define STACK_ARG1 (4) -#define STACK_ARG2 (8) -#define STACK_ARG3 (12) - /*void codegen_debug() { pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); @@ -726,32 +722,32 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop) static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - uint8_t *branch_offset; + uint32_t *branch_offset; host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_short(block); + branch_offset = host_x86_JZ_long(block); host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); host_x86_CALL(block, x86_int); host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; return 0; } static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint8_t *branch_offset; + uint32_t *branch_offset; host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_short(block); + branch_offset = host_x86_JZ_long(block); host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); host_x86_CALL(block, x86_int); host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); @@ -1268,12 +1264,12 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { - uint8_t *branch_offset; + uint32_t *branch_offset; /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_short(block); + branch_offset = host_x86_JS_long(block); /*There is no SSE instruction to convert a floating point value to a 64-bit integer. Instead we have to bounce through memory via x87.*/ @@ -1284,7 +1280,7 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); host_x87_FLDCW(block, &cpu_state.old_fp_control2); - *branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1; + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; } else fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); @@ -2769,7 +2765,7 @@ void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int void codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block->data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); } #endif diff --git a/src/codegen_ir.c b/src/codegen_ir.c index bd0e541..97a2dc1 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "codegen.h" +#include "codegen_allocator.h" #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_reg.h" @@ -20,6 +21,8 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) int jump_target_at_end = -1; int c; + block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); + block_pos = 0; codegen_backend_prologue(block); for (c = 0; c < ir->wr_pos; c++) @@ -114,7 +117,7 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) } codegen_backend_epilogue(block); - + block_write_data = NULL; // if (has_ea) // fatal("IR compilation complete\n"); } diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 735fa44..71c01ac 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -14,6 +14,7 @@ #include "ide.h" #include "cdrom-image.h" #include "scsi_zip.h" +#include "codegen_allocator.h" #include "wx-common.h" drive_info_t drive_info[10]; @@ -135,7 +136,7 @@ int get_status(char* machine, char* device) "\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" + "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS\nMem blocks used : %i (%g MB)" // "\nFully recompiled ins %% : %f%%" ,mips, flops, @@ -158,7 +159,9 @@ int get_status(char* machine, char* device) 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) + ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq), + codegen_allocator_usage, + (double)(codegen_allocator_usage * MEM_BLOCK_SIZE) / (1024.0*1024.0) // ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0 // cpu_reps_latched, cpu_notreps_latched ); From 68464d6e81b389920ac89dd9e5280634fa4e7a73 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 15:16:03 +0000 Subject: [PATCH 0577/1050] Fix 3DNow build issues on ARM platforms. --- src/codegen_backend_arm64_ops.c | 6 ++++ src/codegen_backend_arm64_uops.c | 58 ++++++++++++++++---------------- src/codegen_backend_arm_ops.c | 14 ++++++-- src/codegen_backend_arm_ops.h | 3 ++ src/codegen_backend_arm_uops.c | 30 ++++++++--------- 5 files changed, 65 insertions(+), 46 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 1184a0a..f253a4c 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -167,6 +167,7 @@ #define OPCODE_SADDLP_V2S_4H (0x0e602800) #define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) +#define OPCODE_SCVTF_V2S (0x0e21d800) #define OPCODE_SQADD_V8B (0x0e200c00) #define OPCODE_SQADD_V4H (0x0e600c00) #define OPCODE_SQSUB_V8B (0x0e202c00) @@ -1105,6 +1106,11 @@ void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { if (shift > 16) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index c2c5033..fd89d84 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1696,12 +1696,12 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop) } static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1710,12 +1710,12 @@ static int codegen_PFADD(codeblock_t *block, uop_t *uop) } static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1724,12 +1724,12 @@ static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) } static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1738,12 +1738,12 @@ static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) } static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1752,12 +1752,12 @@ static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) } static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1766,12 +1766,12 @@ static int codegen_PFMAX(codeblock_t *block, uop_t *uop) } static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1780,12 +1780,12 @@ static int codegen_PFMIN(codeblock_t *block, uop_t *uop) } static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1800,9 +1800,9 @@ static int codegen_PFRCP(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm_FMOV_S_ONE(block, REG_D_TEMP); - host_arm_FDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); - host_arm_DUP_V2S(block, dest_reg, dest_reg, 0); + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); } else fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); @@ -1817,10 +1817,10 @@ static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm_FSQRT_S(block, REG_D_TEMP, src_reg_a); - host_arm_FMOV_S_ONE(block, REG_D_TEMP); - host_arm_FDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); - host_arm_DUP_V2S(block, dest_reg, dest_reg, 0); + host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); } else fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); @@ -1834,7 +1834,7 @@ static int codegen_PFSUB(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_arm_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); } else fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 3e17433..f402c49 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -96,8 +96,9 @@ #define OPCODE_VCMP_D 0xeeb40b40 #define OPCODE_VCVT_D_IS 0xeeb80bc0 #define OPCODE_VCVT_D_S 0xeeb70ac0 +#define OPCODE_VCVT_F32_S32 0xf3bb0700 #define OPCODE_VCVT_IS_D 0xeebd0bc0 -#define OPCODE_VCVT_S32_F32 0xf3bb0680 +#define OPCODE_VCVT_S32_F32 0xf3bb0600 #define OPCODE_VCVT_S_D 0xeeb70bc0 #define OPCODE_VCVTR_IS_D 0xeebd0b40 #define OPCODE_VDIV 0xee800b00 @@ -156,6 +157,7 @@ #define OPCODE_VSUB_I8 0xf3000800 #define OPCODE_VSUB_I16 0xf3100800 #define OPCODE_VSUB_I32 0xf3200800 +#define OPCODE_VSUB_F32 0xf3000d00 #define OPCODE_VZIP_D8 0xf3b20180 #define OPCODE_VZIP_D16 0xf3b60180 #define OPCODE_VZIP_D32 0xf3ba0080 @@ -932,6 +934,10 @@ void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); } +void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); +} void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); @@ -1006,7 +1012,7 @@ void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) } void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); } void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { @@ -1198,6 +1204,10 @@ void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 94d9a9b..3e930df 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -166,12 +166,14 @@ void host_arm_VCHS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); +void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm); void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset); void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset); @@ -235,6 +237,7 @@ void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index e65816f..59efc56 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1823,8 +1823,8 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop) } static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1837,8 +1837,8 @@ static int codegen_PFADD(codeblock_t *block, uop_t *uop) } static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1851,8 +1851,8 @@ static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) } static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1865,8 +1865,8 @@ static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) } static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1879,8 +1879,8 @@ static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) } static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1893,8 +1893,8 @@ static int codegen_PFMAX(codeblock_t *block, uop_t *uop) } static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1907,8 +1907,8 @@ static int codegen_PFMIN(codeblock_t *block, uop_t *uop) } static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { @@ -1975,7 +1975,7 @@ static int codegen_PI2FD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - host_arm_VCVT_Q_F32_IS(block, dest_reg, src_reg_a); + host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); } else fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); From 966e74261b4aefae1ec18c6c49112aeb67b4e378 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 15:17:11 +0000 Subject: [PATCH 0578/1050] Update Makefile.am. --- src/Makefile.am | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index d465e30..f098a4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,12 +24,12 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_arith.c codegen_ops_jump.c codegen_ops_logic.c \ -codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ +cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ +codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ +hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 \ -laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ +laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ @@ -40,8 +40,9 @@ vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c vid_colorplus.c vid_compaq_cga.c vi vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.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_t1000.c vid_t3100e.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 vid_wy700.c \ -x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc +vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c vt82c586b.c \ +w83877tf.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc \ +codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c From 7fcb437f293ece9b452be6c2279b987f8fd3b0d3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 16:49:44 +0000 Subject: [PATCH 0579/1050] Fixed index into RTC days_in_month tables. Patch from Tale. --- src/rtc.c | 2 +- src/rtc_tc8521.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtc.c b/src/rtc.c index d1a0515..323e5a6 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -42,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_tc8521.c b/src/rtc_tc8521.c index e5b8649..cfc1a36 100644 --- a/src/rtc_tc8521.c +++ b/src/rtc_tc8521.c @@ -37,7 +37,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; } From d32157306d3b8d8de4f6e5d254ba690b35f1e251 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 16:54:32 +0000 Subject: [PATCH 0580/1050] Use consistent capitalisation of TGUI 9400CXi BIOS file name. Patch from Martin_Riarte. --- src/vid_tgui9440.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index bb8194c..22b14de 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -799,7 +799,7 @@ static void *tgui9440_init() static int tgui9400cxi_available() { - return rom_present("9400CXI.VBI"); + return rom_present("9400CXI.vbi"); } static int tgui9440_available() From 9efd6705aea9e7dfafef58c97a9ea760c22333c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 17:24:33 +0000 Subject: [PATCH 0581/1050] Added ASUS P/I-P55TVP4 and Epox P55-VA. Patch from Martin_Riarte. --- src/ibm.h | 2 ++ src/intel_flash.c | 6 ++++++ src/mem_bios.c | 16 ++++++++++++++++ src/model.c | 32 ++++++++++++++++++++++++++++++++ src/nvr.c | 4 ++++ 5 files changed, 60 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index 50f59b8..177c923 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -430,6 +430,8 @@ enum ROM_WIN486, ROM_PCI486, ROM_SIS496, + ROM_P55VA, /* Epox P55-VA/430VX/Award/SMC FDC37C932FR*/ + ROM_P55TVP4, /* ASUS P/I-P55TVP4/430VX/Award/Winbond W8387F*/ ROM_430VX, ROM_ENDEAVOR, ROM_REVENGE, diff --git a/src/intel_flash.c b/src/intel_flash.c index f2de0bb..43c0825 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -176,6 +176,12 @@ void *intel_flash_init(uint8_t type) case ROM_ZAPPA: strcpy(flash_path, "zappa/"); break; + case ROM_P55VA: + strcpy(flash_path, "p55va/"); + break; + case ROM_P55TVP4: + strcpy(flash_path, "p55tvp4/"); + break; case ROM_430VX: strcpy(flash_path, "430vx/"); break; diff --git a/src/mem_bios.c b/src/mem_bios.c index 5e92146..f258602 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -466,6 +466,22 @@ int loadbios() pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); return 1; + case ROM_P55VA: + f = romfopen("p55va/va021297.bin", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_P55TVP4: + f = romfopen("p55tvp4/tv5i0204.awd", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_430VX: // f = romfopen("430vx/ga586atv.bin", "rb"); // f = fopen("430vx/vx29.bin", "rb"); diff --git a/src/model.c b/src/model.c index 36781a3..b5af7e1 100644 --- a/src/model.c +++ b/src/model.c @@ -93,6 +93,8 @@ void at_ali1429_init(); void at_headland_init(); void at_opti495_init(); void at_sis496_init(); +void at_p55va_init(); +void at_p55tvp4_init(); void at_i430vx_init(); void at_batman_init(); void at_endeavor_init(); @@ -190,6 +192,8 @@ MODEL models[] = {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, + {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55tvp4_init, NULL}, + {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55va_init, NULL}, {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} @@ -648,6 +652,34 @@ void at_zappa_init() device_add(&intel_flash_bxt_ami_device); } +void at_p55va_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x08); + pci_slot(0x09); + pci_slot(0x0A); + pci_slot(0x0B); + i430vx_init(); + piix_init(7, 0x08, 0x09, 0x0A, 0x0B); + um8669f_init(); + device_add(&intel_flash_bxt_device); +} + +void at_p55tvp4_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x0C); + pci_slot(0x0B); + pci_slot(0x0A); + pci_slot(0x09); + i430vx_init(); + piix_init(7, 0x0C, 0x0B, 0x0A, 0x09); + um8669f_init(); + device_add(&intel_flash_bxt_device); +} + void at_i430vx_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 843096f..eca7a1e 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -282,6 +282,8 @@ void loadnvr() case ROM_WIN486: f = nvrfopen("win486.nvr", "rb"); nvrmask = 127; break; case ROM_PCI486: f = nvrfopen("hot-433.nvr", "rb"); nvrmask = 127; break; case ROM_SIS496: f = nvrfopen("sis496.nvr", "rb"); nvrmask = 127; break; + case ROM_P55VA: f = nvrfopen("p55va.nvr", "rb"); nvrmask = 127; break; + case ROM_P55TVP4: f = nvrfopen("p55tvp4.nvr", "rb"); nvrmask = 127; break; case ROM_430VX: f = nvrfopen("430vx.nvr", "rb"); nvrmask = 127; break; case ROM_REVENGE: f = nvrfopen("revenge.nvr", "rb"); nvrmask = 127; break; case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "rb"); nvrmask = 127; break; @@ -375,6 +377,8 @@ void savenvr() case ROM_WIN486: f = nvrfopen("win486.nvr", "wb"); break; case ROM_PCI486: f = nvrfopen("hot-433.nvr", "wb"); break; case ROM_SIS496: f = nvrfopen("sis496.nvr", "wb"); break; + case ROM_P55VA: f = nvrfopen("p55va.nvr", "wb"); break; + case ROM_P55TVP4: f = nvrfopen("p55tvp4.nvr", "wb"); break; case ROM_430VX: f = nvrfopen("430vx.nvr", "wb"); break; case ROM_REVENGE: f = nvrfopen("revenge.nvr", "wb"); break; case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "wb"); break; From f4f9695ca938a03f53aecc054dac7b816d1e0eac Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 12 Jan 2019 18:33:19 +0000 Subject: [PATCH 0582/1050] Added Zenith Data SupersPort. Based on patch from Tux. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/ibm.h | 1 + src/mem_bios.c | 7 +++++ src/model.c | 19 ++++++++++++ src/zenith.c | 50 ++++++++++++++++++++++++++++++ src/zenith.h | 1 + 11 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 src/zenith.c create mode 100644 src/zenith.h diff --git a/src/Makefile.am b/src/Makefile.am index 5b62127..a45f83c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,7 @@ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti03 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_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c \ -x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc +x86seg.c x87.c xi8088.c xtide.c zenith.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 3656f1c..450a3e6 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -20,7 +20,7 @@ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti03 vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ +x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index c4b6f3a..dab01f4 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -20,7 +20,7 @@ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti03 vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ +x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 91c1a7c..cbf8c22 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -24,7 +24,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o zenith.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index b4421f8..41e90c3 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429 vid_olivetti_m24.o vid_oti037.c 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_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ + vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o zenith.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 3587ce3..b0b3445 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -19,7 +19,7 @@ vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti03 vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xi8088.c xtide.o sound_dbopl.o sound_resid.o \ +x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o diff --git a/src/ibm.h b/src/ibm.h index 177c923..110b755 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -465,6 +465,7 @@ enum ROM_IBMPS2_M70_TYPE3, ROM_IBMPS2_M70_TYPE4, ROM_TULIP_TC7, + ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */ ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index f258602..0df10e6 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -950,6 +950,13 @@ int loadbios() biosmask = 0x7fff; return 1; + case ROM_ZD_SUPERS: /* [8088] Zenith Data Systems SupersPort */ + f=romfopen("zdsupers/z184m v3.1d.10d","rb"); + if (!f) break; + romfread(rom, 32768, 1, f); + fclose(f); + biosmask = 0x7fff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index b5af7e1..dc15b0a 100644 --- a/src/model.c +++ b/src/model.c @@ -63,6 +63,7 @@ #include "vid_t1000.h" #include "wd76c10.h" #include "xi8088.h" +#include "zenith.h" void xt_init(); void pcjr_init(); @@ -108,6 +109,7 @@ void at_pb520r_init(); void at_pb570_init(); void compaq_pip_init(); void xt_xi8088_init(); +void xt_zenith_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -131,6 +133,7 @@ MODEL models[] = {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}, {"[8088] Toshiba T1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, &t1000_device}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}, + {"[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, xt_zenith_init, NULL}, {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, @@ -377,6 +380,22 @@ void xt_laserxt_init() laserxt_init(); } +void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */ +{ + dma_init(); + fdc_add(); + lpt_init(); + lpt2_remove(); /* only one parallel port */ + pic_init(); + pit_init(); + serial1_init(0x3f8, 4); /* only one serial port */ + mem_add_bios(); + device_add(&zenith_scratchpad_device); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); +} + void xt_xi8088_init() { /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ diff --git a/src/zenith.c b/src/zenith.c new file mode 100644 index 0000000..f7f361b --- /dev/null +++ b/src/zenith.c @@ -0,0 +1,50 @@ +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "zenith.h" + +static uint8_t *zenith_scratchpad_ram; +static mem_mapping_t zenith_scratchpad_mapping; + +static uint8_t zenith_scratchpad_read(uint32_t addr, void *p) +{ + return zenith_scratchpad_ram[addr & 0x3fff]; +} +static void zenith_scratchpad_write(uint32_t addr, uint8_t val, void *p) +{ + zenith_scratchpad_ram[addr & 0x3fff] = val; +} + +static void *zenith_scratchpad_init() +{ + zenith_scratchpad_ram = malloc(0x4000); + + mem_mapping_disable(&bios_mapping[4]); + mem_mapping_disable(&bios_mapping[5]); + + mem_mapping_add(&zenith_scratchpad_mapping, 0xf0000, 0x4000, + zenith_scratchpad_read, NULL, NULL, + zenith_scratchpad_write, NULL, NULL, + zenith_scratchpad_ram, MEM_MAPPING_EXTERNAL, NULL); + + return zenith_scratchpad_ram; +} + +static void zenith_scratchpad_close(void *p) +{ + free(p); +} + +device_t zenith_scratchpad_device = +{ + "Zenith scratchpad RAM", + 0, + zenith_scratchpad_init, + zenith_scratchpad_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/zenith.h b/src/zenith.h new file mode 100644 index 0000000..0e58f45 --- /dev/null +++ b/src/zenith.h @@ -0,0 +1 @@ +device_t zenith_scratchpad_device; From 8998024225b4e122d42d81c46396e1d309932ea9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 13 Jan 2019 12:57:32 +0000 Subject: [PATCH 0583/1050] Move GPF and early exit routines out of individual code blocks and into the common helper block. --- src/codegen.c | 4 +- src/codegen_backend_arm.c | 84 +++++++++++++++---------------- src/codegen_backend_arm.h | 5 +- src/codegen_backend_arm64.c | 43 ++++++++-------- src/codegen_backend_arm64.h | 3 -- src/codegen_backend_arm64_defs.h | 5 +- src/codegen_backend_arm64_ops.c | 7 ++- src/codegen_backend_arm64_uops.c | 30 +++++------ src/codegen_backend_arm_defs.h | 5 +- src/codegen_backend_arm_ops.c | 6 +++ src/codegen_backend_arm_uops.c | 30 +++++------ src/codegen_backend_x86-64.c | 56 ++++++++++----------- src/codegen_backend_x86-64.h | 5 +- src/codegen_backend_x86-64_defs.h | 3 ++ src/codegen_backend_x86-64_uops.c | 30 +++++------ src/codegen_backend_x86.c | 30 ++++------- src/codegen_backend_x86.h | 5 +- src/codegen_backend_x86_defs.h | 3 ++ src/codegen_backend_x86_uops.c | 30 +++++------ src/codegen_ops_branch.c | 44 ++++++++-------- src/codegen_ops_shift.c | 6 +-- 21 files changed, 217 insertions(+), 217 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 5e3bc13..3db8d60 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -61,7 +61,7 @@ void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, &block->data[BLOCK_GPF_OFFSET]); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); seg->checked = 1; } @@ -78,7 +78,7 @@ void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, &block->data[BLOCK_GPF_OFFSET]); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); seg->checked = 1; } diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index bb861ae..fc77eba 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -35,6 +35,9 @@ void *codegen_mem_store_double; void *codegen_fp_round; +void *codegen_gpf_rout; +void *codegen_exit_rout; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_R4, @@ -78,6 +81,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) LDRB R1, cpu_state.abrt LDR PC, [SP], #4 */ + codegen_alloc(block, 80); host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2); host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); @@ -107,9 +111,9 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm_MOV_IMM(block, REG_R1, 0); host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; + *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); if (size == 1) host_arm_BL(block, (uintptr_t)readmemb386l); @@ -149,6 +153,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) LDRB R1, cpu_state.abrt LDR PC, [SP], #4 */ + codegen_alloc(block, 80); host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2); host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); @@ -178,9 +183,9 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm_MOV_IMM(block, REG_R1, 0); host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; + *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); if (size == 4 && is_float) host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); @@ -202,30 +207,30 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) static void build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + codegen_mem_load_byte = &block_write_data[block_pos]; build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + codegen_mem_load_word = &block_write_data[block_pos]; build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + codegen_mem_load_long = &block_write_data[block_pos]; build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + codegen_mem_load_quad = &block_write_data[block_pos]; build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + codegen_mem_load_single = &block_write_data[block_pos]; build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + codegen_mem_load_double = &block_write_data[block_pos]; build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + codegen_mem_store_byte = &block_write_data[block_pos]; build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + codegen_mem_store_word = &block_write_data[block_pos]; build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + codegen_mem_store_long = &block_write_data[block_pos]; build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + codegen_mem_store_quad = &block_write_data[block_pos]; build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + codegen_mem_store_single = &block_write_data[block_pos]; build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + codegen_mem_store_double = &block_write_data[block_pos]; build_store_routine(block, 8, 1); } @@ -239,23 +244,25 @@ static void build_fp_round_routine(codeblock_t *block) { uint32_t *jump_table; + codegen_alloc(block, 80); + host_arm_MOV_REG(block, REG_TEMP2, REG_LR); host_arm_MOV_REG(block, REG_LR, REG_TEMP2); host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); host_arm_NOP(block); - jump_table = (uint32_t *)&block->data[block_pos]; + jump_table = (uint32_t *)&block_write_data[block_pos]; host_arm_NOP(block); host_arm_NOP(block); host_arm_NOP(block); host_arm_NOP(block); - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block->data[block_pos]; //tie even + jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //pos inf + jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); @@ -264,7 +271,7 @@ static void build_fp_round_routine(codeblock_t *block) host_arm_VMSR_FPSCR(block, REG_TEMP); host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block->data[block_pos]; //neg inf + jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); @@ -273,7 +280,7 @@ static void build_fp_round_routine(codeblock_t *block) host_arm_VMSR_FPSCR(block, REG_TEMP); host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block->data[block_pos]; //zero + jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); host_arm_MOV_REG(block, REG_PC, REG_LR); } @@ -282,12 +289,6 @@ void codegen_backend_init() { codeblock_t *block; int c; -#if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -309,11 +310,21 @@ void codegen_backend_init() build_loadstore_routines(&codeblock[block_current]); printf("block_pos=%i\n", block_pos); - codegen_fp_round = &codeblock[block_current].data[block_pos]; + codegen_fp_round = &block_write_data[block_pos]; build_fp_round_routine(&codeblock[block_current]); - block_write_data = NULL; + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm_MOV_IMM(block, REG_R0, 0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_call(block, x86gpf); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); + + block_write_data = NULL; +//fatal("block_pos=%i\n", block_pos); asm("vmrs %0, fpscr\n" : "=r" (cpu_state.old_fp_control) ); @@ -331,20 +342,7 @@ void codegen_set_rounding_mode(int mode) /*R10 - cpu_state*/ void codegen_backend_prologue(codeblock_t *block) { - block_pos = 0; - - block_pos = BLOCK_GPF_OFFSET; - host_arm_MOV_IMM(block, REG_R0, 0); - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_call(block, x86gpf); - while (block_pos != BLOCK_EXIT_OFFSET) - host_arm_nop(block); - - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - while (block_pos != BLOCK_START) - host_arm_nop(block); + block_pos = BLOCK_START; /*Entry code*/ diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h index f8b330b..cc4a642 100644 --- a/src/codegen_backend_arm.h +++ b/src/codegen_backend_arm.h @@ -9,9 +9,6 @@ #define HASH(l) ((l) & 0x1ffff) -#define BLOCK_GPF_OFFSET 0 -#define BLOCK_EXIT_OFFSET 32 - #define BLOCK_MAX 0x3c0 void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); @@ -23,3 +20,5 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm void host_arm_call(codeblock_t *block, void *dst_addr); void host_arm_nop(codeblock_t *block); + +void codegen_alloc(codeblock_t *block, int size); \ No newline at end of file diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index ba08ca8..4a2885a 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -36,6 +36,9 @@ void *codegen_mem_store_double; void *codegen_fp_round; void *codegen_fp_round_quad; +void *codegen_gpf_rout; +void *codegen_exit_rout; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_X19, @@ -308,8 +311,25 @@ void codegen_backend_init() codegen_fp_round_quad = &block_write_data[block_pos]; build_fp_round_routine(block, 1); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm64_mov_imm(block, REG_ARG0, 0); + host_arm64_mov_imm(block, REG_ARG1, 0); + host_arm64_call(block, x86gpf); + + codegen_exit_rout = &block_write_data[block_pos]; + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_RET(block, REG_X30); + block_write_data = NULL; + codegen_allocator_clean_blocks(block->head_mem_block); + asm("mrs %0, fpcr\n" : "=r" (cpu_state.old_fp_control) ); @@ -325,28 +345,7 @@ void codegen_set_rounding_mode(int mode) /*R10 - cpu_state*/ void codegen_backend_prologue(codeblock_t *block) { - int offset; - - block_pos = 0; - - block_pos = BLOCK_GPF_OFFSET; - host_arm64_mov_imm(block, REG_ARG0, 0); - host_arm64_mov_imm(block, REG_ARG1, 0); - host_arm64_call(block, x86gpf); - while (block_pos != BLOCK_EXIT_OFFSET) - host_arm64_NOP(block); - - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); - host_arm64_RET(block, REG_X30); - - while (block_pos != BLOCK_START) - host_arm64_NOP(block); + block_pos = BLOCK_START; /*Entry code*/ diff --git a/src/codegen_backend_arm64.h b/src/codegen_backend_arm64.h index 74586fb..cd506e1 100644 --- a/src/codegen_backend_arm64.h +++ b/src/codegen_backend_arm64.h @@ -9,9 +9,6 @@ #define HASH(l) ((l) & 0x1ffff) -#define BLOCK_GPF_OFFSET 0 -#define BLOCK_EXIT_OFFSET 32 - #define BLOCK_MAX 0x3c0 diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index cd771cb..a265016 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -129,4 +129,7 @@ extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; extern void *codegen_fp_round; -extern void *codegen_fp_round_quad; \ No newline at end of file +extern void *codegen_fp_round_quad; + +extern void *codegen_gpf_rout; +extern void *codegen_exit_rout; \ No newline at end of file diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index f253a4c..0a7e24d 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -599,9 +599,14 @@ void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { - int offset = dest - (uintptr_t)&block_write_data[block_pos]; + int offset; + + codegen_alloc(block, 4); + offset = dest - (uintptr_t)&block_write_data[block_pos]; if (offset_is_19bit(offset)) + { codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); + } else { codegen_alloc(block, 12); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index fd89d84..48f748b 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -242,7 +242,7 @@ static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_arm64_call(block, uop->p); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); return 0; } @@ -777,7 +777,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); host_arm64_mov_imm(block, REG_ARG0, 7); host_arm64_call(block, x86_int); - host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm64_B(block, codegen_exit_rout); host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); @@ -798,7 +798,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); host_arm64_mov_imm(block, REG_ARG0, 7); host_arm64_call(block, x86_int); - host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]); + host_arm64_B(block, codegen_exit_rout); host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); @@ -883,7 +883,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p); host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); host_arm64_call(block, (void *)loadseg); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); return 0; } @@ -908,7 +908,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) } else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); if (REG_IS_B(dest_size)) { host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); @@ -954,7 +954,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) } else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); if (REG_IS_B(dest_size)) { host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); @@ -990,7 +990,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) if (uop->imm_data) host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); host_arm64_call(block, codegen_mem_load_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); return 0; @@ -1007,7 +1007,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) if (uop->imm_data) host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); host_arm64_call(block, codegen_mem_load_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); return 0; @@ -1041,7 +1041,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) } else fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } @@ -1080,7 +1080,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) } else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } @@ -1092,7 +1092,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); host_arm64_mov_imm(block, REG_W1, uop->imm_data); host_arm64_call(block, codegen_mem_store_byte); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } @@ -1103,7 +1103,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); host_arm64_mov_imm(block, REG_W1, uop->imm_data); host_arm64_call(block, codegen_mem_store_word); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } @@ -1114,7 +1114,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); host_arm64_mov_imm(block, REG_W1, uop->imm_data); host_arm64_call(block, codegen_mem_store_long); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } @@ -1132,7 +1132,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); host_arm64_call(block, codegen_mem_store_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } @@ -1149,7 +1149,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); host_arm64_call(block, codegen_mem_store_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); return 0; } diff --git a/src/codegen_backend_arm_defs.h b/src/codegen_backend_arm_defs.h index def8970..2f50129 100644 --- a/src/codegen_backend_arm_defs.h +++ b/src/codegen_backend_arm_defs.h @@ -83,4 +83,7 @@ extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; -extern void *codegen_fp_round; \ No newline at end of file +extern void *codegen_fp_round; + +extern void *codegen_gpf_rout; +extern void *codegen_exit_rout; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index f402c49..17355cc 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -230,6 +230,12 @@ static inline void codegen_alloc_4(codeblock_t *block) codegen_allocate_new_block(block); } +void codegen_alloc(codeblock_t *block, int size) +{ + if (block_pos >= (BLOCK_MAX-size)) + codegen_allocate_new_block(block); +} + static inline uint32_t arm_data_offset(int offset) { if (offset < -0xffc || offset > 0xffc) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 59efc56..5160511 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -317,7 +317,7 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_arm_call(block, uop->p); host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -848,7 +848,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); host_arm_MOV_IMM(block, REG_ARG0, 7); host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_B(block, (uintptr_t)codegen_exit_rout); *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; @@ -869,7 +869,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); host_arm_MOV_IMM(block, REG_ARG0, 7); host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_B(block, (uintptr_t)codegen_exit_rout); *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; @@ -951,7 +951,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p); host_arm_call(block, loadseg); host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -977,7 +977,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); if (REG_IS_B(dest_size)) { host_arm_BFI(block, dest_reg, REG_R0, 0, 8); @@ -1025,7 +1025,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); if (REG_IS_B(dest_size)) { host_arm_BFI(block, dest_reg, REG_R0, 0, 8); @@ -1062,7 +1062,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); host_arm_BL(block, (uintptr_t)codegen_mem_load_single); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); return 0; @@ -1080,7 +1080,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); host_arm_BL(block, (uintptr_t)codegen_mem_load_double); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); return 0; @@ -1110,7 +1110,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) else fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -1151,7 +1151,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -1164,7 +1164,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) host_arm_MOV_IMM(block, REG_R1, uop->imm_data); host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -1176,7 +1176,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) host_arm_MOV_IMM(block, REG_R1, uop->imm_data); host_arm_BL(block, (uintptr_t)codegen_mem_store_word); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -1188,7 +1188,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) host_arm_MOV_IMM(block, REG_R1, uop->imm_data); host_arm_BL(block, (uintptr_t)codegen_mem_store_long); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -1206,7 +1206,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); host_arm_BL(block, (uintptr_t)codegen_mem_store_single); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } @@ -1224,7 +1224,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); host_arm_BL(block, (uintptr_t)codegen_mem_store_double); host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); return 0; } diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 86ed609..fff5942 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -31,6 +31,9 @@ void *codegen_mem_store_quad; void *codegen_mem_store_single; void *codegen_mem_store_double; +void *codegen_gpf_rout; +void *codegen_exit_rout; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_EAX, @@ -49,8 +52,6 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = REG_XMM6 }; -static void *mem_abrt_rout; - static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; @@ -274,6 +275,7 @@ static void build_loadstore_routines(codeblock_t *block) void codegen_backend_init() { + codeblock_t *block; int c; #if defined(__linux__) || defined(__APPLE__) void *start; @@ -295,10 +297,33 @@ void codegen_backend_init() block_current = 0; block_pos = 0; + block = &codeblock[block_current]; codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL); codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); block_write_data = codeblock[block_current].data; build_loadstore_routines(&codeblock[block_current]); + + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; +#if WIN64 + host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX, REG_ECX); + host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX, REG_EDX); +#else + host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI, REG_EDI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); +#endif + host_x86_CALL(block, (uintptr_t)x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); + block_write_data = NULL; asm( @@ -315,33 +340,6 @@ void codegen_set_rounding_mode(int mode) void codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_GPF_OFFSET; -#if WIN64 - host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX, REG_ECX); - host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX, REG_EDX); -#else - host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI, REG_EDI); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); -#endif - host_x86_CALL(block, (uintptr_t)x86gpf); - while (block_pos < BLOCK_EXIT_OFFSET) - host_x86_NOP(block); - if (block_pos > BLOCK_EXIT_OFFSET) - fatal("block_pos > BLOCK_EXIT_OFFSET\n"); - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); - if (block_pos > BLOCK_START) - fatal("block_pos > BLOCK_START\n"); - block_pos = BLOCK_START; /*Entry code*/ host_x86_PUSH(block, REG_RBX); host_x86_PUSH(block, REG_RBP); diff --git a/src/codegen_backend_x86-64.h b/src/codegen_backend_x86-64.h index de52c3c..150c8c8 100644 --- a/src/codegen_backend_x86-64.h +++ b/src/codegen_backend_x86-64.h @@ -2,14 +2,11 @@ #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff -#define BLOCK_START 40 +#define BLOCK_START 0 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff #define HASH(l) ((l) & 0x1ffff) -#define BLOCK_EXIT_OFFSET 20 -#define BLOCK_GPF_OFFSET 0 - #define BLOCK_MAX 0x3c0 diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index 7f93633..95a5294 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -60,3 +60,6 @@ extern void *codegen_mem_store_long; extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; + +extern void *codegen_gpf_rout; +extern void *codegen_exit_rout; diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index e49fe7f..79bfed3 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -197,7 +197,7 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -727,7 +727,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, REG_EDI, 7); #endif host_x86_CALL(block, x86_int); - host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JMP(block, codegen_exit_rout); *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; return 0; @@ -746,7 +746,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, REG_EDI, 7); #endif host_x86_CALL(block, x86_int); - host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JMP(block, codegen_exit_rout); *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); @@ -842,7 +842,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) #endif host_x86_CALL(block, (void *)loadseg); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -868,7 +868,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) { host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); @@ -911,7 +911,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) { host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); @@ -944,7 +944,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); return 0; @@ -962,7 +962,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); return 0; @@ -992,7 +992,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) else fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1005,7 +1005,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); host_x86_CALL(block, codegen_mem_store_byte); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1017,7 +1017,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); host_x86_CALL(block, codegen_mem_store_word); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1029,7 +1029,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); host_x86_CALL(block, codegen_mem_store_long); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1065,7 +1065,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1084,7 +1084,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1102,7 +1102,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 68d9a36..982f69d 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -32,6 +32,9 @@ void *codegen_mem_store_quad; void *codegen_mem_store_single; void *codegen_mem_store_double; +void *codegen_gpf_rout; +void *codegen_exit_rout; + int codegen_host_reg_list[CODEGEN_HOST_REGS] = { REG_EAX, @@ -49,8 +52,6 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = REG_XMM5 }; -static void *mem_abrt_rout; - static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; @@ -301,16 +302,19 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); block->head_mem_block = codegen_allocator_allocate(NULL); block->data = codeblock_allocator_get_ptr(block->head_mem_block); block_write_data = block->data; - mem_abrt_rout = &block->data[block_pos]; - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x10+4); + build_loadstore_routines(block); + + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); + host_x86_CALL(block, (void *)x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64); host_x86_POP(block, REG_EDI); host_x86_POP(block, REG_ESI); host_x86_POP(block, REG_EBP); host_x86_POP(block, REG_EDX); host_x86_RET(block); - - block_pos = 64; - build_loadstore_routines(block); block_write_data = NULL; cpu_state.old_fp_control = 0; @@ -333,18 +337,6 @@ void codegen_set_rounding_mode(int mode) void codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_GPF_OFFSET; - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); - host_x86_CALL(block, (void *)x86gpf); - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); - block_pos = BLOCK_START; /*Entry code*/ host_x86_PUSH(block, REG_EBX); host_x86_PUSH(block, REG_EBP); diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h index 52df734..7e32927 100644 --- a/src/codegen_backend_x86.h +++ b/src/codegen_backend_x86.h @@ -2,14 +2,11 @@ #define BLOCK_SIZE 0x4000 #define BLOCK_MASK 0x3fff -#define BLOCK_START 32 +#define BLOCK_START 0 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff #define HASH(l) ((l) & 0x1ffff) -#define BLOCK_EXIT_OFFSET 20 -#define BLOCK_GPF_OFFSET 0 - #define BLOCK_MAX 0x3c0 diff --git a/src/codegen_backend_x86_defs.h b/src/codegen_backend_x86_defs.h index 0c9eb1d..8999ca3 100644 --- a/src/codegen_backend_x86_defs.h +++ b/src/codegen_backend_x86_defs.h @@ -39,6 +39,9 @@ extern void *codegen_mem_store_quad; extern void *codegen_mem_store_single; extern void *codegen_mem_store_double; +extern void *codegen_gpf_rout; +extern void *codegen_exit_rout; + #define STACK_ARG0 (0) #define STACK_ARG1 (4) #define STACK_ARG2 (8) diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index b0a54af..9882f82 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -203,7 +203,7 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); // host_x86_CALL(block, codegen_debug); return 0; @@ -730,7 +730,7 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); host_x86_CALL(block, x86_int); - host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JMP(block, codegen_exit_rout); *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; return 0; @@ -746,7 +746,7 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); host_x86_CALL(block, x86_int); - host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JMP(block, codegen_exit_rout); *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); @@ -831,7 +831,7 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); host_x86_CALL(block, loadseg); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -857,7 +857,7 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) { host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); @@ -900,7 +900,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) { host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); @@ -933,7 +933,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); return 0; @@ -952,7 +952,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); return 0; @@ -982,7 +982,7 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) else fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1018,7 +1018,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1031,7 +1031,7 @@ static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); host_x86_CALL(block, codegen_mem_store_byte); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1043,7 +1043,7 @@ static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); host_x86_CALL(block, codegen_mem_store_word); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1055,7 +1055,7 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); host_x86_CALL(block, codegen_mem_store_long); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1074,7 +1074,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } @@ -1092,7 +1092,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]); + host_x86_JNZ(block, codegen_exit_rout); return 0; } diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c index d62e1e5..e5a34fd 100644 --- a/src/codegen_ops_branch.c +++ b/src/codegen_ops_branch.c @@ -48,7 +48,7 @@ static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -60,7 +60,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Overflow is always zero*/ uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); return; case FLAGS_SUB8: case FLAGS_DEC8: @@ -82,7 +82,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } @@ -115,7 +115,7 @@ static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -127,7 +127,7 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Carry is always zero*/ uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); return; case FLAGS_SUB8: @@ -149,7 +149,7 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } @@ -167,7 +167,7 @@ static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -184,7 +184,7 @@ void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } @@ -220,7 +220,7 @@ static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -253,7 +253,7 @@ static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); @@ -305,7 +305,7 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -354,7 +354,7 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } @@ -365,7 +365,7 @@ static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -375,7 +375,7 @@ static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } @@ -414,7 +414,7 @@ static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -452,7 +452,7 @@ static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } @@ -484,7 +484,7 @@ static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) @@ -513,7 +513,7 @@ static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, break; } uop_MOV_IMM(ir, IREG_pc, base_pc + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); @@ -570,7 +570,7 @@ uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet else jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); return op_pc+1; @@ -592,7 +592,7 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); } uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); return op_pc+1; @@ -623,7 +623,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); } uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); @@ -654,7 +654,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); } uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); - uop_JMP(ir, &block->data[BLOCK_EXIT_OFFSET]); + uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); diff --git a/src/codegen_ops_shift.c b/src/codegen_ops_shift.c index 90547d1..d4b5b56 100644 --- a/src/codegen_ops_shift.c +++ b/src/codegen_ops_shift.c @@ -362,7 +362,7 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch return 0; uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); if ((fetchdat & 0xc0) == 0xc0) { @@ -453,7 +453,7 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet return 0; uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); if ((fetchdat & 0xc0) == 0xc0) { @@ -544,7 +544,7 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet return 0; uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); if ((fetchdat & 0xc0) == 0xc0) { From ac886c420f720725e7eac60db207ccbe0d3377e3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 13 Jan 2019 12:58:07 +0000 Subject: [PATCH 0584/1050] Increase ARMv7 and v8 code block count to the normal default of 16384, now that this no longer leads to a massive increase in memory usage. --- src/codegen_backend_arm.h | 6 +++--- src/codegen_backend_arm64.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/codegen_backend_arm.h b/src/codegen_backend_arm.h index cc4a642..bfd5206 100644 --- a/src/codegen_backend_arm.h +++ b/src/codegen_backend_arm.h @@ -1,8 +1,8 @@ #include "codegen_backend_arm_defs.h" -#define BLOCK_SIZE 0x1000 -#define BLOCK_MASK 0x0fff -#define BLOCK_START 64 +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff diff --git a/src/codegen_backend_arm64.h b/src/codegen_backend_arm64.h index cd506e1..1fb0cfb 100644 --- a/src/codegen_backend_arm64.h +++ b/src/codegen_backend_arm64.h @@ -1,8 +1,8 @@ #include "codegen_backend_arm64_defs.h" -#define BLOCK_SIZE 0x1000 -#define BLOCK_MASK 0x0fff -#define BLOCK_START 64 +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff From 1ddcbdaf4c94656bcc247a9f960c8b590158e67d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 13 Jan 2019 22:12:39 +0000 Subject: [PATCH 0585/1050] Added emulation of CGA 3d8h bit 3 (display enable). --- src/vid_cga.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/vid_cga.c b/src/vid_cga.c index 7b616fc..fe7f903 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -169,8 +169,13 @@ void cga_poll(void *p) { for (x = 0; x < cga->crtc[1]; x++) { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; + if (cga->cgamode & 8) + { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + } + else + chr = attr = 0; drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); if (cga->cgamode & 0x20) { @@ -201,8 +206,13 @@ void cga_poll(void *p) { for (x = 0; x < cga->crtc[1]; x++) { - chr = cga->vram[((cga->ma << 1) & 0x3fff)]; - attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + if (cga->cgamode & 8) + { + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + } + else + chr = attr = 0; drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); if (cga->cgamode & 0x20) { @@ -255,7 +265,10 @@ void cga_poll(void *p) } for (x = 0; x < cga->crtc[1]; x++) { - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; cga->ma++; for (c = 0; c < 8; c++) { @@ -271,7 +284,10 @@ void cga_poll(void *p) cols[1] = cga->cgacol & 15; for (x = 0; x < cga->crtc[1]; x++) { - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; cga->ma++; for (c = 0; c < 16; c++) { From 2c5824f2cdde6da720e0a0727e5b38aa12a582f6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 15 Jan 2019 20:00:17 +0000 Subject: [PATCH 0586/1050] Added ASUS P/I-P55T2P4 emulation, along with i430HX chipset emulation. Patch from Martin_Riarte. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- src/i430hx.c | 144 +++++++++++++++++++++++++++++ src/i430hx.h | 1 + src/ibm.h | 1 + src/intel_flash.c | 3 + src/mem_bios.c | 8 ++ src/model.c | 19 +++- src/nvr.c | 2 + 13 files changed, 183 insertions(+), 7 deletions(-) create mode 100644 src/i430hx.c create mode 100644 src/i430hx.h diff --git a/src/Makefile.am b/src/Makefile.am index a45f83c..5ae98ce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ wx-resources.cpp : pc.xrc pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ +hdd.c hdd_esdi.c hdd_file.c headland.c i430hx.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 450a3e6..490e946 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -7,7 +7,7 @@ CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index dab01f4..4a330d6 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -7,7 +7,7 @@ CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index cbf8c22..eb39856 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -8,7 +8,7 @@ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ - device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 41e90c3..f811df3 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -8,7 +8,7 @@ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ - device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ + device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index b0b3445..a2e0a8e 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -6,7 +6,7 @@ CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64= OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ +hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ diff --git a/src/i430hx.c b/src/i430hx.c new file mode 100644 index 0000000..fce9a01 --- /dev/null +++ b/src/i430hx.c @@ -0,0 +1,144 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "pci.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) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +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 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) + { + 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) + i430hx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i430hx[0x5a] ^ val) & 0xf0) + i430hx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i430hx[0x5b] ^ val) & 0x0f) + i430hx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i430hx[0x5b] ^ val) & 0xf0) + i430hx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i430hx[0x5c] ^ val) & 0x0f) + i430hx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i430hx[0x5c] ^ val) & 0xf0) + i430hx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i430hx[0x5d] ^ val) & 0x0f) + i430hx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i430hx[0x5d] ^ val) & 0xf0) + i430hx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i430hx[0x5e] ^ val) & 0x0f) + 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; + } + + card_i430hx[addr] = val; +} + +uint8_t i430hx_read(int func, int addr, void *priv) +{ + if (func) + return 0xff; + + return card_i430hx[addr]; +} + + +void i430hx_init() +{ + 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*/ + card_i430hx[0x04] = 0x06; card_i430hx[0x05] = 0x00; + card_i430hx[0x07] = 0x02; + card_i430hx[0x08] = 0x00; /*A0 stepping*/ + card_i430hx[0x0B] = 0x06; + card_i430hx[0x51] = 0x20; + card_i430hx[0x52] = 0xB5; /*512kb cache*/ + card_i430hx[0x56] = 0x52; /*DRAM control*/ + card_i430hx[0x59] = 0x40; + card_i430hx[0x5A] = card_i430hx[0x5B] = card_i430hx[0x5C] = card_i430hx[0x5D] = 0x44; + card_i430hx[0x5E] = card_i430hx[0x5F] = 0x44; + card_i430hx[0x60] = card_i430hx[0x61] = card_i430hx[0x62] = card_i430hx[0x63] = 0x02; + card_i430hx[0x64] = card_i430hx[0x5F] = 0x02; + card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02; + card_i430hx[0x68] = 0x11; +} diff --git a/src/i430hx.h b/src/i430hx.h new file mode 100644 index 0000000..5a5a7b4 --- /dev/null +++ b/src/i430hx.h @@ -0,0 +1 @@ +void i430hx_init(); diff --git a/src/ibm.h b/src/ibm.h index 110b755..702d93e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -440,6 +440,7 @@ enum ROM_IBMPS1_2121, ROM_AMI386DX_OPTI495, ROM_MR386DX_OPTI495, + ROM_P55T2P4, /* ASUS P/I-P55T2P4/430HX/Award/Winbond W8387F*/ ROM_IBMPS2_M30_286, ROM_IBMPS2_M50, ROM_IBMPS2_M55SX, diff --git a/src/intel_flash.c b/src/intel_flash.c index 43c0825..526d6f0 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -185,6 +185,9 @@ void *intel_flash_init(uint8_t type) case ROM_430VX: strcpy(flash_path, "430vx/"); break; + case ROM_P55T2P4: + strcpy(flash_path, "p55t2p4/"); + break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); } diff --git a/src/mem_bios.c b/src/mem_bios.c index 0df10e6..143490c 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -494,6 +494,14 @@ int loadbios() //is486=1; return 1; + case ROM_P55T2P4: + f = romfopen("p55t2p4/0207_j2.bin", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_REVENGE: f = romfopen("revenge/1009af2_.bio", "rb"); if (!f) break; diff --git a/src/model.c b/src/model.c index dc15b0a..2c898b4 100644 --- a/src/model.c +++ b/src/model.c @@ -19,6 +19,7 @@ #include "gameport.h" #include "headland.h" #include "i430fx.h" +#include "i430hx.h" #include "i430lx.h" #include "i430vx.h" #include "ide.h" @@ -99,6 +100,7 @@ void at_p55tvp4_init(); void at_i430vx_init(); void at_batman_init(); void at_endeavor_init(); +void at_p55t2p4_init(); void xt_laserxt_init(); void at_t3100e_init(); void xt_t1000_init(); @@ -196,8 +198,9 @@ MODEL models[] = {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55tvp4_init, NULL}, - {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55va_init, NULL}, + {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_p55t2p4_init, NULL}, {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55va_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; @@ -713,6 +716,20 @@ void at_i430vx_init() device_add(&intel_flash_bxt_device); } +void at_p55t2p4_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x0C); + pci_slot(0x0B); + pci_slot(0x0A); + pci_slot(0x09); + i430hx_init(); + piix_init(7, 0x0C, 0x0B, 0x0A, 0x09); + um8669f_init(); + device_add(&intel_flash_bxt_device); +} + void model_init() { pclog("Initting as %s\n", model_getname()); diff --git a/src/nvr.c b/src/nvr.c index eca7a1e..2585544 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -287,6 +287,7 @@ void loadnvr() case ROM_430VX: f = nvrfopen("430vx.nvr", "rb"); nvrmask = 127; break; case ROM_REVENGE: f = nvrfopen("revenge.nvr", "rb"); nvrmask = 127; break; case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "rb"); nvrmask = 127; break; + case ROM_P55T2P4: f = nvrfopen("p55t2p4.nvr", "rb"); nvrmask = 127; break; case ROM_PX386: f = nvrfopen("px386.nvr", "rb"); nvrmask = 127; break; case ROM_DTK386: f = nvrfopen("dtk386.nvr", "rb"); nvrmask = 127; break; case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "rb"); nvrmask = 127; break; @@ -382,6 +383,7 @@ void savenvr() case ROM_430VX: f = nvrfopen("430vx.nvr", "wb"); break; case ROM_REVENGE: f = nvrfopen("revenge.nvr", "wb"); break; case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "wb"); break; + case ROM_P55T2P4: f = nvrfopen("p55t2p4.nvr", "wb"); break; case ROM_PX386: f = nvrfopen("px386.nvr", "wb"); break; case ROM_DTK386: f = nvrfopen("dtk386.nvr", "wb"); break; case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "wb"); break; From 140903f4cb4550f7b76da4e94eef4e7f681708d7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 15 Jan 2019 21:33:24 +0000 Subject: [PATCH 0587/1050] Tweaked S3 ViRGE clipping. Based on patch from rene. --- src/vid_s3_virge.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 7f2b72e..d0ffe56 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -2975,7 +2975,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 y_count -= diff_y; } if ((state->y - y_count) < s3d_tri->clip_t) - y_count = state->y - s3d_tri->clip_t; + y_count = (state->y - s3d_tri->clip_t) + 1; } for (; y_count > 0; y_count--) @@ -3018,7 +3018,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (xe < s3d_tri->clip_l) goto tri_skip_line; if (xe > s3d_tri->clip_r) - xe = s3d_tri->clip_r; + xe = s3d_tri->clip_r + 1; if (x < s3d_tri->clip_l) { int diff_x = s3d_tri->clip_l - x; @@ -3043,7 +3043,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (xe > s3d_tri->clip_r) goto tri_skip_line; if (xe < s3d_tri->clip_l) - xe = s3d_tri->clip_l; + xe = s3d_tri->clip_l - 1; if (x > s3d_tri->clip_r) { int diff_x = x - s3d_tri->clip_r; @@ -3068,6 +3068,9 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 dest_addr = dest_offset + (x * (bpp + 1)); z_addr = z_offset + (x << 1); + x &= 0xfff; + xe &= 0xfff; + for (; x != xe; x = (x + x_dir) & 0xfff) { int update = 1; From cc4118fca0e0a3d627858751c979f9c33e37b539 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 16 Jan 2019 18:33:27 +0000 Subject: [PATCH 0588/1050] Remove duplicate i430hx.c in Makefile.am --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 5ae98ce..0aa3d5f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ wx-resources.cpp : pc.xrc pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -hdd.c hdd_esdi.c hdd_file.c headland.c i430hx.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ +hdd.c hdd_esdi.c hdd_file.c headland.c i430hx.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c \ opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ From 178c9d5c1549ba8b8d56d64e13f9c6089f583445 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 16 Jan 2019 21:54:10 +0000 Subject: [PATCH 0589/1050] Don't write back temporary registers if they won't be read again. --- src/codegen_reg.c | 170 +++++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 77 deletions(-) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index c222d04..7c74153 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -45,109 +45,120 @@ enum REG_FP }; +enum +{ + /*Register may be accessed outside of code block, and must be written + back before any control transfers*/ + REG_PERMANENT = 0, + /*Register will not be accessed outside of code block, and does not need + to be written back if there are no readers remaining*/ + REG_VOLATILE = 1 +}; + struct { int native_size; void *p; int type; + int is_volatile; } ireg_data[IREG_COUNT] = { - [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER}, - [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER}, - [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER}, - [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER}, - [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER}, - [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER}, - [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER}, - [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER}, + [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, + [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, + [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, + [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, + [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, + [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, + [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, + [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER}, - [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER}, - [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER}, - [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER}, + [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, - [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER}, - [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER}, + [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, + [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, - [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER}, - [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER}, + [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, + [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, - [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER}, - [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER}, + [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, + [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, - [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER}, + [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, - [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER}, - [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER}, + [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER, REG_PERMANENT}, + [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER}, - [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER}, - [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER}, - [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER}, - [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER}, - [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER}, + [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER}, - [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER}, - [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER}, - [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER}, - [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER}, - [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER}, + [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER}, + [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, - [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, - [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP}, + [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, - [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, + [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP}, + [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP}, - [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP}, - [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP}, - [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP}, - [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP}, - [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP}, - [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP}, - [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP}, + [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, + [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, + [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, + [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, + [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, + [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, + [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, - [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER}, - [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, + [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, - [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER}, - [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER}, + [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, + [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER}, - [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER}, - [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER}, - [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER}, + [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER, REG_VOLATILE}, + [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER, REG_VOLATILE}, + [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER, REG_VOLATILE}, + [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER, REG_VOLATILE}, - [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP}, - [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP}, + [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE}, + [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE}, }; static int reg_is_native_size(ir_reg_t ir_reg) @@ -317,6 +328,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); void *p = ireg_data[ir_reg].p; + if (!reg_version_refcount[ir_reg][reg_set->regs[c].version] && + ireg_data[ir_reg].is_volatile) + return; + switch (ireg_data[ir_reg].native_size) { case REG_BYTE: @@ -520,7 +535,7 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in // pclog(" already loaded %i\n", c); reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version]--; - if (reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] < 0) + if (reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] == (uint8_t)-1) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); if (host_reg_idx) @@ -541,6 +556,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; parent_reg.version = ir_reg.version - 1; + reg_version_refcount[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1]++; codegen_reg_alloc_read_reg(block, parent_reg, &c); From 13087d0031d17752c8a8cdca9d066c9b81755a83 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 17 Jan 2019 18:05:27 +0000 Subject: [PATCH 0590/1050] Added missing codegen allocator files --- src/codegen_allocator.c | 117 ++++++++++++++++++++++++++++++++++++++++ src/codegen_allocator.h | 38 +++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 src/codegen_allocator.c create mode 100644 src/codegen_allocator.h diff --git a/src/codegen_allocator.c b/src/codegen_allocator.c new file mode 100644 index 0000000..3dba230 --- /dev/null +++ b/src/codegen_allocator.c @@ -0,0 +1,117 @@ +#if defined(__linux__) || defined(__APPLE__) +#include +#include +#endif +#if defined WIN32 || defined _WIN32 || defined _WIN32 +#include +#endif + +#include "ibm.h" +#include "codegen.h" +#include "codegen_allocator.h" + +typedef struct mem_block_t +{ + uint32_t offset; /*Offset into mem_block_alloc*/ + uint32_t next; +} mem_block_t; + +static mem_block_t mem_blocks[MEM_BLOCK_NR]; +static uint32_t mem_block_free_list; +static uint8_t *mem_block_alloc = NULL; + +int codegen_allocator_usage = 0; + +void codegen_allocator_init() +{ + int c; + +#if defined WIN32 || defined _WIN32 || defined _WIN32 + mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); +#endif + + for (c = 0; c < MEM_BLOCK_NR; c++) + { + mem_blocks[c].offset = c * MEM_BLOCK_SIZE; + if (c < MEM_BLOCK_NR-1) + mem_blocks[c].next = c+2; + else + mem_blocks[c].next = 0; + } + mem_block_free_list = 1; +} + +mem_block_t *codegen_allocator_allocate(mem_block_t *parent) +{ + mem_block_t *block; + uint32_t block_nr; + + while (!mem_block_free_list) + { + codegen_delete_random_block(); + } +// fatal("codegen_allocator_allocate: free list empty!\n"); + + /*Remove from free list*/ + block_nr = mem_block_free_list; + block = &mem_blocks[block_nr-1]; + mem_block_free_list = block->next; + + if (parent) + { + /*Add to parent list*/ + block->next = parent->next; + parent->next = block_nr; + } + else + block->next = 0; + + codegen_allocator_usage++; +/* if (parent) + pclog("codegen_allocator_allocate with parent: %p %i %i %p\n", block, block_nr, codegen_allocator_usage, parent); + else + pclog("codegen_allocator_allocate: %p %i %i\n", block, block_nr, codegen_allocator_usage);*/ + return block; +} +void codegen_allocator_free(mem_block_t *block) +{ + int block_nr = (((uintptr_t)block - (uintptr_t)mem_blocks) / sizeof(mem_block_t)) + 1; + +// pclog("codegen_allocator_free: %p %i %i %i\n", block, block_nr, codegen_allocator_usage, block->next); + while (1) + { + int next_block_nr = block->next; +// pclog(" free next=%i\n", next_block_nr); + codegen_allocator_usage--; + + block->next = mem_block_free_list; + mem_block_free_list = block_nr; + block_nr = next_block_nr; + + if (block_nr) + block = &mem_blocks[block_nr - 1]; + else + break; + } +} + +uint8_t *codeblock_allocator_get_ptr(mem_block_t *block) +{ + return &mem_block_alloc[block->offset]; +} + +void codegen_allocator_clean_blocks(struct mem_block_t *block) +{ +#if defined __ARM_EABI__ || defined __aarch64__ + while (1) + { + __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); + if (block->next) + block = &mem_blocks[block->next - 1]; + else + break; + } +#endif +} diff --git a/src/codegen_allocator.h b/src/codegen_allocator.h new file mode 100644 index 0000000..22504bf --- /dev/null +++ b/src/codegen_allocator.h @@ -0,0 +1,38 @@ +#ifndef _CODEGEN_ALLOCATOR_H_ +#define _CODEGEN_ALLOCATOR_H_ + +/*The allocator handles all allocation of executable memory. Since the two-pass + recompiler design makes applying hard limits to codeblock size difficult, the + allocator allows memory to be provided as and when required. + + The allocator provides a block size of a little under 1 kB (slightly lower to + limit cache aliasing). Each generated codeblock is allocated one block by default, + and will allocate additional block(s) once the existing memory is sorted. Blocks + are chained together by jump instructions. + + Due to the chaining, the total memory size is limited by the range of a jump + instruction. ARMv7 is restricted to +/- 32 MB, ARMv8 to +/- 128 MB, x86 to + +/- 2GB. As a result, total memory size is limited to 32 MB on ARMv7*/ +#ifdef __ARM_EABI__ +#define MEM_BLOCK_NR 32768 +#else +#define MEM_BLOCK_NR 65536 +#endif + +#define MEM_BLOCK_SIZE 0x3c0 + +void codegen_allocator_init(); +/*Allocate a mem_block_t, and the associated backing memory. + If parent is non-NULL, then the new block will be added to the list in + parent->next*/ +struct mem_block_t *codegen_allocator_allocate(struct mem_block_t *parent); +/*Free a mem_block_t, and any subsequent blocks in the list at block->next*/ +void codegen_allocator_free(struct mem_block_t *block); +/*Get a pointer to the backing memory associated with block*/ +uint8_t *codeblock_allocator_get_ptr(struct mem_block_t *block); +/*Cache clean memory block list*/ +void codegen_allocator_clean_blocks(struct mem_block_t *block); + +extern int codegen_allocator_usage; + +#endif From 57579cdd0762f53d22bf6abe8fb52970df5f964f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 19 Jan 2019 18:05:27 +0000 Subject: [PATCH 0591/1050] Add dummy USB and ACPI implementations to VT82C586B. Windows 2000 and XP now work on FIC VA-503+. --- src/vt82c586b.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/vt82c586b.c b/src/vt82c586b.c index 34a064b..2540d5c 100644 --- a/src/vt82c586b.c +++ b/src/vt82c586b.c @@ -20,8 +20,22 @@ static struct uint8_t sysctrl; sff_busmaster_t busmaster[2]; + + struct + { + uint16_t io_base; + } usb; + struct + { + uint16_t io_base; + } power; } vt82c586b; +#define ACPI_TIMER_FREQ 3579545 + +#define ACPI_IO_ENABLE (1 << 7) +#define ACPI_TIMER_32BIT (1 << 3) + static uint8_t vt82c586b_read(int func, int addr, void *priv) { switch (func) @@ -157,6 +171,28 @@ static void vt82c586b_ide_write(int addr, uint8_t val) } } } + +static uint8_t usb_reg_read(uint16_t addr, void *p) +{ +// pclog("usb_reg_read: addr=%04x\n", addr); + switch (addr & 0x1f) + { + case 0x10: case 0x11: case 0x12: case 0x13: /*Port status*/ + return 0; + } + return 0xff; +} +static void usb_reg_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("usb_reg_write: addr=%04x val=%02x\n", addr, val); +} +static void usb_update_io_mapping() +{ + io_removehandler(vt82c586b.usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, NULL); + vt82c586b.usb.io_base = (vt82c586b.usb_regs[0x20] & ~0x1f) | (vt82c586b.usb_regs[0x21] << 8); + if (vt82c586b.usb_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + io_sethandler(vt82c586b.usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, NULL); +} static void vt82c586b_usb_write(int addr, uint8_t val) { /*Read-only addresses*/ @@ -174,6 +210,7 @@ static void vt82c586b_usb_write(int addr, uint8_t val) { case 4: vt82c586b.usb_regs[4] = val & 0x97; + usb_update_io_mapping(); break; case 7: vt82c586b.usb_regs[7] = val & 0x7f; @@ -181,12 +218,38 @@ static void vt82c586b_usb_write(int addr, uint8_t val) case 0x20: vt82c586b.usb_regs[0x20] = (val & ~0x1f) | 1; + usb_update_io_mapping(); + break; + case 0x21: + vt82c586b.usb_regs[0x21] = val; + usb_update_io_mapping(); break; default: vt82c586b.usb_regs[addr] = val; break; } +// pclog(" USB write %02x %02x\n", addr, val); +} + +static uint8_t power_reg_read(uint16_t addr, void *p) +{ + uint32_t timer; + + switch (addr & 0xff) + { + case 0x08: case 0x09: case 0x0a: case 0x0b: /*ACPI timer*/ + timer = (tsc * ACPI_TIMER_FREQ) / cpu_get_speed(); + if (!(vt82c586b.power_regs[0x41] & ACPI_TIMER_32BIT)) + timer &= 0x00ffffff; + return (timer >> (8 * (addr & 3))) & 0xff; + } +// pclog("power_reg_read: addr=%04x\n", addr); + return 0xff; +} +static void power_reg_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("power_reg_write: addr=%04x val=%02x\n", addr, val); } static void vt82c586b_power_write(int addr, uint8_t val) { @@ -200,6 +263,21 @@ static void vt82c586b_power_write(int addr, uint8_t val) switch (addr) { + case 0x41: + io_removehandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); + vt82c586b.power_regs[addr] = val; + if (vt82c586b.power_regs[0x41] & ACPI_IO_ENABLE) + io_sethandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); + break; + + case 0x49: + io_removehandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); + vt82c586b.power_regs[addr] = val; + vt82c586b.power.io_base = val << 8; + if (vt82c586b.power_regs[0x41] & ACPI_IO_ENABLE) + io_sethandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); + break; + default: vt82c586b.power_regs[addr] = val; break; From 9c595f4b9b63b4960295d0a18afc554922f4615f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 19 Jan 2019 18:06:14 +0000 Subject: [PATCH 0592/1050] Add CMPXCHG8B to the K6 timing model. --- src/codegen_timing_k6.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/codegen_timing_k6.c b/src/codegen_timing_k6.c index 590e605..8499cfa 100644 --- a/src/codegen_timing_k6.c +++ b/src/codegen_timing_k6.c @@ -1204,7 +1204,7 @@ static const risc86_instruction_t *opcode_timings_0f[256] = &vector_bsx_op, &vector_bsx_op, &load_alux_op, &load_alu_op, /*c0*/ &vector_alux_store_op, &vector_alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, &vector_cmpxchg_op, &bswap_op, &bswap_op, &bswap_op, &bswap_op, &bswap_op, &bswap_op, &bswap_op, &bswap_op, @@ -2330,6 +2330,8 @@ void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint } } + if (!ins_table[opcode]) + fatal("!ins_table opcode=%02x last_prefix=%02x\n", opcode, last_prefix); decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } From c07a3b5311cc95cc59a434df07110fa9b2be4643 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 19 Jan 2019 18:08:45 +0000 Subject: [PATCH 0593/1050] Free currently allocated memory blocks on CPU reset. Prevents memory leaks when resetting. --- src/codegen_backend.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend.c b/src/codegen_backend.c index db786b2..8dca3b2 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -94,7 +94,15 @@ void codegen_close() void codegen_reset() { int c; - + + for (c = 1; c < BLOCK_SIZE; c++) + { + codeblock_t *block = &codeblock[c]; + + if (block->pc != BLOCK_PC_INVALID) + delete_block(block); + } + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); mem_reset_page_blocks(); From bf392ffd3a19f4308f54069a897ebf39af57ec79 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 19 Jan 2019 21:54:14 +0000 Subject: [PATCH 0594/1050] Maintain a list of free code blocks, and allocate new blocks from the list rather than evicting at random. Also maintain a list of memory pages with dirty code blocks that can be evicted. This allows the recompiler to evict dirty blocks in preference to freeing usable blocks when the free list is empty. Increase the number of available code blocks on x86. Increase the non-ARM code allocator memory to 128 MB. This reduces the amount of code block churning when running software with a lot of code, eg Windows XP. --- src/codegen.h | 13 ++-- src/codegen_allocator.c | 3 +- src/codegen_allocator.h | 2 +- src/codegen_backend.c | 124 ++++++++++++++++++++++++++++++-------- src/codegen_backend_x86.h | 4 +- src/mem.c | 74 ++++++++++++++++++++--- src/mem.h | 13 ++++ 7 files changed, 189 insertions(+), 44 deletions(-) diff --git a/src/codegen.h b/src/codegen.h index e76391b..39c101f 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -29,12 +29,6 @@ same page). */ -/*Hack until better memory management written*/ -/*This is deliberately _not_ a power of two, to avoid cache aliasing problems. - Try changing this to a power of two, and watch the performance plummet :) - It's probably best for this to be a multiple of the cache line size though*/ -#define BLOCK_DATA_SIZE 0xff80 - typedef struct codeblock_t { uint32_t pc; @@ -59,7 +53,7 @@ typedef struct codeblock_t present in two pages.*/ uint16_t prev, next; uint16_t prev_2, next_2; - + /*First mem_block_t used by this block. Any subsequent mem_block_ts will be in the list starting at head_mem_block->next.*/ struct mem_block_t *head_mem_block; @@ -77,6 +71,8 @@ extern uint8_t *block_write_data; #define CODEBLOCK_STATIC_TOP 2 /*Code block has been compiled*/ #define CODEBLOCK_WAS_RECOMPILED 4 +/*Code block is in free list and is not valid*/ +#define CODEBLOCK_IN_FREE_LIST 8 #define BLOCK_PC_INVALID 0xffffffff @@ -304,9 +300,10 @@ x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fe void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); +int codegen_purge_purgable_list(); /*Delete a random code block to free memory. This is obviously quite expensive, and will only be called when the allocator is out of memory*/ -void codegen_delete_random_block(); +void codegen_delete_random_block(int required_mem_block); extern int cpu_block_end; extern uint32_t codegen_endpc; diff --git a/src/codegen_allocator.c b/src/codegen_allocator.c index 3dba230..b6b8273 100644 --- a/src/codegen_allocator.c +++ b/src/codegen_allocator.c @@ -50,7 +50,8 @@ mem_block_t *codegen_allocator_allocate(mem_block_t *parent) while (!mem_block_free_list) { - codegen_delete_random_block(); + if (!codegen_purge_purgable_list()) + codegen_delete_random_block(1); } // fatal("codegen_allocator_allocate: free list empty!\n"); diff --git a/src/codegen_allocator.h b/src/codegen_allocator.h index 22504bf..ffe633c 100644 --- a/src/codegen_allocator.h +++ b/src/codegen_allocator.h @@ -16,7 +16,7 @@ #ifdef __ARM_EABI__ #define MEM_BLOCK_NR 32768 #else -#define MEM_BLOCK_NR 65536 +#define MEM_BLOCK_NR 131072 #endif #define MEM_BLOCK_SIZE 0x3c0 diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 8dca3b2..034ad61 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -53,10 +53,71 @@ static int last_ssegs; uint32_t instr_counts[256*256]; #endif +static uint16_t block_free_list; +static void delete_block(codeblock_t *block); + +static void block_free_list_add(codeblock_t *block) +{ + if (block_free_list) + block->next = block_free_list; + else + block->next = 0; + block_free_list = get_block_nr(block); + block->flags = CODEBLOCK_IN_FREE_LIST; +// pclog("block_free_list_add: %p %p\n", block, block->next); +} + +int codegen_purge_purgable_list() +{ + if (purgable_page_list_head) + { + page_t *page = &pages[purgable_page_list_head]; + int c; +// pclog("Purge page %08x\n", purgable_page_list_head); + for (c = 0; c < 4; c++) + { +// pclog(" Check %016llx %016llx\n", page->code_present_mask[c], page->dirty_mask[c]); + if (page->code_present_mask[c] & page->dirty_mask[c]) + { + codegen_check_flush(page, page->dirty_mask[c], (purgable_page_list_head << 12) + (c << 10)); +// pclog(" Check %08x %i\n", (purgable_page_list_head << 12) + (c << 10), block_free_list); + if (block_free_list) + return 1; + } + } + } + return 0; +} + +static codeblock_t *block_free_list_get() +{ + codeblock_t *block = NULL; + + while (!block_free_list) + { + /*Free list is empty - free up a block*/ + if (!codegen_purge_purgable_list()) + codegen_delete_random_block(0); + } + + block = &codeblock[block_free_list]; + block_free_list = block->next; + block->flags &= ~CODEBLOCK_IN_FREE_LIST; + block->next = 0; +// pclog("block_free_list_get: %p %p\n", block, block_free_list); + return block; +} + void codegen_init() { + int c; + codegen_allocator_init(); + codegen_backend_init(); + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) + block_free_list_add(&codeblock[c]); #ifdef DEBUG_EXTRA memset(instr_counts, 0, sizeof(instr_counts)); #endif @@ -106,9 +167,13 @@ void codegen_reset() memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); mem_reset_page_blocks(); - + + block_free_list = 0; for (c = 0; c < BLOCK_SIZE; c++) + { codeblock[c].pc = BLOCK_PC_INVALID; + block_free_list_add(&codeblock[c]); + } } void dump_block() @@ -232,24 +297,26 @@ static void delete_block(codeblock_t *block) if (block->head_mem_block) codegen_allocator_free(block->head_mem_block); block->head_mem_block = NULL; + block_free_list_add(block); } -void codegen_delete_random_block() +void codegen_delete_random_block(int required_mem_block) { + int block_nr = rand() & BLOCK_MASK; + while (1) { - int block_nr = rand() & BLOCK_MASK; - if (block_nr && block_nr != block_current) { codeblock_t *block = &codeblock[block_nr]; - - if (block->pc != BLOCK_PC_INVALID && block->head_mem_block) + + if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) { delete_block(block); return; } } + block_nr = (block_nr + 1) & BLOCK_MASK; } } @@ -260,15 +327,16 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) while (block_nr) { codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next; if (mask & block->page_mask) { delete_block(block); cpu_recomp_evicted++; } - if (block == &codeblock[block->next]) + if (block_nr == next_block) fatal("Broken 1\n"); - block_nr = block->next; + block_nr = next_block; } block_nr = page->block_2[(phys_addr >> 10) & 3]; @@ -276,16 +344,26 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) while (block_nr) { codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next_2; if (mask & block->page_mask2) { delete_block(block); cpu_recomp_evicted++; } - if (block == &codeblock[block->next_2]) + if (block_nr == next_block) fatal("Broken 2\n"); - block_nr = block->next_2; + block_nr = next_block; } + + page->code_present_mask[(phys_addr >> 10) & 3] &= ~mask; + page->dirty_mask[(phys_addr >> 10) & 3] &= ~mask; + + if (!(page->code_present_mask[0] & page->dirty_mask[0]) && + !(page->code_present_mask[1] & page->dirty_mask[1]) && + !(page->code_present_mask[2] & page->dirty_mask[2]) && + !(page->code_present_mask[3] & page->dirty_mask[3])) + page_remove_from_evict_list(page); } void codegen_block_init(uint32_t phys_addr) @@ -296,19 +374,11 @@ void codegen_block_init(uint32_t phys_addr) if (!page->block[(phys_addr >> 10) & 3]) mem_flush_write_page(phys_addr, cs+cpu_state.pc); - block_current = (block_current + 1) & BLOCK_MASK; - if (!block_current) - block_current++; - block = &codeblock[block_current]; + block = block_free_list_get(); + if (!block) + fatal("codegen_block_init: block_free_list_get() returned NULL\n"); + block_current = get_block_nr(block); -// if (block->pc == 0xb00b4ff5) -// pclog("Init target block\n"); - if (block->pc != BLOCK_PC_INVALID) - { -// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); - delete_block(block); - cpu_recomp_reuse++; - } block_num = HASH(phys_addr); codeblock_hash[block_num] = block_current; @@ -407,6 +477,7 @@ void codegen_block_generate_end_mask() codeblock_t *block = &codeblock[block_current]; uint32_t start_pc; uint32_t end_pc; + page_t *p; block->page_mask = 0; start_pc = (block->pc & 0x3ff) & ~15; @@ -426,7 +497,10 @@ void codegen_block_generate_end_mask() // pclog(" %08x %llx\n", start_pc, block->page_mask); } - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + p = &pages[block->phys >> 12]; + p->code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + if ((p->dirty_mask[(block->phys >> 10) & 3] & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); block->phys_2 = -1; block->page_mask2 = 0; @@ -443,7 +517,9 @@ void codegen_block_generate_end_mask() 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 ((page_2->dirty_mask[(block->phys_2 >> 10) & 3] & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) mem_flush_write_page(block->phys_2, codegen_endpc); diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h index 7e32927..db521a7 100644 --- a/src/codegen_backend_x86.h +++ b/src/codegen_backend_x86.h @@ -1,7 +1,7 @@ #include "codegen_backend_x86_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x10000 +#define BLOCK_MASK 0xffff #define BLOCK_START 0 #define HASH_SIZE 0x20000 diff --git a/src/mem.c b/src/mem.c index ad095a3..cc253d8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -924,14 +924,51 @@ uint32_t mem_read_raml(uint32_t addr, void *priv) return *(uint32_t *)&ram[addr]; } +uint32_t purgable_page_list_head = 0; +int purgeable_page_count = 0; + +static inline int page_index(page_t *p) +{ + return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); +} +void page_add_to_evict_list(page_t *p) +{ +// pclog("page_add_to_evict_list: %08x %i\n", page_index(p), purgeable_page_count); + pages[purgable_page_list_head].evict_prev = page_index(p); + p->evict_next = purgable_page_list_head; + p->evict_prev = 0; + purgable_page_list_head = pages[purgable_page_list_head].evict_prev; + purgeable_page_count++; +} +void page_remove_from_evict_list(page_t *p) +{ +// pclog("page_remove_from_evict_list: %08x %i\n", page_index(p), purgeable_page_count); + if (!page_in_evict_list(p)) + fatal("page_remove_from_evict_list: not in evict list!\n"); + if (p->evict_prev) + pages[p->evict_prev].evict_next = p->evict_next; + else + purgable_page_list_head = p->evict_next; + if (p->evict_next) + pages[p->evict_next].evict_prev = p->evict_prev; + p->evict_prev = EVICT_NOT_IN_LIST; + purgeable_page_count--; +} + 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[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + int index = (addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; +// pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask, mask); p->mem[addr & 0xfff] = val; + p->dirty_mask[index] |= mask; + if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + { +// pclog("ramb add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } } } void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) @@ -939,11 +976,17 @@ 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); + int index = (addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; if ((addr & 0xf) == 0xf) mask |= (mask << 1); -// pclog("mem_write_ramw_page: %08x %04x %08x\n", addr, val, cs+pc); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; +// pclog("mem_write_ramw_page: %08x %04x %08x %016llx %016llx %016llx %08x %08x %p\n", addr, val, cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask, p->evict_prev, p->evict_next, p); *(uint16_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask[index] |= mask; + if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + { +// pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } } } void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) @@ -951,11 +994,17 @@ 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); + int index = (addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; if ((addr & 0xf) >= 0xd) mask |= (mask << 1); -// pclog("mem_write_raml_page: %08x %08x %08x\n", addr, val, cs+pc); - p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; +// pclog("mem_write_raml_page: %08x %08x %08x %016llx %016llx %016llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask); *(uint32_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask[index] |= mask; + if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + { +// pclog("raml add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } } } @@ -1066,8 +1115,15 @@ 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[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; + page_t *p = &pages[start_addr >> 12]; + int index = (start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; +//pclog("mem_invalidate: %08x\n", start_addr); + p->dirty_mask[index] |= mask; + if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + { +// pclog("invalidate add %08x %016llx %016llx\n", start_addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } } } @@ -1330,6 +1386,7 @@ void mem_init() 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].evict_prev = EVICT_NOT_IN_LIST; } memset(isram, 0, sizeof(isram)); @@ -1439,6 +1496,7 @@ void mem_resize() 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].evict_prev = EVICT_NOT_IN_LIST; } memset(isram, 0, sizeof(isram)); diff --git a/src/mem.h b/src/mem.h index a015acc..3a27a92 100644 --- a/src/mem.h +++ b/src/mem.h @@ -111,6 +111,7 @@ mem_mapping_t bios_high_mapping[8]; extern mem_mapping_t ram_high_mapping; extern mem_mapping_t ram_remapped_mapping; +#define EVICT_NOT_IN_LIST ((uint32_t)-1) typedef struct page_t { void (*write_b)(uint32_t addr, uint8_t val, struct page_t *p); @@ -125,12 +126,22 @@ typedef struct page_t uint16_t head; uint64_t code_present_mask[4], dirty_mask[4]; + + uint32_t evict_prev, evict_next; } page_t; extern page_t *pages; extern page_t **page_lookup; +extern uint32_t purgable_page_list_head; +static inline int page_in_evict_list(page_t *p) +{ + return (p->evict_prev != EVICT_NOT_IN_LIST); +} +void page_remove_from_evict_list(page_t *p); +void page_add_to_evict_list(page_t *p); + 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) @@ -195,4 +206,6 @@ void mmu_invalidate(uint32_t addr); int loadbios(); extern unsigned char isram[0x10000]; + +extern int purgeable_page_count; #endif From ec18c8a2fbb6a89a268b772fded2a95c7b25b92e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 21 Jan 2019 21:52:32 +0000 Subject: [PATCH 0595/1050] Implement more intelligent out-of-memory algorithm. --- src/codegen.h | 1 + src/codegen_allocator.c | 14 +++++++++++--- src/codegen_allocator.h | 3 ++- src/codegen_backend.c | 8 +++++++- src/codegen_backend_x86-64.c | 2 +- src/codegen_backend_x86-64_ops.c | 2 +- src/codegen_backend_x86.c | 2 +- src/codegen_backend_x86_ops.c | 2 +- 8 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/codegen.h b/src/codegen.h index 39c101f..1438dab 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -290,6 +290,7 @@ void codegen_block_remove(); void codegen_block_start_recompile(codeblock_t *block); void codegen_block_end_recompile(codeblock_t *block); void codegen_block_end(); +void codegen_delete_block(codeblock_t *block); void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc); void codegen_generate_seg_restore(); void codegen_set_op32(); diff --git a/src/codegen_allocator.c b/src/codegen_allocator.c index b6b8273..4b4ffd7 100644 --- a/src/codegen_allocator.c +++ b/src/codegen_allocator.c @@ -14,6 +14,7 @@ typedef struct mem_block_t { uint32_t offset; /*Offset into mem_block_alloc*/ uint32_t next; + uint16_t code_block; } mem_block_t; static mem_block_t mem_blocks[MEM_BLOCK_NR]; @@ -35,6 +36,7 @@ void codegen_allocator_init() for (c = 0; c < MEM_BLOCK_NR; c++) { mem_blocks[c].offset = c * MEM_BLOCK_SIZE; + mem_blocks[c].code_block = BLOCK_INVALID; if (c < MEM_BLOCK_NR-1) mem_blocks[c].next = c+2; else @@ -43,15 +45,19 @@ void codegen_allocator_init() mem_block_free_list = 1; } -mem_block_t *codegen_allocator_allocate(mem_block_t *parent) +mem_block_t *codegen_allocator_allocate(mem_block_t *parent, int code_block) { mem_block_t *block; uint32_t block_nr; while (!mem_block_free_list) { - if (!codegen_purge_purgable_list()) - codegen_delete_random_block(1); + /*Pick a random memory block and free the owning code block*/ + block_nr = rand() & MEM_BLOCK_MASK; + block = &mem_blocks[block_nr]; + + if (block->code_block && block->code_block != code_block) + codegen_delete_block(&codeblock[block->code_block]); } // fatal("codegen_allocator_allocate: free list empty!\n"); @@ -60,6 +66,7 @@ mem_block_t *codegen_allocator_allocate(mem_block_t *parent) block = &mem_blocks[block_nr-1]; mem_block_free_list = block->next; + block->code_block = code_block; if (parent) { /*Add to parent list*/ @@ -88,6 +95,7 @@ void codegen_allocator_free(mem_block_t *block) codegen_allocator_usage--; block->next = mem_block_free_list; + block->code_block = BLOCK_INVALID; mem_block_free_list = block_nr; block_nr = next_block_nr; diff --git a/src/codegen_allocator.h b/src/codegen_allocator.h index ffe633c..1adb243 100644 --- a/src/codegen_allocator.h +++ b/src/codegen_allocator.h @@ -19,13 +19,14 @@ #define MEM_BLOCK_NR 131072 #endif +#define MEM_BLOCK_MASK (MEM_BLOCK_NR-1) #define MEM_BLOCK_SIZE 0x3c0 void codegen_allocator_init(); /*Allocate a mem_block_t, and the associated backing memory. If parent is non-NULL, then the new block will be added to the list in parent->next*/ -struct mem_block_t *codegen_allocator_allocate(struct mem_block_t *parent); +struct mem_block_t *codegen_allocator_allocate(struct mem_block_t *parent, int code_block); /*Free a mem_block_t, and any subsequent blocks in the list at block->next*/ void codegen_allocator_free(struct mem_block_t *block); /*Get a pointer to the backing memory associated with block*/ diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 034ad61..c047ba3 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -300,6 +300,12 @@ static void delete_block(codeblock_t *block) block_free_list_add(block); } +void codegen_delete_block(codeblock_t *block) +{ + if (block->pc != BLOCK_PC_INVALID) + delete_block(block); +} + void codegen_delete_random_block(int required_mem_block) { int block_nr = rand() & BLOCK_MASK; @@ -419,7 +425,7 @@ void codegen_block_start_recompile(codeblock_t *block) if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) fatal("Recompile to used block!\n"); - block->head_mem_block = codegen_allocator_allocate(NULL); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); block->data = codeblock_allocator_get_ptr(block->head_mem_block); block->status = cpu_cur_status; diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index fff5942..2c1d970 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -298,7 +298,7 @@ void codegen_backend_init() block_current = 0; block_pos = 0; block = &codeblock[block_current]; - codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL); + codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); block_write_data = codeblock[block_current].data; build_loadstore_routines(&codeblock[block_current]); diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 956f4eb..90700fe 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -101,7 +101,7 @@ static inline void codegen_alloc_bytes(codeblock_t *block, int size) if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) { /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); /*Add a jump instruction to the new block*/ diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 982f69d..6119ea2 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -299,7 +299,7 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); block_current = 0; block_pos = 0; block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); block->data = codeblock_allocator_get_ptr(block->head_mem_block); block_write_data = block->data; build_loadstore_routines(block); diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 56bd27a..2d9ef2c 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -78,7 +78,7 @@ static inline void codegen_addquad(codeblock_t *block, uint64_t val) static void codegen_allocate_new_block(codeblock_t *block) { /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); /*Add a jump instruction to the new block*/ From c1f0b7c35d401c5c5811e60b892f49713ea87abf Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 22 Jan 2019 21:41:00 +0000 Subject: [PATCH 0596/1050] Use readlookup cache in get_phys(). --- src/mem.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/mem.h b/src/mem.h index 3a27a92..790d999 100644 --- a/src/mem.h +++ b/src/mem.h @@ -157,17 +157,34 @@ static inline uint32_t get_phys(uint32_t addr) return addr & rammask; } - get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; + if (readlookup2[addr >> 12] != -1) + get_phys_phys = ((uintptr_t)readlookup2[addr >> 12] + (addr & ~0xfff)) - (uintptr_t)ram; + else + { + get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; + if (!cpu_state.abrt) + addreadlookup(get_phys_virt, get_phys_phys); + } + return get_phys_phys | (addr & 0xfff); // return mmutranslatereal(addr, 0) & rammask; } static inline uint32_t get_phys_noabrt(uint32_t addr) { + uint32_t phys_addr; + if (!(cr0 >> 31)) return addr & rammask; - return mmutranslate_noabrt(addr, 0) & rammask; + if (readlookup2[addr >> 12] != -1) + return ((uintptr_t)readlookup2[addr >> 12] + addr) - (uintptr_t)ram; + + phys_addr = mmutranslate_noabrt(addr, 0) & rammask; + if (!cpu_state.abrt) + addreadlookup(addr, phys_addr); + + return phys_addr; } void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr); From d461bc7cdaef0d6f6a35cd8066d98c1166ea06c2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 24 Jan 2019 20:36:20 +0000 Subject: [PATCH 0597/1050] Fix invalid page check in get_phys_noabrt(). --- src/mem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mem.h b/src/mem.h index 790d999..4b640ea 100644 --- a/src/mem.h +++ b/src/mem.h @@ -181,7 +181,7 @@ static inline uint32_t get_phys_noabrt(uint32_t addr) return ((uintptr_t)readlookup2[addr >> 12] + addr) - (uintptr_t)ram; phys_addr = mmutranslate_noabrt(addr, 0) & rammask; - if (!cpu_state.abrt) + if (phys_addr != 0xffffffff) addreadlookup(addr, phys_addr); return phys_addr; From c3250ca63ee84011b5ef9005baa4a84c62843010 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 20:51:13 +0000 Subject: [PATCH 0598/1050] Don't set oldcpl at the start of each instruction; instead, only set it following a successful CS load. --- src/386.c | 1 - src/386_dynarec.c | 4 ---- src/x86_ops_misc.h | 1 + src/x86seg.c | 17 +++++++++++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/386.c b/src/386.c index e7032d1..8d18d9a 100644 --- a/src/386.c +++ b/src/386.c @@ -238,7 +238,6 @@ void exec386(int cycs) oldcs=CS; cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; cpu_state.op32 = use32; dontprint=0; diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 1238cc0..77bba42 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -533,7 +533,6 @@ void exec386_dynarec(int cycs) { oldcs = CS; cpu_state.oldpc = cpu_state.pc; - oldcpl = CPL; cpu_state.op32 = use32; @@ -549,7 +548,6 @@ void exec386_dynarec(int cycs) { oldcs=CS; cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; cpu_state.op32 = use32; cpu_state.ea_seg = &cpu_state.seg_ds; @@ -708,7 +706,6 @@ inrecomp=0; { oldcs=CS; cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; cpu_state.op32 = use32; cpu_state.ea_seg = &cpu_state.seg_ds; @@ -790,7 +787,6 @@ inrecomp=0; { oldcs=CS; cpu_state.oldpc = cpu_state.pc; - oldcpl=CPL; cpu_state.op32 = use32; cpu_state.ea_seg = &cpu_state.seg_ds; diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index ee6c632..ca11638 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -925,6 +925,7 @@ static int opLOADALL386(uint32_t fetchdat) loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; CLOCK_CYCLES(350); return 0; diff --git a/src/x86seg.c b/src/x86seg.c index 547ed1b..012e930 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -573,6 +573,7 @@ void loadcs(uint16_t seg) do_seg_load(&cpu_state.seg_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; #ifdef CS_ACCESSED cpl_override = 1; @@ -611,6 +612,7 @@ void loadcs(uint16_t seg) if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; } } @@ -697,6 +699,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; /* if (segdat[3]&0x40) { use32=0x300; @@ -801,6 +804,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) CS=seg2; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -856,6 +860,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; cycles -= timing_jmp_rm; } } @@ -1032,6 +1037,7 @@ void loadcscall(uint16_t seg) CS=seg; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; /* if (segdat[3]&0x40) { use32=0x300; @@ -1220,6 +1226,7 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -1324,6 +1331,7 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3]&0x40); cpu_state.pc=newpc; @@ -1373,6 +1381,7 @@ void loadcscall(uint16_t seg) if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2; else cpu_state.seg_cs.access=(0<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; } } @@ -1500,6 +1509,7 @@ void pmoderetf(int is32, uint16_t off) do_seg_load(&cpu_state.seg_cs, segdat); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3] & 0x40); // pclog("CPL=RPL return to %04X:%08X\n",CS,pc); @@ -1651,6 +1661,7 @@ void pmoderetf(int is32, uint16_t off) CS=seg; do_seg_load(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3] & 0x40); if (stack32) ESP+=off; @@ -1982,6 +1993,7 @@ void pmodeint(int num, int soft) cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5); // pclog("New CS = %04X\n",CS); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; set_use32(segdat2[3]&0x40); @@ -2178,6 +2190,7 @@ void pmodeiret(int is32) CS=seg; cpu_state.seg_cs.access=(3<<5) | 2; if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; ESP=newsp; loadseg(newss,&cpu_state.seg_ss); @@ -2297,6 +2310,7 @@ void pmodeiret(int is32) do_seg_load(&cpu_state.seg_cs, segdat); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED @@ -2413,6 +2427,7 @@ void pmodeiret(int is32) do_seg_load(&cpu_state.seg_cs, segdat); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat[3] & 0x40); check_seg_valid(&cpu_state.seg_ds); @@ -2647,6 +2662,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&cpu_state.seg_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(segdat2[3] & 0x40); cpu_cur_status &= ~CPU_STATUS_V86; } @@ -2847,6 +2863,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&cpu_state.seg_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + oldcpl = CPL; set_use32(0); EAX=new_eax | 0xFFFF0000; From 93b42d43d5690bfd1489ffcc6e93f011efdd8b21 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 20:52:02 +0000 Subject: [PATCH 0599/1050] Remove pointless setting of cpu_state.op32 and cycdiff at start of recompiler main loop. --- src/386_dynarec.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 77bba42..41d7bea 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -533,10 +533,8 @@ void exec386_dynarec(int cycs) { oldcs = CS; cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cycdiff=0; oldcyc=cycles; // if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); if (!CACHE_ON()) /*Interpret block*/ From 6c65c34bd3ce33355ab7e53480ab52b377136bed Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 20:52:37 +0000 Subject: [PATCH 0600/1050] Don't clear trap at the start of the recompiler loop; instead, clear it when actually taking a trap. --- src/386_dynarec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 41d7bea..dbd8cb5 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -600,7 +600,6 @@ void exec386_dynarec(int cycs) int hash = HASH(phys_addr); codeblock_t *block = &codeblock[codeblock_hash[hash]]; int valid_block = 0; - trap = 0; if (block && !cpu_state.abrt) { @@ -877,7 +876,7 @@ inrecomp=0; if (trap) { - + trap = 0; flags_rebuild(); // oldpc=pc; // oldcs=CS; From 7b3b6a745d462216611ee3e6cbcb1bb57c04c0bc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 20:52:59 +0000 Subject: [PATCH 0601/1050] Remove pointless NULL check against block in recompiler loop. --- src/386_dynarec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index dbd8cb5..60647e5 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -601,7 +601,7 @@ void exec386_dynarec(int cycs) codeblock_t *block = &codeblock[codeblock_hash[hash]]; int valid_block = 0; - if (block && !cpu_state.abrt) + if (!cpu_state.abrt) { page_t *page = &pages[phys_addr >> 12]; From ee186dbb0d794b9872b6b6c57f0b3965461dca40 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 20:54:22 +0000 Subject: [PATCH 0602/1050] Remove test-USE32-and-mask-PC operation following code block execution. Instead, ensure that all recompiled instructions mask PC correctly. --- src/386_dynarec.c | 1 - src/codegen_ops_branch.c | 106 ++++++++++++++++++++++++--------------- src/codegen_ops_jump.c | 18 +++++-- 3 files changed, 79 insertions(+), 46 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 60647e5..62af26e 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -678,7 +678,6 @@ void exec386_dynarec(int cycs) inrecomp=1; code(); inrecomp=0; - if (!use32) cpu_state.pc &= 0xffff; // cpu_recomp_ins += block->ins; cpu_recomp_blocks++; /* ins += codeblock_ins[index]; diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c index e5a34fd..fdc0569 100644 --- a/src/codegen_ops_branch.c +++ b/src/codegen_ops_branch.c @@ -19,7 +19,7 @@ static int VF_SET_01() return VF_SET() ? 1 : 0; } -static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -47,11 +47,11 @@ static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -59,7 +59,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u { case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Overflow is always zero*/ - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); return; @@ -81,12 +81,12 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -114,11 +114,11 @@ static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -126,7 +126,7 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u { case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Carry is always zero*/ - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); return; @@ -148,12 +148,12 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -166,11 +166,11 @@ static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui { jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -183,12 +183,12 @@ void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t { jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop, jump_uop2 = -1; @@ -219,11 +219,11 @@ static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u } if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop, jump_uop2 = -1; @@ -252,14 +252,14 @@ static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); } -static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -304,11 +304,11 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -353,33 +353,33 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -413,11 +413,11 @@ static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop; @@ -451,12 +451,12 @@ static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop, jump_uop2 = -1; @@ -483,11 +483,11 @@ static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u } if (jump_uop2 != -1) uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); } -static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) +static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { int jump_uop, jump_uop2 = -1; @@ -512,7 +512,7 @@ static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); break; } - uop_MOV_IMM(ir, IREG_pc, base_pc + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); if (jump_uop2 != -1) @@ -523,21 +523,29 @@ static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ - ropJ ## cond ## _common(block, ir, op_pc+1, offset); \ + uint32_t dest_addr = op_pc + 1 + offset; \ + \ + if (!(op_32 & 0x100)) \ + dest_addr &= 0xffff; \ + ropJ ## cond ## _common(block, ir, dest_addr); \ \ return op_pc+1; \ } \ uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ - ropJ ## cond ## _common(block, ir, op_pc+2, offset); \ + uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ + \ + ropJ ## cond ## _common(block, ir, dest_addr); \ \ return op_pc+2; \ } \ uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ uint32_t offset = fastreadl(cs + op_pc); \ - ropJ ## cond ## _common(block, ir, op_pc+4, offset); \ + uint32_t dest_addr = op_pc + 4 + offset; \ + \ + ropJ ## cond ## _common(block, ir, dest_addr); \ \ return op_pc+4; \ } @@ -563,13 +571,17 @@ ropJ(NLE) uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; int jump_uop; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + if (op_32 & 0x200) jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); else jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); @@ -579,8 +591,12 @@ uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; int jump_uop; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + if (op_32 & 0x200) { uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); @@ -591,7 +607,7 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); } - uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); @@ -601,8 +617,12 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; int jump_uop, jump_uop2; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + if (op_32 & 0x200) { uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); @@ -622,7 +642,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe { jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); } - uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); @@ -632,8 +652,12 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; int jump_uop, jump_uop2; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + if (op_32 & 0x200) { uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); @@ -653,7 +677,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f { jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); } - uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c index c5209c1..d559881 100644 --- a/src/codegen_ops_jump.c +++ b/src/codegen_ops_jump.c @@ -12,22 +12,30 @@ uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc+1+offset; - uop_MOV_IMM(ir, IREG_pc, op_pc+1+offset); + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + uop_MOV_IMM(ir, IREG_pc, dest_addr); return -1; } uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); + uint32_t dest_addr = op_pc+2+offset; + + dest_addr &= 0xffff; - uop_MOV_IMM(ir, IREG_pc, op_pc+2+offset); + uop_MOV_IMM(ir, IREG_pc, dest_addr); return -1; } uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = fastreadl(cs + op_pc); - - uop_MOV_IMM(ir, IREG_pc, op_pc+4+offset); + uint32_t dest_addr = op_pc+4+offset; + + uop_MOV_IMM(ir, IREG_pc, dest_addr); return -1; } @@ -65,6 +73,8 @@ uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint16_t dest_addr = ret_addr + offset; int sp_reg; + dest_addr &= 0xffff; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); From 889ca7f3f29d3b28c56a145f2aa24e1efca0624d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 21:22:35 +0000 Subject: [PATCH 0603/1050] Remove test-USE32-and-mask-PC operation from interpreter as well. --- src/386.c | 2 -- src/386_dynarec.c | 6 ------ src/x86_ops_jump.h | 11 +++++++++++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/386.c b/src/386.c index 8d18d9a..12428bf 100644 --- a/src/386.c +++ b/src/386.c @@ -263,8 +263,6 @@ dontprint=0; break; } - if (!use32) cpu_state.pc &= 0xffff; - if (cpu_state.abrt) { flags_rebuild(); diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 62af26e..39d1787 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -567,8 +567,6 @@ void exec386_dynarec(int cycs) x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); } - if (!use32) cpu_state.pc &= 0xffff; - if (((cs + cpu_state.pc) >> 12) != pccache) CPU_BLOCK_END(); @@ -731,8 +729,6 @@ inrecomp=0; break; } - if (!use32) cpu_state.pc &= 0xffff; - /*Cap source code at 4000 bytes per block; this will prevent any block from spanning more than 2 pages. In practice this limit will never be @@ -808,8 +804,6 @@ inrecomp=0; break; } - if (!use32) cpu_state.pc &= 0xffff; - /*Cap source code at 4000 bytes per block; this will prevent any block from spanning more than 2 pages. In practice this limit will never be diff --git a/src/x86_ops_jump.h b/src/x86_ops_jump.h index 292102a..855ddf7 100644 --- a/src/x86_ops_jump.h +++ b/src/x86_ops_jump.h @@ -23,6 +23,8 @@ if (cond_ ## condition) \ { \ cpu_state.pc += offset; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ CLOCK_CYCLES_ALWAYS(timing_bt); \ CPU_BLOCK_END(); \ PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ @@ -40,6 +42,7 @@ if (cond_ ## condition) \ { \ cpu_state.pc += offset; \ + cpu_state.pc &= 0xffff; \ CLOCK_CYCLES_ALWAYS(timing_bt); \ CPU_BLOCK_END(); \ PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ @@ -95,6 +98,7 @@ static int opLOOPNE_w(uint32_t fetchdat) if (CX && !ZF_SET()) { cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -126,6 +130,7 @@ static int opLOOPE_w(uint32_t fetchdat) if (CX && ZF_SET()) { cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -157,6 +162,7 @@ static int opLOOP_w(uint32_t fetchdat) if (CX) { cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -186,6 +192,7 @@ static int opJCXZ(uint32_t fetchdat) if (!CX) { cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); @@ -217,6 +224,8 @@ static int opJMP_r8(uint32_t fetchdat) { int8_t offset = (int8_t)getbytef(); cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); @@ -227,6 +236,7 @@ static int opJMP_r16(uint32_t fetchdat) { int16_t offset = (int16_t)getwordf(); cpu_state.pc += offset; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); @@ -274,6 +284,7 @@ static int opCALL_r16(uint32_t fetchdat) int16_t addr = (int16_t)getwordf(); PUSH_W(cpu_state.pc); cpu_state.pc += addr; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); CLOCK_CYCLES((is486) ? 3 : 7); PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); From 32d4f4c765e241b78ec1c2a79e1535825e482273 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Jan 2019 22:21:06 +0000 Subject: [PATCH 0604/1050] Fix incorrect PC size detection on LOOP/LOOPE/LOOPNE/JCXZ/JECXZ. Fixes Heaven 7. --- src/x86_ops_jump.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/x86_ops_jump.h b/src/x86_ops_jump.h index 855ddf7..a7c4fd5 100644 --- a/src/x86_ops_jump.h +++ b/src/x86_ops_jump.h @@ -98,7 +98,8 @@ static int opLOOPNE_w(uint32_t fetchdat) if (CX && !ZF_SET()) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -114,6 +115,8 @@ static int opLOOPNE_l(uint32_t fetchdat) if (ECX && !ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -130,7 +133,8 @@ static int opLOOPE_w(uint32_t fetchdat) if (CX && ZF_SET()) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -146,6 +150,8 @@ static int opLOOPE_l(uint32_t fetchdat) if (ECX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -162,7 +168,8 @@ static int opLOOP_w(uint32_t fetchdat) if (CX) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -178,6 +185,8 @@ static int opLOOP_l(uint32_t fetchdat) if (ECX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); PREFETCH_FLUSH(); return 1; @@ -192,7 +201,8 @@ static int opJCXZ(uint32_t fetchdat) if (!CX) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); @@ -209,6 +219,8 @@ static int opJECXZ(uint32_t fetchdat) if (!ECX) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CLOCK_CYCLES(4); CPU_BLOCK_END(); PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); From 6e5336ae564c1fbdbc02694c5e54137ff13963c8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 17:40:28 +0000 Subject: [PATCH 0605/1050] When compiling with CODEBLOCK_STATIC_TOP, update TOP register with immediate moves rather than add/sub. --- src/codegen_ops_fpu_arith.c | 26 ++++++++++++-------------- src/codegen_ops_fpu_constant.c | 4 ++-- src/codegen_ops_fpu_loadstore.c | 20 ++++++++++---------- src/codegen_ops_fpu_misc.c | 4 ++-- src/codegen_ops_helpers.h | 21 +++++++++++++++++---- 5 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index 9d4259c..3f05802 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -38,7 +38,7 @@ uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_FP_ENTER(ir); uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -62,7 +62,7 @@ uint32_t ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -72,8 +72,7 @@ uint32_t ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(ir); - fpu_POP(ir); + fpu_POP2(block, ir); return op_pc; } @@ -125,7 +124,7 @@ uint32_t ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_FP_ENTER(ir); uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -136,7 +135,7 @@ uint32_t ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_FP_ENTER(ir); uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -168,7 +167,7 @@ uint32_t ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_FP_ENTER(ir); uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -220,7 +219,7 @@ uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_FP_ENTER(ir); uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -231,7 +230,7 @@ uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_FP_ENTER(ir); uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -255,7 +254,7 @@ uint32_t ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } @@ -265,8 +264,7 @@ uint32_t ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(ir); - fpu_POP(ir); + fpu_POP2(block, ir); return op_pc; } @@ -316,7 +314,7 @@ uint32_t ropFCOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uin uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(ir); \ + fpu_POP(block, ir); \ \ return op_pc+1; \ } \ @@ -447,7 +445,7 @@ uint32_t ropFICOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, ui uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(ir); \ + fpu_POP(block, ir); \ \ return op_pc+1; \ } \ diff --git a/src/codegen_ops_fpu_constant.c b/src/codegen_ops_fpu_constant.c index 187850c..aa264ce 100644 --- a/src/codegen_ops_fpu_constant.c +++ b/src/codegen_ops_fpu_constant.c @@ -17,7 +17,7 @@ uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV_IMM(ir, IREG_temp0, 1); uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc; } @@ -27,7 +27,7 @@ uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV_IMM(ir, IREG_temp0, 0); uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc; } diff --git a/src/codegen_ops_fpu_loadstore.c b/src/codegen_ops_fpu_loadstore.c index 04ee62a..f5e42f3 100644 --- a/src/codegen_ops_fpu_loadstore.c +++ b/src/codegen_ops_fpu_loadstore.c @@ -22,7 +22,7 @@ uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc+1; } @@ -37,7 +37,7 @@ uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_check_seg_read(block, ir, target_seg); uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc+1; } @@ -66,7 +66,7 @@ uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc+1; } @@ -94,7 +94,7 @@ uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc+1; } @@ -112,7 +112,7 @@ uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc+1; } @@ -128,7 +128,7 @@ uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc+1; } @@ -144,7 +144,7 @@ uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc+1; } @@ -176,7 +176,7 @@ uint32_t ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc+1; } @@ -207,7 +207,7 @@ uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc+1; } @@ -223,7 +223,7 @@ uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc+1; } diff --git a/src/codegen_ops_fpu_misc.c b/src/codegen_ops_fpu_misc.c index 18d6f88..58902ac 100644 --- a/src/codegen_ops_fpu_misc.c +++ b/src/codegen_ops_fpu_misc.c @@ -29,7 +29,7 @@ uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); - fpu_PUSH(ir); + fpu_PUSH(block, ir); return op_pc; } @@ -53,7 +53,7 @@ uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - fpu_POP(ir); + fpu_POP(block, ir); return op_pc; } diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h index 1b4cf30..9bde28f 100644 --- a/src/codegen_ops_helpers.h +++ b/src/codegen_ops_helpers.h @@ -46,11 +46,24 @@ static inline void SUB_SP(ir_data_t *ir, int offset) uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void fpu_POP(ir_data_t *ir) +static inline void fpu_POP(codeblock_t *block, ir_data_t *ir) { - uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1); + else + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void fpu_PUSH(ir_data_t *ir) +static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir) { - uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2); + else + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2); +} +static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) +{ + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1); + else + uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } From 427aa72a15a47403deae36b35ff3c62964aa8a40 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 19:25:09 +0000 Subject: [PATCH 0606/1050] Don't set cpu_state.oldpc at the start of every iteration of the recompiler main loop. --- src/386_dynarec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 39d1787..6e2bf35 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -532,8 +532,6 @@ void exec386_dynarec(int cycs) while (cycles>0) { oldcs = CS; - cpu_state.oldpc = cpu_state.pc; - oldcyc=cycles; // if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); @@ -835,6 +833,9 @@ inrecomp=0; // output &= ~2; } + else + cpu_state.oldpc = cpu_state.pc; + // if (output && (SP & 1)) // fatal("odd SP\n"); } From ca89a51478cca5e07286334a5fc4eca531c83cfc Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 20:00:49 +0000 Subject: [PATCH 0607/1050] Remove redundant oldcs variable - when processing an exception, oldcs and CS are the same. --- src/386.c | 6 ------ src/386_dynarec.c | 9 --------- src/808x.c | 8 ++------ src/x86.h | 1 - src/x86seg.c | 16 ---------------- 5 files changed, 2 insertions(+), 38 deletions(-) diff --git a/src/386.c b/src/386.c index 12428bf..a0ad35f 100644 --- a/src/386.c +++ b/src/386.c @@ -50,7 +50,6 @@ extern int oddeven; int inttype; -uint32_t oldcs2; uint32_t oldecx; uint32_t *eal_r, *eal_w; @@ -233,10 +232,8 @@ void exec386(int cycs) /* 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; - oldcs=CS; cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; @@ -283,7 +280,6 @@ dontprint=0; if (cpu_state.abrt) { cpu_state.abrt = 0; - CS = oldcs; cpu_state.pc = cpu_state.oldpc; pclog("Double fault %i\n", ins); pmodeint(8, 0); @@ -302,7 +298,6 @@ dontprint=0; { flags_rebuild(); // oldpc=pc; -// oldcs=CS; if (msw&1) { pmodeint(1,0); @@ -323,7 +318,6 @@ dontprint=0; else if (nmi && nmi_enable && nmi_mask) { cpu_state.oldpc = cpu_state.pc; - oldcs = CS; // pclog("NMI\n"); x86_int(2); nmi_enable = 0; diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 6e2bf35..0137238 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -59,7 +59,6 @@ int oddeven=0; int inttype; -uint32_t oldcs2; uint32_t oldecx; uint32_t *eal_r, *eal_w; @@ -531,8 +530,6 @@ void exec386_dynarec(int cycs) // output=3; while (cycles>0) { - oldcs = CS; - oldcyc=cycles; // if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); if (!CACHE_ON()) /*Interpret block*/ @@ -542,7 +539,6 @@ void exec386_dynarec(int cycs) // 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; cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; @@ -696,7 +692,6 @@ inrecomp=0; // 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; cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; @@ -775,7 +770,6 @@ inrecomp=0; // 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; cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; @@ -854,7 +848,6 @@ inrecomp=0; if (cpu_state.abrt) { cpu_state.abrt = 0; - CS = oldcs; cpu_state.pc = cpu_state.oldpc; pclog("Double fault %i\n", ins); pmodeint(8, 0); @@ -873,7 +866,6 @@ inrecomp=0; trap = 0; flags_rebuild(); // oldpc=pc; -// oldcs=CS; if (msw&1) { pmodeint(1,0); @@ -894,7 +886,6 @@ inrecomp=0; else if (nmi && nmi_enable && nmi_mask) { cpu_state.oldpc = cpu_state.pc; - oldcs = CS; // pclog("NMI\n"); x86_int(2); nmi_enable = 0; diff --git a/src/808x.c b/src/808x.c index 7368a4e..a20dc29 100644 --- a/src/808x.c +++ b/src/808x.c @@ -88,7 +88,6 @@ void writememl(uint32_t s, uint32_t a, uint32_t v) } -uint16_t oldcs; int oldcpl; int tempc; @@ -481,7 +480,6 @@ void makeznptable() } int timetolive=0; -extern uint32_t oldcs2; extern uint32_t oldpc2; int indump = 0; @@ -571,7 +569,7 @@ void dumpregs() else printf("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP); printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,cpu_state.flags); - printf("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2); + printf("%04X %04X\n",cpu_state.oldpc, oldpc2); printf("%i ins\n",ins); if (is386) printf("In %s mode\n",(msw&1)?((cpu_state.eflags&VM_FLAG)?"V86":"protected"):"real"); @@ -1142,7 +1140,6 @@ void execx86(int cycs) { // 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; @@ -1152,7 +1149,6 @@ void execx86(int cycs) nextcyc=0; // if (output) printf("CLOCK %i %i\n",cycdiff,cycles); fetchclocks=0; - oldcs=CS; cpu_state.oldpc = cpu_state.pc; opcodestart: opcode=FETCH(); @@ -3092,7 +3088,7 @@ void execx86(int cycs) break; case 0xF4: /*HLT*/ -// printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83); +// printf("IN HLT!!!! %04X %08X %08X %08X\n",oldpc,old8,old82,old83); /* if (!(flags & I_FLAG)) { pclog("HLT\n"); diff --git a/src/x86.h b/src/x86.h index 195f52a..5a76ba9 100644 --- a/src/x86.h +++ b/src/x86.h @@ -1,4 +1,3 @@ -uint16_t oldcs; extern uint32_t rmdat32; int oldcpl; diff --git a/src/x86seg.c b/src/x86seg.c index 012e930..7876ae0 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -95,7 +95,6 @@ void x86seg_reset() void x86_doabrt(int x86_abrt) { // ingpf = 1; - CS = oldcs; cpu_state.pc = cpu_state.oldpc; cpu_state.seg_cs.access = oldcpl << 5; // pclog("x86_doabrt - %02X %08X %04X:%08X %i\n", x86_abrt, abrt_error, CS, pc, ins); @@ -730,7 +729,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) // pclog("Call gate\n"); cgate32=(type&0x800); cgate16=!cgate32; - oldcs=CS; cpu_state.oldpc = cpu_state.pc; if ((DPL < CPL) || (DPL < (seg&3))) { @@ -1267,8 +1265,6 @@ void loadcscall(uint16_t seg) } } // x86abort("Call gate with count %i\n",count); -// PUSHL(oldcs); -// PUSHL(oldpc); if (cpu_state.abrt) return; } else { @@ -1305,8 +1301,6 @@ void loadcscall(uint16_t seg) } // 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; @@ -1318,16 +1312,6 @@ void loadcscall(uint16_t seg) 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(&cpu_state.seg_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); From f0225d27102ca1ad45ccb19718655fa550fdc7d6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 20:30:08 +0000 Subject: [PATCH 0608/1050] Hide fatal()s in codegen_backend_x86_uops.c behind a RECOMPILER_DEBUG #define. --- src/codegen_backend_x86_uops.c | 342 +++++++++++++++++++++++---------- 1 file changed, 236 insertions(+), 106 deletions(-) diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 9882f82..c6dea83 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -54,9 +54,10 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -84,9 +85,10 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -96,9 +98,10 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); else if (uop->imm_data < 4) host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); +#ifdef RECOMPILER_DEBUG else fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); - +#endif return 0; } @@ -129,9 +132,10 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); host_x86_AND8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -158,9 +162,10 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_AND8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -173,9 +178,10 @@ static int codegen_ANDN(codeblock_t *block, uop_t *uop) { host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -189,10 +195,12 @@ static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); +#ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_L(dest_size)) fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); +#endif host_x86_CALL(block, uop->p); host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); @@ -218,8 +226,10 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); +#endif host_x86_JZ(block, uop->p); return 0; @@ -238,9 +248,10 @@ static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNZ_long(block); return 0; @@ -258,9 +269,10 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JZ_long(block); return 0; @@ -283,9 +295,10 @@ static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNB_long(block); return 0; @@ -307,9 +320,10 @@ static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNBE_long(block); return 0; @@ -331,9 +345,10 @@ static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNL_long(block); return 0; @@ -355,9 +370,10 @@ static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNLE_long(block); return 0; @@ -379,9 +395,10 @@ static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNO_long(block); return 0; @@ -403,9 +420,10 @@ static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNZ_long(block); return 0; @@ -427,9 +445,10 @@ static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JB_long(block); return 0; @@ -451,9 +470,10 @@ static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JBE_long(block); return 0; @@ -475,9 +495,10 @@ static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JL_long(block); return 0; @@ -499,9 +520,10 @@ static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JLE_long(block); return 0; @@ -523,9 +545,10 @@ static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JO_long(block); return 0; @@ -547,9 +570,10 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JZ_long(block); return 0; @@ -566,9 +590,10 @@ static int codegen_FABS(codeblock_t *block, uop_t *uop) host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_FCHS(codeblock_t *block, uop_t *uop) @@ -582,9 +607,10 @@ static int codegen_FCHS(codeblock_t *block, uop_t *uop) host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_FSQRT(codeblock_t *block, uop_t *uop) @@ -596,9 +622,10 @@ static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_FTST(codeblock_t *block, uop_t *uop) @@ -621,9 +648,10 @@ static int codegen_FTST(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -636,9 +664,10 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) { host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FCOM(codeblock_t *block, uop_t *uop) @@ -660,9 +689,10 @@ static int codegen_FCOM(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FDIV(codeblock_t *block, uop_t *uop) @@ -680,9 +710,10 @@ static int codegen_FDIV(codeblock_t *block, uop_t *uop) host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FMUL(codeblock_t *block, uop_t *uop) @@ -694,9 +725,10 @@ static int codegen_FMUL(codeblock_t *block, uop_t *uop) { host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FSUB(codeblock_t *block, uop_t *uop) @@ -714,9 +746,10 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop) host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -778,24 +811,31 @@ static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); - +#endif return 0; } static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); +#endif return 0; } static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); +#endif return 0; } static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); +#endif return 0; } @@ -823,10 +863,12 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { int src_reg = HOST_REG_GET(uop->src_reg_a_real); +#ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (!REG_IS_W(src_size)) fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +#endif host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); host_x86_CALL(block, loadseg); @@ -854,8 +896,10 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, codegen_mem_load_long); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) @@ -897,8 +941,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, codegen_mem_load_quad); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) @@ -923,11 +969,12 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); +#ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -942,11 +989,12 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); +#ifdef RECOMPILER_DEBUG int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -979,8 +1027,10 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1015,8 +1065,10 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_quad); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1063,11 +1115,12 @@ static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); +#ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -1081,11 +1134,12 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); +#ifdef RECOMPILER_DEBUG int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -1122,9 +1176,10 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop) { host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) @@ -1144,9 +1199,10 @@ static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) @@ -1171,8 +1227,10 @@ static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif return 0; } static int codegen_MOVZX(codeblock_t *block, uop_t *uop) @@ -1200,8 +1258,10 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif return 0; } @@ -1228,9 +1288,10 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) host_x87_FSTPd_BASE(block, REG_ESP); host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); } +#ifdef RECOMPILER_DEBUG else fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) @@ -1251,9 +1312,10 @@ static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); host_x86_LDMXCSR(block, &cpu_state.old_fp_control); } +#ifdef RECOMPILER_DEBUG else fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1282,9 +1344,10 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; } +#ifdef RECOMPILER_DEBUG else fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1313,9 +1376,10 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) { host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) @@ -1335,9 +1399,10 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1350,9 +1415,10 @@ static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) @@ -1364,9 +1430,10 @@ static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) @@ -1378,9 +1445,10 @@ static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1393,9 +1461,10 @@ static int codegen_PADDB(codeblock_t *block, uop_t *uop) { host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDW(codeblock_t *block, uop_t *uop) @@ -1407,9 +1476,10 @@ static int codegen_PADDW(codeblock_t *block, uop_t *uop) { host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDD(codeblock_t *block, uop_t *uop) @@ -1421,9 +1491,10 @@ static int codegen_PADDD(codeblock_t *block, uop_t *uop) { host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDSB(codeblock_t *block, uop_t *uop) @@ -1435,9 +1506,10 @@ static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDSW(codeblock_t *block, uop_t *uop) @@ -1449,9 +1521,10 @@ static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) @@ -1463,9 +1536,10 @@ static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) @@ -1477,9 +1551,10 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1492,9 +1567,10 @@ static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) @@ -1506,9 +1582,10 @@ static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) @@ -1520,9 +1597,10 @@ static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) @@ -1534,9 +1612,10 @@ static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) @@ -1548,9 +1627,10 @@ static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) @@ -1562,9 +1642,10 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1579,9 +1660,10 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop) host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); host_x86_LDMXCSR(block, &cpu_state.old_fp_control); } +#ifdef RECOMPILER_DEBUG else fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_PFADD(codeblock_t *block, uop_t *uop) @@ -1593,9 +1675,10 @@ static int codegen_PFADD(codeblock_t *block, uop_t *uop) { host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) @@ -1607,9 +1690,10 @@ static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); } +#ifdef RECOMPILER_DEBUG else fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) @@ -1621,9 +1705,10 @@ static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); } +#ifdef RECOMPILER_DEBUG else fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) @@ -1635,9 +1720,10 @@ static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); } +#ifdef RECOMPILER_DEBUG else fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFMAX(codeblock_t *block, uop_t *uop) @@ -1649,9 +1735,10 @@ static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFMIN(codeblock_t *block, uop_t *uop) @@ -1663,9 +1750,10 @@ static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFMUL(codeblock_t *block, uop_t *uop) @@ -1677,9 +1765,10 @@ static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFRCP(codeblock_t *block, uop_t *uop) @@ -1696,9 +1785,10 @@ static int codegen_PFRCP(codeblock_t *block, uop_t *uop) host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) @@ -1715,9 +1805,10 @@ static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_PFSUB(codeblock_t *block, uop_t *uop) @@ -1735,9 +1826,10 @@ static int codegen_PFSUB(codeblock_t *block, uop_t *uop) host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PI2FD(codeblock_t *block, uop_t *uop) @@ -1749,9 +1841,10 @@ static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); } +#ifdef RECOMPILER_DEBUG else fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } @@ -1764,9 +1857,10 @@ static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PMULHW(codeblock_t *block, uop_t *uop) @@ -1778,9 +1872,10 @@ static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PMULLW(codeblock_t *block, uop_t *uop) @@ -1792,9 +1887,10 @@ static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1807,9 +1903,10 @@ static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) @@ -1821,9 +1918,10 @@ static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) @@ -1835,9 +1933,10 @@ static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) @@ -1849,9 +1948,10 @@ static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) @@ -1863,9 +1963,10 @@ static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) @@ -1877,9 +1978,10 @@ static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) @@ -1891,9 +1993,10 @@ static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) @@ -1905,9 +2008,10 @@ static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) @@ -1919,9 +2023,10 @@ static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1934,9 +2039,10 @@ static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBW(codeblock_t *block, uop_t *uop) @@ -1948,9 +2054,10 @@ static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBD(codeblock_t *block, uop_t *uop) @@ -1962,9 +2069,10 @@ static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) @@ -1976,9 +2084,10 @@ static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) @@ -1990,9 +2099,10 @@ static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) @@ -2004,9 +2114,10 @@ static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) @@ -2018,9 +2129,10 @@ static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -2033,9 +2145,10 @@ static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) @@ -2047,9 +2160,10 @@ static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) @@ -2061,9 +2175,10 @@ static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) @@ -2075,9 +2190,10 @@ static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) @@ -2089,9 +2205,10 @@ static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) @@ -2103,9 +2220,10 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -2133,9 +2251,10 @@ static int codegen_SAR(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SAR8_CL(block, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) @@ -2161,9 +2280,10 @@ static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHL(codeblock_t *block, uop_t *uop) @@ -2190,9 +2310,10 @@ static int codegen_SHL(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHL8_CL(block, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) @@ -2218,9 +2339,10 @@ static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHR(codeblock_t *block, uop_t *uop) @@ -2247,9 +2369,10 @@ static int codegen_SHR(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHR8_CL(block, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) @@ -2275,9 +2398,10 @@ static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -2315,9 +2439,10 @@ static int codegen_SUB(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) @@ -2343,9 +2468,10 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -2366,9 +2492,10 @@ static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { host_x86_TEST8_REG(block, src_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNS_long(block); return 0; @@ -2390,9 +2517,10 @@ static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { host_x86_TEST8_REG(block, src_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JS_long(block); return 0; @@ -2419,9 +2547,10 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) { host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) @@ -2441,9 +2570,10 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } From b018dc1005eea20ea78fa6478452419f8d48d5d0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 21:08:01 +0000 Subject: [PATCH 0609/1050] Remove fake 3-operand instructions in x86 backend. --- src/codegen_backend_x86.c | 16 +-- src/codegen_backend_x86_ops.c | 182 +++++++++------------------------ src/codegen_backend_x86_ops.h | 62 +++++------ src/codegen_backend_x86_uops.c | 137 +++++++++++++------------ 4 files changed, 157 insertions(+), 240 deletions(-) diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 6119ea2..7beffc5 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -99,7 +99,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); else fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); host_x86_RET(block); *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; @@ -189,7 +189,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); else fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); host_x86_RET(block); *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; @@ -203,7 +203,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) if (size == 8) { host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); - host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 8); + host_x86_SUB32_REG_IMM(block, REG_ESP, 8); } host_x86_PUSH(block, REG_EDI); if (size == 1) @@ -216,7 +216,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_CALL(block, (void *)writememql); host_x86_POP(block, REG_EDI); if (size == 8) - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 8); + host_x86_ADD32_REG_IMM(block, REG_ESP, 8); host_x86_POP(block, REG_ECX); host_x86_POP(block, REG_EDX); host_x86_POP(block, REG_EAX); @@ -309,7 +309,7 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); host_x86_CALL(block, (void *)x86gpf); codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64); + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); host_x86_POP(block, REG_EDI); host_x86_POP(block, REG_ESI); host_x86_POP(block, REG_EBP); @@ -342,19 +342,19 @@ void codegen_backend_prologue(codeblock_t *block) host_x86_PUSH(block, REG_EBP); host_x86_PUSH(block, REG_ESI); host_x86_PUSH(block, REG_EDI); - host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 64); + host_x86_SUB32_REG_IMM(block, REG_ESP, 64); host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t)&cpu_state) + 128); if (block->flags & CODEBLOCK_HAS_FPU) { host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, REG_EAX, block->TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); } } void codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 64); + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); host_x86_POP(block, REG_EDI); host_x86_POP(block, REG_ESI); host_x86_POP(block, REG_EBP); diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 2d9ef2c..47f7493 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -103,7 +103,7 @@ static int is_imm8(uint32_t imm_data) return 0; } -void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, int src_reg, void *p) +void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -121,11 +121,8 @@ void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, int src_reg, void * } } -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); - if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -137,11 +134,8 @@ void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ } } -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -160,11 +154,8 @@ void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -184,29 +175,20 @@ void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 } } -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) @@ -220,11 +202,8 @@ void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); - if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -236,11 +215,8 @@ void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ } } -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -259,11 +235,8 @@ void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -283,29 +256,20 @@ void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 } } -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ } -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ } -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_CALL(codeblock_t *block, void *p) @@ -1263,36 +1227,24 @@ void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_OR8_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ } -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_OR16_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ } -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ } -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); - if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -1304,11 +1256,8 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ } } -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1327,11 +1276,8 @@ void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_ codegen_addword(block, imm_data); } } -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -1732,11 +1678,8 @@ void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ } -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); - if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -1748,11 +1691,8 @@ void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ } } -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1771,11 +1711,8 @@ void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -1795,29 +1732,20 @@ void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 } } -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) @@ -1868,36 +1796,24 @@ void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_XOR8_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_XOR16_REG_REG - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); - if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -1909,11 +1825,8 @@ void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ } } -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1932,11 +1845,8 @@ void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); - if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 22a8746..db7b37c 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -1,23 +1,23 @@ -void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, int src_reg, void *p); +void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CALL(codeblock_t *block, void *p); @@ -165,13 +165,13 @@ void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -259,13 +259,13 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -278,13 +278,13 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_ void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); void host_x87_FILDq_BASE(codeblock_t *block, int base_reg); void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c6dea83..55bcc13 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -40,19 +40,19 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -71,19 +71,19 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); else - host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -95,7 +95,12 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { if (!uop->imm_data) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); + else + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); #ifdef RECOMPILER_DEBUG @@ -118,19 +123,19 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -148,19 +153,19 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -638,10 +643,10 @@ static int codegen_FTST(codeblock_t *block, uop_t *uop) host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); if (dest_reg != REG_EAX) host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); @@ -679,10 +684,10 @@ static int codegen_FCOM(codeblock_t *block, uop_t *uop) { if (dest_reg != REG_EAX) host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); @@ -924,7 +929,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); if (REG_IS_B(dest_size)) { host_x86_CALL(block, codegen_mem_load_byte); @@ -977,7 +982,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -997,7 +1002,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1044,7 +1049,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); if (REG_IS_B(src_size)) { host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); @@ -1123,7 +1128,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); @@ -1142,7 +1147,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); @@ -1364,17 +1369,19 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -1385,19 +1392,19 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + if (REG_IS_L(dest_size) && dest_reg == src_reg) { - host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + else if (REG_IS_W(dest_size) && dest_reg == src_reg) { - host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + else if (REG_IS_B(dest_size) && dest_reg == src_reg) { - host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -2425,19 +2432,19 @@ static int codegen_SUB(codeblock_t *block, uop_t *uop) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -2454,19 +2461,19 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { if (dest_reg != src_reg) host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { if (dest_reg != src_reg) host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { if (dest_reg != src_reg) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -2528,24 +2535,24 @@ static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -2555,20 +2562,20 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -2783,8 +2790,8 @@ void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); } void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) @@ -2792,8 +2799,8 @@ void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) @@ -2801,8 +2808,8 @@ void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } @@ -2831,8 +2838,8 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); } void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) @@ -2840,8 +2847,8 @@ void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) @@ -2849,8 +2856,8 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } From 9283ab5fef3632ef7e52c1ad858f52f177f96c44 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 21:21:47 +0000 Subject: [PATCH 0610/1050] Hide fatal()s in codegen_backend_x86-64_uops.c behind a RECOMPILER_DEBUG #define. --- src/codegen_backend_x86-64_uops.c | 350 +++++++++++++++++++++--------- 1 file changed, 244 insertions(+), 106 deletions(-) diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 79bfed3..7b475bf 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -48,9 +48,10 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -78,9 +79,10 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -90,9 +92,10 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); else if (uop->imm_data < 4) host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); +#ifdef RECOMPILER_DEBUG else fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); - +#endif return 0; } @@ -123,9 +126,10 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); host_x86_AND8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -152,9 +156,10 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_AND8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -167,9 +172,10 @@ static int codegen_ANDN(codeblock_t *block, uop_t *uop) { host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -185,8 +191,10 @@ static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); +#ifdef RECOMPILER_DEBUG if (!REG_IS_L(dest_size)) fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); +#endif host_x86_CALL(block, uop->p); host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); @@ -211,8 +219,10 @@ static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); +#endif host_x86_JZ(block, uop->p); return 0; @@ -231,9 +241,10 @@ static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNZ_long(block); return 0; @@ -251,9 +262,10 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JZ_long(block); return 0; @@ -276,9 +288,10 @@ static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNB_long(block); return 0; @@ -300,9 +313,10 @@ static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNBE_long(block); return 0; @@ -324,9 +338,10 @@ static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNL_long(block); return 0; @@ -348,9 +363,10 @@ static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNLE_long(block); return 0; @@ -372,9 +388,10 @@ static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNO_long(block); return 0; @@ -396,9 +413,10 @@ static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNZ_long(block); return 0; @@ -420,9 +438,10 @@ static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JB_long(block); return 0; @@ -444,9 +463,10 @@ static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JBE_long(block); return 0; @@ -468,9 +488,10 @@ static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JL_long(block); return 0; @@ -492,9 +513,10 @@ static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JLE_long(block); return 0; @@ -516,9 +538,10 @@ static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JO_long(block); return 0; @@ -540,9 +563,10 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JZ_long(block); return 0; @@ -559,9 +583,10 @@ static int codegen_FABS(codeblock_t *block, uop_t *uop) host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_FCHS(codeblock_t *block, uop_t *uop) @@ -575,9 +600,10 @@ static int codegen_FCHS(codeblock_t *block, uop_t *uop) host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_FSQRT(codeblock_t *block, uop_t *uop) @@ -589,9 +615,10 @@ static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_FTST(codeblock_t *block, uop_t *uop) @@ -614,9 +641,10 @@ static int codegen_FTST(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -629,9 +657,10 @@ static int codegen_FADD(codeblock_t *block, uop_t *uop) { host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FCOM(codeblock_t *block, uop_t *uop) @@ -653,9 +682,10 @@ static int codegen_FCOM(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FDIV(codeblock_t *block, uop_t *uop) @@ -673,9 +703,10 @@ static int codegen_FDIV(codeblock_t *block, uop_t *uop) host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FMUL(codeblock_t *block, uop_t *uop) @@ -687,9 +718,10 @@ static int codegen_FMUL(codeblock_t *block, uop_t *uop) { host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_FSUB(codeblock_t *block, uop_t *uop) @@ -707,9 +739,10 @@ static int codegen_FSUB(codeblock_t *block, uop_t *uop) host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -776,24 +809,31 @@ static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); #endif } +#ifdef RECOMPILER_DEBUG else fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); - +#endif return 0; } static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); +#endif return 0; } static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); +#endif return 0; } static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); +#endif return 0; } @@ -817,12 +857,16 @@ static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); +#endif return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); +#endif return 0; } @@ -831,8 +875,10 @@ static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) int src_reg = HOST_REG_GET(uop->src_reg_a_real); int src_size = IREG_GET_SIZE(uop->src_reg_a_real); +#ifdef RECOMPILER_DEBUG if (!REG_IS_W(src_size)) fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +#endif #if WIN64 host_x86_MOV16_REG_REG(block, REG_CX, src_reg); host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p); @@ -865,8 +911,10 @@ static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, codegen_mem_load_long); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) @@ -908,8 +956,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, codegen_mem_load_quad); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); if (REG_IS_B(dest_size)) @@ -936,9 +986,10 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); +#ifdef RECOMPILER_DEBUG if (!REG_IS_D(dest_size)) fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -954,9 +1005,10 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); +#ifdef RECOMPILER_DEBUG if (!REG_IS_D(dest_size)) fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -989,8 +1041,10 @@ static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1062,8 +1116,10 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_quad); } +#ifdef RECOMPILER_DEBUG else fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); +#endif host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1075,9 +1131,10 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); +#ifdef RECOMPILER_DEBUG if (!REG_IS_D(src_size)) fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -1093,9 +1150,10 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); int src_size = IREG_GET_SIZE(uop->src_reg_c_real); +#ifdef RECOMPILER_DEBUG if (!REG_IS_D(src_size)) fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); - +#endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); @@ -1132,9 +1190,10 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop) { host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) @@ -1154,9 +1213,10 @@ static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) @@ -1181,8 +1241,10 @@ static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif return 0; } static int codegen_MOVZX(codeblock_t *block, uop_t *uop) @@ -1210,8 +1272,10 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif return 0; } @@ -1234,9 +1298,10 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); } +#ifdef RECOMPILER_DEBUG else fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) @@ -1257,9 +1322,10 @@ static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); host_x86_LDMXCSR(block, &cpu_state.old_fp_control); } +#ifdef RECOMPILER_DEBUG else fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) @@ -1283,9 +1349,10 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; } +#ifdef RECOMPILER_DEBUG else fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1314,9 +1381,10 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) { host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) @@ -1336,9 +1404,10 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1351,9 +1420,10 @@ static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) @@ -1365,9 +1435,10 @@ static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) @@ -1379,9 +1450,10 @@ static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1394,9 +1466,10 @@ static int codegen_PADDB(codeblock_t *block, uop_t *uop) { host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDW(codeblock_t *block, uop_t *uop) @@ -1408,9 +1481,10 @@ static int codegen_PADDW(codeblock_t *block, uop_t *uop) { host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDD(codeblock_t *block, uop_t *uop) @@ -1422,9 +1496,10 @@ static int codegen_PADDD(codeblock_t *block, uop_t *uop) { host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDSB(codeblock_t *block, uop_t *uop) @@ -1436,9 +1511,10 @@ static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDSW(codeblock_t *block, uop_t *uop) @@ -1450,9 +1526,10 @@ static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) @@ -1464,9 +1541,10 @@ static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) @@ -1478,9 +1556,10 @@ static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1493,9 +1572,10 @@ static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) @@ -1507,9 +1587,10 @@ static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) @@ -1521,9 +1602,10 @@ static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) @@ -1535,9 +1617,10 @@ static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) @@ -1549,9 +1632,10 @@ static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) @@ -1563,9 +1647,10 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1580,9 +1665,10 @@ static int codegen_PF2ID(codeblock_t *block, uop_t *uop) host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); host_x86_LDMXCSR(block, &cpu_state.old_fp_control); } +#ifdef RECOMPILER_DEBUG else fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_PFADD(codeblock_t *block, uop_t *uop) @@ -1594,9 +1680,10 @@ static int codegen_PFADD(codeblock_t *block, uop_t *uop) { host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) @@ -1608,9 +1695,10 @@ static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); } +#ifdef RECOMPILER_DEBUG else fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) @@ -1622,9 +1710,10 @@ static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); } +#ifdef RECOMPILER_DEBUG else fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) @@ -1636,9 +1725,10 @@ static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); } +#ifdef RECOMPILER_DEBUG else fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFMAX(codeblock_t *block, uop_t *uop) @@ -1650,9 +1740,10 @@ static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFMIN(codeblock_t *block, uop_t *uop) @@ -1664,9 +1755,10 @@ static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFMUL(codeblock_t *block, uop_t *uop) @@ -1678,9 +1770,10 @@ static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PFRCP(codeblock_t *block, uop_t *uop) @@ -1697,9 +1790,10 @@ static int codegen_PFRCP(codeblock_t *block, uop_t *uop) host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) @@ -1716,9 +1810,10 @@ static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } static int codegen_PFSUB(codeblock_t *block, uop_t *uop) @@ -1736,9 +1831,10 @@ static int codegen_PFSUB(codeblock_t *block, uop_t *uop) host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } +#ifdef RECOMPILER_DEBUG else fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PI2FD(codeblock_t *block, uop_t *uop) @@ -1750,9 +1846,10 @@ static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); } +#ifdef RECOMPILER_DEBUG else fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - +#endif return 0; } @@ -1765,9 +1862,10 @@ static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PMULHW(codeblock_t *block, uop_t *uop) @@ -1779,9 +1877,10 @@ static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PMULLW(codeblock_t *block, uop_t *uop) @@ -1793,9 +1892,10 @@ static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -1808,9 +1908,10 @@ static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) @@ -1822,9 +1923,10 @@ static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) @@ -1836,9 +1938,10 @@ static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) @@ -1850,9 +1953,10 @@ static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) @@ -1864,9 +1968,10 @@ static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) @@ -1878,9 +1983,10 @@ static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) @@ -1892,9 +1998,10 @@ static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) @@ -1906,9 +2013,10 @@ static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) @@ -1920,9 +2028,10 @@ static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -1935,9 +2044,10 @@ static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBW(codeblock_t *block, uop_t *uop) @@ -1949,9 +2059,10 @@ static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBD(codeblock_t *block, uop_t *uop) @@ -1963,9 +2074,10 @@ static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) @@ -1977,9 +2089,10 @@ static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) @@ -1991,9 +2104,10 @@ static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) @@ -2005,9 +2119,10 @@ static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) @@ -2019,9 +2134,10 @@ static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -2034,9 +2150,10 @@ static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) @@ -2048,9 +2165,10 @@ static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) @@ -2062,9 +2180,10 @@ static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) @@ -2076,9 +2195,10 @@ static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) @@ -2090,9 +2210,10 @@ static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) @@ -2104,9 +2225,10 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } @@ -2134,9 +2256,10 @@ static int codegen_SAR(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SAR8_CL(block, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) @@ -2162,9 +2285,10 @@ static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHL(codeblock_t *block, uop_t *uop) @@ -2191,9 +2315,10 @@ static int codegen_SHL(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHL8_CL(block, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) @@ -2219,9 +2344,10 @@ static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHR(codeblock_t *block, uop_t *uop) @@ -2248,9 +2374,10 @@ static int codegen_SHR(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHR8_CL(block, dest_reg); } +#ifdef RECOMPILER_DEBUG else fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) @@ -2276,23 +2403,28 @@ static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG if (((uintptr_t)uop->p) >> 32) fatal("STORE_PTR_IMM 64-bit addr\n"); +#endif host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); return 0; } static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { +#ifdef RECOMPILER_DEBUG if (((uintptr_t)uop->p) >> 32) fatal("STORE_PTR_IMM_8 64-bit addr\n"); +#endif host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); return 0; } @@ -2320,9 +2452,10 @@ static int codegen_SUB(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) @@ -2348,9 +2481,10 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } @@ -2371,9 +2505,10 @@ static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { host_x86_TEST8_REG(block, src_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JNS_long(block); return 0; @@ -2395,9 +2530,10 @@ static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { host_x86_TEST8_REG(block, src_reg, src_reg); } +#ifdef RECOMPILER_DEBUG else fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - +#endif uop->p = host_x86_JS_long(block); return 0; @@ -2424,9 +2560,10 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) { host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } +#ifdef RECOMPILER_DEBUG else fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - +#endif return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) @@ -2446,9 +2583,10 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); } +#ifdef RECOMPILER_DEBUG else fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - +#endif return 0; } From e822460f333a16d177dce7d4699763917e6b8795 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 21:22:03 +0000 Subject: [PATCH 0611/1050] Fix missing function prototypes in codegen_backend_x86-64_ops.h. --- src/codegen_backend_x86-64_ops.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 209e270..0f99fe9 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -99,6 +99,7 @@ void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); +void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); @@ -113,6 +114,7 @@ void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int ba void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); +void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data); void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data); @@ -160,6 +162,7 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MULSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); From 9060f4552f7629ee106645447edb3db0fa41f693 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Jan 2019 21:56:57 +0000 Subject: [PATCH 0612/1050] Remove fake 3-operand instructions in x86-64 backend. --- src/codegen_backend_x86-64.c | 22 ++-- src/codegen_backend_x86-64_ops.c | 210 +++++++++++++++--------------- src/codegen_backend_x86-64_ops.h | 60 ++++----- src/codegen_backend_x86-64_uops.c | 119 +++++++++-------- 4 files changed, 209 insertions(+), 202 deletions(-) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 2c1d970..01eec22 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -100,7 +100,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); else fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); host_x86_RET(block); *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; @@ -198,7 +198,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); else fatal("build_store_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); host_x86_RET(block); *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; @@ -305,15 +305,15 @@ void codegen_backend_init() codegen_gpf_rout = &codeblock[block_current].data[block_pos]; #if WIN64 - host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX, REG_ECX); - host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX, REG_EDX); + host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); + host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); #else - host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI, REG_EDI); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI, REG_ESI); + host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); #endif host_x86_CALL(block, (uintptr_t)x86gpf); codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); host_x86_POP(block, REG_R15); host_x86_POP(block, REG_R14); host_x86_POP(block, REG_R13); @@ -349,19 +349,19 @@ void codegen_backend_prologue(codeblock_t *block) host_x86_PUSH(block, REG_R13); host_x86_PUSH(block, REG_R14); host_x86_PUSH(block, REG_R15); - host_x86_SUB32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t)&cpu_state) + 128); if (block->flags & CODEBLOCK_HAS_FPU) { host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); } } void codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD32_REG_IMM(block, REG_ESP, REG_ESP, 0x38); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); host_x86_POP(block, REG_R15); host_x86_POP(block, REG_R14); host_x86_POP(block, REG_R13); diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 90700fe..9e9928d 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -163,10 +163,10 @@ static inline void jmp(codeblock_t *block, uintptr_t func) } } -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); if (dst_reg == REG_EAX) { @@ -179,10 +179,10 @@ void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ } } -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -202,10 +202,10 @@ void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -238,29 +238,29 @@ void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) else fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); } -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) @@ -274,10 +274,10 @@ void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); if (dst_reg == REG_EAX) { @@ -290,10 +290,10 @@ void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ } } -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -313,10 +313,10 @@ void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -336,29 +336,29 @@ void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 codegen_addlong(block, imm_data); } } -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND8_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ } -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND16_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ } -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ } void host_x86_CALL(codeblock_t *block, void *p) @@ -1512,10 +1512,10 @@ void host_x86_NOP(codeblock_t *block) codegen_addbyte(block, 0x90); /*NOP*/ } -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); if (dst_reg == REG_EAX) { @@ -1528,10 +1528,10 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ } } -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -1551,10 +1551,10 @@ void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_ codegen_addword(block, imm_data); } } -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -1574,29 +1574,29 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ codegen_addlong(block, imm_data); } } -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) @@ -2046,10 +2046,10 @@ void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ } -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); if (dst_reg == REG_EAX) { @@ -2062,10 +2062,10 @@ void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ } } -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -2085,10 +2085,10 @@ void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -2121,29 +2121,29 @@ void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) else fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); } -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_SUB8_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_SUB16_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) @@ -2201,10 +2201,10 @@ void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data) +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); if (dst_reg == REG_EAX) { @@ -2217,10 +2217,10 @@ void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ } } -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data) +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -2240,10 +2240,10 @@ void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16 codegen_addword(block, imm_data); } } -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + if (dst_reg & 8) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); if (is_imm8(imm_data)) { @@ -2263,29 +2263,29 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32 codegen_addlong(block, imm_data); } } -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } #endif diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 0f99fe9..aa7e0c7 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -1,22 +1,22 @@ -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data); -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_CALL(codeblock_t *block, void *p); @@ -168,13 +168,13 @@ void host_x86_MULSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_NOP(codeblock_t *block); -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -262,14 +262,14 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data); -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -281,10 +281,10 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data); -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); +void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); +void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 7b475bf..e17ad0e 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -34,19 +34,19 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) if (dest_reg != src_reg_a) host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -65,19 +65,19 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) if (dest_reg != src_reg) host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); else - host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { if (dest_reg != src_reg) host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { if (dest_reg != src_reg) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -89,7 +89,12 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { if (!uop->imm_data) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); + else + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); #ifdef RECOMPILER_DEBUG @@ -112,19 +117,19 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -142,19 +147,19 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { if (dest_reg != src_reg) host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { if (dest_reg != src_reg) host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { if (dest_reg != src_reg) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -631,10 +636,10 @@ static int codegen_FTST(codeblock_t *block, uop_t *uop) host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); if (dest_reg != REG_EAX) host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); @@ -672,10 +677,10 @@ static int codegen_FCOM(codeblock_t *block, uop_t *uop) { if (dest_reg != REG_EAX) host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3); + host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); if (dest_reg != REG_EAX) { host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); @@ -939,7 +944,7 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); if (REG_IS_B(dest_size)) { host_x86_CALL(block, codegen_mem_load_byte); @@ -992,7 +997,7 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1011,7 +1016,7 @@ static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_CALL(block, codegen_mem_load_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); host_x86_JNZ(block, codegen_exit_rout); @@ -1095,7 +1100,7 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); if (REG_IS_B(src_size)) { host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); @@ -1137,7 +1142,7 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_single); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); @@ -1156,7 +1161,7 @@ static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) #endif host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data); + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); host_x86_CALL(block, codegen_mem_store_double); host_x86_TEST32_REG(block, REG_ESI, REG_ESI); @@ -1369,17 +1374,19 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -1394,15 +1401,15 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -2438,19 +2445,19 @@ static int codegen_SUB(codeblock_t *block, uop_t *uop) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -2467,19 +2474,19 @@ static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { if (dest_reg != src_reg) host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { if (dest_reg != src_reg) host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { if (dest_reg != src_reg) host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -2548,17 +2555,17 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) { host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) + else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) + else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); } #ifdef RECOMPILER_DEBUG else @@ -2573,15 +2580,15 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); } #ifdef RECOMPILER_DEBUG else @@ -2781,8 +2788,8 @@ void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); } void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) @@ -2790,8 +2797,8 @@ void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) @@ -2799,8 +2806,8 @@ void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } @@ -2833,8 +2840,8 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); } void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) @@ -2842,8 +2849,8 @@ void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) @@ -2851,8 +2858,8 @@ void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } From 2ccf771cf3d341a455def1710225ea72c0fbc915 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 1 Feb 2019 20:11:08 +0000 Subject: [PATCH 0613/1050] Cleaned up exec386_dynarec() a bit. --- src/386_dynarec.c | 696 ++++++++++++++++++++++------------------------ 1 file changed, 333 insertions(+), 363 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 0137238..3e77c8a 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -506,7 +506,7 @@ int dontprint=0; #include "386_ops.h" -#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(cpu_state.flags & T_FLAG)) +#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) //#define CACHE_ON() 0 static int cycles_main = 0; @@ -518,7 +518,7 @@ void exec386_dynarec(int cycs) int cycdiff; int oldcyc; int cyc_period = cycs / 2000; /*5us*/ -//output = 3; + cycles_main += cycs; while (cycles_main > 0) { @@ -527,385 +527,317 @@ void exec386_dynarec(int cycs) cycles += cyc_period; cycles_start = cycles; -// output=3; - while (cycles>0) - { - oldcyc=cycles; -// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); - if (!CACHE_ON()) /*Interpret block*/ + while (cycles>0) { - cpu_block_end = 0; - x86_was_reset = 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) + oldcyc=cycles; +// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); + if (!CACHE_ON()) /*Interpret block*/ { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + cpu_block_end = 0; + x86_was_reset = 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) + { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -// if (!fetchdat) -// fatal("Dead with cache off\n"); - if (!cpu_state.abrt) - { - trap = cpu_state.flags & T_FLAG; - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + fetchdat = fastreadl(cs + cpu_state.pc); -// 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); - } - - if (((cs + cpu_state.pc) >> 12) != pccache) - CPU_BLOCK_END(); - -/* if (ssegs) - { - ds=oldds; - ss=oldss; - ssegs=0; - }*/ - if (cpu_state.abrt) - CPU_BLOCK_END(); - if (trap) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - - ins++; - insc++; - -/* if ((cs + pc) == 4) - fatal("4\n");*/ -/* if (ins >= 141400000) - output = 3;*/ - } - } - else - { - uint32_t phys_addr = get_phys(cs+cpu_state.pc); - int hash = HASH(phys_addr); - codeblock_t *block = &codeblock[codeblock_hash[hash]]; - int valid_block = 0; - - if (!cpu_state.abrt) - { - page_t *page = &pages[phys_addr >> 12]; - - /*Block must match current CS, PC, code segment size, - 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) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (!valid_block) - { - uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_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); - if (new_block) + if (!cpu_state.abrt) { - valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (valid_block) - { - block = new_block; - codeblock_hash[hash] = get_block_nr(block); - } + trap = cpu_state.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); } - } - } - if (valid_block && (block->page_mask & *block->dirty_mask)) - { - codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); - page->dirty_mask[(phys_addr >> 10) & 3] = 0; - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - } - if (valid_block && block->page_mask2) - { - /*We don't want the second page to cause a page - fault at this stage - that would break any - code crossing a page boundary where the first - page is present but the second isn't. Instead - 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->pc + 0x400); - 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 & *block->dirty_mask2) - { - 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 == BLOCK_PC_INVALID) - valid_block = 0; - } - } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) - { - /*FPU top-of-stack does not match the value this block was compiled - with, re-compile using dynamic top-of-stack*/ - block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); - } - } + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) - { - void (*code)() = (void *)&block->data[BLOCK_START]; - -// 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; -// cpu_recomp_ins += block->ins; - cpu_recomp_blocks++; -/* ins += codeblock_ins[index]; - insc += codeblock_ins[index];*/ -/* pclog("Exit block now %04X:%04X\n", CS, pc);*/ - } - else if (valid_block && !cpu_state.abrt) - { - uint32_t 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_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) - { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); -// if (fetchdat == 0xffffffff) -// fatal("Dead ffffffff\n"); -// if (!fetchdat) -// fatal("Dead\n"); - if (!cpu_state.abrt) - { - trap = cpu_state.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); - - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - - if (x86_was_reset) - break; - } - - /*Cap source code at 4000 bytes per block; this - 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) > 1000) - CPU_BLOCK_END(); + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); - if (trap) - CPU_BLOCK_END(); - - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - - if (cpu_state.abrt) - { - codegen_block_remove(); - CPU_BLOCK_END(); + ins++; + insc++; } - - ins++; - insc++; - } - - if (!cpu_state.abrt && !x86_was_reset) - codegen_block_end_recompile(block); - - if (x86_was_reset) - codegen_reset(); - - codegen_in_recompile = 0; -// output &= ~2; - } - else if (!cpu_state.abrt) - { - /*Mark block but do not recompile*/ - uint32_t 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) - { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - trap = cpu_state.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++; - - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - - if (x86_was_reset) - break; - } - - /*Cap source code at 4000 bytes per block; this - 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) > 1000) - CPU_BLOCK_END(); - - if (trap) - CPU_BLOCK_END(); - - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - - if (cpu_state.abrt) - { - codegen_block_remove(); - CPU_BLOCK_END(); - } - - ins++; - insc++; - } - - if (!cpu_state.abrt && !x86_was_reset) - codegen_block_end(); - - if (x86_was_reset) - codegen_reset(); - -// output &= ~2; - } - else - cpu_state.oldpc = cpu_state.pc; - -// if (output && (SP & 1)) -// fatal("odd SP\n"); - } - - cycdiff=oldcyc-cycles; - tsc += cycdiff; - -// timer_end_period(cycles); - - if (cpu_state.abrt) - { - flags_rebuild(); - tempi = cpu_state.abrt; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; - pclog("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - pclog("Triple fault - reset\n"); - } - } - } - - if (trap) - { - trap = 0; - flags_rebuild(); -// oldpc=pc; - if (msw&1) - { - pmodeint(1,0); } else { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = &codeblock[codeblock_hash[hash]]; + int valid_block = 0; + + if (!cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + 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) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_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); + 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) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; + codeblock_hash[hash] = get_block_nr(block); + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + 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->pc + 0x400); + 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 & *block->dirty_mask2) + { + 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 == BLOCK_PC_INVALID) + valid_block = 0; + } + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); + } + } + + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +// 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; + + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + uint32_t start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + 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) + { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + trap = cpu_state.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); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + /*Cap source code at 4000 bytes per block; this + 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) > 1000) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + insc++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + uint32_t start_pc = cpu_state.pc; + + cpu_block_end = 0; + x86_was_reset = 0; + + 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) + { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + trap = cpu_state.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++; + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + /*Cap source code at 4000 bytes per block; this + 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) > 1000) + CPU_BLOCK_END(); + + if (trap) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + insc++; + } + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + else + cpu_state.oldpc = cpu_state.pc; + } - } - else if (nmi && nmi_enable && nmi_mask) - { - cpu_state.oldpc = cpu_state.pc; -// pclog("NMI\n"); - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) + + cycdiff=oldcyc-cycles; + tsc += cycdiff; + + if (cpu_state.abrt) { - nmi_auto_clear = 0; - nmi = 0; + flags_rebuild(); + tempi = cpu_state.abrt; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + pclog("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + pclog("Triple fault - reset\n"); + } + } } - } - else if ((cpu_state.flags & I_FLAG) && pic_intpending) - { - temp=picinterrupt(); - if (temp!=0xFF) + + if (trap) { -// pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc); - CPU_BLOCK_END(); + trap = 0; flags_rebuild(); if (msw&1) { - pmodeint(temp,0); + pmodeint(1,0); } else { @@ -913,16 +845,54 @@ inrecomp=0; writememw(ss,(SP-4)&0xFFFF,CS); writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); SP-=6; - addr=temp<<2; + addr = (1 << 2) + idt.base; cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; - oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } } + else if (nmi && nmi_enable && nmi_mask) + { + cpu_state.oldpc = cpu_state.pc; +// pclog("NMI\n"); + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } + } + else if ((cpu_state.flags & I_FLAG) && pic_intpending) + { + 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) + { + pmodeint(temp,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr=temp<<2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + oxpc=cpu_state.pc; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + } } - } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) timer_process(); cycles_main -= (cycles_start - cycles); From 9a6376dbf99eaa651d94d1650fb7756343420cfe Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 2 Feb 2019 13:46:06 +0000 Subject: [PATCH 0614/1050] Clear codeblock physical addresses when resetting codegen. Fixes out-of-bounds accesses to the pages[] array during reset. --- src/codegen_backend.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/codegen_backend.c b/src/codegen_backend.c index c047ba3..4874233 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -161,7 +161,11 @@ void codegen_reset() codeblock_t *block = &codeblock[c]; if (block->pc != BLOCK_PC_INVALID) + { + block->phys = 0; + block->phys_2 = 0; delete_block(block); + } } memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); From 4c523a5fe2518e86825d9805c379fb823d3e62ad Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 2 Feb 2019 19:20:42 +0000 Subject: [PATCH 0615/1050] Split x86 and x86-64 ops files into main/FPU/SSE files. --- src/Makefile.am | 4 +- src/codegen_backend_x86-64.c | 1 + src/codegen_backend_x86-64_ops.c | 707 +--------------------- src/codegen_backend_x86-64_ops.h | 115 ---- src/codegen_backend_x86-64_ops_helpers.h | 102 ++++ src/codegen_backend_x86-64_ops_sse.c | 614 +++++++++++++++++++ src/codegen_backend_x86-64_ops_sse.h | 114 ++++ src/codegen_backend_x86-64_uops.c | 1 + src/codegen_backend_x86.c | 1 + src/codegen_backend_x86_ops.c | 732 +---------------------- src/codegen_backend_x86_ops.h | 119 ---- src/codegen_backend_x86_ops_fpu.c | 80 +++ src/codegen_backend_x86_ops_fpu.h | 5 + src/codegen_backend_x86_ops_helpers.h | 84 +++ src/codegen_backend_x86_ops_sse.c | 588 ++++++++++++++++++ src/codegen_backend_x86_ops_sse.h | 112 ++++ src/codegen_backend_x86_uops.c | 2 + 17 files changed, 1708 insertions(+), 1673 deletions(-) create mode 100644 src/codegen_backend_x86-64_ops_helpers.h create mode 100644 src/codegen_backend_x86-64_ops_sse.c create mode 100644 src/codegen_backend_x86-64_ops_sse.h create mode 100644 src/codegen_backend_x86_ops_fpu.c create mode 100644 src/codegen_backend_x86_ops_fpu.h create mode 100644 src/codegen_backend_x86_ops_helpers.h create mode 100644 src/codegen_backend_x86_ops_sse.c create mode 100644 src/codegen_backend_x86_ops_sse.h diff --git a/src/Makefile.am b/src/Makefile.am index f098a4d..93f8f32 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,12 +72,12 @@ pcem_SOURCES += wx-sdl2-midi.c endif if CPU_I386 -pcem_SOURCES += codegen_backend_x86.c codegen_backend_x86_ops.c codegen_backend_x86_uops.c +pcem_SOURCES += codegen_backend_x86.c codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c codegen_backend_x86_ops_sse.c codegen_backend_x86_uops.c pcem_CFLAGS += -msse2 endif if CPU_X86_64 -pcem_SOURCES += codegen_backend_x86-64.c codegen_backend_x86-64_ops.c codegen_backend_x86-64_uops.c +pcem_SOURCES += codegen_backend_x86-64.c codegen_backend_x86-64_ops.c codegen_backend_x86-64_ops_sse.c codegen_backend_x86-64_uops.c endif if CPU_ARM diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 01eec22..bfbf6a7 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -6,6 +6,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" #include "codegen_backend_x86-64_ops.h" +#include "codegen_backend_x86-64_ops_sse.h" #include "codegen_reg.h" #include "x86.h" diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 9e9928d..a4a8680 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -6,6 +6,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" #include "codegen_backend_x86-64_ops.h" +#include "codegen_backend_x86-64_ops_helpers.h" #define RM_OP_ADD 0x00 #define RM_OP_OR 0x08 @@ -18,109 +19,6 @@ #define RM_OP_SHR 0x28 #define RM_OP_SAR 0x38 -#define JMP_LEN_BYTES 5 - -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) -{ - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); - } - block_write_data[block_pos++] = val; -} -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) -{ - if (block_pos > (BLOCK_MAX-2)) - { - fatal("codegen_addbyte2 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; -} -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) -{ - if (block_pos > (BLOCK_MAX-3)) - { - fatal("codegen_addbyte3 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; -} -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) -{ - if (block_pos > (BLOCK_MAX-4)) - { - fatal("codegen_addbyte4 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; - block_write_data[block_pos++] = vald; -} - -static inline void codegen_addword(codeblock_t *block, uint16_t val) -{ - if (block_pos > (BLOCK_MAX-2)) - { - fatal("codegen_addword over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint16_t *)&block_write_data[block_pos] = val; - block_pos += 2; -} - -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - if (block_pos > (BLOCK_MAX-4)) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; -} - -static inline void codegen_addquad(codeblock_t *block, uint64_t val) -{ - if (block_pos > (BLOCK_MAX-8)) - { - fatal("codegen_addquad over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint64_t *)&block_write_data[block_pos] = val; - block_pos += 8; -} - -static inline void codegen_alloc_bytes(codeblock_t *block, int size) -{ - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - - /*Add a jump instruction to the new block*/ - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); - - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; - } -} - -static int is_imm8(uint32_t imm_data) -{ - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; -} - static inline void call(codeblock_t *block, uintptr_t func) { uintptr_t diff; @@ -263,17 +161,6 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ -} -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { if (dst_reg & 8) @@ -433,86 +320,6 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ -} - -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); -} - -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ -} -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ -} - -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ -} -void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ -} - void host_x86_JMP(codeblock_t *block, void *p) { jmp(block, (uintptr_t)p); @@ -655,27 +462,6 @@ void host_x86_LAHF(codeblock_t *block) codegen_addbyte(block, 0x9f); /*LAHF*/ } -void host_x86_LDMXCSR(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ - codegen_addlong(block, offset); - } - else - { - fatal("host_x86_LDMXCSR - out of range %p\n", p); - } -} - void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { if (offset) @@ -709,12 +495,6 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ -} - void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -1220,187 +1000,6 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) -{ - if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); - - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} - -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); -} - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (dst_reg & 8) - fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); - - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ -} - -void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { codegen_alloc_bytes(block, 4); @@ -1484,28 +1083,6 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); } -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ -} -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ -} - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ -} -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_NOP(codeblock_t *block) { codegen_alloc_bytes(block, 1); @@ -1599,260 +1176,6 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); -} -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); -} -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); -} - -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ -} -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ -} -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ -} -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ -} - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ -} -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ -} -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ -} -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ -} - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ -} -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ -} -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ -} -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ -} -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ -} -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ -} - -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} - -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ -} -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ -} -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ -} -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ -} - -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ -} -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ -} -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ -} - void host_x86_POP(codeblock_t *block, int dst_reg) { if (dst_reg & 8) @@ -2035,17 +1358,6 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ -} -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ -} - void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { if (dst_reg & 8) @@ -2146,17 +1458,6 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ -} -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); -} - #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) @@ -2195,12 +1496,6 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { if (dst_reg & 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index aa7e0c7..eaee044 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -7,9 +7,6 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); @@ -28,28 +25,6 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); -#define CMPPS_EQ 0 -#define CMPPS_NLT 5 -#define CMPPS_NLE 6 -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); - -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); - -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_JMP(codeblock_t *block, void *p); void host_x86_JNZ(codeblock_t *block, void *p); @@ -76,14 +51,10 @@ uint32_t *host_x86_JZ_long(codeblock_t *block); void host_x86_LAHF(codeblock_t *block); -void host_x86_LDMXCSR(codeblock_t *block, void *p); - void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset); void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); @@ -128,24 +99,6 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); - -void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); @@ -159,13 +112,6 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MULSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_NOP(codeblock_t *block); void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); @@ -176,59 +122,6 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); @@ -259,9 +152,6 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); @@ -271,16 +161,11 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg); void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); diff --git a/src/codegen_backend_x86-64_ops_helpers.h b/src/codegen_backend_x86-64_ops_helpers.h new file mode 100644 index 0000000..4e63bbd --- /dev/null +++ b/src/codegen_backend_x86-64_ops_helpers.h @@ -0,0 +1,102 @@ +#define JMP_LEN_BYTES 5 + +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +{ + if (block_pos >= BLOCK_MAX) + { + fatal("codegen_addbyte over! %i\n", block_pos); +// CPU_BLOCK_END(); + } + block_write_data[block_pos++] = val; +} +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +{ + if (block_pos > (BLOCK_MAX-2)) + { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; +} +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +{ + if (block_pos > (BLOCK_MAX-3)) + { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; +} +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +{ + if (block_pos > (BLOCK_MAX-4)) + { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; +} + +static inline void codegen_addword(codeblock_t *block, uint16_t val) +{ + if (block_pos > (BLOCK_MAX-2)) + { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint16_t *)&block_write_data[block_pos] = val; + block_pos += 2; +} + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + if (block_pos > (BLOCK_MAX-4)) + { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; +} + +static inline void codegen_addquad(codeblock_t *block, uint64_t val) +{ + if (block_pos > (BLOCK_MAX-8)) + { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint64_t *)&block_write_data[block_pos] = val; + block_pos += 8; +} + +static inline void codegen_alloc_bytes(codeblock_t *block, int size) +{ + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) + { + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; + } +} + +static inline int is_imm8(uint32_t imm_data) +{ + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; +} diff --git a/src/codegen_backend_x86-64_ops_sse.c b/src/codegen_backend_x86-64_ops_sse.c new file mode 100644 index 0000000..cdff2c6 --- /dev/null +++ b/src/codegen_backend_x86-64_ops_sse.c @@ -0,0 +1,614 @@ +#ifdef __amd64__ + +#include "ibm.h" +#include "codegen.h" +#include "codegen_allocator.h" +#include "codegen_backend.h" +#include "codegen_backend_x86-64_defs.h" +#include "codegen_backend_x86-64_ops_sse.h" +#include "codegen_backend_x86-64_ops_helpers.h" + +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ +} +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ +} + +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); +} + +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ +} +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ +} + +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ +} +void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); +} +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} + +void host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } + else if (offset < (1ull << 32)) + { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ + codegen_addlong(block, offset); + } + else + { + fatal("host_x86_LDMXCSR - out of range %p\n", p); + } +} + +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ +} + +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) +{ + if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); + + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} + +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} + +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } +} +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); + + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); +} + +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ +} + +void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ +} +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ +} + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ +} +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} + +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ +} + +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ +} +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ +} +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ +} +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ +} +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ +} +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ +} + +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} + +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ +} + +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} + +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); +} + +#endif diff --git a/src/codegen_backend_x86-64_ops_sse.h b/src/codegen_backend_x86-64_ops_sse.h new file mode 100644 index 0000000..39e39f4 --- /dev/null +++ b/src/codegen_backend_x86-64_ops_sse.h @@ -0,0 +1,114 @@ +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +#define CMPPS_EQ 0 +#define CMPPS_NLT 5 +#define CMPPS_NLE 6 +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); + +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); + +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_LDMXCSR(codeblock_t *block, void *p); + +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); + +void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index e17ad0e..aaabbbc 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -8,6 +8,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86-64_defs.h" #include "codegen_backend_x86-64_ops.h" +#include "codegen_backend_x86-64_ops_sse.h" #include "codegen_ir_defs.h" #define STACK_ARG0 (0) diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 7beffc5..7aef0e3 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -7,6 +7,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" +#include "codegen_backend_x86_ops_sse.h" #include "codegen_reg.h" #include "x86.h" diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 47f7493..ce64b33 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -6,6 +6,7 @@ #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" +#include "codegen_backend_x86_ops_helpers.h" #define RM_OP_ADD 0x00 #define RM_OP_OR 0x08 @@ -18,91 +19,6 @@ #define RM_OP_SHR 0x28 #define RM_OP_SAR 0x38 -#define JMP_LEN_BYTES 5 - -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) -{ - if (block_pos >= BLOCK_MAX) - fatal("codegen_addbyte over! %i\n", block_pos); - block_write_data[block_pos++] = val; -} -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) -{ - if (block_pos > (BLOCK_MAX-2)) - fatal("codegen_addbyte2 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; -} -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) -{ - if (block_pos > (BLOCK_MAX-3)) - fatal("codegen_addbyte3 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; -} -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) -{ - if (block_pos > (BLOCK_MAX-4)) - fatal("codegen_addbyte4 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; - block_write_data[block_pos++] = vald; -} - -static inline void codegen_addword(codeblock_t *block, uint16_t val) -{ - if (block_pos > (BLOCK_MAX-2)) - fatal("codegen_addword over! %i\n", block_pos); - *(uint16_t *)&block_write_data[block_pos] = val; - block_pos += 2; -} - -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - if (block_pos > (BLOCK_MAX-4)) - fatal("codegen_addlong over! %i\n", block_pos); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; -} - -static inline void codegen_addquad(codeblock_t *block, uint64_t val) -{ - if (block_pos > (BLOCK_MAX-8)) - fatal("codegen_addquad over! %i\n", block_pos); - *(uint64_t *)&block_write_data[block_pos] = val; - block_pos += 8; -} - -static void codegen_allocate_new_block(codeblock_t *block) -{ - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - - /*Add a jump instruction to the new block*/ - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); - - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; -} - -static inline void codegen_alloc_bytes(codeblock_t *block, int size) -{ - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - codegen_allocate_new_block(block); -} - -static int is_imm8(uint32_t imm_data) -{ - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; -} - void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -191,17 +107,6 @@ void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ -} -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { if (dst_reg == REG_EAX) @@ -336,74 +241,6 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ -} - -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); -} - -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ -} -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ -} - -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ -} -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ -} - -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} - -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ -} -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ -} - void host_x86_INC32_ABS(codeblock_t *block, void *p) { codegen_alloc_bytes(block, 6); @@ -562,23 +399,6 @@ void host_x86_LAHF(codeblock_t *block) codegen_addbyte(block, 0x9f); /*LAHF*/ } -void host_x86_LDMXCSR(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} - void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { if (offset) @@ -605,12 +425,6 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ } -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ -} - void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -958,177 +772,6 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d } } -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); -} -void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) -{ - if (!offset) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ - codegen_addbyte(block, 0x24); - } - else if (offset >= -80 || offset < 0x80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte2(block, 0x24, offset & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, offset); - } - -} - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ -} - void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { codegen_alloc_bytes(block, 4); @@ -1205,28 +848,6 @@ void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_r codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ } -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ -} -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ -} - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ -} -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_alloc_bytes(block, 2); @@ -1297,260 +918,6 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); -} -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); -} -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); -} - -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ -} -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ -} -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ -} -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ -} - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ -} -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ -} -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ -} -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ -} - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ -} -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ -} -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ -} -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ -} -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ -} -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ -} - -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} - -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ -} -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ -} -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ -} -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ -} - -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ -} -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ -} -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ -} - void host_x86_POP(codeblock_t *block, int src_reg) { codegen_alloc_bytes(block, 1); @@ -1667,17 +1034,6 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ -} -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ -} - void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { if (dst_reg == REG_EAX) @@ -1748,17 +1104,6 @@ void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ -} -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { codegen_alloc_bytes(block, 2); @@ -1790,12 +1135,6 @@ void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); -} - void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { codegen_alloc_bytes(block, 2); @@ -1866,73 +1205,4 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) } } -void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) -{ - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ - } -} -void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) -{ - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ - } -} -void host_x87_FLDCW(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) -{ - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ - } -} -void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) -{ - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ - } -} - #endif diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index db7b37c..08b7e9f 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -8,9 +8,6 @@ void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); @@ -28,28 +25,6 @@ void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); -#define CMPPS_EQ 0 -#define CMPPS_NLT 5 -#define CMPPS_NLE 6 -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); - -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); - -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg); -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dest_reg, int src_reg); -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_INC32_ABS(codeblock_t *block, void *p); void host_x86_JMP(codeblock_t *block, void *p); @@ -80,14 +55,10 @@ uint32_t *host_x86_JZ_long(codeblock_t *block); void host_x86_LAHF(codeblock_t *block); -void host_x86_LDMXCSR(codeblock_t *block, void *p); - void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32_t offset); void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); @@ -129,23 +100,6 @@ void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); -void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg); - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); @@ -159,12 +113,6 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); @@ -173,59 +121,6 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); @@ -256,9 +151,6 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); @@ -267,17 +159,12 @@ void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_data); -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); @@ -285,9 +172,3 @@ void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x87_FILDq_BASE(codeblock_t *block, int base_reg); -void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg); -void host_x87_FLDCW(codeblock_t *block, void *p); -void host_x87_FLDd_BASE(codeblock_t *block, int base_reg); -void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg); diff --git a/src/codegen_backend_x86_ops_fpu.c b/src/codegen_backend_x86_ops_fpu.c new file mode 100644 index 0000000..1c3f990 --- /dev/null +++ b/src/codegen_backend_x86_ops_fpu.c @@ -0,0 +1,80 @@ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + +#include "ibm.h" +#include "codegen.h" +#include "codegen_allocator.h" +#include "codegen_backend.h" +#include "codegen_backend_x86_defs.h" +#include "codegen_backend_x86_ops_fpu.h" +#include "codegen_backend_x86_ops_helpers.h" + +void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ + } + else + { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ + } +} +void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ + } + else + { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ + } +} +void host_x87_FLDCW(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ + } + else + { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ + } + else + { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ + } +} +void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) +{ + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ + } + else + { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ + } +} + +#endif diff --git a/src/codegen_backend_x86_ops_fpu.h b/src/codegen_backend_x86_ops_fpu.h new file mode 100644 index 0000000..3692715 --- /dev/null +++ b/src/codegen_backend_x86_ops_fpu.h @@ -0,0 +1,5 @@ +void host_x87_FILDq_BASE(codeblock_t *block, int base_reg); +void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg); +void host_x87_FLDCW(codeblock_t *block, void *p); +void host_x87_FLDd_BASE(codeblock_t *block, int base_reg); +void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg); diff --git a/src/codegen_backend_x86_ops_helpers.h b/src/codegen_backend_x86_ops_helpers.h new file mode 100644 index 0000000..9c100ec --- /dev/null +++ b/src/codegen_backend_x86_ops_helpers.h @@ -0,0 +1,84 @@ +#define JMP_LEN_BYTES 5 + +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +{ + if (block_pos >= BLOCK_MAX) + fatal("codegen_addbyte over! %i\n", block_pos); + block_write_data[block_pos++] = val; +} +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +{ + if (block_pos > (BLOCK_MAX-2)) + fatal("codegen_addbyte2 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; +} +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +{ + if (block_pos > (BLOCK_MAX-3)) + fatal("codegen_addbyte3 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; +} +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +{ + if (block_pos > (BLOCK_MAX-4)) + fatal("codegen_addbyte4 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; +} + +static inline void codegen_addword(codeblock_t *block, uint16_t val) +{ + if (block_pos > (BLOCK_MAX-2)) + fatal("codegen_addword over! %i\n", block_pos); + *(uint16_t *)&block_write_data[block_pos] = val; + block_pos += 2; +} + +static inline void codegen_addlong(codeblock_t *block, uint32_t val) +{ + if (block_pos > (BLOCK_MAX-4)) + fatal("codegen_addlong over! %i\n", block_pos); + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; +} + +static inline void codegen_addquad(codeblock_t *block, uint64_t val) +{ + if (block_pos > (BLOCK_MAX-8)) + fatal("codegen_addquad over! %i\n", block_pos); + *(uint64_t *)&block_write_data[block_pos] = val; + block_pos += 8; +} + +static void codegen_allocate_new_block(codeblock_t *block) +{ + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; +} + +static inline void codegen_alloc_bytes(codeblock_t *block, int size) +{ + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) + codegen_allocate_new_block(block); +} + +static inline int is_imm8(uint32_t imm_data) +{ + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; +} diff --git a/src/codegen_backend_x86_ops_sse.c b/src/codegen_backend_x86_ops_sse.c new file mode 100644 index 0000000..dc20d34 --- /dev/null +++ b/src/codegen_backend_x86_ops_sse.c @@ -0,0 +1,588 @@ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + +#include "ibm.h" +#include "codegen.h" +#include "codegen_allocator.h" +#include "codegen_backend.h" +#include "codegen_backend_x86_defs.h" +#include "codegen_backend_x86_ops_sse.h" +#include "codegen_backend_x86_ops_helpers.h" + +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ +} +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ +} + +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); +} + +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ +} +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ +} + +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ +} +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ +} + +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} + +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ +} +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} + +void host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } + else + { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} + +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ +} + +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) +{ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} +void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) +{ + if (!offset) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ + codegen_addbyte(block, 0x24); + } + else if (offset >= -80 || offset < 0x80) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte2(block, 0x24, offset & 0xff); + } + else + { + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, offset); + } + +} + +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } + else + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } +} +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if (addr < 0x80 || addr >= 0xffffff80) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } + else + { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } + else + { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } + else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); +} +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ +} + +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ +} +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ +} + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ +} +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} + +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ +} + +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ +} +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ +} +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ +} +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ +} +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ +} +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ +} + +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} + +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ +} + +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} + +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); +} + +#endif diff --git a/src/codegen_backend_x86_ops_sse.h b/src/codegen_backend_x86_ops_sse.h new file mode 100644 index 0000000..596f361 --- /dev/null +++ b/src/codegen_backend_x86_ops_sse.h @@ -0,0 +1,112 @@ +void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +#define CMPPS_EQ 0 +#define CMPPS_NLT 5 +#define CMPPS_NLE 6 +void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); + +void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); + +void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg); +void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dest_reg, int src_reg); +void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); + +void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_LDMXCSR(codeblock_t *block, void *p); + +void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); +void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); +void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg); + +void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); +void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); +void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + +void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 55bcc13..b05d4c1 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -9,6 +9,8 @@ #include "codegen_backend.h" #include "codegen_backend_x86_defs.h" #include "codegen_backend_x86_ops.h" +#include "codegen_backend_x86_ops_fpu.h" +#include "codegen_backend_x86_ops_sse.h" #include "codegen_ir_defs.h" /*void codegen_debug() From 095cf53265a83f8a84967527d5177978c6d4ae88 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 3 Feb 2019 17:48:11 +0000 Subject: [PATCH 0616/1050] Added segment limit checking to some instructions. --- src/codegen_backend_arm64_uops.c | 40 ++++++++++++++++++++++++ src/codegen_backend_arm_uops.c | 40 ++++++++++++++++++++++++ src/codegen_backend_x86-64_uops.c | 42 +++++++++++++++++++++++++ src/codegen_backend_x86_uops.c | 42 +++++++++++++++++++++++++ src/codegen_ir_defs.h | 17 +++++++++++ src/codegen_ops_fpu_loadstore.c | 2 ++ src/codegen_ops_helpers.h | 18 +++++++++++ src/codegen_ops_mmx_loadstore.c | 2 ++ src/codegen_ops_mov.c | 5 +++ src/codegen_reg.c | 14 +++++++++ src/codegen_reg.h | 51 ++++++++++++++++++++++++++++++- 11 files changed, 272 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 48f748b..47a6b3a 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -306,6 +306,43 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); + + jump_p = host_arm64_BCC_(block); + host_arm64_branch_set_offset(jump_p, uop->p); + + return 0; +} +static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + + jump_p = host_arm64_BHI_(block); + host_arm64_branch_set_offset(jump_p, uop->p); + + return 0; +} + static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2751,6 +2788,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 5160511..a47488d 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -381,6 +381,43 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BCC_(block); + *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BHI_(block); + *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} + static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2900,6 +2937,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index aaabbbc..da8e8e4 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -277,6 +277,45 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +#ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); +#endif + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + + return 0; +} +static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +#ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); +#endif + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + + return 0; +} + static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2665,6 +2704,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index b05d4c1..f3ace1e 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -285,6 +285,45 @@ static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +#ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); +#endif + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + + return 0; +} +static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +#ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); +#endif + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + + return 0; +} + static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2664,6 +2703,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index aa95c06..a69f346 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -125,6 +125,10 @@ #define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_DOUBLE - src_reg_a:[src_reg_b] = src_reg_c*/ #define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) +/*UOP_CMP_JB - if (src_reg_a < src_reg_b) then jump to ptr*/ +#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) +/*UOP_CMP_JNBE - if (src_reg_a > src_reg_b) then jump to ptr*/ +#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ #define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) @@ -563,6 +567,16 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, uop->imm_data = imm; } +static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) +{ + uop_t *uop = uop_alloc(ir); + + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->p = p; +} + #define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) @@ -596,6 +610,9 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) #define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) +#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) +#define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p) + #define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) diff --git a/src/codegen_ops_fpu_loadstore.c b/src/codegen_ops_fpu_loadstore.c index f5e42f3..e61e5cb 100644 --- a/src/codegen_ops_fpu_loadstore.c +++ b/src/codegen_ops_fpu_loadstore.c @@ -79,6 +79,7 @@ uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet op_pc--; target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); return op_pc+1; @@ -92,6 +93,7 @@ uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe op_pc--; target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); fpu_POP(block, ir); diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h index 9bde28f..0da73b6 100644 --- a/src/codegen_ops_helpers.h +++ b/src/codegen_ops_helpers.h @@ -1,3 +1,5 @@ +#include "codegen_backend.h" + static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) { if (stack32) @@ -67,3 +69,19 @@ static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) else uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } + +static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || + (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; + + uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout); + if (end_offset) + { + uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset); + uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout); + } + else + uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); +} diff --git a/src/codegen_ops_mmx_loadstore.c b/src/codegen_ops_mmx_loadstore.c index e0ea5f7..e3c33e0 100644 --- a/src/codegen_ops_mmx_loadstore.c +++ b/src/codegen_ops_mmx_loadstore.c @@ -51,6 +51,7 @@ uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); } @@ -99,6 +100,7 @@ uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); } diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index c33271f..669523d 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -5,6 +5,7 @@ #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" +#include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -50,6 +51,7 @@ uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); } @@ -71,6 +73,7 @@ uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); } @@ -92,6 +95,7 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); } @@ -363,6 +367,7 @@ uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); } diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 7c74153..f352d0a 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -149,6 +149,20 @@ struct [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_low] = {REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_low] = {REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_low] = {REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_low] = {REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_low] = {REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_low] = {REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, + + [IREG_CS_limit_high] = {REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_high] = {REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_high] = {REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_high] = {REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_high] = {REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_high] = {REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 2e76936..b498ac4 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -119,7 +119,21 @@ enum IREG_flagsx = 74, IREG_eflagsx = 75, - IREG_COUNT = 76, + IREG_CS_limit_low = 76, + IREG_DS_limit_low = 77, + IREG_ES_limit_low = 78, + IREG_FS_limit_low = 79, + IREG_GS_limit_low = 80, + IREG_SS_limit_low = 81, + + IREG_CS_limit_high = 82, + IREG_DS_limit_high = 83, + IREG_ES_limit_high = 84, + IREG_FS_limit_high = 85, + IREG_GS_limit_high = 86, + IREG_SS_limit_high = 87, + + IREG_COUNT = 88, IREG_INVALID = 255, @@ -221,6 +235,41 @@ static inline int ireg_seg_base(x86seg *seg) return 0; } +static inline int ireg_seg_limit_low(x86seg *seg) +{ + if (seg == &cpu_state.seg_cs) + return IREG_CS_limit_low; + if (seg == &cpu_state.seg_ds) + return IREG_DS_limit_low; + if (seg == &cpu_state.seg_es) + return IREG_ES_limit_low; + if (seg == &cpu_state.seg_fs) + return IREG_FS_limit_low; + if (seg == &cpu_state.seg_gs) + return IREG_GS_limit_low; + if (seg == &cpu_state.seg_ss) + return IREG_SS_limit_low; + fatal("ireg_seg_limit_low : unknown segment\n"); + return 0; +} +static inline int ireg_seg_limit_high(x86seg *seg) +{ + if (seg == &cpu_state.seg_cs) + return IREG_CS_limit_high; + if (seg == &cpu_state.seg_ds) + return IREG_DS_limit_high; + if (seg == &cpu_state.seg_es) + return IREG_ES_limit_high; + if (seg == &cpu_state.seg_fs) + return IREG_FS_limit_high; + if (seg == &cpu_state.seg_gs) + return IREG_GS_limit_high; + if (seg == &cpu_state.seg_ss) + return IREG_SS_limit_high; + fatal("ireg_seg_limit_high : unknown segment\n"); + return 0; +} + extern uint8_t reg_last_version[IREG_COUNT]; extern uint8_t reg_version_refcount[IREG_COUNT][256]; From d66731f85ad8256108f96a61f4c5418e367f7875 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 3 Feb 2019 21:35:24 +0000 Subject: [PATCH 0617/1050] In codegen_ir_compile(), rearrange order of register lookups and order barrier flushing to reduce pointless writes of temporary registers. --- src/codegen_ir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 97a2dc1..556cb8c 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -33,8 +33,6 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) if (uop->type & UOP_TYPE_BARRIER) codegen_reg_flush_invalidate(ir, block); - else if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); if (uop->type & UOP_TYPE_JUMP_DEST) { @@ -62,6 +60,13 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) { uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); } + } + + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); + + if (uop->type & UOP_TYPE_PARAMS_REGS) + { if (uop->dest_reg_a.reg != IREG_INVALID) { uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); From b105445a522016069616e73b3013706414549dad Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 4 Feb 2019 21:32:25 +0000 Subject: [PATCH 0618/1050] Correct Voodoo hvRetrace register. Fixes intermittent hangs on Voodoo mode setting. --- src/vid_voodoo.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 8a1d76c..a5d03e7 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -6127,8 +6127,19 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) temp = voodoo->line & 0x1fff; break; case SST_hvRetrace: - temp = voodoo->line & 0x1fff; - temp |= ((((tsc - timer_get_ts_int(&voodoo->timer)) * voodoo->h_total) / (voodoo->line_time >> 32)) << 16) & 0x7ff0000; + { + uint32_t line_time = (uint32_t)(voodoo->line_time >> 32); + uint32_t diff = (timer_get_ts_int(&voodoo->timer) > (tsc & 0xffffffff)) ? (timer_get_ts_int(&voodoo->timer) - (tsc & 0xffffffff)) : 0; + uint32_t pre_div = diff * voodoo->h_total; + uint32_t post_div = pre_div / line_time; + uint32_t h_pos = (voodoo->h_total - 1) - post_div; + + if (h_pos >= voodoo->h_total) + h_pos = 0; + + temp = voodoo->line & 0x1fff; + temp |= (h_pos << 16); + } break; case SST_fbiInit5: From 222071b742afabf7538628507ff7ae30131f4aff Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 5 Feb 2019 21:54:38 +0000 Subject: [PATCH 0619/1050] ADC and SBC now use lazy flags. --- src/x86_flags.h | 160 ++++++++++++++++++++++++++++-------------------- 1 file changed, 92 insertions(+), 68 deletions(-) diff --git a/src/x86_flags.h b/src/x86_flags.h index e7c2cc2..8d50dba 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -33,6 +33,14 @@ enum FLAGS_DEC8, FLAGS_DEC16, FLAGS_DEC32, + + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, + + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 }; static inline int ZF_SET() @@ -63,6 +71,12 @@ static inline int ZF_SET() case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: return !cpu_state.flags_res; case FLAGS_UNKNOWN: @@ -83,6 +97,8 @@ static inline int NF_SET() case FLAGS_SAR8: case FLAGS_INC8: case FLAGS_DEC8: + case FLAGS_ADC8: + case FLAGS_SBC8: return cpu_state.flags_res & 0x80; case FLAGS_ZN16: @@ -93,6 +109,8 @@ static inline int NF_SET() case FLAGS_SAR16: case FLAGS_INC16: case FLAGS_DEC16: + case FLAGS_ADC16: + case FLAGS_SBC16: return cpu_state.flags_res & 0x8000; case FLAGS_ZN32: @@ -103,6 +121,8 @@ static inline int NF_SET() case FLAGS_SAR32: case FLAGS_INC32: case FLAGS_DEC32: + case FLAGS_ADC32: + case FLAGS_SBC32: return cpu_state.flags_res & 0x80000000; case FLAGS_UNKNOWN: @@ -139,6 +159,12 @@ static inline int PF_SET() case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; case FLAGS_UNKNOWN: @@ -159,22 +185,28 @@ static inline int VF_SET() case FLAGS_SAR32: return 0; + case FLAGS_ADC8: case FLAGS_ADD8: case FLAGS_INC8: return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_ADC16: case FLAGS_ADD16: case FLAGS_INC16: return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_ADC32: case FLAGS_ADD32: case FLAGS_INC32: return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_SBC8: case FLAGS_SUB8: case FLAGS_DEC8: return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SBC16: case FLAGS_SUB16: case FLAGS_DEC16: return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SBC32: case FLAGS_SUB32: case FLAGS_DEC32: return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); @@ -225,6 +257,16 @@ static inline int AF_SET() case FLAGS_INC32: return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_SUB8: case FLAGS_SUB16: case FLAGS_SUB32: @@ -232,6 +274,12 @@ static inline int AF_SET() case FLAGS_DEC16: case FLAGS_DEC32: return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; + + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || + ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); case FLAGS_UNKNOWN: return cpu_state.flags & A_FLAG; @@ -250,11 +298,27 @@ static inline int CF_SET() case FLAGS_ADD32: return (cpu_state.flags_res < cpu_state.flags_op1); + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_SUB8: case FLAGS_SUB16: case FLAGS_SUB32: return (cpu_state.flags_op1 < cpu_state.flags_op2); - + + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || + (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + case FLAGS_SHL8: return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80; case FLAGS_SHL16: @@ -447,85 +511,45 @@ static inline void setsub32nc(uint32_t a, uint32_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; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable8[c&0xFF]; - if (c & 0x100) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xff; + cpu_state.flags_op = FLAGS_ADC8; } 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; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable16[c&0xFFFF]; - if (c & 0x10000) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xffff; + cpu_state.flags_op = FLAGS_ADC16; +} +static inline void setadc32(uint32_t a, uint32_t b) +{ + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b + tempc; + cpu_state.flags_op = FLAGS_ADC32; } 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; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable8[c&0xFF]; - if (c & 0x100) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x80) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xff; + cpu_state.flags_op = FLAGS_SBC8; } 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; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= (znptable16[c&0xFFFF] & ~4); - cpu_state.flags |= (znptable8[c&0xFF] & 4); - if (c & 0x10000) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x8000) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; -} - -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; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= ((c & 0x80000000) ? N_FLAG : ((!c) ? Z_FLAG : 0)); - cpu_state.flags |= (znptable8[c&0xFF] & P_FLAG); - if ((c < a) || (c == a && tempc)) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x80000000) && ((a ^ c) & 0x80000000)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF) + tempc) & 0x10) - cpu_state.flags |= A_FLAG; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xffff; + cpu_state.flags_op = FLAGS_SBC16; } 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; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= ((c & 0x80000000) ? N_FLAG : ((!c) ? Z_FLAG : 0)); - cpu_state.flags |= (znptable8[c&0xFF] & P_FLAG); - if ((c > a) || (c == a && tempc)) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x80000000) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) - cpu_state.flags |= A_FLAG; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - (b + tempc); + cpu_state.flags_op = FLAGS_SBC32; } From d4d6a26283d4f92f8bf57c456101a0ad4f8b0d2a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 6 Feb 2019 21:07:45 +0000 Subject: [PATCH 0620/1050] Added recompiled versions of ADC and SBC. --- src/codegen_ops.c | 4 +- src/codegen_ops_arith.c | 739 +++++++++++++++++++++++++++++++++++++++- src/codegen_ops_arith.h | 20 ++ src/codegen_reg.h | 1 + src/x86_flags.h | 10 +- 5 files changed, 750 insertions(+), 24 deletions(-) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index a339224..5c63795 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -27,7 +27,7 @@ RecompOpFn recomp_opcodes[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16, +/*10*/ ropADC_b_rmw, ropADC_w_rmw, ropADC_b_rm, ropADC_w_rm, ropADC_AL_imm, ropADC_AX_imm, ropPUSH_SS_16, NULL, ropSBB_b_rmw, ropSBB_w_rmw, ropSBB_b_rm, ropSBB_w_rm, ropSBB_AL_imm, ropSBB_AX_imm, ropPUSH_DS_16, ropPOP_DS_16, /*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL, @@ -49,7 +49,7 @@ RecompOpFn recomp_opcodes[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32, +/*10*/ ropADC_b_rmw, ropADC_l_rmw, ropADC_b_rm, ropADC_l_rm, ropADC_AL_imm, ropADC_EAX_imm, ropPUSH_SS_32, NULL, ropSBB_b_rmw, ropSBB_l_rmw, ropSBB_b_rm, ropSBB_l_rm, ropSBB_AL_imm, ropSBB_EAX_imm, ropPUSH_DS_32, ropPOP_DS_32, /*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL, /*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL, diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 4c7c43d..ca0b980 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -8,6 +8,263 @@ #include "codegen_ops.h" #include "codegen_ops_arith.h" +static inline void get_cf(ir_data_t *ir, int dest_reg) +{ + uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); +} + +uint32_t ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} +uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; +//return 0; + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } + + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } + + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } + + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -462,6 +719,260 @@ uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ return op_pc + 1; } +uint32_t ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + return op_pc + 2; +} +uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } + + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } + + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } + + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -697,9 +1208,6 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ - return 0; - if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -721,6 +1229,26 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); @@ -785,6 +1313,28 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); @@ -826,9 +1376,6 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ - return 0; - if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -850,6 +1397,26 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); @@ -914,6 +1481,28 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); @@ -955,9 +1544,6 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ - return 0; - if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -979,6 +1565,26 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); @@ -1041,6 +1647,28 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV(ir, IREG_flags_res, IREG_temp0); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); @@ -1083,9 +1711,6 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ - return 0; - if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -1107,6 +1732,26 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); @@ -1170,6 +1815,28 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); @@ -1212,11 +1879,6 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t imm; - - if ((fetchdat & 0x30) == 0x10) /*ADC/SBB*/ - return 0; - if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -1237,6 +1899,26 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); @@ -1272,6 +1954,7 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet else { x86seg *target_seg; + uint32_t imm; uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); @@ -1299,6 +1982,28 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MOV(ir, IREG_flags_res, IREG_temp0); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; case 0x20: /*AND*/ uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h index 75a70b2..1338102 100644 --- a/src/codegen_ops_arith.h +++ b/src/codegen_ops_arith.h @@ -1,3 +1,13 @@ +uint32_t ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); @@ -18,6 +28,16 @@ uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index b498ac4..448518e 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -170,6 +170,7 @@ enum IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, + IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, diff --git a/src/x86_flags.h b/src/x86_flags.h index 8d50dba..70d8965 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -292,9 +292,9 @@ static inline int CF_SET() switch (cpu_state.flags_op) { case FLAGS_ADD8: - return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100; + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; case FLAGS_ADD16: - return (cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000; + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; case FLAGS_ADD32: return (cpu_state.flags_res < cpu_state.flags_op1); @@ -320,11 +320,11 @@ static inline int CF_SET() (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); case FLAGS_SHL8: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80; + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; case FLAGS_SHL16: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000; + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; case FLAGS_SHL32: - return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000; + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; case FLAGS_SHR8: case FLAGS_SHR16: From 87031d4d0966930b43c329760adaa56f3ab77473 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 20:18:03 +0000 Subject: [PATCH 0621/1050] Remove readmemb386l() and writememb386l(). --- src/386_common.h | 8 ++--- src/386_dynarec.c | 2 +- src/808x.c | 2 +- src/codegen_backend_x86-64.c | 8 ++--- src/codegen_backend_x86.c | 8 ++--- src/ibm.h | 2 -- src/mem.c | 59 ++---------------------------------- 7 files changed, 17 insertions(+), 72 deletions(-) diff --git a/src/386_common.h b/src/386_common.h index 91bf3c1..fa18096 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -4,10 +4,10 @@ extern uint16_t ea_rseg; #undef writememb -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmemb386l((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) +#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((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)+(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) writememb386l((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) writemembl((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)+(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)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v @@ -225,11 +225,11 @@ static inline void seteaq(uint64_t v) writememql(easeg+cpu_state.eaaddr, v); } -#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v +#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v #define seteaw(v) if (cpu_mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v #define seteal(v) if (cpu_mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v -#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg+cpu_state.eaaddr,v); +#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); #define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); #define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 3e77c8a..f6c5572 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -428,7 +428,7 @@ int checkio(int port) // 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(tr.base + t + (port >> 3)); + d = readmembl(tr.base + t + (port >> 3)); // d=readmemb(tr.base,t+(port>>3)); cpl_override = 0; // pclog("%02X %02X\n",d,d&(1<<(port&7))); diff --git a/src/808x.c b/src/808x.c index a20dc29..465156e 100644 --- a/src/808x.c +++ b/src/808x.c @@ -529,7 +529,7 @@ void dumpregs() for (c=0;c<0x0050000;c++) { cpu_state.abrt = 0; - putc(readmemb386l(c+0x80000000),f); + putc(readmembl(c+0x80000000),f); } fclose(f); pclog("Dumping done\n"); diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index bfbf6a7..f1dcd86 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -71,7 +71,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) * PUSH EAX PUSH EDX PUSH ECX - CALL readmemb386l + CALL readmembl POP ECX POP EDX POP EAX @@ -117,7 +117,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) #endif if (size == 1 && !is_float) { - host_x86_CALL(block, (void *)readmemb386l); + host_x86_CALL(block, (void *)readmembl); host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); } else if (size == 2 && !is_float) @@ -169,7 +169,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) * PUSH EAX PUSH EDX PUSH ECX - CALL writememb386l + CALL writemembl POP ECX POP EDX POP EAX @@ -227,7 +227,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data #endif if (size == 1) - host_x86_CALL(block, (void *)writememb386l); + host_x86_CALL(block, (void *)writemembl); else if (size == 2) host_x86_CALL(block, (void *)writememwl); else if (size == 4) diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 7aef0e3..1700eb0 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -71,7 +71,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) * PUSH EAX PUSH EDX PUSH ECX - CALL readmemb386l + CALL readmembl POP ECX POP EDX POP EAX @@ -110,7 +110,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_x86_PUSH(block, REG_EDX); host_x86_PUSH(block, REG_ECX); if (size == 1) - host_x86_CALL(block, (void *)readmemb386l); + host_x86_CALL(block, (void *)readmembl); else if (size == 2) host_x86_CALL(block, (void *)readmemwl); else if (size == 4) @@ -161,7 +161,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) * PUSH EAX PUSH EDX PUSH ECX - CALL writememb386l + CALL writemembl POP ECX POP EDX POP EAX @@ -208,7 +208,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) } host_x86_PUSH(block, REG_EDI); if (size == 1) - host_x86_CALL(block, (void *)writememb386l); + host_x86_CALL(block, (void *)writemembl); else if (size == 2) host_x86_CALL(block, (void *)writememwl); else if (size == 4) diff --git a/src/ibm.h b/src/ibm.h index b587e62..026d4e0 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -45,8 +45,6 @@ extern int mmu_perm; //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 addr); -void writememb386l(uint32_t addr, uint8_t val); uint16_t readmemwl(uint32_t addr); void writememwl(uint32_t addr, uint16_t val); uint32_t readmemll(uint32_t addr); diff --git a/src/mem.c b/src/mem.c index cc253d8..6cb3888 100644 --- a/src/mem.c +++ b/src/mem.c @@ -497,50 +497,6 @@ void writemembl(uint32_t addr, uint8_t val) // else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); } -uint8_t readmemb386l(uint32_t addr) -{ - mem_logical_addr = addr; -/* if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF) - { - return ram[readlookup2[mem_logical_addr >> 12] + (mem_logical_addr & 0xFFF)]; - }*/ - - if (cr0 >> 31) - { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) return 0xFF; - } - - 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; -} - -void writememb386l(uint32_t addr, uint8_t val) -{ - mem_logical_addr = addr; - if (page_lookup[addr>>12]) - { - page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); - return; - } - if (cr0 >> 31) - { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) return; - } - - 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 addr) { mem_logical_addr = addr; @@ -556,8 +512,7 @@ uint16_t readmemwl(uint32_t addr) if (mmutranslate_read(addr) == 0xffffffff) return 0xffff; if (mmutranslate_read(addr+1) == 0xffffffff) return 0xffff; } - if (is386) return readmemb386l(addr)|(readmemb386l(addr+1)<<8); - else return readmembl(addr)|(readmembl(addr+1)<<8); + return readmembl(addr)|(readmembl(addr+1)<<8); } else if (readlookup2[addr >> 12] != -1) return *(uint16_t *)(readlookup2[addr >> 12] + addr); @@ -594,16 +549,8 @@ void writememwl(uint32_t addr, uint16_t val) if (mmutranslate_write(addr) == 0xffffffff) return; if (mmutranslate_write(addr+1) == 0xffffffff) return; } - if (is386) - { - writememb386l(addr,val); - writememb386l(addr+1,val>>8); - } - else - { - writemembl(addr,val); - writemembl(addr+1,val>>8); - } + writemembl(addr,val); + writemembl(addr+1,val>>8); return; } else if (writelookup2[addr >> 12] != -1) From 5edc23a602c68ee74267f6ded155885fc19403de Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 20:21:39 +0000 Subject: [PATCH 0622/1050] Reduce number of massive static arrays in mem.c. --- src/mem.c | 270 ++++++++++++++++++++++++++---------------------------- 1 file changed, 132 insertions(+), 138 deletions(-) diff --git a/src/mem.c b/src/mem.c index 6cb3888..ccc7057 100644 --- a/src/mem.c +++ b/src/mem.c @@ -22,18 +22,10 @@ page_t *pages; page_t **page_lookup; -static uint8_t (*_mem_read_b[0x40000])(uint32_t addr, void *priv); -static uint16_t (*_mem_read_w[0x40000])(uint32_t addr, void *priv); -static uint32_t (*_mem_read_l[0x40000])(uint32_t addr, void *priv); -static void (*_mem_write_b[0x40000])(uint32_t addr, uint8_t val, void *priv); -static void (*_mem_write_w[0x40000])(uint32_t addr, uint16_t val, void *priv); -static void (*_mem_write_l[0x40000])(uint32_t addr, uint32_t val, void *priv); -static uint8_t *_mem_exec[0x40000]; -static void *_mem_priv_r[0x40000]; -static void *_mem_priv_w[0x40000]; -static mem_mapping_t *_mem_mapping_r[0x40000]; -static mem_mapping_t *_mem_mapping_w[0x40000]; -static int _mem_state[0x40000]; +static mem_mapping_t *read_mapping[0x40000]; +static mem_mapping_t *write_mapping[0x40000]; +static uint8_t *_mem_exec[0x40000]; +static uint8_t _mem_state[0x40000]; static mem_mapping_t base_mapping; mem_mapping_t ram_low_mapping; @@ -448,7 +440,7 @@ uint8_t *getpccache(uint32_t a) if (_mem_exec[a >> 14]) { - if (_mem_mapping_r[a >> 14]->flags & MEM_MAPPING_ROM) + if (read_mapping[a >> 14]->flags & MEM_MAPPING_ROM) cpu_prefetch_cycles = cpu_rom_prefetch_cycles; else cpu_prefetch_cycles = cpu_mem_prefetch_cycles; @@ -464,6 +456,8 @@ uint8_t *getpccache(uint32_t a) uint32_t mem_logical_addr; uint8_t readmembl(uint32_t addr) { + mem_mapping_t *map; + mem_logical_addr = addr; if (cr0 >> 31) { @@ -472,13 +466,17 @@ 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]); + map = read_mapping[addr >> 14]; + if (map && map->read_b) + return map->read_b(addr, map->p); // pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc); return 0xFF; } void writemembl(uint32_t addr, uint8_t val) { + mem_mapping_t *map; + mem_logical_addr = addr; if (page_lookup[addr>>12]) @@ -493,12 +491,16 @@ 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]); + map = write_mapping[addr >> 14]; + if (map && map->write_b) + return map->write_b(addr, val, map->p); // else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); } uint16_t readmemwl(uint32_t addr) { + mem_mapping_t *map; + mem_logical_addr = addr; if (addr & 1) @@ -525,10 +527,15 @@ uint16_t readmemwl(uint32_t addr) addr &= rammask; - if (_mem_read_w[addr >> 14]) return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); + map = read_mapping[addr >> 14]; + if (map) + { + if (map->read_w) + return map->read_w(addr, map->p); - if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]) | (_mem_read_b[(addr + 1) >> 14](addr + 1, _mem_priv_r[addr >> 14]) << 8); + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + } // pclog("Bad readmemwl %08X\n", addr); return 0xffff; @@ -536,6 +543,8 @@ uint16_t readmemwl(uint32_t addr) void writememwl(uint32_t addr, uint16_t val) { + mem_mapping_t *map; + mem_logical_addr = addr; if (addr & 1) @@ -573,23 +582,25 @@ void writememwl(uint32_t addr, uint16_t val) addr &= rammask; - if (_mem_write_w[addr >> 14]) + map = write_mapping[addr >> 14]; + if (map) { - _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - return; + if (map->write_w) + map->write_w(addr, val, map->p); + else if (map->write_b) + { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + } } - if (_mem_write_b[addr >> 14]) - { - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - _mem_write_b[(addr + 1) >> 14](addr + 1, val >> 8, _mem_priv_w[addr >> 14]); - return; - } // pclog("Bad writememwl %08X %04X\n", addr, val); } uint32_t readmemll(uint32_t addr) { + mem_mapping_t *map; + mem_logical_addr = addr; if (addr & 3) @@ -617,11 +628,19 @@ uint32_t readmemll(uint32_t addr) addr&=rammask; - if (_mem_read_l[addr >> 14]) return _mem_read_l[addr >> 14](addr, _mem_priv_r[addr >> 14]); + map = read_mapping[addr >> 14]; + if (map) + { + if (map->read_l) + return map->read_l(addr, map->p); - if (_mem_read_w[addr >> 14]) return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]) | (_mem_read_w[addr >> 14](addr + 2, _mem_priv_r[addr >> 14]) << 16); - - if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]) | (_mem_read_b[addr >> 14](addr + 1, _mem_priv_r[addr >> 14]) << 8) | (_mem_read_b[addr >> 14](addr + 2, _mem_priv_r[addr >> 14]) << 16) | (_mem_read_b[addr >> 14](addr + 3, _mem_priv_r[addr >> 14]) << 24); + if (map->read_w) + return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); + + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | + (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); + } // pclog("Bad readmemll %08X\n", addr); return 0xffffffff; @@ -629,6 +648,8 @@ uint32_t readmemll(uint32_t addr) void writememll(uint32_t addr, uint32_t val) { + mem_mapping_t *map; + mem_logical_addr = addr; if (addr & 3) @@ -665,33 +686,31 @@ void writememll(uint32_t addr, uint32_t val) addr&=rammask; -/* if (addr >= 0xa0000 && addr < 0xc0000) - pclog("writememll %08X %08X\n", addr, val);*/ - - if (_mem_write_l[addr >> 14]) + map = write_mapping[addr >> 14]; + if (map) { - _mem_write_l[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - return; - } - if (_mem_write_w[addr >> 14]) - { - _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - _mem_write_w[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); - return; - } - if (_mem_write_b[addr >> 14]) - { - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 1, val >> 8, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 3, val >> 24, _mem_priv_w[addr >> 14]); - return; + if (map->write_l) + map->write_l(addr, val, map->p); + else if (map->write_w) + { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + } + else if (map->write_b) + { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + } } // pclog("Bad writememll %08X %08X\n", addr, val); } uint64_t readmemql(uint32_t addr) { + mem_mapping_t *map; + mem_logical_addr = addr; if (addr & 7) @@ -718,15 +737,17 @@ uint64_t readmemql(uint32_t addr) addr&=rammask; - if (_mem_read_l[addr >> 14]) - return _mem_read_l[addr >> 14](addr, _mem_priv_r[addr >> 14]) | - ((uint64_t)_mem_read_l[addr >> 14](addr + 4, _mem_priv_r[addr >> 14]) << 32); + map = read_mapping[addr >> 14]; + if (map && map->read_l) + return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); return readmemll(addr) | ((uint64_t)readmemll(addr+4)<<32); } void writememql(uint32_t addr, uint64_t val) { + mem_mapping_t *map; + mem_logical_addr = addr; if (addr & 7) @@ -763,76 +784,87 @@ void writememql(uint32_t addr, uint64_t val) addr&=rammask; - if (_mem_write_l[addr >> 14]) + map = write_mapping[addr >> 14]; + if (map) { - _mem_write_l[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - _mem_write_l[addr >> 14](addr+4, val >> 32, _mem_priv_w[addr >> 14]); - return; - } - if (_mem_write_w[addr >> 14]) - { - _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - _mem_write_w[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); - _mem_write_w[addr >> 14](addr + 4, val >> 32, _mem_priv_w[addr >> 14]); - _mem_write_w[addr >> 14](addr + 6, val >> 48, _mem_priv_w[addr >> 14]); - return; - } - if (_mem_write_b[addr >> 14]) - { - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 1, val >> 8, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 2, val >> 16, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 3, val >> 24, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 4, val >> 32, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 5, val >> 40, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 6, val >> 48, _mem_priv_w[addr >> 14]); - _mem_write_b[addr >> 14](addr + 7, val >> 56, _mem_priv_w[addr >> 14]); - return; + if (map->write_l) + { + map->write_l(addr, val, map->p); + map->write_l(addr + 4, val >> 32, map->p); + } + else if (map->write_w) + { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr + 4, val >> 32, map->p); + map->write_w(addr + 6, val >> 48, map->p); + } + else if (map->write_b) + { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr + 4, val >> 32, map->p); + map->write_b(addr + 5, val >> 40, map->p); + map->write_b(addr + 6, val >> 48, map->p); + map->write_b(addr + 7, val >> 56, map->p); + } } // pclog("Bad writememql %08X %08X\n", addr, val); } uint8_t mem_readb_phys(uint32_t addr) { + mem_mapping_t *map = read_mapping[addr >> 14]; + mem_logical_addr = 0xffffffff; - if (_mem_read_b[addr >> 14]) - return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); + if (map && map->read_b) + return map->read_b(addr, map->p); return 0xff; } uint16_t mem_readw_phys(uint32_t addr) { + mem_mapping_t *map = read_mapping[addr >> 14]; + mem_logical_addr = 0xffffffff; - if (_mem_read_w[addr >> 14] && !(addr & 1)) - return _mem_read_w[addr >> 14](addr, _mem_priv_r[addr >> 14]); + if (map && map->read_w) + return map->read_w(addr, map->p); return mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); } uint32_t mem_readl_phys(uint32_t addr) { + mem_mapping_t *map = read_mapping[addr >> 14]; + mem_logical_addr = 0xffffffff; - if (_mem_read_l[addr >> 14] && !(addr & 3)) - return _mem_read_l[addr >> 14](addr, _mem_priv_r[addr >> 14]); + if (map && map->read_l) + return map->read_l(addr, map->p); return mem_readw_phys(addr) | (mem_readw_phys(addr + 2) << 16); } void mem_writeb_phys(uint32_t addr, uint8_t val) { + mem_mapping_t *map = write_mapping[addr >> 14]; + mem_logical_addr = 0xffffffff; - if (_mem_write_b[addr >> 14]) - _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + if (map && map->write_b) + map->write_b(addr, val, map->p); } void mem_writew_phys(uint32_t addr, uint16_t val) { + mem_mapping_t *map = write_mapping[addr >> 14]; + mem_logical_addr = 0xffffffff; - if (_mem_write_w[addr >> 14] && !(addr & 1)) - _mem_write_w[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + if (map && map->write_w && !(addr & 1)) + map->write_w(addr, val, map->p); else { mem_writeb_phys(addr, val); @@ -841,10 +873,12 @@ void mem_writew_phys(uint32_t addr, uint16_t val) } void mem_writel_phys(uint32_t addr, uint32_t val) { + mem_mapping_t *map = write_mapping[addr >> 14]; + mem_logical_addr = 0xffffffff; - if (_mem_write_l[addr >> 14] && !(addr & 3)) - _mem_write_l[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); + if (map && map->write_l && !(addr & 3)) + map->write_l(addr, val, map->p); else { mem_writew_phys(addr, val); @@ -1119,17 +1153,9 @@ static void mem_mapping_recalc(uint64_t base, uint64_t size) /*Clear out old mappings*/ for (c = base; c < base + size; c += 0x4000) { - _mem_read_b[c >> 14] = NULL; - _mem_read_w[c >> 14] = NULL; - _mem_read_l[c >> 14] = NULL; - _mem_priv_r[c >> 14] = NULL; - _mem_mapping_r[c >> 14] = NULL; + read_mapping[c >> 14] = NULL; + write_mapping[c >> 14] = NULL; _mem_exec[c >> 14] = NULL; - _mem_write_b[c >> 14] = NULL; - _mem_write_w[c >> 14] = NULL; - _mem_write_l[c >> 14] = NULL; - _mem_priv_w[c >> 14] = NULL; - _mem_mapping_w[c >> 14] = NULL; } /*Walk mapping list*/ @@ -1148,24 +1174,16 @@ static void mem_mapping_recalc(uint64_t base, uint64_t size) if ((mapping->read_b || mapping->read_w || mapping->read_l) && mem_mapping_read_allowed(mapping->flags, _mem_state[c >> 14])) { - _mem_read_b[c >> 14] = mapping->read_b; - _mem_read_w[c >> 14] = mapping->read_w; - _mem_read_l[c >> 14] = mapping->read_l; + read_mapping[c >> 14] = mapping; if (mapping->exec) _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); else _mem_exec[c >> 14] = NULL; - _mem_priv_r[c >> 14] = mapping->p; - _mem_mapping_r[c >> 14] = mapping; } if ((mapping->write_b || mapping->write_w || mapping->write_l) && mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) { - _mem_write_b[c >> 14] = mapping->write_b; - _mem_write_w[c >> 14] = mapping->write_w; - _mem_write_l[c >> 14] = mapping->write_l; - _mem_priv_w[c >> 14] = mapping->p; - _mem_mapping_w[c >> 14] = mapping; + write_mapping[c >> 14] = mapping; } } } @@ -1336,20 +1354,8 @@ void mem_init() pages[c].evict_prev = EVICT_NOT_IN_LIST; } - memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 64); c++) - { - isram[c] = 1; - if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff)) - isram[c] = 0; - } - - memset(_mem_read_b, 0, sizeof(_mem_read_b)); - memset(_mem_read_w, 0, sizeof(_mem_read_w)); - memset(_mem_read_l, 0, sizeof(_mem_read_l)); - memset(_mem_write_b, 0, sizeof(_mem_write_b)); - memset(_mem_write_w, 0, sizeof(_mem_write_w)); - memset(_mem_write_l, 0, sizeof(_mem_write_l)); + memset(read_mapping, 0, sizeof(read_mapping)); + memset(write_mapping, 0, sizeof(write_mapping)); memset(_mem_exec, 0, sizeof(_mem_exec)); memset(ff_array, 0xff, sizeof(ff_array)); @@ -1446,20 +1452,8 @@ void mem_resize() pages[c].evict_prev = EVICT_NOT_IN_LIST; } - memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 64); c++) - { - isram[c] = 1; - if ((c >= 0xa && c <= 0xf) || (cpu_16bitbus && c >= 0xfe && c <= 0xff)) - isram[c] = 0; - } - - memset(_mem_read_b, 0, sizeof(_mem_read_b)); - memset(_mem_read_w, 0, sizeof(_mem_read_w)); - memset(_mem_read_l, 0, sizeof(_mem_read_l)); - memset(_mem_write_b, 0, sizeof(_mem_write_b)); - memset(_mem_write_w, 0, sizeof(_mem_write_w)); - memset(_mem_write_l, 0, sizeof(_mem_write_l)); + memset(read_mapping, 0, sizeof(read_mapping)); + memset(write_mapping, 0, sizeof(write_mapping)); memset(_mem_exec, 0, sizeof(_mem_exec)); memset(&base_mapping, 0, sizeof(base_mapping)); From 3c2dbf063ee3ad0eac72d7f75866585bf9288724 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 20:23:14 +0000 Subject: [PATCH 0623/1050] Remove unused and superfluous variables from mem.c. --- src/808x.c | 2 -- src/ali1429.c | 2 -- src/headland.c | 4 +--- src/i430fx.c | 1 - src/i430lx.c | 1 - src/i430vx.c | 1 - src/ibm.h | 8 -------- src/mcr.c | 3 +-- src/mem.c | 23 ++++------------------- src/mem.h | 2 -- src/opti495.c | 7 +------ src/pc.c | 5 +---- src/ps2_mca.c | 4 +--- src/scat.c | 2 -- src/sis496.c | 1 - src/um8881f.c | 3 +-- 16 files changed, 10 insertions(+), 59 deletions(-) diff --git a/src/808x.c b/src/808x.c index 465156e..1ea2091 100644 --- a/src/808x.c +++ b/src/808x.c @@ -97,8 +97,6 @@ int noint=0; int output=0; -int shadowbios=0; - int ins=0; //#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) diff --git a/src/ali1429.c b/src/ali1429.c index 388ab48..099a865 100644 --- a/src/ali1429.c +++ b/src/ali1429.c @@ -55,8 +55,6 @@ void ali1429_write(uint16_t port, uint8_t val, void *priv) ali1429_recalc(); break; case 0x14: - shadowbios = val & 1; - shadowbios_write = val & 2; ali1429_recalc(); break; } diff --git a/src/headland.c b/src/headland.c index b3bc4d0..c0ebe01 100644 --- a/src/headland.c +++ b/src/headland.c @@ -20,9 +20,7 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) pclog("Headland write %02X %02X\n",headland_index,val); if (headland_index == 0x82) { - shadowbios = val & 0x10; - shadowbios_write = !(val & 0x10); - if (shadowbios) + if (val & 0x10) 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); diff --git a/src/i430fx.c b/src/i430fx.c index 8a7fe79..4d328b2 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -65,7 +65,6 @@ void i430fx_write(int func, int addr, uint8_t val, void *priv) if ((card_i430fx[0x59] ^ val) & 0xf0) { i430fx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); } pclog("i430fx_write : PAM0 write %02X\n", val); break; diff --git a/src/i430lx.c b/src/i430lx.c index ebde9bc..17ef4a9 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -65,7 +65,6 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv) if ((card_i430lx[0x59] ^ val) & 0xf0) { i430lx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); } pclog("i430lx_write : PAM0 write %02X\n", val); break; diff --git a/src/i430vx.c b/src/i430vx.c index 6b1c4bb..79b7517 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -64,7 +64,6 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) if ((card_i430vx[0x59] ^ val) & 0xf0) { i430vx_map(0xf0000, 0x10000, val >> 4); - shadowbios = (val & 0x10); } pclog("i430vx_write : PAM0 write %02X\n", val); break; diff --git a/src/ibm.h b/src/ibm.h index 026d4e0..f9974be 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -36,13 +36,6 @@ extern int mmu_perm; #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((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)+(a)) & 3))?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); uint16_t readmemwl(uint32_t addr); @@ -69,7 +62,6 @@ 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; diff --git a/src/mcr.c b/src/mcr.c index 83d7530..81293c2 100644 --- a/src/mcr.c +++ b/src/mcr.c @@ -10,7 +10,6 @@ void resetmcr() { mcrlock=0; mcrfirst=1; - shadowbios=0; } void writemcr(uint16_t addr, uint8_t val) @@ -29,7 +28,7 @@ void writemcr(uint16_t addr, uint8_t val) // exit(-1); break; case 0x23: - if (nextreg6) shadowbios=!val; +// if (nextreg6) shadowbios=!val; break; } mcr22=val; diff --git a/src/mem.c b/src/mem.c index ccc7057..74e7980 100644 --- a/src/mem.c +++ b/src/mem.c @@ -36,10 +36,6 @@ mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; static mem_mapping_t romext_mapping; -int shadowbios,shadowbios_write; - -unsigned char isram[0x10000]; - static uint8_t ff_array[0x1000]; int mem_size; @@ -50,7 +46,10 @@ int cachesize=256; uint8_t *ram, *rom = NULL; uint8_t romext[32768]; -//int abrt=0; +uint32_t mem_logical_addr; + +int mmuflush=0; +int mmu_perm=4; void resetreadlookup() { @@ -68,9 +67,6 @@ void resetreadlookup() } -int mmuflush=0; -int mmu_perm=4; - void flushmmucache() { int c; @@ -202,15 +198,9 @@ void mem_flush_write_page(uint32_t addr, uint32_t virt) } } -extern int output; - #define mmutranslate_read(addr) mmutranslatereal(addr,0) #define mmutranslate_write(addr) mmutranslatereal(addr,1) -int pctrans=0; - -extern uint32_t testr[9]; - static inline uint32_t mmu_readl(uint32_t addr) { return *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff]; @@ -423,16 +413,13 @@ void addwritelookup(uint32_t virt, uint32_t phys) cycles -= 9; } -#undef printf uint8_t *getpccache(uint32_t a) { uint32_t a2=a; if (cr0>>31) { - pctrans=1; a = mmutranslate_read(a); - pctrans=0; if (a==0xFFFFFFFF) return ram; } @@ -451,9 +438,7 @@ uint8_t *getpccache(uint32_t a) pclog("Bad getpccache %08X\n", a); return &ff_array[0-(uintptr_t)(a2 & ~0xFFF)]; } -#define printf pclog -uint32_t mem_logical_addr; uint8_t readmembl(uint32_t addr) { mem_mapping_t *map; diff --git a/src/mem.h b/src/mem.h index 4b640ea..5a21e6a 100644 --- a/src/mem.h +++ b/src/mem.h @@ -222,7 +222,5 @@ void mmu_invalidate(uint32_t addr); int loadbios(); -extern unsigned char isram[0x10000]; - extern int purgeable_page_count; #endif diff --git a/src/opti495.c b/src/opti495.c index 1faef5a..ebf8e2b 100644 --- a/src/opti495.c +++ b/src/opti495.c @@ -27,15 +27,10 @@ static void opti495_write(uint16_t addr, uint8_t val, void *p) } if (optireg == 0x22) { - shadowbios = !(val & 0x80); - shadowbios_write = val & 0x80; - //pclog("shadowbios %i %02x\n", shadowbios, val); - if (shadowbios) + if (!(val & 0x80)) 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; diff --git a/src/pc.c b/src/pc.c index ea77535..23099a1 100644 --- a/src/pc.c +++ b/src/pc.c @@ -360,8 +360,7 @@ void initpc(int argc, char *argv[]) ali1429_reset(); // CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9)); // pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); - shadowbios=0; - + #if __unix if (cdrom_drive == -1) cdrom_null_reset(); @@ -387,7 +386,6 @@ void resetpc() // cpuspeed2=(AT)?2:1; // atfullspeed=0; ///* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); - shadowbios=0; } void resetpc_cad() @@ -449,7 +447,6 @@ void resetpchard() // atfullspeed = 0; // setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); - shadowbios = 0; ali1429_reset(); keyboard_at_reset(); diff --git a/src/ps2_mca.c b/src/ps2_mca.c index 5113642..1e8b77f 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -404,10 +404,8 @@ static void model_55sx_write(uint16_t port, uint8_t val) case 0x105: pclog("Write POS3 %02x\n", val); ps2.option[3] = val; - shadowbios = !(val & 0x10); - shadowbios_write = val & 0x10; - if (shadowbios) + if (!(val & 0x10)) { mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); mem_mapping_disable(&ps2.shadow_mapping); diff --git a/src/scat.c b/src/scat.c index 966814f..a899b95 100644 --- a/src/scat.c +++ b/src/scat.c @@ -564,8 +564,6 @@ void scat_init() mem_mapping_disable(&scat_mapping[i]); } - for(i=4;i<10;i++) isram[i] = 0; - // 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++) { diff --git a/src/sis496.c b/src/sis496.c index b958feb..6738ba5 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -43,7 +43,6 @@ void sis496_recalcmapping(sis496_t *sis496) } flushmmucache(); - shadowbios = (sis496->pci_conf[0x44] & 0xf0); } void sis496_write(int func, int addr, uint8_t val, void *p) diff --git a/src/um8881f.c b/src/um8881f.c index b469bbd..84c0434 100644 --- a/src/um8881f.c +++ b/src/um8881f.c @@ -33,8 +33,7 @@ void um8881f_write(int func, int addr, uint8_t val, void *priv) 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); +// shadowbios = val & 0x80; flushmmucache_nopc(); } } From 2735920f5847907fab354121d527da6b37e4f2c6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 20:34:06 +0000 Subject: [PATCH 0624/1050] De-duplicate allocation code in mem_init(). --- src/mem.c | 78 +++++++++---------------------------------------- src/mem.h | 2 +- src/pc.c | 2 +- src/wx-config.c | 2 +- 4 files changed, 16 insertions(+), 68 deletions(-) diff --git a/src/mem.c b/src/mem.c index 74e7980..9c6c536 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1313,69 +1313,6 @@ void mem_add_bios() int mem_a20_key = 0, mem_a20_alt = 0; static int mem_a20_state = 2; -void mem_init() -{ - int c; - - ram = malloc(mem_size * 1024); -// rom = malloc(0x20000); - 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 * 1024); - memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); - - memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); - - for (c = 0; 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; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - } - - memset(read_mapping, 0, sizeof(read_mapping)); - memset(write_mapping, 0, sizeof(write_mapping)); - memset(_mem_exec, 0, sizeof(_mem_exec)); - - memset(ff_array, 0xff, sizeof(ff_array)); - - memset(&base_mapping, 0, sizeof(base_mapping)); - - memset(_mem_state, 0, sizeof(_mem_state)); - - 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_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) - { - if (cpu_16bitbus && mem_size > 16256) - { - mem_set_mem_state(0x100000, (16256 - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((16256 - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - else - { - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); - } - } - 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); - - 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); -// pclog("Mem resize %i %i\n",mem_size,c); - mem_a20_key = 2; - mem_a20_alt = 0; -} - static void mem_remap_top(int max_size) { int c; @@ -1417,7 +1354,16 @@ void mem_set_704kb() mem_mapping_set_addr(&ram_low_mapping, 0x00000, (mem_size > 704) ? 0xb0000 : mem_size * 1024); } -void mem_resize() +void mem_init() +{ + readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); + writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); + page_lookup = malloc((1 << 20) * sizeof(page_t *)); + + memset(ff_array, 0xff, sizeof(ff_array)); +} + +void mem_alloc() { int c; @@ -1436,7 +1382,9 @@ void mem_resize() pages[c].write_l = mem_write_raml_page; pages[c].evict_prev = EVICT_NOT_IN_LIST; } - + + memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); + memset(read_mapping, 0, sizeof(read_mapping)); memset(write_mapping, 0, sizeof(write_mapping)); memset(_mem_exec, 0, sizeof(_mem_exec)); diff --git a/src/mem.h b/src/mem.h index 5a21e6a..3bffffd 100644 --- a/src/mem.h +++ b/src/mem.h @@ -208,7 +208,7 @@ void mem_flush_write_page(uint32_t addr, uint32_t virt); void mem_add_bios(); void mem_init(); -void mem_resize(); +void mem_alloc(); void mem_set_704kb(); diff --git a/src/pc.c b/src/pc.c index 23099a1..d3fd112 100644 --- a/src/pc.c +++ b/src/pc.c @@ -408,7 +408,7 @@ void resetpchard() sound_reset(); io_init(); cpu_set(); - mem_resize(); + mem_alloc(); fdc_init(); disc_reset(); disc_load(0, discfns[0]); diff --git a/src/wx-config.c b/src/wx-config.c index 618363d..90c38a3 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -553,7 +553,7 @@ int config_dlgsave(void* hdlg) if (has_been_inited) { - mem_resize(); + mem_alloc(); loadbios(); resetpchard(); } From 1af0b660b37601d99ba6029bf730655c6a0d71d4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 21:30:53 +0000 Subject: [PATCH 0625/1050] First pass at sanitising CPU headers. --- src/386.c | 22 +++++------ src/386.h | 13 ------- src/386_common.h | 3 -- src/386_dynarec.c | 27 ++++--------- src/386_dynarec_ops.c | 4 -- src/808x.c | 21 +++++------ src/codegen_ops_jump.c | 1 - src/codegen_ops_misc.c | 1 - src/fdc.c | 1 - src/ibm.h | 1 - src/pc.c | 1 - src/pic.c | 1 - src/x86.h | 86 ++++++++++++++++-------------------------- src/x86_flags.h | 4 ++ src/x86_ops_call.h | 22 +++++------ src/x86_ops_jump.h | 8 ++-- src/x86_ops_ret.h | 5 --- src/x86seg.c | 27 +++++-------- 18 files changed, 87 insertions(+), 161 deletions(-) delete mode 100644 src/386.h diff --git a/src/386.c b/src/386.c index a0ad35f..4568199 100644 --- a/src/386.c +++ b/src/386.c @@ -2,7 +2,6 @@ #include #include #include "ibm.h" -#include "386.h" #include "x86.h" #include "x87.h" #include "mem.h" @@ -20,7 +19,10 @@ extern int codegen_flags_changed; extern int nmi_enable; -int inscounts[256]; +uint32_t use32; +int stack32; +int optype; + uint32_t oldpc2; int trap; @@ -31,7 +33,6 @@ extern int cpl_override; int has_fpu; extern int fpucount; -uint16_t rds; uint16_t ea_rseg; int is486; @@ -42,9 +43,8 @@ int cgate32; uint8_t romext[32768]; uint8_t *ram,*rom; -uint32_t rmdat32; -#define rmdat rmdat32 -#define fetchdat rmdat32 +uint32_t rmdat; + uint32_t backupregs[16]; extern int oddeven; int inttype; @@ -54,9 +54,6 @@ uint32_t oldecx; 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) { eal_r = eal_w = NULL; @@ -245,10 +242,10 @@ dontprint=0; fetchdat = fastreadl(cs + cpu_state.pc); if (!cpu_state.abrt) - { - trap = cpu_state.flags & T_FLAG; - opcode = fetchdat & 0xFF; + { + uint8_t opcode = fetchdat & 0xFF; fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; if (output == 3) { @@ -350,7 +347,6 @@ dontprint=0; addr = (temp << 2) + idt.base; cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; - 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); diff --git a/src/386.h b/src/386.h deleted file mode 100644 index 595773e..0000000 --- a/src/386.h +++ /dev/null @@ -1,13 +0,0 @@ -extern void cpu_386_flags_extract(); -extern void cpu_386_flags_rebuild(); - -void pmodeint(int num, int soft); -void loadcscall(uint16_t seg); -void loadcsjmp(uint16_t seg, uint32_t oxpc); -void pmoderetf(int is32, uint16_t off); -void pmodeiret(int is32); -void x86_int_sw(int num); -int x86_int_sw_rm(int num); - -int divl(uint32_t val); -int idivl(int32_t val); diff --git a/src/386_common.h b/src/386_common.h index fa18096..cf12239 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -239,7 +239,4 @@ static inline void seteaq(uint64_t v) #define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 -#define rmdat rmdat32 -#define fetchdat rmdat32 - void x86_int(int num); diff --git a/src/386_dynarec.c b/src/386_dynarec.c index f6c5572..43388fc 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -2,7 +2,6 @@ #include #include #include "ibm.h" -#include "386.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -32,7 +31,6 @@ int cpu_block_end = 0; int nmi_enable = 1; -int inscounts[256]; uint32_t oldpc2; int trap; @@ -43,7 +41,6 @@ int cpl_override=0; int has_fpu; int fpucount=0; -uint16_t rds; uint16_t ea_rseg; int is486; @@ -53,7 +50,6 @@ int cgate32; uint8_t romext[32768]; uint8_t *ram,*rom; -uint32_t rmdat32; uint32_t backupregs[16]; int oddeven=0; int inttype; @@ -61,11 +57,6 @@ int inttype; uint32_t oldecx; -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) { eal_r = eal_w = NULL; @@ -231,7 +222,6 @@ void x86_int(int num) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; - oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } @@ -278,7 +268,6 @@ void x86_int_sw(int num) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; - oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); cycles -= timing_int_rm; @@ -311,7 +300,6 @@ int x86_int_sw_rm(int num) cpu_state.flags &= ~T_FLAG; cpu_state.pc = new_pc; loadcs(new_cs); - oxpc=cpu_state.pc; cycles -= timing_int_rm; trap = 0; @@ -548,9 +536,9 @@ void exec386_dynarec(int cycs) if (!cpu_state.abrt) { - trap = cpu_state.flags & T_FLAG; - opcode = fetchdat & 0xFF; + uint8_t opcode = fetchdat & 0xFF; fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; // 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]); @@ -685,9 +673,10 @@ void exec386_dynarec(int cycs) if (!cpu_state.abrt) { - trap = cpu_state.flags & T_FLAG; - opcode = fetchdat & 0xFF; + uint8_t opcode = fetchdat & 0xFF; fetchdat >>= 8; + + trap = cpu_state.flags & T_FLAG; // 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); @@ -757,10 +746,11 @@ void exec386_dynarec(int cycs) if (!cpu_state.abrt) { - trap = cpu_state.flags & T_FLAG; - opcode = fetchdat & 0xFF; + uint8_t opcode = fetchdat & 0xFF; fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + // 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); @@ -885,7 +875,6 @@ void exec386_dynarec(int cycs) addr=temp<<2; cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; - oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); } diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index 342e138..1b77f71 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -1,6 +1,5 @@ #include "ibm.h" #include "cpu.h" -#include "386.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" @@ -15,9 +14,6 @@ #include "386_common.h" -extern uint16_t *mod1add[2][8]; -extern uint32_t *mod1seg[8]; - static inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; diff --git a/src/808x.c b/src/808x.c index 1ea2091..fa83679 100644 --- a/src/808x.c +++ b/src/808x.c @@ -38,6 +38,8 @@ int nopageerrors=0; void FETCHCOMPLETE(); +#define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) + #undef readmemb #undef readmemw uint8_t readmemb(uint32_t a) @@ -91,9 +93,8 @@ void writememl(uint32_t s, uint32_t a, uint32_t v) int oldcpl; int tempc; -uint8_t opcode; uint16_t pc2,pc3; -int noint=0; +static int noint=0; int output=0; @@ -330,9 +331,9 @@ reg = If mod=11, (depending on data size, 16 bits/8 bits, 32 bits=extend 16 bit */ uint32_t easeg; -int rmdat; +uint32_t rmdat; -uint16_t zero=0; +static uint16_t zero=0; uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; @@ -429,7 +430,7 @@ static inline void seteaw(uint16_t val) /*Flags*/ uint8_t znptable8[256]; -uint16_t znptable16[65536]; +static uint16_t znptable16[65536]; void makeznptable() { @@ -649,7 +650,6 @@ void resetx86() EAX = 0; ESP=0; mmu_perm=4; - memset(inscounts, 0, sizeof(inscounts)); x86seg_reset(); codegen_reset(); x86_was_reset = 1; @@ -1112,10 +1112,9 @@ void rep(int fv) } -int inhlt=0; -uint16_t lastpc,lastcs; +static int inhlt=0; int firstrepcycle; -int skipnextprint=0; +static int skipnextprint=0; int instime=0; //#if 0 @@ -1136,6 +1135,8 @@ void execx86(int cycs) // return; while (cycles>0) { + uint8_t opcode; + // old83=old82; // old82=old8; // if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; } @@ -2450,8 +2451,6 @@ void execx86(int cycs) cycles-=72; break; case 0xCD: /*INT*/ - lastpc=cpu_state.pc; - lastcs=CS; temp=FETCH(); if (cpu_state.ssegs) ss=oldss; diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c index d559881..c2c7eb6 100644 --- a/src/codegen_ops_jump.c +++ b/src/codegen_ops_jump.c @@ -2,7 +2,6 @@ #include "x86.h" #include "386_common.h" -#include "386.h" #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 8afb20a..2db4c32 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -3,7 +3,6 @@ #include "x86.h" #include "x86_flags.h" #include "386_common.h" -#include "386.h" #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" diff --git a/src/fdc.c b/src/fdc.c index 883cf01..f958bd3 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -70,7 +70,6 @@ typedef struct FDC static FDC fdc; void fdc_callback(); -int timetolive; //#define SECTORS 9 int lastbyte=0; uint8_t disc_3f7; diff --git a/src/ibm.h b/src/ibm.h index f9974be..9b3a07a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -276,7 +276,6 @@ uint32_t dr[8]; //#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL)) extern int cycles_lost; extern int is486; -extern uint8_t opcode; extern int insc; extern int fpucount; extern float mips,flops; diff --git a/src/pc.c b/src/pc.c index d3fd112..d574087 100644 --- a/src/pc.c +++ b/src/pc.c @@ -81,7 +81,6 @@ void fullspeed(); int framecount,fps; -int output; int atfullspeed; void saveconfig(char *fn); diff --git a/src/pic.c b/src/pic.c index b1110a4..a7636ef 100644 --- a/src/pic.c +++ b/src/pic.c @@ -4,7 +4,6 @@ #include "pit.h" #include "video.h" -int output; int intclear; int keywaiting=0; int pic_intpending; diff --git a/src/x86.h b/src/x86.h index 5a76ba9..5f0be4d 100644 --- a/src/x86.h +++ b/src/x86.h @@ -1,22 +1,30 @@ -extern uint32_t rmdat32; -int oldcpl; +extern uint32_t rmdat; +#define fetchdat rmdat + +extern uint32_t easeg; + +extern int oldcpl; extern int nmi_enable; -int tempc; -int output; -int firstrepcycle; +extern int output; +extern int timetolive; -uint32_t easeg,ealimit,ealimitw; +extern uint8_t znptable8[256]; -int skipnextprint; -int inhlt; +extern uint32_t use32; +extern int stack32; + +extern uint16_t *mod1add[2][8]; +extern uint32_t *mod1seg[8]; + +extern int cgate32; + +extern uint32_t *eal_r, *eal_w; + +extern int x86_was_reset; -uint8_t opcode; -int noint; -uint16_t lastcs,lastpc; -int timetolive,keyboardtimer; #define setznp168 setznp16 @@ -29,12 +37,6 @@ int timetolive,keyboardtimer; #define setr16(r,v) cpu_state.regs[r].w=v #define setr32(r,v) cpu_state.regs[r].l=v -uint8_t znptable8[256]; -uint16_t znptable16[65536]; - -int use32; -int stack32; - #define fetchea() { rmdat=readmemb(cs+pc); pc++; \ reg=(rmdat>>3)&7; \ mod=(rmdat>>6)&3; \ @@ -42,34 +44,12 @@ int stack32; if (mod!=3) fetcheal(); } -int optype; +extern int optype; #define JMP 1 #define CALL 2 #define IRET 3 #define OPTYPE_INT 4 -uint32_t oxpc; - -extern uint16_t *mod1add[2][8]; -extern uint32_t *mod1seg[8]; - - -#define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) - -extern int cgate32; - - -extern uint32_t *eal_r, *eal_w; - - -extern uint32_t flags_zn; -extern uint8_t flags_p; -#define FLAG_N (flags_zn>>31) -#define FLAG_Z (flags_zn) -#define FLAG_P (znptable8[flags_p]&P_FLAG) - -extern int gpf; - enum { @@ -86,22 +66,14 @@ extern uint32_t abrt_error; void x86_doabrt(int x86_abrt); -extern uint8_t opcode2; - -extern uint16_t rds; -extern uint32_t rmdat32; - -extern int inscounts[256]; +extern int codegen_flat_ds; +extern int codegen_flat_ss; void x86illegal(); void x86seg_reset(); void x86gpf(char *s, uint16_t error); -extern uint16_t zero; - -extern int x86_was_reset; - void resetx86(); void softresetx86(); void refreshread(); @@ -111,5 +83,13 @@ void execx86(int cycs); void exec386(int cycs); void exec386_dynarec(int cycs); -extern int codegen_flat_ds; -extern int codegen_flat_ss; +void pmodeint(int num, int soft); +void loadcscall(uint16_t seg, uint32_t old_pc); +void loadcsjmp(uint16_t seg, uint32_t old_pc); +void pmoderetf(int is32, uint16_t off); +void pmodeiret(int is32); +void x86_int_sw(int num); +int x86_int_sw_rm(int num); + +int divl(uint32_t val); +int idivl(int32_t val); diff --git a/src/x86_flags.h b/src/x86_flags.h index 70d8965..4332fad 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -1,3 +1,5 @@ +extern int tempc; + enum { FLAGS_UNKNOWN, @@ -553,3 +555,5 @@ static inline void setsbc32(uint32_t a, uint32_t b) cpu_state.flags_op = FLAGS_SBC32; } +extern void cpu_386_flags_extract(); +extern void cpu_386_flags_rebuild(); diff --git a/src/x86_ops_call.h b/src/x86_ops_call.h index aa126c6..4c2e117 100644 --- a/src/x86_ops_call.h +++ b/src/x86_ops_call.h @@ -1,11 +1,10 @@ #define CALL_FAR_w(new_seg, new_pc) \ old_cs = CS; \ old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ cpu_state.pc = new_pc; \ optype = CALL; \ cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ + if (msw & 1) loadcscall(new_seg, old_pc); \ else \ { \ loadcs(new_seg); \ @@ -30,11 +29,10 @@ #define CALL_FAR_l(new_seg, new_pc) \ old_cs = CS; \ old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ cpu_state.pc = new_pc; \ optype = CALL; \ cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ + if (msw & 1) loadcscall(new_seg, old_pc); \ else \ { \ loadcs(new_seg); \ @@ -158,11 +156,11 @@ static int opFF_w_a16(uint32_t fetchdat) case 0x28: /*JMP far*/ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - oxpc = cpu_state.pc; + old_pc = cpu_state.pc; new_pc = readmemw(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0); PREFETCH_FLUSH(); @@ -249,11 +247,11 @@ static int opFF_w_a32(uint32_t fetchdat) case 0x28: /*JMP far*/ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - oxpc = cpu_state.pc; + old_pc = cpu_state.pc; new_pc = readmemw(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1); PREFETCH_FLUSH(); @@ -341,11 +339,11 @@ static int opFF_l_a16(uint32_t fetchdat) case 0x28: /*JMP far*/ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - oxpc = cpu_state.pc; + old_pc = cpu_state.pc; new_pc = readmeml(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0); PREFETCH_FLUSH(); @@ -432,11 +430,11 @@ static int opFF_l_a32(uint32_t fetchdat) case 0x28: /*JMP far*/ if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - oxpc = cpu_state.pc; + old_pc = cpu_state.pc; new_pc = readmeml(easeg, cpu_state.eaaddr); new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; cpu_state.pc = new_pc; - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; CPU_BLOCK_END(); PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); PREFETCH_FLUSH(); diff --git a/src/x86_ops_jump.h b/src/x86_ops_jump.h index a7c4fd5..94cad2d 100644 --- a/src/x86_ops_jump.h +++ b/src/x86_ops_jump.h @@ -270,9 +270,9 @@ 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; + uint32_t old_pc = cpu_state.pc; cpu_state.pc = addr; - loadcsjmp(seg, oxpc); + loadcsjmp(seg, old_pc); CPU_BLOCK_END(); PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); @@ -282,9 +282,9 @@ 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; + uint32_t old_pc = cpu_state.pc; cpu_state.pc = addr; - loadcsjmp(seg, oxpc); + loadcsjmp(seg, old_pc); CPU_BLOCK_END(); PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); diff --git a/src/x86_ops_ret.h b/src/x86_ops_ret.h index b69180c..70ac327 100644 --- a/src/x86_ops_ret.h +++ b/src/x86_ops_ret.h @@ -4,7 +4,6 @@ pmoderetf(0, stack_offset); \ return 1; \ } \ - oxpc = cpu_state.pc; \ if (stack32) \ { \ cpu_state.pc = readmemw(ss, ESP); \ @@ -26,7 +25,6 @@ pmoderetf(1, stack_offset); \ return 1; \ } \ - oxpc = cpu_state.pc; \ if (stack32) \ { \ cpu_state.pc = readmeml(ss, ESP); \ @@ -108,7 +106,6 @@ static int opIRET_286(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -184,7 +181,6 @@ static int opIRET(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; if (stack32) { cpu_state.pc = readmemw(ss, ESP); @@ -230,7 +226,6 @@ static int opIRETD(uint32_t fetchdat) else { uint16_t new_cs; - oxpc = cpu_state.pc; if (stack32) { cpu_state.pc = readmeml(ss, ESP); diff --git a/src/x86seg.c b/src/x86seg.c index 7876ae0..bed02ad 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -5,7 +5,7 @@ #include "ibm.h" #include "mem.h" #include "x86.h" -#include "386.h" +#include "x86_flags.h" #include "386_common.h" #include "cpu.h" #include "config.h" @@ -32,8 +32,6 @@ int intgatesize; void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); void taskswitch386(uint16_t seg, uint16_t *segdat); -int output; - /*NOT PRESENT is INT 0B GPF is INT 0D*/ @@ -60,8 +58,6 @@ void x86abort(const char *format, ...) exit(-1); } -uint8_t opcode2; - static void seg_reset(x86seg *s) { s->access = (0 << 5) | 2; @@ -129,7 +125,6 @@ void x86_doabrt(int x86_abrt) cpu_state.flags &= ~I_FLAG; cpu_state.flags &= ~T_FLAG; - oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); return; @@ -163,8 +158,6 @@ void x86_doabrt(int x86_abrt) SP-=4; } } -// ingpf = 0; -// abrt = gpf = 1; } void x86gpf(char *s, uint16_t error) { @@ -343,7 +336,7 @@ int loadseg(uint16_t seg, x86seg *s) { if (addr>=ldt.limit) { - pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n",seg,ldt.limit, opcode, opcode2, 0/*rmdat*/); + pclog("Bigger than LDT limit %04X %04X %02X\n",seg,ldt.limit, 0/*rmdat*/); // dumppic(); // dumpregs(); // exit(-1); @@ -548,7 +541,7 @@ 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); + pclog("loadcs RPL > CPL %04X %04X %i\n",segdat[2],seg,CPL); return; } if (CPL != DPL) @@ -592,7 +585,7 @@ void loadcs(uint16_t seg) switch (segdat[2]&0xF00) { default: - pclog("Bad CS %02X %02X %i special descriptor %03X %04X\n",opcode,0/*rmdat*/,optype,segdat[2]&0xF00,seg); + pclog("Bad CS %02X %i special descriptor %03X %04X\n",0/*rmdat*/,optype,segdat[2]&0xF00,seg); x86gpf(NULL,seg&~3); return; } @@ -615,7 +608,7 @@ void loadcs(uint16_t seg) } } -void loadcsjmp(uint16_t seg, uint32_t oxpc) +void loadcsjmp(uint16_t seg, uint32_t old_pc) { uint16_t segdat[4]; uint32_t addr; @@ -825,7 +818,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) case 0x100: /*286 Task gate*/ case 0x900: /*386 Task gate*/ // pclog("Task gate\n"); - cpu_state.pc=oxpc; + cpu_state.pc = old_pc; optype=JMP; cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); @@ -837,7 +830,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) return; default: - pclog("Bad JMP CS %02X %02X %i special descriptor %03X %04X\n",opcode,0/*rmdat*/,optype,segdat[2]&0xF00,seg); + pclog("Bad JMP CS %02X %i special descriptor %03X %04X\n",0/*rmdat*/,optype,segdat[2]&0xF00,seg); x86gpf(NULL,0); return; // dumpregs(); @@ -931,7 +924,7 @@ uint32_t POPL() return templ; } -void loadcscall(uint16_t seg) +void loadcscall(uint16_t seg, uint32_t old_pc) { uint16_t seg2; uint16_t segdat[4],segdat2[4],newss; @@ -1337,7 +1330,7 @@ void loadcscall(uint16_t seg) case 0x100: /*286 Task gate*/ case 0x900: /*386 Task gate*/ // pclog("Task gate\n"); - cpu_state.pc=oxpc; + cpu_state.pc = old_pc; cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); cpl_override=0; @@ -2070,7 +2063,6 @@ void pmodeiret(int is32) x86gpf(NULL,0); return; } - oxpc=cpu_state.pc; if (is32) { newpc=POPL(); @@ -2128,7 +2120,6 @@ void pmodeiret(int is32) cpl_override=0; return; } - oxpc=cpu_state.pc; flagmask=0xFFFF; if (CPL) flagmask&=~0x3000; if (IOPL Date: Thu, 7 Feb 2019 21:53:44 +0000 Subject: [PATCH 0626/1050] Second CPU sanitising pass. --- src/386.c | 73 ++----------------------------------------- src/386_common.h | 14 ++------- src/386_dynarec.c | 36 +-------------------- src/386_dynarec_ops.c | 2 -- src/808x.c | 6 +--- src/cpu.c | 2 ++ src/ibm.h | 4 --- src/pc.c | 1 - src/x86.h | 4 +++ src/x86_ops_rep.h | 2 -- 10 files changed, 13 insertions(+), 131 deletions(-) diff --git a/src/386.c b/src/386.c index 4568199..8b81393 100644 --- a/src/386.c +++ b/src/386.c @@ -12,53 +12,25 @@ #include "nmi.h" #include "386_common.h" +#include "codegen.h" +#undef CPU_BLOCK_END #define CPU_BLOCK_END() -extern int codegen_flags_changed; - -extern int nmi_enable; - uint32_t use32; int stack32; int optype; -uint32_t oldpc2; - int trap; - - -extern int cpl_override; - -int has_fpu; -extern int fpucount; -uint16_t ea_rseg; - -int is486; -int cgate32; - - - -uint8_t romext[32768]; -uint8_t *ram,*rom; - uint32_t rmdat; -uint32_t backupregs[16]; -extern int oddeven; -int inttype; - - -uint32_t oldecx; - uint32_t *eal_r, *eal_w; static inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; if (cpu_rm == 4) { uint8_t sib = rmdat >> 8; @@ -85,7 +57,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) else if ((sib & 6) == 4 && !cpu_state.ssegs) { easeg = ss; - ea_rseg = SS; cpu_state.ea_seg = &cpu_state.seg_ss; } if (((sib >> 3) & 7) != 4) @@ -99,7 +70,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) if (cpu_rm == 5 && !cpu_state.ssegs) { easeg = ss; - ea_rseg = SS; cpu_state.ea_seg = &cpu_state.seg_ss; } if (cpu_mod == 1) @@ -131,8 +101,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; - if (!cpu_mod && cpu_rm == 6) + if (!cpu_mod && cpu_rm == 6) { cpu_state.eaaddr = getword(); } @@ -154,7 +123,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat) if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { easeg = ss; - ea_rseg = SS; cpu_state.ea_seg = &cpu_state.seg_ss; } cpu_state.eaaddr &= 0xFFFF; @@ -178,19 +146,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) #define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 #define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ #define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 -extern int xout; -int oldi; - -uint32_t testr[9]; -extern int dontprint; - -#undef NOTRM -#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 0; \ - } #define OP_TABLE(name) ops_ ## name @@ -199,13 +155,6 @@ extern int dontprint; #include "x86_ops.h" -#undef NOTRM -#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\ - { \ - x86_int(6); \ - break; \ - } - void exec386(int cycs) { uint8_t temp; @@ -226,16 +175,9 @@ void exec386(int cycs) // 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;*/ -// oldpc2=oldpc; - cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; -dontprint=0; - cpu_state.ea_seg = &cpu_state.seg_ds; cpu_state.ssegs = 0; @@ -262,15 +204,6 @@ dontprint=0; flags_rebuild(); // pclog("Abort\n"); // if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,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); - if (testr[3]!=EDX) pclog("EDX corrupted %08X\n",pc); - if (testr[4]!=ESI) pclog("ESI corrupted %08X\n",pc); - if (testr[5]!=EDI) pclog("EDI corrupted %08X\n",pc); - if (testr[6]!=EBP) pclog("EBP corrupted %08X\n",pc); - if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc);*/ -/* if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/ tempi = cpu_state.abrt; cpu_state.abrt = 0; x86_doabrt(tempi); diff --git a/src/386_common.h b/src/386_common.h index cf12239..e49bdda 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -1,14 +1,9 @@ -extern uint16_t ea_rseg; - -#undef readmemb -#undef writememb - - #define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((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)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((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) writemembl((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)+(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)+(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)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v @@ -183,7 +178,6 @@ static inline uint16_t geteaw() { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].w; -// cycles-=3; if (eal_r) return *(uint16_t *)eal_r; return readmemw(easeg,cpu_state.eaaddr); @@ -193,7 +187,6 @@ static inline uint32_t geteal() { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].l; -// cycles-=3; if (eal_r) return *eal_r; return readmeml(easeg,cpu_state.eaaddr); @@ -237,6 +230,3 @@ static inline void seteaq(uint64_t v) #define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 #define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ #define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 - - -void x86_int(int num); diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 43388fc..3f9f3f8 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -31,37 +31,15 @@ int cpu_block_end = 0; int nmi_enable = 1; -uint32_t oldpc2; - -int trap; - - - int cpl_override=0; -int has_fpu; int fpucount=0; -uint16_t ea_rseg; -int is486; -int cgate32; - - -uint8_t romext[32768]; -uint8_t *ram,*rom; - -uint32_t backupregs[16]; -int oddeven=0; -int inttype; - - -uint32_t oldecx; static inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; if (cpu_rm == 4) { uint8_t sib = rmdat >> 8; @@ -88,7 +66,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) else if ((sib & 6) == 4 && !cpu_state.ssegs) { easeg = ss; - ea_rseg = SS; cpu_state.ea_seg = &cpu_state.seg_ss; } if (((sib >> 3) & 7) != 4) @@ -102,7 +79,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) if (cpu_rm == 5 && !cpu_state.ssegs) { easeg = ss; - ea_rseg = SS; cpu_state.ea_seg = &cpu_state.seg_ss; } if (cpu_mod == 1) @@ -134,8 +110,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; - if (!cpu_mod && cpu_rm == 6) + if (!cpu_mod && cpu_rm == 6) { cpu_state.eaaddr = getword(); } @@ -157,7 +132,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat) if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { easeg = ss; - ea_rseg = SS; cpu_state.ea_seg = &cpu_state.seg_ss; } cpu_state.eaaddr &= 0xFFFF; @@ -423,9 +397,6 @@ int checkio(int port) return d&(1<<(port&7)); } -int xout=0; - - #define divexcp() { \ pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ x86_int(0); \ @@ -482,11 +453,6 @@ void cpu_386_flags_rebuild() flags_rebuild(); } -int oldi; - -uint32_t testr[9]; -int dontprint=0; - #define OP_TABLE(name) ops_ ## name #define CLOCK_CYCLES(c) cycles -= (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index 1b77f71..249909f 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -18,7 +18,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; @@ -33,7 +32,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; - ea_rseg = cpu_state.ea_seg->seg; if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { uint32_t addr = easeg + cpu_state.eaaddr; diff --git a/src/808x.c b/src/808x.c index fa83679..f53b3df 100644 --- a/src/808x.c +++ b/src/808x.c @@ -40,8 +40,6 @@ void FETCHCOMPLETE(); #define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) -#undef readmemb -#undef readmemw uint8_t readmemb(uint32_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=4; @@ -479,8 +477,6 @@ void makeznptable() } int timetolive=0; -extern uint32_t oldpc2; - int indump = 0; void dumpregs() @@ -568,7 +564,7 @@ void dumpregs() else printf("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP); printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,cpu_state.flags); - printf("%04X %04X\n",cpu_state.oldpc, oldpc2); + printf("%04X\n",cpu_state.oldpc); printf("%i ins\n",ins); if (is386) printf("In %s mode\n",(msw&1)?((cpu_state.eflags&VM_FLAG)?"V86":"protected"):"real"); diff --git a/src/cpu.c b/src/cpu.c index accff09..29d4da2 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -102,6 +102,8 @@ int is386; uint64_t tsc = 0; +int is486; + int timing_rr; int timing_mr, timing_mrl; int timing_rm, timing_rml; diff --git a/src/ibm.h b/src/ibm.h index 9b3a07a..7978dc2 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -32,10 +32,6 @@ 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)+(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)+(a)) & 3))?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); uint16_t readmemwl(uint32_t addr); diff --git a/src/pc.c b/src/pc.c index d574087..f770211 100644 --- a/src/pc.c +++ b/src/pc.c @@ -913,7 +913,6 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "video_speed", video_speed); config_set_string(CFG_MACHINE, NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); config_set_int(CFG_MACHINE, NULL, "cpu_speed", cpuspeed); - config_set_int(CFG_MACHINE, NULL, "has_fpu", hasfpu); config_set_string(CFG_MACHINE, NULL, "disc_a", discfns[0]); config_set_string(CFG_MACHINE, NULL, "disc_b", discfns[1]); config_set_string(CFG_MACHINE, NULL, "hdd_controller", hdd_controller_name); diff --git a/src/x86.h b/src/x86.h index 5f0be4d..a656124 100644 --- a/src/x86.h +++ b/src/x86.h @@ -7,6 +7,8 @@ extern int oldcpl; extern int nmi_enable; +extern int trap; + extern int output; extern int timetolive; @@ -88,6 +90,8 @@ void loadcscall(uint16_t seg, uint32_t old_pc); void loadcsjmp(uint16_t seg, uint32_t old_pc); void pmoderetf(int is32, uint16_t off); void pmodeiret(int is32); + +void x86_int(int num); void x86_int_sw(int num); int x86_int_sw_rm(int num); diff --git a/src/x86_ops_rep.h b/src/x86_ops_rep.h index 4adfcb1..d19a8f2 100644 --- a/src/x86_ops_rep.h +++ b/src/x86_ops_rep.h @@ -1,5 +1,3 @@ -extern int trap; - #define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ static int opREP_INSB_ ## size(uint32_t fetchdat) \ { \ From 1b8a1e79af0c253ad41da035ed285f493b0faa9a Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 22:09:59 +0000 Subject: [PATCH 0627/1050] Move common 386+ functions and variables out of 386.c and 386_dynarec.c and into new 386_common.c. --- src/386.c | 10 -- src/386_common.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++ src/386_dynarec.c | 227 ------------------------------------------- src/Makefile.am | 2 +- 4 files changed, 243 insertions(+), 238 deletions(-) create mode 100644 src/386_common.c diff --git a/src/386.c b/src/386.c index 8b81393..48522c9 100644 --- a/src/386.c +++ b/src/386.c @@ -17,16 +17,6 @@ #undef CPU_BLOCK_END #define CPU_BLOCK_END() -uint32_t use32; -int stack32; -int optype; - -int trap; - -uint32_t rmdat; - -uint32_t *eal_r, *eal_w; - static inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; diff --git a/src/386_common.c b/src/386_common.c new file mode 100644 index 0000000..d1c9326 --- /dev/null +++ b/src/386_common.c @@ -0,0 +1,242 @@ +#include "ibm.h" +#include "x86.h" +#include "386_common.h" +#include "x86_flags.h" +#include "codegen.h" + +uint32_t use32; +int stack32; +int optype; + +int trap; + +uint32_t rmdat; + +uint32_t *eal_r, *eal_w; + +int nmi_enable = 1; + +int cpl_override=0; + +int fpucount=0; + +uint16_t cpu_cur_status = 0; + + +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) + { + pmodeint(num,0); + } + else + { + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) + { + if (idt.limit < 35) + { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + pclog("Triple fault in real mode - reset\n"); + } + else + x86_int(8); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,cpu_state.flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } + + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + cycles-=70; + CPU_BLOCK_END(); +} + +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) + { + pmodeint(num,1); + } + else + { + addr = (num << 2) + idt.base; + + if ((num << 2) + 3 > idt.limit) + { + x86_int(13); + } + else + { + if (stack32) + { + writememw(ss,ESP-2,cpu_state.flags); + writememw(ss,ESP-4,CS); + writememw(ss,ESP-6,cpu_state.pc); + ESP-=6; + } + else + { + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); + SP-=6; + } + + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + cycles -= timing_int_rm; + } + } + trap = 0; + CPU_BLOCK_END(); +} + +int x86_int_sw_rm(int num) +{ + uint32_t addr; + uint16_t new_pc, new_cs; + + flags_rebuild(); + cycles -= timing_int; + + addr = num << 2; + new_pc = readmemw(0, addr); + new_cs = readmemw(0, addr + 2); + + if (cpu_state.abrt) return 1; + + writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; } + writememw(ss,((SP-4)&0xFFFF),CS); + writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; } + SP-=6; + + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = new_pc; + loadcs(new_cs); + + cycles -= timing_int_rm; + trap = 0; + CPU_BLOCK_END(); + + return 0; +} + +void x86illegal() +{ +// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); + +// if (output) +// { +// dumpregs(); +// exit(-1); +// } + x86_int(6); +} + +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 = readmembl(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)); +} + +#define divexcp() { \ + pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ + x86_int(0); \ +} + +int divl(uint32_t val) +{ + 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); + if (quo!=(uint64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} +int idivl(int32_t val) +{ + 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); + if (quo!=(int64_t)quo32) + { + divexcp(); + return 1; + } + EDX=rem; + EAX=quo32; + return 0; +} + + +void cpu_386_flags_extract() +{ + flags_extract(); +} +void cpu_386_flags_rebuild() +{ + flags_rebuild(); +} diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 3f9f3f8..3044b7c 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -18,22 +18,12 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -uint16_t cpu_cur_status = 0; - -int cpu_reps, cpu_reps_latched; -int cpu_notreps, cpu_notreps_latched; - int inrecomp = 0; int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks; int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched; int cpu_block_end = 0; -int nmi_enable = 1; - -int cpl_override=0; - -int fpucount=0; static inline void fetch_ea_32_long(uint32_t rmdat) @@ -151,148 +141,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat) #include "x86_flags.h" -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) - { - pmodeint(num,0); - } - else - { - addr = (num << 2) + idt.base; - - if ((num << 2) + 3 > idt.limit) - { - if (idt.limit < 35) - { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - pclog("Triple fault in real mode - reset\n"); - } - else - x86_int(8); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - cycles-=70; - CPU_BLOCK_END(); -} - -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) - { - pmodeint(num,1); - } - else - { - addr = (num << 2) + idt.base; - - if ((num << 2) + 3 > idt.limit) - { - x86_int(13); - } - else - { - if (stack32) - { - writememw(ss,ESP-2,cpu_state.flags); - writememw(ss,ESP-4,CS); - writememw(ss,ESP-6,cpu_state.pc); - ESP-=6; - } - else - { - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); - SP-=6; - } - - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - cycles -= timing_int_rm; - } - } - trap = 0; - CPU_BLOCK_END(); -} - -int x86_int_sw_rm(int num) -{ - uint32_t addr; - uint16_t new_pc, new_cs; - - flags_rebuild(); - cycles -= timing_int; - - addr = num << 2; - new_pc = readmemw(0, addr); - new_cs = readmemw(0, addr + 2); - - if (cpu_state.abrt) return 1; - - writememw(ss,((SP-2)&0xFFFF),cpu_state.flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; } - writememw(ss,((SP-4)&0xFFFF),CS); - writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; } - SP-=6; - - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = new_pc; - loadcs(new_cs); - - cycles -= timing_int_rm; - trap = 0; - CPU_BLOCK_END(); - - return 0; -} - -void x86illegal() -{ -// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); - -// if (output) -// { -// dumpregs(); -// exit(-1); -// } - x86_int(6); -} /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. @@ -378,81 +226,6 @@ 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; -// 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 = readmembl(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)); -} - -#define divexcp() { \ - pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ - x86_int(0); \ -} - -int divl(uint32_t val) -{ - 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); - if (quo!=(uint64_t)quo32) - { - divexcp(); - return 1; - } - EDX=rem; - EAX=quo32; - return 0; -} -int idivl(int32_t val) -{ - 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); - if (quo!=(int64_t)quo32) - { - divexcp(); - return 1; - } - EDX=rem; - EAX=quo32; - return 0; -} - - -void cpu_386_flags_extract() -{ - flags_extract(); -} -void cpu_386_flags_rebuild() -{ - flags_rebuild(); -} - #define OP_TABLE(name) ops_ ## name #define CLOCK_CYCLES(c) cycles -= (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) diff --git a/src/Makefile.am b/src/Makefile.am index 93f8f32..040b85e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ From 5b58b202a1b04638ffb8853ff7c5a5caf026f7ef Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 7 Feb 2019 22:10:34 +0000 Subject: [PATCH 0628/1050] More CPU sanitisation. --- src/808x.c | 34 +++++++++++----------------------- src/Makefile.am | 10 +++++++++- src/ibm.h | 1 - src/mem.h | 1 - src/pc.c | 4 ---- 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/808x.c b/src/808x.c index f53b3df..83d06b6 100644 --- a/src/808x.c +++ b/src/808x.c @@ -29,13 +29,21 @@ uint64_t xt_cpu_multi; int nmi = 0; int nmi_auto_clear = 0; -int nextcyc=0; -int cycdiff; +int oldcpl; + +int tempc; +static int noint=0; + +int output=0; +int timetolive=0; +int ins=0; + int is8086=0; +int nextcyc=0; int memcycs; -int nopageerrors=0; +static int cycdiff; void FETCHCOMPLETE(); #define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) @@ -88,15 +96,6 @@ void writememl(uint32_t s, uint32_t a, uint32_t v) } -int oldcpl; - -int tempc; -uint16_t pc2,pc3; -static int noint=0; - -int output=0; - -int ins=0; //#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) int fetchcycles=0,memcycs,fetchclocks; @@ -475,7 +474,6 @@ void makeznptable() // makemod1table(); } -int timetolive=0; int indump = 0; @@ -492,7 +490,6 @@ void dumpregs() // savenvr(); // return; chdir(logs_path); - nopageerrors=1; /* f=fopen("rram3.dmp","wb"); for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); fclose(f);*/ @@ -599,12 +596,10 @@ void dumpregs() indump = 0; } -int resets = 0; int x86_was_reset = 0; void resetx86() { pclog("x86 reset\n"); - resets++; ins = 0; use32=0; cpu_cur_status = 0; @@ -1109,11 +1104,8 @@ void rep(int fv) static int inhlt=0; -int firstrepcycle; static int skipnextprint=0; -int instime=0; -//#if 0 void execx86(int cycs) { uint8_t temp,temp2; @@ -1133,10 +1125,6 @@ void execx86(int cycs) { uint8_t opcode; -// old83=old82; -// old82=old8; -// 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; current_diff = 0; cycles-=nextcyc; diff --git a/src/Makefile.am b/src/Makefile.am index 040b85e..fdd7857 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,10 +124,18 @@ pcem_LDADD += wx.res endif if !HAS_OFF64T -pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell +#pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell endif if RELEASE_BUILD pcem_CFLAGS += -DRELEASE_BUILD pcem_CXXFLAGS += -DRELEASE_BUILD endif + +pcem_CFLAGS += -mtune=cortex-a53 +pcem_CXXFLAGS += -mtune=cortex-a53 +#pcem_LDFLAGS = -flto -O3 -mtune=cortex-a15 + +# pcem_CFLAGS += -fprofile-use +# pcem_CXXFLAGS += -fprofile-use +# pcem_LDFLAGS = -fprofile-use diff --git a/src/ibm.h b/src/ibm.h index 7978dc2..74498ef 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -209,7 +209,6 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; extern int ins,output; -extern int cycdiff; x86seg gdt,ldt,idt,tr; x86seg _oldds; diff --git a/src/mem.h b/src/mem.h index 3bffffd..e55aece 100644 --- a/src/mem.h +++ b/src/mem.h @@ -35,7 +35,6 @@ extern uint8_t *ram,*rom; extern uint8_t romext[32768]; extern int readlnum,writelnum; extern int memspeed[11]; -extern int nopageerrors; extern uint32_t biosmask; void mem_mapping_add(mem_mapping_t *mapping, diff --git a/src/pc.c b/src/pc.c index f770211..49d58ee 100644 --- a/src/pc.c +++ b/src/pc.c @@ -561,8 +561,6 @@ void runpc() cpu_recomp_evicted_latched = cpu_recomp_evicted; cpu_recomp_reuse_latched = cpu_recomp_reuse; cpu_recomp_removed_latched = cpu_recomp_removed; - cpu_reps_latched = cpu_reps; - cpu_notreps_latched = cpu_notreps; cpu_recomp_blocks = 0; cpu_state.cpu_recomp_ins = 0; @@ -572,8 +570,6 @@ void runpc() cpu_recomp_evicted = 0; cpu_recomp_reuse = 0; cpu_recomp_removed = 0; - cpu_reps = 0; - cpu_notreps = 0; updatestatus=1; readlnum=writelnum=0; From 255495265828f4af72eb2330872327ab7c000c22 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Feb 2019 19:36:30 +0000 Subject: [PATCH 0629/1050] Remove unused checkio_perm() macro. --- src/386_common.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/386_common.h b/src/386_common.h index e49bdda..9f092bf 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -21,17 +21,6 @@ int checkio(int port); } \ } -#define checkio_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) break; \ - if (tempi) \ - { \ - x86gpf(NULL,0); \ - break; \ - } \ - } - #define SEG_CHECK_READ(seg) \ do \ { \ From 03b5a44aca8812c0b26948064510d3fa6bffc0d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Feb 2019 21:17:56 +0000 Subject: [PATCH 0630/1050] More CPU sanitisation. --- src/386_common.c | 7 ++ src/808x.c | 41 ++++----- src/cpu.c | 4 +- src/cpu.h | 2 + src/gameport.c | 1 + src/ibm.h | 214 +------------------------------------------- src/mcr.c | 1 + src/mem.h | 2 + src/nvr.c | 1 + src/pc.c | 1 - src/sound_opl.c | 1 + src/sound_pas16.c | 1 + src/x86.h | 219 ++++++++++++++++++++++++++++++++++++++++++++-- src/x86seg.c | 5 -- 14 files changed, 248 insertions(+), 252 deletions(-) diff --git a/src/386_common.c b/src/386_common.c index d1c9326..df19e14 100644 --- a/src/386_common.c +++ b/src/386_common.c @@ -4,6 +4,11 @@ #include "x86_flags.h" #include "codegen.h" +x86seg gdt, ldt, idt, tr; + +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; + uint32_t use32; int stack32; int optype; @@ -22,6 +27,8 @@ int fpucount=0; uint16_t cpu_cur_status = 0; +uint32_t pccache; +uint8_t *pccache2; void x86_int(int num) { diff --git a/src/808x.c b/src/808x.c index 83d06b6..cba4273 100644 --- a/src/808x.c +++ b/src/808x.c @@ -40,28 +40,31 @@ int ins=0; int is8086=0; -int nextcyc=0; -int memcycs; +static uint32_t oldds; +uint32_t oldss; + +static int nextcyc=0; +static int memcycs; static int cycdiff; -void FETCHCOMPLETE(); +static void FETCHCOMPLETE(); #define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) -uint8_t readmemb(uint32_t a) +static uint8_t readmemb(uint32_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=4; if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } -uint8_t readmembf(uint32_t a) +static uint8_t readmembf(uint32_t a) { if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } -uint16_t readmemw(uint32_t s, uint16_t a) +static uint16_t readmemw(uint32_t s, uint16_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086); if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s+a); @@ -77,32 +80,28 @@ void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; } cpu_rm=rmdat&7; \ if (cpu_mod!=3) fetcheal(); } -void writememb(uint32_t a, uint8_t v) +static void writememb(uint32_t a, uint8_t v) { memcycs+=4; if (writelookup2[(a)>>12]==-1) writemembl(a,v); else *(uint8_t *)(writelookup2[a >> 12] + a) = v; } -void writememw(uint32_t s, uint32_t a, uint16_t v) +static void writememw(uint32_t s, uint32_t a, uint16_t v) { memcycs+=(8>>is8086); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s+a,v); else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } -void writememl(uint32_t s, uint32_t a, uint32_t v) -{ - if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s+a,v); - else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; -} //#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) -int fetchcycles=0,memcycs,fetchclocks; +static int fetchcycles=0,fetchclocks; + +static uint8_t prefetchqueue[6]; +static uint16_t prefetchpc; +static int prefetchw=0; -uint8_t prefetchqueue[6]; -uint16_t prefetchpc; -int prefetchw=0; static inline uint8_t FETCH() { uint8_t temp; @@ -187,7 +186,7 @@ static inline void FETCHADD(int c) // if (fetchcycles>24) fetchcycles=24; } -void FETCHCOMPLETE() +static void FETCHCOMPLETE() { // pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); if (!(fetchcycles&3)) return; @@ -604,7 +603,6 @@ void resetx86() use32=0; cpu_cur_status = 0; stack32=0; - cpu_hasCX8 = 0; // i86_Reset(); // cs=0xFFFF0; msw=0; @@ -665,7 +663,6 @@ void softresetx86() cr4 = 0; cpu_state.eflags=0; cgate32=0; - cpu_hasCX8 = 0; if (AT) { loadcs(0xF000); @@ -845,7 +842,7 @@ int current_diff = 0; between the two frequencies, use fixed point arithmetic when updating TSC.*/ static uint64_t tsc_frac = 0; -void clockhardware() +static void clockhardware() { int diff = cycdiff - cycles - current_diff; @@ -864,7 +861,7 @@ static int takeint = 0; int firstrepcycle=1; -void rep(int fv) +static void rep(int fv) { uint8_t temp; int c=CX; diff --git a/src/cpu.c b/src/cpu.c index 29d4da2..3963646 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -99,11 +99,11 @@ int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; int is386; +int is486; +int CPUID; uint64_t tsc = 0; -int is486; - int timing_rr; int timing_mr, timing_mrl; int timing_rm, timing_rml; diff --git a/src/cpu.h b/src/cpu.h index 02a1340..ba22f12 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -143,6 +143,8 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv); uint8_t cyrix_read(uint16_t addr, void *priv); extern int is8086; +extern int is486; +extern int CPUID; void cpu_CPUID(); void cpu_RDMSR(); diff --git a/src/gameport.c b/src/gameport.c index fbf142a..d8eb6c4 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -4,6 +4,7 @@ #include "io.h" #include "plat-joystick.h" #include "timer.h" +#include "x86.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" diff --git a/src/ibm.h b/src/ibm.h index 74498ef..ca63e29 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -63,221 +63,9 @@ extern int readlnum,writelnum; /*Processor*/ -#define EAX cpu_state.regs[0].l -#define ECX cpu_state.regs[1].l -#define EDX cpu_state.regs[2].l -#define EBX cpu_state.regs[3].l -#define ESP cpu_state.regs[4].l -#define EBP cpu_state.regs[5].l -#define ESI cpu_state.regs[6].l -#define EDI cpu_state.regs[7].l -#define AX cpu_state.regs[0].w -#define CX cpu_state.regs[1].w -#define DX cpu_state.regs[2].w -#define BX cpu_state.regs[3].w -#define SP cpu_state.regs[4].w -#define BP cpu_state.regs[5].w -#define SI cpu_state.regs[6].w -#define DI cpu_state.regs[7].w -#define AL cpu_state.regs[0].b.l -#define AH cpu_state.regs[0].b.h -#define CL cpu_state.regs[1].b.l -#define CH cpu_state.regs[1].b.h -#define DL cpu_state.regs[2].b.l -#define DH cpu_state.regs[2].b.h -#define BL cpu_state.regs[3].b.l -#define BH cpu_state.regs[3].b.h +extern int ins, output, timetolive; -typedef union -{ - uint32_t l; - uint16_t w; - struct - { - uint8_t l,h; - } b; -} x86reg; - -typedef struct -{ - uint32_t base; - uint32_t limit; - uint8_t access; - uint16_t seg; - uint32_t limit_low, limit_high; - int checked; /*Non-zero if selector is known to be valid*/ -} x86seg; - -typedef union MMX_REG -{ - uint64_t q; - int64_t sq; - uint32_t l[2]; - int32_t sl[2]; - uint16_t w[4]; - int16_t sw[4]; - uint8_t b[8]; - int8_t sb[8]; - float f[2]; -} MMX_REG; - -struct -{ - x86reg regs[8]; - - uint8_t tag[8]; - - x86seg *ea_seg; - uint32_t eaaddr; - - int flags_op; - uint32_t flags_res; - uint32_t flags_op1, flags_op2; - - uint32_t pc; - uint32_t oldpc; - uint32_t op32; - - int TOP; - - union - { - struct - { - int8_t rm, mod, reg; - } rm_mod_reg; - uint32_t rm_mod_reg_data; - } rm_data; - - int8_t ssegs; - int8_t ismmx; - int8_t abrt; - - int _cycles; - int cpu_recomp_ins; - - uint16_t npxs, npxc; - - double ST[8]; - - uint16_t MM_w4[8]; - - MMX_REG MM[8]; - - uint32_t old_fp_control, new_fp_control; -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ - uint16_t old_fp_control2, new_fp_control2; -#endif -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ - uint32_t trunc_fp_control; -#endif - x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; - - union - { - uint32_t l; - uint16_t w; - } CR0; - - uint16_t flags, eflags; -} cpu_state; - -#define cycles cpu_state._cycles - -extern uint16_t cpu_cur_status; - -/*The flags below must match in both cpu_cur_status and block->status for a block - to be valid*/ -#define CPU_STATUS_USE32 (1 << 0) -#define CPU_STATUS_STACK32 (1 << 1) -#define CPU_STATUS_PMODE (1 << 2) -#define CPU_STATUS_V86 (1 << 3) -#define CPU_STATUS_FLAGS 0xff - -/*If the flags below are set in cpu_cur_status, they must be set in block->status. - Otherwise they are ignored*/ -#define CPU_STATUS_NOTFLATDS (1 << 8) -#define CPU_STATUS_NOTFLATSS (1 << 9) -#define CPU_STATUS_MASK 0xff00 - -#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; - -COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); - -#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) - -uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; - -extern int ins,output; - -x86seg gdt,ldt,idt,tr; -x86seg _oldds; - -uint32_t pccache; -uint8_t *pccache2; -/*Segments - - _cs,_ds,_es,_ss are the segment structures - CS,DS,ES,SS is the 16-bit data - cs,ds,es,ss are defines to the bases*/ -#define CS cpu_state.seg_cs.seg -#define DS cpu_state.seg_ds.seg -#define ES cpu_state.seg_es.seg -#define SS cpu_state.seg_ss.seg -#define FS cpu_state.seg_fs.seg -#define GS cpu_state.seg_gs.seg -#define cs cpu_state.seg_cs.base -#define ds cpu_state.seg_ds.base -#define es cpu_state.seg_es.base -#define ss cpu_state.seg_ss.base -//#define seg_fs _fs.base -#define gs cpu_state.seg_gs.base - -#define CPL ((cpu_state.seg_cs.access>>5)&3) - -int loadseg(uint16_t seg, x86seg *s); -void loadcs(uint16_t seg); - -#define cr0 cpu_state.CR0.l -#define msw cpu_state.CR0.w - -uint32_t cr2, cr3, cr4; -uint32_t dr[8]; - -#define C_FLAG 0x0001 -#define P_FLAG 0x0004 -#define A_FLAG 0x0010 -#define Z_FLAG 0x0040 -#define N_FLAG 0x0080 -#define T_FLAG 0x0100 -#define I_FLAG 0x0200 -#define D_FLAG 0x0400 -#define V_FLAG 0x0800 -#define NT_FLAG 0x4000 -#define VM_FLAG 0x0002 /*In EFLAGS*/ -#define VIF_FLAG 0x0008 /*In EFLAGS*/ -#define VIP_FLAG 0x0010 /*In EFLAGS*/ - -#define WP_FLAG 0x10000 /*In CR0*/ - -#define CR4_VME (1 << 0) -#define CR4_PVI (1 << 1) -#define CR4_PSE (1 << 4) - -#define IOPL ((cpu_state.flags >> 12) & 3) - -#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) -//#define IOPLp 1 - -//#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL)) extern int cycles_lost; -extern int is486; -extern int insc; -extern int fpucount; -extern float mips,flops; -extern int cgate16; -extern int CPUID; - -extern int cpl_override; /*Timer*/ typedef struct PIT_nr diff --git a/src/mcr.c b/src/mcr.c index 81293c2..6c7d746 100644 --- a/src/mcr.c +++ b/src/mcr.c @@ -2,6 +2,7 @@ This chip was used as part of many 386 chipsets It controls memory addressing and shadowing*/ #include "ibm.h" +#include "x86.h" int nextreg6; uint8_t mcr22; diff --git a/src/mem.h b/src/mem.h index e55aece..79d0da4 100644 --- a/src/mem.h +++ b/src/mem.h @@ -1,6 +1,8 @@ #ifndef _MEM_H_ #define _MEM_H_ +#include "x86.h" + typedef struct mem_mapping_t { struct mem_mapping_t *prev, *next; diff --git a/src/nvr.c b/src/nvr.c index edabac9..fe89377 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -11,6 +11,7 @@ #include "model.h" #include "nmi.h" #include "t1000.h" +#include "x86.h" int oldromset; int nvrmask=63; diff --git a/src/pc.c b/src/pc.c index 49d58ee..a259bc9 100644 --- a/src/pc.c +++ b/src/pc.c @@ -66,7 +66,6 @@ int start_in_fullscreen = 0; static int override_drive_a = 0, override_drive_b = 0; -int CPUID; int vid_resize, vid_api; int cycles_lost = 0; diff --git a/src/sound_opl.c b/src/sound_opl.c index 33f6fd9..368a1d8 100644 --- a/src/sound_opl.c +++ b/src/sound_opl.c @@ -5,6 +5,7 @@ #include "sound.h" #include "sound_opl.h" #include "sound_dbopl.h" +#include "x86.h" /*Interfaces between PCem and the actual OPL emulator*/ diff --git a/src/sound_pas16.c b/src/sound_pas16.c index 7f44fe7..d55b921 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -12,6 +12,7 @@ #include "sound_pas16.h" #include "sound_sb_dsp.h" #include "timer.h" +#include "x86.h" /* Original PAS uses 2 x OPL2 diff --git a/src/x86.h b/src/x86.h index a656124..a9365c0 100644 --- a/src/x86.h +++ b/src/x86.h @@ -1,32 +1,226 @@ +#ifndef _X86_H_ +#define _X86_H_ + +#define EAX cpu_state.regs[0].l +#define ECX cpu_state.regs[1].l +#define EDX cpu_state.regs[2].l +#define EBX cpu_state.regs[3].l +#define ESP cpu_state.regs[4].l +#define EBP cpu_state.regs[5].l +#define ESI cpu_state.regs[6].l +#define EDI cpu_state.regs[7].l +#define AX cpu_state.regs[0].w +#define CX cpu_state.regs[1].w +#define DX cpu_state.regs[2].w +#define BX cpu_state.regs[3].w +#define SP cpu_state.regs[4].w +#define BP cpu_state.regs[5].w +#define SI cpu_state.regs[6].w +#define DI cpu_state.regs[7].w +#define AL cpu_state.regs[0].b.l +#define AH cpu_state.regs[0].b.h +#define CL cpu_state.regs[1].b.l +#define CH cpu_state.regs[1].b.h +#define DL cpu_state.regs[2].b.l +#define DH cpu_state.regs[2].b.h +#define BL cpu_state.regs[3].b.l +#define BH cpu_state.regs[3].b.h + +typedef union +{ + uint32_t l; + uint16_t w; + struct + { + uint8_t l,h; + } b; +} x86reg; + +typedef struct +{ + uint32_t base; + uint32_t limit; + uint8_t access; + uint16_t seg; + uint32_t limit_low, limit_high; + int checked; /*Non-zero if selector is known to be valid*/ +} x86seg; + +typedef union MMX_REG +{ + uint64_t q; + int64_t sq; + uint32_t l[2]; + int32_t sl[2]; + uint16_t w[4]; + int16_t sw[4]; + uint8_t b[8]; + int8_t sb[8]; + float f[2]; +} MMX_REG; + +struct +{ + x86reg regs[8]; + + uint8_t tag[8]; + + x86seg *ea_seg; + uint32_t eaaddr; + + int flags_op; + uint32_t flags_res; + uint32_t flags_op1, flags_op2; + + uint32_t pc; + uint32_t oldpc; + uint32_t op32; + + int TOP; + + union + { + struct + { + int8_t rm, mod, reg; + } rm_mod_reg; + uint32_t rm_mod_reg_data; + } rm_data; + + int8_t ssegs; + int8_t ismmx; + int8_t abrt; + + int _cycles; + int cpu_recomp_ins; + + uint16_t npxs, npxc; + + double ST[8]; + + uint16_t MM_w4[8]; + + MMX_REG MM[8]; + + uint32_t old_fp_control, new_fp_control; +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ + uint16_t old_fp_control2, new_fp_control2; +#endif +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ + uint32_t trunc_fp_control; +#endif + x86seg seg_cs,seg_ds,seg_es,seg_ss,seg_fs,seg_gs; + + union + { + uint32_t l; + uint16_t w; + } CR0; + + uint16_t flags, eflags; +} cpu_state; + +#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) + +#define cycles cpu_state._cycles + +#define cr0 cpu_state.CR0.l +#define msw cpu_state.CR0.w + +/*Segments - + _cs,_ds,_es,_ss are the segment structures + CS,DS,ES,SS is the 16-bit data + cs,ds,es,ss are defines to the bases*/ +#define CS cpu_state.seg_cs.seg +#define DS cpu_state.seg_ds.seg +#define ES cpu_state.seg_es.seg +#define SS cpu_state.seg_ss.seg +#define FS cpu_state.seg_fs.seg +#define GS cpu_state.seg_gs.seg +#define cs cpu_state.seg_cs.base +#define ds cpu_state.seg_ds.base +#define es cpu_state.seg_es.base +#define ss cpu_state.seg_ss.base +//#define seg_fs _fs.base +#define gs cpu_state.seg_gs.base + +#define CPL ((cpu_state.seg_cs.access>>5)&3) + +#define C_FLAG 0x0001 +#define P_FLAG 0x0004 +#define A_FLAG 0x0010 +#define Z_FLAG 0x0040 +#define N_FLAG 0x0080 +#define T_FLAG 0x0100 +#define I_FLAG 0x0200 +#define D_FLAG 0x0400 +#define V_FLAG 0x0800 +#define NT_FLAG 0x4000 +#define VM_FLAG 0x0002 /*In EFLAGS*/ +#define VIF_FLAG 0x0008 /*In EFLAGS*/ +#define VIP_FLAG 0x0010 /*In EFLAGS*/ + +#define WP_FLAG 0x10000 /*In CR0*/ + +#define CR4_VME (1 << 0) +#define CR4_PVI (1 << 1) +#define CR4_PSE (1 << 4) + +#define IOPL ((cpu_state.flags >> 12) & 3) + +#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) + +extern x86seg gdt, ldt, idt, tr; + +extern uint32_t cr2, cr3, cr4; +extern uint32_t dr[8]; + + +extern uint16_t cpu_cur_status; + +/*The flags below must match in both cpu_cur_status and block->status for a block + to be valid*/ +#define CPU_STATUS_USE32 (1 << 0) +#define CPU_STATUS_STACK32 (1 << 1) +#define CPU_STATUS_PMODE (1 << 2) +#define CPU_STATUS_V86 (1 << 3) +#define CPU_STATUS_FLAGS 0xff + +/*If the flags below are set in cpu_cur_status, they must be set in block->status. + Otherwise they are ignored*/ +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_MASK 0xff00 + + extern uint32_t rmdat; #define fetchdat rmdat extern uint32_t easeg; +extern uint32_t *eal_r, *eal_w; extern int oldcpl; +extern uint32_t oldss; extern int nmi_enable; extern int trap; -extern int output; -extern int timetolive; - -extern uint8_t znptable8[256]; - extern uint32_t use32; extern int stack32; +extern uint8_t znptable8[256]; extern uint16_t *mod1add[2][8]; extern uint32_t *mod1seg[8]; -extern int cgate32; - -extern uint32_t *eal_r, *eal_w; +extern int cgate16, cgate32; +extern int cpl_override; extern int x86_was_reset; - +extern int insc; +extern int fpucount; +extern float mips,flops; #define setznp168 setznp16 @@ -71,6 +265,9 @@ void x86_doabrt(int x86_abrt); extern int codegen_flat_ds; extern int codegen_flat_ss; +extern uint32_t pccache; +extern uint8_t *pccache2; + void x86illegal(); void x86seg_reset(); @@ -86,6 +283,8 @@ void exec386(int cycs); void exec386_dynarec(int cycs); void pmodeint(int num, int soft); +int loadseg(uint16_t seg, x86seg *s); +void loadcs(uint16_t seg); void loadcscall(uint16_t seg, uint32_t old_pc); void loadcsjmp(uint16_t seg, uint32_t old_pc); void pmoderetf(int is32, uint16_t off); @@ -97,3 +296,5 @@ int x86_int_sw_rm(int num); int divl(uint32_t val); int idivl(int32_t val); + +#endif diff --git a/src/x86seg.c b/src/x86seg.c index bed02ad..21a3778 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -1653,11 +1653,6 @@ void pmoderetf(int is32, uint16_t off) } } -void restore_stack() -{ - ss=oldss; cpu_state.seg_ss.limit=oldsslimit; -} - void pmodeint(int num, int soft) { uint16_t segdat[4],segdat2[4],segdat3[4]; From ce4436054d54fadcf5419e77aab6f37a28d417f9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Feb 2019 21:22:53 +0000 Subject: [PATCH 0631/1050] Replace cpu_has* flags with single cpu_features variable and cpu_has_feature() getter. --- src/codegen_timing_pentium.c | 10 ++-- src/cpu.c | 90 ++++++++++-------------------------- src/cpu.h | 20 +++++--- src/x86_ops_3dnow.h | 2 +- src/x86_ops_misc.h | 4 +- src/x86_ops_mmx.h | 4 +- src/x86_ops_mov_ctrl.h | 8 ++-- src/x86_ops_msr.h | 2 +- 8 files changed, 53 insertions(+), 87 deletions(-) diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index f21a70f..9690087 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -815,7 +815,7 @@ static inline int COUNT(uint64_t timings, uint64_t deps, int op_32) case CYCLES_RMW: return 3; case CYCLES_BRANCH: - return cpu_hasMMX ? 1 : 2; + return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2; } fatal("Illegal COUNT %016llx\n", timings); @@ -949,13 +949,13 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) last_prefix = prefix; return; } - if (cpu_hasMMX && prefix == 0x0f) + if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) { /*On Pentium MMX 0fh prefix is 'free'*/ last_prefix = prefix; return; } - if (cpu_hasMMX && (prefix == 0x66 || prefix == 0x67)) + if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67)) { /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ decode_delay_offset += 2; @@ -1239,7 +1239,7 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, else has_displacement = 0; - if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) + if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || 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; @@ -1292,7 +1292,7 @@ nopair: else has_displacement = 0; - if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) + if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) { /*Instruction might pair with next*/ u_pipe_full = 1; diff --git a/src/cpu.c b/src/cpu.c index 3963646..6e45f04 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -7,6 +7,8 @@ #include "pci.h" #include "codegen.h" +uint32_t cpu_features; + static int cpu_turbo_speed, cpu_nonturbo_speed; static int cpu_turbo = 1; @@ -82,12 +84,6 @@ int cpu_multi; int cpu_iscyrix; int cpu_16bitbus; int cpu_busspeed; -int cpu_hasrdtsc; -int cpu_hasMMX, cpu_hasMSR; -int cpu_hasCR4; -int cpu_hasCX8; -int cpu_hasVME; -int cpu_has3DNOW; int cpu_use_dynarec; int cpu_cyrix_alignment; @@ -580,12 +576,6 @@ void cpu_set() if (cpu_s->multi) cpu_busspeed = cpu_s->rspeed / cpu_s->multi; cpu_multi = cpu_s->multi; - cpu_hasrdtsc = 0; - cpu_hasMMX = 0; - cpu_hasMSR = 0; - cpu_hasCR4 = 0; - cpu_hasCX8 = 0; - cpu_has3DNOW = 0; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); @@ -885,8 +875,7 @@ void cpu_set() break; case CPU_iDX4: - cpu_hasCR4 = 1; - cpu_hasVME = 1; + cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; case CPU_i486SX: case CPU_i486DX: @@ -1032,10 +1021,8 @@ void cpu_set() timing_mml = 3; timing_bt = 3-1; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; msr.fcr = (1 << 8) | (1 << 16); - cpu_hasMMX = cpu_hasMSR = 1; - cpu_hasCR4 = 1; cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; /*unknown*/ timing_int_rm = 26; @@ -1072,10 +1059,8 @@ void cpu_set() timing_mml = 3; timing_bt = 3-1; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_hasMMX = cpu_hasMSR = cpu_has3DNOW = 1; - cpu_hasCR4 = 1; cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; /*unknown*/ timing_int_rm = 26; @@ -1132,12 +1117,8 @@ void cpu_set() timing_jmp_pm = 3; timing_jmp_pm_gate = 18; timing_misaligned = 3; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1173,12 +1154,8 @@ void cpu_set() timing_jmp_pm = 3; timing_jmp_pm_gate = 18; timing_misaligned = 3; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1214,11 +1191,8 @@ void cpu_set() timing_jmp_pm_gate = 14; timing_misaligned = 2; cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 0; - cpu_hasCR4 = 0; codegen_timing_set(&codegen_timing_686); CPUID = 0; /*Disabled on powerup by default*/ break; @@ -1254,11 +1228,8 @@ void cpu_set() timing_jmp_pm_gate = 14; timing_misaligned = 2; cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 0; - cpu_hasCR4 = 0; codegen_timing_set(&codegen_timing_686); ccr4 = 0x80; break; @@ -1275,11 +1246,8 @@ void cpu_set() timing_mml = 2; timing_bt = 5-1; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 0; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; codegen_timing_set(&codegen_timing_686); break; @@ -1328,11 +1296,8 @@ void cpu_set() timing_jmp_pm_gate = 14; timing_misaligned = 2; cpu_cyrix_alignment = 1; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; codegen_timing_set(&codegen_timing_686); ccr4 = 0x80; @@ -1369,12 +1334,8 @@ void cpu_set() timing_jmp_pm = 3; timing_jmp_pm_gate = 18; timing_misaligned = 3; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; codegen_timing_set(&codegen_timing_k6); break; @@ -1413,12 +1374,8 @@ void cpu_set() timing_jmp_pm = 3; timing_jmp_pm_gate = 18; timing_misaligned = 3; - cpu_hasrdtsc = 1; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_hasMMX = 1; - cpu_hasMSR = 1; - cpu_hasCR4 = 1; - cpu_hasVME = 1; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; codegen_timing_set(&codegen_timing_k6); break; @@ -1525,7 +1482,7 @@ void cpu_CPUID() EAX = 0x540; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_hasCX8) + if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) EDX |= CPUID_MMX; @@ -1556,7 +1513,7 @@ void cpu_CPUID() EAX = 0x580; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_hasCX8) + if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) EDX |= CPUID_MMX; @@ -1567,11 +1524,11 @@ void cpu_CPUID() case 0x80000001: EAX = 0x580; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_hasCX8) + if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; if (msr.fcr & (1 << 9)) EDX |= CPUID_MMX; - if (cpu_has3DNOW) + if (cpu_has_feature(CPU_FEATURE_3DNOW)) EDX |= CPUID_3DNOW; break; @@ -2021,15 +1978,18 @@ void cpu_WRMSR() break; case 0x107: msr.fcr = EAX; - cpu_hasMMX = EAX & (1 << 9); + if (EAX & (1 << 9)) + cpu_features |= CPU_FEATURE_MMX; + else + cpu_features &= ~CPU_FEATURE_MMX; if (EAX & (1 << 1)) - cpu_hasCX8 = 1; + cpu_features |= CPU_FEATURE_CX8; else - cpu_hasCX8 = 0; + cpu_features &= ~CPU_FEATURE_CX8; if ((EAX & (1 << 20)) && models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) - cpu_has3DNOW = 1; + cpu_features |= CPU_FEATURE_3DNOW; else - cpu_has3DNOW = 0; + cpu_features &= ~CPU_FEATURE_3DNOW; if (EAX & (1 << 29)) CPUID = 0; else diff --git a/src/cpu.h b/src/cpu.h index ba22f12..e3105ef 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -114,13 +114,19 @@ 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; -extern int cpu_hasMMX; -extern int cpu_hasCR4; -extern int cpu_hasVME; -extern int cpu_hasCX8; -extern int cpu_has3DNOW; +#define CPU_FEATURE_RDTSC (1 << 0) +#define CPU_FEATURE_MSR (1 << 1) +#define CPU_FEATURE_MMX (1 << 2) +#define CPU_FEATURE_CR4 (1 << 3) +#define CPU_FEATURE_VME (1 << 4) +#define CPU_FEATURE_CX8 (1 << 5) +#define CPU_FEATURE_3DNOW (1 << 6) + +extern uint32_t cpu_features; +static int cpu_has_feature(int feature) +{ + return cpu_features & feature; +} #define CR4_TSD (1 << 2) #define CR4_DE (1 << 3) diff --git a/src/x86_ops_3dnow.h b/src/x86_ops_3dnow.h index d57a3a3..304943f 100644 --- a/src/x86_ops_3dnow.h +++ b/src/x86_ops_3dnow.h @@ -19,7 +19,7 @@ static int opPREFETCH_a32(uint32_t fetchdat) static int opFEMMS(uint32_t fetchdat) { - ILLEGAL_ON(!cpu_hasMMX); + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); if (cr0 & 4) { x86_int(7); diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index ca11638..aa81a2c 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -946,7 +946,7 @@ static int opCPUID(uint32_t fetchdat) static int opRDMSR(uint32_t fetchdat) { - if (cpu_hasMSR) + if (cpu_has_feature(CPU_FEATURE_MSR)) { cpu_RDMSR(); CLOCK_CYCLES(9); @@ -959,7 +959,7 @@ static int opRDMSR(uint32_t fetchdat) static int opWRMSR(uint32_t fetchdat) { - if (cpu_hasMSR) + if (cpu_has_feature(CPU_FEATURE_MSR)) { cpu_WRMSR(); CLOCK_CYCLES(9); diff --git a/src/x86_ops_mmx.h b/src/x86_ops_mmx.h index 4f361c6..95ed658 100644 --- a/src/x86_ops_mmx.h +++ b/src/x86_ops_mmx.h @@ -17,7 +17,7 @@ } #define MMX_ENTER() \ - if (!cpu_hasMMX) \ + if (!cpu_has_feature(CPU_FEATURE_MMX)) \ { \ cpu_state.pc = cpu_state.oldpc; \ x86illegal(); \ @@ -32,7 +32,7 @@ static int opEMMS(uint32_t fetchdat) { - if (!cpu_hasMMX) + if (!cpu_has_feature(CPU_FEATURE_MMX)) { cpu_state.pc = cpu_state.oldpc; x86illegal(); diff --git a/src/x86_ops_mov_ctrl.h b/src/x86_ops_mov_ctrl.h index 190dfdc..962d1b2 100644 --- a/src/x86_ops_mov_ctrl.h +++ b/src/x86_ops_mov_ctrl.h @@ -21,7 +21,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat) cpu_state.regs[cpu_rm].l = cr3; break; case 4: - if (cpu_hasCR4) + if (cpu_has_feature(CPU_FEATURE_CR4)) { cpu_state.regs[cpu_rm].l = cr4; break; @@ -59,7 +59,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat) cpu_state.regs[cpu_rm].l = cr3; break; case 4: - if (cpu_hasCR4) + if (cpu_has_feature(CPU_FEATURE_CR4)) { cpu_state.regs[cpu_rm].l = cr4; break; @@ -144,7 +144,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) flushmmucache(); break; case 4: - if (cpu_hasCR4) + if (cpu_has_feature(CPU_FEATURE_CR4)) { cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; @@ -200,7 +200,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) flushmmucache(); break; case 4: - if (cpu_hasCR4) + if (cpu_has_feature(CPU_FEATURE_CR4)) { cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; diff --git a/src/x86_ops_msr.h b/src/x86_ops_msr.h index a3080a8..c2d3c3c 100644 --- a/src/x86_ops_msr.h +++ b/src/x86_ops_msr.h @@ -1,6 +1,6 @@ static int opRDTSC(uint32_t fetchdat) { - if (!cpu_hasrdtsc) + if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { cpu_state.pc = cpu_state.oldpc; x86illegal(); From 84622584e203bcb738c4cda97294809f9afddada Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 8 Feb 2019 21:34:02 +0000 Subject: [PATCH 0632/1050] Move CPU tables to separate file. --- src/Makefile.am | 2 +- src/cpu.c | 427 ---------------------------------------------- src/cpu.h | 2 +- src/cpu_tables.c | 430 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 432 insertions(+), 429 deletions(-) create mode 100644 src/cpu_tables.c diff --git a/src/Makefile.am b/src/Makefile.am index fdd7857..b9f82d8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ wx-resources.cpp : pc.xrc pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c \ -dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ +cpu_tables.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 \ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c neat.c nmi.c nvr.c olivetti_m24.c \ diff --git a/src/cpu.c b/src/cpu.c index 6e45f04..42cbee1 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -120,433 +120,6 @@ static struct uint64_t fcr2, fcr3; } msr; -/*Available cpuspeeds : - 0 = 16 MHz - 1 = 20 MHz - 2 = 25 MHz - 3 = 33 MHz - 4 = 40 MHz - 5 = 50 MHz - 6 = 66 MHz - 7 = 75 MHz - 8 = 80 MHz - 9 = 90 MHz - 10 = 100 MHz - 11 = 120 MHz - 12 = 133 MHz - 13 = 150 MHz - 14 = 160 MHz - 15 = 166 MHz - 16 = 180 MHz - 17 = 200 MHz -*/ - -CPU cpus_8088[] = -{ - /*8088 standard*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_pcjr[] = -{ - /*8088 PCjr*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 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, 1}, - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_8086[] = -{ - /*8086 standard*/ - {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_pc1512[] = -{ - /*8086 Amstrad*/ - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_286[] = -{ - /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_ibmat[] = -{ - /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, - {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_ibmxt286[] = -{ - /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_ps1_m2011[] = -{ - /*286*/ - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"", -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, 1}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0, 0} -}; - -CPU cpus_i386SX[] = -{ - /*i386SX*/ - {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_i386DX[] = -{ - /*i386DX*/ - {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_acer[] = -{ - /*i386SX*/ - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_Am386SX[] = -{ - /*Am386*/ - {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_Am386DX[] = -{ - /*Am386*/ - {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_486SLC[] = -{ - /*Cx486SLC*/ - {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, - {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 2*2}, - {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, - {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_486DLC[] = -{ - /*Cx486DLC*/ - {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3}, - {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4}, - {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5}, - {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 2*2}, - {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, - {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, - {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 2*4}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_i486[] = -{ - /*i486*/ - {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2}, - {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, - {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, - {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, (5*3)/2}, - {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, (5*4)/2}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_Am486[] = -{ - /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ - {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, - {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 2*5}, - {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, - {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, - {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, - {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 4*5}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_Cx486[] = -{ - /*Cx486/5x86*/ - {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, - {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 2*5}, - {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, - {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, - {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, - {"", -1, 0, 0, 0} -}; - - CPU cpus_6x86[] = - { - /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, - {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, - {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, - - /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, - {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, - - /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, - {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, - {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, - {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, - {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, - {"", -1, 0, 0, 0} - }; - - - -CPU cpus_WinChip[] = -{ - /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, (3*6)/2}, - {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*7)/2}, - {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*8)/2}, - {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*7}, - {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*8}, - {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*7)/2}, - {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2}, - {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7}, - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, (7*8)/2}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_WinChip_SS7[] = -{ - /*IDT WinChip (Super Socket 7)*/ - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24}, - {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 28}, - {"WinChip 2A/266", CPU_WINCHIP2, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28}, - {"WinChip 2A/300", CPU_WINCHIP2, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_Pentium5V[] = -{ - /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, - {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, - {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_PentiumS5[] = -{ - /*Intel Pentium (Socket 5)*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_Pentium[] = -{ - /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 4*8}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, (9*8)/2}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_K6_S7[] = -{ - /*AMD K6*/ - {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6-2/300 AFR-66", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"", -1, 0, 0, 0} -}; - -CPU cpus_K6_SS7[] = -{ - /*AMD K6*/ - {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6-2/300", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"K6-2/333", CPU_K6_2, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, - {"K6-2/350", CPU_K6_2, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 42}, - {"K6-2/366", CPU_K6_2, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 44}, - {"K6-2/380", CPU_K6_2, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 46}, - {"K6-2/400", CPU_K6_2, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, - {"K6-2/450", CPU_K6_2, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-2/475", CPU_K6_2, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, - {"K6-2/500", CPU_K6_2, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, - {"K6-2/533", CPU_K6_2, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, - {"K6-2/550", CPU_K6_2, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, - {"K6-2+/450", CPU_K6_2P, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-2+/475", CPU_K6_2P, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, - {"K6-2+/500", CPU_K6_2P, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, - {"K6-2+/533", CPU_K6_2P, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, - {"K6-2+/550", CPU_K6_2P, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, - {"K6-III/400", CPU_K6_3, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, - {"K6-III/450", CPU_K6_3, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-III+/400", CPU_K6_3P, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, - {"K6-III+/450", CPU_K6_3P, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-III+/475", CPU_K6_3P, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, - {"K6-III+/500", CPU_K6_3P, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, - {"", -1, 0, 0, 0} -}; - void cpu_set_edx() { EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset; diff --git a/src/cpu.h b/src/cpu.h index e3105ef..2e8cc4f 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -123,7 +123,7 @@ extern int cpu_cyrix_alignment; #define CPU_FEATURE_3DNOW (1 << 6) extern uint32_t cpu_features; -static int cpu_has_feature(int feature) +static inline int cpu_has_feature(int feature) { return cpu_features & feature; } diff --git a/src/cpu_tables.c b/src/cpu_tables.c new file mode 100644 index 0000000..ea5e2d1 --- /dev/null +++ b/src/cpu_tables.c @@ -0,0 +1,430 @@ +#include "ibm.h" +#include "cpu.h" + +/*Available cpuspeeds : + 0 = 16 MHz + 1 = 20 MHz + 2 = 25 MHz + 3 = 33 MHz + 4 = 40 MHz + 5 = 50 MHz + 6 = 66 MHz + 7 = 75 MHz + 8 = 80 MHz + 9 = 90 MHz + 10 = 100 MHz + 11 = 120 MHz + 12 = 133 MHz + 13 = 150 MHz + 14 = 160 MHz + 15 = 166 MHz + 16 = 180 MHz + 17 = 200 MHz +*/ + +CPU cpus_8088[] = +{ + /*8088 standard*/ + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_pcjr[] = +{ + /*8088 PCjr*/ + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 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, 1}, + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_8086[] = +{ + /*8086 standard*/ + {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_pc1512[] = +{ + /*8086 Amstrad*/ + {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_286[] = +{ + /*286*/ + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_ibmat[] = +{ + /*286*/ + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_ibmxt286[] = +{ + /*286*/ + {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_ps1_m2011[] = +{ + /*286*/ + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"", -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, 1}, + {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0, 0} +}; + +CPU cpus_i386SX[] = +{ + /*i386SX*/ + {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_i386DX[] = +{ + /*i386DX*/ + {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_acer[] = +{ + /*i386SX*/ + {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_Am386SX[] = +{ + /*Am386*/ + {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_Am386DX[] = +{ + /*Am386*/ + {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_486SLC[] = +{ + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 2*2}, + {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, + {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_486DLC[] = +{ + /*Cx486DLC*/ + {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3}, + {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4}, + {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5}, + {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 2*2}, + {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, + {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, + {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 2*4}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_i486[] = +{ + /*i486*/ + {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2}, + {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, + {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, (5*3)/2}, + {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, (5*4)/2}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_Am486[] = +{ + /*Am486/5x86*/ + {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 2*5}, + {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, + {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, + {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, + {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 4*5}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_Cx486[] = +{ + /*Cx486/5x86*/ + {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 2*5}, + {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, + {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, + {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, + {"", -1, 0, 0, 0} +}; + + CPU cpus_6x86[] = + { + /*Cyrix 6x86*/ + {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, + {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + + /*Cyrix 6x86L*/ + {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + + /*Cyrix 6x86MX*/ + {"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, + {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, + {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, + {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, + {"", -1, 0, 0, 0} + }; + + + +CPU cpus_WinChip[] = +{ + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, (3*6)/2}, + {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*7)/2}, + {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*8)/2}, + {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*7}, + {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*8}, + {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*7)/2}, + {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2}, + {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7}, + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, (7*8)/2}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_WinChip_SS7[] = +{ + /*IDT WinChip (Super Socket 7)*/ + {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 28}, + {"WinChip 2A/266", CPU_WINCHIP2, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_Pentium5V[] = +{ + /*Intel Pentium (5V, socket 4)*/ + {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, + {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_PentiumS5[] = +{ + /*Intel Pentium (Socket 5)*/ + {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, + {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, + {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, + {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_Pentium[] = +{ + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, + {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, + {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, + {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 4*8}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, (9*8)/2}, + {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_K6_S7[] = +{ + /*AMD K6*/ + {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_K6_SS7[] = +{ + /*AMD K6*/ + {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6-2/300", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/333", CPU_K6_2, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"K6-2/350", CPU_K6_2, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 42}, + {"K6-2/366", CPU_K6_2, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 44}, + {"K6-2/380", CPU_K6_2, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 46}, + {"K6-2/400", CPU_K6_2, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-2/450", CPU_K6_2, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-2/475", CPU_K6_2, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-2/500", CPU_K6_2, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6-2/533", CPU_K6_2, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, + {"K6-2/550", CPU_K6_2, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, + {"K6-2+/450", CPU_K6_2P, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-2+/475", CPU_K6_2P, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-2+/500", CPU_K6_2P, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6-2+/533", CPU_K6_2P, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, + {"K6-2+/550", CPU_K6_2P, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, + {"K6-III/400", CPU_K6_3, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-III/450", CPU_K6_3, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-III+/400", CPU_K6_3P, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-III+/450", CPU_K6_3P, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-III+/475", CPU_K6_3P, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-III+/500", CPU_K6_3P, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"", -1, 0, 0, 0} +}; + From 3f2d9ecf870e64a11c60ab49c2ee1f652734e11c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 10 Feb 2019 12:32:25 +0000 Subject: [PATCH 0633/1050] Optimise out redundant uOPs, where the output register is never read. --- src/codegen_ir.c | 5 ++ src/codegen_ir_defs.h | 69 ++++++++++++------------ src/codegen_reg.c | 119 ++++++++++++++++++++++++++++++++++++------ src/codegen_reg.h | 64 +++++++++++++++++++---- 4 files changed, 200 insertions(+), 57 deletions(-) diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 556cb8c..56d58f7 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -21,6 +21,8 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) int jump_target_at_end = -1; int c; + codegen_reg_mark_as_required(); + codegen_reg_process_dead_list(ir); block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); block_pos = 0; codegen_backend_prologue(block); @@ -45,6 +47,9 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) } } + if ((uop->type & UOP_MASK) == UOP_INVALID) + continue; + if (uop->type & UOP_TYPE_PARAMS_REGS) { codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index a69f346..74b0043 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -312,6 +312,8 @@ #define UOP_MAX 0xc6 +#define UOP_INVALID 0xff + #define UOP_MASK 0xffff typedef struct uop_t @@ -338,7 +340,7 @@ typedef struct ir_data_t int wr_pos; } ir_data_t; -static inline uop_t *uop_alloc(ir_data_t *ir) +static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) { uop_t *uop; @@ -353,7 +355,10 @@ static inline uop_t *uop_alloc(ir_data_t *ir) uop->src_reg_c = invalid_ir_reg; uop->jump_list_next = -1; - + + if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) + codegen_reg_mark_as_required(); + return uop; } @@ -366,7 +371,7 @@ static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -375,7 +380,7 @@ static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -385,7 +390,7 @@ static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -393,7 +398,7 @@ static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int ar static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg); @@ -404,86 +409,86 @@ static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); uop->imm_data = imm; } static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); uop->p = p; } static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg); - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); uop->imm_data = imm; } static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); uop->imm_data = imm; } static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); uop->src_reg_b = codegen_reg_read(src_reg_b); uop->src_reg_c = codegen_reg_read(src_reg_c); - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg); - uop->dest_reg_a = codegen_reg_write(dest_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); uop->imm_data = imm; } static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -494,7 +499,7 @@ static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -504,7 +509,7 @@ static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int sr static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -514,7 +519,7 @@ static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_re static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -525,7 +530,7 @@ static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int sr static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->imm_data = imm; @@ -533,7 +538,7 @@ static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->p = p; @@ -541,7 +546,7 @@ static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->p = p; @@ -550,7 +555,7 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -559,7 +564,7 @@ static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); @@ -569,7 +574,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) { - uop_t *uop = uop_alloc(ir); + uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index f352d0a..dda256c 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -4,8 +4,10 @@ #include "codegen_ir_defs.h" #include "codegen_reg.h" +uint16_t reg_dead_list = 0; + uint8_t reg_last_version[IREG_COUNT]; -uint8_t reg_version_refcount[IREG_COUNT][256]; +reg_version_t reg_version[IREG_COUNT][256]; ir_reg_t invalid_ir_reg = {IREG_INVALID}; @@ -175,6 +177,19 @@ struct [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE}, }; +void codegen_reg_mark_as_required() +{ + int reg; + + for (reg = 0; reg < IREG_COUNT; reg++) + { + int last_version = reg_last_version[reg]; + + if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) + reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; + } +} + static int reg_is_native_size(ir_reg_t ir_reg) { int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; @@ -220,7 +235,7 @@ void codegen_reg_reset() for (c = 0; c < IREG_COUNT; c++) { reg_last_version[c] = 0; - reg_version_refcount[c][0] = 0; + reg_version[c][0].refcount = 0; } for (c = 0; c < CODEGEN_HOST_REGS; c++) { @@ -232,6 +247,8 @@ void codegen_reg_reset() host_fp_reg_set.regs[c] = invalid_ir_reg; host_fp_reg_set.dirty[c] = 0; } + + reg_dead_list = 0; } static inline int ir_reg_is_invalid(ir_reg_t ir_reg) @@ -239,9 +256,9 @@ static inline int ir_reg_is_invalid(ir_reg_t ir_reg) return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } -static inline int ir_get_get_refcount(ir_reg_t ir_reg) +static inline int ir_get_refcount(ir_reg_t ir_reg) { - return reg_version_refcount[IREG_GET_REG(ir_reg.reg)][ir_reg.version]; + return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; } static inline host_reg_set_t *get_reg_set(ir_reg_t ir_reg) @@ -342,7 +359,7 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); void *p = ireg_data[ir_reg].p; - if (!reg_version_refcount[ir_reg][reg_set->regs[c].version] && + if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && ireg_data[ir_reg].is_volatile) return; @@ -463,10 +480,30 @@ static void alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) { if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { - if (reg_set->regs[c].version == ir_reg.version || (reg_set->regs[c].version == (ir_reg.version-1) && reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] == dest_reference)) + if (reg_set->regs[c].version == ir_reg.version) + { reg_set->locked |= (1 << c); + } else + { + /*The immediate prior version may have been + optimised out, so search backwards to find the + last valid version*/ + int prev_version = ir_reg.version-1; +// pclog("prev_version search from %i\n", prev_version); + while (prev_version >= 0) + { + reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + + if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) + { + reg_set->locked |= (1 << c); + return; + } + prev_version--; + } fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); + } return; } } @@ -513,7 +550,13 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) break; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version]) + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version <= ir_reg.version) + { + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; + break; + } + + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); } @@ -522,7 +565,7 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in /*No unused registers. Search for an unlocked register with no pending reads*/ for (c = 0; c < reg_set->nr_regs; c++) { - if (!(reg_set->locked & (1 << c)) && !ir_get_get_refcount(reg_set->regs[c])) + if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && !ir_get_refcount(reg_set->regs[c])) break; } if (c == reg_set->nr_regs) @@ -548,13 +591,13 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in // else // pclog(" already loaded %i\n", c); - reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version]--; - if (reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] == (uint8_t)-1) + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); if (host_reg_idx) *host_reg_idx = c; -// pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], host_regs[c].reg,host_regs[c].version, c); +// pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], reg_set->regs[c].reg,reg_set->regs[c].version, c); return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); } @@ -570,11 +613,11 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; parent_reg.version = ir_reg.version - 1; - reg_version_refcount[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1]++; + reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; codegen_reg_alloc_read_reg(block, parent_reg, &c); - if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version != ir_reg.version-1) + if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version-1) fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, reg_set->regs[c].reg,reg_set->regs[c].version, ir_reg.reg,ir_reg.version); @@ -591,9 +634,9 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { - if (reg_set->regs[c].version == ir_reg.version-1) + if (reg_set->regs[c].version <= ir_reg.version-1) { - if (reg_version_refcount[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version] != 0) + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); break; } @@ -682,3 +725,49 @@ void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) reg_set->dirty[c] = 0; } } + +/*Process dead register list, and optimise out register versions and uOPs where + possible*/ +void codegen_reg_process_dead_list(ir_data_t *ir) +{ + while (reg_dead_list) + { + int version = reg_dead_list & 0xff; + int reg = reg_dead_list >> 8; + reg_version_t *regv = ®_version[reg][version]; + uop_t *uop = &ir->uops[regv->parent_uop]; + + /*Barrier uOPs should be preserved*/ + if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) + { +// pclog(" codegen_process_dead_list: reg=%i version=%i uop=%i\n", reg, version, regv->parent_uop); + uop->type = UOP_INVALID; + /*Adjust refcounts on source registers. If these drop to + zero then those registers can be considered for removal*/ + if (uop->src_reg_a.reg != IREG_INVALID) + { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); + } + if (uop->src_reg_b.reg != IREG_INVALID) + { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); + } + if (uop->src_reg_c.reg != IREG_INVALID) + { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); + } + regv->flags |= REG_FLAGS_DEAD; + } + + reg_dead_list = regv->next; + } +} diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 448518e..01272bc 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -272,7 +272,36 @@ static inline int ireg_seg_limit_high(x86seg *seg) } extern uint8_t reg_last_version[IREG_COUNT]; -extern uint8_t reg_version_refcount[IREG_COUNT][256]; + +/*This version of the register must be calculated, regardless of whether it is + apparently required or not. Do not optimise out.*/ +#define REG_FLAGS_REQUIRED (1 << 0) +/*This register and the parent uOP have been optimised out.*/ +#define REG_FLAGS_DEAD (1 << 1) + +typedef struct +{ + /*Refcount of pending reads on this register version*/ + uint8_t refcount; + /*Flags*/ + uint8_t flags; + /*uOP that generated this register version*/ + uint16_t parent_uop; + /*Pointer to next register version in dead register list*/ + uint16_t next; +} reg_version_t; + +extern reg_version_t reg_version[IREG_COUNT][256]; + +/*Head of dead register list; a list of register versions that are not used and + can be optimised out*/ +extern uint16_t reg_dead_list; + +static inline void add_to_dead_list(reg_version_t *regv, int reg, int version) +{ + regv->next = reg_dead_list; + reg_dead_list = version | (reg << 8); +} typedef struct { @@ -289,37 +318,50 @@ typedef uint16_t ir_host_reg_t; static inline ir_reg_t codegen_reg_read(int reg) { ir_reg_t ireg; + reg_version_t *version; if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_read - IREG_INVALID\n"); ireg.reg = reg; ireg.version = reg_last_version[IREG_GET_REG(reg)]; - reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]++; - if (!reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]) + version = ®_version[IREG_GET_REG(ireg.reg)][ireg.version]; + version->flags = 0; + version->refcount++; + if (!version->refcount) fatal("codegen_reg_read - refcount overflow\n"); - else if (reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version] > REG_VERSION_MAX) + else if (version->refcount > REG_VERSION_MAX) CPU_BLOCK_END(); - +// pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); return ireg; } -static inline ir_reg_t codegen_reg_write(int reg) +static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) { ir_reg_t ireg; - + int last_version = reg_last_version[IREG_GET_REG(reg)]; + reg_version_t *version; + if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_write - IREG_INVALID\n"); ireg.reg = reg; - ireg.version = reg_last_version[IREG_GET_REG(reg)] + 1; + ireg.version = last_version + 1; + + if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && + !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) + add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); + reg_last_version[IREG_GET_REG(reg)]++; if (!reg_last_version[IREG_GET_REG(reg)]) fatal("codegen_reg_write - version overflow\n"); else if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) CPU_BLOCK_END(); - reg_version_refcount[IREG_GET_REG(reg)][ireg.version] = 0; - + version = ®_version[IREG_GET_REG(reg)][ireg.version]; + version->refcount = 0; + version->flags = 0; + version->parent_uop = uop_nr; +// pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); return ireg; } @@ -337,4 +379,6 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); +void codegen_reg_mark_as_required(); +void codegen_reg_process_dead_list(struct ir_data_t *ir); #endif From a73081f0bd23c82ce13ca9c2986ddb8c860ada7c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 13 Feb 2019 21:11:27 +0000 Subject: [PATCH 0634/1050] Fix ARM and ARM64 build errors. --- src/codegen_backend_arm.c | 10 +++++----- src/codegen_backend_arm64.c | 10 +++++----- src/codegen_backend_arm64_ops.c | 2 +- src/codegen_backend_arm_ops.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index fc77eba..0c1c2c8 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -77,7 +77,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) MOV R1, #0 MOV PC, LR * STR LR, [SP, -4]! - BL readmemb386l + BL readmembl LDRB R1, cpu_state.abrt LDR PC, [SP], #4 */ @@ -116,7 +116,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); if (size == 1) - host_arm_BL(block, (uintptr_t)readmemb386l); + host_arm_BL(block, (uintptr_t)readmembl); else if (size == 2) host_arm_BL(block, (uintptr_t)readmemwl); else if (size == 4) @@ -149,7 +149,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) MOV R1, #0 MOV PC, LR * STR LR, [SP, -4]! - BL readmemb386l + BL readmembl LDRB R1, cpu_state.abrt LDR PC, [SP], #4 */ @@ -192,7 +192,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) else if (size == 8) host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); if (size == 1) - host_arm_BL(block, (uintptr_t)writememb386l); + host_arm_BL(block, (uintptr_t)writemembl); else if (size == 2) host_arm_BL(block, (uintptr_t)writememwl); else if (size == 4) @@ -304,7 +304,7 @@ void codegen_backend_init() block_current = 0; block_pos = 0; block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); block->data = codeblock_allocator_get_ptr(block->head_mem_block); block_write_data = block->data; build_loadstore_routines(&codeblock[block_current]); diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 4a2885a..7497a0b 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -82,7 +82,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) MOV W1, #0 RET * STP X29, X30, [SP, #-16] - BL readmemb386l + BL readmembl LDRB R1, cpu_state.abrt LDP X29, X30, [SP, #-16] RET @@ -116,7 +116,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); if (size == 1) - host_arm64_call(block, (uintptr_t)readmemb386l); + host_arm64_call(block, (uintptr_t)readmembl); else if (size == 2) host_arm64_call(block, (uintptr_t)readmemwl); else if (size == 4) @@ -151,7 +151,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) MOV W1, #0 RET * STP X29, X30, [SP, #-16] - BL writememb386l + BL writemembl LDRB R1, cpu_state.abrt LDP X29, X30, [SP, #-16] RET @@ -189,7 +189,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) else if (size == 8) host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); if (size == 1) - host_arm64_call(block, (uintptr_t)writememb386l); + host_arm64_call(block, (uintptr_t)writemembl); else if (size == 2) host_arm64_call(block, (uintptr_t)writememwl); else if (size == 4) @@ -301,7 +301,7 @@ void codegen_backend_init() block_current = 0; block_pos = 0; block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); block->data = codeblock_allocator_get_ptr(block->head_mem_block); block_write_data = block->data; build_loadstore_routines(block); diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 0a7e24d..eaf5089 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -282,7 +282,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) static void codegen_allocate_new_block(codeblock_t *block) { /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); uint32_t offset = (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]; diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 17355cc..b6a6142 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -212,7 +212,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) static void codegen_allocate_new_block(codeblock_t *block) { /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block); + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); uint32_t offset = ((uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]) - 8; From 01e86135ab2b2c71a9f00987c0295c17dcd83bde Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 13 Feb 2019 22:12:53 +0000 Subject: [PATCH 0635/1050] Tweak FDC command timing and add register access waitstates. Fixes floppy in Windows 98 with VA-503. --- src/fdc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/fdc.c b/src/fdc.c index f958bd3..308599f 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -9,6 +9,7 @@ #include "io.h" #include "pic.h" #include "timer.h" +#include "x86.h" static int fdc_reset_stat = 0; /*FDC*/ @@ -320,6 +321,8 @@ 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); int drive; + cycles -= ISA_CYCLES(8); + switch (addr&7) { case 1: return; @@ -550,7 +553,7 @@ bad_command: // pclog("Got all params %02X\n", fdc.command); fdc.stat=0x30; discint=fdc.command&0x1F; - timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); + timer_set_delay_u64(&fdc.timer, 256 * TIMER_USEC); // fdc.drive = fdc.params[0] & 3; disc_drivesel = fdc.drive & 1; fdc_reset_stat = 0; @@ -674,6 +677,9 @@ uint8_t fdc_read(uint16_t addr, void *priv) { uint8_t temp; int drive; + + cycles -= ISA_CYCLES(8); + // /*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) { From 063ffb4eab45a70422cef0b16a03447abb6c6cc3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 14 Feb 2019 19:39:47 +0000 Subject: [PATCH 0636/1050] Update Makefile.mingw-wx-sdl2. --- src/Makefile.mingw-wx-sdl2 | 52 +++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 3bfb669..aab0c0d 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,25 +6,43 @@ WXVERSION = 31 WXINCLUDE = C:/MinGW/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ - device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o \ - i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o \ + cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ + codegen_backend.o codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ + codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o codegen_ir.o codegen_ops.o \ + codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ + codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_jump.o \ + codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ + codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ + codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ + codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ + dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o \ + fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o \ + ide_atapi.o ide_sff8038i.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ + mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ + mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ + piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ + scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ + sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ + vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ + vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ + vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ - wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ - wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ + vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o wx-main.o \ + wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ + wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ + wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o \ + wx-joystickconfig.o wx-createdisc.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 From ab124776a021ebce5e841836d06f8c456c3cbc86 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Mar 2019 14:53:26 +0000 Subject: [PATCH 0637/1050] Rework self modifying code handling. Code blocks now have a varying level of granularity in the page and dirty masks. Most blocks have 64-byte granularity, but blocks that are repeatedly modified drop to 1-byte granularity. This reduces the maximum size of the affected block significantly, but reduces recompilation due to data located too close to code. If the block is still marked as dirty, then it is recompiled without any immediate instruction parameters being baked into the recompiled code, instead being fetched from the RAM array as needed. This severely reduces recompilation rates on some SMC-heavy games, eg Duke Nukem 3D, System Shock, Screamer etc, giving a major speedup. --- src/386_common.h | 16 + src/386_dynarec.c | 34 +- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 4 +- src/codegen.c | 93 ++++-- src/codegen.h | 37 ++- src/codegen_backend.c | 420 +++++++++++++++++++++---- src/codegen_backend_arm64_uops.c | 62 ++++ src/codegen_backend_arm_uops.c | 63 ++++ src/codegen_backend_x86-64_ops.c | 55 +++- src/codegen_backend_x86-64_ops.h | 2 + src/codegen_backend_x86-64_uops.c | 59 +++- src/codegen_backend_x86_ops.c | 17 + src/codegen_backend_x86_ops.h | 2 + src/codegen_backend_x86_uops.c | 59 +++- src/codegen_ir_defs.h | 10 + src/codegen_ops_3dnow.c | 15 + src/codegen_ops_arith.c | 501 +++++++++++++++++++++++++----- src/codegen_ops_branch.c | 7 + src/codegen_ops_helpers.c | 26 ++ src/codegen_ops_helpers.h | 24 ++ src/codegen_ops_jump.c | 11 + src/codegen_ops_logic.c | 85 ++++- src/codegen_ops_misc.c | 14 +- src/codegen_ops_mmx_arith.c | 1 + src/codegen_ops_mmx_cmp.c | 1 + src/codegen_ops_mmx_loadstore.c | 6 +- src/codegen_ops_mmx_logic.c | 8 +- src/codegen_ops_mmx_pack.c | 1 + src/codegen_ops_mmx_shift.c | 6 + src/codegen_ops_mov.c | 71 ++++- src/codegen_ops_shift.c | 133 +++++++- src/codegen_ops_stack.c | 6 + src/codegen_reg.h | 2 + src/mem.c | 85 ++++- src/mem.h | 14 +- 36 files changed, 1719 insertions(+), 233 deletions(-) create mode 100644 src/codegen_ops_helpers.c diff --git a/src/386_common.h b/src/386_common.h index 9f092bf..80da16d 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -1,3 +1,6 @@ +#ifndef _386_COMMON_H_ +#define _386_COMMON_H_ + #define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((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)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) @@ -128,6 +131,17 @@ static inline uint32_t fastreadl(uint32_t a) return val; } +static inline void *get_ram_ptr(uint32_t a) +{ + if ((a >> 12) == pccache) + return &pccache2[a]; + else + { + uint8_t *t = getpccache(a); + return &t[a]; + } +} + static inline uint8_t getbyte() { cpu_state.pc++; @@ -219,3 +233,5 @@ static inline void seteaq(uint64_t v) #define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 #define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ #define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 + +#endif diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 3044b7c..2817727 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -320,8 +320,10 @@ void exec386_dynarec(int cycs) if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - - if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) { /*Walk page tree to see if we find the correct block*/ codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); @@ -339,12 +341,21 @@ void exec386_dynarec(int cycs) } } + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } if (valid_block && (block->page_mask & *block->dirty_mask)) { - codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); - page->dirty_mask[(phys_addr >> 10) & 3] = 0; + codegen_check_flush(page, page->dirty_mask, phys_addr); if (block->pc == BLOCK_PC_INVALID) valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; } if (valid_block && block->page_mask2) { @@ -355,16 +366,17 @@ 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->pc + 0x400); + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); 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 & *block->dirty_mask2) { - 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; + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); if (block->pc == BLOCK_PC_INVALID) valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; } } if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) @@ -390,7 +402,8 @@ void exec386_dynarec(int cycs) else if (valid_block && !cpu_state.abrt) { uint32_t start_pc = cpu_state.pc; - + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; + cpu_block_end = 0; x86_was_reset = 0; @@ -434,7 +447,7 @@ void exec386_dynarec(int cycs) 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) > 1000) + if ((cpu_state.pc - start_pc) >= max_block_size) CPU_BLOCK_END(); if (trap) @@ -465,6 +478,7 @@ void exec386_dynarec(int cycs) { /*Mark block but do not recompile*/ uint32_t start_pc = cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; cpu_block_end = 0; x86_was_reset = 0; @@ -505,7 +519,7 @@ void exec386_dynarec(int cycs) 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) > 1000) + if ((cpu_state.pc - start_pc) >= max_block_size) CPU_BLOCK_END(); if (trap) diff --git a/src/Makefile.am b/src/Makefile.am index b9f82d8..9b2795b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ +cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c \ cpu_tables.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index aab0c0d..435aaf5 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -3,7 +3,7 @@ CPP = g++ CC = gcc WINDRES = windres.exe WXVERSION = 31 -WXINCLUDE = C:/MinGW/include/wx/ +WXINCLUDE = e:/MinGWget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o \ @@ -11,7 +11,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer38 codegen_backend.o codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o codegen_ir.o codegen_ops.o \ codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ - codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_jump.o \ + codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o codegen_ops_jump.o \ codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ diff --git a/src/codegen.c b/src/codegen.c index 3db8d60..23ea678 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -11,6 +11,7 @@ #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_ops.h" +#include "codegen_ops_helpers.h" int has_ea; @@ -85,6 +86,7 @@ void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { + uint32_t old_pc = *op_pc; // pclog("codegen - mod=%i rm=%i reg=%i fetchdat=%08x\n", cpu_mod, cpu_rm, cpu_reg, fetchdat); if (!cpu_mod && cpu_rm == 6) { @@ -145,12 +147,16 @@ static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uin } } + codegen_mark_code_present(ir->block, cs+old_pc, (*op_pc)-old_pc); return op_ea_seg; } static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { + codeblock_t *block = ir->block; + uint32_t old_pc = (*op_pc) + 1; uint32_t new_eaaddr; + int extra_bytes = 0; if (cpu_rm == 4) { @@ -162,13 +168,23 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin case 0: if ((sib & 7) == 5) { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } + else + { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 5; + } (*op_pc) += 4; } else { uop_MOV(ir, IREG_eaaddr, sib & 7); + extra_bytes = 1; } break; case 1: @@ -176,12 +192,22 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); (*op_pc)++; + extra_bytes = 2; break; case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } + else + { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 5; + } (*op_pc) += 4; + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); break; } if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ @@ -215,29 +241,54 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin { if (!cpu_mod && cpu_rm == 5) { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - uop_MOV(ir, IREG_eaaddr, cpu_rm); - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); } else { new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); - (*op_pc) += 4; + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } + + (*op_pc) += 4; + } + else + { + uop_MOV(ir, IREG_eaaddr, cpu_rm); + if (cpu_mod) + { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) + { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); + (*op_pc)++; + extra_bytes = 1; + } + else + { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); + } + else + { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } + (*op_pc) += 4; + } } } } + + if (extra_bytes) + codegen_mark_code_present(ir->block, cs+old_pc, extra_bytes); + return op_ea_seg; } @@ -583,6 +634,7 @@ generate_call: opcode_mask = 0xff; } } + codegen_mark_code_present(block, cs+old_pc, (op_pc - old_pc) - pc_off); // pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) { @@ -654,6 +706,7 @@ generate_call: uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); uop_CALL_INSTRUCTION_FUNC(ir, op); + codegen_mark_code_present(block, cs+cpu_state.pc, 8); last_op_32 = op_32; last_op_ea_seg = op_ea_seg; diff --git a/src/codegen.h b/src/codegen.h index 1438dab..9365e44 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -73,6 +73,14 @@ extern uint8_t *block_write_data; #define CODEBLOCK_WAS_RECOMPILED 4 /*Code block is in free list and is not valid*/ #define CODEBLOCK_IN_FREE_LIST 8 +/*Code block spans two pages, page_mask2 and dirty_mask2 are valid*/ +#define CODEBLOCK_HAS_PAGE2 0x10 +/*Code block is using a byte mask for code present and dirty*/ +#define CODEBLOCK_BYTE_MASK 0x20 +/*Code block is in dirty list*/ +#define CODEBLOCK_IN_DIRTY_LIST 0x40 +/*Code block is not inlining immediate parameters, parameters must be fetched from memory*/ +#define CODEBLOCK_NO_IMMEDIATES 0x80 #define BLOCK_PC_INVALID 0xffffffff @@ -277,10 +285,33 @@ 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 4 +#define PAGE_MASK_SHIFT 6 + +void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len); + +static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) +{ + if (len == 1) + { + if (block->flags & CODEBLOCK_BYTE_MASK) + { + if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ + block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); + } + else + { + if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ + block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + } + } + else + codegen_mark_code_present_multibyte(block, start_pc, len); +} void codegen_init(); void codegen_close(); diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 4874233..0f76cbe 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -55,9 +55,22 @@ uint32_t instr_counts[256*256]; static uint16_t block_free_list; static void delete_block(codeblock_t *block); +static void delete_dirty_block(codeblock_t *block); + +/*Temporary list of code blocks that have recently been evicted. This allows for + some historical state to be kept when a block is the target of self-modifying + code. + + The size of this list is limited to DIRTY_LIST_MAX_SIZE blocks. When this is + exceeded the oldest entry will be moved to the free list.*/ +static uint16_t block_dirty_list_head, block_dirty_list_tail; +static int dirty_list_size = 0; +#define DIRTY_LIST_MAX_SIZE 64 static void block_free_list_add(codeblock_t *block) { + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_free_list_add: block=%p in dirty list\n", block); if (block_free_list) block->next = block_free_list; else @@ -67,23 +80,92 @@ static void block_free_list_add(codeblock_t *block) // pclog("block_free_list_add: %p %p\n", block, block->next); } +static void block_dirty_list_add(codeblock_t *block) +{ + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_dirty_list_add: block=%p already in dirty list\n", block); +// pclog("block_dirty_list_add: block=%i size=%i %i head=%i tail=%i\n", get_block_nr(block), dirty_list_size, dirty_list_check_size(), block_dirty_list_head, block_dirty_list_tail); + if (block_dirty_list_head != BLOCK_INVALID) + { + codeblock_t *old_head = &codeblock[block_dirty_list_head]; + + block->next = block_dirty_list_head; + block->prev = BLOCK_INVALID; + block_dirty_list_head = old_head->prev = get_block_nr(block); +// pclog(" next=%p,%i prev=%i\n", old_head, block->next, old_head->prev); + } + else + { + /*List empty*/ + block->prev = block->next = BLOCK_INVALID; + block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); + } + block->flags |= CODEBLOCK_IN_DIRTY_LIST; +// pclog(" block_dirty_list_add: %p flags = %x\n", block, block->flags); + dirty_list_size++; + if (dirty_list_size > DIRTY_LIST_MAX_SIZE) + { + /*Evict oldest block to the free list*/ + codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; + + if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); + if (!block_dirty_list_tail) + fatal("block_dirty_list_add - !block_dirty_list_tail\n"); + if (evict_block->prev == BLOCK_INVALID) + fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); + + block_dirty_list_tail = evict_block->prev; + codeblock[evict_block->prev].next = BLOCK_INVALID; + + dirty_list_size--; + evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; +// pclog(" block_dirty_list_add: %p flags = %x\n", evict_block, evict_block->flags); + delete_dirty_block(evict_block); + } + +// pclog("block_free_list_add: %p %p\n", block, block->next); +} + +static void block_dirty_list_remove(codeblock_t *block) +{ + codeblock_t *prev_block = &codeblock[block->prev]; + codeblock_t *next_block = &codeblock[block->next]; + + if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); + + /*Is block head of list*/ + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = block->next; + else + prev_block->next = block->next; + + /*Is block tail of list?*/ + if (block->next == BLOCK_INVALID) + block_dirty_list_tail = block->prev; + else + next_block->prev = block->prev; + + dirty_list_size--; + if (dirty_list_size < 0) + fatal("remove - dirty_list_size < 0!\n"); + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; +// pclog(" block_dirty_list_remove: %p flags = %x\n", block, block->flags); +} + int codegen_purge_purgable_list() { if (purgable_page_list_head) { page_t *page = &pages[purgable_page_list_head]; - int c; -// pclog("Purge page %08x\n", purgable_page_list_head); - for (c = 0; c < 4; c++) + + if (page->code_present_mask & page->dirty_mask) { -// pclog(" Check %016llx %016llx\n", page->code_present_mask[c], page->dirty_mask[c]); - if (page->code_present_mask[c] & page->dirty_mask[c]) - { - codegen_check_flush(page, page->dirty_mask[c], (purgable_page_list_head << 12) + (c << 10)); -// pclog(" Check %08x %i\n", (purgable_page_list_head << 12) + (c << 10), block_free_list); - if (block_free_list) - return 1; - } + codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); + + if (block_free_list) + return 1; } } return 0; @@ -95,6 +177,27 @@ static codeblock_t *block_free_list_get() while (!block_free_list) { + /*Free list is empty, check the dirty list*/ + if (block_dirty_list_tail) + { + if (dirty_list_size <= 0) + fatal("get - dirty_list_size <= 0!\n"); + + /*Reuse oldest block*/ + block = &codeblock[block_dirty_list_tail]; + +// pclog("block_free_list_get: remove block=%p size=%i\n", block, dirty_list_size); + block_dirty_list_tail = block->prev; + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = BLOCK_INVALID; + else + codeblock[block->prev].next = BLOCK_INVALID; + dirty_list_size--; + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + delete_dirty_block(block); + block_free_list = get_block_nr(block); + break; + } /*Free list is empty - free up a block*/ if (!codegen_purge_purgable_list()) codegen_delete_random_block(0); @@ -103,6 +206,7 @@ static codeblock_t *block_free_list_get() block = &codeblock[block_free_list]; block_free_list = block->next; block->flags &= ~CODEBLOCK_IN_FREE_LIST; +// pclog(" block_free_list_get: %p flags = %x\n", block, block->flags); block->next = 0; // pclog("block_free_list_get: %p %p\n", block, block_free_list); return block; @@ -118,6 +222,8 @@ void codegen_init() block_free_list = 0; for (c = 0; c < BLOCK_SIZE; c++) block_free_list_add(&codeblock[c]); + block_dirty_list_head = block_dirty_list_tail = 0; + dirty_list_size = 0; #ifdef DEBUG_EXTRA memset(instr_counts, 0, sizeof(instr_counts)); #endif @@ -200,22 +306,23 @@ void dump_block() static void add_to_block_list(codeblock_t *block) { - uint16_t block_prev_nr = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + uint16_t block_prev_nr = pages[block->phys >> 12].block; uint16_t block_nr = get_block_nr(block); +//pclog("Add to block list %p %08x %llx %x\n", block, block->phys, block->page_mask2, block->flags); if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); + fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask,block->page_mask2); if (block_prev_nr) { block->next = block_prev_nr; codeblock[block_prev_nr].prev = block_nr; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block_nr; + pages[block->phys >> 12].block = block_nr; } else { block->next = BLOCK_INVALID; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block_nr; + pages[block->phys >> 12].block = block_nr; } if (block->next) @@ -226,26 +333,31 @@ static void add_to_block_list(codeblock_t *block) if (block->page_mask2) { - block_prev_nr = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; + block->flags |= CODEBLOCK_HAS_PAGE2; + + block_prev_nr = pages[block->phys_2 >> 12].block_2; if (block_prev_nr) { block->next_2 = block_prev_nr; codeblock[block_prev_nr].prev_2 = block_nr; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block_nr; + pages[block->phys_2 >> 12].block_2 = block_nr; } else { block->next_2 = BLOCK_INVALID; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block_nr; + pages[block->phys_2 >> 12].block_2 = block_nr; } } +// pclog(" add_to_block_list: %p flags = %x\n", block, block->flags); } static void remove_from_block_list(codeblock_t *block, uint32_t pc) { if (!block->page_mask) return; + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("remove_from_block_list: in dirty list\n"); if (block->prev) { @@ -255,18 +367,21 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } else { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; + pages[block->phys >> 12].block = block->next; if (block->next) codeblock[block->next].prev = BLOCK_INVALID; else mem_flush_write_page(block->phys, 0); } - if (!block->page_mask2) + + if (!(block->flags & CODEBLOCK_HAS_PAGE2)) { if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); + fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); return; } + block->flags &= ~CODEBLOCK_HAS_PAGE2; +// pclog(" remove_from_block_list: %p flags = %x\n", block, block->flags); if (block->prev_2) { @@ -277,7 +392,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->phys_2 >> 10) & 3] = block->next_2; + pages[block->phys_2 >> 12].block_2 = block->next_2; if (block->next_2) codeblock[block->next_2].prev_2 = BLOCK_INVALID; else @@ -285,6 +400,22 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } } +static void invalidate_block(codeblock_t *block) +{ + uint32_t old_pc = block->pc; + + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("invalidate_block: already in dirty list\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Invalidating deleted block\n"); + + remove_from_block_list(block, old_pc); + block_dirty_list_add(block); + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; +} + static void delete_block(codeblock_t *block) { uint32_t old_pc = block->pc; @@ -297,13 +428,29 @@ static void delete_block(codeblock_t *block) block->pc = BLOCK_PC_INVALID; codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else + remove_from_block_list(block, old_pc); if (block->head_mem_block) codegen_allocator_free(block->head_mem_block); block->head_mem_block = NULL; block_free_list_add(block); } +static void delete_dirty_block(codeblock_t *block) +{ + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; + + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); + block->pc = BLOCK_PC_INVALID; + + codeblock_tree_delete(block); + block_free_list_add(block); +} + void codegen_delete_block(codeblock_t *block) { if (block->pc != BLOCK_PC_INVALID) @@ -332,16 +479,19 @@ void codegen_delete_random_block(int required_mem_block) void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) { - uint16_t block_nr = page->block[(phys_addr >> 10) & 3]; + uint16_t block_nr = page->block; + int remove_from_evict_list = 0; + int c; while (block_nr) { codeblock_t *block = &codeblock[block_nr]; uint16_t next_block = block->next; - if (mask & block->page_mask) + if (*block->dirty_mask & block->page_mask) { - delete_block(block); +// pclog("Delete block from codegen_check_flush %08x %08x %016llx %016llx %016llx %02x\n", phys_addr, block->pc, *block->dirty_mask, block->page_mask, *block->dirty_mask & block->page_mask, block->flags); + invalidate_block(block); cpu_recomp_evicted++; } if (block_nr == next_block) @@ -349,16 +499,17 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) block_nr = next_block; } - block_nr = page->block_2[(phys_addr >> 10) & 3]; + block_nr = page->block_2; while (block_nr) { codeblock_t *block = &codeblock[block_nr]; uint16_t next_block = block->next_2; - - if (mask & block->page_mask2) + + if (*block->dirty_mask2 & block->page_mask2) { - delete_block(block); +// pclog("Delete block from codegen_check_flush2 %08x %08x\n", phys_addr, block->pc);*/ + invalidate_block(block); cpu_recomp_evicted++; } if (block_nr == next_block) @@ -366,13 +517,19 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) block_nr = next_block; } - page->code_present_mask[(phys_addr >> 10) & 3] &= ~mask; - page->dirty_mask[(phys_addr >> 10) & 3] &= ~mask; + if (page->code_present_mask & page->dirty_mask) + remove_from_evict_list = 1; + page->code_present_mask &= ~page->dirty_mask; + page->dirty_mask = 0; - if (!(page->code_present_mask[0] & page->dirty_mask[0]) && - !(page->code_present_mask[1] & page->dirty_mask[1]) && - !(page->code_present_mask[2] & page->dirty_mask[2]) && - !(page->code_present_mask[3] & page->dirty_mask[3])) + for (c = 0; c < 64; c++) + { + if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) + remove_from_evict_list = 0; + page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; + page->byte_dirty_mask[c] = 0; + } + if (remove_from_evict_list) page_remove_from_evict_list(page); } @@ -380,10 +537,9 @@ void codegen_block_init(uint32_t phys_addr) { codeblock_t *block; page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); + if (!page->block) + mem_flush_write_page(phys_addr, cs+cpu_state.pc); block = block_free_list_get(); if (!block) fatal("codegen_block_init: block_free_list_get() returned NULL\n"); @@ -396,16 +552,17 @@ void codegen_block_init(uint32_t phys_addr) block->pc = cs + cpu_state.pc; block->_cs = cs; block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask = &page->dirty_mask; block->dirty_mask2 = NULL; block->next = block->prev = BLOCK_INVALID; block->next_2 = block->prev_2 = BLOCK_INVALID; - block->page_mask = 0; + block->page_mask = block->page_mask2 = 0; block->flags = CODEBLOCK_STATIC_TOP; +// pclog(" block_init: %p flags = %x\n", block, block->flags); block->status = cpu_cur_status; recomp_page = block->phys & ~0xfff; - +// pclog("codegen_block_init: %08x\n", block->pc); codeblock_tree_add(block); } @@ -419,8 +576,8 @@ ir_data_t *codegen_get_ir_data() void codegen_block_start_recompile(codeblock_t *block) { page_t *page = &pages[block->phys >> 12]; - - if (!page->block[(block->phys >> 10) & 3]) + + if (!page->block) mem_flush_write_page(block->phys, cs+cpu_state.pc); block_num = HASH(block->phys); @@ -433,6 +590,9 @@ void codegen_block_start_recompile(codeblock_t *block) block->data = codeblock_allocator_get_ptr(block->head_mem_block); block->status = cpu_cur_status; + + block->page_mask = block->page_mask2 = 0; + block->ins = 0; cpu_block_end = 0; @@ -465,7 +625,14 @@ void codegen_block_start_recompile(codeblock_t *block) codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + if (block->flags & CODEBLOCK_BYTE_MASK) + { + block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; + block->dirty_mask2 = NULL; + } + ir_data = codegen_ir_init(); + ir_data->block = block; codegen_reg_reset(); codegen_accumulate_reset(); codegen_generate_reset(); @@ -482,40 +649,104 @@ void codegen_block_remove() recomp_page = -1; } -void codegen_block_generate_end_mask() +void codegen_block_generate_end_mask_recompile() +{ + codeblock_t *block = &codeblock[block_current]; + page_t *p; +//pclog("gen_end_mask: %08x %08x %016llx %016llx\n", block->pc, codegen_endpc, block->page_mask,block->page_mask2); + + p = &pages[block->phys >> 12]; + if (block->flags & CODEBLOCK_BYTE_MASK) + { + int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + + p->byte_code_present_mask[offset] |= block->page_mask; + } + else + p->code_present_mask |= block->page_mask; + + if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); + + block->phys_2 = -1; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if (block->page_mask2) + { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) + { + page_t *page_2 = &pages[block->phys_2 >> 12]; + + if (block->flags & CODEBLOCK_BYTE_MASK) + { + int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + + page_2->byte_code_present_mask[offset] |= block->page_mask2; + block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; + } + else + { + page_2->code_present_mask |= block->page_mask2; + block->dirty_mask2 = &page_2->dirty_mask; + } + if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); + + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); + + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) + { +// pclog(" next_2->pc=%08x\n", block->next_2->pc); + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); + } + } + } + +// pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); + recomp_page = -1; +} + +void codegen_block_generate_end_mask_mark() { codeblock_t *block = &codeblock[block_current]; uint32_t start_pc; uint32_t end_pc; page_t *p; + if (block->flags & CODEBLOCK_BYTE_MASK) + fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); + block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ codegen_endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; + start_pc = (block->pc & 0xfff) & ~63; + if ((block->pc ^ codegen_endpc) & ~0xfff) + end_pc = 0xfff & ~63; else - end_pc = (codegen_endpc & 0x3ff) & ~15; + end_pc = (codegen_endpc & 0xfff) & ~63; if (end_pc < start_pc) - end_pc = 0x3ff; + end_pc = 0xfff; 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); } - + p = &pages[block->phys >> 12]; - p->code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - if ((p->dirty_mask[(block->phys >> 10) & 3] & block->page_mask) && !page_in_evict_list(p)) + p->code_present_mask |= block->page_mask; + if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) page_add_to_evict_list(p); block->phys_2 = -1; block->page_mask2 = 0; block->next_2 = block->prev_2 = BLOCK_INVALID; - if ((block->pc ^ codegen_endpc) & ~0x3ff) + if ((block->pc ^ codegen_endpc) & ~0xfff) { block->phys_2 = get_phys_noabrt(codegen_endpc); if (block->phys_2 != -1) @@ -523,14 +754,15 @@ void codegen_block_generate_end_mask() page_t *page_2 = &pages[block->phys_2 >> 12]; start_pc = 0; - end_pc = (codegen_endpc & 0x3ff) >> PAGE_MASK_SHIFT; + end_pc = (codegen_endpc & 0xfff) >> 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 ((page_2->dirty_mask[(block->phys_2 >> 10) & 3] & block->page_mask2) && !page_in_evict_list(page_2)) + + page_2->code_present_mask |= block->page_mask2; + if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) page_add_to_evict_list(page_2); - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) + if (!pages[block->phys_2 >> 12].block_2) mem_flush_write_page(block->phys_2, codegen_endpc); if (!block->page_mask2) @@ -542,7 +774,7 @@ void codegen_block_generate_end_mask() fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); } - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = &page_2->dirty_mask; } } @@ -554,7 +786,7 @@ void codegen_block_end() { codeblock_t *block = &codeblock[block_current]; - codegen_block_generate_end_mask(); + codegen_block_generate_end_mask_mark(); add_to_block_list(block); } @@ -562,10 +794,13 @@ void codegen_block_end_recompile(codeblock_t *block) { codegen_timing_block_end(); - remove_from_block_list(block, block->pc); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else + remove_from_block_list(block, block->pc); block->next = block->prev = BLOCK_INVALID; block->next_2 = block->prev_2 = BLOCK_INVALID; - codegen_block_generate_end_mask(); + codegen_block_generate_end_mask_recompile(); add_to_block_list(block); // pclog("End block %i\n", block_num); @@ -580,3 +815,60 @@ void codegen_flush() { return; } + +void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len) +{ + if (len) + { + uint32_t end_pc = start_pc + (len-1); + + if (block->flags & CODEBLOCK_BYTE_MASK) + { + uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; + uint32_t end_pc_masked = start_pc & PAGE_MASK_MASK; + + if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t)1 << start_pc_masked); + } + else if (((start_pc + (len-1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ + { + for (; start_pc_masked <= 63; start_pc_masked++) + block->page_mask |= ((uint64_t)1 << start_pc_masked); + for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t)1 << start_pc_masked); + } + else /*First page only*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask |= ((uint64_t)1 << start_pc_masked); + } + } + else + { + uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; + uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; + start_pc_shifted &= PAGE_MASK_MASK; + end_pc_shifted &= PAGE_MASK_MASK; + + if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); + } + else if (((start_pc + (len-1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ + { + for (; start_pc_shifted <= 63; start_pc_shifted++) + block->page_mask |= ((uint64_t)1 << start_pc_shifted); + for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); + } + else /*First page only*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask |= ((uint64_t)1 << start_pc_shifted); + } + } + } +} diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 47a6b3a..0f56360 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1413,6 +1413,66 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); + if (REG_IS_L(dest_size)) + { + host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); + } + else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); + if (REG_IS_L(dest_size)) + { + host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size)) + { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); + if (REG_IS_L(dest_size)) + { + host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } + else if (REG_IS_W(dest_size)) + { + host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -2765,6 +2825,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index a47488d..402a7d7 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1534,6 +1534,66 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); + if (REG_IS_L(dest_size)) + { + host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); + } + else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); + if (REG_IS_L(dest_size)) + { + host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); + } + else if (REG_IS_W(dest_size)) + { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size)) + { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); + if (REG_IS_L(dest_size)) + { + host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } + else if (REG_IS_W(dest_size)) + { + host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} static int codegen_OR(codeblock_t *block, uop_t *uop) { @@ -2914,6 +2974,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index a4a8680..cd634bd 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1058,6 +1058,29 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } +void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + else + { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } +} void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -1080,7 +1103,37 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) } } else - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad offset %i\n", offset); + { + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } +} +void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + else + { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } } void host_x86_NOP(codeblock_t *block) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index eaee044..8d0c07a 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -110,7 +110,9 @@ void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p); void host_x86_NOP(codeblock_t *block); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index da8e8e4..d0768a2 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1269,6 +1269,60 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); return 0; } +static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } + else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } + else if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } + else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } + else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -2681,7 +2735,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index ce64b33..f6a9bda 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -788,6 +788,23 @@ void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } +void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } + else + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t)p); + } +} void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 08b7e9f..1ef8df8 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -108,7 +108,9 @@ void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); +void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p); void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index f3ace1e..096497c 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1256,6 +1256,60 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); return 0; } +static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } + else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } + else if (REG_IS_B(dest_size)) + { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } + else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) + { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } + else if (REG_IS_W(dest_size)) + { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } + else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); @@ -2680,7 +2734,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 74b0043..7880c7a 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -76,6 +76,12 @@ #define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) /*UOP_MOV_INT_DOUBLE_64 - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ #define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) +/*UOP_MOV_REG_PTR - dest_reg = *p*/ +#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) +/*UOP_MOVZX_REG_PTR_8 - dest_reg = *(uint8_t *)p*/ +#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) +/*UOP_MOVZX_REG_PTR_16 - dest_reg = *(uint16_t *)p*/ +#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ @@ -338,6 +344,7 @@ typedef struct ir_data_t { uop_t uops[UOP_NR_MAX]; int wr_pos; + struct codeblock_t *block; } ir_data_t; static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) @@ -667,6 +674,9 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) #define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) #define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) +#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) +#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) #define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) #define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) #define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) diff --git a/src/codegen_ops_3dnow.c b/src/codegen_ops_3dnow.c index ad846e4..7a2af83 100644 --- a/src/codegen_ops_3dnow.c +++ b/src/codegen_ops_3dnow.c @@ -16,6 +16,7 @@ uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; \ \ uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs+op_pc, 1); \ if ((fetchdat & 0xc0) == 0xc0) \ { \ int src_reg = fetchdat & 7; \ @@ -32,6 +33,7 @@ uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + codegen_mark_code_present(block, cs+op_pc+1, 1); \ return op_pc + 2; \ } @@ -49,6 +51,7 @@ uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -65,6 +68,7 @@ uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } @@ -73,6 +77,7 @@ uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -89,6 +94,7 @@ uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } @@ -97,6 +103,7 @@ uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -113,6 +120,7 @@ uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } @@ -121,6 +129,7 @@ uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -136,6 +145,7 @@ uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -143,6 +153,7 @@ uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -159,6 +170,7 @@ uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -166,6 +178,7 @@ uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -182,6 +195,7 @@ uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } @@ -189,5 +203,6 @@ uint32_t ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index ca0b980..08bb5f1 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -7,6 +7,7 @@ #include "codegen_ir.h" #include "codegen_ops.h" #include "codegen_ops_arith.h" +#include "codegen_ops_helpers.h" static inline void get_cf(ir_data_t *ir, int dest_reg) { @@ -26,6 +27,7 @@ uint32_t ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -41,6 +43,7 @@ uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -56,12 +59,14 @@ uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV(ir, IREG_flags_res, IREG_EAX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } uint32_t ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; -//return 0; + + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -95,6 +100,7 @@ uint32_t ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -131,6 +137,7 @@ uint32_t ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -164,6 +171,7 @@ uint32_t ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -200,6 +208,7 @@ uint32_t ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -232,6 +241,7 @@ uint32_t ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -276,6 +286,7 @@ uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -289,18 +300,29 @@ uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + fetchdat = fastreadl(cs + op_pc); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + codegen_mark_code_present(block, cs+op_pc, 4); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; return op_pc + 4; } @@ -308,6 +330,7 @@ uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -339,6 +362,7 @@ uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -372,6 +396,7 @@ uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -403,6 +428,7 @@ uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -436,6 +462,7 @@ uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -466,6 +493,7 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -507,6 +535,7 @@ uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -520,6 +549,7 @@ uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -532,12 +562,14 @@ uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -569,6 +601,7 @@ uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -600,6 +633,7 @@ uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -631,6 +665,7 @@ uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -662,6 +697,7 @@ uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -692,6 +728,7 @@ uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -732,6 +769,7 @@ uint32_t ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -747,6 +785,7 @@ uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -762,12 +801,14 @@ uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV(ir, IREG_flags_res, IREG_EAX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } uint32_t ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -801,6 +842,7 @@ uint32_t ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -837,6 +879,7 @@ uint32_t ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -870,6 +913,7 @@ uint32_t ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -907,6 +951,7 @@ uint32_t ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -939,6 +984,7 @@ uint32_t ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); get_cf(ir, IREG_temp1); if ((fetchdat & 0xc0) == 0xc0) { @@ -984,6 +1030,7 @@ uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -997,15 +1044,27 @@ uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 4); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); uop_MOV(ir, IREG_flags_res, IREG_EAX); @@ -1016,6 +1075,7 @@ uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -1047,6 +1107,7 @@ uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -1080,6 +1141,7 @@ uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -1111,6 +1173,7 @@ uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -1145,6 +1208,7 @@ uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -1175,6 +1239,7 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -1208,23 +1273,43 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + int skip_immediate = 0; + + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; uint8_t imm = fastreadb(cs + op_pc + 1); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs+op_pc+1); + } + switch (fetchdat & 0x38) { case 0x00: /*ADD*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } + else + { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; @@ -1232,8 +1317,16 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch case 0x10: /*ADC*/ get_cf(ir, IREG_temp1); uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } + else + { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); @@ -1242,38 +1335,68 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch case 0x18: /*SBB*/ get_cf(ir, IREG_temp1); uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } + else + { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; case 0x28: /*SUB*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } + else + { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); break; case 0x38: /*CMP*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } + else + { + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); break; @@ -1372,27 +1495,49 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + int skip_immediate = 0; + + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; uint16_t imm = fastreadw(cs + op_pc + 1); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs+op_pc+1); + } + switch (fetchdat & 0x38) { case 0x00: /*ADD*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } + else + { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; @@ -1400,8 +1545,16 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x10: /*ADC*/ get_cf(ir, IREG_temp1); uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } + else + { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); @@ -1410,38 +1563,68 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x18: /*SBB*/ get_cf(ir, IREG_temp1); uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } + else + { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; case 0x28: /*SUB*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } + else + { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); break; case 0x38: /*CMP*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } + else + { + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); break; @@ -1462,65 +1645,103 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_check_seg_write(block, ir, target_seg); imm = fastreadw(cs + op_pc + 1); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs+op_pc+1); + } switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); break; case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); break; case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); break; case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); break; case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); break; case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); break; case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); @@ -1528,8 +1749,16 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x38: /*CMP*/ uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); + } + else + { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + } uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); break; @@ -1540,27 +1769,49 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs+op_pc+1, 2); return op_pc + 3; } uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + int skip_immediate = 0; + + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; uint32_t imm = fastreadl(cs + op_pc + 1); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs+op_pc+1); + } + switch (fetchdat & 0x38) { case 0x00: /*ADD*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; @@ -1568,8 +1819,16 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x10: /*ADC*/ get_cf(ir, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); @@ -1578,37 +1837,67 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x18: /*SBB*/ get_cf(ir, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; case 0x28: /*SUB*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); break; case 0x38: /*CMP*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } + else + { + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); break; @@ -1630,19 +1919,34 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet imm = fastreadl(cs + op_pc + 1); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs+op_pc+1); + } + switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_temp1); break; case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); uop_MOV(ir, IREG_flags_res, IREG_temp0); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); @@ -1650,44 +1954,68 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x10: /*ADC*/ get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); uop_MOV(ir, IREG_flags_res, IREG_temp1); break; case 0x18: /*SBB*/ get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); uop_MOV(ir, IREG_flags_res, IREG_temp1); break; case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); uop_MOV(ir, IREG_flags_res, IREG_temp0); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); break; case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); uop_MOV(ir, IREG_flags_res, IREG_temp1); break; case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); uop_MOV(ir, IREG_flags_res, IREG_temp0); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); @@ -1695,8 +2023,16 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet case 0x38: /*CMP*/ uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); + } + else + { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + } uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); break; @@ -1706,11 +2042,14 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs+op_pc+1, 4); return op_pc + 5; } uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -1875,10 +2214,12 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -2041,6 +2382,7 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } @@ -2121,6 +2463,7 @@ uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + codegen_mark_code_present(block, cs+op_pc, 1); rebuild_c(ir); if ((fetchdat & 0xc0) == 0xc0) diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c index fdc0569..35e5c46 100644 --- a/src/codegen_ops_branch.c +++ b/src/codegen_ops_branch.c @@ -529,6 +529,7 @@ uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, u dest_addr &= 0xffff; \ ropJ ## cond ## _common(block, ir, dest_addr); \ \ + codegen_mark_code_present(block, cs+op_pc, 1); \ return op_pc+1; \ } \ uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -538,6 +539,7 @@ uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, \ ropJ ## cond ## _common(block, ir, dest_addr); \ \ + codegen_mark_code_present(block, cs+op_pc, 2); \ return op_pc+2; \ } \ uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -547,6 +549,7 @@ uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, \ ropJ ## cond ## _common(block, ir, dest_addr); \ \ + codegen_mark_code_present(block, cs+op_pc, 4); \ return op_pc+4; \ } @@ -585,6 +588,7 @@ uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc+1; } @@ -611,6 +615,7 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc+1; } @@ -647,6 +652,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc+1; } uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -682,5 +688,6 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc+1; } diff --git a/src/codegen_ops_helpers.c b/src/codegen_ops_helpers.c new file mode 100644 index 0000000..8ccd1fb --- /dev/null +++ b/src/codegen_ops_helpers.c @@ -0,0 +1,26 @@ +#include "ibm.h" +#include "x86.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir_defs.h" +#include "codegen_reg.h" +#include "codegen_ops_helpers.h" + +void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +{ + /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr+1)); + uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); +} + +void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +{ + /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); + uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); + uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); + uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3); +} diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h index 0da73b6..e1e2bbc 100644 --- a/src/codegen_ops_helpers.h +++ b/src/codegen_ops_helpers.h @@ -1,3 +1,4 @@ +#include "386_common.h" #include "codegen_backend.h" static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) @@ -85,3 +86,26 @@ static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *s else uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); } + +static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +{ + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); +} + +void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); +static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +{ + if ((addr & 0xfff) == 0xfff) + LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr); + else + uop_MOVZX_REG_PTR_16(ir, dest_reg, get_ram_ptr(addr)); +} + +void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); +static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +{ + if ((addr & 0xfff) >= 0xffd) + LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr); + else + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr)); +} diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c index c2c7eb6..dd417e4 100644 --- a/src/codegen_ops_jump.c +++ b/src/codegen_ops_jump.c @@ -17,6 +17,7 @@ uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f dest_addr &= 0xffff; uop_MOV_IMM(ir, IREG_pc, dest_addr); + codegen_mark_code_present(block, cs+op_pc, 1); return -1; } uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -27,6 +28,7 @@ uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t dest_addr &= 0xffff; uop_MOV_IMM(ir, IREG_pc, dest_addr); + codegen_mark_code_present(block, cs+op_pc, 2); return -1; } uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -35,6 +37,7 @@ uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t dest_addr = op_pc+4+offset; uop_MOV_IMM(ir, IREG_pc, dest_addr); + codegen_mark_code_present(block, cs+op_pc, 4); return -1; } @@ -49,6 +52,7 @@ uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); uop_CALL_FUNC(ir, loadcsjmp); + codegen_mark_code_present(block, cs+op_pc, 4); return -1; } uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -62,6 +66,7 @@ uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); uop_CALL_FUNC(ir, loadcsjmp); + codegen_mark_code_present(block, cs+op_pc, 6); return -1; } @@ -80,6 +85,7 @@ uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t SUB_SP(ir, 2); uop_MOV_IMM(ir, IREG_pc, dest_addr); + codegen_mark_code_present(block, cs+op_pc, 2); return -1; } uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -95,6 +101,7 @@ uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t SUB_SP(ir, 4); uop_MOV_IMM(ir, IREG_pc, dest_addr); + codegen_mark_code_present(block, cs+op_pc, 4); return -1; } @@ -146,6 +153,7 @@ uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 ADD_SP(ir, 2+offset); uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + codegen_mark_code_present(block, cs+op_pc, 2); return -1; } uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -163,6 +171,7 @@ uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 } ADD_SP(ir, 4+offset); + codegen_mark_code_present(block, cs+op_pc, 2); return -1; } @@ -243,6 +252,7 @@ uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_CALL_FUNC(ir, loadcs); ADD_SP(ir, 4+offset); + codegen_mark_code_present(block, cs+op_pc, 2); return -1; } uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -271,5 +281,6 @@ uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_CALL_FUNC(ir, loadcs); ADD_SP(ir, 8+offset); + codegen_mark_code_present(block, cs+op_pc, 2); return -1; } diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c index 8f402f1..015031f 100644 --- a/src/codegen_ops_logic.c +++ b/src/codegen_ops_logic.c @@ -6,6 +6,7 @@ #include "codegen.h" #include "codegen_ir.h" #include "codegen_ops.h" +#include "codegen_ops_helpers.h" #include "codegen_ops_logic.h" uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -17,6 +18,7 @@ uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -28,13 +30,23 @@ uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } + else + { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 4); + uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_EAX); @@ -45,6 +57,7 @@ uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -72,6 +85,7 @@ uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -102,6 +116,7 @@ uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -129,6 +144,7 @@ uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -159,6 +175,7 @@ uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -186,6 +203,7 @@ uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -222,6 +240,7 @@ uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -233,23 +252,35 @@ uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } + else + { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 4); + uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_EAX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -277,6 +308,7 @@ uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -307,6 +339,7 @@ uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -334,6 +367,7 @@ uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -364,6 +398,7 @@ uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -391,6 +426,7 @@ uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -426,6 +462,7 @@ uint32_t ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -436,22 +473,34 @@ uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); + } + else + { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 4); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + } - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } uint32_t ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -479,6 +528,7 @@ uint32_t ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -506,6 +556,7 @@ uint32_t ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -538,6 +589,7 @@ uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AL); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -549,23 +601,35 @@ uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOVZX(ir, IREG_flags_res, IREG_AX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } + else + { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 4); + uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); uop_MOV(ir, IREG_flags_res, IREG_EAX); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -593,6 +657,7 @@ uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -623,6 +688,7 @@ uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -650,6 +716,7 @@ uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -680,6 +747,7 @@ uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -707,6 +775,7 @@ uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 2db4c32..13e0e64 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -16,6 +16,7 @@ uint32_t ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f if ((fetchdat & 0xc0) == 0xc0) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); @@ -28,6 +29,7 @@ uint32_t ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f if ((fetchdat & 0xc0) == 0xc0) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); @@ -43,6 +45,7 @@ uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch if (fetchdat & 0x20) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) reg = IREG_8(fetchdat & 7); else @@ -67,6 +70,7 @@ uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc+2; case 0x10: /*NOT*/ @@ -111,6 +115,7 @@ uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe if (fetchdat & 0x20) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) reg = IREG_16(fetchdat & 7); else @@ -135,6 +140,7 @@ uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc+1, 2); return op_pc+3; case 0x10: /*NOT*/ @@ -179,6 +185,7 @@ uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe if (fetchdat & 0x20) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) reg = IREG_32(fetchdat & 7); else @@ -202,6 +209,7 @@ uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); codegen_flags_changed = 1; + codegen_mark_code_present(block, cs+op_pc+1, 4); return op_pc+5; case 0x10: /*NOT*/ @@ -267,6 +275,7 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { if ((fetchdat & 0x38) == 0x28) @@ -284,7 +293,7 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); src_reg = IREG_temp0_W; } - + switch (fetchdat & 0x38) { case 0x00: /*INC*/ @@ -373,6 +382,7 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { if ((fetchdat & 0x38) == 0x28) @@ -510,6 +520,7 @@ uint32_t rop ## name ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, u if ((fetchdat & 0xc0) == 0xc0) \ return 0; \ \ + codegen_mark_code_present(block, cs+op_pc, 1); \ uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ codegen_check_seg_read(block, ir, target_seg); \ @@ -531,6 +542,7 @@ uint32_t rop ## name ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, u if ((fetchdat & 0xc0) == 0xc0) \ return 0; \ \ + codegen_mark_code_present(block, cs+op_pc, 1); \ uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ codegen_check_seg_read(block, ir, target_seg); \ diff --git a/src/codegen_ops_mmx_arith.c b/src/codegen_ops_mmx_arith.c index cd23e3c..1629fe6 100644 --- a/src/codegen_ops_mmx_arith.c +++ b/src/codegen_ops_mmx_arith.c @@ -16,6 +16,7 @@ uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; \ \ uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs+op_pc, 1); \ if ((fetchdat & 0xc0) == 0xc0) \ { \ int src_reg = fetchdat & 7; \ diff --git a/src/codegen_ops_mmx_cmp.c b/src/codegen_ops_mmx_cmp.c index f56f413..b7fe44d 100644 --- a/src/codegen_ops_mmx_cmp.c +++ b/src/codegen_ops_mmx_cmp.c @@ -16,6 +16,7 @@ uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; \ \ uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs+op_pc, 1); \ if ((fetchdat & 0xc0) == 0xc0) \ { \ int src_reg = fetchdat & 7; \ diff --git a/src/codegen_ops_mmx_loadstore.c b/src/codegen_ops_mmx_loadstore.c index e3c33e0..ac591e8 100644 --- a/src/codegen_ops_mmx_loadstore.c +++ b/src/codegen_ops_mmx_loadstore.c @@ -15,6 +15,7 @@ uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -32,13 +33,13 @@ uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } return op_pc + 1; - } uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int src_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -64,6 +65,7 @@ uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -80,7 +82,6 @@ uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t } return op_pc + 1; - } uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -88,6 +89,7 @@ uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int src_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; diff --git a/src/codegen_ops_mmx_logic.c b/src/codegen_ops_mmx_logic.c index 428a591..744f22b 100644 --- a/src/codegen_ops_mmx_logic.c +++ b/src/codegen_ops_mmx_logic.c @@ -15,6 +15,7 @@ uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -32,13 +33,13 @@ uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } return op_pc + 1; - } uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -56,13 +57,13 @@ uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe } return op_pc + 1; - } uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -80,13 +81,13 @@ uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc } return op_pc + 1; - } uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { int dest_reg = (fetchdat >> 3) & 7; uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -104,5 +105,4 @@ uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } return op_pc + 1; - } diff --git a/src/codegen_ops_mmx_pack.c b/src/codegen_ops_mmx_pack.c index 7bf1941..e625217 100644 --- a/src/codegen_ops_mmx_pack.c +++ b/src/codegen_ops_mmx_pack.c @@ -16,6 +16,7 @@ uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t int dest_reg = (fetchdat >> 3) & 7; \ \ uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs+op_pc, 1); \ if ((fetchdat & 0xc0) == 0xc0) \ { \ int src_reg = fetchdat & 7; \ diff --git a/src/codegen_ops_mmx_shift.c b/src/codegen_ops_mmx_shift.c index ad0f597..3086f4d 100644 --- a/src/codegen_ops_mmx_shift.c +++ b/src/codegen_ops_mmx_shift.c @@ -17,6 +17,7 @@ uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int shift = fastreadb(cs + op_pc + 1); uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); switch (op) { case 0x10: /*PSRLW*/ @@ -33,6 +34,7 @@ uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -42,6 +44,7 @@ uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int shift = fastreadb(cs + op_pc + 1); uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); switch (op) { case 0x10: /*PSRLD*/ @@ -58,6 +61,7 @@ uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -67,6 +71,7 @@ uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ int shift = fastreadb(cs + op_pc + 1); uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs+op_pc, 1); switch (op) { case 0x10: /*PSRLQ*/ @@ -83,5 +88,6 @@ uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c index 669523d..26cd4e5 100644 --- a/src/codegen_ops_mov.c +++ b/src/codegen_ops_mov.c @@ -14,6 +14,7 @@ uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -22,14 +23,21 @@ uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); - - uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); - + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); + } + else + { + fetchdat = fastreadl(cs + op_pc); + uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); + codegen_mark_code_present(block, cs+op_pc, 4); + } return op_pc + 4; } @@ -39,6 +47,9 @@ uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; +// if (block->phys == 0x49a400) +// pclog("ropMOVb_rmarkcode %08x 1\n", cs+op_pc); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -61,6 +72,7 @@ uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -83,6 +95,7 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -105,6 +118,7 @@ uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -126,6 +140,7 @@ uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -147,6 +162,7 @@ uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -178,6 +194,7 @@ uint32_t ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 codegen_check_seg_read(block, ir, op_ea_seg); uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); + codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -193,20 +210,37 @@ uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 codegen_check_seg_read(block, ir, op_ea_seg); uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); + codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr; + uint32_t addr = 0; if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); + { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); + } + else + { + addr = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 4); + } + } else + { addr = fastreadw(cs + op_pc); + codegen_mark_code_present(block, cs+op_pc, 2); + } uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); + if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) + uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); + else + uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); return op_pc + ((op_32 & 0x200) ? 4 : 2); } @@ -224,6 +258,7 @@ uint32_t ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 codegen_check_seg_write(block, ir, op_ea_seg); uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); + codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -239,6 +274,7 @@ uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 codegen_check_seg_write(block, ir, op_ea_seg); uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); + codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -254,6 +290,7 @@ uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 codegen_check_seg_write(block, ir, op_ea_seg); uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); + codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); return op_pc + ((op_32 & 0x200) ? 4 : 2); } @@ -262,6 +299,7 @@ uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uint8_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -278,6 +316,7 @@ uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); } + codegen_mark_code_present(block, cs+op_pc+1, 1); return op_pc + 2; } uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -285,6 +324,7 @@ uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uint16_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -301,6 +341,7 @@ uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); } + codegen_mark_code_present(block, cs+op_pc+1, 2); return op_pc + 3; } uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -308,6 +349,7 @@ uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ x86seg *target_seg; uint32_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -324,6 +366,7 @@ uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); } + codegen_mark_code_present(block, cs+op_pc+1, 4); return op_pc + 5; } @@ -331,6 +374,7 @@ uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg; + codegen_mark_code_present(block, cs+op_pc, 1); switch (fetchdat & 0x38) { case 0x00: /*ES*/ @@ -377,6 +421,7 @@ uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg; + codegen_mark_code_present(block, cs+op_pc, 1); switch (fetchdat & 0x38) { case 0x00: /*ES*/ @@ -423,7 +468,8 @@ uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ { int src_reg; x86seg *rseg; - + + codegen_mark_code_present(block, cs+op_pc, 1); switch (fetchdat & 0x38) { case 0x00: /*ES*/ @@ -468,6 +514,7 @@ uint32_t ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -490,6 +537,7 @@ uint32_t ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -512,6 +560,7 @@ uint32_t ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -535,6 +584,7 @@ uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -557,6 +607,7 @@ uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32 { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -579,6 +630,7 @@ uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 { int dest_reg = (fetchdat >> 3) & 7; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int src_reg = fetchdat & 7; @@ -624,6 +676,7 @@ uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f { int reg1 = IREG_8((fetchdat >> 3) & 7); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int reg2 = IREG_8(fetchdat & 7); @@ -651,6 +704,7 @@ uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int reg1 = IREG_16((fetchdat >> 3) & 7); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int reg2 = IREG_16(fetchdat & 7); @@ -678,6 +732,7 @@ uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int reg1 = IREG_32((fetchdat >> 3) & 7); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int reg2 = IREG_32(fetchdat & 7); diff --git a/src/codegen_ops_shift.c b/src/codegen_ops_shift.c index d4b5b56..7410d4d 100644 --- a/src/codegen_ops_shift.c +++ b/src/codegen_ops_shift.c @@ -7,6 +7,7 @@ #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_ops.h" +#include "codegen_ops_helpers.h" #include "codegen_ops_shift.h" static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) @@ -236,6 +237,81 @@ static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc return op_pc + 1; } +static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count_reg) +{ + if ((fetchdat & 0xc0) == 0xc0) + { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } + else + { + switch (fetchdat & 0x38) + { + case 0x20: case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -245,6 +321,7 @@ uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -253,7 +330,8 @@ uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); } imm = fastreadb(cs + op_pc + 1) & 0x1f; - + codegen_mark_code_present(block, cs+op_pc+1, 1); + if (imm) return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; return op_pc+1; @@ -266,6 +344,7 @@ uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -274,7 +353,8 @@ uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); } imm = fastreadb(cs + op_pc + 1) & 0x1f; - + codegen_mark_code_present(block, cs+op_pc+1, 1); + if (imm) return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; return op_pc+1; @@ -282,11 +362,11 @@ uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { x86seg *target_seg = NULL; - uint8_t imm; if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -294,10 +374,23 @@ uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet codegen_check_seg_write(block, ir, target_seg); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); } - imm = fastreadb(cs + op_pc + 1) & 0x1f; + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + { + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); - if (imm) - return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; + uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + return shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; + } + else + { + uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs+op_pc+1, 1); + + if (imm) + return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; + } return op_pc+1; } @@ -308,6 +401,7 @@ uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -325,6 +419,7 @@ uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -342,6 +437,7 @@ uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ return 0; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -363,7 +459,8 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - + + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -455,6 +552,7 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -546,6 +644,7 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { int dest_reg = fetchdat & 7; @@ -633,13 +732,15 @@ uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 int src_reg = (fetchdat >> 3) & 7; uint8_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); } imm = fastreadb(cs + op_pc + 1) & 0x1f; - + codegen_mark_code_present(block, cs+op_pc+1, 1); + if (!imm) return op_pc+2; @@ -670,6 +771,7 @@ uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); } + return op_pc+2; } uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -678,13 +780,15 @@ uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 int src_reg = (fetchdat >> 3) & 7; uint8_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); } imm = fastreadb(cs + op_pc + 1) & 0x1f; - + codegen_mark_code_present(block, cs+op_pc+1, 1); + if (!imm) return op_pc+2; @@ -715,6 +819,7 @@ uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); } + return op_pc+2; } uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -723,13 +828,15 @@ uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 int src_reg = (fetchdat >> 3) & 7; uint8_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); } imm = fastreadb(cs + op_pc + 1) & 0x1f; - + codegen_mark_code_present(block, cs+op_pc+1, 1); + if (!imm) return op_pc+2; @@ -760,6 +867,7 @@ uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); } + return op_pc+2; } uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -768,13 +876,15 @@ uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 int src_reg = (fetchdat >> 3) & 7; uint8_t imm; + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) != 0xc0) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); } imm = fastreadb(cs + op_pc + 1) & 0x1f; - + codegen_mark_code_present(block, cs+op_pc+1, 1); + if (!imm) return op_pc+2; @@ -805,5 +915,6 @@ uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MOV_IMM(ir, IREG_flags_op2, imm); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); } + return op_pc+2; } diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c index 29d2bda..c3c8a46 100644 --- a/src/codegen_ops_stack.c +++ b/src/codegen_ops_stack.c @@ -75,6 +75,7 @@ uint32_t ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); SUB_SP(ir, 2); + codegen_mark_code_present(block, cs+op_pc, 2); return op_pc + 2; } uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -87,6 +88,7 @@ uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); SUB_SP(ir, 4); + codegen_mark_code_present(block, cs+op_pc, 4); return op_pc + 4; } @@ -100,6 +102,7 @@ uint32_t ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uin uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); SUB_SP(ir, 2); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -112,6 +115,7 @@ uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uin uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); SUB_SP(ir, 4); + codegen_mark_code_present(block, cs+op_pc, 1); return op_pc + 1; } @@ -119,6 +123,7 @@ uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { if (stack32) @@ -154,6 +159,7 @@ uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) { if (stack32) diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 01272bc..6be5cfe 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -167,10 +167,12 @@ enum IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, + IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, + IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, diff --git a/src/mem.c b/src/mem.c index 9c6c536..dd3186d 100644 --- a/src/mem.c +++ b/src/mem.c @@ -46,6 +46,9 @@ int cachesize=256; uint8_t *ram, *rom = NULL; uint8_t romext[32768]; +uint64_t *byte_dirty_mask; +uint64_t *byte_code_present_mask; + uint32_t mem_logical_addr; int mmuflush=0; @@ -401,7 +404,7 @@ void addwritelookup(uint32_t virt, uint32_t phys) // if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff)) // fatal("Bad write mapping\n"); - 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) + 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)]; else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; @@ -926,15 +929,23 @@ 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); - int index = (addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + // pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask, mask); p->mem[addr & 0xfff] = val; - p->dirty_mask[index] |= mask; - if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { // pclog("ramb add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); page_add_to_evict_list(p); } + p->byte_dirty_mask[byte_offset] |= byte_mask; + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) + { +// pclog(" ramb add %08x %016llx %016llx\n", addr, p->byte_code_present_mask[byte_offset], byte_mask); + page_add_to_evict_list(p); + } } } void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) @@ -942,13 +953,34 @@ 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); - int index = (addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + if ((addr & 0xf) == 0xf) mask |= (mask << 1); // pclog("mem_write_ramw_page: %08x %04x %08x %016llx %016llx %016llx %08x %08x %p\n", addr, val, cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask, p->evict_prev, p->evict_next, p); *(uint16_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask[index] |= mask; - if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) + { +// pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } + if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) + { + p->byte_dirty_mask[byte_offset+1] |= 1; + if ((p->byte_code_present_mask[byte_offset+1] & 1) && !page_in_evict_list(p)) + { +// pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } + } + else + byte_mask |= (byte_mask << 1); + + p->byte_dirty_mask[byte_offset] |= byte_mask; + + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) { // pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); page_add_to_evict_list(p); @@ -960,17 +992,31 @@ 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); - int index = (addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); + if ((addr & 0xf) >= 0xd) mask |= (mask << 1); // pclog("mem_write_raml_page: %08x %08x %08x %016llx %016llx %016llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask); *(uint32_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask[index] |= mask; - if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + p->dirty_mask |= mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) { // pclog("raml add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); page_add_to_evict_list(p); } + if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK-3)) + { + uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); + + p->byte_dirty_mask[byte_offset+1] |= byte_mask_2; + if ((p->byte_code_present_mask[byte_offset+1] & byte_mask_2) && !page_in_evict_list(p)) + { +// pclog("raml add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } + } } } @@ -1082,10 +1128,10 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) { uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); page_t *p = &pages[start_addr >> 12]; - int index = (start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK; + //pclog("mem_invalidate: %08x\n", start_addr); - p->dirty_mask[index] |= mask; - if ((p->code_present_mask[index] & mask) && !page_in_evict_list(p)) + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { // pclog("invalidate add %08x %016llx %016llx\n", start_addr, p->code_present_mask[index], mask); page_add_to_evict_list(p); @@ -1371,6 +1417,13 @@ void mem_alloc() ram = malloc(mem_size * 1024); memset(ram, 0, mem_size * 1024); + free(byte_dirty_mask); + byte_dirty_mask = malloc((mem_size * 1024) / 8); + memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); + free(byte_code_present_mask); + byte_code_present_mask = malloc((mem_size * 1024) / 8); + memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); + free(pages); pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); @@ -1381,6 +1434,8 @@ void mem_alloc() pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; } memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); @@ -1431,8 +1486,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[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = BLOCK_INVALID; - pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = BLOCK_INVALID; + pages[c].block = BLOCK_INVALID; + pages[c].block_2 = BLOCK_INVALID; } } diff --git a/src/mem.h b/src/mem.h index 79d0da4..429973a 100644 --- a/src/mem.h +++ b/src/mem.h @@ -112,6 +112,13 @@ mem_mapping_t bios_high_mapping[8]; extern mem_mapping_t ram_high_mapping; extern mem_mapping_t ram_remapped_mapping; +extern uint64_t *byte_dirty_mask; +extern uint64_t *byte_code_present_mask; + +#define PAGE_BYTE_MASK_SHIFT 6 +#define PAGE_BYTE_MASK_OFFSET_MASK 63 +#define PAGE_BYTE_MASK_MASK 63 + #define EVICT_NOT_IN_LIST ((uint32_t)-1) typedef struct page_t { @@ -121,14 +128,17 @@ typedef struct page_t uint8_t *mem; - uint16_t block[4], block_2[4]; + uint16_t block, block_2; /*Head of codeblock tree associated with this page*/ uint16_t head; - uint64_t code_present_mask[4], dirty_mask[4]; + uint64_t code_present_mask, dirty_mask; uint32_t evict_prev, evict_next; + + uint64_t *byte_dirty_mask; + uint64_t *byte_code_present_mask; } page_t; extern page_t *pages; From cd9e228b6d237e46d130f6d346db72c5ec816ca6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Mar 2019 15:46:48 +0000 Subject: [PATCH 0638/1050] Move CODEBLOCK_IN_DIRTY_LIST check to after checking if block needs to be flushed. Improves performance in Eradicator. --- src/386_dynarec.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 2817727..d904612 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -341,14 +341,6 @@ void exec386_dynarec(int cycs) } } - if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) - { - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - if (block->flags & CODEBLOCK_BYTE_MASK) - block->flags |= CODEBLOCK_NO_IMMEDIATES; - else - block->flags |= CODEBLOCK_BYTE_MASK; - } if (valid_block && (block->page_mask & *block->dirty_mask)) { codegen_check_flush(page, page->dirty_mask, phys_addr); @@ -379,6 +371,14 @@ void exec386_dynarec(int cycs) block->flags &= ~CODEBLOCK_WAS_RECOMPILED; } } + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) { /*FPU top-of-stack does not match the value this block was compiled From 4b99070fc066d50bef15fd78d835a1e6b75fee39 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 16 Mar 2019 15:47:49 +0000 Subject: [PATCH 0639/1050] Flush accumulators before call to non-recompiled instruction. --- src/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 23ea678..5ffa2cc 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -692,7 +692,7 @@ generate_call: #ifdef DEBUG_EXTRA uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); #endif - + codegen_accumulate_flush(ir); if (op_table == x86_dynarec_opcodes_3DNOW) uop_MOV_IMM(ir, IREG_pc, next_pc); else From 52f5f43d82d85fc5f44d36c8bb47eec2e811b3d7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 22 Mar 2019 20:31:29 +0000 Subject: [PATCH 0640/1050] Fix PC value following FSTCW/FSTSW. --- src/codegen_ops_fpu_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_ops_fpu_misc.c b/src/codegen_ops_fpu_misc.c index 58902ac..2848ba9 100644 --- a/src/codegen_ops_fpu_misc.c +++ b/src/codegen_ops_fpu_misc.c @@ -69,7 +69,7 @@ uint32_t ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); - return op_pc; + return op_pc+1; } uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -82,7 +82,7 @@ uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe codegen_check_seg_write(block, ir, target_seg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); - return op_pc; + return op_pc+1; } uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { From b35cf7de0976f064d2c8d6a6350262a84b8223a9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 22 Mar 2019 20:31:57 +0000 Subject: [PATCH 0641/1050] Fix codegen timing flush at end of a block. --- src/codegen_backend.c | 1 + src/codegen_timing_k6.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 0f76cbe..106b896 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -793,6 +793,7 @@ void codegen_block_end() void codegen_block_end_recompile(codeblock_t *block) { codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); if (block->flags & CODEBLOCK_IN_DIRTY_LIST) block_dirty_list_remove(block); diff --git a/src/codegen_timing_k6.c b/src/codegen_timing_k6.c index 8499cfa..518a565 100644 --- a/src/codegen_timing_k6.c +++ b/src/codegen_timing_k6.c @@ -2339,7 +2339,11 @@ void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint void codegen_timing_k6_block_end() { if (decode_buffer.nr_uops) + { + int old_last_complete_timestamp = last_complete_timestamp; decode_flush(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } } int codegen_timing_k6_jump_cycles() From 7e099c277e1e38ff4f56c4cd7a9eb9cf07a7b1d8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 25 Mar 2019 19:07:51 +0000 Subject: [PATCH 0642/1050] Added basic loop unrolling. Blocks that end in a JMP, LOOP or conditional branch to a previous instruction in the block will be unrolled up to 10 times. --- src/codegen_ir.c | 52 ++++ src/codegen_ir.h | 1 + src/codegen_ir_defs.h | 4 + src/codegen_ops_branch.c | 588 +++++++++++++++++++++++++++++--------- src/codegen_ops_helpers.c | 45 +++ src/codegen_ops_helpers.h | 15 + src/codegen_ops_jump.c | 15 +- src/codegen_reg.c | 7 +- src/codegen_reg.h | 15 +- 9 files changed, 594 insertions(+), 148 deletions(-) diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 56d58f7..e3a9377 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -8,19 +8,71 @@ extern int has_ea; static ir_data_t ir_block; +static int codegen_unroll_start, codegen_unroll_count; + ir_data_t *codegen_ir_init() { ir_block.wr_pos = 0; // pclog("codegen_ir_init %04x:%04x\n", CS,cpu_state.pc); + codegen_unroll_count = 0; + return &ir_block; } +void codegen_ir_set_unroll(int count, int start) +{ + codegen_unroll_count = count; + codegen_unroll_start = start; +} + +static void duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) +{ + uop_t *new_uop = uop_alloc(ir, uop->type); + +// pclog(" uop type %08x\n", uop->type); + if (!ir_reg_is_invalid(uop->src_reg_a)) + new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); + if (!ir_reg_is_invalid(uop->src_reg_b)) + new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); + if (!ir_reg_is_invalid(uop->src_reg_c)) + new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); + if (!ir_reg_is_invalid(uop->dest_reg_a)) + new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos-1); + + new_uop->type = uop->type; + new_uop->imm_data = uop->imm_data; + new_uop->p = uop->p; + new_uop->pc = uop->pc; + + if (uop->jump_dest_uop != -1) + { + new_uop->jump_dest_uop = uop->jump_dest_uop + offset; + } +} + void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) { int jump_target_at_end = -1; int c; + if (codegen_unroll_count) + { + int unroll_count; + int unroll_end = ir->wr_pos; + + for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) + { + int offset = ir->wr_pos - codegen_unroll_start; +// pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count); + for (c = codegen_unroll_start; c < unroll_end; c++) + { +// pclog(" Duplicate uop %i\n", c); + duplicate_uop(ir, &ir->uops[c], offset); + } + } + } + codegen_reg_mark_as_required(); codegen_reg_process_dead_list(ir); block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); diff --git a/src/codegen_ir.h b/src/codegen_ir.h index aafeca6..b560256 100644 --- a/src/codegen_ir.h +++ b/src/codegen_ir.h @@ -2,4 +2,5 @@ ir_data_t *codegen_ir_init(); +void codegen_ir_set_unroll(int count, int start); void codegen_ir_compile(ir_data_t *ir, codeblock_t *block); diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 7880c7a..82d0af9 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -336,6 +336,7 @@ typedef struct uop_t int jump_dest_uop; int jump_list_next; void *jump_dest; + uint32_t pc; } uop_t; #define UOP_NR_MAX 4096 @@ -361,6 +362,9 @@ static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) uop->src_reg_b = invalid_ir_reg; uop->src_reg_c = invalid_ir_reg; + uop->pc = cpu_state.oldpc; + + uop->jump_dest_uop = -1; uop->jump_list_next = -1; if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c index 35e5c46..d22093a 100644 --- a/src/codegen_ops_branch.c +++ b/src/codegen_ops_branch.c @@ -19,7 +19,7 @@ static int VF_SET_01() return VF_SET() ? 1 : 0; } -static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; @@ -27,7 +27,7 @@ static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) { case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Overflow is always zero*/ - return; + return 0; case FLAGS_SUB8: case FLAGS_DEC8: jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); @@ -50,8 +50,9 @@ static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return 0; } -static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; @@ -61,7 +62,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) /*Overflow is always zero*/ uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); - return; + return 0; case FLAGS_SUB8: case FLAGS_DEC8: jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); @@ -84,43 +85,59 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return 0; } -static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; + int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Carry is always zero*/ - return; + return 0; case FLAGS_SUB8: - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } -static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; + int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { @@ -128,140 +145,266 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) /*Carry is always zero*/ uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); - return; + return 0; case FLAGS_SUB8: - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } -static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; } else { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); + return 0; } -void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; } else { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } + else + { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); + return 0; } -static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop, jump_uop2 = -1; + int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Carry is always zero, so test zero only*/ - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); break; case FLAGS_SUB8: - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + if (do_unroll) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } + else + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } break; } - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); + if (do_unroll) + { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } + else + { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; + } } -static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop, jump_uop2 = -1; + int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: /*Carry is always zero, so test zero only*/ - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); break; case FLAGS_SUB8: - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + if (do_unroll) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + else + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); + if (do_unroll) + { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } + else + { + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } } -static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; + int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { @@ -273,7 +416,10 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) case FLAGS_SAR8: case FLAGS_INC8: case FLAGS_DEC8: - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); break; case FLAGS_ZN16: @@ -284,7 +430,10 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) case FLAGS_SAR16: case FLAGS_INC16: case FLAGS_DEC16: - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); break; case FLAGS_ZN32: @@ -295,22 +444,30 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) case FLAGS_SAR32: case FLAGS_INC32: case FLAGS_DEC32: - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); break; case FLAGS_UNKNOWN: default: uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } -static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; + int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { @@ -322,7 +479,10 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) case FLAGS_SAR8: case FLAGS_INC8: case FLAGS_DEC8: - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); break; case FLAGS_ZN16: @@ -333,7 +493,10 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) case FLAGS_SAR16: case FLAGS_INC16: case FLAGS_DEC16: - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); break; case FLAGS_ZN32: @@ -344,21 +507,28 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) case FLAGS_SAR32: case FLAGS_INC32: case FLAGS_DEC32: - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); break; case FLAGS_UNKNOWN: default: uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } -static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; @@ -367,8 +537,9 @@ static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return 0; } -static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; @@ -377,146 +548,267 @@ static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return 0; } -static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_ZN8: /*V flag is always clear. Condition is true if N is set*/ - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); break; case FLAGS_ZN16: - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); break; case FLAGS_ZN32: - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); break; case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + if (do_unroll) + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } -static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop; - + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_ZN8: /*V flag is always clear. Condition is true if N is set*/ - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); break; case FLAGS_ZN16: - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); break; case FLAGS_ZN32: - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); break; case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + if (do_unroll) + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } -static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop, jump_uop2 = -1; + int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + if (do_unroll) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } + else + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } break; } - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); + if (do_unroll) + { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } + else + { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; + } } -static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr) +static int ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { int jump_uop, jump_uop2 = -1; + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); break; case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); break; case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); break; case FLAGS_UNKNOWN: default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + if (do_unroll) + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } + else + { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } break; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); + if (do_unroll) + { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } + else + { + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } } #define ropJ(cond) \ @@ -524,33 +816,36 @@ uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, u { \ uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ uint32_t dest_addr = op_pc + 1 + offset; \ + int ret; \ \ if (!(op_32 & 0x100)) \ dest_addr &= 0xffff; \ - ropJ ## cond ## _common(block, ir, dest_addr); \ + ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+1); \ \ codegen_mark_code_present(block, cs+op_pc, 1); \ - return op_pc+1; \ + return ret ? dest_addr : (op_pc+1); \ } \ uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ + int ret; \ \ - ropJ ## cond ## _common(block, ir, dest_addr); \ + ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+2); \ \ codegen_mark_code_present(block, cs+op_pc, 2); \ - return op_pc+2; \ + return ret ? dest_addr : (op_pc+2); \ } \ uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ { \ uint32_t offset = fastreadl(cs + op_pc); \ uint32_t dest_addr = op_pc + 4 + offset; \ + int ret; \ \ - ropJ ## cond ## _common(block, ir, dest_addr); \ + ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+4); \ \ codegen_mark_code_present(block, cs+op_pc, 4); \ - return op_pc+4; \ + return ret ? dest_addr : (op_pc+4); \ } ropJ(O) @@ -596,27 +891,48 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet { uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; + uint32_t ret_addr; int jump_uop; if (!(op_32 & 0x100)) dest_addr &= 0xffff; - if (op_32 & 0x200) + if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc+1, dest_addr)) { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + if (op_32 & 0x200) + { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + } + else + { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc+1); + ret_addr = dest_addr; + CPU_BLOCK_END(); } else { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + if (op_32 & 0x200) + { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } + else + { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + ret_addr = op_pc+1; } - uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; + return ret_addr; } uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) diff --git a/src/codegen_ops_helpers.c b/src/codegen_ops_helpers.c index 8ccd1fb..fdde53b 100644 --- a/src/codegen_ops_helpers.c +++ b/src/codegen_ops_helpers.c @@ -2,6 +2,7 @@ #include "x86.h" #include "386_common.h" #include "codegen.h" +#include "codegen_ir.h" #include "codegen_ir_defs.h" #include "codegen_reg.h" #include "codegen_ops_helpers.h" @@ -24,3 +25,47 @@ void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); uop_OR(ir, dest_reg, dest_reg, IREG_temp3); } + +#define UNROLL_MAX_REG_REFERENCES 200 +#define UNROLL_MAX_UOPS 1000 +#define UNROLL_MAX_COUNT 10 +int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +{ + int start; + int max_unroll; + + /*Check that dest instruction was actually compiled into block*/ + for (start = 0; start < ir->wr_pos; start++) + { +// pclog(" uOP %i %08x %08x\n", c, ir->uops[c].pc, dest_addr); + if (ir->uops[start].pc == dest_addr) + break; + if (ir->uops[start].pc > dest_addr) + { +// pclog("Went past dest_addr. start_pc=%08x end_pc=%08x dest_pc=%08x wr_pos=%i loop_size=%i\n", block->pc-cs, next_pc, dest_addr, ir->wr_pos, ir->wr_pos-start); + return 0; + } + } + /*Couldn't find any uOPs corresponding to the destination instruction*/ + if (start == ir->wr_pos) + { + /*Is instruction jumping to itself?*/ + if (dest_addr != cpu_state.oldpc) + { +// pclog("Couldn't find start. start_pc=%08x end_pc=%08x dest_pc=%08x wr_pos=%i loop_size=%i\n", block->pc-cs, next_pc, dest_addr, ir->wr_pos, ir->wr_pos-start); + return 0; + } + } + + max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6); + if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount)) + max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); + if (max_unroll > UNROLL_MAX_COUNT) + max_unroll = UNROLL_MAX_COUNT; + if (max_unroll <= 1) + return 0; + + codegen_ir_set_unroll(max_unroll, start); + + return 1; +} diff --git a/src/codegen_ops_helpers.h b/src/codegen_ops_helpers.h index e1e2bbc..ae3e5ed 100644 --- a/src/codegen_ops_helpers.h +++ b/src/codegen_ops_helpers.h @@ -109,3 +109,18 @@ static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, else uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr)); } + +int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr); +static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +{ + if (block->flags & CODEBLOCK_BYTE_MASK) + return 0; + + /*Is dest within block?*/ + if (dest_addr > next_pc) + return 0; + if ((cs+dest_addr) < block->pc) + return 0; + + return codegen_can_unroll_full(block, ir, next_pc, dest_addr); +} diff --git a/src/codegen_ops_jump.c b/src/codegen_ops_jump.c index dd417e4..5e4cda4 100644 --- a/src/codegen_ops_jump.c +++ b/src/codegen_ops_jump.c @@ -16,9 +16,10 @@ uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f if (!(op_32 & 0x100)) dest_addr &= 0xffff; - uop_MOV_IMM(ir, IREG_pc, dest_addr); + if (offset < 0) + codegen_can_unroll(block, ir, op_pc+1, dest_addr); codegen_mark_code_present(block, cs+op_pc, 1); - return -1; + return dest_addr; } uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -27,18 +28,20 @@ uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t dest_addr &= 0xffff; - uop_MOV_IMM(ir, IREG_pc, dest_addr); + if (offset < 0) + codegen_can_unroll(block, ir, op_pc+1, dest_addr); codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + return dest_addr; } uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { uint32_t offset = fastreadl(cs + op_pc); uint32_t dest_addr = op_pc+4+offset; - uop_MOV_IMM(ir, IREG_pc, dest_addr); + if (offset < 0) + codegen_can_unroll(block, ir, op_pc+1, dest_addr); codegen_mark_code_present(block, cs+op_pc, 4); - return -1; + return dest_addr; } uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index dda256c..eb07cfb 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -4,6 +4,7 @@ #include "codegen_ir_defs.h" #include "codegen_reg.h" +int max_version_refcount; uint16_t reg_dead_list = 0; uint8_t reg_last_version[IREG_COUNT]; @@ -249,11 +250,7 @@ void codegen_reg_reset() } reg_dead_list = 0; -} - -static inline int ir_reg_is_invalid(ir_reg_t ir_reg) -{ - return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); + max_version_refcount = 0; } static inline int ir_get_refcount(ir_reg_t ir_reg) diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 6be5cfe..bd790a9 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -315,7 +315,10 @@ extern ir_reg_t invalid_ir_reg; typedef uint16_t ir_host_reg_t; +extern int max_version_refcount; + #define REG_VERSION_MAX 250 +#define REG_REFCOUNT_MAX 250 static inline ir_reg_t codegen_reg_read(int reg) { @@ -332,8 +335,10 @@ static inline ir_reg_t codegen_reg_read(int reg) version->refcount++; if (!version->refcount) fatal("codegen_reg_read - refcount overflow\n"); - else if (version->refcount > REG_VERSION_MAX) + else if (version->refcount > REG_REFCOUNT_MAX) CPU_BLOCK_END(); + if (version->refcount > max_version_refcount) + max_version_refcount = version->refcount; // pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); return ireg; } @@ -359,6 +364,9 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) fatal("codegen_reg_write - version overflow\n"); else if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) CPU_BLOCK_END(); + if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) + max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; + version = ®_version[IREG_GET_REG(reg)][ireg.version]; version->refcount = 0; version->flags = 0; @@ -367,6 +375,11 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) return ireg; } +static inline int ir_reg_is_invalid(ir_reg_t ir_reg) +{ + return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); +} + struct ir_data_t; void codegen_reg_reset(); From 61722f120c27bd2027b0e1c566e807a095f721ae Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 25 Mar 2019 19:59:46 +0000 Subject: [PATCH 0643/1050] Fix block mask calculation. Fixes rendering errors in Blood. --- src/codegen_backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 106b896..8239e94 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -826,7 +826,7 @@ void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, if (block->flags & CODEBLOCK_BYTE_MASK) { uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; - uint32_t end_pc_masked = start_pc & PAGE_MASK_MASK; + uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ { From 56a01a0e04e18656a8402c5d4b35b935382b3b04 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 26 Mar 2019 22:02:00 +0000 Subject: [PATCH 0644/1050] Provide dummy timing for unknown (usually illegal) opcodes in K6 timing code. --- src/codegen_timing_k6.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/codegen_timing_k6.c b/src/codegen_timing_k6.c index 518a565..5d5aa8e 100644 --- a/src/codegen_timing_k6.c +++ b/src/codegen_timing_k6.c @@ -2330,9 +2330,10 @@ void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint } } - if (!ins_table[opcode]) - fatal("!ins_table opcode=%02x last_prefix=%02x\n", opcode, last_prefix); - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } From efef231d7d7e1245d1bf40cd1def071e037b69b9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 28 Mar 2019 20:37:55 +0000 Subject: [PATCH 0645/1050] Restore correct CS value when aborting in stack operations in CALL far instructions. --- src/x86_ops_call.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/x86_ops_call.h b/src/x86_ops_call.h index 4c2e117..8b6087d 100644 --- a/src/x86_ops_call.h +++ b/src/x86_ops_call.h @@ -16,14 +16,14 @@ if (cgate32) \ { \ uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ } \ else \ { \ uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ } #define CALL_FAR_l(new_seg, new_pc) \ @@ -44,14 +44,14 @@ if (cgate16) \ { \ uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ + PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ } \ else \ { \ uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ + PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ + PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ } From b77bce1efd874b84caf4ebc458188ce22c0e57aa Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 28 Mar 2019 20:38:33 +0000 Subject: [PATCH 0646/1050] Clear page_mask2 when the second page in a block is inaccessible. --- src/codegen_backend.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 8239e94..19e32f6 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -704,6 +704,13 @@ void codegen_block_generate_end_mask_recompile() fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); } } + else + { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; + } } // pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); @@ -776,6 +783,13 @@ void codegen_block_generate_end_mask_mark() block->dirty_mask2 = &page_2->dirty_mask; } + else + { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; + } } // pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); From 8b197e22da0e6353f43847931ce1528cb419514a Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 29 Mar 2019 21:06:01 +0000 Subject: [PATCH 0647/1050] Improved interpreter implementations of ROL and ROR. --- src/x86_ops_shift.h | 109 +++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 71 deletions(-) diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index 1a31316..c248593 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -6,31 +6,20 @@ switch (rmdat & 0x38) \ { \ case 0x00: /*ROL b, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x80) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ + temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x08: /*ROR b,CL*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x80; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ + temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ + seteab(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -98,32 +87,21 @@ switch (rmdat & 0x38) \ { \ case 0x00: /*ROL w, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x8000) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ - case 0x08: /*ROR w, c*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x8000; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ + seteaw(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x10: /*RCL w, c*/ \ @@ -190,33 +168,22 @@ switch (rmdat & 0x38) \ { \ case 0x00: /*ROL l, c*/ \ - while (c > 0) \ - { \ - temp2 = (temp & 0x80000000) ? 1 : 0; \ - temp = (temp << 1) | temp2; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + temp = (temp << c) | (temp >> (32-c)); \ + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ - case 0x08: /*ROR l, c*/ \ - while (c > 0) \ - { \ - temp2 = temp & 1; \ - temp >>= 1; \ - if (temp2) temp |= 0x80000000; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32-c)); \ + seteal(temp); if (cpu_state.abrt) return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x10: /*RCL l, c*/ \ temp2 = CF_SET(); \ From e2a1ae696f954286cbc53c507f51aed938803446 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 30 Mar 2019 14:41:02 +0000 Subject: [PATCH 0648/1050] Added lazy flags for ROL and ROR. --- src/codegen_ops_branch.c | 12 +++---- src/x86_flags.h | 73 +++++++++++++++++++++++++++++++++++++++- src/x86_ops_shift.h | 26 ++++---------- 3 files changed, 85 insertions(+), 26 deletions(-) diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c index d22093a..e41b9ee 100644 --- a/src/codegen_ops_branch.c +++ b/src/codegen_ops_branch.c @@ -189,7 +189,7 @@ static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, u if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!codegen_flags_changed || !flags_res_valid()) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); @@ -205,7 +205,7 @@ static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, u } else { - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!codegen_flags_changed || !flags_res_valid()) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); @@ -226,7 +226,7 @@ int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_ if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!codegen_flags_changed || !flags_res_valid()) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); @@ -242,7 +242,7 @@ int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_ } else { - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!codegen_flags_changed || !flags_res_valid()) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); @@ -954,7 +954,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); } - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!codegen_flags_changed || !flags_res_valid()) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); @@ -990,7 +990,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); } - if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) + if (!codegen_flags_changed || !flags_res_valid()) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); diff --git a/src/x86_flags.h b/src/x86_flags.h index 4332fad..49170f3 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -28,6 +28,14 @@ enum FLAGS_SAR16, FLAGS_SAR32, + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, + + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, + FLAGS_INC8, FLAGS_INC16, FLAGS_INC32, @@ -81,6 +89,12 @@ static inline int ZF_SET() case FLAGS_SBC32: return !cpu_state.flags_res; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: case FLAGS_UNKNOWN: return cpu_state.flags & Z_FLAG; } @@ -127,6 +141,12 @@ static inline int NF_SET() case FLAGS_SBC32: return cpu_state.flags_res & 0x80000000; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: case FLAGS_UNKNOWN: return cpu_state.flags & N_FLAG; } @@ -169,6 +189,12 @@ static inline int PF_SET() case FLAGS_SBC32: return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: case FLAGS_UNKNOWN: return cpu_state.flags & P_FLAG; } @@ -226,7 +252,21 @@ static inline int VF_SET() return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); case FLAGS_SHR32: return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); - + + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + case FLAGS_UNKNOWN: return cpu_state.flags & V_FLAG; } @@ -283,6 +323,12 @@ static inline int AF_SET() return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: case FLAGS_UNKNOWN: return cpu_state.flags & A_FLAG; } @@ -344,6 +390,18 @@ static inline int CF_SET() case FLAGS_ZN16: case FLAGS_ZN32: return 0; + + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; + + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 :0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; case FLAGS_DEC8: case FLAGS_DEC16: @@ -396,6 +454,15 @@ static inline void flags_rebuild_c() } } +static inline int flags_res_valid() +{ + if (cpu_state.flags_op == FLAGS_UNKNOWN || + (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; + + return 1; +} + static inline void setznp8(uint8_t val) { cpu_state.flags_op = FLAGS_ZN8; @@ -418,6 +485,10 @@ static inline void setznp32(uint32_t val) cpu_state.flags_op1 = orig; \ cpu_state.flags_op2 = shift; +#define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ + cpu_state.flags_res = res; + static inline void setadd8(uint8_t a, uint8_t b) { cpu_state.flags_op1 = a; diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index c248593..0d6d193 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -8,18 +8,14 @@ case 0x00: /*ROL b, c*/ \ temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ + set_flags_rotate(FLAGS_ROL8, temp); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x08: /*ROR b,CL*/ \ temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ + seteab(temp); if (cpu_state.abrt) return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -89,18 +85,14 @@ case 0x00: /*ROL w, c*/ \ temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ + set_flags_rotate(FLAGS_ROL16, temp); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x08: /*ROR w,CL*/ \ temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ + set_flags_rotate(FLAGS_ROR16, temp); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ @@ -170,18 +162,14 @@ case 0x00: /*ROL l, c*/ \ temp = (temp << c) | (temp >> (32-c)); \ seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ + set_flags_rotate(FLAGS_ROL32, temp); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ case 0x08: /*ROR l,CL*/ \ temp = (temp >> c) | (temp << (32-c)); \ seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ + set_flags_rotate(FLAGS_ROR32, temp); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ break; \ From e8f39da4591d78b6682edb41555cae8e000b1d1e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 30 Mar 2019 16:10:00 +0000 Subject: [PATCH 0649/1050] Add recompiled versions of ROL and ROR. --- src/codegen_backend_x86-64_ops.c | 90 ++++++++++++ src/codegen_backend_x86-64_ops.h | 16 +++ src/codegen_backend_x86-64_uops.c | 123 ++++++++++++++++ src/codegen_backend_x86_ops.c | 66 +++++++++ src/codegen_backend_x86_ops.h | 16 +++ src/codegen_backend_x86_uops.c | 123 ++++++++++++++++ src/codegen_ir_defs.h | 12 ++ src/codegen_ops_shift.c | 228 ++++++++++++++++++++++++++++-- 8 files changed, 665 insertions(+), 9 deletions(-) diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index cd634bd..48acb73 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -15,6 +15,8 @@ #define RM_OP_XOR 0x30 #define RM_OP_CMP 0x38 +#define RM_OP_ROL 0x00 +#define RM_OP_ROR 0x08 #define RM_OP_SHL 0x20 #define RM_OP_SHR 0x28 #define RM_OP_SAR 0x38 @@ -1263,6 +1265,94 @@ void host_x86_RET(codeblock_t *block) codegen_addbyte(block, 0xc3); /*RET*/ } +void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} + +void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} + +void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR32 im & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) { if (dst_reg & 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 8d0c07a..3cd86fb 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -130,6 +130,22 @@ void host_x86_PUSH(codeblock_t *block, int src_reg); void host_x86_RET(codeblock_t *block); +void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_ROL8_CL(codeblock_t *block, int dst_reg); +void host_x86_ROL16_CL(codeblock_t *block, int dst_reg); +void host_x86_ROL32_CL(codeblock_t *block, int dst_reg); + +void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_ROR8_CL(codeblock_t *block, int dst_reg); +void host_x86_ROR16_CL(codeblock_t *block, int dst_reg); +void host_x86_ROR32_CL(codeblock_t *block, int dst_reg); + void host_x86_SAR8_CL(codeblock_t *block, int dst_reg); void host_x86_SAR16_CL(codeblock_t *block, int dst_reg); void host_x86_SAR32_CL(codeblock_t *block, int dst_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d0768a2..8c35559 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -2333,6 +2333,125 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} +static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} +static int codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} +static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2758,6 +2877,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index f6a9bda..41ab522 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -15,6 +15,8 @@ #define RM_OP_XOR 0x30 #define RM_OP_CMP 0x38 +#define RM_OP_ROL 0x00 +#define RM_OP_ROR 0x08 #define RM_OP_SHL 0x20 #define RM_OP_SHR 0x28 #define RM_OP_SAR 0x38 @@ -953,6 +955,70 @@ void host_x86_RET(codeblock_t *block) codegen_addbyte(block, 0xc3); /*RET*/ } +void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} + +void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} + +void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 1ef8df8..94f526c 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -129,6 +129,22 @@ void host_x86_PUSH(codeblock_t *block, int src_reg); void host_x86_RET(codeblock_t *block); +void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_ROL8_CL(codeblock_t *block, int dst_reg); +void host_x86_ROL16_CL(codeblock_t *block, int dst_reg); +void host_x86_ROL32_CL(codeblock_t *block, int dst_reg); + +void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift); + +void host_x86_ROR8_CL(codeblock_t *block, int dst_reg); +void host_x86_ROR16_CL(codeblock_t *block, int dst_reg); +void host_x86_ROR32_CL(codeblock_t *block, int dst_reg); + void host_x86_SAR8_CL(codeblock_t *block, int dst_reg); void host_x86_SAR16_CL(codeblock_t *block, int dst_reg); void host_x86_SAR32_CL(codeblock_t *block, int dst_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 096497c..91e80d9 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2329,6 +2329,125 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} +static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} +static int codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} +static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } +#ifdef RECOMPILER_DEBUG + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +#endif + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2757,6 +2876,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 82d0af9..1cecf9e 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -148,6 +148,14 @@ #define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) /*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/ #define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) +/*UOP_ROL - dest_reg = src_reg_a rotate<< src_reg_b*/ +#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) +/*UOP_ROL_IMM - dest_reg = src_reg_a rotate<< immediate*/ +#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) +/*UOP_ROR - dest_reg = src_reg_a rotate>> src_reg_b*/ +#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) +/*UOP_ROR_IMM - dest_reg = src_reg_a rotate>> immediate*/ +#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) /*UOP_CMP_IMM_JZ_DEST - if (src_reg_a == imm_data) then jump to ptr*/ #define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) @@ -616,6 +624,10 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) #define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) #define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) +#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) +#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) diff --git a/src/codegen_ops_shift.c b/src/codegen_ops_shift.c index 7410d4d..4e8a97b 100644 --- a/src/codegen_ops_shift.c +++ b/src/codegen_ops_shift.c @@ -18,6 +18,20 @@ static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); @@ -50,6 +64,22 @@ static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, { switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); @@ -94,6 +124,20 @@ static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); @@ -126,6 +170,22 @@ static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc { switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); @@ -169,6 +229,20 @@ static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); @@ -201,6 +275,22 @@ static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc { switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); @@ -245,6 +335,20 @@ static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint3 switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); @@ -277,6 +381,22 @@ static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint3 { switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); @@ -318,7 +438,7 @@ uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch x86seg *target_seg = NULL; uint8_t imm; - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; codegen_mark_code_present(block, cs+op_pc, 1); @@ -341,7 +461,7 @@ uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet x86seg *target_seg = NULL; uint8_t imm; - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; codegen_mark_code_present(block, cs+op_pc, 1); @@ -363,7 +483,7 @@ uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet { x86seg *target_seg = NULL; - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; codegen_mark_code_present(block, cs+op_pc, 1); @@ -398,7 +518,7 @@ uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch { x86seg *target_seg = NULL; - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; codegen_mark_code_present(block, cs+op_pc, 1); @@ -416,7 +536,7 @@ uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet { x86seg *target_seg = NULL; - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; codegen_mark_code_present(block, cs+op_pc, 1); @@ -434,7 +554,7 @@ uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet { x86seg *target_seg = NULL; - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; codegen_mark_code_present(block, cs+op_pc, 1); @@ -451,7 +571,7 @@ uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; if (!(CL & 0x1f) || !block->ins) @@ -467,6 +587,20 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); @@ -506,6 +640,22 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); @@ -543,7 +693,7 @@ uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch } uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; if (!(CL & 0x1f) || !block->ins) @@ -559,6 +709,20 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); @@ -598,6 +762,22 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); @@ -635,7 +815,7 @@ uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ return 0; if (!(CL & 0x1f) || !block->ins) @@ -651,6 +831,20 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + case 0x20: case 0x30: /*SHL*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); @@ -690,6 +884,22 @@ uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + case 0x20: case 0x30: /*SHL*/ uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); From 12d73e8a95eb8f611e3ddaa66e4922295b65bee4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 30 Mar 2019 19:45:29 +0000 Subject: [PATCH 0650/1050] Fix zero sized recompiled shifts. Fixes hang in Gunmetal. --- src/codegen_backend_x86-64_uops.c | 9 ++++++++- src/codegen_backend_x86_uops.c | 7 +++++++ src/codegen_ir_defs.h | 3 +++ src/codegen_ops_shift.c | 11 ++++++++--- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 8c35559..729e4fd 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -1455,6 +1455,11 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2979,7 +2984,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 91e80d9..c09512e 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -1451,6 +1451,11 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2980,6 +2985,8 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP, + #ifdef DEBUG_EXTRA [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR #endif diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 1cecf9e..76f4979 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -54,6 +54,7 @@ #define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_JMP_DEST - jump to ptr*/ #define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) #ifdef DEBUG_EXTRA /*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ @@ -699,6 +700,8 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) #define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) +#define uop_NOP_BARRIER(ir) uop_gen(UOP_NOP_BARRIER, ir) + #define uop_PACKSSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSWB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) diff --git a/src/codegen_ops_shift.c b/src/codegen_ops_shift.c index 4e8a97b..0d19f40 100644 --- a/src/codegen_ops_shift.c +++ b/src/codegen_ops_shift.c @@ -496,12 +496,17 @@ uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet } if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uint32_t new_pc; + int jump_uop; + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); - uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); - return shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; + new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + return new_pc; } else { From 78572ba468f638fee31a48a3a6d782eaa3e51b49 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 30 Mar 2019 21:01:20 +0000 Subject: [PATCH 0651/1050] Added register barriers to LOOPE and LOOPNE. Fixes crash in Age of Empires II. --- src/codegen_ops_branch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/codegen_ops_branch.c b/src/codegen_ops_branch.c index e41b9ee..ea9b986 100644 --- a/src/codegen_ops_branch.c +++ b/src/codegen_ops_branch.c @@ -965,6 +965,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe } uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); @@ -1001,6 +1002,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f } uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop2); From e3d5309e237f587c85604c9548a77a2979fa4025 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 31 Mar 2019 11:29:07 +0100 Subject: [PATCH 0652/1050] Added SST 39SF010 flash for VA-503+. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/model.c | 2 + src/sst39sf010.c | 218 +++++++++++++++++++++++++++++++++++++ src/sst39sf010.h | 1 + 5 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 src/sst39sf010.c create mode 100644 src/sst39sf010.h diff --git a/src/Makefile.am b/src/Makefile.am index 9b2795b..7d2b106 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,7 @@ laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xe opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ +sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c sst39sf010.c tandy_eeprom.c tandy_rom.c \ t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 435aaf5..8414549 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -29,7 +29,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer38 sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ + sound_ym7128.o soundopenal.o sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ diff --git a/src/model.c b/src/model.c index d060d67..bed454f 100644 --- a/src/model.c +++ b/src/model.c @@ -56,6 +56,7 @@ #include "sound_ps1.h" #include "sound_pssj.h" #include "sound_sn76489.h" +#include "sst39sf010.h" #include "tandy_eeprom.h" #include "tandy_rom.h" #include "um8669f.h" @@ -675,6 +676,7 @@ void at_mvp3_init() mvp3_init(); vt82c586b_init(7, 8, 9, 10, 0); w83877tf_init(); + device_add(&sst_39sf010_device); } void model_init() diff --git a/src/sst39sf010.c b/src/sst39sf010.c new file mode 100644 index 0000000..57969b4 --- /dev/null +++ b/src/sst39sf010.c @@ -0,0 +1,218 @@ +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "sst39sf010.h" + +typedef struct sst_t +{ + int command_state; + int id_mode; + int erase; + int dirty; + + char flash_path[1024]; +} sst_t; + +#define SST_CHIP_ERASE 0x10 +#define SST_SECTOR_ERASE 0x30 +#define SST_ERASE 0x80 +#define SST_SET_ID_MODE 0x90 +#define SST_BYTE_PROGRAM 0xa0 +#define SST_CLEAR_ID_MODE 0xf0 + +static void set_id_mode(sst_t *sst); +static void clear_id_mode(sst_t *sst); + +static void sst_new_command(sst_t *sst, uint8_t val) +{ + switch (val) + { + case SST_CHIP_ERASE: + if (sst->erase) + memset(rom, 0xff, 0x20000); + sst->command_state = 0; + sst->erase = 0; + break; + + case SST_ERASE: + sst->command_state = 0; + sst->erase = 1; + break; + + case SST_SET_ID_MODE: + if (!sst->id_mode) + set_id_mode(sst); + sst->command_state = 0; + sst->erase = 0; + break; + + case SST_BYTE_PROGRAM: + sst->command_state = 3; + sst->erase = 0; + break; + + case SST_CLEAR_ID_MODE: + if (sst->id_mode) + clear_id_mode(sst); + sst->command_state = 0; + sst->erase = 0; + break; + + default: + sst->command_state = 0; + sst->erase = 0; + } +} + +static void sst_sector_erase(sst_t *sst, uint32_t addr) +{ +// pclog("SST sector erase %08x\n", addr); + memset(&rom[addr & 0x1f000], 0xff, 4096); + sst->dirty = 1; +} + +static uint8_t sst_read_id(uint32_t addr, void *p) +{ + if ((addr & 0xffff) == 0) + return 0xbf; /*SST*/ + else if ((addr & 0xffff) == 1) + return 0xb5; /*39SF010*/ + else + return 0xff; +// fatal("sst_read_id: addr=%08x\n", addr); +} + +static void sst_write(uint32_t addr, uint8_t val, void *p) +{ + sst_t *sst = (sst_t *)p; + +// pclog("sst_write: addr=%08x val=%02x state=%i\n", addr, val, sst->command_state); + switch (sst->command_state) + { + case 0: + if (val == 0xf0) + { + if (sst->id_mode) + clear_id_mode(sst); + } + else if ((addr & 0xffff) == 0x5555 && val == 0xaa) + sst->command_state = 1; + else + sst->command_state = 0; + break; + case 1: + if ((addr & 0xffff) == 0x2aaa && val == 0x55) + sst->command_state = 2; + else + sst->command_state = 0; + break; + case 2: + if ((addr & 0xffff) == 0x5555) + sst_new_command(sst, val); + else if (val == SST_SECTOR_ERASE && sst->erase) + { + sst_sector_erase(sst, addr); + sst->command_state = 0; + } + else + sst->command_state = 0; + break; + case 3: +// pclog("Byte program %08x %02x\n", addr, val); + rom[addr & 0x1ffff] = val; + sst->command_state = 0; + sst->dirty = 1; + break; + } +} + +static void set_id_mode(sst_t *sst) +{ + int c; + + for (c = 0; c < 8; c++) + { + mem_mapping_set_handler(&bios_mapping[c], + sst_read_id, NULL, NULL, + sst_write, NULL, NULL); + mem_mapping_set_p(&bios_mapping[c], sst); + mem_mapping_set_handler(&bios_high_mapping[c], + sst_read_id, NULL, NULL, + sst_write, NULL, NULL); + mem_mapping_set_p(&bios_high_mapping[c], sst); + } + sst->id_mode = 1; +} + +static void clear_id_mode(sst_t *sst) +{ + int c; + + for (c = 0; c < 8; c++) + { + mem_mapping_set_handler(&bios_mapping[c], + mem_read_bios, mem_read_biosw, mem_read_biosl, + sst_write, NULL, NULL); + mem_mapping_set_p(&bios_mapping[c], sst); + mem_mapping_set_handler(&bios_high_mapping[c], + mem_read_bios, mem_read_biosw, mem_read_biosl, + sst_write, NULL, NULL); + mem_mapping_set_p(&bios_high_mapping[c], sst); + } + sst->id_mode = 0; +} + +static void *sst_39sf010_init() +{ + FILE *f; + sst_t *sst = malloc(sizeof(sst_t)); + memset(sst, 0, sizeof(sst_t)); + + switch(romset) + { + case ROM_FIC_VA503P: + strcpy(sst->flash_path, "fic_va503p/"); + break; + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } + strcat(sst->flash_path, "flash.bin"); + f = romfopen(sst->flash_path, "rb"); + if (f) + { + fread(rom, 0x20000, 1, f); + fclose(f); + } + + clear_id_mode(sst); + + return sst; +} + +static void sst_39sf010_close(void *p) +{ + sst_t *sst = (sst_t *)p; + + if (sst->dirty) + { + FILE *f = romfopen(sst->flash_path, "wb"); + fwrite(rom, 0x20000, 1, f); + fclose(f); + } + + free(sst); +} + +device_t sst_39sf010_device = +{ + "SST 39SF010 Flash BIOS", + 0, + sst_39sf010_init, + sst_39sf010_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/sst39sf010.h b/src/sst39sf010.h new file mode 100644 index 0000000..97d4a63 --- /dev/null +++ b/src/sst39sf010.h @@ -0,0 +1 @@ +extern device_t sst_39sf010_device; From 584e67845beb50ea932f9f8163cf82e74976139b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 31 Mar 2019 18:21:56 +0100 Subject: [PATCH 0653/1050] Added ROL, ROR and NOP uops to ARM and ARM64 backends. --- src/codegen_backend_arm64_ops.c | 11 ++ src/codegen_backend_arm64_ops.h | 3 + src/codegen_backend_arm64_uops.c | 232 ++++++++++++++++++++++++++++++- src/codegen_backend_arm_ops.c | 29 ++++ src/codegen_backend_arm_ops.h | 4 + src/codegen_backend_arm_uops.c | 227 +++++++++++++++++++++++++++++- 6 files changed, 504 insertions(+), 2 deletions(-) diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index eaf5089..1bc49c0 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -91,6 +91,7 @@ #define OPCODE_ORR_ASR (0x154 << 21) #define OPCODE_ORR_LSL (0x150 << 21) #define OPCODE_ORR_LSR (0x152 << 21) +#define OPCODE_ORR_ROR (0x156 << 21) #define OPCODE_ORRX_LSL (0x550 << 21) #define OPCODE_SUB_LSL (0x258 << 21) #define OPCODE_SUB_LSR (0x25a << 21) @@ -164,6 +165,7 @@ #define OPCODE_NOP (0xd503201f) #define OPCODE_ORR_V (0x0ea01c00) #define OPCODE_RET (0xd65f0000) +#define OPCODE_ROR (0x1ac02c00) #define OPCODE_SADDLP_V2S_4H (0x0e602800) #define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) @@ -994,6 +996,10 @@ void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int { codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) { @@ -1092,6 +1098,11 @@ void host_arm64_RET(codeblock_t *block, int reg) codegen_addlong(block, OPCODE_RET | Rn(reg)); } +void host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +{ + codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +} + void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) { codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 42760dd..904aa6d 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -143,6 +143,7 @@ void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_re void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); +void host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data); void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); @@ -162,6 +163,8 @@ void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_RET(codeblock_t *block, int reg); +void host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg); + void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg); void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 0f56360..d7fe7f6 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1474,6 +1474,11 @@ static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2354,6 +2359,225 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_mov_imm(block, REG_TEMP2, 32); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_mov_imm(block, REG_TEMP2, 16); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + cs = cs; + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (!(uop->imm_data & 31)) + { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } + else + { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); + } + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if ((uop->imm_data & 15) == 0) + { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } + else + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } + else + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm64_ROR(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (!(uop->imm_data & 31)) + { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } + else + { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); + } + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if ((uop->imm_data & 15) == 0) + { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2847,6 +3071,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, @@ -2945,7 +3173,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index b6a6142..9be45f2 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -49,6 +49,7 @@ #define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) #define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) #define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) +#define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) #define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) #define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) #define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) @@ -177,10 +178,12 @@ #define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) #define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) #define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +#define SHIFT_ROR_IMM(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) #define SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x)) #define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x)) #define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x)) +#define SHIFT_ROR_REG(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_REG | Rs(x)) #define BFI_lsb(lsb) ((lsb) << 7) #define BFI_msb(msb) ((msb) << 16) @@ -695,6 +698,14 @@ void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int { codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); } +void host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); +} +void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +{ + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); +} void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { @@ -730,6 +741,24 @@ void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, i codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } +void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} +void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 3e930df..7627f51 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -89,6 +89,8 @@ void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift); void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); +void host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift); +void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm); void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm); @@ -106,6 +108,8 @@ void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, i #define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) #define host_arm_ORRVS_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_VS, dst_reg, src_reg, imm) +void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); +void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 402a7d7..12c2eb9 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -1595,6 +1595,11 @@ static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + static int codegen_OR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); @@ -2503,6 +2508,220 @@ static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (!(uop->imm_data & 31)) + { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } + else + { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); + } + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if ((uop->imm_data & 15) == 0) + { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } + else + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } + else + { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) + { + if (!(uop->imm_data & 31)) + { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } + else + { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); + } + } + else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) + { + if ((uop->imm_data & 15) == 0) + { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } + else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } + else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) + { + if ((uop->imm_data & 7) == 0) + { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } + else + { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + static int codegen_SAR(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); @@ -2997,6 +3216,10 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, [UOP_SHR & UOP_MASK] = codegen_SHR, [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, @@ -3095,7 +3318,9 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) From 3890ffdff05596f29837098ec1f8044c59275a2a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 31 Mar 2019 18:23:21 +0100 Subject: [PATCH 0654/1050] Fixed multiple definition of REG_SP in ARM64 backend. Fixes build warnings, also fixes Windows 3.x. --- src/codegen_backend_arm64.c | 46 ++++++++++++++++---------------- src/codegen_backend_arm64_defs.h | 2 +- src/codegen_backend_arm64_uops.c | 28 +++++++++---------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index 7497a0b..b85d3f9 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -114,7 +114,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); if (size != 1) host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); if (size == 1) host_arm64_call(block, (uintptr_t)readmembl); else if (size == 2) @@ -130,7 +130,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); else if (size == 8) host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); host_arm64_RET(block, REG_X30); } @@ -183,7 +183,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); if (size != 1) host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); if (size == 4 && is_float) host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); else if (size == 8) @@ -199,7 +199,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) else fatal("build_store_routine - unknown size %i\n", size); codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); host_arm64_RET(block, REG_X30); } @@ -318,12 +318,12 @@ void codegen_backend_init() host_arm64_call(block, x86gpf); codegen_exit_rout = &block_write_data[block_pos]; - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); host_arm64_RET(block, REG_X30); block_write_data = NULL; @@ -349,12 +349,12 @@ void codegen_backend_prologue(codeblock_t *block) /*Entry code*/ - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16); - host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -64); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t)&cpu_state); @@ -362,18 +362,18 @@ void codegen_backend_prologue(codeblock_t *block) { host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); } } void codegen_backend_epilogue(codeblock_t *block) { - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); host_arm64_RET(block, REG_X30); codegen_allocator_clean_blocks(block->head_mem_block); diff --git a/src/codegen_backend_arm64_defs.h b/src/codegen_backend_arm64_defs.h index a265016..2df1e9f 100644 --- a/src/codegen_backend_arm64_defs.h +++ b/src/codegen_backend_arm64_defs.h @@ -97,7 +97,7 @@ #define REG_V30 30 #define REG_V31 31 -#define REG_SP 31 +#define REG_XSP 31 #define REG_ARG0 REG_X0 #define REG_ARG1 REG_X1 diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index d7fe7f6..458025b 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -3222,7 +3222,7 @@ void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) } void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); @@ -3230,7 +3230,7 @@ void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int } void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); @@ -3238,7 +3238,7 @@ void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); @@ -3282,7 +3282,7 @@ void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) } void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); @@ -3290,7 +3290,7 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int } void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); @@ -3298,7 +3298,7 @@ void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); @@ -3316,47 +3316,47 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { if (in_range12_h(stack_offset)) - host_arm64_LDRH_IMM(block, host_reg, REG_SP, stack_offset); + host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); else fatal("codegen_direct_read_32_stack - not in range\n"); } void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { if (in_range12_w(stack_offset)) - host_arm64_LDR_IMM_W(block, host_reg, REG_SP, stack_offset); + host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); else fatal("codegen_direct_read_32_stack - not in range\n"); } void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { if (in_range12_q(stack_offset)) - host_arm64_LDR_IMM_X(block, host_reg, REG_SP, stack_offset); + host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); else fatal("codegen_direct_read_pointer_stack - not in range\n"); } void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm64_LDR_IMM_F64(block, host_reg, REG_SP, stack_offset); + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { if (in_range12_w(stack_offset)) - host_arm64_STR_IMM_W(block, host_reg, REG_SP, stack_offset); + host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); else fatal("codegen_direct_write_32_stack - not in range\n"); } void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm64_STR_IMM_F64(block, host_reg, REG_SP, stack_offset); + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm64_STR_IMM_F64(block, host_reg, REG_SP, stack_offset); + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } void codegen_set_jump_dest(codeblock_t *block, void *p) From 7a68bca85f4f5400f19a6a4fbef8aeb28e02f6bf Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 31 Mar 2019 18:23:34 +0100 Subject: [PATCH 0655/1050] Fixed some ARM64 build warnings. --- src/codegen_backend_arm64.c | 26 +++++++++++++------------- src/codegen_backend_arm64_ops.h | 4 ++++ src/codegen_backend_arm64_uops.c | 2 +- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index b85d3f9..eb50aa6 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -68,7 +68,7 @@ int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = static void build_load_routine(codeblock_t *block, int size, int is_float) { uint32_t *branch_offset; - uint8_t *misaligned_offset; + uint32_t *misaligned_offset; int offset; /*In - W0 = address @@ -116,13 +116,13 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); if (size == 1) - host_arm64_call(block, (uintptr_t)readmembl); + host_arm64_call(block, (void *)readmembl); else if (size == 2) - host_arm64_call(block, (uintptr_t)readmemwl); + host_arm64_call(block, (void *)readmemwl); else if (size == 4) - host_arm64_call(block, (uintptr_t)readmemll); + host_arm64_call(block, (void *)readmemll); else if (size == 8) - host_arm64_call(block, (uintptr_t)readmemql); + host_arm64_call(block, (void *)readmemql); else fatal("build_load_routine - unknown size %i\n", size); codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); @@ -136,8 +136,8 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) static void build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; int offset; /*In - R0 = address, R1 = data @@ -189,13 +189,13 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) else if (size == 8) host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); if (size == 1) - host_arm64_call(block, (uintptr_t)writemembl); + host_arm64_call(block, (void *)writemembl); else if (size == 2) - host_arm64_call(block, (uintptr_t)writememwl); + host_arm64_call(block, (void *)writememwl); else if (size == 4) - host_arm64_call(block, (uintptr_t)writememll); + host_arm64_call(block, (void *)writememll); else if (size == 8) - host_arm64_call(block, (uintptr_t)writememql); + host_arm64_call(block, (void *)writememql); else fatal("build_store_routine - unknown size %i\n", size); codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); @@ -242,7 +242,7 @@ static void build_fp_round_routine(codeblock_t *block, int is_quad) host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); host_arm64_BR(block, REG_TEMP2); - jump_table = &block_write_data[block_pos]; + jump_table = (uint64_t *)&block_write_data[block_pos]; block_pos += 4*8; jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even @@ -315,7 +315,7 @@ void codegen_backend_init() codegen_gpf_rout = &block_write_data[block_pos]; host_arm64_mov_imm(block, REG_ARG0, 0); host_arm64_mov_imm(block, REG_ARG1, 0); - host_arm64_call(block, x86gpf); + host_arm64_call(block, (void *)x86gpf); codegen_exit_rout = &block_write_data[block_pos]; host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index 904aa6d..2a514ed 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -82,6 +82,8 @@ void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg); void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); @@ -112,6 +114,8 @@ void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg); +void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg); + void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 458025b..5a92749 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1396,7 +1396,7 @@ static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { - uint8_t *branch_offset; + uint32_t *branch_offset; /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); From a0ab14f56f3ce36bc2b498a9f603f70ee57f66b1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 1 Apr 2019 21:23:09 +0100 Subject: [PATCH 0656/1050] When unrolling a loop, set op_32, ea_seg and ssegs to the correct values at the start of the loop. Fixes mode setting on Bahamas 64 and most likely some other bugs. --- src/codegen.c | 46 +++++++++++++++++++++++++++++++++++++++ src/codegen.h | 2 ++ src/codegen_ir.c | 9 ++++++-- src/codegen_ir.h | 2 +- src/codegen_ops_helpers.c | 20 ++++++----------- 5 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 5ffa2cc..503a6c4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -13,6 +13,41 @@ #include "codegen_ops.h" #include "codegen_ops_helpers.h" +#define MAX_INSTRUCTION_COUNT 100 + +static struct +{ + uint32_t pc; + int op_ssegs; + x86seg *op_ea_seg; + uint32_t op_32; + int first_uop; +} codegen_instructions[MAX_INSTRUCTION_COUNT]; + +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction) +{ + int c; + + for (c = 0; c < block->ins; c++) + { + if (codegen_instructions[c].pc == pc) + { + *first_instruction = c; + return codegen_instructions[c].first_uop; + } + } + + *first_instruction = block->ins; + return -1; +} + +void codegen_set_loop_start(ir_data_t *ir, int first_instruction) +{ + uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); + uop_MOV_PTR(ir, IREG_ea_seg, (void *)codegen_instructions[first_instruction].op_ea_seg); + uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); +} + int has_ea; codeblock_t *codeblock; @@ -551,6 +586,12 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t } generate_call: + codegen_instructions[block->ins].pc = cpu_state.oldpc; + codegen_instructions[block->ins].op_ssegs = last_op_ssegs; + codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; + codegen_instructions[block->ins].op_32 = last_op_32; + codegen_instructions[block->ins].first_uop = ir->wr_pos; + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); codegen_accumulate(ACCREG_ins, 1); @@ -646,6 +687,11 @@ generate_call: codegen_endpc = (cs + cpu_state.pc) + 8; + block->ins++; + + if (block->ins >= 50) + CPU_BLOCK_END(); + return; } } diff --git a/src/codegen.h b/src/codegen.h index 9365e44..0f246b3 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -404,6 +404,8 @@ extern int codegen_in_recompile; void codegen_generate_reset(); +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction); +void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); #ifdef DEBUG_EXTRA extern uint32_t instr_counts[256*256]; diff --git a/src/codegen_ir.c b/src/codegen_ir.c index e3a9377..d7e6157 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -9,6 +9,7 @@ extern int has_ea; static ir_data_t ir_block; static int codegen_unroll_start, codegen_unroll_count; +static int codegen_unroll_first_instruction; ir_data_t *codegen_ir_init() { @@ -20,10 +21,11 @@ ir_data_t *codegen_ir_init() return &ir_block; } -void codegen_ir_set_unroll(int count, int start) +void codegen_ir_set_unroll(int count, int start, int first_instruction) { codegen_unroll_count = count; codegen_unroll_start = start; + codegen_unroll_first_instruction = first_instruction; } static void duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) @@ -59,7 +61,10 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) if (codegen_unroll_count) { int unroll_count; - int unroll_end = ir->wr_pos; + int unroll_end; + + codegen_set_loop_start(ir, codegen_unroll_first_instruction); + unroll_end = ir->wr_pos; for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) { diff --git a/src/codegen_ir.h b/src/codegen_ir.h index b560256..6274816 100644 --- a/src/codegen_ir.h +++ b/src/codegen_ir.h @@ -2,5 +2,5 @@ ir_data_t *codegen_ir_init(); -void codegen_ir_set_unroll(int count, int start); +void codegen_ir_set_unroll(int count, int start, int first_instruction); void codegen_ir_compile(ir_data_t *ir, codeblock_t *block); diff --git a/src/codegen_ops_helpers.c b/src/codegen_ops_helpers.c index fdde53b..903a0e5 100644 --- a/src/codegen_ops_helpers.c +++ b/src/codegen_ops_helpers.c @@ -33,21 +33,13 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, { int start; int max_unroll; + int first_instruction; /*Check that dest instruction was actually compiled into block*/ - for (start = 0; start < ir->wr_pos; start++) - { -// pclog(" uOP %i %08x %08x\n", c, ir->uops[c].pc, dest_addr); - if (ir->uops[start].pc == dest_addr) - break; - if (ir->uops[start].pc > dest_addr) - { -// pclog("Went past dest_addr. start_pc=%08x end_pc=%08x dest_pc=%08x wr_pos=%i loop_size=%i\n", block->pc-cs, next_pc, dest_addr, ir->wr_pos, ir->wr_pos-start); - return 0; - } - } + start = codegen_get_instruction_uop(block, dest_addr, &first_instruction); + /*Couldn't find any uOPs corresponding to the destination instruction*/ - if (start == ir->wr_pos) + if (start == -1) { /*Is instruction jumping to itself?*/ if (dest_addr != cpu_state.oldpc) @@ -55,6 +47,8 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, // pclog("Couldn't find start. start_pc=%08x end_pc=%08x dest_pc=%08x wr_pos=%i loop_size=%i\n", block->pc-cs, next_pc, dest_addr, ir->wr_pos, ir->wr_pos-start); return 0; } + else + start = ir->wr_pos; } max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6); @@ -65,7 +59,7 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, if (max_unroll <= 1) return 0; - codegen_ir_set_unroll(max_unroll, start); + codegen_ir_set_unroll(max_unroll, start, first_instruction); return 1; } From 7f99cb7fb17bf52eb12f6e54d0e6464926c51eff Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 1 Apr 2019 21:24:32 +0100 Subject: [PATCH 0657/1050] Use correct value for MAX_INSTRUCTION_COUNT. --- src/codegen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 503a6c4..ba33e47 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -13,7 +13,7 @@ #include "codegen_ops.h" #include "codegen_ops_helpers.h" -#define MAX_INSTRUCTION_COUNT 100 +#define MAX_INSTRUCTION_COUNT 50 static struct { @@ -689,7 +689,7 @@ generate_call: block->ins++; - if (block->ins >= 50) + if (block->ins >= MAX_INSTRUCTION_COUNT) CPU_BLOCK_END(); return; @@ -761,7 +761,7 @@ generate_call: block->ins++; - if (block->ins >= 50) + if (block->ins >= MAX_INSTRUCTION_COUNT) CPU_BLOCK_END(); codegen_endpc = (cs + cpu_state.pc) + 8; From 8a91051e25b958c5d2111aa231d17411a6c9694f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 1 Apr 2019 21:38:21 +0100 Subject: [PATCH 0658/1050] SST flash now keeps local copy of flash data to write back on device close. Prevents flash corruption when switching models and PCem loads the new BIOS before writing out the old flash. --- src/sst39sf010.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sst39sf010.c b/src/sst39sf010.c index 57969b4..8acb664 100644 --- a/src/sst39sf010.c +++ b/src/sst39sf010.c @@ -12,6 +12,7 @@ typedef struct sst_t int dirty; char flash_path[1024]; + uint8_t data[0x20000]; } sst_t; #define SST_CHIP_ERASE 0x10 @@ -30,7 +31,10 @@ static void sst_new_command(sst_t *sst, uint8_t val) { case SST_CHIP_ERASE: if (sst->erase) + { memset(rom, 0xff, 0x20000); + memset(sst->data, 0xff, 0x20000); + } sst->command_state = 0; sst->erase = 0; break; @@ -69,6 +73,7 @@ static void sst_sector_erase(sst_t *sst, uint32_t addr) { // pclog("SST sector erase %08x\n", addr); memset(&rom[addr & 0x1f000], 0xff, 4096); + memset(&sst->data[addr & 0x1f000], 0xff, 4096); sst->dirty = 1; } @@ -121,6 +126,7 @@ static void sst_write(uint32_t addr, uint8_t val, void *p) case 3: // pclog("Byte program %08x %02x\n", addr, val); rom[addr & 0x1ffff] = val; + sst->data[addr & 0x1ffff] = val; sst->command_state = 0; sst->dirty = 1; break; @@ -184,6 +190,7 @@ static void *sst_39sf010_init() fread(rom, 0x20000, 1, f); fclose(f); } + memcpy(sst->data, rom, 0x20000); clear_id_mode(sst); @@ -197,7 +204,7 @@ static void sst_39sf010_close(void *p) if (sst->dirty) { FILE *f = romfopen(sst->flash_path, "wb"); - fwrite(rom, 0x20000, 1, f); + fwrite(sst->data, 0x20000, 1, f); fclose(f); } From fc369826a42b92e6a7abc5aae2d7aaaf57d6c1b4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 2 Apr 2019 20:40:40 +0100 Subject: [PATCH 0659/1050] Fix start address when calculating block size. Fixes rendering issues in Wolfenstein 3D. --- src/386_dynarec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index d904612..eaa2041 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -401,7 +401,7 @@ void exec386_dynarec(int cycs) } else if (valid_block && !cpu_state.abrt) { - uint32_t start_pc = cpu_state.pc; + uint32_t start_pc = cs+cpu_state.pc; const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; cpu_block_end = 0; @@ -447,7 +447,7 @@ void exec386_dynarec(int cycs) 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) >= max_block_size) + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) CPU_BLOCK_END(); if (trap) @@ -477,7 +477,7 @@ void exec386_dynarec(int cycs) else if (!cpu_state.abrt) { /*Mark block but do not recompile*/ - uint32_t start_pc = cpu_state.pc; + uint32_t start_pc = cs+cpu_state.pc; const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; cpu_block_end = 0; @@ -519,7 +519,7 @@ void exec386_dynarec(int cycs) 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) >= max_block_size) + if (((cs+cpu_state.pc) - start_pc) >= max_block_size) CPU_BLOCK_END(); if (trap) From 35962551dd46621920e8c88d7067086b2ec416fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 3 Apr 2019 21:32:48 +0100 Subject: [PATCH 0660/1050] Added emulation of Packard Bell PB410A, along with the built-in Headland HT216-32 video. --- src/Makefile.am | 4 +- src/Makefile.linux32-wx-sdl2 | 4 +- src/Makefile.linux64-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2 | 6 +- src/Makefile.mingw-wx-sdl2-network | 4 +- src/Makefile.osx64-wx-sdl2 | 4 +- src/acc2036.c | 3 + src/acc2168.c | 119 ++++ src/acc2168.h | 1 + src/acc3221.c | 122 ++++ src/acc3221.h | 1 + src/ibm.h | 1 + src/mem_bios.c | 8 + src/model.c | 12 + src/nvr.c | 2 + src/vid_ht216.c | 873 +++++++++++++++++++++++++++++ src/vid_ht216.h | 1 + src/video.c | 22 + 18 files changed, 1178 insertions(+), 13 deletions(-) create mode 100644 src/acc2168.c create mode 100644 src/acc2168.h create mode 100644 src/acc3221.c create mode 100644 src/acc3221.h create mode 100644 src/vid_ht216.c create mode 100644 src/vid_ht216.h diff --git a/src/Makefile.am b/src/Makefile.am index 0aa3d5f..fa29f7d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2036.c acc2168.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430hx.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ @@ -36,7 +36,7 @@ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_e t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ -vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \ +vid_ht216.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.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_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 490e946..f7f89dd 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -16,7 +16,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 4a330d6..a900867 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -16,7 +16,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index eb39856..a308211 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -3,10 +3,10 @@ CPP = g++ CC = gcc WINDRES = windres.exe WXVERSION = 31 -WXINCLUDE = C:/MinGW/include/wx/ +WXINCLUDE = e:/MinGWget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ @@ -17,7 +17,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index f811df3..b062cc9 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ @@ -17,7 +17,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index a2e0a8e..2a99c06 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -3,7 +3,7 @@ CPP = g++ CC = gcc WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -15,7 +15,7 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ diff --git a/src/acc2036.c b/src/acc2036.c index bf511fb..faacd9d 100644 --- a/src/acc2036.c +++ b/src/acc2036.c @@ -88,6 +88,9 @@ static uint8_t acc2036_read(uint16_t addr, void *p) { if (!(addr & 1)) return acc2036.reg_idx; + + if (acc2036.reg_idx >= 0xbc) + return 0xff; return acc2036.regs[acc2036.reg_idx]; } diff --git a/src/acc2168.c b/src/acc2168.c new file mode 100644 index 0000000..e6ab7dd --- /dev/null +++ b/src/acc2168.c @@ -0,0 +1,119 @@ +#include "ibm.h" +#include "acc2168.h" +#include "cpu.h" +#include "io.h" +#include "mem.h" +#include "x86.h" + +static struct +{ + int reg_idx; + uint8_t regs[256]; + uint8_t port_62; +} acc2168; + +static void acc2168_shadow_recalc() +{ + if (acc2168.regs[0x02] & 8) + { + switch (acc2168.regs[0x02] & 0x30) + { + case 0x00: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x20: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x30: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + } + } + else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + + if (acc2168.regs[0x02] & 4) + { + switch (acc2168.regs[0x02] & 0x30) + { + case 0x00: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x20: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x30: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + } + } + else + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + +static void acc2168_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("acc2168_write: addr=%04x val=%02x\n", addr, val); + if (!(addr & 1)) + acc2168.reg_idx = val; + else + { + acc2168.regs[acc2168.reg_idx] = val; +// pclog("acc2168_write: idx=%02x val=%02x %04x:%04x\n", acc2168.reg_idx, val, CS,cpu_state.pc); + + switch (acc2168.reg_idx) + { + case 0x02: + acc2168_shadow_recalc(); + break; + } + } +} + +static uint8_t acc2168_read(uint16_t addr, void *p) +{ + if (!(addr & 1)) + return acc2168.reg_idx; + +// pclog("acc2168_read: idx=%02x val=%02x\n", acc2168.reg_idx, acc2168.regs[acc2168.reg_idx]); + return acc2168.regs[acc2168.reg_idx]; +} + +static uint8_t port78_read(uint16_t addr, void *p) +{ + return 0; +} + +static uint8_t port92_read(uint16_t addr, void *p) +{ + return acc2168.port_62 | 0xfc; +} + +static void port92_write(uint16_t addr, uint8_t val, void *p) +{ + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~acc2168.port_62 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + acc2168.port_62 = val | 0xfC; +} + +void acc2168_init() +{ + memset(&acc2168, 0, sizeof(acc2168)); + io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, NULL); + io_sethandler(0x0078, 0x0001, port78_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, port92_read, NULL, NULL, port92_write, NULL, NULL, NULL); +} diff --git a/src/acc2168.h b/src/acc2168.h new file mode 100644 index 0000000..93515ee --- /dev/null +++ b/src/acc2168.h @@ -0,0 +1 @@ +void acc2168_init(); diff --git a/src/acc3221.c b/src/acc3221.c new file mode 100644 index 0000000..38c6fa9 --- /dev/null +++ b/src/acc3221.c @@ -0,0 +1,122 @@ +#include "ibm.h" +#include "acc3221.h" +#include "fdc.h" +#include "ide.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" + +static struct +{ + int reg_idx; + uint8_t regs[256]; +} acc3221; + +#define REG_BE_LPT1_DISABLE (1 << 4) + +#define REG_DB_SERIAL1_DISABLE (1 << 4) +#define REG_DB_SERIAL2_DISABLE (1 << 1) + +#define REG_DE_SIRQ3_SOURCE (3 << 6) +#define REG_DE_SIRQ3_SERIAL1 (1 << 6) +#define REG_DE_SIRQ3_SERIAL2 (3 << 6) + +#define REG_DE_SIRQ4_SOURCE (3 << 4) +#define REG_DE_SIRQ4_SERIAL1 (1 << 4) +#define REG_DE_SIRQ4_SERIAL2 (3 << 4) + +#define REG_FB_FDC_DISABLE (1 << 1) + +#define REG_FE_IDE_DISABLE (1 << 1) + +static void acc3221_write(uint16_t addr, uint8_t val, void *p) +{ + if (!(addr & 1)) + acc3221.reg_idx = val; + else + { + acc3221.regs[acc3221.reg_idx] = val; +// pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins); + + if (acc3221.reg_idx >= 0xbc) + { +// pclog("Write ACC3221 R%02x %02x %04x:%04x %i\n", acc3221.reg_idx, val, CS,cpu_state.pc, ins); + fdc_remove(); + if (!(acc3221.regs[0xfb] & REG_FB_FDC_DISABLE)) + fdc_add(); + + serial1_remove(); + if (!(acc3221.regs[0xdb] & REG_DB_SERIAL1_DISABLE)) + { + uint16_t addr = (acc3221.regs[0xdc] & 0x7f) << 2; + + if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL1) + { +// pclog("COM1 addr %03x IRQ 3\n", addr); + serial1_set(addr, 3); + } + else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL1) + { +// pclog("COM1 addr %03x IRQ 4\n", addr); + serial1_set(addr, 4); + } +// else +// pclog("COM1 addr %03x no IRQ\n", addr); + } +// else +// pclog("COM1 disabled\n"); + + serial2_remove(); + if (!(acc3221.regs[0xdb] & REG_DB_SERIAL2_DISABLE)) + { + uint16_t addr = (acc3221.regs[0xdd] & 0x7f) << 2; + + if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL2) + { +// pclog("COM2 addr %03x IRQ 3\n", addr); + serial2_set(addr, 3); + } + else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL2) + { +// pclog("COM2 addr %03x IRQ 4\n", addr); + serial2_set(addr, 4); + } +// else +// pclog("COM2 addr %03x no IRQ\n", addr); + } +// else +// pclog("COM2 disabled\n"); + + lpt1_remove(); + lpt2_remove(); + if (!(acc3221.regs[0xbe] & REG_BE_LPT1_DISABLE)) + { +// pclog("LPT1 addr %03x\n", acc3221.regs[0xbf] << 2); + lpt1_init(acc3221.regs[0xbf] << 2); + } +// else +// pclog("LPT1 disabled\n"); + + ide_pri_disable(); + if (!(acc3221.regs[0xfe] & REG_FE_IDE_DISABLE)) + ide_pri_enable(); + } + } +} + +static uint8_t acc3221_read(uint16_t addr, void *p) +{ + if (!(addr & 1)) + return acc3221.reg_idx; + + if (acc3221.reg_idx < 0xbc) + return 0xff; + + return acc3221.regs[acc3221.reg_idx]; +} + +void acc3221_init() +{ + memset(&acc3221, 0, sizeof(acc3221)); + io_sethandler(0x00f2, 0x0002, acc3221_read, NULL, NULL, acc3221_write, NULL, NULL, NULL); +} diff --git a/src/acc3221.h b/src/acc3221.h new file mode 100644 index 0000000..95824ec --- /dev/null +++ b/src/acc3221.h @@ -0,0 +1 @@ +void acc3221_init(); diff --git a/src/ibm.h b/src/ibm.h index 702d93e..e7dca29 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -467,6 +467,7 @@ enum ROM_IBMPS2_M70_TYPE4, ROM_TULIP_TC7, ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */ + ROM_PB410A, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 143490c..c49271e 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -965,6 +965,14 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; + + case ROM_PB410A: + f = romfopen("pb410a/PB410A.080337.4ABF.U25.bin","rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 2c898b4..fa7599c 100644 --- a/src/model.c +++ b/src/model.c @@ -5,6 +5,8 @@ #include "mouse.h" #include "acc2036.h" +#include "acc2168.h" +#include "acc3221.h" #include "acer386sx.h" #include "ali1429.h" #include "amstrad.h" @@ -107,6 +109,7 @@ void xt_t1000_init(); void xt_t1200_init(); void at_sl82c460_init(); void at_zappa_init(); +void at_pb410a_init(); void at_pb520r_init(); void at_pb570_init(); void compaq_pip_init(); @@ -189,6 +192,7 @@ MODEL models[] = {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, {"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, + {"[486] Packard Bell PB410A", ROM_PB410A, "pb410a", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 64, 1, at_pb410a_init, NULL}, {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, {"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL}, @@ -591,6 +595,14 @@ void pb_l300sx_init() acc2036_init(); } +void at_pb410a_init() +{ + at_init(); + acc2168_init(); + acc3221_init(); +} + + void at_sis496_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 2585544..4857825 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -314,6 +314,7 @@ void loadnvr() case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break; case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break; case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "rb"); break; + case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -410,6 +411,7 @@ void savenvr() case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break; case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break; case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "wb"); break; + case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break; default: return; } diff --git a/src/vid_ht216.c b/src/vid_ht216.c new file mode 100644 index 0000000..16db980 --- /dev/null +++ b/src/vid_ht216.c @@ -0,0 +1,873 @@ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "video.h" +#include "vid_ht216.h" +#include "vid_svga.h" +#include "vid_svga_render.h" +#include "vid_unk_ramdac.h" + +typedef struct ht216_t +{ + svga_t svga; + + mem_mapping_t linear_mapping; + + rom_t bios_rom; + + uint32_t vram_mask; + + int ext_reg_enable; + int clk_sel; + + uint8_t read_bank_reg[2], write_bank_reg[2]; + uint32_t read_bank[2], write_bank[2]; + uint8_t misc; + + uint8_t bg_latch[8]; + + uint8_t ht_regs[256]; +} ht216_t; + +#define HT_MISC_PAGE_SEL (1 << 5) + +/*Shifts CPU VRAM read address by 3 bits, for use with fat pixel colour expansion*/ +#define HT_REG_C8_MOVSB (1 << 0) +#define HT_REG_C8_E256 (1 << 4) +#define HT_REG_C8_XLAM (1 << 6) + +#define HT_REG_CD_FP8PCEXP (1 << 1) +#define HT_REG_CD_BMSKSL (3 << 2) +#define HT_REG_CD_RMWMDE (1 << 5) +/*Use GDC data rotate as offset when reading VRAM data into latches*/ +#define HT_REG_CD_ASTODE (1 << 6) +#define HT_REG_CD_EXALU (1 << 7) + +#define HT_REG_E0_SBAE (1 << 7) + +#define HT_REG_F9_XPSEL (1 << 0) + +/*Enables A[14:15] of VRAM address in chain-4 modes*/ +#define HT_REG_FC_ECOLRE (1 << 2) + +#define HT_REG_FE_FBRC (1 << 1) +#define HT_REG_FE_FBMC (3 << 2) +#define HT_REG_FE_FBRSL (3 << 4) + +void ht216_remap(ht216_t *ht216); + +void ht216_out(uint16_t addr, uint8_t val, void *p); +uint8_t ht216_in(uint16_t addr, void *p); + +void ht216_out(uint16_t addr, uint8_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + uint8_t old; + +// pclog("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc); + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) + { + case 0x3c2: + ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2); + ht216->misc = val; + ht216_remap(ht216); + svga_recalctimings(&ht216->svga); + break; + + case 0x3c5: + if (svga->seqaddr == 4) + { + svga->chain4 = val & 8; + ht216_remap(ht216); + } + else if (svga->seqaddr == 6) + { + if (val == 0xea) + ht216->ext_reg_enable = 1; + else if (val == 0xae) + ht216->ext_reg_enable = 0; + } + else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) + { + ht216->ht_regs[svga->seqaddr & 0xff] = val; +// pclog("HT[%02x]=%02x %04x(%08x):%08x\n", svga->seqaddr, val, CS,cs,cpu_state.pc); + switch (svga->seqaddr & 0xff) + { + case 0x83: + svga->attraddr = val & 0x1f; + svga->attrff = (val & 0x80) ? 1 : 0; + break; + + case 0x94: + svga->hwcursor.addr = ((val << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2; + //pclog("cursor_addr = %05x\n", svga->hwcursor.addr); + break; + case 0x9c: case 0x9d: + svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8); + break; + case 0x9e: case 0x9f: + svga->hwcursor.y = ht216->ht_regs[0x9f] | ((ht216->ht_regs[0x9e] & 3) << 8); + break; + case 0xa0: + svga->la = val; + break; + case 0xa1: + svga->lb = val; + break; + case 0xa2: + svga->lc = val; + break; + case 0xa3: + svga->ld = val; + break; + case 0xa4: + ht216->clk_sel = (val >> 2) & 0xf; + svga->miscout = (svga->miscout & ~0xc) | ((ht216->clk_sel & 3) << 2); + break; + case 0xa5: + svga->hwcursor.ena = val & 0x80; + break; + case 0xe8: + ht216->read_bank_reg[0] = val; + ht216->write_bank_reg[0] = val; + break; + case 0xe9: + ht216->read_bank_reg[1] = val; + ht216->write_bank_reg[1] = val; + break; + case 0xf6: + svga->vram_display_mask = (val & 0x40) ? ht216->vram_mask : 0x3ffff; + break; + case 0xff: + svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2; + //pclog("cursor_addr = %05x\n", svga->hwcursor.addr); + break; + } + switch (svga->seqaddr & 0xff) + { + case 0xa4: case 0xf6: case 0xfc: + svga->fullchange = changeframecount; + svga_recalctimings(&ht216->svga); + break; + } + switch (svga->seqaddr & 0xff) + { + case 0xc8: case 0xc9: case 0xcf: + case 0xe0: case 0xe8: case 0xe9: + case 0xf6: case 0xf9: + ht216_remap(ht216); + break; + } + return; + } + break; + + case 0x3cf: + if (svga->gdcaddr == 6) + { + if (val & 8) + svga->banked_mask = 0x7fff; + else + svga->banked_mask = 0xffff; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + +// if (svga->crtcreg == 0xc) +// pclog("CRTC[C]=%02x %08x\n", val, svga->vram_display_mask); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + if (old != val) + { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + svga->fullchange = changeframecount; + svga_recalctimings(&ht216->svga); + } + } + break; + + case 0x46e8: + io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_disable(&ht216->svga.mapping); + mem_mapping_disable(&ht216->linear_mapping); + if (val & 8) + { + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_enable(&ht216->svga.mapping); + ht216_remap(ht216); + } + break; + } + svga_out(addr, val, svga); +} + +uint8_t ht216_in(uint16_t addr, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + +// if (addr != 0x3ba && addr != 0x3da) pclog("ht216 %i in %04X\n", svga->miscout & 1, addr); + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) + { + case 0x3c2: +// pclog("3C2 read\n"); + break; +// return 0x10; + + case 0x3c5: + if (svga->seqaddr == 6) + return ht216->ext_reg_enable; + if (svga->seqaddr >= 0x80) + { + if (ht216->ext_reg_enable) + { +// pclog("Read HT[%02x]=%02x\n", svga->seqaddr & 0xff, ht216->ht_regs[svga->seqaddr & 0xff]); + switch (svga->seqaddr & 0xff) + { + case 0x83: + if (svga->attrff) + return svga->attraddr | 0x80; + return svga->attraddr; + + case 0x8e: return 0x61; /*HT216-32*/ + case 0x8f: return 0x78; + + case 0xa0: + return svga->la; + case 0xa1: + return svga->lb; + case 0xa2: + return svga->lc; + case 0xa3: + return svga->ld; + } + return ht216->ht_regs[svga->seqaddr & 0xff]; + } + else + return 0xff; + } + break; + + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg == 0x1f) + return svga->crtc[0xc] ^ 0xea; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); +} + +void ht216_remap(ht216_t *ht216) +{ + svga_t *svga = &ht216->svga; + + mem_mapping_disable(&ht216->linear_mapping); + if (ht216->ht_regs[0xc8] & HT_REG_C8_XLAM) + { + uint32_t linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24); + + pclog("Linear base %08x\n", linear_base); + mem_mapping_set_addr(&ht216->linear_mapping, linear_base, 0x100000); + + /*Linear mapping enabled*/ + } + else + { + uint32_t read_offset = (ht216->ht_regs[0xf6] & 0xc) << 16; + uint32_t write_offset = (ht216->ht_regs[0xf6] & 0x3) << 18; + + if (svga->chain4 && (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) + { + if (ht216->misc & HT_MISC_PAGE_SEL) + { + read_offset |= (1 << 17); + write_offset |= (1 << 17); + } + if (ht216->ht_regs[0xf9] & HT_REG_F9_XPSEL) + { + read_offset |= (1 << 16); + write_offset |= (1 << 16); + } + } + ht216->read_bank[0] = read_offset + (ht216->read_bank_reg[0] << 12); + ht216->write_bank[0] = write_offset + (ht216->write_bank_reg[0] << 12); + if (ht216->ht_regs[0xe0] & HT_REG_E0_SBAE) + { + /*Split bank*/ + ht216->read_bank[1] = read_offset + (ht216->read_bank_reg[1] << 12); + ht216->write_bank[1] = write_offset + (ht216->write_bank_reg[1] << 12); + } + else + { + ht216->read_bank[1] = ht216->read_bank[0] + (svga->chain4 ? 0x8000 : 0x20000); + ht216->write_bank[1] = ht216->write_bank[0] + (svga->chain4 ? 0x8000 : 0x20000); + } + + if (!svga->chain4) + { + ht216->read_bank[0] >>= 2; + ht216->read_bank[1] >>= 2; + ht216->write_bank[0] >>= 2; + ht216->write_bank[1] >>= 2; + } + } +// pclog("Remap - chain4=%i gdc[6]=%02x read[0]=%05X write[0]=%05X read[1]=%05X write[1]=%05X\n", svga->chain4, svga->gdcreg[6], ht216->read_bank[0], ht216->write_bank[0], ht216->read_bank[1], ht216->write_bank[1]); +} + +void ht216_recalctimings(svga_t *svga) +{ + ht216_t *ht216 = (ht216_t *)svga->p; + +// pclog("clk_sel = %i\n", ht216->clk_sel); + switch (ht216->clk_sel) + { + case 5: svga->clock = cpuclock / 65000000.0; break; + case 6: svga->clock = cpuclock / 40000000.0; break; + case 10: svga->clock = cpuclock / 80000000.0; break; + } + svga->lowres = !(ht216->ht_regs[0xc8] & HT_REG_C8_E256); + svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); + svga->interlace = ht216->ht_regs[0xe0] & 1; + + if (svga->bpp == 8 && !svga->lowres) + svga->render = svga_render_8bpp_highres; +} + +static void ht216_hwcursor_draw(svga_t *svga, int displine) +{ +// ht216_t *ht216 = (ht216_t *)svga->p; + int x; + uint32_t dat[2]; + int offset = svga->hwcursor_latch.x + 32; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; + + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | + (svga->vram[svga->hwcursor_latch.addr+1] << 16) | + (svga->vram[svga->hwcursor_latch.addr+2] << 8) | + svga->vram[svga->hwcursor_latch.addr+3]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr+128] << 24) | + (svga->vram[svga->hwcursor_latch.addr+128+1] << 16) | + (svga->vram[svga->hwcursor_latch.addr+128+2] << 8) | + svga->vram[svga->hwcursor_latch.addr+128+3]; + + for (x = 0; x < 32; x++) + { + if (!(dat[0] & 0x80000000)) + ((uint32_t *)buffer32->line[displine])[offset + x] = 0; + if (dat[1] & 0x80000000) + ((uint32_t *)buffer32->line[displine])[offset + x] ^= 0xffffff; + + dat[0] <<= 1; + dat[1] <<= 1; + } + + svga->hwcursor_latch.addr += 4; + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; +} + +static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b) +{ + uint8_t val; + + switch (op) + { + case 0x0: val = 0; break; + case 0x1: val = ~(input_a | input_b); break; + case 0x2: val = input_a & ~input_b; break; + case 0x3: val = ~input_b; break; + case 0x4: val = ~input_a & input_b; break; + case 0x5: val = ~input_a; break; + case 0x6: val = input_a ^ input_b; break; + case 0x7: val = ~(input_a & input_b); break; + case 0x8: val = input_a & input_b; break; + case 0x9: val = ~(input_a ^ input_b); break; + case 0xa: val = input_a; break; + case 0xb: val = input_a | ~input_b; break; + case 0xc: val = input_b; break; + case 0xd: val = ~input_a | input_b; break; + case 0xe: val = input_a | input_b; break; + case 0xf: default: val = 0xff; break; + } + + return val; +} + +static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bit_mask, uint8_t cpu_dat_unexpanded, uint8_t rop_select) +{ + /*Input B = CD.5 + Input A = FE[3:2] + 00 = Set/Reset output mode + output = CPU-side ALU input + 01 = Solid fg/bg mode (3C4:FA/FB) + Bit mask = 3CF.F5 or CPU byte + 10 = Dithered fg (3CF:EC-EF) + 11 = RMW (dest data) (set if CD.5 = 1) + F/B ROP select = FE[5:4] + 00 = CPU byte + 01 = Bit mask (3CF:8) + 1x = (3C4:F5)*/ + svga_t *svga = &ht216->svga; + uint8_t input_a = 0, input_b = 0; + uint8_t fg, bg; + uint8_t output; + + if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/ + input_b = svga->vram[addr]; + else + input_b = ht216->bg_latch[addr & 7]; + + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) + { + case 0x00: + input_a = cpu_dat; + break; + case 0x04: + if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) + input_a = (cpu_dat_unexpanded & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + else + input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + break; + case 0x08: + input_a = ht216->ht_regs[0xec + (addr & 3)]; + break; + case 0x0c: + input_a = ht216->bg_latch[addr & 7]; + break; + } + + fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b); + bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); +// svga->vram[addr] + output = (fg & rop_select) | (bg & ~rop_select); + svga->vram[addr] = (svga->vram[addr] & ~bit_mask) | (output & bit_mask); +// pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr); + svga->changedvram[addr >> 12] = changeframecount; +} + +static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) +{ + /*Input B = CD.5 + Input A = FE[3:2] + 00 = Set/Reset output mode + output = CPU-side ALU input + 01 = Solid fg/bg mode (3C4:FA/FB) + Bit mask = 3CF.F5 or CPU byte + 10 = Dithered fg (3CF:EC-EF) + 11 = RMW (dest data) (set if CD.5 = 1) + F/B ROP select = FE[5:4] + 00 = CPU byte + 01 = Bit mask (3CF:8) + 1x = (3C4:F5) + */ + uint8_t bit_mask = 0, rop_select = 0; + svga_t *svga = &ht216->svga; + + addr &= 0xfffff; + +// pclog("%08X %02x %08x\n", addr, svga->gdcreg[6], svga->banked_mask); + + val = svga_rotate[svga->gdcreg[3] & 7][val]; + + switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) + { + case 0x00: + bit_mask = svga->gdcreg[8]; + break; + case 0x04: + bit_mask = val; + break; + case 0x08: case 0x0c: + bit_mask = ht216->ht_regs[0xf5]; + break; + } + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) + { + case 0x00: + rop_select = val; + break; + case 0x10: + rop_select = svga->gdcreg[8]; + break; + case 0x20: case 0x30: + rop_select = ht216->ht_regs[0xf5]; + break; + } + + if (ht216->ht_regs[0xcd] & HT_REG_CD_EXALU) /*Extended ALU*/ + { + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ + { + addr = (addr << 3) & 0xfffff; + ht216_dm_extalu_write(ht216, addr, (val & 0x80) ? 0xff : 0, (bit_mask & 0x80) ? 0xff : 0, val, (rop_select & 0x80) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, (bit_mask & 0x40) ? 0xff : 0, val, (rop_select & 0x40) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, (bit_mask & 0x20) ? 0xff : 0, val, (rop_select & 0x20) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, (bit_mask & 0x10) ? 0xff : 0, val, (rop_select & 0x10) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, (bit_mask & 0x08) ? 0xff : 0, val, (rop_select & 0x08) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, (bit_mask & 0x04) ? 0xff : 0, val, (rop_select & 0x04) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, (bit_mask & 0x02) ? 0xff : 0, val, (rop_select & 0x02) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, (bit_mask & 0x01) ? 0xff : 0, val, (rop_select & 0x01) ? 0xff : 0); + } + else + ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select); + } +} + +static void ht216_write(uint32_t addr, uint8_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + +/* if (ht216->ht_regs[0xcd]) + pclog("ht216_write: [CD]=%02x [FE]=%02x %08x %02x ", ht216->ht_regs[0xcd], ht216->ht_regs[0xfe], addr, val); + pclog("ht216_write : %05X %02X ", addr, val);*/ + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; +// pclog("phys_addr=%05x\n", addr); + if (!ht216->ht_regs[0xcd]) + svga_write_linear(addr, val, &ht216->svga); + else + ht216_write_common(ht216, addr, val); +} +static void ht216_writew(uint32_t addr, uint16_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; + if (!ht216->ht_regs[0xcd]) + svga_writew_linear(addr, val, &ht216->svga); + else + { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr+1, val >> 8); + } +} +static void ht216_writel(uint32_t addr, uint32_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; + if (!ht216->ht_regs[0xcd]) + svga_writel_linear(addr, val, &ht216->svga); + else + { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr+1, val >> 8); + ht216_write_common(ht216, addr+2, val >> 16); + ht216_write_common(ht216, addr+3, val >> 24); + } +} + +static void ht216_write_linear(uint32_t addr, uint8_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + if (!svga->chain4) /*Bits 16 and 17 of linear address seem to be unused in planar modes*/ + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + + if (!ht216->ht_regs[0xcd]) + svga_write_linear(addr, val, &ht216->svga); + else + ht216_write_common(ht216, addr, val); +} +static void ht216_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + if (!svga->chain4) + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + + if (!ht216->ht_regs[0xcd]) + svga_writew_linear(addr, val, &ht216->svga); + else + { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr+1, val >> 8); + } +} +static void ht216_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + if (!svga->chain4) + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + + if (!ht216->ht_regs[0xcd]) + svga_writel_linear(addr, val, &ht216->svga); + else + { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr+1, val >> 8); + ht216_write_common(ht216, addr+2, val >> 16); + ht216_write_common(ht216, addr+3, val >> 24); + } +} + +static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) +{ + svga_t *svga = &ht216->svga; + uint8_t temp, temp2, temp3, temp4; + int readplane = svga->readplane; + uint32_t latch_addr; + + if (ht216->ht_regs[0xc8] & HT_REG_C8_MOVSB) + addr <<= 3; +// pclog("%08X\n", addr); + + addr &= 0xfffff; + + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; + + egareads++; + + if (svga->chain4 || svga->fb_only) + { +// if (ht216->ht_regs[0xcd]) +// pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max); + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + latch_addr = (addr & svga->vram_mask) & ~7; + if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) + latch_addr += (svga->gdcreg[3] & 7); + ht216->bg_latch[0] = svga->vram[latch_addr]; + ht216->bg_latch[1] = svga->vram[latch_addr + 1]; + ht216->bg_latch[2] = svga->vram[latch_addr + 2]; + ht216->bg_latch[3] = svga->vram[latch_addr + 3]; + ht216->bg_latch[4] = svga->vram[latch_addr + 4]; + ht216->bg_latch[5] = svga->vram[latch_addr + 5]; + ht216->bg_latch[6] = svga->vram[latch_addr + 6]; + ht216->bg_latch[7] = svga->vram[latch_addr + 7]; + +/*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr, + ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], + ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ + + return svga->vram[addr & svga->vram_mask]; + } + else if (svga->chain2_read) + { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; + } + else + addr<<=2; + + addr &= svga->decode_mask; + + if (addr >= svga->vram_max) + return 0xff; + + addr &= svga->vram_mask; + + latch_addr = addr & ~7; + if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) + { + int offset = addr & 7; + + ht216->bg_latch[0] = svga->vram[latch_addr | offset]; + ht216->bg_latch[1] = svga->vram[latch_addr | ((offset + 1) & 7)]; + ht216->bg_latch[2] = svga->vram[latch_addr | ((offset + 2) & 7)]; + ht216->bg_latch[3] = svga->vram[latch_addr | ((offset + 3) & 7)]; + ht216->bg_latch[4] = svga->vram[latch_addr | ((offset + 4) & 7)]; + ht216->bg_latch[5] = svga->vram[latch_addr | ((offset + 5) & 7)]; + ht216->bg_latch[6] = svga->vram[latch_addr | ((offset + 6) & 7)]; + ht216->bg_latch[7] = svga->vram[latch_addr | ((offset + 7) & 7)]; + } + else + { + ht216->bg_latch[0] = svga->vram[latch_addr]; + ht216->bg_latch[1] = svga->vram[latch_addr | 1]; + ht216->bg_latch[2] = svga->vram[latch_addr | 2]; + ht216->bg_latch[3] = svga->vram[latch_addr | 3]; + ht216->bg_latch[4] = svga->vram[latch_addr | 4]; + ht216->bg_latch[5] = svga->vram[latch_addr | 5]; + ht216->bg_latch[6] = svga->vram[latch_addr | 6]; + ht216->bg_latch[7] = svga->vram[latch_addr | 7]; + } +/*pclog(" Read %02x %02x %02x %02x %02x %02x %02x %02x\n", + ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], + ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ + if (addr & 4) + { + svga->la = ht216->bg_latch[4]; + svga->lb = ht216->bg_latch[5]; + svga->lc = ht216->bg_latch[6]; + svga->ld = ht216->bg_latch[7]; + } + else + { + svga->la = ht216->bg_latch[0]; + svga->lb = ht216->bg_latch[1]; + svga->lc = ht216->bg_latch[2]; + svga->ld = ht216->bg_latch[3]; + } + if (svga->readmode) + { + temp = svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 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]; + +// return svga_read_linear(addr, &ht216->svga); +} +static uint8_t ht216_read(uint32_t addr, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + +// if (ht216->ht_regs[0xcd]) +// pclog("ht216_read: [CD]=%02x [FC]=%02x %08x\n", ht216->ht_regs[0xcd], ht216->ht_regs[0xfc], addr); +// pclog("ht216_read : %05X ", addr); + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->read_bank[(addr >> 15) & 1]; + + return ht216_read_common(ht216, addr); +} + +/*static uint16_t ht216_readw(uint32_t addr, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; + return svga_readw_linear(addr, &ht216->svga); +}*/ + +static uint8_t ht216_read_linear(uint32_t addr, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + + if (svga->chain4) + return ht216_read_common(ht216, addr); + else + return ht216_read_common(ht216, (addr & 0xffff) | ((addr & 0xc0000) >> 2)); +} + +void *ht216_init() +{ + ht216_t *ht216 = malloc(sizeof(ht216_t)); + svga_t *svga = &ht216->svga; + memset(ht216, 0, sizeof(ht216_t)); + + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + + svga_init(&ht216->svga, ht216, 1 << 20, /*1MB*/ + ht216_recalctimings, + ht216_in, ht216_out, + ht216_hwcursor_draw, + NULL); + svga->hwcursor.ysize = 32; + ht216->vram_mask = 0xfffff; + svga->decode_mask = 0xfffff; + + mem_mapping_set_handler(&ht216->svga.mapping, ht216_read, NULL/*ht216_readw*/, NULL, ht216_write, ht216_writew, ht216_writel); + mem_mapping_set_p(&ht216->svga.mapping, ht216); + mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, 0, &ht216->svga); + + svga->bpp = 8; + svga->miscout = 1; + + ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ + + return ht216; +} + +static void *ht216_pb410a_init() +{ + ht216_t *ht216 = ht216_init(); + + return ht216; +} + +void ht216_close(void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + + svga_close(&ht216->svga); + + free(ht216); +} + +void ht216_speed_changed(void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + + svga_recalctimings(&ht216->svga); +} + +void ht216_force_redraw(void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + + ht216->svga.fullchange = changeframecount; +} + +void ht216_add_status_info(char *s, int max_len, void *p) +{ + ht216_t *ht216 = (ht216_t *)p; + + svga_add_status_info(s, max_len, &ht216->svga); +} + +device_t ht216_32_pb410a_device = +{ + "Headland HT216-32 (Packard Bell PB410A)", + 0, + ht216_pb410a_init, + ht216_close, + NULL, + ht216_speed_changed, + ht216_force_redraw, + ht216_add_status_info +}; diff --git a/src/vid_ht216.h b/src/vid_ht216.h new file mode 100644 index 0000000..c5e7b3a --- /dev/null +++ b/src/vid_ht216.h @@ -0,0 +1 @@ +extern device_t ht216_32_pb410a_device; diff --git a/src/video.c b/src/video.c index dfe8e68..b0c8039 100644 --- a/src/video.c +++ b/src/video.c @@ -23,6 +23,7 @@ #include "vid_et4000w32.h" #include "vid_genius.h" #include "vid_hercules.h" +#include "vid_ht216.h" #include "vid_incolor.h" #include "vid_colorplus.h" #include "vid_mda.h" @@ -128,6 +129,7 @@ static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_pc425x = {VIDEO_BUS, 5, 5, 9, 20,20,30}; +static video_timings_t timing_pb410a = {VIDEO_BUS, 5, 5, 9, 20,20,30}; static video_timings_t timing_pb570 = {VIDEO_BUS, 4, 4, 8, 10,10,20}; static video_timings_t timing_pb520r = {VIDEO_BUS, 4, 4, 8, 10,10,20}; @@ -220,6 +222,9 @@ device_t *video_card_getdevice(int card) case ROM_ELX_PC425X: return &tgui9400cxi_elx_device; + case ROM_PB410A: + return &ht216_32_pb410a_device; + case ROM_PB570: return &gd5430_pb570_device; @@ -332,6 +337,7 @@ int video_is_mda() case ROM_T3100E: case ROM_T1000: case ROM_ELX_PC425X: + case ROM_PB410A: case ROM_PB570: case ROM_PB520R: return 0; @@ -371,6 +377,7 @@ int video_is_cga() case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: case ROM_ELX_PC425X: + case ROM_PB410A: case ROM_PB570: case ROM_PB520R: return 0; @@ -407,6 +414,7 @@ int video_is_ega_vga() case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: case ROM_ELX_PC425X: + case ROM_PB410A: case ROM_PB570: case ROM_PB520R: return 1; @@ -561,6 +569,11 @@ void video_updatetiming() timing = &timing_pc425x; break; + case ROM_PB410A: + if (gfxcard == GFX_BUILTIN) + timing = &timing_pb410a; + break; + case ROM_PB570: timing = &timing_pb570; break; @@ -733,6 +746,15 @@ void video_init() device_add(&tgui9400cxi_elx_device); return; + case ROM_PB410A: + device_add(&ht216_32_pb410a_device); + if (gfxcard != GFX_BUILTIN) + { + svga_set_override(svga_get_pri(), 1); + break; + } + return; + case ROM_PB570: device_add(&gd5430_pb570_device); if (gfxcard != GFX_BUILTIN) From 3fd56facb6cb487989644cf42318934ee444d4d7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 5 Apr 2019 17:25:34 +0100 Subject: [PATCH 0661/1050] Fixed Makefile typo introduced in 1211. --- src/Makefile.am | 2 +- src/Makefile.linux32-wx-sdl2 | 2 +- src/Makefile.linux64-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/Makefile.osx64-wx-sdl2 | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index fa29f7d..278330a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2036.c acc2168.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ +pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2168.c acc3221.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430hx.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index f7f89dd..6f20be2 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index a900867..3808ede 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -4,7 +4,7 @@ CC = gcc WXRC = wxrc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index b062cc9..4b1f767 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \ i430vx.o ide.o ide_atapi.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 \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 2a99c06..3f02351 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -3,7 +3,7 @@ CPP = g++ CC = gcc WXRC = wxrc CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2036.o acc2168.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ From d49aab778248c721c13237a41c10f6fe6e044e15 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 7 Apr 2019 21:54:47 +0100 Subject: [PATCH 0662/1050] Reworked HT216-32 banking code. Fixes graphics errors in Windows 3.x. --- src/vid_ht216.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/vid_ht216.c b/src/vid_ht216.c index 16db980..cc8e261 100644 --- a/src/vid_ht216.c +++ b/src/vid_ht216.c @@ -78,6 +78,8 @@ void ht216_out(uint16_t addr, uint8_t val, void *p) case 0x3c2: ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2); ht216->misc = val; + ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x20) | ((val & HT_MISC_PAGE_SEL) ? 0x20 : 0); + ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x20) | ((val & HT_MISC_PAGE_SEL) ? 0x20 : 0); ht216_remap(ht216); svga_recalctimings(&ht216->svga); break; @@ -145,6 +147,12 @@ void ht216_out(uint16_t addr, uint8_t val, void *p) break; case 0xf6: svga->vram_display_mask = (val & 0x40) ? ht216->vram_mask : 0x3ffff; + ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0xc0) | ((val & 0xc) << 4); + ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0xc0) | ((val & 0x3) << 6); + break; + case 0xf9: + ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); + ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); break; case 0xff: svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2; @@ -296,29 +304,24 @@ void ht216_remap(ht216_t *ht216) } else { - uint32_t read_offset = (ht216->ht_regs[0xf6] & 0xc) << 16; - uint32_t write_offset = (ht216->ht_regs[0xf6] & 0x3) << 18; + uint8_t read_bank_reg[2] = {ht216->read_bank_reg[0], ht216->read_bank_reg[1]}; + uint8_t write_bank_reg[2] = {ht216->write_bank_reg[0], ht216->write_bank_reg[1]}; - if (svga->chain4 && (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) + if (!svga->chain4 || !(ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) { - if (ht216->misc & HT_MISC_PAGE_SEL) - { - read_offset |= (1 << 17); - write_offset |= (1 << 17); - } - if (ht216->ht_regs[0xf9] & HT_REG_F9_XPSEL) - { - read_offset |= (1 << 16); - write_offset |= (1 << 16); - } + read_bank_reg[0] &= ~0x30; + read_bank_reg[1] &= ~0x30; + write_bank_reg[0] &= ~0x30; + write_bank_reg[1] &= ~0x30; } - ht216->read_bank[0] = read_offset + (ht216->read_bank_reg[0] << 12); - ht216->write_bank[0] = write_offset + (ht216->write_bank_reg[0] << 12); + + ht216->read_bank[0] = read_bank_reg[0] << 12; + ht216->write_bank[0] = write_bank_reg[0] << 12; if (ht216->ht_regs[0xe0] & HT_REG_E0_SBAE) { /*Split bank*/ - ht216->read_bank[1] = read_offset + (ht216->read_bank_reg[1] << 12); - ht216->write_bank[1] = write_offset + (ht216->write_bank_reg[1] << 12); + ht216->read_bank[1] = read_bank_reg[1] << 12; + ht216->write_bank[1] = write_bank_reg[1] << 12; } else { @@ -334,7 +337,7 @@ void ht216_remap(ht216_t *ht216) ht216->write_bank[1] >>= 2; } } -// pclog("Remap - chain4=%i gdc[6]=%02x read[0]=%05X write[0]=%05X read[1]=%05X write[1]=%05X\n", svga->chain4, svga->gdcreg[6], ht216->read_bank[0], ht216->write_bank[0], ht216->read_bank[1], ht216->write_bank[1]); +// pclog("Remap - chain4=%i [e0]=%02x [e8]=%02x [e9]=%02x [f6]=%02x [fc]=%02x [f9]=%02x misc=%02x gdc[6]=%02x read[0]=%05X write[0]=%05X read[1]=%05X write[1]=%05X\n", svga->chain4, ht216->ht_regs[0xe0], ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], ht216->ht_regs[0xf6], ht216->ht_regs[0xfc], ht216->ht_regs[0xf9], ht216->misc, svga->gdcreg[6], ht216->read_bank[0], ht216->write_bank[0], ht216->read_bank[1], ht216->write_bank[1]); } void ht216_recalctimings(svga_t *svga) From a5fc447950713eafb9e573e934737a530dfc78fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Apr 2019 20:04:38 +0100 Subject: [PATCH 0663/1050] Implement non-extended-ALU extended writes on HT216-32. Fixes Windows 3.1 built-in Video 7 drivers. --- src/vid_ht216.c | 317 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 285 insertions(+), 32 deletions(-) diff --git a/src/vid_ht216.c b/src/vid_ht216.c index cc8e261..ef86782 100644 --- a/src/vid_ht216.c +++ b/src/vid_ht216.c @@ -421,6 +421,233 @@ static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b) return val; } +static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded) +{ + svga_t *svga = &ht216->svga; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; + uint8_t fg_data[4] = {0,0,0,0}; + + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if (svga->chain4 || svga->fb_only) + { + writemask2=1<<(addr&3); + addr&=~3; + } + else if (svga->chain2_write) + { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } + else + { + addr<<=2; + } + if (addr >= svga->vram_max) + return; + + svga->changedvram[addr >> 12]=changeframecount; + + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) + { + case 0x00: + fg_data[0] = fg_data[1] = fg_data[2] = fg_data[3] = cpu_dat; + break; + case 0x04: + if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) + { + if (addr & 4) + { + fg_data[0] = (cpu_dat_unexpanded & (1 << (((addr + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[1] = (cpu_dat_unexpanded & (1 << (((addr + 5) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[2] = (cpu_dat_unexpanded & (1 << (((addr + 6) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[3] = (cpu_dat_unexpanded & (1 << (((addr + 7) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + } + else + { + fg_data[0] = (cpu_dat_unexpanded & (1 << (((addr + 0) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[1] = (cpu_dat_unexpanded & (1 << (((addr + 1) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[2] = (cpu_dat_unexpanded & (1 << (((addr + 2) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[3] = (cpu_dat_unexpanded & (1 << (((addr + 3) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + } + } + else + { + if (addr & 4) + { + fg_data[0] = (ht216->ht_regs[0xf5] & (1 << (((addr + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[1] = (ht216->ht_regs[0xf5] & (1 << (((addr + 5) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[2] = (ht216->ht_regs[0xf5] & (1 << (((addr + 6) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[3] = (ht216->ht_regs[0xf5] & (1 << (((addr + 7) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + } + else + { + fg_data[0] = (ht216->ht_regs[0xf5] & (1 << (((addr + 0) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[1] = (ht216->ht_regs[0xf5] & (1 << (((addr + 1) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[2] = (ht216->ht_regs[0xf5] & (1 << (((addr + 2) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + fg_data[3] = (ht216->ht_regs[0xf5] & (1 << (((addr + 3) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + } + } + break; + case 0x08: + fg_data[0] = ht216->ht_regs[0xec]; + fg_data[1] = ht216->ht_regs[0xed]; + fg_data[2] = ht216->ht_regs[0xee]; + fg_data[3] = ht216->ht_regs[0xef]; + break; + case 0x0c: + fg_data[0] = ht216->ht_regs[0xec]; + fg_data[1] = ht216->ht_regs[0xed]; + fg_data[2] = ht216->ht_regs[0xee]; + fg_data[3] = ht216->ht_regs[0xef]; + break; + } + + + switch (svga->writemode) + { + case 1: + if (writemask2 & 1) svga->vram[addr] = svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; + break; + case 0: + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) + { + if (writemask2 & 1) svga->vram[addr] = fg_data[0]; + if (writemask2 & 2) svga->vram[addr | 0x1] = fg_data[1]; + if (writemask2 & 4) svga->vram[addr | 0x2] = fg_data[2]; + if (writemask2 & 8) svga->vram[addr | 0x3] = fg_data[3]; + } + else + { + if (svga->gdcreg[1] & 1) vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else vala = fg_data[0]; + if (svga->gdcreg[1] & 2) valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else valb = fg_data[1]; + if (svga->gdcreg[1] & 4) valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else valc = fg_data[2]; + if (svga->gdcreg[1] & 8) vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else vald = fg_data[3]; + + switch (svga->gdcreg[3] & 0x18) + { + case 0: /*Set*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + 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: + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) + { + if (writemask2 & 1) svga->vram[addr] = (((cpu_dat & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (((cpu_dat & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (((cpu_dat & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (((cpu_dat & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + } + else + { + vala = ((cpu_dat & 1) ? 0xff : 0); + valb = ((cpu_dat & 2) ? 0xff : 0); + valc = ((cpu_dat & 4) ? 0xff : 0); + vald = ((cpu_dat & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) + { + case 0: /*Set*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 3: + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= cpu_dat; + + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) + { + case 0: /*Set*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + svga->gdcreg[8] = wm; + break; + } +} + static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bit_mask, uint8_t cpu_dat_unexpanded, uint8_t rop_select) { /*Input B = CD.5 @@ -488,42 +715,49 @@ static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) 01 = Bit mask (3CF:8) 1x = (3C4:F5) */ - uint8_t bit_mask = 0, rop_select = 0; svga_t *svga = &ht216->svga; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; + + egawrites++; + addr &= 0xfffff; // pclog("%08X %02x %08x\n", addr, svga->gdcreg[6], svga->banked_mask); val = svga_rotate[svga->gdcreg[3] & 7][val]; - switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) - { - case 0x00: - bit_mask = svga->gdcreg[8]; - break; - case 0x04: - bit_mask = val; - break; - case 0x08: case 0x0c: - bit_mask = ht216->ht_regs[0xf5]; - break; - } - switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) - { - case 0x00: - rop_select = val; - break; - case 0x10: - rop_select = svga->gdcreg[8]; - break; - case 0x20: case 0x30: - rop_select = ht216->ht_regs[0xf5]; - break; - } - if (ht216->ht_regs[0xcd] & HT_REG_CD_EXALU) /*Extended ALU*/ { + uint8_t bit_mask = 0, rop_select = 0; + + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) + { + case 0x00: + rop_select = val; + break; + case 0x10: + rop_select = svga->gdcreg[8]; + break; + case 0x20: case 0x30: + rop_select = ht216->ht_regs[0xf5]; + break; + } + + switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) + { + case 0x00: + bit_mask = svga->gdcreg[8]; + break; + case 0x04: + bit_mask = val; + break; + case 0x08: case 0x0c: + bit_mask = ht216->ht_regs[0xf5]; + break; + } + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ { addr = (addr << 3) & 0xfffff; @@ -539,6 +773,23 @@ static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) else ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select); } + else + { + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ + { + addr = (addr << 3) & 0xfffff; + ht216_dm_write(ht216, addr, (val & 0x80) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, val); + } + else + ht216_dm_write(ht216, addr, val, val); + } } static void ht216_write(uint32_t addr, uint8_t val, void *p) @@ -552,10 +803,12 @@ static void ht216_write(uint32_t addr, uint8_t val, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; // pclog("phys_addr=%05x\n", addr); - if (!ht216->ht_regs[0xcd]) + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) svga_write_linear(addr, val, &ht216->svga); else + { ht216_write_common(ht216, addr, val); + } } static void ht216_writew(uint32_t addr, uint16_t val, void *p) { @@ -564,7 +817,7 @@ static void ht216_writew(uint32_t addr, uint16_t val, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; - if (!ht216->ht_regs[0xcd]) + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) svga_writew_linear(addr, val, &ht216->svga); else { @@ -579,7 +832,7 @@ static void ht216_writel(uint32_t addr, uint32_t val, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; - if (!ht216->ht_regs[0xcd]) + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) svga_writel_linear(addr, val, &ht216->svga); else { @@ -598,7 +851,7 @@ static void ht216_write_linear(uint32_t addr, uint8_t val, void *p) if (!svga->chain4) /*Bits 16 and 17 of linear address seem to be unused in planar modes*/ addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); - if (!ht216->ht_regs[0xcd]) + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) svga_write_linear(addr, val, &ht216->svga); else ht216_write_common(ht216, addr, val); @@ -611,7 +864,7 @@ static void ht216_writew_linear(uint32_t addr, uint16_t val, void *p) if (!svga->chain4) addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); - if (!ht216->ht_regs[0xcd]) + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) svga_writew_linear(addr, val, &ht216->svga); else { @@ -627,7 +880,7 @@ static void ht216_writel_linear(uint32_t addr, uint32_t val, void *p) if (!svga->chain4) addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); - if (!ht216->ht_regs[0xcd]) + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) svga_writel_linear(addr, val, &ht216->svga); else { From b2e236e7204abee57ebc15b61c55a426df20035a Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 9 Apr 2019 22:19:39 +0100 Subject: [PATCH 0664/1050] Mark FINIT as ending a code block. Fixes crash in Armoured Fist II. --- src/x87_ops_misc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 4354cb2..f22d618 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -38,6 +38,7 @@ static int opFINIT(uint32_t fetchdat) cpu_state.TOP = 0; cpu_state.ismmx = 0; CLOCK_CYCLES(17); + CPU_BLOCK_END(); return 0; } From 73c20a723f448182122e0eb5fb05c4a87b3b9729 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 10 Apr 2019 20:28:45 +0100 Subject: [PATCH 0665/1050] Clear integer registers on CPU reset. Fixes hang on reboot on VA-503+. --- src/808x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/808x.c b/src/808x.c index cba4273..1336727 100644 --- a/src/808x.c +++ b/src/808x.c @@ -630,14 +630,13 @@ void resetx86() idt.base = 0; idt.limit = is386 ? 0x03FF : 0xFFFF; cpu_state.flags=2; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; makeznptable(); resetreadlookup(); makemod1table(); FETCHCLEAR(); x87_reset(); cpu_set_edx(); - EAX = 0; - ESP=0; mmu_perm=4; x86seg_reset(); codegen_reset(); @@ -679,6 +678,7 @@ void softresetx86() cpu_state.flags=2; idt.base = 0; idt.limit = is386 ? 0x03FF : 0xFFFF; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; x86seg_reset(); x86_was_reset = 1; } From c79074c980b4a69c6facb180b3d0c2e1f5b6b4ef Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 10 Apr 2019 20:31:31 +0100 Subject: [PATCH 0666/1050] Fix timer bug in AudioPCI. --- src/sound_audiopci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index e9d4ef7..b56b510 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -1224,7 +1224,7 @@ static void es1371_speed_changed(void *p) { es1371_t *es1371 = (es1371_t *)p; - es1371->dac[1].latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); + es1371->dac[1].latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); } void es1371_add_status_info_dac(es1371_t *es1371, char *s, int max_len, int dac_nr) From c0a7fcb3432abf49aae18699253d2fe3f66b680c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 10 Apr 2019 22:05:26 +0100 Subject: [PATCH 0667/1050] Correct code present mask when using 16-bit addressing. Fixes graphics issues on Windows 9x with VGA 16-colour driver. --- src/codegen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index ba33e47..06f6213 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -121,7 +121,7 @@ void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { - uint32_t old_pc = *op_pc; + uint32_t old_pc = (*op_pc) + 1; // pclog("codegen - mod=%i rm=%i reg=%i fetchdat=%08x\n", cpu_mod, cpu_rm, cpu_reg, fetchdat); if (!cpu_mod && cpu_rm == 6) { @@ -182,7 +182,7 @@ static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uin } } - codegen_mark_code_present(ir->block, cs+old_pc, (*op_pc)-old_pc); + codegen_mark_code_present(ir->block, cs+old_pc, ((*op_pc)+1)-old_pc); return op_ea_seg; } From e2cddb8759577daf842ebf6047ff806ca9ce2691 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 10 Apr 2019 22:13:25 +0100 Subject: [PATCH 0668/1050] Fix Mach64 pixel clock. --- src/vid_ati_mach64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index f997892..e38fca3 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -422,7 +422,7 @@ void mach64_recalctimings(svga_t *svga) 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->clock = (cpuclock * (float)(1ull << 32)) / mach64->ics2595.output_clock; svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; From de177759f77d003f95a52f550305a306c7242400 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 11 Apr 2019 20:58:07 +0100 Subject: [PATCH 0669/1050] Fix EA calculations on 3DNow PREFETCH instruction --- src/x86_ops_3dnow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86_ops_3dnow.h b/src/x86_ops_3dnow.h index 304943f..9f852d5 100644 --- a/src/x86_ops_3dnow.h +++ b/src/x86_ops_3dnow.h @@ -10,7 +10,7 @@ static int opPREFETCH_a16(uint32_t fetchdat) } static int opPREFETCH_a32(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_32(fetchdat); ILLEGAL_ON(cpu_mod == 3); CLOCK_CYCLES(1); From 9a49a75eaf599e667d5fd38c4a0cf28c96c12889 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 14 Apr 2019 13:47:20 +0100 Subject: [PATCH 0670/1050] IDE soft reset should also reset ATAPI devices. Should fix at least some 'Device failed to request command' errors. --- src/ide.c | 2 ++ src/ide_atapi.c | 10 ++++++++++ src/ide_atapi.h | 1 + src/scsi.c | 18 ++++++++++++++++++ src/scsi.h | 2 ++ src/scsi_cd.c | 9 +++++++++ src/scsi_hd.c | 1 + src/scsi_zip.c | 9 +++++++++ 8 files changed, 52 insertions(+) diff --git a/src/ide.c b/src/ide.c index 0cbad14..4e8d5ef 100644 --- a/src/ide.c +++ b/src/ide.c @@ -819,6 +819,7 @@ void callbackide(int ide_board) { ide->cylinder=0xEB14; atapi->stop(); + atapi_reset(&ide->atapi); } if (ide->type == IDE_NONE) { @@ -829,6 +830,7 @@ void callbackide(int ide_board) { ide_other->cylinder=0xEB14; atapi->stop(); + atapi_reset(&ide_other->atapi); } if (ide_other->type == IDE_NONE) { diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 78a648b..0324e9c 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -563,3 +563,13 @@ void atapi_process_packet(atapi_device_t *atapi_dev) break; } } + +void atapi_reset(atapi_device_t *atapi_dev) +{ + pclog("atapi_reset\n"); + atapi_dev->state = ATAPI_STATE_IDLE; + atapi_dev->command_pos = 0; + atapi_dev->data_read_pos = 0; + atapi_dev->data_write_pos = 0; + scsi_bus_reset(&atapi_dev->bus); +} diff --git a/src/ide_atapi.h b/src/ide_atapi.h index f737090..ab2174c 100644 --- a/src/ide_atapi.h +++ b/src/ide_atapi.h @@ -64,5 +64,6 @@ uint8_t atapi_read_iir(atapi_device_t *atapi_dev); uint8_t atapi_read_drq(atapi_device_t *atapi_dev); void atapi_process_packet(atapi_device_t *atapi_dev); void atapi_set_transfer_granularity(atapi_device_t *atapi_dev, int size); +void atapi_reset(atapi_device_t *atapi_dev); #endif diff --git a/src/scsi.c b/src/scsi.c index df4b8a8..199ac6e 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -374,3 +374,21 @@ void scsi_bus_close(scsi_bus_t *bus) bus->devices[c]->close(bus->device_data[c]); } } + +void scsi_bus_reset(scsi_bus_t *bus) +{ + int c; + + bus->state = STATE_IDLE; + bus->clear_req = 0; + bus->change_state_delay = 0; + bus->new_req_delay = 0; + bus->bus_in = bus->bus_out = 0; + bus->command_pos = 0; + + for (c = 0; c < 8; c++) + { + if (bus->device_data[c] && bus->devices[c]->reset) + bus->devices[c]->reset(bus->device_data[c]); + } +} diff --git a/src/scsi.h b/src/scsi.h index 8791011..cba4a98 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -9,6 +9,7 @@ typedef struct scsi_device_t void *(*init)(struct scsi_bus_t *bus, int id); void *(*atapi_init)(struct scsi_bus_t *bus, int id, struct atapi_device_t *atapi_dev); void (*close)(void *p); + void (*reset)(void *p); void (*start_command)(void *p); int (*command)(uint8_t *cdb, void *p); @@ -106,6 +107,7 @@ int scsi_bus_match(scsi_bus_t *bus, int bus_assert); void scsi_bus_kick(scsi_bus_t *bus); void scsi_bus_init(scsi_bus_t *bus); void scsi_bus_close(scsi_bus_t *bus); +void scsi_bus_reset(scsi_bus_t *bus); void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id, struct atapi_device_t *atapi_dev); diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 5abe1f3..48dbdb6 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -420,6 +420,14 @@ static void scsi_cd_close(void *p) free(data); } +static void scsi_cd_reset(void *p) +{ + scsi_cd_data_t *data = p; + + timer_disable(&data->callback_timer); + data->cmd_pos = CMD_POS_IDLE; +} + static void scsi_cd_illegal(scsi_cd_data_t *data) { atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INVALID_LUN, 0); @@ -1546,6 +1554,7 @@ scsi_device_t scsi_cd = scsi_cd_init, scsi_cd_atapi_init, scsi_cd_close, + scsi_cd_reset, scsi_cd_start_command, scsi_cd_command, diff --git a/src/scsi_hd.c b/src/scsi_hd.c index bf6412e..914f984 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -816,6 +816,7 @@ scsi_device_t scsi_hd = scsi_hd_init, NULL, scsi_hd_close, + NULL, scsi_hd_start_command, scsi_hd_command, diff --git a/src/scsi_zip.c b/src/scsi_zip.c index 8f81700..51dacb2 100644 --- a/src/scsi_zip.c +++ b/src/scsi_zip.c @@ -218,6 +218,14 @@ static void scsi_zip_close(void *p) zip_data = NULL; } +static void scsi_zip_reset(void *p) +{ + scsi_zip_data *data = p; + + timer_disable(&data->callback_timer); + data->cmd_pos = CMD_POS_IDLE; +} + static int scsi_add_data(uint8_t val, void *p) { scsi_zip_data *data = p; @@ -1195,6 +1203,7 @@ scsi_device_t scsi_zip = scsi_zip_init, scsi_zip_atapi_init, scsi_zip_close, + scsi_zip_reset, scsi_zip_start_command, scsi_zip_command, From f4074eaacd4be4644bbdd7e5c28b305913e54306 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 14 Apr 2019 15:38:13 +0100 Subject: [PATCH 0671/1050] Add better immediate handling to ARM64 backend. --- src/codegen_backend_arm64.h | 2 + src/codegen_backend_arm64_imm.c | 1330 +++++++++++++++++++++++++++++++ src/codegen_backend_arm64_ops.c | 70 +- 3 files changed, 1350 insertions(+), 52 deletions(-) create mode 100644 src/codegen_backend_arm64_imm.c diff --git a/src/codegen_backend_arm64.h b/src/codegen_backend_arm64.h index 1fb0cfb..3263aa1 100644 --- a/src/codegen_backend_arm64.h +++ b/src/codegen_backend_arm64.h @@ -27,3 +27,5 @@ void host_arm64_STRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int o void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); + +uint32_t host_arm64_find_imm(uint32_t data); \ No newline at end of file diff --git a/src/codegen_backend_arm64_imm.c b/src/codegen_backend_arm64_imm.c new file mode 100644 index 0000000..0362b71 --- /dev/null +++ b/src/codegen_backend_arm64_imm.c @@ -0,0 +1,1330 @@ +#include +#include + +/*ARM64 logical instructions have an 'interesting' immediate encoding. + All valid values are in the table below, which we perform a binary + search over*/ +#define IMM_NR 1302 +static uint32_t imm_table[][2] = +{ + {0x800, 0x00000001}, + {0xfc0, 0x00000002}, + {0x801, 0x00000003}, + {0xf80, 0x00000004}, + {0xfc1, 0x00000006}, + {0x802, 0x00000007}, + {0xf40, 0x00000008}, + {0xf81, 0x0000000c}, + {0xfc2, 0x0000000e}, + {0x803, 0x0000000f}, + {0xf00, 0x00000010}, + {0xf41, 0x00000018}, + {0xf82, 0x0000001c}, + {0xfc3, 0x0000001e}, + {0x804, 0x0000001f}, + {0xec0, 0x00000020}, + {0xf01, 0x00000030}, + {0xf42, 0x00000038}, + {0xf83, 0x0000003c}, + {0xfc4, 0x0000003e}, + {0x805, 0x0000003f}, + {0xe80, 0x00000040}, + {0xec1, 0x00000060}, + {0xf02, 0x00000070}, + {0xf43, 0x00000078}, + {0xf84, 0x0000007c}, + {0xfc5, 0x0000007e}, + {0x806, 0x0000007f}, + {0xe40, 0x00000080}, + {0xe81, 0x000000c0}, + {0xec2, 0x000000e0}, + {0xf03, 0x000000f0}, + {0xf44, 0x000000f8}, + {0xf85, 0x000000fc}, + {0xfc6, 0x000000fe}, + {0x807, 0x000000ff}, + {0xe00, 0x00000100}, + {0xe41, 0x00000180}, + {0xe82, 0x000001c0}, + {0xec3, 0x000001e0}, + {0xf04, 0x000001f0}, + {0xf45, 0x000001f8}, + {0xf86, 0x000001fc}, + {0xfc7, 0x000001fe}, + {0x808, 0x000001ff}, + {0xdc0, 0x00000200}, + {0xe01, 0x00000300}, + {0xe42, 0x00000380}, + {0xe83, 0x000003c0}, + {0xec4, 0x000003e0}, + {0xf05, 0x000003f0}, + {0xf46, 0x000003f8}, + {0xf87, 0x000003fc}, + {0xfc8, 0x000003fe}, + {0x809, 0x000003ff}, + {0xd80, 0x00000400}, + {0xdc1, 0x00000600}, + {0xe02, 0x00000700}, + {0xe43, 0x00000780}, + {0xe84, 0x000007c0}, + {0xec5, 0x000007e0}, + {0xf06, 0x000007f0}, + {0xf47, 0x000007f8}, + {0xf88, 0x000007fc}, + {0xfc9, 0x000007fe}, + {0x80a, 0x000007ff}, + {0xd40, 0x00000800}, + {0xd81, 0x00000c00}, + {0xdc2, 0x00000e00}, + {0xe03, 0x00000f00}, + {0xe44, 0x00000f80}, + {0xe85, 0x00000fc0}, + {0xec6, 0x00000fe0}, + {0xf07, 0x00000ff0}, + {0xf48, 0x00000ff8}, + {0xf89, 0x00000ffc}, + {0xfca, 0x00000ffe}, + {0x80b, 0x00000fff}, + {0xd00, 0x00001000}, + {0xd41, 0x00001800}, + {0xd82, 0x00001c00}, + {0xdc3, 0x00001e00}, + {0xe04, 0x00001f00}, + {0xe45, 0x00001f80}, + {0xe86, 0x00001fc0}, + {0xec7, 0x00001fe0}, + {0xf08, 0x00001ff0}, + {0xf49, 0x00001ff8}, + {0xf8a, 0x00001ffc}, + {0xfcb, 0x00001ffe}, + {0x80c, 0x00001fff}, + {0xcc0, 0x00002000}, + {0xd01, 0x00003000}, + {0xd42, 0x00003800}, + {0xd83, 0x00003c00}, + {0xdc4, 0x00003e00}, + {0xe05, 0x00003f00}, + {0xe46, 0x00003f80}, + {0xe87, 0x00003fc0}, + {0xec8, 0x00003fe0}, + {0xf09, 0x00003ff0}, + {0xf4a, 0x00003ff8}, + {0xf8b, 0x00003ffc}, + {0xfcc, 0x00003ffe}, + {0x80d, 0x00003fff}, + {0xc80, 0x00004000}, + {0xcc1, 0x00006000}, + {0xd02, 0x00007000}, + {0xd43, 0x00007800}, + {0xd84, 0x00007c00}, + {0xdc5, 0x00007e00}, + {0xe06, 0x00007f00}, + {0xe47, 0x00007f80}, + {0xe88, 0x00007fc0}, + {0xec9, 0x00007fe0}, + {0xf0a, 0x00007ff0}, + {0xf4b, 0x00007ff8}, + {0xf8c, 0x00007ffc}, + {0xfcd, 0x00007ffe}, + {0x80e, 0x00007fff}, + {0xc40, 0x00008000}, + {0xc81, 0x0000c000}, + {0xcc2, 0x0000e000}, + {0xd03, 0x0000f000}, + {0xd44, 0x0000f800}, + {0xd85, 0x0000fc00}, + {0xdc6, 0x0000fe00}, + {0xe07, 0x0000ff00}, + {0xe48, 0x0000ff80}, + {0xe89, 0x0000ffc0}, + {0xeca, 0x0000ffe0}, + {0xf0b, 0x0000fff0}, + {0xf4c, 0x0000fff8}, + {0xf8d, 0x0000fffc}, + {0xfce, 0x0000fffe}, + {0x80f, 0x0000ffff}, + {0xc00, 0x00010000}, + {0xc20, 0x00010001}, + {0xc41, 0x00018000}, + {0xc82, 0x0001c000}, + {0xcc3, 0x0001e000}, + {0xd04, 0x0001f000}, + {0xd45, 0x0001f800}, + {0xd86, 0x0001fc00}, + {0xdc7, 0x0001fe00}, + {0xe08, 0x0001ff00}, + {0xe49, 0x0001ff80}, + {0xe8a, 0x0001ffc0}, + {0xecb, 0x0001ffe0}, + {0xf0c, 0x0001fff0}, + {0xf4d, 0x0001fff8}, + {0xf8e, 0x0001fffc}, + {0xfcf, 0x0001fffe}, + {0x810, 0x0001ffff}, + {0xbc0, 0x00020000}, + {0xfe0, 0x00020002}, + {0xc01, 0x00030000}, + {0xc21, 0x00030003}, + {0xc42, 0x00038000}, + {0xc83, 0x0003c000}, + {0xcc4, 0x0003e000}, + {0xd05, 0x0003f000}, + {0xd46, 0x0003f800}, + {0xd87, 0x0003fc00}, + {0xdc8, 0x0003fe00}, + {0xe09, 0x0003ff00}, + {0xe4a, 0x0003ff80}, + {0xe8b, 0x0003ffc0}, + {0xecc, 0x0003ffe0}, + {0xf0d, 0x0003fff0}, + {0xf4e, 0x0003fff8}, + {0xf8f, 0x0003fffc}, + {0xfd0, 0x0003fffe}, + {0x811, 0x0003ffff}, + {0xb80, 0x00040000}, + {0xfa0, 0x00040004}, + {0xbc1, 0x00060000}, + {0xfe1, 0x00060006}, + {0xc02, 0x00070000}, + {0xc22, 0x00070007}, + {0xc43, 0x00078000}, + {0xc84, 0x0007c000}, + {0xcc5, 0x0007e000}, + {0xd06, 0x0007f000}, + {0xd47, 0x0007f800}, + {0xd88, 0x0007fc00}, + {0xdc9, 0x0007fe00}, + {0xe0a, 0x0007ff00}, + {0xe4b, 0x0007ff80}, + {0xe8c, 0x0007ffc0}, + {0xecd, 0x0007ffe0}, + {0xf0e, 0x0007fff0}, + {0xf4f, 0x0007fff8}, + {0xf90, 0x0007fffc}, + {0xfd1, 0x0007fffe}, + {0x812, 0x0007ffff}, + {0xb40, 0x00080000}, + {0xf60, 0x00080008}, + {0xb81, 0x000c0000}, + {0xfa1, 0x000c000c}, + {0xbc2, 0x000e0000}, + {0xfe2, 0x000e000e}, + {0xc03, 0x000f0000}, + {0xc23, 0x000f000f}, + {0xc44, 0x000f8000}, + {0xc85, 0x000fc000}, + {0xcc6, 0x000fe000}, + {0xd07, 0x000ff000}, + {0xd48, 0x000ff800}, + {0xd89, 0x000ffc00}, + {0xdca, 0x000ffe00}, + {0xe0b, 0x000fff00}, + {0xe4c, 0x000fff80}, + {0xe8d, 0x000fffc0}, + {0xece, 0x000fffe0}, + {0xf0f, 0x000ffff0}, + {0xf50, 0x000ffff8}, + {0xf91, 0x000ffffc}, + {0xfd2, 0x000ffffe}, + {0x813, 0x000fffff}, + {0xb00, 0x00100000}, + {0xf20, 0x00100010}, + {0xb41, 0x00180000}, + {0xf61, 0x00180018}, + {0xb82, 0x001c0000}, + {0xfa2, 0x001c001c}, + {0xbc3, 0x001e0000}, + {0xfe3, 0x001e001e}, + {0xc04, 0x001f0000}, + {0xc24, 0x001f001f}, + {0xc45, 0x001f8000}, + {0xc86, 0x001fc000}, + {0xcc7, 0x001fe000}, + {0xd08, 0x001ff000}, + {0xd49, 0x001ff800}, + {0xd8a, 0x001ffc00}, + {0xdcb, 0x001ffe00}, + {0xe0c, 0x001fff00}, + {0xe4d, 0x001fff80}, + {0xe8e, 0x001fffc0}, + {0xecf, 0x001fffe0}, + {0xf10, 0x001ffff0}, + {0xf51, 0x001ffff8}, + {0xf92, 0x001ffffc}, + {0xfd3, 0x001ffffe}, + {0x814, 0x001fffff}, + {0xac0, 0x00200000}, + {0xee0, 0x00200020}, + {0xb01, 0x00300000}, + {0xf21, 0x00300030}, + {0xb42, 0x00380000}, + {0xf62, 0x00380038}, + {0xb83, 0x003c0000}, + {0xfa3, 0x003c003c}, + {0xbc4, 0x003e0000}, + {0xfe4, 0x003e003e}, + {0xc05, 0x003f0000}, + {0xc25, 0x003f003f}, + {0xc46, 0x003f8000}, + {0xc87, 0x003fc000}, + {0xcc8, 0x003fe000}, + {0xd09, 0x003ff000}, + {0xd4a, 0x003ff800}, + {0xd8b, 0x003ffc00}, + {0xdcc, 0x003ffe00}, + {0xe0d, 0x003fff00}, + {0xe4e, 0x003fff80}, + {0xe8f, 0x003fffc0}, + {0xed0, 0x003fffe0}, + {0xf11, 0x003ffff0}, + {0xf52, 0x003ffff8}, + {0xf93, 0x003ffffc}, + {0xfd4, 0x003ffffe}, + {0x815, 0x003fffff}, + {0xa80, 0x00400000}, + {0xea0, 0x00400040}, + {0xac1, 0x00600000}, + {0xee1, 0x00600060}, + {0xb02, 0x00700000}, + {0xf22, 0x00700070}, + {0xb43, 0x00780000}, + {0xf63, 0x00780078}, + {0xb84, 0x007c0000}, + {0xfa4, 0x007c007c}, + {0xbc5, 0x007e0000}, + {0xfe5, 0x007e007e}, + {0xc06, 0x007f0000}, + {0xc26, 0x007f007f}, + {0xc47, 0x007f8000}, + {0xc88, 0x007fc000}, + {0xcc9, 0x007fe000}, + {0xd0a, 0x007ff000}, + {0xd4b, 0x007ff800}, + {0xd8c, 0x007ffc00}, + {0xdcd, 0x007ffe00}, + {0xe0e, 0x007fff00}, + {0xe4f, 0x007fff80}, + {0xe90, 0x007fffc0}, + {0xed1, 0x007fffe0}, + {0xf12, 0x007ffff0}, + {0xf53, 0x007ffff8}, + {0xf94, 0x007ffffc}, + {0xfd5, 0x007ffffe}, + {0x816, 0x007fffff}, + {0xa40, 0x00800000}, + {0xe60, 0x00800080}, + {0xa81, 0x00c00000}, + {0xea1, 0x00c000c0}, + {0xac2, 0x00e00000}, + {0xee2, 0x00e000e0}, + {0xb03, 0x00f00000}, + {0xf23, 0x00f000f0}, + {0xb44, 0x00f80000}, + {0xf64, 0x00f800f8}, + {0xb85, 0x00fc0000}, + {0xfa5, 0x00fc00fc}, + {0xbc6, 0x00fe0000}, + {0xfe6, 0x00fe00fe}, + {0xc07, 0x00ff0000}, + {0xc27, 0x00ff00ff}, + {0xc48, 0x00ff8000}, + {0xc89, 0x00ffc000}, + {0xcca, 0x00ffe000}, + {0xd0b, 0x00fff000}, + {0xd4c, 0x00fff800}, + {0xd8d, 0x00fffc00}, + {0xdce, 0x00fffe00}, + {0xe0f, 0x00ffff00}, + {0xe50, 0x00ffff80}, + {0xe91, 0x00ffffc0}, + {0xed2, 0x00ffffe0}, + {0xf13, 0x00fffff0}, + {0xf54, 0x00fffff8}, + {0xf95, 0x00fffffc}, + {0xfd6, 0x00fffffe}, + {0x817, 0x00ffffff}, + {0xa00, 0x01000000}, + {0xe20, 0x01000100}, + {0xe30, 0x01010101}, + {0xa41, 0x01800000}, + {0xe61, 0x01800180}, + {0xa82, 0x01c00000}, + {0xea2, 0x01c001c0}, + {0xac3, 0x01e00000}, + {0xee3, 0x01e001e0}, + {0xb04, 0x01f00000}, + {0xf24, 0x01f001f0}, + {0xb45, 0x01f80000}, + {0xf65, 0x01f801f8}, + {0xb86, 0x01fc0000}, + {0xfa6, 0x01fc01fc}, + {0xbc7, 0x01fe0000}, + {0xfe7, 0x01fe01fe}, + {0xc08, 0x01ff0000}, + {0xc28, 0x01ff01ff}, + {0xc49, 0x01ff8000}, + {0xc8a, 0x01ffc000}, + {0xccb, 0x01ffe000}, + {0xd0c, 0x01fff000}, + {0xd4d, 0x01fff800}, + {0xd8e, 0x01fffc00}, + {0xdcf, 0x01fffe00}, + {0xe10, 0x01ffff00}, + {0xe51, 0x01ffff80}, + {0xe92, 0x01ffffc0}, + {0xed3, 0x01ffffe0}, + {0xf14, 0x01fffff0}, + {0xf55, 0x01fffff8}, + {0xf96, 0x01fffffc}, + {0xfd7, 0x01fffffe}, + {0x818, 0x01ffffff}, + {0x9c0, 0x02000000}, + {0xde0, 0x02000200}, + {0xff0, 0x02020202}, + {0xa01, 0x03000000}, + {0xe21, 0x03000300}, + {0xe31, 0x03030303}, + {0xa42, 0x03800000}, + {0xe62, 0x03800380}, + {0xa83, 0x03c00000}, + {0xea3, 0x03c003c0}, + {0xac4, 0x03e00000}, + {0xee4, 0x03e003e0}, + {0xb05, 0x03f00000}, + {0xf25, 0x03f003f0}, + {0xb46, 0x03f80000}, + {0xf66, 0x03f803f8}, + {0xb87, 0x03fc0000}, + {0xfa7, 0x03fc03fc}, + {0xbc8, 0x03fe0000}, + {0xfe8, 0x03fe03fe}, + {0xc09, 0x03ff0000}, + {0xc29, 0x03ff03ff}, + {0xc4a, 0x03ff8000}, + {0xc8b, 0x03ffc000}, + {0xccc, 0x03ffe000}, + {0xd0d, 0x03fff000}, + {0xd4e, 0x03fff800}, + {0xd8f, 0x03fffc00}, + {0xdd0, 0x03fffe00}, + {0xe11, 0x03ffff00}, + {0xe52, 0x03ffff80}, + {0xe93, 0x03ffffc0}, + {0xed4, 0x03ffffe0}, + {0xf15, 0x03fffff0}, + {0xf56, 0x03fffff8}, + {0xf97, 0x03fffffc}, + {0xfd8, 0x03fffffe}, + {0x819, 0x03ffffff}, + {0x980, 0x04000000}, + {0xda0, 0x04000400}, + {0xfb0, 0x04040404}, + {0x9c1, 0x06000000}, + {0xde1, 0x06000600}, + {0xff1, 0x06060606}, + {0xa02, 0x07000000}, + {0xe22, 0x07000700}, + {0xe32, 0x07070707}, + {0xa43, 0x07800000}, + {0xe63, 0x07800780}, + {0xa84, 0x07c00000}, + {0xea4, 0x07c007c0}, + {0xac5, 0x07e00000}, + {0xee5, 0x07e007e0}, + {0xb06, 0x07f00000}, + {0xf26, 0x07f007f0}, + {0xb47, 0x07f80000}, + {0xf67, 0x07f807f8}, + {0xb88, 0x07fc0000}, + {0xfa8, 0x07fc07fc}, + {0xbc9, 0x07fe0000}, + {0xfe9, 0x07fe07fe}, + {0xc0a, 0x07ff0000}, + {0xc2a, 0x07ff07ff}, + {0xc4b, 0x07ff8000}, + {0xc8c, 0x07ffc000}, + {0xccd, 0x07ffe000}, + {0xd0e, 0x07fff000}, + {0xd4f, 0x07fff800}, + {0xd90, 0x07fffc00}, + {0xdd1, 0x07fffe00}, + {0xe12, 0x07ffff00}, + {0xe53, 0x07ffff80}, + {0xe94, 0x07ffffc0}, + {0xed5, 0x07ffffe0}, + {0xf16, 0x07fffff0}, + {0xf57, 0x07fffff8}, + {0xf98, 0x07fffffc}, + {0xfd9, 0x07fffffe}, + {0x81a, 0x07ffffff}, + {0x940, 0x08000000}, + {0xd60, 0x08000800}, + {0xf70, 0x08080808}, + {0x981, 0x0c000000}, + {0xda1, 0x0c000c00}, + {0xfb1, 0x0c0c0c0c}, + {0x9c2, 0x0e000000}, + {0xde2, 0x0e000e00}, + {0xff2, 0x0e0e0e0e}, + {0xa03, 0x0f000000}, + {0xe23, 0x0f000f00}, + {0xe33, 0x0f0f0f0f}, + {0xa44, 0x0f800000}, + {0xe64, 0x0f800f80}, + {0xa85, 0x0fc00000}, + {0xea5, 0x0fc00fc0}, + {0xac6, 0x0fe00000}, + {0xee6, 0x0fe00fe0}, + {0xb07, 0x0ff00000}, + {0xf27, 0x0ff00ff0}, + {0xb48, 0x0ff80000}, + {0xf68, 0x0ff80ff8}, + {0xb89, 0x0ffc0000}, + {0xfa9, 0x0ffc0ffc}, + {0xbca, 0x0ffe0000}, + {0xfea, 0x0ffe0ffe}, + {0xc0b, 0x0fff0000}, + {0xc2b, 0x0fff0fff}, + {0xc4c, 0x0fff8000}, + {0xc8d, 0x0fffc000}, + {0xcce, 0x0fffe000}, + {0xd0f, 0x0ffff000}, + {0xd50, 0x0ffff800}, + {0xd91, 0x0ffffc00}, + {0xdd2, 0x0ffffe00}, + {0xe13, 0x0fffff00}, + {0xe54, 0x0fffff80}, + {0xe95, 0x0fffffc0}, + {0xed6, 0x0fffffe0}, + {0xf17, 0x0ffffff0}, + {0xf58, 0x0ffffff8}, + {0xf99, 0x0ffffffc}, + {0xfda, 0x0ffffffe}, + {0x81b, 0x0fffffff}, + {0x900, 0x10000000}, + {0xd20, 0x10001000}, + {0xf30, 0x10101010}, + {0xf38, 0x11111111}, + {0x941, 0x18000000}, + {0xd61, 0x18001800}, + {0xf71, 0x18181818}, + {0x982, 0x1c000000}, + {0xda2, 0x1c001c00}, + {0xfb2, 0x1c1c1c1c}, + {0x9c3, 0x1e000000}, + {0xde3, 0x1e001e00}, + {0xff3, 0x1e1e1e1e}, + {0xa04, 0x1f000000}, + {0xe24, 0x1f001f00}, + {0xe34, 0x1f1f1f1f}, + {0xa45, 0x1f800000}, + {0xe65, 0x1f801f80}, + {0xa86, 0x1fc00000}, + {0xea6, 0x1fc01fc0}, + {0xac7, 0x1fe00000}, + {0xee7, 0x1fe01fe0}, + {0xb08, 0x1ff00000}, + {0xf28, 0x1ff01ff0}, + {0xb49, 0x1ff80000}, + {0xf69, 0x1ff81ff8}, + {0xb8a, 0x1ffc0000}, + {0xfaa, 0x1ffc1ffc}, + {0xbcb, 0x1ffe0000}, + {0xfeb, 0x1ffe1ffe}, + {0xc0c, 0x1fff0000}, + {0xc2c, 0x1fff1fff}, + {0xc4d, 0x1fff8000}, + {0xc8e, 0x1fffc000}, + {0xccf, 0x1fffe000}, + {0xd10, 0x1ffff000}, + {0xd51, 0x1ffff800}, + {0xd92, 0x1ffffc00}, + {0xdd3, 0x1ffffe00}, + {0xe14, 0x1fffff00}, + {0xe55, 0x1fffff80}, + {0xe96, 0x1fffffc0}, + {0xed7, 0x1fffffe0}, + {0xf18, 0x1ffffff0}, + {0xf59, 0x1ffffff8}, + {0xf9a, 0x1ffffffc}, + {0xfdb, 0x1ffffffe}, + {0x81c, 0x1fffffff}, + {0x8c0, 0x20000000}, + {0xce0, 0x20002000}, + {0xef0, 0x20202020}, + {0xff8, 0x22222222}, + {0x901, 0x30000000}, + {0xd21, 0x30003000}, + {0xf31, 0x30303030}, + {0xf39, 0x33333333}, + {0x942, 0x38000000}, + {0xd62, 0x38003800}, + {0xf72, 0x38383838}, + {0x983, 0x3c000000}, + {0xda3, 0x3c003c00}, + {0xfb3, 0x3c3c3c3c}, + {0x9c4, 0x3e000000}, + {0xde4, 0x3e003e00}, + {0xff4, 0x3e3e3e3e}, + {0xa05, 0x3f000000}, + {0xe25, 0x3f003f00}, + {0xe35, 0x3f3f3f3f}, + {0xa46, 0x3f800000}, + {0xe66, 0x3f803f80}, + {0xa87, 0x3fc00000}, + {0xea7, 0x3fc03fc0}, + {0xac8, 0x3fe00000}, + {0xee8, 0x3fe03fe0}, + {0xb09, 0x3ff00000}, + {0xf29, 0x3ff03ff0}, + {0xb4a, 0x3ff80000}, + {0xf6a, 0x3ff83ff8}, + {0xb8b, 0x3ffc0000}, + {0xfab, 0x3ffc3ffc}, + {0xbcc, 0x3ffe0000}, + {0xfec, 0x3ffe3ffe}, + {0xc0d, 0x3fff0000}, + {0xc2d, 0x3fff3fff}, + {0xc4e, 0x3fff8000}, + {0xc8f, 0x3fffc000}, + {0xcd0, 0x3fffe000}, + {0xd11, 0x3ffff000}, + {0xd52, 0x3ffff800}, + {0xd93, 0x3ffffc00}, + {0xdd4, 0x3ffffe00}, + {0xe15, 0x3fffff00}, + {0xe56, 0x3fffff80}, + {0xe97, 0x3fffffc0}, + {0xed8, 0x3fffffe0}, + {0xf19, 0x3ffffff0}, + {0xf5a, 0x3ffffff8}, + {0xf9b, 0x3ffffffc}, + {0xfdc, 0x3ffffffe}, + {0x81d, 0x3fffffff}, + {0x880, 0x40000000}, + {0xca0, 0x40004000}, + {0xeb0, 0x40404040}, + {0xfb8, 0x44444444}, + {0xfbc, 0x55555555}, + {0x8c1, 0x60000000}, + {0xce1, 0x60006000}, + {0xef1, 0x60606060}, + {0xff9, 0x66666666}, + {0x902, 0x70000000}, + {0xd22, 0x70007000}, + {0xf32, 0x70707070}, + {0xf3a, 0x77777777}, + {0x943, 0x78000000}, + {0xd63, 0x78007800}, + {0xf73, 0x78787878}, + {0x984, 0x7c000000}, + {0xda4, 0x7c007c00}, + {0xfb4, 0x7c7c7c7c}, + {0x9c5, 0x7e000000}, + {0xde5, 0x7e007e00}, + {0xff5, 0x7e7e7e7e}, + {0xa06, 0x7f000000}, + {0xe26, 0x7f007f00}, + {0xe36, 0x7f7f7f7f}, + {0xa47, 0x7f800000}, + {0xe67, 0x7f807f80}, + {0xa88, 0x7fc00000}, + {0xea8, 0x7fc07fc0}, + {0xac9, 0x7fe00000}, + {0xee9, 0x7fe07fe0}, + {0xb0a, 0x7ff00000}, + {0xf2a, 0x7ff07ff0}, + {0xb4b, 0x7ff80000}, + {0xf6b, 0x7ff87ff8}, + {0xb8c, 0x7ffc0000}, + {0xfac, 0x7ffc7ffc}, + {0xbcd, 0x7ffe0000}, + {0xfed, 0x7ffe7ffe}, + {0xc0e, 0x7fff0000}, + {0xc2e, 0x7fff7fff}, + {0xc4f, 0x7fff8000}, + {0xc90, 0x7fffc000}, + {0xcd1, 0x7fffe000}, + {0xd12, 0x7ffff000}, + {0xd53, 0x7ffff800}, + {0xd94, 0x7ffffc00}, + {0xdd5, 0x7ffffe00}, + {0xe16, 0x7fffff00}, + {0xe57, 0x7fffff80}, + {0xe98, 0x7fffffc0}, + {0xed9, 0x7fffffe0}, + {0xf1a, 0x7ffffff0}, + {0xf5b, 0x7ffffff8}, + {0xf9c, 0x7ffffffc}, + {0xfdd, 0x7ffffffe}, + {0x81e, 0x7fffffff}, + {0x840, 0x80000000}, + {0x841, 0x80000001}, + {0x842, 0x80000003}, + {0x843, 0x80000007}, + {0x844, 0x8000000f}, + {0x845, 0x8000001f}, + {0x846, 0x8000003f}, + {0x847, 0x8000007f}, + {0x848, 0x800000ff}, + {0x849, 0x800001ff}, + {0x84a, 0x800003ff}, + {0x84b, 0x800007ff}, + {0x84c, 0x80000fff}, + {0x84d, 0x80001fff}, + {0x84e, 0x80003fff}, + {0x84f, 0x80007fff}, + {0xc60, 0x80008000}, + {0x850, 0x8000ffff}, + {0xc61, 0x80018001}, + {0x851, 0x8001ffff}, + {0xc62, 0x80038003}, + {0x852, 0x8003ffff}, + {0xc63, 0x80078007}, + {0x853, 0x8007ffff}, + {0xc64, 0x800f800f}, + {0x854, 0x800fffff}, + {0xc65, 0x801f801f}, + {0x855, 0x801fffff}, + {0xc66, 0x803f803f}, + {0x856, 0x803fffff}, + {0xc67, 0x807f807f}, + {0x857, 0x807fffff}, + {0xe70, 0x80808080}, + {0xc68, 0x80ff80ff}, + {0x858, 0x80ffffff}, + {0xe71, 0x81818181}, + {0xc69, 0x81ff81ff}, + {0x859, 0x81ffffff}, + {0xe72, 0x83838383}, + {0xc6a, 0x83ff83ff}, + {0x85a, 0x83ffffff}, + {0xe73, 0x87878787}, + {0xc6b, 0x87ff87ff}, + {0x85b, 0x87ffffff}, + {0xf78, 0x88888888}, + {0xe74, 0x8f8f8f8f}, + {0xc6c, 0x8fff8fff}, + {0x85c, 0x8fffffff}, + {0xf79, 0x99999999}, + {0xe75, 0x9f9f9f9f}, + {0xc6d, 0x9fff9fff}, + {0x85d, 0x9fffffff}, + {0xffc, 0xaaaaaaaa}, + {0xf7a, 0xbbbbbbbb}, + {0xe76, 0xbfbfbfbf}, + {0xc6e, 0xbfffbfff}, + {0x85e, 0xbfffffff}, + {0x881, 0xc0000000}, + {0x882, 0xc0000001}, + {0x883, 0xc0000003}, + {0x884, 0xc0000007}, + {0x885, 0xc000000f}, + {0x886, 0xc000001f}, + {0x887, 0xc000003f}, + {0x888, 0xc000007f}, + {0x889, 0xc00000ff}, + {0x88a, 0xc00001ff}, + {0x88b, 0xc00003ff}, + {0x88c, 0xc00007ff}, + {0x88d, 0xc0000fff}, + {0x88e, 0xc0001fff}, + {0x88f, 0xc0003fff}, + {0x890, 0xc0007fff}, + {0xca1, 0xc000c000}, + {0x891, 0xc000ffff}, + {0xca2, 0xc001c001}, + {0x892, 0xc001ffff}, + {0xca3, 0xc003c003}, + {0x893, 0xc003ffff}, + {0xca4, 0xc007c007}, + {0x894, 0xc007ffff}, + {0xca5, 0xc00fc00f}, + {0x895, 0xc00fffff}, + {0xca6, 0xc01fc01f}, + {0x896, 0xc01fffff}, + {0xca7, 0xc03fc03f}, + {0x897, 0xc03fffff}, + {0xca8, 0xc07fc07f}, + {0x898, 0xc07fffff}, + {0xeb1, 0xc0c0c0c0}, + {0xca9, 0xc0ffc0ff}, + {0x899, 0xc0ffffff}, + {0xeb2, 0xc1c1c1c1}, + {0xcaa, 0xc1ffc1ff}, + {0x89a, 0xc1ffffff}, + {0xeb3, 0xc3c3c3c3}, + {0xcab, 0xc3ffc3ff}, + {0x89b, 0xc3ffffff}, + {0xeb4, 0xc7c7c7c7}, + {0xcac, 0xc7ffc7ff}, + {0x89c, 0xc7ffffff}, + {0xfb9, 0xcccccccc}, + {0xeb5, 0xcfcfcfcf}, + {0xcad, 0xcfffcfff}, + {0x89d, 0xcfffffff}, + {0xfba, 0xdddddddd}, + {0xeb6, 0xdfdfdfdf}, + {0xcae, 0xdfffdfff}, + {0x89e, 0xdfffffff}, + {0x8c2, 0xe0000000}, + {0x8c3, 0xe0000001}, + {0x8c4, 0xe0000003}, + {0x8c5, 0xe0000007}, + {0x8c6, 0xe000000f}, + {0x8c7, 0xe000001f}, + {0x8c8, 0xe000003f}, + {0x8c9, 0xe000007f}, + {0x8ca, 0xe00000ff}, + {0x8cb, 0xe00001ff}, + {0x8cc, 0xe00003ff}, + {0x8cd, 0xe00007ff}, + {0x8ce, 0xe0000fff}, + {0x8cf, 0xe0001fff}, + {0x8d0, 0xe0003fff}, + {0x8d1, 0xe0007fff}, + {0xce2, 0xe000e000}, + {0x8d2, 0xe000ffff}, + {0xce3, 0xe001e001}, + {0x8d3, 0xe001ffff}, + {0xce4, 0xe003e003}, + {0x8d4, 0xe003ffff}, + {0xce5, 0xe007e007}, + {0x8d5, 0xe007ffff}, + {0xce6, 0xe00fe00f}, + {0x8d6, 0xe00fffff}, + {0xce7, 0xe01fe01f}, + {0x8d7, 0xe01fffff}, + {0xce8, 0xe03fe03f}, + {0x8d8, 0xe03fffff}, + {0xce9, 0xe07fe07f}, + {0x8d9, 0xe07fffff}, + {0xef2, 0xe0e0e0e0}, + {0xcea, 0xe0ffe0ff}, + {0x8da, 0xe0ffffff}, + {0xef3, 0xe1e1e1e1}, + {0xceb, 0xe1ffe1ff}, + {0x8db, 0xe1ffffff}, + {0xef4, 0xe3e3e3e3}, + {0xcec, 0xe3ffe3ff}, + {0x8dc, 0xe3ffffff}, + {0xef5, 0xe7e7e7e7}, + {0xced, 0xe7ffe7ff}, + {0x8dd, 0xe7ffffff}, + {0xffa, 0xeeeeeeee}, + {0xef6, 0xefefefef}, + {0xcee, 0xefffefff}, + {0x8de, 0xefffffff}, + {0x903, 0xf0000000}, + {0x904, 0xf0000001}, + {0x905, 0xf0000003}, + {0x906, 0xf0000007}, + {0x907, 0xf000000f}, + {0x908, 0xf000001f}, + {0x909, 0xf000003f}, + {0x90a, 0xf000007f}, + {0x90b, 0xf00000ff}, + {0x90c, 0xf00001ff}, + {0x90d, 0xf00003ff}, + {0x90e, 0xf00007ff}, + {0x90f, 0xf0000fff}, + {0x910, 0xf0001fff}, + {0x911, 0xf0003fff}, + {0x912, 0xf0007fff}, + {0xd23, 0xf000f000}, + {0x913, 0xf000ffff}, + {0xd24, 0xf001f001}, + {0x914, 0xf001ffff}, + {0xd25, 0xf003f003}, + {0x915, 0xf003ffff}, + {0xd26, 0xf007f007}, + {0x916, 0xf007ffff}, + {0xd27, 0xf00ff00f}, + {0x917, 0xf00fffff}, + {0xd28, 0xf01ff01f}, + {0x918, 0xf01fffff}, + {0xd29, 0xf03ff03f}, + {0x919, 0xf03fffff}, + {0xd2a, 0xf07ff07f}, + {0x91a, 0xf07fffff}, + {0xf33, 0xf0f0f0f0}, + {0xd2b, 0xf0fff0ff}, + {0x91b, 0xf0ffffff}, + {0xf34, 0xf1f1f1f1}, + {0xd2c, 0xf1fff1ff}, + {0x91c, 0xf1ffffff}, + {0xf35, 0xf3f3f3f3}, + {0xd2d, 0xf3fff3ff}, + {0x91d, 0xf3ffffff}, + {0xf36, 0xf7f7f7f7}, + {0xd2e, 0xf7fff7ff}, + {0x91e, 0xf7ffffff}, + {0x944, 0xf8000000}, + {0x945, 0xf8000001}, + {0x946, 0xf8000003}, + {0x947, 0xf8000007}, + {0x948, 0xf800000f}, + {0x949, 0xf800001f}, + {0x94a, 0xf800003f}, + {0x94b, 0xf800007f}, + {0x94c, 0xf80000ff}, + {0x94d, 0xf80001ff}, + {0x94e, 0xf80003ff}, + {0x94f, 0xf80007ff}, + {0x950, 0xf8000fff}, + {0x951, 0xf8001fff}, + {0x952, 0xf8003fff}, + {0x953, 0xf8007fff}, + {0xd64, 0xf800f800}, + {0x954, 0xf800ffff}, + {0xd65, 0xf801f801}, + {0x955, 0xf801ffff}, + {0xd66, 0xf803f803}, + {0x956, 0xf803ffff}, + {0xd67, 0xf807f807}, + {0x957, 0xf807ffff}, + {0xd68, 0xf80ff80f}, + {0x958, 0xf80fffff}, + {0xd69, 0xf81ff81f}, + {0x959, 0xf81fffff}, + {0xd6a, 0xf83ff83f}, + {0x95a, 0xf83fffff}, + {0xd6b, 0xf87ff87f}, + {0x95b, 0xf87fffff}, + {0xf74, 0xf8f8f8f8}, + {0xd6c, 0xf8fff8ff}, + {0x95c, 0xf8ffffff}, + {0xf75, 0xf9f9f9f9}, + {0xd6d, 0xf9fff9ff}, + {0x95d, 0xf9ffffff}, + {0xf76, 0xfbfbfbfb}, + {0xd6e, 0xfbfffbff}, + {0x95e, 0xfbffffff}, + {0x985, 0xfc000000}, + {0x986, 0xfc000001}, + {0x987, 0xfc000003}, + {0x988, 0xfc000007}, + {0x989, 0xfc00000f}, + {0x98a, 0xfc00001f}, + {0x98b, 0xfc00003f}, + {0x98c, 0xfc00007f}, + {0x98d, 0xfc0000ff}, + {0x98e, 0xfc0001ff}, + {0x98f, 0xfc0003ff}, + {0x990, 0xfc0007ff}, + {0x991, 0xfc000fff}, + {0x992, 0xfc001fff}, + {0x993, 0xfc003fff}, + {0x994, 0xfc007fff}, + {0xda5, 0xfc00fc00}, + {0x995, 0xfc00ffff}, + {0xda6, 0xfc01fc01}, + {0x996, 0xfc01ffff}, + {0xda7, 0xfc03fc03}, + {0x997, 0xfc03ffff}, + {0xda8, 0xfc07fc07}, + {0x998, 0xfc07ffff}, + {0xda9, 0xfc0ffc0f}, + {0x999, 0xfc0fffff}, + {0xdaa, 0xfc1ffc1f}, + {0x99a, 0xfc1fffff}, + {0xdab, 0xfc3ffc3f}, + {0x99b, 0xfc3fffff}, + {0xdac, 0xfc7ffc7f}, + {0x99c, 0xfc7fffff}, + {0xfb5, 0xfcfcfcfc}, + {0xdad, 0xfcfffcff}, + {0x99d, 0xfcffffff}, + {0xfb6, 0xfdfdfdfd}, + {0xdae, 0xfdfffdff}, + {0x99e, 0xfdffffff}, + {0x9c6, 0xfe000000}, + {0x9c7, 0xfe000001}, + {0x9c8, 0xfe000003}, + {0x9c9, 0xfe000007}, + {0x9ca, 0xfe00000f}, + {0x9cb, 0xfe00001f}, + {0x9cc, 0xfe00003f}, + {0x9cd, 0xfe00007f}, + {0x9ce, 0xfe0000ff}, + {0x9cf, 0xfe0001ff}, + {0x9d0, 0xfe0003ff}, + {0x9d1, 0xfe0007ff}, + {0x9d2, 0xfe000fff}, + {0x9d3, 0xfe001fff}, + {0x9d4, 0xfe003fff}, + {0x9d5, 0xfe007fff}, + {0xde6, 0xfe00fe00}, + {0x9d6, 0xfe00ffff}, + {0xde7, 0xfe01fe01}, + {0x9d7, 0xfe01ffff}, + {0xde8, 0xfe03fe03}, + {0x9d8, 0xfe03ffff}, + {0xde9, 0xfe07fe07}, + {0x9d9, 0xfe07ffff}, + {0xdea, 0xfe0ffe0f}, + {0x9da, 0xfe0fffff}, + {0xdeb, 0xfe1ffe1f}, + {0x9db, 0xfe1fffff}, + {0xdec, 0xfe3ffe3f}, + {0x9dc, 0xfe3fffff}, + {0xded, 0xfe7ffe7f}, + {0x9dd, 0xfe7fffff}, + {0xff6, 0xfefefefe}, + {0xdee, 0xfefffeff}, + {0x9de, 0xfeffffff}, + {0xa07, 0xff000000}, + {0xa08, 0xff000001}, + {0xa09, 0xff000003}, + {0xa0a, 0xff000007}, + {0xa0b, 0xff00000f}, + {0xa0c, 0xff00001f}, + {0xa0d, 0xff00003f}, + {0xa0e, 0xff00007f}, + {0xa0f, 0xff0000ff}, + {0xa10, 0xff0001ff}, + {0xa11, 0xff0003ff}, + {0xa12, 0xff0007ff}, + {0xa13, 0xff000fff}, + {0xa14, 0xff001fff}, + {0xa15, 0xff003fff}, + {0xa16, 0xff007fff}, + {0xe27, 0xff00ff00}, + {0xa17, 0xff00ffff}, + {0xe28, 0xff01ff01}, + {0xa18, 0xff01ffff}, + {0xe29, 0xff03ff03}, + {0xa19, 0xff03ffff}, + {0xe2a, 0xff07ff07}, + {0xa1a, 0xff07ffff}, + {0xe2b, 0xff0fff0f}, + {0xa1b, 0xff0fffff}, + {0xe2c, 0xff1fff1f}, + {0xa1c, 0xff1fffff}, + {0xe2d, 0xff3fff3f}, + {0xa1d, 0xff3fffff}, + {0xe2e, 0xff7fff7f}, + {0xa1e, 0xff7fffff}, + {0xa48, 0xff800000}, + {0xa49, 0xff800001}, + {0xa4a, 0xff800003}, + {0xa4b, 0xff800007}, + {0xa4c, 0xff80000f}, + {0xa4d, 0xff80001f}, + {0xa4e, 0xff80003f}, + {0xa4f, 0xff80007f}, + {0xa50, 0xff8000ff}, + {0xa51, 0xff8001ff}, + {0xa52, 0xff8003ff}, + {0xa53, 0xff8007ff}, + {0xa54, 0xff800fff}, + {0xa55, 0xff801fff}, + {0xa56, 0xff803fff}, + {0xa57, 0xff807fff}, + {0xe68, 0xff80ff80}, + {0xa58, 0xff80ffff}, + {0xe69, 0xff81ff81}, + {0xa59, 0xff81ffff}, + {0xe6a, 0xff83ff83}, + {0xa5a, 0xff83ffff}, + {0xe6b, 0xff87ff87}, + {0xa5b, 0xff87ffff}, + {0xe6c, 0xff8fff8f}, + {0xa5c, 0xff8fffff}, + {0xe6d, 0xff9fff9f}, + {0xa5d, 0xff9fffff}, + {0xe6e, 0xffbfffbf}, + {0xa5e, 0xffbfffff}, + {0xa89, 0xffc00000}, + {0xa8a, 0xffc00001}, + {0xa8b, 0xffc00003}, + {0xa8c, 0xffc00007}, + {0xa8d, 0xffc0000f}, + {0xa8e, 0xffc0001f}, + {0xa8f, 0xffc0003f}, + {0xa90, 0xffc0007f}, + {0xa91, 0xffc000ff}, + {0xa92, 0xffc001ff}, + {0xa93, 0xffc003ff}, + {0xa94, 0xffc007ff}, + {0xa95, 0xffc00fff}, + {0xa96, 0xffc01fff}, + {0xa97, 0xffc03fff}, + {0xa98, 0xffc07fff}, + {0xea9, 0xffc0ffc0}, + {0xa99, 0xffc0ffff}, + {0xeaa, 0xffc1ffc1}, + {0xa9a, 0xffc1ffff}, + {0xeab, 0xffc3ffc3}, + {0xa9b, 0xffc3ffff}, + {0xeac, 0xffc7ffc7}, + {0xa9c, 0xffc7ffff}, + {0xead, 0xffcfffcf}, + {0xa9d, 0xffcfffff}, + {0xeae, 0xffdfffdf}, + {0xa9e, 0xffdfffff}, + {0xaca, 0xffe00000}, + {0xacb, 0xffe00001}, + {0xacc, 0xffe00003}, + {0xacd, 0xffe00007}, + {0xace, 0xffe0000f}, + {0xacf, 0xffe0001f}, + {0xad0, 0xffe0003f}, + {0xad1, 0xffe0007f}, + {0xad2, 0xffe000ff}, + {0xad3, 0xffe001ff}, + {0xad4, 0xffe003ff}, + {0xad5, 0xffe007ff}, + {0xad6, 0xffe00fff}, + {0xad7, 0xffe01fff}, + {0xad8, 0xffe03fff}, + {0xad9, 0xffe07fff}, + {0xeea, 0xffe0ffe0}, + {0xada, 0xffe0ffff}, + {0xeeb, 0xffe1ffe1}, + {0xadb, 0xffe1ffff}, + {0xeec, 0xffe3ffe3}, + {0xadc, 0xffe3ffff}, + {0xeed, 0xffe7ffe7}, + {0xadd, 0xffe7ffff}, + {0xeee, 0xffefffef}, + {0xade, 0xffefffff}, + {0xb0b, 0xfff00000}, + {0xb0c, 0xfff00001}, + {0xb0d, 0xfff00003}, + {0xb0e, 0xfff00007}, + {0xb0f, 0xfff0000f}, + {0xb10, 0xfff0001f}, + {0xb11, 0xfff0003f}, + {0xb12, 0xfff0007f}, + {0xb13, 0xfff000ff}, + {0xb14, 0xfff001ff}, + {0xb15, 0xfff003ff}, + {0xb16, 0xfff007ff}, + {0xb17, 0xfff00fff}, + {0xb18, 0xfff01fff}, + {0xb19, 0xfff03fff}, + {0xb1a, 0xfff07fff}, + {0xf2b, 0xfff0fff0}, + {0xb1b, 0xfff0ffff}, + {0xf2c, 0xfff1fff1}, + {0xb1c, 0xfff1ffff}, + {0xf2d, 0xfff3fff3}, + {0xb1d, 0xfff3ffff}, + {0xf2e, 0xfff7fff7}, + {0xb1e, 0xfff7ffff}, + {0xb4c, 0xfff80000}, + {0xb4d, 0xfff80001}, + {0xb4e, 0xfff80003}, + {0xb4f, 0xfff80007}, + {0xb50, 0xfff8000f}, + {0xb51, 0xfff8001f}, + {0xb52, 0xfff8003f}, + {0xb53, 0xfff8007f}, + {0xb54, 0xfff800ff}, + {0xb55, 0xfff801ff}, + {0xb56, 0xfff803ff}, + {0xb57, 0xfff807ff}, + {0xb58, 0xfff80fff}, + {0xb59, 0xfff81fff}, + {0xb5a, 0xfff83fff}, + {0xb5b, 0xfff87fff}, + {0xf6c, 0xfff8fff8}, + {0xb5c, 0xfff8ffff}, + {0xf6d, 0xfff9fff9}, + {0xb5d, 0xfff9ffff}, + {0xf6e, 0xfffbfffb}, + {0xb5e, 0xfffbffff}, + {0xb8d, 0xfffc0000}, + {0xb8e, 0xfffc0001}, + {0xb8f, 0xfffc0003}, + {0xb90, 0xfffc0007}, + {0xb91, 0xfffc000f}, + {0xb92, 0xfffc001f}, + {0xb93, 0xfffc003f}, + {0xb94, 0xfffc007f}, + {0xb95, 0xfffc00ff}, + {0xb96, 0xfffc01ff}, + {0xb97, 0xfffc03ff}, + {0xb98, 0xfffc07ff}, + {0xb99, 0xfffc0fff}, + {0xb9a, 0xfffc1fff}, + {0xb9b, 0xfffc3fff}, + {0xb9c, 0xfffc7fff}, + {0xfad, 0xfffcfffc}, + {0xb9d, 0xfffcffff}, + {0xfae, 0xfffdfffd}, + {0xb9e, 0xfffdffff}, + {0xbce, 0xfffe0000}, + {0xbcf, 0xfffe0001}, + {0xbd0, 0xfffe0003}, + {0xbd1, 0xfffe0007}, + {0xbd2, 0xfffe000f}, + {0xbd3, 0xfffe001f}, + {0xbd4, 0xfffe003f}, + {0xbd5, 0xfffe007f}, + {0xbd6, 0xfffe00ff}, + {0xbd7, 0xfffe01ff}, + {0xbd8, 0xfffe03ff}, + {0xbd9, 0xfffe07ff}, + {0xbda, 0xfffe0fff}, + {0xbdb, 0xfffe1fff}, + {0xbdc, 0xfffe3fff}, + {0xbdd, 0xfffe7fff}, + {0xfee, 0xfffefffe}, + {0xbde, 0xfffeffff}, + {0xc0f, 0xffff0000}, + {0xc10, 0xffff0001}, + {0xc11, 0xffff0003}, + {0xc12, 0xffff0007}, + {0xc13, 0xffff000f}, + {0xc14, 0xffff001f}, + {0xc15, 0xffff003f}, + {0xc16, 0xffff007f}, + {0xc17, 0xffff00ff}, + {0xc18, 0xffff01ff}, + {0xc19, 0xffff03ff}, + {0xc1a, 0xffff07ff}, + {0xc1b, 0xffff0fff}, + {0xc1c, 0xffff1fff}, + {0xc1d, 0xffff3fff}, + {0xc1e, 0xffff7fff}, + {0xc50, 0xffff8000}, + {0xc51, 0xffff8001}, + {0xc52, 0xffff8003}, + {0xc53, 0xffff8007}, + {0xc54, 0xffff800f}, + {0xc55, 0xffff801f}, + {0xc56, 0xffff803f}, + {0xc57, 0xffff807f}, + {0xc58, 0xffff80ff}, + {0xc59, 0xffff81ff}, + {0xc5a, 0xffff83ff}, + {0xc5b, 0xffff87ff}, + {0xc5c, 0xffff8fff}, + {0xc5d, 0xffff9fff}, + {0xc5e, 0xffffbfff}, + {0xc91, 0xffffc000}, + {0xc92, 0xffffc001}, + {0xc93, 0xffffc003}, + {0xc94, 0xffffc007}, + {0xc95, 0xffffc00f}, + {0xc96, 0xffffc01f}, + {0xc97, 0xffffc03f}, + {0xc98, 0xffffc07f}, + {0xc99, 0xffffc0ff}, + {0xc9a, 0xffffc1ff}, + {0xc9b, 0xffffc3ff}, + {0xc9c, 0xffffc7ff}, + {0xc9d, 0xffffcfff}, + {0xc9e, 0xffffdfff}, + {0xcd2, 0xffffe000}, + {0xcd3, 0xffffe001}, + {0xcd4, 0xffffe003}, + {0xcd5, 0xffffe007}, + {0xcd6, 0xffffe00f}, + {0xcd7, 0xffffe01f}, + {0xcd8, 0xffffe03f}, + {0xcd9, 0xffffe07f}, + {0xcda, 0xffffe0ff}, + {0xcdb, 0xffffe1ff}, + {0xcdc, 0xffffe3ff}, + {0xcdd, 0xffffe7ff}, + {0xcde, 0xffffefff}, + {0xd13, 0xfffff000}, + {0xd14, 0xfffff001}, + {0xd15, 0xfffff003}, + {0xd16, 0xfffff007}, + {0xd17, 0xfffff00f}, + {0xd18, 0xfffff01f}, + {0xd19, 0xfffff03f}, + {0xd1a, 0xfffff07f}, + {0xd1b, 0xfffff0ff}, + {0xd1c, 0xfffff1ff}, + {0xd1d, 0xfffff3ff}, + {0xd1e, 0xfffff7ff}, + {0xd54, 0xfffff800}, + {0xd55, 0xfffff801}, + {0xd56, 0xfffff803}, + {0xd57, 0xfffff807}, + {0xd58, 0xfffff80f}, + {0xd59, 0xfffff81f}, + {0xd5a, 0xfffff83f}, + {0xd5b, 0xfffff87f}, + {0xd5c, 0xfffff8ff}, + {0xd5d, 0xfffff9ff}, + {0xd5e, 0xfffffbff}, + {0xd95, 0xfffffc00}, + {0xd96, 0xfffffc01}, + {0xd97, 0xfffffc03}, + {0xd98, 0xfffffc07}, + {0xd99, 0xfffffc0f}, + {0xd9a, 0xfffffc1f}, + {0xd9b, 0xfffffc3f}, + {0xd9c, 0xfffffc7f}, + {0xd9d, 0xfffffcff}, + {0xd9e, 0xfffffdff}, + {0xdd6, 0xfffffe00}, + {0xdd7, 0xfffffe01}, + {0xdd8, 0xfffffe03}, + {0xdd9, 0xfffffe07}, + {0xdda, 0xfffffe0f}, + {0xddb, 0xfffffe1f}, + {0xddc, 0xfffffe3f}, + {0xddd, 0xfffffe7f}, + {0xdde, 0xfffffeff}, + {0xe17, 0xffffff00}, + {0xe18, 0xffffff01}, + {0xe19, 0xffffff03}, + {0xe1a, 0xffffff07}, + {0xe1b, 0xffffff0f}, + {0xe1c, 0xffffff1f}, + {0xe1d, 0xffffff3f}, + {0xe1e, 0xffffff7f}, + {0xe58, 0xffffff80}, + {0xe59, 0xffffff81}, + {0xe5a, 0xffffff83}, + {0xe5b, 0xffffff87}, + {0xe5c, 0xffffff8f}, + {0xe5d, 0xffffff9f}, + {0xe5e, 0xffffffbf}, + {0xe99, 0xffffffc0}, + {0xe9a, 0xffffffc1}, + {0xe9b, 0xffffffc3}, + {0xe9c, 0xffffffc7}, + {0xe9d, 0xffffffcf}, + {0xe9e, 0xffffffdf}, + {0xeda, 0xffffffe0}, + {0xedb, 0xffffffe1}, + {0xedc, 0xffffffe3}, + {0xedd, 0xffffffe7}, + {0xede, 0xffffffef}, + {0xf1b, 0xfffffff0}, + {0xf1c, 0xfffffff1}, + {0xf1d, 0xfffffff3}, + {0xf1e, 0xfffffff7}, + {0xf5c, 0xfffffff8}, + {0xf5d, 0xfffffff9}, + {0xf5e, 0xfffffffb}, + {0xf9d, 0xfffffffc}, + {0xf9e, 0xfffffffd}, + {0xfde, 0xfffffffe}, +}; + +uint32_t host_arm64_find_imm(uint32_t data) +{ + int l = 0, r = IMM_NR - 1; + + while (l <= r) + { + int m = (l + r) >> 1; + + if (imm_table[m][1] < data) + l = m+1; + else if (imm_table[m][1] > data) + r = m-1; + else + return imm_table[m][0]; + } + return 0; +} diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 1bc49c0..552665a 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -218,6 +218,8 @@ #define IMMR(immr) ((immr) << 16) #define IMMS(imms) ((imms) << 10) +#define IMM_LOGICAL(imm) ((imm) << 10) + #define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) #define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) @@ -379,25 +381,11 @@ void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07)); - } - else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else if (imm_data == 0xffffff00) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); - } - else if (imm_data == 0xffff00ff) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); - } - else if (imm_data == 0x0000ff00) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07)); + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); } else { @@ -424,25 +412,11 @@ void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */ + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07)); - } - else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else if (imm_data == 0xffffff00) - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); - } - else if (imm_data == 0xffff00ff) - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); - } - else if (imm_data == 0x0000ff00) - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07)); + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); } else { @@ -722,9 +696,11 @@ void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int elem void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { - codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); } else { @@ -1062,21 +1038,11 @@ void host_arm64_NOP(codeblock_t *block) void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); - } - else if (imm_data == 0xffff0000) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x0f)); - } - else if (imm_data == 0xffffff00) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17)); - } - else if (imm_data == 0xffff00ff) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17)); + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); } else { From f7c7f46712cee0998d609c7a66ea6128e5e76647 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 14 Apr 2019 15:38:45 +0100 Subject: [PATCH 0672/1050] Add missing ARM64 file to Makefile.am --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 7d2b106..7528428 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,7 +85,7 @@ pcem_SOURCES += codegen_backend_arm.c codegen_backend_arm_ops.c codegen_backend_ endif if CPU_ARM64 -pcem_SOURCES += codegen_backend_arm64.c codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c +pcem_SOURCES += codegen_backend_arm64.c codegen_backend_arm64_imm.c codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c endif if USE_NETWORKING From d527736d21944b201b75b2d8550ce99f468cd774 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 14 Apr 2019 17:03:07 +0100 Subject: [PATCH 0673/1050] ARM64 fixes - mask off immediate data in UOP_MOV_IMM to the destination size, and add UOP_MOVZX_REG_PTR_16 to uop list. --- src/codegen_backend_arm64_uops.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 5a92749..0cad9bb 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -1246,16 +1246,16 @@ static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) } else if (REG_IS_W(dest_size)) { - host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data); + host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); } else if (REG_IS_B(dest_size)) { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data); + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); } else if (REG_IS_BH(dest_size)) { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data); + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); } else @@ -3051,6 +3051,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, From 18a293d5ccb964b08723b487db89e774713c6cce Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 14 Apr 2019 21:40:32 +0100 Subject: [PATCH 0674/1050] Flush MMU cache on CPU soft reset. Fixes hang on reset under some configurations. --- src/808x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/808x.c b/src/808x.c index 1336727..3ac3dae 100644 --- a/src/808x.c +++ b/src/808x.c @@ -680,6 +680,7 @@ void softresetx86() idt.limit = is386 ? 0x03FF : 0xFFFF; EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; x86seg_reset(); + flushmmucache(); x86_was_reset = 1; } From 1f5fc45c0466feecd1958a1140c8723051b699ff Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 15 Apr 2019 19:48:41 +0100 Subject: [PATCH 0675/1050] Amstrad changes : - Add PPC512/640 emulation - Add TV display type to Sinclair PC200 - Add font selection to PC1512 - Add disc change line to PC200 Patch from JohnElliott --- src/amstrad.c | 21 +- src/fdc.c | 5 + src/fdc.h | 1 + src/ibm.h | 3 +- src/mem_bios.c | 29 +- src/model.c | 6 + src/model.h | 1 + src/nvr.c | 11 +- src/vid_ati28800.c | 2 +- src/vid_genius.c | 1 - src/vid_mda.c | 46 +- src/vid_mda.h | 37 ++ src/vid_pc1512.c | 69 ++- src/vid_pc200.c | 1039 ++++++++++++++++++++++++++++++++++++++++++-- src/vid_pc200.h | 3 + src/vid_sigma.c | 1 - src/vid_wy700.c | 1 - src/video.c | 103 +++-- src/video.h | 20 +- src/wx-config.c | 20 +- 20 files changed, 1281 insertions(+), 138 deletions(-) diff --git a/src/amstrad.c b/src/amstrad.c index 8817229..acd5070 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -5,6 +5,7 @@ #include "lpt.h" #include "mouse.h" #include "video.h" +#include "fdc.h" #include "amstrad.h" @@ -25,12 +26,15 @@ uint8_t amstrad_read(uint16_t port, void *priv) case 0x37a: temp = lpt1_read(port, NULL) & 0x1f; if (romset == ROM_PC1512) return temp | 0x20; - if (romset == ROM_PC200) + if (romset == ROM_PC200 || romset == ROM_PPC512) { + if (fdc_discchange_read()) + temp |= 0x20; +/* DIP switches 4,5: Initial video mode */ if (video_is_cga()) - temp |= 0x80; + temp |= 0x80; /* CGA 80 */ else if (video_is_mda()) - temp |= 0xc0; + temp |= 0xc0; /* MDA */ return temp; } if (romset == ROM_PC1640) @@ -55,8 +59,13 @@ uint8_t amstrad_read(uint16_t port, void *priv) } return temp; case 0x3de: - return 0x20; /*PC200 - use external video. If internal video is being used - then this port is handled in vid_pc200.c*/ + if (romset == ROM_PC200 || romset == ROM_PPC512) + { +/* Read DIP switches / internal display adapter status. This code is only + * reached if the IDA is disabled; if it is enabled this read will be + * handled by the video card */ + } + return 0x20; /* Disable IDA */ case 0xdead: return amstrad_dead; } @@ -153,6 +162,6 @@ void amstrad_init() io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); io_sethandler(0x0378, 0x0003, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); - if (romset == ROM_PC200 && gfxcard != GFX_BUILTIN) + if ((romset == ROM_PC200 || romset == ROM_PPC512) && gfxcard != GFX_BUILTIN) io_sethandler(0x03de, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); } diff --git a/src/fdc.c b/src/fdc.c index bec48bc..25ab9f0 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -1421,6 +1421,11 @@ void fdc_discchange_clear(int drive) disc_changed[drive] = 0; } +int fdc_discchange_read() +{ + return (disc_changed[fdc.drive] || drive_empty[fdc.drive]) ? 1 : 0; +} + void fdc_set_dskchg_activelow() { fdc.dskchg_activelow = 1; diff --git a/src/fdc.h b/src/fdc.h index ec198b8..ff8d540 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -7,6 +7,7 @@ void fdc_reset(); void fdc_poll(); void fdc_abort(); void fdc_discchange_clear(int drive); +int fdc_discchange_read(); void fdc_set_dskchg_activelow(); void fdc_3f1_enable(int enable); void fdc_set_ps1(); diff --git a/src/ibm.h b/src/ibm.h index e7dca29..ed3aac2 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -468,7 +468,8 @@ enum ROM_TULIP_TC7, ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */ ROM_PB410A, - + ROM_PPC512, + ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index c49271e..0f04f5f 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -59,9 +59,9 @@ int loadbios() FILE *f=NULL,*ff=NULL; int c; - loadfont("mda.rom", 0); - loadfont("wy700.rom", 3); - loadfont("8x12.bin", 4); + loadfont("mda.rom", FONT_MDA); + loadfont("wy700.rom", FONT_WY700); + loadfont("8x12.bin", FONT_MDSI); biosmask = 0xffff; @@ -85,7 +85,7 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("pc1512/40078.ic127", 2); + loadfont("pc1512/40078.ic127", FONT_CGA); return 1; case ROM_PC1640: f=romfopen("pc1640/40044.v3","rb"); @@ -113,7 +113,20 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("pc200/40109.bin", 1); + loadfont("pc200/40109.bin", FONT_PC200); + return 1; + case ROM_PPC512: + f=romfopen("ppc512/40107.v2","rb"); + ff=romfopen("ppc512/40108.v2","rb"); + if (!f || !ff) break; + for (c=0xC000;c<0x10000;c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + loadfont("ppc512/40109.bin", FONT_PC200); return 1; case ROM_TANDY: f=romfopen("tandy/tandy1t1.020","rb"); @@ -759,7 +772,7 @@ int loadbios() return 1; case ROM_T3100E: - loadfont("t3100e/t3100e_font.bin", 5); + loadfont("t3100e/t3100e_font.bin", FONT_T3100E); f=romfopen("t3100e/t3100e.rom","rb"); if (!f) break; romfread(rom,65536,1,f); @@ -767,7 +780,7 @@ int loadbios() return 1; case ROM_T1000: - loadfont("t1000/t1000font.rom", 2); + loadfont("t1000/t1000font.rom", FONT_CGA); f=romfopen("t1000/t1000.rom","rb"); if (!f) break; romfread(rom, 0x8000,1,f); @@ -777,7 +790,7 @@ int loadbios() return 1; case ROM_T1200: - loadfont("t1200/t1000font.rom", 2); + loadfont("t1200/t1000font.rom", FONT_CGA); f=romfopen("t1200/t1200_019e.ic15.bin","rb"); if (!f) break; romfread(rom, 0x8000,1,f); diff --git a/src/model.c b/src/model.c index fa7599c..a5ad2ef 100644 --- a/src/model.c +++ b/src/model.c @@ -145,6 +145,7 @@ MODEL models[] = {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}, @@ -219,6 +220,11 @@ int model_getromset() return models[model].id; } +int model_getromset_from_model(int model) +{ + return models[model].id; +} + int model_getmodel(int romset) { int c = 0; diff --git a/src/model.h b/src/model.h index 11c442d..7b568f1 100644 --- a/src/model.h +++ b/src/model.h @@ -39,6 +39,7 @@ extern int model; int model_count(); int model_getromset(); +int model_getromset_from_model(int model); int model_getmodel(int romset); char *model_getname(); char *model_get_internal_name(); diff --git a/src/nvr.c b/src/nvr.c index 4857825..a09cb4d 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -211,8 +211,15 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) are always enabled for PS/2 machines - this would mean that other peripherals could fire NMIs regardless of the mask state, but as there aren't any emulated MCA peripherals that do this it's currently a moot point.*/ - if (!(models[model].flags & MODEL_MCA)) + + /* Also don't update the NMI mask on Amstrad PCs - actually + * ought not to do it for any XT because their NMI mask + * register is at 0xA0. But particularly important on the + * PC200 and PPC because their video subsystem issues NMIs */ + if (!(models[model].flags & (MODEL_MCA | MODEL_AMSTRAD))) + { nmi_mask = ~val & 0x80; + } } } @@ -255,6 +262,7 @@ void loadnvr() case ROM_PC200: f = nvrfopen("pc200.nvr", "rb"); break; case ROM_PC2086: f = nvrfopen("pc2086.nvr", "rb"); break; case ROM_PC3086: f = nvrfopen("pc3086.nvr", "rb"); break; + case ROM_PPC512: f = nvrfopen("ppc512.nvr", "rb"); break; case ROM_IBMAT: f = nvrfopen("at.nvr", "rb"); break; case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "rb"); break; case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break; @@ -352,6 +360,7 @@ void savenvr() case ROM_PC200: f = nvrfopen("pc200.nvr", "wb"); break; case ROM_PC2086: f = nvrfopen("pc2086.nvr", "wb"); break; case ROM_PC3086: f = nvrfopen("pc3086.nvr", "wb"); break; + case ROM_PPC512: f = nvrfopen("ppc512.nvr", "wb"); break; case ROM_IBMAT: f = nvrfopen("at.nvr", "wb"); break; case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "wb"); break; case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "wb"); break; diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 845b0ee..026de97 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -364,7 +364,7 @@ void *ati28800k_init() ati28800->ksc5601_mode_enabled = 0; rom_init(&ati28800->bios_rom, "atikorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont("ati_ksc5601.rom", 6); + loadfont("ati_ksc5601.rom", FONT_KSC5601); svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ ati28800k_recalctimings, diff --git a/src/vid_genius.c b/src/vid_genius.c index 088cdf2..735d6ad 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]; diff --git a/src/vid_mda.c b/src/vid_mda.c index fdb549e..3265bb4 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -8,29 +8,6 @@ #include "video.h" #include "vid_mda.h" -typedef struct mda_t -{ - mem_mapping_t mapping; - - uint8_t crtc[32]; - int crtcreg; - - uint8_t ctrl, stat; - - int dispontime, dispofftime; - int vidtime; - - int firstline, lastline; - - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int vsynctime, vadj; - - uint8_t *vram; -} mda_t; static uint32_t mdacols[256][2][2]; @@ -261,19 +238,27 @@ void mda_poll(void *p) } } -void *mda_init() +void *mda_standalone_init() { - int display_type; - int c; mda_t *mda = malloc(sizeof(mda_t)); + memset(mda, 0, sizeof(mda_t)); + mda_init(mda); mda->vram = malloc(0x1000); - timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + return mda; +} + + +void mda_init(mda_t *mda) +{ + int display_type; + int c; + display_type = device_get_config_int("display_type"); cgapal_rebuild(display_type, 0); @@ -295,8 +280,11 @@ void *mda_init() mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; +} - return mda; +void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) +{ + mdacols[chr][blink][fg] = cgapal[cga_ink]; } void mda_close(void *p) @@ -349,7 +337,7 @@ device_t mda_device = { "MDA", 0, - mda_init, + mda_standalone_init, mda_close, NULL, mda_speed_changed, diff --git a/src/vid_mda.h b/src/vid_mda.h index 99aa13c..e61b15e 100644 --- a/src/vid_mda.h +++ b/src/vid_mda.h @@ -1 +1,38 @@ + +typedef struct mda_t +{ + mem_mapping_t mapping; + + uint8_t crtc[32]; + int crtcreg; + + uint8_t ctrl, stat; + + int dispontime, dispofftime; + int vidtime; + + int firstline, lastline; + + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime, vadj; + + uint8_t *vram; +} mda_t; + +void mda_init(mda_t *mda); +void mda_out(uint16_t addr, uint8_t val, void *p); +uint8_t mda_in(uint16_t addr, void *p); +void mda_write(uint32_t addr, uint8_t val, void *p); +uint8_t mda_read(uint32_t addr, void *p); +void mda_recalctimings(mda_t *mda); +void mda_poll(void *p); + +/* Override mapping of attribute to colour */ +void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink); + extern device_t mda_device; + diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 0b5f89a..f643692 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -26,6 +26,7 @@ typedef struct pc1512_t uint8_t plane_write, plane_read, border; + int fontbase; int linepos, displine; int sc, vc; int cgadispon; @@ -220,12 +221,12 @@ static void pc1512_poll(void *p) if (drawcursor) { for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } pc1512->ma++; } @@ -254,13 +255,13 @@ static void pc1512_poll(void *p) { for (c = 0; c < 8; c++) ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { for (c = 0; c < 8; c++) ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } @@ -451,6 +452,7 @@ static void pc1512_poll(void *p) static void *pc1512_init() { + int display_type; pc1512_t *pc1512 = malloc(sizeof(pc1512_t)); memset(pc1512, 0, sizeof(pc1512_t)); @@ -458,10 +460,13 @@ static void *pc1512_init() pc1512->cgacol = 7; pc1512->cgamode = 0x12; - + pc1512->fontbase = (device_get_config_int("codepage") & 3) * 256; + display_type = device_get_config_int("display_type"); + timer_add(pc1512_poll, &pc1512->vidtime, TIMER_ALWAYS_ENABLED, pc1512); mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL, 0, pc1512); io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512); + cgapal_rebuild(display_type, 0); return pc1512; } @@ -480,6 +485,57 @@ static void pc1512_speed_changed(void *p) pc1512_recalctimings(pc1512); } +device_config_t pc1512_config[] = +{ + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "PC-CM (Colour)", + .value = DISPLAY_RGB + }, + { + .description = "PC-MM (Monochrome)", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + } + }, + { + .name = "codepage", + .description = "Hardware font", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "US English", + .value = 3 + }, + { + .description = "Danish", + .value = 1 + }, + { + .description = "Greek", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 3 + }, + { + .type = -1 + } +}; + + device_t pc1512_device = { "Amstrad PC1512 (video)", @@ -489,5 +545,6 @@ device_t pc1512_device = NULL, pc1512_speed_changed, NULL, - NULL + NULL, + pc1512_config }; diff --git a/src/vid_pc200.c b/src/vid_pc200.c index 06f511d..737e943 100644 --- a/src/vid_pc200.c +++ b/src/vid_pc200.c @@ -1,23 +1,51 @@ -/*PC200 video emulation. - 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*/ +/*PC200/PPC video emulation. */ #include #include "ibm.h" #include "device.h" #include "io.h" #include "mem.h" +#include "nmi.h" #include "timer.h" #include "video.h" #include "vid_cga.h" +#include "vid_mda.h" #include "vid_pc200.h" +/* #define PC200LOG(x) pclog x */ +#define PC200LOG(x) + +/* Display type */ +#define PC200_CGA 0 /* CGA monitor */ +#define PC200_MDA 1 /* MDA monitor */ +#define PC200_TV 2 /* Television */ +#define PC200_LCDC 3 /* PPC512 LCD as CGA*/ +#define PC200_LCDM 4 /* PPC512 LCD as MDA*/ + +int pc200_is_mda; + +static uint32_t blue, green; + +static uint32_t lcdcols[256][2][2]; + typedef struct pc200_t { - mem_mapping_t mapping; + mem_mapping_t cga_mapping; + mem_mapping_t mda_mapping; cga_t cga; + mda_t mda; - uint8_t reg_3dd, reg_3de, reg_3df; + int vidtime; + + uint8_t emulation; /* Which display are we emulating? */ + uint8_t dipswitches; /* DIP switches 1-3 */ + uint8_t crtc_index; /* CRTC index readback + * Bit 7: CGA control port written + * Bit 6: Operation control port written + * Bit 5: CRTC register written + * Bits 0-4: Last CRTC register selected */ + uint8_t operation_ctrl; + uint8_t reg_3df; } pc200_t; static uint8_t crtcmask[32] = @@ -26,24 +54,187 @@ static uint8_t crtcmask[32] = 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static void setvidtime(pc200_t *pc200) +{ + switch (pc200->emulation) + { + case PC200_CGA: + case PC200_TV: + case PC200_LCDC: + pc200->vidtime = pc200->cga.vidtime; + break; + + case PC200_MDA: + case PC200_LCDM: + pc200->vidtime = pc200->mda.vidtime; + break; + } +} + +/* LCD colour mappings + * + * 0 => solid green + * 1 => blue on green + * 2 => green on blue + * 3 => solid blue + */ +static unsigned char mapping1[256] = +{ +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ +/*00*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/*10*/ 2, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, +/*20*/ 2, 2, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, +/*30*/ 2, 2, 2, 0, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, +/*40*/ 2, 2, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, +/*50*/ 2, 2, 1, 1, 2, 0, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, +/*60*/ 2, 2, 2, 2, 2, 2, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, +/*70*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, +/*80*/ 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, +/*90*/ 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, +/*A0*/ 2, 2, 2, 1, 2, 2, 1, 1, 2, 2, 0, 1, 2, 2, 1, 1, +/*B0*/ 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 0, 2, 2, 1, 1, +/*C0*/ 2, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 0, 1, 1, 1, +/*D0*/ 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 0, 1, 1, +/*E0*/ 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 1, +/*F0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, +}; + +static unsigned char mapping2[256] = +{ +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ +/*00*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/*10*/ 1, 3, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, +/*20*/ 1, 1, 3, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, +/*30*/ 1, 1, 1, 3, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 2, +/*40*/ 1, 1, 2, 2, 3, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, +/*50*/ 1, 1, 2, 2, 1, 3, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, +/*60*/ 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 2, 2, +/*70*/ 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 2, +/*80*/ 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, +/*90*/ 1, 1, 2, 2, 2, 2, 2, 2, 1, 3, 2, 2, 2, 2, 2, 2, +/*A0*/ 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 3, 2, 1, 1, 2, 2, +/*B0*/ 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 2, 2, +/*C0*/ 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 3, 2, 2, 2, +/*D0*/ 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 3, 2, 2, +/*E0*/ 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, +/*F0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, +}; + +static void set_lcd_cols(uint8_t mode_reg) +{ + unsigned char *mapping = (mode_reg & 0x80) ? mapping2 : mapping1; + int c; + + for (c = 0; c < 256; c++) + { + switch (mapping[c]) + { + case 0: + lcdcols[c][0][0] = lcdcols[c][1][0] = green; + lcdcols[c][0][1] = lcdcols[c][1][1] = green; + break; + + case 1: + lcdcols[c][0][0] = lcdcols[c][1][0] = + lcdcols[c][1][1] = green; + lcdcols[c][0][1] = blue; + break; + + case 2: + lcdcols[c][0][0] = lcdcols[c][1][0] = + lcdcols[c][1][1] = blue; + lcdcols[c][0][1] = green; + break; + + case 3: + lcdcols[c][0][0] = lcdcols[c][1][0] = blue; + lcdcols[c][0][1] = lcdcols[c][1][1] = blue; + break; + } + } +} + + void pc200_out(uint16_t addr, uint8_t val, void *p) { pc200_t *pc200 = (pc200_t *)p; cga_t *cga = &pc200->cga; + mda_t *mda = &pc200->mda; uint8_t old; - + + PC200LOG(("pc200_out(0x%04x), %02x\n", addr, val)); + +/* MDA writes ============================================================== */ switch (addr) { - case 0x3d5: - if (!(pc200->reg_3de & 0x40) && cga->crtcreg <= 11) + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + + /* Writes banned to CRTC registers 0-11? */ + if (!(pc200->operation_ctrl & 0x40) && mda->crtcreg <= 11) { - if (pc200->reg_3de & 0x80) + pc200->crtc_index = 0x20 | (mda->crtcreg & 0x1f); + if (pc200->operation_ctrl & 0x80) + { + PC200LOG(("NMI raised from CRTC register access: reg=0x%02x val=0x%02x nmi_mask=%d\n", mda->crtcreg & 0x1F, val, nmi_mask)); nmi = 1; - - pc200->reg_3dd = 0x20 | (cga->crtcreg & 0x1f); + } pc200->reg_3df = val; return; } + PC200LOG(("CRTM[%02x]:=%02x\n", mda->crtcreg, val)); + old = mda->crtc[mda->crtcreg]; + mda->crtc[mda->crtcreg] = val & crtcmask[mda->crtcreg]; + if (old != val) + { + if (mda->crtcreg < 0xe || mda->crtcreg > 0x10) + { + fullchange = changeframecount; + mda_recalctimings(mda); + setvidtime(pc200); + } + } + return; + + case 0x3b8: + old = mda->ctrl; + mda->ctrl = val; + if ((mda->ctrl ^ old) & 3) + { + mda_recalctimings(mda); + setvidtime(pc200); + } + pc200->crtc_index &= 0x1F; + pc200->crtc_index |= 0x80; + if (pc200->operation_ctrl & 0x80) + { + PC200LOG(("NMI raised from mode control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); + nmi = 1; + } + return; + + +/* CGA writes ============================================================== */ + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + + /* Writes banned to CRTC registers 0-11? */ + if (!(pc200->operation_ctrl & 0x40) && cga->crtcreg <= 11) + { + pc200->crtc_index = 0x20 | (cga->crtcreg & 0x1f); + if (pc200->operation_ctrl & 0x80) + { + PC200LOG(("NMI raised from CRTC register access: reg=0x%02x val=0x%02x nmi_mask=%d\n", cga->crtcreg & 0x1F, val, nmi_mask)); + nmi = 1; + } + pc200->reg_3df = val; + return; + } + PC200LOG(("CRTC[%02x]:=%02x\n", cga->crtcreg, val)); old = cga->crtc[cga->crtcreg]; cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; if (old != val) @@ -52,6 +243,7 @@ void pc200_out(uint16_t addr, uint8_t val, void *p) { fullchange = changeframecount; cga_recalctimings(cga); + setvidtime(pc200); } } return; @@ -60,60 +252,636 @@ void pc200_out(uint16_t addr, uint8_t val, void *p) old = cga->cgamode; cga->cgamode = val; if ((cga->cgamode ^ old) & 3) - cga_recalctimings(cga); - pc200->reg_3dd |= 0x80; - if (pc200->reg_3de & 0x80) - nmi = 1; + { + cga_recalctimings(cga); + setvidtime(pc200); + } + pc200->crtc_index &= 0x1F; + pc200->crtc_index |= 0x80; + if (pc200->operation_ctrl & 0x80) + { + PC200LOG(("NMI raised from mode control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); + nmi = 1; + } + else set_lcd_cols(val); return; +/* PC200 control port writes ============================================== */ case 0x3de: - pc200->reg_3de = val; - pc200->reg_3dd = 0x1f; - if (val & 0x80) - pc200->reg_3dd |= 0x40; + pc200->crtc_index = 0x1f; +/* NMI only seems to be triggered if the value being written has the high + * bit set (enable NMI). So it only protects writes to this port if you + * let it? */ + if (val & 0x80) + { + PC200LOG(("NMI raised from operation control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); + pc200->operation_ctrl = val; + pc200->crtc_index |= 0x40; + nmi = 1; + return; + } + pc200->operation_ctrl = val; + /* Bits 0 and 1 control emulation and output mode */ + if (val & 1) /* Monitor */ + { + pc200->emulation = (val & 2) ? PC200_MDA : PC200_CGA; + } + else if (romset == ROM_PPC512) + { + pc200->emulation = (val & 2) ? PC200_LCDM : PC200_LCDC; + } + else + { + pc200->emulation = PC200_TV; + + } + PC200LOG(("Video emulation set to %d\n", pc200->emulation)); + /* Bit 2 disables the IDA. We don't support dynamic enabling + * and disabling of the IDA (instead, PCEM disconnects the + * IDA from the bus altogether) so don't implement this */ + + /* Enable the appropriate memory ranges depending whether + * the IDA is configured as MDA or CGA */ + if (pc200->emulation == PC200_MDA || + pc200->emulation == PC200_LCDM) + { + mem_mapping_disable(&pc200->cga_mapping); + mem_mapping_enable(&pc200->mda_mapping); + } + else + { + mem_mapping_disable(&pc200->mda_mapping); + mem_mapping_enable(&pc200->cga_mapping); + } return; } - cga_out(addr, val, cga); + if (addr >= 0x3D0 && addr <= 0x3DF) + { + cga_out(addr, val, cga); + } + if (addr >= 0x3B0 && addr <= 0x3BB) + { + mda_out(addr, val, mda); + } } uint8_t pc200_in(uint16_t addr, void *p) { pc200_t *pc200 = (pc200_t *)p; cga_t *cga = &pc200->cga; + mda_t *mda = &pc200->mda; uint8_t temp; + PC200LOG(("pc200_in(0x%04x)\n", addr)); switch (addr) { + case 0x3B8: + PC200LOG((" = %02x\n", mda->ctrl)); + return mda->ctrl; + case 0x3D8: + PC200LOG((" = %02x\n", cga->cgamode)); return cga->cgamode; case 0x3DD: - temp = pc200->reg_3dd; - pc200->reg_3dd &= 0x1f; - nmi = 0; + temp = pc200->crtc_index; /* Read NMI reason */ + pc200->crtc_index &= 0x1f; /* Reset NMI reason */ + nmi = 0; /* And reset NMI flag */ + PC200LOG((" = %02x\n", temp)); return temp; case 0x3DE: - return (pc200->reg_3de & 0xc7) | 0x10; /*External CGA*/ - + PC200LOG((" = %02x\n", ((pc200->operation_ctrl & 0xc7) | pc200->dipswitches))); + return ((pc200->operation_ctrl & 0xc7) | pc200->dipswitches); + case 0x3DF: return pc200->reg_3df; } - return cga_in(addr, cga); + if (addr >= 0x3D0 && addr <= 0x3DF) + { + return cga_in(addr, cga); + } + if (addr >= 0x3B0 && addr <= 0x3BB) + { + return mda_in(addr, mda); + } + return 0xFF; +} + +void lcd_draw_char_80(pc200_t *pc200, uint32_t *buffer, uint8_t chr, + uint8_t attr, int drawcursor, int blink, int sc, + int mode160, uint8_t control) +{ + int c; + uint8_t bits = fontdat[chr + pc200->cga.fontbase][sc]; + uint8_t bright = 0; + uint16_t mask; + + if (attr & 8) /* bright */ + { +/* The brightness algorithm appears to be: replace any bit sequence 011 + * with 001 (assuming an extra 0 to the left of the byte). + */ + bright = bits; + for (c = 0, mask = 0x100; c < 7; c++, mask >>= 1) + { + if (((bits & mask) == 0) && + ((bits & (mask >> 1)) != 0) && + ((bits & (mask >> 2)) != 0)) + { + bright &= ~(mask >> 1); + } + } + bits = bright; + } + + if (drawcursor) bits ^= 0xFF; + + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) + { + if (mode160) + buffer[c] = (attr & mask) ? blue : green; + else if (control & 0x20) /* blinking */ + buffer[c] = lcdcols[attr & 0x7F][blink][(bits & mask) ? 1 : 0]; + else + buffer[c] = lcdcols[attr][blink][(bits & mask) ? 1 : 0]; + } +} + + +void lcd_draw_char_40(pc200_t *pc200, uint32_t *buffer, uint8_t chr, + uint8_t attr, int drawcursor, int blink, int sc, + uint8_t control) +{ + int c; + uint8_t bits = fontdat[chr + pc200->cga.fontbase][sc]; + uint8_t mask = 0x80; + + if (attr & 8) /* bright */ + { + bits = bits & (bits >> 1); + } + if (drawcursor) bits ^= 0xFF; + + for (c = 0; c < 8; c++, mask >>= 1) + { + if (control & 0x20) + { + buffer[c*2] = buffer[c*2+1] = + lcdcols[attr & 0x7F][blink][(bits & mask) ? 1 : 0]; + } + else + { + buffer[c*2] = buffer[c*2+1] = + lcdcols[attr][blink][(bits & mask) ? 1 : 0]; + } + } +} + +void lcdm_poll(pc200_t *pc200) +{ + mda_t *mda = &pc200->mda; + uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x; + int oldvc; + uint8_t chr, attr; + int oldsc; + int blink; + if (!mda->linepos) + { + pc200->vidtime += mda->dispofftime; + mda->stat |= 1; + mda->linepos = 1; + oldsc = mda->sc; + if ((mda->crtc[8] & 3) == 3) + mda->sc = (mda->sc << 1) & 7; + if (mda->dispon) + { + if (mda->displine < mda->firstline) + { + mda->firstline = mda->displine; + video_wait_for_buffer(); + } + mda->lastline = mda->displine; + for (x = 0; x < mda->crtc[1]; x++) + { + chr = mda->vram[(mda->ma << 1) & 0xfff]; + attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; + drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); + blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + + lcd_draw_char_80(pc200, &((uint32_t *)(buffer32->line[mda->displine]))[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl); + mda->ma++; + } + } + mda->sc = oldsc; + 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) + mda->displine=0; + } + else + { + pc200->vidtime += mda->dispontime; + if (mda->dispon) mda->stat&=~1; + mda->linepos=0; + if (mda->vsynctime) + { + mda->vsynctime--; + 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))) + { + mda->con = 0; + mda->coff = 1; + } + if (mda->vadj) + { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + mda->vadj--; + if (!mda->vadj) + { + mda->dispon = 1; + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->sc = 0; + } + } + else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) + { + mda->maback = mda->ma; + mda->sc = 0; + oldvc = mda->vc; + mda->vc++; + mda->vc &= 127; + if (mda->vc == mda->crtc[6]) + mda->dispon=0; + if (oldvc == mda->crtc[4]) + { +// printf("Display over at %i\n",displine); + mda->vc = 0; + mda->vadj = mda->crtc[5]; + if (!mda->vadj) mda->dispon = 1; + if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0; + else mda->cursoron = mda->blink & 16; + } + if (mda->vc == mda->crtc[7]) + { + mda->dispon = 0; + mda->displine = 0; + mda->vsynctime = 16; + if (mda->crtc[7]) + { +// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); + x = mda->crtc[1] * 8; + 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 << 1); + } + + video_blit_memtoscreen(0, mda->firstline, 0, ysize, xsize, ysize); + + frames++; + video_res_x = mda->crtc[1]; + video_res_y = mda->crtc[6]; + video_bpp = 0; + } + mda->firstline = 1000; + mda->lastline = 0; + mda->blink++; + } + } + else + { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + } + if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) + { + mda->con = 1; +// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); + } + } +} + +void lcdc_poll(pc200_t *pc200) +{ + cga_t *cga = &pc200->cga; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + uint16_t dat; + int oldsc; + uint16_t ca; + int blink; + + ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; + + if (!cga->linepos) + { + pc200->vidtime += cga->dispofftime; + cga->cgastat |= 1; + cga->linepos = 1; + oldsc = cga->sc; + if ((cga->crtc[8] & 3) == 3) + cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + if (cga->cgadispon) + { + if (cga->displine < cga->firstline) + { + cga->firstline = cga->displine; + video_wait_for_buffer(); +// printf("Firstline %i\n",firstline); + } + cga->lastline = cga->displine; + + if (cga->cgamode & 1) + { + for (x = 0; x < cga->crtc[1]; x++) + { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); + lcd_draw_char_80(pc200, &((uint32_t *)(buffer32->line[cga->displine]))[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode); + cga->ma++; + } + } + else if (!(cga->cgamode & 2)) + { + for (x = 0; x < cga->crtc[1]; x++) + { + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); + lcd_draw_char_40(pc200, &((uint32_t *)(buffer32->line[cga->displine]))[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode); + cga->ma++; + } + } + else /* Graphics mode */ + { + for (x = 0; x < cga->crtc[1]; x++) + { + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + cga->ma++; + for (c = 0; c < 16; c++) + { + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + c] = (dat & 0x8000) ? blue : green; + dat <<= 1; + } + } + } + } + else + { + if (cga->cgamode & 1) hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3), green); + else hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4), green); + } + + if (cga->cgamode & 1) x = (cga->crtc[1] << 3); + else x = (cga->crtc[1] << 4); + + cga->sc = oldsc; + if (cga->vc == cga->crtc[7] && !cga->sc) + cga->cgastat |= 8; + cga->displine++; + if (cga->displine >= 360) + cga->displine = 0; + } + else + { + pc200->vidtime += cga->dispontime; + cga->linepos = 0; + if (cga->vsynctime) + { + cga->vsynctime--; + if (!cga->vsynctime) + cga->cgastat &= ~8; + } + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) + { + cga->con = 0; + cga->coff = 1; + } + if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) + cga->maback = cga->ma; + if (cga->vadj) + { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + cga->vadj--; + if (!cga->vadj) + { + cga->cgadispon = 1; + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + cga->sc = 0; + } + } + else if (cga->sc == cga->crtc[9]) + { + cga->maback = cga->ma; + cga->sc = 0; + oldvc = cga->vc; + cga->vc++; + cga->vc &= 127; + + if (cga->vc == cga->crtc[6]) + cga->cgadispon = 0; + + if (oldvc == cga->crtc[4]) + { + cga->vc = 0; + cga->vadj = cga->crtc[5]; + if (!cga->vadj) cga->cgadispon = 1; + if (!cga->vadj) cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + if ((cga->crtc[10] & 0x60) == 0x20) cga->cursoron = 0; + else cga->cursoron = cga->cgablink & 8; + } + + if (cga->vc == cga->crtc[7]) + { + cga->cgadispon = 0; + cga->displine = 0; + cga->vsynctime = 16; + if (cga->crtc[7]) + { + if (cga->cgamode & 1) x = (cga->crtc[1] << 3); + else x = (cga->crtc[1] << 4); + cga->lastline++; + if (x != xsize || (cga->lastline - cga->firstline) != ysize) + { + xsize = x; + ysize = cga->lastline - cga->firstline; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, (ysize << 1)); + } + + video_blit_memtoscreen(0, cga->firstline, 0, (cga->lastline - cga->firstline), xsize, (cga->lastline - cga->firstline)); + frames++; + + video_res_x = xsize - 16; + video_res_y = ysize; + if (cga->cgamode & 1) + { + video_res_x /= 8; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } + else if (!(cga->cgamode & 2)) + { + video_res_x /= 16; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } + else if (!(cga->cgamode & 16)) + { + video_res_x /= 2; + video_bpp = 2; + } + else + { + video_bpp = 1; + } + } + cga->firstline = 1000; + cga->lastline = 0; + cga->cgablink++; + cga->oddeven ^= 1; + } + } + else + { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + } + if (cga->cgadispon) + cga->cgastat &= ~1; + if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) + cga->con = 1; + if (cga->cgadispon && (cga->cgamode & 1)) + { + for (x = 0; x < (cga->crtc[1] << 1); x++) + cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; + } + } + +} + +void pc200_poll(void *p) +{ + pc200_t *pc200 = (pc200_t *)p; + + switch (pc200->emulation) + { + case PC200_CGA: + case PC200_TV: + pc200->cga.vidtime = pc200->vidtime; + cga_poll(&pc200->cga); + pc200->vidtime = pc200->cga.vidtime; + return; + + case PC200_MDA: + pc200->mda.vidtime = pc200->vidtime; + mda_poll(&pc200->mda); + pc200->vidtime = pc200->mda.vidtime; + return; + + case PC200_LCDM: + lcdm_poll(pc200); + return; + case PC200_LCDC: + lcdc_poll(pc200); + return; + } } void *pc200_init() { + int display_type, contrast; + pc200_t *pc200 = malloc(sizeof(pc200_t)); - cga_t *cga = &pc200->cga; + memset(pc200, 0, sizeof(pc200_t)); - pc200->cga.vram = malloc(0x4000); + pc200->emulation = device_get_config_int("video_emulation"); + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); + + /* Default to CGA */ + pc200->dipswitches = 0x10; + + /* DIP switches for PC200. Switches 2,3 give video emulation. + * Switch 1 is 'swap floppy drives' (not implemented) */ + if (romset == ROM_PC200) switch (pc200->emulation) + { + case PC200_CGA: pc200->dipswitches = 0x10; break; + case PC200_MDA: pc200->dipswitches = 0x30; break; + case PC200_TV: pc200->dipswitches = 0x00; break; + /* The other combination is 'IDA disabled' (0x20) - see + * amstrad.c */ + } + /* DIP switches for PPC512. Switch 1 is CRT/LCD. Switch 2 + * is MDA / CGA. Switch 3 disables IDA, not implemented. */ + else switch (pc200->emulation) + { + case PC200_CGA: pc200->dipswitches = 0x08; break; + case PC200_MDA: pc200->dipswitches = 0x18; break; + case PC200_LCDC: pc200->dipswitches = 0x00; break; + case PC200_LCDM: pc200->dipswitches = 0x10; break; + } + /* Flag whether the card is behaving like a CGA or an MDA, so that + * DIP switches are reported correctly */ + pc200_is_mda = (pc200->emulation == PC200_MDA || + pc200->emulation == PC200_LCDM); + PC200LOG(("pc200: DIP switches = %02x\n", pc200->dipswitches)); + + pc200->cga.vram = pc200->mda.vram = malloc(0x4000); cga_init(&pc200->cga); - - timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&pc200->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); + mda_init(&pc200->mda); + + /* Attribute 8 is white on black (on a real MDA it's black on black) */ + mda_setcol(0x08, 0, 1, 15); + mda_setcol(0x88, 0, 1, 15); + /* Attribute 64 is black on black (on a real MDA it's white on black) */ + mda_setcol(0x40, 0, 1, 0); + mda_setcol(0xC0, 0, 1, 0); + + pc200->cga.fontbase = (device_get_config_int("codepage") & 3) * 256; + + timer_add(pc200_poll, &pc200->vidtime, TIMER_ALWAYS_ENABLED, pc200); + mem_mapping_add(&pc200->mda_mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, &pc200->mda); + mem_mapping_add(&pc200->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, &pc200->cga); io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); + io_sethandler(0x03b0, 0x000c, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); + + green = makecol(0x1C, 0x71, 0x31); + blue = makecol(0x0f, 0x21, 0x3f); + cgapal_rebuild(display_type, contrast); + set_lcd_cols(0); + return pc200; } @@ -130,8 +898,200 @@ void pc200_speed_changed(void *p) pc200_t *pc200 = (pc200_t *)p; cga_recalctimings(&pc200->cga); + mda_recalctimings(&pc200->mda); + + setvidtime(pc200); } +device_config_t pc200_config[] = +{ + { + .name = "video_emulation", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "CGA monitor", + .value = PC200_CGA, + }, + { + .description = "MDA monitor", + .value = PC200_MDA, + }, + { + .description = "Television", + .value = PC200_TV, + }, + { + .description = "" + } + }, + .default_int = PC200_CGA, + }, + { + .name = "display_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "RGB", + .value = DISPLAY_RGB + }, + { + .description = "RGB (no brown)", + .value = DISPLAY_RGB_NO_BROWN + }, + { + .description = "Green Monochrome", + .value = DISPLAY_GREEN + }, + { + .description = "Amber Monochrome", + .value = DISPLAY_AMBER + }, + { + .description = "White Monochrome", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + }, + .default_int = DISPLAY_RGB + }, + { + .name = "codepage", + .description = "Hardware font", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "US English", + .value = 3 + }, + { + .description = "Portugese", + .value = 2 + }, + { + .description = "Norwegian", + .value = 1 + }, + { + .description = "Greek", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 3 + }, + { + .type = -1 + } +}; + + +device_config_t ppc512_config[] = +{ + { + .name = "video_emulation", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "CGA monitor", + .value = PC200_CGA, + }, + { + .description = "MDA monitor", + .value = PC200_MDA, + }, + { + .description = "LCD (CGA mode)", + .value = PC200_LCDC, + }, + { + .description = "LCD (MDA mode)", + .value = PC200_LCDM, + }, + { + .description = "" + } + }, + .default_int = PC200_LCDC, + }, + { + .name = "display_type", + .description = "External monitor", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "RGB", + .value = DISPLAY_RGB + }, + { + .description = "RGB (no brown)", + .value = DISPLAY_RGB_NO_BROWN + }, + { + .description = "Green Monochrome", + .value = DISPLAY_GREEN + }, + { + .description = "Amber Monochrome", + .value = DISPLAY_AMBER + }, + { + .description = "White Monochrome", + .value = DISPLAY_WHITE + }, + { + .description = "" + } + }, + .default_int = DISPLAY_RGB + }, + { + .name = "codepage", + .description = "Hardware font", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "US English", + .value = 3 + }, + { + .description = "Portugese", + .value = 2 + }, + { + .description = "Norwegian", + .value = 1 + }, + { + .description = "Greek", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 3 + }, + { + .type = -1 + } +}; + + + device_t pc200_device = { "Amstrad PC200 (video)", @@ -141,5 +1101,20 @@ device_t pc200_device = NULL, pc200_speed_changed, NULL, - NULL + NULL, + pc200_config }; + +device_t ppc512_device = +{ + "Amstrad PPC512 (video)", + 0, + pc200_init, + pc200_close, + NULL, + pc200_speed_changed, + NULL, + NULL, + ppc512_config +}; + diff --git a/src/vid_pc200.h b/src/vid_pc200.h index 4b43090..f59de48 100644 --- a/src/vid_pc200.h +++ b/src/vid_pc200.h @@ -1 +1,4 @@ extern device_t pc200_device; +extern device_t ppc512_device; + +extern int pc200_is_mda; diff --git a/src/vid_sigma.c b/src/vid_sigma.c index 6519c81..e44a5f1 100644 --- a/src/vid_sigma.c +++ b/src/vid_sigma.c @@ -9,7 +9,6 @@ #include "video.h" #include "vid_sigma.h" -extern void loadfont(char *s, int format); /* The Sigma Designs Color 400 is a video card from 1985, presumably intended * as an EGA competitor. diff --git a/src/vid_wy700.c b/src/vid_wy700.c index 107b134..a34c49d 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 b0c8039..b416594 100644 --- a/src/video.c +++ b/src/video.c @@ -151,7 +151,7 @@ char *video_card_getname(int card) return video_cards[card].name; } -device_t *video_card_getdevice(int card) +device_t *video_card_getdevice(int card, int romset) { switch (romset) { @@ -169,25 +169,30 @@ device_t *video_card_getdevice(int card) return &pc1512_device; case ROM_PC1640: - if (gfxcard == GFX_BUILTIN) + if (card == GFX_BUILTIN) return &pc1640_device; break; case ROM_PC200: - if (gfxcard == GFX_BUILTIN) + if (card == GFX_BUILTIN) return &pc200_device; break; + + case ROM_PPC512: + if (card == GFX_BUILTIN) + return &ppc512_device; + break; case ROM_OLIM24: return &m24_device; case ROM_PC2086: - if (gfxcard == GFX_BUILTIN) + if (card == GFX_BUILTIN) return ¶dise_pvga1a_pc2086_device; break; case ROM_PC3086: - if (gfxcard == GFX_BUILTIN) + if (card == GFX_BUILTIN) return ¶dise_pvga1a_pc3086_device; break; @@ -234,11 +239,16 @@ device_t *video_card_getdevice(int card) return video_cards[card].device; } -int video_card_has_config(int card) +int video_card_has_config(int card, int romset) { - if (card == GFX_BUILTIN) + /* Allow builtin cards to have configuration */ + device_t *device = video_card_getdevice(card, romset); + + if (!device) + { return 0; - return video_cards[card].device->config ? 1 : 0; + } + return device->config ? 1 : 0; } int video_card_getid(char *s) @@ -312,8 +322,16 @@ int video_is_mda() { switch (romset) { - case ROM_PC1640: case ROM_PC200: + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) + { +/* The chipset here can emulate either CGA or MDA. Find out which */ + return (pc200_is_mda); + } + break; + + case ROM_PC1640: case ROM_PC2086: case ROM_PC3086: case ROM_MEGAPC: @@ -349,8 +367,14 @@ int video_is_cga() switch (romset) { case ROM_PC200: - if (gfxcard != GFX_BUILTIN) - break; + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) + { +/* The chipset here can emulate either CGA or MDA. Find out which */ + return (!pc200_is_mda); + } + break; + case ROM_IBMPCJR: case ROM_TANDY: case ROM_TANDY1000HX: @@ -394,6 +418,7 @@ int video_is_ega_vga() case ROM_TANDY1000SL2: case ROM_PC1512: case ROM_PC200: + case ROM_PPC512: case ROM_OLIM24: case ROM_T3100E: case ROM_T1000: @@ -514,6 +539,7 @@ void video_updatetiming() break; case ROM_PC200: + case ROM_PPC512: if (gfxcard == GFX_BUILTIN) timing = &timing_pc200; break; @@ -676,6 +702,14 @@ void video_init() device_add(&pc200_device); return; } + break; + + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) + { + device_add(&ppc512_device); + return; + } break; case ROM_OLIM24: @@ -788,7 +822,7 @@ uint8_t fontdatksc5601_user[192][32]; /* Korean KSC-5601 user defined font */ int xsize=1,ysize=1; -void loadfont(char *s, int format) +void loadfont(char *s, fontformat_t format) { FILE *f=romfopen(s,"rb"); int c,d; @@ -800,7 +834,7 @@ void loadfont(char *s, int format) } switch (format) { - case 0: /* MDA */ + case FONT_MDA: /* MDA */ for (c=0;c<256;c++) { for (d=0;d<8;d++) @@ -824,33 +858,22 @@ void loadfont(char *s, int format) } } break; - case 1: /* PC200 */ - for (c=0;c<256;c++) - { - for (d=0;d<8;d++) + case FONT_PC200: /* PC200 */ + for (d=0;d<4;d++) /* There are 4 fonts in the ROM */ + { + for (c=0;c<256;c++) /* 8x14 MDA in 8x16 cell */ + { + fread(&fontdatm[256*d+c], 1, 16, f); + } + for (c=0;c<256; c++) /* 8x8 CGA in 8x16 cell */ { - fontdatm[c][d]=getc(f); + fread(fontdat[256*d+c], 1, 8, f); + fseek(f, 8, SEEK_CUR); } } - for (c=0;c<256;c++) - { - for (d=0;d<8;d++) - { - fontdatm[c][d+8]=getc(f); - } - } - fseek(f, 4096, SEEK_SET); - for (c=0;c<256;c++) - { - for (d=0;d<8;d++) - { - fontdat[c][d]=getc(f); - } - for (d=0;d<8;d++) getc(f); - } break; default: - case 2: /* CGA */ + case FONT_CGA: /* CGA */ for (c=0;c<2048;c++) /* Allow up to 2048 chars */ { for (d=0;d<8;d++) @@ -859,7 +882,7 @@ void loadfont(char *s, int format) } } break; - case 3: /* Wyse 700 */ + case FONT_WY700: /* Wyse 700 */ for (c=0;c<512;c++) { for (d=0;d<32;d++) @@ -868,7 +891,7 @@ void loadfont(char *s, int format) } } break; - case 4: /* MDSI Genius */ + case FONT_MDSI: /* MDSI Genius */ for (c=0;c<256;c++) { for (d=0;d<16;d++) @@ -877,7 +900,7 @@ void loadfont(char *s, int format) } } break; - case 5: /* Toshiba 3100e */ + case FONT_T3100E: /* Toshiba 3100e */ for (d = 0; d < 2048; d += 512) /* Four languages... */ { for (c = d; c < d+256; c++) @@ -907,7 +930,7 @@ void loadfont(char *s, int format) } } break; - case 6: /* Korean KSC-5601 */ + case FONT_KSC5601: /* Korean KSC-5601 */ for (c=0;c<16384;c++) { for (d=0;d<32;d++) @@ -916,7 +939,7 @@ void loadfont(char *s, int format) } } break; - case 7: /* Sigma Color 400 */ + case FONT_SIGMA400: /* Sigma Color 400 */ /* The first 4k of the character ROM holds an 8x8 font */ for (c = 0; c < 256; c++) { diff --git a/src/video.h b/src/video.h index f8edf05..4194b7a 100644 --- a/src/video.h +++ b/src/video.h @@ -23,8 +23,8 @@ extern BITMAP *buffer32; int video_card_available(int card); char *video_card_getname(int card); -struct device_t *video_card_getdevice(int card); -int video_card_has_config(int card); +struct device_t *video_card_getdevice(int card, int romset); +int video_card_has_config(int card, int romset); int video_card_getid(char *s); int video_old_to_new(int card); int video_new_to_old(int card); @@ -82,7 +82,21 @@ extern int vid_resize; void video_wait_for_blit(); void video_wait_for_buffer(); -void loadfont(char *s, int format); + +typedef enum +{ + FONT_MDA, /* MDA 8x14 */ + FONT_PC200, /* MDA 8x14 and CGA 8x8, four fonts */ + FONT_CGA, /* CGA 8x8, two fonts */ + FONT_WY700, /* Wy700 16x16, two fonts */ + FONT_MDSI, /* MDSI Genius 8x12 */ + FONT_T3100E, /* Toshiba T3100e, four fonts */ + FONT_KSC5601, /* Korean KSC-5601 */ + FONT_SIGMA400, /* Sigma Color 400, 8x8 and 8x16 */ + +} fontformat_t; + +void loadfont(char *s, fontformat_t format); void initvideo(); void video_init(); diff --git a/src/wx-config.c b/src/wx-config.c index 618363d..13f22cb 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -82,6 +82,7 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) int c = 0, d = 0; int found_card = 0; int cur_gfxcard = gfxcard; + int romset = model_getromset_from_model(model); wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); @@ -92,7 +93,7 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); wx_enablewindow(h, FALSE); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - wx_enablewindow(h, FALSE); + wx_enablewindow(h, video_card_has_config(gfxcard, romset)); return; } @@ -108,6 +109,9 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) d++; } + if (cur_gfxcard == GFX_BUILTIN && !model_has_fixed_gfx(model) && !model_has_optional_gfx(model)) + cur_gfxcard = 0; + while (1) { char *s = video_card_getname(c); @@ -116,7 +120,7 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) break; if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - ((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) + ((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI))) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); if (video_new_to_old(c) == gfxcard && !found_card) @@ -135,7 +139,7 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) wx_enablewindow(h, TRUE); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(video_old_to_new(cur_gfxcard))) + if (video_card_has_config(video_old_to_new(cur_gfxcard), romset)) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); @@ -1095,11 +1099,11 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_CONFIGUREVID")) { h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); - wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), - (LONG_PARAM) temp_str); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), (LONG_PARAM) temp_str); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - deviceconfig_open(hdlg, - (void *) video_card_getdevice(video_card_getid(temp_str))); + deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(temp_str), model_getromset_from_model(temp_model))); } else if (wParam == WX_ID("IDC_COMBOVID")) { @@ -1112,7 +1116,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) gfx = video_card_getid(temp_str); h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(gfx) && !model_has_fixed_gfx(temp_model)) + if (video_card_has_config(gfx, model_getromset_from_model(temp_model))) wx_enablewindow(h, TRUE); else wx_enablewindow(h, FALSE); From 0a5198828a0bf17e814be61054b4b6c47cee3abc Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 18:04:05 +0100 Subject: [PATCH 0676/1050] Latch Voodoo vertices at the start of triangle_setup() before sorting to prevent any races. --- src/vid_voodoo.c | 125 +++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 59 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index a5d03e7..480374e 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -202,6 +202,15 @@ typedef struct texture_t uint32_t *data; } texture_t; +typedef struct vert_t +{ + float sVx, sVy; + float sRed, sGreen, sBlue, sAlpha; + float sVz, sWb; + float sW0, sS0, sT0; + float sW1, sS1, sT1; +} vert_t; + typedef struct voodoo_t { mem_mapping_t mapping; @@ -318,14 +327,7 @@ typedef struct voodoo_t uint32_t cmdfifo_amin, cmdfifo_amax; uint32_t sSetupMode; - struct - { - float sVx, sVy; - float sRed, sGreen, sBlue, sAlpha; - float sVz, sWb; - float sW0, sS0, sT0; - float sW1, sS1, sT1; - } verts[4]; + vert_t verts[4]; int vertex_num; int num_verticies; @@ -3705,10 +3707,15 @@ static void triangle_setup(voodoo_t *voodoo) float area; int va = 0, vb = 1, vc = 2; int reverse_cull = 0; + vert_t verts[3]; - if (voodoo->verts[0].sVy < voodoo->verts[1].sVy) + verts[0] = voodoo->verts[0]; + verts[1] = voodoo->verts[1]; + verts[2] = voodoo->verts[2]; + + if (verts[0].sVy < verts[1].sVy) { - if (voodoo->verts[1].sVy < voodoo->verts[2].sVy) + if (verts[1].sVy < verts[2].sVy) { /* V1>V0, V2>V1, V2>V1>V0*/ va = 0; /*OK*/ @@ -3718,7 +3725,7 @@ static void triangle_setup(voodoo_t *voodoo) else { /* V1>V0, V1>V2*/ - if (voodoo->verts[0].sVy < voodoo->verts[2].sVy) + if (verts[0].sVy < verts[2].sVy) { /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ va = 0; @@ -3737,10 +3744,10 @@ static void triangle_setup(voodoo_t *voodoo) } else { - if (voodoo->verts[1].sVy < voodoo->verts[2].sVy) + if (verts[1].sVy < verts[2].sVy) { /* V0>V1, V2>V1*/ - if (voodoo->verts[0].sVy < voodoo->verts[2].sVy) + if (verts[0].sVy < verts[2].sVy) { /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ va = 1; @@ -3766,10 +3773,10 @@ static void triangle_setup(voodoo_t *voodoo) } } - dxAB = voodoo->verts[va].sVx - voodoo->verts[vb].sVx; - dxBC = voodoo->verts[vb].sVx - voodoo->verts[vc].sVx; - dyAB = voodoo->verts[va].sVy - voodoo->verts[vb].sVy; - dyBC = voodoo->verts[vb].sVy - voodoo->verts[vc].sVy; + dxAB = verts[va].sVx - verts[vb].sVx; + dxBC = verts[vb].sVx - verts[vc].sVx; + dyAB = verts[va].sVy - verts[vb].sVy; + dyBC = verts[vb].sVy - verts[vc].sVy; area = dxAB * dyBC - dxBC * dyAB; @@ -3804,66 +3811,66 @@ static void triangle_setup(voodoo_t *voodoo) return; } - voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(voodoo->verts[va].sVx * 16.0f) & 0xffff); - voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(voodoo->verts[va].sVy * 16.0f) & 0xffff); - voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(voodoo->verts[vb].sVx * 16.0f) & 0xffff); - voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(voodoo->verts[vb].sVy * 16.0f) & 0xffff); - voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(voodoo->verts[vc].sVx * 16.0f) & 0xffff); - voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(voodoo->verts[vc].sVy * 16.0f) & 0xffff); + voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); + voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); + voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff); + voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff); + voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff); + voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); if (voodoo->sSetupMode & SETUPMODE_RGB) { - voodoo->params.startR = (int32_t)(voodoo->verts[va].sRed * 4096.0f); - voodoo->params.dRdX = (int32_t)(((voodoo->verts[va].sRed - voodoo->verts[vb].sRed) * dyBC - (voodoo->verts[vb].sRed - voodoo->verts[vc].sRed) * dyAB) * 4096.0f); - voodoo->params.dRdY = (int32_t)(((voodoo->verts[vb].sRed - voodoo->verts[vc].sRed) * dxAB - (voodoo->verts[va].sRed - voodoo->verts[vb].sRed) * dxBC) * 4096.0f); - voodoo->params.startG = (int32_t)(voodoo->verts[va].sGreen * 4096.0f); - voodoo->params.dGdX = (int32_t)(((voodoo->verts[va].sGreen - voodoo->verts[vb].sGreen) * dyBC - (voodoo->verts[vb].sGreen - voodoo->verts[vc].sGreen) * dyAB) * 4096.0f); - voodoo->params.dGdY = (int32_t)(((voodoo->verts[vb].sGreen - voodoo->verts[vc].sGreen) * dxAB - (voodoo->verts[va].sGreen - voodoo->verts[vb].sGreen) * dxBC) * 4096.0f); - voodoo->params.startB = (int32_t)(voodoo->verts[va].sBlue * 4096.0f); - voodoo->params.dBdX = (int32_t)(((voodoo->verts[va].sBlue - voodoo->verts[vb].sBlue) * dyBC - (voodoo->verts[vb].sBlue - voodoo->verts[vc].sBlue) * dyAB) * 4096.0f); - voodoo->params.dBdY = (int32_t)(((voodoo->verts[vb].sBlue - voodoo->verts[vc].sBlue) * dxAB - (voodoo->verts[va].sBlue - voodoo->verts[vb].sBlue) * dxBC) * 4096.0f); + voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f); + voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); + voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); + voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f); + voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); + voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); + voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f); + voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); + voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); } if (voodoo->sSetupMode & SETUPMODE_ALPHA) { - voodoo->params.startA = (int32_t)(voodoo->verts[va].sAlpha * 4096.0f); - voodoo->params.dAdX = (int32_t)(((voodoo->verts[va].sAlpha - voodoo->verts[vb].sAlpha) * dyBC - (voodoo->verts[vb].sAlpha - voodoo->verts[vc].sAlpha) * dyAB) * 4096.0f); - voodoo->params.dAdY = (int32_t)(((voodoo->verts[vb].sAlpha - voodoo->verts[vc].sAlpha) * dxAB - (voodoo->verts[va].sAlpha - voodoo->verts[vb].sAlpha) * dxBC) * 4096.0f); + voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f); + voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); + voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); } if (voodoo->sSetupMode & SETUPMODE_Z) { - voodoo->params.startZ = (int32_t)(voodoo->verts[va].sVz * 4096.0f); - voodoo->params.dZdX = (int32_t)(((voodoo->verts[va].sVz - voodoo->verts[vb].sVz) * dyBC - (voodoo->verts[vb].sVz - voodoo->verts[vc].sVz) * dyAB) * 4096.0f); - voodoo->params.dZdY = (int32_t)(((voodoo->verts[vb].sVz - voodoo->verts[vc].sVz) * dxAB - (voodoo->verts[va].sVz - voodoo->verts[vb].sVz) * dxBC) * 4096.0f); + voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f); + voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); + voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); } if (voodoo->sSetupMode & SETUPMODE_Wb) { - voodoo->params.startW = (int64_t)(voodoo->verts[va].sWb * 4294967296.0f); - voodoo->params.dWdX = (int64_t)(((voodoo->verts[va].sWb - voodoo->verts[vb].sWb) * dyBC - (voodoo->verts[vb].sWb - voodoo->verts[vc].sWb) * dyAB) * 4294967296.0f); - voodoo->params.dWdY = (int64_t)(((voodoo->verts[vb].sWb - voodoo->verts[vc].sWb) * dxAB - (voodoo->verts[va].sWb - voodoo->verts[vb].sWb) * dxBC) * 4294967296.0f); + voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f); + voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); + voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; } if (voodoo->sSetupMode & SETUPMODE_W0) { - voodoo->params.tmu[0].startW = (int64_t)(voodoo->verts[va].sW0 * 4294967296.0f); - voodoo->params.tmu[0].dWdX = (int64_t)(((voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dyBC - (voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dWdY = (int64_t)(((voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dxAB - (voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f); + voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; } if (voodoo->sSetupMode & SETUPMODE_S0_T0) { - voodoo->params.tmu[0].startS = (int64_t)(voodoo->verts[va].sS0 * 4294967296.0f); - voodoo->params.tmu[0].dSdX = (int64_t)(((voodoo->verts[va].sS0 - voodoo->verts[vb].sS0) * dyBC - (voodoo->verts[vb].sS0 - voodoo->verts[vc].sS0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dSdY = (int64_t)(((voodoo->verts[vb].sS0 - voodoo->verts[vc].sS0) * dxAB - (voodoo->verts[va].sS0 - voodoo->verts[vb].sS0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startT = (int64_t)(voodoo->verts[va].sT0 * 4294967296.0f); - voodoo->params.tmu[0].dTdX = (int64_t)(((voodoo->verts[va].sT0 - voodoo->verts[vb].sT0) * dyBC - (voodoo->verts[vb].sT0 - voodoo->verts[vc].sT0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dTdY = (int64_t)(((voodoo->verts[vb].sT0 - voodoo->verts[vc].sT0) * dxAB - (voodoo->verts[va].sT0 - voodoo->verts[vb].sT0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f); + voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f); + voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; @@ -3873,18 +3880,18 @@ static void triangle_setup(voodoo_t *voodoo) } if (voodoo->sSetupMode & SETUPMODE_W1) { - voodoo->params.tmu[1].startW = (int64_t)(voodoo->verts[va].sW1 * 4294967296.0f); - voodoo->params.tmu[1].dWdX = (int64_t)(((voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dyBC - (voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dWdY = (int64_t)(((voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dxAB - (voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f); + voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); } if (voodoo->sSetupMode & SETUPMODE_S1_T1) { - voodoo->params.tmu[1].startS = (int64_t)(voodoo->verts[va].sS1 * 4294967296.0f); - voodoo->params.tmu[1].dSdX = (int64_t)(((voodoo->verts[va].sS1 - voodoo->verts[vb].sS1) * dyBC - (voodoo->verts[vb].sS1 - voodoo->verts[vc].sS1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dSdY = (int64_t)(((voodoo->verts[vb].sS1 - voodoo->verts[vc].sS1) * dxAB - (voodoo->verts[va].sS1 - voodoo->verts[vb].sS1) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startT = (int64_t)(voodoo->verts[va].sT1 * 4294967296.0f); - voodoo->params.tmu[1].dTdX = (int64_t)(((voodoo->verts[va].sT1 - voodoo->verts[vb].sT1) * dyBC - (voodoo->verts[vb].sT1 - voodoo->verts[vc].sT1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dTdY = (int64_t)(((voodoo->verts[vb].sT1 - voodoo->verts[vc].sT1) * dxAB - (voodoo->verts[va].sT1 - voodoo->verts[vb].sT1) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f); + voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f); + voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); } voodoo->params.sign = (area < 0.0); From 077304fb837c955f789506ae84a850cff019ee9a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 18:17:35 +0100 Subject: [PATCH 0677/1050] Disable memory > 640kb on XT systems when EGA/VGA cards in use. Patch from Greatpsycho. --- src/pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc.c b/src/pc.c index faeaa1a..791dbb1 100644 --- a/src/pc.c +++ b/src/pc.c @@ -417,7 +417,7 @@ void resetpchard() disc_load(1, discfns[1]); model_init(); - if (!AT) + if (!AT && models[model].max_ram > 640 && models[model].max_ram <= 768 && !video_is_ega_vga()) mem_set_704kb(); mouse_emu_init(); video_init(); From 081701a3c816db820a41f6586793062a673e00c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 18:22:22 +0100 Subject: [PATCH 0678/1050] Allow access to Korean font ROM on ATI Korean VGA when Korean character display mode isn't activated. Patch from Greatpsycho. --- src/vid_ati28800.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 026de97..50fe3c7 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -140,7 +140,7 @@ void ati28800k_out(uint16_t addr, uint8_t val, void *p) case 0x3DE: // pclog("ati28800k_out : set port 03DE to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); ati28800->in_get_korean_font_kind_set = 0; - if(ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) + if(ati28800->get_korean_font_enabled) { if((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20][ati28800->get_korean_font_index] = val; @@ -237,7 +237,7 @@ uint8_t ati28800k_in(uint16_t addr, void *p) switch (addr) { case 0x3DE: - if (ati28800->get_korean_font_enabled && (ati28800->regs[0xBF] & 0x20)) + if (ati28800->get_korean_font_enabled) { switch (ati28800->get_korean_font_kind >> 8) { From 4851a2fa9bb9f70c5109fc96e3f23833dff6bc18 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 18:36:02 +0100 Subject: [PATCH 0679/1050] Add software turbo control to Laser Turbo XT. Patch from Greatpsycho. --- src/laserxt.c | 15 ++++++++++++++- src/pc.c | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/laserxt.c b/src/laserxt.c index 361ced7..97c17ee 100644 --- a/src/laserxt.c +++ b/src/laserxt.c @@ -7,6 +7,7 @@ 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; +static uint8_t laserxt_turbo = 0x80; static uint32_t get_laserxt_ems_addr(uint32_t addr) { @@ -25,6 +26,11 @@ static void laserxt_write(uint16_t port, uint8_t val, void *priv) switch (port) { + case 0x01F0: + laserxt_turbo = val; + cpu_set_turbo((val & 0x80) >> 7); + //pclog("Turbo %s at %04X:%04X\n", (val & 0x80) ? "Enabled" : "Disabled", CS, cpu_state.oldpc); + break; 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); @@ -64,6 +70,9 @@ static uint8_t laserxt_read(uint16_t port, void *priv) { switch (port) { + case 0x01F0: + return laserxt_turbo; + case 0x0208: case 0x4208: case 0x8208: case 0xC208: return laserxt_emspage[port >> 14]; @@ -95,6 +104,10 @@ void laserxt_init() { int i; + io_sethandler(0x01F0, 0x0001, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + laserxt_turbo = 0x80; + cpu_set_turbo(1); + if (mem_size > 640) { io_sethandler(0x0208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); @@ -111,5 +124,5 @@ void laserxt_init() 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); + mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } diff --git a/src/pc.c b/src/pc.c index 791dbb1..341f771 100644 --- a/src/pc.c +++ b/src/pc.c @@ -416,9 +416,9 @@ void resetpchard() disc_load(0, discfns[0]); disc_load(1, discfns[1]); - model_init(); if (!AT && models[model].max_ram > 640 && models[model].max_ram <= 768 && !video_is_ega_vga()) mem_set_704kb(); + model_init(); mouse_emu_init(); video_init(); speaker_init(); From 750d7021e442953178780f6f9ca0680d000f02cd Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 18:47:39 +0100 Subject: [PATCH 0680/1050] Fix warning in laserxt.c --- src/laserxt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/laserxt.c b/src/laserxt.c index 97c17ee..5d15034 100644 --- a/src/laserxt.c +++ b/src/laserxt.c @@ -1,5 +1,6 @@ /*This is the chipset used in the LaserXT series model*/ #include "ibm.h" +#include "cpu.h" #include "io.h" #include "mem.h" From 84a098bc9878a5d1aba4088f0c8ace6ce1bcefe1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 20:37:23 +0100 Subject: [PATCH 0681/1050] Add read-only cassette emulation to IBM 5150 PC. Patch from JohnElliott. --- src/808x.c | 8 - src/Makefile.am | 4 +- src/Makefile.linux32-wx-sdl2 | 4 +- src/Makefile.linux64-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2-network | 4 +- src/Makefile.osx64-wx-sdl2 | 4 +- src/cassette.c | 186 +++ src/cassette.h | 30 + src/keyboard_xt.c | 7 +- src/model.c | 3 + src/pc.rc | 5 + src/pc.xrc | 9 + src/pzx.c | 419 +++++ src/pzx.h | 71 + src/resources.h | 2 + src/wx-resources.cpp | 2271 ++++++++++++++-------------- src/wx-sdl2.c | 18 + 18 files changed, 1904 insertions(+), 1149 deletions(-) create mode 100644 src/cassette.c create mode 100644 src/cassette.h create mode 100644 src/pzx.c create mode 100644 src/pzx.h diff --git a/src/808x.c b/src/808x.c index e50a13c..4602a8a 100644 --- a/src/808x.c +++ b/src/808x.c @@ -3484,14 +3484,6 @@ void execx86(int cycs) // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks); FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks); if ((cycdiff-cycles) + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*************************************************************************/ + +#include +#include "ibm.h" +#include "cpu.h" +#include "device.h" +#include "pzx.h" + +char cassettefn[256]; + +typedef struct cassette_t +{ + uint8_t motor; /* Motor status */ + pzxfile_t pzx; + int cycles_last; /* Cycle count at last cassette poll */ + +} cassette_t; + +extern device_t cassette_device; + + +static cassette_t *st_cas; + + + +#define CAS_LOG(x) pclog x +// #define CAS_LOG(x) + + +/* The PCem CPU uses IBM cycles (4.77MHz). PZX uses Spectrum cycles (3.5MHz) + * so scale accordingly. */ +static int32_t pzx_cycles(int32_t pc) +{ + double d = pc; + + return (int32_t)(((d * 3.5) / 4.772728) + 0.5); +} + +void cassette_eject(void) +{ + if (st_cas->pzx.input) + { + pzx_close(&st_cas->pzx); + } + cassettefn[0] = 0; +} + +void cassette_load(const char *filename) +{ + FILE *fp; + unsigned char magic[8]; + + if (!filename) return; + + fp = fopen(filename, "rb"); + if (!fp) + { + /* Warn user? */ + CAS_LOG(("Failed to open cassette input %s\n", filename)); + return; + } + memset(magic, 0, sizeof(magic)); + fread(magic, 1, sizeof(magic), fp); + + /* Check for PZX signature. In due course support could be added for + * other formats like TZX */ + if (!memcmp(magic, "PZXT", 4)) + { + const char *result; + + result = pzx_open(&st_cas->pzx, fp); + + if (result) + { + CAS_LOG(("Failed to open %s as PZX: %s\n", + filename, result)); + fclose(fp); + return; + } + strcpy(cassettefn, filename); + } +} + + +uint8_t cassette_input(void) +{ + int ticks; + + /* While motor is off, result is loopback */ + if (!st_cas->motor) + { + return ppispeakon; + } + /* If there is no tapefile open don't try to extract data */ + if (st_cas->pzx.input == NULL) return 0; + /* Otherwise see how many ticks there have been since the last input */ + if (st_cas->cycles_last == -1) + { + st_cas->cycles_last = cycles; + } + if (cycles <= st_cas->cycles_last) + { + ticks = (st_cas->cycles_last - cycles); + } + else + { + ticks = (st_cas->cycles_last + (cpu_get_speed() / 100) - cycles); + } + st_cas->cycles_last = cycles; + + return pzx_advance(&st_cas->pzx, pzx_cycles(ticks)); +} + + + +void cassette_set_motor(uint8_t on) +{ + if (on && !st_cas->motor) + { + CAS_LOG(("Start cassette motor\n")); + st_cas->cycles_last = -1; + } + if (st_cas->motor && !on) + { + CAS_LOG(("Stop cassette motor\n")); + st_cas->cycles_last = -1; + } + st_cas->motor = on; +} + + +static void *cassette_init(void) +{ + cassette_t *cas = malloc(sizeof(cassette_t)); + + memset(cas, 0, sizeof(cassette_t)); + pzx_init(&cas->pzx); + + st_cas = cas; + return cas; +} + + +static void cassette_close(void *p) +{ + cassette_t *cas = (cassette_t *)p; + + pzx_close(&cas->pzx); + + free(cas); +} + + +device_t cassette_device = +{ + "Cassette", + 0, + cassette_init, + cassette_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + diff --git a/src/cassette.h b/src/cassette.h new file mode 100644 index 0000000..de77354 --- /dev/null +++ b/src/cassette.h @@ -0,0 +1,30 @@ +/************************************************************************ + + PCem: IBM 5150 cassette support + + Copyright (C) 2019 John Elliott + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*************************************************************************/ + +extern device_t cassette_device; + +uint8_t cassette_input(void); +void cassette_set_motor(uint8_t on); +void cassette_eject(void); +void cassette_load(const char *filename); + +extern char cassettefn[256]; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index a36e707..86b3a8f 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "device.h" +#include "cassette.h" #include "fdd.h" #include "io.h" #include "mem.h" @@ -126,7 +127,9 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) timer_process(); timer_update_outstanding(); - if (keyboard_xt.pb2_turbo) + if (romset == ROM_IBMPC) + cassette_set_motor((val & 8) ? 0 : 1); + else if (keyboard_xt.pb2_turbo) cpu_set_turbo((val & 4) ? 0 : 1); speaker_update(); @@ -183,6 +186,8 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) temp = ((mem_size-64) / 32) & 0xf; else temp = ((mem_size-64) / 32) >> 4; + + temp |= (cassette_input()) ? 0x10 : 0; } else if (romset == ROM_ATARIPC3) { diff --git a/src/model.c b/src/model.c index a5ad2ef..587b6ab 100644 --- a/src/model.c +++ b/src/model.c @@ -15,6 +15,7 @@ #include "compaq.h" #include "dells200.h" #include "device.h" +#include "cassette.h" #include "dma.h" #include "fdc.h" #include "fdc37c665.h" @@ -301,6 +302,8 @@ void xt_init() keyboard_xt_init(); nmi_init(); device_add(&gameport_device); + if (romset == ROM_IBMPC) + device_add(&cassette_device); } void compaq_pip_init() diff --git a/src/pc.rc b/src/pc.rc index 0334579..b011d54 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -24,6 +24,11 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Configure hard discs...",IDM_HDCONF END + POPUP "C&assette" + BEGIN + MENUITEM "&Load tapefile...", IDM_CASSETTE_LOAD + MENUITEM "&Eject tape", IDM_CASSETTE_EJECT + END POPUP "&Settings" BEGIN MENUITEM "&Configure...", IDM_CONFIG diff --git a/src/pc.xrc b/src/pc.xrc index 66b6ca8..48ccde8 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -137,6 +137,15 @@ 1 + + + + + + + + + diff --git a/src/pzx.c b/src/pzx.c new file mode 100644 index 0000000..801ce72 --- /dev/null +++ b/src/pzx.c @@ -0,0 +1,419 @@ +/************************************************************************ + + PCem: IBM 5150 Cassette support + + Copyright (C) 2019 John Elliott + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*************************************************************************/ + +#include +#include "ibm.h" +#include "pzx.h" + +/* This module is intended to abstract all the details of a PZX file and + * emit its contents as a bitstream in a form suitable for PCem. Similar + * modules could be written to add support for other tape formats such as TZX, + * TAP or CSW. */ + +#define CAS_LOG(x) pclog x +/* #define CAS_LOG(x) */ + +static uint32_t peek2(uint8_t *data) +{ + return (((uint32_t)data[1]) << 8) | data[0]; +} + +static uint32_t peek4(uint8_t *data) +{ + return (((uint32_t)data[3]) << 24) | + (((uint32_t)data[2]) << 16) | + (((uint32_t)data[1]) << 8) | data[0]; +} + +/* Cue up the next pulse definition from the current PULS block. */ +static void pzx_parse_pulse(pzxfile_t *pzx) +{ + pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); + pzx->puls_ptr += 2; + if (pzx->puls_duration > 0x8000) + { + pzx->puls_count = pzx->puls_duration & 0x7FFF; + pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); + pzx->puls_ptr += 2; + } + if (pzx->puls_duration >= 0x8000) + { + pzx->puls_duration &= 0x7FFF; + pzx->puls_duration <<= 16; + pzx->puls_duration |= peek2(pzx->curblock + pzx->puls_ptr); + pzx->puls_ptr += 2; + } + if (!pzx->puls_count) pzx->puls_count = 1; +} + + + +void pzx_init(pzxfile_t *pzx) +{ + memset(pzx, 0, sizeof(pzxfile_t)); + pzx->state = PZX_CLOSED; +} + +/* Load the next block from a PZX-format file. + * + * Returns block if successful, NULL if end of file or error + * Caller must free the block with free(). */ +uint8_t *pzx_load_block(FILE *fp) +{ + uint8_t block_header[8]; + uint8_t *block_data; + uint32_t block_len; + + /* The first 8 bytes of a PZX block are fixed: the first 4 give + * the ID, the second 4 the length (excluding the header itself) */ + if (fread(block_header, 1, 8, fp) < 8) return NULL; /* EoF */ + + block_len = peek4(block_header + 4); + block_data = malloc(8 + block_len); + if (!block_data) return NULL; + memcpy(block_data, block_header, 8); + if (!block_len) /* Block is only the header */ + { +/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ + return block_data; + } + if (fread(block_data + 8, 1, block_len, fp) < block_len) + { + free(block_data); /* Unexpected EoF */ + return NULL; + } +/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ + return block_data; +} + + +/* Search the current file for PZX version headers and check they're all 1.x */ +static const char * pzx_check_version(FILE *fp) +{ + uint8_t *block; + static char message[80]; + + rewind(fp); + while ( (block = pzx_load_block(fp)) ) + { + if (!memcmp(block, "PZXT", 4)) + { + CAS_LOG(("PZX version %d.%d\n", block[8], block[9])); + if (block[8] != 1) + { + sprintf(message, "Unsupported PZX version %d.%d\n", block[8], block[9]); + free(block); + return message; + } + } + free(block); + } + rewind(fp); + return NULL; +} + + +const char *pzx_open(pzxfile_t *pzx, FILE *fp) +{ + const char *result; + + rewind(fp); + /* Check that this file is compatible */ + result = pzx_check_version(fp); + if (result) return result; + + pzx->level = 0; + pzx->state = PZX_IDLE; + pzx->input = fp; + return NULL; +} + +void pzx_close(pzxfile_t *pzx) +{ + if (pzx->input) + { + fclose(pzx->input); + pzx->input = NULL; + } + if (pzx->curblock) + { + free(pzx->curblock); + pzx->curblock = NULL; + } + pzx->state = PZX_CLOSED; +} + +/* Read the next block of type DATA, PAUS or PULS */ +int pzx_next_block(pzxfile_t *pzx) +{ + long pos; + + pos = ftell(pzx->input); + while (pzx->state == PZX_IDLE) + { + uint8_t *blk; + + /* In idle state there should be no current block. But + * make sure of that */ + if (pzx->curblock) + { + free(pzx->curblock); + pzx->curblock = NULL; + } + + /* Load the next block */ + blk = pzx_load_block(pzx->input); + + /* If that didn't load we've reached the end of file; wrap to + * beginning. */ + if (!blk) + { + rewind(pzx->input); + blk = pzx_load_block(pzx->input); + if (!blk) /* Couldn't even load first block */ + { + pzx_close(pzx); + return 0; + } + /* Have we read the whole file and come back to where + * we were? */ + if (ftell(pzx->input) == pos) + { + free(blk); + pzx_close(pzx); + return 0; + } + } + /* We have loaded the next block. What is it? */ + if (!memcmp(blk, "PULS", 4)) + { + pzx->state = PZX_IN_PULS; + pzx->curblock = blk; + pzx->puls_len = 8 + peek4(blk + 4); + pzx->puls_ptr = 8; + pzx->puls_count = 0; + pzx->puls_remain = 0; + pzx->puls_duration = 0; + pzx->level = 0; + CAS_LOG(("Beginning PULS block\n")); + } + else if (!memcmp(blk, "PAUS", 4)) + { + pzx->state = PZX_IN_PAUS; + pzx->curblock = blk; + pzx->paus_remain = peek4(blk + 8); + pzx->level = (pzx->paus_remain >> 31); + pzx->paus_remain &= 0x7FFFFFFF; + CAS_LOG(("Beginning PAUS block, duration=%d\n", + pzx->paus_remain)); + } + else if (!memcmp(blk, "DATA", 4)) + { + pzx->state = PZX_IN_DATA; + pzx->curblock = blk; + pzx->data_bits = peek4(blk + 8); + pzx->level = (pzx->data_bits >> 31); + pzx->data_bits &= 0x7FFFFFFF; + pzx->data_tail = peek2(blk + 12); + pzx->data_p0 = blk[14]; + pzx->data_p1 = blk[15]; + pzx->data_p = 0; + pzx->data_w = 16; + pzx->data_remain = 0; + pzx->data_ptr = 16 + 2 * (pzx->data_p0 + pzx->data_p1); + pzx->data_mask = 0x80; + CAS_LOG(("Beginning DATA block, length=%d p0=%d p1=%d" + " data_ptr=%d\n", + pzx->data_bits, + pzx->data_p0, pzx->data_p1, + pzx->data_ptr)); + } + } + return 1; +} + +static void pzx_endblock(pzxfile_t *pzx) +{ + if (pzx->curblock) free(pzx->curblock); + pzx->curblock = NULL; + pzx->state = PZX_IDLE; +} + +/* PAUS is easy - just run the timer down */ +static int pzx_advance_paus(pzxfile_t *pzx, int time) +{ + if (pzx->paus_remain > time) + { + pzx->paus_remain -= time; + return 0; + } + time -= pzx->paus_remain; + pzx_endblock(pzx); + return time; +} + + + + + + +static int pzx_advance_puls(pzxfile_t *pzx, int time) +{ + /* At the start of a pulse sequence? */ + if (pzx->puls_count == 0) + { + pzx_parse_pulse(pzx); + pzx->puls_remain = pzx->puls_duration; + } + /* Does sample trigger a pulse change? If not, that's easy. */ + if (time < pzx->puls_remain) + { + pzx->puls_remain -= time; + return 0; + } + /* Sample does trigger a pulse change */ + time -= pzx->puls_remain; + /* If there's another pulse in the current sequence, that's + * straightforward; just flip the level and continue */ + --pzx->puls_count; + pzx->level = !pzx->level; + if (pzx->puls_count) + { + pzx->puls_remain = pzx->puls_duration; + return time; + } + /* If we've reached the end of the pulse sequence, there may be + * another one */ + if (pzx->puls_ptr < pzx->puls_len) + { + return time; + } + /* If there isn't another one, it's the end of the block */ + pzx_endblock(pzx); + return time; +} + + +/* Decode a DATA block */ +static int pzx_advance_data(pzxfile_t *pzx, int time) +{ + uint8_t bit; + + /* Reached end of data? */ + if (pzx->data_bits == 0) + { + /* Time interval is covered by the tail bit */ + if (pzx->data_tail > time) + { + pzx->data_tail -= time; + return 0; + } + /* Have run out of block */ + time -= pzx->data_tail; + pzx_endblock(pzx); + return time; + } + /* No more time remaining on the current bit? */ + if (pzx->data_p < 1 && !pzx->data_remain) + { + bit = pzx->curblock[pzx->data_ptr] & pzx->data_mask; + pzx->data_mask >>= 1; + if (!pzx->data_mask) + { + pzx->data_mask = 0x80; + ++pzx->data_ptr; + } + --pzx->data_bits; + + if (bit) + { + pzx->data_p = pzx->data_p1; + pzx->data_w = 16 + 2 * pzx->data_p0; + pzx->data_remain = 0; + } + else + { + pzx->data_p = pzx->data_p0; + pzx->data_w = 16; + pzx->data_remain = 0; + } + } + /* See if we've started processing the current waveform. If not, + * load its first element (assuming that there is one) */ + if (!pzx->data_remain) + { + if (pzx->data_p) + { + pzx->data_remain = peek2(pzx->curblock + pzx->data_w); + pzx->data_w += 2; + pzx->data_p--; + } + } + if (pzx->data_remain > time) + { + /* Time advance is contained within current wave */ + pzx->data_remain -= time; + return 0; + } + else /* Move on to next element of wave / next bit / next block */ + { + time -= pzx->data_remain; + pzx->data_remain = 0; + pzx->level = !pzx->level; + } + + return time; +} + + + + +int pzx_advance(pzxfile_t *pzx, int time) +{ + if (pzx->state == PZX_CLOSED) return 0; /* No tape loaded */ + + while (time) + { + switch (pzx->state) + { + case PZX_IDLE: + if (!pzx_next_block(pzx)) return 0; + break; + case PZX_IN_PULS: + time = pzx_advance_puls(pzx, time); + break; + case PZX_IN_PAUS: + time = pzx_advance_paus(pzx, time); + break; + case PZX_IN_DATA: + time = pzx_advance_data(pzx, time); + break; + case PZX_CLOSED: /*Should never get here*/ + return 0; + + } + } + return pzx->level; +} + + + diff --git a/src/pzx.h b/src/pzx.h new file mode 100644 index 0000000..94d5ca1 --- /dev/null +++ b/src/pzx.h @@ -0,0 +1,71 @@ +/************************************************************************ + + PCem: IBM 5150 cassette support + + Copyright (C) 2019 John Elliott + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +*************************************************************************/ + +typedef enum +{ + PZX_CLOSED, /* File is not open */ + PZX_IDLE, /* File is open, no block loaded */ + PZX_IN_PULS, /* File is open, current block is a PULS block */ + PZX_IN_DATA, /* File is open, current block is a DATA block */ + PZX_IN_PAUS, /* File is open, current block is a PAUS block */ +} PZX_STATE; + + +typedef struct pzxfile_t +{ + FILE *input; /* Input PZX file */ + uint8_t *curblock; /* Currently-loaded block, if any */ + int level; /* Current signal level */ + PZX_STATE state; /* State machine current status */ +/* State variables for PULS */ + uint32_t puls_ptr; /* Pointer within PULS block */ + uint32_t puls_len; /* Length of PULS block */ + uint32_t puls_count; /* Count of pulses */ + uint32_t puls_duration; /* Duration of each pulse */ + uint32_t puls_remain; /* Time remaining in this pulse */ +/* State variables for PAUS */ + uint32_t paus_remain; /* Time remaining in this pause */ +/* State variables for DATA */ + uint32_t data_ptr; /* Pointer within DATA block */ + uint32_t data_bits; /* Count of bits */ + uint16_t data_tail; /* Length of pulse after last bit */ + uint8_t data_mask; /* Mask for current bit */ + uint8_t data_p0; /* Length of 0 encoding */ + uint8_t data_p1; /* Length of 1 encoding */ + int data_p; /* Current sequence being emitted */ + uint32_t data_w; /* Current waveform */ + uint32_t data_remain; /* Current data pulse time remaining */ +} pzxfile_t; + +uint8_t *pzx_load_block(FILE *fp); + +/* Initialise structure */ +void pzx_init(pzxfile_t *pzx); + +/* Open file for input */ +const char *pzx_open(pzxfile_t *pzx, FILE *fp); + +/* Close file */ +void pzx_close(pzxfile_t *pzx); + +/* Advance by 'time' samples (3.5MHz sample rate) and return current state */ +int pzx_advance(pzxfile_t *pzx, int time); diff --git a/src/resources.h b/src/resources.h index 69d9306..66c4a74 100644 --- a/src/resources.h +++ b/src/resources.h @@ -10,6 +10,8 @@ #define IDM_BPB_DISABLE 40015 #define IDM_CONFIG 40020 #define IDM_STATUS 40030 +#define IDM_CASSETTE_LOAD 40040 +#define IDM_CASSETTE_EJECT 40041 #define IDM_VID_RESIZE 40050 #define IDM_VID_REMEMBER 40051 #define IDM_VID_ASPECT 40052 diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index a5ba214..c088a21 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 137687; +static size_t xml_res_size_26 = 138007; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -2032,731 +2032,671 @@ static unsigned char xml_res_file_26[] = { 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,86,105,100,101,111,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,82,101,115,111,108,117,116,105,111,110, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84, -73,79,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,79,114,105,103,105,110,97,108,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,105,122,97,98, -108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83, -79,76,85,84,73,79,78,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,67,117,115,116,111,109,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,82,69,83,79,76,85,84,73,79,78,95,67,85,83,84,79,77,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,99,117,115, -116,111,109,32,114,101,115,111,108,117,116,105,111,110,46,46,46,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +34,32,110,97,109,101,61,34,73,68,77,95,67,65,83,83,69,84,84,69,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,95,97,115,115,101,116,116, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,67,65,83,83,69,84,84,69,95,76,79,65, +68,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,111,97, +100,32,116,97,112,101,102,105,108,101,46,46,46,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82, -69,77,69,77,66,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,82,101,109,101,109,98,101,114,32,115,105,122,101,32,38,97,109,112, -59,38,97,109,112,59,32,112,111,115,105,116,105,111,110,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101, -62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,70,85,76,76,83,67,82,69,69,78,95,84,79,71,71,76,69,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,103,103,108,101, -32,102,117,108,108,115,99,114,101,101,110,92,116,67,116,114,108,43,65,108, -116,43,80,97,103,101,68,111,119,110,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76, -76,83,67,82,69,69,78,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,70,117,108,108,115,99,114,101,101,110,32,111,110,32,105,110,112, -117,116,32,103,114,97,98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, -97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114, -101,101,110,32,109,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,70,83,95,77,79,68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,95,66,111,114,100,101,114,108,101,115,115, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69, -91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,69,120,99,108,117,115,105,118,101,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68, -82,73,86,69,82,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -95,82,101,110,100,101,114,32,100,114,105,118,101,114,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, -117,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, -78,68,69,82,95,68,82,73,86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116,51,68,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, -110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82, -73,86,69,82,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,79,112,101,110,71,76,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76, -32,51,46,48,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, -78,68,69,82,95,68,82,73,86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,83,111,102,116,119,97,114,101,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,67,65,83,83,69, +84,84,69,95,69,74,69,67,84,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,95,69,106,101,99,116,32,116,97,112,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, +32,60,108,97,98,101,108,62,86,105,100,101,111,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,86,83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,95,86,83,121,110,99,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104, -101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,115,111,108,117,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,76,79,83,84,95,70,79,67,85,83,95,68,73,77,34,62, -10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,68,105,109,32,100, -105,115,112,108,97,121,32,111,110,32,108,111,115,116,32,102,111,99,117, -115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101, -99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,114,105,103,105, +110,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,65,76, -84,69,82,78,65,84,73,86,69,95,85,80,68,65,84,69,95,76,79,67,75,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,108,116,101,114,110, -97,116,105,118,101,32,117,112,100,97,116,101,45,108,111,99,107,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98, -108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34, -47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,83,99,97,108,101,32,102,105,108,116,101,114,105,110,103,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,79, -68,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,78,101,97,114,101,115,116,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,49,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,76,105,110,101,97,114, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, -105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,79,117,116,112,117,116,32,115,116,114,101,116,99,104,45,109, -111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, -78,111,110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -83,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,52,58,51,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70, -83,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,83,113,117,97,114,101,32,112,105,120,101,108,115,60,47,108,97,98, +73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69, +83,79,76,85,84,73,79,78,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,101,115,105,122,97,98,108,101,60,47,108,97,98, 101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, 60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, 108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73,110,116,101,103,101, -114,32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109, -101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116,112,117,116, -32,115,99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83, -67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, -73,68,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,86,73,68,95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32, +109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84,73,79,78,91, +50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +117,115,116,111,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97, +114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,83,79,76,85,84, +73,79,78,95,67,85,83,84,79,77,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,116,32,99,117,115,116,111,109,32,114,101,115, +111,108,117,116,105,111,110,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,77,69,77,66,69,82,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,101,109, +98,101,114,32,115,105,122,101,32,38,97,109,112,59,38,97,109,112,59,32,112, +111,115,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107, +97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,85,76,76,83,67, +82,69,69,78,95,84,79,71,71,76,69,34,62,10,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,111,103,103,108,101,32,102,117,108,108,115,99,114,101, +101,110,92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,68,111,119, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,70,85,76,76,83,67,82,69,69,78,34,62,10,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,117,108,108,115,99,114,101, +101,110,32,111,110,32,105,110,112,117,116,32,103,114,97,98,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108, +101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,101,112,97,114,97,116,111,114,34,47, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,117,108,108,115,99,114,101,101,110,32,109,111,100,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,95,77,79,68,69,91, +48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +66,111,114,100,101,114,108,101,115,115,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, 105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,86,73,68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111, -62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46, -48,32,114,101,110,100,101,114,101,114,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,73,110,112,117,116,32,115,116,114,101,116,99,104,45,109,111, -100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,49,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,50,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97,114,101, -32,112,105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67, -72,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,95,73,110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +68,77,95,86,73,68,95,70,83,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,95,69,120,99,108,117,115,105, +118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34, +73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,34,62,10, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,82,101,110,100,101,114, +32,100,114,105,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,73,110,112,117,116,32,115,99,97, -108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73, +86,69,82,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,105,114,101,99,116,51,68,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73,86,69,82,91,50,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,110, +71,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68, +69,82,95,68,82,73,86,69,82,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,112,101,110,71,76,32,51,46,48,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,82,69,78,68,69,82,95,68,82,73, +86,69,82,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,111,102,116,119,97,114,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,49,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,86,83,89, +78,67,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,86,83, +121,110,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,76, +79,83,84,95,70,79,67,85,83,95,68,73,77,34,62,10,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,68,105,109,32,100,105,115,112,108,97,121,32, +111,110,32,108,111,115,116,32,102,111,99,117,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49, +60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, +109,101,61,34,73,68,77,95,86,73,68,95,65,76,84,69,82,78,65,84,73,86,69, +95,85,80,68,65,84,69,95,76,79,67,75,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,65,108,116,101,114,110,97,116,105,118,101,32,117,112, +100,97,116,101,45,108,111,99,107,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101, +99,107,97,98,108,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34, +62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,97,108,101, +32,102,105,108,116,101,114,105,110,103,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,83,67,65,76,69,95,77,79,68,69,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,101,97,114,101,115, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, +69,95,77,79,68,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,76,105,110,101,97,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, +117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,115,116,114,101,116,99,104,45,109,111,100,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,48,93,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,110,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,49,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,52,58,51,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, +111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,70,83,91,50,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,113,117,97, +114,101,32,112,105,120,101,108,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,86,73,68,95,70,83,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,73,110,116,101,103,101,114,32,115,99,97,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61,34,73,68,77, +95,86,73,68,95,83,67,65,76,69,95,77,69,78,85,34,62,10,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,115,99,97,108,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76,69,91,48, +93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,46, +53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, +97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65,76, +69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,83,67,65, +76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68, +95,83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, +68,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +86,73,68,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, +105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, +68,77,95,86,73,68,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97, +100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114, +97,116,111,114,34,47,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,34,32,110,97,109,101,61, +34,73,68,77,95,86,73,68,95,71,76,51,34,62,10,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,101,110,71,76,32,51,46,48,32,114,101,110,100, +101,114,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,112, +117,116,32,115,116,114,101,116,99,104,45,109,111,100,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, +83,84,82,69,84,67,72,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,78,111,110,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84, +95,83,84,82,69,84,67,72,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,95,52,58,51,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, +83,84,82,69,84,67,72,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,95,83,113,117,97,114,101,32,112,105,120,101, +108,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86, +73,68,95,71,76,51,95,73,78,80,85,84,95,83,84,82,69,84,67,72,91,51,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,73, +110,116,101,103,101,114,32,115,99,97,108,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, +114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,110,112,117,116,32,115,99,97,108,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, 32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85, -84,95,83,67,65,76,69,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,49,46,53,120,60,47,108,97,98,101,108,62,10,32, +84,95,83,67,65,76,69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,48,46,53,120,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, 97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, -83,67,65,76,69,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,50,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +83,67,65,76,69,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,49,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, 62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, 73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91, -52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,50,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,49,46,53,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,53,93,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60, +86,73,68,95,71,76,51,95,73,78,80,85,84,95,83,67,65,76,69,91,51,93,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,120,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,73,78,80,85,84,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97, +51,95,73,78,80,85,84,95,83,67,65,76,69,91,52,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,46,53,120,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, 111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, 116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, -95,73,78,80,85,84,95,83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,52,120,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, -47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,83,104,97,100,101,114,32,114,101,102,114,101,115, -104,32,114,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73, -68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84, -69,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,83,97,109,101,32,97,115,32,101,109,117,108,97,116,101,100,32,100, -105,115,112,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34, -73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69, -83,72,95,82,65,84,69,91,49,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,49,48,32,104,122,60,47,108,97,98,101,108, +95,73,78,80,85,84,95,83,67,65,76,69,91,53,93,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,51,120,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, 47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68, -69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,50,53,93,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,50,53,32,104,122, +32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85, +84,95,83,67,65,76,69,91,54,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,51,46,53,120,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,73,78,80,85,84,95, +83,67,65,76,69,91,55,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,52,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, +110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,104,97,100,101,114,32,114,101,102,114,101,115,104,32,114,97,116,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101, +109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72, +65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,97,109,101, +32,97,115,32,101,109,117,108,97,116,101,100,32,100,105,115,112,108,97,121, 60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114, 97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, 117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, -76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,51, +76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,49, 48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,51,48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +62,49,48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, 10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, 68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83, -72,95,82,65,84,69,91,53,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,53,48,32,104,122,60,47,108,97,98,101,108,62, +72,95,82,65,84,69,91,50,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,50,53,32,104,122,60,47,108,97,98,101,108,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47, 114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, 110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, -82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,54,48,93,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,54,48,32,104,122,60, +82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,51,48,93,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,51,48,32,104,122,60, 47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, 100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, 32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76, -51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,55,50, +51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,53,48, 93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -55,50,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +53,48,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, 119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, 77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82,95,82,69,70,82,69,83,72, -95,82,65,84,69,91,56,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,56,53,32,104,122,60,47,108,97,98,101,108,62,10, +95,82,65,84,69,91,54,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,54,48,32,104,122,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, 97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,101,112,97,114,97,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71, -76,51,95,83,72,65,68,69,82,95,77,65,78,65,71,69,82,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,97,100,101,114,32,109, -97,110,97,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,111,117,110,100, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,66,117,102,102,101,114,32,108,101, -110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69,82, +95,82,69,70,82,69,83,72,95,82,65,84,69,91,55,50,93,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,55,50,32,104,122,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51, +95,83,72,65,68,69,82,95,82,69,70,82,69,83,72,95,82,65,84,69,91,56,53,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,56, +53,32,104,122,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,101,112,97,114,97, +116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,86,73,68,95,71,76,51,95,83,72,65,68,69, +82,95,77,65,78,65,71,69,82,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,104,97,100,101,114,32,109,97,110,97,103,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,111,117,110,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,95,66,117,102,102,101,114,32,108,101,110,103,116,104,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,48,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,53,48,32,109,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85,70,91,49,93,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,49,48,48, +32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, 73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,66,85, -70,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,53,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78, -68,95,66,85,70,91,49,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,49,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, -111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, -77,95,83,78,68,95,66,85,70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,95,50,48,48,32,109,115,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, -97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, -34,73,68,77,95,83,78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, -49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,95,79,117,116,112,117,116,32,108,101,118,101,108,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,48,93,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,95,78,111,114,109,97,108,60,47, -108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105, -111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, -32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,49,93,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,50,32, -100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114, -97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, -101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78, -91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -43,95,52,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71, -65,73,78,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,43,95,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +70,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,50,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62, 10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, 77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, -78,68,95,71,65,73,78,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,43,95,56,32,100,66,60,47,108,97,98,101,108,62,10,32, +78,68,95,66,85,70,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,95,52,48,48,32,109,115,60,47,108,97,98,101,108,62,10,32, 32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100, 105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73, -68,77,95,83,78,68,95,71,65,73,78,91,53,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,60,108,97,98,101,108,62,43,95,49,48,32,100,66,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49, -60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97, -109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,54,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,50,32,100,66,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, +34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,79,117,116, +112,117,116,32,108,101,118,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, +83,78,68,95,71,65,73,78,91,48,93,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,95,78,111,114,109,97,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,83,78,68,95,71,65,73,78,91,49,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,43,95,50,32,100,66,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,50,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,52,32,100,66, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, 105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, 47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, 99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, -34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,55,93, -34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,52, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,51,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,95,54, 32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, 114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, 116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73, -78,91,56,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,43,49,54,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +78,91,52,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,43,95,56,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, 32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101, 110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,78,68, -95,71,65,73,78,91,57,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,43,49,56,32,100,66,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111, -62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98, -101,108,62,77,105,115,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110, -117,34,62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114, -101,101,110,115,104,111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +95,71,65,73,78,91,53,93,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,43,95,49,48,32,100,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, +111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68, +77,95,83,78,68,95,71,65,73,78,91,54,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,43,49,50,32,100,66,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114, +97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61, +34,73,68,77,95,83,78,68,95,71,65,73,78,91,55,93,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,43,49,52,32,100,66,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62, +49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110, +97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,56,93,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,54,32,100,66, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109, +34,32,110,97,109,101,61,34,73,68,77,95,83,78,68,95,71,65,73,78,91,57,93, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,43,49,56, +32,100,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, -101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67, -82,69,69,78,83,72,79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,95,84,97,107,101,32,115,99,114,101,101,110,115,104,111,116, -92,116,67,116,114,108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,77,101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, -61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, -48,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,80,78,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +101,110,117,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115, +99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,34,62,10,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,95,83,99,114,101,101,110,115,104, +111,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116, +101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72, +79,84,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95, +84,97,107,101,32,115,99,114,101,101,110,115,104,111,116,92,116,67,116,114, +108,43,65,108,116,43,80,97,103,101,85,112,60,47,108,97,98,101,108,62,10, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77, +101,110,117,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,95,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95, -83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97, -100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117, -73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78, -83,72,79,84,95,70,79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108, +83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91,48,93,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,78,71,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100, +105,111,62,49,60,47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, +72,79,84,95,70,79,82,77,65,84,91,49,93,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,73,70,70,60,47,108,97,98,101,108, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60, 47,114,97,100,105,111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34, 32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70, -79,82,77,65,84,91,51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32, +79,82,77,65,84,91,50,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,66,77,80,60,47,108,97,98,101,108,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105, 111,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -77,101,110,117,73,116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83, -67,82,69,69,78,83,72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,108,97,98,101,108,62,70,108,97,115,104,32,115,99,114,101, -101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108, -101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32,110,97,109,101, +61,34,73,68,77,95,83,67,82,69,69,78,83,72,79,84,95,70,79,82,77,65,84,91, +51,93,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,74,80,71,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,97,100,105,111,62,49,60,47,114,97,100,105,111,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,77,101,110,117,73, -116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34, -62,10,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105, -110,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,72,68,80,65,78,69,76,34,32,115,116, -97,114,116,61,34,49,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103, -101,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84, -89,80,69,34,32,115,116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,70,78,34,32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32, -60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95, -70,73,76,69,34,32,115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69, -74,69,67,84,34,32,115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60, -105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78, -69,87,34,32,115,116,97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105, -100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, -73,84,95,83,80,84,34,32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32, -32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, -95,69,68,73,84,95,72,80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47, -62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48, +116,101,109,34,32,110,97,109,101,61,34,73,68,77,95,83,67,82,69,69,78,83, +72,79,84,95,70,76,65,83,72,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,108,97,115,104,32,115,99,114,101,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +97,98,108,101,62,49,60,47,99,104,101,99,107,97,98,108,101,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,77,101,110,117,73,116,101,109,34,32, +110,97,109,101,61,34,73,68,77,95,83,84,65,84,85,83,34,62,10,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,95,77,97,99,104,105,110,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,67,95,72,68,80,65,78,69,76,34,32,115,116,97,114,116,61,34,49, 48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109, -101,61,34,73,68,67,95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116, -61,34,49,48,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101, -32,110,97,109,101,61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115, -116,97,114,116,61,34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110, -97,109,101,61,34,67,111,110,102,105,103,117,114,101,68,108,103,34,62,10, -32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, -73,65,76,79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32, -32,32,60,116,105,116,108,101,62,67,111,110,102,105,103,117,114,101,32,80, -67,101,109,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116, -101,114,101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, -110,101,108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34, -62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62, -10,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, -62,10,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, -97,112,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, -111,108,115,47,62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, -98,111,111,107,34,32,110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79, -79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,78,66,95,68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,109,111,116,104,101,114,98,111,97,114,100,46,112,110,103,60, -47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,97,99,104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +101,61,34,73,68,67,95,67,79,77,66,79,68,82,73,86,69,84,89,80,69,34,32,115, +116,97,114,116,61,34,49,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97, +110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,70,78,34, +32,115,116,97,114,116,61,34,51,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,70,73,76,69,34,32, +115,116,97,114,116,61,34,52,48,48,34,47,62,10,32,32,60,105,100,115,45,114, +97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,74,69,67,84,34,32, +115,116,97,114,116,61,34,53,48,48,34,47,62,10,32,32,60,105,100,115,45,114, +97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,32,115,116, +97,114,116,61,34,54,48,48,34,47,62,10,32,32,60,105,100,115,45,114,97,110, +103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,83,80,84,34, +32,115,116,97,114,116,61,34,55,48,48,34,47,62,10,32,32,60,105,100,115,45, +114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,95,72, +80,67,34,32,115,116,97,114,116,61,34,56,48,48,34,47,62,10,32,32,60,105, +100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67,95,69,68, +73,84,95,67,89,76,34,32,115,116,97,114,116,61,34,57,48,48,34,47,62,10,32, +32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101,61,34,73,68,67, +95,84,69,88,84,95,83,73,90,69,34,32,115,116,97,114,116,61,34,49,48,48,48, +34,47,62,10,32,32,60,105,100,115,45,114,97,110,103,101,32,110,97,109,101, +61,34,73,68,67,95,72,68,68,95,76,65,66,69,76,34,32,115,116,97,114,116,61, +34,49,49,48,48,34,47,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +67,111,110,102,105,103,117,114,101,68,108,103,34,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, +108,101,62,67,111,110,102,105,103,117,114,101,32,80,67,101,109,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, +49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, -116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, -67,95,67,79,78,70,73,71,85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, -119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, -110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111, -108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,80,85,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32, +110,97,109,101,61,34,73,68,67,95,78,79,84,69,66,79,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95, +68,69,70,65,85,76,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,109,111,116, +104,101,114,98,111,97,114,100,46,112,110,103,60,47,98,105,116,109,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99, +104,105,110,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, 47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, @@ -2783,12 +2723,109 @@ static unsigned char xml_res_file_26[] = { 60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, 98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80, -85,77,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, -80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,49,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, +85,82,69,77,79,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115, +111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120, +49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110, +103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80,85, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90, +79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,67,80,85,77,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, +51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, 121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44,45,49,60,47,115, 105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, @@ -2796,159 +2833,25 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, -95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,50,48,44, -45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -108,97,98,101,108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112, -105,108,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, -48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110,97,109,101, -61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97, -120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, -84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, -97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -2962,141 +2865,38 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,87,97,105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112,105,108,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, -62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69, -65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, -117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, -120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78, -67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105,122,101, -32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111,99,107,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101, -100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, -115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, -120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, -71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, -48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,101,109,111,114,121,58,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, 112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, @@ -3123,79 +2923,41 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +120,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83, +80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48, +60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, -105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73, -71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,83,112,101,101,100,58,60,47,108,97,98,101,108,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,79,77,66,79,83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, -101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, 47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3206,109 +2968,18 @@ static unsigned char xml_res_file_26[] = { 105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, -78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,72,69,67,75,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -86,111,111,100,111,111,32,71,114,97,112,104,105,99,115,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, -99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70, -73,71,85,82,69,86,79,79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,49,54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115, -46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, -97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, -108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, -120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, -115,95,51,50,120,51,50,95,115,111,117,110,100,46,112,110,103,60,47,98,105, -116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, -105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48, -60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, -114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97, +105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, 112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, @@ -3336,62 +3007,406 @@ static unsigned char xml_res_file_26[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, -67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, -76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, -48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, 98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, -34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110,103,95, -116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, -102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78,67,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,121,110,99,104,114,111,110,105,122,101,32,116,105,109,101, +32,116,111,32,104,111,115,116,32,99,108,111,99,107,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,118,105,100, +101,111,95,109,111,100,101,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,118, +105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, +70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +112,101,101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, +83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, +72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79, +79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111, +32,71,114,97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79, +79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, +114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, +115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, +117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51, +50,95,115,111,117,110,100,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,118, +105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, +119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, +82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,78,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, +70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, +54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, 97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, 101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 50e7a44..d230416 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -18,6 +18,8 @@ #include #include #include "ibm.h" +#include "device.h" +#include "cassette.h" #include "cdrom-ioctl.h" #include "cdrom-image.h" #include "config.h" @@ -899,6 +901,22 @@ int wx_handle_command(void* hwnd, int wParam, int checked) { zip_eject(); } + else if (ID_IS("IDM_CASSETTE_LOAD")) + { + if (!getfile(hwnd, + "Tape image (*.pzxi;*.pzx)|*.pzxi;*.pzx|All files (*.*)|*.*", + cassettefn)) + { + cassette_eject(); + cassette_load(openfilestring); + saveconfig(NULL); + } + } + else if (ID_IS("IDM_CASSETTE_EJECT")) + { + cassette_eject(); + saveconfig(NULL); + } else if (ID_IS("IDM_MACHINE_TOGGLE")) { if (emulation_state != EMULATION_STOPPED) From 4b7328f06edcb83d3ccf3ef2f658b6898027829a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 17 Apr 2019 20:37:48 +0100 Subject: [PATCH 0682/1050] Add cassette emulation to IBM PCjr. --- src/keyboard_pcjr.c | 11 ++++++++++- src/model.c | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/keyboard_pcjr.c b/src/keyboard_pcjr.c index 13f443b..6799aea 100644 --- a/src/keyboard_pcjr.c +++ b/src/keyboard_pcjr.c @@ -1,5 +1,7 @@ #include "ibm.h" #include "device.h" +#include "cassette.h" +#include "fdd.h" #include "io.h" #include "mem.h" #include "nmi.h" @@ -129,6 +131,8 @@ void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) timer_process(); timer_update_outstanding(); + cassette_set_motor((val & 8) ? 0 : 1); + speaker_update(); speaker_gated = val & 1; speaker_enable = val & 2; @@ -171,7 +175,12 @@ uint8_t keyboard_pcjr_read(uint16_t port, void *priv) case 0x62: temp = (keyboard_pcjr.latched ? 1 : 0); temp |= 0x02; /*Modem card not installed*/ - temp |= (ppispeakon ? 0x10 : 0); + if (fdd_get_type(0) == 0) + temp |= 0x04; /*Disc card not installed*/ + if (!(keyboard_pcjr.pb & 8)) + temp |= (cassette_input()) ? 0x10 : 0; + else + temp |= (ppispeakon ? 0x10 : 0); temp |= (ppispeakon ? 0x20 : 0); temp |= (keyboard_pcjr.data ? 0x40: 0); // temp |= 0x04; diff --git a/src/model.c b/src/model.c index 587b6ab..75c17fa 100644 --- a/src/model.c +++ b/src/model.c @@ -325,6 +325,7 @@ void pcjr_init() keyboard_pcjr_init(); device_add(&sn76489_device); nmi_mask = 0x80; + device_add(&cassette_device); } void tandy1k_init() From f250788427ad1274deb0d4e1f52e86cc24b691a9 Mon Sep 17 00:00:00 2001 From: Koutakun Date: Thu, 18 Apr 2019 22:01:33 -0300 Subject: [PATCH 0683/1050] Slight fixes to make FreeBSD compilation easier --- Readme-BSD.txt | 31 +++++++++++++++++++++++++++++++ configure.ac | 12 ++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 Readme-BSD.txt diff --git a/Readme-BSD.txt b/Readme-BSD.txt new file mode 100644 index 0000000..54bd090 --- /dev/null +++ b/Readme-BSD.txt @@ -0,0 +1,31 @@ +PCem v14 BSD supplement + + +You will need the following libraries : + +SDL2 +wxWidgets 3.x +OpenAL + +and their dependencies. + +Open a terminal window, navigate to the PCem directory then enter + +./configure --enable-release-build +gmake + +then ./pcem to run. + +The BSD version stores BIOS ROM images, configuration files, and other data in ~/.pcem + +configure options are : + --enable-release-build : Generate release build. Recommended for regular use. + --enable-debug : Compile with debugging enabled. + --enable-networking : Build with networking support. + --enable-alsa : Build with support for MIDI output through ALSA. Requires libasound. + + +The menu is a pop-up menu in the BSD port. Right-click on the main window when mouse is not +captured. + +CD-ROM support currently only accesses /dev/cdrom. It has not been heavily tested. diff --git a/configure.ac b/configure.ac index 4a30d37..0236e48 100644 --- a/configure.ac +++ b/configure.ac @@ -150,6 +150,18 @@ case "$host" in exit -1]) build_linux="yes" ;; + *-*-freebsd*) + CFLAGS="$CFLAGS -I/usr/local/include" + CXXFLAGS="$CXXFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + AC_CHECK_LIB([GL], [glGetError], [], \ + [echo "You need to install the OpenGL library." + exit -1]) + AC_CHECK_LIB([openal], [alGetError], [], \ + [echo "You need to install the OpenAL library." + exit -1]) + build_other="yes" + ;; *) AC_CHECK_LIB([GL], [glGetError], [], \ [echo "You need to install the OpenGL library." From 406334d9d2c8c0608ac344f5bada07621cc49148 Mon Sep 17 00:00:00 2001 From: Koutakun Date: Thu, 18 Apr 2019 22:39:25 -0300 Subject: [PATCH 0684/1050] It also does not configure properly if install-sh isn't executable --- install-sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 install-sh diff --git a/install-sh b/install-sh old mode 100644 new mode 100755 From 443ae04fa39ed8dbdb1957a96779fc7d659d2243 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 23 Apr 2019 17:00:05 +0100 Subject: [PATCH 0685/1050] Add Bull Micral 45 emulation. Patch from dns2k. --- src/ibm.h | 1 + src/mem_bios.c | 13 +++++++++++++ src/model.c | 1 + src/nvr.c | 2 ++ 4 files changed, 17 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index ed3aac2..45bf831 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -469,6 +469,7 @@ enum ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */ ROM_PB410A, ROM_PPC512, + ROM_BULL_MICRAL_45, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 0f04f5f..2f0c8da 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -986,6 +986,19 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_BULL_MICRAL_45: + f = romfopen("bull_micral_45/even.fil", "rb"); + ff = romfopen("bull_micral_45/odd.fil", "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; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 75c17fa..c2e225b 100644 --- a/src/model.c +++ b/src/model.c @@ -155,6 +155,7 @@ MODEL models[] = {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, {"[286] Award 286 clone", ROM_AWARD286, "award286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_scat_init, NULL}, + {"[286] Bull Micral 45", ROM_BULL_MICRAL_45, "bull_micral_45", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1024, 6144, 128, ibm_at_init, NULL}, {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 640,16384, 128, at_cbm_init, NULL}, {"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 256,15872, 128, ibm_at_init, NULL}, {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 640,16384, 128, dells200_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index a09cb4d..f675742 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -323,6 +323,7 @@ void loadnvr() case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","rb"); break; case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "rb"); break; case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break; + case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); break; default: return; } @@ -421,6 +422,7 @@ void savenvr() case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr","wb"); break; case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "wb"); break; case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break; + case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); break; default: return; } From fb32dfceca15ab90b5c1e8597c8ac5a770fbdfa2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 23 Apr 2019 20:44:26 +0100 Subject: [PATCH 0686/1050] Added Image Manager 1024 emulation. Patch from John Elliott. --- src/Makefile.am | 4 +- src/Makefile.linux32-wx-sdl2 | 4 +- src/Makefile.linux64-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2 | 4 +- src/Makefile.mingw-wx-sdl2-network | 4 +- src/Makefile.osx64-wx-sdl2 | 4 +- src/ibm.h | 2 + src/mem_bios.c | 1 + src/pgc_palettes.h | 1554 +++++++++++++++++ src/vid_im1024.c | 906 ++++++++++ src/vid_im1024.h | 1 + src/vid_pgc.c | 2481 ++++++++++++++++++++++++++++ src/vid_pgc.h | 160 ++ src/video.c | 14 + src/video.h | 2 +- 15 files changed, 5132 insertions(+), 13 deletions(-) create mode 100644 src/pgc_palettes.h create mode 100644 src/vid_im1024.c create mode 100644 src/vid_im1024.h create mode 100644 src/vid_pgc.c create mode 100644 src/vid_pgc.h diff --git a/src/Makefile.am b/src/Makefile.am index f00cd36..9819b75 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,8 +36,8 @@ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_e t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ -vid_ht216.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.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_sigma.c \ +vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \ +vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c \ x86seg.c x87.c xi8088.c xtide.c zenith.c sound_dbopl.cc sound_resid.cc diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 index 4ab2d80..f57456a 100644 --- a/src/Makefile.linux32-wx-sdl2 +++ b/src/Makefile.linux32-wx-sdl2 @@ -16,8 +16,8 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ +vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 index 64e4e3c..6489ce6 100644 --- a/src/Makefile.linux64-wx-sdl2 +++ b/src/Makefile.linux64-wx-sdl2 @@ -16,8 +16,8 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ +vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index b49f36f..4ab7622 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -17,9 +17,9 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_sigma.o vid_stg_ramdac.o vid_svga.o \ + vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 0b2a993..6d80726 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -17,9 +17,9 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ + vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c 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_sigma.o vid_stg_ramdac.o vid_svga.o \ + vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o zenith.o win-midi.o \ wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 index 44169d3..536cfb3 100644 --- a/src/Makefile.osx64-wx-sdl2 +++ b/src/Makefile.osx64-wx-sdl2 @@ -15,8 +15,8 @@ sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_sb. sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o soundopenal.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_ht216.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ +vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ +vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ diff --git a/src/ibm.h b/src/ibm.h index 45bf831..d06218c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -516,6 +516,8 @@ enum GFX_OTI037, /*Oak OTI-037*/ GFX_COMPAQ_CGA, /*Compaq CGA*/ GFX_SIGMA400, /*Sigma Designs Color 400 */ + GFX_PGC, /*Professional Graphics Controller */ + GFX_IM1024, /*Vermont Microsystems IM1024 */ GFX_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 2f0c8da..9a1ed6f 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -62,6 +62,7 @@ int loadbios() loadfont("mda.rom", FONT_MDA); loadfont("wy700.rom", FONT_WY700); loadfont("8x12.bin", FONT_MDSI); + loadfont("im1024font.bin", FONT_IM1024); biosmask = 0xffff; diff --git a/src/pgc_palettes.h b/src/pgc_palettes.h new file mode 100644 index 0000000..2d3d0dd --- /dev/null +++ b/src/pgc_palettes.h @@ -0,0 +1,1554 @@ +/* Palette 0: Default */ + { + makecol(0x00,0x00,0x00), + makecol(0x11,0x11,0x11), + makecol(0x22,0x22,0x22), + makecol(0x33,0x33,0x33), + makecol(0x44,0x44,0x44), + makecol(0x55,0x55,0x55), + makecol(0x66,0x66,0x66), + makecol(0x77,0x77,0x77), + makecol(0x88,0x88,0x88), + makecol(0x99,0x99,0x99), + makecol(0xaa,0xaa,0xaa), + makecol(0xbb,0xbb,0xbb), + makecol(0xcc,0xcc,0xcc), + makecol(0xdd,0xdd,0xdd), + makecol(0xee,0xee,0xee), + makecol(0xff,0xff,0xff), + makecol(0x00,0x00,0x00), + makecol(0x00,0x22,0x00), + makecol(0x00,0x44,0x00), + makecol(0x00,0x66,0x00), + makecol(0x00,0x88,0x00), + makecol(0x00,0xaa,0x00), + makecol(0x00,0xcc,0x00), + makecol(0x00,0xee,0x00), + makecol(0x00,0xff,0x00), + makecol(0x22,0xff,0x22), + makecol(0x44,0xff,0x44), + makecol(0x66,0xff,0x66), + makecol(0x88,0xff,0x88), + makecol(0xaa,0xff,0xaa), + makecol(0xcc,0xff,0xcc), + makecol(0xee,0xff,0xee), + makecol(0x00,0x00,0x00), + makecol(0x00,0x22,0x11), + makecol(0x00,0x44,0x22), + makecol(0x00,0x66,0x33), + makecol(0x00,0x88,0x44), + makecol(0x00,0xaa,0x55), + makecol(0x00,0xcc,0x66), + makecol(0x00,0xee,0x77), + makecol(0x00,0xff,0x88), + makecol(0x22,0xff,0x99), + makecol(0x44,0xff,0xaa), + makecol(0x66,0xff,0xbb), + makecol(0x88,0xff,0xcc), + makecol(0xaa,0xff,0xdd), + makecol(0xcc,0xff,0xee), + makecol(0xee,0xff,0xff), + makecol(0x00,0x00,0x00), + makecol(0x00,0x22,0x22), + makecol(0x00,0x44,0x44), + makecol(0x00,0x66,0x66), + makecol(0x00,0x88,0x88), + makecol(0x00,0xaa,0xaa), + makecol(0x00,0xcc,0xcc), + makecol(0x00,0xee,0xee), + makecol(0x00,0xff,0xff), + makecol(0x22,0xff,0xff), + makecol(0x44,0xff,0xff), + makecol(0x66,0xff,0xff), + makecol(0x88,0xff,0xff), + makecol(0xaa,0xff,0xff), + makecol(0xcc,0xff,0xff), + makecol(0xee,0xff,0xff), + makecol(0x00,0x00,0x00), + makecol(0x00,0x11,0x22), + makecol(0x00,0x22,0x44), + makecol(0x00,0x33,0x66), + makecol(0x00,0x44,0x88), + makecol(0x00,0x55,0xaa), + makecol(0x00,0x66,0xcc), + makecol(0x00,0x77,0xee), + makecol(0x00,0x88,0xff), + makecol(0x22,0x99,0xff), + makecol(0x44,0xaa,0xff), + makecol(0x66,0xbb,0xff), + makecol(0x88,0xcc,0xff), + makecol(0xaa,0xdd,0xff), + makecol(0xcc,0xee,0xff), + makecol(0xee,0xff,0xff), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x22), + makecol(0x00,0x00,0x44), + makecol(0x00,0x00,0x66), + makecol(0x00,0x00,0x88), + makecol(0x00,0x00,0xaa), + makecol(0x00,0x00,0xcc), + makecol(0x00,0x00,0xee), + makecol(0x00,0x00,0xff), + makecol(0x22,0x22,0xff), + makecol(0x44,0x44,0xff), + makecol(0x66,0x66,0xff), + makecol(0x88,0x88,0xff), + makecol(0xaa,0xaa,0xff), + makecol(0xcc,0xcc,0xff), + makecol(0xee,0xee,0xff), + makecol(0x00,0x00,0x00), + makecol(0x11,0x00,0x22), + makecol(0x22,0x00,0x44), + makecol(0x33,0x00,0x66), + makecol(0x44,0x00,0x88), + makecol(0x55,0x00,0xaa), + makecol(0x66,0x00,0xcc), + makecol(0x77,0x00,0xee), + makecol(0x88,0x00,0xff), + makecol(0x99,0x22,0xff), + makecol(0xaa,0x44,0xff), + makecol(0xbb,0x66,0xff), + makecol(0xcc,0x88,0xff), + makecol(0xdd,0xaa,0xff), + makecol(0xee,0xcc,0xff), + makecol(0xff,0xee,0xff), + makecol(0x00,0x00,0x00), + makecol(0x22,0x00,0x22), + makecol(0x44,0x00,0x44), + makecol(0x66,0x00,0x66), + makecol(0x88,0x00,0x88), + makecol(0xaa,0x00,0xaa), + makecol(0xcc,0x00,0xcc), + makecol(0xee,0x00,0xee), + makecol(0xff,0x00,0xff), + makecol(0xff,0x22,0xff), + makecol(0xff,0x44,0xff), + makecol(0xff,0x66,0xff), + makecol(0xff,0x88,0xff), + makecol(0xff,0xaa,0xff), + makecol(0xff,0xcc,0xff), + makecol(0xff,0xee,0xff), + makecol(0x00,0x00,0x00), + makecol(0x22,0x00,0x11), + makecol(0x44,0x00,0x22), + makecol(0x66,0x00,0x33), + makecol(0x88,0x00,0x44), + makecol(0xaa,0x00,0x55), + makecol(0xcc,0x00,0x66), + makecol(0xee,0x00,0x77), + makecol(0xff,0x00,0x88), + makecol(0xff,0x22,0x99), + makecol(0xff,0x44,0xaa), + makecol(0xff,0x66,0xbb), + makecol(0xff,0x88,0xcc), + makecol(0xff,0xaa,0xdd), + makecol(0xff,0xcc,0xee), + makecol(0xff,0xee,0xff), + makecol(0x00,0x00,0x00), + makecol(0x22,0x00,0x00), + makecol(0x44,0x00,0x00), + makecol(0x66,0x00,0x00), + makecol(0x88,0x00,0x00), + makecol(0xaa,0x00,0x00), + makecol(0xcc,0x00,0x00), + makecol(0xee,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x22,0x22), + makecol(0xff,0x44,0x44), + makecol(0xff,0x66,0x66), + makecol(0xff,0x88,0x88), + makecol(0xff,0xaa,0xaa), + makecol(0xff,0xcc,0xcc), + makecol(0xff,0xee,0xee), + makecol(0x00,0x00,0x00), + makecol(0x22,0x11,0x00), + makecol(0x44,0x22,0x00), + makecol(0x66,0x33,0x00), + makecol(0x88,0x44,0x00), + makecol(0xaa,0x55,0x00), + makecol(0xcc,0x66,0x00), + makecol(0xee,0x77,0x00), + makecol(0xff,0x88,0x00), + makecol(0xff,0x99,0x22), + makecol(0xff,0xaa,0x44), + makecol(0xff,0xbb,0x66), + makecol(0xff,0xcc,0x88), + makecol(0xff,0xdd,0xaa), + makecol(0xff,0xee,0xcc), + makecol(0xff,0xff,0xee), + makecol(0x00,0x00,0x00), + makecol(0x22,0x22,0x00), + makecol(0x44,0x44,0x00), + makecol(0x66,0x66,0x00), + makecol(0x88,0x88,0x00), + makecol(0xaa,0xaa,0x00), + makecol(0xcc,0xcc,0x00), + makecol(0xee,0xee,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x22), + makecol(0xff,0xff,0x44), + makecol(0xff,0xff,0x66), + makecol(0xff,0xff,0x88), + makecol(0xff,0xff,0xaa), + makecol(0xff,0xff,0xcc), + makecol(0xff,0xff,0xee), + makecol(0x00,0x00,0x00), + makecol(0x11,0x22,0x00), + makecol(0x22,0x44,0x00), + makecol(0x33,0x66,0x00), + makecol(0x44,0x88,0x00), + makecol(0x55,0xaa,0x00), + makecol(0x66,0xcc,0x00), + makecol(0x77,0xee,0x00), + makecol(0x88,0xff,0x00), + makecol(0x99,0xff,0x22), + makecol(0xaa,0xff,0x44), + makecol(0xbb,0xff,0x66), + makecol(0xcc,0xff,0x88), + makecol(0xdd,0xff,0xaa), + makecol(0xee,0xff,0xcc), + makecol(0xff,0xff,0xee), + makecol(0x00,0x00,0x00), + makecol(0x00,0x11,0x00), + makecol(0x11,0x33,0x11), + makecol(0x11,0x44,0x11), + makecol(0x22,0x66,0x22), + makecol(0x22,0x77,0x22), + makecol(0x33,0x99,0x33), + makecol(0x33,0xaa,0x33), + makecol(0x44,0xcc,0x44), + makecol(0x55,0xcc,0x55), + makecol(0x77,0xdd,0x77), + makecol(0x88,0xdd,0x88), + makecol(0xaa,0xee,0xaa), + makecol(0xbb,0xee,0xbb), + makecol(0xdd,0xff,0xdd), + makecol(0xee,0xff,0xee), + makecol(0x00,0x00,0x00), + makecol(0x11,0x00,0x00), + makecol(0x33,0x11,0x11), + makecol(0x44,0x11,0x11), + makecol(0x66,0x22,0x22), + makecol(0x77,0x22,0x22), + makecol(0x99,0x33,0x33), + makecol(0xaa,0x33,0x33), + makecol(0xcc,0x44,0x44), + makecol(0xcc,0x55,0x55), + makecol(0xdd,0x77,0x77), + makecol(0xdd,0x88,0x88), + makecol(0xee,0xaa,0xaa), + makecol(0xee,0xbb,0xbb), + makecol(0xff,0xdd,0xdd), + makecol(0xff,0xee,0xee), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x11), + makecol(0x11,0x11,0x33), + makecol(0x11,0x11,0x44), + makecol(0x22,0x22,0x66), + makecol(0x22,0x22,0x77), + makecol(0x33,0x33,0x99), + makecol(0x33,0x33,0xaa), + makecol(0x44,0x44,0xcc), + makecol(0x55,0x55,0xcc), + makecol(0x77,0x77,0xdd), + makecol(0x88,0x88,0xdd), + makecol(0xaa,0xaa,0xee), + makecol(0xbb,0xbb,0xee), + makecol(0xdd,0xdd,0xff), + makecol(0xee,0xee,0xff), + }, +/* Palette 1: 16-colour palette */ + { + makecol(0x88,0x66,0xdd), + makecol(0x00,0x00,0x00), + makecol(0x44,0x77,0x22), + makecol(0x77,0xaa,0x44), + makecol(0x00,0x77,0x00), + makecol(0x00,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x99,0xee,0x66), + makecol(0x77,0x77,0x77), + makecol(0xff,0xff,0xff), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x44,0x77,0x22), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x77,0xaa,0x44), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x77), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x99,0xee,0x66), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0x77,0x77,0x77), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + makecol(0xff,0xff,0xff), + }, +/* Palette 2: 2-3-3 truecolour */ + { + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x33), + makecol(0x00,0x00,0x55), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x99), + makecol(0x00,0x00,0xbb), + makecol(0x00,0x00,0xdd), + makecol(0x00,0x00,0xff), + makecol(0x33,0x00,0x00), + makecol(0x33,0x00,0x33), + makecol(0x33,0x00,0x55), + makecol(0x33,0x00,0x77), + makecol(0x33,0x00,0x99), + makecol(0x33,0x00,0xbb), + makecol(0x33,0x00,0xdd), + makecol(0x33,0x00,0xff), + makecol(0x55,0x00,0x00), + makecol(0x55,0x00,0x33), + makecol(0x55,0x00,0x55), + makecol(0x55,0x00,0x77), + makecol(0x55,0x00,0x99), + makecol(0x55,0x00,0xbb), + makecol(0x55,0x00,0xdd), + makecol(0x55,0x00,0xff), + makecol(0x77,0x00,0x00), + makecol(0x77,0x00,0x33), + makecol(0x77,0x00,0x55), + makecol(0x77,0x00,0x77), + makecol(0x77,0x00,0x99), + makecol(0x77,0x00,0xbb), + makecol(0x77,0x00,0xdd), + makecol(0x77,0x00,0xff), + makecol(0x99,0x00,0x00), + makecol(0x99,0x00,0x33), + makecol(0x99,0x00,0x55), + makecol(0x99,0x00,0x77), + makecol(0x99,0x00,0x99), + makecol(0x99,0x00,0xbb), + makecol(0x99,0x00,0xdd), + makecol(0x99,0x00,0xff), + makecol(0xbb,0x00,0x00), + makecol(0xbb,0x00,0x33), + makecol(0xbb,0x00,0x55), + makecol(0xbb,0x00,0x77), + makecol(0xbb,0x00,0x99), + makecol(0xbb,0x00,0xbb), + makecol(0xbb,0x00,0xdd), + makecol(0xbb,0x00,0xff), + makecol(0xdd,0x00,0x00), + makecol(0xdd,0x00,0x33), + makecol(0xdd,0x00,0x55), + makecol(0xdd,0x00,0x77), + makecol(0xdd,0x00,0x99), + makecol(0xdd,0x00,0xbb), + makecol(0xdd,0x00,0xdd), + makecol(0xdd,0x00,0xff), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x33), + makecol(0xff,0x00,0x55), + makecol(0xff,0x00,0x77), + makecol(0xff,0x00,0x99), + makecol(0xff,0x00,0xbb), + makecol(0xff,0x00,0xdd), + makecol(0xff,0x00,0xff), + makecol(0x00,0x55,0x00), + makecol(0x00,0x55,0x33), + makecol(0x00,0x55,0x55), + makecol(0x00,0x55,0x77), + makecol(0x00,0x55,0x99), + makecol(0x00,0x55,0xbb), + makecol(0x00,0x55,0xdd), + makecol(0x00,0x55,0xff), + makecol(0x33,0x55,0x00), + makecol(0x33,0x55,0x33), + makecol(0x33,0x55,0x55), + makecol(0x33,0x55,0x77), + makecol(0x33,0x55,0x99), + makecol(0x33,0x55,0xbb), + makecol(0x33,0x55,0xdd), + makecol(0x33,0x55,0xff), + makecol(0x55,0x55,0x00), + makecol(0x55,0x55,0x33), + makecol(0x55,0x55,0x55), + makecol(0x55,0x55,0x77), + makecol(0x55,0x55,0x99), + makecol(0x55,0x55,0xbb), + makecol(0x55,0x55,0xdd), + makecol(0x55,0x55,0xff), + makecol(0x77,0x55,0x00), + makecol(0x77,0x55,0x33), + makecol(0x77,0x55,0x55), + makecol(0x77,0x55,0x77), + makecol(0x77,0x55,0x99), + makecol(0x77,0x55,0xbb), + makecol(0x77,0x55,0xdd), + makecol(0x77,0x55,0xff), + makecol(0x99,0x55,0x00), + makecol(0x99,0x55,0x33), + makecol(0x99,0x55,0x55), + makecol(0x99,0x55,0x77), + makecol(0x99,0x55,0x99), + makecol(0x99,0x55,0xbb), + makecol(0x99,0x55,0xdd), + makecol(0x99,0x55,0xff), + makecol(0xbb,0x55,0x00), + makecol(0xbb,0x55,0x33), + makecol(0xbb,0x55,0x55), + makecol(0xbb,0x55,0x77), + makecol(0xbb,0x55,0x99), + makecol(0xbb,0x55,0xbb), + makecol(0xbb,0x55,0xdd), + makecol(0xbb,0x55,0xff), + makecol(0xdd,0x55,0x00), + makecol(0xdd,0x55,0x33), + makecol(0xdd,0x55,0x55), + makecol(0xdd,0x55,0x77), + makecol(0xdd,0x55,0x99), + makecol(0xdd,0x55,0xbb), + makecol(0xdd,0x55,0xdd), + makecol(0xdd,0x55,0xff), + makecol(0xff,0x55,0x00), + makecol(0xff,0x55,0x33), + makecol(0xff,0x55,0x55), + makecol(0xff,0x55,0x77), + makecol(0xff,0x55,0x99), + makecol(0xff,0x55,0xbb), + makecol(0xff,0x55,0xdd), + makecol(0xff,0x55,0xff), + makecol(0x00,0xaa,0x00), + makecol(0x00,0xaa,0x33), + makecol(0x00,0xaa,0x55), + makecol(0x00,0xaa,0x77), + makecol(0x00,0xaa,0x99), + makecol(0x00,0xaa,0xbb), + makecol(0x00,0xaa,0xdd), + makecol(0x00,0xaa,0xff), + makecol(0x33,0xaa,0x00), + makecol(0x33,0xaa,0x33), + makecol(0x33,0xaa,0x55), + makecol(0x33,0xaa,0x77), + makecol(0x33,0xaa,0x99), + makecol(0x33,0xaa,0xbb), + makecol(0x33,0xaa,0xdd), + makecol(0x33,0xaa,0xff), + makecol(0x55,0xaa,0x00), + makecol(0x55,0xaa,0x33), + makecol(0x55,0xaa,0x55), + makecol(0x55,0xaa,0x77), + makecol(0x55,0xaa,0x99), + makecol(0x55,0xaa,0xbb), + makecol(0x55,0xaa,0xdd), + makecol(0x55,0xaa,0xff), + makecol(0x77,0xaa,0x00), + makecol(0x77,0xaa,0x33), + makecol(0x77,0xaa,0x55), + makecol(0x77,0xaa,0x77), + makecol(0x77,0xaa,0x99), + makecol(0x77,0xaa,0xbb), + makecol(0x77,0xaa,0xdd), + makecol(0x77,0xaa,0xff), + makecol(0x99,0xaa,0x00), + makecol(0x99,0xaa,0x33), + makecol(0x99,0xaa,0x55), + makecol(0x99,0xaa,0x77), + makecol(0x99,0xaa,0x99), + makecol(0x99,0xaa,0xbb), + makecol(0x99,0xaa,0xdd), + makecol(0x99,0xaa,0xff), + makecol(0xbb,0xaa,0x00), + makecol(0xbb,0xaa,0x33), + makecol(0xbb,0xaa,0x55), + makecol(0xbb,0xaa,0x77), + makecol(0xbb,0xaa,0x99), + makecol(0xbb,0xaa,0xbb), + makecol(0xbb,0xaa,0xdd), + makecol(0xbb,0xaa,0xff), + makecol(0xdd,0xaa,0x00), + makecol(0xdd,0xaa,0x33), + makecol(0xdd,0xaa,0x55), + makecol(0xdd,0xaa,0x77), + makecol(0xdd,0xaa,0x99), + makecol(0xdd,0xaa,0xbb), + makecol(0xdd,0xaa,0xdd), + makecol(0xdd,0xaa,0xff), + makecol(0xff,0xaa,0x00), + makecol(0xff,0xaa,0x33), + makecol(0xff,0xaa,0x55), + makecol(0xff,0xaa,0x77), + makecol(0xff,0xaa,0x99), + makecol(0xff,0xaa,0xbb), + makecol(0xff,0xaa,0xdd), + makecol(0xff,0xaa,0xee), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x33), + makecol(0x00,0xff,0x55), + makecol(0x00,0xff,0x77), + makecol(0x00,0xff,0x99), + makecol(0x00,0xff,0xbb), + makecol(0x00,0xff,0xdd), + makecol(0x00,0xff,0xff), + makecol(0x33,0xff,0x00), + makecol(0x33,0xff,0x33), + makecol(0x33,0xff,0x55), + makecol(0x33,0xff,0x77), + makecol(0x33,0xff,0x99), + makecol(0x33,0xff,0xbb), + makecol(0x33,0xff,0xdd), + makecol(0x33,0xff,0xff), + makecol(0x55,0xff,0x00), + makecol(0x55,0xff,0x33), + makecol(0x55,0xff,0x55), + makecol(0x55,0xff,0x77), + makecol(0x55,0xff,0x99), + makecol(0x55,0xff,0xbb), + makecol(0x55,0xff,0xdd), + makecol(0x55,0xff,0xff), + makecol(0x77,0xff,0x00), + makecol(0x77,0xff,0x33), + makecol(0x77,0xff,0x55), + makecol(0x77,0xff,0x77), + makecol(0x77,0xff,0x99), + makecol(0x77,0xff,0xbb), + makecol(0x77,0xff,0xdd), + makecol(0x77,0xff,0xff), + makecol(0x99,0xff,0x00), + makecol(0x99,0xff,0x33), + makecol(0x99,0xff,0x55), + makecol(0x99,0xff,0x77), + makecol(0x99,0xff,0x99), + makecol(0x99,0xff,0xbb), + makecol(0x99,0xff,0xdd), + makecol(0x99,0xff,0xff), + makecol(0xbb,0xff,0x00), + makecol(0xbb,0xff,0x33), + makecol(0xbb,0xff,0x55), + makecol(0xbb,0xff,0x77), + makecol(0xbb,0xff,0x99), + makecol(0xbb,0xff,0xbb), + makecol(0xbb,0xff,0xdd), + makecol(0xbb,0xff,0xff), + makecol(0xdd,0xff,0x00), + makecol(0xdd,0xff,0x33), + makecol(0xdd,0xff,0x55), + makecol(0xdd,0xff,0x77), + makecol(0xdd,0xff,0x99), + makecol(0xdd,0xff,0xbb), + makecol(0xdd,0xff,0xdd), + makecol(0xdd,0xff,0xff), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x33), + makecol(0xff,0xff,0x55), + makecol(0xff,0xff,0x77), + makecol(0xff,0xff,0x99), + makecol(0xff,0xff,0xbb), + makecol(0xff,0xff,0xdd), + makecol(0xff,0xff,0xff), + }, +/* Palette 3: 3-2-3 truecolour */ + { + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x33), + makecol(0x00,0x00,0x55), + makecol(0x00,0x00,0x77), + makecol(0x00,0x00,0x99), + makecol(0x00,0x00,0xbb), + makecol(0x00,0x00,0xdd), + makecol(0x00,0x00,0xff), + makecol(0x55,0x00,0x00), + makecol(0x55,0x00,0x33), + makecol(0x55,0x00,0x55), + makecol(0x55,0x00,0x77), + makecol(0x55,0x00,0x99), + makecol(0x55,0x00,0xbb), + makecol(0x55,0x00,0xdd), + makecol(0x55,0x00,0xff), + makecol(0xaa,0x00,0x00), + makecol(0xaa,0x00,0x33), + makecol(0xaa,0x00,0x55), + makecol(0xaa,0x00,0x77), + makecol(0xaa,0x00,0x99), + makecol(0xaa,0x00,0xbb), + makecol(0xaa,0x00,0xdd), + makecol(0xaa,0x00,0xff), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x33), + makecol(0xff,0x00,0x55), + makecol(0xff,0x00,0x77), + makecol(0xff,0x00,0x99), + makecol(0xff,0x00,0xbb), + makecol(0xff,0x00,0xdd), + makecol(0xff,0x00,0xff), + makecol(0x00,0x33,0x00), + makecol(0x00,0x33,0x33), + makecol(0x00,0x33,0x55), + makecol(0x00,0x33,0x77), + makecol(0x00,0x33,0x99), + makecol(0x00,0x33,0xbb), + makecol(0x00,0x33,0xdd), + makecol(0x00,0x33,0xff), + makecol(0x55,0x33,0x00), + makecol(0x55,0x33,0x33), + makecol(0x55,0x33,0x55), + makecol(0x55,0x33,0x77), + makecol(0x55,0x33,0x99), + makecol(0x55,0x33,0xbb), + makecol(0x55,0x33,0xdd), + makecol(0x55,0x33,0xff), + makecol(0xaa,0x33,0x00), + makecol(0xaa,0x33,0x33), + makecol(0xaa,0x33,0x55), + makecol(0xaa,0x33,0x77), + makecol(0xaa,0x33,0x99), + makecol(0xaa,0x33,0xbb), + makecol(0xaa,0x33,0xdd), + makecol(0xaa,0x33,0xff), + makecol(0xff,0x33,0x00), + makecol(0xff,0x33,0x33), + makecol(0xff,0x33,0x55), + makecol(0xff,0x33,0x77), + makecol(0xff,0x33,0x99), + makecol(0xff,0x33,0xbb), + makecol(0xff,0x33,0xdd), + makecol(0xff,0x33,0xff), + makecol(0x00,0x55,0x00), + makecol(0x00,0x55,0x33), + makecol(0x00,0x55,0x55), + makecol(0x00,0x55,0x77), + makecol(0x00,0x55,0x99), + makecol(0x00,0x55,0xbb), + makecol(0x00,0x55,0xdd), + makecol(0x00,0x55,0xff), + makecol(0x55,0x55,0x00), + makecol(0x55,0x55,0x33), + makecol(0x55,0x55,0x55), + makecol(0x55,0x55,0x77), + makecol(0x55,0x55,0x99), + makecol(0x55,0x55,0xbb), + makecol(0x55,0x55,0xdd), + makecol(0x55,0x55,0xff), + makecol(0xaa,0x55,0x00), + makecol(0xaa,0x55,0x33), + makecol(0xaa,0x55,0x55), + makecol(0xaa,0x55,0x77), + makecol(0xaa,0x55,0x99), + makecol(0xaa,0x55,0xbb), + makecol(0xaa,0x55,0xdd), + makecol(0xaa,0x55,0xff), + makecol(0xff,0x55,0x00), + makecol(0xff,0x55,0x33), + makecol(0xff,0x55,0x55), + makecol(0xff,0x55,0x77), + makecol(0xff,0x55,0x99), + makecol(0xff,0x55,0xbb), + makecol(0xff,0x55,0xdd), + makecol(0xff,0x55,0xff), + makecol(0x00,0x77,0x00), + makecol(0x00,0x77,0x33), + makecol(0x00,0x77,0x55), + makecol(0x00,0x77,0x77), + makecol(0x00,0x77,0x99), + makecol(0x00,0x77,0xbb), + makecol(0x00,0x77,0xdd), + makecol(0x00,0x77,0xff), + makecol(0x55,0x77,0x00), + makecol(0x55,0x77,0x33), + makecol(0x55,0x77,0x55), + makecol(0x55,0x77,0x77), + makecol(0x55,0x77,0x99), + makecol(0x55,0x77,0xbb), + makecol(0x55,0x77,0xdd), + makecol(0x55,0x77,0xff), + makecol(0xaa,0x77,0x00), + makecol(0xaa,0x77,0x33), + makecol(0xaa,0x77,0x55), + makecol(0xaa,0x77,0x77), + makecol(0xaa,0x77,0x99), + makecol(0xaa,0x77,0xbb), + makecol(0xaa,0x77,0xdd), + makecol(0xaa,0x77,0xff), + makecol(0xff,0x77,0x00), + makecol(0xff,0x77,0x33), + makecol(0xff,0x77,0x55), + makecol(0xff,0x77,0x77), + makecol(0xff,0x77,0x99), + makecol(0xff,0x77,0xbb), + makecol(0xff,0x77,0xdd), + makecol(0xff,0x77,0xff), + makecol(0x00,0x99,0x00), + makecol(0x00,0x99,0x33), + makecol(0x00,0x99,0x55), + makecol(0x00,0x99,0x77), + makecol(0x00,0x99,0x99), + makecol(0x00,0x99,0xbb), + makecol(0x00,0x99,0xdd), + makecol(0x00,0x99,0xff), + makecol(0x55,0x99,0x00), + makecol(0x55,0x99,0x33), + makecol(0x55,0x99,0x55), + makecol(0x55,0x99,0x77), + makecol(0x55,0x99,0x99), + makecol(0x55,0x99,0xbb), + makecol(0x55,0x99,0xdd), + makecol(0x55,0x99,0xff), + makecol(0xaa,0x99,0x00), + makecol(0xaa,0x99,0x33), + makecol(0xaa,0x99,0x55), + makecol(0xaa,0x99,0x77), + makecol(0xaa,0x99,0x99), + makecol(0xaa,0x99,0xbb), + makecol(0xaa,0x99,0xdd), + makecol(0xaa,0x99,0xff), + makecol(0xff,0x99,0x00), + makecol(0xff,0x99,0x33), + makecol(0xff,0x99,0x55), + makecol(0xff,0x99,0x77), + makecol(0xff,0x99,0x99), + makecol(0xff,0x99,0xbb), + makecol(0xff,0x99,0xdd), + makecol(0xff,0x99,0xff), + makecol(0x00,0xbb,0x00), + makecol(0x00,0xbb,0x33), + makecol(0x00,0xbb,0x55), + makecol(0x00,0xbb,0x77), + makecol(0x00,0xbb,0x99), + makecol(0x00,0xbb,0xbb), + makecol(0x00,0xbb,0xdd), + makecol(0x00,0xbb,0xff), + makecol(0x55,0xbb,0x00), + makecol(0x55,0xbb,0x33), + makecol(0x55,0xbb,0x55), + makecol(0x55,0xbb,0x77), + makecol(0x55,0xbb,0x99), + makecol(0x55,0xbb,0xbb), + makecol(0x55,0xbb,0xdd), + makecol(0x55,0xbb,0xff), + makecol(0xaa,0xbb,0x00), + makecol(0xaa,0xbb,0x33), + makecol(0xaa,0xbb,0x55), + makecol(0xaa,0xbb,0x77), + makecol(0xaa,0xbb,0x99), + makecol(0xaa,0xbb,0xbb), + makecol(0xaa,0xbb,0xdd), + makecol(0xaa,0xbb,0xff), + makecol(0xff,0xbb,0x00), + makecol(0xff,0xbb,0x33), + makecol(0xff,0xbb,0x55), + makecol(0xff,0xbb,0x77), + makecol(0xff,0xbb,0x99), + makecol(0xff,0xbb,0xbb), + makecol(0xff,0xbb,0xdd), + makecol(0xff,0xbb,0xff), + makecol(0x00,0xdd,0x00), + makecol(0x00,0xdd,0x33), + makecol(0x00,0xdd,0x55), + makecol(0x00,0xdd,0x77), + makecol(0x00,0xdd,0x99), + makecol(0x00,0xdd,0xbb), + makecol(0x00,0xdd,0xdd), + makecol(0x00,0xdd,0xff), + makecol(0x55,0xdd,0x00), + makecol(0x55,0xdd,0x33), + makecol(0x55,0xdd,0x55), + makecol(0x55,0xdd,0x77), + makecol(0x55,0xdd,0x99), + makecol(0x55,0xdd,0xbb), + makecol(0x55,0xdd,0xdd), + makecol(0x55,0xdd,0xff), + makecol(0xaa,0xdd,0x00), + makecol(0xaa,0xdd,0x33), + makecol(0xaa,0xdd,0x55), + makecol(0xaa,0xdd,0x77), + makecol(0xaa,0xdd,0x99), + makecol(0xaa,0xdd,0xbb), + makecol(0xaa,0xdd,0xdd), + makecol(0xaa,0xdd,0xff), + makecol(0xff,0xdd,0x00), + makecol(0xff,0xdd,0x33), + makecol(0xff,0xdd,0x55), + makecol(0xff,0xdd,0x77), + makecol(0xff,0xdd,0x99), + makecol(0xff,0xdd,0xbb), + makecol(0xff,0xdd,0xdd), + makecol(0xff,0xdd,0xff), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x33), + makecol(0x00,0xff,0x55), + makecol(0x00,0xff,0x77), + makecol(0x00,0xff,0x99), + makecol(0x00,0xff,0xbb), + makecol(0x00,0xff,0xdd), + makecol(0x00,0xff,0xff), + makecol(0x55,0xff,0x00), + makecol(0x55,0xff,0x33), + makecol(0x55,0xff,0x55), + makecol(0x55,0xff,0x77), + makecol(0x55,0xff,0x99), + makecol(0x55,0xff,0xbb), + makecol(0x55,0xff,0xdd), + makecol(0x55,0xff,0xff), + makecol(0xaa,0xff,0x00), + makecol(0xaa,0xff,0x33), + makecol(0xaa,0xff,0x55), + makecol(0xaa,0xff,0x77), + makecol(0xaa,0xff,0x99), + makecol(0xaa,0xff,0xbb), + makecol(0xaa,0xff,0xdd), + makecol(0xaa,0xff,0xff), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x33), + makecol(0xff,0xff,0x55), + makecol(0xff,0xff,0x77), + makecol(0xff,0xff,0x99), + makecol(0xff,0xff,0xbb), + makecol(0xff,0xff,0xdd), + makecol(0xff,0xff,0xff), + }, +/* Palette 4: 3-3-2 truecolour */ + { + makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x55), + makecol(0x00, 0x00, 0xaa), + makecol(0x00, 0x00, 0xff), + makecol(0x00, 0x33, 0x00), + makecol(0x00, 0x33, 0x55), + makecol(0x00, 0x33, 0xaa), + makecol(0x00, 0x33, 0xff), + makecol(0x00, 0x55, 0x00), + makecol(0x00, 0x55, 0x55), + makecol(0x00, 0x55, 0xaa), + makecol(0x00, 0x55, 0xff), + makecol(0x00, 0x77, 0x00), + makecol(0x00, 0x77, 0x55), + makecol(0x00, 0x77, 0xaa), + makecol(0x00, 0x77, 0xff), + makecol(0x00, 0x99, 0x00), + makecol(0x00, 0x99, 0x55), + makecol(0x00, 0x99, 0xaa), + makecol(0x00, 0x99, 0xff), + makecol(0x00, 0xbb, 0x00), + makecol(0x00, 0xbb, 0x55), + makecol(0x00, 0xbb, 0xaa), + makecol(0x00, 0xbb, 0xff), + makecol(0x00, 0xdd, 0x00), + makecol(0x00, 0xdd, 0x55), + makecol(0x00, 0xdd, 0xaa), + makecol(0x00, 0xdd, 0xff), + makecol(0x00, 0xff, 0x00), + makecol(0x00, 0xff, 0x55), + makecol(0x00, 0xff, 0xaa), + makecol(0x00, 0xff, 0xff), + makecol(0x33, 0x00, 0x00), + makecol(0x33, 0x00, 0x55), + makecol(0x33, 0x00, 0xaa), + makecol(0x33, 0x00, 0xff), + makecol(0x33, 0x33, 0x00), + makecol(0x33, 0x33, 0x55), + makecol(0x33, 0x33, 0xaa), + makecol(0x33, 0x33, 0xff), + makecol(0x33, 0x55, 0x00), + makecol(0x33, 0x55, 0x55), + makecol(0x33, 0x55, 0xaa), + makecol(0x33, 0x55, 0xff), + makecol(0x33, 0x77, 0x00), + makecol(0x33, 0x77, 0x55), + makecol(0x33, 0x77, 0xaa), + makecol(0x33, 0x77, 0xff), + makecol(0x33, 0x99, 0x00), + makecol(0x33, 0x99, 0x55), + makecol(0x33, 0x99, 0xaa), + makecol(0x33, 0x99, 0xff), + makecol(0x33, 0xbb, 0x00), + makecol(0x33, 0xbb, 0x55), + makecol(0x33, 0xbb, 0xaa), + makecol(0x33, 0xbb, 0xff), + makecol(0x33, 0xdd, 0x00), + makecol(0x33, 0xdd, 0x55), + makecol(0x33, 0xdd, 0xaa), + makecol(0x33, 0xdd, 0xff), + makecol(0x33, 0xff, 0x00), + makecol(0x33, 0xff, 0x55), + makecol(0x33, 0xff, 0xaa), + makecol(0x33, 0xff, 0xff), + makecol(0x55, 0x00, 0x00), + makecol(0x55, 0x00, 0x55), + makecol(0x55, 0x00, 0xaa), + makecol(0x55, 0x00, 0xff), + makecol(0x55, 0x33, 0x00), + makecol(0x55, 0x33, 0x55), + makecol(0x55, 0x33, 0xaa), + makecol(0x55, 0x33, 0xff), + makecol(0x55, 0x55, 0x00), + makecol(0x55, 0x55, 0x55), + makecol(0x55, 0x55, 0xaa), + makecol(0x55, 0x55, 0xff), + makecol(0x55, 0x77, 0x00), + makecol(0x55, 0x77, 0x55), + makecol(0x55, 0x77, 0xaa), + makecol(0x55, 0x77, 0xff), + makecol(0x55, 0x99, 0x00), + makecol(0x55, 0x99, 0x55), + makecol(0x55, 0x99, 0xaa), + makecol(0x55, 0x99, 0xff), + makecol(0x55, 0xbb, 0x00), + makecol(0x55, 0xbb, 0x55), + makecol(0x55, 0xbb, 0xaa), + makecol(0x55, 0xbb, 0xff), + makecol(0x55, 0xdd, 0x00), + makecol(0x55, 0xdd, 0x55), + makecol(0x55, 0xdd, 0xaa), + makecol(0x55, 0xdd, 0xff), + makecol(0x55, 0xff, 0x00), + makecol(0x55, 0xff, 0x55), + makecol(0x55, 0xff, 0xaa), + makecol(0x55, 0xff, 0xff), + makecol(0x77, 0x00, 0x00), + makecol(0x77, 0x00, 0x55), + makecol(0x77, 0x00, 0xaa), + makecol(0x77, 0x00, 0xff), + makecol(0x77, 0x33, 0x00), + makecol(0x77, 0x33, 0x55), + makecol(0x77, 0x33, 0xaa), + makecol(0x77, 0x33, 0xff), + makecol(0x77, 0x55, 0x00), + makecol(0x77, 0x55, 0x55), + makecol(0x77, 0x55, 0xaa), + makecol(0x77, 0x55, 0xff), + makecol(0x77, 0x77, 0x00), + makecol(0x77, 0x77, 0x55), + makecol(0x77, 0x77, 0xaa), + makecol(0x77, 0x77, 0xff), + makecol(0x77, 0x99, 0x00), + makecol(0x77, 0x99, 0x55), + makecol(0x77, 0x99, 0xaa), + makecol(0x77, 0x99, 0xff), + makecol(0x77, 0xbb, 0x00), + makecol(0x77, 0xbb, 0x55), + makecol(0x77, 0xbb, 0xaa), + makecol(0x77, 0xbb, 0xff), + makecol(0x77, 0xdd, 0x00), + makecol(0x77, 0xdd, 0x55), + makecol(0x77, 0xdd, 0xaa), + makecol(0x77, 0xdd, 0xff), + makecol(0x77, 0xff, 0x00), + makecol(0x77, 0xff, 0x55), + makecol(0x77, 0xff, 0xaa), + makecol(0x77, 0xff, 0xff), + makecol(0x99, 0x00, 0x00), + makecol(0x99, 0x00, 0x55), + makecol(0x99, 0x00, 0xaa), + makecol(0x99, 0x00, 0xff), + makecol(0x99, 0x33, 0x00), + makecol(0x99, 0x33, 0x55), + makecol(0x99, 0x33, 0xaa), + makecol(0x99, 0x33, 0xff), + makecol(0x99, 0x55, 0x00), + makecol(0x99, 0x55, 0x55), + makecol(0x99, 0x55, 0xaa), + makecol(0x99, 0x55, 0xff), + makecol(0x99, 0x77, 0x00), + makecol(0x99, 0x77, 0x55), + makecol(0x99, 0x77, 0xaa), + makecol(0x99, 0x77, 0xff), + makecol(0x99, 0x99, 0x00), + makecol(0x99, 0x99, 0x55), + makecol(0x99, 0x99, 0xaa), + makecol(0x99, 0x99, 0xff), + makecol(0x99, 0xbb, 0x00), + makecol(0x99, 0xbb, 0x55), + makecol(0x99, 0xbb, 0xaa), + makecol(0x99, 0xbb, 0xff), + makecol(0x99, 0xdd, 0x00), + makecol(0x99, 0xdd, 0x55), + makecol(0x99, 0xdd, 0xaa), + makecol(0x99, 0xdd, 0xff), + makecol(0x99, 0xff, 0x00), + makecol(0x99, 0xff, 0x55), + makecol(0x99, 0xff, 0xaa), + makecol(0x99, 0xff, 0xff), + makecol(0xbb, 0x00, 0x00), + makecol(0xbb, 0x00, 0x55), + makecol(0xbb, 0x00, 0xaa), + makecol(0xbb, 0x00, 0xff), + makecol(0xbb, 0x33, 0x00), + makecol(0xbb, 0x33, 0x55), + makecol(0xbb, 0x33, 0xaa), + makecol(0xbb, 0x33, 0xff), + makecol(0xbb, 0x55, 0x00), + makecol(0xbb, 0x55, 0x55), + makecol(0xbb, 0x55, 0xaa), + makecol(0xbb, 0x55, 0xff), + makecol(0xbb, 0x77, 0x00), + makecol(0xbb, 0x77, 0x55), + makecol(0xbb, 0x77, 0xaa), + makecol(0xbb, 0x77, 0xff), + makecol(0xbb, 0x99, 0x00), + makecol(0xbb, 0x99, 0x55), + makecol(0xbb, 0x99, 0xaa), + makecol(0xbb, 0x99, 0xff), + makecol(0xbb, 0xbb, 0x00), + makecol(0xbb, 0xbb, 0x55), + makecol(0xbb, 0xbb, 0xaa), + makecol(0xbb, 0xbb, 0xff), + makecol(0xbb, 0xdd, 0x00), + makecol(0xbb, 0xdd, 0x55), + makecol(0xbb, 0xdd, 0xaa), + makecol(0xbb, 0xdd, 0xff), + makecol(0xbb, 0xff, 0x00), + makecol(0xbb, 0xff, 0x55), + makecol(0xbb, 0xff, 0xaa), + makecol(0xbb, 0xff, 0xff), + makecol(0xdd, 0x00, 0x00), + makecol(0xdd, 0x00, 0x55), + makecol(0xdd, 0x00, 0xaa), + makecol(0xdd, 0x00, 0xff), + makecol(0xdd, 0x33, 0x00), + makecol(0xdd, 0x33, 0x55), + makecol(0xdd, 0x33, 0xaa), + makecol(0xdd, 0x33, 0xff), + makecol(0xdd, 0x55, 0x00), + makecol(0xdd, 0x55, 0x55), + makecol(0xdd, 0x55, 0xaa), + makecol(0xdd, 0x55, 0xff), + makecol(0xdd, 0x77, 0x00), + makecol(0xdd, 0x77, 0x55), + makecol(0xdd, 0x77, 0xaa), + makecol(0xdd, 0x77, 0xff), + makecol(0xdd, 0x99, 0x00), + makecol(0xdd, 0x99, 0x55), + makecol(0xdd, 0x99, 0xaa), + makecol(0xdd, 0x99, 0xff), + makecol(0xdd, 0xbb, 0x00), + makecol(0xdd, 0xbb, 0x55), + makecol(0xdd, 0xbb, 0xaa), + makecol(0xdd, 0xbb, 0xff), + makecol(0xdd, 0xdd, 0x00), + makecol(0xdd, 0xdd, 0x55), + makecol(0xdd, 0xdd, 0xaa), + makecol(0xdd, 0xdd, 0xff), + makecol(0xdd, 0xff, 0x00), + makecol(0xdd, 0xff, 0x55), + makecol(0xdd, 0xff, 0xaa), + makecol(0xdd, 0xff, 0xff), + makecol(0xff, 0x00, 0x00), + makecol(0xff, 0x00, 0x55), + makecol(0xff, 0x00, 0xaa), + makecol(0xff, 0x00, 0xff), + makecol(0xff, 0x33, 0x00), + makecol(0xff, 0x33, 0x55), + makecol(0xff, 0x33, 0xaa), + makecol(0xff, 0x33, 0xff), + makecol(0xff, 0x55, 0x00), + makecol(0xff, 0x55, 0x55), + makecol(0xff, 0x55, 0xaa), + makecol(0xff, 0x55, 0xff), + makecol(0xff, 0x77, 0x00), + makecol(0xff, 0x77, 0x55), + makecol(0xff, 0x77, 0xaa), + makecol(0xff, 0x77, 0xff), + makecol(0xff, 0x99, 0x00), + makecol(0xff, 0x99, 0x55), + makecol(0xff, 0x99, 0xaa), + makecol(0xff, 0x99, 0xff), + makecol(0xff, 0xbb, 0x00), + makecol(0xff, 0xbb, 0x55), + makecol(0xff, 0xbb, 0xaa), + makecol(0xff, 0xbb, 0xff), + makecol(0xff, 0xdd, 0x00), + makecol(0xff, 0xdd, 0x55), + makecol(0xff, 0xdd, 0xaa), + makecol(0xff, 0xdd, 0xff), + makecol(0xff, 0xff, 0x00), + makecol(0xff, 0xff, 0x55), + makecol(0xff, 0xff, 0xaa), + makecol(0xff, 0xff, 0xff), + }, +/* Palette 5: 6x6x6 colour cube */ + { + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x33), + makecol(0x00,0x00,0x66), + makecol(0x00,0x00,0x99), + makecol(0x00,0x00,0xcc), + makecol(0x00,0x00,0xff), + makecol(0x33,0x00,0x00), + makecol(0x33,0x00,0x33), + makecol(0x33,0x00,0x66), + makecol(0x33,0x00,0x99), + makecol(0x33,0x00,0xcc), + makecol(0x33,0x00,0xff), + makecol(0x66,0x00,0x00), + makecol(0x66,0x00,0x33), + makecol(0x66,0x00,0x66), + makecol(0x66,0x00,0x99), + makecol(0x66,0x00,0xcc), + makecol(0x66,0x00,0xff), + makecol(0x99,0x00,0x00), + makecol(0x99,0x00,0x33), + makecol(0x99,0x00,0x66), + makecol(0x99,0x00,0x99), + makecol(0x99,0x00,0xcc), + makecol(0x99,0x00,0xff), + makecol(0xcc,0x00,0x00), + makecol(0xcc,0x00,0x33), + makecol(0xcc,0x00,0x66), + makecol(0xcc,0x00,0x99), + makecol(0xcc,0x00,0xcc), + makecol(0xcc,0x00,0xff), + makecol(0xff,0x00,0x00), + makecol(0xff,0x00,0x33), + makecol(0xff,0x00,0x66), + makecol(0xff,0x00,0x99), + makecol(0xff,0x00,0xcc), + makecol(0xff,0x00,0xff), + makecol(0x00,0x33,0x00), + makecol(0x00,0x33,0x33), + makecol(0x00,0x33,0x66), + makecol(0x00,0x33,0x99), + makecol(0x00,0x33,0xcc), + makecol(0x00,0x33,0xff), + makecol(0x33,0x33,0x00), + makecol(0x33,0x33,0x33), + makecol(0x33,0x33,0x66), + makecol(0x33,0x33,0x99), + makecol(0x33,0x33,0xcc), + makecol(0x33,0x33,0xff), + makecol(0x66,0x33,0x00), + makecol(0x66,0x33,0x33), + makecol(0x66,0x33,0x66), + makecol(0x66,0x33,0x99), + makecol(0x66,0x33,0xcc), + makecol(0x66,0x33,0xff), + makecol(0x99,0x33,0x00), + makecol(0x99,0x33,0x33), + makecol(0x99,0x33,0x66), + makecol(0x99,0x33,0x99), + makecol(0x99,0x33,0xcc), + makecol(0x99,0x33,0xff), + makecol(0xcc,0x33,0x00), + makecol(0xcc,0x33,0x33), + makecol(0xcc,0x33,0x66), + makecol(0xcc,0x33,0x99), + makecol(0xcc,0x33,0xcc), + makecol(0xcc,0x33,0xff), + makecol(0xff,0x33,0x00), + makecol(0xff,0x33,0x33), + makecol(0xff,0x33,0x66), + makecol(0xff,0x33,0x99), + makecol(0xff,0x33,0xcc), + makecol(0xff,0x33,0xff), + makecol(0x00,0x66,0x00), + makecol(0x00,0x66,0x33), + makecol(0x00,0x66,0x66), + makecol(0x00,0x66,0x99), + makecol(0x00,0x66,0xcc), + makecol(0x00,0x66,0xff), + makecol(0x33,0x66,0x00), + makecol(0x33,0x66,0x33), + makecol(0x33,0x66,0x66), + makecol(0x33,0x66,0x99), + makecol(0x33,0x66,0xcc), + makecol(0x33,0x66,0xff), + makecol(0x66,0x66,0x00), + makecol(0x66,0x66,0x33), + makecol(0x66,0x66,0x66), + makecol(0x66,0x66,0x99), + makecol(0x66,0x66,0xcc), + makecol(0x66,0x66,0xff), + makecol(0x99,0x66,0x00), + makecol(0x99,0x66,0x33), + makecol(0x99,0x66,0x66), + makecol(0x99,0x66,0x99), + makecol(0x99,0x66,0xcc), + makecol(0x99,0x66,0xff), + makecol(0xcc,0x66,0x00), + makecol(0xcc,0x66,0x33), + makecol(0xcc,0x66,0x66), + makecol(0xcc,0x66,0x99), + makecol(0xcc,0x66,0xcc), + makecol(0xcc,0x66,0xff), + makecol(0xff,0x66,0x00), + makecol(0xff,0x66,0x33), + makecol(0xff,0x66,0x66), + makecol(0xff,0x66,0x99), + makecol(0xff,0x66,0xcc), + makecol(0xff,0x66,0xff), + makecol(0x00,0x99,0x00), + makecol(0x00,0x99,0x33), + makecol(0x00,0x99,0x66), + makecol(0x00,0x99,0x99), + makecol(0x00,0x99,0xcc), + makecol(0x00,0x99,0xff), + makecol(0x33,0x99,0x00), + makecol(0x33,0x99,0x33), + makecol(0x33,0x99,0x66), + makecol(0x33,0x99,0x99), + makecol(0x33,0x99,0xcc), + makecol(0x33,0x99,0xff), + makecol(0x66,0x99,0x00), + makecol(0x66,0x99,0x33), + makecol(0x66,0x99,0x66), + makecol(0x66,0x99,0x99), + makecol(0x66,0x99,0xcc), + makecol(0x66,0x99,0xff), + makecol(0x99,0x99,0x00), + makecol(0x99,0x99,0x33), + makecol(0x99,0x99,0x66), + makecol(0x99,0x99,0x99), + makecol(0x99,0x99,0xcc), + makecol(0x99,0x99,0xff), + makecol(0xcc,0x99,0x00), + makecol(0xcc,0x99,0x33), + makecol(0xcc,0x99,0x66), + makecol(0xcc,0x99,0x99), + makecol(0xcc,0x99,0xcc), + makecol(0xcc,0x99,0xff), + makecol(0xff,0x99,0x00), + makecol(0xff,0x99,0x33), + makecol(0xff,0x99,0x66), + makecol(0xff,0x99,0x99), + makecol(0xff,0x99,0xcc), + makecol(0xff,0x99,0xff), + makecol(0x00,0xcc,0x00), + makecol(0x00,0xcc,0x33), + makecol(0x00,0xcc,0x66), + makecol(0x00,0xcc,0x99), + makecol(0x00,0xcc,0xcc), + makecol(0x00,0xcc,0xff), + makecol(0x33,0xcc,0x00), + makecol(0x33,0xcc,0x33), + makecol(0x33,0xcc,0x66), + makecol(0x33,0xcc,0x99), + makecol(0x33,0xcc,0xcc), + makecol(0x33,0xcc,0xff), + makecol(0x66,0xcc,0x00), + makecol(0x66,0xcc,0x33), + makecol(0x66,0xcc,0x66), + makecol(0x66,0xcc,0x99), + makecol(0x66,0xcc,0xcc), + makecol(0x66,0xcc,0xff), + makecol(0x99,0xcc,0x00), + makecol(0x99,0xcc,0x33), + makecol(0x99,0xcc,0x66), + makecol(0x99,0xcc,0x99), + makecol(0x99,0xcc,0xcc), + makecol(0x99,0xcc,0xff), + makecol(0xcc,0xcc,0x00), + makecol(0xcc,0xcc,0x33), + makecol(0xcc,0xcc,0x66), + makecol(0xcc,0xcc,0x99), + makecol(0xcc,0xcc,0xcc), + makecol(0xcc,0xcc,0xff), + makecol(0xff,0xcc,0x00), + makecol(0xff,0xcc,0x33), + makecol(0xff,0xcc,0x66), + makecol(0xff,0xcc,0x99), + makecol(0xff,0xcc,0xcc), + makecol(0xff,0xcc,0xff), + makecol(0x00,0xff,0x00), + makecol(0x00,0xff,0x33), + makecol(0x00,0xff,0x66), + makecol(0x00,0xff,0x99), + makecol(0x00,0xff,0xcc), + makecol(0x00,0xff,0xff), + makecol(0x33,0xff,0x00), + makecol(0x33,0xff,0x33), + makecol(0x33,0xff,0x66), + makecol(0x33,0xff,0x99), + makecol(0x33,0xff,0xcc), + makecol(0x33,0xff,0xff), + makecol(0x66,0xff,0x00), + makecol(0x66,0xff,0x33), + makecol(0x66,0xff,0x66), + makecol(0x66,0xff,0x99), + makecol(0x66,0xff,0xcc), + makecol(0x66,0xff,0xff), + makecol(0x99,0xff,0x00), + makecol(0x99,0xff,0x33), + makecol(0x99,0xff,0x66), + makecol(0x99,0xff,0x99), + makecol(0x99,0xff,0xcc), + makecol(0x99,0xff,0xff), + makecol(0xcc,0xff,0x00), + makecol(0xcc,0xff,0x33), + makecol(0xcc,0xff,0x66), + makecol(0xcc,0xff,0x99), + makecol(0xcc,0xff,0xcc), + makecol(0xcc,0xff,0xff), + makecol(0xff,0xff,0x00), + makecol(0xff,0xff,0x33), + makecol(0xff,0xff,0x66), + makecol(0xff,0xff,0x99), + makecol(0xff,0xff,0xcc), + makecol(0xff,0xff,0xff), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + makecol(0x00,0x00,0x00), + }, diff --git a/src/vid_im1024.c b/src/vid_im1024.c new file mode 100644 index 0000000..386059a --- /dev/null +++ b/src/vid_im1024.c @@ -0,0 +1,906 @@ +#include +#include +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_pgc.h" +#include "vid_im1024.h" + +/* This implements just enough of the Vermont Microsystems IM-1024 to + * support the Windows 1.03 driver. Functions are partially implemented + * or hardwired to the behaviour expected by the Windows driver. + * + * One major difference seems to be that in hex mode, coordinates are + * passed as 2-byte integer words rather than 4-byte fixed-point fractions. + * I don't know what triggers this, so for now it's always on. + */ + +extern uint8_t fontdat12x18[256][36]; + +typedef struct im1024_t +{ + pgc_core_t pgc; + unsigned char fontx[256]; + unsigned char fonty[256]; + unsigned char font[256][128]; + + unsigned char *fifo; + unsigned fifo_len, fifo_wrptr, fifo_rdptr; +} im1024_t; + +/* As well as the usual PGC ring buffer at 0xC6000, the IM1024 appears to + * have an alternate method of passing commands. This is enabled by setting + * 0xC6330 to 1, and then: + * + * CX = count to write + * SI -> bytes to write + * + * Set pending bytes to 0 + * Read [C6331]. This gives number of bytes that can be written: + * 0xFF => 0, 0xFE => 1, 0xFD => 2 etc. + * Write that number of bytes to C6000. + * If there are more to come, go back to reading [C6331]. + * As far as I can see, at least one byte is always written; there's no + * provision to pause if the queue is full. + * + * I am implementing this by holding a FIFO of unlimited depth in the + * IM1024 to receive the data. + * + */ + +static void fifo_write(im1024_t *im1024, unsigned char val) +{ +/* PGCLOG(("fifo_write: %02x [rd=%04x wr=%04x]\n", val, + im1024->fifo_rdptr, im1024->fifo_wrptr)); */ + if (((im1024->fifo_wrptr + 1) % im1024->fifo_len) == im1024->fifo_rdptr) + { +/* FIFO is full. Double its size. */ + unsigned char *buf; + + PGCLOG(("fifo_resize: %d to %d\n", + im1024->fifo_len, 2 * im1024->fifo_len)); + + buf = realloc(im1024->fifo, 2 * im1024->fifo_len); + if (!buf) return; +/* Move the [0..wrptr] range to the newly-allocated area [len..len+wrptr] */ + memmove(buf + im1024->fifo_len, buf, im1024->fifo_wrptr); + im1024->fifo = buf; + im1024->fifo_wrptr += im1024->fifo_len; + im1024->fifo_len *= 2; + } +/* Append to the queue */ + im1024->fifo[im1024->fifo_wrptr] = val; + ++im1024->fifo_wrptr; + +/* Wrap if end of buffer reached */ + if (im1024->fifo_wrptr >= im1024->fifo_len) + { + im1024->fifo_wrptr = 0; + } +} + + +static int fifo_read(im1024_t *im1024) +{ + uint8_t result; + + if (im1024->fifo_wrptr == im1024->fifo_rdptr) + { + return -1; /* FIFO empty */ + } + result = im1024->fifo[im1024->fifo_rdptr]; + ++im1024->fifo_rdptr; + if (im1024->fifo_rdptr >= im1024->fifo_len) + { + im1024->fifo_rdptr = 0; + } +/* + PGCLOG(("fifo_read: %02x\n", result)); +*/ + return result; + +} + +/* Where a normal PGC would just read from the ring buffer at 0xC6300, the + * IM-1024 can read either from this or from its internal FIFO. The internal + * FIFO has priority. */ +int im1024_input_byte(pgc_core_t *pgc, uint8_t *result) +{ + im1024_t *im1024 = (im1024_t *)pgc; + + /* If input buffer empty, wait for it to fill */ + while ((im1024->fifo_wrptr == im1024->fifo_rdptr) && + (pgc->mapram[0x300] == pgc->mapram[0x301])) + { + pgc->waiting_input_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + if (im1024->fifo_wrptr == im1024->fifo_rdptr) + { + *result = pgc->mapram[pgc->mapram[0x301]]; + ++pgc->mapram[0x301]; + } + else + { + *result = fifo_read(im1024); + } + return 1; +} + +/* Macros to disable clipping and save clip state */ +#define PUSHCLIP { \ + uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \ + vp_x1 = pgc->vp_x1; \ + vp_y1 = pgc->vp_y1; \ + vp_x2 = pgc->vp_x2; \ + vp_y2 = pgc->vp_y2; \ + pgc->vp_x1 = 0; \ + pgc->vp_y1 = 0; \ + pgc->vp_x2 = pgc->maxw - 1; \ + pgc->vp_y2 = pgc->maxh - 1; \ + +/* And to restore clip state */ +#define POPCLIP \ + pgc->vp_x1 = vp_x1; \ + pgc->vp_y1 = vp_y1; \ + pgc->vp_x2 = vp_x2; \ + pgc->vp_y2 = vp_y2; \ + } + + +/* Override memory read to return FIFO space */ +uint8_t im1024_read(uint32_t addr, void *p) +{ + im1024_t *im1024 = (im1024_t *)p; + + if (addr == 0xC6331 && im1024->pgc.mapram[0x330] == 1) + { + return 0x80; /* Hardcode that there are 128 bytes + * free */ + } + return pgc_read(addr, &im1024->pgc); +} + +/* Override memory write to handle writes to the FIFO */ +void im1024_write(uint32_t addr, uint8_t val, void *p) +{ + im1024_t *im1024 = (im1024_t *)p; + + /* If we are in 'fast' input mode, send all writes to the internal + * FIFO */ + if (addr >= 0xC6000 && addr < 0xC6100 && im1024->pgc.mapram[0x330] == 1) + { + fifo_write(im1024, val); +/* + PGCLOG(("im1024_write(%02x)\n", val)); +*/ + if (im1024->pgc.waiting_input_fifo) + { + im1024->pgc.waiting_input_fifo = 0; + pgc_wake(&im1024->pgc); + } + return; + } + pgc_write(addr, val, &im1024->pgc); +} + + + +/* I don't know what the IMGSIZ command does, only that the Windows driver + * issues it. So just parse and ignore it */ +void hndl_imgsiz(pgc_core_t *pgc) +{ + int16_t w,h; + uint8_t a,b; +// im1024_t *im1024 = (im1024_t *)pgc; + + if (!pgc_param_word(pgc, &w)) return; + if (!pgc_param_word(pgc, &h)) return; + if (!pgc_param_byte(pgc, &a)) return; + if (!pgc_param_byte(pgc, &b)) return; + + PGCLOG(("IMGSIZ %d,%d,%d,%d\n", w,h,a,b)); +} + + +/* I don't know what the IPREC command does, only that the Windows driver + * issues it. So just parse and ignore it */ +void hndl_iprec(pgc_core_t *pgc) +{ + uint8_t param; +// im1024_t *im1024 = (im1024_t *)pgc; + + if (!pgc_param_byte(pgc, ¶m)) return; + + PGCLOG(("IPREC %d\n", param)); +} + +/* I think PAN controls which part of the 1024x1024 framebuffer is displayed + * in the 1024x800 visible screen. */ +void hndl_pan(pgc_core_t *pgc) +{ + int16_t x,y; + + if (!pgc_param_word(pgc, &x)) return; + if (!pgc_param_word(pgc, &y)) return; + + PGCLOG(("PAN %d,%d\n", x, y)); + + pgc->pan_x = x; + pgc->pan_y = y; +} + +/* PLINE draws a non-filled polyline at a fixed position */ +void hndl_pline(pgc_core_t *pgc) +{ + int16_t x[257]; + int16_t y[257]; + uint8_t count; + unsigned n; + uint16_t linemask = pgc->line_pattern; + + if (!pgc_param_byte(pgc, &count)) return; + + PGCLOG(("PLINE (%d) ", count)); + for (n = 0; n < count; n++) + { + if (!pgc_param_word(pgc, &x[n])) return; + if (!pgc_param_word(pgc, &y[n])) return; + PGCLOG((" (%d,%d)\n", x[n], y[n])); + } + for (n = 1; n < count; n++) + { + linemask = pgc_draw_line(pgc, x[n - 1] << 16, y[n - 1] << 16, + x[n] << 16, y[n] << 16, linemask); + } +} + + +/* Blit a single row of pixels from one location to another. To avoid + * difficulties if the two overlap, read both rows into memory, process them + * there, and write the result back. */ +void blkmov_row(pgc_core_t *pgc, int16_t x0, int16_t x1, int16_t x2, + int16_t sy, int16_t ty) +{ + int16_t x; + uint8_t src[1024]; + uint8_t dst[1024]; + + for (x = x0; x <= x1; x++) + { + src[x - x0] = pgc_read_pixel(pgc, x, sy); + dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty); + } + for (x = x0; x <= x1; x++) + { + switch (pgc->draw_mode) + { + default: + case 0: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); break; + case 1: pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF); break; + case 2: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); break; + case 3: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); break; + } + } + +} + + +/* BLKMOV blits a rectangular area from one location to another, with no + * clipping. */ +void hndl_blkmov(pgc_core_t *pgc) +{ + int16_t x0,y0; + int16_t x1,y1; + int16_t x2,y2; + int16_t y; +// im1024_t *im1024 = (im1024_t *)pgc; + + if (!pgc_param_word(pgc, &x0)) return; + if (!pgc_param_word(pgc, &y0)) return; + if (!pgc_param_word(pgc, &x1)) return; + if (!pgc_param_word(pgc, &y1)) return; + if (!pgc_param_word(pgc, &x2)) return; + if (!pgc_param_word(pgc, &y2)) return; + + PGCLOG(("BLKMOV %d,%d,%d,%d,%d,%d\n", x0,y0,x1,y1,x2,y2)); + + /* Disable clipping */ + PUSHCLIP + + /* Either go down from the top, or up from the bottom, depending + * whether areas might overlap */ + if (y2 <= y0) + { + for (y = y0; y <= y1; y++) + { + blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); + } + } + else + { + for (y = y1; y >= y0; y--) + { + blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); + } + } + /* Restore clipping */ + POPCLIP +} + + +/* This overrides the PGC ELIPSE command to parse its parameters as words + * rather than coordinates */ +static void hndl_ellipse(pgc_core_t *pgc) +{ + int16_t x, y; + + if (!pgc_param_word(pgc, &x)) return; + if (!pgc_param_word(pgc, &y)) return; + + PGCLOG(("ELLIPSE %d,%d @ %d,%d\n", x,y, + pgc->x >> 16, pgc->y >> 16)); + pgc_draw_ellipse(pgc, x << 16, y << 16); +} + + + +/* This overrides the PGC MOVE command to parse its parameters as words + * rather than coordinates */ +static void hndl_move(pgc_core_t *pgc) +{ + int16_t x, y; + + if (!pgc_param_word(pgc, &x)) return; + if (!pgc_param_word(pgc, &y)) return; + + pgc->x = x << 16; + pgc->y = y << 16; + PGCLOG(("MOVE %d,%d\n", x,y)); +} + +/* This overrides the PGC DRAW command to parse its parameters as words + * rather than coordinates */ +static void hndl_draw(pgc_core_t *pgc) +{ + int16_t x, y; + + if (!pgc_param_word(pgc, &x)) return; + if (!pgc_param_word(pgc, &y)) return; + + PGCLOG(("DRAW %d,%d to %d,%d\n", + pgc->x >> 16, pgc->y >> 16, x, y)); + pgc_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern); + pgc->x = x << 16; + pgc->y = y << 16; +} + + + + +/* This overrides the PGC POLY command to parse its parameters as words + * rather than coordinates */ +static void hndl_poly(pgc_core_t *pgc) +{ + int32_t *x, *y; + int32_t n; + int16_t xw, yw, mask; + unsigned realcount = 0; + int parsing = 1; + int as = 256; + + x = malloc(as * sizeof(int32_t)); + y = malloc(as * sizeof(int32_t)); + + if (!x || !y) + { + PGCLOG(("hndl_poly: malloc failed\n")); + return; + } + while (parsing) + { + uint8_t count; + if (!pgc_param_byte(pgc, &count)) return; + + if (count + realcount >= as) + { + int32_t *nx, *ny; + + nx = realloc(x, 2 * as * sizeof(int32_t)); + ny = realloc(y, 2 * as * sizeof(int32_t)); + if (!x || !y) + { + PGCLOG(("hndl_poly: realloc failed\n")); + break; + } + x = nx; + y = ny; + as *= 2; + } + + for (n = 0; n < count; n++) + { + if (!pgc_param_word(pgc, &xw)) return; + if (!pgc_param_word(pgc, &yw)) return; + + /* Skip degenerate line segments */ + if (realcount > 0 && + (xw << 16) == x[realcount - 1] && + (yw << 16) == y[realcount - 1]) + { + continue; + } + x[realcount] = xw << 16; + y[realcount] = yw << 16; + ++realcount; + } +/* If we're in a command list, peek ahead to see if the next command is + * also POLY. If so, that's a continuation of this polygon! */ + parsing = 0; + if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr && + pgc->clcur->list[pgc->clcur->rdptr] == 0x30) + { + PGCLOG(("hndl_poly: POLY continues!\n")); + parsing = 1; + /* Swallow the POLY */ + ++pgc->clcur->rdptr; + } + + } + + PGCLOG(("POLY (%d) fill_mode=%d\n", realcount, pgc->fill_mode)); + for (n = 0; n < realcount; n++) + { + PGCLOG((" (%d,%d)\n", x[n] >> 16, y[n] >> 16)); + } + if (pgc->fill_mode) + { + pgc_fill_polygon(pgc, realcount, x, y); + } + /* Now draw borders */ + mask = pgc->line_pattern; + for (n = 1; n < realcount; n++) + { + mask = pgc_draw_line(pgc, x[n - 1], y[n - 1], x[n], y[n], mask); + } + pgc_draw_line(pgc, x[realcount - 1], y[realcount - 1], x[0], y[0], mask); + free(y); + free(x); +} + + +static int parse_poly(pgc_core_t *pgc, pgc_commandlist_t *cl, int c) +{ + uint8_t count; + + PGCLOG(("parse_poly\n")); + if (!pgc_param_byte(pgc, &count)) return 0; + + PGCLOG(("parse_poly: count=%02x\n", count)); + if (!pgc_commandlist_append(cl, count)) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + PGCLOG(("parse_poly: parse %d words\n", 2 * count)); + return pgc_parse_words(pgc, cl, count * 2); +} + + + +/* This overrides the PGC RECT command to parse its parameters as words + * rather than coordinates */ +static void hndl_rect(pgc_core_t *pgc) +{ + int16_t x0, y0, x1, y1, p, q; + + x0 = pgc->x >> 16; + y0 = pgc->y >> 16; + + if (!pgc_param_word(pgc, &x1)) return; + if (!pgc_param_word(pgc, &y1)) return; + + /* Convert to raster coords */ + pgc_sto_raster(pgc, &x0, &y0); + pgc_sto_raster(pgc, &x1, &y1); + + if (x0 > x1) { p = x0; x0 = x1; x1 = p; } + if (y0 > y1) { q = y0; y0 = y1; y1 = q; } + + PGCLOG(("RECT (%d,%d) -> (%d,%d)\n", x0, y0, x1, y1)); + + if (pgc->fill_mode) + { + for (p = y0; p <= y1; p++) + { + pgc_fill_line_r(pgc, x0, x1, p); + } + } + else /* Outline: 4 lines */ + { + p = pgc->line_pattern; + p = pgc_draw_line_r(pgc, x0, y0, x1, y0, p); + p = pgc_draw_line_r(pgc, x1, y0, x1, y1, p); + p = pgc_draw_line_r(pgc, x1, y1, x0, y1, p); + p = pgc_draw_line_r(pgc, x0, y1, x0, y0, p); + } +} + + +/* TODO: Text drawing should probably be implemented in vid_pgc.c rather + * than vid_im1024.c */ +static void hndl_tdefin(pgc_core_t *pgc) +{ + unsigned char ch, bt; + unsigned char rows, cols; + unsigned len, n; +// unsigned x = 0; + im1024_t * im1024 = (im1024_t *)pgc; + + if (!pgc_param_byte(pgc, &ch)) return; + if (!pgc_param_byte(pgc, &cols)) return; + if (!pgc_param_byte(pgc, &rows)) return; + + PGCLOG(("TDEFIN (%d,%d,%d) 0x%02x 0x%02x\n", ch, rows, cols, + pgc->mapram[0x300], pgc->mapram[0x301])); + + len = ((cols + 7) / 8) * rows; + for (n = 0; n < len; n++) + { +// char buf[10]; +// unsigned char mask; + + if (!pgc_param_byte(pgc, &bt)) return; + +// buf[0] = 0; +// for (mask = 0x80; mask != 0; mask >>= 1) +// { +// if (bt & mask) strcat(buf, "#"); +// else strcat(buf, "-"); +// ++x; +// if (x == cols) { strcat(buf, "\n"); x = 0; } +// } +// PGCLOG((buf)); + + if (n < sizeof(im1024->font[ch])) im1024->font[ch][n] = bt; + } + im1024->fontx[ch] = cols; + im1024->fonty[ch] = rows; +} + +static void hndl_tsize(pgc_core_t *pgc) +{ + int16_t size; + + if (!pgc_param_word(pgc, &size)) return; + PGCLOG(("TSIZE(%d)\n", size)); + + pgc->tsize = size << 16; +} + + + +static void hndl_twrite(pgc_core_t *pgc) +{ + unsigned char count; + unsigned char mask; + unsigned char *row; + int x, y, wb, n; + im1024_t * im1024 = (im1024_t *)pgc; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; + unsigned char buf[256]; +/* unsigned char rbuf[256];*/ + + if (!pgc_param_byte(pgc, &count)) return; + + for (n = 0; n < count; n++) + { + if (!pgc_param_byte(pgc, &buf[n])) return; + } + buf[count] = 0; +/* for (n = 0; n <= count; n++) + { + if (isprint(buf[n]) || 0 == buf[n]) + { + rbuf[n] = buf[n]; + } + else rbuf[n] = '?'; + }*/ + pgc_sto_raster(pgc, &x0, &y0); + PGCLOG(("TWRITE (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0)); + + for (n = 0; n < count; n++) + { + wb = (im1024->fontx[buf[n]] + 7) / 8; + PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", + buf[n], im1024->fontx[buf[n]], + im1024->fonty[buf[n]], wb)); + for (y = 0; y < im1024->fonty[buf[n]]; y++) + { + mask = 0x80; + row = &im1024->font[buf[n]][y * wb]; + for (x = 0; x < im1024->fontx[buf[n]]; x++) + { +/* rbuf[x] = (row[0] & mask) ? '#' : '-';*/ + if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y); + mask = mask >> 1; + if (mask == 0) { mask = 0x80; ++row; } + } +/* rbuf[x++] = '\n'; + rbuf[x++] = 0;*/ +// PGCLOG((rbuf); + } + x0 += im1024->fontx[buf[n]]; + } +} + + + +static void hndl_txt88(pgc_core_t *pgc) +{ + unsigned char count; + unsigned char mask; + unsigned char *row; + int x, y, /*wb, */n; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; + unsigned char buf[256]; +/* unsigned char rbuf[256];*/ + + if (!pgc_param_byte(pgc, &count)) return; + + for (n = 0; n < count; n++) + { + if (!pgc_param_byte(pgc, &buf[n])) return; + } + buf[count] = 0; +/* for (n = 0; n <= count; n++) + { + if (isprint(buf[n]) || 0 == buf[n]) + { + rbuf[n] = buf[n]; + } + else rbuf[n] = '?'; + }*/ + pgc_sto_raster(pgc, &x0, &y0); + PGCLOG(("TXT88 (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0)); + + for (n = 0; n < count; n++) + { +/* wb = 2;*/ + PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", buf[n], 12, 18, wb)); + for (y = 0; y < 18; y++) + { + mask = 0x80; + row = &fontdat12x18[buf[n]][y * 2]; + for (x = 0; x < 12; x++) + { +/* rbuf[x] = (row[0] & mask) ? '#' : '-';*/ + if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y); + mask = mask >> 1; + if (mask == 0) { mask = 0x80; ++row; } + } +/* rbuf[x++] = '\n'; + rbuf[x++] = 0;*/ +// PGCLOG((rbuf); + } + x0 += 12; + } +} + + + + +static void hndl_imagew(pgc_core_t *pgc) +{ + int16_t row1, col1, col2; + uint8_t v1, v2; + int16_t vp_x1, vp_y1, vp_x2, vp_y2; + + if (!pgc_param_word(pgc, &row1)) return; + if (!pgc_param_word(pgc, &col1)) return; + if (!pgc_param_word(pgc, &col2)) return; + + /* IMAGEW already uses raster coordinates so there is no need to + * convert it */ + PGCLOG(("IMAGEW (row=%d,col1=%d,col2=%d)\n", row1, col1, col2)); + + vp_x1 = pgc->vp_x1; + vp_y1 = pgc->vp_y1; + vp_x2 = pgc->vp_x2; + vp_y2 = pgc->vp_y2; + /* Disable clipping */ + pgc->vp_x1 = 0; + pgc->vp_y1 = 0; + pgc->vp_x2 = pgc->maxw - 1; + pgc->vp_y2 = pgc->maxh - 1; + + /* In ASCII mode, what is written is a stream of bytes */ + if (pgc->ascii_mode) + { + while (col1 <= col2) + { + if (!pgc_param_byte(pgc, &v1)) return; + pgc_write_pixel(pgc, col1, row1, v1); + ++col1; + } + return; + } + else /* In hex mode, it's RLE compressed */ + { + while (col1 <= col2) + { + if (!pgc_param_byte(pgc, &v1)) return; + + if (v1 & 0x80) /* Literal run */ + { + v1 -= 0x7F; + while (col1 <= col2 && v1 != 0) + { + if (!pgc_param_byte(pgc, &v2)) return; + pgc_write_pixel(pgc, col1, row1, v2); + ++col1; + --v1; + } + } + else /* Repeated run */ + { + if (!pgc_param_byte(pgc, &v2)) return; + + ++v1; + while (col1 <= col2 && v1 != 0) + { + pgc_write_pixel(pgc, col1, row1, v2); + ++col1; + --v1; + } + } + } + } + /* Restore clipping */ + pgc->vp_x1 = vp_x1; + pgc->vp_y1 = vp_y1; + pgc->vp_x2 = vp_x2; + pgc->vp_y2 = vp_y2; +} + +/* I have called this command DOT - I don't know its proper name. Draws a + * single pixel at the current location */ +static void hndl_dot(pgc_core_t *pgc) +{ + int16_t x = pgc->x >> 16, y = pgc->y >> 16; + + pgc_sto_raster(pgc, &x, &y); + + PGCLOG(("Dot @ %d,%d ink=%d mode=%d\n", x, y, pgc->colour, pgc->draw_mode)); + pgc_plot(pgc, x, y); +} + +/* This command (which I have called IMAGEX, since I don't know its real + * name) is a screen-to-memory blit. It reads a rectangle of bytes, rather + * than the single row read by IMAGER, and does not attempt to compress + * the result */ +static void hndl_imagex(pgc_core_t *pgc) +{ + int16_t x0, x1, y0, y1; + int16_t p,q; + + if (!pgc_param_word(pgc, &x0)) return; + if (!pgc_param_word(pgc, &y0)) return; + if (!pgc_param_word(pgc, &x1)) return; + if (!pgc_param_word(pgc, &y1)) return; + + /* IMAGEX already uses raster coordinates so don't convert */ + PGCLOG(("IMAGEX (%d,%d,%d,%d)\n", x0,y0,x1,y1)); + + for (p = y0; p <= y1; p++) + { + for (q = x0; q <= x1; q++) + { + if (!pgc_result_byte(pgc, pgc_read_pixel(pgc, q, p))) + return; + } + } +} + +/* Commands implemented by the IM-1024. + * + * TODO: A lot of commands need commandlist parsers. + * TODO: The IM-1024 has a lot more commands that are not included here + * (BLINK, BUTRD, COPROC, RBAND etc) because the Windows 1.03 driver + * does not use them. + */ +static const pgc_command_t im1024_commands[] = +{ + { "BLKMOV", 0xDF, hndl_blkmov, pgc_parse_words, 6 }, + { "DRAW", 0x28, hndl_draw, pgc_parse_words, 2 }, + { "D", 0x28, hndl_draw, pgc_parse_words, 2 }, + { "DOT", 0x08, hndl_dot }, + { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2 }, + { "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 }, + { "IMAGEW", 0xD9, hndl_imagew }, + { "IW", 0xD9, hndl_imagew }, + { "IMAGEX", 0xDA, hndl_imagex }, + { "TXT88", 0x88, hndl_txt88 }, + { "TWRITE", 0x8B, hndl_twrite }, + { "TDEFIN", 0x84, hndl_tdefin }, + { "TD", 0x84, hndl_tdefin }, + { "TSIZE", 0x81, hndl_tsize }, + { "TS", 0x81, hndl_tsize }, + { "IPREC", 0xE4, hndl_iprec }, + { "IMGSIZ", 0x4E, hndl_imgsiz }, + { "LUT8", 0xE6, pgc_hndl_lut8 }, + { "L8", 0xE6, pgc_hndl_lut8 }, + { "LUT8RD", 0x53, pgc_hndl_lut8rd }, + { "L8RD", 0x53, pgc_hndl_lut8rd }, + { "PAN", 0xB7, hndl_pan }, + { "POLY", 0x30, hndl_poly, parse_poly }, + { "P", 0x30, hndl_poly, parse_poly }, + { "PLINE", 0x36, hndl_pline }, + { "PL", 0x37, hndl_pline }, + { "MOVE", 0x10, hndl_move, pgc_parse_words, 2 }, + { "M", 0x10, hndl_move, pgc_parse_words, 2 }, + { "RECT", 0x34, hndl_rect }, + { "R", 0x34, hndl_rect }, + { "******", 0x00, NULL } +}; + + +void *im1024_init() +{ + im1024_t *im1024 = malloc(sizeof(im1024_t)); + memset(im1024, 0, sizeof(im1024_t)); + + im1024->fifo = malloc(4096); + im1024->fifo_len = 4096; + im1024->fifo_wrptr = 0; + im1024->fifo_rdptr = 0; + + /* 1024x1024 framebuffer with 1024x800 visible + Pixel clock is a guess */ + pgc_core_init(&im1024->pgc, 1024, 1024, 1024, 800, im1024_input_byte, 65000000.0); + + mem_mapping_set_handler(&im1024->pgc.mapping, + im1024_read, NULL, NULL, + im1024_write, NULL, NULL); + + im1024->pgc.pgc_commands = im1024_commands; + return im1024; +} + +void im1024_close(void *p) +{ + im1024_t *im1024 = (im1024_t *)p; + + pgc_close(&im1024->pgc); +} + +void im1024_speed_changed(void *p) +{ + im1024_t *im1024 = (im1024_t *)p; + + pgc_speed_changed(&im1024->pgc); +} + +device_t im1024_device = +{ + "Image Manager 1024", + 0, + im1024_init, + im1024_close, + NULL, + im1024_speed_changed, + NULL, + NULL, + NULL +}; diff --git a/src/vid_im1024.h b/src/vid_im1024.h new file mode 100644 index 0000000..145401e --- /dev/null +++ b/src/vid_im1024.h @@ -0,0 +1 @@ +extern device_t im1024_device; diff --git a/src/vid_pgc.c b/src/vid_pgc.c new file mode 100644 index 0000000..ba9845b --- /dev/null +++ b/src/vid_pgc.c @@ -0,0 +1,2481 @@ +/*PGC emulation*/ +#include +#include +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "timer.h" +#include "thread.h" +#include "video.h" +#include "vid_pgc.h" +#include + +/* This implements just enough of the Professional Graphics Controller to + * act as a basis for the Vermont Microsystems IM-1024. + * + * PGC features implemented include: + * > The CGA-compatible display modes + * > Switching to and from native mode + * > Communicating with the host PC + * + * Numerous features are implemented partially or not at all, such as: + * > 2D drawing + * > 3D drawing + * > Command lists + * Some of these are marked TODO. + * + * The PGC has two display modes: CGA (in which it appears in the normal CGA + * memory and I/O ranges) and native (in which all functions are accessed + * through reads and writes to 1k of memory at 0xC6000). The PGC's 8088 + * processor monitors this buffer and executes instructions left there + * for it. We simulate this behaviour with a separate thread. + */ + +#define PGC_CGA_WIDTH 640 +#define PGC_CGA_HEIGHT 400 + +static int pgc_parse_command(pgc_core_t *pgc, const pgc_command_t **pcmd); +int pgc_clist_byte(pgc_core_t *pgc, uint8_t *val); + + + + +static const char *pgc_err_msgs[] = +{ + "Range \r", + "Integer \r", + "Memory \r", + "Overflow\r", + "Digit \r", + "Opcode \r", + "Running \r", + "Stack \r", + "Too long\r", + "Area \r", + "Missing \r" +}; + +#define HWORD(u) ((u) >> 16) +#define LWORD(u) ((u) & 0xFFFF) + + +/* Initial palettes */ +uint32_t init_palette[6][256] = +{ +#include "pgc_palettes.h" +}; + + + +/* When idle, the PGC drawing thread sleeps. pgc_wake() awakens it - but + * not immediately. Like the Voodoo, it has a short delay so that writes + * can be batched */ +#define WAKE_DELAY (TIMER_USEC * 500) +void pgc_wake(pgc_core_t *pgc) +{ + if (!pgc->wake_timer) + { + timer_process(); + pgc->wake_timer = WAKE_DELAY; + timer_update_outstanding(); + } +} + + +/* When the wake timer expires, that's when the drawing thread is actually + * woken */ +static void pgc_wake_timer(void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + pgc->wake_timer = 0; + PGCLOG(("pgc: Waking up\n")); + thread_set_event(pgc->pgc_wake_thread); +} + +/* This is called by the drawing thread when it's waiting for the host + * to put more input in its input FIFO, or drain output from its output + * FIFO. */ +void pgc_sleep(pgc_core_t *pgc) +{ + + PGCLOG(("pgc: Sleeping on %d %d %d 0x%02x 0x%02x\n", + pgc->waiting_input_fifo, + pgc->waiting_output_fifo, + pgc->waiting_error_fifo, + pgc->mapram[0x300], pgc->mapram[0x301])); + /* Race condition: If host wrote to the PGC during the pclog() that + * won't be noticed */ + if (pgc->waiting_input_fifo && pgc->mapram[0x300] != pgc->mapram[0x301]) + { + pgc->waiting_input_fifo = 0; + return; + } + /* Same if they read */ + if (pgc->waiting_output_fifo && pgc->mapram[0x302] != (uint8_t)(pgc->mapram[0x303] - 1)) + { + pgc->waiting_output_fifo = 0; + return; + } + thread_wait_event(pgc->pgc_wake_thread, -1); + thread_reset_event(pgc->pgc_wake_thread); + +} + +/* Switch between CGA mode (DISPLAY 1) and native mode (DISPLAY 0) */ +void pgc_setdisplay(pgc_core_t *pgc, int cga) +{ + PGCLOG(("pgc_setdisplay(%d): cga_selected=%d cga_enabled=%d\n", + cga, pgc->cga_selected, pgc->cga_enabled)); + if (pgc->cga_selected != (pgc->cga_enabled && cga)) + { + pgc->cga_selected = (pgc->cga_enabled && cga); + + if (pgc->cga_selected) + { + mem_mapping_enable(&pgc->cga_mapping); + pgc->screenw = PGC_CGA_WIDTH; + pgc->screenh = PGC_CGA_HEIGHT; + } + else + { + mem_mapping_disable(&pgc->cga_mapping); + pgc->screenw = pgc->visw; + pgc->screenh = pgc->vish; + } + pgc_recalctimings(pgc); + } +} + + + + + +/* Convert coordinates based on the current window / viewport to raster + * coordinates. */ +void pgc_dto_raster(pgc_core_t *pgc, double *x, double *y) +{ +/* double x0 = *x, y0 = *y; */ + + *x += (pgc->vp_x1 - pgc->win_x1); + *y += (pgc->vp_y1 - pgc->win_y1); + +/* PGCLOG(("Coords to raster: (%f, %f) -> (%f, %f)\n", x0, y0, *x, *y)); */ +} + + +/* Overloads that take ints */ +void pgc_sto_raster(pgc_core_t *pgc, int16_t *x, int16_t *y) +{ + double xd = *x, yd = *y; + + pgc_dto_raster(pgc, &xd, &yd); + *x = (int16_t)xd; + *y = (int16_t)yd; +} + +void pgc_ito_raster(pgc_core_t *pgc, int32_t *x, int32_t *y) +{ + double xd = *x, yd = *y; + + pgc_dto_raster(pgc, &xd, &yd); + *x = (int32_t)xd; + *y = (int32_t)yd; +} + + +/* Add a byte to a command list. We allow command lists to be + * arbitrarily large */ +int pgc_commandlist_append(pgc_commandlist_t *list, uint8_t v) +{ + if (list->listmax == 0 || list->list == NULL) + { + list->list = malloc(4096); + if (!list->list) + { + PGCLOG(("Out of memory initialising command list\n")); + return 0; + } + list->listmax = 4096; + } + while (list->wrptr >= list->listmax) + { + uint8_t *buf = realloc(list->list, 2 * list->listmax); + if (!buf) + { + PGCLOG(("Out of memory growing command list\n")); + return 0; + } + list->list = buf; + list->listmax *= 2; + } + list->list[list->wrptr++] = v; + return 1; +} + +/* Beginning of a command list. Parse commands up to the next CLEND, + * storing them (in hex form) in the named command list. */ +static void hndl_clbeg(pgc_core_t *pgc) +{ + uint8_t param; + pgc_commandlist_t cl; + const pgc_command_t *cmd; + + memset(&cl, 0, sizeof(cl)); + if (!pgc_param_byte(pgc, ¶m)) return; + + PGCLOG(("CLBEG(%d)\n", param)); + while (1) + { + if (!pgc_parse_command(pgc, &cmd)) + { + /* PGC has been reset */ + return; + } + if (!cmd) + { + pgc_error(pgc, PGC_ERROR_OPCODE); + return; + } + else if (pgc->hex_command == 0x71) /* CLEND */ + { + pgc->clist[param] = cl; + return; + } + else + { + if (!pgc_commandlist_append(&cl, pgc->hex_command)) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return; + } + if (cmd->parser) + { + if (!(*cmd->parser)(pgc, &cl, cmd->p)) + { + return; + } + } + } + } +} + +static void hndl_clend(pgc_core_t *pgc) +{ + /* Shouldn't happen outside a CLBEG */ +} + +/* Execute a command list. If one was already executing, remember it so + * we can return to it afterwards. */ +static void hndl_clrun(pgc_core_t *pgc) +{ + uint8_t param; + pgc_commandlist_t *clprev = pgc->clcur; + + if (!pgc_param_byte(pgc, ¶m)) return; + + pgc->clcur = &pgc->clist[param]; + pgc->clcur->rdptr = 0; + pgc->clcur->repeat = 1; + pgc->clcur->chain = clprev; +} + +/* Execute a command list multiple times. */ +static void hndl_cloop(pgc_core_t *pgc) +{ + uint8_t param; + int16_t repeat; + pgc_commandlist_t *clprev = pgc->clcur; + + if (!pgc_param_byte(pgc, ¶m)) return; + if (!pgc_param_word(pgc, &repeat)) return; + + pgc->clcur = &pgc->clist[param]; + pgc->clcur->rdptr = 0; + pgc->clcur->repeat = repeat; + pgc->clcur->chain = clprev; +} + + +/* Read back a command list */ +static void hndl_clread(pgc_core_t *pgc) +{ + uint8_t param; + int n; + + if (!pgc_param_byte(pgc, ¶m)) return; + + for (n = 0; n < pgc->clist[param].wrptr; n++) + { + if (!pgc_result_byte(pgc, pgc->clist[param].list[n])) + return; + } +} + + +/* Delete a command list */ +static void hndl_cldel(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc_param_byte(pgc, ¶m)) return; + memset(&pgc->clist[param], 0, sizeof(pgc_commandlist_t)); +} + + + +/* Clear the screen to a specified colour */ +static void hndl_clears(pgc_core_t *pgc) +{ + uint8_t param; + int y; + + if (!pgc_param_byte(pgc, ¶m)) return; + + for (y = 0; y < pgc->screenh; y++) + memset(pgc->vram + y * pgc->maxw, param, pgc->screenw); +} + +/* Select drawing colour */ +static void hndl_color(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc_param_byte(pgc, ¶m)) return; + + pgc->colour = param; + PGCLOG(("COLOR(%d)\n", param)); +} + + +/* Set drawing mode. + * + * 0 => Draw + * 1 => Invert + * 2 => XOR (IM-1024) + * 3 => AND (IM-1024) + * + */ +static void hndl_linfun(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc_param_byte(pgc, ¶m)) return; + + /* TODO: Not range-checked. Strictly speaking we should limit to 0-1 + * for the PGC and 0-3 for the IM-1024. */ + pgc->draw_mode = param; + PGCLOG(("LINFUN(%d)\n", param)); +} + +/* Set the line drawing pattern */ +static void hndl_linpat(pgc_core_t *pgc) +{ + uint16_t param; + + if (!pgc_param_word(pgc, (int16_t *)¶m)) return; + + pgc->line_pattern = param; + PGCLOG(("LINPAT(0x%04x)\n", param)); +} + +/* Set the polygon fill mode (0=hollow, 1=filled, 2=fast fill) */ +static void hndl_prmfil(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc_param_byte(pgc, ¶m)) return; + + PGCLOG(("PRMFIL(%d)\n", param)); + if (param < 3) + { + pgc->fill_mode = param; + } + else + { + pgc_error(pgc, PGC_ERROR_RANGE); + } +} + + +/* Set the 2D drawing position */ +static void hndl_move(pgc_core_t *pgc) +{ + int32_t x = 0, y = 0; + + if (!pgc_param_coord(pgc, &x)) return; + if (!pgc_param_coord(pgc, &y)) return; + + pgc->x = x; + pgc->y = y; + PGCLOG(("MOVE %x.%04x,%x.%04x\n", HWORD(x), LWORD(x), HWORD(y), LWORD(y))); +} + +/* Set the 3D drawing position */ +static void hndl_move3(pgc_core_t *pgc) +{ + int32_t x = 0, y = 0, z = 0; + + if (!pgc_param_coord(pgc, &x)) return; + if (!pgc_param_coord(pgc, &y)) return; + if (!pgc_param_coord(pgc, &z)) return; + + pgc->x = x; + pgc->y = y; + pgc->z = z; +} + +/* Relative move (2D) */ +static void hndl_mover(pgc_core_t *pgc) +{ + int32_t x = 0, y = 0; + + if (!pgc_param_coord(pgc, &x)) return; + if (!pgc_param_coord(pgc, &y)) return; + + pgc->x += x; + pgc->y += y; +} + +/* Relative move (3D) */ +static void hndl_mover3(pgc_core_t *pgc) +{ + int32_t x = 0, y = 0, z = 0; + + if (!pgc_param_coord(pgc, &x)) return; + if (!pgc_param_coord(pgc, &y)) return; + if (!pgc_param_coord(pgc, &z)) return; + + pgc->x += x; + pgc->y += y; + pgc->z += z; +} + + + +/* Draw a line (using PGC fixed-point coordinates) */ +uint16_t pgc_draw_line(pgc_core_t *pgc, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint16_t linemask) +{ + + PGCLOG(("pgc_draw_line: (%d,%d) to (%d,%d)\n", x0 >> 16, y0 >> 16, + x1 >> 16, y1 >> 16)); + /* Convert from PGC fixed-point to device coordinates */ + x0 >>= 16; + x1 >>= 16; + y0 >>= 16; + y1 >>= 16; + + pgc_ito_raster(pgc, &x0, &y0); + pgc_ito_raster(pgc, &x1, &y1); + + return pgc_draw_line_r(pgc, x0, y0, x1, y1, linemask); +} + +/* Draw a line (using raster coordinates) + Bresenham's Algorithm from + * + * The line pattern mask to use is passed in. The return value is the line + * pattern mask rotated by the number of points drawn. + */ +uint16_t pgc_draw_line_r(pgc_core_t *pgc, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint16_t linemask) +{ + int32_t dx, dy, sx, sy, err, e2; + + dx = abs(x1 - x0); + dy = abs(y1 - y0); + sx = (x0 < x1) ? 1 : -1; + sy = (y0 < y1) ? 1 : -1; + err = (dx > dy ? dx : -dy) / 2; + + for(;;) + { + if (linemask & 0x8000) + { + pgc_plot(pgc, x0, y0); + linemask = (linemask << 1) | 1; + } + else + { + linemask = (linemask << 1); + } + if (x0 == x1 && y0 == y1) break; + e2 = err; + if (e2 > -dx) { err -= dy; x0 += sx; } + if (e2 < dy) { err += dx; y0 += sy; } + } + return linemask; +} + +/* Draw a horizontal line in the current fill pattern + * (using raster coordinates) */ +void pgc_fill_line_r(pgc_core_t *pgc, int32_t x0, int32_t x1, int32_t y0) +{ + int32_t x; + int32_t mask = 0x8000 >> (x0 & 0x0F); + + if (x0 > x1) { x = x1; x1 = x0; x0 = x; } + + for (x = x0; x <= x1; x++) + { + if (pgc->fill_pattern[y0 & 0x0F] & mask) + pgc_plot(pgc, x, y0); + mask = mask >> 1; + if (mask == 0) mask = 0x8000; + } +} + +/* For sorting polygon nodes */ +static int compare_double(const void *a, const void *b) +{ + const double *da = (const double *)a; + const double *db = (const double *)b; + + if (*da > *db) return 1; + if (*da < *db) return -1; + return 0; +} + +/* Draw a filled polygon (using PGC fixed-point coordinates) */ +void pgc_fill_polygon(pgc_core_t *pgc, + unsigned corners, int32_t *x, int32_t *y) +{ + double *nodex; + double *dx; + double *dy; + unsigned n, nodes, i, j; + double ymin, ymax, ypos; + + PGCLOG(("pgc_fill_polygon(%d corners)\n", corners)); + + if (corners < 2) return; /* Degenerate polygon */ + nodex = malloc(corners * sizeof(double)); + dx = malloc(corners * sizeof(double)); + dy = malloc(corners * sizeof(double)); + if (!nodex || !dx || !dy) return; + + ymin = ymax = y[0] / 65536.0; + for (n = 0; n < corners; n++) + { + /* Convert from PGC fixed-point to native floating-point */ + dx[n] = x[n] / 65536.0; + dy[n] = y[n] / 65536.0; + + if (dy[n] < ymin) ymin = dy[n]; + if (dy[n] > ymax) ymax = dy[n]; + } + /* Polygon fill. Based on */ + /* For each row, work out where the polygon lines intersect with + * that row. */ + for (ypos = ymin; ypos <= ymax; ypos++) + { + nodes = 0; + j = corners - 1; + for (i = 0; i < corners; i++) + { + if ((dy[i] < ypos && dy[j] >= ypos) + || (dy[j] < ypos && dy[i] >= ypos)) /* Line crosses */ + { + nodex[nodes++] = dx[i] + (ypos-dy[i])/(dy[j]-dy[i]) * (dx[j] - dx[i]); + } + j = i; + } + + /* Sort the intersections */ + if (nodes) qsort(nodex, nodes, sizeof(double), compare_double); +/* + PGCLOG(("pgc_fill_polygon ypos=%f nodes=%d ", ypos, nodes)); + for (i = 0; i < nodes; i++) + { + PGCLOG(("%f;", nodex[i])); + } + PGCLOG(("\n")); +*/ + /* And fill between them */ + for (i = 0; i < nodes; i += 2) + { + int16_t x1 = nodex[i], x2 = nodex[i + 1], + y1 = ypos, y2 = ypos; + pgc_sto_raster(pgc, &x1, &y1); + pgc_sto_raster(pgc, &x2, &y2); +/* PGCLOG(("pgc_fill_polygon raster %d,%d to %d,%d\n", + x1, y1, x2, y2)); */ + pgc_fill_line_r(pgc, x1, x2, y1); + } + } + free(nodex); + free(dx); + free(dy); +} + + + +/* Draw a filled ellipse (using PGC fixed-point coordinates) */ +void pgc_draw_ellipse(pgc_core_t *pgc, int32_t x, int32_t y) +{ + /* Convert from PGC fixed-point to native floating-point */ + double h = y / 65536.0; + double w = x / 65536.0; + double y0 = pgc->y / 65536.0; + double x0 = pgc->x / 65536.0; + double ypos = 0.0, xpos = 0.0; + double x1; + double xlast = 0.0; + int16_t linemask = pgc->line_pattern; + + pgc_dto_raster(pgc, &x0, &y0); + PGCLOG(("Ellipse: Colour=%d Drawmode=%d fill=%d\n", pgc->colour, + pgc->draw_mode, pgc->fill_mode)); + for (ypos = 0; ypos <= h; ypos++) + { + if (ypos == 0) + { + if (pgc->fill_mode) + { + pgc_fill_line_r(pgc, x0 - w, x0 + w, y0); + } + if (linemask & 0x8000) + { + pgc_plot(pgc, x0 + w, y0); + pgc_plot(pgc, x0 - w, y0); + linemask = (linemask << 1) | 1; + } + else + { + linemask = linemask << 1; + } + xlast = w; + } + else + { + x1 = sqrt((h * h) - (ypos * ypos)) * w / h; + + if (pgc->fill_mode) + { + pgc_fill_line_r(pgc, x0 - x1, x0 + x1, y0 + ypos); + pgc_fill_line_r(pgc, x0 - x1, x0 + x1, y0 - ypos); + } + + /* Draw border */ + for (xpos = xlast; xpos >= x1; xpos--) + { + if (linemask & 0x8000) + { + pgc_plot(pgc, x0 + xpos, y0 + ypos); + pgc_plot(pgc, x0 - xpos, y0 + ypos); + pgc_plot(pgc, x0 + xpos, y0 - ypos); + pgc_plot(pgc, x0 - xpos, y0 - ypos); + linemask = (linemask << 1) | 1; + } + else + { + linemask = linemask << 1; + } + + } + xlast = x1; + } + } +} + +/* Handle the ELIPSE (sic) command */ +static void hndl_ellipse(pgc_core_t *pgc) +{ + int32_t x = 0, y = 0; + + if (!pgc_param_coord(pgc, &x)) return; + if (!pgc_param_coord(pgc, &y)) return; + + pgc_draw_ellipse(pgc, x, y); +} + + + + +/* Handle the POLY command */ +static void hndl_poly(pgc_core_t *pgc) +{ + uint8_t count; + int32_t x[256]; + int32_t y[256]; + int32_t n; + + if (!pgc_param_byte(pgc, &count)) return; + + for (n = 0; n < count; n++) + { + if (!pgc_param_coord(pgc, &x[n])) return; + if (!pgc_param_coord(pgc, &y[n])) return; + } + PGCLOG(("POLY (%d)\n", count)); +} + +/* Parse but don't execute a POLY command (for adding to a command list) */ +static int parse_poly(pgc_core_t *pgc, pgc_commandlist_t *cl, int c) +{ + uint8_t count; + + PGCLOG(("parse_poly\n")); + if (!pgc_param_byte(pgc, &count)) return 0; + PGCLOG(("parse_poly: count=%02x\n", count)); + + if (!pgc_commandlist_append(cl, count)) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + PGCLOG(("parse_poly: parse %d coords\n", 2 * count)); + return pgc_parse_coords(pgc, cl, 2 * count); +} + + +/* Parse but don't execute a command with a fixed number of byte parameters */ +int pgc_parse_bytes(pgc_core_t *pgc, pgc_commandlist_t *cl, int count) +{ + uint8_t *param = malloc(count); + int n; + + if (!param) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + for (n = 0; n < count; n++) + { + if (!pgc_param_byte(pgc, ¶m[n])) + { + free(param); + return 0; + } + } + for (n = 0; n < count; n++) + { + if (!pgc_commandlist_append(cl, param[n])) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } + } + free(param); + return 1; +} + + +/* Parse but don't execute a command with a fixed number of word parameters */ +int pgc_parse_words(pgc_core_t *pgc, pgc_commandlist_t *cl, int count) +{ + int16_t *param = malloc(count * sizeof(int16_t)); + int n; + + if (!param) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + for (n = 0; n < count; n++) + { + if (!pgc_param_word(pgc, ¶m[n])) return 0; + } + for (n = 0; n < count; n++) + { + if (!pgc_commandlist_append(cl, param[n] & 0xFF) || + !pgc_commandlist_append(cl, param[n] >> 8)) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } + } + return 1; +} + + + +/* Parse but don't execute a command with a fixed number of coord parameters */ +int pgc_parse_coords(pgc_core_t *pgc, pgc_commandlist_t *cl, int count) +{ + int32_t *param = malloc(count * sizeof(int32_t)); + int n; + + if (!param) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + for (n = 0; n < count; n++) + { + if (!pgc_param_coord(pgc, ¶m[n])) return 0; + } +/* Here's how the real PGC serialises coords: + * + * 100.5 -> 64 00 00 80 ie 0064.8000 + * 100.3 -> 64 00 CD 4C ie 0064.4CCD + * + */ + for (n = 0; n < count; n++) + { + /* Serialise integer part */ + if (!pgc_commandlist_append(cl, (param[n] >> 16) & 0xFF) || + !pgc_commandlist_append(cl, (param[n] >> 24) & 0xFF) || + /* Serialise fraction part */ + !pgc_commandlist_append(cl, (param[n] ) & 0xFF) || + !pgc_commandlist_append(cl, (param[n] >> 8) & 0xFF)) + { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } + } + return 1; +} + + + +/* Handle the DISPLAY command */ +static void hndl_display(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc_param_byte(pgc, ¶m)) return; + + PGCLOG(("DISPLAY(%d)\n", param)); + if (param > 1) + { + pgc_error(pgc, PGC_ERROR_RANGE); + } + else + { + pgc_setdisplay(pgc, param); + } +} + + +/* Handle the IMAGEW command (memory to screen blit) */ +static void hndl_imagew(pgc_core_t *pgc) +{ + int16_t row, col1, col2; + uint8_t v1, v2; + + if (!pgc_param_word(pgc, &row)) return; + if (!pgc_param_word(pgc, &col1)) return; + if (!pgc_param_word(pgc, &col2)) return; + + if (row >= pgc->screenh || col1 >= pgc->maxw || col2 >= pgc->maxw) + { + pgc_error(pgc, PGC_ERROR_RANGE); + return; + } + + /* In ASCII mode, what is written is a stream of bytes */ + if (pgc->ascii_mode) + { + while (col1 <= col2) + { + if (!pgc_param_byte(pgc, &v1)) return; + pgc_write_pixel(pgc, col1, row, v1); + ++col1; + } + return; + } + else /* In hex mode, it's RLE compressed */ + { + while (col1 <= col2) + { + if (!pgc_param_byte(pgc, &v1)) return; + + if (v1 & 0x80) /* Literal run */ + { + v1 -= 0x7F; + while (col1 <= col2 && v1 != 0) + { + if (!pgc_param_byte(pgc, &v2)) return; + pgc_write_pixel(pgc, col1, row, v2); + ++col1; + --v1; + } + } + else /* Repeated run */ + { + if (!pgc_param_byte(pgc, &v2)) return; + + ++v1; + while (col1 <= col2 && v1 != 0) + { + pgc_write_pixel(pgc, col1, row, v2); + ++col1; + --v1; + } + } + } + } +} + + +/* Select one of the built-in palettes */ +static void pgc_init_lut(pgc_core_t *pgc, int param) +{ + if (param >= 0 && param < 6) + { + memcpy(pgc->palette, init_palette[param], sizeof(pgc->palette)); + } + else if (param == 0xFF) + { + memcpy(pgc->palette, pgc->userpal, sizeof(pgc->palette)); + } + else + { + pgc_error(pgc, PGC_ERROR_RANGE); + } +} + +/* Save the current palette */ +static void hndl_lutsav(pgc_core_t *pgc) +{ + memcpy(pgc->userpal, pgc->palette, sizeof(pgc->palette)); +} + + +/* Handle LUTINT (select palette) */ +static void hndl_lutint(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc_param_byte(pgc, ¶m)) return; + + pgc_init_lut(pgc, param); +} + + +/* Handle LUTRD (read palette register) */ +static void hndl_lutrd(pgc_core_t *pgc) +{ + uint8_t param; + uint32_t col; + + if (!pgc_param_byte(pgc, ¶m)) return; + + col = pgc->palette[param]; + + pgc_result_byte(pgc, (col >> 20) & 0x0F); + pgc_result_byte(pgc, (col >> 12) & 0x0F); + pgc_result_byte(pgc, (col >> 4) & 0x0F); +} + +/* Handle LUT (write palette register) */ +static void hndl_lut(pgc_core_t *pgc) +{ + uint8_t param[4]; + int n; + + for (n = 0; n < 4; n++) + { + if (!pgc_param_byte(pgc, ¶m[n])) return; + if (n > 0 && param[n] > 15) + { + pgc_error(pgc, PGC_ERROR_RANGE); + param[n] &= 0x0F; + } + } + pgc->palette[param[0]] = makecol((param[1] * 0x11), + (param[2] * 0x11), + (param[3] * 0x11)); +} + +/* LUT8RD and LUT8 are extensions implemented by several PGC clones, so + * here are functions that implement them even though they aren't + * used by the PGC */ +void pgc_hndl_lut8rd(pgc_core_t *pgc) +{ + uint8_t param; + uint32_t col; + + if (!pgc_param_byte(pgc, ¶m)) return; + + col = pgc->palette[param]; + + pgc_result_byte(pgc, (col >> 16) & 0xFF); + pgc_result_byte(pgc, (col >> 8) & 0xFF); + pgc_result_byte(pgc, col & 0xFF); +} + +void pgc_hndl_lut8(pgc_core_t *pgc) +{ + uint8_t param[4]; + int n; + + for (n = 0; n < 4; n++) + { + if (!pgc_param_byte(pgc, ¶m[n])) return; + } + pgc->palette[param[0]] = makecol((param[1]), (param[2]), (param[3])); +} + + +/* Handle AREAPT (set 16x16 fill pattern) */ +static void hndl_areapt(pgc_core_t *pgc) +{ + int16_t pattern[16]; + int n; + + for (n = 0; n < 16; n++) + { + if (!pgc_param_word(pgc, &pattern[n])) return; + } + memcpy(pgc->fill_pattern, pattern, sizeof(pgc->fill_pattern)); + PGCLOG(("AREAPT(%04x %04x %04x %04x...)\n", + pattern[0] & 0xFFFF, pattern[1] & 0xFFFF, + pattern[2] & 0xFFFF, pattern[3] & 0xFFFF)); +} + + +/* Handle CA (select ASCII mode) */ +static void hndl_ca(pgc_core_t *pgc) +{ + pgc->ascii_mode = 1; +} + +/* Handle CX (select hex mode) */ +static void hndl_cx(pgc_core_t *pgc) +{ + pgc->ascii_mode = 0; +} + +/* CA and CX remain valid in hex mode; they are handled as command 0x43 ('C') + * with a one-byte parameter */ +static void hndl_c(pgc_core_t *pgc) +{ + uint8_t param; + + if (!pgc->inputbyte(pgc, ¶m)) return; + + if (param == 'A') pgc->ascii_mode = 1; + if (param == 'X') pgc->ascii_mode = 0; +} + +/* RESETF resets the PGC */ +static void hndl_resetf(pgc_core_t *pgc) +{ + pgc_reset(pgc); +} + + + +/* TJUST sets text justify settings */ +static void hndl_tjust(pgc_core_t *pgc) +{ + uint8_t param[2]; + + if (!pgc->inputbyte(pgc, ¶m[0])) return; + if (!pgc->inputbyte(pgc, ¶m[1])) return; + + if (param[0] >= 1 && param[0] <= 3 && + param[1] >= 1 && param[1] <= 3) + { + pgc->tjust_h = param[0]; + pgc->tjust_v = param[1]; + } + else + { + pgc_error(pgc, PGC_ERROR_RANGE); + } +} + +/* TSIZE controls text horizontal spacing */ +static void hndl_tsize(pgc_core_t *pgc) +{ + int32_t param = 0; + + if (!pgc_param_coord(pgc, ¶m)) return; + + pgc->tsize = param; + PGCLOG(("TSIZE %d\n", param)); +} + + +/* VWPORT sets up the viewport (roughly, the clip rectangle) in raster + * coordinates, measured from the bottom left of the screen */ +static void hndl_vwport(pgc_core_t *pgc) +{ + int16_t x1, x2, y1, y2; + + if (!pgc_param_word(pgc, &x1)) return; + if (!pgc_param_word(pgc, &x2)) return; + if (!pgc_param_word(pgc, &y1)) return; + if (!pgc_param_word(pgc, &y2)) return; + + PGCLOG(("VWPORT %d,%d,%d,%d\n", x1,x2,y1,y2)); + pgc->vp_x1 = x1; + pgc->vp_x2 = x2; + pgc->vp_y1 = y1; + pgc->vp_y2 = y2; +} + +/* WINDOW defines the coordinate system in use */ +static void hndl_window(pgc_core_t *pgc) +{ + int16_t x1, x2, y1, y2; + + if (!pgc_param_word(pgc, &x1)) return; + if (!pgc_param_word(pgc, &x2)) return; + if (!pgc_param_word(pgc, &y1)) return; + if (!pgc_param_word(pgc, &y2)) return; + + PGCLOG(("WINDOW %d,%d,%d,%d\n", x1,x2,y1,y2)); + pgc->win_x1 = x1; + pgc->win_x2 = x2; + pgc->win_y1 = y1; + pgc->win_y2 = y2; +} + + + +/* The list of commands implemented by this mini-PGC. In order to support + * the original PGC and clones, we support two lists; core commands (listed + * below) and subclass commands (listed in the clone). + * + * Each row has five parameters: + * ASCII-mode command + * Hex-mode command + * Function that executes this command + * Function that parses this command when building a command list + * Parameter for the parse function + * + * TODO: This list omits numerous commands present in a genuine PGC + * (ARC, AREA, AREABC, BUFFER, CIRCLE etc etc). + * TODO: Some commands don't have a parse function (for example, IMAGEW) + * + * The following ASCII entries have special meaning: + * ~~~~~~ command is valid only in hex mode + * ****** end of subclass command list, now process core command list + * @@@@@@ end of core command list + * + */ +static const pgc_command_t pgc_core_commands[] = +{ + { "AREAPT", 0xE7, hndl_areapt, pgc_parse_words, 16 }, + { "AP", 0xE7, hndl_areapt, pgc_parse_words, 16 }, + { "~~~~~~", 0x43, hndl_c }, /* Handle CA / CX in hex mode */ + { "CA", 0xD2, hndl_ca }, + { "CLBEG", 0x70, hndl_clbeg }, + { "CB", 0x70, hndl_clbeg }, + { "CLDEL", 0x74, hndl_cldel, pgc_parse_bytes, 1 }, + { "CD", 0x74, hndl_cldel, pgc_parse_bytes, 1 }, + { "CLEND", 0x71, hndl_clend }, + { "CLRUN", 0x72, hndl_clrun, pgc_parse_bytes, 1 }, + { "CR", 0x72, hndl_clrun, pgc_parse_bytes, 1 }, + { "CLRD", 0x75, hndl_clread, pgc_parse_bytes, 1 }, + { "CRD", 0x75, hndl_clread, pgc_parse_bytes, 1 }, + { "CLOOP", 0x73, hndl_cloop }, + { "CL", 0x73, hndl_cloop }, + { "CLEARS", 0x0F, hndl_clears, pgc_parse_bytes, 1 }, + { "CLS", 0x0F, hndl_clears, pgc_parse_bytes, 1 }, + { "COLOR", 0x06, hndl_color, pgc_parse_bytes, 1 }, + { "C", 0x06, hndl_color, pgc_parse_bytes, 1 }, + { "CX", 0xD1, hndl_cx }, + { "DISPLA", 0xD0, hndl_display, pgc_parse_bytes, 1 }, + { "DI", 0xD0, hndl_display, pgc_parse_bytes, 1 }, + { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_coords, 2 }, + { "EL", 0x39, hndl_ellipse, pgc_parse_coords, 2 }, + { "IMAGEW", 0xD9, hndl_imagew }, + { "IW", 0xD9, hndl_imagew }, + { "LINFUN", 0xEB, hndl_linfun, pgc_parse_bytes, 1 }, + { "LF", 0xEB, hndl_linfun, pgc_parse_bytes, 1 }, + { "LINPAT", 0xEA, hndl_linpat, pgc_parse_words, 1 }, + { "LP", 0xEA, hndl_linpat, pgc_parse_words, 1 }, + { "LUTINT", 0xEC, hndl_lutint, pgc_parse_bytes, 1 }, + { "LI", 0xEC, hndl_lutint, pgc_parse_bytes, 1 }, + { "LUTRD", 0x50, hndl_lutrd, pgc_parse_bytes, 1 }, + { "LUTSAV", 0xED, hndl_lutsav, NULL, 0 }, + { "LUT", 0xEE, hndl_lut, pgc_parse_bytes, 4 }, + { "MOVE", 0x10, hndl_move, pgc_parse_coords, 2 }, + { "M", 0x10, hndl_move, pgc_parse_coords, 2 }, + { "MOVE3", 0x12, hndl_move3, pgc_parse_coords, 3 }, + { "M3", 0x12, hndl_move3, pgc_parse_coords, 3 }, + { "MOVER", 0x11, hndl_mover, pgc_parse_coords, 2 }, + { "MR", 0x11, hndl_mover, pgc_parse_coords, 2 }, + { "MOVER3", 0x13, hndl_mover3, pgc_parse_coords, 3 }, + { "MR3", 0x13, hndl_mover3, pgc_parse_coords, 3 }, + { "PRMFIL", 0xE9, hndl_prmfil, pgc_parse_bytes, 1 }, + { "PF", 0xE9, hndl_prmfil, pgc_parse_bytes, 1 }, + { "POLY", 0x30, hndl_poly, parse_poly }, + { "P", 0x30, hndl_poly, parse_poly }, + { "RESETF", 0x04, hndl_resetf, NULL, 0 }, + { "RF", 0x04, hndl_resetf, NULL, 0 }, + { "TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2 }, + { "TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2 }, + { "TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1 }, + { "TS", 0x81, hndl_tsize, pgc_parse_coords, 1 }, + { "VWPORT", 0xB2, hndl_vwport, pgc_parse_words, 4 }, + { "VWP", 0xB2, hndl_vwport, pgc_parse_words, 4 }, + { "WINDOW", 0xB3, hndl_window, pgc_parse_words, 4 }, + { "WI", 0xB3, hndl_window, pgc_parse_words, 4 }, + + { "@@@@@@", 0x00, NULL } +}; + + +/* Writes to CGA registers are copied into the transfer memory buffer */ +void pgc_out(uint16_t addr, uint8_t val, void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + switch(addr) + { + case 0x3D0: case 0x3D2: case 0x3D4: case 0x3D6: + pgc->mapram[0x3D0] = val; break; + case 0x3D1: case 0x3D3: case 0x3D5: case 0x3D7: + if (pgc->mapram[0x3D0] < 18) + { + pgc->mapram[0x3E0 + pgc->mapram[0x3D0]] = val; + } + break; + case 0x3D8: pgc->mapram[0x3D8] = val; break; + case 0x3D9: pgc->mapram[0x3D9] = val; break; + } + +} + +/* Read back the CGA registers */ +uint8_t pgc_in(uint16_t addr, void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + switch(addr) + { + case 0x3D0: case 0x3D2: case 0x3D4: case 0x3D6: + return pgc->mapram[0x3D0]; + case 0x3D1: case 0x3D3: case 0x3D5: case 0x3D7: + if (pgc->mapram[0x3D0] < 18) + { + return pgc->mapram[0x3E0 + pgc->mapram[0x3D0]]; + } + return 0xFF; + + case 0x3D8: return pgc->mapram[0x3D8]; + case 0x3D9: return pgc->mapram[0x3D9]; + case 0x3DA: return pgc->mapram[0x3DA]; + } + return 0xFF; +} + +/* Memory write to the transfer buffer */ +void pgc_write(uint32_t addr, uint8_t val, void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + /* It seems variable whether the PGC maps 1k or 2k at 0xC6000. + * Map 2k here in case a clone requires it */ + if (addr >= 0xC6000 && addr < 0xC6800) + { + addr &= 0x7FF; + + /* If one of the FIFOs has been updated, this may cause + * the drawing thread to be woken */ + + if (pgc->mapram[addr] != val) + { + pgc->mapram[addr] = val; + switch (addr) + { + case 0x300: /* Input write pointer */ + if (pgc->waiting_input_fifo && + pgc->mapram[0x300] != pgc->mapram[0x301]) + { + pgc->waiting_input_fifo = 0; + pgc_wake(pgc); + } + break; + + case 0x303: /* Output read pointer */ + if (pgc->waiting_output_fifo && + pgc->mapram[0x302] != (uint8_t)(pgc->mapram[0x303] - 1)) + { + pgc->waiting_output_fifo = 0; + pgc_wake(pgc); + } + break; + + case 0x305: /* Error read pointer */ + if (pgc->waiting_error_fifo && + pgc->mapram[0x304] != (uint8_t)(pgc->mapram[0x305] - 1)) + { + pgc->waiting_error_fifo = 0; + pgc_wake(pgc); + } + break; + + case 0x306: /* Cold start flag */ + /* XXX This should be in IM-1024 specific code */ + pgc->mapram[0x306] = 0; + break; + + case 0x030C: /* Display type */ + pgc_setdisplay(p, pgc->mapram[0x30C]); + pgc->mapram[0x30D] = pgc->mapram[0x30C]; + break; + + + case 0x3FF: /* Reboot the PGC + (handled on core thread) */ + pgc_wake(pgc); + break; + } // end switch (addr) + } + } + if (addr >= 0xB8000 && addr < 0xBC000 && pgc->cga_selected) + { + addr &= 0x3FFF; + pgc->cga_vram[addr] = val; + } +} + + +uint8_t pgc_read(uint32_t addr, void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + if (addr >= 0xC6000 && addr < 0xC6800) + { + addr &= 0x7FF; + + return pgc->mapram[addr]; + } + if (addr >= 0xB8000 && addr < 0xBC000 && pgc->cga_selected) + { + addr &= 0x3FFF; + return pgc->cga_vram[addr]; + } + return 0xFF; +} + +/* Called by the drawing thread to read the next byte from the input + * buffer. If no byte available will sleep until one is. Returns 0 if + * a PGC reset has been triggered by a write to 0xC63FF */ +int pgc_input_byte(pgc_core_t *pgc, uint8_t *result) +{ + /* If input buffer empty, wait for it to fill */ + while (pgc->mapram[0x300] == pgc->mapram[0x301]) + { + pgc->waiting_input_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + + *result = pgc->mapram[pgc->mapram[0x301]]; + ++pgc->mapram[0x301]; + return 1; +} + +/* Called by the drawing thread to write a byte to the output buffer. + * If buffer is full will sleep until it is not. Returns 0 if + * a PGC reset has been triggered by a write to 0xC63FF */ +int pgc_output_byte(pgc_core_t *pgc, uint8_t val) +{ + /* If output buffer full, wait for it to empty */ + while (pgc->mapram[0x302] == (uint8_t)(pgc->mapram[0x303] - 1)) + { + PGCLOG(("Output buffer state: %02x %02x Sleeping\n", + pgc->mapram[0x302], pgc->mapram[0x303])); + pgc->waiting_output_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + pgc->mapram[0x100 + pgc->mapram[0x302]] = val; + ++pgc->mapram[0x302]; +/* + PGCLOG(("Output %02x: new state: %02x %02x\n", val, + pgc->mapram[0x302], pgc->mapram[0x303])); */ + return 1; +} + +/* Helper to write an entire string to the output buffer */ +int pgc_output_string(pgc_core_t *pgc, const char *s) +{ + while (*s) + { + if (!pgc_output_byte(pgc, *s)) return 0; + ++s; + } + return 1; +} + +/* As pgc_output_byte, for the error buffer */ +int pgc_error_byte(pgc_core_t *pgc, uint8_t val) +{ + /* If error buffer full, wait for it to empty */ + while (pgc->mapram[0x304] == pgc->mapram[0x305] - 1) + { + pgc->waiting_error_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + pgc->mapram[0x200 + pgc->mapram[0x304]] = val; + ++pgc->mapram[0x304]; + return 1; +} + +/* As pgc_output_string, for the error buffer */ +int pgc_error_string(pgc_core_t *pgc, const char *s) +{ + while (*s) + { + if (!pgc_error_byte(pgc, *s)) return 0; + ++s; + } + return 1; +} + + +/* Report an error, either in ASCII or in hex */ +int pgc_error(pgc_core_t *pgc, int err) +{ + if (pgc->mapram[0x307]) /* Errors enabled? */ + { + if (pgc->ascii_mode) + { + if (err >= PGC_ERROR_RANGE && err <= PGC_ERROR_MISSING) + return pgc_error_string(pgc, pgc_err_msgs[err]); + return pgc_error_string(pgc, "Unknown error\r"); + } + else + { + return pgc_error_byte(pgc, err); + } + } + return 1; +} + + +static inline int is_whitespace(char ch) +{ + return (ch != 0 && strchr(" \r\n\t,;()+-", ch) != NULL); +} + + +/* Read a byte and interpret as ASCII: ignore control characters other than + * CR, LF or tab. */ +int pgc_input_char(pgc_core_t *pgc, char *result) +{ + uint8_t ch; + + while (1) + { + if (!pgc->inputbyte(pgc, &ch)) return 0; + + ch &= 0x7F; + if (ch == '\r' || ch == '\n' || ch == '\t' || ch >= ' ') + { + *result = toupper(ch); + return 1; + } + } +} + + +/* Parameter passed is not a number: abort */ +static int err_digit(pgc_core_t *pgc) +{ + uint8_t asc; + + do /* Swallow everything until the next separator */ + { + if (!pgc->inputbyte(pgc, &asc)) return 0; + } + while (!is_whitespace(asc)); + pgc_error(pgc, PGC_ERROR_DIGIT); + return 0; +} + + +typedef enum parse_state_t +{ + PS_MAIN, + PS_FRACTION, + PS_EXPONENT +} parse_state_t; + +/* Read in a PGC coordinate, either as hex (4 bytes) or ASCII (xxxx.yyyyEeee) + * Returns 0 if PGC reset detected while the value is being read */ +int pgc_param_coord(pgc_core_t *pgc, int32_t *value) +{ + uint8_t asc; + int sign = 1; + int esign = 1; + int n; + uint16_t dp = 1; + uint16_t integer = 0; + uint16_t frac = 0; + uint16_t exponent = 0; + uint32_t res; + parse_state_t state = PS_MAIN; + uint8_t encoded[4]; + + /* If there is a command list running, pull the bytes out of that + * command list */ + if (pgc->clcur) + { + for (n = 0; n < 4; n++) + { + if (!pgc_clist_byte(pgc, &encoded[n])) return 0; + } + integer = (((int16_t)encoded[1]) << 8) | encoded[0]; + frac = (((int16_t)encoded[3]) << 8) | encoded[2]; + + *value = (((int32_t)integer) << 16) | frac; + return 1; + } + /* If in hex mode, read in the encoded integer and fraction parts + * from the hex stream */ + if (!pgc->ascii_mode) + { + for (n = 0; n < 4; n++) + { + if (!pgc->inputbyte(pgc, &encoded[n])) return 0; + } + integer = (((int16_t)encoded[1]) << 8) | encoded[0]; + frac = (((int16_t)encoded[3]) << 8) | encoded[2]; + + *value = (((int32_t)integer) << 16) | frac; + return 1; + } + /* Parsing an ASCII value */ + + /* Skip separators */ + do + { + if (!pgc->inputbyte(pgc, &asc)) return 0; + if (asc == '-') sign = -1; + } + while (is_whitespace(asc)); + + /* There had better be a digit next */ + if (!isdigit(asc)) + { + pgc_error(pgc, PGC_ERROR_MISSING); + return 0; + } + do + { + switch (asc) + { +/* Decimal point is acceptable in 'main' state (start of fraction) + * not otherwise */ + case '.': + if (state == PS_MAIN) + { + if (!pgc->inputbyte(pgc, &asc)) return 0; + state = PS_FRACTION; + continue; + } + else + { + pgc_error(pgc, PGC_ERROR_MISSING); + return err_digit(pgc); + } + break; + /* Scientific notation */ + case 'd': case 'D': case 'e': case 'E': + esign = 1; + if (!pgc->inputbyte(pgc, &asc)) return 0; + if (asc == '-') + { + sign = -1; + if (!pgc->inputbyte(pgc, &asc)) return 0; + } + state = PS_EXPONENT; + continue; + /* Should be a number or a separator */ + default: + if (is_whitespace(asc)) break; + if (!isdigit(asc)) + { + pgc_error(pgc, PGC_ERROR_MISSING); + return err_digit(pgc); + } + asc -= '0'; /* asc is digit */ + switch (state) + { + case PS_MAIN: + integer = (integer * 10)+asc; + if (integer & 0x8000) /* Overflow */ + { + pgc_error(pgc, PGC_ERROR_RANGE); + integer = 0x7FFF; + } + break; + case PS_FRACTION: + frac = (frac * 10)+asc; + dp *= 10; + break; + case PS_EXPONENT: + exponent = (exponent * 10)+asc; + break; + } + + } + if (!pgc->inputbyte(pgc, &asc)) return 0; + } + while (!is_whitespace(asc)); + + + res = (frac << 16) / dp; + PGCLOG(("integer=%u frac=%u exponent=%u dp=%d res=0x%08x\n", + integer, frac, exponent, dp, res)); + + res = (res & 0xFFFF) | (integer << 16); + if (exponent) + { + for (n = 0; n < exponent; n++) + { + if (esign > 0) res *= 10; + else res /= 10; + } + } + *value = sign*res; + + return 1; +} + +/* Pull the next byte from the current command list */ +int pgc_clist_byte(pgc_core_t *pgc, uint8_t *val) +{ + if (pgc->clcur == NULL) return 0; + + if (pgc->clcur->rdptr < pgc->clcur->wrptr) + { + *val = pgc->clcur->list[pgc->clcur->rdptr++]; + } + else + { + *val = 0; + } + /* If we've reached the end, reset to the beginning and + * (if repeating) run the repeat */ + if (pgc->clcur->rdptr >= pgc->clcur->wrptr) + { + pgc->clcur->rdptr = 0; + --pgc->clcur->repeat; + if (pgc->clcur->repeat == 0) + { + pgc->clcur = pgc->clcur->chain; + } + } + return 1; +} + + +/* Read in a byte, either as hex (1 byte) or ASCII (decimal). + * Returns 0 if PGC reset detected while the value is being read */ +int pgc_param_byte(pgc_core_t *pgc, uint8_t *val) +{ + int32_t c; + + if (pgc->clcur) return pgc_clist_byte(pgc, val); + + if (!pgc->ascii_mode) return pgc->inputbyte(pgc, val); + + if (!pgc_param_coord(pgc, &c)) return 0; + c = (c >> 16); /* Drop fractional part */ + + if (c > 255) + { + pgc_error(pgc, PGC_ERROR_RANGE); + return 0; + } + *val = (uint8_t)c; + return 1; +} + +/* Read in a word, either as hex (2 bytes) or ASCII (decimal). + * Returns 0 if PGC reset detected while the value is being read */ +int pgc_param_word(pgc_core_t *pgc, int16_t *val) +{ + int32_t c; + + if (pgc->clcur) + { + uint8_t lo, hi; + + if (!pgc_clist_byte(pgc, &lo)) return 0; + if (!pgc_clist_byte(pgc, &hi)) return 0; + *val = (((int16_t)hi) << 8) | lo; + return 1; + } + + if (!pgc->ascii_mode) + { + uint8_t lo, hi; + + if (!pgc->inputbyte(pgc, &lo)) return 0; + if (!pgc->inputbyte(pgc, &hi)) return 0; + *val = (((int16_t)hi) << 8) | lo; + return 1; + } + + if (!pgc_param_coord(pgc, &c)) return 0; + + c = (c >> 16); + if (c > 0x7FFF || c < -0x7FFF) + { + pgc_error(pgc, PGC_ERROR_RANGE); + return 0; + } + *val = (int16_t)c; + return 1; +} + + +/* Output a byte, either as hex or ASCII depending on the mode */ +int pgc_result_byte(pgc_core_t *pgc, uint8_t val) +{ + char buf[20]; + + if (!pgc->ascii_mode) return pgc_output_byte(pgc, val); + + if (pgc->result_count) + { + if (!pgc_output_byte(pgc, ',')) return 0; + } + sprintf(buf, "%d", val); + ++pgc->result_count; + return pgc_output_string(pgc, buf); +} + + +/* Output a word, either as hex or ASCII depending on the mode */ +int pgc_result_word(pgc_core_t *pgc, int16_t val) +{ + char buf[20]; + + if (!pgc->ascii_mode) + { + if (!pgc_output_byte(pgc, val & 0xFF)) return 0; + return pgc_output_byte(pgc, val >> 8); + } + + if (pgc->result_count) + { + if (!pgc_output_byte(pgc, ',')) return 0; + } + sprintf(buf, "%d", val); + ++pgc->result_count; + return pgc_output_string(pgc, buf); +} + + +/* Write a screen pixel (x and y are raster coordinates, ink is the + * value to write) */ +void pgc_write_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y, uint8_t ink) +{ + uint8_t *vram; + + /* Suppress out-of-range writes; clip to viewport */ + if (x < pgc->vp_x1 || x > pgc->vp_x2 || x >= pgc->maxw || + y < pgc->vp_y1 || y > pgc->vp_y2 || y >= pgc->maxh) + { + PGCLOG(("pgc_write_pixel clipped: (%d,%d) " + "vp_x1=%d vp_y1=%d vp_x2=%d vp_y2=%d " + "ink=0x%02x\n", x, y, + pgc->vp_x1, pgc->vp_y1, + pgc->vp_x2, pgc->vp_y2, ink)); + return; + } + vram = pgc_vram_addr(pgc, x, y); + if (vram) *vram = ink; +} + +/* Read a screen pixel (x and y are raster coordinates) */ +uint8_t pgc_read_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y) +{ + uint8_t *vram; + + /* Suppress out-of-range reads */ + if (x >= pgc->maxw || y >= pgc->maxh) + { + return 0; + } + vram = pgc_vram_addr(pgc, x, y); + if (vram) return *vram; + return 0; +} + + + + +/* Plot a point in the current colour and draw mode. Raster coordinates. */ +void pgc_plot(pgc_core_t *pgc, uint16_t x, uint16_t y) +{ + uint8_t *vram; + + /* Only allow plotting within the current viewport. */ + if (x < pgc->vp_x1 || x > pgc->vp_x2 || x >= pgc->maxw || + y < pgc->vp_y1 || y > pgc->vp_y2 || y >= pgc->maxh) + { + PGCLOG(("pgc_plot clipped: (%d,%d) %d <= x <= %d; %d <= y <= %d; " + "mode=%d ink=0x%02x\n", x, y, + pgc->vp_x1, pgc->vp_x2, pgc->vp_y1, pgc->vp_y2, + pgc->draw_mode, pgc->colour)); + return; + } + vram = pgc_vram_addr(pgc, x, y); + if (!vram) return; + + /* TODO: Does not implement the PGC plane mask (set by MASK) */ + switch (pgc->draw_mode) + { + default: + case 0: *vram = pgc->colour; break; /* Write */ + case 1: *vram ^= 0xFF; break; /* Invert */ + case 2: *vram ^= pgc->colour; break; /* XOR colour */ + case 3: *vram &= pgc->colour; break; /* AND */ + } +} + + +/* Given raster coordinates, find the matching address in PGC video RAM */ +uint8_t *pgc_vram_addr(pgc_core_t *pgc, int16_t x, int16_t y) +{ + int offset; + +/* We work from the bottom left-hand corner */ + if (y < 0 || y >= pgc->maxh || x < 0 || x >= pgc->maxw) return NULL; + + offset = (pgc->maxh - 1 -y) * (pgc->maxw) + x; +// PGCLOG(("pgc_vram_addr x=%d y=%d offset=%d\n", x, y, offset); + + if (offset < 0 || offset >= (pgc->maxw * pgc->maxh)) + { + return NULL; + } + return &pgc->vram[offset]; +} + + + +/* Read in the next command, either as hex (1 byte) or ASCII (up to 6 + * characters) */ +int pgc_read_command(pgc_core_t *pgc) +{ + if (pgc->clcur) + { + return pgc_clist_byte(pgc, &pgc->hex_command); + } + else if (pgc->ascii_mode) + { + char ch; + int count = 0; + + while (count < 7) + { + if (!pgc_input_char(pgc, &ch)) return 0; + if (is_whitespace(ch)) + { + /* Pad to 6 characters */ + while (count < 6) + pgc->asc_command[count++] = ' '; + pgc->asc_command[6] = 0; + return 1; + } + pgc->asc_command[count++] = toupper(ch); + } + return 1; + } + else + { + return pgc->inputbyte(pgc, &pgc->hex_command); + } +} + + +/* Read in the next command and parse it */ +static int pgc_parse_command(pgc_core_t *pgc, const pgc_command_t **pcmd) +{ + const pgc_command_t *cmd; + char match[7]; + + *pcmd = NULL; + pgc->hex_command = 0; + memset(pgc->asc_command, ' ', 6); + pgc->asc_command[6] = 0; + if (!pgc_read_command(pgc)) + { + /* PGC has been reset */ + return 0; + } +/* Scan the list of valid commands. pgc->pgc_commands may be a subclass + * list (terminated with '*') or the core list (terminated with '@') */ + for (cmd = pgc->pgc_commands; cmd->ascii[0] != '@'; cmd++) + { + /* End of subclass command list, chain to core */ + if (cmd->ascii[0] == '*') cmd = pgc_core_commands; + + /* If in ASCII mode match on the ASCII command */ + if (pgc->ascii_mode && !pgc->clcur) + { + sprintf(match, "%-6.6s", cmd->ascii); + if (!strncmp(match, pgc->asc_command, 6)) + { + *pcmd = cmd; + pgc->hex_command = cmd->hex; + break; + } + } + else /* Otherwise match on the hex command */ + { + if (cmd->hex == pgc->hex_command) + { + sprintf(pgc->asc_command, "%-6.6s", + cmd->ascii); + *pcmd = cmd; + break; + } + } + } + return 1; +} + + +/* The PGC drawing thread main loop. Read in commands and execute them ad + * infinitum */ +void pgc_core_thread(void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + const pgc_command_t *cmd; + + PGCLOG(("pgc_core_thread begins")); + while (1) + { + if (!pgc_parse_command(pgc, &cmd)) + { + /* PGC has been reset */ + continue; + } + PGCLOG(("PGC command: [%02x] '%s' found=%d\n", + pgc->hex_command, pgc->asc_command, (cmd != NULL))); + + if (cmd) + { + pgc->result_count = 0; + (*cmd->handler)(pgc); + } + else + { + pgc_error(pgc, PGC_ERROR_OPCODE); + } + } +} + +void pgc_recalctimings(pgc_core_t *pgc) +{ + double disptime, _dispontime, _dispofftime; + double pixel_clock = pgc->cga_selected ? 25175000.0 : pgc->native_pixel_clock; + + /* Use a fixed 640 columns, like the T3100e */ + disptime = pgc->screenw + 11; + _dispontime = pgc->screenw * (cpuclock / pixel_clock); + _dispofftime = (disptime - _dispontime) * (cpuclock / pixel_clock); + pgc->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + pgc->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +} + +/* Draw the display in CGA (640x400) text mode */ +void pgc_cga_text(pgc_core_t *pgc, int w) +{ + int x, c; + uint8_t chr, attr; + int drawcursor = 0; + uint32_t cols[2]; + int pitch = (pgc->mapram[0x3E9] + 1) * 2; + uint16_t sc = (pgc->displine & 0x0F) % pitch; + uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; + uint16_t ca = (pgc->mapram[0x3EF] | (pgc->mapram[0x3EE] << 8)) & 0x3fff; + uint8_t *addr; + int cw = (w == 80) ? 8 : 16; + + addr = &pgc->cga_vram[((ma << 1) + (((pgc->displine / pitch)*w)) * 2) & 0x3ffe]; + ma += (pgc->displine / pitch) * w; + + for (x = 0; x < w; x++) + { + chr = addr[0]; + attr = addr[1]; + addr += 2; + + /* Cursor enabled? */ + if (ma == ca && (pgc->cgablink & 8) && + (pgc->mapram[0x3EA] & 0x60) != 0x20) + { + drawcursor = ((pgc->mapram[0x3EA] & 0x1F) <= (sc >> 1)) + && ((pgc->mapram[0x3EB] & 0x1F) >= (sc >> 1)); + } + else drawcursor = 0; + if (pgc->mapram[0x3D8] & 0x20) + { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((pgc->cgablink & 8) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } + else + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + if (drawcursor) + { + for (c = 0; c < cw; c++) + { + if (w == 80) + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 3) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + else + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + } + else + { + for (c = 0; c < cw; c++) + { + if (w == 80) + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 3) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + else + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << ((c >> 1) ^ 7))) ? 1 : 0]; + } + } + ma++; + } +} + + +/* Draw the display in CGA (320x200) graphics mode */ +void pgc_cga_gfx40(pgc_core_t *pgc) +{ + int x, c; + uint32_t cols[4]; + int col; + uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; + uint8_t *addr; + uint16_t dat; + + cols[0] = pgc->mapram[0x3D9] & 15; + col = (pgc->mapram[0x3D9] & 16) ? 8 : 0; + + if (pgc->mapram[0x3D8] & 4) + { + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; + } + else if (pgc->mapram[0x3D9] & 32) + { + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; + } + else + { + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; + } + for (x = 0; x < 40; x++) + { + addr = &pgc->cga_vram[(ma + 2 * x + 80 * (pgc->displine >> 2) + 0x2000 * ((pgc->displine >> 1) & 1)) & 0x3FFF]; + dat = (addr[0] << 8) | addr[1]; + pgc->ma++; + for (c = 0; c < 8; c++) + { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + (c << 1)] = + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + (c << 1) + 1] = cols[dat >> 14]; + dat <<= 2; + } + } +} + + +/* Draw the display in CGA (640x200) graphics mode */ +void pgc_cga_gfx80(pgc_core_t *pgc) +{ + int x, c; + uint32_t cols[2]; + uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; + uint8_t *addr; + uint16_t dat; + + cols[0] = 0; + cols[1] = pgc->mapram[0x3D9] & 15; + + for (x = 0; x < 40; x++) + { + addr = &pgc->cga_vram[(ma + 2 * x + 80 * (pgc->displine >> 2) + 0x2000 * ((pgc->displine >> 1) & 1)) & 0x3FFF]; + dat = (addr[0] << 8) | addr[1]; + pgc->ma++; + for (c = 0; c < 16; c++) + { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[dat >> 15]; + dat <<= 1; + } + } +} + + + +/* Draw the screen in CGA mode. Based on the simplified WY700 renderer + * rather than the original CGA, since the PGC doesn't have a real 6845 */ +void pgc_cga_poll(pgc_core_t *pgc) +{ + int c; + uint32_t cols[2]; + + if (!pgc->linepos) + { + pgc->vidtime += pgc->dispofftime; + pgc->mapram[0x3DA] |= 1; + pgc->linepos = 1; + if (pgc->cgadispon) + { + if (pgc->displine == 0) + { + video_wait_for_buffer(); + } + + if ((pgc->mapram[0x3D8] & 0x12) == 0x12) + { + pgc_cga_gfx80(pgc); + } + else if (pgc->mapram[0x3D8] & 0x02) + { + pgc_cga_gfx40(pgc); + } + else if (pgc->mapram[0x3D8] & 0x01) + { + pgc_cga_text(pgc, 80); + } + else + { + pgc_cga_text(pgc, 40); + } + } + else + { + cols[0] = ((pgc->mapram[0x3D8] & 0x12) == 0x12) ? 0 : (pgc->mapram[0x3D9] & 15); + hline(buffer32, 0, pgc->displine & 2047, PGC_CGA_WIDTH, cols[0]); + } + + for (c = 0; c < PGC_CGA_WIDTH; c++) + ((uint32_t *)buffer32->line[pgc->displine & 2047])[c] = cgapal[((uint32_t *)buffer32->line[pgc->displine & 2047])[c] & 0xf]; + + pgc->displine++; + if (pgc->displine == PGC_CGA_HEIGHT) + { + pgc->mapram[0x3DA] |= 8; + pgc->cgadispon = 0; + } + if (pgc->displine == PGC_CGA_HEIGHT + 32) + { + pgc->mapram[0x3DA] &= ~8; + pgc->cgadispon = 1; + pgc->displine = 0; + } + } + else + { + if (pgc->cgadispon) + { + pgc->mapram[0x3DA] &= ~1; + } + pgc->vidtime += pgc->dispontime; + pgc->linepos = 0; + + if (pgc->displine == PGC_CGA_HEIGHT) + { + if (PGC_CGA_WIDTH != xsize || PGC_CGA_HEIGHT != ysize) + { + xsize = PGC_CGA_WIDTH; + ysize = PGC_CGA_HEIGHT; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + frames++; + + /* We have a fixed 640x400 screen for + * CGA modes */ + video_res_x = PGC_CGA_WIDTH; + video_res_y = PGC_CGA_HEIGHT; + switch (pgc->mapram[0x3D8] & 0x12) + { + case 0x12: video_bpp = 1; break; + case 0x02: video_bpp = 2; break; + default: video_bpp = 0; break; + } + pgc->cgablink++; + } + } +} + + + +/* Draw the screen in CGA or native mode. */ +void pgc_poll(void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + int x, y; + + if (pgc->cga_selected) + { + pgc_cga_poll(pgc); + return; + } +/* Not CGA, so must be native mode */ + if (!pgc->linepos) + { + pgc->vidtime += pgc->dispofftime; + pgc->mapram[0x3DA] |= 1; + pgc->linepos = 1; + if (pgc->cgadispon && pgc->displine < pgc->maxh) + { + if (pgc->displine == 0) + { + video_wait_for_buffer(); + } + /* Don't know why pan needs to be multiplied by -2, but + * the IM1024 driver uses PAN -112 for an offset of + * 224. */ + y = pgc->displine - 2 * pgc->pan_y; + for (x = 0; x < pgc->screenw; x++) + { + if (x + pgc->pan_x < pgc->maxw) + { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[x] = pgc->palette[pgc->vram[y * pgc->maxw + x]]; + } + else + { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[x] = pgc->palette[0]; + } + } + } + else + { + hline(buffer32, 0, pgc->displine & 2047, pgc->screenw, pgc->palette[0]); + } + pgc->displine++; + if (pgc->displine == pgc->screenh) + { + pgc->mapram[0x3DA] |= 8; + pgc->cgadispon = 0; + } + if (pgc->displine == pgc->screenh + 32) + { + pgc->mapram[0x3DA] &= ~8; + pgc->cgadispon = 1; + pgc->displine = 0; + } + } + else + { + if (pgc->cgadispon) + { + pgc->mapram[0x3DA] &= ~1; + } + pgc->vidtime += pgc->dispontime; + pgc->linepos = 0; + + if (pgc->displine == pgc->screenh) + { + if (pgc->screenw != xsize || pgc->screenh != ysize) + { + xsize = pgc->screenw; + ysize = pgc->screenh; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + frames++; + + video_res_x = pgc->screenw; + video_res_y = pgc->screenh; + video_bpp = 8; + pgc->cgablink++; + } + } +} + + +/* Initialise RAM and registers to default values */ +void pgc_reset(pgc_core_t *pgc) +{ + int n; + + memset(pgc->mapram, 0, sizeof(pgc->mapram)); +/* There is no point in emulating the 'CGA disable' jumper as this is only + * appropriate for a dual-head system, not emulated by PCEM */ + pgc->mapram[0x30B] = pgc->cga_enabled = 1; + pgc->mapram[0x3F8] = 0x03; /* Minor version */ + pgc->mapram[0x3F9] = 0x01; /* Minor version */ + pgc->mapram[0x3FB] = 0xA5; /* } */ + pgc->mapram[0x3FC] = 0x5A; /* PGC self-test passed */ + pgc->mapram[0x3FD] = 0x55; /* } */ + pgc->mapram[0x3FE] = 0x5A; /* } */ + + pgc->ascii_mode = 1; /* Start off in ASCII mode */ + pgc->line_pattern = 0xFFFF; + memset(pgc->fill_pattern, 0xFF, sizeof(pgc->fill_pattern)); + pgc->colour = 0xFF; + pgc->tjust_h = 1; + pgc->tjust_v = 1; + + /* Reset panning */ + pgc->pan_x = 0; + pgc->pan_y = 0; + + /* Reset clipping */ + pgc->vp_x1 = 0; + pgc->vp_y1 = 0; + pgc->vp_x2 = pgc->visw - 1; + pgc->vp_y2 = pgc->vish - 1; + + /* Empty command lists */ + for (n = 0; n < 256; n++) + { + pgc->clist[n].wrptr = 0; + pgc->clist[n].rdptr = 0; + pgc->clist[n].repeat = 0; + pgc->clist[n].chain = 0; + } + pgc->clcur = NULL; + /* Select CGA display */ + pgc->cga_selected = -1; + pgc_setdisplay(pgc, pgc->cga_enabled); + pgc->mapram[0x30C] = pgc->cga_enabled; + pgc->mapram[0x30D] = pgc->cga_enabled; + /* Default palette is 0 */ + pgc_init_lut(pgc, 0); + hndl_lutsav(pgc); +} + + +/* Initialisation code common to the PGC and its subclasses. + * + * Pass the 'input byte' function in since this is overridden in + * the IM-1024, and needs to be set before the drawing thread is + * launched */ +void pgc_core_init(pgc_core_t *pgc, int maxw, int maxh, int visw, int vish, + int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock) +{ + int n; + + mem_mapping_add(&pgc->mapping, 0xC6000, 0x800, + pgc_read, NULL, NULL, + pgc_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, pgc); + mem_mapping_add(&pgc->cga_mapping, 0xB8000, 0x8000, + pgc_read, NULL, NULL, + pgc_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, pgc); + io_sethandler(0x3D0, 0x0010, pgc_in, NULL, NULL, pgc_out, NULL, NULL, + pgc); + + pgc->maxw = maxw; + pgc->maxh = maxh; + pgc->visw = visw; + pgc->vish = vish; + pgc->vram = malloc(maxw * maxh); + pgc->cga_vram = malloc(0x4000); + pgc->clist = calloc(256, sizeof(pgc_commandlist_t)); + pgc->clcur = NULL; + pgc->native_pixel_clock = native_pixel_clock; + + memset(pgc->vram, 0, maxw * maxh); + memset(pgc->cga_vram, 0, 0x4000); + /* Empty command lists */ + for (n = 0; n < 256; n++) + { + pgc->clist[n].list = NULL; + pgc->clist[n].listmax = 0; + pgc->clist[n].wrptr = 0; + pgc->clist[n].rdptr = 0; + pgc->clist[n].repeat = 0; + pgc->clist[n].chain = NULL; + } + + pgc_reset(pgc); + pgc->inputbyte = inpbyte; + pgc->pgc_commands = pgc_core_commands; + pgc->pgc_wake_thread = thread_create_event(); + pgc->pgc_thread = thread_create(pgc_core_thread, pgc); + + timer_add(pgc_poll, &pgc->vidtime, TIMER_ALWAYS_ENABLED, pgc); + + timer_add(pgc_wake_timer, &pgc->wake_timer, &pgc->wake_timer, + (void *)pgc); +} + + +/* Initialisation code specific to the PGC */ +void *pgc_standalone_init() +{ + pgc_core_t *pgc = malloc(sizeof(pgc_core_t)); + memset(pgc, 0, sizeof(pgc_core_t)); + + /* Framebuffer and screen are both 640x480 */ + pgc_core_init(pgc, 640, 480, 640, 480, pgc_input_byte, 25175000.0); + return pgc; +} + + +void pgc_close(void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + thread_kill(pgc->pgc_thread); + thread_destroy_event(pgc->pgc_wake_thread); + + if (pgc->cga_vram) + { + free(pgc->cga_vram); + } + if (pgc->vram) + { + free(pgc->vram); + } + free(pgc); +} + +void pgc_speed_changed(void *p) +{ + pgc_core_t *pgc = (pgc_core_t *)p; + + pgc_recalctimings(pgc); +} + + +device_config_t pgc_config[] = +{ + { + .type = -1 + } +}; + +device_t pgc_device = +{ + "PGC", + 0, + pgc_standalone_init, + pgc_close, + NULL, + pgc_speed_changed, + NULL, + NULL, + pgc_config +}; + diff --git a/src/vid_pgc.h b/src/vid_pgc.h new file mode 100644 index 0000000..9d3412d --- /dev/null +++ b/src/vid_pgc.h @@ -0,0 +1,160 @@ +struct pgc_core_t; + +typedef struct pgc_commandlist_t +{ + uint8_t *list; + uint32_t listmax; + uint32_t wrptr; + uint32_t rdptr; + uint32_t repeat; + struct pgc_commandlist_t *chain; +} pgc_commandlist_t; + +int pgc_commandlist_append(pgc_commandlist_t *list, uint8_t v); + +typedef struct pgc_command_t +{ + char ascii[6]; + uint8_t hex; + void (*handler)(struct pgc_core_t *pgc); + int (*parser) (struct pgc_core_t *pgc, pgc_commandlist_t *cl, + int p); + int p; +} pgc_command_t; + + +typedef struct pgc_core_t +{ + mem_mapping_t mapping; + mem_mapping_t cga_mapping; + + pgc_commandlist_t *clist; + pgc_commandlist_t *clcur; + uint8_t mapram[2048]; /* Host <--> PGC communication buffer */ + uint8_t *cga_vram; + uint8_t *vram; + char asc_command[7]; + uint8_t hex_command; + uint32_t palette[256]; + uint32_t userpal[256]; + uint32_t maxw, maxh; /* Maximum framebuffer size */ + uint32_t visw, vish; /* Maximum screen size */ + uint32_t screenw, screenh; + int16_t pan_x, pan_y; + uint16_t win_x1, win_x2, win_y1, win_y2; + uint16_t vp_x1, vp_x2, vp_y1, vp_y2; + int16_t fill_pattern[16]; + int16_t line_pattern; + uint8_t draw_mode; + uint8_t fill_mode; + uint8_t colour; + uint8_t tjust_h; /* Horizontal alignment 1=left 2=centre 3=right*/ + uint8_t tjust_v; /* Vertical alignment 1=bottom 2=centre 3=top*/ + int32_t tsize; /* Horizontal spacing */ + + int32_t x, y, z;/* Drawing position */ + + const pgc_command_t *pgc_commands; + thread_t *pgc_thread; + event_t *pgc_wake_thread; + int wake_timer; + + int waiting_input_fifo; + int waiting_output_fifo; + int waiting_error_fifo; + int cga_enabled; + int cga_selected; + int ascii_mode; + int result_count; + + int fontbase; + int linepos, displine; + int vc; + int cgadispon; + int con, coff, cursoron, cgablink; + int vsynctime, vadj; + uint16_t ma, maback; + int oddeven; + + int dispontime, dispofftime; + int vidtime; + double native_pixel_clock; + + int drawcursor; + + int (*inputbyte)(struct pgc_core_t *pgc, uint8_t *result); + +} pgc_core_t; + +void pgc_init(pgc_core_t *pgc); +void pgc_out(uint16_t addr, uint8_t val, void *p); +uint8_t pgc_in(uint16_t addr, void *p); +void pgc_write(uint32_t addr, uint8_t val, void *p); +uint8_t pgc_read(uint32_t addr, void *p); +void pgc_recalctimings(pgc_core_t *pgc); +void pgc_poll(void *p); +void pgc_reset(pgc_core_t *pgc); +void pgc_wake(pgc_core_t *pgc); +/* Plot a pixel (raster coordinates, current ink) */ +void pgc_plot(pgc_core_t *pgc, uint16_t x, uint16_t y); +void pgc_write_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y, uint8_t ink); +uint8_t pgc_read_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y); +uint8_t *pgc_vram_addr(pgc_core_t *pgc, int16_t x, int16_t y); +/* Draw line (window coordinates) */ +uint16_t pgc_draw_line(pgc_core_t *pgc, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t linemask); +/* Draw line (raster coordinates) */ +uint16_t pgc_draw_line_r(pgc_core_t *pgc, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t linemask); +void pgc_draw_ellipse(pgc_core_t *pgc, int32_t x, int32_t y); +void pgc_fill_polygon(pgc_core_t *pgc, unsigned corners, int32_t *x, int32_t *y); +/* Horizontal line in fill pattern (raster coordinates) */ +void pgc_fill_line_r(pgc_core_t *pgc, int32_t x0, int32_t x1, int32_t y); + +/* Convert to raster coordinates */ +void pgc_sto_raster(pgc_core_t *pgc, int16_t *x, int16_t *y); +void pgc_ito_raster(pgc_core_t *pgc, int32_t *x, int32_t *y); +void pgc_dto_raster(pgc_core_t *pgc, double *x, double *y); + +/* Read/write to the PGC's FIFOs */ +int pgc_input_byte(pgc_core_t *pgc, uint8_t *val); +int pgc_output_byte(pgc_core_t *pgc, uint8_t val); +int pgc_output_string(pgc_core_t *pgc, const char *val); +int pgc_error_byte(pgc_core_t *pgc, uint8_t val); +int pgc_error_string(pgc_core_t *pgc, const char *val); + +int pgc_param_byte(pgc_core_t *pgc, uint8_t *val); +int pgc_param_word(pgc_core_t *pgc, int16_t *val); +int pgc_param_coord(pgc_core_t *pgc, int32_t *val); +int pgc_result_byte(pgc_core_t *pgc, uint8_t val); +int pgc_result_word(pgc_core_t *pgc, int16_t val); +int pgc_result_coord(pgc_core_t *pgc, int32_t val); + +void pgc_sleep(pgc_core_t *pgc); +int pgc_error(pgc_core_t *pgc, int err); +void pgc_core_init(pgc_core_t *pgc, int maxw, int maxh, int visw, int vish, + int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock); +void pgc_speed_changed(void *p); +void pgc_close(void *p); + +void pgc_hndl_lut8(pgc_core_t *pgc); +void pgc_hndl_lut8rd(pgc_core_t *pgc); + +int pgc_parse_bytes(pgc_core_t *pgc, pgc_commandlist_t *cl, int p); +int pgc_parse_words(pgc_core_t *pgc, pgc_commandlist_t *cl, int p); +int pgc_parse_coords(pgc_core_t *pgc, pgc_commandlist_t *cl, int p); + +extern device_t pgc_device; + +#define PGC_ERROR_RANGE 0x01 +#define PGC_ERROR_INTEGER 0x02 +#define PGC_ERROR_MEMORY 0x03 +#define PGC_ERROR_OVERFLOW 0x04 +#define PGC_ERROR_DIGIT 0x05 +#define PGC_ERROR_OPCODE 0x06 +#define PGC_ERROR_RUNNING 0x07 +#define PGC_ERROR_STACK 0x08 +#define PGC_ERROR_TOOLONG 0x09 +#define PGC_ERROR_AREA 0x0A +#define PGC_ERROR_MISSING 0x0B + +/* #define PGCLOG(x) pclog x */ +#define PGCLOG(x) diff --git a/src/video.c b/src/video.c index b416594..7eb151d 100644 --- a/src/video.c +++ b/src/video.c @@ -24,6 +24,7 @@ #include "vid_genius.h" #include "vid_hercules.h" #include "vid_ht216.h" +#include "vid_im1024.h" #include "vid_incolor.h" #include "vid_colorplus.h" #include "vid_mda.h" @@ -35,6 +36,7 @@ #include "vid_pc1640.h" #include "vid_pc200.h" #include "vid_pcjr.h" +#include "vid_pgc.h" #include "vid_ps1_svga.h" #include "vid_s3.h" #include "vid_s3_virge.h" @@ -94,6 +96,7 @@ static VIDEO_CARD video_cards[] = {"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, @@ -101,6 +104,9 @@ static VIDEO_CARD video_cards[] = {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}, +/* Not offered as the emulation is very incomplete + {"Professional Graphics Controller", "pgc", &pgc_device, GFX_PGC, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, +*/ {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, @@ -817,6 +823,7 @@ uint8_t fontdat[2048][8]; uint8_t fontdatm[2048][16]; uint8_t fontdatw[512][32]; /* Wyse700 font */ uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +uint8_t fontdat12x18[256][36]; /* IM1024 font */ uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */ uint8_t fontdatksc5601_user[192][32]; /* Korean KSC-5601 user defined font */ @@ -952,6 +959,13 @@ void loadfont(char *s, fontformat_t format) fread(&fontdatm[c][0], 1, 16, f); } break; + case FONT_IM1024: /* Image Manager 1024 native font */ + for (c=0;c<256;c++) + { + fread(&fontdat12x18[c][0], 1, 36, f); + } + break; + } fclose(f); } diff --git a/src/video.h b/src/video.h index 4194b7a..459abcb 100644 --- a/src/video.h +++ b/src/video.h @@ -93,7 +93,7 @@ typedef enum FONT_T3100E, /* Toshiba T3100e, four fonts */ FONT_KSC5601, /* Korean KSC-5601 */ FONT_SIGMA400, /* Sigma Color 400, 8x8 and 8x16 */ - + FONT_IM1024, /* Image Manager 1024 */ } fontformat_t; void loadfont(char *s, fontformat_t format); From 1db2fc69083c2ee90efd9ffbde8e1cd01117b237 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 23 Apr 2019 21:23:14 +0100 Subject: [PATCH 0687/1050] Use mmap() to allocate Voodoo recompiler memory on Linux instead of malloc() + mprotect(). Based on patch from Martin_Riarte. --- src/vid_voodoo_codegen_x86-64.h | 14 ++------------ src/vid_voodoo_codegen_x86.h | 14 ++------------ 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index d729231..c8bb5f8 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -3354,17 +3354,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) #if WIN64 voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2); -#endif - -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)voodoo->codegen_data & pagemask); - len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } + voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); #endif for (c = 0; c < 256; c++) @@ -3394,7 +3384,7 @@ static void voodoo_codegen_close(voodoo_t *voodoo) #if WIN64 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else - free(voodoo->codegen_data); + munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); #endif } diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 48b0cca..b09ed0e 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -3292,17 +3292,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) #if defined WIN32 || defined _WIN32 || defined _WIN32 voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); -#endif - -#if defined(__linux__) || defined(__APPLE__) - start = (void *)((long)voodoo->codegen_data & pagemask); - len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM*2) + pagesize) & pagemask; - if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) - { - perror("mprotect"); - exit(-1); - } + voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); #endif for (c = 0; c < 256; c++) @@ -3332,6 +3322,6 @@ static void voodoo_codegen_close(voodoo_t *voodoo) #if defined WIN32 || defined _WIN32 || defined _WIN32 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else - free(voodoo->codegen_data); + munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); #endif } From 9ee37e424eadf599fb3f9ce8b4cad68419ccf46e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Apr 2019 12:15:26 +0100 Subject: [PATCH 0688/1050] Rename codegen_backend.c to codegen_block.c --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 4 ++-- src/{codegen_backend.c => codegen_block.c} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/{codegen_backend.c => codegen_block.c} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 7746e30..ada57f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ +cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c \ cpu_tables.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 9c28a55..a1aa7ed 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -8,8 +8,8 @@ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno CXXFLAGS = $(CFLAGS) OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ - codegen_backend.o codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o \ - codegen_backend_x86_ops_sse.o codegen_backend_x86_uops.o codegen_ir.o codegen_ops.o \ + codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ + codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o codegen_ops_jump.o \ codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ diff --git a/src/codegen_backend.c b/src/codegen_block.c similarity index 100% rename from src/codegen_backend.c rename to src/codegen_block.c From 38b9ada47b9587c377dbd88a7e5ce56ec6669d73 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Apr 2019 12:28:39 +0100 Subject: [PATCH 0689/1050] Fix incorrect op/uop separation for PUNPCKH* on x86 backend. --- src/codegen_backend_x86_ops_sse.c | 28 +++++++--------------------- src/codegen_backend_x86_ops_sse.h | 5 ++--- src/codegen_backend_x86_uops.c | 9 ++++++--- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/codegen_backend_x86_ops_sse.c b/src/codegen_backend_x86_ops_sse.c index dc20d34..ed603e7 100644 --- a/src/codegen_backend_x86_ops_sse.c +++ b/src/codegen_backend_x86_ops_sse.c @@ -429,6 +429,13 @@ void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } +void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, shuffle); +} + void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { codegen_alloc_bytes(block, 5); @@ -520,27 +527,6 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_alloc_bytes(block, 4); diff --git a/src/codegen_backend_x86_ops_sse.h b/src/codegen_backend_x86_ops_sse.h index 596f361..e8afdcb 100644 --- a/src/codegen_backend_x86_ops_sse.h +++ b/src/codegen_backend_x86_ops_sse.h @@ -88,6 +88,8 @@ void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle); + void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -96,9 +98,6 @@ void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c09512e..8690266 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2250,7 +2250,8 @@ static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ } #ifdef RECOMPILER_DEBUG else @@ -2265,7 +2266,8 @@ static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ } #ifdef RECOMPILER_DEBUG else @@ -2280,7 +2282,8 @@ static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ } #ifdef RECOMPILER_DEBUG else From 1242754343e3da629968074bd4a0d36e1a767dd3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Apr 2019 17:48:00 +0100 Subject: [PATCH 0690/1050] Fix IM-1024 timing. --- src/vid_pgc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_pgc.c b/src/vid_pgc.c index 311e2f2..5f61dfa 100644 --- a/src/vid_pgc.c +++ b/src/vid_pgc.c @@ -1984,7 +1984,7 @@ void pgc_recalctimings(pgc_core_t *pgc) /* Use a fixed 640 columns, like the T3100e */ disptime = pgc->screenw + 11; _dispontime = pgc->screenw * pixel_clock; - _dispofftime = (disptime - _dispontime) * pixel_clock; + _dispofftime = (disptime - pgc->screenw) * pixel_clock; pgc->dispontime = (uint64_t)_dispontime; pgc->dispofftime = (uint64_t)_dispofftime; } From b3f61c09c079fc6e952e36dc8dccf87eb842d87e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Apr 2019 17:49:28 +0100 Subject: [PATCH 0691/1050] Clamp 286/386 prefetch queue size. --- src/386_dynarec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index eaa2041..fd2861b 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -212,6 +212,8 @@ static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int } prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; } static void prefetch_flush() From 2f19e036f2a16f57f7c66fc8a11302d9409ce58e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Apr 2019 17:49:54 +0100 Subject: [PATCH 0692/1050] Disable fflush in pclog() accidentally enable in a previous commit. --- src/pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pc.c b/src/pc.c index 9deea6d..c6f0469 100644 --- a/src/pc.c +++ b/src/pc.c @@ -104,7 +104,7 @@ void pclog(const char *format, ...) vsprintf(buf, format, ap); va_end(ap); fputs(buf,pclogf); - fflush(pclogf); +// fflush(pclogf); #endif } From c8f012f7f9d3db98d90f10117b28fb3c6d8d7d96 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Apr 2019 21:25:52 +0100 Subject: [PATCH 0693/1050] Makefile fixes. --- src/Makefile.am | 4 +-- src/Makefile.mingw-wx-sdl2 | 8 ++--- src/Makefile.mingw-wx-sdl2-network | 52 ++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a9e94d2..2df6e70 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -132,8 +132,8 @@ pcem_CFLAGS += -DRELEASE_BUILD pcem_CXXFLAGS += -DRELEASE_BUILD endif -pcem_CFLAGS += -mtune=cortex-a53 -pcem_CXXFLAGS += -mtune=cortex-a53 +#pcem_CFLAGS += -mtune=cortex-a53 +#pcem_CXXFLAGS += -mtune=cortex-a53 #pcem_LDFLAGS = -flto -O3 -mtune=cortex-a15 # pcem_CFLAGS += -fprofile-use diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 1f36ced..7d195ab 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/MinGWget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer386sx.o ali1429.o amstrad.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ @@ -18,13 +18,13 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer38 codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o \ - fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430lx.o i430fx.o i430vx.o ide.o \ + fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ - piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ + piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ @@ -32,7 +32,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acer38 sound_ym7128.o soundopenal.o sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ - vid_et4000w32i.o vid_genius.o vid_hercules.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o \ + vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 6d80726..4e8907e 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,25 +6,43 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o cbm_io.o cdrom-ioctl.o cdrom-image.o \ - cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o \ - device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o \ - i430vx.o ide.o ide_atapi.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o \ - mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o \ - scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ + cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ + codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ + codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ + codegen_ops_3dnow.o codegen_ops_branch.o codegen_ops_arith.o codegen_ops_fpu_arith.o \ + codegen_ops_fpu_constant.o codegen_ops_fpu_loadstore.o codegen_ops_fpu_misc.o codegen_ops_helpers.o codegen_ops_jump.o \ + codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ + codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ + codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ + codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ + dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o \ + fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ + ide_atapi.o ide_sff8038i.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ + mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ + mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ + piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ + scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ + sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ + vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ + vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ + vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ - vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o zenith.o win-midi.o \ - wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o \ - wx-sdl2.o wx-config.o wx-deviceconfig.o wx-hostconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ - wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o wx.res + vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ + vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o wx-main.o \ + wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ + wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ + wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ + wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o \ + wx-joystickconfig.o wx-createdisc.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 NETOBJ = ne2000.o nethandler.o From 22ebbec20136d2513c2753dc8e5021a8b63a5370 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 Apr 2019 08:14:51 +0100 Subject: [PATCH 0694/1050] Makefile.am fixes. --- Makefile.in | 24 +- configure | 317 ++++-- src/Makefile.am | 43 +- src/Makefile.in | 2447 ++++++++++++++++++++++++----------------------- 4 files changed, 1525 insertions(+), 1306 deletions(-) diff --git a/Makefile.in b/Makefile.in index bcd0ae0..903d123 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -133,7 +133,7 @@ am__recursive_targets = \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir distdir-am dist dist-all distcheck + cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -308,6 +308,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -341,8 +342,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -460,10 +461,7 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -528,7 +526,7 @@ distdir-am: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -554,7 +552,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -572,7 +570,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -582,7 +580,7 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff --git a/configure b/configure index a6186e3..7b59503 100755 --- a/configure +++ b/configure @@ -647,6 +647,7 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE +am__quote am__include DEPDIR OBJEXT @@ -710,6 +711,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -728,8 +730,7 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL -am__quote' +SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -803,6 +804,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1055,6 +1057,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1192,7 +1203,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1345,6 +1356,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -2124,7 +2136,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac -am__api_version='1.16' +am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2640,8 +2652,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -2692,7 +2704,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3554,45 +3566,45 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 -$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } -cat > confinc.mk << 'END' + +am_make=${MAKE-make} +cat > confinc << 'END' am__doit: - @echo this is the am__doit target >confinc.out + @echo this is the am__doit target .PHONY: am__doit END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 - (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - case $?:`cat confinc.out 2>/dev/null` in #( - '0:this is the am__doit target') : - case $s in #( - BSD) : - am__include='.include' am__quote='"' ;; #( - *) : - am__include='include' am__quote='' ;; -esac ;; #( - *) : - ;; +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; esac - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 -$as_echo "${_am_result}" >&6; } +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -4489,8 +4501,8 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 -$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 +$as_echo_n "checking for SDL... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -4530,7 +4542,7 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -4548,7 +4560,7 @@ fi sdl_pc=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } sdl_pc=no else @@ -5444,6 +5456,110 @@ fi build_linux="yes" ;; + *-*-freebsd*) + CFLAGS="$CFLAGS -I/usr/local/include" + CXXFLAGS="$CXXFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +$as_echo_n "checking for glGetError in -lGL... " >&6; } +if ${ac_cv_lib_GL_glGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGL $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char glGetError (); +int +main () +{ +return glGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GL_glGetError=yes +else + ac_cv_lib_GL_glGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +$as_echo "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGL 1 +_ACEOF + + LIBS="-lGL $LIBS" + +else + \ + echo "You need to install the OpenGL library." + exit -1 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +$as_echo_n "checking for alGetError in -lopenal... " >&6; } +if ${ac_cv_lib_openal_alGetError+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lopenal $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char alGetError (); +int +main () +{ +return alGetError (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_openal_alGetError=yes +else + ac_cv_lib_openal_alGetError=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +$as_echo "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBOPENAL 1 +_ACEOF + + LIBS="-lopenal $LIBS" + +else + \ + echo "You need to install the OpenAL library." + exit -1 +fi + + build_other="yes" + ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 $as_echo_n "checking for glGetError in -lGL... " >&6; } @@ -6371,7 +6487,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF @@ -6817,35 +6933,29 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - case $CONFIG_FILES in #( - *\'*) : - eval set x "$CONFIG_FILES" ;; #( - *) : - set x $CONFIG_FILES ;; #( - *) : - ;; -esac + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf + for mf do # Strip MF so we end up with the name of the file. - am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`$as_dirname -- "$am_mf" || -$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$am_mf" : 'X\(//\)[^/]' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$am_mf" | + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -6863,48 +6973,53 @@ $as_echo X"$am_mf" | q } s/.*/./; q'` - am_filepart=`$as_basename -- "$am_mf" || -$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$am_mf" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } - /^X\/\(\/\/\)$/{ + /^X\(\/\/\)[^/].*/{ s//\1/ q } - /^X\/\(\/\).*/{ + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` - { echo "$as_me:$LINENO: cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles" >&5 - (cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } || am_rc=$? + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done done - if test $am_rc -ne 0; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking). -See \`config.log' for more details" "$LINENO" 5; } - fi - { am_dirpart=; unset am_dirpart;} - { am_filepart=; unset am_filepart;} - { am_mf=; unset am_mf;} - { am_rc=; unset am_rc;} - rm -f conftest-deps.mk } ;; diff --git a/src/Makefile.am b/src/Makefile.am index 2df6e70..416bc92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,26 +23,33 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c codegen_ops_shift.c \ -codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c \ -cpu_tables.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 \ -laserxt.c lpt.c lpt_dac.c lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c neat.c nmi.c nvr.c olivetti_m24.c \ -opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ -serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 sst39sf010.c tandy_eeprom.c tandy_rom.c \ -t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ -vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \ -vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ +pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2168.c acc3221.c acer386sx.c \ +ali1429.c amstrad.c cassette.c cbm_io.c cdrom-image.cc cdrom-null.c cmd640.c codegen.c codegen_accumulate.c \ +codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c \ +codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c \ +codegen_ops_fpu_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c codegen_ops_mmx_loadstore.c \ +codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_helpers.c codegen_ops_jump.c \ +codegen_ops_logic.c codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c \ +codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c \ +codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ +disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ +hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c lpt_dss.c \ +mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \ +neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ +ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ +scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ +sst39sf010.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c \ +vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c \ +vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ +vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c vt82c586b.c \ -w83877tf.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc \ -codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c +w83877tf.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.in b/src/Makefile.in index ba15208..038f20f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -97,11 +97,11 @@ bin_PROGRAMS = pcem$(EXEEXT) @USE_ALSA_TRUE@am__append_3 = -lasound @USE_ALSA_TRUE@am__append_4 = midi_alsa.c @USE_ALSA_FALSE@am__append_5 = wx-sdl2-midi.c -@CPU_I386_TRUE@am__append_6 = codegen_backend_x86.c codegen_backend_x86_uops.c +@CPU_I386_TRUE@am__append_6 = codegen_backend_x86.c codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c codegen_backend_x86_ops_sse.c codegen_backend_x86_uops.c @CPU_I386_TRUE@am__append_7 = -msse2 -@CPU_X86_64_TRUE@am__append_8 = codegen_backend_x86-64.c codegen_backend_x86-64_uops.c -@CPU_ARM_TRUE@am__append_9 = codegen_backend_arm.c codegen_backend_arm_uops.c -@CPU_ARM64_TRUE@am__append_10 = codegen_backend_arm64.c codegen_backend_arm64_uops.c +@CPU_X86_64_TRUE@am__append_8 = codegen_backend_x86-64.c codegen_backend_x86-64_ops.c codegen_backend_x86-64_ops_sse.c codegen_backend_x86-64_uops.c +@CPU_ARM_TRUE@am__append_9 = codegen_backend_arm.c codegen_backend_arm_ops.c codegen_backend_arm_uops.c +@CPU_ARM64_TRUE@am__append_10 = codegen_backend_arm64.c codegen_backend_arm64_imm.c codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c @USE_NETWORKING_TRUE@am__append_11 = -DUSE_NETWORKING @USE_NETWORKING_TRUE@am__append_12 = -DUSE_NETWORKING # SLiRP @@ -139,69 +139,89 @@ 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 \ - acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c \ +am__pcem_SOURCES_DIST = 386.c 386_common.c 386_dynarec.c \ + 386_dynarec_ops.c 808x.c acc2036.c acc2168.c acc3221.c \ + acer386sx.c ali1429.c amstrad.c cassette.c cbm_io.c \ cdrom-image.cc cdrom-null.c cmd640.c codegen.c \ - codegen_backend.c codegen_ir.c codegen_timing_486.c \ + codegen_accumulate.c codegen_allocator.c codegen_block.c \ + codegen_ir.c codegen_ops.c codegen_ops_3dnow.c \ + codegen_ops_arith.c codegen_ops_branch.c \ + codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c \ + codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c \ + codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c \ + codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c \ + codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c \ + codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c \ + codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c \ + codegen_ops_stack.c codegen_reg.c codegen_timing_486.c \ codegen_timing_686.c codegen_timing_common.c \ - codegen_timing_pentium.c codegen_timing_winchip.c compaq.c \ - config.c cpu.c dells200.c device.c disc.c disc_fdi.c \ - disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c \ - fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c hdd_file.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.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 \ + codegen_timing_k6.c codegen_timing_pentium.c \ + codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c \ + config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ + disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c \ + fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ + hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c \ + ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ - neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c \ - pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ - ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ - scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ - serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ - sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ + mvp3.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c \ + pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ + ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c \ + rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c \ + scsi_cd.c scsi_hd.c scsi_zip.c serial.c sio.c sis496.c \ + sl82c460.c sound.c sound_ad1848.c sound_adlib.c \ + sound_adlibgold.c sound_audiopci.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 sst39sf010.c tandy_eeprom.c \ tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c \ - vid_et4000w32.c vid_genius.c vid_hercules.c vid_icd2061.c \ - vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c \ - vid_oti037.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_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c \ + vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c \ + vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c \ + vid_paradise.c vid_pc200.c vid_pc1512.c vid_pc1640.c \ + vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c \ + vid_sdac_ramdac.c vid_sigma.c vid_stg_ramdac.c vid_svga.c \ vid_svga_render.c vid_t1000.c vid_t3100e.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 \ - vid_wy700.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc \ - sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ - dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ - wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ - wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ - wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ - wx-status.cc wx-sdl2-status.c wx-thread.c wx-common.c \ - wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ - wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ - wx-createdisc.cc wx-resources.cpp midi_alsa.c wx-sdl2-midi.c \ - codegen_backend_x86.c codegen_backend_x86_uops.c \ - codegen_backend_x86-64.c codegen_backend_x86-64_uops.c \ - codegen_backend_arm.c codegen_backend_arm_uops.c \ - codegen_backend_arm64.c codegen_backend_arm64_uops.c ne2000.c \ - nethandler.c wx-hostconfig.c slirp/bootp.c slirp/cksum.c \ - slirp/debug.c slirp/if.c slirp/ip_icmp.c slirp/ip_input.c \ - slirp/ip_output.c slirp/mbuf.c slirp/misc.c slirp/queue.c \ - slirp/sbuf.c slirp/slirp.c slirp/socket.c slirp/tcp_input.c \ + vid_wy700.c vt82c586b.c w83877tf.c x86seg.c x87.c xi8088.c \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ + wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ + wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ + wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ + wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ + wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ + midi_alsa.c wx-sdl2-midi.c codegen_backend_x86.c \ + codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c \ + codegen_backend_x86_ops_sse.c codegen_backend_x86_uops.c \ + codegen_backend_x86-64.c codegen_backend_x86-64_ops.c \ + codegen_backend_x86-64_ops_sse.c codegen_backend_x86-64_uops.c \ + codegen_backend_arm.c codegen_backend_arm_ops.c \ + codegen_backend_arm_uops.c codegen_backend_arm64.c \ + codegen_backend_arm64_imm.c codegen_backend_arm64_ops.c \ + codegen_backend_arm64_uops.c ne2000.c nethandler.c \ + wx-hostconfig.c slirp/bootp.c slirp/cksum.c slirp/debug.c \ + slirp/if.c slirp/ip_icmp.c slirp/ip_input.c slirp/ip_output.c \ + slirp/mbuf.c slirp/misc.c slirp/queue.c slirp/sbuf.c \ + slirp/slirp.c slirp/socket.c slirp/tcp_input.c \ slirp/tcp_output.c slirp/tcp_subr.c slirp/tcp_timer.c \ slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c wx-sdl2-display.c \ cdrom-ioctl-dummy.c cdrom-ioctl-osx.c cdrom-ioctl.c \ @@ -210,13 +230,21 @@ am__dirstamp = $(am__leading_dot)dirstamp @USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) @USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) @CPU_I386_TRUE@am__objects_3 = pcem-codegen_backend_x86.$(OBJEXT) \ +@CPU_I386_TRUE@ pcem-codegen_backend_x86_ops.$(OBJEXT) \ +@CPU_I386_TRUE@ pcem-codegen_backend_x86_ops_fpu.$(OBJEXT) \ +@CPU_I386_TRUE@ pcem-codegen_backend_x86_ops_sse.$(OBJEXT) \ @CPU_I386_TRUE@ pcem-codegen_backend_x86_uops.$(OBJEXT) @CPU_X86_64_TRUE@am__objects_4 = \ @CPU_X86_64_TRUE@ pcem-codegen_backend_x86-64.$(OBJEXT) \ +@CPU_X86_64_TRUE@ pcem-codegen_backend_x86-64_ops.$(OBJEXT) \ +@CPU_X86_64_TRUE@ pcem-codegen_backend_x86-64_ops_sse.$(OBJEXT) \ @CPU_X86_64_TRUE@ pcem-codegen_backend_x86-64_uops.$(OBJEXT) @CPU_ARM_TRUE@am__objects_5 = pcem-codegen_backend_arm.$(OBJEXT) \ +@CPU_ARM_TRUE@ pcem-codegen_backend_arm_ops.$(OBJEXT) \ @CPU_ARM_TRUE@ pcem-codegen_backend_arm_uops.$(OBJEXT) @CPU_ARM64_TRUE@am__objects_6 = pcem-codegen_backend_arm64.$(OBJEXT) \ +@CPU_ARM64_TRUE@ pcem-codegen_backend_arm64_imm.$(OBJEXT) \ +@CPU_ARM64_TRUE@ pcem-codegen_backend_arm64_ops.$(OBJEXT) \ @CPU_ARM64_TRUE@ pcem-codegen_backend_arm64_uops.$(OBJEXT) @USE_NETWORKING_TRUE@am__objects_7 = pcem-ne2000.$(OBJEXT) \ @USE_NETWORKING_TRUE@ pcem-nethandler.$(OBJEXT) \ @@ -248,32 +276,59 @@ am__dirstamp = $(am__leading_dot)dirstamp @OS_MACOSX_TRUE@ pcem-wx-sdl2-display.$(OBJEXT) @OS_WINDOWS_TRUE@am__objects_11 = pcem-cdrom-ioctl.$(OBJEXT) \ @OS_WINDOWS_TRUE@ pcem-wx-sdl2-display-win.$(OBJEXT) -am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ - pcem-386_dynarec_ops.$(OBJEXT) pcem-808x.$(OBJEXT) \ - pcem-acc2036.$(OBJEXT) pcem-acer386sx.$(OBJEXT) \ - pcem-ali1429.$(OBJEXT) pcem-amstrad.$(OBJEXT) \ +am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ + pcem-386_dynarec.$(OBJEXT) pcem-386_dynarec_ops.$(OBJEXT) \ + pcem-808x.$(OBJEXT) pcem-acc2036.$(OBJEXT) \ + pcem-acc2168.$(OBJEXT) pcem-acc3221.$(OBJEXT) \ + pcem-acer386sx.$(OBJEXT) pcem-ali1429.$(OBJEXT) \ + pcem-amstrad.$(OBJEXT) pcem-cassette.$(OBJEXT) \ pcem-cbm_io.$(OBJEXT) pcem-cdrom-image.$(OBJEXT) \ pcem-cdrom-null.$(OBJEXT) pcem-cmd640.$(OBJEXT) \ - pcem-codegen.$(OBJEXT) pcem-codegen_backend.$(OBJEXT) \ - pcem-codegen_ir.$(OBJEXT) pcem-codegen_timing_486.$(OBJEXT) \ + pcem-codegen.$(OBJEXT) pcem-codegen_accumulate.$(OBJEXT) \ + pcem-codegen_allocator.$(OBJEXT) pcem-codegen_block.$(OBJEXT) \ + pcem-codegen_ir.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ + pcem-codegen_ops_3dnow.$(OBJEXT) \ + pcem-codegen_ops_arith.$(OBJEXT) \ + pcem-codegen_ops_branch.$(OBJEXT) \ + pcem-codegen_ops_fpu_arith.$(OBJEXT) \ + pcem-codegen_ops_fpu_constant.$(OBJEXT) \ + pcem-codegen_ops_fpu_loadstore.$(OBJEXT) \ + pcem-codegen_ops_fpu_misc.$(OBJEXT) \ + pcem-codegen_ops_mmx_arith.$(OBJEXT) \ + pcem-codegen_ops_mmx_cmp.$(OBJEXT) \ + pcem-codegen_ops_mmx_loadstore.$(OBJEXT) \ + pcem-codegen_ops_mmx_logic.$(OBJEXT) \ + pcem-codegen_ops_mmx_pack.$(OBJEXT) \ + pcem-codegen_ops_mmx_shift.$(OBJEXT) \ + pcem-codegen_ops_helpers.$(OBJEXT) \ + pcem-codegen_ops_jump.$(OBJEXT) \ + pcem-codegen_ops_logic.$(OBJEXT) \ + pcem-codegen_ops_shift.$(OBJEXT) \ + pcem-codegen_ops_misc.$(OBJEXT) pcem-codegen_ops_mov.$(OBJEXT) \ + pcem-codegen_ops_stack.$(OBJEXT) pcem-codegen_reg.$(OBJEXT) \ + pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_common.$(OBJEXT) \ + pcem-codegen_timing_k6.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ - pcem-codegen_timing_winchip.$(OBJEXT) pcem-compaq.$(OBJEXT) \ + pcem-codegen_timing_winchip.$(OBJEXT) \ + pcem-codegen_timing_winchip2.$(OBJEXT) pcem-compaq.$(OBJEXT) \ pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) \ - pcem-dells200.$(OBJEXT) pcem-device.$(OBJEXT) \ - pcem-disc.$(OBJEXT) pcem-disc_fdi.$(OBJEXT) \ - pcem-disc_img.$(OBJEXT) pcem-disc_sector.$(OBJEXT) \ - pcem-dma.$(OBJEXT) pcem-esdi_at.$(OBJEXT) pcem-fdc.$(OBJEXT) \ + pcem-cpu_tables.$(OBJEXT) pcem-dells200.$(OBJEXT) \ + pcem-device.$(OBJEXT) pcem-disc.$(OBJEXT) \ + pcem-disc_fdi.$(OBJEXT) pcem-disc_img.$(OBJEXT) \ + pcem-disc_sector.$(OBJEXT) pcem-dma.$(OBJEXT) \ + pcem-esdi_at.$(OBJEXT) pcem-fdc.$(OBJEXT) \ pcem-fdc37c665.$(OBJEXT) pcem-fdd.$(OBJEXT) \ pcem-fdi2raw.$(OBJEXT) pcem-gameport.$(OBJEXT) \ pcem-hdd.$(OBJEXT) pcem-hdd_esdi.$(OBJEXT) \ pcem-hdd_file.$(OBJEXT) pcem-headland.$(OBJEXT) \ pcem-i430lx.$(OBJEXT) pcem-i430fx.$(OBJEXT) \ - pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ - pcem-ide_atapi.$(OBJEXT) pcem-intel.$(OBJEXT) \ - pcem-intel_flash.$(OBJEXT) pcem-io.$(OBJEXT) \ - pcem-jim.$(OBJEXT) pcem-joystick_ch_flightstick_pro.$(OBJEXT) \ + pcem-i430hx.$(OBJEXT) pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ + pcem-ide_atapi.$(OBJEXT) pcem-ide_sff8038i.$(OBJEXT) \ + pcem-intel.$(OBJEXT) pcem-intel_flash.$(OBJEXT) \ + pcem-io.$(OBJEXT) pcem-jim.$(OBJEXT) \ + pcem-joystick_ch_flightstick_pro.$(OBJEXT) \ pcem-joystick_standard.$(OBJEXT) \ pcem-joystick_sw_pad.$(OBJEXT) pcem-joystick_tm_fcs.$(OBJEXT) \ pcem-keyboard.$(OBJEXT) pcem-keyboard_amstrad.$(OBJEXT) \ @@ -286,14 +341,14 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-mfm_xebec.$(OBJEXT) pcem-model.$(OBJEXT) \ pcem-mouse.$(OBJEXT) pcem-mouse_msystems.$(OBJEXT) \ pcem-mouse_ps2.$(OBJEXT) pcem-mouse_serial.$(OBJEXT) \ - pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ - pcem-olivetti_m24.$(OBJEXT) pcem-opti495.$(OBJEXT) \ - pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) pcem-pc87306.$(OBJEXT) \ - pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) \ - pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) pcem-ps1.$(OBJEXT) \ - pcem-ps2.$(OBJEXT) pcem-ps2_mca.$(OBJEXT) \ + pcem-mvp3.$(OBJEXT) pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) \ + pcem-nvr.$(OBJEXT) pcem-olivetti_m24.$(OBJEXT) \ + pcem-opti495.$(OBJEXT) pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) \ + pcem-pc87306.$(OBJEXT) pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) \ + pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) \ + pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) pcem-ps2_mca.$(OBJEXT) \ pcem-ps2_nvr.$(OBJEXT) pcem-nvr_tc8521.$(OBJEXT) \ - pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) \ + pcem-pzx.$(OBJEXT) pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) \ pcem-rtc_tc8521.$(OBJEXT) pcem-scat.$(OBJEXT) \ pcem-scsi.$(OBJEXT) pcem-scsi_53c400.$(OBJEXT) \ pcem-scsi_aha1540.$(OBJEXT) pcem-scsi_cd.$(OBJEXT) \ @@ -310,37 +365,40 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-sound_sn76489.$(OBJEXT) pcem-sound_speaker.$(OBJEXT) \ pcem-sound_ssi2001.$(OBJEXT) pcem-sound_wss.$(OBJEXT) \ pcem-sound_ym7128.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ - pcem-tandy_eeprom.$(OBJEXT) pcem-tandy_rom.$(OBJEXT) \ - pcem-t1000.$(OBJEXT) pcem-t3100e.$(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_colorplus.$(OBJEXT) pcem-vid_compaq_cga.$(OBJEXT) \ - pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ - pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ - pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ - pcem-vid_ics2595.$(OBJEXT) pcem-vid_incolor.$(OBJEXT) \ - pcem-vid_mda.$(OBJEXT) pcem-vid_olivetti_m24.$(OBJEXT) \ - pcem-vid_oti037.$(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_ps1_svga.$(OBJEXT) \ + pcem-sst39sf010.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ + pcem-tandy_rom.$(OBJEXT) pcem-t1000.$(OBJEXT) \ + pcem-t3100e.$(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_colorplus.$(OBJEXT) \ + pcem-vid_compaq_cga.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ + pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ + pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ + pcem-vid_ht216.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ + pcem-vid_ics2595.$(OBJEXT) pcem-vid_im1024.$(OBJEXT) \ + pcem-vid_incolor.$(OBJEXT) pcem-vid_mda.$(OBJEXT) \ + pcem-vid_olivetti_m24.$(OBJEXT) pcem-vid_oti037.$(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_pgc.$(OBJEXT) pcem-vid_ps1_svga.$(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_t1000.$(OBJEXT) pcem-vid_t3100e.$(OBJEXT) \ - pcem-vid_tandy.$(OBJEXT) pcem-vid_tandysl.$(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-vid_wy700.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ - pcem-x87.$(OBJEXT) pcem-xi8088.$(OBJEXT) pcem-xtide.$(OBJEXT) \ - pcem-sound_dbopl.$(OBJEXT) pcem-sound_resid.$(OBJEXT) \ - dosbox/pcem-cdrom_image.$(OBJEXT) dosbox/pcem-dbopl.$(OBJEXT) \ - dosbox/pcem-nukedopl.$(OBJEXT) \ + pcem-vid_sdac_ramdac.$(OBJEXT) pcem-vid_sigma.$(OBJEXT) \ + pcem-vid_stg_ramdac.$(OBJEXT) pcem-vid_svga.$(OBJEXT) \ + pcem-vid_svga_render.$(OBJEXT) pcem-vid_t1000.$(OBJEXT) \ + pcem-vid_t3100e.$(OBJEXT) pcem-vid_tandy.$(OBJEXT) \ + pcem-vid_tandysl.$(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-vid_wy700.$(OBJEXT) \ + pcem-vt82c586b.$(OBJEXT) pcem-w83877tf.$(OBJEXT) \ + pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xi8088.$(OBJEXT) \ + pcem-xtide.$(OBJEXT) pcem-sound_dbopl.$(OBJEXT) \ + pcem-sound_resid.$(OBJEXT) dosbox/pcem-cdrom_image.$(OBJEXT) \ + dosbox/pcem-dbopl.$(OBJEXT) dosbox/pcem-nukedopl.$(OBJEXT) \ dosbox/pcem-vid_cga_comp.$(OBJEXT) \ resid-fp/pcem-convolve.$(OBJEXT) \ resid-fp/pcem-convolve-sse.$(OBJEXT) \ @@ -393,194 +451,7 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/pcem-386.Po \ - ./$(DEPDIR)/pcem-386_dynarec.Po \ - ./$(DEPDIR)/pcem-386_dynarec_ops.Po ./$(DEPDIR)/pcem-808x.Po \ - ./$(DEPDIR)/pcem-acc2036.Po ./$(DEPDIR)/pcem-acer386sx.Po \ - ./$(DEPDIR)/pcem-ali1429.Po ./$(DEPDIR)/pcem-amstrad.Po \ - ./$(DEPDIR)/pcem-cbm_io.Po ./$(DEPDIR)/pcem-cdrom-image.Po \ - ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po \ - ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po \ - ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po \ - ./$(DEPDIR)/pcem-cdrom-ioctl.Po ./$(DEPDIR)/pcem-cdrom-null.Po \ - ./$(DEPDIR)/pcem-cmd640.Po ./$(DEPDIR)/pcem-codegen.Po \ - ./$(DEPDIR)/pcem-codegen_backend.Po \ - ./$(DEPDIR)/pcem-codegen_backend_arm.Po \ - ./$(DEPDIR)/pcem-codegen_backend_arm64.Po \ - ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po \ - ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po \ - ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po \ - ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po \ - ./$(DEPDIR)/pcem-codegen_backend_x86.Po \ - ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po \ - ./$(DEPDIR)/pcem-codegen_ir.Po \ - ./$(DEPDIR)/pcem-codegen_timing_486.Po \ - ./$(DEPDIR)/pcem-codegen_timing_686.Po \ - ./$(DEPDIR)/pcem-codegen_timing_common.Po \ - ./$(DEPDIR)/pcem-codegen_timing_pentium.Po \ - ./$(DEPDIR)/pcem-codegen_timing_winchip.Po \ - ./$(DEPDIR)/pcem-compaq.Po ./$(DEPDIR)/pcem-config.Po \ - ./$(DEPDIR)/pcem-cpu.Po ./$(DEPDIR)/pcem-dells200.Po \ - ./$(DEPDIR)/pcem-device.Po ./$(DEPDIR)/pcem-disc.Po \ - ./$(DEPDIR)/pcem-disc_fdi.Po ./$(DEPDIR)/pcem-disc_img.Po \ - ./$(DEPDIR)/pcem-disc_sector.Po ./$(DEPDIR)/pcem-dma.Po \ - ./$(DEPDIR)/pcem-esdi_at.Po ./$(DEPDIR)/pcem-fdc.Po \ - ./$(DEPDIR)/pcem-fdc37c665.Po ./$(DEPDIR)/pcem-fdd.Po \ - ./$(DEPDIR)/pcem-fdi2raw.Po ./$(DEPDIR)/pcem-gameport.Po \ - ./$(DEPDIR)/pcem-hdd.Po ./$(DEPDIR)/pcem-hdd_esdi.Po \ - ./$(DEPDIR)/pcem-hdd_file.Po ./$(DEPDIR)/pcem-headland.Po \ - ./$(DEPDIR)/pcem-i430fx.Po ./$(DEPDIR)/pcem-i430lx.Po \ - ./$(DEPDIR)/pcem-i430vx.Po ./$(DEPDIR)/pcem-ide.Po \ - ./$(DEPDIR)/pcem-ide_atapi.Po ./$(DEPDIR)/pcem-intel.Po \ - ./$(DEPDIR)/pcem-intel_flash.Po ./$(DEPDIR)/pcem-io.Po \ - ./$(DEPDIR)/pcem-jim.Po \ - ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po \ - ./$(DEPDIR)/pcem-joystick_standard.Po \ - ./$(DEPDIR)/pcem-joystick_sw_pad.Po \ - ./$(DEPDIR)/pcem-joystick_tm_fcs.Po \ - ./$(DEPDIR)/pcem-keyboard.Po \ - ./$(DEPDIR)/pcem-keyboard_amstrad.Po \ - ./$(DEPDIR)/pcem-keyboard_at.Po \ - ./$(DEPDIR)/pcem-keyboard_olim24.Po \ - ./$(DEPDIR)/pcem-keyboard_pcjr.Po \ - ./$(DEPDIR)/pcem-keyboard_xt.Po ./$(DEPDIR)/pcem-laserxt.Po \ - ./$(DEPDIR)/pcem-lpt.Po ./$(DEPDIR)/pcem-lpt_dac.Po \ - ./$(DEPDIR)/pcem-lpt_dss.Po ./$(DEPDIR)/pcem-mca.Po \ - ./$(DEPDIR)/pcem-mcr.Po ./$(DEPDIR)/pcem-mem.Po \ - ./$(DEPDIR)/pcem-mem_bios.Po ./$(DEPDIR)/pcem-mfm_at.Po \ - ./$(DEPDIR)/pcem-mfm_xebec.Po ./$(DEPDIR)/pcem-midi_alsa.Po \ - ./$(DEPDIR)/pcem-model.Po ./$(DEPDIR)/pcem-mouse.Po \ - ./$(DEPDIR)/pcem-mouse_msystems.Po \ - ./$(DEPDIR)/pcem-mouse_ps2.Po ./$(DEPDIR)/pcem-mouse_serial.Po \ - ./$(DEPDIR)/pcem-ne2000.Po ./$(DEPDIR)/pcem-neat.Po \ - ./$(DEPDIR)/pcem-nethandler.Po ./$(DEPDIR)/pcem-nmi.Po \ - ./$(DEPDIR)/pcem-nvr.Po ./$(DEPDIR)/pcem-nvr_tc8521.Po \ - ./$(DEPDIR)/pcem-olivetti_m24.Po ./$(DEPDIR)/pcem-opti495.Po \ - ./$(DEPDIR)/pcem-paths.Po ./$(DEPDIR)/pcem-pc.Po \ - ./$(DEPDIR)/pcem-pc87306.Po ./$(DEPDIR)/pcem-pci.Po \ - ./$(DEPDIR)/pcem-pic.Po ./$(DEPDIR)/pcem-piix.Po \ - ./$(DEPDIR)/pcem-pit.Po ./$(DEPDIR)/pcem-ppi.Po \ - ./$(DEPDIR)/pcem-ps1.Po ./$(DEPDIR)/pcem-ps2.Po \ - ./$(DEPDIR)/pcem-ps2_mca.Po ./$(DEPDIR)/pcem-ps2_nvr.Po \ - ./$(DEPDIR)/pcem-rom.Po ./$(DEPDIR)/pcem-rtc.Po \ - ./$(DEPDIR)/pcem-rtc_tc8521.Po ./$(DEPDIR)/pcem-scat.Po \ - ./$(DEPDIR)/pcem-scsi.Po ./$(DEPDIR)/pcem-scsi_53c400.Po \ - ./$(DEPDIR)/pcem-scsi_aha1540.Po ./$(DEPDIR)/pcem-scsi_cd.Po \ - ./$(DEPDIR)/pcem-scsi_hd.Po ./$(DEPDIR)/pcem-scsi_zip.Po \ - ./$(DEPDIR)/pcem-serial.Po ./$(DEPDIR)/pcem-sio.Po \ - ./$(DEPDIR)/pcem-sis496.Po ./$(DEPDIR)/pcem-sl82c460.Po \ - ./$(DEPDIR)/pcem-sound.Po ./$(DEPDIR)/pcem-sound_ad1848.Po \ - ./$(DEPDIR)/pcem-sound_adlib.Po \ - ./$(DEPDIR)/pcem-sound_adlibgold.Po \ - ./$(DEPDIR)/pcem-sound_audiopci.Po \ - ./$(DEPDIR)/pcem-sound_cms.Po ./$(DEPDIR)/pcem-sound_dbopl.Po \ - ./$(DEPDIR)/pcem-sound_emu8k.Po ./$(DEPDIR)/pcem-sound_gus.Po \ - ./$(DEPDIR)/pcem-sound_mpu401_uart.Po \ - ./$(DEPDIR)/pcem-sound_opl.Po ./$(DEPDIR)/pcem-sound_pas16.Po \ - ./$(DEPDIR)/pcem-sound_ps1.Po ./$(DEPDIR)/pcem-sound_pssj.Po \ - ./$(DEPDIR)/pcem-sound_resid.Po ./$(DEPDIR)/pcem-sound_sb.Po \ - ./$(DEPDIR)/pcem-sound_sb_dsp.Po \ - ./$(DEPDIR)/pcem-sound_sn76489.Po \ - ./$(DEPDIR)/pcem-sound_speaker.Po \ - ./$(DEPDIR)/pcem-sound_ssi2001.Po \ - ./$(DEPDIR)/pcem-sound_wss.Po ./$(DEPDIR)/pcem-sound_ym7128.Po \ - ./$(DEPDIR)/pcem-soundopenal.Po ./$(DEPDIR)/pcem-t1000.Po \ - ./$(DEPDIR)/pcem-t3100e.Po ./$(DEPDIR)/pcem-tandy_eeprom.Po \ - ./$(DEPDIR)/pcem-tandy_rom.Po ./$(DEPDIR)/pcem-timer.Po \ - ./$(DEPDIR)/pcem-um8669f.Po ./$(DEPDIR)/pcem-um8881f.Po \ - ./$(DEPDIR)/pcem-vid_ati18800.Po \ - ./$(DEPDIR)/pcem-vid_ati28800.Po \ - ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po \ - ./$(DEPDIR)/pcem-vid_ati_eeprom.Po \ - ./$(DEPDIR)/pcem-vid_ati_mach64.Po ./$(DEPDIR)/pcem-vid_cga.Po \ - ./$(DEPDIR)/pcem-vid_cl5429.Po \ - ./$(DEPDIR)/pcem-vid_colorplus.Po \ - ./$(DEPDIR)/pcem-vid_compaq_cga.Po ./$(DEPDIR)/pcem-vid_ega.Po \ - ./$(DEPDIR)/pcem-vid_et4000.Po \ - ./$(DEPDIR)/pcem-vid_et4000w32.Po \ - ./$(DEPDIR)/pcem-vid_genius.Po \ - ./$(DEPDIR)/pcem-vid_hercules.Po \ - ./$(DEPDIR)/pcem-vid_icd2061.Po \ - ./$(DEPDIR)/pcem-vid_ics2595.Po \ - ./$(DEPDIR)/pcem-vid_incolor.Po ./$(DEPDIR)/pcem-vid_mda.Po \ - ./$(DEPDIR)/pcem-vid_olivetti_m24.Po \ - ./$(DEPDIR)/pcem-vid_oti037.Po ./$(DEPDIR)/pcem-vid_oti067.Po \ - ./$(DEPDIR)/pcem-vid_paradise.Po \ - ./$(DEPDIR)/pcem-vid_pc1512.Po ./$(DEPDIR)/pcem-vid_pc1640.Po \ - ./$(DEPDIR)/pcem-vid_pc200.Po ./$(DEPDIR)/pcem-vid_pcjr.Po \ - ./$(DEPDIR)/pcem-vid_ps1_svga.Po ./$(DEPDIR)/pcem-vid_s3.Po \ - ./$(DEPDIR)/pcem-vid_s3_virge.Po \ - ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po \ - ./$(DEPDIR)/pcem-vid_stg_ramdac.Po \ - ./$(DEPDIR)/pcem-vid_svga.Po \ - ./$(DEPDIR)/pcem-vid_svga_render.Po \ - ./$(DEPDIR)/pcem-vid_t1000.Po ./$(DEPDIR)/pcem-vid_t3100e.Po \ - ./$(DEPDIR)/pcem-vid_tandy.Po ./$(DEPDIR)/pcem-vid_tandysl.Po \ - ./$(DEPDIR)/pcem-vid_tgui9440.Po \ - ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po \ - ./$(DEPDIR)/pcem-vid_tvga.Po \ - ./$(DEPDIR)/pcem-vid_unk_ramdac.Po ./$(DEPDIR)/pcem-vid_vga.Po \ - ./$(DEPDIR)/pcem-vid_voodoo.Po ./$(DEPDIR)/pcem-vid_wy700.Po \ - ./$(DEPDIR)/pcem-video.Po ./$(DEPDIR)/pcem-wd76c10.Po \ - ./$(DEPDIR)/pcem-wx-app.Po ./$(DEPDIR)/pcem-wx-common.Po \ - ./$(DEPDIR)/pcem-wx-config.Po \ - ./$(DEPDIR)/pcem-wx-config_sel.Po \ - ./$(DEPDIR)/pcem-wx-createdisc.Po \ - ./$(DEPDIR)/pcem-wx-deviceconfig.Po \ - ./$(DEPDIR)/pcem-wx-dialogbox.Po \ - ./$(DEPDIR)/pcem-wx-glslp-parser.Po \ - ./$(DEPDIR)/pcem-wx-hostconfig.Po \ - ./$(DEPDIR)/pcem-wx-joystickconfig.Po \ - ./$(DEPDIR)/pcem-wx-main.Po ./$(DEPDIR)/pcem-wx-resources.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-display.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-midi.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-status.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po \ - ./$(DEPDIR)/pcem-wx-sdl2-video.Po ./$(DEPDIR)/pcem-wx-sdl2.Po \ - ./$(DEPDIR)/pcem-wx-shader_man.Po \ - ./$(DEPDIR)/pcem-wx-shaderconfig.Po \ - ./$(DEPDIR)/pcem-wx-status.Po ./$(DEPDIR)/pcem-wx-thread.Po \ - ./$(DEPDIR)/pcem-wx-utils.Po ./$(DEPDIR)/pcem-x86seg.Po \ - ./$(DEPDIR)/pcem-x87.Po ./$(DEPDIR)/pcem-xi8088.Po \ - ./$(DEPDIR)/pcem-xtide.Po dosbox/$(DEPDIR)/pcem-cdrom_image.Po \ - dosbox/$(DEPDIR)/pcem-dbopl.Po \ - dosbox/$(DEPDIR)/pcem-nukedopl.Po \ - dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po \ - resid-fp/$(DEPDIR)/pcem-convolve-sse.Po \ - resid-fp/$(DEPDIR)/pcem-convolve.Po \ - resid-fp/$(DEPDIR)/pcem-envelope.Po \ - resid-fp/$(DEPDIR)/pcem-extfilt.Po \ - resid-fp/$(DEPDIR)/pcem-filter.Po \ - resid-fp/$(DEPDIR)/pcem-pot.Po resid-fp/$(DEPDIR)/pcem-sid.Po \ - resid-fp/$(DEPDIR)/pcem-voice.Po \ - resid-fp/$(DEPDIR)/pcem-wave.Po \ - resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po \ - resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po \ - resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po \ - resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po \ - resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po \ - resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po \ - resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po \ - resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po \ - slirp/$(DEPDIR)/pcem-bootp.Po slirp/$(DEPDIR)/pcem-cksum.Po \ - slirp/$(DEPDIR)/pcem-debug.Po slirp/$(DEPDIR)/pcem-if.Po \ - slirp/$(DEPDIR)/pcem-ip_icmp.Po \ - slirp/$(DEPDIR)/pcem-ip_input.Po \ - slirp/$(DEPDIR)/pcem-ip_output.Po slirp/$(DEPDIR)/pcem-mbuf.Po \ - slirp/$(DEPDIR)/pcem-misc.Po slirp/$(DEPDIR)/pcem-queue.Po \ - slirp/$(DEPDIR)/pcem-sbuf.Po slirp/$(DEPDIR)/pcem-slirp.Po \ - slirp/$(DEPDIR)/pcem-socket.Po \ - slirp/$(DEPDIR)/pcem-tcp_input.Po \ - slirp/$(DEPDIR)/pcem-tcp_output.Po \ - slirp/$(DEPDIR)/pcem-tcp_subr.Po \ - slirp/$(DEPDIR)/pcem-tcp_timer.Po slirp/$(DEPDIR)/pcem-tftp.Po \ - slirp/$(DEPDIR)/pcem-udp.Po +am__depfiles_maybe = depfiles am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -747,6 +618,7 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -767,65 +639,79 @@ WINDRES = $(shell $(WX_CONFIG_PATH) --rescomp) # DOSBox # resid-fp -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c \ - acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc \ - cdrom-null.c cmd640.c codegen.c codegen_backend.c codegen_ir.c \ - codegen_timing_486.c codegen_timing_686.c \ - codegen_timing_common.c codegen_timing_pentium.c \ - codegen_timing_winchip.c compaq.c config.c cpu.c dells200.c \ - device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c \ - esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c \ - hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c \ - ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c \ - joystick_ch_flightstick_pro.c joystick_standard.c \ +pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c \ + 808x.c acc2036.c acc2168.c acc3221.c acer386sx.c ali1429.c \ + amstrad.c cassette.c cbm_io.c cdrom-image.cc cdrom-null.c \ + cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c \ + codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c \ + codegen_ops_arith.c codegen_ops_branch.c \ + codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c \ + codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c \ + codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c \ + codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c \ + codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c \ + codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c \ + codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c \ + codegen_ops_stack.c codegen_reg.c codegen_timing_486.c \ + codegen_timing_686.c codegen_timing_common.c \ + codegen_timing_k6.c codegen_timing_pentium.c \ + codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c \ + config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ + disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c \ + fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ + hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c \ + ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ - neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c \ - pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ - ps2_nvr.c nvr_tc8521.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c \ - scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_zip.c \ - serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ - sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ + mvp3.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c \ + pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ + ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c \ + rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c \ + scsi_cd.c scsi_hd.c scsi_zip.c serial.c sio.c sis496.c \ + sl82c460.c sound.c sound_ad1848.c sound_adlib.c \ + sound_adlibgold.c sound_audiopci.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 sst39sf010.c tandy_eeprom.c \ tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c \ - vid_et4000w32.c vid_genius.c vid_hercules.c vid_icd2061.c \ - vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c \ - vid_oti037.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_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c \ + vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c \ + vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c \ + vid_paradise.c vid_pc200.c vid_pc1512.c vid_pc1640.c \ + vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c \ + vid_sdac_ramdac.c vid_sigma.c vid_stg_ramdac.c vid_svga.c \ vid_svga_render.c vid_t1000.c vid_t3100e.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 \ - vid_wy700.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc \ - sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ - dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc \ - wx-config_sel.c wx-dialogbox.cc wx-utils.cc wx-app.cc \ - wx-sdl2-joystick.c wx-sdl2-mouse.c wx-sdl2-keyboard.c \ - wx-sdl2-video.c wx-sdl2.c wx-config.c wx-deviceconfig.cc \ - wx-status.cc wx-sdl2-status.c wx-thread.c wx-common.c \ - wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c wx-glslp-parser.c \ - wx-shader_man.c wx-shaderconfig.cc wx-joystickconfig.cc \ - wx-createdisc.cc wx-resources.cpp $(am__append_4) \ - $(am__append_5) $(am__append_6) $(am__append_8) \ - $(am__append_9) $(am__append_10) $(am__append_13) \ - $(am__append_15) $(am__append_16) $(am__append_17) \ - $(am__append_20) + vid_wy700.c vt82c586b.c w83877tf.c x86seg.c x87.c xi8088.c \ + xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ + dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ + wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ + wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ + wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ + wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ + wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ + wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_8) $(am__append_9) $(am__append_10) \ + $(am__append_13) $(am__append_15) $(am__append_16) \ + $(am__append_17) $(am__append_20) pcem_CFLAGS = $(subst -fpermissive,,$(shell $(WX_CONFIG_PATH) \ --cxxflags) $(shell sdl2-config --cflags)) $(am__append_7) \ $(am__append_11) $(am__append_18) $(am__append_22) @@ -855,8 +741,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + 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) @@ -1021,281 +907,325 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec_ops.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-808x.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2036.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acer386sx.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ali1429.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-amstrad.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ir.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_486.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_686.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_pentium.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_winchip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-compaq.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-config.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-device.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_fdi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_img.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_sector.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc37c665.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdi2raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-headland.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430fx.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430lx.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430vx.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide_atapi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel_flash.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-io.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-jim.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_standard.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_sw_pad.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_tm_fcs.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_amstrad.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_at.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_olim24.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_pcjr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_xt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-laserxt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mcr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem_bios.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_at.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-model.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_msystems.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_ps2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_serial.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ne2000.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nmi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr_tc8521.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pci.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-piix.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pit.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ppi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps1.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_mca.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ad1848.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlib.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlibgold.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_audiopci.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_cms.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_dbopl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_emu8k.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_gus.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_mpu401_uart.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_opl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pas16.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ps1.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb_dsp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sn76489.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_speaker.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ssi2001.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_wss.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ym7128.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-timer.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8669f.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8881f.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati18800.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati28800.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_eeprom.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_mach64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cga.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cl5429.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_colorplus.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ega.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000w32.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_genius.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_hercules.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_icd2061.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ics2595.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_mda.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_olivetti_m24.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti037.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti067.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_paradise.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1512.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1640.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc200.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pcjr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ps1_svga.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3_virge.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_sdac_ramdac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_stg_ramdac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga_render.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t1000.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandy.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandysl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tgui9440.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tvga.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_unk_ramdac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_vga.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_wy700.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x86seg.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x87.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xi8088.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_common.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-acc2036.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2168.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc3221.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-amstrad.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cassette.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-dummy.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-ioctl-osx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_accumulate.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_allocator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_imm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_ops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_ops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_block.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ir.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_ops_3dnow.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_arith.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_branch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_arith.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_constant.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_helpers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_jump.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_logic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_arith.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_logic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_pack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_shift.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mov.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_shift.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_stack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_reg.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_686.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_k6.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_timing_winchip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_winchip2.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-cpu_tables.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.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-disc_sector.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.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-fdd.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-hdd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.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-i430hx.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-ide_atapi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide_sff8038i.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-joystick_ch_flightstick_pro.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_standard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_sw_pad.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_tm_fcs.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-laserxt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.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-mem_bios.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_at.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.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_msystems.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-mvp3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ne2000.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.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-nvr_tc8521.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.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-ps2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_mca.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pzx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.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_audiopci.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_dbopl.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_ps1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.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-sound_ym7128.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sst39sf010.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.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_colorplus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.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_genius.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_ht216.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_im1024.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.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_oti037.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_pgc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ps1_svga.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_sigma.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_t1000.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.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_tandysl.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-vid_wy700.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vt82c586b.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-w83877tf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.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-xi8088.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -1327,6 +1257,20 @@ pcem-386.obj: 386.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_common.o: 386_common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386_common.o -MD -MP -MF $(DEPDIR)/pcem-386_common.Tpo -c -o pcem-386_common.o `test -f '386_common.c' || echo '$(srcdir)/'`386_common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-386_common.Tpo $(DEPDIR)/pcem-386_common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='386_common.c' object='pcem-386_common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386_common.o `test -f '386_common.c' || echo '$(srcdir)/'`386_common.c + +pcem-386_common.obj: 386_common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386_common.obj -MD -MP -MF $(DEPDIR)/pcem-386_common.Tpo -c -o pcem-386_common.obj `if test -f '386_common.c'; then $(CYGPATH_W) '386_common.c'; else $(CYGPATH_W) '$(srcdir)/386_common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-386_common.Tpo $(DEPDIR)/pcem-386_common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='386_common.c' object='pcem-386_common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386_common.obj `if test -f '386_common.c'; then $(CYGPATH_W) '386_common.c'; else $(CYGPATH_W) '$(srcdir)/386_common.c'; fi` + pcem-386_dynarec.o: 386_dynarec.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-386_dynarec.Tpo $(DEPDIR)/pcem-386_dynarec.Po @@ -1383,6 +1327,34 @@ pcem-acc2036.obj: acc2036.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc2036.obj `if test -f 'acc2036.c'; then $(CYGPATH_W) 'acc2036.c'; else $(CYGPATH_W) '$(srcdir)/acc2036.c'; fi` +pcem-acc2168.o: acc2168.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc2168.o -MD -MP -MF $(DEPDIR)/pcem-acc2168.Tpo -c -o pcem-acc2168.o `test -f 'acc2168.c' || echo '$(srcdir)/'`acc2168.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc2168.Tpo $(DEPDIR)/pcem-acc2168.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc2168.c' object='pcem-acc2168.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc2168.o `test -f 'acc2168.c' || echo '$(srcdir)/'`acc2168.c + +pcem-acc2168.obj: acc2168.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc2168.obj -MD -MP -MF $(DEPDIR)/pcem-acc2168.Tpo -c -o pcem-acc2168.obj `if test -f 'acc2168.c'; then $(CYGPATH_W) 'acc2168.c'; else $(CYGPATH_W) '$(srcdir)/acc2168.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc2168.Tpo $(DEPDIR)/pcem-acc2168.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc2168.c' object='pcem-acc2168.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc2168.obj `if test -f 'acc2168.c'; then $(CYGPATH_W) 'acc2168.c'; else $(CYGPATH_W) '$(srcdir)/acc2168.c'; fi` + +pcem-acc3221.o: acc3221.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc3221.o -MD -MP -MF $(DEPDIR)/pcem-acc3221.Tpo -c -o pcem-acc3221.o `test -f 'acc3221.c' || echo '$(srcdir)/'`acc3221.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc3221.Tpo $(DEPDIR)/pcem-acc3221.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc3221.c' object='pcem-acc3221.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc3221.o `test -f 'acc3221.c' || echo '$(srcdir)/'`acc3221.c + +pcem-acc3221.obj: acc3221.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc3221.obj -MD -MP -MF $(DEPDIR)/pcem-acc3221.Tpo -c -o pcem-acc3221.obj `if test -f 'acc3221.c'; then $(CYGPATH_W) 'acc3221.c'; else $(CYGPATH_W) '$(srcdir)/acc3221.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc3221.Tpo $(DEPDIR)/pcem-acc3221.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acc3221.c' object='pcem-acc3221.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acc3221.obj `if test -f 'acc3221.c'; then $(CYGPATH_W) 'acc3221.c'; else $(CYGPATH_W) '$(srcdir)/acc3221.c'; fi` + pcem-acer386sx.o: acer386sx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-acer386sx.Tpo $(DEPDIR)/pcem-acer386sx.Po @@ -1425,6 +1397,20 @@ pcem-amstrad.obj: amstrad.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-cassette.o: cassette.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cassette.o -MD -MP -MF $(DEPDIR)/pcem-cassette.Tpo -c -o pcem-cassette.o `test -f 'cassette.c' || echo '$(srcdir)/'`cassette.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cassette.Tpo $(DEPDIR)/pcem-cassette.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cassette.c' object='pcem-cassette.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cassette.o `test -f 'cassette.c' || echo '$(srcdir)/'`cassette.c + +pcem-cassette.obj: cassette.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cassette.obj -MD -MP -MF $(DEPDIR)/pcem-cassette.Tpo -c -o pcem-cassette.obj `if test -f 'cassette.c'; then $(CYGPATH_W) 'cassette.c'; else $(CYGPATH_W) '$(srcdir)/cassette.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cassette.Tpo $(DEPDIR)/pcem-cassette.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cassette.c' object='pcem-cassette.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cassette.obj `if test -f 'cassette.c'; then $(CYGPATH_W) 'cassette.c'; else $(CYGPATH_W) '$(srcdir)/cassette.c'; fi` + pcem-cbm_io.o: cbm_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cbm_io.o -MD -MP -MF $(DEPDIR)/pcem-cbm_io.Tpo -c -o pcem-cbm_io.o `test -f 'cbm_io.c' || echo '$(srcdir)/'`cbm_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cbm_io.Tpo $(DEPDIR)/pcem-cbm_io.Po @@ -1481,19 +1467,47 @@ pcem-codegen.obj: codegen.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_backend.o: codegen_backend.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend.Tpo -c -o pcem-codegen_backend.o `test -f 'codegen_backend.c' || echo '$(srcdir)/'`codegen_backend.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend.Tpo $(DEPDIR)/pcem-codegen_backend.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend.c' object='pcem-codegen_backend.o' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_accumulate.o: codegen_accumulate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_accumulate.o -MD -MP -MF $(DEPDIR)/pcem-codegen_accumulate.Tpo -c -o pcem-codegen_accumulate.o `test -f 'codegen_accumulate.c' || echo '$(srcdir)/'`codegen_accumulate.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_accumulate.Tpo $(DEPDIR)/pcem-codegen_accumulate.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_accumulate.c' object='pcem-codegen_accumulate.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend.o `test -f 'codegen_backend.c' || echo '$(srcdir)/'`codegen_backend.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_accumulate.o `test -f 'codegen_accumulate.c' || echo '$(srcdir)/'`codegen_accumulate.c -pcem-codegen_backend.obj: codegen_backend.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend.Tpo -c -o pcem-codegen_backend.obj `if test -f 'codegen_backend.c'; then $(CYGPATH_W) 'codegen_backend.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend.Tpo $(DEPDIR)/pcem-codegen_backend.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend.c' object='pcem-codegen_backend.obj' libtool=no @AMDEPBACKSLASH@ +pcem-codegen_accumulate.obj: codegen_accumulate.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_accumulate.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_accumulate.Tpo -c -o pcem-codegen_accumulate.obj `if test -f 'codegen_accumulate.c'; then $(CYGPATH_W) 'codegen_accumulate.c'; else $(CYGPATH_W) '$(srcdir)/codegen_accumulate.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_accumulate.Tpo $(DEPDIR)/pcem-codegen_accumulate.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_accumulate.c' object='pcem-codegen_accumulate.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend.obj `if test -f 'codegen_backend.c'; then $(CYGPATH_W) 'codegen_backend.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_accumulate.obj `if test -f 'codegen_accumulate.c'; then $(CYGPATH_W) 'codegen_accumulate.c'; else $(CYGPATH_W) '$(srcdir)/codegen_accumulate.c'; fi` + +pcem-codegen_allocator.o: codegen_allocator.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_allocator.o -MD -MP -MF $(DEPDIR)/pcem-codegen_allocator.Tpo -c -o pcem-codegen_allocator.o `test -f 'codegen_allocator.c' || echo '$(srcdir)/'`codegen_allocator.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_allocator.Tpo $(DEPDIR)/pcem-codegen_allocator.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_allocator.c' object='pcem-codegen_allocator.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_allocator.o `test -f 'codegen_allocator.c' || echo '$(srcdir)/'`codegen_allocator.c + +pcem-codegen_allocator.obj: codegen_allocator.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_allocator.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_allocator.Tpo -c -o pcem-codegen_allocator.obj `if test -f 'codegen_allocator.c'; then $(CYGPATH_W) 'codegen_allocator.c'; else $(CYGPATH_W) '$(srcdir)/codegen_allocator.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_allocator.Tpo $(DEPDIR)/pcem-codegen_allocator.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_allocator.c' object='pcem-codegen_allocator.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_allocator.obj `if test -f 'codegen_allocator.c'; then $(CYGPATH_W) 'codegen_allocator.c'; else $(CYGPATH_W) '$(srcdir)/codegen_allocator.c'; fi` + +pcem-codegen_block.o: codegen_block.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_block.o -MD -MP -MF $(DEPDIR)/pcem-codegen_block.Tpo -c -o pcem-codegen_block.o `test -f 'codegen_block.c' || echo '$(srcdir)/'`codegen_block.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_block.Tpo $(DEPDIR)/pcem-codegen_block.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_block.c' object='pcem-codegen_block.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_block.o `test -f 'codegen_block.c' || echo '$(srcdir)/'`codegen_block.c + +pcem-codegen_block.obj: codegen_block.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_block.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_block.Tpo -c -o pcem-codegen_block.obj `if test -f 'codegen_block.c'; then $(CYGPATH_W) 'codegen_block.c'; else $(CYGPATH_W) '$(srcdir)/codegen_block.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_block.Tpo $(DEPDIR)/pcem-codegen_block.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_block.c' object='pcem-codegen_block.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_block.obj `if test -f 'codegen_block.c'; then $(CYGPATH_W) 'codegen_block.c'; else $(CYGPATH_W) '$(srcdir)/codegen_block.c'; fi` pcem-codegen_ir.o: codegen_ir.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ir.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ir.Tpo -c -o pcem-codegen_ir.o `test -f 'codegen_ir.c' || echo '$(srcdir)/'`codegen_ir.c @@ -1509,6 +1523,314 @@ pcem-codegen_ir.obj: codegen_ir.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ir.obj `if test -f 'codegen_ir.c'; then $(CYGPATH_W) 'codegen_ir.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ir.c'; fi` +pcem-codegen_ops.o: codegen_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops.Tpo $(DEPDIR)/pcem-codegen_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops.Tpo $(DEPDIR)/pcem-codegen_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)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@ $(AM_V_CC@am__nodep@)$(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_ops_3dnow.o: codegen_ops_3dnow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_3dnow.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_3dnow.Tpo -c -o pcem-codegen_ops_3dnow.o `test -f 'codegen_ops_3dnow.c' || echo '$(srcdir)/'`codegen_ops_3dnow.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_3dnow.Tpo $(DEPDIR)/pcem-codegen_ops_3dnow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_3dnow.c' object='pcem-codegen_ops_3dnow.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_3dnow.o `test -f 'codegen_ops_3dnow.c' || echo '$(srcdir)/'`codegen_ops_3dnow.c + +pcem-codegen_ops_3dnow.obj: codegen_ops_3dnow.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_3dnow.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_3dnow.Tpo -c -o pcem-codegen_ops_3dnow.obj `if test -f 'codegen_ops_3dnow.c'; then $(CYGPATH_W) 'codegen_ops_3dnow.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_3dnow.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_3dnow.Tpo $(DEPDIR)/pcem-codegen_ops_3dnow.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_3dnow.c' object='pcem-codegen_ops_3dnow.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_3dnow.obj `if test -f 'codegen_ops_3dnow.c'; then $(CYGPATH_W) 'codegen_ops_3dnow.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_3dnow.c'; fi` + +pcem-codegen_ops_arith.o: codegen_ops_arith.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_arith.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_arith.Tpo -c -o pcem-codegen_ops_arith.o `test -f 'codegen_ops_arith.c' || echo '$(srcdir)/'`codegen_ops_arith.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_arith.Tpo $(DEPDIR)/pcem-codegen_ops_arith.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_arith.c' object='pcem-codegen_ops_arith.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_arith.o `test -f 'codegen_ops_arith.c' || echo '$(srcdir)/'`codegen_ops_arith.c + +pcem-codegen_ops_arith.obj: codegen_ops_arith.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_arith.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_arith.Tpo -c -o pcem-codegen_ops_arith.obj `if test -f 'codegen_ops_arith.c'; then $(CYGPATH_W) 'codegen_ops_arith.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_arith.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_arith.Tpo $(DEPDIR)/pcem-codegen_ops_arith.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_arith.c' object='pcem-codegen_ops_arith.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_arith.obj `if test -f 'codegen_ops_arith.c'; then $(CYGPATH_W) 'codegen_ops_arith.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_arith.c'; fi` + +pcem-codegen_ops_branch.o: codegen_ops_branch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_branch.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_branch.Tpo -c -o pcem-codegen_ops_branch.o `test -f 'codegen_ops_branch.c' || echo '$(srcdir)/'`codegen_ops_branch.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_branch.Tpo $(DEPDIR)/pcem-codegen_ops_branch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_branch.c' object='pcem-codegen_ops_branch.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_branch.o `test -f 'codegen_ops_branch.c' || echo '$(srcdir)/'`codegen_ops_branch.c + +pcem-codegen_ops_branch.obj: codegen_ops_branch.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_branch.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_branch.Tpo -c -o pcem-codegen_ops_branch.obj `if test -f 'codegen_ops_branch.c'; then $(CYGPATH_W) 'codegen_ops_branch.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_branch.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_branch.Tpo $(DEPDIR)/pcem-codegen_ops_branch.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_branch.c' object='pcem-codegen_ops_branch.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_branch.obj `if test -f 'codegen_ops_branch.c'; then $(CYGPATH_W) 'codegen_ops_branch.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_branch.c'; fi` + +pcem-codegen_ops_fpu_arith.o: codegen_ops_fpu_arith.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_arith.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_arith.Tpo -c -o pcem-codegen_ops_fpu_arith.o `test -f 'codegen_ops_fpu_arith.c' || echo '$(srcdir)/'`codegen_ops_fpu_arith.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_arith.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_arith.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_arith.c' object='pcem-codegen_ops_fpu_arith.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_arith.o `test -f 'codegen_ops_fpu_arith.c' || echo '$(srcdir)/'`codegen_ops_fpu_arith.c + +pcem-codegen_ops_fpu_arith.obj: codegen_ops_fpu_arith.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_arith.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_arith.Tpo -c -o pcem-codegen_ops_fpu_arith.obj `if test -f 'codegen_ops_fpu_arith.c'; then $(CYGPATH_W) 'codegen_ops_fpu_arith.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_arith.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_arith.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_arith.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_arith.c' object='pcem-codegen_ops_fpu_arith.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_arith.obj `if test -f 'codegen_ops_fpu_arith.c'; then $(CYGPATH_W) 'codegen_ops_fpu_arith.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_arith.c'; fi` + +pcem-codegen_ops_fpu_constant.o: codegen_ops_fpu_constant.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_constant.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_constant.Tpo -c -o pcem-codegen_ops_fpu_constant.o `test -f 'codegen_ops_fpu_constant.c' || echo '$(srcdir)/'`codegen_ops_fpu_constant.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_constant.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_constant.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_constant.c' object='pcem-codegen_ops_fpu_constant.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_constant.o `test -f 'codegen_ops_fpu_constant.c' || echo '$(srcdir)/'`codegen_ops_fpu_constant.c + +pcem-codegen_ops_fpu_constant.obj: codegen_ops_fpu_constant.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_constant.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_constant.Tpo -c -o pcem-codegen_ops_fpu_constant.obj `if test -f 'codegen_ops_fpu_constant.c'; then $(CYGPATH_W) 'codegen_ops_fpu_constant.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_constant.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_constant.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_constant.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_constant.c' object='pcem-codegen_ops_fpu_constant.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_constant.obj `if test -f 'codegen_ops_fpu_constant.c'; then $(CYGPATH_W) 'codegen_ops_fpu_constant.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_constant.c'; fi` + +pcem-codegen_ops_fpu_loadstore.o: codegen_ops_fpu_loadstore.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_loadstore.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Tpo -c -o pcem-codegen_ops_fpu_loadstore.o `test -f 'codegen_ops_fpu_loadstore.c' || echo '$(srcdir)/'`codegen_ops_fpu_loadstore.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_loadstore.c' object='pcem-codegen_ops_fpu_loadstore.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_loadstore.o `test -f 'codegen_ops_fpu_loadstore.c' || echo '$(srcdir)/'`codegen_ops_fpu_loadstore.c + +pcem-codegen_ops_fpu_loadstore.obj: codegen_ops_fpu_loadstore.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_loadstore.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Tpo -c -o pcem-codegen_ops_fpu_loadstore.obj `if test -f 'codegen_ops_fpu_loadstore.c'; then $(CYGPATH_W) 'codegen_ops_fpu_loadstore.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_loadstore.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_loadstore.c' object='pcem-codegen_ops_fpu_loadstore.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_loadstore.obj `if test -f 'codegen_ops_fpu_loadstore.c'; then $(CYGPATH_W) 'codegen_ops_fpu_loadstore.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_loadstore.c'; fi` + +pcem-codegen_ops_fpu_misc.o: codegen_ops_fpu_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_misc.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_misc.Tpo -c -o pcem-codegen_ops_fpu_misc.o `test -f 'codegen_ops_fpu_misc.c' || echo '$(srcdir)/'`codegen_ops_fpu_misc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_misc.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_misc.c' object='pcem-codegen_ops_fpu_misc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_misc.o `test -f 'codegen_ops_fpu_misc.c' || echo '$(srcdir)/'`codegen_ops_fpu_misc.c + +pcem-codegen_ops_fpu_misc.obj: codegen_ops_fpu_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_fpu_misc.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_fpu_misc.Tpo -c -o pcem-codegen_ops_fpu_misc.obj `if test -f 'codegen_ops_fpu_misc.c'; then $(CYGPATH_W) 'codegen_ops_fpu_misc.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_misc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_fpu_misc.Tpo $(DEPDIR)/pcem-codegen_ops_fpu_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_fpu_misc.c' object='pcem-codegen_ops_fpu_misc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_fpu_misc.obj `if test -f 'codegen_ops_fpu_misc.c'; then $(CYGPATH_W) 'codegen_ops_fpu_misc.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_fpu_misc.c'; fi` + +pcem-codegen_ops_mmx_arith.o: codegen_ops_mmx_arith.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_arith.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_arith.Tpo -c -o pcem-codegen_ops_mmx_arith.o `test -f 'codegen_ops_mmx_arith.c' || echo '$(srcdir)/'`codegen_ops_mmx_arith.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_arith.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_arith.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_arith.c' object='pcem-codegen_ops_mmx_arith.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_arith.o `test -f 'codegen_ops_mmx_arith.c' || echo '$(srcdir)/'`codegen_ops_mmx_arith.c + +pcem-codegen_ops_mmx_arith.obj: codegen_ops_mmx_arith.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_arith.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_arith.Tpo -c -o pcem-codegen_ops_mmx_arith.obj `if test -f 'codegen_ops_mmx_arith.c'; then $(CYGPATH_W) 'codegen_ops_mmx_arith.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_arith.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_arith.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_arith.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_arith.c' object='pcem-codegen_ops_mmx_arith.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_arith.obj `if test -f 'codegen_ops_mmx_arith.c'; then $(CYGPATH_W) 'codegen_ops_mmx_arith.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_arith.c'; fi` + +pcem-codegen_ops_mmx_cmp.o: codegen_ops_mmx_cmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_cmp.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_cmp.Tpo -c -o pcem-codegen_ops_mmx_cmp.o `test -f 'codegen_ops_mmx_cmp.c' || echo '$(srcdir)/'`codegen_ops_mmx_cmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_cmp.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_cmp.c' object='pcem-codegen_ops_mmx_cmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_cmp.o `test -f 'codegen_ops_mmx_cmp.c' || echo '$(srcdir)/'`codegen_ops_mmx_cmp.c + +pcem-codegen_ops_mmx_cmp.obj: codegen_ops_mmx_cmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_cmp.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_cmp.Tpo -c -o pcem-codegen_ops_mmx_cmp.obj `if test -f 'codegen_ops_mmx_cmp.c'; then $(CYGPATH_W) 'codegen_ops_mmx_cmp.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_cmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_cmp.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_cmp.c' object='pcem-codegen_ops_mmx_cmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_cmp.obj `if test -f 'codegen_ops_mmx_cmp.c'; then $(CYGPATH_W) 'codegen_ops_mmx_cmp.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_cmp.c'; fi` + +pcem-codegen_ops_mmx_loadstore.o: codegen_ops_mmx_loadstore.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_loadstore.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Tpo -c -o pcem-codegen_ops_mmx_loadstore.o `test -f 'codegen_ops_mmx_loadstore.c' || echo '$(srcdir)/'`codegen_ops_mmx_loadstore.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_loadstore.c' object='pcem-codegen_ops_mmx_loadstore.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_loadstore.o `test -f 'codegen_ops_mmx_loadstore.c' || echo '$(srcdir)/'`codegen_ops_mmx_loadstore.c + +pcem-codegen_ops_mmx_loadstore.obj: codegen_ops_mmx_loadstore.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_loadstore.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Tpo -c -o pcem-codegen_ops_mmx_loadstore.obj `if test -f 'codegen_ops_mmx_loadstore.c'; then $(CYGPATH_W) 'codegen_ops_mmx_loadstore.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_loadstore.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_loadstore.c' object='pcem-codegen_ops_mmx_loadstore.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_loadstore.obj `if test -f 'codegen_ops_mmx_loadstore.c'; then $(CYGPATH_W) 'codegen_ops_mmx_loadstore.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_loadstore.c'; fi` + +pcem-codegen_ops_mmx_logic.o: codegen_ops_mmx_logic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_logic.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_logic.Tpo -c -o pcem-codegen_ops_mmx_logic.o `test -f 'codegen_ops_mmx_logic.c' || echo '$(srcdir)/'`codegen_ops_mmx_logic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_logic.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_logic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_logic.c' object='pcem-codegen_ops_mmx_logic.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_logic.o `test -f 'codegen_ops_mmx_logic.c' || echo '$(srcdir)/'`codegen_ops_mmx_logic.c + +pcem-codegen_ops_mmx_logic.obj: codegen_ops_mmx_logic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_logic.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_logic.Tpo -c -o pcem-codegen_ops_mmx_logic.obj `if test -f 'codegen_ops_mmx_logic.c'; then $(CYGPATH_W) 'codegen_ops_mmx_logic.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_logic.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_logic.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_logic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_logic.c' object='pcem-codegen_ops_mmx_logic.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_logic.obj `if test -f 'codegen_ops_mmx_logic.c'; then $(CYGPATH_W) 'codegen_ops_mmx_logic.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_logic.c'; fi` + +pcem-codegen_ops_mmx_pack.o: codegen_ops_mmx_pack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_pack.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_pack.Tpo -c -o pcem-codegen_ops_mmx_pack.o `test -f 'codegen_ops_mmx_pack.c' || echo '$(srcdir)/'`codegen_ops_mmx_pack.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_pack.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_pack.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_pack.c' object='pcem-codegen_ops_mmx_pack.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_pack.o `test -f 'codegen_ops_mmx_pack.c' || echo '$(srcdir)/'`codegen_ops_mmx_pack.c + +pcem-codegen_ops_mmx_pack.obj: codegen_ops_mmx_pack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_pack.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_pack.Tpo -c -o pcem-codegen_ops_mmx_pack.obj `if test -f 'codegen_ops_mmx_pack.c'; then $(CYGPATH_W) 'codegen_ops_mmx_pack.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_pack.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_pack.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_pack.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_pack.c' object='pcem-codegen_ops_mmx_pack.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_pack.obj `if test -f 'codegen_ops_mmx_pack.c'; then $(CYGPATH_W) 'codegen_ops_mmx_pack.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_pack.c'; fi` + +pcem-codegen_ops_mmx_shift.o: codegen_ops_mmx_shift.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_shift.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_shift.Tpo -c -o pcem-codegen_ops_mmx_shift.o `test -f 'codegen_ops_mmx_shift.c' || echo '$(srcdir)/'`codegen_ops_mmx_shift.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_shift.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_shift.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_shift.c' object='pcem-codegen_ops_mmx_shift.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_shift.o `test -f 'codegen_ops_mmx_shift.c' || echo '$(srcdir)/'`codegen_ops_mmx_shift.c + +pcem-codegen_ops_mmx_shift.obj: codegen_ops_mmx_shift.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mmx_shift.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mmx_shift.Tpo -c -o pcem-codegen_ops_mmx_shift.obj `if test -f 'codegen_ops_mmx_shift.c'; then $(CYGPATH_W) 'codegen_ops_mmx_shift.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_shift.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mmx_shift.Tpo $(DEPDIR)/pcem-codegen_ops_mmx_shift.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mmx_shift.c' object='pcem-codegen_ops_mmx_shift.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mmx_shift.obj `if test -f 'codegen_ops_mmx_shift.c'; then $(CYGPATH_W) 'codegen_ops_mmx_shift.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mmx_shift.c'; fi` + +pcem-codegen_ops_helpers.o: codegen_ops_helpers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_helpers.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_helpers.Tpo -c -o pcem-codegen_ops_helpers.o `test -f 'codegen_ops_helpers.c' || echo '$(srcdir)/'`codegen_ops_helpers.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_helpers.Tpo $(DEPDIR)/pcem-codegen_ops_helpers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_helpers.c' object='pcem-codegen_ops_helpers.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_helpers.o `test -f 'codegen_ops_helpers.c' || echo '$(srcdir)/'`codegen_ops_helpers.c + +pcem-codegen_ops_helpers.obj: codegen_ops_helpers.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_helpers.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_helpers.Tpo -c -o pcem-codegen_ops_helpers.obj `if test -f 'codegen_ops_helpers.c'; then $(CYGPATH_W) 'codegen_ops_helpers.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_helpers.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_helpers.Tpo $(DEPDIR)/pcem-codegen_ops_helpers.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_helpers.c' object='pcem-codegen_ops_helpers.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_helpers.obj `if test -f 'codegen_ops_helpers.c'; then $(CYGPATH_W) 'codegen_ops_helpers.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_helpers.c'; fi` + +pcem-codegen_ops_jump.o: codegen_ops_jump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_jump.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_jump.Tpo -c -o pcem-codegen_ops_jump.o `test -f 'codegen_ops_jump.c' || echo '$(srcdir)/'`codegen_ops_jump.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_jump.Tpo $(DEPDIR)/pcem-codegen_ops_jump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_jump.c' object='pcem-codegen_ops_jump.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_jump.o `test -f 'codegen_ops_jump.c' || echo '$(srcdir)/'`codegen_ops_jump.c + +pcem-codegen_ops_jump.obj: codegen_ops_jump.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_jump.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_jump.Tpo -c -o pcem-codegen_ops_jump.obj `if test -f 'codegen_ops_jump.c'; then $(CYGPATH_W) 'codegen_ops_jump.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_jump.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_jump.Tpo $(DEPDIR)/pcem-codegen_ops_jump.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_jump.c' object='pcem-codegen_ops_jump.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_jump.obj `if test -f 'codegen_ops_jump.c'; then $(CYGPATH_W) 'codegen_ops_jump.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_jump.c'; fi` + +pcem-codegen_ops_logic.o: codegen_ops_logic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_logic.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_logic.Tpo -c -o pcem-codegen_ops_logic.o `test -f 'codegen_ops_logic.c' || echo '$(srcdir)/'`codegen_ops_logic.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_logic.Tpo $(DEPDIR)/pcem-codegen_ops_logic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_logic.c' object='pcem-codegen_ops_logic.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_logic.o `test -f 'codegen_ops_logic.c' || echo '$(srcdir)/'`codegen_ops_logic.c + +pcem-codegen_ops_logic.obj: codegen_ops_logic.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_logic.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_logic.Tpo -c -o pcem-codegen_ops_logic.obj `if test -f 'codegen_ops_logic.c'; then $(CYGPATH_W) 'codegen_ops_logic.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_logic.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_logic.Tpo $(DEPDIR)/pcem-codegen_ops_logic.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_logic.c' object='pcem-codegen_ops_logic.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_logic.obj `if test -f 'codegen_ops_logic.c'; then $(CYGPATH_W) 'codegen_ops_logic.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_logic.c'; fi` + +pcem-codegen_ops_shift.o: codegen_ops_shift.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_shift.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_shift.Tpo -c -o pcem-codegen_ops_shift.o `test -f 'codegen_ops_shift.c' || echo '$(srcdir)/'`codegen_ops_shift.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_shift.Tpo $(DEPDIR)/pcem-codegen_ops_shift.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_shift.c' object='pcem-codegen_ops_shift.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_shift.o `test -f 'codegen_ops_shift.c' || echo '$(srcdir)/'`codegen_ops_shift.c + +pcem-codegen_ops_shift.obj: codegen_ops_shift.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_shift.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_shift.Tpo -c -o pcem-codegen_ops_shift.obj `if test -f 'codegen_ops_shift.c'; then $(CYGPATH_W) 'codegen_ops_shift.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_shift.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_shift.Tpo $(DEPDIR)/pcem-codegen_ops_shift.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_shift.c' object='pcem-codegen_ops_shift.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_shift.obj `if test -f 'codegen_ops_shift.c'; then $(CYGPATH_W) 'codegen_ops_shift.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_shift.c'; fi` + +pcem-codegen_ops_misc.o: codegen_ops_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_misc.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_misc.Tpo -c -o pcem-codegen_ops_misc.o `test -f 'codegen_ops_misc.c' || echo '$(srcdir)/'`codegen_ops_misc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_misc.Tpo $(DEPDIR)/pcem-codegen_ops_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_misc.c' object='pcem-codegen_ops_misc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_misc.o `test -f 'codegen_ops_misc.c' || echo '$(srcdir)/'`codegen_ops_misc.c + +pcem-codegen_ops_misc.obj: codegen_ops_misc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_misc.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_misc.Tpo -c -o pcem-codegen_ops_misc.obj `if test -f 'codegen_ops_misc.c'; then $(CYGPATH_W) 'codegen_ops_misc.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_misc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_misc.Tpo $(DEPDIR)/pcem-codegen_ops_misc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_misc.c' object='pcem-codegen_ops_misc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_misc.obj `if test -f 'codegen_ops_misc.c'; then $(CYGPATH_W) 'codegen_ops_misc.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_misc.c'; fi` + +pcem-codegen_ops_mov.o: codegen_ops_mov.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mov.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mov.Tpo -c -o pcem-codegen_ops_mov.o `test -f 'codegen_ops_mov.c' || echo '$(srcdir)/'`codegen_ops_mov.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mov.Tpo $(DEPDIR)/pcem-codegen_ops_mov.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mov.c' object='pcem-codegen_ops_mov.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mov.o `test -f 'codegen_ops_mov.c' || echo '$(srcdir)/'`codegen_ops_mov.c + +pcem-codegen_ops_mov.obj: codegen_ops_mov.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_mov.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_mov.Tpo -c -o pcem-codegen_ops_mov.obj `if test -f 'codegen_ops_mov.c'; then $(CYGPATH_W) 'codegen_ops_mov.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mov.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_mov.Tpo $(DEPDIR)/pcem-codegen_ops_mov.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_mov.c' object='pcem-codegen_ops_mov.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_mov.obj `if test -f 'codegen_ops_mov.c'; then $(CYGPATH_W) 'codegen_ops_mov.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_mov.c'; fi` + +pcem-codegen_ops_stack.o: codegen_ops_stack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_stack.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_stack.Tpo -c -o pcem-codegen_ops_stack.o `test -f 'codegen_ops_stack.c' || echo '$(srcdir)/'`codegen_ops_stack.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_stack.Tpo $(DEPDIR)/pcem-codegen_ops_stack.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_stack.c' object='pcem-codegen_ops_stack.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_stack.o `test -f 'codegen_ops_stack.c' || echo '$(srcdir)/'`codegen_ops_stack.c + +pcem-codegen_ops_stack.obj: codegen_ops_stack.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops_stack.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops_stack.Tpo -c -o pcem-codegen_ops_stack.obj `if test -f 'codegen_ops_stack.c'; then $(CYGPATH_W) 'codegen_ops_stack.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_stack.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_ops_stack.Tpo $(DEPDIR)/pcem-codegen_ops_stack.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_ops_stack.c' object='pcem-codegen_ops_stack.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops_stack.obj `if test -f 'codegen_ops_stack.c'; then $(CYGPATH_W) 'codegen_ops_stack.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops_stack.c'; fi` + +pcem-codegen_reg.o: codegen_reg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_reg.o -MD -MP -MF $(DEPDIR)/pcem-codegen_reg.Tpo -c -o pcem-codegen_reg.o `test -f 'codegen_reg.c' || echo '$(srcdir)/'`codegen_reg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_reg.Tpo $(DEPDIR)/pcem-codegen_reg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_reg.c' object='pcem-codegen_reg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_reg.o `test -f 'codegen_reg.c' || echo '$(srcdir)/'`codegen_reg.c + +pcem-codegen_reg.obj: codegen_reg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_reg.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_reg.Tpo -c -o pcem-codegen_reg.obj `if test -f 'codegen_reg.c'; then $(CYGPATH_W) 'codegen_reg.c'; else $(CYGPATH_W) '$(srcdir)/codegen_reg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_reg.Tpo $(DEPDIR)/pcem-codegen_reg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_reg.c' object='pcem-codegen_reg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_reg.obj `if test -f 'codegen_reg.c'; then $(CYGPATH_W) 'codegen_reg.c'; else $(CYGPATH_W) '$(srcdir)/codegen_reg.c'; fi` + pcem-codegen_timing_486.o: codegen_timing_486.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_486.Tpo $(DEPDIR)/pcem-codegen_timing_486.Po @@ -1551,6 +1873,20 @@ pcem-codegen_timing_common.obj: codegen_timing_common.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_common.obj `if test -f 'codegen_timing_common.c'; then $(CYGPATH_W) 'codegen_timing_common.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_common.c'; fi` +pcem-codegen_timing_k6.o: codegen_timing_k6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_k6.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_k6.Tpo -c -o pcem-codegen_timing_k6.o `test -f 'codegen_timing_k6.c' || echo '$(srcdir)/'`codegen_timing_k6.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_k6.Tpo $(DEPDIR)/pcem-codegen_timing_k6.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_k6.c' object='pcem-codegen_timing_k6.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_k6.o `test -f 'codegen_timing_k6.c' || echo '$(srcdir)/'`codegen_timing_k6.c + +pcem-codegen_timing_k6.obj: codegen_timing_k6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_k6.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_k6.Tpo -c -o pcem-codegen_timing_k6.obj `if test -f 'codegen_timing_k6.c'; then $(CYGPATH_W) 'codegen_timing_k6.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_k6.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_k6.Tpo $(DEPDIR)/pcem-codegen_timing_k6.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_k6.c' object='pcem-codegen_timing_k6.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_k6.obj `if test -f 'codegen_timing_k6.c'; then $(CYGPATH_W) 'codegen_timing_k6.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_k6.c'; fi` + pcem-codegen_timing_pentium.o: codegen_timing_pentium.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_pentium.Tpo $(DEPDIR)/pcem-codegen_timing_pentium.Po @@ -1579,6 +1915,20 @@ pcem-codegen_timing_winchip.obj: codegen_timing_winchip.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_winchip.obj `if test -f 'codegen_timing_winchip.c'; then $(CYGPATH_W) 'codegen_timing_winchip.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_winchip.c'; fi` +pcem-codegen_timing_winchip2.o: codegen_timing_winchip2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_winchip2.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_winchip2.Tpo -c -o pcem-codegen_timing_winchip2.o `test -f 'codegen_timing_winchip2.c' || echo '$(srcdir)/'`codegen_timing_winchip2.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_winchip2.Tpo $(DEPDIR)/pcem-codegen_timing_winchip2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_winchip2.c' object='pcem-codegen_timing_winchip2.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_winchip2.o `test -f 'codegen_timing_winchip2.c' || echo '$(srcdir)/'`codegen_timing_winchip2.c + +pcem-codegen_timing_winchip2.obj: codegen_timing_winchip2.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_winchip2.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_winchip2.Tpo -c -o pcem-codegen_timing_winchip2.obj `if test -f 'codegen_timing_winchip2.c'; then $(CYGPATH_W) 'codegen_timing_winchip2.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_winchip2.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_winchip2.Tpo $(DEPDIR)/pcem-codegen_timing_winchip2.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_winchip2.c' object='pcem-codegen_timing_winchip2.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_winchip2.obj `if test -f 'codegen_timing_winchip2.c'; then $(CYGPATH_W) 'codegen_timing_winchip2.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_winchip2.c'; fi` + pcem-compaq.o: compaq.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-compaq.Tpo $(DEPDIR)/pcem-compaq.Po @@ -1621,6 +1971,20 @@ pcem-cpu.obj: cpu.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-cpu_tables.o: cpu_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cpu_tables.o -MD -MP -MF $(DEPDIR)/pcem-cpu_tables.Tpo -c -o pcem-cpu_tables.o `test -f 'cpu_tables.c' || echo '$(srcdir)/'`cpu_tables.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cpu_tables.Tpo $(DEPDIR)/pcem-cpu_tables.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpu_tables.c' object='pcem-cpu_tables.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cpu_tables.o `test -f 'cpu_tables.c' || echo '$(srcdir)/'`cpu_tables.c + +pcem-cpu_tables.obj: cpu_tables.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cpu_tables.obj -MD -MP -MF $(DEPDIR)/pcem-cpu_tables.Tpo -c -o pcem-cpu_tables.obj `if test -f 'cpu_tables.c'; then $(CYGPATH_W) 'cpu_tables.c'; else $(CYGPATH_W) '$(srcdir)/cpu_tables.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cpu_tables.Tpo $(DEPDIR)/pcem-cpu_tables.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpu_tables.c' object='pcem-cpu_tables.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cpu_tables.obj `if test -f 'cpu_tables.c'; then $(CYGPATH_W) 'cpu_tables.c'; else $(CYGPATH_W) '$(srcdir)/cpu_tables.c'; fi` + pcem-dells200.o: dells200.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.o -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po @@ -1887,6 +2251,20 @@ pcem-i430fx.obj: i430fx.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-i430hx.o: i430hx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430hx.o -MD -MP -MF $(DEPDIR)/pcem-i430hx.Tpo -c -o pcem-i430hx.o `test -f 'i430hx.c' || echo '$(srcdir)/'`i430hx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-i430hx.Tpo $(DEPDIR)/pcem-i430hx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='i430hx.c' object='pcem-i430hx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430hx.o `test -f 'i430hx.c' || echo '$(srcdir)/'`i430hx.c + +pcem-i430hx.obj: i430hx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430hx.obj -MD -MP -MF $(DEPDIR)/pcem-i430hx.Tpo -c -o pcem-i430hx.obj `if test -f 'i430hx.c'; then $(CYGPATH_W) 'i430hx.c'; else $(CYGPATH_W) '$(srcdir)/i430hx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-i430hx.Tpo $(DEPDIR)/pcem-i430hx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='i430hx.c' object='pcem-i430hx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430hx.obj `if test -f 'i430hx.c'; then $(CYGPATH_W) 'i430hx.c'; else $(CYGPATH_W) '$(srcdir)/i430hx.c'; fi` + pcem-i430vx.o: i430vx.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-i430vx.Tpo $(DEPDIR)/pcem-i430vx.Po @@ -1929,6 +2307,20 @@ pcem-ide_atapi.obj: ide_atapi.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide_atapi.obj `if test -f 'ide_atapi.c'; then $(CYGPATH_W) 'ide_atapi.c'; else $(CYGPATH_W) '$(srcdir)/ide_atapi.c'; fi` +pcem-ide_sff8038i.o: ide_sff8038i.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ide_sff8038i.o -MD -MP -MF $(DEPDIR)/pcem-ide_sff8038i.Tpo -c -o pcem-ide_sff8038i.o `test -f 'ide_sff8038i.c' || echo '$(srcdir)/'`ide_sff8038i.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-ide_sff8038i.Tpo $(DEPDIR)/pcem-ide_sff8038i.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ide_sff8038i.c' object='pcem-ide_sff8038i.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide_sff8038i.o `test -f 'ide_sff8038i.c' || echo '$(srcdir)/'`ide_sff8038i.c + +pcem-ide_sff8038i.obj: ide_sff8038i.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ide_sff8038i.obj -MD -MP -MF $(DEPDIR)/pcem-ide_sff8038i.Tpo -c -o pcem-ide_sff8038i.obj `if test -f 'ide_sff8038i.c'; then $(CYGPATH_W) 'ide_sff8038i.c'; else $(CYGPATH_W) '$(srcdir)/ide_sff8038i.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-ide_sff8038i.Tpo $(DEPDIR)/pcem-ide_sff8038i.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ide_sff8038i.c' object='pcem-ide_sff8038i.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide_sff8038i.obj `if test -f 'ide_sff8038i.c'; then $(CYGPATH_W) 'ide_sff8038i.c'; else $(CYGPATH_W) '$(srcdir)/ide_sff8038i.c'; fi` + pcem-intel.o: intel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-intel.Tpo $(DEPDIR)/pcem-intel.Po @@ -2335,6 +2727,20 @@ pcem-mouse_serial.obj: mouse_serial.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-mvp3.o: mvp3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mvp3.o -MD -MP -MF $(DEPDIR)/pcem-mvp3.Tpo -c -o pcem-mvp3.o `test -f 'mvp3.c' || echo '$(srcdir)/'`mvp3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mvp3.Tpo $(DEPDIR)/pcem-mvp3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mvp3.c' object='pcem-mvp3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mvp3.o `test -f 'mvp3.c' || echo '$(srcdir)/'`mvp3.c + +pcem-mvp3.obj: mvp3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mvp3.obj -MD -MP -MF $(DEPDIR)/pcem-mvp3.Tpo -c -o pcem-mvp3.obj `if test -f 'mvp3.c'; then $(CYGPATH_W) 'mvp3.c'; else $(CYGPATH_W) '$(srcdir)/mvp3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-mvp3.Tpo $(DEPDIR)/pcem-mvp3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mvp3.c' object='pcem-mvp3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mvp3.obj `if test -f 'mvp3.c'; then $(CYGPATH_W) 'mvp3.c'; else $(CYGPATH_W) '$(srcdir)/mvp3.c'; fi` + pcem-neat.o: neat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-neat.Tpo $(DEPDIR)/pcem-neat.Po @@ -2587,6 +2993,20 @@ pcem-nvr_tc8521.obj: nvr_tc8521.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nvr_tc8521.obj `if test -f 'nvr_tc8521.c'; then $(CYGPATH_W) 'nvr_tc8521.c'; else $(CYGPATH_W) '$(srcdir)/nvr_tc8521.c'; fi` +pcem-pzx.o: pzx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pzx.o -MD -MP -MF $(DEPDIR)/pcem-pzx.Tpo -c -o pcem-pzx.o `test -f 'pzx.c' || echo '$(srcdir)/'`pzx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pzx.Tpo $(DEPDIR)/pcem-pzx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pzx.c' object='pcem-pzx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pzx.o `test -f 'pzx.c' || echo '$(srcdir)/'`pzx.c + +pcem-pzx.obj: pzx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pzx.obj -MD -MP -MF $(DEPDIR)/pcem-pzx.Tpo -c -o pcem-pzx.obj `if test -f 'pzx.c'; then $(CYGPATH_W) 'pzx.c'; else $(CYGPATH_W) '$(srcdir)/pzx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pzx.Tpo $(DEPDIR)/pcem-pzx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pzx.c' object='pcem-pzx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pzx.obj `if test -f 'pzx.c'; then $(CYGPATH_W) 'pzx.c'; else $(CYGPATH_W) '$(srcdir)/pzx.c'; fi` + pcem-rom.o: rom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-rom.Tpo $(DEPDIR)/pcem-rom.Po @@ -3077,6 +3497,20 @@ pcem-soundopenal.obj: soundopenal.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-sst39sf010.o: sst39sf010.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sst39sf010.o -MD -MP -MF $(DEPDIR)/pcem-sst39sf010.Tpo -c -o pcem-sst39sf010.o `test -f 'sst39sf010.c' || echo '$(srcdir)/'`sst39sf010.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sst39sf010.Tpo $(DEPDIR)/pcem-sst39sf010.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sst39sf010.c' object='pcem-sst39sf010.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sst39sf010.o `test -f 'sst39sf010.c' || echo '$(srcdir)/'`sst39sf010.c + +pcem-sst39sf010.obj: sst39sf010.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sst39sf010.obj -MD -MP -MF $(DEPDIR)/pcem-sst39sf010.Tpo -c -o pcem-sst39sf010.obj `if test -f 'sst39sf010.c'; then $(CYGPATH_W) 'sst39sf010.c'; else $(CYGPATH_W) '$(srcdir)/sst39sf010.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sst39sf010.Tpo $(DEPDIR)/pcem-sst39sf010.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sst39sf010.c' object='pcem-sst39sf010.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sst39sf010.obj `if test -f 'sst39sf010.c'; then $(CYGPATH_W) 'sst39sf010.c'; else $(CYGPATH_W) '$(srcdir)/sst39sf010.c'; fi` + pcem-tandy_eeprom.o: tandy_eeprom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-tandy_eeprom.o -MD -MP -MF $(DEPDIR)/pcem-tandy_eeprom.Tpo -c -o pcem-tandy_eeprom.o `test -f 'tandy_eeprom.c' || echo '$(srcdir)/'`tandy_eeprom.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-tandy_eeprom.Tpo $(DEPDIR)/pcem-tandy_eeprom.Po @@ -3371,6 +3805,20 @@ pcem-vid_hercules.obj: vid_hercules.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_ht216.o: vid_ht216.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ht216.o -MD -MP -MF $(DEPDIR)/pcem-vid_ht216.Tpo -c -o pcem-vid_ht216.o `test -f 'vid_ht216.c' || echo '$(srcdir)/'`vid_ht216.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ht216.Tpo $(DEPDIR)/pcem-vid_ht216.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_ht216.c' object='pcem-vid_ht216.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ht216.o `test -f 'vid_ht216.c' || echo '$(srcdir)/'`vid_ht216.c + +pcem-vid_ht216.obj: vid_ht216.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ht216.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ht216.Tpo -c -o pcem-vid_ht216.obj `if test -f 'vid_ht216.c'; then $(CYGPATH_W) 'vid_ht216.c'; else $(CYGPATH_W) '$(srcdir)/vid_ht216.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ht216.Tpo $(DEPDIR)/pcem-vid_ht216.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_ht216.c' object='pcem-vid_ht216.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ht216.obj `if test -f 'vid_ht216.c'; then $(CYGPATH_W) 'vid_ht216.c'; else $(CYGPATH_W) '$(srcdir)/vid_ht216.c'; fi` + pcem-vid_icd2061.o: vid_icd2061.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_icd2061.Tpo $(DEPDIR)/pcem-vid_icd2061.Po @@ -3399,6 +3847,20 @@ pcem-vid_ics2595.obj: vid_ics2595.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_im1024.o: vid_im1024.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_im1024.o -MD -MP -MF $(DEPDIR)/pcem-vid_im1024.Tpo -c -o pcem-vid_im1024.o `test -f 'vid_im1024.c' || echo '$(srcdir)/'`vid_im1024.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_im1024.Tpo $(DEPDIR)/pcem-vid_im1024.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_im1024.c' object='pcem-vid_im1024.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_im1024.o `test -f 'vid_im1024.c' || echo '$(srcdir)/'`vid_im1024.c + +pcem-vid_im1024.obj: vid_im1024.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_im1024.obj -MD -MP -MF $(DEPDIR)/pcem-vid_im1024.Tpo -c -o pcem-vid_im1024.obj `if test -f 'vid_im1024.c'; then $(CYGPATH_W) 'vid_im1024.c'; else $(CYGPATH_W) '$(srcdir)/vid_im1024.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_im1024.Tpo $(DEPDIR)/pcem-vid_im1024.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_im1024.c' object='pcem-vid_im1024.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_im1024.obj `if test -f 'vid_im1024.c'; then $(CYGPATH_W) 'vid_im1024.c'; else $(CYGPATH_W) '$(srcdir)/vid_im1024.c'; fi` + pcem-vid_incolor.o: vid_incolor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_incolor.o -MD -MP -MF $(DEPDIR)/pcem-vid_incolor.Tpo -c -o pcem-vid_incolor.o `test -f 'vid_incolor.c' || echo '$(srcdir)/'`vid_incolor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_incolor.Tpo $(DEPDIR)/pcem-vid_incolor.Po @@ -3539,6 +4001,20 @@ pcem-vid_pcjr.obj: vid_pcjr.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_pgc.o: vid_pgc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pgc.o -MD -MP -MF $(DEPDIR)/pcem-vid_pgc.Tpo -c -o pcem-vid_pgc.o `test -f 'vid_pgc.c' || echo '$(srcdir)/'`vid_pgc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_pgc.Tpo $(DEPDIR)/pcem-vid_pgc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_pgc.c' object='pcem-vid_pgc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pgc.o `test -f 'vid_pgc.c' || echo '$(srcdir)/'`vid_pgc.c + +pcem-vid_pgc.obj: vid_pgc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pgc.obj -MD -MP -MF $(DEPDIR)/pcem-vid_pgc.Tpo -c -o pcem-vid_pgc.obj `if test -f 'vid_pgc.c'; then $(CYGPATH_W) 'vid_pgc.c'; else $(CYGPATH_W) '$(srcdir)/vid_pgc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_pgc.Tpo $(DEPDIR)/pcem-vid_pgc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_pgc.c' object='pcem-vid_pgc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pgc.obj `if test -f 'vid_pgc.c'; then $(CYGPATH_W) 'vid_pgc.c'; else $(CYGPATH_W) '$(srcdir)/vid_pgc.c'; fi` + pcem-vid_ps1_svga.o: vid_ps1_svga.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ps1_svga.o -MD -MP -MF $(DEPDIR)/pcem-vid_ps1_svga.Tpo -c -o pcem-vid_ps1_svga.o `test -f 'vid_ps1_svga.c' || echo '$(srcdir)/'`vid_ps1_svga.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ps1_svga.Tpo $(DEPDIR)/pcem-vid_ps1_svga.Po @@ -3595,6 +4071,20 @@ pcem-vid_sdac_ramdac.obj: vid_sdac_ramdac.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_sigma.o: vid_sigma.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_sigma.o -MD -MP -MF $(DEPDIR)/pcem-vid_sigma.Tpo -c -o pcem-vid_sigma.o `test -f 'vid_sigma.c' || echo '$(srcdir)/'`vid_sigma.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_sigma.Tpo $(DEPDIR)/pcem-vid_sigma.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_sigma.c' object='pcem-vid_sigma.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_sigma.o `test -f 'vid_sigma.c' || echo '$(srcdir)/'`vid_sigma.c + +pcem-vid_sigma.obj: vid_sigma.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_sigma.obj -MD -MP -MF $(DEPDIR)/pcem-vid_sigma.Tpo -c -o pcem-vid_sigma.obj `if test -f 'vid_sigma.c'; then $(CYGPATH_W) 'vid_sigma.c'; else $(CYGPATH_W) '$(srcdir)/vid_sigma.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_sigma.Tpo $(DEPDIR)/pcem-vid_sigma.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_sigma.c' object='pcem-vid_sigma.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_sigma.obj `if test -f 'vid_sigma.c'; then $(CYGPATH_W) 'vid_sigma.c'; else $(CYGPATH_W) '$(srcdir)/vid_sigma.c'; fi` + pcem-vid_stg_ramdac.o: vid_stg_ramdac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_stg_ramdac.Tpo $(DEPDIR)/pcem-vid_stg_ramdac.Po @@ -3819,6 +4309,34 @@ pcem-vid_wy700.obj: vid_wy700.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_wy700.obj `if test -f 'vid_wy700.c'; then $(CYGPATH_W) 'vid_wy700.c'; else $(CYGPATH_W) '$(srcdir)/vid_wy700.c'; fi` +pcem-vt82c586b.o: vt82c586b.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vt82c586b.o -MD -MP -MF $(DEPDIR)/pcem-vt82c586b.Tpo -c -o pcem-vt82c586b.o `test -f 'vt82c586b.c' || echo '$(srcdir)/'`vt82c586b.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vt82c586b.Tpo $(DEPDIR)/pcem-vt82c586b.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vt82c586b.c' object='pcem-vt82c586b.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vt82c586b.o `test -f 'vt82c586b.c' || echo '$(srcdir)/'`vt82c586b.c + +pcem-vt82c586b.obj: vt82c586b.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vt82c586b.obj -MD -MP -MF $(DEPDIR)/pcem-vt82c586b.Tpo -c -o pcem-vt82c586b.obj `if test -f 'vt82c586b.c'; then $(CYGPATH_W) 'vt82c586b.c'; else $(CYGPATH_W) '$(srcdir)/vt82c586b.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vt82c586b.Tpo $(DEPDIR)/pcem-vt82c586b.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vt82c586b.c' object='pcem-vt82c586b.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vt82c586b.obj `if test -f 'vt82c586b.c'; then $(CYGPATH_W) 'vt82c586b.c'; else $(CYGPATH_W) '$(srcdir)/vt82c586b.c'; fi` + +pcem-w83877tf.o: w83877tf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-w83877tf.o -MD -MP -MF $(DEPDIR)/pcem-w83877tf.Tpo -c -o pcem-w83877tf.o `test -f 'w83877tf.c' || echo '$(srcdir)/'`w83877tf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-w83877tf.Tpo $(DEPDIR)/pcem-w83877tf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='w83877tf.c' object='pcem-w83877tf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-w83877tf.o `test -f 'w83877tf.c' || echo '$(srcdir)/'`w83877tf.c + +pcem-w83877tf.obj: w83877tf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-w83877tf.obj -MD -MP -MF $(DEPDIR)/pcem-w83877tf.Tpo -c -o pcem-w83877tf.obj `if test -f 'w83877tf.c'; then $(CYGPATH_W) 'w83877tf.c'; else $(CYGPATH_W) '$(srcdir)/w83877tf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-w83877tf.Tpo $(DEPDIR)/pcem-w83877tf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='w83877tf.c' object='pcem-w83877tf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-w83877tf.obj `if test -f 'w83877tf.c'; then $(CYGPATH_W) 'w83877tf.c'; else $(CYGPATH_W) '$(srcdir)/w83877tf.c'; fi` + pcem-x86seg.o: x86seg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-x86seg.Tpo $(DEPDIR)/pcem-x86seg.Po @@ -4127,6 +4645,48 @@ pcem-codegen_backend_x86.obj: codegen_backend_x86.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86.obj `if test -f 'codegen_backend_x86.c'; then $(CYGPATH_W) 'codegen_backend_x86.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86.c'; fi` +pcem-codegen_backend_x86_ops.o: codegen_backend_x86_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_ops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_ops.Tpo -c -o pcem-codegen_backend_x86_ops.o `test -f 'codegen_backend_x86_ops.c' || echo '$(srcdir)/'`codegen_backend_x86_ops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_ops.Tpo $(DEPDIR)/pcem-codegen_backend_x86_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_ops.c' object='pcem-codegen_backend_x86_ops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_ops.o `test -f 'codegen_backend_x86_ops.c' || echo '$(srcdir)/'`codegen_backend_x86_ops.c + +pcem-codegen_backend_x86_ops.obj: codegen_backend_x86_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_ops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_ops.Tpo -c -o pcem-codegen_backend_x86_ops.obj `if test -f 'codegen_backend_x86_ops.c'; then $(CYGPATH_W) 'codegen_backend_x86_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_ops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_ops.Tpo $(DEPDIR)/pcem-codegen_backend_x86_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_ops.c' object='pcem-codegen_backend_x86_ops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_ops.obj `if test -f 'codegen_backend_x86_ops.c'; then $(CYGPATH_W) 'codegen_backend_x86_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_ops.c'; fi` + +pcem-codegen_backend_x86_ops_fpu.o: codegen_backend_x86_ops_fpu.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_ops_fpu.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Tpo -c -o pcem-codegen_backend_x86_ops_fpu.o `test -f 'codegen_backend_x86_ops_fpu.c' || echo '$(srcdir)/'`codegen_backend_x86_ops_fpu.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Tpo $(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_ops_fpu.c' object='pcem-codegen_backend_x86_ops_fpu.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_ops_fpu.o `test -f 'codegen_backend_x86_ops_fpu.c' || echo '$(srcdir)/'`codegen_backend_x86_ops_fpu.c + +pcem-codegen_backend_x86_ops_fpu.obj: codegen_backend_x86_ops_fpu.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_ops_fpu.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Tpo -c -o pcem-codegen_backend_x86_ops_fpu.obj `if test -f 'codegen_backend_x86_ops_fpu.c'; then $(CYGPATH_W) 'codegen_backend_x86_ops_fpu.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_ops_fpu.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Tpo $(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_ops_fpu.c' object='pcem-codegen_backend_x86_ops_fpu.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_ops_fpu.obj `if test -f 'codegen_backend_x86_ops_fpu.c'; then $(CYGPATH_W) 'codegen_backend_x86_ops_fpu.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_ops_fpu.c'; fi` + +pcem-codegen_backend_x86_ops_sse.o: codegen_backend_x86_ops_sse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_ops_sse.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Tpo -c -o pcem-codegen_backend_x86_ops_sse.o `test -f 'codegen_backend_x86_ops_sse.c' || echo '$(srcdir)/'`codegen_backend_x86_ops_sse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Tpo $(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_ops_sse.c' object='pcem-codegen_backend_x86_ops_sse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_ops_sse.o `test -f 'codegen_backend_x86_ops_sse.c' || echo '$(srcdir)/'`codegen_backend_x86_ops_sse.c + +pcem-codegen_backend_x86_ops_sse.obj: codegen_backend_x86_ops_sse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_ops_sse.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Tpo -c -o pcem-codegen_backend_x86_ops_sse.obj `if test -f 'codegen_backend_x86_ops_sse.c'; then $(CYGPATH_W) 'codegen_backend_x86_ops_sse.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_ops_sse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Tpo $(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86_ops_sse.c' object='pcem-codegen_backend_x86_ops_sse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86_ops_sse.obj `if test -f 'codegen_backend_x86_ops_sse.c'; then $(CYGPATH_W) 'codegen_backend_x86_ops_sse.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86_ops_sse.c'; fi` + pcem-codegen_backend_x86_uops.o: codegen_backend_x86_uops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86_uops.Tpo -c -o pcem-codegen_backend_x86_uops.o `test -f 'codegen_backend_x86_uops.c' || echo '$(srcdir)/'`codegen_backend_x86_uops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86_uops.Tpo $(DEPDIR)/pcem-codegen_backend_x86_uops.Po @@ -4155,6 +4715,34 @@ pcem-codegen_backend_x86-64.obj: codegen_backend_x86-64.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64.obj `if test -f 'codegen_backend_x86-64.c'; then $(CYGPATH_W) 'codegen_backend_x86-64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64.c'; fi` +pcem-codegen_backend_x86-64_ops.o: codegen_backend_x86-64_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_ops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_ops.Tpo -c -o pcem-codegen_backend_x86-64_ops.o `test -f 'codegen_backend_x86-64_ops.c' || echo '$(srcdir)/'`codegen_backend_x86-64_ops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_ops.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64_ops.c' object='pcem-codegen_backend_x86-64_ops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64_ops.o `test -f 'codegen_backend_x86-64_ops.c' || echo '$(srcdir)/'`codegen_backend_x86-64_ops.c + +pcem-codegen_backend_x86-64_ops.obj: codegen_backend_x86-64_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_ops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_ops.Tpo -c -o pcem-codegen_backend_x86-64_ops.obj `if test -f 'codegen_backend_x86-64_ops.c'; then $(CYGPATH_W) 'codegen_backend_x86-64_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64_ops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_ops.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64_ops.c' object='pcem-codegen_backend_x86-64_ops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64_ops.obj `if test -f 'codegen_backend_x86-64_ops.c'; then $(CYGPATH_W) 'codegen_backend_x86-64_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64_ops.c'; fi` + +pcem-codegen_backend_x86-64_ops_sse.o: codegen_backend_x86-64_ops_sse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_ops_sse.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Tpo -c -o pcem-codegen_backend_x86-64_ops_sse.o `test -f 'codegen_backend_x86-64_ops_sse.c' || echo '$(srcdir)/'`codegen_backend_x86-64_ops_sse.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64_ops_sse.c' object='pcem-codegen_backend_x86-64_ops_sse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64_ops_sse.o `test -f 'codegen_backend_x86-64_ops_sse.c' || echo '$(srcdir)/'`codegen_backend_x86-64_ops_sse.c + +pcem-codegen_backend_x86-64_ops_sse.obj: codegen_backend_x86-64_ops_sse.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_ops_sse.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Tpo -c -o pcem-codegen_backend_x86-64_ops_sse.obj `if test -f 'codegen_backend_x86-64_ops_sse.c'; then $(CYGPATH_W) 'codegen_backend_x86-64_ops_sse.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64_ops_sse.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_x86-64_ops_sse.c' object='pcem-codegen_backend_x86-64_ops_sse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_x86-64_ops_sse.obj `if test -f 'codegen_backend_x86-64_ops_sse.c'; then $(CYGPATH_W) 'codegen_backend_x86-64_ops_sse.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_x86-64_ops_sse.c'; fi` + pcem-codegen_backend_x86-64_uops.o: codegen_backend_x86-64_uops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_x86-64_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Tpo -c -o pcem-codegen_backend_x86-64_uops.o `test -f 'codegen_backend_x86-64_uops.c' || echo '$(srcdir)/'`codegen_backend_x86-64_uops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Tpo $(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po @@ -4183,6 +4771,20 @@ pcem-codegen_backend_arm.obj: codegen_backend_arm.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm.obj `if test -f 'codegen_backend_arm.c'; then $(CYGPATH_W) 'codegen_backend_arm.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm.c'; fi` +pcem-codegen_backend_arm_ops.o: codegen_backend_arm_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm_ops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm_ops.Tpo -c -o pcem-codegen_backend_arm_ops.o `test -f 'codegen_backend_arm_ops.c' || echo '$(srcdir)/'`codegen_backend_arm_ops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm_ops.Tpo $(DEPDIR)/pcem-codegen_backend_arm_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm_ops.c' object='pcem-codegen_backend_arm_ops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm_ops.o `test -f 'codegen_backend_arm_ops.c' || echo '$(srcdir)/'`codegen_backend_arm_ops.c + +pcem-codegen_backend_arm_ops.obj: codegen_backend_arm_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm_ops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm_ops.Tpo -c -o pcem-codegen_backend_arm_ops.obj `if test -f 'codegen_backend_arm_ops.c'; then $(CYGPATH_W) 'codegen_backend_arm_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm_ops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm_ops.Tpo $(DEPDIR)/pcem-codegen_backend_arm_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm_ops.c' object='pcem-codegen_backend_arm_ops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm_ops.obj `if test -f 'codegen_backend_arm_ops.c'; then $(CYGPATH_W) 'codegen_backend_arm_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm_ops.c'; fi` + pcem-codegen_backend_arm_uops.o: codegen_backend_arm_uops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm_uops.Tpo -c -o pcem-codegen_backend_arm_uops.o `test -f 'codegen_backend_arm_uops.c' || echo '$(srcdir)/'`codegen_backend_arm_uops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm_uops.Tpo $(DEPDIR)/pcem-codegen_backend_arm_uops.Po @@ -4211,6 +4813,34 @@ pcem-codegen_backend_arm64.obj: codegen_backend_arm64.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64.obj `if test -f 'codegen_backend_arm64.c'; then $(CYGPATH_W) 'codegen_backend_arm64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64.c'; fi` +pcem-codegen_backend_arm64_imm.o: codegen_backend_arm64_imm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_imm.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_imm.Tpo -c -o pcem-codegen_backend_arm64_imm.o `test -f 'codegen_backend_arm64_imm.c' || echo '$(srcdir)/'`codegen_backend_arm64_imm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_imm.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_imm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64_imm.c' object='pcem-codegen_backend_arm64_imm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64_imm.o `test -f 'codegen_backend_arm64_imm.c' || echo '$(srcdir)/'`codegen_backend_arm64_imm.c + +pcem-codegen_backend_arm64_imm.obj: codegen_backend_arm64_imm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_imm.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_imm.Tpo -c -o pcem-codegen_backend_arm64_imm.obj `if test -f 'codegen_backend_arm64_imm.c'; then $(CYGPATH_W) 'codegen_backend_arm64_imm.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64_imm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_imm.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_imm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64_imm.c' object='pcem-codegen_backend_arm64_imm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64_imm.obj `if test -f 'codegen_backend_arm64_imm.c'; then $(CYGPATH_W) 'codegen_backend_arm64_imm.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64_imm.c'; fi` + +pcem-codegen_backend_arm64_ops.o: codegen_backend_arm64_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_ops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_ops.Tpo -c -o pcem-codegen_backend_arm64_ops.o `test -f 'codegen_backend_arm64_ops.c' || echo '$(srcdir)/'`codegen_backend_arm64_ops.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_ops.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64_ops.c' object='pcem-codegen_backend_arm64_ops.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64_ops.o `test -f 'codegen_backend_arm64_ops.c' || echo '$(srcdir)/'`codegen_backend_arm64_ops.c + +pcem-codegen_backend_arm64_ops.obj: codegen_backend_arm64_ops.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_ops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_ops.Tpo -c -o pcem-codegen_backend_arm64_ops.obj `if test -f 'codegen_backend_arm64_ops.c'; then $(CYGPATH_W) 'codegen_backend_arm64_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64_ops.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_ops.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_ops.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_backend_arm64_ops.c' object='pcem-codegen_backend_arm64_ops.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_backend_arm64_ops.obj `if test -f 'codegen_backend_arm64_ops.c'; then $(CYGPATH_W) 'codegen_backend_arm64_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_backend_arm64_ops.c'; fi` + pcem-codegen_backend_arm64_uops.o: codegen_backend_arm64_uops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_backend_arm64_uops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_backend_arm64_uops.Tpo -c -o pcem-codegen_backend_arm64_uops.o `test -f 'codegen_backend_arm64_uops.c' || echo '$(srcdir)/'`codegen_backend_arm64_uops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_backend_arm64_uops.Tpo $(DEPDIR)/pcem-codegen_backend_arm64_uops.Po @@ -5163,10 +5793,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -5245,275 +5872,7 @@ clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/pcem-386.Po - -rm -f ./$(DEPDIR)/pcem-386_dynarec.Po - -rm -f ./$(DEPDIR)/pcem-386_dynarec_ops.Po - -rm -f ./$(DEPDIR)/pcem-808x.Po - -rm -f ./$(DEPDIR)/pcem-acc2036.Po - -rm -f ./$(DEPDIR)/pcem-acer386sx.Po - -rm -f ./$(DEPDIR)/pcem-ali1429.Po - -rm -f ./$(DEPDIR)/pcem-amstrad.Po - -rm -f ./$(DEPDIR)/pcem-cbm_io.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-image.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-null.Po - -rm -f ./$(DEPDIR)/pcem-cmd640.Po - -rm -f ./$(DEPDIR)/pcem-codegen.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_ir.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_486.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_686.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_common.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_pentium.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip.Po - -rm -f ./$(DEPDIR)/pcem-compaq.Po - -rm -f ./$(DEPDIR)/pcem-config.Po - -rm -f ./$(DEPDIR)/pcem-cpu.Po - -rm -f ./$(DEPDIR)/pcem-dells200.Po - -rm -f ./$(DEPDIR)/pcem-device.Po - -rm -f ./$(DEPDIR)/pcem-disc.Po - -rm -f ./$(DEPDIR)/pcem-disc_fdi.Po - -rm -f ./$(DEPDIR)/pcem-disc_img.Po - -rm -f ./$(DEPDIR)/pcem-disc_sector.Po - -rm -f ./$(DEPDIR)/pcem-dma.Po - -rm -f ./$(DEPDIR)/pcem-esdi_at.Po - -rm -f ./$(DEPDIR)/pcem-fdc.Po - -rm -f ./$(DEPDIR)/pcem-fdc37c665.Po - -rm -f ./$(DEPDIR)/pcem-fdd.Po - -rm -f ./$(DEPDIR)/pcem-fdi2raw.Po - -rm -f ./$(DEPDIR)/pcem-gameport.Po - -rm -f ./$(DEPDIR)/pcem-hdd.Po - -rm -f ./$(DEPDIR)/pcem-hdd_esdi.Po - -rm -f ./$(DEPDIR)/pcem-hdd_file.Po - -rm -f ./$(DEPDIR)/pcem-headland.Po - -rm -f ./$(DEPDIR)/pcem-i430fx.Po - -rm -f ./$(DEPDIR)/pcem-i430lx.Po - -rm -f ./$(DEPDIR)/pcem-i430vx.Po - -rm -f ./$(DEPDIR)/pcem-ide.Po - -rm -f ./$(DEPDIR)/pcem-ide_atapi.Po - -rm -f ./$(DEPDIR)/pcem-intel.Po - -rm -f ./$(DEPDIR)/pcem-intel_flash.Po - -rm -f ./$(DEPDIR)/pcem-io.Po - -rm -f ./$(DEPDIR)/pcem-jim.Po - -rm -f ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po - -rm -f ./$(DEPDIR)/pcem-joystick_standard.Po - -rm -f ./$(DEPDIR)/pcem-joystick_sw_pad.Po - -rm -f ./$(DEPDIR)/pcem-joystick_tm_fcs.Po - -rm -f ./$(DEPDIR)/pcem-keyboard.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_amstrad.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_at.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_olim24.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_pcjr.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_xt.Po - -rm -f ./$(DEPDIR)/pcem-laserxt.Po - -rm -f ./$(DEPDIR)/pcem-lpt.Po - -rm -f ./$(DEPDIR)/pcem-lpt_dac.Po - -rm -f ./$(DEPDIR)/pcem-lpt_dss.Po - -rm -f ./$(DEPDIR)/pcem-mca.Po - -rm -f ./$(DEPDIR)/pcem-mcr.Po - -rm -f ./$(DEPDIR)/pcem-mem.Po - -rm -f ./$(DEPDIR)/pcem-mem_bios.Po - -rm -f ./$(DEPDIR)/pcem-mfm_at.Po - -rm -f ./$(DEPDIR)/pcem-mfm_xebec.Po - -rm -f ./$(DEPDIR)/pcem-midi_alsa.Po - -rm -f ./$(DEPDIR)/pcem-model.Po - -rm -f ./$(DEPDIR)/pcem-mouse.Po - -rm -f ./$(DEPDIR)/pcem-mouse_msystems.Po - -rm -f ./$(DEPDIR)/pcem-mouse_ps2.Po - -rm -f ./$(DEPDIR)/pcem-mouse_serial.Po - -rm -f ./$(DEPDIR)/pcem-ne2000.Po - -rm -f ./$(DEPDIR)/pcem-neat.Po - -rm -f ./$(DEPDIR)/pcem-nethandler.Po - -rm -f ./$(DEPDIR)/pcem-nmi.Po - -rm -f ./$(DEPDIR)/pcem-nvr.Po - -rm -f ./$(DEPDIR)/pcem-nvr_tc8521.Po - -rm -f ./$(DEPDIR)/pcem-olivetti_m24.Po - -rm -f ./$(DEPDIR)/pcem-opti495.Po - -rm -f ./$(DEPDIR)/pcem-paths.Po - -rm -f ./$(DEPDIR)/pcem-pc.Po - -rm -f ./$(DEPDIR)/pcem-pc87306.Po - -rm -f ./$(DEPDIR)/pcem-pci.Po - -rm -f ./$(DEPDIR)/pcem-pic.Po - -rm -f ./$(DEPDIR)/pcem-piix.Po - -rm -f ./$(DEPDIR)/pcem-pit.Po - -rm -f ./$(DEPDIR)/pcem-ppi.Po - -rm -f ./$(DEPDIR)/pcem-ps1.Po - -rm -f ./$(DEPDIR)/pcem-ps2.Po - -rm -f ./$(DEPDIR)/pcem-ps2_mca.Po - -rm -f ./$(DEPDIR)/pcem-ps2_nvr.Po - -rm -f ./$(DEPDIR)/pcem-rom.Po - -rm -f ./$(DEPDIR)/pcem-rtc.Po - -rm -f ./$(DEPDIR)/pcem-rtc_tc8521.Po - -rm -f ./$(DEPDIR)/pcem-scat.Po - -rm -f ./$(DEPDIR)/pcem-scsi.Po - -rm -f ./$(DEPDIR)/pcem-scsi_53c400.Po - -rm -f ./$(DEPDIR)/pcem-scsi_aha1540.Po - -rm -f ./$(DEPDIR)/pcem-scsi_cd.Po - -rm -f ./$(DEPDIR)/pcem-scsi_hd.Po - -rm -f ./$(DEPDIR)/pcem-scsi_zip.Po - -rm -f ./$(DEPDIR)/pcem-serial.Po - -rm -f ./$(DEPDIR)/pcem-sio.Po - -rm -f ./$(DEPDIR)/pcem-sis496.Po - -rm -f ./$(DEPDIR)/pcem-sl82c460.Po - -rm -f ./$(DEPDIR)/pcem-sound.Po - -rm -f ./$(DEPDIR)/pcem-sound_ad1848.Po - -rm -f ./$(DEPDIR)/pcem-sound_adlib.Po - -rm -f ./$(DEPDIR)/pcem-sound_adlibgold.Po - -rm -f ./$(DEPDIR)/pcem-sound_audiopci.Po - -rm -f ./$(DEPDIR)/pcem-sound_cms.Po - -rm -f ./$(DEPDIR)/pcem-sound_dbopl.Po - -rm -f ./$(DEPDIR)/pcem-sound_emu8k.Po - -rm -f ./$(DEPDIR)/pcem-sound_gus.Po - -rm -f ./$(DEPDIR)/pcem-sound_mpu401_uart.Po - -rm -f ./$(DEPDIR)/pcem-sound_opl.Po - -rm -f ./$(DEPDIR)/pcem-sound_pas16.Po - -rm -f ./$(DEPDIR)/pcem-sound_ps1.Po - -rm -f ./$(DEPDIR)/pcem-sound_pssj.Po - -rm -f ./$(DEPDIR)/pcem-sound_resid.Po - -rm -f ./$(DEPDIR)/pcem-sound_sb.Po - -rm -f ./$(DEPDIR)/pcem-sound_sb_dsp.Po - -rm -f ./$(DEPDIR)/pcem-sound_sn76489.Po - -rm -f ./$(DEPDIR)/pcem-sound_speaker.Po - -rm -f ./$(DEPDIR)/pcem-sound_ssi2001.Po - -rm -f ./$(DEPDIR)/pcem-sound_wss.Po - -rm -f ./$(DEPDIR)/pcem-sound_ym7128.Po - -rm -f ./$(DEPDIR)/pcem-soundopenal.Po - -rm -f ./$(DEPDIR)/pcem-t1000.Po - -rm -f ./$(DEPDIR)/pcem-t3100e.Po - -rm -f ./$(DEPDIR)/pcem-tandy_eeprom.Po - -rm -f ./$(DEPDIR)/pcem-tandy_rom.Po - -rm -f ./$(DEPDIR)/pcem-timer.Po - -rm -f ./$(DEPDIR)/pcem-um8669f.Po - -rm -f ./$(DEPDIR)/pcem-um8881f.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati18800.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati28800.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati_eeprom.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati_mach64.Po - -rm -f ./$(DEPDIR)/pcem-vid_cga.Po - -rm -f ./$(DEPDIR)/pcem-vid_cl5429.Po - -rm -f ./$(DEPDIR)/pcem-vid_colorplus.Po - -rm -f ./$(DEPDIR)/pcem-vid_compaq_cga.Po - -rm -f ./$(DEPDIR)/pcem-vid_ega.Po - -rm -f ./$(DEPDIR)/pcem-vid_et4000.Po - -rm -f ./$(DEPDIR)/pcem-vid_et4000w32.Po - -rm -f ./$(DEPDIR)/pcem-vid_genius.Po - -rm -f ./$(DEPDIR)/pcem-vid_hercules.Po - -rm -f ./$(DEPDIR)/pcem-vid_icd2061.Po - -rm -f ./$(DEPDIR)/pcem-vid_ics2595.Po - -rm -f ./$(DEPDIR)/pcem-vid_incolor.Po - -rm -f ./$(DEPDIR)/pcem-vid_mda.Po - -rm -f ./$(DEPDIR)/pcem-vid_olivetti_m24.Po - -rm -f ./$(DEPDIR)/pcem-vid_oti037.Po - -rm -f ./$(DEPDIR)/pcem-vid_oti067.Po - -rm -f ./$(DEPDIR)/pcem-vid_paradise.Po - -rm -f ./$(DEPDIR)/pcem-vid_pc1512.Po - -rm -f ./$(DEPDIR)/pcem-vid_pc1640.Po - -rm -f ./$(DEPDIR)/pcem-vid_pc200.Po - -rm -f ./$(DEPDIR)/pcem-vid_pcjr.Po - -rm -f ./$(DEPDIR)/pcem-vid_ps1_svga.Po - -rm -f ./$(DEPDIR)/pcem-vid_s3.Po - -rm -f ./$(DEPDIR)/pcem-vid_s3_virge.Po - -rm -f ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_stg_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_svga.Po - -rm -f ./$(DEPDIR)/pcem-vid_svga_render.Po - -rm -f ./$(DEPDIR)/pcem-vid_t1000.Po - -rm -f ./$(DEPDIR)/pcem-vid_t3100e.Po - -rm -f ./$(DEPDIR)/pcem-vid_tandy.Po - -rm -f ./$(DEPDIR)/pcem-vid_tandysl.Po - -rm -f ./$(DEPDIR)/pcem-vid_tgui9440.Po - -rm -f ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_tvga.Po - -rm -f ./$(DEPDIR)/pcem-vid_unk_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_vga.Po - -rm -f ./$(DEPDIR)/pcem-vid_voodoo.Po - -rm -f ./$(DEPDIR)/pcem-vid_wy700.Po - -rm -f ./$(DEPDIR)/pcem-video.Po - -rm -f ./$(DEPDIR)/pcem-wd76c10.Po - -rm -f ./$(DEPDIR)/pcem-wx-app.Po - -rm -f ./$(DEPDIR)/pcem-wx-common.Po - -rm -f ./$(DEPDIR)/pcem-wx-config.Po - -rm -f ./$(DEPDIR)/pcem-wx-config_sel.Po - -rm -f ./$(DEPDIR)/pcem-wx-createdisc.Po - -rm -f ./$(DEPDIR)/pcem-wx-deviceconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-dialogbox.Po - -rm -f ./$(DEPDIR)/pcem-wx-glslp-parser.Po - -rm -f ./$(DEPDIR)/pcem-wx-hostconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-joystickconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-main.Po - -rm -f ./$(DEPDIR)/pcem-wx-resources.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-midi.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-status.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2.Po - -rm -f ./$(DEPDIR)/pcem-wx-shader_man.Po - -rm -f ./$(DEPDIR)/pcem-wx-shaderconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-status.Po - -rm -f ./$(DEPDIR)/pcem-wx-thread.Po - -rm -f ./$(DEPDIR)/pcem-wx-utils.Po - -rm -f ./$(DEPDIR)/pcem-x86seg.Po - -rm -f ./$(DEPDIR)/pcem-x87.Po - -rm -f ./$(DEPDIR)/pcem-xi8088.Po - -rm -f ./$(DEPDIR)/pcem-xtide.Po - -rm -f dosbox/$(DEPDIR)/pcem-cdrom_image.Po - -rm -f dosbox/$(DEPDIR)/pcem-dbopl.Po - -rm -f dosbox/$(DEPDIR)/pcem-nukedopl.Po - -rm -f dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po - -rm -f resid-fp/$(DEPDIR)/pcem-convolve-sse.Po - -rm -f resid-fp/$(DEPDIR)/pcem-convolve.Po - -rm -f resid-fp/$(DEPDIR)/pcem-envelope.Po - -rm -f resid-fp/$(DEPDIR)/pcem-extfilt.Po - -rm -f resid-fp/$(DEPDIR)/pcem-filter.Po - -rm -f resid-fp/$(DEPDIR)/pcem-pot.Po - -rm -f resid-fp/$(DEPDIR)/pcem-sid.Po - -rm -f resid-fp/$(DEPDIR)/pcem-voice.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po - -rm -f slirp/$(DEPDIR)/pcem-bootp.Po - -rm -f slirp/$(DEPDIR)/pcem-cksum.Po - -rm -f slirp/$(DEPDIR)/pcem-debug.Po - -rm -f slirp/$(DEPDIR)/pcem-if.Po - -rm -f slirp/$(DEPDIR)/pcem-ip_icmp.Po - -rm -f slirp/$(DEPDIR)/pcem-ip_input.Po - -rm -f slirp/$(DEPDIR)/pcem-ip_output.Po - -rm -f slirp/$(DEPDIR)/pcem-mbuf.Po - -rm -f slirp/$(DEPDIR)/pcem-misc.Po - -rm -f slirp/$(DEPDIR)/pcem-queue.Po - -rm -f slirp/$(DEPDIR)/pcem-sbuf.Po - -rm -f slirp/$(DEPDIR)/pcem-slirp.Po - -rm -f slirp/$(DEPDIR)/pcem-socket.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_input.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_output.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_subr.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_timer.Po - -rm -f slirp/$(DEPDIR)/pcem-tftp.Po - -rm -f slirp/$(DEPDIR)/pcem-udp.Po + -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -5559,275 +5918,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/pcem-386.Po - -rm -f ./$(DEPDIR)/pcem-386_dynarec.Po - -rm -f ./$(DEPDIR)/pcem-386_dynarec_ops.Po - -rm -f ./$(DEPDIR)/pcem-808x.Po - -rm -f ./$(DEPDIR)/pcem-acc2036.Po - -rm -f ./$(DEPDIR)/pcem-acer386sx.Po - -rm -f ./$(DEPDIR)/pcem-ali1429.Po - -rm -f ./$(DEPDIR)/pcem-amstrad.Po - -rm -f ./$(DEPDIR)/pcem-cbm_io.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-image.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl.Po - -rm -f ./$(DEPDIR)/pcem-cdrom-null.Po - -rm -f ./$(DEPDIR)/pcem-cmd640.Po - -rm -f ./$(DEPDIR)/pcem-codegen.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86.Po - -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po - -rm -f ./$(DEPDIR)/pcem-codegen_ir.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_486.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_686.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_common.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_pentium.Po - -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip.Po - -rm -f ./$(DEPDIR)/pcem-compaq.Po - -rm -f ./$(DEPDIR)/pcem-config.Po - -rm -f ./$(DEPDIR)/pcem-cpu.Po - -rm -f ./$(DEPDIR)/pcem-dells200.Po - -rm -f ./$(DEPDIR)/pcem-device.Po - -rm -f ./$(DEPDIR)/pcem-disc.Po - -rm -f ./$(DEPDIR)/pcem-disc_fdi.Po - -rm -f ./$(DEPDIR)/pcem-disc_img.Po - -rm -f ./$(DEPDIR)/pcem-disc_sector.Po - -rm -f ./$(DEPDIR)/pcem-dma.Po - -rm -f ./$(DEPDIR)/pcem-esdi_at.Po - -rm -f ./$(DEPDIR)/pcem-fdc.Po - -rm -f ./$(DEPDIR)/pcem-fdc37c665.Po - -rm -f ./$(DEPDIR)/pcem-fdd.Po - -rm -f ./$(DEPDIR)/pcem-fdi2raw.Po - -rm -f ./$(DEPDIR)/pcem-gameport.Po - -rm -f ./$(DEPDIR)/pcem-hdd.Po - -rm -f ./$(DEPDIR)/pcem-hdd_esdi.Po - -rm -f ./$(DEPDIR)/pcem-hdd_file.Po - -rm -f ./$(DEPDIR)/pcem-headland.Po - -rm -f ./$(DEPDIR)/pcem-i430fx.Po - -rm -f ./$(DEPDIR)/pcem-i430lx.Po - -rm -f ./$(DEPDIR)/pcem-i430vx.Po - -rm -f ./$(DEPDIR)/pcem-ide.Po - -rm -f ./$(DEPDIR)/pcem-ide_atapi.Po - -rm -f ./$(DEPDIR)/pcem-intel.Po - -rm -f ./$(DEPDIR)/pcem-intel_flash.Po - -rm -f ./$(DEPDIR)/pcem-io.Po - -rm -f ./$(DEPDIR)/pcem-jim.Po - -rm -f ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po - -rm -f ./$(DEPDIR)/pcem-joystick_standard.Po - -rm -f ./$(DEPDIR)/pcem-joystick_sw_pad.Po - -rm -f ./$(DEPDIR)/pcem-joystick_tm_fcs.Po - -rm -f ./$(DEPDIR)/pcem-keyboard.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_amstrad.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_at.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_olim24.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_pcjr.Po - -rm -f ./$(DEPDIR)/pcem-keyboard_xt.Po - -rm -f ./$(DEPDIR)/pcem-laserxt.Po - -rm -f ./$(DEPDIR)/pcem-lpt.Po - -rm -f ./$(DEPDIR)/pcem-lpt_dac.Po - -rm -f ./$(DEPDIR)/pcem-lpt_dss.Po - -rm -f ./$(DEPDIR)/pcem-mca.Po - -rm -f ./$(DEPDIR)/pcem-mcr.Po - -rm -f ./$(DEPDIR)/pcem-mem.Po - -rm -f ./$(DEPDIR)/pcem-mem_bios.Po - -rm -f ./$(DEPDIR)/pcem-mfm_at.Po - -rm -f ./$(DEPDIR)/pcem-mfm_xebec.Po - -rm -f ./$(DEPDIR)/pcem-midi_alsa.Po - -rm -f ./$(DEPDIR)/pcem-model.Po - -rm -f ./$(DEPDIR)/pcem-mouse.Po - -rm -f ./$(DEPDIR)/pcem-mouse_msystems.Po - -rm -f ./$(DEPDIR)/pcem-mouse_ps2.Po - -rm -f ./$(DEPDIR)/pcem-mouse_serial.Po - -rm -f ./$(DEPDIR)/pcem-ne2000.Po - -rm -f ./$(DEPDIR)/pcem-neat.Po - -rm -f ./$(DEPDIR)/pcem-nethandler.Po - -rm -f ./$(DEPDIR)/pcem-nmi.Po - -rm -f ./$(DEPDIR)/pcem-nvr.Po - -rm -f ./$(DEPDIR)/pcem-nvr_tc8521.Po - -rm -f ./$(DEPDIR)/pcem-olivetti_m24.Po - -rm -f ./$(DEPDIR)/pcem-opti495.Po - -rm -f ./$(DEPDIR)/pcem-paths.Po - -rm -f ./$(DEPDIR)/pcem-pc.Po - -rm -f ./$(DEPDIR)/pcem-pc87306.Po - -rm -f ./$(DEPDIR)/pcem-pci.Po - -rm -f ./$(DEPDIR)/pcem-pic.Po - -rm -f ./$(DEPDIR)/pcem-piix.Po - -rm -f ./$(DEPDIR)/pcem-pit.Po - -rm -f ./$(DEPDIR)/pcem-ppi.Po - -rm -f ./$(DEPDIR)/pcem-ps1.Po - -rm -f ./$(DEPDIR)/pcem-ps2.Po - -rm -f ./$(DEPDIR)/pcem-ps2_mca.Po - -rm -f ./$(DEPDIR)/pcem-ps2_nvr.Po - -rm -f ./$(DEPDIR)/pcem-rom.Po - -rm -f ./$(DEPDIR)/pcem-rtc.Po - -rm -f ./$(DEPDIR)/pcem-rtc_tc8521.Po - -rm -f ./$(DEPDIR)/pcem-scat.Po - -rm -f ./$(DEPDIR)/pcem-scsi.Po - -rm -f ./$(DEPDIR)/pcem-scsi_53c400.Po - -rm -f ./$(DEPDIR)/pcem-scsi_aha1540.Po - -rm -f ./$(DEPDIR)/pcem-scsi_cd.Po - -rm -f ./$(DEPDIR)/pcem-scsi_hd.Po - -rm -f ./$(DEPDIR)/pcem-scsi_zip.Po - -rm -f ./$(DEPDIR)/pcem-serial.Po - -rm -f ./$(DEPDIR)/pcem-sio.Po - -rm -f ./$(DEPDIR)/pcem-sis496.Po - -rm -f ./$(DEPDIR)/pcem-sl82c460.Po - -rm -f ./$(DEPDIR)/pcem-sound.Po - -rm -f ./$(DEPDIR)/pcem-sound_ad1848.Po - -rm -f ./$(DEPDIR)/pcem-sound_adlib.Po - -rm -f ./$(DEPDIR)/pcem-sound_adlibgold.Po - -rm -f ./$(DEPDIR)/pcem-sound_audiopci.Po - -rm -f ./$(DEPDIR)/pcem-sound_cms.Po - -rm -f ./$(DEPDIR)/pcem-sound_dbopl.Po - -rm -f ./$(DEPDIR)/pcem-sound_emu8k.Po - -rm -f ./$(DEPDIR)/pcem-sound_gus.Po - -rm -f ./$(DEPDIR)/pcem-sound_mpu401_uart.Po - -rm -f ./$(DEPDIR)/pcem-sound_opl.Po - -rm -f ./$(DEPDIR)/pcem-sound_pas16.Po - -rm -f ./$(DEPDIR)/pcem-sound_ps1.Po - -rm -f ./$(DEPDIR)/pcem-sound_pssj.Po - -rm -f ./$(DEPDIR)/pcem-sound_resid.Po - -rm -f ./$(DEPDIR)/pcem-sound_sb.Po - -rm -f ./$(DEPDIR)/pcem-sound_sb_dsp.Po - -rm -f ./$(DEPDIR)/pcem-sound_sn76489.Po - -rm -f ./$(DEPDIR)/pcem-sound_speaker.Po - -rm -f ./$(DEPDIR)/pcem-sound_ssi2001.Po - -rm -f ./$(DEPDIR)/pcem-sound_wss.Po - -rm -f ./$(DEPDIR)/pcem-sound_ym7128.Po - -rm -f ./$(DEPDIR)/pcem-soundopenal.Po - -rm -f ./$(DEPDIR)/pcem-t1000.Po - -rm -f ./$(DEPDIR)/pcem-t3100e.Po - -rm -f ./$(DEPDIR)/pcem-tandy_eeprom.Po - -rm -f ./$(DEPDIR)/pcem-tandy_rom.Po - -rm -f ./$(DEPDIR)/pcem-timer.Po - -rm -f ./$(DEPDIR)/pcem-um8669f.Po - -rm -f ./$(DEPDIR)/pcem-um8881f.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati18800.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati28800.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati_eeprom.Po - -rm -f ./$(DEPDIR)/pcem-vid_ati_mach64.Po - -rm -f ./$(DEPDIR)/pcem-vid_cga.Po - -rm -f ./$(DEPDIR)/pcem-vid_cl5429.Po - -rm -f ./$(DEPDIR)/pcem-vid_colorplus.Po - -rm -f ./$(DEPDIR)/pcem-vid_compaq_cga.Po - -rm -f ./$(DEPDIR)/pcem-vid_ega.Po - -rm -f ./$(DEPDIR)/pcem-vid_et4000.Po - -rm -f ./$(DEPDIR)/pcem-vid_et4000w32.Po - -rm -f ./$(DEPDIR)/pcem-vid_genius.Po - -rm -f ./$(DEPDIR)/pcem-vid_hercules.Po - -rm -f ./$(DEPDIR)/pcem-vid_icd2061.Po - -rm -f ./$(DEPDIR)/pcem-vid_ics2595.Po - -rm -f ./$(DEPDIR)/pcem-vid_incolor.Po - -rm -f ./$(DEPDIR)/pcem-vid_mda.Po - -rm -f ./$(DEPDIR)/pcem-vid_olivetti_m24.Po - -rm -f ./$(DEPDIR)/pcem-vid_oti037.Po - -rm -f ./$(DEPDIR)/pcem-vid_oti067.Po - -rm -f ./$(DEPDIR)/pcem-vid_paradise.Po - -rm -f ./$(DEPDIR)/pcem-vid_pc1512.Po - -rm -f ./$(DEPDIR)/pcem-vid_pc1640.Po - -rm -f ./$(DEPDIR)/pcem-vid_pc200.Po - -rm -f ./$(DEPDIR)/pcem-vid_pcjr.Po - -rm -f ./$(DEPDIR)/pcem-vid_ps1_svga.Po - -rm -f ./$(DEPDIR)/pcem-vid_s3.Po - -rm -f ./$(DEPDIR)/pcem-vid_s3_virge.Po - -rm -f ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_stg_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_svga.Po - -rm -f ./$(DEPDIR)/pcem-vid_svga_render.Po - -rm -f ./$(DEPDIR)/pcem-vid_t1000.Po - -rm -f ./$(DEPDIR)/pcem-vid_t3100e.Po - -rm -f ./$(DEPDIR)/pcem-vid_tandy.Po - -rm -f ./$(DEPDIR)/pcem-vid_tandysl.Po - -rm -f ./$(DEPDIR)/pcem-vid_tgui9440.Po - -rm -f ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_tvga.Po - -rm -f ./$(DEPDIR)/pcem-vid_unk_ramdac.Po - -rm -f ./$(DEPDIR)/pcem-vid_vga.Po - -rm -f ./$(DEPDIR)/pcem-vid_voodoo.Po - -rm -f ./$(DEPDIR)/pcem-vid_wy700.Po - -rm -f ./$(DEPDIR)/pcem-video.Po - -rm -f ./$(DEPDIR)/pcem-wd76c10.Po - -rm -f ./$(DEPDIR)/pcem-wx-app.Po - -rm -f ./$(DEPDIR)/pcem-wx-common.Po - -rm -f ./$(DEPDIR)/pcem-wx-config.Po - -rm -f ./$(DEPDIR)/pcem-wx-config_sel.Po - -rm -f ./$(DEPDIR)/pcem-wx-createdisc.Po - -rm -f ./$(DEPDIR)/pcem-wx-deviceconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-dialogbox.Po - -rm -f ./$(DEPDIR)/pcem-wx-glslp-parser.Po - -rm -f ./$(DEPDIR)/pcem-wx-hostconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-joystickconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-main.Po - -rm -f ./$(DEPDIR)/pcem-wx-resources.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-midi.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-status.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video.Po - -rm -f ./$(DEPDIR)/pcem-wx-sdl2.Po - -rm -f ./$(DEPDIR)/pcem-wx-shader_man.Po - -rm -f ./$(DEPDIR)/pcem-wx-shaderconfig.Po - -rm -f ./$(DEPDIR)/pcem-wx-status.Po - -rm -f ./$(DEPDIR)/pcem-wx-thread.Po - -rm -f ./$(DEPDIR)/pcem-wx-utils.Po - -rm -f ./$(DEPDIR)/pcem-x86seg.Po - -rm -f ./$(DEPDIR)/pcem-x87.Po - -rm -f ./$(DEPDIR)/pcem-xi8088.Po - -rm -f ./$(DEPDIR)/pcem-xtide.Po - -rm -f dosbox/$(DEPDIR)/pcem-cdrom_image.Po - -rm -f dosbox/$(DEPDIR)/pcem-dbopl.Po - -rm -f dosbox/$(DEPDIR)/pcem-nukedopl.Po - -rm -f dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po - -rm -f resid-fp/$(DEPDIR)/pcem-convolve-sse.Po - -rm -f resid-fp/$(DEPDIR)/pcem-convolve.Po - -rm -f resid-fp/$(DEPDIR)/pcem-envelope.Po - -rm -f resid-fp/$(DEPDIR)/pcem-extfilt.Po - -rm -f resid-fp/$(DEPDIR)/pcem-filter.Po - -rm -f resid-fp/$(DEPDIR)/pcem-pot.Po - -rm -f resid-fp/$(DEPDIR)/pcem-sid.Po - -rm -f resid-fp/$(DEPDIR)/pcem-voice.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po - -rm -f resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po - -rm -f slirp/$(DEPDIR)/pcem-bootp.Po - -rm -f slirp/$(DEPDIR)/pcem-cksum.Po - -rm -f slirp/$(DEPDIR)/pcem-debug.Po - -rm -f slirp/$(DEPDIR)/pcem-if.Po - -rm -f slirp/$(DEPDIR)/pcem-ip_icmp.Po - -rm -f slirp/$(DEPDIR)/pcem-ip_input.Po - -rm -f slirp/$(DEPDIR)/pcem-ip_output.Po - -rm -f slirp/$(DEPDIR)/pcem-mbuf.Po - -rm -f slirp/$(DEPDIR)/pcem-misc.Po - -rm -f slirp/$(DEPDIR)/pcem-queue.Po - -rm -f slirp/$(DEPDIR)/pcem-sbuf.Po - -rm -f slirp/$(DEPDIR)/pcem-slirp.Po - -rm -f slirp/$(DEPDIR)/pcem-socket.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_input.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_output.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_subr.Po - -rm -f slirp/$(DEPDIR)/pcem-tcp_timer.Po - -rm -f slirp/$(DEPDIR)/pcem-tftp.Po - -rm -f slirp/$(DEPDIR)/pcem-udp.Po + -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -5847,7 +5938,7 @@ uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ @@ -5873,6 +5964,14 @@ wx.res: wx.rc wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp +#pcem_CFLAGS += -mtune=cortex-a53 +#pcem_CXXFLAGS += -mtune=cortex-a53 +#pcem_LDFLAGS = -flto -O3 -mtune=cortex-a15 + +# pcem_CFLAGS += -fprofile-use +# pcem_CXXFLAGS += -fprofile-use +# pcem_LDFLAGS = -fprofile-use + # 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: From c876f1376d4da2521f358676aae229be373d9b01 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 Apr 2019 08:17:40 +0100 Subject: [PATCH 0695/1050] Remove obsolete linux/osx Makefiles. Users of those platforms should use autoreconf; ./configure; make instead. --- src/Makefile.linux32-wx-sdl2 | 52 ------------------------------------ src/Makefile.linux64-wx-sdl2 | 52 ------------------------------------ src/Makefile.osx64-wx-sdl2 | 51 ----------------------------------- 3 files changed, 155 deletions(-) delete mode 100644 src/Makefile.linux32-wx-sdl2 delete mode 100644 src/Makefile.linux64-wx-sdl2 delete mode 100644 src/Makefile.osx64-wx-sdl2 diff --git a/src/Makefile.linux32-wx-sdl2 b/src/Makefile.linux32-wx-sdl2 deleted file mode 100644 index f57456a..0000000 --- a/src/Makefile.linux32-wx-sdl2 +++ /dev/null @@ -1,52 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++ -CC = gcc -WXRC = wxrc -CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ -cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ -dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ -serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ -sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ -timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ -vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ -wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ -wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -lGL - -PCem-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2" $(LIBS) - -all : PCem-wx-SDL2 - -clean : - rm *.o - rm PCem-wx-SDL2 - -wx-resources.o : pc.xrc - $(WXRC) -c pc.xrc -o wx-resources.cpp - $(CPP) $(CFLAGS) -c wx-resources.cpp - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CXXFLAGS) -c $< - -%.o : %.cpp - $(CPP) $(CXXFLAGS) -c $< diff --git a/src/Makefile.linux64-wx-sdl2 b/src/Makefile.linux64-wx-sdl2 deleted file mode 100644 index 6489ce6..0000000 --- a/src/Makefile.linux64-wx-sdl2 +++ /dev/null @@ -1,52 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++ -CC = gcc -WXRC = wxrc -CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o cbm_io.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ -cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ -dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ -serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ -sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ -timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ -vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ -wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ -wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -lGL - -PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) - -all : PCem64-wx-SDL2 - -clean : - rm *.o - rm PCem64-wx-SDL2 - -wx-resources.o : pc.xrc - $(WXRC) -c pc.xrc -o wx-resources.cpp - $(CPP) $(CFLAGS) -c wx-resources.cpp - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CXXFLAGS) -c $< - -%.o : %.cpp - $(CPP) $(CXXFLAGS) -c $< diff --git a/src/Makefile.osx64-wx-sdl2 b/src/Makefile.osx64-wx-sdl2 deleted file mode 100644 index 536cfb3..0000000 --- a/src/Makefile.osx64-wx-sdl2 +++ /dev/null @@ -1,51 +0,0 @@ -VPATH = . dosbox resid-fp -CPP = g++ -CC = gcc -WXRC = wxrc -CFLAGS = -D__unix=1 -DPCEM_RENDER_WITH_TIMER -DPCEM_RENDER_TIMER_LOOP -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello -Doff64_t=off_t -O3 -fomit-frame-pointer -msse2 -m64 $(shell wx-config --cxxflags) $(shell sdl2-config --cflags) -I/usr/local/opt/openal-soft/include -I/usr/local/include -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o cbm_io.o cdrom-ioctl-osx.o cdrom-image.o cdrom-null.o \ -cmd640.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_common.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ -device.o dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ -hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o ide_atapi.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 \ -laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o \ -opti495.o paths.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o \ -serial.o sio.o sis496.o sl82c460.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_emu8k.o sound_gus.o \ -sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.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 t1000.o t3100e.o tandy_eeprom.o tandy_rom.o \ -timer.o um8669f.o um8881f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o \ -vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_genius.o vid_hercules.o \ -vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc200.o \ -vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o \ -vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o wd76c10.o \ -x86seg.o x87.o xi8088.c xtide.o zenith.o sound_dbopl.o sound_resid.o \ -wx-main.o wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2-midi.o \ -wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display.o \ -wx-sdl2-video-renderer.o wx-sdl2-video-gl3.o wx-glslp-parser.o wx-shader_man.o wx-shaderconfig.o wx-joystickconfig.o wx-createdisc.o -DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 - -LIBS = -lopenal -lstdc++ -lpthread -lm $(shell wx-config --libs) $(shell sdl2-config --libs) -L/usr/local/opt/openal-soft/lib -framework OpenGL - -PCem64-wx-SDL2: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64-wx-SDL2" $(LIBS) - -all : PCem64-wx-SDL2 - -clean : - rm *.o - rm PCem64-wx-SDL2 - -wx-resources.o : pc.xrc - $(WXRC) -c pc.xrc -o wx-resources.cpp - $(CPP) $(CFLAGS) -c wx-resources.cpp - -%.o : %.c - $(CC) $(CFLAGS) -c $< - -%.o : %.cc - $(CPP) $(CFLAGS) -c $< - -%.o : %.cpp - $(CPP) $(CFLAGS) -c $< From 58e42fda81e42df6f5361bb2a2d6205e13e208e6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 09:02:55 +0100 Subject: [PATCH 0696/1050] Don't enable RTC clock on speed change if RTC timer not enabled. Fixes crash when changing configuration with XT models. --- src/nvr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nvr.c b/src/nvr.c index 3c68768..e9af3b6 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -65,6 +65,11 @@ void nvr_recalc() { int c; + if (!(nvrram[RTC_REGA] & RTC_RS)) + { + timer_disable(&rtc_timer); + return; + } c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); } From 3508059f169e64cbf767f48800e8389c083fb5c6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 14:59:34 +0100 Subject: [PATCH 0697/1050] Make RTC/NVR a normal device instead of a special thing. Fixes nvr_recalc() being called on systems without NVR, which could cause timer crashes. --- src/model.c | 14 +++--- src/nvr.c | 120 ++++++++++++++++++++++++++++++++++------------------ src/nvr.h | 6 +-- src/pc.c | 2 - 4 files changed, 90 insertions(+), 52 deletions(-) diff --git a/src/model.c b/src/model.c index 8c364dc..00b3e4e 100644 --- a/src/model.c +++ b/src/model.c @@ -372,7 +372,7 @@ void ams_init() lpt1_remove(); amstrad_init(); keyboard_amstrad_init(); - nvr_init(); + device_add(&nvr_device); nmi_init(); fdc_set_dskchg_activelow(); device_add(&gameport_device); @@ -393,7 +393,7 @@ void olim24_init() common_init(); mem_add_bios(); keyboard_olim24_init(); - nvr_init(); + device_add(&nvr_device); olivetti_m24_init(); nmi_init(); device_add(&gameport_device); @@ -429,7 +429,7 @@ void xt_xi8088_init() keyboard_at_init(); keyboard_at_init_ps2(); nmi_init(); - nvr_init(); + device_add(&nvr_device); pic2_init(); device_add(&gameport_device); } @@ -442,7 +442,7 @@ void at_init() pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); keyboard_at_init(); - nvr_init(); + device_add(&nvr_device); pic2_init(); device_add(&gameport_device); nmi_mask = 0; @@ -480,7 +480,7 @@ void ps1_common_init() pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); keyboard_at_init(); - nvr_init(); + device_add(&nvr_device); pic2_init(); fdc_set_dskchg_activelow(); device_add(&ps1_audio_device); @@ -511,7 +511,7 @@ void ps2_m30_286_init() dma16_init(); keyboard_at_init(); // mouse_ps2_init(); - nvr_init(); + device_add(&nvr_device); pic2_init(); ps2board_init(); fdc_set_dskchg_activelow(); @@ -527,7 +527,7 @@ static void ps2_common_init() keyboard_at_init(); keyboard_at_init_ps2(); // mouse_ps2_init(); - nvr_init(); + device_add(&nvr_device); pic2_init(); pit_ps2_init(); diff --git a/src/nvr.c b/src/nvr.c index e9af3b6..f080247 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -1,5 +1,7 @@ #include +#include #include "ibm.h" +#include "device.h" #include "io.h" #include "nvr.h" #include "nvr_tc8521.h" @@ -20,10 +22,14 @@ int nvraddr; int nvr_dosave = 0; -static pc_timer_t nvr_onesec_timer; -static int nvr_onesec_cnt = 0; +typedef struct nvr_t +{ + pc_timer_t rtc_timer; + pc_timer_t onesec_timer; + pc_timer_t update_end_timer; -static pc_timer_t rtc_timer; + int onesec_cnt; +} nvr_t; FILE *nvrfopen(char *fn, char *mode) { @@ -61,37 +67,44 @@ void getnvrtime() time_get(nvrram); } -void nvr_recalc() +static void nvr_speed_changed(void *p) { - int c; + nvr_t *nvr = (nvr_t *)p; if (!(nvrram[RTC_REGA] & RTC_RS)) { - timer_disable(&rtc_timer); + timer_disable(&nvr->rtc_timer); return; } - c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); + else + { + int c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); + timer_set_delay_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); + } } -void nvr_rtc(void *p) +static void nvr_rtc(void *p) { - int c; + nvr_t *nvr = (nvr_t *)p; + if (!(nvrram[RTC_REGA] & RTC_RS)) { - timer_disable(&rtc_timer); + timer_disable(&nvr->rtc_timer); return; } - c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - timer_advance_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); -// pclog("RTCtime now %f\n",rtctime); - nvrram[RTC_REGC] |= RTC_PF; - if (nvrram[RTC_REGB] & RTC_PIE) + else { - nvrram[RTC_REGC] |= RTC_IRQF; - if (AMSTRAD) picint(2); - else picint(0x100); -// pclog("RTC int\n"); + int c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); + timer_advance_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); +// 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"); + } } } @@ -104,10 +117,11 @@ int nvr_check_alarm(int nvraddr) return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE); } -pc_timer_t nvr_update_end_timer; -void nvr_update_end(void *p) +static void nvr_update_end(void *p) { +// nvr_t *nvr = (nvr_t *)p; + if (!(nvrram[RTC_REGB] & RTC_SET)) { getnvrtime(); @@ -138,25 +152,28 @@ void nvr_update_end(void *p) // pclog("RTC onesec\n"); } -void nvr_onesec(void *p) +static void nvr_onesec(void *p) { - nvr_onesec_cnt++; - if (nvr_onesec_cnt >= 100) + nvr_t *nvr = (nvr_t *)p; + + nvr->onesec_cnt++; + if (nvr->onesec_cnt >= 100) { if (!(nvrram[RTC_REGB] & RTC_SET)) { nvr_update_status = RTC_UIP; rtc_tick(); - timer_set_delay_u64(&nvr_update_end_timer, (uint64_t)((244.0 + 1984.0) * TIMER_USEC)); + timer_set_delay_u64(&nvr->update_end_timer, (uint64_t)((244.0 + 1984.0) * TIMER_USEC)); } - nvr_onesec_cnt = 0; + nvr->onesec_cnt = 0; } - timer_advance_u64(&nvr_onesec_timer, (uint64_t)(10000 * TIMER_USEC)); + timer_advance_u64(&nvr->onesec_timer, (uint64_t)(10000 * TIMER_USEC)); } -void writenvr(uint16_t addr, uint8_t val, void *priv) +static void writenvr(uint16_t addr, uint8_t val, void *p) { + nvr_t *nvr = (nvr_t *)p; int c, old; cycles -= ISA_CYCLES(8); @@ -178,10 +195,10 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) if (val & RTC_RS) { c = 1 << ((val & RTC_RS) - 1); - timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); + timer_set_delay_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); } else - timer_disable(&rtc_timer); + timer_disable(&nvr->rtc_timer); } else { @@ -227,8 +244,9 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) } } -uint8_t readnvr(uint16_t addr, void *priv) +uint8_t readnvr(uint16_t addr, void *p) { +// nvr_t *nvr = (nvr_t *)p; uint8_t temp; // printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc); cycles -= ISA_CYCLES(8); @@ -256,7 +274,7 @@ uint8_t readnvr(uint16_t addr, void *priv) void loadnvr() { FILE *f; - int c; + nvrmask=63; oldromset=romset; switch (romset) @@ -353,8 +371,6 @@ void loadnvr() fclose(f); nvrram[RTC_REGA] = 6; nvrram[RTC_REGB] = RTC_2412; - c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - timer_set_delay_u64(&rtc_timer, (uint64_t)(RTCCONST * c)); } void savenvr() { @@ -436,11 +452,35 @@ void savenvr() fclose(f); } -void nvr_init() +static void *nvr_init() { - io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL); - timer_add(&rtc_timer, nvr_rtc, NULL, 1); - timer_add(&nvr_onesec_timer, nvr_onesec, NULL, 1); - timer_add(&nvr_update_end_timer, nvr_update_end, NULL, 0); + nvr_t *nvr = (nvr_t *)malloc(sizeof(nvr_t)); + memset(nvr, 0, sizeof(nvr_t)); + io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, nvr); + timer_add(&nvr->rtc_timer, nvr_rtc, nvr, 1); + timer_add(&nvr->onesec_timer, nvr_onesec, nvr, 1); + timer_add(&nvr->update_end_timer, nvr_update_end, nvr, 0); + + return nvr; } + +static void nvr_close(void *p) +{ + nvr_t *nvr = (nvr_t *)p; + + free(nvr); +} + +device_t nvr_device = +{ + "Motorola MC146818 RTC", + 0, + nvr_init, + nvr_close, + NULL, + nvr_speed_changed, + NULL, + NULL, + NULL +}; diff --git a/src/nvr.h b/src/nvr.h index f92942b..b01d7df 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -1,4 +1,6 @@ -void nvr_init(); +#include "device.h" + +extern device_t nvr_device; extern int enable_sync; @@ -7,8 +9,6 @@ extern int nvr_dosave; void loadnvr(); void savenvr(); -void nvr_recalc(); - FILE *nvrfopen(char *fn, char *mode); extern uint8_t nvrram[128]; diff --git a/src/pc.c b/src/pc.c index c6f0469..1951134 100644 --- a/src/pc.c +++ b/src/pc.c @@ -601,7 +601,6 @@ void fullspeed() // else setpitclock(clocks[AT?1:0][cpuspeed2][0]); } atfullspeed=1; - nvr_recalc(); } void speedchanged() @@ -610,7 +609,6 @@ void speedchanged() setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); else setpitclock(14318184.0); - nvr_recalc(); } void closepc() From 650b8cb5dafd18ec90c8c98c9a523336d6f654eb Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 15:16:33 +0100 Subject: [PATCH 0698/1050] Fix waitstate on accessing timer on timer registers on Premiere/PCI and Packard Bell PB520R. --- src/intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intel.c b/src/intel.c index 85ebcbf..5fcbdbb 100644 --- a/src/intel.c +++ b/src/intel.c @@ -64,7 +64,7 @@ static uint8_t batman_timer_read(uint16_t addr, void *p) { uint16_t batman_timer_latch; - cycles -= (int)PITCONST; + cycles -= (int)(PITCONST >> 32); batman_timer_latch = timer_get_remaining_us(&batman_timer); From 9aca6a8cb8208f210da6d4b74fe7f2935b6bf628 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 17:06:38 +0100 Subject: [PATCH 0699/1050] Don't double-add the T1000/T1200 video device. Fixes T1000/T1200 video. --- src/model.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/model.c b/src/model.c index 00b3e4e..9dcf5e2 100644 --- a/src/model.c +++ b/src/model.c @@ -142,7 +142,7 @@ MODEL models[] = {"[8088] Tandy 1000", ROM_TANDY, "tandy", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 128, tandy1k_init, &tandy1000_device}, {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}, - {"[8088] Toshiba T1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, &t1000_device}, + {"[8088] Toshiba T1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, NULL}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}, {"[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, xt_zenith_init, NULL}, {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}, @@ -155,7 +155,7 @@ MODEL models[] = {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}, - {"[8088] Toshiba T1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, &t1000_device}, + {"[8088] Toshiba T1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, NULL}, {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 1152, 128, xt_laserxt_init, NULL}, {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, From 5d9b14ac4ab5fffab5ba16636f764a2070a334fa Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 17:28:01 +0100 Subject: [PATCH 0700/1050] Fix pixel clocks on ATI-28800, ET4000 and Trident graphics cards. --- src/vid_ati28800.c | 28 ++++++++++++++-------------- src/vid_et4000.c | 6 +++--- src/vid_et4000w32.c | 2 +- src/vid_tgui9440.c | 30 +++++++++++++++--------------- src/vid_tvga.c | 12 ++++++------ 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 50fe3c7..005d1f0 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -272,20 +272,20 @@ void ati28800_recalctimings(svga_t *svga) switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { - case 0x00: svga->clock = cpuclock / 42954000.0; break; - case 0x01: svga->clock = cpuclock / 48771000.0; break; - case 0x03: svga->clock = cpuclock / 36000000.0; break; - case 0x04: svga->clock = cpuclock / 50350000.0; break; - case 0x05: svga->clock = cpuclock / 56640000.0; break; - case 0x07: svga->clock = cpuclock / 44900000.0; break; - case 0x08: svga->clock = cpuclock / 30240000.0; break; - case 0x09: svga->clock = cpuclock / 32000000.0; break; - case 0x0A: svga->clock = cpuclock / 37500000.0; break; - case 0x0B: svga->clock = cpuclock / 39000000.0; break; - case 0x0C: svga->clock = cpuclock / 40000000.0; break; - case 0x0D: svga->clock = cpuclock / 56644000.0; break; - case 0x0E: svga->clock = cpuclock / 75000000.0; break; - case 0x0F: svga->clock = cpuclock / 65000000.0; break; + case 0x00: svga->clock = (cpuclock * (double)(1ull << 32)) / 42954000.0; break; + case 0x01: svga->clock = (cpuclock * (double)(1ull << 32)) / 48771000.0; break; + case 0x03: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; + case 0x04: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; + case 0x05: svga->clock = (cpuclock * (double)(1ull << 32)) / 56640000.0; break; + case 0x07: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; + case 0x08: svga->clock = (cpuclock * (double)(1ull << 32)) / 30240000.0; break; + case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; break; + case 0x0A: svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; break; + case 0x0B: svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; break; + case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x0D: svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; break; + case 0x0E: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; + case 0x0F: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; default: break; } if (ati28800->regs[0xb8] & 0x40) diff --git a/src/vid_et4000.c b/src/vid_et4000.c index 174fbdd..c56db96 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -240,9 +240,9 @@ void et4000_recalctimings(svga_t *svga) switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: case 1: break; - case 3: svga->clock = cpuclock / 40000000.0; break; - case 5: svga->clock = cpuclock / 65000000.0; break; - default: svga->clock = cpuclock / 36000000.0; break; + case 3: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; + default: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; } switch (svga->bpp) diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 1775977..e8a8e8f 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -293,7 +293,7 @@ void et4000w32p_recalctimings(svga_t *svga) switch ((svga->miscout >> 2) & 3) { case 0: case 1: break; - case 2: case 3: svga->clock = cpuclock / icd2061_getfreq(&et4000->icd2061, 2); break; + case 2: case 3: svga->clock = (cpuclock * (double)(1ull << 32)) / icd2061_getfreq(&et4000->icd2061, 2); break; } switch (svga->bpp) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 22b14de..a2e13bd 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -482,7 +482,7 @@ void tgui_recalctimings(svga_t *svga) if (tgui->type >= TGUI_9440) { if (svga->miscout & 8) - svga->clock = cpuclock / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); + svga->clock = (cpuclock * (double)(1ull << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); if (svga->gdcreg[0xf] & 0x08) svga->clock *= 2; @@ -493,20 +493,20 @@ void tgui_recalctimings(svga_t *svga) { switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { - case 0x02: svga->clock = cpuclock/ 44900000.0; break; - case 0x03: svga->clock = cpuclock/ 36000000.0; break; - case 0x04: svga->clock = cpuclock/ 57272000.0; break; - case 0x05: svga->clock = cpuclock/ 65000000.0; break; - case 0x06: svga->clock = cpuclock/ 50350000.0; break; - case 0x07: svga->clock = cpuclock/ 40000000.0; break; - case 0x08: svga->clock = cpuclock/ 88000000.0; break; - case 0x09: svga->clock = cpuclock/ 98000000.0; break; - case 0x0a: svga->clock = cpuclock/118800000.0; break; - case 0x0b: svga->clock = cpuclock/108000000.0; break; - case 0x0c: svga->clock = cpuclock/ 72000000.0; break; - case 0x0d: svga->clock = cpuclock/ 77000000.0; break; - case 0x0e: svga->clock = cpuclock/ 80000000.0; break; - case 0x0f: svga->clock = cpuclock/ 75000000.0; break; + case 0x02: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; + case 0x03: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; + case 0x04: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; + case 0x05: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; + case 0x06: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; + case 0x07: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x08: svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; break; + case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; break; + case 0x0a: svga->clock = (cpuclock * (double)(1ull << 32)) /118800000.0; break; + case 0x0b: svga->clock = (cpuclock * (double)(1ull << 32)) /108000000.0; break; + case 0x0c: svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; break; + case 0x0d: svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; break; + case 0x0e: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; + case 0x0f: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; } if (svga->gdcreg[0xf] & 0x08) { diff --git a/src/vid_tvga.c b/src/vid_tvga.c index 9d24c8b..623534b 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -248,12 +248,12 @@ void tvga_recalctimings(svga_t *svga) switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) { - case 2: svga->clock = cpuclock/44900000.0; break; - case 3: svga->clock = cpuclock/36000000.0; break; - case 4: svga->clock = cpuclock/57272000.0; break; - case 5: svga->clock = cpuclock/65000000.0; break; - case 6: svga->clock = cpuclock/50350000.0; break; - case 7: svga->clock = cpuclock/40000000.0; break; + case 2: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; + case 3: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; + case 4: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; + case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; + case 6: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; + case 7: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; } if (tvga->oldctrl2 & 0x10) From f7e8aa652e4cbd3a3e7ef4a83f86eeec74fdcb99 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 17:32:14 +0100 Subject: [PATCH 0701/1050] Fix pixel clock on HT216-32. --- src/vid_ht216.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vid_ht216.c b/src/vid_ht216.c index ef86782..ab2e021 100644 --- a/src/vid_ht216.c +++ b/src/vid_ht216.c @@ -347,9 +347,9 @@ void ht216_recalctimings(svga_t *svga) // pclog("clk_sel = %i\n", ht216->clk_sel); switch (ht216->clk_sel) { - case 5: svga->clock = cpuclock / 65000000.0; break; - case 6: svga->clock = cpuclock / 40000000.0; break; - case 10: svga->clock = cpuclock / 80000000.0; break; + case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; + case 6: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 10: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; } svga->lowres = !(ht216->ht_regs[0xc8] & HT_REG_C8_E256); svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); From b9e7f1b9d6060b967ca38df7d4f89d4bca641a91 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 17:48:22 +0100 Subject: [PATCH 0702/1050] Correct fixed horizontal timing on PC1512 video. Fixes refresh rate. --- src/vid_pc1512.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 2b8a229..a5e4983 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -148,7 +148,7 @@ static uint8_t pc1512_read(uint32_t addr, void *p) static void pc1512_recalctimings(pc1512_t *pc1512) { double _dispontime, _dispofftime, disptime; - disptime = 128; /*Fixed on PC1512*/ + disptime = 114; /*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]); From 6560782b73712e173105eb361371a7e81b81816a Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Apr 2019 17:55:33 +0100 Subject: [PATCH 0703/1050] Fix missing text cursor on PC1512. --- src/vid_pc1512.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index a5e4983..afe3c5d 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -222,7 +222,7 @@ static void pc1512_poll(void *p) if (drawcursor) { for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; } else { From 8cb5c5eff2d625be6fd2b4b78a2c167d29c79cb3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 27 Apr 2019 12:47:45 +0100 Subject: [PATCH 0704/1050] Fixed register typo in 0x81 NO_IMMEDIATES ADC/SBB. Fixes SB audio in Worms. --- src/codegen_ops_arith.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c index 08bb5f1..2127c57 100644 --- a/src/codegen_ops_arith.c +++ b/src/codegen_ops_arith.c @@ -1953,12 +1953,12 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet break; case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); + get_cf(ir, IREG_temp3); if (block->flags & CODEBLOCK_NO_IMMEDIATES) uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); else uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); if (block->flags & CODEBLOCK_NO_IMMEDIATES) @@ -1970,12 +1970,12 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet break; case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); + get_cf(ir, IREG_temp3); if (block->flags & CODEBLOCK_NO_IMMEDIATES) uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); else uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); if (block->flags & CODEBLOCK_NO_IMMEDIATES) From 16bc3bb6ec83720bdb51a4b70bdba3af39302661 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 27 Apr 2019 18:31:22 +0100 Subject: [PATCH 0705/1050] Don't call addreadlookup() from get_phys() unless the address being translated is in RAM. Fixes Windows 95 install on Packard Bell PB410. --- src/mem.c | 7 +++++++ src/mem.h | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/mem.c b/src/mem.c index dd3186d..7f1d7bd 100644 --- a/src/mem.c +++ b/src/mem.c @@ -54,6 +54,13 @@ uint32_t mem_logical_addr; int mmuflush=0; int mmu_perm=4; +int mem_addr_is_ram(uint32_t addr) +{ + mem_mapping_t *mapping = read_mapping[addr >> 14]; + + return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_remapped_mapping); +} + void resetreadlookup() { int c; diff --git a/src/mem.h b/src/mem.h index 429973a..5c7935b 100644 --- a/src/mem.h +++ b/src/mem.h @@ -153,6 +153,8 @@ static inline int page_in_evict_list(page_t *p) void page_remove_from_evict_list(page_t *p); void page_add_to_evict_list(page_t *p); +int mem_addr_is_ram(uint32_t addr); + 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) @@ -173,7 +175,7 @@ static inline uint32_t get_phys(uint32_t addr) else { get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; - if (!cpu_state.abrt) + if (!cpu_state.abrt && mem_addr_is_ram(get_phys_phys)) addreadlookup(get_phys_virt, get_phys_phys); } @@ -192,7 +194,7 @@ static inline uint32_t get_phys_noabrt(uint32_t addr) return ((uintptr_t)readlookup2[addr >> 12] + addr) - (uintptr_t)ram; phys_addr = mmutranslate_noabrt(addr, 0) & rammask; - if (phys_addr != 0xffffffff) + if (phys_addr != 0xffffffff && mem_addr_is_ram(phys_addr)) addreadlookup(addr, phys_addr); return phys_addr; From 16a86adbf8dc2eeff474b073fd6d478a3047928e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 28 Apr 2019 10:04:30 +0100 Subject: [PATCH 0706/1050] Force implicit dependency on previous register version when accessing a partial register. Fixes graphics issues in Windows 95 on Packard Bell PB410A using built-in HT216 video. --- src/codegen_reg.c | 2 +- src/codegen_reg.h | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index eb07cfb..2601b5a 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -191,7 +191,7 @@ void codegen_reg_mark_as_required() } } -static int reg_is_native_size(ir_reg_t ir_reg) +int reg_is_native_size(ir_reg_t ir_reg) { int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; int requested_size = IREG_GET_SIZE(ir_reg.reg); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index bd790a9..6bdb7c2 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -343,6 +343,8 @@ static inline ir_reg_t codegen_reg_read(int reg) return ireg; } +int reg_is_native_size(ir_reg_t ir_reg); + static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) { ir_reg_t ireg; @@ -357,7 +359,10 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) - add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); + { + if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/ + add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); + } reg_last_version[IREG_GET_REG(reg)]++; if (!reg_last_version[IREG_GET_REG(reg)]) From 4476fee2ec7054a15898bac6acb4b70b0a8e5cb7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 28 Apr 2019 18:34:33 +0100 Subject: [PATCH 0707/1050] Loading SS in real mode does not change stack size. Fixes Solaris 8 bootup. --- src/x86seg.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 21a3778..8335897 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -455,8 +455,6 @@ int loadseg(uint16_t seg, x86seg *s) s->access = (3 << 5) | 2; s->base = seg << 4; s->seg = seg; - if (s == &cpu_state.seg_ss) - set_stack32(0); s->checked = 1; if (s == &cpu_state.seg_ds) codegen_flat_ds = 0; From 57be2ef8d4bae8cb4269cb022f1522443518e9c8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 28 Apr 2019 18:35:11 +0100 Subject: [PATCH 0708/1050] Add ability to change AT keyboard scancode and disable translation. Fixes keyboard in Solaris 8. --- src/keyboard.c | 172 +++++++++++++++++++++++++++++++++++++++++++++- src/keyboard.h | 9 +++ src/keyboard_at.c | 85 +++++++++++++++++++++++ 3 files changed, 265 insertions(+), 1 deletion(-) diff --git a/src/keyboard.c b/src/keyboard.c index 27213d0..820d5ff 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -84,6 +84,156 @@ static scancode scancode_set1[272] = { {0xe0, 0xee, 0}, {0} }, { {0xe0, 0xf1, 0}, {0} }, { {0xe0, 0xfe, 0}, {0} }, { {0xe0, 0xff, 0}, {0} } /*10c*/ }; +/*272 = 256 + 16 fake interim scancodes for disambiguation purposes.*/ +static scancode scancode_set2[272] = +{ + { {0}, {0} }, { {0x76, 0}, {0xf0, 0x76, 0} }, { {0x16, 0}, {0xf0, 0x16, 0} }, { {0x1e, 0}, {0xf0, 0x1e, 0} }, + { {0x26, 0}, {0xf0, 0x26, 0} }, { {0x25, 0}, {0xf0, 0x25, 0} }, { {0x2e, 0}, {0xf0, 0x2e, 0} }, { {0x36, 0}, {0xf0, 0x36, 0} }, + { {0x3d, 0}, {0xf0, 0x3d, 0} }, { {0x3e, 0}, {0xf0, 0x3e, 0} }, { {0x46, 0}, {0xf0, 0x46, 0} }, { {0x45, 0}, {0xf0, 0x45, 0} }, + { {0x4e, 0}, {0xf0, 0x4e, 0} }, { {0x55, 0}, {0xf0, 0x55, 0} }, { {0x66, 0}, {0xf0, 0x66, 0} }, { {0x0d, 0}, {0xf0, 0x0d, 0} }, + { {0x15, 0}, {0xf0, 0x15, 0} }, { {0x1d, 0}, {0xf0, 0x1d, 0} }, { {0x24, 0}, {0xf0, 0x24, 0} }, { {0x2d, 0}, {0xf0, 0x2d, 0} }, + { {0x2c, 0}, {0xf0, 0x2c, 0} }, { {0x35, 0}, {0xf0, 0x35, 0} }, { {0x3c, 0}, {0xf0, 0x3c, 0} }, { {0x43, 0}, {0xf0, 0x43, 0} }, + { {0x44, 0}, {0xf0, 0x44, 0} }, { {0x4d, 0}, {0xf0, 0x4d, 0} }, { {0x54, 0}, {0xf0, 0x54, 0} }, { {0x5b, 0}, {0xf0, 0x5b, 0} }, + { {0x5a, 0}, {0xf0, 0x5a, 0} }, { {0x14, 0}, {0xf0, 0x14, 0} }, { {0x1c, 0}, {0xf0, 0x1c, 0} }, { {0x1b, 0}, {0xf0, 0x1b, 0} }, + { {0x23, 0}, {0xf0, 0x23, 0} }, { {0x2b, 0}, {0xf0, 0x2b, 0} }, { {0x34, 0}, {0xf0, 0x34, 0} }, { {0x33, 0}, {0xf0, 0x33, 0} }, + { {0x3b, 0}, {0xf0, 0x3b, 0} }, { {0x42, 0}, {0xf0, 0x42, 0} }, { {0x4b, 0}, {0xf0, 0x4b, 0} }, { {0x4c, 0}, {0xf0, 0x4c, 0} }, + { {0x52, 0}, {0xf0, 0x52, 0} }, { {0x0e, 0}, {0xf0, 0x0e, 0} }, { {0x12, 0}, {0xf0, 0x12, 0} }, { {0x5d, 0}, {0xf0, 0x5d, 0} }, + { {0x1a, 0}, {0xf0, 0x1a, 0} }, { {0x22, 0}, {0xf0, 0x22, 0} }, { {0x21, 0}, {0xf0, 0x21, 0} }, { {0x2a, 0}, {0xf0, 0x2a, 0} }, + { {0x32, 0}, {0xf0, 0x32, 0} }, { {0x31, 0}, {0xf0, 0x31, 0} }, { {0x3a, 0}, {0xf0, 0x3a, 0} }, { {0x41, 0}, {0xf0, 0x41, 0} }, + { {0x49, 0}, {0xf0, 0x49, 0} }, { {0x4a, 0}, {0xf0, 0x4a, 0} }, { {0x59, 0}, {0xf0, 0x59, 0} }, { {0x7c, 0}, {0xf0, 0x7c, 0} }, + { {0x11, 0}, {0xf0, 0x11, 0} }, { {0x29, 0}, {0xf0, 0x29, 0} }, { {0x58, 0}, {0xf0, 0x58, 0} }, { {0x05, 0}, {0xf0, 0x05, 0} }, + { {0x06, 0}, {0xf0, 0x06, 0} }, { {0x04, 0}, {0xf0, 0x04, 0} }, { {0x0c, 0}, {0xf0, 0x0c, 0} }, { {0x03, 0}, {0xf0, 0x03, 0} }, + { {0x0b, 0}, {0xf0, 0x0b, 0} }, { {0x83, 0}, {0xf0, 0x83, 0} }, { {0x0a, 0}, {0xf0, 0x0a, 0} }, { {0x01, 0}, {0xf0, 0x01, 0} }, + { {0x09, 0}, {0xf0, 0x09, 0} }, { {0x77, 0}, {0xf0, 0x77, 0} }, { {0x7e, 0}, {0xf0, 0x7e, 0} }, { {0x6c, 0}, {0xf0, 0x6c, 0} }, + { {0x75, 0}, {0xf0, 0x75, 0} }, { {0x7d, 0}, {0xf0, 0x7d, 0} }, { {0x7b, 0}, {0xf0, 0x7b, 0} }, { {0x6b, 0}, {0xf0, 0x6b, 0} }, + { {0x73, 0}, {0xf0, 0x73, 0} }, { {0x74, 0}, {0xf0, 0x74, 0} }, { {0x79, 0}, {0xf0, 0x79, 0} }, { {0x69, 0}, {0xf0, 0x69, 0} }, + { {0x72, 0}, {0xf0, 0x72, 0} }, { {0x7a, 0}, {0xf0, 0x7a, 0} }, { {0x70, 0}, {0xf0, 0x70, 0} }, { {0x71, 0}, {0xf0, 0x71, 0} }, + { {0x84, 0}, {0xf0, 0x84, 0} }, { {0, 0}, {0, 0} }, { {0x61, 0}, {0xf0, 0x61, 0} }, { {0x78, 0}, {0xf0, 0x78, 0} }, + { {0x07, 0}, {0xf0, 0x07, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0xe0, 0x5a, 0}, {0xe0, 0xf0, 0x5a, 0} }, { {0xe0, 0x14, 0}, {0xe0, 0xf0, 0x14, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0xe0, 0x4a, 0}, {0xe0, 0xf0, 0x4a, 0} }, { {0, 0}, {0, 0} }, { {0xe0, 0x7c, 0}, {0xe0, 0xf0, 0x7c, 0} }, + { {0xe0, 0x11, 0}, {0xe0, 0xf0, 0x11, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0xe0, 0x6c, 0}, {0xe0, 0xf0, 0x6c, 0} }, + { {0xe0, 0x75, 0}, {0xe0, 0xf0, 0x75, 0} }, { {0xe0, 0x7d, 0}, {0xe0, 0xf0, 0x7d, 0} }, { {0, 0}, {0, 0} }, { {0xe0, 0x6b, 0}, {0xe0, 0xf0, 0x6b, 0} }, + { {0, 0}, {0, 0} }, { {0xe0, 0x74, 0}, {0xe0, 0xf0, 0x74, 0} }, { {0, 0}, {0, 0} }, { {0xe0, 0x69, 0}, {0xe0, 0xf0, 0x69, 0} }, + { {0xe0, 0x72, 0}, {0xe0, 0xf0, 0x72, 0} }, { {0xe0, 0x7a, 0}, {0xe0, 0xf0, 0x7a, 0} }, { {0xe0, 0x70, 0}, {0xe0, 0xf0, 0x70, 0} }, { {0xe0, 0x71, 0}, {0xe0, 0xf0, 0x71, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0xe0, 0x1f, 0}, {0xe0, 0xf0, 0x1f, 0} }, + { {0xe0, 0x27, 0}, {0xe0, 0xf0, 0x27, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + + { {0}, {0} }, { {0xe0, 0x01, 0}, {0xe0, 0xf0, 0x01, 0} }, { {0xe0, 0x02, 0}, {0xe0, 0xf0, 0x02, 0} }, { {0}, {0} }, /*100*/ + { {0}, {0} }, { {0xe0, 0x05, 0}, {0xe0, 0xf0, 0x15, 0} }, { {0xe0, 0x06, 0}, {0xe0, 0xf0, 0x06, 0} }, { {0xe0, 0x07, 0}, {0xe0, 0xf0, 0x07, 0} }, /*104*/ + { {0xe0, 0x71, 0}, {0xe0, 0xf0, 0x71, 0} }, { {0xe0, 0x72, 0}, {0xe0, 0xf0, 0x72, 0} }, { {0xe0, 0x7f, 0}, {0xe0, 0xf0, 0x7f, 0} }, { {0xe0, 0xe1, 0}, {0} }, /*108*/ + { {0xe0, 0xee, 0}, {0} }, { {0xe0, 0xf1, 0}, {0} }, { {0xe0, 0xfe, 0}, {0} }, { {0xe0, 0xff, 0}, {0} } /*10c*/ +}; + +/*272 = 256 + 16 fake interim scancodes for disambiguation purposes.*/ +static scancode scancode_set3[272] = +{ + { {0}, {0} }, { {0x76, 0}, {0xf0, 0x76, 0} }, { {0x16, 0}, {0xf0, 0x16, 0} }, { {0x1e, 0}, {0xf0, 0x1e, 0} }, + { {0x26, 0}, {0xf0, 0x26, 0} }, { {0x25, 0}, {0xf0, 0x25, 0} }, { {0x2e, 0}, {0xf0, 0x2e, 0} }, { {0x36, 0}, {0xf0, 0x36, 0} }, + { {0x3d, 0}, {0xf0, 0x3d, 0} }, { {0x3e, 0}, {0xf0, 0x3e, 0} }, { {0x46, 0}, {0xf0, 0x46, 0} }, { {0x45, 0}, {0xf0, 0x45, 0} }, + { {0x4e, 0}, {0xf0, 0x4e, 0} }, { {0x55, 0}, {0xf0, 0x55, 0} }, { {0x66, 0}, {0xf0, 0x66, 0} }, { {0x0d, 0}, {0xf0, 0x0d, 0} }, + { {0x15, 0}, {0xf0, 0x15, 0} }, { {0x1d, 0}, {0xf0, 0x1d, 0} }, { {0x24, 0}, {0xf0, 0x24, 0} }, { {0x2d, 0}, {0xf0, 0x2d, 0} }, + { {0x2c, 0}, {0xf0, 0x2c, 0} }, { {0x35, 0}, {0xf0, 0x35, 0} }, { {0x3c, 0}, {0xf0, 0x3c, 0} }, { {0x43, 0}, {0xf0, 0x43, 0} }, + { {0x44, 0}, {0xf0, 0x44, 0} }, { {0x4d, 0}, {0xf0, 0x4d, 0} }, { {0x54, 0}, {0xf0, 0x54, 0} }, { {0x5b, 0}, {0xf0, 0x5b, 0} }, + { {0x5a, 0}, {0xf0, 0x5a, 0} }, { {0x19, 0}, {0xf0, 0x19, 0} }, { {0x1c, 0}, {0xf0, 0x1c, 0} }, { {0x1b, 0}, {0xf0, 0x1b, 0} }, + { {0x23, 0}, {0xf0, 0x23, 0} }, { {0x2b, 0}, {0xf0, 0x2b, 0} }, { {0x34, 0}, {0xf0, 0x34, 0} }, { {0x33, 0}, {0xf0, 0x33, 0} }, + { {0x3b, 0}, {0xf0, 0x3b, 0} }, { {0x42, 0}, {0xf0, 0x42, 0} }, { {0x4b, 0}, {0xf0, 0x4b, 0} }, { {0x4c, 0}, {0xf0, 0x4c, 0} }, + { {0x52, 0}, {0xf0, 0x52, 0} }, { {0x0e, 0}, {0xf0, 0x0e, 0} }, { {0x12, 0}, {0xf0, 0x12, 0} }, { {0x5c, 0}, {0xf0, 0x5c, 0} }, + { {0x1a, 0}, {0xf0, 0x1a, 0} }, { {0x22, 0}, {0xf0, 0x22, 0} }, { {0x21, 0}, {0xf0, 0x21, 0} }, { {0x2a, 0}, {0xf0, 0x2a, 0} }, + { {0x32, 0}, {0xf0, 0x32, 0} }, { {0x31, 0}, {0xf0, 0x31, 0} }, { {0x3a, 0}, {0xf0, 0x3a, 0} }, { {0x41, 0}, {0xf0, 0x41, 0} }, + { {0x49, 0}, {0xf0, 0x49, 0} }, { {0x4a, 0}, {0xf0, 0x4a, 0} }, { {0x59, 0}, {0xf0, 0x59, 0} }, { {0x7c, 0}, {0xf0, 0x7c, 0} }, + { {0x11, 0}, {0xf0, 0x11, 0} }, { {0x29, 0}, {0xf0, 0x29, 0} }, { {0x14, 0}, {0xf0, 0x14, 0} }, { {0x05, 0}, {0xf0, 0x05, 0} }, + { {0x06, 0}, {0xf0, 0x06, 0} }, { {0x04, 0}, {0xf0, 0x04, 0} }, { {0x0c, 0}, {0xf0, 0x0c, 0} }, { {0x03, 0}, {0xf0, 0x03, 0} }, + { {0x0b, 0}, {0xf0, 0x0b, 0} }, { {0x83, 0}, {0xf0, 0x83, 0} }, { {0x0a, 0}, {0xf0, 0x0a, 0} }, { {0x01, 0}, {0xf0, 0x01, 0} }, + { {0x09, 0}, {0xf0, 0x09, 0} }, { {0x77, 0}, {0xf0, 0x77, 0} }, { {0x7e, 0}, {0xf0, 0x7e, 0} }, { {0x6c, 0}, {0xf0, 0x6c, 0} }, + { {0x75, 0}, {0xf0, 0x75, 0} }, { {0x7d, 0}, {0xf0, 0x7d, 0} }, { {0x7b, 0}, {0xf0, 0x7b, 0} }, { {0x6b, 0}, {0xf0, 0x6b, 0} }, + { {0x73, 0}, {0xf0, 0x73, 0} }, { {0x74, 0}, {0xf0, 0x74, 0} }, { {0x79, 0}, {0xf0, 0x79, 0} }, { {0x69, 0}, {0xf0, 0x69, 0} }, + { {0x72, 0}, {0xf0, 0x72, 0} }, { {0x7a, 0}, {0xf0, 0x7a, 0} }, { {0x70, 0}, {0xf0, 0x70, 0} }, { {0x71, 0}, {0xf0, 0x71, 0} }, + { {0x84, 0}, {0xf0, 0x84, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0x78, 0}, {0xf0, 0x78, 0} }, + { {0x07, 0}, {0xf0, 0x07, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0x79, 0}, {0xf0, 0x79, 0} }, { {0x58, 0}, {0xf0, 0x58, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0x77, 0}, {0xf0, 0x77, 0} }, { {0, 0}, {0, 0} }, { {0x57, 0}, {0xf0, 0x57, 0} }, + { {0x39, 0}, {0xf0, 0x39, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0x6e, 0}, {0xf0, 0x6e, 0} }, + { {0x63, 0}, {0xf0, 0x63, 0} }, { {0x6f, 0}, {0xf0, 0x6f, 0} }, { {0, 0}, {0, 0} }, { {0x61, 0}, {0xf0, 0x61, 0} }, + { {0, 0}, {0, 0} }, { {0x6a, 0}, {0xf0, 0x6a, 0} }, { {0, 0}, {0, 0} }, { {0x65, 0}, {0xf0, 0x65, 0} }, + { {0x60, 0}, {0xf0, 0x60, 0} }, { {0x6d, 0}, {0xf0, 0x6d, 0} }, { {0x67, 0}, {0xf0, 0x67, 0} }, { {0x64, 0}, {0xf0, 0x64, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0x8b, 0}, {0xf0, 0x8b, 0} }, + { {0x8c, 0}, {0xf0, 0x8c, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, + { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} }, +}; + /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ static scancode scancode_xt[272] = { @@ -238,11 +388,31 @@ void (*keyboard_send)(uint8_t val); void (*keyboard_poll)(); int keyboard_scan = 1; +static scancode *at_scancodes; + +void keyboard_set_scancode_set(int set) +{ + switch (set) + { + case SCANCODE_SET_1: + at_scancodes = scancode_set1; + break; + case SCANCODE_SET_2: + at_scancodes = scancode_set2; + break; + case SCANCODE_SET_3: + at_scancodes = scancode_set3; + break; + default: + pclog("Invalid scancode set: %i\n", set); + } +} + void keyboard_process() { int c; int d; - scancode *scancodes = (AT) ? scancode_set1 : scancode_xt; + scancode *scancodes = (AT) ? at_scancodes : scancode_xt; if (!keyboard_scan) return; if (TANDY) scancodes = scancode_tandy; diff --git a/src/keyboard.h b/src/keyboard.h index 6f6bc59..b48a02d 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -4,3 +4,12 @@ void keyboard_process(); extern int keyboard_scan; extern uint8_t pcem_key[272]; + +enum +{ + SCANCODE_SET_1, + SCANCODE_SET_2, + SCANCODE_SET_3 +}; + +void keyboard_set_scancode_set(int set); diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 2f06842..bed2be9 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -36,6 +36,10 @@ struct uint8_t mem[0x20]; uint8_t out; int out_new, out_delayed; + + int scancode_set; + int translate; + int next_is_release; uint8_t input_port; uint8_t output_port; @@ -56,6 +60,26 @@ struct pc_timer_t send_delay_timer; } keyboard_at; +/*Translation table taken from https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3*/ +static uint8_t at_translation[256] = +{ + 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, + 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, + 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, + 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, + 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, + 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, + 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, + 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, + 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; static uint8_t key_ctrl_queue[16]; static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0; @@ -173,6 +197,21 @@ void keyboard_at_adddata_keyboard(uint8_t val) case 0x4D: t3100e_notify_set(0x0F); break; /* Right */ } } + if (keyboard_at.translate) + { + if (val == 0xf0) + { + keyboard_at.next_is_release = 1; + return; + } + else + { + val = at_translation[val]; + if (keyboard_at.next_is_release) + val |= 0x80; + keyboard_at.next_is_release = 0; + } + } key_queue[key_queue_end] = val; key_queue_end = (key_queue_end + 1) & 0xf; // pclog("keyboard_at : %02X added to key queue\n", val); @@ -221,6 +260,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) if (!(val & 1) && keyboard_at.wantirq) keyboard_at.wantirq = 0; mouse_scan = !(val & 0x20); + keyboard_at.translate = val & 0x40; } break; @@ -274,6 +314,45 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xed: /*Set/reset LEDs*/ keyboard_at_adddata_keyboard(0xfa); break; + + case 0xf0: /*Set scancode set*/ + switch (val) + { + case 0: /*Read current set*/ + keyboard_at_adddata_keyboard(0xfa); + switch (keyboard_at.scancode_set) + { + case SCANCODE_SET_1: + keyboard_at_adddata_keyboard(0x01); + break; + case SCANCODE_SET_2: + keyboard_at_adddata_keyboard(0x02); + break; + case SCANCODE_SET_3: + keyboard_at_adddata_keyboard(0x03); + break; + } + break; + case 1: + keyboard_at.scancode_set = SCANCODE_SET_1; + keyboard_set_scancode_set(SCANCODE_SET_1); + keyboard_at_adddata_keyboard(0xfa); + break; + case 2: + keyboard_at.scancode_set = SCANCODE_SET_2; + keyboard_set_scancode_set(SCANCODE_SET_2); + keyboard_at_adddata_keyboard(0xfa); + break; + case 3: + keyboard_at.scancode_set = SCANCODE_SET_3; + keyboard_set_scancode_set(SCANCODE_SET_3); + keyboard_at_adddata_keyboard(0xfa); + break; + default: + keyboard_at_adddata_keyboard(0xfe); + break; + } + break; case 0xf3: /*Set typematic rate/delay*/ keyboard_at_adddata_keyboard(0xfa); @@ -299,6 +378,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at_adddata_keyboard(0xfa); break; + case 0xf0: /*Set scancode set*/ + keyboard_at.key_wantdata = 1; + keyboard_at_adddata_keyboard(0xfa); + break; + case 0xf2: /*Read ID*/ keyboard_at_adddata_keyboard(0xfa); keyboard_at_adddata_keyboard(0xab); @@ -639,6 +723,7 @@ void keyboard_at_init() keyboard_at.mouse_write = NULL; keyboard_at.mouse_p = NULL; keyboard_at.is_ps2 = 0; + keyboard_set_scancode_set(SCANCODE_SET_2); timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1); } From b98a6d63b1953a2db262a76cef8d0babf6e8f23f Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 30 Apr 2019 21:20:00 +0100 Subject: [PATCH 0709/1050] Fix up offset calculations in x86-64 absolute address opcode generation, and add pointer to RAM array in NO_IMMEDIATES blocks. Fixes crashes/segfaults with x86-64 recompiler. --- src/codegen_backend_x86-64.c | 2 + src/codegen_backend_x86-64_defs.h | 2 + src/codegen_backend_x86-64_ops.c | 86 +++++++++++++++++++++++++------ 3 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index f1dcd86..9d92f2f 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -358,6 +358,8 @@ void codegen_backend_prologue(codeblock_t *block) host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t)ram); } void codegen_backend_epilogue(codeblock_t *block) diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index 95a5294..a368651 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -1,3 +1,5 @@ +/*RBP = cpu_state + 128 + R12 = ram (if block->flags & CODEBLOCK_NO_IMMEDIATES)*/ #define REG_AX 0 #define REG_CX 1 #define REG_DX 2 diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index 48acb73..c017699 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -499,7 +499,7 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); if (offset >= -128 && offset < 127) { @@ -519,7 +519,7 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) } void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); if (offset >= -128 && offset < 127) { @@ -540,7 +540,7 @@ void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); if (src_reg & 8) fatal("host_x86_MOV8_ABS_REG - bad reg\n"); @@ -614,7 +614,7 @@ void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) } void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); if (src_reg & 8) fatal("host_x86_MOV64_ABS_REG - bad reg\n"); @@ -675,8 +675,9 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_r void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + if (dst_reg & 8) fatal("host_x86_MOV8_REG_ABS reg & 8\n"); @@ -691,6 +692,12 @@ void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } + else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { fatal("host_x86_MOV8_REG_ABS - out of range\n"); @@ -698,7 +705,8 @@ void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) } void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; if (dst_reg & 8) fatal("host_x86_MOV16_REG_ABS reg & 8\n"); @@ -714,15 +722,28 @@ void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } + else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) + { + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, ram_offset); + } else { fatal("host_x86_MOV16_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 1); + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ } } void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + if (dst_reg & 8) fatal("host_x86_MOV32_REG_ABS reg & 8\n"); @@ -737,6 +758,12 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ codegen_addlong(block, offset); } + else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { fatal("host_x86_MOV32_REG_ABS - out of range\n"); @@ -748,7 +775,7 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) } void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); if (dst_reg & 8) fatal("host_x86_MOV64_REG_ABS reg & 8\n"); @@ -1062,8 +1089,9 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + if (dst_reg & 8) fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); @@ -1073,6 +1101,13 @@ void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) codegen_addbyte(block, 0x66); codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ } + else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) + { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x66, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { codegen_alloc_bytes(block, 10); @@ -1085,8 +1120,9 @@ void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) } void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + // if (dst_reg & 8) // fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); @@ -1104,6 +1140,16 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ } } + else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) + { + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { if (dst_reg & 8) @@ -1118,8 +1164,9 @@ void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) } void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + if (dst_reg & 8) fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); @@ -1128,6 +1175,13 @@ void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ } + else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) + { + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { codegen_alloc_bytes(block, 10); From abb5184ed4950e4e24f3fe4f4205cce8938f03a6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 30 Apr 2019 21:47:17 +0100 Subject: [PATCH 0710/1050] Loading SS in v86 mode (but not real mode) does reset the stack size. Fixes DOS programs in Windows 9x. --- src/x86seg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x86seg.c b/src/x86seg.c index 8335897..bd7c6db 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -460,6 +460,8 @@ int loadseg(uint16_t seg, x86seg *s) codegen_flat_ds = 0; if (s == &cpu_state.seg_ss) codegen_flat_ss = 0; + if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) + set_stack32(0); } if (s == &cpu_state.seg_ds) From 66b0b9c9266a6c166cc2b6ab6e58e8755efa93ae Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 1 May 2019 20:18:13 +0100 Subject: [PATCH 0711/1050] Use inline assembly routine for x87 comparisons on x86-64. Fixes Unreal. --- src/x87_ops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/x87_ops.h b/src/x87_ops.h index 1208854..315c17d 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -208,7 +208,7 @@ static inline void x87_stmmx(MMX_REG r) 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 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ uint32_t out; /* Memory barrier, to force GCC to write to the input parameters @@ -242,7 +242,7 @@ static inline uint16_t x87_compare(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 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ uint32_t out; /* Memory barrier, to force GCC to write to the input parameters From 49f2f342499d4178bc59e2e9b49aab7838133189 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 1 May 2019 21:38:28 +0100 Subject: [PATCH 0712/1050] Fixed CTRL-ALT-DEL menu option broken by recent keyboard changes. --- src/keyboard.c | 19 +++++++++++++++++++ src/keyboard.h | 1 + src/pc.c | 12 ++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index 820d5ff..26d7280 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -463,3 +463,22 @@ void keyboard_process() } } } + +void keyboard_send_scancode(int code, int is_break) +{ + scancode *scancodes = (AT) ? at_scancodes : scancode_xt; + int d = 0; + + if (!keyboard_scan) return; + + if (!is_break) + { + while (scancodes[code].scancodes_make[d] != 0) + keyboard_send(scancodes[code].scancodes_make[d++]); + } + else + { + while (scancodes[code].scancodes_break[d] != 0) + keyboard_send(scancodes[code].scancodes_break[d++]); + } +} diff --git a/src/keyboard.h b/src/keyboard.h index b48a02d..c4a63e0 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -13,3 +13,4 @@ enum }; void keyboard_set_scancode_set(int set); +void keyboard_send_scancode(int code, int is_break); diff --git a/src/pc.c b/src/pc.c index 1951134..2cbf071 100644 --- a/src/pc.c +++ b/src/pc.c @@ -388,12 +388,12 @@ void resetpc() void resetpc_cad() { - keyboard_send(29); /* Ctrl key pressed */ - keyboard_send(56); /* Alt key pressed */ - keyboard_send(83); /* Delete key pressed */ - keyboard_send(157); /* Ctrl key released */ - keyboard_send(184); /* Alt key released */ - keyboard_send(211); /* Delete key released */ + keyboard_send_scancode(29, 0); /* Ctrl key pressed */ + keyboard_send_scancode(56, 0); /* Alt key pressed */ + keyboard_send_scancode(83, 0); /* Delete key pressed */ + keyboard_send_scancode(29, 1); /* Ctrl key released */ + keyboard_send_scancode(56, 1); /* Alt key released */ + keyboard_send_scancode(83, 1); /* Delete key released */ } void resetpchard() From 277b4c3988e743aca137840d72cfad82bde8e5d0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 2 May 2019 19:55:29 +0100 Subject: [PATCH 0713/1050] Mask PC correctly on IRET to V86 mode. Fixes Windows NT 3.51 installer. --- src/x86seg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86seg.c b/src/x86seg.c index bd7c6db..d58f8c2 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2152,7 +2152,7 @@ void pmodeiret(int is32) // pclog("V86 IRET %04X:%08X\n",SS,ESP); // output=3; - cpu_state.pc=newpc; + cpu_state.pc = newpc & 0xffff; cpu_state.seg_cs.base=seg<<4; cpu_state.seg_cs.limit=0xFFFF; cpu_state.seg_cs.limit_low = 0; From 7be2eb53e223c46fcd6f4da461ebbd663cdbdfb0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 2 May 2019 21:54:08 +0100 Subject: [PATCH 0714/1050] Restore correct CS on abort while processing a CALL to a non-conforming code segment. Fixes OS/2 Warp. --- src/x86seg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/x86seg.c b/src/x86seg.c index d58f8c2..acaa2dd 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -1124,6 +1124,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ if (DPL < CPL) { + uint16_t oldcs = CS; oaddr = addr; /*Load new stack*/ oldss=SS; @@ -1239,6 +1240,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc) pclog("ABRT PUSHL\n"); SS = oldss; ESP = oldsp2; + CS = oldcs; return; } // if (output) pclog("Stack now %04X:%08X\n",SS,ESP); @@ -1253,6 +1255,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc) pclog("ABRT COPYL\n"); SS = oldss; ESP = oldsp2; + CS = oldcs; return; } } @@ -1270,6 +1273,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc) pclog("ABRT PUSHW\n"); SS = oldss; ESP = oldsp2; + CS = oldcs; return; } if (output) pclog("Write SP to %04X:%04X\n",SS,SP); @@ -1288,6 +1292,7 @@ void loadcscall(uint16_t seg, uint32_t old_pc) pclog("ABRT COPYW\n"); SS = oldss; ESP = oldsp2; + CS = oldcs; return; } } From 12439b7c62ff05aeca1e12d43d4dc13346bda68f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 May 2019 15:53:46 +0100 Subject: [PATCH 0715/1050] Add 82091AA AIP SuperIO for Packard Bell PB520R. Fixes floppy drives and duplicate ports in Windows 95. --- src/82091aa.c | 196 +++++++++++++++++++++++++++++ src/82091aa.h | 1 + src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/model.c | 2 + 6 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/82091aa.c create mode 100644 src/82091aa.h diff --git a/src/82091aa.c b/src/82091aa.c new file mode 100644 index 0000000..bd95071 --- /dev/null +++ b/src/82091aa.c @@ -0,0 +1,196 @@ +#include "ibm.h" +#include "82091aa.h" +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" + +#define AIP_AIPID 0x00 +#define AIP_AIPREV 0x01 +#define AIP_AIPCFG1 0x02 +#define AIP_AIPCFG2 0x03 +#define AIP_FCFG1 0x10 +#define AIP_FCFG2 0x11 +#define AIP_PCFG1 0x20 +#define AIP_PCFG2 0x21 +#define AIP_SACFG1 0x30 +#define AIP_SACFG2 0x31 +#define AIP_SBCFG1 0x40 +#define AIP_SBCFG2 0x41 +#define AIP_IDECFG 0x50 + +#define FCFG1_FDC_ENA (1 << 0) +#define FCFG1_FDC_ADDR (1 << 1) + +#define PCFG1_PP_ENA (1 << 0) +#define PCFG1_PP_ADDR (3 << 1) +#define PCFG1_PP_ADDR_378 (0 << 1) +#define PCFG1_PP_ADDR_278 (1 << 1) +#define PCFG1_PP_ADDR_3BC (2 << 1) + +#define SxCFG1_ENA (1 << 0) +#define SxCFG1_ADDR (7 << 1) +#define SxCFG1_ADDR_3F8 (0 << 1) +#define SxCFG1_ADDR_2F8 (1 << 1) +#define SxCFG1_ADDR_220 (2 << 1) +#define SxCFG1_ADDR_228 (3 << 1) +#define SxCFG1_ADDR_238 (4 << 1) +#define SxCFG1_ADDR_2E8 (5 << 1) +#define SxCFG1_ADDR_338 (6 << 1) +#define SxCFG1_ADDR_3E8 (7 << 1) +#define SxCFG1_IRQ (1 << 4) +#define SxCFG1_IRQ_3 (0 << 4) +#define SxCFG1_IRQ_4 (1 << 4) + +static struct +{ + int idx; + uint8_t regs[256]; +} aip; + +static uint8_t aip_read(uint16_t addr, void *p) +{ + uint8_t temp; + + if (!(addr & 1)) + temp = aip.idx; + else + temp = aip.regs[aip.idx]; + +// pclog("aip_read: addr=%04x val=%02x\n", addr, temp); + return temp; +} + +static void aip_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("aip_write: addr=%04x val=%02x\n", addr, val); + if (!(addr & 1)) + aip.idx = val; + else + { +// pclog("AIP register write: idx=%02x val=%02x\n", aip.idx, val); + switch (aip.idx) + { + case AIP_AIPCFG1: + aip.regs[AIP_AIPCFG1] = (val & ~0x4e) | (aip.regs[AIP_AIPCFG1] & 0x48); + break; + case AIP_AIPCFG2: + aip.regs[AIP_AIPCFG2] = val & 0xf8; + break; + case AIP_FCFG1: + aip.regs[AIP_FCFG1] = val & 0x83; + fdc_remove(); + if ((aip.regs[AIP_FCFG1] & FCFG1_FDC_ENA) && !(aip.regs[AIP_FCFG1] & FCFG1_FDC_ADDR)) + fdc_add(); + break; + case AIP_FCFG2: + aip.regs[AIP_FCFG2] = (val & 0x0d) | (aip.regs[AIP_FCFG2] & 0x02); + break; + case AIP_PCFG1: + aip.regs[AIP_PCFG1] = val & 0xef; + lpt1_remove(); + if (aip.regs[AIP_PCFG1] & PCFG1_PP_ENA) + { + switch (aip.regs[AIP_PCFG1] & PCFG1_PP_ADDR) + { + case PCFG1_PP_ADDR_378: + lpt1_init(0x378); + break; + case PCFG1_PP_ADDR_278: + lpt1_init(0x278); + break; + case PCFG1_PP_ADDR_3BC: + lpt1_init(0x3bc); + break; + } + } + break; + case AIP_PCFG2: + aip.regs[AIP_PCFG2] = (val & 0x0d) | (aip.regs[AIP_PCFG2] & 0x22); + break; + case AIP_SACFG1: + aip.regs[AIP_SACFG1] = val & 0x9f; + serial1_remove(); + if (aip.regs[AIP_SACFG1] & SxCFG1_ENA) + { + uint16_t base = 0; + int irq = 0; + + switch (aip.regs[AIP_SACFG1] & SxCFG1_ADDR) + { + case SxCFG1_ADDR_3F8: base = 0x3f8; break; + case SxCFG1_ADDR_2F8: base = 0x2f8; break; + case SxCFG1_ADDR_220: base = 0x220; break; + case SxCFG1_ADDR_228: base = 0x228; break; + case SxCFG1_ADDR_238: base = 0x238; break; + case SxCFG1_ADDR_2E8: base = 0x2e8; break; + case SxCFG1_ADDR_338: base = 0x338; break; + case SxCFG1_ADDR_3E8: base = 0x3e8; break; + } + switch (aip.regs[AIP_SACFG1] & SxCFG1_IRQ) + { + case SxCFG1_IRQ_3: irq = 3; break; + case SxCFG1_IRQ_4: irq = 4; break; + } + serial1_set(base, irq); + } + break; + case AIP_SACFG2: + aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); + break; + case AIP_SBCFG1: + aip.regs[AIP_SBCFG1] = val & 0x9f; + serial2_remove(); + if (aip.regs[AIP_SBCFG1] & SxCFG1_ENA) + { + uint16_t base = 0; + int irq = 0; + + switch (aip.regs[AIP_SBCFG1] & SxCFG1_ADDR) + { + case SxCFG1_ADDR_3F8: base = 0x3f8; break; + case SxCFG1_ADDR_2F8: base = 0x2f8; break; + case SxCFG1_ADDR_220: base = 0x220; break; + case SxCFG1_ADDR_228: base = 0x228; break; + case SxCFG1_ADDR_238: base = 0x238; break; + case SxCFG1_ADDR_2E8: base = 0x2e8; break; + case SxCFG1_ADDR_338: base = 0x338; break; + case SxCFG1_ADDR_3E8: base = 0x3e8; break; + } + switch (aip.regs[AIP_SBCFG1] & SxCFG1_IRQ) + { + case SxCFG1_IRQ_3: irq = 3; break; + case SxCFG1_IRQ_4: irq = 4; break; + } + serial2_set(base, irq); + } + break; + case AIP_SBCFG2: + aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); + break; + case AIP_IDECFG: + aip.regs[AIP_IDECFG] = val & 0x07; + break; + } + } +} + +void aip_82091aa_init(uint16_t base) +{ + io_sethandler(base, 0x0002, aip_read, NULL, NULL, aip_write, NULL, NULL, NULL); + + memset(&aip.regs, 0xff, sizeof(aip.regs)); + aip.regs[AIP_AIPID] = 0xa0; + aip.regs[AIP_AIPREV] = 0x00; + aip.regs[AIP_AIPCFG1] = 0x40; + aip.regs[AIP_AIPCFG2] = 0x00; + aip.regs[AIP_FCFG1] = 0x01; + aip.regs[AIP_FCFG2] = 0x00; + aip.regs[AIP_PCFG1] = 0x00; + aip.regs[AIP_PCFG2] = 0x00; + aip.regs[AIP_SACFG1] = 0x00; + aip.regs[AIP_SACFG2] = 0x02; + aip.regs[AIP_SBCFG1] = 0x00; + aip.regs[AIP_SBCFG2] = 0x02; + aip.regs[AIP_IDECFG] = 0x01; +} diff --git a/src/82091aa.h b/src/82091aa.h new file mode 100644 index 0000000..79467d6 --- /dev/null +++ b/src/82091aa.h @@ -0,0 +1 @@ +void aip_82091aa_init(uint16_t base); diff --git a/src/Makefile.am b/src/Makefile.am index 416bc92..e92dc82 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acc2168.c acc3221.c acer386sx.c \ +pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c 820911.c acc2036.c acc2168.c acc3221.c acer386sx.c \ ali1429.c amstrad.c cassette.c cbm_io.c cdrom-image.cc cdrom-null.c cmd640.c codegen.c codegen_accumulate.c \ codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c \ codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 7d195ab..afab4b2 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/MinGWget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 820911.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 4e8907e..7f26ab5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 820911.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ diff --git a/src/model.c b/src/model.c index 9dcf5e2..84ca918 100644 --- a/src/model.c +++ b/src/model.c @@ -4,6 +4,7 @@ #include "io.h" #include "mouse.h" +#include "82091aa.h" #include "acc2036.h" #include "acc2168.h" #include "acc3221.h" @@ -660,6 +661,7 @@ void at_pb520r_init() i430lx_init(); sio_init(2, 0xc, 0xe, 0x6, 0); cmd640b_init(1); + aip_82091aa_init(0x22); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); } From cfd2e4e14c8443100271da2cd0f56747851d08e3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 May 2019 16:02:55 +0100 Subject: [PATCH 0716/1050] Fix gameport timing when no joystick plugged in. Fixes phantom joystick in some games (eg Rayman, The Lion King, Zone 66). --- src/gameport.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/gameport.c b/src/gameport.c index d8eb6c4..9b797b4 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -87,15 +87,19 @@ typedef struct gameport_t static gameport_t *gameport_global = NULL; -static uint64_t gameport_time(int axis) +static void gameport_time(gameport_t *gameport, int nr, int axis) { if (axis == AXIS_NOT_PRESENT) - return 0; - - axis += 32768; - axis = (axis * 100) / 65; /*Axis now in ohms*/ - axis = (axis * 11) / 1000; - return TIMER_USEC * (axis + 24); /*max = 11.115 ms*/ + { + timer_disable(&gameport->axis[nr].timer); + } + else + { + axis += 32768; + axis = (axis * 100) / 65; /*Axis now in ohms*/ + axis = (axis * 11) / 1000; + timer_set_delay_u64(&gameport->axis[nr].timer, TIMER_USEC * (axis + 24)); /*max = 11.115 ms*/ + } } void gameport_write(uint16_t addr, uint8_t val, void *p) @@ -104,11 +108,11 @@ void gameport_write(uint16_t addr, uint8_t val, void *p) gameport->state |= 0x0f; // pclog("gameport_write : joysticks_present=%i\n", joysticks_present); - - timer_set_delay_u64(&gameport->axis[0].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0))); - timer_set_delay_u64(&gameport->axis[1].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1))); - timer_set_delay_u64(&gameport->axis[2].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 2))); - timer_set_delay_u64(&gameport->axis[3].timer, gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 3))); + + gameport_time(gameport, 0, gameport->joystick->read_axis(gameport->joystick_dat, 0)); + gameport_time(gameport, 1, gameport->joystick->read_axis(gameport->joystick_dat, 1)); + gameport_time(gameport, 2, gameport->joystick->read_axis(gameport->joystick_dat, 2)); + gameport_time(gameport, 3, gameport->joystick->read_axis(gameport->joystick_dat, 3)); gameport->joystick->write(gameport->joystick_dat); From 8a7c3d78e794a722da1f4b0cbee2fc39b492695c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 May 2019 18:26:14 +0100 Subject: [PATCH 0717/1050] Fix timer bugs in Windows Sound System emulation. --- src/sound_ad1848.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound_ad1848.c b/src/sound_ad1848.c index abbbc96..077611b 100644 --- a/src/sound_ad1848.c +++ b/src/sound_ad1848.c @@ -67,16 +67,16 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p) case 7: freq /= 2560; break; } ad1848->freq = freq; - ad1848->timer_latch = (int)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); + ad1848->timer_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); break; case 9: if (!ad1848->enable && (val & 0x41) == 0x01) { if (ad1848->timer_latch) - timer_advance_u64(&ad1848->timer, ad1848->timer_latch); + timer_set_delay_u64(&ad1848->timer, ad1848->timer_latch); else - timer_advance_u64(&ad1848->timer, TIMER_USEC); + timer_set_delay_u64(&ad1848->timer, TIMER_USEC); } ad1848->enable = ((val & 0x41) == 0x01); if (!ad1848->enable) @@ -122,7 +122,7 @@ static void ad1848_poll(void *p) if (ad1848->timer_latch) timer_advance_u64(&ad1848->timer, ad1848->timer_latch); else - timer_advance_u64(&ad1848->timer, TIMER_USEC); + timer_advance_u64(&ad1848->timer, TIMER_USEC*1000); ad1848_update(ad1848); From e2a9629a89b7cdd46a523c15b46d7a5943d9381b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 May 2019 09:22:26 +0100 Subject: [PATCH 0718/1050] Fix typo in Makefiles. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index e92dc82..993e6c0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,7 +23,7 @@ wx-resources.cpp : pc.xrc -wxrc -c pc.xrc -o wx-resources.cpp # PCem -pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c 820911.c acc2036.c acc2168.c acc3221.c acer386sx.c \ +pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c 808x.c 82091aa.c acc2036.c acc2168.c acc3221.c acer386sx.c \ ali1429.c amstrad.c cassette.c cbm_io.c cdrom-image.cc cdrom-null.c cmd640.c codegen.c codegen_accumulate.c \ codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c codegen_ops_arith.c \ codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ops_fpu_loadstore.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index afab4b2..63ba36c 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/MinGWget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 820911.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 7f26ab5..b0e5509 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -6,7 +6,7 @@ WXVERSION = 31 WXINCLUDE = e:/mingwget/include/wx/ CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Werror -fno-strict-aliasing -DUSE_NETWORKING CXXFLAGS = $(CFLAGS) -OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 820911.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ +OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc2036.o acc2168.o acc3221.o acer386sx.o ali1429.o amstrad.o cassette.o \ cbm_io.o cdrom-ioctl.o cdrom-image.o cmd640.o codegen.o codegen_accumulate.o codegen_allocator.o \ codegen_backend_x86.o codegen_backend_x86_ops.o codegen_backend_x86_ops_fpu.o codegen_backend_x86_ops_sse.o \ codegen_backend_x86_uops.o codegen_block.o codegen_ir.o codegen_ops.o \ From 5e35e48ec76dbea1479eced18f9f929302ca4698 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 May 2019 14:49:10 +0100 Subject: [PATCH 0719/1050] XMM registers are not preserved across function calls, and should be flushed & discarded by the recompiler prior to calling external functions. Fixes graphics issues in some games (eg World Cup 98 title/menus). --- src/codegen_backend.h | 18 ++++++- src/codegen_backend_arm.c | 34 ++++++------- src/codegen_backend_arm64.c | 40 ++++++++-------- src/codegen_backend_x86-64.c | 34 ++++++++----- src/codegen_backend_x86-64_defs.h | 2 +- src/codegen_backend_x86.c | 25 +++++----- src/codegen_reg.c | 80 +++++++++++++++++-------------- 7 files changed, 135 insertions(+), 98 deletions(-) diff --git a/src/codegen_backend.h b/src/codegen_backend.h index 7a5c5c0..45668df 100644 --- a/src/codegen_backend.h +++ b/src/codegen_backend.h @@ -1,3 +1,6 @@ +#ifndef _CODEGEN_BACKEND_H_ +#define _CODEGEN_BACKEND_H_ + //#ifdef __amd64__ //#include "codegen_x86-64.h" #if defined __amd64__ @@ -25,5 +28,16 @@ typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop); extern const uOpFn uop_handlers[]; -extern int codegen_host_reg_list[CODEGEN_HOST_REGS]; -extern int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS]; +/*Register will not be preserved across function calls*/ +#define HOST_REG_FLAG_VOLATILE (1 << 0) + +typedef struct host_reg_def_t +{ + int reg; + int flags; +} host_reg_def_t; + +extern host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS]; +extern host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS]; + +#endif diff --git a/src/codegen_backend_arm.c b/src/codegen_backend_arm.c index 0c1c2c8..aa9345c 100644 --- a/src/codegen_backend_arm.c +++ b/src/codegen_backend_arm.c @@ -38,27 +38,27 @@ void *codegen_fp_round; void *codegen_gpf_rout; void *codegen_exit_rout; -int codegen_host_reg_list[CODEGEN_HOST_REGS] = +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { - REG_R4, - REG_R5, - REG_R6, - REG_R7, - REG_R8, - REG_R9, - REG_R11, + {REG_R4, 0}, + {REG_R5, 0}, + {REG_R6, 0}, + {REG_R7, 0}, + {REG_R8, 0}, + {REG_R9, 0}, + {REG_R11, 0} }; -int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { - REG_D8, - REG_D9, - REG_D10, - REG_D11, - REG_D12, - REG_D13, - REG_D14, - REG_D15 + {REG_D8, 0}, + {REG_D9, 0}, + {REG_D10, 0}, + {REG_D11, 0}, + {REG_D12, 0}, + {REG_D13, 0}, + {REG_D14, 0}, + {REG_D15, 0} }; static void build_load_routine(codeblock_t *block, int size, int is_float) diff --git a/src/codegen_backend_arm64.c b/src/codegen_backend_arm64.c index eb50aa6..1885e61 100644 --- a/src/codegen_backend_arm64.c +++ b/src/codegen_backend_arm64.c @@ -39,30 +39,30 @@ void *codegen_fp_round_quad; void *codegen_gpf_rout; void *codegen_exit_rout; -int codegen_host_reg_list[CODEGEN_HOST_REGS] = +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { - REG_X19, - REG_X20, - REG_X21, - REG_X22, - REG_X23, - REG_X24, - REG_X25, - REG_X26, - REG_X27, - REG_X28 + {REG_X19, 0}, + {REG_X20, 0}, + {REG_X21, 0}, + {REG_X22, 0}, + {REG_X23, 0}, + {REG_X24, 0}, + {REG_X25, 0}, + {REG_X26, 0}, + {REG_X27, 0}, + {REG_X28, 0} }; -int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { - REG_V8, - REG_V9, - REG_V10, - REG_V11, - REG_V12, - REG_V13, - REG_V14, - REG_V15 + {REG_V8, 0}, + {REG_V9, 0}, + {REG_V10, 0}, + {REG_V11, 0}, + {REG_V12, 0}, + {REG_V13, 0}, + {REG_V14, 0}, + {REG_V15, 0} }; static void build_load_routine(codeblock_t *block, int size, int is_float) diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 9d92f2f..03cde31 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -35,22 +35,32 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -int codegen_host_reg_list[CODEGEN_HOST_REGS] = +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { - REG_EAX, - REG_EBX, - REG_EDX + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + {REG_EBX, 0}, + {REG_EDX, 0} }; -int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { - REG_XMM0, - REG_XMM1, - REG_XMM2, - REG_XMM3, - REG_XMM4, - REG_XMM5, - REG_XMM6 +#if WIN64 + /*Windows x86-64 calling convention preserves XMM6-XMM15*/ + {REG_XMM6, 0}, + {REG_XMM7, 0}, +#else + /*System V AMD64 calling convention does not preserve any XMM registers*/ + {REG_XMM6, HOST_REG_FLAG_VOLATILE}, + {REG_XMM7, HOST_REG_FLAG_VOLATILE}, +#endif + {REG_XMM1, HOST_REG_FLAG_VOLATILE}, + {REG_XMM2, HOST_REG_FLAG_VOLATILE}, + {REG_XMM3, HOST_REG_FLAG_VOLATILE}, + {REG_XMM4, HOST_REG_FLAG_VOLATILE}, + {REG_XMM5, HOST_REG_FLAG_VOLATILE} }; static void build_load_routine(codeblock_t *block, int size, int is_float) diff --git a/src/codegen_backend_x86-64_defs.h b/src/codegen_backend_x86-64_defs.h index a368651..8856887 100644 --- a/src/codegen_backend_x86-64_defs.h +++ b/src/codegen_backend_x86-64_defs.h @@ -44,7 +44,7 @@ #define REG_XMM6 6 #define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM7 +#define REG_XMM_TEMP REG_XMM0 #define CODEGEN_HOST_REGS 3 #define CODEGEN_HOST_FP_REGS 7 diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 1700eb0..2fd0565 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -36,21 +36,24 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -int codegen_host_reg_list[CODEGEN_HOST_REGS] = +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { - REG_EAX, - REG_EBX, - REG_EDX + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + {REG_EBX, 0}, + {REG_EDX, 0} }; -int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { - REG_XMM0, - REG_XMM1, - REG_XMM2, - REG_XMM3, - REG_XMM4, - REG_XMM5 + {REG_XMM0, HOST_REG_FLAG_VOLATILE}, + {REG_XMM1, HOST_REG_FLAG_VOLATILE}, + {REG_XMM2, HOST_REG_FLAG_VOLATILE}, + {REG_XMM3, HOST_REG_FLAG_VOLATILE}, + {REG_XMM4, HOST_REG_FLAG_VOLATILE}, + {REG_XMM5, HOST_REG_FLAG_VOLATILE} }; static void build_load_routine(codeblock_t *block, int size, int is_float) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 2601b5a..e28068b 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -22,7 +22,7 @@ typedef struct host_reg_set_t { ir_reg_t *regs; uint8_t *dirty; - int *reg_list; + host_reg_def_t *reg_list; uint16_t locked; int nr_regs; } host_reg_set_t; @@ -274,72 +274,72 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_16_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_16(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; case REG_DWORD: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_32_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_32(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; case REG_QWORD: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_64_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_64(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; case REG_POINTER: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_pointer_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_pointer(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; case REG_DOUBLE: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_double_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else - codegen_direct_read_double(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; case REG_FPU_ST_BYTE: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_8(block, reg_set->reg_list[c], &cpu_state.tag[ir_reg.reg & 7]); + codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); else - codegen_direct_read_st_8(block, reg_set->reg_list[c], &cpu_state.tag[0], ir_reg.reg & 7); + codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); break; case REG_FPU_ST_QWORD: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_64(block, reg_set->reg_list[c], &cpu_state.MM[ir_reg.reg & 7]); + codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); else - codegen_direct_read_st_64(block, reg_set->reg_list[c], &cpu_state.MM[0], ir_reg.reg & 7); + codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); break; case REG_FPU_ST_DOUBLE: if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]); + codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); else - codegen_direct_read_st_double(block, reg_set->reg_list[c], &cpu_state.ST[0], ir_reg.reg & 7); + codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); break; default: @@ -367,7 +367,7 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_BYTE %p\n", p); - codegen_direct_write_8(block, p, reg_set->reg_list[c]); + codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); break; case REG_WORD: @@ -375,25 +375,25 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_WORD %p\n", p); - codegen_direct_write_16(block, p, reg_set->reg_list[c]); + codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); break; case REG_DWORD: if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); if ((uintptr_t)p < 256) - codegen_direct_write_32_stack(block, (int)p, reg_set->reg_list[c]); + codegen_direct_write_32_stack(block, (int)p, reg_set->reg_list[c].reg); else - codegen_direct_write_32(block, p, reg_set->reg_list[c]); + codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); break; case REG_QWORD: if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); if ((uintptr_t)p < 256) - codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c]); + codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c].reg); else - codegen_direct_write_64(block, p, reg_set->reg_list[c]); + codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); break; case REG_POINTER: @@ -401,43 +401,43 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_POINTER %p\n", p); - codegen_direct_write_ptr(block, p, reg_set->reg_list[c]); + codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); break; case REG_DOUBLE: if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); if ((uintptr_t)p < 256) - codegen_direct_write_double_stack(block, (int)p, reg_set->reg_list[c]); + codegen_direct_write_double_stack(block, (int)p, reg_set->reg_list[c].reg); else - codegen_direct_write_double(block, p, reg_set->reg_list[c]); + codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); break; case REG_FPU_ST_BYTE: if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); + codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); else - codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); + codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); break; case REG_FPU_ST_QWORD: if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); + codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); else - codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); + codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); break; case REG_FPU_ST_DOUBLE: if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); + codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); else - codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); + codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); break; default: @@ -595,7 +595,7 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in if (host_reg_idx) *host_reg_idx = c; // pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], reg_set->regs[c].reg,reg_set->regs[c].version, c); - return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) @@ -623,7 +623,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) reg_set->regs[c].version = ir_reg.version; reg_set->dirty[c] = 1; // pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } /*Search for previous version in host register*/ @@ -668,7 +668,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) reg_set->regs[c].version = ir_reg.version; reg_set->dirty[c] = 1; // pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) @@ -683,6 +683,11 @@ void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { codegen_reg_writeback(reg_set, block, c, 0); } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) + { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } } reg_set = &host_fp_reg_set; @@ -692,6 +697,11 @@ void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { codegen_reg_writeback(reg_set, block, c, 0); } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) + { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } } } From 5ef5fc1f98c3bcd4c709e6d9df18277c5266adc9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 5 May 2019 17:08:17 +0100 Subject: [PATCH 0720/1050] Tweak Voodoo swap pending code. Fixes hang in Carmageddon 3DFX version. --- src/vid_voodoo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 480374e..157d62c 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -4307,7 +4307,7 @@ static void wait_for_swap_complete(voodoo_t *voodoo) { thread_wait_event(voodoo->wake_fifo_thread, -1); thread_reset_event(voodoo->wake_fifo_thread); - if ((voodoo->swap_pending && voodoo->flush) || FIFO_ENTRIES >= 65536) + if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) { /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ memset(voodoo->dirty_line, 1, 1024); From 6a27983f179695c263ebc95f52b8ef81008fb4bb Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 8 May 2019 21:49:47 +0100 Subject: [PATCH 0721/1050] In Windows IOCTL CD-ROM code, only try reading via SPTI if ReadFile returned success but didn't read all requested data. Fixes Red Alert 2 installer. --- src/cdrom-ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 3ae7a23..8c8eb2b 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -451,8 +451,8 @@ static int ioctl_readsector(uint8_t *b, int sector, int count) status = ReadFile(hIOCTL, b, count*2048, (LPDWORD)&size, NULL); ioctl_close(); - /*If the read failed, try again using SPTI*/ - if (!status || size != count*2048) + /*If the read 'succeeded' but didn't read all required data, try again using SPTI*/ + if (status && size != count*2048) { uint8_t cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; From 2b6b14f17516b4af88739c7821ab2d382bdd4818 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 8 May 2019 21:50:52 +0100 Subject: [PATCH 0722/1050] Set BUSY_STAT in ATAPI code. Fixes 'Device failed to request command' error when installing Windows ME. --- src/ide_atapi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ide_atapi.c b/src/ide_atapi.c index 0324e9c..45586e7 100644 --- a/src/ide_atapi.c +++ b/src/ide_atapi.c @@ -36,6 +36,7 @@ void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val) { atapi_dev->state = ATAPI_STATE_GOT_COMMAND; timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); } break; @@ -48,6 +49,7 @@ void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val) atapi_dev->bus_state = 0; atapi_dev->state = ATAPI_STATE_WRITE_DATA; timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); } break; } @@ -74,6 +76,7 @@ uint16_t atapi_data_read(atapi_device_t *atapi_dev) { atapi_dev->state = ATAPI_STATE_NEXT_PHASE; timer_set_delay_u64(&ide_timer[atapi_dev->board], 6*IDE_TIME); + *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); } break; } From 83f286912300b9f744124ecd36df3df7e3548f0c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 May 2019 11:44:33 +0100 Subject: [PATCH 0723/1050] Don't unroll a loop if x87 top of stack is different at the start and end of the loop. Fixes Battlezone. --- src/codegen.c | 5 ++++- src/codegen.h | 2 +- src/codegen_ops_helpers.c | 9 ++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 06f6213..a84e8cf 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -22,9 +22,10 @@ static struct x86seg *op_ea_seg; uint32_t op_32; int first_uop; + int TOP; } codegen_instructions[MAX_INSTRUCTION_COUNT]; -int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction) +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) { int c; @@ -33,6 +34,7 @@ int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_inst if (codegen_instructions[c].pc == pc) { *first_instruction = c; + *TOP = codegen_instructions[c].TOP; return codegen_instructions[c].first_uop; } } @@ -590,6 +592,7 @@ generate_call: codegen_instructions[block->ins].op_ssegs = last_op_ssegs; codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; codegen_instructions[block->ins].op_32 = last_op_32; + codegen_instructions[block->ins].TOP = cpu_state.TOP; codegen_instructions[block->ins].first_uop = ir->wr_pos; codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); diff --git a/src/codegen.h b/src/codegen.h index 0f246b3..1d88e23 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -404,7 +404,7 @@ extern int codegen_in_recompile; void codegen_generate_reset(); -int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction); +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); #ifdef DEBUG_EXTRA diff --git a/src/codegen_ops_helpers.c b/src/codegen_ops_helpers.c index 903a0e5..896ac29 100644 --- a/src/codegen_ops_helpers.c +++ b/src/codegen_ops_helpers.c @@ -34,9 +34,10 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, int start; int max_unroll; int first_instruction; + int TOP = -1; /*Check that dest instruction was actually compiled into block*/ - start = codegen_get_instruction_uop(block, dest_addr, &first_instruction); + start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); /*Couldn't find any uOPs corresponding to the destination instruction*/ if (start == -1) @@ -48,8 +49,14 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, return 0; } else + { start = ir->wr_pos; + TOP = cpu_state.TOP; + } } + + if (TOP != cpu_state.TOP) + return 0; max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6); if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount)) From 451e80a333a78ae38f6eeb821cba20dfb4bf629e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 May 2019 11:45:08 +0100 Subject: [PATCH 0724/1050] Fall back to interpreter version of FADD if x87 rounding mode is not nearest. Fixes software rendering in Battlezone. --- src/codegen_ops_fpu_arith.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/codegen_ops_fpu_arith.c b/src/codegen_ops_fpu_arith.c index 3f05802..e3bfb28 100644 --- a/src/codegen_ops_fpu_arith.c +++ b/src/codegen_ops_fpu_arith.c @@ -274,6 +274,8 @@ uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint { \ x86seg *target_seg; \ \ + if ((cpu_state.npxc >> 10) & 3) \ + return 0; \ uop_FP_ENTER(ir); \ uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ op_pc--; \ From c682e070a6e3892e48e03016c2a88747abdb26f3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 May 2019 18:41:31 +0100 Subject: [PATCH 0725/1050] Fix x87 tag register when using MMX instructions. Fixes numerous issues when an MMX process is running at the same time as one or more other MMX/FPU processes (usually seen running 3dfx games with AudioPCI). --- src/x87.c | 2 +- src/x87.h | 2 +- src/x87_ops_misc.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/x87.c b/src/x87.c index 44f22e0..ac2650d 100644 --- a/src/x87.c +++ b/src/x87.c @@ -35,7 +35,7 @@ uint16_t x87_gettag() ret |= X87_TAG_EMPTY << (c * 2); else if (cpu_state.tag[c] & TAG_UINT64) ret |= 2 << (c*2); - else if (cpu_state.ST[c] == 0.0) + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) ret |= X87_TAG_ZERO << (c * 2); else ret |= X87_TAG_VALID << (c * 2); diff --git a/src/x87.h b/src/x87.h index 2ec4405..9441a41 100644 --- a/src/x87.h +++ b/src/x87.h @@ -9,7 +9,7 @@ uint16_t x87_pc_seg,x87_op_seg; static inline void x87_set_mmx() { cpu_state.TOP = 0; - *(uint64_t *)cpu_state.tag = 0; + *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; cpu_state.ismmx = 1; } diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index f22d618..0cae387 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -117,8 +117,8 @@ static int FSTOR() something like this is needed*/ 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; + !cpu_state.TOP && (*(uint64_t *)cpu_state.tag == 0x0101010101010101ull)) + cpu_state.ismmx = 1; CLOCK_CYCLES((cr0 & 1) ? 34 : 44); if (fplog) pclog("FRSTOR %08X:%08X %i %i %04X\n", easeg, cpu_state.eaaddr, cpu_state.ismmx, cpu_state.TOP, x87_gettag()); From bd8cade1fbf5ec0fa2dce17fa91ab25a0c0d1432 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 12 May 2019 17:58:37 +0100 Subject: [PATCH 0726/1050] Remove 4 MB option from Bahamas 64; this card only supports up to 2 MB. --- src/vid_s3.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index e22e6cd..a6ac6a1 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2907,11 +2907,10 @@ static device_config_t s3_bahamas64_config[] = .description = "2 MB", .value = 2 }, - { - .description = "4 MB", - .value = 4 - }, - /*Vision864 also supports 8 MB, however the Paradise BIOS is buggy (VESA modes don't work correctly)*/ + /*Vision864 also supports 4 and 8 MB, however the Paradise + BIOS is buggy (VESA modes don't work correctly), and UNIVBE and + OS/2 Warp misdetect the VRAM size. Bahamas 64 only supports + up to 2 MB on the board anyway. */ { .description = "" } From 51c4a1455ea833ac70b2a341c76dee078d9be4f8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 12 May 2019 17:59:21 +0100 Subject: [PATCH 0727/1050] Fix clock selection on S3 Vision864 w/SDAC (Bahamas 64). --- src/vid_s3.c | 6 +++++- src/vid_sdac_ramdac.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index a6ac6a1..25bcca2 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1186,6 +1186,10 @@ void s3_recalctimings(svga_t *svga) { s3_t *s3 = (s3_t *)svga->p; svga->hdisp = svga->hdisp_old; + int clk_sel = (svga->miscout >> 2) & 3; + + if (clk_sel == 3 && s3->chip == S3_VISION864) + clk_sel = svga->crtc[0x42] & 0xf; // pclog("%i %i\n", svga->hdisp, svga->hdisp_time); // pclog("recalctimings\n"); @@ -1206,7 +1210,7 @@ void s3_recalctimings(svga_t *svga) else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; svga->interlace = svga->crtc[0x42] & 0x20; - svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock((svga->miscout >> 2) & 3, s3->getclock_p); + svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock(clk_sel, s3->getclock_p); switch (svga->crtc[0x67] >> 4) { diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index 0c62f23..2ced27f 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -148,10 +148,14 @@ float sdac_getclock(int clock, void *p) sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; float t; int m, n1, n2; + + if (ramdac->regs[0xe] & (1 << 5)) + clock = ramdac->regs[0xe] & 7; + // pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]); + clock &= 7; if (clock == 0) return 25175000.0; if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ m = (ramdac->regs[clock] & 0x7f) + 2; n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; n2 = ((ramdac->regs[clock] >> 13) & 0x07); From aa933688eb13ebf0162cdd7cd224e947d959dac9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 12 May 2019 18:00:19 +0100 Subject: [PATCH 0728/1050] Fix reads of 3C6 on SDAC (Bahamas 64) when not returning command register or RAMDAC ID. --- src/vid_sdac_ramdac.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index 2ced27f..6d29120 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -96,7 +96,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 %i %i\n",addr,CS,cpu_state.pc, ramdac->rs2, ramdac->rindex, ramdac->windex); switch (addr) { @@ -105,15 +104,15 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) ramdac->magic_count++; if (ramdac->magic_count == 4) { - temp = 0x70; /*SDAC ID*/ ramdac->rs2 = 1; + return 0x70; /*SDAC ID*/ } if (ramdac->magic_count == 5) { - temp = ramdac->command; ramdac->magic_count = 0; + return ramdac->command; } - return temp; + break; case 3: ramdac->magic_count=0; break; From 388229aeb5ab286e091739338545c31912f11153 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 12 May 2019 18:00:48 +0100 Subject: [PATCH 0729/1050] Rework bit depth selection on SDAC to add a few missing cases. --- src/vid_sdac_ramdac.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index 6d29120..ba0c3ee 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -9,14 +9,31 @@ static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) { ramdac->command = val; // pclog("RAMDAC command reg now %02X\n", val); - switch (val >> 4) + switch (val & 0xf0) { - case 0x2: case 0x3: case 0xa: svga->bpp = 15; break; - case 0x4: case 0xe: svga->bpp = 24; break; - case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: svga->bpp = 32; break; - - case 0: case 1: default: svga->bpp = 8; break; + case 0x00: case 0x10: + svga->bpp = 8; + break; + + case 0x20: case 0x30: case 0x80: case 0xa0: + svga->bpp = 15; + break; + + case 0x50: case 0x60: case 0xc0: + svga->bpp = 16; + break; + + case 0x40: case 0x90: case 0xe0: + svga->bpp = 24; + break; + + case 0x70: + svga->bpp = 32; + break; + + default: + svga->bpp = 8; + break; } } From a1e2ee3218a53c9bd680a0969b2a18b27a646963 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 13 May 2019 17:49:33 +0100 Subject: [PATCH 0730/1050] Set eviction/mask entries in pages[] array for remapped pages. Fixes crashes on PS/2 and possibly some other models. --- src/mem.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mem.c b/src/mem.c index 7f1d7bd..a7545a1 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1381,10 +1381,14 @@ static void mem_remap_top(int max_size) for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - pages[c].mem = &ram[0xA0000 + ((c - ((start * 1024) >> 12)) << 12)]; + int offset = c - ((start * 1024) >> 12); + pages[c].mem = &ram[0xA0000 + (offset << 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; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; } mem_set_mem_state(start * 1024, size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); From 1f57a70a213b5083c4cc18b36bc92a071f1148c3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 13 May 2019 19:39:56 +0100 Subject: [PATCH 0731/1050] Slow down sector read/write speed on AT Fixed Disk Adapter. Fixes OS/2 v1.0 hard drive formatter. --- src/mfm_at.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mfm_at.c b/src/mfm_at.c index 83fee43..cccd1c9 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -21,6 +21,14 @@ #define IDE_TIME (TIMER_USEC*10)//(5 * 100 * (1 << TIMER_SHIFT)) +/*Rough estimate - MFM drives spin at 3600 RPM, with 17 sectors per track, + meaning (3600/60)*17 = 1020 sectors per second, or 980us per sector. + + This is required for OS/2 on slow 286 systems, as the hard drive formatter + will crash with 'internal processing error' if write sector interrupts are too + close in time*/ +#define SECTOR_TIME (TIMER_USEC * 980) + #define STAT_ERR 0x01 #define STAT_INDEX 0x02 #define STAT_CORRECTED_DATA 0x04 @@ -313,7 +321,7 @@ void mfm_writew(uint16_t port, uint16_t val, void *p) { mfm->pos = 0; mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME); + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); } } @@ -382,7 +390,7 @@ uint16_t mfm_readw(uint16_t port, void *p) { mfm_next_sector(mfm); mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 6*IDE_TIME); + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); } } } From de3bb62e0c7518d350296a58fd8e7fd0bb9ffd05 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 May 2019 20:32:32 +0100 Subject: [PATCH 0732/1050] Interpreter now updates TSC every instruction. Fixes Desert Strike. --- src/386.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/386.c b/src/386.c index 48522c9..6b0dcd0 100644 --- a/src/386.c +++ b/src/386.c @@ -165,6 +165,8 @@ void exec386(int cycs) // pclog("%i %02X\n", ins, ram[8]); while (cycdiff < cycle_period) { + int ins_cycles = cycles; + cpu_state.oldpc = cpu_state.pc; cpu_state.op32 = use32; @@ -212,6 +214,9 @@ void exec386(int cycs) } } } + ins_cycles -= cycles; + tsc += ins_cycles; + cycdiff=oldcyc-cycles; if (trap) @@ -289,7 +294,6 @@ void exec386(int cycs) } } - tsc += cycdiff; if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) timer_process(); } From 51341c5ca67b7fab18ef1ecf39d46a1fca2e8def Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 15 May 2019 19:51:57 +0100 Subject: [PATCH 0733/1050] Support CD-ROM commands with zero allocation length. Fixes 'Device failed to request command' on PB570. --- src/scsi_cd.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/scsi_cd.c b/src/scsi_cd.c index 48dbdb6..a4fe299 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -750,7 +750,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) atapi_sense_clear(data, temp_command, 0); data->bytes_expected = data->data_pos_write = MIN(alloc_length, 18); - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case SCSI_SEEK_6: if (data->cmd_pos == CMD_POS_IDLE) @@ -800,7 +800,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_pos_read = 0; data->bytes_expected = data->data_pos_write = MIN(alloc_length, 8); - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_READ_TOC_PMA_ATIP: // pclog("Read TOC ready? %08X\n",ide); @@ -831,7 +831,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) } data->data_pos_read = 0; data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_READ_CD: // pclog("Read CD : start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n",cdb[2],cdb[3],cdb[4],cdb[5],cdb[6],cdb[7],cdb[8],cdb[9]); @@ -1032,7 +1032,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[1] = data->data_in[2] = data->data_in[3] = 0; data->bytes_expected = data->data_pos_write = MIN(6, alloc_length); - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: @@ -1070,7 +1070,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->bytes_expected = data->data_pos_write = MIN(len, alloc_length); data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -1176,7 +1176,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_READ_DISC_INFORMATION: alloc_length = cdb[8] | (cdb[7] << 8); @@ -1192,7 +1192,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->bytes_expected = data->data_pos_write = MIN(alloc_length, 34); data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_PLAY_AUDIO_10: case GPCMD_PLAY_AUDIO_12: @@ -1245,7 +1245,7 @@ static int scsi_cd_command(uint8_t *cdb, void *p) if (!(cdb[2] & 0x40)) len=4; data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_START_STOP_UNIT: if (!cdb[4]) atapi->stop(); @@ -1345,7 +1345,7 @@ atapi_out: data->data_in[size_idx] = idx - preamble_len; data->bytes_expected = data->data_pos_write = MIN(alloc_length, idx); - return SCSI_PHASE_DATA_IN; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; case GPCMD_PREVENT_REMOVAL: data->cmd_pos = CMD_POS_IDLE; From 12f8751e5c40bfdfe384df8faa6a6ba50adf28df Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 May 2019 21:52:07 +0100 Subject: [PATCH 0734/1050] Fix read of Cirrus Logic cursor position registers. OS/2 Warp now detects CL cards correctly. --- src/vid_cl5429.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index c9a20d5..1098ad8 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -71,6 +71,8 @@ typedef struct gd5429_t uint32_t lfb_base; int mmio_vram_overlap; + + uint8_t sr10_read, sr11_read; } gd5429_t; static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); @@ -111,11 +113,13 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x10: case 0x30: case 0x50: case 0x70: case 0x90: case 0xb0: case 0xd0: case 0xf0: svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); + gd5429->sr10_read = svga->seqaddr & 0xe0; // pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); break; case 0x11: case 0x31: case 0x51: case 0x71: case 0x91: case 0xb1: case 0xd1: case 0xf1: svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); + gd5429->sr11_read = svga->seqaddr & 0xe0; // pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); break; case 0x12: @@ -311,6 +315,13 @@ uint8_t gd5429_in(uint16_t addr, void *p) switch (addr) { + case 0x3c4: + if ((svga->seqaddr & 0x1f) == 0x10) + return (svga->seqaddr & 0x1f) | gd5429->sr10_read; + if ((svga->seqaddr & 0x1f) == 0x11) + return (svga->seqaddr & 0x1f) | gd5429->sr11_read; + return svga->seqaddr & 0x1f; + case 0x3c5: if (svga->seqaddr > 5) { From e2c7bf02abfcd860480e0575b3201b892a9a75e8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 May 2019 22:05:18 +0100 Subject: [PATCH 0735/1050] Add support for 64x64 cursors to Cirrus Logic cards (used by OS/2 Warp). --- src/vid_cl5429.c | 69 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 1098ad8..43d4573 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -126,10 +126,17 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = val & 1; svga->hwcursor.ysize = (val & 4) ? 64 : 32; svga->hwcursor.yoff = 0; + if (svga->hwcursor.ysize == 64) + svga->hwcursor.addr = (0x3fc000 + ((svga->seqregs[0x13] & 0x3c) * 256)) & svga->vram_mask; + else + svga->hwcursor.addr = (0x3fc000 + ((svga->seqregs[0x13] & 0x3f) * 256)) & svga->vram_mask; // pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); break; case 0x13: - svga->hwcursor.addr = (0x3fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; + if (svga->hwcursor.ysize == 64) + svga->hwcursor.addr = (0x3fc000 + ((val & 0x3c) * 256)) & svga->vram_mask; + else + svga->hwcursor.addr = (0x3fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; // pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); break; @@ -577,33 +584,61 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) uint8_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int line_offset = (svga->seqregs[0x12] & 0x04) ? 16 : 4; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += line_offset; - for (x = 0; x < 32; x += 8) + if (svga->seqregs[0x12] & 0x04) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) + for (x = 0; x < 64; x += 8) { - if (offset >= svga->hwcursor_latch.x) + dat[0] = svga->vram[svga->hwcursor_latch.addr]; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 8]; + for (xx = 0; xx < 8; xx++) { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + if (offset >= svga->hwcursor_latch.x) + { + if (dat[1] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; + if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + } + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; + svga->hwcursor_latch.addr++; + } + svga->hwcursor_latch.addr += 8; + } + else + { + for (x = 0; x < 32; x += 8) + { + dat[0] = svga->vram[svga->hwcursor_latch.addr]; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; + for (xx = 0; xx < 8; xx++) + { + if (offset >= svga->hwcursor_latch.x) + { + if (dat[1] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; + if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + } + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr++; } - svga->hwcursor_latch.addr++; } if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += line_offset; } From c39dc641a6b86ab9c851dd16ecf59fef3fa23aa0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 May 2019 22:07:57 +0100 Subject: [PATCH 0736/1050] Reset Cirrus Logic hidden DAC counter on accesses to 3c7/3c8/3c9. --- src/vid_cl5429.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 43d4573..3a863e5 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -161,7 +161,10 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) } gd5429->dac_3c6_count = 0; break; - + case 0x3c7: case 0x3c8: case 0x3c9: + gd5429->dac_3c6_count = 0; + break; + case 0x3cf: // pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); if (svga->gdcaddr == 0) @@ -373,6 +376,9 @@ uint8_t gd5429_in(uint16_t addr, void *p) } gd5429->dac_3c6_count++; break; + case 0x3c7: case 0x3c8: case 0x3c9: + gd5429->dac_3c6_count = 0; + break; case 0x3cf: if (svga->gdcaddr > 8) From a9509e04eed8c592b051dee45202bf4348a8f14d Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 17:03:38 +0100 Subject: [PATCH 0737/1050] Cirrus GD5429 doesn't support PCI, so don't look at the PCI command register when updating mappings. Fixes GD5429 on PCI systems. --- src/vid_cl5429.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 3a863e5..6d62d43 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -437,7 +437,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) { svga_t *svga = &gd5429->svga; - if (PCI && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + if (PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd5429->linear_mapping); From 4b061cdcf4ffb7fe195969ca14ee4639afe99a5a Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 17:04:01 +0100 Subject: [PATCH 0738/1050] Fixed typo when reading SR[17] on Cirrus Logic cards. --- src/vid_cl5429.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 6d62d43..081dc46 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -343,7 +343,7 @@ uint8_t gd5429_in(uint16_t addr, void *p) return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; case 0x17: - temp = svga->gdcreg[0x17]; + temp = svga->seqregs[0x17]; temp &= ~(7 << 3); if (gd5429->type == CL_TYPE_GD5429) { From a4b33a6353cbd2f001e55bf0bf59e2ecc7d5fb03 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 17:40:12 +0100 Subject: [PATCH 0739/1050] Correct memory limits on Socket 7 boards. 430VX boards support 8-128 MB. While the 430HX chipset supports up to 512 MB, the real ASUS P55T2P4 only supports up to 256 MB. --- src/model.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/model.c b/src/model.c index 84ca918..b2492f5 100644 --- a/src/model.c +++ b/src/model.c @@ -210,10 +210,10 @@ MODEL models[] = {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, - {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55tvp4_init, NULL}, - {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_p55t2p4_init, NULL}, - {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, - {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 256, 1, at_p55va_init, NULL}, + {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}, + {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 1, at_p55t2p4_init, NULL}, + {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, + {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55va_init, NULL}, {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, From e6df3901d944e7cc1855a3fd6628129dff82539f Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 17:40:54 +0100 Subject: [PATCH 0740/1050] Rename Award 430VX PCI to Shuttle HOT-557. --- src/model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index b2492f5..7d58ec2 100644 --- a/src/model.c +++ b/src/model.c @@ -212,8 +212,8 @@ MODEL models[] = {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}, {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 1, at_p55t2p4_init, NULL}, - {"[Socket 7] Award 430VX PCI", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55va_init, NULL}, + {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, From 60058283ebaa0e92de398602a110eb9391df7185 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 20:15:09 +0100 Subject: [PATCH 0741/1050] Disable FDC when enabling W83877TF config registers at 0x3f0, to prevent bus conflicts. Fixes duplicate FDC/COM/LPT ports on VA-503+. --- src/w83877tf.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/w83877tf.c b/src/w83877tf.c index 78c2a63..17e80f1 100644 --- a/src/w83877tf.c +++ b/src/w83877tf.c @@ -138,12 +138,21 @@ static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p) { case 0x3f0: /*Enable/index register*/ if (val == 0xaa) + { + fdc_remove(); + if (w83877tf->enable_regs && w83877tf->regs[0x20] >= 0x40) + fdc_add(); w83877tf->enable_regs = 0; + } else if (!w83877tf->enable_regs) { w83877tf->key[1] = w83877tf->key[0]; w83877tf->key[0] = val; w83877tf->enable_regs = (w83877tf->key[0] == 0x87 && w83877tf->key[1] == 0x87); + /*The FDC conflicts with the 3fx config registers, so disable + it when enabling config registers*/ + if (w83877tf->enable_regs) + fdc_remove(); } else w83877tf->index = val; From 08b019eb8545f55584ccf26cef31293a6fe166af Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 20:15:56 +0100 Subject: [PATCH 0742/1050] ASUS Socket 7 boards use W83877F for SuperIO. --- src/model.c | 6 +++--- src/w83877tf.c | 55 ++++++++++++++++++++++++++++++++++++++++++++------ src/w83877tf.h | 3 ++- 3 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/model.c b/src/model.c index 7d58ec2..900b7f8 100644 --- a/src/model.c +++ b/src/model.c @@ -730,7 +730,7 @@ void at_p55tvp4_init() pci_slot(0x09); i430vx_init(); piix_init(7, 0x0C, 0x0B, 0x0A, 0x09); - um8669f_init(); + w83877f_init(0x3f0, 0x87); device_add(&intel_flash_bxt_device); } @@ -758,7 +758,7 @@ void at_p55t2p4_init() pci_slot(0x09); i430hx_init(); piix_init(7, 0x0C, 0x0B, 0x0A, 0x09); - um8669f_init(); + w83877f_init(0x3f0, 0x87); device_add(&intel_flash_bxt_device); } @@ -771,7 +771,7 @@ void at_mvp3_init() pci_slot(10); mvp3_init(); vt82c586b_init(7, 8, 9, 10, 0); - w83877tf_init(); + w83877tf_init(0x250, 0x89); device_add(&sst_39sf010_device); } diff --git a/src/w83877tf.c b/src/w83877tf.c index 17e80f1..524510e 100644 --- a/src/w83877tf.c +++ b/src/w83877tf.c @@ -6,12 +6,20 @@ #include "serial.h" #include "w83877tf.h" +enum +{ + CHIP_W83877F, + CHIP_W83877TF +}; + typedef struct w83877tf_t { int enable_regs; uint8_t key[2]; + uint8_t unlock_key; int index; uint8_t regs[256]; + int chip; } w83877tf_t; static w83877tf_t w83877tf_global; @@ -26,6 +34,13 @@ static void w83877tf_write_reg(w83877tf_t *w83877tf, int index, uint8_t val) // pclog("w83877tf_write: index=%02x val=%02x\n", index, val); switch (index) { + case 0x0c: + if (w83877tf->regs[0x16] & 1) + w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x87 : 0x86; + else + w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x89 : 0x88; + break; + case 0x16: if (val == 2) /*Written by VA-503+ BIOS. Apparently should not change IO mapping*/ return; @@ -33,9 +48,15 @@ static void w83877tf_write_reg(w83877tf_t *w83877tf, int index, uint8_t val) io_removehandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); io_removehandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); if (val & 0x01) + { io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); + w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x87 : 0x86; + } else + { io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x89 : 0x88; + } if ((w83877tf->regs[0x16] & 4) && !(val & 4)) { @@ -81,7 +102,14 @@ static uint8_t w83877tf_read_reg(w83877tf_t *w83877tf, int index) switch (w83877tf->index) { case 0x09: - return 0x0c; /*W83877TF ID*/ + switch (w83877tf->chip) + { + case CHIP_W83877F: + return 0x0a; /*W83877F ID*/ + case CHIP_W83877TF: + return 0x0c; /*W83877TF ID*/ + } + break; } return w83877tf->regs[index]; } @@ -95,7 +123,7 @@ static void w83877tf_write_25x(uint16_t port, uint8_t val, void *p) switch (port) { case 0x250: /*Enable register*/ - w83877tf->enable_regs = (val == 0x89) ? 1 : 0; + w83877tf->enable_regs = (val == w83877tf->unlock_key) ? 1 : 0; break; case 0x251: /*Index*/ if (w83877tf->enable_regs) @@ -148,7 +176,7 @@ static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p) { w83877tf->key[1] = w83877tf->key[0]; w83877tf->key[0] = val; - w83877tf->enable_regs = (w83877tf->key[0] == 0x87 && w83877tf->key[1] == 0x87); + w83877tf->enable_regs = (w83877tf->key[0] == w83877tf->unlock_key && w83877tf->key[1] == w83877tf->unlock_key); /*The FDC conflicts with the 3fx config registers, so disable it when enabling config registers*/ if (w83877tf->enable_regs) @@ -187,12 +215,15 @@ static uint8_t w83877tf_read_3fx(uint16_t port, void *p) return ret; } -void w83877tf_init() +static void w83877_common_init(int chip, uint16_t base, uint8_t key) { memset(&w83877tf_global, 0, sizeof(w83877tf_t)); - io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); - + if (base == 0x250) + io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + else + io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); + /*Defaults*/ w83877tf_global.regs[0x03] = 0x30; w83877tf_global.regs[0x09] = 0x0c; @@ -208,4 +239,16 @@ void w83877tf_init() w83877tf_global.regs[0x27] = 0x05; w83877tf_global.regs[0x28] = 0x43; w83877tf_global.regs[0x29] = 0x60; + + w83877tf_global.chip = chip; + w83877tf_global.unlock_key = key; +} + +void w83877f_init(uint16_t base, uint8_t key) +{ + w83877_common_init(CHIP_W83877F, base, key); +} +void w83877tf_init(uint16_t base, uint8_t key) +{ + w83877_common_init(CHIP_W83877TF, base, key); } diff --git a/src/w83877tf.h b/src/w83877tf.h index dcfb853..6371497 100644 --- a/src/w83877tf.h +++ b/src/w83877tf.h @@ -1 +1,2 @@ -void w83877tf_init(); +void w83877f_init(uint16_t base, uint8_t key); +void w83877tf_init(uint16_t base, uint8_t key); From 846103d310951f9b7b763297684fb777f2e40a52 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 20:16:10 +0100 Subject: [PATCH 0743/1050] Remove some dead comments from ibm.h. --- src/ibm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 8bc82ea..4212fad 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -169,8 +169,8 @@ extern int AMSTRAD, AT, is386, PCI, TANDY; enum { - ROM_IBMPC = 0, /*301 keyboard error, 131 cassette (!!!) error*/ - ROM_IBMXT, /*301 keyboard error*/ + ROM_IBMPC = 0, + ROM_IBMXT, ROM_IBMPCJR, ROM_GENXT, /*'Generic XT BIOS'*/ ROM_DTKXT, From 0b57135b3cff2c94a81bad69a0a073df9d5bb4be Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 21:31:57 +0100 Subject: [PATCH 0744/1050] Add FDC37C932FR SuperIO for Epox P55-VA. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/fdc37c93x.c | 253 +++++++++++++++++++++++++++++ src/fdc37c93x.h | 1 + src/model.c | 3 +- 6 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 src/fdc37c93x.c create mode 100644 src/fdc37c93x.h diff --git a/src/Makefile.am b/src/Makefile.am index 993e6c0..3a83dae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,7 +32,7 @@ codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_o codegen_ops_logic.c codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c \ codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ -disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ +disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c lpt_dss.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 63ba36c..3f8ce14 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -17,7 +17,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ - dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o \ + dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index b0e5509..a0e2415 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -17,7 +17,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ - dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdd.o \ + dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.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 \ diff --git a/src/fdc37c93x.c b/src/fdc37c93x.c new file mode 100644 index 0000000..890d95d --- /dev/null +++ b/src/fdc37c93x.c @@ -0,0 +1,253 @@ +#include "ibm.h" + +#include "fdc.h" +#include "fdd.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "fdc37c93x.h" + +typedef struct fdc37c93x_t +{ + int index; + + uint8_t global_regs[0x30]; + uint8_t fdc_regs[0x100]; + uint8_t ide1_regs[0x100]; + uint8_t ide2_regs[0x100]; + uint8_t lpt_regs[0x100]; + uint8_t com1_regs[0x100]; + uint8_t com2_regs[0x100]; + uint8_t rtc_regs[0x100]; + uint8_t kbd_regs[0x100]; + uint8_t auxio_regs[0x100]; + uint8_t accessbus_regs[0x100]; + + uint8_t lock[2]; +} fdc37c93x_t; + +static fdc37c93x_t fdc37c93x_global; + +static void write_lock(fdc37c93x_t *fdc37c93x, uint8_t val) +{ + if (val == 0x55 && fdc37c93x->lock[1] == 0x55) + fdc_3f1_enable(0); + if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55 && val != 0x55) + fdc_3f1_enable(1); + + fdc37c93x->lock[0] = fdc37c93x->lock[1]; + fdc37c93x->lock[1] = val; +} + +void fdc37c93x_write(uint16_t port, uint8_t val, void *p) +{ + fdc37c93x_t *fdc37c93x = (fdc37c93x_t *)p; + +// pclog("Write SuperIO %04x %02x\n", port, val); + if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55) + { + if (port == 0x3f0) + { + if (val == 0xaa) + write_lock(fdc37c93x, val); + else + fdc37c93x->index = val; + } + else + { + uint16_t addr; + int irq; + +// pclog("fdc37c93x_write: index=%02x dev=%i val=%02x\n", fdc37c93x->index, fdc37c93x->global_regs[7], val); + if (fdc37c93x->index < 0x30) + { + if (fdc37c93x->index != 0x20 && fdc37c93x->index != 0x21) + fdc37c93x->global_regs[fdc37c93x->index] = val; + } + else switch (fdc37c93x->global_regs[7]) + { + case 0: + fdc37c93x->fdc_regs[fdc37c93x->index] = val; + break; + case 1: + fdc37c93x->ide1_regs[fdc37c93x->index] = val; + break; + case 2: + fdc37c93x->ide2_regs[fdc37c93x->index] = val; + break; + case 3: + fdc37c93x->lpt_regs[fdc37c93x->index] = val; + break; + case 4: + fdc37c93x->com1_regs[fdc37c93x->index] = val; + break; + case 5: + fdc37c93x->com2_regs[fdc37c93x->index] = val; + break; + case 6: + fdc37c93x->rtc_regs[fdc37c93x->index] = val; + break; + case 7: + fdc37c93x->kbd_regs[fdc37c93x->index] = val; + break; + case 8: + fdc37c93x->auxio_regs[fdc37c93x->index] = val; + break; + case 9: + fdc37c93x->accessbus_regs[fdc37c93x->index] = val; + break; + } + + fdc_remove(); + if ((fdc37c93x->global_regs[0x22] & 0x01) && (fdc37c93x->fdc_regs[0x30] & 0x01)) + { +// pclog("FDC enabled\n"); + fdc_add(); + } +/* else + pclog("FDC disabled\n");*/ + + lpt1_remove(); + lpt2_remove(); + addr = (fdc37c93x->lpt_regs[0x61] & 0xfc) | ((fdc37c93x->lpt_regs[0x60] & 3) << 8); + if ((fdc37c93x->global_regs[0x22] & (1 << 3)) && (fdc37c93x->lpt_regs[0x30] & 0x01)) + { +// pclog("LPT addr = %04x\n", addr); + lpt1_init(addr); + } +/* else + pclog("LPT disabled\n");*/ + + serial1_remove(); + addr = (fdc37c93x->com1_regs[0x61] & 0xf8) | ((fdc37c93x->com1_regs[0x60] & 3) << 8); + irq = fdc37c93x->com1_regs[0x70] & 0xf; + if ((fdc37c93x->global_regs[0x22] & (1 << 4)) && (fdc37c93x->com1_regs[0x30] & 0x01)) + { +// pclog("COM1 addr = %04x, IRQ = %i\n", addr, irq); + serial1_set(addr, irq); + } +/* else + pclog("COM1 disabled\n");*/ + + serial2_remove(); + addr = (fdc37c93x->com2_regs[0x61] & 0xf8) | ((fdc37c93x->com2_regs[0x60] & 3) << 8); + irq = fdc37c93x->com2_regs[0x70] & 0xf; + if ((fdc37c93x->global_regs[0x22] & (1 << 5)) && (fdc37c93x->com2_regs[0x30] & 0x01)) + { +// pclog("COM2 addr = %04x, IRQ = %i\n", addr, irq); + serial2_set(addr, irq); + } +/* else + pclog("COM2 disabled\n");*/ + + + fdc_update_enh_mode(fdc37c93x->fdc_regs[0xf0] & 1); + + fdc_update_densel_force((fdc37c93x->fdc_regs[0xf1] & 0x0c) >> 2); + fdd_swap = (fdc37c93x->fdc_regs[0xf0] & (1 << 4)) ? 1 : 0; + } + } + else + { + if (port == 0x3f0) + write_lock(fdc37c93x, val); + } +} + +uint8_t fdc37c93x_read(uint16_t port, void *p) +{ + fdc37c93x_t *fdc37c93x = (fdc37c93x_t *)p; + +// pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); + if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55) + { + if (port == 0x3f1) + { + if (fdc37c93x->index < 0x30) + return fdc37c93x->global_regs[fdc37c93x->index]; + else switch (fdc37c93x->global_regs[7]) + { + case 0: + return fdc37c93x->fdc_regs[fdc37c93x->index]; + case 1: + return fdc37c93x->ide1_regs[fdc37c93x->index]; + case 2: + return fdc37c93x->ide2_regs[fdc37c93x->index]; + case 3: + return fdc37c93x->lpt_regs[fdc37c93x->index]; + case 4: + return fdc37c93x->com1_regs[fdc37c93x->index]; + case 5: + return fdc37c93x->com2_regs[fdc37c93x->index]; + case 6: + return fdc37c93x->rtc_regs[fdc37c93x->index]; + case 7: + return fdc37c93x->kbd_regs[fdc37c93x->index]; + case 8: + return fdc37c93x->auxio_regs[fdc37c93x->index]; + case 9: + return fdc37c93x->accessbus_regs[fdc37c93x->index]; + } + } + } + return 0xff; +} + +void fdc37c932fr_init() +{ + fdc37c93x_t *fdc37c93x = &fdc37c93x_global; + int c; + + io_sethandler(0x03f0, 0x0002, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, fdc37c93x); + + fdc_update_is_nsc(0); + + memset(&fdc37c93x_global, 0, sizeof(fdc37c93x_global)); + + fdc37c93x->global_regs[0x03] = 0x03; + fdc37c93x->global_regs[0x20] = 0x03; + fdc37c93x->global_regs[0x21] = 0x01; + fdc37c93x->global_regs[0x24] = 0x04; + fdc37c93x->global_regs[0x26] = 0xf0; + fdc37c93x->global_regs[0x27] = 0x03; + + fdc37c93x->fdc_regs[0x60] = 0x03; + fdc37c93x->fdc_regs[0x61] = 0xf0; + fdc37c93x->fdc_regs[0x70] = 0x06; + fdc37c93x->fdc_regs[0x74] = 0x02; + fdc37c93x->fdc_regs[0xf0] = 0x0e; + fdc37c93x->fdc_regs[0xf2] = 0xff; + + fdc37c93x->ide1_regs[0x60] = 0x01; + fdc37c93x->ide1_regs[0x61] = 0xf0; + fdc37c93x->ide1_regs[0x62] = 0x03; + fdc37c93x->ide1_regs[0x63] = 0xf6; + fdc37c93x->ide1_regs[0x70] = 0x0e; + fdc37c93x->ide1_regs[0xf0] = 0x0c; + fdc37c93x->ide1_regs[0xf1] = 0x0d; + + fdc37c93x->lpt_regs[0x74] = 0x04; + fdc37c93x->lpt_regs[0xf0] = 0x3c; + + fdc37c93x->com2_regs[0x74] = 0x04; + fdc37c93x->com2_regs[0xf1] = 0x02; + fdc37c93x->com2_regs[0xf2] = 0x03; + + fdc37c93x->rtc_regs[0x63] = 0x70; + fdc37c93x->rtc_regs[0xf4] = 0x03; + + fdc37c93x->auxio_regs[0xb1] = 0x80; + fdc37c93x->auxio_regs[0xc0] = 0x01; + fdc37c93x->auxio_regs[0xc1] = 0x01; + fdc37c93x->auxio_regs[0xc5] = 0x01; + fdc37c93x->auxio_regs[0xc6] = 0x01; + fdc37c93x->auxio_regs[0xc7] = 0x01; + fdc37c93x->auxio_regs[0xc8] = 0x01; + fdc37c93x->auxio_regs[0xc9] = 0x80; + for (c = 0xcb; c < 0xee; c++) + fdc37c93x->auxio_regs[c] = 0x01; + + fdc_update_densel_polarity(1); + fdc_update_densel_force(0); + fdd_swap = 0; +} diff --git a/src/fdc37c93x.h b/src/fdc37c93x.h new file mode 100644 index 0000000..e661c3d --- /dev/null +++ b/src/fdc37c93x.h @@ -0,0 +1 @@ +extern void fdc37c932fr_init(); diff --git a/src/model.c b/src/model.c index 900b7f8..d9f0c06 100644 --- a/src/model.c +++ b/src/model.c @@ -20,6 +20,7 @@ #include "dma.h" #include "fdc.h" #include "fdc37c665.h" +#include "fdc37c93x.h" #include "gameport.h" #include "headland.h" #include "i430fx.h" @@ -716,7 +717,7 @@ void at_p55va_init() pci_slot(0x0B); i430vx_init(); piix_init(7, 0x08, 0x09, 0x0A, 0x0B); - um8669f_init(); + fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } From b84fefacb77f14b2ae35eebea9b572b7a0102a5a Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 May 2019 21:32:07 +0100 Subject: [PATCH 0745/1050] Add K6 CPUs to Socket 7 motherboards. --- src/model.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/model.c b/src/model.c index d9f0c06..a7551eb 100644 --- a/src/model.c +++ b/src/model.c @@ -211,10 +211,10 @@ MODEL models[] = {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, - {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}, - {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 1, at_p55t2p4_init, NULL}, - {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55va_init, NULL}, - {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, + {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}, + {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 1, at_p55t2p4_init, NULL}, + {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55va_init, NULL}, + {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, From cb6422b32458b5effac3a3ee5aec7f8177fe3b01 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 May 2019 14:05:30 +0100 Subject: [PATCH 0746/1050] MMX fixes : - Initialise x87 tags correctly in recompiler - EMMS/FEMMS now respect cr0 TS bit - FRSTOR now doesn't force all non-uint64 tags to valid Fixes Heaven 7 with AudioPCI --- src/codegen_backend_arm64_uops.c | 5 +++-- src/codegen_backend_arm_uops.c | 3 ++- src/codegen_backend_x86-64_uops.c | 4 ++-- src/codegen_backend_x86_uops.c | 4 ++-- src/x86_ops_3dnow.h | 2 +- src/x86_ops_mmx.h | 2 +- src/x87_ops.h | 2 +- 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 0cad9bb..73623f0 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -839,8 +839,9 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); - host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_TEMP, 0x01010101); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 12c2eb9..19706cd 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -910,9 +910,10 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + host_arm_MOV_IMM(block, REG_TEMP, 0); host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 729e4fd..596f262 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -826,8 +826,8 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_x86_CALL(block, x86_int); host_x86_JMP(block, codegen_exit_rout); *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 8690266..0acf07c 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -827,8 +827,8 @@ static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_x86_CALL(block, x86_int); host_x86_JMP(block, codegen_exit_rout); *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); diff --git a/src/x86_ops_3dnow.h b/src/x86_ops_3dnow.h index 9f852d5..3ac36cb 100644 --- a/src/x86_ops_3dnow.h +++ b/src/x86_ops_3dnow.h @@ -20,7 +20,7 @@ static int opPREFETCH_a32(uint32_t fetchdat) static int opFEMMS(uint32_t fetchdat) { ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); - if (cr0 & 4) + if (cr0 & 0xc) { x86_int(7); return 1; diff --git a/src/x86_ops_mmx.h b/src/x86_ops_mmx.h index 95ed658..712d185 100644 --- a/src/x86_ops_mmx.h +++ b/src/x86_ops_mmx.h @@ -38,7 +38,7 @@ static int opEMMS(uint32_t fetchdat) x86illegal(); return 1; } - if (cr0 & 4) + if (cr0 & 0xc) { x86_int(7); return 1; diff --git a/src/x87_ops.h b/src/x87_ops.h index 315c17d..2ccd7b8 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -187,7 +187,7 @@ static inline void x87_ld_frstor(int reg) } else { - cpu_state.tag[reg] = TAG_VALID; + cpu_state.tag[reg] &= ~TAG_UINT64; cpu_state.ST[reg] = x87_ld80(); } } From b16e3d84bd7afb8cb93a405fe82f449c87230ae4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 May 2019 14:51:14 +0100 Subject: [PATCH 0747/1050] Fix issues accessing W83877* config registers. Fixes floppy drives on ASUS and FIC boards. --- src/w83877tf.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/w83877tf.c b/src/w83877tf.c index 524510e..70d6ff2 100644 --- a/src/w83877tf.c +++ b/src/w83877tf.c @@ -36,9 +36,9 @@ static void w83877tf_write_reg(w83877tf_t *w83877tf, int index, uint8_t val) { case 0x0c: if (w83877tf->regs[0x16] & 1) - w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x87 : 0x86; + w83877tf->unlock_key = (val & (1 << 5)) ? 0x87 : 0x86; else - w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x89 : 0x88; + w83877tf->unlock_key = (val & (1 << 5)) ? 0x89 : 0x88; break; case 0x16: @@ -228,9 +228,15 @@ static void w83877_common_init(int chip, uint16_t base, uint8_t key) w83877tf_global.regs[0x03] = 0x30; w83877tf_global.regs[0x09] = 0x0c; w83877tf_global.regs[0x0b] = 0x0c; - w83877tf_global.regs[0x0c] = 0x28; + if (key == 0x88 || key == 0x86) + w83877tf_global.regs[0x0c] = 0x08; + else + w83877tf_global.regs[0x0c] = 0x28; w83877tf_global.regs[0x0d] = 0xa3; - w83877tf_global.regs[0x16] = 0x04; + if (base == 0x250) + w83877tf_global.regs[0x16] = 0x04; + else + w83877tf_global.regs[0x16] = 0x05; w83877tf_global.regs[0x20] = 0xfc; w83877tf_global.regs[0x23] = 0xde; w83877tf_global.regs[0x24] = 0xfe; From 8b46bbe1af056c0d2944f2e8e05d6eff2302146c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 May 2019 15:48:43 +0100 Subject: [PATCH 0748/1050] Better FDC enabling/disabling on W83877*. Fixes floppy drive on FIC VA-503+ in Windows 9x. --- src/w83877tf.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/w83877tf.c b/src/w83877tf.c index 70d6ff2..6d86ad6 100644 --- a/src/w83877tf.c +++ b/src/w83877tf.c @@ -167,9 +167,7 @@ static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p) case 0x3f0: /*Enable/index register*/ if (val == 0xaa) { - fdc_remove(); - if (w83877tf->enable_regs && w83877tf->regs[0x20] >= 0x40) - fdc_add(); + fdc_3f1_enable(1); w83877tf->enable_regs = 0; } else if (!w83877tf->enable_regs) @@ -180,7 +178,7 @@ static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p) /*The FDC conflicts with the 3fx config registers, so disable it when enabling config registers*/ if (w83877tf->enable_regs) - fdc_remove(); + fdc_3f1_enable(0); } else w83877tf->index = val; From 1dd8cf1e81e9df0fe90861aff6f8bbbb59e7e84e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 May 2019 17:35:32 +0100 Subject: [PATCH 0749/1050] Move port 0xcf9 handling from i430FX/VX to PIIX, adding reset callback for FX/HX/VX northbridges. Add IDE reset to port 0xcf9. Reset IDE error register on reset of non-existent devices. Fixes IDE related issues on soft reset for ASUS boards. --- src/i430fx.c | 24 +++++------------------- src/i430fx.h | 1 + src/i430hx.c | 5 +++++ src/i430hx.h | 1 + src/i430lx.c | 4 +++- src/i430vx.c | 5 +++++ src/i430vx.h | 1 + src/ide.c | 26 ++++++++++++++++++++++++++ src/ide.h | 1 + src/model.c | 14 +++++++------- src/piix.c | 29 ++++++++++++++++++++++++++++- src/piix.h | 2 +- 12 files changed, 84 insertions(+), 29 deletions(-) diff --git a/src/i430fx.c b/src/i430fx.c index 4d328b2..a562447 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -119,23 +119,6 @@ uint8_t i430fx_read(int func, int addr, void *priv) return card_i430fx[addr]; } -static uint8_t trc = 0; - -void i430fx_trc_write(uint16_t port, uint8_t val, void *p) -{ - 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*/ - keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ - } - resetx86(); - } - - trc = val; -} - void i430fx_init() { pci_add_specific(0, i430fx_read, i430fx_write, NULL); @@ -158,6 +141,9 @@ void i430fx_init() card_i430fx[0x72] = 0x02; // card_i430fx[0x74] = 0x0e; // card_i430fx[0x78] = 0x23; - - io_sethandler(0x0cf9, 0x0001, NULL, NULL, NULL, i430fx_trc_write, NULL, NULL, NULL); +} + +void i430fx_reset() +{ + i430fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ } diff --git a/src/i430fx.h b/src/i430fx.h index fff11d2..0265f27 100644 --- a/src/i430fx.h +++ b/src/i430fx.h @@ -1 +1,2 @@ void i430fx_init(); +void i430fx_reset(); diff --git a/src/i430hx.c b/src/i430hx.c index d7133f5..0871ca9 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -142,3 +142,8 @@ void i430hx_init() card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02; card_i430hx[0x68] = 0x11; } + +void i430hx_reset() +{ + i430hx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ +} diff --git a/src/i430hx.h b/src/i430hx.h index 5a5a7b4..30a6685 100644 --- a/src/i430hx.h +++ b/src/i430hx.h @@ -1 +1,2 @@ void i430hx_init(); +void i430hx_reset(); diff --git a/src/i430lx.c b/src/i430lx.c index 17ef4a9..d051e96 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -1,6 +1,7 @@ #include #include "ibm.h" +#include "ide.h" #include "io.h" #include "keyboard_at.h" #include "mem.h" @@ -134,10 +135,11 @@ void i430lx_trc_write(uint16_t port, uint8_t val, void *p) { i430lx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ + ide_reset_devices(); } resetx86(); } - + trc = val; } diff --git a/src/i430vx.c b/src/i430vx.c index 79b7517..5d97d23 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -142,3 +142,8 @@ void i430vx_init() card_i430vx[0x74] = 0x0e; card_i430vx[0x78] = 0x23; } + +void i430vx_reset() +{ + i430vx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ +} diff --git a/src/i430vx.h b/src/i430vx.h index 22bde47..25cda4a 100644 --- a/src/i430vx.h +++ b/src/i430vx.h @@ -1 +1,2 @@ void i430vx_init(); +void i430vx_reset(); diff --git a/src/ide.c b/src/ide.c index 4e8d5ef..552aa16 100644 --- a/src/ide.c +++ b/src/ide.c @@ -824,6 +824,7 @@ void callbackide(int ide_board) if (ide->type == IDE_NONE) { ide->cylinder=0xFFFF; + ide->error = 0xff; atapi->stop(); } if (IDE_DRIVE_IS_CDROM(ide_other)) @@ -835,6 +836,7 @@ void callbackide(int ide_board) if (ide_other->type == IDE_NONE) { ide_other->cylinder=0xFFFF; + ide_other->error = 0xff; atapi->stop(); } // pclog("Reset callback\n"); @@ -1281,6 +1283,30 @@ void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, v ide_bus_master_p = p; } +void ide_reset_devices() +{ + if (ide_drives[0].type != IDE_NONE || ide_drives[1].type != IDE_NONE) + { + timer_set_delay_u64(&ide_timer[0], 500*IDE_TIME); + ide_drives[0].reset = ide_drives[1].reset = 1; + ide_drives[0].atastat = ide_drives[1].atastat = BUSY_STAT; + if (ide_drives[0].type != IDE_NONE) + cur_ide[0] = 0; + else + cur_ide[0] = 1; + } + if (ide_drives[2].type != IDE_NONE || ide_drives[3].type != IDE_NONE) + { + timer_set_delay_u64(&ide_timer[1], 500*IDE_TIME); + ide_drives[2].reset = ide_drives[3].reset = 1; + ide_drives[2].atastat = ide_drives[3].atastat = BUSY_STAT; + if (ide_drives[2].type != IDE_NONE) + cur_ide[1] = 2; + else + cur_ide[1] = 3; + } +} + device_t ide_device = { "Standard IDE", diff --git a/src/ide.h b/src/ide.h index 0c2ce0b..2ce681a 100644 --- a/src/ide.h +++ b/src/ide.h @@ -18,6 +18,7 @@ extern void ide_pri_disable(); extern void ide_sec_disable(); extern void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), int (*write_data)(int channel, uint8_t *data, int size, void *p), void (*set_irq)(int channel, void *p), void *p); void ide_irq_raise(struct IDE *ide); +void ide_reset_devices(); extern int (*ide_bus_master_read_data)(int channel, uint8_t *data, int size, void *p); extern int (*ide_bus_master_write_data)(int channel, uint8_t *data, int size, void *p); diff --git a/src/model.c b/src/model.c index a7551eb..33b65c1 100644 --- a/src/model.c +++ b/src/model.c @@ -675,7 +675,7 @@ void at_endeavor_init() pci_slot(0xf); pci_slot(0x10); i430fx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0xd, 0xe, 0xf, 0x10, i430fx_reset); pc87306_init(0x2e); intel_endeavor_init(); device_add(&intel_flash_bxt_ami_device); @@ -687,7 +687,7 @@ void at_pb570_init() pci_slot(0x11); pci_slot(0x13); i430fx_init(); - piix_init(7, 0x11, 0x13, 0xb, 0x8); + piix_init(7, 0x11, 0x13, 0xb, 0x8, i430fx_reset); pc87306_init(0x2e); intel_endeavor_init(); device_add(&intel_flash_bxt_ami_device); @@ -701,7 +701,7 @@ void at_zappa_init() pci_slot(0xf); pci_slot(0x10); i430fx_init(); - piix_init(7, 0xd, 0xf, 0xe, 0x10); + piix_init(7, 0xd, 0xf, 0xe, 0x10, i430fx_reset); pc87306_init(0x2e); intel_zappa_init(); device_add(&intel_flash_bxt_ami_device); @@ -716,7 +716,7 @@ void at_p55va_init() pci_slot(0x0A); pci_slot(0x0B); i430vx_init(); - piix_init(7, 0x08, 0x09, 0x0A, 0x0B); + piix_init(7, 0x08, 0x09, 0x0A, 0x0B, i430vx_reset); fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } @@ -730,7 +730,7 @@ void at_p55tvp4_init() pci_slot(0x0A); pci_slot(0x09); i430vx_init(); - piix_init(7, 0x0C, 0x0B, 0x0A, 0x09); + piix_init(7, 0x0C, 0x0B, 0x0A, 0x09, i430vx_reset); w83877f_init(0x3f0, 0x87); device_add(&intel_flash_bxt_device); } @@ -744,7 +744,7 @@ void at_i430vx_init() pci_slot(0x13); pci_slot(0x14); i430vx_init(); - piix_init(7, 18, 17, 20, 19); + piix_init(7, 18, 17, 20, 19, i430vx_reset); um8669f_init(); device_add(&intel_flash_bxt_device); } @@ -758,7 +758,7 @@ void at_p55t2p4_init() pci_slot(0x0A); pci_slot(0x09); i430hx_init(); - piix_init(7, 0x0C, 0x0B, 0x0A, 0x09); + piix_init(7, 0x0C, 0x0B, 0x0A, 0x09, i430hx_reset); w83877f_init(0x3f0, 0x87); device_add(&intel_flash_bxt_device); } diff --git a/src/piix.c b/src/piix.c index 73676cf..5ce6ec5 100644 --- a/src/piix.c +++ b/src/piix.c @@ -8,6 +8,7 @@ #include "ibm.h" #include "ide.h" #include "ide_sff8038i.h" +#include "keyboard_at.h" #include "io.h" #include "mem.h" #include "pci.h" @@ -17,6 +18,8 @@ static uint8_t card_piix[256], card_piix_ide[256]; static sff_busmaster_t piix_busmaster[2]; +static uint8_t piix_rc = 0; +static void (*piix_nb_reset)(); void piix_write(int func, int addr, uint8_t val, void *priv) { @@ -140,7 +143,28 @@ uint8_t piix_read(int func, int addr, void *priv) } -void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) +uint8_t piix_rc_read(uint16_t port, void *p) +{ + return piix_rc; +} + +void piix_rc_write(uint16_t port, uint8_t val, void *p) +{ + if (val & 4) + { + if (val & 2) /*Hard reset*/ + { + piix_nb_reset(); + keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ + ide_reset_devices(); + } + resetx86(); + } + + piix_rc = val & ~4; +} + +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -190,4 +214,7 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) ide_sec_disable(); pic_init_elcrx(); + + io_sethandler(0x0cf9, 0x0001, piix_rc_read, NULL, NULL, piix_rc_write, NULL, NULL, NULL); + piix_nb_reset = nb_reset; } diff --git a/src/piix.h b/src/piix.h index 88a2666..e8d7039 100644 --- a/src/piix.h +++ b/src/piix.h @@ -1 +1 @@ -void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); From a5b59efb3fb5a166bb9466358ab42a8e9fd7fae0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 May 2019 19:31:33 +0100 Subject: [PATCH 0750/1050] readme.txt updates --- readme.txt | 365 ++++++++++++++++------------------------------------- 1 file changed, 111 insertions(+), 254 deletions(-) diff --git a/readme.txt b/readme.txt index 6441056..76dff2e 100644 --- a/readme.txt +++ b/readme.txt @@ -189,6 +189,14 @@ ROM files needed: ltxt\27c64.bin +Zenith Data SupersPort (1987) + +8088 at 8 MHz, 128-640kb RAM. Built-in LCD video is not currently emulated + +ROM files needed: + zdsupers/z184m v3.1d.10d + + Xi8088 (2015) 8088 at 4.77 - 13.33 MHz, 640kb RAM @@ -239,6 +247,16 @@ ROM files needed: pc3086\c000.bin +Amstrad PPC512/640 (1988) + +8086 at 8 MHz, 512-640kb RAM, built-in CGA driving plasma display. + +ROM files needed: + ppc512/40107.v2 + ppc512/40108.v2 + ppc512/40109.bin + + Olivetti M24 (1984) 8086 at 8 MHz, 128kb-640kb RAM, built-in enhanced CGA (supports 640x400x2). @@ -250,7 +268,7 @@ ROM files needed: Sinclair PC200/Amstrad PC20 (1988) -8086 at 8 MHz, 512-640kb RAM, built-in CGA. +8086 at 8 MHz, 512-640kb RAM, built-in CGA. Video supports TV out (50 HZ PAL). ROM files needed: pc200\pc20v2.0 @@ -312,6 +330,15 @@ ROM files needed: award286\award.bin +Bull Micral 45 (1988) + +286 at 12 MHz, 1-6MB RAM. + +ROM files needed: + bull_micral_45/even.fil + bull_micral_45/odd.fil + + Commodore PC30-III (1988) 286 at 12 MHz, 512kb - 16MB RAM. @@ -441,6 +468,15 @@ ROM files needed : t3100e\t3100e.rom +Tulip AT Compact (198x) + +286 at MHz, 640kb - 16 MB RAM + +ROM files needed : + tulip_tc7/tc7be.bin + tulip_tc7/tc7bo.bin + + 386SX based : @@ -623,19 +659,67 @@ ROM files needed : ibmps2_m70_type3/70-a_odd.bin +Packard Bell PB410A (1993) + +486 at 25-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive +at 63-83 MHz. 1-64MB RAM. Built-in HT-216 video. + +ROM files needed: + pb410a/PB410A.080337.4ABF.U25.bin + + + Pentium based : +ASUS P/I-P55TVP4 (1996) + +Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, +Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- +PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip +2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB +RAM. + +ROM files needed: + p55tvp4/tv5i0204.awd + + +ASUS P/I-P55T2P4 (1996) + +Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, +Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- +PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip +2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-512MB +RAM. + +ROM files needed: + p55t2p4/0207_j2.bin + + Award 430VX PCI (1996) Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- -PR400(285 MHz), IDT WinChip at 75-240 MHz. 1-128MB RAM (PCem allows up to 256). +PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip +2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB +RAM. ROM files needed: 430vx\55xwuq0e.bin +Epox P55-VA (1997) + +Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, +Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- +PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip +2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB +RAM. + +ROM files needed: + p55va/va021297.bin + + Intel Advanced/EV (Endeavor) (1995) Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. @@ -688,6 +772,23 @@ ROM files needed: pb570/gd5430.bin + +Super Socket 7 : + +FIC VA-503+ (1998) + +AMD K6 at 166-300 MHz, AMD K6-2 at 233-550 MHz, AMD K6-III at 400-450 MHz, AMD K6-2+ +at 450-550 MHz, AMD K6-III+ at 400-500 MHz, Pentium at 75-200 MHz, Pentium MMX at +166-233 MHz, Mobile Pentium MMX at 120-300 MHz, Cyrix 6x86 at PR90(80 MHz)-PR200(200 +MHz), Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz), IDT WinChip at 75-240 MHz, +IDT WinChip2 at 200-250 MHz, IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz). 1-512MB +RAM. + +ROM files needed: + fic_va503p/je4333.bin + + + PCem emulates the following graphics adapters : @@ -953,6 +1054,9 @@ Paradise EGA. Can use external video card. Amstrad PC2086/PC3086 Paradise PVGA1. An early SVGA clone with 256kb VRAM. Can use external video card. +Amstrad PPC512/640 +CGA/MDA outputting to 640x200 plasma display. Can use external video card. + Elonex PC-425X Trident TGUI9400CXi with 512kb VRAM. @@ -973,6 +1077,9 @@ CGA with double-res text modes and a 640x400 mode. I haven't seen a dump of the ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd as it is 14-line instead of 16-line. +Packard Bell PB410A +Headland HT-216. Can use external video card. + Packard Bell PB520R Cirrus Logic GD-5434. Can use external video card. @@ -980,7 +1087,8 @@ Packard Bell PB570 Cirrus Logic GD-5430. Can use external video card. Sinclair PC200 -CGA. Can use external video card. +CGA. Can use external video card. Internal video can output to a TV, as this is a UK machine +this runs at 50 Hz. Tandy 1000 Clone of PCjr video. Widely supported in 80s games. @@ -1189,254 +1297,3 @@ Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've Software tested: -CP/M-86 1.0 - -PC-DOS 1.0 -MS-DOS 2.11 -MS-DOS 3.30 -PC-DOS 4.01 -MS-DOS 5.0 -PC-DOS 5.02 -MS-DOS 6.0 -MS-DOS 6.22 - -Windows 1.03 -Windows/286 2.11 -Windows/386 2.11 -Windows 3.0 -Windows 3.1 -Windows for Workgroups 3.11 -Windows 95 -Windows 95 OSR2 -Windows 98 -Windows 98 SE -Windows ME - -Windows NT 3.51 -Windows NT 4 -Windows 2000 -Windows XP - -OS/2 v1.0 -OS/2 v1.1 -OS/2 v1.2 -OS/2 v1.3 -OS/2 v2.1 -OS/2 Warp 3 -OS/2 Warp 4 - -Corel Linux 1.2 -Red Hat Linux 7.1 (Seawolf) - -Solaris 2.4 -Solaris 2.5.1 - -BeOS 5 Personal -BeOS 5 Professional - -DESQview/X - -GEM Desktop 3.11 - -After Dark 3.0 -Aldus PageMaker 5.0 -Ami Pro 3.0 -Borland C++ 3.1 -Cubasis v1.13 -Fasttracker 2.08 -Firefox 12.0 -Internet Explorer 5 (windows 3.x and 9x versions tested) -Microsoft Basic 4.0 -Microsoft Office 95 -Microsoft Visual C++ 6.0 Standard Edition -Microsoft Word 1.1 -Microsoft Word for Windows 1.1 -Microsoft Word for Windows 2.0c -Microsoft Word 6.0 -Microsoft Works 2.0 -Microsoft Works for Windows 3.0 -Netscape Communicator 4.73 -Norton Utilities 8.0 -PC Paintbrush v1.05 -Photoshop v3.0.4 -Tantrakr - -Actua Soccer -Age of Empires -Aladdin -All New World of Lemmings -American McGee's Alice -Area 51 -Arkanoid -Ascendancy -Battlezone -Beyond Castle Wolfenstein -Bio Menace (shareware) -Blood 2 -Boppin' -Brix (shareware) -Bust-A-Move 2 -Caesar 3 -Cannon Fodder 2 -CART: Precision Racing -Civilization II -Clusterball -Command and Conquer : Red Alert -Commando -Commandos: Behind Enemy Lines -Commandos: Beyond the Call of Duty -Conquest -Corridor 7 -Curse of Monkey Island -Dawn Patrol -Desert Strike -Dethkarz -Deus Ex -Discworld II -Digger -Dogz -Doom (v1.2 registered) -Doom II (v1.666) -Double Dragon -Down Under Dan -Drakan : Order of the Flame -Dreamweb -Duke Nukem 3D (shareware) -Dune -Dune II -Dungeon Keeper 2 -Earthworm Jim (DOS) -Epic Pinball (v2.1 registered) -Final Fantasy VII -Forsaken -Frogger -G-Police -Grand Theft Auto -Hardwar -Heartlight -Heretic -Heretic II -Hitch-Hiker's Guide to the Galaxy -Hocus Pocus (v1.1 shareware) -House of the Dead 2 -Incoming -Jazz Jackrabbit -Jazz Jackrabbit 2 -Joe Montana Football -Jumpman -King's Quest -King's Quest II -Lemmings -Lemmings 2 : The Tribes -Little Big Adventure 2 -Lotus III -Mageslayer -Maniac Mansion -Maniac Mansion (enhanced) -Microsoft Arcade -Monkey Island 2 -Monster Bash (shareware) -Monster Truck Madness -Mortal Kombat II -Mortal Kombat Trilogy -Necrodome -Need for Speed II SE -Nerf Arena Blast -Network Q RAC Rally -NFL Blitz -NFL Blitz 2000 -Pax Corpus -Pinball Fantasies -Pinball Illusions -Police Quest II -Power Drive -Prince of Persia -Pro Pinball : Big Race USA -Pro Pinball : The Web -Pro Pinball : Timeshock -Puyo Puyo Tsu -Quake (v1.01 registered) -Quake 2 -Quake III Arena -Railroad Tycoon II -Rampage World Tour -Rayman -Redline Racer (1998 US release) -Revolution X -Rollercoaster Tycoon -Rollo and the Brush Bros -Screamer -Screamer 2 -Secret of Monkey Island -SimCity 2000 (DOS) -SimCity 2000 (OS/2) -SimCity 3000 (Linux) -Slipstream 5000 -Sonic R -Space Strike -Star Trek : Starfleet Command -Star Trek : Voyager - Elite Force -Stargunner -Super Zaxxon -Syndicate -System Shock -Take No Prisoners -Terminal Velocity -TFX -The Humans -The Lion King -The Ultimate Doom (v1.9) -Theme Hospital -Theme Park (floppy version) -Tomb Raider -Tomb Raider II -Tony Hawks Pro Skater 2 -Total Annihilation -Transport Tycoon -Transport Tycoon Deluxe -Turok : Dinosaur Hunter -Turrican II -UFO : Enemy Unknown (v1.2) -Unreal -Unreal Tournament -Wacky Wheels -Warcraft II -Wargasm -Wetrix -Wing Commander 3 -Wing Commander Privateer -Wolfenstein 3D (v1.4 registered) -Worms -Worms United -Worms 2 -X-Wing (floppy version) -Zak McKracken -Zone 66 (shareware) -Zone Raiders - -Cascada - Cronologia -Complex - Cyboman 2 -EMF - Verses -Future Crew - Second Reality -Gazebo - Cyboman! -Hornet - Introjr -Logic Design - Fashion -Orange - X14 -Renaissance - Amnesia -Skull - Putrefaction -Tran - Ambience -Tran - Luminati -Tran - Timeless -Triton - Crystal Dream -Triton - Crystal Dream II -Ultraforce - Coldcut -Ultraforce - Vectdemo -Witan - Witan House - -BeebInC v0.99f -Fellow v0.33 -KGen98 v0.4b -PaCifiST v0.45 -SNES9x v0.96 -vMac v1.9.1.1 -ZSNES v0.800 \ No newline at end of file From 803b48ea1c8accc2214c03b2227b82e34ab77b62 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 May 2019 08:17:10 +0100 Subject: [PATCH 0751/1050] Fixed direction of AudioPCI sample counters. Fixes stuttering MIDI in some games (eg Theme Hospital). --- src/sound_audiopci.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index b56b510..5fb4156 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -47,7 +47,8 @@ typedef struct es1371_t uint32_t addr, addr_latch; uint16_t count, size; - uint16_t samp_ct, curr_samp_ct; + uint16_t samp_ct; + int curr_samp_ct; pc_timer_t timer; uint64_t latch; @@ -579,8 +580,6 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) case 0xc: es1371->dac[0].size = val & 0xffff; es1371->dac[0].count = val >> 16; - if (es1371->dac[0].count) - es1371->dac[0].count -= 4; break; case 0xd: @@ -1101,16 +1100,13 @@ static void es1371_poll(void *p) es1371_next_sample_filtered(es1371, 0, es1371->dac[0].f_pos ? 16 : 0); es1371->dac[0].f_pos = (es1371->dac[0].f_pos + 1) & 1; - es1371->dac[0].curr_samp_ct++; - if (es1371->dac[0].curr_samp_ct == es1371->dac[0].samp_ct) + es1371->dac[0].curr_samp_ct--; + if (es1371->dac[0].curr_samp_ct < 0) { // pclog("DAC1 IRQ\n"); es1371->int_status |= INT_STATUS_DAC1; es1371_update_irqs(es1371); - } - if (es1371->dac[0].curr_samp_ct > es1371->dac[0].samp_ct) - { - es1371->dac[0].curr_samp_ct = 0; + es1371->dac[0].curr_samp_ct = es1371->dac[0].samp_ct; } } } @@ -1134,16 +1130,14 @@ static void es1371_poll(void *p) es1371_next_sample_filtered(es1371, 1, es1371->dac[1].f_pos ? 16 : 0); es1371->dac[1].f_pos = (es1371->dac[1].f_pos + 1) & 1; - es1371->dac[1].curr_samp_ct++; - if (es1371->dac[1].curr_samp_ct == es1371->dac[1].samp_ct) + es1371->dac[1].curr_samp_ct--; + if (es1371->dac[1].curr_samp_ct < 0) { -// es1371->dac[1].curr_samp_ct = 0; // pclog("DAC2 IRQ\n"); es1371->int_status |= INT_STATUS_DAC2; es1371_update_irqs(es1371); + es1371->dac[1].curr_samp_ct = es1371->dac[1].samp_ct; } - if (es1371->dac[1].curr_samp_ct > es1371->dac[1].samp_ct) - es1371->dac[1].curr_samp_ct = 0; } } } From e676e6b9e0e0d5158a58627641dbfc913b49eef4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 May 2019 17:38:31 +0100 Subject: [PATCH 0752/1050] Update version number to v15. --- Readme-BSD.txt | 2 +- Readme-LINUX.txt | 2 +- readme.txt | 376 +++++++++++++++++++++++++++++++++++--- src/pc.c | 2 +- src/wx-sdl2-display-win.c | 2 +- 5 files changed, 353 insertions(+), 31 deletions(-) diff --git a/Readme-BSD.txt b/Readme-BSD.txt index 54bd090..f129d58 100644 --- a/Readme-BSD.txt +++ b/Readme-BSD.txt @@ -1,4 +1,4 @@ -PCem v14 BSD supplement +PCem v15 BSD supplement You will need the following libraries : diff --git a/Readme-LINUX.txt b/Readme-LINUX.txt index 514d331..a6d36da 100644 --- a/Readme-LINUX.txt +++ b/Readme-LINUX.txt @@ -1,4 +1,4 @@ -PCem v14 Linux supplement +PCem v15 Linux supplement You will need the following libraries : diff --git a/readme.txt b/readme.txt index 76dff2e..aca3df4 100644 --- a/readme.txt +++ b/readme.txt @@ -1,34 +1,22 @@ -PCem v14 +PCem v15 PCem is licensed under the GPL, see COPYING for more details. -Changes since v13.1: +Changes since v14: +- New machines added - Zenith Data SupersPort, Bull Micral 45, Tulip AT Compact, + Amstrad PPC512/640, Packard Bell PB410A, ASUS P/I-P55TVP4, ASUS P/I-P55T2P4, + Epox P55-VA, FIC VA-503+ +- New graphics cards added - Image Manager 1024, Sigma Designs Color 400, + Trigem Korean VGA +- Added emulation of AMD K6 family and IDT Winchip 2 +- New CPU recompiler. This provides several optimisations, and the new design allows + for greater portability and more scope for optimisation in the future +- Experimental ARM and ARM64 host support +- Read-only cassette emulation for IBM PC and PCjr +- Numerous bug fixes -- New machines added - Compaq Portable Plus, Compaq Portable II, Elonex PC-425X, - IBM PS/2 Model 70 (types 3 & 4), Intel Advanced/ZP, NCR PC4i, Packard Bell Legend 300SX, - Packard Bell PB520R, Packard Bell PB570, Thomson TO16 PC, Toshiba T1000, Toshiba T1200, Xi8088 -- New graphics cards added - ATI Korean VGA, Cirrus Logic CL-GD5429, Cirrus Logic CL-GD5430, - Cirrus Logic CL-GD5435, OAK OTI-037, Trident TGUI9400CXi -- New network adapters added - Realtek RTL8029AS -- Iomega Zip drive emulation -- Added option for default video timing -- Added dynamic low-pass filter for SB16/AWE32 DSP playback -- Can select external video card on some systems with built-in video -- Can use IDE hard drives up to 127 GB -- Can now use 7 SCSI devices -- Implemented CMPXCHG8B on Winchip. Can now boot Windows XP on Winchip processors -- CD-ROM emulation on OS X -- Tweaks to Pentium and 6x86 timing -- Numerous bug fixes - fixes Wing Commander : Privateer, Wing Commander III, Wings of Fury, - Zone Raiders, NFL Blitz 2000, Joe Montana Football, SB16 with Earthworm Jim, SB16 with SimCity - 2000, SB16 with Visual Player 2.0, AHA-1542C with Solaris 2.4, Voodoo 2 with FMV in Urban Chaos, - SB2.0 with Syndicate, floppy on early Linux kernels, clicking ADPCM sound playback, varying speed - in Desert Strike, keyboard hang on KMX-C-02, S3 video cards with Linux and OS/2 Warp, AudioPCI - hangs on Windows 2000/XP, OS/2 v2.0 on machines with remapped memory (eg PS/2), OS/2 v2.0 IO - performance with PS/2 ESDI, etc etc - -Thanks to darksabre76, dns2kv2, EluanCM, Greatpsycho, ja've, John Elliott, leilei and nerd73 for -contributions towards this release. +Thanks to dns2kv2, Greatpsycho, Greg V, John Elliott, Koutakun, leilei, Martin_Riarte, +rene, Tale and Tux for contributions towards this release. PCem emulates the following machines: @@ -1297,3 +1285,337 @@ Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've Software tested: +PC-DOS 1.0 +PC-DOS 2.10 +PC-DOS 3.30 +MS-DOS 3.30 +MS-DOS 3.31 +PC-DOS 4.0 +MS-DOS 4.01 +PC-DOS 5.02 +MS-DOS 6.22 + +Windows 1.03 +Windows 2.03 +Windows/286 2.11 +Windows/386 2.11 +Windows 3.0 +Windows 3.1 +Windows for Workgroups 3.11 +Windows 95 +Windows 95 OSR2 +Windows 98SE +Windows ME + +Windows NT 3.1 +Windows NT 3.51 +Windows NT 4 Workstation (SP6a) +Windows 2000 +Windows XP + +OS/2 v1.0 +OS/2 v1.1 +OS/2 v1.2 +OS/2 v1.3 +OS/2 v2.1 +OS/2 Warp 3 +OS/2 Warp 4 + +Corel Linux 1.2 +Red Hat Linux 7.1 (Seawolf) +SuSE Linux 6.3 +Ubuntu 6.06.1 + +BeOS 5.0 Personal Edition +BeOS 5.0 Professional Edition + +CorelDRAW! v2.5 for OS/2 +Cubasis +Fasttracker 2.08 +Lotus SmartSuite 97 +Microsoft Office 95 +Microsoft Word 1.1 for OS/2 +Microsoft Word 1.1 for Windows +Microsoft Word 2.0 +Microsoft Word 6.1 +Microsoft Works for Windows 3.0 +Mozilla Firefox 1.5.0.5 +Visual Basic 4.0 +Winzip 6.2 + +3-Demon +Abuse +Abuse (demo) +Actua Soccer +Age of Empires +Aladdin +Aladdin (demo) +Alien Breed : Tower Assault (demo) +Alien Carnage (shareware) +Alien vs Predator +All New World of Lemmings +American McGee's Alice +Apache (demo) +Atomic Bomberman +Backtrack (demo) +Balls of Steel (demo) +Battlezone +Battlezone (1998) +Battlezone II +Big Red Racing +Bio Menace (shareware) +Blackthorne (demo) +Blake Stone (shareware) +Blast Doors +Blood (demo) +Blood 2 +Breakneck +Brix (shareware) +Bust-a-Move 2 : Arcade Edition +Cannon Fodder 2 +Caesar III +Captain Claw +Carmageddon +Carnivores 2 +Catacomb Abyss (demo) +Carmageddon (demo) +CD-MAN +Charlie the Duck (demo) +Clusterball +Colin McRae Rally +Colonization +Command and Conquer (demo) +Command and Conquer : Red Alert +Commander Keen : Goodbye Galaxy +Commander Keen : Invasion of the Vorticons +Corridor 7 +Counter-Strike 2D +Curse of Monkey Island +Cyril Cyberpunk (demo) +Dark Forces (demo) +Dark Forces +Dawn Patrol +Death Rally +Descent (v1.4) +Descent (demo) +Desert Strike +Destruction Derby +Destruction Derby (demo) +Deus Ex +Diablo +Digger +Discworld II +Dogz +Doom (v1.2) +Doom (shareware) +Doom II (v1.666) +Doom II for Windows 95 +Dune +Dune II +Duke Nukem (shareware) +Duke Nukem 3D (shareware) +DX-Ball 2 +Earthworm Jim (demo) +Ecstatica +Epic Pinball +Epic Pinball (shareware) +Eradicator +Expendable +Expendable (demo) +Extreme Assault +Final Fantasy VII +Flashback (demo) +Frogger +Frogger (1998) +Frontier : First Encounters +Full Throttle (demo) +G-Police +Galactix +GLQuake (v0.93) +Gods (demo) +Grand Theft Auto +Grand Theft Auto 2 +Grim Fandango +Half-Life (1.0.0.9) +Heartlight (shareware) +Heretic +Heretic (demo) +Hexen +Hexen (demo) +Hexen95 +Hocus Pocus (shareware) +House of the Dead 2 +Hover! +Incoming +Indiana Jones and the Fate of Atlantis (demo) +Indy Car Racing 2 (demo) +Interstate 76 Nitro Riders +Interstate 82 +Jazz Jackrabbit (shareware) +Jazz Jackrabbit 2 +Jedi Knight +Jumpman +Kings Quest +Kings Quest II +Lamborghini American Challenge (demo) +LBA 2 +Lemmings +Lemmings (demo) +Lemmings 2 : The Tribes +Lemmings Paintball +Lotus III +Mageslayer +Magic Carpet +MDK +MegaMan X (demo) +Metal Gear Solid +Microsoft Arcade +Monster Bash (shareware) +Mortal Kombat +Mortal Kombat II +Mortal Kombat Trilogy +Moto Racer +NASCAR Heat +NBA Hangtime +Need for Speed (demo) +Need for Speed II SE +Need for Speed III +Nerf Arena Blast +Network Q RAC Rally +No One Lives Forever +No One Lives Forever (tech demo) +Oddworld : Abe's Oddysee +Out of this World (demo) +Panzer Dragoon +Pinball Fantasies +Pinball Illusions +Populous : The Beginning +Prince of Persia (demo) +Prince of Persia 2 (demo) +Pro Pinball : Big Race USA +Pro Pinball : Timeshock! +Pro Pinball : The Web +Project X (demo) +Psycho Pinball +Quake (v1.01) +Quake (shareware) +Quake II +Quake III Arena (1.27g) +Quake III Arena (1.30) +Radix (demo) +Railroad Tycoon II (demo) +Raptor (shareware) +Rayman +Realms of Chaos (shareware) +Red Faction +Resident Evil 2 +Return to Castle Wolfenstein (v1.32) +Rise of the Triad (shareware) +Road Rash +Rogue Spear (demo) +Rollcage (demo) +Rollercoaster Tycoon +Sam and Max Hit the Road (demo) +Screamer +Screamer 2 (demo) +Screamer Rally (NOT 3DFX) +Secret of Monkey Island (demo) +Serious Sam +Shadow Warrior (demo) +Simcity 2000 +Simcity 2000 (demo) +Simcity 2000 for OS/2 Warp +SimCity 3000 +Simcopter +Sonic 3 & Knuckles +Speed Haste (demo) +Star Trek Voyager : Elite Force +Stargunner +Street Racer (demo) +Streets of Simcity +Striker 95 +Super Angelo (demo) +Superkarts +Super Street Fighter 2 (demo) +Syndicate +Syndicate (demo) +System Shock +Tennis Elbow (demo) +Terminal velocity +Terminal Velocity (shareware) +The Adventures of Captain Comic +The Chaos Engine +The Chaos Engine (demo) +The Humans +The Incredible Machine (demo) +The Lion King +The Lion King (demo) +Thief II +Theme Hospital +Theme Hospital (demo) +Theme Park +Threat (demo) +Tie Fighter (demo) +Tomb Raider +Tomb Raider (demo) +Tomb Raider II +Tomb Raider III +Tony Hawk's Pro Skater 2 +Transport Tycoon +Transport Tycoon Deluxe +Turok (demo) +Tyrian +Tyrian (shareware) +UFO : Enemy Unknown +Ultimate Doom (v1.9) +Unreal +Unreal Gold +Unreal Tournament +Unreal Tournament (v436 GOTY) +Virtual Pool (demo) +Wacky Wheels +Warcraft (demo) +Warcraft II (demo) +Wing Commander +Wolfenstein 3D (v1.4) +Wolfenstein 3D (shareware) +World Cup 98 +Worms +Worms (demo) +Worms 2 +Worms World Party +X-Com : Terror From The Deep +X-Wing +Z (demo) +Z.A.R. (demo) +Zone 66 +Zone 66 (shareware) + +Cascada - Cronologia +Complex - Cyboman 2 +EMF - Verses +Exceed - Heaven 7 +Future Crew - Second Reality +Gazebo - Cyboman! +KFMF - Dance, Move, Shake +KFMF - Trip +Logic Design - Fashion +Orange - x14 +Renaissance - Amnesia +Skull - Putre Faction +Tran - Ambience +Tran - Luminati +Tran - Timeless +Triton - Crystal Dream II +Triton - Crystal Dream +Ultraforce - Coldcut +Ultraforce - Vector Demo + +BeebInC v0.99f +Fellow v0.3.3 +KGen98 v0.4 +PaCifiST v0.45 +SNES9x v0.96 +UltraHLE v1.0.0 +vMac v0.1.9.1 +ZSNES v0.800c diff --git a/src/pc.c b/src/pc.c index 2cbf071..7b6fa59 100644 --- a/src/pc.c +++ b/src/pc.c @@ -581,7 +581,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v14 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem v15 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index f1062d5..61779c2 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -584,7 +584,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v14", /* Title Text */ + "PCem v15", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From 2c6b130ec8690fc2653cdf847d5b8782104a9c7e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 May 2019 17:41:11 +0100 Subject: [PATCH 0753/1050] Update Makefile.in --- src/Makefile.in | 96 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 32 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index 038f20f..9bcb781 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -140,8 +140,8 @@ CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__pcem_SOURCES_DIST = 386.c 386_common.c 386_dynarec.c \ - 386_dynarec_ops.c 808x.c acc2036.c acc2168.c acc3221.c \ - acer386sx.c ali1429.c amstrad.c cassette.c cbm_io.c \ + 386_dynarec_ops.c 808x.c 82091aa.c acc2036.c acc2168.c \ + acc3221.c acer386sx.c ali1429.c amstrad.c cassette.c cbm_io.c \ cdrom-image.cc cdrom-null.c cmd640.c codegen.c \ codegen_accumulate.c codegen_allocator.c codegen_block.c \ codegen_ir.c codegen_ops.c codegen_ops_3dnow.c \ @@ -159,12 +159,12 @@ am__pcem_SOURCES_DIST = 386.c 386_common.c 386_dynarec.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c \ config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c \ - fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ - hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c \ - ide.c ide_atapi.c ide_sff8038i.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 \ + fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430hx.c \ + i430vx.c ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ @@ -278,13 +278,14 @@ am__dirstamp = $(am__leading_dot)dirstamp @OS_WINDOWS_TRUE@ pcem-wx-sdl2-display-win.$(OBJEXT) am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ pcem-386_dynarec.$(OBJEXT) pcem-386_dynarec_ops.$(OBJEXT) \ - pcem-808x.$(OBJEXT) pcem-acc2036.$(OBJEXT) \ - pcem-acc2168.$(OBJEXT) pcem-acc3221.$(OBJEXT) \ - pcem-acer386sx.$(OBJEXT) pcem-ali1429.$(OBJEXT) \ - pcem-amstrad.$(OBJEXT) pcem-cassette.$(OBJEXT) \ - pcem-cbm_io.$(OBJEXT) pcem-cdrom-image.$(OBJEXT) \ - pcem-cdrom-null.$(OBJEXT) pcem-cmd640.$(OBJEXT) \ - pcem-codegen.$(OBJEXT) pcem-codegen_accumulate.$(OBJEXT) \ + pcem-808x.$(OBJEXT) pcem-82091aa.$(OBJEXT) \ + pcem-acc2036.$(OBJEXT) pcem-acc2168.$(OBJEXT) \ + pcem-acc3221.$(OBJEXT) pcem-acer386sx.$(OBJEXT) \ + pcem-ali1429.$(OBJEXT) pcem-amstrad.$(OBJEXT) \ + pcem-cassette.$(OBJEXT) pcem-cbm_io.$(OBJEXT) \ + pcem-cdrom-image.$(OBJEXT) pcem-cdrom-null.$(OBJEXT) \ + pcem-cmd640.$(OBJEXT) pcem-codegen.$(OBJEXT) \ + pcem-codegen_accumulate.$(OBJEXT) \ pcem-codegen_allocator.$(OBJEXT) pcem-codegen_block.$(OBJEXT) \ pcem-codegen_ir.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ pcem-codegen_ops_3dnow.$(OBJEXT) \ @@ -319,12 +320,13 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ pcem-disc_fdi.$(OBJEXT) pcem-disc_img.$(OBJEXT) \ pcem-disc_sector.$(OBJEXT) pcem-dma.$(OBJEXT) \ pcem-esdi_at.$(OBJEXT) pcem-fdc.$(OBJEXT) \ - pcem-fdc37c665.$(OBJEXT) pcem-fdd.$(OBJEXT) \ - pcem-fdi2raw.$(OBJEXT) pcem-gameport.$(OBJEXT) \ - pcem-hdd.$(OBJEXT) pcem-hdd_esdi.$(OBJEXT) \ - pcem-hdd_file.$(OBJEXT) pcem-headland.$(OBJEXT) \ - pcem-i430lx.$(OBJEXT) pcem-i430fx.$(OBJEXT) \ - pcem-i430hx.$(OBJEXT) pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ + pcem-fdc37c665.$(OBJEXT) pcem-fdc37c93x.$(OBJEXT) \ + pcem-fdd.$(OBJEXT) pcem-fdi2raw.$(OBJEXT) \ + pcem-gameport.$(OBJEXT) pcem-hdd.$(OBJEXT) \ + pcem-hdd_esdi.$(OBJEXT) pcem-hdd_file.$(OBJEXT) \ + pcem-headland.$(OBJEXT) pcem-i430lx.$(OBJEXT) \ + pcem-i430fx.$(OBJEXT) pcem-i430hx.$(OBJEXT) \ + pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ pcem-ide_atapi.$(OBJEXT) pcem-ide_sff8038i.$(OBJEXT) \ pcem-intel.$(OBJEXT) pcem-intel_flash.$(OBJEXT) \ pcem-io.$(OBJEXT) pcem-jim.$(OBJEXT) \ @@ -640,11 +642,11 @@ WINDRES = $(shell $(WX_CONFIG_PATH) --rescomp) # resid-fp pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c \ - 808x.c acc2036.c acc2168.c acc3221.c acer386sx.c ali1429.c \ - amstrad.c cassette.c cbm_io.c cdrom-image.cc cdrom-null.c \ - cmd640.c codegen.c codegen_accumulate.c codegen_allocator.c \ - codegen_block.c codegen_ir.c codegen_ops.c codegen_ops_3dnow.c \ - codegen_ops_arith.c codegen_ops_branch.c \ + 808x.c 82091aa.c acc2036.c acc2168.c acc3221.c acer386sx.c \ + ali1429.c amstrad.c cassette.c cbm_io.c cdrom-image.cc \ + cdrom-null.c cmd640.c codegen.c codegen_accumulate.c \ + codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c \ + codegen_ops_3dnow.c codegen_ops_arith.c codegen_ops_branch.c \ codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c \ codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c \ codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c \ @@ -658,12 +660,12 @@ pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c \ config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c \ - fdc37c665.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ - hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c \ - ide.c ide_atapi.c ide_sff8038i.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 \ + fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c \ + hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430hx.c \ + i430vx.c ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ @@ -912,6 +914,7 @@ distclean-compile: @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-82091aa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2036.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2168.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc3221.Po@am__quote@ @@ -991,6 +994,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.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-fdc37c93x.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdd.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@ @@ -1313,6 +1317,20 @@ pcem-808x.obj: 808x.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-82091aa.o: 82091aa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-82091aa.o -MD -MP -MF $(DEPDIR)/pcem-82091aa.Tpo -c -o pcem-82091aa.o `test -f '82091aa.c' || echo '$(srcdir)/'`82091aa.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-82091aa.Tpo $(DEPDIR)/pcem-82091aa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='82091aa.c' object='pcem-82091aa.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-82091aa.o `test -f '82091aa.c' || echo '$(srcdir)/'`82091aa.c + +pcem-82091aa.obj: 82091aa.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-82091aa.obj -MD -MP -MF $(DEPDIR)/pcem-82091aa.Tpo -c -o pcem-82091aa.obj `if test -f '82091aa.c'; then $(CYGPATH_W) '82091aa.c'; else $(CYGPATH_W) '$(srcdir)/82091aa.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-82091aa.Tpo $(DEPDIR)/pcem-82091aa.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='82091aa.c' object='pcem-82091aa.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-82091aa.obj `if test -f '82091aa.c'; then $(CYGPATH_W) '82091aa.c'; else $(CYGPATH_W) '$(srcdir)/82091aa.c'; fi` + pcem-acc2036.o: acc2036.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acc2036.o -MD -MP -MF $(DEPDIR)/pcem-acc2036.Tpo -c -o pcem-acc2036.o `test -f 'acc2036.c' || echo '$(srcdir)/'`acc2036.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-acc2036.Tpo $(DEPDIR)/pcem-acc2036.Po @@ -2125,6 +2143,20 @@ pcem-fdc37c665.obj: fdc37c665.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-fdc37c93x.o: fdc37c93x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdc37c93x.o -MD -MP -MF $(DEPDIR)/pcem-fdc37c93x.Tpo -c -o pcem-fdc37c93x.o `test -f 'fdc37c93x.c' || echo '$(srcdir)/'`fdc37c93x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-fdc37c93x.Tpo $(DEPDIR)/pcem-fdc37c93x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fdc37c93x.c' object='pcem-fdc37c93x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdc37c93x.o `test -f 'fdc37c93x.c' || echo '$(srcdir)/'`fdc37c93x.c + +pcem-fdc37c93x.obj: fdc37c93x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdc37c93x.obj -MD -MP -MF $(DEPDIR)/pcem-fdc37c93x.Tpo -c -o pcem-fdc37c93x.obj `if test -f 'fdc37c93x.c'; then $(CYGPATH_W) 'fdc37c93x.c'; else $(CYGPATH_W) '$(srcdir)/fdc37c93x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-fdc37c93x.Tpo $(DEPDIR)/pcem-fdc37c93x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fdc37c93x.c' object='pcem-fdc37c93x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdc37c93x.obj `if test -f 'fdc37c93x.c'; then $(CYGPATH_W) 'fdc37c93x.c'; else $(CYGPATH_W) '$(srcdir)/fdc37c93x.c'; fi` + pcem-fdd.o: fdd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdd.o -MD -MP -MF $(DEPDIR)/pcem-fdd.Tpo -c -o pcem-fdd.o `test -f 'fdd.c' || echo '$(srcdir)/'`fdd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-fdd.Tpo $(DEPDIR)/pcem-fdd.Po From 2489fd9c6eb4a21ae7a1d737322663aeec5aee7a Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Dec 2019 11:24:08 +0000 Subject: [PATCH 0754/1050] Add ATI EGA Wonder 800+ emulation. --- src/ibm.h | 1 + src/vid_ati18800.c | 123 ++++++++++++++++++++++++++++++++++++++++++- src/vid_ati18800.h | 1 + src/vid_ati_eeprom.c | 2 +- src/vid_svga.c | 10 +++- src/vid_svga.h | 5 ++ src/video.c | 1 + 7 files changed, 140 insertions(+), 3 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 4212fad..e59b322 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -300,6 +300,7 @@ enum GFX_SIGMA400, /*Sigma Designs Color 400 */ GFX_PGC, /*Professional Graphics Controller */ GFX_IM1024, /*Vermont Microsystems IM1024 */ + GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/ GFX_MAX }; diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index 7e672a0..fd00caa 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -19,6 +19,10 @@ typedef struct ati18800_t uint8_t regs[256]; int index; + + int is_ega; + int ega_switches; + int ega_switch_read; } ati18800_t; void ati18800_out(uint16_t addr, uint8_t val, void *p) @@ -56,6 +60,43 @@ void ati18800_out(uint16_t addr, uint8_t val, void *p) } break; + case 0x3c2: + if (ati18800->is_ega) + { + if ((val & 0x80) != (svga->miscout & 0x80)) + { + int c; + + if (val & 0x80) + { + for (c = 0; c < 256; c++) + { + ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + ati18800->svga.pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + } + ati18800->svga.vertical_linedbl = 0; + } + else + { + for (c = 0; c < 256; c++) + { + if ((c & 0x17) == 6) + ati18800->svga.pallook[c] = makecol32(0xaa, 0x55, 0x00); + else + { + ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + ati18800->svga.pallook[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); + } + } + ati18800->svga.vertical_linedbl = 1; + } + + svga->fullchange = changeframecount; + } + ati18800->ega_switch_read = val & 0xc; + } + break; + case 0x3D4: svga->crtcreg = val & 0x3f; return; @@ -109,6 +150,20 @@ uint8_t ati18800_in(uint16_t addr, void *p) } break; + case 0x3c2: + if (ati18800->is_ega) + { + switch (ati18800->ega_switch_read) + { + case 0xc: return (ati18800->ega_switches & 1) ? 0x10 : 0; + case 0x8: return (ati18800->ega_switches & 2) ? 0x10 : 0; + case 0x4: return (ati18800->ega_switches & 4) ? 0x10 : 0; + case 0x0: return (ati18800->ega_switches & 8) ? 0x10 : 0; + } + } + break; + + case 0x3D4: temp = svga->crtcreg; break; @@ -119,10 +174,25 @@ uint8_t ati18800_in(uint16_t addr, void *p) temp = svga_in(addr, svga); break; } - if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); +// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); return temp; } +static void ega_wonder_800_recalctimings(svga_t *svga) +{ + ati18800_t *ati18800 = (ati18800_t *)svga->p; + int clksel = ((svga->miscout & 0xc) >> 2) | ((ati18800->regs[0xbe] & 0x10) ? 4 : 0); + + switch (clksel) + { + case 0: svga->clock = (cpuclock * (double)(1ull << 32)) / 25175000.0; break; + case 1: svga->clock = (cpuclock * (double)(1ull << 32)) / 28322000.0; break; + case 4: svga->clock = (cpuclock * (double)(1ull << 32)) / 14318181.0; break; + case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 16257000.0; break; + case 7: default: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; + } +} + void *ati18800_init() { ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); @@ -146,11 +216,51 @@ void *ati18800_init() return ati18800; } +void *ega_wonder_800_init() +{ + int c; + + ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); + memset(ati18800, 0, sizeof(ati18800_t)); + + rom_init(&ati18800->bios_rom, "ATI EGA Wonder 800+ N1.00.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + svga_init(&ati18800->svga, ati18800, 1 << 18, /*256kb*/ + ega_wonder_800_recalctimings, + ati18800_in, ati18800_out, + NULL, + NULL); + + io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03c0, 0x0006, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03ca, 0x0016, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + + ati18800->svga.miscout = 1; + + for (c = 0; c < 256; c++) + { + ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + ati18800->svga.pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + } + + ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); + + ati18800->is_ega = 1; + ati18800->ega_switches = 9; + + return ati18800; +} + static int ati18800_available() { return rom_present("vgaedge16.vbi"); } +static int ega_wonder_800_available() +{ + return rom_present("ATI EGA Wonder 800+ N1.00.BIN"); +} + void ati18800_close(void *p) { ati18800_t *ati18800 = (ati18800_t *)p; @@ -193,3 +303,14 @@ device_t ati18800_device = ati18800_add_status_info }; +device_t ati_ega_wonder_800_device = +{ + "ATI EGA Wonder 800+", + 0, + ega_wonder_800_init, + ati18800_close, + ega_wonder_800_available, + ati18800_speed_changed, + ati18800_force_redraw, + ati18800_add_status_info +}; diff --git a/src/vid_ati18800.h b/src/vid_ati18800.h index 83fe2c0..0d667ab 100644 --- a/src/vid_ati18800.h +++ b/src/vid_ati18800.h @@ -1 +1,2 @@ extern device_t ati18800_device; +extern device_t ati_ega_wonder_800_device; diff --git a/src/vid_ati_eeprom.c b/src/vid_ati_eeprom.c index 3586894..ce13701 100644 --- a/src/vid_ati_eeprom.c +++ b/src/vid_ati_eeprom.c @@ -37,7 +37,7 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) f = nvrfopen(eeprom->fn, "rb"); if (!f) { - memset(eeprom->data, 0, eeprom->type ? 512 : 128); + memset(eeprom->data, 0xff, eeprom->type ? 512 : 128); return; } fread(eeprom->data, 1, eeprom->type ? 512 : 128, f); diff --git a/src/vid_svga.c b/src/vid_svga.c index 538b131..3418ae1 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -582,6 +582,11 @@ void svga_poll(void *p) svga->ma = svga->maback; } } + svga->hsync_divisor = !svga->hsync_divisor; + + if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) + return; + svga->vc++; svga->vc &= 2047; @@ -1296,7 +1301,10 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) if (xsize<64) xsize=656; if (ysize<32) ysize=200; - updatewindowsize(xsize,ysize); + if (svga->vertical_linedbl) + updatewindowsize(xsize,ysize*2); + else + updatewindowsize(xsize,ysize); } if (vid_resize) { diff --git a/src/vid_svga.h b/src/vid_svga.h index 08f5111..5a7efa3 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -129,6 +129,11 @@ typedef struct svga_t void *p; uint8_t ksc5601_sbyte_mask; + + int vertical_linedbl; + + /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ + int hsync_divisor; } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize, diff --git a/src/video.c b/src/video.c index 7eb151d..3b31973 100644 --- a/src/video.c +++ b/src/video.c @@ -83,6 +83,7 @@ static VIDEO_CARD video_cards[] = { {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"ATI EGA Wonder 800+ (ATI-18800)", "egawonder800", &ati_ega_wonder_800_device, GFX_EGAWONDER800, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"ATI Korean VGA (ATI-28800)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From f56f5e76e663d849b067fade82a2d17878be0833 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Dec 2019 17:01:53 +0000 Subject: [PATCH 0755/1050] Fix latching in svga_read_linear(). Fixes Jazz Jackrabbit on Cirrus Logic cards. --- src/vid_svga.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index 3418ae1..c265266 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -1229,6 +1229,7 @@ uint8_t svga_read_linear(uint32_t addr, void *p) svga_t *svga = (svga_t *)p; uint8_t temp, temp2, temp3, temp4; int readplane = svga->readplane; + uint32_t latch_addr = (addr << 2) & svga->decode_mask; cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; @@ -1253,15 +1254,24 @@ uint8_t svga_read_linear(uint32_t addr, void *p) addr &= svga->decode_mask; + if (latch_addr >= svga->vram_max) + { + svga->la = svga->lb = svga->lc = svga->ld = 0xff; + } + else + { + latch_addr &= svga->vram_mask; + 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]; + } + if (addr >= svga->vram_max) return 0xff; addr &= svga->vram_mask; - 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->la; From 5c8e1aecc21056da2171367a86569b337a3c79a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Dec 2019 17:19:25 +0000 Subject: [PATCH 0756/1050] Added emulation of Commodore SL386SX-25 (PC Player II). As part of this, added emulation of the onboard AVGA2, and fixed a couple of bugs in the Cirrus Logic extended write modes. Currently chipset (VLSI SCAMP) is missing EMS emulation. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/ibm.h | 3 +- src/mem_bios.c | 7 + src/model.c | 9 + src/nvr.c | 2 + src/scamp.c | 230 +++++++++++++++++++++++++ src/scamp.h | 1 + src/vid_cl5429.c | 262 +++++++++++++++++++++++++---- src/vid_cl5429.h | 1 + src/video.c | 15 ++ 12 files changed, 499 insertions(+), 37 deletions(-) create mode 100644 src/scamp.c create mode 100644 src/scamp.h diff --git a/src/Makefile.am b/src/Makefile.am index 3a83dae..89e5664 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,7 +38,7 @@ jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c joysti keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c laserxt.c lpt.c lpt_dac.c lpt_dss.c \ mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \ neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ -ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ +ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 3f8ce14..61af689 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -24,7 +24,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ - piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ + piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index a0e2415..60dd89c 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -24,7 +24,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ - piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scat.o scsi.o \ + piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/ibm.h b/src/ibm.h index e59b322..370ccbf 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -252,7 +252,8 @@ enum ROM_PPC512, ROM_BULL_MICRAL_45, ROM_FIC_VA503P, - + ROM_CBM_SL386SX25, + ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 8f787ea..66d0f38 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -1008,6 +1008,13 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_CBM_SL386SX25: + f = romfopen("cbm_sl386sx25/f000.rom", "rb"); + if (!f) break; + romfread(rom, 0x10000, 1, f); + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 33b65c1..5d582f5 100644 --- a/src/model.c +++ b/src/model.c @@ -54,6 +54,7 @@ #include "ps1.h" #include "ps2.h" #include "ps2_mca.h" +#include "scamp.h" #include "scat.h" #include "serial.h" #include "sio.h" @@ -96,6 +97,7 @@ void ps2_model_55sx_init(); void ps2_model_70_init(); void ps2_model_80_init(); void at_neat_init(); +void at_scamp_init(); void at_scat_init(); void at_scatsx_init(); void at_acer386sx_init(); @@ -184,6 +186,7 @@ MODEL models[] = {"[386SX] AMA-932J", ROM_AMA932J, "ama932j", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_headland_init, NULL}, {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"[386SX] Commodore SL386SX-25", ROM_CBM_SL386SX25, "cbm_sl386sx25", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1024,16384, 512, at_scamp_init, NULL}, {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, @@ -567,6 +570,12 @@ void at_neat_init() neat_init(); } +void at_scamp_init() +{ + at_init(); + scamp_init(); +} + void at_scat_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index f080247..3a15a55 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -347,6 +347,7 @@ void loadnvr() case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); nvrmask = 127; break; case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); break; case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break; + case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -445,6 +446,7 @@ void savenvr() case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); break; case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); break; case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break; + case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break; default: return; } diff --git a/src/scamp.c b/src/scamp.c new file mode 100644 index 0000000..6fe9570 --- /dev/null +++ b/src/scamp.c @@ -0,0 +1,230 @@ +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "scamp.h" + +static struct +{ + int cfg_index; + uint8_t cfg_regs[256]; + int cfg_enable; + + uint8_t port_92; +} scamp; + +#define CFG_ID 0x00 +#define CFG_SLTPTR 0x02 +#define CFG_RAMMAP 0x03 +#define CFG_ABAXS 0x0e +#define CFG_CAXS 0x0f +#define CFG_DAXS 0x10 +#define CFG_FEAXS 0x11 + +#define ID_VL82C311 0xd6 + +#define RAMMAP_REMP386 (1 << 4) + +static void shadow_control(uint32_t addr, uint32_t size, int state) +{ +// pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); + switch (state) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +void scamp_write(uint16_t addr, uint8_t val, void *p) +{ +// pclog("scamp_write: addr=%04x val=%02x\n", addr, val); + switch (addr) + { + case 0x92: + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~scamp.port_92 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + scamp.port_92 = val; + break; + + case 0xec: + if (scamp.cfg_enable) + scamp.cfg_index = val; + break; + + case 0xed: + if (scamp.cfg_enable) + { + if (scamp.cfg_index >= 0x02 && scamp.cfg_index <= 0x16) + { + scamp.cfg_regs[scamp.cfg_index] = val; +// pclog("SCAMP CFG[%02x]=%02x\n", scamp.cfg_index, val); + switch (scamp.cfg_index) + { + case CFG_SLTPTR: +#if 0 + if (!val) + { + /*Disable all RAM*/ + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_high_mapping); + } + else if (val < 0x10) + { + mem_mapping_set_addr(&ram_low_mapping, 0, (val > 9) ? 0xa0000 : (val << 16)); + mem_mapping_disable(&ram_high_mapping); + } + else + { + mem_mapping_enable(&ram_low_mapping); + mem_mapping_enable(&ram_high_mapping); + } +#endif + break; + + case CFG_RAMMAP: + mem_mapping_disable(&ram_remapped_mapping); + if (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) + { + /*Enabling remapping will disable all shadowing*/ + mem_remap_top_384k(); + shadow_control(0xa0000, 0x60000, 0); + } + else + { + shadow_control(0xa0000, 0x8000, scamp.cfg_regs[CFG_ABAXS] & 3); + shadow_control(0xa8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); + shadow_control(0xb0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); + shadow_control(0xb8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + + shadow_control(0xc0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3); + shadow_control(0xc4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); + shadow_control(0xc8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); + shadow_control(0xcc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + + shadow_control(0xd0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3); + shadow_control(0xd4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); + shadow_control(0xd8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); + shadow_control(0xdc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + + shadow_control(0xe0000, 0x8000, scamp.cfg_regs[CFG_ABAXS] & 3); + shadow_control(0xe8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); + shadow_control(0xf0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); + shadow_control(0xf8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + } + break; + + case CFG_ABAXS: + if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) + { + shadow_control(0xa0000, 0x8000, val & 3); + shadow_control(0xa8000, 0x8000, (val >> 2) & 3); + shadow_control(0xb0000, 0x8000, (val >> 4) & 3); + shadow_control(0xb8000, 0x8000, (val >> 6) & 3); + } + break; + + case CFG_CAXS: + if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) + { + shadow_control(0xc0000, 0x4000, val & 3); + shadow_control(0xc4000, 0x4000, (val >> 2) & 3); + shadow_control(0xc8000, 0x4000, (val >> 4) & 3); + shadow_control(0xcc000, 0x4000, (val >> 6) & 3); + } + break; + + case CFG_DAXS: + if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) + { + shadow_control(0xd0000, 0x4000, val & 3); + shadow_control(0xd4000, 0x4000, (val >> 2) & 3); + shadow_control(0xd8000, 0x4000, (val >> 4) & 3); + shadow_control(0xdc000, 0x4000, (val >> 6) & 3); + } + break; + + case CFG_FEAXS: + if (!(scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) + { + shadow_control(0xe0000, 0x8000, val & 3); + shadow_control(0xe8000, 0x8000, (val >> 2) & 3); + shadow_control(0xf0000, 0x8000, (val >> 4) & 3); + shadow_control(0xf8000, 0x8000, (val >> 6) & 3); + } + break; + } + } + } + break; + + case 0xee: + if (scamp.cfg_enable && mem_a20_alt) + { + scamp.port_92 &= ~2; + mem_a20_alt = 0; + mem_a20_recalc(); + } + break; + } +} + +uint8_t scamp_read(uint16_t addr, void *p) +{ + uint8_t ret = 0xff; + + switch (addr) + { + case 0x92: + ret = scamp.port_92; + break; + + case 0xee: + if (!mem_a20_alt) + { + scamp.port_92 |= 2; + mem_a20_alt = 1; + mem_a20_recalc(); + } + break; + + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } + +// pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret); + return ret; +} + +void scamp_init(void) +{ + memset(&scamp, 0, sizeof(scamp)); + scamp.cfg_regs[CFG_ID] = ID_VL82C311; + scamp.cfg_enable = 1; + + io_sethandler(0x0092, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00e8, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00ea, 0x0006, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00f4, 0x0002, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00f9, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00fb, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); +} diff --git a/src/scamp.h b/src/scamp.h new file mode 100644 index 0000000..a4785ca --- /dev/null +++ b/src/scamp.h @@ -0,0 +1 @@ +void scamp_init(void); diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 081dc46..70c0635 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -15,7 +15,8 @@ enum { - CL_TYPE_GD5429 = 0, + CL_TYPE_AVGA2 = 0, + CL_TYPE_GD5429, CL_TYPE_GD5430, CL_TYPE_GD5434 }; @@ -73,8 +74,14 @@ typedef struct gd5429_t int mmio_vram_overlap; uint8_t sr10_read, sr11_read; + + uint8_t latch_ext[4]; } gd5429_t; +#define GRB_X8_ADDRESSING (1 << 1) +#define GRB_WRITEMODE_EXT (1 << 2) +#define GRB_8B_LATCHES (1 << 3) + static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p); static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p); @@ -88,13 +95,15 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p); void gd5429_recalc_banking(gd5429_t *gd5429); void gd5429_recalc_mapping(gd5429_t *gd5429); +uint8_t gd5429_read_linear(uint32_t addr, void *p); + void gd5429_out(uint16_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; // pclog("gd5429 out %04X %02X\n", addr, val); @@ -143,7 +152,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; case 0x17: - gd5429_recalc_mapping(gd5429); + if (gd5429->type >= CL_TYPE_GD5429) + gd5429_recalc_mapping(gd5429); break; } return; @@ -196,6 +206,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) if (svga->gdcaddr > 8) { svga->gdcreg[svga->gdcaddr & 0x3f] = val; + if (gd5429->type < CL_TYPE_GD5429 && (svga->gdcaddr > 0xb)) + return; switch (svga->gdcaddr) { case 0x09: case 0x0a: case 0x0b: @@ -318,7 +330,7 @@ uint8_t gd5429_in(uint16_t addr, void *p) gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3d0) && !(svga->miscout & 1)) + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; // if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr); @@ -343,6 +355,8 @@ uint8_t gd5429_in(uint16_t addr, void *p) return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; case 0x17: + if (gd5429->type < CL_TYPE_GD5429) + break; temp = svga->seqregs[0x17]; temp &= ~(7 << 3); if (gd5429->type == CL_TYPE_GD5429) @@ -395,6 +409,8 @@ uint8_t gd5429_in(uint16_t addr, void *p) case 0x27: /*ID*/ switch (gd5429->type) { + case CL_TYPE_AVGA2: + return 0x18; /*AVGA2*/ case CL_TYPE_GD5429: return 0x9c; /*GD5429*/ case CL_TYPE_GD5430: @@ -654,10 +670,10 @@ static void gd5429_write(uint32_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; -// pclog("gd5429_write : %05X %02X ", addr, val); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; -// pclog("%08X\n", addr); + gd5429_write_linear(addr, val, p); } static void gd5429_writew(uint32_t addr, uint16_t val, void *p) @@ -668,7 +684,7 @@ static void gd5429_writew(uint32_t addr, uint16_t val, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - if (svga->writemode < 4) + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_writew_linear(addr, val, svga); else { @@ -684,7 +700,7 @@ static void gd5429_writel(uint32_t addr, uint32_t val, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - if (svga->writemode < 4) + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_writel_linear(addr, val, svga); else { @@ -699,13 +715,10 @@ static uint8_t gd5429_read(uint32_t addr, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; - uint8_t ret; -// pclog("gd5429_read : %05X ", addr); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - ret = svga_read_linear(addr, &gd5429->svga); -// pclog("%08X %02X\n", addr, ret); - return ret; + return gd5429_read_linear(addr, gd5429); } static uint16_t gd5429_readw(uint32_t addr, void *p) { @@ -714,7 +727,10 @@ static uint16_t gd5429_readw(uint32_t addr, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - return svga_readw_linear(addr, &gd5429->svga); + + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readw_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8); } static uint32_t gd5429_readl(uint32_t addr, void *p) { @@ -723,7 +739,11 @@ static uint32_t gd5429_readl(uint32_t addr, void *p) addr &= svga->banked_mask; addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - return svga_readl_linear(addr, &gd5429->svga); + + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readl_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8) | + (gd5429_read_linear(addr+2, gd5429) << 16) | (gd5429_read_linear(addr+3, gd5429) << 24); } void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) @@ -731,7 +751,7 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) gd5429_t *gd5429 = (gd5429_t *)p; svga_t *svga = &gd5429->svga; uint8_t vala, valb, valc, vald, wm = svga->writemask; - int writemask2 = svga->writemask; + int writemask2 = svga->seqregs[2]; cycles -= video_timing_write_b; cycles_lost += video_timing_write_b; @@ -741,7 +761,9 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) // if (svga_output) pclog("Write LFB %08X %02X ", addr, val); if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) + if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + addr <<= 3; + else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; @@ -818,7 +840,6 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) else { // pclog("Writemode 4 : %X ", addr); - addr <<= 1; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); if (val & svga->seqregs[2] & 0x80) @@ -891,7 +912,6 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) else { // pclog("Writemode 5 : %X ", addr); - addr <<= 1; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); if (svga->seqregs[2] & 0x80) @@ -914,10 +934,27 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) break; case 1: - if (writemask2 & 1) svga->vram[addr] = svga->la; - if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; - if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; - if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; + if (svga->gdcreg[0xb] & GRB_WRITEMODE_EXT) + { + if (writemask2 & 0x80) svga->vram[addr] = svga->la; + if (writemask2 & 0x40) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 0x20) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 0x10) svga->vram[addr | 0x3] = svga->ld; + if (svga->gdcreg[0xb] & GRB_8B_LATCHES) + { + if (writemask2 & 0x08) svga->vram[addr | 0x4] = gd5429->latch_ext[0]; + if (writemask2 & 0x04) svga->vram[addr | 0x5] = gd5429->latch_ext[1]; + if (writemask2 & 0x02) svga->vram[addr | 0x6] = gd5429->latch_ext[2]; + if (writemask2 & 0x01) svga->vram[addr | 0x7] = gd5429->latch_ext[3]; + } + } + else + { + if (writemask2 & 1) svga->vram[addr] = svga->la; + if (writemask2 & 2) svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) svga->vram[addr | 0x3] = svga->ld; + } break; case 0: if (svga->gdcreg[3] & 7) @@ -1055,13 +1092,92 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) } } +uint8_t gd5429_read_linear(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + uint8_t temp, temp2, temp3, temp4; + int readplane = svga->readplane; + uint32_t latch_addr = (addr << 2) & svga->decode_mask; + + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; + + egareads++; + + if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + addr <<= 3; + else if (svga->chain4 || svga->fb_only) + { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + return svga->vram[addr & svga->vram_mask]; + } + else if (svga->chain2_read) + { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; + } + else + addr<<=2; + + addr &= svga->decode_mask; + + if (latch_addr >= svga->vram_max) + { + svga->la = svga->lb = svga->lc = svga->ld = 0xff; + if (svga->gdcreg[0xb] & GRB_8B_LATCHES) + gd5429->latch_ext[0] = gd5429->latch_ext[1] = gd5429->latch_ext[2] = gd5429->latch_ext[3] = 0xff; + } + else + { + latch_addr &= svga->vram_mask; + 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]; + if (svga->gdcreg[0xb] & GRB_8B_LATCHES) + { + gd5429->latch_ext[0] = svga->vram[latch_addr | 0x4]; + gd5429->latch_ext[1] = svga->vram[latch_addr | 0x5]; + gd5429->latch_ext[2] = svga->vram[latch_addr | 0x6]; + gd5429->latch_ext[3] = svga->vram[latch_addr | 0x7]; + } + } + + if (addr >= svga->vram_max) + return 0xff; + + addr &= svga->vram_mask; + + if (svga->readmode) + { + temp = svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 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]; +} + static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; gd5429_t *gd5429 = (gd5429_t *)svga->p; -// pclog("gd5429_writeb : %08X %02X\n", addr, val); - if (svga->writemode < 4) + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_write_linear(addr, val, svga); else gd5429_write_linear(addr, val & 0xff, gd5429); @@ -1071,8 +1187,7 @@ static void gd5429_writew_linear(uint32_t addr, uint16_t val, void *p) svga_t *svga = (svga_t *)p; gd5429_t *gd5429 = (gd5429_t *)svga->p; -// pclog("gd5429_writew : %08X %04X\n", addr, val); - if (svga->writemode < 4) + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_writew_linear(addr, val, svga); else { @@ -1085,8 +1200,7 @@ static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p) svga_t *svga = (svga_t *)p; gd5429_t *gd5429 = (gd5429_t *)svga->p; -// pclog("gd5429_writel : %08X %08X %i\n", addr, val, svga->writemode); - if (svga->writemode < 4) + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_writel_linear(addr, val, svga); else { @@ -1096,7 +1210,36 @@ static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p) gd5429_write_linear(addr+3, val >> 24, gd5429); } } - + +static uint8_t gd5429_readb_linear(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_read_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429); +} +static uint16_t gd5429_readw_linear(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readw_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8); +} +static uint32_t gd5429_readl_linear(uint32_t addr, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readl_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr+1, gd5429) << 8) | + (gd5429_read_linear(addr+2, gd5429) << 16) | (gd5429_read_linear(addr+3, gd5429) << 24); +} + void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { @@ -1685,13 +1828,16 @@ static void *cl_init(int type, char *fn, int pci_card) memset(gd5429, 0, sizeof(gd5429_t)); vram_size = device_get_config_int("memory"); - gd5429->vram_mask = (vram_size << 20) - 1; + if (vram_size >= 256) + gd5429->vram_mask = (vram_size << 10) - 1; + else + gd5429->vram_mask = (vram_size << 20) - 1; gd5429->type = type; rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&gd5429->svga, gd5429, vram_size << 20, + svga_init(&gd5429->svga, gd5429, (vram_size >= 256) ? (vram_size << 10) : (vram_size << 20), gd5429_recalctimings, gd5429_in, gd5429_out, gd5429_hwcursor_draw, @@ -1701,9 +1847,15 @@ static void *cl_init(int type, char *fn, int pci_card) mem_mapping_set_p(&gd5429->svga.mapping, gd5429); mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); - mem_mapping_add(&gd5429->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga); + mem_mapping_add(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga); io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (type == CL_TYPE_AVGA2) + { + io_sethandler(0x0102, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + svga->decode_mask = svga->vram_mask; + } svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -1741,6 +1893,10 @@ static void *cl_init(int type, char *fn, int pci_card) } +static void *avga2_cbm_sl386sx_init() +{ + return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1); +} static void *gd5429_init() { return cl_init(CL_TYPE_GD5429, "5429.vbi", -1); @@ -1805,6 +1961,33 @@ void gd5429_add_status_info(char *s, int max_len, void *p) svga_add_status_info(s, max_len, &gd5429->svga); } +static device_config_t avga2_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "256 kB", + .value = 256 + }, + { + .description = "512 kB", + .value = 512 + }, + { + .description = "" + } + }, + .default_int = 512 + }, + { + .type = -1 + } +}; + static device_config_t gd5429_config[] = { { @@ -1858,6 +2041,19 @@ static device_config_t gd5434_config[] = } }; +device_t avga2_cbm_sl386sx_device = +{ + "AVGA2 (Commodore SL386SX-25)", + 0, + avga2_cbm_sl386sx_init, + gd5429_close, + gd5430_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + avga2_config +}; + device_t gd5429_device = { "Cirrus Logic GD5429", diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index a045e6e..9398b27 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1,3 +1,4 @@ +extern device_t avga2_cbm_sl386sx_device; extern device_t gd5429_device; extern device_t gd5430_device; extern device_t gd5430_pb570_device; diff --git a/src/video.c b/src/video.c index 3b31973..9200938 100644 --- a/src/video.c +++ b/src/video.c @@ -130,6 +130,7 @@ static video_timings_t timing_pc200 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_m24 = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_pvga1a = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_wd90c11 = {VIDEO_ISA, 3, 3, 6, 5, 5,10}; +static video_timings_t timing_avga2 = {VIDEO_ISA, 3, 3, 6, 5, 5,10}; static video_timings_t timing_oti067 = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; @@ -242,6 +243,9 @@ device_t *video_card_getdevice(int card, int romset) case ROM_PB520R: return &gd5434_pb520r_device; + + case ROM_CBM_SL386SX25: + return &avga2_cbm_sl386sx_device; } return video_cards[card].device; } @@ -365,6 +369,7 @@ int video_is_mda() case ROM_PB410A: case ROM_PB570: case ROM_PB520R: + case ROM_CBM_SL386SX25: return 0; } return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA; @@ -411,6 +416,7 @@ int video_is_cga() case ROM_PB410A: case ROM_PB570: case ROM_PB520R: + case ROM_CBM_SL386SX25: return 0; } return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA; @@ -449,6 +455,7 @@ int video_is_ega_vga() case ROM_PB410A: case ROM_PB570: case ROM_PB520R: + case ROM_CBM_SL386SX25: return 1; } return (video_cards[video_old_to_new(gfxcard)].flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL; @@ -614,6 +621,10 @@ void video_updatetiming() case ROM_PB520R: timing = &timing_pb520r; break; + + case ROM_CBM_SL386SX25: + timing = &timing_avga2; + break; } @@ -813,6 +824,10 @@ void video_init() break; } return; + + case ROM_CBM_SL386SX25: + device_add(&avga2_cbm_sl386sx_device); + return; } device_add(video_cards[video_old_to_new(gfxcard)].device); } From a140d2631511f315ba259b37a813cb008077b0e1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 15 Jan 2020 19:59:33 +0000 Subject: [PATCH 0757/1050] Fix some offset size checks in instruction generation code. --- src/codegen_backend_x86-64_ops.c | 2 +- src/codegen_backend_x86_ops.c | 2 +- src/codegen_backend_x86_ops_sse.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index c017699..c32cd26 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1014,7 +1014,7 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ codegen_addlong(block, imm_data); } - else if (offset >= -80 || offset < 0x80) + else if (offset >= -0x80 && offset < 0x80) { codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 41ab522..23726eb 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -759,7 +759,7 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ codegen_addlong(block, imm_data); } - else if (offset >= -80 || offset < 0x80) + else if (offset >= -0x80 && offset < 0x80) { codegen_alloc_bytes(block, 8); codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ diff --git a/src/codegen_backend_x86_ops_sse.c b/src/codegen_backend_x86_ops_sse.c index ed603e7..50ec638 100644 --- a/src/codegen_backend_x86_ops_sse.c +++ b/src/codegen_backend_x86_ops_sse.c @@ -200,7 +200,7 @@ void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ codegen_addbyte(block, 0x24); } - else if (offset >= -80 || offset < 0x80) + else if (offset >= -0x80 && offset < 0x80) { codegen_alloc_bytes(block, 6); codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ From 22977a4ff7246766a2a44826e666238b0403b10e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 15 Jan 2020 20:00:04 +0000 Subject: [PATCH 0758/1050] Reset purgable page list on reset. Fixes crashes when switching between machines. --- src/mem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mem.c b/src/mem.c index a7545a1..8c23410 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1486,6 +1486,9 @@ void mem_alloc() mem_a20_key = 2; mem_a20_alt = 0; mem_a20_recalc(); + + purgable_page_list_head = 0; + purgeable_page_count = 0; } void mem_reset_page_blocks() From 483c7db70924b58c61426ab3fa84cc65b9d1ff13 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 15 Jan 2020 22:17:36 +0000 Subject: [PATCH 0759/1050] Added Matrox Mystique emulation. This is a work in progress, and has a few known issues : - Only YUV supported for scaled ILOAD operations - Several BLTMOD formats missing - Bad texturing in Actua Soccer - Flickering in Croc (broken vsync waiting?) - Turok doesn't swap buffers correctly - Some missing features --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/ibm.h | 2 + src/thread.h | 6 + src/vid_mga.c | 5130 ++++++++++++++++++++++++++++ src/vid_mga.h | 1 + src/vid_svga.c | 18 +- src/vid_svga.h | 5 + src/video.c | 2 + src/wx-thread.c | 37 + 11 files changed, 5199 insertions(+), 8 deletions(-) create mode 100644 src/vid_mga.c create mode 100644 src/vid_mga.h diff --git a/src/Makefile.am b/src/Makefile.am index 89e5664..b74eb1f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,7 @@ sound_sb.c sound_sb_dsp.c sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_ sst39sf010.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c \ vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c \ -vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ +vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c vt82c586b.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 61af689..1aa71d7 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -33,7 +33,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 60dd89c..0297862 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -33,7 +33,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ - vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ diff --git a/src/ibm.h b/src/ibm.h index 370ccbf..b5d2c83 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -302,6 +302,8 @@ enum GFX_PGC, /*Professional Graphics Controller */ GFX_IM1024, /*Vermont Microsystems IM1024 */ GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/ + GFX_MYSTIQUE, /*Matrox Mystique*/ + GFX_MAX }; diff --git a/src/thread.h b/src/thread.h index fb47f28..0fe75aa 100644 --- a/src/thread.h +++ b/src/thread.h @@ -9,4 +9,10 @@ void thread_reset_event(event_t *_event); int thread_wait_event(event_t *event, int timeout); void thread_destroy_event(event_t *_event); +typedef void mutex_t; +mutex_t *thread_create_mutex(void); +void thread_lock_mutex(mutex_t *mutex); +void thread_unlock_mutex(mutex_t *mutex); +void thread_destroy_mutex(mutex_t *mutex); + void thread_sleep(int t); diff --git a/src/vid_mga.c b/src/vid_mga.c new file mode 100644 index 0000000..97cf402 --- /dev/null +++ b/src/vid_mga.c @@ -0,0 +1,5130 @@ +/*Matrox Mystique emulation*/ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "thread.h" +#include "video.h" +#include "vid_mga.h" +#include "vid_svga.h" +#include "vid_svga_render.h" + +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) +#define FIFO_THRESHOLD 0xe000 + +#define WAKE_DELAY (100 * TIMER_USEC) /*100us*/ + +#define FIFO_ENTRIES (mystique->fifo_write_idx - mystique->fifo_read_idx) +#define FIFO_FULL ((mystique->fifo_write_idx - mystique->fifo_read_idx) >= (FIFO_SIZE-1)) +#define FIFO_EMPTY (mystique->fifo_read_idx == mystique->fifo_write_idx) + +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff + +enum +{ + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_CTRL_BYTE = (0x01 << 24), + FIFO_WRITE_CTRL_LONG = (0x02 << 24), + FIFO_WRITE_ILOAD_LONG = (0x03 << 24) +}; + +typedef struct +{ + uint32_t addr_type; + uint32_t val; +} fifo_entry_t; + +typedef struct mystique_t +{ + svga_t svga; + + rom_t bios_rom; + + mem_mapping_t lfb_mapping; + mem_mapping_t ctrl_mapping; + mem_mapping_t iload_mapping; + + uint8_t pci_regs[256]; + uint8_t int_line; + int card; + + int vram_size; + uint32_t vram_mask, vram_mask_w, vram_mask_l; + + uint32_t lfb_base, ctrl_base, iload_base; + + uint8_t crtcext_regs[6]; + int crtcext_idx; + + uint8_t xreg_regs[256]; + int xreg_idx; + + uint32_t ma_latch_old; + + uint32_t maccess, mctlwtst; + uint32_t maccess_running; + + uint32_t status; + + uint8_t xcurctrl; + + uint8_t xsyspllm, xsysplln, xsyspllp; + struct + { + int m, n, p, s; + } xpixpll[3]; + + uint8_t xgenioctrl; + uint8_t xgeniodata; + uint8_t xmulctrl; + uint8_t xgenctrl; + uint8_t xmiscctrl; + uint8_t xpixclkctrl; + uint8_t xvrefctrl; + int xzoomctrl; + + uint8_t ien; + + struct + { + uint8_t funcnt, stylelen; + int xoff, yoff; + + uint16_t cxleft, cxright; + int16_t fxleft, fxright; + uint16_t length; + + uint32_t dwgctrl; + uint32_t dwgctrl_running; + uint32_t bcol, fcol; + uint32_t pitch; + uint32_t plnwt; + uint32_t ybot; + uint32_t ydstorg; + uint32_t ytop; + int selline; + + uint32_t src[4]; + uint32_t ar[7]; + uint32_t dr[16]; + + int pattern[8][8]; + + struct + { + int sdydxl; + int scanleft; + int sdxl; + int sdy; + int sdxr; + } sgn; + + uint32_t tmr[9]; + uint32_t texorg, texwidth, texheight; + uint32_t texctl, textrans; + uint32_t zorg; + + int ydst; + uint32_t ydst_lin; + + int length_cur; + int16_t xdst; + uint32_t src_addr; + uint32_t z_base; + + int iload_rem_count; + uint32_t iload_rem_data; + int idump_end_of_line; + + int words; + + int ta_key, ta_mask; + + int lastpix_r, lastpix_g, lastpix_b; + + int highv_line; + uint32_t highv_data; + + int beta; + + int dither; + + uint8_t dmamod; + } dwgreg; + + struct + { + uint8_t r, g, b; + } lut[256]; + + struct + { + uint16_t pos_x, pos_y; + uint16_t addr; + uint32_t col[3]; + } cursor; + + uint8_t dmamod, dmadatasiz, dirdatasiz; + struct + { + uint32_t primaddress, primend; + uint32_t secaddress, secend; + + int pri_pos, sec_pos, iload_pos; + uint32_t pri_header, sec_header, iload_header; + + int pri_state, sec_state, iload_state; + + int state; + + mutex_t *lock; +// pc_timer_t timer; + } dma; + + uint8_t dmamap[16]; + + volatile int busy; + volatile int blitter_submit_refcount; + volatile int blitter_submit_dma_refcount; + volatile int blitter_complete_refcount; + + volatile int endprdmasts_pending; + volatile int softrap_pending; + uint32_t softrap_pending_val; + + pc_timer_t softrap_pending_timer; + + uint64_t blitter_time; + uint64_t status_time; + + int pixel_count, trap_count; + + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; + + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; + + pc_timer_t wake_timer; +} mystique_t; + +static void mystique_start_blit(mystique_t *mystique); +static void mystique_update_irqs(mystique_t *mystique); + +static void wake_fifo_thread(mystique_t *mystique); +static void wait_fifo_idle(mystique_t *mystique); +static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); + +static const uint8_t trans_masks[16][16] = +{ + { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 + }, + { + 1, 0, 1, 0, + 0, 1, 0, 1, + 1, 0, 1, 0, + 0, 1, 0, 1 + }, + { + 0, 1, 0, 1, + 1, 0, 1, 0, + 0, 1, 0, 1, + 1, 0, 1, 0 + }, + { + 1, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 1, 0, + 0, 0, 0, 0 + }, + { + 0, 1, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 1, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 1, 0 + }, + { + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 1 + }, + { + 1, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1 + }, + { + 0, 0, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0 + }, + { + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 0 + }, + { + 0, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + } +}; + +static int8_t dither5[256][2][2]; +static int8_t dither6[256][2][2]; + +enum +{ + DMA_STATE_IDLE = 0, + DMA_STATE_PRI, + DMA_STATE_SEC +}; + +#define DMA_POLL_TIME_US 100 /*100us*/ +#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ + +/*These registers are also mirrored into 0x1dxx, with the mirrored versions starting + the blitter*/ +#define REG_DWGCTL 0x1c00 +#define REG_MACCESS 0x1c04 +#define REG_MCTLWTST 0x1c08 +#define REG_ZORG 0x1c0c +#define REG_PAT0 0x1c10 +#define REG_PAT1 0x1c14 +#define REG_PLNWT 0x1c1c +#define REG_BCOL 0x1c20 +#define REG_FCOL 0x1c24 +#define REG_SRC0 0x1c30 +#define REG_SRC1 0x1c34 +#define REG_SRC2 0x1c38 +#define REG_SRC3 0x1c3c +#define REG_XYSTRT 0x1c40 +#define REG_XYEND 0x1c44 +#define REG_SHIFT 0x1c50 +#define REG_DMAPAD 0x1c54 +#define REG_SGN 0x1c58 +#define REG_LEN 0x1c5c +#define REG_AR0 0x1c60 +#define REG_AR1 0x1c64 +#define REG_AR2 0x1c68 +#define REG_AR3 0x1c6c +#define REG_AR4 0x1c70 +#define REG_AR5 0x1c74 +#define REG_AR6 0x1c78 +#define REG_CXBNDRY 0x1c80 +#define REG_FXBNDRY 0x1c84 +#define REG_YDSTLEN 0x1c88 +#define REG_PITCH 0x1c8c +#define REG_YDST 0x1c90 +#define REG_YDSTORG 0x1c94 +#define REG_YTOP 0x1c98 +#define REG_YBOT 0x1c9c +#define REG_CXLEFT 0x1ca0 +#define REG_CXRIGHT 0x1ca4 +#define REG_FXLEFT 0x1ca8 +#define REG_FXRIGHT 0x1cac +#define REG_XDST 0x1cb0 +#define REG_DR0 0x1cc0 +#define REG_DR2 0x1cc8 +#define REG_DR3 0x1ccc +#define REG_DR4 0x1cd0 +#define REG_DR6 0x1cd8 +#define REG_DR7 0x1cdc +#define REG_DR8 0x1ce0 +#define REG_DR10 0x1ce8 +#define REG_DR11 0x1cec +#define REG_DR12 0x1cf0 +#define REG_DR14 0x1cf8 +#define REG_DR15 0x1cfc + +#define REG_FIFOSTATUS 0x1e10 +#define REG_STATUS 0x1e14 +#define REG_ICLEAR 0x1e18 +#define REG_IEN 0x1e1c +#define REG_VCOUNT 0x1e20 +#define REG_DMAMAP 0x1e30 +#define REG_RST 0x1e40 +#define REG_OPMODE 0x1e54 +#define REG_PRIMADDRESS 0x1e58 +#define REG_PRIMEND 0x1e5c +#define REG_DWG_INDIR_WT 0x1e80 + +#define REG_INSTS0 0x1fc2 +#define REG_MISC 0x1fc2 +#define REG_SEQ_IDX 0x1fc4 +#define REG_SEQ_DATA 0x1fc5 +#define REG_MISCREAD 0x1fcc +#define REG_CRTC_IDX 0x1fd4 +#define REG_CRTC_DATA 0x1fd5 +#define REG_INSTS1 0x1fda +#define REG_CRTCEXT_IDX 0x1fde +#define REG_CRTCEXT_DATA 0x1fdf +#define REG_CACHEFLUSH 0x1fff + +#define REG_TMR0 0x2c00 +#define REG_TMR1 0x2c04 +#define REG_TMR2 0x2c08 +#define REG_TMR3 0x2c0c +#define REG_TMR4 0x2c10 +#define REG_TMR5 0x2c14 +#define REG_TMR6 0x2c18 +#define REG_TMR7 0x2c1c +#define REG_TMR8 0x2c20 +#define REG_TEXORG 0x2c24 +#define REG_TEXWIDTH 0x2c28 +#define REG_TEXHEIGHT 0x2c2c +#define REG_TEXCTL 0x2c30 +#define REG_TEXTRANS 0x2c34 +#define REG_SECADDRESS 0x2c40 +#define REG_SECEND 0x2c44 +#define REG_SOFTRAP 0x2c48 + +#define REG_PALWTADD 0x3c00 +#define REG_PALDATA 0x3c01 +#define REG_PIXRDMSK 0x3c02 +#define REG_PALRDADD 0x3c03 +#define REG_X_DATAREG 0x3c0a +#define REG_CURPOSX 0x3c0c +#define REG_CURPOSY 0x3c0e + +#define REG_STATUS_VSYNCSTS (1 << 3) + +#define CRTCX_R0_STARTADD_MASK (0xf << 0) +#define CRTCX_R0_OFFSET_MASK (3 << 4) + +#define CRTCX_R1_HTOTAL8 (1 << 0) + +#define CRTCX_R2_VTOTAL10 (1 << 0) +#define CRTCX_R2_VTOTAL11 (1 << 1) +#define CRTCX_R2_VDISPEND10 (1 << 2) +#define CRTCX_R2_VBLKSTR10 (1 << 3) +#define CRTCX_R2_VBLKSTR11 (1 << 4) +#define CRTCX_R2_VSYNCSTR10 (1 << 5) +#define CRTCX_R2_VSYNCSTR11 (1 << 6) +#define CRTCX_R2_LINECOMP10 (1 << 7) + +#define CRTCX_R3_MGAMODE (1 << 7) + +#define XREG_XCURADDL 0x04 +#define XREG_XCURADDH 0x05 +#define XREG_XCURCTRL 0x06 + +#define XREG_XCURCOL0R 0x08 +#define XREG_XCURCOL0G 0x09 +#define XREG_XCURCOL0B 0x0a + +#define XREG_XCURCOL1R 0x0c +#define XREG_XCURCOL1G 0x0d +#define XREG_XCURCOL1B 0x0e + +#define XREG_XCURCOL2R 0x10 +#define XREG_XCURCOL2G 0x11 +#define XREG_XCURCOL2B 0x12 + +#define XREG_XVREFCTRL 0x18 +#define XREG_XMULCTRL 0x19 +#define XREG_XPIXCLKCTRL 0x1a +#define XREG_XGENCTRL 0x1d +#define XREG_XMISCCTRL 0x1e + +#define XREG_XGENIOCTRL 0x2a +#define XREG_XGENIODATA 0x2b + +#define XREG_XSYSPLLM 0x2c +#define XREG_XSYSPLLN 0x2d +#define XREG_XSYSPLLP 0x2e +#define XREG_XSYSPLLSTAT 0x2f + +#define XREG_XZOOMCTRL 0x38 + +#define XREG_XPIXPLLCM 0x4c +#define XREG_XPIXPLLCN 0x4d +#define XREG_XPIXPLLCP 0x4e +#define XREG_XPIXPLLSTAT 0x4f + +#define XMISCCTRL_VGA8DAC (1 << 3) + +#define XMULCTRL_DEPTH_MASK (7 << 0) +#define XMULCTRL_DEPTH_8 (0 << 0) +#define XMULCTRL_DEPTH_15 (1 << 0) +#define XMULCTRL_DEPTH_16 (2 << 0) +#define XMULCTRL_DEPTH_24 (3 << 0) +#define XMULCTRL_DEPTH_32_OVERLAYED (4 << 0) +#define XMULCTRL_DEPTH_2G8V16 (5 << 0) +#define XMULCTRL_DEPTH_G16V16 (6 << 0) +#define XMULCTRL_DEPTH_32 (7 << 0) + +#define XSYSPLLSTAT_SYSLOCK (1 << 6) + +#define XPIXPLLSTAT_SYSLOCK (1 << 6) + +#define DWGCTRL_OPCODE_MASK (0xf << 0) +#define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0) +#define DWGCTRL_OPCODE_AUTOLINE_OPEN (0x1 << 0) +#define DWGCTRL_OPCODE_AUTOLINE_CLOSE (0x3 << 0) +#define DWGCTRL_OPCODE_TRAP (0x4 << 0) +#define DWGCTRL_OPCODE_TEXTURE_TRAP (0x6 << 0) +#define DWGCTRL_OPCODE_ILOAD_HIGH (0x7 << 0) +#define DWGCTRL_OPCODE_BITBLT (0x8 << 0) +#define DWGCTRL_OPCODE_ILOAD (0x9 << 0) +#define DWGCTRL_OPCODE_IDUMP (0xa << 0) +#define DWGCTRL_OPCODE_ILOAD_SCALE (0xd << 0) +#define DWGCTRL_OPCODE_ILOAD_HIGHV (0xe << 0) +#define DWGCTRL_ATYPE_MASK (7 << 4) +#define DWGCTRL_ATYPE_RPL (0 << 4) +#define DWGCTRL_ATYPE_RSTR (1 << 4) +#define DWGCTRL_ATYPE_ZI (3 << 4) +#define DWGCTRL_ATYPE_BLK (4 << 4) +#define DWGCTRL_ATYPE_I (7 << 4) +#define DWGCTRL_LINEAR (1 << 7) +#define DWGCTRL_ZMODE_MASK (7 << 8) +#define DWGCTRL_ZMODE_NOZCMP (0 << 8) +#define DWGCTRL_ZMODE_ZE (2 << 8) +#define DWGCTRL_ZMODE_ZNE (3 << 8) +#define DWGCTRL_ZMODE_ZLT (4 << 8) +#define DWGCTRL_ZMODE_ZLTE (5 << 8) +#define DWGCTRL_ZMODE_ZGT (6 << 8) +#define DWGCTRL_ZMODE_ZGTE (7 << 8) +#define DWGCTRL_SOLID (1 << 11) +#define DWGCTRL_ARZERO (1 << 12) +#define DWGCTRL_SGNZERO (1 << 13) +#define DWGCTRL_SHTZERO (1 << 14) +#define DWGCTRL_BOP_MASK (0xf << 16) +#define DWGCTRL_TRANS_SHIFT (20) +#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) +#define DWGCTRL_BLTMOD_MASK (0xf << 25) +#define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) +#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) +#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) +#define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) +#define DWGCTRL_BLTMOD_BUYUV (0xe << 25) +#define DWGCTRL_BLTMOD_BU24RGB (0xf << 25) +#define DWGCTRL_PATTERN (1 << 29) +#define DWGCTRL_TRANSC (1 << 30) +#define BOP(x) ((x) << 16) + +#define MACCESS_PWIDTH_MASK (3 << 0) +#define MACCESS_PWIDTH_8 (0 << 0) +#define MACCESS_PWIDTH_16 (1 << 0) +#define MACCESS_PWIDTH_32 (2 << 0) +#define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_TLUTLOAD (1 << 29) +#define MACCESS_NODITHER (1 << 30) +#define MACCESS_DIT555 (1 << 31) + +#define PITCH_MASK 0x7e0 +#define PITCH_YLIN (1 << 15) + +#define SGN_SDYDXL (1 << 0) +#define SGN_SCANLEFT (1 << 0) +#define SGN_SDXL (1 << 1) +#define SGN_SDY (1 << 2) +#define SGN_SDXR (1 << 5) + +#define DMA_ADDR_MASK 0xfffffffc +#define DMA_MODE_MASK 3 + +#define DMA_MODE_REG 0 +#define DMA_MODE_BLIT 1 +#define DMA_MODE_VECTOR 2 + +#define STATUS_SOFTRAPEN (1 << 0) +#define STATUS_VLINEPEN (1 << 5) +#define STATUS_DWGENGSTS (1 << 16) +#define STATUS_ENDPRDMASTS (1 << 17) + +#define ICLEAR_SOFTRAPICLR (1 << 0) +#define ICLEAR_VLINEICLR (1 << 5) + +#define IEN_SOFTRAPEN (1 << 0) + +#define TEXCTL_TEXFORMAT_MASK (7 << 0) +#define TEXCTL_TEXFORMAT_TW4 (0 << 0) +#define TEXCTL_TEXFORMAT_TW8 (1 << 0) +#define TEXCTL_TEXFORMAT_TW15 (2 << 0) +#define TEXCTL_TEXFORMAT_TW16 (3 << 0) +#define TEXCTL_TEXFORMAT_TW12 (4 << 0) +#define TEXCTL_PALSEL_MASK (0xf << 4) +#define TEXCTL_TPITCH_SHIFT (16) +#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_DECALCKEY (1 << 24) +#define TEXCTL_TAKEY (1 << 25) +#define TEXCTL_TAMASK (1 << 26) +#define TEXCTL_CLAMPV (1 << 27) +#define TEXCTL_CLAMPU (1 << 28) +#define TEXCTL_TMODULATE (1 << 29) +#define TEXCTL_STRANS (1 << 30) +#define TEXCTL_ITRANS (1 << 31) + +#define TEXHEIGHT_TH_MASK (0x3f << 0) +#define TEXHEIGHT_THMASK_SHIFT (18) +#define TEXHEIGHT_THMASK_MASK (0x7ff << TEXHEIGHT_THMASK_SHIFT) + +#define TEXWIDTH_TW_MASK (0x3f << 0) +#define TEXWIDTH_TWMASK_SHIFT (18) +#define TEXWIDTH_TWMASK_MASK (0x7ff << TEXWIDTH_TWMASK_SHIFT) + +#define TEXTRANS_TCKEY_MASK (0xffff) +#define TEXTRANS_TKMASK_SHIFT (16) +#define TEXTRANS_TKMASK_MASK (0xffff << TEXTRANS_TKMASK_SHIFT) + +#define DITHER_565 0 +#define DITHER_NONE_565 1 +#define DITHER_555 2 +#define DITHER_NONE_555 3 + +static void mystique_recalc_mapping(mystique_t *mystique); +static int mystique_line_compare(svga_t *svga); + +static uint8_t mystique_iload_read_b(uint32_t addr, void *p); +static uint32_t mystique_iload_read_l(uint32_t addr, void *p); +static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p); +static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p); + +static uint32_t blit_idump_read(mystique_t *mystique); +static void blit_iload_write(mystique_t *mystique, uint32_t data, int size); + +void mystique_out(uint16_t addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t old; + + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; // mono / color addr selection + +// pclog("mystique_out : %04X %02X\n", addr, val); +// pclog(" %04X:%04X\n", CS,cpu_state.pc); + switch (addr) + { + case 0x3c8: + mystique->xreg_idx = val; + break; + + case 0x3cf: + if ((svga->gdcaddr & 15) == 6 && svga->gdcreg[6] != val) + { + svga->gdcreg[svga->gdcaddr & 15] = val; + mystique_recalc_mapping(mystique); + return; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: +// if (svga->crtcreg == 0xc) +// pclog("Buffer swap\n"); + if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) + return; + if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg & 0x3f]; + svga->crtc[svga->crtcreg & 31] = val; + if (old != val) + { + if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) + { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + + case 0x3de: + mystique->crtcext_idx = val; + break; + case 0x3df: + if (mystique->crtcext_idx < 6) + mystique->crtcext_regs[mystique->crtcext_idx] = val; + if (mystique->crtcext_idx < 4) + { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 3) + { + if (val & CRTCX_R3_MGAMODE) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(svga); + +// pclog("Write CRTCX[3]=%02x\n", val); + } + if (mystique->crtcext_idx == 4) + { + if (svga->gdcreg[6] & 0xc) + { + /*64k banks*/ + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } + else + { + /*128k banks*/ + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } +// pclog("Write CRTCX[4]=%02x %08x\n", val, svga->read_bank); + } + break; + + } + svga_out(addr, val, svga); +} + +uint8_t mystique_in(uint16_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t temp = 0xff; + + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; // mono / color addr selection + +// if (addr != 0x3da && addr != 0x3ba) pclog("mystique_in : %04X ", addr); + + switch (addr) + { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg & 0x3f]; + break; + + case 0x3df: + if (mystique->crtcext_idx < 6) + temp = mystique->crtcext_regs[mystique->crtcext_idx]; + break; + + default: + temp = svga_in(addr, svga); + break; + } + +// if (addr != 0x3da && addr != 0x3ba) pclog("%02X\n", temp); + return temp; +} + +static int mystique_line_compare(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *)svga->p; + + mystique->status |= STATUS_VLINEPEN; + mystique_update_irqs(mystique); + + return 0; +} + +void mystique_recalctimings(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *)svga->p; + int clk_sel = (svga->miscout >> 2) & 3; + + if (clk_sel & 2) + { + int m = mystique->xpixpll[2].m; + int n = mystique->xpixpll[2].n; + int p = mystique->xpixpll[2].p; + + double fvco = 14318181.0 * (n + 1) / (m + 1); + double fo = fvco / (p + 1); + +// pclog("m=%i n=%i p=%i fo=%g\n", m, n, p, fo); + svga->clock = (cpuclock * (float)(1ull << 32)) / fo; + } + + if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) + svga->htotal += 0x100; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) + svga->vtotal += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) + svga->vtotal += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) + svga->dispend += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) + svga->vblankstart += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) + svga->vblankstart += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) + svga->vsyncstart += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) + svga->vsyncstart += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) + svga->split += 0x400; +// pclog("svga->split=%i\n", svga->split); + + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) + { + int row_offset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + +// svga->split = 99999; + svga->lowres = 0; + svga->rowoffset = row_offset * 2; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 17) | + (svga->crtc[0xc] << 9) | (svga->crtc[0xd] << 1); + + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + if (svga->ma_latch != mystique->ma_latch_old) + { +// pclog("ma_latch change: old=%08x new=%08x ma=%08x ", mystique->ma_latch_old, svga->ma_latch, svga->maback); + svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); +// pclog("ma_new=%08x\n", svga->maback); + mystique->ma_latch_old = svga->ma_latch; + } + + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) + { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; + } + + svga->line_compare = mystique_line_compare; +// pclog("recalc: htotal=%i vtotal=%i dispend=%i\n", svga->htotal, svga->vtotal, svga->dispend); + } + else + { + svga->line_compare = NULL; + svga->bpp = 8; + } +} + +static void mystique_recalc_mapping(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + + io_removehandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + if ((mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (mystique->pci_regs[0x41] & 1)) + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + + if (!(mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mystique->ctrl_mapping); + mem_mapping_disable(&mystique->lfb_mapping); + mem_mapping_disable(&mystique->iload_mapping); + return; + } + + mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); + + if (mystique->pci_regs[0x41] & 1) + { + switch (svga->gdcreg[6] & 0x0C) + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0x1ffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + if (svga->gdcreg[6] & 0xc) + { + /*64k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + } + else + { + /*128k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + } + } + else + mem_mapping_disable(&svga->mapping); +} + +static void mystique_update_irqs(mystique_t *mystique) +{ + int irq = 0; + + if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) + irq = 1; + + if (irq) + pci_set_irq(mystique->card, PCI_INTA); + else + pci_clear_irq(mystique->card, PCI_INTA); +} + +#define READ8(addr, var) switch ((addr) & 3) \ + { \ + case 0: ret = (var) & 0xff; break; \ + case 1: ret = ((var) >> 8) & 0xff; break; \ + case 2: ret = ((var) >> 16) & 0xff; break; \ + case 3: ret = ((var) >> 24) & 0xff; break; \ + } + +#define WRITE8(addr, var, val) switch ((addr) & 3) \ + { \ + case 0: var = (var & 0xffffff00) | (val); break; \ + case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ + case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ + case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ + } + +static uint8_t mystique_read_xreg(mystique_t *mystique, int reg) +{ + uint8_t ret = 0xff; + + switch (reg) + { + case XREG_XCURADDL: + ret = mystique->cursor.addr & 0xff; + break; + case XREG_XCURADDH: + ret = mystique->cursor.addr >> 8; + break; + case XREG_XCURCTRL: + ret = mystique->xcurctrl; + break; + + case XREG_XCURCOL0R: case XREG_XCURCOL0G: case XREG_XCURCOL0B: + READ8(reg, mystique->cursor.col[0]); + break; + case XREG_XCURCOL1R: case XREG_XCURCOL1G: case XREG_XCURCOL1B: + READ8(reg, mystique->cursor.col[1]); + break; + case XREG_XCURCOL2R: case XREG_XCURCOL2G: case XREG_XCURCOL2B: + READ8(reg, mystique->cursor.col[2]); + break; + + case XREG_XMULCTRL: + ret = mystique->xmulctrl; + break; + + case XREG_XMISCCTRL: + ret = mystique->xmiscctrl; + break; + + case XREG_XGENCTRL: + ret = mystique->xgenctrl; + break; + + case XREG_XGENIOCTRL: + ret = mystique->xgenioctrl; + break; + case XREG_XGENIODATA: + ret = mystique->xgeniodata; + break; + + case XREG_XSYSPLLM: + ret = mystique->xsyspllm; + break; + case XREG_XSYSPLLN: + ret = mystique->xsysplln; + break; + case XREG_XSYSPLLP: + ret = mystique->xsyspllp; + break; + + case XREG_XZOOMCTRL: + ret = mystique->xzoomctrl; + break; + + case XREG_XPIXCLKCTRL: + ret = mystique->xpixclkctrl; + break; + + case XREG_XSYSPLLSTAT: + ret = XSYSPLLSTAT_SYSLOCK; + break; + + case XREG_XPIXPLLSTAT: + ret = XPIXPLLSTAT_SYSLOCK; + break; + + case XREG_XPIXPLLCM: + ret = mystique->xpixpll[2].m; + break; + case XREG_XPIXPLLCN: + ret = mystique->xpixpll[2].n; + break; + case XREG_XPIXPLLCP: + ret = mystique->xpixpll[2].p | (mystique->xpixpll[2].s << 3); + break; + + case 0x00: case 0x20: case 0x3f: + ret = 0xff; + break; + + default: + if (reg >= 0x50) + ret = 0xff; + else + fatal("Read XREG %02x\n", reg); + break; + } + return ret; +} + +static void mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) +{ + svga_t *svga = &mystique->svga; + + switch (reg) + { + case XREG_XCURADDL: + mystique->cursor.addr = (mystique->cursor.addr & 0x1f00) | val; + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; + case XREG_XCURADDH: + mystique->cursor.addr = (mystique->cursor.addr & 0x00ff) | ((val & 0x1f) << 8); + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; + + case XREG_XCURCTRL: + mystique->xcurctrl = val; + svga->hwcursor.ena = (val & 3) ? 1 : 0; + break; + + case XREG_XCURCOL0R: case XREG_XCURCOL0G: case XREG_XCURCOL0B: + WRITE8(reg, mystique->cursor.col[0], val); + break; + case XREG_XCURCOL1R: case XREG_XCURCOL1G: case XREG_XCURCOL1B: + WRITE8(reg, mystique->cursor.col[1], val); + break; + case XREG_XCURCOL2R: case XREG_XCURCOL2G: case XREG_XCURCOL2B: + WRITE8(reg, mystique->cursor.col[2], val); + break; + + case XREG_XMULCTRL: + mystique->xmulctrl = val; + break; + + case XREG_XMISCCTRL: + mystique->xmiscctrl = val; + svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; + + case XREG_XGENCTRL: + mystique->xgenctrl = val; + break; + + case XREG_XVREFCTRL: + mystique->xvrefctrl = val; + break; + + case XREG_XGENIOCTRL: + mystique->xgenioctrl = val; + break; + case XREG_XGENIODATA: + mystique->xgeniodata = val; + break; + + case XREG_XSYSPLLM: + mystique->xsyspllm = val; + break; + case XREG_XSYSPLLN: + mystique->xsysplln = val; + break; + case XREG_XSYSPLLP: + mystique->xsyspllp = val; + break; + + case XREG_XZOOMCTRL: + mystique->xzoomctrl = val & 3; + break; + + case XREG_XPIXCLKCTRL: + mystique->xpixclkctrl = val; + break; + + case XREG_XPIXPLLCM: + mystique->xpixpll[2].m = val; + break; + case XREG_XPIXPLLCN: + mystique->xpixpll[2].n = val; + break; + case XREG_XPIXPLLCP: + mystique->xpixpll[2].p = val & 7; + mystique->xpixpll[2].s = (val >> 3) & 3; + break; + + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x07: case 0x0b: case 0x0f: + case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x1b: case 0x1c: case 0x20: case 0x39: case 0x3b: case 0x3f: + case 0x47: case 0x4b: + break; + + default: + if (reg < 0x50) + fatal("Write XREG %02x %02x\n", reg, val); + break; + } +} + +static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t ret = 0xff; + int fifocount; + +// pclog("mystique read %04x %08x\n", addr & 0x3fff, cpu_state.pc); + + switch (addr & 0x3fff) + { + case REG_FIFOSTATUS: + fifocount = FIFO_SIZE - FIFO_ENTRIES; + if (fifocount > 64) + fifocount = 64; + ret = fifocount; + break; + case REG_FIFOSTATUS+1: + if (FIFO_EMPTY) + ret |= 2; + else if (FIFO_ENTRIES >= 64) + ret |= 1; +// ret = 2; /*Empty*/ + break; + case REG_FIFOSTATUS+2: case REG_FIFOSTATUS+3: + ret = 0; + break; + + case REG_STATUS: + ret = mystique->status & 0xff; + if (svga->cgastat & 8) + ret |= REG_STATUS_VSYNCSTS; +// pclog("REG_STATUS %02x\n", ret); + break; + case REG_STATUS+1: + ret = (mystique->status >> 8) & 0xff; + break; + case REG_STATUS+2: + ret = (mystique->status >> 16) & 0xff; + if (mystique->busy || + ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || + !FIFO_EMPTY) + ret |= (STATUS_DWGENGSTS >> 16); +/* thread_lock_mutex(mystique->dma.lock); + if (mystique->dma.state == DMA_STATE_IDLE) + ret |= (STATUS_ENDPRDMASTS >> 16); + thread_unlock_mutex(mystique->dma.lock);*/ +/* pclog("Read status %02x %i %i %i fifo=%i\n", ret, mystique->busy, + ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount), + !FIFO_EMPTY, FIFO_ENTRIES);*/ +// ret |= 2; + break; + case REG_STATUS+3: + ret = (mystique->status >> 24) & 0xff; + break; + + case REG_IEN: + ret = mystique->ien & 0x64; + break; + case REG_IEN+1: case REG_IEN+2: case REG_IEN+3: + ret = 0; + break; + + case REG_OPMODE: + ret = mystique->dmamod << 2; + break; + case REG_OPMODE+1: + ret = mystique->dmadatasiz; + break; + case REG_OPMODE+2: + ret = mystique->dirdatasiz; + break; + case REG_OPMODE+3: + break; + + case REG_PRIMADDRESS: case REG_PRIMADDRESS+1: case REG_PRIMADDRESS+2: case REG_PRIMADDRESS+3: + READ8(addr, mystique->dma.primaddress); + break; + case REG_PRIMEND: case REG_PRIMEND+1: case REG_PRIMEND+2: case REG_PRIMEND+3: + READ8(addr, mystique->dma.primend); + break; + + case REG_SECADDRESS: case REG_SECADDRESS+1: case REG_SECADDRESS+2: case REG_SECADDRESS+3: + READ8(addr, mystique->dma.secaddress); + break; + + case REG_VCOUNT: case REG_VCOUNT+1: case REG_VCOUNT+2: case REG_VCOUNT+3: + READ8(addr, svga->vc); + break; + + case REG_INSTS0: + ret = svga_in(0x3c2, svga); + break; + + case REG_SEQ_IDX: + ret = svga_in(0x3c4, svga); + break; + case REG_SEQ_DATA: + ret = svga_in(0x3c5, svga); + break; + + case REG_MISCREAD: + ret = svga_in(0x3cc, svga); + break; + + case REG_CRTC_IDX: + ret = mystique_in(0x3d4, mystique); + break; + case REG_CRTC_DATA: + ret = mystique_in(0x3d5, mystique); + break; + + case REG_INSTS1: + ret = mystique_in(0x3da, mystique); + break; + + case REG_CRTCEXT_IDX: + ret = mystique_in(0x3de, mystique); + break; + case REG_CRTCEXT_DATA: + ret = mystique_in(0x3df, mystique); + break; + + case REG_PALWTADD: + ret = svga_in(0x3c8, svga); + break; + case REG_PALDATA: + ret = svga_in(0x3c9, svga); + break; + case REG_PIXRDMSK: + ret = svga_in(0x3c6, svga); + break; + case REG_PALRDADD: + ret = svga_in(0x3c7, svga); + break; + + case REG_X_DATAREG: + ret = mystique_read_xreg(mystique, mystique->xreg_idx); + break; + + case REG_ICLEAR: case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: + case 0x2c30: case 0x2c31: case 0x2c32: case 0x2c33: + case 0x3e08: + break; + + default: + if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) + break; + fatal("Read MGA control %08x\n", addr & 0x3fff); + } + +// pclog("mcrb: addr=%08x ret=%02x\n", addr, ret); + return ret; +} + +static void mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + int start_blit = 0; + int x; + +// pclog("mystique accel addr=%04x val=%02x\n", addr & 0x3fff, val); + + if ((addr & 0x300) == 0x100) + { + addr &= ~0x100; + start_blit = 1; + } + + switch (addr & 0x3fff) + { + case REG_MACCESS: case REG_MACCESS+1: case REG_MACCESS+2: case REG_MACCESS+3: + WRITE8(addr, mystique->maccess, val); + mystique->dwgreg.dither = mystique->maccess >> 30; + break; + + case REG_MCTLWTST: case REG_MCTLWTST+1: case REG_MCTLWTST+2: case REG_MCTLWTST+3: + WRITE8(addr, mystique->mctlwtst, val); + break; + + + case REG_PAT0: case REG_PAT0+1: case REG_PAT0+2: case REG_PAT0+3: + case REG_PAT1: case REG_PAT1+1: case REG_PAT1+2: case REG_PAT1+3: + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7-x)); + break; + + case REG_XYSTRT: case REG_XYSTRT+1: + WRITE8(addr&1, mystique->dwgreg.ar[5], val); + if (mystique->dwgreg.ar[5] & 0x8000) + mystique->dwgreg.ar[5] |= 0xffff8000; + else + mystique->dwgreg.ar[5] &= ~0xffff8000; + WRITE8(addr&1, mystique->dwgreg.xdst, val); + break; + case REG_XYSTRT+2: case REG_XYSTRT+3: + WRITE8(addr & 1, mystique->dwgreg.ar[6], val); + if (mystique->dwgreg.ar[6] & 0x8000) + mystique->dwgreg.ar[6] |= 0xffff8000; + else + mystique->dwgreg.ar[6] &= ~0xffff8000; + WRITE8(addr & 1, mystique->dwgreg.ydst, val); + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; + + case REG_XYEND: case REG_XYEND+1: + WRITE8(addr&1, mystique->dwgreg.ar[0], val); + if (mystique->dwgreg.ar[0] & 0x8000) + mystique->dwgreg.ar[0] |= 0xffff8000; + else + mystique->dwgreg.ar[0] &= ~0xffff8000; +// pclog("XYEND AR[0]=%08x\n", mystique->dwgreg.ar[0]); + break; + case REG_XYEND+2: case REG_XYEND+3: + WRITE8(addr & 1, mystique->dwgreg.ar[2], val); + if (mystique->dwgreg.ar[2] & 0x8000) + mystique->dwgreg.ar[2] |= 0xffff8000; + else + mystique->dwgreg.ar[2] &= ~0xffff8000; + break; + + + case REG_SGN: + mystique->dwgreg.sgn.sdydxl = val & SGN_SDYDXL; + mystique->dwgreg.sgn.scanleft = val & SGN_SCANLEFT; + mystique->dwgreg.sgn.sdxl = val & SGN_SDXL; + mystique->dwgreg.sgn.sdy = val & SGN_SDY; + mystique->dwgreg.sgn.sdxr = val & SGN_SDXR; + break; + case REG_SGN+1: case REG_SGN+2: case REG_SGN+3: + break; + + + case REG_LEN: case REG_LEN+1: + WRITE8(addr, mystique->dwgreg.length, val); + break; + case REG_LEN+2: + break; + case REG_LEN+3: + mystique->dwgreg.beta = val >> 4; + if (!mystique->dwgreg.beta) + mystique->dwgreg.beta = 16; + break; + + case REG_CXBNDRY: case REG_CXBNDRY+1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXBNDRY+2: case REG_CXBNDRY+3: + WRITE8(addr & 1, mystique->dwgreg.cxright, val); + break; + case REG_FXBNDRY: case REG_FXBNDRY+1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXBNDRY+2: case REG_FXBNDRY+3: + WRITE8(addr & 1, mystique->dwgreg.fxright, val); + break; + + case REG_YDSTLEN: case REG_YDSTLEN+1: + WRITE8(addr, mystique->dwgreg.length, val); +// pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); + break; + case REG_YDSTLEN+2: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + { + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } +// pclog("Write YDSTLEN+2 %i %08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); + break; + case REG_YDSTLEN+3: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & 0xff) | (((int32_t)(int8_t)val) << 8); + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; +// pclog("Write YDSTLEN+3 %i %08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); + break; + + + case REG_XDST: case REG_XDST+1: + WRITE8(addr & 1, mystique->dwgreg.xdst, val); + break; + case REG_XDST+2: case REG_XDST+3: + break; + + + case REG_YDSTORG: case REG_YDSTORG+1: case REG_YDSTORG+2: case REG_YDSTORG+3: + WRITE8(addr, mystique->dwgreg.ydstorg, val); + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg*2 + mystique->dwgreg.zorg; +// pclog("ydstorg=%06x z_base=%06x\n", mystique->dwgreg.ydstorg, mystique->dwgreg.z_base); + break; + case REG_YTOP: case REG_YTOP+1: case REG_YTOP+2: case REG_YTOP+3: + WRITE8(addr, mystique->dwgreg.ytop, val); + break; + case REG_YBOT: case REG_YBOT+1: case REG_YBOT+2: case REG_YBOT+3: + WRITE8(addr, mystique->dwgreg.ybot, val); + break; + + case REG_CXLEFT: case REG_CXLEFT+1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXLEFT+2: case REG_CXLEFT+3: + break; + case REG_CXRIGHT: case REG_CXRIGHT+1: + WRITE8(addr, mystique->dwgreg.cxright, val); + break; + case REG_CXRIGHT+2: case REG_CXRIGHT+3: + break; + + case REG_FXLEFT: case REG_FXLEFT+1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXLEFT+2: case REG_FXLEFT+3: + break; + case REG_FXRIGHT: case REG_FXRIGHT+1: + WRITE8(addr, mystique->dwgreg.fxright, val); + break; + case REG_FXRIGHT+2: case REG_FXRIGHT+3: + break; + + + case REG_SECADDRESS: case REG_SECADDRESS+1: case REG_SECADDRESS+2: case REG_SECADDRESS+3: + WRITE8(addr, mystique->dma.secaddress, val); + mystique->dma.sec_state = 0; + break; + + + case REG_TMR0: case REG_TMR0+1: case REG_TMR0+2: case REG_TMR0+3: + WRITE8(addr, mystique->dwgreg.tmr[0], val); + break; + case REG_TMR1: case REG_TMR1+1: case REG_TMR1+2: case REG_TMR1+3: + WRITE8(addr, mystique->dwgreg.tmr[1], val); + break; + case REG_TMR2: case REG_TMR2+1: case REG_TMR2+2: case REG_TMR2+3: + WRITE8(addr, mystique->dwgreg.tmr[2], val); + break; + case REG_TMR3: case REG_TMR3+1: case REG_TMR3+2: case REG_TMR3+3: + WRITE8(addr, mystique->dwgreg.tmr[3], val); + break; + case REG_TMR4: case REG_TMR4+1: case REG_TMR4+2: case REG_TMR4+3: + WRITE8(addr, mystique->dwgreg.tmr[4], val); + break; + case REG_TMR5: case REG_TMR5+1: case REG_TMR5+2: case REG_TMR5+3: + WRITE8(addr, mystique->dwgreg.tmr[5], val); + break; + case REG_TMR6: case REG_TMR6+1: case REG_TMR6+2: case REG_TMR6+3: + WRITE8(addr, mystique->dwgreg.tmr[6], val); + break; + case REG_TMR7: case REG_TMR7+1: case REG_TMR7+2: case REG_TMR7+3: + WRITE8(addr, mystique->dwgreg.tmr[7], val); + break; + case REG_TMR8: case REG_TMR8+1: case REG_TMR8+2: case REG_TMR8+3: + WRITE8(addr, mystique->dwgreg.tmr[8], val); + break; + + case REG_TEXORG: case REG_TEXORG+1: case REG_TEXORG+2: case REG_TEXORG+3: + WRITE8(addr, mystique->dwgreg.texorg, val); +// if ((addr & 3) == 3) pclog("texorg=%08x\n", mystique->dwgreg.texorg); + break; + case REG_TEXWIDTH: case REG_TEXWIDTH+1: case REG_TEXWIDTH+2: case REG_TEXWIDTH+3: + WRITE8(addr, mystique->dwgreg.texwidth, val); +// if ((addr & 3) == 3) pclog("texwith=%08x\n", mystique->dwgreg.texwidth); + break; + case REG_TEXHEIGHT: case REG_TEXHEIGHT+1: case REG_TEXHEIGHT+2: case REG_TEXHEIGHT+3: + WRITE8(addr, mystique->dwgreg.texheight, val); +// if ((addr & 3) == 3) pclog("texheight=%08x %i %i\n", mystique->dwgreg.texheight, mystique->dwgreg.texheight&0x3f, (int)(((mystique->dwgreg.texheight >> 9) & 0x3f) | ((mystique->dwgreg.texheight & (1 << 14)) ? 0xffffffc0 : 0))); + break; + case REG_TEXCTL: case REG_TEXCTL+1: case REG_TEXCTL+2: case REG_TEXCTL+3: + WRITE8(addr, mystique->dwgreg.texctl, val); +// if ((addr & 3) == 3) pclog("texctl=%08x\n", mystique->dwgreg.texctl); + mystique->dwgreg.ta_key = (mystique->dwgreg.texctl & TEXCTL_TAKEY) ? 1 : 0; + mystique->dwgreg.ta_mask = (mystique->dwgreg.texctl & TEXCTL_TAMASK) ? 1 : 0; + break; + case REG_TEXTRANS: case REG_TEXTRANS+1: case REG_TEXTRANS+2: case REG_TEXTRANS+3: + WRITE8(addr, mystique->dwgreg.textrans, val); +// /*if ((addr & 3) == 3) */pclog("textrans=%08x\n", mystique->dwgreg.textrans); + break; + + case 0x1c28: case 0x1c29: case 0x1c2a: case 0x1c2b: + case 0x1c2c: case 0x1c2d: case 0x1c2e: case 0x1c2f: + case 0x1cc4: case 0x1cc5: case 0x1cc6: case 0x1cc7: + case 0x1cd4: case 0x1cd5: case 0x1cd6: case 0x1cd7: + case 0x1ce4: case 0x1ce5: case 0x1ce6: case 0x1ce7: + case 0x1cf4: case 0x1cf5: case 0x1cf6: case 0x1cf7: + break; + + case REG_OPMODE: + mystique->dwgreg.dmamod = (val >> 2) & 3; + mystique->dma.iload_state = 0; + break; + + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + fatal("Write MGA accel control %08x %02x\n", addr & 0x3fff, val); + break; + } + + if (start_blit) + { + mystique_start_blit(mystique); +// fatal("Start blit\n"); + } +} +static void mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + +// pclog("mystique addr=%04x val=%02x\n", addr & 0x3fff, val); + + if ((addr & 0x3fff) < 0x1c00) + { + mystique_iload_write_b(addr, val, p); + return; + } + if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) + { + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; +// pclog("mystique queue addr=%04x val=%02x\n", addr & 0x3fff, val); + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + return; + } + + switch (addr & 0x3fff) + { + case REG_ICLEAR: +// pclog("ICLEAR %02x\n", val); + if (val & ICLEAR_SOFTRAPICLR) + { + mystique->status &= ~STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } + if (val & ICLEAR_VLINEICLR) + { + mystique->status &= ~STATUS_VLINEPEN; + mystique_update_irqs(mystique); + } + break; + case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: + break; + + case REG_IEN: + mystique->ien = val & 0x65; +// pclog("Write IEN %02x\n", val); + break; + case REG_IEN+1: case REG_IEN+2: case REG_IEN+3: + break; + + case REG_OPMODE: + mystique->dmamod = (val >> 2) & 3; +// pclog("OPMODE\n"); + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + break; + case REG_OPMODE+1: + mystique->dmadatasiz = val & 3; + break; + case REG_OPMODE+2: + mystique->dirdatasiz = val & 3; + break; + case REG_OPMODE+3: + break; + + case REG_PRIMADDRESS: case REG_PRIMADDRESS+1: case REG_PRIMADDRESS+2: case REG_PRIMADDRESS+3: + thread_lock_mutex(mystique->dma.lock); + WRITE8(addr, mystique->dma.primaddress, val); + mystique->dma.pri_state = 0; +// pclog("PRIMADDRESS write %04x %08x\n", addr, mystique->dma.primaddress); + thread_unlock_mutex(mystique->dma.lock); + break; + + case REG_DMAMAP: case REG_DMAMAP+0x1: case REG_DMAMAP+0x2: case REG_DMAMAP+0x3: + case REG_DMAMAP+0x4: case REG_DMAMAP+0x5: case REG_DMAMAP+0x6: case REG_DMAMAP+0x7: + case REG_DMAMAP+0x8: case REG_DMAMAP+0x9: case REG_DMAMAP+0xa: case REG_DMAMAP+0xb: + case REG_DMAMAP+0xc: case REG_DMAMAP+0xd: case REG_DMAMAP+0xe: case REG_DMAMAP+0xf: + mystique->dmamap[addr & 0xf] = val; + break; + + case REG_RST: case REG_RST+1: case REG_RST+2: case REG_RST+3: +// pclog("Write REG_RST\n"); + wait_fifo_idle(mystique); + mystique->busy = 0; + mystique->blitter_submit_refcount = 0; + mystique->blitter_submit_dma_refcount = 0; + mystique->blitter_complete_refcount = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->status = STATUS_ENDPRDMASTS; + break; + + case REG_MISC: + svga_out(0x3c2, val, svga); + break; + + case REG_SEQ_IDX: + svga_out(0x3c4, val, svga); + break; + case REG_SEQ_DATA: + svga_out(0x3c5, val, svga); + break; + + case REG_CRTC_IDX: + mystique_out(0x3d4, val, mystique); + break; + case REG_CRTC_DATA: + mystique_out(0x3d5, val, mystique); + break; + + case REG_CRTCEXT_IDX: + mystique_out(0x3de, val, mystique); + break; + case REG_CRTCEXT_DATA: + mystique_out(0x3df, val, mystique); + break; + + case REG_CACHEFLUSH: + break; + + case REG_PALWTADD: + svga_out(0x3c8, val, svga); + mystique->xreg_idx = val; + break; + case REG_PALDATA: + svga_out(0x3c9, val, svga); + break; + case REG_PIXRDMSK: + svga_out(0x3c6, val, svga); + break; + case REG_PALRDADD: + svga_out(0x3c7, val, svga); + break; + + case REG_X_DATAREG: + mystique_write_xreg(mystique, mystique->xreg_idx, val); + break; + + case REG_CURPOSX: case REG_CURPOSX+1: + WRITE8(addr, mystique->cursor.pos_x, val); + svga->hwcursor.x = mystique->cursor.pos_x - 64; + break; + case REG_CURPOSY: case REG_CURPOSY+1: + WRITE8(addr & 1, mystique->cursor.pos_y, val); + svga->hwcursor.y = mystique->cursor.pos_y - 64; + break; + + case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53: + case 0x3c0b: case 0x3e02: case 0x3e08: + break; + + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + fatal("Write MGA control %08x %02x\n", addr & 0x3fff, val); + break; + } +} + +static uint32_t mystique_ctrl_read_l(uint32_t addr, void *p) +{ + uint32_t ret; + +// pclog("mystique_ctrl_read_l: addr=%08x %08x\n", addr, cpu_state.pc); + if ((addr & 0x3fff) < 0x1c00) + return mystique_iload_read_l(addr, p); + + ret = mystique_ctrl_read_b(addr, p); + ret |= mystique_ctrl_read_b(addr+1, p) << 8; + ret |= mystique_ctrl_read_b(addr+2, p) << 16; + ret |= mystique_ctrl_read_b(addr+3, p) << 24; +// pclog("mcrl: addr=%08x ret=%08x %08x\n", addr, ret, mystique->status); + + return ret; +} + +static void mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + int start_blit = 0; + +// pclog("mystique accel addr=%04x val=%08x\n", addr & 0x3fff, val); + if ((addr & 0x300) == 0x100) + { + addr &= ~0x100; + start_blit = 1; + } + + switch (addr & 0x3ffc) + { + case REG_DWGCTL: +// pclog(" dwgctrl write %08x %08x\n", addr2, val); + mystique->dwgreg.dwgctrl = val; + break; + + case REG_ZORG: + mystique->dwgreg.zorg = val; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg*2 + mystique->dwgreg.zorg; +// pclog("zorg=%08x z_base=%08x\n", mystique->dwgreg.zorg, mystique->dwgreg.z_base); + break; + + case REG_PLNWT: + mystique->dwgreg.plnwt = val; + break; + + case REG_SHIFT: + mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.xoff = val & 7; + mystique->dwgreg.yoff = (val >> 4) & 7; + mystique->dwgreg.stylelen = (val >> 16) & 0xff; + break; + + case REG_PITCH: + mystique->dwgreg.pitch = val & 0xffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; +// pclog("pitch=%04x %i\n", mystique->dwgreg.pitch, addr&1); + break; + + case REG_YDST: + mystique->dwgreg.ydst = val & 0x3fffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) + { + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val >> 29; + } + else + { + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } +// pclog("ydst=%i ydsth=%08x %08x pitch=%08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin, mystique->dwgreg.pitch); + break; + + case REG_BCOL: + mystique->dwgreg.bcol = val; +// pclog("BCOL %i %02x\n", addr & 3, val); + break; + case REG_FCOL: + mystique->dwgreg.fcol = val; +// pclog("FCOL %i %02x\n", addr & 3, val); + break; + + case REG_SRC0: + mystique->dwgreg.src[0] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[0], 32); + break; + case REG_SRC1: + mystique->dwgreg.src[1] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[1], 32); + break; + case REG_SRC2: + mystique->dwgreg.src[2] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[2], 32); + break; + case REG_SRC3: + mystique->dwgreg.src[3] = val; + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[3], 32); + break; + + + case REG_DMAPAD: + break; + + case REG_AR0: + mystique->dwgreg.ar[0] = val; +// pclog("AR[0]=%08x\n", mystique->dwgreg.ar[0]); + break; + case REG_AR1: + mystique->dwgreg.ar[1] = val; + break; + case REG_AR2: + mystique->dwgreg.ar[2] = val; + break; + case REG_AR3: + mystique->dwgreg.ar[3] = val; +// pclog("AR[3]=%08x\n", mystique->dwgreg.ar[3]); + break; + case REG_AR4: + mystique->dwgreg.ar[4] = val; + break; + case REG_AR5: + mystique->dwgreg.ar[5] = val; + break; + case REG_AR6: + mystique->dwgreg.ar[6] = val; + break; + + case REG_DR0: + mystique->dwgreg.dr[0] = val; + break; + case REG_DR2: + mystique->dwgreg.dr[2] = val; + break; + case REG_DR3: + mystique->dwgreg.dr[3] = val; + break; + case REG_DR4: + mystique->dwgreg.dr[4] = val; +// if ((addr & 3) == 3) pclog("DR[4]=%08x\n", mystique->dwgreg.dr[4]); + break; + case REG_DR6: + mystique->dwgreg.dr[6] = val; +// if ((addr & 3) == 3) pclog("DR[6]=%08x\n", mystique->dwgreg.dr[6]); + break; + case REG_DR7: + mystique->dwgreg.dr[7] = val; +// if ((addr & 3) == 3) pclog("DR[7]=%08x\n", mystique->dwgreg.dr[7]); + break; + case REG_DR8: + mystique->dwgreg.dr[8] = val; + break; + case REG_DR10: + mystique->dwgreg.dr[10] = val; + break; + case REG_DR11: + mystique->dwgreg.dr[11] = val; + break; + case REG_DR12: + mystique->dwgreg.dr[12] = val; + break; + case REG_DR14: + mystique->dwgreg.dr[14] = val; + break; + case REG_DR15: + mystique->dwgreg.dr[15] = val; + break; + + case REG_SECEND: +// pclog("SECEND write %08x\n", val); + mystique->dma.secend = val; + if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) + { +// pclog(" DMA state STATE_SEC\n"); + mystique->dma.state = DMA_STATE_SEC; + } + break; + + case REG_SOFTRAP: +// pclog("SOFTRAP\n"); +/* mystique->dma.secaddress = val;*/ + mystique->dma.state = DMA_STATE_IDLE; + mystique->endprdmasts_pending = 1; + mystique->softrap_pending_val = val; + mystique->softrap_pending = 1; +// pclog("SOFTRAP DMA state STATE_IDLE\n"); +/* mystique->status |= STATUS_SOFTRAPEN; + mystique_update_irqs(mystique);*/ + break; + + default: + mystique_accel_ctrl_write_b(addr, val & 0xff, p); + mystique_accel_ctrl_write_b(addr+1, (val >> 8) & 0xff, p); + mystique_accel_ctrl_write_b(addr+2, (val >> 16) & 0xff, p); + mystique_accel_ctrl_write_b(addr+3, (val >> 24) & 0xff, p); + break; + } + + if (start_blit) + { + mystique_start_blit(mystique); +// fatal("Start blit\n"); + } +} + +static void mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + uint32_t reg_addr; + +// pclog("mystique addr=%04x val=%08x\n", addr & 0x3fff, val); + if ((addr & 0x3fff) < 0x1c00) + { + mystique_iload_write_l(addr, val, p); + return; + } + + if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) + { + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; +// pclog("mystique queue addr=%04x val=%08x\n", addr & 0x3fff, val); + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_LONG); + return; + } + + switch (addr & 0x3ffc) + { + case REG_PRIMEND: + thread_lock_mutex(mystique->dma.lock); +// pclog("PRIMEND write %08x\n", val); + mystique->dma.primend = val; + if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) + { +// pclog("Clear DMA end flag\n"); + mystique->endprdmasts_pending = 0; + mystique->status &= ~STATUS_ENDPRDMASTS; + + mystique->dma.state = DMA_STATE_PRI; +// pclog(" DMA state STATE_PRI\n"); + mystique->dma.pri_state = 0; + wake_fifo_thread(mystique); + } + thread_unlock_mutex(mystique->dma.lock); + break; + + case REG_DWG_INDIR_WT: case REG_DWG_INDIR_WT+0x04: case REG_DWG_INDIR_WT+0x08: case REG_DWG_INDIR_WT+0x0c: + case REG_DWG_INDIR_WT+0x10: case REG_DWG_INDIR_WT+0x14: case REG_DWG_INDIR_WT+0x18: case REG_DWG_INDIR_WT+0x1c: + case REG_DWG_INDIR_WT+0x20: case REG_DWG_INDIR_WT+0x24: case REG_DWG_INDIR_WT+0x28: case REG_DWG_INDIR_WT+0x2c: + case REG_DWG_INDIR_WT+0x30: case REG_DWG_INDIR_WT+0x34: case REG_DWG_INDIR_WT+0x38: case REG_DWG_INDIR_WT+0x3c: + reg_addr = (mystique->dmamap[(addr >> 2) & 0xf] & 0x7f) << 2; + if (mystique->dmamap[(addr >> 2) & 0xf] & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + +// pclog("mystique queue dwg addr=%04x val=%08x\n", reg_addr, val); + mystique_queue(mystique, reg_addr, val, FIFO_WRITE_CTRL_LONG); + break; + + default: + mystique_ctrl_write_b(addr, val & 0xff, p); + mystique_ctrl_write_b(addr+1, (val >> 8) & 0xff, p); + mystique_ctrl_write_b(addr+2, (val >> 16) & 0xff, p); + mystique_ctrl_write_b(addr+3, (val >> 24) & 0xff, p); + break; + } +} + +static uint8_t mystique_iload_read_b(uint32_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + wait_fifo_idle(mystique); + if (!mystique->busy) + fatal("mystique_iload_read_b: !busy\n"); + +// pclog("Readb MGA ILOAD %08x\n", addr); + return blit_idump_read(mystique); +} +static uint32_t mystique_iload_read_l(uint32_t addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + wait_fifo_idle(mystique); + if (!mystique->busy) + fatal("mystique_iload_read_l: !busy\n"); + +// pclog("Readl MGA ILOAD %08x %i\n", addr, mystique->dwgreg.words); + mystique->dwgreg.words++; + return blit_idump_read(mystique); +} +static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p) +{ + fatal("Write MGA ILOAD %08x %02x\n", addr, val); +} +static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + +// pclog("mystique queue iload addr=%04x val=%08x\n", addr, val); + mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); +} + +static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + +// pclog(" Write ILOAD %08x %i %i\n", val, mystique->dwgreg.dmamod, mystique->dma.iload_state); + switch (mystique->dwgreg.dmamod) + { + case DMA_MODE_REG: + if (mystique->dma.iload_state == 0) + { +// pclog(" ILOAD header\n"); + mystique->dma.iload_header = val; + mystique->dma.iload_state = 1; + } + else + { + uint32_t reg_addr = (mystique->dma.iload_header & 0x7f) << 2; + if (mystique->dma.iload_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + +// pclog(" ILOAD write %08x to %02x %04x\n", val, mystique->dma.iload_header & 0xff, reg_addr); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + + mystique->dma.iload_header >>= 8; + mystique->dma.iload_state = (mystique->dma.iload_state == 4) ? 0 : (mystique->dma.iload_state+1); + } + break; + + case DMA_MODE_BLIT: + if (!mystique->busy) + fatal("mystique_iload_write_l: !busy\n"); + blit_iload_write(mystique, val, 32); + break; + + default: + fatal("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); + } +} + + + + + +static void run_dma(mystique_t *mystique) +{ + int words_transferred = 0; + + thread_lock_mutex(mystique->dma.lock); + + if (mystique->dma.state == DMA_STATE_IDLE) + { + thread_unlock_mutex(mystique->dma.lock); + return; + } + + while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) + { + switch (mystique->dma.state)// != DMA_STATE_IDLE) + { + case DMA_STATE_PRI: + switch (mystique->dma.primaddress & DMA_MODE_MASK) + { + case DMA_MODE_REG: + if (mystique->dma.pri_state == 0) + { + mystique->dma.pri_header = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; +// pclog("DMA pri read header %08x from %08x %08x\n", mystique->dma.pri_header, mystique->dma.primaddress, mystique->dma.primend); + mystique->dma.primaddress += 4; + } + +// if ((mystique->dma.pri_header & 0xff) != 0x15) + { + uint32_t val = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; + uint32_t reg_addr; + + mystique->dma.primaddress += 4; + + reg_addr = (mystique->dma.pri_header & 0x7f) << 2; + if (mystique->dma.pri_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + +// pclog(" DMA pri write %08x to %02x %04x %08x %08x\n", val, mystique->dma.pri_header & 0xff, reg_addr, (mystique->dma.primaddress & DMA_ADDR_MASK), (mystique->dma.primend & DMA_ADDR_MASK)); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + } + + mystique->dma.pri_header >>= 8; + mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; + + words_transferred++; + if (mystique->dma.state == DMA_STATE_SEC) + mystique->dma.pri_state = 0; + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) + { +// pclog("DMA pri end\n"); + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } + break; + + default: + fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + } + break; + + case DMA_STATE_SEC: + switch (mystique->dma.secaddress & DMA_MODE_MASK) + { + case DMA_MODE_REG: + if (mystique->dma.sec_state == 0) + { + mystique->dma.sec_header = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; +// pclog("DMA sec read header %08x from %08x %08x\n", mystique->dma.sec_header, mystique->dma.secaddress, mystique->dma.secend); + mystique->dma.secaddress += 4; + } + +// if ((mystique->dma.sec_header & 0xff) != 0x15) + { + uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + uint32_t reg_addr; + + mystique->dma.secaddress += 4; + + reg_addr = (mystique->dma.sec_header & 0x7f) << 2; + if (mystique->dma.sec_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; + +// pclog(" DMA sec write %08x to %02x %04x %08x %08x\n", val, mystique->dma.sec_header & 0xff, reg_addr, (mystique->dma.secaddress & DMA_ADDR_MASK), (mystique->dma.secend & DMA_ADDR_MASK)); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + } + + mystique->dma.sec_header >>= 8; + mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; + + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) + { +// pclog("DMA sec end\n"); + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) + { +// pclog("DMA pri end\n"); + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } + else + { +// pclog("DMA pri resume\n"); + mystique->dma.state = DMA_STATE_PRI; + } + } + break; + + case DMA_MODE_BLIT: + { + uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; +// pclog(" DMA_MODE_BLIT %08x %08x %08x %08x\n", mystique->dma.secaddress & DMA_ADDR_MASK, mystique->dma.secend & DMA_ADDR_MASK, mystique->dwgreg.dwgctrl_running, mystique->maccess_running); + mystique->dma.secaddress += 4; + + if (!mystique->busy) + fatal("mystique_iload_write_l: !busy\n"); + + blit_iload_write(mystique, val, 32); + + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) + { +// pclog("DMA sec end\n"); + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) + { +// pclog("DMA pri end\n"); + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } + else + { +// pclog("DMA pri resume\n"); + mystique->dma.state = DMA_STATE_PRI; + } + } + } + break; + + default: + fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + } + break; + } + } + thread_unlock_mutex(mystique->dma.lock); +} + +static void fifo_thread(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + while (1) + { + thread_set_event(mystique->fifo_not_full_event); + thread_wait_event(mystique->wake_fifo_thread, -1); + thread_reset_event(mystique->wake_fifo_thread); + + while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) + { + int words_transferred = 0; + + while (!FIFO_EMPTY && words_transferred < 100) + { + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; + + switch (fifo->addr_type & FIFO_TYPE) + { + case FIFO_WRITE_CTRL_BYTE: + mystique_accel_ctrl_write_b(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_CTRL_LONG: + mystique_accel_ctrl_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_ILOAD_LONG: + mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + } + + fifo->addr_type = FIFO_INVALID; + mystique->fifo_read_idx++; + + if (FIFO_ENTRIES > FIFO_THRESHOLD) + thread_set_event(mystique->fifo_not_full_event); + + words_transferred++; + } + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); + } + } +} + +static void wake_fifo_thread(mystique_t *mystique) +{ + if (!timer_is_enabled(&mystique->wake_timer)) + { + /*Don't wake FIFO thread immediately - if we do that it will probably + process one word and go back to sleep, requiring it to be woken on + almost every write. Instead, wait a short while so that the CPU + emulation writes more data so we have more batched-up work.*/ + timer_set_delay_u64(&mystique->wake_timer, WAKE_DELAY); + } +} + +static void wake_fifo_thread_now(mystique_t *mystique) +{ + thread_set_event(mystique->wake_fifo_thread); +} + +static void mystique_wake_timer(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + thread_set_event(mystique->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} + +static void wait_fifo_idle(mystique_t *mystique) +{ + while (!FIFO_EMPTY) + { + wake_fifo_thread_now(mystique); + thread_wait_event(mystique->fifo_not_full_event, 1); + } +} + +/*IRQ code (PCI & PIC) is not currently thread safe. SOFTRAP IRQ requests must + therefore be submitted from the main emulation thread, in this case via a timer + callback. End-of-DMA status is also deferred here to prevent races between + SOFTRAP IRQs and code reading the status register. Croc will get into an IRQ + loop and triple fault if the ENDPRDMASTS flag is seen before the IRQ is taken*/ +static void mystique_softrap_pending_timer(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); + + if (mystique->endprdmasts_pending) + { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; + } + if (mystique->softrap_pending) + { + mystique->softrap_pending = 0; + +// pclog("Take SOFTRAP %08x\n", cpu_state.pc); + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } +} + +static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type) +{ + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_write_idx & FIFO_MASK]; + + if (FIFO_FULL) + { + thread_reset_event(mystique->fifo_not_full_event); + if (FIFO_FULL) + { + thread_wait_event(mystique->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } + + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + mystique->fifo_write_idx++; + + if (FIFO_ENTRIES > FIFO_THRESHOLD || FIFO_ENTRIES < 8) + wake_fifo_thread(mystique); + +// wait_fifo_idle(mystique); +} + + + +static uint32_t bitop(uint32_t src, uint32_t dst, uint32_t dwgctrl) +{ + switch (dwgctrl & DWGCTRL_BOP_MASK) + { + case BOP(0x0): return 0; + case BOP(0x1): return ~(dst | src); + case BOP(0x2): return dst & ~src; + case BOP(0x3): return ~src; + case BOP(0x4): return ~dst & src; + case BOP(0x5): return ~dst; + case BOP(0x6): return dst ^ src; + case BOP(0x7): return ~(dst & src); + case BOP(0x8): return dst & src; + case BOP(0x9): return ~(dst ^ src); + case BOP(0xa): return dst; + case BOP(0xb): return dst | ~src; + case BOP(0xc): return src; + case BOP(0xd): return ~dst | src; + case BOP(0xe): return dst | src; + case BOP(0xf): return ~0; + } + return 0; +} + +static uint16_t dither(mystique_t *mystique, int r, int g, int b, int x, int y) +{ + switch (mystique->dwgreg.dither) + { + case DITHER_NONE_555: + return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10); + + case DITHER_NONE_565: + return (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + + case DITHER_555: + return dither5[b][y][x] | (dither5[g][y][x] << 5) | (dither5[r][y][x] << 10); + + case DITHER_565: + default: + return dither5[b][y][x] | (dither6[g][y][x] << 5) | (dither5[r][y][x] << 11); + } +} + + +static uint32_t blit_idump_idump(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + uint64_t val64 = 0; + uint32_t val = 0; + int count = 0; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BU32RGB: + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: +// pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + while (count < 32) + { + val |= (svga->vram[mystique->dwgreg.src_addr & mystique->vram_mask] << count); + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } + else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + + count += 8; + } + break; + + case MACCESS_PWIDTH_16: + // pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + while (count < 32) + { + val |= (((uint16_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_w] << count); + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } + else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + + count += 16; + } + break; + + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.idump_end_of_line) + { + mystique->dwgreg.idump_end_of_line = 0; + val = mystique->dwgreg.iload_rem_data; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + + count += mystique->dwgreg.iload_rem_count; + val64 = mystique->dwgreg.iload_rem_data; + +// pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + while ((count < 32) && !mystique->dwgreg.idump_end_of_line) + { + val64 |= (uint64_t)((*(uint32_t *)&svga->vram[(mystique->dwgreg.src_addr * 3) & mystique->vram_mask]) & 0xffffff) << count; +/* pclog(" %i %i %i %016llx\n", count, mystique->dwgreg.xdst, + mystique->dwgreg.length_cur, val64);*/ + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } + else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else + { + count = 32; + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) + { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else + { + count = 32; + break; + } + } + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + + count += 24; + } + if (count > 32) + mystique->dwgreg.iload_rem_count = count - 32; + else + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = (uint32_t)(val64 >> 32); + val = val64 & 0xffffffff; + break; + + case MACCESS_PWIDTH_32: +// pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + + val = (((uint32_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_l] << count); + + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } + else + mystique->dwgreg.src_addr++; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + break; + + default: + fatal("IDUMP DWGCTRL_BLTMOD_BU32RGB %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->maccess_running); + } + break; + + default: + fatal("IDUMP DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + + return val; +} + +static uint32_t blit_idump_read(mystique_t *mystique) +{ + uint32_t ret = 0xffffffff; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) + { + case DWGCTRL_OPCODE_IDUMP: + ret = blit_idump_idump(mystique); + break; + + default: + fatal("blit_idump_read: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); + } + +// pclog(" idump returned %08x\n", ret); + return ret; +} + +static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) +{ + svga_t *svga = &mystique->svga; + uint32_t src, dst; + uint64_t data64; + int min_size; + uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; + const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + bltckey &= 0xff; + bltcmsk &= 0xff; + break; + case MACCESS_PWIDTH_16: + bltckey &= 0xffff; + bltcmsk &= 0xffff; + break; + } + + mystique->dwgreg.words++; +// pclog("blit_iload_iload: %08x %06x %02x %i %08x words=%i %08x %08x\n", data, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, data, (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF, mystique->dwgreg.dwgctrl_running, mystique->dwgreg.words,mystique->dwgreg.words, mystique->maccess_running); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: + if (mystique->maccess_running & MACCESS_TLUTLOAD) + { + while ((mystique->dwgreg.length_cur > 0) && (size >= 16)) + { + uint16_t src = data & 0xffff; +// pclog(" LUT[%02x]=%04x\n", mystique->dwgreg.ydst & 0xff, src); + + mystique->lut[mystique->dwgreg.ydst & 0xff].r = (src >> 11) << 3; + mystique->lut[mystique->dwgreg.ydst & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[mystique->dwgreg.ydst & 0xff].b = (src & 0x1f) << 3; + mystique->dwgreg.ydst++; + mystique->dwgreg.length_cur--; + data >>= 16; + size -= 16; + } + + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BFCOL: + size += mystique->dwgreg.iload_rem_count; +// pclog(" size=%i xdst=%i cur=%i data= %08x %08x ", size, mystique->dwgreg.xdst, mystique->dwgreg.length_cur, mystique->dwgreg.iload_rem_data, data); + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); +// pclog("%016llx words=%i\n", data64, mystique->dwgreg.words); + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + min_size = 8; + break; + case MACCESS_PWIDTH_16: + min_size = 16; + break; + case MACCESS_PWIDTH_24: + min_size = 24; + break; + case MACCESS_PWIDTH_32: + min_size = 32; + break; + } + + while (size >= min_size) + { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) + { + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(data & 0xff, dst, mystique->dwgreg.dwgctrl_running); +// pclog(" 8 %06x=%04x\n", mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, dst); + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + } +/* else + pclog(" Clipped %i,%i %i %08x,%08x %08x\n", + mystique->dwgreg.cxleft, mystique->dwgreg.cxright, mystique->dwgreg.xdst, + mystique->dwgreg.ytop, mystique->dwgreg.ybot, mystique->dwgreg.ydst_lin);*/ + + data >>= 8; + size -= 8; + break; + + case MACCESS_PWIDTH_16: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) + { + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); +// pclog(" 16 %06x=%04x\n", mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, dst); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + } + + data >>= 16; + size -= 16; + break; + + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + uint32_t old_dst = *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]); + + dst = bitop(data64, old_dst, mystique->dwgreg.dwgctrl_running); + *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]) = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } + + data64 >>= 24; + size -= 24; + break; + + case MACCESS_PWIDTH_32: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) + { + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); +// pclog(" 32 %06x=%04x\n", mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, dst); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } + + size = 0; + break; + + default: + fatal("ILOAD RSTR/RPL BFCOL pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + + case DWGCTRL_BLTMOD_BMONOWF: + data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); + while (size) + { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + ((data & 0x80000000) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + trans[mystique->dwgreg.xdst & 3]) + { + uint32_t old_dst; + + src = (data & 0x80000000) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + +// pclog(" %02x %02x %06x ", src, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); +// pclog("%02x\n", dst); + + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + +// pclog(" %02x %02x %06x ", src, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); +// pclog("%02x\n", dst); + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]; + +// pclog(" %02x %02x %06x ", src, old_dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); +// pclog("%02x %08x %08x %08x %i\n", dst, data, mystique->dwgreg.fcol, mystique->dwgreg.bcol, mystique->dwgreg.xdst); + + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + +// pclog(" %02x %02x %06x ", src, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); +// pclog("%02x %08x %08x %08x %i\n", dst, data, mystique->dwgreg.fcol, mystique->dwgreg.bcol, mystique->dwgreg.xdst); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BMONOWF pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + data <<= 1; + size--; + } + break; + + case DWGCTRL_BLTMOD_BU24RGB: + size += mystique->dwgreg.iload_rem_count; +// pclog(" size=%i data= %08x %08x ", size, mystique->dwgreg.iload_rem_data, data); + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); +// pclog("%016llx\n", data64); + + while (size >= 24) + { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + +// pclog(" %06llx %02x %06x ", data64 & 0xffffff, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); +// pclog("x=%i l=%i ", mystique->dwgreg.xdst, mystique->dwgreg.length_cur); + dst = bitop(data64 & 0xffffff, dst, mystique->dwgreg.dwgctrl_running); +// pclog("%02x\n", dst); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD RSTR/RPL BU24RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + data64 >>= 24; + size -= 24; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); + break; + } + break; + + default: + fatal("Unknown ILOAD iload atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + +#define CLAMP(x) do \ + { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } \ + while (0) + +static void blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) +{ + svga_t *svga = &mystique->svga; + uint64_t data64 = 0; + int y0, y1; + int u, v; + int dR, dG, dB; + int r0, g0, b0; + int r1, g1, b1; + +// pclog(" iload_scale: data=%08x\n", data); + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + + dR = (309*v) >> 8; + dG = (100*u + 208*v) >> 8; + dB = (516*u) >> 8; + + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_16: + data = (b0 >> 3) | ((g0 >> 2) << 5) | ((r0 >> 3) << 11); + data |= (((b1 >> 3) | ((g1 >> 2) << 5) | ((r1 >> 3) << 11)) << 16); + size = 32; + break; + case MACCESS_PWIDTH_32: + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t)b0 << 32) | ((uint64_t)g0 << 40) | ((uint64_t)r0 << 48); + size = 64; + break; + + default: + fatal("blit_iload_iload_scale BUYUV pwidth %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + break; + + default: + fatal("blit_iload_iload_scale bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_16: + while (size >= 16) + { +// pclog(" Write %i %i %08x\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, mystique->dwgreg.ar[6]); + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + uint16_t dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + } + + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) + { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data >>= 16; + size -= 16; + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + break; + + case MACCESS_PWIDTH_32: + while (size >= 32) + { +// pclog(" Write %i %i %08x\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, mystique->dwgreg.ar[6]); + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + uint32_t dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst = bitop(data64, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } + + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) + { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data64 >>= 32; + size -= 32; + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + break; + + default: + fatal("ILOAD_SCALE pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } +} + +static void blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) +{ + svga_t *svga = &mystique->svga; + uint32_t out_data; + int y0, y1, u, v; + int dR, dG, dB; + int r = 0, g = 0, b = 0; + int next_r = 0, next_g = 0, next_b = 0; + +// pclog(" iload_high: data=%08x\n", data); + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + + dR = (309*v) >> 8; + dG = (100*u + 208*v) >> 8; + dB = (516*u) >> 8; + + r = y0 + dR; + CLAMP(r); + g = y0 - dG; + CLAMP(g); + b = y0 + dB; + CLAMP(b); + + next_r = y1 + dR; + CLAMP(next_r); + next_g = y1 - dG; + CLAMP(next_g); + next_b = y1 + dB; + CLAMP(next_b); + + size = 32; + break; + + default: + fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + + while (size >= 16) + { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + uint32_t dst; + int f1 = (mystique->dwgreg.ar[6] >> 12) & 0xf; + int f0 = 0x10 - f1; + int out_r = ((mystique->dwgreg.lastpix_r * f0) + (r * f1)) >> 4; + int out_g = ((mystique->dwgreg.lastpix_g * f0) + (g * f1)) >> 4; + int out_b = ((mystique->dwgreg.lastpix_b * f0) + (b * f1)) >> 4; + +// pclog(" Write %i %i %08x %i %i %i %i %i\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, mystique->dwgreg.ar[6], mystique->dwgreg.lastpix_r, r, f0, f1, out_r); + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_16: + out_data = (out_b >> 3) | ((out_g >> 2) << 5) | ((out_r >> 3) << 11); + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + case MACCESS_PWIDTH_32: + out_data = out_b | (out_g << 8) | (out_r << 16); + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("ILOAD_SCALE_HIGH RSTR/RPL BUYUV pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) + { + mystique->dwgreg.ar[6] -= 65536; + size -= 16; + + mystique->dwgreg.lastpix_r = r; + mystique->dwgreg.lastpix_g = g; + mystique->dwgreg.lastpix_b = b; + r = next_r; + g = next_g; + b = next_b; + } + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) + { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; + + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) + { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } +} + +static void blit_iload_iload_highv(mystique_t *mystique, uint32_t data, int size) +{ + uint8_t *src0, *src1; + +// pclog(" iload_highv: data=%08x\n", data); + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BUYUV: + if (!mystique->dwgreg.highv_line) + { + mystique->dwgreg.highv_data = data; + mystique->dwgreg.highv_line = 1; + return; + } + mystique->dwgreg.highv_line = 0; + + src0 = (uint8_t *)&mystique->dwgreg.highv_data; + src1 = (uint8_t *)&data; + + src1[0] = ((src0[0] * mystique->dwgreg.beta) + (src1[0] * (16 - mystique->dwgreg.beta))) >> 4; + src1[1] = ((src0[1] * mystique->dwgreg.beta) + (src1[1] * (16 - mystique->dwgreg.beta))) >> 4; + src1[2] = ((src0[2] * mystique->dwgreg.beta) + (src1[2] * (16 - mystique->dwgreg.beta))) >> 4; + src1[3] = ((src0[3] * mystique->dwgreg.beta) + (src1[3] * (16 - mystique->dwgreg.beta))) >> 4; + blit_iload_iload_high(mystique, data, 32); + break; + + default: + fatal("blit_iload_iload_highv bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } +} + +static void blit_iload_write(mystique_t *mystique, uint32_t data, int size) +{ +// pclog(" ILOAD %08x %08x\n", data, mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) + { + case DWGCTRL_OPCODE_ILOAD: + blit_iload_iload(mystique, data, size); + break; + + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_iload_scale(mystique, data, size); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_iload_high(mystique, data, size); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_iload_highv(mystique, data, size); + break; + + default: + fatal("blit_iload_write: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); + } +} + +static int z_check(uint16_t z, uint16_t old_z, uint32_t z_mode)//mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +{ + switch (z_mode) + { + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); + + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; + } +} + +static void blit_line(mystique_t *mystique, int closed) +{ + svga_t *svga = &mystique->svga; + uint32_t src, dst, old_dst; + int x; + int z_write; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_RPL: + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) + { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + src = mystique->dwgreg.fcol; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + +// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + src = mystique->dwgreg.fcol; + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + +// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + src = mystique->dwgreg.fcol; + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + +// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + src = mystique->dwgreg.fcol; + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + +// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("LINE RSTR/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + + if ((int32_t)mystique->dwgreg.ar[1] >= 0) + { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + + mystique->dwgreg.length--; + } + break; + + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) + { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t old_z = z_p[x]; + + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) + { + int r = 0, g = 0, b = 0; + + if (z_write) + z_p[x] = z; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_16: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 17) & 0x3f; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 18) & 0x1f; + dst = (r << 11) | (g << 5) | b; + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + default: + fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + } + + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + + if ((int32_t)mystique->dwgreg.ar[1] >= 0) + { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; + } + else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + + mystique->dwgreg.length--; + } + break; + + + default: + fatal("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + mystique->blitter_complete_refcount++; +} + +static void blit_autoline(mystique_t *mystique, int closed) +{ + int start_x = (int32_t)mystique->dwgreg.ar[5]; + int start_y = (int32_t)mystique->dwgreg.ar[6]; + int end_x = (int32_t)mystique->dwgreg.ar[0]; + int end_y = (int32_t)mystique->dwgreg.ar[2]; + int dx = end_x - start_x; + int dy = end_y - start_y; + + if (ABS(dx) > ABS(dy)) + { + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.ar[0] = 2*ABS(dy); + mystique->dwgreg.ar[1] = 2*ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2*ABS(dy) - 2*ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); + } + else + { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.ar[0] = 2*ABS(dx); + mystique->dwgreg.ar[1] = 2*ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2*ABS(dx) - 2*ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); + } + mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; + + +/* pclog("Autoline %s\n", closed ? "closed" : "open"); + pclog("Start %i,%i\n", start_x, start_y); + pclog("End %i,%i\n", end_x, end_y); + pclog("SGN=%x\n", mystique->dwgreg.sgn); + pclog("AR0=%08x AR1=%08x AR2=%08x\n", mystique->dwgreg.ar[0], + mystique->dwgreg.ar[1], + mystique->dwgreg.ar[2]); + pclog("Length %i\n", mystique->dwgreg.length);*/ + blit_line(mystique, closed); + + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; +} + +static void blit_trap(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + uint32_t z_back, r_back, g_back, b_back; + int z_write; + int y; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + + mystique->trap_count++; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_BLK: + case DWGCTRL_ATYPE_RPL: + //fxleft, fxright + //fcol +/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("fcol=%08x\n", mystique->dwgreg.fcol); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("pitch=%08x\n", mystique->dwgreg.pitch); + pclog("ydst_lin=%08x\n", mystique->dwgreg.ydst_lin);*/ +// if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_SGNZERO)) +// fatal("Not rectangle\n"); + + for (y = 0; y < mystique->dwgreg.length; y++) + { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int x_l = mystique->dwgreg.fxleft & 0xffff; + int x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + +// pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); + while (x_l != x_r) + { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) + { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t dst; + +// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = + (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = + (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; + *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = + ((pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff) | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = + pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + x_l = (x_l + 1) & 0xffff; + mystique->pixel_count++; + } + + if ((int32_t)mystique->dwgreg.ar[1] < 0) + { + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } + else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if ((int32_t)mystique->dwgreg.ar[4] < 0) + { + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) + { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } + else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + case DWGCTRL_ATYPE_RSTR: + for (y = 0; y < mystique->dwgreg.length; y++) + { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int x_l = mystique->dwgreg.fxleft & 0xffff; + int x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + +// pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); + while (x_l != x_r) + { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) + { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); +// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); +// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]; + + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); +// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; + + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); +// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + x_l = (x_l + 1) & 0xffff; + mystique->pixel_count++; + } + + if ((int32_t)mystique->dwgreg.ar[1] < 0) + { + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } + else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + if ((int32_t)mystique->dwgreg.ar[4] < 0) + { + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) + { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } + else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); +/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("fcol=%08x\n", mystique->dwgreg.fcol); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("pitch=%08x\n", mystique->dwgreg.pitch); + pclog("ydst_lin=%08x\n", mystique->dwgreg.ydst_lin); + pclog("trap! maccess=%08x %08x %08x %08x\n", mystique->maccess_running, mystique->dwgreg.dr[4], mystique->dwgreg.dr[8], mystique->dwgreg.dr[12]);*/ + + for (y = 0; y < mystique->dwgreg.length; y++) + { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int x_l = mystique->dwgreg.fxleft & 0xffff; + int x_r = mystique->dwgreg.fxright & 0xffff; + int old_x_l = x_l; + int dx; + + z_back = mystique->dwgreg.dr[0]; + r_back = mystique->dwgreg.dr[4]; + g_back = mystique->dwgreg.dr[8]; + b_back = mystique->dwgreg.dr[12]; + +// pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); + while (x_l != x_r) + { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) + { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) + { + uint32_t dst = 0, old_dst; + int r = 0, g = 0, b = 0; + + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + + if (z_write) + z_p[x_l] = z; + +// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = dither(mystique, r, g, b, x_l & 1, mystique->dwgreg.selline & 1); +// pclog(" %08x %08x %08x %04x\n", mystique->dwgreg.dr[4], mystique->dwgreg.dr[8], mystique->dwgreg.dr[12], dst); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; + *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = old_dst | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = b | (g << 8) | (r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + } + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + + x_l = (x_l + 1) & 0xffff; + mystique->pixel_count++; + } + + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) + { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx*mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx*mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx*mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx*mystique->dwgreg.dr[14]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + default: + fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + + mystique->blitter_complete_refcount++; +} + +static int texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) +{ + svga_t *svga = &mystique->svga; + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s, t; + + if (mystique->dwgreg.texctl & TEXCTL_NPCEN) + { + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + + s = (int32_t)mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t)mystique->dwgreg.tmr[7] >> t_shift; + } + else + { + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? ((0x100000000ll / (int64_t)(int32_t)mystique->dwgreg.tmr[8]) /*>> 16*/) : 0; + + s = (((int64_t)(int32_t)mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift;/*((16+20)-12);*/ + t = (((int64_t)(int32_t)mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift;/*((16+20)-9);*/ + } + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) + { + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; + } + else + s &= w_mask; + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) + { + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; + } + else + t &= h_mask; + + switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) + { + case TEXCTL_TEXFORMAT_TW4: + src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + if (s & 1) + src >>= 4; + else + src &= 0xf; + *tex_r = mystique->lut[src | palsel].r; + *tex_g = mystique->lut[src | palsel].g; + *tex_b = mystique->lut[src | palsel].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW8: + src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + *tex_r = mystique->lut[src].r; + *tex_g = mystique->lut[src].g; + *tex_b = mystique->lut[src].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW15: + src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 10) & 0x1f) << 3; + *tex_g = ((src >> 5) & 0x1f) << 3; + *tex_b = (src & 0x1f) << 3; + if (((src >> 15) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key) + *atransp = 1; + else + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW16: + src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = (src >> 11) << 3; + *tex_g = ((src >> 5) & 0x3f) << 2; + *tex_b = (src & 0x1f) << 3; + *atransp = 0; + break; + default: + fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); + break; + } + + return ((src & tkmask) == tckey); +} + +static void blit_texture_trap(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + int y; + int z_write; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); + + mystique->trap_count++; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); +// pclog("fxleft=%i fxright=%i texctl=%08x texorg=%08x ydst=%i len=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright, mystique->dwgreg.texctl, mystique->dwgreg.texorg, mystique->dwgreg.ydst, mystique->dwgreg.length); +/* pclog("fcol=%08x\n", mystique->dwgreg.fcol); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("pitch=%08x\n", mystique->dwgreg.pitch); + pclog("ydst=%i ydst_lin=%08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); + pclog("dYl =%08x errl =%08x -|dXl|=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[1], mystique->dwgreg.ar[2]); + pclog("errr=%08x -|dXr|=%08x dYr =%08x\n", mystique->dwgreg.ar[4], mystique->dwgreg.ar[5], mystique->dwgreg.ar[6]); + pclog(" q/wc=%08x q/wc/dX=%08x q/wc/dY=%08x\n", + mystique->dwgreg.tmr[8], mystique->dwgreg.tmr[4], mystique->dwgreg.tmr[5]); + pclog(" s/wc=%08x s/wc/dX=%08x s/wc/dY=%08x\n", + mystique->dwgreg.tmr[6], mystique->dwgreg.tmr[0], mystique->dwgreg.tmr[1]); + pclog(" t/wc=%08x t/wc/dX=%08x t/wc/dY=%08x\n", + mystique->dwgreg.tmr[7], mystique->dwgreg.tmr[2], mystique->dwgreg.tmr[3]);*/ + + for (y = 0; y < mystique->dwgreg.length; y++) + { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int x_l = mystique->dwgreg.fxleft & 0xffff; + int x_r = mystique->dwgreg.fxright & 0xffff; + int old_x_l = x_l; + int dx; + + uint32_t z_back = mystique->dwgreg.dr[0]; + uint32_t r_back = mystique->dwgreg.dr[4]; + uint32_t g_back = mystique->dwgreg.dr[8]; + uint32_t b_back = mystique->dwgreg.dr[12]; + uint32_t s_back = mystique->dwgreg.tmr[6]; + uint32_t t_back = mystique->dwgreg.tmr[7]; + uint32_t q_back = mystique->dwgreg.tmr[8]; + +// pclog(" line %i: %i %i %08x %08x %08x %08x %i\n", __y, x_l, x_r, mystique->dwgreg.dr[0],mystique->dwgreg.dr[2],mystique->dwgreg.dr[3], mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg, z_write); +// pclog(" %08x %08x %08x\n", mystique->dwgreg.tmr[4],mystique->dwgreg.tmr[5], mystique->dwgreg.tmr[8]); +// pclog(" %08x %08x %08x\n", mystique->dwgreg.ar[4], mystique->dwgreg.ar[5], mystique->dwgreg.ar[6]); + + while (x_l != x_r) + { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x_l & 3]) + { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) + { + int tex_r = 0, tex_g = 0, tex_b = 0; + int ctransp, atransp = 0; + int i_r = 0, i_g = 0, i_b = 0; + + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + i_g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + + switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) + { + case 0: + if (ctransp) + goto skip_pixel; + if (atransp) + { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; + + case TEXCTL_DECALCKEY: + if (ctransp) + { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; + + case (TEXCTL_STRANS | TEXCTL_DECALCKEY): + if (ctransp) + goto skip_pixel; + break; + + case TEXCTL_TMODULATE: + if (ctransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) + { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; + + case (TEXCTL_TMODULATE | TEXCTL_STRANS): + if (ctransp || atransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) + { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; + + + default: + fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); + } + + if (dest32) + { + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + } + else + { + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + } + if (z_write) + z_p[x_l] = z; + } + } +skip_pixel: + x_l = (x_l + 1) & 0xffff; + mystique->pixel_count++; + + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + } + + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) + { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + + dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx*mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx*mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx*mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx*mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += dx*mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += dx*mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += dx*mystique->dwgreg.tmr[4]; + + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; + + default: + fatal("Unknown atype %03x %08x TEXTURE_TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + + mystique->blitter_complete_refcount++; +} + +static void blit_bitblt(mystique_t *mystique) +{ + svga_t *svga = &mystique->svga; + uint32_t src_addr; + int y; + int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; + int x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_BLK: +// if (mystique->maccess_running & MACCESS_TLUTLOAD) +// fatal("Bitblt TLUTLOAD BLK\n"); +// if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) +// fatal("BITBLT BLK with pattern\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BMONOLEF: +// pclog("ar0=%08x ar3=%08x ar5=%08x dwgctrl=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5], mystique->dwgreg.dwgctrl_running); +// pclog("fxleft=%i fxright=%i ydst=%i fcol=%08x bcol=%08x\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright, mystique->dwgreg.ydst, mystique->dwgreg.fcol, mystique->dwgreg.bcol); + + src_addr = mystique->dwgreg.ar[3]; +// mystique->dwgreg.bit_offset = 0; + + for (y = 0; y < mystique->dwgreg.length; y++) + { + int x = x_start; + +// pclog(" line %03i: %08x %08x %02x\n", y, mystique->dwgreg.ydst_lin, src_addr, svga->vram[0x2eba3]); + while (1) + { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) + { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; + uint32_t old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: +// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) + { + if (svga->vram[byte_addr] & (1 << bit_offset)) + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = mystique->dwgreg.fcol; + } + else + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = + (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: +// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) + { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = mystique->dwgreg.fcol; + } + else + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = + (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; +// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) + { + if (svga->vram[byte_addr] & (1 << bit_offset)) + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = + (old_dst & 0xff000000) | (mystique->dwgreg.fcol & 0xffffff); + } + else + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = + (old_dst & 0xff000000) | (((svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: +// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) + { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & 0xfffff] = mystique->dwgreg.fcol; + } + else + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & 0xfffff] = + (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT DWGCTRL_ATYPE_BLK unknown MACCESS %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } + else + src_addr += x_dir; + + if (x != x_end) + x = (x + x_dir) & 0xffff; + else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; + + default: + fatal("BITBLT BLK %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + break; + + + case DWGCTRL_ATYPE_RPL: +// pclog(" bitblt RPL\n"); + if (mystique->maccess_running & MACCESS_TLUTLOAD) + { +// pclog("TLUTLOAD!\n"); + src_addr = mystique->dwgreg.ar[3]; + + y = mystique->dwgreg.ydst; + + while (mystique->dwgreg.length) + { + uint16_t src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; +// pclog(" LUT[%02x]=VRAM[%05X]=%04x\n", y & 0xff, src_addr, src); + + mystique->lut[y & 0xff].r = (src >> 11) << 3; + mystique->lut[y & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[y & 0xff].b = (src & 0x1f) << 3; + src_addr++; + y++; + mystique->dwgreg.length--; + } + break; + } + case DWGCTRL_ATYPE_RSTR: +// pclog(" bitblt RPL or RSTR\n"); +// if (mystique->maccess_running & MACCESS_TLUTLOAD) +// fatal("Bitblt TLUTLOAD RSTR\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BMONOLEF: +// pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); +// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) + { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int x = x_start; + +// pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, src_addr); + while (1) + { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; + + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + trans[x & 3]) + { + uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + +// pclog(" %02x %02x ", src, dst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + +// pclog(" %02x %02x ", src, dst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + +// pclog(" %02x %02x ", src, old_dst); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + default: + fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } + else + src_addr += x_dir; + + if (x != x_end) + x = (x + x_dir) & 0xffff; + else + break; + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; + + + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BU32RGB: +// pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); +// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + + src_addr = mystique->dwgreg.ar[3]; + + for (y = 0; y < mystique->dwgreg.length; y++) + { + uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t old_src_addr = src_addr; + int x = x_start; + +// pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, src_addr); + while (1) + { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + trans[x & 3]) + { + uint32_t src, dst, old_dst; + + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) + { + case MACCESS_PWIDTH_8: + src = svga->vram[src_addr & mystique->vram_mask]; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + +// pclog(" %02x %02x ", src, dst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_16: + src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + +// pclog(" %02x %02x ", src, dst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + + case MACCESS_PWIDTH_24: + src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + +// pclog(" %02x %02x ", src, old_dst); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; + + case MACCESS_PWIDTH_32: + src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + +// pclog(" %02x %02x ", src, dst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + + default: + fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + src_addr = ((src_addr + x_dir) & 7) | (src_addr & ~7); + else if (src_addr == mystique->dwgreg.ar[0]) + { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } + else + src_addr += x_dir; + + if (x != x_end) + x = (x + x_dir) & 0xffff; + else + break; + } + + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + { + src_addr = old_src_addr; + if (mystique->dwgreg.sgn.sdy) + src_addr = ((src_addr - 32) & 0xe0) | (src_addr & ~0xe0); + else + src_addr = ((src_addr + 32) & 0xe0) | (src_addr & ~0xe0); + } + + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; + + default: + fatal("BITBLT DWGCTRL_ATYPE_RPL unknown BLTMOD %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + } + break; + + default: + fatal("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } + mystique->blitter_complete_refcount++; +} + +static void blit_iload(mystique_t *mystique) +{ +// if (mystique->maccess_running & MACCESS_TLUTLOAD) +// fatal("ILOAD TLUTLOAD\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BMONOWF: + case DWGCTRL_BLTMOD_BU24RGB: +// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); +// pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + break; + + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + +static void blit_idump(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: +// pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); +// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + mystique->dwgreg.words = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.idump_end_of_line = 0; + mystique->busy = 1; + break; + + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + +static void blit_iload_scale(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BUYUV: +/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); + pclog("ar2=%08x\n", mystique->dwgreg.ar[2]); + pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); + pclog("ar5=%08x\n", mystique->dwgreg.ar[5]); + pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + break; + + default: + fatal("ILOAD_SCALE DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD_SCALE atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} +static void blit_iload_high(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BUYUV: +/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); + pclog("ar2=%08x\n", mystique->dwgreg.ar[2]); + pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); + pclog("ar5=%08x\n", mystique->dwgreg.ar[5]); + pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + break; + + default: + fatal("ILOAD_HIGH DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD_HIGH atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} +static void blit_iload_highv(mystique_t *mystique) +{ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) + { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) + { + case DWGCTRL_BLTMOD_BUYUV: +/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); + pclog("ar2=%08x\n", mystique->dwgreg.ar[2]); + pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); + pclog("ar5=%08x\n", mystique->dwgreg.ar[5]); + pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + mystique->dwgreg.highv_line = 0; + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; + break; + + default: + fatal("ILOAD_HIGHV DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; + + default: + fatal("Unknown ILOAD_HIGHV atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + } +} + +static void mystique_start_blit(mystique_t *mystique) +{ + uint64_t start_time = timer_read(); + uint64_t end_time; + + mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; + mystique->maccess_running = mystique->maccess; +// pclog("start_blit %08x length=%i fxleft=%i fxright=%i %02x %i %i %i ylin=%08x ytop=%08x ybot=%08x\n", mystique->dwgreg.dwgctrl_running, mystique->dwgreg.length, mystique->dwgreg.fxleft, mystique->dwgreg.fxright, mystique->svga.vram[0x5c056], mystique->blitter_submit_refcount, mystique->blitter_submit_dma_refcount, mystique->blitter_complete_refcount, mystique->dwgreg.ydst_lin, mystique->dwgreg.ytop, mystique->dwgreg.ybot); + if (mystique->busy) + fatal("mystique_start_blit: mystique->busy!\n"); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + { + int x, y; + + for (y = 0; y < 8; y++) + { + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[y][x] = 1; + } + mystique->dwgreg.src[0] = 0xffffffff; + mystique->dwgreg.src[1] = 0xffffffff; + mystique->dwgreg.src[2] = 0xffffffff; + mystique->dwgreg.src[3] = 0xffffffff; + } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_ARZERO) + { + mystique->dwgreg.ar[0] = 0; + mystique->dwgreg.ar[1] = 0; + mystique->dwgreg.ar[2] = 0; + mystique->dwgreg.ar[4] = 0; + mystique->dwgreg.ar[5] = 0; + mystique->dwgreg.ar[6] = 0; + } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SGNZERO) + { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.sgn.scanleft = 0; + mystique->dwgreg.sgn.sdxl = 0; + mystique->dwgreg.sgn.sdy = 0; + mystique->dwgreg.sgn.sdxr = 0; + } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SHTZERO) + { + mystique->dwgreg.funcnt = 0; + mystique->dwgreg.stylelen = 0; + mystique->dwgreg.xoff = 0; + mystique->dwgreg.yoff = 0; + } + + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) + { + case DWGCTRL_OPCODE_LINE_OPEN: + blit_line(mystique, 0); + break; + + case DWGCTRL_OPCODE_AUTOLINE_OPEN: + blit_autoline(mystique, 0); + break; + + case DWGCTRL_OPCODE_AUTOLINE_CLOSE: + blit_autoline(mystique, 1); + break; + + case DWGCTRL_OPCODE_TRAP: + blit_trap(mystique); + break; + + case DWGCTRL_OPCODE_TEXTURE_TRAP: + blit_texture_trap(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_high(mystique); + break; + + case DWGCTRL_OPCODE_BITBLT: + blit_bitblt(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD: + blit_iload(mystique); + break; + + case DWGCTRL_OPCODE_IDUMP: + blit_idump(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_scale(mystique); + break; + + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_highv(mystique); + break; + + default: + fatal("mystique_start_blit: unknown blit %08x\n", mystique->dwgreg.dwgctrl_running); + } +// pclog("blit done\n"); + + end_time = timer_read(); + mystique->blitter_time += end_time - start_time; +} + + +static void mystique_hwcursor_draw(svga_t *svga, int displine) +{ + int x; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + + dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += 16; + for (x = 0; x < 64; x ++) + { + if (!(dat[1] & (1ull << 63))) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[0] & (1ull << 63)) ? 0xffffff : 0; + else if (dat[0] & (1ull << 63)) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } +} + + + + +static uint8_t mystique_pci_read(int func, int addr, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + +// pclog("mystique PCI read %08X\n", addr); + switch (addr) + { + case 0x00: return 0x2b; /*Matrox*/ + case 0x01: return 0x10; + + case 0x02: return 0x1a; /*MGA-1064SG*/ + case 0x03: return 0x05; + + case PCI_REG_COMMAND: + return mystique->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + + case 0x07: return 0 << 1; /*Fast DEVSEL timing*/ + + case 0x08: return 0; /*Revision ID*/ + case 0x09: return 0; /*Programming interface*/ + + case 0x0a: return 0x00; /*Supports VGA interface*/ + case 0x0b: return 0x03; + + case 0x10: return 0x00; /*Control aperture*/ + case 0x11: return (mystique->ctrl_base >> 8) & 0xc0; + case 0x12: return mystique->ctrl_base >> 16; + case 0x13: return mystique->ctrl_base >> 24; + + case 0x14: return 0x00; /*Linear frame buffer*/ + case 0x16: return (mystique->lfb_base >> 16) & 0x80; + case 0x17: return mystique->lfb_base >> 24; + + case 0x18: return 0x00; /*Pseudo-DMA (ILOAD)*/ + case 0x1a: return (mystique->iload_base >> 16) & 0x80; + case 0x1b: return mystique->iload_base >> 24; + + case 0x30: return mystique->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: return 0x00; + case 0x32: return mystique->pci_regs[0x32]; + case 0x33: return mystique->pci_regs[0x33]; + + case 0x3c: return mystique->int_line; + case 0x3d: return PCI_INTA; + + case 0x40: return mystique->pci_regs[0x40]; + case 0x41: return mystique->pci_regs[0x41]; + case 0x42: return mystique->pci_regs[0x42]; + case 0x43: return mystique->pci_regs[0x43]; + + case 0x44: return mystique->pci_regs[0x44]; + case 0x45: return mystique->pci_regs[0x45]; + + case 0x48: case 0x49: case 0x4a: case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | + ((mystique->pci_regs[0x45] & 0x3f) << 8) | + (addr & 3); + return mystique_ctrl_read_b(addr, mystique); + } + return 0; +} + +static void mystique_pci_write(int func, int addr, uint8_t val, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + +// pclog("mystique_pci_write: func=%i addr=%02x val=%02x\n", func, addr, val); + switch (addr) + { + case PCI_REG_COMMAND: + mystique->pci_regs[PCI_REG_COMMAND] = val & 0x23; + mystique_recalc_mapping(mystique); + break; + + case 0x11: + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + break; + case 0x12: + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + break; + case 0x13: + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + break; + + case 0x16: + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x17: + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; + + case 0x1a: + mystique->iload_base = (mystique->iload_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x1b: + mystique->iload_base = (mystique->iload_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; + + case 0x30: case 0x32: case 0x33: + mystique->pci_regs[addr] = val; + if (mystique->pci_regs[0x30] & 0x01) + { + uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + } + else + mem_mapping_disable(&mystique->bios_rom.mapping); + return; + + case 0x3c: + mystique->int_line = val; + return; + + case 0x40: case 0x41: case 0x42: case 0x43: + mystique->pci_regs[addr] = val; + break; + + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + mystique->pci_regs[addr-0x20] = val; + break; + + case 0x44: case 0x45: + mystique->pci_regs[addr] = val; + break; + + case 0x48: case 0x49: case 0x4a: case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | + ((mystique->pci_regs[0x45] & 0x3f) << 8) | + (addr & 3); + mystique_ctrl_write_b(addr, val, mystique); + break; + } +} + +void *mystique_init() +{ + int c; + mystique_t *mystique = malloc(sizeof(mystique_t)); + memset(mystique, 0, sizeof(mystique_t)); + + rom_init(&mystique->bios_rom, "MYSTIQUE.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + mystique->vram_size = device_get_config_int("memory"); + mystique->vram_mask = (mystique->vram_size << 20) - 1; + mystique->vram_mask_w = mystique->vram_mask >> 1; + mystique->vram_mask_l = mystique->vram_mask >> 2; + + svga_init(&mystique->svga, mystique, mystique->vram_size << 20, + mystique_recalctimings, + mystique_in, mystique_out, + mystique_hwcursor_draw, + NULL); + + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + mem_mapping_add(&mystique->ctrl_mapping, 0, 0, + mystique_ctrl_read_b, NULL, mystique_ctrl_read_l, + mystique_ctrl_write_b, NULL, mystique_ctrl_write_l, + NULL, 0, mystique); + mem_mapping_add(&mystique->lfb_mapping, 0, 0, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, 0, mystique); + mem_mapping_add(&mystique->iload_mapping, 0, 0, + mystique_iload_read_b, NULL, mystique_iload_read_l, + mystique_iload_write_b, NULL, mystique_iload_write_l, + NULL, 0, mystique); + + + mystique->card = pci_add(mystique_pci_read, mystique_pci_write, mystique); + mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ff8]; + + mystique->svga.miscout = 1; + mystique->pci_regs[0x41] = 0x01; /*vgaboot=1*/ + +// timer_add(&mystique->dma.timer, dma_callback, mystique, 1); + + for (c = 0; c < 256; c++) + { + dither5[c][0][0] = c >> 3; + dither5[c][1][1] = (c + 2) >> 3; + dither5[c][1][0] = (c + 4) >> 3; + dither5[c][0][1] = (c + 6) >> 3; + + if (dither5[c][1][1] > 31) + dither5[c][1][1] = 31; + if (dither5[c][1][0] > 31) + dither5[c][1][0] = 31; + if (dither5[c][0][1] > 31) + dither5[c][0][1] = 31; + + dither6[c][0][0] = c >> 2; + dither6[c][1][1] = (c + 1) >> 2; + dither6[c][1][0] = (c + 2) >> 2; + dither6[c][0][1] = (c + 3) >> 2; + + if (dither6[c][1][1] > 63) + dither6[c][1][1] = 63; + if (dither6[c][1][0] > 63) + dither6[c][1][0] = 63; + if (dither6[c][0][1] > 63) + dither6[c][0][1] = 63; + } + + mystique->wake_fifo_thread = thread_create_event(); + mystique->fifo_not_full_event = thread_create_event(); + mystique->fifo_thread = thread_create(fifo_thread, mystique); + mystique->dma.lock = thread_create_mutex(); + + timer_add(&mystique->wake_timer, mystique_wake_timer, (void *)mystique, 0); + timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *)mystique, 1); + + mystique->status = STATUS_ENDPRDMASTS; + + return mystique; +} + +static int mystique_available() +{ + return rom_present("MYSTIQUE.VBI"); +} + +static void mystique_close(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + thread_kill(mystique->fifo_thread); + thread_destroy_event(mystique->wake_fifo_thread); + thread_destroy_event(mystique->fifo_not_full_event); + thread_destroy_mutex(mystique->dma.lock); + + svga_close(&mystique->svga); + + free(mystique); +} + +static void mystique_speed_changed(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + svga_recalctimings(&mystique->svga); +} + +static void mystique_force_redraw(void *p) +{ + mystique_t *mystique = (mystique_t *)p; + + mystique->svga.fullchange = changeframecount; +} + +static void mystique_add_status_info(char *s, int max_len, void *p) +{ + mystique_t *mystique = (mystique_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - mystique->status_time; + mystique->status_time = new_time; + + if (!status_diff) + status_diff = 1; + + svga_add_status_info(s, max_len, &mystique->svga); + sprintf(temps, "In %s mode\n%f Mpixels/sec\n%f ktraps/sec\n%f%% CPU\n%f%% CPU (real)\n\n", + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) ? "MGA" : "SVGA", + (double)mystique->pixel_count/1000000.0, + (double)mystique->trap_count/1000.0, + ((double)mystique->blitter_time * 100.0) / timer_freq, + ((double)mystique->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); + + mystique->pixel_count = mystique->trap_count = 0; + mystique->blitter_time = 0; +} + +static device_config_t mystique_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; + +device_t mystique_device = +{ + "Matrox Mystique", + 0, + mystique_init, + mystique_close, + mystique_available, + mystique_speed_changed, + mystique_force_redraw, + mystique_add_status_info, + mystique_config +}; diff --git a/src/vid_mga.h b/src/vid_mga.h new file mode 100644 index 0000000..278f7be --- /dev/null +++ b/src/vid_mga.h @@ -0,0 +1 @@ +extern device_t mystique_device; diff --git a/src/vid_svga.c b/src/vid_svga.c index c265266..5361c29 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -592,11 +592,19 @@ void svga_poll(void *p) if (svga->vc == svga->split) { -// pclog("VC split\n"); - svga->ma = svga->maback = 0; - svga->sc = 0; - if (svga->attrregs[0x10] & 0x20) - svga->scrollcache = 0; + int ret = 1; + + if (svga->line_compare) + ret = svga->line_compare(svga); + + if (ret) + { +// pclog("VC split\n"); + svga->ma = svga->maback = 0; + svga->sc = 0; + if (svga->attrregs[0x10] & 0x20) + svga->scrollcache = 0; + } } if (svga->vc == svga->dispend) { diff --git a/src/vid_svga.h b/src/vid_svga.h index 5a7efa3..234a632 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -123,6 +123,11 @@ typedef struct svga_t void (*vblank_start)(struct svga_t *svga); + /*Called when VC=R18 and friends. If this returns zero then MA resetting + is skipped. Matrox Mystique in Power mode reuses this counter for + vertical line interrupt*/ + int (*line_compare)(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; diff --git a/src/video.c b/src/video.c index 9200938..b8afde8 100644 --- a/src/video.c +++ b/src/video.c @@ -28,6 +28,7 @@ #include "vid_incolor.h" #include "vid_colorplus.h" #include "vid_mda.h" +#include "vid_mga.h" #include "vid_olivetti_m24.h" #include "vid_oti037.h" #include "vid_oti067.h" @@ -98,6 +99,7 @@ static VIDEO_CARD video_cards[] = {"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, diff --git a/src/wx-thread.c b/src/wx-thread.c index 1ab591f..b96a3c9 100644 --- a/src/wx-thread.c +++ b/src/wx-thread.c @@ -69,6 +69,43 @@ void thread_destroy_event(event_t *_event) free(event); } +typedef struct win_mutex_t +{ + HANDLE handle; +} win_mutex_t; + +mutex_t *thread_create_mutex(void) +{ + win_mutex_t *mutex = malloc(sizeof(win_mutex_t)); + + mutex->handle = CreateSemaphore(NULL, 1, 1, NULL); + + return mutex; + +} + +void thread_lock_mutex(mutex_t *_mutex) +{ + win_mutex_t *mutex = (win_mutex_t *)_mutex; + + WaitForSingleObject(mutex->handle, INFINITE); +} + +void thread_unlock_mutex(mutex_t *_mutex) +{ + win_mutex_t *mutex = (win_mutex_t *)_mutex; + + ReleaseSemaphore(mutex->handle, 1, NULL); +} + +void thread_destroy_mutex(mutex_t *_mutex) +{ + win_mutex_t *mutex = (win_mutex_t *)_mutex; + + CloseHandle(mutex->handle); + + free(mutex); +} #else #include #include From 3d0986fb731fb151951451561044c362857cb546 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 Jan 2020 19:52:53 +0000 Subject: [PATCH 0760/1050] Don't map Mystique memory ranges when base addresses are zero. Fixes boot of FIC VA-503 BIOS with Mystique selected. --- src/vid_mga.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 97cf402..a4aa4d4 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -882,9 +882,18 @@ static void mystique_recalc_mapping(mystique_t *mystique) return; } - mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); - mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); - mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); + if (mystique->ctrl_base) + mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); + else + mem_mapping_disable(&mystique->ctrl_mapping); + if (mystique->lfb_base) + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + else + mem_mapping_disable(&mystique->lfb_mapping); + if (mystique->iload_base) + mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); + else + mem_mapping_disable(&mystique->iload_mapping); if (mystique->pci_regs[0x41] & 1) { From 5bf090f874efbb3b1fb0b03d78d52356d75ad6d4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 Jan 2020 20:30:35 +0000 Subject: [PATCH 0761/1050] Added pthread mutex implementation for non-Windows hosts. --- src/wx-thread.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/wx-thread.c b/src/wx-thread.c index b96a3c9..b5958ad 100644 --- a/src/wx-thread.c +++ b/src/wx-thread.c @@ -214,4 +214,43 @@ void thread_sleep(int t) { usleep(t * 1000); } + + +typedef struct pt_mutex_t +{ + pthread_mutex_t mutex; +} pt_mutex_t; + +mutex_t *thread_create_mutex(void) +{ + pt_mutex_t *mutex = malloc(sizeof(pt_mutex_t)); + + pthread_mutex_init(&mutex->mutex, NULL); + + return mutex; + +} + +void thread_lock_mutex(mutex_t *_mutex) +{ + pt_mutex_t *mutex = (pt_mutex_t *)_mutex; + + pthread_mutex_lock(&mutex->mutex); +} + +void thread_unlock_mutex(mutex_t *_mutex) +{ + pt_mutex_t *mutex = (pt_mutex_t *)_mutex; + + pthread_mutex_unlock(&mutex->mutex); +} + +void thread_destroy_mutex(mutex_t *_mutex) +{ + pt_mutex_t *mutex = (pt_mutex_t *)_mutex; + + pthread_mutex_destroy(&mutex->mutex); + + free(mutex); +} #endif From e6949e75996c6efd95da1de15402f08d6e56546e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 17 Jan 2020 19:00:00 +0000 Subject: [PATCH 0762/1050] Fix broken mappings in Cirrus Logic cards. --- src/vid_cl5429.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 70c0635..21bfab0 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1174,8 +1174,8 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - gd5429_t *gd5429 = (gd5429_t *)svga->p; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_write_linear(addr, val, svga); @@ -1184,8 +1184,8 @@ static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p) } static void gd5429_writew_linear(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - gd5429_t *gd5429 = (gd5429_t *)svga->p; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_writew_linear(addr, val, svga); @@ -1197,8 +1197,8 @@ static void gd5429_writew_linear(uint32_t addr, uint16_t val, void *p) } static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; - gd5429_t *gd5429 = (gd5429_t *)svga->p; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) svga_writel_linear(addr, val, svga); @@ -1296,15 +1296,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) else { if (!(svga->seqregs[7] & 0xf0)) - { mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); - mem_mapping_set_p(&svga->mapping, gd5429); - } else - { - mem_mapping_set_handler(&gd5429->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); - mem_mapping_set_p(&gd5429->linear_mapping, svga); - } + mem_mapping_set_handler(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); gd5429_recalc_mapping(gd5429); } } @@ -1494,15 +1488,9 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) if (gd5429->blt.mode & 0x04) { if (!(svga->seqregs[7] & 0xf0)) - { mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); - mem_mapping_set_p(&svga->mapping, gd5429); - } else - { - mem_mapping_set_handler(&gd5429->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); - mem_mapping_set_p(&gd5429->linear_mapping, svga); - } + mem_mapping_set_handler(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear); // mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); // mem_mapping_set_p(&gd5429->svga.mapping, gd5429); gd5429_recalc_mapping(gd5429); @@ -1847,7 +1835,7 @@ static void *cl_init(int type, char *fn, int pci_card) mem_mapping_set_p(&gd5429->svga.mapping, gd5429); mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); - mem_mapping_add(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, svga); + mem_mapping_add(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, gd5429); io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); if (type == CL_TYPE_AVGA2) From b72aa2117b3abc06be356a66272d3dfc513ff5cd Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 Jan 2020 15:50:46 +0000 Subject: [PATCH 0763/1050] Mystique fixes : - MGA mode disables all VGA data processing on reads / writes - MGA mode forces 8 pixels per character - DMAPAD acts as an ILOAD mirror during ILOAD operations, same as SRCx - Handle signed X coordinates better in blit operations - Add more MMIO registers - Don't fatal on ILOAD reads when blitter not busy Fixes Windows XP with Mystique. --- src/vid_mga.c | 212 ++++++++++++++++++++++++++++++++++++++++++------- src/vid_svga.c | 5 +- src/vid_svga.h | 1 + 3 files changed, 189 insertions(+), 29 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index a4aa4d4..655ed1b 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -222,6 +222,13 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); +static uint8_t mystique_readb_linear(uint32_t addr, void *p); +static uint16_t mystique_readw_linear(uint32_t addr, void *p); +static uint32_t mystique_readl_linear(uint32_t addr, void *p); +static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p); +static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p); +static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p); + static const uint8_t trans_masks[16][16] = { { @@ -401,11 +408,15 @@ enum #define REG_PRIMEND 0x1e5c #define REG_DWG_INDIR_WT 0x1e80 +#define REG_ATTR_IDX 0x1fc0 +#define REG_ATTR_DATA 0x1fc1 #define REG_INSTS0 0x1fc2 #define REG_MISC 0x1fc2 #define REG_SEQ_IDX 0x1fc4 #define REG_SEQ_DATA 0x1fc5 #define REG_MISCREAD 0x1fcc +#define REG_GCTL_IDX 0x1fce +#define REG_GCTL_DATA 0x1fcf #define REG_CRTC_IDX 0x1fd4 #define REG_CRTC_DATA 0x1fd5 #define REG_INSTS1 0x1fda @@ -814,6 +825,9 @@ void mystique_recalctimings(svga_t *svga) // svga->split = 99999; svga->lowres = 0; + svga->char_width = 8; + svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp_time = svga->hdisp; svga->rowoffset = row_offset * 2; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 17) | (svga->crtc[0xc] << 9) | (svga->crtc[0xd] << 1); @@ -857,11 +871,19 @@ void mystique_recalctimings(svga_t *svga) svga->line_compare = mystique_line_compare; // pclog("recalc: htotal=%i vtotal=%i dispend=%i\n", svga->htotal, svga->vtotal, svga->dispend); + + mem_mapping_set_handler(&mystique->lfb_mapping, + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear); } else { svga->line_compare = NULL; svga->bpp = 8; + + mem_mapping_set_handler(&mystique->lfb_mapping, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear); } } @@ -1243,7 +1265,14 @@ static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) case REG_VCOUNT: case REG_VCOUNT+1: case REG_VCOUNT+2: case REG_VCOUNT+3: READ8(addr, svga->vc); break; - + + case REG_ATTR_IDX: + ret = svga_in(0x3c0, svga); + break; + case REG_ATTR_DATA: + ret = svga_in(0x3c1, svga); + break; + case REG_INSTS0: ret = svga_in(0x3c2, svga); break; @@ -1259,6 +1288,13 @@ static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) ret = svga_in(0x3cc, svga); break; + case REG_GCTL_IDX: + ret = mystique_in(0x3ce, mystique); + break; + case REG_GCTL_DATA: + ret = mystique_in(0x3cf, mystique); + break; + case REG_CRTC_IDX: ret = mystique_in(0x3d4, mystique); break; @@ -1294,6 +1330,7 @@ static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) ret = mystique_read_xreg(mystique, mystique->xreg_idx); break; + case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53: case REG_ICLEAR: case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: case 0x2c30: case 0x2c31: case 0x2c32: case 0x2c33: case 0x3e08: @@ -1302,6 +1339,8 @@ static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) default: if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) break; + if ((addr & 0x3fff) >= 0x3e00) + break; fatal("Read MGA control %08x\n", addr & 0x3fff); } @@ -1647,6 +1686,13 @@ static void mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) mystique->status = STATUS_ENDPRDMASTS; break; + case REG_ATTR_IDX: + svga_out(0x3c0, val, svga); + break; + case REG_ATTR_DATA: + svga_out(0x3c1, val, svga); + break; + case REG_MISC: svga_out(0x3c2, val, svga); break; @@ -1658,6 +1704,13 @@ static void mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) svga_out(0x3c5, val, svga); break; + case REG_GCTL_IDX: + mystique_out(0x3ce, val, mystique); + break; + case REG_GCTL_DATA: + mystique_out(0x3cf, val, mystique); + break; + case REG_CRTC_IDX: mystique_out(0x3d4, val, mystique); break; @@ -1709,6 +1762,8 @@ static void mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) default: if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) break; + if ((addr & 0x3fff) >= 0x3e00) + break; fatal("Write MGA control %08x %02x\n", addr & 0x3fff, val); break; } @@ -1727,7 +1782,7 @@ static uint32_t mystique_ctrl_read_l(uint32_t addr, void *p) ret |= mystique_ctrl_read_b(addr+2, p) << 16; ret |= mystique_ctrl_read_b(addr+3, p) << 24; // pclog("mcrl: addr=%08x ret=%08x %08x\n", addr, ret, mystique->status); - + return ret; } @@ -1823,6 +1878,8 @@ static void mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) case REG_DMAPAD: + if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[0], 32); break; case REG_AR0: @@ -1999,7 +2056,10 @@ static uint8_t mystique_iload_read_b(uint32_t addr, void *p) wait_fifo_idle(mystique); if (!mystique->busy) - fatal("mystique_iload_read_b: !busy\n"); + { +// fatal("mystique_iload_read_b: %08x !busy\n", addr); + return 0xff; + } // pclog("Readb MGA ILOAD %08x\n", addr); return blit_idump_read(mystique); @@ -2010,7 +2070,10 @@ static uint32_t mystique_iload_read_l(uint32_t addr, void *p) wait_fifo_idle(mystique); if (!mystique->busy) - fatal("mystique_iload_read_l: !busy\n"); + { +// fatal("mystique_iload_read_l: !busy\n"); + return 0xffffffff; + } // pclog("Readl MGA ILOAD %08x %i\n", addr, mystique->dwgreg.words); mystique->dwgreg.words++; @@ -2032,7 +2095,7 @@ static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) { mystique_t *mystique = (mystique_t *)p; -// pclog(" Write ILOAD %08x %i %i\n", val, mystique->dwgreg.dmamod, mystique->dma.iload_state); +// pclog(" Write ILOAD %08x %i %i %08x\n", val, mystique->dwgreg.dmamod, mystique->dma.iload_state, mystique->dwgreg.dwgctrl); switch (mystique->dwgreg.dmamod) { case DMA_MODE_REG: @@ -2072,6 +2135,101 @@ static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) } +static uint8_t mystique_readb_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + egareads++; + + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + + return svga->vram[addr & svga->vram_mask]; +} +static uint16_t mystique_readw_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + egareads += 2; + + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; + + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; +} +static uint32_t mystique_readl_linear(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + + egareads += 4; + + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; + + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; +} + +static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + egawrites++; + + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr] = val; +} +static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + egawrites += 2; + + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; +} +static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + + egawrites += 4; + + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; +} + @@ -3550,8 +3708,8 @@ static void blit_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int x_l = mystique->dwgreg.fxleft & 0xffff; - int x_r = mystique->dwgreg.fxright & 0xffff; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; // pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); @@ -3597,7 +3755,7 @@ static void blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l = (x_l + 1) & 0xffff; + x_l++; mystique->pixel_count++; } @@ -3635,8 +3793,8 @@ static void blit_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int x_l = mystique->dwgreg.fxleft & 0xffff; - int x_r = mystique->dwgreg.fxright & 0xffff; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; // pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); @@ -3693,7 +3851,7 @@ static void blit_trap(mystique_t *mystique) fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l = (x_l + 1) & 0xffff; + x_l++; mystique->pixel_count++; } @@ -3741,9 +3899,9 @@ static void blit_trap(mystique_t *mystique) { uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - int x_l = mystique->dwgreg.fxleft & 0xffff; - int x_r = mystique->dwgreg.fxright & 0xffff; - int old_x_l = x_l; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; int dx; z_back = mystique->dwgreg.dr[0]; @@ -3813,7 +3971,7 @@ static void blit_trap(mystique_t *mystique) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - x_l = (x_l + 1) & 0xffff; + x_l++; mystique->pixel_count++; } @@ -3985,9 +4143,9 @@ static void blit_texture_trap(mystique_t *mystique) { uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - int x_l = mystique->dwgreg.fxleft & 0xffff; - int x_r = mystique->dwgreg.fxright & 0xffff; - int old_x_l = x_l; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; int dx; uint32_t z_back = mystique->dwgreg.dr[0]; @@ -4095,7 +4253,7 @@ static void blit_texture_trap(mystique_t *mystique) } } skip_pixel: - x_l = (x_l + 1) & 0xffff; + x_l++; mystique->pixel_count++; mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; @@ -4159,8 +4317,8 @@ static void blit_bitblt(mystique_t *mystique) uint32_t src_addr; int y; int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; - int x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; - int x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) @@ -4181,7 +4339,7 @@ static void blit_bitblt(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { - int x = x_start; + int16_t x = x_start; // pclog(" line %03i: %08x %08x %02x\n", y, mystique->dwgreg.ydst_lin, src_addr, svga->vram[0x2eba3]); while (1) @@ -4264,7 +4422,7 @@ static void blit_bitblt(mystique_t *mystique) src_addr += x_dir; if (x != x_end) - x = (x + x_dir) & 0xffff; + x += x_dir; else break; } @@ -4324,7 +4482,7 @@ static void blit_bitblt(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int x = x_start; + int16_t x = x_start; // pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, src_addr); while (1) @@ -4390,7 +4548,7 @@ static void blit_bitblt(mystique_t *mystique) src_addr += x_dir; if (x != x_end) - x = (x + x_dir) & 0xffff; + x += x_dir; else break; } @@ -4414,7 +4572,7 @@ static void blit_bitblt(mystique_t *mystique) { uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; uint32_t old_src_addr = src_addr; - int x = x_start; + int16_t x = x_start; // pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, src_addr); while (1) @@ -4492,7 +4650,7 @@ static void blit_bitblt(mystique_t *mystique) src_addr += x_dir; if (x != x_end) - x = (x + x_dir) & 0xffff; + x += x_dir; else break; } diff --git a/src/vid_svga.c b/src/vid_svga.c index 5361c29..9c3cd7c 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -418,13 +418,14 @@ void svga_recalctimings(svga_t *svga) svga->linedbl = svga->crtc[9] & 0x80; svga->rowcount = svga->crtc[9] & 31; + svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; if (svga->recalctimings_ex) svga->recalctimings_ex(svga); if (svga->vblankstart < svga->dispend) svga->dispend = svga->vblankstart; - crtcconst = (svga->seqregs[1] & 1) ? (svga->clock * 8.0) : (svga->clock * 9.0); + crtcconst = svga->clock * svga->char_width; disptime = svga->htotal; _dispontime = svga->hdisp_time; @@ -670,7 +671,7 @@ void svga_poll(void *p) // pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres); if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ { - svga->video_res_x /= (svga->seqregs[1] & 1) ? 8 : 9; + svga->video_res_x /= svga->char_width; svga->video_res_y /= (svga->crtc[9] & 31) + 1; svga->video_bpp = 0; } diff --git a/src/vid_svga.h b/src/vid_svga.h index 234a632..83d9cbc 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -77,6 +77,7 @@ typedef struct svga_t int linepos, vslines, linecountff, oddeven; int con, cursoron, blink; int scrollcache; + int char_width; int firstline, lastline; int firstline_draw, lastline_draw; From 60472b3a66797ddd2eca350c957d73aa0ea16cd6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 Jan 2020 21:26:50 +0000 Subject: [PATCH 0764/1050] Add emulation of SCAMP DRAM controls. This primarily emulates the mirroring effects of the controller programmed to the wrong DRAM size, which is required for the Commodore SL386SX to be able to detect memory size correctly. --- src/scamp.c | 588 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 558 insertions(+), 30 deletions(-) diff --git a/src/scamp.c b/src/scamp.c index 6fe9570..d11e3cc 100644 --- a/src/scamp.c +++ b/src/scamp.c @@ -9,12 +9,23 @@ static struct uint8_t cfg_regs[256]; int cfg_enable; + int ram_config; + + mem_mapping_t ram_mapping[2]; + uint32_t ram_virt_base[2], ram_phys_base[2]; + uint32_t ram_mask[2]; + int row_virt_shift[2], row_phys_shift[2]; + int ram_interleaved[2]; + int ibank_shift[2]; + uint8_t port_92; } scamp; #define CFG_ID 0x00 #define CFG_SLTPTR 0x02 #define CFG_RAMMAP 0x03 +#define CFG_EMSEN1 0x0b +#define CFG_EMSEN2 0x0c #define CFG_ABAXS 0x0e #define CFG_CAXS 0x0f #define CFG_DAXS 0x10 @@ -24,6 +35,453 @@ static struct #define RAMMAP_REMP386 (1 << 4) +/*Commodore SL386SX requires proper memory slot decoding to detect memory size. + Therefore we emulate the SCAMP memory address decoding, and therefore are + limited to the DRAM combinations supported by the actual chip*/ +enum +{ + BANK_NONE, + BANK_256K, + BANK_256K_INTERLEAVED, + BANK_1M, + BANK_1M_INTERLEAVED, + BANK_4M, + BANK_4M_INTERLEAVED +}; + +static const struct +{ + int size_kb; + int rammap; + int bank[2]; +} ram_configs[] = +{ + {512, 0x0, {BANK_256K, BANK_NONE}}, + {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}}, + {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}}, + {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}}, + {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}}, + {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}}, + {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}}, + {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}}, + {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}}, +}; + +static const struct +{ + int bank[2]; + int remapped; +} rammap[16] = +{ + {{BANK_256K, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0}, + + {{BANK_1M, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + + {{BANK_4M, BANK_NONE}, 0}, + {{BANK_4M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/ + {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/ + + {{BANK_256K_INTERLEAVED, BANK_1M}, 0}, + {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/ +}; + +/*The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous, + so we use separate routines for that special case*/ +static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return 0xff; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + return ram[addr + scamp.ram_phys_base[bank]]; +} +static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + ram[addr + scamp.ram_phys_base[bank]] = val; +} + +/*Read/write handlers for interleaved memory banks. We must keep CPU and ram array + mapping linear, otherwise we won't be able to execute code from interleaved banks*/ +static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return 0xff; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = (addr >> (scamp.row_virt_shift[bank]+1)) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + return ram[addr + scamp.ram_phys_base[bank]]; +} +static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) + { + if (addr & 0x400) + return; + + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } + else + { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = (addr >> (scamp.row_virt_shift[bank]+1)) & scamp.ram_mask[bank]; + + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank]+1)); + } + + ram[addr + scamp.ram_phys_base[bank]] = val; +} + +static uint8_t ram_mirrored_read(uint32_t addr, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + + return ram[addr + scamp.ram_phys_base[bank]]; +} +static void ram_mirrored_write(uint32_t addr, uint8_t val, void *p) +{ + int bank = (int)p; + int row, column, byte; + + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + + ram[addr + scamp.ram_phys_base[bank]] = val; +} + +static void recalc_mappings(void) +{ + int c; + uint32_t virt_base = 0; + uint8_t cur_rammap = scamp.cfg_regs[CFG_RAMMAP] & 0xf; + int bank_nr = 0; + + for (c = 0; c < 2; c++) + mem_mapping_disable(&scamp.ram_mapping[c]); + + /*Once the BIOS programs the correct DRAM configuration, switch to regular + linear memory mapping*/ + if (cur_rammap == ram_configs[scamp.ram_config].rammap) + { + mem_mapping_set_handler(&ram_low_mapping, + mem_read_ram, mem_read_ramw, mem_read_raml, + mem_write_ram, mem_write_ramw, mem_write_raml); + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_enable(&ram_high_mapping); + return; + } + else + { + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_low_mapping); + } + + if (rammap[cur_rammap].bank[0] == BANK_NONE) + bank_nr = 1; + + pclog("Bank remap, cur_rammap=%x\n", cur_rammap); + + for (; bank_nr < 2; bank_nr++) + { + uint32_t old_virt_base = virt_base; + int phys_bank = ram_configs[scamp.ram_config].bank[bank_nr]; + + pclog(" Bank %i: phys_bank=%i rammap_bank=%i virt_base=%08x phys_base=%08x\n", bank_nr, phys_bank, rammap[cur_rammap].bank[bank_nr], virt_base, scamp.ram_phys_base[bank_nr]); + scamp.ram_virt_base[bank_nr] = virt_base; + + if (virt_base == 0) + { + switch (rammap[cur_rammap].bank[bank_nr]) + { + case BANK_NONE: + fatal("Bank 0 is empty!\n"); + break; + + case BANK_256K: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + } + virt_base += 512*1024; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + } + virt_base += 512*1024*2; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_1M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x100000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 2048*1024; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x300000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 2048*1024*2; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_4M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x700000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 8192*1024; + scamp.row_virt_shift[bank_nr] = 12; + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0xf00000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 8192*1024*2; + scamp.row_virt_shift[bank_nr] = 12; + break; + } + } + else + { + switch (rammap[cur_rammap].bank[bank_nr]) + { + case BANK_NONE: + break; + + case BANK_256K: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x80000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 512*1024; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x100000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 512*1024*2; + scamp.row_virt_shift[bank_nr] = 10; + break; + + case BANK_1M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x200000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 2048*1024; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x400000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 2048*1024*2; + scamp.row_virt_shift[bank_nr] = 11; + break; + + case BANK_4M: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x800000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 8192*1024; + scamp.row_virt_shift[bank_nr] = 12; + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) + { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x1000000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 8192*1024*2; + scamp.row_virt_shift[bank_nr] = 12; + break; + } + } + switch (rammap[cur_rammap].bank[bank_nr]) + { + case BANK_256K: case BANK_1M: case BANK_4M: + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + pclog(" not interleaved\n"); + break; + + case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED: + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + pclog(" interleaved\n"); + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) + { + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + pclog(" 256k in 4mi\n"); + } + else + { + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + pclog(" interleaved\n"); + } + break; + } + } +} + +#define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) + static void shadow_control(uint32_t addr, uint32_t size, int state) { // pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); @@ -79,27 +537,10 @@ void scamp_write(uint16_t addr, uint8_t val, void *p) switch (scamp.cfg_index) { case CFG_SLTPTR: -#if 0 - if (!val) - { - /*Disable all RAM*/ - mem_mapping_disable(&ram_low_mapping); - mem_mapping_disable(&ram_high_mapping); - } - else if (val < 0x10) - { - mem_mapping_set_addr(&ram_low_mapping, 0, (val > 9) ? 0xa0000 : (val << 16)); - mem_mapping_disable(&ram_high_mapping); - } - else - { - mem_mapping_enable(&ram_low_mapping); - mem_mapping_enable(&ram_high_mapping); - } -#endif break; case CFG_RAMMAP: + recalc_mappings(); mem_mapping_disable(&ram_remapped_mapping); if (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) { @@ -114,20 +555,20 @@ void scamp_write(uint16_t addr, uint8_t val, void *p) shadow_control(0xb0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); shadow_control(0xb8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); - shadow_control(0xc0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xc4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xc8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xcc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + shadow_control(0xc0000, 0x4000, scamp.cfg_regs[CFG_CAXS] & 3); + shadow_control(0xc4000, 0x4000, (scamp.cfg_regs[CFG_CAXS] >> 2) & 3); + shadow_control(0xc8000, 0x4000, (scamp.cfg_regs[CFG_CAXS] >> 4) & 3); + shadow_control(0xcc000, 0x4000, (scamp.cfg_regs[CFG_CAXS] >> 6) & 3); - shadow_control(0xd0000, 0x4000, scamp.cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xd4000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xd8000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xdc000, 0x4000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + shadow_control(0xd0000, 0x4000, scamp.cfg_regs[CFG_DAXS] & 3); + shadow_control(0xd4000, 0x4000, (scamp.cfg_regs[CFG_DAXS] >> 2) & 3); + shadow_control(0xd8000, 0x4000, (scamp.cfg_regs[CFG_DAXS] >> 4) & 3); + shadow_control(0xdc000, 0x4000, (scamp.cfg_regs[CFG_DAXS] >> 6) & 3); - shadow_control(0xe0000, 0x8000, scamp.cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xe8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xf0000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xf8000, 0x8000, (scamp.cfg_regs[CFG_ABAXS] >> 6) & 3); + shadow_control(0xe0000, 0x8000, scamp.cfg_regs[CFG_FEAXS] & 3); + shadow_control(0xe8000, 0x8000, (scamp.cfg_regs[CFG_FEAXS] >> 2) & 3); + shadow_control(0xf0000, 0x8000, (scamp.cfg_regs[CFG_FEAXS] >> 4) & 3); + shadow_control(0xf8000, 0x8000, (scamp.cfg_regs[CFG_FEAXS] >> 6) & 3); } break; @@ -217,6 +658,9 @@ uint8_t scamp_read(uint16_t addr, void *p) void scamp_init(void) { + uint32_t addr; + int c; + memset(&scamp, 0, sizeof(scamp)); scamp.cfg_regs[CFG_ID] = ID_VL82C311; scamp.cfg_enable = 1; @@ -227,4 +671,88 @@ void scamp_init(void) io_sethandler(0x00f4, 0x0002, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); io_sethandler(0x00f9, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); io_sethandler(0x00fb, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + + scamp.ram_config = 0; + + /*Find best fit configuration for the requested memory size*/ + for (c = 0; c < NR_ELEMS(ram_configs); c++) + { + if (mem_size < ram_configs[c].size_kb) + break; + + scamp.ram_config = c; + } + + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_high_mapping); + + addr = 0; + for (c = 0; c < 2; c++) + { + mem_mapping_add(&scamp.ram_mapping[c], 0, 0, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL, + &ram[addr], MEM_MAPPING_INTERNAL, (void *)c); + mem_mapping_disable(&scamp.ram_mapping[c]); + + scamp.ram_phys_base[c] = addr; +// pclog("Bank calc : %i = %08x\n", c ,addr); + + switch (ram_configs[scamp.ram_config].bank[c]) + { + case BANK_NONE: + scamp.ram_mask[c] = 0; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_256K: + addr += 512*1024; + scamp.ram_mask[c] = 0x1ff; + scamp.row_phys_shift[c] = 10; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_256K_INTERLEAVED: + addr += 512*1024*2; + scamp.ram_mask[c] = 0x1ff; + scamp.row_phys_shift[c] = 10; + scamp.ibank_shift[c] = 19; + scamp.ram_interleaved[c] = 1; + break; + + case BANK_1M: + addr += 2048*1024; + scamp.ram_mask[c] = 0x3ff; + scamp.row_phys_shift[c] = 11; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_1M_INTERLEAVED: + addr += 2048*1024*2; + scamp.ram_mask[c] = 0x3ff; + scamp.row_phys_shift[c] = 11; + scamp.ibank_shift[c] = 21; + scamp.ram_interleaved[c] = 1; + break; + + case BANK_4M: + addr += 8192*1024; + scamp.ram_mask[c] = 0x7ff; + scamp.row_phys_shift[c] = 12; + scamp.ram_interleaved[c] = 0; + break; + + case BANK_4M_INTERLEAVED: + addr += 8192*1024*2; + scamp.ram_mask[c] = 0x7ff; + scamp.row_phys_shift[c] = 12; + scamp.ibank_shift[c] = 23; + scamp.ram_interleaved[c] = 1; + break; + } + } + + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } From cbcc5d126a01393f7bc0af080b6e1011cda734f2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 20 Jan 2020 18:04:29 +0000 Subject: [PATCH 0765/1050] Fix read latch address on AVGA2/Cirrus Logic cards. --- src/vid_cl5429.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 21bfab0..ebd3118 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1098,13 +1098,18 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) svga_t *svga = &gd5429->svga; uint8_t temp, temp2, temp3, temp4; int readplane = svga->readplane; - uint32_t latch_addr = (addr << 2) & svga->decode_mask; + uint32_t latch_addr; cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; egareads++; + if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + latch_addr = (addr << 3) & svga->decode_mask; + else + latch_addr = (addr << 2) & svga->decode_mask; + if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; else if (svga->chain4 || svga->fb_only) From bbef0fd1cd45db6f5492b5b294dc117516357feb Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 20 Jan 2020 18:22:50 +0000 Subject: [PATCH 0766/1050] Added discrete AVGA2 card. --- src/ibm.h | 1 + src/vid_cl5429.c | 21 +++++++++++++++++++++ src/vid_cl5429.h | 1 + src/video.c | 1 + 4 files changed, 24 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index b5d2c83..661d950 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -303,6 +303,7 @@ enum GFX_IM1024, /*Vermont Microsystems IM1024 */ GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/ GFX_MYSTIQUE, /*Matrox Mystique*/ + GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/ GFX_MAX }; diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index ebd3118..f94fddf 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1886,6 +1886,10 @@ static void *cl_init(int type, char *fn, int pci_card) } +static void *avga2_init() +{ + return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1); +} static void *avga2_cbm_sl386sx_init() { return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1); @@ -1911,6 +1915,10 @@ static void *gd5434_pb520r_init() return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3); } +static int avga2_available() +{ + return rom_present("avga2vram.vbi"); +} static int gd5429_available() { return rom_present("5429.vbi"); @@ -2034,6 +2042,19 @@ static device_config_t gd5434_config[] = } }; +device_t avga2_device = +{ + "AVGA2 / Cirrus Logic GD5402", + 0, + avga2_init, + gd5429_close, + avga2_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + avga2_config +}; + device_t avga2_cbm_sl386sx_device = { "AVGA2 (Commodore SL386SX-25)", diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index 9398b27..7ba0941 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1,3 +1,4 @@ +extern device_t avga2_device; extern device_t avga2_cbm_sl386sx_device; extern device_t gd5429_device; extern device_t gd5430_device; diff --git a/src/video.c b/src/video.c index b8afde8..0105b48 100644 --- a/src/video.c +++ b/src/video.c @@ -82,6 +82,7 @@ typedef struct static VIDEO_CARD video_cards[] = { + {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI EGA Wonder 800+ (ATI-18800)", "egawonder800", &ati_ega_wonder_800_device, GFX_EGAWONDER800, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From 0e8926936df117feb59cecbaca10141a9d568a05 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 22 Jan 2020 20:53:13 +0000 Subject: [PATCH 0767/1050] Added FPU support for pre-486 CPUs. This commit does not include timings for 8087, 80287 or 80387 FPUs, these will be added later. It also does not restrict the use of 486 and later FPU instructions. --- src/8087.h | 98 +++ src/808x.c | 76 ++- src/cpu.c | 55 +- src/cpu.h | 23 + src/cpu_tables.c | 493 ++++++++------- src/keyboard_xt.c | 4 +- src/pc.c | 4 + src/pc.xrc | 39 ++ src/wx-config.c | 59 +- src/wx-resources.cpp | 1411 ++++++++++++++++++++++-------------------- src/x87_ops.h | 4 + 11 files changed, 1348 insertions(+), 918 deletions(-) create mode 100644 src/8087.h diff --git a/src/8087.h b/src/8087.h new file mode 100644 index 0000000..6e5401a --- /dev/null +++ b/src/8087.h @@ -0,0 +1,98 @@ +/*This file is a series of macros to get the 386+ based x87 emulation working with + the 808x emulation*/ +#define X8087 +#define OP_TABLE(name) ops_808x_ ## name + +#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + +#define fetch_ea_16(fetchdat) +#define fetch_ea_32(fetchdat) +#define SEG_CHECK_READ(seg) +#define SEG_CHECK_WRITE(seg) +#define CHECK_WRITE(seg, addr_lo, addr_hi) +#define PREFETCH_RUN(timing, bytes, rmdat, a, b, c, d, e) + +static uint32_t readmeml(uint32_t seg, uint32_t addr) +{ + return readmemw(seg, addr) | (readmemw(seg, addr+2) << 16); +} +static uint64_t readmemq(uint32_t seg, uint32_t addr) +{ + return (uint64_t)readmemw(seg, addr) | ((uint64_t)readmemw(seg, addr+2) << 16) | + ((uint64_t)readmemw(seg, addr+4) << 32) | + ((uint64_t)readmemw(seg, addr+6) << 48); +} + +static void writememb_8087(uint32_t seg, uint32_t addr, uint8_t val) +{ + writememb(seg+addr, val); +} +static void writememl(uint32_t seg, uint32_t addr, uint32_t val) +{ + writememw(seg, addr, val & 0xffff); + writememw(seg, addr+2, (val >> 16) & 0xffff); +} +static void writememq(uint32_t seg, uint32_t addr, uint64_t val) +{ + writememw(seg, addr, val & 0xffff); + writememw(seg, addr+2, (val >> 16) & 0xffff); + writememw(seg, addr+4, (val >> 32) & 0xffff); + writememw(seg, addr+6, (val >> 48) & 0xffff); +} + +static inline uint32_t geteal() +{ + if (cpu_mod == 3) + fatal("geteal cpu_mod==3\n"); + return readmeml(easeg, cpu_state.eaaddr); +} +static inline uint64_t geteaq() +{ + if (cpu_mod == 3) + fatal("geteaq cpu_mod==3\n"); + return readmemq(easeg, cpu_state.eaaddr); +} +static inline void seteal(uint32_t val) +{ + if (cpu_mod == 3) + fatal("seteal cpu_mod==3\n"); + else + writememl(easeg, cpu_state.eaaddr, val); +} +static inline void seteaq(uint64_t val) +{ + if (cpu_mod == 3) + fatal("seteaq cpu_mod==3\n"); + else + writememq(easeg, cpu_state.eaaddr, val); +} + +#define flags_rebuild() + +#define CF_SET() (cpu_state.flags & C_FLAG) +#define NF_SET() (cpu_state.flags & N_FLAG) +#define PF_SET() (cpu_state.flags & P_FLAG) +#define VF_SET() (cpu_state.flags & V_FLAG) +#define ZF_SET() (cpu_state.flags & Z_FLAG) + +#define cond_O ( VF_SET()) +#define cond_NO (!VF_SET()) +#define cond_B ( CF_SET()) +#define cond_NB (!CF_SET()) +#define cond_E ( ZF_SET()) +#define cond_NE (!ZF_SET()) +#define cond_BE ( CF_SET() || ZF_SET()) +#define cond_NBE (!CF_SET() && !ZF_SET()) +#define cond_S ( NF_SET()) +#define cond_NS (!NF_SET()) +#define cond_P ( PF_SET()) +#define cond_NP (!PF_SET()) +#define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0)) +#define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0)) +#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) +#define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET())) + +#define writememb writememb_8087 +#include "x87_ops.h" +#undef writememb diff --git a/src/808x.c b/src/808x.c index af45bf4..12566f9 100644 --- a/src/808x.c +++ b/src/808x.c @@ -1104,6 +1104,8 @@ static void rep(int fv) static int inhlt=0; static int skipnextprint=0; +#include "8087.h" + void execx86(int cycs) { uint8_t temp,temp2; @@ -2945,10 +2947,78 @@ void execx86(int cycs) AL=readmemb(ds+addr); cycles-=11; break; - case 0xD9: case 0xDA: case 0xDB: case 0xDD: /*ESCAPE*/ - case 0xDC: case 0xDE: case 0xDF: case 0xD8: + + case 0xd8: fetchea(); - geteab(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_d8_a16[rmdat >> 3](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xd9: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_d9_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xda: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_da_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdb: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_db_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdc: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_dc_a16[rmdat >> 3](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdd: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_dd_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xde: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_de_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdf: + fetchea(); + if (hasfpu) + { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_df_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } break; case 0xE0: /*LOOPNE*/ diff --git a/src/cpu.c b/src/cpu.c index 42cbee1..07e46b0 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -7,6 +7,7 @@ #include "pci.h" #include "codegen.h" +int fpu_type; uint32_t cpu_features; static int cpu_turbo_speed, cpu_nonturbo_speed; @@ -125,10 +126,59 @@ void cpu_set_edx() EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset; } +int fpu_get_type(int model, int manu, int cpu, const char *internal_name) +{ + CPU *cpu_s = &models[model].cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; + + while (fpus[c].internal_name) + { + if (!strcmp(internal_name, fpus[c].internal_name)) + fpu_type = fpus[c].type; + c++; + } + + return fpu_type; +} + +const char *fpu_get_internal_name(int model, int manu, int cpu, int type) +{ + CPU *cpu_s = &models[model].cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int c = 0; + + while (fpus[c].internal_name) + { + if (fpus[c].type == type) + return fpus[c].internal_name; + c++; + } + + return fpus[0].internal_name; +} + +const char *fpu_get_name_from_index(int model, int manu, int cpu, int c) +{ + CPU *cpu_s = &models[model].cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + + return fpus[c].name; +} + +int fpu_get_type_from_index(int model, int manu, int cpu, int c) +{ + CPU *cpu_s = &models[model].cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + + return fpus[c].type; +} + void cpu_set() { CPU *cpu_s; - + if (!models[model].cpu[cpu_manufacturer].cpus) { /*CPU is invalid, set to default*/ @@ -143,7 +193,8 @@ void cpu_set() is8086 = (cpu_s->cpu_type > CPU_8088); is386 = (cpu_s->cpu_type >= CPU_386SX); is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC); - hasfpu = (cpu_s->cpu_type >= CPU_i486DX); + hasfpu = (fpu_type != FPU_NONE); + 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) diff --git a/src/cpu.h b/src/cpu.h index 2e8cc4f..1cb4cf8 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -2,6 +2,7 @@ #define _CPU_H_ extern int cpu, cpu_manufacturer; +extern int fpu_type; /*808x class CPUs*/ #define CPU_8088 0 @@ -60,10 +61,27 @@ extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; extern int timing_misaligned; +enum +{ + FPU_NONE, + FPU_8087, + FPU_287, + FPU_387, + FPU_BUILTIN +}; + +typedef struct +{ + const char *name; + const char *internal_name; + const int type; +} FPU; + typedef struct { char name[32]; int cpu_type; + const FPU *fpus; int speed; int rspeed; int multi; @@ -171,4 +189,9 @@ int cpu_get_speed(); extern int has_vlb; +int fpu_get_type(int model, int manu, int cpu, const char *internal_name); +const char *fpu_get_internal_name(int model, int manu, int cpu, int type); +const char *fpu_get_name_from_index(int model, int manu, int cpu, int c); +int fpu_get_type_from_index(int model, int manu, int cpu, int c); + #endif diff --git a/src/cpu_tables.c b/src/cpu_tables.c index ea5e2d1..84863d4 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -22,257 +22,286 @@ 17 = 200 MHz */ +FPU fpus_none[] = +{ + {"None", "none", FPU_NONE}, + {NULL, NULL, 0} +}; +FPU fpus_8088[] = +{ + {"None", "none", FPU_NONE}, + {"8087", "8087", FPU_8087}, + {NULL, NULL, 0} +}; +FPU fpus_80286[] = +{ + {"None", "none", FPU_NONE}, + {"287", "287", FPU_287}, + {NULL, NULL, 0} +}; +FPU fpus_80386[] = +{ + {"None", "none", FPU_NONE}, + {"387", "387", FPU_387}, + {NULL, NULL, 0} +}; +FPU fpus_builtin[] = +{ + {"Built-in", "builtin", FPU_BUILTIN}, + {NULL, NULL, 0} +}; + CPU cpus_8088[] = { /*8088 standard*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/4.77", CPU_8088, fpus_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, fpus_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/8", CPU_8088, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, fpus_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, fpus_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, fpus_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_pcjr[] = { /*8088 PCjr*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/4.77", CPU_8088, fpus_none, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 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, 1}, - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/4.77", CPU_8088, fpus_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, fpus_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/9.54", CPU_8088, fpus_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_8086[] = { /*8086 standard*/ - {"8086/7.16", CPU_8086, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/9.54", CPU_8086, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/12", CPU_8086, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/16", CPU_8086, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, + {"8086/7.16", CPU_8086, fpus_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/8", CPU_8086, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, fpus_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/10", CPU_8086, fpus_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/12", CPU_8086, fpus_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/16", CPU_8086, fpus_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, {"", -1, 0, 0, 0, 0} }; CPU cpus_pc1512[] = { /*8086 Amstrad*/ - {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/8", CPU_8086, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_286[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/8", CPU_286, fpus_80286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, fpus_80286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, fpus_80286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, fpus_80286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ibmat[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, - {"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, + {"286/8", CPU_286, fpus_80286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ibmxt286[] = { /*286*/ - {"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, {"", -1, 0, 0, 0, 0} }; CPU cpus_ps1_m2011[] = { /*286*/ - {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, {"", -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, 1}, - {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, - {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, - {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1}, + {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/16", CPU_286, fpus_80286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"286/20", CPU_286, fpus_80286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, + {"286/25", CPU_286, fpus_80286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3}, {"", -1, 0, 0, 0, 0} }; CPU cpus_i386SX[] = { /*i386SX*/ - {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"i386SX/16", CPU_386SX, fpus_80386, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"i386SX/20", CPU_386SX, fpus_80386, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"i386SX/33", CPU_386SX, fpus_80386, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, {"", -1, 0, 0, 0} }; CPU cpus_i386DX[] = { /*i386DX*/ - {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, - {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"i386DX/16", CPU_386DX, fpus_80386, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2}, + {"i386DX/20", CPU_386DX, fpus_80386, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/25", CPU_386DX, fpus_80386, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"i386DX/33", CPU_386DX, fpus_80386, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, {"", -1, 0, 0, 0} }; CPU cpus_acer[] = { /*i386SX*/ - {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3}, + {"i386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3}, {"", -1, 0, 0, 0} }; CPU cpus_Am386SX[] = { /*Am386*/ - {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, - {"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, + {"Am386SX/16", CPU_386SX, fpus_80386, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2}, + {"Am386SX/20", CPU_386SX, fpus_80386, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386SX/33", CPU_386SX, fpus_80386, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386SX/40", CPU_386SX, fpus_80386, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5}, {"", -1, 0, 0, 0} }; CPU cpus_Am386DX[] = { /*Am386*/ - {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, - {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, - {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, + {"Am386DX/25", CPU_386DX, fpus_80386, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3}, + {"Am386DX/33", CPU_386DX, fpus_80386, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4}, + {"Am386DX/40", CPU_386DX, fpus_80386, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5}, {"", -1, 0, 0, 0} }; CPU cpus_486SLC[] = { /*Cx486SLC*/ - {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, - {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, - {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 2*2}, - {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, - {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, + {"Cx486SLC/20", CPU_486SLC, fpus_80386, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/25", CPU_486SLC, fpus_80386, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3}, + {"Cx486SLC/33", CPU_486SLC, fpus_80386, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4}, + {"Cx486SRx2/32", CPU_486SLC, fpus_80386, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 2*2}, + {"Cx486SRx2/40", CPU_486SLC, fpus_80386, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, + {"Cx486SRx2/50", CPU_486SLC, fpus_80386, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 2*3}, {"", -1, 0, 0, 0} }; CPU cpus_486DLC[] = { /*Cx486DLC*/ - {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3}, - {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4}, - {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5}, - {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 2*2}, - {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, - {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, - {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 2*4}, + {"Cx486DLC/25", CPU_486DLC, fpus_80386, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3}, + {"Cx486DLC/33", CPU_486DLC, fpus_80386, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4}, + {"Cx486DLC/40", CPU_486DLC, fpus_80386, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5}, + {"Cx486DRx2/32", CPU_486DLC, fpus_80386, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 2*2}, + {"Cx486DRx2/40", CPU_486DLC, fpus_80386, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, + {"Cx486DRx2/50", CPU_486DLC, fpus_80386, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 2*3}, + {"Cx486DRx2/66", CPU_486DLC, fpus_80386, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 2*4}, {"", -1, 0, 0, 0} }; CPU cpus_i486[] = { /*i486*/ - {"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2}, - {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, - {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, - {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, (5*3)/2}, - {"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, (5*4)/2}, + {"i486SX/16", CPU_i486SX, fpus_none, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2}, + {"i486SX/20", CPU_i486SX, fpus_none, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486SX/25", CPU_i486SX, fpus_none, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486SX/33", CPU_i486SX, fpus_none, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"i486SX2/50", CPU_i486SX, fpus_none, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX/25", CPU_i486DX, fpus_builtin, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"i486DX/33", CPU_i486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"i486DX/50", CPU_i486DX, fpus_builtin, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, + {"i486DX2/40", CPU_i486DX, fpus_builtin, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX2/50", CPU_i486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"i486DX2/66", CPU_i486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"iDX4/75", CPU_iDX4, fpus_builtin, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, fpus_builtin, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"Pentium OverDrive/63", CPU_PENTIUM, fpus_builtin, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, (5*3)/2}, + {"Pentium OverDrive/83", CPU_PENTIUM, fpus_builtin, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, (5*4)/2}, {"", -1, 0, 0, 0} }; CPU cpus_Am486[] = { /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ - {"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, - {"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 2*5}, - {"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, - {"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, - {"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, - {"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 4*5}, + {"Am486SX/33", CPU_Am486SX, fpus_none, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Am486SX/40", CPU_Am486SX, fpus_none, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Am486SX2/50", CPU_Am486SX, fpus_none, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX, fpus_none, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/ + {"Am486DX/33", CPU_Am486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Am486DX/40", CPU_Am486DX, fpus_builtin, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Am486DX2/50", CPU_Am486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"Am486DX2/66", CPU_Am486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"Am486DX2/80", CPU_Am486DX, fpus_builtin, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 2*5}, + {"Am486DX4/75", CPU_Am486DX, fpus_builtin, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, + {"Am486DX4/90", CPU_Am486DX, fpus_builtin, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Am486DX4/100", CPU_Am486DX, fpus_builtin, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Am486DX4/120", CPU_Am486DX, fpus_builtin, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, + {"Am5x86/P75", CPU_Am486DX, fpus_builtin, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, + {"Am5x86/P75+", CPU_Am486DX, fpus_builtin, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 4*5}, {"", -1, 0, 0, 0} }; CPU cpus_Cx486[] = { /*Cx486/5x86*/ - {"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, - {"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, - {"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, - {"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, - {"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, - {"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 2*5}, - {"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, - {"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, - {"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, - {"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, + {"Cx486S/25", CPU_Cx486S, fpus_none, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, + {"Cx486S/33", CPU_Cx486S, fpus_none, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Cx486S/40", CPU_Cx486S, fpus_none, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Cx486DX/33", CPU_Cx486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, + {"Cx486DX/40", CPU_Cx486DX, fpus_builtin, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5}, + {"Cx486DX2/50", CPU_Cx486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 2*3}, + {"Cx486DX2/66", CPU_Cx486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*4}, + {"Cx486DX2/80", CPU_Cx486DX, fpus_builtin, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 2*5}, + {"Cx486DX4/75", CPU_Cx486DX, fpus_builtin, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 3*3}, + {"Cx486DX4/100", CPU_Cx486DX, fpus_builtin, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Cx5x86/100", CPU_Cx5x86, fpus_builtin, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 3*4}, + {"Cx5x86/120", CPU_Cx5x86, fpus_builtin, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 3*5}, + {"Cx5x86/133", CPU_Cx5x86, fpus_builtin, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*4}, {"", -1, 0, 0, 0} }; CPU cpus_6x86[] = { /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, - {"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, - {"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, + {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, - {"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, - {"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, - {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, - {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, - {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, + {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + {"6x86MX-PR300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, + {"6x86MX-PR333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, + {"6x86MX-PR366", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, + {"6x86MX-PR400", CPU_Cx6x86MX, fpus_builtin, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, {"", -1, 0, 0, 0} }; @@ -281,150 +310,150 @@ CPU cpus_Cx486[] = CPU cpus_WinChip[] = { /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, (3*6)/2}, - {"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*7)/2}, - {"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*8)/2}, - {"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*7}, - {"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*8}, - {"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*7)/2}, - {"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2}, - {"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7}, - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, (7*8)/2}, + {"WinChip 75", CPU_WINCHIP, fpus_builtin, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, (3*6)/2}, + {"WinChip 90", CPU_WINCHIP, fpus_builtin, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*7)/2}, + {"WinChip 100", CPU_WINCHIP, fpus_builtin, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, (3*8)/2}, + {"WinChip 120", CPU_WINCHIP, fpus_builtin, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*7}, + {"WinChip 133", CPU_WINCHIP, fpus_builtin, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 2*8}, + {"WinChip 150", CPU_WINCHIP, fpus_builtin, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*7)/2}, + {"WinChip 166", CPU_WINCHIP, fpus_builtin, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, (5*8)/2}, + {"WinChip 180", CPU_WINCHIP, fpus_builtin, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*7}, + {"WinChip 200", CPU_WINCHIP, fpus_builtin, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 240", CPU_WINCHIP, fpus_builtin, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/240", CPU_WINCHIP2, fpus_builtin, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2A/233", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, (7*8)/2}, {"", -1, 0, 0, 0} }; CPU cpus_WinChip_SS7[] = { /*IDT WinChip (Super Socket 7)*/ - {"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, - {"WinChip 2/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, - {"WinChip 2/225", CPU_WINCHIP2, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, - {"WinChip 2/240", CPU_WINCHIP2, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"WinChip 2/250", CPU_WINCHIP2, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24}, - {"WinChip 2A/233", CPU_WINCHIP2, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 28}, - {"WinChip 2A/266", CPU_WINCHIP2, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28}, - {"WinChip 2A/300", CPU_WINCHIP2, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 200", CPU_WINCHIP, fpus_builtin, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 225", CPU_WINCHIP, fpus_builtin, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 240", CPU_WINCHIP, fpus_builtin, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 4*7}, + {"WinChip 2/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*8}, + {"WinChip 2/225", CPU_WINCHIP2, fpus_builtin, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 3*9}, + {"WinChip 2/240", CPU_WINCHIP2, fpus_builtin, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, fpus_builtin, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 28}, + {"WinChip 2A/266", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, fpus_builtin, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 30}, {"", -1, 0, 0, 0} }; CPU cpus_Pentium5V[] = { /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, - {"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, - {"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium 60", CPU_PENTIUM, fpus_builtin, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7}, + {"Pentium 66", CPU_PENTIUM, fpus_builtin, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8}, + {"Pentium OverDrive 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium OverDrive 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, {"", -1, 0, 0, 0} }; CPU cpus_PentiumS5[] = { /*Intel Pentium (Socket 5)*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium 75", CPU_PENTIUM, fpus_builtin, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, + {"Pentium 90", CPU_PENTIUM, fpus_builtin, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"Pentium 100/66", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, + {"Pentium 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium OverDrive 125",CPU_PENTIUM,fpus_builtin, 15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive 150",CPU_PENTIUM,fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive 166",CPU_PENTIUM,fpus_builtin, 17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_builtin, 15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_builtin, 17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_builtin, 20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, {"", -1, 0, 0, 0} }; CPU cpus_Pentium[] = { /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, - {"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, - {"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, - {"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 4*8}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, (9*8)/2}, - {"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium 75", CPU_PENTIUM, fpus_builtin, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, (3*6)/2}, + {"Pentium 90", CPU_PENTIUM, fpus_builtin, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*7)/2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"Pentium 100/66", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, (3*8)/2}, + {"Pentium 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Pentium 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Pentium 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium 166", CPU_PENTIUM, fpus_builtin, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium 200", CPU_PENTIUM, fpus_builtin, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium MMX 233", CPU_PENTIUMMMX, fpus_builtin, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, fpus_builtin, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, fpus_builtin, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, fpus_builtin, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, (7*8)/2}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, fpus_builtin, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 4*8}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, fpus_builtin, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, (9*8)/2}, + {"Pentium OverDrive 125", CPU_PENTIUM, fpus_builtin, 15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive 166", CPU_PENTIUM, fpus_builtin, 17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_builtin, 15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, (5*6)/2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_builtin, 17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_builtin, 20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, {"", -1, 0, 0, 0} }; CPU cpus_K6_S7[] = { /*AMD K6*/ - {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6-2/300 AFR-66", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6/166", CPU_K6, fpus_builtin, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K6/200", CPU_K6, fpus_builtin, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"K6/233", CPU_K6, fpus_builtin, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6/266", CPU_K6, fpus_builtin, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6/300", CPU_K6, fpus_builtin, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/233", CPU_K6_2, fpus_builtin, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6-2/266", CPU_K6_2, fpus_builtin, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, fpus_builtin, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, {"", -1, 0, 0, 0} }; CPU cpus_K6_SS7[] = { /*AMD K6*/ - {"K6/166", CPU_K6, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, - {"K6/200", CPU_K6, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, - {"K6/233", CPU_K6, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6/266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6/300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"K6-2/233", CPU_K6_2, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, - {"K6-2/266", CPU_K6_2, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"K6-2/300", CPU_K6_2, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, - {"K6-2/333", CPU_K6_2, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, - {"K6-2/350", CPU_K6_2, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 42}, - {"K6-2/366", CPU_K6_2, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 44}, - {"K6-2/380", CPU_K6_2, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 46}, - {"K6-2/400", CPU_K6_2, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, - {"K6-2/450", CPU_K6_2, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-2/475", CPU_K6_2, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, - {"K6-2/500", CPU_K6_2, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, - {"K6-2/533", CPU_K6_2, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, - {"K6-2/550", CPU_K6_2, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, - {"K6-2+/450", CPU_K6_2P, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-2+/475", CPU_K6_2P, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, - {"K6-2+/500", CPU_K6_2P, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, - {"K6-2+/533", CPU_K6_2P, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, - {"K6-2+/550", CPU_K6_2P, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, - {"K6-III/400", CPU_K6_3, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, - {"K6-III/450", CPU_K6_3, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-III+/400", CPU_K6_3P, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, - {"K6-III+/450", CPU_K6_3P, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, - {"K6-III+/475", CPU_K6_3P, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, - {"K6-III+/500", CPU_K6_3P, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6/166", CPU_K6, fpus_builtin, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20}, + {"K6/200", CPU_K6, fpus_builtin, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24}, + {"K6/233", CPU_K6, fpus_builtin, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6/266", CPU_K6, fpus_builtin, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6/300", CPU_K6, fpus_builtin, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/233", CPU_K6_2, fpus_builtin, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, + {"K6-2/266", CPU_K6_2, fpus_builtin, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, + {"K6-2/300", CPU_K6_2, fpus_builtin, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36}, + {"K6-2/333", CPU_K6_2, fpus_builtin, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, + {"K6-2/350", CPU_K6_2, fpus_builtin, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 42}, + {"K6-2/366", CPU_K6_2, fpus_builtin, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 44}, + {"K6-2/380", CPU_K6_2, fpus_builtin, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 46}, + {"K6-2/400", CPU_K6_2, fpus_builtin, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-2/450", CPU_K6_2, fpus_builtin, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-2/475", CPU_K6_2, fpus_builtin, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-2/500", CPU_K6_2, fpus_builtin, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6-2/533", CPU_K6_2, fpus_builtin, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, + {"K6-2/550", CPU_K6_2, fpus_builtin, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, + {"K6-2+/450", CPU_K6_2P, fpus_builtin, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-2+/475", CPU_K6_2P, fpus_builtin, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-2+/500", CPU_K6_2P, fpus_builtin, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, + {"K6-2+/533", CPU_K6_2P, fpus_builtin, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 64}, + {"K6-2+/550", CPU_K6_2P, fpus_builtin, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 66}, + {"K6-III/400", CPU_K6_3, fpus_builtin, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-III/450", CPU_K6_3, fpus_builtin, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-III+/400", CPU_K6_3P, fpus_builtin, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 48}, + {"K6-III+/450", CPU_K6_3P, fpus_builtin, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 54}, + {"K6-III+/475", CPU_K6_3P, fpus_builtin, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 57}, + {"K6-III+/500", CPU_K6_3P, fpus_builtin, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 60}, {"", -1, 0, 0, 0} }; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 0dce487..0cfac2c 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -165,6 +165,8 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) temp = 0x7D; else temp = 0x6D; + if (hasfpu) + temp |= 0x02; } else if ((romset == ROM_ATARIPC3) && (keyboard_xt.pb & 0x80)) { @@ -209,7 +211,7 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) temp = 6; } else - temp = 0xD; + temp = hasfpu ? 0xf : 0xd; } temp |= (ppispeakon ? 0x20 : 0); if (keyboard_xt.tandy) diff --git a/src/pc.c b/src/pc.c index 7b6fa59..f867092 100644 --- a/src/pc.c +++ b/src/pc.c @@ -7,6 +7,7 @@ #include "ali1429.h" #include "cdrom-ioctl.h" #include "cdrom-image.h" +#include "cpu.h" #include "disc.h" #include "disc_img.h" #include "mem.h" @@ -709,6 +710,8 @@ void loadconfig(char *fn) romset = model_getromset(); cpu_manufacturer = config_get_int(CFG_MACHINE, NULL, "cpu_manufacturer", 0); cpu = config_get_int(CFG_MACHINE, NULL, "cpu", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "fpu", "none"); + fpu_type = fpu_get_type(model, cpu_manufacturer, cpu, p); cpu_use_dynarec = config_get_int(CFG_MACHINE, NULL, "cpu_use_dynarec", 0); cpu_waitstates = config_get_int(CFG_MACHINE, NULL, "cpu_waitstates", 0); @@ -899,6 +902,7 @@ void saveconfig(char *fn) config_set_string(CFG_MACHINE, NULL, "model", model_get_internal_name()); config_set_int(CFG_MACHINE, NULL, "cpu_manufacturer", cpu_manufacturer); config_set_int(CFG_MACHINE, NULL, "cpu", cpu); + config_set_string(CFG_MACHINE, NULL, "fpu", (char *)fpu_get_internal_name(model, cpu_manufacturer, cpu, fpu_type)); config_set_int(CFG_MACHINE, NULL, "cpu_use_dynarec", cpu_use_dynarec); config_set_int(CFG_MACHINE, NULL, "cpu_waitstates", cpu_waitstates); diff --git a/src/pc.xrc b/src/pc.xrc index 48ccde8..cbc4b59 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -618,6 +618,44 @@ 5 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 120,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + wxEXPAND @@ -639,6 +677,7 @@ 5 0,0 + wxALL | wxALIGN_CENTER_VERTICAL diff --git a/src/wx-config.c b/src/wx-config.c index 4b8d40e..09fea3e 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -76,6 +76,33 @@ static int mouse_valid(int type, int model) return FALSE; }*/ +static void recalc_fpu_list(void *hdlg, int model, int manu, int cpu, int fpu) +{ + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + int c = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + while (1) + { + const char *name = fpu_get_name_from_index(model, manu, cpu, c); + int type = fpu_get_type_from_index(model, manu, cpu, c); + if (!name) + break; + + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)name); + if (!c || type == fpu) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + + c++; + } + if (c > 1) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); +} + static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) { void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); @@ -405,8 +432,8 @@ int config_dlgsave(void* hdlg) char temp_str[256]; void* h; int c; - int gfx, fpu; - int temp_cpu, temp_cpu_m, temp_model; + int gfx;//, fpu; + int temp_cpu, temp_cpu_m, temp_model, temp_fpu; int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; int temp_dynarec; int temp_fda_type, temp_fdb_type; @@ -442,8 +469,11 @@ int config_dlgsave(void* hdlg) temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type - >= CPU_i486DX) ? 1 : 0; +// fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type +// >= CPU_i486DX) ? 1 : 0; + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); @@ -490,8 +520,8 @@ int config_dlgsave(void* hdlg) temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; #endif - if (temp_model != model || gfx != gfxcard || mem != mem_size || - fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || + if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_fpu != fpu_type || + 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_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || @@ -511,6 +541,7 @@ int config_dlgsave(void* hdlg) mem_size = mem; cpu_manufacturer = temp_cpu_m; cpu = temp_cpu; + fpu_type = temp_fpu; GAMEBLASTER = temp_GAMEBLASTER; GUS = temp_GUS; SSI2001 = temp_SSI2001; @@ -600,7 +631,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) void* h; int c, d; int gfx, mem; - int temp_cpu, temp_cpu_m, temp_model; + int temp_cpu, temp_cpu_m, temp_model, temp_fpu; int temp_sound_card_current; int temp_dynarec; int cpu_flags; @@ -665,6 +696,8 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_enablewindow(h, TRUE); wx_sendmessage(h, WX_CB_SETCURSEL, cpu, 0); + recalc_fpu_list(hdlg, romstomodel[romset], cpu_manufacturer, cpu, fpu_type); + recalc_snd_list(hdlg, romstomodel[romset]); h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); @@ -926,6 +959,10 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) temp_cpu = c - 1; wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); @@ -1035,6 +1072,10 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) temp_cpu = c - 1; wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); @@ -1067,6 +1108,10 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index c088a21..553b49d 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 138007; +static size_t xml_res_size_26 = 139477; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -2846,607 +2846,58 @@ static unsigned char xml_res_file_26[] = { 122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, -34,73,68,67,95,67,72,69,67,75,68,89,78,65,82,69,67,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,68,121,110,97,109,105,99,32,114,101,99,111,109,112,105,108,101,114, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104, -101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,101,109,111,114,121,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -77,69,77,83,80,73,78,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83, -80,95,65,82,82,79,87,95,75,69,89,83,60,47,115,116,121,108,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,118,97,108,117,101,62,48,60,47,118,97,108,117,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -109,105,110,62,48,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,97,120,62,49,48, -60,47,109,97,120,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, -32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, -61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,77,66,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, -49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, 82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, 98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, 120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97, -105,116,115,116,97,116,101,115,58,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97, -112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, -116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95, -67,79,77,66,79,87,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, -66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, -89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48, -44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44, +45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,80,85,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71, -78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, -97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,89,78,67,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,83,121,110,99,104,114,111,110,105,122,101,32,116,105,109,101, -32,116,111,32,104,111,115,116,32,99,108,111,99,107,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, -101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,118,105,100, -101,111,95,109,111,100,101,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, -65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, -108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, -98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,118, -105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,86,73,68, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, -79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, -70,73,71,85,82,69,86,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, -54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, -112,101,101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, -47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, -98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79, -83,80,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,32,124,32,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116, -121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, -44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,70,80,85,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, -66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79, -79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,111,111,100,111,111, -32,71,114,97,112,104,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, -34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79, -79,68,79,79,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95, -115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, -102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, -62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111, -117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51, -50,95,115,111,117,110,100,46,112,110,103,60,47,98,105,116,109,97,112,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, -65,66,95,84,82,65,86,69,82,83,65,76,60,47,115,116,121,108,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111, -108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, -98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, -62,56,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,118, -105,99,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,50,48,44,45,49,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111, -120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79, -82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,78,68, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, -79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, -66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, -70,73,71,85,82,69,83,78,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, -101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,49, -54,120,49,54,95,115,101,116,116,105,110,103,95,116,111,111,108,115,46,112, -110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, -98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,67,72,69,67,75,51,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -67,77,83,32,47,32,71,97,109,101,32,66,108,97,115,116,101,114,60,47,108, -97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, -101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, -95,67,72,69,67,75,71,85,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,97,118,105, -115,32,85,108,116,114,97,115,111,117,110,100,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -3474,17 +2925,101 @@ static unsigned char xml_res_file_26[] = { 115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, 48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +68,89,78,65,82,69,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,121,110,97,109,105,99, +32,114,101,99,111,109,112,105,108,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, 102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, -111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,83,83,73, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,73,110,110,111,118,97,116,105,111,110,32,83, -83,73,45,50,48,48,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, -62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,111,114,121,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, +84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,112,105,110,67,116,114,108,34,32,110, +97,109,101,61,34,73,68,67,95,77,69,77,83,80,73,78,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,83,80,95,65,82,82,79,87,95,75,69,89,83,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,109,105,110,62,48,60,47,109,105,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,97,120,62,49,48,60,47,109,97,120,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,73,68,67,95,84,69,88,84,95,77,66,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, @@ -3509,60 +3044,310 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, -98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108,97,98,101, -108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +32,60,108,97,98,101,108,62,87,97,105,116,115,116,97,116,101,115,58,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,87,83,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75, +83,89,78,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,121,110,99,104,114,111,110,105, +122,101,32,116,105,109,101,32,116,111,32,104,111,115,116,32,99,108,111, +99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119, +120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110, +115,95,51,50,120,51,50,95,118,105,100,101,111,95,109,111,100,101,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,86,73,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,112,101,101,100,58,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, 62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, 111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47, -111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,83,80,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120,67, +66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, 34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, -99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, +78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, 101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,86,79,79,68,79,79,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,111,111,100,111,111,32,71,114,97,112,104, +105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,78,70,73,71,85,82,69,86,79,79,68,79,79,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, +116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, +112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116,105,110, +103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, @@ -3572,47 +3357,327 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, 99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105, 116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112, -112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105,118,101,46, +112,36,105,99,111,110,115,95,51,50,120,51,50,95,115,111,117,110,100,46, 112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69,76,95,68,82, -73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83,65,76,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, -101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, -119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, -103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, -108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82,83, +65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,101,118,105,99,101,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,73,68,67,95,67,79,77,66,79,83,78,68,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97, +108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,85,82,69,83,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,115,101,116,116, +105,110,103,95,116,111,111,108,115,46,112,110,103,60,47,98,105,116,109, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,72,69,67,75,51, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,77,83,32,47,32,71,97,109,101,32,66,108,97, +115,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62, +48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,72,69,67,75,71,85,83,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,114,97,118,105,115,32,85,108,116,114,97,115,111,117,110,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,72,69,67,75,83,83,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,110,111,118, +97,116,105,111,110,32,83,83,73,45,50,48,48,49,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,80,84,32,68,101,118,105,99,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, 105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, 108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, -100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119,115, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60, -47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, -111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, -108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,77,66,79,76,80,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124, +119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115, +101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, +115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,114,105, +118,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,80,65,78,69, +76,95,68,82,73,86,69,83,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,65,66,95,84,82,65,86,69,82, +83,65,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, +47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, 114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, 112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, diff --git a/src/x87_ops.h b/src/x87_ops.h index 2ccd7b8..53ffc23 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -286,6 +286,9 @@ typedef union uint64_t i; } x87_td; +#ifdef X8087 +#define FP_ENTER() fpucount++ +#else #define FP_ENTER() do \ { \ if (cr0 & 0xc) \ @@ -295,6 +298,7 @@ typedef union } \ fpucount++; \ } while (0) +#endif #include "x87_ops_arith.h" #include "x87_ops_misc.h" From 4875f24b537292e52456bac66d3d69e8ae8756ea Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 24 Jan 2020 20:33:35 +0000 Subject: [PATCH 0768/1050] Added initial attempt at instruction timings for 8087/287/387. Also added 287XL using 387 timings. --- src/cpu.c | 24 +++++++++++ src/cpu.h | 1 + src/cpu_tables.c | 5 ++- src/x87_ops.h | 1 + src/x87_ops_arith.h | 90 ++++++++++++++++++++--------------------- src/x87_ops_loadstore.h | 66 +++++++++++++++--------------- src/x87_ops_misc.h | 90 ++++++++++++++++++++--------------------- 7 files changed, 153 insertions(+), 124 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 07e46b0..7d6c1a2 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -6,6 +6,7 @@ #include "mem.h" #include "pci.h" #include "codegen.h" +#include "x87_timings.h" int fpu_type; uint32_t cpu_features; @@ -1007,6 +1008,29 @@ void cpu_set() default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } + + switch (fpu_type) + { + case FPU_NONE: + break; + + case FPU_8087: + x87_timings = x87_timings_8087; + break; + + case FPU_287: + x87_timings = x87_timings_287; + break; + + case FPU_287XL: + case FPU_387: + x87_timings = x87_timings_387; + break; + + default: + x87_timings = x87_timings_486; + break; + } } void cpu_CPUID() diff --git a/src/cpu.h b/src/cpu.h index 1cb4cf8..69d7cc5 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -66,6 +66,7 @@ enum FPU_NONE, FPU_8087, FPU_287, + FPU_287XL, FPU_387, FPU_BUILTIN }; diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 84863d4..aa19596 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -35,8 +35,9 @@ FPU fpus_8088[] = }; FPU fpus_80286[] = { - {"None", "none", FPU_NONE}, - {"287", "287", FPU_287}, + {"None", "none", FPU_NONE}, + {"287", "287", FPU_287}, + {"287XL", "287xl", FPU_287XL}, {NULL, NULL, 0} }; FPU fpus_80386[] = diff --git a/src/x87_ops.h b/src/x87_ops.h index 53ffc23..225d56c 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -1,5 +1,6 @@ #include #include +#include "x87_timings.h" #define fplog 0 diff --git a/src/x87_ops_arith.h b/src/x87_ops_arith.h index f52abe8..cf8d1ae 100644 --- a/src/x87_ops_arith.h +++ b/src/x87_ops_arith.h @@ -1,4 +1,4 @@ -#define opFPU(name, optype, a_size, load_var, get, use_var) \ +#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ { \ optype t; \ @@ -12,7 +12,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(8); \ + CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ return 0; \ } \ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -24,7 +24,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES(4); \ + CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ return 0; \ } \ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -37,7 +37,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ x87_pop(); \ - CLOCK_CYCLES(4); \ + CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ return 0; \ } \ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -49,7 +49,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(73); \ + CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ return 0; \ } \ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -61,7 +61,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(73); \ + CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ return 0; \ } \ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -73,7 +73,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(11); \ + CLOCK_CYCLES(x87_timings.fmul ## cycle_postfix); \ return 0; \ } \ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -85,7 +85,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(8); \ + CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ return 0; \ } \ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -97,20 +97,20 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(8); \ + CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ return 0; \ } -opFPU(s, x87_ts, 16, t.i, geteal, t.s) -opFPU(s, x87_ts, 32, t.i, geteal, t.s) -opFPU(d, x87_td, 16, t.i, geteaq, t.d) -opFPU(d, x87_td, 32, t.i, geteaq, t.d) +opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) +opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) +opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) +opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t) -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t) -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t) -opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t) +opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) +opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) +opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32) +opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) @@ -122,7 +122,7 @@ static int opFADD(uint32_t fetchdat) if (fplog) pclog("FADD\n"); ST(0) = ST(0) + ST(fetchdat & 7); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFADDr(uint32_t fetchdat) @@ -132,7 +132,7 @@ static int opFADDr(uint32_t fetchdat) if (fplog) pclog("FADD\n"); ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFADDP(uint32_t fetchdat) @@ -143,7 +143,7 @@ static int opFADDP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -155,7 +155,7 @@ static int opFCOM(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -167,7 +167,7 @@ static int opFCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -184,7 +184,7 @@ static int opFCOMPP(uint32_t fetchdat) x87_pop(); x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFUCOMPP(uint32_t fetchdat) @@ -196,7 +196,7 @@ static int opFUCOMPP(uint32_t fetchdat) cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); x87_pop(); x87_pop(); - CLOCK_CYCLES(5); + CLOCK_CYCLES(x87_timings.fucom); return 0; } @@ -209,7 +209,7 @@ static int opFCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } static int opFCOMIP(uint32_t fetchdat) @@ -222,7 +222,7 @@ static int opFCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fcom); return 0; } @@ -233,7 +233,7 @@ static int opFDIV(uint32_t fetchdat) if (fplog) pclog("FDIV\n"); x87_div(ST(0), ST(0), ST(fetchdat & 7)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVr(uint32_t fetchdat) @@ -243,7 +243,7 @@ static int opFDIVr(uint32_t fetchdat) if (fplog) pclog("FDIV\n"); x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVP(uint32_t fetchdat) @@ -254,7 +254,7 @@ static int opFDIVP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } @@ -265,7 +265,7 @@ static int opFDIVR(uint32_t fetchdat) if (fplog) pclog("FDIVR\n"); x87_div(ST(0), ST(fetchdat&7), ST(0)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVRr(uint32_t fetchdat) @@ -275,7 +275,7 @@ static int opFDIVRr(uint32_t fetchdat) if (fplog) pclog("FDIVR\n"); x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } static int opFDIVRP(uint32_t fetchdat) @@ -286,7 +286,7 @@ static int opFDIVRP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(73); + CLOCK_CYCLES(x87_timings.fdiv); return 0; } @@ -297,7 +297,7 @@ static int opFMUL(uint32_t fetchdat) if (fplog) pclog("FMUL\n"); ST(0) = ST(0) * ST(fetchdat & 7); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(16); + CLOCK_CYCLES(x87_timings.fmul); return 0; } static int opFMULr(uint32_t fetchdat) @@ -307,7 +307,7 @@ static int opFMULr(uint32_t fetchdat) if (fplog) pclog("FMUL\n"); ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; - CLOCK_CYCLES(16); + CLOCK_CYCLES(x87_timings.fmul); return 0; } static int opFMULP(uint32_t fetchdat) @@ -318,7 +318,7 @@ static int opFMULP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(16); + CLOCK_CYCLES(x87_timings.fmul); return 0; } @@ -329,7 +329,7 @@ static int opFSUB(uint32_t fetchdat) if (fplog) pclog("FSUB\n"); ST(0) = ST(0) - ST(fetchdat & 7); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBr(uint32_t fetchdat) @@ -339,7 +339,7 @@ static int opFSUBr(uint32_t fetchdat) if (fplog) pclog("FSUB\n"); ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBP(uint32_t fetchdat) @@ -350,7 +350,7 @@ static int opFSUBP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -361,7 +361,7 @@ static int opFSUBR(uint32_t fetchdat) if (fplog) pclog("FSUBR\n"); ST(0) = ST(fetchdat & 7) - ST(0); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBRr(uint32_t fetchdat) @@ -371,7 +371,7 @@ static int opFSUBRr(uint32_t fetchdat) if (fplog) pclog("FSUBR\n"); ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } static int opFSUBRP(uint32_t fetchdat) @@ -382,7 +382,7 @@ static int opFSUBRP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fadd); return 0; } @@ -393,7 +393,7 @@ static int opFUCOM(uint32_t fetchdat) if (fplog) pclog("FUCOM\n"); cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } @@ -405,7 +405,7 @@ static int opFUCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } @@ -418,7 +418,7 @@ static int opFUCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } static int opFUCOMIP(uint32_t fetchdat) @@ -431,6 +431,6 @@ static int opFUCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fucom); return 0; } diff --git a/src/x87_ops_loadstore.h b/src/x87_ops_loadstore.h index 96c18e6..6c61b7f 100644 --- a/src/x87_ops_loadstore.h +++ b/src/x87_ops_loadstore.h @@ -8,7 +8,7 @@ static int opFILDiw_a16(uint32_t fetchdat) temp = geteaw(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", (double)temp); x87_push((double)temp); - CLOCK_CYCLES(13); + CLOCK_CYCLES(x87_timings.fild_16); return 0; } static int opFILDiw_a32(uint32_t fetchdat) @@ -21,7 +21,7 @@ static int opFILDiw_a32(uint32_t fetchdat) temp = geteaw(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", (double)temp); x87_push((double)temp); - CLOCK_CYCLES(13); + CLOCK_CYCLES(x87_timings.fild_16); return 0; } @@ -36,7 +36,7 @@ static int opFISTiw_a16(uint32_t fetchdat) /* if (temp64 > 32767 || temp64 < -32768) fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return cpu_state.abrt; } static int opFISTiw_a32(uint32_t fetchdat) @@ -50,7 +50,7 @@ static int opFISTiw_a32(uint32_t fetchdat) /* if (temp64 > 32767 || temp64 < -32768) fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return cpu_state.abrt; } @@ -66,7 +66,7 @@ static int opFISTPiw_a16(uint32_t fetchdat) fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return 0; } static int opFISTPiw_a32(uint32_t fetchdat) @@ -81,7 +81,7 @@ static int opFISTPiw_a32(uint32_t fetchdat) fatal("FISTw overflow %i\n", temp64);*/ seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_16); return 0; } @@ -98,7 +98,7 @@ static int opFILDiq_a16(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; - CLOCK_CYCLES(10); + CLOCK_CYCLES(x87_timings.fild_64); return 0; } static int opFILDiq_a32(uint32_t fetchdat) @@ -114,7 +114,7 @@ static int opFILDiq_a32(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; - CLOCK_CYCLES(10); + CLOCK_CYCLES(x87_timings.fild_64); return 0; } @@ -143,6 +143,7 @@ static int FBSTP_a16(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); + CLOCK_CYCLES(x87_timings.fbstp); return 0; } static int FBSTP_a32(uint32_t fetchdat) @@ -170,6 +171,7 @@ static int FBSTP_a32(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); + CLOCK_CYCLES(x87_timings.fbstp); return 0; } @@ -186,7 +188,7 @@ static int FISTPiq_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_64); return 0; } static int FISTPiq_a32(uint32_t fetchdat) @@ -202,7 +204,7 @@ static int FISTPiq_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(29); + CLOCK_CYCLES(x87_timings.fist_64); return 0; } @@ -216,7 +218,7 @@ static int opFILDil_a16(uint32_t fetchdat) templ = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); x87_push((double)templ); - CLOCK_CYCLES(9); + CLOCK_CYCLES(x87_timings.fild_32); return 0; } static int opFILDil_a32(uint32_t fetchdat) @@ -229,7 +231,7 @@ static int opFILDil_a32(uint32_t fetchdat) templ = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f %08X %i\n", (double)templ, templ, templ); x87_push((double)templ); - CLOCK_CYCLES(9); + CLOCK_CYCLES(x87_timings.fild_32); return 0; } @@ -244,7 +246,7 @@ static int opFISTil_a16(uint32_t fetchdat) /* if (temp64 > 2147483647 || temp64 < -2147483647) fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return cpu_state.abrt; } static int opFISTil_a32(uint32_t fetchdat) @@ -258,7 +260,7 @@ static int opFISTil_a32(uint32_t fetchdat) /* if (temp64 > 2147483647 || temp64 < -2147483647) fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return cpu_state.abrt; } @@ -274,7 +276,7 @@ static int opFISTPil_a16(uint32_t fetchdat) fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return 0; } static int opFISTPil_a32(uint32_t fetchdat) @@ -289,7 +291,7 @@ static int opFISTPil_a32(uint32_t fetchdat) fatal("FISTl out of range! %i\n", temp64);*/ seteal((int32_t)temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(28); + CLOCK_CYCLES(x87_timings.fist_32); return 0; } @@ -303,7 +305,7 @@ static int opFLDe_a16(uint32_t fetchdat) t=x87_ld80(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t); x87_push(t); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fld_80); return 0; } static int opFLDe_a32(uint32_t fetchdat) @@ -316,7 +318,7 @@ static int opFLDe_a32(uint32_t fetchdat) t=x87_ld80(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t); x87_push(t); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fld_80); return 0; } @@ -328,7 +330,7 @@ static int opFSTPe_a16(uint32_t fetchdat) if (fplog) pclog("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fst_80); return 0; } static int opFSTPe_a32(uint32_t fetchdat) @@ -339,7 +341,7 @@ static int opFSTPe_a32(uint32_t fetchdat) if (fplog) pclog("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fst_80); return 0; } @@ -353,7 +355,7 @@ static int opFLDd_a16(uint32_t fetchdat) t.i = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t.d); x87_push(t.d); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_64); return 0; } static int opFLDd_a32(uint32_t fetchdat) @@ -366,7 +368,7 @@ static int opFLDd_a32(uint32_t fetchdat) t.i = geteaq(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", t.d); x87_push(t.d); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_64); return 0; } @@ -379,7 +381,7 @@ static int opFSTd_a16(uint32_t fetchdat) if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return cpu_state.abrt; } static int opFSTd_a32(uint32_t fetchdat) @@ -391,7 +393,7 @@ static int opFSTd_a32(uint32_t fetchdat) if (fplog) pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return cpu_state.abrt; } @@ -406,7 +408,7 @@ static int opFSTPd_a16(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return 0; } static int opFSTPd_a32(uint32_t fetchdat) @@ -420,7 +422,7 @@ static int opFSTPd_a32(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fst_64); return 0; } @@ -434,7 +436,7 @@ static int opFLDs_a16(uint32_t fetchdat) ts.i = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", ts.s); x87_push((double)ts.s); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_32); return 0; } static int opFLDs_a32(uint32_t fetchdat) @@ -447,7 +449,7 @@ static int opFLDs_a32(uint32_t fetchdat) ts.i = geteal(); if (cpu_state.abrt) return 1; if (fplog) pclog(" %f\n", ts.s); x87_push((double)ts.s); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fld_32); return 0; } @@ -460,7 +462,7 @@ static int opFSTs_a16(uint32_t fetchdat) if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return cpu_state.abrt; } static int opFSTs_a32(uint32_t fetchdat) @@ -472,7 +474,7 @@ static int opFSTs_a32(uint32_t fetchdat) if (fplog) pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return cpu_state.abrt; } @@ -486,7 +488,7 @@ static int opFSTPs_a16(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return 0; } static int opFSTPs_a32(uint32_t fetchdat) @@ -499,6 +501,6 @@ static int opFSTPs_a32(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES(7); + CLOCK_CYCLES(x87_timings.fst_32); return 0; } diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 0cae387..a5fc002 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -4,7 +4,7 @@ static int opFSTSW_AX(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSTSW\n"); AX = cpu_state.npxs; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return 0; } @@ -14,7 +14,7 @@ static int opFNOP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fnop); return 0; } @@ -23,7 +23,7 @@ static int opFCLEX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= 0xff00; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fclex); return 0; } @@ -37,7 +37,7 @@ static int opFINIT(uint32_t fetchdat) *(uint64_t *)cpu_state.tag = 0; cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES(17); + CLOCK_CYCLES(x87_timings.finit); CPU_BLOCK_END(); return 0; } @@ -49,7 +49,7 @@ static int opFFREE(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FFREE\n"); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.ffree); return 0; } @@ -60,7 +60,7 @@ static int opFST(uint32_t fetchdat) if (fplog) pclog("FST\n"); ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fst); return 0; } @@ -72,7 +72,7 @@ static int opFSTP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; x87_pop(); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fst); return 0; } @@ -120,7 +120,7 @@ static int FSTOR() !cpu_state.TOP && (*(uint64_t *)cpu_state.tag == 0x0101010101010101ull)) cpu_state.ismmx = 1; - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES(x87_timings.frstor); if (fplog) pclog("FRSTOR %08X:%08X %i %i %04X\n", easeg, cpu_state.eaaddr, cpu_state.ismmx, cpu_state.TOP, x87_gettag()); return cpu_state.abrt; } @@ -283,7 +283,7 @@ static int FSAVE() cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES(x87_timings.fsave); return cpu_state.abrt; } static int opFSAVE_a16(uint32_t fetchdat) @@ -310,7 +310,7 @@ static int opFSTSW_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } static int opFSTSW_a32(uint32_t fetchdat) @@ -320,7 +320,7 @@ static int opFSTSW_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } @@ -338,7 +338,7 @@ static int opFLD(uint32_t fetchdat) x87_push(ST(fetchdat&7)); cpu_state.tag[cpu_state.TOP&7] = old_tag; cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fld); return 0; } @@ -360,7 +360,7 @@ static int opFXCH(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fxch); return 0; } @@ -371,7 +371,7 @@ static int opFCHS(uint32_t fetchdat) if (fplog) pclog("FCHS\n"); ST(0) = -ST(0); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(6); + CLOCK_CYCLES(x87_timings.fchs); return 0; } @@ -382,7 +382,7 @@ static int opFABS(uint32_t fetchdat) if (fplog) pclog("FABS %f\n", ST(0)); ST(0) = fabs(ST(0)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fabs); return 0; } @@ -394,7 +394,7 @@ static int opFTST(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == 0.0) cpu_state.npxs |= C3; else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.ftst); return 0; } @@ -408,7 +408,7 @@ static int opFXAM(uint32_t fetchdat) else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fxam); return 0; } @@ -418,7 +418,7 @@ static int opFLD1(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLD1\n"); x87_push(1.0); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fld_z1); return 0; } @@ -428,7 +428,7 @@ static int opFLDL2T(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLDL2T\n"); x87_push(3.3219280948873623); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -438,7 +438,7 @@ static int opFLDL2E(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLDL2E\n"); x87_push(1.4426950408889634); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -448,7 +448,7 @@ static int opFLDPI(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLDPI\n"); x87_push(3.141592653589793); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -458,7 +458,7 @@ static int opFLDEG2(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLDEG2\n"); x87_push(0.3010299956639812); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -468,7 +468,7 @@ static int opFLDLN2(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FLDLN2\n"); x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES(8); + CLOCK_CYCLES(x87_timings.fld_const); return 0; } @@ -479,7 +479,7 @@ static int opFLDZ(uint32_t fetchdat) if (fplog) pclog("FLDZ\n"); x87_push(0.0); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fld_z1); return 0; } @@ -490,7 +490,7 @@ static int opF2XM1(uint32_t fetchdat) if (fplog) pclog("F2XM1\n"); ST(0) = pow(2.0, ST(0)) - 1.0; cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(200); + CLOCK_CYCLES(x87_timings.f2xm1); return 0; } @@ -502,7 +502,7 @@ static int opFYL2X(uint32_t fetchdat) ST(1) = ST(1) * (log(ST(0)) / log(2.0)); cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(250); + CLOCK_CYCLES(x87_timings.fyl2x); return 0; } @@ -514,7 +514,7 @@ static int opFYL2XP1(uint32_t fetchdat) ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(250); + CLOCK_CYCLES(x87_timings.fyl2xp1); return 0; } @@ -527,7 +527,7 @@ static int opFPTAN(uint32_t fetchdat) cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; - CLOCK_CYCLES(235); + CLOCK_CYCLES(x87_timings.fptan); return 0; } @@ -539,7 +539,7 @@ static int opFPATAN(uint32_t fetchdat) ST(1) = atan2(ST(1), ST(0)); cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); - CLOCK_CYCLES(250); + CLOCK_CYCLES(x87_timings.fpatan); return 0; } @@ -549,7 +549,7 @@ static int opFDECSTP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDECSTP\n"); cpu_state.TOP--; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fincdecstp); return 0; } @@ -559,7 +559,7 @@ static int opFINCSTP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FDECSTP\n"); cpu_state.TOP++; - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fincdecstp); return 0; } @@ -577,7 +577,7 @@ static int opFPREM(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(100); + CLOCK_CYCLES(x87_timings.fprem); return 0; } static int opFPREM1(uint32_t fetchdat) @@ -594,7 +594,7 @@ static int opFPREM1(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES(100); + CLOCK_CYCLES(x87_timings.fprem1); return 0; } @@ -605,7 +605,7 @@ static int opFSQRT(uint32_t fetchdat) if (fplog) pclog("FSQRT\n"); ST(0) = sqrt(ST(0)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(83); + CLOCK_CYCLES(x87_timings.fsqrt); return 0; } @@ -620,7 +620,7 @@ static int opFSINCOS(uint32_t fetchdat) cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; - CLOCK_CYCLES(330); + CLOCK_CYCLES(x87_timings.fsincos); return 0; } @@ -632,7 +632,7 @@ static int opFRNDINT(uint32_t fetchdat) ST(0) = (double)x87_fround(ST(0)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; if (fplog) pclog("%g\n", ST(0)); - CLOCK_CYCLES(21); + CLOCK_CYCLES(x87_timings.frndint); return 0; } @@ -645,7 +645,7 @@ static int opFSCALE(uint32_t fetchdat) temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; - CLOCK_CYCLES(30); + CLOCK_CYCLES(x87_timings.fscale); return 0; } @@ -657,7 +657,7 @@ static int opFSIN(uint32_t fetchdat) ST(0) = sin(ST(0)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES(300); + CLOCK_CYCLES(x87_timings.fsin_cos); return 0; } @@ -669,7 +669,7 @@ static int opFCOS(uint32_t fetchdat) ST(0) = cos(ST(0)); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES(300); + CLOCK_CYCLES(x87_timings.fsin_cos); return 0; } @@ -697,7 +697,7 @@ static int FLDENV() cpu_state.TOP = (cpu_state.npxs >> 11) & 7; break; } - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES(x87_timings.fldenv); return cpu_state.abrt; } @@ -729,7 +729,7 @@ static int opFLDCW_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fldcw); return 0; } static int opFLDCW_a32(uint32_t fetchdat) @@ -743,7 +743,7 @@ static int opFLDCW_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(4); + CLOCK_CYCLES(x87_timings.fldcw); return 0; } @@ -787,7 +787,7 @@ static int FSTENV() writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); break; } - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES(x87_timings.fstenv); return cpu_state.abrt; } @@ -815,7 +815,7 @@ static int opFSTCW_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw(cpu_state.npxc); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } static int opFSTCW_a32(uint32_t fetchdat) @@ -825,7 +825,7 @@ static int opFSTCW_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); if (fplog) pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); seteaw(cpu_state.npxc); - CLOCK_CYCLES(3); + CLOCK_CYCLES(x87_timings.fstcw_sw); return cpu_state.abrt; } From ea4dd4047c8361e23faeea321dbcf6bc576469b8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 24 Jan 2020 20:33:59 +0000 Subject: [PATCH 0769/1050] Added FENI/FDISI for 8087. --- src/x87_ops.h | 6 ++++-- src/x87_ops_misc.h | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/x87_ops.h b/src/x87_ops.h index 225d56c..361dcb7 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -10,6 +10,8 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ #define STATUS_ZERODIVIDE 4 +#define FPCW_DISI (1 << 7) + #define x87_div(dst, src1, src2) do \ { \ if (((double)src2) == 0.0) \ @@ -639,7 +641,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, + opFENI, opFDISI, 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, @@ -679,7 +681,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, + opFENI, opFDISI, 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_misc.h b/src/x87_ops_misc.h index a5fc002..3a572cc 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -1,3 +1,30 @@ +static int opFDISI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + if (fpu_type == FPU_8087) + { + cpu_state.npxc |= FPCW_DISI; + CLOCK_CYCLES(x87_timings.fdisi_eni); + } + else + CLOCK_CYCLES(x87_timings.fnop); + return 0; +} +static int opFENI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + if (fpu_type == FPU_8087) + { + cpu_state.npxc &= ~FPCW_DISI; + CLOCK_CYCLES(x87_timings.fdisi_eni); + } + else + CLOCK_CYCLES(x87_timings.fnop); + return 0; +} + static int opFSTSW_AX(uint32_t fetchdat) { FP_ENTER(); From 10f98a85b43596aab71be7892159e08b432013c3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 25 Jan 2020 08:14:27 +0000 Subject: [PATCH 0770/1050] Added x87_timings.c/h missing from rev 1492. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/x87_timings.c | 309 +++++++++++++++++++++++++++++ src/x87_timings.h | 56 ++++++ 5 files changed, 368 insertions(+), 3 deletions(-) create mode 100644 src/x87_timings.c create mode 100644 src/x87_timings.h diff --git a/src/Makefile.am b/src/Makefile.am index b74eb1f..1822b92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,7 +49,7 @@ vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c v vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c vt82c586b.c \ -w83877tf.c x86seg.c x87.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc +w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 1aa71d7..f5d3acc 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -37,7 +37,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ - vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o wx-main.o \ + vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 0297862..6fc6344 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -37,7 +37,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ - vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o xi8088.c xtide.o win-midi.o wx-main.o \ + vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/x87_timings.c b/src/x87_timings.c new file mode 100644 index 0000000..757f05c --- /dev/null +++ b/src/x87_timings.c @@ -0,0 +1,309 @@ +#include "ibm.h" +#include "x87_timings.h" + +x87_timings_t x87_timings; + +const x87_timings_t x87_timings_8087 = +{ + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = (6 + 12) / 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = 0, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 4, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 +}; + +/*Mostly the same as 8087*/ +const x87_timings_t x87_timings_287 = +{ + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = (2 + 8) / 2, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 3, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 +}; + +const x87_timings_t x87_timings_387 = +{ + .f2xm1 = (211 + 476) / 2, + .fabs = 22, + .fadd = (23 + 34) / 2, + .fadd_32 = (24 + 32) / 2, + .fadd_64 = (29 + 37) / 2, + .fbld = (266 + 275) / 2, + .fbstp = (512 + 534) / 2, + .fchs = (24 + 25) / 2, + .fclex = 11, + .fcom = 24, + .fcom_32 = 26, + .fcom_64 = 31, + .fcos = (122 + 772) / 2, + .fincdecstp = 22, + .fdisi_eni = 2, + .fdiv = (88 + 91) / 2, + .fdiv_32 = 89, + .fdiv_64 = 94, + .ffree = 18, + .fadd_i16 = (71 + 85) / 2, + .fadd_i32 = (57 + 72) / 2, + .fcom_i16 = (71 + 75) / 2, + .fcom_i32 = (56 + 63) / 2, + .fdiv_i16 = (136 + 140) / 2, + .fdiv_i32 = (120 + 127) / 2, + .fild_16 = (61 + 65) / 2, + .fild_32 = (45 + 52) / 2, + .fild_64 = (56 + 67) / 2, + .fmul_i16 = (76 + 87) / 2, + .fmul_i32 = (61 + 82) / 2, + .finit = 33, + .fist_16 = (82 + 95) / 2, + .fist_32 = (79 + 93) / 2, + .fist_64 = (80 + 97) / 2, + .fld = 14, + .fld_32 = 20, + .fld_64 = 25, + .fld_80 = 44, + .fld_z1 = (20 + 24) / 2, + .fld_const = 40, + .fldcw = 19, + .fldenv = 71, + .fmul = (29 + 57) / 2, + .fmul_32 = (27 + 35) / 2, + .fmul_64 = (32 + 57) / 2, + .fnop = 12, + .fpatan = (314 + 487) / 2, + .fprem = (74 + 155) / 2, + .fprem1 = (95 + 185) / 2, + .fptan = (191 + 497) / 2, + .frndint = (66 + 80) / 2, + .frstor = 308, + .fsave = 375, + .fscale = (67 + 86) / 2, + .fsetpm = 12, + .fsin_cos = (122 + 771) / 2, + .fsincos = (194 + 809) / 2, + .fsqrt = (122 + 129) / 2, + .fst = 11, + .fst_32 = 44, + .fst_64 = 45, + .fst_80 = 53, + .fstcw_sw = 15, + .fstenv = 103, + .ftst = 28, + .fucom = 24, + .fwait = 6, + .fxam = (30 + 38) / 2, + .fxch = 18, + .fxtract = (70 + 76) / 2, + .fyl2x = (120 + 538) / 2, + .fyl2xp1 = (257 + 547) / 2 +}; + +const x87_timings_t x87_timings_486 = +{ + .f2xm1 = (140 + 270) / 2, + .fabs = 3, + .fadd = (8 + 20) / 2, + .fadd_32 = (8 + 20) / 2, + .fadd_64 = (8 + 20) / 2, + .fbld = (70 + 103) / 2, + .fbstp = (172 + 176) / 2, + .fchs = 6, + .fclex = 7, + .fcom = 4, + .fcom_32 = 4, + .fcom_64 = 4, + .fcos = (257 + 354) / 2, + .fincdecstp = 3, + .fdisi_eni = 3, + .fdiv = 73, + .fdiv_32 = 73, + .fdiv_64 = 73, + .ffree = 3, + .fadd_i16 = (20 + 35) / 2, + .fadd_i32 = (19 + 32) / 2, + .fcom_i16 = (16 + 20) / 2, + .fcom_i32 = (15 + 17) / 2, + .fdiv_i16 = (85 + 89) / 2, + .fdiv_i32 = (84 + 86) / 2, + .fild_16 = (13 + 16) / 2, + .fild_32 = (9 + 12) / 2, + .fild_64 = (10 + 18) / 2, + .fmul_i16 = (23 + 27) / 2, + .fmul_i32 = (22 + 24) / 2, + .finit = 17, + .fist_16 = (29 + 34) / 2, + .fist_32 = (28 + 34) / 2, + .fist_64 = (29 + 34) / 2, + .fld = 4, + .fld_32 = 3, + .fld_64 = 3, + .fld_80 = 6, + .fld_z1 = 4, + .fld_const = 8, + .fldcw = 4, + .fldenv = 34, + .fmul = 16, + .fmul_32 = 11, + .fmul_64 = 14, + .fnop = 3, + .fpatan = (218 + 303) / 2, + .fprem = (70 + 138) / 2, + .fprem1 = (72 + 167) / 2, + .fptan = (200 + 273) / 2, + .frndint = (21 + 30) / 2, + .frstor = 120, + .fsave = 143, + .fscale = (30 + 32) / 2, + .fsetpm = 3, + .fsin_cos = (257 + 354) / 2, + .fsincos = (292 + 365) / 2, + .fsqrt = (83 + 87) / 2, + .fst = 3, + .fst_32 = 7, + .fst_64 = 8, + .fst_80 = 6, + .fstcw_sw = 3, + .fstenv = 56, + .ftst = 4, + .fucom = 4, + .fwait = (1 + 3) / 2, + .fxam = 8, + .fxch = 4, + .fxtract = (16 + 20) / 2, + .fyl2x = (196 + 329) / 2, + .fyl2xp1 = (171 + 326) / 2 +}; diff --git a/src/x87_timings.h b/src/x87_timings.h new file mode 100644 index 0000000..14ab7dd --- /dev/null +++ b/src/x87_timings.h @@ -0,0 +1,56 @@ +typedef struct +{ + int f2xm1; + int fabs; + int fadd, fadd_32, fadd_64; + int fbld; + int fbstp; + int fchs; + int fclex; + int fcom, fcom_32, fcom_64; + int fcos; + int fincdecstp; + int fdisi_eni; + int fdiv, fdiv_32, fdiv_64; + int ffree; + int fadd_i16, fadd_i32; + int fcom_i16, fcom_i32; + int fdiv_i16, fdiv_i32; + int fild_16, fild_32, fild_64; + int fmul_i16, fmul_i32; + int finit; + int fist_16, fist_32, fist_64; + int fld, fld_32, fld_64, fld_80; + int fld_z1, fld_const; + int fldcw; + int fldenv; + int fmul, fmul_32, fmul_64; + int fnop; + int fpatan; + int fprem, fprem1; + int fptan; + int frndint; + int frstor; + int fsave; + int fscale; + int fsetpm; + int fsin_cos, fsincos; + int fsqrt; + int fst, fst_32, fst_64, fst_80; + int fstcw_sw; + int fstenv; + int ftst; + int fucom; + int fwait; + int fxam; + int fxch; + int fxtract; + int fyl2x, fyl2xp1; +} x87_timings_t; + +extern const x87_timings_t x87_timings_8087; +extern const x87_timings_t x87_timings_287; +extern const x87_timings_t x87_timings_387; +extern const x87_timings_t x87_timings_486; + +extern x87_timings_t x87_timings; From 68a2d8cb3c91a992882c2f3de6f9e30fe04563a0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 1 Feb 2020 16:30:34 +0000 Subject: [PATCH 0771/1050] Added Cirrus Logic GD5428 emulation. As part of this, added emulation of the GD5428-based IBM 1MB SVGA Adapter/A, along with support for external graphics cards on MCA platforms, adding the ability to override the onboard VGA controller. --- src/hdd_esdi.c | 2 +- src/ibm.h | 4 +- src/mca.c | 18 +++- src/mca.h | 3 +- src/model.c | 14 +-- src/ps2_mca.c | 15 ++- src/sound_adlib.c | 2 +- src/sound_sb.c | 4 +- src/vid_cl5429.c | 257 ++++++++++++++++++++++++++++++++++++++++++---- src/vid_cl5429.h | 2 + src/vid_vga.c | 30 ++++++ src/vid_vga.h | 6 ++ src/video.c | 23 ++++- src/wx-config.c | 5 +- 14 files changed, 342 insertions(+), 43 deletions(-) diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 6eb239a..04c4317 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -917,7 +917,7 @@ static void *esdi_init() timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); - mca_add(esdi_mca_read, esdi_mca_write, esdi); + mca_add(esdi_mca_read, esdi_mca_write, NULL, esdi); esdi->pos_regs[0] = 0xff; esdi->pos_regs[1] = 0xdd; diff --git a/src/ibm.h b/src/ibm.h index 661d950..f801989 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -165,7 +165,7 @@ int driveempty[2]; #define PCJR (romset == ROM_IBMPCJR) int GAMEBLASTER, GUS, SSI2001, voodoo_enabled; -extern int AMSTRAD, AT, is386, PCI, TANDY; +extern int AMSTRAD, AT, is386, PCI, TANDY, MCA; enum { @@ -304,6 +304,8 @@ enum GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/ GFX_MYSTIQUE, /*Matrox Mystique*/ GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/ + GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/ + GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/ GFX_MAX }; diff --git a/src/mca.c b/src/mca.c index ebd8ccb..11f8268 100644 --- a/src/mca.c +++ b/src/mca.c @@ -6,6 +6,7 @@ void (*mca_card_write[8])(int addr, uint8_t val, void *priv); uint8_t (*mca_card_read[8])(int addr, void *priv); +void (*mca_card_reset[8])(void *priv); void *mca_priv[8]; static int mca_index; static int mca_nr_cards; @@ -14,10 +15,13 @@ void mca_init(int nr_cards) { int c; + MCA = 1; + for (c = 0; c < 8; c++) { mca_card_read[c] = NULL; mca_card_write[c] = NULL; + mca_card_reset[c] = NULL; mca_priv[c] = NULL; } @@ -47,7 +51,18 @@ void mca_write(uint16_t port, uint8_t val) 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) +void mca_reset(void) +{ + int c; + + for (c = 0; c < 8; c++) + { + if (mca_card_reset[c]) + mca_card_reset[c](mca_priv[c]); + } +} + +void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), void *priv) { int c; @@ -57,6 +72,7 @@ void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint { mca_card_read[c] = read; mca_card_write[c] = write; + mca_card_reset[c] = reset; mca_priv[c] = priv; return; } diff --git a/src/mca.h b/src/mca.h index cf9361f..a298d24 100644 --- a/src/mca.h +++ b/src/mca.h @@ -1,5 +1,6 @@ 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_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(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); +void mca_reset(void); diff --git a/src/model.c b/src/model.c index 5d582f5..669fb37 100644 --- a/src/model.c +++ b/src/model.c @@ -127,7 +127,7 @@ void xt_zenith_init(); void at_mvp3_init(); int model; -int AMSTRAD, AT, PCI, TANDY; +int AMSTRAD, AT, PCI, TANDY, MCA; MODEL models[] = { @@ -174,7 +174,7 @@ MODEL models[] = {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 512,16384, 512, ps1_m2011_init, NULL}, {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL}, {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, @@ -190,21 +190,21 @@ MODEL models[] = {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512,16384, 128, at_neat_init, NULL}, {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, + {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 512, at_scatsx_init, NULL}, {"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL}, {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, - {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, + {"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, + {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, - {"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, + {"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, {"[486] Packard Bell PB410A", ROM_PB410A, "pb410a", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 64, 1, at_pb410a_init, NULL}, {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, @@ -788,7 +788,7 @@ void at_mvp3_init() void model_init() { pclog("Initting as %s\n", model_getname()); - AMSTRAD = AT = PCI = TANDY = 0; + AMSTRAD = AT = PCI = TANDY = MCA = 0; ide_set_bus_master(NULL, NULL, NULL, NULL); models[model].init(); diff --git a/src/ps2_mca.c b/src/ps2_mca.c index 1e8b77f..f510e46 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -9,6 +9,7 @@ #include "ps2_nvr.h" #include "rom.h" #include "serial.h" +#include "vid_vga.h" #include "x86.h" //static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; @@ -652,6 +653,8 @@ static void ps2_mca_write(uint16_t port, uint8_t val, void *p) ps2.setup = val; break; case 0x96: + if ((val & 0x80) && !(ps2.adapter_setup & 0x80)) + mca_reset(); ps2.adapter_setup = val; mca_set_index(val & 7); break; @@ -671,7 +674,15 @@ static void ps2_mca_write(uint16_t port, uint8_t val, void *p) if (!(ps2.setup & PS2_SETUP_IO)) ps2.planar_write(port, val); else if (!(ps2.setup & PS2_SETUP_VGA)) + { + if (mb_vga) + { + vga_disable(mb_vga); + if (val & 1) + vga_enable(mb_vga); + } ps2.pos_vga = val; + } else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) mca_write(port, val); break; @@ -1018,7 +1029,7 @@ void ps2_mca_board_model_70_type34_init(int is_type4) break; } - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL); mem_mapping_add(&ps2.expansion_mapping, 0x800000, (mem_size - 8192)*1024, @@ -1119,7 +1130,7 @@ void ps2_mca_board_model_80_type2_init() break; } - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL); mem_mapping_add(&ps2.expansion_mapping, 0x400000, (mem_size - 4096)*1024, diff --git a/src/sound_adlib.c b/src/sound_adlib.c index 0be5259..da3de33 100644 --- a/src/sound_adlib.c +++ b/src/sound_adlib.c @@ -76,7 +76,7 @@ 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); + mca_add(adlib_mca_read, adlib_mca_write, NULL, adlib); adlib->pos_regs[0] = 0xd7; adlib->pos_regs[1] = 0x70; diff --git a/src/sound_sb.c b/src/sound_sb.c index 0fb5d48..9766291 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -999,7 +999,7 @@ void *sb_mcv_init() sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sound_add_handler(sb_get_buffer_sb2, sb); /* I/O handlers activated in sb_mcv_write */ - mca_add(sb_mcv_read, sb_mcv_write, sb); + mca_add(sb_mcv_read, sb_mcv_write, NULL, sb); sb->pos_regs[0] = 0x84; sb->pos_regs[1] = 0x50; return sb; @@ -1124,7 +1124,7 @@ void *sb_pro_mcv_init() sound_add_handler(sb_get_buffer_sbpro, sb); /* I/O handlers activated in sb_pro_mcv_write */ - mca_add(sb_pro_mcv_read, sb_pro_mcv_write, sb); + mca_add(sb_pro_mcv_read, sb_pro_mcv_write, NULL, sb); sb->pos_regs[0] = 0x03; sb->pos_regs[1] = 0x51; diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index f94fddf..8dafa52 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -4,6 +4,7 @@ #include "cpu.h" #include "device.h" #include "io.h" +#include "mca.h" #include "mem.h" #include "pci.h" #include "rom.h" @@ -11,11 +12,13 @@ #include "vid_cl5429.h" #include "vid_svga.h" #include "vid_svga_render.h" +#include "vid_vga.h" #include "vid_unk_ramdac.h" enum { CL_TYPE_AVGA2 = 0, + CL_TYPE_GD5428, CL_TYPE_GD5429, CL_TYPE_GD5430, CL_TYPE_GD5434 @@ -25,6 +28,10 @@ enum #define BLIT_DEPTH_16 1 #define BLIT_DEPTH_32 3 +#define CL_GD5428_SYSTEM_BUS_MCA 5 +#define CL_GD5428_SYSTEM_BUS_VESA 6 +#define CL_GD5428_SYSTEM_BUS_ISA 7 + #define CL_GD5429_SYSTEM_BUS_VESA 5 #define CL_GD5429_SYSTEM_BUS_ISA 7 @@ -50,7 +57,8 @@ typedef struct gd5429_t struct { - uint32_t bg_col, fg_col; + uint32_t bg_col, fg_col; + uint16_t trans_col, trans_mask; uint16_t width, height; uint16_t dst_pitch, src_pitch; uint32_t dst_addr, src_addr; @@ -60,6 +68,9 @@ typedef struct gd5429_t uint16_t width_backup, height_internal; int x_count, y_count; int depth; + + int mem_word_sel; + uint16_t mem_word_save; } blt; uint8_t hidden_dac_reg; @@ -69,6 +80,9 @@ typedef struct gd5429_t uint8_t int_line; int card; + uint8_t pos_regs[8]; + svga_t *mb_vga; + uint32_t lfb_base; int mmio_vram_overlap; @@ -76,6 +90,8 @@ typedef struct gd5429_t uint8_t sr10_read, sr11_read; uint8_t latch_ext[4]; + + int vidsys_ena; } gd5429_t; #define GRB_X8_ADDRESSING (1 << 1) @@ -97,6 +113,8 @@ void gd5429_recalc_mapping(gd5429_t *gd5429); uint8_t gd5429_read_linear(uint32_t addr, void *p); +static void ibm_gd5428_mapping_update(gd5429_t *gd5429); + void gd5429_out(uint16_t addr, uint8_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; @@ -110,6 +128,14 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) switch (addr) { + case 0x3c3: + if (MCA) + { + gd5429->vidsys_ena = val & 1; + ibm_gd5428_mapping_update(gd5429); + } + break; + case 0x3c4: svga->seqaddr = val; break; @@ -206,7 +232,7 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) if (svga->gdcaddr > 8) { svga->gdcreg[svga->gdcaddr & 0x3f] = val; - if (gd5429->type < CL_TYPE_GD5429 && (svga->gdcaddr > 0xb)) + if (gd5429->type < CL_TYPE_GD5428 && (svga->gdcaddr > 0xb)) return; switch (svga->gdcaddr) { @@ -296,7 +322,24 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x31: gd5429_mmio_write(0xb8040, val, gd5429); break; - } + + case 0x34: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_col = (gd5429->blt.trans_col & 0xff00) | val; + break; + case 0x35: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_col = (gd5429->blt.trans_col & 0x00ff) | (val << 8); + break; + case 0x36: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0xff00) | val; + break; + case 0x37: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0x00ff) | (val << 8); + break; + } return; } break; @@ -337,6 +380,11 @@ uint8_t gd5429_in(uint16_t addr, void *p) switch (addr) { + case 0x3c3: + if (MCA) + return gd5429->vidsys_ena; + break; + case 0x3c4: if ((svga->seqaddr & 0x1f) == 0x10) return (svga->seqaddr & 0x1f) | gd5429->sr10_read; @@ -355,11 +403,20 @@ uint8_t gd5429_in(uint16_t addr, void *p) return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; case 0x17: - if (gd5429->type < CL_TYPE_GD5429) + if (gd5429->type < CL_TYPE_GD5428) break; temp = svga->seqregs[0x17]; temp &= ~(7 << 3); - if (gd5429->type == CL_TYPE_GD5429) + if (gd5429->type == CL_TYPE_GD5428) + { + if (MCA) + temp |= (CL_GD5428_SYSTEM_BUS_MCA << 3); + else if (has_vlb) + temp |= (CL_GD5428_SYSTEM_BUS_VESA << 3); + else + temp |= (CL_GD5428_SYSTEM_BUS_ISA << 3); + } + else if (gd5429->type == CL_TYPE_GD5429) { if (has_vlb) temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); @@ -411,6 +468,8 @@ uint8_t gd5429_in(uint16_t addr, void *p) { case CL_TYPE_AVGA2: return 0x18; /*AVGA2*/ + case CL_TYPE_GD5428: + return 0x98; /*GD5428*/ case CL_TYPE_GD5429: return 0x9c; /*GD5429*/ case CL_TYPE_GD5430: @@ -453,7 +512,8 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) { svga_t *svga = &gd5429->svga; - if (PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + if ((PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) || + (MCA && (!(gd5429->pos_regs[2] & 0x01) || !gd5429->vidsys_ena))) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd5429->linear_mapping); @@ -487,7 +547,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) gd5429->mmio_vram_overlap = 1; break; } - if (svga->seqregs[0x17] & 0x04) + if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); else mem_mapping_disable(&gd5429->mmio_mapping); @@ -516,7 +576,7 @@ void gd5429_recalc_mapping(gd5429_t *gd5429) } mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd5429->linear_mapping, base, size); - if (svga->seqregs[0x17] & 0x04) + if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); else mem_mapping_disable(&gd5429->mmio_mapping); @@ -1448,9 +1508,18 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) } //pclog("%02X %02X\n", dst, mask); - if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && - !((gd5429->blt.mode & 0x08) && !mask)) - svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; + if (gd5429->type <= CL_TYPE_GD5428) + { + if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && + (!(gd5429->blt.mode & 0x08) || (dst & gd5429->blt.trans_mask) != gd5429->blt.trans_col)) + svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; + } + else + { + if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && + !((gd5429->blt.mode & 0x08) && !mask)) + svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; + } gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); @@ -1708,14 +1777,22 @@ static uint32_t gd5429_mmio_readl(uint32_t addr, void *p) void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) { + gd5429_t *gd5429 = (gd5429_t *)p; + // pclog("gd5429_blt_write_w %08X %08X\n", addr, val); - gd5429_start_blit(val, 16, p); + if (!gd5429->blt.mem_word_sel) + gd5429->blt.mem_word_save = val; + else + gd5429_start_blit(gd5429->blt.mem_word_save | (val << 16), 32, p); + gd5429->blt.mem_word_sel = !gd5429->blt.mem_word_sel; + } void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; - + + gd5429->blt.mem_word_sel = 0; // pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); if ((gd5429->blt.mode & 0x84) == 0x84) { @@ -1728,6 +1805,78 @@ void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) gd5429_start_blit(val, 32, p); } +uint8_t ibm_gd5428_mca_read(int port, void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + +// pclog("gd5429_pro_mcv_read: port=%04x %02x %04x:%04x\n", port, gd5429->pos_regs[port & 7], CS, cpu_state.pc); + + return gd5429->pos_regs[port & 7]; +} + +static void ibm_gd5428_mapping_update(gd5429_t *gd5429) +{ + gd5429_recalc_mapping(gd5429); + + io_removehandler(0x03a0, 0x0023, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_removehandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if ((gd5429->pos_regs[2] & 0x01) && gd5429->vidsys_ena) + { +// pclog(" GD5429 enable registers\n"); + io_sethandler(0x03c0, 0x0003, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (!(gd5429->svga.miscout & 1)) + io_sethandler(0x03a0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429->svga.override = 0; + if (mb_vga) + svga_set_override(mb_vga, 1); + } + else + { +// pclog(" GD5429 disable registers\n"); + gd5429->svga.override = 1; + if (mb_vga) + svga_set_override(mb_vga, 0); + } +} + +void ibm_gd5428_mca_write(int port, uint8_t val, void *p) +{ +// svga_set_override(voodoo->svga, val & 1); + gd5429_t *gd5429 = (gd5429_t *)p; + +// pclog("gd5429_pro_mcv_write: port=%04x val=%02x\n", port, val); + + if (port < 0x102) + return; + gd5429->pos_regs[port & 7] = val; + + if ((port & 7) == 2) + { + mem_mapping_disable(&gd5429->bios_rom.mapping); + io_removehandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (gd5429->pos_regs[2] & 0x01) + { +// pclog("Enable BIOS mapping\n"); + mem_mapping_enable(&gd5429->bios_rom.mapping); + io_sethandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + } +// else +// pclog("Disable BIOS mapping\n"); + } + + ibm_gd5428_mapping_update(gd5429); +} + +static void ibm_gd5428_mca_reset(void *p) +{ + gd5429_t *gd5429 = (gd5429_t *)p; + +// pclog("ibm_gd5428_mca_reset\n"); + gd5429->vidsys_ena = 0; + ibm_gd5428_mca_write(0x102, 0, gd5429); +} + static uint8_t cl_pci_read(int func, int addr, void *p) { gd5429_t *gd5429 = (gd5429_t *)p; @@ -1813,14 +1962,17 @@ static void cl_pci_write(int func, int addr, uint8_t val, void *p) } } -static void *cl_init(int type, char *fn, int pci_card) +static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) { gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); svga_t *svga = &gd5429->svga; int vram_size; memset(gd5429, 0, sizeof(gd5429_t)); - vram_size = device_get_config_int("memory"); + if (force_vram_size) + vram_size = force_vram_size; + else + vram_size = device_get_config_int("memory"); if (vram_size >= 256) gd5429->vram_mask = (vram_size << 10) - 1; else @@ -1849,6 +2001,8 @@ static void *cl_init(int type, char *fn, int pci_card) io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); svga->decode_mask = svga->vram_mask; } + if (type == CL_TYPE_GD5428) + svga->decode_mask = svga->vram_mask; svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -1888,37 +2042,70 @@ static void *cl_init(int type, char *fn, int pci_card) static void *avga2_init() { - return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1); + return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1, 0); } static void *avga2_cbm_sl386sx_init() { - return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1); + return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1, 0); +} +static void *gd5428_init() +{ + return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0); +} +static void *ibm_gd5428_init() +{ + gd5429_t *gd5429; + svga_t *mb_vga = svga_get_pri(); + + gd5429 = cl_init(CL_TYPE_GD5428, "SVGA141.ROM", -1, 1); /*Only supports 1MB*/ + gd5429->mb_vga = mb_vga; + + mca_add(ibm_gd5428_mca_read, ibm_gd5428_mca_write, ibm_gd5428_mca_reset, gd5429); + gd5429->pos_regs[0] = 0x7b; + gd5429->pos_regs[1] = 0x91; + gd5429->pos_regs[2] = 0; + + gd5429_recalc_mapping(gd5429); + io_removehandler(0x03a0, 0x0040, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429->svga.override = 1; + mem_mapping_disable(&gd5429->bios_rom.mapping); + io_sethandler(0x46e8, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + + return gd5429; } static void *gd5429_init() { - return cl_init(CL_TYPE_GD5429, "5429.vbi", -1); + return cl_init(CL_TYPE_GD5429, "5429.vbi", -1, 0); } static void *gd5430_init() { - return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1); + return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1, 0); } static void *gd5430_pb570_init() { - return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8); + return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8, 0); } static void *gd5434_init() { - return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1); + return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1, 0); } static void *gd5434_pb520r_init() { - return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3); + return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3, 0); } static int avga2_available() { return rom_present("avga2vram.vbi"); } +static int gd5428_available() +{ + return rom_present("Machspeed_VGA_GUI_2100_VLB.vbi"); +} +static int ibm_gd5428_available() +{ + return rom_present(/*"FILE.ROM"*/"SVGA141.ROM"); +} static int gd5429_available() { return rom_present("5429.vbi"); @@ -2068,6 +2255,32 @@ device_t avga2_cbm_sl386sx_device = avga2_config }; +device_t gd5428_device = +{ + "Cirrus Logic GD5428", + 0, + gd5428_init, + gd5429_close, + gd5428_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config +}; + +device_t ibm_gd5428_device = +{ + "IBM 1MB SVGA Adapter/A (Cirrus Logic GD5428)", + DEVICE_MCA, + ibm_gd5428_init, + gd5429_close, + ibm_gd5428_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + NULL +}; + device_t gd5429_device = { "Cirrus Logic GD5429", diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index 7ba0941..1dc6ef0 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1,5 +1,7 @@ extern device_t avga2_device; extern device_t avga2_cbm_sl386sx_device; +extern device_t gd5428_device; +extern device_t ibm_gd5428_device; extern device_t gd5429_device; extern device_t gd5430_device; extern device_t gd5430_pb570_device; diff --git a/src/vid_vga.c b/src/vid_vga.c index 241166f..64bd67c 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -9,6 +9,8 @@ #include "vid_svga.h" #include "vid_vga.h" +svga_t *mb_vga = NULL; + typedef struct vga_t { svga_t svga; @@ -84,6 +86,30 @@ uint8_t vga_in(uint16_t addr, void *p) return temp; } +void vga_disable(void *p) +{ + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; + +// pclog("vga_disable\n"); + io_removehandler(0x03a0, 0x0040, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + mem_mapping_disable(&svga->mapping); +} + +void vga_enable(void *p) +{ + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; + +// pclog("vga_enable\n"); + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + if (!(svga->miscout & 1)) + io_sethandler(0x03a0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + + mem_mapping_enable(&svga->mapping); +} + + void *vga_init() { vga_t *vga = malloc(sizeof(vga_t)); @@ -122,6 +148,8 @@ void *ps1vga_init() vga->svga.bpp = 8; vga->svga.miscout = 1; + mb_vga = &vga->svga; + return vga; } @@ -134,6 +162,8 @@ void vga_close(void *p) { vga_t *vga = (vga_t *)p; + mb_vga = NULL; + svga_close(&vga->svga); free(vga); diff --git a/src/vid_vga.h b/src/vid_vga.h index 3bf9459..cf58f72 100644 --- a/src/vid_vga.h +++ b/src/vid_vga.h @@ -1,2 +1,8 @@ extern device_t vga_device; extern device_t ps1vga_device; + +void vga_disable(void *p); +void vga_enable(void *p); + +struct svga_t; +extern struct svga_t *mb_vga; diff --git a/src/video.c b/src/video.c index 0105b48..d159715 100644 --- a/src/video.c +++ b/src/video.c @@ -90,6 +90,7 @@ static VIDEO_CARD video_cards[] = {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Cirrus Logic CL-GD5428", "cl_gd5428", &gd5428_device, GFX_CL_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, @@ -99,6 +100,7 @@ static VIDEO_CARD video_cards[] = {"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"IBM 1MB SVGA Adapter/A (CL GD5428)", "ibm1mbsvga", &ibm_gd5428_device, GFX_IBM_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, @@ -218,13 +220,17 @@ device_t *video_card_getdevice(int card, int romset) case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: + return &ps1vga_device; + case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: case ROM_IBMPS2_M70_TYPE3: case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: - return &ps1vga_device; - + if (card == GFX_BUILTIN) + return &ps1vga_device; + break; + case ROM_IBMPS1_2121: return &ps1_m2121_svga_device; @@ -588,12 +594,16 @@ void video_updatetiming() case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: + timing = &timing_vga; + break; + case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: case ROM_IBMPS2_M70_TYPE3: case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: - timing = &timing_vga; + if (gfxcard == GFX_BUILTIN) + timing = &timing_vga; break; case ROM_IBMPS1_2121: @@ -776,13 +786,18 @@ void video_init() case ROM_IBMPS1_2011: case ROM_IBMPS2_M30_286: + device_add(&ps1vga_device); + return; + case ROM_IBMPS2_M50: case ROM_IBMPS2_M55SX: case ROM_IBMPS2_M70_TYPE3: case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: device_add(&ps1vga_device); - return; + if (gfxcard == GFX_BUILTIN) + return; + break; case ROM_IBMPS1_2121: device_add(&ps1_m2121_svga_device); diff --git a/src/wx-config.c b/src/wx-config.c index 09fea3e..cd24749 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -147,7 +147,10 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) break; if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - ((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI))) + ((models[model].flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI)) && + ((models[model].flags & MODEL_MCA) || !(video_card_getdevice(c, romset)->flags & DEVICE_MCA)) && + (!(models[model].flags & MODEL_MCA) || (video_card_getdevice(c, romset)->flags & DEVICE_MCA)) + ) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); if (video_new_to_old(c) == gfxcard && !found_card) From adf4a2de932f648dc92d66c106ac2b8c731be1ec Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 09:07:34 +0000 Subject: [PATCH 0772/1050] Fix MOV TRx, reg encoding on non-Pentium machines. --- src/386_ops.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/386_ops.h b/src/386_ops.h index 2ad1789..34c7847 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -280,7 +280,7 @@ OpFn OP_TABLE(386_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -302,7 +302,7 @@ OpFn OP_TABLE(386_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -324,7 +324,7 @@ OpFn OP_TABLE(386_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -346,7 +346,7 @@ OpFn OP_TABLE(386_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -371,7 +371,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -393,7 +393,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -415,7 +415,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -437,7 +437,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -462,7 +462,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -484,7 +484,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -506,7 +506,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -528,7 +528,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, From 8870334114a18ed076225d3939109a4634572597 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 12:17:06 +0000 Subject: [PATCH 0773/1050] Add IBM PS/1 Model 2133 (EMEA 451) emulation. Currently displays a cache error on boot, but otherwise seems to work fine. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/ibm.h | 1 + src/mem_bios.c | 8 ++ src/model.c | 10 ++ src/nvr.c | 2 + src/ps1.c | 62 +++++++++++ src/ps1.h | 1 + src/vid_cl5429.c | 53 +++++++-- src/vid_cl5429.h | 2 + src/video.c | 16 ++- src/vl82c480.c | 169 +++++++++++++++++++++++++++++ src/vl82c480.h | 1 + 14 files changed, 319 insertions(+), 12 deletions(-) create mode 100644 src/vl82c480.c create mode 100644 src/vl82c480.h diff --git a/src/Makefile.am b/src/Makefile.am index 1822b92..cffac57 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,7 +49,7 @@ vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c v vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c vt82c586b.c \ -w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc +vl82c480.c w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index f5d3acc..cd7d7cd 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -36,7 +36,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ + vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o vl82c480.o \ vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 6fc6344..bafc186 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -36,7 +36,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o \ + vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o vl82c480.o \ vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ diff --git a/src/ibm.h b/src/ibm.h index f801989..4d4c07d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -253,6 +253,7 @@ enum ROM_BULL_MICRAL_45, ROM_FIC_VA503P, ROM_CBM_SL386SX25, + ROM_IBMPS1_2133_451, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 66d0f38..7d68fe4 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -1015,6 +1015,14 @@ int loadbios() romfread(rom, 0x10000, 1, f); fclose(f); return 1; + + case ROM_IBMPS1_2133_451: + f = romfopen("ibmps1_2133/PS1_2133_52G2974_ROM.bin", "rb"); + if (!f) break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 669fb37..38aa5d2 100644 --- a/src/model.c +++ b/src/model.c @@ -70,6 +70,7 @@ #include "vid_pcjr.h" #include "vid_tandy.h" #include "vid_t1000.h" +#include "vl82c480.h" #include "vt82c586b.h" #include "w83877tf.h" #include "wd76c10.h" @@ -91,6 +92,7 @@ void deskpro386_init(); void pb_l300sx_init(); void ps1_m2011_init(); void ps1_m2121_init(); +void ps1_m2133_init(void); void ps2_m30_286_init(); void ps2_model_50_init(); void ps2_model_55sx_init(); @@ -204,6 +206,7 @@ MODEL models[] = {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] Award SiS 496/497", ROM_SIS496, "sis496", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_sl82c460_init, NULL}, + {"[486] IBM PS/1 Model 2133 (EMEA 451)",ROM_IBMPS1_2133_451, "ibmps1_2133", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 2, 64, 2, ps1_m2133_init, NULL}, {"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, {"[486] Packard Bell PB410A", ROM_PB410A, "pb410a", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 64, 1, at_pb410a_init, NULL}, @@ -507,6 +510,13 @@ void ps1_m2121_init() fdc_set_ps1(); } +void ps1_m2133_init(void) +{ + at_init(); + vl82c480_init(); + ps1mb_m2133_init(); +} + void ps2_m30_286_init() { AT = 1; diff --git a/src/nvr.c b/src/nvr.c index 3a15a55..140e0e9 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -348,6 +348,7 @@ void loadnvr() case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); break; case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break; case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break; + case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -447,6 +448,7 @@ void savenvr() case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); break; case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break; case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break; + case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break; default: return; } diff --git a/src/ps1.c b/src/ps1.c index b2ea50f..f248647 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -301,3 +301,65 @@ void ps1mb_m2121_init() mem_remap_top_384k(); } + + +/*Not sure what this SuperIO chip is, so define it here for now*/ +static struct +{ + int idx; + uint8_t regs[3]; +} ps1_m2133_superio; + +static uint16_t ps1_lpt_io[4] = {0x378, 0x3bc, 0x278, 0x378}; +static uint16_t ps1_com_io[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; + +static uint8_t ps1_m2133_read(uint16_t port, void *p) +{ + uint8_t ret = 0xff; + switch (port) + { + case 0x398: + ret = ps1_m2133_superio.idx; + break; + + case 0x399: + if (ps1_m2133_superio.idx < 3) + ret = ps1_m2133_superio.regs[ps1_m2133_superio.idx]; + break; + } + return ret; +} + +static void ps1_m2133_write(uint16_t port, uint8_t val, void *p) +{ +// pclog("ps1_m2133_write: port=%04x val=%02x\n", port, val); + switch (port) + { + case 0x398: + ps1_m2133_superio.idx = val; + break; + + case 0x399: + if (ps1_m2133_superio.idx < 3) + { + ps1_m2133_superio.regs[ps1_m2133_superio.idx] = val; + + lpt1_remove(); + serial1_remove(); + serial2_remove(); + + if (ps1_m2133_superio.regs[0] & 1) + lpt1_init(ps1_lpt_io[ps1_m2133_superio.regs[1] & 3]); + if (ps1_m2133_superio.regs[0] & 2) + serial1_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 2) & 3], 4); + if (ps1_m2133_superio.regs[0] & 4) + serial2_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 4) & 3], 3); + } + break; + } +} + +void ps1mb_m2133_init(void) +{ + io_sethandler(0x0398, 0x0002, ps1_m2133_read, NULL, NULL, ps1_m2133_write, NULL, NULL, NULL); +} diff --git a/src/ps1.h b/src/ps1.h index c054bcb..7253c8b 100644 --- a/src/ps1.h +++ b/src/ps1.h @@ -1,2 +1,3 @@ void ps1mb_init(); void ps1mb_m2121_init(); +void ps1mb_m2133_init(void); diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 8dafa52..153723d 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -18,6 +18,7 @@ enum { CL_TYPE_AVGA2 = 0, + CL_TYPE_GD5426, CL_TYPE_GD5428, CL_TYPE_GD5429, CL_TYPE_GD5430, @@ -226,13 +227,27 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) svga->gdcreg[6] = val; gd5429_recalc_mapping(gd5429); } + + /*Hack - the Windows 3.x drivers for the GD5426/8 require VRAM wraparound + for pattern & cursor writes to work correctly, but the BIOSes require + no wrapping to detect memory size - albeit with odd/even mode enabled. + This may be a quirk of address mapping. So change wrapping mode based on + odd/even mode for now*/ + if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) + { + if (val & 2) /*Odd/Even*/ + svga->decode_mask = 0x1fffff; + else + svga->decode_mask = svga->vram_mask; + } + svga->gdcreg[6] = val; return; } if (svga->gdcaddr > 8) { svga->gdcreg[svga->gdcaddr & 0x3f] = val; - if (gd5429->type < CL_TYPE_GD5428 && (svga->gdcaddr > 0xb)) + if (gd5429->type < CL_TYPE_GD5426 && (svga->gdcaddr > 0xb)) return; switch (svga->gdcaddr) { @@ -403,11 +418,11 @@ uint8_t gd5429_in(uint16_t addr, void *p) return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; case 0x17: - if (gd5429->type < CL_TYPE_GD5428) + if (gd5429->type < CL_TYPE_GD5426) break; temp = svga->seqregs[0x17]; temp &= ~(7 << 3); - if (gd5429->type == CL_TYPE_GD5428) + if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) { if (MCA) temp |= (CL_GD5428_SYSTEM_BUS_MCA << 3); @@ -468,6 +483,8 @@ uint8_t gd5429_in(uint16_t addr, void *p) { case CL_TYPE_AVGA2: return 0x18; /*AVGA2*/ + case CL_TYPE_GD5426: + return 0x90; /*GD5426*/ case CL_TYPE_GD5428: return 0x98; /*GD5428*/ case CL_TYPE_GD5429: @@ -644,8 +661,12 @@ void gd5429_recalctimings(svga_t *svga) n = svga->seqregs[0xb + clock] & 0x7f; d = (svga->seqregs[0x1b + clock] >> 1) & 0x1f; p = svga->seqregs[0x1b + clock] & 1; - - vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p); + + /*Prevent divide by zero during clock setup*/ + if (d && n) + vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p); + else + vclk = 14318184.0; switch (svga->seqregs[7] & ((gd5429->type >= CL_TYPE_GD5434) ? 0xe : 0x6)) { case 2: @@ -1980,7 +2001,8 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) gd5429->type = type; - rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (fn) + rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&gd5429->svga, gd5429, (vram_size >= 256) ? (vram_size << 10) : (vram_size << 20), gd5429_recalctimings, @@ -2001,8 +2023,6 @@ static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); svga->decode_mask = svga->vram_mask; } - if (type == CL_TYPE_GD5428) - svga->decode_mask = svga->vram_mask; svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -2048,6 +2068,10 @@ static void *avga2_cbm_sl386sx_init() { return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1, 0); } +static void *gd5426_ps1_init() +{ + return cl_init(CL_TYPE_GD5426, NULL, -1, 1); +} static void *gd5428_init() { return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0); @@ -2255,6 +2279,19 @@ device_t avga2_cbm_sl386sx_device = avga2_config }; +device_t gd5426_ps1_device = +{ + "Cirrus Logic GD5426 (IBM PS/1)", + 0, + gd5426_ps1_init, + gd5429_close, + NULL, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + NULL +}; + device_t gd5428_device = { "Cirrus Logic GD5428", diff --git a/src/vid_cl5429.h b/src/vid_cl5429.h index 1dc6ef0..edeab65 100644 --- a/src/vid_cl5429.h +++ b/src/vid_cl5429.h @@ -1,8 +1,10 @@ extern device_t avga2_device; extern device_t avga2_cbm_sl386sx_device; +extern device_t gd5426_ps1_device; extern device_t gd5428_device; extern device_t ibm_gd5428_device; extern device_t gd5429_device; +extern device_t gd5429_reply_m25_device; extern device_t gd5430_device; extern device_t gd5430_pb570_device; extern device_t gd5434_device; diff --git a/src/video.c b/src/video.c index d159715..2c7dd21 100644 --- a/src/video.c +++ b/src/video.c @@ -234,6 +234,9 @@ device_t *video_card_getdevice(int card, int romset) case ROM_IBMPS1_2121: return &ps1_m2121_svga_device; + case ROM_IBMPS1_2133_451: + return &gd5426_ps1_device; + case ROM_T3100E: return &t3100e_device; @@ -372,7 +375,8 @@ int video_is_mda() case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: - case ROM_T3100E: + case ROM_IBMPS1_2133_451: + case ROM_T3100E: case ROM_T1000: case ROM_ELX_PC425X: case ROM_PB410A: @@ -421,6 +425,7 @@ int video_is_cga() case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: + case ROM_IBMPS1_2133_451: case ROM_ELX_PC425X: case ROM_PB410A: case ROM_PB570: @@ -460,6 +465,7 @@ int video_is_ega_vga() case ROM_IBMPS2_M70_TYPE4: case ROM_IBMPS2_M80: case ROM_IBMPS1_2121: + case ROM_IBMPS1_2133_451: case ROM_ELX_PC425X: case ROM_PB410A: case ROM_PB570: @@ -610,6 +616,10 @@ void video_updatetiming() timing = &timing_ps1_svga; break; + case ROM_IBMPS1_2133_451: + timing = &timing_pb570; + break; + case ROM_T3100E: timing = &timing_t3100e; break; @@ -803,6 +813,10 @@ void video_init() device_add(&ps1_m2121_svga_device); return; + case ROM_IBMPS1_2133_451: + device_add(&gd5426_ps1_device); + return; + case ROM_T3100E: device_add(&t3100e_device); return; diff --git a/src/vl82c480.c b/src/vl82c480.c new file mode 100644 index 0000000..57bcce5 --- /dev/null +++ b/src/vl82c480.c @@ -0,0 +1,169 @@ +#include "ibm.h" +#include "io.h" +#include "mem.h" +#include "vl82c480.h" + +static struct +{ + int cfg_index; + uint8_t cfg_regs[256]; + + uint8_t port_92; +} vl82c480; + +#define CFG_ID 0x00 +#define CFG_AAXS 0x0d +#define CFG_BAXS 0x0e +#define CFG_CAXS 0x0f +#define CFG_DAXS 0x10 +#define CFG_EAXS 0x11 +#define CFG_FAXS 0x12 + +#define ID_VL82C480 0x90 + +static void shadow_control(uint32_t addr, uint32_t size, int state) +{ +// pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); + switch (state) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +void vl82c480_write(uint16_t addr, uint8_t val, void *p) +{ +// if (addr != 0x92) pclog("vl82c480_write: addr=%04x val=%02x\n", addr, val); + switch (addr) + { + case 0x92: + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~vl82c480.port_92 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + vl82c480.port_92 = val; + break; + + case 0xec: + vl82c480.cfg_index = val; + break; + + case 0xed: + if (vl82c480.cfg_index >= 0x01 && vl82c480.cfg_index <= 0x24) + { + vl82c480.cfg_regs[vl82c480.cfg_index] = val; + switch (vl82c480.cfg_index) + { + case CFG_AAXS: + shadow_control(0xa0000, 0x4000, val & 3); + shadow_control(0xa4000, 0x4000, (val >> 2) & 3); + shadow_control(0xa8000, 0x4000, (val >> 4) & 3); + shadow_control(0xac000, 0x4000, (val >> 6) & 3); + break; + case CFG_BAXS: + shadow_control(0xb0000, 0x4000, val & 3); + shadow_control(0xb4000, 0x4000, (val >> 2) & 3); + shadow_control(0xb8000, 0x4000, (val >> 4) & 3); + shadow_control(0xbc000, 0x4000, (val >> 6) & 3); + break; + case CFG_CAXS: + shadow_control(0xc0000, 0x4000, val & 3); + shadow_control(0xc4000, 0x4000, (val >> 2) & 3); + shadow_control(0xc8000, 0x4000, (val >> 4) & 3); + shadow_control(0xcc000, 0x4000, (val >> 6) & 3); + break; + case CFG_DAXS: + shadow_control(0xd0000, 0x4000, val & 3); + shadow_control(0xd4000, 0x4000, (val >> 2) & 3); + shadow_control(0xd8000, 0x4000, (val >> 4) & 3); + shadow_control(0xdc000, 0x4000, (val >> 6) & 3); + break; + case CFG_EAXS: + shadow_control(0xe0000, 0x4000, val & 3); + shadow_control(0xe4000, 0x4000, (val >> 2) & 3); + shadow_control(0xe8000, 0x4000, (val >> 4) & 3); + shadow_control(0xec000, 0x4000, (val >> 6) & 3); + break; + case CFG_FAXS: + shadow_control(0xf0000, 0x4000, val & 3); + shadow_control(0xf4000, 0x4000, (val >> 2) & 3); + shadow_control(0xf8000, 0x4000, (val >> 4) & 3); + shadow_control(0xfc000, 0x4000, (val >> 6) & 3); + break; + } + } + break; + + case 0xee: + if (mem_a20_alt) + { + vl82c480.port_92 &= ~2; + mem_a20_alt = 0; + mem_a20_recalc(); + } + break; + } +} + +uint8_t vl82c480_read(uint16_t addr, void *p) +{ + uint8_t ret = 0xff; + + switch (addr) + { + case 0x92: + ret = vl82c480.port_92; + break; + + case 0xec: + ret = vl82c480.cfg_index; + break; + + case 0xed: + ret = vl82c480.cfg_regs[vl82c480.cfg_index]; + break; + + case 0xee: + if (!mem_a20_alt) + { + vl82c480.port_92 |= 2; + mem_a20_alt = 1; + mem_a20_recalc(); + } + break; + + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } + +// pclog("vl82c480_read: addr=%04x ret=%02x\n", addr, ret); + return ret; +} + +void vl82c480_init(void) +{ + memset(&vl82c480, 0, sizeof(vl82c480)); + vl82c480.cfg_regs[CFG_ID] = ID_VL82C480; + + io_sethandler(0x0092, 0x0001, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL); + io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL); +} diff --git a/src/vl82c480.h b/src/vl82c480.h new file mode 100644 index 0000000..07cf6f7 --- /dev/null +++ b/src/vl82c480.h @@ -0,0 +1 @@ +void vl82c480_init(void); From 1540da6adab0ac4f3dae1566f88f0a0b6522851d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 12:48:09 +0000 Subject: [PATCH 0774/1050] Add IRQ 12 setting to NE2000. Patch from EluanCM. --- src/ne2000.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ne2000.c b/src/ne2000.c index 329af7e..2622f2b 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -2010,6 +2010,10 @@ static device_config_t ne2000_config[] = .description = "IRQ 11", .value = 11 }, + { + .description = "IRQ 12", + .value = 12 + }, { .description = "" } From a0a6b0faa8d6aa56d6bd8b4b524a5ba83b608bc3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 12:59:46 +0000 Subject: [PATCH 0775/1050] Fix serial IRQs on ACC3221. Patch from EluanCM. --- src/acc3221.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/acc3221.c b/src/acc3221.c index 38c6fa9..2b3fb8a 100644 --- a/src/acc3221.c +++ b/src/acc3221.c @@ -55,7 +55,7 @@ static void acc3221_write(uint16_t addr, uint8_t val, void *p) // pclog("COM1 addr %03x IRQ 3\n", addr); serial1_set(addr, 3); } - else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL1) + else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ4_SERIAL1) { // pclog("COM1 addr %03x IRQ 4\n", addr); serial1_set(addr, 4); @@ -76,7 +76,7 @@ static void acc3221_write(uint16_t addr, uint8_t val, void *p) // pclog("COM2 addr %03x IRQ 3\n", addr); serial2_set(addr, 3); } - else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ3_SERIAL2) + else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ4_SERIAL2) { // pclog("COM2 addr %03x IRQ 4\n", addr); serial2_set(addr, 4); From cda00d95cf4b3c5a37ae362956597d8cfe996264 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 13:00:39 +0000 Subject: [PATCH 0776/1050] Fix SB Pro mixer compatibility registers. Patch from EluanCM. --- src/sound_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index 9766291..58d0297 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -521,7 +521,7 @@ void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p) { /* Compatibility: chain registers 0x02 and 0x22 as well as 0x06 and 0x26 */ case 0x02: case 0x06: - mixer->regs[mixer->index+0x20]=((val&0xE) << 4)||(val&0xE) << 4; + mixer->regs[mixer->index+0x20]=((val&0xE) << 4) | (val&0xE); break; case 0x22: case 0x26: From e997985326bb87e521e0a20fb420481d7d949c00 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 13:01:37 +0000 Subject: [PATCH 0777/1050] Add additional guards in scsi_hd.c. Patch from EluanCM. --- src/scsi_hd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/scsi_hd.c b/src/scsi_hd.c index 914f984..2a064d5 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -414,7 +414,9 @@ static int scsi_hd_command(uint8_t *cdb, void *p) } for (; len >= 0; len--) + { add_data_len(0); + } len = data->data_pos_write; if (cdb[0] == SCSI_MODE_SENSE_6) From 11c199653959ff3be7ae6433f7ce2c109b7dbf88 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 14:22:00 +0000 Subject: [PATCH 0778/1050] Use AT scancodes on Xi8088. Patch from EluanCM. --- src/keyboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index 26d7280..f41d59f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -412,7 +412,7 @@ void keyboard_process() { int c; int d; - scancode *scancodes = (AT) ? at_scancodes : scancode_xt; + scancode *scancodes = (AT || romset == ROM_XI8088) ? at_scancodes : scancode_xt; if (!keyboard_scan) return; if (TANDY) scancodes = scancode_tandy; @@ -466,7 +466,7 @@ void keyboard_process() void keyboard_send_scancode(int code, int is_break) { - scancode *scancodes = (AT) ? at_scancodes : scancode_xt; + scancode *scancodes = (AT || romset == ROM_XI8088) ? at_scancodes : scancode_xt; int d = 0; if (!keyboard_scan) return; From a77fd1e7f5e7f5091d21c94bb48795dd048658e2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 17:55:28 +0000 Subject: [PATCH 0779/1050] 8087 FNINIT initialises control word to 0x3ff. Fixes FPU detection on Xi8088. --- src/x87_ops_misc.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index 3a572cc..b2f7d32 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -58,7 +58,10 @@ static int opFINIT(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.npxc = 0x37F; + if (fpu_type == FPU_8087) + cpu_state.npxc = 0x3ff; + else + cpu_state.npxc = 0x37f; codegen_set_rounding_mode(X87_ROUNDING_NEAREST); cpu_state.npxs = 0; *(uint64_t *)cpu_state.tag = 0; From 868ef093a9cc51e9559aad07269881e0bf3c0969 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 9 Feb 2020 17:56:16 +0000 Subject: [PATCH 0780/1050] Route IRQ 2 to IRQ 9 on Xi8088. Patch from EluanCM. --- src/pic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pic.c b/src/pic.c index a7636ef..3bbefbf 100644 --- a/src/pic.c +++ b/src/pic.c @@ -323,7 +323,7 @@ int pic_current[16]; void picint(uint16_t num) { - if (AT && num == (1 << 2)) + if ((AT || romset == ROM_XI8088) && num == (1 << 2)) num = 1 << 9; // pclog("picint : %04X\n", num); // if (num == 0x10) pclog("PICINT 10\n"); @@ -345,7 +345,7 @@ void picintlevel(uint16_t num) { int c = 0; while (!(num & (1 << c))) c++; - if (AT && c == 2) + if ((AT || romset == ROM_XI8088) && num == (1 << 2)) { c = 9; num = 1 << 9; @@ -371,7 +371,7 @@ void picintc(uint16_t num) if (!num) return; while (!(num & (1 << c))) c++; - if (AT && c == 2) + if ((AT || romset == ROM_XI8088) && num == (1 << 2)) { c = 9; num = 1 << 9; From 00f65675afb2d07120a74b1584fea6752217f79f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 10 Feb 2020 20:51:26 +0000 Subject: [PATCH 0781/1050] Add delay to keyboard AT reset response. A few other keyboard / PS2 mouse fixes. Based on patch from EluanCM. --- src/keyboard_at.c | 25 ++++++++++++++++++++++--- src/mouse_ps2.c | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index bed2be9..2cb829f 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -26,6 +26,8 @@ #define PS2_REFRESH_TIME (16 * TIMER_USEC) +#define RESET_DELAY_TIME (100 * 10) /*600ms*/ + struct { int initialised; @@ -58,6 +60,8 @@ struct int is_ps2; pc_timer_t send_delay_timer; + + int reset_delay; } keyboard_at; /*Translation table taken from https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3*/ @@ -89,6 +93,8 @@ static int key_queue_start = 0, key_queue_end = 0; static uint8_t mouse_queue[16]; int mouse_queue_start = 0, mouse_queue_end = 0; +void keyboard_at_adddata_keyboard(uint8_t val); + void keyboard_at_poll() { timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC)); @@ -151,7 +157,14 @@ void keyboard_at_poll() { keyboard_at.out_new = key_queue[key_queue_start]; key_queue_start = (key_queue_start + 1) & 0xf; - } + } + + if (keyboard_at.reset_delay) + { + keyboard_at.reset_delay--; + if (!keyboard_at.reset_delay) + keyboard_at_adddata_keyboard(0xaa); + } } void keyboard_at_adddata(uint8_t val) @@ -168,6 +181,8 @@ void keyboard_at_adddata(uint8_t val) void keyboard_at_adddata_keyboard(uint8_t val) { + if (keyboard_at.reset_delay) + return; /* if (val == 0x1c) { key_1c++; @@ -406,7 +421,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xff: /*Reset*/ key_queue_start = key_queue_end = 0; /*Clear key queue*/ keyboard_at_adddata_keyboard(0xfa); - keyboard_at_adddata_keyboard(0xaa); + keyboard_at.reset_delay = RESET_DELAY_TIME; break; default: @@ -651,7 +666,10 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) { case 0x60: temp = keyboard_at.out; - keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); + if (keyboard_at.last_irq == 0x1000) + keyboard_at.status &= ~(STAT_OFULL | STAT_MFULL); + else + keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); picintc(keyboard_at.last_irq); keyboard_at.last_irq = 0; break; @@ -699,6 +717,7 @@ void keyboard_at_reset() else keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; keyboard_at.out_new = -1; + keyboard_at.out_delayed = -1; keyboard_at.last_irq = 0; keyboard_at.key_wantdata = 0; diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index 1603cd9..32f38f9 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -123,6 +123,7 @@ void mouse_ps2_write(uint8_t val, void *p) mouse->mode = MOUSE_STREAM; mouse->flags = 0; mouse->intellimouse_mode = 0; + mouse_queue_start = mouse_queue_end = 0; keyboard_at_adddata_mouse(0xfa); keyboard_at_adddata_mouse(0xaa); keyboard_at_adddata_mouse(0x00); From 32563970c25265aee4325db14d9f1f12bc0ce628 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 18 Feb 2020 12:08:53 +0000 Subject: [PATCH 0782/1050] Bit 0 of port 3da on Amstrad PC1512 is a toggle bit instead of display enable. --- src/vid_pc1512.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index afe3c5d..3c962d0 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -107,7 +107,8 @@ static uint8_t pc1512_in(uint16_t addr, void *p) case 0x3d5: return pc1512->crtc[pc1512->crtcreg]; case 0x3da: - return pc1512->stat; + pc1512->stat ^= 0x01; /*Bit 0 is toggle bit on PC1512*/ + return pc1512->stat ^ 0x01; } return 0xff; } @@ -174,7 +175,6 @@ static void pc1512_poll(void *p) if (!pc1512->linepos) { timer_advance_u64(&pc1512->timer, pc1512->dispofftime); - pc1512->stat |= 1; pc1512->linepos = 1; oldsc = pc1512->sc; if (pc1512->dispon) @@ -342,8 +342,6 @@ static void pc1512_poll(void *p) timer_advance_u64(&pc1512->timer, pc1512->dispontime); if ((pc1512->lastline - pc1512->firstline) == 199) pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ - if (pc1512->dispon) - pc1512->stat &= ~1; pc1512->linepos = 0; if (pc1512->vsynctime) { From 74df0bf1453807c3948e2af43086e2b2354417aa Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 18 Feb 2020 21:34:20 +0000 Subject: [PATCH 0783/1050] Revert part of rev 1505 related to clearing STAT_MFULL on reading port 0x60. Fixes PS/2 8601 errors. --- src/keyboard_at.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 2cb829f..d4e85be 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -666,10 +666,7 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) { case 0x60: temp = keyboard_at.out; - if (keyboard_at.last_irq == 0x1000) - keyboard_at.status &= ~(STAT_OFULL | STAT_MFULL); - else - keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); + keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); picintc(keyboard_at.last_irq); keyboard_at.last_irq = 0; break; From 61bdb5c8ba7f86f0141524d083cd5670f18815eb Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 26 Feb 2020 22:26:12 +0000 Subject: [PATCH 0784/1050] Added IBM SCSI Adapter with Cache (Spock) emulation. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/hdd.c | 2 + src/scsi_ibm.c | 1278 ++++++++++++++++++++++++++++ src/scsi_ibm.h | 1 + 6 files changed, 1284 insertions(+), 3 deletions(-) create mode 100644 src/scsi_ibm.c create mode 100644 src/scsi_ibm.h diff --git a/src/Makefile.am b/src/Makefile.am index cffac57..7e0ab63 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,7 +39,7 @@ keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \ neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ -scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c \ +scsi_ibm.c scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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 \ sst39sf010.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.c timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index cd7d7cd..b022645 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -25,7 +25,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ - scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ + scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index bafc186..18962a0 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -25,7 +25,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ - scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ + scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.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 \ diff --git a/src/hdd.c b/src/hdd.c index f2a9fd7..00b246d 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -9,6 +9,7 @@ #include "mfm_xebec.h" #include "scsi_53c400.h" #include "scsi_aha1540.h" +#include "scsi_ibm.h" #include "xtide.h" char hdd_controller_name[16]; @@ -39,6 +40,7 @@ static struct {"[IDE] XTIDE (PS/1)", "xtide_ps1", &xtide_ps1_device, 0, 1, 0}, {"[SCSI] Adaptec AHA-1542C", "aha1542c", &scsi_aha1542c_device, 0, 0, 1}, {"[SCSI] BusLogic BT-545S", "bt545s", &scsi_bt545s_device, 0, 0, 1}, + {"[SCSI] IBM SCSI Adapter with Cache", "ibmscsi_mca",&scsi_ibm_device, 0, 0, 1}, {"[SCSI] Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device, 0, 0, 1}, {"[SCSI] Rancho RT1000B", "rt1000b", &scsi_rt1000b_device, 0, 0, 1}, {"[SCSI] Trantor T130B", "t130b", &scsi_t130b_device, 0, 0, 1}, diff --git a/src/scsi_ibm.c b/src/scsi_ibm.c new file mode 100644 index 0000000..708c24e --- /dev/null +++ b/src/scsi_ibm.c @@ -0,0 +1,1278 @@ +#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 "scsi.h" +#include "timer.h" + +#include "scsi_ibm.h" + +#define SCSI_TIME (20) +#define POLL_TIME (TIMER_USEC * 10) +#define MAX_BYTES_TRANSFERRED_PER_POLL 50 + +extern char ide_fn[4][512]; + +typedef enum +{ + SCB_STATE_IDLE, + SCB_STATE_START, + SCB_STATE_WAIT, + SCB_STATE_COMPLETE +} sbc_state_t; + +typedef enum +{ + SCSI_STATE_IDLE, + SCSI_STATE_SELECT, + SCSI_STATE_SELECT_FAILED, + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_NEXT_PHASE, + SCSI_STATE_END_PHASE, + SCSI_STATE_READ_DATA, + SCSI_STATE_WRITE_DATA, + SCSI_STATE_READ_STATUS, + SCSI_STATE_READ_MESSAGE +} scsi_state_t; + +typedef struct scb_t +{ + uint16_t command; + uint16_t enable; + uint32_t lba_addr; + uint32_t sys_buf_addr; + uint32_t sys_buf_byte_count; + uint32_t term_status_block_addr; + uint32_t scb_chain_addr; + uint16_t block_count; + uint16_t block_length; +} scb_t; + +typedef struct scsi_ibm_t +{ + rom_t bios_rom; + + uint8_t pos_regs[8]; + + uint8_t basic_ctrl; + uint32_t command; + + uint8_t attention; + uint8_t attention_pending; + int attention_waiting; + + uint8_t cir[4]; + uint8_t cir_pending[4]; + + uint8_t irq_status; + + uint32_t scb_addr; + + uint8_t status; + + int in_invalid; + int in_reset; + sbc_state_t scb_state; + + scb_t scb; + int scb_id; + + int cmd_status; + int cir_status; + + uint8_t pacing; + + uint8_t buf[0x600]; + + uint8_t int_buffer[512]; + + struct + { + int phys_id; + int lun_id; + } dev_id[16]; + + struct + { + int idx, len; + uint8_t data[256]; + + int data_idx, data_len; + uint32_t data_pointer; + + uint8_t last_status; + + int bytes_transferred; + + int target_id; + } cdb; + + int irq_requests[16]; + + int cmd_timer; + pc_timer_t callback_timer; + + scsi_state_t scsi_state; + scsi_bus_t bus; +} scsi_ibm_t; + +#define CTRL_RESET (1 << 7) +#define CTRL_DMA_ENA (1 << 1) +#define CTRL_IRQ_ENA (1 << 0) + +#define STATUS_CMD_FULL (1 << 3) +#define STATUS_CMD_EMPTY (1 << 2) +#define STATUS_IRQ (1 << 1) +#define STATUS_BUSY (1 << 0) + +#define ENABLE_PT (1 << 12) + +#define CMD_MASK 0xff3f +#define CMD_ASSIGN 0x040e +#define CMD_DEVICE_INQUIRY 0x1c0b +#define CMD_DMA_PACING_CONTROL 0x040d +#define CMD_FEATURE_CONTROL 0x040c +#define CMD_GET_POS_INFO 0x1c0a +#define CMD_INVALID_412 0x0412 +#define CMD_GET_COMPLETE_STATUS 0x1c07 +#define CMD_READ_DATA 0x1c01 +#define CMD_READ_DEVICE_CAPACITY 0x1c09 +#define CMD_REQUEST_SENSE 0x1c08 +#define CMD_RESET 0x0400 +#define CMD_SEND_OTHER_SCSI 0x241f +#define CMD_UNKNOWN_1c10 0x1c10 +#define CMD_UNKNOWN_1c11 0x1c11 +#define CMD_WRITE_DATA 0x1c02 +#define CMD_VERIFY 0x1c03 + +#define IRQ_TYPE_NONE 0x0 +#define IRQ_TYPE_SCB_COMPLETE 0x1 +#define IRQ_TYPE_SCB_COMPLETE_RETRY 0x5 +#define IRQ_TYPE_ADAPTER_HW_FAILURE 0x7 +#define IRQ_TYPE_IMM_CMD_COMPLETE 0xa +#define IRQ_TYPE_COMMAND_FAIL 0xc +#define IRQ_TYPE_COMMAND_ERROR 0xe +#define IRQ_TYPE_SW_SEQ_ERROR 0xf +#define IRQ_TYPE_RESET_COMPLETE 0x10 + +static void scsi_rethink_irqs(scsi_ibm_t *scsi) +{ + int irq_pending = 0; + int c; + +/* pclog("scsi_rethink_irqs: basic_ctrl=%02x status=%02x\n", scsi->basic_ctrl, scsi->irq_status); + pclog(" "); + for (c = 0; c < 16; c++) + pclog(" %02x", scsi->irq_requests[c]); + pclog("\n");*/ + + if (!scsi->irq_status) + { + for (c = 0; c < 16; c++) + { + if (scsi->irq_requests[c] != IRQ_TYPE_NONE) + { +// pclog(" Found IRQ on %i\n", c); + /*Found IRQ*/ + scsi->irq_status = c | (scsi->irq_requests[c] << 4); + scsi->status |= STATUS_IRQ; + irq_pending = 1; + break; + } + } + } + else + irq_pending = 1; + + if (scsi->basic_ctrl & CTRL_IRQ_ENA) + { + if (irq_pending) + { + picintlevel(1 << 14); +// pclog(" SCSI assert INT\n"); + } + else + { + /*No IRQs pending, clear IRQ state*/ + scsi->irq_status = 0; + scsi->status &= ~STATUS_IRQ; + picintc(1 << 14); +// pclog(" SCSI clear INT - no IRQ\n"); + } + } + else + { + picintc(1 << 14); +// pclog(" SCSI clear INT - IRQs disabled\n"); + } +} + +static inline void scsi_ibm_set_irq(scsi_ibm_t *scsi, int id, int type) +{ +// pclog("scsi_ibm_set_irq id=%i type=%x %02x\n", id, type, scsi->irq_status); + scsi->irq_requests[id] = type; + if (!scsi->irq_status) /*Don't change IRQ status if one is currently being processed*/ + scsi_rethink_irqs(scsi); +} +static inline void scsi_clear_irq(scsi_ibm_t *scsi, int id) +{ + scsi->irq_requests[id] = IRQ_TYPE_NONE; + scsi_rethink_irqs(scsi); +} + +static uint8_t scsi_read(uint16_t port, void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + uint8_t temp = 0xff; + + switch (port & 7) + { + case 0: case 1: case 2: case 3: /*Command Interface Register*/ + temp = scsi->cir_pending[port & 3]; + break; + + case 4: /*Attention Register*/ + temp = scsi->attention_pending; + break; + case 5: /*Basic Control Register*/ + temp = scsi->basic_ctrl; + break; + case 6: /*IRQ status*/ + temp = scsi->irq_status; + break; + case 7: /*Status*/ + temp = scsi->status; + if (scsi->cir_status == 0) + temp |= STATUS_CMD_EMPTY; + if (scsi->cir_status == 3) + temp |= STATUS_CMD_FULL; + break; + } + +// pclog("scsi_read: port=%04x val=%02x %04x(%05x):%04x %i %02x\n", port, temp,CS,cs,cpu_state.pc, 0/*scsi->callback*/, BH); + return temp; +} + +static void scsi_write(uint16_t port, uint8_t val, void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + +// pclog("scsi_write: port=%04x val=%02x %04x:%04x\n", port, val,CS,cpu_state.pc); + + switch (port & 7) + { + case 0: case 1: case 2: case 3: /*Command Interface Register*/ + scsi->cir_pending[port & 3] = val; + if (port & 2) + scsi->cir_status |= 2; + else + scsi->cir_status |= 1; + break; + + case 4: /*Attention Register*/ + scsi->attention_pending = val; + scsi->attention_waiting = 2; + scsi->status |= STATUS_BUSY; + break; + + case 5: /*Basic Control Register*/ + if ((scsi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) + { +// pclog("SCSI reset\n"); + scsi->in_reset = 1; + scsi->cmd_timer = SCSI_TIME*2; + scsi->status |= STATUS_BUSY; + } + scsi->basic_ctrl = val; + scsi_rethink_irqs(scsi); + break; + +// default: +// fatal("scsi_write port=%04x val=%02x\n", port, val); + } +} + +static uint16_t scsi_readw(uint16_t port, void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + uint16_t temp = 0xffff; + + switch (port & 7) + { + case 0: /*Command Interface Register*/ + temp = scsi->cir_pending[0] | (scsi->cir_pending[1] << 8); + break; + case 2: /*Command Interface Register*/ + temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); + break; + +// default: +// fatal("scsi_readw port=%04x\n", port); + } + +// pclog("scsi_readw: port=%04x val=%04x\n", port, temp); + return temp; +} + +static void scsi_writew(uint16_t port, uint16_t val, void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + + switch (port & 7) + { + case 0: /*Command Interface Register*/ + scsi->cir_pending[0] = val & 0xff; + scsi->cir_pending[1] = val >> 8; + scsi->cir_status |= 1; + break; + case 2: /*Command Interface Register*/ + scsi->cir_pending[2] = val & 0xff; + scsi->cir_pending[3] = val >> 8; + scsi->cir_status |= 2; + break; + +// default: +// fatal("scsi_writew port=%04x val=%04x\n", port, val); + } + +// pclog("scsi_writew: port=%04x val=%04x\n", port, val); +} + +static void sg_fetch_next(scsi_ibm_t *scsi) +{ + if (scsi->scb.sys_buf_byte_count > 0) + { + scsi->cdb.data_idx = 0; + scsi->cdb.data_pointer = mem_readl_phys(scsi->scb.sys_buf_addr); + scsi->cdb.data_len = mem_readl_phys(scsi->scb.sys_buf_addr + 4); +// pclog("SG list: from %08x addr=%08x len=%08x\n", scsi->scb.sys_buf_addr, scsi->cdb.data_pointer, scsi->cdb.data_len); + scsi->scb.sys_buf_addr += 8; + scsi->scb.sys_buf_byte_count -= 8; + } +} + +static void process_ibm_cmd(void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scb_t *scb = &scsi->scb; + int c; + int old_scb_state; + +// pclog("scsi_callback: in_reset=%i command=%x\n", scsi->in_reset, scsi->command); + if (scsi->in_reset) + { + scsi->status &= ~STATUS_BUSY; + + scsi->irq_status = 0; + for (c = 0; c < 16; c++) + scsi_clear_irq(scsi, c); + if (scsi->in_reset == 1) + { + scsi->basic_ctrl |= CTRL_IRQ_ENA; + scsi_ibm_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE); + } + else + scsi_ibm_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE); + + /*Reset device mappings*/ + for (c = 0; c < 7; c++) + { + scsi->dev_id[c].phys_id = c; + scsi->dev_id[c].lun_id = 0; + } + for (; c < 15; c++) + scsi->dev_id[c].phys_id = -1; + + scsi->in_reset = 0; +// pclog("scsi reset complete\n"); + return; + } + if (scsi->in_invalid) + { + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_ERROR); + scsi->in_invalid = 0; + return; + } + do + { + old_scb_state = scsi->scb_state; + +// pclog("scb_state=%i\n", scsi->scb_state); + switch (scsi->scb_state) + { + case SCB_STATE_IDLE: + break; + + case SCB_STATE_START: + if (scsi->dev_id[scsi->scb_id].phys_id == -1) + { + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = SCB_STATE_IDLE; + mem_writew_phys(scb->term_status_block_addr + 0x7*2, (0xe << 8) | 0); + mem_writew_phys(scb->term_status_block_addr + 0x8*2, (0xa << 8) | 0); + break; + } + + scb->command = mem_readw_phys(scsi->scb_addr); + scb->enable = mem_readw_phys(scsi->scb_addr + 0x02); + scb->lba_addr = mem_readl_phys(scsi->scb_addr + 0x04); + scb->sys_buf_addr = mem_readl_phys(scsi->scb_addr + 0x08); + scb->sys_buf_byte_count = mem_readl_phys(scsi->scb_addr + 0x0c); + scb->term_status_block_addr = mem_readl_phys(scsi->scb_addr + 0x10); + scb->scb_chain_addr = mem_readl_phys(scsi->scb_addr + 0x14); + scb->block_count = mem_readw_phys(scsi->scb_addr + 0x18); + scb->block_length = mem_readw_phys(scsi->scb_addr + 0x1a); + +/* pclog("SCB : \n" + " Command = %04x\n" + " Enable = %04x\n" + " LBA addr = %08x\n" + " System buffer addr = %08x\n" + " System buffer byte count = %08x\n" + " Terminate status block addr = %08x\n" + " SCB chain address = %08x\n" + " Block count = %04x\n" + " Block length = %04x\n", + scb->command, scb->enable, scb->lba_addr, + scb->sys_buf_addr, scb->sys_buf_byte_count, + scb->term_status_block_addr, scb->scb_chain_addr, + scb->block_count, scb->block_length);*/ + + if (scb->enable & ENABLE_PT) + sg_fetch_next(scsi); + else + { + scsi->cdb.data_idx = 0; + scsi->cdb.data_pointer = scb->sys_buf_addr; + scsi->cdb.data_len = scb->sys_buf_byte_count; + } + + switch (scb->command & CMD_MASK) + { + case CMD_GET_COMPLETE_STATUS: + mem_writew_phys(scb->sys_buf_addr + 0x0*2, 0x201); /*SCB status*/ + mem_writew_phys(scb->sys_buf_addr + 0x1*2, 0); /*Retry counts*/ + mem_writel_phys(scb->sys_buf_addr + 0x2*2, 0); /*Residual byte count*/ + mem_writel_phys(scb->sys_buf_addr + 0x4*2, 0); /*Scatter/gather list element address*/ + mem_writew_phys(scb->sys_buf_addr + 0x6*2, 0xc); /*Device dependent status length*/ + mem_writew_phys(scb->sys_buf_addr + 0x7*2, scsi->cmd_status << 8); + mem_writew_phys(scb->sys_buf_addr + 0x8*2, 0); /*Error*/ + mem_writew_phys(scb->sys_buf_addr + 0x9*2, 0); /*Reserved*/ + mem_writew_phys(scb->sys_buf_addr + 0xa*2, 0); /*Cache information status*/ + mem_writel_phys(scb->sys_buf_addr + 0xb*2, scsi->scb_addr); + scsi->scb_state = SCB_STATE_COMPLETE; + break; + + case CMD_UNKNOWN_1c10: + for (c = 0; c < 0x600 && c < scb->sys_buf_byte_count; c++) + scsi->buf[c] = mem_readb_phys(scb->sys_buf_addr + c); + scsi->scb_state = SCB_STATE_COMPLETE; + break; + case CMD_UNKNOWN_1c11: + for (c = 0; c < 0x600 && c < scb->sys_buf_byte_count; c++) + mem_writeb_phys(scb->sys_buf_addr + c, scsi->buf[c]); + scsi->scb_state = SCB_STATE_COMPLETE; + break; + + case CMD_GET_POS_INFO: + mem_writew_phys(scb->sys_buf_addr + 0x0*2, 0x8eff); + mem_writew_phys(scb->sys_buf_addr + 0x1*2, scsi->pos_regs[3] | (scsi->pos_regs[2] << 8)); + mem_writew_phys(scb->sys_buf_addr + 0x2*2, 0x0e | (scsi->pos_regs[4] << 8)); + mem_writew_phys(scb->sys_buf_addr + 0x3*2, 1 << 12); + mem_writew_phys(scb->sys_buf_addr + 0x4*2, (7 << 8) | 8); + mem_writew_phys(scb->sys_buf_addr + 0x5*2, (16 << 8) | scsi->pacing); + mem_writew_phys(scb->sys_buf_addr + 0x6*2, (30 << 8) | 1); + mem_writew_phys(scb->sys_buf_addr + 0x7*2, 0); + mem_writew_phys(scb->sys_buf_addr + 0x8*2, 0); + scsi->scb_state = SCB_STATE_COMPLETE; + break; + + case CMD_DEVICE_INQUIRY: + scsi->cdb.data[0] = SCSI_INQUIRY; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = 0; /*Page code*/ + scsi->cdb.data[3] = 0; + scsi->cdb.data[4] = scb->sys_buf_byte_count; /*Allocation length*/ + scsi->cdb.data[5] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 6; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->cdb.data_pointer = scb->sys_buf_addr; + scsi->cdb.data_idx = 0; + scsi->cdb.data_len = scb->sys_buf_byte_count; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + + case CMD_SEND_OTHER_SCSI: +// pclog("SEND_OTHER_SCSI:"); + for (c = 0; c < 12; c++) + { + scsi->cdb.data[c] = mem_readb_phys(scsi->scb_addr + 0x18 + c); +// pclog(" %02x", scsi->cdb.data[c]); + } +// pclog("\n"); + scsi->cdb.data[1] = (scsi->cdb.data[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ + scsi->cdb.idx = 0; + scsi->cdb.len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; +// pclog("SEND_OTHER_SCSI: %04x\n", scb->lba_addr & 0xffff); + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + + case CMD_READ_DEVICE_CAPACITY: + scsi->cdb.data[0] = SCSI_READ_CAPACITY_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = 0; /*LBA*/ + scsi->cdb.data[3] = 0; + scsi->cdb.data[4] = 0; + scsi->cdb.data[5] = 0; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = 0; + scsi->cdb.data[8] = 0; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + + case CMD_READ_DATA: + scsi->cdb.data[0] = SCSI_READ_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb.data[5] = scb->lba_addr & 0xff; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb.data[8] = scb->block_count & 0xff; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + + case CMD_REQUEST_SENSE: + scsi->cdb.data[0] = SCSI_REQUEST_SENSE; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = 0; + scsi->cdb.data[3] = 0; + scsi->cdb.data[4] = scb->block_count & 0xff; /*Allocation length*/ + scsi->cdb.data[5] = 0; + scsi->cdb.idx = 0; + scsi->cdb.len = 6; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + + case CMD_WRITE_DATA: + scsi->cdb.data[0] = SCSI_WRITE_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb.data[5] = scb->lba_addr & 0xff; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb.data[8] = scb->block_count & 0xff; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + + case CMD_VERIFY: + scsi->cdb.data[0] = SCSI_VERIFY_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb.data[5] = scb->lba_addr & 0xff; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb.data[8] = scb->block_count & 0xff; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->cdb.data_len = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; + +#ifndef RELEASE_BUILD + default: + fatal("SCB command %04x\n", scb->command); +#endif + } + break; + + case SCB_STATE_WAIT: + if (scsi->scsi_state == SCSI_STATE_IDLE) + { + if (scsi->cdb.last_status == STATUS_GOOD) + scsi->scb_state = SCB_STATE_COMPLETE; + else if (scsi->cdb.last_status == STATUS_CHECK_CONDITION) + { + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = SCB_STATE_IDLE; + mem_writew_phys(scb->term_status_block_addr + 0x7*2, (0xc << 8) | 2); + mem_writew_phys(scb->term_status_block_addr + 0x8*2, 0x20); + mem_writew_phys(scb->term_status_block_addr + 0xb*2, scsi->scb_addr & 0xffff); + mem_writew_phys(scb->term_status_block_addr + 0xc*2, scsi->scb_addr >> 16); + } +#ifndef RELEASE_BUILD + else + fatal("SCB unknown result %02x\n", scsi->cdb.last_status); +#endif + } + else if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) + { +// pclog("SCB_STATE_WAIT SELECT_FAILED\n"); + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = SCB_STATE_IDLE; + mem_writew_phys(scb->term_status_block_addr + 0x7*2, (0xc << 8) | 2); + mem_writew_phys(scb->term_status_block_addr + 0x8*2, 0x10); + } +#ifndef RELEASE_BUILD + else + fatal("SCB_STATE_WAIT other %i\n", scsi->scsi_state); +#endif + break; + + case SCB_STATE_COMPLETE: + if (scb->enable & 1) + { + scsi->scb_state = SCB_STATE_START; + scsi->scb_addr = scb->scb_chain_addr; +// pclog("Next SCB - %08x\n", scsi->scb_addr); + } + else + { + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); + scsi->scb_state = SCB_STATE_IDLE; + } + break; + } + } while (scsi->scb_state != old_scb_state); +} + +static void process_immediate_command(scsi_ibm_t *scsi) +{ + switch (scsi->command & CMD_MASK) + { + case CMD_ASSIGN: +// pclog("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", (scsi->command >> 16) & 0xf, (scsi->command >> 20) & 7, (scsi->command >> 24) & 7); + if (((scsi->command >> 16) & 0xf) == 0xf && ((scsi->command >> 20) & 7) == 7) /*Device 15 always adapter*/ + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + else if (((scsi->command >> 16) & 0xf) == 0xf) /*Can not re-assign device 15 (always adapter)*/ + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); + else if (scsi->command & (1 << 23)) + { + scsi->dev_id[(scsi->command >> 16) & 0xf].phys_id = -1; + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + } + else if (((scsi->command >> 20) & 7) == 7) /*Can not assign adapter*/ + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); + else + { + scsi->dev_id[(scsi->command >> 16) & 0xf].phys_id = (scsi->command >> 20) & 7; + scsi->dev_id[(scsi->command >> 16) & 0xf].lun_id = (scsi->command >> 24) & 7; + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + } + break; + + case CMD_DMA_PACING_CONTROL: + scsi->pacing = scsi->cir[2]; +// pclog("Pacing control: %i\n", scsi->pacing); + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + case CMD_FEATURE_CONTROL: +// pclog("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29); + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + case CMD_INVALID_412: + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + case CMD_RESET: + if ((scsi->attention & 0xf) == 0xf) /*Adapter reset*/ + { + scsi_bus_reset(&scsi->bus); + scsi->scb_state = SCB_STATE_IDLE; + } + else /*Device reset*/ + { + } + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; + + default: + fatal("scsi_callback: Bad command %02x\n", scsi->command); + } +} + +static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) +{ + int c; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(bus); + + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) + { + if (!req_needed || (bus_state & BUS_REQ)) + return 1; + } + } + + return 0; +} + +static void process_scsi(scsi_ibm_t *scsi) +{ + int c; + int bytes_transferred = 0; + + switch (scsi->scsi_state) + { + case SCSI_STATE_IDLE: + break; + + case SCSI_STATE_SELECT: + scsi->cdb.last_status = 0; +// pclog("Select target ID %i\n", scsi->cdb.target_id); + scsi_bus_update(&scsi->bus, BUS_SEL | BUS_SETDATA(1 << scsi->cdb.target_id)); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY) || scsi->cdb.target_id > 6) + { +// pclog("STATE_SCSI_SELECT failed to select target %i\n", scsi->cdb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } + + scsi_bus_update(&scsi->bus, 0); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY)) + { +// pclog("STATE_SCSI_SELECT failed to select target %i 2\n", scsi->cdb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } + + /*Device should now be selected*/ + if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) + { +// pclog("Device failed to request command\n"); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } + + scsi->scsi_state = SCSI_STATE_SEND_COMMAND; + break; + + case SCSI_STATE_SELECT_FAILED: + break; + + case SCSI_STATE_SEND_COMMAND: + while (scsi->cdb.idx < scsi->cdb.len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int bus_out; + + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + +#ifndef RELEASE_BUILD + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + fatal("SEND_COMMAND - bus phase incorrect\n"); +#endif + if (bus_state & BUS_REQ) + break; + } + if (c == 20) + { +// pclog("SEND_COMMAND timed out\n"); + break; + } + + bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); +// pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len); + scsi->cdb.idx++; + bytes_transferred++; + + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + } + if (scsi->cdb.idx == scsi->cdb.len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + + case SCSI_STATE_NEXT_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); +#ifndef RELEASE_BUILD + if (!(bus_state & BUS_BSY)) + fatal("NEXT_PHASE - dropped BSY waiting\n"); +#endif + if (bus_state & BUS_REQ) + { + int bus_out; +// pclog("SCSI next phase - %x\n", bus_state); + switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) + { + case 0: +// pclog("Move to write data\n"); + scsi->scsi_state = SCSI_STATE_WRITE_DATA; + break; + + case BUS_IO: +// pclog("Move to read data\n"); + scsi->scsi_state = SCSI_STATE_READ_DATA; + break; + + case (BUS_CD | BUS_IO): +// pclog("Move to read status\n"); + scsi->scsi_state = SCSI_STATE_READ_STATUS; + break; + + case (BUS_CD | BUS_IO | BUS_MSG): +// pclog("Move to read message\n"); + scsi->scsi_state = SCSI_STATE_READ_MESSAGE; + break; + + case BUS_CD: + bus_out = BUS_SETDATA(0); + + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + +#ifndef RELEASE_BUILD + default: + fatal(" Bad new phase %x\n", bus_state); +#endif + } + break; + } + } + break; + + case SCSI_STATE_END_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); + + if (!(bus_state & BUS_BSY)) + { +// pclog("END_PHASE - dropped BSY waiting\n"); +// if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) +// fatal("No sense data\n"); + scsi->scsi_state = SCSI_STATE_IDLE; +// pclog("End of command\n"); + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } +#ifndef RELEASE_BUILD + if (bus_state & BUS_REQ) + fatal("END_PHASE - unexpected REQ\n"); +#endif + } + break; + + case SCSI_STATE_READ_DATA: + while (scsi->scsi_state == SCSI_STATE_READ_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int d; + + for (d = 0; d < 20; d++) + { + int bus_state = scsi_bus_read(&scsi->bus); +#ifndef RELEASE_BUILD + if (!(bus_state & BUS_BSY)) + fatal("READ_DATA - dropped BSY waiting\n"); +#endif + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) + { +// pclog("READ_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t data = BUS_GETDATA(bus_state); + int bus_out = 0; + + if (scsi->cdb.data_idx < scsi->cdb.data_len) + { + if (scsi->cdb.data_pointer == -1) + scsi->int_buffer[scsi->cdb.data_idx] = data; + else + mem_writeb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx, data); + scsi->cdb.data_idx++; + + if ((scsi->scb.enable & ENABLE_PT) && scsi->cdb.data_idx == scsi->cdb.data_len) + sg_fetch_next(scsi); + } + scsi->cdb.bytes_transferred++; + +// pclog("Read data %02x %i %06x\n", data, scsi->cdb.data_idx, scsi->cdb.data_pointer + scsi->cdb.data_idx); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } + + bytes_transferred++; + } + break; + + case SCSI_STATE_WRITE_DATA: + while (scsi->scsi_state == SCSI_STATE_WRITE_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) + { + int d; + + for (d = 0; d < 20; d++) + { + int bus_state = scsi_bus_read(&scsi->bus); +#ifndef RELEASE_BUILD + if (!(bus_state & BUS_BSY)) + fatal("WRITE_DATA - dropped BSY waiting\n"); +#endif + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) + { +// pclog("WRITE_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t data;// = BUS_GETDATA(bus_state); + int bus_out; + + if (scsi->cdb.data_idx < scsi->cdb.data_len) + { + if (scsi->cdb.data_pointer == -1) + data = scsi->int_buffer[scsi->cdb.data_idx]; + else + data = mem_readb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx); + + scsi->cdb.data_idx++; + if ((scsi->scb.enable & ENABLE_PT) && scsi->cdb.data_idx == scsi->cdb.data_len) + sg_fetch_next(scsi); + } + else + data = 0xff; + scsi->cdb.bytes_transferred++; + +// pclog("Write data %02x %i\n", data, scsi->cdb.data_idx); + bus_out = BUS_SETDATA(data); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } + + bytes_transferred++; + } +// if (scsi->cdb.data_idx == scsi->cdb.data_len) +// scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + + case SCSI_STATE_READ_STATUS: + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); +#ifndef RELEASE_BUILD + if (!(bus_state & BUS_BSY)) + fatal("READ_STATUS - dropped BSY waiting\n"); +#endif + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) + { +// pclog("READ_STATUS - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t status = BUS_GETDATA(bus_state); + int bus_out = 0; + +// pclog("Read status %02x\n", status); + scsi->cdb.last_status = status; + + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + } + break; + + case SCSI_STATE_READ_MESSAGE: + for (c = 0; c < 20; c++) + { + int bus_state = scsi_bus_read(&scsi->bus); +#ifndef RELEASE_BUILD + if (!(bus_state & BUS_BSY)) + fatal("READ_MESSAGE - dropped BSY waiting\n"); +#endif + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) + { +// pclog("READ_MESSAGE - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + + if (bus_state & BUS_REQ) + { + uint8_t msg = BUS_GETDATA(bus_state); + int bus_out = 0; + +// pclog("Read message %02x\n", msg); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + + switch (msg) + { + case MSG_COMMAND_COMPLETE: + scsi->scsi_state = SCSI_STATE_END_PHASE; + break; +#ifndef RELEASE_BUILD + default: + fatal("READ_MESSAGE - unknown message %02x\n", msg); +#endif + } + break; + } + } + break; + +#ifndef RELEASE_BUILD + default: + fatal("Unknown SCSI_state %d\n", scsi->scsi_state); +#endif + } +} + +static void scsi_callback(void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + + timer_advance_u64(&scsi->callback_timer, POLL_TIME); + +// pclog("poll %i\n", scsi->cmd_state); + if (scsi->cmd_timer) + { + scsi->cmd_timer--; + if (!scsi->cmd_timer) + process_ibm_cmd(scsi); + } + if (scsi->attention_waiting && + (scsi->scb_state == SCB_STATE_IDLE || (scsi->attention_pending & 0xf0) == 0xe0)) + { + scsi->attention_waiting--; + if (!scsi->attention_waiting) + { +// pclog("Process attention request\n"); + scsi->attention = scsi->attention_pending; + scsi->status &= ~STATUS_BUSY; + scsi->cir[0] = scsi->cir_pending[0]; + scsi->cir[1] = scsi->cir_pending[1]; + scsi->cir[2] = scsi->cir_pending[2]; + scsi->cir[3] = scsi->cir_pending[3]; + scsi->cir_status = 0; + + switch (scsi->attention >> 4) + { + case 0x1: /*Immediate command*/ + scsi->cmd_status = 0xa; + scsi->command = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + switch (scsi->command & CMD_MASK) + { + case CMD_ASSIGN: + case CMD_DMA_PACING_CONTROL: + case CMD_FEATURE_CONTROL: + case CMD_INVALID_412: + case CMD_RESET: + process_immediate_command(scsi); + break; + +#ifndef RELEASE_BUILD + default: + fatal("Unknown immediate command %08x\n", scsi->command); +#endif + } + break; + + case 0x3: case 0x4: case 0xf: /*Start SCB*/ + scsi->cmd_status = 0x1; + scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + scsi->scb_state = SCB_STATE_START; + scsi->scb_id = scsi->attention & 0xf; + scsi->cmd_timer = SCSI_TIME*2; +// pclog("Start SCB at %08x\n", scsi->scb_addr); + break; + + case 5: /*Invalid*/ + case 0xa: /*Invalid*/ + scsi->in_invalid = 1; + scsi->cmd_timer = SCSI_TIME*2; + break; + + case 0xe: /*EOI*/ + scsi->irq_status = 0; + scsi_clear_irq(scsi, scsi->attention & 0xf); + break; +#ifndef RELEASE_BUILD + default: + fatal("Attention Register 5 %02x\n", scsi->attention); +#endif + } + } + } + process_scsi(scsi); +} + +static uint8_t scsi_ibm_mca_read(int port, void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + +// pclog("scsi_mca_read: port=%04x %02x %04x:%04x\n", port, scsi->pos_regs[port & 7], CS,cpu_state.pc); + + return scsi->pos_regs[port & 7]; +} + +static void scsi_ibm_mca_write(int port, uint8_t val, void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + + if (port < 0x102) + return; + +// pclog("scsi_mca_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); + + io_removehandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, scsi_read, scsi_readw, NULL, scsi_write, scsi_writew, NULL, scsi); + mem_mapping_disable(&scsi->bios_rom.mapping); + + scsi->pos_regs[port & 7] = val; + + if (scsi->pos_regs[2] & 1) + { +// pclog(" scsi io = %04x\n", (((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540); + io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, scsi_read, scsi_readw, NULL, scsi_write, scsi_writew, NULL, scsi); + if ((scsi->pos_regs[2] & 0xf0) != 0xf0) + { + mem_mapping_enable(&scsi->bios_rom.mapping); + mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); +// pclog("SCSI BIOS ROM at %05x %02x\n", ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, scsi->pos_regs[2]); + } + } +} + +static void scsi_ibm_reset(void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + +// pclog("scsi_ibm_reset\n"); + scsi->in_reset = 2; + scsi->cmd_timer = SCSI_TIME * 50; + scsi->status = STATUS_BUSY; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->scb_state = SCB_STATE_IDLE; + scsi->in_invalid = 0; + scsi->attention_waiting = 0; + scsi->basic_ctrl = 0; + scsi_bus_reset(&scsi->bus); +} + +static void *scsi_ibm_init() +{ + int c; + scsi_ibm_t *scsi = malloc(sizeof(scsi_ibm_t)); + memset(scsi, 0, sizeof(scsi_ibm_t)); + + rom_init_interleaved(&scsi->bios_rom, "92F2244.U68", "92F2245.U69", 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&scsi->bios_rom.mapping); + + timer_add(&scsi->callback_timer, scsi_callback, scsi, 1); + + mca_add(scsi_ibm_mca_read, scsi_ibm_mca_write, scsi_ibm_reset, scsi); + + scsi->pos_regs[0] = 0xff; + scsi->pos_regs[1] = 0x8e; + + scsi->in_reset = 2; + scsi->cmd_timer = SCSI_TIME * 50; + scsi->status = STATUS_BUSY; + + scsi_bus_init(&scsi->bus); + +/* for (c = 0; c < 7; c++) + { + scsi->dev_id[c].phys_id = c; + scsi->dev_id[c].lun_id = 0; + }*/ + for (c = 0; c < 15; c++) + scsi->dev_id[c].phys_id = -1; + scsi->dev_id[15].phys_id = 7; + + return scsi; +} + +static void scsi_ibm_close(void *p) +{ + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + + free(scsi); +} + +static int scsi_ibm_available() +{ + return rom_present("92F2244.U68") && rom_present("92F2245.U69"); +} + +device_t scsi_ibm_device = +{ + "IBM SCSI Adapter with Cache (MCA)", + DEVICE_MCA, + scsi_ibm_init, + scsi_ibm_close, + scsi_ibm_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/scsi_ibm.h b/src/scsi_ibm.h new file mode 100644 index 0000000..b528486 --- /dev/null +++ b/src/scsi_ibm.h @@ -0,0 +1 @@ +extern device_t scsi_ibm_device; From 53291432e8b112932829bceb3f9a21a3000a8761 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 Feb 2020 14:04:31 +0000 Subject: [PATCH 0785/1050] Add CD-ROM drive model configuration. Patch from EluanCM. --- src/pc.c | 2 + src/pc.xrc | 37 ++++++++- src/scsi_cd.c | 161 ++++++++++++++++++++++++++++++++++++--- src/scsi_cd.h | 16 ++++ src/wx-config.c | 110 +++++++++++++++++++++++++-- src/wx-resources.cpp | 176 ++++++++++++++++++++++++++++++------------- 6 files changed, 435 insertions(+), 67 deletions(-) diff --git a/src/pc.c b/src/pc.c index f867092..93f9f2b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -808,6 +808,7 @@ void loadconfig(char *fn) bpb_disable = config_get_int(CFG_MACHINE, NULL, "bpb_disable", 0); cd_speed = config_get_int(CFG_MACHINE, NULL, "cd_speed", 24); + cd_model = cd_model_from_config((char *)config_get_string(CFG_MACHINE, NULL, "cd_model", cd_get_config_model(0))); joystick_type = config_get_int(CFG_MACHINE, NULL, "joystick_type", 0); mouse_type = config_get_int(CFG_MACHINE, NULL, "mouse_type", 0); @@ -955,6 +956,7 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "bpb_disable", bpb_disable); config_set_int(CFG_MACHINE, NULL, "cd_speed", cd_speed); + config_set_string(CFG_MACHINE, NULL, "cd_model", cd_model_to_config(cd_model)); config_set_int(CFG_MACHINE, NULL, "joystick_type", joystick_type); config_set_int(CFG_MACHINE, NULL, "mouse_type", mouse_type); diff --git a/src/pc.xrc b/src/pc.xrc index cbc4b59..9db0ca0 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -1181,7 +1181,42 @@ 5 80,-1 - + + -1 + + + + + wxEXPAND + 5 + + wxHORIZONTAL + + + wxALL + 5 + + + 350,-1 + + + + + + + + + wxEXPAND + 5 + 0,0 + + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + 80,-1 + -1 diff --git a/src/scsi_cd.c b/src/scsi_cd.c index a4fe299..5a56550 100644 --- a/src/scsi_cd.c +++ b/src/scsi_cd.c @@ -204,6 +204,8 @@ typedef struct scsi_cd_data_t int short_seek, long_seek; int max_speed, cur_speed; + + int cur_model; } scsi_cd_data_t; static scsi_cd_data_t *cd_data = NULL; @@ -266,6 +268,146 @@ void cd_set_speed(int speed) } } +static struct +{ + // suffix numbers are sizes from the specs + char *vendor_8; + char *model_and_firmware_40; + char *serial_20; + char *model_16; + char *firmware_4; + + char *serial2_20; + char *firmware2_8; + char *model2_40; + + // for PCem config only + char *model_string_40; + char *model_config_string_40; + int interfaces; + int speed; // Not an index, but a "speed" value. -1 == allow override +} const cd_models[] = +{ + { + // Generic PCem CD + "PCem", + "PCemCD v1.0", + "53R141", + "PCemCD", + "1.0", + + "", + "v1.0", + "PCemCD", + "PCemCD", + "pcemcd", + CD_MODEL_INTERFACE_ALL, + -1, + }, + { + // A 4x CD-ROM drive from Aztech. Choose if your system image has the SGIDECD.SYS driver + "AZT", + "AZT 46802I v1.15", + "53R141", // TODO: clone serial from my real one + "46802I", + "1.15", + + "", + "v1.15", + "CDA46802I", + "AZT CDA 468-02I 4X", + "azt_cda_468_02i_4x", + CD_MODEL_INTERFACE_IDE, + 4, + }, +}; + +char *cd_model = NULL; + +char *cd_get_model(int i) +{ + return cd_models[i].model_string_40; +} + +char *cd_get_config_model(int i) +{ + return cd_models[i].model_config_string_40; +} + +void cd_set_model(char *model) +{ + if (cd_data) + { + int c = 0; + + while (1) + { + if (!model) + break; + if (c > MAX_CD_MODEL) + break; + if (!strncmp(cd_models[c].model_string_40, model, 40)) + break; + + c++; + } + + cd_data->cur_model = c; + } +} + +int cd_get_model_interfaces(int i) +{ + return cd_models[i].interfaces; +} + +int cd_get_model_speed(int i) +{ + return cd_models[i].speed; +} + +char *cd_model_to_config(char *model) +{ + int c = 0; + + while (1) + { + if (!model) + break; + if (c > MAX_CD_MODEL) + { + c = 0; // default + break; + } + if (!strncmp(cd_models[c].model_string_40, model, 40)) + break; + + c++; + } + return cd_models[c].model_config_string_40; +} + +char *cd_model_from_config(char *config) +{ + int c = 0; + + while (1) + { + if (!config) + break; + if (c > MAX_CD_MODEL) + { + c = 0; // default + break; + } + if (!strncmp(cd_models[c].model_config_string_40, config, 40)) + break; + + c++; + } + return cd_models[c].model_string_40; +} + static void scsi_cd_callback(void *p) { scsi_cd_data_t *data = p; @@ -398,6 +540,7 @@ static void *scsi_cd_init(scsi_bus_t *bus, int id) cd_data = data; cd_set_speed(cd_speed); + cd_set_model(cd_model); return data; } @@ -1299,11 +1442,11 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[idx++] = 0x01; data->data_in[idx++] = 0x00; data->data_in[idx++] = 68; - ide_padstr8(data->data_in + idx, 8, "PCem"); /* Vendor */ + ide_padstr8(data->data_in + idx, 8, cd_models[cd_data->cur_model].vendor_8); /* Vendor */ idx += 8; - ide_padstr8(data->data_in + idx, 40, "PCemCD v1.0"); /* Product */ + ide_padstr8(data->data_in + idx, 40, cd_models[cd_data->cur_model].model_and_firmware_40); /* Product */ idx += 40; - ide_padstr8(data->data_in + idx, 20, "53R141"); /* Product */ + ide_padstr8(data->data_in + idx, 20, cd_models[cd_data->cur_model].serial_20); /* Product */ idx += 20; break; @@ -1334,9 +1477,9 @@ static int scsi_cd_command(uint8_t *cdb, void *p) data->data_in[6] = 0; data->data_in[7] = 0; - ide_padstr8(data->data_in + 8, 8, "PCem"); /* Vendor */ - ide_padstr8(data->data_in + 16, 16, "PCemCD"); /* Product */ - ide_padstr8(data->data_in + 32, 4, "1.0"); /* Revision */ + ide_padstr8(data->data_in + 8, 8, cd_models[cd_data->cur_model].vendor_8); /* Vendor */ + ide_padstr8(data->data_in + 16, 16, cd_models[cd_data->cur_model].model_16); /* Product */ + ide_padstr8(data->data_in + 32, 4, cd_models[cd_data->cur_model].firmware_4); /* Revision */ idx = 36; } @@ -1488,9 +1631,9 @@ static void scsi_cd_atapi_identify(uint16_t *buffer, void *p) memset(buffer, 0, 512); buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *)(buffer + 23), "v1.0", 8); /* Firmware */ - ide_padstr((char *)(buffer + 27), "PCemCD", 40); /* Model */ + ide_padstr((char *)(buffer + 10), cd_models[cd_data->cur_model].serial2_20, 20); /* Serial Number */ + ide_padstr((char *)(buffer + 23), cd_models[cd_data->cur_model].firmware2_8, 8); /* Firmware */ + ide_padstr((char *)(buffer + 27), cd_models[cd_data->cur_model].model2_40, 40); /* Model */ buffer[49] = 0x300; /*DMA and LBA supported*/ buffer[51] = 120; buffer[52] = 120; diff --git a/src/scsi_cd.h b/src/scsi_cd.h index dc86826..5b3f701 100644 --- a/src/scsi_cd.h +++ b/src/scsi_cd.h @@ -5,3 +5,19 @@ int cd_get_speed(int i); void cd_set_speed(int speed); extern int cd_speed; + +#define MAX_CD_MODEL 1 + +#define CD_MODEL_INTERFACE_ALL 0 // even when controller is not IDE and not SCSI (to always have the PCemCD model as default, even when not selectable) +#define CD_MODEL_INTERFACE_IDE 1 +#define CD_MODEL_INTERFACE_SCSI 2 + +char *cd_get_model(int i); +char *cd_get_config_model(int i); +void cd_set_model(char *model); +int cd_get_model_interfaces(int i); +int cd_get_model_speed(int i); +char *cd_model_to_config(char *model); +char *cd_model_from_config(char *config); + +extern char *cd_model; diff --git a/src/wx-config.c b/src/wx-config.c index cd24749..aa89a5c 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -50,6 +50,8 @@ extern void deviceconfig_open(void* hwnd, device_t *device); extern int hdconf_init(void* hdlg); extern int hdconf_update(void* hdlg); +static int hdd_controller_selected_is_ide(void* hdlg); +static int hdd_controller_selected_is_scsi(void* hdlg); static int hdd_controller_selected_has_config(void *hdlg); static device_t *hdd_controller_selected_get_device(void *hdlg); @@ -360,12 +362,64 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for } } -static void recalc_cd_list(void *hdlg, int cur_speed) +// TODO: split this into model/speed recalcs? +static void recalc_cd_list(void *hdlg, int cur_speed, char *cur_model) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + int temp_model = -1; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); int c = 0; - + int found = 0; + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + if (hdd_controller_selected_is_ide(hdlg) || hdd_controller_selected_is_scsi(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + while (1) + { + char s[40]; + char *model; + + if ((cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_ALL) || + (cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_IDE && hdd_controller_selected_is_ide(hdlg)) || + (cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_SCSI && hdd_controller_selected_is_scsi(hdlg))) + { + + model = cd_get_model(c); + sprintf(s, "%s", model); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + + if (!strncmp(s, cur_model, 40)) + { + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + temp_model = c; + found = 1; + } + } + + c++; + if (c > MAX_CD_MODEL) + break; + } + if (!found) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); // assume that there is always at least one TODO: is this necessary? + + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + c = 0; + found = 0; + + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + if (temp_model >= 0 && cd_get_model_speed(temp_model) != -1) + { + // this model has a specific speed + wx_enablewindow(h, FALSE); + cur_speed = cd_get_model_speed(temp_model); + } + else if (hdd_controller_selected_is_ide(hdlg) || hdd_controller_selected_is_scsi(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); while (1) { char s[8]; @@ -376,12 +430,17 @@ static void recalc_cd_list(void *hdlg, int cur_speed) wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); if (speed == cur_speed) + { wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - + found = 1; + } + c++; if (speed >= MAX_CD_SPEED) break; } + if (!found) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); // fall back TODO: is this necessary? } #ifdef USE_NETWORKING @@ -615,6 +674,10 @@ int config_dlgsave(void* hdlg) cd_speed = cd_get_speed(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); cd_set_speed(cd_speed); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + cd_model = cd_get_model(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + cd_set_model(cd_model); + if (has_been_inited) saveconfig(NULL); @@ -639,6 +702,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) int temp_dynarec; int cpu_flags; int cpu_type; + int temp_cd_model, temp_cd_speed; int temp_mouse_type; #ifdef USE_NETWORKING int temp_network_card; @@ -893,7 +957,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); } - recalc_cd_list(hdlg, cd_speed); + recalc_cd_list(hdlg, cd_speed, cd_model); #ifdef USE_NETWORKING recalc_net_list(hdlg, romstomodel[romset]); @@ -1048,6 +1112,12 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) recalc_hdd_list(hdlg, temp_model, 1, force_ide); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); + recalc_snd_list(hdlg, temp_model); #ifdef USE_NETWORKING recalc_net_list(hdlg, temp_model); @@ -1198,11 +1268,25 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; recalc_hdd_list(hdlg, temp_model, 1, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); } else if (wParam == WX_ID("IDC_CONFIGUREHDD")) { deviceconfig_open(hdlg, (void *)hdd_controller_selected_get_device(hdlg)); } + else if (wParam == WX_ID("IDC_COMBO_CDMODEL")) + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); + } #ifdef USE_NETWORKING else if (wParam == WX_ID("IDC_COMBO_NETCARD")) { @@ -1337,6 +1421,22 @@ static int hdd_controller_selected_is_mfm(void* hdlg) return hdd_controller_is_mfm(hdd_names[c]); return 0; } +static int hdd_controller_selected_is_ide(void* hdlg) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_is_ide(hdd_names[c]); + return 0; +} +static int hdd_controller_selected_is_scsi(void* hdlg) +{ + void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_is_scsi(hdd_names[c]); + return 0; +} static int hdd_controller_selected_has_config(void* hdlg) { void* h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 553b49d..6ed31ee 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 139477; +static size_t xml_res_size_26 = 141099; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -3915,58 +3915,130 @@ static unsigned char xml_res_file_26[] = { 99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, 47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,45,82,79,77, -58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, -68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, -105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, -105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, -111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,67,79, -77,66,79,95,67,68,83,80,69,69,68,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67, -66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,32,77,111,100, +101,108,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, -62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,77,66,79,95,67,68,77,79,68,69,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,68,32,83,112,101, +101,100,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, +49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67, +95,67,79,77,66,79,95,67,68,83,80,69,69,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, From c93a4eb29527fc7ee5c949864556fa07a5e3568c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Mar 2020 17:19:43 +0000 Subject: [PATCH 0786/1050] AT/IDE drive status has ready set in between sector transfers in multi-sector reads. Fixes some early AMI BIOSes. --- src/ide.c | 2 +- src/mfm_at.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ide.c b/src/ide.c index 552aa16..468a809 100644 --- a/src/ide.c +++ b/src/ide.c @@ -766,7 +766,7 @@ uint16_t readidew(int ide_board) if (ide->secount) { ide_next_sector(ide); - ide->atastat = BUSY_STAT; + ide->atastat = BUSY_STAT | READY_STAT | DSC_STAT; if (ide->command == WIN_READ_MULTIPLE) callbackide(ide_board); else diff --git a/src/mfm_at.c b/src/mfm_at.c index cccd1c9..9293f18 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -389,7 +389,7 @@ uint16_t mfm_readw(uint16_t port, void *p) if (mfm->secount) { mfm_next_sector(mfm); - mfm->status = STAT_BUSY; + mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); } } From 18cc83b28fefb131213d2d56d0f1d8fd75a5178d Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Mar 2020 17:20:23 +0000 Subject: [PATCH 0787/1050] Added ECS 386/32 emulation. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/cs8230.c | 115 +++++++++++++++++++++++++++++ src/cs8230.h | 1 + src/ibm.h | 1 + src/mem_bios.c | 13 ++++ src/model.c | 9 +++ src/nvr.c | 2 + 9 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 src/cs8230.c create mode 100644 src/cs8230.h diff --git a/src/Makefile.am b/src/Makefile.am index 7e0ab63..b074a05 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -31,7 +31,7 @@ codegen_ops_fpu_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c codegen_ops codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_helpers.c codegen_ops_jump.c \ codegen_ops_logic.c codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c \ codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c \ -codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ +codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c cs8230.c dells200.c device.c disc.c \ disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index b022645..8422b25 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -16,7 +16,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ + codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 18962a0..bcce1a5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -16,7 +16,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ - codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o device.o \ + codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o \ diff --git a/src/cs8230.c b/src/cs8230.c new file mode 100644 index 0000000..783c179 --- /dev/null +++ b/src/cs8230.c @@ -0,0 +1,115 @@ +/*CS8230 CHIPSet consists of : + 82c301 bus controller + 82c302 page/interleave memory controller + 82a303 high address buffer + 82a304 low address buffer + 82b305 data buffer + 82a306 control buffer*/ +#include "ibm.h" +#include "cs8230.h" +#include "io.h" +#include "mem.h" + +static struct +{ + int idx; + uint8_t regs[256]; +} cs8230; + +static void shadow_control(uint32_t addr, uint32_t size, int state) +{ +// pclog("shadow_control: addr=%08x size=%04x state=%02x\n", addr, size, state); + switch (state) + { + case 0x00: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x01: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x11: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + } + flushmmucache_nopc(); +} + +static void rethink_shadow_mappings(void) +{ + int c; + + for (c = 0; c < 4*8; c++) /*Addresses 40000-bffff in 16k blocks*/ + { + if (cs8230.regs[0xa + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0x40000 + c*0x4000, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /*IO channel*/ + else + mem_set_mem_state(0x40000 + c*0x4000, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /*System board*/ + } + for (c = 0; c < 2*8; c++) /*Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here*/ + { + if (cs8230.regs[0xe + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0xc0000 + c*0x4000, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /*IO channel*/ + else + shadow_control(0xc0000 + c*0x4000, 0x4000, (cs8230.regs[9] >> (3-(c >> 2))) & 0x11); + } +} + +static uint8_t cs8230_read(uint16_t port, void *p) +{ + uint8_t ret = 0xff; + + if (port & 1) + { + switch (cs8230.idx) + { + case 0x04: /*82C301 ID/version*/ + ret = cs8230.regs[cs8230.idx] & ~0xe3; + break; + + case 0x08: /*82C302 ID/Version*/ + ret = cs8230.regs[cs8230.idx] & ~0xe0; + break; + + case 0x05: case 0x06: /*82C301 registers*/ + case 0x09: case 0x0a: case 0x0b: case 0x0c: /*82C302 registers*/ + case 0x0d: case 0x0e: case 0x0f: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x28: case 0x29: case 0x2a: + ret = cs8230.regs[cs8230.idx]; + break; + } + } + + return ret; +} + +static void cs8230_write(uint16_t port, uint8_t val, void *p) +{ + if (!(port & 1)) + cs8230.idx = val; + else + { +// pclog("cs8230_write: reg=%02x val=%02x\n", cs8230.idx, val); + cs8230.regs[cs8230.idx] = val; + switch (cs8230.idx) + { + case 0x09: /*RAM/ROM Configuration in boot area*/ + case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /*Address maps*/ + rethink_shadow_mappings(); + break; + } + } +} + +void cs8230_init(void) +{ + memset(&cs8230, 0, sizeof(cs8230)); + + io_sethandler(0x0022, 0x0002, + cs8230_read, NULL, NULL, + cs8230_write, NULL, NULL, + NULL); +} diff --git a/src/cs8230.h b/src/cs8230.h new file mode 100644 index 0000000..d4bd4a0 --- /dev/null +++ b/src/cs8230.h @@ -0,0 +1 @@ +void cs8230_init(void); diff --git a/src/ibm.h b/src/ibm.h index 4d4c07d..efad69d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -254,6 +254,7 @@ enum ROM_FIC_VA503P, ROM_CBM_SL386SX25, ROM_IBMPS1_2133_451, + ROM_ECS_386_32, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 7d68fe4..59f0979 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -1023,6 +1023,19 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_ECS_386_32: + f = romfopen("ecs386_32/386_32_even.bin", "rb"); + ff = romfopen("ecs386_32/386_32_odd.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; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 38aa5d2..7570cc1 100644 --- a/src/model.c +++ b/src/model.c @@ -14,6 +14,7 @@ #include "cbm_io.h" #include "cmd640.h" #include "compaq.h" +#include "cs8230.h" #include "dells200.h" #include "device.h" #include "cassette.h" @@ -104,6 +105,7 @@ void at_scat_init(); void at_scatsx_init(); void at_acer386sx_init(); void at_wd76c10_init(); +void at_cs8230_init(); void at_ali1429_init(); void at_headland_init(); void at_opti495_init(); @@ -198,6 +200,7 @@ MODEL models[] = {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"[386DX] ECS 386/32", ROM_ECS_386_32, "ecs_386_32", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 16, 1, at_cs8230_init, NULL}, {"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, @@ -622,6 +625,12 @@ void at_opti495_init() opti495_init(); } +void at_cs8230_init() +{ + at_init(); + cs8230_init(); +} + void at_ali1429_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 140e0e9..f0bd52a 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -349,6 +349,7 @@ void loadnvr() case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); nvrmask = 127; break; case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break; + case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -449,6 +450,7 @@ void savenvr() case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); break; case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break; case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break; + case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "wb"); break; default: return; } From 11904d765a61d122ea133041057be450ac7c2b1a Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 21:57:20 +0000 Subject: [PATCH 0788/1050] FDC multi-track commands do not literally access multiple tracks. Limited read/ write data to a single track/cylinder. --- src/fdc.c | 125 +++++++++++++++++++++++------------------------------- 1 file changed, 52 insertions(+), 73 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index ca3a4fc..93c03f8 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -34,8 +34,7 @@ typedef struct FDC int format_state; int tc; int written; - int in_seek_mt; - + int pcjr, ps1; pc_timer_t watchdog_timer; @@ -860,102 +859,82 @@ void fdc_callback() discint = 0; return; case 5: /*Write data*/ - if (!fdc.in_seek_mt) + readflash_set(READFLASH_FDC, fdc.drive); + if (fdc.sector == fdc.params[5]) { - readflash_set(READFLASH_FDC, fdc.drive); - fdc.sector++; - if (fdc.sector > fdc.params[5]) + fdc.sector = 1; + if (fdc.command & 0x80) { - fdc.sector = 1; - if (fdc.command & 0x80) - { - fdc.head ^= 1; - if (!fdc.head) - { - fdc.rw_track++; - doseek = 1; - } - } - else + fdc.head ^= 1; + if (!fdc.head) { fdc.rw_track++; fdc.tc = 1; } } - if (fdc.tc) + else { - discint=-2; - fdc_int(); - fdc.stat=0xD0; - fdc.res[4]=(fdc.head?4:0)|fdc.drive; - fdc.res[5]=fdc.res[6]=0; - fdc.res[7]=fdc.rw_track; - fdc.res[8]=fdc.head; - fdc.res[9]=fdc.sector; - fdc.res[10]=fdc.params[4]; - paramstogo=7; - return; - } - if (doseek) - { - fdd_seek(fdc.drive, 1); - fdc.in_seek_mt = 1; - /*Allow seek to complete before starting next sector write*/ - return; + fdc.rw_track++; + fdc.tc = 1; } } - fdc.in_seek_mt = 0; + else + fdc.sector++; + if (fdc.tc) + { + discint=-2; + fdc_int(); + fdc.stat=0xD0; + fdc.res[4]=(fdc.head?4:0)|fdc.drive; + fdc.res[5]=fdc.res[6]=0; + fdc.res[7]=fdc.rw_track; + fdc.res[8]=fdc.head; + fdc.res[9]=fdc.sector; + fdc.res[10]=fdc.params[4]; + paramstogo=7; + return; + } disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); // ioc_fiq(IOC_FIQ_DISC_DATA); return; case 6: /*Read data*/ // rpclog("Read data %i\n", fdc.tc); - if (!fdc.in_seek_mt) + readflash_set(READFLASH_FDC, fdc.drive); + if (fdc.sector == fdc.params[5]) { - readflash_set(READFLASH_FDC, fdc.drive); - fdc.sector++; - if (fdc.sector > fdc.params[5]) + fdc.sector = 1; + if (fdc.command & 0x80) { - fdc.sector = 1; - if (fdc.command & 0x80) - { - fdc.head ^= 1; - if (!fdc.head) - { - fdc.rw_track++; - doseek = 1; - } - } - else + fdc.head ^= 1; + if (!fdc.head) { fdc.rw_track++; fdc.tc = 1; } } - if (fdc.tc) + else { - fdc.inread = 0; - discint=-2; - fdc_int(); - fdc.stat=0xD0; - fdc.res[4]=(fdc.head?4:0)|fdc.drive; - fdc.res[5]=fdc.res[6]=0; - fdc.res[7]=fdc.rw_track; - fdc.res[8]=fdc.head; - fdc.res[9]=fdc.sector; - fdc.res[10]=fdc.params[4]; - paramstogo=7; - return; - } - if (doseek) - { - fdd_seek(fdc.drive, 1); - fdc.in_seek_mt = 1; - /*Allow seek to complete before starting next sector read*/ - return; + fdc.rw_track++; + fdc.tc = 1; } } - fdc.in_seek_mt = 0; + else + fdc.sector++; + if (fdc.tc) + { + fdc.inread = 0; + discint=-2; + fdc_int(); + fdc.stat=0xD0; + fdc.res[4]=(fdc.head?4:0)|fdc.drive; + fdc.res[5]=fdc.res[6]=0; + fdc.res[7]=fdc.rw_track; + fdc.res[8]=fdc.head; + fdc.res[9]=fdc.sector; + fdc.res[10]=fdc.params[4]; + paramstogo=7; + return; + } disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); fdc.inread = 1; return; From 702d856d2c5f5727d12e45932761fe597ec897ea Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 21:57:40 +0000 Subject: [PATCH 0789/1050] Fix missing parameters on FDC dump registers command. --- src/fdc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index 93c03f8..dd5a455 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -1033,14 +1033,16 @@ void fdc_callback() return; case 0x0e: /*Dump registers*/ fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[3] = fdc.track[0]; - fdc.res[4] = fdc.track[1]; - fdc.res[5] = 0; - fdc.res[6] = 0; - 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); + fdc.res[1] = fdc.track[0]; + fdc.res[2] = fdc.track[1]; + fdc.res[3] = 0; + fdc.res[4] = 0; + 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; return; From 25fc4d438d5e8633823fce7470e888080f485cee Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 21:58:07 +0000 Subject: [PATCH 0790/1050] FDC cleanup. --- src/fdc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index dd5a455..041d0b5 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -403,8 +403,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) { fdc.tc = 0; fdc.data_ready = 0; - fdc.in_seek_mt = 0; - + fdc.command=val; // pclog("Starting FDC command %02X\n",fdc.command); switch (fdc.command&0x1F) From a51b0e97f65ad195b1cae43de7e2a812330c25a0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 21:58:34 +0000 Subject: [PATCH 0791/1050] Do not reset FDC status when write to 3F2 has bit 2 set, only when bit 2 changes. --- src/fdc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index 041d0b5..927f1ac 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -348,11 +348,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) } else { - if (val&4) - { - fdc.stat=0x80; - fdc.pnum=fdc.ptot=0; - } if ((val&4) && !(fdc.dor&4)) { timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); From 31569b8652231470734f5660cb9e63985681770b Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 22:01:15 +0000 Subject: [PATCH 0792/1050] Full FDC command decoding. Prevents unimplemented command 0x2e from succeeding due to alias with command 0x0e; this would cause a newer FDC that is actually emulated to be detected. Also allows unlock command (0x94) to execute properly. --- src/fdc.c | 74 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index 927f1ac..dc2fcc8 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -401,7 +401,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.command=val; // pclog("Starting FDC command %02X\n",fdc.command); - switch (fdc.command&0x1F) + switch (fdc.command) { case 1: /*Mode*/ if (!fdc.is_nsc) goto bad_command; @@ -412,23 +412,23 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.format_state = 0; break; - case 2: /*Read track*/ + case 0x02: case 0x42: /*Read track*/ fdc.pnum=0; fdc.ptot=8; fdc.stat=0x90; fdc.pos=0; break; - case 3: /*Specify*/ + case 0x03: /*Specify*/ fdc.pnum=0; fdc.ptot=2; fdc.stat=0x90; break; - case 4: /*Sense drive status*/ + case 0x04: /*Sense drive status*/ fdc.pnum=0; fdc.ptot=1; fdc.stat=0x90; break; - case 5: /*Write data*/ + case 0x05: case 0x45: case 0x85: case 0xc5: /*Write data*/ // printf("Write data!\n"); fdc.pnum=0; fdc.ptot=8; @@ -436,18 +436,19 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.pos=0; // readflash=1; break; - case 6: /*Read data*/ + case 0x06: case 0x26: case 0x46: case 0x66: /*Read data*/ + case 0x86: case 0xa6: case 0xc6: case 0xe6: fdc.pnum=0; fdc.ptot=8; fdc.stat=0x90; fdc.pos=0; break; - case 7: /*Recalibrate*/ + case 0x07: /*Recalibrate*/ fdc.pnum=0; fdc.ptot=1; fdc.stat=0x90; break; - case 8: /*Sense interrupt status*/ + case 0x08: /*Sense interrupt status*/ if (fdc.int_pending || fdc_reset_stat) { // printf("Sense interrupt status %i\n",curdrive); @@ -464,20 +465,20 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); } break; - case 10: /*Read sector ID*/ + case 0x0a: case 0x4a: /*Read sector ID*/ fdc.pnum=0; fdc.ptot=1; fdc.stat=0x90; fdc.pos=0; break; - case 0x0d: /*Format track*/ + case 0x0d: case 0x4d: /*Format track*/ fdc.pnum=0; fdc.ptot=5; fdc.stat=0x90; fdc.pos=0; fdc.format_state = 0; break; - case 15: /*Seek*/ + case 0x0f: /*Seek*/ fdc.pnum=0; fdc.ptot=2; fdc.stat=0x90; @@ -545,15 +546,15 @@ bad_command: // pclog("Got all params %02X\n", fdc.command); fdc.stat=0x30; - discint=fdc.command&0x1F; timer_set_delay_u64(&fdc.timer, 256 * TIMER_USEC); // fdc.drive = fdc.params[0] & 3; disc_drivesel = fdc.drive & 1; fdc_reset_stat = 0; disc_set_drivesel(fdc.drive & 1); - switch (discint) + discint = fdc.command & 0x1f; + switch (fdc.command) { - case 2: /*Read a track*/ + case 0x02: case 0x42: /*Read track*/ fdc_rate(fdc.drive); fdc.head=fdc.params[2]; fdc.sector=fdc.params[3]; @@ -569,7 +570,7 @@ bad_command: fdc.inread = 1; break; - case 3: /*Specify*/ + case 0x03: /*Specify*/ fdc.stat=0x80; fdc.specify[0] = fdc.params[0]; fdc.specify[1] = fdc.params[1]; @@ -577,18 +578,20 @@ bad_command: timer_disable(&fdc.timer); break; - case 5: /*Write data*/ + case 0x05: case 0x45: case 0x85: case 0xc5: /*Write data*/ fdc_rate(fdc.drive); fdc.head=fdc.params[2]; fdc.sector=fdc.params[3]; fdc.sector_size = fdc.params[4]; fdc.eot[fdc.drive] = fdc.params[5]; - if (fdc.config & 0x40) - fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); - fdc.track[fdc.drive]=fdc.params[1]; fdc.rw_track = fdc.params[1]; - - disc_writesector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); + if (fdc.config & 0x40) + { + fdd_seek(fdc.drive, fdc.rw_track - fdc.track[fdc.drive]); + fdc.track[fdc.drive] = fdc.rw_track; + } + + disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); timer_disable(&fdc.timer); fdc.written = 0; readflash_set(READFLASH_FDC, fdc.drive); @@ -598,24 +601,27 @@ bad_command: // ioc_fiq(IOC_FIQ_DISC_DATA); break; - case 6: /*Read data*/ + case 0x06: case 0x26: case 0x46: case 0x66: /*Read data*/ + case 0x86: case 0xa6: case 0xc6: case 0xe6: fdc_rate(fdc.drive); fdc.head=fdc.params[2]; fdc.sector=fdc.params[3]; fdc.sector_size = fdc.params[4]; fdc.eot[fdc.drive] = fdc.params[5]; - if (fdc.config & 0x40) - fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); - fdc.track[fdc.drive]=fdc.params[1]; fdc.rw_track = fdc.params[1]; + if (fdc.config & 0x40) + { + fdd_seek(fdc.drive, fdc.rw_track - fdc.track[fdc.drive]); + fdc.track[fdc.drive] = fdc.rw_track; + } - disc_readsector(fdc.drive, fdc.sector, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); + disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); timer_disable(&fdc.timer); readflash_set(READFLASH_FDC, fdc.drive); fdc.inread = 1; break; - case 7: /*Recalibrate*/ + case 0x07: /*Recalibrate*/ fdc.stat = 1 << fdc.drive; timer_disable(&fdc.timer); time = fdd_seek(fdc.drive, SEEK_RECALIBRATE); @@ -623,7 +629,7 @@ bad_command: timer_set_delay_u64(&fdc.timer, time); break; - case 0x0d: /*Format*/ + case 0x0d: case 0x4d: /*Format*/ fdc_rate(fdc.drive); fdc.head = (fdc.params[0] & 4) ? 1 : 0; fdc.format_state = 1; @@ -631,7 +637,7 @@ bad_command: fdc.stat = 0x30; break; - case 0xf: /*Seek*/ + case 0x0f: /*Seek*/ fdc.stat = 1 << fdc.drive; fdc.head = (fdc.params[0] & 4) ? 1 : 0; timer_disable(&fdc.timer); @@ -641,13 +647,17 @@ bad_command: // pclog("Seek to %i\n", fdc.params[1]); break; - case 10: /*Read sector ID*/ + case 0x0a: case 0x4a: /*Read sector ID*/ fdc_rate(fdc.drive); timer_disable(&fdc.timer); fdc.head = (fdc.params[0] & 4) ? 1 : 0; // pclog("Read sector ID %i %i\n", fdc.rate, fdc.drive); disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate); break; + + case 0x94: /*Unlock*/ + discint = 0x94; + break; } } } @@ -753,10 +763,6 @@ uint8_t fdc_read(uint16_t addr, void *priv) temp=fdc.dat; fdc.data_ready = 0; } - if (discint==0xA) - { - timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); - } fdc.stat &= 0xf0; break; case 7: /*Disk change*/ From 2e3444697fe92de1049e5298405d81a2ab69b144 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 22:01:57 +0000 Subject: [PATCH 0793/1050] FDC seek command always reports ST0 with head 0. Fixes numerous disc access issues on Windows 98SE/ME. --- src/fdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fdc.c b/src/fdc.c index dc2fcc8..070d05b 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -639,7 +639,7 @@ bad_command: case 0x0f: /*Seek*/ fdc.stat = 1 << fdc.drive; - fdc.head = (fdc.params[0] & 4) ? 1 : 0; + fdc.head = 0; timer_disable(&fdc.timer); time = fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); if (time) From 38f19f7c9f59631362360888c8e80ac019d8d240 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Mar 2020 22:03:08 +0000 Subject: [PATCH 0794/1050] Better implementation of FDC 'not found' errors - can now distinguish missing address mark (eg disc not present or track not formatted), sector not found, wrong cylinder and bad cylinder. --- src/disc.c | 2 +- src/disc.h | 2 +- src/disc_fdi.c | 3 +- src/disc_sector.c | 79 +++++++++++++++++++++++++++++++++++------------ src/fdc.c | 36 ++++++++++++++++++--- src/fdc.h | 10 ++++++ 6 files changed, 106 insertions(+), 26 deletions(-) diff --git a/src/disc.c b/src/disc.c index b2e0a0c..6b76b9b 100644 --- a/src/disc.c +++ b/src/disc.c @@ -143,7 +143,7 @@ void disc_poll() { disc_notfound--; if (!disc_notfound) - fdc_notfound(); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); } } diff --git a/src/disc.h b/src/disc.h index d8e33a5..714af06 100644 --- a/src/disc.h +++ b/src/disc.h @@ -37,7 +37,7 @@ void fdc_callback(); int fdc_data(uint8_t dat); void fdc_spindown(); void fdc_finishread(); -void fdc_notfound(); +void fdc_notfound(int reason); void fdc_datacrcerror(); void fdc_headercrcerror(); void fdc_writeprotect(); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index 498a623..1393bc2 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -3,6 +3,7 @@ #include "ibm.h" #include "disc.h" #include "disc_fdi.h" +#include "fdc.h" #include "fdi2raw.h" static struct @@ -314,7 +315,7 @@ void fdi_poll() if (fdi_revs == 3) { // pclog("Not found!\n"); - fdc_notfound(); + fdc_notfound(FDC_STATUS_NOT_FOUND); fdi_inread = fdi_inreadaddr = 0; return; } diff --git a/src/disc_sector.c b/src/disc_sector.c index b7805d6..26759bf 100644 --- a/src/disc_sector.c +++ b/src/disc_sector.c @@ -46,7 +46,9 @@ static int disc_intersector_delay = 0; static uint8_t disc_sector_fill; static int cur_sector, cur_byte; static int index_count; - + +static int disc_sector_status; + void disc_sector_reset(int drive, int side) { disc_sector_count[drive][side] = 0; @@ -90,6 +92,8 @@ void disc_sector_readsector(int drive, int sector, int track, int side, int rate disc_sector_sector = sector; disc_sector_n = sector_size; index_count = 0; + + disc_sector_status = FDC_STATUS_AM_NOT_FOUND; } void disc_sector_writesector(int drive, int sector, int track, int side, int rate, int sector_size) @@ -103,6 +107,8 @@ void disc_sector_writesector(int drive, int sector, int track, int side, int rat disc_sector_sector = sector; disc_sector_n = sector_size; index_count = 0; + + disc_sector_status = FDC_STATUS_AM_NOT_FOUND; } void disc_sector_readaddress(int drive, int track, int side, int rate) @@ -114,6 +120,8 @@ void disc_sector_readaddress(int drive, int track, int side, int rate) disc_sector_side = side; disc_sector_drive = drive; index_count = 0; + + disc_sector_status = FDC_STATUS_AM_NOT_FOUND; } void disc_sector_format(int drive, int track, int side, int rate, uint8_t fill) @@ -179,7 +187,7 @@ void disc_sector_poll() if (index_count > 1) { // pclog("Find sector not found\n"); - fdc_notfound(); + fdc_notfound(disc_sector_status); disc_sector_state = STATE_IDLE; break; } @@ -187,10 +195,11 @@ void disc_sector_poll() disc_sector_side != s->h, disc_sector_sector != s->r, fdc_get_bitcell_period() != get_bitcell_period());*/ - if (cur_byte || disc_sector_track != s->c || - disc_sector_side != s->h || - disc_sector_sector != s->r || - disc_sector_n != s->n || + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + + if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || !fdd_can_read_medium(disc_sector_drive ^ fdd_swap) || disc_intersector_delay) @@ -198,6 +207,16 @@ void disc_sector_poll() advance_byte(); break; } + if (disc_sector_track != s->c || + disc_sector_side != s->h || + disc_sector_sector != s->r || + disc_sector_n != s->n) + { + if (disc_sector_track != s->c) + disc_sector_status = (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER; + advance_byte(); + break; + } disc_sector_state = STATE_READ_SECTOR; case STATE_READ_SECTOR: // pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte, disc_intersector_delay); @@ -218,10 +237,14 @@ void disc_sector_poll() if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { // pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); disc_sector_state = STATE_IDLE; break; } + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + if (cur_byte || !index_count || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { @@ -244,14 +267,14 @@ void disc_sector_poll() if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { // pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); disc_sector_state = STATE_IDLE; break; } if (index_count) { // pclog("Find next sector hit end of track\n"); - fdc_notfound(); + fdc_notfound(disc_sector_status); disc_sector_state = STATE_IDLE; break; } @@ -277,10 +300,15 @@ void disc_sector_poll() if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { // pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); disc_sector_state = STATE_IDLE; break; } + + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + if (writeprot[disc_sector_drive]) { fdc_writeprotect(); @@ -290,20 +318,27 @@ void disc_sector_poll() if (index_count > 1) { // pclog("Write find sector not found\n"); - fdc_notfound(); + fdc_notfound(disc_sector_status); disc_sector_state = STATE_IDLE; break; } - if (cur_byte || disc_sector_track != s->c || - disc_sector_side != s->h || - disc_sector_sector != s->r || - disc_sector_n != s->n || + if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { advance_byte(); break; } + if (disc_sector_track != s->c || + disc_sector_side != s->h || + disc_sector_sector != s->r || + disc_sector_n != s->n) + { + if (disc_sector_track != s->c) + disc_sector_status = (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER; + advance_byte(); + break; + } disc_sector_state = STATE_WRITE_SECTOR; case STATE_WRITE_SECTOR: data = fdc_getdata(cur_byte == ((128 << s->n) - 1)); @@ -323,14 +358,19 @@ void disc_sector_poll() if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { // pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); disc_sector_state = STATE_IDLE; break; } + + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + if (index_count) { // pclog("Find next sector hit end of track\n"); - fdc_notfound(); + fdc_notfound(disc_sector_status); disc_sector_state = STATE_IDLE; break; } @@ -343,6 +383,7 @@ void disc_sector_poll() disc_sector_state = STATE_READ_ADDRESS; case STATE_READ_ADDRESS: fdc_sectorid(s->c, s->h, s->r, s->n, 0, 0); + advance_byte(); disc_sector_state = STATE_IDLE; break; @@ -362,13 +403,13 @@ void disc_sector_poll() if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { // pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(); + fdc_notfound(FDC_STATUS_NOT_FOUND); disc_sector_state = STATE_IDLE; break; } if (fdc_get_bitcell_period() != get_bitcell_period()) { - fdc_notfound(); + fdc_notfound(FDC_STATUS_NOT_FOUND); disc_sector_state = STATE_IDLE; break; } diff --git a/src/fdc.c b/src/fdc.c index 070d05b..514bc07 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -5,12 +5,23 @@ #include "disc.h" #include "disc_sector.h" #include "dma.h" +#include "fdc.h" #include "fdd.h" #include "io.h" #include "pic.h" #include "timer.h" #include "x86.h" +#define ST1_DE (1 << 5) +#define ST1_ND (1 << 2) +#define ST1_NW (1 << 1) +#define ST1_MA (1 << 0) + +#define ST2_DD (1 << 5) +#define ST2_WC (1 << 4) /*Wrong cylinder*/ +#define ST2_BC (1 << 1) /*Bad cylinder*/ +#define ST2_MD (1 << 0) + static int fdc_reset_stat = 0; /*FDC*/ typedef struct FDC @@ -790,7 +801,6 @@ uint8_t fdc_read(uint16_t addr, void *priv) void fdc_callback() { int temp; - int doseek = 0; int drive; // pclog("fdc_callback %i\n", discint); @@ -1187,15 +1197,33 @@ void fdc_finishread() // rpclog("fdc_finishread\n"); } -void fdc_notfound() +void fdc_notfound(int reason) { +// pclog("fdc_notfound: reason=%i\n", reason); timer_disable(&fdc.timer); fdc_int(); fdc.stat=0xD0; fdc.res[4]=0x40|(fdc.head?4:0)|fdc.drive; - fdc.res[5]=5; - fdc.res[6]=0; + switch (reason) + { + case FDC_STATUS_AM_NOT_FOUND: + fdc.res[5] = ST1_ND | ST1_MA; + fdc.res[6] = 0; + break; + case FDC_STATUS_NOT_FOUND: + fdc.res[5] = ST1_ND; + fdc.res[6] = 0; + break; + case FDC_STATUS_WRONG_CYLINDER: + fdc.res[5] = ST1_ND; + fdc.res[6] = ST2_WC; + break; + case FDC_STATUS_BAD_CYLINDER: + fdc.res[5] = ST1_ND; + fdc.res[6] = ST2_WC | ST2_BC; + break; + } fdc.res[7] = fdc.rw_track; fdc.res[8] = fdc.head; fdc.res[9] = fdc.sector; diff --git a/src/fdc.h b/src/fdc.h index ff8d540..f0aecce 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -24,3 +24,13 @@ void fdc_update_boot_drive(int boot_drive); void fdc_update_densel_polarity(int densel_polarity); void fdc_update_densel_force(int densel_force); void fdc_update_drvrate(int drive, int drvrate); + + + +enum +{ + FDC_STATUS_AM_NOT_FOUND, + FDC_STATUS_NOT_FOUND, + FDC_STATUS_WRONG_CYLINDER, + FDC_STATUS_BAD_CYLINDER +}; From 57607b537da93de8562466c4d8dfe8748e83552c Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 5 Mar 2020 17:10:29 +0000 Subject: [PATCH 0795/1050] Added Cyrix MII CPUs. Patch from leilei. --- src/cpu.h | 1 + src/cpu_tables.c | 86 ++++++++++++++++++++++++++++++++++-------------- src/model.c | 2 +- 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/cpu.h b/src/cpu.h index 69d7cc5..c1cf577 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -114,6 +114,7 @@ extern CPU cpus_Pentium5V[]; extern CPU cpus_PentiumS5[]; extern CPU cpus_Pentium[]; extern CPU cpus_6x86[]; +extern CPU cpus_6x86_SS7[]; extern CPU cpus_K6_S7[]; extern CPU cpus_K6_SS7[]; diff --git a/src/cpu_tables.c b/src/cpu_tables.c index aa19596..a32032f 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -278,35 +278,71 @@ CPU cpus_Cx486[] = {"", -1, 0, 0, 0} }; - CPU cpus_6x86[] = - { - /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, - {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, - {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, - {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, +CPU cpus_6x86[] = +{ + /*Cyrix 6x86*/ + {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, + {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, - /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, - {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, - {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + /*Cyrix 6x86L*/ + {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, - /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, - {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, - {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, - {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, - {"6x86MX-PR300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, - {"6x86MX-PR333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, - {"6x86MX-PR366", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, - {"6x86MX-PR400", CPU_Cx6x86MX, fpus_builtin, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, - {"", -1, 0, 0, 0} - }; + /*Cyrix 6x86MX*/ + {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + /*Cyrix M II*/ + {"M II-200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"M II-233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x601, 0x601, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"M II-266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + {"M II-300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, + {"M II-333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, + {"", -1, 0, 0, 0} +}; + +CPU cpus_6x86_SS7[] = +{ + /*Cyrix 6x86*/ + {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 2*5}, + {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*6}, + {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + + /*Cyrix 6x86L*/ + {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 2*7}, + {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*7}, + {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*9}, + + /*Cyrix 6x86MX*/ + {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 2*8}, + {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + + /*Cyrix M II*/ + {"M II-200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"M II-233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x601, 0x601, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*9)/2}, + {"M II-266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, (5*10)/2}, + {"M II-300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, (7*8)/2}, + {"M II-333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 3*10}, + {"M II-366", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 3*10}, + {"M II-400", CPU_Cx6x86MX, fpus_builtin, 18, 285000000, 3, 31666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*11}, + {"M II-433", CPU_Cx6x86MX, fpus_builtin, 18, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*12}, + {"", -1, 0, 0, 0} +}; CPU cpus_WinChip[] = { diff --git a/src/model.c b/src/model.c index 7570cc1..76ee39e 100644 --- a/src/model.c +++ b/src/model.c @@ -225,7 +225,7 @@ MODEL models[] = {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55va_init, NULL}, {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, - {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, + {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86_SS7}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; From 63b14455bad7c0385699e8f3350bc265dee8bf4c Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Mar 2020 22:10:18 +0000 Subject: [PATCH 0796/1050] Add keyboard command 0xee (Diagnostic Echo). Fixes keyboard detection in FreeBSD 4.2. --- src/keyboard_at.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index d4e85be..ac55e65 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -393,6 +393,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at_adddata_keyboard(0xfa); break; + case 0xee: /*Diagnostic echo*/ + keyboard_at_adddata_keyboard(0xee); + break; + case 0xf0: /*Set scancode set*/ keyboard_at.key_wantdata = 1; keyboard_at_adddata_keyboard(0xfa); From cac99a8bf4293223ba9824c734d902971e328e1f Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Mar 2020 22:10:38 +0000 Subject: [PATCH 0797/1050] Added PS/2 mouse command 0xeb (Get Mouse Data). --- src/mouse_ps2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index 32f38f9..e6c065f 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -96,6 +96,27 @@ void mouse_ps2_write(uint8_t val, void *p) keyboard_at_adddata_mouse(mouse->sample_rate); break; + case 0xeb: /*Get mouse data*/ + keyboard_at_adddata_mouse(0xfa); + + temp = 0; + if (mouse->x < 0) + temp |= 0x10; + if (mouse->y < 0) + temp |= 0x20; + if (mouse_buttons & 1) + temp |= 1; + if (mouse_buttons & 2) + temp |= 2; + if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + temp |= 4; + keyboard_at_adddata_mouse(temp); + keyboard_at_adddata_mouse(mouse->x & 0xff); + keyboard_at_adddata_mouse(mouse->y & 0xff); + if (mouse->intellimouse_mode) + keyboard_at_adddata_mouse(mouse->z); + break; + case 0xf2: /*Read ID*/ keyboard_at_adddata_mouse(0xfa); if (mouse->intellimouse_mode) From e3b9ed13fcf8100ba5bafef4edfe5d1f58a8e3c7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 5 Mar 2020 17:22:34 +0000 Subject: [PATCH 0798/1050] Pre-386 CPUs don't clear integer registers on soft reset. Patch from Greatpsycho. --- src/808x.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/808x.c b/src/808x.c index 12566f9..f3f8d0f 100644 --- a/src/808x.c +++ b/src/808x.c @@ -677,8 +677,15 @@ void softresetx86() //rammask=0xFFFFFFFF; cpu_state.flags=2; idt.base = 0; - idt.limit = is386 ? 0x03FF : 0xFFFF; - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + if (is386) + { + idt.limit = 0x03FF; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + } + else + { + idt.limit = 0xFFFF; + } x86seg_reset(); flushmmucache(); x86_was_reset = 1; From cab6aa43b2cca9c22983a18ea1e110b1f5478156 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 13:46:16 +0000 Subject: [PATCH 0799/1050] Use pre-translation AT keyboard ID to avoid putting the ID through translation twice. --- src/keyboard_at.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index ac55e65..7ef516f 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -405,7 +405,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xf2: /*Read ID*/ keyboard_at_adddata_keyboard(0xfa); keyboard_at_adddata_keyboard(0xab); - keyboard_at_adddata_keyboard(0x41); + keyboard_at_adddata_keyboard(0x83); break; case 0xf3: /*Set typematic rate/delay*/ From 832717fe66bd74049490052d977eac5ec2b6ccad Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 13:47:10 +0000 Subject: [PATCH 0800/1050] Added Goldstar GDC-212M. Patch from Greatpsycho. --- src/ibm.h | 1 + src/mem_bios.c | 7 +++++++ src/model.c | 1 + src/nvr.c | 2 ++ 4 files changed, 11 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index efad69d..bcaf310 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -196,6 +196,7 @@ enum ROM_AMI286, ROM_TG286M, ROM_AWARD286, + ROM_GDC212M, ROM_GW286CT, ROM_SPC4200P, ROM_SPC4216P, diff --git a/src/mem_bios.c b/src/mem_bios.c index 59f0979..956c526 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -372,6 +372,13 @@ int loadbios() fclose(f); return 1; + case ROM_GDC212M: + f=romfopen("gdc212m/gdc212m_72h.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_GW286CT: f=romfopen("gw286ct/2ctc001.bin","rb"); if (!f) break; diff --git a/src/model.c b/src/model.c index 76ee39e..97ea917 100644 --- a/src/model.c +++ b/src/model.c @@ -174,6 +174,7 @@ MODEL models[] = {"[286] DELL System 200", ROM_DELL200, "dells200", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 640,16384, 128, dells200_init, NULL}, {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, at_init, NULL}, {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 256,15872, 128, at_init, NULL}, + {"[286] Goldstar GDC-212M", ROM_GDC212M, "gdc212m", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 4096, 512, at_scat_init, NULL}, {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 128, at_scat_init, NULL}, {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 512,16384, 512, ps1_m2011_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index f0bd52a..4a5cead 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -297,6 +297,7 @@ void loadnvr() case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); nvrmask = 127; break; case ROM_TG286M: f = nvrfopen("tg286m.nvr", "rb"); nvrmask = 127; break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break; + case ROM_GDC212M: f = nvrfopen("gdc212m.nvr", "rb"); nvrmask = 127; break; case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); nvrmask = 127; break; @@ -398,6 +399,7 @@ void savenvr() case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); break; case ROM_TG286M: f = nvrfopen("tg286m.nvr", "wb"); break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break; + case ROM_GDC212M: f = nvrfopen("gdc212m.nvr", "wb"); break; case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); break; From c8638b9b2be6b73351376b3f14686a7974e96687 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 13:47:37 +0000 Subject: [PATCH 0801/1050] Added Samsung SPC-4620P. Patch from Greatpsycho. --- src/ibm.h | 1 + src/mem_bios.c | 21 +++++++++++++++++++++ src/model.c | 1 + src/nvr.c | 2 ++ src/scat.c | 1 + src/vid_ati28800.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/vid_ati28800.h | 1 + src/video.c | 22 ++++++++++++++++++++-- 8 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index bcaf310..889d029 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -200,6 +200,7 @@ enum ROM_GW286CT, ROM_SPC4200P, ROM_SPC4216P, + ROM_SPC4620P, ROM_DELL200, ROM_MISC286, ROM_IBMAT386, diff --git a/src/mem_bios.c b/src/mem_bios.c index 956c526..85f8169 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -418,6 +418,27 @@ int loadbios() } break; + case ROM_SPC4620P: + f=romfopen("spc4620p/svb6120a_font.rom","rb"); + if (!f) break; + fclose(f); + f = romfopen("spc4620p/31005h.u8", "rb"); + ff = romfopen("spc4620p/31005h.u10","rb"); + if (f && ff) + { + fseek(f, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); + for (c = 0x0000; c < 0x10000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + } + break; + case ROM_EUROPC: // return 0; f=romfopen("europc/50145","rb"); diff --git a/src/model.c b/src/model.c index 97ea917..1e205e5 100644 --- a/src/model.c +++ b/src/model.c @@ -183,6 +183,7 @@ MODEL models[] = {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", { {"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL}, {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, + {"[286] Samsung SPC-4620P", ROM_SPC4620P, "spc4620p", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}, {"[286] Toshiba T3100e", ROM_T3100E, "t3100e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}, {"[286] Trigem 286M", ROM_TG286M, "tg286m", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}, {"[286] Tulip AT Compact", ROM_TULIP_TC7, "tulip_tc7", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 640,15872, 128, ibm_at_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 4a5cead..1ebc5a9 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -301,6 +301,7 @@ void loadnvr() case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); nvrmask = 127; break; + case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "rb"); nvrmask = 127; break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); break; @@ -403,6 +404,7 @@ void savenvr() case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); break; + case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "wb"); break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); break; diff --git a/src/scat.c b/src/scat.c index ca41c39..a4a4b3f 100644 --- a/src/scat.c +++ b/src/scat.c @@ -1369,6 +1369,7 @@ void scat_init() { case ROM_GW286CT: case ROM_SPC4216P: + case ROM_SPC4620P: scat_regs[SCAT_VERSION] = 4; break; default: diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 005d1f0..a86bf2a 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -383,6 +383,39 @@ void *ati28800k_init() return ati28800; } +void *ati28800k_spc4620p_init() +{ + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); + + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; + + rom_init_interleaved(&ati28800->bios_rom, "spc4620p/31005h.u8", "spc4620p/31005h.u10", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("spc4620p/svb6120a_font.rom", 6); + + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800k_recalctimings, + ati28800k_in, ati28800k_out, + NULL, + NULL); + + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + + ati28800->svga.miscout = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; + + ati_eeprom_load(&ati28800->eeprom, "svb6120a.nvr", 0); + + return ati28800; +} + static int ati28800_available() { return rom_present("bios.bin"); @@ -457,3 +490,15 @@ device_t ati28800k_device = ati28800_force_redraw, ati28800k_add_status_info }; + +device_t ati28800k_spc4620p_device = +{ + "SVB-6120A", + 0, + ati28800k_spc4620p_init, + ati28800_close, + NULL, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800k_add_status_info +}; diff --git a/src/vid_ati28800.h b/src/vid_ati28800.h index 51f3615..ed30dbb 100644 --- a/src/vid_ati28800.h +++ b/src/vid_ati28800.h @@ -1,2 +1,3 @@ extern device_t ati28800_device; extern device_t ati28800k_device; +extern device_t ati28800k_spc4620p_device; diff --git a/src/video.c b/src/video.c index 2c7dd21..1b3a91b 100644 --- a/src/video.c +++ b/src/video.c @@ -141,6 +141,7 @@ static video_timings_t timing_vga = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_ps1_svga = {VIDEO_ISA, 6, 8,16, 6, 8,16}; static video_timings_t timing_t3100e = {VIDEO_ISA, 8,16,32, 8,16,32}; static video_timings_t timing_t1000 = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_spc4620p = {VIDEO_ISA, 2, 2, 4, 4, 4, 8}; static video_timings_t timing_pc425x = {VIDEO_BUS, 5, 5, 9, 20,20,30}; static video_timings_t timing_pb410a = {VIDEO_BUS, 5, 5, 9, 20,20,30}; static video_timings_t timing_pb570 = {VIDEO_BUS, 4, 4, 8, 10,10,20}; @@ -211,7 +212,11 @@ device_t *video_card_getdevice(int card, int romset) case ROM_MEGAPC: return ¶dise_wd90c11_megapc_device; - + + case ROM_SPC4620P: + if (card == GFX_BUILTIN) + return &ati28800k_spc4620p_device; + case ROM_ACER386: return &oti067_acer386_device; @@ -587,6 +592,11 @@ void video_updatetiming() if (gfxcard == GFX_BUILTIN) timing = &timing_wd90c11; break; + + case ROM_SPC4620P: + if (gfxcard == GFX_BUILTIN) + timing = &timing_spc4620p; + break; case ROM_ACER386: if (gfxcard == GFX_BUILTIN) @@ -780,7 +790,15 @@ void video_init() return; } break; - + + case ROM_SPC4620P: + if (gfxcard == GFX_BUILTIN) + { + device_add(&ati28800k_spc4620p_device); + return; + } + break; + case ROM_ACER386: device_add(&oti067_acer386_device); if (gfxcard != GFX_BUILTIN) From 07b2574279ca618ac16ccff4587423b14c32e721 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 14:17:40 +0000 Subject: [PATCH 0802/1050] Show correct CPU speeds in Advanced/ZP CMOS Setup. Patch from EluanCM. --- src/intel.c | 38 +++++++++++++++++++++++++++++++++++++- src/pc87306.c | 2 +- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/intel.c b/src/intel.c index 5fcbdbb..691d254 100644 --- a/src/intel.c +++ b/src/intel.c @@ -2,6 +2,7 @@ #include "cpu.h" #include "io.h" #include "mem.h" +#include "model.h" #include "pit.h" #include "timer.h" #include "x86.h" @@ -103,11 +104,46 @@ void intel_endeavor_init() static uint8_t zappa_brdconfig(uint16_t port, void *p) { + uint8_t temp; + CPU *cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu]; // pclog("zappa_brdconfig read port=%04x\n", port); switch (port) { case 0x79: - return 0xff; + // Bit # | Description | Bit = 1 | Bit = 0 + // 0 | Internal CPU Clock Freq. (Switch 6) | 3/2x | 2x (Manual has these swapped in one place?) + // 1 | No Connect | | + // 2 | No Connect | | + // 3 | External CPU clock (Switch 7) | | + // 4 | External CPU clock (Switch 8) | | + // 5 | Setup Disable (Switch 5) | Enable access | Disable access + // 6 | Clear CMOS (Switch 4) | Keep values | Clear values + // 7 | Password Clear (Switch 3) | Keep password | Clear password + + // Bus Speed | Switch 7 | Switch 8 + // 50 MHz | Off | Off + // 60 Mhz | On | Off + // 66 MHz | Off | On + + // Multiplier for each supported processor- + // -The 3/2 setting is used for 75 MHz, 90 MHz, and 100 MHz processors + // -The 2 times setting is used for 120 MHz processors. + + if (cpu_s->rspeed == 75000000 && cpu_s->pci_speed == 25000000) + temp = 0x01; + else if (cpu_s->rspeed == 90000000 && cpu_s->pci_speed == 30000000) + temp = 0x01 | 0x08; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 25000000) + temp = 0x00; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 33333333) + temp = 0x01 | 0x10; + else if (cpu_s->rspeed == 120000000 && cpu_s->pci_speed == 30000000) + temp = 0x08; + else if (cpu_s->rspeed == 133333333 && cpu_s->pci_speed == 33333333) + temp = 0x10; + else + temp = 0x10; // TODO: how are the overdrive processors configured? + return 0xe0 | temp; } return 0; } diff --git a/src/pc87306.c b/src/pc87306.c index dc96d9b..91b95e0 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -200,6 +200,6 @@ void pc87306_init(uint16_t port) pc87306_global.regs[REG_FAR] = 0x10; pc87306_global.regs[REG_GPBA] = 0x78 >> 2; pc87306_global.regs[REG_SCF0] = 0x30; - pc87306_global.gpio_2 = 0xfa; + pc87306_global.gpio_2 = 0xff; // this is a mask only, output will be defined by zappa_brdconfig and endeavor_brdconfig in intel.c io_sethandler(0x0078, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); } From da26a60364014de1831043aca36db5a7a9653791 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 14:36:03 +0000 Subject: [PATCH 0803/1050] Port diff 1526 to Advanced/EV. --- src/intel.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/intel.c b/src/intel.c index 691d254..2010cc3 100644 --- a/src/intel.c +++ b/src/intel.c @@ -88,11 +88,46 @@ void intel_batman_init() uint8_t endeavor_brdconfig(uint16_t port, void *p) { + uint8_t temp; + CPU *cpu_s = &models[model].cpu[cpu_manufacturer].cpus[cpu]; // pclog("endeavor_brdconfig read port=%04x\n", port); switch (port) { case 0x79: - return 0xff; + // Bit # | Description | Bit = 1 | Bit = 0 + // 0 | Internal CPU Clock Freq. (Switch 6) | 3/2x | 2x (Manual has these swapped in one place?) + // 1 | Soft Off capable power supply | No | Yes + // 2 | On-board Audio present | Yes | No + // 3 | External CPU clock (Switch 7) | | + // 4 | External CPU clock (Switch 8) | | + // 5 | Setup Disable (Switch 5) | Enable access | Disable access + // 6 | Clear CMOS (Switch 4) | Keep values | Clear values + // 7 | Password Clear (Switch 3) | Keep password | Clear password + + // Bus Speed | Switch 7 | Switch 8 + // 50 MHz | Off | Off + // 60 Mhz | On | Off + // 66 MHz | Off | On + + // Multiplier for each supported processor- + // -The 3/2 setting is used for 75 MHz, 90 MHz, and 100 MHz processors + // -The 2 times setting is used for 120 MHz processors. + + if (cpu_s->rspeed == 75000000 && cpu_s->pci_speed == 25000000) + temp = 0x01; + else if (cpu_s->rspeed == 90000000 && cpu_s->pci_speed == 30000000) + temp = 0x01 | 0x08; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 25000000) + temp = 0x00; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 33333333) + temp = 0x01 | 0x10; + else if (cpu_s->rspeed == 120000000 && cpu_s->pci_speed == 30000000) + temp = 0x08; + else if (cpu_s->rspeed == 133333333 && cpu_s->pci_speed == 33333333) + temp = 0x10; + else + temp = 0x10; // TODO: how are the overdrive processors configured? + return 0xe2 | temp; } return 0; } From ee103457fa9a7a48f0782efcafbc526fbde7a803 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 14:36:30 +0000 Subject: [PATCH 0804/1050] Add waitstates to AT keyboard read. Fixes keyboard detection on Advanced/EV & ZP. --- src/keyboard_at.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 7ef516f..c298da7 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -663,6 +663,8 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) uint8_t keyboard_at_read(uint16_t port, void *priv) { uint8_t temp = 0xff; + + cycles -= ISA_CYCLES(8); // if (port != 0x61) pclog("keyboard_at : read %04X ", port); if (romset == ROM_XI8088 && port == 0x63) port = 0x61; From a552c25b3221e3789bdda72fce0490330da78e93 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 7 Mar 2020 18:01:47 +0000 Subject: [PATCH 0805/1050] Added Leading Edge Model M. --- src/ibm.h | 1 + src/keyboard_xt.c | 21 +++++++++++++++++++-- src/mem_bios.c | 8 ++++++++ src/model.c | 1 + 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 889d029..ee076de 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -257,6 +257,7 @@ enum ROM_CBM_SL386SX25, ROM_IBMPS1_2133_451, ROM_ECS_386_32, + ROM_LEDGE_MODELM, ROM_MAX }; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 0cfac2c..7f5c794 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -157,7 +157,7 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) switch (port) { case 0x60: - if ((romset == ROM_IBMPC) && (keyboard_xt.pb & 0x80)) + if ((romset == ROM_IBMPC || romset == ROM_LEDGE_MODELM) && (keyboard_xt.pb & 0x80)) { if (video_is_ega_vga()) temp = 0x4D; @@ -190,7 +190,12 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) else temp = ((mem_size-64) / 32) >> 4; - temp |= (cassette_input()) ? 0x10 : 0; + temp |= (cassette_input()) ? 0x10 : 0; + } + else if (romset == ROM_LEDGE_MODELM) + { + /*High bit of memory size is read from port 0xa0*/ + temp = ((mem_size-64) / 32) & 0xf; } else if (romset == ROM_ATARIPC3) { @@ -227,6 +232,16 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) return temp; } +static uint8_t ledge_modelm_read(uint16_t port, void *p) +{ + uint8_t temp = 0; + + if (((mem_size-64) / 32) >> 4) + temp |= 0x40; + + return temp; +} + void keyboard_xt_reset() { keyboard_xt.wantirq = 0; @@ -238,6 +253,8 @@ void keyboard_xt_init() { //return; io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); + if (romset == ROM_LEDGE_MODELM) + io_sethandler(0x00a0, 0x0001, ledge_modelm_read, NULL, NULL, NULL, NULL, NULL, NULL); keyboard_xt_reset(); keyboard_send = keyboard_xt_adddata; keyboard_poll = keyboard_xt_poll; diff --git a/src/mem_bios.c b/src/mem_bios.c index 85f8169..a6ef874 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -1064,6 +1064,14 @@ int loadbios() fclose(ff); fclose(f); return 1; + + case ROM_LEDGE_MODELM: + f = romfopen("leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin","rb"); + if (!f) break; + romfread(rom, 0x4000, 1, f); + fclose(f); + biosmask = 0x3fff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 1e205e5..c1ea6a4 100644 --- a/src/model.c +++ b/src/model.c @@ -144,6 +144,7 @@ MODEL models[] = {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { {"", cpus_pcjr}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 64, pcjr_init, &pcjr_device}, {"[8088] IBM XT", ROM_IBMXT, "ibmxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, + {"[8088] Leading Edge Model M", ROM_LEDGE_MODELM, "ledge_modelm", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 704, 64, xt_init, NULL}, {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 256, 640, 64, xt_init, NULL}, {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", { {"", cpus_europc}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, europc_init, NULL}, From 54664b1123dbf6b313da9a666e3f8432285452f6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Mar 2020 19:38:21 +0000 Subject: [PATCH 0806/1050] Fix MDA/CGA switch for MDSI Genius. --- src/video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video.c b/src/video.c index 1b3a91b..81dc3ec 100644 --- a/src/video.c +++ b/src/video.c @@ -104,7 +104,7 @@ static VIDEO_CARD video_cards[] = {"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}, {"OAK OTI-037", "oti037", &oti037_device, GFX_OTI037, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}, From 360b51451221d436dbe69bc1140de582f3a4b8ee Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Mar 2020 19:44:06 +0000 Subject: [PATCH 0807/1050] Correct blue graphics on MDSI Genius. Patch from JohnElliott. --- src/vid_genius.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_genius.c b/src/vid_genius.c index f06345b..f8c3688 100644 --- a/src/vid_genius.c +++ b/src/vid_genius.c @@ -420,7 +420,7 @@ void genius_hiresline(genius_t *genius) { int x, c; uint32_t dat; - uint8_t ink; + uint32_t ink; uint32_t addr; ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; @@ -457,7 +457,7 @@ void genius_poll(void *p) { genius_t *genius = (genius_t *)p; int x; - uint8_t background; + uint32_t background; if (!genius->linepos) { From 62cd99283910f9becfeac93a0b7f4eea0a8056a4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Mar 2020 19:55:52 +0000 Subject: [PATCH 0808/1050] Added language select to Amstrad PCs. Patch from JohnElliott. --- src/amstrad.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++- src/amstrad.h | 5 ++ src/model.c | 12 ++-- 3 files changed, 174 insertions(+), 7 deletions(-) diff --git a/src/amstrad.c b/src/amstrad.c index acd5070..b952151 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -11,6 +11,7 @@ static uint8_t amstrad_dead; int amstrad_latch = 0; +static uint8_t amstrad_language; uint8_t amstrad_read(uint16_t port, void *priv) { @@ -22,7 +23,7 @@ uint8_t amstrad_read(uint16_t port, void *priv) case 0x378: return lpt1_read(port, NULL); case 0x379: - return lpt1_read(port, NULL) | 7; + return lpt1_read(port, NULL) | (amstrad_language & 7); case 0x37a: temp = lpt1_read(port, NULL) & 0x1f; if (romset == ROM_PC1512) return temp | 0x20; @@ -164,4 +165,165 @@ void amstrad_init() io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); if ((romset == ROM_PC200 || romset == ROM_PPC512) && gfxcard != GFX_BUILTIN) io_sethandler(0x03de, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); + + } + +static void *ams1512_init() +{ + amstrad_language = device_get_config_int("language"); + return &amstrad_language; +} + +device_config_t ams1512_config[] = +{ + { + .name = "language", + .description = "BIOS language", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "English", + .value = 7 + }, + { + .description = "German", + .value = 6 + }, + { + .description = "French", + .value = 5 + }, + { + .description = "Spanish", + .value = 4 + }, + { + .description = "Danish", + .value = 3 + }, + { + .description = "Swedish", + .value = 2 + }, + { + .description = "Italian", + .value = 1 + }, + { + .description = "Diagnostic mode", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .type = -1 + } +}; + + +device_config_t ams2086_config[] = +{ + { + .name = "language", + .description = "BIOS language", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "English", + .value = 7 + }, + { + .description = "Diagnostic mode", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .type = -1 + } +}; + + + +device_config_t ams3086_config[] = +{ + { + .name = "language", + .description = "BIOS language", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "English", + .value = 7 + }, + { + .description = "Diagnostic mode", + .value = 3 + }, + { + .description = "" + } + }, + .default_int = 7 + }, + { + .type = -1 + } +}; + + + + +device_t ams1512_device = +{ + "Amstrad PC1512 (BIOS)", + 0, + ams1512_init, + NULL, + NULL, + NULL, + NULL, + NULL, + ams1512_config +}; + + + +device_t ams2086_device = +{ + "Amstrad PC2086 (BIOS)", + 0, + ams1512_init, + NULL, + NULL, + NULL, + NULL, + NULL, + ams2086_config +}; + + +device_t ams3086_device = +{ + "Amstrad PC3086 (BIOS)", + 0, + ams1512_init, + NULL, + NULL, + NULL, + NULL, + NULL, + ams3086_config +}; diff --git a/src/amstrad.h b/src/amstrad.h index bc13c37..0c54fcb 100644 --- a/src/amstrad.h +++ b/src/amstrad.h @@ -1,10 +1,15 @@ #include "mouse.h" +#include "device.h" void amstrad_init(); extern mouse_t mouse_amstrad; extern int amstrad_latch; +extern device_t ams1512_device; +extern device_t ams2086_device; +extern device_t ams3086_device; + enum { AMSTRAD_NOLATCH, diff --git a/src/model.c b/src/model.c index c1ea6a4..2778be7 100644 --- a/src/model.c +++ b/src/model.c @@ -156,13 +156,13 @@ MODEL models[] = {"[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, xt_zenith_init, NULL}, {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}, - {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, + {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams1512_device}, + {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams2086_device}, + {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams3086_device}, + {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}, {"[8088] Toshiba T1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048,1024, xt_t1200_init, NULL}, {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 1152, 128, xt_laserxt_init, NULL}, From 47e557e9cee5af0e7fdb50737eb8934635b93a83 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 10 Mar 2020 21:14:57 +0000 Subject: [PATCH 0809/1050] Implement Amstrad reset port 0x66. Fixes CTRL-ALT-DEL on Amstrad machines. --- src/808x.c | 1 + src/amstrad.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/808x.c b/src/808x.c index f3f8d0f..b080c97 100644 --- a/src/808x.c +++ b/src/808x.c @@ -689,6 +689,7 @@ void softresetx86() x86seg_reset(); flushmmucache(); x86_was_reset = 1; + FETCHCLEAR(); } static void setznp8(uint8_t val) diff --git a/src/amstrad.c b/src/amstrad.c index b952151..714380c 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -6,6 +6,7 @@ #include "mouse.h" #include "video.h" #include "fdc.h" +#include "x86.h" #include "amstrad.h" @@ -77,6 +78,10 @@ void amstrad_write(uint16_t port, uint8_t val, void *priv) { switch (port) { + case 0x66: + softresetx86(); + break; + case 0x378: case 0x379: case 0x37a: @@ -161,6 +166,7 @@ void amstrad_init() io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); + io_sethandler(0x0066, 0x0001, NULL, NULL, NULL, amstrad_write, NULL, NULL, NULL); io_sethandler(0x0378, 0x0003, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); if ((romset == ROM_PC200 || romset == ROM_PPC512) && gfxcard != GFX_BUILTIN) From 1181b13c2d3dd927db733dea11cb61ffc49c7796 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Mar 2020 21:21:09 +0000 Subject: [PATCH 0810/1050] Added Aztech Sound Galaxy Pro 16 AB (Washington, AZ2316A) and Aztech Sound Galaxy Nova 16 Extra (Clinton, AZ1605) emulation. Patch from EluanCM. Clinton is currently marked as DEVICE_NOT_WORKING due to issues with DOS drivers. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/sound.c | 37 +- src/sound_ad1848.c | 107 +- src/sound_ad1848.h | 12 +- src/sound_azt2316a.c | 1620 ++++++++++++++++++++++++++++ src/sound_azt2316a.h | 4 + src/sound_emu8k.h | 4 + src/sound_mpu401_uart.c | 38 +- src/sound_mpu401_uart.h | 13 +- src/sound_pas16.c | 2 +- src/sound_sb.c | 120 +-- src/sound_sb.h | 114 ++ src/sound_sb_dsp.c | 131 ++- src/sound_sb_dsp.h | 20 +- src/sound_wss.c | 2 +- 17 files changed, 2051 insertions(+), 179 deletions(-) create mode 100644 src/sound_azt2316a.c create mode 100644 src/sound_azt2316a.h diff --git a/src/Makefile.am b/src/Makefile.am index b074a05..4be48a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,7 @@ mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ scsi_ibm.c scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.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_azt2316a.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 \ sst39sf010.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 8422b25..c129df8 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -26,7 +26,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ - sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index bcce1a5..c6445db 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -26,7 +26,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ - sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_cms.o sound_dbopl.o \ + sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ diff --git a/src/sound.c b/src/sound.c index a5e7320..f038613 100644 --- a/src/sound.c +++ b/src/sound.c @@ -15,6 +15,7 @@ #include "sound_adlib.h" #include "sound_adlibgold.h" #include "sound_audiopci.h" +#include "sound_azt2316a.h" #include "sound_pas16.h" #include "sound_sb.h" #include "sound_sb_dsp.h" @@ -35,23 +36,25 @@ typedef struct static SOUND_CARD sound_cards[] = { - {"None", "none", NULL}, - {"Adlib", "adlib", &adlib_device}, - {"Adlib", "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}, - {"Pro Audio Spectrum 16", "pas16", &pas16_device}, - {"Ensoniq AudioPCI (ES1371)", "es1371", &es1371_device}, - {"Sound Blaster PCI 128", "sbpci128", &es1371_device}, + {"None", "none", NULL}, + {"Adlib", "adlib", &adlib_device}, + {"Adlib", "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}, + {"Aztech Sound Galaxy Pro 16 AB (Washington)", "azt2316a", &azt2316a_device}, + {"Aztech Sound Galaxy Nova 16 Extra (Clinton)", "azt1605", &azt1605_device}, + {"Pro Audio Spectrum 16", "pas16", &pas16_device}, + {"Ensoniq AudioPCI (ES1371)", "es1371", &es1371_device}, + {"Sound Blaster PCI 128", "sbpci128", &es1371_device}, {"", "", NULL} }; diff --git a/src/sound_ad1848.c b/src/sound_ad1848.c index 077611b..91bdcf9 100644 --- a/src/sound_ad1848.c +++ b/src/sound_ad1848.c @@ -4,8 +4,10 @@ #include "pic.h" #include "sound.h" #include "sound_ad1848.h" +#include "x86.h" -static int ad1848_vols[64]; +static int ad1848_vols_6bits[64]; +static uint32_t ad1848_vols_5bits_aux_gain[32]; void ad1848_setirq(ad1848_t *ad1848, int irq) { @@ -21,7 +23,7 @@ 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*/ @@ -34,7 +36,10 @@ uint8_t ad1848_read(uint16_t addr, void *p) temp = ad1848->status; break; } -// pclog("return %02X\n", temp); +// if ((addr & 3) == 1 && (ad1848->index & 0x1f) > 0x0f) +// pclog("ad1848_read_EXTENDED - addr %04X %04X(%08X):%08X return %02X\n", addr, CS, cs, cpu_state.pc, temp); +// else +// pclog("ad1848_read - addr %04X %04X(%08X):%08X return %02X\n", addr, CS, cs, cpu_state.pc, temp); return temp; } @@ -42,11 +47,18 @@ 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); + uint32_t new_cd_vol_l, new_cd_vol_r; +// if ((addr & 3) == 0 && (val & 0x1f) > 0x0f) +// pclog("ad1848_write_EXTENDED - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); +// else +// pclog("ad1848_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); switch (addr & 3) { case 0: /*Index*/ - ad1848->index = val & 0xf; + if (ad1848->regs[12] & 0x40 && ad1848->type == AD1848_TYPE_CS4231) + ad1848->index = val & 0x1f; // cs4231a extended mode enabled + else + ad1848->index = val & 0x0f; // ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? ad1848->trd = val & 0x20; ad1848->mce = val & 0x40; break; @@ -71,29 +83,49 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p) break; case 9: - if (!ad1848->enable && (val & 0x41) == 0x01) - { - if (ad1848->timer_latch) - timer_set_delay_u64(&ad1848->timer, ad1848->timer_latch); - else - timer_set_delay_u64(&ad1848->timer, TIMER_USEC); - } + if (!ad1848->enable && (val & 0x41) == 0x01) + { + if (ad1848->timer_latch) + timer_set_delay_u64(&ad1848->timer, ad1848->timer_latch); + else + timer_set_delay_u64(&ad1848->timer, TIMER_USEC); + } ad1848->enable = ((val & 0x41) == 0x01); if (!ad1848->enable) - { - timer_disable(&ad1848->timer); + { + timer_disable(&ad1848->timer); ad1848->out_l = ad1848->out_r = 0; - } + } break; case 12: + ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80; return; case 14: ad1848->count = ad1848->regs[15] | (val << 8); break; + // TODO: see which of the extended registers should be read only } ad1848->regs[ad1848->index] = val; + + if (ad1848->type == AD1848_TYPE_CS4231) // TODO: configure CD volume for CS4248/AD1848 too + { + if (ad1848->regs[0x12] & 0x80) + new_cd_vol_l = 0; + else + new_cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[0x12] & 0x1f]; + if (ad1848->regs[0x13] & 0x80) + new_cd_vol_r = 0; + else + new_cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[0x13] & 0x1f]; + + // Apparently there is no master volume to modulate here + // (The windows mixer just adjusts all registers at the same + // time when the master slider is adjusted) + sound_set_cd_volume(new_cd_vol_l, new_cd_vol_r); + } + break; case 2: ad1848->status &= 0xfe; @@ -125,7 +157,7 @@ static void ad1848_poll(void *p) timer_advance_u64(&ad1848->timer, TIMER_USEC*1000); ad1848_update(ad1848); - + // TODO: line in, mic, etc... if (ad1848->enable) { int32_t temp; @@ -155,12 +187,12 @@ static void ad1848_poll(void *p) if (ad1848->regs[6] & 0x80) ad1848->out_l = 0; else - ad1848->out_l = (ad1848->out_l * ad1848_vols[ad1848->regs[6] & 0x3f]) >> 16; + ad1848->out_l = (ad1848->out_l * ad1848_vols_6bits[ad1848->regs[6] & 0x3f]) >> 16; if (ad1848->regs[7] & 0x80) ad1848->out_r = 0; else - ad1848->out_r = (ad1848->out_r * ad1848_vols[ad1848->regs[7] & 0x3f]) >> 16; + ad1848->out_r = (ad1848->out_r * ad1848_vols_6bits[ad1848->regs[7] & 0x3f]) >> 16; if (ad1848->count < 0) { @@ -179,15 +211,17 @@ static void ad1848_poll(void *p) else { ad1848->out_l = ad1848->out_r = 0; + sound_set_cd_volume(0, 0); // pclog("ad1848_poll : not enable\n"); } } -void ad1848_init(ad1848_t *ad1848) +void ad1848_init(ad1848_t *ad1848, int type) { int c; double attenuation; + ad1848->type = type; ad1848->enable = 0; ad1848->status = 0xcc; @@ -195,15 +229,24 @@ void ad1848_init(ad1848_t *ad1848) ad1848->mce = 0x40; ad1848->regs[0] = ad1848->regs[1] = 0; - ad1848->regs[2] = ad1848->regs[3] = 0x80; + ad1848->regs[2] = ad1848->regs[3] = 0x80; // AZT2316A Line-in ad1848->regs[4] = ad1848->regs[5] = 0x80; - ad1848->regs[6] = ad1848->regs[7] = 0x80; + ad1848->regs[6] = ad1848->regs[7] = 0x80; // AZT2316A Master? ad1848->regs[8] = 0; ad1848->regs[9] = 0x08; ad1848->regs[10] = ad1848->regs[11] = 0; - ad1848->regs[12] = 0xa; + if (ad1848->type == AD1848_TYPE_CS4248 || ad1848->type == AD1848_TYPE_CS4231) + ad1848->regs[12] = 0x8a; + else + ad1848->regs[12] = 0xa; ad1848->regs[13] = 0; ad1848->regs[14] = ad1848->regs[15] = 0; + + if (ad1848->type == AD1848_TYPE_CS4231) + { + ad1848->regs[0x12] = ad1848->regs[0x13] = 0x80; // AZT2316A CD + ad1848->regs[0x1A] = 0x80; // AZT2316A Mic + } ad1848->out_l = 0; ad1848->out_r = 0; @@ -220,9 +263,23 @@ 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]); + ad1848_vols_6bits[c] = (int)(attenuation * 65536); +// pclog("ad1848_vols_6bits %i = %f %i\n", c, attenuation, ad1848_vols_6bits[c]); } - + for (c = 0; c < 32; c++) + { + attenuation = 12.0; + if (c & 0x01) attenuation -= 1.5; + if (c & 0x02) attenuation -= 3.0; + if (c & 0x04) attenuation -= 6.0; + if (c & 0x08) attenuation -= 12.0; + if (c & 0x10) attenuation -= 24.0; + + attenuation = pow(10, attenuation / 10); + + ad1848_vols_5bits_aux_gain[c] = (int)(attenuation * 65536); +// pclog("ad1848_vols_5bits_aux_gain %i = %f %i\n", c, attenuation, ad1848_vols_5bits_aux_gain[c]); + } + timer_add(&ad1848->timer, ad1848_poll, ad1848, 0); } diff --git a/src/sound_ad1848.h b/src/sound_ad1848.h index a0c436d..de951d9 100644 --- a/src/sound_ad1848.h +++ b/src/sound_ad1848.h @@ -1,9 +1,13 @@ #include "timer.h" +#define AD1848_TYPE_DEFAULT 0 +#define AD1848_TYPE_CS4248 1 +#define AD1848_TYPE_CS4231 2 + typedef struct ad1848_t { int index; - uint8_t regs[16]; + uint8_t regs[32]; // 16 original + 16 CS4231A extensions uint8_t status; int trd; @@ -20,10 +24,12 @@ typedef struct ad1848_t int freq; pc_timer_t timer; - uint64_t timer_latch; + uint64_t timer_latch; int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; + + int type; } ad1848_t; void ad1848_setirq(ad1848_t *ad1848, int irq); @@ -35,4 +41,4 @@ 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); +void ad1848_init(ad1848_t *ad1848, int type); diff --git a/src/sound_azt2316a.c b/src/sound_azt2316a.c new file mode 100644 index 0000000..b5fda11 --- /dev/null +++ b/src/sound_azt2316a.c @@ -0,0 +1,1620 @@ +/* + * TYPE 0x11: (Washington) + * Aztech MMPRO16AB, + * Aztech Sound Galaxy Pro 16 AB + * Aztech Sound Galaxy Washington 16 + * Packard Bell Sound 16A + * ...and other OEM names + * FCC ID I38-MMSN824 and others + * + * TYPE 0x0C: (Clinton) + * Aztech Sound Galaxy Nova 16 Extra + * Aztech Sound Galaxy Clinton 16 + * Packard Bell Forte 16 + * ...and other OEM names + * + * Also works more or less for drivers of other models with the same chipsets. + * + * Copyright (c) 2020 Eluan Costa Miranda All rights reserved. + * + * 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 3 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, see . + * + * ============================================================================= + * + * The CS4248 DSP used is pin and software compatible with the AD1848. + * I also have one of these cards with a CS4231. The driver talks to the + * emulated card as if it was a CS4231 and I still don't know how to tell the + * drivers to see the CS4248. The CS4231 more advanced features are NOT used, + * just the new input/output channels. Apparently some drivers are hardcoded + * for one or the other, so there is an option for this. + * + * There is lots more to be learned form the Win95 drivers. The Linux driver is + * very straightforward and doesn't do much. + * + * Recording and voice modes in the windows mixer still do nothing in PCem, so + * this is missing. + * + * There is a jumper to load the startup configuration from an EEPROM. This is + * implemented, so any software-configured parameters will be saved. + * + * The CD-ROM interface commands are just ignored, along with gameport. + * The MPU401 is always enabled. + * The OPL3 is always active in some (all?) drivers/cards, so there is no + * configuration for this. + * + * Tested with DOS (driver installation, tools, diagnostics), Win3.1 (driver + * installation, tools), Win95 (driver auto-detection), Win NT 3.1 (driver + * installation), lots of games. + * + * I consider type 0x11 (Washington) to be very well tested. Type 0x0C (Clinton) + * wasn't fully tested, but works well for WSS/Windows. BEWARE that there are + * *too many* driver types and OEM versions for each card. Maybe yours isn't + * emulated or you have the wrong driver. Some features of each card may work + * when using wrong drivers. CODEC selection is also important. + * + * Any updates to the WSS and SBPROV2 sound cards should be synced here when + * appropriate. The WSS was completely cloned here, while the SBPROV2 tends + * to call the original functions, except for initialization. + * + * TODO/Notes: + * -Some stuff still not understood on I/O addresses 0x624 and 0x530-0x533. + * -Is the CS42xx dither mode used anywhere? Implement. + * -What are the voice commands mode in Win95 mixer again? + * -Configuration options not present on Aztech's CONFIG.EXE have been commented + * out or deleted. Other types of cards with this chipset may need them. + * -Sfademo on the Descent CD fails under Win95, works under DOS, see if it + * happens on real hardware (and OPL3 stops working after the failure) + * -There appears to be some differences in sound volumes bertween MIDI, + * SBPROV2, WSS and OPL3? Also check relationship between the SBPROV2 mixer and + * the WSS mixer! Are they independent? Current mode selects which mixer? Are + * they entangled? + * -Check real hardware to see if advanced, mic boost, etc appear in the mixer? + * -CD-ROM driver shipped with the card (SGIDECD.SYS) checks for model strings. + * I have implemented mine (AZtech CDA 468-02I 4x) in PCem. + * -Descent 2 W95 version can't start cd music. Happens on real hardware. + * Explanation further below. + * -DOSQuake and Descent 2 DOS cd music do not work under Win95. The mode + * selects get truncated and send all zeros for output channel selection and + * volume, Descent 2 also has excess zeros! This is a PCem bug, happens on all + * sound cards. CD audio works in Winquake and Descent 2 DOS setup program. + * -DOSQuake CD audio works under DOS with VIDE-CDD.SYS and SGIDECD.SYS. + * Descent 2 DOS is still mute but volume selection appears to be working. + * Descent 2 fails to launch with SGIDECD.SYS with "Device failed to request + * command". SGIDECD.SYS is the CD-ROM driver included with the sound card + * drivers. My real CD-ROM drive can't read anything so I can't check the + * real behavior of this driver. + * -Some cards just have regular IDE ports while other have proprietary ports. + * The regular IDE ports just have a option to enable an almost-generic CD-ROM + * driver in CONFIG.SYS/AUTOEXEC.BAT (like SGIDECD.SYS) and the onboard port + * is enabled/disabled by jumpers. The proprietary ones also have + * address/dma/irq settings. Since the configuration options are ignored here, + * this behaves like a card with a regular interface disabled by jumper and + * the configuration just adds/removes the drivers (which will see other IDE + * interfaces present) from the boot process. + * -Continue reverse engineering to see if the AZT1605 shares the SB DMA with + * WSS or if it is set separately by the TSR loaded on boot. Currently it is + * only set by PCem config and then saved to EEPROM (which would make it fixed + * if loading from EEPROM too). + * -Related to the previous note, part of the SBPROV2 emulation on the CLINTON + * family appears to be implemented with a TSR. It's better to remove the TSR + * for now. I need to investigate this. Mixer is also weird under DOS (and + * wants to save to EEPROM? I don't think the WASHINGTON does this). + * -VOLSET.EXE /S:S is supposed to be a no-op on the MMP16AB? + * -Search for TODO in this file. :-) + * + * Misc things I use to test for regressions: Windows sounds, Descent under + * dos/windows, Descent 2 dos/windows (+ cd music option), Descent 2 W95 + cd + * music, Age of Empires (CD + Midi), cd-audio under Windows + volume, + * cd-audio under dos + volume, Aztech diagnose.exe, Aztech volset /M:3 then + * volset /D, Aztech setmode, mixer (volume + balance) under dos and windows, + * DOSQuake under dos and windows (+ cd music and volumes, + Winquake). + * + * Reason for Descent 2 Win95 CD-Audio not working: + * The game calls auxGetNumDevs() to check if any of the AUX devices has + * caps.wTechnology == AUXCAPS_CDAUDIO, but this fails because the Aztech + * Win95 driver only returns a "Line-In" device. I'm not aware of any other + * game that does this and this is completely unnecessary. Other games that + * play cd audio correctly have the exact *same* initialization code, minus + * this check that only Descent 2 Win95 does. It would work if it just skipped + * this check and progressed with calling mciSendCommand() with + * mciOpenParms.lpstrDeviceType = "cdaudio", like other games do. There are + * some sound cards listed as incompatible in the game's README.TXT file that + * are probably due to this. + */ + +#include +#include +#include "ibm.h" + +#include "device.h" +#include "dma.h" +#include "io.h" +#include "nvr.h" +#include "pic.h" +#include "sound.h" +#include "sound_ad1848.h" +#include "sound_azt2316a.h" +#include "sound_opl.h" +#include "sound_sb.h" +#include "sound_sb_dsp.h" + +/*530, 11, 3 - 530=23*/ +/*530, 11, 1 - 530=22*/ +/*530, 11, 0 - 530=21*/ +/*530, 10, 1 - 530=1a*/ +/*530, 10, 0 - 530=19*/ +/*530, 9, 1 - 530=12*/ +/*530, 7, 1 - 530=0a*/ +/*604, 11, 1 - 530=22*/ +/*e80, 11, 1 - 530=22*/ +/*f40, 11, 1 - 530=22*/ + + +static int azt2316a_wss_dma[4] = {0, 0, 1, 3}; +static int azt2316a_wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /* W95 only uses 7-10, others may be wrong */ +//static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; + +typedef struct azt2316a_t +{ + int type; + int wss_interrupt_after_config; + + uint8_t wss_config; + + uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; + + uint8_t cur_irq, cur_dma, opl_emu; // sb + uint8_t cur_wss_enabled, cur_wss_irq, cur_wss_dma; + uint8_t cur_mpu401_irq; + + uint32_t config_word; + uint32_t config_word_unlocked; + + uint8_t cur_mode; + + ad1848_t ad1848; + + sb_t *sb; +} azt2316a_t; + +uint8_t azt2316a_wss_read(uint16_t addr, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; +// pclog("azt2316a_read - addr %04X\n", addr); + // TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to + // 0x530 makes reading from 0x533 return 0x44, but writing 0x50 + // makes this return 0x04. Why? + if (addr & 1) + temp = 4 | (azt2316a->wss_config & 0x40); + else + temp = 4 | (azt2316a->wss_config & 0xC0); +// pclog("return %02X\n", temp); + return temp; +} + +void azt2316a_wss_write(uint16_t addr, uint8_t val, void *p) +{ + int interrupt = 0; + azt2316a_t *azt2316a = (azt2316a_t *)p; +// pclog("azt2316a_write - addr %04X val %02X\n", addr, val); + + if (azt2316a->wss_interrupt_after_config) + if ((azt2316a->wss_config & 0x40) && !(val & 0x40)) // TODO: is this the right edge? + interrupt = 1; + + azt2316a->wss_config = val; + azt2316a->cur_wss_dma = azt2316a_wss_dma[val & 3]; + azt2316a->cur_wss_irq = azt2316a_wss_irq[(val >> 3) & 7]; + ad1848_setdma(&azt2316a->ad1848, azt2316a_wss_dma[val & 3]); + ad1848_setirq(&azt2316a->ad1848, azt2316a_wss_irq[(val >> 3) & 7]); + + if (interrupt) + picint(1 << azt2316a->cur_wss_irq); +} + +// generate a config word based on current settings +void azt1605_create_config_word(void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint32_t temp = 0; + + // not implemented / hardcoded + uint8_t game_enable = 1; + uint8_t mpu401_enable = 1; + uint8_t cd_type = 0; // TODO: see if the cd-rom was originally connected there on the real machines emulated by PCem (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) + uint8_t cd_dma8 = -1; + uint8_t cd_irq = 0; + + switch (azt2316a->cur_addr) + { + case 0x220: + // do nothing + //temp += 0 << 0; + break; + case 0x240: + temp += 1 << 0; + break; +/* + case 0x260: // TODO: INVALID? + temp += 2 << 0; + break; + case 0x280: // TODO: INVALID? + temp += 3 << 0; + break; +*/ + default: + fatal("Bad AZT1605 addr %04X\n", azt2316a->cur_addr); + } + switch (azt2316a->cur_irq) + { + case 2: + temp += 1 << 8; + break; + case 3: + temp += 1 << 9; + break; + case 5: + temp += 1 << 10; + break; + case 7: + temp += 1 << 11; + break; + default: + fatal("Bad AZT1605 irq %02X\n", azt2316a->cur_irq); + } + switch (azt2316a->cur_wss_addr) + { + case 0x530: + // do nothing + //temp += 0 << 16; + break; + case 0x604: + temp += 1 << 16; + break; + case 0xE80: + temp += 2 << 16; + break; + case 0xF40: + temp += 3 << 16; + break; + default: + fatal("Bad AZT1605 WSS addr %04X\n", azt2316a->cur_wss_addr); + } + if (azt2316a->cur_wss_enabled) + temp += 1 << 18; + if (game_enable) + temp += 1 << 4; + switch (azt2316a->cur_mpu401_addr) + { + case 0x300: + // do nothing + //temp += 0 << 2; + break; + case 0x330: + temp += 1 << 2; + break; + default: + fatal("Bad AZT1605 MPU401 addr %04X\n", azt2316a->cur_mpu401_addr); + } + if (mpu401_enable) + temp += 1 << 3; + switch (cd_type) + { + case 0: // disabled + // do nothing + //temp += 0 << 5; + break; + case 1: // panasonic + temp += 1 << 5; + break; + case 2: // mitsumi/sony/aztech + temp += 2 << 5; + break; + case 3: // all enabled + temp += 3 << 5; + break; + case 4: // unused + temp += 4 << 5; + break; + case 5: // unused + temp += 5 << 5; + break; + case 6: // unused + temp += 6 << 5; + break; + case 7: // unused + temp += 7 << 5; + break; + default: + fatal("Bad AZT1605 CD type %02X\n", cd_type); + } + switch (cd_dma8) + { + case 0xFF: // -1 + // do nothing + //temp += 0 << 22; + break; + case 0: + temp += 1 << 22; + break; + case 1: + temp += 2 << 22; + break; + case 3: + temp += 3 << 22; + break; + default: + fatal("Bad AZT1605 cd dma8 %02X\n", cd_dma8); + + } + switch (azt2316a->cur_mpu401_irq) + + { + case 2: + temp += 1 << 12; + break; + case 3: + temp += 1 << 13; + break; + case 5: + temp += 1 << 14; + break; + case 7: + temp += 1 << 15; + break; + default: + fatal("Bad AZT1605 mpu401 irq %02X\n", azt2316a->cur_mpu401_irq); + } + switch (cd_irq) + { + case 0: // disabled + // do nothing + break; + case 11: + temp += 1 << 19; + break; + case 12: + temp += 1 << 20; + break; + case 15: + temp += 1 << 21; + break; + default: + fatal("Bad AZT1605 cd irq %02X\n", cd_irq); + } + + azt2316a->config_word = temp; +} +void azt2316a_create_config_word(void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint32_t temp = 0; + + // not implemented / hardcoded + uint8_t game_enable = 1; + uint8_t mpu401_enable = 1; + uint16_t cd_addr = 0x310; + uint8_t cd_type = 0; // TODO: see if the cd-rom was originally connected there on the real machines emulated by PCem (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) + uint8_t cd_dma8 = -1; + uint8_t cd_dma16 = -1; + uint8_t cd_irq = 15; + + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) + { + azt1605_create_config_word(p); + return; + } + + switch (azt2316a->cur_addr) + { + case 0x220: + // do nothing + //temp += 0 << 0; + break; + case 0x240: + temp += 1 << 0; + break; +/* + case 0x260: // TODO: INVALID? + temp += 2 << 0; + break; + case 0x280: // TODO: INVALID? + temp += 3 << 0; + break; +*/ + default: + fatal("Bad AZT2316A addr %04X\n", azt2316a->cur_addr); + } + switch (azt2316a->cur_irq) + { + case 2: + temp += 1 << 2; + break; + case 5: + temp += 1 << 3; + break; + case 7: + temp += 1 << 4; + break; + case 10: + temp += 1 << 5; + break; + default: + fatal("Bad AZT2316A irq %02X\n", azt2316a->cur_irq); + } + switch (azt2316a->cur_dma) + { +/* + // TODO: INVALID? + case 0xFF: // -1 + // do nothing + //temp += 0 << 6; + break; +*/ + case 0: + temp += 1 << 6; + break; + case 1: + temp += 2 << 6; + break; + case 3: + temp += 3 << 6; + break; + default: + fatal("Bad AZT2316A dma %02X\n", azt2316a->cur_dma); + } + switch (azt2316a->cur_wss_addr) + { + case 0x530: + // do nothing + //temp += 0 << 8; + break; + case 0x604: + temp += 1 << 8; + break; + case 0xE80: + temp += 2 << 8; + break; + case 0xF40: + temp += 3 << 8; + break; + default: + fatal("Bad AZT2316A WSS addr %04X\n", azt2316a->cur_wss_addr); + } + if (azt2316a->cur_wss_enabled) + temp += 1 << 10; + if (game_enable) + temp += 1 << 11; + switch (azt2316a->cur_mpu401_addr) + { + case 0x300: + // do nothing + //temp += 0 << 12; + break; + case 0x330: + temp += 1 << 12; + break; + default: + fatal("Bad AZT2316A MPU401 addr %04X\n", azt2316a->cur_mpu401_addr); + } + if (mpu401_enable) + temp += 1 << 13; + switch (cd_addr) + { + case 0x310: + // do nothing + //temp += 0 << 14; + break; + case 0x320: + temp += 1 << 14; + break; + case 0x340: + temp += 2 << 14; + break; + case 0x350: + temp += 3 << 14; + break; + default: + fatal("Bad AZT2316A CD addr %04X\n", cd_addr); + } + switch (cd_type) + { + case 0: // disabled + // do nothing + //temp += 0 << 16; + break; + case 1: // panasonic + temp += 1 << 16; + break; + case 2: // sony + temp += 2 << 16; + break; + case 3: // mitsumi + temp += 3 << 16; + break; + case 4: // aztech + temp += 4 << 16; + break; + case 5: // unused + temp += 5 << 16; + break; + case 6: // unused + temp += 6 << 16; + break; + case 7: // unused + temp += 7 << 16; + break; + default: + fatal("Bad AZT2316A CD type %02X\n", cd_type); + } + switch (cd_dma8) + { + case 0xFF: // -1 + // do nothing + //temp += 0 << 20; + break; + case 0: + temp += 1 << 20; + break; +/* + case 1: // TODO: INVALID? + temp += 2 << 20; + break; +*/ + case 3: + temp += 3 << 20; + break; + default: + fatal("Bad AZT2316A cd dma8 %02X\n", cd_dma8); + } + switch (cd_dma16) + { + case 0xFF: // -1 + // do nothing + //temp += 0 << 22; + break; + case 5: + temp += 1 << 22; + break; + case 6: + temp += 2 << 22; + break; + case 7: + temp += 3 << 22; + break; + default: + fatal("Bad AZT2316A cd dma16 %02X\n", cd_dma16); + } + switch (azt2316a->cur_mpu401_irq) + + { + case 2: + temp += 1 << 24; + break; + case 5: + temp += 1 << 25; + break; + case 7: + temp += 1 << 26; + break; + case 10: + temp += 1 << 27; + break; + default: + fatal("Bad AZT2316A mpu401 irq %02X\n", azt2316a->cur_mpu401_irq); + } + switch (cd_irq) + { + case 5: + temp += 1 << 28; + break; + case 11: + temp += 1 << 29; + break; + case 12: + temp += 1 << 30; + break; + case 15: + temp += 1 << 31; + break; + default: + fatal("Bad AZT2316A cd irq %02X\n", cd_irq); + } + + azt2316a->config_word = temp; +} + +uint8_t azt2316a_config_read(uint16_t addr, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; +// pclog("azt2316a_config_read - addr %04X\n", addr); + + // Some WSS config here + config change enable bit + // (setting bit 7 and writing back) + if (addr == azt2316a->cur_addr + 0x404) + { + // TODO: what is the real meaning of the read value? + // I got a mention of bit 0x10 for WSS from disassembling the source + // code of the driver, and when playing with the I/O ports on real + // hardware after doing some configuration, but didn't dig into it. + // Bit 0x08 seems to be a busy flag and generates a timeout + // (continuous re-reading when initializing windows 98) + temp = azt2316a->cur_mode ? 0x07 : 0x0F; + if (azt2316a->config_word_unlocked) + temp |= 0x80; + } + else + { + // Rest of config. These are documented in the Linux driver. + switch (addr & 0x3) + { + case 0: + temp = azt2316a->config_word & 0xFF; + break; + case 1: + temp = (azt2316a->config_word >> 8) & 0xFF; + break; + case 2: + temp = (azt2316a->config_word >> 16) & 0xFF; + break; + case 3: + temp = (azt2316a->config_word >> 24) & 0xFF; + break; + } + } + +// pclog("return %02X\n", temp); + return temp; +} + +void azt1605_config_write(uint16_t addr, uint8_t val, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; +// pclog("azt2316a_config_write - addr %04X val %02X\n", addr, val); + + if (addr == azt2316a->cur_addr + 0x404) + { + if (val & 0x80) + azt2316a->config_word_unlocked = 1; + else + azt2316a->config_word_unlocked = 0; + } + else if (azt2316a->config_word_unlocked) + { + if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! + return; + switch (addr & 0x3) + { + case 0: + azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) + val; + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_addr = 0x220; + else if (temp == 1) + azt2316a->cur_addr = 0x240; +/* + else if (temp == 2) + azt2316a->cur_addr = 0x260; // TODO: INVALID + else if (temp == 3) + azt2316a->cur_addr = 0x280; // TODO: INVALID +*/ + + if (val & 0x4) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + // mpu401_enabled is harcoded + //if (val & 0x8) + // azt2316a->cur_mpu401_enabled = 1; + //else + // azt2316a->cur_mpu401_enabled = 0; + + // game_enabled is hardcoded + //if (val & 0x10) + // azt2316a->cur_game_enabled = 1; + //else + // azt2316a->cur_game_enabled = 0; + + // cd_type is hardcoded + //azt2316a->cur_cd_type = (val >> 5) & 0x7; + break; + case 1: + azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) + (val << 8); + + if (val & 0x1) + azt2316a->cur_irq = 2; + else if (val & 0x2) + azt2316a->cur_irq = 3; + else if (val & 0x4) + azt2316a->cur_irq = 5; + else if (val & 0x8) + azt2316a->cur_irq = 7; + // else undefined? + + if (val & 0x10) + azt2316a->cur_mpu401_irq = 2; + else if (val & 0x20) + azt2316a->cur_mpu401_irq = 3; + else if (val & 0x40) + azt2316a->cur_mpu401_irq = 5; + else if (val & 0x80) + azt2316a->cur_mpu401_irq = 7; + // else undefined? + break; + case 2: + azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) + (val << 16); + + io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_wss_addr = 0x530; + else if (temp == 1) + azt2316a->cur_wss_addr = 0x604; + else if (temp == 2) + azt2316a->cur_wss_addr = 0xE80; + else if (temp == 3) + azt2316a->cur_wss_addr = 0xF40; + + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + // no actual effect + if (val & 0x4) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; + + // cd_irq is hardcoded + //if (val & 0x8) + // azt2316a->cur_cd_irq = 11; + //else if (val & 0x10) + // azt2316a->cur_cd_irq = 12; + //else if (val & 0x20) + // azt2316a->cur_cd_irq = 15; + // else disable? + + // cd_dma8 is hardcoded + //temp = (val >> 6) & 0x3; + //if (temp == 0) + // azt2316a->cur_cd_dma8 = -1; + //else if (temp == 1) + // azt2316a->cur_cd_dma8 = 0; + //else if (temp == 3) + // azt2316a->cur_cd_dma8 = 3; + //else error + break; + case 3: + break; + } + // update sbprov2 configs + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + + mpu401_uart_update_addr(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr); + mpu401_uart_update_irq(&azt2316a->sb->mpu, azt2316a->cur_mpu401_irq); + } +} +void azt2316a_config_write(uint16_t addr, uint8_t val, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; +// pclog("azt2316a_config_write - addr %04X val %02X\n", addr, val); + + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) + { + azt1605_config_write(addr, val, p); + return; + } + + if (addr == azt2316a->cur_addr + 0x404) + { + if (val & 0x80) + azt2316a->config_word_unlocked = 1; + else + azt2316a->config_word_unlocked = 0; + } + else if (azt2316a->config_word_unlocked) + { + if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! + return; + switch (addr & 0x3) + { + case 0: + azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) + val; + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_addr = 0x220; + else if (temp == 1) + azt2316a->cur_addr = 0x240; +/* + else if (temp == 2) + azt2316a->cur_addr = 0x260; // TODO: INVALID + else if (temp == 3) + azt2316a->cur_addr = 0x280; // TODO: INVALID +*/ + + if (val & 0x4) + azt2316a->cur_irq = 2; + else if (val & 0x8) + azt2316a->cur_irq = 5; + else if (val & 0x10) + azt2316a->cur_irq = 7; + else if (val & 0x20) + azt2316a->cur_irq = 10; + // else undefined? + + temp = (val >> 6) & 0x3; +/* + if (temp == 0) + azt2316a->cur_dma = -1; // TODO: INVALID? + else */if (temp == 1) + azt2316a->cur_dma = 0; + else if (temp == 2) + azt2316a->cur_dma = 1; + else if (temp == 3) + azt2316a->cur_dma = 3; + break; + case 1: + azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) + (val << 8); + + io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_wss_addr = 0x530; + else if (temp == 1) + azt2316a->cur_wss_addr = 0x604; + else if (temp == 2) + azt2316a->cur_wss_addr = 0xE80; + else if (temp == 3) + azt2316a->cur_wss_addr = 0xF40; + + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + // no actual effect + if (val & 0x4) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; + + // game_enabled is hardcoded + //if (val & 0x8) + // azt2316a->cur_game_enabled = 1; + //else + // azt2316a->cur_game_enabled = 0; + + if (val & 0x10) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + // mpu401_enabled is harcoded + //if (val & 0x20) + // azt2316a->cur_mpu401_enabled = 1; + //else + // azt2316a->cur_mpu401_enabled = 0; + + // cd_addr is hardcoded + //temp = (val >> 6) & 0x3; + //if (temp == 0) + // azt2316a->cur_cd_addr = 0x310; + //else if (temp == 1) + // azt2316a->cur_cd_addr = 0x320; + //else if (temp == 2) + // azt2316a->cur_cd_addr = 0x340; + //else if (temp == 3) + // azt2316a->cur_cd_addr = 0x350; + break; + case 2: + azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) + (val << 16); + + // cd_type is hardcoded + //azt2316a->cur_cd_type = val & 0x7; + + // cd_dma8 is hardcoded + //temp = (val >> 4) & 0x3; + //if (temp == 0) + // azt2316a->cur_cd_dma8 = -1; + //else if (temp == 1) + // azt2316a->cur_cd_dma8 = 0; + //else if (temp == 2) + // azt2316a->cur_cd_dma8 = 1; + //else if (temp == 3) + // azt2316a->cur_cd_dma8 = 3; + + // cd_dma16 is hardcoded + //temp = (val >> 6) & 0x3; + //if (temp == 0) + // azt2316a->cur_cd_dma16 = -1; + //else if (temp == 1) + // azt2316a->cur_cd_dma16 = 5; + //else if (temp == 2) + // azt2316a->cur_cd_dma16 = 6; + //else if (temp == 3) + // azt2316a->cur_cd_dma16 = 7; + break; + case 3: + azt2316a->config_word = (azt2316a->config_word & 0x00FFFFFF) + (val << 24); + + if (val & 0x1) + azt2316a->cur_mpu401_irq = 2; + else if (val & 0x2) + azt2316a->cur_mpu401_irq = 5; + else if (val & 0x4) + azt2316a->cur_mpu401_irq = 7; + else if (val & 0x8) + azt2316a->cur_mpu401_irq = 10; + // else undefined? + + // cd_irq is hardcoded + //if (val & 0x10) + // azt2316a->cur_cd_irq = 5; + //else if (val & 0x20) + // azt2316a->cur_cd_irq = 11; + //else if (val & 0x40) + // azt2316a->cur_cd_irq = 12; + //else if (val & 0x80) + // azt2316a->cur_cd_irq = 15; + // else undefined? + break; + } + // update sbprov2 configs + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + + mpu401_uart_update_addr(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr); + mpu401_uart_update_irq(&azt2316a->sb->mpu, azt2316a->cur_mpu401_irq); + } +} + +// How it behaves when one or another is activated may affect games auto-detecting (and will also use more of the limited system resources!) +void azt2316a_enable_wss(uint8_t enable, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + + if (enable) + { + azt2316a->cur_mode = 1; + if (!azt2316a->cur_wss_enabled) + { +// apparently it doesn't work like this! +// azt2316a->cur_wss_enabled = 1; +// azt2316a->config_word |= 1 << 10; + } + } + else + { + azt2316a->cur_mode = 0; + if (azt2316a->cur_wss_enabled) + { +// apparently it doesn't work like this! +// azt2316a->cur_wss_enabled = 0; +// azt2316a->config_word &= 0xFFFFFFFF - (1 << 10); + } + } +} + +static void azt2316a_get_buffer(int32_t *buffer, int len, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + + int c; + + // wss part + ad1848_update(&azt2316a->ad1848); + for (c = 0; c < len * 2; c++) + { + buffer[c] += (azt2316a->ad1848.buffer[c] / 2); + } + + azt2316a->ad1848.pos = 0; + + // sbprov2 part + sb_get_buffer_sbpro(buffer, len, azt2316a->sb); +} + +void *azt_common_init(const int type, char *nvr_filename) +{ + int i; + int loaded_from_eeprom = 0; + uint16_t addr_setting; + uint8_t read_eeprom[AZTECH_EEPROM_SIZE]; + azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); + memset(azt2316a, 0, sizeof(azt2316a_t)); + + // load configs from eeprom + FILE *f; + f = nvrfopen(nvr_filename, "rb"); + if (f) + { + uint8_t checksum = 0x7F; + uint8_t saved_checksum; + size_t res; // avoid warning + + res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, f); + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + checksum += read_eeprom[i]; + + res = fread(&saved_checksum, sizeof(saved_checksum), 1, f); + (void)res; + + fclose(f); + + if (checksum == saved_checksum) + loaded_from_eeprom = 1; + } + + // no eeprom saved or invalid checksum, load defaults + if (!loaded_from_eeprom) + { + if (type == SB_SUBTYPE_CLONE_AZT2316A_0X11) + { + read_eeprom[0] = 0x00; + read_eeprom[1] = 0x00; + read_eeprom[2] = 0x00; + read_eeprom[3] = 0x00; + read_eeprom[4] = 0x00; + read_eeprom[5] = 0x00; + read_eeprom[6] = 0x00; + read_eeprom[7] = 0x00; + read_eeprom[8] = 0x00; + read_eeprom[9] = 0x00; + read_eeprom[10] = 0x00; + read_eeprom[11] = 0x88; + read_eeprom[12] = 0xbc; + read_eeprom[13] = 0x00; + read_eeprom[14] = 0x01; + read_eeprom[15] = 0x00; + } + else if (type == SB_SUBTYPE_CLONE_AZT1605_0X0C) + { + read_eeprom[0] = 0x80; + read_eeprom[1] = 0x80; + read_eeprom[2] = 0x9F; + read_eeprom[3] = 0x13; + read_eeprom[4] = 0x16; + read_eeprom[5] = 0x13; + read_eeprom[6] = 0x00; + read_eeprom[7] = 0x00; + read_eeprom[8] = 0x16; + read_eeprom[9] = 0x0B; + read_eeprom[10] = 0x06; + read_eeprom[11] = 0x01; + read_eeprom[12] = 0x1C; + read_eeprom[13] = 0x14; + read_eeprom[14] = 0x04; + read_eeprom[15] = 0x1C; + } + else + fatal("Aztech: unknown type %d\n", type); + } + + // restore settings from EEPROM bytes + if (type == SB_SUBTYPE_CLONE_AZT2316A_0X11) + { + azt2316a->config_word = read_eeprom[11] + (read_eeprom[12] << 8) + (read_eeprom[13] << 16) + (read_eeprom[14] << 24); + switch (azt2316a->config_word & (3 << 0)) + { + case 0: + azt2316a->cur_addr = 0x220; + break; + case 1: + azt2316a->cur_addr = 0x240; + break; + default: + fatal("AZT2316A: invalid sb addr in config word %08X\n", azt2316a->config_word); + } + + if (azt2316a->config_word & (1 << 2)) + azt2316a->cur_irq = 2; + else if (azt2316a->config_word & (1 << 3)) + azt2316a->cur_irq = 5; + else if (azt2316a->config_word & (1 << 4)) + azt2316a->cur_irq = 7; + else if (azt2316a->config_word & (1 << 5)) + azt2316a->cur_irq = 10; + else + fatal("AZT2316A: invalid sb irq in config word %08X\n", azt2316a->config_word); + + switch (azt2316a->config_word & (3 << 6)) + { + case 1 << 6: + azt2316a->cur_dma = 0; + break; + case 2 << 6: + azt2316a->cur_dma = 1; + break; + case 3 << 6: + azt2316a->cur_dma = 3; + break; + default: + fatal("AZT2316A: invalid sb dma in config word %08X\n", azt2316a->config_word); + } + + switch (azt2316a->config_word & (3 << 8)) + { + case 0: + azt2316a->cur_wss_addr = 0x530; + break; + case 1 << 8: + azt2316a->cur_wss_addr = 0x604; + break; + case 2 << 8: + azt2316a->cur_wss_addr = 0xE80; + break; + case 3 << 8: + azt2316a->cur_wss_addr = 0xF40; + break; + default: + fatal("AZT2316A: invalid wss addr in config word %08X\n", azt2316a->config_word); + } + + if (azt2316a->config_word & (1 << 10)) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; + + // game_enabled is hardcoded + //if (azt2316a->config_word & (1 << 11)) + // azt2316a->cur_game_enabled = 1; + //else + // azt2316a->cur_game_enabled = 0; + + if (azt2316a->config_word & (1 << 12)) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + // mpu401_enabled is hardcoded + //if (azt2316a->config_word & (1 << 13)) + // azt2316a->cur_mpu401_enabled = 1; + //else + // azt2316a->cur_mpu401_enabled = 0; + + // cd_addr is hardcoded + //switch (azt2316a->config_word & (3 << 14)) + //{ + // case 0: + // azt2316a->cur_cd_addr = 0x310; + // break; + // case 1 << 14: + // azt2316a->cur_cd_addr = 0x320; + // break; + // case 2 << 14: + // azt2316a->cur_cd_addr = 0x340; + // break; + // case 3 << 14: + // azt2316a->cur_cd_addr = 0x350; + // break; + // default: + // fatal("AZT2316A: invalid cd addr in config word %08X\n", azt2316a->config_word); + //} + + // cd_type is hardcoded + //azt2316a->cur_cd_type = (azt2316a->config_word >> 16) & 0x7; + + // cd_dma8 is hardcoded + //switch (azt2316a->config_word & (3 << 20)) + //{ + // case 0: + // azt2316a->cur_cd_dma8 = -1; + // break; + // case 1 << 20: + // azt2316a->cur_cd_dma8 = 0; + // break; + // case 2 << 20: + // azt2316a->cur_cd_dma8 = 1; + // break; + // case 3 << 20: + // azt2316a->cur_cd_dma8 = 3; + // break; + // default: + // fatal("AZT2316A: invalid cd dma8 in config word %08X\n", azt2316a->config_word); + //} + + // cd_dma16 is hardcoded + //switch (azt2316a->config_word & (3 << 22)) + //{ + // case 0: + // azt2316a->cur_cd_dma16 = -1; + // break; + // case 1 << 22: + // azt2316a->cur_cd_dma16 = 5; + // break; + // case 2 << 22: + // azt2316a->cur_cd_dma16 = 6; + // break; + // case 3 << 22: + // azt2316a->cur_cd_dma16 = 7; + // break; + // default: + // fatal("AZT2316A: invalid cd dma16 in config word %08X\n", azt2316a->config_word); + //} + + if (azt2316a->config_word & (1 << 24)) + azt2316a->cur_mpu401_irq = 2; + else if (azt2316a->config_word & (1 << 25)) + azt2316a->cur_mpu401_irq = 5; + else if (azt2316a->config_word & (1 << 26)) + azt2316a->cur_mpu401_irq = 7; + else if (azt2316a->config_word & (1 << 27)) + azt2316a->cur_mpu401_irq = 10; + else + fatal("AZT2316A: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); + + // cd_irq is hardcoded + //if (azt2316a->config_word & (1 << 28)) + // azt2316a->cur_cd_irq = 5; + //else if (azt2316a->config_word & (1 << 29)) + // azt2316a->cur_cd_irq = 11; + //else if (azt2316a->config_word & (1 << 30)) + // azt2316a->cur_cd_irq = 12; + //else if (azt2316a->config_word & (1 << 31)) + // azt2316a->cur_cd_irq = 15; + //else + // fatal("AZT2316A: invalid cd irq in config word %08X\n", azt2316a->config_word); + + // these are not present on the EEPROM + azt2316a->cur_wss_irq = 10; + azt2316a->cur_wss_dma = 0; + azt2316a->cur_mode = 0; + } + else if (type == SB_SUBTYPE_CLONE_AZT1605_0X0C) + { + azt2316a->config_word = read_eeprom[12] + (read_eeprom[13] << 8) + (read_eeprom[14] << 16); + switch (azt2316a->config_word & (3 << 0)) + { + case 0: + azt2316a->cur_addr = 0x220; + break; + case 1: + azt2316a->cur_addr = 0x240; + break; + default: + fatal("AZT1605: invalid sb addr in config word %08X\n", azt2316a->config_word); + } + + if (azt2316a->config_word & (1 << 2)) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + // mpu401_enabled is hardcoded + //if (azt2316a->config_word & (1 << 3)) + // azt2316a->cur_mpu401_enabled = 1; + //else + // azt2316a->cur_mpu401_enabled = 0; + + // game_enabled is hardcoded + //if (azt2316a->config_word & (1 << 4)) + // azt2316a->cur_game_enabled = 1; + //else + // azt2316a->cur_game_enabled = 0; + + // cd_type is hardcoded + //azt2316a->cur_cd_type = (azt2316a->config_word >> 5) & 0x7; + + if (azt2316a->config_word & (1 << 8)) + azt2316a->cur_irq = 2; + else if (azt2316a->config_word & (1 << 9)) + azt2316a->cur_irq = 3; + else if (azt2316a->config_word & (1 << 10)) + azt2316a->cur_irq = 5; + else if (azt2316a->config_word & (1 << 11)) + azt2316a->cur_irq = 7; + else + fatal("AZT1605: invalid sb irq in config word %08X\n", azt2316a->config_word); + + if (azt2316a->config_word & (1 << 12)) + azt2316a->cur_mpu401_irq = 2; + else if (azt2316a->config_word & (1 << 13)) + azt2316a->cur_mpu401_irq = 3; + else if (azt2316a->config_word & (1 << 14)) + azt2316a->cur_mpu401_irq = 5; + else if (azt2316a->config_word & (1 << 15)) + azt2316a->cur_mpu401_irq = 7; + else + fatal("AZT1605: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); + + switch (azt2316a->config_word & (3 << 16)) + { + case 0: + azt2316a->cur_wss_addr = 0x530; + break; + case 1 << 16: + azt2316a->cur_wss_addr = 0x604; + break; + case 2 << 16: + azt2316a->cur_wss_addr = 0xE80; + break; + case 3 << 16: + azt2316a->cur_wss_addr = 0xF40; + break; + default: + fatal("AZT1605: invalid wss addr in config word %08X\n", azt2316a->config_word); + } + + if (azt2316a->config_word & (1 << 18)) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; + + // cd_irq is hardcoded + //if (azt2316a->config_word & (1 << 19)) + // azt2316a->cur_cd_irq = 11; + //else if (azt2316a->config_word & (1 << 20)) + // azt2316a->cur_cd_irq = 12; + //else if (azt2316a->config_word & (1 << 21)) + // azt2316a->cur_cd_irq = 15; + //else + // fatal("AZT1605: invalid cd irq in config word %08X\n", azt2316a->config_word); + + // cd_dma8 is hardcoded + //switch (azt2316a->config_word & (3 << 22)) + //{ + // case 0: + // azt2316a->cur_cd_dma8 = -1; + // break; + // case 1 << 22: + // azt2316a->cur_cd_dma8 = 0; + // break; + // case 2 << 22: + // azt2316a->cur_cd_dma8 = 1; + // break; + // case 3 << 22: + // azt2316a->cur_cd_dma8 = 3; + // break; + // default: + // fatal("AZT1605: invalid cd dma8 in config word %08X\n", azt2316a->config_word); + //} + + // these are not present on the EEPROM + azt2316a->cur_dma = 1; // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? + azt2316a->cur_wss_irq = 10; + azt2316a->cur_wss_dma = 0; + azt2316a->cur_mode = 0; + } + else + fatal("Aztech: unknown type %d\n", type); + + // check for sb addr override jumper + addr_setting = device_get_config_int("addr"); + if (addr_setting) + azt2316a->cur_addr = addr_setting; + + // now we can continue initializing + azt2316a->opl_emu = device_get_config_int("opl_emu"); + azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); + + azt2316a->type = type; + + // wss part + ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); + + ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); + ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); + + io_sethandler(azt2316a->cur_addr + 0x0400, 0x0040, azt2316a_config_read, NULL, NULL, azt2316a_config_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + + // sbprov2 part + /*sbpro port mappings. 220h or 240h. + 2x0 to 2x3 -> FM chip (18 voices) + 2x4 to 2x5 -> Mixer interface + 2x6, 2xA, 2xC, 2xE -> DSP chip + + 2x8, 2x9, 388 and 389 FM chip (9 voices).*/ + azt2316a->sb = malloc(sizeof(sb_t)); + memset(azt2316a->sb, 0, sizeof(sb_t)); + + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + azt2316a->sb->dsp.azt_eeprom[i] = read_eeprom[i]; + + azt2316a->sb->opl_emu = azt2316a->opl_emu; + opl3_init(&azt2316a->sb->opl, azt2316a->sb->opl_emu); + sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + sb_ct1345_mixer_reset(azt2316a->sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + io_sethandler(azt2316a->cur_addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(azt2316a->cur_addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(azt2316a->cur_addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, azt2316a->sb); + mpu401_uart_init(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq); + + azt2316a_create_config_word(azt2316a); // recreate even if we have read it from EEPROM, because we have some overrides (CD interfaces always off, etc) + sound_add_handler(azt2316a_get_buffer, azt2316a); + + return azt2316a; +} + +void *azt2316a_init() +{ + return azt_common_init(SB_SUBTYPE_CLONE_AZT2316A_0X11, "azt2316a.nvr"); +} + +void *azt1605_init() +{ + return azt_common_init(SB_SUBTYPE_CLONE_AZT1605_0X0C, "azt1605.nvr"); +} + +void azt_common_close(void *p, char *nvr_filename) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + int i; + uint8_t checksum = 0x7F; + + // always save to eeprom (recover from bad values) + FILE *f = nvrfopen(nvr_filename, "wb"); + if (f) + { + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + checksum += azt2316a->sb->dsp.azt_eeprom[i]; + fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, f); + + // TODO: confirm any models saving mixer settings to EEPROM and implement reading back + // TODO: should remember to save wss duplex setting if PCem has voice recording implemented in the future? Also, default azt2316a->wss_config + // TODO: azt2316a->cur_mode is not saved to EEPROM? + fwrite(&checksum, sizeof(checksum), 1, f); + + fclose(f); + } + + sb_close(azt2316a->sb); + + free(azt2316a); +} + +void azt2316a_close(void *p) +{ + azt_common_close(p, "azt2316a.nvr"); +} + +void azt1605_close(void *p) +{ + azt_common_close(p, "azt1605.nvr"); +} + +void azt2316a_speed_changed(void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + + ad1848_speed_changed(&azt2316a->ad1848); + sb_speed_changed(azt2316a->sb); +} + +void azt2316a_add_status_info(char *s, int max_len, void *p) +{ + azt2316a_t *azt2316a = (azt2316a_t *)p; + + sb_dsp_add_status_info(s, max_len, &azt2316a->sb->dsp); +} + +static device_config_t azt2316a_config[] = +{ + { + .name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "CS4248", + .value = AD1848_TYPE_CS4248 + }, + { + .description = "CS4231", + .value = AD1848_TYPE_CS4231 + }, + }, + .default_int = AD1848_TYPE_CS4248 + }, + { + .name = "wss_interrupt_after_config", + .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "addr", + .description = "SB Address", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x220", + .value = 0x220 + }, + { + .description = "0x240", + .value = 0x240 + }, + { + .description = "Use EEPROM setting", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .name = "midi", + .description = "MIDI out device", + .type = CONFIG_MIDI, + .default_int = 0 + }, + { + .name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DBOPL", + .value = OPL_DBOPL + }, + { + .description = "NukedOPL", + .value = OPL_NUKED + }, + }, + .default_int = OPL_DBOPL + }, + { + .type = -1 + } +}; + +device_t azt2316a_device = +{ + "Aztech Sound Galaxy Pro 16 AB (Washington)", + 0, + azt2316a_init, + azt2316a_close, + NULL, + azt2316a_speed_changed, + NULL, + azt2316a_add_status_info, + azt2316a_config +}; + +device_t azt1605_device = +{ + "Aztech Sound Galaxy Nova 16 Extra (Clinton)", + DEVICE_NOT_WORKING, + azt1605_init, + azt1605_close, + NULL, + azt2316a_speed_changed, + NULL, + azt2316a_add_status_info, + azt2316a_config +}; diff --git a/src/sound_azt2316a.h b/src/sound_azt2316a.h new file mode 100644 index 0000000..2b7d7fa --- /dev/null +++ b/src/sound_azt2316a.h @@ -0,0 +1,4 @@ +extern device_t azt2316a_device; +extern device_t azt1605_device; + +void azt2316a_enable_wss(uint8_t enable, void *p); diff --git a/src/sound_emu8k.h b/src/sound_emu8k.h index 4094863..85eeea6 100644 --- a/src/sound_emu8k.h +++ b/src/sound_emu8k.h @@ -1,3 +1,5 @@ +#ifndef SOUND_EMU8K_H +#define SOUND_EMU8K_H /* All these defines are in samples, not in bytes. */ #define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF @@ -773,3 +775,5 @@ Treble Parameters: 0xD308 0xD308 0xD308 0xD308 0xD308 0xD308 0xD3019 0xD32A 0xD34C 0xD36E 0xD36E 0xD36E 0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 */ + +#endif /* SOUND_EMU8K_H */ diff --git a/src/sound_mpu401_uart.c b/src/sound_mpu401_uart.c index b75cfa8..6ec3614 100644 --- a/src/sound_mpu401_uart.c +++ b/src/sound_mpu401_uart.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "io.h" +#include "pic.h" #include "plat-midi.h" #include "sound_mpu401_uart.h" @@ -9,6 +10,14 @@ enum STATUS_INPUT_NOT_READY = 0x80 }; +static void mpu401_uart_raise_irq(void *p) +{ + mpu401_uart_t *mpu = (mpu401_uart_t *)p; + + if (mpu->irq != -1) + picint(1 << mpu->irq); +} + static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) { mpu401_uart_t *mpu = (mpu401_uart_t *)p; @@ -18,15 +27,20 @@ static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) switch (val) { case 0xff: /*Reset*/ + // From Roland: "An ACK will not be sent back upon sending a SYSTEM RESET to leave the UART MODE ($3F)." + // But actual behaviour is weird. For example, the MPU401 port test in the AZT1605 drivers for Windows NT + // want this to return an Ack but the IRQ test in the same driver wants this to raise no interrupts! mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = 0; + mpu->status = STATUS_OUTPUT_NOT_READY; mpu->uart_mode = 0; + //mpu401_uart_raise_irq(p); break; case 0x3f: /*Enter UART mode*/ mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = 0; + mpu->status = STATUS_OUTPUT_NOT_READY; mpu->uart_mode = 1; + mpu401_uart_raise_irq(p); break; } return; @@ -45,14 +59,30 @@ static uint8_t mpu401_uart_read(uint16_t addr, void *p) return mpu->status; /*Data*/ - mpu->status |= STATUS_INPUT_NOT_READY; + mpu->status = STATUS_INPUT_NOT_READY; return mpu->rx_data; } -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr) +void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq) { mpu->status = STATUS_INPUT_NOT_READY; mpu->uart_mode = 0; + mpu->addr = addr; + mpu->irq = irq; io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); } + +void mpu401_uart_update_addr(mpu401_uart_t *mpu, uint16_t addr) +{ + io_removehandler(mpu->addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); + mpu->addr = addr; + if (addr != 0) + io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); +} + +void mpu401_uart_update_irq(mpu401_uart_t *mpu, int irq) +{ + mpu->irq = irq; +} + diff --git a/src/sound_mpu401_uart.h b/src/sound_mpu401_uart.h index 91f4119..b133d80 100644 --- a/src/sound_mpu401_uart.h +++ b/src/sound_mpu401_uart.h @@ -1,9 +1,18 @@ +#ifndef SOUND_MPU401_UART +#define SOUND_MPU401_UART + typedef struct mpu401_uart_t { uint8_t status; uint8_t rx_data; - int uart_mode; + int uart_mode; + uint16_t addr; + int irq; } mpu401_uart_t; -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr); +void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq); +void mpu401_uart_update_addr(mpu401_uart_t *mpu, uint16_t addr); +void mpu401_uart_update_irq(mpu401_uart_t *mpu, int irq); + +#endif /* SOUND_MPU401_UART */ diff --git a/src/sound_pas16.c b/src/sound_pas16.c index d55b921..e88ec2e 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -737,7 +737,7 @@ void *pas16_init() memset(pas16, 0, sizeof(pas16_t)); opl3_init(&pas16->opl, 0); - sb_dsp_init(&pas16->dsp, SB2); + sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); diff --git a/src/sound_sb.c b/src/sound_sb.c index 58d0297..e2aa7f3 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -21,102 +21,6 @@ FILE* soundfsb = 0/*NULL*/; FILE* soundfsbin = 0/*NULL*/; #endif - - -/* SB 2.0 CD version */ -typedef struct sb_ct1335_mixer_t -{ - int32_t master; - int32_t voice; - int32_t fm; - int32_t cd; - - uint8_t index; - uint8_t regs[256]; -} sb_ct1335_mixer_t; -/* SB PRO */ -typedef struct sb_ct1345_mixer_t -{ - int32_t master_l, master_r; - int32_t voice_l, voice_r; - int32_t fm_l, fm_r; - int32_t cd_l, cd_r; - int32_t line_l, line_r; - int32_t mic; - /*see sb_ct1745_mixer for values for input selector*/ - int32_t input_selector; - - int input_filter; - int in_filter_freq; - int output_filter; - - int stereo; - int stereo_isleft; - - uint8_t index; - uint8_t regs[256]; - -} sb_ct1345_mixer_t; -/* SB16 and AWE32 */ -typedef struct sb_ct1745_mixer_t -{ - int32_t master_l, master_r; - int32_t voice_l, voice_r; - int32_t fm_l, fm_r; - int32_t cd_l, cd_r; - int32_t line_l, line_r; - int32_t mic; - int32_t speaker; - - int bass_l, bass_r; - int treble_l, treble_r; - - int output_selector; - #define OUTPUT_MIC 1 - #define OUTPUT_CD_R 2 - #define OUTPUT_CD_L 4 - #define OUTPUT_LINE_R 8 - #define OUTPUT_LINE_L 16 - - int input_selector_left; - int input_selector_right; - #define INPUT_MIC 1 - #define INPUT_CD_R 2 - #define INPUT_CD_L 4 - #define INPUT_LINE_R 8 - #define INPUT_LINE_L 16 - #define INPUT_MIDI_R 32 - #define INPUT_MIDI_L 64 - - int mic_agc; - - int32_t input_gain_L; - int32_t input_gain_R; - int32_t output_gain_L; - int32_t output_gain_R; - - uint8_t index; - uint8_t regs[256]; -} sb_ct1745_mixer_t; - -typedef struct sb_t -{ - opl_t opl; - sb_dsp_t dsp; - union { - sb_ct1335_mixer_t mixer_sb2; - sb_ct1345_mixer_t mixer_sbpro; - sb_ct1745_mixer_t mixer_sb16; - }; - mpu401_uart_t mpu; - emu8k_t emu8k; - - int pos; - - uint8_t pos_regs[8]; - - int opl_emu; -} sb_t; /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude-1. */ const float sb_bass_treble_4bits[]= { @@ -195,7 +99,7 @@ static void sb_get_buffer_sb2_mixer(int32_t *buffer, int len, void *p) sb->dsp.pos = 0; } -static void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) +void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p) { sb_t *sb = (sb_t *)p; sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; @@ -950,7 +854,7 @@ void *sb_1_init() memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB1); + sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb); 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")); @@ -972,7 +876,7 @@ void *sb_15_init() memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB15); + sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); 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")); @@ -993,7 +897,7 @@ void *sb_mcv_init() memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB15); + sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, 0);//addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); @@ -1024,7 +928,7 @@ void *sb_2_init() memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB2); + sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); 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")); @@ -1061,7 +965,7 @@ void *sb_pro_v1_init() memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SBPRO); + sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); 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")); @@ -1091,7 +995,7 @@ void *sb_pro_v2_init() uint16_t addr = device_get_config_int("addr"); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SBPRO2); + sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); 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")); @@ -1118,7 +1022,7 @@ void *sb_pro_mcv_init() sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SBPRO2); + sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); /* I/O handlers activated in sb_mcv_write */ sound_add_handler(sb_get_buffer_sbpro, sb); @@ -1139,7 +1043,7 @@ void *sb_16_init() uint16_t addr = device_get_config_int("addr"); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SB16); + sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); // TODO: irq and dma options too? sb_ct1745_mixer_reset(sb); @@ -1148,7 +1052,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_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16, sb); - mpu401_uart_init(&sb->mpu, 0x330); + mpu401_uart_init(&sb->mpu, 0x330, -1); return sb; @@ -1169,7 +1073,7 @@ void *sb_awe32_init() uint16_t emu_addr = device_get_config_int("emu_addr"); sb->opl_emu = device_get_config_int("opl_emu"); opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SB16 + 1); + sb_dsp_init(&sb->dsp, SB16 + 1, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); // TODO: irq and dma options too? sb_ct1745_mixer_reset(sb); @@ -1178,7 +1082,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_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_uart_init(&sb->mpu, 0x330); + mpu401_uart_init(&sb->mpu, 0x330, -1); emu8k_init(&sb->emu8k, emu_addr, onboard_ram); return sb; diff --git a/src/sound_sb.h b/src/sound_sb.h index fb856c8..405bd39 100644 --- a/src/sound_sb.h +++ b/src/sound_sb.h @@ -1,3 +1,10 @@ +#ifndef SOUND_SB_H +#define SOUND_SB_H + +#include "sound_emu8k.h" +#include "sound_mpu401_uart.h" +#include "sound_sb_dsp.h" + extern device_t sb_1_device; extern device_t sb_15_device; extern device_t sb_mcv_device; @@ -7,3 +14,110 @@ 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; + +/* SB 2.0 CD version */ +typedef struct sb_ct1335_mixer_t +{ + int32_t master; + int32_t voice; + int32_t fm; + int32_t cd; + + uint8_t index; + uint8_t regs[256]; +} sb_ct1335_mixer_t; +/* SB PRO */ +typedef struct sb_ct1345_mixer_t +{ + int32_t master_l, master_r; + int32_t voice_l, voice_r; + int32_t fm_l, fm_r; + int32_t cd_l, cd_r; + int32_t line_l, line_r; + int32_t mic; + /*see sb_ct1745_mixer for values for input selector*/ + int32_t input_selector; + + int input_filter; + int in_filter_freq; + int output_filter; + + int stereo; + int stereo_isleft; + + uint8_t index; + uint8_t regs[256]; + +} sb_ct1345_mixer_t; +/* SB16 and AWE32 */ +typedef struct sb_ct1745_mixer_t +{ + int32_t master_l, master_r; + int32_t voice_l, voice_r; + int32_t fm_l, fm_r; + int32_t cd_l, cd_r; + int32_t line_l, line_r; + int32_t mic; + int32_t speaker; + + int bass_l, bass_r; + int treble_l, treble_r; + + int output_selector; + #define OUTPUT_MIC 1 + #define OUTPUT_CD_R 2 + #define OUTPUT_CD_L 4 + #define OUTPUT_LINE_R 8 + #define OUTPUT_LINE_L 16 + + int input_selector_left; + int input_selector_right; + #define INPUT_MIC 1 + #define INPUT_CD_R 2 + #define INPUT_CD_L 4 + #define INPUT_LINE_R 8 + #define INPUT_LINE_L 16 + #define INPUT_MIDI_R 32 + #define INPUT_MIDI_L 64 + + int mic_agc; + + int32_t input_gain_L; + int32_t input_gain_R; + int32_t output_gain_L; + int32_t output_gain_R; + + uint8_t index; + uint8_t regs[256]; +} sb_ct1745_mixer_t; + +typedef struct sb_t +{ + opl_t opl; + sb_dsp_t dsp; + union { + sb_ct1335_mixer_t mixer_sb2; + sb_ct1345_mixer_t mixer_sbpro; + sb_ct1745_mixer_t mixer_sb16; + }; + mpu401_uart_t mpu; + emu8k_t emu8k; + + int pos; + + uint8_t pos_regs[8]; + + int opl_emu; +} sb_t; + +// exported for clone cards +void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p); +void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p); +uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p); +void sb_ct1345_mixer_reset(sb_t* sb); + +void sb_close(void *p); +void sb_speed_changed(void *p); +void sb_add_status_info(char *s, int max_len, void *p); + +#endif /* SOUND_SB_H */ diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 25de3ee..0cf391a 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -10,13 +10,16 @@ #include "ibm.h" +#include "device.h" #include "dma.h" #include "filters.h" #include "io.h" #include "pic.h" #include "sound.h" +#include "sound_azt2316a.h" #include "sound_sb_dsp.h" #include "timer.h" +#include "x86.h" /*The recording safety margin is intended for uneven "len" calls to the get_buffer mixer calls on sound_sb*/ #define SB_DSP_REC_SAFEFTY_MARGIN 4096 @@ -205,10 +208,18 @@ void sb_doreset(sb_dsp_t *dsp) int c; sb_dsp_reset(dsp); - - if (dsp->sb_type==SB16) sb_commands[8] = 1; - else sb_commands[8] = -1; - + + if (IS_AZTECH(dsp)) + { + sb_commands[8] = 1; + sb_commands[9] = 1; + } + else + { + if (dsp->sb_type==SB16) sb_commands[8] = 1; + else sb_commands[8] = -1; + } + for (c = 0; c < 256; c++) dsp->sb_asp_regs[c] = 0; dsp->sb_asp_regs[5] = 0x01; @@ -579,6 +590,20 @@ void sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, ~dsp->sb_data[0]); break; case 0xE1: /*Get DSP version*/ + if (IS_AZTECH(dsp)) + { + if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) + { + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + } + else if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) + { + sb_add_data(dsp, 0x2); + sb_add_data(dsp, 0x1); + } + break; + } sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] >> 8); sb_add_data(dsp, sb_dsp_versions[dsp->sb_type] & 0xff); break; @@ -617,6 +642,32 @@ void sb_exec_command(sb_dsp_t *dsp) case 0xFF: break; case 0x08: /*ASP get version*/ + if (IS_AZTECH(dsp)) + { + if ((dsp->sb_data[0] == 0x55 || dsp->sb_data[0] == 0x05) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) + sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ + else if ((dsp->sb_data[0] == 0x55 || dsp->sb_data[0] == 0x05) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) + sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ + else if (dsp->sb_data[0] == 0x08) + { + // EEPROM address to write followed by byte + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); + dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; + break; + } + else if (dsp->sb_data[0] == 0x07) + { + // EEPROM address to read + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); + sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); + break; + } + else + pclog("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); // 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen + break; + } if (dsp->sb_type < SB16) break; sb_add_data(dsp, 0x18); break; @@ -644,10 +695,26 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x04: case 0x05: break; -// default: -// fatal("Exec bad SB command %02X\n",sb_command); - - + case 0x09: /*AZTECH mode set*/ + if (dsp->sb_data[0] == 0x00) + { + pclog("AZT2316A: WSS MODE!\n"); + azt2316a_enable_wss(1, dsp->parent); + } + else if (dsp->sb_data[0] == 0x01) + { + pclog("AZT2316A: SB8PROV2 MODE!\n"); + azt2316a_enable_wss(0, dsp->parent); + } + else + pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen + break; + case 0x38: /*TODO: AZTECH MIDI-related? */ + break; + default: + fatal("Exec bad SB command %02X\n",dsp->sb_command); + + /*TODO: Some more data about the DSP registeres * http://the.earth.li/~tfm/oldpage/sb_dsp.html * http://www.synchrondata.com/pheaven/www/area19.htm @@ -680,7 +747,7 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; return; case 0xC: /*Command/data write*/ - timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); + timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); if (dsp->asp_data_len) { // pclog("ASP data %i\n", dsp->asp_data_len); @@ -699,11 +766,27 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sb_data_stat++; } else - dsp->sb_data[dsp->sb_data_stat++] = v; + { + dsp->sb_data[dsp->sb_data_stat++] = v; + if (IS_AZTECH(dsp)) + { + // variable length commands + if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) + sb_commands[dsp->sb_command] = 3; + else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) + sb_commands[dsp->sb_command] = 2; + } + } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); dsp->sb_data_stat = -1; + if (IS_AZTECH(dsp)) + { + // variable length commands + if (dsp->sb_command == 0x08) + sb_commands[dsp->sb_command] = 1; + } } break; } @@ -732,13 +815,31 @@ uint8_t sb_read(uint16_t a, void *priv) if (dsp->wb_full || (dsp->busy_count & 2)) { dsp->wb_full = timer_is_enabled(&dsp->wb_timer); - return 0xff; +// pclog("SB read 0x80\n"); + if (IS_AZTECH(dsp)) + return 0x80; + else + return 0xFF; } - return 0x7f; +// pclog("SB read 0x00\n"); + if (IS_AZTECH(dsp)) + return 0x00; + else + return 0x7F; case 0xE: /*Read data ready*/ picintc(1 << dsp->sb_irqnum); dsp->sb_irq8 = dsp->sb_irq16 = 0; - return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; + // Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. + if (IS_AZTECH(dsp)) + { +// pclog("SB read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80); + return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; + } + else + { +// pclog("SB read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7F : 0xFF); + return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7F : 0xFF; + } case 0xF: /*16-bit ack*/ dsp->sb_irq16 = 0; if (!dsp->sb_irq8) picintc(1 << dsp->sb_irqnum); @@ -751,9 +852,11 @@ static void sb_wb_clear(void *p) { } -void sb_dsp_init(sb_dsp_t *dsp, int type) +void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) { dsp->sb_type = type; + dsp->sb_subtype = subtype; + dsp->parent = parent; // Default values. Use sb_dsp_setxxx() methods to change. dsp->sb_irqnum = 7; diff --git a/src/sound_sb_dsp.h b/src/sound_sb_dsp.h index cb14af5..33661c0 100644 --- a/src/sound_sb_dsp.h +++ b/src/sound_sb_dsp.h @@ -1,6 +1,20 @@ +#ifndef SOUND_SB_DSP_H +#define SOUND_SB_DSP_H + +/*Sound Blaster Clones, for quirks*/ +#define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ +#define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ +#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ + +// aztech-related +#define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) // check for future AZT cards here +#define AZTECH_EEPROM_SIZE 16 + typedef struct sb_dsp_t { int sb_type; + int sb_subtype; // which clone + void *parent; // "sb_t *" if default subtype, "azt2316a_t *" if aztech. int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; int sb_8_dmanum; @@ -67,9 +81,11 @@ typedef struct sb_dsp_t int16_t record_buffer[0xFFFF]; int16_t buffer[MAXSOUNDBUFLEN * 2]; int pos; + + uint8_t azt_eeprom[AZTECH_EEPROM_SIZE]; // the eeprom in the Aztech cards is attached to the DSP } sb_dsp_t; -void sb_dsp_init(sb_dsp_t *dsp, int type); +void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent); void sb_dsp_close(sb_dsp_t *dsp); void sb_dsp_setirq(sb_dsp_t *dsp, int irq); @@ -86,3 +102,5 @@ void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp); void sb_dsp_update(sb_dsp_t *dsp); + +#endif /* SOUND_SB_DSP_H */ diff --git a/src/sound_wss.c b/src/sound_wss.c index 4129744..edbc272 100644 --- a/src/sound_wss.c +++ b/src/sound_wss.c @@ -84,7 +84,7 @@ void *wss_init() opl_emu = device_get_config_int("opl_emu"); opl3_init(&wss->opl, opl_emu); - ad1848_init(&wss->ad1848); + ad1848_init(&wss->ad1848, AD1848_TYPE_DEFAULT); ad1848_setirq(&wss->ad1848, 7); ad1848_setdma(&wss->ad1848, 3); From dcf354688d9419092a6f1bdd0280232a74691a8d Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Mar 2020 18:12:47 +0000 Subject: [PATCH 0811/1050] Support serial UART without FIFO. Patch from EluanCM. --- src/model.c | 8 ++++---- src/ps1.c | 4 ++-- src/ps2.c | 2 +- src/ps2_mca.c | 16 ++++++++-------- src/serial.c | 9 ++++++--- src/serial.h | 5 +++-- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/model.c b/src/model.c index 2778be7..419c6e7 100644 --- a/src/model.c +++ b/src/model.c @@ -312,8 +312,8 @@ void common_init() lpt_init(); pic_init(); pit_init(); - serial1_init(0x3f8, 4); - serial2_init(0x2f8, 3); + serial1_init(0x3f8, 4, 1); + serial2_init(0x2f8, 3, 1); } void xt_init() @@ -343,7 +343,7 @@ void pcjr_init() pic_init(); pit_init(); pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); keyboard_pcjr_init(); device_add(&sn76489_device); nmi_mask = 0x80; @@ -427,7 +427,7 @@ void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */ lpt2_remove(); /* only one parallel port */ pic_init(); pit_init(); - serial1_init(0x3f8, 4); /* only one serial port */ + serial1_init(0x3f8, 4, 1); /* only one serial port */ mem_add_bios(); device_add(&zenith_scratchpad_device); pit_set_out_func(&pit, 1, pit_refresh_timer_xt); diff --git a/src/ps1.c b/src/ps1.c index f248647..e1f6fce 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -73,7 +73,7 @@ void ps1_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else serial1_remove(); if (val & 0x10) @@ -238,7 +238,7 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else serial1_remove(); if (val & 0x10) diff --git a/src/ps2.c b/src/ps2.c index 6334666..fe0d6a9 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -68,7 +68,7 @@ void ps2_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else serial1_remove(); if (val & 0x10) diff --git a/src/ps2_mca.c b/src/ps2_mca.c index f510e46..dd4e024 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -315,9 +315,9 @@ static void model_50_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); @@ -371,9 +371,9 @@ static void model_55sx_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); @@ -445,9 +445,9 @@ static void model_70_type3_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); @@ -494,9 +494,9 @@ static void model_80_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); diff --git a/src/serial.c b/src/serial.c index 2866f7c..b563b0d 100644 --- a/src/serial.c +++ b/src/serial.c @@ -111,7 +111,8 @@ void serial_write(uint16_t addr, uint8_t val, void *p) serial_update_ints(serial); break; case 2: - serial->fcr = val; + if (serial->has_fifo) + serial->fcr = val; break; case 3: serial->lcr = val; @@ -247,7 +248,7 @@ void serial_receive_callback(void *p) } /*Tandy might need COM1 at 2f8*/ -void serial1_init(uint16_t addr, int irq) +void serial1_init(uint16_t addr, int irq, int has_fifo) { memset(&serial1, 0, sizeof(serial1)); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); @@ -255,6 +256,7 @@ void serial1_init(uint16_t addr, int irq) serial1.addr = addr; serial1.rcr_callback = NULL; timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0); + serial1.has_fifo = has_fifo; } void serial1_set(uint16_t addr, int irq) { @@ -268,7 +270,7 @@ void serial1_remove() io_removehandler(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } -void serial2_init(uint16_t addr, int irq) +void serial2_init(uint16_t addr, int irq, int has_fifo) { memset(&serial2, 0, sizeof(serial2)); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); @@ -276,6 +278,7 @@ void serial2_init(uint16_t addr, int irq) serial2.addr = addr; serial2.rcr_callback = NULL; timer_add(&serial2.receive_timer, serial_receive_callback, &serial2, 0); + serial2.has_fifo = has_fifo; } void serial2_set(uint16_t addr, int irq) { diff --git a/src/serial.h b/src/serial.h index 453acbf..841aaaa 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,7 +1,7 @@ #include "timer.h" -void serial1_init(uint16_t addr, int irq); -void serial2_init(uint16_t addr, int irq); +void serial1_init(uint16_t addr, int irq, int has_fifo); +void serial2_init(uint16_t addr, int irq, int has_fifo); void serial1_set(uint16_t addr, int irq); void serial2_set(uint16_t addr, int irq); void serial1_remove(); @@ -26,6 +26,7 @@ typedef struct void *rcr_callback_p; uint8_t fifo[256]; int fifo_read, fifo_write; + int has_fifo; pc_timer_t receive_timer; } SERIAL; From a113e4546f8fcb00f0785aabdf3c95995daf4362 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Mar 2020 18:14:07 +0000 Subject: [PATCH 0812/1050] Added Hyundai Super-286TR emulation. Patch from EluanCM. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/cpu.h | 1 + src/cpu_tables.c | 7 + src/f82c710_upc.c | 323 +++++++++++++++++++++++++++++ src/f82c710_upc.h | 4 + src/ibm.h | 1 + src/keyboard_at.c | 12 ++ src/mem_bios.c | 7 + src/model.c | 2 + src/nvr.c | 2 + 12 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 src/f82c710_upc.c create mode 100644 src/f82c710_upc.h diff --git a/src/Makefile.am b/src/Makefile.am index 4be48a1..34f85d3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,7 +32,7 @@ codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_o codegen_ops_logic.c codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c \ codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c cs8230.c dells200.c device.c disc.c \ -disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ +disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f82c710_upc.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c lpt_dss.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index c129df8..7f82868 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -17,7 +17,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ - dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ + dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f82c710_upc.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index c6445db..956ef98 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -17,7 +17,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ - dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ + dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f82c710_upc.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ ide_atapi.o ide_sff8038i.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 \ diff --git a/src/cpu.h b/src/cpu.h index c1cf577..4188cff 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -121,6 +121,7 @@ extern CPU cpus_K6_SS7[]; extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; extern CPU cpus_pc1512[]; +extern CPU cpus_super286tr[]; extern CPU cpus_ibmat[]; extern CPU cpus_ibmxt286[]; extern CPU cpus_ps1_m2011[]; diff --git a/src/cpu_tables.c b/src/cpu_tables.c index a32032f..1c9e1c7 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -112,6 +112,13 @@ CPU cpus_286[] = {"", -1, 0, 0, 0, 0} }; +CPU cpus_super286tr[] = +{ + /*286*/ + {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2}, + {"", -1, 0, 0, 0, 0} +}; + CPU cpus_ibmat[] = { /*286*/ diff --git a/src/f82c710_upc.c b/src/f82c710_upc.c new file mode 100644 index 0000000..f700d04 --- /dev/null +++ b/src/f82c710_upc.c @@ -0,0 +1,323 @@ +/* + * Chips & Technologies F82C710 Universal Peripheral Controller (UPC) + * + * Copyright (c) 2020 Eluan Costa Miranda All rights reserved. + * + * 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 3 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, see . + * + * ============================================================================= + * + * This SuperIO chip is commonly seem paired with the Single-chip AT (SCAT) + * chip. Only the functionality needed for the Hyundai Super-286TR BIOS is + * implented for now. + * + * One of the goals of this chip was getting rid of jumpers and have everything + * configured by software, but there is no configuration for serial and + * parallel IRQs. Because of that, motherboards still supply jumpers for these + * two signals. + * + */ + +#include "ibm.h" + +#include "fdc.h" +#include "ide.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" + +typedef struct upc_t +{ + int configuration_state; // state of algorithm to enter configuration mode + int configuration_mode; + uint16_t cri_addr; // cri = configuration index register, addr is even + uint16_t cap_addr; // cap = configuration access port, addr is odd and is cri_addr + 1 + uint8_t cri; // currently indexed register + + // these regs are not affected by reset + uint8_t regs[15]; // there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit config mode + + int serial_irq; + int parallel_irq; // TODO: currently not implemented in PCem +} upc_t; + +static upc_t upc; + +void upc_update_ports(upc_t *upc) +{ + serial1_remove(); + serial2_remove(); + lpt1_remove(); + lpt2_remove(); + fdc_remove(); + ide_pri_disable(); + ide_sec_disable(); + + if (upc->regs[0] & 0x4) + { + serial1_init(upc->regs[4] * 4, upc->serial_irq, 0); + pclog("UPC: UART at %04X, irq %d\n", upc->regs[4] * 4, upc->serial_irq); + } + else + pclog("UPC: UART disabled\n"); + + if (upc->regs[0] & 0x8) + { + lpt1_init(upc->regs[6] * 4); + pclog("UPC: PARALLEL at %04X, irq %d\n", upc->regs[6] * 4, upc->parallel_irq); + } + else + pclog("UPC: PARALLEL disabled\n"); + + if (upc->regs[12] & 0x80) + { + ide_pri_enable(); + pclog("UPC: IDE enabled\n"); + } + else + pclog("UPC: IDE disabled\n"); + + if (upc->regs[12] & 0x20) + { + fdc_add(); + pclog("UPC: FDC enabled\n"); + } + else + pclog("UPC: FDC disabled\n"); + + if ((upc->regs[0] & 0x60) != 0) + pclog("UPC: Oscillator control not implemented!\n"); + if ((upc->regs[1] & 0x80) != 0) + pclog("UPC: Restricted serial reset not implemented!\n"); + if ((upc->regs[1] & 0x80) != 0) + pclog("UPC: Restricted serial reset not implemented!\n"); + if ((upc->regs[1] & 0x40) != 0) + pclog("UPC: Bidirectional parallel port support not implemented!\n"); + if ((upc->regs[1] & 0x38) != 0) + pclog("UPC: UART force CTS, DSR, DCD not implemented!\n"); + if ((upc->regs[2] & 0x70) != 0) + pclog("UPC: UART clock control not implemented!\n"); + if (upc->regs[9] == 0xb0) + pclog("UPC: GPCS not implemented! (at default address: %04X)\n", upc->regs[9] * 4); + else if (upc->regs[9] != 0) + pclog("UPC: GPCS not implemented! (at address: %04X)\n", upc->regs[9] * 4); + if ((upc->regs[12] & 0x40) != 0) + pclog("UPC: IDE XT mode not implemented!\n"); + if ((upc->regs[12] & 0x10) != 0) + pclog("UPC: FDC power down mode not implemented!\n"); + if ((upc->regs[12] & 0x0C) != 0) + pclog("UPC: RTCCS not implemented!\n"); + if ((upc->regs[12] & 0x01) != 0) + pclog("UPC: PS/2 mouse port power down not implemented!\n"); + if (upc->regs[13] != 0) + pclog("UPC: PS/2 mouse port not implemented!\n"); + if (upc->regs[14] != 0) + pclog("UPC: Test mode not implemented!\n"); + // regs 10 and 11 not looked at +} + +uint8_t upc_config_read(uint16_t port, void *priv) +{ + upc_t *upc = (upc_t *)priv; + uint8_t temp = 0xff; + + if (upc->configuration_mode) + { + if (port == upc->cri_addr) + { + temp = upc->cri; + } + else if (port == upc->cap_addr) + { + if (upc->cri == 0xf) + temp = upc->cri_addr / 4; + else + temp = upc->regs[upc->cri]; + } + } + +// pclog("UPC READ : %04X, %02X\n", port, temp); + return temp; +} + +void upc_config_write(uint16_t port, uint8_t val, void *priv) +{ + upc_t *upc = (upc_t *)priv; + int configuration_state_event = 0; + +// pclog("UPC WRITE: %04X, %02X\n", port, val); + + switch(port) + { + case 0x2fa: + if (upc->configuration_state == 0 && val == 0x55) + configuration_state_event = 1; + else if (upc->configuration_state == 4) + { + uint8_t addr_verify = upc->cri_addr / 4; + addr_verify += val; + if (addr_verify == 0xff) + { + upc->configuration_mode = 1; + // TODO: is the value of cri reset here or when exiting configuration mode? + io_sethandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, upc); + pclog("UPC: in configuration mode at %04X\n", upc->cri_addr); + } + else + { + upc->configuration_mode = 0; + pclog("UPC: configuration mode failed (sum = %02X)\n", addr_verify); + } + } + break; + case 0x3fa: + if (upc->configuration_state == 1 && val == 0xaa) + configuration_state_event = 1; + else if (upc->configuration_state == 2 && val == 0x36) + configuration_state_event = 1; + else if (upc->configuration_state == 3) + { + upc->cri_addr = val * 4; + upc->cap_addr = upc->cri_addr + 1; + configuration_state_event = 1; + } + break; + default: + break; + } + if (upc->configuration_mode) + { + if (port == upc->cri_addr) + { + upc->cri = val & 0xf; + } + else if (port == upc->cap_addr) + { + if (upc->cri == 0xf) + { + pclog("UPC: exiting configuration mode\n"); + upc->configuration_mode = 0; + io_removehandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, upc); + upc_update_ports(upc); // TODO: any benefit in updating at each register write instead of when exiting config mode? + } + else + { + upc->regs[upc->cri] = val; + } + } + } + + // TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? + if ((port == 0x2fa || port == 0x3fa) && configuration_state_event) + upc->configuration_state++; + else + upc->configuration_state = 0; +} + +static void *upc_init() +{ + pclog("UPC INIT\n"); + memset(&upc, 0, sizeof(upc)); + + upc.serial_irq = device_get_config_int("serial_irq"); + upc.parallel_irq = device_get_config_int("parallel_irq"); + + // because of these addresses, serial ports must be 16450 without fifos + io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, upc_config_write, NULL, NULL, &upc); + io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, upc_config_write, NULL, NULL, &upc); + + upc.regs[0] = 0x0c; + upc.regs[1] = 0x00; + upc.regs[2] = 0x00; + upc.regs[3] = 0x00; + upc.regs[4] = 0xfe; + upc.regs[5] = 0x00; + upc.regs[6] = 0x9e; + upc.regs[7] = 0x00; + upc.regs[8] = 0x00; + upc.regs[9] = 0xb0; + upc.regs[10] = 0x00; + upc.regs[11] = 0x00; + upc.regs[12] = 0xa0; + upc.regs[13] = 0x00; + upc.regs[14] = 0x00; + + upc_update_ports(&upc); + + return &upc; +} + +static device_config_t upc_config[] = +{ + { + .name = "serial_irq", + .description = "Serial Port IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 4 (for address 0x3F8/COM1)", + .value = 4 + }, + { + .description = "IRQ 3 (for address 0x2F8/COM2)", + .value = 3 + }, + { + .description = "Disabled", + .value = 0 // TODO: see if this breaks PCem's PIC + } + }, + .default_int = 4 + }, + { + .name = "parallel_irq", + .description = "Parallel Port IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 7 (for address 0x378/LPTB)", + .value = 7 + }, + { + .description = "IRQ 5 (for address 0x278/LPTC)", + .value = 5 + }, + { + .description = "Disabled", + .value = 0 // TODO: see if this breaks PCem's PIC + } + }, + .default_int = 7 + }, + // For the Hyundai Super-286TR, the only other jumper is the Color/Mono one and it's handled by the at keyboard controller code. + { + .type = -1 + } +}; + + +device_t f82c710_upc_device = +{ + "F82C710 UPC", + 0, + upc_init, + NULL, + NULL, + NULL, + NULL, + NULL, + upc_config +}; diff --git a/src/f82c710_upc.h b/src/f82c710_upc.h new file mode 100644 index 0000000..fd816d8 --- /dev/null +++ b/src/f82c710_upc.h @@ -0,0 +1,4 @@ +#include "device.h" + +extern device_t f82c710_upc_device; + diff --git a/src/ibm.h b/src/ibm.h index ee076de..54e1634 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -258,6 +258,7 @@ enum ROM_IBMPS1_2133_451, ROM_ECS_386_32, ROM_LEDGE_MODELM, + ROM_HYUNDAI_SUPER286TR, ROM_MAX }; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index c298da7..5643797 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -639,6 +639,18 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xe0: /*Read test inputs*/ keyboard_at_adddata(0x00); break; + + case 0xe8: /* Super-286TR: turbo ON */ + // TODO: 0xe8 is always followed by 0xba + // TODO: I don't know where to call cpu_set_turbo(1) to avoid slow POST after ctrl-alt-del when on low speed (if this is the real behavior!) + if (romset == ROM_HYUNDAI_SUPER286TR) + cpu_set_turbo(1); // 12 MHz + break; + + case 0xe9: /* Super-286TR: turbo OFF */ + if (romset == ROM_HYUNDAI_SUPER286TR) + cpu_set_turbo(0); // 8 MHz + break; case 0xef: /*??? - sent by AMI486*/ break; diff --git a/src/mem_bios.c b/src/mem_bios.c index a6ef874..6b44a01 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -379,6 +379,13 @@ int loadbios() fclose(f); return 1; + case ROM_HYUNDAI_SUPER286TR: + f=romfopen("super286tr/award.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1; + case ROM_GW286CT: f=romfopen("gw286ct/2ctc001.bin","rb"); if (!f) break; diff --git a/src/model.c b/src/model.c index 419c6e7..2a85479 100644 --- a/src/model.c +++ b/src/model.c @@ -19,6 +19,7 @@ #include "device.h" #include "cassette.h" #include "dma.h" +#include "f82c710_upc.h" #include "fdc.h" #include "fdc37c665.h" #include "fdc37c93x.h" @@ -177,6 +178,7 @@ MODEL models[] = {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 256,15872, 128, at_init, NULL}, {"[286] Goldstar GDC-212M", ROM_GDC212M, "gdc212m", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 512, 4096, 512, at_scat_init, NULL}, {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", { {"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 128, at_scat_init, NULL}, + {"[286] Hyundai Super-286TR", ROM_HYUNDAI_SUPER286TR, "super286tr", { {"AMD", cpus_super286tr}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1024, 4096, 128, at_scat_init, &f82c710_upc_device}, {"[286] IBM AT", ROM_IBMAT, "ibmat", { {"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT, 256,15872, 128, ibm_at_init, NULL}, {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { {"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 512,16384, 512, ps1_m2011_init, NULL}, {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { {"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 1ebc5a9..c5dbe9f 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -298,6 +298,7 @@ void loadnvr() case ROM_TG286M: f = nvrfopen("tg286m.nvr", "rb"); nvrmask = 127; break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); nvrmask = 127; break; case ROM_GDC212M: f = nvrfopen("gdc212m.nvr", "rb"); nvrmask = 127; break; + case ROM_HYUNDAI_SUPER286TR: f = nvrfopen("super286tr.nvr", "rb"); nvrmask = 127; break; case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); nvrmask = 127; break; @@ -401,6 +402,7 @@ void savenvr() case ROM_TG286M: f = nvrfopen("tg286m.nvr", "wb"); break; case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); break; case ROM_GDC212M: f = nvrfopen("gdc212m.nvr", "wb"); break; + case ROM_HYUNDAI_SUPER286TR: f = nvrfopen("super286tr.nvr", "wb"); break; case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); break; case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); break; From 9b92305913f205ddea44cc297e96468688bb37be Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Mar 2020 18:14:41 +0000 Subject: [PATCH 0813/1050] Added Itautec Infoway Multim?dia emulation. Patch from EluanCM. --- src/ibm.h | 1 + src/intel_flash.c | 3 +++ src/mem_bios.c | 18 ++++++++++++++++++ src/model.c | 1 + src/nvr.c | 2 ++ 5 files changed, 25 insertions(+) diff --git a/src/ibm.h b/src/ibm.h index 54e1634..68cd837 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -259,6 +259,7 @@ enum ROM_ECS_386_32, ROM_LEDGE_MODELM, ROM_HYUNDAI_SUPER286TR, + ROM_ITAUTEC_INFOWAYM, ROM_MAX }; diff --git a/src/intel_flash.c b/src/intel_flash.c index 526d6f0..95285ee 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -188,6 +188,9 @@ void *intel_flash_init(uint8_t type) case ROM_P55T2P4: strcpy(flash_path, "p55t2p4/"); break; + case ROM_ITAUTEC_INFOWAYM: + strcpy(flash_path, "infowaym/"); + break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); } diff --git a/src/mem_bios.c b/src/mem_bios.c index 6b44a01..c0e776e 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -921,6 +921,24 @@ int loadbios() biosmask = 0x1ffff; return 1; + // keep separate from generic Zappa because there is a BIOS logo + // in flash.bin + case ROM_ITAUTEC_INFOWAYM: + if (!rom_present("infowaym/gd5434.bin")) + break; + f = romfopen("infowaym/1006bs0_.bio", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("infowaym/1006bs0_.bi1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_PB520R: if (!rom_present("pb520r/gd5434.bin")) break; diff --git a/src/model.c b/src/model.c index 2a85479..a347159 100644 --- a/src/model.c +++ b/src/model.c @@ -223,6 +223,7 @@ MODEL models[] = {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, + {"[Socket 5] Itautec Infoway Multimidia", ROM_ITAUTEC_INFOWAYM, "infowaym",{ {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_zappa_init, NULL}, {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index c5dbe9f..452937d 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -342,6 +342,7 @@ void loadnvr() case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); nvrmask = 127; break; case ROM_PB570: f = nvrfopen("pb570.nvr", "rb"); nvrmask = 127; break; case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "rb"); nvrmask = 127; break; + case ROM_ITAUTEC_INFOWAYM: f = nvrfopen("infowaym.nvr", "rb"); nvrmask = 127; break; case ROM_PB520R: f = nvrfopen("pb520r.nvr", "rb"); nvrmask = 127; break; case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","rb"); break; @@ -446,6 +447,7 @@ void savenvr() case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); break; case ROM_PB570: f = nvrfopen("pb570.nvr", "wb"); break; case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "wb"); break; + case ROM_ITAUTEC_INFOWAYM: f = nvrfopen("infowaym.nvr", "wb"); break; case ROM_PB520R: f = nvrfopen("pb520r.nvr", "wb"); break; case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); break; case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr","wb"); break; From 4e51641f29cfd53699bda4ab74d52c93d7135d4f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Mar 2020 11:37:04 +0000 Subject: [PATCH 0814/1050] Remove superfluous CRTC R17 adjustment on ATI 28800. Fixes 800x600 modes on 28800 cards. Patch from Greatpsycho. --- src/vid_ati28800.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index a86bf2a..8cdd8e8 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -297,15 +297,6 @@ void ati28800_recalctimings(svga_t *svga) svga->rowoffset <<= 1; } - if (svga->crtc[0x17] & 4) - { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } - if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ { pclog("8bpp_highres\n"); From 7d9f1f58c36f22835df9734b9d8b63f14ef479dc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Mar 2020 11:37:35 +0000 Subject: [PATCH 0815/1050] Remove superfluous CRTC R17 adjustment on TGUI cards. Fixes 1280x1024 on TGUI9400. --- src/vid_tgui9440.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index a2e13bd..2edf8c7 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -470,15 +470,6 @@ void tgui_recalctimings(svga_t *svga) if (svga->interlace && tgui->type < TGUI_9440) svga->rowoffset >>= 1; - if (svga->crtc[0x17] & 4) - { - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vsyncstart *= 2; - svga->split *= 2; - svga->vblankstart *= 2; - } - if (tgui->type >= TGUI_9440) { if (svga->miscout & 8) From ab11e20bb194c2e38f46a957351704a6883e6c74 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Mar 2020 18:44:43 +0000 Subject: [PATCH 0816/1050] Temporary hack to restrict minimum window size on Windows. This prevents some nasty behaviour relating to menu wrapping and window movement/sizing. --- src/wx-sdl2-display-win.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 61779c2..974e958 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -68,6 +68,15 @@ extern void device_force_redraw(); extern void mouse_wheel_update(int); extern void toggle_fullscreen(); +/*Minimum window width to prevent menu wrapping. + This is a horrible hack to work around issues with PCem, SDL2, and the + AdjustWindowRectEx() function. Allowing the menu to wrap causes some quite odd + window behaviour, mainly shooting to the bottom of the screen when you try to + move it. + This hard coded limit is highly fragile and will be replaced by a proper fix as + soon as I work out what that should be!*/ +#define MIN_WIDTH 360 + void display_resize(int width, int height) { winsizex = width*(video_scale+1) >> 1; @@ -81,6 +90,8 @@ void display_resize(int width, int height) winsizex = rect.w; winsizey = rect.h; + if (winsizex < MIN_WIDTH) + winsizex = MIN_WIDTH; win_doresize = 1; } From 68ea5ec3bd89db88901da99f026d8913e63c2b82 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Mar 2020 21:33:38 +0000 Subject: [PATCH 0817/1050] Rewrite !WXGTK memory spinner code to fix issues with up/down on some machines. --- src/wx-config.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/wx-config.c b/src/wx-config.c index aa89a5c..3d253ed 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -46,6 +46,8 @@ static int new_zip_channel; extern int pause; +static int memspin_old; + extern void deviceconfig_open(void* hwnd, device_t *device); extern int hdconf_init(void* hdlg); extern int hdconf_update(void* hdlg); @@ -810,9 +812,15 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) | models[romstomodel[romset]].max_ram); wx_sendmessage(h, WX_UDM_SETINCR, 0, models[model].ram_granularity); if (!((models[model].flags & MODEL_AT) && models[model].ram_granularity < 128)) + { wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size); + memspin_old = mem_size; + } else + { wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size / 1024); + memspin_old = mem_size / 1024; + } h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); if (model_getdevice(model)) @@ -1371,20 +1379,18 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); - if (mem & granularity_mask) + if (mem < memspin_old) { - if ((mem & granularity_mask) < (granularity / 2)) - { - /*Assume increase*/ - mem = (mem + granularity_mask) & ~granularity_mask; - } - else - { - /*Assumg decrease*/ - mem &= ~granularity_mask; - } - mem = wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + /*Assume decrease*/ + mem &= ~granularity_mask; } + else + { + /*Assume increase*/ + mem = (mem + granularity_mask) & ~granularity_mask; + } + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + memspin_old = mem; } #endif return 0; From 61a5ca2f3987d71c0bc3ffdeec74f90d91fc7269 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Mar 2020 14:53:48 +0000 Subject: [PATCH 0818/1050] Fix alphabetical ordering in model and video menu. --- src/model.c | 2 +- src/video.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/model.c b/src/model.c index a347159..f4a1e51 100644 --- a/src/model.c +++ b/src/model.c @@ -154,8 +154,8 @@ MODEL models[] = {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}, {"[8088] Toshiba T1000", ROM_T1000, "t1000", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, NULL}, {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}, - {"[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, xt_zenith_init, NULL}, {"[8088] Xi8088", ROM_XI8088, "xi8088", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}, + {"[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, xt_zenith_init, NULL}, {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", { {"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams1512_device}, diff --git a/src/video.c b/src/video.c index 81dc3ec..dc0ecfd 100644 --- a/src/video.c +++ b/src/video.c @@ -119,10 +119,10 @@ static VIDEO_CARD video_cards[] = {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"Sigma Color 400", "sigma400", &sigma_device, GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, - {"Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, - {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, + {"Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, + {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"", "", NULL, 0} From 4ee83be7b5b5e239653dda36f23c71c9ad6f83ca Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Mar 2020 14:54:54 +0000 Subject: [PATCH 0819/1050] Don't add keyboard waitstates on AT or XT Model 286. Fixes POST of these machines at 6 MHz. --- src/keyboard_at.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 5643797..8fcb279 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -675,8 +675,9 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) uint8_t keyboard_at_read(uint16_t port, void *priv) { uint8_t temp = 0xff; - - cycles -= ISA_CYCLES(8); + + if (romset != ROM_IBMAT && romset != ROM_IBMXT286) + cycles -= ISA_CYCLES(8); // if (port != 0x61) pclog("keyboard_at : read %04X ", port); if (romset == ROM_XI8088 && port == 0x63) port = 0x61; From 56a3ab7020f0ac1aea9328ea35df28e0fe8122a3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Mar 2020 22:33:18 +0000 Subject: [PATCH 0820/1050] Fix missing read handling for SCAMP registers. Fixes boot on some RAM sizes on Commodore SL386SX-25. --- src/scamp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/scamp.c b/src/scamp.c index d11e3cc..4cd5a78 100644 --- a/src/scamp.c +++ b/src/scamp.c @@ -637,6 +637,14 @@ uint8_t scamp_read(uint16_t addr, void *p) ret = scamp.port_92; break; + case 0xed: + if (scamp.cfg_enable) + { + if (scamp.cfg_index >= 0x00 && scamp.cfg_index <= 0x16) + ret = scamp.cfg_regs[scamp.cfg_index]; + } + break; + case 0xee: if (!mem_a20_alt) { From 0116512d39025503adb53cb2fce6d861a160ecab Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Mar 2020 20:19:11 +0000 Subject: [PATCH 0821/1050] Fixed recompiled version of JMP far indirect. Fixes Red Hat 3.0.3. --- src/codegen_ops_misc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index 13e0e64..4eb5906 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -356,11 +356,11 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return -1; case 0x28: /*JMP far*/ + uop_MOVZX(ir, IREG_pc, src_reg); uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); uop_CALL_FUNC(ir, loadcsjmp); - uop_MOVZX(ir, IREG_pc, src_reg); return -1; case 0x30: /*PUSH*/ @@ -463,11 +463,11 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe return -1; case 0x28: /*JMP far*/ + uop_MOV(ir, IREG_pc, src_reg); uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); uop_CALL_FUNC(ir, loadcsjmp); - uop_MOV(ir, IREG_pc, src_reg); return -1; case 0x30: /*PUSH*/ From d60084fb04f7ac72ef606948ce2109453f1bb2cf Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 28 Mar 2020 17:23:57 +0000 Subject: [PATCH 0822/1050] PS/2 mouse fixes : - Don't process pending mouse data when mouse was disabled - Commands a7/a8 (disable/enable mouse port) now update keyboard controller command - Implicitly enable mouse when writing data to mouse Fixes PS/2 mouse with Red Hat 5.0. --- src/keyboard_at.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 8fcb279..4acd81d 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -104,15 +104,23 @@ void keyboard_at_poll() keyboard_at.wantirq = 0; if (keyboard_at.out_new & 0x100) { - if (keyboard_at.mem[0] & 0x02) - picint(0x1000); - keyboard_at.out = keyboard_at.out_new & 0xff; - keyboard_at.out_new = -1; - 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; + if (mouse_scan) + { +// pclog("keyboard_at : take IRQ12\n"); + if (keyboard_at.mem[0] & 0x02) + picint(0x1000); + keyboard_at.out = keyboard_at.out_new & 0xff; + keyboard_at.out_new = -1; + keyboard_at.status |= STAT_OFULL; + keyboard_at.status &= ~STAT_IFULL; + keyboard_at.status |= STAT_MFULL; + keyboard_at.last_irq = 0x1000; + } + else + { +// pclog("keyboard_at: suppressing IRQ12\n"); + keyboard_at.out_new = -1; + } } else { @@ -151,7 +159,7 @@ void keyboard_at_poll() { keyboard_at.out_new = mouse_queue[mouse_queue_start] | 0x100; mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } + } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && !(keyboard_at.mem[0] & 0x10) && key_queue_start != key_queue_end) { @@ -308,7 +316,12 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xd4: /*Write to mouse*/ if (keyboard_at.mouse_write) + { keyboard_at.mouse_write(val, keyboard_at.mouse_p); + /*Implicitly enable mouse*/ + mouse_scan = 1; + keyboard_at.mem[0] &= ~0x20; + } break; default: @@ -490,10 +503,12 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) case 0xa7: /*Disable mouse port*/ mouse_scan = 0; + keyboard_at.mem[0] |= 0x20; break; case 0xa8: /*Enable mouse port*/ mouse_scan = 1; + keyboard_at.mem[0] &= ~0x20; break; case 0xa9: /*Test mouse port*/ From 12fae4b9ed8679d8d9ffba7d601b76fa947f4489 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 29 Mar 2020 15:21:38 +0100 Subject: [PATCH 0823/1050] Mystique fixes : - Add previously unimplemented XREGs - Fix CRTC register masking - Use cursor colours when plotting cursor - Add little-endian mono ILOAD Fixes Mystique with BeOS and Redhat 5 --- src/vid_mga.c | 132 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 117 insertions(+), 15 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 655ed1b..a0820cc 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -87,7 +87,10 @@ typedef struct mystique_t uint8_t xmiscctrl; uint8_t xpixclkctrl; uint8_t xvrefctrl; + uint8_t xcolkeymskl, xcolkeymskh; + uint8_t xcolkeyl, xcolkeyh; int xzoomctrl; + uint8_t xcrcbitsel; uint8_t ien; @@ -500,6 +503,17 @@ enum #define XREG_XZOOMCTRL 0x38 +#define XREG_XSENSETEST 0x3a + +#define XREG_XCRCREML 0x3c +#define XREG_XCRCREMH 0x3d +#define XREG_XCRCBITSEL 0x3e + +#define XREG_XCOLKEYMSKL 0x40 +#define XREG_XCOLKEYMSKH 0x41 +#define XREG_XCOLKEYL 0x42 +#define XREG_XCOLKEYH 0x43 + #define XREG_XPIXPLLCM 0x4c #define XREG_XPIXPLLCN 0x4d #define XREG_XPIXPLLCP 0x4e @@ -521,6 +535,11 @@ enum #define XPIXPLLSTAT_SYSLOCK (1 << 6) +#define XCURCTRL_CURMODE_MASK (3 << 0) +#define XCURCTRL_CURMODE_3COL (1 << 0) +#define XCURCTRL_CURMODE_XGA (2 << 0) +#define XCURCTRL_CURMODE_XWIN (3 << 0) + #define DWGCTRL_OPCODE_MASK (0xf << 0) #define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0) #define DWGCTRL_OPCODE_AUTOLINE_OPEN (0x1 << 0) @@ -679,15 +698,15 @@ void mystique_out(uint16_t addr, uint8_t val, void *p) case 0x3D5: // if (svga->crtcreg == 0xc) // pclog("Buffer swap\n"); - if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) + if (((svga->crtcreg & 0x3f) < 7) && (svga->crtc[0x11] & 0x80)) return; - if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) + if (((svga->crtcreg & 0x3f) == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg & 0x3f]; - svga->crtc[svga->crtcreg & 31] = val; + svga->crtc[svga->crtcreg & 0x3f] = val; if (old != val) { - if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) + if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -1022,6 +1041,10 @@ static uint8_t mystique_read_xreg(mystique_t *mystique, int reg) ret = mystique->xgenctrl; break; + case XREG_XVREFCTRL: + ret = mystique->xvrefctrl; + break; + case XREG_XGENIOCTRL: ret = mystique->xgenioctrl; break; @@ -1042,6 +1065,39 @@ static uint8_t mystique_read_xreg(mystique_t *mystique, int reg) case XREG_XZOOMCTRL: ret = mystique->xzoomctrl; break; + + case XREG_XSENSETEST: + ret = 0; + if (mystique->svga.vgapal[0].b < 0x80) + ret |= 1; + if (mystique->svga.vgapal[0].g < 0x80) + ret |= 2; + if (mystique->svga.vgapal[0].r < 0x80) + ret |= 4; + break; + + case XREG_XCRCREML: /*CRC not implemented*/ + ret = 0; + break; + case XREG_XCRCREMH: + ret = 0; + break; + case XREG_XCRCBITSEL: + ret = mystique->xcrcbitsel; + break; + + case XREG_XCOLKEYMSKL: + ret = mystique->xcolkeymskl; + break; + case XREG_XCOLKEYMSKH: + ret = mystique->xcolkeymskh; + break; + case XREG_XCOLKEYL: + ret = mystique->xcolkeyl; + break; + case XREG_XCOLKEYH: + ret = mystique->xcolkeyh; + break; case XREG_XPIXCLKCTRL: ret = mystique->xpixclkctrl; @@ -1147,6 +1203,36 @@ static void mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) mystique->xzoomctrl = val & 3; break; + case XREG_XSENSETEST: + break; + + case XREG_XCRCREML: /*CRC not implemented*/ + break; + case XREG_XCRCREMH: + break; + case XREG_XCRCBITSEL: + mystique->xcrcbitsel = val & 0x1f; + break; + + case XREG_XCOLKEYMSKL: + mystique->xcolkeymskl = val; + break; + case XREG_XCOLKEYMSKH: + mystique->xcolkeymskh = val; + break; + case XREG_XCOLKEYL: + mystique->xcolkeyl = val; + break; + case XREG_XCOLKEYH: + mystique->xcolkeyh = val; + break; + + case XREG_XSYSPLLSTAT: + break; + + case XREG_XPIXPLLSTAT: + break; + case XREG_XPIXCLKCTRL: mystique->xpixclkctrl = val; break; @@ -1336,6 +1422,9 @@ static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) case 0x3e08: break; + case 0x3c08: case 0x3c09: case 0x3c0b: + break; + default: if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) break; @@ -2801,6 +2890,7 @@ static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t data_mask = 1; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { @@ -2969,16 +3059,18 @@ static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) case DWGCTRL_BLTMOD_BMONOWF: data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); + data_mask = (1 << 31); + case DWGCTRL_BLTMOD_BMONOLEF: while (size) { if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - ((data & 0x80000000) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + ((data & data_mask) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[mystique->dwgreg.xdst & 3]) { uint32_t old_dst; - src = (data & 0x80000000) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + src = (data & data_mask) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -3046,7 +3138,10 @@ static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) } else mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - data <<= 1; + if (data_mask == 1) + data >>= 1; + else + data <<= 1; size--; } break; @@ -4694,6 +4789,7 @@ static void blit_iload(mystique_t *mystique) switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BMONOLEF: case DWGCTRL_BLTMOD_BMONOWF: case DWGCTRL_BLTMOD_BU24RGB: // pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); @@ -4950,6 +5046,7 @@ static void mystique_start_blit(mystique_t *mystique) static void mystique_hwcursor_draw(svga_t *svga, int displine) { + mystique_t *mystique = (mystique_t *)svga->p; int x; uint64_t dat[2]; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; @@ -4957,16 +5054,21 @@ static void mystique_hwcursor_draw(svga_t *svga, int displine) dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]); dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]); svga->hwcursor_latch.addr += 16; - for (x = 0; x < 64; x ++) + switch (mystique->xcurctrl & XCURCTRL_CURMODE_MASK) { - if (!(dat[1] & (1ull << 63))) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[0] & (1ull << 63)) ? 0xffffff : 0; - else if (dat[0] & (1ull << 63)) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + case XCURCTRL_CURMODE_XGA: + for (x = 0; x < 64; x ++) + { + if (!(dat[1] & (1ull << 63))) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[0] & (1ull << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; + else if (dat[0] & (1ull << 63)) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; - offset++; - dat[0] <<= 1; - dat[1] <<= 1; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; } } From a017de3c577830b817d59ba1acc6bc6c473eb40d Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 30 Mar 2020 20:59:40 +0100 Subject: [PATCH 0824/1050] Add missing Mystique vsync interrupt. Helps with some Mystique Win9x drivers. --- src/vid_mga.c | 24 ++++++++++++++++++++++++ src/vid_svga.c | 3 +++ src/vid_svga.h | 3 +++ 3 files changed, 30 insertions(+) diff --git a/src/vid_mga.c b/src/vid_mga.c index a0820cc..131b30f 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -611,6 +611,7 @@ enum #define DMA_MODE_VECTOR 2 #define STATUS_SOFTRAPEN (1 << 0) +#define STATUS_VSYNCPEN (1 << 4) #define STATUS_VLINEPEN (1 << 5) #define STATUS_DWGENGSTS (1 << 16) #define STATUS_ENDPRDMASTS (1 << 17) @@ -711,6 +712,12 @@ void mystique_out(uint16_t addr, uint8_t val, void *p) svga->fullchange = changeframecount; svga_recalctimings(svga); } + if (svga->crtcreg == 0x11) + { + if (!(val & 0x10)) + mystique->status &= ~STATUS_VSYNCPEN; + mystique_update_irqs(mystique); + } } break; @@ -800,6 +807,18 @@ static int mystique_line_compare(svga_t *svga) return 0; } +static void mystique_vsync_callback(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *)svga->p; + + if (svga->crtc[0x11] & 0x10) + { + mystique->status |= STATUS_VSYNCPEN; + mystique_update_irqs(mystique); + } + +} + void mystique_recalctimings(svga_t *svga) { mystique_t *mystique = (mystique_t *)svga->p; @@ -976,10 +995,13 @@ static void mystique_recalc_mapping(mystique_t *mystique) static void mystique_update_irqs(mystique_t *mystique) { + svga_t *svga = &mystique->svga; int irq = 0; if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) irq = 1; + if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) + irq = 1; if (irq) pci_set_irq(mystique->card, PCI_INTA); @@ -5298,6 +5320,8 @@ void *mystique_init() mystique->status = STATUS_ENDPRDMASTS; + mystique->svga.vsync_callback = mystique_vsync_callback; + return mystique; } diff --git a/src/vid_svga.c b/src/vid_svga.c index 9c3cd7c..65443de 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -697,6 +697,9 @@ void svga_poll(void *p) // 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->vsync_callback) + svga->vsync_callback(svga); } if (svga->vc == svga->vtotal) { diff --git a/src/vid_svga.h b/src/vid_svga.h index 83d9cbc..4b21f3d 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -129,6 +129,9 @@ typedef struct svga_t vertical line interrupt*/ int (*line_compare)(struct svga_t *svga); + /*Called at the start of vertical sync*/ + void (*vsync_callback)(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; From bb1f314d9c4884a101a13e8f9a4bfbae20c0e346 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 30 Mar 2020 21:03:59 +0100 Subject: [PATCH 0825/1050] Mystique DMAPAD register doesn't act like an ILOAD mirror on DMA writes. --- src/vid_mga.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 131b30f..5db5c25 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -2385,10 +2385,11 @@ static void run_dma(mystique_t *mystique) reg_addr += 0x1c00; // pclog(" DMA pri write %08x to %02x %04x %08x %08x\n", val, mystique->dma.pri_header & 0xff, reg_addr, (mystique->dma.primaddress & DMA_ADDR_MASK), (mystique->dma.primend & DMA_ADDR_MASK)); - if ((reg_addr & 0x300) == 0x100) + if ((reg_addr & 0x300) == 0x100 && reg_addr != REG_DMAPAD) mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + if (reg_addr != REG_DMAPAD) + mystique_accel_ctrl_write_l(reg_addr, val, mystique); } mystique->dma.pri_header >>= 8; @@ -2435,10 +2436,11 @@ static void run_dma(mystique_t *mystique) reg_addr += 0x1c00; // pclog(" DMA sec write %08x to %02x %04x %08x %08x\n", val, mystique->dma.sec_header & 0xff, reg_addr, (mystique->dma.secaddress & DMA_ADDR_MASK), (mystique->dma.secend & DMA_ADDR_MASK)); - if ((reg_addr & 0x300) == 0x100) + if ((reg_addr & 0x300) == 0x100 && reg_addr != REG_DMAPAD) mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + if (reg_addr != REG_DMAPAD) + mystique_accel_ctrl_write_l(reg_addr, val, mystique); } mystique->dma.sec_header >>= 8; From feaf6d456c61c1fd561198ba13529dea6d147dc9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 30 Mar 2020 21:28:00 +0100 Subject: [PATCH 0826/1050] Allow CPU to write too much data to Mystique ILOAD (and ignore all superfluous data). Fixes G-Police on Mystique with default Windows 98 SE driver. --- src/vid_mga.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 5db5c25..9bd1e20 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -2235,9 +2235,8 @@ static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) break; case DMA_MODE_BLIT: - if (!mystique->busy) - fatal("mystique_iload_write_l: !busy\n"); - blit_iload_write(mystique, val, 32); + if (mystique->busy) + blit_iload_write(mystique, val, 32); break; default: @@ -2470,10 +2469,8 @@ static void run_dma(mystique_t *mystique) // pclog(" DMA_MODE_BLIT %08x %08x %08x %08x\n", mystique->dma.secaddress & DMA_ADDR_MASK, mystique->dma.secend & DMA_ADDR_MASK, mystique->dwgreg.dwgctrl_running, mystique->maccess_running); mystique->dma.secaddress += 4; - if (!mystique->busy) - fatal("mystique_iload_write_l: !busy\n"); - - blit_iload_write(mystique, val, 32); + if (mystique->busy) + blit_iload_write(mystique, val, 32); words_transferred++; if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) From eb3ccc24f8b8ad8cb85e5bd5a8d5ea3f5338c833 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 31 Mar 2020 08:24:49 +0100 Subject: [PATCH 0827/1050] Backed out changeset: dc48ccf585b6 --- src/vid_mga.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 9bd1e20..5bece6e 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -2384,11 +2384,10 @@ static void run_dma(mystique_t *mystique) reg_addr += 0x1c00; // pclog(" DMA pri write %08x to %02x %04x %08x %08x\n", val, mystique->dma.pri_header & 0xff, reg_addr, (mystique->dma.primaddress & DMA_ADDR_MASK), (mystique->dma.primend & DMA_ADDR_MASK)); - if ((reg_addr & 0x300) == 0x100 && reg_addr != REG_DMAPAD) + if ((reg_addr & 0x300) == 0x100) mystique->blitter_submit_dma_refcount++; - if (reg_addr != REG_DMAPAD) - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + mystique_accel_ctrl_write_l(reg_addr, val, mystique); } mystique->dma.pri_header >>= 8; @@ -2435,11 +2434,10 @@ static void run_dma(mystique_t *mystique) reg_addr += 0x1c00; // pclog(" DMA sec write %08x to %02x %04x %08x %08x\n", val, mystique->dma.sec_header & 0xff, reg_addr, (mystique->dma.secaddress & DMA_ADDR_MASK), (mystique->dma.secend & DMA_ADDR_MASK)); - if ((reg_addr & 0x300) == 0x100 && reg_addr != REG_DMAPAD) + if ((reg_addr & 0x300) == 0x100) mystique->blitter_submit_dma_refcount++; - if (reg_addr != REG_DMAPAD) - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + mystique_accel_ctrl_write_l(reg_addr, val, mystique); } mystique->dma.sec_header >>= 8; From b66c37c8afe5b8c679d88b84526ae6a9f1573abe Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 31 Mar 2020 08:55:59 +0100 Subject: [PATCH 0828/1050] Don't allow Mystique SRCx/DMAPAD writes to reach ILOAD processing unless a command is actually in progress. Fixes Incoming with default Windows 98SE driver --- src/vid_mga.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 5bece6e..2e161fc 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -1968,28 +1968,28 @@ static void mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) case REG_SRC0: mystique->dwgreg.src[0] = val; - if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[0], 32); break; case REG_SRC1: mystique->dwgreg.src[1] = val; - if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[1], 32); break; case REG_SRC2: mystique->dwgreg.src[2] = val; - if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[2], 32); break; case REG_SRC3: mystique->dwgreg.src[3] = val; - if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[3], 32); break; case REG_DMAPAD: - if ((mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) blit_iload_write(mystique, mystique->dwgreg.src[0], 32); break; From b892c7d874bbc40e8521cc424c9aa11221382293 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 31 Mar 2020 14:50:45 +0100 Subject: [PATCH 0829/1050] Pass the correct data to ILOAD from a write to DMAPAD. Fixes Windows 9x desktop on Matrox drivers 4.12.013. --- src/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 2e161fc..85680a3 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -1990,7 +1990,7 @@ static void mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) case REG_DMAPAD: if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[0], 32); + blit_iload_write(mystique, val, 32); break; case REG_AR0: From fb6d107e19e154f1dc692473d4df2822a771cd9e Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 1 Apr 2020 18:34:35 +0100 Subject: [PATCH 0830/1050] Add bounds checking on Mystique bus master reads. --- src/vid_mga.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index 85680a3..6d0319b 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -2341,7 +2341,15 @@ static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) } - +static uint32_t mystique_dma_read(uint32_t addr) +{ + if ((addr & DMA_ADDR_MASK) > (mem_size * 1024)) + { +// pclog("PCI DMA out of range\n"); + return -1; + } + return *(uint32_t *)&ram[addr & DMA_ADDR_MASK]; +} static void run_dma(mystique_t *mystique) { @@ -2365,14 +2373,14 @@ static void run_dma(mystique_t *mystique) case DMA_MODE_REG: if (mystique->dma.pri_state == 0) { - mystique->dma.pri_header = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; + mystique->dma.pri_header = mystique_dma_read(mystique->dma.primaddress); // pclog("DMA pri read header %08x from %08x %08x\n", mystique->dma.pri_header, mystique->dma.primaddress, mystique->dma.primend); mystique->dma.primaddress += 4; } // if ((mystique->dma.pri_header & 0xff) != 0x15) { - uint32_t val = *(uint32_t *)&ram[mystique->dma.primaddress & DMA_ADDR_MASK]; + uint32_t val = mystique_dma_read(mystique->dma.primaddress); uint32_t reg_addr; mystique->dma.primaddress += 4; @@ -2415,14 +2423,14 @@ static void run_dma(mystique_t *mystique) case DMA_MODE_REG: if (mystique->dma.sec_state == 0) { - mystique->dma.sec_header = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + mystique->dma.sec_header = mystique_dma_read(mystique->dma.secaddress); // pclog("DMA sec read header %08x from %08x %08x\n", mystique->dma.sec_header, mystique->dma.secaddress, mystique->dma.secend); mystique->dma.secaddress += 4; } // if ((mystique->dma.sec_header & 0xff) != 0x15) { - uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + uint32_t val = mystique_dma_read(mystique->dma.secaddress); uint32_t reg_addr; mystique->dma.secaddress += 4; @@ -2463,7 +2471,7 @@ static void run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { - uint32_t val = *(uint32_t *)&ram[mystique->dma.secaddress & DMA_ADDR_MASK]; + uint32_t val = mystique_dma_read(mystique->dma.secaddress); // pclog(" DMA_MODE_BLIT %08x %08x %08x %08x\n", mystique->dma.secaddress & DMA_ADDR_MASK, mystique->dma.secend & DMA_ADDR_MASK, mystique->dwgreg.dwgctrl_running, mystique->maccess_running); mystique->dma.secaddress += 4; From dfa6dac4a964196d7462a10f8b7ab5678c3a006b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 4 Apr 2020 16:01:45 +0100 Subject: [PATCH 0831/1050] Added missing mono -> 32-bit bitblt on Mystique. Fixes 32-bit colour modes in Windows 3.1. --- src/vid_mga.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vid_mga.c b/src/vid_mga.c index 6d0319b..bd416da 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -4655,6 +4655,17 @@ static void blit_bitblt(mystique_t *mystique) svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; break; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + +// pclog(" %02x %02x ", src, dst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK +// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 10] = changeframecount; + break; + default: fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } From c5a01772ed2870eadd047a010996d556f184c7f6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 10 Apr 2020 19:43:44 +0100 Subject: [PATCH 0832/1050] Mark Matrox Mystique as DEVICE_NOT_WORKING for v16. --- src/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_mga.c b/src/vid_mga.c index bd416da..4bcc091 100644 --- a/src/vid_mga.c +++ b/src/vid_mga.c @@ -5428,7 +5428,7 @@ static device_config_t mystique_config[] = device_t mystique_device = { "Matrox Mystique", - 0, + DEVICE_NOT_WORKING, mystique_init, mystique_close, mystique_available, From c90ef0be59eeda02152f2e6e82904f3041b945b7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Apr 2020 12:24:16 +0100 Subject: [PATCH 0833/1050] Don't fatal on unknown SB commands. Fixes Seek & Destroy. --- src/sound_sb_dsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 0cf391a..09f10d6 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -711,8 +711,8 @@ void sb_exec_command(sb_dsp_t *dsp) break; case 0x38: /*TODO: AZTECH MIDI-related? */ break; - default: - fatal("Exec bad SB command %02X\n",dsp->sb_command); +// default: +// fatal("Exec bad SB command %02X\n",dsp->sb_command); /*TODO: Some more data about the DSP registeres From 9db376c4d2582d11b39aa1ee310d313df7d7fddd Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Apr 2020 12:24:43 +0100 Subject: [PATCH 0834/1050] Add Aztech guards to SB DSP command 0x09. --- src/sound_sb_dsp.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 09f10d6..c7b575b 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -696,18 +696,21 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x05: break; case 0x09: /*AZTECH mode set*/ - if (dsp->sb_data[0] == 0x00) + if (IS_AZTECH(dsp)) { - pclog("AZT2316A: WSS MODE!\n"); - azt2316a_enable_wss(1, dsp->parent); + if (dsp->sb_data[0] == 0x00) + { + pclog("AZT2316A: WSS MODE!\n"); + azt2316a_enable_wss(1, dsp->parent); + } + else if (dsp->sb_data[0] == 0x01) + { + pclog("AZT2316A: SB8PROV2 MODE!\n"); + azt2316a_enable_wss(0, dsp->parent); + } + else + pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen } - else if (dsp->sb_data[0] == 0x01) - { - pclog("AZT2316A: SB8PROV2 MODE!\n"); - azt2316a_enable_wss(0, dsp->parent); - } - else - pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen break; case 0x38: /*TODO: AZTECH MIDI-related? */ break; From 5e437fc7364d48fc50190c730685b87d6a324c74 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 11 Apr 2020 14:47:19 +0100 Subject: [PATCH 0835/1050] Fallback to old MPU behaviour on SB cards. Fixes SB16/AWE32 initialisation on Windows 3.1. --- src/sound_azt2316a.c | 2 +- src/sound_mpu401_uart.c | 21 ++++++++++++++++----- src/sound_mpu401_uart.h | 4 +++- src/sound_sb.c | 4 ++-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/sound_azt2316a.c b/src/sound_azt2316a.c index b5fda11..da41bce 100644 --- a/src/sound_azt2316a.c +++ b/src/sound_azt2316a.c @@ -1446,7 +1446,7 @@ void *azt_common_init(const int type, char *nvr_filename) io_sethandler(azt2316a->cur_addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); io_sethandler(azt2316a->cur_addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, azt2316a->sb); - mpu401_uart_init(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq); + mpu401_uart_init(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, 1); azt2316a_create_config_word(azt2316a); // recreate even if we have read it from EEPROM, because we have some overrides (CD interfaces always off, etc) sound_add_handler(azt2316a_get_buffer, azt2316a); diff --git a/src/sound_mpu401_uart.c b/src/sound_mpu401_uart.c index 6ec3614..22cb638 100644 --- a/src/sound_mpu401_uart.c +++ b/src/sound_mpu401_uart.c @@ -31,16 +31,26 @@ static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) // But actual behaviour is weird. For example, the MPU401 port test in the AZT1605 drivers for Windows NT // want this to return an Ack but the IRQ test in the same driver wants this to raise no interrupts! mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = STATUS_OUTPUT_NOT_READY; mpu->uart_mode = 0; - //mpu401_uart_raise_irq(p); + if (mpu->is_aztech) + mpu->status = STATUS_OUTPUT_NOT_READY; + else + { + mpu->status = 0; + mpu401_uart_raise_irq(p); + } break; case 0x3f: /*Enter UART mode*/ mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = STATUS_OUTPUT_NOT_READY; mpu->uart_mode = 1; - mpu401_uart_raise_irq(p); + if (mpu->is_aztech) + { + mpu->status = STATUS_OUTPUT_NOT_READY; + mpu401_uart_raise_irq(p); + } + else + mpu->status = 0; break; } return; @@ -63,12 +73,13 @@ static uint8_t mpu401_uart_read(uint16_t addr, void *p) return mpu->rx_data; } -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq) +void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq, int is_aztech) { mpu->status = STATUS_INPUT_NOT_READY; mpu->uart_mode = 0; mpu->addr = addr; mpu->irq = irq; + mpu->is_aztech = is_aztech; io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); } diff --git a/src/sound_mpu401_uart.h b/src/sound_mpu401_uart.h index b133d80..9634d58 100644 --- a/src/sound_mpu401_uart.h +++ b/src/sound_mpu401_uart.h @@ -9,9 +9,11 @@ typedef struct mpu401_uart_t int uart_mode; uint16_t addr; int irq; + + int is_aztech; } mpu401_uart_t; -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq); +void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq, int is_aztech); void mpu401_uart_update_addr(mpu401_uart_t *mpu, uint16_t addr); void mpu401_uart_update_irq(mpu401_uart_t *mpu, int irq); diff --git a/src/sound_sb.c b/src/sound_sb.c index e2aa7f3..08830d0 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -1052,7 +1052,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_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_sb16, sb); - mpu401_uart_init(&sb->mpu, 0x330, -1); + mpu401_uart_init(&sb->mpu, 0x330, -1, 0); return sb; @@ -1082,7 +1082,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_ct1745_mixer_read, NULL, NULL, sb_ct1745_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_uart_init(&sb->mpu, 0x330, -1); + mpu401_uart_init(&sb->mpu, 0x330, -1, 0); emu8k_init(&sb->emu8k, emu_addr, onboard_ram); return sb; From bbbbefcd914fba21255483de69a235fb7932de93 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 16 Apr 2020 20:06:17 +0100 Subject: [PATCH 0836/1050] Remove broken additional SVGA status print from Voodoo status. Add a newline after the SB status to make SB + Voodoo read better. --- src/sound_sb_dsp.c | 1 + src/vid_voodoo.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index c7b575b..3edf0d6 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -1385,4 +1385,5 @@ void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) sprintf(temps, "SB playback frequency : %iHz\n", freq); strncat(s, temps, max_len); } + strncat(s, "\n", max_len); } diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 157d62c..36baf19 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -7477,8 +7477,6 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) if (!status_diff) status_diff = 1; - svga_add_status_info(s, max_len, &voodoo->svga); - pixel_count_current[0] = voodoo->pixel_count[0]; pixel_count_current[1] = voodoo->pixel_count[1]; texel_count_current[0] = voodoo->texel_count[0]; From 098fe35462aa26689a211257634e016f0aa63fd9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 Apr 2020 12:05:41 +0100 Subject: [PATCH 0837/1050] Tweak Sidewinder Pad timings, now works again (was broken in v15). --- src/joystick_sw_pad.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/joystick_sw_pad.c b/src/joystick_sw_pad.c index b5aab34..9bc64dc 100644 --- a/src/joystick_sw_pad.c +++ b/src/joystick_sw_pad.c @@ -4,7 +4,7 @@ - Currently alternates between Mode A and Mode B (is there any way of actually controlling which is used?) - Windows 9x drivers require Mode B when more than 1 pad connected - - Packet preceeded by high data (currently 50us), and followed by low + - Packet preceeded by high data (currently 40us), and followed by low data (currently 160us) - timings are probably wrong, but good enough for everything I've tried - Analogue inputs are only used to time ID packet request. If A0 timing @@ -55,7 +55,7 @@ static void sw_timer_over(void *p) if (sw->poll_left == 1 && !sw->poll_clock) timer_advance_u64(&sw->poll_timer, TIMER_USEC * 160); else if (sw->poll_left) - timer_advance_u64(&sw->poll_timer, TIMER_USEC * 5); + timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 5); } static void sw_trigger_timer_over(void *p) @@ -129,12 +129,10 @@ static void sw_write(void *p) if (!JOYSTICK_PRESENT(0)) return; - timer_process(); - if (!sw->poll_left) { sw->poll_clock = 1; - timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 50); + timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 40); if (time_since_last > 9900 && time_since_last < 9940) { From 798eabcac73ea33a92385f99e2bd695c6fbe3a74 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 Apr 2020 12:06:20 +0100 Subject: [PATCH 0838/1050] Rewrite SVGA status resolution code, should now be less wrong. --- src/vid_svga.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index 65443de..1f145de 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -684,8 +684,12 @@ void svga_poll(void *p) else if (!(svga->crtc[0x17] & 1)) svga->video_res_y *= 2; svga->video_res_y /= (svga->crtc[9] & 31) + 1; - if (svga->lowres) - svga->video_res_x /= 2; + if (svga->render == svga_render_8bpp_lowres || + svga->render == svga_render_15bpp_lowres || + svga->render == svga_render_16bpp_lowres || + svga->render == svga_render_24bpp_lowres || + svga->render == svga_render_32bpp_lowres) + svga->video_res_x /= 2; switch (svga->gdcreg[5] & 0x60) { From d0ea349f3f7a9df29b2613e076d785b7cdf02088 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 Apr 2020 17:12:15 +0100 Subject: [PATCH 0839/1050] Some readme.txt updating and reformatting. --- readme.txt | 1538 ++++++++++++++++++++++++++-------------------------- 1 file changed, 778 insertions(+), 760 deletions(-) diff --git a/readme.txt b/readme.txt index aca3df4..ff45709 100644 --- a/readme.txt +++ b/readme.txt @@ -23,139 +23,129 @@ PCem emulates the following machines: 8088 based : -AMI XT clone (1989) + AMI XT clone (1989) + 8088 at 8+ MHz, 64-640kb RAM. -8088 at 8+ MHz, 64-640kb RAM. - -ROM files needed: - amixt\ami_8088_bios_31jan89.bin + ROM files needed: + amixt\ami_8088_bios_31jan89.bin -Atari PC3 (19xx) + Atari PC3 (19xx) + 8088 at 8 MHz, 640kb RAM. -8088 at 8 MHz, 640kb RAM. - -ROM files needed: - ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN + ROM files needed: + ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN -Compaq Portable Plus (1983) + Compaq Portable Plus (1983) + 8088 at 4.77 MHz, 128-640kb RAM. -8088 at 4.77 MHz, 128-640kb RAM. - -ROM files needed: - compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin + ROM files needed: + compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin -DTK Clone XT (1986) + DTK Clone XT (1986) + 8088 at 8/10 MHz, 64kb-640kb RAM. -8088 at 8/10 MHz, 64kb-640kb RAM. - -ROM files needed: - dtk/dtk_erso_2.42_2764.bin + ROM files needed: + dtk/dtk_erso_2.42_2764.bin -(c)Anonymous Generic Turbo XT BIOS (1988?) + (c)Anonymous Generic Turbo XT BIOS (1988?) + 8088 at 8+ MHz, 64-640kb RAM. -8088 at 8+ MHz, 64-640kb RAM. - -ROM files needed: - genxt\pcxt.rom + ROM files needed: + genxt\pcxt.rom -IBM PC (1981) + IBM PC (1981) + 8088 at 4.77 MHz, 16-640kb RAM (PCem emulates minimum 64kb) -8088 at 4.77 MHz, 16-640kb RAM (PCem emulates minimum 64kb) - -ROM files needed: - ibmpc\pc102782.bin - ibmpc\basicc11.f6 - ibmpc\basicc11.f8 - ibmpc\basicc11.fa - ibmpc\basicc11.fc + ROM files needed: + ibmpc\pc102782.bin + ibmpc\basicc11.f6 + ibmpc\basicc11.f8 + ibmpc\basicc11.fa + ibmpc\basicc11.fc -IBM PCjr (1984) + IBM PCjr (1984) + 8088 at 4.77 MHz, 64-640kb RAM (PCem emulates minimum 128kb), built-in 16 colour graphics, 3 voice sound. + Not generally PC compatible. -8088 at 4.77 MHz, 64-640kb RAM (PCem emulates minimum 128kb), built-in 16 colour graphics, 3 voice sound. -Not generally PC compatible. - -ROM files needed: - ibmpcjr\bios.rom + ROM files needed: + ibmpcjr\bios.rom -IBM XT (1983) + IBM XT (1983) + 8088 at 4.77 MHz, 64-640kb RAM -8088 at 4.77 MHz, 64-640kb RAM - -ROM files needed: - ibmxt\5000027.u19 - ibmxt\1501512.u18 + ROM files needed: + ibmxt\5000027.u19 + ibmxt\1501512.u18 -Juko XT clone (1988) + Juko XT clone (1988) -ROM files needed: - -jukopc\000o001.bin + ROM files needed: + jukopc\000o001.bin -NCR PC4i (1985) + Leading Edge Model M (1983) + 8088 at 7.16 MHz, 128-704kB RAM -8088 at 4.77 MHz, 256-640kb RAM - -ROM files needed: - ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN + ROM files needed: + leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin -Phoenix XT clone (1986) + NCR PC4i (1985) + 8088 at 4.77 MHz, 256-640kb RAM -8088 at 8/10 MHz, 64kb-640kb RAM. - -ROM files needed: - pxxt\000p001.bin + ROM files needed: + ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN -Schneider Euro PC (1988) + Phoenix XT clone (1986) + 8088 at 8/10 MHz, 64kb-640kb RAM. -8088 at 9.54 MHz, 512-640kb RAM. - -ROM files needed: - europc\50145 - europc\50146 + ROM files needed: + pxxt\000p001.bin -Tandy 1000 (1984) + Schneider Euro PC (1988) + 8088 at 9.54 MHz, 512-640kb RAM. -8088 at 4.77 MHz, 128kb-640kb RAM, built-in 16 colour graphics + 3 voice sound - -ROM files needed: - tandy\tandy1t1.020 + ROM files needed: + europc\50145 + europc\50146 -Tandy 1000HX (1987) + Tandy 1000 (1984) + 8088 at 4.77 MHz, 128kb-640kb RAM, built-in 16 colour graphics + 3 voice sound -8088 at 7.16 MHz, 256-640kb RAM, built-in 16 colour graphics + 3 voice sound. -Has DOS 2.11 in ROM. -A Tandy 1000 with a faster 7.16 MHz 8088, and DOS in ROM. - -ROM files needed: - tandy1000hx\v020000.u12 + ROM files needed: + tandy\tandy1t1.020 -Thomson TO16 PC (1987) + Tandy 1000HX (1987) + 8088 at 7.16 MHz, 256-640kb RAM, built-in 16 colour graphics + 3 voice sound. + Has DOS 2.11 in ROM. -8088 at 9.54 MHz, 512-640kb RAM. - -ROM files needed: - to16_pc/TO16_103.bin + ROM files needed: + tandy1000hx\v020000.u12 -Toshiba T1000 (1987) + Thomson TO16 PC (1987) + 8088 at 9.54 MHz, 512-640kb RAM. -8088 at 4.77 MHz, 512-1024 kb RAM, CGA on built-in LCD. + ROM files needed: + to16_pc/TO16_103.bin -PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : + + Toshiba T1000 (1987) + 8088 at 4.77 MHz, 512-1024 kb RAM, CGA on built-in LCD. + + PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : Fn + Num Lock - toggle numpad Fn + Home - Internal LCD display Fn + Page Down - Turbo on @@ -163,121 +153,107 @@ PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supporte Fn + End - External CRT display Fn + SysRQ - Toggle window -ROM files needed: - t1000/t1000.rom - t1000/t1000font.rom + ROM files needed: + t1000/t1000.rom + t1000/t1000font.rom -VTech Laser Turbo XT (1987) + VTech Laser Turbo XT (1987) + 8088 at 10 MHz, 640kb RAM -8088 at 10 MHz, 640kb RAM - -ROM files needed: - -ltxt\27c64.bin + ROM files needed: + ltxt\27c64.bin -Zenith Data SupersPort (1987) + Zenith Data SupersPort (1987) + 8088 at 8 MHz, 128-640kb RAM. Built-in LCD video is not currently emulated -8088 at 8 MHz, 128-640kb RAM. Built-in LCD video is not currently emulated - -ROM files needed: - zdsupers/z184m v3.1d.10d + ROM files needed: + zdsupers/z184m v3.1d.10d -Xi8088 (2015) + Xi8088 (2015) + 8088 at 4.77 - 13.33 MHz, 640kb RAM -8088 at 4.77 - 13.33 MHz, 640kb RAM - -ROM files needed: - xi8088/bios-xi8088.bin + ROM files needed: + xi8088/bios-xi8088.bin 8086 based : + Amstrad PC1512 (1986) + 8086 at 8 MHz, 512kb-640kb RAM, enhanced CGA (supports 640x200x16), custom mouse port. -Amstrad PC1512 (1986) - -8086 at 8 MHz, 512kb-640kb RAM, enhanced CGA (supports 640x200x16), custom mouse port. - -ROM files needed: - pc1512\40043.v1 - pc1512\40044.v2 - pc1512\40078.ic127 + ROM files needed: + pc1512\40043.v1 + pc1512\40044.v2 + pc1512\40078.ic127 -Amstrad PC1640 (1987) + Amstrad PC1640 (1987) + 8086 at 8 MHz, 640kb RAM, built-in Paradise EGA, custom mouse port. -8086 at 8 MHz, 640kb RAM, built-in Paradise EGA, custom mouse port. - -ROM files needed: - pc1640\40043.v3 - pc1640\40044.v3 - pc1640\40100 + ROM files needed: + pc1640\40043.v3 + pc1640\40044.v3 + pc1640\40100 -Amstrad PC2086 (1989) + Amstrad PC2086 (1989) + 8086 at 8 MHz, 640kb, built-in VGA. -8086 at 8 MHz, 640kb, built-in VGA. - -ROM files needed: - pc2086\40179.ic129 - pc2086\40180.ic132 - pc2086\40186.ic171 + ROM files needed: + pc2086\40179.ic129 + pc2086\40180.ic132 + pc2086\40186.ic171 -Amstrad PC3086 (1990) + Amstrad PC3086 (1990) + 8086 at 8 MHz, 640kb, built-in VGA. -8086 at 8 MHz, 640kb, built-in VGA. - -ROM files needed: - pc3086\fc00.bin - pc3086\c000.bin + ROM files needed: + pc3086\fc00.bin + pc3086\c000.bin -Amstrad PPC512/640 (1988) + Amstrad PPC512/640 (1988) + 8086 at 8 MHz, 512-640kb RAM, built-in CGA driving plasma display. -8086 at 8 MHz, 512-640kb RAM, built-in CGA driving plasma display. - -ROM files needed: - ppc512/40107.v2 - ppc512/40108.v2 - ppc512/40109.bin + ROM files needed: + ppc512/40107.v2 + ppc512/40108.v2 + ppc512/40109.bin -Olivetti M24 (1984) + Olivetti M24 (1984) + 8086 at 8 MHz, 128kb-640kb RAM, built-in enhanced CGA (supports 640x400x2). -8086 at 8 MHz, 128kb-640kb RAM, built-in enhanced CGA (supports 640x400x2). - -ROM files needed: - olivetti_m24\olivetti_m24_version_1.43_low.bin - olivetti_m24\olivetti_m24_version_1.43_high.bin + ROM files needed: + olivetti_m24\olivetti_m24_version_1.43_low.bin + olivetti_m24\olivetti_m24_version_1.43_high.bin -Sinclair PC200/Amstrad PC20 (1988) + Sinclair PC200/Amstrad PC20 (1988) + 8086 at 8 MHz, 512-640kb RAM, built-in CGA. Video supports TV out (50 HZ PAL). -8086 at 8 MHz, 512-640kb RAM, built-in CGA. Video supports TV out (50 HZ PAL). - -ROM files needed: - pc200\pc20v2.0 - pc200\pc20v2.1 - pc200\40109.bin + ROM files needed: + pc200\pc20v2.0 + pc200\pc20v2.1 + pc200\40109.bin -Tandy 1000SL/2 (1989) + Tandy 1000SL/2 (1989) + 8086 at 9.54 MHz, 512-768kb RAM, built-in 16 colour graphics + 4 voice sound. -8086 at 9.54 MHz, 512-768kb RAM, built-in 16 colour graphics + 4 voice sound. - -ROM files needed: - tandy1000sl2\8079047.hu1 - tandy1000sl2\8079048.hu2 + ROM files needed: + tandy1000sl2\8079047.hu1 + tandy1000sl2\8079048.hu2 -Toshiba T1200 (1987) + Toshiba T1200 (1987) + 8086 at 9.54 MHz, 1-2 MB RAM, CGA on built-in LCD. -8086 at 9.54 MHz, 1-2 MB RAM, CGA on built-in LCD. - -PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : + PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : Fn + Num Lock - toggle numpad Fn + Home - Internal LCD display Fn + Page Down - Turbo on @@ -285,845 +261,876 @@ PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supporte Fn + End - External CRT display Fn + SysRQ - Toggle window -ROM files needed: - t1200/t1200_019e.ic15.bin - t1200/t1000font.rom + ROM files needed: + t1200/t1200_019e.ic15.bin + t1200/t1000font.rom -VTech Laser XT3 (1988) + VTech Laser XT3 (1988) + 8086 at 10 MHz, 512-1152kb RAM. -8086 at 10 MHz, 512-1152kb RAM. - -ROM files needed: - lxt3\27c64d.bin + ROM files needed: + lxt3\27c64d.bin 286 based : + AMI 286 clone (1990) + 286 at 8+ MHz, 512kb - 16MB RAM. -AMI 286 clone (1990) + ROM files needed: + ami286\amic206.bin -286 at 8+ MHz, 512kb - 16MB RAM. -ROM files needed: - ami286\amic206.bin + Award 286 clone (1990) + 286 at 8+ MHz, 512kb - 16MB RAM. + ROM files needed: + award286\award.bin -Award 286 clone (1990) -286 at 8+ MHz, 512kb - 16MB RAM. + Bull Micral 45 (1988) + 286 at 12 MHz, 1-6MB RAM. -ROM files needed: - award286\award.bin + ROM files needed: + bull_micral_45/even.fil + bull_micral_45/odd.fil -Bull Micral 45 (1988) + Commodore PC30-III (1988) + 286 at 12 MHz, 512kb - 16MB RAM. -286 at 12 MHz, 1-6MB RAM. + ROM files needed: + cmdpc30\commodore pc 30 iii even.bin + cmdpc30\commodore pc 30 iii odd.bin -ROM files needed: - bull_micral_45/even.fil - bull_micral_45/odd.fil + Compaq Portable II (1986) + 286 at 8 MHz, 256kb-15MB RAM. -Commodore PC30-III (1988) + ROM files needed: + compaq_pii/109739-001.rom + compaq_pii/109740-001.rom -286 at 12 MHz, 512kb - 16MB RAM. -ROM files needed: - cmdpc30\commodore pc 30 iii even.bin - cmdpc30\commodore pc 30 iii odd.bin + Dell System 200 (1990?) + 286 at 12 MHz, 640kb-16MB RAM. + ROM files needed: + dells200\dell0.bin + dells200\dell1.bin -Compaq Portable II (1986) -286 at 8 MHz, 256kb-15MB RAM. + Epson PC AX (1989) + 286, 256kb - 16MB RAM. -ROM files needed: - compaq_pii/109739-001.rom - compaq_pii/109740-001.rom + ROM files needed : + epson_pcax\EVAX + epson_pcax\ODAX -Dell System 200 (1990?) + Epson PC AX2e (1989) + 286 at 12 MHz, 256kb - 16MB RAM. -286 at 12 MHz, 640kb-16MB RAM. + ROM files needed : + epson_pcax2e\EVAX + epson_pcax2e\ODAX -ROM files needed: - dells200\dell0.bin - dells200\dell1.bin + Goldstar GDC-212M + 286 at 12 MHz, 512kb - 4MB RAM. -Epson PC AX (1989) + ROM files needed : + gdc212m/gdc212m_72h.bin -286, 256kb - 16MB RAM. -ROM files needed : - epson_pcax\EVAX - epson_pcax\ODAX + GW-286CT GEAR + 286 at 8+ MHz, 512kb - 16MB RAM. + ROM files needed: + gw286ct/2ctc001.bin -Epson PC AX2e (1989) -286 at 12 MHz, 256kb - 16MB RAM. + Hyundai Super-286TR (19xx) + 286 at 12 MHz, 1-4MB RAM -ROM files needed : - epson_pcax2e\EVAX - epson_pcax2e\ODAX + ROM files needed: + super286tr/award.bin -GW-286CT GEAR + IBM AT (1984) + 286 at 6 or 8 MHz, 256kb-16mb RAM -286 at 8+ MHz, 512kb - 16MB RAM. + ROM files needed: + ibmat\at111585.0 + ibmat\at111585.1 -ROM files needed: - gw286ct/2ctc001.bin + IBM PS/1 Model 2011 (1990) + 286 at 10 MHz, 512kb-16MB RAM, built-in VGA, DOS 4.01 + GUI menu system in ROM. + ROM files needed : + ibmps1\f80000.bin -IBM AT (1984) -286 at 6 or 8 MHz, 256kb-16mb RAM + IBM PS/2 Model 30-286 (1988) + 286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. -ROM files needed: - ibmat\at111585.0 - ibmat\at111585.1 + ROM files needed : + ibmps2_m30_286\33f5381a.bin -IBM PS/1 Model 2011 (1990) + IBM PS/2 Model 50 (1987) + 286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. -286 at 10 MHz, 512kb-16MB RAM, built-in VGA, DOS 4.01 + GUI menu system in ROM. + ROM files needed : + i8550021\90x7420.zm13 + i8550021\90x7423.zm14 + i8550021\90x7426.zm16 + i8550021\90x7429.zm18 -ROM files needed : - ibmps1\f80000.bin + IBM XT Model 286 (1986) + 286 at 6 MHz, 256kb-16mb RAM -IBM PS/2 Model 30-286 (1988) + ROM files needed : + ibmxt286\BIOS_5162_21APR86_U34_78X7460_27256.BIN + ibmxt286\BIOS_5162_21APR86_U35_78X7461_27256.BIN -286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. -ROM files needed : - ibmps2_m30_286\33f5381a.bin + Samsung SPC-4200P + 286 at 12 MHz, 512kb - 2MB RAM + ROM files needed : + spc4200p\u8.01 -IBM PS/2 Model 50 (1987) -286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. + Samsung SPC-4216P + 286 at 12 MHz, 1MB - 5MB RAM -ROM files needed : - i8550021\90x7420.zm13 - i8550021\90x7423.zm14 - i8550021\90x7426.zm16 - i8550021\90x7429.zm18 + ROM files needed : + spc4216p\phoenix.bin + or + spc4216p\7101.u8 + spc4216p\ac64.u10 -IBM XT Model 286 (1986) + Samsung SPC-4620P + 286 at 12 MHz, 1MB - 5MB RAM. Built-in Korean ATI-28800. -286 at 6 MHz, 256kb-16mb RAM + ROM files needed : + spc4620p/31005h.u8 + spc4620p/31005h.u10 + spc4620p/svb6120a_font.rom + spc4620p/31005h.u8 + spc4620p/31005h.u10 -ROM files needed : - ibmxt286\BIOS_5162_21APR86_U34_78X7460_27256.BIN - ibmxt286\BIOS_5162_21APR86_U35_78X7461_27256.BIN + Toshiba T3100e (1986) + 286 at 12 MHz, 1MB - 5MB RAM, CGA on gas-plasma display -Samsung SPC-4200P + PCem maps [Fn] to right-Ctrl and right-Alt. -286 at 12 MHz, 512kb - 2MB RAM + ROM files needed : + t3100e\t3100e_font.bin + t3100e\t3100e.rom -ROM files needed : -spc4200p\u8.01 + Tulip AT Compact (198x) + 286 at MHz, 640kb - 16 MB RAM -Samsung SPC-4216P - -286 at 12 MHz, 1MB - 5MB RAM - -ROM files needed : - spc4216p\phoenix.bin -or - spc4216p\7101.u8 - spc4216p\ac64.u10 - - -Toshiba T3100e (1986) - -286 at 12 MHz, 1MB - 5MB RAM, CGA on gas-plasma display - -PCem maps [Fn] to right-Ctrl and right-Alt. - -ROM files needed : - t3100e\t3100e_font.bin - t3100e\t3100e.rom - - -Tulip AT Compact (198x) - -286 at MHz, 640kb - 16 MB RAM - -ROM files needed : - tulip_tc7/tc7be.bin - tulip_tc7/tc7bo.bin + ROM files needed : + tulip_tc7/tc7be.bin + tulip_tc7/tc7bo.bin 386SX based : + Acermate 386SX/25N (1992?) + 386SX at 25 MHz, 2-16MB RAM, built-in Oak SVGA. -Acermate 386SX/25N (1992?) - -386SX at 25 MHz, 2-16MB RAM, built-in Oak SVGA. - -ROM files needed : - acer386\acer386.bin - acer386\oti067.bin + ROM files needed : + acer386\acer386.bin + acer386\oti067.bin -AMI 386SX clone (1994) + AMI 386SX clone (1994) + 386SX at 25 MHz, 1-16MB RAM. -386SX at 25 MHz, 1-16MB RAM. - -ROM files needed : - ami386\ami386.bin + ROM files needed : + ami386\ami386.bin -Amstrad MegaPC (1992) + Amstrad MegaPC (1992) + 386SX at 25 MHz, 1-16MB RAM, built-in VGA. -386SX at 25 MHz, 1-16MB RAM, built-in VGA. + The original machine had a built-in Sega MegaDrive. This is not emulated in PCem. -The original machine had a built-in Sega MegaDrive. This is not emulated in PCem. - -ROM files needed : - megapc\41651-bios lo.u18 - megapc\211253-bios hi.u19 + ROM files needed : + megapc\41651-bios lo.u18 + megapc\211253-bios hi.u19 -DTK 386SX clone (1990) + Commodore SL386SX-25 (1992) + 386SX at 25 MHz, 1-16MB RAM, built-in AVGA2. -386SX, 512kb - 16MB RAM. - -ROM files needed : - dtk386\3cto001.bin + ROM files needed : + cbm_sl386sx25/f000.bin + cbm_sl386sx25/c000.bin -Epson PC AX3 (1989) + DTK 386SX clone (1990) + 386SX, 512kb - 16MB RAM. -386SX at 16 MHz, 256kb-16MB RAM. - -ROM files needed : - epson_pcax3\EVAX3 - epson_pcax3\ODAX3 + ROM files needed : + dtk386\3cto001.bin -IBM PS/1 Model 2121 (1990) + Epson PC AX3 (1989) + 386SX at 16 MHz, 256kb-16MB RAM. -386SX at 20 MHz, 1MB-16MB RAM, built-in VGA. - -ROM files needed: - ibmps1_2121\fc0000.bin + ROM files needed : + epson_pcax3\EVAX3 + epson_pcax3\ODAX3 -IBM PS/2 Model 55SX (1989) + IBM PS/1 Model 2121 (1990) + 386SX at 20 MHz, 1MB-16MB RAM, built-in VGA. -386SX at 16 MHz, 1MB-8MB RAM, built-in VGA, MCA bus. - -ROM files needed : - i8555081\33f8146.zm41 - i8555081\33f8145.zm40 + ROM files needed: + ibmps1_2121\fc0000.bin -KMX-C-02 + IBM PS/2 Model 55SX (1989) + 386SX at 16 MHz, 1MB-8MB RAM, built-in VGA, MCA bus. -386SX, 512kb-16MB RAM. - -ROM files needed : - kmxc02\3ctm005.bin + ROM files needed : + i8555081\33f8146.zm41 + i8555081\33f8145.zm40 -Packard Bell Legend 300SX (1992) + KMX-C-02 + 386SX, 512kb-16MB RAM. -386 SX at 16 MHz, 1-16MB RAM + ROM files needed : + kmxc02\3ctm005.bin -ROM files needed : - pb_l300sx/pb_l300sx.bin + + Packard Bell Legend 300SX (1992) + 386 SX at 16 MHz, 1-16MB RAM + + ROM files needed : + pb_l300sx/pb_l300sx.bin 386DX based : + AMI 386DX clone (1994) + 386DX at 40 MHz, 1-32MB RAM. -AMI 386DX clone (1994) - -386DX at 40 MHz, 1-32MB RAM. - -ROM files needed: - ami386dx\opt495sx.ami + ROM files needed: + ami386dx\opt495sx.ami -Compaq Deskpro 386 (1989) + Compaq Deskpro 386 (1989) + 386DX at 20 MHz, 1MB-15MB RAM. -386DX at 20 MHz, 1MB-15MB RAM. - -ROM files needed: - deskpro386\109592-005.u11.bin - deskpro386\109591-005.u13.bin + ROM files needed: + deskpro386\109592-005.u11.bin + deskpro386\109591-005.u13.bin -IBM PS/2 Model 70 (type 3) (1989) + ECS 386/32 (1988) + 386DX at 20 MHz, 1-16MB RAM. -386DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. - -ROM files needed : - ibmps2_m70_type3/70-a_even.bin - ibmps2_m70_type3/70-a_odd.bin + ROM files needed: + ecs386_32/386_32_even.bin + ecs386_32/386_32_odd.bin -IBM PS/2 Model 80 (1987) + IBM PS/2 Model 70 (type 3) (1989) + 386DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. -386DX at 20 MHz, 1MB-12MB RAM, built-in VGA, MCA bus. - -ROM files needed : - i8580111\15f6637.bin - i8580111\15f6639.bin + ROM files needed : + ibmps2_m70_type3/70-a_even.bin + ibmps2_m70_type3/70-a_odd.bin -MR 386DX clone (1994) -This is a generic 386DX clone with an MR BIOS. + IBM PS/2 Model 80 (1987) + 386DX at 20 MHz, 1MB-12MB RAM, built-in VGA, MCA bus. -ROM files needed: + ROM files needed : + i8580111\15f6637.bin + i8580111\15f6639.bin -mr386dx\opt495sx.mr + MR 386DX clone (1994) + This is a generic 386DX clone with an MR BIOS. + + ROM files needed: + mr386dx\opt495sx.mr 486 based : + AMI 486 clone (1993) + 486 at 16-66 MHz, 1-32MB RAM. -AMI 486 clone (1993) - -486 at 16-66 MHz, 1-32MB RAM. - -ROM files needed: - ami486\ami486.bin + ROM files needed: + ami486\ami486.bin -AMI WinBIOS 486 clone (1994) + AMI WinBIOS 486 clone (1994) + 486 at 16-66 MHz, 1-32MB RAM. -486 at 16-66 MHz, 1-32MB RAM. - -ROM files needed: - win486\ali1429g.amw + ROM files needed: + win486\ali1429g.amw -Award SiS 496/497 (1995) + Award SiS 496/497 (1995) + 486 at 16-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive + at 63-83 MHz. 1-64MB RAM. -486 at 16-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive -at 63-83 MHz. 1-64MB RAM. - -ROM files needed: - sis496\sis496-1.awa + ROM files needed: + sis496\sis496-1.awa -Elonex PC-425X (1993) + Elonex PC-425X (1993) + 486SX at 25 MHz, 1-256MB RAM, built-in Trident TGUI9440CXi -486SX at 25 MHz, 1-256MB RAM, built-in Trident TGUI9440CXi - -ROM files needed: - elx_pc425x/elx_pc425x.bin -or - elx_pc425x/elx_pc425x_bios.bin - elx_pc425x/elx_pc425x_vbios.bin + ROM files needed: + elx_pc425x/elx_pc425x.bin + or + elx_pc425x/elx_pc425x_bios.bin + elx_pc425x/elx_pc425x_vbios.bin -IBM PS/2 Model 70 (type 4) (1990) + IBM PS/1 Model 2133 (EMEA 451) (1993) + 486SX at 25 MHz, 2-64MB RAM, built-in Cirrus Logic GD5426 -486DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. - -PCem's FPU emulation is not bit accurate and can not pass IBM's floating point tests. As a result, -this machine will always print 12903 and 162 errors on bootup. These can be ignored - F1 will boot -the machine. - -ROM files needed : - ibmps2_m70_type3/70-a_even.bin - ibmps2_m70_type3/70-a_odd.bin + ROM files needed: + ibmps1_2133/PS1_2133_52G2974_ROM.bin -Packard Bell PB410A (1993) + IBM PS/2 Model 70 (type 4) (1990) + 486DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. -486 at 25-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive -at 63-83 MHz. 1-64MB RAM. Built-in HT-216 video. + PCem's FPU emulation is not bit accurate and can not pass IBM's floating point tests. As a result, + this machine will always print 12903 and 162 errors on bootup. These can be ignored - F1 will boot + the machine. -ROM files needed: - pb410a/PB410A.080337.4ABF.U25.bin + ROM files needed : + ibmps2_m70_type3/70-a_even.bin + ibmps2_m70_type3/70-a_odd.bin + Packard Bell PB410A (1993) + 486 at 25-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive + at 63-83 MHz. 1-64MB RAM. Built-in HT-216 video. + + ROM files needed: + pb410a/PB410A.080337.4ABF.U25.bin + Pentium based : + ASUS P/I-P55TVP4 (1996) + Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, + Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- + PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip + 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB + RAM. -ASUS P/I-P55TVP4 (1996) - -Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, -Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- -PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip -2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB -RAM. - -ROM files needed: - p55tvp4/tv5i0204.awd + ROM files needed: + p55tvp4/tv5i0204.awd -ASUS P/I-P55T2P4 (1996) + ASUS P/I-P55T2P4 (1996) + Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, + Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- + PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip + 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-512MB + RAM. -Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, -Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- -PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip -2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-512MB -RAM. - -ROM files needed: - p55t2p4/0207_j2.bin + ROM files needed: + p55t2p4/0207_j2.bin -Award 430VX PCI (1996) + Award 430VX PCI (1996) + Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, + Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- + PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip + 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB + RAM. -Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, -Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- -PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip -2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB -RAM. - -ROM files needed: - 430vx\55xwuq0e.bin + ROM files needed: + 430vx\55xwuq0e.bin -Epox P55-VA (1997) + Epox P55-VA (1997) + Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, + Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- + PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip + 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB + RAM. -Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, -Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- -PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip -2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB -RAM. - -ROM files needed: - p55va/va021297.bin + ROM files needed: + p55va/va021297.bin -Intel Advanced/EV (Endeavor) (1995) + Intel Advanced/EV (Endeavor) (1995) + Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. -Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. + The real board has a Sound Blaster 16 onboard, and optionally an S3 Trio64V+. Neither + are emulated as onboard devices. -The real board has a Sound Blaster 16 onboard, and optionally an S3 Trio64V+. Neither -are emulated as onboard devices. - -ROM files needed: - endeavor\1006cb0_.bi0 - endeavor\1006cb0_.bi1 + ROM files needed: + endeavor\1006cb0_.bi0 + endeavor\1006cb0_.bi1 -Intel Advanced/ZP (Zappa) (1995) + Intel Advanced/ZP (Zappa) (1995) + Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. -Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. - -ROM files needed: - zappa/1006bs0_.bio - zappa/1006bs0_.bi1 + ROM files needed: + zappa/1006bs0_.bio + zappa/1006bs0_.bi1 -Intel Premiere/PCI (Batman's Revenge) (1994) + Intel Premiere/PCI (Batman's Revenge) (1994) + Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz. -Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz. - -ROM files needed: - revenge\1009af2_.bi0 - revenge\1009af2_.bi1 + ROM files needed: + revenge\1009af2_.bi0 + revenge\1009af2_.bi1 -Packard Bell PB520R (Robin LC) (1995) + Itautec Infoway Multimidia (1996) + Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 8-128MB RAM. -Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz, 1-128MB RAM, built-in Cirrus -Logic GD-5434. - -ROM files needed: - pb520r/1009bc0r.bio - pb520r/1009bc0r.bi1 - pb520r/gd5434.bin + ROM files needed: + infowaym/1006bs0_.bio + infowaym/1006bs0_.bi1 -Packard Bell PB570 (Hillary) (1995) + Packard Bell PB520R (Robin LC) (1995) + Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz, 1-128MB RAM, built-in Cirrus + Logic GD-5434. -Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM, built-in Cirrus -Logic GD-5430. + ROM files needed: + pb520r/1009bc0r.bio + pb520r/1009bc0r.bi1 + pb520r/gd5434.bin -ROM files needed: - pb570/1007by0r.bio - pb570/1007by0r.bi1 - pb570/gd5430.bin + Packard Bell PB570 (Hillary) (1995) + Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM, built-in Cirrus + Logic GD-5430. + + ROM files needed: + pb570/1007by0r.bio + pb570/1007by0r.bi1 + pb570/gd5430.bin Super Socket 7 : -FIC VA-503+ (1998) + FIC VA-503+ (1998) + AMD K6 at 166-300 MHz, AMD K6-2 at 233-550 MHz, AMD K6-III at 400-450 MHz, AMD K6-2+ + at 450-550 MHz, AMD K6-III+ at 400-500 MHz, Pentium at 75-200 MHz, Pentium MMX at + 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, Cyrix 6x86 at PR90(80 MHz)-PR200(200 + MHz), Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz), IDT WinChip at 75-240 MHz, + IDT WinChip2 at 200-250 MHz, IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz). 1-512MB + RAM. -AMD K6 at 166-300 MHz, AMD K6-2 at 233-550 MHz, AMD K6-III at 400-450 MHz, AMD K6-2+ -at 450-550 MHz, AMD K6-III+ at 400-500 MHz, Pentium at 75-200 MHz, Pentium MMX at -166-233 MHz, Mobile Pentium MMX at 120-300 MHz, Cyrix 6x86 at PR90(80 MHz)-PR200(200 -MHz), Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz), IDT WinChip at 75-240 MHz, -IDT WinChip2 at 200-250 MHz, IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz). 1-512MB -RAM. - -ROM files needed: - fic_va503p/je4333.bin + ROM files needed: + fic_va503p/je4333.bin PCem emulates the following graphics adapters : - -MDA (1981) -80x25 monochrome text. + MDA (1981) + 80x25 monochrome text. -CGA (1981) -40x25 and 80x25 text, 320x200 in 4 colours, 620x200 in 2 colours. Supports composite -output for ~16 colours. + CGA (1981) + 40x25 and 80x25 text, 320x200 in 4 colours, 620x200 in 2 colours. Supports composite + output for ~16 colours. -Hercules (1982) -80x25 monochrome text, 720x348 in monochrome. + Hercules (1982) + 80x25 monochrome text, 720x348 in monochrome. -Plantronics ColorPlus -An enhanced CGA board, with support for 320x200x16 and 640x200x4. + Plantronics ColorPlus + An enhanced CGA board, with support for 320x200x16 and 640x200x4. -Wyse WY-700 -A CGA-compatible board, with support for a 1280x800 mode + Wyse WY-700 + A CGA-compatible board, with support for a 1280x800 mode -IBM EGA (1984) -Text up to 80x43, graphics up to 640x350 in 16 colours. + MDSI Genius + Mono portrait board, with support for a 728x1008 mode. -ROM files needed: - ibm_6277356_ega_card_u44_27128.bin + ROM files needed: + 8x12.bin -Hercules InColor -An enhanced Hercules with a custom 720x350 16 colour mode. + IBM EGA (1984) + Text up to 80x43, graphics up to 640x350 in 16 colours. + + ROM files needed: + ibm_6277356_ega_card_u44_27128.bin + + + ATI EGA Wonder 800+ + An enhanced EGA-compatible board, with support for up to 800x600 in 16 colours + + ROM files needed: + ATI EGA Wonder 800+ N1.00.BIN + + + Hercules InColor + An enhanced Hercules with a custom 720x350 16 colour mode. Unaccelerated (S)VGA cards : + ATI Korean VGA + ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. Korean font support. -ATI Korean VGA -ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. Korean font support. - -ROM files needed: - atikorvga.bin - ati_ksc5601.rom + ROM files needed: + atikorvga.bin + ati_ksc5601.rom -ATI VGA Edge-16 -ATI-18800 based. 512kb VRAM, supports up to 8-bit colour. + ATI VGA Edge-16 + ATI-18800 based. 512kb VRAM, supports up to 8-bit colour. -ROM files needed: - vgaedge16.vbi + ROM files needed: + vgaedge16.vbi -ATI VGA Charger -ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. + ATI VGA Charger + ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. -ROM files needed: - bios.bin + ROM files needed: + bios.bin -IBM VGA (1987) -256kb VRAM, Text up to 80x50, graphics up to 320x200 in 256 colours or 640x480 in 16 colours. + AVGA2 + Also known as Cirrus Logic GD5402. 256-512kb VRAM, supports up to 8-bit colour. -ROM files needed: - ibm_vga.bin + ROM files needed: + avga2vram.vbi -OAK OTI-037C -256kb VRAM, supports up to 8-bit colour. + IBM VGA (1987) + 256kb VRAM, Text up to 80x50, graphics up to 320x200 in 256 colours or 640x480 in 16 colours. -ROM files needed: - oti037\bios.bin + ROM files needed: + ibm_vga.bin -OAK OTI-067 -256kb-512kb VRAM, supports up to 8-bit colour. + OAK OTI-037C + 256kb VRAM, supports up to 8-bit colour. -ROM files needed: - oti067\bios.bin + ROM files needed: + oti037\bios.bin -Olivetti GO481 (Paradise PVGA1A) -256kb VRAM, supports up to 8-bit colour. + OAK OTI-067 + 256kb-512kb VRAM, supports up to 8-bit colour. -ROM files needed : - oli_go481_lo.bin - oli_go481_hi.bin + ROM files needed: + oti067\bios.bin -Trident 8900D SVGA -256kb-1MB VRAM, supports up to 24-bit colour. + Olivetti GO481 (Paradise PVGA1A) + 256kb VRAM, supports up to 8-bit colour. -ROM files needed: - trident.bin + ROM files needed : + oli_go481_lo.bin + oli_go481_hi.bin -Trident TGUI9400CXi -1-2MB VRAM, supports up to 24-bit colour. + Trident 8900D SVGA + 256kb-1MB VRAM, supports up to 24-bit colour. -ROM files needed: -9440.vbi + ROM files needed: + trident.bin -Tseng ET4000AX SVGA -1MB VRAM, supports up to 8-bit colour. + Trident TGUI9400CXi + 1-2MB VRAM, supports up to 24-bit colour. -ROM files needed: - et4000.bin + ROM files needed: + 9440.vbi + + + Tseng ET4000AX SVGA + 1MB VRAM, supports up to 8-bit colour. + + ROM files needed: + et4000.bin 2D accelerated SVGA cards : -ATI Graphics Pro Turbo -Mach64GX based. 1-4MB VRAM. + ATI Graphics Pro Turbo + Mach64GX based. 1-4MB VRAM. -ROM files needed: - mach64gx\bios.bin + ROM files needed: + mach64gx\bios.bin -ATI Video Xpression -Mach64VT2 based. 2-4MB VRAM. Has video acceleration. + ATI Video Xpression + Mach64VT2 based. 2-4MB VRAM. Has video acceleration. -ROM files needed : - atimach64vt2pci.bin + ROM files needed : + atimach64vt2pci.bin -Cirrus Logic GD-5429 -1-2MB VRAM. + Cirrus Logic GD-5428 + 1-2MB VRAM. -ROM files needed: - 5429.vbi + ROM files needed: + Machspeed_VGA_GUI_2100_VLB.vbi -Cirrus Logic GD-5430 -1-2MB VRAM. + Cirrus Logic GD-5429 + 1-2MB VRAM. -ROM files needed: - gd5430/pci.bin + ROM files needed: + 5429.vbi -Cirrus Logic GD-5434 -2-4MB VRAM. Real chip also supports 1MB configurations, however this is not currently -supported in PCem. + Cirrus Logic GD-5430 + 1-2MB VRAM. -ROM files needed: - gd5434.bin + ROM files needed: + gd5430/pci.bin -Diamond Stealth 32 SVGA -ET4000/W32p based. 1-2MB VRAM. + Cirrus Logic GD-5434 + 2-4MB VRAM. Real chip also supports 1MB configurations, however this is not currently + supported in PCem. -ROM files needed: - et4000w32.bin + ROM files needed: + gd5434.bin -Number Nine 9FX -S3 Trio64 based. 1-2MB VRAM. + Diamond Stealth 32 SVGA + ET4000/W32p based. 1-2MB VRAM. -ROM files needed: - s3_764.bin + ROM files needed: + et4000w32.bin -Paradise Bahamas 64 -S3 Vision864 based. 1-4MB VRAM. + IBM 1MB SVGA Adapter/A + Cirrus Logic GD5428 based. 1 MB VRAM. Only supported on PS/2 models. -ROM files needed: - bahamas64.bin + ROM files needed: + SVGA141.ROM + + Number Nine 9FX + S3 Trio64 based. 1-2MB VRAM. + + ROM files needed: + s3_764.bin -Phoenix S3 Trio32 -S3 Trio32 based. 512kb-2MB VRAM. + Paradise Bahamas 64 + S3 Vision864 based. 1-4MB VRAM. -ROM files needed: - 86c732p.bin + ROM files needed: + bahamas64.bin -Phoenix S3 Trio64 -S3 Trio64 based. 1MB-4MB VRAM. + Phoenix S3 Trio32 + S3 Trio32 based. 512kb-2MB VRAM. -ROM files needed: - 86c764x1.bin + ROM files needed: + 86c732p.bin -Trident TGUI9440 -Trident TGUI9440 based. 1-2MB VRAM. + Phoenix S3 Trio64 + S3 Trio64 based. 1MB-4MB VRAM. -ROM files needed: -9440.vbi + ROM files needed: + 86c764x1.bin + Trident TGUI9440 + Trident TGUI9440 based. 1-2MB VRAM. + + ROM files needed: + 9440.vbi + 3D accelerated SVGA cards : + Diamond Stealth 3D 2000 + S3 ViRGE/325 based. 2-4MB VRAM. -Diamond Stealth 3D 2000 -S3 ViRGE/325 based. 2-4MB VRAM. + PCem emulates the ViRGE S3D engine in software. This works with most games I tried, but + there may be some issues. The Direct3D drivers for the /325 are fairly poor (often showing + as missing triangles), so use of the /DX instead is recommended. -PCem emulates the ViRGE S3D engine in software. This works with most games I tried, but -there may be some issues. The Direct3D drivers for the /325 are fairly poor (often showing -as missing triangles), so use of the /DX instead is recommended. + The streams processor (video overlay) is also emulated, however many features are missing. -The streams processor (video overlay) is also emulated, however many features are missing. - -ROM files needed: - s3virge.bin + ROM files needed: + s3virge.bin -S3 ViRGE/DX -S3 ViRGE/DX based. 2-4MB VRAM. + S3 ViRGE/DX + S3 ViRGE/DX based. 2-4MB VRAM. -The drivers that come with Windows are similar to those for the /325, however better ones -do exist (try the 8-21-1997 version). With the correct drivers, many early Direct3D games -work okay (if slowly). + The drivers that come with Windows are similar to those for the /325, however better ones + do exist (try the 8-21-1997 version). With the correct drivers, many early Direct3D games + work okay (if slowly). -ROM files needed: -86c375_1.bin + ROM files needed: + 86c375_1.bin 3D only cards : -3DFX Voodoo Graphics -3D accelerator. Widely supported in late 90s games. + 3DFX Voodoo Graphics + 3D accelerator. Widely supported in late 90s games. -PCem emulates this in software. The emulation is a lot faster than in v10 (thanks to a new -dynamic recompiler) and should be capable of hitting Voodoo 1 performance on most machines -when two render threads are used. As before, the emulated CPU is the bottleneck for most games. + PCem emulates this in software. The emulation is a lot faster than in v10 (thanks to a new + dynamic recompiler) and should be capable of hitting Voodoo 1 performance on most machines + when two render threads are used. As before, the emulated CPU is the bottleneck for most games. -PCem can emulate 6 and 8 MB configurations, but defaults to 4 MB for compatibility. It can also -emulate the screen filter present on the original card, though this does at present have a -noticeable performance hit. + PCem can emulate 6 and 8 MB configurations, but defaults to 4 MB for compatibility. It can also + emulate the screen filter present on the original card, though this does at present have a + noticeable performance hit. -Almost everything I've tried works okay, with a very few exceptions - Screamer 2 and Rally have -serious issues. + Almost everything I've tried works okay, with a very few exceptions - Screamer 2 and Rally have + serious issues. -Obsidian SB50 -Voodoo Graphics with 2 TMUs. Drivers for this are a bit limited - the official drivers don't -support 2 TMUs in Direct3D. + Obsidian SB50 + Voodoo Graphics with 2 TMUs. Drivers for this are a bit limited - the official drivers don't + support 2 TMUs in Direct3D. -Voodoo 2 -Improved Voodoo Graphics - higher clocks, 2 TMUs, triangle setup etc. + Voodoo 2 + Improved Voodoo Graphics - higher clocks, 2 TMUs, triangle setup etc. -PCem can emulate both 8 and 12 MB configurations. It can also emulate 6 and 10 MB configurations -(with 2MB framebuffer memory), which were never sold into the PC market but do exist for arcade -systems. + PCem can emulate both 8 and 12 MB configurations. It can also emulate 6 and 10 MB configurations + (with 2MB framebuffer memory), which were never sold into the PC market but do exist for arcade + systems. Some models have fixed graphics adapters : -Amstrad MegaPC -Paradise 90C11. A development of the PVGA1, with 512kb VRAM. Can use external video card. + Amstrad MegaPC + Paradise 90C11. A development of the PVGA1, with 512kb VRAM. Can use external video card. -Acer 386SX/25N -Oak OTI-067. Another 512kb SVGA clone. Can use external video card. + Acer 386SX/25N + Oak OTI-067. Another 512kb SVGA clone. Can use external video card. -Amstrad PC1512 -CGA with a new mode (640x200x16). + Amstrad PC1512 + CGA with a new mode (640x200x16). -Amstrad PC1640 -Paradise EGA. Can use external video card. + Amstrad PC1640 + Paradise EGA. Can use external video card. -Amstrad PC2086/PC3086 -Paradise PVGA1. An early SVGA clone with 256kb VRAM. Can use external video card. + Amstrad PC2086/PC3086 + Paradise PVGA1. An early SVGA clone with 256kb VRAM. Can use external video card. -Amstrad PPC512/640 -CGA/MDA outputting to 640x200 plasma display. Can use external video card. + Amstrad PPC512/640 + CGA/MDA outputting to 640x200 plasma display. Can use external video card. -Elonex PC-425X -Trident TGUI9400CXi with 512kb VRAM. + Commodore SL386SX-25 + AVGA2 with 256-512kb VRAM. -IBM PCjr -CGA with various new modes - 160x200x16, 320x200x16, 640x200x4. + Elonex PC-425X + Trident TGUI9400CXi with 512kb VRAM. -IBM PS/1 Model 2011 -Stock VGA with 256kb VRAM. + IBM PCjr + CGA with various new modes - 160x200x16, 320x200x16, 640x200x4. -IBM PS/1 Model 2121 -Basic (and unknown) SVGA with 256kb VRAM. + IBM PS/1 Model 2011 + Stock VGA with 256kb VRAM. -IBM PS/2 machines -Stock VGA with 256kb VRAM. + IBM PS/1 Model 2121 + Basic (and unknown) SVGA with 256kb VRAM. -Olivetti M24 -CGA with double-res text modes and a 640x400 mode. I haven't seen a dump of the font -ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd -as it is 14-line instead of 16-line. + IBM PS/2 machines + Stock VGA with 256kb VRAM. -Packard Bell PB410A -Headland HT-216. Can use external video card. + Olivetti M24 + CGA with double-res text modes and a 640x400 mode. I haven't seen a dump of the font + ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd + as it is 14-line instead of 16-line. -Packard Bell PB520R -Cirrus Logic GD-5434. Can use external video card. + Packard Bell PB410A + Headland HT-216. Can use external video card. -Packard Bell PB570 -Cirrus Logic GD-5430. Can use external video card. + Packard Bell PB520R + Cirrus Logic GD-5434. Can use external video card. -Sinclair PC200 -CGA. Can use external video card. Internal video can output to a TV, as this is a UK machine -this runs at 50 Hz. + Packard Bell PB570 + Cirrus Logic GD-5430. Can use external video card. -Tandy 1000 -Clone of PCjr video. Widely supported in 80s games. + Sinclair PC200 + CGA. Can use external video card. Internal video can output to a TV, as this is a UK machine + this runs at 50 Hz. -Tandy 1000 SL/2 -Improvement of Tandy 1000, with support for 640x200x16. + Tandy 1000 + Clone of PCjr video. Widely supported in 80s games. -Toshiba T-series -CGA on built-in LCD or plasma display. + Tandy 1000 SL/2 + Improvement of Tandy 1000, with support for 640x200x16. + + Toshiba T-series + CGA on built-in LCD or plasma display. PCem emulates the following sound devices : -PC speaker -The standard beeper on all PCs. Supports samples/RealSound. + PC speaker + The standard beeper on all PCs. Supports samples/RealSound. -Tandy PSG -The Texas Instruments chip in the PCjr and Tandy 1000. Supports 3 voices plus -noise. I reused the emulator in B-em for this (slightly modified). -PCem emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 -(currently assigned to the Tandy 1000HX). Maniac Mansion and Zak McKraken will only sound -correct on the latter. + Tandy PSG + The Texas Instruments chip in the PCjr and Tandy 1000. Supports 3 voices plus + noise. I reused the emulator in B-em for this (slightly modified). + PCem emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 + (currently assigned to the Tandy 1000HX). Maniac Mansion and Zak McKraken will only sound + correct on the latter. -Tandy PSSJ -Used on the Tandy 1000SL/2, this clones the NCR8496, adding an addition frequency divider (did any -software actually use this?) and an 8-bit DAC. + Tandy PSSJ + Used on the Tandy 1000SL/2, this clones the NCR8496, adding an addition frequency divider (did any + software actually use this?) and an 8-bit DAC. -PS/1 audio card -An SN76496 clone plus an 8-bit DAC. The SN76496 isn't at the same address as PCjr/Tandy, so most -software doesn't support it. + PS/1 audio card + An SN76496 clone plus an 8-bit DAC. The SN76496 isn't at the same address as PCjr/Tandy, so most + software doesn't support it. -Gameblaster -The Creative Labs Gameblaster/Creative Music System, Creative's first sound card -introduced in 1987. Has two Philips SAA1099, giving 12 voices of square waves plus 4 noise -voices. In stereo! + Gameblaster + The Creative Labs Gameblaster/Creative Music System, Creative's first sound card + introduced in 1987. Has two Philips SAA1099, giving 12 voices of square waves plus 4 noise + voices. In stereo! -Adlib -Has a Yamaha YM3812, giving 9 voices of 2 op FM, or 6 voices plus a rhythm section. PCem -uses the DOSBox dbopl emulator. + Adlib + Has a Yamaha YM3812, giving 9 voices of 2 op FM, or 6 voices plus a rhythm section. PCem + uses the DOSBox dbopl emulator. -Adlib Gold -OPL3 with YM318Z 12-bit digital section. Possibly some bugs (not a lot of software to test). -The surround module is now emulated. + Adlib Gold + OPL3 with YM318Z 12-bit digital section. Possibly some bugs (not a lot of software to test). + The surround module is now emulated. -Sound Blaster -Several Sound Blasters are emulated : + Sound Blaster + Several Sound Blasters are emulated : SB v1.0 - The original. Limited to 22khz, and no auto-init DMA (can cause crackles sometimes). SB v1.5 - Adds auto-init DMA SB v2.0 - Upped to 41khz @@ -1131,153 +1138,164 @@ Several Sound Blasters are emulated : SB Pro v2.0 - Stereo, with OPL 3 chip SB 16 - 16 bit stereo SB AWE32 - SB 16 + wavetable MIDI. This requires a ROM dump from a real AWE32. -All are set to Address 220, IRQ 7 and DMA 1 (and High DMA 5). IRQ and DMA can be changed for the -SB16 & AWE32 in the drivers. -The relevant SET line for autoexec.bat is - SET BLASTER = A220 I7 D1 Tx - where Tx is T1 for SB v1.0, T3 for SB v2.0, T4 for SB Pro, + All are set to Address 220, IRQ 7 and DMA 1 (and High DMA 5). IRQ and DMA can be changed for the + SB16 & AWE32 in the drivers. + The relevant SET line for autoexec.bat is + SET BLASTER = A220 I7 D1 Tx - where Tx is T1 for SB v1.0, T3 for SB v2.0, T4 for SB Pro, and T6 for SB16. -AWE32 requires a ROM dump called awe32.raw. AWE-DUMP is a utility which can get a dump from a real -card. Most EMU8000 functionality should work, however filters are not correct and reverb/chorus -effects are not currently emulated. + AWE32 requires a ROM dump called awe32.raw. AWE-DUMP is a utility which can get a dump from a real + card. Most EMU8000 functionality should work, however filters are not correct and reverb/chorus + effects are not currently emulated. -Gravis Ultrasound -32 voice sample playback. Port address is fixed to 240, IRQ and DMA can be changed from the drivers. -Emulation is improved significantly over previous versions. + Gravis Ultrasound + 32 voice sample playback. Port address is fixed to 240, IRQ and DMA can be changed from the drivers. + Emulation is improved significantly over previous versions. -Windows Sound System -16-bit digital + OPL3. Note that this only emulates WSS itself, and should not be used with drivers -from compatible boards with additional components (eg Turtle Beach Monte Carlo) + Windows Sound System + 16-bit digital + OPL3. Note that this only emulates WSS itself, and should not be used with drivers + from compatible boards with additional components (eg Turtle Beach Monte Carlo) -Innovation SSI-2001 -SID6581. Emulated using resid-fp. Board is fixed to port 280. + Aztech Sound Galaxy Pro 16 AB (Washington) + SB compatible + WSS compatible -Ensoniq AudioPCI (ES1371) / Sound Blaster PCI 128 -Basic PCI sound card. Emulates Sound Blaster in software. + Innovation SSI-2001 + SID6581. Emulated using resid-fp. Board is fixed to port 280. + + Ensoniq AudioPCI (ES1371) / Sound Blaster PCI 128 + Basic PCI sound card. Emulates Sound Blaster in software. PCem emulates the following hard drive controllers : -[MFM] Fixed Disk Adapter (Xebec) -MFM controller originally included in the IBM XT. This controller only supports HD types 0, 2, 13 -and 16. + [MFM] Fixed Disk Adapter (Xebec) + MFM controller originally included in the IBM XT. This controller only supports HD types 0, 2, 13 + and 16. -ROM files needed : -ibm_xebec_62x0822_1985.bin + ROM files needed : + ibm_xebec_62x0822_1985.bin -[MFM] DTC 5150X -8-bit MFM controller. To configure drive types, run DEBUG.EXE and enter 'g=c800:5'. + [MFM] DTC 5150X + 8-bit MFM controller. To configure drive types, run DEBUG.EXE and enter 'g=c800:5'. -ROM files needed : -dtc_cxd21a.bin + ROM files needed : + dtc_cxd21a.bin -[MFM] AT Fixed Disk Adapter -MFM controller originally included in the IBM AT. Supported by all AT-compatible BIOSes. + [MFM] AT Fixed Disk Adapter + MFM controller originally included in the IBM AT. Supported by all AT-compatible BIOSes. -[ESDI] Western Digital WD1007V-SE1 -16-bit ESDI controller. + [ESDI] Western Digital WD1007V-SE1 + 16-bit ESDI controller. -ROM files needed : -62-000279-061.bin + ROM files needed : + 62-000279-061.bin -[ESDI] IBM ESDI Fixed Disk Controller -MCA ESDI controller. Only supported on PS/2 models. + [ESDI] IBM ESDI Fixed Disk Controller + MCA ESDI controller. Only supported on PS/2 models. -ROM files needed : -90x8969.bin -90x8970.bin + ROM files needed : + 90x8969.bin + 90x8970.bin -[IDE] Standard IDE -Standard IDE controller. Supported by all AT-compatible BIOSes. Use this if in any doubt! + [IDE] Standard IDE + Standard IDE controller. Supported by all AT-compatible BIOSes. Use this if in any doubt! -[IDE] XTIDE -8-bit IDE controller. The BIOS is available at : + [IDE] XTIDE + 8-bit IDE controller. The BIOS is available at : -http://code.google.com/p/xtideuniversalbios/ + http://code.google.com/p/xtideuniversalbios/ -v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues. + v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues. -ROM files needed : -ide_xt.bin + ROM files needed : + ide_xt.bin -[IDE] XTIDE (AT) -16-bit IDE controller. + [IDE] XTIDE (AT) + 16-bit IDE controller. -ROM files needed : -ide_at.bin + ROM files needed : + ide_at.bin -[IDE] XTIDE (PS/1) -IDE controller for the PS/1 model 2033. For this machine you will need BIOS version v1.1.5. The -PS/1 is a bit fussy with XTIDE, and I've found that it works best when the XTIDE configuration -has 'Full Operating Mode' disabled. + [IDE] XTIDE (PS/1) + IDE controller for the PS/1 model 2033. For this machine you will need BIOS version v1.1.5. The + PS/1 is a bit fussy with XTIDE, and I've found that it works best when the XTIDE configuration + has 'Full Operating Mode' disabled. -ROM files needed : -ide_at_1_1_5.bin + ROM files needed : + ide_at_1_1_5.bin -[SCSI] Longshine LCS-6821N -8-bit SCSI controller. + [SCSI] Longshine LCS-6821N + 8-bit SCSI controller. -ROM files needed : -Longshine LCS-6821N - BIOS version 1.04.bin + ROM files needed : + Longshine LCS-6821N - BIOS version 1.04.bin -[SCSI] Rancho RT1000B -8-bit SCSI controller. + [SCSI] Rancho RT1000B + 8-bit SCSI controller. -ROM files needed : -Rancho_RT1000_RTBios_version_8.10R.bin + ROM files needed : + Rancho_RT1000_RTBios_version_8.10R.bin -[SCSI] Trantor T130B -8-bit SCSI controller. + [SCSI] Trantor T130B + 8-bit SCSI controller. -ROM files needed : -trantor_t130b_bios_v2.14.bin + ROM files needed : + trantor_t130b_bios_v2.14.bin -[SCSI] Adaptec AHA-1542C -16-bit SCSI controller. + [SCSI] IBM SCSI Adapter with Cache + MCA SCSI controller. Only supported on PS/2 models. -ROM files needed : -adaptec_aha1542c_bios_534201-00.bin + ROM files needed : + 92F2244.U68 + 92F2245.U69 -[SCSI] BusLogic BT-545S -16-bit SCSI controller. + [SCSI] Adaptec AHA-1542C + 16-bit SCSI controller. -ROM files needed : -BusLogic_BT-545S_U15_27128_5002026-4.50.bin + ROM files needed : + adaptec_aha1542c_bios_534201-00.bin + + + [SCSI] BusLogic BT-545S + 16-bit SCSI controller. + + ROM files needed : + BusLogic_BT-545S_U15_27128_5002026-4.50.bin Other stuff emulated : Serial mouse -A Microsoft compatible serial mouse on COM1. Compatible drivers are all over the place for this. + A Microsoft compatible serial mouse on COM1. Compatible drivers are all over the place for this. M24 mouse -I haven't seen a DOS mouse driver for this yet, but the regular scancode mode works, as does the -Windows 1.x driver. + I haven't seen a DOS mouse driver for this yet, but the regular scancode mode works, as does the + Windows 1.x driver. PC1512 mouse -The PC1512's perculiar quadrature mouse. You need Amstrad's actual driver for this one. + The PC1512's perculiar quadrature mouse. You need Amstrad's actual driver for this one. PS/2 mouse -A standard 2 button PS/2 mouse. As with serial, compatible drivers are common. + A standard 2 button PS/2 mouse. As with serial, compatible drivers are common. Microsoft PS/2 Intellimouse -A PS/2 mouse with mouse wheel. + A PS/2 mouse with mouse wheel. ATAPI CD-ROM -Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've tried. + Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've tried. From bc42a068c023f0d3e9813a6e26b884fb860bb749 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 Apr 2020 17:12:58 +0100 Subject: [PATCH 0840/1050] Don't require gd5434.bin for Itautec Infoway Multimidia; it isn't currently used. --- src/mem_bios.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mem_bios.c b/src/mem_bios.c index c0e776e..6da00e9 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -924,8 +924,8 @@ int loadbios() // keep separate from generic Zappa because there is a BIOS logo // in flash.bin case ROM_ITAUTEC_INFOWAYM: - if (!rom_present("infowaym/gd5434.bin")) - break; +// if (!rom_present("infowaym/gd5434.bin")) +// break; f = romfopen("infowaym/1006bs0_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); From adfda61a2f8b7d1dbb57582a0938d7abc2d24846 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 18 Apr 2020 17:13:24 +0100 Subject: [PATCH 0841/1050] Initialise AT keyboard scancode set properly on reset. --- src/keyboard_at.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4acd81d..40987c1 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -774,6 +774,7 @@ void keyboard_at_init() keyboard_at.mouse_p = NULL; keyboard_at.is_ps2 = 0; keyboard_set_scancode_set(SCANCODE_SET_2); + keyboard_at.scancode_set = SCANCODE_SET_2; timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1); } From d0c7ea56a7d2a51717060f935db2de615ec88c65 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 Apr 2020 15:50:51 +0100 Subject: [PATCH 0842/1050] Update version number to v16. --- Readme-BSD.txt | 2 +- Readme-LINUX.txt | 2 +- readme.txt | 25 +++++++++++-------------- src/pc.c | 2 +- src/wx-sdl2-display-win.c | 2 +- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Readme-BSD.txt b/Readme-BSD.txt index f129d58..e100c85 100644 --- a/Readme-BSD.txt +++ b/Readme-BSD.txt @@ -1,4 +1,4 @@ -PCem v15 BSD supplement +PCem v16 BSD supplement You will need the following libraries : diff --git a/Readme-LINUX.txt b/Readme-LINUX.txt index a6d36da..766db70 100644 --- a/Readme-LINUX.txt +++ b/Readme-LINUX.txt @@ -1,4 +1,4 @@ -PCem v15 Linux supplement +PCem v16 Linux supplement You will need the following libraries : diff --git a/readme.txt b/readme.txt index ff45709..3a4b244 100644 --- a/readme.txt +++ b/readme.txt @@ -1,22 +1,19 @@ -PCem v15 +PCem v16 PCem is licensed under the GPL, see COPYING for more details. -Changes since v14: -- New machines added - Zenith Data SupersPort, Bull Micral 45, Tulip AT Compact, - Amstrad PPC512/640, Packard Bell PB410A, ASUS P/I-P55TVP4, ASUS P/I-P55T2P4, - Epox P55-VA, FIC VA-503+ -- New graphics cards added - Image Manager 1024, Sigma Designs Color 400, - Trigem Korean VGA -- Added emulation of AMD K6 family and IDT Winchip 2 -- New CPU recompiler. This provides several optimisations, and the new design allows - for greater portability and more scope for optimisation in the future -- Experimental ARM and ARM64 host support -- Read-only cassette emulation for IBM PC and PCjr +Changes since v15 +- New machines added - Commodore SL386SX-25, ECS 386/32, Goldstar GDC-212M, + Hyundai Super-286TR, IBM PS/1 Model 2133 (EMEA 451), Itautec Infoway Multimidia, + Samsung SPC-4620P, Leading Edge Model M +- New graphics cards added - ATI EGA Wonder 800+, AVGA2, Cirrus Logic GD5428, + IBM 1MB SVGA Adapter/A +- New sound card added - Aztech Sound Galaxy Pro 16 AB (Washington) +- New SCSI card added - IBM SCSI Adapter with Cache +- Support FPU emulation on pre-486 machines - Numerous bug fixes -Thanks to dns2kv2, Greatpsycho, Greg V, John Elliott, Koutakun, leilei, Martin_Riarte, -rene, Tale and Tux for contributions towards this release. +Thanks to EluanCM, Greatpsycho, John Elliott, and leilei for contributions towards this release. PCem emulates the following machines: diff --git a/src/pc.c b/src/pc.c index 93f9f2b..4779266 100644 --- a/src/pc.c +++ b/src/pc.c @@ -582,7 +582,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v15 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem v16 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 974e958..57f92e6 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -595,7 +595,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v15", /* Title Text */ + "PCem v16", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From c49fcff413e4a770511ad352576c0a47d18591c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 19 Apr 2020 16:30:54 +0100 Subject: [PATCH 0843/1050] Update autoconf version to v16. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0e1b3d2..42f8716 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # AC_PREREQ([2.61]) -AC_INIT(PCem, v14, Sarah Walker , pcem) +AC_INIT(PCem, v16, Sarah Walker , pcem) AC_CANONICAL_HOST From 1f63723d9d6d1d911e2fc2660cd890e14ab95cb8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 20 Jun 2020 18:40:53 +0100 Subject: [PATCH 0844/1050] Add -fcommon to configure.ac. Should fix building on GCC 10.x. --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 42f8716..baf37d8 100644 --- a/configure.ac +++ b/configure.ac @@ -27,12 +27,12 @@ AC_MSG_CHECKING([whether to enable debugging]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [build debug executable])) if test "$enable_debug" = "yes"; then - CFLAGS="-Wall -O0 -g -D_DEBUG" - CXXFLAGS="-Wall -O0 -g -D_DEBUG" + CFLAGS="-Wall -O0 -g -D_DEBUG -fcommon" + CXXFLAGS="-Wall -O0 -g -D_DEBUG -fcommon" AC_MSG_RESULT([yes]) else - CFLAGS="-O3" - CXXFLAGS="-O3" + CFLAGS="-O3 -fcommon" + CXXFLAGS="-O3 -fcommon" AC_MSG_RESULT([no]) fi From bb7dff751e178b5c9360be702286a7c48772a4d7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:07:02 +0100 Subject: [PATCH 0845/1050] Enable shadow RAM control at A0000-BFFFF on CS8230 chipset (ECS 386/32). Patch from Greatpsycho. --- src/cs8230.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cs8230.c b/src/cs8230.c index 783c179..c2125ed 100644 --- a/src/cs8230.c +++ b/src/cs8230.c @@ -112,4 +112,9 @@ void cs8230_init(void) cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, NULL); + if (mem_size > 768) + { + mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); + } } From 7570ba4271abaf5822254a3b4b740b3f507bd1e7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:17:25 +0100 Subject: [PATCH 0846/1050] Add numeric-keypad alternatives to CTRL-ALT-END/PGUP/PGDN shortcuts. Patch from tigerforce. --- src/wx-sdl2-display-win.c | 6 +++--- src/wx-sdl2-display.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 57f92e6..5ac647a 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -780,7 +780,7 @@ int render() break; } } - if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] && + if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_3)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) trigger_fullscreen = 1; @@ -789,7 +789,7 @@ int render() trigger_fullscreen = 0; toggle_fullscreen(); } - else if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] && + else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_9)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) trigger_screenshot = 1; @@ -798,7 +798,7 @@ int render() trigger_screenshot = 0; take_screenshot = 1; } - else if (event.key.keysym.scancode == SDL_SCANCODE_END && + else if ((event.key.keysym.scancode == SDL_SCANCODE_END || event.key.keysym.scancode == SDL_SCANCODE_KP_1) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) trigger_inputrelease = 1; else if (trigger_inputrelease) diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index 0de48c5..ac8c23e 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -541,7 +541,7 @@ int render() } } } - if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] && + if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_3)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) trigger_fullscreen = 1; @@ -550,7 +550,7 @@ int render() trigger_fullscreen = 0; toggle_fullscreen(); } - else if (rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] && + else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_9)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) trigger_screenshot = 1; @@ -559,7 +559,7 @@ int render() trigger_screenshot = 0; take_screenshot = 1; } - else if (event.key.keysym.scancode == SDL_SCANCODE_END && + else if ((event.key.keysym.scancode == SDL_SCANCODE_END || event.key.keysym.scancode == SDL_SCANCODE_KP_1) && (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) trigger_inputrelease = 1; else if (trigger_inputrelease) From e3fd8698dfc8a912c46dc455b5f906d84c8cba7d Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:30:19 +0100 Subject: [PATCH 0847/1050] Remove faulty cyrix special register read access Patch from davefiddes. Original commit message : GCC 10.1 reports this line as being logically always false so will never run. On inspection it may be that this was intended to be: if ((cyrix_addr & 0xf0) == 0xc0) return 0xff; According to the IBM 6X86MX Microprocessor Databook (http://datasheets.chipdb.org/IBM/x86/6x86MX/mx_full.pdf) this would correspond to the Address Region 0 - 3 registers but omit Address Region 4 - 7 registers which doesn't seem to make a lot of sense. Delete the code as the default response from the function is to return 0xff and this is what its behviour up until now has been. --- src/cpu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cpu.c b/src/cpu.c index 7d6c1a2..d69df1f 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1747,7 +1747,6 @@ uint8_t cyrix_read(uint16_t addr, void *priv) case 0xfe: return models[model].cpu[cpu_manufacturer].cpus[cpu].cyrix_id & 0xff; case 0xff: return models[model].cpu[cpu_manufacturer].cpus[cpu].cyrix_id >> 8; } - if ((cyrix_addr & ~0xf0) == 0xc0) return 0xff; if (cyrix_addr == 0x20 && models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_Cx5x86) return 0xff; } return 0xff; From 9441cd94460e75c62f81673ab1221354389ba675 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:33:06 +0100 Subject: [PATCH 0848/1050] scamp.c: Fix 64-bit integer-as-pointer use for bank number warning Patch from davefiddes. Original commit message : The bank number is stored in a pointer value but is used exclusively as a bank number integer reference. To do this safely it needs to be an intptr_t. --- src/scamp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/scamp.c b/src/scamp.c index 4cd5a78..93c716f 100644 --- a/src/scamp.c +++ b/src/scamp.c @@ -100,7 +100,7 @@ static const struct so we use separate routines for that special case*/ static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *p) { - int bank = (int)p; + int bank = (intptr_t)p; int row, column, byte; addr -= scamp.ram_virt_base[bank]; @@ -128,7 +128,7 @@ static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *p) } static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *p) { - int bank = (int)p; + int bank = (intptr_t)p; int row, column, byte; addr -= scamp.ram_virt_base[bank]; @@ -159,7 +159,7 @@ static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *p) mapping linear, otherwise we won't be able to execute code from interleaved banks*/ static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *p) { - int bank = (int)p; + int bank = (intptr_t)p; int row, column, byte; addr -= scamp.ram_virt_base[bank]; @@ -187,7 +187,7 @@ static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *p) } static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *p) { - int bank = (int)p; + int bank = (intptr_t)p; int row, column, byte; addr -= scamp.ram_virt_base[bank]; @@ -216,7 +216,7 @@ static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *p) static uint8_t ram_mirrored_read(uint32_t addr, void *p) { - int bank = (int)p; + int bank = (intptr_t)p; int row, column, byte; addr -= scamp.ram_virt_base[bank]; @@ -229,7 +229,7 @@ static uint8_t ram_mirrored_read(uint32_t addr, void *p) } static void ram_mirrored_write(uint32_t addr, uint8_t val, void *p) { - int bank = (int)p; + int bank = (intptr_t)p; int row, column, byte; addr -= scamp.ram_virt_base[bank]; @@ -246,7 +246,7 @@ static void recalc_mappings(void) int c; uint32_t virt_base = 0; uint8_t cur_rammap = scamp.cfg_regs[CFG_RAMMAP] & 0xf; - int bank_nr = 0; + intptr_t bank_nr = 0; for (c = 0; c < 2; c++) mem_mapping_disable(&scamp.ram_mapping[c]); @@ -667,7 +667,7 @@ uint8_t scamp_read(uint16_t addr, void *p) void scamp_init(void) { uint32_t addr; - int c; + intptr_t c; memset(&scamp, 0, sizeof(scamp)); scamp.cfg_regs[CFG_ID] = ID_VL82C311; From a52066c75a554bf33541ef3aaddd25126d60c31a Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:36:02 +0100 Subject: [PATCH 0849/1050] Fix unused variable in vid_voodoo_codegen_x86-64.h Patch from davefiddes. Original commit message : Remove several unused variable references which look like they were required for earlier versions of the code. Tests: - Clean build on Fedora 32 with gcc 10.1 --- src/vid_voodoo_codegen_x86-64.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index c8bb5f8..8462479 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -69,8 +69,6 @@ static __m128i xmm_01_w;// = 0x0001000100010001ull; static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; static __m128i xmm_ff_b;// = 0x00000000ffffffffull; -static uint32_t zero = 0; - static __m128i alookup[257], aminuslookup[256]; static __m128i minus_254;// = 0xff02ff02ff02ff02ull; static __m128i bilinear_lookup[256*2]; @@ -3344,12 +3342,6 @@ voodoo_recomp++; static void voodoo_codegen_init(voodoo_t *voodoo) { int c; -#if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif #if WIN64 voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); From b5bc47ea2f9ccc9d5439b4df8ea86c003e0a723b Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:42:20 +0100 Subject: [PATCH 0850/1050] Fix buffer overflow warnings in OpenGL 3.0 video display file handling Patch from davefiddes. Original commit message : This fixes issues reported by gcc 10 with the size of various filename buffers when concatenating strings into them. Tests: - Build cleanly with gcc 10 - Run a Pentium MMX Win98 machine and use custom GLSLP shader --- src/wx-glslp-parser.c | 4 ++-- src/wx-glslp-parser.h | 2 +- src/wx-sdl2-video-gl3.c | 2 +- src/wx-sdl2.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wx-glslp-parser.c b/src/wx-glslp-parser.c index dd1fec1..387918a 100644 --- a/src/wx-glslp-parser.c +++ b/src/wx-glslp-parser.c @@ -163,9 +163,9 @@ void get_glslp_name(const char* f, char* s, int size) glslp_t* glslp_parse(const char* f) { int i, j, len, sublen; - char s[512], t[512], z[512]; + char s[512], t[512], z[540]; - s[511] = 0; + memset(s, 0, sizeof(s)); if (endswith(f, ".glsl")) return glsl_parse(f); diff --git a/src/wx-glslp-parser.h b/src/wx-glslp-parser.h index 59ae315..970eb35 100644 --- a/src/wx-glslp-parser.h +++ b/src/wx-glslp-parser.h @@ -22,7 +22,7 @@ struct texture { }; struct shader { - char shader_fn[512]; + char shader_fn[1024]; char* shader_program; char alias[64]; int filter_linear; diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index f8895b3..3ce76e1 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -559,7 +559,7 @@ static glsl_t* load_glslp(glsl_t* glsl, int num_shader, const char* f) if (p) { char path[512]; - char file[512]; + char file[1024]; int failed = 0; strcpy(path, f); char* filename = get_filename(path); diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index d230416..aedfb44 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -504,7 +504,7 @@ int pc_main(int argc, char** argv) paths_init(); #ifdef __linux__ - char s[512]; + char s[1024]; /* create directories if they don't exist */ if (!wx_setup(pcem_path)) return FALSE; From 9b737f65b14447d20157f5f1ad96a069761615e6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 19:54:15 +0100 Subject: [PATCH 0851/1050] Fix warnings when compiling codegen_*.c Patch from davefiddes. Original commit message : This fixes the following warnings: codegen_allocator.c: - implict function declaration of rand() due to missing stdlib.h codegen_backend_x86-64.c: - implict function declaration of malloc() due to missing stdlib.h - unused variables in codegen_backend_init() - invalid typecast in use of host_x86_CALL() codegen_backend_x86-64-uop.c: - Remove unused variable declarations in codegen_CALL_FUNC_RESULT(), codegen_LOAD_SEG(), codegen_OR_IMM(), codegen_XOR() and codegen_XOR_IMM() - Move debug only variable declarations under the debug conditional define in codegen_CALL_FUNC_RESULT(), codegen_LOAD_SEG(), codegen_MEM_LOAD_SINGLE(), codegen_MEM_LOAD_DOUBLE(), codegen_MEM_STORE_SINGLE(), codegen_MEM_STORE_DOUBLE() codegen_reg.c: - Change (int) typecasts to the correct (intptr_t) for small values stored in a pointer. This fixes a series of 64-bit compilation warnings. Tests: - Build with no warnings on Fedora 32 with gcc 10.1 - Boot a Win98 machine with dynamic compilation enabled --- src/codegen_allocator.c | 1 + src/codegen_backend_x86-64.c | 9 ++------- src/codegen_backend_x86-64_uops.c | 18 +++++++++--------- src/codegen_reg.c | 16 ++++++++-------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/codegen_allocator.c b/src/codegen_allocator.c index 4b4ffd7..5807b5d 100644 --- a/src/codegen_allocator.c +++ b/src/codegen_allocator.c @@ -1,6 +1,7 @@ #if defined(__linux__) || defined(__APPLE__) #include #include +#include #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 #include diff --git a/src/codegen_backend_x86-64.c b/src/codegen_backend_x86-64.c index 03cde31..a214b69 100644 --- a/src/codegen_backend_x86-64.c +++ b/src/codegen_backend_x86-64.c @@ -13,6 +13,7 @@ #if defined(__linux__) || defined(__APPLE__) #include #include +#include #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 #include @@ -288,12 +289,6 @@ void codegen_backend_init() { codeblock_t *block; int c; -#if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); -#endif codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); @@ -322,7 +317,7 @@ void codegen_backend_init() host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); #endif - host_x86_CALL(block, (uintptr_t)x86gpf); + host_x86_CALL(block, (void *)x86gpf); codegen_exit_rout = &codeblock[block_current].data[block_pos]; host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); host_x86_POP(block, REG_R15); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 596f262..8b73909 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -195,9 +195,9 @@ static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); #ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_L(dest_size)) fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); #endif @@ -918,9 +918,9 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); #ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (!REG_IS_W(src_size)) fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); #endif @@ -1029,9 +1029,9 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); #ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); #endif @@ -1048,9 +1048,9 @@ static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); #ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); if (!REG_IS_D(dest_size)) fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); #endif @@ -1174,9 +1174,9 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); #ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); #endif @@ -1193,9 +1193,9 @@ static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); #ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); if (!REG_IS_D(src_size)) fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); #endif @@ -1495,7 +1495,7 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) @@ -2766,7 +2766,7 @@ static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) @@ -2793,7 +2793,7 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); if (REG_IS_L(dest_size) && REG_IS_L(src_size)) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index e28068b..da6dd8c 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -274,7 +274,7 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; @@ -283,7 +283,7 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; @@ -292,7 +292,7 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; @@ -301,7 +301,7 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; @@ -310,7 +310,7 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); break; @@ -382,7 +382,7 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); if ((uintptr_t)p < 256) - codegen_direct_write_32_stack(block, (int)p, reg_set->reg_list[c].reg); + codegen_direct_write_32_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); else codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); break; @@ -391,7 +391,7 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); if ((uintptr_t)p < 256) - codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c].reg); + codegen_direct_write_64_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); else codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); break; @@ -408,7 +408,7 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); if ((uintptr_t)p < 256) - codegen_direct_write_double_stack(block, (int)p, reg_set->reg_list[c].reg); + codegen_direct_write_double_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); else codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); break; From 7d4bc7237c5855341becb4e1818d4dbe0ca0ec52 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 30 Sep 2020 21:31:33 +0100 Subject: [PATCH 0852/1050] Add Compaq Deskpro emulation. --- src/ibm.h | 1 + src/mem_bios.c | 8 ++++++++ src/model.c | 9 +++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 68cd837..454ff8c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -260,6 +260,7 @@ enum ROM_LEDGE_MODELM, ROM_HYUNDAI_SUPER286TR, ROM_ITAUTEC_INFOWAYM, + ROM_DESKPRO, ROM_MAX }; diff --git a/src/mem_bios.c b/src/mem_bios.c index 6da00e9..f524f57 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -1097,6 +1097,14 @@ int loadbios() fclose(f); biosmask = 0x3fff; return 1; + + case ROM_DESKPRO: + f = romfopen("deskpro/Compaq - BIOS - Revision J - 106265-002.bin","rb"); + if (!f) break; + romfread(rom, 0x2000, 1, f); + fclose(f); + biosmask = 0x1fff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index f4a1e51..380a04f 100644 --- a/src/model.c +++ b/src/model.c @@ -126,7 +126,7 @@ void at_zappa_init(); void at_pb410a_init(); void at_pb520r_init(); void at_pb570_init(); -void compaq_pip_init(); +void compaq_xt_init(); void xt_xi8088_init(); void xt_zenith_init(); void at_mvp3_init(); @@ -138,7 +138,7 @@ MODEL models[] = { {"[8088] AMI XT clone", ROM_AMIXT, "amixt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, - {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 64, compaq_pip_init, NULL}, + {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 64, compaq_xt_init, NULL}, {"[8088] DTK XT clone", ROM_DTKXT, "dtk", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}, {"[8088] Generic XT clone", ROM_GENXT, "genxt", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 32, 704, 16, xt_init, NULL}, {"[8088] IBM PC", ROM_IBMPC, "ibmpc", { {"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 32, xt_init, NULL}, @@ -161,7 +161,8 @@ MODEL models[] = {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams1512_device}, {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams2086_device}, {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams3086_device}, - {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, + {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, + {"[8086] Compaq Deskpro", ROM_DESKPRO, "deskpro", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, compaq_xt_init, NULL}, {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}, @@ -331,7 +332,7 @@ void xt_init() device_add(&cassette_device); } -void compaq_pip_init() +void compaq_xt_init() { xt_init(); lpt1_remove(); From 264cfc3a1275b9f349aee34af1109f43e02a8b76 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Oct 2020 17:21:12 +0100 Subject: [PATCH 0853/1050] Add Trident TVGA9000B emulation. --- src/ibm.h | 1 + src/vid_tvga.c | 112 ++++++++++++++++++++++++++++++++++++++++--------- src/vid_tvga.h | 1 + src/video.c | 1 + 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 454ff8c..3edbad6 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -314,6 +314,7 @@ enum GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/ GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/ GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/ + GFX_TVGA9000B, /*Trident TVGA9000B*/ GFX_MAX }; diff --git a/src/vid_tvga.c b/src/vid_tvga.c index 623534b..d9213ea 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -11,6 +11,12 @@ #include "vid_tkd8001_ramdac.h" #include "vid_tvga.h" +enum +{ + TVGA_8900D = 0x33, + TVGA_9000 = 0x23 +}; + typedef struct tvga_t { mem_mapping_t linear_mapping; @@ -28,6 +34,8 @@ typedef struct tvga_t int vram_size; uint32_t vram_mask; + + uint8_t id; } tvga_t; static uint8_t crtc_mask[0x40] = @@ -67,7 +75,7 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) break; case 0xd: if (tvga->oldmode) - tvga->oldctrl2 = val; + tvga->oldctrl2 = val; else { tvga->newctrl2 = val; @@ -76,7 +84,10 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) break; case 0xE: if (tvga->oldmode) + { tvga->oldctrl1 = val; + svga_recalctimings(svga); + } else { svga->seqregs[0xe] = val ^ 2; @@ -88,8 +99,12 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); - return; + if (tvga->id != TVGA_9000) + { + tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); + return; + } + break; case 0x3CF: switch (svga->gdcaddr & 15) @@ -166,7 +181,7 @@ uint8_t tvga_in(uint16_t addr, void *p) { // printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); tvga->oldmode = 0; - return 0x33; /*TVGA8900D*/ + return tvga->id; } if ((svga->seqaddr & 0xf) == 0xc) { @@ -185,7 +200,9 @@ uint8_t tvga_in(uint16_t addr, void *p) } break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); + if (tvga->id != TVGA_9000) + return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); + break; case 0x3D4: return svga->crtcreg; case 0x3D5: @@ -217,6 +234,9 @@ static void tvga_recalcbanking(tvga_t *tvga) void tvga_recalctimings(svga_t *svga) { tvga_t *tvga = (tvga_t *)svga->p; + int clksel; + int high_res_256 = 0; + if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, given that TVGA8900D has no overflow bits. Some sort of overflow is required for 320x200x24 and 1024x768x16*/ @@ -246,18 +266,43 @@ void tvga_recalctimings(svga_t *svga) if (svga->interlace) svga->rowoffset >>= 1; - switch (((svga->miscout >> 2) & 3) | ((tvga->newctrl2 << 2) & 4)) + if (tvga->id == TVGA_8900D) + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1); + else + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3); + switch (clksel) { - case 2: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; - case 3: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; - case 4: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; - case 5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; - case 6: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; - case 7: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x2: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; + case 0x3: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; + case 0x4: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; + case 0x5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; + case 0x6: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; + case 0x7: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x8: svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; break; + case 0x9: svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; break; + case 0xa: svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; break; + case 0xb: svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; break; + case 0xc: svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; break; + case 0xd: svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; break; + case 0xe: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; + case 0xf: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; } - if (tvga->oldctrl2 & 0x10) + if (tvga->id == TVGA_9000) { + /*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode + (without the VGA pixel doubling). Instead it implements these modes by + doubling the horizontal pixel count and pixel clock. Hence we use a + basic heuristic to detect this*/ + if (svga->interlace) + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + else + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + } + if ((tvga->oldctrl2 & 0x10) || high_res_256) + { + if (high_res_256) + svga->hdisp /= 2; switch (svga->bpp) { case 8: @@ -280,31 +325,46 @@ void tvga_recalctimings(svga_t *svga) } } -void *tvga8900d_init() +static void *tvga_common_init(char *fn, uint32_t id, int vram_size) { tvga_t *tvga = malloc(sizeof(tvga_t)); memset(tvga, 0, sizeof(tvga_t)); - - tvga->vram_size = device_get_config_int("memory") << 10; + + tvga->vram_size = vram_size << 10; tvga->vram_mask = tvga->vram_size - 1; - - rom_init(&tvga->bios_rom, "trident.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - + tvga->id = id; + + rom_init(&tvga->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + svga_init(&tvga->svga, tvga, tvga->vram_size, tvga_recalctimings, tvga_in, tvga_out, NULL, NULL); - + io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); return tvga; } +static void *tvga8900d_init() +{ + int vram_size = device_get_config_int("memory"); + + return tvga_common_init("trident.bin", TVGA_8900D, vram_size); +} +static void *tvga9000b_init() +{ + return tvga_common_init("tvga9000b/BIOS.BIN", TVGA_9000, 512); +} static int tvga8900d_available() { return rom_present("trident.bin"); } +static int tvga9000b_available() +{ + return rom_present("tvga9000b/BIOS.BIN"); +} void tvga_close(void *p) { @@ -380,3 +440,15 @@ device_t tvga8900d_device = tvga_add_status_info, tvga_config }; +device_t tvga9000b_device = +{ + "Trident TVGA 9000B", + 0, + tvga9000b_init, + tvga_close, + tvga9000b_available, + tvga_speed_changed, + tvga_force_redraw, + tvga_add_status_info, + NULL +}; diff --git a/src/vid_tvga.h b/src/vid_tvga.h index d55ff65..c2c1019 100644 --- a/src/vid_tvga.h +++ b/src/vid_tvga.h @@ -1 +1,2 @@ extern device_t tvga8900d_device; +extern device_t tvga9000b_device; diff --git a/src/video.c b/src/video.c index dc0ecfd..d0bca3f 100644 --- a/src/video.c +++ b/src/video.c @@ -119,6 +119,7 @@ static VIDEO_CARD video_cards[] = {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"Sigma Color 400", "sigma400", &sigma_device, GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}, + {"Trident TVGA9000B", "tvga9000b", &tvga9000b_device, GFX_TVGA9000B, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 7, 7, 12, 7, 7, 12}}, {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}, {"Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, From 2efda3598b1521c5899f0a20d0b94fd97b2b4c6e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 2 Oct 2020 17:21:41 +0100 Subject: [PATCH 0854/1050] Trident TVGA8900D appears to implement port 0x3db as an alternative clock select. Fixes pixel clocks & refresh rates on this card. --- src/vid_tvga.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vid_tvga.c b/src/vid_tvga.c index d9213ea..59e11e3 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -161,6 +161,16 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) tvga_recalcbanking(tvga); } return; + case 0x3DB: + if (tvga->id == TVGA_8900D) + { + /*3db appears to be a 4 bit clock select register on 8900D*/ + svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2); + tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2); + tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1); + svga_recalctimings(svga); + } + break; } svga_out(addr, val, svga); } From 9bdbcc18c028fd3c419c51282119b3e70b2598e4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 12:25:36 +0000 Subject: [PATCH 0855/1050] Added Samsung SPC-6000A and SPC-6033P. Patch from Greatpsycho. --- src/ibm.h | 2 ++ src/keyboard_at.c | 4 ++-- src/mem_bios.c | 31 ++++++++++++++++++++++++++++ src/model.c | 2 ++ src/nvr.c | 4 ++++ src/vid_ati28800.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-- src/vid_ati28800.h | 1 + src/video.c | 15 ++++++++++++++ 8 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 3edbad6..5d3ac3b 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -209,6 +209,8 @@ enum ROM_MEGAPC, ROM_AMA932J, ROM_AMI386SX, + ROM_SPC6000A, + ROM_SPC6033P, ROM_AMI486, ROM_WIN486, ROM_PCI486, diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 40987c1..5cadb78 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -522,9 +522,9 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) key_ctrl_queue_start = key_ctrl_queue_end = 0; keyboard_at.status &= ~STAT_OFULL; } - /* T3100e expects STAT_IFULL to be set immediately + /* T3100e and Samsung SPC-6000A expects STAT_IFULL to be set immediately * after sending 0xAA */ - if(romset == ROM_T3100E) keyboard_at.status |= STAT_IFULL; + if(romset == ROM_T3100E || romset == ROM_SPC6000A) keyboard_at.status |= STAT_IFULL; keyboard_at.status |= STAT_SYSFLAG; keyboard_at.mem[0] |= 0x04; keyboard_at_adddata(0x55); diff --git a/src/mem_bios.c b/src/mem_bios.c index f524f57..270080d 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -446,6 +446,37 @@ int loadbios() } break; + case ROM_SPC6000A: + f = romfopen("spc6000a/3c80.u27", "rb"); + ff = romfopen("spc6000a/9f80.u26","rb"); + if (f && ff) + { + for (c = 0x8000; c < 0x10000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + } + break; + + case ROM_SPC6033P: + f=romfopen("spc6033p/svb6120a_font.rom","rb"); + if (!f) break; + fclose(f); + f=romfopen("spc6033p/phoenix.bin","rb"); + if (f) + { + fseek(f, 0x10000, SEEK_SET); + romfread(rom,65536,1,f); + + fclose(f); + return 1; + } + break; + case ROM_EUROPC: // return 0; f=romfopen("europc/50145","rb"); diff --git a/src/model.c b/src/model.c index 380a04f..1b8c40f 100644 --- a/src/model.c +++ b/src/model.c @@ -203,6 +203,7 @@ MODEL models[] = {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT, 512,16384, 512, at_scatsx_init, NULL}, {"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL}, + {"[386SX] Samsung SPC-6033P", ROM_SPC6033P, "spc6033p", { {"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW|MODEL_AT|MODEL_PS2|MODEL_HAS_IDE, 2, 12, 2, at_scamp_init, NULL}, {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, @@ -210,6 +211,7 @@ MODEL models[] = {"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}, {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PS2|MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"[386DX] Samsung SPC-6000A", ROM_SPC6000A, "spc6000a", { {"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 32, 1, at_cs8230_init, NULL}, {"[486] AMI 486 clone", ROM_AMI486, "ami486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", { {"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE|MODEL_AT|MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 452937d..2d14e08 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -303,6 +303,8 @@ void loadnvr() case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); nvrmask = 127; break; case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "rb"); nvrmask = 127; break; + case ROM_SPC6000A: f = nvrfopen("spc6000a.nvr", "rb"); nvrmask = 127; break; + case ROM_SPC6033P: f = nvrfopen("spc6033p.nvr", "rb"); nvrmask = 127; break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); break; @@ -408,6 +410,8 @@ void savenvr() case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); break; case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); break; case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "wb"); break; + case ROM_SPC6000A: f = nvrfopen("spc6000a.nvr", "wb"); break; + case ROM_SPC6033P: f = nvrfopen("spc6033p.nvr", "wb"); break; case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); break; case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); break; case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); break; diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 8cdd8e8..1d024f4 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -268,7 +268,7 @@ uint8_t ati28800k_in(uint16_t addr, void *p) void ati28800_recalctimings(svga_t *svga) { ati28800_t *ati28800 = (ati28800_t *)svga->p; - pclog("ati28800_recalctimings\n"); + //pclog("ati28800_recalctimings\n"); switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { @@ -299,7 +299,7 @@ void ati28800_recalctimings(svga_t *svga) if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ { - pclog("8bpp_highres\n"); + //pclog("8bpp_highres\n"); svga->render = svga_render_8bpp_highres; svga->rowoffset <<= 1; svga->ma <<= 1; @@ -407,6 +407,40 @@ void *ati28800k_spc4620p_init() return ati28800; } +void *ati28800k_spc6033p_init() +{ + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); + + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; + + rom_init(&ati28800->bios_rom, "spc6033p/phoenix.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("spc6033p/svb6120a_font.rom", 6); + + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800k_recalctimings, + ati28800k_in, ati28800k_out, + NULL, + NULL); + + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + + ati28800->svga.miscout = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; + + + ati_eeprom_load(&ati28800->eeprom, "svb6120a_spc6033p.nvr", 0); + + return ati28800; +} + static int ati28800_available() { return rom_present("bios.bin"); @@ -493,3 +527,15 @@ device_t ati28800k_spc4620p_device = ati28800_force_redraw, ati28800k_add_status_info }; + +device_t ati28800k_spc6033p_device = +{ + "SVB-6120A", + 0, + ati28800k_spc6033p_init, + ati28800_close, + NULL, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800k_add_status_info +}; diff --git a/src/vid_ati28800.h b/src/vid_ati28800.h index ed30dbb..2d2cd8a 100644 --- a/src/vid_ati28800.h +++ b/src/vid_ati28800.h @@ -1,3 +1,4 @@ extern device_t ati28800_device; extern device_t ati28800k_device; extern device_t ati28800k_spc4620p_device; +extern device_t ati28800k_spc6033p_device; diff --git a/src/video.c b/src/video.c index d0bca3f..fd78a5c 100644 --- a/src/video.c +++ b/src/video.c @@ -217,6 +217,12 @@ device_t *video_card_getdevice(int card, int romset) case ROM_SPC4620P: if (card == GFX_BUILTIN) return &ati28800k_spc4620p_device; + break; + + case ROM_SPC6033P: + if (card == GFX_BUILTIN) + return &ati28800k_spc6033p_device; + break; case ROM_ACER386: return &oti067_acer386_device; @@ -595,6 +601,7 @@ void video_updatetiming() break; case ROM_SPC4620P: + case ROM_SPC6033P: if (gfxcard == GFX_BUILTIN) timing = &timing_spc4620p; break; @@ -800,6 +807,14 @@ void video_init() } break; + case ROM_SPC6033P: + if (gfxcard == GFX_BUILTIN) + { + device_add(&ati28800k_spc6033p_device); + return; + } + break; + case ROM_ACER386: device_add(&oti067_acer386_device); if (gfxcard != GFX_BUILTIN) From ed30e1712884bb80c9d153aeabcf12567e596012 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 13:38:07 +0000 Subject: [PATCH 0856/1050] Implement VGA byte panning and cursor skew. Patch from Greatpsycho. --- src/vid_et4000.c | 5 +++++ src/vid_svga.c | 11 ++++++----- src/vid_svga.h | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vid_et4000.c b/src/vid_et4000.c index c56db96..161e741 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -264,6 +264,11 @@ void et4000k_recalctimings(svga_t *svga) if (svga->render == svga_render_text_80 && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { + if(et4000->port_32cb_val & 0x80) + { + svga->ma_latch -= 2; + svga->ca_adj = -2; + } if((et4000->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { svga->render = svga_render_text_80_ksc5601; diff --git a/src/vid_svga.c b/src/vid_svga.c index 1f145de..cb65e29 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -322,7 +322,7 @@ void svga_recalctimings(svga_t *svga) if (svga->crtc[9] & 0x20) svga->vblankstart |= 0x200; svga->vblankstart++; - svga->hdisp = svga->crtc[1]; + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); svga->hdisp++; svga->htotal = svga->crtc[0]; @@ -336,7 +336,8 @@ void svga_recalctimings(svga_t *svga) svga->interlace = 0; - svga->ma_latch = (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->ca_adj = 0; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -658,9 +659,9 @@ void svga_poll(void *p) changeframecount = svga->interlace ? 3 : 2; svga->vslines = 0; - if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); - else svga->ma = svga->maback = svga->ma_latch; - svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf]; + if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + else svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); + svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; svga->ma <<= 2; svga->maback <<= 2; diff --git a/src/vid_svga.h b/src/vid_svga.h index 4b21f3d..1f99150 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -60,7 +60,7 @@ typedef struct svga_t int lowres, interlace; int linedbl, rowcount; double clock; - uint32_t ma_latch; + uint32_t ma_latch, ca_adj; int bpp; uint64_t dispontime, dispofftime; From 87941f29038a285b1951dff59e5ab8c31b1b72fc Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 14:20:37 +0000 Subject: [PATCH 0857/1050] Added Kasan Hangulmadang-16 emulation. Patch from Greatpsycho. --- src/ibm.h | 1 + src/vid_ati28800.c | 13 ++- src/vid_et4000.c | 256 +++++++++++++++++++++++++++++++++++++++++- src/vid_et4000.h | 1 + src/vid_svga.c | 1 + src/vid_svga.h | 5 +- src/vid_svga_render.c | 20 +++- src/video.c | 1 + 8 files changed, 290 insertions(+), 8 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 5d3ac3b..62f8035 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -281,6 +281,7 @@ enum GFX_EGA, /*Using IBM EGA BIOS*/ GFX_TVGA, /*Using Trident TVGA8900D BIOS*/ GFX_ET4000, /*Tseng ET4000*/ + GFX_KASAN16VGA, /*Kasan Hangulmadang-16 (Tseng ET4000AX)*/ GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/ GFX_ET4000W32, /*Tseng ET4000/W32p (Diamond Stealth 32)*/ GFX_BAHAMAS64, /*S3 Vision864 (Paradise Bahamas 64)*/ diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 1d024f4..871f1c5 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -368,6 +368,10 @@ void *ati28800k_init() ati28800->svga.miscout = 1; ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0); @@ -401,6 +405,10 @@ void *ati28800k_spc4620p_init() ati28800->svga.miscout = 1; ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; ati_eeprom_load(&ati28800->eeprom, "svb6120a.nvr", 0); @@ -434,7 +442,10 @@ void *ati28800k_spc6033p_init() ati28800->svga.miscout = 1; ati28800->svga.ksc5601_sbyte_mask = 0; - + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; ati_eeprom_load(&ati28800->eeprom, "svb6120a_spc6033p.nvr", 0); diff --git a/src/vid_et4000.c b/src/vid_et4000.c index 161e741..25cb60d 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -25,6 +25,11 @@ typedef struct et4000_t int get_korean_font_enabled; int get_korean_font_index; uint16_t get_korean_font_base; + + uint8_t kasan_cfg_index; + uint8_t kasan_cfg_regs[16]; + uint16_t kasan_access_addr; + uint8_t kasan_font_data[4]; } et4000_t; static uint8_t crtc_mask[0x40] = @@ -39,6 +44,9 @@ static uint8_t crtc_mask[0x40] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +void et4000_kasan_out(uint16_t addr, uint8_t val, void *p); +uint8_t et4000_kasan_in(uint16_t addr, void *p); + void et4000_out(uint16_t addr, uint8_t val, void *p) { et4000_t *et4000 = (et4000_t *)p; @@ -137,6 +145,118 @@ void et4000k_out(uint16_t addr, uint8_t val, void *p) et4000->port_32cb_val = val; svga_recalctimings(&et4000->svga); break; + default: + et4000_out(addr, val, p); + break; + } +} + +void et4000_kasan_out(uint16_t addr, uint8_t val, void *p) +{ + et4000_t *et4000 = (et4000_t *)p; + +// pclog("ET4000k out %04X %02X\n", addr, val); + + + if(addr == 0x258) + { + //pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc); + et4000->kasan_cfg_index = val; + } + else if(addr == 0x259) + { + //pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc); + if(et4000->kasan_cfg_index >= 0xF0) + { + switch(et4000->kasan_cfg_index - 0xF0) + { + case 0: + if(et4000->kasan_cfg_regs[4] & 8) + val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3); + et4000->kasan_cfg_regs[0] = val; + svga_recalctimings(&et4000->svga); + break; + case 1: + case 2: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; + io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + //pclog("Set font access address to %04X\n", et4000->kasan_access_addr); + break; + case 4: + if(et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + et4000->svga.ksc5601_swap_mode = (val & 4) >> 2; + et4000->kasan_cfg_regs[4] = val; + svga_recalctimings(&et4000->svga); + break; + case 5: + et4000->kasan_cfg_regs[5] = val; + et4000->svga.ksc5601_english_font_type = 0x100 | val; + case 6: + case 7: + et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; + default: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + svga_recalctimings(&et4000->svga); + break; + } + } + } + else if(addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) + { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) + { + case 0: + if(et4000->kasan_cfg_regs[0] & 2) + { + et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1); + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5); + } + break; + case 1: + if(et4000->kasan_cfg_regs[0] & 2) + { + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3); + } + break; + case 2: + if(et4000->kasan_cfg_regs[0] & 2) + { + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11); + } + break; + case 3: + case 4: + case 5: + if(et4000->kasan_cfg_regs[0] & 1) + { + et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; + } + break; + case 6: + if((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !val & 0x80) && (et4000->get_korean_font_base & 0x7F) >= 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) + { + if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) + { + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + } + else if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) + { + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + } + } + et4000->kasan_font_data[3] = val; + break; + default: + break; + } + //pclog("Write port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + } + else + { + et4000_out(addr, val, p); } } @@ -220,7 +340,60 @@ uint8_t et4000k_in(uint16_t addr, void *p) return et4000->port_32cb_val; } - return 0xff; + return et4000_in(addr, p); +} + +uint8_t et4000_kasan_in(uint16_t addr, void *p) +{ + uint8_t val = 0xFF; + et4000_t *et4000 = (et4000_t *)p; + + if(addr == 0x258) + { + //pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + val = et4000->kasan_cfg_index; + } + else if(addr == 0x259) + { + //pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + if (et4000->kasan_cfg_index >= 0xF0) + { + val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0]; + if(et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + } + } + else if(addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) + { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) + { + case 2: + val = 0; + break; + case 5: + if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) + { + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; + } + else if(((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) + { + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; + } + else + { + val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index]; + } + break; + default: + break; + } + //pclog(stderr, "Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + } + else + { + val = et4000_in(addr, p); + } + return val; } void et4000_recalctimings(svga_t *svga) @@ -276,6 +449,22 @@ void et4000k_recalctimings(svga_t *svga) } } +void et4000_kasan_recalctimings(svga_t *svga) +{ + et4000_t *et4000 = (et4000_t *)svga->p; + + et4000_recalctimings(svga); + + if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) + { + svga->ma_latch -= 3; + svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; + svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; + if((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) + svga->render = svga_render_text_80_ksc5601; + } +} + void *et4000_init() { et4000_t *et4000 = malloc(sizeof(et4000_t)); @@ -317,6 +506,54 @@ void *et4000k_init() NULL); et4000->svga.ksc5601_sbyte_mask = 0x80; + et4000->svga.ksc5601_udc_area_msb[0] = 0xC9; + et4000->svga.ksc5601_udc_area_msb[1] = 0xFE; + et4000->svga.ksc5601_swap_mode = 0; + et4000->svga.ksc5601_english_font_type = 0; + + return et4000; +} + +void *et4000_kasan_init() +{ + int i; + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); + + rom_init(&et4000->bios_rom, "et4000_kasan16.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("kasan_ksc5601.rom", 6); + + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); + + io_sethandler(0x0258, 0x0002, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + + svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + et4000_kasan_recalctimings, + et4000_in, et4000_out, + NULL, + NULL); + + et4000->svga.ksc5601_sbyte_mask = 0; + et4000->kasan_cfg_index = 0; + for(i=0; i<16; i++) + et4000->kasan_cfg_regs[i] = 0; + for(i=0; i<4; i++) + et4000->kasan_font_data[i] = 0; + et4000->kasan_cfg_regs[1] = 0x50; + et4000->kasan_cfg_regs[2] = 2; + et4000->kasan_cfg_regs[3] = 6; + et4000->kasan_cfg_regs[4] = 0x78; + et4000->kasan_cfg_regs[5] = 0xFF; + et4000->kasan_cfg_regs[6] = 0xC9; + et4000->kasan_cfg_regs[7] = 0xFE; + et4000->kasan_access_addr = 0x250; + io_sethandler(0x250, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + + et4000->svga.ksc5601_sbyte_mask = 0; + et4000->svga.ksc5601_udc_area_msb[0] = 0xC9; + et4000->svga.ksc5601_udc_area_msb[1] = 0xFE; + et4000->svga.ksc5601_swap_mode = 0; + et4000->svga.ksc5601_english_font_type = 0x1FF; return et4000; } @@ -331,6 +568,11 @@ static int et4000k_available() return rom_present("tgkorvga.bin") && rom_present("tg_ksc5601.rom");; } +static int et4000_kasan_available() +{ + return rom_present("et4000_kasan16.bin") && rom_present("kasan_ksc5601.rom");; +} + void et4000_close(void *p) { et4000_t *et4000 = (et4000_t *)p; @@ -384,3 +626,15 @@ device_t et4000k_device = et4000_force_redraw, et4000_add_status_info }; + +device_t et4000_kasan_device = +{ + "Kasan Hangulmadang-16(Tseng Labs ET4000AX)", + 0, + et4000_kasan_init, + et4000_close, + et4000_kasan_available, + et4000_speed_changed, + et4000_force_redraw, + et4000_add_status_info +}; diff --git a/src/vid_et4000.h b/src/vid_et4000.h index b5b0170..9d18590 100644 --- a/src/vid_et4000.h +++ b/src/vid_et4000.h @@ -1,2 +1,3 @@ extern device_t et4000_device; extern device_t et4000k_device; +extern device_t et4000_kasan_device; diff --git a/src/vid_svga.c b/src/vid_svga.c index cb65e29..7b0098e 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -774,6 +774,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; svga->hwcursor.ysize = 64; + svga->ksc5601_english_font_type = 0; // _svga_recalctimings(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); diff --git a/src/vid_svga.h b/src/vid_svga.h index 1f99150..3a0668b 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -138,7 +138,10 @@ typedef struct svga_t void *p; uint8_t ksc5601_sbyte_mask; - + uint8_t ksc5601_udc_area_msb[2]; + int ksc5601_swap_mode; + uint16_t ksc5601_english_font_type; + int vertical_linedbl; /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 92d177c..680772d 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -203,10 +203,17 @@ void svga_render_text_80_ksc5601(svga_t *svga) if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc]; + if((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc]; else if(nextchr & 0x80) + { + if(svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) + { + if(chr >= 0x80 && chr < 0x99) chr += 0x30; + else if(chr >= 0xB0 && chr < 0xC9) chr -= 0x30; + } dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; + } else dat = 0xFF; } @@ -215,7 +222,8 @@ void svga_render_text_80_ksc5601(svga_t *svga) if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); - dat = svga->vram[charaddr + (svga->sc << 2)]; + if ((svga->ksc5601_english_font_type >> 8) == 1) dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)][((chr & 1) << 4) | svga->sc]; + else dat = svga->vram[charaddr + (svga->sc << 2)]; } if (svga->seqregs[1] & 1) { @@ -255,10 +263,12 @@ void svga_render_text_80_ksc5601(svga_t *svga) } } - if((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16]; + if((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16]; else if(nextchr & 0x80) + { dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; + } else dat = 0xFF; if (svga->seqregs[1] & 1) diff --git a/src/video.c b/src/video.c index fd78a5c..2c81093 100644 --- a/src/video.c +++ b/src/video.c @@ -102,6 +102,7 @@ static VIDEO_CARD video_cards[] = {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"IBM 1MB SVGA Adapter/A (CL GD5428)", "ibm1mbsvga", &ibm_gd5428_device, GFX_IBM_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Kasan Hangulmadang-16 (Tseng ET4000AX)", "kasan16", &et4000_kasan_device, GFX_KASAN16VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, From d1021b5b6b3fcf047b33695e31a8a919afbc15f5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 15:34:27 +0000 Subject: [PATCH 0858/1050] =?UTF-8?q?S=C3=823:=20implement=20RCBASE/DSTBAS?= =?UTF-8?q?E,=20treat=20clip=20rectangle=20as=20unsigned.=20Patch=20from?= =?UTF-8?q?=20twilen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vid_s3.c | 82 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index 25bcca2..f4064a9 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1726,10 +1726,30 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; uint32_t rd_mask = s3->accel.rd_mask; int cmd = s3->accel.cmd >> 13; + uint32_t srcbase, dstbase; if ((s3->chip == S3_TRIO64) && (s3->accel.cmd & (1 << 11))) cmd |= 8; + if ((s3->accel.multifunc[13] >> 4) & 7) + srcbase = 0x100000 * ((s3->accel.multifunc[13] >> 4) & 3); + else + srcbase = 0x100000 * ((s3->accel.multifunc[14] >> 2) & 3); + if ((s3->accel.multifunc[13] >> 0) & 7) + dstbase = 0x100000 * ((s3->accel.multifunc[13] >> 0) & 3); + else + dstbase = 0x100000 * ((s3->accel.multifunc[14] >> 0) & 3); + if (s3->bpp == 1) + { + srcbase >>= 1; + dstbase >>= 1; + } + else if (s3->bpp == 3) + { + srcbase >>= 2; + dstbase >>= 2; + } + s3->force_busy = 1; //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); @@ -1792,8 +1812,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { while (count-- && s3->accel.sy >= 0) { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -1842,8 +1862,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { while (count-- && s3->accel.sy >= 0) { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -1927,7 +1947,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.cy = s3->accel.cur_y; if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.dest = dstbase + 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); } @@ -1940,8 +1960,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat while (count-- && s3->accel.sy >= 0) { - if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && - s3->accel.cy >= clip_t && s3->accel.cy <= clip_b) + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -1987,7 +2007,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.cmd & 0x80) s3->accel.cy++; else s3->accel.cy--; - s3->accel.dest = s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.cy * s3->width; s3->accel.sy--; if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; @@ -2017,8 +2037,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.cy = s3->accel.cur_y & 0xfff; if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + 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); } @@ -2037,8 +2057,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { while (1) { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { READ_SRC(s3->accel.src + s3->accel.cx, src_dat); READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); @@ -2060,8 +2080,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.cy++; s3->accel.dy++; - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -2074,8 +2094,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { while (count-- && s3->accel.sy >= 0) { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { if (vram_mask) { @@ -2148,8 +2168,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dy--; } - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -2182,12 +2202,12 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat // 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; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.cx = s3->accel.dx & 7; s3->accel.cy = s3->accel.dy & 7; - s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.src = srcbase + 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(); @@ -2202,8 +2222,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat while (count-- && s3->accel.sy >= 0) { - if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && - s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { if (vram_mask) { @@ -2275,8 +2295,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dy--; } - s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); - s3->accel.dest = s3->accel.dy * s3->width; + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; @@ -2309,12 +2329,12 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int y = s3->accel.poly_cy; int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - s3->accel.dest = y * s3->width; + s3->accel.dest = dstbase + y * s3->width; while (x_count-- && count--) { - if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && - s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && + (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { switch (frgd_mix) { @@ -2384,15 +2404,15 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int y = s3->accel.poly_cy; int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - s3->accel.src = s3->accel.pattern + ((y & 7) * s3->width); - s3->accel.dest = y * s3->width; + s3->accel.src = srcbase + s3->accel.pattern + ((y & 7) * s3->width); + s3->accel.dest = dstbase + y * s3->width; while (x_count-- && count--) { int pat_x = s3->accel.poly_x & 7; - if (s3->accel.poly_x >= clip_l && s3->accel.poly_x <= clip_r && - s3->accel.poly_cy >= clip_t && s3->accel.poly_cy <= clip_b) + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && + (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { if (vram_mask) { From 602d6f1ce65a1c77f64a9cc4a931d453aa2fde10 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 19:12:07 +0000 Subject: [PATCH 0859/1050] Add VHD hard disc image support. Patch from shermanp. --- src/Makefile.am | 4 + src/Makefile.mingw-wx-sdl2 | 7 +- src/Makefile.mingw-wx-sdl2-network | 7 +- src/hdd_file.c | 189 ++- src/hdd_file.h | 9 +- src/minivhd/CREDITS.md | 12 + src/minivhd/LICENSE | 21 + src/minivhd/cwalk.c | 1421 ++++++++++++++++++++ src/minivhd/cwalk.h | 457 +++++++ src/minivhd/libxml2_encoding.c | 447 +++++++ src/minivhd/libxml2_encoding.h | 12 + src/minivhd/minivhd.h | 269 ++++ src/minivhd/minivhd_convert.c | 105 ++ src/minivhd/minivhd_create.c | 482 +++++++ src/minivhd/minivhd_create.h | 8 + src/minivhd/minivhd_internal.h | 96 ++ src/minivhd/minivhd_io.c | 276 ++++ src/minivhd/minivhd_io.h | 132 ++ src/minivhd/minivhd_manage.c | 531 ++++++++ src/minivhd/minivhd_struct_rw.c | 165 +++ src/minivhd/minivhd_struct_rw.h | 38 + src/minivhd/minivhd_util.c | 323 +++++ src/minivhd/minivhd_util.h | 136 ++ src/pc.xrc | 55 +- src/resources.h | 1 + src/wx-config.c | 406 +++++- src/wx-resources.cpp | 1954 +++++++++++++++------------- src/wx-sdl2.c | 10 + src/wx-sdl2.h | 1 + src/wx-utils.cc | 15 + src/wx-utils.h | 5 + 31 files changed, 6540 insertions(+), 1054 deletions(-) create mode 100644 src/minivhd/CREDITS.md create mode 100644 src/minivhd/LICENSE create mode 100644 src/minivhd/cwalk.c create mode 100644 src/minivhd/cwalk.h create mode 100644 src/minivhd/libxml2_encoding.c create mode 100644 src/minivhd/libxml2_encoding.h create mode 100644 src/minivhd/minivhd.h create mode 100644 src/minivhd/minivhd_convert.c create mode 100644 src/minivhd/minivhd_create.c create mode 100644 src/minivhd/minivhd_create.h create mode 100644 src/minivhd/minivhd_internal.h create mode 100644 src/minivhd/minivhd_io.c create mode 100644 src/minivhd/minivhd_io.h create mode 100644 src/minivhd/minivhd_manage.c create mode 100644 src/minivhd/minivhd_struct_rw.c create mode 100644 src/minivhd/minivhd_struct_rw.h create mode 100644 src/minivhd/minivhd_util.c create mode 100644 src/minivhd/minivhd_util.h diff --git a/src/Makefile.am b/src/Makefile.am index 34f85d3..3338098 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,6 +62,10 @@ 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 +#MiniVHD +pcem_SOURCES += minivhd/cwalk.c minivhd/libxml2_encoding.c minivhd/minivhd_convert.c minivhd/minivhd_create.c \ +minivhd/minivhd_io.c minivhd/minivhd_manage.c minivhd/minivhd_struct_rw.c minivhd/minivhd_util.c + pcem_CFLAGS = $(subst -fpermissive,,$(shell $(WX_CONFIG_PATH) --cxxflags) $(shell sdl2-config --cflags)) pcem_CXXFLAGS = $(shell $(WX_CONFIG_PATH) --cxxflags) $(shell sdl2-config --cflags) pcem_LDADD = @LIBS@ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 7f82868..cca1422 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -1,4 +1,4 @@ -VPATH = . dosbox resid-fp +VPATH = . dosbox resid-fp minivhd CPP = g++ CC = gcc WINDRES = windres.exe @@ -45,11 +45,12 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 wx-joystickconfig.o wx-createdisc.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 +MVHDOBJ = cwalk.o libxml2_encoding.o minivhd_convert.o minivhd_create.o minivhd_io.o minivhd_manage.o minivhd_struct_rw.o minivhd_util.o LIBS = -Wl,--subsystem,windows -mthreads -mwindows -lwxmsw$(WXVERSION)u_xrc -lwxmsw$(WXVERSION)u_html -lwxmsw$(WXVERSION)u_adv -lwxbase$(WXVERSION)u_xml -lwxmsw$(WXVERSION)u_core -lwxbase$(WXVERSION)u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -lcomdlg32 -lwinspool -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lmingw32 -lopengl32 -lopenal32 -lstdc++ -lSDL2main -lSDL2 -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc -PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem-wx-SDL2.exe" $(LIBS) +PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(MVHDOBJ) + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(MVHDOBJ) -o "PCem-wx-SDL2.exe" $(LIBS) strip -s PCem-wx-SDL2.exe all : PCem-wx-SDL2.exe diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 956ef98..f63b3f5 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -1,4 +1,4 @@ -VPATH = . dosbox resid-fp +VPATH = . dosbox resid-fp minivhd CPP = g++ CC = gcc WINDRES = windres.exe @@ -45,12 +45,13 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 wx-joystickconfig.o wx-createdisc.o wx.res DBOBJ = cdrom_image.o dbopl.o nukedopl.o vid_cga_comp.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 +MVHDOBJ = cwalk.o libxml2_encoding.o minivhd_convert.o minivhd_create.o minivhd_io.o minivhd_manage.o minivhd_struct_rw.o minivhd_util.o NETOBJ = ne2000.o nethandler.o LIBS = -Wl,--subsystem,windows -mthreads -mwindows -lwxmsw$(WXVERSION)u_xrc -lwxmsw$(WXVERSION)u_html -lwxmsw$(WXVERSION)u_adv -lwxbase$(WXVERSION)u_xml -lwxmsw$(WXVERSION)u_core -lwxbase$(WXVERSION)u -lwxtiff -lwxjpeg -lwxpng -lwxzlib -lwxregexu -lwxexpat -lkernel32 -lcomdlg32 -lwinspool -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lmingw32 -lopengl32 -lopenal32 -lstdc++ -lSDL2main -lSDL2 -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc -lwsock32 -liphlpapi -PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) libslirp.a - $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(NETOBJ) slirp/libslirp.a -o "PCem-wx-SDL2.exe" $(LIBS) +PCem-wx-SDL2.exe: $(OBJ) $(DBOBJ) $(SIDOBJ) $(MVHDOBJ) $(NETOBJ) libslirp.a + $(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) $(MVHDOBJ) $(NETOBJ) slirp/libslirp.a -o "PCem-wx-SDL2.exe" $(LIBS) strip -s PCem-wx-SDL2.exe libslirp.a: diff --git a/src/hdd_file.c b/src/hdd_file.c index 27cba2e..f5c4ffd 100644 --- a/src/hdd_file.c +++ b/src/hdd_file.c @@ -5,6 +5,8 @@ #include "ibm.h" #include "hdd_file.h" +#include "minivhd/minivhd.h" +#include "minivhd/minivhd_util.h" void hdd_load_ext(hdd_file_t *hdd, const char *fn, int spt, int hpc, int tracks, int read_only) { @@ -12,17 +14,52 @@ void hdd_load_ext(hdd_file_t *hdd, const char *fn, int spt, int hpc, int tracks, { /* Try to open existing hard disk image */ if (read_only) - hdd->f = fopen64(fn, "rb"); + hdd->f = (void*)fopen64(fn, "rb"); + else + hdd->f = (void*)fopen64(fn, "rb+"); + if (hdd->f != NULL) + { + hdd->img_type = HDD_IMG_RAW; + /* Check if the file we opened is a VHD */ + if (mvhd_file_is_vhd((FILE*)hdd->f)) + { + int err; + fclose((FILE*)hdd->f); + MVHDMeta *vhdm = mvhd_open(fn, (bool)read_only, &err); + if (vhdm == NULL) + { + hdd->f = NULL; + if (err == MVHD_ERR_FILE) + { + pclog("Cannot open VHD file '%s' : %s", + fn, strerror(mvhd_errno)); + } + else + { + pclog("Cannot open VHD file '%s' : %s", + fn, mvhd_strerr(err)); + } + return; + } + else if (err == MVHD_ERR_TIMESTAMP) + { + pclog("VHD: Parent/child timestamp mismatch"); + mvhd_close(vhdm); + hdd->f = NULL; + return; + } + hdd->f = (void*)vhdm; + hdd->img_type = HDD_IMG_VHD; + } + } else - hdd->f = fopen64(fn, "rb+"); - if (hdd->f == NULL) { /* Failed to open existing hard disk image */ if (errno == ENOENT && !read_only) { /* Failed because it does not exist, so try to create new file */ - hdd->f = fopen64(fn, "wb+"); + hdd->f = (void*)fopen64(fn, "wb+"); if (hdd->f == NULL) { pclog("Cannot create file '%s': %s", @@ -37,13 +74,24 @@ void hdd_load_ext(hdd_file_t *hdd, const char *fn, int spt, int hpc, int tracks, fn, strerror(errno)); return; } + hdd->img_type = HDD_IMG_RAW; } } - - hdd->spt = spt; - hdd->hpc = hpc; - hdd->tracks = tracks; - hdd->sectors = spt * hpc * tracks; + if (hdd->img_type == HDD_IMG_VHD) + { + MVHDMeta *vhdm = (MVHDMeta*)hdd->f; + MVHDGeom geom = mvhd_get_geometry(vhdm); + hdd->spt = geom.spt; + hdd->hpc = geom.heads; + hdd->tracks = geom.cyl; + } + else if (hdd->img_type == HDD_IMG_RAW) + { + hdd->spt = spt; + hdd->hpc = hpc; + hdd->tracks = tracks; + } + hdd->sectors = hdd->spt * hdd->hpc * hdd->tracks; hdd->read_only = read_only; } @@ -56,68 +104,99 @@ void hdd_close(hdd_file_t *hdd) { if (hdd->f) { - fclose(hdd->f); - hdd->f = NULL; + if (hdd->img_type == HDD_IMG_VHD) + mvhd_close((MVHDMeta*)hdd->f); + else if (hdd->img_type == HDD_IMG_RAW) + fclose((FILE*)hdd->f); } + hdd->img_type = HDD_IMG_RAW; + hdd->f = NULL; } int hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { - off64_t addr; - int transfer_sectors = nr_sectors; + if (hdd->img_type == HDD_IMG_VHD) + { + return mvhd_read_sectors((MVHDMeta*)hdd->f, offset, nr_sectors, buffer); + } + else if (hdd->img_type == HDD_IMG_RAW) + { + off64_t addr; + int transfer_sectors = nr_sectors; - if ((hdd->sectors - offset) < transfer_sectors) - transfer_sectors = hdd->sectors - offset; - addr = (uint64_t)offset * 512; + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; + addr = (uint64_t)offset * 512; - fseeko64(hdd->f, addr, SEEK_SET); - fread(buffer, transfer_sectors*512, 1, hdd->f); - - if (nr_sectors != transfer_sectors) - return 1; - return 0; + fseeko64((FILE*)hdd->f, addr, SEEK_SET); + fread(buffer, transfer_sectors*512, 1, (FILE*)hdd->f); + + if (nr_sectors != transfer_sectors) + return 1; + return 0; + } + /* Keep the compiler happy */ + return 1; } int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { - off64_t addr; - int transfer_sectors = nr_sectors; - - if (hdd->read_only) - return 1; + if (hdd->img_type == HDD_IMG_VHD) + { + return mvhd_write_sectors((MVHDMeta*)hdd->f, offset, nr_sectors, buffer); + } + else if (hdd->img_type == HDD_IMG_RAW) + { + off64_t addr; + int transfer_sectors = nr_sectors; - if ((hdd->sectors - offset) < transfer_sectors) - transfer_sectors = hdd->sectors - offset; - addr = (uint64_t)offset * 512; + if (hdd->read_only) + return 1; - fseeko64(hdd->f, addr, SEEK_SET); - fwrite(buffer, transfer_sectors*512, 1, hdd->f); - - if (nr_sectors != transfer_sectors) - return 1; - return 0; + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; + addr = (uint64_t)offset * 512; + + fseeko64((FILE*)hdd->f, addr, SEEK_SET); + fwrite(buffer, transfer_sectors*512, 1, (FILE*)hdd->f); + + if (nr_sectors != transfer_sectors) + return 1; + return 0; + } + /* Keep the compiler happy */ + return 1; } int hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) { - off64_t addr; - int c; - uint8_t zero_buffer[512]; - int transfer_sectors = nr_sectors; - - if (hdd->read_only) - return 1; + if (hdd->img_type == HDD_IMG_VHD) + { + return mvhd_format_sectors((MVHDMeta*)hdd->f, offset, nr_sectors); + } + else if (hdd->img_type == HDD_IMG_RAW) + { + off64_t addr; + int c; + uint8_t zero_buffer[512]; + int transfer_sectors = nr_sectors; - memset(zero_buffer, 0, 512); - - if ((hdd->sectors - offset) < transfer_sectors) - transfer_sectors = hdd->sectors - offset; - addr = (uint64_t)offset * 512; - fseeko64(hdd->f, addr, SEEK_SET); - for (c = 0; c < transfer_sectors; c++) - fwrite(zero_buffer, 512, 1, hdd->f); - - if (nr_sectors != transfer_sectors) - return 1; - return 0; + if (hdd->read_only) + return 1; + + memset(zero_buffer, 0, 512); + + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; + addr = (uint64_t)offset * 512; + fseeko64((FILE*)hdd->f, addr, SEEK_SET); + for (c = 0; c < transfer_sectors; c++) + fwrite(zero_buffer, 512, 1, (FILE*)hdd->f); + + if (nr_sectors != transfer_sectors) + return 1; + return 0; + } + /* Keep the compiler happy */ + return 1; } diff --git a/src/hdd_file.h b/src/hdd_file.h index e3265e3..485e09f 100644 --- a/src/hdd_file.h +++ b/src/hdd_file.h @@ -1,11 +1,18 @@ +typedef enum hdd_img_type +{ + HDD_IMG_RAW, + HDD_IMG_VHD, +} hdd_img_type; + typedef struct hdd_file_t { - FILE *f; + void *f; int spt; int hpc; int tracks; int sectors; int read_only; + hdd_img_type img_type; } hdd_file_t; void hdd_load(hdd_file_t *hdd, int d, const char *fn); diff --git a/src/minivhd/CREDITS.md b/src/minivhd/CREDITS.md new file mode 100644 index 0000000..c494d4e --- /dev/null +++ b/src/minivhd/CREDITS.md @@ -0,0 +1,12 @@ +# Credits +MiniVHD Copyright (c) 2019 Sherman Perry + +MiniVHD was made possible with the help of the following projects + +### libxml2 +**Project Home:** http://www.xmlsoft.org/ +**License:** MIT (see src/libxml2_encoding.c for details) + +### cwalk +**Project Home:** https://likle.github.io/cwalk/ +**Licence:** MIT (https://github.com/likle/cwalk/blob/master/LICENSE.md) diff --git a/src/minivhd/LICENSE b/src/minivhd/LICENSE new file mode 100644 index 0000000..b5392e6 --- /dev/null +++ b/src/minivhd/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019-2020 Sherman Perry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/minivhd/cwalk.c b/src/minivhd/cwalk.c new file mode 100644 index 0000000..265de0f --- /dev/null +++ b/src/minivhd/cwalk.c @@ -0,0 +1,1421 @@ +#include +#include +#include +#include +#include +#include "cwalk.h" +/** + * We try to default to a different path style depending on the operating + * system. So this should detect whether we should use windows or unix paths. + */ +#if defined(WIN32) || defined(_WIN32) || \ + defined(__WIN32) && !defined(__CYGWIN__) +static enum cwk_path_style path_style = CWK_STYLE_WINDOWS; +#else +static enum cwk_path_style path_style = CWK_STYLE_UNIX; +#endif + +/** + * This is a list of separators used in different styles. Windows can read + * multiple separators, but it generally outputs just a backslash. The output + * will always use the first character for the output. + */ +static const char *separators[] = {[CWK_STYLE_WINDOWS] = "\\/", + [CWK_STYLE_UNIX] = "/"}; + +/** + * A joined path represents multiple path strings which are concatenated, but + * not (necessarily) stored in contiguous memory. The joined path allows to + * iterate over the segments as if it was one piece of path. + */ +struct cwk_segment_joined +{ + struct cwk_segment segment; + const char **paths; + size_t path_index; +}; + +static size_t cwk_path_output_sized(char *buffer, size_t buffer_size, + size_t position, const char *str, size_t length) +{ + size_t amount_written; + + // First we determine the amount which we can write to the buffer. There are + // three cases. In the first case we have enough to store the whole string in + // it. In the second one we can only store a part of it, and in the third we + // have no space left. + if (buffer_size > position + length) { + amount_written = length; + } else if (buffer_size > position) { + amount_written = buffer_size - position; + } else { + amount_written = 0; + } + + // If we actually want to write out something we will do that here. We will + // always append a '\0', this way we are guaranteed to have a valid string at + // all times. + if (amount_written > 0) { + memmove(&buffer[position], str, amount_written); + } + + // Return the theoretical length which would have been written when everything + // would have fit in the buffer. + return length; +} + +static size_t cwk_path_output_current(char *buffer, size_t buffer_size, + size_t position) +{ + // We output a "current" directory, which is a single character. This + // character is currently not style dependant. + return cwk_path_output_sized(buffer, buffer_size, position, ".", 1); +} + +static size_t cwk_path_output_back(char *buffer, size_t buffer_size, + size_t position) +{ + // We output a "back" directory, which ahs two characters. This + // character is currently not style dependant. + return cwk_path_output_sized(buffer, buffer_size, position, "..", 2); +} + +static size_t cwk_path_output_separator(char *buffer, size_t buffer_size, + size_t position) +{ + // We output a separator, which is a single character. + return cwk_path_output_sized(buffer, buffer_size, position, + separators[path_style], 1); +} + +static size_t cwk_path_output_dot(char *buffer, size_t buffer_size, + size_t position) +{ + // We output a dot, which is a single character. This is used for extensions. + return cwk_path_output_sized(buffer, buffer_size, position, ".", 1); +} + +static size_t cwk_path_output(char *buffer, size_t buffer_size, size_t position, + const char *str) +{ + size_t length; + + // This just does a sized output internally, but first measuring the + // null-terminated string. + length = strlen(str); + return cwk_path_output_sized(buffer, buffer_size, position, str, length); +} + +static void cwk_path_terminate_output(char *buffer, size_t buffer_size, + size_t pos) +{ + if (buffer_size > 0) { + if (pos >= buffer_size) { + buffer[buffer_size - 1] = '\0'; + } else { + buffer[pos] = '\0'; + } + } +} + +static bool cwk_path_is_string_equal(const char *first, const char *second, + size_t n) +{ + // If the path style is UNIX, we will compare case sensitively. This can be + // done easily using strncmp. + if (path_style == CWK_STYLE_UNIX) { + return strncmp(first, second, n) == 0; + } + + // However, if this is windows we will have to compare case insensitively. + // Since there is no standard method to do that we will have to do it on our + // own. + while (*first && *second && n > 0) { + // We can consider the string to be not equal if the two lowercase + // characters are not equal. + if (tolower(*first++) != tolower(*second++)) { + return false; + } + + --n; + } + + // We can consider the string to be equal if we either reached n == 0 or both + // cursors point to a null character. + return n == 0 || (*first == '\0' && *second == '\0'); +} + +static const char *cwk_path_find_next_stop(const char *c) +{ + // We just move forward until we find a '\0' or a separator, which will be our + // next "stop". + while (*c != '\0' && !cwk_path_is_separator(c)) { + ++c; + } + + // Return the pointer of the next stop. + return c; +} + +static const char *cwk_path_find_previous_stop(const char *begin, const char *c) +{ + // We just move back until we find a separator or reach the beginning of the + // path, which will be our previous "stop". + while (c > begin && !cwk_path_is_separator(c)) { + --c; + } + + // Return the pointer to the previous stop. We have to return the first + // character after the separator, not on the separator itself. + if (cwk_path_is_separator(c)) { + return c + 1; + } else { + return c; + } +} + +static bool cwk_path_get_first_segment_without_root(const char *path, + const char *segments, struct cwk_segment *segment) +{ + // Let's remember the path. We will move the path pointer afterwards, that's + // why this has to be done first. + segment->path = path; + segment->segments = segments; + + // Now let's check whether this is an empty string. An empty string has no + // segment it could use. + if (*segments == '\0') { + return false; + } + + // If the string starts with separators, we will jump over those. If there is + // only a slash and a '\0' after it, we can't determine the first segment + // since there is none. + while (cwk_path_is_separator(segments)) { + ++segments; + if (*segments == '\0') { + return false; + } + } + + // So this is the beginning of our segment. + segment->begin = segments; + + // Now let's determine the end of the segment, which we do by moving the path + // pointer further until we find a separator. + segments = cwk_path_find_next_stop(segments); + + // And finally, calculate the size of the segment by subtracting the position + // from the end. + segment->size = segments - segment->begin; + segment->end = segments; + + // Tell the caller that we found a segment. + return true; +} + +static bool cwk_path_get_last_segment_without_root(const char *path, + struct cwk_segment *segment) +{ + // Now this is fairly similar to the normal algorithm, however, it will assume + // that there is no root in the path. So we grab the first segment at this + // position, assuming there is no root. + if (!cwk_path_get_first_segment_without_root(path, path, segment)) { + return false; + } + + // Now we find our last segment. The segment struct of the caller + // will contain the last segment, since the function we call here will not + // change the segment struct when it reaches the end. + while (cwk_path_get_next_segment(segment)) { + // We just loop until there is no other segment left. + } + + return true; +} + +static bool cwk_path_get_first_segment_joined(const char **paths, + struct cwk_segment_joined *sj) +{ + bool result; + + // Prepare the first segment. We position the joined segment on the first path + // and assign the path array to the struct. + sj->path_index = 0; + sj->paths = paths; + + // We loop through all paths until we find one which has a segment. The result + // is stored in a variable, so we can let the caller know whether we found one + // or not. + result = false; + while (paths[sj->path_index] != NULL && + (result = cwk_path_get_first_segment(paths[sj->path_index], + &sj->segment)) == false) { + ++sj->path_index; + } + + return result; +} + +static bool cwk_path_get_next_segment_joined(struct cwk_segment_joined *sj) +{ + bool result; + + if (sj->paths[sj->path_index] == NULL) { + // We reached already the end of all paths, so there is no other segment + // left. + return false; + } else if (cwk_path_get_next_segment(&sj->segment)) { + // There was another segment on the current path, so we are good to + // continue. + return true; + } + + // We try to move to the next path which has a segment available. We must at + // least move one further since the current path reached the end. + result = false; + + do { + ++sj->path_index; + + // And we obviously have to stop this loop if there are no more paths left. + if (sj->paths[sj->path_index] == NULL) { + break; + } + + // Grab the first segment of the next path and determine whether this path + // has anything useful in it. There is one more thing we have to consider + // here - for the first time we do this we want to skip the root, but + // afterwards we will consider that to be part of the segments. + result = cwk_path_get_first_segment_without_root(sj->paths[sj->path_index], + sj->paths[sj->path_index], &sj->segment); + + } while (!result); + + // Finally, report the result back to the caller. + return result; +} + +static bool cwk_path_get_previous_segment_joined(struct cwk_segment_joined *sj) +{ + bool result; + + if (*sj->paths == NULL) { + // It's possible that there is no initialized segment available in the + // struct since there are no paths. In that case we can return false, since + // there is no previous segment. + return false; + } else if (cwk_path_get_previous_segment(&sj->segment)) { + // Now we try to get the previous segment from the current path. If we can + // do that successfully, we can let the caller know that we found one. + return true; + } + + result = false; + + do { + // We are done once we reached index 0. In that case there are no more + // segments left. + if (sj->path_index == 0) { + break; + } + + // There is another path which we have to inspect. So we decrease the path + // index. + --sj->path_index; + + // If this is the first path we will have to consider that this path might + // include a root, otherwise we just treat is as a segment. + if (sj->path_index == 0) { + result = cwk_path_get_last_segment(sj->paths[sj->path_index], + &sj->segment); + } else { + result = cwk_path_get_last_segment_without_root(sj->paths[sj->path_index], + &sj->segment); + } + + } while (!result); + + return result; +} + +static bool cwk_path_segment_back_will_be_removed(struct cwk_segment_joined *sj) +{ + enum cwk_segment_type type; + int counter; + + // We are handling back segments here. We must verify how many back segments + // and how many normal segments come before this one to decide whether we keep + // or remove it. + + // The counter determines how many normal segments are our current segment, + // which will popped off before us. If the counter goes above zero it means + // that our segment will be popped as well. + counter = 0; + + // We loop over all previous segments until we either reach the beginning, + // which means our segment will not be dropped or the counter goes above zero. + while (cwk_path_get_previous_segment_joined(sj)) { + + // Now grab the type. The type determines whether we will increase or + // decrease the counter. We don't handle a CWK_CURRENT frame here since it + // has no influence. + type = cwk_path_get_segment_type(&sj->segment); + if (type == CWK_NORMAL) { + // This is a normal segment. The normal segment will increase the counter + // since it neutralizes one back segment. If we go above zero we can + // return immediately. + ++counter; + if (counter > 0) { + return true; + } + } else if (type == CWK_BACK) { + // A CWK_BACK segment will reduce the counter by one. We can not remove a + // back segment as long we are not above zero since we don't have the + // opposite normal segment which we would remove. + --counter; + } + } + + // We never got a count larger than zero, so we will keep this segment alive. + return false; +} + +static bool cwk_path_segment_normal_will_be_removed( + struct cwk_segment_joined *sj) +{ + enum cwk_segment_type type; + int counter; + + // The counter determines how many segments are above our current segment, + // which will popped off before us. If the counter goes below zero it means + // that our segment will be popped as well. + counter = 0; + + // We loop over all following segments until we either reach the end, which + // means our segment will not be dropped or the counter goes below zero. + while (cwk_path_get_next_segment_joined(sj)) { + + // First, grab the type. The type determines whether we will increase or + // decrease the counter. We don't handle a CWK_CURRENT frame here since it + // has no influence. + type = cwk_path_get_segment_type(&sj->segment); + if (type == CWK_NORMAL) { + // This is a normal segment. The normal segment will increase the counter + // since it will be removed by a "../" before us. + ++counter; + } else if (type == CWK_BACK) { + // A CWK_BACK segment will reduce the counter by one. If we are below zero + // we can return immediately. + --counter; + if (counter < 0) { + return true; + } + } + } + + // We never got a negative count, so we will keep this segment alive. + return false; +} + +static bool +cwk_path_segment_will_be_removed(const struct cwk_segment_joined *sj, + bool absolute) +{ + enum cwk_segment_type type; + struct cwk_segment_joined sjc; + + // We copy the joined path so we don't need to modify it. + sjc = *sj; + + // First we check whether this is a CWK_CURRENT or CWK_BACK segment, since + // those will always be dropped. + type = cwk_path_get_segment_type(&sj->segment); + if (type == CWK_CURRENT) { + return true; + } else if (type == CWK_BACK && absolute) { + return true; + } else if (type == CWK_BACK) { + return cwk_path_segment_back_will_be_removed(&sjc); + } else { + return cwk_path_segment_normal_will_be_removed(&sjc); + } +} + +static bool +cwk_path_segment_joined_skip_invisible(struct cwk_segment_joined *sj, + bool absolute) +{ + while (cwk_path_segment_will_be_removed(sj, absolute)) { + if (!cwk_path_get_next_segment_joined(sj)) { + return false; + } + } + + return true; +} + +static void cwk_path_get_root_windows(const char *path, size_t *length) +{ + const char *c; + bool is_device_path; + + // A device path is a path which starts with "\\." or "\\?". A device path can + // be a UNC path as well, in which case it will take up one more segment. + is_device_path = false; + + // We can not determine the root if this is an empty string. So we set the + // root to NULL and the length to zero and cancel the whole thing. + c = path; + *length = 0; + if (!*c) { + return; + } + + // Now we have to verify whether this is a windows network path (UNC), which + // we will consider our root. + if (cwk_path_is_separator(c)) { + ++c; + + // Check whether the path starts with a single back slash, which means this + // is not a network path - just a normal path starting with a backslash. + if (!cwk_path_is_separator(c)) { + // Okay, this is not a network path but we still use the backslash as a + // root. + ++(*length); + return; + } + + // Yes, this is a network or device path. Skip the previous separator. Now + // we need to determine whether this is a device path. We might advance one + // character here if the server name starts with a '?' or a '.', but that's + // fine since we will search for a separator afterwards anyway. + ++c; + is_device_path = (*c == '?' || *c == '.') && cwk_path_is_separator(++c); + if (is_device_path) { + // That's a device path, and the root must be either "\\.\" or "\\?\" + // which is 4 characters long. (at least that's how Windows + // GetFullPathName behaves.) + *length = 4; + return; + } + + // We will grab anything up to the next stop. The next top might be a '\0' + // or another separator. That will be the server name. + c = cwk_path_find_next_stop(c); + + // If this is a separator and not the end of a string we wil have to include + // it. However, if this is a '\0' we must not skip it. + while (cwk_path_is_separator(c)) { + ++c; + } + + // We are now skipping the shared folder name, which will end after the + // next stop. + c = cwk_path_find_next_stop(c); + + // Then there might be a separator at the end. We will include that as well, + // it will mark the path as absolute. + if (cwk_path_is_separator(c)) { + ++c; + } + + // Finally, calculate the size of the root. + *length = c - path; + return; + } + + // Move to the next and check whether this is a colon. + if (*++c == ':') { + *length = 2; + + // Now check whether this is a backslash (or slash). If it is not, we could + // assume that the next character is a '\0' if it is a valid path. However, + // we will not assume that - since ':' is not valid in a path it must be a + // mistake by the caller than. We will try to understand it anyway. + if (cwk_path_is_separator(++c)) { + *length = 3; + } + } +} + +static void cwk_path_get_root_unix(const char *path, size_t *length) +{ + // The slash of the unix path represents the root. There is no root if there + // is no slash. + if (cwk_path_is_separator(path)) { + *length = 1; + } else { + *length = 0; + } +} + +static bool cwk_path_is_root_absolute(const char *path, size_t length) +{ + // This is definitely not absolute if there is no root. + if (length == 0) { + return false; + } + + // If there is a separator at the end of the root, we can safely consider this + // to be an absolute path. + return cwk_path_is_separator(&path[length - 1]); +} + +static size_t cwk_path_join_and_normalize_multiple(const char **paths, + char *buffer, size_t buffer_size) +{ + size_t pos; + bool absolute, has_segment_output; + struct cwk_segment_joined sj; + + // We initialize the position after the root, which should get us started. + cwk_path_get_root(paths[0], &pos); + + // Determine whether the path is absolute or not. We need that to determine + // later on whether we can remove superfluous "../" or not. + absolute = cwk_path_is_root_absolute(paths[0], pos); + + // First copy the root to the output. We will not modify the root. + cwk_path_output_sized(buffer, buffer_size, 0, paths[0], pos); + + // So we just grab the first segment. If there is no segment we will always + // output a "/", since we currently only support absolute paths here. + if (!cwk_path_get_first_segment_joined(paths, &sj)) { + goto done; + } + + // Let's assume that we don't have any segment output for now. We will toggle + // this flag once there is some output. + has_segment_output = false; + + do { + // Check whether we have to drop this segment because of resolving a + // relative path or because it is a CWK_CURRENT segment. + if (cwk_path_segment_will_be_removed(&sj, absolute)) { + continue; + } + + // Remember that we have segment output, so we can handle the trailing slash + // later on. This is necessary since we might have segments but they are all + // removed. + has_segment_output = true; + + // Write out the segment but keep in mind that we need to follow the + // buffer size limitations. That's why we use the path output functions + // here. + pos += cwk_path_output_sized(buffer, buffer_size, pos, sj.segment.begin, + sj.segment.size); + pos += cwk_path_output_separator(buffer, buffer_size, pos); + } while (cwk_path_get_next_segment_joined(&sj)); + + // Remove the trailing slash, but only if we have segment output. We don't + // want to remove anything from the root. + if (has_segment_output) { + --pos; + } else if (pos == 0) { + // This may happen if the path is absolute and all segments have been + // removed. We can not have an empty output - and empty output means we stay + // in the current directory. So we will output a ".". + assert(absolute == false); + pos += cwk_path_output_current(buffer, buffer_size, pos); + } + + // We must append a '\0' in any case, unless the buffer size is zero. If the + // buffer size is zero, which means we can not. +done: + cwk_path_terminate_output(buffer, buffer_size, pos); + + // And finally let our caller know about the total size of the normalized + // path. + return pos; +} + +size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, + size_t buffer_size) +{ + size_t i; + const char *paths[4]; + + // The basename should be an absolute path if the caller is using the API + // correctly. However, he might not and in that case we will append a fake + // root at the beginning. + if (cwk_path_is_absolute(base)) { + i = 0; + } else { + paths[0] = "/"; + i = 1; + } + + if (cwk_path_is_absolute(path)) { + // If the submitted path is not relative the base path becomes irrelevant. + // We will only normalize the submitted path instead. + paths[i++] = path; + paths[i] = NULL; + } else { + // Otherwise we append the relative path to the base path and normalize it. + // The result will be a new absolute path. + paths[i++] = base; + paths[i++] = path; + paths[i] = NULL; + } + + // Finally join everything together and normalize it. + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); +} + +static void cwk_path_skip_segments_until_diverge(struct cwk_segment_joined *bsj, + struct cwk_segment_joined *osj, bool absolute, bool *base_available, + bool *other_available) +{ + // Now looping over all segments until they start to diverge. A path may + // diverge if two segments are not equal or if one path reaches the end. + do { + + // Check whether there is anything available after we skip everything which + // is invisible. We do that for both paths, since we want to let the caller + // know which path has some trailing segments after they diverge. + *base_available = cwk_path_segment_joined_skip_invisible(bsj, absolute); + *other_available = cwk_path_segment_joined_skip_invisible(osj, absolute); + + // We are done if one or both of those paths reached the end. They either + // diverge or both reached the end - but in both cases we can not continue + // here. + if (!*base_available || !*other_available) { + break; + } + + // Compare the content of both segments. We are done if they are not equal, + // since they diverge. + if (!cwk_path_is_string_equal(bsj->segment.begin, osj->segment.begin, + bsj->segment.size)) { + break; + } + + // We keep going until one of those segments reached the end. The next + // segment might be invisible, but we will check for that in the beginning + // of the loop once again. + *base_available = cwk_path_get_next_segment_joined(bsj); + *other_available = cwk_path_get_next_segment_joined(osj); + } while (*base_available && *other_available); +} + +size_t cwk_path_get_relative(const char *base_directory, const char *path, + char *buffer, size_t buffer_size) +{ + size_t pos, base_root_length, path_root_length; + bool absolute, base_available, other_available, has_output; + const char *base_paths[2], *other_paths[2]; + struct cwk_segment_joined bsj, osj; + + pos = 0; + + // First we compare the roots of those two paths. If the roots are not equal + // we can't continue, since there is no way to get a relative path from + // different roots. + cwk_path_get_root(base_directory, &base_root_length); + cwk_path_get_root(path, &path_root_length); + if (!cwk_path_is_string_equal(base_directory, path, base_root_length)) { + return pos; + } + + // Verify whether this is an absolute path. We need to know that since we can + // remove all back-segments if it is. + absolute = cwk_path_is_root_absolute(base_directory, base_root_length); + + // Initialize our joined segments. This will allow us to use the internal + // functions to skip until diverge and invisible. We only have one path in + // them though. + base_paths[0] = base_directory; + base_paths[1] = NULL; + other_paths[0] = path; + other_paths[1] = NULL; + cwk_path_get_first_segment_joined(base_paths, &bsj); + cwk_path_get_first_segment_joined(other_paths, &osj); + + // Okay, now we skip until the segments diverge. We don't have anything to do + // with the segments which are equal. + cwk_path_skip_segments_until_diverge(&bsj, &osj, absolute, &base_available, + &other_available); + + // Assume there is no output until we have got some. We will need this + // information later on to remove trailing slashes or alternatively output a + // current-segment. + has_output = false; + + // So if we still have some segments left in the base path we will now output + // a back segment for all of them. + if (base_available) { + do { + // Skip any invisible segment. We don't care about those and we don't need + // to navigate back because of them. + if (!cwk_path_segment_joined_skip_invisible(&bsj, absolute)) { + break; + } + + // Toggle the flag if we have output. We need to remember that, since we + // want to remove the trailing slash. + has_output = true; + + // Output the back segment and a separator. No need to worry about the + // superfluous segment since it will be removed later on. + pos += cwk_path_output_back(buffer, buffer_size, pos); + pos += cwk_path_output_separator(buffer, buffer_size, pos); + } while (cwk_path_get_next_segment_joined(&bsj)); + } + + // And if we have some segments available of the target path we will output + // all of those. + if (other_available) { + do { + // Again, skip any invisible segments since we don't need to navigate into + // them. + if (!cwk_path_segment_joined_skip_invisible(&osj, absolute)) { + break; + } + + // Toggle the flag if we have output. We need to remember that, since we + // want to remove the trailing slash. + has_output = true; + + // Output the current segment and a separator. No need to worry about the + // superfluous segment since it will be removed later on. + pos += cwk_path_output_sized(buffer, buffer_size, pos, osj.segment.begin, + osj.segment.size); + pos += cwk_path_output_separator(buffer, buffer_size, pos); + } while (cwk_path_get_next_segment_joined(&osj)); + } + + // If we have some output by now we will have to remove the trailing slash. We + // simply do that by moving back one character. The terminate output function + // will then place the '\0' on this position. Otherwise, if there is no + // output, we will have to output a "current directory", since the target path + // points to the base path. + if (has_output) { + --pos; + } else { + pos += cwk_path_output_current(buffer, buffer_size, pos); + } + + // Finally, we can terminate the output - which means we place a '\0' at the + // current position or at the end of the buffer. + cwk_path_terminate_output(buffer, buffer_size, pos); + + return pos; +} + +size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, + size_t buffer_size) +{ + const char *paths[3]; + + // This is simple. We will just create an array with the two paths which we + // wish to join. + paths[0] = path_a; + paths[1] = path_b; + paths[2] = NULL; + + // And then call the join and normalize function which will do the hard work + // for us. + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); +} + +size_t cwk_path_join_multiple(const char **paths, char *buffer, + size_t buffer_size) +{ + // We can just call the internal join and normalize function for this one, + // since it will handle everything. + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); +} + +void cwk_path_get_root(const char *path, size_t *length) +{ + // We use a different implementation here based on the configuration of the + // library. + if (path_style == CWK_STYLE_WINDOWS) { + cwk_path_get_root_windows(path, length); + } else { + cwk_path_get_root_unix(path, length); + } +} + +size_t cwk_path_change_root(const char *path, const char *new_root, + char *buffer, size_t buffer_size) +{ + const char *tail; + size_t root_length, path_length, tail_length, new_root_length, new_path_size; + + // First we need to determine the actual size of the root which we will + // change. + cwk_path_get_root(path, &root_length); + + // Now we determine the sizes of the new root and the path. We need that to + // determine the size of the part after the root (the tail). + new_root_length = strlen(new_root); + path_length = strlen(path); + + // Okay, now we calculate the position of the tail and the length of it. + tail = path + root_length; + tail_length = path_length - root_length; + + // We first output the tail and then the new root, that's because the source + // path and the buffer may be overlapping. This way the root will not + // overwrite the tail. + cwk_path_output_sized(buffer, buffer_size, new_root_length, tail, + tail_length); + cwk_path_output_sized(buffer, buffer_size, 0, new_root, new_root_length); + + // Finally we calculate the size o the new path and terminate the output with + // a '\0'. + new_path_size = tail_length + new_root_length; + cwk_path_terminate_output(buffer, buffer_size, new_path_size); + + return new_path_size; +} + +bool cwk_path_is_absolute(const char *path) +{ + size_t length; + + // We grab the root of the path. This root does not include the first + // separator of a path. + cwk_path_get_root(path, &length); + + // Now we can determine whether the root is absolute or not. + return cwk_path_is_root_absolute(path, length); +} + +bool cwk_path_is_relative(const char *path) +{ + // The path is relative if it is not absolute. + return !cwk_path_is_absolute(path); +} + +void cwk_path_get_basename(const char *path, const char **basename, + size_t *length) +{ + struct cwk_segment segment; + + // We get the last segment of the path. The last segment will contain the + // basename if there is any. If there are no segments we will set the basename + // to NULL and the length to 0. + if (!cwk_path_get_last_segment(path, &segment)) { + *basename = NULL; + *length = 0; + return; + } + + // Now we can just output the segment contents, since that's our basename. + // There might be trailing separators after the basename, but the size does + // not include those. + *basename = segment.begin; + *length = segment.size; +} + +size_t cwk_path_change_basename(const char *path, const char *new_basename, + char *buffer, size_t buffer_size) +{ + struct cwk_segment segment; + size_t pos, root_size, new_basename_size; + + // First we try to get the last segment. We may only have a root without any + // segments, in which case we will create one. + if (!cwk_path_get_last_segment(path, &segment)) { + + // So there is no segment in this path. First we grab the root and output + // that. We are not going to modify the root in any way. + cwk_path_get_root(path, &root_size); + pos = cwk_path_output_sized(buffer, buffer_size, 0, path, root_size); + + // We have to trim the separators from the beginning of the new basename. + // This is quite easy to do. + while (cwk_path_is_separator(new_basename)) { + ++new_basename; + } + + // Now we measure the length of the new basename, this is a two step + // process. First we find the '\0' character at the end of the string. + new_basename_size = 0; + while (new_basename[new_basename_size]) { + ++new_basename_size; + } + + // And then we trim the separators at the end of the basename until we reach + // the first valid character. + while (new_basename_size > 0 && + cwk_path_is_separator(&new_basename[new_basename_size - 1])) { + --new_basename_size; + } + + // Now we will output the new basename after the root. + pos += cwk_path_output_sized(buffer, buffer_size, pos, new_basename, + new_basename_size); + + // And finally terminate the output and return the total size of the path. + cwk_path_terminate_output(buffer, buffer_size, pos); + return pos; + } + + // If there is a last segment we can just forward this call, which is fairly + // easy. + return cwk_path_change_segment(&segment, new_basename, buffer, buffer_size); +} + +void cwk_path_get_dirname(const char *path, size_t *length) +{ + struct cwk_segment segment; + + // We get the last segment of the path. The last segment will contain the + // basename if there is any. If there are no segments we will set the length + // to 0. + if (!cwk_path_get_last_segment(path, &segment)) { + *length = 0; + return; + } + + // We can now return the length from the beginning of the string up to the + // beginning of the last segment. + *length = segment.begin - path; +} + +bool cwk_path_get_extension(const char *path, const char **extension, + size_t *length) +{ + struct cwk_segment segment; + const char *c; + + // We get the last segment of the path. The last segment will contain the + // extension if there is any. + if (!cwk_path_get_last_segment(path, &segment)) { + return false; + } + + // Now we search for a dot within the segment. If there is a dot, we consider + // the rest of the segment the extension. We do this from the end towards the + // beginning, since we want to find the last dot. + for (c = segment.end; c >= segment.begin; --c) { + if (*c == '.') { + // Okay, we found an extension. We can stop looking now. + *extension = c; + *length = segment.end - c; + return true; + } + } + + // We couldn't find any extension. + return false; +} + +bool cwk_path_has_extension(const char *path) +{ + const char *extension; + size_t length; + + // We just wrap the get_extension call which will then do the work for us. + return cwk_path_get_extension(path, &extension, &length); +} + +size_t cwk_path_change_extension(const char *path, const char *new_extension, + char *buffer, size_t buffer_size) +{ + struct cwk_segment segment; + const char *c, *old_extension; + size_t pos, root_size, trail_size, new_extension_size; + + // First we try to get the last segment. We may only have a root without any + // segments, in which case we will create one. + if (!cwk_path_get_last_segment(path, &segment)) { + + // So there is no segment in this path. First we grab the root and output + // that. We are not going to modify the root in any way. If there is no + // root, this will end up with a root size 0, and nothing will be written. + cwk_path_get_root(path, &root_size); + pos = cwk_path_output_sized(buffer, buffer_size, 0, path, root_size); + + // Add a dot if the submitted value doesn't have any. + if (*new_extension != '.') { + pos += cwk_path_output_dot(buffer, buffer_size, pos); + } + + // And finally terminate the output and return the total size of the path. + pos += cwk_path_output(buffer, buffer_size, pos, new_extension); + cwk_path_terminate_output(buffer, buffer_size, pos); + return pos; + } + + // Now we seek the old extension in the last segment, which we will replace + // with the new one. If there is no old extension, it will point to the end of + // the segment. + old_extension = segment.end; + for (c = segment.begin; c < segment.end; ++c) { + if (*c == '.') { + old_extension = c; + } + } + + pos = cwk_path_output_sized(buffer, buffer_size, 0, segment.path, + old_extension - segment.path); + + // If the new extension starts with a dot, we will skip that dot. We always + // output exactly one dot before the extension. If the extension contains + // multiple dots, we will output those as part of the extension. + if (*new_extension == '.') { + ++new_extension; + } + + // We calculate the size of the new extension, including the dot, in order to + // output the trail - which is any part of the path coming after the + // extension. We must output this first, since the buffer may overlap with the + // submitted path - and it would be overridden by longer extensions. + new_extension_size = strlen(new_extension) + 1; + trail_size = cwk_path_output(buffer, buffer_size, pos + new_extension_size, + segment.end); + + // Finally we output the dot and the new extension. The new extension itself + // doesn't contain the dot anymore, so we must output that first. + pos += cwk_path_output_dot(buffer, buffer_size, pos); + pos += cwk_path_output(buffer, buffer_size, pos, new_extension); + + // Now we terminate the output with a null-terminating character, but before + // we do that we must add the size of the trail to the position which we + // output before. + pos += trail_size; + cwk_path_terminate_output(buffer, buffer_size, pos); + + // And the position is our output size now. + return pos; +} + +size_t cwk_path_normalize(const char *path, char *buffer, size_t buffer_size) +{ + const char *paths[2]; + + // Now we initialize the paths which we will normalize. Since this function + // only supports submitting a single path, we will only add that one. + paths[0] = path; + paths[1] = NULL; + + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); +} + +size_t cwk_path_get_intersection(const char *path_base, const char *path_other) +{ + bool absolute; + size_t base_root_length, other_root_length; + const char *end; + const char *paths_base[2], *paths_other[2]; + struct cwk_segment_joined base, other; + + // We first compare the two roots. We just return zero if they are not equal. + // This will also happen to return zero if the paths are mixed relative and + // absolute. + cwk_path_get_root(path_base, &base_root_length); + cwk_path_get_root(path_other, &other_root_length); + if (!cwk_path_is_string_equal(path_base, path_other, base_root_length)) { + return 0; + } + + // Configure our paths. We just have a single path in here for now. + paths_base[0] = path_base; + paths_base[1] = NULL; + paths_other[0] = path_other; + paths_other[1] = NULL; + + // So we get the first segment of both paths. If one of those paths don't have + // any segment, we will return 0. + if (!cwk_path_get_first_segment_joined(paths_base, &base) || + !cwk_path_get_first_segment_joined(paths_other, &other)) { + return base_root_length; + } + + // We now determine whether the path is absolute or not. This is required + // because if will ignore removed segments, and this behaves differently if + // the path is absolute. However, we only need to check the base path because + // we are guaranteed that both paths are either relative or absolute. + absolute = cwk_path_is_root_absolute(path_base, base_root_length); + + // We must keep track of the end of the previous segment. Initially, this is + // set to the beginning of the path. This means that 0 is returned if the + // first segment is not equal. + end = path_base + base_root_length; + + // Now we loop over both segments until one of them reaches the end or their + // contents are not equal. + do { + // We skip all segments which will be removed in each path, since we want to + // know about the true path. + if (!cwk_path_segment_joined_skip_invisible(&base, absolute) || + !cwk_path_segment_joined_skip_invisible(&other, absolute)) { + break; + } + + if (!cwk_path_is_string_equal(base.segment.begin, other.segment.begin, + base.segment.size)) { + // So the content of those two segments are not equal. We will return the + // size up to the beginning. + return end - path_base; + } + + // Remember the end of the previous segment before we go to the next one. + end = base.segment.end; + } while (cwk_path_get_next_segment_joined(&base) && + cwk_path_get_next_segment_joined(&other)); + + // Now we calculate the length up to the last point where our paths pointed to + // the same place. + return end - path_base; +} + +bool cwk_path_get_first_segment(const char *path, struct cwk_segment *segment) +{ + size_t length; + const char *segments; + + // We skip the root since that's not part of the first segment. The root is + // treated as a separate entity. + cwk_path_get_root(path, &length); + segments = path + length; + + // Now, after we skipped the root we can continue and find the actual segment + // content. + return cwk_path_get_first_segment_without_root(path, segments, segment); +} + +bool cwk_path_get_last_segment(const char *path, struct cwk_segment *segment) +{ + // We first grab the first segment. This might be our last segment as well, + // but we don't know yet. There is no last segment if there is no first + // segment, so we return false in that case. + if (!cwk_path_get_first_segment(path, segment)) { + return false; + } + + // Now we find our last segment. The segment struct of the caller + // will contain the last segment, since the function we call here will not + // change the segment struct when it reaches the end. + while (cwk_path_get_next_segment(segment)) { + // We just loop until there is no other segment left. + } + + return true; +} + +bool cwk_path_get_next_segment(struct cwk_segment *segment) +{ + const char *c; + + // First we jump to the end of the previous segment. The first character must + // be either a '\0' or a separator. + c = segment->begin + segment->size; + if (*c == '\0') { + return false; + } + + // Now we skip all separator until we reach something else. We are not yet + // guaranteed to have a segment, since the string could just end afterwards. + assert(cwk_path_is_separator(c)); + do { + ++c; + } while (cwk_path_is_separator(c)); + + // If the string ends here, we can safely assume that there is no other + // segment after this one. + if (*c == '\0') { + return false; + } + + // Now we are safe to assume there is a segment. We store the beginning of + // this segment in the segment struct of the caller. + segment->begin = c; + + // And now determine the size of this segment, and store it in the struct of + // the caller as well. + c = cwk_path_find_next_stop(c); + segment->end = c; + segment->size = c - segment->begin; + + // Tell the caller that we found a segment. + return true; +} + +bool cwk_path_get_previous_segment(struct cwk_segment *segment) +{ + const char *c; + + // The current position might point to the first character of the path, which + // means there are no previous segments available. + c = segment->begin; + if (c <= segment->segments) { + return false; + } + + // We move towards the beginning of the path until we either reached the + // beginning or the character is no separator anymore. + do { + --c; + if (c <= segment->segments) { + // So we reached the beginning here and there is no segment. So we return + // false and don't change the segment structure submitted by the caller. + return false; + } + } while (cwk_path_is_separator(c)); + + // We are guaranteed now that there is another segment, since we moved before + // the previous separator and did not reach the segment path beginning. + segment->end = c + 1; + segment->begin = cwk_path_find_previous_stop(segment->segments, c); + segment->size = segment->end - segment->begin; + + return true; +} + +enum cwk_segment_type cwk_path_get_segment_type( + const struct cwk_segment *segment) +{ + // We just make a string comparison with the segment contents and return the + // appropriate type. + if (strncmp(segment->begin, ".", segment->size) == 0) { + return CWK_CURRENT; + } else if (strncmp(segment->begin, "..", segment->size) == 0) { + return CWK_BACK; + } + + return CWK_NORMAL; +} + +bool cwk_path_is_separator(const char *str) +{ + const char *c; + + // We loop over all characters in the read symbols. + c = separators[path_style]; + while (*c) { + if (*c == *str) { + return true; + } + + ++c; + } + + return false; +} + +size_t cwk_path_change_segment(struct cwk_segment *segment, const char *value, + char *buffer, size_t buffer_size) +{ + size_t pos, value_size, tail_size; + + // First we have to output the head, which is the whole string up to the + // beginning of the segment. This part of the path will just stay the same. + pos = cwk_path_output_sized(buffer, buffer_size, 0, segment->path, + segment->begin - segment->path); + + // In order to trip the submitted value, we will skip any separator at the + // beginning of it and behave as if it was never there. + while (cwk_path_is_separator(value)) { + ++value; + } + + // Now we determine the length of the value. In order to do that we first + // locate the '\0'. + value_size = 0; + while (value[value_size]) { + ++value_size; + } + + // Since we trim separators at the beginning and in the end of the value we + // have to subtract from the size until there are either no more characters + // left or the last character is no separator. + while (value_size > 0 && cwk_path_is_separator(&value[value_size - 1])) { + --value_size; + } + + // We also have to determine the tail size, which is the part of the string + // following the current segment. This part will not change. + tail_size = strlen(segment->end); + + // Now we output the tail. We have to do that, because if the buffer and the + // source are overlapping we would override the tail if the value is + // increasing in length. + cwk_path_output_sized(buffer, buffer_size, pos + value_size, segment->end, + tail_size); + + // Finally we can output the value in the middle of the head and the tail, + // where we have enough space to fit the whole trimmed value. + pos += cwk_path_output_sized(buffer, buffer_size, pos, value, value_size); + + // Now we add the tail size to the current position and terminate the output - + // basically, ensure that there is a '\0' at the end of the buffer. + pos += tail_size; + cwk_path_terminate_output(buffer, buffer_size, pos); + + // And now tell the caller how long the whole path would be. + return pos; +} + +enum cwk_path_style cwk_path_guess_style(const char *path) +{ + const char *c; + size_t root_length; + struct cwk_segment segment; + + // First we determine the root. Only windows roots can be longer than a single + // slash, so if we can determine that it starts with something like "C:", we + // know that this is a windows path. + cwk_path_get_root_windows(path, &root_length); + if (root_length > 1) { + return CWK_STYLE_WINDOWS; + } + + // Next we check for slashes. Windows uses backslashes, while unix uses + // forward slashes. Windows actually supports both, but our best guess is to + // assume windows with backslashes and unix with forward slashes. + for (c = path; *c; ++c) { + if (*c == *separators[CWK_STYLE_UNIX]) { + return CWK_STYLE_UNIX; + } else if (*c == *separators[CWK_STYLE_WINDOWS]) { + return CWK_STYLE_WINDOWS; + } + } + + // This path does not have any slashes. We grab the last segment (which + // actually must be the first one), and determine whether the segment starts + // with a dot. A dot is a hidden folder or file in the UNIX world, in that + // case we assume the path to have UNIX style. + if (!cwk_path_get_last_segment(path, &segment)) { + // We couldn't find any segments, so we default to a UNIX path style since + // there is no way to make any assumptions. + return CWK_STYLE_UNIX; + } + + if (*segment.begin == '.') { + return CWK_STYLE_UNIX; + } + + // And finally we check whether the last segment contains a dot. If it + // contains a dot, that might be an extension. Windows is more likely to have + // file names with extensions, so our guess would be windows. + for (c = segment.begin; *c; ++c) { + if (*c == '.') { + return CWK_STYLE_WINDOWS; + } + } + + // All our checks failed, so we will return a default value which is currently + // UNIX. + return CWK_STYLE_UNIX; +} + +void cwk_path_set_style(enum cwk_path_style style) +{ + // We can just set the global path style variable and then the behaviour for + // all functions will change accordingly. + assert(style == CWK_STYLE_UNIX || style == CWK_STYLE_WINDOWS); + path_style = style; +} + +enum cwk_path_style cwk_path_get_style(void) +{ + // Simply return the path style which we store in a global variable. + return path_style; +} diff --git a/src/minivhd/cwalk.h b/src/minivhd/cwalk.h new file mode 100644 index 0000000..baa5d43 --- /dev/null +++ b/src/minivhd/cwalk.h @@ -0,0 +1,457 @@ +#pragma once + +#ifndef CWK_LIBRARY_H +#define CWK_LIBRARY_H + +#include +#include + +/** + * A segment represents a single component of a path. For instance, on linux a + * path might look like this "/var/log/", which consists of two segments "var" + * and "log". + */ +struct cwk_segment +{ + const char *path; + const char *segments; + const char *begin; + const char *end; + size_t size; +}; + +/** + * The segment type can be used to identify whether a segment is a special + * segment or not. + * + * CWK_NORMAL - normal folder or file segment + * CWK_CURRENT - "./" current folder segment + * CWK_BACK - "../" relative back navigation segment + */ +enum cwk_segment_type +{ + CWK_NORMAL, + CWK_CURRENT, + CWK_BACK +}; + +/** + * @brief Determines the style which is used for the path parsing and + * generation. + */ +enum cwk_path_style +{ + CWK_STYLE_WINDOWS, + CWK_STYLE_UNIX +}; + +/** + * @brief Generates an absolute path based on a base. + * + * This function generates an absolute path based on a base path and another + * path. It is guaranteed to return an absolute path. If the second submitted + * path is absolute, it will override the base path. The result will be written + * to a buffer, which might be truncated if the buffer is not large enough to + * hold the full path. However, the truncated result will always be + * null-terminated. The returned value is the amount of characters which the + * resulting path would take if it was not truncated (excluding the + * null-terminating character). + * + * @param base The base path on which the relative path will be applied. + * @param path The relative path which will be applied on the base path. + * @param buffer The buffer where the result will be written to. + * @param buffer_size The size of the result buffer. + * @return Returns the total amount of characters of the new absolute path. + */ +size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, + size_t buffer_size); + +/** + * @brief Generates a relative path based on a base. + * + * This function generates a relative path based on a base path and another + * path. It determines how to get to the submitted path, starting from the base + * directory. The result will be written to a buffer, which might be truncated + * if the buffer is not large enough to hold the full path. However, the + * truncated result will always be null-terminated. The returned value is the + * amount of characters which the resulting path would take if it was not + * truncated (excluding the null-terminating character). + * + * @param base_directory The base path from which the relative path will start. + * @param path The target path where the relative path will point to. + * @param buffer The buffer where the result will be written to. + * @param buffer_size The size of the result buffer. + * @return Returns the total amount of characters of the full path. + */ +size_t cwk_path_get_relative(const char *base_directory, const char *path, + char *buffer, size_t buffer_size); + +/** + * @brief Joins two paths together. + * + * This function generates a new path by combining the two submitted paths. It + * will remove double separators, and unlike cwk_path_get_absolute it permits + * the use of two relative paths to combine. The result will be written to a + * buffer, which might be truncated if the buffer is not large enough to hold + * the full path. However, the truncated result will always be null-terminated. + * The returned value is the amount of characters which the resulting path would + * take if it was not truncated (excluding the null-terminating character). + * + * @param path_a The first path which comes first. + * @param path_b The second path which comes after the first. + * @param buffer The buffer where the result will be written to. + * @param buffer_size The size of the result buffer. + * @return Returns the total amount of characters of the full, combined path. + */ +size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, + size_t buffer_size); + +/** + * @brief Joins multiple paths together. + * + * This function generates a new path by joining multiple paths together. It + * will remove double separators, and unlike cwk_path_get_absolute it permits + * the use of multiple relative paths to combine. The last path of the submitted + * string array must be set to NULL. The result will be written to a buffer, + * which might be truncated if the buffer is not large enough to hold the full + * path. However, the truncated result will always be null-terminated. The + * returned value is the amount of characters which the resulting path would + * take if it was not truncated (excluding the null-terminating character). + * + * @param paths An array of paths which will be joined. + * @param buffer The buffer where the result will be written to. + * @param buffer_size The size of the result buffer. + * @return Returns the total amount of characters of the full, combined path. + */ +size_t cwk_path_join_multiple(const char **paths, char *buffer, + size_t buffer_size); + +/** + * @brief Determines the root of a path. + * + * This function determines the root of a path by finding it's length. The root + * always starts at the submitted path. If the path has no root, the length will + * be set to zero. + * + * @param path The path which will be inspected. + * @param length The output of the root length. + */ +void cwk_path_get_root(const char *path, size_t *length); + +/** + * @brief Changes the root of a path. + * + * This function changes the root of a path. It does not normalize the result. + * The result will be written to a buffer, which might be truncated if the + * buffer is not large enough to hold the full path. However, the truncated + * result will always be null-terminated. The returned value is the amount of + * characters which the resulting path would take if it was not truncated + * (excluding the null-terminating character). + * + * @param path The original path which will get a new root. + * @param new_root The new root which will be placed in the path. + * @param buffer The output buffer where the result is written to. + * @param buffer_size The size of the output buffer where the result is written + * to. + * @return Returns the total amount of characters of the new path. + */ +size_t cwk_path_change_root(const char *path, const char *new_root, + char *buffer, size_t buffer_size); + +/** + * @brief Determine whether the path is absolute or not. + * + * This function checks whether the path is an absolute path or not. A path is + * considered to be absolute if the root ends with a separator. + * + * @param path The path which will be checked. + * @return Returns true if the path is absolute or false otherwise. + */ +bool cwk_path_is_absolute(const char *path); + +/** + * @brief Determine whether the path is relative or not. + * + * This function checks whether the path is a relative path or not. A path is + * considered to be relative if the root does not end with a separator. + * + * @param path The path which will be checked. + * @return Returns true if the path is relative or false otherwise. + */ +bool cwk_path_is_relative(const char *path); + +/** + * @brief Gets the basename of a file path. + * + * This function gets the basename of a file path. A pointer to the beginning of + * the basename will be returned through the basename parameter. This pointer + * will be positioned on the first letter after the separator. The length of the + * file path will be returned through the length parameter. The length will be + * set to zero and the basename to NULL if there is no basename available. + * + * @param path The path which will be inspected. + * @param basename The output of the basename pointer. + * @param length The output of the length of the basename. + */ +void cwk_path_get_basename(const char *path, const char **basename, + size_t *length); + +/** + * @brief Changes the basename of a file path. + * + * This function changes the basename of a file path. This function will not + * write out more than the specified buffer can contain. However, the generated + * string is always null-terminated - even if not the whole path is written out. + * The function returns the total number of characters the complete buffer would + * have, even if it was not written out completely. The path may be the same + * memory address as the buffer. + * + * @param path The original path which will be used for the modified path. + * @param new_basename The new basename which will replace the old one. + * @param buffer The buffer where the changed path will be written to. + * @param buffer_size The size of the result buffer where the changed path is + * written to. + * @return Returns the size which the complete new path would have if it was not + * truncated. + */ +size_t cwk_path_change_basename(const char *path, const char *new_basename, + char *buffer, size_t buffer_size); + +/** + * @brief Gets the dirname of a file path. + * + * This function determines the dirname of a file path and returns the length up + * to which character is considered to be part of it. If no dirname is found, + * the length will be set to zero. The beginning of the dirname is always equal + * to the submitted path pointer. + * + * @param path The path which will be inspected. + * @param length The length of the dirname. + */ +void cwk_path_get_dirname(const char *path, size_t *length); + +/** + * @brief Gets the extension of a file path. + * + * This function extracts the extension portion of a file path. A pointer to + * the beginning of the extension will be returned through the extension + * parameter if an extension is found and true is returned. This pointer will be + * positioned on the dot. The length of the extension name will be returned + * through the length parameter. If no extension is found both parameters won't + * be touched and false will be returned. + * + * @param path The path which will be inspected. + * @param extension The output of the extension pointer. + * @param length The output of the length of the extension. + * @return Returns true if an extension is found or false otherwise. + */ +bool cwk_path_get_extension(const char *path, const char **extension, + size_t *length); + +/** + * @brief Determines whether the file path has an extension. + * + * This function determines whether the submitted file path has an extension. + * This will evaluate to true if the last segment of the path contains a dot. + * + * @param path The path which will be inspected. + * @return Returns true if the path has an extension or false otherwise. + */ +bool cwk_path_has_extension(const char *path); + +/** + * @brief Changes the extension of a file path. + * + * This function changes the extension of a file name. The function will append + * an extension if the basename does not have an extension, or use the extension + * as a basename if the path does not have a basename. This function will not + * write out more than the specified buffer can contain. However, the generated + * string is always null-terminated - even if not the whole path is written out. + * The function returns the total number of characters the complete buffer would + * have, even if it was not written out completely. The path may be the same + * memory address as the buffer. + * + * @param path The path which will be used to make the change. + * @param new_extension The extension which will be placed within the new path. + * @param buffer The output buffer where the result will be written to. + * @param buffer_size The size of the output buffer where the result will be + * written to. + * @return Returns the total size which the output would have if it was not + * truncated. + */ +size_t cwk_path_change_extension(const char *path, const char *new_extension, + char *buffer, size_t buffer_size); + +/** + * @brief Creates a normalized version of the path. + * + * This function creates a normalized version of the path within the specified + * buffer. This function will not write out more than the specified buffer can + * contain. However, the generated string is always null-terminated - even if + * not the whole path is written out. The function returns the total number of + * characters the complete buffer would have, even if it was not written out + * completely. The path may be the same memory address as the buffer. + * + * The following will be true for the normalized path: + * 1) "../" will be resolved. + * 2) "./" will be removed. + * 3) double separators will be fixed with a single separator. + * 4) separator suffixes will be removed. + * + * @param path The path which will be normalized. + * @param buffer The buffer where the new path is written to. + * @param buffer_size The size of the buffer. + * @return The size which the complete normalized path has if it was not + * truncated. + */ +size_t cwk_path_normalize(const char *path, char *buffer, size_t buffer_size); + +/** + * @brief Finds common portions in two paths. + * + * This function finds common portions in two paths and returns the number + * characters from the beginning of the base path which are equal to the other + * path. + * + * @param path_base The base path which will be compared with the other path. + * @param path_other The other path which will compared with the base path. + * @return Returns the number of characters which are common in the base path. + */ +size_t cwk_path_get_intersection(const char *path_base, const char *path_other); + +/** + * @brief Gets the first segment of a path. + * + * This function finds the first segment of a path. The position of the segment + * is set to the first character after the separator, and the length counts all + * characters until the next separator (excluding the separator). + * + * @param path The path which will be inspected. + * @param segment The segment which will be extracted. + * @return Returns true if there is a segment or false if there is none. + */ +bool cwk_path_get_first_segment(const char *path, struct cwk_segment *segment); + +/** + * @brief Gets the last segment of the path. + * + * This function gets the last segment of a path. This function may return false + * if the path doesn't contain any segments, in which case the submitted segment + * parameter is not modified. The position of the segment is set to the first + * character after the separator, and the length counts all characters until the + * end of the path (excluding the separator). + * + * @param path The path which will be inspected. + * @param segment The segment which will be extracted. + * @return Returns true if there is a segment or false if there is none. + */ +bool cwk_path_get_last_segment(const char *path, struct cwk_segment *segment); + +/** + * @brief Advances to the next segment. + * + * This function advances the current segment to the next segment. If there are + * no more segments left, the submitted segment structure will stay unchanged + * and false is returned. + * + * @param segment The current segment which will be advanced to the next one. + * @return Returns true if another segment was found or false otherwise. + */ +bool cwk_path_get_next_segment(struct cwk_segment *segment); + +/** + * @brief Moves to the previous segment. + * + * This function moves the current segment to the previous segment. If the + * current segment is the first one, the submitted segment structure will stay + * unchanged and false is returned. + * + * @param segment The current segment which will be moved to the previous one. + * @return Returns true if there is a segment before this one or false + * otherwise. + */ +bool cwk_path_get_previous_segment(struct cwk_segment *segment); + +/** + * @brief Gets the type of the submitted path segment. + * + * This function inspects the contents of the segment and determines the type of + * it. Currently, there are three types CWK_NORMAL, CWK_CURRENT and CWK_BACK. A + * CWK_NORMAL segment is a normal folder or file entry. A CWK_CURRENT is a "./" + * and a CWK_BACK a "../" segment. + * + * @param segment The segment which will be inspected. + * @return Returns the type of the segment. + */ +enum cwk_segment_type cwk_path_get_segment_type( + const struct cwk_segment *segment); + +/** + * @brief Changes the content of a segment. + * + * This function overrides the content of a segment to the submitted value and + * outputs the whole new path to the submitted buffer. The result might require + * less or more space than before if the new value length differs from the + * original length. The output is truncated if the new path is larger than the + * submitted buffer size, but it is always null-terminated. The source of the + * segment and the submitted buffer may be the same. + * + * @param segment The segment which will be modifier. + * @param value The new content of the segment. + * @param buffer The buffer where the modified path will be written to. + * @param buffer_size The size of the output buffer. + * @return Returns the total size which would have been written if the output + * was not truncated. + */ +size_t cwk_path_change_segment(struct cwk_segment *segment, const char *value, + char *buffer, size_t buffer_size); + +/** + * @brief Checks whether the submitted pointer points to a separator. + * + * This function simply checks whether the submitted pointer points to a + * separator, which has to be null-terminated (but not necessarily after the + * separator). The function will return true if it is a separator, or false + * otherwise. + * + * @param symbol A pointer to a string. + * @return Returns true if it is a separator, or false otherwise. + */ +bool cwk_path_is_separator(const char *str); + +/** + * @brief Guesses the path style. + * + * This function guesses the path style based on a submitted path-string. The + * guessing will look at the root and the type of slashes contained in the path + * and return the style which is more likely used in the path. + * + * @param path The path which will be inspected. + * @return Returns the style which is most likely used for the path. + */ +enum cwk_path_style cwk_path_guess_style(const char *path); + +/** + * @brief Configures which path style is used. + * + * This function configures which path style is used. The following styles are + * currently supported. + * + * CWK_STYLE_WINDOWS: Use backslashes as a separator and volume for the root. + * CWK_STYLE_UNIX: Use slashes as a separator and a slash for the root. + * + * @param style The style which will be used from now on. + */ +void cwk_path_set_style(enum cwk_path_style style); + +/** + * @brief Gets the path style configuration. + * + * This function gets the style configuration which is currently used for the + * paths. This configuration determines how paths are parsed and generated. + * + * @return Returns the current path style configuration. + */ +enum cwk_path_style cwk_path_get_style(void); + +#endif diff --git a/src/minivhd/libxml2_encoding.c b/src/minivhd/libxml2_encoding.c new file mode 100644 index 0000000..cb881a8 --- /dev/null +++ b/src/minivhd/libxml2_encoding.c @@ -0,0 +1,447 @@ +/* + * encoding.c : implements the encoding conversion functions needed for XML + * + * Related specs: + * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies + * rfc2781 UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau + * [ISO-10646] UTF-8 and UTF-16 in Annexes + * [ISO-8859-1] ISO Latin-1 characters codes. + * [UNICODE] The Unicode Consortium, "The Unicode Standard -- + * Worldwide Character Encoding -- Version 1.0", Addison- + * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is + * described in Unicode Technical Report #4. + * [US-ASCII] Coded Character Set--7-bit American Standard Code for + * Information Interchange, ANSI X3.4-1986. + * + * See Copyright for the status of this software. + * + * daniel@veillard.com + * + * Original code for IsoLatin1 and UTF-16 by "Martin J. Duerst" + * + * Adapted and abridged for MiniVHD by Sherman Perry + */ +#include + +static int xmlLittleEndian = 1; + +/* Note: extracted from original 'void xmlInitCharEncodingHandlers(void)' function */ +void xmlEncodingInit(void) +{ + unsigned short int tst = 0x1234; + unsigned char *ptr = (unsigned char *) &tst; + + if (*ptr == 0x12) xmlLittleEndian = 0; + else if (*ptr == 0x34) xmlLittleEndian = 1; +} + +/** + * UTF16LEToUTF8: + * @out: a pointer to an array of bytes to store the result + * @outlen: the length of @out + * @inb: a pointer to an array of UTF-16LE passwd as a byte array + * @inlenb: the length of @in in UTF-16LE chars + * + * Take a block of UTF-16LE ushorts in and try to convert it to an UTF-8 + * block of chars out. This function assumes the endian property + * is the same between the native type of this machine and the + * inputed one. + * + * Returns the number of bytes written, or -1 if lack of space, or -2 + * if the transcoding fails (if *in is not a valid utf16 string) + * The value of *inlen after return is the number of octets consumed + * if the return value is positive, else unpredictable. + */ +int UTF16LEToUTF8(unsigned char* out, int *outlen, + const unsigned char* inb, int *inlenb) +{ + unsigned char* outstart = out; + const unsigned char* processed = inb; + unsigned char* outend = out + *outlen; + unsigned short* in = (unsigned short*) inb; + unsigned short* inend; + unsigned int c, d, inlen; + unsigned char *tmp; + int bits; + + if ((*inlenb % 2) == 1) + (*inlenb)--; + inlen = *inlenb / 2; + inend = in + inlen; + while ((in < inend) && (out - outstart + 5 < *outlen)) { + if (xmlLittleEndian) { + c= *in++; + } else { + tmp = (unsigned char *) in; + c = *tmp++; + c = c | (((unsigned int)*tmp) << 8); + in++; + } + if ((c & 0xFC00) == 0xD800) { /* surrogates */ + if (in >= inend) { /* (in > inend) shouldn't happens */ + break; + } + if (xmlLittleEndian) { + d = *in++; + } else { + tmp = (unsigned char *) in; + d = *tmp++; + d = d | (((unsigned int)*tmp) << 8); + in++; + } + if ((d & 0xFC00) == 0xDC00) { + c &= 0x03FF; + c <<= 10; + c |= d & 0x03FF; + c += 0x10000; + } + else { + *outlen = out - outstart; + *inlenb = processed - inb; + return(-2); + } + } + + /* assertion: c is a single UTF-4 value */ + if (out >= outend) + break; + if (c < 0x80) { *out++= c; bits= -6; } + else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; } + else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; } + else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; } + + for ( ; bits >= 0; bits-= 6) { + if (out >= outend) + break; + *out++= ((c >> bits) & 0x3F) | 0x80; + } + processed = (const unsigned char*) in; + } + *outlen = out - outstart; + *inlenb = processed - inb; + return(*outlen); +} + +/** + * UTF8ToUTF16LE: + * @outb: a pointer to an array of bytes to store the result + * @outlen: the length of @outb + * @in: a pointer to an array of UTF-8 chars + * @inlen: the length of @in + * + * Take a block of UTF-8 chars in and try to convert it to an UTF-16LE + * block of chars out. + * + * Returns the number of bytes written, or -1 if lack of space, or -2 + * if the transcoding failed. + */ +int UTF8ToUTF16LE(unsigned char* outb, int *outlen, + const unsigned char* in, int *inlen) +{ + unsigned short* out = (unsigned short*) outb; + const unsigned char* processed = in; + const unsigned char *const instart = in; + unsigned short* outstart= out; + unsigned short* outend; + const unsigned char* inend; + unsigned int c, d; + int trailing; + unsigned char *tmp; + unsigned short tmp1, tmp2; + + /* UTF16LE encoding has no BOM */ + if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1); + if (in == NULL) { + *outlen = 0; + *inlen = 0; + return(0); + } + inend= in + *inlen; + outend = out + (*outlen / 2); + while (in < inend) { + d= *in++; + if (d < 0x80) { c= d; trailing= 0; } + else if (d < 0xC0) { + /* trailing byte in leading position */ + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return(-2); + } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; } + else if (d < 0xF0) { c= d & 0x0F; trailing= 2; } + else if (d < 0xF8) { c= d & 0x07; trailing= 3; } + else { + /* no chance for this in UTF-16 */ + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return(-2); + } + + if (inend - in < trailing) { + break; + } + + for ( ; trailing; trailing--) { + if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80)) + break; + c <<= 6; + c |= d & 0x3F; + } + + /* assertion: c is a single UTF-4 value */ + if (c < 0x10000) { + if (out >= outend) + break; + if (xmlLittleEndian) { + *out++ = c; + } else { + tmp = (unsigned char *) out; + *tmp = c ; + *(tmp + 1) = c >> 8 ; + out++; + } + } + else if (c < 0x110000) { + if (out+1 >= outend) + break; + c -= 0x10000; + if (xmlLittleEndian) { + *out++ = 0xD800 | (c >> 10); + *out++ = 0xDC00 | (c & 0x03FF); + } else { + tmp1 = 0xD800 | (c >> 10); + tmp = (unsigned char *) out; + *tmp = (unsigned char) tmp1; + *(tmp + 1) = tmp1 >> 8; + out++; + + tmp2 = 0xDC00 | (c & 0x03FF); + tmp = (unsigned char *) out; + *tmp = (unsigned char) tmp2; + *(tmp + 1) = tmp2 >> 8; + out++; + } + } + else + break; + processed = in; + } + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return(*outlen); +} + +/** + * UTF16BEToUTF8: + * @out: a pointer to an array of bytes to store the result + * @outlen: the length of @out + * @inb: a pointer to an array of UTF-16 passed as a byte array + * @inlenb: the length of @in in UTF-16 chars + * + * Take a block of UTF-16 ushorts in and try to convert it to an UTF-8 + * block of chars out. This function assumes the endian property + * is the same between the native type of this machine and the + * inputed one. + * + * Returns the number of bytes written, or -1 if lack of space, or -2 + * if the transcoding fails (if *in is not a valid utf16 string) + * The value of *inlen after return is the number of octets consumed + * if the return value is positive, else unpredictable. + */ +int UTF16BEToUTF8(unsigned char* out, int *outlen, + const unsigned char* inb, int *inlenb) +{ + unsigned char* outstart = out; + const unsigned char* processed = inb; + unsigned char* outend = out + *outlen; + unsigned short* in = (unsigned short*) inb; + unsigned short* inend; + unsigned int c, d, inlen; + unsigned char *tmp; + int bits; + + if ((*inlenb % 2) == 1) + (*inlenb)--; + inlen = *inlenb / 2; + inend= in + inlen; + while (in < inend) { + if (xmlLittleEndian) { + tmp = (unsigned char *) in; + c = *tmp++; + c = c << 8; + c = c | (unsigned int) *tmp; + in++; + } else { + c= *in++; + } + if ((c & 0xFC00) == 0xD800) { /* surrogates */ + if (in >= inend) { /* (in > inend) shouldn't happens */ + *outlen = out - outstart; + *inlenb = processed - inb; + return(-2); + } + if (xmlLittleEndian) { + tmp = (unsigned char *) in; + d = *tmp++; + d = d << 8; + d = d | (unsigned int) *tmp; + in++; + } else { + d= *in++; + } + if ((d & 0xFC00) == 0xDC00) { + c &= 0x03FF; + c <<= 10; + c |= d & 0x03FF; + c += 0x10000; + } + else { + *outlen = out - outstart; + *inlenb = processed - inb; + return(-2); + } + } + + /* assertion: c is a single UTF-4 value */ + if (out >= outend) + break; + if (c < 0x80) { *out++= c; bits= -6; } + else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; } + else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; } + else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; } + + for ( ; bits >= 0; bits-= 6) { + if (out >= outend) + break; + *out++= ((c >> bits) & 0x3F) | 0x80; + } + processed = (const unsigned char*) in; + } + *outlen = out - outstart; + *inlenb = processed - inb; + return(*outlen); +} + +/** + * UTF8ToUTF16BE: + * @outb: a pointer to an array of bytes to store the result + * @outlen: the length of @outb + * @in: a pointer to an array of UTF-8 chars + * @inlen: the length of @in + * + * Take a block of UTF-8 chars in and try to convert it to an UTF-16BE + * block of chars out. + * + * Returns the number of byte written, or -1 by lack of space, or -2 + * if the transcoding failed. + */ +int UTF8ToUTF16BE(unsigned char* outb, int *outlen, + const unsigned char* in, int *inlen) +{ + unsigned short* out = (unsigned short*) outb; + const unsigned char* processed = in; + const unsigned char *const instart = in; + unsigned short* outstart= out; + unsigned short* outend; + const unsigned char* inend; + unsigned int c, d; + int trailing; + unsigned char *tmp; + unsigned short tmp1, tmp2; + + /* UTF-16BE has no BOM */ + if ((outb == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1); + if (in == NULL) { + *outlen = 0; + *inlen = 0; + return(0); + } + inend= in + *inlen; + outend = out + (*outlen / 2); + while (in < inend) { + d= *in++; + if (d < 0x80) { c= d; trailing= 0; } + else if (d < 0xC0) { + /* trailing byte in leading position */ + *outlen = out - outstart; + *inlen = processed - instart; + return(-2); + } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; } + else if (d < 0xF0) { c= d & 0x0F; trailing= 2; } + else if (d < 0xF8) { c= d & 0x07; trailing= 3; } + else { + /* no chance for this in UTF-16 */ + *outlen = out - outstart; + *inlen = processed - instart; + return(-2); + } + + if (inend - in < trailing) { + break; + } + + for ( ; trailing; trailing--) { + if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80)) break; + c <<= 6; + c |= d & 0x3F; + } + + /* assertion: c is a single UTF-4 value */ + if (c < 0x10000) { + if (out >= outend) break; + if (xmlLittleEndian) { + tmp = (unsigned char *) out; + *tmp = c >> 8; + *(tmp + 1) = c; + out++; + } else { + *out++ = c; + } + } + else if (c < 0x110000) { + if (out+1 >= outend) break; + c -= 0x10000; + if (xmlLittleEndian) { + tmp1 = 0xD800 | (c >> 10); + tmp = (unsigned char *) out; + *tmp = tmp1 >> 8; + *(tmp + 1) = (unsigned char) tmp1; + out++; + + tmp2 = 0xDC00 | (c & 0x03FF); + tmp = (unsigned char *) out; + *tmp = tmp2 >> 8; + *(tmp + 1) = (unsigned char) tmp2; + out++; + } else { + *out++ = 0xD800 | (c >> 10); + *out++ = 0xDC00 | (c & 0x03FF); + } + } + else + break; + processed = in; + } + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return(*outlen); +} + +/* This file is licenced under the MIT licence as follows: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is fur- +nished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ \ No newline at end of file diff --git a/src/minivhd/libxml2_encoding.h b/src/minivhd/libxml2_encoding.h new file mode 100644 index 0000000..831aea4 --- /dev/null +++ b/src/minivhd/libxml2_encoding.h @@ -0,0 +1,12 @@ +#ifndef LIBXML2_ENCODING_H +#define LIBXML2_ENCODING_H + +#include +typedef uint16_t mvhd_utf16; + +void xmlEncodingInit(void); +int UTF16LEToUTF8(unsigned char* out, int *outlen, const unsigned char* inb, int *inlenb); +int UTF8ToUTF16LE(unsigned char* outb, int *outlen, const unsigned char* in, int *inlen); +int UTF16BEToUTF8(unsigned char* out, int *outlen, const unsigned char* inb, int *inlenb); +int UTF8ToUTF16BE(unsigned char* outb, int *outlen, const unsigned char* in, int *inlen); +#endif \ No newline at end of file diff --git a/src/minivhd/minivhd.h b/src/minivhd/minivhd.h new file mode 100644 index 0000000..0d925f7 --- /dev/null +++ b/src/minivhd/minivhd.h @@ -0,0 +1,269 @@ +#ifndef MINIVHD_H +#define MINIVHD_H + +#include +#include +#include + +extern int mvhd_errno; + +typedef enum MVHDError { + MVHD_ERR_MEM = -128, + MVHD_ERR_FILE, + MVHD_ERR_NOT_VHD, + MVHD_ERR_TYPE, + MVHD_ERR_FOOTER_CHECKSUM, + MVHD_ERR_SPARSE_CHECKSUM, + MVHD_ERR_UTF_TRANSCODING_FAILED, + MVHD_ERR_UTF_SIZE, + MVHD_ERR_PATH_REL, + MVHD_ERR_PATH_LEN, + MVHD_ERR_PAR_NOT_FOUND, + MVHD_ERR_INVALID_PAR_UUID, + MVHD_ERR_INVALID_GEOM, + MVHD_ERR_INVALID_SIZE, + MVHD_ERR_INVALID_BLOCK_SIZE, + MVHD_ERR_INVALID_PARAMS, + MVHD_ERR_CONV_SIZE, + MVHD_ERR_TIMESTAMP +} MVHDError; + +typedef enum MVHDType { + MVHD_TYPE_FIXED = 2, + MVHD_TYPE_DYNAMIC = 3, + MVHD_TYPE_DIFF = 4 +} MVHDType; + +typedef enum MVHDBlockSize { + MVHD_BLOCK_DEFAULT = 0, /**< 2 MB blocks */ + MVHD_BLOCK_SMALL = 1024, /**< 512 KB blocks */ + MVHD_BLOCK_LARGE = 4096 /**< 2 MB blocks */ +} MVHDBlockSize; + +typedef struct MVHDGeom { + uint16_t cyl; + uint8_t heads; + uint8_t spt; +} MVHDGeom; + +typedef void (*mvhd_progress_callback)(uint32_t current_sector, uint32_t total_sectors); + +typedef struct MVHDCreationOptions { + int type; /** MVHD_TYPE_FIXED, MVHD_TYPE_DYNAMIC, or MVHD_TYPE_DIFF */ + char* path; /** Absolute path of the new VHD file */ + char* parent_path; /** For MVHD_TYPE_DIFF, this is the absolute path of the VHD's parent. For non-diff VHDs, this should be NULL. */ + uint64_t size_in_bytes; /** Total size of the VHD's virtual disk in bytes. Must be a multiple of 512. If 0, the size is auto-calculated from the geometry field. Ignored for MVHD_TYPE_DIFF. */ + MVHDGeom geometry; /** The geometry of the VHD. If set to 0, the geometry is auto-calculated from the size_in_bytes field. */ + uint32_t block_size_in_sectors; /** MVHD_BLOCK_LARGE or MVHD_BLOCK_SMALL, or 0 for the default value. The number of sectors per block. */ + mvhd_progress_callback progress_callback; /** Optional; if not NULL, gets called to indicate progress on the creation operation. Only applies to MVHD_TYPE_FIXED. */ +} MVHDCreationOptions; + +typedef struct MVHDMeta MVHDMeta; + +/** + * \brief Output a string from a MiniVHD error number + * + * \param [in] err is the error number to return string from + * + * \return Error string + */ +const char* mvhd_strerr(MVHDError err); + +/** + * \brief A simple test to see if a given file is a VHD + * + * \param [in] f file to test + * + * \retval true if f is a VHD + * \retval false if f is not a VHD + */ +bool mvhd_file_is_vhd(FILE* f); + +/** + * \brief Open a VHD image for reading and/or writing + * + * The returned pointer contains all required values and structures (and files) to + * read and write to a VHD file. + * + * Remember to call mvhd_close() when you are finished. + * + * \param [in] Absolute path to VHD file. Relative path will cause issues when opening + * a differencing VHD file + * \param [in] readonly set this to true to open the VHD in a read only manner + * \param [out] err will be set if the VHD fails to open. Value could be one of + * MVHD_ERR_MEM, MVHD_ERR_FILE, MVHD_ERR_NOT_VHD, MVHD_ERR_FOOTER_CHECKSUM, MVHD_ERR_SPARSE_CHECKSUM, + * MVHD_ERR_TYPE, MVHD_ERR_TIMESTAMP + * If MVHD_ERR_FILE is set, mvhd_errno will be set to the appropriate system errno value + * + * \return MVHDMeta pointer. If NULL, check err. err may also be set to MVHD_ERR_TIMESTAMP if + * opening a differencing VHD. + */ +MVHDMeta* mvhd_open(const char* path, bool readonly, int* err); + +/** + * \brief Update the parent modified timestamp in the VHD file + * + * Differencing VHD's use a parent last modified timestamp to try and detect if the + * parent has been modified after the child has been created. However, this is rather + * fragile and can be broken by moving/copying the parent. Also, MS DiskPart does not + * set this timestamp in the child :( + * + * Be careful when using this function that you don't update the timestamp after the + * parent actually has been modified. + * + * \param [in] vhdm Differencing VHD to update. + * \param [out] err will be set if the timestamp could not be updated + * + * \return non-zero on error, 0 on success + */ +int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err); + +/** + * \brief Create a fixed VHD image + * + * \param [in] path is the absolute path to the image to create + * \param [in] geom is the HDD geometry of the image to create. Determines final image size + * \param [out] err indicates what error occurred, if any + * \param [out] progress_callback optional; if not NULL, gets called to indicate progress on the creation operation + * + * \retval NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_progress_callback progress_callback); + +/** + * \brief Create sparse (dynamic) VHD image. + * + * \param [in] path is the absolute path to the VHD file to create + * \param [in] geom is the HDD geometry of the image to create. Determines final image size + * \param [out] err indicates what error occurred, if any + * + * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +MVHDMeta* mvhd_create_sparse(const char* path, MVHDGeom geom, int* err); + +/** + * \brief Create differencing VHD imagee. + * + * \param [in] path is the absolute path to the VHD file to create + * \param [in] par_path is the absolute path to a parent image. If NULL, a sparse image is created, otherwise create a differencing image + * \param [out] err indicates what error occurred, if any + * + * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +MVHDMeta* mvhd_create_diff(const char* path, const char* par_path, int* err); + +/** + * \brief Create a VHD using the provided options + * + * Use mvhd_create_ex if you want more control over the VHD's options. For quick creation, you can use mvhd_create_fixed, mvhd_create_sparse, or mvhd_create_diff. + * + * \param [in] options the VHD creation options. + * \param [out] err indicates what error occurred, if any + * + * \retval NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +MVHDMeta* mvhd_create_ex(MVHDCreationOptions options, int* err); + +/** + * \brief Safely close a VHD image + * + * \param [in] vhdm MiniVHD data structure to close + */ +void mvhd_close(MVHDMeta* vhdm); + +/** + * \brief Calculate hard disk geometry from a provided size + * + * The VHD format uses Cylinder, Heads, Sectors per Track (CHS) when accessing the disk. + * The size of the disk can be determined from C * H * S * sector_size. + * + * Note, maximum geometry size (in bytes) is 65535 * 16 * 255 * 512, which is 127GB. + * However, the maximum VHD size is 2040GB. For VHDs larger than 127GB, the geometry size will be + * smaller than the actual VHD size. + * + * This function determines the appropriate CHS geometry from a provided size in bytes. + * The calculations used are those provided in "Appendix: CHS Calculation" from the document + * "Virtual Hard Disk Image Format Specification" provided by Microsoft. + * + * \param [in] size the desired VHD image size, in bytes + * + * \return MVHDGeom the calculated geometry. This can be used in the appropriate create functions. + */ +MVHDGeom mvhd_calculate_geometry(uint64_t size); + +/** + * \brief Convert a raw disk image to a fixed VHD image + * + * \param [in] utf8_raw_path is the path of the raw image to convert + * \param [in] utf8_vhd_path is the path of the VHD to create + * \param [out] err indicates what error occurred, if any + * + * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +MVHDMeta* mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_vhd_path, int* err); + +/** + * \brief Convert a raw disk image to a sparse VHD image + * + * \param [in] utf8_raw_path is the path of the raw image to convert + * \param [in] utf8_vhd_path is the path of the VHD to create + * \param [out] err indicates what error occurred, if any + * + * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8_vhd_path, int* err); + +/** + * \brief Convert a VHD image to a raw disk image + * + * \param [in] utf8_vhd_path is the path of the VHD to convert + * \param [in] utf8_raw_path is the path of the raw image to create + * \param [out] err indicates what error occurred, if any + * + * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns the raw disk image FILE pointer + */ +FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, int *err); + +/** + * \brief Read sectors from VHD file + * + * Read num_sectors, beginning at offset from the VHD file into a buffer + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset the sector offset from which to start reading from + * \param [in] num_sectors the number of sectors to read + * \param [out] out_buff the buffer to write sector data to + * + * \return the number of sectors that were not read, or zero + */ +int mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Write sectors to VHD file + * + * Write num_sectors, beginning at offset from a buffer VHD file into the VHD file + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset the sector offset from which to start writing to + * \param [in] num_sectors the number of sectors to write + * \param [in] in_buffer the buffer to write sector data to + * + * \return the number of sectors that were not written, or zero + */ +int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +/** + * \brief Write zeroed sectors to VHD file + * + * Write num_sectors, beginning at offset, of zero data into the VHD file. + * We reuse the existing write functions, with a preallocated zero buffer as + * our source buffer. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset the sector offset from which to start writing to + * \param [in] num_sectors the number of sectors to write + * + * \return the number of sectors that were not written, or zero + */ +int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors); +#endif \ No newline at end of file diff --git a/src/minivhd/minivhd_convert.c b/src/minivhd/minivhd_convert.c new file mode 100644 index 0000000..231e0f9 --- /dev/null +++ b/src/minivhd/minivhd_convert.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include "minivhd_create.h" +#include "minivhd_internal.h" +#include "minivhd_util.h" +#include "minivhd.h" + +static FILE* mvhd_open_existing_raw_img(const char* utf8_raw_path, MVHDGeom* geom, int* err); + +static FILE* mvhd_open_existing_raw_img(const char* utf8_raw_path, MVHDGeom* geom, int* err) { + FILE *raw_img = mvhd_fopen(utf8_raw_path, "rb", err); + if (raw_img == NULL) { + *err = MVHD_ERR_FILE; + return NULL; + } + if (geom == NULL) { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } + mvhd_fseeko64(raw_img, 0, SEEK_END); + uint64_t size_bytes = (uint64_t)mvhd_ftello64(raw_img); + MVHDGeom new_geom = mvhd_calculate_geometry(size_bytes); + if (mvhd_calc_size_bytes(&new_geom) != size_bytes) { + *err = MVHD_ERR_CONV_SIZE; + return NULL; + } + geom->cyl = new_geom.cyl; + geom->heads = new_geom.heads; + geom->spt = new_geom.spt; + mvhd_fseeko64(raw_img, 0, SEEK_SET); + return raw_img; +} + +MVHDMeta* mvhd_convert_to_vhd_fixed(const char* utf8_raw_path, const char* utf8_vhd_path, int* err) { + MVHDGeom geom; + FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); + if (raw_img == NULL) { + return NULL; + } + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + MVHDMeta *vhdm = mvhd_create_fixed_raw(utf8_vhd_path, raw_img, size_in_bytes, &geom, err, NULL); + if (vhdm == NULL) { + return NULL; + } + return vhdm; +} +MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8_vhd_path, int* err) { + MVHDGeom geom; + MVHDMeta *vhdm = NULL; + FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); + if (raw_img == NULL) { + return NULL; + } + vhdm = mvhd_create_sparse(utf8_vhd_path, geom, err); + if (vhdm == NULL) { + goto end; + } + uint8_t buff[4096] = {0}; // 8 sectors + uint8_t empty_buff[4096] = {0}; + int total_sectors = mvhd_calc_size_sectors(&geom); + int copy_sect = 0; + for (int i = 0; i < total_sectors; i += 8) { + copy_sect = 8; + if ((i + 8) >= total_sectors) { + copy_sect = total_sectors - i; + memset(buff, 0, sizeof buff); + } + fread(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); + /* Only write data if there's data to write, to take advantage of the sparse VHD format */ + if (memcmp(buff, empty_buff, sizeof buff) != 0) { + mvhd_write_sectors(vhdm, i, copy_sect, buff); + } + } +end: + fclose(raw_img); + return vhdm; +} +FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, int *err) { + FILE *raw_img = mvhd_fopen(utf8_raw_path, "wb", err); + if (raw_img == NULL) { + return NULL; + } + MVHDMeta *vhdm = mvhd_open(utf8_vhd_path, true, err); + if (vhdm == NULL) { + fclose(raw_img); + return NULL; + } + uint8_t buff[4096] = {0}; // 8 sectors + int total_sectors = mvhd_calc_size_sectors((MVHDGeom*)&vhdm->footer.geom); + int copy_sect = 0; + for (int i = 0; i < total_sectors; i += 8) { + copy_sect = 8; + if ((i + 8) >= total_sectors) { + copy_sect = total_sectors - i; + } + mvhd_read_sectors(vhdm, i, copy_sect, buff); + fwrite(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); + } + mvhd_close(vhdm); + mvhd_fseeko64(raw_img, 0, SEEK_SET); + return raw_img; +} \ No newline at end of file diff --git a/src/minivhd/minivhd_create.c b/src/minivhd/minivhd_create.c new file mode 100644 index 0000000..e1bf916 --- /dev/null +++ b/src/minivhd/minivhd_create.c @@ -0,0 +1,482 @@ +#include +#include +#include +#include +#include +#include "cwalk.h" +#include "libxml2_encoding.h" +#include "minivhd_internal.h" +#include "minivhd_util.h" +#include "minivhd_struct_rw.h" +#include "minivhd_io.h" +#include "minivhd_create.h" +#include "minivhd.h" + +static void mvhd_gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType type, uint64_t sparse_header_off); +static void mvhd_gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors); +static int mvhd_gen_par_loc(MVHDSparseHeader* header, + const char* child_path, + const char* par_path, + uint64_t start_offset, + mvhd_utf16* w2ku_path_buff, + mvhd_utf16* w2ru_path_buff, + MVHDError* err); +static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_bytes, MVHDGeom* geom, uint32_t block_size_in_sectors, int* err); + +/** + * \brief Populate a VHD footer + * + * \param [in] footer to populate + * \param [in] size_in_bytes is the total size of the virtual hard disk in bytes + * \param [in] geom to use + * \param [in] type of HVD that is being created + * \param [in] sparse_header_off, an absolute file offset to the sparse header. Not used for fixed VHD images + */ +static void mvhd_gen_footer(MVHDFooter* footer, uint64_t size_in_bytes, MVHDGeom* geom, MVHDType type, uint64_t sparse_header_off) { + memcpy(footer->cookie, "conectix", sizeof footer->cookie); + footer->features = 0x00000002; + footer->fi_fmt_vers = 0x00010000; + footer->data_offset = (type == MVHD_TYPE_DIFF || type == MVHD_TYPE_DYNAMIC) ? sparse_header_off : 0xffffffffffffffff; + footer->timestamp = vhd_calc_timestamp(); + memcpy(footer->cr_app, "mvhd", sizeof footer->cr_app); + footer->cr_vers = 0x000e0000; + memcpy(footer->cr_host_os, "Wi2k", sizeof footer->cr_host_os); + footer->orig_sz = footer->curr_sz = size_in_bytes; + footer->geom.cyl = geom->cyl; + footer->geom.heads = geom->heads; + footer->geom.spt = geom->spt; + footer->disk_type = type; + mvhd_generate_uuid(footer->uuid); + footer->checksum = mvhd_gen_footer_checksum(footer); +} + +/** + * \brief Populate a VHD sparse header + * + * \param [in] header for sparse and differencing images + * \param [in] num_blks is the number of data blocks that the image contains + * \param [in] bat_offset is the absolute file offset for start of the Block Allocation Table + * \param [in] block_size_in_sectors is the block size in sectors. + */ +static void mvhd_gen_sparse_header(MVHDSparseHeader* header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors) { + memcpy(header->cookie, "cxsparse", sizeof header->cookie); + header->data_offset = 0xffffffffffffffff; + header->bat_offset = bat_offset; + header->head_vers = 0x00010000; + header->max_bat_ent = num_blks; + header->block_sz = block_size_in_sectors * (uint32_t)MVHD_SECTOR_SIZE; + header->checksum = mvhd_gen_sparse_checksum(header); +} + +/** + * \brief Generate parent locators for differencing VHD images + * + * \param [in] header the sparse header to populate with parent locator entries + * \param [in] child_path is the full path to the VHD being created + * \param [in] par_path is the full path to the parent image + * \param [in] start_offset is the absolute file offset from where to start storing the entries themselves. Must be sector aligned. + * \param [out] w2ku_path_buff is a buffer containing the full path to the parent, encoded as UTF16-LE + * \param [out] w2ru_path_buff is a buffer containing the relative path to the parent, encoded as UTF16-LE + * \param [out] err indicates what error occurred, if any + * + * \retval 0 if success + * \retval < 0 if an error occurrs. Check value of *err for actual error + */ +static int mvhd_gen_par_loc(MVHDSparseHeader* header, + const char* child_path, + const char* par_path, + uint64_t start_offset, + mvhd_utf16* w2ku_path_buff, + mvhd_utf16* w2ru_path_buff, + MVHDError* err) { + /* Get our paths to store in the differencing VHD. We want both the absolute path to the parent, + as well as the relative path from the child VHD */ + int rv = 0; + char* par_filename; + size_t par_fn_len; + char rel_path[MVHD_MAX_PATH_BYTES] = {0}; + char child_dir[MVHD_MAX_PATH_BYTES] = {0}; + size_t child_dir_len; + if (strlen(child_path) < sizeof child_dir) { + strcpy_s(child_dir, MVHD_MAX_PATH_BYTES, child_path); + } else { + *err = MVHD_ERR_PATH_LEN; + rv = -1; + goto end; + } + cwk_path_get_basename(par_path, (const char**)&par_filename, &par_fn_len); + cwk_path_get_dirname(child_dir, &child_dir_len); + child_dir[child_dir_len] = '\0'; + size_t rel_len = cwk_path_get_relative(child_dir, par_path, rel_path, sizeof rel_path); + if (rel_len > sizeof rel_path) { + *err = MVHD_ERR_PATH_LEN; + rv = -1; + goto end; + } + /* We have our paths, now store the parent filename directly in the sparse header. */ + int outlen = sizeof header->par_utf16_name; + int utf_ret; + utf_ret = UTF8ToUTF16BE((unsigned char*)header->par_utf16_name, &outlen, (const unsigned char*)par_filename, (int*)&par_fn_len); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, (int*)err); + rv = -1; + goto end; + } + + /* And encode the paths to UTF16-LE */ + size_t par_path_len = strlen(par_path); + outlen = sizeof *w2ku_path_buff * MVHD_MAX_PATH_CHARS; + utf_ret = UTF8ToUTF16LE((unsigned char*)w2ku_path_buff, &outlen, (const unsigned char*)par_path, (int*)&par_path_len); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, (int*)err); + rv = -1; + goto end; + } + int w2ku_len = utf_ret; + outlen = sizeof *w2ru_path_buff * MVHD_MAX_PATH_CHARS; + utf_ret = UTF8ToUTF16LE((unsigned char*)w2ru_path_buff, &outlen, (const unsigned char*)rel_path, (int*)&rel_len); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, (int*)err); + rv = -1; + goto end; + } + int w2ru_len = utf_ret; + /** + * Finally populate the parent locaters in the sparse header. + * This is the information needed to find the paths saved elsewhere + * in the VHD image + */ + + /* Note about the plat_data_space field: The VHD spec says this field stores the number of sectors needed to store the locator path. + * However, Hyper-V and VPC store the number of bytes, not the number of sectors, and will refuse to open VHDs which have the + * number of sectors in this field. + * See https://stackoverflow.com/questions/40760181/mistake-in-virtual-hard-disk-image-format-specification + */ + header->par_loc_entry[0].plat_code = MVHD_DIF_LOC_W2KU; + header->par_loc_entry[0].plat_data_len = (uint32_t)w2ku_len; + header->par_loc_entry[0].plat_data_offset = (uint64_t)start_offset; + header->par_loc_entry[0].plat_data_space = ((header->par_loc_entry[0].plat_data_len / MVHD_SECTOR_SIZE) + 1) * MVHD_SECTOR_SIZE; + header->par_loc_entry[1].plat_code = MVHD_DIF_LOC_W2RU; + header->par_loc_entry[1].plat_data_len = (uint32_t)w2ru_len; + header->par_loc_entry[1].plat_data_offset = (uint64_t)start_offset + ((uint64_t)header->par_loc_entry[0].plat_data_space); + header->par_loc_entry[1].plat_data_space = ((header->par_loc_entry[1].plat_data_len / MVHD_SECTOR_SIZE) + 1) * MVHD_SECTOR_SIZE; + goto end; + +end: + return rv; +} + +MVHDMeta* mvhd_create_fixed(const char* path, MVHDGeom geom, int* err, mvhd_progress_callback progress_callback) { + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + return mvhd_create_fixed_raw(path, NULL, size_in_bytes, &geom, err, progress_callback); +} + +/** + * \brief internal function that implements public mvhd_create_fixed() functionality + * + * Contains one more parameter than the public function, to allow using an existing + * raw disk image as the data source for the new fixed VHD. + * + * \param [in] raw_image file handle to a raw disk image to populate VHD + */ +MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback) { + uint8_t img_data[MVHD_SECTOR_SIZE] = {0}; + uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; + MVHDMeta* vhdm = calloc(1, sizeof *vhdm); + if (vhdm == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { + *err = MVHD_ERR_INVALID_GEOM; + goto cleanup_vhdm; + } + FILE* f = mvhd_fopen(path, "wb+", err); + if (f == NULL) { + goto cleanup_vhdm; + } + mvhd_fseeko64(f, 0, SEEK_SET); + uint32_t size_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); + uint32_t s; + if (progress_callback) + progress_callback(0, size_sectors); + if (raw_img != NULL) { + mvhd_fseeko64(raw_img, 0, SEEK_END); + uint64_t raw_size = (uint64_t)mvhd_ftello64(raw_img); + MVHDGeom raw_geom = mvhd_calculate_geometry(raw_size); + if (mvhd_calc_size_bytes(&raw_geom) != raw_size) { + *err = MVHD_ERR_CONV_SIZE; + goto cleanup_vhdm; + } + mvhd_gen_footer(&vhdm->footer, raw_size, geom, MVHD_TYPE_FIXED, 0); + mvhd_fseeko64(raw_img, 0, SEEK_SET); + for (s = 0; s < size_sectors; s++) { + fread(img_data, sizeof img_data, 1, raw_img); + fwrite(img_data, sizeof img_data, 1, f); + if (progress_callback) + progress_callback(s + 1, size_sectors); + } + } else { + mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_FIXED, 0); + for (s = 0; s < size_sectors; s++) { + fwrite(img_data, sizeof img_data, 1, f); + if (progress_callback) + progress_callback(s + 1, size_sectors); + } + } + mvhd_footer_to_buffer(&vhdm->footer, footer_buff); + fwrite(footer_buff, sizeof footer_buff, 1, f); + fclose(f); + f = NULL; + free(vhdm); + vhdm = mvhd_open(path, false, err); + goto end; + +cleanup_vhdm: + free(vhdm); + vhdm = NULL; +end: + return vhdm; +} + +/** + * \brief Create sparse or differencing VHD image. + * + * \param [in] path is the absolute path to the VHD file to create + * \param [in] par_path is the absolute path to a parent image. If NULL, a sparse image is created, otherwise create a differencing image + * \param [in] size_in_bytes is the total size in bytes of the virtual hard disk image + * \param [in] geom is the HDD geometry of the image to create. Determines final image size + * \param [in] block_size_in_sectors is the block size in sectors + * \param [out] err indicates what error occurred, if any + * + * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct + */ +static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, uint64_t size_in_bytes, MVHDGeom* geom, uint32_t block_size_in_sectors, int* err) { + uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; + uint8_t sparse_buff[MVHD_SPARSE_SIZE] = {0}; + uint8_t bat_sect[MVHD_SECTOR_SIZE]; + MVHDGeom par_geom = {0}; + memset(bat_sect, 0xffffffff, sizeof bat_sect); + MVHDMeta* vhdm = NULL; + MVHDMeta* par_vhdm = NULL; + mvhd_utf16* w2ku_path_buff = NULL; + mvhd_utf16* w2ru_path_buff = NULL; + uint32_t par_mod_timestamp = 0; + if (par_path != NULL) { + par_mod_timestamp = mvhd_file_mod_timestamp(par_path, err); + if (*err != 0) { + goto end; + } + par_vhdm = mvhd_open(par_path, true, err); + if (par_vhdm == NULL) { + goto end; + } + } + vhdm = calloc(1, sizeof *vhdm); + if (vhdm == NULL) { + *err = MVHD_ERR_MEM; + goto cleanup_par_vhdm; + } + if (par_vhdm != NULL) { + /* We use the geometry from the parent VHD, not what was passed in */ + par_geom.cyl = par_vhdm->footer.geom.cyl; + par_geom.heads = par_vhdm->footer.geom.heads; + par_geom.spt = par_vhdm->footer.geom.spt; + geom = &par_geom; + size_in_bytes = par_vhdm->footer.curr_sz; + } else if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { + *err = MVHD_ERR_INVALID_GEOM; + goto cleanup_vhdm; + } + + FILE* f = mvhd_fopen(path, "wb+", err); + if (f == NULL) { + goto cleanup_vhdm; + } + mvhd_fseeko64(f, 0, SEEK_SET); + /* Note, the sparse header follows the footer copy at the beginning of the file */ + if (par_path == NULL) { + mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DYNAMIC, MVHD_FOOTER_SIZE); + } else { + mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DIFF, MVHD_FOOTER_SIZE); + } + mvhd_footer_to_buffer(&vhdm->footer, footer_buff); + /* As mentioned, start with a copy of the footer */ + fwrite(footer_buff, sizeof footer_buff, 1, f); + /** + * Calculate the number of (2MB or 512KB) data blocks required to store the entire + * contents of the disk image, followed by the number of sectors the + * BAT occupies in the image. Note, the BAT is sector aligned, and is padded + * to the next sector boundary + * */ + uint32_t size_in_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); + uint32_t num_blks = size_in_sectors / block_size_in_sectors; + if (size_in_sectors % block_size_in_sectors != 0) { + num_blks += 1; + } + uint32_t num_bat_sect = num_blks / MVHD_BAT_ENT_PER_SECT; + if (num_blks % MVHD_BAT_ENT_PER_SECT != 0) { + num_bat_sect += 1; + } + /* Storing the BAT directly following the footer and header */ + uint64_t bat_offset = MVHD_FOOTER_SIZE + MVHD_SPARSE_SIZE; + uint64_t par_loc_offset = 0; + + /** + * If creating a differencing VHD, populate the sparse header with additional + * data about the parent image, and where to find it, and it's last modified timestamp + * */ + if (par_vhdm != NULL) { + /** + * Create output buffers to encode paths into. + * The paths are not stored directly in the sparse header, hence the need to + * store them in buffers to be written to the VHD image later + */ + w2ku_path_buff = calloc(MVHD_MAX_PATH_CHARS, sizeof * w2ku_path_buff); + if (w2ku_path_buff == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + w2ru_path_buff = calloc(MVHD_MAX_PATH_CHARS, sizeof * w2ru_path_buff); + if (w2ru_path_buff == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + memcpy(vhdm->sparse.par_uuid, par_vhdm->footer.uuid, sizeof vhdm->sparse.par_uuid); + par_loc_offset = bat_offset + ((uint64_t)num_bat_sect * MVHD_SECTOR_SIZE) + (5 * MVHD_SECTOR_SIZE); + if (mvhd_gen_par_loc(&vhdm->sparse, path, par_path, par_loc_offset, w2ku_path_buff, w2ru_path_buff, (MVHDError*)err) < 0) { + goto cleanup_vhdm; + } + vhdm->sparse.par_timestamp = par_mod_timestamp; + } + mvhd_gen_sparse_header(&vhdm->sparse, num_blks, bat_offset, block_size_in_sectors); + mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); + fwrite(sparse_buff, sizeof sparse_buff, 1, f); + /* The BAT sectors need to be filled with 0xffffffff */ + for (uint32_t i = 0; i < num_bat_sect; i++) { + fwrite(bat_sect, sizeof bat_sect, 1, f); + } + mvhd_write_empty_sectors(f, 5); + /** + * If creating a differencing VHD, the paths to the parent image need to be written + * tp the file. Both absolute and relative paths are written + * */ + if (par_vhdm != NULL) { + uint64_t curr_pos = (uint64_t)mvhd_ftello64(f); + /* Double check my sums... */ + assert(curr_pos == par_loc_offset); + /* Fill the space required for location data with zero */ + uint8_t empty_sect[MVHD_SECTOR_SIZE] = {0}; + for (int i = 0; i < 2; i++) { + for (uint32_t j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { + fwrite(empty_sect, sizeof empty_sect, 1, f); + } + } + /* Now write the location entries */ + mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET); + fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, f); + mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset, SEEK_SET); + fwrite(w2ru_path_buff, vhdm->sparse.par_loc_entry[1].plat_data_len, 1, f); + /* and reset the file position to continue */ + mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset + vhdm->sparse.par_loc_entry[1].plat_data_space, SEEK_SET); + mvhd_write_empty_sectors(f, 5); + } + /* And finish with the footer */ + fwrite(footer_buff, sizeof footer_buff, 1, f); + fclose(f); + f = NULL; + free(vhdm); + vhdm = mvhd_open(path, false, err); + goto end; + +cleanup_vhdm: + free(vhdm); + vhdm = NULL; +cleanup_par_vhdm: + if (par_vhdm != NULL) { + mvhd_close(par_vhdm); + } +end: + free(w2ku_path_buff); + free(w2ru_path_buff); + return vhdm; +} + +MVHDMeta* mvhd_create_sparse(const char* path, MVHDGeom geom, int* err) { + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + return mvhd_create_sparse_diff(path, NULL, size_in_bytes, &geom, MVHD_BLOCK_LARGE, err); +} + +MVHDMeta* mvhd_create_diff(const char* path, const char* par_path, int* err) { + return mvhd_create_sparse_diff(path, par_path, 0, NULL, MVHD_BLOCK_LARGE, err); +} + +MVHDMeta* mvhd_create_ex(MVHDCreationOptions options, int* err) { + uint32_t geom_sector_size; + switch (options.type) + { + case MVHD_TYPE_FIXED: + case MVHD_TYPE_DYNAMIC: + geom_sector_size = mvhd_calc_size_sectors(&(options.geometry)); + if ((options.size_in_bytes > 0 && (options.size_in_bytes % MVHD_SECTOR_SIZE) > 0) + || (options.size_in_bytes > MVHD_MAX_SIZE_IN_BYTES) + || (options.size_in_bytes == 0 && geom_sector_size == 0)) + { + *err = MVHD_ERR_INVALID_SIZE; + return NULL; + } + + if (options.size_in_bytes > 0 && ((uint64_t)geom_sector_size * MVHD_SECTOR_SIZE) > options.size_in_bytes) + { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } + + if (options.size_in_bytes == 0) + options.size_in_bytes = (uint64_t)geom_sector_size * MVHD_SECTOR_SIZE; + + if (geom_sector_size == 0) + options.geometry = mvhd_calculate_geometry(options.size_in_bytes); + break; + case MVHD_TYPE_DIFF: + if (options.parent_path == NULL) + { + *err = MVHD_ERR_FILE; + return NULL; + } + break; + default: + *err = MVHD_ERR_TYPE; + return NULL; + } + + if (options.path == NULL) + { + *err = MVHD_ERR_FILE; + return NULL; + } + + if (options.type != MVHD_TYPE_FIXED) + { + if (options.block_size_in_sectors == MVHD_BLOCK_DEFAULT) + options.block_size_in_sectors = MVHD_BLOCK_LARGE; + + if (options.block_size_in_sectors != MVHD_BLOCK_LARGE && options.block_size_in_sectors != MVHD_BLOCK_SMALL) + { + *err = MVHD_ERR_INVALID_BLOCK_SIZE; + return NULL; + } + } + + switch (options.type) + { + case MVHD_TYPE_FIXED: + return mvhd_create_fixed_raw(options.path, NULL, options.size_in_bytes, &(options.geometry), err, options.progress_callback); + case MVHD_TYPE_DYNAMIC: + return mvhd_create_sparse_diff(options.path, NULL, options.size_in_bytes, &(options.geometry), options.block_size_in_sectors, err); + case MVHD_TYPE_DIFF: + return mvhd_create_sparse_diff(options.path, options.parent_path, 0, NULL, options.block_size_in_sectors, err); + } + + return NULL; /* Make the compiler happy */ +} \ No newline at end of file diff --git a/src/minivhd/minivhd_create.h b/src/minivhd/minivhd_create.h new file mode 100644 index 0000000..9840d19 --- /dev/null +++ b/src/minivhd/minivhd_create.h @@ -0,0 +1,8 @@ +#ifndef MINIVHD_CREATE_H +#define MINIVHD_CREATE_H +#include +#include "minivhd.h" + +MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback); + +#endif \ No newline at end of file diff --git a/src/minivhd/minivhd_internal.h b/src/minivhd/minivhd_internal.h new file mode 100644 index 0000000..ea75284 --- /dev/null +++ b/src/minivhd/minivhd_internal.h @@ -0,0 +1,96 @@ +#ifndef MINIVHD_INTERNAL_H +#define MINIVHD_INTERNAL_H +#include +#include +#include + +#define MVHD_FOOTER_SIZE 512 +#define MVHD_SPARSE_SIZE 1024 + +#define MVHD_SECTOR_SIZE 512 +#define MVHD_BAT_ENT_PER_SECT 128 + +#define MVHD_MAX_SIZE_IN_BYTES 0x1fe00000000 + +#define MVHD_SPARSE_BLK 0xffffffff +/* For simplicity, we don't handle paths longer than this + * Note, this is the max path in characters, as that is what + * Windows uses + */ +#define MVHD_MAX_PATH_CHARS 260 +#define MVHD_MAX_PATH_BYTES 1040 + +#define MVHD_DIF_LOC_W2RU 0x57327275 +#define MVHD_DIF_LOC_W2KU 0x57326B75 + +typedef struct MVHDSectorBitmap { + uint8_t* curr_bitmap; + int sector_count; + int curr_block; +} MVHDSectorBitmap; + +typedef struct MVHDFooter { + uint8_t cookie[8]; + uint32_t features; + uint32_t fi_fmt_vers; + uint64_t data_offset; + uint32_t timestamp; + uint8_t cr_app[4]; + uint32_t cr_vers; + uint8_t cr_host_os[4]; + uint64_t orig_sz; + uint64_t curr_sz; + struct { + uint16_t cyl; + uint8_t heads; + uint8_t spt; + } geom; + uint32_t disk_type; + uint32_t checksum; + uint8_t uuid[16]; + uint8_t saved_st; + uint8_t reserved[427]; +} MVHDFooter; + +typedef struct MVHDSparseHeader { + uint8_t cookie[8]; + uint64_t data_offset; + uint64_t bat_offset; + uint32_t head_vers; + uint32_t max_bat_ent; + uint32_t block_sz; + uint32_t checksum; + uint8_t par_uuid[16]; + uint32_t par_timestamp; + uint32_t reserved_1; + uint8_t par_utf16_name[512]; + struct { + uint32_t plat_code; + uint32_t plat_data_space; + uint32_t plat_data_len; + uint32_t reserved; + uint64_t plat_data_offset; + } par_loc_entry[8]; + uint8_t reserved_2[256]; +} MVHDSparseHeader; + +typedef struct MVHDMeta MVHDMeta; +struct MVHDMeta { + FILE* f; + bool readonly; + char filename[MVHD_MAX_PATH_BYTES]; + struct MVHDMeta* parent; + MVHDFooter footer; + MVHDSparseHeader sparse; + uint32_t* block_offset; + int sect_per_block; + MVHDSectorBitmap bitmap; + int (*read_sectors)(MVHDMeta*, uint32_t, int, void*); + int (*write_sectors)(MVHDMeta*, uint32_t, int, void*); + struct { + uint8_t* zero_data; + int sector_count; + } format_buffer; +}; + +#endif \ No newline at end of file diff --git a/src/minivhd/minivhd_io.c b/src/minivhd/minivhd_io.c new file mode 100644 index 0000000..8e9172e --- /dev/null +++ b/src/minivhd/minivhd_io.c @@ -0,0 +1,276 @@ +/** + * \file + * \brief Sector reading and writing implementations + */ + +#include +#include +#include "minivhd_internal.h" +#include "minivhd_util.h" + +/* The following bit array macros adapted from + http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html */ + +#define VHD_SETBIT(A,k) ( A[(k/8)] |= (0x80 >> (k%8)) ) +#define VHD_CLEARBIT(A,k) ( A[(k/8)] &= ~(0x80 >> (k%8)) ) +#define VHD_TESTBIT(A,k) ( A[(k/8)] & (0x80 >> (k%8)) ) + +static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect); +static void mvhd_read_sect_bitmap(MVHDMeta* vhdm, int blk); +static void mvhd_write_bat_entry(MVHDMeta* vhdm, int blk); +static void mvhd_create_block(MVHDMeta* vhdm, int blk); +static void mvhd_write_curr_sect_bitmap(MVHDMeta* vhdm); + +/** + * \brief Check that we will not be overflowing buffers + * + * \param [in] offset The offset from which we are beginning from + * \param [in] num_sectors The number of sectors which we desire to read/write + * \param [in] total_sectors The total number of sectors available + * \param [out] transfer_sect The number of sectors to actually write. + * This may be lower than num_sectors if offset + num_sectors >= total_sectors + * \param [out] trunc_sectors The number of sectors truncated if transfer_sectors < num_sectors + */ +static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int* transfer_sect, int* trunc_sect) { + *transfer_sect = num_sectors; + *trunc_sect = 0; + if ((total_sectors - offset) < (uint32_t)*transfer_sect) { + *transfer_sect = total_sectors - offset; + *trunc_sect = num_sectors - *transfer_sect; + } +} + +void mvhd_write_empty_sectors(FILE* f, int sector_count) { + uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; + for (int i = 0; i < sector_count; i++) { + fwrite(zero_bytes, sizeof zero_bytes, 1, f); + } +} + +/** + * \brief Read the sector bitmap for a block. + * + * If the block is sparse, the sector bitmap in memory will be + * zeroed. Otherwise, the sector bitmap is read from the VHD file. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] blk The block for which to read the sector bitmap from + */ +static void mvhd_read_sect_bitmap(MVHDMeta* vhdm, int blk) { + if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { + mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); + fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); + } else { + memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); + } + vhdm->bitmap.curr_block = blk; +} + +/** + * \brief Write the current sector bitmap in memory to file + * + * \param [in] vhdm MiniVHD data structure + */ +static void mvhd_write_curr_sect_bitmap(MVHDMeta* vhdm) { + if (vhdm->bitmap.curr_block >= 0) { + int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET); + fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f); + } +} + +/** + * \brief Write block offset from memory into file + * + * \param [in] vhdm MiniVHD data structure + * \param [in] blk The block for which to write the offset for + */ +static void mvhd_write_bat_entry(MVHDMeta* vhdm, int blk) { + uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); + uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); + mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET); + fwrite(&offset, sizeof offset, 1, vhdm->f); +} + +/** + * \brief Create an empty block in a sparse or differencing VHD image + * + * VHD images store data in blocks, which are typically 4096 sectors in size + * (~2MB). These blocks may be stored on disk in any order. Blocks are created + * on demand when required. + * + * This function creates new, empty blocks, by replacing the footer at the end of the file + * and then re-inserting the footer at the new file end. The BAT table entry for the + * new block is updated with the new offset. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] blk The block number to create + */ +static void mvhd_create_block(MVHDMeta* vhdm, int blk) { + uint8_t footer[MVHD_FOOTER_SIZE]; + /* Seek to where the footer SHOULD be */ + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(footer, sizeof footer, 1, vhdm->f); + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + if (!mvhd_is_conectix_str(footer)) { + /* Oh dear. We use the header instead, since something has gone wrong at the footer */ + mvhd_fseeko64(vhdm->f, 0, SEEK_SET); + fread(footer, sizeof footer, 1, vhdm->f); + mvhd_fseeko64(vhdm->f, 0, SEEK_END); + } + int64_t abs_offset = mvhd_ftello64(vhdm->f); + if (abs_offset % MVHD_SECTOR_SIZE != 0) { + /* Yikes! We're supposed to be on a sector boundary. Add some padding */ + int64_t padding_amount = (int64_t)MVHD_SECTOR_SIZE - (abs_offset % MVHD_SECTOR_SIZE); + uint8_t zero_byte = 0; + for (int i = 0; i < padding_amount; i++) { + fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); + } + abs_offset += padding_amount; + } + uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE); + int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; + mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors); + /* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */ + mvhd_write_empty_sectors(vhdm->f, 5); + /* And we finish with the footer */ + fwrite(footer, sizeof footer, 1, vhdm->f); + /* We no longer have a sparse block. Update that BAT! */ + vhdm->block_offset[blk] = sect_offset; + mvhd_write_bat_entry(vhdm, blk); +} + +int mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + int64_t addr; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + addr = (int64_t)offset * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + fread(out_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + return truncated_sectors; +} + +int mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t* buff = (uint8_t*)out_buff; + int64_t addr; + uint32_t s, ls; + int blk, prev_blk, sib; + ls = offset + transfer_sectors; + prev_blk = -1; + for (s = offset; s < ls; s++) { + blk = s / vhdm->sect_per_block; + sib = s % vhdm->sect_per_block; + if (blk != prev_blk) { + prev_blk = blk; + if (vhdm->bitmap.curr_block != blk) { + mvhd_read_sect_bitmap(vhdm, blk); + mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); + } else { + addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + } + } + if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { + fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); + } else { + memset(buff, 0, MVHD_SECTOR_SIZE); + mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR); + } + buff += MVHD_SECTOR_SIZE; + } + return truncated_sectors; +} + +int mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t* buff = (uint8_t*)out_buff; + MVHDMeta* curr_vhdm = vhdm; + uint32_t s, ls; + int blk, sib; + ls = offset + transfer_sectors; + for (s = offset; s < ls; s++) { + while (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF) { + blk = s / curr_vhdm->sect_per_block; + sib = s % curr_vhdm->sect_per_block; + if (curr_vhdm->bitmap.curr_block != blk) { + mvhd_read_sect_bitmap(curr_vhdm, blk); + } + if (!VHD_TESTBIT(curr_vhdm->bitmap.curr_bitmap, sib)) { + curr_vhdm = curr_vhdm->parent; + } else { break; } + } + /* We handle actual sector reading using the fixed or sparse functions, + as a differencing VHD is also a sparse VHD */ + if (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF || curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { + mvhd_sparse_read(curr_vhdm, s, 1, buff); + } else { + mvhd_fixed_read(curr_vhdm, s, 1, buff); + } + curr_vhdm = vhdm; + buff += MVHD_SECTOR_SIZE; + } + return truncated_sectors; +} + +int mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + int64_t addr; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + addr = (int64_t)offset * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + fwrite(in_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f); + return truncated_sectors; +} + +int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t* buff = (uint8_t*)in_buff; + int64_t addr; + uint32_t s, ls; + int blk, prev_blk, sib; + ls = offset + transfer_sectors; + prev_blk = -1; + for (s = offset; s < ls; s++) { + blk = s / vhdm->sect_per_block; + sib = s % vhdm->sect_per_block; + if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { + /* "read" the sector bitmap first, before creating a new block, as the bitmap will be + zero either way */ + mvhd_read_sect_bitmap(vhdm, blk); + mvhd_create_block(vhdm, blk); + } + if (blk != prev_blk) { + if (vhdm->bitmap.curr_block != blk) { + if (prev_blk >= 0) { + /* Write the sector bitmap for the previous block, before we replace it. */ + mvhd_write_curr_sect_bitmap(vhdm); + } + mvhd_read_sect_bitmap(vhdm, blk); + mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); + } else { + addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + } + prev_blk = blk; + } + fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); + VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); + buff += MVHD_SECTOR_SIZE; + } + /* And write the sector bitmap for the last block we visited to disk */ + mvhd_write_curr_sect_bitmap(vhdm); + return truncated_sectors; +} + +int mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + return 0; +} \ No newline at end of file diff --git a/src/minivhd/minivhd_io.h b/src/minivhd/minivhd_io.h new file mode 100644 index 0000000..cdbfa6d --- /dev/null +++ b/src/minivhd/minivhd_io.h @@ -0,0 +1,132 @@ +#ifndef MINIVHD_IO_H +#define MINIVHD_IO_H +#include "minivhd.h" + +/** + * \brief Write zero filled sectors to file. + * + * Note, the caller should set the file position before calling this + * function for correct operation. + * + * \param [in] f File to write sectors to + * \param [in] sector_count The number of sectors to write + */ +void mvhd_write_empty_sectors(FILE* f, int sector_count); + +/** + * \brief Read a fixed VHD image + * + * Fixed VHD images are essentially raw image files with a footer tacked on + * the end. They are therefore straightforward to write + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to read from + * \param [in] num_sectors The desired number of sectors to read + * \param [out] out_buff An output buffer to store read sectors. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were read from file + * \retval >0 < num_sectors were read from file + */ +int mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Read a sparse VHD image + * + * Sparse, or dynamic images are VHD images that grow as data is written to them. + * + * This function implements the logic to read sectors from the file, taking into + * account the fact that blocks may be stored on disk in any order, and that the + * read could cross block boundaries. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to read from + * \param [in] num_sectors The desired number of sectors to read + * \param [out] out_buff An output buffer to store read sectors. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were read from file + * \retval >0 < num_sectors were read from file + */ +int mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Read a differencing VHD image + * + * Differencing images are a variant of a sparse image. They contain the grow-on-demand + * properties of sparse images, but also reference a parent image. Data is read from the + * child image only if it is newer than the data stored in the parent image. + * + * This function implements the logic to read sectors from the child, or a parent image. + * Differencing images may have a differencing image as a parent, creating a chain of images. + * There is no theoretical chain length limit, although I do not consider long chains to be + * advisable. Verifying the parent-child relationship is not very robust. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to read from + * \param [in] num_sectors The desired number of sectors to read + * \param [out] out_buff An output buffer to store read sectors. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were read from file + * \retval >0 < num_sectors were read from file + */ +int mvhd_diff_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff); + +/** + * \brief Write to a fixed VHD image + * + * Fixed VHD images are essentially raw image files with a footer tacked on + * the end. They are therefore straightforward to write + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to write to + * \param [in] num_sectors The desired number of sectors to write + * \param [in] in_buff A source buffer to write sectors from. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were written to file + * \retval >0 < num_sectors were written to file + */ +int mvhd_fixed_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +/** + * \brief Write to a sparse or differencing VHD image + * + * Sparse, or dynamic images are VHD images that grow as data is written to them. + * + * Differencing images are a variant of a sparse image. They contain the grow-on-demand + * properties of sparse images, but also reference a parent image. Data is always written + * to the child image. This makes writing to differencing images essentially identical to + * writing to sparse images, hence they use the same function. + * + * This function implements the logic to write sectors to the file, taking into + * account the fact that blocks may be stored on disk in any order, and that the + * write operation could cross block boundaries. + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to write to + * \param [in] num_sectors The desired number of sectors to write + * \param [in] in_buff A source buffer to write sectors from. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were written to file + * \retval >0 < num_sectors were written to file + */ +int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +/** + * \brief A no-op function to "write" to read-only VHD images + * + * \param [in] vhdm MiniVHD data structure + * \param [in] offset Sector offset to write to + * \param [in] num_sectors The desired number of sectors to write + * \param [in] in_buff A source buffer to write sectors from. Must be + * large enough to hold num_sectors worth of sectors. + * + * \retval 0 num_sectors were written to file + * \retval >0 < num_sectors were written to file + */ +int mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); + +#endif \ No newline at end of file diff --git a/src/minivhd/minivhd_manage.c b/src/minivhd/minivhd_manage.c new file mode 100644 index 0000000..5942e96 --- /dev/null +++ b/src/minivhd/minivhd_manage.c @@ -0,0 +1,531 @@ +/** + * \file + * \brief VHD management functions (open, close, read write etc) + */ + +#include +#include +#include +#include +#include +#include "cwalk.h" +#include "libxml2_encoding.h" +#include "minivhd_internal.h" +#include "minivhd_io.h" +#include "minivhd_util.h" +#include "minivhd_struct_rw.h" +#include "minivhd.h" + +int mvhd_errno = 0; +static char tmp_open_path[MVHD_MAX_PATH_BYTES] = {0}; +struct MVHDPaths { + char dir_path[MVHD_MAX_PATH_BYTES]; + char file_name[MVHD_MAX_PATH_BYTES]; + char w2ku_path[MVHD_MAX_PATH_BYTES]; + char w2ru_path[MVHD_MAX_PATH_BYTES]; + char joined_path[MVHD_MAX_PATH_BYTES]; + uint16_t tmp_src_path[MVHD_MAX_PATH_CHARS]; +}; + +static void mvhd_read_footer(MVHDMeta* vhdm); +static void mvhd_read_sparse_header(MVHDMeta* vhdm); +static bool mvhd_footer_checksum_valid(MVHDMeta* vhdm); +static bool mvhd_sparse_checksum_valid(MVHDMeta* vhdm); +static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err); +static void mvhd_calc_sparse_values(MVHDMeta* vhdm); +static int mvhd_init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err); + +/** + * \brief Populate data stuctures with content from a VHD footer + * + * \param [in] vhdm MiniVHD data structure + */ +static void mvhd_read_footer(MVHDMeta* vhdm) { + uint8_t buffer[MVHD_FOOTER_SIZE]; + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(buffer, sizeof buffer, 1, vhdm->f); + mvhd_buffer_to_footer(&vhdm->footer, buffer); +} + +/** + * \brief Populate data stuctures with content from a VHD sparse header + * + * \param [in] vhdm MiniVHD data structure + */ +static void mvhd_read_sparse_header(MVHDMeta* vhdm) { + uint8_t buffer[MVHD_SPARSE_SIZE]; + mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET); + fread(buffer, sizeof buffer, 1, vhdm->f); + mvhd_buffer_to_header(&vhdm->sparse, buffer); +} + +/** + * \brief Validate VHD footer checksum + * + * This works by generating a checksum from the footer, and comparing it against the stored checksum. + * + * \param [in] vhdm MiniVHD data structure + */ +static bool mvhd_footer_checksum_valid(MVHDMeta* vhdm) { + return vhdm->footer.checksum == mvhd_gen_footer_checksum(&vhdm->footer); +} + +/** + * \brief Validate VHD sparse header checksum + * + * This works by generating a checksum from the sparse header, and comparing it against the stored checksum. + * + * \param [in] vhdm MiniVHD data structure + */ +static bool mvhd_sparse_checksum_valid(MVHDMeta* vhdm) { + return vhdm->sparse.checksum == mvhd_gen_sparse_checksum(&vhdm->sparse); +} + +/** + * \brief Read BAT into MiniVHD data structure + * + * The Block Allocation Table (BAT) is the structure in a sparse and differencing VHD which stores + * the 4-byte sector offsets for each data block. This function allocates enough memory to contain + * the entire BAT, and then reads the contents of the BAT into the buffer. + * + * \param [in] vhdm MiniVHD data structure + * \param [out] err this is populated with MVHD_ERR_MEM if the calloc fails + * + * \retval -1 if an error occurrs. Check value of err in this case + * \retval 0 if the function call succeeds + */ +static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err) { + vhdm->block_offset = calloc(vhdm->sparse.max_bat_ent, sizeof *vhdm->block_offset); + if (vhdm->block_offset == NULL) { + *err = MVHD_ERR_MEM; + return -1; + } + mvhd_fseeko64(vhdm->f, vhdm->sparse.bat_offset, SEEK_SET); + for (uint32_t i = 0; i < vhdm->sparse.max_bat_ent; i++) { + fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f); + vhdm->block_offset[i] = mvhd_from_be32(vhdm->block_offset[i]); + } + return 0; +} + +/** + * \brief Perform a one-time calculation of some sparse VHD values + * + * \param [in] vhdm MiniVHD data structure + */ +static void mvhd_calc_sparse_values(MVHDMeta* vhdm) { + vhdm->sect_per_block = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; + int bm_bytes = vhdm->sect_per_block / 8; + vhdm->bitmap.sector_count = bm_bytes / MVHD_SECTOR_SIZE; + if (bm_bytes % MVHD_SECTOR_SIZE > 0) { + vhdm->bitmap.sector_count++; + } +} + +/** + * \brief Allocate memory for a sector bitmap. + * + * Each data block is preceded by a sector bitmap. Each bit indicates whether the corresponding sector + * is considered 'clean' or 'dirty' (for sparse VHD images), or whether to read from the parent or current + * image (for differencing images). + * + * \param [in] vhdm MiniVHD data structure + * \param [out] err this is populated with MVHD_ERR_MEM if the calloc fails + * + * \retval -1 if an error occurrs. Check value of err in this case + * \retval 0 if the function call succeeds + */ +static int mvhd_init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err) { + vhdm->bitmap.curr_bitmap = calloc(vhdm->bitmap.sector_count, MVHD_SECTOR_SIZE); + if (vhdm->bitmap.curr_bitmap == NULL) { + *err = MVHD_ERR_MEM; + return -1; + } + vhdm->bitmap.curr_block = -1; + return 0; +} + +/** + * \brief Check if the path for a given platform code exists + * + * From the available paths, both relative and absolute, construct a full path + * and attempt to open a file at that path. + * + * Note, this function makes no attempt to verify that the path is the correct + * VHD image, or even a VHD image at all. + * + * \param [in] paths a struct containing all available paths to work with + * \param [in] the platform code to try and obtain a path for. Setting this to zero + * will try using the directory of the child image + * + * \retval true if a file is found + * \retval false if a file is not found + */ +static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) { + memset(paths->joined_path, 0, sizeof paths->joined_path); + FILE* f; + int cwk_ret, ferr; + enum cwk_path_style style = cwk_path_guess_style((const char*)paths->dir_path); + cwk_path_set_style(style); + cwk_ret = 1; + if (plat_code == MVHD_DIF_LOC_W2RU && *paths->w2ru_path) { + cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->w2ru_path, paths->joined_path, sizeof paths->joined_path); + } else if (plat_code == MVHD_DIF_LOC_W2KU && *paths->w2ku_path) { + strncpy_s(paths->joined_path, sizeof paths->joined_path, (const char*)paths->w2ku_path, sizeof paths->joined_path); + cwk_ret = 0; + } else if (plat_code == 0) { + cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->file_name, paths->joined_path, sizeof paths->joined_path); + } + if (cwk_ret > MVHD_MAX_PATH_BYTES) { + return false; + } + f = mvhd_fopen((const char*)paths->joined_path, "rb", &ferr); + if (f != NULL) { + /* We found a file at the requested path! */ + strncpy_s(tmp_open_path, sizeof tmp_open_path, paths->joined_path, sizeof tmp_open_path); + fclose(f); + return true; + } else { + return false; + } +} + +/** + * \brief attempt to obtain a file path to a file that may be a valid VHD image + * + * Differential VHD images store both a UTF-16BE file name (or path), and up to + * eight "parent locator" entries. Using this information, this function tries to + * find a parent image. + * + * This function does not verify if the path returned is a valid parent image. + * + * \param [in] vhdm current MiniVHD data structure + * \param [out] err any errors that may occurr. Check this if NULL is returned + * + * \return a pointer to the global string `tmp_open_path`, or NULL if a path could + * not be found, or some error occurred + */ +static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { + int utf_outlen, utf_inlen, utf_ret; + char* par_fp = NULL; + /* We can't resolve relative paths if we don't have an absolute + path to work with */ + if (!cwk_path_is_absolute((const char*)vhdm->filename)) { + *err = MVHD_ERR_PATH_REL; + goto end; + } + struct MVHDPaths* paths = calloc(1, sizeof *paths); + if (paths == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + size_t dirlen; + cwk_path_get_dirname((const char*)vhdm->filename, &dirlen); + if (dirlen >= sizeof paths->dir_path) { + *err = MVHD_ERR_PATH_LEN; + goto paths_cleanup; + } + strncpy_s(paths->dir_path, sizeof paths->dir_path, vhdm->filename, dirlen); + /* Get the filename field from the sparse header. */ + utf_outlen = (int)sizeof paths->file_name; + utf_inlen = (int)sizeof vhdm->sparse.par_utf16_name; + utf_ret = UTF16BEToUTF8((unsigned char*)paths->file_name, &utf_outlen, (const unsigned char*)vhdm->sparse.par_utf16_name, &utf_inlen); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, err); + goto paths_cleanup; + } + /* Now read the parent locator entries, both relative and absolute, if they exist */ + unsigned char* loc_path; + for (int i = 0; i < 8; i++) { + utf_outlen = MVHD_MAX_PATH_BYTES - 1; + if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2RU) { + loc_path = (unsigned char*)paths->w2ru_path; + } else if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2KU) { + loc_path = (unsigned char*)paths->w2ku_path; + } else { + continue; + } + utf_inlen = vhdm->sparse.par_loc_entry[i].plat_data_len; + if (utf_inlen > MVHD_MAX_PATH_BYTES) { + *err = MVHD_ERR_PATH_LEN; + goto paths_cleanup; + } + mvhd_fseeko64(vhdm->f, vhdm->sparse.par_loc_entry[i].plat_data_offset, SEEK_SET); + fread(paths->tmp_src_path, sizeof (uint8_t), utf_inlen, vhdm->f); + /* Note, the W2*u parent locators are UTF-16LE, unlike the filename field previously obtained, + which is UTF-16BE */ + utf_ret = UTF16LEToUTF8(loc_path, &utf_outlen, (const unsigned char*)paths->tmp_src_path, &utf_inlen); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, err); + goto paths_cleanup; + } + } + /* We have paths in UTF-8. We should have enough info to try and find the parent VHD */ + /* Does the relative path exist? */ + if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2RU)) { + par_fp = tmp_open_path; + goto paths_cleanup; + } + /* What about trying the child directory? */ + if (mvhd_parent_path_exists(paths, 0)) { + par_fp = tmp_open_path; + goto paths_cleanup; + } + /* Well, all else fails, try the stored absolute path, if it exists */ + if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2KU)) { + par_fp = tmp_open_path; + goto paths_cleanup; + } + /* If we reach this point, we could not find a path with a valid file */ + par_fp = NULL; + *err = MVHD_ERR_PAR_NOT_FOUND; + +paths_cleanup: + free(paths); + paths = NULL; +end: + return par_fp; +} + +/** + * \brief Attach the read/write function pointers to read/write functions + * + * Depending on the VHD type, different sector reading and writing functions are used. + * The functions are called via function pointers stored in the vhdm struct. + * + * \param [in] vhdm MiniVHD data structure + */ +static void mvhd_assign_io_funcs(MVHDMeta* vhdm) { + switch (vhdm->footer.disk_type) { + case MVHD_TYPE_FIXED: + vhdm->read_sectors = mvhd_fixed_read; + vhdm->write_sectors = mvhd_fixed_write; + break; + case MVHD_TYPE_DYNAMIC: + vhdm->read_sectors = mvhd_sparse_read; + vhdm->write_sectors = mvhd_sparse_diff_write; + break; + case MVHD_TYPE_DIFF: + vhdm->read_sectors = mvhd_diff_read; + vhdm->write_sectors = mvhd_sparse_diff_write; + break; + } + if (vhdm->readonly) { + vhdm->write_sectors = mvhd_noop_write; + } +} + +bool mvhd_file_is_vhd(FILE* f) { + if (f) { + uint8_t con_str[8]; + mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(con_str, sizeof con_str, 1, f); + return mvhd_is_conectix_str(con_str); + } else { + return false; + } +} + +MVHDGeom mvhd_calculate_geometry(uint64_t size) { + MVHDGeom chs; + uint32_t ts = (uint32_t)(size / MVHD_SECTOR_SIZE); + uint32_t spt, heads, cyl, cth; + if (ts > 65535 * 16 * 255) { + ts = 65535 * 16 * 255; + } + if (ts >= 65535 * 16 * 63) { + spt = 255; + heads = 16; + cth = ts / spt; + } else { + spt = 17; + cth = ts / spt; + heads = (cth + 1023) / 1024; + if (heads < 4) { + heads = 4; + } + if (cth >= (heads * 1024) || heads > 16) { + spt = 31; + heads = 16; + cth = ts / spt; + } + if (cth >= (heads * 1024)) { + spt = 63; + heads = 16; + cth = ts / spt; + } + } + cyl = cth / heads; + chs.heads = heads; + chs.spt = spt; + chs.cyl = cyl; + return chs; +} + +MVHDMeta* mvhd_open(const char* path, bool readonly, int* err) { + MVHDError open_err; + MVHDMeta *vhdm = calloc(sizeof *vhdm, 1); + if (vhdm == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + if (strlen(path) >= sizeof vhdm->filename) { + *err = MVHD_ERR_PATH_LEN; + goto cleanup_vhdm; + } + strcpy_s(vhdm->filename, sizeof vhdm->filename, path); + vhdm->f = readonly ? mvhd_fopen((const char*)vhdm->filename, "rb", err) : mvhd_fopen((const char*)vhdm->filename, "rb+", err); + if (vhdm->f == NULL) { + /* note, mvhd_fopen sets err for us */ + goto cleanup_vhdm; + } + vhdm->readonly = readonly; + if (!mvhd_file_is_vhd(vhdm->f)) { + *err = MVHD_ERR_NOT_VHD; + goto cleanup_file; + } + mvhd_read_footer(vhdm); + if (!mvhd_footer_checksum_valid(vhdm)) { + *err = MVHD_ERR_FOOTER_CHECKSUM; + goto cleanup_file; + } + if (vhdm->footer.disk_type == MVHD_TYPE_DIFF || vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { + mvhd_read_sparse_header(vhdm); + if (!mvhd_sparse_checksum_valid(vhdm)) { + *err = MVHD_ERR_SPARSE_CHECKSUM; + goto cleanup_file; + } + if (mvhd_read_bat(vhdm, &open_err) == -1) { + *err = open_err; + goto cleanup_file; + } + mvhd_calc_sparse_values(vhdm); + if (mvhd_init_sector_bitmap(vhdm, &open_err) == -1) { + *err = open_err; + goto cleanup_bat; + } + + } else if (vhdm->footer.disk_type != MVHD_TYPE_FIXED) { + *err = MVHD_ERR_TYPE; + goto cleanup_bitmap; + } + mvhd_assign_io_funcs(vhdm); + vhdm->format_buffer.zero_data = calloc(64, MVHD_SECTOR_SIZE); + if (vhdm->format_buffer.zero_data == NULL) { + *err = MVHD_ERR_MEM; + goto cleanup_bitmap; + } + vhdm->format_buffer.sector_count = 64; + if (vhdm->footer.disk_type == MVHD_TYPE_DIFF) { + char* par_path = mvhd_get_diff_parent_path(vhdm, err); + if (par_path == NULL) { + goto cleanup_format_buff; + } + uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); + if (*err != 0) { + goto cleanup_format_buff; + } + if (vhdm->sparse.par_timestamp != par_mod_ts) { + /* The last-modified timestamp is to fragile to make this a fatal error. + Instead, we inform the caller of the potential problem. */ + *err = MVHD_ERR_TIMESTAMP; + } + vhdm->parent = mvhd_open(par_path, true, err); + if (vhdm->parent == NULL) { + goto cleanup_format_buff; + } + if (memcmp(vhdm->sparse.par_uuid, vhdm->parent->footer.uuid, sizeof vhdm->sparse.par_uuid) != 0) { + *err = MVHD_ERR_INVALID_PAR_UUID; + goto cleanup_format_buff; + } + } + /* If we've reached this point, we are good to go, so skip the cleanup steps */ + goto end; +cleanup_format_buff: + free(vhdm->format_buffer.zero_data); + vhdm->format_buffer.zero_data = NULL; +cleanup_bitmap: + free(vhdm->bitmap.curr_bitmap); + vhdm->bitmap.curr_bitmap = NULL; +cleanup_bat: + free(vhdm->block_offset); + vhdm->block_offset = NULL; +cleanup_file: + fclose(vhdm->f); + vhdm->f = NULL; +cleanup_vhdm: + free(vhdm); + vhdm = NULL; +end: + return vhdm; +} + +void mvhd_close(MVHDMeta* vhdm) { + if (vhdm != NULL) { + if (vhdm->parent != NULL) { + mvhd_close(vhdm->parent); + } + fclose(vhdm->f); + if (vhdm->block_offset != NULL) { + free(vhdm->block_offset); + vhdm->block_offset = NULL; + } + if (vhdm->bitmap.curr_bitmap != NULL) { + free(vhdm->bitmap.curr_bitmap); + vhdm->bitmap.curr_bitmap = NULL; + } + if (vhdm->format_buffer.zero_data != NULL) { + free(vhdm->format_buffer.zero_data); + vhdm->format_buffer.zero_data = NULL; + } + free(vhdm); + vhdm = NULL; + } +} + +int mvhd_diff_update_par_timestamp(MVHDMeta* vhdm, int* err) { + uint8_t sparse_buff[1024]; + if (vhdm == NULL || err == NULL) { + *err = MVHD_ERR_INVALID_PARAMS; + return -1; + } + if (vhdm->footer.disk_type != MVHD_TYPE_DIFF) { + *err = MVHD_ERR_TYPE; + return -1; + } + char* par_path = mvhd_get_diff_parent_path(vhdm, err); + if (par_path == NULL) { + return -1; + } + uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); + if (*err != 0) { + return -1; + } + /* Update the timestamp and sparse header checksum */ + vhdm->sparse.par_timestamp = par_mod_ts; + vhdm->sparse.checksum = mvhd_gen_sparse_checksum(&vhdm->sparse); + /* Generate and write the updated sparse header */ + mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); + mvhd_fseeko64(vhdm->f, (int64_t)vhdm->footer.data_offset, SEEK_SET); + fwrite(sparse_buff, sizeof sparse_buff, 1, vhdm->f); + return 0; +} + +int mvhd_read_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_buff) { + return vhdm->read_sectors(vhdm, offset, num_sectors, out_buff); +} + +int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { + return vhdm->write_sectors(vhdm, offset, num_sectors, in_buff); +} + +int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors) { + int num_full = num_sectors / vhdm->format_buffer.sector_count; + int remain = num_sectors % vhdm->format_buffer.sector_count; + for (int i = 0; i < num_full; i++) { + vhdm->write_sectors(vhdm, offset, vhdm->format_buffer.sector_count, vhdm->format_buffer.zero_data); + offset += vhdm->format_buffer.sector_count; + } + vhdm->write_sectors(vhdm, offset, remain, vhdm->format_buffer.zero_data); + return 0; +} \ No newline at end of file diff --git a/src/minivhd/minivhd_struct_rw.c b/src/minivhd/minivhd_struct_rw.c new file mode 100644 index 0000000..66f2289 --- /dev/null +++ b/src/minivhd/minivhd_struct_rw.c @@ -0,0 +1,165 @@ +/** + * \file + * \brief Header and footer serialize/deserialize functions + */ + +#include +#include +#include +#include +#include +#include "minivhd_util.h" +#include "minivhd_internal.h" + +/* Read data from footer into the struct members, swapping endian where necessary + Note: order matters here! We must read each field in the order the struct is in. + Doing this may be less elegant than performing a memcpy to a packed struct, but + it avoids potential data alignment issues, and the endian swapping allows us to + use the fields directly. */ + +static void mvhd_next_buffer_to_struct(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer); +static void mvhd_next_struct_to_buffer(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer); + +/** + * \brief Get the next field from a buffer and store it in a struct member, converting endian if necessary + * + * \param [out] struct_memb struct member to save the field to + * \param [in] memb_size the size of struct_memb, in bytes + * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) + * \param [in] buffer the buffer from which fields are read from. Will be advanced at the end of the function call + */ +static void mvhd_next_buffer_to_struct(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer) { + memcpy(struct_memb, *buffer, memb_size); + if (req_endian) { + switch (memb_size) { + case 2: + *(uint16_t*)(struct_memb) = mvhd_from_be16(*(uint16_t*)(struct_memb)); + break; + case 4: + *(uint32_t*)(struct_memb) = mvhd_from_be32(*(uint32_t*)(struct_memb)); + break; + case 8: + *(uint64_t*)(struct_memb) = mvhd_from_be64(*(uint64_t*)(struct_memb)); + break; + } + } + *buffer += memb_size; +} + +/** + * \brief Save a struct member into a buffer, converting endian if necessary + * + * \param [in] struct_memb struct member read from + * \param [in] memb_size the size of struct_memb, in bytes + * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) + * \param [out] buffer the buffer from which struct member is saved to. Will be advanced at the end of the function call + */ +static void mvhd_next_struct_to_buffer(void* struct_memb, size_t memb_size, bool req_endian, uint8_t** buffer) { + uint8_t *buf_ptr = *buffer; + memcpy(buf_ptr, struct_memb, memb_size); + if (req_endian) { + switch (memb_size) { + case 2: + *((uint16_t*)buf_ptr) = mvhd_to_be16(*(uint16_t*)(struct_memb)); + break; + case 4: + *((uint32_t*)buf_ptr) = mvhd_to_be32(*(uint32_t*)(struct_memb)); + break; + case 8: + *((uint64_t*)buf_ptr) = mvhd_to_be64(*(uint64_t*)(struct_memb)); + break; + } + } + buf_ptr += memb_size; + *buffer = buf_ptr; +} + +void mvhd_buffer_to_footer(MVHDFooter* footer, uint8_t* buffer) { + uint8_t* buff_ptr = buffer; + mvhd_next_buffer_to_struct(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->features, sizeof footer->features, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); +} + +void mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer) { + uint8_t* buff_ptr = buffer; + mvhd_next_struct_to_buffer(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->features, sizeof footer->features, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); +} + +void mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer) { + uint8_t* buff_ptr = buffer; + mvhd_next_buffer_to_struct(&header->cookie, sizeof header->cookie, false, &buff_ptr); + mvhd_next_buffer_to_struct(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->checksum, sizeof header->checksum, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); + for (int i = 0; i < 8; i++) { + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); + } + mvhd_next_buffer_to_struct(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); +} + +void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer) { + uint8_t* buff_ptr = buffer; + mvhd_next_struct_to_buffer(&header->cookie, sizeof header->cookie, false, &buff_ptr); + mvhd_next_struct_to_buffer(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->checksum, sizeof header->checksum, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); + for (int i = 0; i < 8; i++) { + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); + } + mvhd_next_struct_to_buffer(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); +} \ No newline at end of file diff --git a/src/minivhd/minivhd_struct_rw.h b/src/minivhd/minivhd_struct_rw.h new file mode 100644 index 0000000..0b1e018 --- /dev/null +++ b/src/minivhd/minivhd_struct_rw.h @@ -0,0 +1,38 @@ +#ifndef MINIVHD_STRUCT_RW_H +#define minivhd_struct_rw + +#include "minivhd_internal.h" + +/** + * \brief Save the contents of a VHD footer from a buffer to a struct + * + * \param [out] footer save contents of buffer into footer + * \param [in] buffer VHD footer in raw bytes + */ +void mvhd_buffer_to_footer(MVHDFooter* footer, uint8_t* buffer); + +/** + * \brief Save the contents of a VHD sparse header from a buffer to a struct + * + * \param [out] header save contents of buffer into header + * \param [in] buffer VHD header in raw bytes + */ +void mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer); + +/** + * \brief Save the contents of a VHD footer struct to a buffer + * + * \param [in] footer save contents of struct into buffer + * \param [out] buffer VHD footer in raw bytes + */ +void mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer); + +/** + * \brief Save the contents of a VHD sparse header struct to a buffer + * + * \param [in] header save contents of struct into buffer + * \param [out] buffer VHD sparse header in raw bytes + */ +void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer); + +#endif \ No newline at end of file diff --git a/src/minivhd/minivhd_util.c b/src/minivhd/minivhd_util.c new file mode 100644 index 0000000..d1ddab2 --- /dev/null +++ b/src/minivhd/minivhd_util.c @@ -0,0 +1,323 @@ +/** + * \file + * \brief Utility functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libxml2_encoding.h" +#include "minivhd_internal.h" +#include "minivhd_util.h" + +const char MVHD_CONECTIX_COOKIE[] = "conectix"; +const char MVHD_CREATOR[] = "pcem"; +const char MVHD_CREATOR_HOST_OS[] = "Wi2k"; +const char MVHD_CXSPARSE_COOKIE[] = "cxsparse"; + +uint16_t mvhd_from_be16(uint16_t val) { + uint8_t *tmp = (uint8_t*)&val; + uint16_t ret = 0; + ret |= (uint16_t)tmp[0] << 8; + ret |= (uint16_t)tmp[1] << 0; + return ret; +} +uint32_t mvhd_from_be32(uint32_t val) { + uint8_t *tmp = (uint8_t*)&val; + uint32_t ret = 0; + ret = (uint32_t)tmp[0] << 24; + ret |= (uint32_t)tmp[1] << 16; + ret |= (uint32_t)tmp[2] << 8; + ret |= (uint32_t)tmp[3] << 0; + return ret; +} +uint64_t mvhd_from_be64(uint64_t val) { + uint8_t *tmp = (uint8_t*)&val; + uint64_t ret = 0; + ret = (uint64_t)tmp[0] << 56; + ret |= (uint64_t)tmp[1] << 48; + ret |= (uint64_t)tmp[2] << 40; + ret |= (uint64_t)tmp[3] << 32; + ret |= (uint64_t)tmp[4] << 24; + ret |= (uint64_t)tmp[5] << 16; + ret |= (uint64_t)tmp[6] << 8; + ret |= (uint64_t)tmp[7] << 0; + return ret; +} +uint16_t mvhd_to_be16(uint16_t val) { + uint16_t ret = 0; + uint8_t *tmp = (uint8_t*)&ret; + tmp[0] = (val & 0xff00) >> 8; + tmp[1] = (val & 0x00ff) >> 0; + return ret; +} +uint32_t mvhd_to_be32(uint32_t val) { + uint32_t ret = 0; + uint8_t *tmp = (uint8_t*)&ret; + tmp[0] = (val & 0xff000000) >> 24; + tmp[1] = (val & 0x00ff0000) >> 16; + tmp[2] = (val & 0x0000ff00) >> 8; + tmp[3] = (val & 0x000000ff) >> 0; + return ret; +} +uint64_t mvhd_to_be64(uint64_t val) { + uint64_t ret = 0; + uint8_t *tmp = (uint8_t*)&ret; + tmp[0] = (uint8_t)((val & 0xff00000000000000) >> 56); + tmp[1] = (uint8_t)((val & 0x00ff000000000000) >> 48); + tmp[2] = (uint8_t)((val & 0x0000ff0000000000) >> 40); + tmp[3] = (uint8_t)((val & 0x000000ff00000000) >> 32); + tmp[4] = (uint8_t)((val & 0x00000000ff000000) >> 24); + tmp[5] = (uint8_t)((val & 0x0000000000ff0000) >> 16); + tmp[6] = (uint8_t)((val & 0x000000000000ff00) >> 8); + tmp[7] = (uint8_t)((val & 0x00000000000000ff) >> 0); + return ret; +} + +bool mvhd_is_conectix_str(const void* buffer) { + if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) { + return true; + } else { + return false; + } +} + +void mvhd_generate_uuid(uint8_t* uuid) +{ + /* We aren't doing crypto here, so using system time as seed should be good enough */ + srand((unsigned int)time(0)); + for (int n = 0; n < 16; n++) { + uuid[n] = rand(); + } + uuid[6] &= 0x0F; + uuid[6] |= 0x40; /* Type 4 */ + uuid[8] &= 0x3F; + uuid[8] |= 0x80; /* Variant 1 */ +} + +uint32_t vhd_calc_timestamp(void) +{ + time_t start_time; + time_t curr_time; + double vhd_time; + start_time = MVHD_START_TS; /* 1 Jan 2000 00:00 */ + curr_time = time(NULL); + vhd_time = difftime(curr_time, start_time); + return (uint32_t)vhd_time; +} + +uint32_t mvhd_epoch_to_vhd_ts(time_t ts) { + time_t start_time = MVHD_START_TS; + if (ts < start_time) { + return start_time; + } + double vhd_time = difftime(ts, start_time); + return (uint32_t)vhd_time; +} + +time_t vhd_get_created_time(MVHDMeta *vhdm) +{ + time_t vhd_time = (time_t)vhdm->footer.timestamp; + time_t vhd_time_unix = MVHD_START_TS + vhd_time; + return vhd_time_unix; +} + +FILE* mvhd_fopen(const char* path, const char* mode, int* err) { + FILE* f = NULL; +#ifdef _WIN32 + size_t path_len = strlen(path); + size_t mode_len = strlen(mode); + mvhd_utf16 new_path[260] = {0}; + int new_path_len = (sizeof new_path) - 2; + mvhd_utf16 mode_str[5] = {0}; + int new_mode_len = (sizeof mode_str) - 2; + int path_res = UTF8ToUTF16LE((unsigned char*)new_path, &new_path_len, (const unsigned char*)path, (int*)&path_len); + int mode_res = UTF8ToUTF16LE((unsigned char*)mode_str, &new_mode_len, (const unsigned char*)mode, (int*)&mode_len); + if (path_res > 0 && mode_res > 0) { + int wfopen_err = _wfopen_s(&f, new_path, mode_str); + if (wfopen_err != 0 || f == NULL) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + } + } else { + if (path_res == -1 || mode_res == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (path_res == -2 || mode_res == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } + } +#else + f = fopen64(path, mode); + if (f == NULL) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + } +#endif + return f; +} + +void mvhd_set_encoding_err(int encoding_retval, int* err) { + if (encoding_retval == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (encoding_retval == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } +} + +uint64_t mvhd_calc_size_bytes(MVHDGeom *geom) { + uint64_t img_size = (uint64_t)geom->cyl * (uint64_t)geom->heads * (uint64_t)geom->spt * (uint64_t)MVHD_SECTOR_SIZE; + return img_size; +} + +uint32_t mvhd_calc_size_sectors(MVHDGeom *geom) { + uint32_t sector_size = (uint32_t)geom->cyl * (uint32_t)geom->heads * (uint32_t)geom->spt; + return sector_size; +} + +MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm) { + MVHDGeom geometry = { .cyl = vhdm->footer.geom.cyl, .heads = vhdm->footer.geom.heads, .spt = vhdm->footer.geom.spt }; + return geometry; +} + +uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer) { + uint32_t new_chk = 0; + uint32_t orig_chk = footer->checksum; + footer->checksum = 0; + uint8_t* footer_bytes = (uint8_t*)footer; + for (size_t i = 0; i < sizeof *footer; i++) { + new_chk += footer_bytes[i]; + } + footer->checksum = orig_chk; + return ~new_chk; +} + +uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader* header) { + uint32_t new_chk = 0; + uint32_t orig_chk = header->checksum; + header->checksum = 0; + uint8_t* sparse_bytes = (uint8_t*)header; + for (size_t i = 0; i < sizeof *header; i++) { + new_chk += sparse_bytes[i]; + } + header->checksum = orig_chk; + return ~new_chk; +} + +const char* mvhd_strerr(MVHDError err) { + switch (err) { + case MVHD_ERR_MEM: + return "memory allocation error"; + case MVHD_ERR_FILE: + return "file error"; + case MVHD_ERR_NOT_VHD: + return "file is not a VHD image"; + case MVHD_ERR_TYPE: + return "unsupported VHD image type"; + case MVHD_ERR_FOOTER_CHECKSUM: + return "invalid VHD footer checksum"; + case MVHD_ERR_SPARSE_CHECKSUM: + return "invalid VHD sparse header checksum"; + case MVHD_ERR_UTF_TRANSCODING_FAILED: + return "error converting path encoding"; + case MVHD_ERR_UTF_SIZE: + return "buffer size mismatch when converting path encoding"; + case MVHD_ERR_PATH_REL: + return "relative path detected where absolute path expected"; + case MVHD_ERR_PATH_LEN: + return "path length exceeds MVHD_MAX_PATH"; + case MVHD_ERR_PAR_NOT_FOUND: + return "parent VHD image not found"; + case MVHD_ERR_INVALID_PAR_UUID: + return "UUID mismatch between child and parent VHD"; + case MVHD_ERR_INVALID_GEOM: + return "invalid geometry detected"; + case MVHD_ERR_INVALID_SIZE: + return "invalid size"; + case MVHD_ERR_INVALID_BLOCK_SIZE: + return "invalid block size"; + case MVHD_ERR_INVALID_PARAMS: + return "invalid parameters passed to function"; + case MVHD_ERR_CONV_SIZE: + return "error converting image. Size mismatch detechted"; + default: + return "unknown error"; + } +} + +int64_t mvhd_ftello64(FILE* stream) +{ +#ifdef _MSC_VER + return _ftelli64(stream); +#else + return ftello64(stream); +#endif +} + +int mvhd_fseeko64(FILE* stream, int64_t offset, int origin) +{ +#ifdef _MSC_VER + return _fseeki64(stream, offset, origin); +#else + return fseeko64(stream, offset, origin); +#endif +} + +uint32_t mvhd_crc32_for_byte(uint32_t r) { + for (int j = 0; j < 8; ++j) + r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; + return r ^ (uint32_t)0xFF000000L; +} + +uint32_t mvhd_crc32(const void* data, size_t n_bytes) { + static uint32_t table[0x100]; + if (!*table) + for (size_t i = 0; i < 0x100; ++i) + table[i] = mvhd_crc32_for_byte(i); + + uint32_t crc = 0; + for (size_t i = 0; i < n_bytes; ++i) + crc = table[(uint8_t)crc ^ ((uint8_t*)data)[i]] ^ crc >> 8; + + return crc; +} + +uint32_t mvhd_file_mod_timestamp(const char* path, int *err) { + *err = 0; +#ifdef _WIN32 + struct _stat file_stat; + size_t path_len = strlen(path); + mvhd_utf16 new_path[260] = {0}; + int new_path_len = (sizeof new_path) - 2; + int path_res = UTF8ToUTF16LE((unsigned char*)new_path, &new_path_len, (const unsigned char*)path, (int*)&path_len); + if (path_res > 0) { + int stat_res = _wstat(new_path, &file_stat); + if (stat_res != 0) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + return 0; + } + return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); + } else { + if (path_res == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (path_res == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } + return 0; + } +#else + struct stat file_stat; + int stat_res = stat(path, &file_stat); + if (stat_res != 0) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + return 0; + } + return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); +#endif +} diff --git a/src/minivhd/minivhd_util.h b/src/minivhd/minivhd_util.h new file mode 100644 index 0000000..df68410 --- /dev/null +++ b/src/minivhd/minivhd_util.h @@ -0,0 +1,136 @@ +#ifndef MINIVHD_UTIL_H +#define MINIVHD_UTIL_H + +#include +#include +#include +#include "minivhd_internal.h" +#include "minivhd.h" +#define MVHD_START_TS 946684800 + +/** + * Functions to deal with endian issues + */ +uint16_t mvhd_from_be16(uint16_t val); +uint32_t mvhd_from_be32(uint32_t val); +uint64_t mvhd_from_be64(uint64_t val); +uint16_t mvhd_to_be16(uint16_t val); +uint32_t mvhd_to_be32(uint32_t val); +uint64_t mvhd_to_be64(uint64_t val); + +/** + * \brief Check if provided buffer begins with the string "conectix" + * + * \param [in] buffer The buffer to compare. Must be at least 8 bytes in length + * + * \return true if the buffer begins with "conectix" + * \return false if the buffer does not begin with "conectix" + */ +bool mvhd_is_conectix_str(const void* buffer); + +/** + * \brief Generate a raw 16 byte UUID + * + * \param [out] uuid A 16 byte buffer in which the generated UUID will be stored to + */ +void mvhd_generate_uuid(uint8_t *uuid); + +/** + * \brief Calculate a VHD formatted timestamp from the current time + */ +uint32_t vhd_calc_timestamp(void); + +/** + * \brief Convert an epoch timestamp to a VHD timestamp + * + * \param [in] ts epoch timestamp to convert. + * + * \return The adjusted timestamp, or 0 if the input timestamp is + * earlier that 1 Janurary 2000 + */ +uint32_t mvhd_epoch_to_vhd_ts(time_t ts); + +/** + * \brief Return the created time from a VHD image + * + * \param [in] vhdm Pointer to the MiniVHD metadata structure + * + * \return The created time, as a Unix timestamp + */ +time_t vhd_get_created_time(MVHDMeta *vhdm); + +/** + * \brief Cross platform, unicode filepath opening + * + * This function accounts for the fact that fopen() handles file paths differently compared to other + * operating systems. Windows version of fopen() will not handle multi byte encoded text like UTF-8. + * + * Unicode filepath support on Windows requires using the _wfopen() function, which expects UTF-16LE + * encoded path and modestring. + * + * \param [in] path The filepath to open as a UTF-8 string + * \param [in] mode The mode string to use (eg: "rb+"") + * \param [out] err The error value, if an error occurrs + * + * \return a FILE pointer if successful, NULL otherwise. If NULL, check the value of err + */ +FILE* mvhd_fopen(const char* path, const char* mode, int* err); + +void mvhd_set_encoding_err(int encoding_retval, int* err); +uint64_t mvhd_calc_size_bytes(MVHDGeom *geom); +uint32_t mvhd_calc_size_sectors(MVHDGeom *geom); +MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm); + +/** + * \brief Generate VHD footer checksum + * + * \param [in] vhdm MiniVHD data structure + */ +uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer); + +/** + * \brief Generate VHD sparse header checksum + * + * \param [in] vhdm MiniVHD data structure + */ +uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader* header); + +/** + * \brief Get current position in file stream + * + * This is a portable version of the POSIX ftello64(). * + */ +int64_t mvhd_ftello64(FILE* stream); + +/** + * \brief Reposition the file stream's position + * + * This is a portable version of the POSIX fseeko64(). * + */ +int mvhd_fseeko64(FILE* stream, int64_t offset, int origin); + +/** + * \brief Calculate the CRC32 of a data buffer. + * + * This function can be used for verifying data integrity. + * + * \param [in] data The data buffer + * \param [in] n_bytes The size of the data buffer in bytes + * + * \return The CRC32 of the data buffer + */ +uint32_t mvhd_crc32(const void* data, size_t n_bytes); + +/** + * \brief Calculate the file modification timestamp. + * + * This function is primarily to help protect differencing VHD's + * + * \param [in] path the UTF-8 file path + * \param [out] err The error value, if an error occurrs + * + * \return The file modified timestamp, in VHD compatible timestamp. + * 'err' will be set to non-zero on error + */ +uint32_t mvhd_file_mod_timestamp(const char* path, int *err); +#endif diff --git a/src/pc.xrc b/src/pc.xrc index 9db0ca0..400842d 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -2838,13 +2838,39 @@ 0 1 + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + wxALIGN_CENTER_VERTICAL|wxALL 5 80,-1 - + -1 @@ -2853,7 +2879,6 @@ wxALL 5 - 350,-1 @@ -2987,6 +3012,32 @@ 5 0,0 + + + wxALL | wxALIGN_CENTER_VERTICAL + 5 + + + -1 + + + + + wxALL + 5 + + + 350,-1 + + + + + + + wxEXPAND + 5 + 0,0 + diff --git a/src/resources.h b/src/resources.h index 66c4a74..02b4772 100644 --- a/src/resources.h +++ b/src/resources.h @@ -124,6 +124,7 @@ #define IDC_EDIT_F_FN 1233 #define IDC_HDTYPE 1280 +#define IDC_HDFORMAT 1281 #define IDC_CONFIGUREVID 1200 #define IDC_CONFIGURESND 1201 diff --git a/src/wx-config.c b/src/wx-config.c index 3d253ed..a35f8da 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -20,6 +20,9 @@ #include "video.h" #include "vid_voodoo.h" +#include "MiniVHD/minivhd.h" +#include "MiniVHD/minivhd_util.h" + //#define MAX_CYLINDERS ((((1 << 28)-1) / 16) / 63) #define MAX_CYLINDERS 265264 /*Award 430VX won't POST with a larger drive*/ extern int pause; @@ -84,7 +87,7 @@ static void recalc_fpu_list(void *hdlg, int model, int manu, int cpu, int fpu) { void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); int c = 0; - + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); @@ -117,7 +120,7 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - + if (model_has_fixed_gfx(model)) { wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Built-in video"); @@ -139,10 +142,10 @@ static void recalc_vid_list(void* hdlg, int model, int force_builtin_video) } d++; } - + if (cur_gfxcard == GFX_BUILTIN && !model_has_fixed_gfx(model) && !model_has_optional_gfx(model)) cur_gfxcard = 0; - + while (1) { char *s = video_card_getname(c); @@ -297,7 +300,7 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); hdd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); h = wx_getdlgitem(hdlg, WX_ID("IDC_HDCBOOK")); - + while (wx_sendmessage(h, WX_CHB_GETPAGECOUNT, 0, 0)) wx_sendmessage(h, WX_CHB_REMOVEPAGE, 0, 0); @@ -305,20 +308,20 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for { void *page; char s[80]; - + sprintf(s, "IDC_HDPANEL[%i]", c); - + page = wx_getdlgitem(hdlg, WX_ID(s)); wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); wx_sendmessage(h, WX_CHB_ADDPAGE, (LONG_PARAM)page, (LONG_PARAM)"dummy name"); - } + } if (hdd_controller_is_scsi(hdd_names[hdd_type])) - { + { for (c = 0; c < 7; c++) { void *page; char s[80]; - + sprintf(s, "IDC_HDPANEL[%i]", c); page = wx_getdlgitem(hdlg, WX_ID(s)); wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); @@ -350,7 +353,7 @@ static void recalc_hdd_list(void* hdlg, int model, int use_selected_hdd, int for { void *page; char s[80]; - + sprintf(s, "IDC_HDPANEL[%i]", c); page = wx_getdlgitem(hdlg, WX_ID(s)); wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); @@ -426,11 +429,11 @@ static void recalc_cd_list(void *hdlg, int cur_speed, char *cur_model) { char s[8]; int speed; - + speed = cd_get_speed(c); sprintf(s, "%iX", speed); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - + if (speed == cur_speed) { wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); @@ -567,7 +570,7 @@ int config_dlgsave(void* hdlg) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; @@ -582,7 +585,7 @@ int config_dlgsave(void* hdlg) #ifdef USE_NETWORKING h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; -#endif +#endif if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_fpu != fpu_type || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || @@ -945,13 +948,13 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) hd_changed = 0; new_cdrom_channel = cdrom_channel; new_zip_channel = zip_channel; - + hdconf_init(hdlg); - + for (c = 0; c < 7; c++) { char s[80]; - + sprintf(s, "IDC_COMBODRIVETYPE[%i]", c); h = wx_getdlgitem(hdlg, WX_ID(s)); wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); @@ -964,7 +967,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); } - + recalc_cd_list(hdlg, cd_speed, cd_model); #ifdef USE_NETWORKING @@ -984,15 +987,15 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { if (wParam == WX_ID("IDC_COMBO1")) { - int force_ide = 0; + int force_ide = 0; int force_builtin_video = 0; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - + if (temp_model == prev_model) break; - + if ((models[temp_model].flags & MODEL_HAS_IDE) && !(models[prev_model].flags & MODEL_HAS_IDE)) force_ide = 1; if (model_has_optional_gfx(temp_model)) @@ -1037,7 +1040,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); - + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); @@ -1300,7 +1303,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); if (network_card_has_config(temp_network_card)) wx_enablewindow(h, TRUE); @@ -1311,14 +1314,14 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); } #endif else if (wParam == WX_ID("IDC_COMBOJOY")) { int temp_joystick_type; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); @@ -1334,7 +1337,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_JOY1")) { int temp_joystick_type; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 0, temp_joystick_type); @@ -1342,7 +1345,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_JOY2")) { int temp_joystick_type; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 1, temp_joystick_type); @@ -1350,7 +1353,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_JOY3")) { int temp_joystick_type; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 2, temp_joystick_type); @@ -1358,7 +1361,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) else if (wParam == WX_ID("IDC_JOY4")) { int temp_joystick_type; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 3, temp_joystick_type); @@ -1370,7 +1373,7 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) int mem; int granularity; int granularity_mask; - + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; @@ -1558,7 +1561,7 @@ static void update_hdd_cdrom(void* hdlg) } static volatile int create_drive_pos; -static int create_drive(void* data) +static int create_drive_raw(void* data) { int c; uint8_t buf[512]; @@ -1575,6 +1578,134 @@ static int create_drive(void* data) return 1; } +static void vhd_progress_callback(uint32_t current_sector, uint32_t total_sectors) +{ + create_drive_pos = (int)current_sector; +} + +/* If the disk geometry requested in the PCem GUI is not compatible with the internal VHD geometry, + * we adjust it to the next-largest size that is compatible. On average, this will be a difference + * of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more + * than a tenth of a percent change in size. + */ +static void adjust_pcem_geometry_for_vhd(MVHDGeom *vhd_geometry) +{ + if (hd_new_cyl <= 65535) + return; + + int desired_sectors = hd_new_cyl * hd_new_hpc * hd_new_spt; + if (desired_sectors > 267321600) + desired_sectors = 267321600; + + int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ + if (remainder > 0) + desired_sectors += (85680 - remainder); + + hd_new_cyl = desired_sectors / (16 * 63); + hd_new_hpc = 16; + hd_new_spt = 63; + + vhd_geometry->cyl = desired_sectors / (16 * 255); + vhd_geometry->heads = 16; + vhd_geometry->spt = 255; +} + +static void adjust_vhd_geometry_for_pcem() +{ + if (hd_new_spt <= 63) + return; + + int desired_sectors = hd_new_cyl * hd_new_hpc * hd_new_spt; + if (desired_sectors > 267321600) + desired_sectors = 267321600; + + int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ + if (remainder > 0) + desired_sectors -= remainder; + + hd_new_cyl = desired_sectors / (16 * 63); + hd_new_hpc = 16; + hd_new_spt = 63; +} + +static int create_drive_vhd_fixed(void *data) +{ + MVHDGeom geometry = { .cyl = hd_new_cyl, .heads = hd_new_hpc, .spt = hd_new_spt }; + adjust_pcem_geometry_for_vhd(&geometry); + + int vhd_error = 0; + MVHDMeta *vhd = mvhd_create_fixed(hd_new_name, geometry, &vhd_error, vhd_progress_callback); + if (vhd == NULL) + { + return 0; + } + else + { + mvhd_close(vhd); + return 1; + } +} + +static int create_drive_vhd_dynamic(int blocksize) +{ + MVHDGeom geometry = { .cyl = hd_new_cyl, .heads = hd_new_hpc, .spt = hd_new_spt }; + adjust_pcem_geometry_for_vhd(&geometry); + int vhd_error = 0; + MVHDCreationOptions options; + options.block_size_in_sectors = blocksize; + options.path = hd_new_name; + options.size_in_bytes = 0; + options.geometry = geometry; + options.type = MVHD_TYPE_DYNAMIC; + + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + if (vhd == NULL) + { + return 0; + } + else + { + mvhd_close(vhd); + return 1; + } +} + +static int create_drive_vhd_diff(char* parent_filename, int blocksize) +{ + int vhd_error = 0; + MVHDCreationOptions options; + options.block_size_in_sectors = blocksize; + options.path = hd_new_name; + options.parent_path = parent_filename; + options.type = MVHD_TYPE_DIFF; + + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + if (vhd == NULL) + { + return 0; + } + else + { + MVHDGeom vhd_geom = mvhd_get_geometry(vhd); + + if (vhd_geom.spt > 63) + { + hd_new_cyl = mvhd_calc_size_sectors(&vhd_geom) / (16 * 63); + hd_new_hpc = 16; + hd_new_spt = 63; + } + else + { + hd_new_cyl = vhd_geom.cyl; + hd_new_hpc = vhd_geom.heads; + hd_new_spt = vhd_geom.spt; + } + + mvhd_close(vhd); + return 1; + } +} + static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { char s[260]; @@ -1582,7 +1713,7 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l int c; PcemHDC hd[7]; FILE *f; - int hd_type; + int hd_type, hd_format, hd_blocksize; int size; switch (message) @@ -1615,6 +1746,22 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l } wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Raw (.img)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Fixed-size VHD (.vhd)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Dynamic-size VHD (.vhd)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Differencing VHD (.vhd)"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Large blocks (2 MB)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Small blocks (512 KB)"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)" "); + return TRUE; case WX_COMMAND: if (wParam == wxID_OK) { @@ -1653,13 +1800,49 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l return TRUE; } - f = fopen64(hd_new_name, "wb"); - if (!f) + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + hd_blocksize = (wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0) == 0) ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; + + if (hd_format == 0) /* Raw .img */ { - wx_messagebox(hdlg, "Can't open file for write", "PCem error", WX_MB_OK); - return TRUE; + f = fopen64(hd_new_name, "wb"); + if (!f) + { + wx_messagebox(hdlg, "Can't open file for write", "PCem error", WX_MB_OK); + return TRUE; + } + wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive_raw, f, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos); + } + else if (hd_format == 1) /* Fixed VHD */ + { + if (!wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive_vhd_fixed, NULL, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos)) + { + wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); + return TRUE; + } + } + else if (hd_format == 2) /* Dynamic VHD */ + { + if (!create_drive_vhd_dynamic(hd_blocksize)) + { + wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); + return TRUE; + } + } + else if (hd_format == 3) /* Differencing VHD */ + { + if (!getfilewithcaption(hdlg, "VHD file (*.vhd)|*.vhd|All files (*.*)|*.*", "", "Select the parent VHD")) + { + if (!create_drive_vhd_diff(openfilestring, hd_blocksize)) + { + wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); + return TRUE; + } + } } - wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive, f, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos); wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", WX_MB_OK); @@ -1669,7 +1852,13 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l wx_enddialog(hdlg, 0); return TRUE; } else if (ID_IS("IDC_CFILE")) { - if (!getsfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "", NULL, "img")) + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (!getsfile(hdlg, + hd_format == 0 ? "Raw Hard disc image (*.img)|*.img|All files (*.*)|*.*" : "VHD file (*.vhd)|*.vhd|All files (*.*)|*.*", + "", + NULL, + hd_format == 0 ? "img" : "vhd")) { h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) openfilestring); @@ -1749,6 +1938,68 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l } return TRUE; } + else if (ID_IS("IDC_HDFORMAT")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hd_format == 3) /* They switched to a dynamic VHD; disable the geometry fields. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + } + else /* Restore geometry fields if necessary. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 0, (LONG_PARAM)s); + if (!strncmp(s, "(use parent)", 12)) + { + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"63"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"16"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"511"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"251"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + } + } + + if (hd_format == 2 || hd_format == 3) /* For dynamic and diff VHDs, show the block size dropdown. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"Block size:"); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)1); + } + else /* Hide it otherwise. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)" "); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)0); + } + + return TRUE; + } break; } @@ -1848,12 +2099,12 @@ static int hdsize_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM int hdconf_init(void* hdlg) { int c; - + for (c = 0; c < 7; c++) { char s[260]; void *h; - + sprintf(s, "IDC_EDIT_SPT[%i]", c); h = wx_getdlgitem(hdlg, WX_ID(s)); sprintf(s, "%i", hdc[c].spt); @@ -1899,7 +2150,7 @@ int hdconf_update(void* hdlg) wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); } - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); if (hdd_controller_selected_has_config(hdlg)) wx_enablewindow(h, TRUE); else @@ -1911,7 +2162,7 @@ int hdconf_update(void* hdlg) static int hd_eject(void *hdlg, int drive) { char s[80]; - + ide_fn[drive][0] = 0; sprintf(s, "IDC_EDIT_SPT[%i]", drive); wx_setdlgitemtext(hdlg, WX_ID(s), "0"); @@ -1922,7 +2173,7 @@ static int hd_eject(void *hdlg, int drive) sprintf(s, "IDC_EDIT_FN[%i]", drive); wx_setdlgitemtext(hdlg, WX_ID(s), ""); hd_changed = 1; - + return TRUE; } @@ -1933,7 +2184,7 @@ static int hd_new(void *hdlg, int drive) char s[80]; char id[80]; void *h; - + sprintf(id, "IDC_EDIT_SPT[%i]", drive); h = wx_getdlgitem(hdlg, WX_ID(id)); sprintf(s, "%i", hd_new_spt); @@ -1962,7 +2213,7 @@ static int hd_new(void *hdlg, int drive) static int hd_file(void *hdlg, int drive) { - if (!getfile(hdlg, "Hard disc image (*.img)|*.img|All files (*.*)|*.*", "")) + if (!getfile(hdlg, "Hard disc image (*.img;*.vhd)|*.img;*.vhd|All files (*.*)|*.*", "")) { off64_t sz; FILE *f = fopen64(openfilestring, "rb"); @@ -1971,17 +2222,64 @@ static int hd_file(void *hdlg, int drive) wx_messagebox(hdlg,"Can't open file for read","PCem error",WX_MB_OK); return TRUE; } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(hdlg, sz); + + if (mvhd_file_is_vhd(f)) + { + fclose(f); + int vhdError = 0; + MVHDMeta *vhd = mvhd_open(openfilestring, false, &vhdError); + if (vhd == NULL) + { + wx_messagebox(hdlg,mvhd_strerr(vhdError),"PCem error",WX_MB_OK); + return TRUE; + } + else if (vhdError == MVHD_ERR_TIMESTAMP) + { + const char ts_warning[] = + "WARNING: VHD PARENT/CHILD TIMESTAMPS DO NOT MATCH!\n\n" + "This could indicate that the parent image was modified after this VHD was created.\n\n" + "This could also happen if the VHD files were moved/copied, or the differencing VHD was created with DiskPart.\n\n" + "Do you wish to fix this error after a file copy or DiskPart creation?"; + int wx_res = wx_messagebox(hdlg,ts_warning,"PCem error", WX_MB_NODEFAULT); + if (wx_res == WX_MB_YES) + { + int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhdError); + if (ts_res != 0) + { + wx_messagebox(hdlg,"Can't fix VHD timestamps","PCem error",WX_MB_OK); + mvhd_close(vhd); + return TRUE; + } + } + else + { + mvhd_close(vhd); + return TRUE; + } + + } + MVHDGeom geom = mvhd_get_geometry(vhd); + hd_new_cyl = geom.cyl; + hd_new_hpc = geom.heads; + hd_new_spt = geom.spt; + hd_new_type = 0; + adjust_vhd_geometry_for_pcem(); + mvhd_close(vhd); + } + else + { + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + } if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) { char s[80]; char id[80]; void *h; - + sprintf(id, "IDC_EDIT_SPT[%i]", drive); h = wx_getdlgitem(hdlg, WX_ID(id)); sprintf(s, "%i", hd_new_spt); @@ -2015,7 +2313,7 @@ static int hd_edit(void *hdlg, int drive) char id[80]; void *h; int spt, hpc, tracks; - + sprintf(id, "IDC_EDIT_SPT[%i]", drive); h = wx_getdlgitem(hdlg, WX_ID(id)); wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); @@ -2033,7 +2331,7 @@ static int hd_edit(void *hdlg, int drive) h = wx_getdlgitem(hdlg, WX_ID(id)); sprintf(s, "%imb", ((((tracks*hpc)*spt)*512)/1024)/1024); wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - + return TRUE; } diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 6ed31ee..6d1fa79 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -1784,7 +1784,7 @@ static unsigned char xml_res_file_25[] = { 87,93,129,205,251,40,255,176,89,15,134,167,154,149,127,4,24,0,227,17,114, 29,252,169,144,138,0,0,0,0,73,69,78,68,174,66,96,130}; -static size_t xml_res_size_26 = 141099; +static size_t xml_res_size_26 = 142917; static unsigned char xml_res_file_26[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,33,45,45, @@ -6653,105 +6653,174 @@ static unsigned char xml_res_file_26[] = { 97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, 111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, -69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, -97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,115,105,122,101,62,56,48,44,45,49,60,47,115,105,122,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,70,105,108,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114, -97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, -48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69, -68,73,84,67,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,109,97,103,101,32,70,111, +114,109,97,116,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,70,79, +82,77,65,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,48, +44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,70,105,108,101,58,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,67,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45, +49,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,73,68,67,95,67,70,73,76,69,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85, +95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, +45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, +95,49,54,120,49,54,95,102,111,108,100,101,114,46,112,110,103,60,47,98,105, +116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -67,70,73,76,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,49,54,120,49,54,95,102,111,108, -100,101,114,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, -111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, -111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, -105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60, -47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, -62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, -101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, -99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47, -119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, +114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72, +101,97,100,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119, +114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, 116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, 114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, 61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, -73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -6766,7 +6835,346 @@ static unsigned char xml_res_file_26[] = { 101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, 105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,108,105,110,100,101,114, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,105,122,101,32,40,77,66,41,58,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,52,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65, +68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,73,68,67,95,72,68,66,76,79,67,75,83,73,90,69,76,65,66,69,76,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +66,108,111,99,107,32,115,105,122,101,58,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, +60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73,68, +67,95,72,68,66,76,79,67,75,83,73,90,69,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97, +110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, +108,111,103,34,32,110,97,109,101,61,34,72,100,83,105,122,101,68,108,103, +34,62,10,32,32,32,32,60,116,105,116,108,101,62,72,97,114,100,32,68,105, +115,99,32,80,97,114,97,109,101,116,101,114,115,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101, +110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,32,124, +32,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,73,110,105,116,105,97,108,32,115,101,116, +116,105,110,103,115,32,97,114,101,32,98,97,115,101,100,32,111,110,32,102, +105,108,101,32,115,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48, +44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119, +115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,99,116,111,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, +45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,73,68,67,95,69,68,73,84,49,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100, +115,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, +69,68,73,84,50,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,121,108,105,110,100,101,114,115,58,60,47,108, 97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, @@ -6780,7 +7188,7 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, 114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, -116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50, +116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51, 34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, 118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, @@ -6796,99 +7204,91 @@ static unsigned char xml_res_file_26[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, 97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, -108,62,67,121,108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105, -122,101,32,40,77,66,41,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49, -60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +108,62,83,105,122,101,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60, +47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109, +98,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, 111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, -69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, -103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,52,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +60,102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95, -67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, -114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, -109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, -68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60, -47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101, -47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, -116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,73,68,67,95,72,68,84,89,80,69,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,53,48,44,45,49,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108, +117,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114, +105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, 60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, @@ -6897,26 +7297,6 @@ static unsigned char xml_res_file_26[] = { 62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, 32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, -101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101, -110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, -111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, @@ -6950,642 +7330,388 @@ static unsigned char xml_res_file_26[] = { 98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, 10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, 101,99,116,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,72,100,83,105, -122,101,68,108,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,72,97, -114,100,32,68,105,115,99,32,80,97,114,97,109,101,116,101,114,115,60,47, +34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34,67,111,110, +102,105,103,117,114,101,83,101,108,101,99,116,105,111,110,68,108,103,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,32,67,111,110, +102,105,103,117,114,97,116,105,111,110,32,77,97,110,97,103,101,114,60,47, 116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100, 62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, -32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, -108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,60,114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32, -32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, -32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32, -32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32, -32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,47, -62,10,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69,82, -95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116, -105,97,108,32,115,101,116,116,105,110,103,115,32,97,114,101,32,98,97,115, -101,100,32,111,110,32,102,105,108,101,32,115,105,122,101,60,47,108,97,98, -101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114, -111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, -62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, -115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, -119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, -108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111,119, -115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, -115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104, -103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, -114,111,119,97,98,108,101,99,111,108,115,47,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, -115,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, -106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, -109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, -105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,111,114,115,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,73,68,67,95, -69,68,73,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, -95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, -116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,72,101,97,100,115,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114, -97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, -32,110,97,109,101,61,34,73,68,67,95,69,68,73,84,50,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,121, -108,105,110,100,101,114,115,58,60,47,108,97,98,101,108,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62,45, -49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, -47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, -101,61,34,73,68,67,95,69,68,73,84,51,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, -124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, -116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,122,101,58, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, -73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, -53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, -73,68,67,95,84,69,88,84,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,48,109,98,60,47,108,97, -98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,119,114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, -99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,32,124,32,119,120,65,76,73,71,78,95,67,69,78,84,69, -82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, -99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,108,97,98,101,108,62,84,121,112,101,58,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,114,97,112,62, -45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,73, -68,67,95,72,68,84,89,80,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, -87,78,124,119,120,67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108, -101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, -101,62,51,53,48,44,45,49,60,47,115,105,122,101,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,47,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, -105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120, -72,79,82,73,90,79,78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, -122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, -61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,108,97,98,101,108,62,79,75,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, -114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, -97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,99, -101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97,108, -111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,103,117,114,101,83, -101,108,101,99,116,105,111,110,68,108,103,34,62,10,32,32,32,32,60,116,105, -116,108,101,62,80,67,101,109,32,67,111,110,102,105,103,117,114,97,116,105, -111,110,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62,10,32, -32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110,116,101, -114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, -10,32,32,32,32,32,32,60,114,111,119,115,62,49,60,47,114,111,119,115,62, -10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, -32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, -32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32, -32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, -103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, -103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, -97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, -62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62, -10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, -122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62, -50,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, -108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, -60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, -32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, -60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, -47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, -65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, -82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112, -116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, -61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73,78, -71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,53,48,44,51,48,48,60,47, -115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, -116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65, -76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, -100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97, -112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, -79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115, -116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,116,111,111,108,116,105,112,62,76,111,97,100,60,47,116,111,111,108, -116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, -46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,110,116, -114,111,108,95,112,108,97,121,95,98,108,117,101,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, -76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -116,111,111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,60,47, -116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117, -114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95, -115,101,116,116,105,110,103,95,116,111,111,108,115,46,112,110,103,60,47, -98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, -47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, -60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, -116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,71, -95,72,79,83,84,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, -60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,111,110,102,105,103, -117,114,101,32,72,111,115,116,60,47,116,111,111,108,116,105,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, -112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, -99,111,110,115,95,51,50,120,51,50,95,119,105,100,101,115,99,114,101,101, -110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, -60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, -105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, -102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, -100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,114,111,119,115, +62,49,60,47,114,111,119,115,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,48, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, 32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, -111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, -97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88, +80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,60,114,111,119,115,62,50,60,47,114,111,119,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, -109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95, -78,69,87,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47, -115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,116,111,111,108,116,105,112,62,78,101,119,60,47,116,111,111, -108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109, -112,117,116,101,114,95,97,100,100,46,112,110,103,60,47,98,105,116,109,97, -112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, 116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, 10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, -110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108, -97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, -114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, -115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32, -110,97,109,101,61,34,73,68,67,95,82,69,78,65,77,69,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, -120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,82,101,110,97,109,101,60,47,116,111,111,108,116,105,112,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, -97,112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36, -105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114, -95,101,100,105,116,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, -108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, -97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48, -60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, -101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111, +120,34,32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +53,48,44,51,48,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, 32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, -101,61,34,73,68,67,95,67,79,80,89,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, -84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,111, -112,121,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84, +79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,76,111, +97,100,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, 101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, -50,120,51,50,95,99,111,109,112,117,116,101,114,95,103,111,46,112,110,103, -60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97, -117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, -105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, -99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117, -116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,68,69,76,69,84,69, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, -121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121, -108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -116,111,111,108,116,105,112,62,68,101,108,101,116,101,60,47,116,111,111, -108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101, -115,46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109, -112,117,116,101,114,95,100,101,108,101,116,101,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, +50,120,51,50,95,99,111,110,116,114,111,108,95,112,108,97,121,95,98,108, +117,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62, +49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84, +79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,111, +110,102,105,103,117,114,101,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97, +112,62,119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105, +99,111,110,115,95,51,50,120,51,50,95,115,101,116,116,105,110,103,95,116, +111,111,108,115,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,78,70,73,71,95,72,79,83,84,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,67,111,110,102,105,103,117,114,101,32,72,111,115, +116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114,101, +115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51,50, +120,51,50,95,119,105,100,101,115,99,114,101,101,110,46,112,110,103,60,47, +98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, 98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, 106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, 99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, 99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47, +32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47, 111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, -108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, -101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, -116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, -76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, -105,112,62,81,117,105,116,60,47,116,111,111,108,116,105,112,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120, -45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115, -95,51,50,120,51,50,95,100,111,111,114,95,105,110,46,112,110,103,60,47,98, -105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, -101,102,97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, -32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111, -98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,60,47,111,98,106,101,99,116,62,10,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, -101,61,34,83,104,97,100,101,114,77,97,110,97,103,101,114,68,108,103,34, -62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84, -95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,83,84,65,89,95,79,78, -95,84,79,80,60,47,115,116,121,108,101,62,10,32,32,32,32,60,116,105,116, -108,101,62,80,67,101,109,32,83,104,97,100,101,114,32,77,97,110,97,103,101, -114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114, -101,100,62,49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, -108,34,32,110,97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32, -32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, -120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111, -98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, -101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, -120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60, -98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, -32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, -119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78, -84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, -101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48, -60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, -115,116,66,111,120,34,32,110,97,109,101,61,34,73,68,67,95,76,73,83,84,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, -101,62,119,120,76,66,95,83,73,78,71,76,69,60,47,115,116,121,108,101,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, -51,48,48,44,51,53,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,105,116,109,97,112,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,73,68,67,95,78,69,87,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,78,101,119,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,97,100, +100,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, -62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, -66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, -65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, -105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102, -108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60, -47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, -60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,82,69,77,79,86,69,34,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, -62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116, +105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68, +67,95,82,69,78,65,77,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68, +82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,110,97, +109,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62,119,120,45,114, +101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111,110,115,95,51, +50,120,51,50,95,99,111,109,112,117,116,101,114,95,101,100,105,116,46,112, +110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,80, +89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,67,111,112,121,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,99,111,109,112, +117,116,101,114,95,103,111,46,112,110,103,60,47,98,105,116,109,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,73,68,67,95,68,69,76,69,84,69,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95, +65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62, +68,101,108,101,116,101,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109,97,112,62, +119,120,45,114,101,115,111,117,114,99,101,115,46,99,112,112,36,105,99,111, +110,115,95,51,50,120,51,50,95,99,111,109,112,117,116,101,114,95,100,101, +108,101,116,101,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79, +68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,81,117,105,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,105,116,109,97,112,62,119,120,45,114,101,115,111,117,114,99,101,115, +46,99,112,112,36,105,99,111,110,115,95,51,50,120,51,50,95,100,111,111,114, +95,105,110,46,112,110,103,60,47,98,105,116,109,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,97,108,111,103,34,32,110,97,109,101,61,34,83,104,97,100,101,114, +77,97,110,97,103,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,32,83,104, +97,100,101,114,32,77,97,110,97,103,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60,47,99,101,110, +116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,82, +79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111,114,105, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97, +109,101,61,34,73,68,67,95,76,73,83,84,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,83,73, +78,71,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,48,48,44,51,53,48,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105, +101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110, 116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, +95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67,95,67,79,78, +70,73,71,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,102,105,103,117,114,101,46,46, +46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,85,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,111,118,101,32,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118, +101,32,100,111,119,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, 110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, 68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, @@ -7597,135 +7723,91 @@ static unsigned char xml_res_file_26[] = { 60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, 32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, -109,101,61,34,73,68,67,95,67,79,78,70,73,71,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, -110,102,105,103,117,114,101,46,46,46,60,47,108,97,98,101,108,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, -116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, -114,62,48,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, -61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,73,68,67, -95,77,79,86,69,95,85,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,118,101,32,117,112, -60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,112,112, +108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,77,79,86,69,95,68,79,87,78,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,77,111,118,101,32,100,111,119,110,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101, -114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, -112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, -69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, -76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, -32,110,97,109,101,61,34,73,68,67,95,65,80,80,76,89,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, -65,112,112,108,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, -32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, -62,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98, -111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, -117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, -62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, -97,98,101,108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, -62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, -99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, -119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111, -114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, -116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, -76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -60,108,97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, -101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, -111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, -106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, -62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, -47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105, -97,108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82, -101,109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121, -108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, -76,69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108, -101,62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116, -105,116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62, -49,60,47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106, -101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, -97,109,101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32, -32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120, -83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101, -110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, -62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, -115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, -32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, -110,62,10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, -88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, -60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, -32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, -34,119,120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, -32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79, -78,84,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, -122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62, -10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116, -109,97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81, -85,69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116, -61,34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47, +100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, 115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, -112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, -102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, 65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, -110,97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76, -34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,97, +108,111,103,34,32,110,97,109,101,61,34,67,111,110,102,105,114,109,82,101, +109,101,109,98,101,114,68,108,103,34,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,83,84,65,89,95,79,78,95,84,79,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,116,105,116,108,101,62,80,67,101,109,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,99,101,110,116,101,114,101,100,62,49,60, +47,99,101,110,116,101,114,101,100,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,82,79,79,84,95,80,65,78,69,76,34,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65, +76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,112,116,105,111,110,62,48,60,47,111,112,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,105,116,109,97,112,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,105,116,109, +97,112,32,115,116,111,99,107,95,105,100,61,34,119,120,65,82,84,95,81,85, +69,83,84,73,79,78,34,32,115,116,111,99,107,95,99,108,105,101,110,116,61, +34,119,120,65,82,84,95,67,77,78,95,68,73,65,76,79,71,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, 108,62,73,68,67,95,67,79,78,70,73,82,77,95,76,65,66,69,76,60,47,108,97, 98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119, 114,97,112,62,45,49,60,47,119,114,97,112,62,10,32,32,32,32,32,32,32,32, diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index aedfb44..3ff93fb 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -761,6 +761,16 @@ int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext) return ret; } +int getfilewithcaption(void* hwnd, char *f, char *fn, char *caption) +{ + int ret = wx_filedialog(hwnd, caption, fn, f, 0, 1, openfilestring); +#ifdef __APPLE__ + /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ + window_doreset = 1; +#endif + return ret; +} + void atapi_close(void) { switch (cdrom_drive) diff --git a/src/wx-sdl2.h b/src/wx-sdl2.h index fdc45ef..233ceab 100644 --- a/src/wx-sdl2.h +++ b/src/wx-sdl2.h @@ -5,6 +5,7 @@ extern "C" { void leave_fullscreen(); int getfile(void* hwnd, char *f, char *fn); int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext); +int getfilewithcaption(void* hwnd, char *f, char *fn, char *caption); void screenshot_taken(unsigned char* rgb, int width, int height); #ifdef __cplusplus diff --git a/src/wx-utils.cc b/src/wx-utils.cc index 561eeea..819475e 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -402,6 +402,21 @@ int wx_sendmessage(void* window, int type, LONG_PARAM param1, LONG_PARAM param2) ((wxWindow *)window)->Reparent((wxWindow *)param1); break; } + case WX_WM_ENABLE: + { + ((wxWindow*)window)->Enable((bool)param2); + break; + } + case WX_WM_SHOW: + { + ((wxWindow*)window)->Show((bool)param2); + break; + } + case WX_WM_LAYOUT: + { + ((wxWindow*)window)->Layout(); + break; + } } ((wxWindow*)window)->Fit(); diff --git a/src/wx-utils.h b/src/wx-utils.h index 945d54f..631f6d1 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -152,9 +152,14 @@ extern void (*wx_idle_func)(void* window, void* event); #define WX_REPARENT 72 +#define WX_WM_ENABLE 80 +#define WX_WM_SHOW 81 +#define WX_WM_LAYOUT 82 +#define WX_MB_YES wxYES #define WX_MB_OK wxOK #define WX_MB_OKCANCEL wxOK|wxCANCEL +#define WX_MB_NODEFAULT wxYES_NO|wxNO_DEFAULT #define WX_IDOK wxOK #define IMAGE_JPG "jpg" From cf33ab6c3997b73bca746058cbdc4a5c17e7955b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 20 Jun 2020 20:22:24 +0100 Subject: [PATCH 0860/1050] Add initial implementation of Intel VS440FX motherboard. As part of this, add dummy Pentium Pro emulation, as well as Intel 440FX chipset, PC87307 SuperIO and Intel 28FB200BX-T Flash. --- src/386_ops.h | 93 +++++++++++++++++++- src/cpu.c | 67 +++++++++++++++ src/cpu.h | 2 + src/cpu_tables.c | 9 ++ src/i440fx.c | 145 ++++++++++++++++++++++++++++++++ src/i440fx.h | 2 + src/ibm.h | 15 ++-- src/intel_flash.c | 210 ++++++++++++++++++++++++++++++++++++---------- src/intel_flash.h | 1 + src/mem_bios.c | 129 +++++++++++++++++----------- src/model.c | 20 +++++ src/nvr.c | 2 + src/pc87307.c | 151 +++++++++++++++++++++++++++++++++ src/pc87307.h | 1 + src/x86_ops.h | 3 + 15 files changed, 750 insertions(+), 100 deletions(-) create mode 100644 src/i440fx.c create mode 100644 src/i440fx.h create mode 100644 src/pc87307.c create mode 100644 src/pc87307.h diff --git a/src/386_ops.h b/src/386_ops.h index 34c7847..e57389e 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -820,7 +820,98 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, }; -OpFn OP_TABLE(286)[1024] = +OpFn OP_TABLE(pentiumpro_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +OpFn OP_TABLE(286)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ diff --git a/src/cpu.c b/src/cpu.c index d69df1f..6601413 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1005,6 +1005,55 @@ void cpu_set() codegen_timing_set(&codegen_timing_k6); break; + case CPU_PENTIUMPRO: + x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 2; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_pentium); + break; + default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } @@ -1526,6 +1575,24 @@ void cpu_CPUID() break; } break; + + case CPU_PENTIUMPRO: + if (!EAX) + { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } + else if (EAX == 1) + { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV; + } + else + EAX = EBX = ECX = EDX = 0; + break; } } diff --git a/src/cpu.h b/src/cpu.h index 4188cff..8341be3 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -41,6 +41,7 @@ extern int fpu_type; #define CPU_K6_3 25 #define CPU_K6_2P 26 #define CPU_K6_3P 27 +#define CPU_PENTIUMPRO 28 #define MANU_INTEL 0 #define MANU_AMD 1 @@ -117,6 +118,7 @@ extern CPU cpus_6x86[]; extern CPU cpus_6x86_SS7[]; extern CPU cpus_K6_S7[]; extern CPU cpus_K6_SS7[]; +extern CPU cpus_PentiumPro[]; extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 1c9e1c7..6ee40e8 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -501,3 +501,12 @@ CPU cpus_K6_SS7[] = {"", -1, 0, 0, 0} }; +CPU cpus_PentiumPro[] = +{ + /*Intel Pentium Pro*/ + {"Pentium Pro 150", CPU_PENTIUMPRO, fpus_builtin, 17, 150000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*7)/2}, + {"Pentium Pro 166", CPU_PENTIUMPRO, fpus_builtin, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, + {"Pentium Pro 180", CPU_PENTIUMPRO, fpus_builtin, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium Pro 200", CPU_PENTIUMPRO, fpus_builtin, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"", -1, 0, 0, 0} +}; diff --git a/src/i440fx.c b/src/i440fx.c new file mode 100644 index 0000000..c95c79c --- /dev/null +++ b/src/i440fx.c @@ -0,0 +1,145 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "keyboard_at.h" +#include "mem.h" +#include "pci.h" +#include "x86.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) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +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 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_i440fx[0x59] ^ val) & 0xf0) + { + i440fx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i440fx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i440fx[0x5a] ^ val) & 0x0f) + i440fx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5a] ^ val) & 0xf0) + i440fx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i440fx[0x5b] ^ val) & 0x0f) + i440fx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5b] ^ val) & 0xf0) + i440fx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i440fx[0x5c] ^ val) & 0x0f) + i440fx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5c] ^ val) & 0xf0) + i440fx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i440fx[0x5d] ^ val) & 0x0f) + i440fx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5d] ^ val) & 0xf0) + i440fx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i440fx[0x5e] ^ val) & 0x0f) + 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; + } + + card_i440fx[addr] = val; +} + +uint8_t i440fx_read(int func, int addr, void *priv) +{ + if (func) + return 0xff; + + return card_i440fx[addr]; +} + +void i440fx_init() +{ + 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*/ + card_i440fx[0x04] = 0x06; card_i440fx[0x05] = 0x00; + card_i440fx[0x06] = 0x80; card_i440fx[0x07] = 0x02; + card_i440fx[0x08] = 0x00; /*A0 stepping*/ + card_i440fx[0x09] = 0x00; card_i440fx[0x0a] = 0x00; card_i440fx[0x0b] = 0x06; + card_i440fx[0x51] = 0x84; /*Uniprocessor, 66 MHz bus*/ + card_i440fx[0x53] = 0x80; + card_i440fx[0x57] = 0x01; + card_i440fx[0x58] = 0x10; + card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = 0x01; + card_i440fx[0x71] = 0x10; + card_i440fx[0x72] = 0x02; +} + +void i440fx_reset() +{ + i440fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ +} diff --git a/src/i440fx.h b/src/i440fx.h new file mode 100644 index 0000000..e16eab7 --- /dev/null +++ b/src/i440fx.h @@ -0,0 +1,2 @@ +void i440fx_init(); +void i440fx_reset(); diff --git a/src/ibm.h b/src/ibm.h index 62f8035..925b889 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -95,12 +95,12 @@ typedef struct PIT int initial[3]; int latched[3]; int disabled[3]; - + 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; @@ -127,7 +127,7 @@ typedef struct dma_t uint8_t stat, stat_rq; uint8_t command; int size; - + uint8_t ps2_mode; uint8_t arb_level; uint16_t io_addr; @@ -181,7 +181,7 @@ enum ROM_PC200, ROM_PC1640, ROM_PC2086, - ROM_PC3086, + ROM_PC3086, ROM_AMIXT, /*XT Clone with AMI BIOS*/ ROM_LTXT, ROM_LXT3, @@ -263,6 +263,7 @@ enum ROM_HYUNDAI_SUPER286TR, ROM_ITAUTEC_INFOWAYM, ROM_DESKPRO, + ROM_VS440FX, ROM_MAX }; @@ -288,7 +289,7 @@ enum GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/ GFX_VIRGE, /*S3 Virge*/ GFX_TGUI9440, /*Trident TGUI9440*/ - GFX_VGA, /*IBM VGA*/ + GFX_VGA, /*IBM VGA*/ GFX_VGAEDGE16, /*ATI VGA Edge-16 (18800-1)*/ GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/ GFX_VGACHARGER, /*ATI VGA Charger (28800-5)*/ @@ -298,7 +299,7 @@ enum GFX_VIRGEDX, /*S3 Virge/DX*/ GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/ GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/ - GFX_INCOLOR, /* Hercules InColor */ + GFX_INCOLOR, /* Hercules InColor */ GFX_COLORPLUS, /* Plantronics ColorPlus */ GFX_WY700, /* Wyse 700 */ GFX_GENIUS, /* MDSI Genius */ diff --git a/src/intel_flash.c b/src/intel_flash.c index 95285ee..2d28956 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -3,6 +3,7 @@ #include "device.h" #include "mem.h" +#define FLASH_2MBIT 4 #define FLASH_IS_BXB 2 #define FLASH_INVERT 1 @@ -10,6 +11,7 @@ #define BLOCK_DATA1 1 #define BLOCK_DATA2 2 #define BLOCK_BOOT 3 +#define BLOCK_MAIN2 4 /*2Mbit devices only*/ enum { @@ -27,10 +29,12 @@ typedef struct flash_t { uint8_t command, status; uint8_t flash_id; + uint8_t type; int invert_high_pin; - mem_mapping_t mapping[8], mapping_h[8]; - uint32_t block_start[4], block_end[4], block_len[4]; - uint8_t array[131072]; + mem_mapping_t mapping[8], mapping_h[10]; + uint32_t block_start[5], block_end[5], block_len[5]; + uint8_t array[256*1024]; + uint32_t addr_mask; } flash_t; static char flash_path[1024]; @@ -42,10 +46,10 @@ static uint8_t flash_read(uint32_t addr, void *p) { // 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]; + if (addr & 0xfff00000) return flash->array[addr & flash->addr_mask]; } // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); - addr &= 0x1ffff; + addr &= flash->addr_mask; switch (flash->command) { case CMD_READ_ARRAY: @@ -65,7 +69,7 @@ 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; - addr &= 0x1ffff; + addr &= flash->addr_mask; if (flash->invert_high_pin) addr ^= 0x10000; return *(uint16_t *)&(flash->array[addr]); } @@ -73,7 +77,7 @@ static uint16_t flash_readw(uint32_t addr, void *p) static uint32_t flash_readl(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; - addr &= 0x1ffff; + addr &= flash->addr_mask; if (flash->invert_high_pin) addr ^= 0x10000; return *(uint32_t *)&(flash->array[addr]); } @@ -82,14 +86,14 @@ 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); + 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) { addr ^= 0x10000; if (addr & 0xfff00000) return; } - addr &= 0x1ffff; + addr &= flash->addr_mask; switch (flash->command) { @@ -111,7 +115,7 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) case CMD_PROGRAM_SETUP: // pclog("flash_write: program %05x %02x\n", addr, val); - if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000)) + if ((addr & 0x3e000) != (flash->block_start[3] & 0x3e000)) flash->array[addr] = val; flash->command = CMD_READ_STATUS; flash->status = 0x80; @@ -134,9 +138,23 @@ static void intel_flash_add_mappings(flash_t *flash) for (i = 0; i <= 7; i++) { - mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), 0, (void *)flash); + mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + (((i << 14) + 0x20000) & flash->addr_mask), MEM_MAPPING_EXTERNAL, (void *)flash); + mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + (((i << 14) + 0x20000) & flash->addr_mask), 0, (void *)flash); } + + if (flash->type & FLASH_2MBIT) + { + mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x20000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array, 0, (void *)flash); + } } /* This is for boards which invert the high pin - the flash->array pointers need to pointer invertedly in order for INTERNAL writes to go to the right part of the array. */ @@ -146,9 +164,27 @@ static void intel_flash_add_mappings_inverted(flash_t *flash) for (i = 0; i <= 7; i++) { - mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), 0, (void *)flash); + mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + ((((i << 14) ^ 0x10000) + 0x20000) & flash->addr_mask), MEM_MAPPING_EXTERNAL, (void *)flash); + mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + ((((i << 14) ^ 0x10000) + 0x20000) & flash->addr_mask), 0, (void *)flash); } + + if (flash->type & FLASH_2MBIT) + { + mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array + 0x10000, 0, (void *)flash); + mem_mapping_add(&flash->mapping_h[9], 0xfffd0000, 0x10000, + flash_read, flash_readw, flash_readl, + flash_write, mem_write_nullw, mem_write_nulll, + flash->array, 0, (void *)flash); + } } void *intel_flash_init(uint8_t type) @@ -158,6 +194,8 @@ void *intel_flash_init(uint8_t type) memset(flash, 0, sizeof(flash_t)); char fpath[1024]; int i; + + flash->type = type; switch(romset) { @@ -191,42 +229,99 @@ void *intel_flash_init(uint8_t type) case ROM_ITAUTEC_INFOWAYM: strcpy(flash_path, "infowaym/"); break; + case ROM_VS440FX: + strcpy(flash_path, "vs440fx/"); + 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; + switch (type & (FLASH_IS_BXB | FLASH_2MBIT)) + { + case 0: + flash->flash_id = 0x94; + break; + case FLASH_IS_BXB: + flash->flash_id = 0x95; + break; + case FLASH_2MBIT: + flash->flash_id = 0x74; + break; + } + + flash->addr_mask = (type & FLASH_2MBIT) ? 0x3ffff : 0x1ffff; + +// flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; flash->invert_high_pin = (type & FLASH_INVERT); - /* The block lengths are the same both flash types. */ - flash->block_len[BLOCK_MAIN] = 0x1c000; - flash->block_len[BLOCK_DATA1] = 0x01000; - flash->block_len[BLOCK_DATA2] = 0x01000; - flash->block_len[BLOCK_BOOT] = 0x02000; + if (type & FLASH_2MBIT) + { + flash->block_len[BLOCK_MAIN] = 0x20000; + flash->block_len[BLOCK_MAIN2] = 0x18000; + flash->block_len[BLOCK_DATA1] = 0x02000; + flash->block_len[BLOCK_DATA2] = 0x02000; + flash->block_len[BLOCK_BOOT] = 0x04000; - if (type & FLASH_IS_BXB) /* 28F001BX-B */ - { - flash->block_start[BLOCK_MAIN] = 0x04000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1ffff; - flash->block_start[BLOCK_DATA1] = 0x03000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x03fff; - flash->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x04fff; - flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x01fff; - } - else /* 28F001BX-T */ - { - flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1bfff; - flash->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x1cfff; - flash->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x1dfff; - flash->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x1ffff; - } + if (type & FLASH_IS_BXB) /* 28F001BX-B */ + { + flash->block_start[BLOCK_MAIN] = 0x20000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x3ffff; + flash->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN2] = 0x1ffff; + flash->block_start[BLOCK_DATA1] = 0x04000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x05fff; + flash->block_start[BLOCK_DATA2] = 0x06000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x07fff; + flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x03fff; + } + else /* 28F001BX-T */ + { + flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1ffff; + flash->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN2] = 0x37fff; + flash->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x39fff; + flash->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x3bfff; + flash->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x3ffff; + } + } + else + { + /* The block lengths are the same both flash types. */ + flash->block_len[BLOCK_MAIN] = 0x1c000; + flash->block_len[BLOCK_DATA1] = 0x01000; + flash->block_len[BLOCK_DATA2] = 0x01000; + flash->block_len[BLOCK_BOOT] = 0x02000; + + if (type & FLASH_IS_BXB) /* 28F001BX-B */ + { + flash->block_start[BLOCK_MAIN] = 0x04000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1ffff; + flash->block_start[BLOCK_DATA1] = 0x03000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x03fff; + flash->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x04fff; + flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x01fff; + } + else /* 28F001BX-T */ + { + flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1bfff; + flash->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x1cfff; + flash->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x1dfff; + flash->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x1ffff; + } + } for (i = 0; i < 8; i++) { @@ -238,10 +333,17 @@ void *intel_flash_init(uint8_t type) { memcpy(flash->array, rom + 65536, 65536); memcpy(flash->array + 65536, rom, 65536); + if (type & FLASH_2MBIT) + { + memcpy(flash->array + 0x20000, rom + 0x30000, 65536); + memcpy(flash->array + 0x30000, rom + 0x20000, 65536); + } } else { memcpy(flash->array, rom, 131072); + if (type & FLASH_2MBIT) + memcpy(flash->array + 0x20000, rom + 0x20000, 131072); } if (flash->invert_high_pin) @@ -262,7 +364,9 @@ void *intel_flash_init(uint8_t type) if (f) { fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); - fread(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); + if (type & FLASH_2MBIT) + fread(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 1, f); + fread(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); fread(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); fclose(f); } @@ -288,6 +392,11 @@ void *intel_flash_bxb_init() return intel_flash_init(FLASH_IS_BXB); } +static void *intel_flash_28fb200bxt_init(void) +{ + return intel_flash_init(FLASH_INVERT | FLASH_2MBIT); +} + void intel_flash_close(void *p) { FILE *f; @@ -299,6 +408,8 @@ void intel_flash_close(void *p) strcat(fpath, "flash.bin"); f = romfopen(fpath, "wb"); fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + if (flash->type & FLASH_2MBIT) + fwrite(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 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); fclose(f); @@ -344,3 +455,16 @@ device_t intel_flash_bxb_device = NULL, NULL }; + +device_t intel_flash_28fb200bxt_device = +{ + "Intel 28FB200BX-T Flash BIOS", + 0, + intel_flash_28fb200bxt_init, + intel_flash_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/intel_flash.h b/src/intel_flash.h index 2b4cb14..8ab1a6b 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_bxt_device; extern device_t intel_flash_bxb_device; +extern device_t intel_flash_28fb200bxt_device; diff --git a/src/mem_bios.c b/src/mem_bios.c index 270080d..78e59c7 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -19,7 +19,7 @@ static int mem_load_basic(char *path) { char s[256]; FILE *f; - + sprintf(s, "%s/ibm-basic-1.10.rom", path); f = romfopen(s, "rb"); if (!f) @@ -53,26 +53,26 @@ static int mem_load_basic(char *path) return 1; } - + int loadbios() { FILE *f=NULL,*ff=NULL; int c; - + loadfont("mda.rom", FONT_MDA); loadfont("wy700.rom", FONT_WY700); loadfont("8x12.bin", FONT_MDSI); loadfont("im1024font.bin", FONT_IM1024); - + biosmask = 0xffff; - + if (!rom) - rom = malloc(0x20000); + rom = malloc(0x40000); memset(romext,0x63,0x4000); memset(rom, 0xff, 0x20000); - + pclog("Starting with romset %i\n", romset); - + switch (romset) { case ROM_PC1512: @@ -184,14 +184,14 @@ int loadbios() return 1; } break; - + case ROM_IBMPCJR: f = romfopen("ibmpcjr/bios.rom","rb"); if (!f) break; romfread(rom, 0x10000, 1, f); fclose(f); return 1; - + case ROM_GENXT: f=romfopen("genxt/pcxt.rom","rb"); if (!f) break; @@ -218,7 +218,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_PC2086: f = romfopen("pc2086/40179.ic129" ,"rb"); ff = romfopen("pc2086/40180.ic132","rb"); @@ -246,7 +246,7 @@ int loadbios() f = romfopen("pc3086/c000.bin", "rb"); if (!f) break; fclose(f); - biosmask = 0x3fff; + biosmask = 0x3fff; return 1; case ROM_IBMAT: @@ -434,7 +434,7 @@ int loadbios() if (f && ff) { fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); for (c = 0x0000; c < 0x10000; c += 2) { rom[c] = getc(f); @@ -501,7 +501,7 @@ int loadbios() ff = romfopen("megapc/211253-bios hi.u19", "rb"); if (!f || !ff) break; fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); for (c = 0x0000; c < 0x10000; c+=2) { rom[c]=getc(f); @@ -510,7 +510,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_AMI486: f=romfopen("ami486/ami486.bin","rb"); if (!f) break; @@ -518,7 +518,7 @@ int loadbios() fclose(f); //is486=1; return 1; - + case ROM_WIN486: // f=romfopen("win486/win486.bin","rb"); f=romfopen("win486/ali1429g.amw","rb"); @@ -529,9 +529,9 @@ int loadbios() return 1; case ROM_PCI486: - f=romfopen("hot-433/hot-433.ami","rb"); + f=romfopen("hot-433/hot-433.ami","rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -540,16 +540,16 @@ int loadbios() case ROM_SIS496: f = romfopen("sis496/sis496-1.awa", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); return 1; - + case ROM_P55VA: f = romfopen("p55va/va021297.bin", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -557,7 +557,7 @@ int loadbios() case ROM_P55TVP4: f = romfopen("p55tvp4/tv5i0204.awd", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -566,9 +566,9 @@ int loadbios() // f = romfopen("430vx/ga586atv.bin", "rb"); // f = fopen("430vx/vx29.bin", "rb"); f = romfopen("430vx/55xwuq0e.bin", "rb"); -// f=romfopen("430vx/430vx","rb"); +// f=romfopen("430vx/430vx","rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -577,7 +577,7 @@ int loadbios() case ROM_P55T2P4: f = romfopen("p55t2p4/0207_j2.bin", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -586,12 +586,12 @@ int loadbios() f = romfopen("revenge/1009af2_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("revenge/1009af2_.bi1", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); + romfread(rom, 0xc000, 1, f); fclose(f); biosmask = 0x1ffff; //is486=1; @@ -600,7 +600,7 @@ int loadbios() f = romfopen("endeavor/1006cb0_.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("endeavor/1006cb0_.bi1", "rb"); if (!f) break; @@ -630,7 +630,7 @@ int loadbios() f = romfopen("ibmps1es/f80000.bin", "rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); //#endif biosmask = 0x1ffff; @@ -640,7 +640,7 @@ int loadbios() f = romfopen("ibmps1_2121/fc0000.bin", "rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -665,7 +665,7 @@ int loadbios() romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; - + case ROM_LTXT: f = romfopen("ltxt/27c64.bin", "rb"); if (!f) break; @@ -717,11 +717,11 @@ int loadbios() romfread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; - + case ROM_IBMPS2_M30_286: f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); if (!f) break; - romfread(rom, 0x20000, 1, f); + romfread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; @@ -777,7 +777,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_ATARIPC3: f=romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN","rb"); if (!f) break; @@ -797,7 +797,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_EPSON_PCAX: f = romfopen("epson_pcax/EVAX", "rb"); ff = romfopen("epson_pcax/ODAX", "rb"); @@ -824,7 +824,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_EPSON_PCAX3: f = romfopen("epson_pcax3/EVAX3", "rb"); ff = romfopen("epson_pcax3/ODAX3", "rb"); @@ -837,7 +837,7 @@ int loadbios() fclose(ff); fclose(f); return 1; - + case ROM_T3100E: loadfont("t3100e/t3100e_font.bin", FONT_T3100E); f=romfopen("t3100e/t3100e.rom","rb"); @@ -865,14 +865,14 @@ int loadbios() biosmask = 0x7fff; fclose(f); return 1; - + case ROM_PB_L300SX: f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); if (!f) break; romfread(rom, 65536, 1, f); fclose(f); return 1; - + case ROM_NCR_PC4I: f=romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN" ,"rb"); if (!f) break; @@ -880,14 +880,14 @@ int loadbios() fclose(f); biosmask = 0x3fff; return 1; - + case ROM_TO16_PC: f=romfopen("to16_pc/TO16_103.bin","rb"); if (!f) break; romfread(rom+0x8000,32768,1,f); fclose(f); return 1; - + case ROM_COMPAQ_PII: f = romfopen("compaq_pii/109740-001.rom", "rb"); ff = romfopen("compaq_pii/109739-001.rom", "rb"); @@ -901,7 +901,7 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; - + case ROM_ELX_PC425X: /*PC-425X uses a single ROM chip containing both main and video BIOSes. First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. @@ -927,7 +927,7 @@ int loadbios() f = romfopen("pb570/1007by0r.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("pb570/1007by0r.bi1", "rb"); if (!f) break; @@ -937,7 +937,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_ZAPPA: f = romfopen("zappa/1006bs0_.bio", "rb"); if (!f) break; @@ -976,7 +976,7 @@ int loadbios() f = romfopen("pb520r/1009bc0r.bio", "rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom + 0x10000, 0x10000, 1, f); fclose(f); f = romfopen("pb520r/1009bc0r.bi1", "rb"); if (!f) break; @@ -986,7 +986,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_COMPAQ_PIP: f=romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin","rb"); if (!f) break; @@ -1041,7 +1041,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_TULIP_TC7: f = romfopen("tulip_tc7/tc7be.bin", "rb"); ff = romfopen("tulip_tc7/tc7bo.bin", "rb"); @@ -1055,7 +1055,7 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; - + case ROM_ZD_SUPERS: /* [8088] Zenith Data Systems SupersPort */ f=romfopen("zdsupers/z184m v3.1d.10d","rb"); if (!f) break; @@ -1071,7 +1071,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; - + case ROM_BULL_MICRAL_45: f = romfopen("bull_micral_45/even.fil", "rb"); ff = romfopen("bull_micral_45/odd.fil", "rb"); @@ -1136,6 +1136,37 @@ int loadbios() fclose(f); biosmask = 0x1fff; return 1; + + case ROM_VS440FX: + f = romfopen("vs440fx/1018CS1_.BIO", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x00000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI2", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x30000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI3", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x20000, 0x0a000, 1, f); + fclose(f); + + f = romfopen("vs440fx/1018CS1_.RCV", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x2c000, 0x04000, 1, f); + fclose(f); + + biosmask = 0x3ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 1b8c40f..35a2efd 100644 --- a/src/model.c +++ b/src/model.c @@ -29,6 +29,7 @@ #include "i430hx.h" #include "i430lx.h" #include "i430vx.h" +#include "i440fx.h" #include "ide.h" #include "intel.h" #include "intel_flash.h" @@ -49,6 +50,7 @@ #include "olivetti_m24.h" #include "opti495.h" #include "pc87306.h" +#include "pc87307.h" #include "pci.h" #include "pic.h" #include "piix.h" @@ -130,6 +132,7 @@ void compaq_xt_init(); void xt_xi8088_init(); void xt_zenith_init(); void at_mvp3_init(); +void at_vs440fx_init(); int model; int AMSTRAD, AT, PCI, TANDY, MCA; @@ -235,6 +238,8 @@ MODEL models[] = {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}, {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86_SS7}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}, + + {"[Socket 8] Intel VS440FX", ROM_VS440FX, "vs440fx", { {"Intel", cpus_PentiumPro}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 8, at_vs440fx_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; @@ -813,6 +818,21 @@ void at_mvp3_init() device_add(&sst_39sf010_device); } +void at_vs440fx_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xf); + pci_slot(0x11); + pci_slot(0x13); + i440fx_init(); + piix_init(7, 0xb, 0xf, 0x11, 0x13, i440fx_reset); + pc87307_init(0x2e); +// i440fx_init(); + device_add(&intel_flash_28fb200bxt_device); +} + void model_init() { pclog("Initting as %s\n", model_getname()); diff --git a/src/nvr.c b/src/nvr.c index 2d14e08..21df383 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -356,6 +356,7 @@ void loadnvr() case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); nvrmask = 127; break; case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break; case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); nvrmask = 127; break; + case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -463,6 +464,7 @@ void savenvr() case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); break; case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break; case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "wb"); break; + case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "wb"); break; default: return; } diff --git a/src/pc87307.c b/src/pc87307.c new file mode 100644 index 0000000..e4f8ed4 --- /dev/null +++ b/src/pc87307.c @@ -0,0 +1,151 @@ +#include "ibm.h" + +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "pc87307.h" + +typedef struct pc87307_t +{ + int cur_reg; + int cur_device; + + uint8_t superio_cfg1, superio_cfg2; + + struct + { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[9]; +} pc87307_t; + +static pc87307_t pc87307_global; + +#define DEV_KBC 0 +#define DEV_MOUSE 1 +#define DEV_RTC 2 +#define DEV_FDC 3 +#define DEV_LPT 4 +#define DEV_COM2 5 +#define DEV_COM1 6 +#define DEV_GPIO 7 +#define DEV_POWER 8 + +#define REG_DEVICE 0x07 +#define REG_SID 0x20 +#define REG_SUPERIO_CFG1 0x21 +#define REG_SUPERIO_CFG2 0x22 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 + +void pc87307_write(uint16_t port, uint8_t val, void *p) +{ + pc87307_t *pc87307 = (pc87307_t *)p; + + if (port == 0x2e) + pc87307->cur_reg = val; + else + { + if (pc87307->cur_reg == REG_DEVICE) + pc87307->cur_device = val & 0xf; + else + { +// pclog("Write pc87307 %02x [%02x] %02x\n", pc87307->cur_reg, pc87307->cur_device, val); + switch (pc87307->cur_reg) + { + case REG_ENABLE: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].enable = val; + break; + case REG_ADDRLO: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].irq = val; + break; + case REG_DMA: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].dma = val; + break; + } + + switch (pc87307->cur_device) + { + case DEV_FDC: + fdc_remove(); + if (pc87307->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (pc87307->dev[DEV_COM1].enable & 1) + serial1_set(pc87307->dev[DEV_COM1].addr, pc87307->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (pc87307->dev[DEV_COM2].enable & 1) + serial2_set(pc87307->dev[DEV_COM2].addr, pc87307->dev[DEV_COM2].irq); + break; + case DEV_LPT: + lpt1_remove(); + lpt2_remove(); + if (pc87307->dev[DEV_LPT].enable & 1) + lpt1_init(pc87307->dev[DEV_LPT].addr); + break; + } + } + } +} + +uint8_t pc87307_read(uint16_t port, void *p) +{ + pc87307_t *pc87307 = (pc87307_t *)p; + +// pclog("Read pc87307 %02x\n", pc87307->cur_reg); + + switch (pc87307->cur_reg) + { + case REG_DEVICE: + return pc87307->cur_device; + case REG_SID: + return 0x20; /*PC87307*/ + case REG_SUPERIO_CFG1: + return pc87307->superio_cfg1; + case REG_SUPERIO_CFG2: + return pc87307->superio_cfg2; + case REG_ENABLE: + return pc87307->dev[pc87307->cur_device].enable; + case REG_ADDRLO: + return pc87307->dev[pc87307->cur_device].addr & 0xff; + case REG_ADDRHI: + return pc87307->dev[pc87307->cur_device].addr >> 8; + case REG_IRQ: + return pc87307->dev[pc87307->cur_device].irq; + case REG_DMA: + return pc87307->dev[pc87307->cur_device].dma; + } + + return 0xff; +} + +void pc87307_init(uint16_t base) +{ + memset(&pc87307_global, 0, sizeof(pc87307_t)); + + pc87307_global.superio_cfg1 = 0x04; + pc87307_global.superio_cfg2 = 0x03; + + io_sethandler(base, 0x0002, pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, &pc87307_global); +} diff --git a/src/pc87307.h b/src/pc87307.h new file mode 100644 index 0000000..e28ae8a --- /dev/null +++ b/src/pc87307.h @@ -0,0 +1 @@ +void pc87307_init(uint16_t addr); diff --git a/src/x86_ops.h b/src/x86_ops.h index 73a0b6f..d317f50 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -38,6 +38,8 @@ extern OpFn dynarec_ops_winchip2_0f[1024]; extern OpFn dynarec_ops_pentium_0f[1024]; extern OpFn dynarec_ops_pentiummmx_0f[1024]; +extern OpFn dynarec_ops_pentiumpro_0f[1024]; + extern OpFn dynarec_ops_c6x86mx_0f[1024]; extern OpFn dynarec_ops_fpu_d8_a16[32]; @@ -104,6 +106,7 @@ extern OpFn ops_winchip2_0f[1024]; extern OpFn ops_pentium_0f[1024]; extern OpFn ops_pentiummmx_0f[1024]; +extern OpFn ops_pentiumpro_0f[1024]; extern OpFn ops_c6x86mx_0f[1024]; From 21dbd868e15cd2fbc0d6e900dbe49fffbc06a457 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 24 Jun 2020 20:42:24 +0100 Subject: [PATCH 0861/1050] Add initial P6 timing model. Currently only basic decoder limits (4-1-1 rule and 16-byte limit) have been implemented. --- src/codegen.h | 1 + src/codegen_timing_p6.c | 2085 +++++++++++++++++++++++++++++++++++++++ src/cpu.c | 2 +- 3 files changed, 2087 insertions(+), 1 deletion(-) create mode 100644 src/codegen_timing_p6.c diff --git a/src/codegen.h b/src/codegen.h index 1d88e23..0ca3df5 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -375,6 +375,7 @@ extern codegen_timing_t codegen_timing_486; extern codegen_timing_t codegen_timing_winchip; extern codegen_timing_t codegen_timing_winchip2; extern codegen_timing_t codegen_timing_k6; +extern codegen_timing_t codegen_timing_p6; void codegen_timing_set(codegen_timing_t *timing); diff --git a/src/codegen_timing_p6.c b/src/codegen_timing_p6.c new file mode 100644 index 0000000..49a90a1 --- /dev/null +++ b/src/codegen_timing_p6.c @@ -0,0 +1,2085 @@ +#include "ibm.h" +#include "cpu.h" +#include "model.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "386_common.h" +#include "mem.h" +#include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" + +typedef enum uop_type_t +{ + UOP_ALU0 = 0, /*Executes in port 0 ALU*/ + UOP_ALU1, /*Executes in port 1 ALU*/ + UOP_ALU01, /*Executes in either port 0 or 1 ALU*/ + UOP_BRANCH, /*Executes in port 1 branch*/ + UOP_LOAD, /*Executes in port 2 Load unit*/ + UOP_STOREADDR, /*Executes in port 3 Store Address unit*/ + UOP_STOREDATA, /*Executes in port 4 Store Data unit*/ + UOP_FLOAT /*Executes in port 0 Floating Point unit*/ +} uop_type_t; + +#define MAX_UOPS 300 + +typedef struct p6_uop_t +{ + uop_type_t type; + int throughput; + int latency; +} p6_uop_t; + +typedef struct p6_instruction_t +{ + int nr_uops; + p6_uop_t uop[MAX_UOPS]; +} p6_instruction_t; + +static const p6_instruction_t alu_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu0_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu1_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu01_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu4_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu6_op = +{ + .nr_uops = 6, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t aluc_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_alu_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_aluc_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu_store_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t alu0_store_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t aluc_store_op = +{ + .nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t branch_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t load_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +}; + +static const p6_instruction_t store_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; + + +static const p6_instruction_t bswap_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t leave_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t lods_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t loop_op = +{ + .nr_uops = 11, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t movs_op = +{ + .nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t pop_reg_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t pop_mem_op = +{ + .nr_uops = 8, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t push_imm_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t push_mem_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t push_seg_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t rcx_op = +{ + .nr_uops = 8, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t rcx_store_op = +{ + .nr_uops = 11, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t stos_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t xchg_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t mmx_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t mmx_mul_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 3} +}; +static const p6_instruction_t mmx_shift_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_mmx_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_mmx_mul_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_mmx_shift_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t faddsub_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 3} +}; +static const p6_instruction_t load_faddsub_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 3} +}; +static const p6_instruction_t fbstp_op = +{ + .nr_uops = 5, + .uop[0] = {.type = UOP_FLOAT, .throughput = 165, .latency = 165}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t fcom_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_fcom_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t fcompp_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t fild_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_fi_op = +{ + .nr_uops = 7, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t fmul_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 5} +}; +static const p6_instruction_t load_fmul_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 5} +}; + +static const p6_instruction_t fxch_op = +{ + .nr_uops = 0 +}; + +static const p6_instruction_t fist_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t fdiv_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 37, .latency = 38} +}; +static const p6_instruction_t fdiv_mem_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 37, .latency = 38} +}; +static const p6_instruction_t fsin_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} +}; +static const p6_instruction_t fsqrt_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 69, .latency = 69} +}; + +static const p6_instruction_t float_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t fldcw_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 7, .latency = 7}, +}; +static const p6_instruction_t flde_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t frstor_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 72, .latency = 72} +}; +static const p6_instruction_t fsave_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 141, .latency = 141} +}; +static const p6_instruction_t fste_op = +{ + .nr_uops = 6, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t fstsw_ax_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t fstsw_mem_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; + +static const p6_instruction_t aad_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t aam_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}, + .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 9}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t arpl_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_ALU01, .throughput = 3, .latency = 3} +}; +static const p6_instruction_t bound_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU0, .throughput = 7, .latency = 7}, + .uop[3] = {.type = UOP_ALU01, .throughput = 6, .latency = 6} +}; +static const p6_instruction_t bsx_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t load_bsx_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t call_far_op = +{ + .nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 28, .latency = 28} +}; +static const p6_instruction_t load_call_far_op = +{ + .nr_uops = 7, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 28, .latency = 28} +}; +static const p6_instruction_t cli_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU01, .throughput = 9, .latency = 9} +}; +static const p6_instruction_t sti_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU01, .throughput = 17, .latency = 17} +}; +static const p6_instruction_t cmps_op = +{ + .nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t cmpxchg_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t cpuid_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU0, .throughput = 48, .latency = 48} +}; +/*static const p6_instruction_t div8_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU0, .throughput = 12, .latency = 17}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +};*/ +/*static const p6_instruction_t div8_mem_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[0] = {.type = UOP_ALU0, .throughput = 12, .latency = 17}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +};*/ +static const p6_instruction_t div16_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU0, .throughput = 21, .latency = 21}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t div16_mem_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[0] = {.type = UOP_ALU0, .throughput = 21, .latency = 21}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t div32_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU0, .throughput = 35, .latency = 35}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t div32_mem_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[0] = {.type = UOP_ALU0, .throughput = 35, .latency = 35}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t emms_op = +{ + .nr_uops = 11, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t enter_op = +{ + .nr_uops = 14, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t io_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_LOAD, .throughput = 18, .latency = 18} +}; +static const p6_instruction_t ins_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_ALU0, .throughput = 18, .latency = 18}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t int_op = +{ + .nr_uops = 7, + .uop[0] = {.type = UOP_ALU0, .throughput = 20, .latency = 20}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t iret_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU01, .throughput = 20, .latency = 20}, +}; +static const p6_instruction_t invd_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU01, .throughput = 1000, .latency = 1000} +}; +static const p6_instruction_t jmp_far_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 21, .latency = 21} +}; +static const p6_instruction_t load_jmp_far_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU0, .throughput = 21, .latency = 21} +}; +static const p6_instruction_t lss_op = +{ + .nr_uops = 11, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +/*static const p6_instruction_t mov_mem_seg_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, +};*/ +static const p6_instruction_t mov_seg_mem_op = +{ + .nr_uops = 9, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t mov_seg_reg_op = +{ + .nr_uops = 8, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t mul_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 4} +}; +static const p6_instruction_t mul_mem_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4} +}; +static const p6_instruction_t outs_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 18, .latency = 18}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t pusha_op = +{ + .nr_uops = 18, + .uop[0] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[14] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[15] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[16] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[17] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t popa_op = +{ + .nr_uops = 10, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t popf_op = +{ + .nr_uops = 17, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[14] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[15] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[16] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t pushf_op = +{ + .nr_uops = 16, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[14] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[15] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t ret_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t reti_op = +{ + .nr_uops = 5, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t retf_op = +{ + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU0, .throughput = 23, .latency = 23}, +}; +static const p6_instruction_t scas_op = +{ + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t xchg_mem_op = +{ + .nr_uops = 7, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} +}; +static const p6_instruction_t xlat_op = +{ + .nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +}; +static const p6_instruction_t wbinvd_op = +{ + .nr_uops = 1, + .uop[0] = {.type = UOP_ALU0, .throughput = 10000, .latency = 10000} +}; + +#define INVALID NULL + +static const p6_instruction_t *opcode_timings[256] = +{ +/* ADD ADD ADD ADD*/ +/*00*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, +/* ADD ADD PUSH ES POP ES*/ + &alu_op, &alu_op, &push_seg_op, &mov_seg_mem_op, +/* OR OR OR OR*/ + &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, +/* OR OR PUSH CS */ + &alu_op, &alu_op, &push_seg_op, INVALID, + +/* ADC ADC ADC ADC*/ +/*10*/ &aluc_store_op, &aluc_store_op, &load_aluc_op, &load_aluc_op, +/* ADC ADC PUSH SS POP SS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, +/* SBB SBB SBB SBB*/ +/*10*/ &aluc_store_op, &aluc_store_op, &load_aluc_op, &load_aluc_op, +/* SBB SBB PUSH DS POP DS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, + +/* AND AND AND AND*/ +/*20*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, +/* AND AND DAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, +/* SUB SUB SUB SUB*/ + &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, +/* SUB SUB DAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + +/* XOR XOR XOR XOR*/ +/*30*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, +/* XOR XOR AAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, +/* CMP CMP CMP CMP*/ + &load_alu_op, &load_alu_op, &load_alu_op, &load_alu_op, +/* CMP CMP AAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ &store_op, &store_op, &store_op, &store_op, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, +/* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, +/* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &mul_op, &push_imm_op, &mul_op, +/* INSB INSW OUTSB OUTSW*/ + &ins_op, &ins_op, &outs_op, &outs_op, + +/* Jxx*/ +/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + &load_alu_op, &load_alu_op, &xchg_mem_op, &xchg_mem_op, +/* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, +/* MOV from seg LEA MOV to seg POP*/ + &store_op, &alu0_op, &mov_seg_mem_op, &pop_mem_op, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ &alu_op, &xchg_op, &xchg_op, &xchg_op, +/* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, +/* CBW CWD CALL far WAIT*/ + &alu_op, &alu0_op, &call_far_op, &alu_op, +/* PUSHF POPF SAHF LAHF*/ + &pushf_op, &popf_op, &alu_op, &alu_op, + +/* MOV MOV MOV MOV*/ +/*a0*/ &load_op, &load_op, &store_op, &store_op, +/* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &cmps_op, &cmps_op, +/* TEST TEST STOSB STOSW*/ + &load_alu_op, &load_alu_op, &stos_op, &stos_op, +/* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &scas_op, &scas_op, + +/* MOV*/ +/*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + +/* RET imm RET*/ +/*c0*/ INVALID, INVALID, &reti_op, &ret_op, +/* LES LDS MOV MOV*/ + &lss_op, &lss_op, &store_op, &store_op, +/* ENTER LEAVE RETF RETF*/ + &enter_op, &leave_op, &retf_op, &retf_op, +/* INT3 INT INTO IRET*/ + &int_op, &int_op, &int_op, &iret_op, + + +/*d0*/ INVALID, INVALID, INVALID, INVALID, +/* AAM AAD SETALC XLAT*/ + &aam_op, &aad_op, &alu_op, &xlat_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, +/* CALL JMP JMP JMP*/ + &store_op, &branch_op, &jmp_far_op, &branch_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, + +/* REPNE REPE*/ +/*f0*/ INVALID, INVALID, INVALID, INVALID, +/* HLT CMC*/ + &alu4_op, &alu_op, INVALID, INVALID, +/* CLC STC CLI STI*/ + &alu_op, &alu_op, &cli_op, &sti_op, +/* CLD STD INCDEC*/ + &alu4_op, &alu4_op, &store_op, INVALID +}; + +static const p6_instruction_t *opcode_timings_mod3[256] = +{ +/* ADD ADD ADD ADD*/ +/*00*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* ADD ADD PUSH ES POP ES*/ + &alu_op, &alu_op, &push_seg_op, &mov_seg_mem_op, +/* OR OR OR OR*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* OR OR PUSH CS */ + &alu_op, &alu_op, &push_seg_op, INVALID, + +/* ADC ADC ADC ADC*/ +/*10*/ &aluc_op, &aluc_op, &aluc_op, &aluc_op, +/* ADC ADC PUSH SS POP SS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, +/* SBB SBB SBB SBB*/ + &aluc_op, &aluc_op, &aluc_op, &aluc_op, +/* SBB SBB PUSH DS POP DS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, + +/* AND AND AND AND*/ +/*20*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* AND AND DAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, +/* SUB SUB SUB SUB*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* SUB SUB DAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + +/* XOR XOR XOR XOR*/ +/*30*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* XOR XOR AAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, +/* CMP CMP CMP CMP*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* CMP CMP AAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ &store_op, &store_op, &store_op, &store_op, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, +/* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, +/* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &mul_op, &push_imm_op, &mul_op, +/* INSB INSW OUTSB OUTSW*/ + &ins_op, &ins_op, &outs_op, &outs_op, + +/* Jxx*/ +/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + &alu_op, &alu_op, &xchg_op, &xchg_op, +/* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, +/* MOV from seg LEA MOV to seg POP*/ + &alu_op, &alu0_op, &mov_seg_reg_op, &pop_reg_op, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ &alu_op, &xchg_op, &xchg_op, &xchg_op, +/* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, +/* CBW CWD CALL far WAIT*/ + &alu_op, &alu0_op, &call_far_op, &alu_op, +/* PUSHF POPF SAHF LAHF*/ + &pushf_op, &popf_op, &alu_op, &alu_op, + +/* MOV MOV MOV MOV*/ +/*a0*/ &load_op, &load_op, &store_op, &store_op, +/* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &cmps_op, &cmps_op, +/* TEST TEST STOSB STOSW*/ + &alu_op, &alu_op, &stos_op, &stos_op, +/* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &scas_op, &scas_op, + +/* MOV*/ +/*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + +/* RET imm RET*/ +/*c0*/ INVALID, INVALID, &reti_op, &ret_op, +/* LES LDS MOV MOV*/ + &lss_op, &lss_op, &store_op, &store_op, +/* ENTER LEAVE RETF RETF*/ + &enter_op, &leave_op, &retf_op, &retf_op, +/* INT3 INT INTO IRET*/ + &int_op, &int_op, &int_op, &iret_op, + + +/*d0*/ INVALID, INVALID, INVALID, INVALID, +/* AAM AAD SETALC XLAT*/ + &aam_op, &aad_op, &alu_op, &xlat_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, +/* CALL JMP JMP JMP*/ + &store_op, &branch_op, &jmp_far_op, &branch_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, + +/* REPNE REPE*/ +/*f0*/ INVALID, INVALID, INVALID, INVALID, +/* HLT CMC*/ + &alu4_op, &alu_op, INVALID, INVALID, +/* CLC STC CLI STI*/ + &alu_op, &alu_op, &cli_op, &sti_op, +/* CLD STD INCDEC*/ + &alu4_op, &alu4_op, &alu_op, INVALID +}; + +static const p6_instruction_t *opcode_timings_0f[256] = +{ +/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, + INVALID, &alu6_op, &alu6_op, INVALID, + &invd_op, &wbinvd_op, INVALID, INVALID, + INVALID, &load_op, INVALID, INVALID, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*20*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, + &alu6_op, &alu6_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ &alu6_op, &alu6_op, &alu6_op, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + INVALID, INVALID, &load_op, &load_op, + +/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &emms_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, &store_op, &store_op, + +/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*90*/ &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + +/*a0*/ &push_seg_op, &mov_seg_mem_op, &cpuid_op, &load_alu_op, + &alu_store_op, &alu_store_op, INVALID, INVALID, + &push_seg_op, &mov_seg_mem_op, INVALID, &load_alu_op, + &alu_store_op, &alu_store_op, INVALID, &mul_op, + +/*b0*/ &cmpxchg_op, &cmpxchg_op, &lss_op, &load_alu_op, + &lss_op, &lss_op, &load_alu_op, &load_alu_op, + INVALID, INVALID, &load_alu_op, &load_alu_op, + &load_bsx_op, &load_bsx_op, &load_alu_op, &load_alu_op, + +/*c0*/ &alu_store_op, &alu_store_op, INVALID, INVALID, + INVALID, INVALID, INVALID, &cmpxchg_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + +/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + INVALID, &load_mmx_mul_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + +/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, + INVALID, &load_mmx_mul_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + +/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + INVALID, &load_mmx_mul_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, +}; +static const p6_instruction_t *opcode_timings_0f_mod3[256] = +{ +/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, + INVALID, &alu6_op, &alu6_op, INVALID, + &invd_op, &wbinvd_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*20*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, + &alu6_op, &alu6_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ &alu6_op, &alu6_op, &alu6_op, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, + &mmx_op, &mmx_op, &mmx_op, &mmx_op, + &mmx_op, &mmx_op, &mmx_op, &mmx_op, + INVALID, INVALID, &mmx_op, &mmx_op, + +/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + &mmx_op, &mmx_op, &mmx_op, &emms_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, &mmx_op, &mmx_op, + +/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*90*/ &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + +/*a0*/ &push_seg_op, &mov_seg_mem_op, &cpuid_op, &alu_op, + &alu_op, &alu_op, INVALID, INVALID, + &push_seg_op, &mov_seg_mem_op, INVALID, &alu_op, + &alu_op, &alu_op, INVALID, &mul_op, + +/*b0*/ &cmpxchg_op, &cmpxchg_op, &lss_op, &alu_op, + &lss_op, &lss_op, &alu_op, &alu_op, + INVALID, INVALID, &alu_op, &alu_op, + &bsx_op, &bsx_op, &alu_op, &alu_op, + +/*c0*/ &alu_op, &alu_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + +/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + INVALID, &mmx_mul_op, INVALID, INVALID, + &mmx_op, &mmx_op, INVALID, &mmx_op, + &mmx_op, &mmx_op, INVALID, &mmx_op, + +/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, + INVALID, &mmx_mul_op, INVALID, INVALID, + &mmx_op, &mmx_op, INVALID, &mmx_op, + &mmx_op, &mmx_op, INVALID, &mmx_op, + +/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + INVALID, &mmx_mul_op, INVALID, INVALID, + &mmx_op, &mmx_op, &mmx_op, INVALID, + &mmx_op, &mmx_op, &mmx_op, INVALID, +}; + +static const p6_instruction_t *opcode_timings_shift[8] = +{ + &alu0_store_op, &alu0_store_op, &rcx_store_op, &rcx_store_op, + &alu0_store_op, &alu0_store_op, &alu0_store_op, &alu0_store_op +}; +static const p6_instruction_t *opcode_timings_shift_mod3[8] = +{ + &alu0_op, &alu0_op, &rcx_op, &rcx_op, + &alu0_op, &alu0_op, &alu0_op, &alu0_op +}; + +static const p6_instruction_t *opcode_timings_8x[8] = +{ + &alu_store_op, &alu_store_op, &aluc_store_op, &aluc_store_op, + &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, +}; +static const p6_instruction_t *opcode_timings_8x_mod3[8] = +{ + &alu_op, &alu_op, &aluc_op, &aluc_op, + &alu_op, &alu_op, &alu_op, &alu_op, +}; + +static const p6_instruction_t *opcode_timings_f6[8] = +{ +/* TST NOT NEG*/ + &load_alu_op, INVALID, &alu_store_op, &alu_store_op, +/* MUL IMUL DIV IDIV*/ + &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, +}; +static const p6_instruction_t *opcode_timings_f6_mod3[8] = +{ +/* TST NOT NEG*/ + &alu_op, INVALID, &alu_op, &alu_op, +/* MUL IMUL DIV IDIV*/ + &mul_op, &mul_op, &div16_op, &div16_op, +}; +static const p6_instruction_t *opcode_timings_f7[8] = +{ +/* TST NOT NEG*/ + &load_alu_op, INVALID, &alu_store_op, &alu_store_op, +/* MUL IMUL DIV IDIV*/ + &mul_mem_op, &mul_mem_op, &div32_mem_op, &div32_mem_op, +}; +static const p6_instruction_t *opcode_timings_f7_mod3[8] = +{ +/* TST NOT NEG*/ + &alu_op, INVALID, &alu_op, &alu_op, +/* MUL IMUL DIV IDIV*/ + &mul_op, &mul_op, &div32_op, &div32_op, +}; +static const p6_instruction_t *opcode_timings_ff[8] = +{ +/* INC DEC CALL CALL far*/ + &alu_store_op, &alu_store_op, &store_op, &load_call_far_op, +/* JMP JMP far PUSH*/ + &branch_op, &load_jmp_far_op, &push_mem_op, INVALID +}; +static const p6_instruction_t *opcode_timings_ff_mod3[8] = +{ +/* INC DEC CALL CALL far*/ + &alu_op, &alu_op, &store_op, &call_far_op, +/* JMP JMP far PUSH*/ + &branch_op, &load_jmp_far_op, &push_mem_op, INVALID +}; + +static const p6_instruction_t *opcode_timings_d8[8] = +{ +/* FADDs FMULs FCOMs FCOMPs*/ + &load_faddsub_op, &load_fmul_op, &fcom_op, &load_fcom_op, +/* FSUBs FSUBRs FDIVs FDIVRs*/ + &load_faddsub_op, &load_faddsub_op, &fdiv_mem_op, &fdiv_mem_op, +}; +static const p6_instruction_t *opcode_timings_d8_mod3[8] = +{ +/* FADD FMUL FCOM FCOMP*/ + &faddsub_op, &fmul_op, &fcom_op, &fcom_op, +/* FSUB FSUBR FDIV FDIVR*/ + &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op, +}; + +static const p6_instruction_t *opcode_timings_d9[8] = +{ +/* FLDs FSTs FSTPs*/ + &load_op, INVALID, &store_op, &store_op, +/* FLDENV FLDCW FSTENV FSTCW*/ + &flde_op, &fldcw_op, &fste_op, &fstsw_mem_op +}; +static const p6_instruction_t *opcode_timings_d9_mod3[64] = +{ + /*FLD*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, + /*FXCH*/ + &fxch_op, &fxch_op, &fxch_op, &fxch_op, + &fxch_op, &fxch_op, &fxch_op, &fxch_op, + /*FNOP*/ + &float_op, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, +/* opFCHS opFABS*/ + &float_op, &float_op, INVALID, INVALID, +/* opFTST opFXAM*/ + &float_op, &float_op, INVALID, INVALID, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + &float_op, &float_op, &float_op, &float_op, +/* opFLDEG2 opFLDLN2 opFLDZ*/ + &float_op, &float_op, &float_op, INVALID, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + &fsin_op, &fsin_op, &fsin_op, &fsin_op, +/* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, &float_op, &float_op, +/* opFPREM opFSQRT opFSINCOS*/ + &fdiv_op, INVALID, &fsqrt_op, &fsin_op, +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + &float_op, &fdiv_op, &fsin_op, &fsin_op +}; + +static const p6_instruction_t *opcode_timings_da[8] = +{ +/* FIADDl FIMULl FICOMl FICOMPl*/ + &load_fi_op, &load_fi_op, &load_fcom_op, &load_fcom_op, +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + &load_fi_op, &load_fi_op, &load_fi_op, &load_fi_op, +}; +static const p6_instruction_t *opcode_timings_da_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FCOMPP*/ + INVALID, &fcompp_op, INVALID, INVALID +}; + +static const p6_instruction_t *opcode_timings_db[8] = +{ +/* FLDil FSTil FSTPil*/ + &fild_op, INVALID, &fist_op, &fist_op, +/* FLDe FSTPe*/ + INVALID, &flde_op, INVALID, &fste_op +}; +static const p6_instruction_t *opcode_timings_db_mod3[64] = +{ + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/* opFNOP opFCLEX opFINIT*/ + INVALID, &float_op, &float_op, &float_op, +/* opFNOP opFNOP*/ + &float_op, &float_op, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +}; + +static const p6_instruction_t *opcode_timings_dc[8] = +{ +/* FADDd FMULd FCOMd FCOMPd*/ + &load_faddsub_op, &load_fmul_op, &load_fcom_op, &load_fcom_op, +/* FSUBd FSUBRd FDIVd FDIVRd*/ + &load_faddsub_op, &load_faddsub_op, &fdiv_mem_op, &fdiv_mem_op, +}; +static const p6_instruction_t *opcode_timings_dc_mod3[8] = +{ +/* opFADDr opFMULr*/ + &faddsub_op, &fmul_op, INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op +}; + +static const p6_instruction_t *opcode_timings_dd[8] = +{ +/* FLDd FSTd FSTPd*/ + &load_op, INVALID, &store_op, &store_op, +/* FRSTOR FSAVE FSTSW*/ + &frstor_op, INVALID, &fsave_op, &fstsw_mem_op +}; +static const p6_instruction_t *opcode_timings_dd_mod3[8] = +{ +/* FFFREE FST FSTP*/ + &float_op, INVALID, &float_op, &float_op, +/* FUCOM FUCOMP*/ + &float_op, &float_op, INVALID, INVALID +}; + +static const p6_instruction_t *opcode_timings_de[8] = +{ +/* FIADDw FIMULw FICOMw FICOMPw*/ + &load_fi_op, &load_fi_op, &load_fcom_op, &load_fcom_op, +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + &load_fi_op, &load_fi_op, &load_fi_op, &load_fi_op, +}; +static const p6_instruction_t *opcode_timings_de_mod3[8] = +{ +/* FADDP FMULP FCOMPP*/ + &faddsub_op, &fmul_op, INVALID, &fcompp_op, +/* FSUBP FSUBRP FDIVP FDIVRP*/ + &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op, +}; + +static const p6_instruction_t *opcode_timings_df[8] = +{ +/* FILDiw FISTiw FISTPiw*/ + &fild_op, INVALID, &fist_op, &fist_op, +/* FILDiq FBSTP FISTPiq*/ + INVALID, &fild_op, &fbstp_op, &fist_op, +}; +static const p6_instruction_t *opcode_timings_df_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FSTSW AX*/ + &fstsw_ax_op, INVALID, INVALID, INVALID +}; + + +static uint8_t last_prefix; +static int prefixes; + +static int decode_timestamp; +static int last_complete_timestamp; + +typedef struct p6_unit_t +{ + uint32_t uop_mask; + int first_available_cycle; +} p6_unit_t; + +enum +{ + UNIT_INT0 = 0, + UNIT_INT1, + UNIT_FPU, + UNIT_MMX_ADD, + UNIT_MMX_MUL, + UNIT_JUMP, + UNIT_LOAD, + UNIT_STORE_ADDR, + UNIT_STORE_DATA +}; + +/*Each port can only be used once per clock*/ +typedef struct p6_port_t +{ + uint32_t unit_mask; +} p6_port_t; + +static const p6_port_t ports[] = +{ + {UNIT_INT0 | UNIT_FPU | UNIT_MMX_MUL}, + {UNIT_INT1 | UNIT_MMX_ADD | UNIT_JUMP}, + {UNIT_LOAD}, + {UNIT_STORE_ADDR}, + {UNIT_STORE_DATA} +}; + + +static p6_unit_t units[] = +{ + [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU01)}, /*Integer 0*/ + [UNIT_INT1] = {.uop_mask = (1 << UOP_ALU1) | (1 << UOP_ALU01)}, /*Integer 1*/ + [UNIT_FPU] = {.uop_mask = 1 << UOP_FLOAT}, + [UNIT_MMX_ADD] = {.uop_mask = 0}, + [UNIT_MMX_MUL] = {.uop_mask = 0}, + [UNIT_JUMP] = {.uop_mask = 1 << UOP_BRANCH}, + [UNIT_LOAD] = {.uop_mask = 1 << UOP_LOAD}, + [UNIT_STORE_ADDR] = {.uop_mask = 1 << UOP_STOREADDR}, + [UNIT_STORE_DATA] = {.uop_mask = 1 << UOP_STOREDATA} +}; +const int nr_units = (sizeof(units) / sizeof(p6_unit_t)); + +static int uop_run(const p6_uop_t *uop, int decode_time) +{ +#if 0 + int c; + p6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; + + /*Find execution unit for this uOP*/ + for (c = 0; c < nr_units; c++) + { + if (units[c].uop_mask & (1 << uop->type)) + { + if (units[c].first_available_cycle < best_start_cycle) + { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } + } + } + if (!best_unit) + fatal("uop_run: can not find execution unit %x\n", uop->type); + + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; + + return best_start_cycle + uop->throughput; +#endif + return decode_time+1; +} + +/*The P6 decoder can decode up to three instructions per clock + First can be up to 4 uOPs + Second and third must be 1 uOP each + Up to 16 bytes per cycle + 1 cycle per prefix beyond 1 prefix + 0x66 causes delays if instruction has immediate + 0x67 causes delays if modr/m present (and mod != 3) +*/ +static struct +{ + int nr_ins; + int nr_uops; + const p6_uop_t *uops[6]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[6]; +} decode_buffer; + +#define NR_REGS 8 +/*Timestamp of when last operation on an integer register completed*/ +static int reg_available_timestamp[NR_REGS]; +/*Timestamp of when last operation on an FPU register completed*/ +static int fpu_st_timestamp[8]; +/*Completion time of the last uop to be processed. Used to calculate timing of + dependent uop chains*/ +static int last_uop_timestamp = 0; + +static void decode_flush() +{ + int c; + int uop_timestamp = 0; + + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; + + /*Submit uops to execution units, and determine the latest completion time*/ + for (c = 0; c < decode_buffer.nr_uops; c++) + { + int start_timestamp; + +// pclog("uOP %i, %p\n", c, decode_buffer.uops[c]); + + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; + else + start_timestamp = decode_buffer.earliest_start[c]; + + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } + + /*Calculate opquad completion time. Since opquads complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + decode_timestamp++; + decode_buffer.nr_uops = 0; + decode_buffer.nr_ins = 0; +} + +/*The instruction is only of interest here if it's longer than 8 bytes, as that's the + limit on P6 short decoding*/ +static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +{ + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) + { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_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; +} + +static int ifetch_length = 0; +static void decode_instruction(const p6_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, uint32_t op_pc, int bit8) +{ + uint32_t regmask_required; + uint32_t regmask_modified; + int c, d; + int earliest_start = 0; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) + { + if (regmask_required & (1 << c)) + { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; + } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if ((deps & FPU_RW_STREG)) + { + int reg = fetchdat & 7; + + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } + +// pclog("ins->nr_uops=%i decode_buffer.nr_uops=%i decode_buffer.nr_ins=%i instr_length=%i\n", ins->nr_uops, decode_buffer.nr_uops, decode_buffer.nr_ins, instr_length); + + /*Can only decode 16 bytes per cycle*/ + if ((ifetch_length + instr_length) > 16) + decode_flush(); + else + ifetch_length += instr_length; + + if (ins->nr_uops > 4) + { +// pclog("Long decode\n"); + /*Multi-cycle decode (> 4 uOPs) instruction*/ + if (decode_buffer.nr_ins) + decode_flush(); + + d = 0; + + for (c = 0; c < ins->nr_uops; c++) + { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; + + if (d == 4) + { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush(); + } + } + if (d) + { + decode_buffer.nr_uops = d; + decode_flush(); + } + } + else if (ins->nr_uops > 1 || instr_length > 8) + { +// pclog("Mid decode\n"); + /*Long (> 1 uOPs) instruction*/ + if (decode_buffer.nr_ins) + decode_flush(); + + decode_buffer.nr_uops = ins->nr_uops; + + for (c = 0; c < ins->nr_uops; c++) + { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; + else + decode_buffer.earliest_start[c] = -1; + } + decode_buffer.nr_ins++; + } + else if (ins->nr_uops == 1) + { +// pclog("Short decode\n"); + /*Short (1 uOP) instruction*/ + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_ins++; + decode_buffer.nr_uops++; + + if (decode_buffer.nr_ins == 3) + decode_flush(); + } + + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) + { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) + { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c+1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) + { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c+2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) + { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c+1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) + { + int reg = fetchdat & 7; + if (deps & FPU_POP) + reg--; + if (reg >= 0 && + !(reg == 0 && (deps & FPU_WRITE_ST0)) && + !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } +} + +void codegen_timing_p6_block_start() +{ + int c; + + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; + + decode_timestamp = 0; + last_complete_timestamp = 0; + + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; +} + +void codegen_timing_p6_start() +{ +// units = p6_units; +// nr_units = NR_P6_UNITS; + last_prefix = 0; + prefixes = 0; +} + +/*Prefixes : + - first is free + - operand size prefix has a penalty of 'a few clocks' if instruction has 16 or + 32 bit immediate + - address size prefix has penalty if instruction has explicit memory operand*/ +void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) +{ + if (last_prefix) /*First prefix is free*/ + decode_timestamp++; + + last_prefix = prefix; + prefixes++; +} + +void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +{ + const p6_instruction_t **ins_table; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); + +// pclog("timing_opcode %02x\n", opcode); + switch (last_prefix) + { + case 0x0f: + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; +// pclog("timings 0f\n"); + break; + + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; +// pclog("timings d8\n"); + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings d9\n"); + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; +// pclog("timings da\n"); + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings db\n"); + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; +// pclog("timings dc\n"); + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; +// pclog("timings dd\n"); + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; +// pclog("timings de\n"); + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; +// pclog("timings df\n"); + break; + + default: + switch (opcode) + { + case 0x80: case 0x81: case 0x82: case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + 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 0xd0: case 0xd2: + case 0xc1: case 0xd1: case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; +// pclog("timings c1\n"); + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f6\n"); + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f7\n"); + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; +// pclog("timings ff\n"); + break; + + default: + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; +// pclog("timings normal\n"); + break; + } + } + + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, op_pc, bit8); + else + decode_instruction(&alu01_op, 0, fetchdat, op_32, op_pc, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); +} + +void codegen_timing_p6_block_end() +{ + if (decode_buffer.nr_ins) + { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } +// pclog("codegen_block_cycles=%i\n", codegen_block_cycles); +} + +int codegen_timing_p6_jump_cycles() +{ + if (decode_buffer.nr_uops) + return 1; + return 0; +} + +codegen_timing_t codegen_timing_p6 = +{ + codegen_timing_p6_start, + codegen_timing_p6_prefix, + codegen_timing_p6_opcode, + codegen_timing_p6_block_start, + codegen_timing_p6_block_end, + codegen_timing_p6_jump_cycles +}; + diff --git a/src/cpu.c b/src/cpu.c index 6601413..13d3c9b 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1051,7 +1051,7 @@ void cpu_set() cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; - codegen_timing_set(&codegen_timing_pentium); + codegen_timing_set(&codegen_timing_p6); break; default: From 4fd7305d1dcf6e2bce20506f30709c5263d2d016 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 25 Jun 2020 19:47:10 +0100 Subject: [PATCH 0862/1050] Limit P6 pipeline throughput to 3 uOPs/cycle --- src/codegen_timing_p6.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/codegen_timing_p6.c b/src/codegen_timing_p6.c index 49a90a1..7f9a8e0 100644 --- a/src/codegen_timing_p6.c +++ b/src/codegen_timing_p6.c @@ -1606,8 +1606,26 @@ static p6_unit_t units[] = }; const int nr_units = (sizeof(units) / sizeof(p6_unit_t)); +static int rat_timestamp = 0; +static int rat_uops = 0; + static int uop_run(const p6_uop_t *uop, int decode_time) { + /*Peak of 3 uOPs from decode to RAT per cycle*/ + if (decode_time < rat_timestamp) + decode_time = rat_timestamp; + else if (decode_time > rat_timestamp) + { + rat_timestamp = decode_time; + rat_uops = 0; + } + + rat_uops++; + if (rat_uops == 3) + { + rat_timestamp++; + rat_uops = 0; + } #if 0 int c; p6_unit_t *best_unit = NULL; @@ -1908,7 +1926,10 @@ void codegen_timing_p6_block_start() decode_timestamp = 0; last_complete_timestamp = 0; - + + rat_timestamp = 0; + rat_uops = 0; + for (c = 0; c < NR_REGS; c++) reg_available_timestamp[c] = 0; for (c = 0; c < 8; c++) From 5ad5764500c93b2eb9f7e66399f315b72a9e8631 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 26 Jun 2020 20:37:39 +0100 Subject: [PATCH 0863/1050] Add P6 execution unit timing. OoO behaviour is not very faithful yet. --- src/codegen_timing_p6.c | 51 +++++++++++++++++++++++++---------------- src/ibm.h | 3 ++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/codegen_timing_p6.c b/src/codegen_timing_p6.c index 7f9a8e0..0aee290 100644 --- a/src/codegen_timing_p6.c +++ b/src/codegen_timing_p6.c @@ -1559,7 +1559,8 @@ static int last_complete_timestamp; typedef struct p6_unit_t { - uint32_t uop_mask; + const uint32_t uop_mask; + const int port; int first_available_cycle; } p6_unit_t; @@ -1582,6 +1583,8 @@ typedef struct p6_port_t uint32_t unit_mask; } p6_port_t; +static int port_last_timestamps[5]; + static const p6_port_t ports[] = { {UNIT_INT0 | UNIT_FPU | UNIT_MMX_MUL}, @@ -1594,15 +1597,15 @@ static const p6_port_t ports[] = static p6_unit_t units[] = { - [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU01)}, /*Integer 0*/ - [UNIT_INT1] = {.uop_mask = (1 << UOP_ALU1) | (1 << UOP_ALU01)}, /*Integer 1*/ - [UNIT_FPU] = {.uop_mask = 1 << UOP_FLOAT}, - [UNIT_MMX_ADD] = {.uop_mask = 0}, - [UNIT_MMX_MUL] = {.uop_mask = 0}, - [UNIT_JUMP] = {.uop_mask = 1 << UOP_BRANCH}, - [UNIT_LOAD] = {.uop_mask = 1 << UOP_LOAD}, - [UNIT_STORE_ADDR] = {.uop_mask = 1 << UOP_STOREADDR}, - [UNIT_STORE_DATA] = {.uop_mask = 1 << UOP_STOREDATA} + [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU01), .port = 0}, /*Integer 0*/ + [UNIT_INT1] = {.uop_mask = (1 << UOP_ALU1) | (1 << UOP_ALU01), .port = 1}, /*Integer 1*/ + [UNIT_FPU] = {.uop_mask = 1 << UOP_FLOAT, .port = 0}, + [UNIT_MMX_ADD] = {.uop_mask = 0, .port = 1}, + [UNIT_MMX_MUL] = {.uop_mask = 0, .port = 0}, + [UNIT_JUMP] = {.uop_mask = 1 << UOP_BRANCH, .port = 1}, + [UNIT_LOAD] = {.uop_mask = 1 << UOP_LOAD, .port = 2}, + [UNIT_STORE_ADDR] = {.uop_mask = 1 << UOP_STOREADDR, .port = 3}, + [UNIT_STORE_DATA] = {.uop_mask = 1 << UOP_STOREDATA, .port = 4} }; const int nr_units = (sizeof(units) / sizeof(p6_unit_t)); @@ -1611,6 +1614,10 @@ static int rat_uops = 0; static int uop_run(const p6_uop_t *uop, int decode_time) { + int c; + p6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; + /*Peak of 3 uOPs from decode to RAT per cycle*/ if (decode_time < rat_timestamp) decode_time = rat_timestamp; @@ -1626,20 +1633,21 @@ static int uop_run(const p6_uop_t *uop, int decode_time) rat_timestamp++; rat_uops = 0; } -#if 0 - int c; - p6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; + /*Find execution unit for this uOP*/ for (c = 0; c < nr_units; c++) { - if (units[c].uop_mask & (1 << uop->type)) + p6_unit_t *unit = &units[c]; + if (unit->uop_mask & (1 << uop->type)) { - if (units[c].first_available_cycle < best_start_cycle) + int start_cycle = MAX(unit->first_available_cycle, + port_last_timestamps[units[c].port]); + + if (start_cycle < best_start_cycle) { - best_unit = &units[c]; - best_start_cycle = units[c].first_available_cycle; + best_unit = unit; + best_start_cycle = start_cycle; } } } @@ -1649,10 +1657,10 @@ static int uop_run(const p6_uop_t *uop, int decode_time) if (best_start_cycle < decode_time) best_start_cycle = decode_time; best_unit->first_available_cycle = best_start_cycle + uop->throughput; + port_last_timestamps[best_unit->port] = best_start_cycle + 1; return best_start_cycle + uop->throughput; -#endif - return decode_time+1; +// return decode_time+1; } /*The P6 decoder can decode up to three instructions per clock @@ -1929,6 +1937,9 @@ void codegen_timing_p6_block_start() rat_timestamp = 0; rat_uops = 0; + + for (c = 0; c < 5; c++) + port_last_timestamps[c] = 0; for (c = 0; c < NR_REGS; c++) reg_available_timestamp[c] = 0; diff --git a/src/ibm.h b/src/ibm.h index 925b889..1d0f48b 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -8,7 +8,8 @@ #undef ABS #endif -#define ABS(x) ((x) > 0 ? (x) : -(x)) +#define ABS(x) ((x) > 0 ? (x) : -(x)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define printf pclog From 3c4fa0511ef4a219d068db1631b91a1c2eaa5082 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 27 Jun 2020 11:55:45 +0100 Subject: [PATCH 0864/1050] Add Pentium II Overdrive emulation. --- src/cpu.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cpu.h | 1 + src/cpu_tables.c | 2 ++ 3 files changed, 70 insertions(+) diff --git a/src/cpu.c b/src/cpu.c index 13d3c9b..4a96355 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1054,6 +1054,55 @@ void cpu_set() codegen_timing_set(&codegen_timing_p6); break; + case CPU_PENTIUM_2: + x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_686_db_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; + x86_opcodes_da_a16 = ops_fpu_686_da_a16; + x86_opcodes_da_a32 = ops_fpu_686_da_a32; + x86_opcodes_db_a16 = ops_fpu_686_db_a16; + x86_opcodes_db_a32 = ops_fpu_686_db_a32; + x86_opcodes_df_a16 = ops_fpu_686_df_a16; + x86_opcodes_df_a32 = ops_fpu_686_df_a32; + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 2; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_p6); + break; + default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } @@ -1593,6 +1642,24 @@ void cpu_CPUID() else EAX = EBX = ECX = EDX = 0; break; + + case CPU_PENTIUM_2: + if (!EAX) + { + EAX = 0x00000001; + EBX = 0x756e6547; + EDX = 0x49656e69; + ECX = 0x6c65746e; + } + else if (EAX == 1) + { + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + } + else + EAX = EBX = ECX = EDX = 0; + break; } } diff --git a/src/cpu.h b/src/cpu.h index 8341be3..c3d0009 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -42,6 +42,7 @@ extern int fpu_type; #define CPU_K6_2P 26 #define CPU_K6_3P 27 #define CPU_PENTIUMPRO 28 +#define CPU_PENTIUM_2 29 #define MANU_INTEL 0 #define MANU_AMD 1 diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 6ee40e8..3f2bc9f 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -508,5 +508,7 @@ CPU cpus_PentiumPro[] = {"Pentium Pro 166", CPU_PENTIUMPRO, fpus_builtin, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, (5*8)/2}, {"Pentium Pro 180", CPU_PENTIUMPRO, fpus_builtin, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, {"Pentium Pro 200", CPU_PENTIUMPRO, fpus_builtin, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 3*8}, + {"Pentium II Overdrive 300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36}, + {"Pentium II Overdrive 333", CPU_PENTIUM_2, fpus_builtin, 21, 333333333, 3, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40}, {"", -1, 0, 0, 0} }; From fda3832e3ab4d56867c4245dffcb8f187ea7d0aa Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 28 Jun 2020 16:05:52 +0100 Subject: [PATCH 0865/1050] Add Gigabyte GA-686BX emulation. As part of this, add i440BX chipset, PIIX4, and i28F002BC Flash. --- src/cpu.c | 29 +++++- src/cpu.h | 16 +-- src/cpu_tables.c | 13 +++ src/i440bx.c | 176 +++++++++++++++++++++++++++++++++ src/i440bx.h | 2 + src/ibm.h | 1 + src/intel_flash.c | 59 +++++++---- src/intel_flash.h | 1 + src/keyboard_at.c | 13 ++- src/mem.c | 36 +++---- src/mem.h | 2 +- src/mem_bios.c | 9 ++ src/model.c | 18 ++++ src/nvr.c | 2 + src/piix.c | 245 +++++++++++++++++++++++++++++++++++++++++++++- src/piix.h | 1 + 16 files changed, 570 insertions(+), 53 deletions(-) create mode 100644 src/i440bx.c create mode 100644 src/i440bx.h diff --git a/src/cpu.c b/src/cpu.c index 4a96355..0192e8c 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -70,6 +70,7 @@ enum CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_CMPXCHG8B = (1 << 8), + CPUID_SEP = (1 << 11), CPUID_CMOV = (1 << 15), CPUID_MMX = (1 << 23) }; @@ -1048,7 +1049,7 @@ void cpu_set() timing_jmp_pm = 3; timing_jmp_pm_gate = 18; timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_SYSCALL; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_p6); @@ -1097,7 +1098,7 @@ void cpu_set() timing_jmp_pm = 3; timing_jmp_pm_gate = 18; timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX | CPU_FEATURE_SYSCALL; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_p6); @@ -1637,7 +1638,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV;// | CPUID_SEP; } else EAX = EBX = ECX = EDX = 0; @@ -1655,7 +1656,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;// | CPUID_SEP; } else EAX = EBX = ECX = EDX = 0; @@ -1735,6 +1736,17 @@ void cpu_RDMSR() break; } break; + case CPU_PENTIUMPRO: + case CPU_PENTIUM_2: + EAX = EDX = 0; + switch (ECX) + { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + break; } } @@ -1818,6 +1830,15 @@ void cpu_WRMSR() break; } break; + case CPU_PENTIUMPRO: + case CPU_PENTIUM_2: + switch (ECX) + { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + } + break; } } diff --git a/src/cpu.h b/src/cpu.h index c3d0009..9a6ff03 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -120,6 +120,7 @@ extern CPU cpus_6x86_SS7[]; extern CPU cpus_K6_S7[]; extern CPU cpus_K6_SS7[]; extern CPU cpus_PentiumPro[]; +extern CPU cpus_Slot1_100MHz[]; extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; @@ -138,13 +139,14 @@ extern int cpu_multi; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ extern int cpu_cyrix_alignment; -#define CPU_FEATURE_RDTSC (1 << 0) -#define CPU_FEATURE_MSR (1 << 1) -#define CPU_FEATURE_MMX (1 << 2) -#define CPU_FEATURE_CR4 (1 << 3) -#define CPU_FEATURE_VME (1 << 4) -#define CPU_FEATURE_CX8 (1 << 5) -#define CPU_FEATURE_3DNOW (1 << 6) +#define CPU_FEATURE_RDTSC (1 << 0) +#define CPU_FEATURE_MSR (1 << 1) +#define CPU_FEATURE_MMX (1 << 2) +#define CPU_FEATURE_CR4 (1 << 3) +#define CPU_FEATURE_VME (1 << 4) +#define CPU_FEATURE_CX8 (1 << 5) +#define CPU_FEATURE_3DNOW (1 << 6) +#define CPU_FEATURE_SYSCALL (1 << 7) extern uint32_t cpu_features; static inline int cpu_has_feature(int feature) diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 3f2bc9f..0c651f8 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -512,3 +512,16 @@ CPU cpus_PentiumPro[] = {"Pentium II Overdrive 333", CPU_PENTIUM_2, fpus_builtin, 21, 333333333, 3, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40}, {"", -1, 0, 0, 0} }; + +CPU cpus_Slot1_100MHz[] = +{ + /*Intel Pentium II*/ + {"Pentium II/233", CPU_PENTIUM_2, fpus_builtin, 20, 233333333, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 28}, + {"Pentium II/266", CPU_PENTIUM_2, fpus_builtin, 20, 266666666, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 32}, + {"Pentium II/300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36}, + {"Pentium II/333", CPU_PENTIUM_2, fpus_builtin, 20, 333333333, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40}, + {"Pentium II/350", CPU_PENTIUM_2, fpus_builtin, 20, 350000000, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 42}, + {"Pentium II/400", CPU_PENTIUM_2, fpus_builtin, 20, 400000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 48}, + {"Pentium II/450", CPU_PENTIUM_2, fpus_builtin, 20, 450000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 54}, + {"", -1, 0, 0, 0} +}; diff --git a/src/i440bx.c b/src/i440bx.c new file mode 100644 index 0000000..4a1304e --- /dev/null +++ b/src/i440bx.c @@ -0,0 +1,176 @@ +#include + +#include "ibm.h" +#include "io.h" +#include "keyboard_at.h" +#include "mem.h" +#include "pci.h" +#include "x86.h" + +#include "i440bx.h" + +static uint8_t card_i440bx[256]; + +static void i440bx_map(uint32_t addr, uint32_t size, int state) +{ + switch (state & 3) + { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); +} + +void i440bx_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 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_i440bx[0x59] ^ val) & 0xf0) + { + i440bx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i440bx_write : PAM0 write %02X\n", val); +// if (val == 0x10) +// output = 3; + break; + case 0x5a: /*PAM1*/ + if ((card_i440bx[0x5a] ^ val) & 0x0f) + i440bx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i440bx[0x5a] ^ val) & 0xf0) + i440bx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i440bx[0x5b] ^ val) & 0x0f) + i440bx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i440bx[0x5b] ^ val) & 0xf0) + i440bx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i440bx[0x5c] ^ val) & 0x0f) + i440bx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i440bx[0x5c] ^ val) & 0xf0) + i440bx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i440bx[0x5d] ^ val) & 0x0f) + i440bx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i440bx[0x5d] ^ val) & 0xf0) + i440bx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i440bx[0x5e] ^ val) & 0x0f) + i440bx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i440bx[0x5e] ^ val) & 0xf0) + i440bx_map(0xe4000, 0x04000, val >> 4); + pclog("i440bx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i440bx[0x5f] ^ val) & 0x0f) + i440bx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i440bx[0x5f] ^ val) & 0xf0) + i440bx_map(0xec000, 0x04000, val >> 4); + pclog("i440bx_write : PAM6 write %02X\n", val); + break; + + case 0x72: /*SMRAM*/ +// pclog("Write SMRAM %02x was %02x\n", val, + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i440bx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i440bx[0x72] & 0x08); + } + if ((card_i440bx[0x72] ^ val) & 0x40) + { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } + + card_i440bx[addr] = val; +} + +uint8_t i440bx_read(int func, int addr, void *priv) +{ + if (func) + return 0xff; + + return card_i440bx[addr]; +} + +void i440bx_init() +{ + pci_add_specific(0, i440bx_read, i440bx_write, NULL); + + memset(card_i440bx, 0, 256); + card_i440bx[0x00] = 0x86; card_i440bx[0x01] = 0x80; /*Intel*/ + card_i440bx[0x02] = 0x92; card_i440bx[0x03] = 0x71; /*82441FX*/ + card_i440bx[0x04] = 0x06; card_i440bx[0x05] = 0x00; + card_i440bx[0x06] = 0x00; card_i440bx[0x07] = 0x02; + card_i440bx[0x08] = 0x02; /*B1 stepping*/ + card_i440bx[0x09] = 0x00; card_i440bx[0x0a] = 0x00; card_i440bx[0x0b] = 0x06; + card_i440bx[0x51] = 0x20; /*66 MHz bus*/ + card_i440bx[0x60] = card_i440bx[0x61] = card_i440bx[0x62] = card_i440bx[0x63] = 0x01; + card_i440bx[0x64] = card_i440bx[0x65] = card_i440bx[0x66] = card_i440bx[0x67] = 0x01; + card_i440bx[0x72] = 0x02; + card_i440bx[0x73] = 0x38; + card_i440bx[0x7a] = 0x02; /*AGP disabled*/ +} + +void i440bx_reset() +{ + i440bx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + i440bx_write(0, 0x5a, 0x0, NULL); + i440bx_write(0, 0x5b, 0x0, NULL); + i440bx_write(0, 0x5c, 0x0, NULL); + i440bx_write(0, 0x5d, 0x0, NULL); + i440bx_write(0, 0x5e, 0x0, NULL); + i440bx_write(0, 0x5f, 0x0, NULL); +} diff --git a/src/i440bx.h b/src/i440bx.h new file mode 100644 index 0000000..8ed559f --- /dev/null +++ b/src/i440bx.h @@ -0,0 +1,2 @@ +void i440bx_init(); +void i440bx_reset(); diff --git a/src/ibm.h b/src/ibm.h index 1d0f48b..86ac97a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -265,6 +265,7 @@ enum ROM_ITAUTEC_INFOWAYM, ROM_DESKPRO, ROM_VS440FX, + ROM_GA686BX, ROM_MAX }; diff --git a/src/intel_flash.c b/src/intel_flash.c index 2d28956..716d450 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -28,7 +28,7 @@ enum typedef struct flash_t { uint8_t command, status; - uint8_t flash_id; + uint16_t flash_id; uint8_t type; int invert_high_pin; mem_mapping_t mapping[8], mapping_h[10]; @@ -71,7 +71,18 @@ static uint16_t flash_readw(uint32_t addr, void *p) flash_t *flash = (flash_t *)p; addr &= flash->addr_mask; if (flash->invert_high_pin) addr ^= 0x10000; - return *(uint16_t *)&(flash->array[addr]); + switch (flash->command) + { + case CMD_READ_ARRAY: + default: + return *(uint16_t *)&(flash->array[addr]); + + case CMD_IID: + return 0x89 | (flash->flash_id << 8); + + case CMD_READ_STATUS: + return flash->status; + } } static uint32_t flash_readl(uint32_t addr, void *p) @@ -187,7 +198,7 @@ static void intel_flash_add_mappings_inverted(flash_t *flash) } } -void *intel_flash_init(uint8_t type) +void *intel_flash_init(uint8_t type, uint8_t flash_id) { FILE *f; flash_t *flash = malloc(sizeof(flash_t)); @@ -232,24 +243,16 @@ void *intel_flash_init(uint8_t type) case ROM_VS440FX: strcpy(flash_path, "vs440fx/"); break; + case ROM_GA686BX: + strcpy(flash_path, "ga686bx/"); + break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); } // pclog("Flash init: Path is: %s\n", flash_path); - switch (type & (FLASH_IS_BXB | FLASH_2MBIT)) - { - case 0: - flash->flash_id = 0x94; - break; - case FLASH_IS_BXB: - flash->flash_id = 0x95; - break; - case FLASH_2MBIT: - flash->flash_id = 0x74; - break; - } + flash->flash_id = flash_id; flash->addr_mask = (type & FLASH_2MBIT) ? 0x3ffff : 0x1ffff; @@ -377,24 +380,29 @@ void *intel_flash_init(uint8_t type) /* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ void *intel_flash_bxt_ami_init() { - return intel_flash_init(FLASH_INVERT); + return intel_flash_init(FLASH_INVERT, 0x94); } /* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */ void *intel_flash_bxt_init() { - return intel_flash_init(0); + return intel_flash_init(0, 0x94); } /* For Acer BIOS'es - Intel 28F001BXB. */ void *intel_flash_bxb_init() { - return intel_flash_init(FLASH_IS_BXB); + return intel_flash_init(FLASH_IS_BXB, 0x95); } static void *intel_flash_28fb200bxt_init(void) { - return intel_flash_init(FLASH_INVERT | FLASH_2MBIT); + return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x74); +} + +static void *intel_flash_28f002bc_init(void) +{ + return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x7c); } void intel_flash_close(void *p) @@ -468,3 +476,16 @@ device_t intel_flash_28fb200bxt_device = NULL, NULL }; + +device_t intel_flash_28f002bc_device = +{ + "Intel 28F002BC Flash BIOS", + 0, + intel_flash_28f002bc_init, + intel_flash_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/intel_flash.h b/src/intel_flash.h index 8ab1a6b..2ea4db5 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -2,3 +2,4 @@ extern device_t intel_flash_bxt_ami_device; extern device_t intel_flash_bxt_device; extern device_t intel_flash_bxb_device; extern device_t intel_flash_28fb200bxt_device; +extern device_t intel_flash_28f002bc_device; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 5cadb78..572ab30 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -310,6 +310,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.output_port = val; break; + case 0xd2: /*Write to keyboard output buffer*/ + keyboard_at_adddata(val); + break; + case 0xd3: /*Write to mouse output buffer*/ keyboard_at_adddata_mouse(val); break; @@ -624,7 +628,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) break; case 0xca: /*AMI - read keyboard mode*/ - keyboard_at_adddata(0x00); /*ISA mode*/ + if (romset == ROM_GA686BX) /*TODO*/ + keyboard_at_adddata(0x01); /*PS2 mode*/ + else + keyboard_at_adddata(0x00); /*ISA mode*/ break; case 0xcb: /*AMI - set keyboard mode*/ @@ -643,6 +650,10 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.want60 = 1; break; + case 0xd2: /*Write keyboard output buffer*/ + keyboard_at.want60 = 1; + break; + case 0xd3: /*Write mouse output buffer*/ keyboard_at.want60 = 1; break; diff --git a/src/mem.c b/src/mem.c index 8c23410..fc53ab0 100644 --- a/src/mem.c +++ b/src/mem.c @@ -33,7 +33,7 @@ mem_mapping_t ram_high_mapping; mem_mapping_t ram_mid_mapping; mem_mapping_t ram_remapped_mapping; mem_mapping_t bios_mapping[8]; -mem_mapping_t bios_high_mapping[8]; +mem_mapping_t bios_high_mapping[9]; static mem_mapping_t romext_mapping; static uint8_t ff_array[0x1000]; @@ -1343,24 +1343,26 @@ void mem_add_bios() { if (AT || (romset == ROM_XI8088 && xi8088_bios_128kb())) { - mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[0], 0xe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x20000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[1], 0xe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x24000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[2], 0xe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x28000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[3], 0xec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x2c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); } - mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[4], 0xf0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x30000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[5], 0xf4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x34000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[6], 0xf8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x38000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_mapping[7], 0xfc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x3c000 & biosmask), MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x4000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x8000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0xc000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x10000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x14000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x18000 & biosmask), MEM_MAPPING_ROM, 0); - mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x1c000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[0], (AT && cpu_16bitbus) ? 0xfe0000 : 0xfffe0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x20000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[1], (AT && cpu_16bitbus) ? 0xfe4000 : 0xfffe4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x24000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[2], (AT && cpu_16bitbus) ? 0xfe8000 : 0xfffe8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x28000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[3], (AT && cpu_16bitbus) ? 0xfec000 : 0xfffec000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x2c000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[4], (AT && cpu_16bitbus) ? 0xff0000 : 0xffff0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x30000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[5], (AT && cpu_16bitbus) ? 0xff4000 : 0xffff4000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x34000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[6], (AT && cpu_16bitbus) ? 0xff8000 : 0xffff8000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x38000 & biosmask), MEM_MAPPING_ROM, 0); + mem_mapping_add(&bios_high_mapping[7], (AT && cpu_16bitbus) ? 0xffc000 : 0xffffc000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (0x3c000 & biosmask), MEM_MAPPING_ROM, 0); + if (biosmask == 0x3ffff) + mem_mapping_add(&bios_high_mapping[8], (AT && cpu_16bitbus) ? 0xfc0000 : 0xfffc0000, 0x20000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, MEM_MAPPING_ROM, 0); } int mem_a20_key = 0, mem_a20_alt = 0; diff --git a/src/mem.h b/src/mem.h index 5c7935b..34d5194 100644 --- a/src/mem.h +++ b/src/mem.h @@ -107,7 +107,7 @@ 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]; +mem_mapping_t bios_high_mapping[9]; extern mem_mapping_t ram_high_mapping; extern mem_mapping_t ram_remapped_mapping; diff --git a/src/mem_bios.c b/src/mem_bios.c index 78e59c7..f461a79 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -1167,6 +1167,15 @@ int loadbios() biosmask = 0x3ffff; return 1; + + case ROM_GA686BX: + f = romfopen("ga686bx/6BX.F2a", "rb"); + if (!f) break; + romfread(rom, 0x40000, 1, f); + fclose(f); + + biosmask = 0x3ffff; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 35a2efd..de53ef2 100644 --- a/src/model.c +++ b/src/model.c @@ -29,6 +29,7 @@ #include "i430hx.h" #include "i430lx.h" #include "i430vx.h" +#include "i440bx.h" #include "i440fx.h" #include "ide.h" #include "intel.h" @@ -133,6 +134,7 @@ void xt_xi8088_init(); void xt_zenith_init(); void at_mvp3_init(); void at_vs440fx_init(); +void at_ga686bx_init(); int model; int AMSTRAD, AT, PCI, TANDY, MCA; @@ -241,6 +243,8 @@ MODEL models[] = {"[Socket 8] Intel VS440FX", ROM_VS440FX, "vs440fx", { {"Intel", cpus_PentiumPro}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 8, at_vs440fx_init, NULL}, + {"[Slot 1] Gigabyte GA-686BX", ROM_GA686BX, "ga686bx", { {"Intel", cpus_Slot1_100MHz}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 512, 8, at_ga686bx_init, NULL}, + {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; @@ -833,6 +837,20 @@ void at_vs440fx_init() device_add(&intel_flash_28fb200bxt_device); } +void at_ga686bx_init() +{ + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x8); + pci_slot(0x9); + pci_slot(0xa); + pci_slot(0xb); + i440bx_init(); + piix4_init(7, 0x8, 0x9, 0xa, 0xb, i440bx_reset); + w83877tf_init(0x250, 0x89); + device_add(&intel_flash_28f002bc_device); +} + void model_init() { pclog("Initting as %s\n", model_getname()); diff --git a/src/nvr.c b/src/nvr.c index 21df383..0c813c6 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -357,6 +357,7 @@ void loadnvr() case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); nvrmask = 127; break; case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); nvrmask = 127; break; case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "rb"); nvrmask = 127; break; + case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "rb"); nvrmask = 127; break; default: return; } @@ -465,6 +466,7 @@ void savenvr() case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); break; case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "wb"); break; case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "wb"); break; + case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "wb"); break; default: return; } diff --git a/src/piix.c b/src/piix.c index 5ce6ec5..05214ea 100644 --- a/src/piix.c +++ b/src/piix.c @@ -16,15 +16,168 @@ #include "piix.h" +enum +{ + TYPE_PIIX = 0, + TYPE_PIIX3, + TYPE_PIIX4 +}; + +static struct +{ + int type; + + /*PIIX4*/ + uint8_t card_pm[256]; + + uint16_t pmba; + struct + { + uint64_t timer_offset; + } pm; + + uint16_t smbba; + struct + { + uint8_t host_ctrl; + } smbus; + + uint8_t port_92; +} piix; + static uint8_t card_piix[256], card_piix_ide[256]; static sff_busmaster_t piix_busmaster[2]; static uint8_t piix_rc = 0; static void (*piix_nb_reset)(); +static void piix_pm_write(uint16_t port, uint8_t val, void *p) +{ +// pclog("piix_pm_write: port=%04x val=%02x\n", port, val); +} +static uint8_t piix_pm_read(uint16_t port, void *p) +{ + uint8_t ret = 0xff; + + switch (port & 0x3f) + { + case 0x02: case 0x03: + ret = 0; + break; + + case 0x04: case 0x05: + ret = 0; + break; + + case 0x08: case 0x09: case 0x0a: case 0x0b: + { + uint64_t timer = tsc - piix.pm.timer_offset; + uint32_t pm_timer = (timer * 3579545) / cpu_get_speed(); + + ret = pm_timer >> ((port & 3) * 8); + break; + } + + case 0x0e: case 0x0f: + ret = 0; + break; + + case 0x10: case 0x11: + ret = 0; + break; + + case 0x18: case 0x19: + ret = 0; + break; + + case 0x20: case 0x21: + ret = 0; + break; + + case 0x28: case 0x29: case 0x2a: case 0x2b: + ret = 0; + break; + + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + ret = 0; + break; + + case 0x30: + ret = 0; + break; + case 0x31: + ret = 0; + break; + case 0x32: + ret = 0; + break; + +// default: +// fatal("piix_pm_read: unknown read %04x\n", port); + } + + return ret; +} + +static void piix_smbus_write(uint16_t port, uint8_t val, void *p) +{ +// pclog("piix_smbus_write: port=%04x val=%02x\n", port, val); + + switch (port & 0xf) + { + case 0x2: + piix.smbus.host_ctrl = (val & 0x5f) | (piix.smbus.host_ctrl & 0x40); + break; + } +} +static uint8_t piix_smbus_read(uint16_t port, void *p) +{ + uint8_t ret = 0xff; + + switch (port & 0x0f) + { + case 0x0: + ret = 0; + break; + + case 0x2: + ret = piix.smbus.host_ctrl; + break; + + case 0x5: + ret = 0; + break; + +// default: +// fatal("piix_smbus_read: unknown read %04x\n", port); + } + + return ret; +} + +static void pm_clear_io(void) +{ + io_removehandler(piix.pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, NULL); + io_removehandler(piix.smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, NULL); +} +static void pm_set_io(void) +{ +// pclog("pm_set_io: %02x %04x\n", piix.card_pm[0x04], piix.smbba); + if ((piix.card_pm[0x04] & 0x01) && piix.pmba) + { +// pclog("PMBA=%04x\n", piix.pmba); + io_sethandler(piix.pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, NULL); + } + if ((piix.card_pm[0x04] & 0x01) && piix.smbba) + { +// pclog("SMBBA=%04x\n", piix.smbba); + io_sethandler(piix.smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, NULL); + } +} + void piix_write(int func, int addr, uint8_t val, void *priv) { // pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); - if (func > 1) + if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1)) return; if (func == 1) /*IDE*/ @@ -82,6 +235,41 @@ void piix_write(int func, int addr, uint8_t val, void *priv) } // pclog("PIIX write %02X %02X\n", addr, val); } + else if (func == 2) /*USB*/ + { + /*Not implemented*/ + } + else if (func == 3) /*PM*/ + { + switch (addr) + { + case 0x04: + pm_clear_io(); + piix.card_pm[0x04] = val & 1; + pm_set_io(); + break; + case 0x40: + pm_clear_io(); + piix.pmba = (piix.pmba & 0xff00) | (val & 0xc0); + pm_set_io(); + break; + case 0x41: + pm_clear_io(); + piix.pmba = (piix.pmba & 0xc0) | (val << 8); + pm_set_io(); + break; + case 0x90: + pm_clear_io(); + piix.smbba = (piix.smbba & 0xff00) | (val & 0xf0); + pm_set_io(); + break; + case 0x91: + pm_clear_io(); + piix.smbba = (piix.smbba & 0xf0) | (val << 8); + pm_set_io(); + break; + } + } else { if (addr >= 0x0f && addr < 0x4c) @@ -130,16 +318,20 @@ 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 > ((piix.type == TYPE_PIIX4) ? 3 : 1)) + return 0xff; if (func == 1) /*IDE*/ { // pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]); return card_piix_ide[addr]; } + else if (func == 2) /*USB*/ + return 0xff; /*Not implemented*/ + else if (func == 3) + return piix.card_pm[addr]; else - return card_piix[addr]; + return card_piix[addr]; } @@ -157,6 +349,7 @@ void piix_rc_write(uint16_t port, uint8_t val, void *p) piix_nb_reset(); keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ ide_reset_devices(); + piix.pm.timer_offset = tsc; } resetx86(); } @@ -164,6 +357,25 @@ void piix_rc_write(uint16_t port, uint8_t val, void *p) piix_rc = val & ~4; } +static uint8_t piix_92_read(uint16_t port, void *p) +{ + return piix.port_92; +} +static void piix_92_write(uint16_t port, uint8_t val, void *p) +{ + if ((mem_a20_alt ^ val) & 2) + { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~piix.port_92 & val) & 1) + { + softresetx86(); + cpu_set_edx(); + } + piix.port_92 = val; +} + void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -217,4 +429,29 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_r io_sethandler(0x0cf9, 0x0001, piix_rc_read, NULL, NULL, piix_rc_write, NULL, NULL, NULL); piix_nb_reset = nb_reset; + + piix.type = TYPE_PIIX3; +} + +void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) +{ + piix_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); + + piix.type = TYPE_PIIX4; + + card_piix[0x02] = 0x10; card_piix[0x03] = 0x71; /*82371EB (PIIX4)*/ + + card_piix_ide[0x02] = 0x11; card_piix_ide[0x03] = 0x71; /*82371EB (PIIX4)*/ + + memset(&piix.card_pm, 0, sizeof(piix.card_pm)); + piix.card_pm[0x00] = 0x86; piix.card_pm[0x01] = 0x80; /*Intel*/ + piix.card_pm[0x02] = 0x13; piix.card_pm[0x03] = 0x71; /*82371EB (PIIX4)*/ + piix.card_pm[0x06] = 0x80; piix.card_pm[0x07] = 0x02; + piix.card_pm[0x09] = 0x00; piix.card_pm[0x0a] = 0x80; piix.card_pm[0x0b] = 0x06; /*Bridge device*/ + piix.card_pm[0x3d] = 0x01; /*IRQA*/ + piix.card_pm[0x40] = 0x01; + piix.card_pm[0x90] = 0x01; + piix.pm.timer_offset = 0; + + io_sethandler(0x0092, 0x0001, piix_92_read, NULL, NULL, piix_92_write, NULL, NULL, NULL); } diff --git a/src/piix.h b/src/piix.h index e8d7039..08b0032 100644 --- a/src/piix.h +++ b/src/piix.h @@ -1 +1,2 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); +void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); From 7eff4f4ba8a668dd5ada119e3a9b890bd17c0c2e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 29 Jun 2020 22:19:41 +0100 Subject: [PATCH 0866/1050] Add SYSENTER and SYSEXIT instructions --- src/386_common.c | 3 ++ src/386_ops.h | 99 ++++++++++++++++++++++++++++++++++++++++++++-- src/cpu.c | 29 ++++++++++++-- src/x86.h | 6 +++ src/x86_ops.h | 2 + src/x86_ops_flag.h | 5 ++- src/x86_ops_misc.h | 25 ++++++++++++ src/x86seg.c | 64 ++++++++++++++++++++++++++++++ 8 files changed, 224 insertions(+), 9 deletions(-) diff --git a/src/386_common.c b/src/386_common.c index df19e14..4d0a761 100644 --- a/src/386_common.c +++ b/src/386_common.c @@ -9,6 +9,9 @@ x86seg gdt, ldt, idt, tr; uint32_t cr2, cr3, cr4; uint32_t dr[8]; +uint16_t sysenter_cs; +uint32_t sysenter_eip, sysenter_esp; + uint32_t use32; int stack32; int optype; diff --git a/src/386_ops.h b/src/386_ops.h index e57389e..a7a791c 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -827,7 +827,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -849,7 +849,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -871,7 +871,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -893,7 +893,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -911,6 +911,97 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; +OpFn OP_TABLE(pentium2_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, +/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, +/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, +/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, +/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +}; + OpFn OP_TABLE(286)[1024] = { /*16-bit data, 16-bit addr*/ diff --git a/src/cpu.c b/src/cpu.c index 0192e8c..2de3673 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1056,7 +1056,7 @@ void cpu_set() break; case CPU_PENTIUM_2: - x86_setopcodes(ops_386, ops_c6x86mx_0f, dynarec_ops_386, dynarec_ops_c6x86mx_0f); + x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_686_db_a16; @@ -1638,7 +1638,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV;// | CPUID_SEP; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_SEP; } else EAX = EBX = ECX = EDX = 0; @@ -1656,7 +1656,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;// | CPUID_SEP; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX | CPUID_SEP; } else EAX = EBX = ECX = EDX = 0; @@ -1745,6 +1745,19 @@ void cpu_RDMSR() EAX = tsc & 0xffffffff; EDX = tsc >> 32; break; + + case 0x174: + EAX = sysenter_cs; + EDX = 0; + break; + case 0x175: + EAX = sysenter_esp; + EDX = 0; + break; + case 0x176: + EAX = sysenter_eip; + EDX = 0; + break; } break; } @@ -1837,6 +1850,16 @@ void cpu_WRMSR() case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; + + case 0x174: + sysenter_cs = EAX & 0xffff; + break; + case 0x175: + sysenter_esp = EAX; + break; + case 0x176: + sysenter_eip = EAX; + break; } break; } diff --git a/src/x86.h b/src/x86.h index a9365c0..578ebdd 100644 --- a/src/x86.h +++ b/src/x86.h @@ -175,6 +175,9 @@ extern x86seg gdt, ldt, idt, tr; extern uint32_t cr2, cr3, cr4; extern uint32_t dr[8]; +extern uint16_t sysenter_cs; +extern uint32_t sysenter_eip, sysenter_esp; + extern uint16_t cpu_cur_status; @@ -294,6 +297,9 @@ void x86_int(int num); void x86_int_sw(int num); int x86_int_sw_rm(int num); +void sysenter(void); +void sysexit(void); + int divl(uint32_t val); int idivl(int32_t val); diff --git a/src/x86_ops.h b/src/x86_ops.h index d317f50..8cdd4e7 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -39,6 +39,7 @@ extern OpFn dynarec_ops_winchip2_0f[1024]; extern OpFn dynarec_ops_pentium_0f[1024]; extern OpFn dynarec_ops_pentiummmx_0f[1024]; extern OpFn dynarec_ops_pentiumpro_0f[1024]; +extern OpFn dynarec_ops_pentium2_0f[1024]; extern OpFn dynarec_ops_c6x86mx_0f[1024]; @@ -107,6 +108,7 @@ extern OpFn ops_winchip2_0f[1024]; extern OpFn ops_pentium_0f[1024]; extern OpFn ops_pentiummmx_0f[1024]; extern OpFn ops_pentiumpro_0f[1024]; +extern OpFn ops_pentium2_0f[1024]; extern OpFn ops_c6x86mx_0f[1024]; diff --git a/src/x86_ops_flag.h b/src/x86_ops_flag.h index db1dc20..04ceda1 100644 --- a/src/x86_ops_flag.h +++ b/src/x86_ops_flag.h @@ -85,11 +85,12 @@ static int opSTI(uint32_t fetchdat) else cpu_state.flags |= I_FLAG; - CPU_BLOCK_END(); +/*TODO - should end block after 1 further instruction*/ +// CPU_BLOCK_END(); CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + return 1; } static int opSAHF(uint32_t fetchdat) diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index aa81a2c..b34570f 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -970,3 +970,28 @@ static int opWRMSR(uint32_t fetchdat) return 1; } +static int opSYSENTER(uint32_t fetchdat) +{ + if (!(cr0 & 1) || !(sysenter_cs & 0xfffc)) + { + x86gpf(NULL,0); + return 1; + } +// pclog("opSYSENTER: CS=%04x EIP=%08x ESP=%08x %04x:%08x %i\n", sysenter_cs, sysenter_eip, sysenter_esp, CS,cpu_state.pc, times); + sysenter(); + CPU_BLOCK_END(); + return 0; +} + +static int opSYSEXIT(uint32_t fetchdat) +{ + if (!(cr0 & 1) || !(sysenter_cs & 0xfffc) || CPL) + { + x86gpf(NULL,0); + return 1; + } +// pclog("opSYSEXIT\n"); + sysexit(); + CPU_BLOCK_END(); + return 0; +} diff --git a/src/x86seg.c b/src/x86seg.c index acaa2dd..f28e7c5 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2873,3 +2873,67 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) tr.access=segdat[2]>>8; } + +void sysenter(void) +{ + cpu_state.eflags &= ~VM_FLAG; + cpu_state.flags &= ~I_FLAG; + + ESP = sysenter_esp; + cpu_state.pc = sysenter_eip; + + cpu_state.seg_cs.seg = sysenter_cs & 0xfffc; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = 0x1b; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; + + cpu_state.seg_ss.seg = (sysenter_cs & 0xfffc) + 8; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.limit_high = 0xffffffff; + cpu_state.seg_ss.access = 0x13; + cpu_state.seg_ss.checked = 1; + + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); + set_use32(1); + set_stack32(1); + +// pclog("syscall to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); +} + +void sysexit(void) +{ + ESP = ECX; + cpu_state.pc = EDX; + + cpu_state.seg_cs.seg = (sysenter_cs | 3) + 16; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = 0x7b; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; + + cpu_state.seg_ss.seg = (sysenter_cs | 3) + 24; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.limit_high = 0xffffffff; + cpu_state.seg_ss.access = 0x73; + cpu_state.seg_ss.checked = 1; + + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); + flushmmucache_cr3(); + set_use32(1); + set_stack32(1); + +// pclog("sysexit to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); +} From b973755ca376dbb47c3a8c85a53f4058f0ccc54d Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 30 Jun 2020 20:19:58 +0100 Subject: [PATCH 0867/1050] Add hintable NOPs for Pentium Pro and II. --- src/386_ops.h | 16 ++++++++-------- src/codegen.c | 2 +- src/x86_ops_misc.h | 11 +++++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/386_ops.h b/src/386_ops.h index a7a791c..0f78ffa 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -825,7 +825,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -847,7 +847,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -869,7 +869,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -891,7 +891,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -916,7 +916,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -938,7 +938,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -960,7 +960,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -982,7 +982,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, opSYSENTER, opSYSEXIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, diff --git a/src/codegen.c b/src/codegen.c index a84e8cf..4206db3 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -368,7 +368,7 @@ static uint8_t opcode_modrm[256] = static uint8_t opcode_0f_modrm[256] = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ 1, 1, 1, 1, 1, 1, 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*/ diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index b34570f..4dc7566 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -995,3 +995,14 @@ static int opSYSEXIT(uint32_t fetchdat) CPU_BLOCK_END(); return 0; } + +static int opHINTNOP_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + return 0; +} +static int opHINTNOP_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + return 0; +} From bf68656e8fedf58fa3cf303d8bd7175a6720a2e8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 30 Jun 2020 21:07:21 +0100 Subject: [PATCH 0868/1050] Implement CPUID cache register for Pentium Pro/II. --- src/cpu.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 2de3673..a08f2f1 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1629,7 +1629,7 @@ void cpu_CPUID() case CPU_PENTIUMPRO: if (!EAX) { - EAX = 0x00000001; + EAX = 0x00000002; EBX = 0x756e6547; EDX = 0x49656e69; ECX = 0x6c65746e; @@ -1640,6 +1640,13 @@ void cpu_CPUID() EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_SEP; } + else if (EAX == 2) + { + EAX = 0x03020101; + EBX = 0; + ECX = 0; + EDX = 0x06040a42; + } else EAX = EBX = ECX = EDX = 0; break; @@ -1647,7 +1654,7 @@ void cpu_CPUID() case CPU_PENTIUM_2: if (!EAX) { - EAX = 0x00000001; + EAX = 0x00000002; EBX = 0x756e6547; EDX = 0x49656e69; ECX = 0x6c65746e; @@ -1658,6 +1665,13 @@ void cpu_CPUID() EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX | CPUID_SEP; } + else if (EAX == 2) + { + EAX = 0x03020101; + EBX = 0; + ECX = 0; + EDX = 0x08040c43; + } else EAX = EBX = ECX = EDX = 0; break; From 5b2087f84dfa9e217f6ec514e0ce18fb742213ed Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 30 Jun 2020 21:20:53 +0100 Subject: [PATCH 0869/1050] Added Celeron emulation. --- src/cpu.c | 15 ++++++++++++++- src/cpu.h | 2 ++ src/cpu_tables.c | 12 ++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/cpu.c b/src/cpu.c index a08f2f1..3335a3e 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1056,6 +1056,8 @@ void cpu_set() break; case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: x86_setopcodes(ops_386, ops_pentium2_0f, dynarec_ops_386, dynarec_ops_pentium2_0f); x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_686_da_a16; x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_686_da_a32; @@ -1652,6 +1654,8 @@ void cpu_CPUID() break; case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: if (!EAX) { EAX = 0x00000002; @@ -1670,7 +1674,12 @@ void cpu_CPUID() EAX = 0x03020101; EBX = 0; ECX = 0; - EDX = 0x08040c43; + if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUM_2) + EDX = 0x08040c43; /*512kb L2 cache*/ + else if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_CELERON) + EDX = 0x08040c40; /*No L2 cache*/ + else + EDX = 0x08040c41; /*128kb L2 cache*/ } else EAX = EBX = ECX = EDX = 0; @@ -1752,6 +1761,8 @@ void cpu_RDMSR() break; case CPU_PENTIUMPRO: case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: EAX = EDX = 0; switch (ECX) { @@ -1859,6 +1870,8 @@ void cpu_WRMSR() break; case CPU_PENTIUMPRO: case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: switch (ECX) { case 0x10: diff --git a/src/cpu.h b/src/cpu.h index 9a6ff03..dad9d2b 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -43,6 +43,8 @@ extern int fpu_type; #define CPU_K6_3P 27 #define CPU_PENTIUMPRO 28 #define CPU_PENTIUM_2 29 +#define CPU_CELERON 30 +#define CPU_CELERON_A 31 #define MANU_INTEL 0 #define MANU_AMD 1 diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 0c651f8..3ff519c 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -523,5 +523,17 @@ CPU cpus_Slot1_100MHz[] = {"Pentium II/350", CPU_PENTIUM_2, fpus_builtin, 20, 350000000, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 42}, {"Pentium II/400", CPU_PENTIUM_2, fpus_builtin, 20, 400000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 48}, {"Pentium II/450", CPU_PENTIUM_2, fpus_builtin, 20, 450000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 54}, + {"Pentium II/266", CPU_PENTIUM_2, fpus_builtin, 20, 266666666, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 32}, + {"Pentium II/300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36}, + {"Celeron 266", CPU_CELERON, fpus_builtin, 20, 266666666, 3, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 32}, + {"Celeron 300", CPU_CELERON, fpus_builtin, 20, 300000000, 3, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36}, + {"Celeron-A 300", CPU_CELERON_A, fpus_builtin, 20, 300000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40}, + {"Celeron 333", CPU_CELERON_A, fpus_builtin, 20, 333333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 44}, + {"Celeron 366", CPU_CELERON_A, fpus_builtin, 20, 366666666, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 48}, + {"Celeron 400", CPU_CELERON_A, fpus_builtin, 20, 400000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 52}, + {"Celeron 433", CPU_CELERON_A, fpus_builtin, 20, 433333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 56}, + {"Celeron 466", CPU_CELERON_A, fpus_builtin, 20, 466666666, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 60}, + {"Celeron 500", CPU_CELERON_A, fpus_builtin, 20, 500000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 64}, + {"Celeron 533", CPU_CELERON_A, fpus_builtin, 20, 533333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 68}, {"", -1, 0, 0, 0} }; From 4fe71bdbed6ea85fd636d4e0b509de031634a7ff Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 1 Jul 2020 21:50:11 +0100 Subject: [PATCH 0870/1050] The instruction following STI is always executed, even if an interrupt is pending. Fixes Windows 9x boot broken by SYSENTER commit. --- src/386_dynarec.c | 25 +++++++++++++++++++++++++ src/x86.h | 2 ++ src/x86_ops_flag.h | 9 +++++---- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index fd2861b..12ecebf 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -238,6 +238,8 @@ static void prefetch_flush() #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) //#define CACHE_ON() 0 +int cpu_end_block_after_ins = 0; + static int cycles_main = 0; void exec386_dynarec(int cycs) { @@ -297,10 +299,17 @@ void exec386_dynarec(int cycs) CPU_BLOCK_END(); if (nmi && nmi_enable && nmi_mask) CPU_BLOCK_END(); + if (cpu_end_block_after_ins) + { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } ins++; insc++; } + cpu_end_block_after_ins = 0; } else { @@ -458,6 +467,13 @@ void exec386_dynarec(int cycs) if (nmi && nmi_enable && nmi_mask) CPU_BLOCK_END(); + if (cpu_end_block_after_ins) + { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } + if (cpu_state.abrt) { codegen_block_remove(); @@ -467,6 +483,7 @@ void exec386_dynarec(int cycs) ins++; insc++; } + cpu_end_block_after_ins = 0; if (!cpu_state.abrt && !x86_was_reset) codegen_block_end_recompile(block); @@ -530,6 +547,13 @@ void exec386_dynarec(int cycs) if (nmi && nmi_enable && nmi_mask) CPU_BLOCK_END(); + if (cpu_end_block_after_ins) + { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } + if (cpu_state.abrt) { codegen_block_remove(); @@ -539,6 +563,7 @@ void exec386_dynarec(int cycs) ins++; insc++; } + cpu_end_block_after_ins = 0; if (!cpu_state.abrt && !x86_was_reset) codegen_block_end(); diff --git a/src/x86.h b/src/x86.h index 578ebdd..753edf5 100644 --- a/src/x86.h +++ b/src/x86.h @@ -303,4 +303,6 @@ void sysexit(void); int divl(uint32_t val); int idivl(int32_t val); +extern int cpu_end_block_after_ins; + #endif diff --git a/src/x86_ops_flag.h b/src/x86_ops_flag.h index 04ceda1..64f43e9 100644 --- a/src/x86_ops_flag.h +++ b/src/x86_ops_flag.h @@ -85,12 +85,13 @@ static int opSTI(uint32_t fetchdat) else cpu_state.flags |= I_FLAG; -/*TODO - should end block after 1 further instruction*/ -// CPU_BLOCK_END(); - + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; + CLOCK_CYCLES(2); PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 1; + return 0; } static int opSAHF(uint32_t fetchdat) From 3cbcf5f57578bd0d160f90e20b9f16bcf83c21df Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 6 Jul 2020 22:19:38 +0100 Subject: [PATCH 0871/1050] Optimise Voodoo FIFO processing of framebuffer / texture / register writes. Speeds up games that write large amounts of data to the FIFO, eg menus in Expendable. --- src/vid_voodoo.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 36baf19..ad5f36f 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -6190,12 +6190,8 @@ static void voodoo_writew(uint32_t addr, uint16_t val, void *p) voodoo_t *voodoo = (voodoo_t *)p; voodoo->wr_count++; addr &= 0xffffff; - - if (addr == voodoo->last_write_addr+4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; + + cycles -= voodoo->write_time; if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ queue_command(voodoo, addr | FIFO_WRITEW_FB, val); @@ -6585,23 +6581,45 @@ static void fifo_thread(void *param) switch (fifo->addr_type & FIFO_TYPE) { case FIFO_WRITEL_REG: - voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) + { + voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } break; case FIFO_WRITEW_FB: wait_for_render_thread_idle(voodoo); - voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) + { + voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } break; case FIFO_WRITEL_FB: wait_for_render_thread_idle(voodoo); - voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) + { + voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } break; case FIFO_WRITEL_TEX: - if (!(fifo->addr_type & 0x400000)) - voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) + { + if (!(fifo->addr_type & 0x400000)) + voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } break; } - voodoo->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; if (FIFO_ENTRIES > 0xe000) thread_set_event(voodoo->fifo_not_full_event); @@ -6653,7 +6671,7 @@ static void fifo_thread(void *param) if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) voodoo->cmd_written_fifo++; - + voodoo_reg_writel(addr, val, voodoo); if (header & (1 << 15)) From 41238b3c85c4a8a28b38c831402f8be26ef49b47 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 14 Jul 2020 21:35:23 +0100 Subject: [PATCH 0872/1050] Split vid_voodoo.c into multiple source & header files. --- src/vid_voodoo.c | 6745 +------------------------------ src/vid_voodoo_blitter.c | 479 +++ src/vid_voodoo_blitter.h | 3 + src/vid_voodoo_codegen_x86-64.h | 6 +- src/vid_voodoo_codegen_x86.h | 6 +- src/vid_voodoo_common.h | 399 ++ src/vid_voodoo_display.c | 603 +++ src/vid_voodoo_display.h | 6 + src/vid_voodoo_dither.h | 8 +- src/vid_voodoo_fb.c | 397 ++ src/vid_voodoo_fb.h | 4 + src/vid_voodoo_fifo.c | 394 ++ src/vid_voodoo_fifo.h | 8 + src/vid_voodoo_reg.c | 1140 ++++++ src/vid_voodoo_reg.h | 1 + src/vid_voodoo_regs.h | 680 ++++ src/vid_voodoo_render.c | 1608 ++++++++ src/vid_voodoo_render.h | 324 ++ src/vid_voodoo_setup.c | 215 + src/vid_voodoo_setup.h | 1 + src/vid_voodoo_texture.c | 564 +++ src/vid_voodoo_texture.h | 18 + 22 files changed, 6893 insertions(+), 6716 deletions(-) create mode 100644 src/vid_voodoo_blitter.c create mode 100644 src/vid_voodoo_blitter.h create mode 100644 src/vid_voodoo_common.h create mode 100644 src/vid_voodoo_display.c create mode 100644 src/vid_voodoo_display.h create mode 100644 src/vid_voodoo_fb.c create mode 100644 src/vid_voodoo_fb.h create mode 100644 src/vid_voodoo_fifo.c create mode 100644 src/vid_voodoo_fifo.h create mode 100644 src/vid_voodoo_reg.c create mode 100644 src/vid_voodoo_reg.h create mode 100644 src/vid_voodoo_regs.h create mode 100644 src/vid_voodoo_render.c create mode 100644 src/vid_voodoo_render.h create mode 100644 src/vid_voodoo_setup.c create mode 100644 src/vid_voodoo_setup.h create mode 100644 src/vid_voodoo_texture.c create mode 100644 src/vid_voodoo_texture.h diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index ad5f36f..a59347f 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -10,1079 +10,30 @@ #include "video.h" #include "vid_svga.h" #include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_blitter.h" +#include "vid_voodoo_display.h" #include "vid_voodoo_dither.h" +#include "vid_voodoo_fb.h" +#include "vid_voodoo_fifo.h" +#include "vid_voodoo_reg.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_texture.h" -#ifdef MIN -#undef MIN -#endif -#ifdef CLAMP -#undef CLAMP -#endif -#define MIN(a, b) ((a) < (b) ? (a) : (b)) +rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; -#define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x))) -#define CLAMP16(x) (((x) < 0) ? 0 : (((x) > 0xffff) ? 0xffff : (x))) -#define LOD_MAX 8 - -#define TEX_DIRTY_SHIFT 10 - -#define TEX_CACHE_MAX 64 - -enum -{ - VOODOO_1 = 0, - VOODOO_SB50 = 1, - VOODOO_2 = 2 -}; - -static uint32_t texture_offset[LOD_MAX+3] = -{ - 0, - 256*256, - 256*256 + 128*128, - 256*256 + 128*128 + 64*64, - 256*256 + 128*128 + 64*64 + 32*32, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1 + 1 -}; - -static int tris = 0; +int tris = 0; static uint64_t status_time = 0; -typedef union int_float -{ - uint32_t i; - float f; -} int_float; -typedef struct rgb_t -{ - uint8_t b, g, r; - uint8_t pad; -} rgb_t; -typedef struct rgba8_t -{ - uint8_t b, g, r, a; -} rgba8_t; - -typedef union rgba_u -{ - struct - { - uint8_t b, g, r, a; - } rgba; - uint32_t u; -} rgba_u; - -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) - -#define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx) -#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE-4) -#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITEL_REG = (0x01 << 24), - FIFO_WRITEW_FB = (0x02 << 24), - FIFO_WRITEL_FB = (0x03 << 24), - FIFO_WRITEL_TEX = (0x04 << 24) -}; - -#define PARAM_SIZE 1024 -#define PARAM_MASK (PARAM_SIZE - 1) -#define PARAM_ENTRY_SIZE (1 << 31) - -#define PARAM_ENTRIES_1 (voodoo->params_write_idx - voodoo->params_read_idx[0]) -#define PARAM_ENTRIES_2 (voodoo->params_write_idx - voodoo->params_read_idx[1]) -#define PARAM_FULL_1 ((voodoo->params_write_idx - voodoo->params_read_idx[0]) >= PARAM_SIZE) -#define PARAM_FULL_2 ((voodoo->params_write_idx - voodoo->params_read_idx[1]) >= PARAM_SIZE) -#define PARAM_EMPTY_1 (voodoo->params_read_idx[0] == voodoo->params_write_idx) -#define PARAM_EMPTY_2 (voodoo->params_read_idx[1] == voodoo->params_write_idx) - -typedef struct -{ - uint32_t addr_type; - uint32_t val; -} fifo_entry_t; - -static rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; - -typedef struct voodoo_params_t -{ - int command; - - int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; - - uint32_t startR, startG, startB, startZ, startA; - - int32_t dBdX, dGdX, dRdX, dAdX, dZdX; - - int32_t dBdY, dGdY, dRdY, dAdY, dZdY; - - int64_t startW, dWdX, dWdY; - - struct - { - int64_t startS, startT, startW, p1; - int64_t dSdX, dTdX, dWdX, p2; - int64_t dSdY, dTdY, dWdY, p3; - } tmu[2]; - - uint32_t color0, color1; - - uint32_t fbzMode; - uint32_t fbzColorPath; - - uint32_t fogMode; - rgb_t fogColor; - struct - { - uint8_t fog, dfog; - } fogTable[64]; - - uint32_t alphaMode; - - uint32_t zaColor; - - int chromaKey_r, chromaKey_g, chromaKey_b; - uint32_t chromaKey; - - uint32_t textureMode[2]; - uint32_t tLOD[2]; - - uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; - - uint32_t tex_base[2][LOD_MAX+2]; - uint32_t tex_end[2][LOD_MAX+2]; - int tex_width[2]; - int tex_w_mask[2][LOD_MAX+2]; - int tex_w_nmask[2][LOD_MAX+2]; - int tex_h_mask[2][LOD_MAX+2]; - int tex_shift[2][LOD_MAX+2]; - int tex_lod[2][LOD_MAX+2]; - int tex_entry[2]; - int detail_max[2], detail_bias[2], detail_scale[2]; - - uint32_t draw_offset, aux_offset; - - int tformat[2]; - - int clipLeft, clipRight, clipLowY, clipHighY; - - int sign; - - uint32_t front_offset; - - uint32_t swapbufferCMD; - - uint32_t stipple; -} voodoo_params_t; - -typedef struct texture_t -{ - uint32_t base; - uint32_t tLOD; - volatile int refcount, refcount_r[2]; - int is16; - uint32_t palette_checksum; - uint32_t addr_start[4], addr_end[4]; - uint32_t *data; -} texture_t; - -typedef struct vert_t -{ - float sVx, sVy; - float sRed, sGreen, sBlue, sAlpha; - float sVz, sWb; - float sW0, sS0, sT0; - float sW1, sS1, sT1; -} vert_t; - -typedef struct voodoo_t -{ - mem_mapping_t mapping; - - int pci_enable; - - uint8_t dac_data[8]; - int dac_reg, dac_reg_ff; - uint8_t dac_readdata; - uint16_t dac_pll_regs[16]; - - float pixel_clock; - uint64_t line_time; - - voodoo_params_t params; - - uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4; - uint32_t fbiInit5, fbiInit6, fbiInit7; /*Voodoo 2*/ - - uint32_t initEnable; - - uint32_t lfbMode; - - uint32_t memBaseAddr; - - int_float fvertexAx, fvertexAy, fvertexBx, fvertexBy, fvertexCx, fvertexCy; - - uint32_t front_offset, back_offset; - - uint32_t fb_read_offset, fb_write_offset; - - int row_width; - int block_width; - - uint8_t *fb_mem, *tex_mem[2]; - uint16_t *tex_mem_w[2]; - - int rgb_sel; - - uint32_t trexInit1[2]; - - uint32_t tmuConfig; - - int swap_count; - - int disp_buffer, draw_buffer; - pc_timer_t timer; - - int line; - svga_t *svga; - - uint32_t backPorch; - uint32_t videoDimensions; - uint32_t hSync, vSync; - - int h_total, v_total, v_disp; - int h_disp; - int v_retrace; - - struct - { - uint32_t y[4], i[4], q[4]; - } nccTable[2][2]; - - rgba_u palette[2][256]; - - rgba_u ncc_lookup[2][2][256]; - int ncc_dirty[2]; - - thread_t *fifo_thread; - thread_t *render_thread[2]; - event_t *wake_fifo_thread; - event_t *wake_main_thread; - event_t *fifo_not_full_event; - event_t *render_not_full_event[2]; - event_t *wake_render_thread[2]; - - int voodoo_busy; - int render_voodoo_busy[2]; - - int render_threads; - int odd_even_mask; - - int pixel_count[2], texel_count[2], tri_count, frame_count; - int pixel_count_old[2], texel_count_old[2]; - int wr_count, rd_count, tex_count; - - int retrace_count; - int swap_interval; - uint32_t swap_offset; - int swap_pending; - - int bilinear_enabled; - - int fb_size; - uint32_t fb_mask; - - int texture_size; - uint32_t texture_mask; - - int dual_tmus; - int type; - - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; - volatile int cmd_read, cmd_written, cmd_written_fifo; - - voodoo_params_t params_buffer[PARAM_SIZE]; - volatile int params_read_idx[2], params_write_idx; - - uint32_t cmdfifo_base, cmdfifo_end; - int cmdfifo_rp; - volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; - uint32_t cmdfifo_amin, cmdfifo_amax; - - uint32_t sSetupMode; - vert_t verts[4]; - int vertex_num; - int num_verticies; - - int flush; - - int scrfilter; - int scrfilterEnabled; - int scrfilterThreshold; - int scrfilterThresholdOld; - - uint32_t last_write_addr; - - uint32_t fbiPixelsIn; - uint32_t fbiChromaFail; - uint32_t fbiZFuncFail; - uint32_t fbiAFuncFail; - uint32_t fbiPixelsOut; - - uint32_t bltSrcBaseAddr; - uint32_t bltDstBaseAddr; - int bltSrcXYStride, bltDstXYStride; - uint32_t bltSrcChromaRange, bltDstChromaRange; - int bltSrcChromaMinR, bltSrcChromaMinG, bltSrcChromaMinB; - int bltSrcChromaMaxR, bltSrcChromaMaxG, bltSrcChromaMaxB; - int bltDstChromaMinR, bltDstChromaMinG, bltDstChromaMinB; - int bltDstChromaMaxR, bltDstChromaMaxG, bltDstChromaMaxB; - - int bltClipRight, bltClipLeft; - int bltClipHighY, bltClipLowY; - - int bltSrcX, bltSrcY; - int bltDstX, bltDstY; - int bltSizeX, bltSizeY; - int bltRop[4]; - uint16_t bltColorFg, bltColorBg; - - uint32_t bltCommand; - - struct - { - int dst_x, dst_y; - int cur_x; - int size_x, size_y; - int x_dir, y_dir; - int dst_stride; - } blt; - - rgb_t clutData[33]; - int clutData_dirty; - rgb_t clutData256[256]; - uint32_t video_16to32[0x10000]; - - uint8_t dirty_line[1024]; - int dirty_line_low, dirty_line_high; - - int fb_write_buffer, fb_draw_buffer; - int buffer_cutoff; - - int read_time, write_time, burst_time; - - pc_timer_t wake_timer; - - uint8_t thefilter[256][256]; // pixel filter, feeding from one or two - uint8_t thefilterg[256][256]; // for green - uint8_t thefilterb[256][256]; // for blue - - /* the voodoo adds purple lines for some reason */ - uint16_t purpleline[256][3]; - - texture_t texture_cache[2][TEX_CACHE_MAX]; - uint8_t texture_present[2][4096]; - int texture_last_removed; - - uint32_t palette_checksum[2]; - int palette_dirty[2]; - - uint64_t time; - int render_time[2]; - - int use_recompiler; - void *codegen_data; - - struct voodoo_set_t *set; -} voodoo_t; - -typedef struct voodoo_set_t -{ - voodoo_t *voodoos[2]; - - mem_mapping_t snoop_mapping; - - int nr_cards; -} voodoo_set_t; - -static inline void wait_for_render_thread_idle(voodoo_t *voodoo); - -enum -{ - SST_status = 0x000, - SST_intrCtrl = 0x004, - - SST_vertexAx = 0x008, - SST_vertexAy = 0x00c, - SST_vertexBx = 0x010, - SST_vertexBy = 0x014, - SST_vertexCx = 0x018, - SST_vertexCy = 0x01c, - - SST_startR = 0x0020, - SST_startG = 0x0024, - SST_startB = 0x0028, - SST_startZ = 0x002c, - SST_startA = 0x0030, - SST_startS = 0x0034, - SST_startT = 0x0038, - SST_startW = 0x003c, - - SST_dRdX = 0x0040, - SST_dGdX = 0x0044, - SST_dBdX = 0x0048, - SST_dZdX = 0x004c, - SST_dAdX = 0x0050, - SST_dSdX = 0x0054, - SST_dTdX = 0x0058, - SST_dWdX = 0x005c, - - SST_dRdY = 0x0060, - SST_dGdY = 0x0064, - SST_dBdY = 0x0068, - SST_dZdY = 0x006c, - SST_dAdY = 0x0070, - SST_dSdY = 0x0074, - SST_dTdY = 0x0078, - SST_dWdY = 0x007c, - - SST_triangleCMD = 0x0080, - - SST_fvertexAx = 0x088, - SST_fvertexAy = 0x08c, - SST_fvertexBx = 0x090, - SST_fvertexBy = 0x094, - SST_fvertexCx = 0x098, - SST_fvertexCy = 0x09c, - - SST_fstartR = 0x00a0, - SST_fstartG = 0x00a4, - SST_fstartB = 0x00a8, - SST_fstartZ = 0x00ac, - SST_fstartA = 0x00b0, - SST_fstartS = 0x00b4, - SST_fstartT = 0x00b8, - SST_fstartW = 0x00bc, - - SST_fdRdX = 0x00c0, - SST_fdGdX = 0x00c4, - SST_fdBdX = 0x00c8, - SST_fdZdX = 0x00cc, - SST_fdAdX = 0x00d0, - SST_fdSdX = 0x00d4, - SST_fdTdX = 0x00d8, - SST_fdWdX = 0x00dc, - - SST_fdRdY = 0x00e0, - SST_fdGdY = 0x00e4, - SST_fdBdY = 0x00e8, - SST_fdZdY = 0x00ec, - SST_fdAdY = 0x00f0, - SST_fdSdY = 0x00f4, - SST_fdTdY = 0x00f8, - SST_fdWdY = 0x00fc, - - SST_ftriangleCMD = 0x0100, - - SST_fbzColorPath = 0x104, - SST_fogMode = 0x108, - - SST_alphaMode = 0x10c, - SST_fbzMode = 0x110, - SST_lfbMode = 0x114, - - SST_clipLeftRight = 0x118, - SST_clipLowYHighY = 0x11c, - - SST_nopCMD = 0x120, - SST_fastfillCMD = 0x124, - SST_swapbufferCMD = 0x128, - - SST_fogColor = 0x12c, - SST_zaColor = 0x130, - SST_chromaKey = 0x134, - - SST_userIntrCMD = 0x13c, - SST_stipple = 0x140, - SST_color0 = 0x144, - SST_color1 = 0x148, - - SST_fbiPixelsIn = 0x14c, - SST_fbiChromaFail = 0x150, - SST_fbiZFuncFail = 0x154, - SST_fbiAFuncFail = 0x158, - SST_fbiPixelsOut = 0x15c, - - SST_fogTable00 = 0x160, - SST_fogTable01 = 0x164, - SST_fogTable02 = 0x168, - SST_fogTable03 = 0x16c, - SST_fogTable04 = 0x170, - SST_fogTable05 = 0x174, - SST_fogTable06 = 0x178, - SST_fogTable07 = 0x17c, - SST_fogTable08 = 0x180, - SST_fogTable09 = 0x184, - SST_fogTable0a = 0x188, - SST_fogTable0b = 0x18c, - SST_fogTable0c = 0x190, - SST_fogTable0d = 0x194, - SST_fogTable0e = 0x198, - SST_fogTable0f = 0x19c, - SST_fogTable10 = 0x1a0, - SST_fogTable11 = 0x1a4, - SST_fogTable12 = 0x1a8, - SST_fogTable13 = 0x1ac, - SST_fogTable14 = 0x1b0, - SST_fogTable15 = 0x1b4, - SST_fogTable16 = 0x1b8, - SST_fogTable17 = 0x1bc, - SST_fogTable18 = 0x1c0, - SST_fogTable19 = 0x1c4, - SST_fogTable1a = 0x1c8, - SST_fogTable1b = 0x1cc, - SST_fogTable1c = 0x1d0, - SST_fogTable1d = 0x1d4, - SST_fogTable1e = 0x1d8, - SST_fogTable1f = 0x1dc, - - SST_cmdFifoBaseAddr = 0x1e0, - SST_cmdFifoBump = 0x1e4, - SST_cmdFifoRdPtr = 0x1e8, - SST_cmdFifoAMin = 0x1ec, - SST_cmdFifoAMax = 0x1f0, - SST_cmdFifoDepth = 0x1f4, - SST_cmdFifoHoles = 0x1f8, - - SST_fbiInit4 = 0x200, - SST_vRetrace = 0x204, - SST_backPorch = 0x208, - SST_videoDimensions = 0x20c, - SST_fbiInit0 = 0x210, - SST_fbiInit1 = 0x214, - SST_fbiInit2 = 0x218, - SST_fbiInit3 = 0x21c, - SST_hSync = 0x220, - SST_vSync = 0x224, - SST_clutData = 0x228, - SST_dacData = 0x22c, - - SST_scrFilter = 0x230, - - SST_hvRetrace = 0x240, - SST_fbiInit5 = 0x244, - SST_fbiInit6 = 0x248, - SST_fbiInit7 = 0x24c, - - SST_sSetupMode = 0x260, - SST_sVx = 0x264, - SST_sVy = 0x268, - SST_sARGB = 0x26c, - SST_sRed = 0x270, - SST_sGreen = 0x274, - SST_sBlue = 0x278, - SST_sAlpha = 0x27c, - SST_sVz = 0x280, - SST_sWb = 0x284, - SST_sW0 = 0x288, - SST_sS0 = 0x28c, - SST_sT0 = 0x290, - SST_sW1 = 0x294, - SST_sS1 = 0x298, - SST_sT1 = 0x29c, - - SST_sDrawTriCMD = 0x2a0, - SST_sBeginTriCMD = 0x2a4, - - SST_bltSrcBaseAddr = 0x2c0, - SST_bltDstBaseAddr = 0x2c4, - SST_bltXYStrides = 0x2c8, - SST_bltSrcChromaRange = 0x2cc, - SST_bltDstChromaRange = 0x2d0, - SST_bltClipX = 0x2d4, - SST_bltClipY = 0x2d8, - - SST_bltSrcXY = 0x2e0, - SST_bltDstXY = 0x2e4, - SST_bltSize = 0x2e8, - SST_bltRop = 0x2ec, - SST_bltColor = 0x2f0, - - SST_bltCommand = 0x2f8, - SST_bltData = 0x2fc, - - SST_textureMode = 0x300, - SST_tLOD = 0x304, - SST_tDetail = 0x308, - SST_texBaseAddr = 0x30c, - SST_texBaseAddr1 = 0x310, - SST_texBaseAddr2 = 0x314, - SST_texBaseAddr38 = 0x318, - - SST_trexInit1 = 0x320, - - SST_nccTable0_Y0 = 0x324, - SST_nccTable0_Y1 = 0x328, - SST_nccTable0_Y2 = 0x32c, - SST_nccTable0_Y3 = 0x330, - SST_nccTable0_I0 = 0x334, - SST_nccTable0_I1 = 0x338, - SST_nccTable0_I2 = 0x33c, - SST_nccTable0_I3 = 0x340, - SST_nccTable0_Q0 = 0x344, - SST_nccTable0_Q1 = 0x348, - SST_nccTable0_Q2 = 0x34c, - SST_nccTable0_Q3 = 0x350, - - SST_nccTable1_Y0 = 0x354, - SST_nccTable1_Y1 = 0x358, - SST_nccTable1_Y2 = 0x35c, - SST_nccTable1_Y3 = 0x360, - SST_nccTable1_I0 = 0x364, - SST_nccTable1_I1 = 0x368, - SST_nccTable1_I2 = 0x36c, - SST_nccTable1_I3 = 0x370, - SST_nccTable1_Q0 = 0x374, - SST_nccTable1_Q1 = 0x378, - SST_nccTable1_Q2 = 0x37c, - SST_nccTable1_Q3 = 0x380, - - SST_remap_status = 0x000 | 0x400, - - SST_remap_vertexAx = 0x008 | 0x400, - SST_remap_vertexAy = 0x00c | 0x400, - SST_remap_vertexBx = 0x010 | 0x400, - SST_remap_vertexBy = 0x014 | 0x400, - SST_remap_vertexCx = 0x018 | 0x400, - SST_remap_vertexCy = 0x01c | 0x400, - - SST_remap_startR = 0x0020 | 0x400, - SST_remap_startG = 0x002c | 0x400, - SST_remap_startB = 0x0038 | 0x400, - SST_remap_startZ = 0x0044 | 0x400, - SST_remap_startA = 0x0050 | 0x400, - SST_remap_startS = 0x005c | 0x400, - SST_remap_startT = 0x0068 | 0x400, - SST_remap_startW = 0x0074 | 0x400, - - SST_remap_dRdX = 0x0024 | 0x400, - SST_remap_dGdX = 0x0030 | 0x400, - SST_remap_dBdX = 0x003c | 0x400, - SST_remap_dZdX = 0x0048 | 0x400, - SST_remap_dAdX = 0x0054 | 0x400, - SST_remap_dSdX = 0x0060 | 0x400, - SST_remap_dTdX = 0x006c | 0x400, - SST_remap_dWdX = 0x0078 | 0x400, - - SST_remap_dRdY = 0x0028 | 0x400, - SST_remap_dGdY = 0x0034 | 0x400, - SST_remap_dBdY = 0x0040 | 0x400, - SST_remap_dZdY = 0x004c | 0x400, - SST_remap_dAdY = 0x0058 | 0x400, - SST_remap_dSdY = 0x0064 | 0x400, - SST_remap_dTdY = 0x0070 | 0x400, - SST_remap_dWdY = 0x007c | 0x400, - - SST_remap_triangleCMD = 0x0080 | 0x400, - - SST_remap_fvertexAx = 0x088 | 0x400, - SST_remap_fvertexAy = 0x08c | 0x400, - SST_remap_fvertexBx = 0x090 | 0x400, - SST_remap_fvertexBy = 0x094 | 0x400, - SST_remap_fvertexCx = 0x098 | 0x400, - SST_remap_fvertexCy = 0x09c | 0x400, - - SST_remap_fstartR = 0x00a0 | 0x400, - SST_remap_fstartG = 0x00ac | 0x400, - SST_remap_fstartB = 0x00b8 | 0x400, - SST_remap_fstartZ = 0x00c4 | 0x400, - SST_remap_fstartA = 0x00d0 | 0x400, - SST_remap_fstartS = 0x00dc | 0x400, - SST_remap_fstartT = 0x00e8 | 0x400, - SST_remap_fstartW = 0x00f4 | 0x400, - - SST_remap_fdRdX = 0x00a4 | 0x400, - SST_remap_fdGdX = 0x00b0 | 0x400, - SST_remap_fdBdX = 0x00bc | 0x400, - SST_remap_fdZdX = 0x00c8 | 0x400, - SST_remap_fdAdX = 0x00d4 | 0x400, - SST_remap_fdSdX = 0x00e0 | 0x400, - SST_remap_fdTdX = 0x00ec | 0x400, - SST_remap_fdWdX = 0x00f8 | 0x400, - - SST_remap_fdRdY = 0x00a8 | 0x400, - SST_remap_fdGdY = 0x00b4 | 0x400, - SST_remap_fdBdY = 0x00c0 | 0x400, - SST_remap_fdZdY = 0x00cc | 0x400, - SST_remap_fdAdY = 0x00d8 | 0x400, - SST_remap_fdSdY = 0x00e4 | 0x400, - SST_remap_fdTdY = 0x00f0 | 0x400, - SST_remap_fdWdY = 0x00fc | 0x400, -}; - -enum -{ - LFB_WRITE_FRONT = 0x0000, - LFB_WRITE_BACK = 0x0010, - LFB_WRITE_MASK = 0x0030 -}; - -enum -{ - LFB_READ_FRONT = 0x0000, - LFB_READ_BACK = 0x0040, - LFB_READ_AUX = 0x0080, - LFB_READ_MASK = 0x00c0 -}; - -enum -{ - LFB_FORMAT_RGB565 = 0, - LFB_FORMAT_RGB555 = 1, - LFB_FORMAT_ARGB1555 = 2, - LFB_FORMAT_ARGB8888 = 5, - LFB_FORMAT_DEPTH = 15, - LFB_FORMAT_MASK = 15 -}; - -enum -{ - LFB_WRITE_COLOUR = 1, - LFB_WRITE_DEPTH = 2 -}; - -enum -{ - FBZ_CHROMAKEY = (1 << 1), - FBZ_W_BUFFER = (1 << 3), - FBZ_DEPTH_ENABLE = (1 << 4), - - FBZ_DITHER = (1 << 8), - FBZ_RGB_WMASK = (1 << 9), - FBZ_DEPTH_WMASK = (1 << 10), - FBZ_DITHER_2x2 = (1 << 11), - - FBZ_DRAW_FRONT = 0x0000, - FBZ_DRAW_BACK = 0x4000, - FBZ_DRAW_MASK = 0xc000, - - FBZ_DEPTH_BIAS = (1 << 16), - - FBZ_DEPTH_SOURCE = (1 << 20), - - FBZ_PARAM_ADJUST = (1 << 26) -}; - -enum -{ - TEX_RGB332 = 0x0, - TEX_Y4I2Q2 = 0x1, - TEX_A8 = 0x2, - TEX_I8 = 0x3, - TEX_AI8 = 0x4, - TEX_PAL8 = 0x5, - TEX_APAL8 = 0x6, - TEX_ARGB8332 = 0x8, - TEX_A8Y4I2Q2 = 0x9, - TEX_R5G6B5 = 0xa, - TEX_ARGB1555 = 0xb, - TEX_ARGB4444 = 0xc, - TEX_A8I8 = 0xd, - TEX_APAL88 = 0xe -}; - -enum -{ - TEXTUREMODE_NCC_SEL = (1 << 5), - TEXTUREMODE_TCLAMPS = (1 << 6), - TEXTUREMODE_TCLAMPT = (1 << 7), - TEXTUREMODE_TRILINEAR = (1 << 30) -}; - -enum -{ - FBIINIT0_VGA_PASS = 1, - FBIINIT0_GRAPHICS_RESET = (1 << 1) -}; - -enum -{ - FBIINIT1_MULTI_SST = (1 << 2), /*Voodoo Graphics only*/ - FBIINIT1_VIDEO_RESET = (1 << 8), - FBIINIT1_SLI_ENABLE = (1 << 23) -}; - -enum -{ - FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9) -}; - -enum -{ - FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9), - FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9), - FBIINIT2_SWAP_ALGORITHM_PCI_FIFO_STALL = (2 << 9), - FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9) -}; - -enum -{ - FBIINIT3_REMAP = 1 -}; - -enum -{ - FBIINIT5_MULTI_CVG = (1 << 14) -}; - -enum -{ - FBIINIT7_CMDFIFO_ENABLE = (1 << 8) -}; - -enum -{ - CC_LOCALSELECT_ITER_RGB = 0, - CC_LOCALSELECT_TEX = 1, - CC_LOCALSELECT_COLOR1 = 2, - CC_LOCALSELECT_LFB = 3 -}; - -enum -{ - CCA_LOCALSELECT_ITER_A = 0, - CCA_LOCALSELECT_COLOR0 = 1, - CCA_LOCALSELECT_ITER_Z = 2 -}; - -enum -{ - C_SEL_ITER_RGB = 0, - C_SEL_TEX = 1, - C_SEL_COLOR1 = 2, - C_SEL_LFB = 3 -}; - -enum -{ - A_SEL_ITER_A = 0, - A_SEL_TEX = 1, - A_SEL_COLOR1 = 2, - A_SEL_LFB = 3 -}; - -enum -{ - CC_MSELECT_ZERO = 0, - CC_MSELECT_CLOCAL = 1, - CC_MSELECT_AOTHER = 2, - CC_MSELECT_ALOCAL = 3, - CC_MSELECT_TEX = 4, - CC_MSELECT_TEXRGB = 5 -}; - -enum -{ - CCA_MSELECT_ZERO = 0, - CCA_MSELECT_ALOCAL = 1, - CCA_MSELECT_AOTHER = 2, - CCA_MSELECT_ALOCAL2 = 3, - CCA_MSELECT_TEX = 4 -}; - -enum -{ - TC_MSELECT_ZERO = 0, - TC_MSELECT_CLOCAL = 1, - TC_MSELECT_AOTHER = 2, - TC_MSELECT_ALOCAL = 3, - TC_MSELECT_DETAIL = 4, - TC_MSELECT_LOD_FRAC = 5 -}; - -enum -{ - TCA_MSELECT_ZERO = 0, - TCA_MSELECT_CLOCAL = 1, - TCA_MSELECT_AOTHER = 2, - TCA_MSELECT_ALOCAL = 3, - TCA_MSELECT_DETAIL = 4, - TCA_MSELECT_LOD_FRAC = 5 -}; - -enum -{ - CC_ADD_CLOCAL = 1, - CC_ADD_ALOCAL = 2 -}; - -enum -{ - CCA_ADD_CLOCAL = 1, - CCA_ADD_ALOCAL = 2 -}; - -enum -{ - AFUNC_AZERO = 0x0, - AFUNC_ASRC_ALPHA = 0x1, - AFUNC_A_COLOR = 0x2, - AFUNC_ADST_ALPHA = 0x3, - AFUNC_AONE = 0x4, - AFUNC_AOMSRC_ALPHA = 0x5, - AFUNC_AOM_COLOR = 0x6, - AFUNC_AOMDST_ALPHA = 0x7, - AFUNC_ASATURATE = 0xf -}; - -enum -{ - AFUNC_ACOLORBEFOREFOG = 0xf -}; - -enum -{ - AFUNC_NEVER = 0, - AFUNC_LESSTHAN = 1, - AFUNC_EQUAL = 2, - AFUNC_LESSTHANEQUAL = 3, - AFUNC_GREATERTHAN = 4, - AFUNC_NOTEQUAL = 5, - AFUNC_GREATERTHANEQUAL = 6, - AFUNC_ALWAYS = 7 -}; - -enum -{ - DEPTHOP_NEVER = 0, - DEPTHOP_LESSTHAN = 1, - DEPTHOP_EQUAL = 2, - DEPTHOP_LESSTHANEQUAL = 3, - DEPTHOP_GREATERTHAN = 4, - DEPTHOP_NOTEQUAL = 5, - DEPTHOP_GREATERTHANEQUAL = 6, - DEPTHOP_ALWAYS = 7 -}; - -enum -{ - FOG_ENABLE = 0x01, - FOG_ADD = 0x02, - FOG_MULT = 0x04, - FOG_ALPHA = 0x08, - FOG_Z = 0x10, - FOG_W = 0x18, - FOG_CONSTANT = 0x20 -}; - -enum -{ - LOD_ODD = (1 << 18), - LOD_SPLIT = (1 << 19), - LOD_S_IS_WIDER = (1 << 20), - LOD_TMULTIBASEADDR = (1 << 24), - LOD_TMIRROR_S = (1 << 28), - LOD_TMIRROR_T = (1 << 29) -}; -enum -{ - CMD_INVALID = 0, - CMD_DRAWTRIANGLE, - CMD_FASTFILL, - CMD_SWAPBUF -}; - -enum -{ - FBZCP_TEXTURE_ENABLED = (1 << 27) -}; - -enum -{ - BLTCMD_SRC_TILED = (1 << 14), - BLTCMD_DST_TILED = (1 << 15) -}; - -enum -{ - INITENABLE_SLI_MASTER_SLAVE = (1 << 11) -}; - -#define TEXTUREMODE_MASK 0x3ffff000 -#define TEXTUREMODE_PASSTHROUGH 0 - -#define TEXTUREMODE_LOCAL_MASK 0x00643000 -#define TEXTUREMODE_LOCAL 0x00241000 - -static void voodoo_threshold_check(voodoo_t *voodoo); - -static void voodoo_update_ncc(voodoo_t *voodoo, int tmu) -{ - int tbl; - - for (tbl = 0; tbl < 2; tbl++) - { - int col; - - for (col = 0; col < 256; col++) - { - int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; - int i_r, i_g, i_b; - int q_r, q_g, q_b; - - y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; - - i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; - if (i_r & 0x100) - i_r |= 0xfffffe00; - i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; - if (i_g & 0x100) - i_g |= 0xfffffe00; - i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; - if (i_b & 0x100) - i_b |= 0xfffffe00; - - q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; - if (q_r & 0x100) - q_r |= 0xfffffe00; - q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; - if (q_g & 0x100) - q_g |= 0xfffffe00; - q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; - if (q_b & 0x100) - q_b |= 0xfffffe00; - - voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); - voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); - voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); - voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; - } - } -} - -#define SLI_ENABLED (voodoo->fbiInit1 & FBIINIT1_SLI_ENABLE) -#define TRIPLE_BUFFER ((voodoo->fbiInit2 & 0x10) || (voodoo->fbiInit5 & 0x600) == 0x400) -static void voodoo_recalc(voodoo_t *voodoo) +void voodoo_recalc(voodoo_t *voodoo) { uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; - + voodoo->params.front_offset = voodoo->disp_buffer*buffer_offset; voodoo->back_offset = voodoo->draw_buffer*buffer_offset; @@ -1124,7 +75,7 @@ static void voodoo_recalc(voodoo_t *voodoo) default: fatal("voodoo_recalc : unknown lfb source\n"); } - + switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) { case FBZ_DRAW_FRONT: @@ -1139,7 +90,7 @@ static void voodoo_recalc(voodoo_t *voodoo) default: fatal("voodoo_recalc : unknown draw buffer\n"); } - + voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; if (voodoo->fbiInit6 & (1 << 30)) voodoo->block_width += 1; @@ -1151,4769 +102,6 @@ static void voodoo_recalc(voodoo_t *voodoo) pclog(" fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ } -static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) -{ - int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; - int width = 256, height = 256; - int shift = 8; - int lod; - uint32_t base = voodoo->params.texBaseAddr[tmu]; - uint32_t offset = 0; - int tex_lod = 0; - - if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) - height >>= aspect; - else - { - width >>= aspect; - shift -= aspect; - } - - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD)) - { - width >>= 1; - height >>= 1; - shift--; - tex_lod++; - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - base = voodoo->params.texBaseAddr1[tmu]; - } - - for (lod = 0; lod <= LOD_MAX+1; lod++) - { - if (!width) - width = 1; - if (!height) - height = 1; - if (shift < 0) - shift = 0; - voodoo->params.tex_base[tmu][lod] = base + offset; - if (voodoo->params.tformat[tmu] & 8) - voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2); - else - voodoo->params.tex_end[tmu][lod] = base + offset + (width * height); - voodoo->params.tex_w_mask[tmu][lod] = width - 1; - voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1); - voodoo->params.tex_h_mask[tmu][lod] = height - 1; - voodoo->params.tex_shift[tmu][lod] = shift; - voodoo->params.tex_lod[tmu][lod] = tex_lod; - - if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) - { - if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) - { - if (voodoo->params.tformat[tmu] & 8) - offset += width * height * 2; - else - offset += width * height; - - if (voodoo->params.tLOD[tmu] & LOD_SPLIT) - { - width >>= 2; - height >>= 2; - shift -= 2; - tex_lod += 2; - } - else - { - width >>= 1; - height >>= 1; - shift--; - tex_lod++; - } - - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - { - switch (tex_lod) - { - case 0: - base = voodoo->params.texBaseAddr[tmu]; - break; - case 1: - base = voodoo->params.texBaseAddr1[tmu]; - break; - case 2: - base = voodoo->params.texBaseAddr2[tmu]; - break; - default: - base = voodoo->params.texBaseAddr38[tmu]; - break; - } - } - } - } - } - - voodoo->params.tex_width[tmu] = width; -} - -#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) - -static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) -{ - int c, d; - int lod; - int lod_min, lod_max; - uint32_t addr = 0, addr_end; - uint32_t palette_checksum; - - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; - - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - { - if (voodoo->palette_dirty[tmu]) - { - palette_checksum = 0; - - for (c = 0; c < 256; c++) - palette_checksum ^= voodoo->palette[tmu][c].u; - - voodoo->palette_checksum[tmu] = palette_checksum; - voodoo->palette_dirty[tmu] = 0; - } - else - palette_checksum = voodoo->palette_checksum[tmu]; - } - else - palette_checksum = 0; - - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - addr = params->texBaseAddr1[tmu]; - else - addr = params->texBaseAddr[tmu]; - - /*Try to find texture in cache*/ - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->texture_cache[tmu][c].base == addr && - voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && - voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) - { - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; - return; - } - } - - /*Texture not found, search for unused texture*/ - do - { - for (c = 0; c < TEX_CACHE_MAX; c++) - { - voodoo->texture_last_removed++; - voodoo->texture_last_removed &= (TEX_CACHE_MAX-1); - if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && - (voodoo->render_threads == 1 || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) - break; - } - if (c == TEX_CACHE_MAX) - wait_for_render_thread_idle(voodoo); - } while (c == TEX_CACHE_MAX); - if (c == TEX_CACHE_MAX) - fatal("Texture cache full!\n"); - - c = voodoo->texture_last_removed; - - - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; - else - voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; - voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; - - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; -// pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); - lod_min = MIN(lod_min, 8); - lod_max = MIN(lod_max, 8); - for (lod = lod_min; lod <= lod_max; lod++) - { - uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; - uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; - int x, y; - int shift = 8 - params->tex_lod[tmu][lod]; - rgba_u *pal; - - //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: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_Y4I2Q2: - pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_A8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(dat, dat, dat, dat); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(dat, dat, dat, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_AI8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_PAL8: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_APAL8: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3); - int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2); - int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); - int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); - - base[x] = makergba(r, g, b, a); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_ARGB8332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_A8Y4I2Q2: - pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_R5G6B5: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_ARGB1555: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_ARGB4444: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_A8I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_APAL88: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - default: - fatal("Unknown texture format %i\n", params->tformat[tmu]); - } - } - - voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; - - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; - else - voodoo->texture_cache[tmu][c].palette_checksum = 0; - - if (lod_min == 0) - { - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; - voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; - } - else - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; - - if (lod_min <= 1 && lod_max >= 1) - { - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; - voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; - } - else - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; - - if (lod_min <= 2 && lod_max >= 2) - { - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; - voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; - } - else - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; - - if (lod_max >= 3) - { - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; - voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; - } - else - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; - - - for (d = 0; d < 4; d++) - { - addr = voodoo->texture_cache[tmu][c].addr_start[d]; - addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - - if (addr_end != 0) - { - for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; -} - -static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) -{ - int wait_for_idle = 0; - int c; - - memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); -// 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 d; - - for (d = 0; d < 4; d++) - { - int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; - int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - - if (addr_end != 0) - { - int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; - int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; - - if (addr_end_masked < addr_start_masked) - addr_end_masked = voodoo->texture_mask+1; - if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) - { -// 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])) - wait_for_idle = 1; - - voodoo->texture_cache[tmu][c].base = -1; - } - else - { - for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - } - } - } - if (wait_for_idle) - wait_for_render_thread_idle(voodoo); -} - -typedef struct voodoo_state_t -{ - int xstart, xend, xdir; - uint32_t base_r, base_g, base_b, base_a, base_z; - struct - { - int64_t base_s, base_t, base_w; - int lod; - } tmu[2]; - int64_t base_w; - int lod; - int lod_min[2], lod_max[2]; - int dx1, dx2; - int y, yend, ydir; - int32_t dxAB, dxAC, dxBC; - int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; - int tex_s, tex_t; - int clamp_s[2], clamp_t[2]; - - int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; - - uint32_t *tex[2][LOD_MAX+1]; - int tformat; - - int *tex_w_mask[2]; - int *tex_h_mask[2]; - int *tex_shift[2]; - int *tex_lod[2]; - - uint16_t *fb_mem, *aux_mem; - - int32_t ib, ig, ir, ia; - int32_t z; - - int32_t new_depth; - - int64_t tmu0_s, tmu0_t; - int64_t tmu0_w; - int64_t tmu1_s, tmu1_t; - int64_t tmu1_w; - int64_t w; - - int pixel_count, texel_count; - int x, x2; - - uint32_t w_depth; - - float log_temp; - uint32_t ebp_store; - uint32_t texBaseAddr; - - int lod_frac[2]; -} voodoo_state_t; - -static int voodoo_output = 0; - -static uint8_t logtable[256] = -{ - 0x00,0x01,0x02,0x04,0x05,0x07,0x08,0x09,0x0b,0x0c,0x0e,0x0f,0x10,0x12,0x13,0x15, - 0x16,0x17,0x19,0x1a,0x1b,0x1d,0x1e,0x1f,0x21,0x22,0x23,0x25,0x26,0x27,0x28,0x2a, - 0x2b,0x2c,0x2e,0x2f,0x30,0x31,0x33,0x34,0x35,0x36,0x38,0x39,0x3a,0x3b,0x3d,0x3e, - 0x3f,0x40,0x41,0x43,0x44,0x45,0x46,0x47,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x50,0x51, - 0x52,0x53,0x54,0x55,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x60,0x61,0x62,0x63, - 0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x83,0x84,0x85, - 0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94, - 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa2,0xa3, - 0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xad,0xae,0xaf,0xb0,0xb1,0xb2, - 0xb3,0xb4,0xb5,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbc,0xbd,0xbe,0xbf,0xc0, - 0xc1,0xc2,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xcd, - 0xce,0xcf,0xd0,0xd1,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd6,0xd7,0xd8,0xd9,0xda,0xda, - 0xdb,0xdc,0xdd,0xde,0xde,0xdf,0xe0,0xe1,0xe1,0xe2,0xe3,0xe4,0xe5,0xe5,0xe6,0xe7, - 0xe8,0xe8,0xe9,0xea,0xeb,0xeb,0xec,0xed,0xee,0xef,0xef,0xf0,0xf1,0xf2,0xf2,0xf3, - 0xf4,0xf5,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff -}; - -static inline int fastlog(uint64_t val) -{ - uint64_t oldval = val; - int exp = 63; - int frac; - - if (!val || val & (1ULL << 63)) - return 0x80000000; - - if (!(val & 0xffffffff00000000)) - { - exp -= 32; - val <<= 32; - } - if (!(val & 0xffff000000000000)) - { - exp -= 16; - val <<= 16; - } - if (!(val & 0xff00000000000000)) - { - exp -= 8; - val <<= 8; - } - if (!(val & 0xf000000000000000)) - { - exp -= 4; - val <<= 4; - } - if (!(val & 0xc000000000000000)) - { - exp -= 2; - val <<= 2; - } - if (!(val & 0x8000000000000000)) - { - exp -= 1; - val <<= 1; - } - - if (exp >= 8) - frac = (oldval >> (exp - 8)) & 0xff; - else - frac = (oldval << (8 - exp)) & 0xff; - - return (exp << 8) | logtable[frac]; -} - -static inline int voodoo_fls(uint16_t val) -{ - int num = 0; - -//pclog("fls(%04x) = ", val); - if (!(val & 0xff00)) - { - num += 8; - val <<= 8; - } - if (!(val & 0xf000)) - { - num += 4; - val <<= 4; - } - if (!(val & 0xc000)) - { - num += 2; - val <<= 2; - } - if (!(val & 0x8000)) - { - num += 1; - val <<= 1; - } -//pclog("%i %04x\n", num, val); - return num; -} - -typedef struct voodoo_texture_state_t -{ - int s, t; - int w_mask, h_mask; - int tex_shift; -} voodoo_texture_state_t; - -static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) -{ - uint32_t dat; - - if (texture_state->s & ~texture_state->w_mask) - { - if (state->clamp_s[tmu]) - { - if (texture_state->s < 0) - texture_state->s = 0; - if (texture_state->s > texture_state->w_mask) - texture_state->s = texture_state->w_mask; - } - else - texture_state->s &= texture_state->w_mask; - } - if (texture_state->t & ~texture_state->h_mask) - { - if (state->clamp_t[tmu]) - { - if (texture_state->t < 0) - texture_state->t = 0; - if (texture_state->t > texture_state->h_mask) - texture_state->t = texture_state->h_mask; - } - else - texture_state->t &= texture_state->h_mask; - } - - dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; - - state->tex_b[tmu] = dat & 0xff; - state->tex_g[tmu] = (dat >> 8) & 0xff; - state->tex_r[tmu] = (dat >> 16) & 0xff; - state->tex_a[tmu] = (dat >> 24) & 0xff; -} - -#define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) -#define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) - -static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) -{ - rgba_u dat[4]; - - if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) - { - int c; - for (c = 0; c < 4; c++) - { - int _s = s + (c & 1); - int _t = t + ((c & 2) >> 1); - - if (_s & ~texture_state->w_mask) - { - if (state->clamp_s[tmu]) - { - if (_s < 0) - _s = 0; - if (_s > texture_state->w_mask) - _s = texture_state->w_mask; - } - else - _s &= texture_state->w_mask; - } - if (_t & ~texture_state->h_mask) - { - if (state->clamp_t[tmu]) - { - if (_t < 0) - _t = 0; - if (_t > texture_state->h_mask) - _t = texture_state->h_mask; - } - else - _t &= texture_state->h_mask; - } - dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; - } - } - else - { - dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; - dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; - dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; - dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; - } - - state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; - state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; - state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; - state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; -} - -static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) -{ - voodoo_texture_state_t texture_state; - int d[4]; - int s, t; - int tex_lod = state->tex_lod[tmu][state->lod]; - - texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; - texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; - texture_state.tex_shift = 8 - tex_lod; - - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - if (state->tex_s & 0x1000) - state->tex_s = ~state->tex_s; - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - if (state->tex_t & 0x1000) - state->tex_t = ~state->tex_t; - } - - if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) - { - int _ds, dt; - - state->tex_s -= 1 << (3+tex_lod); - state->tex_t -= 1 << (3+tex_lod); - - s = state->tex_s >> tex_lod; - t = state->tex_t >> tex_lod; - - _ds = s & 0xf; - dt = t & 0xf; - - s >>= 4; - t >>= 4; -//if (x == 80) -//if (voodoo_output) -// 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) -{ - if (params->textureMode[tmu] & 1) - { - int64_t _w = 0; - - if (tmu) - { - if (state->tmu1_w) - _w = (int64_t)((1ULL << 48) / state->tmu1_w); - state->tex_s = (int32_t)(((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } - else - { - if (state->tmu0_w) - _w = (int64_t)((1ULL << 48) / state->tmu0_w); - state->tex_s = (int32_t)(((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } - - state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); - } - else - { - if (tmu) - { - state->tex_s = (int32_t)(state->tmu1_s >> (14+14)); - state->tex_t = (int32_t)(state->tmu1_t >> (14+14)); - } - else - { - state->tex_s = (int32_t)(state->tmu0_s >> (14+14)); - state->tex_t = (int32_t)(state->tmu0_t >> (14+14)); - } - state->lod = state->tmu[tmu].lod; - } - - if (state->lod < state->lod_min[tmu]) - state->lod = state->lod_min[tmu]; - else if (state->lod > state->lod_max[tmu]) - state->lod = state->lod_max[tmu]; - state->lod_frac[tmu] = state->lod & 0xff; - state->lod >>= 8; - - voodoo_get_texture(voodoo, params, state, tmu, x); -} - -#define DEPTH_TEST(comp_depth) \ - do \ - { \ - switch (depth_op) \ - { \ - case DEPTHOP_NEVER: \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - case DEPTHOP_LESSTHAN: \ - if (!(comp_depth < old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_EQUAL: \ - if (!(comp_depth == old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_LESSTHANEQUAL: \ - if (!(comp_depth <= old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_GREATERTHAN: \ - if (!(comp_depth > old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_NOTEQUAL: \ - if (!(comp_depth != old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_GREATERTHANEQUAL: \ - if (!(comp_depth >= old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_ALWAYS: \ - break; \ - } \ - } while (0) - -#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \ - do \ - { \ - if (params->fogMode & FOG_CONSTANT) \ - { \ - src_r += params->fogColor.r; \ - src_g += params->fogColor.g; \ - src_b += params->fogColor.b; \ - } \ - else \ - { \ - int fog_r, fog_g, fog_b, fog_a = 0; \ - int fog_idx; \ - \ - if (!(params->fogMode & FOG_ADD)) \ - { \ - fog_r = params->fogColor.r; \ - fog_g = params->fogColor.g; \ - fog_b = params->fogColor.b; \ - } \ - else \ - fog_r = fog_g = fog_b = 0; \ - \ - if (!(params->fogMode & FOG_MULT)) \ - { \ - fog_r -= src_r; \ - fog_g -= src_g; \ - fog_b -= src_b; \ - } \ - \ - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) \ - { \ - case 0: \ - fog_idx = (w_depth >> 10) & 0x3f; \ - \ - fog_a = params->fogTable[fog_idx].fog; \ - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \ - break; \ - case FOG_Z: \ - fog_a = (z >> 20) & 0xff; \ - break; \ - case FOG_ALPHA: \ - fog_a = CLAMP(ia >> 12); \ - break; \ - case FOG_W: \ - fog_a = CLAMP((w >> 32) & 0xff); \ - break; \ - } \ - fog_a++; \ - \ - fog_r = (fog_r * fog_a) >> 8; \ - fog_g = (fog_g * fog_a) >> 8; \ - fog_b = (fog_b * fog_a) >> 8; \ - \ - if (params->fogMode & FOG_MULT) \ - { \ - src_r = fog_r; \ - src_g = fog_g; \ - src_b = fog_b; \ - } \ - else \ - { \ - src_r += fog_r; \ - src_g += fog_g; \ - src_b += fog_b; \ - } \ - } \ - \ - src_r = CLAMP(src_r); \ - src_g = CLAMP(src_g); \ - src_b = CLAMP(src_b); \ - } while (0) - -#define ALPHA_TEST(src_a) \ - do \ - { \ - switch (alpha_func) \ - { \ - case AFUNC_NEVER: \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - case AFUNC_LESSTHAN: \ - if (!(src_a < a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_EQUAL: \ - if (!(src_a == a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_LESSTHANEQUAL: \ - if (!(src_a <= a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_GREATERTHAN: \ - if (!(src_a > a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_NOTEQUAL: \ - if (!(src_a != a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_GREATERTHANEQUAL: \ - if (!(src_a >= a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_ALWAYS: \ - break; \ - } \ - } while (0) - -#define ALPHA_BLEND(src_r, src_g, src_b, src_a) \ - do \ - { \ - int _a; \ - int newdest_r = 0, newdest_g = 0, newdest_b = 0; \ - \ - switch (dest_afunc) \ - { \ - case AFUNC_AZERO: \ - newdest_r = newdest_g = newdest_b = 0; \ - break; \ - case AFUNC_ASRC_ALPHA: \ - newdest_r = (dest_r * src_a) / 255; \ - newdest_g = (dest_g * src_a) / 255; \ - newdest_b = (dest_b * src_a) / 255; \ - break; \ - case AFUNC_A_COLOR: \ - newdest_r = (dest_r * src_r) / 255; \ - newdest_g = (dest_g * src_g) / 255; \ - newdest_b = (dest_b * src_b) / 255; \ - break; \ - case AFUNC_ADST_ALPHA: \ - newdest_r = (dest_r * dest_a) / 255; \ - newdest_g = (dest_g * dest_a) / 255; \ - newdest_b = (dest_b * dest_a) / 255; \ - break; \ - case AFUNC_AONE: \ - newdest_r = dest_r; \ - newdest_g = dest_g; \ - newdest_b = dest_b; \ - break; \ - case AFUNC_AOMSRC_ALPHA: \ - newdest_r = (dest_r * (255-src_a)) / 255; \ - newdest_g = (dest_g * (255-src_a)) / 255; \ - newdest_b = (dest_b * (255-src_a)) / 255; \ - break; \ - case AFUNC_AOM_COLOR: \ - newdest_r = (dest_r * (255-src_r)) / 255; \ - newdest_g = (dest_g * (255-src_g)) / 255; \ - newdest_b = (dest_b * (255-src_b)) / 255; \ - break; \ - case AFUNC_AOMDST_ALPHA: \ - newdest_r = (dest_r * (255-dest_a)) / 255; \ - newdest_g = (dest_g * (255-dest_a)) / 255; \ - newdest_b = (dest_b * (255-dest_a)) / 255; \ - break; \ - case AFUNC_ASATURATE: \ - _a = MIN(src_a, 1-dest_a); \ - newdest_r = (dest_r * _a) / 255; \ - newdest_g = (dest_g * _a) / 255; \ - newdest_b = (dest_b * _a) / 255; \ - break; \ - } \ - \ - switch (src_afunc) \ - { \ - case AFUNC_AZERO: \ - src_r = src_g = src_b = 0; \ - break; \ - case AFUNC_ASRC_ALPHA: \ - src_r = (src_r * src_a) / 255; \ - src_g = (src_g * src_a) / 255; \ - src_b = (src_b * src_a) / 255; \ - break; \ - case AFUNC_A_COLOR: \ - src_r = (src_r * dest_r) / 255; \ - src_g = (src_g * dest_g) / 255; \ - src_b = (src_b * dest_b) / 255; \ - break; \ - case AFUNC_ADST_ALPHA: \ - src_r = (src_r * dest_a) / 255; \ - src_g = (src_g * dest_a) / 255; \ - src_b = (src_b * dest_a) / 255; \ - break; \ - case AFUNC_AONE: \ - break; \ - case AFUNC_AOMSRC_ALPHA: \ - src_r = (src_r * (255-src_a)) / 255; \ - src_g = (src_g * (255-src_a)) / 255; \ - src_b = (src_b * (255-src_a)) / 255; \ - break; \ - case AFUNC_AOM_COLOR: \ - src_r = (src_r * (255-dest_r)) / 255; \ - src_g = (src_g * (255-dest_g)) / 255; \ - src_b = (src_b * (255-dest_b)) / 255; \ - break; \ - case AFUNC_AOMDST_ALPHA: \ - src_r = (src_r * (255-dest_a)) / 255; \ - src_g = (src_g * (255-dest_a)) / 255; \ - src_b = (src_b * (255-dest_a)) / 255; \ - break; \ - case AFUNC_ACOLORBEFOREFOG: \ - fatal("AFUNC_ACOLORBEFOREFOG\n"); \ - break; \ - } \ - \ - src_r += newdest_r; \ - src_g += newdest_g; \ - src_b += newdest_b; \ - \ - src_r = CLAMP(src_r); \ - src_g = CLAMP(src_g); \ - src_b = CLAMP(src_b); \ - } while(0) - - -#define _rgb_sel ( params->fbzColorPath & 3) -#define a_sel ( (params->fbzColorPath >> 2) & 3) -#define cc_localselect ( params->fbzColorPath & (1 << 4)) -#define cca_localselect ( (params->fbzColorPath >> 5) & 3) -#define cc_localselect_override ( params->fbzColorPath & (1 << 7)) -#define cc_zero_other ( params->fbzColorPath & (1 << 8)) -#define cc_sub_clocal ( params->fbzColorPath & (1 << 9)) -#define cc_mselect ( (params->fbzColorPath >> 10) & 7) -#define cc_reverse_blend ( params->fbzColorPath & (1 << 13)) -#define cc_add ( (params->fbzColorPath >> 14) & 3) -#define cc_add_alocal ( params->fbzColorPath & (1 << 15)) -#define cc_invert_output ( params->fbzColorPath & (1 << 16)) -#define cca_zero_other ( params->fbzColorPath & (1 << 17)) -#define cca_sub_clocal ( params->fbzColorPath & (1 << 18)) -#define cca_mselect ( (params->fbzColorPath >> 19) & 7) -#define cca_reverse_blend ( params->fbzColorPath & (1 << 22)) -#define cca_add ( (params->fbzColorPath >> 23) & 3) -#define cca_invert_output ( params->fbzColorPath & (1 << 25)) -#define tc_zero_other (params->textureMode[0] & (1 << 12)) -#define tc_sub_clocal (params->textureMode[0] & (1 << 13)) -#define tc_mselect ((params->textureMode[0] >> 14) & 7) -#define tc_reverse_blend (params->textureMode[0] & (1 << 17)) -#define tc_add_clocal (params->textureMode[0] & (1 << 18)) -#define tc_add_alocal (params->textureMode[0] & (1 << 19)) -#define tc_invert_output (params->textureMode[0] & (1 << 20)) -#define tca_zero_other (params->textureMode[0] & (1 << 21)) -#define tca_sub_clocal (params->textureMode[0] & (1 << 22)) -#define tca_mselect ((params->textureMode[0] >> 23) & 7) -#define tca_reverse_blend (params->textureMode[0] & (1 << 26)) -#define tca_add_clocal (params->textureMode[0] & (1 << 27)) -#define tca_add_alocal (params->textureMode[0] & (1 << 28)) -#define tca_invert_output (params->textureMode[0] & (1 << 29)) - -#define tc_sub_clocal_1 (params->textureMode[1] & (1 << 13)) -#define tc_mselect_1 ((params->textureMode[1] >> 14) & 7) -#define tc_reverse_blend_1 (params->textureMode[1] & (1 << 17)) -#define tc_add_clocal_1 (params->textureMode[1] & (1 << 18)) -#define tc_add_alocal_1 (params->textureMode[1] & (1 << 19)) -#define tca_sub_clocal_1 (params->textureMode[1] & (1 << 22)) -#define tca_mselect_1 ((params->textureMode[1] >> 23) & 7) -#define tca_reverse_blend_1 (params->textureMode[1] & (1 << 26)) -#define tca_add_clocal_1 (params->textureMode[1] & (1 << 27)) -#define tca_add_alocal_1 (params->textureMode[1] & (1 << 28)) - -#define src_afunc ( (params->alphaMode >> 8) & 0xf) -#define dest_afunc ( (params->alphaMode >> 12) & 0xf) -#define alpha_func ( (params->alphaMode >> 1) & 7) -#define a_ref ( params->alphaMode >> 24) -#define depth_op ( (params->fbzMode >> 5) & 7) -#define dither ( params->fbzMode & FBZ_DITHER) -#define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) - -/*Perform texture fetch and blending for both TMUs*/ -static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) -{ - int r,g,b,a; - int c_reverse, a_reverse; -// int c_reverse1, a_reverse1; - int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; - - voodoo_tmu_fetch(voodoo, params, state, 1, x); - - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) - { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } - else - { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } -/* c_reverse1 = c_reverse; - a_reverse1 = a_reverse;*/ - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL: - factor_r = state->tex_r[1]; - factor_g = state->tex_g[1]; - factor_b = state->tex_b[1]; - break; - case TC_MSELECT_AOTHER: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_ALOCAL: - factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_DETAIL: - factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_r > params->detail_max[1]) - factor_r = params->detail_max[1]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC: - factor_r = factor_g = factor_b = state->lod_frac[1]; - break; - } - if (!c_reverse) - { - r = (-state->tex_r[1] * (factor_r + 1)) >> 8; - g = (-state->tex_g[1] * (factor_g + 1)) >> 8; - b = (-state->tex_b[1] * (factor_b + 1)) >> 8; - } - else - { - r = (-state->tex_r[1] * ((factor_r^0xff) + 1)) >> 8; - g = (-state->tex_g[1] * ((factor_g^0xff) + 1)) >> 8; - b = (-state->tex_b[1] * ((factor_b^0xff) + 1)) >> 8; - } - if (tc_add_clocal_1) - { - r += state->tex_r[1]; - g += state->tex_g[1]; - b += state->tex_b[1]; - } - else if (tc_add_alocal_1) - { - r += state->tex_a[1]; - g += state->tex_a[1]; - b += state->tex_a[1]; - } - state->tex_r[1] = CLAMP(r); - state->tex_g[1] = CLAMP(g); - state->tex_b[1] = CLAMP(b); - } - if (tca_sub_clocal_1) - { - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: - factor_a = 0; - break; - case TCA_MSELECT_CLOCAL: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_AOTHER: - factor_a = 0; - break; - case TCA_MSELECT_ALOCAL: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_DETAIL: - factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_a > params->detail_max[1]) - factor_a = params->detail_max[1]; - break; - case TCA_MSELECT_LOD_FRAC: - factor_a = state->lod_frac[1]; - break; - } - if (!a_reverse) - a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (-state->tex_a[1] * (factor_a + 1)) >> 8; - if (tca_add_clocal_1 || tca_add_alocal_1) - a += state->tex_a[1]; - state->tex_a[1] = CLAMP(a); - } - - - voodoo_tmu_fetch(voodoo, params, state, 0, x); - - if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) - { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } - else - { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } - - if (!tc_zero_other) - { - r = state->tex_r[1]; - g = state->tex_g[1]; - b = state->tex_b[1]; - } - else - r = g = b = 0; - if (tc_sub_clocal) - { - r -= state->tex_r[0]; - g -= state->tex_g[0]; - b -= state->tex_b[0]; - } - switch (tc_mselect) - { - case TC_MSELECT_ZERO: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL: - factor_r = state->tex_r[0]; - factor_g = state->tex_g[0]; - factor_b = state->tex_b[0]; - break; - case TC_MSELECT_AOTHER: - factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_ALOCAL: - factor_r = factor_g = factor_b = state->tex_a[0]; - break; - case TC_MSELECT_DETAIL: - factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_r > params->detail_max[0]) - factor_r = params->detail_max[0]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC: - factor_r = factor_g = factor_b = state->lod_frac[0]; - break; - } - if (!c_reverse) - { - r = (r * (factor_r + 1)) >> 8; - g = (g * (factor_g + 1)) >> 8; - b = (b * (factor_b + 1)) >> 8; - } - else - { - r = (r * ((factor_r^0xff) + 1)) >> 8; - g = (g * ((factor_g^0xff) + 1)) >> 8; - b = (b * ((factor_b^0xff) + 1)) >> 8; - } - if (tc_add_clocal) - { - r += state->tex_r[0]; - g += state->tex_g[0]; - b += state->tex_b[0]; - } - else if (tc_add_alocal) - { - r += state->tex_a[0]; - g += state->tex_a[0]; - b += state->tex_a[0]; - } - - if (!tca_zero_other) - a = state->tex_a[1]; - else - a = 0; - if (tca_sub_clocal) - a -= state->tex_a[0]; - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: - factor_a = 0; - break; - case TCA_MSELECT_CLOCAL: - factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_AOTHER: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_ALOCAL: - factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_DETAIL: - factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_a > params->detail_max[0]) - factor_a = params->detail_max[0]; - break; - case TCA_MSELECT_LOD_FRAC: - factor_a = state->lod_frac[0]; - break; - } - if (a_reverse) - a = (a * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (a * (factor_a + 1)) >> 8; - if (tca_add_clocal || tca_add_alocal) - a += state->tex_a[0]; - - - state->tex_r[0] = CLAMP(r); - state->tex_g[0] = CLAMP(g); - state->tex_b[0] = CLAMP(b); - state->tex_a[0] = CLAMP(a); - - if (tc_invert_output) - { - state->tex_r[0] ^= 0xff; - state->tex_g[0] ^= 0xff; - state->tex_b[0] ^= 0xff; - } - if (tca_invert_output) - state->tex_a[0] ^= 0xff; -} - -#if (defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__) -#include "vid_voodoo_codegen_x86.h" -#elif (defined __amd64__) -#include "vid_voodoo_codegen_x86-64.h" -#else -#define NO_CODEGEN -static int voodoo_recomp = 0; -#endif - -static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) -{ -/* int rgb_sel = params->fbzColorPath & 3; - int a_sel = (params->fbzColorPath >> 2) & 3; - int cc_localselect = params->fbzColorPath & (1 << 4); - int cca_localselect = (params->fbzColorPath >> 5) & 3; - int cc_localselect_override = params->fbzColorPath & (1 << 7); - int cc_zero_other = params->fbzColorPath & (1 << 8); - int cc_sub_clocal = params->fbzColorPath & (1 << 9); - int cc_mselect = (params->fbzColorPath >> 10) & 7; - int cc_reverse_blend = params->fbzColorPath & (1 << 13); - int cc_add = (params->fbzColorPath >> 14) & 3; - int cc_add_alocal = params->fbzColorPath & (1 << 15); - int cc_invert_output = params->fbzColorPath & (1 << 16); - int cca_zero_other = params->fbzColorPath & (1 << 17); - int cca_sub_clocal = params->fbzColorPath & (1 << 18); - int cca_mselect = (params->fbzColorPath >> 19) & 7; - int cca_reverse_blend = params->fbzColorPath & (1 << 22); - int cca_add = (params->fbzColorPath >> 23) & 3; - int cca_invert_output = params->fbzColorPath & (1 << 25); - int src_afunc = (params->alphaMode >> 8) & 0xf; - int dest_afunc = (params->alphaMode >> 12) & 0xf; - int alpha_func = (params->alphaMode >> 1) & 7; - int a_ref = params->alphaMode >> 24; - int depth_op = (params->fbzMode >> 5) & 7; - int dither = params->fbzMode & FBZ_DITHER;*/ - int texels; - int c; -#ifndef NO_CODEGEN - uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); -#endif - int y_diff = SLI_ENABLED ? 2 : 1; - - if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - texels = 1; - else - texels = 2; - - state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; - state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; - state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; - state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; -// int last_x; -// 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++) - { - state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; - state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; - } - - state->tformat = params->tformat[0]; - - state->tex_w_mask[0] = params->tex_w_mask[0]; - state->tex_h_mask[0] = params->tex_h_mask[0]; - state->tex_shift[0] = params->tex_shift[0]; - state->tex_lod[0] = params->tex_lod[0]; - state->tex_w_mask[1] = params->tex_w_mask[1]; - state->tex_h_mask[1] = params->tex_h_mask[1]; - state->tex_shift[1] = params->tex_shift[1]; - state->tex_lod[1] = params->tex_lod[1]; - - if ((params->fbzMode & 1) && (ystart < params->clipLowY)) - { - int dy = params->clipLowY - ystart; - - state->base_r += params->dRdY*dy; - state->base_g += params->dGdY*dy; - state->base_b += params->dBdY*dy; - state->base_a += params->dAdY*dy; - state->base_z += params->dZdY*dy; - state->tmu[0].base_s += params->tmu[0].dSdY*dy; - state->tmu[0].base_t += params->tmu[0].dTdY*dy; - state->tmu[0].base_w += params->tmu[0].dWdY*dy; - state->tmu[1].base_s += params->tmu[1].dSdY*dy; - state->tmu[1].base_t += params->tmu[1].dTdY*dy; - state->tmu[1].base_w += params->tmu[1].dWdY*dy; - state->base_w += params->dWdY*dy; - state->xstart += state->dx1*dy; - state->xend += state->dx2*dy; - - ystart = params->clipLowY; - } - - if ((params->fbzMode & 1) && (yend >= params->clipHighY)) - yend = params->clipHighY-1; - - state->y = ystart; -// yend--; - - if (SLI_ENABLED) - { - int test_y; - - if (params->fbzMode & (1 << 17)) - test_y = (voodoo->v_disp-1) - state->y; - else - test_y = state->y; - - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) - { - state->y++; - - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - } -#ifndef NO_CODEGEN - if (voodoo->use_recompiler) - voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); - else - voodoo_draw = NULL; -#endif - - if (voodoo_output) - 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 += y_diff) - { - int x, x2; - int real_y = (state->y << 4) + 8; - int start_x, start_x2; - int dx; - uint16_t *fb_mem, *aux_mem; - - state->ir = state->base_r; - state->ig = state->base_g; - state->ib = state->base_b; - state->ia = state->base_a; - state->z = state->base_z; - state->tmu0_s = state->tmu[0].base_s; - state->tmu0_t = state->tmu[0].base_t; - state->tmu0_w = state->tmu[0].base_w; - state->tmu1_s = state->tmu[1].base_s; - state->tmu1_t = state->tmu[1].base_t; - state->tmu1_w = state->tmu[1].base_w; - state->w = state->base_w; - - x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); - - if (real_y < state->vertexBy) - x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); - else - x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); - - if (params->fbzMode & (1 << 17)) - real_y = (voodoo->v_disp-1) - (real_y >> 4); - else - real_y >>= 4; - - if (SLI_ENABLED) - { - if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) - goto next_line; - } - else - { - if ((real_y & voodoo->odd_even_mask) != odd_even) - goto next_line; - } - - start_x = x; - - if (state->xdir > 0) - x2 -= (1 << 16); - else - x -= (1 << 16); - dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); - start_x2 = x + 0x7000; - x = (x + 0x7000) >> 16; - x2 = (x2 + 0x7000) >> 16; - - if (voodoo_output) - pclog("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); - - state->ir += (params->dRdX * dx); - state->ig += (params->dGdX * dx); - state->ib += (params->dBdX * dx); - state->ia += (params->dAdX * dx); - state->z += (params->dZdX * dx); - state->tmu0_s += (params->tmu[0].dSdX * dx); - state->tmu0_t += (params->tmu[0].dTdX * dx); - state->tmu0_w += (params->tmu[0].dWdX * dx); - state->tmu1_s += (params->tmu[1].dSdX * dx); - state->tmu1_t += (params->tmu[1].dTdX * dx); - state->tmu1_w += (params->tmu[1].dWdX * dx); - state->w += (params->dWdX * dx); - - if (voodoo_output) - 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) - { - if (state->xdir > 0) - { - if (x < params->clipLeft) - { - int dx = params->clipLeft - x; - - state->ir += params->dRdX*dx; - state->ig += params->dGdX*dx; - state->ib += params->dBdX*dx; - state->ia += params->dAdX*dx; - state->z += params->dZdX*dx; - state->tmu0_s += params->tmu[0].dSdX*dx; - state->tmu0_t += params->tmu[0].dTdX*dx; - state->tmu0_w += params->tmu[0].dWdX*dx; - state->tmu1_s += params->tmu[1].dSdX*dx; - state->tmu1_t += params->tmu[1].dTdX*dx; - state->tmu1_w += params->tmu[1].dWdX*dx; - state->w += params->dWdX*dx; - - x = params->clipLeft; - } - if (x2 >= params->clipRight) - x2 = params->clipRight-1; - } - else - { - if (x >= params->clipRight) - { - int dx = (params->clipRight-1) - x; - - state->ir += params->dRdX*dx; - state->ig += params->dGdX*dx; - state->ib += params->dBdX*dx; - state->ia += params->dAdX*dx; - state->z += params->dZdX*dx; - state->tmu0_s += params->tmu[0].dSdX*dx; - state->tmu0_t += params->tmu[0].dTdX*dx; - state->tmu0_w += params->tmu[0].dWdX*dx; - state->tmu1_s += params->tmu[1].dSdX*dx; - state->tmu1_t += params->tmu[1].dTdX*dx; - state->tmu1_w += params->tmu[1].dWdX*dx; - state->w += params->dWdX*dx; - - x = params->clipRight-1; - } - if (x2 < params->clipLeft) - x2 = params->clipLeft; - } - } - - if (x2 < x && state->xdir > 0) - goto next_line; - if (x2 > x && state->xdir < 0) - goto next_line; - - if (SLI_ENABLED) - { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * voodoo->row_width)) & voodoo->fb_mask]; - } - else - { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; - } - - if (voodoo_output) - 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); - - state->pixel_count = 0; - state->texel_count = 0; - state->x = x; - state->x2 = x2; -#ifndef NO_CODEGEN - if (voodoo->use_recompiler) - { - voodoo_draw(state, params, x, real_y); - } - else -#endif - do - { - start_x = x; - state->x = x; - voodoo->pixel_count[odd_even]++; - voodoo->texel_count[odd_even] += texels; - voodoo->fbiPixelsIn++; - - if (voodoo_output) - 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 = 0, src_g = 0, src_b = 0, src_a = 0; - int msel_r, msel_g, msel_b, msel_a; - uint8_t dest_r, dest_g, dest_b, dest_a; - uint16_t dat; - int sel; - int32_t new_depth, w_depth; - - if (state->w & 0xffff00000000) - w_depth = 0; - else if (!(state->w & 0xffff0000)) - w_depth = 0xf001; - else - { - int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); - int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; - w_depth = (exp << 12) + mant + 1; - if (w_depth > 0xffff) - w_depth = 0xffff; - } - -// w_depth = CLAMP16(w_depth); - - if (params->fbzMode & FBZ_W_BUFFER) - new_depth = w_depth; - else - new_depth = CLAMP16(state->z >> 12); - - if (params->fbzMode & FBZ_DEPTH_BIAS) - new_depth = CLAMP16(new_depth + (int16_t)params->zaColor); - - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = aux_mem[x]; - - DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); - } - - dat = fb_mem[x]; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { - /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ - voodoo_tmu_fetch(voodoo, params, state, 0, x); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { - /*TMU0 in pass-through mode, only sample TMU1*/ - voodoo_tmu_fetch(voodoo, params, state, 1, x); - - state->tex_r[0] = state->tex_r[1]; - state->tex_g[0] = state->tex_g[1]; - state->tex_b[0] = state->tex_b[1]; - state->tex_a[0] = state->tex_a[1]; - } - else - { - voodoo_tmu_fetch_and_blend(voodoo, params, state, x); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - state->tex_r[0] == params->chromaKey_r && - state->tex_g[0] == params->chromaKey_g && - state->tex_b[0] == params->chromaKey_b) - { - voodoo->fbiChromaFail++; - goto skip_pixel; - } - } - - if (voodoo->trexInit1[0] & (1 << 18)) - { - state->tex_r[0] = state->tex_g[0] = 0; - state->tex_b[0] = voodoo->tmuConfig; - } - - if (cc_localselect_override) - sel = (state->tex_a[0] & 0x80) ? 1 : 0; - else - sel = cc_localselect; - - if (sel) - { - clocal_r = (params->color0 >> 16) & 0xff; - clocal_g = (params->color0 >> 8) & 0xff; - clocal_b = params->color0 & 0xff; - } - else - { - clocal_r = CLAMP(state->ir >> 12); - clocal_g = CLAMP(state->ig >> 12); - clocal_b = CLAMP(state->ib >> 12); - } - - switch (_rgb_sel) - { - case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ - cother_r = CLAMP(state->ir >> 12); - cother_g = CLAMP(state->ig >> 12); - cother_b = CLAMP(state->ib >> 12); - break; - - case CC_LOCALSELECT_TEX: /*TREX Color Output*/ - cother_r = state->tex_r[0]; - cother_g = state->tex_g[0]; - cother_b = state->tex_b[0]; - break; - - case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ - cother_r = (params->color1 >> 16) & 0xff; - cother_g = (params->color1 >> 8) & 0xff; - cother_b = params->color1 & 0xff; - break; - - case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ - cother_r = src_r; - cother_g = src_g; - cother_b = src_b; - break; - } - - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - alocal = CLAMP(state->ia >> 12); - break; - - case CCA_LOCALSELECT_COLOR0: - alocal = (params->color0 >> 24) & 0xff; - break; - - case CCA_LOCALSELECT_ITER_Z: - alocal = CLAMP(state->z >> 20); - break; - - default: - fatal("Bad cca_localselect %i\n", cca_localselect); - alocal = 0xff; - break; - } - - switch (a_sel) - { - case A_SEL_ITER_A: - aother = CLAMP(state->ia >> 12); - break; - case A_SEL_TEX: - aother = state->tex_a[0]; - break; - case A_SEL_COLOR1: - aother = (params->color1 >> 24) & 0xff; - break; - default: - fatal("Bad a_sel %i\n", a_sel); - aother = 0; - break; - } - - if (cc_zero_other) - { - src_r = 0; - src_g = 0; - src_b = 0; - } - else - { - src_r = cother_r; - src_g = cother_g; - src_b = cother_b; - } - - if (cca_zero_other) - src_a = 0; - else - src_a = aother; - - if (cc_sub_clocal) - { - src_r -= clocal_r; - src_g -= clocal_g; - src_b -= clocal_b; - } - - if (cca_sub_clocal) - src_a -= alocal; - - switch (cc_mselect) - { - case CC_MSELECT_ZERO: - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - case CC_MSELECT_CLOCAL: - msel_r = clocal_r; - msel_g = clocal_g; - msel_b = clocal_b; - break; - case CC_MSELECT_AOTHER: - msel_r = aother; - msel_g = aother; - msel_b = aother; - break; - case CC_MSELECT_ALOCAL: - msel_r = alocal; - msel_g = alocal; - msel_b = alocal; - break; - case CC_MSELECT_TEX: - msel_r = state->tex_a[0]; - msel_g = state->tex_a[0]; - msel_b = state->tex_a[0]; - break; - case CC_MSELECT_TEXRGB: - msel_r = state->tex_r[0]; - msel_g = state->tex_g[0]; - msel_b = state->tex_b[0]; - break; - - default: - fatal("Bad cc_mselect %i\n", cc_mselect); - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - } - - switch (cca_mselect) - { - case CCA_MSELECT_ZERO: - msel_a = 0; - break; - case CCA_MSELECT_ALOCAL: - msel_a = alocal; - break; - case CCA_MSELECT_AOTHER: - msel_a = aother; - break; - case CCA_MSELECT_ALOCAL2: - msel_a = alocal; - break; - case CCA_MSELECT_TEX: - msel_a = state->tex_a[0]; - break; - - default: - fatal("Bad cca_mselect %i\n", cca_mselect); - msel_a = 0; - break; - } - - if (!cc_reverse_blend) - { - msel_r ^= 0xff; - msel_g ^= 0xff; - msel_b ^= 0xff; - } - msel_r++; - msel_g++; - msel_b++; - - if (!cca_reverse_blend) - msel_a ^= 0xff; - msel_a++; - - src_r = (src_r * msel_r) >> 8; - src_g = (src_g * msel_g) >> 8; - src_b = (src_b * msel_b) >> 8; - src_a = (src_a * msel_a) >> 8; - - switch (cc_add) - { - case CC_ADD_CLOCAL: - src_r += clocal_r; - src_g += clocal_g; - src_b += clocal_b; - break; - case CC_ADD_ALOCAL: - src_r += alocal; - src_g += alocal; - src_b += alocal; - break; - case 0: - break; - default: - fatal("Bad cc_add %i\n", cc_add); - } - - if (cca_add) - src_a += alocal; - - src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b); - src_a = CLAMP(src_a); - - if (cc_invert_output) - { - src_r ^= 0xff; - src_g ^= 0xff; - src_b ^= 0xff; - } - if (cca_invert_output) - src_a ^= 0xff; - - if (params->fogMode & FOG_ENABLE) - APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); - - if (params->alphaMode & 1) - ALPHA_TEST(src_a); - - if (params->alphaMode & (1 << 4)) - ALPHA_BLEND(src_r, src_g, src_b, src_a); - - if (update) - { - if (dither) - { - if (dither2x2) - { - src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; - src_g = dither_g2x2[src_g][real_y & 1][x & 1]; - src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; - } - else - { - src_r = dither_rb[src_r][real_y & 3][x & 3]; - src_g = dither_g[src_g][real_y & 3][x & 3]; - src_b = dither_rb[src_b][real_y & 3][x & 3]; - } - } - else - { - src_r >>= 3; - src_g >>= 2; - src_b >>= 3; - } - - if (params->fbzMode & FBZ_RGB_WMASK) - fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - aux_mem[x] = new_depth; - } - } - voodoo_output &= ~2; - voodoo->fbiPixelsOut++; -skip_pixel: - if (state->xdir > 0) - { - state->ir += params->dRdX; - state->ig += params->dGdX; - state->ib += params->dBdX; - state->ia += params->dAdX; - state->z += params->dZdX; - state->tmu0_s += params->tmu[0].dSdX; - state->tmu0_t += params->tmu[0].dTdX; - state->tmu0_w += params->tmu[0].dWdX; - state->tmu1_s += params->tmu[1].dSdX; - state->tmu1_t += params->tmu[1].dTdX; - state->tmu1_w += params->tmu[1].dWdX; - state->w += params->dWdX; - } - else - { - state->ir -= params->dRdX; - state->ig -= params->dGdX; - state->ib -= params->dBdX; - state->ia -= params->dAdX; - state->z -= params->dZdX; - state->tmu0_s -= params->tmu[0].dSdX; - state->tmu0_t -= params->tmu[0].dTdX; - state->tmu0_w -= params->tmu[0].dWdX; - state->tmu1_s -= params->tmu[1].dSdX; - state->tmu1_t -= params->tmu[1].dTdX; - state->tmu1_w -= params->tmu[1].dWdX; - state->w -= params->dWdX; - } - - x += state->xdir; - } while (start_x != x2); - - voodoo->pixel_count[odd_even] += state->pixel_count; - voodoo->texel_count[odd_even] += state->texel_count; - voodoo->fbiPixelsIn += state->pixel_count; - - if (voodoo->params.draw_offset == voodoo->params.front_offset) - voodoo->dirty_line[real_y >> 1] = 1; -next_line: - if (SLI_ENABLED) - { - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - - voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; - voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; -} - -static void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) -{ - voodoo_state_t state; - int vertexAy_adjusted; - int vertexCy_adjusted; - int dx, dy; - - uint64_t tempdx, tempdy; - uint64_t tempLOD; - int LOD; - int lodbias; - - voodoo->tri_count++; - - dx = 8 - (params->vertexAx & 0xf); - if ((params->vertexAx & 0xf) > 8) - dx += 16; - dy = 8 - (params->vertexAy & 0xf); - if ((params->vertexAy & 0xf) > 8) - dy += 16; - -/* pclog("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, - (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, - (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ - - state.base_r = params->startR; - state.base_g = params->startG; - state.base_b = params->startB; - state.base_a = params->startA; - state.base_z = params->startZ; - state.tmu[0].base_s = params->tmu[0].startS; - state.tmu[0].base_t = params->tmu[0].startT; - state.tmu[0].base_w = params->tmu[0].startW; - state.tmu[1].base_s = params->tmu[1].startS; - state.tmu[1].base_t = params->tmu[1].startT; - state.tmu[1].base_w = params->tmu[1].startW; - state.base_w = params->startW; - - if (params->fbzColorPath & FBZ_PARAM_ADJUST) - { - state.base_r += (dx*params->dRdX + dy*params->dRdY) >> 4; - state.base_g += (dx*params->dGdX + dy*params->dGdY) >> 4; - state.base_b += (dx*params->dBdX + dy*params->dBdY) >> 4; - state.base_a += (dx*params->dAdX + dy*params->dAdY) >> 4; - state.base_z += (dx*params->dZdX + dy*params->dZdY) >> 4; - state.tmu[0].base_s += (dx*params->tmu[0].dSdX + dy*params->tmu[0].dSdY) >> 4; - state.tmu[0].base_t += (dx*params->tmu[0].dTdX + dy*params->tmu[0].dTdY) >> 4; - state.tmu[0].base_w += (dx*params->tmu[0].dWdX + dy*params->tmu[0].dWdY) >> 4; - state.tmu[1].base_s += (dx*params->tmu[1].dSdX + dy*params->tmu[1].dSdY) >> 4; - state.tmu[1].base_t += (dx*params->tmu[1].dTdX + dy*params->tmu[1].dTdY) >> 4; - state.tmu[1].base_w += (dx*params->tmu[1].dWdX + dy*params->tmu[1].dWdY) >> 4; - state.base_w += (dx*params->dWdX + dy*params->dWdY) >> 4; - } - - tris++; - - state.vertexAy = params->vertexAy & ~0xffff0000; - if (state.vertexAy & 0x8000) - state.vertexAy |= 0xffff0000; - state.vertexBy = params->vertexBy & ~0xffff0000; - if (state.vertexBy & 0x8000) - state.vertexBy |= 0xffff0000; - state.vertexCy = params->vertexCy & ~0xffff0000; - if (state.vertexCy & 0x8000) - state.vertexCy |= 0xffff0000; - - state.vertexAx = params->vertexAx & ~0xffff0000; - if (state.vertexAx & 0x8000) - state.vertexAx |= 0xffff0000; - state.vertexBx = params->vertexBx & ~0xffff0000; - if (state.vertexBx & 0x8000) - state.vertexBx |= 0xffff0000; - state.vertexCx = params->vertexCx & ~0xffff0000; - if (state.vertexCx & 0x8000) - state.vertexCx |= 0xffff0000; - - vertexAy_adjusted = (state.vertexAy+7) >> 4; - vertexCy_adjusted = (state.vertexCy+7) >> 4; - - if (state.vertexBy - state.vertexAy) - state.dxAB = (int)((((int64_t)state.vertexBx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexBy - state.vertexAy); - else - state.dxAB = 0; - if (state.vertexCy - state.vertexAy) - state.dxAC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexCy - state.vertexAy); - else - state.dxAC = 0; - if (state.vertexCy - state.vertexBy) - state.dxBC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexBx << 12)) << 4) / (int)(state.vertexCy - state.vertexBy); - else - state.dxBC = 0; - - state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; - state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; - if (state.lod_max[0] > 0x800) - state.lod_max[0] = 0x800; - state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; - state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; - if (state.lod_max[1] > 0x800) - state.lod_max[1] = 0x800; - - state.xstart = state.xend = state.vertexAx << 8; - state.xdir = params->sign ? -1 : 1; - - state.y = (state.vertexAy + 8) >> 4; - state.ydir = 1; - - - tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); - tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); - - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; - - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; - - lodbias = (params->tLOD[0] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[0].lod = LOD + (lodbias << 6); - - - tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); - tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); - - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; - - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; - - lodbias = (params->tLOD[1] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[1].lod = LOD + (lodbias << 6); - - - voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); -} - -static inline void wake_render_thread(voodoo_t *voodoo) -{ - thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/ - if (voodoo->render_threads == 2) - thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ -} - -static inline void wait_for_render_thread_idle(voodoo_t *voodoo) -{ - while (!PARAM_EMPTY_1 || (voodoo->render_threads == 2 && !PARAM_EMPTY_2) || voodoo->render_voodoo_busy[0] || (voodoo->render_threads == 2 && voodoo->render_voodoo_busy[1])) - { - wake_render_thread(voodoo); - if (!PARAM_EMPTY_1 || voodoo->render_voodoo_busy[0]) - thread_wait_event(voodoo->render_not_full_event[0], 1); - if (voodoo->render_threads == 2 && (!PARAM_EMPTY_2 || voodoo->render_voodoo_busy[1])) - thread_wait_event(voodoo->render_not_full_event[1], 1); - } -} - -static void render_thread(void *param, int odd_even) -{ - voodoo_t *voodoo = (voodoo_t *)param; - - while (1) - { - thread_set_event(voodoo->render_not_full_event[odd_even]); - thread_wait_event(voodoo->wake_render_thread[odd_even], -1); - thread_reset_event(voodoo->wake_render_thread[odd_even]); - voodoo->render_voodoo_busy[odd_even] = 1; - - while (!(odd_even ? PARAM_EMPTY_2 : PARAM_EMPTY_1)) - { - uint64_t start_time = timer_read(); - uint64_t end_time; - voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; - - voodoo_triangle(voodoo, params, odd_even); - - voodoo->params_read_idx[odd_even]++; - - if ((odd_even ? PARAM_ENTRIES_2 : PARAM_ENTRIES_1) > (PARAM_SIZE - 10)) - thread_set_event(voodoo->render_not_full_event[odd_even]); - - end_time = timer_read(); - voodoo->render_time[odd_even] += end_time - start_time; - } - - voodoo->render_voodoo_busy[odd_even] = 0; - } -} - -static void render_thread_1(void *param) -{ - render_thread(param, 0); -} -static void render_thread_2(void *param) -{ - render_thread(param, 1); -} - -static inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) -{ - voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; - - while (PARAM_FULL_1 || (voodoo->render_threads == 2 && PARAM_FULL_2)) - { - thread_reset_event(voodoo->render_not_full_event[0]); - if (voodoo->render_threads == 2) - thread_reset_event(voodoo->render_not_full_event[1]); - if (PARAM_FULL_1) - { - thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ - } - if (voodoo->render_threads == 2 && PARAM_FULL_2) - { - thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ - } - } - - use_texture(voodoo, params, 0); - if (voodoo->dual_tmus) - use_texture(voodoo, params, 1); - - memcpy(params_new, params, sizeof(voodoo_params_t)); - - voodoo->params_write_idx++; - - if (PARAM_ENTRIES_1 < 4 || (voodoo->render_threads == 2 && PARAM_ENTRIES_2 < 4)) - wake_render_thread(voodoo); -} - -static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) -{ - int y; - int low_y, high_y; - - if (params->fbzMode & (1 << 17)) - { - high_y = voodoo->v_disp - params->clipLowY; - low_y = voodoo->v_disp - params->clipHighY; - } - else - { - low_y = params->clipLowY; - high_y = params->clipHighY; - } - - if (params->fbzMode & FBZ_RGB_WMASK) - { - int r, g, b; - uint16_t col; - - r = ((params->color1 >> 16) >> 3) & 0x1f; - g = ((params->color1 >> 8) >> 2) & 0x3f; - b = (params->color1 >> 3) & 0x1f; - col = b | (g << 5) | (r << 11); - - if (SLI_ENABLED) - { - for (y = low_y; y < high_y; y += 2) - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } - else - { - for (y = low_y; y < high_y; y++) - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } - } - if (params->fbzMode & FBZ_DEPTH_WMASK) - { - if (SLI_ENABLED) - { - for (y = low_y; y < high_y; y += 2) - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } - else - { - for (y = low_y; y < high_y; y++) - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } - } -} - -enum -{ - SETUPMODE_RGB = (1 << 0), - SETUPMODE_ALPHA = (1 << 1), - SETUPMODE_Z = (1 << 2), - SETUPMODE_Wb = (1 << 3), - SETUPMODE_W0 = (1 << 4), - SETUPMODE_S0_T0 = (1 << 5), - SETUPMODE_W1 = (1 << 6), - SETUPMODE_S1_T1 = (1 << 7), - - SETUPMODE_STRIP_MODE = (1 << 16), - SETUPMODE_CULLING_ENABLE = (1 << 17), - SETUPMODE_CULLING_SIGN = (1 << 18), - SETUPMODE_DISABLE_PINGPONG = (1 << 19) -}; - -static void triangle_setup(voodoo_t *voodoo) -{ - float dxAB, dxBC, dyAB, dyBC; - float area; - int va = 0, vb = 1, vc = 2; - int reverse_cull = 0; - vert_t verts[3]; - - verts[0] = voodoo->verts[0]; - verts[1] = voodoo->verts[1]; - verts[2] = voodoo->verts[2]; - - if (verts[0].sVy < verts[1].sVy) - { - if (verts[1].sVy < verts[2].sVy) - { - /* V1>V0, V2>V1, V2>V1>V0*/ - va = 0; /*OK*/ - vb = 1; - vc = 2; - } - else - { - /* V1>V0, V1>V2*/ - if (verts[0].sVy < verts[2].sVy) - { - /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ - va = 0; - vb = 2; - vc = 1; - reverse_cull = 1; - } - else - { - /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ - va = 2; - vb = 0; - vc = 1; - } - } - } - else - { - if (verts[1].sVy < verts[2].sVy) - { - /* V0>V1, V2>V1*/ - if (verts[0].sVy < verts[2].sVy) - { - /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ - va = 1; - vb = 0; - vc = 2; - reverse_cull = 1; - } - else - { - /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ - va = 1; - vb = 2; - vc = 0; - } - } - else - { - /*V0>V1>V2*/ - va = 2; - vb = 1; - vc = 0; - reverse_cull = 1; - } - } - - dxAB = verts[va].sVx - verts[vb].sVx; - dxBC = verts[vb].sVx - verts[vc].sVx; - dyAB = verts[va].sVy - verts[vb].sVy; - dyBC = verts[vb].sVy - verts[vc].sVy; - - area = dxAB * dyBC - dxBC * dyAB; - - if (area == 0.0) - { - if ((voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) && - !(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) - voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; - - return; - } - - dxAB /= area; - dxBC /= area; - dyAB /= area; - dyBC /= area; - - if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) - { - int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; - int sign = (area < 0.0); - - if (!(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) - voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; - - if (reverse_cull) - sign = !sign; - - if (cull_sign && sign) - return; - if (!cull_sign && !sign) - return; - } - - voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); - voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); - voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff); - voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff); - voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff); - voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); - - if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) - fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); - - if (voodoo->sSetupMode & SETUPMODE_RGB) - { - voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f); - voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); - voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); - voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f); - voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); - voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); - voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f); - voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); - voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_ALPHA) - { - voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f); - voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); - voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Z) - { - voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f); - voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); - voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Wb) - { - voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f); - voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); - voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; - voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; - voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_W0) - { - voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f); - voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; - voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; - voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_S0_T0) - { - voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f); - voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f); - voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; - voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; - voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; - voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; - voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; - voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; - } - if (voodoo->sSetupMode & SETUPMODE_W1) - { - voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f); - voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); - } - if (voodoo->sSetupMode & SETUPMODE_S1_T1) - { - voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f); - voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f); - voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); - } - - voodoo->params.sign = (area < 0.0); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - queue_triangle(voodoo, &voodoo->params); -} - -enum -{ - BLIT_COMMAND_SCREEN_TO_SCREEN = 0, - BLIT_COMMAND_CPU_TO_SCREEN = 1, - BLIT_COMMAND_RECT_FILL = 2, - BLIT_COMMAND_SGRAM_FILL = 3 -}; - -enum -{ - BLIT_SRC_1BPP = (0 << 3), - BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), - BLIT_SRC_16BPP = (2 << 3), - BLIT_SRC_24BPP = (3 << 3), - BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), - BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) -}; - -enum -{ - BLIT_SRC_RGB_ARGB = (0 << 6), - BLIT_SRC_RGB_ABGR = (1 << 6), - BLIT_SRC_RGB_RGBA = (2 << 6), - BLIT_SRC_RGB_BGRA = (3 << 6) -}; - -enum -{ - BLIT_COMMAND_MASK = 7, - BLIT_SRC_FORMAT = (7 << 3), - BLIT_SRC_RGB_FORMAT = (3 << 6), - BLIT_SRC_CHROMA = (1 << 10), - BLIT_DST_CHROMA = (1 << 12), - BLIT_CLIPPING_ENABLED = (1 << 16) -}; - -enum -{ - BLIT_ROP_DST_PASS = (1 << 0), - BLIT_ROP_SRC_PASS = (1 << 1) -}; - -#define MIX(src_dat, dst_dat, rop) \ - switch (rop) \ - { \ - case 0x0: dst_dat = 0; break; \ - case 0x1: dst_dat = ~(src_dat | dst_dat); break; \ - case 0x2: dst_dat = ~src_dat & dst_dat; break; \ - case 0x3: dst_dat = ~src_dat; break; \ - case 0x4: dst_dat = src_dat & ~dst_dat; break; \ - case 0x5: dst_dat = ~dst_dat; break; \ - case 0x6: dst_dat = src_dat ^ dst_dat; break; \ - case 0x7: dst_dat = ~(src_dat & dst_dat); break; \ - case 0x8: dst_dat = src_dat & dst_dat; break; \ - case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \ - case 0xa: dst_dat = dst_dat; break; \ - case 0xb: dst_dat = ~src_dat | dst_dat; break; \ - case 0xc: dst_dat = src_dat; break; \ - case 0xd: dst_dat = src_dat | ~dst_dat; break; \ - case 0xe: dst_dat = src_dat | dst_dat; break; \ - case 0xf: dst_dat = 0xffff; break; \ - } - -static void blit_start(voodoo_t *voodoo) -{ - uint64_t dat64; - int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); - int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; - int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; - int dst_x; - int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; - int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8); - int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); - uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); - uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - int x, y; - -/* pclog("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", - voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ - - wait_for_render_thread_idle(voodoo); - - switch (voodoo->bltCommand & BLIT_COMMAND_MASK) - { - case BLIT_COMMAND_SCREEN_TO_SCREEN: - for (y = 0; y <= size_y; y++) - { - uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y*src_stride]; - uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; - int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; - - for (x = 0; x <= size_x; x++) - { - uint16_t src_dat = src[src_x]; - uint16_t dst_dat = dst[dst_x]; - int rop = 0; - - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_blit; - } - - if (voodoo->bltCommand & BLIT_SRC_CHROMA) - { - int r = (src_dat >> 11); - int g = (src_dat >> 5) & 0x3f; - int b = src_dat & 0x1f; - - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) - { - int r = (dst_dat >> 11); - int g = (dst_dat >> 5) & 0x3f; - int b = dst_dat & 0x1f; - - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } - - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - - dst[dst_x] = dst_dat; -skip_pixel_blit: - src_x += x_dir; - dst_x += x_dir; - } - - src_y += y_dir; - dst_y += y_dir; - } - break; - - case BLIT_COMMAND_CPU_TO_SCREEN: - voodoo->blt.dst_x = voodoo->bltDstX; - voodoo->blt.dst_y = voodoo->bltDstY; - voodoo->blt.cur_x = 0; - voodoo->blt.size_x = size_x; - voodoo->blt.size_y = size_y; - voodoo->blt.x_dir = x_dir; - voodoo->blt.y_dir = y_dir; - voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); - break; - - case BLIT_COMMAND_RECT_FILL: - for (y = 0; y <= size_y; y++) - { - uint16_t *dst; - int dst_x = voodoo->bltDstX; - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_line_fill; - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; - } - else - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; - - for (x = 0; x <= size_x; x++) - { - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_fill; - } - - dst[dst_x] = voodoo->bltColorFg; -skip_pixel_fill: - dst_x += x_dir; - } -skip_line_fill: - dst_y += y_dir; - } - break; - - case BLIT_COMMAND_SGRAM_FILL: - /*32x32 tiles - 2kb*/ - dst_y = voodoo->bltDstY & 0x3ff; - size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb - size_y = voodoo->bltSizeY & 0x3ff; - - dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | - ((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48); - - for (y = 0; y <= size_y; y++) - { - uint64_t *dst; - - /*This may be wrong*/ - if (!y) - { - dst_x = voodoo->bltDstX & 0x1ff; - size_x = 511 - dst_x; - } - else if (y < size_y) - { - dst_x = 0; - size_x = 511; - } - else - { - dst_x = 0; - size_x = voodoo->bltSizeX & 0x1ff; - } - - dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask]; - - for (x = 0; x <= size_x; x++) - dst[x] = dat64; - - dst_y++; - } - break; - - default: - fatal("bad blit command %08x\n", voodoo->bltCommand); - } -} - -static void blit_data(voodoo_t *voodoo, uint32_t data) -{ - int src_bits = 32; - uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - uint32_t addr; - uint16_t *dst; - - if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) - return; - - if (SLI_ENABLED) - { - addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } - else - { - addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } - - if (addr >= voodoo->front_offset && voodoo->row_width) - { - int y = (addr - voodoo->front_offset) / voodoo->row_width; - if (y < voodoo->v_disp) - voodoo->dirty_line[y] = 2; - } - - while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) - { - int r = 0, g = 0, b = 0; - uint16_t src_dat = 0, dst_dat; - int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); - int rop = 0; - - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) - { - case BLIT_SRC_1BPP: case BLIT_SRC_1BPP_BYTE_PACKED: - src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; - data >>= 1; - src_bits--; - break; - case BLIT_SRC_16BPP: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) - { - case BLIT_SRC_RGB_ARGB: case BLIT_SRC_RGB_RGBA: - src_dat = data & 0xffff; - break; - case BLIT_SRC_RGB_ABGR: case BLIT_SRC_RGB_BGRA: - src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); - break; - } - data >>= 16; - src_bits -= 16; - break; - case BLIT_SRC_24BPP: case BLIT_SRC_24BPP_DITHER_2X2: case BLIT_SRC_24BPP_DITHER_4X4: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) - { - case BLIT_SRC_RGB_ARGB: - r = (data >> 16) & 0xff; - g = (data >> 8) & 0xff; - b = data & 0xff; - break; - case BLIT_SRC_RGB_ABGR: - r = data & 0xff; - g = (data >> 8) & 0xff; - b = (data >> 16) & 0xff; - break; - case BLIT_SRC_RGB_RGBA: - r = (data >> 24) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 8) & 0xff; - break; - case BLIT_SRC_RGB_BGRA: - r = (data >> 8) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 24) & 0xff; - break; - } - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) - { - case BLIT_SRC_24BPP: - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_2X2: - r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; - g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; - b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_4X4: - r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; - g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; - b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - } - src_bits = 0; - break; - } - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_pixel; - } - - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || - voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) - goto skip_pixel; - } - - dst_dat = dst[x]; - - if (voodoo->bltCommand & BLIT_SRC_CHROMA) - { - r = (src_dat >> 11); - g = (src_dat >> 5) & 0x3f; - b = src_dat & 0x1f; - - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) - { - r = (dst_dat >> 11); - g = (dst_dat >> 5) & 0x3f; - b = dst_dat & 0x1f; - - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } - - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - - dst[x] = dst_dat; - -skip_pixel: - voodoo->blt.cur_x++; - } - - if (voodoo->blt.cur_x > voodoo->blt.size_x) - { - voodoo->blt.size_y--; - if (voodoo->blt.size_y >= 0) - { - voodoo->blt.cur_x = 0; - voodoo->blt.dst_y += voodoo->blt.y_dir; - } - } -} - -enum -{ - CHIP_FBI = 0x1, - CHIP_TREX0 = 0x2, - CHIP_TREX1 = 0x4, - CHIP_TREX2 = 0x8 -}; - -static void wait_for_swap_complete(voodoo_t *voodoo) -{ - while (voodoo->swap_pending) - { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) - { - /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ - memset(voodoo->dirty_line, 1, 1024); - voodoo->front_offset = voodoo->params.front_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - break; - } - } -} - -static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - union - { - uint32_t i; - float f; - } tempif; - int ad21 = addr & (1 << 21); - int chip = (addr >> 10) & 0xf; - if (!chip) - chip = 0xf; - - tempif.i = val; -//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) - addr |= 0x400; - switch (addr) - { - case SST_swapbufferCMD: -// pclog(" start swap buffer command\n"); - - if (TRIPLE_BUFFER) - { - voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; - voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; - } - else - { - voodoo->disp_buffer = !voodoo->disp_buffer; - voodoo->draw_buffer = !voodoo->draw_buffer; - } - voodoo_recalc(voodoo); - - voodoo->params.swapbufferCMD = val; - - pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); -// voodoo->front_offset = params->front_offset; - wait_for_render_thread_idle(voodoo); - if (!(val & 1)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->front_offset = voodoo->params.front_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - } - else if (TRIPLE_BUFFER) - { - if (voodoo->swap_pending) - wait_for_swap_complete(voodoo); - - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - } - else - { - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - - wait_for_swap_complete(voodoo); - } - voodoo->cmd_read++; - break; - - case SST_vertexAx: case SST_remap_vertexAx: - voodoo->params.vertexAx = val & 0xffff; - break; - case SST_vertexAy: case SST_remap_vertexAy: - voodoo->params.vertexAy = val & 0xffff; - break; - case SST_vertexBx: case SST_remap_vertexBx: - voodoo->params.vertexBx = val & 0xffff; - break; - case SST_vertexBy: case SST_remap_vertexBy: - voodoo->params.vertexBy = val & 0xffff; - break; - case SST_vertexCx: case SST_remap_vertexCx: - voodoo->params.vertexCx = val & 0xffff; - break; - case SST_vertexCy: case SST_remap_vertexCy: - voodoo->params.vertexCy = val & 0xffff; - break; - - case SST_startR: case SST_remap_startR: - voodoo->params.startR = val & 0xffffff; - break; - case SST_startG: case SST_remap_startG: - voodoo->params.startG = val & 0xffffff; - break; - case SST_startB: case SST_remap_startB: - voodoo->params.startB = val & 0xffffff; - break; - case SST_startZ: case SST_remap_startZ: - voodoo->params.startZ = val; - break; - case SST_startA: case SST_remap_startA: - voodoo->params.startA = val & 0xffffff; - break; - case SST_startS: case SST_remap_startS: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = ((int64_t)(int32_t)val) << 14; - break; - case SST_startT: case SST_remap_startT: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = ((int64_t)(int32_t)val) << 14; - break; - case SST_startW: case SST_remap_startW: - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(int32_t)val << 2; - break; - - case SST_dRdX: case SST_remap_dRdX: - voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdX: case SST_remap_dGdX: - voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdX: case SST_remap_dBdX: - voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdX: case SST_remap_dZdX: - voodoo->params.dZdX = val; - break; - case SST_dAdX: case SST_remap_dAdX: - voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdX: case SST_remap_dSdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdX: case SST_remap_dTdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdX: case SST_remap_dWdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(int32_t)val << 2; - break; - - case SST_dRdY: case SST_remap_dRdY: - voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdY: case SST_remap_dGdY: - voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdY: case SST_remap_dBdY: - voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdY: case SST_remap_dZdY: - voodoo->params.dZdY = val; - break; - case SST_dAdY: case SST_remap_dAdY: - voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdY: case SST_remap_dSdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdY: case SST_remap_dTdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdY: case SST_remap_dWdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(int32_t)val << 2; - break; - - case SST_triangleCMD: case SST_remap_triangleCMD: - voodoo->params.sign = val & (1 << 31); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - queue_triangle(voodoo, &voodoo->params); - - voodoo->cmd_read++; - break; - - case SST_fvertexAx: case SST_remap_fvertexAx: - voodoo->fvertexAx.i = val; - voodoo->params.vertexAx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAx.f * 16.0f) & 0xffff; - break; - case SST_fvertexAy: case SST_remap_fvertexAy: - voodoo->fvertexAy.i = val; - voodoo->params.vertexAy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAy.f * 16.0f) & 0xffff; - break; - case SST_fvertexBx: case SST_remap_fvertexBx: - voodoo->fvertexBx.i = val; - voodoo->params.vertexBx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBx.f * 16.0f) & 0xffff; - break; - case SST_fvertexBy: case SST_remap_fvertexBy: - voodoo->fvertexBy.i = val; - voodoo->params.vertexBy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBy.f * 16.0f) & 0xffff; - break; - case SST_fvertexCx: case SST_remap_fvertexCx: - voodoo->fvertexCx.i = val; - voodoo->params.vertexCx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCx.f * 16.0f) & 0xffff; - break; - case SST_fvertexCy: case SST_remap_fvertexCy: - voodoo->fvertexCy.i = val; - voodoo->params.vertexCy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCy.f * 16.0f) & 0xffff; - break; - - case SST_fstartR: case SST_remap_fstartR: - tempif.i = val; - voodoo->params.startR = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartG: case SST_remap_fstartG: - tempif.i = val; - voodoo->params.startG = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartB: case SST_remap_fstartB: - tempif.i = val; - voodoo->params.startB = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartZ: case SST_remap_fstartZ: - tempif.i = val; - voodoo->params.startZ = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartA: case SST_remap_fstartA: - tempif.i = val; - voodoo->params.startA = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartS: case SST_remap_fstartS: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartT: case SST_remap_fstartT: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartW: case SST_remap_fstartW: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(tempif.f * 4294967296.0f); - break; - - case SST_fdRdX: case SST_remap_fdRdX: - tempif.i = val; - voodoo->params.dRdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdX: case SST_remap_fdGdX: - tempif.i = val; - voodoo->params.dGdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdX: case SST_remap_fdBdX: - tempif.i = val; - voodoo->params.dBdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdX: case SST_remap_fdZdX: - tempif.i = val; - voodoo->params.dZdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdX: case SST_remap_fdAdX: - tempif.i = val; - voodoo->params.dAdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdX: case SST_remap_fdSdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdX: case SST_remap_fdTdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdX: case SST_remap_fdWdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(tempif.f * 4294967296.0f); - break; - - case SST_fdRdY: case SST_remap_fdRdY: - tempif.i = val; - voodoo->params.dRdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdY: case SST_remap_fdGdY: - tempif.i = val; - voodoo->params.dGdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdY: case SST_remap_fdBdY: - tempif.i = val; - voodoo->params.dBdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdY: case SST_remap_fdZdY: - tempif.i = val; - voodoo->params.dZdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdY: case SST_remap_fdAdY: - tempif.i = val; - voodoo->params.dAdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdY: case SST_remap_fdSdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdY: case SST_remap_fdTdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdY: case SST_remap_fdWdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(tempif.f * 4294967296.0f); - break; - - case SST_ftriangleCMD: - voodoo->params.sign = val & (1 << 31); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - queue_triangle(voodoo, &voodoo->params); - - voodoo->cmd_read++; - break; - - case SST_fbzColorPath: - voodoo->params.fbzColorPath = val; - voodoo->rgb_sel = val & 3; - break; - - case SST_fogMode: - voodoo->params.fogMode = val; - break; - case SST_alphaMode: - voodoo->params.alphaMode = val; - break; - case SST_fbzMode: - voodoo->params.fbzMode = val; - voodoo_recalc(voodoo); - break; - case SST_lfbMode: - voodoo->lfbMode = val; - voodoo_recalc(voodoo); - break; - - case SST_clipLeftRight: - if (voodoo->type >= VOODOO_2) - { - voodoo->params.clipRight = val & 0xfff; - voodoo->params.clipLeft = (val >> 16) & 0xfff; - } - else - { - voodoo->params.clipRight = val & 0x3ff; - voodoo->params.clipLeft = (val >> 16) & 0x3ff; - } - break; - case SST_clipLowYHighY: - if (voodoo->type >= VOODOO_2) - { - voodoo->params.clipHighY = val & 0xfff; - voodoo->params.clipLowY = (val >> 16) & 0xfff; - } - else - { - voodoo->params.clipHighY = val & 0x3ff; - voodoo->params.clipLowY = (val >> 16) & 0x3ff; - } - break; - - case SST_nopCMD: - voodoo->cmd_read++; - voodoo->fbiPixelsIn = 0; - voodoo->fbiChromaFail = 0; - voodoo->fbiZFuncFail = 0; - voodoo->fbiAFuncFail = 0; - voodoo->fbiPixelsOut = 0; - break; - case SST_fastfillCMD: - wait_for_render_thread_idle(voodoo); - voodoo_fastfill(voodoo, &voodoo->params); - voodoo->cmd_read++; - break; - - case SST_fogColor: - voodoo->params.fogColor.r = (val >> 16) & 0xff; - voodoo->params.fogColor.g = (val >> 8) & 0xff; - voodoo->params.fogColor.b = val & 0xff; - break; - - case SST_zaColor: - voodoo->params.zaColor = val; - break; - case SST_chromaKey: - voodoo->params.chromaKey_r = (val >> 16) & 0xff; - voodoo->params.chromaKey_g = (val >> 8) & 0xff; - voodoo->params.chromaKey_b = val & 0xff; - voodoo->params.chromaKey = val & 0xffffff; - break; - case SST_stipple: - voodoo->params.stipple = val; - break; - case SST_color0: - voodoo->params.color0 = val; - break; - case SST_color1: - voodoo->params.color1 = val; - break; - - case SST_fogTable00: case SST_fogTable01: case SST_fogTable02: case SST_fogTable03: - case SST_fogTable04: case SST_fogTable05: case SST_fogTable06: case SST_fogTable07: - case SST_fogTable08: case SST_fogTable09: case SST_fogTable0a: case SST_fogTable0b: - case SST_fogTable0c: case SST_fogTable0d: case SST_fogTable0e: case SST_fogTable0f: - case SST_fogTable10: case SST_fogTable11: case SST_fogTable12: case SST_fogTable13: - case SST_fogTable14: case SST_fogTable15: case SST_fogTable16: case SST_fogTable17: - case SST_fogTable18: case SST_fogTable19: case SST_fogTable1a: case SST_fogTable1b: - case SST_fogTable1c: case SST_fogTable1d: case SST_fogTable1e: case SST_fogTable1f: - addr = (addr - SST_fogTable00) >> 1; - voodoo->params.fogTable[addr].dfog = val & 0xff; - voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; - voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; - voodoo->params.fogTable[addr+1].fog = (val >> 24) & 0xff; - break; - - case SST_clutData: - voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) - { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; - } - voodoo->clutData_dirty = 1; - break; - - case SST_sSetupMode: - voodoo->sSetupMode = val; - break; - case SST_sVx: - tempif.i = val; - voodoo->verts[3].sVx = tempif.f; -// 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); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - break; - case SST_sRed: - tempif.i = val; - voodoo->verts[3].sRed = tempif.f; - break; - case SST_sGreen: - tempif.i = val; - voodoo->verts[3].sGreen = tempif.f; - break; - case SST_sBlue: - tempif.i = val; - voodoo->verts[3].sBlue = tempif.f; - break; - case SST_sAlpha: - tempif.i = val; - voodoo->verts[3].sAlpha = tempif.f; - break; - case SST_sVz: - tempif.i = val; - voodoo->verts[3].sVz = tempif.f; - break; - case SST_sWb: - tempif.i = val; - voodoo->verts[3].sWb = tempif.f; - break; - case SST_sW0: - tempif.i = val; - voodoo->verts[3].sW0 = tempif.f; - break; - case SST_sS0: - tempif.i = val; - voodoo->verts[3].sS0 = tempif.f; - break; - case SST_sT0: - tempif.i = val; - voodoo->verts[3].sT0 = tempif.f; - break; - case SST_sW1: - tempif.i = val; - voodoo->verts[3].sW1 = tempif.f; - break; - case SST_sS1: - tempif.i = val; - voodoo->verts[3].sS1 = tempif.f; - break; - case SST_sT1: - tempif.i = val; - voodoo->verts[3].sT1 = tempif.f; - break; - - case SST_sBeginTriCMD: -// 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]; - - voodoo->num_verticies++; - voodoo->vertex_num++; - if (voodoo->num_verticies == 3) - { -// pclog("triangle_setup\n"); - triangle_setup(voodoo); - - voodoo->num_verticies = 2; - } - if (voodoo->vertex_num == 4) - fatal("sDrawTriCMD overflow\n"); - break; - - case SST_bltSrcBaseAddr: - voodoo->bltSrcBaseAddr = val & 0x3fffff; - break; - case SST_bltDstBaseAddr: -// 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; - voodoo->bltSrcChromaMinB = val & 0x1f; - voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; - voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; - voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltDstChromaRange: - voodoo->bltDstChromaRange = val; - voodoo->bltDstChromaMinB = val & 0x1f; - voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; - voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; - voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltClipX: - voodoo->bltClipRight = val & 0xfff; - voodoo->bltClipLeft = (val >> 16) & 0xfff; - break; - case SST_bltClipY: - voodoo->bltClipHighY = val & 0xfff; - voodoo->bltClipLowY = (val >> 16) & 0xfff; - break; - - case SST_bltSrcXY: - voodoo->bltSrcX = val & 0x7ff; - voodoo->bltSrcY = (val >> 16) & 0x7ff; - break; - case SST_bltDstXY: -// 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; - voodoo->bltSizeY = (val >> 16) & 0xfff; - if (voodoo->bltSizeY & 0x800) - voodoo->bltSizeY |= 0xfffff000; - if (val & (1 << 31)) - blit_start(voodoo); - break; - case SST_bltRop: - voodoo->bltRop[0] = val & 0xf; - voodoo->bltRop[1] = (val >> 4) & 0xf; - voodoo->bltRop[2] = (val >> 8) & 0xf; - voodoo->bltRop[3] = (val >> 12) & 0xf; - break; - case SST_bltColor: -// 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; - case SST_bltData: - blit_data(voodoo, val); - break; - - case SST_textureMode: - if (chip & CHIP_TREX0) - { - voodoo->params.textureMode[0] = val; - voodoo->params.tformat[0] = (val >> 8) & 0xf; - } - if (chip & CHIP_TREX1) - { - voodoo->params.textureMode[1] = val; - voodoo->params.tformat[1] = (val >> 8) & 0xf; - } - break; - case SST_tLOD: - if (chip & CHIP_TREX0) - { - voodoo->params.tLOD[0] = val; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.tLOD[1] = val; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_tDetail: - if (chip & CHIP_TREX0) - { - voodoo->params.detail_max[0] = val & 0xff; - voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[0] = (val >> 14) & 7; - } - if (chip & CHIP_TREX1) - { - voodoo->params.detail_max[1] = val & 0xff; - voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[1] = (val >> 14) & 7; - } - break; - case SST_texBaseAddr: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr1: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr2: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr38: - if (chip & CHIP_TREX0) - { - voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - - case SST_trexInit1: - if (chip & CHIP_TREX0) - voodoo->trexInit1[0] = val; - if (chip & CHIP_TREX1) - voodoo->trexInit1[1] = val; - break; - - case SST_nccTable0_Y0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - - case SST_nccTable0_I0: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I2: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q0: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q2: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) - { - int p = (val >> 23) & 0xfe; - if (chip & CHIP_TREX0) - { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; - - case SST_nccTable0_I1: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I3: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q1: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q3: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) - { - int p = ((val >> 23) & 0xfe) | 0x01; - if (chip & CHIP_TREX0) - { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; - - case SST_nccTable1_Y0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - - case SST_userIntrCMD: - fatal("userIntrCMD write %08x from FIFO\n", val); - break; - } -} - - -static uint16_t voodoo_fb_readw(uint32_t addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint16_t temp; - - x = (addr >> 1) & 0x3ff; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - - y >>= 1; - } - - read_addr = voodoo->fb_read_offset + (x << 1) + (y * voodoo->row_width); - - if (read_addr > voodoo->fb_mask) - return 0xffff; - - temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - -// 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) -{ - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint32_t temp; - - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - - y >>= 1; - } - - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); - - if (read_addr > voodoo->fb_mask) - return 0xffffffff; - - temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - -// 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) -{ - int r, g, b; - - if (dither) - { - if (dither2x2) - { - r = dither_rb2x2[col.r][y & 1][x & 1]; - g = dither_g2x2[col.g][y & 1][x & 1]; - b = dither_rb2x2[col.b][y & 1][x & 1]; - } - else - { - r = dither_rb[col.r][y & 3][x & 3]; - g = dither_g[col.g][y & 3][x & 3]; - b = dither_rb[col.b][y & 3][x & 3]; - } - } - else - { - r = col.r >> 3; - g = col.g >> 2; - b = col.b >> 3; - } - - return b | (g << 5) | (r << 11); -} - -static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data; - uint16_t depth_data; - uint8_t alpha_data; - int write_mask = 0; - - colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; - - depth_data = voodoo->params.zaColor & 0xffff; - alpha_data = voodoo->params.zaColor >> 24; - -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); - -// pclog("voodoo_fb_writew : %08X %04X\n", addr, val); - - - switch (voodoo->lfbMode & LFB_FORMAT_MASK) - { - case LFB_FORMAT_RGB565: - colour_data = rgb565[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_RGB555: - colour_data = argb1555[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_ARGB1555: - colour_data = argb1555[val]; - alpha_data = colour_data.a; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_DEPTH: - depth_data = val; - write_mask = LFB_WRITE_DEPTH; - break; - - default: - fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); - } - - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } - - - if (voodoo->fb_write_offset == voodoo->params.front_offset) - voodoo->dirty_line[y] = 1; - - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - -// pclog("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); - - if (voodoo->lfbMode & 0x100) - { - { - rgba8_t write_data = colour_data; - uint16_t new_depth = depth_data; - - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - - DEPTH_TEST(new_depth); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; - - if (params->fogMode & FOG_ENABLE) - { - int32_t z = new_depth << 12; - int64_t w_depth = (int64_t)(int32_t)new_depth; - int32_t ia = alpha_data << 12; - - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } - - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data); - - if (params->alphaMode & (1 << 4)) - { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; - - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); - } - - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - -skip_pixel: - x = x; - } - } - else - { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; - } -} - - -static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data[2]; - uint16_t depth_data[2]; - uint8_t alpha_data[2]; - int write_mask = 0, count = 1; - - depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; - alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); - -// pclog("voodoo_fb_writel : %08X %08X\n", addr, val); - - switch (voodoo->lfbMode & LFB_FORMAT_MASK) - { - case LFB_FORMAT_RGB565: - colour_data[0] = rgb565[val & 0xffff]; - colour_data[1] = rgb565[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_RGB555: - colour_data[0] = argb1555[val & 0xffff]; - colour_data[1] = argb1555[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_ARGB1555: - colour_data[0] = argb1555[val & 0xffff]; - alpha_data[0] = colour_data[0].a; - colour_data[1] = argb1555[val >> 16]; - alpha_data[1] = colour_data[1].a; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - - case LFB_FORMAT_ARGB8888: - colour_data[0].b = val & 0xff; - colour_data[0].g = (val >> 8) & 0xff; - colour_data[0].r = (val >> 16) & 0xff; - alpha_data[0] = (val >> 24) & 0xff; - write_mask = LFB_WRITE_COLOUR; - addr >>= 1; - break; - - case LFB_FORMAT_DEPTH: - depth_data[0] = val; - depth_data[1] = val >> 16; - write_mask = LFB_WRITE_DEPTH; - count = 2; - break; - - default: - fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); - } - - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } - - if (voodoo->fb_write_offset == voodoo->params.front_offset) - voodoo->dirty_line[y] = 1; - - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - -// 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) - { - int c; - - for (c = 0; c < count; c++) - { - rgba8_t write_data = colour_data[c]; - uint16_t new_depth = depth_data[c]; - - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - - DEPTH_TEST(new_depth); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; - - if (params->fogMode & FOG_ENABLE) - { - int32_t z = new_depth << 12; - int64_t w_depth = new_depth; - int32_t ia = alpha_data[c] << 12; - - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } - - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data[c]); - - if (params->alphaMode & (1 << 4)) - { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; - - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); - } - - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - -skip_pixel: - write_addr += 2; - write_addr_aux += 2; - } - } - else - { - int c; - - for (c = 0; c < count; c++) - { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; - - write_addr += 2; - write_addr_aux += 2; - } - } -} - -static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) -{ - int lod, s, t; - voodoo_t *voodoo = (voodoo_t *)p; - int tmu; - - if (addr & 0x400000) - return; /*TREX != 0*/ - - tmu = (addr & 0x200000) ? 1 : 0; - - if (tmu && !voodoo->dual_tmus) - return; - -// 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) - s = (addr >> 1) & 0xfe; - else - { - if (voodoo->params.textureMode[tmu] & (1 << 31)) - s = addr & 0xfc; - else - s = (addr >> 1) & 0xfc; - } - - if (lod > LOD_MAX) - return; - -// if (addr >= 0x200000) -// return; - - if (voodoo->params.tformat[tmu] & 8) - addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; - else - addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); - if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) - { -// 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) -{ - if (!timer_is_enabled(&voodoo->wake_timer)) - { - /*Don't wake FIFO thread immediately - if we do that it will probably - process one word and go back to sleep, requiring it to be woken on - almost every write. Instead, wait a short while so that the CPU - emulation writes more data so we have more batched-up work.*/ - timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); - } -} - -static inline void wake_fifo_thread_now(voodoo_t *voodoo) -{ - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static void voodoo_wake_timer(void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ -} - -static inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) -{ - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; - - while (FIFO_FULL) - { - thread_reset_event(voodoo->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ - if (FIFO_FULL) - wake_fifo_thread_now(voodoo); - } - } - - fifo->val = val; - fifo->addr_type = addr_type; - - voodoo->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000) - wake_fifo_thread(voodoo); -} static uint16_t voodoo_readw(uint32_t addr, void *p) { @@ -5939,10 +127,10 @@ static uint16_t voodoo_readw(uint32_t addr, void *p) voodoo->flush = 1; while (!FIFO_EMPTY) { - wake_fifo_thread_now(voodoo); + voodoo_wake_fifo_thread_now(voodoo); thread_wait_event(voodoo->fifo_not_full_event, 1); } - wait_for_render_thread_idle(voodoo); + voodoo_wait_for_render_thread_idle(voodoo); voodoo->flush = 0; return voodoo_fb_readw(addr, voodoo); @@ -5951,24 +139,6 @@ 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 void wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) -{ - wake_fifo_thread(voodoo); - if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) - wake_fifo_thread(set->voodoos[1]); -} static uint32_t voodoo_readl(uint32_t addr, void *p) { @@ -5999,10 +169,10 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) voodoo->flush = 1; while (!FIFO_EMPTY) { - wake_fifo_thread_now(voodoo); + voodoo_wake_fifo_thread_now(voodoo); thread_wait_event(voodoo->fifo_not_full_event, 1); } - wait_for_render_thread_idle(voodoo); + voodoo_wait_for_render_thread_idle(voodoo); voodoo->flush = 0; temp = voodoo_fb_readl(addr, voodoo); @@ -6029,7 +199,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) busy = 1; if (!voodoo_other->voodoo_busy) - wake_fifo_thread(voodoo_other); + voodoo_wake_fifo_thread(voodoo_other); } fifo_size = 0xffff - fifo_entries; @@ -6049,7 +219,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) temp |= 0x380; /*Busy*/ if (!voodoo->voodoo_busy) - wake_fifo_thread(voodoo); + voodoo_wake_fifo_thread(voodoo); } break; @@ -6194,31 +364,7 @@ static void voodoo_writew(uint32_t addr, uint16_t val, void *p) cycles -= voodoo->write_time; if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - queue_command(voodoo, addr | FIFO_WRITEW_FB, val); -} - -static void voodoo_pixelclock_update(voodoo_t *voodoo) -{ - int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; - int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; - int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); - float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - double clock_const; - int line_length; - - if ((voodoo->dac_data[6] & 0xf0) == 0x20 || - (voodoo->dac_data[6] & 0xf0) == 0x60 || - (voodoo->dac_data[6] & 0xf0) == 0x70) - t /= 2.0f; - - line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); - -// pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); - - voodoo->pixel_clock = t; - - clock_const = cpuclock / t; - voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32)); + voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val); } static void voodoo_writel(uint32_t addr, uint32_t val, void *p) @@ -6238,11 +384,11 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) if (addr & 0x800000) /*Texture*/ { voodoo->tex_count++; - queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); } else if (addr & 0x400000) /*Framebuffer*/ { - queue_command(voodoo, addr | FIFO_WRITEL_FB, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { @@ -6250,7 +396,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; voodoo->cmdfifo_depth_wr++; if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) - wake_fifo_thread(voodoo); + voodoo_wake_fifo_thread(voodoo); } else switch (addr & 0x3fc) { @@ -6267,41 +413,41 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->swap_count++; if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) return; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; case SST_triangleCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) return; voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; case SST_ftriangleCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) return; voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; case SST_fastfillCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) return; voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; case SST_nopCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) return; voodoo->cmd_written++; - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; case SST_fbiInit4: @@ -6483,7 +629,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) } else { - queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); } break; } @@ -6517,296 +663,6 @@ static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) voodoo_writel(addr, val, set->voodoos[1]); } -static uint32_t cmdfifo_get(voodoo_t *voodoo) -{ - uint32_t val; - - while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) - { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - } - - val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; - - voodoo->cmdfifo_depth_rd++; - voodoo->cmdfifo_rp += 4; - -// pclog(" CMDFIFO get %08x\n", val); - return val; -} - -static inline float cmdfifo_get_f(voodoo_t *voodoo) -{ - union - { - uint32_t i; - float f; - } tempif; - - tempif.i = cmdfifo_get(voodoo); - return tempif.f; -} - -enum -{ - CMDFIFO3_PC_MASK_RGB = (1 << 10), - CMDFIFO3_PC_MASK_ALPHA = (1 << 11), - CMDFIFO3_PC_MASK_Z = (1 << 12), - CMDFIFO3_PC_MASK_Wb = (1 << 13), - CMDFIFO3_PC_MASK_W0 = (1 << 14), - CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), - CMDFIFO3_PC_MASK_W1 = (1 << 16), - CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), - - CMDFIFO3_PC = (1 << 28) -}; - -static void fifo_thread(void *param) -{ - voodoo_t *voodoo = (voodoo_t *)param; - - while (1) - { - thread_set_event(voodoo->fifo_not_full_event); - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - voodoo->voodoo_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITEL_REG: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) - { - voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEW_FB: - wait_for_render_thread_idle(voodoo); - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) - { - voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_FB: - wait_for_render_thread_idle(voodoo); - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) - { - voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_TEX: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) - { - if (!(fifo->addr_type & 0x400000)) - voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - } - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(voodoo->fifo_not_full_event); - - end_time = timer_read(); - voodoo->time += end_time - start_time; - } - - while (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) - { - uint64_t start_time = timer_read(); - uint64_t end_time; - uint32_t header = cmdfifo_get(voodoo); - uint32_t addr; - uint32_t mask; - int smode; - int num; - int num_verticies; - int v_num; - -// 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*/ - break; - - case 3: /*JMP local frame buffer*/ - voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; -// pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); - break; - - default: - fatal("Bad CMDFIFO0 %08x\n", header); - } - break; - - case 1: - num = header >> 16; - addr = (header & 0x7ff8) >> 1; -// pclog("CMDFIFO1 addr=%08x\n",addr); - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - - voodoo_reg_writel(addr, val, voodoo); - - if (header & (1 << 15)) - addr += 4; - } - break; - - case 3: - num = (header >> 29) & 7; - mask = header;//(header >> 10) & 0xff; - smode = (header >> 22) & 0xf; - voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); - num_verticies = (header >> 6) & 0xf; - v_num = 0; - if (((header >> 3) & 7) == 2) - v_num = 1; -// 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--) - { - voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); - voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_RGB) - { - if (header & CMDFIFO3_PC) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - } - else - { - voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); - voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); - voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); - } - } - if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) - voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Z) - voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Wb) - voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_W0) - voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S0_T0) - { - voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); - } - if (mask & CMDFIFO3_PC_MASK_W1) - voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S1_T1) - { - voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); - } - if (v_num) - voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); - else - voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); - v_num++; - if (v_num == 3 && ((header >> 3) & 7) == 0) - v_num = 0; - } - break; - - case 4: - num = (header >> 29) & 7; - mask = (header >> 15) & 0x3fff; - addr = (header & 0x7ff8) >> 1; -// pclog("CMDFIFO4 addr=%08x\n",addr); - while (mask) - { - if (mask & 1) - { - uint32_t val = cmdfifo_get(voodoo); - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - - voodoo_reg_writel(addr, val, voodoo); - } - - addr += 4; - mask >>= 1; - } - while (num--) - cmdfifo_get(voodoo); - break; - - case 5: - if (header & 0x3fc0000) - fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); - num = (header >> 3) & 0x7ffff; - addr = cmdfifo_get(voodoo) & 0xffffff; -// pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); - switch (header >> 30) - { - case 2: /*Framebuffer*/ - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo_fb_writel(addr, val, voodoo); - addr += 4; - } - break; - case 3: /*Texture*/ - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo_tex_writel(addr, val, voodoo); - addr += 4; - } - break; - - default: - fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); - } - break; - - default: - pclog("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); - } - - end_time = timer_read(); - voodoo->time += end_time - start_time; - } - voodoo->voodoo_busy = 0; - } -} - static void voodoo_recalcmapping(voodoo_set_t *set) { if (set->nr_cards == 2) @@ -6953,529 +809,6 @@ void voodoo_pci_write(int func, int addr, uint8_t val, void *p) } } -static void voodoo_calc_clutData(voodoo_t *voodoo) -{ - int c; - - for (c = 0; c < 256; c++) - { - voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].r*(c & 7)) >> 3; - voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].g*(c & 7)) >> 3; - voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].b*(c & 7)) >> 3; - } - - for (c = 0; c < 65536; c++) - { - int r = (c >> 8) & 0xf8; - int g = (c >> 3) & 0xfc; - int b = (c << 3) & 0xf8; -// r |= (r >> 5); -// g |= (g >> 6); -// b |= (b >> 5); - - voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; - } -} - - - -#define FILTDIV 256 - -static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ - -static void voodoo_generate_filter_v1(voodoo_t *voodoo) -{ - int g, h; - float difference, diffg, diffb; - float thiscol, thiscolg, thiscolb, lined; - float fcr, fcg, fcb; - - fcr = FILTCAP * 5; - fcg = FILTCAPG * 6; - fcb = FILTCAPB * 5; - - for (g=0;g FILTCAP) - difference = FILTCAP; - if (difference < -FILTCAP) - difference = -FILTCAP; - - if (diffg > FILTCAPG) - diffg = FILTCAPG; - if (diffg < -FILTCAPG) - diffg = -FILTCAPG; - - if (diffb > FILTCAPB) - diffb = FILTCAPB; - if (diffb < -FILTCAPB) - diffb = -FILTCAPB; - - // hack - to make it not bleed onto black - //if (g == 0){ - //difference = diffg = diffb = 0; - //} - - if ((difference < fcr) || (-difference > -fcr)) - thiscol = g + (difference / 2); - if ((diffg < fcg) || (-diffg > -fcg)) - thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ - if ((diffb < fcb) || (-diffb > -fcb)) - thiscolb = g + (diffb / 2); - - if (thiscol < 0) - thiscol = 0; - if (thiscol > FILTDIV-1) - thiscol = FILTDIV-1; - - if (thiscolg < 0) - thiscolg = 0; - if (thiscolg > FILTDIV-1) - thiscolg = FILTDIV-1; - - if (thiscolb < 0) - thiscolb = 0; - if (thiscolb > FILTDIV-1) - thiscolb = FILTDIV-1; - - voodoo->thefilter[g][h] = thiscol; - voodoo->thefilterg[g][h] = thiscolg; - voodoo->thefilterb[g][h] = thiscolb; - } - - lined = g + 4; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][2] = lined; - - lined = g + 0; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][1] = lined; - } -} - -static void voodoo_generate_filter_v2(voodoo_t *voodoo) -{ - int g, h; - float difference; - float thiscol, thiscolg, thiscolb, lined; - float clr, clg, clb = 0; - float fcr, fcg, fcb = 0; - - // pre-clamping - - fcr = FILTCAP; - fcg = FILTCAPG; - fcb = FILTCAPB; - - if (fcr > 32) fcr = 32; - if (fcg > 32) fcg = 32; - if (fcb > 32) fcb = 32; - - for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into - { - for (h=0;h<256;h++) // pixel 2 - our main pixel - { - float avg; - float avgdiff; - - difference = (float)(g - h); - avg = (float)((g + g + g + g + h) / 5); - avgdiff = avg - (float)((g + h + h + h + h) / 5); - if (avgdiff < 0) avgdiff *= -1; - if (difference < 0) difference *= -1; - - thiscol = thiscolg = thiscolb = g; - - // try lighten - if (h > g) - { - clr = clg = clb = avgdiff; - - if (clr>fcr) clr=fcr; - if (clg>fcg) clg=fcg; - if (clb>fcb) clb=fcb; - - - thiscol = g + clr; - thiscolg = g + clg; - thiscolb = g + clb; - - if (thiscol>g+FILTCAP) - thiscol=g+FILTCAP; - if (thiscolg>g+FILTCAPG) - thiscolg=g+FILTCAPG; - if (thiscolb>g+FILTCAPB) - thiscolb=g+FILTCAPB; - - - if (thiscol>g+avgdiff) - thiscol=g+avgdiff; - if (thiscolg>g+avgdiff) - thiscolg=g+avgdiff; - if (thiscolb>g+avgdiff) - thiscolb=g+avgdiff; - - } - - if (difference > FILTCAP) - thiscol = g; - if (difference > FILTCAPG) - thiscolg = g; - if (difference > FILTCAPB) - thiscolb = g; - - // clamp - if (thiscol < 0) thiscol = 0; - if (thiscolg < 0) thiscolg = 0; - if (thiscolb < 0) thiscolb = 0; - - if (thiscol > 255) thiscol = 255; - if (thiscolg > 255) thiscolg = 255; - if (thiscolb > 255) thiscolb = 255; - - // add to the table - voodoo->thefilter[g][h] = (thiscol); - voodoo->thefilterg[g][h] = (thiscolg); - voodoo->thefilterb[g][h] = (thiscolb); - - // debug the ones that don't give us much of a difference - //if (difference < FILTCAP) - //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][0] = lined; - voodoo->purpleline[g][1] = 0; - voodoo->purpleline[g][2] = lined; - } -} - -static void voodoo_threshold_check(voodoo_t *voodoo) -{ - int r, g, b; - - if (!voodoo->scrfilterEnabled) - return; /* considered disabled; don't check and generate */ - - /* Check for changes, to generate anew table */ - if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) - { - r = (voodoo->scrfilterThreshold >> 16) & 0xFF; - g = (voodoo->scrfilterThreshold >> 8 ) & 0xFF; - b = voodoo->scrfilterThreshold & 0xFF; - - FILTCAP = r; - FILTCAPG = g; - FILTCAPB = b; - - pclog("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); - - voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; - - if (voodoo->type == VOODOO_2) - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); - } -} - -static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) -{ - int x; - - // Scratchpad for avoiding feedback streaks - uint8_t fil3[(voodoo->h_disp) * 3]; - - /* 16 to 32-bit */ - for (x=0; x> 5) & 63) << 2); - fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - - // Copy to our scratchpads - fil3[x*3+0] = fil[x*3+0]; - fil3[x*3+1] = fil[x*3+1]; - fil3[x*3+2] = fil[x*3+2]; - } - - - /* lines */ - - if (line & 1) - { - for (x=0; xpurpleline[fil[x*3]][0]; - fil[x*3+1] = voodoo->purpleline[fil[x*3+1]][1]; - fil[x*3+2] = voodoo->purpleline[fil[x*3+2]][2]; - } - } - - - /* filtering time */ - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - - for (x=1; xthefilterb[fil3[x*3]][fil3[ (x-1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x-1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x-1) *3+2]]; - } - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - - for (x=0; xthefilterb[fil3[x*3]][fil3[ (x+1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x+1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x+1) *3+2]]; - } -} - - -static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) -{ - int x; - - // Scratchpad for blending filter - uint8_t fil3[(voodoo->h_disp) * 3]; - - /* 16 to 32-bit */ - for (x=0; x> 5) & 63) << 2); - fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - } - - /* filtering time */ - - for (x=1; xthefilterb [((src[x+3] & 31) << 3)] [((src[x] & 31) << 3)]; - fil3[(x+3)*3+1] = voodoo->thefilterg [(((src[x+3] >> 5) & 63) << 2)] [(((src[x] >> 5) & 63) << 2)]; - fil3[(x+3)*3+2] = voodoo->thefilter [(((src[x+3] >> 11) & 31) << 3)] [(((src[x] >> 11) & 31) << 3)]; - - fil[(x+2)*3] = voodoo->thefilterb [fil3[(x+2)*3]][((src[x] & 31) << 3)]; - fil[(x+2)*3+1] = voodoo->thefilterg [fil3[(x+2)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x+2)*3+2] = voodoo->thefilter [fil3[(x+2)*3+2]][(((src[x] >> 11) & 31) << 3)]; - - fil3[(x+1)*3] = voodoo->thefilterb [fil[(x+1)*3]][((src[x] & 31) << 3)]; - fil3[(x+1)*3+1] = voodoo->thefilterg [fil[(x+1)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil3[(x+1)*3+2] = voodoo->thefilter [fil[(x+1)*3+2]][(((src[x] >> 11) & 31) << 3)]; - - fil[(x-1)*3] = voodoo->thefilterb [fil3[(x-1)*3]][((src[x] & 31) << 3)]; - fil[(x-1)*3+1] = voodoo->thefilterg [fil3[(x-1)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; - } - - // unroll for edge cases - - fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-3)*3+2] = voodoo->thefilter [(((src[column-3] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-2)*3] = voodoo->thefilterb [((src[column-2] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-2)*3+1] = voodoo->thefilterg [(((src[column-2] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-2)*3+2] = voodoo->thefilter [(((src[column-2] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-1)*3] = voodoo->thefilterb [((src[column-1] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-1)*3+1] = voodoo->thefilterg [(((src[column-1] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-1)*3+2] = voodoo->thefilter [(((src[column-1] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil[(column-2)*3] = voodoo->thefilterb [fil3[(column-2)*3]][((src[column] & 31) << 3)]; - fil[(column-2)*3+1] = voodoo->thefilterg [fil3[(column-2)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column-2)*3+2] = voodoo->thefilter [fil3[(column-2)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - fil[(column-1)*3] = voodoo->thefilterb [fil3[(column-1)*3]][((src[column] & 31) << 3)]; - fil[(column-1)*3+1] = voodoo->thefilterg [fil3[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column-1)*3+2] = voodoo->thefilter [fil3[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-1)*3] = voodoo->thefilterb [fil[(column-1)*3]][((src[column] & 31) << 3)]; - fil3[(column-1)*3+1] = voodoo->thefilterg [fil[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil3[(column-1)*3+2] = voodoo->thefilter [fil[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; -} - -void voodoo_callback(void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) - { - if (voodoo->line < voodoo->v_disp) - { - voodoo_t *draw_voodoo; - int draw_line; - - if (SLI_ENABLED) - { - if (voodoo == voodoo->set->voodoos[1]) - goto skip_draw; - - if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) - draw_voodoo = voodoo; - else - draw_voodoo = voodoo->set->voodoos[1]; - draw_line = voodoo->line >> 1; - } - else - { - if (!(voodoo->fbiInit0 & 1)) - goto skip_draw; - draw_voodoo = voodoo; - draw_line = voodoo->line; - } - - if (draw_voodoo->dirty_line[draw_line]) - { - uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32]; - uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line*draw_voodoo->row_width]; - int x; - - draw_voodoo->dirty_line[draw_line] = 0; - - if (voodoo->line < voodoo->dirty_line_low) - { - voodoo->dirty_line_low = voodoo->line; - video_wait_for_buffer(); - } - if (voodoo->line > voodoo->dirty_line_high) - voodoo->dirty_line_high = voodoo->line; - - if (voodoo->scrfilter && voodoo->scrfilterEnabled) - { - uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ - - if (voodoo->type == VOODOO_2) - voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); - else - voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); - - for (x = 0; x < voodoo->h_disp; x++) - { - p[x] = (voodoo->clutData256[fil[x*3]].b << 0 | voodoo->clutData256[fil[x*3+1]].g << 8 | voodoo->clutData256[fil[x*3+2]].r << 16); - } - } - else - { - for (x = 0; x < voodoo->h_disp; x++) - { - p[x] = draw_voodoo->video_16to32[src[x]]; - } - } - } - } - } -skip_draw: - if (voodoo->line == voodoo->v_disp) - { -// pclog("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); - voodoo->retrace_count++; - if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) - { - if (voodoo == voodoo->set->voodoos[0]) - { - voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; - - /*Only swap if both Voodoos are waiting for buffer swap*/ - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && - voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - - memset(voodoo_1->dirty_line, 1, 1024); - voodoo_1->retrace_count = 0; - voodoo_1->front_offset = voodoo_1->swap_offset; - if (voodoo_1->swap_count > 0) - voodoo_1->swap_count--; - voodoo_1->swap_pending = 0; - - thread_set_event(voodoo->wake_fifo_thread); - thread_set_event(voodoo_1->wake_fifo_thread); - - voodoo->frame_count++; - voodoo_1->frame_count++; - } - } - } - else - { - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; - } - } - voodoo->v_retrace = 1; - } - voodoo->line++; - - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) - { - if (voodoo->line == voodoo->v_disp) - { - if (voodoo->dirty_line_high > voodoo->dirty_line_low) - svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp-1, voodoo->svga); - if (voodoo->clutData_dirty) - { - voodoo->clutData_dirty = 0; - voodoo_calc_clutData(voodoo); - } - voodoo->dirty_line_high = -1; - voodoo->dirty_line_low = 2000; - } - } - - if (voodoo->line >= voodoo->v_total) - { - voodoo->line = 0; - voodoo->v_retrace = 0; - } - if (voodoo->line_time) - timer_advance_u64(&voodoo->timer, voodoo->line_time); - else - timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); -} static void voodoo_add_status_info(char *s, int max_len, void *p) { @@ -7652,10 +985,10 @@ void *voodoo_card_init() voodoo->fifo_not_full_event = thread_create_event(); voodoo->render_not_full_event[0] = thread_create_event(); voodoo->render_not_full_event[1] = thread_create_event(); - voodoo->fifo_thread = thread_create(fifo_thread, voodoo); - voodoo->render_thread[0] = thread_create(render_thread_1, voodoo); + voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); if (voodoo->render_threads == 2) - voodoo->render_thread[1] = thread_create(render_thread_2, voodoo); + voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); diff --git a/src/vid_voodoo_blitter.c b/src/vid_voodoo_blitter.c new file mode 100644 index 0000000..f9b7538 --- /dev/null +++ b/src/vid_voodoo_blitter.c @@ -0,0 +1,479 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_blitter.h" +#include "vid_voodoo_dither.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" + +enum +{ + BLIT_COMMAND_SCREEN_TO_SCREEN = 0, + BLIT_COMMAND_CPU_TO_SCREEN = 1, + BLIT_COMMAND_RECT_FILL = 2, + BLIT_COMMAND_SGRAM_FILL = 3 +}; + +enum +{ + BLIT_SRC_1BPP = (0 << 3), + BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), + BLIT_SRC_16BPP = (2 << 3), + BLIT_SRC_24BPP = (3 << 3), + BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), + BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) +}; + +enum +{ + BLIT_SRC_RGB_ARGB = (0 << 6), + BLIT_SRC_RGB_ABGR = (1 << 6), + BLIT_SRC_RGB_RGBA = (2 << 6), + BLIT_SRC_RGB_BGRA = (3 << 6) +}; + +enum +{ + BLIT_COMMAND_MASK = 7, + BLIT_SRC_FORMAT = (7 << 3), + BLIT_SRC_RGB_FORMAT = (3 << 6), + BLIT_SRC_CHROMA = (1 << 10), + BLIT_DST_CHROMA = (1 << 12), + BLIT_CLIPPING_ENABLED = (1 << 16) +}; + +enum +{ + BLIT_ROP_DST_PASS = (1 << 0), + BLIT_ROP_SRC_PASS = (1 << 1) +}; + +#define MIX(src_dat, dst_dat, rop) \ + switch (rop) \ + { \ + case 0x0: dst_dat = 0; break; \ + case 0x1: dst_dat = ~(src_dat | dst_dat); break; \ + case 0x2: dst_dat = ~src_dat & dst_dat; break; \ + case 0x3: dst_dat = ~src_dat; break; \ + case 0x4: dst_dat = src_dat & ~dst_dat; break; \ + case 0x5: dst_dat = ~dst_dat; break; \ + case 0x6: dst_dat = src_dat ^ dst_dat; break; \ + case 0x7: dst_dat = ~(src_dat & dst_dat); break; \ + case 0x8: dst_dat = src_dat & dst_dat; break; \ + case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \ + case 0xa: dst_dat = dst_dat; break; \ + case 0xb: dst_dat = ~src_dat | dst_dat; break; \ + case 0xc: dst_dat = src_dat; break; \ + case 0xd: dst_dat = src_dat | ~dst_dat; break; \ + case 0xe: dst_dat = src_dat | dst_dat; break; \ + case 0xf: dst_dat = 0xffff; break; \ + } + +void voodoo_v2_blit_start(voodoo_t *voodoo) +{ + uint64_t dat64; + int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); + int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; + int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; + int dst_x; + int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; + int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8); + int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); + uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); + uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); + int x, y; + +/* pclog("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", + voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ + + voodoo_wait_for_render_thread_idle(voodoo); + + switch (voodoo->bltCommand & BLIT_COMMAND_MASK) + { + case BLIT_COMMAND_SCREEN_TO_SCREEN: + for (y = 0; y <= size_y; y++) + { + uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y*src_stride]; + uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; + int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; + + for (x = 0; x <= size_x; x++) + { + uint16_t src_dat = src[src_x]; + uint16_t dst_dat = dst[dst_x]; + int rop = 0; + + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) + { + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || + dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) + goto skip_pixel_blit; + } + + if (voodoo->bltCommand & BLIT_SRC_CHROMA) + { + int r = (src_dat >> 11); + int g = (src_dat >> 5) & 0x3f; + int b = src_dat & 0x1f; + + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && + g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && + b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) + { + int r = (dst_dat >> 11); + int g = (dst_dat >> 5) & 0x3f; + int b = dst_dat & 0x1f; + + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && + g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && + b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } + + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + + dst[dst_x] = dst_dat; +skip_pixel_blit: + src_x += x_dir; + dst_x += x_dir; + } + + src_y += y_dir; + dst_y += y_dir; + } + break; + + case BLIT_COMMAND_CPU_TO_SCREEN: + voodoo->blt.dst_x = voodoo->bltDstX; + voodoo->blt.dst_y = voodoo->bltDstY; + voodoo->blt.cur_x = 0; + voodoo->blt.size_x = size_x; + voodoo->blt.size_y = size_y; + voodoo->blt.x_dir = x_dir; + voodoo->blt.y_dir = y_dir; + voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); + break; + + case BLIT_COMMAND_RECT_FILL: + for (y = 0; y <= size_y; y++) + { + uint16_t *dst; + int dst_x = voodoo->bltDstX; + + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_line_fill; + dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; + } + else + dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; + + for (x = 0; x <= size_x; x++) + { + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) + { + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || + dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) + goto skip_pixel_fill; + } + + dst[dst_x] = voodoo->bltColorFg; +skip_pixel_fill: + dst_x += x_dir; + } +skip_line_fill: + dst_y += y_dir; + } + break; + + case BLIT_COMMAND_SGRAM_FILL: + /*32x32 tiles - 2kb*/ + dst_y = voodoo->bltDstY & 0x3ff; + size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb + size_y = voodoo->bltSizeY & 0x3ff; + + dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | + ((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48); + + for (y = 0; y <= size_y; y++) + { + uint64_t *dst; + + /*This may be wrong*/ + if (!y) + { + dst_x = voodoo->bltDstX & 0x1ff; + size_x = 511 - dst_x; + } + else if (y < size_y) + { + dst_x = 0; + size_x = 511; + } + else + { + dst_x = 0; + size_x = voodoo->bltSizeX & 0x1ff; + } + + dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask]; + + for (x = 0; x <= size_x; x++) + dst[x] = dat64; + + dst_y++; + } + break; + + default: + fatal("bad blit command %08x\n", voodoo->bltCommand); + } +} + +void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) +{ + int src_bits = 32; + uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); + uint32_t addr; + uint16_t *dst; + + if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) + return; + + if (SLI_ENABLED) + { + addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; + dst = (uint16_t *)&voodoo->fb_mem[addr]; + } + else + { + addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride; + dst = (uint16_t *)&voodoo->fb_mem[addr]; + } + + if (addr >= voodoo->front_offset && voodoo->row_width) + { + int y = (addr - voodoo->front_offset) / voodoo->row_width; + if (y < voodoo->v_disp) + voodoo->dirty_line[y] = 2; + } + + while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) + { + int r = 0, g = 0, b = 0; + uint16_t src_dat = 0, dst_dat; + int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); + int rop = 0; + + switch (voodoo->bltCommand & BLIT_SRC_FORMAT) + { + case BLIT_SRC_1BPP: case BLIT_SRC_1BPP_BYTE_PACKED: + src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; + data >>= 1; + src_bits--; + break; + case BLIT_SRC_16BPP: + switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) + { + case BLIT_SRC_RGB_ARGB: case BLIT_SRC_RGB_RGBA: + src_dat = data & 0xffff; + break; + case BLIT_SRC_RGB_ABGR: case BLIT_SRC_RGB_BGRA: + src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); + break; + } + data >>= 16; + src_bits -= 16; + break; + case BLIT_SRC_24BPP: case BLIT_SRC_24BPP_DITHER_2X2: case BLIT_SRC_24BPP_DITHER_4X4: + switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) + { + case BLIT_SRC_RGB_ARGB: + r = (data >> 16) & 0xff; + g = (data >> 8) & 0xff; + b = data & 0xff; + break; + case BLIT_SRC_RGB_ABGR: + r = data & 0xff; + g = (data >> 8) & 0xff; + b = (data >> 16) & 0xff; + break; + case BLIT_SRC_RGB_RGBA: + r = (data >> 24) & 0xff; + g = (data >> 16) & 0xff; + b = (data >> 8) & 0xff; + break; + case BLIT_SRC_RGB_BGRA: + r = (data >> 8) & 0xff; + g = (data >> 16) & 0xff; + b = (data >> 24) & 0xff; + break; + } + switch (voodoo->bltCommand & BLIT_SRC_FORMAT) + { + case BLIT_SRC_24BPP: + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + case BLIT_SRC_24BPP_DITHER_2X2: + r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; + g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; + b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + case BLIT_SRC_24BPP_DITHER_4X4: + r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; + g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; + b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + } + src_bits = 0; + break; + } + + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_pixel; + } + + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) + { + if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || + voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) + goto skip_pixel; + } + + dst_dat = dst[x]; + + if (voodoo->bltCommand & BLIT_SRC_CHROMA) + { + r = (src_dat >> 11); + g = (src_dat >> 5) & 0x3f; + b = src_dat & 0x1f; + + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && + g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && + b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) + { + r = (dst_dat >> 11); + g = (dst_dat >> 5) & 0x3f; + b = dst_dat & 0x1f; + + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && + g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && + b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } + + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + + dst[x] = dst_dat; + +skip_pixel: + voodoo->blt.cur_x++; + } + + if (voodoo->blt.cur_x > voodoo->blt.size_x) + { + voodoo->blt.size_y--; + if (voodoo->blt.size_y >= 0) + { + voodoo->blt.cur_x = 0; + voodoo->blt.dst_y += voodoo->blt.y_dir; + } + } +} + + +void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) +{ + int y; + int low_y, high_y; + + if (params->fbzMode & (1 << 17)) + { + high_y = voodoo->v_disp - params->clipLowY; + low_y = voodoo->v_disp - params->clipHighY; + } + else + { + low_y = params->clipLowY; + high_y = params->clipHighY; + } + + if (params->fbzMode & FBZ_RGB_WMASK) + { + int r, g, b; + uint16_t col; + + r = ((params->color1 >> 16) >> 3) & 0x1f; + g = ((params->color1 >> 8) >> 2) & 0x3f; + b = (params->color1 >> 3) & 0x1f; + col = b | (g << 5) | (r << 11); + + if (SLI_ENABLED) + { + for (y = low_y; y < high_y; y += 2) + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } + } + else + { + for (y = low_y; y < high_y; y++) + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } + } + } + if (params->fbzMode & FBZ_DEPTH_WMASK) + { + if (SLI_ENABLED) + { + for (y = low_y; y < high_y; y += 2) + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } + } + else + { + for (y = low_y; y < high_y; y++) + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } + } + } +} diff --git a/src/vid_voodoo_blitter.h b/src/vid_voodoo_blitter.h new file mode 100644 index 0000000..8d315df --- /dev/null +++ b/src/vid_voodoo_blitter.h @@ -0,0 +1,3 @@ +void voodoo_v2_blit_start(voodoo_t *voodoo); +void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data); +void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params); diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 8462479..4b5335b 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -3288,7 +3288,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xC3); /*RET*/ } -static int voodoo_recomp = 0; +int voodoo_recomp = 0; static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { int c; @@ -3339,7 +3339,7 @@ voodoo_recomp++; return data->code_block; } -static void voodoo_codegen_init(voodoo_t *voodoo) +void voodoo_codegen_init(voodoo_t *voodoo) { int c; @@ -3371,7 +3371,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16)); } -static void voodoo_codegen_close(voodoo_t *voodoo) +void voodoo_codegen_close(voodoo_t *voodoo) { #if WIN64 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index b09ed0e..5d14b24 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -3227,7 +3227,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) cs = cs; } -static int voodoo_recomp = 0; +int voodoo_recomp = 0; static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { @@ -3279,7 +3279,7 @@ voodoo_recomp++; return data->code_block; } -static void voodoo_codegen_init(voodoo_t *voodoo) +void voodoo_codegen_init(voodoo_t *voodoo) { int c; #if defined(__linux__) || defined(__APPLE__) @@ -3317,7 +3317,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16)); } -static void voodoo_codegen_close(voodoo_t *voodoo) +void voodoo_codegen_close(voodoo_t *voodoo) { #if defined WIN32 || defined _WIN32 || defined _WIN32 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h new file mode 100644 index 0000000..093fccd --- /dev/null +++ b/src/vid_voodoo_common.h @@ -0,0 +1,399 @@ +#ifdef MIN +#undef MIN +#endif +#ifdef CLAMP +#undef CLAMP +#endif + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x))) +#define CLAMP16(x) (((x) < 0) ? 0 : (((x) > 0xffff) ? 0xffff : (x))) + + +#define LOD_MAX 8 + +#define TEX_DIRTY_SHIFT 10 + +#define TEX_CACHE_MAX 64 + +enum +{ + VOODOO_1 = 0, + VOODOO_SB50 = 1, + VOODOO_2 = 2 +}; + +typedef union int_float +{ + uint32_t i; + float f; +} int_float; + +typedef struct rgb_t +{ + uint8_t b, g, r; + uint8_t pad; +} rgb_t; +typedef struct rgba8_t +{ + uint8_t b, g, r, a; +} rgba8_t; + +typedef union rgba_u +{ + struct + { + uint8_t b, g, r, a; + } rgba; + uint32_t u; +} rgba_u; + +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) + +#define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx) +#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE-4) +#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx) + +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff + +enum +{ + FIFO_INVALID = (0x00 << 24), + FIFO_WRITEL_REG = (0x01 << 24), + FIFO_WRITEW_FB = (0x02 << 24), + FIFO_WRITEL_FB = (0x03 << 24), + FIFO_WRITEL_TEX = (0x04 << 24) +}; + +#define PARAM_SIZE 1024 +#define PARAM_MASK (PARAM_SIZE - 1) +#define PARAM_ENTRY_SIZE (1 << 31) + +#define PARAM_ENTRIES_1 (voodoo->params_write_idx - voodoo->params_read_idx[0]) +#define PARAM_ENTRIES_2 (voodoo->params_write_idx - voodoo->params_read_idx[1]) +#define PARAM_FULL_1 ((voodoo->params_write_idx - voodoo->params_read_idx[0]) >= PARAM_SIZE) +#define PARAM_FULL_2 ((voodoo->params_write_idx - voodoo->params_read_idx[1]) >= PARAM_SIZE) +#define PARAM_EMPTY_1 (voodoo->params_read_idx[0] == voodoo->params_write_idx) +#define PARAM_EMPTY_2 (voodoo->params_read_idx[1] == voodoo->params_write_idx) + +typedef struct +{ + uint32_t addr_type; + uint32_t val; +} fifo_entry_t; + +typedef struct voodoo_params_t +{ + int command; + + int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; + + uint32_t startR, startG, startB, startZ, startA; + + int32_t dBdX, dGdX, dRdX, dAdX, dZdX; + + int32_t dBdY, dGdY, dRdY, dAdY, dZdY; + + int64_t startW, dWdX, dWdY; + + struct + { + int64_t startS, startT, startW, p1; + int64_t dSdX, dTdX, dWdX, p2; + int64_t dSdY, dTdY, dWdY, p3; + } tmu[2]; + + uint32_t color0, color1; + + uint32_t fbzMode; + uint32_t fbzColorPath; + + uint32_t fogMode; + rgb_t fogColor; + struct + { + uint8_t fog, dfog; + } fogTable[64]; + + uint32_t alphaMode; + + uint32_t zaColor; + + int chromaKey_r, chromaKey_g, chromaKey_b; + uint32_t chromaKey; + + uint32_t textureMode[2]; + uint32_t tLOD[2]; + + uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; + + uint32_t tex_base[2][LOD_MAX+2]; + uint32_t tex_end[2][LOD_MAX+2]; + int tex_width[2]; + int tex_w_mask[2][LOD_MAX+2]; + int tex_w_nmask[2][LOD_MAX+2]; + int tex_h_mask[2][LOD_MAX+2]; + int tex_shift[2][LOD_MAX+2]; + int tex_lod[2][LOD_MAX+2]; + int tex_entry[2]; + int detail_max[2], detail_bias[2], detail_scale[2]; + + uint32_t draw_offset, aux_offset; + + int tformat[2]; + + int clipLeft, clipRight, clipLowY, clipHighY; + + int sign; + + uint32_t front_offset; + + uint32_t swapbufferCMD; + + uint32_t stipple; +} voodoo_params_t; + +typedef struct texture_t +{ + uint32_t base; + uint32_t tLOD; + volatile int refcount, refcount_r[2]; + int is16; + uint32_t palette_checksum; + uint32_t addr_start[4], addr_end[4]; + uint32_t *data; +} texture_t; + +typedef struct vert_t +{ + float sVx, sVy; + float sRed, sGreen, sBlue, sAlpha; + float sVz, sWb; + float sW0, sS0, sT0; + float sW1, sS1, sT1; +} vert_t; + +typedef struct voodoo_t +{ + mem_mapping_t mapping; + + int pci_enable; + + uint8_t dac_data[8]; + int dac_reg, dac_reg_ff; + uint8_t dac_readdata; + uint16_t dac_pll_regs[16]; + + float pixel_clock; + uint64_t line_time; + + voodoo_params_t params; + + uint32_t fbiInit0, fbiInit1, fbiInit2, fbiInit3, fbiInit4; + uint32_t fbiInit5, fbiInit6, fbiInit7; /*Voodoo 2*/ + + uint32_t initEnable; + + uint32_t lfbMode; + + uint32_t memBaseAddr; + + int_float fvertexAx, fvertexAy, fvertexBx, fvertexBy, fvertexCx, fvertexCy; + + uint32_t front_offset, back_offset; + + uint32_t fb_read_offset, fb_write_offset; + + int row_width; + int block_width; + + uint8_t *fb_mem, *tex_mem[2]; + uint16_t *tex_mem_w[2]; + + int rgb_sel; + + uint32_t trexInit1[2]; + + uint32_t tmuConfig; + + int swap_count; + + int disp_buffer, draw_buffer; + pc_timer_t timer; + + int line; + svga_t *svga; + + uint32_t backPorch; + uint32_t videoDimensions; + uint32_t hSync, vSync; + + int h_total, v_total, v_disp; + int h_disp; + int v_retrace; + + struct + { + uint32_t y[4], i[4], q[4]; + } nccTable[2][2]; + + rgba_u palette[2][256]; + + rgba_u ncc_lookup[2][2][256]; + int ncc_dirty[2]; + + thread_t *fifo_thread; + thread_t *render_thread[2]; + event_t *wake_fifo_thread; + event_t *wake_main_thread; + event_t *fifo_not_full_event; + event_t *render_not_full_event[2]; + event_t *wake_render_thread[2]; + + int voodoo_busy; + int render_voodoo_busy[2]; + + int render_threads; + int odd_even_mask; + + int pixel_count[2], texel_count[2], tri_count, frame_count; + int pixel_count_old[2], texel_count_old[2]; + int wr_count, rd_count, tex_count; + + int retrace_count; + int swap_interval; + uint32_t swap_offset; + int swap_pending; + + int bilinear_enabled; + + int fb_size; + uint32_t fb_mask; + + int texture_size; + uint32_t texture_mask; + + int dual_tmus; + int type; + + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; + volatile int cmd_read, cmd_written, cmd_written_fifo; + + voodoo_params_t params_buffer[PARAM_SIZE]; + volatile int params_read_idx[2], params_write_idx; + + uint32_t cmdfifo_base, cmdfifo_end; + int cmdfifo_rp; + volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; + uint32_t cmdfifo_amin, cmdfifo_amax; + + uint32_t sSetupMode; + vert_t verts[4]; + int vertex_num; + int num_verticies; + + int flush; + + int scrfilter; + int scrfilterEnabled; + int scrfilterThreshold; + int scrfilterThresholdOld; + + uint32_t last_write_addr; + + uint32_t fbiPixelsIn; + uint32_t fbiChromaFail; + uint32_t fbiZFuncFail; + uint32_t fbiAFuncFail; + uint32_t fbiPixelsOut; + + uint32_t bltSrcBaseAddr; + uint32_t bltDstBaseAddr; + int bltSrcXYStride, bltDstXYStride; + uint32_t bltSrcChromaRange, bltDstChromaRange; + int bltSrcChromaMinR, bltSrcChromaMinG, bltSrcChromaMinB; + int bltSrcChromaMaxR, bltSrcChromaMaxG, bltSrcChromaMaxB; + int bltDstChromaMinR, bltDstChromaMinG, bltDstChromaMinB; + int bltDstChromaMaxR, bltDstChromaMaxG, bltDstChromaMaxB; + + int bltClipRight, bltClipLeft; + int bltClipHighY, bltClipLowY; + + int bltSrcX, bltSrcY; + int bltDstX, bltDstY; + int bltSizeX, bltSizeY; + int bltRop[4]; + uint16_t bltColorFg, bltColorBg; + + uint32_t bltCommand; + + struct + { + int dst_x, dst_y; + int cur_x; + int size_x, size_y; + int x_dir, y_dir; + int dst_stride; + } blt; + + rgb_t clutData[33]; + int clutData_dirty; + rgb_t clutData256[256]; + uint32_t video_16to32[0x10000]; + + uint8_t dirty_line[1024]; + int dirty_line_low, dirty_line_high; + + int fb_write_buffer, fb_draw_buffer; + int buffer_cutoff; + + int read_time, write_time, burst_time; + + pc_timer_t wake_timer; + + uint8_t thefilter[256][256]; // pixel filter, feeding from one or two + uint8_t thefilterg[256][256]; // for green + uint8_t thefilterb[256][256]; // for blue + + /* the voodoo adds purple lines for some reason */ + uint16_t purpleline[256][3]; + + texture_t texture_cache[2][TEX_CACHE_MAX]; + uint8_t texture_present[2][4096]; + int texture_last_removed; + + uint32_t palette_checksum[2]; + int palette_dirty[2]; + + uint64_t time; + int render_time[2]; + + int use_recompiler; + void *codegen_data; + + struct voodoo_set_t *set; +} voodoo_t; + +typedef struct voodoo_set_t +{ + voodoo_t *voodoos[2]; + + mem_mapping_t snoop_mapping; + + int nr_cards; +} voodoo_set_t; + + +extern rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; + + + + +void voodoo_recalc(voodoo_t *voodoo); +void voodoo_update_ncc(voodoo_t *voodoo, int tmu); + diff --git a/src/vid_voodoo_display.c b/src/vid_voodoo_display.c new file mode 100644 index 0000000..d643d5d --- /dev/null +++ b/src/vid_voodoo_display.c @@ -0,0 +1,603 @@ +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_display.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" + +void voodoo_update_ncc(voodoo_t *voodoo, int tmu) +{ + int tbl; + + for (tbl = 0; tbl < 2; tbl++) + { + int col; + + for (col = 0; col < 256; col++) + { + int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; + int i_r, i_g, i_b; + int q_r, q_g, q_b; + + y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; + + i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; + if (i_r & 0x100) + i_r |= 0xfffffe00; + i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; + if (i_g & 0x100) + i_g |= 0xfffffe00; + i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; + if (i_b & 0x100) + i_b |= 0xfffffe00; + + q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; + if (q_r & 0x100) + q_r |= 0xfffffe00; + q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; + if (q_g & 0x100) + q_g |= 0xfffffe00; + q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; + if (q_b & 0x100) + q_b |= 0xfffffe00; + + voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); + voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); + voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); + voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; + } + } +} + +void voodoo_pixelclock_update(voodoo_t *voodoo) +{ + int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; + int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; + int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); + float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); + double clock_const; + int line_length; + + if ((voodoo->dac_data[6] & 0xf0) == 0x20 || + (voodoo->dac_data[6] & 0xf0) == 0x60 || + (voodoo->dac_data[6] & 0xf0) == 0x70) + t /= 2.0f; + + line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); + +// pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); + + voodoo->pixel_clock = t; + + clock_const = cpuclock / t; + voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32)); +} + +static void voodoo_calc_clutData(voodoo_t *voodoo) +{ + int c; + + for (c = 0; c < 256; c++) + { + voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r*(8-(c & 7)) + + voodoo->clutData[(c >> 3)+1].r*(c & 7)) >> 3; + voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g*(8-(c & 7)) + + voodoo->clutData[(c >> 3)+1].g*(c & 7)) >> 3; + voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b*(8-(c & 7)) + + voodoo->clutData[(c >> 3)+1].b*(c & 7)) >> 3; + } + + for (c = 0; c < 65536; c++) + { + int r = (c >> 8) & 0xf8; + int g = (c >> 3) & 0xfc; + int b = (c << 3) & 0xf8; +// r |= (r >> 5); +// g |= (g >> 6); +// b |= (b >> 5); + + voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; + } +} + + + +#define FILTDIV 256 + +static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ + +void voodoo_generate_filter_v1(voodoo_t *voodoo) +{ + int g, h; + float difference, diffg, diffb; + float thiscol, thiscolg, thiscolb, lined; + float fcr, fcg, fcb; + + fcr = FILTCAP * 5; + fcg = FILTCAPG * 6; + fcb = FILTCAPB * 5; + + for (g=0;g FILTCAP) + difference = FILTCAP; + if (difference < -FILTCAP) + difference = -FILTCAP; + + if (diffg > FILTCAPG) + diffg = FILTCAPG; + if (diffg < -FILTCAPG) + diffg = -FILTCAPG; + + if (diffb > FILTCAPB) + diffb = FILTCAPB; + if (diffb < -FILTCAPB) + diffb = -FILTCAPB; + + // hack - to make it not bleed onto black + //if (g == 0){ + //difference = diffg = diffb = 0; + //} + + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ + if ((diffb < fcb) || (-diffb > -fcb)) + thiscolb = g + (diffb / 2); + + if (thiscol < 0) + thiscol = 0; + if (thiscol > FILTDIV-1) + thiscol = FILTDIV-1; + + if (thiscolg < 0) + thiscolg = 0; + if (thiscolg > FILTDIV-1) + thiscolg = FILTDIV-1; + + if (thiscolb < 0) + thiscolb = 0; + if (thiscolb > FILTDIV-1) + thiscolb = FILTDIV-1; + + voodoo->thefilter[g][h] = thiscol; + voodoo->thefilterg[g][h] = thiscolg; + voodoo->thefilterb[g][h] = thiscolb; + } + + lined = g + 4; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][2] = lined; + + lined = g + 0; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][1] = lined; + } +} + +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][0] = lined; + voodoo->purpleline[g][1] = 0; + voodoo->purpleline[g][2] = lined; + } +} + +void voodoo_threshold_check(voodoo_t *voodoo) +{ + int r, g, b; + + if (!voodoo->scrfilterEnabled) + return; /* considered disabled; don't check and generate */ + + /* Check for changes, to generate anew table */ + if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) + { + r = (voodoo->scrfilterThreshold >> 16) & 0xFF; + g = (voodoo->scrfilterThreshold >> 8 ) & 0xFF; + b = voodoo->scrfilterThreshold & 0xFF; + + FILTCAP = r; + FILTCAPG = g; + FILTCAPB = b; + + pclog("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); + + voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; + + if (voodoo->type == VOODOO_2) + voodoo_generate_filter_v2(voodoo); + else + voodoo_generate_filter_v1(voodoo); + } +} + +static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) +{ + int x; + + // Scratchpad for avoiding feedback streaks + uint8_t fil3[(voodoo->h_disp) * 3]; + + /* 16 to 32-bit */ + for (x=0; x> 5) & 63) << 2); + fil[x*3+2] = (((src[x] >> 11) & 31) << 3); + + // Copy to our scratchpads + fil3[x*3+0] = fil[x*3+0]; + fil3[x*3+1] = fil[x*3+1]; + fil3[x*3+2] = fil[x*3+2]; + } + + + /* lines */ + + if (line & 1) + { + for (x=0; xpurpleline[fil[x*3]][0]; + fil[x*3+1] = voodoo->purpleline[fil[x*3+1]][1]; + fil[x*3+2] = voodoo->purpleline[fil[x*3+2]][2]; + } + } + + + /* filtering time */ + + for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; + fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; + fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; + } + + for (x=1; xthefilterb[fil3[x*3]][fil3[ (x-1) *3]]; + fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x-1) *3+1]]; + fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x-1) *3+2]]; + } + + for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; + fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; + fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; + } + + for (x=0; xthefilterb[fil3[x*3]][fil3[ (x+1) *3]]; + fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x+1) *3+1]]; + fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x+1) *3+2]]; + } +} + + +static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) +{ + int x; + + // Scratchpad for blending filter + uint8_t fil3[(voodoo->h_disp) * 3]; + + /* 16 to 32-bit */ + for (x=0; x> 5) & 63) << 2); + fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); + } + + /* filtering time */ + + for (x=1; xthefilterb [((src[x+3] & 31) << 3)] [((src[x] & 31) << 3)]; + fil3[(x+3)*3+1] = voodoo->thefilterg [(((src[x+3] >> 5) & 63) << 2)] [(((src[x] >> 5) & 63) << 2)]; + fil3[(x+3)*3+2] = voodoo->thefilter [(((src[x+3] >> 11) & 31) << 3)] [(((src[x] >> 11) & 31) << 3)]; + + fil[(x+2)*3] = voodoo->thefilterb [fil3[(x+2)*3]][((src[x] & 31) << 3)]; + fil[(x+2)*3+1] = voodoo->thefilterg [fil3[(x+2)*3+1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x+2)*3+2] = voodoo->thefilter [fil3[(x+2)*3+2]][(((src[x] >> 11) & 31) << 3)]; + + fil3[(x+1)*3] = voodoo->thefilterb [fil[(x+1)*3]][((src[x] & 31) << 3)]; + fil3[(x+1)*3+1] = voodoo->thefilterg [fil[(x+1)*3+1]][(((src[x] >> 5) & 63) << 2)]; + fil3[(x+1)*3+2] = voodoo->thefilter [fil[(x+1)*3+2]][(((src[x] >> 11) & 31) << 3)]; + + fil[(x-1)*3] = voodoo->thefilterb [fil3[(x-1)*3]][((src[x] & 31) << 3)]; + fil[(x-1)*3+1] = voodoo->thefilterg [fil3[(x-1)*3+1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; + } + + // unroll for edge cases + + fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; + fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; + fil3[(column-3)*3+2] = voodoo->thefilter [(((src[column-3] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; + + fil3[(column-2)*3] = voodoo->thefilterb [((src[column-2] & 31) << 3)] [((src[column] & 31) << 3)]; + fil3[(column-2)*3+1] = voodoo->thefilterg [(((src[column-2] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; + fil3[(column-2)*3+2] = voodoo->thefilter [(((src[column-2] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; + + fil3[(column-1)*3] = voodoo->thefilterb [((src[column-1] & 31) << 3)] [((src[column] & 31) << 3)]; + fil3[(column-1)*3+1] = voodoo->thefilterg [(((src[column-1] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; + fil3[(column-1)*3+2] = voodoo->thefilter [(((src[column-1] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; + + fil[(column-2)*3] = voodoo->thefilterb [fil3[(column-2)*3]][((src[column] & 31) << 3)]; + fil[(column-2)*3+1] = voodoo->thefilterg [fil3[(column-2)*3+1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column-2)*3+2] = voodoo->thefilter [fil3[(column-2)*3+2]][(((src[column] >> 11) & 31) << 3)]; + + fil[(column-1)*3] = voodoo->thefilterb [fil3[(column-1)*3]][((src[column] & 31) << 3)]; + fil[(column-1)*3+1] = voodoo->thefilterg [fil3[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column-1)*3+2] = voodoo->thefilter [fil3[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; + + fil3[(column-1)*3] = voodoo->thefilterb [fil[(column-1)*3]][((src[column] & 31) << 3)]; + fil3[(column-1)*3+1] = voodoo->thefilterg [fil[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; + fil3[(column-1)*3+2] = voodoo->thefilter [fil[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; +} + +void voodoo_callback(void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + + if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) + { + if (voodoo->line < voodoo->v_disp) + { + voodoo_t *draw_voodoo; + int draw_line; + + if (SLI_ENABLED) + { + if (voodoo == voodoo->set->voodoos[1]) + goto skip_draw; + + if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) + draw_voodoo = voodoo; + else + draw_voodoo = voodoo->set->voodoos[1]; + draw_line = voodoo->line >> 1; + } + else + { + if (!(voodoo->fbiInit0 & 1)) + goto skip_draw; + draw_voodoo = voodoo; + draw_line = voodoo->line; + } + + if (draw_voodoo->dirty_line[draw_line]) + { + uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32]; + uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line*draw_voodoo->row_width]; + int x; + + draw_voodoo->dirty_line[draw_line] = 0; + + if (voodoo->line < voodoo->dirty_line_low) + { + voodoo->dirty_line_low = voodoo->line; + video_wait_for_buffer(); + } + if (voodoo->line > voodoo->dirty_line_high) + voodoo->dirty_line_high = voodoo->line; + + if (voodoo->scrfilter && voodoo->scrfilterEnabled) + { + uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ + + if (voodoo->type == VOODOO_2) + voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); + else + voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); + + for (x = 0; x < voodoo->h_disp; x++) + { + p[x] = (voodoo->clutData256[fil[x*3]].b << 0 | voodoo->clutData256[fil[x*3+1]].g << 8 | voodoo->clutData256[fil[x*3+2]].r << 16); + } + } + else + { + for (x = 0; x < voodoo->h_disp; x++) + { + p[x] = draw_voodoo->video_16to32[src[x]]; + } + } + } + } + } +skip_draw: + if (voodoo->line == voodoo->v_disp) + { +// pclog("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); + voodoo->retrace_count++; + if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) + { + if (voodoo == voodoo->set->voodoos[0]) + { + voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; + + /*Only swap if both Voodoos are waiting for buffer swap*/ + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && + voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) + { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + + memset(voodoo_1->dirty_line, 1, 1024); + voodoo_1->retrace_count = 0; + voodoo_1->front_offset = voodoo_1->swap_offset; + if (voodoo_1->swap_count > 0) + voodoo_1->swap_count--; + voodoo_1->swap_pending = 0; + + thread_set_event(voodoo->wake_fifo_thread); + thread_set_event(voodoo_1->wake_fifo_thread); + + voodoo->frame_count++; + voodoo_1->frame_count++; + } + } + } + else + { + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) + { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } + } + voodoo->v_retrace = 1; + } + voodoo->line++; + + if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) + { + if (voodoo->line == voodoo->v_disp) + { + if (voodoo->dirty_line_high > voodoo->dirty_line_low) + svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp-1, voodoo->svga); + if (voodoo->clutData_dirty) + { + voodoo->clutData_dirty = 0; + voodoo_calc_clutData(voodoo); + } + voodoo->dirty_line_high = -1; + voodoo->dirty_line_low = 2000; + } + } + + if (voodoo->line >= voodoo->v_total) + { + voodoo->line = 0; + voodoo->v_retrace = 0; + } + if (voodoo->line_time) + timer_advance_u64(&voodoo->timer, voodoo->line_time); + else + timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); +} diff --git a/src/vid_voodoo_display.h b/src/vid_voodoo_display.h new file mode 100644 index 0000000..46cbc00 --- /dev/null +++ b/src/vid_voodoo_display.h @@ -0,0 +1,6 @@ +void voodoo_update_ncc(voodoo_t *voodoo, int tmu); +void voodoo_pixelclock_update(voodoo_t *voodoo); +void voodoo_generate_filter_v1(voodoo_t *voodoo); +void voodoo_generate_filter_v2(voodoo_t *voodoo); +void voodoo_threshold_check(voodoo_t *voodoo); +void voodoo_callback(void *p); diff --git a/src/vid_voodoo_dither.h b/src/vid_voodoo_dither.h index 7ec7471..daf26d5 100644 --- a/src/vid_voodoo_dither.h +++ b/src/vid_voodoo_dither.h @@ -1,4 +1,4 @@ -uint8_t dither_rb[256][4][4] = +static const uint8_t dither_rb[256][4][4] = { { {0, 0, 0, 0}, @@ -1538,7 +1538,7 @@ uint8_t dither_rb[256][4][4] = }, }; -uint8_t dither_g[256][4][4] = +static const uint8_t dither_g[256][4][4] = { { {0, 0, 0, 0}, @@ -3078,7 +3078,7 @@ uint8_t dither_g[256][4][4] = }, }; -uint8_t dither_rb2x2[256][2][2] = +static const uint8_t dither_rb2x2[256][2][2] = { { {0, 0}, @@ -4106,7 +4106,7 @@ uint8_t dither_rb2x2[256][2][2] = }, }; -uint8_t dither_g2x2[256][2][2] = +static const uint8_t dither_g2x2[256][2][2] = { { {0, 0}, diff --git a/src/vid_voodoo_fb.c b/src/vid_voodoo_fb.c new file mode 100644 index 0000000..39fa2ac --- /dev/null +++ b/src/vid_voodoo_fb.c @@ -0,0 +1,397 @@ +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_dither.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_fb.h" + +uint16_t voodoo_fb_readw(uint32_t addr, void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + int x, y; + uint32_t read_addr; + uint16_t temp; + + x = (addr >> 1) & 0x3ff; + y = (addr >> 11) & 0x3ff; + + if (SLI_ENABLED) + { + voodoo_set_t *set = voodoo->set; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + + y >>= 1; + } + + read_addr = voodoo->fb_read_offset + (x << 1) + (y * voodoo->row_width); + + if (read_addr > voodoo->fb_mask) + return 0xffff; + + temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); + +// 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; +} +uint32_t voodoo_fb_readl(uint32_t addr, void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + int x, y; + uint32_t read_addr; + uint32_t temp; + + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + + if (SLI_ENABLED) + { + voodoo_set_t *set = voodoo->set; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + + y >>= 1; + } + + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); + + if (read_addr > voodoo->fb_mask) + return 0xffffffff; + + temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); + +// 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) +{ + int r, g, b; + + if (dither) + { + if (dither2x2) + { + r = dither_rb2x2[col.r][y & 1][x & 1]; + g = dither_g2x2[col.g][y & 1][x & 1]; + b = dither_rb2x2[col.b][y & 1][x & 1]; + } + else + { + r = dither_rb[col.r][y & 3][x & 3]; + g = dither_g[col.g][y & 3][x & 3]; + b = dither_rb[col.b][y & 3][x & 3]; + } + } + else + { + r = col.r >> 3; + g = col.g >> 2; + b = col.b >> 3; + } + + return b | (g << 5) | (r << 11); +} + +void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + voodoo_params_t *params = &voodoo->params; + int x, y; + uint32_t write_addr, write_addr_aux; + rgba8_t colour_data; + uint16_t depth_data; + uint8_t alpha_data; + int write_mask = 0; + + colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; + + depth_data = voodoo->params.zaColor & 0xffff; + alpha_data = voodoo->params.zaColor >> 24; + +// while (!RB_EMPTY) +// thread_reset_event(voodoo->not_full_event); + +// pclog("voodoo_fb_writew : %08X %04X\n", addr, val); + + + switch (voodoo->lfbMode & LFB_FORMAT_MASK) + { + case LFB_FORMAT_RGB565: + colour_data = rgb565[val]; + alpha_data = 0xff; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_RGB555: + colour_data = argb1555[val]; + alpha_data = 0xff; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_ARGB1555: + colour_data = argb1555[val]; + alpha_data = colour_data.a; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_DEPTH: + depth_data = val; + write_mask = LFB_WRITE_DEPTH; + break; + + default: + fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); + } + + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } + + + if (voodoo->fb_write_offset == voodoo->params.front_offset) + voodoo->dirty_line[y] = 1; + + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + +// pclog("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); + + if (voodoo->lfbMode & 0x100) + { + { + rgba8_t write_data = colour_data; + uint16_t new_depth = depth_data; + + if (params->fbzMode & FBZ_DEPTH_ENABLE) + { + uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); + + DEPTH_TEST(new_depth); + } + + if ((params->fbzMode & FBZ_CHROMAKEY) && + write_data.r == params->chromaKey_r && + write_data.g == params->chromaKey_g && + write_data.b == params->chromaKey_b) + goto skip_pixel; + + if (params->fogMode & FOG_ENABLE) + { + int32_t z = new_depth << 12; + int64_t w_depth = (int64_t)(int32_t)new_depth; + int32_t ia = alpha_data << 12; + + APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); + } + + if (params->alphaMode & 1) + ALPHA_TEST(alpha_data); + + if (params->alphaMode & (1 << 4)) + { + uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); + int dest_r, dest_g, dest_b, dest_a; + + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; + + ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); + } + + if (params->fbzMode & FBZ_RGB_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y); + if (params->fbzMode & FBZ_DEPTH_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; + +skip_pixel: + x = x; + } + } + else + { + if (write_mask & LFB_WRITE_COLOUR) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y); + if (write_mask & LFB_WRITE_DEPTH) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; + } +} + + +void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + voodoo_params_t *params = &voodoo->params; + int x, y; + uint32_t write_addr, write_addr_aux; + rgba8_t colour_data[2]; + uint16_t depth_data[2]; + uint8_t alpha_data[2]; + int write_mask = 0, count = 1; + + depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; + alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; +// while (!RB_EMPTY) +// thread_reset_event(voodoo->not_full_event); + +// pclog("voodoo_fb_writel : %08X %08X\n", addr, val); + + switch (voodoo->lfbMode & LFB_FORMAT_MASK) + { + case LFB_FORMAT_RGB565: + colour_data[0] = rgb565[val & 0xffff]; + colour_data[1] = rgb565[val >> 16]; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + case LFB_FORMAT_RGB555: + colour_data[0] = argb1555[val & 0xffff]; + colour_data[1] = argb1555[val >> 16]; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + case LFB_FORMAT_ARGB1555: + colour_data[0] = argb1555[val & 0xffff]; + alpha_data[0] = colour_data[0].a; + colour_data[1] = argb1555[val >> 16]; + alpha_data[1] = colour_data[1].a; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + + case LFB_FORMAT_ARGB8888: + colour_data[0].b = val & 0xff; + colour_data[0].g = (val >> 8) & 0xff; + colour_data[0].r = (val >> 16) & 0xff; + alpha_data[0] = (val >> 24) & 0xff; + write_mask = LFB_WRITE_COLOUR; + addr >>= 1; + break; + + case LFB_FORMAT_DEPTH: + depth_data[0] = val; + depth_data[1] = val >> 16; + write_mask = LFB_WRITE_DEPTH; + count = 2; + break; + + default: + fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); + } + + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + + if (SLI_ENABLED) + { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } + + if (voodoo->fb_write_offset == voodoo->params.front_offset) + voodoo->dirty_line[y] = 1; + + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + +// 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) + { + int c; + + for (c = 0; c < count; c++) + { + rgba8_t write_data = colour_data[c]; + uint16_t new_depth = depth_data[c]; + + if (params->fbzMode & FBZ_DEPTH_ENABLE) + { + uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); + + DEPTH_TEST(new_depth); + } + + if ((params->fbzMode & FBZ_CHROMAKEY) && + write_data.r == params->chromaKey_r && + write_data.g == params->chromaKey_g && + write_data.b == params->chromaKey_b) + goto skip_pixel; + + if (params->fogMode & FOG_ENABLE) + { + int32_t z = new_depth << 12; + int64_t w_depth = new_depth; + int32_t ia = alpha_data[c] << 12; + + APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); + } + + if (params->alphaMode & 1) + ALPHA_TEST(alpha_data[c]); + + if (params->alphaMode & (1 << 4)) + { + uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); + int dest_r, dest_g, dest_b, dest_a; + + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; + + ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); + } + + if (params->fbzMode & FBZ_RGB_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y); + if (params->fbzMode & FBZ_DEPTH_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; + +skip_pixel: + write_addr += 2; + write_addr_aux += 2; + } + } + else + { + int c; + + for (c = 0; c < count; c++) + { + if (write_mask & LFB_WRITE_COLOUR) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); + if (write_mask & LFB_WRITE_DEPTH) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; + + write_addr += 2; + write_addr_aux += 2; + } + } +} diff --git a/src/vid_voodoo_fb.h b/src/vid_voodoo_fb.h new file mode 100644 index 0000000..fcb2513 --- /dev/null +++ b/src/vid_voodoo_fb.h @@ -0,0 +1,4 @@ +uint16_t voodoo_fb_readw(uint32_t addr, void *p); +uint32_t voodoo_fb_readl(uint32_t addr, void *p); +void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p); +void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p); diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c new file mode 100644 index 0000000..ccf112e --- /dev/null +++ b/src/vid_voodoo_fifo.c @@ -0,0 +1,394 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_fb.h" +#include "vid_voodoo_fifo.h" +#include "vid_voodoo_reg.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_texture.h" + +#define WAKE_DELAY (TIMER_USEC * 100) +void voodoo_wake_fifo_thread(voodoo_t *voodoo) +{ + if (!timer_is_enabled(&voodoo->wake_timer)) + { + /*Don't wake FIFO thread immediately - if we do that it will probably + process one word and go back to sleep, requiring it to be woken on + almost every write. Instead, wait a short while so that the CPU + emulation writes more data so we have more batched-up work.*/ + timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); + } +} + +void voodoo_wake_fifo_thread_now(voodoo_t *voodoo) +{ + thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} + +void voodoo_wake_timer(void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + + thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} + +void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) +{ + fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; + + while (FIFO_FULL) + { + thread_reset_event(voodoo->fifo_not_full_event); + if (FIFO_FULL) + { + thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ + if (FIFO_FULL) + voodoo_wake_fifo_thread_now(voodoo); + } + } + + fifo->val = val; + fifo->addr_type = addr_type; + + voodoo->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000) + voodoo_wake_fifo_thread(voodoo); +} + +void voodoo_flush(voodoo_t *voodoo) +{ + voodoo->flush = 1; + while (!FIFO_EMPTY) + { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; +} + +void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) +{ + voodoo_wake_fifo_thread(voodoo); + if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) + voodoo_wake_fifo_thread(set->voodoos[1]); +} + +void voodoo_wait_for_swap_complete(voodoo_t *voodoo) +{ + while (voodoo->swap_pending) + { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) + { + /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ + memset(voodoo->dirty_line, 1, 1024); + voodoo->front_offset = voodoo->params.front_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + break; + } + } +} + + +static uint32_t cmdfifo_get(voodoo_t *voodoo) +{ + uint32_t val; + + while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) + { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + } + + val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; + + voodoo->cmdfifo_depth_rd++; + voodoo->cmdfifo_rp += 4; + +// pclog(" CMDFIFO get %08x\n", val); + return val; +} + +static inline float cmdfifo_get_f(voodoo_t *voodoo) +{ + union + { + uint32_t i; + float f; + } tempif; + + tempif.i = cmdfifo_get(voodoo); + return tempif.f; +} + +enum +{ + CMDFIFO3_PC_MASK_RGB = (1 << 10), + CMDFIFO3_PC_MASK_ALPHA = (1 << 11), + CMDFIFO3_PC_MASK_Z = (1 << 12), + CMDFIFO3_PC_MASK_Wb = (1 << 13), + CMDFIFO3_PC_MASK_W0 = (1 << 14), + CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), + CMDFIFO3_PC_MASK_W1 = (1 << 16), + CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), + + CMDFIFO3_PC = (1 << 28) +}; + +void voodoo_fifo_thread(void *param) +{ + voodoo_t *voodoo = (voodoo_t *)param; + + while (1) + { + thread_set_event(voodoo->fifo_not_full_event); + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + voodoo->voodoo_busy = 1; + while (!FIFO_EMPTY) + { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + + switch (fifo->addr_type & FIFO_TYPE) + { + case FIFO_WRITEL_REG: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) + { + voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEW_FB: + voodoo_wait_for_render_thread_idle(voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) + { + voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_FB: + voodoo_wait_for_render_thread_idle(voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) + { + voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_TEX: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) + { + if (!(fifo->addr_type & 0x400000)) + voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + } + + if (FIFO_ENTRIES > 0xe000) + thread_set_event(voodoo->fifo_not_full_event); + + end_time = timer_read(); + voodoo->time += end_time - start_time; + } + + while (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + { + uint64_t start_time = timer_read(); + uint64_t end_time; + uint32_t header = cmdfifo_get(voodoo); + uint32_t addr; + uint32_t mask; + int smode; + int num; + int num_verticies; + int v_num; + +// 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*/ + break; + + case 3: /*JMP local frame buffer*/ + voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; +// pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); + break; + + default: + fatal("Bad CMDFIFO0 %08x\n", header); + } + break; + + case 1: + num = header >> 16; + addr = (header & 0x7ff8) >> 1; +// pclog("CMDFIFO1 addr=%08x\n",addr); + while (num--) + { + uint32_t val = cmdfifo_get(voodoo); + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || + (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; + + voodoo_reg_writel(addr, val, voodoo); + + if (header & (1 << 15)) + addr += 4; + } + break; + + case 3: + num = (header >> 29) & 7; + mask = header;//(header >> 10) & 0xff; + smode = (header >> 22) & 0xf; + voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); + num_verticies = (header >> 6) & 0xf; + v_num = 0; + if (((header >> 3) & 7) == 2) + v_num = 1; +// 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--) + { + voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); + voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_RGB) + { + if (header & CMDFIFO3_PC) + { + uint32_t val = cmdfifo_get(voodoo); + voodoo->verts[3].sBlue = (float)(val & 0xff); + voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); + } + else + { + voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); + voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); + voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); + } + } + if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) + voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_Z) + voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_Wb) + voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_W0) + voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_S0_T0) + { + voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); + voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); + } + if (mask & CMDFIFO3_PC_MASK_W1) + voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_S1_T1) + { + voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); + voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); + } + if (v_num) + voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); + else + voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); + v_num++; + if (v_num == 3 && ((header >> 3) & 7) == 0) + v_num = 0; + } + break; + + case 4: + num = (header >> 29) & 7; + mask = (header >> 15) & 0x3fff; + addr = (header & 0x7ff8) >> 1; +// pclog("CMDFIFO4 addr=%08x\n",addr); + while (mask) + { + if (mask & 1) + { + uint32_t val = cmdfifo_get(voodoo); + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || + (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; + + voodoo_reg_writel(addr, val, voodoo); + } + + addr += 4; + mask >>= 1; + } + while (num--) + cmdfifo_get(voodoo); + break; + + case 5: + if (header & 0x3fc0000) + fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); + num = (header >> 3) & 0x7ffff; + addr = cmdfifo_get(voodoo) & 0xffffff; +// pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); + switch (header >> 30) + { + case 2: /*Framebuffer*/ + while (num--) + { + uint32_t val = cmdfifo_get(voodoo); + voodoo_fb_writel(addr, val, voodoo); + addr += 4; + } + break; + case 3: /*Texture*/ + while (num--) + { + uint32_t val = cmdfifo_get(voodoo); + voodoo_tex_writel(addr, val, voodoo); + addr += 4; + } + break; + + default: + fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); + } + break; + + default: + pclog("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + } + + end_time = timer_read(); + voodoo->time += end_time - start_time; + } + voodoo->voodoo_busy = 0; + } +} diff --git a/src/vid_voodoo_fifo.h b/src/vid_voodoo_fifo.h new file mode 100644 index 0000000..c1caeba --- /dev/null +++ b/src/vid_voodoo_fifo.h @@ -0,0 +1,8 @@ +void voodoo_wake_fifo_thread(voodoo_t *voodoo); +void voodoo_wake_fifo_thread_now(voodoo_t *voodoo); +void voodoo_wake_timer(void *p); +void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val); +void voodoo_flush(voodoo_t *voodoo); +void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo); +void voodoo_wait_for_swap_complete(voodoo_t *voodoo); +void voodoo_fifo_thread(void *param); diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c new file mode 100644 index 0000000..52557f1 --- /dev/null +++ b/src/vid_voodoo_reg.c @@ -0,0 +1,1140 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_blitter.h" +#include "vid_voodoo_dither.h" +#include "vid_voodoo_fifo.h" +#include "vid_voodoo_reg.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_setup.h" +#include "vid_voodoo_texture.h" + +enum +{ + CHIP_FBI = 0x1, + CHIP_TREX0 = 0x2, + CHIP_TREX1 = 0x4, + CHIP_TREX2 = 0x8 +}; + +void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) +{ + voodoo_t *voodoo = (voodoo_t *)p; + union + { + uint32_t i; + float f; + } tempif; + int ad21 = addr & (1 << 21); + int chip = (addr >> 10) & 0xf; + if (!chip) + chip = 0xf; + + tempif.i = val; +//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) + addr |= 0x400; + switch (addr) + { + case SST_swapbufferCMD: +// pclog(" start swap buffer command\n"); + + if (TRIPLE_BUFFER) + { + voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; + voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; + } + else + { + voodoo->disp_buffer = !voodoo->disp_buffer; + voodoo->draw_buffer = !voodoo->draw_buffer; + } + voodoo_recalc(voodoo); + + voodoo->params.swapbufferCMD = val; + + pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); +// voodoo->front_offset = params->front_offset; + voodoo_wait_for_render_thread_idle(voodoo); + if (!(val & 1)) + { + memset(voodoo->dirty_line, 1, 1024); + voodoo->front_offset = voodoo->params.front_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + } + else if (TRIPLE_BUFFER) + { + if (voodoo->swap_pending) + voodoo_wait_for_swap_complete(voodoo); + + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->params.front_offset; + voodoo->swap_pending = 1; + } + else + { + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->params.front_offset; + voodoo->swap_pending = 1; + + voodoo_wait_for_swap_complete(voodoo); + } + voodoo->cmd_read++; + break; + + case SST_vertexAx: case SST_remap_vertexAx: + voodoo->params.vertexAx = val & 0xffff; + break; + case SST_vertexAy: case SST_remap_vertexAy: + voodoo->params.vertexAy = val & 0xffff; + break; + case SST_vertexBx: case SST_remap_vertexBx: + voodoo->params.vertexBx = val & 0xffff; + break; + case SST_vertexBy: case SST_remap_vertexBy: + voodoo->params.vertexBy = val & 0xffff; + break; + case SST_vertexCx: case SST_remap_vertexCx: + voodoo->params.vertexCx = val & 0xffff; + break; + case SST_vertexCy: case SST_remap_vertexCy: + voodoo->params.vertexCy = val & 0xffff; + break; + + case SST_startR: case SST_remap_startR: + voodoo->params.startR = val & 0xffffff; + break; + case SST_startG: case SST_remap_startG: + voodoo->params.startG = val & 0xffffff; + break; + case SST_startB: case SST_remap_startB: + voodoo->params.startB = val & 0xffffff; + break; + case SST_startZ: case SST_remap_startZ: + voodoo->params.startZ = val; + break; + case SST_startA: case SST_remap_startA: + voodoo->params.startA = val & 0xffffff; + break; + case SST_startS: case SST_remap_startS: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startS = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startS = ((int64_t)(int32_t)val) << 14; + break; + case SST_startT: case SST_remap_startT: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startT = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startT = ((int64_t)(int32_t)val) << 14; + break; + case SST_startW: case SST_remap_startW: + if (chip & CHIP_FBI) + voodoo->params.startW = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startW = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startW = (int64_t)(int32_t)val << 2; + break; + + case SST_dRdX: case SST_remap_dRdX: + voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dGdX: case SST_remap_dGdX: + voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dBdX: case SST_remap_dBdX: + voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dZdX: case SST_remap_dZdX: + voodoo->params.dZdX = val; + break; + case SST_dAdX: case SST_remap_dAdX: + voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dSdX: case SST_remap_dSdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdX = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdX = ((int64_t)(int32_t)val) << 14; + break; + case SST_dTdX: case SST_remap_dTdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdX = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdX = ((int64_t)(int32_t)val) << 14; + break; + case SST_dWdX: case SST_remap_dWdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdX = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdX = (int64_t)(int32_t)val << 2; + if (chip & CHIP_FBI) + voodoo->params.dWdX = (int64_t)(int32_t)val << 2; + break; + + case SST_dRdY: case SST_remap_dRdY: + voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dGdY: case SST_remap_dGdY: + voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dBdY: case SST_remap_dBdY: + voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dZdY: case SST_remap_dZdY: + voodoo->params.dZdY = val; + break; + case SST_dAdY: case SST_remap_dAdY: + voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dSdY: case SST_remap_dSdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdY = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdY = ((int64_t)(int32_t)val) << 14; + break; + case SST_dTdY: case SST_remap_dTdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdY = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdY = ((int64_t)(int32_t)val) << 14; + break; + case SST_dWdY: case SST_remap_dWdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdY = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdY = (int64_t)(int32_t)val << 2; + if (chip & CHIP_FBI) + voodoo->params.dWdY = (int64_t)(int32_t)val << 2; + break; + + case SST_triangleCMD: case SST_remap_triangleCMD: + voodoo->params.sign = val & (1 << 31); + + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + + voodoo_queue_triangle(voodoo, &voodoo->params); + + voodoo->cmd_read++; + break; + + case SST_fvertexAx: case SST_remap_fvertexAx: + voodoo->fvertexAx.i = val; + voodoo->params.vertexAx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAx.f * 16.0f) & 0xffff; + break; + case SST_fvertexAy: case SST_remap_fvertexAy: + voodoo->fvertexAy.i = val; + voodoo->params.vertexAy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAy.f * 16.0f) & 0xffff; + break; + case SST_fvertexBx: case SST_remap_fvertexBx: + voodoo->fvertexBx.i = val; + voodoo->params.vertexBx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBx.f * 16.0f) & 0xffff; + break; + case SST_fvertexBy: case SST_remap_fvertexBy: + voodoo->fvertexBy.i = val; + voodoo->params.vertexBy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBy.f * 16.0f) & 0xffff; + break; + case SST_fvertexCx: case SST_remap_fvertexCx: + voodoo->fvertexCx.i = val; + voodoo->params.vertexCx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCx.f * 16.0f) & 0xffff; + break; + case SST_fvertexCy: case SST_remap_fvertexCy: + voodoo->fvertexCy.i = val; + voodoo->params.vertexCy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCy.f * 16.0f) & 0xffff; + break; + + case SST_fstartR: case SST_remap_fstartR: + tempif.i = val; + voodoo->params.startR = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartG: case SST_remap_fstartG: + tempif.i = val; + voodoo->params.startG = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartB: case SST_remap_fstartB: + tempif.i = val; + voodoo->params.startB = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartZ: case SST_remap_fstartZ: + tempif.i = val; + voodoo->params.startZ = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartA: case SST_remap_fstartA: + tempif.i = val; + voodoo->params.startA = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartS: case SST_remap_fstartS: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startS = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startS = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fstartT: case SST_remap_fstartT: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startT = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startT = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fstartW: case SST_remap_fstartW: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startW = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startW = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.startW = (int64_t)(tempif.f * 4294967296.0f); + break; + + case SST_fdRdX: case SST_remap_fdRdX: + tempif.i = val; + voodoo->params.dRdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdGdX: case SST_remap_fdGdX: + tempif.i = val; + voodoo->params.dGdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdBdX: case SST_remap_fdBdX: + tempif.i = val; + voodoo->params.dBdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdZdX: case SST_remap_fdZdX: + tempif.i = val; + voodoo->params.dZdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdAdX: case SST_remap_fdAdX: + tempif.i = val; + voodoo->params.dAdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdSdX: case SST_remap_fdSdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdX = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdTdX: case SST_remap_fdTdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdX = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdWdX: case SST_remap_fdWdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.dWdX = (int64_t)(tempif.f * 4294967296.0f); + break; + + case SST_fdRdY: case SST_remap_fdRdY: + tempif.i = val; + voodoo->params.dRdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdGdY: case SST_remap_fdGdY: + tempif.i = val; + voodoo->params.dGdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdBdY: case SST_remap_fdBdY: + tempif.i = val; + voodoo->params.dBdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdZdY: case SST_remap_fdZdY: + tempif.i = val; + voodoo->params.dZdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdAdY: case SST_remap_fdAdY: + tempif.i = val; + voodoo->params.dAdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdSdY: case SST_remap_fdSdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdY = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdTdY: case SST_remap_fdTdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdY = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdWdY: case SST_remap_fdWdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.dWdY = (int64_t)(tempif.f * 4294967296.0f); + break; + + case SST_ftriangleCMD: + voodoo->params.sign = val & (1 << 31); + + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + + voodoo_queue_triangle(voodoo, &voodoo->params); + + voodoo->cmd_read++; + break; + + case SST_fbzColorPath: + voodoo->params.fbzColorPath = val; + voodoo->rgb_sel = val & 3; + break; + + case SST_fogMode: + voodoo->params.fogMode = val; + break; + case SST_alphaMode: + voodoo->params.alphaMode = val; + break; + case SST_fbzMode: + voodoo->params.fbzMode = val; + voodoo_recalc(voodoo); + break; + case SST_lfbMode: + voodoo->lfbMode = val; + voodoo_recalc(voodoo); + break; + + case SST_clipLeftRight: + if (voodoo->type >= VOODOO_2) + { + voodoo->params.clipRight = val & 0xfff; + voodoo->params.clipLeft = (val >> 16) & 0xfff; + } + else + { + voodoo->params.clipRight = val & 0x3ff; + voodoo->params.clipLeft = (val >> 16) & 0x3ff; + } + break; + case SST_clipLowYHighY: + if (voodoo->type >= VOODOO_2) + { + voodoo->params.clipHighY = val & 0xfff; + voodoo->params.clipLowY = (val >> 16) & 0xfff; + } + else + { + voodoo->params.clipHighY = val & 0x3ff; + voodoo->params.clipLowY = (val >> 16) & 0x3ff; + } + break; + + case SST_nopCMD: + voodoo->cmd_read++; + voodoo->fbiPixelsIn = 0; + voodoo->fbiChromaFail = 0; + voodoo->fbiZFuncFail = 0; + voodoo->fbiAFuncFail = 0; + voodoo->fbiPixelsOut = 0; + break; + case SST_fastfillCMD: + voodoo_wait_for_render_thread_idle(voodoo); + voodoo_fastfill(voodoo, &voodoo->params); + voodoo->cmd_read++; + break; + + case SST_fogColor: + voodoo->params.fogColor.r = (val >> 16) & 0xff; + voodoo->params.fogColor.g = (val >> 8) & 0xff; + voodoo->params.fogColor.b = val & 0xff; + break; + + case SST_zaColor: + voodoo->params.zaColor = val; + break; + case SST_chromaKey: + voodoo->params.chromaKey_r = (val >> 16) & 0xff; + voodoo->params.chromaKey_g = (val >> 8) & 0xff; + voodoo->params.chromaKey_b = val & 0xff; + voodoo->params.chromaKey = val & 0xffffff; + break; + case SST_stipple: + voodoo->params.stipple = val; + break; + case SST_color0: + voodoo->params.color0 = val; + break; + case SST_color1: + voodoo->params.color1 = val; + break; + + case SST_fogTable00: case SST_fogTable01: case SST_fogTable02: case SST_fogTable03: + case SST_fogTable04: case SST_fogTable05: case SST_fogTable06: case SST_fogTable07: + case SST_fogTable08: case SST_fogTable09: case SST_fogTable0a: case SST_fogTable0b: + case SST_fogTable0c: case SST_fogTable0d: case SST_fogTable0e: case SST_fogTable0f: + case SST_fogTable10: case SST_fogTable11: case SST_fogTable12: case SST_fogTable13: + case SST_fogTable14: case SST_fogTable15: case SST_fogTable16: case SST_fogTable17: + case SST_fogTable18: case SST_fogTable19: case SST_fogTable1a: case SST_fogTable1b: + case SST_fogTable1c: case SST_fogTable1d: case SST_fogTable1e: case SST_fogTable1f: + addr = (addr - SST_fogTable00) >> 1; + voodoo->params.fogTable[addr].dfog = val & 0xff; + voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; + voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; + voodoo->params.fogTable[addr+1].fog = (val >> 24) & 0xff; + break; + + case SST_clutData: + voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; + if (val & 0x20000000) + { + voodoo->clutData[(val >> 24) & 0x3f].b = 255; + voodoo->clutData[(val >> 24) & 0x3f].g = 255; + voodoo->clutData[(val >> 24) & 0x3f].r = 255; + } + voodoo->clutData_dirty = 1; + break; + + case SST_sSetupMode: + voodoo->sSetupMode = val; + break; + case SST_sVx: + tempif.i = val; + voodoo->verts[3].sVx = tempif.f; +// 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); + voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); + break; + case SST_sRed: + tempif.i = val; + voodoo->verts[3].sRed = tempif.f; + break; + case SST_sGreen: + tempif.i = val; + voodoo->verts[3].sGreen = tempif.f; + break; + case SST_sBlue: + tempif.i = val; + voodoo->verts[3].sBlue = tempif.f; + break; + case SST_sAlpha: + tempif.i = val; + voodoo->verts[3].sAlpha = tempif.f; + break; + case SST_sVz: + tempif.i = val; + voodoo->verts[3].sVz = tempif.f; + break; + case SST_sWb: + tempif.i = val; + voodoo->verts[3].sWb = tempif.f; + break; + case SST_sW0: + tempif.i = val; + voodoo->verts[3].sW0 = tempif.f; + break; + case SST_sS0: + tempif.i = val; + voodoo->verts[3].sS0 = tempif.f; + break; + case SST_sT0: + tempif.i = val; + voodoo->verts[3].sT0 = tempif.f; + break; + case SST_sW1: + tempif.i = val; + voodoo->verts[3].sW1 = tempif.f; + break; + case SST_sS1: + tempif.i = val; + voodoo->verts[3].sS1 = tempif.f; + break; + case SST_sT1: + tempif.i = val; + voodoo->verts[3].sT1 = tempif.f; + break; + + case SST_sBeginTriCMD: +// 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]; + + voodoo->num_verticies++; + voodoo->vertex_num++; + if (voodoo->num_verticies == 3) + { +// pclog("triangle_setup\n"); + voodoo_triangle_setup(voodoo); + + voodoo->num_verticies = 2; + } + if (voodoo->vertex_num == 4) + fatal("sDrawTriCMD overflow\n"); + break; + + case SST_bltSrcBaseAddr: + voodoo->bltSrcBaseAddr = val & 0x3fffff; + break; + case SST_bltDstBaseAddr: +// 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; + voodoo->bltSrcChromaMinB = val & 0x1f; + voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; + voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; + voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; + voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; + voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; + break; + case SST_bltDstChromaRange: + voodoo->bltDstChromaRange = val; + voodoo->bltDstChromaMinB = val & 0x1f; + voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; + voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; + voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; + voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; + voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; + break; + case SST_bltClipX: + voodoo->bltClipRight = val & 0xfff; + voodoo->bltClipLeft = (val >> 16) & 0xfff; + break; + case SST_bltClipY: + voodoo->bltClipHighY = val & 0xfff; + voodoo->bltClipLowY = (val >> 16) & 0xfff; + break; + + case SST_bltSrcXY: + voodoo->bltSrcX = val & 0x7ff; + voodoo->bltSrcY = (val >> 16) & 0x7ff; + break; + case SST_bltDstXY: +// pclog("Write bltDstXY %08x\n", val); + voodoo->bltDstX = val & 0x7ff; + voodoo->bltDstY = (val >> 16) & 0x7ff; + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltSize: +// pclog("Write bltSize %08x\n", val); + voodoo->bltSizeX = val & 0xfff; + if (voodoo->bltSizeX & 0x800) + voodoo->bltSizeX |= 0xfffff000; + voodoo->bltSizeY = (val >> 16) & 0xfff; + if (voodoo->bltSizeY & 0x800) + voodoo->bltSizeY |= 0xfffff000; + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltRop: + voodoo->bltRop[0] = val & 0xf; + voodoo->bltRop[1] = (val >> 4) & 0xf; + voodoo->bltRop[2] = (val >> 8) & 0xf; + voodoo->bltRop[3] = (val >> 12) & 0xf; + break; + case SST_bltColor: +// 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)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltData: + voodoo_v2_blit_data(voodoo, val); + break; + + case SST_textureMode: + if (chip & CHIP_TREX0) + { + voodoo->params.textureMode[0] = val; + voodoo->params.tformat[0] = (val >> 8) & 0xf; + } + if (chip & CHIP_TREX1) + { + voodoo->params.textureMode[1] = val; + voodoo->params.tformat[1] = (val >> 8) & 0xf; + } + break; + case SST_tLOD: + if (chip & CHIP_TREX0) + { + voodoo->params.tLOD[0] = val; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) + { + voodoo->params.tLOD[1] = val; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_tDetail: + if (chip & CHIP_TREX0) + { + voodoo->params.detail_max[0] = val & 0xff; + voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; + voodoo->params.detail_scale[0] = (val >> 14) & 7; + } + if (chip & CHIP_TREX1) + { + voodoo->params.detail_max[1] = val & 0xff; + voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; + voodoo->params.detail_scale[1] = (val >> 14) & 7; + } + break; + case SST_texBaseAddr: + if (chip & CHIP_TREX0) + { + voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) + { + voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr1: + if (chip & CHIP_TREX0) + { + voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) + { + voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr2: + if (chip & CHIP_TREX0) + { + voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) + { + voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr38: + if (chip & CHIP_TREX0) + { + voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) + { + voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + + case SST_trexInit1: + if (chip & CHIP_TREX0) + voodoo->trexInit1[0] = val; + if (chip & CHIP_TREX1) + voodoo->trexInit1[1] = val; + break; + + case SST_nccTable0_Y0: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].y[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].y[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y1: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].y[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].y[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y2: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].y[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].y[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y3: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].y[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].y[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + + case SST_nccTable0_I0: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].i[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].i[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_I2: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q0: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].q[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].q[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q2: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + if (val & (1 << 31)) + { + int p = (val >> 23) & 0xfe; + if (chip & CHIP_TREX0) + { + voodoo->palette[0][p].u = val | 0xff000000; + voodoo->palette_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->palette[1][p].u = val | 0xff000000; + voodoo->palette_dirty[1] = 1; + } + } + break; + + case SST_nccTable0_I1: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].i[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].i[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_I3: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].i[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].i[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q1: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].q[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].q[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q3: + if (!(val & (1 << 31))) + { + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][0].q[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][0].q[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + if (val & (1 << 31)) + { + int p = ((val >> 23) & 0xfe) | 0x01; + if (chip & CHIP_TREX0) + { + voodoo->palette[0][p].u = val | 0xff000000; + voodoo->palette_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->palette[1][p].u = val | 0xff000000; + voodoo->palette_dirty[1] = 1; + } + } + break; + + case SST_nccTable1_Y0: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].y[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].y[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y1: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].y[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].y[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y2: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].y[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].y[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y3: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].y[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].y[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I0: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].i[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].i[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I1: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].i[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].i[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I2: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I3: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].i[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].i[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q0: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].q[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].q[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q1: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].q[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].q[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q2: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].q[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].q[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q3: + if (chip & CHIP_TREX0) + { + voodoo->nccTable[0][1].q[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) + { + voodoo->nccTable[1][1].q[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + + case SST_userIntrCMD: + fatal("userIntrCMD write %08x from FIFO\n", val); + break; + } +} diff --git a/src/vid_voodoo_reg.h b/src/vid_voodoo_reg.h new file mode 100644 index 0000000..f3a9418 --- /dev/null +++ b/src/vid_voodoo_reg.h @@ -0,0 +1 @@ +void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p); diff --git a/src/vid_voodoo_regs.h b/src/vid_voodoo_regs.h new file mode 100644 index 0000000..e065a71 --- /dev/null +++ b/src/vid_voodoo_regs.h @@ -0,0 +1,680 @@ +enum +{ + SST_status = 0x000, + SST_intrCtrl = 0x004, + + SST_vertexAx = 0x008, + SST_vertexAy = 0x00c, + SST_vertexBx = 0x010, + SST_vertexBy = 0x014, + SST_vertexCx = 0x018, + SST_vertexCy = 0x01c, + + SST_startR = 0x0020, + SST_startG = 0x0024, + SST_startB = 0x0028, + SST_startZ = 0x002c, + SST_startA = 0x0030, + SST_startS = 0x0034, + SST_startT = 0x0038, + SST_startW = 0x003c, + + SST_dRdX = 0x0040, + SST_dGdX = 0x0044, + SST_dBdX = 0x0048, + SST_dZdX = 0x004c, + SST_dAdX = 0x0050, + SST_dSdX = 0x0054, + SST_dTdX = 0x0058, + SST_dWdX = 0x005c, + + SST_dRdY = 0x0060, + SST_dGdY = 0x0064, + SST_dBdY = 0x0068, + SST_dZdY = 0x006c, + SST_dAdY = 0x0070, + SST_dSdY = 0x0074, + SST_dTdY = 0x0078, + SST_dWdY = 0x007c, + + SST_triangleCMD = 0x0080, + + SST_fvertexAx = 0x088, + SST_fvertexAy = 0x08c, + SST_fvertexBx = 0x090, + SST_fvertexBy = 0x094, + SST_fvertexCx = 0x098, + SST_fvertexCy = 0x09c, + + SST_fstartR = 0x00a0, + SST_fstartG = 0x00a4, + SST_fstartB = 0x00a8, + SST_fstartZ = 0x00ac, + SST_fstartA = 0x00b0, + SST_fstartS = 0x00b4, + SST_fstartT = 0x00b8, + SST_fstartW = 0x00bc, + + SST_fdRdX = 0x00c0, + SST_fdGdX = 0x00c4, + SST_fdBdX = 0x00c8, + SST_fdZdX = 0x00cc, + SST_fdAdX = 0x00d0, + SST_fdSdX = 0x00d4, + SST_fdTdX = 0x00d8, + SST_fdWdX = 0x00dc, + + SST_fdRdY = 0x00e0, + SST_fdGdY = 0x00e4, + SST_fdBdY = 0x00e8, + SST_fdZdY = 0x00ec, + SST_fdAdY = 0x00f0, + SST_fdSdY = 0x00f4, + SST_fdTdY = 0x00f8, + SST_fdWdY = 0x00fc, + + SST_ftriangleCMD = 0x0100, + + SST_fbzColorPath = 0x104, + SST_fogMode = 0x108, + + SST_alphaMode = 0x10c, + SST_fbzMode = 0x110, + SST_lfbMode = 0x114, + + SST_clipLeftRight = 0x118, + SST_clipLowYHighY = 0x11c, + + SST_nopCMD = 0x120, + SST_fastfillCMD = 0x124, + SST_swapbufferCMD = 0x128, + + SST_fogColor = 0x12c, + SST_zaColor = 0x130, + SST_chromaKey = 0x134, + + SST_userIntrCMD = 0x13c, + SST_stipple = 0x140, + SST_color0 = 0x144, + SST_color1 = 0x148, + + SST_fbiPixelsIn = 0x14c, + SST_fbiChromaFail = 0x150, + SST_fbiZFuncFail = 0x154, + SST_fbiAFuncFail = 0x158, + SST_fbiPixelsOut = 0x15c, + + SST_fogTable00 = 0x160, + SST_fogTable01 = 0x164, + SST_fogTable02 = 0x168, + SST_fogTable03 = 0x16c, + SST_fogTable04 = 0x170, + SST_fogTable05 = 0x174, + SST_fogTable06 = 0x178, + SST_fogTable07 = 0x17c, + SST_fogTable08 = 0x180, + SST_fogTable09 = 0x184, + SST_fogTable0a = 0x188, + SST_fogTable0b = 0x18c, + SST_fogTable0c = 0x190, + SST_fogTable0d = 0x194, + SST_fogTable0e = 0x198, + SST_fogTable0f = 0x19c, + SST_fogTable10 = 0x1a0, + SST_fogTable11 = 0x1a4, + SST_fogTable12 = 0x1a8, + SST_fogTable13 = 0x1ac, + SST_fogTable14 = 0x1b0, + SST_fogTable15 = 0x1b4, + SST_fogTable16 = 0x1b8, + SST_fogTable17 = 0x1bc, + SST_fogTable18 = 0x1c0, + SST_fogTable19 = 0x1c4, + SST_fogTable1a = 0x1c8, + SST_fogTable1b = 0x1cc, + SST_fogTable1c = 0x1d0, + SST_fogTable1d = 0x1d4, + SST_fogTable1e = 0x1d8, + SST_fogTable1f = 0x1dc, + + SST_cmdFifoBaseAddr = 0x1e0, + SST_cmdFifoBump = 0x1e4, + SST_cmdFifoRdPtr = 0x1e8, + SST_cmdFifoAMin = 0x1ec, + SST_cmdFifoAMax = 0x1f0, + SST_cmdFifoDepth = 0x1f4, + SST_cmdFifoHoles = 0x1f8, + + SST_fbiInit4 = 0x200, + SST_vRetrace = 0x204, + SST_backPorch = 0x208, + SST_videoDimensions = 0x20c, + SST_fbiInit0 = 0x210, + SST_fbiInit1 = 0x214, + SST_fbiInit2 = 0x218, + SST_fbiInit3 = 0x21c, + SST_hSync = 0x220, + SST_vSync = 0x224, + SST_clutData = 0x228, + SST_dacData = 0x22c, + + SST_scrFilter = 0x230, + + SST_hvRetrace = 0x240, + SST_fbiInit5 = 0x244, + SST_fbiInit6 = 0x248, + SST_fbiInit7 = 0x24c, + + SST_sSetupMode = 0x260, + SST_sVx = 0x264, + SST_sVy = 0x268, + SST_sARGB = 0x26c, + SST_sRed = 0x270, + SST_sGreen = 0x274, + SST_sBlue = 0x278, + SST_sAlpha = 0x27c, + SST_sVz = 0x280, + SST_sWb = 0x284, + SST_sW0 = 0x288, + SST_sS0 = 0x28c, + SST_sT0 = 0x290, + SST_sW1 = 0x294, + SST_sS1 = 0x298, + SST_sT1 = 0x29c, + + SST_sDrawTriCMD = 0x2a0, + SST_sBeginTriCMD = 0x2a4, + + SST_bltSrcBaseAddr = 0x2c0, + SST_bltDstBaseAddr = 0x2c4, + SST_bltXYStrides = 0x2c8, + SST_bltSrcChromaRange = 0x2cc, + SST_bltDstChromaRange = 0x2d0, + SST_bltClipX = 0x2d4, + SST_bltClipY = 0x2d8, + + SST_bltSrcXY = 0x2e0, + SST_bltDstXY = 0x2e4, + SST_bltSize = 0x2e8, + SST_bltRop = 0x2ec, + SST_bltColor = 0x2f0, + + SST_bltCommand = 0x2f8, + SST_bltData = 0x2fc, + + SST_textureMode = 0x300, + SST_tLOD = 0x304, + SST_tDetail = 0x308, + SST_texBaseAddr = 0x30c, + SST_texBaseAddr1 = 0x310, + SST_texBaseAddr2 = 0x314, + SST_texBaseAddr38 = 0x318, + + SST_trexInit1 = 0x320, + + SST_nccTable0_Y0 = 0x324, + SST_nccTable0_Y1 = 0x328, + SST_nccTable0_Y2 = 0x32c, + SST_nccTable0_Y3 = 0x330, + SST_nccTable0_I0 = 0x334, + SST_nccTable0_I1 = 0x338, + SST_nccTable0_I2 = 0x33c, + SST_nccTable0_I3 = 0x340, + SST_nccTable0_Q0 = 0x344, + SST_nccTable0_Q1 = 0x348, + SST_nccTable0_Q2 = 0x34c, + SST_nccTable0_Q3 = 0x350, + + SST_nccTable1_Y0 = 0x354, + SST_nccTable1_Y1 = 0x358, + SST_nccTable1_Y2 = 0x35c, + SST_nccTable1_Y3 = 0x360, + SST_nccTable1_I0 = 0x364, + SST_nccTable1_I1 = 0x368, + SST_nccTable1_I2 = 0x36c, + SST_nccTable1_I3 = 0x370, + SST_nccTable1_Q0 = 0x374, + SST_nccTable1_Q1 = 0x378, + SST_nccTable1_Q2 = 0x37c, + SST_nccTable1_Q3 = 0x380, + + SST_remap_status = 0x000 | 0x400, + + SST_remap_vertexAx = 0x008 | 0x400, + SST_remap_vertexAy = 0x00c | 0x400, + SST_remap_vertexBx = 0x010 | 0x400, + SST_remap_vertexBy = 0x014 | 0x400, + SST_remap_vertexCx = 0x018 | 0x400, + SST_remap_vertexCy = 0x01c | 0x400, + + SST_remap_startR = 0x0020 | 0x400, + SST_remap_startG = 0x002c | 0x400, + SST_remap_startB = 0x0038 | 0x400, + SST_remap_startZ = 0x0044 | 0x400, + SST_remap_startA = 0x0050 | 0x400, + SST_remap_startS = 0x005c | 0x400, + SST_remap_startT = 0x0068 | 0x400, + SST_remap_startW = 0x0074 | 0x400, + + SST_remap_dRdX = 0x0024 | 0x400, + SST_remap_dGdX = 0x0030 | 0x400, + SST_remap_dBdX = 0x003c | 0x400, + SST_remap_dZdX = 0x0048 | 0x400, + SST_remap_dAdX = 0x0054 | 0x400, + SST_remap_dSdX = 0x0060 | 0x400, + SST_remap_dTdX = 0x006c | 0x400, + SST_remap_dWdX = 0x0078 | 0x400, + + SST_remap_dRdY = 0x0028 | 0x400, + SST_remap_dGdY = 0x0034 | 0x400, + SST_remap_dBdY = 0x0040 | 0x400, + SST_remap_dZdY = 0x004c | 0x400, + SST_remap_dAdY = 0x0058 | 0x400, + SST_remap_dSdY = 0x0064 | 0x400, + SST_remap_dTdY = 0x0070 | 0x400, + SST_remap_dWdY = 0x007c | 0x400, + + SST_remap_triangleCMD = 0x0080 | 0x400, + + SST_remap_fvertexAx = 0x088 | 0x400, + SST_remap_fvertexAy = 0x08c | 0x400, + SST_remap_fvertexBx = 0x090 | 0x400, + SST_remap_fvertexBy = 0x094 | 0x400, + SST_remap_fvertexCx = 0x098 | 0x400, + SST_remap_fvertexCy = 0x09c | 0x400, + + SST_remap_fstartR = 0x00a0 | 0x400, + SST_remap_fstartG = 0x00ac | 0x400, + SST_remap_fstartB = 0x00b8 | 0x400, + SST_remap_fstartZ = 0x00c4 | 0x400, + SST_remap_fstartA = 0x00d0 | 0x400, + SST_remap_fstartS = 0x00dc | 0x400, + SST_remap_fstartT = 0x00e8 | 0x400, + SST_remap_fstartW = 0x00f4 | 0x400, + + SST_remap_fdRdX = 0x00a4 | 0x400, + SST_remap_fdGdX = 0x00b0 | 0x400, + SST_remap_fdBdX = 0x00bc | 0x400, + SST_remap_fdZdX = 0x00c8 | 0x400, + SST_remap_fdAdX = 0x00d4 | 0x400, + SST_remap_fdSdX = 0x00e0 | 0x400, + SST_remap_fdTdX = 0x00ec | 0x400, + SST_remap_fdWdX = 0x00f8 | 0x400, + + SST_remap_fdRdY = 0x00a8 | 0x400, + SST_remap_fdGdY = 0x00b4 | 0x400, + SST_remap_fdBdY = 0x00c0 | 0x400, + SST_remap_fdZdY = 0x00cc | 0x400, + SST_remap_fdAdY = 0x00d8 | 0x400, + SST_remap_fdSdY = 0x00e4 | 0x400, + SST_remap_fdTdY = 0x00f0 | 0x400, + SST_remap_fdWdY = 0x00fc | 0x400, +}; + +enum +{ + LFB_WRITE_FRONT = 0x0000, + LFB_WRITE_BACK = 0x0010, + LFB_WRITE_MASK = 0x0030 +}; + +enum +{ + LFB_READ_FRONT = 0x0000, + LFB_READ_BACK = 0x0040, + LFB_READ_AUX = 0x0080, + LFB_READ_MASK = 0x00c0 +}; + +enum +{ + LFB_FORMAT_RGB565 = 0, + LFB_FORMAT_RGB555 = 1, + LFB_FORMAT_ARGB1555 = 2, + LFB_FORMAT_ARGB8888 = 5, + LFB_FORMAT_DEPTH = 15, + LFB_FORMAT_MASK = 15 +}; + +enum +{ + LFB_WRITE_COLOUR = 1, + LFB_WRITE_DEPTH = 2 +}; + +enum +{ + FBZ_CHROMAKEY = (1 << 1), + FBZ_W_BUFFER = (1 << 3), + FBZ_DEPTH_ENABLE = (1 << 4), + + FBZ_DITHER = (1 << 8), + FBZ_RGB_WMASK = (1 << 9), + FBZ_DEPTH_WMASK = (1 << 10), + FBZ_DITHER_2x2 = (1 << 11), + + FBZ_DRAW_FRONT = 0x0000, + FBZ_DRAW_BACK = 0x4000, + FBZ_DRAW_MASK = 0xc000, + + FBZ_DEPTH_BIAS = (1 << 16), + + FBZ_DEPTH_SOURCE = (1 << 20), + + FBZ_PARAM_ADJUST = (1 << 26) +}; + +enum +{ + TEX_RGB332 = 0x0, + TEX_Y4I2Q2 = 0x1, + TEX_A8 = 0x2, + TEX_I8 = 0x3, + TEX_AI8 = 0x4, + TEX_PAL8 = 0x5, + TEX_APAL8 = 0x6, + TEX_ARGB8332 = 0x8, + TEX_A8Y4I2Q2 = 0x9, + TEX_R5G6B5 = 0xa, + TEX_ARGB1555 = 0xb, + TEX_ARGB4444 = 0xc, + TEX_A8I8 = 0xd, + TEX_APAL88 = 0xe +}; + +enum +{ + TEXTUREMODE_NCC_SEL = (1 << 5), + TEXTUREMODE_TCLAMPS = (1 << 6), + TEXTUREMODE_TCLAMPT = (1 << 7), + TEXTUREMODE_TRILINEAR = (1 << 30) +}; + +enum +{ + FBIINIT0_VGA_PASS = 1, + FBIINIT0_GRAPHICS_RESET = (1 << 1) +}; + +enum +{ + FBIINIT1_MULTI_SST = (1 << 2), /*Voodoo Graphics only*/ + FBIINIT1_VIDEO_RESET = (1 << 8), + FBIINIT1_SLI_ENABLE = (1 << 23) +}; + +enum +{ + FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9) +}; + +enum +{ + FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9), + FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9), + FBIINIT2_SWAP_ALGORITHM_PCI_FIFO_STALL = (2 << 9), + FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9) +}; + +enum +{ + FBIINIT3_REMAP = 1 +}; + +enum +{ + FBIINIT5_MULTI_CVG = (1 << 14) +}; + +enum +{ + FBIINIT7_CMDFIFO_ENABLE = (1 << 8) +}; + +enum +{ + CC_LOCALSELECT_ITER_RGB = 0, + CC_LOCALSELECT_TEX = 1, + CC_LOCALSELECT_COLOR1 = 2, + CC_LOCALSELECT_LFB = 3 +}; + +enum +{ + CCA_LOCALSELECT_ITER_A = 0, + CCA_LOCALSELECT_COLOR0 = 1, + CCA_LOCALSELECT_ITER_Z = 2 +}; + +enum +{ + C_SEL_ITER_RGB = 0, + C_SEL_TEX = 1, + C_SEL_COLOR1 = 2, + C_SEL_LFB = 3 +}; + +enum +{ + A_SEL_ITER_A = 0, + A_SEL_TEX = 1, + A_SEL_COLOR1 = 2, + A_SEL_LFB = 3 +}; + +enum +{ + CC_MSELECT_ZERO = 0, + CC_MSELECT_CLOCAL = 1, + CC_MSELECT_AOTHER = 2, + CC_MSELECT_ALOCAL = 3, + CC_MSELECT_TEX = 4, + CC_MSELECT_TEXRGB = 5 +}; + +enum +{ + CCA_MSELECT_ZERO = 0, + CCA_MSELECT_ALOCAL = 1, + CCA_MSELECT_AOTHER = 2, + CCA_MSELECT_ALOCAL2 = 3, + CCA_MSELECT_TEX = 4 +}; + +enum +{ + TC_MSELECT_ZERO = 0, + TC_MSELECT_CLOCAL = 1, + TC_MSELECT_AOTHER = 2, + TC_MSELECT_ALOCAL = 3, + TC_MSELECT_DETAIL = 4, + TC_MSELECT_LOD_FRAC = 5 +}; + +enum +{ + TCA_MSELECT_ZERO = 0, + TCA_MSELECT_CLOCAL = 1, + TCA_MSELECT_AOTHER = 2, + TCA_MSELECT_ALOCAL = 3, + TCA_MSELECT_DETAIL = 4, + TCA_MSELECT_LOD_FRAC = 5 +}; + +enum +{ + CC_ADD_CLOCAL = 1, + CC_ADD_ALOCAL = 2 +}; + +enum +{ + CCA_ADD_CLOCAL = 1, + CCA_ADD_ALOCAL = 2 +}; + +enum +{ + AFUNC_AZERO = 0x0, + AFUNC_ASRC_ALPHA = 0x1, + AFUNC_A_COLOR = 0x2, + AFUNC_ADST_ALPHA = 0x3, + AFUNC_AONE = 0x4, + AFUNC_AOMSRC_ALPHA = 0x5, + AFUNC_AOM_COLOR = 0x6, + AFUNC_AOMDST_ALPHA = 0x7, + AFUNC_ASATURATE = 0xf +}; + +enum +{ + AFUNC_ACOLORBEFOREFOG = 0xf +}; + +enum +{ + AFUNC_NEVER = 0, + AFUNC_LESSTHAN = 1, + AFUNC_EQUAL = 2, + AFUNC_LESSTHANEQUAL = 3, + AFUNC_GREATERTHAN = 4, + AFUNC_NOTEQUAL = 5, + AFUNC_GREATERTHANEQUAL = 6, + AFUNC_ALWAYS = 7 +}; + +enum +{ + DEPTHOP_NEVER = 0, + DEPTHOP_LESSTHAN = 1, + DEPTHOP_EQUAL = 2, + DEPTHOP_LESSTHANEQUAL = 3, + DEPTHOP_GREATERTHAN = 4, + DEPTHOP_NOTEQUAL = 5, + DEPTHOP_GREATERTHANEQUAL = 6, + DEPTHOP_ALWAYS = 7 +}; + +enum +{ + FOG_ENABLE = 0x01, + FOG_ADD = 0x02, + FOG_MULT = 0x04, + FOG_ALPHA = 0x08, + FOG_Z = 0x10, + FOG_W = 0x18, + FOG_CONSTANT = 0x20 +}; + +enum +{ + LOD_ODD = (1 << 18), + LOD_SPLIT = (1 << 19), + LOD_S_IS_WIDER = (1 << 20), + LOD_TMULTIBASEADDR = (1 << 24), + LOD_TMIRROR_S = (1 << 28), + LOD_TMIRROR_T = (1 << 29) +}; +enum +{ + CMD_INVALID = 0, + CMD_DRAWTRIANGLE, + CMD_FASTFILL, + CMD_SWAPBUF +}; + +enum +{ + FBZCP_TEXTURE_ENABLED = (1 << 27) +}; + +enum +{ + BLTCMD_SRC_TILED = (1 << 14), + BLTCMD_DST_TILED = (1 << 15) +}; + +enum +{ + INITENABLE_SLI_MASTER_SLAVE = (1 << 11) +}; + +enum +{ + SETUPMODE_RGB = (1 << 0), + SETUPMODE_ALPHA = (1 << 1), + SETUPMODE_Z = (1 << 2), + SETUPMODE_Wb = (1 << 3), + SETUPMODE_W0 = (1 << 4), + SETUPMODE_S0_T0 = (1 << 5), + SETUPMODE_W1 = (1 << 6), + SETUPMODE_S1_T1 = (1 << 7), + + SETUPMODE_STRIP_MODE = (1 << 16), + SETUPMODE_CULLING_ENABLE = (1 << 17), + SETUPMODE_CULLING_SIGN = (1 << 18), + SETUPMODE_DISABLE_PINGPONG = (1 << 19) +}; + +#define TEXTUREMODE_MASK 0x3ffff000 +#define TEXTUREMODE_PASSTHROUGH 0 + +#define TEXTUREMODE_LOCAL_MASK 0x00643000 +#define TEXTUREMODE_LOCAL 0x00241000 + + +#define SLI_ENABLED (voodoo->fbiInit1 & FBIINIT1_SLI_ENABLE) +#define TRIPLE_BUFFER ((voodoo->fbiInit2 & 0x10) || (voodoo->fbiInit5 & 0x600) == 0x400) + + +#define _rgb_sel ( params->fbzColorPath & 3) +#define a_sel ( (params->fbzColorPath >> 2) & 3) +#define cc_localselect ( params->fbzColorPath & (1 << 4)) +#define cca_localselect ( (params->fbzColorPath >> 5) & 3) +#define cc_localselect_override ( params->fbzColorPath & (1 << 7)) +#define cc_zero_other ( params->fbzColorPath & (1 << 8)) +#define cc_sub_clocal ( params->fbzColorPath & (1 << 9)) +#define cc_mselect ( (params->fbzColorPath >> 10) & 7) +#define cc_reverse_blend ( params->fbzColorPath & (1 << 13)) +#define cc_add ( (params->fbzColorPath >> 14) & 3) +#define cc_add_alocal ( params->fbzColorPath & (1 << 15)) +#define cc_invert_output ( params->fbzColorPath & (1 << 16)) +#define cca_zero_other ( params->fbzColorPath & (1 << 17)) +#define cca_sub_clocal ( params->fbzColorPath & (1 << 18)) +#define cca_mselect ( (params->fbzColorPath >> 19) & 7) +#define cca_reverse_blend ( params->fbzColorPath & (1 << 22)) +#define cca_add ( (params->fbzColorPath >> 23) & 3) +#define cca_invert_output ( params->fbzColorPath & (1 << 25)) +#define tc_zero_other (params->textureMode[0] & (1 << 12)) +#define tc_sub_clocal (params->textureMode[0] & (1 << 13)) +#define tc_mselect ((params->textureMode[0] >> 14) & 7) +#define tc_reverse_blend (params->textureMode[0] & (1 << 17)) +#define tc_add_clocal (params->textureMode[0] & (1 << 18)) +#define tc_add_alocal (params->textureMode[0] & (1 << 19)) +#define tc_invert_output (params->textureMode[0] & (1 << 20)) +#define tca_zero_other (params->textureMode[0] & (1 << 21)) +#define tca_sub_clocal (params->textureMode[0] & (1 << 22)) +#define tca_mselect ((params->textureMode[0] >> 23) & 7) +#define tca_reverse_blend (params->textureMode[0] & (1 << 26)) +#define tca_add_clocal (params->textureMode[0] & (1 << 27)) +#define tca_add_alocal (params->textureMode[0] & (1 << 28)) +#define tca_invert_output (params->textureMode[0] & (1 << 29)) + +#define tc_sub_clocal_1 (params->textureMode[1] & (1 << 13)) +#define tc_mselect_1 ((params->textureMode[1] >> 14) & 7) +#define tc_reverse_blend_1 (params->textureMode[1] & (1 << 17)) +#define tc_add_clocal_1 (params->textureMode[1] & (1 << 18)) +#define tc_add_alocal_1 (params->textureMode[1] & (1 << 19)) +#define tca_sub_clocal_1 (params->textureMode[1] & (1 << 22)) +#define tca_mselect_1 ((params->textureMode[1] >> 23) & 7) +#define tca_reverse_blend_1 (params->textureMode[1] & (1 << 26)) +#define tca_add_clocal_1 (params->textureMode[1] & (1 << 27)) +#define tca_add_alocal_1 (params->textureMode[1] & (1 << 28)) + +#define src_afunc ( (params->alphaMode >> 8) & 0xf) +#define dest_afunc ( (params->alphaMode >> 12) & 0xf) +#define alpha_func ( (params->alphaMode >> 1) & 7) +#define a_ref ( params->alphaMode >> 24) +#define depth_op ( (params->fbzMode >> 5) & 7) +#define dither ( params->fbzMode & FBZ_DITHER) +#define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c new file mode 100644 index 0000000..641e8e2 --- /dev/null +++ b/src/vid_voodoo_render.c @@ -0,0 +1,1608 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_dither.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_texture.h" + +typedef struct voodoo_state_t +{ + int xstart, xend, xdir; + uint32_t base_r, base_g, base_b, base_a, base_z; + struct + { + int64_t base_s, base_t, base_w; + int lod; + } tmu[2]; + int64_t base_w; + int lod; + int lod_min[2], lod_max[2]; + int dx1, dx2; + int y, yend, ydir; + int32_t dxAB, dxAC, dxBC; + int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; + int tex_s, tex_t; + int clamp_s[2], clamp_t[2]; + + int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; + + uint32_t *tex[2][LOD_MAX+1]; + int tformat; + + int *tex_w_mask[2]; + int *tex_h_mask[2]; + int *tex_shift[2]; + int *tex_lod[2]; + + uint16_t *fb_mem, *aux_mem; + + int32_t ib, ig, ir, ia; + int32_t z; + + int32_t new_depth; + + int64_t tmu0_s, tmu0_t; + int64_t tmu0_w; + int64_t tmu1_s, tmu1_t; + int64_t tmu1_w; + int64_t w; + + int pixel_count, texel_count; + int x, x2; + + uint32_t w_depth; + + float log_temp; + uint32_t ebp_store; + uint32_t texBaseAddr; + + int lod_frac[2]; +} voodoo_state_t; + +static int voodoo_output = 0; + +static uint8_t logtable[256] = +{ + 0x00,0x01,0x02,0x04,0x05,0x07,0x08,0x09,0x0b,0x0c,0x0e,0x0f,0x10,0x12,0x13,0x15, + 0x16,0x17,0x19,0x1a,0x1b,0x1d,0x1e,0x1f,0x21,0x22,0x23,0x25,0x26,0x27,0x28,0x2a, + 0x2b,0x2c,0x2e,0x2f,0x30,0x31,0x33,0x34,0x35,0x36,0x38,0x39,0x3a,0x3b,0x3d,0x3e, + 0x3f,0x40,0x41,0x43,0x44,0x45,0x46,0x47,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x50,0x51, + 0x52,0x53,0x54,0x55,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x60,0x61,0x62,0x63, + 0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74, + 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x83,0x84,0x85, + 0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94, + 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa2,0xa3, + 0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xad,0xae,0xaf,0xb0,0xb1,0xb2, + 0xb3,0xb4,0xb5,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbc,0xbd,0xbe,0xbf,0xc0, + 0xc1,0xc2,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xcd, + 0xce,0xcf,0xd0,0xd1,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd6,0xd7,0xd8,0xd9,0xda,0xda, + 0xdb,0xdc,0xdd,0xde,0xde,0xdf,0xe0,0xe1,0xe1,0xe2,0xe3,0xe4,0xe5,0xe5,0xe6,0xe7, + 0xe8,0xe8,0xe9,0xea,0xeb,0xeb,0xec,0xed,0xee,0xef,0xef,0xf0,0xf1,0xf2,0xf2,0xf3, + 0xf4,0xf5,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff +}; + +static inline int fastlog(uint64_t val) +{ + uint64_t oldval = val; + int exp = 63; + int frac; + + if (!val || val & (1ULL << 63)) + return 0x80000000; + + if (!(val & 0xffffffff00000000)) + { + exp -= 32; + val <<= 32; + } + if (!(val & 0xffff000000000000)) + { + exp -= 16; + val <<= 16; + } + if (!(val & 0xff00000000000000)) + { + exp -= 8; + val <<= 8; + } + if (!(val & 0xf000000000000000)) + { + exp -= 4; + val <<= 4; + } + if (!(val & 0xc000000000000000)) + { + exp -= 2; + val <<= 2; + } + if (!(val & 0x8000000000000000)) + { + exp -= 1; + val <<= 1; + } + + if (exp >= 8) + frac = (oldval >> (exp - 8)) & 0xff; + else + frac = (oldval << (8 - exp)) & 0xff; + + return (exp << 8) | logtable[frac]; +} + +static inline int voodoo_fls(uint16_t val) +{ + int num = 0; + +//pclog("fls(%04x) = ", val); + if (!(val & 0xff00)) + { + num += 8; + val <<= 8; + } + if (!(val & 0xf000)) + { + num += 4; + val <<= 4; + } + if (!(val & 0xc000)) + { + num += 2; + val <<= 2; + } + if (!(val & 0x8000)) + { + num += 1; + val <<= 1; + } +//pclog("%i %04x\n", num, val); + return num; +} + +typedef struct voodoo_texture_state_t +{ + int s, t; + int w_mask, h_mask; + int tex_shift; +} voodoo_texture_state_t; + +static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) +{ + uint32_t dat; + + if (texture_state->s & ~texture_state->w_mask) + { + if (state->clamp_s[tmu]) + { + if (texture_state->s < 0) + texture_state->s = 0; + if (texture_state->s > texture_state->w_mask) + texture_state->s = texture_state->w_mask; + } + else + texture_state->s &= texture_state->w_mask; + } + if (texture_state->t & ~texture_state->h_mask) + { + if (state->clamp_t[tmu]) + { + if (texture_state->t < 0) + texture_state->t = 0; + if (texture_state->t > texture_state->h_mask) + texture_state->t = texture_state->h_mask; + } + else + texture_state->t &= texture_state->h_mask; + } + + dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; + + state->tex_b[tmu] = dat & 0xff; + state->tex_g[tmu] = (dat >> 8) & 0xff; + state->tex_r[tmu] = (dat >> 16) & 0xff; + state->tex_a[tmu] = (dat >> 24) & 0xff; +} + +#define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) +#define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) + +static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) +{ + rgba_u dat[4]; + + if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) + { + int c; + for (c = 0; c < 4; c++) + { + int _s = s + (c & 1); + int _t = t + ((c & 2) >> 1); + + if (_s & ~texture_state->w_mask) + { + if (state->clamp_s[tmu]) + { + if (_s < 0) + _s = 0; + if (_s > texture_state->w_mask) + _s = texture_state->w_mask; + } + else + _s &= texture_state->w_mask; + } + if (_t & ~texture_state->h_mask) + { + if (state->clamp_t[tmu]) + { + if (_t < 0) + _t = 0; + if (_t > texture_state->h_mask) + _t = texture_state->h_mask; + } + else + _t &= texture_state->h_mask; + } + dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; + } + } + else + { + dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; + dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; + dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; + dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; + } + + state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; + state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; + state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; + state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; +} + +static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +{ + voodoo_texture_state_t texture_state; + int d[4]; + int s, t; + int tex_lod = state->tex_lod[tmu][state->lod]; + + texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; + texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; + texture_state.tex_shift = 8 - tex_lod; + + if (params->tLOD[tmu] & LOD_TMIRROR_S) + { + if (state->tex_s & 0x1000) + state->tex_s = ~state->tex_s; + } + if (params->tLOD[tmu] & LOD_TMIRROR_T) + { + if (state->tex_t & 0x1000) + state->tex_t = ~state->tex_t; + } + + if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) + { + int _ds, dt; + + state->tex_s -= 1 << (3+tex_lod); + state->tex_t -= 1 << (3+tex_lod); + + s = state->tex_s >> tex_lod; + t = state->tex_t >> tex_lod; + + _ds = s & 0xf; + dt = t & 0xf; + + s >>= 4; + t >>= 4; +//if (x == 80) +//if (voodoo_output) +// 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) +{ + if (params->textureMode[tmu] & 1) + { + int64_t _w = 0; + + if (tmu) + { + if (state->tmu1_w) + _w = (int64_t)((1ULL << 48) / state->tmu1_w); + state->tex_s = (int32_t)(((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + state->tex_t = (int32_t)(((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + } + else + { + if (state->tmu0_w) + _w = (int64_t)((1ULL << 48) / state->tmu0_w); + state->tex_s = (int32_t)(((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + state->tex_t = (int32_t)(((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + } + + state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); + } + else + { + if (tmu) + { + state->tex_s = (int32_t)(state->tmu1_s >> (14+14)); + state->tex_t = (int32_t)(state->tmu1_t >> (14+14)); + } + else + { + state->tex_s = (int32_t)(state->tmu0_s >> (14+14)); + state->tex_t = (int32_t)(state->tmu0_t >> (14+14)); + } + state->lod = state->tmu[tmu].lod; + } + + if (state->lod < state->lod_min[tmu]) + state->lod = state->lod_min[tmu]; + else if (state->lod > state->lod_max[tmu]) + state->lod = state->lod_max[tmu]; + state->lod_frac[tmu] = state->lod & 0xff; + state->lod >>= 8; + + voodoo_get_texture(voodoo, params, state, tmu, x); +} + + +/*Perform texture fetch and blending for both TMUs*/ +static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) +{ + int r,g,b,a; + int c_reverse, a_reverse; +// int c_reverse1, a_reverse1; + int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; + + voodoo_tmu_fetch(voodoo, params, state, 1, x); + + if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) + { + c_reverse = tc_reverse_blend; + a_reverse = tca_reverse_blend; + } + else + { + c_reverse = !tc_reverse_blend; + a_reverse = !tca_reverse_blend; + } +/* c_reverse1 = c_reverse; + a_reverse1 = a_reverse;*/ + if (tc_sub_clocal_1) + { + switch (tc_mselect_1) + { + case TC_MSELECT_ZERO: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_CLOCAL: + factor_r = state->tex_r[1]; + factor_g = state->tex_g[1]; + factor_b = state->tex_b[1]; + break; + case TC_MSELECT_AOTHER: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_ALOCAL: + factor_r = factor_g = factor_b = state->tex_a[1]; + break; + case TC_MSELECT_DETAIL: + factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; + if (factor_r > params->detail_max[1]) + factor_r = params->detail_max[1]; + factor_g = factor_b = factor_r; + break; + case TC_MSELECT_LOD_FRAC: + factor_r = factor_g = factor_b = state->lod_frac[1]; + break; + } + if (!c_reverse) + { + r = (-state->tex_r[1] * (factor_r + 1)) >> 8; + g = (-state->tex_g[1] * (factor_g + 1)) >> 8; + b = (-state->tex_b[1] * (factor_b + 1)) >> 8; + } + else + { + r = (-state->tex_r[1] * ((factor_r^0xff) + 1)) >> 8; + g = (-state->tex_g[1] * ((factor_g^0xff) + 1)) >> 8; + b = (-state->tex_b[1] * ((factor_b^0xff) + 1)) >> 8; + } + if (tc_add_clocal_1) + { + r += state->tex_r[1]; + g += state->tex_g[1]; + b += state->tex_b[1]; + } + else if (tc_add_alocal_1) + { + r += state->tex_a[1]; + g += state->tex_a[1]; + b += state->tex_a[1]; + } + state->tex_r[1] = CLAMP(r); + state->tex_g[1] = CLAMP(g); + state->tex_b[1] = CLAMP(b); + } + if (tca_sub_clocal_1) + { + switch (tca_mselect_1) + { + case TCA_MSELECT_ZERO: + factor_a = 0; + break; + case TCA_MSELECT_CLOCAL: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_AOTHER: + factor_a = 0; + break; + case TCA_MSELECT_ALOCAL: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_DETAIL: + factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; + if (factor_a > params->detail_max[1]) + factor_a = params->detail_max[1]; + break; + case TCA_MSELECT_LOD_FRAC: + factor_a = state->lod_frac[1]; + break; + } + if (!a_reverse) + a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; + else + a = (-state->tex_a[1] * (factor_a + 1)) >> 8; + if (tca_add_clocal_1 || tca_add_alocal_1) + a += state->tex_a[1]; + state->tex_a[1] = CLAMP(a); + } + + + voodoo_tmu_fetch(voodoo, params, state, 0, x); + + if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) + { + c_reverse = tc_reverse_blend; + a_reverse = tca_reverse_blend; + } + else + { + c_reverse = !tc_reverse_blend; + a_reverse = !tca_reverse_blend; + } + + if (!tc_zero_other) + { + r = state->tex_r[1]; + g = state->tex_g[1]; + b = state->tex_b[1]; + } + else + r = g = b = 0; + if (tc_sub_clocal) + { + r -= state->tex_r[0]; + g -= state->tex_g[0]; + b -= state->tex_b[0]; + } + switch (tc_mselect) + { + case TC_MSELECT_ZERO: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_CLOCAL: + factor_r = state->tex_r[0]; + factor_g = state->tex_g[0]; + factor_b = state->tex_b[0]; + break; + case TC_MSELECT_AOTHER: + factor_r = factor_g = factor_b = state->tex_a[1]; + break; + case TC_MSELECT_ALOCAL: + factor_r = factor_g = factor_b = state->tex_a[0]; + break; + case TC_MSELECT_DETAIL: + factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; + if (factor_r > params->detail_max[0]) + factor_r = params->detail_max[0]; + factor_g = factor_b = factor_r; + break; + case TC_MSELECT_LOD_FRAC: + factor_r = factor_g = factor_b = state->lod_frac[0]; + break; + } + if (!c_reverse) + { + r = (r * (factor_r + 1)) >> 8; + g = (g * (factor_g + 1)) >> 8; + b = (b * (factor_b + 1)) >> 8; + } + else + { + r = (r * ((factor_r^0xff) + 1)) >> 8; + g = (g * ((factor_g^0xff) + 1)) >> 8; + b = (b * ((factor_b^0xff) + 1)) >> 8; + } + if (tc_add_clocal) + { + r += state->tex_r[0]; + g += state->tex_g[0]; + b += state->tex_b[0]; + } + else if (tc_add_alocal) + { + r += state->tex_a[0]; + g += state->tex_a[0]; + b += state->tex_a[0]; + } + + if (!tca_zero_other) + a = state->tex_a[1]; + else + a = 0; + if (tca_sub_clocal) + a -= state->tex_a[0]; + switch (tca_mselect) + { + case TCA_MSELECT_ZERO: + factor_a = 0; + break; + case TCA_MSELECT_CLOCAL: + factor_a = state->tex_a[0]; + break; + case TCA_MSELECT_AOTHER: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_ALOCAL: + factor_a = state->tex_a[0]; + break; + case TCA_MSELECT_DETAIL: + factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; + if (factor_a > params->detail_max[0]) + factor_a = params->detail_max[0]; + break; + case TCA_MSELECT_LOD_FRAC: + factor_a = state->lod_frac[0]; + break; + } + if (a_reverse) + a = (a * ((factor_a ^ 0xff) + 1)) >> 8; + else + a = (a * (factor_a + 1)) >> 8; + if (tca_add_clocal || tca_add_alocal) + a += state->tex_a[0]; + + + state->tex_r[0] = CLAMP(r); + state->tex_g[0] = CLAMP(g); + state->tex_b[0] = CLAMP(b); + state->tex_a[0] = CLAMP(a); + + if (tc_invert_output) + { + state->tex_r[0] ^= 0xff; + state->tex_g[0] ^= 0xff; + state->tex_b[0] ^= 0xff; + } + if (tca_invert_output) + state->tex_a[0] ^= 0xff; +} + +#if (defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__) +#include "vid_voodoo_codegen_x86.h" +#elif (defined __amd64__) +#include "vid_voodoo_codegen_x86-64.h" +#else +int voodoo_recomp = 0; +#endif + +static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) +{ +/* int rgb_sel = params->fbzColorPath & 3; + int a_sel = (params->fbzColorPath >> 2) & 3; + int cc_localselect = params->fbzColorPath & (1 << 4); + int cca_localselect = (params->fbzColorPath >> 5) & 3; + int cc_localselect_override = params->fbzColorPath & (1 << 7); + int cc_zero_other = params->fbzColorPath & (1 << 8); + int cc_sub_clocal = params->fbzColorPath & (1 << 9); + int cc_mselect = (params->fbzColorPath >> 10) & 7; + int cc_reverse_blend = params->fbzColorPath & (1 << 13); + int cc_add = (params->fbzColorPath >> 14) & 3; + int cc_add_alocal = params->fbzColorPath & (1 << 15); + int cc_invert_output = params->fbzColorPath & (1 << 16); + int cca_zero_other = params->fbzColorPath & (1 << 17); + int cca_sub_clocal = params->fbzColorPath & (1 << 18); + int cca_mselect = (params->fbzColorPath >> 19) & 7; + int cca_reverse_blend = params->fbzColorPath & (1 << 22); + int cca_add = (params->fbzColorPath >> 23) & 3; + int cca_invert_output = params->fbzColorPath & (1 << 25); + int src_afunc = (params->alphaMode >> 8) & 0xf; + int dest_afunc = (params->alphaMode >> 12) & 0xf; + int alpha_func = (params->alphaMode >> 1) & 7; + int a_ref = params->alphaMode >> 24; + int depth_op = (params->fbzMode >> 5) & 7; + int dither = params->fbzMode & FBZ_DITHER;*/ + int texels; + int c; +#ifndef NO_CODEGEN + uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); +#endif + int y_diff = SLI_ENABLED ? 2 : 1; + + if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || + (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) + texels = 1; + else + texels = 2; + + state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; + state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; + state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; + state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; +// int last_x; +// 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++) + { + state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; + state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; + } + + state->tformat = params->tformat[0]; + + state->tex_w_mask[0] = params->tex_w_mask[0]; + state->tex_h_mask[0] = params->tex_h_mask[0]; + state->tex_shift[0] = params->tex_shift[0]; + state->tex_lod[0] = params->tex_lod[0]; + state->tex_w_mask[1] = params->tex_w_mask[1]; + state->tex_h_mask[1] = params->tex_h_mask[1]; + state->tex_shift[1] = params->tex_shift[1]; + state->tex_lod[1] = params->tex_lod[1]; + + if ((params->fbzMode & 1) && (ystart < params->clipLowY)) + { + int dy = params->clipLowY - ystart; + + state->base_r += params->dRdY*dy; + state->base_g += params->dGdY*dy; + state->base_b += params->dBdY*dy; + state->base_a += params->dAdY*dy; + state->base_z += params->dZdY*dy; + state->tmu[0].base_s += params->tmu[0].dSdY*dy; + state->tmu[0].base_t += params->tmu[0].dTdY*dy; + state->tmu[0].base_w += params->tmu[0].dWdY*dy; + state->tmu[1].base_s += params->tmu[1].dSdY*dy; + state->tmu[1].base_t += params->tmu[1].dTdY*dy; + state->tmu[1].base_w += params->tmu[1].dWdY*dy; + state->base_w += params->dWdY*dy; + state->xstart += state->dx1*dy; + state->xend += state->dx2*dy; + + ystart = params->clipLowY; + } + + if ((params->fbzMode & 1) && (yend >= params->clipHighY)) + yend = params->clipHighY-1; + + state->y = ystart; +// yend--; + + if (SLI_ENABLED) + { + int test_y; + + if (params->fbzMode & (1 << 17)) + test_y = (voodoo->v_disp-1) - state->y; + else + test_y = state->y; + + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) + { + state->y++; + + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } + } +#ifndef NO_CODEGEN + if (voodoo->use_recompiler) + voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); + else + voodoo_draw = NULL; +#endif + + if (voodoo_output) + 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 += y_diff) + { + int x, x2; + int real_y = (state->y << 4) + 8; + int start_x, start_x2; + int dx; + uint16_t *fb_mem, *aux_mem; + + state->ir = state->base_r; + state->ig = state->base_g; + state->ib = state->base_b; + state->ia = state->base_a; + state->z = state->base_z; + state->tmu0_s = state->tmu[0].base_s; + state->tmu0_t = state->tmu[0].base_t; + state->tmu0_w = state->tmu[0].base_w; + state->tmu1_s = state->tmu[1].base_s; + state->tmu1_t = state->tmu[1].base_t; + state->tmu1_w = state->tmu[1].base_w; + state->w = state->base_w; + + x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); + + if (real_y < state->vertexBy) + x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); + else + x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); + + if (params->fbzMode & (1 << 17)) + real_y = (voodoo->v_disp-1) - (real_y >> 4); + else + real_y >>= 4; + + if (SLI_ENABLED) + { + if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) + goto next_line; + } + else + { + if ((real_y & voodoo->odd_even_mask) != odd_even) + goto next_line; + } + + start_x = x; + + if (state->xdir > 0) + x2 -= (1 << 16); + else + x -= (1 << 16); + dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); + start_x2 = x + 0x7000; + x = (x + 0x7000) >> 16; + x2 = (x2 + 0x7000) >> 16; + + if (voodoo_output) + pclog("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); + + state->ir += (params->dRdX * dx); + state->ig += (params->dGdX * dx); + state->ib += (params->dBdX * dx); + state->ia += (params->dAdX * dx); + state->z += (params->dZdX * dx); + state->tmu0_s += (params->tmu[0].dSdX * dx); + state->tmu0_t += (params->tmu[0].dTdX * dx); + state->tmu0_w += (params->tmu[0].dWdX * dx); + state->tmu1_s += (params->tmu[1].dSdX * dx); + state->tmu1_t += (params->tmu[1].dTdX * dx); + state->tmu1_w += (params->tmu[1].dWdX * dx); + state->w += (params->dWdX * dx); + + if (voodoo_output) + 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) + { + if (state->xdir > 0) + { + if (x < params->clipLeft) + { + int dx = params->clipLeft - x; + + state->ir += params->dRdX*dx; + state->ig += params->dGdX*dx; + state->ib += params->dBdX*dx; + state->ia += params->dAdX*dx; + state->z += params->dZdX*dx; + state->tmu0_s += params->tmu[0].dSdX*dx; + state->tmu0_t += params->tmu[0].dTdX*dx; + state->tmu0_w += params->tmu[0].dWdX*dx; + state->tmu1_s += params->tmu[1].dSdX*dx; + state->tmu1_t += params->tmu[1].dTdX*dx; + state->tmu1_w += params->tmu[1].dWdX*dx; + state->w += params->dWdX*dx; + + x = params->clipLeft; + } + if (x2 >= params->clipRight) + x2 = params->clipRight-1; + } + else + { + if (x >= params->clipRight) + { + int dx = (params->clipRight-1) - x; + + state->ir += params->dRdX*dx; + state->ig += params->dGdX*dx; + state->ib += params->dBdX*dx; + state->ia += params->dAdX*dx; + state->z += params->dZdX*dx; + state->tmu0_s += params->tmu[0].dSdX*dx; + state->tmu0_t += params->tmu[0].dTdX*dx; + state->tmu0_w += params->tmu[0].dWdX*dx; + state->tmu1_s += params->tmu[1].dSdX*dx; + state->tmu1_t += params->tmu[1].dTdX*dx; + state->tmu1_w += params->tmu[1].dWdX*dx; + state->w += params->dWdX*dx; + + x = params->clipRight-1; + } + if (x2 < params->clipLeft) + x2 = params->clipLeft; + } + } + + if (x2 < x && state->xdir > 0) + goto next_line; + if (x2 > x && state->xdir < 0) + goto next_line; + + if (SLI_ENABLED) + { + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * voodoo->row_width)]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * voodoo->row_width)) & voodoo->fb_mask]; + } + else + { + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; + } + + if (voodoo_output) + 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); + + state->pixel_count = 0; + state->texel_count = 0; + state->x = x; + state->x2 = x2; +#ifndef NO_CODEGEN + if (voodoo->use_recompiler) + { + voodoo_draw(state, params, x, real_y); + } + else +#endif + do + { + start_x = x; + state->x = x; + voodoo->pixel_count[odd_even]++; + voodoo->texel_count[odd_even] += texels; + voodoo->fbiPixelsIn++; + + if (voodoo_output) + 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 = 0, src_g = 0, src_b = 0, src_a = 0; + int msel_r, msel_g, msel_b, msel_a; + uint8_t dest_r, dest_g, dest_b, dest_a; + uint16_t dat; + int sel; + int32_t new_depth, w_depth; + + if (state->w & 0xffff00000000) + w_depth = 0; + else if (!(state->w & 0xffff0000)) + w_depth = 0xf001; + else + { + int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); + int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; + w_depth = (exp << 12) + mant + 1; + if (w_depth > 0xffff) + w_depth = 0xffff; + } + +// w_depth = CLAMP16(w_depth); + + if (params->fbzMode & FBZ_W_BUFFER) + new_depth = w_depth; + else + new_depth = CLAMP16(state->z >> 12); + + if (params->fbzMode & FBZ_DEPTH_BIAS) + new_depth = CLAMP16(new_depth + (int16_t)params->zaColor); + + if (params->fbzMode & FBZ_DEPTH_ENABLE) + { + uint16_t old_depth = aux_mem[x]; + + DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); + } + + dat = fb_mem[x]; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; + + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) + { + if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) + { + /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ + voodoo_tmu_fetch(voodoo, params, state, 0, x); + } + else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) + { + /*TMU0 in pass-through mode, only sample TMU1*/ + voodoo_tmu_fetch(voodoo, params, state, 1, x); + + state->tex_r[0] = state->tex_r[1]; + state->tex_g[0] = state->tex_g[1]; + state->tex_b[0] = state->tex_b[1]; + state->tex_a[0] = state->tex_a[1]; + } + else + { + voodoo_tmu_fetch_and_blend(voodoo, params, state, x); + } + + if ((params->fbzMode & FBZ_CHROMAKEY) && + state->tex_r[0] == params->chromaKey_r && + state->tex_g[0] == params->chromaKey_g && + state->tex_b[0] == params->chromaKey_b) + { + voodoo->fbiChromaFail++; + goto skip_pixel; + } + } + + if (voodoo->trexInit1[0] & (1 << 18)) + { + state->tex_r[0] = state->tex_g[0] = 0; + state->tex_b[0] = voodoo->tmuConfig; + } + + if (cc_localselect_override) + sel = (state->tex_a[0] & 0x80) ? 1 : 0; + else + sel = cc_localselect; + + if (sel) + { + clocal_r = (params->color0 >> 16) & 0xff; + clocal_g = (params->color0 >> 8) & 0xff; + clocal_b = params->color0 & 0xff; + } + else + { + clocal_r = CLAMP(state->ir >> 12); + clocal_g = CLAMP(state->ig >> 12); + clocal_b = CLAMP(state->ib >> 12); + } + + switch (_rgb_sel) + { + case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ + cother_r = CLAMP(state->ir >> 12); + cother_g = CLAMP(state->ig >> 12); + cother_b = CLAMP(state->ib >> 12); + break; + + case CC_LOCALSELECT_TEX: /*TREX Color Output*/ + cother_r = state->tex_r[0]; + cother_g = state->tex_g[0]; + cother_b = state->tex_b[0]; + break; + + case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ + cother_r = (params->color1 >> 16) & 0xff; + cother_g = (params->color1 >> 8) & 0xff; + cother_b = params->color1 & 0xff; + break; + + case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ + cother_r = src_r; + cother_g = src_g; + cother_b = src_b; + break; + } + + switch (cca_localselect) + { + case CCA_LOCALSELECT_ITER_A: + alocal = CLAMP(state->ia >> 12); + break; + + case CCA_LOCALSELECT_COLOR0: + alocal = (params->color0 >> 24) & 0xff; + break; + + case CCA_LOCALSELECT_ITER_Z: + alocal = CLAMP(state->z >> 20); + break; + + default: + fatal("Bad cca_localselect %i\n", cca_localselect); + alocal = 0xff; + break; + } + + switch (a_sel) + { + case A_SEL_ITER_A: + aother = CLAMP(state->ia >> 12); + break; + case A_SEL_TEX: + aother = state->tex_a[0]; + break; + case A_SEL_COLOR1: + aother = (params->color1 >> 24) & 0xff; + break; + default: + fatal("Bad a_sel %i\n", a_sel); + aother = 0; + break; + } + + if (cc_zero_other) + { + src_r = 0; + src_g = 0; + src_b = 0; + } + else + { + src_r = cother_r; + src_g = cother_g; + src_b = cother_b; + } + + if (cca_zero_other) + src_a = 0; + else + src_a = aother; + + if (cc_sub_clocal) + { + src_r -= clocal_r; + src_g -= clocal_g; + src_b -= clocal_b; + } + + if (cca_sub_clocal) + src_a -= alocal; + + switch (cc_mselect) + { + case CC_MSELECT_ZERO: + msel_r = 0; + msel_g = 0; + msel_b = 0; + break; + case CC_MSELECT_CLOCAL: + msel_r = clocal_r; + msel_g = clocal_g; + msel_b = clocal_b; + break; + case CC_MSELECT_AOTHER: + msel_r = aother; + msel_g = aother; + msel_b = aother; + break; + case CC_MSELECT_ALOCAL: + msel_r = alocal; + msel_g = alocal; + msel_b = alocal; + break; + case CC_MSELECT_TEX: + msel_r = state->tex_a[0]; + msel_g = state->tex_a[0]; + msel_b = state->tex_a[0]; + break; + case CC_MSELECT_TEXRGB: + msel_r = state->tex_r[0]; + msel_g = state->tex_g[0]; + msel_b = state->tex_b[0]; + break; + + default: + fatal("Bad cc_mselect %i\n", cc_mselect); + msel_r = 0; + msel_g = 0; + msel_b = 0; + break; + } + + switch (cca_mselect) + { + case CCA_MSELECT_ZERO: + msel_a = 0; + break; + case CCA_MSELECT_ALOCAL: + msel_a = alocal; + break; + case CCA_MSELECT_AOTHER: + msel_a = aother; + break; + case CCA_MSELECT_ALOCAL2: + msel_a = alocal; + break; + case CCA_MSELECT_TEX: + msel_a = state->tex_a[0]; + break; + + default: + fatal("Bad cca_mselect %i\n", cca_mselect); + msel_a = 0; + break; + } + + if (!cc_reverse_blend) + { + msel_r ^= 0xff; + msel_g ^= 0xff; + msel_b ^= 0xff; + } + msel_r++; + msel_g++; + msel_b++; + + if (!cca_reverse_blend) + msel_a ^= 0xff; + msel_a++; + + src_r = (src_r * msel_r) >> 8; + src_g = (src_g * msel_g) >> 8; + src_b = (src_b * msel_b) >> 8; + src_a = (src_a * msel_a) >> 8; + + switch (cc_add) + { + case CC_ADD_CLOCAL: + src_r += clocal_r; + src_g += clocal_g; + src_b += clocal_b; + break; + case CC_ADD_ALOCAL: + src_r += alocal; + src_g += alocal; + src_b += alocal; + break; + case 0: + break; + default: + fatal("Bad cc_add %i\n", cc_add); + } + + if (cca_add) + src_a += alocal; + + src_r = CLAMP(src_r); + src_g = CLAMP(src_g); + src_b = CLAMP(src_b); + src_a = CLAMP(src_a); + + if (cc_invert_output) + { + src_r ^= 0xff; + src_g ^= 0xff; + src_b ^= 0xff; + } + if (cca_invert_output) + src_a ^= 0xff; + + if (params->fogMode & FOG_ENABLE) + APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); + + if (params->alphaMode & 1) + ALPHA_TEST(src_a); + + if (params->alphaMode & (1 << 4)) + ALPHA_BLEND(src_r, src_g, src_b, src_a); + + if (update) + { + if (dither) + { + if (dither2x2) + { + src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; + src_g = dither_g2x2[src_g][real_y & 1][x & 1]; + src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; + } + else + { + src_r = dither_rb[src_r][real_y & 3][x & 3]; + src_g = dither_g[src_g][real_y & 3][x & 3]; + src_b = dither_rb[src_b][real_y & 3][x & 3]; + } + } + else + { + src_r >>= 3; + src_g >>= 2; + src_b >>= 3; + } + + if (params->fbzMode & FBZ_RGB_WMASK) + fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); + + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) + aux_mem[x] = new_depth; + } + } + voodoo_output &= ~2; + voodoo->fbiPixelsOut++; +skip_pixel: + if (state->xdir > 0) + { + state->ir += params->dRdX; + state->ig += params->dGdX; + state->ib += params->dBdX; + state->ia += params->dAdX; + state->z += params->dZdX; + state->tmu0_s += params->tmu[0].dSdX; + state->tmu0_t += params->tmu[0].dTdX; + state->tmu0_w += params->tmu[0].dWdX; + state->tmu1_s += params->tmu[1].dSdX; + state->tmu1_t += params->tmu[1].dTdX; + state->tmu1_w += params->tmu[1].dWdX; + state->w += params->dWdX; + } + else + { + state->ir -= params->dRdX; + state->ig -= params->dGdX; + state->ib -= params->dBdX; + state->ia -= params->dAdX; + state->z -= params->dZdX; + state->tmu0_s -= params->tmu[0].dSdX; + state->tmu0_t -= params->tmu[0].dTdX; + state->tmu0_w -= params->tmu[0].dWdX; + state->tmu1_s -= params->tmu[1].dSdX; + state->tmu1_t -= params->tmu[1].dTdX; + state->tmu1_w -= params->tmu[1].dWdX; + state->w -= params->dWdX; + } + + x += state->xdir; + } while (start_x != x2); + + voodoo->pixel_count[odd_even] += state->pixel_count; + voodoo->texel_count[odd_even] += state->texel_count; + voodoo->fbiPixelsIn += state->pixel_count; + + if (voodoo->params.draw_offset == voodoo->params.front_offset) + voodoo->dirty_line[real_y >> 1] = 1; +next_line: + if (SLI_ENABLED) + { + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } + + voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; + voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; +} + +void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) +{ + voodoo_state_t state; + int vertexAy_adjusted; + int vertexCy_adjusted; + int dx, dy; + + uint64_t tempdx, tempdy; + uint64_t tempLOD; + int LOD; + int lodbias; + + voodoo->tri_count++; + + dx = 8 - (params->vertexAx & 0xf); + if ((params->vertexAx & 0xf) > 8) + dx += 16; + dy = 8 - (params->vertexAy & 0xf); + if ((params->vertexAy & 0xf) > 8) + dy += 16; + +/* pclog("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, + (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, + (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, + (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, + (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ + + state.base_r = params->startR; + state.base_g = params->startG; + state.base_b = params->startB; + state.base_a = params->startA; + state.base_z = params->startZ; + state.tmu[0].base_s = params->tmu[0].startS; + state.tmu[0].base_t = params->tmu[0].startT; + state.tmu[0].base_w = params->tmu[0].startW; + state.tmu[1].base_s = params->tmu[1].startS; + state.tmu[1].base_t = params->tmu[1].startT; + state.tmu[1].base_w = params->tmu[1].startW; + state.base_w = params->startW; + + if (params->fbzColorPath & FBZ_PARAM_ADJUST) + { + state.base_r += (dx*params->dRdX + dy*params->dRdY) >> 4; + state.base_g += (dx*params->dGdX + dy*params->dGdY) >> 4; + state.base_b += (dx*params->dBdX + dy*params->dBdY) >> 4; + state.base_a += (dx*params->dAdX + dy*params->dAdY) >> 4; + state.base_z += (dx*params->dZdX + dy*params->dZdY) >> 4; + state.tmu[0].base_s += (dx*params->tmu[0].dSdX + dy*params->tmu[0].dSdY) >> 4; + state.tmu[0].base_t += (dx*params->tmu[0].dTdX + dy*params->tmu[0].dTdY) >> 4; + state.tmu[0].base_w += (dx*params->tmu[0].dWdX + dy*params->tmu[0].dWdY) >> 4; + state.tmu[1].base_s += (dx*params->tmu[1].dSdX + dy*params->tmu[1].dSdY) >> 4; + state.tmu[1].base_t += (dx*params->tmu[1].dTdX + dy*params->tmu[1].dTdY) >> 4; + state.tmu[1].base_w += (dx*params->tmu[1].dWdX + dy*params->tmu[1].dWdY) >> 4; + state.base_w += (dx*params->dWdX + dy*params->dWdY) >> 4; + } + + tris++; + + state.vertexAy = params->vertexAy & ~0xffff0000; + if (state.vertexAy & 0x8000) + state.vertexAy |= 0xffff0000; + state.vertexBy = params->vertexBy & ~0xffff0000; + if (state.vertexBy & 0x8000) + state.vertexBy |= 0xffff0000; + state.vertexCy = params->vertexCy & ~0xffff0000; + if (state.vertexCy & 0x8000) + state.vertexCy |= 0xffff0000; + + state.vertexAx = params->vertexAx & ~0xffff0000; + if (state.vertexAx & 0x8000) + state.vertexAx |= 0xffff0000; + state.vertexBx = params->vertexBx & ~0xffff0000; + if (state.vertexBx & 0x8000) + state.vertexBx |= 0xffff0000; + state.vertexCx = params->vertexCx & ~0xffff0000; + if (state.vertexCx & 0x8000) + state.vertexCx |= 0xffff0000; + + vertexAy_adjusted = (state.vertexAy+7) >> 4; + vertexCy_adjusted = (state.vertexCy+7) >> 4; + + if (state.vertexBy - state.vertexAy) + state.dxAB = (int)((((int64_t)state.vertexBx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexBy - state.vertexAy); + else + state.dxAB = 0; + if (state.vertexCy - state.vertexAy) + state.dxAC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexCy - state.vertexAy); + else + state.dxAC = 0; + if (state.vertexCy - state.vertexBy) + state.dxBC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexBx << 12)) << 4) / (int)(state.vertexCy - state.vertexBy); + else + state.dxBC = 0; + + state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; + state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; + if (state.lod_max[0] > 0x800) + state.lod_max[0] = 0x800; + state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; + state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; + if (state.lod_max[1] > 0x800) + state.lod_max[1] = 0x800; + + state.xstart = state.xend = state.vertexAx << 8; + state.xdir = params->sign ? -1 : 1; + + state.y = (state.vertexAy + 8) >> 4; + state.ydir = 1; + + + tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); + tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); + + if (tempdx > tempdy) + tempLOD = tempdx; + else + tempLOD = tempdy; + + LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); + LOD >>= 2; + + lodbias = (params->tLOD[0] >> 12) & 0x3f; + if (lodbias & 0x20) + lodbias |= ~0x3f; + state.tmu[0].lod = LOD + (lodbias << 6); + + + tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); + tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); + + if (tempdx > tempdy) + tempLOD = tempdx; + else + tempLOD = tempdy; + + LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); + LOD >>= 2; + + lodbias = (params->tLOD[1] >> 12) & 0x3f; + if (lodbias & 0x20) + lodbias |= ~0x3f; + state.tmu[1].lod = LOD + (lodbias << 6); + + + voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); +} + + +static void render_thread(void *param, int odd_even) +{ + voodoo_t *voodoo = (voodoo_t *)param; + + while (1) + { + thread_set_event(voodoo->render_not_full_event[odd_even]); + thread_wait_event(voodoo->wake_render_thread[odd_even], -1); + thread_reset_event(voodoo->wake_render_thread[odd_even]); + voodoo->render_voodoo_busy[odd_even] = 1; + + while (!(odd_even ? PARAM_EMPTY_2 : PARAM_EMPTY_1)) + { + uint64_t start_time = timer_read(); + uint64_t end_time; + voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; + + voodoo_triangle(voodoo, params, odd_even); + + voodoo->params_read_idx[odd_even]++; + + if ((odd_even ? PARAM_ENTRIES_2 : PARAM_ENTRIES_1) > (PARAM_SIZE - 10)) + thread_set_event(voodoo->render_not_full_event[odd_even]); + + end_time = timer_read(); + voodoo->render_time[odd_even] += end_time - start_time; + } + + voodoo->render_voodoo_busy[odd_even] = 0; + } +} + +void voodoo_render_thread_1(void *param) +{ + render_thread(param, 0); +} +void voodoo_render_thread_2(void *param) +{ + render_thread(param, 1); +} + +void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) +{ + voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; + + while (PARAM_FULL_1 || (voodoo->render_threads == 2 && PARAM_FULL_2)) + { + thread_reset_event(voodoo->render_not_full_event[0]); + if (voodoo->render_threads == 2) + thread_reset_event(voodoo->render_not_full_event[1]); + if (PARAM_FULL_1) + { + thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ + } + if (voodoo->render_threads == 2 && PARAM_FULL_2) + { + thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ + } + } + + voodoo_use_texture(voodoo, params, 0); + if (voodoo->dual_tmus) + voodoo_use_texture(voodoo, params, 1); + + memcpy(params_new, params, sizeof(voodoo_params_t)); + + voodoo->params_write_idx++; + + if (PARAM_ENTRIES_1 < 4 || (voodoo->render_threads == 2 && PARAM_ENTRIES_2 < 4)) + voodoo_wake_render_thread(voodoo); +} diff --git a/src/vid_voodoo_render.h b/src/vid_voodoo_render.h new file mode 100644 index 0000000..ec8a551 --- /dev/null +++ b/src/vid_voodoo_render.h @@ -0,0 +1,324 @@ +#if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__) +#define NO_CODEGEN +#endif + +#ifndef NO_CODEGEN +void voodoo_codegen_init(voodoo_t *voodoo); +void voodoo_codegen_close(voodoo_t *voodoo); +#endif + +#define DEPTH_TEST(comp_depth) \ + do \ + { \ + switch (depth_op) \ + { \ + case DEPTHOP_NEVER: \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + case DEPTHOP_LESSTHAN: \ + if (!(comp_depth < old_depth)) \ + { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_EQUAL: \ + if (!(comp_depth == old_depth)) \ + { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_LESSTHANEQUAL: \ + if (!(comp_depth <= old_depth)) \ + { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_GREATERTHAN: \ + if (!(comp_depth > old_depth)) \ + { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_NOTEQUAL: \ + if (!(comp_depth != old_depth)) \ + { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_GREATERTHANEQUAL: \ + if (!(comp_depth >= old_depth)) \ + { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_ALWAYS: \ + break; \ + } \ + } while (0) + +#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \ + do \ + { \ + if (params->fogMode & FOG_CONSTANT) \ + { \ + src_r += params->fogColor.r; \ + src_g += params->fogColor.g; \ + src_b += params->fogColor.b; \ + } \ + else \ + { \ + int fog_r, fog_g, fog_b, fog_a = 0; \ + int fog_idx; \ + \ + if (!(params->fogMode & FOG_ADD)) \ + { \ + fog_r = params->fogColor.r; \ + fog_g = params->fogColor.g; \ + fog_b = params->fogColor.b; \ + } \ + else \ + fog_r = fog_g = fog_b = 0; \ + \ + if (!(params->fogMode & FOG_MULT)) \ + { \ + fog_r -= src_r; \ + fog_g -= src_g; \ + fog_b -= src_b; \ + } \ + \ + switch (params->fogMode & (FOG_Z|FOG_ALPHA)) \ + { \ + case 0: \ + fog_idx = (w_depth >> 10) & 0x3f; \ + \ + fog_a = params->fogTable[fog_idx].fog; \ + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \ + break; \ + case FOG_Z: \ + fog_a = (z >> 20) & 0xff; \ + break; \ + case FOG_ALPHA: \ + fog_a = CLAMP(ia >> 12); \ + break; \ + case FOG_W: \ + fog_a = CLAMP((w >> 32) & 0xff); \ + break; \ + } \ + fog_a++; \ + \ + fog_r = (fog_r * fog_a) >> 8; \ + fog_g = (fog_g * fog_a) >> 8; \ + fog_b = (fog_b * fog_a) >> 8; \ + \ + if (params->fogMode & FOG_MULT) \ + { \ + src_r = fog_r; \ + src_g = fog_g; \ + src_b = fog_b; \ + } \ + else \ + { \ + src_r += fog_r; \ + src_g += fog_g; \ + src_b += fog_b; \ + } \ + } \ + \ + src_r = CLAMP(src_r); \ + src_g = CLAMP(src_g); \ + src_b = CLAMP(src_b); \ + } while (0) + +#define ALPHA_TEST(src_a) \ + do \ + { \ + switch (alpha_func) \ + { \ + case AFUNC_NEVER: \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + case AFUNC_LESSTHAN: \ + if (!(src_a < a_ref)) \ + { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_EQUAL: \ + if (!(src_a == a_ref)) \ + { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_LESSTHANEQUAL: \ + if (!(src_a <= a_ref)) \ + { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_GREATERTHAN: \ + if (!(src_a > a_ref)) \ + { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_NOTEQUAL: \ + if (!(src_a != a_ref)) \ + { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_GREATERTHANEQUAL: \ + if (!(src_a >= a_ref)) \ + { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_ALWAYS: \ + break; \ + } \ + } while (0) + +#define ALPHA_BLEND(src_r, src_g, src_b, src_a) \ + do \ + { \ + int _a; \ + int newdest_r = 0, newdest_g = 0, newdest_b = 0; \ + \ + switch (dest_afunc) \ + { \ + case AFUNC_AZERO: \ + newdest_r = newdest_g = newdest_b = 0; \ + break; \ + case AFUNC_ASRC_ALPHA: \ + newdest_r = (dest_r * src_a) / 255; \ + newdest_g = (dest_g * src_a) / 255; \ + newdest_b = (dest_b * src_a) / 255; \ + break; \ + case AFUNC_A_COLOR: \ + newdest_r = (dest_r * src_r) / 255; \ + newdest_g = (dest_g * src_g) / 255; \ + newdest_b = (dest_b * src_b) / 255; \ + break; \ + case AFUNC_ADST_ALPHA: \ + newdest_r = (dest_r * dest_a) / 255; \ + newdest_g = (dest_g * dest_a) / 255; \ + newdest_b = (dest_b * dest_a) / 255; \ + break; \ + case AFUNC_AONE: \ + newdest_r = dest_r; \ + newdest_g = dest_g; \ + newdest_b = dest_b; \ + break; \ + case AFUNC_AOMSRC_ALPHA: \ + newdest_r = (dest_r * (255-src_a)) / 255; \ + newdest_g = (dest_g * (255-src_a)) / 255; \ + newdest_b = (dest_b * (255-src_a)) / 255; \ + break; \ + case AFUNC_AOM_COLOR: \ + newdest_r = (dest_r * (255-src_r)) / 255; \ + newdest_g = (dest_g * (255-src_g)) / 255; \ + newdest_b = (dest_b * (255-src_b)) / 255; \ + break; \ + case AFUNC_AOMDST_ALPHA: \ + newdest_r = (dest_r * (255-dest_a)) / 255; \ + newdest_g = (dest_g * (255-dest_a)) / 255; \ + newdest_b = (dest_b * (255-dest_a)) / 255; \ + break; \ + case AFUNC_ASATURATE: \ + _a = MIN(src_a, 1-dest_a); \ + newdest_r = (dest_r * _a) / 255; \ + newdest_g = (dest_g * _a) / 255; \ + newdest_b = (dest_b * _a) / 255; \ + break; \ + } \ + \ + switch (src_afunc) \ + { \ + case AFUNC_AZERO: \ + src_r = src_g = src_b = 0; \ + break; \ + case AFUNC_ASRC_ALPHA: \ + src_r = (src_r * src_a) / 255; \ + src_g = (src_g * src_a) / 255; \ + src_b = (src_b * src_a) / 255; \ + break; \ + case AFUNC_A_COLOR: \ + src_r = (src_r * dest_r) / 255; \ + src_g = (src_g * dest_g) / 255; \ + src_b = (src_b * dest_b) / 255; \ + break; \ + case AFUNC_ADST_ALPHA: \ + src_r = (src_r * dest_a) / 255; \ + src_g = (src_g * dest_a) / 255; \ + src_b = (src_b * dest_a) / 255; \ + break; \ + case AFUNC_AONE: \ + break; \ + case AFUNC_AOMSRC_ALPHA: \ + src_r = (src_r * (255-src_a)) / 255; \ + src_g = (src_g * (255-src_a)) / 255; \ + src_b = (src_b * (255-src_a)) / 255; \ + break; \ + case AFUNC_AOM_COLOR: \ + src_r = (src_r * (255-dest_r)) / 255; \ + src_g = (src_g * (255-dest_g)) / 255; \ + src_b = (src_b * (255-dest_b)) / 255; \ + break; \ + case AFUNC_AOMDST_ALPHA: \ + src_r = (src_r * (255-dest_a)) / 255; \ + src_g = (src_g * (255-dest_a)) / 255; \ + src_b = (src_b * (255-dest_a)) / 255; \ + break; \ + case AFUNC_ACOLORBEFOREFOG: \ + fatal("AFUNC_ACOLORBEFOREFOG\n"); \ + break; \ + } \ + \ + src_r += newdest_r; \ + src_g += newdest_g; \ + src_b += newdest_b; \ + \ + src_r = CLAMP(src_r); \ + src_g = CLAMP(src_g); \ + src_b = CLAMP(src_b); \ + } while(0) + + + +void voodoo_render_thread_1(void *param); +void voodoo_render_thread_2(void *param); +void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params); + +extern int voodoo_recomp; +extern int tris; + +static inline void voodoo_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 voodoo_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])) + { + voodoo_wake_render_thread(voodoo); + if (!PARAM_EMPTY_1 || voodoo->render_voodoo_busy[0]) + thread_wait_event(voodoo->render_not_full_event[0], 1); + if (voodoo->render_threads == 2 && (!PARAM_EMPTY_2 || voodoo->render_voodoo_busy[1])) + thread_wait_event(voodoo->render_not_full_event[1], 1); + } +} diff --git a/src/vid_voodoo_setup.c b/src/vid_voodoo_setup.c new file mode 100644 index 0000000..f3fe076 --- /dev/null +++ b/src/vid_voodoo_setup.c @@ -0,0 +1,215 @@ +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_setup.h" + +void voodoo_triangle_setup(voodoo_t *voodoo) +{ + float dxAB, dxBC, dyAB, dyBC; + float area; + int va = 0, vb = 1, vc = 2; + int reverse_cull = 0; + vert_t verts[3]; + + verts[0] = voodoo->verts[0]; + verts[1] = voodoo->verts[1]; + verts[2] = voodoo->verts[2]; + + if (verts[0].sVy < verts[1].sVy) + { + if (verts[1].sVy < verts[2].sVy) + { + /* V1>V0, V2>V1, V2>V1>V0*/ + va = 0; /*OK*/ + vb = 1; + vc = 2; + } + else + { + /* V1>V0, V1>V2*/ + if (verts[0].sVy < verts[2].sVy) + { + /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ + va = 0; + vb = 2; + vc = 1; + reverse_cull = 1; + } + else + { + /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ + va = 2; + vb = 0; + vc = 1; + } + } + } + else + { + if (verts[1].sVy < verts[2].sVy) + { + /* V0>V1, V2>V1*/ + if (verts[0].sVy < verts[2].sVy) + { + /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ + va = 1; + vb = 0; + vc = 2; + reverse_cull = 1; + } + else + { + /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ + va = 1; + vb = 2; + vc = 0; + } + } + else + { + /*V0>V1>V2*/ + va = 2; + vb = 1; + vc = 0; + reverse_cull = 1; + } + } + + dxAB = verts[va].sVx - verts[vb].sVx; + dxBC = verts[vb].sVx - verts[vc].sVx; + dyAB = verts[va].sVy - verts[vb].sVy; + dyBC = verts[vb].sVy - verts[vc].sVy; + + area = dxAB * dyBC - dxBC * dyAB; + + if (area == 0.0) + { + if ((voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) && + !(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) + voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; + + return; + } + + dxAB /= area; + dxBC /= area; + dyAB /= area; + dyBC /= area; + + if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) + { + int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; + int sign = (area < 0.0); + + if (!(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) + voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; + + if (reverse_cull) + sign = !sign; + + if (cull_sign && sign) + return; + if (!cull_sign && !sign) + return; + } + + voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); + voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); + voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff); + voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff); + voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff); + voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); + + if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) + fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); + + if (voodoo->sSetupMode & SETUPMODE_RGB) + { + voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f); + voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); + voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); + voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f); + voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); + voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); + voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f); + voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); + voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_ALPHA) + { + voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f); + voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); + voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_Z) + { + voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f); + voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); + voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_Wb) + { + voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f); + voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); + voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; + voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; + voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; + } + if (voodoo->sSetupMode & SETUPMODE_W0) + { + voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f); + voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; + voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; + voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; + } + if (voodoo->sSetupMode & SETUPMODE_S0_T0) + { + voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f); + voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f); + voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; + voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; + voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; + voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; + voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; + voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; + } + if (voodoo->sSetupMode & SETUPMODE_W1) + { + voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f); + voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); + } + if (voodoo->sSetupMode & SETUPMODE_S1_T1) + { + voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f); + voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f); + voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); + } + + voodoo->params.sign = (area < 0.0); + + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + + voodoo_queue_triangle(voodoo, &voodoo->params); +} diff --git a/src/vid_voodoo_setup.h b/src/vid_voodoo_setup.h new file mode 100644 index 0000000..06d2f8d --- /dev/null +++ b/src/vid_voodoo_setup.h @@ -0,0 +1 @@ +void voodoo_triangle_setup(voodoo_t *voodoo); diff --git a/src/vid_voodoo_texture.c b/src/vid_voodoo_texture.c new file mode 100644 index 0000000..69bcbd3 --- /dev/null +++ b/src/vid_voodoo_texture.c @@ -0,0 +1,564 @@ +#include +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_dither.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "vid_voodoo_texture.h" + +void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) +{ + int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; + int width = 256, height = 256; + int shift = 8; + int lod; + uint32_t base = voodoo->params.texBaseAddr[tmu]; + uint32_t offset = 0; + int tex_lod = 0; + + if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) + height >>= aspect; + else + { + width >>= aspect; + shift -= aspect; + } + + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD)) + { + width >>= 1; + height >>= 1; + shift--; + tex_lod++; + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) + base = voodoo->params.texBaseAddr1[tmu]; + } + + for (lod = 0; lod <= LOD_MAX+1; lod++) + { + if (!width) + width = 1; + if (!height) + height = 1; + if (shift < 0) + shift = 0; + voodoo->params.tex_base[tmu][lod] = base + offset; + if (voodoo->params.tformat[tmu] & 8) + voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2); + else + voodoo->params.tex_end[tmu][lod] = base + offset + (width * height); + voodoo->params.tex_w_mask[tmu][lod] = width - 1; + voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1); + voodoo->params.tex_h_mask[tmu][lod] = height - 1; + voodoo->params.tex_shift[tmu][lod] = shift; + voodoo->params.tex_lod[tmu][lod] = tex_lod; + + if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) + { + if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) + { + if (voodoo->params.tformat[tmu] & 8) + offset += width * height * 2; + else + offset += width * height; + + if (voodoo->params.tLOD[tmu] & LOD_SPLIT) + { + width >>= 2; + height >>= 2; + shift -= 2; + tex_lod += 2; + } + else + { + width >>= 1; + height >>= 1; + shift--; + tex_lod++; + } + + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) + { + switch (tex_lod) + { + case 0: + base = voodoo->params.texBaseAddr[tmu]; + break; + case 1: + base = voodoo->params.texBaseAddr1[tmu]; + break; + case 2: + base = voodoo->params.texBaseAddr2[tmu]; + break; + default: + base = voodoo->params.texBaseAddr38[tmu]; + break; + } + } + } + } + } + + voodoo->params.tex_width[tmu] = width; +} + +#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) + +void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) +{ + int c, d; + int lod; + int lod_min, lod_max; + uint32_t addr = 0, addr_end; + uint32_t palette_checksum; + + lod_min = (params->tLOD[tmu] >> 2) & 15; + lod_max = (params->tLOD[tmu] >> 8) & 15; + + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) + { + if (voodoo->palette_dirty[tmu]) + { + palette_checksum = 0; + + for (c = 0; c < 256; c++) + palette_checksum ^= voodoo->palette[tmu][c].u; + + voodoo->palette_checksum[tmu] = palette_checksum; + voodoo->palette_dirty[tmu] = 0; + } + else + palette_checksum = voodoo->palette_checksum[tmu]; + } + else + palette_checksum = 0; + + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + addr = params->texBaseAddr1[tmu]; + else + addr = params->texBaseAddr[tmu]; + + /*Try to find texture in cache*/ + for (c = 0; c < TEX_CACHE_MAX; c++) + { + if (voodoo->texture_cache[tmu][c].base == addr && + voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && + voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) + { + params->tex_entry[tmu] = c; + voodoo->texture_cache[tmu][c].refcount++; + return; + } + } + + /*Texture not found, search for unused texture*/ + do + { + for (c = 0; c < TEX_CACHE_MAX; c++) + { + voodoo->texture_last_removed++; + voodoo->texture_last_removed &= (TEX_CACHE_MAX-1); + if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && + (voodoo->render_threads == 1 || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) + break; + } + if (c == TEX_CACHE_MAX) + voodoo_wait_for_render_thread_idle(voodoo); + } while (c == TEX_CACHE_MAX); + if (c == TEX_CACHE_MAX) + fatal("Texture cache full!\n"); + + c = voodoo->texture_last_removed; + + + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; + else + voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; + voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; + + lod_min = (params->tLOD[tmu] >> 2) & 15; + lod_max = (params->tLOD[tmu] >> 8) & 15; +// pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); + lod_min = MIN(lod_min, 8); + lod_max = MIN(lod_max, 8); + for (lod = lod_min; lod <= lod_max; lod++) + { + uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; + uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; + int x, y; + int shift = 8 - params->tex_lod[tmu][lod]; + rgba_u *pal; + + //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: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_Y4I2Q2: + pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_A8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + base[x] = makergba(dat, dat, dat, dat); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_I8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + base[x] = makergba(dat, dat, dat, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_AI8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + base[x] = makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_PAL8: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_APAL8: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; + + int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3); + int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2); + int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); + int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); + + base[x] = makergba(r, g, b, a); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_ARGB8332: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + case TEX_A8Y4I2Q2: + pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + case TEX_R5G6B5: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + case TEX_ARGB1555: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + case TEX_ARGB4444: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + case TEX_A8I8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + case TEX_APAL88: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) + { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) + { + uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); + base += (1 << shift); + } + break; + + default: + fatal("Unknown texture format %i\n", params->tformat[tmu]); + } + } + + voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; + + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) + voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; + else + voodoo->texture_cache[tmu][c].palette_checksum = 0; + + if (lod_min == 0) + { + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; + voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; + } + else + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; + + if (lod_min <= 1 && lod_max >= 1) + { + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; + voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; + } + else + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; + + if (lod_min <= 2 && lod_max >= 2) + { + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; + voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; + } + else + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; + + if (lod_max >= 3) + { + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; + voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; + } + else + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; + + + for (d = 0; d < 4; d++) + { + addr = voodoo->texture_cache[tmu][c].addr_start[d]; + addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + + if (addr_end != 0) + { + for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } + } + + params->tex_entry[tmu] = c; + voodoo->texture_cache[tmu][c].refcount++; +} + +static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) +{ + int wait_for_idle = 0; + int c; + + memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); +// 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 d; + + for (d = 0; d < 4; d++) + { + int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; + int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + + if (addr_end != 0) + { + int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; + int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; + + if (addr_end_masked < addr_start_masked) + addr_end_masked = voodoo->texture_mask+1; + if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) + { +// 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])) + wait_for_idle = 1; + + voodoo->texture_cache[tmu][c].base = -1; + } + else + { + for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } + } + } + } + } + if (wait_for_idle) + voodoo_wait_for_render_thread_idle(voodoo); +} + +void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) +{ + int lod, s, t; + voodoo_t *voodoo = (voodoo_t *)p; + int tmu; + + if (addr & 0x400000) + return; /*TREX != 0*/ + + tmu = (addr & 0x200000) ? 1 : 0; + + if (tmu && !voodoo->dual_tmus) + return; + +// 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) + s = (addr >> 1) & 0xfe; + else + { + if (voodoo->params.textureMode[tmu] & (1 << 31)) + s = addr & 0xfc; + else + s = (addr >> 1) & 0xfc; + } + + if (lod > LOD_MAX) + return; + +// if (addr >= 0x200000) +// return; + + if (voodoo->params.tformat[tmu] & 8) + addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; + else + addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); + if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) + { +// 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; +} diff --git a/src/vid_voodoo_texture.h b/src/vid_voodoo_texture.h new file mode 100644 index 0000000..e744f17 --- /dev/null +++ b/src/vid_voodoo_texture.h @@ -0,0 +1,18 @@ +static const uint32_t texture_offset[LOD_MAX+3] = +{ + 0, + 256*256, + 256*256 + 128*128, + 256*256 + 128*128 + 64*64, + 256*256 + 128*128 + 64*64 + 32*32, + 256*256 + 128*128 + 64*64 + 32*32 + 16*16, + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8, + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4, + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2, + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1, + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1 + 1 +}; + +void voodoo_recalc_tex(voodoo_t *voodoo, int tmu); +void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu); +void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p); From 19a5dfa579b0ce90d8b1809e1af1a5b12de2b0d5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 11 Aug 2020 11:18:03 +0100 Subject: [PATCH 0873/1050] Added Voodoo Banshee emulation. Known issues : - Tiled framebuffer layout is not yet implemented. This causes horizontal offsets in some 2D 16bpp stuff (eg FMV in Tomb Raider 2, UI in Expendable) - Fog is broken and currently disabled for Banshee - Possibly at least 1 race in 2D blitter emulation - A few things not yet emulated - overlay filters, some (rarely used) 2D blitter functions --- src/ibm.h | 1 + src/vid_svga.c | 59 +- src/vid_svga.h | 4 +- src/vid_voodoo.c | 137 +- src/vid_voodoo_banshee.c | 1997 ++++++++++++++++++++++++++++++ src/vid_voodoo_banshee.h | 3 + src/vid_voodoo_banshee_blitter.c | 1305 +++++++++++++++++++ src/vid_voodoo_banshee_blitter.h | 1 + src/vid_voodoo_codegen_x86.h | 3 + src/vid_voodoo_common.h | 114 +- src/vid_voodoo_fifo.c | 97 +- src/vid_voodoo_reg.c | 130 +- src/vid_voodoo_regs.h | 13 +- src/vid_voodoo_render.c | 7 +- src/vid_voodoo_setup.c | 54 +- src/vid_voodoo_texture.c | 55 +- src/vid_voodoo_texture.h | 1 + src/video.c | 2 + 18 files changed, 3860 insertions(+), 123 deletions(-) create mode 100644 src/vid_voodoo_banshee.c create mode 100644 src/vid_voodoo_banshee.h create mode 100644 src/vid_voodoo_banshee_blitter.c create mode 100644 src/vid_voodoo_banshee_blitter.h diff --git a/src/ibm.h b/src/ibm.h index 86ac97a..02fb0fc 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -321,6 +321,7 @@ enum GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/ GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/ GFX_TVGA9000B, /*Trident TVGA9000B*/ + GFX_BANSHEE, GFX_MAX }; diff --git a/src/vid_svga.c b/src/vid_svga.c index 7b0098e..b881dd0 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -667,36 +667,39 @@ void svga_poll(void *p) svga->maback <<= 2; svga->ca <<= 2; - 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) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ + if (!svga->video_res_override) { - svga->video_res_x /= svga->char_width; - svga->video_res_y /= (svga->crtc[9] & 31) + 1; - svga->video_bpp = 0; - } - else - { - if (svga->crtc[9] & 0x80) - svga->video_res_y /= 2; - if (!(svga->crtc[0x17] & 2)) - svga->video_res_y *= 4; - else if (!(svga->crtc[0x17] & 1)) - svga->video_res_y *= 2; - svga->video_res_y /= (svga->crtc[9] & 31) + 1; - if (svga->render == svga_render_8bpp_lowres || - svga->render == svga_render_15bpp_lowres || - svga->render == svga_render_16bpp_lowres || - svga->render == svga_render_24bpp_lowres || - svga->render == svga_render_32bpp_lowres) - svga->video_res_x /= 2; + svga->video_res_x = wx; + svga->video_res_y = wy + 1; - switch (svga->gdcreg[5] & 0x60) + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ { - case 0x00: svga->video_bpp = 4; break; - case 0x20: svga->video_bpp = 2; break; - case 0x40: case 0x60: svga->video_bpp = svga->bpp; break; + svga->video_res_x /= svga->char_width; + svga->video_res_y /= (svga->crtc[9] & 31) + 1; + svga->video_bpp = 0; + } + else + { + if (svga->crtc[9] & 0x80) + svga->video_res_y /= 2; + if (!(svga->crtc[0x17] & 2)) + svga->video_res_y *= 4; + else if (!(svga->crtc[0x17] & 1)) + svga->video_res_y *= 2; + svga->video_res_y /= (svga->crtc[9] & 31) + 1; + if (svga->render == svga_render_8bpp_lowres || + svga->render == svga_render_15bpp_lowres || + svga->render == svga_render_16bpp_lowres || + svga->render == svga_render_24bpp_lowres || + svga->render == svga_render_32bpp_lowres) + svga->video_res_x /= 2; + + switch (svga->gdcreg[5] & 0x60) + { + case 0x00: svga->video_bpp = 4; break; + case 0x20: svga->video_bpp = 2; break; + case 0x40: case 0x60: svga->video_bpp = svga->bpp; break; + } } } // if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2); @@ -767,7 +770,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->vram_display_mask = memsize - 1; svga->vram_mask = memsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x800000 >> 12); + svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x1000000 >> 12); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out; diff --git a/src/vid_svga.h b/src/vid_svga.h index 3a0668b..9e49bfd 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -50,7 +50,7 @@ typedef struct svga_t int set_reset_disabled; uint8_t egapal[16]; - uint32_t pallook[256]; + uint32_t pallook[512]; PALETTE vgapal; int ramdac_type; @@ -93,6 +93,8 @@ typedef struct svga_t int fullchange; int video_res_x, video_res_y, video_bpp; + int video_res_override; /*If clear then SVGA code will set above variables, if + set then card code will*/ int frames, fps; struct diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index a59347f..79fac67 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -34,6 +34,9 @@ void voodoo_recalc(voodoo_t *voodoo) { uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; + if (voodoo->type >= VOODOO_BANSHEE) + return; + voodoo->params.front_offset = voodoo->disp_buffer*buffer_offset; voodoo->back_offset = voodoo->draw_buffer*buffer_offset; @@ -1050,6 +1053,114 @@ void *voodoo_card_init() return voodoo; } +void *voodoo_2d3d_card_init(int type) +{ + int c; + voodoo_t *voodoo = malloc(sizeof(voodoo_t)); + memset(voodoo, 0, sizeof(voodoo_t)); + + voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->scrfilter = 0; + voodoo->render_threads = device_get_config_int("render_threads"); + voodoo->odd_even_mask = voodoo->render_threads - 1; +#ifndef NO_CODEGEN + voodoo->use_recompiler = device_get_config_int("recompiler"); +#endif + voodoo->type = type; + voodoo->dual_tmus = 0; + + /*generate filter lookup tables*/ + voodoo_generate_filter_v2(voodoo); + + for (c = 0; c < TEX_CACHE_MAX; c++) + { + voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); + voodoo->texture_cache[0][c].base = -1; /*invalid*/ + voodoo->texture_cache[0][c].refcount = 0; + if (voodoo->dual_tmus) + { + voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); + voodoo->texture_cache[1][c].base = -1; /*invalid*/ + voodoo->texture_cache[1][c].refcount = 0; + } + } + + timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + + voodoo->fbiInit0 = 0; + + voodoo->wake_fifo_thread = thread_create_event(); + voodoo->wake_render_thread[0] = thread_create_event(); + voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_main_thread = thread_create_event(); + voodoo->fifo_not_full_event = thread_create_event(); + voodoo->render_not_full_event[0] = thread_create_event(); + voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); + if (voodoo->render_threads == 2) + voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + + timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); + + for (c = 0; c < 0x100; c++) + { + rgb332[c].r = c & 0xe0; + rgb332[c].g = (c << 3) & 0xe0; + rgb332[c].b = (c << 6) & 0xc0; + rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); + rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); + rgb332[c].a = 0xff; + + ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); + ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); + ai44[c].g = ai44[c].b = ai44[c].r; + } + + for (c = 0; c < 0x10000; c++) + { + rgb565[c].r = (c >> 8) & 0xf8; + rgb565[c].g = (c >> 3) & 0xfc; + rgb565[c].b = (c << 3) & 0xf8; + rgb565[c].r |= (rgb565[c].r >> 5); + rgb565[c].g |= (rgb565[c].g >> 6); + rgb565[c].b |= (rgb565[c].b >> 5); + rgb565[c].a = 0xff; + + argb1555[c].r = (c >> 7) & 0xf8; + argb1555[c].g = (c >> 2) & 0xf8; + argb1555[c].b = (c << 3) & 0xf8; + argb1555[c].r |= (argb1555[c].r >> 5); + argb1555[c].g |= (argb1555[c].g >> 5); + argb1555[c].b |= (argb1555[c].b >> 5); + argb1555[c].a = (c & 0x8000) ? 0xff : 0; + + argb4444[c].a = (c >> 8) & 0xf0; + argb4444[c].r = (c >> 4) & 0xf0; + argb4444[c].g = c & 0xf0; + argb4444[c].b = (c << 4) & 0xf0; + argb4444[c].a |= (argb4444[c].a >> 4); + argb4444[c].r |= (argb4444[c].r >> 4); + argb4444[c].g |= (argb4444[c].g >> 4); + argb4444[c].b |= (argb4444[c].b >> 4); + + ai88[c].a = (c >> 8); + ai88[c].r = c & 0xff; + ai88[c].g = c & 0xff; + ai88[c].b = c & 0xff; + } +#ifndef NO_CODEGEN + voodoo_codegen_init(voodoo); +#endif + + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; + + return voodoo; +} + void *voodoo_init() { voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); @@ -1116,14 +1227,17 @@ void voodoo_card_close(voodoo_t *voodoo) int c; #ifndef RELEASE_BUILD - f = romfopen("texram.dmp", "wb"); - fwrite(voodoo->tex_mem[0], voodoo->texture_size*1024*1024, 1, f); - fclose(f); - if (voodoo->dual_tmus) + if (voodoo->tex_mem[0]) { - f = romfopen("texram2.dmp", "wb"); - fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f); + f = romfopen("texram.dmp", "wb"); + fwrite(voodoo->tex_mem[0], voodoo->texture_size*1024*1024, 1, f); fclose(f); + if (voodoo->dual_tmus) + { + f = romfopen("texram2.dmp", "wb"); + fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f); + fclose(f); + } } #endif @@ -1148,10 +1262,13 @@ void voodoo_card_close(voodoo_t *voodoo) #ifndef NO_CODEGEN voodoo_codegen_close(voodoo); #endif - free(voodoo->fb_mem); - if (voodoo->dual_tmus) - free(voodoo->tex_mem[1]); - free(voodoo->tex_mem[0]); + if (voodoo->type != VOODOO_BANSHEE && voodoo->fb_mem) + { + free(voodoo->fb_mem); + if (voodoo->dual_tmus) + free(voodoo->tex_mem[1]); + free(voodoo->tex_mem[0]); + } free(voodoo); } diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c new file mode 100644 index 0000000..26c14c8 --- /dev/null +++ b/src/vid_voodoo_banshee.c @@ -0,0 +1,1997 @@ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "pci.h" +#include "rom.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_svga_render.h" +#include "vid_voodoo_banshee.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_fifo.h" +#include "vid_voodoo_regs.h" +#include "vid_voodoo_render.h" +#include "x86.h" + +#ifdef CLAMP +#undef CLAMP +#endif + +typedef struct banshee_t +{ + svga_t svga; + + rom_t bios_rom; + + uint8_t pci_regs[256]; + + uint32_t memBaseAddr0; + uint32_t memBaseAddr1; + uint32_t ioBaseAddr; + + uint32_t agpInit0; + uint32_t dramInit0, dramInit1; + uint32_t lfbMemoryConfig; + uint32_t miscInit0, miscInit1; + uint32_t pciInit0; + uint32_t vgaInit0, vgaInit1; + + uint32_t command_2d; + uint32_t srcBaseAddr_2d; + + uint32_t pllCtrl0, pllCtrl1, pllCtrl2; + + uint32_t dacMode; + int dacAddr; + + uint32_t vidDesktopOverlayStride; + uint32_t vidDesktopStartAddr; + uint32_t vidProcCfg; + uint32_t vidScreenSize; + + int overlay_pix_fmt; + + uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1; + + uint32_t intrCtrl; + + uint32_t overlay_buffer[4096]; + + mem_mapping_t linear_mapping; + + mem_mapping_t reg_mapping_low; /*0000000-07fffff*/ + mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ + + voodoo_t *voodoo; +} banshee_t; + +enum +{ + Init_status = 0x00, + Init_pciInit0 = 0x04, + Init_lfbMemoryConfig = 0x0c, + Init_miscInit0 = 0x10, + Init_miscInit1 = 0x14, + Init_dramInit0 = 0x18, + Init_dramInit1 = 0x1c, + Init_agpInit0 = 0x20, + Init_vgaInit0 = 0x28, + Init_vgaInit1 = 0x2c, + Init_2dCommand = 0x30, + Init_2dSrcBaseAddr = 0x34, + Init_strapInfo = 0x38, + + PLL_pllCtrl0 = 0x40, + PLL_pllCtrl1 = 0x44, + PLL_pllCtrl2 = 0x48, + + DAC_dacMode = 0x4c, + DAC_dacAddr = 0x50, + DAC_dacData = 0x54, + + Video_vidProcCfg = 0x5c, + Video_hwCurPatAddr = 0x60, + Video_hwCurLoc = 0x64, + Video_hwCurC0 = 0x68, + Video_hwCurC1 = 0x6c, + Video_vidScreenSize = 0x98, + Video_vidOverlayStartCoords = 0x9c, + Video_vidOverlayEndScreenCoords = 0xa0, + Video_vidOverlayDudx = 0xa4, + Video_vidOverlayDudxOffsetSrcWidth = 0xa8, + Video_vidOverlayDvdy = 0xac, + Video_vidOverlayDvdyOffset = 0xe0, + Video_vidDesktopStartAddr = 0xe4, + Video_vidDesktopOverlayStride = 0xe8 +}; + +enum +{ + cmdBaseAddr0 = 0x20, + cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48 +}; + +#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) + +#define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) +#define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) +#define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) +#define VIDPROCCFG_DESKTOP_PIX_FORMAT ((banshee->vidProcCfg >> 18) & 7) +#define VIDPROCCFG_OVERLAY_PIX_FORMAT ((banshee->vidProcCfg >> 21) & 7) +#define VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT (21) +#define VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK (7 << VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT) +#define VIDPROCCFG_DESKTOP_TILE (1 << 24) +#define VIDPROCCFG_OVERLAY_TILE (1 << 25) +#define VIDPROCCFG_2X_MODE (1 << 26) +#define VIDPROCCFG_HWCURSOR_ENA (1 << 27) + +#define OVERLAY_FMT_YUYV422 (5) +#define OVERLAY_FMT_UYVY422 (6) +#define OVERLAY_FMT_565_DITHER (7) + +#define OVERLAY_START_X_MASK (0xfff) +#define OVERLAY_START_Y_SHIFT (12) +#define OVERLAY_START_Y_MASK (0xfff << OVERLAY_START_Y_SHIFT) + +#define OVERLAY_END_X_MASK (0xfff) +#define OVERLAY_END_Y_SHIFT (12) +#define OVERLAY_END_Y_MASK (0xfff << OVERLAY_END_Y_SHIFT) + +#define OVERLAY_SRC_WIDTH_SHIFT (19) +#define OVERLAY_SRC_WIDTH_MASK (0x1fff << OVERLAY_SRC_WIDTH_SHIFT) + +#define VID_STRIDE_OVERLAY_SHIFT (16) +#define VID_STRIDE_OVERLAY_MASK (0x7fff << VID_STRIDE_OVERLAY_SHIFT) + +#define VID_DUDX_MASK (0xffffff) +#define VID_DVDY_MASK (0xffffff) + +#define PIX_FORMAT_8 0 +#define PIX_FORMAT_RGB565 1 +#define PIX_FORMAT_RGB24 2 +#define PIX_FORMAT_RGB32 3 + + +static uint32_t banshee_status(banshee_t *banshee); + +static void banshee_out(uint16_t addr, uint8_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + svga_t *svga = &banshee->svga; + uint8_t old; + +// /*if (addr != 0x3c9) */pclog("banshee_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) + { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) + { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) + { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); +} + +static uint8_t banshee_in(uint16_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + svga_t *svga = &banshee->svga; + uint8_t temp; + +// if (addr != 0x3da) pclog("banshee_in : %04X ", addr); + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) + { + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x40) + temp = 0; + else + temp = 0x10; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } +// if (addr != 0x3da) pclog("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); + return temp; +} + +static void banshee_updatemapping(banshee_t *banshee) +{ + svga_t *svga = &banshee->svga; + + if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) + { +// pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&banshee->linear_mapping); + mem_mapping_disable(&banshee->reg_mapping_low); + mem_mapping_disable(&banshee->reg_mapping_high); + return; + } + + pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + + pclog("Linear framebuffer %08X ", banshee->memBaseAddr1); + mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20); + pclog("registers %08X\n", banshee->memBaseAddr0); + mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20); + mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); +} + +static void banshee_recalctimings(svga_t *svga) +{ + banshee_t *banshee = (banshee_t *)svga->p; + voodoo_t *voodoo = banshee->voodoo; + +/*7 R/W Horizontal Retrace End bit 5. - + 6 R/W Horizontal Retrace Start bit 8 0x4 + 5 R/W Horizontal Blank End bit 6. - + 4 R/W Horizontal Blank Start bit 8. 0x3 + 3 R/W Reserved. - + 2 R/W Horizontal Display Enable End bit 8. 0x1 + 1 R/W Reserved. - + 0 R/W Horizontal Total bit 8. 0x0*/ + if (svga->crtc[0x1a] & 0x01) svga->htotal += 0x100; + if (svga->crtc[0x1a] & 0x04) svga->hdisp += 0x100; +/*6 R/W Vertical Retrace Start bit 10 0x10 + 5 R/W Reserved. - + 4 R/W Vertical Blank Start bit 10. 0x15 + 3 R/W Reserved. - + 2 R/W Vertical Display Enable End bit 10 0x12 + 1 R/W Reserved. - + 0 R/W Vertical Total bit 10. 0x6*/ + if (svga->crtc[0x1b] & 0x01) svga->vtotal += 0x400; + if (svga->crtc[0x1b] & 0x04) svga->dispend += 0x400; + if (svga->crtc[0x1b] & 0x10) svga->vblankstart += 0x400; + if (svga->crtc[0x1b] & 0x40) svga->vsyncstart += 0x400; + pclog("svga->hdisp=%i\n", svga->hdisp); + + if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) + { + switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) + { + case PIX_FORMAT_8: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case PIX_FORMAT_RGB565: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case PIX_FORMAT_RGB24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case PIX_FORMAT_RGB32: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; + default: + fatal("Unknown pixel format %08x\n", banshee->vgaInit0); + } + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) + svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; + else + svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; + svga->ma_latch = banshee->vidDesktopStartAddr >> 2; + pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); + + svga->char_width = 8; + svga->split = 99999; + + if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) + { + svga->hdisp *= 2; + svga->htotal *= 2; + } + + svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE; + + svga->overlay.x = voodoo->overlay.start_x; + svga->overlay.y = voodoo->overlay.start_y; + svga->overlay.xsize = voodoo->overlay.size_x; + svga->overlay.ysize = voodoo->overlay.size_y; + svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) + svga->overlay.pitch *= 128; + if (svga->overlay.xsize <= 0 || svga->overlay.ysize <= 0) + svga->overlay.ena = 0; + if (svga->overlay.ena) + { + pclog("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", + voodoo->overlay.start_x, voodoo->overlay.start_y, + voodoo->overlay.end_x, voodoo->overlay.end_y, + voodoo->overlay.size_x, voodoo->overlay.size_y, + svga->overlay.pitch); + } + + svga->video_res_override = 1; + svga->video_res_x = svga->hdisp; + svga->video_res_y = svga->dispend; + svga->video_bpp = svga->bpp; + } + else + { + pclog("Normal shift out\n"); + svga->bpp = 8; + svga->video_res_override = 0; + } + + if (((svga->miscout >> 2) & 3) == 3) + { + int k = banshee->pllCtrl0 & 3; + int m = (banshee->pllCtrl0 >> 2) & 0x3f; + int n = (banshee->pllCtrl0 >> 8) & 0xff; + double freq = (((double)n + 2) / (((double)m + 2) * (double)(1 << k))) * 14318184.0; + + svga->clock = (cpuclock * (float)(1ull << 32)) / freq; +// svga->clock = cpuclock / freq; + +// pclog("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); + } +} + +static void banshee_ext_out(uint16_t addr, uint8_t val, void *p) +{ +// banshee_t *banshee = (banshee_t *)p; +// svga_t *svga = &banshee->svga; + +// pclog("banshee_ext_out: addr=%04x val=%02x\n", addr, val); + + switch (addr & 0xff) + { + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + case 0xc0: case 0xc1: case 0xc2: case 0xc3: + case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: + case 0xcc: case 0xcd: case 0xce: case 0xcf: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: + case 0xdc: case 0xdd: case 0xde: case 0xdf: + banshee_out((addr & 0xff)+0x300, val, p); + break; + + default: + fatal("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); + } +} +static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + +// pclog("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); + + switch (addr & 0xff) + { + case Init_pciInit0: + banshee->pciInit0 = val; + voodoo->read_time = pci_nonburst_time + pci_burst_time * ((val & 0x100) ? 2 : 1); + voodoo->burst_time = pci_burst_time * ((val & 0x200) ? 1 : 0); + voodoo->write_time = pci_nonburst_time + voodoo->burst_time; + break; + + case Init_lfbMemoryConfig: + banshee->lfbMemoryConfig = val; +// pclog("lfbMemoryConfig=%08x\n", val); + voodoo->tile_base = (val & 0x1fff) << 12; + voodoo->tile_stride = 1024 << ((val >> 13) & 7); + voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); + voodoo->tile_x = ((val >> 16) & 0x7f) * 128; + break; + + case Init_miscInit0: + banshee->miscInit0 = val; + break; + case Init_miscInit1: + banshee->miscInit1 = val; + break; + case Init_dramInit0: + banshee->dramInit0 = val; + break; + case Init_dramInit1: + banshee->dramInit1 = val; + break; + case Init_agpInit0: + banshee->agpInit0 = val; + break; + + case Init_2dCommand: + banshee->command_2d = val; + break; + case Init_2dSrcBaseAddr: + banshee->srcBaseAddr_2d = val; + break; + case Init_vgaInit0: + banshee->vgaInit0 = val; + break; + case Init_vgaInit1: + banshee->vgaInit1 = val; + svga->write_bank = (val & 0x3ff) << 15; + svga->read_bank = ((val >> 10) & 0x3ff) << 15; + break; + + case PLL_pllCtrl0: + banshee->pllCtrl0 = val; + break; + case PLL_pllCtrl1: + banshee->pllCtrl1 = val; + break; + case PLL_pllCtrl2: + banshee->pllCtrl2 = val; + break; + + case DAC_dacMode: + banshee->dacMode = val; + break; + case DAC_dacAddr: + banshee->dacAddr = val & 0x1ff; + break; + case DAC_dacData: + svga->pallook[banshee->dacAddr] = val & 0xffffff; + svga->fullchange = changeframecount; + break; + + case Video_vidProcCfg: + banshee->vidProcCfg = val; +// pclog("vidProcCfg=%08x\n", val); + banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; + svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + + case Video_hwCurPatAddr: + banshee->hwCurPatAddr = val; + svga->hwcursor.addr = val & 0xfffff0; + break; + case Video_hwCurLoc: + banshee->hwCurLoc = val; + svga->hwcursor.x = (val & 0x7ff) - 32; + svga->hwcursor.y = ((val >> 16) & 0x7ff) - 64; + if (svga->hwcursor.y < 0) + { + svga->hwcursor.yoff = -svga->hwcursor.y; + svga->hwcursor.y = 0; + } + else + svga->hwcursor.yoff = 0; + svga->hwcursor.xsize = 64; + svga->hwcursor.ysize = 64; +// pclog("hwCurLoc %08x %i\n", val, svga->hwcursor.y); + break; + case Video_hwCurC0: + banshee->hwCurC0 = val; + break; + case Video_hwCurC1: + banshee->hwCurC1 = val; + break; + + case Video_vidScreenSize: + banshee->vidScreenSize = val; + voodoo->h_disp = (val & 0xfff) + 1; + voodoo->v_disp = (val >> 12) & 0xfff; + break; + case Video_vidOverlayStartCoords: + voodoo->overlay.vidOverlayStartCoords = val; + voodoo->overlay.start_x = val & OVERLAY_START_X_MASK; + voodoo->overlay.start_y = (val & OVERLAY_START_Y_MASK) >> OVERLAY_START_Y_SHIFT; + voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; + voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; + svga_recalctimings(svga); + break; + case Video_vidOverlayEndScreenCoords: + voodoo->overlay.vidOverlayEndScreenCoords = val; + voodoo->overlay.end_x = val & OVERLAY_END_X_MASK; + voodoo->overlay.end_y = (val & OVERLAY_END_Y_MASK) >> OVERLAY_END_Y_SHIFT; + voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; + voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; + svga_recalctimings(svga); + break; + case Video_vidOverlayDudx: + voodoo->overlay.vidOverlayDudx = val & VID_DUDX_MASK; +// pclog("vidOverlayDudx=%08x\n", val); + break; + case Video_vidOverlayDudxOffsetSrcWidth: + voodoo->overlay.vidOverlayDudxOffsetSrcWidth = val; + voodoo->overlay.overlay_bytes = (val & OVERLAY_SRC_WIDTH_MASK) >> OVERLAY_SRC_WIDTH_SHIFT; +// pclog("vidOverlayDudxOffsetSrcWidth=%08x\n", val); + break; + case Video_vidOverlayDvdy: + voodoo->overlay.vidOverlayDvdy = val & VID_DVDY_MASK; +// pclog("vidOverlayDvdy=%08x\n", val); + break; + case Video_vidOverlayDvdyOffset: + voodoo->overlay.vidOverlayDvdyOffset = val; + break; + + + case Video_vidDesktopStartAddr: + banshee->vidDesktopStartAddr = val; +// pclog("vidDesktopStartAddr=%08x\n", val); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + case Video_vidDesktopOverlayStride: + banshee->vidDesktopOverlayStride = val; +// pclog("vidDesktopOverlayStride=%08x\n", val); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; +// default: +// fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); + } +} + +static uint8_t banshee_ext_in(uint16_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; +// svga_t *svga = &banshee->svga; + uint8_t ret = 0xff; + + switch (addr & 0xff) + { + case Init_status: case Init_status+1: case Init_status+2: case Init_status+3: + ret = (banshee_status(banshee) >> ((addr & 3) * 8)) & 0xff; +// pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; + + case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: + case 0xbc: case 0xbd: case 0xbe: case 0xbf: + case 0xc0: case 0xc1: case 0xc2: case 0xc3: + case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: + case 0xcc: case 0xcd: case 0xce: case 0xcf: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: + case 0xdc: case 0xdd: case 0xde: case 0xdf: + ret = banshee_in((addr & 0xff)+0x300, p); + break; + + default: + fatal("bad banshee_ext_in: addr=%04x\n", addr); + break; + } + +// pclog("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); + + return ret; +} + +static uint32_t banshee_status(banshee_t *banshee) +{ + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + int fifo_entries = FIFO_ENTRIES; + int fifo_size = 0xffff - fifo_entries; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); + uint32_t ret; + + ret = 0; + if (fifo_size < 0x20) + ret |= fifo_size; + else + ret |= 0x1f; + if (fifo_size) + ret |= 0x20; + if (swap_count < 7) + ret |= (swap_count << 28); + else + ret |= (7 << 28); + if (!(svga->cgastat & 8)) + ret |= 0x40; + + if (busy) + ret |= 0x780; /*Busy*/ + + if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + ret |= (1 << 11); + + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_thread(voodoo); + +// pclog("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); + + return ret; +} + +static uint32_t banshee_ext_inl(uint16_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + uint32_t ret = 0xffffffff; + + cycles -= voodoo->read_time; + + switch (addr & 0xff) + { + case Init_status: + ret = banshee_status(banshee); +// pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; + case Init_lfbMemoryConfig: + ret = banshee->lfbMemoryConfig; + break; + + case Init_miscInit0: + ret = banshee->miscInit0; + break; + case Init_miscInit1: + ret = banshee->miscInit1; + break; + case Init_dramInit0: + ret = banshee->dramInit0; + break; + case Init_dramInit1: + ret = banshee->dramInit1; + break; + case Init_agpInit0: + ret = banshee->agpInit0; + break; + + case Init_vgaInit0: + ret = banshee->vgaInit0; + break; + case Init_vgaInit1: + ret = banshee->vgaInit1; + break; + + case Init_2dCommand: + ret = banshee->command_2d; + break; + case Init_2dSrcBaseAddr: + ret = banshee->srcBaseAddr_2d; + break; + case Init_strapInfo: + ret = 0x00000040; /*8 MB SGRAM, PCI, IRQ enabled, 32kB BIOS*/ + break; + + case PLL_pllCtrl0: + ret = banshee->pllCtrl0; + break; + case PLL_pllCtrl1: + ret = banshee->pllCtrl1; + break; + case PLL_pllCtrl2: + ret = banshee->pllCtrl2; + break; + + case DAC_dacMode: + ret = banshee->dacMode; + break; + case DAC_dacAddr: + ret = banshee->dacAddr; + break; + case DAC_dacData: + ret = svga->pallook[banshee->dacAddr]; + break; + + case Video_vidProcCfg: + ret = banshee->vidProcCfg; + break; + + case Video_hwCurPatAddr: + ret = banshee->hwCurPatAddr; + break; + case Video_hwCurLoc: + ret = banshee->hwCurLoc; + break; + case Video_hwCurC0: + ret = banshee->hwCurC0; + break; + case Video_hwCurC1: + ret = banshee->hwCurC1; + break; + + case Video_vidScreenSize: + ret = banshee->vidScreenSize; + break; + case Video_vidOverlayStartCoords: + ret = voodoo->overlay.vidOverlayStartCoords; + break; + case Video_vidOverlayEndScreenCoords: + ret = voodoo->overlay.vidOverlayEndScreenCoords; + break; + case Video_vidOverlayDudx: + ret = voodoo->overlay.vidOverlayDudx; + break; + case Video_vidOverlayDudxOffsetSrcWidth: + ret = voodoo->overlay.vidOverlayDudxOffsetSrcWidth; + break; + case Video_vidOverlayDvdy: + ret = voodoo->overlay.vidOverlayDvdy; + break; + case Video_vidOverlayDvdyOffset: + ret = voodoo->overlay.vidOverlayDvdyOffset; + break; + + case Video_vidDesktopStartAddr: + ret = banshee->vidDesktopStartAddr; + break; + case Video_vidDesktopOverlayStride: + ret = banshee->vidDesktopOverlayStride; + break; + + default: +// fatal("bad banshee_ext_inl: addr=%04x\n", addr); + break; + } + +// /*if (addr) */pclog("banshee_ext_inl: addr=%04x val=%08x\n", addr, ret); + + return ret; +} + + +static uint32_t banshee_reg_readl(uint32_t addr, void *p); + +static uint8_t banshee_reg_read(uint32_t addr, void *p) +{ +// pclog("banshee_reg_read: addr=%08x\n", addr); + return banshee_reg_readl(addr & ~3, p) >> (8*(addr & 3)); +} + +static uint16_t banshee_reg_readw(uint32_t addr, void *p) +{ +// pclog("banshee_reg_readw: addr=%08x\n", addr); + return banshee_reg_readl(addr & ~3, p) >> (8*(addr & 2)); +} + +static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) +{ + voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; + + switch (addr & 0x1fc) + { + case cmdBaseAddr0: + ret = voodoo->cmdfifo_base >> 12; +// pclog("Read cmdfifo_base %08x\n", ret); + break; + + case cmdRdPtrL0: + ret = voodoo->cmdfifo_rp; +// pclog("Read cmdfifo_rp %08x\n", ret); + break; + + case cmdFifoDepth0: + ret = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; +// pclog("Read cmdfifo_depth %08x\n", ret); + break; + + case 0x108: + break; + + default: + fatal("Unknown banshee_cmd_read %08x\n", addr); + } + + return ret; +} + +static uint32_t banshee_reg_readl(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; + + cycles -= voodoo->read_time; + + switch (addr & 0x1f00000) + { + case 0x0000000: /*IO remap*/ + if (!(addr & 0x80000)) + ret = banshee_ext_inl(addr & 0xff, banshee); + else + ret = banshee_cmd_read(banshee, addr); + break; + + case 0x0100000: /*2D registers*/ + voodoo_flush(voodoo); + switch (addr & 0x1fc) + { + case 0x08: + ret = voodoo->banshee_blt.clip0Min; + break; + case 0x0c: + ret = voodoo->banshee_blt.clip0Max; + break; + case 0x10: + ret = voodoo->banshee_blt.dstBaseAddr; + break; + case 0x14: + ret = voodoo->banshee_blt.dstFormat; + break; + case 0x34: + ret = voodoo->banshee_blt.srcBaseAddr; + break; + case 0x38: + ret = voodoo->banshee_blt.commandExtra; + break; + case 0x5c: + ret = voodoo->banshee_blt.srcXY; + break; + case 0x60: + ret = voodoo->banshee_blt.colorBack; + break; + case 0x64: + ret = voodoo->banshee_blt.colorFore; + break; + case 0x68: + ret = voodoo->banshee_blt.dstSize; + break; + case 0x6c: + ret = voodoo->banshee_blt.dstXY; + break; + case 0x70: + ret = voodoo->banshee_blt.command; + break; + default: + pclog("banshee_reg_readl: addr=%08x\n", addr); + } + break; + + case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/ + switch (addr & 0x3fc) + { + case SST_status: + ret = banshee_status(banshee); + break; + + case SST_intrCtrl: + ret = banshee->intrCtrl & 0x0030003f; + break; + + case SST_fbzColorPath: + voodoo_flush(voodoo); + ret = voodoo->params.fbzColorPath; + break; + case SST_fogMode: + voodoo_flush(voodoo); + ret = voodoo->params.fogMode; + break; + case SST_alphaMode: + voodoo_flush(voodoo); + ret = voodoo->params.alphaMode; + break; + case SST_fbzMode: + voodoo_flush(voodoo); + ret = voodoo->params.fbzMode; + break; + case SST_lfbMode: + voodoo_flush(voodoo); + ret = voodoo->lfbMode; + break; + case SST_clipLeftRight: + voodoo_flush(voodoo); + ret = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); + break; + case SST_clipLowYHighY: + voodoo_flush(voodoo); + ret = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); + break; + + case SST_clipLeftRight1: + voodoo_flush(voodoo); + ret = voodoo->params.clipRight1 | (voodoo->params.clipLeft1 << 16); + break; + case SST_clipTopBottom1: + voodoo_flush(voodoo); + ret = voodoo->params.clipHighY1 | (voodoo->params.clipLowY1 << 16); + break; + + case SST_stipple: + voodoo_flush(voodoo); + ret = voodoo->params.stipple; + break; + case SST_color0: + voodoo_flush(voodoo); + ret = voodoo->params.color0; + break; + case SST_color1: + voodoo_flush(voodoo); + ret = voodoo->params.color1; + break; + + case SST_fbiPixelsIn: + ret = voodoo->fbiPixelsIn & 0xffffff; + break; + case SST_fbiChromaFail: + ret = voodoo->fbiChromaFail & 0xffffff; + break; + case SST_fbiZFuncFail: + ret = voodoo->fbiZFuncFail & 0xffffff; + break; + case SST_fbiAFuncFail: + ret = voodoo->fbiAFuncFail & 0xffffff; + break; + case SST_fbiPixelsOut: + ret = voodoo->fbiPixelsOut & 0xffffff; + break; + + default: + fatal("banshee_reg_readl: 3D addr=%08x\n", addr); + break; + } + break; + } + +// /*if (addr != 0xe0000000) */pclog("banshee_reg_readl: addr=%08x ret=%08x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); +// if (cpu_state.pc == 0x1000e437) +// output = 3; + return ret; +} + +static void banshee_reg_write(uint32_t addr, uint8_t val, void *p) +{ +// pclog("banshee_reg_writeb: addr=%08x val=%02x\n", addr, val); +} + +static void banshee_reg_writew(uint32_t addr, uint16_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + + cycles -= voodoo->write_time; + +// pclog("banshee_reg_writew: addr=%08x val=%04x\n", addr, val); + switch (addr & 0x1f00000) + { + case 0x1000000: case 0x1100000: case 0x1200000: case 0x1300000: /*3D LFB*/ + case 0x1400000: case 0x1500000: case 0x1600000: case 0x1700000: + case 0x1800000: case 0x1900000: case 0x1a00000: case 0x1b00000: + case 0x1c00000: case 0x1d00000: case 0x1e00000: case 0x1f00000: + voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); + break; + } +} + +static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) +{ + voodoo_t *voodoo = banshee->voodoo; +// pclog("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); + switch (addr & 0x1fc) + { + case cmdBaseAddr0: + voodoo->cmdfifo_base = (val & 0x3ff) << 12; + voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); +// pclog("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val); + break; + + case cmdBaseSize0: + voodoo->cmdfifo_size = val; + voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); +// pclog("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + break; + +// voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; +// pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); +// break; + + case cmdRdPtrL0: + voodoo->cmdfifo_rp = val; + break; + case cmdAMin0: + voodoo->cmdfifo_amin = val; + break; + case cmdAMax0: + voodoo->cmdfifo_amax = val; + break; + case cmdFifoDepth0: + voodoo->cmdfifo_depth_rd = 0; + voodoo->cmdfifo_depth_wr = val & 0xffff; + break; + + default: + pclog("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val); + break; + } + +/* cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48 + }*/ +} + +static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + + if (addr == voodoo->last_write_addr+4) + cycles -= voodoo->burst_time; + else + cycles -= voodoo->write_time; + voodoo->last_write_addr = addr; + +// pclog("banshee_reg_writel: addr=%08x val=%08x\n", addr, val); + + switch (addr & 0x1f00000) + { + case 0x0000000: /*IO remap*/ + if (!(addr & 0x80000)) + banshee_ext_outl(addr & 0xff, val, banshee); + else + banshee_cmd_write(banshee, addr, val); +// pclog("CMD!!! write %08x %08x\n", addr, val); + break; + + case 0x0100000: /*2D registers*/ + voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val); + break; + + case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/ + switch (addr & 0x3fc) + { + case SST_intrCtrl: + banshee->intrCtrl = val & 0x0030003f; +// pclog("intrCtrl=%08x\n", val); + break; + + case SST_userIntrCMD: + fatal("userIntrCMD write %08x\n", val); + break; + + case SST_swapbufferCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); +// pclog("SST_swapbufferCMD write: %i %i\n", voodoo->cmd_written, voodoo->cmd_written_fifo); + break; + case SST_triangleCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_ftriangleCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_fastfillCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_nopCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + + case SST_swapPending: + voodoo->swap_count++; +// voodoo->cmd_written++; + break; + + default: + voodoo_queue_command(voodoo, (addr & 0x3ffffc) | FIFO_WRITEL_REG, val); + break; + } + break; + + case 0x0600000: case 0x0700000: /*Texture download*/ + voodoo->tex_count++; + voodoo_queue_command(voodoo, (addr & 0x1ffffc) | FIFO_WRITEL_TEX, val); + break; + + case 0x1000000: case 0x1100000: case 0x1200000: case 0x1300000: /*3D LFB*/ + case 0x1400000: case 0x1500000: case 0x1600000: case 0x1700000: + case 0x1800000: case 0x1900000: case 0x1a00000: case 0x1b00000: + case 0x1c00000: case 0x1d00000: case 0x1e00000: case 0x1f00000: + voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); + break; + } +} + +static uint8_t banshee_read_linear(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + cycles -= voodoo->read_time; + + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) + { + int x, y; +// uint32_t old_addr = addr; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride-1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + x + y*voodoo->tile_x; +// pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; + + egareads++; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; + +// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + + return svga->vram[addr & svga->vram_mask]; +} + +static uint16_t banshee_read_linear_w(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + cycles -= voodoo->read_time; + + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) + { + int x, y; +// uint32_t old_addr = addr; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride-1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + x + y*voodoo->tile_x; +// pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; + + egareads++; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; + +// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; +} + +static uint32_t banshee_read_linear_l(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + cycles -= voodoo->read_time; + + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) + { + int x, y; +// uint32_t old_addr = addr; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride-1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + x + y*voodoo->tile_x; +// pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; + + egareads++; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; + +// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; +} + +static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + cycles -= voodoo->write_time; + +// pclog("write_linear: addr=%08x val=%02x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) + { + int x, y; + uint32_t old_addr = addr; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride-1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + x + y*voodoo->tile_x; +// pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return; + + egawrites++; + + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; + + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr & svga->vram_mask] = val; +} + +static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + cycles -= voodoo->write_time; + +// pclog("write_linear: addr=%08x val=%02x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) + { + int x, y; + uint32_t old_addr = addr; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride-1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + x + y*voodoo->tile_x; +// pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return; + + egawrites++; + + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; + + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr & svga->vram_mask] = val; +} + +static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + if (addr == voodoo->last_write_addr+4) + cycles -= voodoo->burst_time; + else + cycles -= voodoo->write_time; + voodoo->last_write_addr = addr; + +// /*if (val) */pclog("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) + { + int x, y; + uint32_t old_addr = addr; + uint32_t addr_off; + uint32_t addr2; + + addr -= voodoo->tile_base; + addr_off = addr; + x = addr & (voodoo->tile_stride-1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr2 = x + y*voodoo->tile_x; +// pclog(" Tile %08x->%08x->%08x->%08x %i %i stride=%i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_stride, voodoo->tile_x); + } + + if (addr >= svga->vram_max) + return; + + egawrites += 4; + + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; + + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; + if (addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) + { +// pclog("CMDFIFO write %08x %08x %04x:%08x\n", addr, val, CS,cpu_state.pc); + voodoo->cmdfifo_depth_wr++; +// if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) + voodoo_wake_fifo_thread(voodoo); + } +} + +void banshee_hwcursor_draw(svga_t *svga, int displine) +{ + banshee_t *banshee = (banshee_t *)svga->p; + int x, c; + int x_off; + uint32_t col0 = banshee->hwCurC0; + uint32_t col1 = banshee->hwCurC1; + uint8_t plane0[8], plane1[8]; + + for (c = 0; c < 8; c++) + plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; + for (c = 0; c < 8; c++) + plane1[c] = svga->vram[svga->hwcursor_latch.addr + c + 8]; + svga->hwcursor_latch.addr += 16; + + x_off = svga->hwcursor_latch.x; + + for (x = 0; x < 64; x += 8) + { + if (x_off > (32-8)) + { + int xx; + + for (xx = 0; xx < 8; xx++) + { + if (!(plane0[x >> 3] & (1 << 7))) + ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + else if (plane1[x >> 3] & (1 << 7)) + ((uint32_t *)buffer32->line[displine])[x_off + xx] ^= 0xffffff; + + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; + } + } + + x_off += 8; + } +} + +#define CLAMP(x) do \ + { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } \ + while (0) + +#define DECODE_RGB565() \ + do \ + { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ + { \ + uint16_t data = *(uint16_t *)src; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + banshee->overlay_buffer[wp++] = (r << 3) | (g << 10) | (b << 19); \ + src += 2; \ + } \ + } while (0) + +#define DECODE_YUYV422() \ + do \ + { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) \ + { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359*Cr) >> 8; \ + dG = (88*Cb + 183*Cr) >> 8; \ + dB = (453*Cb) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + } \ + } while (0) + +#define DECODE_UYUV422() \ + do \ + { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) \ + { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + Cr = src[0] - 0x80; \ + y1 = src[1]; \ + Cb = src[2] - 0x80; \ + y2 = src[3]; \ + src += 4; \ + \ + dR = (359*Cr) >> 8; \ + dG = (88*Cb + 183*Cr) >> 8; \ + dB = (453*Cb) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + } \ + } while (0) + + +#define OVERLAY_SAMPLE() \ + do \ + { \ + switch (banshee->overlay_pix_fmt) \ + { \ + case 0: \ + break; \ + \ + case OVERLAY_FMT_YUYV422: \ + DECODE_YUYV422(); \ + break; \ + \ + case OVERLAY_FMT_UYVY422: \ + DECODE_UYUV422(); \ + break; \ + \ + case OVERLAY_FMT_565_DITHER: \ + DECODE_RGB565(); \ + break; \ + \ + default: \ + fatal("Unknown overlay pix fmt %i\n", banshee->overlay_pix_fmt); \ + } \ + } while (0) + +static void banshee_overlay_draw(svga_t *svga, int displine) +{ + banshee_t *banshee = (banshee_t *)svga->p; + voodoo_t *voodoo = banshee->voodoo; + uint32_t *p; + int x; + uint32_t src_addr = svga->overlay_latch.addr + svga->overlay_latch.pitch * (voodoo->overlay.src_y >> 20); + uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; + uint32_t src_x = 0; + +// pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); +// if (src_addr >= 0x800000) +// fatal("overlay out of range!\n"); + p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + 32]; + + OVERLAY_SAMPLE(); + + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + p[x] = banshee->overlay_buffer[src_x >> 20]; + + src_x += voodoo->overlay.vidOverlayDudx; + } + } + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[x]; + } + + if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) + voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; + else + voodoo->overlay.src_y += (1 << 20); +} + +void banshee_set_overlay_addr(void *p, uint32_t addr) +{ + banshee_t *banshee = (banshee_t *)p; + + banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; + banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; +} + +static void banshee_vsync_callback(svga_t *svga) +{ + banshee_t *banshee = (banshee_t *)svga->p; + voodoo_t *voodoo = banshee->voodoo; + + voodoo->retrace_count++; + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) + { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + banshee_set_overlay_addr(banshee, voodoo->swap_offset); + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } + + voodoo->overlay.src_y = 0; +} + +static uint8_t banshee_pci_read(int func, int addr, void *p) +{ + banshee_t *banshee = (banshee_t *)p; +// svga_t *svga = &banshee->svga; + uint8_t ret = 0; + + pclog("Banshee PCI read %08X ", addr); + switch (addr) + { + case 0x00: ret = 0x1a; break; /*3DFX*/ + case 0x01: ret = 0x12; break; + + case 0x02: ret = 0x03; break; + case 0x03: ret = 0x00; break; + + case 0x04: ret = banshee->pci_regs[0x04] & 0x27; break; + + case 0x07: ret = banshee->pci_regs[0x07] & 0x36; break; + + case 0x08: ret = 1; break; /*Revision ID*/ + case 0x09: ret = 0; break; /*Programming interface*/ + + case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ + case 0x0b: ret = 0x03; /*output = 3; */break; + + case 0x0d: ret = banshee->pci_regs[0x0d] & 0xf8; break; + + case 0x10: ret = 0x00; break; /*memBaseAddr0*/ + case 0x11: ret = 0x00; break; + case 0x12: ret = 0x00; break; + case 0x13: ret = banshee->memBaseAddr0 >> 24; break; + + case 0x14: ret = 0x00; break; /*memBaseAddr1*/ + case 0x15: ret = 0x00; break; + case 0x16: ret = 0x00; break; + case 0x17: ret = banshee->memBaseAddr1 >> 24; break; + + case 0x18: ret = 0x01; break; /*ioBaseAddr*/ + case 0x19: ret = banshee->ioBaseAddr >> 8; break; + case 0x1a: ret = 0x00; break; + case 0x1b: ret = 0x00; break; + + case 0x30: ret = banshee->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ + case 0x31: ret = 0x00; break; + case 0x32: ret = banshee->pci_regs[0x32]; break; + case 0x33: ret = banshee->pci_regs[0x33]; break; + + case 0x3c: ret = banshee->pci_regs[0x3c]; break; + + case 0x3d: ret = 0x01; break; /*INTA*/ + + case 0x3e: ret = 0x04; break; + case 0x3f: ret = 0xff; break; + + } + pclog("%02X\n", ret); + return ret; +} + +static void banshee_update_mapping(banshee_t *banshee) +{ +} + +static void banshee_pci_write(int func, int addr, uint8_t val, void *p) +{ + banshee_t *banshee = (banshee_t *)p; +// svga_t *svga = &banshee->svga; + + pclog("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + 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: + banshee_update_mapping(banshee); + if (val & PCI_COMMAND_IO) + { + io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + if (banshee->ioBaseAddr) + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + + io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + if (banshee->ioBaseAddr) + io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + } + else + { + io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + } + banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27; +// s3_virge_updatemapping(virge); + return; + case 0x07: + banshee->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + banshee->pci_regs[0x0d] = val & 0xf8; + return; + + case 0x13: + banshee->memBaseAddr0 = (val & 0xfe) << 24; + banshee_updatemapping(banshee); + return; + + case 0x17: + banshee->memBaseAddr1 = (val & 0xfe) << 24; + banshee_updatemapping(banshee); + return; + + case 0x19: + if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + banshee->ioBaseAddr = val << 8; + if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr) + io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + pclog("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr); +// s3_virge_updatemapping(virge); + return; + + case 0x30: case 0x32: case 0x33: + banshee->pci_regs[addr] = val; + if (banshee->pci_regs[0x30] & 0x01) + { + uint32_t addr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24); + pclog("Banshee bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x8000); + mem_mapping_enable(&banshee->bios_rom.mapping); + } + else + { + pclog("Banshee bios_rom disabled\n"); + mem_mapping_disable(&banshee->bios_rom.mapping); + } + return; + case 0x3c: + banshee->pci_regs[0x3c] = val; + return; + } +} + +static device_config_t banshee_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "" + } + }, + .default_int = 16 + }, + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 2 + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, +#endif + { + .type = -1 + } +}; + +static void *banshee_init() +{ + int mem_size; + banshee_t *banshee = malloc(sizeof(banshee_t)); + memset(banshee, 0, sizeof(banshee_t)); + + // rom_init(&banshee->bios_rom, "gainward.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&banshee->bios_rom, "a-trend.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + mem_size = device_get_config_int("memory"); + svga_init(&banshee->svga, banshee, mem_size << 20, + banshee_recalctimings, + banshee_in, banshee_out, + banshee_hwcursor_draw, + banshee_overlay_draw); + banshee->svga.vsync_callback = banshee_vsync_callback; + + mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear, + banshee_read_linear_w, + banshee_read_linear_l, + banshee_write_linear, + banshee_write_linear_w, + banshee_write_linear_l, + NULL, + 0, + &banshee->svga); + mem_mapping_add(&banshee->reg_mapping_low, 0, 0,banshee_reg_read, + banshee_reg_readw, + banshee_reg_readl, + banshee_reg_write, + banshee_reg_writew, + banshee_reg_writel, + NULL, + 0, + banshee); + mem_mapping_add(&banshee->reg_mapping_high, 0,0,banshee_reg_read, + banshee_reg_readw, + banshee_reg_readl, + banshee_reg_write, + banshee_reg_writew, + banshee_reg_writel, + NULL, + 0, + banshee); + +// io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + + banshee->svga.bpp = 8; + banshee->svga.miscout = 1; + + banshee->dramInit0 = 1 << 27; + if (mem_size == 16) + banshee->dramInit0 |= (1 << 26); /*2xSGRAM = 16 MB*/ +// banshee->dramInit1 = 1 << 30; /*SDRAM*/ + banshee->svga.decode_mask = 0x1ffffff; + + pci_add(banshee_pci_read, banshee_pci_write, banshee); + + banshee->voodoo = voodoo_2d3d_card_init(VOODOO_BANSHEE); + banshee->voodoo->p = banshee; + banshee->voodoo->vram = banshee->svga.vram; + banshee->voodoo->changedvram = banshee->svga.changedvram; + banshee->voodoo->fb_mem = banshee->svga.vram; + banshee->voodoo->fb_mask = banshee->svga.vram_mask; + banshee->voodoo->tex_mem[0] = banshee->svga.vram; + banshee->voodoo->tex_mem_w[0] = (uint16_t *)banshee->svga.vram; + banshee->voodoo->texture_mask = banshee->svga.vram_mask; + + return banshee; +} + +static int banshee_available() +{ + return rom_present("a-trend.VBI"); +} + +static void banshee_close(void *p) +{ + banshee_t *banshee = (banshee_t *)p; + + voodoo_card_close(banshee->voodoo); + svga_close(&banshee->svga); + + free(banshee); +} + +static void banshee_speed_changed(void *p) +{ + banshee_t *banshee = (banshee_t *)p; + + svga_recalctimings(&banshee->svga); +} + +static void banshee_force_redraw(void *p) +{ + banshee_t *banshee = (banshee_t *)p; + + banshee->svga.fullchange = changeframecount; +} + +static uint64_t status_time = 0; + +static void banshee_add_status_info(char *s, int max_len, void *p) +{ + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + char temps[512]; + int pixel_count_current[2]; + int pixel_count_total; + int texel_count_current[2]; + int texel_count_total; + int render_time[2]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; + + svga_add_status_info(s, max_len, &banshee->svga); + + + pixel_count_current[0] = voodoo->pixel_count[0]; + pixel_count_current[1] = voodoo->pixel_count[1]; + texel_count_current[0] = voodoo->texel_count[0]; + texel_count_current[1] = voodoo->texel_count[1]; + render_time[0] = voodoo->render_time[0]; + render_time[1] = voodoo->render_time[1]; + + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); + texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); + sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, + (double)pixel_count_total/1000000.0, + ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), + (double)texel_count_total/1000000.0, + ((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff), + (double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, + ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); + if (voodoo->render_threads == 2) + { + char temps2[512]; + sprintf(temps2, "%f%% CPU (%f%% real)\n", + ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps)-1); + } + + strncat(s, temps, max_len); + strncat(s, "\n", max_len); + + voodoo->pixel_count_old[0] = pixel_count_current[0]; + voodoo->pixel_count_old[1] = pixel_count_current[1]; + voodoo->texel_count_old[0] = texel_count_current[0]; + voodoo->texel_count_old[1] = texel_count_current[1]; + voodoo->tri_count = voodoo->frame_count = 0; + voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; + voodoo->time = 0; + voodoo->render_time[0] = voodoo->render_time[1] = 0; + + voodoo->read_time = pci_nonburst_time + pci_burst_time; + + voodoo_recomp = 0; +} + +device_t atrend_voodoo_banshee_device = +{ + "A-Trend Helios 3D (Voodoo Banshee)", + 0, + banshee_init, + banshee_close, + banshee_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_config +}; diff --git a/src/vid_voodoo_banshee.h b/src/vid_voodoo_banshee.h new file mode 100644 index 0000000..9479816 --- /dev/null +++ b/src/vid_voodoo_banshee.h @@ -0,0 +1,3 @@ +extern device_t atrend_voodoo_banshee_device; + +void banshee_set_overlay_addr(void *p, uint32_t addr); diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c new file mode 100644 index 0000000..032215b --- /dev/null +++ b/src/vid_voodoo_banshee_blitter.c @@ -0,0 +1,1305 @@ +/*Current issues : + - missing screen->screen scaled blits with format conversion + - missing YUV blits + - missing linestyle + - missing wait for vsync + - missing reversible lines + + Notes : + - 16 bpp runs with tiled framebuffer - to aid 3D? + 8 and 32 bpp use linear +*/ +#include +#include +#include "ibm.h" +#include "device.h" +#include "mem.h" +#include "thread.h" +#include "video.h" +#include "vid_svga.h" +#include "vid_voodoo.h" +#include "vid_voodoo_common.h" +#include "vid_voodoo_banshee_blitter.h" + +#define COMMAND_CMD_MASK (0xf) +#define COMMAND_CMD_NOP (0 << 0) +#define COMMAND_CMD_SCREEN_TO_SCREEN_BLT (1 << 0) +#define COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT (2 << 0) +#define COMMAND_CMD_HOST_TO_SCREEN_BLT (3 << 0) +#define COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT (4 << 0) +#define COMMAND_CMD_RECTFILL (5 << 0) +#define COMMAND_CMD_LINE (6 << 0) +#define COMMAND_CMD_POLYLINE (7 << 0) +#define COMMAND_CMD_POLYFILL (8 << 0) +#define COMMAND_INITIATE (1 << 8) +#define COMMAND_PATTERN_MONO (1 << 13) +#define COMMAND_DX (1 << 14) +#define COMMAND_DY (1 << 15) +#define COMMAND_TRANS_MONO (1 << 16) +#define COMMAND_PATOFF_X_MASK (7 << 17) +#define COMMAND_PATOFF_X_SHIFT (17) +#define COMMAND_PATOFF_Y_MASK (7 << 20) +#define COMMAND_PATOFF_Y_SHIFT (20) +#define COMMAND_CLIP_SEL (1 << 23) + +#define CMDEXTRA_SRC_COLORKEY (1 << 0) +#define CMDEXTRA_DST_COLORKEY (1 << 1) +#define CMDEXTRA_FORCE_PAT_ROW0 (1 << 3) + +#define SRC_FORMAT_STRIDE_MASK (0x1fff) +#define SRC_FORMAT_COL_MASK (0xf << 16) +#define SRC_FORMAT_COL_1_BPP (0 << 16) +#define SRC_FORMAT_COL_8_BPP (1 << 16) +#define SRC_FORMAT_COL_16_BPP (3 << 16) +#define SRC_FORMAT_COL_24_BPP (4 << 16) +#define SRC_FORMAT_COL_32_BPP (5 << 16) +#define SRC_FORMAT_COL_YUYV (8 << 16) +#define SRC_FORMAT_COL_UYVY (9 << 16) +#define SRC_FORMAT_BYTE_SWIZZLE (1 << 20) +#define SRC_FORMAT_WORD_SWIZZLE (1 << 21) +#define SRC_FORMAT_PACKING_MASK (3 << 22) +#define SRC_FORMAT_PACKING_STRIDE (0 << 22) +#define SRC_FORMAT_PACKING_BYTE (1 << 22) +#define SRC_FORMAT_PACKING_WORD (2 << 22) +#define SRC_FORMAT_PACKING_DWORD (3 << 22) + +#define DST_FORMAT_STRIDE_MASK (0x1fff) +#define DST_FORMAT_COL_MASK (0xf << 16) +#define DST_FORMAT_COL_8_BPP (1 << 16) +#define DST_FORMAT_COL_16_BPP (3 << 16) +#define DST_FORMAT_COL_24_BPP (4 << 16) +#define DST_FORMAT_COL_32_BPP (5 << 16) + +#define BRES_ERROR_MASK (0xffff) +#define BRES_ERROR_USE (1 << 31) + +enum +{ + COLORKEY_8, + COLORKEY_16, + COLORKEY_32 +}; + +static int colorkey(voodoo_t *voodoo, uint32_t src, int src_notdst, int color_format) +{ + uint32_t min = src_notdst ? voodoo->banshee_blt.srcColorkeyMin : voodoo->banshee_blt.dstColorkeyMin; + uint32_t max = src_notdst ? voodoo->banshee_blt.srcColorkeyMax : voodoo->banshee_blt.dstColorkeyMax; + + if (!(voodoo->banshee_blt.commandExtra & (src_notdst ? CMDEXTRA_SRC_COLORKEY : CMDEXTRA_DST_COLORKEY))) + return 0; + + switch (color_format) + { + case COLORKEY_8: + return ((src & 0xff) >= (min & 0xff)) && ((src & 0xff) <= (max & 0xff)); + + case COLORKEY_16: + { + int r = (src >> 11) & 0x1f, r_min = (min >> 11) & 0x1f, r_max = (max >> 11) & 0x1f; + int g = (src >> 5) & 0x3f, g_min = (min >> 5) & 0x3f, g_max = (max >> 5) & 0x3f; + int b = src & 0x1f, b_min = min & 0x1f, b_max = max & 0x1f; + + return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && + (b >= b_min) && (b <= b_max); + } + + case COLORKEY_32: + { + int r = (src >> 16) & 0xff, r_min = (min >> 16) & 0xff, r_max = (max >> 16) & 0xff; + int g = (src >> 8) & 0xff, g_min = (min >> 8) & 0xff, g_max = (max >> 8) & 0xff; + int b = src & 0xff, b_min = min & 0xff, b_max = max & 0xff; + + return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && + (b >= b_min) && (b <= b_max); + } + + default: + return 0; + } +} + +static uint32_t MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t pattern, int colour_format_src, int colour_format_dest) +{ + int rop_nr = 0; + uint32_t result = 0; + uint32_t rop; + + if (colorkey(voodoo, src, 1, colour_format_src)) + rop_nr |= 2; + if (colorkey(voodoo, dest, 0, colour_format_dest)) + rop_nr |= 1; + + rop = voodoo->banshee_blt.rops[rop_nr]; + + if (rop & 0x01) + result |= (~pattern & ~src & ~dest); + if (rop & 0x02) + result |= (~pattern & ~src & dest); + if (rop & 0x04) + result |= (~pattern & src & ~dest); + if (rop & 0x08) + result |= (~pattern & src & dest); + if (rop & 0x10) + result |= ( pattern & ~src & ~dest); + if (rop & 0x20) + result |= ( pattern & ~src & dest); + if (rop & 0x40) + result |= ( pattern & src & ~dest); + if (rop & 0x80) + result |= ( pattern & src & dest); + + return result; +} + +static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) +{ + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) + { + case DST_FORMAT_COL_8_BPP: + { + uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7)*8]; + + voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + } +} + +static void update_src_stride(voodoo_t *voodoo) +{ + int bpp; + + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) + { + case SRC_FORMAT_COL_1_BPP: + bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + bpp = 8; + break; + case SRC_FORMAT_COL_16_BPP: + bpp = 16; + break; + case SRC_FORMAT_COL_24_BPP: + bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + bpp = 32; + break; + + default: + bpp = 16; + break; + } + + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) + { + case SRC_FORMAT_PACKING_STRIDE: + voodoo->banshee_blt.src_stride_src = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + voodoo->banshee_blt.src_stride_dest = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + (voodoo->banshee_blt.srcX & 3) + 7) >> 3; + voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + (voodoo->banshee_blt.srcX & 3) + 7) >> 3; +// pclog("Stride packing %08x %08x bpp=%i dstSizeX=%i\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest, bpp, voodoo->banshee_blt.dstSizeX); + break; + + case SRC_FORMAT_PACKING_BYTE: + voodoo->banshee_blt.src_stride_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.src_stride_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; +// pclog("Byte packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + break; + + case SRC_FORMAT_PACKING_WORD: + voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 15) >> 4) * 2; + voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 15) >> 4) * 2; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; +// pclog("Word packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + break; + + case SRC_FORMAT_PACKING_DWORD: + voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 31) >> 5) * 4; + voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 31) >> 5) * 4; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; +// pclog("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + break; + } +} + +static void banshee_do_rectfill(voodoo_t *voodoo) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + +// pclog("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); +// pclog("clipping: %i,%i -> %i,%i\n", clip->x_min, clip->y_min, clip->x_max, clip->y_max); +// pclog("colorFore=%08x\n", voodoo->banshee_blt.colorFore); + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) + { + int dst_x = voodoo->banshee_blt.dstX; + + if (dst_y >= clip->y_min && dst_y < clip->y_max) + { + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) + { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } + } + dst_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + if (!(voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0)) + pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } +} + + +static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int src_colorkey; + + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) + { + case SRC_FORMAT_COL_8_BPP: + src_colorkey = COLORKEY_8; + break; + case SRC_FORMAT_COL_16_BPP: + src_colorkey = COLORKEY_16; + break; + default: + src_colorkey = COLORKEY_32; + break; + } +// pclog("do_screen_to_screen_line: srcFormat=%08x dst=%08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.dstFormat); + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == + (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) + { + /*No conversion required*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) + { + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) + { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) + { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) + { + case DST_FORMAT_COL_8_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x]; + uint32_t dest = voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7)*8]; + + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *)&src_p[src_x*2]; + uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint16_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x*3]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint32_t *)&voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x*4]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint32_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + } + } + if (use_x_dir) + { + src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } + else + { + src_x++; + dst_x++; + pat_x++; + } + } + } + voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } + else + { + /*Conversion required*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) + { +// int src_x = voodoo->banshee_blt.srcX; + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) + { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) + { + uint32_t src_data = 0; + int transparent = 0; + + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) + { + case SRC_FORMAT_COL_1_BPP: + { + uint8_t src_byte = src_p[src_x >> 3]; + src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; + if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) + transparent = !(src_byte & (0x80 >> (src_x & 7))); +// pclog(" 1bpp src_byte=%02x src_x=%i src_data=%x transparent=%i\n", src_byte, src_x, src_data, transparent); + break; + } + case SRC_FORMAT_COL_8_BPP: + { + src_data = src_p[src_x]; + break; + } + case SRC_FORMAT_COL_16_BPP: + { + uint16_t src_16 = *(uint16_t *)&src_p[src_x*2]; + int r = (src_16 >> 11); + int g = (src_16 >> 5) & 0x3f; + int b = src_16 & 0x1f; + + r = (r << 3) | (r >> 2); + g = (g << 2) | (g >> 4); + b = (b << 3) | (b >> 2); + src_data = (r << 16) | (g << 8) | b; + break; + } + case SRC_FORMAT_COL_24_BPP: + { + src_data = *(uint32_t *)&src_p[src_x*3]; + break; + } + case SRC_FORMAT_COL_32_BPP: + { + src_data = *(uint32_t *)&src_p[src_x*4]; + break; + } + + default: + fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); + } + + if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && + (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) + { + int r = src_data >> 16; + int g = (src_data >> 8) & 0xff; + int b = src_data & 0xff; + + src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + } + + if (!transparent) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, src_colorkey); + } + if (use_x_dir) + { + src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } + else + { + src_x++; + dst_x++; + pat_x++; + } + } + } + voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } +} + +static void banshee_do_screen_to_screen_blt(voodoo_t *voodoo) +{ +// pclog("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); +// return; + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) + { + uint32_t src_addr = (voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*/*voodoo->banshee_blt.src_stride*/voodoo->banshee_blt.src_stride_dest) & voodoo->fb_mask; +// if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) +// pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); + do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX); + } +} + +static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) +{ +// if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) +// pclog("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) + data = (data >> 16) | (data << 16); + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) + { + int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; + + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + if (voodoo->banshee_blt.host_data_count >= last_byte) + { +// pclog(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) + { + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7); + else + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0); + voodoo->banshee_blt.cur_y++; + } + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; + else + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + +// pclog(" %i %i %i %i %i\n", (voodoo->banshee_blt.srcX & 3), (last_byte & 3), (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK)); +#if 0 + if ((voodoo->banshee_blt.srcX & 3) >= last_byte)// & 3) && (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) < 4) + { + *(uint32_t *)voodoo->banshee_blt.host_data = *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count-4]; + voodoo->banshee_blt.host_data_count = 4; + } + else + { +#endif + voodoo->banshee_blt.host_data_count = 0; +// } +// last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; +// pclog(" host_data_count=%i last_byte=%i srcX=%i\n", voodoo->banshee_blt.host_data_count, last_byte, voodoo->banshee_blt.srcX); + } + } + else + { + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_dest) + { + voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_dest; + +// pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) + { + do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0); + voodoo->banshee_blt.cur_y++; + } + + if (voodoo->banshee_blt.host_data_count) + { +// pclog(" remaining=%i\n", voodoo->banshee_blt.host_data_count); + *(uint32_t *)&voodoo->banshee_blt.host_data[0] = data >> (4-voodoo->banshee_blt.host_data_count)*8; + } + } + } +} + +static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, int src_x, int *src_y) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; +// int src_y = voodoo->banshee_blt.srcY; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; + + //int error_y = voodoo->banshee_blt.dstSizeY / 2; + +/* pclog("banshee_do_screen_to_screen_stretch_blt:\n"); + pclog(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY); + pclog(" dstXY=%i,%i dstsizeXY=%i,%i\n", voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) + { +// int src_x = voodoo->banshee_blt.srcX; + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int error_x = voodoo->banshee_blt.dstSizeX / 2; + +// pclog(" Plot dest line %03i : src line %03i\n", dst_y, src_y); + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) + { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) + { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) + { + case DST_FORMAT_COL_8_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x]; + uint32_t dest = voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); +// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *)&src_p[src_x*2]; + uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint16_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); +// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x*3]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint32_t *)&voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *)&voodoo->vram[dst_addr] & 0xff000000); +// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x*4]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? + ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : + colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + + *(uint32_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); +// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + } + } + + error_x -= voodoo->banshee_blt.srcSizeX; + while (error_x < 0) + { + error_x += voodoo->banshee_blt.dstSizeX; + src_x++; + } + dst_x++; + pat_x++; + } + } + + voodoo->banshee_blt.bres_error_0 -= voodoo->banshee_blt.srcSizeY; + while (voodoo->banshee_blt.bres_error_0 < 0) + { + voodoo->banshee_blt.bres_error_0 += voodoo->banshee_blt.dstSizeY; + if (src_y) + (*src_y) += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; +// pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; +} + +static void banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) +{ +// pclog("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); +// return; + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) + { + uint32_t src_addr = (voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; + pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); +// if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) +// pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); + do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); + } +} + +static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, uint32_t data) +{ +// if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) +// pclog("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) + data = (data >> 16) | (data << 16); + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) + { + int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_src; + + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + if (voodoo->banshee_blt.host_data_count >= last_byte) + { +// pclog(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) + { + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], voodoo->banshee_blt.srcX & 7, NULL); + else + do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, NULL); + voodoo->banshee_blt.cur_y++; + } + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; + else + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + + voodoo->banshee_blt.host_data_count = 0; + } + } + else + { + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_src) + { + voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_src; + +// pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) + { + do_screen_to_screen_stretch_line(voodoo, voodoo->banshee_blt.host_data, 0, NULL); + voodoo->banshee_blt.cur_y++; + } + + if (voodoo->banshee_blt.host_data_count) + { +// pclog(" remaining=%i\n", voodoo->banshee_blt.host_data_count); + *(uint32_t *)&voodoo->banshee_blt.host_data[0] = data >> (4-voodoo->banshee_blt.host_data_count)*8; + } + } + } +} + +static void banshee_do_line(voodoo_t *voodoo) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.srcY); + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.srcX; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); + int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); + int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; + int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; + int x = voodoo->banshee_blt.srcX; + int y = voodoo->banshee_blt.srcY; + int error; + + if (dx > dy) /*X major*/ + { + error = dx/2; + while (x != voodoo->banshee_blt.dstX) + { + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + + error -= dy; + if (error < 0) + { + error += dx; + y += y_inc; + pat_y += y_inc; + } + x += x_inc; + pat_x += x_inc; + } + } + else /*Y major*/ + { + error = dy/2; + while (y != voodoo->banshee_blt.dstY) + { + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + + error -= dx; + if (error < 0) + { + error += dy; + x += x_inc; + pat_x += x_inc; + } + y += y_inc; + pat_y += y_inc; + } + } + + voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16); + voodoo->banshee_blt.srcX = x; + voodoo->banshee_blt.srcY = y; +} + +static void banshee_polyfill_start(voodoo_t *voodoo) +{ + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.srcY; + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.dstY; + voodoo->banshee_blt.lx[1] = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.ly[1] = voodoo->banshee_blt.srcY; + voodoo->banshee_blt.rx[1] = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.ry[1] = voodoo->banshee_blt.dstY; + voodoo->banshee_blt.lx_cur = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.rx_cur = voodoo->banshee_blt.dstX; +} + +static void banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); + int y_end; + +// pclog("Polyfill : data %08x\n", data); + + /*if r1.y>=l1.y, next vertex is left*/ + if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) + { + voodoo->banshee_blt.lx[1] = ((int32_t)(data << 19)) >> 19; + voodoo->banshee_blt.ly[1] = ((int32_t)(data << 3)) >> 19; + voodoo->banshee_blt.dx[0] = ABS(voodoo->banshee_blt.lx[1] - voodoo->banshee_blt.lx[0]); + voodoo->banshee_blt.dy[0] = ABS(voodoo->banshee_blt.ly[1] - voodoo->banshee_blt.ly[0]); + voodoo->banshee_blt.x_inc[0] = (voodoo->banshee_blt.lx[1] > voodoo->banshee_blt.lx[0]) ? 1 : -1; + voodoo->banshee_blt.error[0] = voodoo->banshee_blt.dy[0] / 2; + } + else + { + voodoo->banshee_blt.rx[1] = ((int32_t)(data << 19)) >> 19; + voodoo->banshee_blt.ry[1] = ((int32_t)(data << 3)) >> 19; + voodoo->banshee_blt.dx[1] = ABS(voodoo->banshee_blt.rx[1] - voodoo->banshee_blt.rx[0]); + voodoo->banshee_blt.dy[1] = ABS(voodoo->banshee_blt.ry[1] - voodoo->banshee_blt.ry[0]); + voodoo->banshee_blt.x_inc[1] = (voodoo->banshee_blt.rx[1] > voodoo->banshee_blt.rx[0]) ? 1 : -1; + voodoo->banshee_blt.error[1] = voodoo->banshee_blt.dy[1] / 2; + } + +/* pclog(" verts now : %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[0], voodoo->banshee_blt.ly[0], voodoo->banshee_blt.rx[0], voodoo->banshee_blt.ry[0]); + pclog(" %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[1], voodoo->banshee_blt.ly[1], voodoo->banshee_blt.rx[1], voodoo->banshee_blt.ry[1]); + pclog(" left dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[0],voodoo->banshee_blt.dy[0],voodoo->banshee_blt.x_inc[0],voodoo->banshee_blt.error[0]); + pclog(" right dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[1],voodoo->banshee_blt.dy[1],voodoo->banshee_blt.x_inc[1],voodoo->banshee_blt.error[1]);*/ + y_end = MIN(voodoo->banshee_blt.ly[1], voodoo->banshee_blt.ry[1]); +// pclog("Polyfill : draw spans from %i-%i\n", y, y_end); + for (; y < y_end; y++) + { +// pclog(" %i: %i %i\n", y, voodoo->banshee_blt.lx_cur, voodoo->banshee_blt.rx_cur); + /*Draw span from lx_cur to rx_cur*/ + if (y >= clip->y_min && y < clip->y_max) + { + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + y); + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int x; + + for (x = voodoo->banshee_blt.lx_cur; x < voodoo->banshee_blt.rx_cur; x++) + { + int pat_x = voodoo->banshee_blt.patoff_x + x; + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + + if (x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + } + } + + voodoo->banshee_blt.error[0] -= voodoo->banshee_blt.dx[0]; + while (voodoo->banshee_blt.error[0] < 0) + { + voodoo->banshee_blt.error[0] += voodoo->banshee_blt.dy[0]; + voodoo->banshee_blt.lx_cur += voodoo->banshee_blt.x_inc[0]; + } + voodoo->banshee_blt.error[1] -= voodoo->banshee_blt.dx[1]; + while (voodoo->banshee_blt.error[1] < 0) + { + voodoo->banshee_blt.error[1] += voodoo->banshee_blt.dy[1]; + voodoo->banshee_blt.rx_cur += voodoo->banshee_blt.x_inc[1]; + } + } + + if (voodoo->banshee_blt.ry[1] == voodoo->banshee_blt.ly[1]) + { + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; + } + else if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) + { + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; + } + else + { + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; + } +} + +static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) +{ + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) + { + case COMMAND_CMD_NOP: + break; + + case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: + banshee_do_screen_to_screen_blt(voodoo); + break; + + case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: + banshee_do_screen_to_screen_stretch_blt(voodoo); + break; + + case COMMAND_CMD_HOST_TO_SCREEN_BLT: + banshee_do_host_to_screen_blt(voodoo, count, data); + break; + + case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: + banshee_do_host_to_screen_stretch_blt(voodoo, count, data); + break; + + case COMMAND_CMD_RECTFILL: + banshee_do_rectfill(voodoo); + break; + + case COMMAND_CMD_POLYLINE: + banshee_do_line(voodoo); + break; + + default: + fatal("banshee_do_2d_blit: unknown command=%08x\n", voodoo->banshee_blt.command); + } +} + +void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) +{ +// /*if ((addr & 0x1fc) != 0x80) */pclog("2D reg write %03x %08x\n", addr & 0x1fc, val); + switch (addr & 0x1fc) + { + case 0x08: + voodoo->banshee_blt.clip0Min = val; + voodoo->banshee_blt.clip[0].x_min = val & 0xfff; + voodoo->banshee_blt.clip[0].y_min = (val >> 16) & 0xfff; + break; + case 0x0c: + voodoo->banshee_blt.clip0Max = val; + voodoo->banshee_blt.clip[0].x_max = val & 0xfff; + voodoo->banshee_blt.clip[0].y_max = (val >> 16) & 0xfff; + break; + case 0x10: + voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; + voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; + if (voodoo->banshee_blt.dstBaseAddr_tiled) + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128; + else + voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; +// pclog("dstBaseAddr=%08x\n", val); + break; + case 0x14: + voodoo->banshee_blt.dstFormat = val; + if (voodoo->banshee_blt.dstBaseAddr_tiled) + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128; + else + voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; +// pclog("dstFormat=%08x\n", val); + break; + + case 0x18: + voodoo->banshee_blt.srcColorkeyMin = val & 0xffffff; + break; + case 0x1c: + voodoo->banshee_blt.srcColorkeyMax = val & 0xffffff; + break; + case 0x20: + voodoo->banshee_blt.dstColorkeyMin = val & 0xffffff; + break; + case 0x24: + voodoo->banshee_blt.dstColorkeyMax = val & 0xffffff; + break; + + case 0x28: + voodoo->banshee_blt.bresError0 = val; + voodoo->banshee_blt.bres_error_0 = val & 0xffff; + break; + case 0x2c: + voodoo->banshee_blt.bresError1 = val; + voodoo->banshee_blt.bres_error_1 = val & 0xffff; + break; + + case 0x30: + voodoo->banshee_blt.rop = val; + voodoo->banshee_blt.rops[1] = val & 0xff; + voodoo->banshee_blt.rops[2] = (val >> 8) & 0xff; + voodoo->banshee_blt.rops[3] = (val >> 16) & 0xff; +// pclog("rop=%08x\n", val); + break; + case 0x34: + voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; + voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; + if (voodoo->banshee_blt.srcBaseAddr_tiled) + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128; + else + voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + update_src_stride(voodoo); +// pclog("srcBaseAddr=%08x\n", val); + break; + case 0x38: + voodoo->banshee_blt.commandExtra = val; +// pclog("commandExtra=%08x\n", val); + break; + case 0x44: + voodoo->banshee_blt.colorPattern[0] = val; +// pclog("colorPattern0=%08x\n", val); + voodoo->banshee_blt.colorPattern24[0] = val & 0xffffff; + voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xffff00) | (val >> 24); + voodoo->banshee_blt.colorPattern16[0] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[1] = (val >> 16) & 0xffff; + voodoo->banshee_blt.colorPattern8[0] = val & 0xff; + voodoo->banshee_blt.colorPattern8[1] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[2] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[3] = (val >> 24) & 0xff; + break; + case 0x48: + voodoo->banshee_blt.colorPattern[1] = val; +// pclog("colorPattern1=%08x\n", val); + voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xff) | ((val & 0xffff) << 8); + voodoo->banshee_blt.colorPattern24[2] = (voodoo->banshee_blt.colorPattern24[2] & 0xff0000) | (val >> 16); + voodoo->banshee_blt.colorPattern16[2] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[3] = (val >> 16) & 0xffff; + voodoo->banshee_blt.colorPattern8[4] = val & 0xff; + voodoo->banshee_blt.colorPattern8[5] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[6] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[7] = (val >> 24) & 0xff; + break; + case 0x4c: + voodoo->banshee_blt.clip1Min = val; + voodoo->banshee_blt.clip[1].x_min = val & 0xfff; + voodoo->banshee_blt.clip[1].y_min = (val >> 16) & 0xfff; + break; + case 0x50: + voodoo->banshee_blt.clip1Max = val; + voodoo->banshee_blt.clip[1].x_max = val & 0xfff; + voodoo->banshee_blt.clip[1].y_max = (val >> 16) & 0xfff; + break; + case 0x54: + voodoo->banshee_blt.srcFormat = val; + if (voodoo->banshee_blt.srcBaseAddr_tiled) + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128; + else + voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + update_src_stride(voodoo); +// pclog("srcFormat=%08x\n", val); + break; + case 0x58: + voodoo->banshee_blt.srcSize = val; + voodoo->banshee_blt.srcSizeX = voodoo->banshee_blt.srcSize & 0x1fff; + voodoo->banshee_blt.srcSizeY = (voodoo->banshee_blt.srcSize >> 16) & 0x1fff; + update_src_stride(voodoo); +// pclog("srcSize=%08x\n", val); + break; + case 0x5c: + voodoo->banshee_blt.srcXY = val; + voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; + update_src_stride(voodoo); +// pclog("srcXY=%08x\n", val); + break; + case 0x60: + voodoo->banshee_blt.colorBack = val; + break; + case 0x64: + voodoo->banshee_blt.colorFore = val; + break; + case 0x68: + voodoo->banshee_blt.dstSize = val; + voodoo->banshee_blt.dstSizeX = voodoo->banshee_blt.dstSize & 0x1fff; + voodoo->banshee_blt.dstSizeY = (voodoo->banshee_blt.dstSize >> 16) & 0x1fff; + update_src_stride(voodoo); +// pclog("dstSize=%08x\n", val); + break; + case 0x6c: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; +// pclog("dstXY=%08x\n", val); + break; + case 0x70: + voodoo->banshee_blt.command = val; + voodoo->banshee_blt.rops[0] = val >> 24; +// pclog("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); + voodoo->banshee_blt.patoff_x = (val & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; + voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; + voodoo->banshee_blt.cur_x = 0; + voodoo->banshee_blt.cur_y = 0; + voodoo->banshee_blt.srcX = ((int32_t)(voodoo->banshee_blt.srcXY << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t)(voodoo->banshee_blt.srcXY << 3)) >> 19; + voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.host_data_remainder = 0; + voodoo->banshee_blt.host_data_count = 0; + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) + { +/* case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: + if (voodoo->banshee_blt.bresError0 & BRES_ERROR_USE) + voodoo->banshee_blt.bres_error_0 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError0 & BRES_ERROR_MASK); + else + voodoo->banshee_blt.bres_error_0 = voodoo->banshee_blt.dstSizeY / 2; + if (voodoo->banshee_blt.bresError1 & BRES_ERROR_USE) + voodoo->banshee_blt.bres_error_1 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError1 & BRES_ERROR_MASK); + else + voodoo->banshee_blt.bres_error_1 = voodoo->banshee_blt.dstSizeX / 2; + + if (val & COMMAND_INITIATE) + banshee_do_2d_blit(voodoo, -1, 0); + break;*/ + + case COMMAND_CMD_POLYFILL: + if (val & COMMAND_INITIATE) + { + voodoo->banshee_blt.dstXY = voodoo->banshee_blt.srcXY; + voodoo->banshee_blt.dstX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.dstY = voodoo->banshee_blt.srcY; + } + banshee_polyfill_start(voodoo); + break; + + default: + if (val & COMMAND_INITIATE) + { + banshee_do_2d_blit(voodoo, -1, 0); + // fatal("Initiate command!\n"); + } + break; + } + break; + + case 0x80: case 0x84: case 0x88: case 0x8c: + case 0x90: case 0x94: case 0x98: case 0x9c: + case 0xa0: case 0xa4: case 0xa8: case 0xac: + case 0xb0: case 0xb4: case 0xb8: case 0xbc: + case 0xc0: case 0xc4: case 0xc8: case 0xcc: + case 0xd0: case 0xd4: case 0xd8: case 0xdc: + case 0xe0: case 0xe4: case 0xe8: case 0xec: + case 0xf0: case 0xf4: case 0xf8: case 0xfc: +// pclog("launch %08x %08x %08x %08x\n", voodoo->banshee_blt.command, voodoo->banshee_blt.commandExtra, voodoo->banshee_blt.srcColorkeyMin, voodoo->banshee_blt.srcColorkeyMax); + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) + { + case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: + voodoo->banshee_blt.srcXY = val; + voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; + banshee_do_screen_to_screen_blt(voodoo); + break; + + case COMMAND_CMD_HOST_TO_SCREEN_BLT: + banshee_do_2d_blit(voodoo, 32, val); + break; + + case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: + banshee_do_2d_blit(voodoo, 32, val); + break; + + case COMMAND_CMD_RECTFILL: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + banshee_do_rectfill(voodoo); + break; + +/* case COMMAND_CMD_LINE: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + banshee_do_line(voodoo); + break;*/ + + case COMMAND_CMD_POLYLINE: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + banshee_do_line(voodoo); + break; + + case COMMAND_CMD_POLYFILL: + banshee_polyfill_continue(voodoo, val); + break; + + default: + fatal("launch area write, command=%08x\n", voodoo->banshee_blt.command); + } + break; + + case 0x100: case 0x104: case 0x108: case 0x10c: + case 0x110: case 0x114: case 0x118: case 0x11c: + case 0x120: case 0x124: case 0x128: case 0x12c: + case 0x130: case 0x134: case 0x138: case 0x13c: + case 0x140: case 0x144: case 0x148: case 0x14c: + case 0x150: case 0x154: case 0x158: case 0x15c: + case 0x160: case 0x164: case 0x168: case 0x16c: + case 0x170: case 0x174: case 0x178: case 0x17c: + case 0x180: case 0x184: case 0x188: case 0x18c: + case 0x190: case 0x194: case 0x198: case 0x19c: + case 0x1a0: case 0x1a4: case 0x1a8: case 0x1ac: + case 0x1b0: case 0x1b4: case 0x1b8: case 0x1bc: + case 0x1c0: case 0x1c4: case 0x1c8: case 0x1cc: + case 0x1d0: case 0x1d4: case 0x1d8: case 0x1dc: + case 0x1e0: case 0x1e4: case 0x1e8: case 0x1ec: + case 0x1f0: case 0x1f4: case 0x1f8: case 0x1fc: + voodoo->banshee_blt.colorPattern[(addr >> 2) & 63] = val; + if ((addr & 0x1fc) < 0x1c0) + { + int base_addr = (addr & 0xfc) / 0xc; + uintptr_t src_p = (uintptr_t)&voodoo->banshee_blt.colorPattern[base_addr * 3]; + int col24 = base_addr * 4; + + voodoo->banshee_blt.colorPattern24[col24] = *(uint32_t *)src_p & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 1] = *(uint32_t *)(src_p + 3) & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 2] = *(uint32_t *)(src_p + 6) & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 3] = *(uint32_t *)(src_p + 9) & 0xffffff; + } + if ((addr & 0x1fc) < 0x180) + { + voodoo->banshee_blt.colorPattern16[(addr >> 1) & 62] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[((addr >> 1) & 62) + 1] = (val >> 16) & 0xffff; + } + if ((addr & 0x1fc) < 0x140) + { + voodoo->banshee_blt.colorPattern8[addr & 60] = val & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 1] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 2] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 3] = (val >> 24) & 0xff; + } +// pclog("colorPattern%02x=%08x\n", (addr >> 2) & 63, val); + break; + + default: + fatal("Unknown 2D reg write %03x %08x\n", addr & 0x1fc, val); + } +} diff --git a/src/vid_voodoo_banshee_blitter.h b/src/vid_voodoo_banshee_blitter.h new file mode 100644 index 0000000..cc7a8f2 --- /dev/null +++ b/src/vid_voodoo_banshee_blitter.h @@ -0,0 +1 @@ +void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 5d14b24..193e1b9 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -2175,6 +2175,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo // addbyte(0x7e); // addbyte(0x87); // addlong(offsetof(voodoo_state_t, out)); + if (voodoo->type != VOODOO_BANSHEE) /*HACK*/ + { if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) @@ -2377,6 +2379,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo src_g = CLAMP(src_g); src_b = CLAMP(src_b);*/ } + } if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) { diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 093fccd..4d3a809 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -20,8 +20,9 @@ enum { VOODOO_1 = 0, - VOODOO_SB50 = 1, - VOODOO_2 = 2 + VOODOO_SB50, + VOODOO_2, + VOODOO_BANSHEE }; typedef union int_float @@ -62,11 +63,12 @@ typedef union rgba_u enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITEL_REG = (0x01 << 24), - FIFO_WRITEW_FB = (0x02 << 24), - FIFO_WRITEL_FB = (0x03 << 24), - FIFO_WRITEL_TEX = (0x04 << 24) + FIFO_INVALID = (0x00 << 24), + FIFO_WRITEL_REG = (0x01 << 24), + FIFO_WRITEW_FB = (0x02 << 24), + FIFO_WRITEL_FB = (0x03 << 24), + FIFO_WRITEL_TEX = (0x04 << 24), + FIFO_WRITEL_2DREG = (0x05 << 24) }; #define PARAM_SIZE 1024 @@ -147,6 +149,7 @@ typedef struct voodoo_params_t int tformat[2]; int clipLeft, clipRight, clipLowY, clipHighY; + int clipLeft1, clipRight1, clipLowY1, clipHighY1; int sign; @@ -177,6 +180,12 @@ typedef struct vert_t float sW1, sS1, sT1; } vert_t; +typedef struct clip_t +{ + int x_min, x_max; + int y_min, y_max; +} clip_t; + typedef struct voodoo_t { mem_mapping_t mapping; @@ -287,7 +296,7 @@ typedef struct voodoo_t voodoo_params_t params_buffer[PARAM_SIZE]; volatile int params_read_idx[2], params_write_idx; - uint32_t cmdfifo_base, cmdfifo_end; + uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; int cmdfifo_rp; volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; uint32_t cmdfifo_amin, cmdfifo_amax; @@ -296,6 +305,7 @@ typedef struct voodoo_t vert_t verts[4]; int vertex_num; int num_verticies; + int cull_pingpong; int flush; @@ -332,6 +342,8 @@ typedef struct voodoo_t uint32_t bltCommand; + uint32_t leftOverlayBuf; + struct { int dst_x, dst_y; @@ -341,6 +353,80 @@ typedef struct voodoo_t int dst_stride; } blt; + struct + { + uint32_t bresError0, bresError1; + uint32_t clip0Min, clip0Max; + uint32_t clip1Min, clip1Max; + uint32_t colorBack, colorFore; + uint32_t command, commandExtra; + uint32_t dstBaseAddr; + uint32_t dstFormat; + uint32_t dstSize; + uint32_t dstXY; + uint32_t rop; + uint32_t srcBaseAddr; + uint32_t srcFormat; + uint32_t srcSize; + uint32_t srcXY; + + uint32_t colorPattern[64]; + + int bres_error_0, bres_error_1; + uint32_t colorPattern8[64], colorPattern16[64], colorPattern24[64]; + int cur_x, cur_y; + uint32_t dstBaseAddr_tiled; + uint32_t dstColorkeyMin, dstColorkeyMax; + int dstSizeX, dstSizeY; + int dstX, dstY; + int dst_stride; + int patoff_x, patoff_y; + uint8_t rops[4]; + uint32_t srcBaseAddr_tiled; + uint32_t srcColorkeyMin, srcColorkeyMax; + int srcSizeX, srcSizeY; + int srcX, srcY; + int src_stride; + int old_srcX; + + /*Used for handling packed 24bpp host data*/ + int host_data_remainder; + uint32_t old_host_data; + + /*Polyfill coordinates*/ + int lx[2], rx[2]; + int ly[2], ry[2]; + + /*Polyfill state*/ + int error[2]; + int dx[2], dy[2]; + int x_inc[2]; /*y_inc is always 1 for polyfill*/ + int lx_cur, rx_cur; + + clip_t clip[2]; + + uint8_t host_data[16384]; + int host_data_count; + int host_data_size_src, host_data_size_dest; + int src_stride_src, src_stride_dest; + } banshee_blt; + + struct + { + uint32_t vidOverlayStartCoords; + uint32_t vidOverlayEndScreenCoords; + uint32_t vidOverlayDudx, vidOverlayDudxOffsetSrcWidth; + uint32_t vidOverlayDvdy, vidOverlayDvdyOffset; + //uint32_t vidDesktopOverlayStride; + + int start_x, start_y; + int end_x, end_y; + int size_x, size_y; + int overlay_bytes; + + unsigned int src_y; + } overlay; + rgb_t clutData[33]; int clutData_dirty; rgb_t clutData256[256]; @@ -351,6 +437,9 @@ typedef struct voodoo_t int fb_write_buffer, fb_draw_buffer; int buffer_cutoff; + + uint32_t tile_base, tile_stride; + int tile_stride_shift, tile_x; int read_time, write_time, burst_time; @@ -364,7 +453,7 @@ typedef struct voodoo_t uint16_t purpleline[256][3]; texture_t texture_cache[2][TEX_CACHE_MAX]; - uint8_t texture_present[2][4096]; + uint8_t texture_present[2][16384]; int texture_last_removed; uint32_t palette_checksum[2]; @@ -377,6 +466,11 @@ typedef struct voodoo_t void *codegen_data; struct voodoo_set_t *set; + + + uint8_t *vram, *changedvram; + + void *p; } voodoo_t; typedef struct voodoo_set_t @@ -397,3 +491,5 @@ extern rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], a void voodoo_recalc(voodoo_t *voodoo); void voodoo_update_ncc(voodoo_t *voodoo, int tmu); +void *voodoo_2d3d_card_init(int type); +void voodoo_card_close(voodoo_t *voodoo); diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index ccf112e..393137e 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -8,6 +8,7 @@ #include "vid_svga.h" #include "vid_voodoo.h" #include "vid_voodoo_common.h" +#include "vid_voodoo_banshee_blitter.h" #include "vid_voodoo_fb.h" #include "vid_voodoo_fifo.h" #include "vid_voodoo_reg.h" @@ -205,6 +206,18 @@ void voodoo_fifo_thread(void *param) fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; } break; + case FIFO_WRITEL_2DREG: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG) + { + voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + + default: + fatal("Unknown fifo entry %08x\n", fifo->addr_type); } if (FIFO_ENTRIES > 0xe000) @@ -226,7 +239,7 @@ void voodoo_fifo_thread(void *param) int num_verticies; int v_num; -// pclog(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); +// pclog(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); switch (header & 7) { @@ -254,17 +267,48 @@ void voodoo_fifo_thread(void *param) while (num--) { uint32_t val = cmdfifo_get(voodoo); - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; + if ((addr & (1 << 13)) && voodoo->type == VOODOO_BANSHEE) + { +// if (voodoo->type != VOODOO_BANSHEE) +// fatal("CMDFIFO1: Not Banshee\n"); +// pclog("CMDFIFO1: write %08x %08x\n", addr, val); + voodoo_2d_reg_writel(voodoo, addr, val); + } + else + { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || + (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; - voodoo_reg_writel(addr, val, voodoo); + if (voodoo->type == VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); + } if (header & (1 << 15)) addr += 4; } break; + case 2: + if (voodoo->type != VOODOO_BANSHEE) + fatal("CMDFIFO2: Not Banshee\n"); + mask = (header >> 3); + addr = 8; + while (mask) + { + if (mask & 1) + { + uint32_t val = cmdfifo_get(voodoo); + + voodoo_2d_reg_writel(voodoo, addr, val); + } + + addr += 4; + mask >>= 1; + } + break; + case 3: num = (header >> 29) & 7; mask = header;//(header >> 10) & 0xff; @@ -338,11 +382,24 @@ void voodoo_fifo_thread(void *param) if (mask & 1) { uint32_t val = cmdfifo_get(voodoo); - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - voodoo_reg_writel(addr, val, voodoo); + if ((addr & (1 << 13)) && voodoo->type == VOODOO_BANSHEE) + { + if (voodoo->type != VOODOO_BANSHEE) + fatal("CMDFIFO1: Not Banshee\n"); +// pclog("CMDFIFO1: write %08x %08x\n", addr, val); + voodoo_2d_reg_writel(voodoo, addr, val); + } + else + { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || + (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; + + if (voodoo->type == VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); + } } addr += 4; @@ -353,13 +410,29 @@ void voodoo_fifo_thread(void *param) break; case 5: - if (header & 0x3fc0000) - fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); +// if (header & 0x3fc00000) +// fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); num = (header >> 3) & 0x7ffff; addr = cmdfifo_get(voodoo) & 0xffffff; + if (!num) + num = 1; // pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); switch (header >> 30) { + case 0: /*Linear framebuffer (Banshee)*/ + if (voodoo->texture_present[0][(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, 0); + } + while (num--) + { + uint32_t val = cmdfifo_get(voodoo); + if (addr <= voodoo->fb_mask) + *(uint32_t *)&voodoo->fb_mem[addr] = val; + addr += 4; + } + break; case 2: /*Framebuffer*/ while (num--) { @@ -383,7 +456,7 @@ void voodoo_fifo_thread(void *param) break; default: - pclog("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); } end_time = timer_read(); diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 52557f1..fc0626c 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -8,6 +8,7 @@ #include "vid_svga.h" #include "vid_voodoo.h" #include "vid_voodoo_common.h" +#include "vid_voodoo_banshee.h" #include "vid_voodoo_blitter.h" #include "vid_voodoo_dither.h" #include "vid_voodoo_fifo.h" @@ -47,7 +48,38 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) switch (addr) { case SST_swapbufferCMD: -// pclog(" start swap buffer command\n"); + if (voodoo->type == VOODOO_BANSHEE) + { +// pclog("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); + + voodoo_wait_for_render_thread_idle(voodoo); + if (!(val & 1)) + { + banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->frame_count++; + } + else if (TRIPLE_BUFFER) + { + if (voodoo->swap_pending) + voodoo_wait_for_swap_complete(voodoo); + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->leftOverlayBuf; + voodoo->swap_pending = 1; + } + else + { + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->leftOverlayBuf; + voodoo->swap_pending = 1; + + voodoo_wait_for_swap_complete(voodoo); + } + + voodoo->cmd_read++; + break; + } if (TRIPLE_BUFFER) { @@ -63,7 +95,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.swapbufferCMD = val; - pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); +// pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); // voodoo->front_offset = params->front_offset; voodoo_wait_for_render_thread_idle(voodoo); if (!(val & 1)) @@ -503,6 +535,52 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; voodoo->params.fogTable[addr+1].fog = (val >> 24) & 0xff; break; + + case SST_clipLeftRight1: + if (voodoo->type == VOODOO_BANSHEE) + { + voodoo->params.clipRight1 = val & 0xfff; + voodoo->params.clipLeft1 = (val >> 16) & 0xfff; + } + break; + case SST_clipTopBottom1: + if (voodoo->type == VOODOO_BANSHEE) + { + voodoo->params.clipHighY1 = val & 0xfff; + voodoo->params.clipLowY1 = (val >> 16) & 0xfff; + } + break; + + case SST_colBufferAddr: + if (voodoo->type == VOODOO_BANSHEE) + { + voodoo->params.draw_offset = val & 0xfffff0; + voodoo->fb_write_offset = voodoo->params.draw_offset; +// pclog("colorBufferAddr=%06x\n", voodoo->params.draw_offset); + } + break; + case SST_colBufferStride: + if (voodoo->type == VOODOO_BANSHEE) + { + if (val & (1 << 15)) + { + voodoo->row_width = (val & 0x7f) * 128; +// pclog("colBufferStride = %i bytes, tiled\n", voodoo->row_width); + } + else + { + voodoo->row_width = val & 0x3fff; +// pclog("colBufferStride = %i bytes, linear\n", voodoo->row_width); + } + } + break; + case SST_auxBufferAddr: + if (voodoo->type == VOODOO_BANSHEE) + { + voodoo->params.aux_offset = val & 0xfffff0; +// pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); + } + break; case SST_clutData: voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; @@ -590,6 +668,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->verts[0] = voodoo->verts[3]; voodoo->vertex_num = 1; voodoo->num_verticies = 1; + voodoo->cull_pingpong = 0; break; case SST_sDrawTriCMD: // pclog("sDrawTriCMD %i %i %i\n", voodoo->num_verticies, voodoo->vertex_num, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); @@ -603,6 +682,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { // pclog("triangle_setup\n"); voodoo_triangle_setup(voodoo); + voodoo->cull_pingpong = !voodoo->cull_pingpong; voodoo->num_verticies = 2; } @@ -734,48 +814,73 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_texBaseAddr: if (chip & CHIP_TREX0) { - voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; +// pclog("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); voodoo_recalc_tex(voodoo, 0); } if (chip & CHIP_TREX1) { - voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 1); } break; case SST_texBaseAddr1: if (chip & CHIP_TREX0) { - voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr1[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 0); } if (chip & CHIP_TREX1) { - voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr1[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 1); } break; case SST_texBaseAddr2: if (chip & CHIP_TREX0) { - voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr2[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 0); } if (chip & CHIP_TREX1) { - voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr2[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 1); } break; case SST_texBaseAddr38: if (chip & CHIP_TREX0) { - voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr38[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 0); } if (chip & CHIP_TREX1) { - voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; + if (voodoo->type == VOODOO_BANSHEE) + voodoo->params.texBaseAddr38[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; voodoo_recalc_tex(voodoo, 1); } break; @@ -1136,5 +1241,10 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_userIntrCMD: fatal("userIntrCMD write %08x from FIFO\n", val); break; + + + case SST_leftOverlayBuf: + voodoo->leftOverlayBuf = val; + break; } } diff --git a/src/vid_voodoo_regs.h b/src/vid_voodoo_regs.h index e065a71..f7ab208 100644 --- a/src/vid_voodoo_regs.h +++ b/src/vid_voodoo_regs.h @@ -144,6 +144,14 @@ enum SST_cmdFifoAMax = 0x1f0, SST_cmdFifoDepth = 0x1f4, SST_cmdFifoHoles = 0x1f8, + + SST_colBufferAddr = 0x1ec, /*Banshee*/ + SST_colBufferStride = 0x1f0, /*Banshee*/ + SST_auxBufferAddr = 0x1f4, /*Banshee*/ + SST_auxBufferStride = 0x1f8, /*Banshee*/ + + SST_clipLeftRight1 = 0x200, /*Banshee*/ + SST_clipTopBottom1 = 0x204, /*Banshee*/ SST_fbiInit4 = 0x200, SST_vRetrace = 0x204, @@ -164,7 +172,10 @@ enum SST_fbiInit5 = 0x244, SST_fbiInit6 = 0x248, SST_fbiInit7 = 0x24c, - + + SST_swapPending = 0x24c, /*Banshee*/ + SST_leftOverlayBuf = 0x250, /*Banshee*/ + SST_sSetupMode = 0x260, SST_sVx = 0x264, SST_sVy = 0x268, diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index 641e8e2..b348ad5 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -1266,8 +1266,11 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (cca_invert_output) src_a ^= 0xff; - if (params->fogMode & FOG_ENABLE) - APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); + if (voodoo->type != VOODOO_BANSHEE) /*HACK*/ + { + if (params->fogMode & FOG_ENABLE) + APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); + } if (params->alphaMode & 1) ALPHA_TEST(src_a); diff --git a/src/vid_voodoo_setup.c b/src/vid_voodoo_setup.c index f3fe076..3572447 100644 --- a/src/vid_voodoo_setup.c +++ b/src/vid_voodoo_setup.c @@ -15,7 +15,6 @@ void voodoo_triangle_setup(voodoo_t *voodoo) float dxAB, dxBC, dyAB, dyBC; float area; int va = 0, vb = 1, vc = 2; - int reverse_cull = 0; vert_t verts[3]; verts[0] = voodoo->verts[0]; @@ -40,7 +39,6 @@ void voodoo_triangle_setup(voodoo_t *voodoo) va = 0; vb = 2; vc = 1; - reverse_cull = 1; } else { @@ -62,7 +60,6 @@ void voodoo_triangle_setup(voodoo_t *voodoo) va = 1; vb = 0; vc = 2; - reverse_cull = 1; } else { @@ -78,10 +75,35 @@ void voodoo_triangle_setup(voodoo_t *voodoo) va = 2; vb = 1; vc = 0; - reverse_cull = 1; } } + dxAB = verts[0].sVx - verts[1].sVx; + dxBC = verts[1].sVx - verts[2].sVx; + dyAB = verts[0].sVy - verts[1].sVy; + dyBC = verts[1].sVy - verts[2].sVy; + + area = dxAB * dyBC - dxBC * dyAB; + + if (area == 0.0) + return; + + if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) + { + int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; + int sign = (area < 0.0); + + if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG)) + == SETUPMODE_CULLING_ENABLE && voodoo->cull_pingpong) + cull_sign = !cull_sign; + + if (cull_sign && sign) + return; + if (!cull_sign && !sign) + return; + } + + dxAB = verts[va].sVx - verts[vb].sVx; dxBC = verts[vb].sVx - verts[vc].sVx; dyAB = verts[va].sVy - verts[vb].sVy; @@ -89,36 +111,12 @@ void voodoo_triangle_setup(voodoo_t *voodoo) area = dxAB * dyBC - dxBC * dyAB; - if (area == 0.0) - { - if ((voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) && - !(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) - voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; - - return; - } - dxAB /= area; dxBC /= area; dyAB /= area; dyBC /= area; - if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) - { - int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; - int sign = (area < 0.0); - if (!(voodoo->sSetupMode & SETUPMODE_DISABLE_PINGPONG)) - voodoo->sSetupMode ^= SETUPMODE_CULLING_SIGN; - - if (reverse_cull) - sign = !sign; - - if (cull_sign && sign) - return; - if (!cull_sign && !sign) - return; - } voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); diff --git a/src/vid_voodoo_texture.c b/src/vid_voodoo_texture.c index 69bcbd3..3326f5e 100644 --- a/src/vid_voodoo_texture.c +++ b/src/vid_voodoo_texture.c @@ -157,7 +157,7 @@ void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) return; } } - + /*Texture not found, search for unused texture*/ do { @@ -469,7 +469,7 @@ void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) voodoo->texture_cache[tmu][c].refcount++; } -static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) +void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) { int wait_for_idle = 0; int c; @@ -531,30 +531,41 @@ 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) - s = (addr >> 1) & 0xfe; - else + if (voodoo->type != VOODOO_BANSHEE) { - if (voodoo->params.textureMode[tmu] & (1 << 31)) - s = addr & 0xfc; + if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type == VOODOO_BANSHEE) + { + lod = (addr >> 16) & 0xf; + t = (addr >> 8) & 0xff; + } else - s = (addr >> 1) & 0xfc; + { + lod = (addr >> 17) & 0xf; + t = (addr >> 9) & 0xff; + } + if (voodoo->params.tformat[tmu] & 8) + s = (addr >> 1) & 0xfe; + else + { + if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type == VOODOO_BANSHEE) + s = addr & 0xfc; + else + s = (addr >> 1) & 0xfc; + } + if (lod > LOD_MAX) + return; + +// if (addr >= 0x200000) +// return; + + if (voodoo->params.tformat[tmu] & 8) + addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; + else + addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); } - - if (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]); + addr = (addr & 0x1ffffc) + voodoo->params.tex_base[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); diff --git a/src/vid_voodoo_texture.h b/src/vid_voodoo_texture.h index e744f17..e4c5602 100644 --- a/src/vid_voodoo_texture.h +++ b/src/vid_voodoo_texture.h @@ -16,3 +16,4 @@ static const uint32_t texture_offset[LOD_MAX+3] = void voodoo_recalc_tex(voodoo_t *voodoo, int tmu); void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu); void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p); +void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu); diff --git a/src/video.c b/src/video.c index 2c81093..0550186 100644 --- a/src/video.c +++ b/src/video.c @@ -50,6 +50,7 @@ #include "vid_wy700.h" #include "vid_t3100e.h" #include "vid_t1000.h" +#include "vid_voodoo_banshee.h" enum { @@ -82,6 +83,7 @@ typedef struct static VIDEO_CARD video_cards[] = { + {"A-Trend Helios 3D (Voodoo Banshee)", "banshee", &atrend_voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, From 32900491b74e1cc724595342161d9c951c703f5b Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 11 Aug 2020 11:31:50 +0100 Subject: [PATCH 0874/1050] Update Makefiles --- src/Makefile.am | 10 ++++++---- src/Makefile.mingw-wx-sdl2 | 10 ++++++---- src/Makefile.mingw-wx-sdl2-network | 10 ++++++---- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 3338098..1732e68 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,14 +30,14 @@ codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ codegen_ops_fpu_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c codegen_ops_mmx_loadstore.c \ codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_helpers.c codegen_ops_jump.c \ codegen_ops_logic.c codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c \ -codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_pentium.c \ +codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_p6.c codegen_timing_pentium.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c cs8230.c dells200.c device.c disc.c \ disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f82c710_upc.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ -hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c ide.c ide_atapi.c ide_sff8038i.c intel.c intel_flash.c io.c \ +hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c i440fx.c i440bx.c ide.c ide_atapi.c ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c lpt_dss.c \ mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \ -neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ +neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pc87307.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ scsi_ibm.c scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c \ sound_azt2316a.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 \ @@ -48,7 +48,9 @@ vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c vid_icd2061 vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.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 vid_wy700.c vt82c586b.c \ +vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c vid_voodoo_banshee.c vid_voodoo_banshee_blitter.c \ +vid_voodoo_blitter.c vid_voodoo_display.c vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c \ +vid_voodoo_render.c vid_voodoo_setup.c vid_voodoo_texture.c video.c wd76c10.c vid_wy700.c vt82c586b.c \ vl82c480.c w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc # DOSBox diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index cca1422..d7ae669 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -15,15 +15,15 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_p6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f82c710_upc.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ - fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ + fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o i440fx.o i440bx.o ide.o \ ide_atapi.o ide_sff8038i.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ - mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ + mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pc87307.o pci.o pic.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.o sound_cms.o sound_dbopl.o \ @@ -36,7 +36,9 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o vl82c480.o \ + vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \ + vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \ + vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \ vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index f63b3f5..7a4bb46 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -15,15 +15,15 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_pentium.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_p6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f82c710_upc.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ - fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o ide.o \ + fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o i440fx.o i440bx.o ide.o \ ide_atapi.o ide_sff8038i.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 laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ - mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pci.o pic.o \ + mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pc87307.o pci.o pic.o \ piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.o sound_cms.o sound_dbopl.o \ @@ -36,7 +36,9 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_t1000.o vid_t3100e.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_voodoo.o vid_wy700.o video.o vl82c480.o \ + vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \ + vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \ + vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \ vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ From 133f19fe39d1f98ec261e19f063838ce7ad74713 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Aug 2020 15:13:48 +0100 Subject: [PATCH 0875/1050] Implement Banshee tiled surfaces --- src/vid_voodoo.c | 1 + src/vid_voodoo_banshee.c | 82 +++++++++++++++++++--- src/vid_voodoo_banshee_blitter.c | 116 +++++++++++++++++++------------ src/vid_voodoo_blitter.c | 44 +++++++++--- src/vid_voodoo_codegen_x86-64.h | 96 ++++++++++++++++++------- src/vid_voodoo_codegen_x86.h | 96 ++++++++++++++++++------- src/vid_voodoo_common.h | 8 ++- src/vid_voodoo_reg.c | 25 +++++-- src/vid_voodoo_render.c | 32 ++++++--- 9 files changed, 373 insertions(+), 127 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 79fac67..310014e 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -100,6 +100,7 @@ void voodoo_recalc(voodoo_t *voodoo) if (voodoo->fbiInit1 & (1 << 24)) voodoo->block_width += 32; voodoo->row_width = voodoo->block_width * 32 * 2; + voodoo->aux_row_width = voodoo->row_width; /* 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); pclog(" fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 26c14c8..8c0e02b 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -66,6 +66,10 @@ typedef struct banshee_t mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ voodoo_t *voodoo; + + uint32_t desktop_addr; + int desktop_y; + uint32_t desktop_stride_tiled; } banshee_t; enum @@ -275,6 +279,35 @@ static void banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } +static void banshee_render_16bpp_tiled(svga_t *svga) +{ + banshee_t *banshee = (banshee_t *)svga->p; + int x; + int offset = 32; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + uint32_t addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 64) + { + int xx; + + for (xx = 0; xx < 64; xx += 2) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(addr + (xx << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + + addr += 128*32; + } + + banshee->desktop_y++; +} + static void banshee_recalctimings(svga_t *svga) { banshee_t *banshee = (banshee_t *)svga->p; @@ -312,7 +345,7 @@ static void banshee_recalctimings(svga_t *svga) svga->bpp = 8; break; case PIX_FORMAT_RGB565: - svga->render = svga_render_16bpp_highres; + svga->render = (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) ? banshee_render_16bpp_tiled : svga_render_16bpp_highres; svga->bpp = 16; break; case PIX_FORMAT_RGB24: @@ -331,6 +364,7 @@ static void banshee_recalctimings(svga_t *svga) else svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; svga->ma_latch = banshee->vidDesktopStartAddr >> 2; + banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); svga->char_width = 8; @@ -350,7 +384,7 @@ static void banshee_recalctimings(svga_t *svga) svga->overlay.ysize = voodoo->overlay.size_y; svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) - svga->overlay.pitch *= 128; + svga->overlay.pitch *= 128*32; if (svga->overlay.xsize <= 0 || svga->overlay.ysize <= 0) svga->overlay.ena = 0; if (svga->overlay.ena) @@ -440,6 +474,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) voodoo->tile_stride = 1024 << ((val >> 13) & 7); voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); voodoo->tile_x = ((val >> 16) & 0x7f) * 128; + voodoo->tile_x_real = ((val >> 16) & 0x7f) * 128*32; break; case Init_miscInit0: @@ -1180,7 +1215,7 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1213,7 +1248,7 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1246,7 +1281,7 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1280,7 +1315,7 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1314,7 +1349,7 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1355,9 +1390,9 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; addr2 = x + y*voodoo->tile_x; -// pclog(" Tile %08x->%08x->%08x->%08x %i %i stride=%i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_stride, voodoo->tile_x); +// pclog(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_x_real); } if (addr >= svga->vram_max) @@ -1443,6 +1478,23 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) } \ } while (0) +#define DECODE_RGB565_TILED() \ + do \ + { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ + { \ + uint16_t data = *(uint16_t *)&src[(c & 127) + (c >> 7)*128*32]; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + banshee->overlay_buffer[wp++] = (r << 3) | (g << 10) | (b << 19); \ + } \ + } while (0) + #define DECODE_YUYV422() \ do \ { \ @@ -1543,7 +1595,10 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) break; \ \ case OVERLAY_FMT_565_DITHER: \ - DECODE_RGB565(); \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ + DECODE_RGB565_TILED(); \ + else \ + DECODE_RGB565(); \ break; \ \ default: \ @@ -1557,7 +1612,10 @@ static void banshee_overlay_draw(svga_t *svga, int displine) voodoo_t *voodoo = banshee->voodoo; uint32_t *p; int x; - uint32_t src_addr = svga->overlay_latch.addr + svga->overlay_latch.pitch * (voodoo->overlay.src_y >> 20); + int y = voodoo->overlay.src_y >> 20; + uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? + ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : + y * svga->overlay_latch.pitch); uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; uint32_t src_x = 0; @@ -1616,6 +1674,8 @@ static void banshee_vsync_callback(svga_t *svga) } voodoo->overlay.src_y = 0; + banshee->desktop_addr = banshee->vidDesktopStartAddr; + banshee->desktop_y = 0; } static uint8_t banshee_pci_read(int func, int addr, void *p) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index 032215b..6a3204d 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -151,13 +151,24 @@ static uint32_t MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t patt return result; } +static uint32_t get_addr(voodoo_t *voodoo, int x, int y, int src_notdst, uint32_t src_stride) +{ + uint32_t stride = src_notdst ? src_stride : voodoo->banshee_blt.dst_stride; + uint32_t base_addr = src_notdst ? voodoo->banshee_blt.srcBaseAddr : voodoo->banshee_blt.dstBaseAddr; + + if (src_notdst ? voodoo->banshee_blt.srcBaseAddr_tiled : voodoo->banshee_blt.dstBaseAddr_tiled) + return (base_addr + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*stride) & voodoo->fb_mask; + else + return (base_addr + x + y*stride) & voodoo->fb_mask; +} + static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) { switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { case DST_FORMAT_COL_8_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -169,7 +180,7 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } case DST_FORMAT_COL_16_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x*2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -181,7 +192,7 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } case DST_FORMAT_COL_24_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x*3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -193,7 +204,7 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } case DST_FORMAT_COL_32_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x*4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -309,7 +320,7 @@ static void banshee_do_rectfill(voodoo_t *voodoo) } -static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x) +static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; int dst_y = voodoo->banshee_blt.dstY; @@ -346,6 +357,10 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128*32); if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { @@ -353,8 +368,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x { case DST_FORMAT_COL_8_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x]; + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x_real]; uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -366,8 +381,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case DST_FORMAT_COL_16_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *)&src_p[src_x*2]; + uint32_t dst_addr = get_addr(voodoo, dst_x*2, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *)&src_p[src_x_real]; uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -379,8 +394,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case DST_FORMAT_COL_24_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x*3]; + uint32_t dst_addr = get_addr(voodoo, dst_x*3, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x_real]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -392,8 +407,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case DST_FORMAT_COL_32_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x*4]; + uint32_t dst_addr = get_addr(voodoo, dst_x*4, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x_real]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -435,6 +450,10 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128*32); if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { @@ -445,7 +464,7 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x { case SRC_FORMAT_COL_1_BPP: { - uint8_t src_byte = src_p[src_x >> 3]; + uint8_t src_byte = src_p[src_x_real]; src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) transparent = !(src_byte & (0x80 >> (src_x & 7))); @@ -454,12 +473,12 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case SRC_FORMAT_COL_8_BPP: { - src_data = src_p[src_x]; + src_data = src_p[src_x_real]; break; } case SRC_FORMAT_COL_16_BPP: { - uint16_t src_16 = *(uint16_t *)&src_p[src_x*2]; + uint16_t src_16 = *(uint16_t *)&src_p[src_x_real]; int r = (src_16 >> 11); int g = (src_16 >> 5) & 0x3f; int b = src_16 & 0x1f; @@ -472,12 +491,12 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case SRC_FORMAT_COL_24_BPP: { - src_data = *(uint32_t *)&src_p[src_x*3]; + src_data = *(uint32_t *)&src_p[src_x_real]; break; } case SRC_FORMAT_COL_32_BPP: { - src_data = *(uint32_t *)&src_p[src_x*4]; + src_data = *(uint32_t *)&src_p[src_x_real]; break; } @@ -523,10 +542,10 @@ static void banshee_do_screen_to_screen_blt(voodoo_t *voodoo) // return; for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - uint32_t src_addr = (voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*/*voodoo->banshee_blt.src_stride*/voodoo->banshee_blt.src_stride_dest) & voodoo->fb_mask; + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_dest); // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); - do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX); + do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcBaseAddr_tiled); } } @@ -552,9 +571,9 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7); + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7, 0); else - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0); + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); voodoo->banshee_blt.cur_y++; } @@ -563,20 +582,7 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t else voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); -// pclog(" %i %i %i %i %i\n", (voodoo->banshee_blt.srcX & 3), (last_byte & 3), (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK)); -#if 0 - if ((voodoo->banshee_blt.srcX & 3) >= last_byte)// & 3) && (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) < 4) - { - *(uint32_t *)voodoo->banshee_blt.host_data = *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count-4]; - voodoo->banshee_blt.host_data_count = 4; - } - else - { -#endif voodoo->banshee_blt.host_data_count = 0; -// } -// last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; -// pclog(" host_data_count=%i last_byte=%i srcX=%i\n", voodoo->banshee_blt.host_data_count, last_byte, voodoo->banshee_blt.srcX); } } else @@ -590,7 +596,7 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t // pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { - do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0); + do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); voodoo->banshee_blt.cur_y++; } @@ -638,7 +644,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in { case DST_FORMAT_COL_8_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = src_p[src_x]; uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -652,7 +658,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in } case DST_FORMAT_COL_16_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x*2, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = *(uint16_t *)&src_p[src_x*2]; uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -666,7 +672,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in } case DST_FORMAT_COL_24_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x*3, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = *(uint32_t *)&src_p[src_x*3]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -680,7 +686,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in } case DST_FORMAT_COL_32_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x*4, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = *(uint32_t *)&src_p[src_x*4]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -723,8 +729,8 @@ static void banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) // return; for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - uint32_t src_addr = (voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; - pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_src);//(voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; +// pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); @@ -1018,7 +1024,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; // pclog("dstBaseAddr=%08x\n", val); @@ -1026,7 +1032,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) case 0x14: voodoo->banshee_blt.dstFormat = val; if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; // pclog("dstFormat=%08x\n", val); @@ -1065,7 +1071,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; update_src_stride(voodoo); @@ -1112,10 +1118,28 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) case 0x54: voodoo->banshee_blt.srcFormat = val; if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; update_src_stride(voodoo); + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) + { + case SRC_FORMAT_COL_1_BPP: + voodoo->banshee_blt.src_bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + voodoo->banshee_blt.src_bpp = 8; + break; + case SRC_FORMAT_COL_24_BPP: + voodoo->banshee_blt.src_bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + voodoo->banshee_blt.src_bpp = 32; + break; + case SRC_FORMAT_COL_16_BPP: default: + voodoo->banshee_blt.src_bpp = 16; + break; + } // pclog("srcFormat=%08x\n", val); break; case 0x58: diff --git a/src/vid_voodoo_blitter.c b/src/vid_voodoo_blitter.c index f9b7538..01048f9 100644 --- a/src/vid_voodoo_blitter.c +++ b/src/vid_voodoo_blitter.c @@ -443,11 +443,25 @@ void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { 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; + if (voodoo->col_tiled) + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; + for (x = params->clipLeft; x < params->clipRight; x++) + { + int x2 = (x & 63) | ((x >> 6) * 128*32/2); + cbuf[x2] = col; + } + } + else + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } } } } @@ -468,11 +482,25 @@ void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { 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; + if (voodoo->aux_tiled) + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; + for (x = params->clipLeft; x < params->clipRight; x++) + { + int x2 = (x & 63) | ((x >> 6) * 128*32/2); + abuf[x2] = params->zaColor & 0xffff; + } + } + else + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } } } } diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 4b5335b..716e684 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -41,28 +41,36 @@ typedef struct voodoo_x86_data_t static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; -#define addbyte(val) \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addbyte(val) \ + do { \ + code_block[block_pos++] = val; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addword(val) \ + do { \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addlong(val) \ + do { \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addquad(val) \ + do { \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) static __m128i xmm_01_w;// = 0x0001000100010001ull; @@ -782,6 +790,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); addbyte(0xfe); + if (voodoo->col_tiled || voodoo->aux_tiled) + { + addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*AND EAX, 63*/ + addbyte(0xe0); + addbyte(63); + addbyte(0xc1); /*SHR EBX, 6*/ + addbyte(0xeb); + addbyte(6); + addbyte(0xc1); /*SHL EBX, 11 - tile is 128*32, << 12, div 2 because word index*/ + addbyte(0xe3); + addbyte(11); + addbyte(0x01); /*ADD EAX, EBX*/ + addbyte(0xd8); + addbyte(0x89); /*MOV state->x_tiled[EDI], EAX*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x_tiled)); + } addbyte(0x66); /*PXOR XMM2, XMM2*/ addbyte(0x0f); addbyte(0xef); @@ -899,7 +929,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x48); /*MOV RCX, aux_mem[RDI]*/ addbyte(0x8b); addbyte(0x8f); @@ -2483,7 +2516,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addquad((uintptr_t)rgb565); addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x48); /*MOV RBP, fb_mem*/ addbyte(0x8b); addbyte(0xaf); @@ -2865,8 +2901,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x66); /*MOV EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2932,7 +2971,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x4c); /*ADD RSI, R8*/ addbyte(0x01); addbyte(0xc6); @@ -3018,6 +3060,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ + addbyte(0x97); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); addbyte(0x87); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 193e1b9..3fe0335 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -39,28 +39,36 @@ typedef struct voodoo_x86_data_t static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; -#define addbyte(val) \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addbyte(val) \ + do { \ + code_block[block_pos++] = val; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addword(val) \ + do { \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addlong(val) \ + do { \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addquad(val) \ + do { \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) static __m128i xmm_01_w;// = 0x0001000100010001ull; @@ -694,6 +702,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x74); addbyte(0x24); addbyte(8+16); + if (voodoo->col_tiled || voodoo->aux_tiled) + { + addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*AND EAX, 63*/ + addbyte(0xe0); + addbyte(63); + addbyte(0xc1); /*SHR EBX, 6*/ + addbyte(0xeb); + addbyte(6); + addbyte(0xc1); /*SHL EBX, 11 - tile is 128*32, << 12, div 2 because word index*/ + addbyte(0xe3); + addbyte(11); + addbyte(0x01); /*ADD EAX, EBX*/ + addbyte(0xd8); + addbyte(0x89); /*MOV state->x_tiled[EDI], EAX*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x_tiled)); + } addbyte(0x66); /*PXOR XMM2, XMM2*/ addbyte(0x0f); addbyte(0xef); @@ -826,7 +856,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x8b);/*MOV ECX, aux_mem[EDI]*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, aux_mem)); @@ -2439,7 +2472,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x8b); /*MOV EBP, fb_mem*/ addbyte(0xaf); addlong(offsetof(voodoo_state_t, fb_mem)); @@ -2818,8 +2854,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x66); /*MOV EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2887,7 +2926,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); if (dither2x2) { addbyte(0xc1); /*SHL ECX, 2*/ @@ -2971,6 +3013,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ + addbyte(0x97); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); addbyte(0x87); diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 4d3a809..1c296c2 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -217,8 +217,10 @@ typedef struct voodoo_t uint32_t fb_read_offset, fb_write_offset; - int row_width; + int row_width, aux_row_width; int block_width; + + int col_tiled, aux_tiled; uint8_t *fb_mem, *tex_mem[2]; uint16_t *tex_mem_w[2]; @@ -409,6 +411,8 @@ typedef struct voodoo_t int host_data_count; int host_data_size_src, host_data_size_dest; int src_stride_src, src_stride_dest; + + int src_bpp; } banshee_blt; struct @@ -439,7 +443,7 @@ typedef struct voodoo_t int buffer_cutoff; uint32_t tile_base, tile_stride; - int tile_stride_shift, tile_x; + int tile_stride_shift, tile_x, tile_x_real; int read_time, write_time, burst_time; diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index fc0626c..97b1c2e 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -562,15 +562,16 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_colBufferStride: if (voodoo->type == VOODOO_BANSHEE) { - if (val & (1 << 15)) + voodoo->col_tiled = val & (1 << 15); + if (voodoo->col_tiled) { - voodoo->row_width = (val & 0x7f) * 128; -// pclog("colBufferStride = %i bytes, tiled\n", voodoo->row_width); + voodoo->row_width = (val & 0x7f) * 128*32; +// pclog("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); } else { voodoo->row_width = val & 0x3fff; -// pclog("colBufferStride = %i bytes, linear\n", voodoo->row_width); +// pclog("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); } } break; @@ -581,6 +582,22 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) // pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); } break; + case SST_auxBufferStride: + if (voodoo->type == VOODOO_BANSHEE) + { + voodoo->aux_tiled = val & (1 << 15); + if (voodoo->aux_tiled) + { + voodoo->aux_row_width = (val & 0x7f) * 128*32; +// pclog("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); + } + else + { + voodoo->aux_row_width = val & 0x3fff; +// pclog("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); + } + } + break; case SST_clutData: voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index b348ad5..8de9489 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -56,7 +56,7 @@ typedef struct voodoo_state_t int64_t w; int pixel_count, texel_count; - int x, x2; + int x, x2, x_tiled; uint32_t w_depth; @@ -920,8 +920,14 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood } else { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; + if (voodoo->col_tiled) + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * voodoo->row_width + (real_y & 31) * 128]; + else + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; + if (voodoo->aux_tiled) + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * voodoo->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; + else + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; } if (voodoo_output) @@ -940,6 +946,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood #endif do { + int x_tiled = (x & 63) | ((x >> 6) * 128*32/2); start_x = x; state->x = x; voodoo->pixel_count[odd_even]++; @@ -985,12 +992,12 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (params->fbzMode & FBZ_DEPTH_ENABLE) { - uint16_t old_depth = aux_mem[x]; + uint16_t old_depth = voodoo->aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); } - dat = fb_mem[x]; + dat = voodoo->col_tiled ? fb_mem[x_tiled] : fb_mem[x]; dest_r = (dat >> 8) & 0xf8; dest_g = (dat >> 3) & 0xfc; dest_b = (dat << 3) & 0xf8; @@ -1303,10 +1310,19 @@ 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 (voodoo->col_tiled) + fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); + else + fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); + } if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - aux_mem[x] = new_depth; + { + if (voodoo->aux_tiled) + aux_mem[x_tiled] = new_depth; + else + aux_mem[x] = new_depth; + } } } voodoo_output &= ~2; From 11b29c7c18a33a80138bc777b67de9bf5227c073 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Aug 2020 18:07:04 +0100 Subject: [PATCH 0876/1050] Fix Banshee host data size when source format is 1 bpp. Fixes some bad icon masks in Windows 98. --- src/vid_voodoo_banshee_blitter.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index 6a3204d..41c1947 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -561,7 +561,12 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { - int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; + int last_byte; + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + last_byte = (((voodoo->banshee_blt.srcX + 7) >> 3) & 3) + voodoo->banshee_blt.host_data_size_dest; + else + last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; voodoo->banshee_blt.host_data_count += 4; From 0298d0ffaf3edc7bc18104fcb84b1f75f86e12d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Aug 2020 20:32:54 +0100 Subject: [PATCH 0877/1050] Fix uninitialised variable in Banshee texture writes. --- src/vid_voodoo_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_texture.c b/src/vid_voodoo_texture.c index 3326f5e..0396a8a 100644 --- a/src/vid_voodoo_texture.c +++ b/src/vid_voodoo_texture.c @@ -564,7 +564,7 @@ void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); } else - addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][lod]; + addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0]; if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { From d1f17cd8ae7865259eb2861f73c74213a36865fe Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Aug 2020 20:36:01 +0100 Subject: [PATCH 0878/1050] Don't flush Banshee pipeline when reading clipping registers. Fixes severe slowdown in 3dMark2000 fill rate test. --- src/vid_voodoo_banshee.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 8c0e02b..147d02c 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -966,20 +966,16 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p) ret = voodoo->lfbMode; break; case SST_clipLeftRight: - voodoo_flush(voodoo); ret = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); break; case SST_clipLowYHighY: - voodoo_flush(voodoo); ret = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); break; case SST_clipLeftRight1: - voodoo_flush(voodoo); ret = voodoo->params.clipRight1 | (voodoo->params.clipLeft1 << 16); break; case SST_clipTopBottom1: - voodoo_flush(voodoo); ret = voodoo->params.clipHighY1 | (voodoo->params.clipLowY1 << 16); break; From 3040c4e9946012377048e8db5b3b678acbb78c98 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Aug 2020 21:39:07 +0100 Subject: [PATCH 0879/1050] Additional Banshee host data size fix. --- src/vid_voodoo_banshee_blitter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index 41c1947..f52c172 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -249,8 +249,8 @@ static void update_src_stride(voodoo_t *voodoo) case SRC_FORMAT_PACKING_STRIDE: voodoo->banshee_blt.src_stride_src = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; voodoo->banshee_blt.src_stride_dest = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + (voodoo->banshee_blt.srcX & 3) + 7) >> 3; - voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + (voodoo->banshee_blt.srcX & 3) + 7) >> 3; + voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; // pclog("Stride packing %08x %08x bpp=%i dstSizeX=%i\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest, bpp, voodoo->banshee_blt.dstSizeX); break; From 771c5c6ba3725571cbb702c89360fc992f6384ac Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 13 Aug 2020 21:18:20 +0100 Subject: [PATCH 0880/1050] More Banshee host data size tweaking. --- src/vid_voodoo_banshee_blitter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index f52c172..c04ea87 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -564,10 +564,10 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t int last_byte; if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - last_byte = (((voodoo->banshee_blt.srcX + 7) >> 3) & 3) + voodoo->banshee_blt.host_data_size_dest; + last_byte = ((voodoo->banshee_blt.srcX & 31) + voodoo->banshee_blt.dstSizeX + 7) >> 3; else last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; - + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; voodoo->banshee_blt.host_data_count += 4; if (voodoo->banshee_blt.host_data_count >= last_byte) From 63186246611ecdc3457e4eac186cf15a9edce654 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 14 Aug 2020 20:34:23 +0100 Subject: [PATCH 0881/1050] Banshee fog table seems to be inverted compared to other Voodoo cards (hardware bug?). Re-enabled fog. --- src/vid_voodoo_reg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 97b1c2e..df48abe 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -530,6 +530,9 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_fogTable18: case SST_fogTable19: case SST_fogTable1a: case SST_fogTable1b: case SST_fogTable1c: case SST_fogTable1d: case SST_fogTable1e: case SST_fogTable1f: addr = (addr - SST_fogTable00) >> 1; + if (voodoo->type == VOODOO_BANSHEE) + val = ~val; /*Banshee fog table seems to be inverted. There's a reference + in the glide2x source to a "banshee (rev<3) fogTable hack"*/ voodoo->params.fogTable[addr].dfog = val & 0xff; voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; From 06a07cfcbc7ca8c8c2041251de894cc62bf7eaae Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 14 Aug 2020 21:44:11 +0100 Subject: [PATCH 0882/1050] Fix off-by-one size error with Banshee overlay. --- src/vid_voodoo_banshee.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 147d02c..ecdaa6b 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -581,8 +581,8 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) voodoo->overlay.vidOverlayEndScreenCoords = val; voodoo->overlay.end_x = val & OVERLAY_END_X_MASK; voodoo->overlay.end_y = (val & OVERLAY_END_Y_MASK) >> OVERLAY_END_Y_SHIFT; - voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; - voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; + voodoo->overlay.size_x = (voodoo->overlay.end_x - voodoo->overlay.start_x) + 1; + voodoo->overlay.size_y = (voodoo->overlay.end_y - voodoo->overlay.start_y) + 1; svga_recalctimings(svga); break; case Video_vidOverlayDudx: From 21a3a9acec39639b4ebaf1234f5d9ef2d6d8b78e Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 14 Aug 2020 22:16:35 +0100 Subject: [PATCH 0883/1050] Update Voodoo framebuffer read/write for Banshee. --- src/vid_voodoo_fb.c | 78 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/src/vid_voodoo_fb.c b/src/vid_voodoo_fb.c index 39fa2ac..52bec1f 100644 --- a/src/vid_voodoo_fb.c +++ b/src/vid_voodoo_fb.c @@ -18,8 +18,16 @@ uint16_t voodoo_fb_readw(uint32_t addr, void *p) uint32_t read_addr; uint16_t temp; - x = (addr >> 1) & 0x3ff; - y = (addr >> 11) & 0x3ff; + if (voodoo->type == VOODOO_BANSHEE) + { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } + else + { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } if (SLI_ENABLED) { @@ -33,7 +41,10 @@ uint16_t voodoo_fb_readw(uint32_t addr, void *p) y >>= 1; } - read_addr = voodoo->fb_read_offset + (x << 1) + (y * voodoo->row_width); + if (voodoo->col_tiled) + read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); if (read_addr > voodoo->fb_mask) return 0xffff; @@ -50,8 +61,16 @@ uint32_t voodoo_fb_readl(uint32_t addr, void *p) uint32_t read_addr; uint32_t temp; - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; + if (voodoo->type == VOODOO_BANSHEE) + { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } + else + { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } if (SLI_ENABLED) { @@ -65,7 +84,10 @@ uint32_t voodoo_fb_readl(uint32_t addr, void *p) y >>= 1; } - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); if (read_addr > voodoo->fb_mask) return 0xffffffff; @@ -153,8 +175,16 @@ void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); } - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; + if (voodoo->type == VOODOO_BANSHEE) + { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } + else + { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } if (SLI_ENABLED) { @@ -168,8 +198,14 @@ void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) if (voodoo->fb_write_offset == voodoo->params.front_offset) voodoo->dirty_line[y] = 1; - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + if (voodoo->aux_tiled) + write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + 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); @@ -300,8 +336,16 @@ void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); } - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; + if (voodoo->type == VOODOO_BANSHEE) + { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } + else + { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } if (SLI_ENABLED) { @@ -314,8 +358,14 @@ void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) if (voodoo->fb_write_offset == voodoo->params.front_offset) voodoo->dirty_line[y] = 1; - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + if (voodoo->aux_tiled) + write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + 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); From bb70f4ff0f287c1891471d2ed765b78f8634c8c1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 14:38:31 +0100 Subject: [PATCH 0884/1050] Re-enable fog on Banshee. --- src/vid_voodoo_codegen_x86.h | 3 --- src/vid_voodoo_render.c | 7 ++----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 3fe0335..5867d85 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -2208,8 +2208,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo // addbyte(0x7e); // addbyte(0x87); // addlong(offsetof(voodoo_state_t, out)); - if (voodoo->type != VOODOO_BANSHEE) /*HACK*/ - { if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) @@ -2412,7 +2410,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo src_g = CLAMP(src_g); src_b = CLAMP(src_b);*/ } - } if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) { diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index 8de9489..b2b3e89 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -1273,11 +1273,8 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (cca_invert_output) src_a ^= 0xff; - if (voodoo->type != VOODOO_BANSHEE) /*HACK*/ - { - if (params->fogMode & FOG_ENABLE) - APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); - } + if (params->fogMode & FOG_ENABLE) + APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); if (params->alphaMode & 1) ALPHA_TEST(src_a); From 8ee4396b4c1f308d2b1f82e01b4a49b6019c2bb0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 15:56:32 +0100 Subject: [PATCH 0885/1050] Fix race condition in Voodoo FIFO code that could cause an 'Unknown fifo entry' error --- src/vid_voodoo_fifo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index 393137e..c5ca5a9 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -173,6 +173,8 @@ void voodoo_fifo_thread(void *param) voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); fifo->addr_type = FIFO_INVALID; voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; } break; @@ -183,6 +185,8 @@ void voodoo_fifo_thread(void *param) voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); fifo->addr_type = FIFO_INVALID; voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; } break; @@ -193,6 +197,8 @@ void voodoo_fifo_thread(void *param) voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); fifo->addr_type = FIFO_INVALID; voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; } break; @@ -203,6 +209,8 @@ void voodoo_fifo_thread(void *param) voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); fifo->addr_type = FIFO_INVALID; voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; } break; @@ -212,6 +220,8 @@ void voodoo_fifo_thread(void *param) voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val); fifo->addr_type = FIFO_INVALID; voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; } break; From 2212b9a47093cedda3d8986ec8e6036dddc9e0ad Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 15:57:39 +0100 Subject: [PATCH 0886/1050] Implement out-of-order CMDFIFO handling on Banshee. --- src/vid_voodoo_banshee.c | 52 +++++++++++++++++++++++++++++++++++++--- src/vid_voodoo_common.h | 1 + 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index ecdaa6b..796a42d 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1403,10 +1403,56 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; if (addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) { -// pclog("CMDFIFO write %08x %08x %04x:%08x\n", addr, val, CS,cpu_state.pc); - voodoo->cmdfifo_depth_wr++; -// if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) +// pclog("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); + if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) + { +// if (voodoo->cmdfifo_holecount) +// fatal("CMDFIFO reset pointers while outstanding holes\n"); + /*Reset pointers*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base; + voodoo->cmdfifo_amax = voodoo->cmdfifo_base; + voodoo->cmdfifo_depth_wr++; voodoo_wake_fifo_thread(voodoo); + } + else if (voodoo->cmdfifo_holecount) + { +// if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax) +// fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); +// pclog("holecount %i\n", voodoo->cmdfifo_holecount); + voodoo->cmdfifo_holecount--; + if (!voodoo->cmdfifo_holecount) + { + int words_to_add = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) + 1; + /*Filled in holes, resume normal operation*/ + voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); + voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; + voodoo_wake_fifo_thread(voodoo); +// pclog("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); + } + } + else if (addr == voodoo->cmdfifo_amax+4) + { + /*In-order write*/ + voodoo->cmdfifo_amin = addr; + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_depth_wr++; + voodoo_wake_fifo_thread(voodoo); + } + else + { + /*Out-of-order write*/ + if (addr < voodoo->cmdfifo_amin) + { + /*Reset back to start. Note that write is still out of order!*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base-4; + + } +// else if (addr < voodoo->cmdfifo_amax) +// fatal("Out-of-order write really out of order\n"); + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; +// pclog("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); + } } } diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 1c296c2..ee15c16 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -302,6 +302,7 @@ typedef struct voodoo_t int cmdfifo_rp; volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; uint32_t cmdfifo_amin, cmdfifo_amax; + int cmdfifo_holecount; uint32_t sSetupMode; vert_t verts[4]; From a85f315dafa9ed14f0627148184f6395575c6526 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 16:46:15 +0100 Subject: [PATCH 0887/1050] The existing A-Trend Banshee card is AGP, which is not currently emulated. Replaced with a reference SGRAM PCI card, and added a Creative SDRAM card. --- src/ibm.h | 3 +- src/vid_voodoo_banshee.c | 93 +++++++++++++++++++++++++++++++++++----- src/vid_voodoo_banshee.h | 3 +- src/video.c | 3 +- 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 02fb0fc..5365a29 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -321,7 +321,8 @@ enum GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/ GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/ GFX_TVGA9000B, /*Trident TVGA9000B*/ - GFX_BANSHEE, + GFX_BANSHEE, /*Voodoo Banshee - reference PCI board with SGRAM*/ + GFX_CL_BANSHEE, /*Creative Labs Voodoo Blaster Banshee PCI - with SDRAM*/ GFX_MAX }; diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 796a42d..61e7132 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1864,7 +1864,7 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) } } -static device_config_t banshee_config[] = +static device_config_t banshee_sgram_config[] = { { .name = "memory", @@ -1925,16 +1925,60 @@ static device_config_t banshee_config[] = } }; -static void *banshee_init() +static device_config_t banshee_sdram_config[] = +{ + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1", + .value = 1 + }, + { + .description = "2", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 2 + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 + }, +#endif + { + .type = -1 + } +}; + +static void *banshee_init_common(char *fn, int has_sgram) { int mem_size; banshee_t *banshee = malloc(sizeof(banshee_t)); memset(banshee, 0, sizeof(banshee_t)); - // rom_init(&banshee->bios_rom, "gainward.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - rom_init(&banshee->bios_rom, "a-trend.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&banshee->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - mem_size = device_get_config_int("memory"); + if (has_sgram) + mem_size = device_get_config_int("memory"); + else + mem_size = 16; /*SDRAM Banshee only supports 16 MB*/ + svga_init(&banshee->svga, banshee, mem_size << 20, banshee_recalctimings, banshee_in, banshee_out, @@ -1976,9 +2020,10 @@ static void *banshee_init() banshee->svga.miscout = 1; banshee->dramInit0 = 1 << 27; - if (mem_size == 16) + if (has_sgram && mem_size == 16) banshee->dramInit0 |= (1 << 26); /*2xSGRAM = 16 MB*/ -// banshee->dramInit1 = 1 << 30; /*SDRAM*/ + if (!has_sgram) + banshee->dramInit1 = 1 << 30; /*SDRAM*/ banshee->svga.decode_mask = 0x1ffffff; pci_add(banshee_pci_read, banshee_pci_write, banshee); @@ -1996,9 +2041,22 @@ static void *banshee_init() return banshee; } +static void *banshee_init(FILE *f, int has_sgram) +{ + return banshee_init_common("pci_sg.rom", 1); +} +static void *creative_banshee_init(FILE *f, int has_sgram) +{ + return banshee_init_common("blasterpci.rom", 0); +} + static int banshee_available() { - return rom_present("a-trend.VBI"); + return rom_present("pci_sg.rom"); +} +static int creative_banshee_available() +{ + return rom_present("blasterpci.rom"); } static void banshee_close(void *p) @@ -2085,9 +2143,9 @@ static void banshee_add_status_info(char *s, int max_len, void *p) voodoo_recomp = 0; } -device_t atrend_voodoo_banshee_device = +device_t voodoo_banshee_device = { - "A-Trend Helios 3D (Voodoo Banshee)", + "Voodoo Banshee PCI (reference)", 0, banshee_init, banshee_close, @@ -2095,5 +2153,18 @@ device_t atrend_voodoo_banshee_device = banshee_speed_changed, banshee_force_redraw, banshee_add_status_info, - banshee_config + banshee_sgram_config +}; + +device_t creative_voodoo_banshee_device = +{ + "Creative Labs 3D Blaster Banshee PCI", + 0, + creative_banshee_init, + banshee_close, + creative_banshee_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_sdram_config }; diff --git a/src/vid_voodoo_banshee.h b/src/vid_voodoo_banshee.h index 9479816..6e72747 100644 --- a/src/vid_voodoo_banshee.h +++ b/src/vid_voodoo_banshee.h @@ -1,3 +1,4 @@ -extern device_t atrend_voodoo_banshee_device; +extern device_t voodoo_banshee_device; +extern device_t creative_voodoo_banshee_device; void banshee_set_overlay_addr(void *p, uint32_t addr); diff --git a/src/video.c b/src/video.c index 0550186..a8c7dbb 100644 --- a/src/video.c +++ b/src/video.c @@ -83,7 +83,6 @@ typedef struct static VIDEO_CARD video_cards[] = { - {"A-Trend Helios 3D (Voodoo Banshee)", "banshee", &atrend_voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, @@ -97,6 +96,7 @@ static VIDEO_CARD video_cards[] = {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}, {"Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Creative Labs 3D Blaster Banshee PCI", "cl_banshee", &creative_voodoo_banshee_device, GFX_CL_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}, {"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, @@ -129,6 +129,7 @@ static VIDEO_CARD video_cards[] = {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, + {"Voodoo Banshee (reference)", "banshee", &voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"", "", NULL, 0} }; From 93c0bc85c7dfcda2aa0c8244b2f23015c74fd194 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 16:48:02 +0100 Subject: [PATCH 0888/1050] Mark Banshee mappings as external. Banshee cards now work on GA-686BX. --- src/vid_voodoo_banshee.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 61e7132..69b6f77 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1993,7 +1993,7 @@ static void *banshee_init_common(char *fn, int has_sgram) banshee_write_linear_w, banshee_write_linear_l, NULL, - 0, + MEM_MAPPING_EXTERNAL, &banshee->svga); mem_mapping_add(&banshee->reg_mapping_low, 0, 0,banshee_reg_read, banshee_reg_readw, @@ -2002,7 +2002,7 @@ static void *banshee_init_common(char *fn, int has_sgram) banshee_reg_writew, banshee_reg_writel, NULL, - 0, + MEM_MAPPING_EXTERNAL, banshee); mem_mapping_add(&banshee->reg_mapping_high, 0,0,banshee_reg_read, banshee_reg_readw, @@ -2011,7 +2011,7 @@ static void *banshee_init_common(char *fn, int has_sgram) banshee_reg_writew, banshee_reg_writel, NULL, - 0, + MEM_MAPPING_EXTERNAL, banshee); // io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); From 801e560b539092f4c53bf30f606e01953c27625b Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 15 Aug 2020 21:13:08 +0100 Subject: [PATCH 0889/1050] Remove duplicates from Slot 1 CPU list. --- src/cpu_tables.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cpu_tables.c b/src/cpu_tables.c index 3ff519c..ac6f7be 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -523,8 +523,6 @@ CPU cpus_Slot1_100MHz[] = {"Pentium II/350", CPU_PENTIUM_2, fpus_builtin, 20, 350000000, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 42}, {"Pentium II/400", CPU_PENTIUM_2, fpus_builtin, 20, 400000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 48}, {"Pentium II/450", CPU_PENTIUM_2, fpus_builtin, 20, 450000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 54}, - {"Pentium II/266", CPU_PENTIUM_2, fpus_builtin, 20, 266666666, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 32}, - {"Pentium II/300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36}, {"Celeron 266", CPU_CELERON, fpus_builtin, 20, 266666666, 3, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 32}, {"Celeron 300", CPU_CELERON, fpus_builtin, 20, 300000000, 3, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 36}, {"Celeron-A 300", CPU_CELERON_A, fpus_builtin, 20, 300000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 40}, From 870a19f5378816723cbfd7c4acf0406e9b6e5743 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Aug 2020 20:32:43 +0100 Subject: [PATCH 0890/1050] Don't fatal() on unknown Banshee port read/write. Fixes Windows 95 hardware detection. --- src/vid_voodoo_banshee.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 69b6f77..49dc782 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -447,7 +447,7 @@ static void banshee_ext_out(uint16_t addr, uint8_t val, void *p) break; default: - fatal("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); + pclog("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); } } static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) @@ -649,7 +649,7 @@ static uint8_t banshee_ext_in(uint16_t addr, void *p) break; default: - fatal("bad banshee_ext_in: addr=%04x\n", addr); + pclog("bad banshee_ext_in: addr=%04x\n", addr); break; } From fccd59ba92c17a27cbd60b69e5a54b396de30061 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Aug 2020 20:57:15 +0100 Subject: [PATCH 0891/1050] Add Banshee RGB565 undithered overlay format. Currently dithered and undithered are handled the same. --- src/vid_voodoo_banshee.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 49dc782..9ddc4cf 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -139,6 +139,7 @@ enum #define VIDPROCCFG_2X_MODE (1 << 26) #define VIDPROCCFG_HWCURSOR_ENA (1 << 27) +#define OVERLAY_FMT_565 (1) #define OVERLAY_FMT_YUYV422 (5) #define OVERLAY_FMT_UYVY422 (6) #define OVERLAY_FMT_565_DITHER (7) @@ -1636,6 +1637,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) DECODE_UYUV422(); \ break; \ \ + case OVERLAY_FMT_565: \ case OVERLAY_FMT_565_DITHER: \ if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ DECODE_RGB565_TILED(); \ From c9bf81f599b8f05e0db4a639eadf98dc930b4e59 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Aug 2020 19:47:57 +0100 Subject: [PATCH 0892/1050] Fix Banshee CMDFIFO base address mask. --- src/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 9ddc4cf..09ec5c4 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1053,7 +1053,7 @@ static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) switch (addr & 0x1fc) { case cmdBaseAddr0: - voodoo->cmdfifo_base = (val & 0x3ff) << 12; + voodoo->cmdfifo_base = (val & 0xfff) << 12; voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); // pclog("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val); break; From 9adb36ece3a11bee4178aa23cb97d560dbf1c94d Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Aug 2020 21:11:32 +0100 Subject: [PATCH 0893/1050] Banshee status now returns busy when either of the render threads is busy. Fixed HUD in Jedi Knight. --- src/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 09ec5c4..1104996 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -667,7 +667,7 @@ static uint32_t banshee_status(banshee_t *banshee) int fifo_size = 0xffff - fifo_entries; int swap_count = voodoo->swap_count; int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1]; uint32_t ret; ret = 0; From 1ebaa7c640c9270f664d35b93202caf5618cd861 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 17 Aug 2020 21:38:25 +0100 Subject: [PATCH 0894/1050] Banshee 2D blitter should wait for 3D to go idle before starting a blit. Fixes text in Forsaken. --- src/vid_voodoo_banshee_blitter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index c04ea87..aa942b2 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -20,6 +20,7 @@ #include "vid_voodoo.h" #include "vid_voodoo_common.h" #include "vid_voodoo_banshee_blitter.h" +#include "vid_voodoo_render.h" #define COMMAND_CMD_MASK (0xf) #define COMMAND_CMD_NOP (0 << 0) @@ -1181,6 +1182,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) // pclog("dstXY=%08x\n", val); break; case 0x70: + voodoo_wait_for_render_thread_idle(voodoo); voodoo->banshee_blt.command = val; voodoo->banshee_blt.rops[0] = val >> 24; // pclog("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); From 95ccdcae5c6eb1ff13802d286eaf34bccc20df3f Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 18 Aug 2020 20:06:08 +0100 Subject: [PATCH 0895/1050] Implement bilinear filtering on Banshee video overlay. --- src/vid_voodoo_banshee.c | 121 ++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 27 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 1104996..0ad35e8 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -58,7 +58,7 @@ typedef struct banshee_t uint32_t intrCtrl; - uint32_t overlay_buffer[4096]; + uint32_t overlay_buffer[2][4096]; mem_mapping_t linear_mapping; @@ -130,6 +130,11 @@ enum #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) +#define VIDPROCCFG_FILTER_MODE_MASK (3 << 16) +#define VIDPROCCFG_FILTER_MODE_POINT (0 << 16) +#define VIDPROCCFG_FILTER_MODE_DITHER_2X2 (1 << 16) +#define VIDPROCCFG_FILTER_MODE_DITHER_4X4 (2 << 16) +#define VIDPROCCFG_FILTER_MODE_BILINEAR (3 << 16) #define VIDPROCCFG_DESKTOP_PIX_FORMAT ((banshee->vidProcCfg >> 18) & 7) #define VIDPROCCFG_OVERLAY_PIX_FORMAT ((banshee->vidProcCfg >> 21) & 7) #define VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT (21) @@ -1503,7 +1508,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) } \ while (0) -#define DECODE_RGB565() \ +#define DECODE_RGB565(buf) \ do \ { \ int c; \ @@ -1516,12 +1521,12 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ \ - banshee->overlay_buffer[wp++] = (r << 3) | (g << 10) | (b << 19); \ + banshee->overlay_buffer[buf][wp++] = (r << 3) | (g << 10) | (b << 19); \ src += 2; \ } \ } while (0) -#define DECODE_RGB565_TILED() \ +#define DECODE_RGB565_TILED(buf) \ do \ { \ int c; \ @@ -1534,11 +1539,11 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ \ - banshee->overlay_buffer[wp++] = (r << 3) | (g << 10) | (b << 19); \ + banshee->overlay_buffer[buf][wp++] = (r << 3) | (g << 10) | (b << 19); \ } \ } while (0) -#define DECODE_YUYV422() \ +#define DECODE_YUYV422(buf) \ do \ { \ int c; \ @@ -1567,7 +1572,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y1 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ \ r = y2 + dR; \ CLAMP(r); \ @@ -1575,11 +1580,11 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y2 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ } \ } while (0) -#define DECODE_UYUV422() \ +#define DECODE_UYUV422(buf) \ do \ { \ int c; \ @@ -1608,7 +1613,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y1 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ \ r = y2 + dR; \ CLAMP(r); \ @@ -1616,12 +1621,12 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y2 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[wp++] = r | (g << 8) | (b << 16); \ + banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ } \ } while (0) -#define OVERLAY_SAMPLE() \ +#define OVERLAY_SAMPLE(buf) \ do \ { \ switch (banshee->overlay_pix_fmt) \ @@ -1630,19 +1635,19 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) break; \ \ case OVERLAY_FMT_YUYV422: \ - DECODE_YUYV422(); \ + DECODE_YUYV422(buf); \ break; \ \ case OVERLAY_FMT_UYVY422: \ - DECODE_UYUV422(); \ + DECODE_UYUV422(buf); \ break; \ \ case OVERLAY_FMT_565: \ case OVERLAY_FMT_565_DITHER: \ if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ - DECODE_RGB565_TILED(); \ + DECODE_RGB565_TILED(buf); \ else \ - DECODE_RGB565(); \ + DECODE_RGB565(buf); \ break; \ \ default: \ @@ -1660,29 +1665,91 @@ static void banshee_overlay_draw(svga_t *svga, int displine) uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch); + uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? + (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : + (y + 1) * svga->overlay_latch.pitch); uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; uint32_t src_x = 0; + unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; // pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); // if (src_addr >= 0x800000) // fatal("overlay out of range!\n"); p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + 32]; - OVERLAY_SAMPLE(); + OVERLAY_SAMPLE(0); - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) + switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) { - for (x = 0; x < svga->overlay_latch.xsize; x++) + case VIDPROCCFG_FILTER_MODE_BILINEAR: + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(1); + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - p[x] = banshee->overlay_buffer[src_x >> 20]; - - src_x += voodoo->overlay.vidOverlayDudx; + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + unsigned int x_coeff = (src_x & 0xfffff) >> 4; + unsigned int coeffs[4] = { + ((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, + ( x_coeff * (0x10000 - y_coeff)) >> 16, + ((0x10000 - x_coeff) * y_coeff) >> 16, + ( x_coeff * y_coeff) >> 16 + }; + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; + uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; + uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; + int r = (((samp0 >> 16) & 0xff) * coeffs[0] + + ((samp1 >> 16) & 0xff) * coeffs[1] + + ((samp2 >> 16) & 0xff) * coeffs[2] + + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; + int g = (((samp0 >> 8) & 0xff) * coeffs[0] + + ((samp1 >> 8) & 0xff) * coeffs[1] + + ((samp2 >> 8) & 0xff) * coeffs[2] + + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; + int b = ((samp0 & 0xff) * coeffs[0] + + (samp1 & 0xff) * coeffs[1] + + (samp2 & 0xff) * coeffs[2] + + (samp3 & 0xff) * coeffs[3]) >> 16; + p[x] = (r << 16) | (g << 8) | b; + + src_x += voodoo->overlay.vidOverlayDudx; + } } - } - else - { - for (x = 0; x < svga->overlay_latch.xsize; x++) - p[x] = banshee->overlay_buffer[x]; + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; + int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + + ((samp1 >> 16) & 0xff) * y_coeff) >> 16; + int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + + ((samp1 >> 8) & 0xff) * y_coeff) >> 16; + int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + + (samp1 & 0xff) * y_coeff) >> 16; + p[x] = (r << 16) | (g << 8) | b; + } + } + break; + + case VIDPROCCFG_FILTER_MODE_POINT: + default: + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + + src_x += voodoo->overlay.vidOverlayDudx; + } + } + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + break; } if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) From 191514939158fb5c1ee6446f549d6788c8fa85cf Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 27 Aug 2020 08:31:43 +0100 Subject: [PATCH 0896/1050] Increase Banshee revision to 3, matching my real CL Banshee card. Removes the need for any fogTable hack, which is in any case inconsistently applied by drivers and I think may only be needed on pre-production devices. --- src/vid_voodoo_banshee.c | 2 +- src/vid_voodoo_reg.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 0ad35e8..592a78d 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1808,7 +1808,7 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x07: ret = banshee->pci_regs[0x07] & 0x36; break; - case 0x08: ret = 1; break; /*Revision ID*/ + case 0x08: ret = 3; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index df48abe..97b1c2e 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -530,9 +530,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_fogTable18: case SST_fogTable19: case SST_fogTable1a: case SST_fogTable1b: case SST_fogTable1c: case SST_fogTable1d: case SST_fogTable1e: case SST_fogTable1f: addr = (addr - SST_fogTable00) >> 1; - if (voodoo->type == VOODOO_BANSHEE) - val = ~val; /*Banshee fog table seems to be inverted. There's a reference - in the glide2x source to a "banshee (rev<3) fogTable hack"*/ voodoo->params.fogTable[addr].dfog = val & 0xff; voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; From fb391d2484e92edec0061e18bdc689296e7e3be9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 31 Aug 2020 13:31:23 +0100 Subject: [PATCH 0897/1050] Rewrite Voodoo triangle setup vertex selection code. Fixes missing triangles on Banshee with some D3D games (eg Black & White, Viper Racing) --- src/vid_voodoo_common.h | 3 +- src/vid_voodoo_reg.c | 62 +++++++++++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index ee15c16..da64d6e 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -306,7 +306,8 @@ typedef struct voodoo_t uint32_t sSetupMode; vert_t verts[4]; - int vertex_num; + unsigned int vertex_ages[3]; + unsigned int vertex_next_age; int num_verticies; int cull_pingpong; diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 97b1c2e..1af1131 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -683,18 +683,66 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) 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->verts[1] = voodoo->verts[3]; + voodoo->verts[2] = voodoo->verts[3]; + voodoo->vertex_next_age = 0; + voodoo->vertex_ages[0] = voodoo->vertex_next_age++; + voodoo->num_verticies = 1; voodoo->cull_pingpong = 0; 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]; +// pclog("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); + /*I'm not sure this is the vertex selection algorithm actually used in the 3dfx + chips, but this works with a number of games that switch between strip and fan + mode in the middle of a run (eg Black & White, Viper Racing)*/ + if (voodoo->vertex_next_age < 3) + { + /*Fewer than three vertices already written, store in next slot*/ + int vertex_nr = voodoo->vertex_next_age; + + voodoo->verts[vertex_nr] = voodoo->verts[3]; + voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; + } + else + { + int vertex_nr = 0; + + if (!(voodoo->sSetupMode & SETUPMODE_STRIP_MODE)) + { + /*Strip - find oldest vertex*/ + if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && + (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && + (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) + vertex_nr = 1; + else + vertex_nr = 2; + } + else + { + /*Fan - find second oldest vertex (ie pivot around oldest)*/ + if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && + (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[0]) && + (voodoo->vertex_ages[0] < voodoo->vertex_ages[1])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && + (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) + vertex_nr = 1; + else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[1]) && + (voodoo->vertex_ages[1] < voodoo->vertex_ages[0])) + vertex_nr = 1; + else + vertex_nr = 2; + } + voodoo->verts[vertex_nr] = voodoo->verts[3]; + voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; + } voodoo->num_verticies++; - voodoo->vertex_num++; if (voodoo->num_verticies == 3) { // pclog("triangle_setup\n"); @@ -703,8 +751,6 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->num_verticies = 2; } - if (voodoo->vertex_num == 4) - fatal("sDrawTriCMD overflow\n"); break; case SST_bltSrcBaseAddr: From 24d817659448693e207d95d381e696b91b67fee2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 2 Sep 2020 21:00:03 +0100 Subject: [PATCH 0898/1050] Reset P6 current ifetch_length on start of code block and on decoder flush. --- src/codegen_timing_p6.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/codegen_timing_p6.c b/src/codegen_timing_p6.c index 0aee290..b668f99 100644 --- a/src/codegen_timing_p6.c +++ b/src/codegen_timing_p6.c @@ -1691,6 +1691,8 @@ static int fpu_st_timestamp[8]; dependent uop chains*/ static int last_uop_timestamp = 0; +static int ifetch_length = 0; + static void decode_flush() { int c; @@ -1727,6 +1729,7 @@ static void decode_flush() decode_timestamp++; decode_buffer.nr_uops = 0; decode_buffer.nr_ins = 0; + ifetch_length = 0; } /*The instruction is only of interest here if it's longer than 8 bytes, as that's the @@ -1779,7 +1782,6 @@ static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_ return len; } -static int ifetch_length = 0; static void decode_instruction(const p6_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, uint32_t op_pc, int bit8) { uint32_t regmask_required; @@ -1945,6 +1947,8 @@ void codegen_timing_p6_block_start() reg_available_timestamp[c] = 0; for (c = 0; c < 8; c++) fpu_st_timestamp[c] = 0; + + ifetch_length = 0; } void codegen_timing_p6_start() From eb524e6f12f1170f16f77f579dfba2c2e16fa61f Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 5 Sep 2020 17:16:33 +0100 Subject: [PATCH 0899/1050] Move trap handling out of main dynarec loop. --- src/386_dynarec.c | 54 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 12ecebf..82f1093 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -309,6 +309,29 @@ void exec386_dynarec(int cycs) ins++; insc++; } + + if (trap) + { + trap = 0; + flags_rebuild(); + if (msw&1) + { + pmodeint(1,0); + } + else + { + writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); + writememw(ss,(SP-4)&0xFFFF,CS); + writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); + SP-=6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc=readmemw(0,addr); + loadcs(readmemw(0,addr+2)); + } + } + cpu_end_block_after_ins = 0; } else @@ -439,8 +462,6 @@ void exec386_dynarec(int cycs) uint8_t opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - // 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); @@ -461,7 +482,7 @@ void exec386_dynarec(int cycs) if (((cs+cpu_state.pc) - start_pc) >= max_block_size) CPU_BLOCK_END(); - if (trap) + if (cpu_state.flags & T_FLAG) CPU_BLOCK_END(); if (nmi && nmi_enable && nmi_mask) @@ -521,8 +542,6 @@ void exec386_dynarec(int cycs) uint8_t opcode = fetchdat & 0xFF; fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - // 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); @@ -541,7 +560,7 @@ void exec386_dynarec(int cycs) if (((cs+cpu_state.pc) - start_pc) >= max_block_size) CPU_BLOCK_END(); - if (trap) + if (cpu_state.flags & T_FLAG) CPU_BLOCK_END(); if (nmi && nmi_enable && nmi_mask) @@ -601,28 +620,7 @@ void exec386_dynarec(int cycs) } } - if (trap) - { - trap = 0; - flags_rebuild(); - if (msw&1) - { - pmodeint(1,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - else if (nmi && nmi_enable && nmi_mask) + if (nmi && nmi_enable && nmi_mask) { cpu_state.oldpc = cpu_state.pc; // pclog("NMI\n"); From 5a94c78cbbf9070e8bec5cfd790762b8e0c35633 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 5 Sep 2020 20:51:50 +0100 Subject: [PATCH 0900/1050] Split up exec386_dynarec() a bit. --- src/386_dynarec.c | 675 ++++++++++++++++++++++------------------------ 1 file changed, 325 insertions(+), 350 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 82f1093..d52efde 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -240,11 +240,331 @@ static void prefetch_flush() int cpu_end_block_after_ins = 0; + +static inline void exec_interpreter(void) +{ + cpu_block_end = 0; + x86_was_reset = 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) + { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + uint8_t opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; + +// 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); + } + + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); + + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if (cpu_end_block_after_ins) + { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } + + ins++; + insc++; + } + + if (trap) + { + trap = 0; + cpu_state.oldpc = cpu_state.pc; + x86_int(1); + } + + cpu_end_block_after_ins = 0; +} + +static inline void exec_recompiler(void) +{ + uint32_t phys_addr = get_phys(cs+cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = &codeblock[codeblock_hash[hash]]; + int valid_block = 0; + + if (!cpu_state.abrt) + { + page_t *page = &pages[phys_addr >> 12]; + + /*Block must match current CS, PC, code segment size, + 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) & CPU_STATUS_FLAGS) && + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) + { + uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) + { + /*Walk page tree to see if we find the correct block*/ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + 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) & CPU_STATUS_FLAGS) && + ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) + { + block = new_block; + codeblock_hash[hash] = get_block_nr(block); + } + } + } + } + + if (valid_block && (block->page_mask & *block->dirty_mask)) + { + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } + if (valid_block && block->page_mask2) + { + /*We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + 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->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); + 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 & *block->dirty_mask2) + { + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } + } + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) + { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) + { + /*FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); + } + } + + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) + { + void (*code)() = (void *)&block->data[BLOCK_START]; + +// 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; + + cpu_recomp_blocks++; + } + else if (valid_block && !cpu_state.abrt) + { + uint32_t start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; + + cpu_block_end = 0; + x86_was_reset = 0; + + cpu_new_blocks++; + + 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) + { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + uint8_t 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); + + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + + if (x86_was_reset) + break; + } + + /*Cap source code at 4000 bytes per block; this + 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 (((cs+cpu_state.pc) - start_pc) >= max_block_size) + CPU_BLOCK_END(); + + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_end_block_after_ins) + { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + insc++; + } + cpu_end_block_after_ins = 0; + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end_recompile(block); + + if (x86_was_reset) + codegen_reset(); + + codegen_in_recompile = 0; + } + else if (!cpu_state.abrt) + { + /*Mark block but do not recompile*/ + uint32_t start_pc = cs+cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; + + cpu_block_end = 0; + x86_was_reset = 0; + + 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) + { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; + + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); + + if (!cpu_state.abrt) + { + uint8_t 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); + + if (x86_was_reset) + break; + } + + /*Cap source code at 4000 bytes per block; this + 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 (((cs+cpu_state.pc) - start_pc) >= max_block_size) + CPU_BLOCK_END(); + + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + + if (cpu_end_block_after_ins) + { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } + + if (cpu_state.abrt) + { + codegen_block_remove(); + CPU_BLOCK_END(); + } + + ins++; + insc++; + } + cpu_end_block_after_ins = 0; + + if (!cpu_state.abrt && !x86_was_reset) + codegen_block_end(); + + if (x86_was_reset) + codegen_reset(); + } + else + cpu_state.oldpc = cpu_state.pc; + +} + + static int cycles_main = 0; void exec386_dynarec(int cycs) { uint8_t temp; - uint32_t addr; int tempi; int cycdiff; int oldcyc; @@ -263,338 +583,9 @@ void exec386_dynarec(int cycs) 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; - x86_was_reset = 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) - { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - uint8_t opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; - -// 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); - } - - if (((cs + cpu_state.pc) >> 12) != pccache) - CPU_BLOCK_END(); - - if (cpu_state.abrt) - CPU_BLOCK_END(); - if (trap) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if (cpu_end_block_after_ins) - { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } - - ins++; - insc++; - } - - if (trap) - { - trap = 0; - flags_rebuild(); - if (msw&1) - { - pmodeint(1,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } - } - - cpu_end_block_after_ins = 0; - } + exec_interpreter(); else - { - uint32_t phys_addr = get_phys(cs+cpu_state.pc); - int hash = HASH(phys_addr); - codeblock_t *block = &codeblock[codeblock_hash[hash]]; - int valid_block = 0; - - if (!cpu_state.abrt) - { - page_t *page = &pages[phys_addr >> 12]; - - /*Block must match current CS, PC, code segment size, - 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) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (!valid_block) - { - uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); - - if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) - { - /*Walk page tree to see if we find the correct block*/ - codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); - 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) & CPU_STATUS_FLAGS) && - ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (valid_block) - { - block = new_block; - codeblock_hash[hash] = get_block_nr(block); - } - } - } - } - - if (valid_block && (block->page_mask & *block->dirty_mask)) - { - codegen_check_flush(page, page->dirty_mask, phys_addr); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - } - if (valid_block && block->page_mask2) - { - /*We don't want the second page to cause a page - fault at this stage - that would break any - code crossing a page boundary where the first - page is present but the second isn't. Instead - 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->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); - 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 & *block->dirty_mask2) - { - codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - } - } - if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) - { - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - if (block->flags & CODEBLOCK_BYTE_MASK) - block->flags |= CODEBLOCK_NO_IMMEDIATES; - else - block->flags |= CODEBLOCK_BYTE_MASK; - } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) - { - /*FPU top-of-stack does not match the value this block was compiled - with, re-compile using dynamic top-of-stack*/ - block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); - } - } - - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) - { - void (*code)() = (void *)&block->data[BLOCK_START]; - -// 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; - - cpu_recomp_blocks++; - } - else if (valid_block && !cpu_state.abrt) - { - uint32_t start_pc = cs+cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; - - cpu_block_end = 0; - x86_was_reset = 0; - - cpu_new_blocks++; - - 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) - { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - uint8_t 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); - - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - - if (x86_was_reset) - break; - } - - /*Cap source code at 4000 bytes per block; this - 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 (((cs+cpu_state.pc) - start_pc) >= max_block_size) - CPU_BLOCK_END(); - - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - - if (cpu_end_block_after_ins) - { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } - - if (cpu_state.abrt) - { - codegen_block_remove(); - CPU_BLOCK_END(); - } - - ins++; - insc++; - } - cpu_end_block_after_ins = 0; - - if (!cpu_state.abrt && !x86_was_reset) - codegen_block_end_recompile(block); - - if (x86_was_reset) - codegen_reset(); - - codegen_in_recompile = 0; - } - else if (!cpu_state.abrt) - { - /*Mark block but do not recompile*/ - uint32_t start_pc = cs+cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; - - cpu_block_end = 0; - x86_was_reset = 0; - - 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) - { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; - - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); - - if (!cpu_state.abrt) - { - uint8_t 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); - - if (x86_was_reset) - break; - } - - /*Cap source code at 4000 bytes per block; this - 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 (((cs+cpu_state.pc) - start_pc) >= max_block_size) - CPU_BLOCK_END(); - - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - - if (cpu_end_block_after_ins) - { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } - - if (cpu_state.abrt) - { - codegen_block_remove(); - CPU_BLOCK_END(); - } - - ins++; - insc++; - } - cpu_end_block_after_ins = 0; - - if (!cpu_state.abrt && !x86_was_reset) - codegen_block_end(); - - if (x86_was_reset) - codegen_reset(); - } - else - cpu_state.oldpc = cpu_state.pc; - - } - + exec_recompiler(); cycdiff=oldcyc-cycles; tsc += cycdiff; @@ -637,25 +628,9 @@ void exec386_dynarec(int cycs) temp=picinterrupt(); if (temp!=0xFF) { + cpu_state.oldpc = cpu_state.pc; + x86_int(temp); // pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc); - CPU_BLOCK_END(); - flags_rebuild(); - if (msw&1) - { - pmodeint(temp,0); - } - else - { - writememw(ss,(SP-2)&0xFFFF,cpu_state.flags); - writememw(ss,(SP-4)&0xFFFF,CS); - writememw(ss,(SP-6)&0xFFFF,cpu_state.pc); - SP-=6; - addr=temp<<2; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc=readmemw(0,addr); - loadcs(readmemw(0,addr+2)); - } } } } From cccaf86fd33855607bea49a984d53de88ddad2d3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 9 Sep 2020 21:49:28 +0100 Subject: [PATCH 0901/1050] Mark some exceptions (mainly v86 related) as 'expected', meaning they won't cause a code block deletion. This speeds up some v86 code due to a reduction in code block churning. --- src/386.c | 2 +- src/386_common.h | 5 ++++- src/386_dynarec.c | 13 ++++++++----- src/x86.h | 11 +++++++++++ src/x86_ops_int.h | 2 +- src/x86_ops_ret.h | 4 ++-- src/x86seg.c | 15 ++++++++++++--- 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/386.c b/src/386.c index 6b0dcd0..8276b40 100644 --- a/src/386.c +++ b/src/386.c @@ -196,7 +196,7 @@ void exec386(int cycs) flags_rebuild(); // pclog("Abort\n"); // if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt); - tempi = cpu_state.abrt; + tempi = cpu_state.abrt & ABRT_MASK; cpu_state.abrt = 0; x86_doabrt(tempi); if (cpu_state.abrt) diff --git a/src/386_common.h b/src/386_common.h index 80da16d..143984a 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -19,7 +19,10 @@ int checkio(int port); if (cpu_state.abrt) return 1; \ if (tempi) \ { \ - x86gpf(NULL,0); \ + if (cpu_state.eflags & VM_FLAG) \ + x86gpf_expected(NULL,0); \ + else \ + x86gpf(NULL,0); \ return 1; \ } \ } diff --git a/src/386_dynarec.c b/src/386_dynarec.c index d52efde..171c6b3 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -462,7 +462,8 @@ static inline void exec_recompiler(void) if (cpu_state.abrt) { - codegen_block_remove(); + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); CPU_BLOCK_END(); } @@ -471,7 +472,7 @@ static inline void exec_recompiler(void) } cpu_end_block_after_ins = 0; - if (!cpu_state.abrt && !x86_was_reset) + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) codegen_block_end_recompile(block); if (x86_was_reset) @@ -540,7 +541,8 @@ static inline void exec_recompiler(void) if (cpu_state.abrt) { - codegen_block_remove(); + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); CPU_BLOCK_END(); } @@ -549,7 +551,8 @@ static inline void exec_recompiler(void) } cpu_end_block_after_ins = 0; - if (!cpu_state.abrt && !x86_was_reset) +// if (!cpu_state.abrt && !x86_was_reset) + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) codegen_block_end(); if (x86_was_reset) @@ -592,7 +595,7 @@ void exec386_dynarec(int cycs) if (cpu_state.abrt) { flags_rebuild(); - tempi = cpu_state.abrt; + tempi = cpu_state.abrt & ABRT_MASK; cpu_state.abrt = 0; x86_doabrt(tempi); if (cpu_state.abrt) diff --git a/src/x86.h b/src/x86.h index 753edf5..2665249 100644 --- a/src/x86.h +++ b/src/x86.h @@ -261,6 +261,16 @@ enum ABRT_PF = 0xE }; +#define ABRT_MASK 0x7f +/*An 'expected' exception is one that would be expected to occur on every execution + of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is + one that would be unlikely to occur on the next exception, eg a page fault may be + fixed up by the exception handler and the next execution would not hit it. + + This distinction is used by the dynarec; a block that hits an 'expected' exception + would be compiled, a block that hits an 'unexpected' exception would be rejected so + that we don't end up with an unnecessarily short block*/ +#define ABRT_EXPECTED 0x80 extern uint32_t abrt_error; void x86_doabrt(int x86_abrt); @@ -275,6 +285,7 @@ void x86illegal(); void x86seg_reset(); void x86gpf(char *s, uint16_t error); +void x86gpf_expected(char *s, uint16_t error); void resetx86(); void softresetx86(); diff --git a/src/x86_ops_int.h b/src/x86_ops_int.h index efb2a5d..3ac96f3 100644 --- a/src/x86_ops_int.h +++ b/src/x86_ops_int.h @@ -59,7 +59,7 @@ static int opINT(uint32_t fetchdat) } } } - x86gpf(NULL,0); + x86gpf_expected(NULL,0); return 1; } // /*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); diff --git a/src/x86_ops_ret.h b/src/x86_ops_ret.h index 70ac327..3dd93f4 100644 --- a/src/x86_ops_ret.h +++ b/src/x86_ops_ret.h @@ -166,7 +166,7 @@ static int opIRET(uint32_t fetchdat) } else { - x86gpf(NULL,0); + x86gpf_expected(NULL,0); return 1; } } @@ -214,7 +214,7 @@ static int opIRETD(uint32_t fetchdat) if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { - x86gpf(NULL,0); + x86gpf_expected(NULL,0); return 1; } if (msw & 1) diff --git a/src/x86seg.c b/src/x86seg.c index f28e7c5..a69dfcd 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -161,10 +161,16 @@ void x86_doabrt(int x86_abrt) } void x86gpf(char *s, uint16_t error) { -// pclog("GPF %04X\n", error); +// pclog("GPF %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc); cpu_state.abrt = ABRT_GPF; abrt_error = error; } +void x86gpf_expected(char *s, uint16_t error) +{ +// pclog("GPF_v86 %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc); + cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; + abrt_error = error; +} void x86ss(char *s, uint16_t error) { // pclog("SS %04X\n", error); @@ -1715,8 +1721,11 @@ 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); +// pclog("No seg\n"); + if (cpu_state.eflags & VM_FLAG) /*This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn*/ + x86gpf_expected(NULL,(num*8)+2); + else + x86gpf(NULL,(num*8)+2); return; } if (DPL Date: Mon, 14 Sep 2020 20:46:56 +0100 Subject: [PATCH 0902/1050] Add register rename optimisation to dynarec to eliminate some redundant UOP_MOVs. --- src/codegen_ir.c | 69 ++++++++++++++++++++++++++++------------------- src/codegen_reg.c | 36 +++++++++++++++++++++++++ src/codegen_reg.h | 2 ++ 3 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/codegen_ir.c b/src/codegen_ir.c index d7e6157..e902a1e 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -107,37 +107,52 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) if ((uop->type & UOP_MASK) == UOP_INVALID) continue; - if (uop->type & UOP_TYPE_PARAMS_REGS) - { - codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); - if (uop->src_reg_a.reg != IREG_INVALID) - { - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - } - if (uop->src_reg_b.reg != IREG_INVALID) - { - uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); - } - if (uop->src_reg_c.reg != IREG_INVALID) - { - uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); - } - } - - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); - if (uop->type & UOP_TYPE_PARAMS_REGS) + if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && + reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) { - if (uop->dest_reg_a.reg != IREG_INVALID) - { - uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); - } + /*Special case for UOP_MOV - if source register won't be used again then + just rename it to dest register instead of moving*/ + codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); + codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); } + else + { + if (uop->type & UOP_TYPE_PARAMS_REGS) + { + codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); + if (uop->src_reg_a.reg != IREG_INVALID) + { + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); + } + if (uop->src_reg_b.reg != IREG_INVALID) + { + uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); + } + if (uop->src_reg_c.reg != IREG_INVALID) + { + uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); + } + } + + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); + + if (uop->type & UOP_TYPE_PARAMS_REGS) + { + if (uop->dest_reg_a.reg != IREG_INVALID) + { + uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); + } + } - if (!uop_handlers[uop->type & UOP_MASK]) - fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); - uop_handlers[uop->type & UOP_MASK](block, uop); + if (!uop_handlers[uop->type & UOP_MASK]) + fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); + uop_handlers[uop->type & UOP_MASK](block, uop); + } if (uop->type & UOP_TYPE_JUMP) { diff --git a/src/codegen_reg.c b/src/codegen_reg.c index da6dd8c..c300a93 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -671,6 +671,42 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } +void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) +{ + host_reg_set_t *reg_set = get_reg_set(src); + int c; + int target; + +// pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) + { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) + break; + } + if (c == reg_set->nr_regs) + fatal("codegen_reg_rename: Can't find register to rename\n"); + + target = c; + if (reg_set->dirty[target]) + codegen_reg_writeback(reg_set, block, target, 0); + reg_set->regs[target] = dst; + reg_set->dirty[target] = 1; +// pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); + + /*Invalidate any stale copies of the dest register*/ + for (c = 0; c < reg_set->nr_regs; c++) + { + if (c == target) + continue; + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) + { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } +} + void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { host_reg_set_t *reg_set; diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 6bdb7c2..5a30f65 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -399,6 +399,8 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); +void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst); + void codegen_reg_mark_as_required(); void codegen_reg_process_dead_list(struct ir_data_t *ir); #endif From 25fe224ea93df363d3abd93ee6f0d85efd078ddc Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 16 Sep 2020 20:47:12 +0100 Subject: [PATCH 0903/1050] Add dynarec optimisation for UOP_MOV_IMM, to avoid register allocation if the destination register won't be immediately used again. --- src/codegen_backend_x86-64.h | 2 + src/codegen_backend_x86-64_ops.c | 44 ++++++++++++++++++++++ src/codegen_backend_x86-64_ops.h | 3 ++ src/codegen_backend_x86-64_uops.c | 17 +++++++++ src/codegen_backend_x86.h | 2 + src/codegen_backend_x86_ops.c | 39 +++++++++++++++++++ src/codegen_backend_x86_ops.h | 3 ++ src/codegen_backend_x86_uops.c | 23 ++++++++++++ src/codegen_ir.c | 10 ++++- src/codegen_ir_defs.h | 7 ++++ src/codegen_reg.c | 62 +++++++++++++++++++++++++++++++ src/codegen_reg.h | 5 +++ 12 files changed, 216 insertions(+), 1 deletion(-) diff --git a/src/codegen_backend_x86-64.h b/src/codegen_backend_x86-64.h index 150c8c8..3339224 100644 --- a/src/codegen_backend_x86-64.h +++ b/src/codegen_backend_x86-64.h @@ -10,3 +10,5 @@ #define HASH(l) ((l) & 0x1ffff) #define BLOCK_MAX 0x3c0 + +#define CODEGEN_BACKEND_HAS_MOV_IMM diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index c32cd26..41a88b2 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -517,6 +517,26 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) codegen_addbyte(block, imm_data); } } +void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) +{ + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addword(block, imm_data); + } + else + { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 10); + codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addword(block, imm_data); + } +} void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -941,6 +961,30 @@ void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); } +void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) +{ + if (base_reg & 8) + fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); + + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_RSP) + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } + else + { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } + else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); +} + void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { if (reg >= 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index 3cd86fb..e1db22a 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -56,6 +56,7 @@ void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); +void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); @@ -72,6 +73,8 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg); +void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data); + void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index 8b73909..b2ca7dc 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -3141,4 +3141,21 @@ void codegen_set_jump_dest(codeblock_t *block, void *p) *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); } +void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) +{ + host_x86_MOV8_ABS_IMM(block, p, imm_data); +} +void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) +{ + host_x86_MOV16_ABS_IMM(block, p, imm_data); +} +void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) +{ + host_x86_MOV32_ABS_IMM(block, p, imm_data); +} +void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) +{ + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); +} + #endif diff --git a/src/codegen_backend_x86.h b/src/codegen_backend_x86.h index db521a7..7f9f233 100644 --- a/src/codegen_backend_x86.h +++ b/src/codegen_backend_x86.h @@ -10,3 +10,5 @@ #define HASH(l) ((l) & 0x1ffff) #define BLOCK_MAX 0x3c0 + +#define CODEGEN_BACKEND_HAS_MOV_IMM diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 23726eb..7c8a18d 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -445,6 +445,24 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) codegen_addbyte(block, imm_data); } } +void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) +{ + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + + if (offset >= -128 && offset < 127) + { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addword(block, imm_data); + } + else + { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addword(block, imm_data); + } +} void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); @@ -701,6 +719,27 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); } +void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) +{ + if (offset >= -128 && offset < 127) + { + if (base_reg == REG_ESP) + { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } + else + { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } + else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); +} + void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { codegen_alloc_bytes(block, 2); diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 94f526c..a6ca19f 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -60,6 +60,7 @@ void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift); void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); +void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data); void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); @@ -75,6 +76,8 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); +void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data); + void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index 0acf07c..94092c3 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2644,6 +2644,11 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); return 0; } +static int codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} static int codegen_SUB(codeblock_t *block, uop_t *uop) { @@ -2839,6 +2844,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM_16 & UOP_MASK] = codegen_STORE_PTR_IMM_16, [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, @@ -3139,4 +3145,21 @@ void codegen_set_jump_dest(codeblock_t *block, void *p) *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); } +void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) +{ + host_x86_MOV8_ABS_IMM(block, p, imm_data); +} +void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) +{ + host_x86_MOV16_ABS_IMM(block, p, imm_data); +} +void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) +{ + host_x86_MOV32_ABS_IMM(block, p, imm_data); +} +void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) +{ + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); +} + #endif diff --git a/src/codegen_ir.c b/src/codegen_ir.c index e902a1e..5406d6e 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -107,7 +107,15 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) if ((uop->type & UOP_MASK) == UOP_INVALID) continue; - +#ifdef CODEGEN_BACKEND_HAS_MOV_IMM + if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) + { + /*Special case for UOP_MOV_IMM - if destination not already in host register + and won't be used again then just store directly to memory*/ + codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); + } + else +#endif if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) { diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 76f4979..b1f4b3c 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -55,6 +55,7 @@ /*UOP_JMP_DEST - jump to ptr*/ #define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) #define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) +#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) #ifdef DEBUG_EXTRA /*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ @@ -765,6 +766,7 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) #define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) #define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) @@ -807,4 +809,9 @@ void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int void codegen_set_jump_dest(codeblock_t *block, void *p); +void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data); +void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data); +void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data); +void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data); + #endif diff --git a/src/codegen_reg.c b/src/codegen_reg.c index c300a93..aed144b 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -449,6 +449,45 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i reg_set->dirty[c] = 0; } +#ifdef CODEGEN_BACKEND_HAS_MOV_IMM +void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data) +{ + int reg_idx = IREG_GET_REG(ir_reg.reg); + void *p = ireg_data[reg_idx].p; + + switch (ireg_data[reg_idx].native_size) + { + case REG_BYTE: + if ((uintptr_t)p < 256) + fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); + codegen_direct_write_8_imm(block, p, imm_data); + break; + + case REG_WORD: + if ((uintptr_t)p < 256) + fatal("codegen_reg_write_imm - REG_WORD %p\n", p); + codegen_direct_write_16_imm(block, p, imm_data); + break; + + case REG_DWORD: + if ((uintptr_t)p < 256) + codegen_direct_write_32_imm_stack(block, (int)p, imm_data); + else + codegen_direct_write_32_imm(block, p, imm_data); + break; + + case REG_POINTER: + case REG_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_BYTE: + case REG_FPU_ST_QWORD: + case REG_FPU_ST_DOUBLE: + default: + fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); + } +} +#endif + static void alloc_reg(ir_reg_t ir_reg) { host_reg_set_t *reg_set = get_reg_set(ir_reg); @@ -671,6 +710,29 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } +#ifdef CODEGEN_BACKEND_HAS_MOV_IMM +int codegen_reg_is_loaded(ir_reg_t ir_reg) +{ + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; + + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) + { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) + { + if (reg_set->regs[c].version <= ir_reg.version-1) + { + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); + return 1; + } + } + } + return 0; +} +#endif + void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) { host_reg_set_t *reg_set = get_reg_set(src); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 5a30f65..80bc859 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -396,6 +396,11 @@ void codegen_reg_flush_invalidate(struct ir_data_t *ir, codeblock_t *block); /*Register ir_reg usage for this uOP. This ensures that required registers aren't evicted*/ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c); +#ifdef CODEGEN_BACKEND_HAS_MOV_IMM +int codegen_reg_is_loaded(ir_reg_t ir_reg); +void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data); +#endif + ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); From 6a09e9636c972670712e3857ec2aa8febdc785d8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 17 Sep 2020 20:37:30 +0100 Subject: [PATCH 0904/1050] Disable a lot of dynarec sanity checks in release builds. --- src/codegen_block.c | 49 +++++++++++++++++++++++++++++------- src/codegen_ir.c | 3 ++- src/codegen_reg.c | 60 ++++++++++++++++++++++++++++++++++++++++++--- src/codegen_reg.h | 16 +++++++++--- 4 files changed, 111 insertions(+), 17 deletions(-) diff --git a/src/codegen_block.c b/src/codegen_block.c index 19e32f6..c8cdc7f 100644 --- a/src/codegen_block.c +++ b/src/codegen_block.c @@ -69,8 +69,10 @@ static int dirty_list_size = 0; static void block_free_list_add(codeblock_t *block) { +#ifndef RELEASE_BUILD if (block->flags & CODEBLOCK_IN_DIRTY_LIST) fatal("block_free_list_add: block=%p in dirty list\n", block); +#endif if (block_free_list) block->next = block_free_list; else @@ -82,8 +84,10 @@ static void block_free_list_add(codeblock_t *block) static void block_dirty_list_add(codeblock_t *block) { +#ifndef RELEASE_BUILD if (block->flags & CODEBLOCK_IN_DIRTY_LIST) fatal("block_dirty_list_add: block=%p already in dirty list\n", block); +#endif // pclog("block_dirty_list_add: block=%i size=%i %i head=%i tail=%i\n", get_block_nr(block), dirty_list_size, dirty_list_check_size(), block_dirty_list_head, block_dirty_list_tail); if (block_dirty_list_head != BLOCK_INVALID) { @@ -108,12 +112,14 @@ static void block_dirty_list_add(codeblock_t *block) /*Evict oldest block to the free list*/ codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; +#ifndef RELEASE_BUILD if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); if (!block_dirty_list_tail) fatal("block_dirty_list_add - !block_dirty_list_tail\n"); if (evict_block->prev == BLOCK_INVALID) fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); +#endif block_dirty_list_tail = evict_block->prev; codeblock[evict_block->prev].next = BLOCK_INVALID; @@ -132,8 +138,10 @@ static void block_dirty_list_remove(codeblock_t *block) codeblock_t *prev_block = &codeblock[block->prev]; codeblock_t *next_block = &codeblock[block->next]; +#ifndef RELEASE_BUILD if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); +#endif /*Is block head of list*/ if (block->prev == BLOCK_INVALID) @@ -148,8 +156,10 @@ static void block_dirty_list_remove(codeblock_t *block) next_block->prev = block->prev; dirty_list_size--; +#ifndef RELEASE_BUILD if (dirty_list_size < 0) fatal("remove - dirty_list_size < 0!\n"); +#endif block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; // pclog(" block_dirty_list_remove: %p flags = %x\n", block, block->flags); } @@ -180,9 +190,10 @@ static codeblock_t *block_free_list_get() /*Free list is empty, check the dirty list*/ if (block_dirty_list_tail) { +#ifndef RELEASE_BUILD if (dirty_list_size <= 0) fatal("get - dirty_list_size <= 0!\n"); - +#endif /*Reuse oldest block*/ block = &codeblock[block_dirty_list_tail]; @@ -310,9 +321,10 @@ static void add_to_block_list(codeblock_t *block) uint16_t block_nr = get_block_nr(block); //pclog("Add to block list %p %08x %llx %x\n", block, block->phys, block->page_mask2, block->flags); +#ifndef RELEASE_BUILD if (!block->page_mask) fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask,block->page_mask2); - +#endif if (block_prev_nr) { block->next = block_prev_nr; @@ -327,8 +339,10 @@ static void add_to_block_list(codeblock_t *block) if (block->next) { +#ifndef RELEASE_BUILD if (codeblock[block->next].pc == BLOCK_PC_INVALID) fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], (void *)codeblock, block_current, block_pos); +#endif } if (block->page_mask2) @@ -356,9 +370,10 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) { if (!block->page_mask) return; +#ifndef RELEASE_BUILD if (block->flags & CODEBLOCK_IN_DIRTY_LIST) fatal("remove_from_block_list: in dirty list\n"); - +#endif if (block->prev) { codeblock[block->prev].next = block->next; @@ -376,8 +391,10 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) if (!(block->flags & CODEBLOCK_HAS_PAGE2)) { +#ifndef RELEASE_BUILD if (block->prev_2 || block->next_2) fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); +#endif return; } block->flags &= ~CODEBLOCK_HAS_PAGE2; @@ -404,11 +421,12 @@ static void invalidate_block(codeblock_t *block) { uint32_t old_pc = block->pc; +#ifndef RELEASE_BUILD if (block->flags & CODEBLOCK_IN_DIRTY_LIST) fatal("invalidate_block: already in dirty list\n"); if (block->pc == BLOCK_PC_INVALID) fatal("Invalidating deleted block\n"); - +#endif remove_from_block_list(block, old_pc); block_dirty_list_add(block); if (block->head_mem_block) @@ -423,8 +441,10 @@ static void delete_block(codeblock_t *block) if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; +#ifndef RELEASE_BUILD if (block->pc == BLOCK_PC_INVALID) fatal("Deleting deleted block\n"); +#endif block->pc = BLOCK_PC_INVALID; codeblock_tree_delete(block); @@ -443,8 +463,10 @@ static void delete_dirty_block(codeblock_t *block) if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; +#ifndef RELEASE_BUILD if (block->pc == BLOCK_PC_INVALID) fatal("Deleting deleted block\n"); +#endif block->pc = BLOCK_PC_INVALID; codeblock_tree_delete(block); @@ -494,8 +516,10 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) invalidate_block(block); cpu_recomp_evicted++; } +#ifndef RELEASE_BUILD if (block_nr == next_block) fatal("Broken 1\n"); +#endif block_nr = next_block; } @@ -512,8 +536,10 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) invalidate_block(block); cpu_recomp_evicted++; } +#ifndef RELEASE_BUILD if (block_nr == next_block) fatal("Broken 2\n"); +#endif block_nr = next_block; } @@ -541,8 +567,10 @@ void codegen_block_init(uint32_t phys_addr) if (!page->block) mem_flush_write_page(phys_addr, cs+cpu_state.pc); block = block_free_list_get(); +#ifndef RELEASE_BUILD if (!block) fatal("codegen_block_init: block_free_list_get() returned NULL\n"); +#endif block_current = get_block_nr(block); block_num = HASH(phys_addr); @@ -582,10 +610,10 @@ void codegen_block_start_recompile(codeblock_t *block) block_num = HASH(block->phys); block_current = get_block_nr(block);//block->pnt; - +#ifndef RELEASE_BUILD if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) fatal("Recompile to used block!\n"); - +#endif block->head_mem_block = codegen_allocator_allocate(NULL, block_current); block->data = codeblock_allocator_get_ptr(block->head_mem_block); @@ -695,6 +723,7 @@ void codegen_block_generate_end_mask_recompile() if (!pages[block->phys_2 >> 12].block_2) mem_flush_write_page(block->phys_2, codegen_endpc); +#ifndef RELEASE_BUILD if (!block->page_mask2) fatal("!page_mask2\n"); if (block->next_2) @@ -703,6 +732,7 @@ void codegen_block_generate_end_mask_recompile() if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); } +#endif } else { @@ -724,9 +754,10 @@ void codegen_block_generate_end_mask_mark() uint32_t end_pc; page_t *p; +#ifndef RELEASE_BUILD if (block->flags & CODEBLOCK_BYTE_MASK) fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); - +#endif block->page_mask = 0; start_pc = (block->pc & 0xfff) & ~63; if ((block->pc ^ codegen_endpc) & ~0xfff) @@ -771,7 +802,7 @@ void codegen_block_generate_end_mask_mark() if (!pages[block->phys_2 >> 12].block_2) mem_flush_write_page(block->phys_2, codegen_endpc); - +#ifndef RELEASE_BUILD if (!block->page_mask2) fatal("!page_mask2\n"); if (block->next_2) @@ -780,7 +811,7 @@ void codegen_block_generate_end_mask_mark() if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); } - +#endif block->dirty_mask2 = &page_2->dirty_mask; } else diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 5406d6e..e42ac49 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -156,9 +156,10 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); } } - +#ifndef RELEASE_BUILD if (!uop_handlers[uop->type & UOP_MASK]) fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); +#endif uop_handlers[uop->type & UOP_MASK](block, uop); } diff --git a/src/codegen_reg.c b/src/codegen_reg.c index aed144b..b8966b9 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -271,8 +271,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { case REG_WORD: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); +#endif if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else @@ -280,8 +282,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_DWORD: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); +#endif if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else @@ -289,8 +293,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_QWORD: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); +#endif if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else @@ -298,8 +304,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_POINTER: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); +#endif if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else @@ -307,8 +315,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_DOUBLE: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); +#endif if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); else @@ -316,8 +326,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_FPU_ST_BYTE: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); +#endif if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); else @@ -325,8 +337,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_FPU_ST_QWORD: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); +#endif if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); else @@ -334,8 +348,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, break; case REG_FPU_ST_DOUBLE: +#ifndef RELEASE_BUILD if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); +#endif if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); else @@ -363,24 +379,30 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i switch (ireg_data[ir_reg].native_size) { case REG_BYTE: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_BYTE %p\n", p); +#endif codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); break; case REG_WORD: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_WORD %p\n", p); +#endif codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); break; case REG_DWORD: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); +#endif if ((uintptr_t)p < 256) codegen_direct_write_32_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); else @@ -388,8 +410,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i break; case REG_QWORD: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); +#endif if ((uintptr_t)p < 256) codegen_direct_write_64_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); else @@ -397,16 +421,20 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i break; case REG_POINTER: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); if ((uintptr_t)p < 256) fatal("codegen_reg_writeback - REG_POINTER %p\n", p); +#endif codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); break; case REG_DOUBLE: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); +#endif if ((uintptr_t)p < 256) codegen_direct_write_double_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); else @@ -414,8 +442,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i break; case REG_FPU_ST_BYTE: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_INTEGER) fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); +#endif if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); else @@ -423,8 +453,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i break; case REG_FPU_ST_QWORD: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); +#endif if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); else @@ -432,8 +464,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i break; case REG_FPU_ST_DOUBLE: +#ifndef RELEASE_BUILD if (ireg_data[ir_reg].type != REG_FP) fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); +#endif if (block->flags & CODEBLOCK_STATIC_TOP) codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); else @@ -458,14 +492,18 @@ void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_dat switch (ireg_data[reg_idx].native_size) { case REG_BYTE: +#ifndef RELEASE_BUILD if ((uintptr_t)p < 256) fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); +#endif codegen_direct_write_8_imm(block, p, imm_data); break; case REG_WORD: +#ifndef RELEASE_BUILD if ((uintptr_t)p < 256) fatal("codegen_reg_write_imm - REG_WORD %p\n", p); +#endif codegen_direct_write_16_imm(block, p, imm_data); break; @@ -498,8 +536,10 @@ static void alloc_reg(ir_reg_t ir_reg) { if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { +#ifndef RELEASE_BUILD if (reg_set->regs[c].version != ir_reg.version) fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); +#endif reg_set->locked |= (1 << c); return; } @@ -591,9 +631,10 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; break; } - +#ifndef RELEASE_BUILD if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); +#endif } if (c == reg_set->nr_regs) @@ -612,8 +653,10 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in if (!(reg_set->locked & (1 << c))) break; } +#ifndef RELEASE_BUILD if (c == reg_set->nr_regs) fatal("codegen_reg_alloc_read_reg - out of registers\n"); +#endif } if (reg_set->dirty[c]) codegen_reg_writeback(reg_set, block, c, 1); @@ -628,8 +671,10 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in // pclog(" already loaded %i\n", c); reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; +#ifndef RELEASE_BUILD if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); +#endif if (host_reg_idx) *host_reg_idx = c; @@ -653,11 +698,13 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) codegen_reg_alloc_read_reg(block, parent_reg, &c); +#ifndef RELEASE_BUILD if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version-1) fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, reg_set->regs[c].reg,reg_set->regs[c].version, ir_reg.reg,ir_reg.version); - +#endif + reg_set->regs[c].reg = ir_reg.reg; reg_set->regs[c].version = ir_reg.version; reg_set->dirty[c] = 1; @@ -672,8 +719,10 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { if (reg_set->regs[c].version <= ir_reg.version-1) { +#ifndef RELEASE_BUILD if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); +#endif break; } } @@ -696,8 +745,10 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) if (!(reg_set->locked & (1 << c))) break; } +#ifndef RELEASE_BUILD if (c == reg_set->nr_regs) fatal("codegen_reg_alloc_write_reg - out of registers\n"); +#endif if (reg_set->dirty[c]) codegen_reg_writeback(reg_set, block, c, 1); } @@ -723,8 +774,10 @@ int codegen_reg_is_loaded(ir_reg_t ir_reg) { if (reg_set->regs[c].version <= ir_reg.version-1) { +#ifndef RELEASE_BUILD if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); +#endif return 1; } } @@ -746,9 +799,10 @@ void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) break; } +#ifndef RELEASE_BUILD if (c == reg_set->nr_regs) fatal("codegen_reg_rename: Can't find register to rename\n"); - +#endif target = c; if (reg_set->dirty[target]) codegen_reg_writeback(reg_set, block, target, 0); diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 80bc859..4aaa231 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -325,17 +325,21 @@ static inline ir_reg_t codegen_reg_read(int reg) ir_reg_t ireg; reg_version_t *version; +#ifndef RELEASE_BUILD if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_read - IREG_INVALID\n"); - +#endif ireg.reg = reg; ireg.version = reg_last_version[IREG_GET_REG(reg)]; version = ®_version[IREG_GET_REG(ireg.reg)][ireg.version]; version->flags = 0; version->refcount++; +#ifndef RELEASE_BUILD if (!version->refcount) fatal("codegen_reg_read - refcount overflow\n"); - else if (version->refcount > REG_REFCOUNT_MAX) + else +#endif + if (version->refcount > REG_REFCOUNT_MAX) CPU_BLOCK_END(); if (version->refcount > max_version_refcount) max_version_refcount = version->refcount; @@ -351,9 +355,10 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) int last_version = reg_last_version[IREG_GET_REG(reg)]; reg_version_t *version; +#ifndef RELEASE_BUILD if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_write - IREG_INVALID\n"); - +#endif ireg.reg = reg; ireg.version = last_version + 1; @@ -365,9 +370,12 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) } reg_last_version[IREG_GET_REG(reg)]++; +#ifndef RELEASE_BUILD if (!reg_last_version[IREG_GET_REG(reg)]) fatal("codegen_reg_write - version overflow\n"); - else if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) + else +#endif + if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) CPU_BLOCK_END(); if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; From 1900499aced6b65a6ccf25314d1537734472aa2b Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 17 Sep 2020 20:47:39 +0100 Subject: [PATCH 0905/1050] Fix "effective clockspeed" display when using Banshee. --- src/vid_voodoo_banshee.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 592a78d..8e544c6 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1206,6 +1206,7 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p) svga_t *svga = &banshee->svga; cycles -= voodoo->read_time; + cycles_lost += voodoo->read_time; addr &= svga->decode_mask; if (addr >= voodoo->tile_base) @@ -1239,6 +1240,7 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p) svga_t *svga = &banshee->svga; cycles -= voodoo->read_time; + cycles_lost += voodoo->read_time; addr &= svga->decode_mask; if (addr >= voodoo->tile_base) @@ -1272,6 +1274,7 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p) svga_t *svga = &banshee->svga; cycles -= voodoo->read_time; + cycles_lost += voodoo->read_time; addr &= svga->decode_mask; if (addr >= voodoo->tile_base) @@ -1305,6 +1308,7 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) svga_t *svga = &banshee->svga; cycles -= voodoo->write_time; + cycles_lost += voodoo->write_time; // pclog("write_linear: addr=%08x val=%02x\n", addr, val); addr &= svga->decode_mask; @@ -1339,6 +1343,7 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) svga_t *svga = &banshee->svga; cycles -= voodoo->write_time; + cycles_lost += voodoo->write_time; // pclog("write_linear: addr=%08x val=%02x\n", addr, val); addr &= svga->decode_mask; @@ -1371,11 +1376,14 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) banshee_t *banshee = (banshee_t *)p; voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + int timing; if (addr == voodoo->last_write_addr+4) - cycles -= voodoo->burst_time; + timing = voodoo->burst_time; else - cycles -= voodoo->write_time; + timing = voodoo->write_time; + cycles -= timing; + cycles_lost += timing; voodoo->last_write_addr = addr; // /*if (val) */pclog("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base); From e761045e40fb05a2b0dd902e5a0dcb11cae3fd7b Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 17 Sep 2020 20:52:31 +0100 Subject: [PATCH 0906/1050] Remove unused variables in Banshee. --- src/vid_voodoo_banshee.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 8e544c6..1062e56 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1212,7 +1212,6 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p) if (addr >= voodoo->tile_base) { int x, y; -// uint32_t old_addr = addr; addr -= voodoo->tile_base; x = addr & (voodoo->tile_stride-1); @@ -1246,7 +1245,6 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p) if (addr >= voodoo->tile_base) { int x, y; -// uint32_t old_addr = addr; addr -= voodoo->tile_base; x = addr & (voodoo->tile_stride-1); @@ -1280,7 +1278,6 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p) if (addr >= voodoo->tile_base) { int x, y; -// uint32_t old_addr = addr; addr -= voodoo->tile_base; x = addr & (voodoo->tile_stride-1); @@ -1315,7 +1312,6 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) if (addr >= voodoo->tile_base) { int x, y; - uint32_t old_addr = addr; addr -= voodoo->tile_base; x = addr & (voodoo->tile_stride-1); @@ -1350,7 +1346,6 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) if (addr >= voodoo->tile_base) { int x, y; - uint32_t old_addr = addr; addr -= voodoo->tile_base; x = addr & (voodoo->tile_stride-1); @@ -1391,17 +1386,12 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) if (addr >= voodoo->tile_base) { int x, y; - uint32_t old_addr = addr; - uint32_t addr_off; - uint32_t addr2; - + addr -= voodoo->tile_base; - addr_off = addr; x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; - addr2 = x + y*voodoo->tile_x; // pclog(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_x_real); } @@ -1436,7 +1426,6 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) voodoo->cmdfifo_holecount--; if (!voodoo->cmdfifo_holecount) { - int words_to_add = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) + 1; /*Filled in holes, resume normal operation*/ voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; From 3e5e519d10ed8727943544a12a2649c8388f0a73 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 27 Sep 2020 21:45:02 +0100 Subject: [PATCH 0907/1050] Implement dirty updating on Banshee 16bpp tiled modes --- src/vid_voodoo_banshee.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 1062e56..144c7f0 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -292,25 +292,34 @@ static void banshee_render_16bpp_tiled(svga_t *svga) int offset = 32; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; uint32_t addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + int drawn = 0; for (x = 0; x <= svga->hdisp; x += 64) { - int xx; - - for (xx = 0; xx < 64; xx += 2) + if (svga->hwcursor_on || svga->overlay_on) + svga->changedvram[addr >> 12] = 2; + if (svga->changedvram[addr >> 12] || svga->fullchange) { - uint32_t dat = *(uint32_t *)(&svga->vram[(addr + (xx << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + uint16_t *vram_p = (uint16_t *)&svga->vram[addr & svga->vram_display_mask]; + int xx; + + for (xx = 0; xx < 64; xx++) + *p++ = video_16to32[*vram_p++]; + + drawn = 1; } - + else + p += 64; addr += 128*32; } + if (drawn) + { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + } + banshee->desktop_y++; } From 2cf57ab8b21ebecc1845bee891be7223d9a7af40 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Sep 2020 19:44:33 +0100 Subject: [PATCH 0908/1050] If Banshee video overlay is full screen (as would be the case for full screen 3D), don't bother rendering the desktop behind it. --- src/vid_voodoo_banshee.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 144c7f0..c1a1f64 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -409,6 +409,14 @@ static void banshee_recalctimings(svga_t *svga) voodoo->overlay.end_x, voodoo->overlay.end_y, voodoo->overlay.size_x, voodoo->overlay.size_y, svga->overlay.pitch); + if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && + svga->hdisp == voodoo->overlay.size_x && svga->dispend == voodoo->overlay.size_y) + { + /*Overlay is full screen, so don't bother rendering the desktop + behind it*/ + svga->render = svga_render_null; + svga->bpp = 0; + } } svga->video_res_override = 1; From f6406c77e528f2a22553dcdaffb0b50de74249dc Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 28 Sep 2020 20:02:38 +0100 Subject: [PATCH 0909/1050] Add fast path in Banshee overlay render; if overlay is unfiltered and unscaled then just write straight to destination buffer. --- src/vid_voodoo_banshee.c | 147 +++++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 69 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index c1a1f64..199f751 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1535,7 +1535,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ \ - banshee->overlay_buffer[buf][wp++] = (r << 3) | (g << 10) | (b << 19); \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ src += 2; \ } \ } while (0) @@ -1553,7 +1553,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ \ - banshee->overlay_buffer[buf][wp++] = (r << 3) | (g << 10) | (b << 19); \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ } \ } while (0) @@ -1586,7 +1586,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y1 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ + buf[wp++] = r | (g << 8) | (b << 16); \ \ r = y2 + dR; \ CLAMP(r); \ @@ -1594,7 +1594,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y2 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ + buf[wp++] = r | (g << 8) | (b << 16); \ } \ } while (0) @@ -1627,7 +1627,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y1 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ + buf[wp++] = r | (g << 8) | (b << 16); \ \ r = y2 + dR; \ CLAMP(r); \ @@ -1635,7 +1635,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) CLAMP(g); \ b = y2 + dB; \ CLAMP(b); \ - banshee->overlay_buffer[buf][wp++] = r | (g << 8) | (b << 16); \ + buf[wp++] = r | (g << 8) | (b << 16); \ } \ } while (0) @@ -1691,79 +1691,88 @@ static void banshee_overlay_draw(svga_t *svga, int displine) // fatal("overlay out of range!\n"); p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + 32]; - OVERLAY_SAMPLE(0); - - switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && + !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)) { - case VIDPROCCFG_FILTER_MODE_BILINEAR: - src = &svga->vram[src_addr2 & svga->vram_mask]; - OVERLAY_SAMPLE(1); - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) - { - for (x = 0; x < svga->overlay_latch.xsize; x++) - { - unsigned int x_coeff = (src_x & 0xfffff) >> 4; - unsigned int coeffs[4] = { - ((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, - ( x_coeff * (0x10000 - y_coeff)) >> 16, - ((0x10000 - x_coeff) * y_coeff) >> 16, - ( x_coeff * y_coeff) >> 16 - }; - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; - uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; - uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; - int r = (((samp0 >> 16) & 0xff) * coeffs[0] + - ((samp1 >> 16) & 0xff) * coeffs[1] + - ((samp2 >> 16) & 0xff) * coeffs[2] + - ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; - int g = (((samp0 >> 8) & 0xff) * coeffs[0] + - ((samp1 >> 8) & 0xff) * coeffs[1] + - ((samp2 >> 8) & 0xff) * coeffs[2] + - ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; - int b = ((samp0 & 0xff) * coeffs[0] + - (samp1 & 0xff) * coeffs[1] + - (samp2 & 0xff) * coeffs[2] + - (samp3 & 0xff) * coeffs[3]) >> 16; - p[x] = (r << 16) | (g << 8) | b; + /*No scaling or filtering required, just write straight to output buffer*/ + OVERLAY_SAMPLE(p); + } + else + { + OVERLAY_SAMPLE(banshee->overlay_buffer[0]); - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else + switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) { - for (x = 0; x < svga->overlay_latch.xsize; x++) + case VIDPROCCFG_FILTER_MODE_BILINEAR: + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(banshee->overlay_buffer[1]); + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; - int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + - ((samp1 >> 16) & 0xff) * y_coeff) >> 16; - int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + - ((samp1 >> 8) & 0xff) * y_coeff) >> 16; - int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + - (samp1 & 0xff) * y_coeff) >> 16; - p[x] = (r << 16) | (g << 8) | b; + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + unsigned int x_coeff = (src_x & 0xfffff) >> 4; + unsigned int coeffs[4] = { + ((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, + ( x_coeff * (0x10000 - y_coeff)) >> 16, + ((0x10000 - x_coeff) * y_coeff) >> 16, + ( x_coeff * y_coeff) >> 16 + }; + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; + uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; + uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; + int r = (((samp0 >> 16) & 0xff) * coeffs[0] + + ((samp1 >> 16) & 0xff) * coeffs[1] + + ((samp2 >> 16) & 0xff) * coeffs[2] + + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; + int g = (((samp0 >> 8) & 0xff) * coeffs[0] + + ((samp1 >> 8) & 0xff) * coeffs[1] + + ((samp2 >> 8) & 0xff) * coeffs[2] + + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; + int b = ((samp0 & 0xff) * coeffs[0] + + (samp1 & 0xff) * coeffs[1] + + (samp2 & 0xff) * coeffs[2] + + (samp3 & 0xff) * coeffs[3]) >> 16; + p[x] = (r << 16) | (g << 8) | b; + + src_x += voodoo->overlay.vidOverlayDudx; + } } - } - break; + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; + int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + + ((samp1 >> 16) & 0xff) * y_coeff) >> 16; + int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + + ((samp1 >> 8) & 0xff) * y_coeff) >> 16; + int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + + (samp1 & 0xff) * y_coeff) >> 16; + p[x] = (r << 16) | (g << 8) | b; + } + } + break; - case VIDPROCCFG_FILTER_MODE_POINT: - default: - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) - { - for (x = 0; x < svga->overlay_latch.xsize; x++) + case VIDPROCCFG_FILTER_MODE_POINT: + default: + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; - src_x += voodoo->overlay.vidOverlayDudx; + src_x += voodoo->overlay.vidOverlayDudx; + } } + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + break; } - else - { - for (x = 0; x < svga->overlay_latch.xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - break; } if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) From 679322882bd3c36af6aa23a9afdbad0cbb80b5d2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 29 Sep 2020 20:40:53 +0100 Subject: [PATCH 0910/1050] Add missing svga_render_null() function. --- src/vid_svga_render.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 680772d..eac363f 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -4,6 +4,13 @@ #include "vid_svga.h" #include "vid_svga_render.h" +void svga_render_null(svga_t *svga) +{ + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; +} + void svga_render_blank(svga_t *svga) { int x, xx; From 92e0b785480a2a5e49aac3eac97c3bab156b13ad Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 29 Sep 2020 20:40:53 +0100 Subject: [PATCH 0911/1050] Add missing svga_render_null() function. --- src/vid_svga_render.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index fb88e8d..625ba6b 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -9,6 +9,7 @@ extern int scrollcache; extern uint8_t edatlookup[4][4]; +void svga_render_null(svga_t *svga); void svga_render_blank(svga_t *svga); void svga_render_text_40(svga_t *svga); void svga_render_text_80(svga_t *svga); From dbb10c0894920a260cb7dc792c0fb9fbb00a8207 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 29 Sep 2020 21:16:47 +0100 Subject: [PATCH 0912/1050] Don't sample & filter EMU8000 voice if current volume is zero. --- src/sound_emu8k.c | 191 +++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 94 deletions(-) diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index e283922..bee7e1b 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -1719,106 +1719,109 @@ void emu8k_update(emu8k_t *emu8k) { int32_t dat; - /* Waveform oscillator */ -#ifdef RESAMPLER_LINEAR - dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); - -#elif defined RESAMPLER_CUBIC - dat = EMU8K_READ_INTERP_CUBIC(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); -#endif - - /* Filter section */ - if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF ) + if (emu_voice->cvcf_curr_volume) { - int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; - const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; - const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; - const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; - /* clip at twice the range */ - #define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 : buf + /* Waveform oscillator */ + #ifdef RESAMPLER_LINEAR + dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); - #ifdef FILTER_INITIAL - #define NOOP(x) (void)x; - NOOP(coef1) - /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). - * Work in 24bits. */ - dat = (dat * emu_voice->filt_att) >> 8; - - int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; - emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; - emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; - dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } + #elif defined RESAMPLER_CUBIC + dat = EMU8K_READ_INTERP_CUBIC(emu8k, emu_voice->addr.int_address, + emu_voice->addr.fract_address); + #endif - #elif defined FILTER_MOOG - - /*move to 24bits*/ - dat <<= 8; - - dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ - int64_t t1 = emu_voice->filt_buffer[1]; - emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; - emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - - int64_t t2 = emu_voice->filt_buffer[2]; - emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; - emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); - - int64_t t3 = emu_voice->filt_buffer[3]; - emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; - emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); - - emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; - emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); - - emu_voice->filt_buffer[0] = ClipBuffer(dat); - - dat = (int32_t)(emu_voice->filt_buffer[4] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #elif defined FILTER_CONSTANT - - /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). - * Also stay at 24bits.*/ - dat = (dat * emu_voice->filt_att) >> 8; - - emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] - + coef0 * (dat + - ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1]))>>24)) - ) >> 24; - emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] - + coef0 * emu_voice->filt_buffer[0]) >> 24; - - emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); - emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - - dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { dat = 32767; } - else if (dat < -32768) { dat = -32768; } - - #endif - - } - if (( emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) - { - /*volume and pan*/ - dat = (dat * emu_voice->cvcf_curr_volume) >> 16; - - (*buf++) += (dat * emu_voice->vol_l) >> 8; - (*buf++) += (dat * emu_voice->vol_r) >> 8; - - /* Effects section */ - if (emu_voice->ptrx_revb_send > 0) + /* Filter section */ + if (emu_voice->filterq_idx || emu_voice->cvcf_curr_filt_ctoff != 0xFFFF ) { - emu8k->reverb_in_buffer[pos]+=(dat*emu_voice->ptrx_revb_send) >> 8; + int cutoff = emu_voice->cvcf_curr_filt_ctoff >> 8; + const int64_t coef0 = filt_coeffs[emu_voice->filterq_idx][cutoff][0]; + const int64_t coef1 = filt_coeffs[emu_voice->filterq_idx][cutoff][1]; + const int64_t coef2 = filt_coeffs[emu_voice->filterq_idx][cutoff][2]; + /* clip at twice the range */ + #define ClipBuffer(buf) (buf < -16777216) ? -16777216 : (buf > 16777216) ? 16777216 : buf + + #ifdef FILTER_INITIAL + #define NOOP(x) (void)x; + NOOP(coef1) + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one doesn't). + * Work in 24bits. */ + dat = (dat * emu_voice->filt_att) >> 8; + + int64_t vhp = ((-emu_voice->filt_buffer[0] * coef2) >> 24) - emu_voice->filt_buffer[1] - dat; + emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; + emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; + dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #elif defined FILTER_MOOG + + /*move to 24bits*/ + dat <<= 8; + + dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ + int64_t t1 = emu_voice->filt_buffer[1]; + emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + int64_t t2 = emu_voice->filt_buffer[2]; + emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; + emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); + + int64_t t3 = emu_voice->filt_buffer[3]; + emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; + emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); + + emu_voice->filt_buffer[4] = ((emu_voice->filt_buffer[3] + t3) * coef0 - emu_voice->filt_buffer[4] * coef1) >> 24; + emu_voice->filt_buffer[4] = ClipBuffer(emu_voice->filt_buffer[4]); + + emu_voice->filt_buffer[0] = ClipBuffer(dat); + + dat = (int32_t)(emu_voice->filt_buffer[4] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #elif defined FILTER_CONSTANT + + /* Apply expected attenuation. (FILTER_MOOG does it implicitly, but this one is constant gain). + * Also stay at 24bits.*/ + dat = (dat * emu_voice->filt_att) >> 8; + + emu_voice->filt_buffer[0] = (coef1 * emu_voice->filt_buffer[0] + + coef0 * (dat + + ((coef2 * (emu_voice->filt_buffer[0] - emu_voice->filt_buffer[1]))>>24)) + ) >> 24; + emu_voice->filt_buffer[1] = (coef1 * emu_voice->filt_buffer[1] + + coef0 * emu_voice->filt_buffer[0]) >> 24; + + emu_voice->filt_buffer[0] = ClipBuffer(emu_voice->filt_buffer[0]); + emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); + + dat = (int32_t)(emu_voice->filt_buffer[1] >> 8); + if (dat > 32767) { dat = 32767; } + else if (dat < -32768) { dat = -32768; } + + #endif + } - if (emu_voice->csl_chor_send > 0) + if (( emu8k->hwcf3 & 0x04) && !CCCA_DMA_ACTIVE(emu_voice->ccca)) { - emu8k->chorus_in_buffer[pos]+=(dat*emu_voice->csl_chor_send) >> 8; + /*volume and pan*/ + dat = (dat * emu_voice->cvcf_curr_volume) >> 16; + + (*buf++) += (dat * emu_voice->vol_l) >> 8; + (*buf++) += (dat * emu_voice->vol_r) >> 8; + + /* Effects section */ + if (emu_voice->ptrx_revb_send > 0) + { + emu8k->reverb_in_buffer[pos]+=(dat*emu_voice->ptrx_revb_send) >> 8; + } + if (emu_voice->csl_chor_send > 0) + { + emu8k->chorus_in_buffer[pos]+=(dat*emu_voice->csl_chor_send) >> 8; + } } } From 52a79fbb57a00b68b16492e5df3f62a8dda6ae0f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 5 Oct 2020 19:34:20 +0100 Subject: [PATCH 0913/1050] Add option for Voodoo to use 4 render threads. --- src/vid_voodoo.c | 111 ++++++++++++++++++++++---------- src/vid_voodoo_banshee.c | 55 +++++++++++----- src/vid_voodoo_codegen_x86-64.h | 14 ++-- src/vid_voodoo_codegen_x86.h | 14 ++-- src/vid_voodoo_common.h | 27 ++++---- src/vid_voodoo_render.c | 35 +++++++--- src/vid_voodoo_render.h | 22 +++++-- 7 files changed, 185 insertions(+), 93 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 310014e..414948f 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -820,35 +820,38 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) voodoo_t *voodoo = voodoo_set->voodoos[0]; voodoo_t *voodoo_slave = voodoo_set->voodoos[1]; char temps[512], temps2[256]; - int pixel_count_current[2]; + int pixel_count_current[4]; int pixel_count_total; - int texel_count_current[2]; + int texel_count_current[4]; int texel_count_total; - int render_time[2]; + int render_time[4]; uint64_t new_time = timer_read(); uint64_t status_diff = new_time - status_time; status_time = new_time; + int c; if (!status_diff) status_diff = 1; - pixel_count_current[0] = voodoo->pixel_count[0]; - pixel_count_current[1] = voodoo->pixel_count[1]; - texel_count_current[0] = voodoo->texel_count[0]; - texel_count_current[1] = voodoo->texel_count[1]; - render_time[0] = voodoo->render_time[0]; - render_time[1] = voodoo->render_time[1]; + for (c = 0; c < 4; c++) + { + pixel_count_current[c] = voodoo->pixel_count[c]; + texel_count_current[c] = voodoo->texel_count[c]; + render_time[c] = voodoo->render_time[c]; + } if (voodoo_set->nr_cards == 2) { - pixel_count_current[0] += voodoo_slave->pixel_count[0]; - pixel_count_current[1] += voodoo_slave->pixel_count[1]; - texel_count_current[0] += voodoo_slave->texel_count[0]; - texel_count_current[1] += voodoo_slave->texel_count[1]; - render_time[0] = (render_time[0] + voodoo_slave->render_time[0]) / 2; - render_time[1] = (render_time[1] + voodoo_slave->render_time[1]) / 2; + for (c = 0; c < 4; c++) + { + pixel_count_current[c] += voodoo_slave->pixel_count[c]; + texel_count_current[c] += voodoo_slave->texel_count[c]; + render_time[c] = (render_time[c] + voodoo_slave->render_time[c]) / 2; + } } - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); - texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - + (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]); + texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - + (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]); sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, (double)pixel_count_total/1000000.0, ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), @@ -856,45 +859,61 @@ static void voodoo_add_status_info(char *s, int max_len, void *p) ((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff), (double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) { sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } + if (voodoo->render_threads == 4) + { + sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + ((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff, + ((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps)-1); + } if (voodoo_set->nr_cards == 2) { sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); - if (voodoo_slave->render_threads == 2) + if (voodoo_slave->render_threads >= 2) { sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } + if (voodoo_slave->render_threads == 4) + { + sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + ((double)voodoo_slave->render_time[2] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[2] * 100.0) / status_diff, + ((double)voodoo_slave->render_time[3] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[3] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps)-1); + } } strncat(s, temps, max_len); - voodoo->pixel_count_old[0] = pixel_count_current[0]; - voodoo->pixel_count_old[1] = pixel_count_current[1]; - voodoo->texel_count_old[0] = texel_count_current[0]; - voodoo->texel_count_old[1] = texel_count_current[1]; + for (c = 0; c < 4; c++) + { + voodoo->pixel_count_old[c] = pixel_count_current[c]; + voodoo->texel_count_old[c] = texel_count_current[c]; + voodoo->render_time[c] = 0; + } voodoo->tri_count = voodoo->frame_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; voodoo->time = 0; - voodoo->render_time[0] = voodoo->render_time[1] = 0; if (voodoo_set->nr_cards == 2) { - voodoo_slave->pixel_count_old[0] = pixel_count_current[0]; - voodoo_slave->pixel_count_old[1] = pixel_count_current[1]; - voodoo_slave->texel_count_old[0] = texel_count_current[0]; - voodoo_slave->texel_count_old[1] = texel_count_current[1]; + for (c = 0; c < 4; c++) + { + voodoo_slave->pixel_count_old[c] = pixel_count_current[c]; + voodoo_slave->texel_count_old[c] = texel_count_current[c]; + voodoo_slave->render_time[c] = 0; + } voodoo_slave->tri_count = voodoo_slave->frame_count = 0; voodoo_slave->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0; voodoo_slave->time = 0; - voodoo_slave->render_time[0] = voodoo_slave->render_time[1] = 0; } voodoo_recomp = 0; } @@ -985,15 +1004,23 @@ void *voodoo_card_init() voodoo->wake_fifo_thread = thread_create_event(); voodoo->wake_render_thread[0] = thread_create_event(); voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_render_thread[2] = thread_create_event(); + voodoo->wake_render_thread[3] = thread_create_event(); voodoo->wake_main_thread = thread_create_event(); voodoo->fifo_not_full_event = thread_create_event(); voodoo->render_not_full_event[0] = thread_create_event(); voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->render_not_full_event[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); - + if (voodoo->render_threads == 4) + { + voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); + } timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); for (c = 0; c < 0x100; c++) @@ -1093,14 +1120,23 @@ void *voodoo_2d3d_card_init(int type) voodoo->wake_fifo_thread = thread_create_event(); voodoo->wake_render_thread[0] = thread_create_event(); voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_render_thread[2] = thread_create_event(); + voodoo->wake_render_thread[3] = thread_create_event(); voodoo->wake_main_thread = thread_create_event(); voodoo->fifo_not_full_event = thread_create_event(); voodoo->render_not_full_event[0] = thread_create_event(); voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->render_not_full_event[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + if (voodoo->render_threads == 4) + { + voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); + } timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); @@ -1244,8 +1280,13 @@ void voodoo_card_close(voodoo_t *voodoo) thread_kill(voodoo->fifo_thread); thread_kill(voodoo->render_thread[0]); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) thread_kill(voodoo->render_thread[1]); + if (voodoo->render_threads == 4) + { + thread_kill(voodoo->render_thread[2]); + thread_kill(voodoo->render_thread[3]); + } thread_destroy_event(voodoo->fifo_not_full_event); thread_destroy_event(voodoo->wake_main_thread); thread_destroy_event(voodoo->wake_fifo_thread); @@ -1376,6 +1417,10 @@ static device_config_t voodoo_config[] = .description = "2", .value = 2 }, + { + .description = "4", + .value = 4 + }, { .description = "" } diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 199f751..a18f412 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1998,6 +1998,10 @@ static device_config_t banshee_sgram_config[] = .description = "2", .value = 2 }, + { + .description = "4", + .value = 4 + }, { .description = "" } @@ -2039,6 +2043,10 @@ static device_config_t banshee_sdram_config[] = .description = "2", .value = 2 }, + { + .description = "4", + .value = 4 + }, { .description = "" } @@ -2182,27 +2190,30 @@ static void banshee_add_status_info(char *s, int max_len, void *p) banshee_t *banshee = (banshee_t *)p; voodoo_t *voodoo = banshee->voodoo; char temps[512]; - int pixel_count_current[2]; + int pixel_count_current[4]; int pixel_count_total; - int texel_count_current[2]; + int texel_count_current[4]; int texel_count_total; - int render_time[2]; + int render_time[4]; uint64_t new_time = timer_read(); uint64_t status_diff = new_time - status_time; + int c; status_time = new_time; svga_add_status_info(s, max_len, &banshee->svga); - pixel_count_current[0] = voodoo->pixel_count[0]; - pixel_count_current[1] = voodoo->pixel_count[1]; - texel_count_current[0] = voodoo->texel_count[0]; - texel_count_current[1] = voodoo->texel_count[1]; - render_time[0] = voodoo->render_time[0]; - render_time[1] = voodoo->render_time[1]; + for (c = 0; c < 4; c++) + { + pixel_count_current[c] = voodoo->pixel_count[c]; + texel_count_current[c] = voodoo->texel_count[c]; + render_time[c] = voodoo->render_time[c]; + } - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); - texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - + (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]); + texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - + (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]); sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, (double)pixel_count_total/1000000.0, ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), @@ -2210,25 +2221,35 @@ static void banshee_add_status_info(char *s, int max_len, void *p) ((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff), (double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) { char temps2[512]; sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); strncat(temps, temps2, sizeof(temps)-1); } + if (voodoo->render_threads == 4) + { + char temps2[512]; + sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + ((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff, + ((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps)-1); + } strncat(s, temps, max_len); strncat(s, "\n", max_len); - voodoo->pixel_count_old[0] = pixel_count_current[0]; - voodoo->pixel_count_old[1] = pixel_count_current[1]; - voodoo->texel_count_old[0] = texel_count_current[0]; - voodoo->texel_count_old[1] = texel_count_current[1]; + for (c = 0; c < 4; c++) + { + voodoo->pixel_count_old[c] = pixel_count_current[c]; + voodoo->texel_count_old[c] = texel_count_current[c]; + voodoo->render_time[c] = 0; + } + voodoo->tri_count = voodoo->frame_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; voodoo->time = 0; - voodoo->render_time[0] = voodoo->render_time[1] = 0; voodoo->read_time = pci_nonburst_time + pci_burst_time; diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 716e684..ba11ce5 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -38,8 +38,8 @@ typedef struct voodoo_x86_data_t //static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; -static int last_block[2] = {0, 0}; -static int next_block_to_write[2] = {0, 0}; +static int last_block[4] = {0, 0}; +static int next_block_to_write[4] = {0, 0}; #define addbyte(val) \ do { \ @@ -3346,7 +3346,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, for (c = 0; c < 8; c++) { - data = &voodoo_x86_data[odd_even + c*2]; //&voodoo_x86_data[odd_even][b]; + data = &voodoo_x86_data[odd_even + c*4]; //&voodoo_x86_data[odd_even][b]; if (state->xdir == data->xdir && params->alphaMode == data->alphaMode && @@ -3366,7 +3366,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, b = (b + 1) & 7; } voodoo_recomp++; - data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*2]; + data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*4]; // code_block = data->code_block; voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3392,9 +3392,9 @@ void voodoo_codegen_init(voodoo_t *voodoo) int c; #if WIN64 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); + voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); #endif for (c = 0; c < 256; c++) @@ -3424,7 +3424,7 @@ void voodoo_codegen_close(voodoo_t *voodoo) #if WIN64 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); + munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); #endif } diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 5867d85..d49c6ed 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -36,8 +36,8 @@ typedef struct voodoo_x86_data_t uint32_t trexInit1; } voodoo_x86_data_t; -static int last_block[2] = {0, 0}; -static int next_block_to_write[2] = {0, 0}; +static int last_block[4] = {0, 0}; +static int next_block_to_write[4] = {0, 0}; #define addbyte(val) \ do { \ @@ -3286,7 +3286,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, for (c = 0; c < 8; c++) { - data = &codegen_data[odd_even + b*2]; + data = &codegen_data[odd_even + b*4]; if (state->xdir == data->xdir && params->alphaMode == data->alphaMode && @@ -3306,7 +3306,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, b = (b + 1) & 7; } voodoo_recomp++; - data = &codegen_data[odd_even + next_block_to_write[odd_even]*2]; + data = &codegen_data[odd_even + next_block_to_write[odd_even]*4]; // code_block = data->code_block; voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3338,9 +3338,9 @@ void voodoo_codegen_init(voodoo_t *voodoo) #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); + voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); #endif for (c = 0; c < 256; c++) @@ -3370,6 +3370,6 @@ void voodoo_codegen_close(voodoo_t *voodoo) #if defined WIN32 || defined _WIN32 || defined _WIN32 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); + munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); #endif } diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index da64d6e..2bab154 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -75,12 +75,9 @@ enum #define PARAM_MASK (PARAM_SIZE - 1) #define PARAM_ENTRY_SIZE (1 << 31) -#define PARAM_ENTRIES_1 (voodoo->params_write_idx - voodoo->params_read_idx[0]) -#define PARAM_ENTRIES_2 (voodoo->params_write_idx - voodoo->params_read_idx[1]) -#define PARAM_FULL_1 ((voodoo->params_write_idx - voodoo->params_read_idx[0]) >= PARAM_SIZE) -#define PARAM_FULL_2 ((voodoo->params_write_idx - voodoo->params_read_idx[1]) >= PARAM_SIZE) -#define PARAM_EMPTY_1 (voodoo->params_read_idx[0] == voodoo->params_write_idx) -#define PARAM_EMPTY_2 (voodoo->params_read_idx[1] == voodoo->params_write_idx) +#define PARAM_ENTRIES(x) (voodoo->params_write_idx - voodoo->params_read_idx[x]) +#define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE) +#define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx) typedef struct { @@ -164,7 +161,7 @@ typedef struct texture_t { uint32_t base; uint32_t tLOD; - volatile int refcount, refcount_r[2]; + volatile int refcount, refcount_r[4]; int is16; uint32_t palette_checksum; uint32_t addr_start[4], addr_end[4]; @@ -258,21 +255,21 @@ typedef struct voodoo_t int ncc_dirty[2]; thread_t *fifo_thread; - thread_t *render_thread[2]; + thread_t *render_thread[4]; event_t *wake_fifo_thread; event_t *wake_main_thread; event_t *fifo_not_full_event; - event_t *render_not_full_event[2]; - event_t *wake_render_thread[2]; + event_t *render_not_full_event[4]; + event_t *wake_render_thread[4]; int voodoo_busy; - int render_voodoo_busy[2]; + int render_voodoo_busy[4]; int render_threads; int odd_even_mask; - int pixel_count[2], texel_count[2], tri_count, frame_count; - int pixel_count_old[2], texel_count_old[2]; + int pixel_count[4], texel_count[4], tri_count, frame_count; + int pixel_count_old[4], texel_count_old[4]; int wr_count, rd_count, tex_count; int retrace_count; @@ -296,7 +293,7 @@ typedef struct voodoo_t volatile int cmd_read, cmd_written, cmd_written_fifo; voodoo_params_t params_buffer[PARAM_SIZE]; - volatile int params_read_idx[2], params_write_idx; + volatile int params_read_idx[4], params_write_idx; uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; int cmdfifo_rp; @@ -466,7 +463,7 @@ typedef struct voodoo_t int palette_dirty[2]; uint64_t time; - int render_time[2]; + int render_time[4]; int use_recompiler; void *codegen_data; diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index b2b3e89..a2125cb 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -1562,7 +1562,7 @@ static void render_thread(void *param, int odd_even) thread_reset_event(voodoo->wake_render_thread[odd_even]); voodoo->render_voodoo_busy[odd_even] = 1; - while (!(odd_even ? PARAM_EMPTY_2 : PARAM_EMPTY_1)) + while (!PARAM_EMPTY(odd_even)) { uint64_t start_time = timer_read(); uint64_t end_time; @@ -1572,7 +1572,7 @@ static void render_thread(void *param, int odd_even) voodoo->params_read_idx[odd_even]++; - if ((odd_even ? PARAM_ENTRIES_2 : PARAM_ENTRIES_1) > (PARAM_SIZE - 10)) + if (PARAM_ENTRIES(odd_even) > (PARAM_SIZE - 10)) thread_set_event(voodoo->render_not_full_event[odd_even]); end_time = timer_read(); @@ -1591,24 +1591,38 @@ void voodoo_render_thread_2(void *param) { render_thread(param, 1); } +void voodoo_render_thread_3(void *param) +{ + render_thread(param, 2); +} +void voodoo_render_thread_4(void *param) +{ + render_thread(param, 3); +} void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) { voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; - while (PARAM_FULL_1 || (voodoo->render_threads == 2 && PARAM_FULL_2)) + while (PARAM_FULL(0) || (voodoo->render_threads >= 2 && PARAM_FULL(1)) || + (voodoo->render_threads == 4 && (PARAM_FULL(2) || PARAM_FULL(3)))) { thread_reset_event(voodoo->render_not_full_event[0]); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) thread_reset_event(voodoo->render_not_full_event[1]); - if (PARAM_FULL_1) + if (voodoo->render_threads == 4) { + thread_reset_event(voodoo->render_not_full_event[2]); + thread_reset_event(voodoo->render_not_full_event[3]); + } + if (PARAM_FULL(0)) thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ - } - if (voodoo->render_threads == 2 && PARAM_FULL_2) - { + if (voodoo->render_threads >= 2 && PARAM_FULL(1)) thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ - } + if (voodoo->render_threads == 4 && PARAM_FULL(2)) + thread_wait_event(voodoo->render_not_full_event[2], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads == 4 && PARAM_FULL(3)) + thread_wait_event(voodoo->render_not_full_event[3], -1); /*Wait for room in ringbuffer*/ } voodoo_use_texture(voodoo, params, 0); @@ -1619,6 +1633,7 @@ void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) voodoo->params_write_idx++; - if (PARAM_ENTRIES_1 < 4 || (voodoo->render_threads == 2 && PARAM_ENTRIES_2 < 4)) + if (PARAM_ENTRIES(0) < 4 || (voodoo->render_threads >= 2 && PARAM_ENTRIES(1) < 4) || + (voodoo->render_threads == 4 && (PARAM_ENTRIES(2) < 4 || PARAM_ENTRIES(3) < 4))) voodoo_wake_render_thread(voodoo); } diff --git a/src/vid_voodoo_render.h b/src/vid_voodoo_render.h index ec8a551..9ba73dc 100644 --- a/src/vid_voodoo_render.h +++ b/src/vid_voodoo_render.h @@ -299,6 +299,8 @@ void voodoo_codegen_close(voodoo_t *voodoo); void voodoo_render_thread_1(void *param); void voodoo_render_thread_2(void *param); +void voodoo_render_thread_3(void *param); +void voodoo_render_thread_4(void *param); void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params); extern int voodoo_recomp; @@ -307,18 +309,30 @@ extern int tris; static inline void voodoo_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) + if (voodoo->render_threads >= 2) thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ + if (voodoo->render_threads == 4) + { + thread_set_event(voodoo->wake_render_thread[2]); /*Wake up render thread if moving from idle*/ + thread_set_event(voodoo->wake_render_thread[3]); /*Wake up render thread if moving from idle*/ + } } static inline void voodoo_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])) + while (!PARAM_EMPTY(0) || (voodoo->render_threads >= 2 && !PARAM_EMPTY(1)) || + (voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || !PARAM_EMPTY(3))) || + voodoo->render_voodoo_busy[0] || (voodoo->render_threads >= 2 && voodoo->render_voodoo_busy[1]) || + (voodoo->render_threads == 4 && (voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3]))) { voodoo_wake_render_thread(voodoo); - if (!PARAM_EMPTY_1 || voodoo->render_voodoo_busy[0]) + if (!PARAM_EMPTY(0) || voodoo->render_voodoo_busy[0]) thread_wait_event(voodoo->render_not_full_event[0], 1); - if (voodoo->render_threads == 2 && (!PARAM_EMPTY_2 || voodoo->render_voodoo_busy[1])) + if (voodoo->render_threads >= 2 && (!PARAM_EMPTY(1) || voodoo->render_voodoo_busy[1])) thread_wait_event(voodoo->render_not_full_event[1], 1); + if (voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || voodoo->render_voodoo_busy[2])) + thread_wait_event(voodoo->render_not_full_event[2], 1); + if (voodoo->render_threads == 4 && (!PARAM_EMPTY(3) || voodoo->render_voodoo_busy[3])) + thread_wait_event(voodoo->render_not_full_event[3], 1); } } From 2415d8ad504610dd3817987176433e79b6719b05 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 5 Oct 2020 19:35:15 +0100 Subject: [PATCH 0914/1050] Mask Banshee desktop start address correctly. --- src/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index a18f412..a65202c 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -627,7 +627,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Video_vidDesktopStartAddr: - banshee->vidDesktopStartAddr = val; + banshee->vidDesktopStartAddr = val & 0xffffff; // pclog("vidDesktopStartAddr=%08x\n", val); svga->fullchange = changeframecount; svga_recalctimings(svga); From 6df66c59fbdd1d01fc33acf6571226f16b50dcf2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 8 Oct 2020 17:56:28 +0100 Subject: [PATCH 0915/1050] Add Voodoo 3 emulation. --- src/ibm.h | 2 + src/vid_voodoo.c | 4 +- src/vid_voodoo_banshee.c | 91 +++++++++++++++++++++++++++++++++++----- src/vid_voodoo_banshee.h | 2 + src/vid_voodoo_common.h | 3 +- src/vid_voodoo_fb.c | 8 ++-- src/vid_voodoo_fifo.c | 17 +++++--- src/vid_voodoo_reg.c | 30 ++++++------- src/vid_voodoo_texture.c | 11 +++-- src/video.c | 2 + 10 files changed, 128 insertions(+), 42 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 5365a29..90f24cb 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -323,6 +323,8 @@ enum GFX_TVGA9000B, /*Trident TVGA9000B*/ GFX_BANSHEE, /*Voodoo Banshee - reference PCI board with SGRAM*/ GFX_CL_BANSHEE, /*Creative Labs Voodoo Blaster Banshee PCI - with SDRAM*/ + GFX_VOODOO_3_2000, /*Voodoo 3 2000*/ + GFX_VOODOO_3_3000, /*Voodoo 3 3000*/ GFX_MAX }; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 414948f..6245106 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -1095,7 +1095,7 @@ void *voodoo_2d3d_card_init(int type) voodoo->use_recompiler = device_get_config_int("recompiler"); #endif voodoo->type = type; - voodoo->dual_tmus = 0; + voodoo->dual_tmus = (type == VOODOO_3) ? 1 : 0; /*generate filter lookup tables*/ voodoo_generate_filter_v2(voodoo); @@ -1304,7 +1304,7 @@ void voodoo_card_close(voodoo_t *voodoo) #ifndef NO_CODEGEN voodoo_codegen_close(voodoo); #endif - if (voodoo->type != VOODOO_BANSHEE && voodoo->fb_mem) + if (voodoo->type < VOODOO_BANSHEE && voodoo->fb_mem) { free(voodoo->fb_mem); if (voodoo->dual_tmus) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index a65202c..816ce60 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -20,6 +20,13 @@ #undef CLAMP #endif +enum +{ + TYPE_BANSHEE = 0, + TYPE_V3_2000, + TYPE_V3_3000 +}; + typedef struct banshee_t { svga_t svga; @@ -70,6 +77,8 @@ typedef struct banshee_t uint32_t desktop_addr; int desktop_y; uint32_t desktop_stride_tiled; + + int type; } banshee_t; enum @@ -734,6 +743,9 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p) case Init_status: ret = banshee_status(banshee); // pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; + case Init_pciInit0: + ret = banshee->pciInit0; break; case Init_lfbMemoryConfig: ret = banshee->lfbMemoryConfig; @@ -1818,13 +1830,15 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) // svga_t *svga = &banshee->svga; uint8_t ret = 0; + if (func) + return 0xff; pclog("Banshee PCI read %08X ", addr); switch (addr) { case 0x00: ret = 0x1a; break; /*3DFX*/ case 0x01: ret = 0x12; break; - case 0x02: ret = 0x03; break; + case 0x02: ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; break; case 0x03: ret = 0x00; break; case 0x04: ret = banshee->pci_regs[0x04] & 0x27; break; @@ -1854,6 +1868,12 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x1a: ret = 0x00; break; case 0x1b: ret = 0x00; break; + /*Undocumented, but Voodoo 3 BIOS checks this*/ + case 0x2c: ret = 0x1a; break; + case 0x2d: ret = 0x12; break; + case 0x2e: ret = (banshee->type == TYPE_V3_3000) ? 0x3a : 0x30; break; + case 0x2f: ret = 0x00; break; + case 0x30: ret = banshee->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; case 0x32: ret = banshee->pci_regs[0x32]; break; @@ -1880,6 +1900,8 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) banshee_t *banshee = (banshee_t *)p; // svga_t *svga = &banshee->svga; + if (func) + return; pclog("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch (addr) { @@ -1941,7 +1963,7 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) { uint32_t addr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24); pclog("Banshee bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x8000); + mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x10000); mem_mapping_enable(&banshee->bios_rom.mapping); } else @@ -2066,14 +2088,17 @@ static device_config_t banshee_sdram_config[] = } }; -static void *banshee_init_common(char *fn, int has_sgram) +static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_type) { int mem_size; banshee_t *banshee = malloc(sizeof(banshee_t)); memset(banshee, 0, sizeof(banshee_t)); - - rom_init(&banshee->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + banshee->type = type; + + rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&banshee->bios_rom.mapping); + if (has_sgram) mem_size = device_get_config_int("memory"); else @@ -2125,10 +2150,10 @@ static void *banshee_init_common(char *fn, int has_sgram) if (!has_sgram) banshee->dramInit1 = 1 << 30; /*SDRAM*/ banshee->svga.decode_mask = 0x1ffffff; - + pci_add(banshee_pci_read, banshee_pci_write, banshee); - banshee->voodoo = voodoo_2d3d_card_init(VOODOO_BANSHEE); + banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); banshee->voodoo->p = banshee; banshee->voodoo->vram = banshee->svga.vram; banshee->voodoo->changedvram = banshee->svga.changedvram; @@ -2136,18 +2161,28 @@ static void *banshee_init_common(char *fn, int has_sgram) banshee->voodoo->fb_mask = banshee->svga.vram_mask; banshee->voodoo->tex_mem[0] = banshee->svga.vram; banshee->voodoo->tex_mem_w[0] = (uint16_t *)banshee->svga.vram; + banshee->voodoo->tex_mem[1] = banshee->svga.vram; + banshee->voodoo->tex_mem_w[1] = (uint16_t *)banshee->svga.vram; banshee->voodoo->texture_mask = banshee->svga.vram_mask; return banshee; } -static void *banshee_init(FILE *f, int has_sgram) +static void *banshee_init() { - return banshee_init_common("pci_sg.rom", 1); + return banshee_init_common("pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE); } -static void *creative_banshee_init(FILE *f, int has_sgram) +static void *creative_banshee_init() { - return banshee_init_common("blasterpci.rom", 0); + return banshee_init_common("blasterpci.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE); +} +static void *v3_2000_init() +{ + return banshee_init_common("voodoo3_2000/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3); +} +static void *v3_3000_init() +{ + return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3); } static int banshee_available() @@ -2158,6 +2193,14 @@ static int creative_banshee_available() { return rom_present("blasterpci.rom"); } +static int v3_2000_available() +{ + return rom_present("voodoo3_2000/2k11sd.rom"); +} +static int v3_3000_available() +{ + return rom_present("voodoo3_3000/3k12sd.rom"); +} static void banshee_close(void *p) { @@ -2281,3 +2324,29 @@ device_t creative_voodoo_banshee_device = banshee_add_status_info, banshee_sdram_config }; + +device_t voodoo_3_2000_device = +{ + "Voodoo 3 2000 PCI", + 0, + v3_2000_init, + banshee_close, + v3_2000_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_sdram_config +}; + +device_t voodoo_3_3000_device = +{ + "Voodoo 3 3000 PCI", + 0, + v3_3000_init, + banshee_close, + v3_3000_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_sdram_config +}; diff --git a/src/vid_voodoo_banshee.h b/src/vid_voodoo_banshee.h index 6e72747..ddd7e3f 100644 --- a/src/vid_voodoo_banshee.h +++ b/src/vid_voodoo_banshee.h @@ -1,4 +1,6 @@ extern device_t voodoo_banshee_device; extern device_t creative_voodoo_banshee_device; +extern device_t voodoo_3_2000_device; +extern device_t voodoo_3_3000_device; void banshee_set_overlay_addr(void *p, uint32_t addr); diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 2bab154..c72d079 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -22,7 +22,8 @@ enum VOODOO_1 = 0, VOODOO_SB50, VOODOO_2, - VOODOO_BANSHEE + VOODOO_BANSHEE, + VOODOO_3 }; typedef union int_float diff --git a/src/vid_voodoo_fb.c b/src/vid_voodoo_fb.c index 52bec1f..b3d3918 100644 --- a/src/vid_voodoo_fb.c +++ b/src/vid_voodoo_fb.c @@ -18,7 +18,7 @@ uint16_t voodoo_fb_readw(uint32_t addr, void *p) uint32_t read_addr; uint16_t temp; - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { x = addr & 0xffe; y = (addr >> 12) & 0x3ff; @@ -61,7 +61,7 @@ uint32_t voodoo_fb_readl(uint32_t addr, void *p) uint32_t read_addr; uint32_t temp; - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { x = addr & 0xffe; y = (addr >> 12) & 0x3ff; @@ -175,7 +175,7 @@ void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); } - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { x = addr & 0xffe; y = (addr >> 12) & 0x3ff; @@ -336,7 +336,7 @@ void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); } - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { x = addr & 0xffe; y = (addr >> 12) & 0x3ff; diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index c5ca5a9..35f63bf 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -277,7 +277,7 @@ void voodoo_fifo_thread(void *param) while (num--) { uint32_t val = cmdfifo_get(voodoo); - if ((addr & (1 << 13)) && voodoo->type == VOODOO_BANSHEE) + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { // if (voodoo->type != VOODOO_BANSHEE) // fatal("CMDFIFO1: Not Banshee\n"); @@ -290,7 +290,7 @@ void voodoo_fifo_thread(void *param) (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) voodoo->cmd_written_fifo++; - if (voodoo->type == VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) voodoo->cmd_written_fifo++; voodoo_reg_writel(addr, val, voodoo); } @@ -301,7 +301,7 @@ void voodoo_fifo_thread(void *param) break; case 2: - if (voodoo->type != VOODOO_BANSHEE) + if (voodoo->type < VOODOO_BANSHEE) fatal("CMDFIFO2: Not Banshee\n"); mask = (header >> 3); addr = 8; @@ -393,9 +393,9 @@ void voodoo_fifo_thread(void *param) { uint32_t val = cmdfifo_get(voodoo); - if ((addr & (1 << 13)) && voodoo->type == VOODOO_BANSHEE) + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { - if (voodoo->type != VOODOO_BANSHEE) + if (voodoo->type < VOODOO_BANSHEE) fatal("CMDFIFO1: Not Banshee\n"); // pclog("CMDFIFO1: write %08x %08x\n", addr, val); voodoo_2d_reg_writel(voodoo, addr, val); @@ -406,7 +406,7 @@ void voodoo_fifo_thread(void *param) (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) voodoo->cmd_written_fifo++; - if (voodoo->type == VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) voodoo->cmd_written_fifo++; voodoo_reg_writel(addr, val, voodoo); } @@ -435,6 +435,11 @@ void voodoo_fifo_thread(void *param) // pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); } + if (voodoo->texture_present[1][(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, 1); + } while (num--) { uint32_t val = cmdfifo_get(voodoo); diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 1af1131..965c6f6 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -48,7 +48,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) switch (addr) { case SST_swapbufferCMD: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { // pclog("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); @@ -537,14 +537,14 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_clipLeftRight1: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { voodoo->params.clipRight1 = val & 0xfff; voodoo->params.clipLeft1 = (val >> 16) & 0xfff; } break; case SST_clipTopBottom1: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { voodoo->params.clipHighY1 = val & 0xfff; voodoo->params.clipLowY1 = (val >> 16) & 0xfff; @@ -552,7 +552,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_colBufferAddr: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { voodoo->params.draw_offset = val & 0xfffff0; voodoo->fb_write_offset = voodoo->params.draw_offset; @@ -560,7 +560,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } break; case SST_colBufferStride: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { voodoo->col_tiled = val & (1 << 15); if (voodoo->col_tiled) @@ -576,14 +576,14 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } break; case SST_auxBufferAddr: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { voodoo->params.aux_offset = val & 0xfffff0; // pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); } break; case SST_auxBufferStride: - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) { voodoo->aux_tiled = val & (1 << 15); if (voodoo->aux_tiled) @@ -877,7 +877,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_texBaseAddr: if (chip & CHIP_TREX0) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr[0] = val & 0xfffff0; else voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; @@ -886,7 +886,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } if (chip & CHIP_TREX1) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr[1] = val & 0xfffff0; else voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; @@ -896,7 +896,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_texBaseAddr1: if (chip & CHIP_TREX0) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr1[0] = val & 0xfffff0; else voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; @@ -904,7 +904,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } if (chip & CHIP_TREX1) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr1[1] = val & 0xfffff0; else voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; @@ -914,7 +914,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_texBaseAddr2: if (chip & CHIP_TREX0) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr2[0] = val & 0xfffff0; else voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; @@ -922,7 +922,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } if (chip & CHIP_TREX1) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr2[1] = val & 0xfffff0; else voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; @@ -932,7 +932,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_texBaseAddr38: if (chip & CHIP_TREX0) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr38[0] = val & 0xfffff0; else voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; @@ -940,7 +940,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) } if (chip & CHIP_TREX1) { - if (voodoo->type == VOODOO_BANSHEE) + if (voodoo->type >= VOODOO_BANSHEE) voodoo->params.texBaseAddr38[1] = val & 0xfffff0; else voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; diff --git a/src/vid_voodoo_texture.c b/src/vid_voodoo_texture.c index 0396a8a..f52a314 100644 --- a/src/vid_voodoo_texture.c +++ b/src/vid_voodoo_texture.c @@ -531,9 +531,9 @@ void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) if (tmu && !voodoo->dual_tmus) return; - if (voodoo->type != VOODOO_BANSHEE) + if (voodoo->type < VOODOO_BANSHEE) { - if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type == VOODOO_BANSHEE) + if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type >= VOODOO_BANSHEE) { lod = (addr >> 16) & 0xf; t = (addr >> 8) & 0xff; @@ -547,7 +547,7 @@ void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) s = (addr >> 1) & 0xfe; else { - if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type == VOODOO_BANSHEE) + if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type >= VOODOO_BANSHEE) s = addr & 0xfc; else s = (addr >> 1) & 0xfc; @@ -571,5 +571,10 @@ void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) // pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); } + if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu^1][(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^1); + } *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; } diff --git a/src/video.c b/src/video.c index a8c7dbb..b58bc1d 100644 --- a/src/video.c +++ b/src/video.c @@ -83,6 +83,8 @@ typedef struct static VIDEO_CARD video_cards[] = { + {"3DFX Voodoo 3 2000", "v3_2000", &voodoo_3_2000_device, GFX_VOODOO_3_2000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, + {"3DFX Voodoo 3 3000", "v3_3000", &voodoo_3_3000_device, GFX_VOODOO_3_3000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, From 2b43125f79c470b6c801d6b3089679bfdd9bdf0d Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 8 Oct 2020 17:58:11 +0100 Subject: [PATCH 0916/1050] Rename Banshee reference card to match Voodoo 3s. --- src/video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video.c b/src/video.c index b58bc1d..7c53f11 100644 --- a/src/video.c +++ b/src/video.c @@ -83,6 +83,7 @@ typedef struct static VIDEO_CARD video_cards[] = { + {"3DFX Voodoo Banshee (reference)", "banshee", &voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"3DFX Voodoo 3 2000", "v3_2000", &voodoo_3_2000_device, GFX_VOODOO_3_2000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"3DFX Voodoo 3 3000", "v3_3000", &voodoo_3_3000_device, GFX_VOODOO_3_3000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, @@ -131,7 +132,6 @@ static VIDEO_CARD video_cards[] = {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"Voodoo Banshee (reference)", "banshee", &voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"", "", NULL, 0} }; From 114cdd7a15058703490db1d70dadd214a16b6de3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 8 Oct 2020 21:06:32 +0100 Subject: [PATCH 0917/1050] Add VIA Cyrix III CPUs. Note that this is currently limited to 500 MHz, as Windows 98 won't boot on anything any faster than this. This is most likely a limitation of the current timer subsystem. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/codegen.h | 1 + src/codegen_timing_cyrixiii.c | 679 +++++++++++++++++++++++++++++ src/cpu.c | 109 +++++ src/cpu.h | 3 + src/cpu_tables.c | 14 + src/model.c | 2 +- 9 files changed, 810 insertions(+), 4 deletions(-) create mode 100644 src/codegen_timing_cyrixiii.c diff --git a/src/Makefile.am b/src/Makefile.am index 1732e68..83236d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,7 +30,7 @@ codegen_ops_branch.c codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c codegen_ codegen_ops_fpu_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c codegen_ops_mmx_loadstore.c \ codegen_ops_mmx_logic.c codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_helpers.c codegen_ops_jump.c \ codegen_ops_logic.c codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c \ -codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_k6.c codegen_timing_p6.c codegen_timing_pentium.c \ +codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_cyrixiii.c codegen_timing_k6.c codegen_timing_p6.c codegen_timing_pentium.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c config.c cpu.c cpu_tables.c cs8230.c dells200.c device.c disc.c \ disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c f82c710_upc.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c hdd_esdi.c \ hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c i440fx.c i440bx.c ide.c ide_atapi.c ide_sff8038i.c intel.c intel_flash.c io.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index d7ae669..4c13f55 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -15,7 +15,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_p6.o codegen_timing_pentium.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_cyrixiii.o codegen_timing_k6.o codegen_timing_p6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f82c710_upc.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o i440fx.o i440bx.o ide.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 7a4bb46..e58e406 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -15,7 +15,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 codegen_ops_logic.o codegen_ops_misc.o codegen_ops_mmx_arith.o codegen_ops_mmx_cmp.o \ codegen_ops_mmx_loadstore.o codegen_ops_mmx_logic.o codegen_ops_mmx_pack.o codegen_ops_mmx_shift.o \ codegen_ops_mov.o codegen_ops_shift.o codegen_ops_stack.o codegen_reg.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_common.o codegen_timing_k6.o codegen_timing_p6.o codegen_timing_pentium.o \ + codegen_timing_686.o codegen_timing_common.o codegen_timing_cyrixiii.o codegen_timing_k6.o codegen_timing_p6.o codegen_timing_pentium.o \ codegen_timing_winchip.o codegen_timing_winchip2.o compaq.o config.o cpu.o cpu_tables.o cs8230.o device.o \ dells200.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o esdi_at.o f82c710_upc.o fdc.o fdc37c665.o fdc37c93x.o fdd.o \ fdi2raw.o gameport.o hdd.o hdd_esdi.o hdd_file.o headland.o i430hx.o i430lx.o i430fx.o i430vx.o i440fx.o i440bx.o ide.o \ diff --git a/src/codegen.h b/src/codegen.h index 0ca3df5..83f37ae 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -374,6 +374,7 @@ extern codegen_timing_t codegen_timing_686; extern codegen_timing_t codegen_timing_486; extern codegen_timing_t codegen_timing_winchip; extern codegen_timing_t codegen_timing_winchip2; +extern codegen_timing_t codegen_timing_cyrixiii; extern codegen_timing_t codegen_timing_k6; extern codegen_timing_t codegen_timing_p6; diff --git a/src/codegen_timing_cyrixiii.c b/src/codegen_timing_cyrixiii.c new file mode 100644 index 0000000..c89defc --- /dev/null +++ b/src/codegen_timing_cyrixiii.c @@ -0,0 +1,679 @@ +/*Since VIA didn't document cycle timings in the Cyrix III/C3 datasheets, and + I don't currently own either chip to test against, most of the timing here is + a guess. This code makes the current (probably wrong) assumptions, based on the + few details in the Cyrix III datasheet : + - Most common integer instructions are 1 cycle, including register-memory and + memory-register versions + - Basic FPU instructions are 2 cycles. The datasheet claims "a non-dependent + add or multiply can start every two clocks"; it's not clear if this is referring + to CPU or FPU clocks, since the FPU runs at 1/2 CPU speed on these chips. + - MMX instructions are 1 cycle + - No instruction pairing of any kind (unlike WinChip 2) + - Prefixes other than 0x0f cost 1 cycle each + - AGI stalls cost 1 cycle, except for implicit references to ESP*/ +#include "ibm.h" +#include "cpu.h" +#include "x86.h" +#include "x86_ops.h" +#include "x87.h" +#include "mem.h" +#include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" + +/*Instruction has different execution time for 16 and 32 bit data. Does not pair */ +#define CYCLES_HAS_MULTI (1 << 31) + +#define CYCLES_FPU (1 << 30) + +#define CYCLES_IS_MMX_MUL (1 << 29) +#define CYCLES_IS_MMX_SHIFT (1 << 28) +#define CYCLES_IS_MMX_ANY (1 << 27) +#define CYCLES_IS_3DNOW (1 << 26) + +#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) +#define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c) +#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) +#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) + +#define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) + +#define GET_CYCLES(c) (c & ~(CYCLES_HAS_MULTI | CYCLES_FPU | CYCLES_IS_MMX)) + +#define CYCLES(c) c +#define CYCLES2(c16, c32) (CYCLES_HAS_MULTI | c16 | (c32 << 8)) + +/*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) (comp_time) | (i_overlap << 8) | (f_overlap << 16) | CYCLES_FPU + +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 8) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 16) & 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 >> 8) & 0xff) + +#define INVALID 0 + +static uint32_t opcode_timings[256] = +{ +/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, +/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), +/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), +/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + +/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(17,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), +/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(5), CYCLES(6), +/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), +/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), +/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*c0*/ CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), +/*d0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), +/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID +}; + +static uint32_t opcode_timings_mod3[256] = +{ +/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, +/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), +/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), +/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + +/*40*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*50*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*60*/ CYCLES(11), CYCLES(9), CYCLES(7), CYCLES(9), CYCLES(4), CYCLES(4), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES2(14,25), CYCLES(1), CYCLES2(17,20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), +/*70*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(2), CYCLES(1), +/*90*/ CYCLES(1), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(0), CYCLES(4), CYCLES(4), CYCLES(5), CYCLES(2), CYCLES(3), +/*a0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(7), CYCLES(7), CYCLES(8), CYCLES(8), CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), +/*b0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), + +/*c0*/ CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), +/*d0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*e0*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(5), CYCLES(14), CYCLES(14), CYCLES(16), CYCLES(16), CYCLES(3), CYCLES(3), CYCLES(17), CYCLES(3), CYCLES(14), CYCLES(14), CYCLES(14), CYCLES(14), +/*f0*/ CYCLES(4), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(4), CYCLES(2), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, +}; + +static uint32_t opcode_timings_0f[256] = +{ +/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), +/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*60*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), +/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), +/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30), +/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + +/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), +/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), +/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(2), INVALID, +}; +static uint32_t opcode_timings_0f_mod3[256] = +{ +/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), +/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*50*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +/*60*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), +/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), + +/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*90*/ CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3), +/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18,30), +/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + +/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), +/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), +/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), +/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, +}; + +static uint32_t opcode_timings_shift[8] = +{ + CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) +}; +static uint32_t opcode_timings_shift_mod3[8] = +{ + CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) +}; + +static uint32_t opcode_timings_f6[8] = +{ + CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) +}; +static uint32_t opcode_timings_f6_mod3[8] = +{ + CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) +}; +static uint32_t opcode_timings_f7[8] = +{ + CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) +}; +static uint32_t opcode_timings_f7_mod3[8] = +{ + CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) +}; +static uint32_t opcode_timings_ff[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID +}; +static uint32_t opcode_timings_ff_mod3[8] = +{ + CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID +}; + +static uint32_t opcode_timings_d8[8] = +{ +/* FADDs FMULs FCOMs FCOMPs*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FSUBs FSUBRs FDIVs FDIVRs*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; +static uint32_t opcode_timings_d8_mod3[8] = +{ +/* FADD FMUL FCOM FCOMP*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FSUB FSUBR FDIV FDIVR*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; + +static uint32_t opcode_timings_d9[8] = +{ +/* FLDs FSTs FSTPs*/ + FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FLDENV FLDCW FSTENV FSTCW*/ + FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0) +}; +static uint32_t opcode_timings_d9_mod3[64] = +{ + /*FLD*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), + /*FXCH*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), + /*FNOP*/ + FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* opFCHS opFABS*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), INVALID, INVALID, +/* opFTST opFXAM*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(21,4,0), INVALID, INVALID, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), +/* opFLDEG2 opFLDLN2 opFLDZ*/ + FPU_CYCLES(5,2,2), FPU_CYCLES(5,2,2), FPU_CYCLES(2,0,0), INVALID, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + FPU_CYCLES(53,2,2), FPU_CYCLES(103,2,2),FPU_CYCLES(120,36,0),FPU_CYCLES(112,2,2), +/* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* opFPREM opFSQRT opFSINCOS*/ + FPU_CYCLES(64,2,2), INVALID, FPU_CYCLES(70,69,2),FPU_CYCLES(89,2,2), +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + FPU_CYCLES(9,0,0), FPU_CYCLES(20,5,0), FPU_CYCLES(65,2,2), FPU_CYCLES(65,2,2) +}; + +static uint32_t opcode_timings_da[8] = +{ +/* FIADDl FIMULl FICOMl FICOMPl*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) +}; +static uint32_t opcode_timings_da_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FCOMPP*/ + INVALID, FPU_CYCLES(2,0,0), INVALID, INVALID +}; + + +static uint32_t opcode_timings_db[8] = +{ +/* FLDil FSTil FSTPil*/ + FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), +/* FLDe FSTPe*/ + INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0) +}; +static uint32_t opcode_timings_db_mod3[64] = +{ + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/* opFNOP opFCLEX opFINIT*/ + INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(7,0,0), FPU_CYCLES(17,0,0), +/* opFNOP opFNOP*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +}; + +static uint32_t opcode_timings_dc[8] = +{ +/* FADDd FMULd FCOMd FCOMPd*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FSUBd FSUBRd FDIVd FDIVRd*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; +static uint32_t opcode_timings_dc_mod3[8] = +{ +/* opFADDr opFMULr*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2),INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2),FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; + +static uint32_t opcode_timings_dd[8] = +{ +/* FLDd FSTd FSTPd*/ + FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FRSTOR FSAVE FSTSW*/ + FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0) +}; +static uint32_t opcode_timings_dd_mod3[8] = +{ +/* FFFREE FST FSTP*/ + FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), +/* FUCOM FUCOMP*/ + FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),INVALID, INVALID +}; + +static uint32_t opcode_timings_de[8] = +{ +/* FIADDw FIMULw FICOMw FICOMPw*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) +}; +static uint32_t opcode_timings_de_mod3[8] = +{ +/* FADDP FMULP FCOMPP*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), INVALID, FPU_CYCLES(2,0,0), +/* FSUBP FSUBRP FDIVP FDIVRP*/ + FPU_CYCLES(4,2,2), FPU_CYCLES(4,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) +}; + +static uint32_t opcode_timings_df[8] = +{ +/* FILDiw FISTiw FISTPiw*/ + FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), +/* FILDiq FBSTP FISTPiq*/ + INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0) +}; +static uint32_t opcode_timings_df_mod3[8] = +{ + INVALID, INVALID, INVALID, INVALID, +/* FSTSW AX*/ + FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID +}; + +static uint32_t opcode_timings_8x[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; +static uint32_t opcode_timings_8x_mod3[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; +static uint32_t opcode_timings_81[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; +static uint32_t opcode_timings_81_mod3[8] = +{ + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) +}; + +static int timing_count; +static uint8_t last_prefix; +static uint32_t regmask_modified; +static int decode_delay, decode_delay_offset; +static int fpu_latency; +static int fpu_st_latency[8]; + + +static inline int COUNT(uint32_t c, int op_32) +{ + if (c & CYCLES_FPU) + return FPU_I_LATENCY(c); + if (c & CYCLES_HAS_MULTI) + { + if (op_32 & 0x100) + return (c >> 8) & 0xff; + return c & 0xff; + } + return GET_CYCLES(c); +} + +static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32) +{ + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); + + /*Instructions that use ESP implicitly (eg PUSH, POP, CALL etc) do not + cause AGIs with each other, but do with instructions that use it explicitly*/ + if ((addr_regmask & REGMASK_IMPL_ESP) && (regmask_modified & (1 << REG_ESP)) && !(regmask_modified & REGMASK_IMPL_ESP)) + addr_regmask |= (1 << REG_ESP); + + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; +} + +static int codegen_fpu_latencies(uint64_t deps, int reg) +{ + int latency = fpu_latency; + + if ((deps & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((deps & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((deps & 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 void codegen_instruction(uint32_t *timings, uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32, int exec_delay) +{ + int instr_cycles, latency = 0; + + if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[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); + instr_cycles += exec_delay; + 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 (deps[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 (deps[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] & CYCLES_FPU) + { + /* if (fpu_latency) + fatal("Bad latency FPU\n");*/ + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (deps[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 (deps[opcode] & FPU_WRITE_ST0) + { +/* if (fpu_st_latency[0]) + fatal("Bad latency ST0\n");*/ + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_ST1) + { +/* if (fpu_st_latency[1]) + fatal("Bad latency ST1\n");*/ + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (deps[opcode] & FPU_WRITE_STREG) + { + int reg = fetchdat & 7; + if (deps[opcode] & FPU_POP) + reg--; + if (reg >= 0 && + !(reg == 0 && (deps[opcode] & FPU_WRITE_ST0)) && + !(reg == 1 && (deps[opcode] & FPU_WRITE_ST1))) + { +/* if (fpu_st_latency[reg]) + fatal("Bad latency STREG %i %08x %i %016llx %02x\n",fpu_st_latency[reg], fetchdat, reg, timings[opcode], opcode);*/ + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); + } + } +} + +static void codegen_timing_cyrixiii_block_start() +{ + regmask_modified = 0; + decode_delay = decode_delay_offset = 0; +} + +static void codegen_timing_cyrixiii_start() +{ + timing_count = 0; + last_prefix = 0; +} + +static void codegen_timing_cyrixiii_prefix(uint8_t prefix, uint32_t fetchdat) +{ + if (prefix == 0x0f) + { + /*0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + /*On C3 all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; +} + +static void codegen_timing_cyrixiii_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +{ + uint32_t *timings; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int bit8 = !(opcode & 1); + int agi_stall = 0; + + switch (last_prefix) + { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; +// pclog("timings 0f\n"); + break; + + case 0xd8: + timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; +// pclog("timings d8\n"); + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings d9\n"); + break; + case 0xda: + timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; +// pclog("timings da\n"); + break; + case 0xdb: + timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; +// pclog("timings db\n"); + break; + case 0xdc: + timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; +// pclog("timings dc\n"); + break; + case 0xdd: + timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; +// pclog("timings dd\n"); + break; + case 0xde: + timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; +// pclog("timings de\n"); + break; + case 0xdf: + timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; +// pclog("timings df\n"); + break; + + default: + switch (opcode) + { + case 0x80: case 0x82: case 0x83: + timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3; + opcode = (fetchdat >> 3) & 7; +// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); + break; + case 0x81: + timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; + 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; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; +// pclog("timings c0\n"); + break; + + case 0xf6: + timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f6\n"); + break; + case 0xf7: + timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; +// pclog("timings f7\n"); + break; + case 0xff: + timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; +// pclog("timings ff\n"); + break; + + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; +// pclog("timings normal\n"); + break; + } + } + + if (check_agi(deps, opcode, fetchdat, op_32)) + agi_stall = 1; + codegen_instruction(timings, deps, opcode, fetchdat, decode_delay_offset, op_32, agi_stall); + decode_delay_offset = 0; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); +} + +static void codegen_timing_cyrixiii_block_end() +{ +} + +int codegen_timing_cyrixiii_jump_cycles() +{ + return 0; +} + +codegen_timing_t codegen_timing_cyrixiii = +{ + codegen_timing_cyrixiii_start, + codegen_timing_cyrixiii_prefix, + codegen_timing_cyrixiii_opcode, + codegen_timing_cyrixiii_block_start, + codegen_timing_cyrixiii_block_end, + codegen_timing_cyrixiii_jump_cycles +}; diff --git a/src/cpu.c b/src/cpu.c index 3335a3e..fb9a042 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1106,6 +1106,44 @@ void cpu_set() codegen_timing_set(&codegen_timing_p6); break; + case CPU_CYRIX_III: + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 1; /*register dest - memory src*/ + timing_mr = 1; /*memory dest - register src*/ + timing_mm = 1; + timing_rml = 1; /*register dest - memory src long*/ + timing_mrl = 1; /*memory dest - register src long*/ + timing_mml = 1; + timing_bt = 1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; + codegen_timing_set(&codegen_timing_cyrixiii); + break; + default: fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); } @@ -1684,6 +1722,75 @@ void cpu_CPUID() else EAX = EBX = ECX = EDX = 0; break; + + case CPU_CYRIX_III: + switch (EAX) + { + case 0: + EAX = 1; + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + break; + case 1: + EAX = models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; + + case 0x80000002: /*Processor name string*/ + if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670) + { + EAX = 0x20414956; /*VIA Samuel 2*/ + EBX = 0x756d6153; + ECX = 0x32206c65; + EDX = 0x00000000; + } + else + { + EAX = 0x20414956; /*VIA SamuelM*/ + EBX = 0x756d6153; + ECX = 0x004d6c65; + EDX = 0x00000000; + } + break; + + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x40040120; /*L1 data cache*/ + EDX = 0x40020120; /*L1 instruction cache*/ + break; + + case 0x80000006: /*L2 Cache information*/ + if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670) + ECX = 0x40040120; /*L2 cache*/ + else + ECX = 0; + EAX = EBX = EDX = 0; + break; + + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; } } @@ -1693,6 +1800,7 @@ void cpu_RDMSR() { case CPU_WINCHIP: case CPU_WINCHIP2: + case CPU_CYRIX_III: EAX = EDX = 0; switch (ECX) { @@ -1794,6 +1902,7 @@ void cpu_WRMSR() { case CPU_WINCHIP: case CPU_WINCHIP2: + case CPU_CYRIX_III: switch (ECX) { case 0x02: diff --git a/src/cpu.h b/src/cpu.h index dad9d2b..ca8f4da 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -45,11 +45,13 @@ extern int fpu_type; #define CPU_PENTIUM_2 29 #define CPU_CELERON 30 #define CPU_CELERON_A 31 +#define CPU_CYRIX_III 32 #define MANU_INTEL 0 #define MANU_AMD 1 #define MANU_CYRIX 2 #define MANU_IDT 3 +#define MANU_VIA 4 extern int timing_rr; extern int timing_mr, timing_mrl; @@ -123,6 +125,7 @@ extern CPU cpus_K6_S7[]; extern CPU cpus_K6_SS7[]; extern CPU cpus_PentiumPro[]; extern CPU cpus_Slot1_100MHz[]; +extern CPU cpus_VIA_100MHz[]; extern CPU cpus_pcjr[]; extern CPU cpus_europc[]; diff --git a/src/cpu_tables.c b/src/cpu_tables.c index ac6f7be..c0bd920 100644 --- a/src/cpu_tables.c +++ b/src/cpu_tables.c @@ -535,3 +535,17 @@ CPU cpus_Slot1_100MHz[] = {"Celeron 533", CPU_CELERON_A, fpus_builtin, 20, 533333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 68}, {"", -1, 0, 0, 0} }; + +CPU cpus_VIA_100MHz[] = +{ + /*VIA Cyrix III*/ + {"Cyrix III/500", CPU_CYRIX_III, fpus_builtin, 20, 500000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 64}, +/*Below are disabled as Windows 98 won't boot. This is most likely a limitation of the timer system*/ +/* {"Cyrix III/550", CPU_CYRIX_III, fpus_builtin, 20, 550000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 70}, + {"Cyrix III/600", CPU_CYRIX_III, fpus_builtin, 20, 600000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 76}, + {"Cyrix III/650", CPU_CYRIX_III, fpus_builtin, 20, 650000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 82}, + {"Cyrix III/700", CPU_CYRIX_III, fpus_builtin, 20, 700000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 88}, + {"C3/750", CPU_CYRIX_III, fpus_builtin, 20, 750000000, 3, 33333333, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 94}, + {"C3/800", CPU_CYRIX_III, fpus_builtin, 20, 800000000, 3, 33333333, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 100},*/ + {"", -1, 0, 0, 0} +}; diff --git a/src/model.c b/src/model.c index de53ef2..55e9177 100644 --- a/src/model.c +++ b/src/model.c @@ -243,7 +243,7 @@ MODEL models[] = {"[Socket 8] Intel VS440FX", ROM_VS440FX, "vs440fx", { {"Intel", cpus_PentiumPro}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 8, at_vs440fx_init, NULL}, - {"[Slot 1] Gigabyte GA-686BX", ROM_GA686BX, "ga686bx", { {"Intel", cpus_Slot1_100MHz}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 512, 8, at_ga686bx_init, NULL}, + {"[Slot 1] Gigabyte GA-686BX", ROM_GA686BX, "ga686bx", { {"Intel", cpus_Slot1_100MHz}, {"VIA", cpus_VIA_100MHz}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 512, 8, at_ga686bx_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0, 0} }; From 086287809b756114dc4135bfe1778e87cdd316b2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 9 Oct 2020 16:46:47 +0100 Subject: [PATCH 0918/1050] Mark Banshee/Voodoo 3 cards as PCI. --- src/vid_voodoo_banshee.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 816ce60..5f10cea 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -2302,7 +2302,7 @@ static void banshee_add_status_info(char *s, int max_len, void *p) device_t voodoo_banshee_device = { "Voodoo Banshee PCI (reference)", - 0, + DEVICE_PCI, banshee_init, banshee_close, banshee_available, @@ -2315,7 +2315,7 @@ device_t voodoo_banshee_device = device_t creative_voodoo_banshee_device = { "Creative Labs 3D Blaster Banshee PCI", - 0, + DEVICE_PCI, creative_banshee_init, banshee_close, creative_banshee_available, @@ -2328,7 +2328,7 @@ device_t creative_voodoo_banshee_device = device_t voodoo_3_2000_device = { "Voodoo 3 2000 PCI", - 0, + DEVICE_PCI, v3_2000_init, banshee_close, v3_2000_available, @@ -2341,7 +2341,7 @@ device_t voodoo_3_2000_device = device_t voodoo_3_3000_device = { "Voodoo 3 3000 PCI", - 0, + DEVICE_PCI, v3_3000_init, banshee_close, v3_3000_available, From d254f41817185146ccf89b6d0cc229976075d466 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 9 Oct 2020 17:20:25 +0100 Subject: [PATCH 0919/1050] Banshee/Voodoo 3 status returns busy when FIFO thread is busy, regardless of command/cmdfifo/render thread status. Fixes some 2D races where drivers start to write to framebuffer while (final) 2D blit command is still running. --- src/vid_voodoo_banshee.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 5f10cea..fb0ca99 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -698,7 +698,10 @@ static uint32_t banshee_status(banshee_t *banshee) int fifo_size = 0xffff - fifo_entries; int swap_count = voodoo->swap_count; int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1]; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || + voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || + voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || + voodoo->voodoo_busy; uint32_t ret; ret = 0; From c9891895da11b361a857ffce40bf9c504e50d962 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 12 Oct 2020 20:08:35 +0100 Subject: [PATCH 0920/1050] Implement Voodoo CMDFIFO enable bit. --- src/vid_voodoo.c | 3 +++ src/vid_voodoo_banshee.c | 3 ++- src/vid_voodoo_common.h | 1 + src/vid_voodoo_fifo.c | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 6245106..19c5467 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -603,7 +603,10 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) break; case SST_fbiInit7: if (voodoo->initEnable & 0x01) + { voodoo->fbiInit7 = val; + voodoo->cmdfifo_enabled = val & 0x100; + } break; case SST_cmdFifoBaseAddr: diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index fb0ca99..0e95ccc 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1098,6 +1098,7 @@ static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) case cmdBaseSize0: voodoo->cmdfifo_size = val; voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); + voodoo->cmdfifo_enabled = val & 0x100; // pclog("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); break; @@ -1437,7 +1438,7 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) svga->changedvram[addr >> 12] = changeframecount; *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; - if (addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) + if (voodoo->cmdfifo_enabled && addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) { // pclog("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index c72d079..637ccca 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -299,6 +299,7 @@ typedef struct voodoo_t uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; int cmdfifo_rp; volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; + volatile int cmdfifo_enabled; uint32_t cmdfifo_amin, cmdfifo_amax; int cmdfifo_holecount; diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index 35f63bf..0d35b3a 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -237,7 +237,7 @@ void voodoo_fifo_thread(void *param) voodoo->time += end_time - start_time; } - while (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + while (voodoo->cmdfifo_enabled && voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) { uint64_t start_time = timer_read(); uint64_t end_time; From 5eb6f4d168071e4cc892721895e332126ba77160 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 15 Oct 2020 20:20:12 +0100 Subject: [PATCH 0921/1050] Implement plug and play monitor support on Voodoo Banshee & 3. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/vid_ddc.c | 301 +++++++++++++++++++++++++++++ src/vid_ddc.h | 4 + src/vid_ddc.o | Bin 0 -> 5308 bytes src/vid_voodoo_banshee.c | 35 ++++ 7 files changed, 343 insertions(+), 3 deletions(-) create mode 100644 src/vid_ddc.c create mode 100644 src/vid_ddc.h create mode 100644 src/vid_ddc.o diff --git a/src/Makefile.am b/src/Makefile.am index 83236d0..599fdc1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,7 +43,7 @@ scsi_ibm.c scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_azt2316a.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 \ sst39sf010.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c \ +vid_ati18800.c vid_ati28800.c vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c vid_colorplus.c vid_compaq_cga.c vid_ddc.c vid_ega.c \ vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c \ vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 4c13f55..3d9401f 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -31,7 +31,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ - vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ + vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ddc.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index e58e406..7b7c632 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -31,7 +31,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ - vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ega.o vid_et4000.o vid_et4000w32.o \ + vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ddc.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ vid_mga.o vid_olivetti_m24.o vid_oti037.c vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_pgc.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_sigma.o vid_stg_ramdac.o vid_svga.o \ diff --git a/src/vid_ddc.c b/src/vid_ddc.c new file mode 100644 index 0000000..78e40c4 --- /dev/null +++ b/src/vid_ddc.c @@ -0,0 +1,301 @@ +#include "ibm.h" +#include "vid_ddc.h" +#include "x86.h" + +static uint8_t edid_data[128] = +{ + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, /*Fixed header pattern*/ + 0x65, 0x40, /*Manufacturer "PCE" - apparently unassigned by UEFI*/ + 0x00, 0x00, /*Product code*/ + 0x12, 0x34, 0x56, 0x78, /*Serial number*/ + 0x01, 9, /*Manufacturer week and year*/ + 0x01, 0x03, /*EDID version (1.3)*/ + + 0x08, /*Analogue input, separate sync*/ + 34, 0, /*Landscape, 4:3*/ + 0, /*Gamma*/ + 0x08, /*RGB colour*/ + 0x81, 0xf1, 0xa3, 0x57, 0x53, 0x9f, 0x27, 0x0a, 0x50, /*Chromaticity*/ + + 0xff, 0xff, 0xff, /*Established timing bitmap*/ + 0x00, 0x00, /*Standard timing information*/ + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + + /*Detailed mode descriptions*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x00, /*No extensions*/ + 0x00 +}; + +/*This should probably be split off into a separate I2C module*/ +enum +{ + TRANSMITTER_MONITOR = 1, + TRANSMITTER_HOST = -1 +}; + +enum +{ + I2C_IDLE = 0, + I2C_RECEIVE, + I2C_RECEIVE_WAIT, + I2C_TRANSMIT_START, + I2C_TRANSMIT, + I2C_ACKNOWLEDGE, + I2C_TRANSACKNOWLEDGE, + I2C_TRANSMIT_WAIT +}; + +enum +{ + PROM_IDLE = 0, + PROM_RECEIVEADDR, + PROM_RECEIVEDATA, + PROM_SENDDATA, + PROM_INVALID +}; + +static struct +{ + int clock, data; + int state; + int last_data; + int pos; + int transmit; + uint8_t byte; +} i2c; + +static struct +{ + int state; + int addr; + int rw; +} prom; + +static void prom_stop(void) +{ +// pclog("prom_stop()\n"); + prom.state = PROM_IDLE; + i2c.transmit = TRANSMITTER_HOST; +} + +static void prom_next_byte(void) +{ +// pclog("prom_next_byte(%d)\n", prom.addr); + i2c.byte = edid_data[(prom.addr++) & 0x7F]; +} + +static void prom_write(uint8_t byte) +{ +// pclog("prom_write: byte=%02x\n", byte); + switch (prom.state) + { + case PROM_IDLE: + if ((byte & 0xfe) != 0xa0) + { +// pclog("I2C address not PROM\n"); + prom.state = PROM_INVALID; + break; + } + prom.rw = byte & 1; + if (prom.rw) + { + prom.state = PROM_SENDDATA; + i2c.transmit = TRANSMITTER_MONITOR; + i2c.byte = edid_data[(prom.addr++) & 0x7F]; +// pclog("PROM - %02X from %02X\n",i2c.byte, prom.addr-1); +// pclog("Transmitter now PROM\n"); + } + else + { + prom.state = PROM_RECEIVEADDR; + i2c.transmit = TRANSMITTER_HOST; + } +// pclog("PROM R/W=%i\n",promrw); + return; + + case PROM_RECEIVEADDR: +// pclog("PROM addr=%02X\n",byte); + prom.addr = byte; + if (prom.rw) + prom.state = PROM_SENDDATA; + else + prom.state = PROM_RECEIVEDATA; + break; + + case PROM_RECEIVEDATA: +// pclog("PROM write %02X %02X\n",promaddr,byte); + break; + + case PROM_SENDDATA: + break; + } +} + +void ddc_i2c_change(int new_clock, int new_data) +{ +// pclog("I2C update clock %i->%i data %i->%i state %i\n",i2c.clock,new_clock,i2c.last_data,new_data,i2c.state); + switch (i2c.state) + { + case I2C_IDLE: + if (i2c.clock && new_clock) + { + if (i2c.last_data && !new_data) /*Start bit*/ + { +// pclog("Start bit received\n"); + i2c.state = I2C_RECEIVE; + i2c.pos = 0; + } + } + break; + + case I2C_RECEIVE_WAIT: + if (!i2c.clock && new_clock) + i2c.state = I2C_RECEIVE; + case I2C_RECEIVE: + if (!i2c.clock && new_clock) + { + i2c.byte <<= 1; + if (new_data) + i2c.byte |= 1; + else + i2c.byte &= 0xFE; + i2c.pos++; + if (i2c.pos == 8) + { + prom_write(i2c.byte); + i2c.state = I2C_ACKNOWLEDGE; + } + } + else if (i2c.clock && new_clock && new_data && !i2c.last_data) /*Stop bit*/ + { +// pclog("Stop bit received\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } + else if (i2c.clock && new_clock && !new_data && i2c.last_data) /*Start bit*/ + { +// pclog("Start bit received\n"); + i2c.pos = 0; + prom.state = PROM_IDLE; + } + break; + + case I2C_ACKNOWLEDGE: + if (!i2c.clock && new_clock) + { +// pclog("Acknowledging transfer\n"); + new_data = 0; + i2c.pos = 0; + if (i2c.transmit == TRANSMITTER_HOST) + i2c.state = I2C_RECEIVE_WAIT; + else + i2c.state = I2C_TRANSMIT; + } + break; + + case I2C_TRANSACKNOWLEDGE: + if (!i2c.clock && new_clock) + { + if (new_data) /*It's not acknowledged - must be end of transfer*/ + { +// pclog("End of transfer\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } + else /*Next byte to transfer*/ + { + i2c.state = I2C_TRANSMIT_START; + prom_next_byte(); + i2c.pos = 0; +// pclog("Next byte - %02X\n",i2c.byte); + } + } + break; + + case I2C_TRANSMIT_WAIT: + if (i2c.clock && new_clock) + { + if (i2c.last_data && !new_data) /*Start bit*/ + { + prom_next_byte(); + i2c.pos = 0; +// pclog("Next byte - %02X\n",i2c.byte); + } + if (!i2c.last_data && new_data) /*Stop bit*/ + { +// pclog("Stop bit received\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } + } + break; + + case I2C_TRANSMIT_START: + if (!i2c.clock && new_clock) + i2c.state = I2C_TRANSMIT; + case I2C_TRANSMIT: + if (!i2c.clock && new_clock) + { + i2c.clock = new_clock; +// if (!i2c.pos) +// pclog("Transmit byte %02x\n", i2c.byte); + i2c.data = new_data = i2c.byte & 0x80; +// pclog("Transmit bit %i %i\n", i2c.byte, i2c.pos); + i2c.byte <<= 1; + i2c.pos++; + return; + } + if (i2c.clock && !new_clock && i2c.pos == 8) + { + i2c.state = I2C_TRANSACKNOWLEDGE; +// pclog("Acknowledge mode\n"); + } + break; + + } + if (!i2c.clock && new_clock) + i2c.data = new_data; + i2c.last_data = new_data; + i2c.clock = new_clock; +} + +int ddc_read_clock(void) +{ + return i2c.clock; +} +int ddc_read_data(void) +{ + if (i2c.state == I2C_TRANSMIT || i2c.state == I2C_ACKNOWLEDGE) + return i2c.data; + if (i2c.state == I2C_RECEIVE_WAIT) + return 0; /*ACK*/ + return 1; +} + +void ddc_init(void) +{ + int c; + uint8_t checksum = 0; + + for (c = 0; c < 127; c++) + checksum += edid_data[c]; + edid_data[127] = 256 - checksum; +} diff --git a/src/vid_ddc.h b/src/vid_ddc.h new file mode 100644 index 0000000..7b8f8bd --- /dev/null +++ b/src/vid_ddc.h @@ -0,0 +1,4 @@ +void ddc_init(void); +void ddc_i2c_change(int new_clock, int new_data); +int ddc_read_clock(void); +int ddc_read_data(void); diff --git a/src/vid_ddc.o b/src/vid_ddc.o new file mode 100644 index 0000000000000000000000000000000000000000..4b52766d6a34a8a5b93bf4b2e961a75337efd08f GIT binary patch literal 5308 zcmcJTe{7pa8OQH+;?$I+Z#7ymAQ5hBZLMhCIIAZV)G1xtWoVnonvMAm-J-@AM6xu3q*k7^qPg%i3Eost^0uxX5$l2z2>7h<<2MDxd0I)PVE z^c)W-<7V7ZZW27v%|BA<7vJDmxeCq;WDoO2rtB5xV?{=P{S3gFcx+PlKZ zoRKg`4W$b4aDx!7svD~km8L|tMLsVS7}#F$WM#6#r@Hv@(J zTaegLY7LbSg_=udsIh!Bv{`>{$tOg)h4NNH(}=~ic@KnUkX0SI->R4$)}mhA2u~x` z$n{rO5K6Lqsf~)4qCtwcZl-u?`jva}M)GdNFOiWl8bo7--vkz>M}?hVj!OF#{mjDD zHET&PJ_9d`*Y#pvdP9}1s$R5^vKB{vUT&d|M3zd?R=lUbq7`nO)@Ms#QEH>Csg@Ap ze@x9xzkCm=tN!cOn@Cv|y?7PxIjjU!puUoH3_a0jWld4F7R`pqs#b2J7L>Vzg%1NI znbxgVlr78tTJZ8A`1Q!hXUkEVSADixQvOxZlQZ*$d0(jox|qY_vzx2EbsP29cKTWP zL!CZ_cezb=8mS73V#KXq;{7Ul9I2L~*X#6*=|#te>W3#V^P7lBi6+GpWxmsSvTA=uSu6|gk97$G zP0mHUBa4OoK{8Ohc`+1g%QBqW;I)to>;j(}{H> z$OoFv+7&2MuTTEv_T-0W&CM6&Aj*YPqd}Owq3N^Niq%pZEi&`-Y7bndH6^Is%l;r@ zS|97~huS#os2WsG)u2UCi&Hmdp^52VQ+$rLqho)bBL}B@mJ1(fqn{}J$ETmE=(Cjt z-rwhFw>!!|QTl7)-S-MNgP8KCkkzMWq@#WMvY(3j{8_0kOQ(JQoSkZyd33~5$u5~P z?NpCUjo7KOI1yFI`=O1%OjY>M{kbFuScSxF&o{`e&#*jX{CFJu@ zAnEgeL&m2Ni>pg-o>MBNspS%rq;8RGvdj=Jv-=UG--Y<5vw?{nH zx}WIvY6l)W{NSSpdXFAH;>k+S9p|X{3j7tMb@YS((h>NY?9|BQv{>QCZWIN3(zD_GHdF&DHa~ zt=03qjm3wC;`u>O*K+Y8XxK;H2M=}zcRrRH?miaIh z(8iAlZ6ct3rn#|k3VSmMjefT1T;D>`!A;Fa3JuTteA$h^UD(w42=1htA$Q>kA%FGy zN!n37`=H6o44CW;;7LMz7jJQ3Q^4{)*y8uS{TiARblB2Wvq@}Y+6f|CO@ex&avx_p z#`JZj1QVUlss^34ioVPAGp2c_D$^f9^mEcA-eTe8Rx0;?=GghnRYNmnYx*dG8s%crjtyknVx6*9@BZI zi%j!OZ!q0rYQ)Vz`P|I(Nu~~_BTO+SgDD46GdRZDDW(~wA2a=m={2U;nf}1^H;}S? zleJq+A2DsfI#>PJ#uQrk9y6GF@W2!t{Hl z8%+OZ+JG&pJpDA&E~dRqQKko&uw?{&{58q5L=jyI6_Hg%wA&TYnWTt50u<31q9|z7 z7IBE_Nv1SYxG$A9kfLxK*O`88G?k1clZkLbiFW)c`>lzf@L~U~4Y5>*tU#V(it)s< z_-VF_DTNZdYz50%mctnc3StbUWtmGJx4V>HD92fG{sTa+G-!t~j&6UQU;nZ#Z4xEj z!TIGcJ=EwtbqD8HKO8_?LBupO_2B&Cha)I+n9O+sox&98SD-=LA$e^yU<>qzL4#IA zOs%>Do!n>bIiS7?L6_Opay}8mrH<4rMF>#ri&(u3>EFRqS7P!O=TxZ7_g!U3Iqy+^ z>QZ9%P0e9h-O-$Fsq2|TAr0-d vi$TQPmwOTGuHVq%4`0betbXHNWp(FtrLwM+YEs@>ZCtHVzk8xaJt6)Jh1MFf literal 0 HcmV?d00001 diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 0e95ccc..20b8292 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -7,6 +7,7 @@ #include "rom.h" #include "thread.h" #include "video.h" +#include "vid_ddc.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_voodoo_banshee.h" @@ -58,6 +59,7 @@ typedef struct banshee_t uint32_t vidDesktopStartAddr; uint32_t vidProcCfg; uint32_t vidScreenSize; + uint32_t vidSerialParallelPort; int overlay_pix_fmt; @@ -110,6 +112,7 @@ enum Video_hwCurLoc = 0x64, Video_hwCurC0 = 0x68, Video_hwCurC1 = 0x6c, + Video_vidSerialParallelPort = 0x78, Video_vidScreenSize = 0x98, Video_vidOverlayStartCoords = 0x9c, Video_vidOverlayEndScreenCoords = 0xa0, @@ -180,6 +183,14 @@ enum #define PIX_FORMAT_RGB24 2 #define PIX_FORMAT_RGB32 3 +#define VIDSERIAL_DDC_DCK_W (1 << 19) +#define VIDSERIAL_DDC_DDA_W (1 << 20) +#define VIDSERIAL_DDC_DCK_R (1 << 21) +#define VIDSERIAL_DDC_DDA_R (1 << 22) +#define VIDSERIAL_I2C_SCK_W (1 << 24) +#define VIDSERIAL_I2C_SDA_W (1 << 25) +#define VIDSERIAL_I2C_SCK_R (1 << 26) +#define VIDSERIAL_I2C_SDA_R (1 << 27) static uint32_t banshee_status(banshee_t *banshee); @@ -596,6 +607,12 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) banshee->hwCurC1 = val; break; + case Video_vidSerialParallelPort: + banshee->vidSerialParallelPort = val; +// pclog("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); + ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0); + break; + case Video_vidScreenSize: banshee->vidScreenSize = val; voodoo->h_disp = (val & 0xfff) + 1; @@ -824,6 +841,20 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p) ret = banshee->hwCurC1; break; + case Video_vidSerialParallelPort: + ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R); + if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && ddc_read_clock()) + ret |= VIDSERIAL_DDC_DCK_R; + if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && ddc_read_data()) + ret |= VIDSERIAL_DDC_DDA_R; + ret = ret & ~(VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); + if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SCK_W) + ret |= VIDSERIAL_I2C_SCK_R; + if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SDA_W) + ret |= VIDSERIAL_I2C_SDA_R; +// pclog("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); + break; + case Video_vidScreenSize: ret = banshee->vidScreenSize; break; @@ -2169,6 +2200,10 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t banshee->voodoo->tex_mem_w[1] = (uint16_t *)banshee->svga.vram; banshee->voodoo->texture_mask = banshee->svga.vram_mask; + banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; + + ddc_init(); + return banshee; } From 7e2c6a53445a6d87ab11b62a44915e533cb39590 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 15 Oct 2020 21:51:58 +0100 Subject: [PATCH 0922/1050] Add DDC/plug and play monitor support to S3 ViRGE. --- src/vid_ddc.c | 6 ++++++ src/vid_ddc.o | Bin 5308 -> 0 bytes src/vid_s3_virge.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 40 insertions(+), 3 deletions(-) delete mode 100644 src/vid_ddc.o diff --git a/src/vid_ddc.c b/src/vid_ddc.c index 78e40c4..c06613c 100644 --- a/src/vid_ddc.c +++ b/src/vid_ddc.c @@ -251,6 +251,12 @@ void ddc_i2c_change(int new_clock, int new_data) case I2C_TRANSMIT_START: if (!i2c.clock && new_clock) i2c.state = I2C_TRANSMIT; + if (i2c.clock && new_clock && !i2c.last_data && new_data) /*Stop bit*/ + { +// pclog("Stop bit received\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } case I2C_TRANSMIT: if (!i2c.clock && new_clock) { diff --git a/src/vid_ddc.o b/src/vid_ddc.o deleted file mode 100644 index 4b52766d6a34a8a5b93bf4b2e961a75337efd08f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5308 zcmcJTe{7pa8OQH+;?$I+Z#7ymAQ5hBZLMhCIIAZV)G1xtWoVnonvMAm-J-@AM6xu3q*k7^qPg%i3Eost^0uxX5$l2z2>7h<<2MDxd0I)PVE z^c)W-<7V7ZZW27v%|BA<7vJDmxeCq;WDoO2rtB5xV?{=P{S3gFcx+PlKZ zoRKg`4W$b4aDx!7svD~km8L|tMLsVS7}#F$WM#6#r@Hv@(J zTaegLY7LbSg_=udsIh!Bv{`>{$tOg)h4NNH(}=~ic@KnUkX0SI->R4$)}mhA2u~x` z$n{rO5K6Lqsf~)4qCtwcZl-u?`jva}M)GdNFOiWl8bo7--vkz>M}?hVj!OF#{mjDD zHET&PJ_9d`*Y#pvdP9}1s$R5^vKB{vUT&d|M3zd?R=lUbq7`nO)@Ms#QEH>Csg@Ap ze@x9xzkCm=tN!cOn@Cv|y?7PxIjjU!puUoH3_a0jWld4F7R`pqs#b2J7L>Vzg%1NI znbxgVlr78tTJZ8A`1Q!hXUkEVSADixQvOxZlQZ*$d0(jox|qY_vzx2EbsP29cKTWP zL!CZ_cezb=8mS73V#KXq;{7Ul9I2L~*X#6*=|#te>W3#V^P7lBi6+GpWxmsSvTA=uSu6|gk97$G zP0mHUBa4OoK{8Ohc`+1g%QBqW;I)to>;j(}{H> z$OoFv+7&2MuTTEv_T-0W&CM6&Aj*YPqd}Owq3N^Niq%pZEi&`-Y7bndH6^Is%l;r@ zS|97~huS#os2WsG)u2UCi&Hmdp^52VQ+$rLqho)bBL}B@mJ1(fqn{}J$ETmE=(Cjt z-rwhFw>!!|QTl7)-S-MNgP8KCkkzMWq@#WMvY(3j{8_0kOQ(JQoSkZyd33~5$u5~P z?NpCUjo7KOI1yFI`=O1%OjY>M{kbFuScSxF&o{`e&#*jX{CFJu@ zAnEgeL&m2Ni>pg-o>MBNspS%rq;8RGvdj=Jv-=UG--Y<5vw?{nH zx}WIvY6l)W{NSSpdXFAH;>k+S9p|X{3j7tMb@YS((h>NY?9|BQv{>QCZWIN3(zD_GHdF&DHa~ zt=03qjm3wC;`u>O*K+Y8XxK;H2M=}zcRrRH?miaIh z(8iAlZ6ct3rn#|k3VSmMjefT1T;D>`!A;Fa3JuTteA$h^UD(w42=1htA$Q>kA%FGy zN!n37`=H6o44CW;;7LMz7jJQ3Q^4{)*y8uS{TiARblB2Wvq@}Y+6f|CO@ex&avx_p z#`JZj1QVUlss^34ioVPAGp2c_D$^f9^mEcA-eTe8Rx0;?=GghnRYNmnYx*dG8s%crjtyknVx6*9@BZI zi%j!OZ!q0rYQ)Vz`P|I(Nu~~_BTO+SgDD46GdRZDDW(~wA2a=m={2U;nf}1^H;}S? zleJq+A2DsfI#>PJ#uQrk9y6GF@W2!t{Hl z8%+OZ+JG&pJpDA&E~dRqQKko&uw?{&{58q5L=jyI6_Hg%wA&TYnWTt50u<31q9|z7 z7IBE_Nv1SYxG$A9kfLxK*O`88G?k1clZkLbiFW)c`>lzf@L~U~4Y5>*tU#V(it)s< z_-VF_DTNZdYz50%mctnc3StbUWtmGJx4V>HD92fG{sTa+G-!t~j&6UQU;nZ#Z4xEj z!TIGcJ=EwtbqD8HKO8_?LBupO_2B&Cha)I+n9O+sox&98SD-=LA$e^yU<>qzL4#IA zOs%>Do!n>bIiS7?L6_Opay}8mrH<4rMF>#ri&(u3>EFRqS7P!O=TxZ7_g!U3Iqy+^ z>QZ9%P0e9h-O-$Fsq2|TAr0-d vi$TQPmwOTGuHVq%4`0betbXHNWp(FtrLwM+YEs@>ZCtHVzk8xaJt6)Jh1MFf diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 60afc23..562842d 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -8,6 +8,7 @@ #include "rom.h" #include "thread.h" #include "video.h" +#include "vid_ddc.h" #include "vid_s3_virge.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -235,6 +236,8 @@ typedef struct virge_t int virge_busy; uint8_t subsys_stat, subsys_cntl; + + uint8_t serialport; } virge_t; static inline void wake_fifo_thread(virge_t *virge) @@ -306,6 +309,11 @@ enum #define INT_3DF_EMP (1 << 6) #define INT_MASK 0xff +#define SERIAL_PORT_SCW (1 << 0) +#define SERIAL_PORT_SDW (1 << 1) +#define SERIAL_PORT_SCR (1 << 2) +#define SERIAL_PORT_SDR (1 << 3) + static void s3_virge_update_irqs(virge_t *virge) { if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) @@ -786,6 +794,14 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: return s3_virge_in(addr & 0x3ff, p); + + case 0xff20: case 0xff21: + ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); + if ((virge->serialport & SERIAL_PORT_SCW) && ddc_read_clock()) + ret |= SERIAL_PORT_SCR; + if ((virge->serialport & SERIAL_PORT_SDW) && ddc_read_data()) + ret |= SERIAL_PORT_SDR; + return ret; } return 0xff; } @@ -1355,9 +1371,12 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: s3_virge_out(addr & 0x3ff, val, p); break; - } - + case 0xff20: + virge->serialport = val; + ddc_i2c_change((val & SERIAL_PORT_SCW) ? 1 : 0, (val & SERIAL_PORT_SDW) ? 1 : 0); + break; + } } static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { @@ -1374,6 +1393,10 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) s3_virge_mmio_write(addr, val, p); s3_virge_mmio_write(addr + 1, val >> 8, p); break; + + case 0xff20: + s3_virge_mmio_write(addr, val, p); + break; } } static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) @@ -1817,6 +1840,10 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) // s3_virge_triangle(virge); break; + + case 0xff20: + s3_virge_mmio_write(addr, val, p); + break; } } @@ -3916,6 +3943,8 @@ static void *s3_virge_init() virge->fifo_not_full_event = thread_create_event(); virge->fifo_thread = thread_create(fifo_thread, virge); + ddc_init(); + return virge; } @@ -4012,7 +4041,9 @@ static void *s3_virge_375_init() virge->wake_fifo_thread = thread_create_event(); virge->fifo_not_full_event = thread_create_event(); virge->fifo_thread = thread_create(fifo_thread, virge); - + + ddc_init(); + return virge; } From a19829cf11fbbb5650315e5730f9caac4f3ce2ef Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 17 Oct 2020 20:10:23 +0100 Subject: [PATCH 0923/1050] Add DDC / plug and play monitor support for Mach64VT2. --- src/vid_ati_mach64.c | 31 ++++++++++++++++++++++++++++--- src/vid_ddc.c | 3 +++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index e38fca3..8b752f2 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -8,6 +8,7 @@ #include "rom.h" #include "thread.h" #include "video.h" +#include "vid_ddc.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_ati68860_ramdac.h" @@ -1838,11 +1839,27 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) 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); + case 0xc4: case 0xc5: case 0xc6: READ8(addr, mach64->dac_cntl); break; + case 0xc7: + READ8(addr, mach64->dac_cntl); + if (mach64->type == MACH64_VT2) + { + uint8_t gpio_state = 6; + + if ((ret & (1 << 4)) && !(ret & (1 << 1))) + gpio_state &= ~(1 << 1); + if (!(ret & (1 << 4)) && !ddc_read_data()) + gpio_state &= ~(1 << 1); + if ((ret & (1 << 5)) && !(ret & (1 << 2))) + gpio_state &= ~(1 << 2); + if (!(ret & (1 << 5)) && !ddc_read_clock()) + gpio_state &= ~(1 << 2); + + ret = (ret & ~6) | gpio_state; + } + break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: READ8(addr, mach64->gen_test_cntl); @@ -2354,6 +2371,12 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) WRITE8(addr, mach64->dac_cntl, val); svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); ati68860_set_ramdac_type(&mach64->ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + { + int data = (val & (1 << 4)) ? ((val & (1 << 1)) ? 1 : 0) : 1; + int clk = (val & (1 << 5)) ? ((val & (1 << 2)) ? 1 : 0) : 1; + + ddc_i2c_change(clk, data); + } break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: @@ -3397,6 +3420,8 @@ static void *mach64_common_init() mach64->wake_fifo_thread = thread_create_event(); mach64->fifo_not_full_event = thread_create_event(); mach64->fifo_thread = thread_create(fifo_thread, mach64); + + ddc_init(); return mach64; } diff --git a/src/vid_ddc.c b/src/vid_ddc.c index c06613c..9ccc7ca 100644 --- a/src/vid_ddc.c +++ b/src/vid_ddc.c @@ -304,4 +304,7 @@ void ddc_init(void) for (c = 0; c < 127; c++) checksum += edid_data[c]; edid_data[127] = 256 - checksum; + + i2c.clock = 1; + i2c.data = 1; } From 44433fd020d302cd870625bf71a81cbb611084f8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 18 Oct 2020 14:04:15 +0100 Subject: [PATCH 0924/1050] Reset Banshee/V3 2D blitter coordinates on new command start. Fixes corruption in Winamp. --- src/vid_voodoo_banshee_blitter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index aa942b2..e2a78dd 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -1190,6 +1190,8 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_y = 0; + voodoo->banshee_blt.dstX = ((int32_t)(voodoo->banshee_blt.dstXY << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(voodoo->banshee_blt.dstXY << 3)) >> 19; voodoo->banshee_blt.srcX = ((int32_t)(voodoo->banshee_blt.srcXY << 19)) >> 19; voodoo->banshee_blt.srcY = ((int32_t)(voodoo->banshee_blt.srcXY << 3)) >> 19; voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; From 6ead42d868c63a5e798dfa21616a3b7a438508a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Oct 2020 20:09:36 +0100 Subject: [PATCH 0925/1050] Fix off-by-one issue with Voodoo clipping. --- src/vid_voodoo_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index a2125cb..3648c78 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -736,7 +736,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood } if ((params->fbzMode & 1) && (yend >= params->clipHighY)) - yend = params->clipHighY-1; + yend = params->clipHighY; state->y = ystart; // yend--; From ec9ca6c97bfb4567405aa1be99a660f2150f3119 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 19 Oct 2020 20:58:52 +0100 Subject: [PATCH 0926/1050] Fix missing immediate markers in opcode_deps[] tables. --- src/codegen_timing_common.c | 118 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/codegen_timing_common.c b/src/codegen_timing_common.c index c29f24f..a74410f 100644 --- a/src/codegen_timing_common.c +++ b/src/codegen_timing_common.c @@ -3,41 +3,41 @@ uint64_t opcode_deps[256] = { -/* ADD ADD ADD ADD*/ -/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* ADD ADD PUSH ES POP ES*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* OR OR OR OR*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* OR OR PUSH CS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, +/* ADD ADD ADD ADD*/ +/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* ADD ADD PUSH ES POP ES*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, IMPL_ESP, +/* OR OR OR OR*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* OR OR PUSH CS*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, 0, -/* ADC ADC ADC ADC*/ -/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* ADC ADC PUSH SS POP SS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, -/* SBB SBB SBB SBB*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* SBB SBB PUSH DS POP DS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, +/* ADC ADC ADC ADC*/ +/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* ADC ADC PUSH SS POP SS*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, IMPL_ESP, +/* SBB SBB SBB SBB*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* SBB SBB PUSH DS POP DS*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, IMPL_ESP, -/* AND AND AND AND*/ -/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* AND AND DAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* SUB SUB SUB SUB*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* SUB SUB DAS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, +/* AND AND AND AND*/ +/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* AND AND DAA*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, +/* SUB SUB SUB SUB*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* SUB SUB DAS*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, -/* XOR XOR XOR XOR*/ -/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, -/* XOR XOR AAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, -/* CMP CMP CMP CMP*/ - SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, -/* CMP CMP AAS*/ - SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, +/* XOR XOR XOR XOR*/ +/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, +/* XOR XOR AAA*/ + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, +/* CMP CMP CMP CMP*/ + SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, +/* CMP CMP AAS*/ + SRCDEP_EAX | HAS_IMM8, SRCDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, /* INC EAX INC ECX INC EDX INC EBX*/ /*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, @@ -61,7 +61,7 @@ uint64_t opcode_deps[256] = /*60*/ IMPL_ESP, IMPL_ESP, 0, 0, 0, 0, 0, 0, /* PUSH imm IMUL PUSH imm IMUL*/ - IMPL_ESP, DSTDEP_REG | MODRM, IMPL_ESP, DSTDEP_REG | MODRM, + IMPL_ESP | HAS_IMM1632,DSTDEP_REG | MODRM, IMPL_ESP | HAS_IMM8, DSTDEP_REG | MODRM, /* INSB INSW OUTSB OUTSW*/ 0, 0, 0, 0, @@ -95,15 +95,15 @@ uint64_t opcode_deps[256] = 0, 0, 0, 0, /* MOV*/ -/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, +/*b0*/ DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM1632, DSTDEP_ECX | HAS_IMM1632, DSTDEP_EDX | HAS_IMM1632, DSTDEP_EBX | HAS_IMM1632, + DSTDEP_ESP | HAS_IMM1632, DSTDEP_EBP | HAS_IMM1632, DSTDEP_ESI | HAS_IMM1632, DSTDEP_EDI | HAS_IMM1632, /* RET imm RET*/ /*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, /* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM, MODRM, + DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM | HAS_IMM8, MODRM | HAS_IMM1632, /* ENTER LEAVE RETF RETF*/ IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, /* INT3 INT INTO IRET*/ @@ -140,38 +140,38 @@ uint64_t opcode_deps_mod3[256] = /* ADD ADD ADD ADD*/ /*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* ADD ADD PUSH ES POP ES*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, IMPL_ESP, /* OR OR OR OR*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* OR OR PUSH CS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, 0, /* ADC ADC ADC ADC*/ /*10*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* ADC ADC PUSH SS POP SS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, IMPL_ESP, /* SBB SBB SBB SBB*/ SRCDEP_REG |SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* SBB SBB PUSH DS POP DS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, IMPL_ESP, IMPL_ESP, /* AND AND AND AND*/ /*20*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* AND AND DAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, /* SUB SUB SUB SUB*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* SUB SUB DAS*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, /* XOR XOR XOR XOR*/ /*30*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, /* XOR XOR AAA*/ - SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX, + SRCDEP_EAX | DSTDEP_EAX | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, /* CMP CMP CMP CMP*/ SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, /* CMP CMP AAS*/ - SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX, + SRCDEP_EAX | HAS_IMM8, SRCDEP_EAX | HAS_IMM1632, 0, SRCDEP_EAX | DSTDEP_EAX, /* INC EAX INC ECX INC EDX INC EBX*/ /*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX, @@ -195,7 +195,7 @@ uint64_t opcode_deps_mod3[256] = /*60*/ IMPL_ESP, IMPL_ESP, 0, 0, 0, 0, 0, 0, /* PUSH imm IMUL PUSH imm IMUL*/ - IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, + IMPL_ESP | HAS_IMM1632,DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP | HAS_IMM8, DSTDEP_REG | SRCDEP_RM | MODRM, /* INSB INSW OUTSB OUTSW*/ 0, 0, 0, 0, @@ -229,19 +229,19 @@ uint64_t opcode_deps_mod3[256] = 0, 0, 0, 0, /* MOV*/ -/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX, - DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI, +/*b0*/ DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM1632, DSTDEP_ECX | HAS_IMM1632, DSTDEP_EDX | HAS_IMM1632, DSTDEP_EBX | HAS_IMM1632, + DSTDEP_ESP | HAS_IMM1632, DSTDEP_EBP | HAS_IMM1632, DSTDEP_ESI | HAS_IMM1632, DSTDEP_EDI | HAS_IMM1632, -/* RET imm RET*/ -/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, -/* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM, DSTDEP_RM | MODRM, -/* ENTER LEAVE RETF RETF*/ - IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, -/* INT3 INT INTO IRET*/ - 0, 0, 0, 0, +/* RET imm RET*/ +/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, +/* LES LDS MOV MOV*/ + DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM | HAS_IMM8, DSTDEP_RM | MODRM | HAS_IMM1632, +/* ENTER LEAVE RETF RETF*/ + IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP, +/* INT3 INT INTO IRET*/ + 0, 0, 0, 0, /*d0*/ 0, 0, 0, 0, From b40cc2b87ef8967031b195354c2c4b005a37451c Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Oct 2020 20:07:37 +0100 Subject: [PATCH 0927/1050] Implement P6 operand & address size prefix penalties. --- src/codegen_timing_p6.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/codegen_timing_p6.c b/src/codegen_timing_p6.c index b668f99..1b4d53d 100644 --- a/src/codegen_timing_p6.c +++ b/src/codegen_timing_p6.c @@ -1692,6 +1692,7 @@ static int fpu_st_timestamp[8]; static int last_uop_timestamp = 0; static int ifetch_length = 0; +static int has_66_prefix, has_67_prefix; static void decode_flush() { @@ -1787,9 +1788,16 @@ static void decode_instruction(const p6_instruction_t *ins, uint64_t deps, uint3 uint32_t regmask_required; uint32_t regmask_modified; int c, d; - int earliest_start = 0; + int earliest_start; int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + if (has_66_prefix && (deps & HAS_IMM1632)) + decode_timestamp += 2; + if (has_67_prefix && (deps & MODRM)) + decode_timestamp += 4; + + earliest_start = decode_timestamp; + /*Generate input register mask, and determine the earliest time this instruction can start. This is not accurate, as this is calculated per x86 instruction when it should be handled per uop*/ @@ -1957,6 +1965,8 @@ void codegen_timing_p6_start() // nr_units = NR_P6_UNITS; last_prefix = 0; prefixes = 0; + has_66_prefix = 0; + has_67_prefix = 0; } /*Prefixes : @@ -1968,6 +1978,10 @@ void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) { if (last_prefix) /*First prefix is free*/ decode_timestamp++; + if (prefix == 0x66) + has_66_prefix = 1; + if (prefix == 0x67) + has_67_prefix = 1; last_prefix = prefix; prefixes++; From 826389a37ac5248c11aac8d0a5410ee5ef46ee9f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Oct 2020 19:39:56 +0000 Subject: [PATCH 0928/1050] Rework Voodoo texture precalc to support non-split trilinear textures. Fixes trilinear bugs on Voodoo 3. --- src/vid_voodoo_texture.c | 115 ++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/src/vid_voodoo_texture.c b/src/vid_voodoo_texture.c index f52a314..ed1f8c3 100644 --- a/src/vid_voodoo_texture.c +++ b/src/vid_voodoo_texture.c @@ -22,6 +22,8 @@ void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) uint32_t base = voodoo->params.texBaseAddr[tmu]; uint32_t offset = 0; int tex_lod = 0; + uint32_t offsets[LOD_MAX+3]; + int widths[LOD_MAX+3], heights[LOD_MAX+3], shifts[LOD_MAX+3]; if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) height >>= aspect; @@ -31,77 +33,78 @@ void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) shift -= aspect; } - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD)) + for (lod = 0; lod <= LOD_MAX + 2; lod++) { - width >>= 1; - height >>= 1; - shift--; - tex_lod++; - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - base = voodoo->params.texBaseAddr1[tmu]; + offsets[lod] = offset; + widths[lod] = width >> lod; + heights[lod] = height >> lod; + shifts[lod] = shift - lod; + + if (!widths[lod]) + widths[lod] = 1; + if (!heights[lod]) + heights[lod] = 1; + if (shifts[lod] < 0) + shifts[lod] = 0; + + if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || + ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || + (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) + { + if (voodoo->params.tformat[tmu] & 8) + offset += (width >> lod) * (height >> lod) * 2; + else + offset += (width >> lod) * (height >> lod); + } } + + if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) + tex_lod++; /*Skip LOD 0*/ + + pclog("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); for (lod = 0; lod <= LOD_MAX+1; lod++) { - if (!width) - width = 1; - if (!height) - height = 1; - if (shift < 0) - shift = 0; - voodoo->params.tex_base[tmu][lod] = base + offset; + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) + { + switch (tex_lod) + { + case 0: + base = voodoo->params.texBaseAddr[tmu]; + break; + case 1: + base = voodoo->params.texBaseAddr1[tmu]; + break; + case 2: + base = voodoo->params.texBaseAddr2[tmu]; + break; + default: + base = voodoo->params.texBaseAddr38[tmu]; + break; + } + } + + voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod]; if (voodoo->params.tformat[tmu] & 8) - voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2); + voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2); else - voodoo->params.tex_end[tmu][lod] = base + offset + (width * height); - voodoo->params.tex_w_mask[tmu][lod] = width - 1; - voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1); - voodoo->params.tex_h_mask[tmu][lod] = height - 1; - voodoo->params.tex_shift[tmu][lod] = shift; + voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]); + voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1; + voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1); + voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1; + voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod]; voodoo->params.tex_lod[tmu][lod] = tex_lod; - if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) + if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) || + ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || + (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) { - if (voodoo->params.tformat[tmu] & 8) - offset += width * height * 2; - else - offset += width * height; - - if (voodoo->params.tLOD[tmu] & LOD_SPLIT) - { - width >>= 2; - height >>= 2; - shift -= 2; + if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) tex_lod += 2; - } else - { - width >>= 1; - height >>= 1; - shift--; tex_lod++; - } - - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - { - switch (tex_lod) - { - case 0: - base = voodoo->params.texBaseAddr[tmu]; - break; - case 1: - base = voodoo->params.texBaseAddr1[tmu]; - break; - case 2: - base = voodoo->params.texBaseAddr2[tmu]; - break; - default: - base = voodoo->params.texBaseAddr38[tmu]; - break; - } - } } } } From 9fc93833c44d7a0a21d07eeb95390a325016395a Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 26 Oct 2020 20:41:12 +0000 Subject: [PATCH 0929/1050] Disable logging added in previous commit. --- src/vid_voodoo_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_texture.c b/src/vid_voodoo_texture.c index ed1f8c3..f1d5c78 100644 --- a/src/vid_voodoo_texture.c +++ b/src/vid_voodoo_texture.c @@ -62,7 +62,7 @@ void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) tex_lod++; /*Skip LOD 0*/ - pclog("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); +// pclog("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); for (lod = 0; lod <= LOD_MAX+1; lod++) { if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) From f705fd82612aa46136161250fb2b1258860a0ac2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Oct 2020 08:24:11 +0000 Subject: [PATCH 0930/1050] Change Voodoo 3 PCI revision from 3 to 1. --- src/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 20b8292..2026d8e 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1880,7 +1880,7 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x07: ret = banshee->pci_regs[0x07] & 0x36; break; - case 0x08: ret = 3; break; /*Revision ID*/ + case 0x08: ret = (banshee->type == TYPE_BANSHEE) ? 3 : 1; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ From 70ab9384399e8ac467baf0121febfc3123b8daf0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Oct 2020 20:35:06 +0000 Subject: [PATCH 0931/1050] Update dest x/y at end of Banshee blitter command if required. Fixes corruption in Windows 2000. --- src/vid_voodoo_banshee_blitter.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index e2a78dd..ab33e76 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -33,6 +33,8 @@ #define COMMAND_CMD_POLYLINE (7 << 0) #define COMMAND_CMD_POLYFILL (8 << 0) #define COMMAND_INITIATE (1 << 8) +#define COMMAND_INC_X_START (1 << 10) +#define COMMAND_INC_Y_START (1 << 11) #define COMMAND_PATTERN_MONO (1 << 13) #define COMMAND_DX (1 << 14) #define COMMAND_DY (1 << 15) @@ -281,6 +283,22 @@ static void update_src_stride(voodoo_t *voodoo) } } +static void end_command(voodoo_t *voodoo) +{ + /*Update dest coordinates if required*/ + if (voodoo->banshee_blt.command & COMMAND_INC_X_START) + { + voodoo->banshee_blt.dstXY &= ~0x0000ffff; + voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstX & 0xffff); + } + + if (voodoo->banshee_blt.command & COMMAND_INC_Y_START) + { + voodoo->banshee_blt.dstXY &= ~0xffff0000; + voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstY << 16); + } +} + static void banshee_do_rectfill(voodoo_t *voodoo) { clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; @@ -318,8 +336,9 @@ static void banshee_do_rectfill(voodoo_t *voodoo) if (!(voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0)) pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; } -} + end_command(voodoo); +} static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { @@ -548,6 +567,7 @@ static void banshee_do_screen_to_screen_blt(voodoo_t *voodoo) // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcBaseAddr_tiled); } + end_command(voodoo); } static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) @@ -581,6 +601,8 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t else do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); } if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) @@ -604,6 +626,8 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t { do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); } if (voodoo->banshee_blt.host_data_count) @@ -741,6 +765,7 @@ static void banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); } + end_command(voodoo); } static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, uint32_t data) @@ -769,6 +794,8 @@ static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, u else do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, NULL); voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); } if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) @@ -792,6 +819,8 @@ static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, u { do_screen_to_screen_stretch_line(voodoo, voodoo->banshee_blt.host_data, 0, NULL); voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); } if (voodoo->banshee_blt.host_data_count) From 0cbbd22c881d67fc42c78242fa3f23db1249d457 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 31 Oct 2020 20:30:10 +0000 Subject: [PATCH 0932/1050] Add emulation of System Management Mode. --- src/386.c | 7 +- src/386_dynarec.c | 17 ++-- src/386_ops.h | 56 ++++++------- src/808x.c | 4 +- src/x86.h | 10 ++- src/x86_ops_io.h | 28 ++++++- src/x86_ops_pmode.h | 11 +++ src/x86seg.c | 200 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 295 insertions(+), 38 deletions(-) diff --git a/src/386.c b/src/386.c index 8276b40..6ef54b6 100644 --- a/src/386.c +++ b/src/386.c @@ -219,7 +219,12 @@ void exec386(int cycs) cycdiff=oldcyc-cycles; - if (trap) + if (cpu_state.smi_pending) + { + cpu_state.smi_pending = 0; + x86_smi_enter(); + } + else if (trap) { flags_rebuild(); // oldpc=pc; diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 171c6b3..da47b20 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -274,6 +274,8 @@ static inline void exec_interpreter(void) if (cpu_state.abrt) CPU_BLOCK_END(); + if (cpu_state.smi_pending) + CPU_BLOCK_END(); if (trap) CPU_BLOCK_END(); if (nmi && nmi_enable && nmi_mask) @@ -446,10 +448,10 @@ static inline void exec_recompiler(void) hit, as host block size is only 2kB*/ if (((cs+cpu_state.pc) - start_pc) >= max_block_size) CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) CPU_BLOCK_END(); - + if (cpu_state.smi_pending) + CPU_BLOCK_END(); if (nmi && nmi_enable && nmi_mask) CPU_BLOCK_END(); @@ -525,10 +527,10 @@ static inline void exec_recompiler(void) hit, as host block size is only 2kB*/ if (((cs+cpu_state.pc) - start_pc) >= max_block_size) CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) CPU_BLOCK_END(); - + if (cpu_state.smi_pending) + CPU_BLOCK_END(); if (nmi && nmi_enable && nmi_mask) CPU_BLOCK_END(); @@ -614,7 +616,12 @@ void exec386_dynarec(int cycs) } } - if (nmi && nmi_enable && nmi_mask) + if (cpu_state.smi_pending) + { + cpu_state.smi_pending = 0; + x86_smi_enter(); + } + else if (nmi && nmi_enable && nmi_mask) { cpu_state.oldpc = cpu_state.pc; // pclog("NMI\n"); diff --git a/src/386_ops.h b/src/386_ops.h index 0f78ffa..79ea171 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -381,7 +381,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -403,7 +403,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -425,7 +425,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -447,7 +447,7 @@ OpFn OP_TABLE(winchip_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -472,7 +472,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -494,7 +494,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -516,7 +516,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -538,7 +538,7 @@ OpFn OP_TABLE(winchip2_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -563,7 +563,7 @@ OpFn OP_TABLE(pentium_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -585,7 +585,7 @@ OpFn OP_TABLE(pentium_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -607,7 +607,7 @@ OpFn OP_TABLE(pentium_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -629,7 +629,7 @@ OpFn OP_TABLE(pentium_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -654,7 +654,7 @@ OpFn OP_TABLE(pentiummmx_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -676,7 +676,7 @@ OpFn OP_TABLE(pentiummmx_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -698,7 +698,7 @@ OpFn OP_TABLE(pentiummmx_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -720,7 +720,7 @@ OpFn OP_TABLE(pentiummmx_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -745,7 +745,7 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -767,7 +767,7 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -789,7 +789,7 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -811,7 +811,7 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -836,7 +836,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -858,7 +858,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -880,7 +880,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -902,7 +902,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -927,7 +927,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, /*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -949,7 +949,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, /*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, /*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -971,7 +971,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, /*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, @@ -993,7 +993,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] = /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, /*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, /*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, diff --git a/src/808x.c b/src/808x.c index b080c97..825d9f9 100644 --- a/src/808x.c +++ b/src/808x.c @@ -523,7 +523,7 @@ void dumpregs() putc(readmembl(c+0x80000000),f); } fclose(f); - pclog("Dumping done\n"); + pclog("Dumping done\n"); /* f=fopen("rram6.dmp","wb"); for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f); fclose(f);*/ @@ -583,6 +583,7 @@ void dumpregs() { printf("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit"); printf("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4); + pclog("SMBASE=%08x\n", cpu_state.smbase); } printf("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum); for (c=0;c<1024*1024;c++) @@ -641,6 +642,7 @@ void resetx86() x86seg_reset(); codegen_reset(); x86_was_reset = 1; + cpu_state.smbase = 0x30000; } void softresetx86() diff --git a/src/x86.h b/src/x86.h index 2665249..9c0d328 100644 --- a/src/x86.h +++ b/src/x86.h @@ -40,7 +40,7 @@ typedef struct { uint32_t base; uint32_t limit; - uint8_t access; + uint8_t access, access2; uint16_t seg; uint32_t limit_low, limit_high; int checked; /*Non-zero if selector is known to be valid*/ @@ -90,6 +90,7 @@ struct int8_t ssegs; int8_t ismmx; int8_t abrt; + int8_t smi_pending; int _cycles; int cpu_recomp_ins; @@ -118,6 +119,8 @@ struct } CR0; uint16_t flags, eflags; + + uint32_t smbase; } cpu_state; #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) @@ -187,6 +190,7 @@ extern uint16_t cpu_cur_status; #define CPU_STATUS_STACK32 (1 << 1) #define CPU_STATUS_PMODE (1 << 2) #define CPU_STATUS_V86 (1 << 3) +#define CPU_STATUS_SMM (1 << 4) #define CPU_STATUS_FLAGS 0xff /*If the flags below are set in cpu_cur_status, they must be set in block->status. @@ -316,4 +320,8 @@ int idivl(int32_t val); extern int cpu_end_block_after_ins; +void x86_smi_trigger(void); +void x86_smi_enter(void); +void x86_smi_leave(void); + #endif diff --git a/src/x86_ops_io.h b/src/x86_ops_io.h index d427a7f..cd18934 100644 --- a/src/x86_ops_io.h +++ b/src/x86_ops_io.h @@ -5,6 +5,8 @@ static int opIN_AL_imm(uint32_t fetchdat) AL = inb(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -17,6 +19,8 @@ static int opIN_AX_imm(uint32_t fetchdat) AX = inw(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -31,6 +35,8 @@ static int opIN_EAX_imm(uint32_t fetchdat) EAX = inl(port); CLOCK_CYCLES(12); PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -43,10 +49,12 @@ static int opOUT_AL_imm(uint32_t fetchdat) outb(port, AL); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (port == 0x64) - return x86_was_reset; + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; + if (port == 0x64) + return x86_was_reset; return 0; } static int opOUT_AX_imm(uint32_t fetchdat) @@ -57,6 +65,8 @@ static int opOUT_AX_imm(uint32_t fetchdat) outw(port, AX); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -71,6 +81,8 @@ static int opOUT_EAX_imm(uint32_t fetchdat) outl(port, EAX); CLOCK_CYCLES(10); PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -82,6 +94,8 @@ static int opIN_AL_DX(uint32_t fetchdat) AL = inb(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -93,6 +107,8 @@ static int opIN_AX_DX(uint32_t fetchdat) AX = inw(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -106,6 +122,8 @@ static int opIN_EAX_DX(uint32_t fetchdat) EAX = inl(DX); CLOCK_CYCLES(12); PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -117,6 +135,8 @@ static int opOUT_AL_DX(uint32_t fetchdat) outb(DX, AL); CLOCK_CYCLES(11); PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return x86_was_reset; @@ -129,6 +149,8 @@ static int opOUT_AX_DX(uint32_t fetchdat) outw(DX, AX); CLOCK_CYCLES(11); PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; @@ -141,6 +163,8 @@ static int opOUT_EAX_DX(uint32_t fetchdat) check_io_perm(DX + 3); outl(DX, EAX); PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0); + if (cpu_state.smi_pending) + return 1; if (nmi && nmi_enable && nmi_mask) return 1; return 0; diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index 5301ef3..a93cfa7 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -470,3 +470,14 @@ static int op0F01_286(uint32_t fetchdat) return op0F01_common(fetchdat, 0, 1, 0); } + + +static int opRSM(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + x86_smi_leave(); + else + x86illegal(); + + return 1; +} diff --git a/src/x86seg.c b/src/x86seg.c index a69dfcd..566767a 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -10,6 +10,7 @@ #include "cpu.h" #include "config.h" #include "paths.h" +#include "i440bx.h" /*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ #define CS_ACCESSED @@ -61,6 +62,7 @@ void x86abort(const char *format, ...) static void seg_reset(x86seg *s) { s->access = (0 << 5) | 2; + s->access2 = 0; s->limit = 0xFFFF; s->limit_low = 0; s->limit_high = 0xffff; @@ -223,6 +225,7 @@ static void do_seg_load(x86seg *s, uint16_t *segdat) if (is386) s->base |= ((segdat[3] >> 8) << 24); s->access = segdat[2] >> 8; + s->access2 = segdat[3] & 0xf0; if ((segdat[2] & 0x1800) != 0x1000 || !(segdat[2] & (1 << 10))) /*expand-down*/ { @@ -255,6 +258,7 @@ static void do_seg_load(x86seg *s, uint16_t *segdat) static void do_seg_v86_init(x86seg *s) { s->access = (3 << 5) | 2; + s->access2 = 0; s->limit = 0xffff; s->limit_low = 0; s->limit_high = 0xffff; @@ -459,6 +463,7 @@ int loadseg(uint16_t seg, x86seg *s) else { s->access = (3 << 5) | 2; + s->access2 = 0; s->base = seg << 4; s->seg = seg; s->checked = 1; @@ -2946,3 +2951,198 @@ void sysexit(void) // pclog("sysexit to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); } + +void x86_smi_trigger(void) +{ + cpu_state.smi_pending = 1; +} + +static void smi_write_descriptor_cache(uint32_t addr, x86seg *seg) +{ + writememl(0, addr + 8, seg->seg | (seg->access << 16) | (seg->access2 << 24)); + writememl(0, addr + 4, seg->base); + writememl(0, addr, seg->limit); +} +static void smi_load_descriptor_cache(uint32_t addr, x86seg *seg) +{ + uint32_t temp; + + temp = readmeml(0, addr + 8); + seg->base = readmeml(0, addr + 4); + seg->limit = readmeml(0, addr); + seg->seg = temp & 0xffff; + seg->access = temp >> 16; + seg->access2 = temp >> 24; + if ((seg->access & 0x18) != 0x10 || !(seg->access & (1 << 2))) /*expand-down*/ + { + seg->limit_high = seg->limit; + seg->limit_low = 0; + } + else + { + seg->limit_high = (seg->access2 & 0x40) ? 0xffffffff : 0xffff; + seg->limit_low = seg->limit + 1; + } +} + +static void smi_load_smi_selector(x86seg *seg) +{ + seg->seg = 0; + seg->base = 0; + seg->limit = 0xffffffff; + seg->limit_low = 0; + seg->limit_high = 0xffffffff; + seg->access = (3 << 5) | 2; + seg->access2 = 0; +} + +void x86_smi_enter(void) +{ + uint32_t old_cr0 = cr0; + + if (smram_enable) + smram_enable(); + flushmmucache(); + + cpu_386_flags_rebuild(); + cpl_override = 1; + cr0 = 0; /*Disable MMU*/ + writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16)); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); + writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase); + writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000); + cpl_override = 0; + + cpu_cur_status = CPU_STATUS_SMM; + cpu_state.flags = 2; + cpu_state.eflags = 0; + cpu_state.pc = 0x8000; + cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); + dr[7] = 0x400; + smi_load_smi_selector(&cpu_state.seg_ds); + smi_load_smi_selector(&cpu_state.seg_es); + smi_load_smi_selector(&cpu_state.seg_fs); + smi_load_smi_selector(&cpu_state.seg_gs); + smi_load_smi_selector(&cpu_state.seg_ss); + cpu_state.seg_cs.seg = 0x3000; + cpu_state.seg_cs.base = cpu_state.smbase; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = (3 << 5) | 2; + + use32 = 0; + stack32 = 0; + +// pclog("x86_smi_enter\n"); +} + +void x86_smi_leave(void) +{ + uint32_t temp; + uint32_t new_cr0; + + cpl_override = 1; + new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc); + cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8); + temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4); + cpu_state.flags = temp & 0xffff; + cpu_state.eflags = temp >> 16; + cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0); + EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec); + ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8); + EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4); + ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0); + EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc); + EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8); + ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4); + EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0); + dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc); + dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8); + tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4); + ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0); + cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc); + cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8); + cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4); + cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0); + cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac); + cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); + cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28); + cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8); + cpl_override = 0; + + cpu_cur_status = 0; + if (cpu_state.seg_cs.access2 & 0x40) + { + cpu_cur_status |= CPU_STATUS_USE32; + use32 = 0x300; + } + else + use32 = 0; + if (cpu_state.seg_ss.access2 & 0x40) + { + cpu_cur_status |= CPU_STATUS_STACK32; + stack32 = 1; + } + else + stack32 = 0; + if (cr0 & 1) + { + cpu_cur_status |= CPU_STATUS_PMODE; + if (cpu_state.eflags & VM_FLAG) + cpu_cur_status |= CPU_STATUS_V86; + } + if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + + cr0 = new_cr0; + + if (smram_disable) + smram_disable(); + flushmmucache(); + +// pclog("x86_smi_leave\n"); +} From 8f04c11a76e1184a07567710e51f092f764b2a22 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 31 Oct 2020 20:34:52 +0000 Subject: [PATCH 0933/1050] Implement PIIX4 power management. Soft power off is currently 'implemented' by killing the emulator. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/i440bx.c | 16 ++ src/mem.c | 10 +- src/mem.h | 3 + src/piix.c | 191 +------------ src/piix.h | 40 +++ src/piix_pm.c | 414 +++++++++++++++++++++++++++++ src/piix_pm.h | 3 + 10 files changed, 493 insertions(+), 190 deletions(-) create mode 100644 src/piix_pm.c create mode 100644 src/piix_pm.h diff --git a/src/Makefile.am b/src/Makefile.am index 599fdc1..d514a98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,7 +37,7 @@ hdd_file.c headland.c i430lx.c i430fx.c i430hx.c i430vx.c i440fx.c i440bx.c ide. 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 laserxt.c lpt.c lpt_dac.c lpt_dss.c \ mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c mvp3.c \ -neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pc87307.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ +neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c pc.c pc87306.c pc87307.c pci.c pic.c piix.c piix_pm.c pit.c ppi.c ps1.c ps2.c ps2_mca.c \ ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c scsi_cd.c scsi_hd.c \ scsi_ibm.c scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c \ sound_azt2316a.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 \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 3d9401f..2926e83 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -24,7 +24,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pc87307.o pci.o pic.o \ - piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ + piix.o piix_pm.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.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 \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 7b7c632..fd03280 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -24,7 +24,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o laserxt.o lpt.o lpt_dac.o lpt_dss.o mca.o mcr.o \ mem.o mem_bios.o mfm_at.o mfm_xebec.o model.o mouse.o mouse_msystems.o mouse_ps2.o mouse_serial.o \ mvp3.o neat.o nmi.o nvr.o nvr_tc8521.o olivetti_m24.o opti495.o paths.o pc.o pc87306.o pc87307.o pci.o pic.o \ - piix.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ + piix.o piix_pm.o pit.o ppi.o ps1.o ps2.o ps2_mca.o ps2_nvr.o pzx.o rom.o rtc.o rtc_tc8521.o scamp.o scat.o scsi.o \ scsi_53c400.o scsi_aha1540.o scsi_cd.o scsi_hd.o scsi_ibm.o scsi_zip.o serial.o sio.o sis496.o sl82c460.o \ sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.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 \ diff --git a/src/i440bx.c b/src/i440bx.c index 4a1304e..910f71b 100644 --- a/src/i440bx.c +++ b/src/i440bx.c @@ -145,6 +145,19 @@ uint8_t i440bx_read(int func, int addr, void *priv) return card_i440bx[addr]; } +static void i440bx_smram_enable(void) +{ +// pclog("i440bx_smram_enable: 440BX 0x72=%02x\n", card_i440bx[0x72]); + if (card_i440bx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void i440bx_smram_disable(void) +{ +// pclog("i440bx_smram_disable: 440BX 0x72=%02x\n", card_i440bx[0x72]); + if (card_i440bx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void i440bx_init() { pci_add_specific(0, i440bx_read, i440bx_write, NULL); @@ -162,6 +175,9 @@ void i440bx_init() card_i440bx[0x72] = 0x02; card_i440bx[0x73] = 0x38; card_i440bx[0x7a] = 0x02; /*AGP disabled*/ + + smram_enable = i440bx_smram_enable; + smram_disable = i440bx_smram_disable; } void i440bx_reset() diff --git a/src/mem.c b/src/mem.c index fc53ab0..98dc738 100644 --- a/src/mem.c +++ b/src/mem.c @@ -51,6 +51,9 @@ uint64_t *byte_code_present_mask; uint32_t mem_logical_addr; +void (*smram_enable)(void); +void (*smram_disable)(void); + int mmuflush=0; int mmu_perm=4; @@ -1420,6 +1423,9 @@ void mem_init() page_lookup = malloc((1 << 20) * sizeof(page_t *)); memset(ff_array, 0xff, sizeof(ff_array)); + + smram_enable = NULL; + smram_disable = NULL; } void mem_alloc() @@ -1462,7 +1468,7 @@ void mem_alloc() memset(_mem_state, 0, sizeof(_mem_state)); 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(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); 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) @@ -1479,7 +1485,7 @@ void mem_alloc() } } 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(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, 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); diff --git a/src/mem.h b/src/mem.h index 34d5194..bd733e7 100644 --- a/src/mem.h +++ b/src/mem.h @@ -236,4 +236,7 @@ void mmu_invalidate(uint32_t addr); int loadbios(); extern int purgeable_page_count; + +extern void (*smram_enable)(void); +extern void (*smram_disable)(void); #endif diff --git a/src/piix.c b/src/piix.c index 05214ea..184c748 100644 --- a/src/piix.c +++ b/src/piix.c @@ -13,8 +13,8 @@ #include "mem.h" #include "pci.h" #include "pic.h" - #include "piix.h" +#include "piix_pm.h" enum { @@ -23,156 +23,12 @@ enum TYPE_PIIX4 }; -static struct -{ - int type; - - /*PIIX4*/ - uint8_t card_pm[256]; - - uint16_t pmba; - struct - { - uint64_t timer_offset; - } pm; - - uint16_t smbba; - struct - { - uint8_t host_ctrl; - } smbus; - - uint8_t port_92; -} piix; - +static piix_t piix; static uint8_t card_piix[256], card_piix_ide[256]; static sff_busmaster_t piix_busmaster[2]; static uint8_t piix_rc = 0; static void (*piix_nb_reset)(); -static void piix_pm_write(uint16_t port, uint8_t val, void *p) -{ -// pclog("piix_pm_write: port=%04x val=%02x\n", port, val); -} -static uint8_t piix_pm_read(uint16_t port, void *p) -{ - uint8_t ret = 0xff; - - switch (port & 0x3f) - { - case 0x02: case 0x03: - ret = 0; - break; - - case 0x04: case 0x05: - ret = 0; - break; - - case 0x08: case 0x09: case 0x0a: case 0x0b: - { - uint64_t timer = tsc - piix.pm.timer_offset; - uint32_t pm_timer = (timer * 3579545) / cpu_get_speed(); - - ret = pm_timer >> ((port & 3) * 8); - break; - } - - case 0x0e: case 0x0f: - ret = 0; - break; - - case 0x10: case 0x11: - ret = 0; - break; - - case 0x18: case 0x19: - ret = 0; - break; - - case 0x20: case 0x21: - ret = 0; - break; - - case 0x28: case 0x29: case 0x2a: case 0x2b: - ret = 0; - break; - - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - ret = 0; - break; - - case 0x30: - ret = 0; - break; - case 0x31: - ret = 0; - break; - case 0x32: - ret = 0; - break; - -// default: -// fatal("piix_pm_read: unknown read %04x\n", port); - } - - return ret; -} - -static void piix_smbus_write(uint16_t port, uint8_t val, void *p) -{ -// pclog("piix_smbus_write: port=%04x val=%02x\n", port, val); - - switch (port & 0xf) - { - case 0x2: - piix.smbus.host_ctrl = (val & 0x5f) | (piix.smbus.host_ctrl & 0x40); - break; - } -} -static uint8_t piix_smbus_read(uint16_t port, void *p) -{ - uint8_t ret = 0xff; - - switch (port & 0x0f) - { - case 0x0: - ret = 0; - break; - - case 0x2: - ret = piix.smbus.host_ctrl; - break; - - case 0x5: - ret = 0; - break; - -// default: -// fatal("piix_smbus_read: unknown read %04x\n", port); - } - - return ret; -} - -static void pm_clear_io(void) -{ - io_removehandler(piix.pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, NULL); - io_removehandler(piix.smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, NULL); -} -static void pm_set_io(void) -{ -// pclog("pm_set_io: %02x %04x\n", piix.card_pm[0x04], piix.smbba); - if ((piix.card_pm[0x04] & 0x01) && piix.pmba) - { -// pclog("PMBA=%04x\n", piix.pmba); - io_sethandler(piix.pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, NULL); - } - if ((piix.card_pm[0x04] & 0x01) && piix.smbba) - { -// pclog("SMBBA=%04x\n", piix.smbba); - io_sethandler(piix.smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, NULL); - } -} void piix_write(int func, int addr, uint8_t val, void *priv) { @@ -241,34 +97,7 @@ void piix_write(int func, int addr, uint8_t val, void *priv) } else if (func == 3) /*PM*/ { - switch (addr) - { - case 0x04: - pm_clear_io(); - piix.card_pm[0x04] = val & 1; - pm_set_io(); - break; - case 0x40: - pm_clear_io(); - piix.pmba = (piix.pmba & 0xff00) | (val & 0xc0); - pm_set_io(); - break; - case 0x41: - pm_clear_io(); - piix.pmba = (piix.pmba & 0xc0) | (val << 8); - pm_set_io(); - break; - case 0x90: - pm_clear_io(); - piix.smbba = (piix.smbba & 0xff00) | (val & 0xf0); - pm_set_io(); - break; - case 0x91: - pm_clear_io(); - piix.smbba = (piix.smbba & 0xf0) | (val << 8); - pm_set_io(); - break; - } + piix_pm_pci_write(addr, val, &piix); } else { @@ -329,7 +158,7 @@ uint8_t piix_read(int func, int addr, void *priv) else if (func == 2) /*USB*/ return 0xff; /*Not implemented*/ else if (func == 3) - return piix.card_pm[addr]; + return piix_pm_pci_read(addr, &piix); else return card_piix[addr]; } @@ -376,6 +205,7 @@ static void piix_92_write(uint16_t port, uint8_t val, void *p) piix.port_92 = val; } + void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -443,15 +273,6 @@ void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_ card_piix_ide[0x02] = 0x11; card_piix_ide[0x03] = 0x71; /*82371EB (PIIX4)*/ - memset(&piix.card_pm, 0, sizeof(piix.card_pm)); - piix.card_pm[0x00] = 0x86; piix.card_pm[0x01] = 0x80; /*Intel*/ - piix.card_pm[0x02] = 0x13; piix.card_pm[0x03] = 0x71; /*82371EB (PIIX4)*/ - piix.card_pm[0x06] = 0x80; piix.card_pm[0x07] = 0x02; - piix.card_pm[0x09] = 0x00; piix.card_pm[0x0a] = 0x80; piix.card_pm[0x0b] = 0x06; /*Bridge device*/ - piix.card_pm[0x3d] = 0x01; /*IRQA*/ - piix.card_pm[0x40] = 0x01; - piix.card_pm[0x90] = 0x01; - piix.pm.timer_offset = 0; - io_sethandler(0x0092, 0x0001, piix_92_read, NULL, NULL, piix_92_write, NULL, NULL, NULL); + piix_pm_init(&piix); } diff --git a/src/piix.h b/src/piix.h index 08b0032..1ac8884 100644 --- a/src/piix.h +++ b/src/piix.h @@ -1,2 +1,42 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); + +typedef struct piix_t +{ + int type; + + /*PIIX4*/ + uint8_t card_pm[256]; + + uint16_t pmba; + struct + { + uint8_t apmc, apms; + + uint64_t timer_offset; + + uint16_t pmsts; + uint16_t pmen; + uint16_t pmcntrl; + uint32_t devctl; + uint32_t devsts; + uint16_t glbsts; + uint16_t gpen; + uint16_t gpsts; + uint32_t pcntrl; + uint16_t glben; + uint32_t glbctl; + uint32_t gporeg; + + int dev13_enable; + uint16_t dev13_base, dev13_size; + } pm; + + uint16_t smbba; + struct + { + uint8_t host_ctrl; + } smbus; + + uint8_t port_92; +} piix_t; diff --git a/src/piix_pm.c b/src/piix_pm.c new file mode 100644 index 0000000..ac62dec --- /dev/null +++ b/src/piix_pm.c @@ -0,0 +1,414 @@ +#include "ibm.h" +#include "io.h" +#include "piix.h" +#include "piix_pm.h" +#include "x86.h" + +#define DEVSTS_TRP_STS_DEV13 (1 << 29) + +#define DEVCTL_TRP_EN_DEV13 (1 << 25) + +#define GLBSTS_APM_STS (1 << 5) + +static uint8_t dev13_read(uint16_t addr, void *p) +{ + piix_t *piix = (piix_t *)p; + +// pclog("dev13_read: addr=%04x %08x\n", addr, piix.pm.devctl); + if (piix->pm.devctl & DEVCTL_TRP_EN_DEV13) + { + piix->pm.devsts |= DEVSTS_TRP_STS_DEV13; + x86_smi_trigger(); + } + return 0xff; +} +static void dev13_write(uint16_t addr, uint8_t val, void *p) +{ + piix_t *piix = (piix_t *)p; + +// pclog("dev13_write: addr=%04x val=%02x %08x\n", addr, val, piix.pm.devctl); + if (piix->pm.devctl & DEVCTL_TRP_EN_DEV13) + { + piix->pm.devsts |= DEVSTS_TRP_STS_DEV13; + x86_smi_trigger(); + } +} + +static void dev13_recalc(piix_t *piix) +{ + if (piix->pm.dev13_enable) + io_removehandler(piix->pm.dev13_base, piix->pm.dev13_size, + dev13_read, NULL, NULL, + dev13_write, NULL, NULL, piix); + piix->pm.dev13_base = piix->card_pm[0x70] | (piix->card_pm[0x71] << 8); + piix->pm.dev13_size = (piix->card_pm[0x72] & 0xf) + 1; + piix->pm.dev13_enable = piix->card_pm[0x72] & 0x10; + if (piix->pm.dev13_enable) + io_sethandler(piix->pm.dev13_base, piix->pm.dev13_size, + dev13_read, NULL, NULL, + dev13_write, NULL, NULL, piix); +} + +static void piix_pm_write(uint16_t port, uint8_t val, void *p) +{ + piix_t *piix = (piix_t *)p; + +// pclog("piix_pm_write: port=%04x val=%02x\n", port, val); + switch (port & 0x3f) + { + case 0x00: + piix->pm.pmsts &= ~(val & 0x31); + break; + case 0x01: + piix->pm.pmsts &= ~((val & 0x8d) << 8); + break; + + case 0x02: + piix->pm.pmen = (piix->pm.pmen & ~0xff) | (val & 0x21); + break; + case 0x03: + piix->pm.pmen = (piix->pm.pmen & ~0xff00) | ((val & 0x05) << 8); + break; + + case 0x04: + piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff) | (val & 0x03); + break; + case 0x05: + pclog("PM reg 5 write %02x\n", val); + if (val & 0x20) + { + pclog("PIIX transition to power state %i\n", (val >> 2) & 7); + if (val == 0x20) + fatal("Power off\n"); + } + piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff00) | ((val & 0x1c) << 8); + break; + + case 0x0c: case 0x0d: + piix->pm.gpsts &= ~(val << ((port & 1) * 8)); + break; + + case 0x0e: + piix->pm.pmen = (piix->pm.pmen & ~0xff) | (val & 0x01); + break; + case 0x0f: + piix->pm.pmen = (piix->pm.pmen & ~0xff00) | ((val & 0x0f) << 8); + break; + + case 0x10: + piix->pm.pcntrl = (piix->pm.pcntrl & ~0xff) | (val & 0x1e); + break; + case 0x11: + piix->pm.pcntrl = (piix->pm.pcntrl & ~0xff00) | ((val & 0x3e) << 8); + break; + + case 0x18: + piix->pm.glbsts &= ~(val & 0x25); + break; + case 0x19: + piix->pm.glbsts &= ~((val & 0x0d) << 8); + break; + + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + piix->pm.devsts &= ~(val << ((port & 3) * 8)); + break; + + case 0x20: + piix->pm.glben = (piix->pm.glben & ~0xff) | (val & 0x01); + break; + case 0x21: + piix->pm.glben = (piix->pm.glben & ~0xff00) | ((val & 0x0f) << 8); + break; + + case 0x28: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff) | (val & 0x05); + break; + case 0x29: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff00) | ((val & 0xff) << 8); + break; + case 0x2a: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff0000) | ((val & 0x01) << 16); + break; + case 0x2b: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff000000) | ((val & 0x07) << 24); + break; + + case 0x2c: + piix->pm.devctl = (piix->pm.devctl & ~0xff) | val; + break; + case 0x2d: + piix->pm.devctl = (piix->pm.devctl & ~0xff00) | (val << 8); + break; + case 0x2e: + piix->pm.devctl = (piix->pm.devctl & ~0xff0000) | (val << 16); + break; + case 0x2f: + piix->pm.devctl = (piix->pm.devctl & ~0xff000000) | ((val & 0x0f) << 24); + break; + + case 0x34: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff) | val; + break; + case 0x35: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff00) | (val << 8); + break; + case 0x36: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff0000) | (val << 16); + break; + case 0x37: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff000000) | (val << 24); + break; + } +} +static uint8_t piix_pm_read(uint16_t port, void *p) +{ + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; + + switch (port & 0x3f) + { + case 0x00: case 0x01: + ret = piix->pm.pmsts >> ((port & 1) * 8); + break; + + case 0x02: case 0x03: + ret = piix->pm.pmen >> ((port & 1) * 8); + break; + + case 0x04: case 0x05: + ret = piix->pm.pmcntrl >> ((port & 1) * 8); + break; + + case 0x08: case 0x09: case 0x0a: case 0x0b: + { + uint64_t timer = tsc - piix->pm.timer_offset; + uint32_t pm_timer = (timer * 3579545) / cpu_get_speed(); + + ret = pm_timer >> ((port & 3) * 8); + break; + } + + case 0x0c: case 0x0d: + ret = piix->pm.gpsts >> ((port & 1) * 8); + break; + + case 0x0e: case 0x0f: + ret = piix->pm.pmen >> ((port & 1) * 8); + break; + + case 0x10: case 0x11: case 0x12: case 0x13: + ret = piix->pm.pcntrl >> ((port & 3) * 8); + break; + + case 0x14: + ret = 0; + break; + case 0x15: + ret = 0; + break; + + case 0x18: case 0x19: + ret = piix->pm.glbsts >> ((port & 1) * 8); + break; + + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + ret = piix->pm.devsts >> ((port & 3) * 8); + break; + + case 0x20: case 0x21: + ret = piix->pm.glben >> ((port & 1) * 8); + break; + + case 0x28: case 0x29: case 0x2a: case 0x2b: + ret = piix->pm.glbctl >> ((port & 3) * 8); + break; + + case 0x2c: case 0x2d: case 0x2e: case 0x2f: + ret = piix->pm.devctl >> ((port & 3) * 8); + break; + + case 0x30: + ret = 0x00; + break; + case 0x31: + ret = 0x00; + break; + case 0x32: + /*GA686BX - bit 1 = low battery*/ + ret = 0x00; + break; + + case 0x34: case 0x35: case 0x36: case 0x37: + ret = piix->pm.gporeg >> ((port & 3) * 8); + break; + +// default: +// fatal("piix_pm_read: unknown read %04x\n", port); + } + +// pclog("piix_pm_read: port=%04x val=%02x\n", port, ret); + return ret; +} + +static void piix_smbus_write(uint16_t port, uint8_t val, void *p) +{ + piix_t *piix = (piix_t *)p; +// pclog("piix_smbus_write: port=%04x val=%02x\n", port, val); + + switch (port & 0xf) + { + case 0x2: + piix->smbus.host_ctrl = (val & 0x5f) | (piix->smbus.host_ctrl & 0x40); + break; + } +} +static uint8_t piix_smbus_read(uint16_t port, void *p) +{ + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; + + switch (port & 0x0f) + { + case 0x0: + ret = 0; + break; + + case 0x2: + ret = piix->smbus.host_ctrl; + break; + + case 0x5: + ret = 0; + break; + +// default: +// fatal("piix_smbus_read: unknown read %04x\n", port); + } + + return ret; +} + +static uint8_t piix_apm_read(uint16_t port, void *p) +{ + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; + + switch (port) + { + case 0xb2: + ret = piix->pm.apmc; + break; + + case 0xb3: + ret = piix->pm.apms; + break; + } +// pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); + return ret; +} +static void piix_apm_write(uint16_t port, uint8_t val, void *p) +{ + piix_t *piix = (piix_t *)p; + +// pclog("piix_apm_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0xb2: + piix->pm.apmc = val; + if (piix->card_pm[0x5b] & (1 << 1)) + { + piix->pm.glbsts |= GLBSTS_APM_STS; +// pclog("APMC write causes SMI\n"); + x86_smi_trigger(); + } + break; + + case 0xb3: + piix->pm.apms = val; + break; + } +} + +static void pm_clear_io(piix_t *piix) +{ + io_removehandler(piix->pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, piix); + io_removehandler(piix->smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, piix); +} +static void pm_set_io(piix_t *piix) +{ +// pclog("pm_set_io: %02x %04x\n", piix.card_pm[0x04], piix.smbba); + if ((piix->card_pm[0x04] & 0x01) && piix->pmba) + { +// pclog("PMBA=%04x\n", piix.pmba); + io_sethandler(piix->pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, piix); + } + if ((piix->card_pm[0x04] & 0x01) && piix->smbba) + { +// pclog("SMBBA=%04x\n", piix.smbba); + io_sethandler(piix->smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, piix); + } +} + +void piix_pm_pci_write(int addr, uint8_t val, void *p) +{ + piix_t *piix = (piix_t *)p; + + switch (addr) + { + case 0x04: + pm_clear_io(piix); + piix->card_pm[0x04] = val & 1; + pm_set_io(piix); + break; + case 0x40: + pm_clear_io(piix); + piix->pmba = (piix->pmba & 0xff00) | (val & 0xc0); + pm_set_io(piix); + break; + case 0x41: + pm_clear_io(piix); + piix->pmba = (piix->pmba & 0xc0) | (val << 8); + pm_set_io(piix); + break; + case 0x58: case 0x59: case 0x5b: case 0x5c: + piix->card_pm[addr] = val; + break; + case 0x70: case 0x71: case 0x72: + piix->card_pm[addr] = val; + dev13_recalc(piix); + break; + case 0x90: + pm_clear_io(piix); + piix->smbba = (piix->smbba & 0xff00) | (val & 0xf0); + pm_set_io(piix); + break; + case 0x91: + pm_clear_io(piix); + piix->smbba = (piix->smbba & 0xf0) | (val << 8); + pm_set_io(piix); + break; + } +} +uint8_t piix_pm_pci_read(int addr, void *p) +{ + piix_t *piix = (piix_t *)p; + + return piix->card_pm[addr]; +} + +void piix_pm_init(piix_t *piix) +{ + memset(&piix->card_pm, 0, sizeof(piix->card_pm)); + piix->card_pm[0x00] = 0x86; piix->card_pm[0x01] = 0x80; /*Intel*/ + piix->card_pm[0x02] = 0x13; piix->card_pm[0x03] = 0x71; /*82371EB (PIIX4)*/ + piix->card_pm[0x06] = 0x80; piix->card_pm[0x07] = 0x02; + piix->card_pm[0x09] = 0x00; piix->card_pm[0x0a] = 0x80; piix->card_pm[0x0b] = 0x06; /*Bridge device*/ + piix->card_pm[0x3d] = 0x01; /*IRQA*/ + piix->card_pm[0x40] = 0x01; + piix->card_pm[0x90] = 0x01; + piix->pm.timer_offset = 0; + piix->pm.gporeg = 0x7fffbfff; + + io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, piix); +} diff --git a/src/piix_pm.h b/src/piix_pm.h new file mode 100644 index 0000000..dcc06f6 --- /dev/null +++ b/src/piix_pm.h @@ -0,0 +1,3 @@ +void piix_pm_init(piix_t *piix); +void piix_pm_pci_write(int addr, uint8_t val, void *p); +uint8_t piix_pm_pci_read(int addr, void *p); From 00034c1ece976d18304a217daae76b267139f689 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 31 Oct 2020 22:06:09 +0000 Subject: [PATCH 0934/1050] Implement API to terminate current emulator session from within main emulator thread (ie soft power off). --- src/386_dynarec.c | 2 +- src/ibm.h | 2 ++ src/pc.c | 2 ++ src/piix_pm.c | 5 ++++- src/wx-app.cc | 11 +++++++++++ src/wx-app.h | 2 ++ src/wx-sdl2.c | 8 ++++++++ src/wx-utils.cc | 7 +++++++ src/wx-utils.h | 1 + src/x86.h | 1 + 10 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index da47b20..895c745 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -566,7 +566,7 @@ static inline void exec_recompiler(void) } -static int cycles_main = 0; +int cycles_main = 0; void exec386_dynarec(int cycs) { uint8_t temp; diff --git a/src/ibm.h b/src/ibm.h index 90f24cb..a7925c3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -444,3 +444,5 @@ void saveconfig_global_only(); #define MIN(a, b) ((a) < (b) ? (a) : (b)) void ide_padstr(char *str, const char *src, int len); + +void stop_emulation_now(void); diff --git a/src/pc.c b/src/pc.c index 4779266..49c43af 100644 --- a/src/pc.c +++ b/src/pc.c @@ -489,6 +489,8 @@ void resetpchard() sound_update_buf_length(); cpu_set_turbo(1); + + cycles = cycles_main = 0; } 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/piix_pm.c b/src/piix_pm.c index ac62dec..a3947b7 100644 --- a/src/piix_pm.c +++ b/src/piix_pm.c @@ -79,7 +79,10 @@ static void piix_pm_write(uint16_t port, uint8_t val, void *p) { pclog("PIIX transition to power state %i\n", (val >> 2) & 7); if (val == 0x20) - fatal("Power off\n"); + { + pclog("Power off\n"); + stop_emulation_now(); + } } piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff00) | ((val & 0x1c) << 8); break; diff --git a/src/wx-app.cc b/src/wx-app.cc index ca70c16..cbe4f17 100644 --- a/src/wx-app.cc +++ b/src/wx-app.cc @@ -33,6 +33,7 @@ extern void InitXmlResource(); wxDEFINE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); wxDEFINE_EVENT(WX_EXIT_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); +wxDEFINE_EVENT(WX_STOP_EMULATION_NOW_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); wxDEFINE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); @@ -89,6 +90,7 @@ Frame::Frame(App* app, const wxString& title, const wxPoint& pos, Bind(WX_EXIT_EVENT, &Frame::OnExitEvent, this); Bind(WX_EXIT_COMPLETE_EVENT, &Frame::OnExitCompleteEvent, this); Bind(WX_STOP_EMULATION_EVENT, &Frame::OnStopEmulationEvent, this); + Bind(WX_STOP_EMULATION_NOW_EVENT, &Frame::OnStopEmulationNowEvent, this); Bind(WX_CALLBACK_EVENT, &Frame::OnCallbackEvent, this); #ifdef _WIN32 Bind(WX_WIN_SEND_MESSAGE_EVENT, &Frame::OnWinSendMessageEvent, this); @@ -151,6 +153,15 @@ void Frame::OnStopEmulationEvent(wxCommandEvent& event) } } +void Frame::OnStopEmulationNowEvent(wxCommandEvent& event) +{ + stop_emulation(); + if (!config_override) + ShowConfigSelection(); + else + Quit(1); +} + void Frame::OnShowWindowEvent(wxCommandEvent& event) { wxWindow* window = (wxWindow*)event.GetEventObject(); diff --git a/src/wx-app.h b/src/wx-app.h index 803f5d1..4c6d29a 100644 --- a/src/wx-app.h +++ b/src/wx-app.h @@ -14,6 +14,7 @@ class PopupMenuEvent; wxDECLARE_EVENT(WX_CALLBACK_EVENT, CallbackEvent); wxDECLARE_EVENT(WX_EXIT_EVENT, wxCommandEvent); wxDECLARE_EVENT(WX_STOP_EMULATION_EVENT, wxCommandEvent); +wxDECLARE_EVENT(WX_STOP_EMULATION_NOW_EVENT, wxCommandEvent); wxDECLARE_EVENT(WX_EXIT_COMPLETE_EVENT, wxCommandEvent); wxDECLARE_EVENT(WX_SHOW_WINDOW_EVENT, wxCommandEvent); wxDECLARE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); @@ -155,6 +156,7 @@ private: void OnExitEvent(wxCommandEvent& event); void OnExitCompleteEvent(wxCommandEvent& event); void OnStopEmulationEvent(wxCommandEvent& event); + void OnStopEmulationNowEvent(wxCommandEvent& event); void OnShowWindowEvent(wxCommandEvent& event); void OnPopupMenuEvent(PopupMenuEvent& event); void OnCallbackEvent(CallbackEvent& event); diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 3ff93fb..0813929 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -223,6 +223,14 @@ int mainthread(void* param) return TRUE; } +void stop_emulation_now(void) +{ + /*Deduct a sufficiently large number of cycles that no instructions will + run before the main thread is terminated*/ + cycles -= 99999999; + wx_stop_emulation_now(ghwnd); +} + int dir_exists(char* path) { return wx_dir_exists(path); diff --git a/src/wx-utils.cc b/src/wx-utils.cc index 819475e..f62a8ec 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -449,6 +449,13 @@ void wx_stop_emulation(void* window) wxQueueEvent((wxWindow*)window, event); } +void wx_stop_emulation_now(void* window) +{ + wxCommandEvent* event = new wxCommandEvent(WX_STOP_EMULATION_NOW_EVENT, wxID_ANY); + event->SetEventObject((wxWindow*)window); + wxQueueEvent((wxWindow*)window, event); +} + int wx_yield() { return wxYield(); diff --git a/src/wx-utils.h b/src/wx-utils.h index 631f6d1..0b12970 100644 --- a/src/wx-utils.h +++ b/src/wx-utils.h @@ -52,6 +52,7 @@ extern "C" { void wx_exit(void* window, int value); void wx_stop_emulation(void* window); + void wx_stop_emulation_now(void* window); void* wx_createtimer(void (*fn)()); void wx_starttimer(void* timer, int milliseconds, int once); diff --git a/src/x86.h b/src/x86.h index 9c0d328..12125e4 100644 --- a/src/x86.h +++ b/src/x86.h @@ -126,6 +126,7 @@ struct #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) #define cycles cpu_state._cycles +extern int cycles_main; #define cr0 cpu_state.CR0.l #define msw cpu_state.CR0.w From 93756d3f011e18bd3884018bc28db09a7f72d570 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Nov 2020 14:41:39 +0000 Subject: [PATCH 0935/1050] SMM fixes --- src/x86seg.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 566767a..669001e 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -3060,7 +3060,7 @@ void x86_smi_enter(void) cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_low = 0; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = (3 << 5) | 2; + cpu_state.seg_cs.access = (0 << 5) | 2; use32 = 0; stack32 = 0; @@ -3112,34 +3112,34 @@ void x86_smi_leave(void) cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8); cpl_override = 0; + cr0 = new_cr0; + cpu_cur_status = 0; - if (cpu_state.seg_cs.access2 & 0x40) - { - cpu_cur_status |= CPU_STATUS_USE32; - use32 = 0x300; - } - else - use32 = 0; - if (cpu_state.seg_ss.access2 & 0x40) - { - cpu_cur_status |= CPU_STATUS_STACK32; - stack32 = 1; - } - else - stack32 = 0; + use32 = stack32 = 0; if (cr0 & 1) { cpu_cur_status |= CPU_STATUS_PMODE; if (cpu_state.eflags & VM_FLAG) cpu_cur_status |= CPU_STATUS_V86; + else + { + if (cpu_state.seg_cs.access2 & 0x40) + { + cpu_cur_status |= CPU_STATUS_USE32; + use32 = 0x300; + } + if (cpu_state.seg_ss.access2 & 0x40) + { + cpu_cur_status |= CPU_STATUS_STACK32; + stack32 = 1; + } + } } if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) cpu_cur_status |= CPU_STATUS_NOTFLATDS; if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) cpu_cur_status |= CPU_STATUS_NOTFLATSS; - cr0 = new_cr0; - if (smram_disable) smram_disable(); flushmmucache(); From 38cee364d3592cc8e847e4429245365f7f42e686 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Nov 2020 14:46:56 +0000 Subject: [PATCH 0936/1050] Add basic APM functionality for PIIX/PIIX3 and i430FX, i430VX, i430HX and i440FX chipsets. --- src/i430fx.c | 38 ++++++++++++++++++++++++ src/i430hx.c | 39 ++++++++++++++++++++++++- src/i430vx.c | 39 ++++++++++++++++++++++++- src/i440fx.c | 38 ++++++++++++++++++++++++ src/intel.c | 2 +- src/piix.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/piix_pm.c | 6 ++-- 7 files changed, 234 insertions(+), 9 deletions(-) diff --git a/src/i430fx.c b/src/i430fx.c index a562447..678c824 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -106,6 +106,30 @@ void i430fx_write(int func, int addr, uint8_t val, void *priv) i430fx_map(0xec000, 0x04000, val >> 4); pclog("i430fx_write : PAM6 write %02X\n", val); break; + + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i430fx[0x72] & 0x08); + } + if ((card_i430fx[0x72] ^ val) & 0x40) + { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; } card_i430fx[addr] = val; @@ -119,6 +143,17 @@ uint8_t i430fx_read(int func, int addr, void *priv) return card_i430fx[addr]; } +static void i430fx_smram_enable(void) +{ + if (card_i430fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void i430fx_smram_disable(void) +{ + if (card_i430fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void i430fx_init() { pci_add_specific(0, i430fx_read, i430fx_write, NULL); @@ -141,6 +176,9 @@ void i430fx_init() card_i430fx[0x72] = 0x02; // card_i430fx[0x74] = 0x0e; // card_i430fx[0x78] = 0x23; + + smram_enable = i430fx_smram_enable; + smram_disable = i430fx_smram_disable; } void i430fx_reset() diff --git a/src/i430hx.c b/src/i430hx.c index 0871ca9..466b002 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -106,6 +106,30 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) i430hx_map(0xec000, 0x04000, val >> 4); pclog("i430hx_write : PAM6 write %02X\n", val); break; + + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430hx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i430hx[0x72] & 0x08); + } + if ((card_i430hx[0x72] ^ val) & 0x40) + { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; } card_i430hx[addr] = val; @@ -119,7 +143,17 @@ uint8_t i430hx_read(int func, int addr, void *priv) return card_i430hx[addr]; } - +static void i430hx_smram_enable(void) +{ + if (card_i430hx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void i430hx_smram_disable(void) +{ + if (card_i430hx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void i430hx_init() { pci_add_specific(0, i430hx_read, i430hx_write, NULL); @@ -141,6 +175,9 @@ void i430hx_init() card_i430hx[0x64] = card_i430hx[0x5F] = 0x02; card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02; card_i430hx[0x68] = 0x11; + + smram_enable = i430hx_smram_enable; + smram_disable = i430hx_smram_disable; } void i430hx_reset() diff --git a/src/i430vx.c b/src/i430vx.c index 5d97d23..fde2258 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -105,6 +105,30 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) i430vx_map(0xec000, 0x04000, val >> 4); pclog("i430vx_write : PAM6 write %02X\n", val); break; + + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430vx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i430vx[0x72] & 0x08); + } + if ((card_i430vx[0x72] ^ val) & 0x40) + { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; } card_i430vx[addr] = val; @@ -118,7 +142,17 @@ uint8_t i430vx_read(int func, int addr, void *priv) return card_i430vx[addr]; } - +static void i430vx_smram_enable(void) +{ + if (card_i430vx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void i430vx_smram_disable(void) +{ + if (card_i430vx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void i430vx_init() { pci_add_specific(0, i430vx_read, i430vx_write, NULL); @@ -141,6 +175,9 @@ void i430vx_init() card_i430vx[0x72] = 0x02; card_i430vx[0x74] = 0x0e; card_i430vx[0x78] = 0x23; + + smram_enable = i430vx_smram_enable; + smram_disable = i430vx_smram_disable; } void i430vx_reset() diff --git a/src/i440fx.c b/src/i440fx.c index c95c79c..87d1dfe 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -106,6 +106,30 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) i440fx_map(0xec000, 0x04000, val >> 4); pclog("i440fx_write : PAM6 write %02X\n", val); break; + + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i440fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i440fx[0x72] & 0x08); + } + if ((card_i440fx[0x72] ^ val) & 0x40) + { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; } card_i440fx[addr] = val; @@ -119,6 +143,17 @@ uint8_t i440fx_read(int func, int addr, void *priv) return card_i440fx[addr]; } +static void i440fx_smram_enable(void) +{ + if (card_i440fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void i440fx_smram_disable(void) +{ + if (card_i440fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void i440fx_init() { pci_add_specific(0, i440fx_read, i440fx_write, NULL); @@ -137,6 +172,9 @@ void i440fx_init() card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = 0x01; card_i440fx[0x71] = 0x10; card_i440fx[0x72] = 0x02; + + smram_enable = i440fx_smram_enable; + smram_disable = i440fx_smram_disable; } void i440fx_reset() diff --git a/src/intel.c b/src/intel.c index 2010cc3..3d66644 100644 --- a/src/intel.c +++ b/src/intel.c @@ -127,7 +127,7 @@ uint8_t endeavor_brdconfig(uint16_t port, void *p) temp = 0x10; else temp = 0x10; // TODO: how are the overdrive processors configured? - return 0xe2 | temp; + return 0xe0 | temp; } return 0; } diff --git a/src/piix.c b/src/piix.c index 184c748..35eebe2 100644 --- a/src/piix.c +++ b/src/piix.c @@ -29,6 +29,12 @@ static sff_busmaster_t piix_busmaster[2]; static uint8_t piix_rc = 0; static void (*piix_nb_reset)(); +#define REG_SMIEN 0xa2 +#define REG_SMIREQ 0xaa + +#define SMIEN_APMC (1 << 7) +#define SMIREQ_RAPMC (1 << 7) + void piix_write(int func, int addr, uint8_t val, void *priv) { @@ -139,6 +145,21 @@ void piix_write(int func, int addr, uint8_t val, void *priv) else pci_set_irq_routing(PCI_INTD, val & 0xf); break; + case REG_SMIREQ: + if (piix.type <= TYPE_PIIX3) + { + card_piix[addr] &= val; + return; + } + break; + case REG_SMIREQ+1: + if (piix.type <= TYPE_PIIX3) + { + card_piix[addr] &= val; + return; + } + break; + } card_piix[addr] = val; } @@ -179,8 +200,11 @@ void piix_rc_write(uint16_t port, uint8_t val, void *p) keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ ide_reset_devices(); piix.pm.timer_offset = tsc; + resetx86(); + piix.pm.apmc = piix.pm.apms = 0; } - resetx86(); + else + softresetx86(); } piix_rc = val & ~4; @@ -205,9 +229,53 @@ static void piix_92_write(uint16_t port, uint8_t val, void *p) piix.port_92 = val; } - -void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) +static uint8_t piix_apm_read(uint16_t port, void *p) { + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; + + switch (port) + { + case 0xb2: + ret = piix->pm.apmc; + break; + + case 0xb3: + ret = piix->pm.apms; + break; + } +// pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); + return ret; +} + +static void piix_apm_write(uint16_t port, uint8_t val, void *p) +{ + piix_t *piix = (piix_t *)p; + +// pclog("piix_apm_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0xb2: + piix->pm.apmc = val; + if (card_piix[REG_SMIEN] & SMIEN_APMC) + { + card_piix[REG_SMIREQ] |= SMIREQ_RAPMC; +// pclog("APMC write causes SMI\n"); + x86_smi_trigger(); + } + break; + + case 0xb3: + piix->pm.apms = val; + break; + } +} + +static void piix_common_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) +{ + memset(&piix, 0, sizeof(piix_t)); + pci_add_specific(card, piix_read, piix_write, NULL); memset(card_piix, 0, 256); @@ -263,6 +331,13 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_r piix.type = TYPE_PIIX3; } +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) +{ + piix_common_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); + + io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, &piix); +} + void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { piix_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); diff --git a/src/piix_pm.c b/src/piix_pm.c index a3947b7..e55766f 100644 --- a/src/piix_pm.c +++ b/src/piix_pm.c @@ -291,7 +291,7 @@ static uint8_t piix_smbus_read(uint16_t port, void *p) return ret; } -static uint8_t piix_apm_read(uint16_t port, void *p) +static uint8_t piix4_apm_read(uint16_t port, void *p) { piix_t *piix = (piix_t *)p; uint8_t ret = 0xff; @@ -309,7 +309,7 @@ static uint8_t piix_apm_read(uint16_t port, void *p) // pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); return ret; } -static void piix_apm_write(uint16_t port, uint8_t val, void *p) +static void piix4_apm_write(uint16_t port, uint8_t val, void *p) { piix_t *piix = (piix_t *)p; @@ -413,5 +413,5 @@ void piix_pm_init(piix_t *piix) piix->pm.timer_offset = 0; piix->pm.gporeg = 0x7fffbfff; - io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, piix); + io_sethandler(0x00b2, 0x0002, piix4_apm_read, NULL, NULL, piix4_apm_write, NULL, NULL, piix); } From 82b1486f6b841099eb38adf8f42bd825960bef14 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Nov 2020 16:55:21 +0000 Subject: [PATCH 0937/1050] Implement APM on i430LX and SIO chipset. --- src/i430lx.c | 42 +++++++++++++++++++++++++++++++- src/sio.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/i430lx.c b/src/i430lx.c index d051e96..4d2bb74 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -6,6 +6,7 @@ #include "keyboard_at.h" #include "mem.h" #include "pci.h" +#include "sio.h" #include "x86.h" #include "i430lx.h" @@ -107,6 +108,30 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv) i430lx_map(0xec000, 0x04000, val >> 4); pclog("i430lx_write : PAM6 write %02X\n", val); break; + + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x38) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430lx[0x72] & 0x08); /*D_LCK can not be cleared by software*/ + if (val & 0x08) /*D_LCK locks D_OPEN*/ + { + val &= ~0x20; /*D_OPEN is forced to 0*/ + } + val |= (card_i430lx[0x72] & 0x08); + if ((card_i430lx[0x72] ^ val) & 0x20) + { + if (val & 0x20) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; } card_i430lx[addr] = val; @@ -134,15 +159,27 @@ void i430lx_trc_write(uint16_t port, uint8_t val, void *p) 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*/ + card_i430lx[0x72] = 0; /*Also clear SMRAM register so BIOS will relocate SMBASE*/ keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ ide_reset_devices(); + resetx86(); } - resetx86(); + else + softresetx86(); } trc = val; } +static void i430lx_smram_enable(void) +{ + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void i430lx_smram_disable(void) +{ + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void i430lx_init() { pci_add_specific(0, i430lx_read, i430lx_write, NULL); @@ -168,4 +205,7 @@ void i430lx_init() // card_i430lx[0x78] = 0x23; io_sethandler(0x0cf9, 0x0001, i430lx_trc_read, NULL, NULL, i430lx_trc_write, NULL, NULL, NULL); + + smram_enable = i430lx_smram_enable; + smram_disable = i430lx_smram_disable; } diff --git a/src/sio.c b/src/sio.c index bc2dc33..65c8980 100644 --- a/src/sio.c +++ b/src/sio.c @@ -8,9 +8,23 @@ #include "sio.h" +typedef struct sio_t +{ + struct + { + uint8_t apmc, apms; + } pm; +} sio_t; +static sio_t sio; static uint8_t card_sio[256]; //static int pci_cards_ids[4]; +#define REG_SMIEN 0xa2 +#define REG_SMIREQ 0xaa + +#define SMIEN_APMC (1 << 7) +#define SMIREQ_RAPMC (1 << 7) + 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, cpu_state.pc); @@ -70,6 +84,13 @@ void sio_write(int func, int addr, uint8_t val, void *priv) else pci_set_irq_routing(PCI_INTD, val & 0xf); break; + + case REG_SMIREQ: + card_sio[addr] &= val; + return; + case REG_SMIREQ+1: + card_sio[addr] &= val; + return; } card_sio[addr] = val; } @@ -83,8 +104,53 @@ uint8_t sio_read(int func, int addr, void *priv) return card_sio[addr]; } +static uint8_t sio_apm_read(uint16_t port, void *p) +{ + sio_t *sio = (sio_t *)p; + uint8_t ret = 0xff; + + switch (port) + { + case 0xb2: + ret = sio->pm.apmc; + break; + + case 0xb3: + ret = sio->pm.apms; + break; + } +// pclog("sio_apm_read: port=%04x ret=%02x\n", port, ret); + return ret; +} + +static void sio_apm_write(uint16_t port, uint8_t val, void *p) +{ + sio_t *sio = (sio_t *)p; + +// pclog("sio_apm_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0xb2: + sio->pm.apmc = val; + if (card_sio[REG_SMIEN] & SMIEN_APMC) + { + card_sio[REG_SMIREQ] |= SMIREQ_RAPMC; +// pclog("APMC write causes SMI\n"); + x86_smi_trigger(); + } + break; + + case 0xb3: + sio->pm.apms = val; + break; + } +} + void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { + memset(&sio, 0, sizeof(sio_t)); + pci_add_specific(card, sio_read, sio_write, NULL); memset(card_sio, 0, 256); @@ -116,4 +182,6 @@ void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) pci_set_card_routing(pci_c, PCI_INTC); if (pci_d) pci_set_card_routing(pci_d, PCI_INTD); + + io_sethandler(0x00b2, 0x0002, sio_apm_read, NULL, NULL, sio_apm_write, NULL, NULL, &sio); } From 038a27767a6c98ba36a8221154840702e951d47e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Nov 2020 20:46:27 +0000 Subject: [PATCH 0938/1050] Implement APM/ACPI functionality for MVP3/VT82C586B, including soft power off. --- src/mvp3.c | 24 +++++++++++ src/vt82c586b.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/src/mvp3.c b/src/mvp3.c index 2760d99..f2d77b1 100644 --- a/src/mvp3.c +++ b/src/mvp3.c @@ -107,6 +107,16 @@ static void mvp3_host_bridge_write(int addr, uint8_t val) if ((mvp3.host_bridge_regs[0x63] ^ val) & 0xc0) mvp3_map(0xe0000, 0x10000, (val & 0xc0) >> 6); mvp3.host_bridge_regs[0x63] = val; + if ((val & 3) == 1 || ((val & 3) == 3 && (cpu_cur_status & CPU_STATUS_SMM))) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + else + { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } // if (val == 0xb0) // output = 3; return; @@ -169,6 +179,17 @@ static void mvp3_write(int func, int addr, uint8_t val, void *priv) } } +static void mvp3_smram_enable(void) +{ + if ((mvp3.host_bridge_regs[0x63] & 3) == 3) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); +} +static void mvp3_smram_disable(void) +{ + if ((mvp3.host_bridge_regs[0x63] & 3) != 1) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} + void mvp3_init() { pci_add_specific(0, mvp3_read, mvp3_write, NULL); @@ -216,4 +237,7 @@ void mvp3_init() mvp3.pci_bridge_regs[0x24] = 0xf0; mvp3.pci_bridge_regs[0x25] = 0xff; + + smram_enable = mvp3_smram_enable; + smram_disable = mvp3_smram_disable; } diff --git a/src/vt82c586b.c b/src/vt82c586b.c index 2540d5c..1235317 100644 --- a/src/vt82c586b.c +++ b/src/vt82c586b.c @@ -28,6 +28,16 @@ static struct struct { uint16_t io_base; + + uint16_t pm_status; + uint16_t pm_enable; + uint16_t pm_ctrl; + + uint16_t gbl_status; + uint16_t gbl_enable; + uint16_t gbl_ctrl; + + uint8_t smi_cmd; } power; } vt82c586b; @@ -36,6 +46,12 @@ static struct #define ACPI_IO_ENABLE (1 << 7) #define ACPI_TIMER_32BIT (1 << 3) +#define GBL_SW_SMI_STS (1 << 6) +#define GBL_SW_SMI_EN (1 << 6) + +#define PM_CTRL_SLP_EN (1 << 13) +#define PM_CTRL_SLP_TYP_MASK (7 << 10) + static uint8_t vt82c586b_read(int func, int addr, void *priv) { switch (func) @@ -235,21 +251,110 @@ static void vt82c586b_usb_write(int addr, uint8_t val) static uint8_t power_reg_read(uint16_t addr, void *p) { uint32_t timer; + uint8_t ret = 0xff; switch (addr & 0xff) { + case 0x00: case 0x01: + ret = vt82c586b.power.pm_status >> ((addr & 1) * 8); + break; + case 0x02: case 0x03: + ret = vt82c586b.power.pm_enable >> ((addr & 1) * 8); + break; + case 0x04: case 0x05: + ret = vt82c586b.power.pm_ctrl >> ((addr & 1) * 8); + break; + case 0x08: case 0x09: case 0x0a: case 0x0b: /*ACPI timer*/ timer = (tsc * ACPI_TIMER_FREQ) / cpu_get_speed(); if (!(vt82c586b.power_regs[0x41] & ACPI_TIMER_32BIT)) timer &= 0x00ffffff; return (timer >> (8 * (addr & 3))) & 0xff; + + case 0x28: case 0x29: + ret = vt82c586b.power.gbl_status >> ((addr & 1) * 8); + break; + case 0x2a: case 0x2b: + ret = vt82c586b.power.gbl_enable >> ((addr & 1) * 8); + break; + case 0x2c: case 0x2d: + ret = vt82c586b.power.gbl_ctrl >> ((addr & 1) * 8); + break; + + case 0x2f: + ret = vt82c586b.power.smi_cmd; + break; } -// pclog("power_reg_read: addr=%04x\n", addr); - return 0xff; +// pclog("power_reg_read: addr=%04x ret=%02x\n", addr, ret); + return ret; } static void power_reg_write(uint16_t addr, uint8_t val, void *p) { // pclog("power_reg_write: addr=%04x val=%02x\n", addr, val); + switch (addr & 0xff) + { + case 0x00: + vt82c586b.power.pm_status &= ~(val & 0x31); + break; + case 0x01: + vt82c586b.power.pm_status &= ~((val & 0x8d) << 8); + break; + + case 0x02: + vt82c586b.power.pm_enable = (vt82c586b.power.pm_enable & ~0xff) | (val & 0x21); + break; + case 0x03: + vt82c586b.power.pm_enable = (vt82c586b.power.pm_enable & ~0xff00) | ((val & 0x05) << 8); + break; + + case 0x04: + vt82c586b.power.pm_ctrl = (vt82c586b.power.pm_ctrl & ~0xff) | (val & 0x07); + if (val & (1 << 2)) + pclog("VT82C586B set GBL_RLS\n"); + break; + case 0x05: + vt82c586b.power.pm_ctrl = (vt82c586b.power.pm_ctrl & ~0xff00) | ((val & 0x1c) << 8); + /*Note: PM_CTRL_SLP_EN is write-only, hence not stored in pm_ctrl*/ + if (val & (PM_CTRL_SLP_EN >> 8)) + { + pclog("VT82C586B transition to power state %i\n", (val >> 2) & 7); + if (!(vt82c586b.power.pm_ctrl & PM_CTRL_SLP_TYP_MASK)) + { + pclog("Power off\n"); + stop_emulation_now(); + } + } + break; + + case 0x28: + vt82c586b.power.gbl_status &= ~(val & 0x7f); + break; + + case 0x2a: + vt82c586b.power.gbl_enable = (vt82c586b.power.gbl_enable & ~0xff) | (val & 0x7f); + break; + + case 0x2c: + vt82c586b.power.gbl_ctrl = (vt82c586b.power.gbl_ctrl & ~0xff) | (val & 0x17); + if (val & (1 << 1)) + pclog("VT82C586B set BIOS_RLS\n"); + break; + case 0x2d: + if (val & 1) + vt82c586b.power.gbl_ctrl &= ~0x100; + break; + + case 0x2f: + vt82c586b.power.smi_cmd = val; + vt82c586b.power_regs[0x47] = val; + if (vt82c586b.power.gbl_enable & GBL_SW_SMI_EN) + { + vt82c586b.power.gbl_status |= GBL_SW_SMI_STS; + x86_smi_trigger(); + } + pclog("SMI_CMD write %02x\n", val); + break; + } } static void vt82c586b_power_write(int addr, uint8_t val) { From 984437dfa96c798541fe58180bdbfb150b268345 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 1 Nov 2020 21:42:55 +0000 Subject: [PATCH 0939/1050] Default W83877TF SuperIO to all devices disabled. Fixes FIC VA-503+ IO port conflicts introduced following APM/ACPI implementation. --- src/w83877tf.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/w83877tf.c b/src/w83877tf.c index 6d86ad6..bc4dccc 100644 --- a/src/w83877tf.c +++ b/src/w83877tf.c @@ -235,14 +235,20 @@ static void w83877_common_init(int chip, uint16_t base, uint8_t key) w83877tf_global.regs[0x16] = 0x04; else w83877tf_global.regs[0x16] = 0x05; - w83877tf_global.regs[0x20] = 0xfc; - w83877tf_global.regs[0x23] = 0xde; - w83877tf_global.regs[0x24] = 0xfe; - w83877tf_global.regs[0x25] = 0xbe; - w83877tf_global.regs[0x26] = 0x23; - w83877tf_global.regs[0x27] = 0x05; - w83877tf_global.regs[0x28] = 0x43; - w83877tf_global.regs[0x29] = 0x60; + w83877tf_global.regs[0x20] = 0; + w83877tf_global.regs[0x23] = 0; + w83877tf_global.regs[0x24] = 0; + w83877tf_global.regs[0x25] = 0; + w83877tf_global.regs[0x26] = 0; + w83877tf_global.regs[0x27] = 0; + w83877tf_global.regs[0x28] = 0; + w83877tf_global.regs[0x29] = 0; + + fdc_remove(); + lpt1_remove(); + lpt2_remove(); + serial1_remove(); + serial2_remove(); w83877tf_global.chip = chip; w83877tf_global.unlock_key = key; From 193645a426fb15eb0e9ecbb8899966285618d8c4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 3 Nov 2020 21:17:29 +0000 Subject: [PATCH 0940/1050] Add mutex to protect Voodoo swap count and pending. Should fix hangs sometimes changing video mode on Voodoo 3. --- src/vid_voodoo.c | 7 ++++++- src/vid_voodoo_banshee.c | 13 ++++++++++--- src/vid_voodoo_common.h | 1 + src/vid_voodoo_display.c | 13 +++++++++++-- src/vid_voodoo_fifo.c | 5 +++++ src/vid_voodoo_reg.c | 4 ++++ 6 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 19c5467..5d556df 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -414,7 +414,9 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) case SST_swapbufferCMD: voodoo->cmd_written++; + thread_lock_mutex(voodoo->swap_mutex); voodoo->swap_count++; + thread_unlock_mutex(voodoo->swap_mutex); if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) return; voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); @@ -495,7 +497,9 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) { voodoo->line = 0; + thread_lock_mutex(voodoo->swap_mutex); voodoo->swap_count = 0; + thread_unlock_mutex(voodoo->swap_mutex); voodoo->retrace_count = 0; } voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); @@ -1024,6 +1028,7 @@ void *voodoo_card_init() voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); } + voodoo->swap_mutex = thread_create_mutex(); timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); for (c = 0; c < 0x100; c++) @@ -1140,7 +1145,7 @@ void *voodoo_2d3d_card_init(int type) voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); } - + voodoo->swap_mutex = thread_create_mutex(); timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); for (c = 0; c < 0x100; c++) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 2026d8e..d705c57 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1239,7 +1239,9 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_swapPending: + thread_lock_mutex(voodoo->swap_mutex); voodoo->swap_count++; + thread_unlock_mutex(voodoo->swap_mutex); // voodoo->cmd_written++; break; @@ -1842,17 +1844,22 @@ static void banshee_vsync_callback(svga_t *svga) voodoo_t *voodoo = banshee->voodoo; voodoo->retrace_count++; + thread_lock_mutex(voodoo->swap_mutex); if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - banshee_set_overlay_addr(banshee, voodoo->swap_offset); if (voodoo->swap_count > 0) voodoo->swap_count--; voodoo->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); + + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + banshee_set_overlay_addr(banshee, voodoo->swap_offset); thread_set_event(voodoo->wake_fifo_thread); voodoo->frame_count++; } + else + thread_unlock_mutex(voodoo->swap_mutex); voodoo->overlay.src_y = 0; banshee->desktop_addr = banshee->vidDesktopStartAddr; diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 637ccca..364407f 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -229,6 +229,7 @@ typedef struct voodoo_t uint32_t tmuConfig; + mutex_t *swap_mutex; int swap_count; int disp_buffer, draw_buffer; diff --git a/src/vid_voodoo_display.c b/src/vid_voodoo_display.c index d643d5d..a8cda43 100644 --- a/src/vid_voodoo_display.c +++ b/src/vid_voodoo_display.c @@ -531,6 +531,7 @@ skip_draw: { voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; + thread_lock_mutex(voodoo->swap_mutex); /*Only swap if both Voodoos are waiting for buffer swap*/ if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) @@ -548,6 +549,7 @@ skip_draw: if (voodoo_1->swap_count > 0) voodoo_1->swap_count--; voodoo_1->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); thread_set_event(voodoo->wake_fifo_thread); thread_set_event(voodoo_1->wake_fifo_thread); @@ -555,21 +557,28 @@ skip_draw: voodoo->frame_count++; voodoo_1->frame_count++; } + else + thread_unlock_mutex(voodoo->swap_mutex); } } else { + thread_lock_mutex(voodoo->swap_mutex); if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; voodoo->front_offset = voodoo->swap_offset; if (voodoo->swap_count > 0) voodoo->swap_count--; voodoo->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); + + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; thread_set_event(voodoo->wake_fifo_thread); voodoo->frame_count++; } + else + thread_unlock_mutex(voodoo->swap_mutex); } voodoo->v_retrace = 1; } diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index 0d35b3a..1c807d4 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -90,6 +90,8 @@ void voodoo_wait_for_swap_complete(voodoo_t *voodoo) { thread_wait_event(voodoo->wake_fifo_thread, -1); thread_reset_event(voodoo->wake_fifo_thread); + + thread_lock_mutex(voodoo->swap_mutex); if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) { /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ @@ -98,8 +100,11 @@ void voodoo_wait_for_swap_complete(voodoo_t *voodoo) if (voodoo->swap_count > 0) voodoo->swap_count--; voodoo->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); break; } + else + thread_unlock_mutex(voodoo->swap_mutex); } } diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 965c6f6..82f4bac 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -56,8 +56,10 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) if (!(val & 1)) { banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); + thread_lock_mutex(voodoo->swap_mutex); if (voodoo->swap_count > 0) voodoo->swap_count--; + thread_unlock_mutex(voodoo->swap_mutex); voodoo->frame_count++; } else if (TRIPLE_BUFFER) @@ -102,8 +104,10 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { memset(voodoo->dirty_line, 1, 1024); voodoo->front_offset = voodoo->params.front_offset; + thread_lock_mutex(voodoo->swap_mutex); if (voodoo->swap_count > 0) voodoo->swap_count--; + thread_unlock_mutex(voodoo->swap_mutex); } else if (TRIPLE_BUFFER) { From 8a5a0fc48ce053c640bd18fbe3280bce1f52f4a6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 4 Nov 2020 20:56:40 +0000 Subject: [PATCH 0941/1050] Intel flash chips respond to writes at all addresses. Fixes NVRAM errors on VS440FX. --- src/intel_flash.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/intel_flash.c b/src/intel_flash.c index 716d450..91ea964 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -43,11 +43,7 @@ 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 & flash->addr_mask]; - } // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); addr &= flash->addr_mask; switch (flash->command) @@ -97,13 +93,10 @@ 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); +// 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) - { addr ^= 0x10000; - if (addr & 0xfff00000) return; - } addr &= flash->addr_mask; switch (flash->command) From c0bc163eaf69e4d79c6ee352133ed32214ac6b30 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Nov 2020 20:46:42 +0000 Subject: [PATCH 0942/1050] Implement Cyrix SMM mode. --- src/386_ops.h | 110 +++++++++++- src/codegen_ops_mmx_loadstore.c | 3 + src/cpu.c | 41 ++++- src/x86.h | 18 +- src/x86_ops.h | 2 + src/x86_ops_cyrix.h | 274 +++++++++++++++++++++++++++++ src/x86_ops_mmx_mov.h | 48 +++++- src/x86_ops_pmode.h | 6 +- src/x86seg.c | 293 ++++++++++++++++++++++---------- 9 files changed, 688 insertions(+), 107 deletions(-) create mode 100644 src/x86_ops_cyrix.h diff --git a/src/386_ops.h b/src/386_ops.h index 79ea171..d59132a 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -119,6 +119,7 @@ static int ILLEGAL(uint32_t fetchdat) #include "x86_ops_bit.h" #include "x86_ops_bitscan.h" #include "x86_ops_call.h" +#include "x86_ops_cyrix.h" #include "x86_ops_flag.h" #include "x86_ops_fpu.h" #include "x86_ops_inc_dec.h" @@ -638,7 +639,98 @@ OpFn OP_TABLE(pentium_0f)[1024] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -OpFn OP_TABLE(pentiummmx_0f)[1024] = +OpFn OP_TABLE(c6x86_0f)[1024] = +{ + /*16-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL, + +/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 16-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16, +/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16, + +/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*16-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, ILLEGAL, + +/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL, + +/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + + /*32-bit data, 32-bit addr*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, ILLEGAL, + +/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, +/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, +/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32, +/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32, + +/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI, +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + +OpFn OP_TABLE(pentiummmx_0f)[1024] = { /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -736,12 +828,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, -/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16, /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, @@ -758,12 +850,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16, -/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16, /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16, @@ -780,12 +872,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, -/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32, /*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, @@ -802,12 +894,12 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] = /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32, /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32, -/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32, +/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32, /*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, /*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32, diff --git a/src/codegen_ops_mmx_loadstore.c b/src/codegen_ops_mmx_loadstore.c index ac591e8..a376f9b 100644 --- a/src/codegen_ops_mmx_loadstore.c +++ b/src/codegen_ops_mmx_loadstore.c @@ -38,6 +38,9 @@ uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t { int src_reg = (fetchdat >> 3) & 7; + if (cpu_iscyrix && (cpu_cur_status & CPU_STATUS_SMM)) + return 0; + uop_MMX_ENTER(ir); codegen_mark_code_present(block, cs+op_pc, 1); if ((fetchdat & 0xc0) == 0xc0) diff --git a/src/cpu.c b/src/cpu.c index fb9a042..e381931 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -787,7 +787,7 @@ void cpu_set() break; case CPU_Cx6x86: - x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); timing_rr = 1; /*register dest - register src*/ timing_rm = 1; /*register dest - memory src*/ timing_mr = 2; /*memory dest - register src*/ @@ -2003,6 +2003,13 @@ void cpu_WRMSR() static int cyrix_addr; +#define CCR1_USE_SMI (1 << 1) +#define CCR1_SMAC (1 << 2) +#define CCR1_SM3 (1 << 7) + +#define CCR3_SMI_LOCK (1 << 0) +#define CCR3_NMI_EN (1 << 1) + void cyrix_write(uint16_t addr, uint8_t val, void *priv) { if (!(addr & 1)) @@ -2013,14 +2020,46 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv) ccr0 = val; break; case 0xc1: /*CCR1*/ + if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM)) + val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); ccr1 = val; break; case 0xc2: /*CCR2*/ ccr2 = val; break; case 0xc3: /*CCR3*/ + if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM)) + val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; ccr3 = val; break; + case 0xcd: + if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) + { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xce: + if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) + { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xcf: + if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) + { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); + if ((val & 0xf) == 0xf) + cyrix.arr[3].size = 1ull << 32; /*4 GB*/ + else if (val & 0xf) + cyrix.arr[3].size = 2048 << (val & 0xf); + else + cyrix.arr[3].size = 0; /*Disabled*/ + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xe8: /*CCR4*/ if ((ccr3 & 0xf0) == 0x10) { diff --git a/src/x86.h b/src/x86.h index 12125e4..f0f2238 100644 --- a/src/x86.h +++ b/src/x86.h @@ -39,7 +39,7 @@ typedef union typedef struct { uint32_t base; - uint32_t limit; + uint32_t limit, limit_raw; uint8_t access, access2; uint16_t seg; uint32_t limit_low, limit_high; @@ -325,4 +325,20 @@ void x86_smi_trigger(void); void x86_smi_enter(void); void x86_smi_leave(void); +void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg); +void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); + +#define SMHR_VALID (1 << 0) +#define SMHR_ADDR_MASK (0xfffffffc) + +struct +{ + struct + { + uint32_t base; + uint64_t size; + } arr[8]; + uint32_t smhr; +} cyrix; + #endif diff --git a/src/x86_ops.h b/src/x86_ops.h index 8cdd4e7..578b7cf 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -41,6 +41,7 @@ extern OpFn dynarec_ops_pentiummmx_0f[1024]; extern OpFn dynarec_ops_pentiumpro_0f[1024]; extern OpFn dynarec_ops_pentium2_0f[1024]; +extern OpFn dynarec_ops_c6x86_0f[1024]; extern OpFn dynarec_ops_c6x86mx_0f[1024]; extern OpFn dynarec_ops_fpu_d8_a16[32]; @@ -110,6 +111,7 @@ extern OpFn ops_pentiummmx_0f[1024]; extern OpFn ops_pentiumpro_0f[1024]; extern OpFn ops_pentium2_0f[1024]; +extern OpFn ops_c6x86_0f[1024]; extern OpFn ops_c6x86mx_0f[1024]; extern OpFn ops_fpu_d8_a16[32]; diff --git a/src/x86_ops_cyrix.h b/src/x86_ops_cyrix.h new file mode 100644 index 0000000..e6464ce --- /dev/null +++ b/src/x86_ops_cyrix.h @@ -0,0 +1,274 @@ +/*Cyrix-only instructions*/ +/*System Management Mode*/ +static void opSVDC_common(uint32_t fetchdat) +{ + switch (rmdat & 0x38) + { + case 0x00: /*ES*/ + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); + writememw(0, easeg+cpu_state.eaaddr+8, ES); + break; + case 0x08: /*CS*/ + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs); + writememw(0, easeg+cpu_state.eaaddr+8, CS); + break; + case 0x18: /*DS*/ + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); + writememw(0, easeg+cpu_state.eaaddr+8, DS); + break; + case 0x10: /*SS*/ + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); + writememw(0, easeg+cpu_state.eaaddr+8, SS); + break; + case 0x20: /*FS*/ + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); + writememw(0, easeg+cpu_state.eaaddr+8, FS); + break; + case 0x28: /*GS*/ + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); + writememw(0, easeg+cpu_state.eaaddr+8, GS); + break; + default: + pclog("opSVDC: unknown rmdat %02x\n", rmdat); + x86illegal(); + } +} +static int opSVDC_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } + else + x86illegal(); + + return cpu_state.abrt; +} +static int opSVDC_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } + else + x86illegal(); + + return cpu_state.abrt; +} + +static void opRSDC_common(uint32_t fetchdat) +{ + switch (rmdat & 0x38) + { + case 0x00: /*ES*/ + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); + break; + case 0x20: /*FS*/ + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); + break; + default: + pclog("opRSDC: unknown rmdat %02x\n", rmdat); + x86illegal(); + } +} +static int opRSDC_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } + else + x86illegal(); + + return cpu_state.abrt; +} +static int opRSDC_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } + else + x86illegal(); + + return cpu_state.abrt; +} + +static int opSVLDT_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); + writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); + } + else + x86illegal(); + + return cpu_state.abrt; +} +static int opSVLDT_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); + writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); + } + else + x86illegal(); + + return cpu_state.abrt; +} + +static int opRSLDT_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); + } + else + x86illegal(); + + return cpu_state.abrt; +} +static int opRSLDT_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); + } + else + x86illegal(); + + return cpu_state.abrt; +} + +static int opSVTS_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); + writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); + } + else + x86illegal(); + + return cpu_state.abrt; +} +static int opSVTS_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); + writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); + } + else + x86illegal(); + + return cpu_state.abrt; +} + +static int opRSTS_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); + writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); + } + else + x86illegal(); + + return cpu_state.abrt; +} +static int opRSTS_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); + writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); + } + else + x86illegal(); + + return cpu_state.abrt; +} + +static int opSMINT(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opSMINT\n"); + else + x86illegal(); + + return 1; +} + +static int opRDSHR_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opRDSHR_a16\n"); + else + x86illegal(); + + return 1; +} +static int opRDSHR_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opRDSHR_a32\n"); + else + x86illegal(); + + return 1; +} + +static int opWRSHR_a16(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opWRSHR_a16\n"); + else + x86illegal(); + + return 1; +} +static int opWRSHR_a32(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opWRSHR_a32\n"); + else + x86illegal(); + + return 1; +} diff --git a/src/x86_ops_mmx_mov.h b/src/x86_ops_mmx_mov.h index 133d48d..548b6c4 100644 --- a/src/x86_ops_mmx_mov.h +++ b/src/x86_ops_mmx_mov.h @@ -50,7 +50,7 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat) static int opMOVD_mm_l_a16(uint32_t fetchdat) { MMX_ENTER(); - + fetch_ea_16(fetchdat); if (cpu_mod == 3) { @@ -69,6 +69,52 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat) static int opMOVD_mm_l_a32(uint32_t fetchdat) { MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) + { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + return 0; +} + +/*Cyrix maps both MOVD and SMINT to the same opcode*/ +static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + return opSMINT(fetchdat); + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) + { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } + else + { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; + CLOCK_CYCLES(2); + } + return 0; +} +static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) +{ + if (cpu_cur_status & CPU_STATUS_SMM) + return opSMINT(fetchdat); + + MMX_ENTER(); fetch_ea_32(fetchdat); if (cpu_mod == 3) diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index a93cfa7..5ad244f 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -165,7 +165,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) int dpl, valid, granularity; uint32_t addr, base, limit; uint16_t desc, sel; - uint8_t access; + uint8_t access, access2; // pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); switch (rmdat & 0x38) @@ -198,10 +198,12 @@ static int op0F00_common(uint32_t fetchdat, int ea32) limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); access = readmemb(0, addr + 5); + access2 = readmemb(0, addr + 6); granularity = readmemb(0, addr + 6) & 0x80; if (cpu_state.abrt) return 1; ldt.limit = limit; ldt.access = access; + ldt.access2 = access2; if (granularity) { ldt.limit <<= 12; @@ -226,6 +228,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); access = readmemb(0, addr + 5); + access2 = readmemb(0, addr + 6); granularity = readmemb(0, addr + 6) & 0x80; if (cpu_state.abrt) return 1; access |= 2; @@ -234,6 +237,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) tr.seg = sel; tr.limit = limit; tr.access = access; + tr.access2 = access2; if (granularity) { tr.limit <<= 12; diff --git a/src/x86seg.c b/src/x86seg.c index 669001e..6703f8f 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -219,6 +219,7 @@ static void set_use32(int u) static void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); + s->limit_raw = s->limit; if (segdat[3] & 0x80) s->limit = (s->limit << 12) | 0xFFF; s->base = segdat[1] | ((segdat[2] & 0xFF) << 16); @@ -2996,6 +2997,51 @@ static void smi_load_smi_selector(x86seg *seg) seg->access2 = 0; } +void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) +{ + writememl(0, addr, (seg->limit_raw & 0xffff) | (seg->base << 16)); + writememl(0, addr+4, ((seg->base >> 16) & 0xff) | + (seg->access << 8) | + (seg->limit_raw & 0xf0000) | + (seg->access2 << 16) | + (seg->base & 0xff000000)); +} + +void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) +{ + uint16_t segdat[4], selector; + + segdat[0] = readmemw(0, addr); + segdat[1] = readmemw(0, addr+2); + segdat[2] = readmemw(0, addr+4); + segdat[3] = readmemw(0, addr+6); + selector = readmemw(0, addr+8); + + if (!cpu_state.abrt) + { + do_seg_load(seg, segdat); + seg->seg = selector; + seg->checked = 0; + if (seg == &cpu_state.seg_ds) + { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + codegen_flat_ds = 0; + } + if (seg == &cpu_state.seg_ss) + { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((segdat[3] & 0x40) ? 1 : 0); + codegen_flat_ss = 0; + } + } +} + void x86_smi_enter(void) { uint32_t old_cr0 = cr0; @@ -3007,63 +3053,102 @@ void x86_smi_enter(void) cpu_386_flags_rebuild(); cpl_override = 1; cr0 = 0; /*Disable MMU*/ - writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16)); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); - writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase); - writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000); - cpl_override = 0; - cpu_cur_status = CPU_STATUS_SMM; - cpu_state.flags = 2; - cpu_state.eflags = 0; - cpu_state.pc = 0x8000; - cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); - dr[7] = 0x400; - smi_load_smi_selector(&cpu_state.seg_ds); - smi_load_smi_selector(&cpu_state.seg_es); - smi_load_smi_selector(&cpu_state.seg_fs); - smi_load_smi_selector(&cpu_state.seg_gs); - smi_load_smi_selector(&cpu_state.seg_ss); - cpu_state.seg_cs.seg = 0x3000; - cpu_state.seg_cs.base = cpu_state.smbase; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = (0 << 5) | 2; + if (cpu_iscyrix) + { + uint32_t base; - use32 = 0; - stack32 = 0; + if (!cyrix.smhr & SMHR_VALID) + cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; + base = cyrix.smhr & SMHR_ADDR_MASK; + + writememl(0, base-4, dr[7]); + writememl(0, base-8, cpu_state.flags | (cpu_state.eflags << 16)); + writememl(0, base-0xc, old_cr0); + writememl(0, base-0x10, cpu_state.oldpc); + writememl(0, base-0x14, cpu_state.pc); + writememl(0, base-0x18, CS | (CPL << 21)); + cyrix_write_seg_descriptor(base-0x20, &cpu_state.seg_cs); + writememl(0, base-0x24, 0); + + cpl_override = 0; + + cpu_cur_status = CPU_STATUS_SMM; + cpu_state.flags = 2; + cpu_state.eflags = 0; + cpu_state.pc = 0; + cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); + dr[7] = 0x400; + cpu_state.seg_cs.seg = cyrix.arr[3].base >> 4; /*Guess*/ + cpu_state.seg_cs.base = cyrix.arr[3].base; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = (0 << 5) | 2; + + use32 = 0; + stack32 = 0; + } + else + { + writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16)); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); + writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase); + writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000); + cpl_override = 0; + + cpu_cur_status = CPU_STATUS_SMM; + cpu_state.flags = 2; + cpu_state.eflags = 0; + cpu_state.pc = 0x8000; + cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); + dr[7] = 0x400; + smi_load_smi_selector(&cpu_state.seg_ds); + smi_load_smi_selector(&cpu_state.seg_es); + smi_load_smi_selector(&cpu_state.seg_fs); + smi_load_smi_selector(&cpu_state.seg_gs); + smi_load_smi_selector(&cpu_state.seg_ss); + cpu_state.seg_cs.seg = 0x3000; + cpu_state.seg_cs.base = cpu_state.smbase; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = (0 << 5) | 2; + + use32 = 0; + stack32 = 0; + } // pclog("x86_smi_enter\n"); } @@ -3073,47 +3158,67 @@ void x86_smi_leave(void) uint32_t temp; uint32_t new_cr0; - cpl_override = 1; - new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc); - cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8); - temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4); - cpu_state.flags = temp & 0xffff; - cpu_state.eflags = temp >> 16; - cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0); - EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec); - ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8); - EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4); - ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0); - EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc); - EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8); - ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4); - EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0); - dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc); - dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8); - tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4); - ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0); - cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc); - cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8); - cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4); - cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0); - cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac); - cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); - cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28); - cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8); - cpl_override = 0; + if (cpu_iscyrix) + { + uint32_t base = cyrix.smhr & SMHR_ADDR_MASK; - cr0 = new_cr0; + cpl_override = 1; + dr[7] = readmeml(0, base-4); + temp = readmeml(0, base-8); + cpu_state.flags = temp & 0xffff; + cpu_state.eflags = temp >> 16; + new_cr0 = readmeml(0, base-0xc); + cpu_state.pc = readmeml(0, base-0x14); + cyrix_load_seg_descriptor(base-0x20, &cpu_state.seg_cs); + cpl_override = 0; + cr0 = new_cr0; + } + else + { + cpl_override = 1; + new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc); + cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8); + temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4); + cpu_state.flags = temp & 0xffff; + cpu_state.eflags = temp >> 16; + cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0); + EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec); + ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8); + EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4); + ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0); + EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc); + EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8); + ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4); + EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0); + dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc); + dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8); + tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4); + ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0); + cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc); + cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8); + cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4); + cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0); + cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac); + cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); + cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28); + cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8); + cpl_override = 0; + + cr0 = new_cr0; + } + + cpu_386_flags_extract(); cpu_cur_status = 0; use32 = stack32 = 0; if (cr0 & 1) From 7f206c5484834043f7e45d26f8d407740958efc5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Nov 2020 22:11:15 +0000 Subject: [PATCH 0943/1050] Clear CR4 mask by default. Fixes issues when switching between CPUs that implement CR4 and those that don't. --- src/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu.c b/src/cpu.c index e381931..0c4487d 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -333,6 +333,7 @@ void cpu_set() timing_misaligned = 0; cpu_cyrix_alignment = 0; + cpu_CR4_mask = 0; switch (cpu_s->cpu_type) { From 624f1cfcfcfa0e48a68af4635cefacf7665a5c12 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Nov 2020 08:06:49 +0000 Subject: [PATCH 0944/1050] Set raw limits on LLDT & LTR instructions - Cyrix RSLDT/RSTS instructions no longer corrupt LDT/TR limits. --- src/x86_ops_pmode.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index 5ad244f..3578b5f 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -202,6 +202,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) granularity = readmemb(0, addr + 6) & 0x80; if (cpu_state.abrt) return 1; ldt.limit = limit; + ldt.limit_raw = limit; ldt.access = access; ldt.access2 = access2; if (granularity) @@ -236,6 +237,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) if (cpu_state.abrt) return 1; tr.seg = sel; tr.limit = limit; + tr.limit_raw = limit; tr.access = access; tr.access2 = access2; if (granularity) From a01cc90866594d6cc3838298ab4fcd02818e4453 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Nov 2020 08:07:36 +0000 Subject: [PATCH 0945/1050] Tweak search range when codegen looking for start uOP for given instruction. Fixes range when unrolling LOOP instruction pointing to itself (which could skip initial cycle count update), fixes Windows 98 boot on 6x86 chips. --- src/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 4206db3..373c15c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -29,7 +29,7 @@ int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_inst { int c; - for (c = 0; c < block->ins; c++) + for (c = 0; c <= block->ins; c++) { if (codegen_instructions[c].pc == pc) { From 4683d674b67f973a2d42b4a398db251c5f79dae6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Nov 2020 19:29:21 +0000 Subject: [PATCH 0946/1050] Implement PIIX SMI gate. Fixes some issues seen on Shuttle HOT-433 when power management disabled in BIOS, which results in the BIOS failing to initialise and relocate the SMI handler but still advertise APM availability. --- src/piix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/piix.c b/src/piix.c index 35eebe2..4e76b26 100644 --- a/src/piix.c +++ b/src/piix.c @@ -29,9 +29,11 @@ static sff_busmaster_t piix_busmaster[2]; static uint8_t piix_rc = 0; static void (*piix_nb_reset)(); +#define REG_SMICNTL 0xa0 #define REG_SMIEN 0xa2 #define REG_SMIREQ 0xaa +#define SMICNTL_CSMIGATE (1 << 0) #define SMIEN_APMC (1 << 7) #define SMIREQ_RAPMC (1 << 7) @@ -262,7 +264,8 @@ static void piix_apm_write(uint16_t port, uint8_t val, void *p) { card_piix[REG_SMIREQ] |= SMIREQ_RAPMC; // pclog("APMC write causes SMI\n"); - x86_smi_trigger(); + if (card_piix[REG_SMICNTL] & SMICNTL_CSMIGATE) + x86_smi_trigger(); } break; From c598f88f67ae127df0d3a39bc86116a89ba30668 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Nov 2020 19:56:51 +0000 Subject: [PATCH 0947/1050] Implement Banshee/V3 vidProcCfg half mode. Fixes low res 16 bpp modes. --- src/vid_voodoo_banshee.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index d705c57..fa14821 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -139,6 +139,7 @@ enum #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) +#define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) @@ -311,9 +312,14 @@ static void banshee_render_16bpp_tiled(svga_t *svga) int x; int offset = 32; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - uint32_t addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + uint32_t addr; int drawn = 0; + if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE) + addr = banshee->desktop_addr + ((banshee->desktop_y >> 1) & 31) * 128 + ((banshee->desktop_y >> 6) * banshee->desktop_stride_tiled); + else + addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + for (x = 0; x <= svga->hdisp; x += 64) { if (svga->hwcursor_on || svga->overlay_on) From 5c3069c561980869699ba64755c72cc440d8c19a Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 9 Nov 2020 21:50:42 +0000 Subject: [PATCH 0948/1050] Add W83977TF SuperIO chip for Gigabyte GA686BX. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/model.c | 3 +- src/w83977tf.c | 197 +++++++++++++++++++++++++++++ src/w83977tf.h | 1 + 6 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 src/w83977tf.c create mode 100644 src/w83977tf.h diff --git a/src/Makefile.am b/src/Makefile.am index d514a98..ca69439 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,7 +51,7 @@ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c vid_voodoo_banshee.c vid_voodoo_banshee_blitter.c \ vid_voodoo_blitter.c vid_voodoo_display.c vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c \ vid_voodoo_render.c vid_voodoo_setup.c vid_voodoo_texture.c video.c wd76c10.c vid_wy700.c vt82c586b.c \ -vl82c480.c w83877tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc +vl82c480.c w83877tf.c w83977tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 2926e83..790468e 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -39,7 +39,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \ vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \ vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \ - vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ + vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index fd03280..6952573 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -39,7 +39,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \ vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \ vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \ - vt82c586b.o w83877tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ + vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/model.c b/src/model.c index 55e9177..fd10cb5 100644 --- a/src/model.c +++ b/src/model.c @@ -78,6 +78,7 @@ #include "vl82c480.h" #include "vt82c586b.h" #include "w83877tf.h" +#include "w83977tf.h" #include "wd76c10.h" #include "xi8088.h" #include "zenith.h" @@ -847,7 +848,7 @@ void at_ga686bx_init() pci_slot(0xb); i440bx_init(); piix4_init(7, 0x8, 0x9, 0xa, 0xb, i440bx_reset); - w83877tf_init(0x250, 0x89); + w83977tf_init(0x3f0, 0x87); device_add(&intel_flash_28f002bc_device); } diff --git a/src/w83977tf.c b/src/w83977tf.c new file mode 100644 index 0000000..520b4ed --- /dev/null +++ b/src/w83977tf.c @@ -0,0 +1,197 @@ +#include "ibm.h" + +#include "fdc.h" +#include "io.h" +#include "lpt.h" +#include "serial.h" +#include "w83977tf.h" + +typedef struct winbond_t +{ + int cur_reg; + int cur_device; + int index; + + uint8_t unlock_key; + uint8_t key[2]; + int enable_regs; + + struct + { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[11]; +} winbond_t; + +static winbond_t winbond_global; + +#define DEV_FDC 0x0 +#define DEV_LPT 0x1 +#define DEV_COM1 0x2 +#define DEV_COM2 0x3 +#define DEV_KBC 0x5 +#define DEV_GPIO 0x7 +#define DEV_GPIO_II 0x8 +#define DEV_GPIO_III 0x9 +#define DEV_ACPI 0xa + +#define REG_DEVICE 0x07 +#define REG_DEVICE_ID 0x20 +#define REG_DEVICE_REV 0x21 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 + +void winbond_write_reg(winbond_t *winbond, int index, uint8_t val) +{ + if (index == REG_DEVICE) + winbond->cur_device = val & 0xf; + else + { +// pclog("Write winbond %02x [%02x] %02x\n", winbond->cur_reg, winbond->cur_device, val); + switch (index) + { + case REG_ENABLE: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].enable = val; + break; + case REG_ADDRLO: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].irq = val; + break; + case REG_DMA: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].dma = val; + break; + } + + switch (winbond->cur_device) + { + case DEV_FDC: + fdc_remove(); + if (winbond->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (winbond->dev[DEV_COM1].enable & 1) + serial1_set(winbond->dev[DEV_COM1].addr, winbond->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (winbond->dev[DEV_COM2].enable & 1) + serial2_set(winbond->dev[DEV_COM2].addr, winbond->dev[DEV_COM2].irq); + break; + case DEV_LPT: + lpt1_remove(); + lpt2_remove(); + if (winbond->dev[DEV_LPT].enable & 1) + lpt1_init(winbond->dev[DEV_LPT].addr); + break; + } + } +} + +uint8_t winbond_read_reg(winbond_t *winbond, int index) +{ +// pclog("Read winbond %02x\n", winbond->cur_reg); + + switch (index) + { + case REG_DEVICE: + return winbond->cur_device; + case REG_DEVICE_ID: + return 0x97; + case REG_DEVICE_REV: + return 0x73; + case REG_ENABLE: + return winbond->dev[winbond->cur_device].enable; + case REG_ADDRLO: + return winbond->dev[winbond->cur_device].addr & 0xff; + case REG_ADDRHI: + return winbond->dev[winbond->cur_device].addr >> 8; + case REG_IRQ: + return winbond->dev[winbond->cur_device].irq; + case REG_DMA: + return winbond->dev[winbond->cur_device].dma; + } + + return 0xff; +} + +static void winbond_write_3fx(uint16_t port, uint8_t val, void *p) +{ + winbond_t *winbond = (winbond_t *)p; + +// pclog("winbond_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0x3f0: /*Enable/index register*/ + if (val == 0xaa) + { + fdc_3f1_enable(1); + winbond->enable_regs = 0; + } + else if (!winbond->enable_regs) + { + winbond->key[1] = winbond->key[0]; + winbond->key[0] = val; + winbond->enable_regs = (winbond->key[0] == winbond->unlock_key && winbond->key[1] == winbond->unlock_key); + /*The FDC conflicts with the 3fx config registers, so disable + it when enabling config registers*/ + if (winbond->enable_regs) + fdc_3f1_enable(0); + } + else + winbond->index = val; + break; + case 0x3f1: /*Data*/ + if (winbond->enable_regs) + winbond_write_reg(winbond, winbond->index, val); + break; + } +} + +static uint8_t winbond_read_3fx(uint16_t port, void *p) +{ + winbond_t *winbond = (winbond_t *)p; + uint8_t ret = 0xff; + + switch (port) + { + case 0x3f0: /*Index*/ + if (winbond->enable_regs) + ret = winbond->index; + break; + + case 0x3f1: /*Data*/ + if (winbond->enable_regs) + ret = winbond_read_reg(winbond, winbond->index); + break; + } + +// pclog("winbond_read: port=%04x val=%02x\n", port, ret); + + return ret; +} + +void w83977tf_init(uint16_t base, uint8_t key) +{ + memset(&winbond_global, 0, sizeof(winbond_t)); + + winbond_global.unlock_key = key; + io_sethandler(base, 0x0002, winbond_read_3fx, NULL, NULL, winbond_write_3fx, NULL, NULL, &winbond_global); +} diff --git a/src/w83977tf.h b/src/w83977tf.h new file mode 100644 index 0000000..290f571 --- /dev/null +++ b/src/w83977tf.h @@ -0,0 +1 @@ +void w83977tf_init(uint16_t base, uint8_t key); From 0469ab60cb9f1946947e537bfbc8151d10e8269b Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Nov 2020 19:52:13 +0000 Subject: [PATCH 0949/1050] Implement penalties for segment load on Pentium Pro. --- src/codegen_timing_p6.c | 45 +++++++++++++++++++++++++++++------------ src/cpu.c | 4 ++-- src/cpu.h | 2 ++ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/codegen_timing_p6.c b/src/codegen_timing_p6.c index 1b4d53d..a608164 100644 --- a/src/codegen_timing_p6.c +++ b/src/codegen_timing_p6.c @@ -19,7 +19,8 @@ typedef enum uop_type_t UOP_LOAD, /*Executes in port 2 Load unit*/ UOP_STOREADDR, /*Executes in port 3 Store Address unit*/ UOP_STOREDATA, /*Executes in port 4 Store Data unit*/ - UOP_FLOAT /*Executes in port 0 Floating Point unit*/ + UOP_FLOAT, /*Executes in port 0 Floating Point unit*/ + UOP_ALU0_SEG /*Executes in port 0 ALU, loads segment, causing pipeline flush on PPro*/ } uop_type_t; #define MAX_UOPS 300 @@ -512,7 +513,7 @@ static const p6_instruction_t call_far_op = .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 28, .latency = 28} + .uop[5] = {.type = UOP_ALU0_SEG, .throughput = 28, .latency = 28} }; static const p6_instruction_t load_call_far_op = { @@ -523,7 +524,7 @@ static const p6_instruction_t load_call_far_op = .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU0, .throughput = 28, .latency = 28} + .uop[6] = {.type = UOP_ALU0_SEG, .throughput = 28, .latency = 28} }; static const p6_instruction_t cli_op = { @@ -676,15 +677,15 @@ static const p6_instruction_t invd_op = static const p6_instruction_t jmp_far_op = { .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0, .throughput = 21, .latency = 21} + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 21, .latency = 21} }; static const p6_instruction_t load_jmp_far_op = { .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU0, .throughput = 21, .latency = 21} + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU0_SEG, .throughput = 21, .latency = 21} }; static const p6_instruction_t lss_op = { @@ -692,7 +693,7 @@ static const p6_instruction_t lss_op = .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0_SEG,.throughput = 1, .latency = 1}, .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, @@ -712,7 +713,7 @@ static const p6_instruction_t mov_seg_mem_op = { .nr_uops = 9, .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0_SEG,.throughput = 1, .latency = 1}, .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, @@ -725,7 +726,7 @@ static const p6_instruction_t mov_seg_reg_op = { .nr_uops = 8, .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0_SEG,.throughput = 1, .latency = 1}, .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, @@ -1593,11 +1594,11 @@ static const p6_port_t ports[] = {UNIT_STORE_ADDR}, {UNIT_STORE_DATA} }; - +const int nr_ports = (sizeof(ports) / sizeof(p6_port_t)); static p6_unit_t units[] = { - [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU01), .port = 0}, /*Integer 0*/ + [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU0_SEG) | (1 << UOP_ALU01), .port = 0}, /*Integer 0*/ [UNIT_INT1] = {.uop_mask = (1 << UOP_ALU1) | (1 << UOP_ALU01), .port = 1}, /*Integer 1*/ [UNIT_FPU] = {.uop_mask = 1 << UOP_FLOAT, .port = 0}, [UNIT_MMX_ADD] = {.uop_mask = 0, .port = 1}, @@ -1654,6 +1655,24 @@ static int uop_run(const p6_uop_t *uop, int decode_time) if (!best_unit) fatal("uop_run: can not find execution unit %x\n", uop->type); + if (cpu_s->cpu_type == CPU_PENTIUMPRO && uop->type == UOP_ALU0_SEG) + { + /*Pentium Pro will flush pipeline on a segment load. Find last + execution unit to complete, then set earliest start times on + _all_ execution units to after this point*/ + int last_start_cycle = 0; + + for (c = 0; c < nr_units; c++) + { + p6_unit_t *unit = &units[c]; + int start_cycle = unit->first_available_cycle; + + if (start_cycle > last_start_cycle) + last_start_cycle = start_cycle; + } + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = last_start_cycle+1; + } if (best_start_cycle < decode_time) best_start_cycle = decode_time; best_unit->first_available_cycle = best_start_cycle + uop->throughput; diff --git a/src/cpu.c b/src/cpu.c index 0c4487d..ce1dbc0 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -177,10 +177,10 @@ int fpu_get_type_from_index(int model, int manu, int cpu, int c) return fpus[c].type; } +CPU *cpu_s; + void cpu_set() { - CPU *cpu_s; - if (!models[model].cpu[cpu_manufacturer].cpus) { /*CPU is invalid, set to default*/ diff --git a/src/cpu.h b/src/cpu.h index ca8f4da..ee54925 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -102,6 +102,8 @@ typedef struct int atclk_div; } CPU; +extern CPU *cpu_s; + extern CPU cpus_8088[]; extern CPU cpus_8086[]; extern CPU cpus_286[]; From 91e165a6d644471a77c4e7445e2377f43aaa4bf3 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 11 Nov 2020 19:55:48 +0000 Subject: [PATCH 0950/1050] Reduce level of Voodoo Banshee/3 logging. --- src/vid_voodoo_banshee.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index fa14821..97b6deb 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -375,7 +375,7 @@ static void banshee_recalctimings(svga_t *svga) if (svga->crtc[0x1b] & 0x04) svga->dispend += 0x400; if (svga->crtc[0x1b] & 0x10) svga->vblankstart += 0x400; if (svga->crtc[0x1b] & 0x40) svga->vsyncstart += 0x400; - pclog("svga->hdisp=%i\n", svga->hdisp); +// pclog("svga->hdisp=%i\n", svga->hdisp); if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) { @@ -406,7 +406,7 @@ static void banshee_recalctimings(svga_t *svga) svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; svga->ma_latch = banshee->vidDesktopStartAddr >> 2; banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; - pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); +// pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); svga->char_width = 8; svga->split = 99999; @@ -430,11 +430,11 @@ static void banshee_recalctimings(svga_t *svga) svga->overlay.ena = 0; if (svga->overlay.ena) { - pclog("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", +/* pclog("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", voodoo->overlay.start_x, voodoo->overlay.start_y, voodoo->overlay.end_x, voodoo->overlay.end_y, voodoo->overlay.size_x, voodoo->overlay.size_y, - svga->overlay.pitch); + svga->overlay.pitch);*/ if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && svga->hdisp == voodoo->overlay.size_x && svga->dispend == voodoo->overlay.size_y) { @@ -452,7 +452,7 @@ static void banshee_recalctimings(svga_t *svga) } else { - pclog("Normal shift out\n"); +// pclog("Normal shift out\n"); svga->bpp = 8; svga->video_res_override = 0; } @@ -1880,7 +1880,7 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) if (func) return 0xff; - pclog("Banshee PCI read %08X ", addr); +// pclog("Banshee PCI read %08X ", addr); switch (addr) { case 0x00: ret = 0x1a; break; /*3DFX*/ @@ -1935,7 +1935,7 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x3f: ret = 0xff; break; } - pclog("%02X\n", ret); +// pclog("%02X\n", ret); return ret; } @@ -1950,7 +1950,7 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) if (func) return; - pclog("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); +// pclog("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: From a366d977aa1b03b6baeb1279277556a7d8e95551 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Nov 2020 08:10:07 +0000 Subject: [PATCH 0951/1050] Added Voodoo Banshee/3 screen filter. Patch from leilei. --- src/vid_voodoo.c | 2 +- src/vid_voodoo_banshee.c | 364 ++++++++++++++++++++++++++++++++++++++- src/vid_voodoo_common.h | 11 +- src/vid_voodoo_display.c | 11 +- 4 files changed, 372 insertions(+), 16 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 5d556df..a9fc77c 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -1096,7 +1096,7 @@ void *voodoo_2d3d_card_init(int type) memset(voodoo, 0, sizeof(voodoo_t)); voodoo->bilinear_enabled = device_get_config_int("bilinear"); - voodoo->scrfilter = 0; + voodoo->scrfilter = device_get_config_int("dacfilter"); voodoo->render_threads = device_get_config_int("render_threads"); voodoo->odd_even_mask = voodoo->render_threads - 1; #ifndef NO_CODEGEN diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 97b6deb..da14e09 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -12,6 +12,7 @@ #include "vid_svga_render.h" #include "vid_voodoo_banshee.h" #include "vid_voodoo_common.h" +#include "vid_voodoo_display.h" #include "vid_voodoo_fifo.h" #include "vid_voodoo_regs.h" #include "vid_voodoo_render.h" @@ -21,6 +22,12 @@ #undef CLAMP #endif +static uint8_t vb_filter_v1_rb[256][256]; +static uint8_t vb_filter_v1_g [256][256]; + +static uint8_t vb_filter_bx_rb[256][256]; +static uint8_t vb_filter_bx_g [256][256]; + enum { TYPE_BANSHEE = 0, @@ -108,6 +115,7 @@ enum DAC_dacData = 0x54, Video_vidProcCfg = 0x5c, + Video_maxRgbDelta = 0x58, Video_hwCurPatAddr = 0x60, Video_hwCurLoc = 0x64, Video_hwCurC0 = 0x68, @@ -587,6 +595,17 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) svga_recalctimings(svga); break; + case Video_maxRgbDelta: + banshee->voodoo->scrfilterThreshold = val; + if (val > 0x00) + banshee->voodoo->scrfilterEnabled = 1; + else + banshee->voodoo->scrfilterEnabled = 0; + voodoo_threshold_check(banshee->voodoo); + pclog("Banshee Filter: %06x\n", val); + + break; + case Video_hwCurPatAddr: banshee->hwCurPatAddr = val; svga->hwcursor.addr = val & 0xfffff0; @@ -1724,6 +1743,141 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) } \ } while (0) +/* generate both filters for the static table here */ +void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) +{ + int g, h; + float difference, diffg; + float thiscol, thiscolg; + float clr, clg = 0; + float hack = 1.0f; + // pre-clamping + + fcr *= hack; + fcg *= hack; + + + /* box prefilter */ + 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 = g; + avgdiff = avg - h; + + avgdiff = avgdiff * 0.75f; + if (avgdiff < 0) avgdiff *= -1; + if (difference < 0) difference *= -1; + + thiscol = thiscolg = g; + + if (h > g) + { + clr = clg = avgdiff; + + if (clr>fcr) clr=fcr; + if (clg>fcg) clg=fcg; + + thiscol = g; + thiscolg = g; + + if (thiscol>g+fcr) + thiscol=g+fcr; + if (thiscolg>g+fcg) + thiscolg=g+fcg; + + if (thiscol>g+difference) + thiscol=g+difference; + if (thiscolg>g+difference) + thiscolg=g+difference; + + // hmm this might not be working out.. + int ugh = g - h; + if (ugh < fcr) + thiscol = h; + if (ugh < fcg) + thiscolg = h; + } + + if (difference > fcr) + thiscol = g; + if (difference > fcg) + thiscolg = g; + + // clamp + if (thiscol < 0) thiscol = 0; + if (thiscolg < 0) thiscolg = 0; + + if (thiscol > 255) thiscol = 255; + if (thiscolg > 255) thiscolg = 255; + + vb_filter_bx_rb[g][h] = (thiscol); + vb_filter_bx_g [g][h] = (thiscolg); + + } + float 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; + } + + /* 4x1 and 2x2 filter */ + //fcr *= 5; + //fcg *= 6; + + for (g=0;g<256;g++) // pixel 1 + { + for (h=0;h<256;h++) // pixel 2 + { + difference = (float)(h - g); + diffg = difference; + + thiscol = thiscolg = g; + + if (difference > fcr) + difference = fcr; + if (difference < -fcr) + difference = -fcr; + + if (diffg > fcg) + diffg = fcg; + if (diffg < -fcg) + diffg = -fcg; + + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); + + if (thiscol < 0) + thiscol = 0; + if (thiscol > 255) + thiscol = 255; + + if (thiscolg < 0) + thiscolg = 0; + if (thiscolg > 255) + thiscolg = 255; + + vb_filter_v1_rb[g][h] = thiscol; + vb_filter_v1_g [g][h] = thiscolg; + + } + } + +} + + static void banshee_overlay_draw(svga_t *svga, int displine) { banshee_t *banshee = (banshee_t *)svga->p; @@ -1740,14 +1894,21 @@ static void banshee_overlay_draw(svga_t *svga, int displine) uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; uint32_t src_x = 0; unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; + int skip_filtering; // pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); // if (src_addr >= 0x800000) // fatal("overlay out of range!\n"); p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + 32]; - if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && - !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)) + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && + !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && + !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); + else + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR); + + if (skip_filtering) { /*No scaling or filtering required, just write straight to output buffer*/ OVERLAY_SAMPLE(p); @@ -1810,6 +1971,175 @@ static void banshee_overlay_draw(svga_t *svga, int displine) } break; + case VIDPROCCFG_FILTER_MODE_DITHER_4X4: + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) + { + uint8_t fil[(svga->overlay_latch.xsize) * 3]; + uint8_t fil3[(svga->overlay_latch.xsize) * 3]; + + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */ + { + for (x=0; xoverlay_latch.xsize;x++) + { + fil[x*3] = ((banshee->overlay_buffer[0][src_x >> 20])); + fil[x*3+1] = ((banshee->overlay_buffer[0][src_x >> 20] >> 8)); + fil[x*3+2] = ((banshee->overlay_buffer[0][src_x >> 20] >> 16)); + fil3[x*3+0] = fil[x*3+0]; + fil3[x*3+1] = fil[x*3+1]; + fil3[x*3+2] = fil[x*3+2]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } + else + { + for (x=0; xoverlay_latch.xsize;x++) + { + fil[x*3] = ((banshee->overlay_buffer[0][x])); + fil[x*3+1] = ((banshee->overlay_buffer[0][x] >> 8)); + fil[x*3+2] = ((banshee->overlay_buffer[0][x] >> 16)); + fil3[x*3+0] = fil[x*3+0]; + fil3[x*3+1] = fil[x*3+1]; + fil3[x*3+2] = fil[x*3+2]; + } + } + if (y % 2 == 0) + { + for (x=0; xoverlay_latch.xsize;x++) + { + fil[x*3] = banshee->voodoo->purpleline[fil[x*3+0]][0]; + fil[x*3+1] = banshee->voodoo->purpleline[fil[x*3+1]][1]; + fil[x*3+2] = banshee->voodoo->purpleline[fil[x*3+2]][2]; + } + } + + for (x=1; xoverlay_latch.xsize;x++) + { + fil3[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil[(x-1) *3]]; + fil3[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil[(x-1) *3+1]]; + fil3[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil[(x-1) *3+2]]; + } + for (x=1; xoverlay_latch.xsize;x++) + { + fil[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil3[(x-1) *3]]; + fil[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil3[(x-1) *3+1]]; + fil[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil3[(x-1) *3+2]]; + } + for (x=1; xoverlay_latch.xsize;x++) + { + fil3[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil[(x-1) *3]]; + fil3[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil[(x-1) *3+1]]; + fil3[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil[(x-1) *3+2]]; + } + for (x=0; xoverlay_latch.xsize;x++) + { + fil[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil3[(x+1) *3]]; + fil[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil3[(x+1) *3+1]]; + fil[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil3[(x+1) *3+2]]; + p[x] = (fil[x*3+2] << 16) | (fil[x*3+1] << 8) | fil[x*3]; + } + } + else /* filter disabled by emulator option */ + { + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + } + break; + + case VIDPROCCFG_FILTER_MODE_DITHER_2X2: + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) + { + uint8_t fil[(svga->overlay_latch.xsize) * 3]; + uint8_t soak[(svga->overlay_latch.xsize) * 3]; + uint8_t soak2[(svga->overlay_latch.xsize) * 3]; + + uint8_t samp1[(svga->overlay_latch.xsize) * 3]; + uint8_t samp2[(svga->overlay_latch.xsize) * 3]; + uint8_t samp3[(svga->overlay_latch.xsize) * 3]; + uint8_t samp4[(svga->overlay_latch.xsize) * 3]; + + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(banshee->overlay_buffer[1]); + for (x=0; xoverlay_latch.xsize;x++) + { + samp1[x*3] = ((banshee->overlay_buffer[0][x])); + samp1[x*3+1] = ((banshee->overlay_buffer[0][x] >> 8)); + samp1[x*3+2] = ((banshee->overlay_buffer[0][x] >> 16)); + + samp2[x*3+0] = ((banshee->overlay_buffer[0][x+1])); + samp2[x*3+1] = ((banshee->overlay_buffer[0][x+1] >> 8)); + samp2[x*3+2] = ((banshee->overlay_buffer[0][x+1] >> 16)); + + samp3[x*3+0] = ((banshee->overlay_buffer[1][x])); + samp3[x*3+1] = ((banshee->overlay_buffer[1][x] >> 8)); + samp3[x*3+2] = ((banshee->overlay_buffer[1][x] >> 16)); + + samp4[x*3+0] = ((banshee->overlay_buffer[1][x+1])); + samp4[x*3+1] = ((banshee->overlay_buffer[1][x+1] >> 8)); + samp4[x*3+2] = ((banshee->overlay_buffer[1][x+1] >> 16)); + + /* sample two lines */ + + soak[x*3+0] = vb_filter_bx_rb [samp1[x*3+0]] [samp2[x*3+0]]; + soak[x*3+1] = vb_filter_bx_g [samp1[x*3+1]] [samp2[x*3+1]]; + soak[x*3+2] = vb_filter_bx_rb [samp1[x*3+2]] [samp2[x*3+2]]; + + soak2[x*3+0] = vb_filter_bx_rb[samp3[x*3+0]] [samp4[x*3+0]]; + soak2[x*3+1] = vb_filter_bx_g [samp3[x*3+1]] [samp4[x*3+1]]; + soak2[x*3+2] = vb_filter_bx_rb[samp3[x*3+2]] [samp4[x*3+2]]; + + /* then pour it on the rest */ + + fil[x*3+0] = vb_filter_v1_rb[soak[x*3+0]] [soak2[x*3+0]]; + fil[x*3+1] = vb_filter_v1_g [soak[x*3+1]] [soak2[x*3+1]]; + fil[x*3+2] = vb_filter_v1_rb[soak[x*3+2]] [soak2[x*3+2]]; + } + + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ + { + for (x=0; xoverlay_latch.xsize;x++) + { + p[x] = (fil[(src_x >> 20)*3+2] << 16) | (fil[(src_x >> 20)*3+1] << 8) | fil[(src_x >> 20)*3]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } + else + { + for (x=0; xoverlay_latch.xsize;x++) + { + p[x] = (fil[x*3+2] << 16) | (fil[x*3+1] << 8) | fil[x*3]; + } + } + } + else /* filter disabled by emulator option */ + { + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + + src_x += voodoo->overlay.vidOverlayDudx; + } + } + else + { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + } + break; + case VIDPROCCFG_FILTER_MODE_POINT: default: if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) @@ -2054,6 +2384,12 @@ static device_config_t banshee_sgram_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, { .name = "render_threads", .description = "Render threads", @@ -2099,6 +2435,12 @@ static device_config_t banshee_sdram_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, { .name = "render_threads", .description = "Render threads", @@ -2212,6 +2554,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t banshee->voodoo->tex_mem[1] = banshee->svga.vram; banshee->voodoo->tex_mem_w[1] = (uint16_t *)banshee->svga.vram; banshee->voodoo->texture_mask = banshee->svga.vram_mask; + voodoo_generate_filter_v1(banshee->voodoo); banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; @@ -2333,6 +2676,23 @@ static void banshee_add_status_info(char *s, int max_len, void *p) } strncat(s, temps, max_len); + + strncat(s, "Overlay mode: ", max_len); /* leilei debug additions */ + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_DITHER_2X2) + strncat(s, "2x2 box filter\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_DITHER_4X4) + strncat(s, "4x1 tap filter\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_POINT) + strncat(s, "Nearest neighbor\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_BILINEAR) + strncat(s, "Bilinear filtered\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)) + strncat(s, "H scaled \n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) + strncat(s, "V scaled \n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_2X_MODE)) + strncat(s, "2X mode\n", max_len); + strncat(s, "\n", max_len); for (c = 0; c < 4; c++) diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 364407f..14f775f 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -451,11 +451,10 @@ typedef struct voodoo_t pc_timer_t wake_timer; - uint8_t thefilter[256][256]; // pixel filter, feeding from one or two - uint8_t thefilterg[256][256]; // for green - uint8_t thefilterb[256][256]; // for blue - - /* the voodoo adds purple lines for some reason */ + /* screen filter tables */ + uint8_t thefilter[256][256]; + uint8_t thefilterg[256][256]; + uint8_t thefilterb[256][256]; uint16_t purpleline[256][3]; texture_t texture_cache[2][TEX_CACHE_MAX]; @@ -492,7 +491,7 @@ typedef struct voodoo_set_t extern rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; - +void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg); void voodoo_recalc(voodoo_t *voodoo); void voodoo_update_ncc(voodoo_t *voodoo, int tmu); diff --git a/src/vid_voodoo_display.c b/src/vid_voodoo_display.c index a8cda43..9ce92dd 100644 --- a/src/vid_voodoo_display.c +++ b/src/vid_voodoo_display.c @@ -196,7 +196,7 @@ void voodoo_generate_filter_v2(voodoo_t *voodoo) { int g, h; float difference; - float thiscol, thiscolg, thiscolb, lined; + float thiscol, thiscolg, thiscolb; float clr, clg, clb = 0; float fcr, fcg, fcb = 0; @@ -282,12 +282,6 @@ void voodoo_generate_filter_v2(voodoo_t *voodoo) //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][0] = lined; - voodoo->purpleline[g][1] = 0; - voodoo->purpleline[g][2] = lined; } } @@ -317,6 +311,9 @@ void voodoo_threshold_check(voodoo_t *voodoo) voodoo_generate_filter_v2(voodoo); else voodoo_generate_filter_v1(voodoo); + + if (voodoo->type >= VOODOO_BANSHEE) + voodoo_generate_vb_filters(voodoo, FILTCAP, FILTCAPG); } } From 86a5b13f46cc61c7dd7c0012f825ee89a0b02550 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Nov 2020 08:30:34 +0000 Subject: [PATCH 0952/1050] Add dirty updating for Voodoo Banshee/3 overlay. --- src/vid_voodoo_banshee.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index da14e09..691600f 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1896,6 +1896,17 @@ static void banshee_overlay_draw(svga_t *svga, int displine) unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; int skip_filtering; + if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && + !svga->fullchange && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) + { + if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) + voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; + else + voodoo->overlay.src_y += (1 << 20); + return; + } + + voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; // pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); // if (src_addr >= 0x800000) // fatal("overlay out of range!\n"); @@ -2169,9 +2180,11 @@ static void banshee_overlay_draw(svga_t *svga, int displine) void banshee_set_overlay_addr(void *p, uint32_t addr) { banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; + memset(voodoo->dirty_line, 1, 1024); } static void banshee_vsync_callback(svga_t *svga) From ed37bc4e24c6100a9e3cfe0bb093cbabbbc05419 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Nov 2020 19:38:28 +0000 Subject: [PATCH 0953/1050] Fix Banshee/V3 mappings following write of PCI command register. Fixes hang following monitor suspend/wakeup. --- src/vid_voodoo_banshee.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 691600f..368eef3 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -2282,10 +2282,6 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) return ret; } -static void banshee_update_mapping(banshee_t *banshee) -{ -} - static void banshee_pci_write(int func, int addr, uint8_t val, void *p) { banshee_t *banshee = (banshee_t *)p; @@ -2302,7 +2298,6 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) return; case PCI_REG_COMMAND: - banshee_update_mapping(banshee); if (val & PCI_COMMAND_IO) { io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); @@ -2319,7 +2314,7 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); } banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27; -// s3_virge_updatemapping(virge); + banshee_updatemapping(banshee); return; case 0x07: banshee->pci_regs[0x07] = val & 0x3e; @@ -2330,7 +2325,7 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) case 0x13: banshee->memBaseAddr0 = (val & 0xfe) << 24; - banshee_updatemapping(banshee); + banshee_updatemapping(banshee); return; case 0x17: From 49bdd9534fc3b9861ca1bb527422bdd886f535c2 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 13 Nov 2020 20:35:02 +0000 Subject: [PATCH 0954/1050] Add X11 cursor mode to Banshee/V3. --- src/vid_voodoo_banshee.c | 53 ++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 368eef3..1f0a018 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -147,6 +147,7 @@ enum #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) +#define VIDPROCCFG_CURSOR_MODE (1 << 1) #define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) @@ -1567,25 +1568,51 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) x_off = svga->hwcursor_latch.x; - for (x = 0; x < 64; x += 8) + if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE) { - if (x_off > (32-8)) + /*X11 mode*/ + for (x = 0; x < 64; x += 8) { - int xx; - - for (xx = 0; xx < 8; xx++) + if (x_off > (32-8)) { - if (!(plane0[x >> 3] & (1 << 7))) - ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; - else if (plane1[x >> 3] & (1 << 7)) - ((uint32_t *)buffer32->line[displine])[x_off + xx] ^= 0xffffff; + int xx; - plane0[x >> 3] <<= 1; - plane1[x >> 3] <<= 1; + for (xx = 0; xx < 8; xx++) + { + if (plane0[x >> 3] & (1 << 7)) + ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; + } } - } - x_off += 8; + x_off += 8; + } + } + else + { + /*Windows mode*/ + for (x = 0; x < 64; x += 8) + { + if (x_off > (32-8)) + { + int xx; + + for (xx = 0; xx < 8; xx++) + { + if (!(plane0[x >> 3] & (1 << 7))) + ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + else if (plane1[x >> 3] & (1 << 7)) + ((uint32_t *)buffer32->line[displine])[x_off + xx] ^= 0xffffff; + + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; + } + } + + x_off += 8; + } } } From 9bea8c138a8d463f28ce62e5d65f0f9640df3e94 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 09:22:45 +0000 Subject: [PATCH 0955/1050] Intel Advanced ZP/EV derived systems don't seem to support Cyrix 6x86 CPUs (executes MSR and CPUID instructions without any preceeding checks). Removed these CPUs from those systems. --- src/model.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/model.c b/src/model.c index fd10cb5..6904b44 100644 --- a/src/model.c +++ b/src/model.c @@ -230,10 +230,10 @@ MODEL models[] = {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, {"[Socket 4] Packard Bell PB520R",ROM_PB520R, "pb520r", { {"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb520r_init, NULL}, - {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, - {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, - {"[Socket 5] Itautec Infoway Multimidia", ROM_ITAUTEC_INFOWAYM, "infowaym",{ {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_zappa_init, NULL}, - {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, + {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_zappa_init, NULL}, + {"[Socket 5] Itautec Infoway Multimidia", ROM_ITAUTEC_INFOWAYM, "infowaym",{ {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_zappa_init, NULL}, + {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", { {"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_DISABLE_SW|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 1, 128, 1, at_pb570_init, NULL}, {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}, {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", { {"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, MODEL_GFX_NONE|MODEL_AT|MODEL_PCI|MODEL_PS2|MODEL_HAS_IDE, 8, 256, 1, at_p55t2p4_init, NULL}, From 5ae201b7e7304acc2fcbd4eb52c4650f71859624 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 14 Nov 2020 11:38:04 +0000 Subject: [PATCH 0956/1050] Disable Banshee lazy overlay update when vertical scaling enabled. Fixes artifacts in low resolution modes (where the lazy update has little benefit anyway). --- src/vid_voodoo_banshee.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 1f0a018..697dccd 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1923,13 +1923,12 @@ static void banshee_overlay_draw(svga_t *svga, int displine) unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; int skip_filtering; - if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && - !svga->fullchange && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) + if (svga->render == svga_render_null && + !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && + !svga->fullchange && !voodoo->dirty_line[voodoo->overlay.src_y >> 20] && + !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { - if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) - voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; - else - voodoo->overlay.src_y += (1 << 20); + voodoo->overlay.src_y += (1 << 20); return; } From 322b25a4dca2ee0bd4baa00247fef1f983619052 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Nov 2020 08:58:59 +0000 Subject: [PATCH 0957/1050] VHD build fixes. Patch from shermanp. --- src/minivhd/minivhd_create.c | 2 +- src/minivhd/minivhd_manage.c | 10 ++++++---- src/wx-config.c | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/minivhd/minivhd_create.c b/src/minivhd/minivhd_create.c index e1bf916..9e34ece 100644 --- a/src/minivhd/minivhd_create.c +++ b/src/minivhd/minivhd_create.c @@ -98,7 +98,7 @@ static int mvhd_gen_par_loc(MVHDSparseHeader* header, char child_dir[MVHD_MAX_PATH_BYTES] = {0}; size_t child_dir_len; if (strlen(child_path) < sizeof child_dir) { - strcpy_s(child_dir, MVHD_MAX_PATH_BYTES, child_path); + strcpy(child_dir, child_path); } else { *err = MVHD_ERR_PATH_LEN; rv = -1; diff --git a/src/minivhd/minivhd_manage.c b/src/minivhd/minivhd_manage.c index 5942e96..75e0953 100644 --- a/src/minivhd/minivhd_manage.c +++ b/src/minivhd/minivhd_manage.c @@ -171,7 +171,7 @@ static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) if (plat_code == MVHD_DIF_LOC_W2RU && *paths->w2ru_path) { cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->w2ru_path, paths->joined_path, sizeof paths->joined_path); } else if (plat_code == MVHD_DIF_LOC_W2KU && *paths->w2ku_path) { - strncpy_s(paths->joined_path, sizeof paths->joined_path, (const char*)paths->w2ku_path, sizeof paths->joined_path); + memcpy(paths->joined_path, paths->w2ku_path, (sizeof paths->joined_path) - 1); cwk_ret = 0; } else if (plat_code == 0) { cwk_ret = cwk_path_join((const char*)paths->dir_path, (const char*)paths->file_name, paths->joined_path, sizeof paths->joined_path); @@ -182,7 +182,8 @@ static bool mvhd_parent_path_exists(struct MVHDPaths* paths, uint32_t plat_code) f = mvhd_fopen((const char*)paths->joined_path, "rb", &ferr); if (f != NULL) { /* We found a file at the requested path! */ - strncpy_s(tmp_open_path, sizeof tmp_open_path, paths->joined_path, sizeof tmp_open_path); + memcpy(tmp_open_path, paths->joined_path, (sizeof paths->joined_path) - 1); + tmp_open_path[sizeof tmp_open_path - 1] = '\0'; fclose(f); return true; } else { @@ -225,7 +226,7 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { *err = MVHD_ERR_PATH_LEN; goto paths_cleanup; } - strncpy_s(paths->dir_path, sizeof paths->dir_path, vhdm->filename, dirlen); + memcpy(paths->dir_path, vhdm->filename, dirlen); /* Get the filename field from the sparse header. */ utf_outlen = (int)sizeof paths->file_name; utf_inlen = (int)sizeof vhdm->sparse.par_utf16_name; @@ -373,7 +374,8 @@ MVHDMeta* mvhd_open(const char* path, bool readonly, int* err) { *err = MVHD_ERR_PATH_LEN; goto cleanup_vhdm; } - strcpy_s(vhdm->filename, sizeof vhdm->filename, path); + //This is safe, as we've just checked for potential overflow above + strcpy(vhdm->filename, path); vhdm->f = readonly ? mvhd_fopen((const char*)vhdm->filename, "rb", err) : mvhd_fopen((const char*)vhdm->filename, "rb+", err); if (vhdm->f == NULL) { /* note, mvhd_fopen sets err for us */ diff --git a/src/wx-config.c b/src/wx-config.c index a35f8da..2421d67 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -20,8 +20,8 @@ #include "video.h" #include "vid_voodoo.h" -#include "MiniVHD/minivhd.h" -#include "MiniVHD/minivhd_util.h" +#include "minivhd/minivhd.h" +#include "minivhd/minivhd_util.h" //#define MAX_CYLINDERS ((((1 << 28)-1) / 16) / 63) #define MAX_CYLINDERS 265264 /*Award 430VX won't POST with a larger drive*/ From 95e6819f02afe46da336b028c23a2b5fbdbacb7a Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Nov 2020 09:02:32 +0000 Subject: [PATCH 0958/1050] Remove use of _wfopen_s in minivhd. --- src/minivhd/minivhd_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/minivhd/minivhd_util.c b/src/minivhd/minivhd_util.c index d1ddab2..d8f44ca 100644 --- a/src/minivhd/minivhd_util.c +++ b/src/minivhd/minivhd_util.c @@ -139,8 +139,8 @@ FILE* mvhd_fopen(const char* path, const char* mode, int* err) { int path_res = UTF8ToUTF16LE((unsigned char*)new_path, &new_path_len, (const unsigned char*)path, (int*)&path_len); int mode_res = UTF8ToUTF16LE((unsigned char*)mode_str, &new_mode_len, (const unsigned char*)mode, (int*)&mode_len); if (path_res > 0 && mode_res > 0) { - int wfopen_err = _wfopen_s(&f, new_path, mode_str); - if (wfopen_err != 0 || f == NULL) { + f = _wfopen(new_path, mode_str); + if (f == NULL) { mvhd_errno = errno; *err = MVHD_ERR_FILE; } From a89347d4158c611129f7743e029d91d082c37665 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Nov 2020 11:11:41 +0000 Subject: [PATCH 0959/1050] Add Amstrad PC5086 emulation. Patch from davide78. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- src/f82c710_upc.c | 344 +++++++++++++++++++++++------ src/f82c710_upc.h | 2 + src/fdc.c | 4 +- src/ibm.h | 1 + src/keyboard_at.c | 2 +- src/keyboard_at.h | 1 + src/mem_bios.c | 8 + src/model.c | 19 +- src/mouse_ps2.c | 11 +- src/nvr.c | 2 + src/pic.c | 89 ++++---- src/serial.c | 8 + src/serial.h | 2 + src/superxt.c | 60 +++++ src/superxt.h | 1 + 18 files changed, 428 insertions(+), 132 deletions(-) create mode 100644 src/superxt.c create mode 100644 src/superxt.h diff --git a/src/Makefile.am b/src/Makefile.am index ca69439..8197093 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi scsi_ibm.c scsi_zip.c serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_audiopci.c \ sound_azt2316a.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 \ -sst39sf010.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.c timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c \ +sst39sf010.c superxt.c tandy_eeprom.c tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ddc.c vid_ega.c \ vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c \ vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 790468e..4d16048 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -29,7 +29,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ + sound_ym7128.o soundopenal.o sst39sf010.o superxt.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ddc.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index 6952573..d181926 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -29,7 +29,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_audiopci.o sound_azt2316a.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 sst39sf010.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ + sound_ym7128.o soundopenal.o sst39sf010.o superxt.o t1000.o t3100e.o tandy_eeprom.o tandy_rom.o timer.o um8881f.o um8669f.o \ vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \ vid_cl5429.o vid_colorplus.o vid_compaq_cga.o vid_ddc.o vid_ega.o vid_et4000.o vid_et4000w32.o \ vid_et4000w32i.o vid_genius.o vid_hercules.o vid_ht216.o vid_icd2061.o vid_ics2595.o vid_im1024.o vid_incolor.o vid_mda.o \ diff --git a/src/f82c710_upc.c b/src/f82c710_upc.c index f700d04..40dfd19 100644 --- a/src/f82c710_upc.c +++ b/src/f82c710_upc.c @@ -36,11 +36,24 @@ #include "io.h" #include "lpt.h" #include "serial.h" +#include "x86.h" +#include "keyboard_at.h" +#include "pic.h" + +#define UPC_MOUSE_DEV_IDLE 0x01 /* bit 0, Device Idle */ +#define UPC_MOUSE_RX_FULL 0x02 /* bit 1, Device Char received */ +#define UPC_MOUSE_TX_IDLE 0x04 /* bit 2, Device XMIT Idle */ +#define UPC_MOUSE_RESET 0x08 /* bit 3, Device Reset */ +#define UPC_MOUSE_INTS_ON 0x10 /* bit 4, Device Interrupt On */ +#define UPC_MOUSE_ERROR_FLAG 0x20 /* bit 5, Device Error */ +#define UPC_MOUSE_CLEAR 0x40 /* bit 6, Device Clear */ +#define UPC_MOUSE_ENABLE 0x80 /* bit 7, Device Enable */ typedef struct upc_t { int configuration_state; // state of algorithm to enter configuration mode int configuration_mode; + uint8_t next_value; // next expected value of configuration algorithm uint16_t cri_addr; // cri = configuration index register, addr is even uint16_t cap_addr; // cap = configuration access port, addr is odd and is cri_addr + 1 uint8_t cri; // currently indexed register @@ -50,81 +63,139 @@ typedef struct upc_t int serial_irq; int parallel_irq; // TODO: currently not implemented in PCem + + int mouse_irq; + uint16_t mdata_addr; // Address of PS/2 data register + uint16_t mstat_addr; // Address of PS/2 status register + uint8_t mouse_status; // Mouse interface status register + uint8_t mouse_data; // Mouse interface data register + void (*mouse_write)(uint8_t val, void *p); + void *mouse_p; + pc_timer_t mouse_delay_timer; } upc_t; static upc_t upc; -void upc_update_ports(upc_t *upc) +uint8_t upc_config_read(uint16_t port, void *priv); +void upc_config_write(uint16_t port, uint8_t val, void *priv); + +void upc_mouse_disable(upc_t *upc); +void upc_mouse_enable(upc_t *upc); +uint8_t upc_mouse_read(uint16_t port, void *priv); +void upc_mouse_write(uint16_t port, uint8_t val, void *priv); +void upc_mouse_poll(void *priv); + +void upc_update_config(upc_t *upc) { - serial1_remove(); - serial2_remove(); - lpt1_remove(); - lpt2_remove(); - fdc_remove(); - ide_pri_disable(); - ide_sec_disable(); - - if (upc->regs[0] & 0x4) + switch(upc->cri) { - serial1_init(upc->regs[4] * 4, upc->serial_irq, 0); - pclog("UPC: UART at %04X, irq %d\n", upc->regs[4] * 4, upc->serial_irq); - } - else - pclog("UPC: UART disabled\n"); + case 0: + if (upc->regs[0] & 0x4) + { + serial1_set(upc->regs[4] * 4, upc->serial_irq); + pclog("UPC: UART at %04X, irq %d\n", upc->regs[4] * 4, upc->serial_irq); + } + else + { + serial1_remove(); + pclog("UPC: UART disabled\n"); + } + if (upc->regs[0] & 0x8) + { + lpt1_init(upc->regs[6] * 4); + pclog("UPC: PARALLEL at %04X, irq %d\n", upc->regs[6] * 4, upc->parallel_irq); + } + else + { + lpt1_remove(); + pclog("UPC: PARALLEL disabled\n"); + } + if ((upc->regs[0] & 0x60) != 0) + pclog("UPC: Oscillator control not implemented!\n"); + break; - if (upc->regs[0] & 0x8) - { - lpt1_init(upc->regs[6] * 4); - pclog("UPC: PARALLEL at %04X, irq %d\n", upc->regs[6] * 4, upc->parallel_irq); - } - else - pclog("UPC: PARALLEL disabled\n"); + case 1: + if ((upc->regs[1] & 0x80) != 0) + pclog("UPC: Restricted serial reset not implemented!\n"); + if ((upc->regs[1] & 0x80) != 0) + pclog("UPC: Restricted serial reset not implemented!\n"); + if ((upc->regs[1] & 0x40) != 0) + pclog("UPC: Bidirectional parallel port support not implemented!\n"); + if ((upc->regs[1] & 0x38) != 0) + pclog("UPC: UART force CTS, DSR, DCD not implemented!\n"); + break; - if (upc->regs[12] & 0x80) - { - ide_pri_enable(); - pclog("UPC: IDE enabled\n"); - } - else - pclog("UPC: IDE disabled\n"); + case 2: + if ((upc->regs[2] & 0x70) != 0) + pclog("UPC: UART clock control not implemented!\n"); + break; - if (upc->regs[12] & 0x20) - { - fdc_add(); - pclog("UPC: FDC enabled\n"); - } - else - pclog("UPC: FDC disabled\n"); + case 9: + if (upc->regs[9] == 0xb0) + pclog("UPC: GPCS not implemented! (at default address: %04X)\n", upc->regs[9] * 4); + else if (upc->regs[9] != 0) + pclog("UPC: GPCS not implemented! (at address: %04X)\n", upc->regs[9] * 4); + break; - if ((upc->regs[0] & 0x60) != 0) - pclog("UPC: Oscillator control not implemented!\n"); - if ((upc->regs[1] & 0x80) != 0) - pclog("UPC: Restricted serial reset not implemented!\n"); - if ((upc->regs[1] & 0x80) != 0) - pclog("UPC: Restricted serial reset not implemented!\n"); - if ((upc->regs[1] & 0x40) != 0) - pclog("UPC: Bidirectional parallel port support not implemented!\n"); - if ((upc->regs[1] & 0x38) != 0) - pclog("UPC: UART force CTS, DSR, DCD not implemented!\n"); - if ((upc->regs[2] & 0x70) != 0) - pclog("UPC: UART clock control not implemented!\n"); - if (upc->regs[9] == 0xb0) - pclog("UPC: GPCS not implemented! (at default address: %04X)\n", upc->regs[9] * 4); - else if (upc->regs[9] != 0) - pclog("UPC: GPCS not implemented! (at address: %04X)\n", upc->regs[9] * 4); - if ((upc->regs[12] & 0x40) != 0) - pclog("UPC: IDE XT mode not implemented!\n"); - if ((upc->regs[12] & 0x10) != 0) - pclog("UPC: FDC power down mode not implemented!\n"); - if ((upc->regs[12] & 0x0C) != 0) - pclog("UPC: RTCCS not implemented!\n"); - if ((upc->regs[12] & 0x01) != 0) - pclog("UPC: PS/2 mouse port power down not implemented!\n"); - if (upc->regs[13] != 0) - pclog("UPC: PS/2 mouse port not implemented!\n"); - if (upc->regs[14] != 0) - pclog("UPC: Test mode not implemented!\n"); - // regs 10 and 11 not looked at + case 12: + /* Adding the IDE and floppy controllers when they are already present causes problems.*/ + /* FIX: remove floppy and IDE controllers before adding them again if needed. */ + fdc_remove(); + ide_pri_disable(); + if ((upc->regs[12] & 0x40) != 0) + { + pclog("UPC: IDE XT mode not implemented!\n"); + } + else + { + if (upc->regs[12] & 0x80) + { + ide_pri_enable(); + pclog("UPC: AT IDE enabled\n"); + } + else + { + pclog("UPC: AT IDE disabled\n"); + } + } + + if (upc->regs[12] & 0x20) + { + fdc_add(); + pclog("UPC: FDC enabled\n"); + } + else + { + pclog("UPC: FDC disabled\n"); + } + + if ((upc->regs[12] & 0x10) != 0) + pclog("UPC: FDC power down mode not implemented!\n"); + if ((upc->regs[12] & 0x0C) != 0) + pclog("UPC: RTCCS not implemented!\n"); + if ((upc->regs[12] & 0x01) != 0) + pclog("UPC: PS/2 mouse port power down not implemented!\n"); + break; + + case 13: + if (upc->regs[13] != 0) + { + upc->mdata_addr = upc->regs[13] * 4; + upc->mstat_addr = upc->mdata_addr + 1; + pclog("UPC: PS/2 mouse port at %04X, irq %d\n", upc->mdata_addr, upc->mouse_irq); + upc_mouse_enable(upc); + } + else + { + pclog("UPC: PS/2 mouse port disabled\n"); + upc_mouse_disable(upc); + } + + case 14: + if (upc->regs[14] != 0) + pclog("UPC: Test mode not implemented!\n"); + break; + } } uint8_t upc_config_read(uint16_t port, void *priv) @@ -161,8 +232,13 @@ void upc_config_write(uint16_t port, uint8_t val, void *priv) switch(port) { case 0x2fa: - if (upc->configuration_state == 0 && val == 0x55) + /* Execute configuration step 1 for any value except 9, ff or 36 */ + if (upc->configuration_state == 0) + { configuration_state_event = 1; + /* next value should be the 1's complement of the current one */ + upc->next_value = 0xff - val; + } else if (upc->configuration_state == 4) { uint8_t addr_verify = upc->cri_addr / 4; @@ -182,7 +258,8 @@ void upc_config_write(uint16_t port, uint8_t val, void *priv) } break; case 0x3fa: - if (upc->configuration_state == 1 && val == 0xaa) + /* go to configuration step 2 if value is the expected one */ + if (upc->configuration_state == 1 && val == upc->next_value) configuration_state_event = 1; else if (upc->configuration_state == 2 && val == 0x36) configuration_state_event = 1; @@ -201,6 +278,7 @@ void upc_config_write(uint16_t port, uint8_t val, void *priv) if (port == upc->cri_addr) { upc->cri = val & 0xf; + } else if (port == upc->cap_addr) { @@ -209,11 +287,12 @@ void upc_config_write(uint16_t port, uint8_t val, void *priv) pclog("UPC: exiting configuration mode\n"); upc->configuration_mode = 0; io_removehandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, upc); - upc_update_ports(upc); // TODO: any benefit in updating at each register write instead of when exiting config mode? } else { upc->regs[upc->cri] = val; + /* configuration should be updated at each register write, otherwise PC5086 do not detect ports correctly */ + upc_update_config(upc); } } } @@ -228,6 +307,17 @@ void upc_config_write(uint16_t port, uint8_t val, void *priv) static void *upc_init() { pclog("UPC INIT\n"); + + /* Disable all peripherals. upc_update_config will enable configured peripherals */ + serial1_remove(); + serial2_remove(); + lpt1_remove(); + lpt2_remove(); + fdc_remove(); + ide_pri_disable(); + ide_sec_disable(); + serial1_set_has_fifo(0); + memset(&upc, 0, sizeof(upc)); upc.serial_irq = device_get_config_int("serial_irq"); @@ -253,7 +343,21 @@ static void *upc_init() upc.regs[13] = 0x00; upc.regs[14] = 0x00; - upc_update_ports(&upc); + for (upc.cri = 0; upc.cri < 15; upc.cri++) + upc_update_config(&upc); + upc.cri = 0; + + /********************* Initialize mouse interface ********************/ + if(romset == ROM_PC5086) /* IRQ is 2 for PC5086 and 12 for others */ + upc.mouse_irq = 2; + else + upc.mouse_irq = 12; + upc.mdata_addr = upc.regs[13] * 4; + upc.mstat_addr = upc.mdata_addr + 1; + upc.mouse_status = UPC_MOUSE_DEV_IDLE | UPC_MOUSE_TX_IDLE; + upc.mouse_data = 0xff; + /* Set timer for mouse polling */ + timer_add(&upc.mouse_delay_timer, upc_mouse_poll, &upc, 1); return &upc; } @@ -321,3 +425,105 @@ device_t f82c710_upc_device = NULL, upc_config }; + +/****************** PS/2 mouse port *********************/ +uint8_t upc_mouse_read(uint16_t port, void *priv) +{ + upc_t *upc = (upc_t *)priv; + uint8_t temp = 0xff; + if (port == upc->mstat_addr) + { + temp = upc->mouse_status; + } + + if (port == upc->mdata_addr && (upc->mouse_status & UPC_MOUSE_RX_FULL)) + { + temp = upc->mouse_data; + upc->mouse_data = 0xff; + upc->mouse_status &= ~UPC_MOUSE_RX_FULL; + upc->mouse_status |= UPC_MOUSE_DEV_IDLE; + // pclog("%04X:%04X UPC mouse READ: %04X, %02X\n", CS, cpu_state.pc, port, temp); + } + + // pclog("%04X:%04X UPC mouse READ: %04X, %02X\n", CS, cpu_state.pc, port, temp); + return temp; +} + +void upc_mouse_write(uint16_t port, uint8_t val, void *priv) +{ + // pclog("%04X:%04X UPC mouse WRITE: %04X, %02X\n", CS, cpu_state.pc, port, val); + + upc_t *upc = (upc_t *)priv; + if (port == upc->mstat_addr) + { + /* write status bits + * DEV_IDLE, TX_IDLE, RX_FULL and ERROR_FLAG bits are unchanged + */ + upc->mouse_status = (val & 0xD8) | (upc->mouse_status & 0x27); + if (upc->mouse_status & UPC_MOUSE_ENABLE) + mouse_scan = 1; + else + mouse_scan = 0; + if (upc->mouse_status & (UPC_MOUSE_CLEAR | UPC_MOUSE_RESET)) + { + /* if CLEAR or RESET bit is set, clear mouse queue */ + mouse_queue_start = mouse_queue_end; + upc->mouse_status &= ~UPC_MOUSE_RX_FULL; + upc->mouse_status |= UPC_MOUSE_DEV_IDLE | UPC_MOUSE_TX_IDLE; + mouse_scan = 0; + } + } + + if (port == upc->mdata_addr) + { + if ((upc->mouse_status & UPC_MOUSE_TX_IDLE) && (upc->mouse_status & UPC_MOUSE_ENABLE)) + { + upc->mouse_data = val; + if (upc->mouse_write) + upc->mouse_write(val, upc->mouse_p); + } + } +} + +void upc_mouse_disable(upc_t *upc) +{ + io_removehandler(upc->mdata_addr, 0x0002, upc_mouse_read, NULL, NULL, upc_mouse_write, NULL, NULL, upc); +} + +void upc_mouse_enable(upc_t *upc) +{ + io_sethandler(upc->mdata_addr, 0x0002, upc_mouse_read, NULL, NULL, upc_mouse_write, NULL, NULL, upc); +} + +void upc_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) +{ + upc.mouse_write = mouse_write; + upc.mouse_p = p; +} + +void upc_mouse_poll(void *priv) +{ + upc_t *upc = (upc_t *)priv; + timer_advance_u64(&upc->mouse_delay_timer, (1000 * TIMER_USEC)); + + /* check if there is something in the mouse queue */ + if (mouse_queue_start != mouse_queue_end) + { + // pclog("Mouse timer. %d %d %02X %02X\n", mouse_queue_start, mouse_queue_end, upc->mouse_status, upc->mouse_data); + if ((upc->mouse_status & UPC_MOUSE_ENABLE) && !(upc->mouse_status & UPC_MOUSE_RX_FULL)) + { + upc->mouse_data = mouse_queue[mouse_queue_start]; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; + /* update mouse status */ + upc->mouse_status |= UPC_MOUSE_RX_FULL; + upc->mouse_status &= ~(UPC_MOUSE_DEV_IDLE); + // pclog("Reading %02X from the mouse queue at %i %i. New status is %02X\n", upc->mouse_data, mouse_queue_start, mouse_queue_end, upc->mouse_status); + /* raise IRQ if enabled */ + if (upc->mouse_status & UPC_MOUSE_INTS_ON) + { + picint(1 << upc->mouse_irq); + // pclog("upc_mouse : take IRQ %d\n", upc->mouse_irq); + } + } + } +} diff --git a/src/f82c710_upc.h b/src/f82c710_upc.h index fd816d8..05764af 100644 --- a/src/f82c710_upc.h +++ b/src/f82c710_upc.h @@ -1,4 +1,6 @@ #include "device.h" +void upc_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p); + extern device_t f82c710_upc_device; diff --git a/src/fdc.c b/src/fdc.c index 514bc07..e818c93 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -97,7 +97,7 @@ void fdc_reset() fdc.lock = 0; fdc.head = 0; fdc.abort = 0; - if (!AT && romset != ROM_XI8088) + if (!AT && romset != ROM_XI8088 && romset != ROM_PC5086) { fdc.rate = 2; // fdc_update_rate(); @@ -674,7 +674,7 @@ bad_command: } return; case 7: - if (!AT && romset != ROM_XI8088) + if (!AT && romset != ROM_XI8088 && romset != ROM_PC5086) return; fdc.rate=val&3; diff --git a/src/ibm.h b/src/ibm.h index a7925c3..75d476b 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -266,6 +266,7 @@ enum ROM_DESKPRO, ROM_VS440FX, ROM_GA686BX, + ROM_PC5086, ROM_MAX }; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 572ab30..f86cb21 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -90,7 +90,7 @@ static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0; static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; -static uint8_t mouse_queue[16]; +uint8_t mouse_queue[16]; int mouse_queue_start = 0, mouse_queue_end = 0; void keyboard_at_adddata_keyboard(uint8_t val); diff --git a/src/keyboard_at.h b/src/keyboard_at.h index 6271e75..5dc00fa 100644 --- a/src/keyboard_at.h +++ b/src/keyboard_at.h @@ -5,5 +5,6 @@ void keyboard_at_poll(); void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p); void keyboard_at_adddata_mouse(uint8_t val); +extern uint8_t mouse_queue[16]; extern int mouse_queue_start, mouse_queue_end; extern int mouse_scan; diff --git a/src/mem_bios.c b/src/mem_bios.c index f461a79..2b6b174 100644 --- a/src/mem_bios.c +++ b/src/mem_bios.c @@ -249,6 +249,14 @@ int loadbios() biosmask = 0x3fff; return 1; + case ROM_PC5086: + f = romfopen("pc5086/sys_rom.bin" ,"rb"); + if (!f) break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + + case ROM_IBMAT: /* f=romfopen("amic206.bin","rb"); if (!f) break; diff --git a/src/model.c b/src/model.c index 6904b44..672b110 100644 --- a/src/model.c +++ b/src/model.c @@ -68,6 +68,7 @@ #include "sound_ps1.h" #include "sound_pssj.h" #include "sound_sn76489.h" +#include "superxt.h" #include "sst39sf010.h" #include "tandy_eeprom.h" #include "tandy_rom.h" @@ -88,6 +89,7 @@ void pcjr_init(); void tandy1k_init(); void tandy1ksl2_init(); void ams_init(); +void pc5086_init(); void europc_init(); void olim24_init(); void at_init(); @@ -167,6 +169,7 @@ MODEL models[] = {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams1512_device}, {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams2086_device}, {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams3086_device}, + {"[8086] Amstrad PC5086", ROM_PC5086, "pc5086", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE|MODEL_PS2, 640, 640, 0, pc5086_init, &f82c710_upc_device}, {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW|MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}, {"[8086] Compaq Deskpro", ROM_DESKPRO, "deskpro", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, compaq_xt_init, NULL}, {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED|MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, @@ -403,11 +406,23 @@ void ams_init() amstrad_init(); keyboard_amstrad_init(); device_add(&nvr_device); - nmi_init(); - fdc_set_dskchg_activelow(); + nmi_init(); + fdc_set_dskchg_activelow(); device_add(&gameport_device); } +void pc5086_init() +{ + xt_init(); + lpt1_remove(); /* remove LPT ports, they will be enabled by 82C710 */ + lpt2_remove(); + serial1_remove(); /* remove COM ports, they will be enabled by 82C710 */ + serial2_remove(); + device_add(&nvr_device); + fdc_set_dskchg_activelow(); + superxt_init(); +} + void europc_init() { common_init(); diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index e6c065f..28a362b 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -4,6 +4,8 @@ #include "mouse.h" #include "mouse_ps2.h" #include "plat-mouse.h" +#include "x86.h" +#include "f82c710_upc.h" int mouse_scan = 0; @@ -175,7 +177,7 @@ void 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; @@ -236,8 +238,11 @@ void *mouse_ps2_init() mouse->flags = 0; mouse->mode = MOUSE_STREAM; - keyboard_at_set_mouse(mouse_ps2_write, mouse); - + if(romset == ROM_PC5086) + upc_set_mouse(mouse_ps2_write, mouse); + else + keyboard_at_set_mouse(mouse_ps2_write, mouse); + return mouse; } diff --git a/src/nvr.c b/src/nvr.c index 0c813c6..7a96db5 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -284,6 +284,7 @@ void loadnvr() case ROM_PC200: f = nvrfopen("pc200.nvr", "rb"); break; case ROM_PC2086: f = nvrfopen("pc2086.nvr", "rb"); break; case ROM_PC3086: f = nvrfopen("pc3086.nvr", "rb"); break; + case ROM_PC5086: f = nvrfopen("pc5086.nvr", "rb"); break; case ROM_PPC512: f = nvrfopen("ppc512.nvr", "rb"); break; case ROM_IBMAT: f = nvrfopen("at.nvr", "rb"); break; case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "rb"); break; @@ -393,6 +394,7 @@ void savenvr() case ROM_PC200: f = nvrfopen("pc200.nvr", "wb"); break; case ROM_PC2086: f = nvrfopen("pc2086.nvr", "wb"); break; case ROM_PC3086: f = nvrfopen("pc3086.nvr", "wb"); break; + case ROM_PC5086: f = nvrfopen("pc5086.nvr", "wb"); break; case ROM_PPC512: f = nvrfopen("ppc512.nvr", "wb"); break; case ROM_IBMAT: f = nvrfopen("at.nvr", "wb"); break; case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "wb"); break; diff --git a/src/pic.c b/src/pic.c index 3bbefbf..c93def6 100644 --- a/src/pic.c +++ b/src/pic.c @@ -10,13 +10,19 @@ int pic_intpending; void pic_updatepending() { - if ((pic2.pend&~pic2.mask)&~pic2.mask2) - pic.pend |= (1 << 2); + if (AT || romset == ROM_XI8088) + { + if ((pic2.pend&~pic2.mask)&~pic2.mask2) + pic.pend |= (1 << 2); + else + pic.pend &= ~(1 << 2); + pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; + if (!((pic.mask | pic.mask2) & (1 << 2))) + pic_intpending |= ((pic2.pend&~pic2.mask)&~pic2.mask2); + } else - pic.pend &= ~(1 << 2); - pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; - if (!((pic.mask | pic.mask2) & (1 << 2))) - pic_intpending |= ((pic2.pend&~pic2.mask)&~pic2.mask2); + pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; + /* pclog("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2); pclog(" %02X %02X %02X %02X %i %i\n", pic2.ins, pic2.pend, pic2.mask, pic2.mask2, ((pic.mask | pic.mask2) & (1 << 2)), ((pic2.pend&~pic2.mask)&~pic2.mask2));*/ } @@ -64,7 +70,7 @@ static void pic_autoeoi() pic.ins&=~(1<0xFF) + if ((AT || romset == ROM_XI8088) && num>0xFF) { pic2.pend|=(num>>8); if ((pic2.pend&~pic2.mask)&~pic2.mask2) pic.pend |= (1 << 2); } - else + else if (num <= 0xff) { pic.pend|=num; } @@ -379,13 +384,13 @@ void picintc(uint16_t num) // pclog("INTC %04X %i\n", num, c); pic_current[c]=0; - if (num > 0xff) + if ((AT || romset == ROM_XI8088) && num > 0xff) { pic2.pend &= ~(num >> 8); if (!((pic2.pend&~pic2.mask)&~pic2.mask2)) pic.pend &= ~(1 << 2); } - else + else if(num <= 0xff) { pic.pend&=~num; } @@ -396,54 +401,35 @@ uint8_t picinterrupt() { uint8_t temp=pic.pend&~pic.mask; int c; - for (c = 0; c < 2; c++) + for (c = 0; c < 8; c++) { - if (temp & (1 << c)) + if ((AT || romset == ROM_XI8088) && (temp & (1 << 2))) { - if (!(pic.level_sensitive & (1 << c))) - 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(); - - return c+pic.vector; - } - } - if (temp & (1 << 2)) - { - uint8_t temp2 = pic2.pend & ~pic2.mask; - for (c = 0; c < 8; c++) - { - if (temp2 & (1 << c)) + uint8_t temp2 = pic2.pend & ~pic2.mask; + for (c = 0; c < 8; c++) { - if (!(pic2.level_sensitive & (1 << c))) - pic2.pend &= ~(1 << c); - pic2.ins |= (1 << c); - pic_update_mask(&pic2.mask2, pic2.ins); + if (temp2 & (1 << c)) + { + if (!(pic2.level_sensitive & (1 << c))) + pic2.pend &= ~(1 << c); + pic2.ins |= (1 << c); + pic_update_mask(&pic2.mask2, pic2.ins); - if (!(pic2.level_sensitive & (1 << c))) - pic.pend &= ~(1 << c); - pic.ins |= (1 << 2); /*Cascade IRQ*/ - pic_update_mask(&pic.mask2, pic.ins); + if (!(pic2.level_sensitive & (1 << c))) + pic.pend &= ~(1 << c); + pic.ins |= (1 << 2); /*Cascade IRQ*/ + pic_update_mask(&pic.mask2, pic.ins); - pic_updatepending(); + pic_updatepending(); - if (pic2.icw4 & 0x02) - pic2_autoeoi(); + if (pic2.icw4 & 0x02) + pic2_autoeoi(); - return c+pic2.vector; + return c+pic2.vector; + } } } - } - for (c = 3; c < 8; c++) - { - if (temp & (1 << c)) + else if (temp & (1 << c)) { if (!(pic.level_sensitive & (1 << c))) pic.pend &= ~(1 << c); @@ -453,7 +439,6 @@ uint8_t picinterrupt() if (pic.icw4 & 0x02) pic_autoeoi(); - return c+pic.vector; } } diff --git a/src/serial.c b/src/serial.c index b563b0d..91cf7e8 100644 --- a/src/serial.c +++ b/src/serial.c @@ -265,6 +265,10 @@ void serial1_set(uint16_t addr, int irq) serial1.irq = irq; serial1.addr = addr; } +void serial1_set_has_fifo(int has_fifo) +{ + serial1.has_fifo = has_fifo; +} void serial1_remove() { io_removehandler(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); @@ -287,6 +291,10 @@ void serial2_set(uint16_t addr, int irq) serial2.irq = irq; serial2.addr = addr; } +void serial2_set_has_fifo(int has_fifo) +{ + serial2.has_fifo = has_fifo; +} void serial2_remove() { io_removehandler(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); diff --git a/src/serial.h b/src/serial.h index 841aaaa..13cee6d 100644 --- a/src/serial.h +++ b/src/serial.h @@ -4,6 +4,8 @@ void serial1_init(uint16_t addr, int irq, int has_fifo); void serial2_init(uint16_t addr, int irq, int has_fifo); void serial1_set(uint16_t addr, int irq); void serial2_set(uint16_t addr, int irq); +void serial1_set_has_fifo(int has_fifo); +void serial2_set_has_fifo(int has_fifo); void serial1_remove(); void serial2_remove(); void serial_reset(); diff --git a/src/superxt.c b/src/superxt.c new file mode 100644 index 0000000..5c3bed4 --- /dev/null +++ b/src/superxt.c @@ -0,0 +1,60 @@ +/*This is the Chips and Technologies C82100 chipset used in the Amstrad PC5086 model*/ +#include "ibm.h" +#include "io.h" +#include "x86.h" +#include "superxt.h" + +static uint8_t superxt_regs[256]; +static int superxt_index; +static int superxt_emspage[4]; + +void superxt_write(uint16_t port, uint8_t val, void *priv) +{ + switch (port) + { + case 0x22: + superxt_index = val; + break; + + case 0x23: + superxt_regs[superxt_index] = val; + + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + superxt_emspage[port >> 14] = val; + break; + + // default: + // pclog("%04X:%04X SUPERXT WRITE : %04X, %02X\n", CS, cpu_state.pc, port, val); + } +} + +uint8_t superxt_read(uint16_t port, void *priv) +{ + switch (port) + { + case 0x22: + return superxt_index; + + case 0x23: + return superxt_regs[superxt_index]; + + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + return superxt_emspage[port >> 14]; + + // default: + // pclog("%04X:%04X SUPERXT READ : %04X\n", CS, cpu_state.pc, port); + } + return 0xff; +} + +void superxt_init() +{ + /* Set register 0x42 to invalid configuration at startup */ + superxt_regs[0x42] = 0; + + io_sethandler(0x0022, 0x0002, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x0208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x4208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x8208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0xc208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); +} diff --git a/src/superxt.h b/src/superxt.h new file mode 100644 index 0000000..f21eb6a --- /dev/null +++ b/src/superxt.h @@ -0,0 +1 @@ +void superxt_init(); From 142301adbf3cd5bc6b93a07885bd326e3de7bf5c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Nov 2020 13:44:23 +0000 Subject: [PATCH 0960/1050] Don't enable SCAT shadow RAM if SCAT configured for less than 1 MB of low memory. Fixes Hyundai Super-286TR with 1 MB RAM configured. --- src/scat.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/scat.c b/src/scat.c index a4a4b3f..2e29d17 100644 --- a/src/scat.c +++ b/src/scat.c @@ -78,10 +78,19 @@ void scat_shadow_state_update() { int i, val; - for (i = 0; i < 24; i++) + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) < 4) { - val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL | MEM_WRITE_INTERNAL : MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; - mem_set_mem_state((i + 40) << 14, 0x4000, val); + /*Less than 1MB low memory, no shadow RAM available*/ + for (i = 0; i < 24; i++) + mem_set_mem_state((i + 40) << 14, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + else + { + for (i = 0; i < 24; i++) + { + val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL | MEM_WRITE_INTERNAL : MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL; + mem_set_mem_state((i + 40) << 14, 0x4000, val); + } } flushmmucache(); @@ -1043,6 +1052,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) break; case SCAT_DRAM_CONFIGURATION: scat_map_update = 1; + scat_shadow_update = 1; if((scat_regs[SCAT_VERSION] & 0xF0) == 0) { From fbb5904b52213f98090551fe5a529f86737da7a1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 15 Nov 2020 16:56:43 +0000 Subject: [PATCH 0961/1050] Rework AudioPCI IO port handling to avoid potential conflict between native and CODEC ports. Fixes AudioPCI with Windows XP. --- src/sound_audiopci.c | 65 +++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/sound_audiopci.c b/src/sound_audiopci.c index 5fb4156..21df235 100644 --- a/src/sound_audiopci.c +++ b/src/sound_audiopci.c @@ -130,7 +130,7 @@ const int32_t codec_attn[]= }; static void es1371_fetch(es1371_t *es1371, int dac_nr); -static void update_legacy(es1371_t *es1371); +static void update_legacy(es1371_t *es1371, uint32_t old_legacy_ctrl); static void es1371_update_irqs(es1371_t *es1371) { @@ -353,6 +353,7 @@ static uint32_t es1371_inl(uint16_t port, void *p) static void es1371_outb(uint16_t port, uint8_t val, void *p) { es1371_t *es1371 = (es1371_t *)p; + uint32_t old_legacy_ctrl; // pclog("es1371_outb: port=%04x val=%02x %04x:%08x\n", port, val, cs, cpu_state.pc); switch (port & 0x3f) @@ -397,14 +398,16 @@ static void es1371_outb(uint16_t port, uint8_t val, void *p) nmi = 0; break; case 0x1a: + old_legacy_ctrl = es1371->legacy_ctrl; es1371->legacy_ctrl = (es1371->legacy_ctrl & 0xff00ffff) | (val << 16); - update_legacy(es1371); + update_legacy(es1371, old_legacy_ctrl); break; case 0x1b: + old_legacy_ctrl = es1371->legacy_ctrl; es1371->legacy_ctrl = (es1371->legacy_ctrl & 0x00ffffff) | (val << 24); es1371_update_irqs(es1371); // output = 3; - update_legacy(es1371); + update_legacy(es1371, old_legacy_ctrl); break; case 0x20: @@ -721,26 +724,44 @@ static uint8_t capture_read_slave_dma(uint16_t port, void *p) return 0xff; } -static void update_legacy(es1371_t *es1371) +static void update_legacy(es1371_t *es1371, uint32_t old_legacy_ctrl) { - io_removehandler(0x0320, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - io_removehandler(0x0330, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - io_removehandler(0x0340, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - io_removehandler(0x0350, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); - - io_removehandler(0x5300, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); - io_removehandler(0xe800, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); - io_removehandler(0xf400, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); - - io_removehandler(0x0220, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); - io_removehandler(0x0240, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); - - io_removehandler(0x0388, 0x0004, capture_read_adlib,NULL,NULL, capture_write_adlib,NULL,NULL, es1371); - - io_removehandler(0x0020, 0x0002, capture_read_master_pic,NULL,NULL, capture_write_master_pic,NULL,NULL, es1371); - io_removehandler(0x0000, 0x0010, capture_read_master_dma,NULL,NULL, capture_write_master_dma,NULL,NULL, es1371); - io_removehandler(0x00a0, 0x0002, capture_read_slave_pic,NULL,NULL, capture_write_slave_pic,NULL,NULL, es1371); - io_removehandler(0x00c0, 0x0020, capture_read_slave_dma,NULL,NULL, capture_write_slave_dma,NULL,NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) + { + switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) + { + case 0: io_removehandler(0x0320, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + case 1: io_removehandler(0x0330, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + case 2: io_removehandler(0x0340, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + case 3: io_removehandler(0x0350, 0x0008, capture_read_sscape,NULL,NULL, capture_write_sscape,NULL,NULL, es1371); break; + } + } + if (old_legacy_ctrl & LEGACY_CAPTURE_CODEC) + { + switch ((old_legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) + { + case 0: io_removehandler(0x5300, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; + case 2: io_removehandler(0xe800, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; + case 3: io_removehandler(0xf400, 0x0080, capture_read_codec,NULL,NULL, capture_write_codec,NULL,NULL, es1371); break; + } + } + if (old_legacy_ctrl & LEGACY_CAPTURE_SB) + { + if (!(old_legacy_ctrl & LEGACY_SB_ADDR)) + io_removehandler(0x0220, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); + else + io_removehandler(0x0240, 0x0010, capture_read_sb,NULL,NULL, capture_write_sb,NULL,NULL, es1371); + } + if (old_legacy_ctrl & LEGACY_CAPTURE_ADLIB) + io_removehandler(0x0388, 0x0004, capture_read_adlib,NULL,NULL, capture_write_adlib,NULL,NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) + io_removehandler(0x0020, 0x0002, capture_read_master_pic,NULL,NULL, capture_write_master_pic,NULL,NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) + io_removehandler(0x0000, 0x0010, capture_read_master_dma,NULL,NULL, capture_write_master_dma,NULL,NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) + io_removehandler(0x00a0, 0x0002, capture_read_slave_pic,NULL,NULL, capture_write_slave_pic,NULL,NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) + io_removehandler(0x00c0, 0x0020, capture_read_slave_dma,NULL,NULL, capture_write_slave_dma,NULL,NULL, es1371); if (es1371->legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { From d5dbe302b5691087fe0bbdd2069906b1c34cc94f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 16 Nov 2020 17:59:57 +0000 Subject: [PATCH 0962/1050] Implement CPU clock control on SCAT. Patch from Greatpsycho. --- src/cpu.c | 17 +++++++++++++++++ src/cpu.h | 3 +++ src/scat.c | 6 ++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index ce1dbc0..99c0c8b 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -212,6 +212,7 @@ void cpu_set() cpu_nonturbo_speed = cpu_s->rspeed; else cpu_nonturbo_speed = 8000000; + cpu_turbo = 1; cpu_update_waitstates(); @@ -2181,9 +2182,25 @@ void cpu_set_turbo(int turbo) } } +int cpu_get_turbo() +{ + return cpu_turbo; +} + int cpu_get_speed() { if (cpu_turbo) return cpu_turbo_speed; return cpu_nonturbo_speed; } + +void cpu_set_nonturbo_divider(int divider) +{ + if (divider < 2) + cpu_set_turbo(1); + else + { + cpu_nonturbo_speed = cpu_turbo_speed / divider; + cpu_set_turbo(0); + } +} diff --git a/src/cpu.h b/src/cpu.h index ee54925..97acec1 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -196,10 +196,13 @@ extern uint64_t xt_cpu_multi; extern int isa_cycles; #define ISA_CYCLES(x) (x * isa_cycles) +#define CPU_CLOCK_DIVIDER_MAX 16384 void cpu_update_waitstates(); void cpu_set(); void cpu_set_edx(); void cpu_set_turbo(int turbo); +int cpu_get_turbo(); +void cpu_set_nonturbo_divider(int divider); int cpu_get_speed(); extern int has_vlb; diff --git a/src/scat.c b/src/scat.c index 2e29d17..ca33af5 100644 --- a/src/scat.c +++ b/src/scat.c @@ -1046,8 +1046,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_POWER_MANAGEMENT: - // TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. - val &= (scat_regs[SCAT_VERSION] & 0xF0) == 0 ? 0x40 : 0x60; + cpu_set_nonturbo_divider((val & 0xc) > 0 ? 1 << ((val & 0xc) >> 2) : 0); scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: @@ -1220,6 +1219,9 @@ uint8_t scat_read(uint16_t port, void *priv) case SCAT_MISCELLANEOUS_STATUS: val = (scat_regs[scat_index] & 0x3f) | (~nmi_mask & 0x80) | ((mem_a20_key & 2) << 5); break; + case SCAT_POWER_MANAGEMENT: + val = (scat_regs[scat_index] & (cpu_get_turbo() ? 0xF3 : 0xFF)); + break; case SCAT_DRAM_CONFIGURATION: if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) val = (scat_regs[scat_index] & 0x8f) | (cpu_waitstates == 1 ? 0 : 0x10); else val = scat_regs[scat_index]; From 4459c7175d4f2479a020d187a12aad35d66fea61 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 16 Nov 2020 19:34:28 +0000 Subject: [PATCH 0963/1050] Close all IDE drives on IDE device destruction. --- src/ide.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ide.c b/src/ide.c index 468a809..86a3619 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1273,6 +1273,13 @@ static void *ide_init() static void ide_close(void *p) { + int c; + + for (c = 0; c < 4; c++) + { + ide_drives[c].type = IDE_NONE; + hdd_close(&ide_drives[c].hdd_file); + } } void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), int (*write_data)(int channel, uint8_t *data, int size, void *p), void (*set_irq)(int channel, void *p), void *p) From d6bf0baed06f40394588bc2b2a4ef4eac853d9f8 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 16 Nov 2020 19:34:58 +0000 Subject: [PATCH 0964/1050] Close all devices on emulation shutdown. --- src/wx-sdl2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 0813929..9411d5b 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -721,6 +721,7 @@ int stop_emulation() endblit(); SDL_DestroyMutex(ghMutex); + device_close_all(); midi_close(); pclog("Emulation stopped.\n"); From 5c20fe7c576989796417e2269b2de1b9411dbf2d Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 16 Nov 2020 20:05:44 +0000 Subject: [PATCH 0965/1050] Implement Banshee half mode on non-tiled surfaces. Fixes low res VESA modes. --- src/vid_svga.c | 3 ++- src/vid_voodoo_banshee.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index b881dd0..f6890a9 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -339,6 +339,8 @@ void svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; + svga->rowcount = svga->crtc[9] & 31; + svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; if (!svga->scrblank && svga->attr_palette_enable) @@ -418,7 +420,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; svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; if (svga->recalctimings_ex) svga->recalctimings_ex(svga); diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 697dccd..c6df176 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -409,6 +409,10 @@ static void banshee_recalctimings(svga_t *svga) default: fatal("Unknown pixel format %08x\n", banshee->vgaInit0); } + if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) + svga->rowcount = 1; + else + svga->rowcount = 0; if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; else From 8cfb60608e15d5bd01d2cac559ede7defae98d90 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 17 Nov 2020 08:32:12 +0000 Subject: [PATCH 0966/1050] Increase size of Voodoo dirty_line array to 2048 lines, and add some bounds checking before accessing. Fixes crash running 3DMark 2001 on Voodoo 3. --- src/vid_voodoo_banshee.c | 10 ++++++---- src/vid_voodoo_common.h | 2 +- src/vid_voodoo_fb.c | 4 ++-- src/vid_voodoo_fifo.c | 2 +- src/vid_voodoo_reg.c | 2 +- src/vid_voodoo_render.c | 3 ++- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index c6df176..06773d7 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1929,14 +1929,16 @@ static void banshee_overlay_draw(svga_t *svga, int displine) if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && - !svga->fullchange && !voodoo->dirty_line[voodoo->overlay.src_y >> 20] && + !svga->fullchange && + ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { voodoo->overlay.src_y += (1 << 20); return; } - voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; + if ((voodoo->overlay.src_y >> 20) < 2048) + voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; // pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); // if (src_addr >= 0x800000) // fatal("overlay out of range!\n"); @@ -2214,7 +2216,7 @@ void banshee_set_overlay_addr(void *p, uint32_t addr) banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; - memset(voodoo->dirty_line, 1, 1024); + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); } static void banshee_vsync_callback(svga_t *svga) @@ -2231,7 +2233,7 @@ static void banshee_vsync_callback(svga_t *svga) voodoo->swap_pending = 0; thread_unlock_mutex(voodoo->swap_mutex); - memset(voodoo->dirty_line, 1, 1024); + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); voodoo->retrace_count = 0; banshee_set_overlay_addr(banshee, voodoo->swap_offset); thread_set_event(voodoo->wake_fifo_thread); diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 14f775f..9fb9c05 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -438,7 +438,7 @@ typedef struct voodoo_t rgb_t clutData256[256]; uint32_t video_16to32[0x10000]; - uint8_t dirty_line[1024]; + uint8_t dirty_line[2048]; int dirty_line_low, dirty_line_high; int fb_write_buffer, fb_draw_buffer; diff --git a/src/vid_voodoo_fb.c b/src/vid_voodoo_fb.c index b3d3918..cbf8c17 100644 --- a/src/vid_voodoo_fb.c +++ b/src/vid_voodoo_fb.c @@ -195,7 +195,7 @@ void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) } - if (voodoo->fb_write_offset == voodoo->params.front_offset) + if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) voodoo->dirty_line[y] = 1; if (voodoo->col_tiled) @@ -355,7 +355,7 @@ void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) y >>= 1; } - if (voodoo->fb_write_offset == voodoo->params.front_offset) + if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) voodoo->dirty_line[y] = 1; if (voodoo->col_tiled) diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index 1c807d4..472df3f 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -95,7 +95,7 @@ void voodoo_wait_for_swap_complete(voodoo_t *voodoo) if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) { /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ - memset(voodoo->dirty_line, 1, 1024); + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); voodoo->front_offset = voodoo->params.front_offset; if (voodoo->swap_count > 0) voodoo->swap_count--; diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 82f4bac..d413130 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -102,7 +102,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo_wait_for_render_thread_idle(voodoo); if (!(val & 1)) { - memset(voodoo->dirty_line, 1, 1024); + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); voodoo->front_offset = voodoo->params.front_offset; thread_lock_mutex(voodoo->swap_mutex); if (voodoo->swap_count > 0) diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index 3648c78..4815db9 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -1363,8 +1363,9 @@ skip_pixel: voodoo->texel_count[odd_even] += state->texel_count; voodoo->fbiPixelsIn += state->pixel_count; - if (voodoo->params.draw_offset == voodoo->params.front_offset) + if (voodoo->params.draw_offset == voodoo->params.front_offset && (real_y >> 1) < 2048) voodoo->dirty_line[real_y >> 1] = 1; + next_line: if (SLI_ENABLED) { From 09a7b468c387f2a20ee466fc115d3ea20557605f Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 17 Nov 2020 21:43:30 +0000 Subject: [PATCH 0967/1050] Move Voodoo colour/aux buffer tiled mode flags to params structure. Fixed crash in 3DMark 2001 demo mode. --- src/vid_voodoo_codegen_x86-64.h | 17 ++++++++++------- src/vid_voodoo_codegen_x86.h | 17 ++++++++++------- src/vid_voodoo_common.h | 3 +++ src/vid_voodoo_reg.c | 4 ++++ src/vid_voodoo_render.c | 24 ++++++++++++------------ 5 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index ba11ce5..5f61b2c 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -34,6 +34,7 @@ typedef struct voodoo_x86_data_t uint32_t textureMode[2]; uint32_t tLOD[2]; uint32_t trexInit1; + int is_tiled; } voodoo_x86_data_t; //static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; @@ -790,7 +791,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); addbyte(0xfe); - if (voodoo->col_tiled || voodoo->aux_tiled) + if (params->col_tiled || params->aux_tiled) { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); @@ -929,7 +930,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); - if (voodoo->aux_tiled) + if (params->aux_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -2516,7 +2517,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addquad((uintptr_t)rgb565); addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); - if (voodoo->col_tiled) + if (params->col_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -2901,7 +2902,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - if (voodoo->col_tiled) + if (params->col_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -2971,7 +2972,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - if (voodoo->col_tiled) + if (params->col_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -3062,7 +3063,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - if (voodoo->aux_tiled) + if (params->aux_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -3357,7 +3358,8 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, params->textureMode[0] == data->textureMode[0] && params->textureMode[1] == data->textureMode[1] && (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && - (params->tLOD[1] & LOD_MASK) == data->tLOD[1]) + (params->tLOD[1] & LOD_MASK) == data->tLOD[1] && + ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) { last_block[odd_even] = b; return data->code_block; @@ -3381,6 +3383,7 @@ voodoo_recomp++; data->textureMode[1] = params->textureMode[1]; data->tLOD[0] = params->tLOD[0] & LOD_MASK; data->tLOD[1] = params->tLOD[1] & LOD_MASK; + data->is_tiled = (params->col_tiled || params->aux_tiled) ? 1 : 0; next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7; diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index d49c6ed..fc2be0c 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -34,6 +34,7 @@ typedef struct voodoo_x86_data_t uint32_t textureMode[2]; uint32_t tLOD[2]; uint32_t trexInit1; + int is_tiled; } voodoo_x86_data_t; static int last_block[4] = {0, 0}; @@ -702,7 +703,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x74); addbyte(0x24); addbyte(8+16); - if (voodoo->col_tiled || voodoo->aux_tiled) + if (params->col_tiled || params->aux_tiled) { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); @@ -856,7 +857,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); - if (voodoo->aux_tiled) + if (params->aux_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -2469,7 +2470,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); - if (voodoo->col_tiled) + if (params->col_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -2851,7 +2852,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - if (voodoo->col_tiled) + if (params->col_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -2923,7 +2924,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - if (voodoo->col_tiled) + if (params->col_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -3012,7 +3013,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - if (voodoo->aux_tiled) + if (params->aux_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); @@ -3297,7 +3298,8 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, params->textureMode[0] == data->textureMode[0] && params->textureMode[1] == data->textureMode[1] && (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && - (params->tLOD[1] & LOD_MASK) == data->tLOD[1]) + (params->tLOD[1] & LOD_MASK) == data->tLOD[1] && + ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) { last_block[odd_even] = b; return data->code_block; @@ -3321,6 +3323,7 @@ voodoo_recomp++; data->textureMode[1] = params->textureMode[1]; data->tLOD[0] = params->tLOD[0] & LOD_MASK; data->tLOD[1] = params->tLOD[1] & LOD_MASK; + data->is_tiled = (params->col_tiled || params->aux_tiled) ? 1 : 0; next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7; diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 9fb9c05..cf62410 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -156,6 +156,9 @@ typedef struct voodoo_params_t uint32_t swapbufferCMD; uint32_t stipple; + + int col_tiled, aux_tiled; + int row_width, aux_row_width; } voodoo_params_t; typedef struct texture_t diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index d413130..63e590b 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -567,6 +567,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) if (voodoo->type >= VOODOO_BANSHEE) { voodoo->col_tiled = val & (1 << 15); + voodoo->params.col_tiled = voodoo->col_tiled; if (voodoo->col_tiled) { voodoo->row_width = (val & 0x7f) * 128*32; @@ -577,6 +578,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->row_width = val & 0x3fff; // pclog("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); } + voodoo->params.row_width = voodoo->row_width; } break; case SST_auxBufferAddr: @@ -590,6 +592,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) if (voodoo->type >= VOODOO_BANSHEE) { voodoo->aux_tiled = val & (1 << 15); + voodoo->params.aux_tiled = voodoo->aux_tiled; if (voodoo->aux_tiled) { voodoo->aux_row_width = (val & 0x7f) * 128*32; @@ -600,6 +603,7 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->aux_row_width = val & 0x3fff; // pclog("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); } + voodoo->params.aux_row_width = voodoo->aux_row_width; } break; diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index 4815db9..2116180 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -915,19 +915,19 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (SLI_ENABLED) { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * voodoo->row_width)) & voodoo->fb_mask]; + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * params->row_width)]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * params->row_width)) & voodoo->fb_mask]; } else { - if (voodoo->col_tiled) - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * voodoo->row_width + (real_y & 31) * 128]; + if (params->col_tiled) + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * params->row_width + (real_y & 31) * 128]; else - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - if (voodoo->aux_tiled) - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * voodoo->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * params->row_width)]; + if (params->aux_tiled) + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * params->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; else - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * params->row_width)) & voodoo->fb_mask]; } if (voodoo_output) @@ -992,12 +992,12 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (params->fbzMode & FBZ_DEPTH_ENABLE) { - uint16_t old_depth = voodoo->aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; + uint16_t old_depth = voodoo->params.aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); } - dat = voodoo->col_tiled ? fb_mem[x_tiled] : fb_mem[x]; + dat = voodoo->params.col_tiled ? fb_mem[x_tiled] : fb_mem[x]; dest_r = (dat >> 8) & 0xf8; dest_g = (dat >> 3) & 0xfc; dest_b = (dat << 3) & 0xf8; @@ -1308,14 +1308,14 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (params->fbzMode & FBZ_RGB_WMASK) { - if (voodoo->col_tiled) + if (voodoo->params.col_tiled) fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); else fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); } if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { - if (voodoo->aux_tiled) + if (voodoo->params.aux_tiled) aux_mem[x_tiled] = new_depth; else aux_mem[x] = new_depth; From aef6ea93e643496556651341e4f57e2ddf4a3757 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Nov 2020 19:31:36 +0000 Subject: [PATCH 0968/1050] More changes to Banshee/V3 half mode. --- src/vid_svga.c | 2 +- src/vid_voodoo_banshee.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index f6890a9..5092ccf 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -340,6 +340,7 @@ void svga_recalctimings(svga_t *svga) svga->ca_adj = 0; svga->rowcount = svga->crtc[9] & 31; + svga->linedbl = svga->crtc[9] & 0x80; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -419,7 +420,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->char_width = (svga->seqregs[1] & 1) ? 8 : 9; if (svga->recalctimings_ex) svga->recalctimings_ex(svga); diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 06773d7..ba73cce 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -409,10 +409,11 @@ static void banshee_recalctimings(svga_t *svga) default: fatal("Unknown pixel format %08x\n", banshee->vgaInit0); } + svga->rowcount = 0; if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) - svga->rowcount = 1; + svga->linedbl = 1; else - svga->rowcount = 0; + svga->linedbl = 0; if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; else From 035f6b348c506d4691cc0fd28c424f192ab1b6fb Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Nov 2020 19:49:58 +0000 Subject: [PATCH 0969/1050] Fix horizontal scaling of unfiltered Banshee/V3 overlay. --- src/vid_voodoo_banshee.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index ba73cce..8304b8b 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1950,7 +1950,8 @@ static void banshee_overlay_draw(svga_t *svga, int displine) !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); else - skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR); + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && + !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)); if (skip_filtering) { From 088354f607c8f454bab74dddde71fb0de7cbcbd1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Nov 2020 20:00:55 +0000 Subject: [PATCH 0970/1050] Mask off source address correctly for Banshee/V3 RGB565 tiled overlay --- src/vid_voodoo_banshee.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 8304b8b..7bf2359 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1651,10 +1651,11 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) { \ int c; \ int wp = 0; \ + uint32_t base_addr = buf ? src_addr2 : src_addr; \ \ for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ { \ - uint16_t data = *(uint16_t *)&src[(c & 127) + (c >> 7)*128*32]; \ + uint16_t data = *(uint16_t *)&svga->vram[(base_addr + (c & 127) + (c >> 7)*128*32) & svga->vram_mask]; \ int r = data & 0x1f; \ int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ From 6cbce169f5798beddec088665912046af2f6b28d Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Nov 2020 20:39:41 +0000 Subject: [PATCH 0971/1050] Ensure Voodoo 1/2 keep params copy of buffer row widths updated. --- src/vid_voodoo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index a9fc77c..369bb0a 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -100,7 +100,9 @@ void voodoo_recalc(voodoo_t *voodoo) if (voodoo->fbiInit1 & (1 << 24)) voodoo->block_width += 32; voodoo->row_width = voodoo->block_width * 32 * 2; + voodoo->params.row_width = voodoo->row_width; voodoo->aux_row_width = voodoo->row_width; + voodoo->params.aux_row_width = voodoo->aux_row_width; /* 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); pclog(" fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ From e15f66b349186025077e0499f7e6af4424696163 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 18 Nov 2020 20:43:07 +0000 Subject: [PATCH 0972/1050] Add specific warning message when creating differencing VHD. Patch from shermanp. --- src/wx-config.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wx-config.c b/src/wx-config.c index 2421d67..9f24e2c 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -1842,9 +1842,13 @@ static int hdnew_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM l return TRUE; } } + wx_messagebox(hdlg, "Differencing VHD image created.\n\n" + "WARNING: Do not open or modify the parent image(s) while this file exists.", "PCem", WX_MB_OK); + } + if (hd_format != 3) + { + wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", WX_MB_OK); } - - wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", WX_MB_OK); wx_enddialog(hdlg, 1); return TRUE; From 49ba35733e95e4ac1c95b9526c67c48b273a2f82 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Nov 2020 19:38:34 +0000 Subject: [PATCH 0973/1050] Implement Banshee/V3 CLUT lookup on 16-bit RGB overlay. --- src/vid_voodoo_banshee.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 7bf2359..f3a7868 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -150,6 +150,8 @@ enum #define VIDPROCCFG_CURSOR_MODE (1 << 1) #define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) +#define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11) +#define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) #define VIDPROCCFG_FILTER_MODE_MASK (3 << 16) @@ -1641,7 +1643,12 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ \ - buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + else \ + buf[wp++] = (clut[r << 3] & 0x0000ff) | \ + (clut[g << 2] & 0x00ff00) | \ + (clut[b << 3] & 0xff0000); \ src += 2; \ } \ } while (0) @@ -1660,7 +1667,12 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) int g = (data >> 5) & 0x3f; \ int b = data >> 11; \ \ - buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + else \ + buf[wp++] = (clut[r << 3] & 0x0000ff) | \ + (clut[g << 2] & 0x00ff00) | \ + (clut[b << 3] & 0xff0000); \ } \ } while (0) @@ -1928,6 +1940,7 @@ static void banshee_overlay_draw(svga_t *svga, int displine) uint32_t src_x = 0; unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; int skip_filtering; + uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && From 6b96f56632e2daa06eeaf7d96f798395d7951935 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Nov 2020 19:46:49 +0000 Subject: [PATCH 0974/1050] Fix off-by-one issue on Banshee/V3 RGB565 overlay render. --- src/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index f3a7868..15ac43e 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1658,7 +1658,7 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) { \ int c; \ int wp = 0; \ - uint32_t base_addr = buf ? src_addr2 : src_addr; \ + uint32_t base_addr = (buf == banshee->overlay_buffer[1]) ? src_addr2 : src_addr; \ \ for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ { \ From 8053c8a523ad38ecd9ce68f2df96dd2603c49713 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Nov 2020 22:09:41 +0000 Subject: [PATCH 0975/1050] Ensure that any cycles spent when entering IRQ/NMI in dynarec are accounted for in the TSC, and by extension the timer system. Fixes slowdown and stuttering music in Museum Madness. --- src/386_dynarec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 895c745..9dedf44 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -591,8 +591,6 @@ void exec386_dynarec(int cycs) exec_interpreter(); else exec_recompiler(); - cycdiff=oldcyc-cycles; - tsc += cycdiff; if (cpu_state.abrt) { @@ -643,6 +641,9 @@ void exec386_dynarec(int cycs) // pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc); } } + + cycdiff=oldcyc-cycles; + tsc += cycdiff; } if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) From 0cbe6ae918527ceaf6875278e2bb15efba02c457 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 19 Nov 2020 22:17:05 +0000 Subject: [PATCH 0976/1050] Ensure that any cycles spent when entering IRQ/NMI in interpreter are accounted for in the TSC, and by extension the timer system. --- src/386.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/386.c b/src/386.c index 6ef54b6..fc9cb3b 100644 --- a/src/386.c +++ b/src/386.c @@ -214,10 +214,6 @@ void exec386(int cycs) } } } - ins_cycles -= cycles; - tsc += ins_cycles; - - cycdiff=oldcyc-cycles; if (cpu_state.smi_pending) { @@ -291,6 +287,11 @@ void exec386(int cycs) ins++; insc++; + ins_cycles -= cycles; + tsc += ins_cycles; + + cycdiff=oldcyc-cycles; + if (timetolive) { timetolive--; From f72da770f1aa6fe021b5a7918c68ffcd4eb1e9c5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Nov 2020 20:41:41 +0000 Subject: [PATCH 0977/1050] Don't fatal() on "triangle_setup wrong order". These usually means one of the vertices is not valid. --- src/vid_voodoo_setup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_setup.c b/src/vid_voodoo_setup.c index 3572447..360d14a 100644 --- a/src/vid_voodoo_setup.c +++ b/src/vid_voodoo_setup.c @@ -126,7 +126,10 @@ void voodoo_triangle_setup(voodoo_t *voodoo) voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) - fatal("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); + { + pclog("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); + return; + } if (voodoo->sSetupMode & SETUPMODE_RGB) { From 39713ccdc40841626fa46671c3c3ecc2d105e309 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 20 Nov 2020 20:51:19 +0000 Subject: [PATCH 0978/1050] Don't fatal() on unknown Voodoo 1/2 register reads; we probably have all the important ones covered by now. Fixes Frogger 2. --- src/vid_voodoo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 369bb0a..132ced4 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -354,7 +354,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) break; default: - fatal("voodoo_readl : bad addr %08X\n", addr); + pclog("voodoo_readl : bad addr %08X\n", addr); temp = 0xffffffff; } From 87524de18bb1517af0c0de8188a7f050d85a2e02 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 09:44:46 +0000 Subject: [PATCH 0979/1050] Implement Voodoo CMDFIFO JSR/RET. Fixed "Bad CMDFIFO0" seen sometimes, particularly when running OpenGL games windowed. --- src/vid_voodoo_banshee.c | 2 ++ src/vid_voodoo_common.h | 3 ++- src/vid_voodoo_fifo.c | 26 +++++++++++++++++++++----- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 15ac43e..769d9de 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1163,6 +1163,8 @@ static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) voodoo->cmdfifo_size = val; voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); voodoo->cmdfifo_enabled = val & 0x100; + if (!voodoo->cmdfifo_enabled) + voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/ // pclog("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); break; diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index cf62410..d8ca533 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -301,7 +301,8 @@ typedef struct voodoo_t volatile int params_read_idx[4], params_write_idx; uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; - int cmdfifo_rp; + int cmdfifo_rp, cmdfifo_ret_addr; + int cmdfifo_in_sub; volatile int cmdfifo_depth_rd, cmdfifo_depth_wr; volatile int cmdfifo_enabled; uint32_t cmdfifo_amin, cmdfifo_amax; diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index 472df3f..59861f3 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -113,15 +113,19 @@ static uint32_t cmdfifo_get(voodoo_t *voodoo) { uint32_t val; - while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) + if (!voodoo->cmdfifo_in_sub) { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); + while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) + { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + } } val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; - voodoo->cmdfifo_depth_rd++; + if (!voodoo->cmdfifo_in_sub) + voodoo->cmdfifo_depth_rd++; voodoo->cmdfifo_rp += 4; // pclog(" CMDFIFO get %08x\n", val); @@ -242,7 +246,7 @@ void voodoo_fifo_thread(void *param) voodoo->time += end_time - start_time; } - while (voodoo->cmdfifo_enabled && voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) { uint64_t start_time = timer_read(); uint64_t end_time; @@ -265,6 +269,18 @@ void voodoo_fifo_thread(void *param) case 0: /*NOP*/ break; + case 1: /*JSR*/ +// pclog("JSR %08x\n", (header >> 4) & 0xfffffc); + voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp; + voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; + voodoo->cmdfifo_in_sub = 1; + break; + + case 2: /*RET*/ + voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr; + voodoo->cmdfifo_in_sub = 0; + break; + case 3: /*JMP local frame buffer*/ voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; // pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); From 302d05c02ae34b5bbaf5326ab31bf22673592f71 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 09:47:52 +0000 Subject: [PATCH 0980/1050] Build fixes for MiniVHD. Patch from shermanp. --- src/minivhd/cwalk.c | 3 +++ src/minivhd/minivhd_convert.c | 3 +++ src/minivhd/minivhd_create.c | 3 +++ src/minivhd/minivhd_io.c | 3 +++ src/minivhd/minivhd_manage.c | 4 +++- src/minivhd/minivhd_struct_rw.c | 4 +++- src/minivhd/minivhd_struct_rw.h | 2 +- src/minivhd/minivhd_util.c | 14 ++++++++++---- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/minivhd/cwalk.c b/src/minivhd/cwalk.c index 265de0f..f0c4842 100644 --- a/src/minivhd/cwalk.c +++ b/src/minivhd/cwalk.c @@ -1,3 +1,6 @@ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include diff --git a/src/minivhd/minivhd_convert.c b/src/minivhd/minivhd_convert.c index 231e0f9..1de6f46 100644 --- a/src/minivhd/minivhd_convert.c +++ b/src/minivhd/minivhd_convert.c @@ -1,3 +1,6 @@ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include diff --git a/src/minivhd/minivhd_create.c b/src/minivhd/minivhd_create.c index 9e34ece..c47c7d8 100644 --- a/src/minivhd/minivhd_create.c +++ b/src/minivhd/minivhd_create.c @@ -1,3 +1,6 @@ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include diff --git a/src/minivhd/minivhd_io.c b/src/minivhd/minivhd_io.c index 8e9172e..ddd1717 100644 --- a/src/minivhd/minivhd_io.c +++ b/src/minivhd/minivhd_io.c @@ -3,6 +3,9 @@ * \brief Sector reading and writing implementations */ +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include "minivhd_internal.h" diff --git a/src/minivhd/minivhd_manage.c b/src/minivhd/minivhd_manage.c index 75e0953..e9473c0 100644 --- a/src/minivhd/minivhd_manage.c +++ b/src/minivhd/minivhd_manage.c @@ -2,7 +2,9 @@ * \file * \brief VHD management functions (open, close, read write etc) */ - +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include diff --git a/src/minivhd/minivhd_struct_rw.c b/src/minivhd/minivhd_struct_rw.c index 66f2289..c77fa60 100644 --- a/src/minivhd/minivhd_struct_rw.c +++ b/src/minivhd/minivhd_struct_rw.c @@ -2,7 +2,9 @@ * \file * \brief Header and footer serialize/deserialize functions */ - +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include diff --git a/src/minivhd/minivhd_struct_rw.h b/src/minivhd/minivhd_struct_rw.h index 0b1e018..ee49bb6 100644 --- a/src/minivhd/minivhd_struct_rw.h +++ b/src/minivhd/minivhd_struct_rw.h @@ -1,5 +1,5 @@ #ifndef MINIVHD_STRUCT_RW_H -#define minivhd_struct_rw +#define MINIVHD_STRUCT_RW_H #include "minivhd_internal.h" diff --git a/src/minivhd/minivhd_util.c b/src/minivhd/minivhd_util.c index d8f44ca..5bfc599 100644 --- a/src/minivhd/minivhd_util.c +++ b/src/minivhd/minivhd_util.c @@ -2,7 +2,9 @@ * \file * \brief Utility functions */ - +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif #include #include #include @@ -152,7 +154,7 @@ FILE* mvhd_fopen(const char* path, const char* mode, int* err) { } } #else - f = fopen64(path, mode); + f = fopen(path, mode); if (f == NULL) { mvhd_errno = errno; *err = MVHD_ERR_FILE; @@ -253,8 +255,10 @@ int64_t mvhd_ftello64(FILE* stream) { #ifdef _MSC_VER return _ftelli64(stream); -#else +#elif defined(__MINGW32__) return ftello64(stream); +#else /* This should work with linux (with _FILE_OFFSET_BITS), and hopefully OS X and BSD */ + return ftello(stream); #endif } @@ -262,8 +266,10 @@ int mvhd_fseeko64(FILE* stream, int64_t offset, int origin) { #ifdef _MSC_VER return _fseeki64(stream, offset, origin); -#else +#elif defined(__MINGW32__) return fseeko64(stream, offset, origin); +#else /* This should work with linux (with _FILE_OFFSET_BITS), and hopefully OS X and BSD */ + return fseeko(stream, offset, origin); #endif } From cada868428f2eb74a973f2188bf31cd5dc3ebfad Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 20:45:56 +0000 Subject: [PATCH 0981/1050] Tweak accesses to S3 system control and extension registers. Fixes banking on some versions of UNIVBE (eg as used by Pro Pinball : The Web). --- src/vid_s3.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vid_s3.c b/src/vid_s3.c index f4064a9..f56ae34 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -999,7 +999,11 @@ void s3_out(uint16_t addr, uint8_t val, void *p) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) return; + if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && svga->crtcreg != 0x39 && (svga->crtc[0x38] & 0xcc) != 0x48) + { + if (!((svga->crtc[0x39] & 0xe0) == 0xa0 && svga->crtcreg >= 0x40 && svga->crtcreg <= 0x6d)) + return; + } old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; switch (svga->crtcreg) From e791bf372b4cb37cfd673a7ff8837934761ae500 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 20:51:09 +0000 Subject: [PATCH 0982/1050] Fix EOF in MiniVHD files. Patch from shermanp. --- src/minivhd/libxml2_encoding.c | 2 +- src/minivhd/libxml2_encoding.h | 2 +- src/minivhd/minivhd.h | 2 +- src/minivhd/minivhd_convert.c | 2 +- src/minivhd/minivhd_create.c | 2 +- src/minivhd/minivhd_create.h | 2 +- src/minivhd/minivhd_internal.h | 2 +- src/minivhd/minivhd_io.c | 2 +- src/minivhd/minivhd_io.h | 2 +- src/minivhd/minivhd_manage.c | 2 +- src/minivhd/minivhd_struct_rw.c | 2 +- src/minivhd/minivhd_struct_rw.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/minivhd/libxml2_encoding.c b/src/minivhd/libxml2_encoding.c index cb881a8..1c9575b 100644 --- a/src/minivhd/libxml2_encoding.c +++ b/src/minivhd/libxml2_encoding.c @@ -444,4 +444,4 @@ NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ \ No newline at end of file +THE SOFTWARE. */ diff --git a/src/minivhd/libxml2_encoding.h b/src/minivhd/libxml2_encoding.h index 831aea4..d86770b 100644 --- a/src/minivhd/libxml2_encoding.h +++ b/src/minivhd/libxml2_encoding.h @@ -9,4 +9,4 @@ int UTF16LEToUTF8(unsigned char* out, int *outlen, const unsigned char* inb, int int UTF8ToUTF16LE(unsigned char* outb, int *outlen, const unsigned char* in, int *inlen); int UTF16BEToUTF8(unsigned char* out, int *outlen, const unsigned char* inb, int *inlenb); int UTF8ToUTF16BE(unsigned char* outb, int *outlen, const unsigned char* in, int *inlen); -#endif \ No newline at end of file +#endif diff --git a/src/minivhd/minivhd.h b/src/minivhd/minivhd.h index 0d925f7..357c91e 100644 --- a/src/minivhd/minivhd.h +++ b/src/minivhd/minivhd.h @@ -266,4 +266,4 @@ int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i * \return the number of sectors that were not written, or zero */ int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors); -#endif \ No newline at end of file +#endif diff --git a/src/minivhd/minivhd_convert.c b/src/minivhd/minivhd_convert.c index 1de6f46..8e712e4 100644 --- a/src/minivhd/minivhd_convert.c +++ b/src/minivhd/minivhd_convert.c @@ -105,4 +105,4 @@ FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, mvhd_close(vhdm); mvhd_fseeko64(raw_img, 0, SEEK_SET); return raw_img; -} \ No newline at end of file +} diff --git a/src/minivhd/minivhd_create.c b/src/minivhd/minivhd_create.c index c47c7d8..c1725c4 100644 --- a/src/minivhd/minivhd_create.c +++ b/src/minivhd/minivhd_create.c @@ -482,4 +482,4 @@ MVHDMeta* mvhd_create_ex(MVHDCreationOptions options, int* err) { } return NULL; /* Make the compiler happy */ -} \ No newline at end of file +} diff --git a/src/minivhd/minivhd_create.h b/src/minivhd/minivhd_create.h index 9840d19..203834a 100644 --- a/src/minivhd/minivhd_create.h +++ b/src/minivhd/minivhd_create.h @@ -5,4 +5,4 @@ MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_in_bytes, MVHDGeom* geom, int* err, mvhd_progress_callback progress_callback); -#endif \ No newline at end of file +#endif diff --git a/src/minivhd/minivhd_internal.h b/src/minivhd/minivhd_internal.h index ea75284..9f4db19 100644 --- a/src/minivhd/minivhd_internal.h +++ b/src/minivhd/minivhd_internal.h @@ -93,4 +93,4 @@ struct MVHDMeta { } format_buffer; }; -#endif \ No newline at end of file +#endif diff --git a/src/minivhd/minivhd_io.c b/src/minivhd/minivhd_io.c index ddd1717..7aa55be 100644 --- a/src/minivhd/minivhd_io.c +++ b/src/minivhd/minivhd_io.c @@ -276,4 +276,4 @@ int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, voi int mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff) { return 0; -} \ No newline at end of file +} diff --git a/src/minivhd/minivhd_io.h b/src/minivhd/minivhd_io.h index cdbfa6d..0f4017a 100644 --- a/src/minivhd/minivhd_io.h +++ b/src/minivhd/minivhd_io.h @@ -129,4 +129,4 @@ int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, voi */ int mvhd_noop_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* in_buff); -#endif \ No newline at end of file +#endif diff --git a/src/minivhd/minivhd_manage.c b/src/minivhd/minivhd_manage.c index e9473c0..97eed8e 100644 --- a/src/minivhd/minivhd_manage.c +++ b/src/minivhd/minivhd_manage.c @@ -532,4 +532,4 @@ int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors) { } vhdm->write_sectors(vhdm, offset, remain, vhdm->format_buffer.zero_data); return 0; -} \ No newline at end of file +} diff --git a/src/minivhd/minivhd_struct_rw.c b/src/minivhd/minivhd_struct_rw.c index c77fa60..bef6590 100644 --- a/src/minivhd/minivhd_struct_rw.c +++ b/src/minivhd/minivhd_struct_rw.c @@ -164,4 +164,4 @@ void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer) { mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); } mvhd_next_struct_to_buffer(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); -} \ No newline at end of file +} diff --git a/src/minivhd/minivhd_struct_rw.h b/src/minivhd/minivhd_struct_rw.h index ee49bb6..a587177 100644 --- a/src/minivhd/minivhd_struct_rw.h +++ b/src/minivhd/minivhd_struct_rw.h @@ -35,4 +35,4 @@ void mvhd_footer_to_buffer(MVHDFooter* footer, uint8_t* buffer); */ void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer); -#endif \ No newline at end of file +#endif From c7e5dd93b4e0b95123dd48a5bcc6e3aacd9d5401 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 20:55:05 +0000 Subject: [PATCH 0983/1050] Remove duplicate typedef from minivhd_internal.h. Patch from shermanp. --- src/minivhd/minivhd_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/minivhd/minivhd_internal.h b/src/minivhd/minivhd_internal.h index 9f4db19..f42ca58 100644 --- a/src/minivhd/minivhd_internal.h +++ b/src/minivhd/minivhd_internal.h @@ -3,6 +3,7 @@ #include #include #include +#include "minivhd.h" /* Pull in the MVHDMeta typedef */ #define MVHD_FOOTER_SIZE 512 #define MVHD_SPARSE_SIZE 1024 @@ -74,7 +75,6 @@ typedef struct MVHDSparseHeader { uint8_t reserved_2[256]; } MVHDSparseHeader; -typedef struct MVHDMeta MVHDMeta; struct MVHDMeta { FILE* f; bool readonly; From 22e7faaabc9500e7be315e23944f1853f89c9d49 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 20:56:11 +0000 Subject: [PATCH 0984/1050] MiniVHD: Add convenience functions to public API. Patch from shermanp. --- src/minivhd/minivhd.h | 40 ++++++++++++++++++++++++++++++++++++++ src/minivhd/minivhd_util.c | 5 +++++ src/minivhd/minivhd_util.h | 3 --- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/minivhd/minivhd.h b/src/minivhd/minivhd.h index 357c91e..aafd559 100644 --- a/src/minivhd/minivhd.h +++ b/src/minivhd/minivhd.h @@ -191,6 +191,46 @@ void mvhd_close(MVHDMeta* vhdm); */ MVHDGeom mvhd_calculate_geometry(uint64_t size); +/** + * \brief Get the CHS geometry from the image + * + * \param [in] vhdm MiniVHD data structure + * + * \return The CHS geometry as stored in the image + */ +MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm); + +/** + * \brief Get the 'current_size' value from the image + * + * Note that the size returned may not match the size calculated from the + * CHS geometry. It is up to the caller to decide how best to handle this. + * + * \param [in] vhdm MiniVHD data structure + * + * \return The 'current_size' value in bytes, as stored in the image. + * Note, this may not match the CHS geometry. + */ +uint64_t mvhd_get_current_size(MVHDMeta* vhdm); + +/** + * \brief Calculate CHS geometry size in bytes + * + * \param [in] geom the CHS geometry to calculate + * + * \return the size in bytes + */ +uint64_t mvhd_calc_size_bytes(MVHDGeom *geom); + +/** + * \brief Calculate CHS geometry size in sectors + * + * \param [in] geom the CHS geometry to calculate + * + * \return the size in sectors + */ +uint32_t mvhd_calc_size_sectors(MVHDGeom *geom); + /** * \brief Convert a raw disk image to a fixed VHD image * diff --git a/src/minivhd/minivhd_util.c b/src/minivhd/minivhd_util.c index 5bfc599..cd7d446 100644 --- a/src/minivhd/minivhd_util.c +++ b/src/minivhd/minivhd_util.c @@ -16,6 +16,7 @@ #include "libxml2_encoding.h" #include "minivhd_internal.h" #include "minivhd_util.h" +#include "minivhd.h" const char MVHD_CONECTIX_COOKIE[] = "conectix"; const char MVHD_CREATOR[] = "pcem"; @@ -186,6 +187,10 @@ MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm) { return geometry; } +uint64_t mvhd_get_current_size(MVHDMeta* vhdm) { + return vhdm->footer.curr_sz; +} + uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer) { uint32_t new_chk = 0; uint32_t orig_chk = footer->checksum; diff --git a/src/minivhd/minivhd_util.h b/src/minivhd/minivhd_util.h index df68410..8a18b55 100644 --- a/src/minivhd/minivhd_util.h +++ b/src/minivhd/minivhd_util.h @@ -77,9 +77,6 @@ time_t vhd_get_created_time(MVHDMeta *vhdm); FILE* mvhd_fopen(const char* path, const char* mode, int* err); void mvhd_set_encoding_err(int encoding_retval, int* err); -uint64_t mvhd_calc_size_bytes(MVHDGeom *geom); -uint32_t mvhd_calc_size_sectors(MVHDGeom *geom); -MVHDGeom mvhd_get_geometry(MVHDMeta* vhdm); /** * \brief Generate VHD footer checksum From 744583433e8cd473f3dbfcbf96f9dd352e03bcb9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 20:57:28 +0000 Subject: [PATCH 0985/1050] MiniVHD: Fix multi sector writes. Patch from sards3. --- src/minivhd/minivhd_io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/minivhd/minivhd_io.c b/src/minivhd/minivhd_io.c index 7aa55be..4169d66 100644 --- a/src/minivhd/minivhd_io.c +++ b/src/minivhd/minivhd_io.c @@ -245,6 +245,10 @@ int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, voi for (s = offset; s < ls; s++) { blk = s / vhdm->sect_per_block; sib = s % vhdm->sect_per_block; + if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { + /* Write the sector bitmap for the previous block, before we replace it. */ + mvhd_write_curr_sect_bitmap(vhdm); + } if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { /* "read" the sector bitmap first, before creating a new block, as the bitmap will be zero either way */ @@ -252,11 +256,7 @@ int mvhd_sparse_diff_write(MVHDMeta* vhdm, uint32_t offset, int num_sectors, voi mvhd_create_block(vhdm, blk); } if (blk != prev_blk) { - if (vhdm->bitmap.curr_block != blk) { - if (prev_blk >= 0) { - /* Write the sector bitmap for the previous block, before we replace it. */ - mvhd_write_curr_sect_bitmap(vhdm); - } + if (vhdm->bitmap.curr_block != blk) { mvhd_read_sect_bitmap(vhdm, blk); mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); } else { From 8fa271dca9c76c6e1ca9d232ec054e29292e6d7e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 21 Nov 2020 20:58:32 +0000 Subject: [PATCH 0986/1050] Remove inclusion of minivhd_utils.h in wx-config.c. Patch from shermanp. --- src/wx-config.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wx-config.c b/src/wx-config.c index 9f24e2c..5ff7679 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -21,7 +21,6 @@ #include "vid_voodoo.h" #include "minivhd/minivhd.h" -#include "minivhd/minivhd_util.h" //#define MAX_CYLINDERS ((((1 << 28)-1) / 16) / 63) #define MAX_CYLINDERS 265264 /*Award 430VX won't POST with a larger drive*/ From d4dc2e9441c145e742efa5e1bdaf003713947ac7 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Nov 2020 12:48:24 +0000 Subject: [PATCH 0987/1050] Load VGA latches even on 'fast' chained mode byte reads. Fixes missing logos on Amnesia. --- src/vid_svga.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index 5092ccf..a8c978e 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -996,7 +996,7 @@ uint8_t svga_read(uint32_t addr, void *p) cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; - + egareads++; // pclog("Readega %06X ",addr); @@ -1012,6 +1012,11 @@ uint8_t svga_read(uint32_t addr, void *p) addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; + latch_addr = addr & svga->vram_mask & ~3; + 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]; return svga->vram[addr & svga->vram_mask]; } else if (svga->chain2_read) @@ -1060,7 +1065,6 @@ uint8_t svga_read(uint32_t addr, void *p) return ~(temp | temp2 | temp3 | temp4); } //pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); - return svga->vram[addr | readplane]; } From e518b4312b281c9ffd1c2db1172dfda2c62dcd65 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Nov 2020 14:28:57 +0000 Subject: [PATCH 0988/1050] Handle unaligned LFB reads/writes on Banshee/V3. Fixes UI glitches in Red Alert 2. --- src/vid_voodoo_banshee.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 769d9de..5915c27 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1339,6 +1339,9 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + if (addr & 1) + return banshee_read_linear(addr, p) | (banshee_read_linear(addr+1, p) << 8); + cycles -= voodoo->read_time; cycles_lost += voodoo->read_time; @@ -1372,6 +1375,9 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + if (addr & 3) + return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr+2, p) << 16); + cycles -= voodoo->read_time; cycles_lost += voodoo->read_time; @@ -1439,6 +1445,13 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; + if (addr & 1) + { + banshee_write_linear(addr, val, p); + banshee_write_linear(addr + 1, val >> 8, p); + return; + } + cycles -= voodoo->write_time; cycles_lost += voodoo->write_time; @@ -1474,6 +1487,13 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) svga_t *svga = &banshee->svga; int timing; + if (addr & 3) + { + banshee_write_linear_w(addr, val, p); + banshee_write_linear_w(addr + 2, val >> 16, p); + return; + } + if (addr == voodoo->last_write_addr+4) timing = voodoo->burst_time; else From 81a8873d593e5a197e1bdaf7e9650aa07afad852 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Nov 2020 17:11:13 +0000 Subject: [PATCH 0989/1050] Fix Banshee/V3 cursor vertical clipping. --- src/vid_voodoo_banshee.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 5915c27..abe269e 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -616,7 +616,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Video_hwCurPatAddr: banshee->hwCurPatAddr = val; - svga->hwcursor.addr = val & 0xfffff0; + svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16); break; case Video_hwCurLoc: banshee->hwCurLoc = val; @@ -629,6 +629,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) } else svga->hwcursor.yoff = 0; + svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); svga->hwcursor.xsize = 64; svga->hwcursor.ysize = 64; // pclog("hwCurLoc %08x %i\n", val, svga->hwcursor.y); From 57fb74a4a3e8e25fb20d5d5d29ed3eb2b6718d54 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 22 Nov 2020 22:03:21 +0000 Subject: [PATCH 0990/1050] Fix Voodoo recompiler chromakey for rgbselect != texture RGB. Fixes rendering issues in Manx TT. --- src/vid_voodoo_codegen_x86-64.h | 42 +++++++++++++++++++++++++++++---- src/vid_voodoo_codegen_x86.h | 42 +++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 5f61b2c..0177631 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -1733,10 +1733,44 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & FBZ_CHROMAKEY)) { - addbyte(0x66); /*MOVD EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); + switch (_rgb_sel) + { + case CC_LOCALSELECT_ITER_RGB: + addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x87); + addlong(offsetof(voodoo_state_t, ib)); + addbyte(0x66); /*PSRAD XMM0, 12*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xe0); + addbyte(12); + addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0); + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0); + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + case CC_LOCALSELECT_COLOR1: + addbyte(0x8b); /*MOV EAX, params->color1[RSI]*/ + addbyte(0x86); + addlong(offsetof(voodoo_params_t, color1)); + break; + case CC_LOCALSELECT_TEX: + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + } addbyte(0x8b); /*MOV EBX, params->chromaKey[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, chromaKey)); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index fc2be0c..3721f70 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -1668,10 +1668,44 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & FBZ_CHROMAKEY)) { - addbyte(0x66); /*MOVD EAX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0xc0); + switch (_rgb_sel) + { + case CC_LOCALSELECT_ITER_RGB: + addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x87); + addlong(offsetof(voodoo_state_t, ib)); + addbyte(0x66); /*PSRAD XMM0, 12*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xe0); + addbyte(12); + addbyte(0x66); /*PACKSSDW XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0); + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0); + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + case CC_LOCALSELECT_COLOR1: + addbyte(0x8b); /*MOV EAX, params->color1[ESI]*/ + addbyte(0x86); + addlong(offsetof(voodoo_params_t, color1)); + break; + case CC_LOCALSELECT_TEX: + addbyte(0x66); /*MOVD EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + } addbyte(0x8b); /*MOV EBX, params->chromaKey[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, chromaKey)); From 6f8401c72c228d61f87d0cdc173fdc29ae3e0b69 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 23 Nov 2020 21:57:15 +0000 Subject: [PATCH 0991/1050] ATI 28800 (VGA Charger) was selecting the wrong dot clock for VGA standard graphics modes. In the absence of better information or a board to test with, I am currently assuming the table I used as reference was incorrect. Changing timings to allow for correct refresh rate. --- src/vid_ati28800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 871f1c5..55ccad0 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -282,7 +282,7 @@ void ati28800_recalctimings(svga_t *svga) case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; break; case 0x0A: svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; break; case 0x0B: svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; break; - case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; + case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; case 0x0D: svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; break; case 0x0E: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; case 0x0F: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; From 969266a09c2f74d94fd92f44d943a5cfef786ed4 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 25 Nov 2020 20:21:51 +0000 Subject: [PATCH 0992/1050] Fix uninitialised variable in ati18800_in(). --- src/vid_ati18800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index fd00caa..2b30d4c 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -124,7 +124,7 @@ uint8_t ati18800_in(uint16_t addr, void *p) { ati18800_t *ati18800 = (ati18800_t *)p; svga_t *svga = &ati18800->svga; - uint8_t temp; + uint8_t temp = 0xff; // if (addr != 0x3da) pclog("ati18800_in : %04X ", addr); From 15fd983fa9b6fb85f00491be3e5c9ea17b23c5db Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 26 Nov 2020 08:29:14 +0000 Subject: [PATCH 0993/1050] Don't fatal() on unknown Banshee/V3 3D reg read. Fixes Spearhead. --- src/vid_voodoo_banshee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index abe269e..76733ca 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1112,7 +1112,7 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p) break; default: - fatal("banshee_reg_readl: 3D addr=%08x\n", addr); + pclog("banshee_reg_readl: 3D addr=%08x\n", addr); break; } break; From 0ec9c6e728fb45f48d0572b955ec628c85a6d775 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 26 Nov 2020 08:39:54 +0000 Subject: [PATCH 0994/1050] Remove C99 declarations in for loops from MiniVHD. Patch from Greatpsycho. --- src/minivhd/minivhd_convert.c | 8 ++++---- src/minivhd/minivhd_create.c | 9 ++++++--- src/minivhd/minivhd_io.c | 6 ++++-- src/minivhd/minivhd_manage.c | 9 ++++++--- src/minivhd/minivhd_struct_rw.c | 6 ++++-- src/minivhd/minivhd_util.c | 17 +++++++++++------ 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/minivhd/minivhd_convert.c b/src/minivhd/minivhd_convert.c index 8e712e4..1b4f4f0 100644 --- a/src/minivhd/minivhd_convert.c +++ b/src/minivhd/minivhd_convert.c @@ -64,8 +64,8 @@ MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8 uint8_t buff[4096] = {0}; // 8 sectors uint8_t empty_buff[4096] = {0}; int total_sectors = mvhd_calc_size_sectors(&geom); - int copy_sect = 0; - for (int i = 0; i < total_sectors; i += 8) { + int copy_sect = 0, i; + for (i = 0; i < total_sectors; i += 8) { copy_sect = 8; if ((i + 8) >= total_sectors) { copy_sect = total_sectors - i; @@ -93,8 +93,8 @@ FILE* mvhd_convert_to_raw(const char* utf8_vhd_path, const char* utf8_raw_path, } uint8_t buff[4096] = {0}; // 8 sectors int total_sectors = mvhd_calc_size_sectors((MVHDGeom*)&vhdm->footer.geom); - int copy_sect = 0; - for (int i = 0; i < total_sectors; i += 8) { + int copy_sect = 0, i; + for (i = 0; i < total_sectors; i += 8) { copy_sect = 8; if ((i + 8) >= total_sectors) { copy_sect = total_sectors - i; diff --git a/src/minivhd/minivhd_create.c b/src/minivhd/minivhd_create.c index c1725c4..9bb63c1 100644 --- a/src/minivhd/minivhd_create.c +++ b/src/minivhd/minivhd_create.c @@ -356,7 +356,8 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); fwrite(sparse_buff, sizeof sparse_buff, 1, f); /* The BAT sectors need to be filled with 0xffffffff */ - for (uint32_t i = 0; i < num_bat_sect; i++) { + uint32_t i; + for (i = 0; i < num_bat_sect; i++) { fwrite(bat_sect, sizeof bat_sect, 1, f); } mvhd_write_empty_sectors(f, 5); @@ -370,8 +371,10 @@ static MVHDMeta* mvhd_create_sparse_diff(const char* path, const char* par_path, assert(curr_pos == par_loc_offset); /* Fill the space required for location data with zero */ uint8_t empty_sect[MVHD_SECTOR_SIZE] = {0}; - for (int i = 0; i < 2; i++) { - for (uint32_t j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { + int i; + uint32_t j; + for (i = 0; i < 2; i++) { + for (j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { fwrite(empty_sect, sizeof empty_sect, 1, f); } } diff --git a/src/minivhd/minivhd_io.c b/src/minivhd/minivhd_io.c index 4169d66..c21f68d 100644 --- a/src/minivhd/minivhd_io.c +++ b/src/minivhd/minivhd_io.c @@ -45,7 +45,8 @@ static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t void mvhd_write_empty_sectors(FILE* f, int sector_count) { uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; - for (int i = 0; i < sector_count; i++) { + int i; + for (i = 0; i < sector_count; i++) { fwrite(zero_bytes, sizeof zero_bytes, 1, f); } } @@ -126,7 +127,8 @@ static void mvhd_create_block(MVHDMeta* vhdm, int blk) { /* Yikes! We're supposed to be on a sector boundary. Add some padding */ int64_t padding_amount = (int64_t)MVHD_SECTOR_SIZE - (abs_offset % MVHD_SECTOR_SIZE); uint8_t zero_byte = 0; - for (int i = 0; i < padding_amount; i++) { + int i; + for (i = 0; i < padding_amount; i++) { fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); } abs_offset += padding_amount; diff --git a/src/minivhd/minivhd_manage.c b/src/minivhd/minivhd_manage.c index 97eed8e..d852a94 100644 --- a/src/minivhd/minivhd_manage.c +++ b/src/minivhd/minivhd_manage.c @@ -103,7 +103,8 @@ static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err) { return -1; } mvhd_fseeko64(vhdm->f, vhdm->sparse.bat_offset, SEEK_SET); - for (uint32_t i = 0; i < vhdm->sparse.max_bat_ent; i++) { + uint32_t i; + for (i = 0; i < vhdm->sparse.max_bat_ent; i++) { fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f); vhdm->block_offset[i] = mvhd_from_be32(vhdm->block_offset[i]); } @@ -239,7 +240,8 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) { } /* Now read the parent locator entries, both relative and absolute, if they exist */ unsigned char* loc_path; - for (int i = 0; i < 8; i++) { + int i; + for (i = 0; i < 8; i++) { utf_outlen = MVHD_MAX_PATH_BYTES - 1; if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2RU) { loc_path = (unsigned char*)paths->w2ru_path; @@ -526,7 +528,8 @@ int mvhd_write_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* i int mvhd_format_sectors(MVHDMeta* vhdm, uint32_t offset, int num_sectors) { int num_full = num_sectors / vhdm->format_buffer.sector_count; int remain = num_sectors % vhdm->format_buffer.sector_count; - for (int i = 0; i < num_full; i++) { + int i; + for (i = 0; i < num_full; i++) { vhdm->write_sectors(vhdm, offset, vhdm->format_buffer.sector_count, vhdm->format_buffer.zero_data); offset += vhdm->format_buffer.sector_count; } diff --git a/src/minivhd/minivhd_struct_rw.c b/src/minivhd/minivhd_struct_rw.c index bef6590..77f26a4 100644 --- a/src/minivhd/minivhd_struct_rw.c +++ b/src/minivhd/minivhd_struct_rw.c @@ -133,7 +133,8 @@ void mvhd_buffer_to_header(MVHDSparseHeader* header, uint8_t* buffer) { mvhd_next_buffer_to_struct(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); mvhd_next_buffer_to_struct(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); mvhd_next_buffer_to_struct(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); - for (int i = 0; i < 8; i++) { + int i; + for (i = 0; i < 8; i++) { mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); @@ -156,7 +157,8 @@ void mvhd_header_to_buffer(MVHDSparseHeader* header, uint8_t* buffer) { mvhd_next_struct_to_buffer(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); mvhd_next_struct_to_buffer(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); mvhd_next_struct_to_buffer(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); - for (int i = 0; i < 8; i++) { + int i; + for (i = 0; i < 8; i++) { mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); diff --git a/src/minivhd/minivhd_util.c b/src/minivhd/minivhd_util.c index cd7d446..b04e022 100644 --- a/src/minivhd/minivhd_util.c +++ b/src/minivhd/minivhd_util.c @@ -94,7 +94,8 @@ void mvhd_generate_uuid(uint8_t* uuid) { /* We aren't doing crypto here, so using system time as seed should be good enough */ srand((unsigned int)time(0)); - for (int n = 0; n < 16; n++) { + int n; + for (n = 0; n < 16; n++) { uuid[n] = rand(); } uuid[6] &= 0x0F; @@ -196,7 +197,8 @@ uint32_t mvhd_gen_footer_checksum(MVHDFooter* footer) { uint32_t orig_chk = footer->checksum; footer->checksum = 0; uint8_t* footer_bytes = (uint8_t*)footer; - for (size_t i = 0; i < sizeof *footer; i++) { + size_t i; + for (i = 0; i < sizeof *footer; i++) { new_chk += footer_bytes[i]; } footer->checksum = orig_chk; @@ -208,7 +210,8 @@ uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader* header) { uint32_t orig_chk = header->checksum; header->checksum = 0; uint8_t* sparse_bytes = (uint8_t*)header; - for (size_t i = 0; i < sizeof *header; i++) { + size_t i; + for (i = 0; i < sizeof *header; i++) { new_chk += sparse_bytes[i]; } header->checksum = orig_chk; @@ -279,19 +282,21 @@ int mvhd_fseeko64(FILE* stream, int64_t offset, int origin) } uint32_t mvhd_crc32_for_byte(uint32_t r) { - for (int j = 0; j < 8; ++j) + int j; + for (j = 0; j < 8; ++j) r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; return r ^ (uint32_t)0xFF000000L; } uint32_t mvhd_crc32(const void* data, size_t n_bytes) { static uint32_t table[0x100]; + size_t i; if (!*table) - for (size_t i = 0; i < 0x100; ++i) + for (i = 0; i < 0x100; ++i) table[i] = mvhd_crc32_for_byte(i); uint32_t crc = 0; - for (size_t i = 0; i < n_bytes; ++i) + for (i = 0; i < n_bytes; ++i) crc = table[(uint8_t)crc ^ ((uint8_t*)data)[i]] ^ crc >> 8; return crc; From 2ad5b83d6e0fc0f88db155a4c0a6a85348f87630 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 26 Nov 2020 08:42:14 +0000 Subject: [PATCH 0995/1050] Add README.md documentation revamp. Patch from gen_angry. --- README.md | 375 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..74a693b --- /dev/null +++ b/README.md @@ -0,0 +1,375 @@ +# [PCem](https://pcem-emulator.co.uk/) +## Download: [Windows](https://pcem-emulator.co.uk/files/PCemV16Win.zip)/[Linux](https://pcem-emulator.co.uk/files/PCemV16Linux.tar.gz) + +Latest version: v16 [Changelog](https://pcem-emulator.co.uk/index.html) + +PCem is licensed under GPL v2.0, see [COPYING](COPYING) for more details. + +You can submit patches on our [forum](https://pcem-emulator.co.uk/phpBB3/viewforum.php?f=4). Before you do, please note the [guidelines](https://pcem-emulator.co.uk/phpBB3/viewtopic.php?f=3&t=5) for submitting patches. + +:exclamation: Note: NO COPYRIGHTED ROM FILES ARE INCLUDED NOR WILL THEY BE. PLEASE DO NOT ASK FOR THEM. + +## BSD and Linux supplement (v16) + +You will need the following libraries (and their dependencies): +- SDL2 +- wxWidgets 3.x +- OpenAL + +Open a terminal window, navigate to the PCem directory then enter: +### Linux +``` +./configure --enable-release +make +``` +### BSD +``` +./configure --enable-release-build +gmake +``` + +then `./pcem` to run. + +The Linux/BSD versions store BIOS ROM images, configuration files, and other data in `~/.pcem` + +configure options are : +``` + --enable-release-build : Generate release build. Recommended for regular use. + --enable-debug : Compile with debugging enabled. + --enable-networking : Build with networking support. + --enable-alsa : Build with support for MIDI output through ALSA. Requires libasound. +``` + +The menu is a pop-up menu in the Linux/BSD port. Right-click on the main window when mouse is not +captured. + +CD-ROM support currently only accesses `/dev/cdrom`. It has not been heavily tested. + +## Links + +### PCem emulates the following hardware (as of v16): + +Hardware | Links +--- | --- +Systems | [8088](#8088-based)
[8086](#8086-based)
[286](#286-based)
[386](#386-based)
[486](#486-based)
[Pentium](#pentium-based)
[Super Socket 7](#super-socket-7-based) +Graphics | [Basic](#basic-cards)
[Unaccelerated (S)VGA cards](#unaccelerated-svga-cards)
[2D accelerated SVGA cards](#2d-accelerated-svga-cards)
[3D accelerated SVGA cards](#3d-accelerated-svga-cards)
[3D only cards](#3d-only-cards) +Sound | [Cards](#sound-cards) +HDD Controller | [Cards](#hdd-controller-cards) +Misc | [Cards](#misc-cards) + +### [Software Tested](TESTED.md) (list) +- [DOS](TESTED.md#dos)
+- [Windows](TESTED.md#windows)
+- [Windows NT](TESTED.md#windows-nt)
+- [OS/2](TESTED.md#os2)
+- [Linux](TESTED.md#linux)
+- [Applications](TESTED.md#applications)
+- [Games](TESTED.md#games)
+- [Demos](TESTED.md#demos)
+- [Emulators](TESTED.md#emulators)
+ +
+ +## Systems + +### 8088 based +Release | Machine | ROM file needed
(within ./roms/ folder) +:-: | --- | --- +1981 | IBM PC
8088 at 4.77 MHz
16KB - 640KB RAM (min. 64KB) | ibmpc/pc102782.bin
ibmpc/basicc11.f6
ibmpc/basicc11.f8
ibmpc/basicc11.fa
ibmpc/basicc11.fc +1983 | Compaq Portable Plus
8088 at 4.77 MHz
128KB - 640KB RAM | compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin +1983 | IBM XT
8088 at 4.77 MHz
64KB - 640KB RAM | ibmxt/5000027.u19
ibmxt/1501512.u18 +1983 | Leading Edge Model M
8088 at 7.16 MHz
128KB - 704KB RAM | leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin +1984 | IBM PCjr [[5]](#system-note-5)
8088 at 4.77 MHz
64KB - 640KB RAM (min. 128KB)
Built-in 16 colour graphics
3 voice sound
Not generally PC compatible. | ibmpcjr/bios.rom +1984 | Tandy 1000 [[5]](#system-note-5)
8088 at 4.77 MHz
128KB - 640KB RAM
Built-in 16 colour graphics
3 voice sound | tandy/tandy1t1.020 +1985 | NCR PC4i
8088 at 4.77 MHz
256KB - 640KB RAM | ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN +1986 | DTK Clone XT
8088 at 8/10 MHz
64KB - 640KB RAM | dtk/dtk_erso_2.42_2764.bin +1986 | Phoenix XT clone
8088 at 8/10 MHz
64KB - 640KB RAM | pxxt/000p001.bin +1987 | Tandy 1000HX
8088 at 7.16 MHz
256KB - 640KB RAM
Built-in 16 colour graphics
3 voice sound
Has DOS 2.11 in ROM | tandy1000hx/v020000.u12 +1987 | Thomson TO16 PC
8088 at 9.54 MHz
512KB - 640KB RAM | to16_pc/TO16_103.bin +1987 | Toshiba T1000 [[1]](#system-note-1) [[5]](#system-note-5)
8088 at 4.77 MHz
512KB - 1024KB RAM
CGA on built-in LCD | t1000/t1000.rom
t1000/t1000font.rom +1987 | VTech Laser Turbo XT
8088 at 10 MHz
640KB RAM | ltxt/27c64.bin +1987 | Zenith Data SupersPort
8088 at 8 MHz
128KB - 640KB RAM
Built-in LCD video is not currently emulated | zdsupers/z184m v3.1d.10d +1988? | ©Anonymous Generic Turbo XT BIOS
8088 at 8+ MHz
64KB - 640KB RAM | genxt/pcxt.rom +1988 | Atari PC3
8088 at 8 MHz
640KB RAM | ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN +1988 | Juko XT clone | jukopc/000o001.bin +1988 | Schneider Euro PC
8088 at 9.54 MHz
512KB - 640KB RAM | europc/50145
europc/50146 +1989 | AMI XT clone
8088 at 8+ MHz
64KB - 640KB RAM | amixt/ami_8088_bios_31jan89.bin +2015 | Xi8088
8088 at 4.77-13.33 MHz
640KB RAM | xi8088/bios-xi8088.bin + +### 8086 based +Release | Machine | ROM file needed
(within ./roms/ folder) +:-: | --- | --- +1984 | Olivetti M24 [[5]](#system-note-5)
8086 at 8 MHz
128KB - 640KB RAM
Built-in enhanced CGA (supports 640x400x2) | olivetti_m24/olivetti_m24_version_1.43_low.bin
olivetti_m24/olivetti_m24_version_1.43_high.bin +1986 | Amstrad PC1512 [[5]](#system-note-5)
8086 at 8 MHz
512KB - 640KB RAM
Enhanced CGA (supports 640x200x16)
Custom mouse port | pc1512/40043.v1
pc1512/40044.v2
pc1512/40078.ic127 +1987 | Amstrad PC1640 [[5]](#system-note-5)
8086 at 8 MHz
640KB RAM
Built-in Paradise EGA
Custom mouse port | pc1640/40043.v3
pc1640/40044.v3
pc1640/40100 +1987 | Toshiba T1200 [[1]](#system-note-1) [[5]](#system-note-5)
8086 at 9.54 MHz
1MB - 2MB RAM
CGA on built-in LCD | t1200/t1200_019e.ic15.bin
t1200/t1000font.rom +1988 | Amstrad PPC512/640 [[5]](#system-note-5)
8086 at 8 MHz
512KB - 640KB RAM
Built-in CGA w/ plasma display | ppc512/40107.v2
ppc512/40108.v2
ppc512/40109.bin +1988 | Sinclair PC200/Amstrad PC20 [[5]](#system-note-5)
8086 at 8 MHz
512KB - 640KB RAM
Built-in CGA (supports TV-out 50hz PAL) | pc200/pc20v2.0
pc200/pc20v2.1
pc200/40109.bin +1988 | VTech Laser XT3
8086 at 10 MHz
512KB - 1152KB RAM | lxt3/27c64d.bin +1989 | Amstrad PC2086 [[5]](#system-note-5)
8086 at 8 MHz
640KB RAM
Built-in VGA | pc2086/40179.ic129
pc2086/40180.ic132
pc2086/40186.ic171 +1989 | Tandy 1000SL/2 [[5]](#system-note-5)
8086 at 9.54 MHz
512KB - 768KB RAM
Built-in 16 colour graphics
4 voice sound | tandy1000sl2/8079047.hu1
tandy1000sl2/8079048.hu2 +1990 | Amstrad PC3086 [[5]](#system-note-5)
8086 at 8 MHz
640KB RAM
Built-in VGA | pc3086/fc00.bin
pc3086/c000.bin + +### 286 based +Release | Machine | ROM file needed
(within ./roms/ folder) +:-: | --- | --- +1984 | IBM AT
286 at 6 or 8 MHz
256KB - 16MB RAM | ibmat/at111585.0
ibmat/at111585.1 +1986 | Compaq Portable II
286 at 8 MHz
256KB - 15MB RAM | compaq_pii/109739-001.rom
compaq_pii/109740-001.rom +1986 | IBM XT Model 286
286 at 6 MHz
256KB - 16MB RAM | ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN
ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.BIN +1986 | Toshiba T3100e [[1]](#system-note-1) [[5]](#system-note-5)
286 at 12 MHz
1MB - 5MB RAM
CGA on gas-plasma display | t3100e/t3100e_font.bin
t3100e/t3100e.rom +1987 | IBM PS/2 Model 50 [[5]](#system-note-5)
286 at 10 MHz
1MB - 16MB RAM
Built-in VGA
MCA bus | i8550021/90x7420.zm13
i8550021/90x7423.zm14
i8550021/90x7426.zm16
i8550021/90x7429.zm18 +1988 | Bull Micral 45
286 at 12 MHz
1MB - 6MB RAM | bull_micral_45/even.fil
bull_micral_45/odd.fil +1988 | Commodore PC30-III
286 at 12 MHz
512KB - 16MB RAM | cmdpc30/commodore pc 30 iii even.bin
cmdpc30/commodore pc 30 iii odd.bin +1988 | IBM PS/2 Model 30-286
286 at 10 MHz
1MB - 16MB RAM
Built-in VGA
MCA bus | ibmps2_m30_286/33f5381a.bin +1989 | Epson PC AX
286
256KB - 16MB RAM | epson_pcax/EVAX
epson_pcax/ODAX +1989 | Epson PC AX2e
286 at 12 MHz
256KB - 16MB RAM | epson_pcax2e/EVAX
epson_pcax2e/ODAX +1990 | AMI 286 clone
286 at 8+ MHz
512KB - 16MB RAM | ami286/amic206.bin +1990 | Award 286 clone
286 at 8+ MHz
512KB - 16MB RAM | award286/award.bin +1990? | Dell System 200
286 at 12 MHz
640KB - 16MB RAM | dells200/dell0.bin
dells200/dell1.bin +1990 | IBM PS/1 Model 2011 [[5]](#system-note-5)
286 at 10 MHz
512KB - 16MB RAM
Built-in VGA
DOS 4.01 + GUI menu system in ROM | ibmps1/f80000.bin +? | Goldstar GDC-212M
286 at 12 MHz
512KB - 4MB RAM | gdc212m/gdc212m_72h.bin +? | GW-286CT GEAR
286 at 8+ MHz
512KB - 16MB RAM | gw286ct/2ctc001.bin +? | Hyundai Super-286TR
286 at 12 MHz
1MB - 4MB RAM | super286tr/award.bin +? | Samsung SPC-4200P
286 at 12 MHz
512KB - 2MB RAM | spc4200p/u8.01 +? | Samsung SPC-4216P
286 at 12 MHz
1MB - 5MB RAM | spc4216p/phoenix.bin
   or
spc4216p/7101.u8
spc4216p/ac64.u10 +? | Samsung SPC-4620P
286 at 12 MHz
1MB - 5MB RAM
Built-in Korean ATI-28800 | spc4620p/31005h.u8
spc4620p/31005h.u10
spc4620p/svb6120a_font.rom
spc4620p/31005h.u8
spc4620p/31005h.u10 +? | Tulip AT Compact
286
640KB - 16MB RAM | tulip_tc7/tc7be.bin
tulip_tc7/tc7bo.bin + +### 386 based +Release | Machine | ROM file needed
(within ./roms/ folder) +:-: | --- | --- +1987 | IBM PS/2 Model 80 [[5]](#system-note-5)
386DX at 20 MHz
1MB - 12MB RAM
Built-in VGA
MCA bus | i8580111/15f6637.bin
i8580111/15f6639.bin +1988 | ECS 386/32
386DX at 20 MHz
1MB - 16MB RAM | ecs386_32/386_32_even.bin
ecs386_32/386_32_odd.bin +1989 | IBM PS/2 Model 70 (type 3) [[5]](#system-note-5)
386DX at 25 MHz
2MB - 16MB RAM
Built-in VGA
MCA bus | ibmps2_m70_type3/70-a_even.bin
ibmps2_m70_type3/70-a_odd.bin +1989 | Compaq Deskpro 386
386DX at 20 MHz
1MB - 15MB RAM | deskpro386/109592-005.u11.bin
deskpro386/109591-005.u13.bin +1989 | Epson PC AX3
386SX at 16 MHz
256KB - 16MB RAM | epson_pcax3/EVAX3
epson_pcax3/ODAX3 +1989 | IBM PS/2 Model 55SX
386SX at 16 MHz
1MB - 8MB RAM
Built-in VGA
MCA bus | i8555081/33f8146.zm41
i8555081/33f8145.zm40 +1990 | DTK 386SX clone
386SX
512KB - 16MB RAM | dtk386/3cto001.bin +1990 | IBM PS/1 Model 2121 [[5]](#system-note-5)
386SX at 20 MHz
1MB - 16MB RAM
Built-in VGA | ibmps1_2121/fc0000.bin +1992? | Acermate 386SX/25N [[5]](#system-note-5)
386SX at 25 MHz
2MB - 16MB RAM
Built-in Oak SVGA | acer386/acer386.bin
acer386/oti067.bin +1992 | Amstrad MegaPC [[2]](#system-note-2) [[5]](#system-note-5)
386SX at 25 MHz
1MB - 16MB RAM
Built-in VGA
| megapc/41651-bios lo.u18
megapc/211253-bios hi.u19 +1992 | Commodore SL386SX-25 [[5]](#system-note-5)
386SX at 25 MHz
1MB - 16MB RAM
Built-in AVGA2 | cbm_sl386sx25/f000.bin
cbm_sl386sx25/c000.bin +1992 | Packard Bell Legend 300SX
386SX at 16 MHz
1MB - 16MB RAM | pb_l300sx/pb_l300sx.bin +1994 | AMI 386DX clone
386DX at 40 MHz
1MB - 32MB RAM | ami386dx/opt495sx.ami +1994 | AMI 386SX clone
386SX at 25 MHz
1MB - 16MB RAM | ami386/ami386.bin +1994 | MR 386DX clone
This is a generic 386DX clone with an MR BIOS | mr386dx/opt495sx.mr +? | KMX-C-02
386SX
512KB - 16MB RAM | kmxc02/3ctm005.bin + +### 486 based +Release | Machine
(+ addl. hardware) | CPU(s) Supported | ROM file needed
(within ./roms/ folder) +:-: | --- | --- | --- +1990 | IBM PS/2 Model 70 (type 4) [[3]](#system-note-3)
2MB - 16MB RAM
Built-in VGA
MCA bus | 486DX at 25 MHz | ibmps2_m70_type3/70-a_even.bin
ibmps2_m70_type3/70-a_odd.bin +1993 | AMI 486 clone
1MB - 32MB RAM | 486 at 16-66 MHz | ami486/ami486.bin +1993 | Elonex PC-425X [[5]](#system-note-5)
1MB - 256MB RAM
Built-in Trident TGUI9440CXi | 486SX at 25 MHz | elx_pc425x/elx_pc425x.bin
   or
elx_pc425x/elx_pc425x_bios.bin
elx_pc425x/elx_pc425x_vbios.bin +1993 | IBM PS/1 Model 2133 (EMEA 451)
2MB - 64MB RAM
Built-in Cirrus Logic GD5426 | 486SX at 25 MHz | ibmps1_2133/PS1_2133_52G2974_ROM.bin +1993 | Packard Bell PB410A [[5]](#system-note-5)
1MB - 64MB RAM
Built-in HT-216 video | 486 at 25-120 MHz
Am5x86 at 133-160 MHz
Cx5x86 at 100-133 MHz
Pentium Overdrive at 63-83 MHz | pb410a/PB410A.080337.4ABF.U25.bin +1994 | AMI WinBIOS 486 clone
1MB - 32MB RAM | 486 at 16-66 MHz | win486/ali1429g.amw +1995 | Award SiS 496/497
1MB - 64MB RAM | 486 at 16-120 MHz
Am5x86 at 133-160 MHz
Cx5x86 at 100-133 MHz
Pentium Overdrive at 63-83 MHz | sis496/sis496-1.awa + +### Pentium based +Release | Machine
(+ addl. hardware) | CPU(s) Supported | ROM file needed
(within ./roms/ folder) +:-: | --- | --- | --- +1994 | Intel Premiere/PCI (Batman's Revenge)
1MB - 128MB RAM | Pentium at 60-66 MHz
Pentium Overdrive at 120-133 MHz | revenge/1009af2_.bi0
revenge/1009af2_.bi1 +1995 | Intel Advanced/EV (Endeavor) [[4]](#system-note-4)
1MB - 128MB RAM | Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz | endeavor/1006cb0_.bi0
endeavor/1006cb0_.bi1 +1995 | Intel Advanced/ZP (Zappa)
1MB - 128MB RAM | Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz | zappa/1006bs0_.bio
zappa/1006bs0_.bi1 +1995 | Packard Bell PB520R (Robin LC) [[5]](#system-note-5)
1MB - 128MB RAM
Built-in Cirrus Logic GD-5434 | Pentium at 60-66 MHz
Pentium Overdrive at 120-133 MHz | pb520r/1009bc0r.bio
pb520r/1009bc0r.bi1
pb520r/gd5434.bin +1995 | Packard Bell PB570 (Hillary) [[5]](#system-note-5)
1MB - 128MB RAM
Built-in Cirrus Logic GD-5430 | Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz | pb570/1007by0r.bio
pb570/1007by0r.bi1
pb570/gd5430.bin +1996 | ASUS P/I-P55TVP4
1MB - 128MB RAM | Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz | p55tvp4/tv5i0204.awd +1996 | ASUS P/I-P55T2P4
1MB - 512MB RAM | Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz | p55t2p4/0207_j2.bin +1996 | Award 430VX PCI
1MB - 128MB RAM | Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz | 430vx/55xwuq0e.bin +1996 | Itautec Infoway Multimidia
8MB - 128MB RAM | Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz | infowaym/1006bs0_.bio
infowaym/1006bs0_.bi1 +1997 | Epox P55-VA
1MB - 128MB RAM | Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz | p55va/va021297.bin + +### Super Socket 7 based +Release | Machine
(+ addl. hardware) | CPU(s) Supported | ROM file needed
(within ./roms/ folder) +:-: | --- | --- | --- +1998 | FIC VA-503+
1MB - 512MB RAM | AMD K6 at 166-300 MHz
AMD K6-2 at 233-550 MHz
AMD K6-2+ at 450-550 MHz
AMD K6-III at 400-450 MHz
AMD K6-III+ at 400-500 MHz
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT WinChip2 at 200-250 MHz
IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz) | fic_va503p/je4333.bin + +#### Additional Notes +`[1]` Toshiba Button Mapping: +PCem maps [Fn] to `right-Ctrl` and `right-Alt`. The following functions are supported: +Key Combo | Function +---|--- +Fn + Num Lock | toggle numpad +Fn + Home | Internal LCD display +Fn + Page Down | Turbo on +Fn + Right | Toggle LCD font +Fn + End | External CRT display +Fn + SysRQ | Toggle window + +`[2]` Amstrad MegaPC (386SX): The original machine had a built-in Sega MegaDrive. This is not emulated in PCem. + +`[3]` IBM PS/2 Model 70 (type 4) (486DX): PCem's FPU emulation is not bit accurate and can not pass IBM's floating point tests. As a result, this machine will always print 12903 and 162 errors on bootup. These can be ignored - F1 will boot the machine. + +`[4]` Intel Advanced/EV (Endeavor) (Pentium): The real board has a Sound Blaster 16 onboard and optionally an S3 Trio64V+. Neither are emulated as onboard devices. + +`[5]` Some systems have fixed graphics adapters:
+** = Can use external video card. +System | Graphics | Addl. Info | ** +--- | --- | --- | :-: +Amstrad MegaPC | Paradise 90C11 | A development of the PVGA1 with 512KB VRAM | ✔ +Acer 386SX/25N | Oak OTI-067 | Another 512KB SVGA clone | ✔ +Amstrad PC1512 | CGA | Has a new mode (640x200x16) | X +Amstrad PC1640 | Paradise EGA |   | ✔ +Amstrad PC2086/PC3086 | Paradise PVGA1 | An early SVGA clone with 256KB VRAM | ✔ +Amstrad PPC512/640 | CGA/MDA | Outputs to 640x200 plasma display | ✔ +Commodore SL386SX-25 | AVGA2 | 256KB - 512KB VRAM | X +Elonex PC-425X | Trident TGUI9400CXi | 512KB VRAM | X +IBM PCjr | CGA | Has various new modes:
160x200 x 16
320x200 x 16
640x200 x 4 | X +IBM PS/1 Model 2011 | Stock VGA | 256KB VRAM | X +IBM PS/1 Model 2121 | Basic (and unknown) SVGA | 256KB VRAM | X +IBM PS/2 machines | Stock VGA | 256KB VRAM | X +Olivetti M24 [[6]](#system-note-6)| CGA | Has double-res text modes + 640x400 mode | X +Packard Bell PB410A | Headland HT-216 |   | ✔ +Packard Bell PB520R | Cirrus Logic GD-5434 |   | ✔ +Packard Bell PB570 | Cirrus Logic GD-5430 |   | ✔ +Sinclair PC200 | CGA | Can output to TV @ 50hz (UK) | ✔ +Tandy 1000 | Clone of PCjr video | Widely supported in 80s games | X +Tandy 1000 SL/2 | Improved Tandy 1000 | Has support for 640x200x16 | X +Toshiba T-series | CGA | Outputs to built-in LCD or plasma display | X + +`[6]` Olivetti M24 (display): I haven't seen a dump of the font ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd as it is 14-line instead of 16-line. + +
+ +## Graphics Cards + +### Basic cards +Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) +--- | --- | --- +MDA (1981) | 80x25 monochrome text | (none) +CGA (1981) | 40x25 and 80x25 text
320x200 in 4 colours
620x200 in 2 colours
Supports composite output for ~16 colours. | (none) +Hercules (1982) | 80x25 monochrome text
720x348 in monochrome | (none) +Plantronics ColorPlus | An enhanced CGA board with support for 320x200x16 and 640x200x4 | (none) +Wyse WY-700 | A CGA-compatible board with support for a 1280x800 mode | (none) +MDSI Genius | Mono portrait board with support for a 728x1008 mode | 8x12.bin +IBM EGA (1984) | Text up to 80x43
Graphics up to 640x350 in 16 colours | ibm_6277356_ega_card_u44_27128.bin +ATI EGA Wonder 800+ | An enhanced EGA-compatible board with support for up to 800x600 in 16 colours | ATI EGA Wonder 800+ N1.00.BIN +Hercules InColor | An enhanced Hercules with a custom 720x350 16 colour mode | (none) + +### Unaccelerated (S)VGA cards +Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) +--- | --- | --- +ATI Korean VGA | ATI-28800 based.
512KB VRAM
Supports up to 8-bit colour
Korean font support | atikorvga.bin
ati_ksc5601.rom +ATI VGA Edge-16 | ATI-18800 based
512KB VRAM
Supports up to 8-bit colour | vgaedge16.vbi +ATI VGA Charger | ATI-28800 based
512KB VRAM
Supports up to 8-bit colour | bios.bin +AVGA2 | Also known as Cirrus Logic GD5402
256KB - 512KB VRAM
Supports up to 8-bit colour | avga2vram.vbi +IBM VGA (1987) | 256KB VRAM
Text up to 80x50
Graphics up to 320x200 in 256 colours or 640x480 in 16 colours | ibm_vga.bin +OAK OTI-037C | 256KB VRAM
Supports up to 8-bit colour | oti037/bios.bin +OAK OTI-067 | 256KB - 512KB VRAM
Supports up to 8-bit colour | oti067/bios.bin +Olivetti GO481 (Paradise PVGA1A) | 256KB VRAM
Supports up to 8-bit colour | oli_go481_lo.bin
oli_go481_hi.bin +Trident 8900D SVGA | 256KB - 1MB VRAM
Supports up to 24-bit colour | trident.bin +Trident TGUI9400CXi | 1MB - 2MB VRAM
Supports up to 24-bit colour | 9440.vbi +Tseng ET4000AX SVGA | 1MB VRAM
Supports up to 8-bit colour | et4000.bin + +### 2D Accelerated SVGA cards +Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) +--- | --- | --- +ATI Graphics Pro Turbo | Mach64GX based
1MB - 4MB VRAM | mach64gx/bios.bin +ATI Video Xpression | Mach64VT2 based
2MB - 4MB VRAM
Has video acceleration | atimach64vt2pci.bin +Cirrus Logic GD-5428 | 1MB - 2MB VRAM | Machspeed_VGA_GUI_2100_VLB.vbi +Cirrus Logic GD-5429 | 1MB - 2MB VRAM | 5429.vbi +Cirrus Logic GD-5430 | 1MB - 2MB VRAM | gd5430/pci.bin +Cirrus Logic GD-5434 [[1]](#graphics-note-1) | 2MB - 4MB VRAM | gd5434.bin +Diamond Stealth 32 SVGA | ET4000/W32p based
1MB - 2MB VRAM | et4000w32.bin +IBM 1MB SVGA Adapter/A | Cirrus Logic GD5428 based
1 MB VRAM
Only supported on PS/2 models | SVGA141.ROM +Number Nine 9FX | S3 Trio64 based
1MB - 2MB VRAM | s3_764.bin +Paradise Bahamas 64 | S3 Vision864 based
1MB - 4MB VRAM | bahamas64.bin +Phoenix S3 Trio32 | S3 Trio32 based
512KB - 2MB VRAM | 86c732p.bin +Phoenix S3 Trio64 | S3 Trio64 based
1MB - 4MB VRAM | 86c764x1.bin +Trident TGUI9440 | 1MB - 2MB VRAM | 9440.vbi + +### 3D Accelerated SVGA cards +Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) +--- | --- | --- +Diamond Stealth 3D 2000 [[2]](#graphics-note-2)| S3 ViRGE/325 based
2MB - 4MB VRAM | s3virge.bin +S3 ViRGE/DX [[3]](#graphics-note-3)| S3 ViRGE/DX based
2MB - 4MB VRAM | 86c375_1.bin + +### 3D only cards +Hardware | Addl. Info +--- | --- +3DFX Voodoo Graphics [[4]](#graphics-note-4)| 3D accelerator. Widely supported in late 90s games. +Obsidian SB50 [[5]](#graphics-note-5)| Voodoo with 2 TMUs +3DFX Voodoo 2 [[6]](#graphics-note-6)| Improved Voodoo Graphics
Higher clocks
2 TMUs
Triangle setup, etc. + +#### Additional Notes +`[1]` Cirrus Logic GD-5434: Real chip also supports 1MB configurations, however this is not currently supported in PCem. + +`[2]` Diamond Stealth 3D 2000: PCem emulates the ViRGE S3D engine in software. This works with most games I tried, but there may be some issues. The Direct3D drivers for the /325 are fairly poor (often showing as missing triangles), so use of the /DX instead is recommended. + +`[3]` S3 ViRGE/DX: The drivers that come with Windows are similar to those for the /325, however better ones do exist (try the 8-21-1997 version). With the correct drivers, many early Direct3D games work okay (if slowly). + +`[4]` 3DFX Voodoo Graphics: PCem emulates this in software. The emulation is a lot faster than in v10 (thanks to a new dynamic recompiler) and should be capable of hitting Voodoo 1 performance on most machines when two render threads are used. As before, the emulated CPU is the bottleneck for most games.

PCem can emulate 6 and 8 MB configurations, but defaults to 4 MB for compatibility. It can also emulate the screen filter present on the original card, though this does at present have a noticeable performance hit.

Almost everything I've tried works okay, with a very few exceptions - Screamer 2 and Rally have serious issues. + +`[5]` Obsidian SB50: Drivers for this are a bit limited - the official drivers don't support 2 TMUs in Direct3D. + +`[6]` 3DFX Voodoo 2: PCem can emulate both 8 and 12 MB configurations. It can also emulate 6 and 10 MB configurations (with 2MB framebuffer memory), which were never sold into the PC market but do exist for arcade systems. + +
+ +## Sound Cards + +Hardware | Notes +--- | --- +PC speaker | The standard beeper on all PCs. Supports samples/RealSound. +Tandy PSG | The Texas Instruments chip in the PCjr and Tandy 1000. Supports 3 voices plus noise. I reused the emulator in B-em for this (slightly modified). PCem emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 (currently assigned to the Tandy 1000HX). Maniac Mansion and Zak McKraken will only sound correct on the latter. +Tandy PSSJ | Used on the Tandy 1000SL/2, this clones the NCR8496, adding an addition frequency divider (did any software actually use this?) and an 8-bit DAC. +PS/1 audio card | An SN76496 clone plus an 8-bit DAC. The SN76496 isn't at the same address as PCjr/Tandy, so most software doesn't support it. +Gameblaster | The Creative Labs Gameblaster/Creative Music System, Creative's first sound card introduced in 1987. Has two Philips SAA1099, giving 12 voices of square waves plus 4 noise voices. In stereo! +Adlib | Has a Yamaha YM3812, giving 9 voices of 2 op FM, or 6 voices plus a rhythm section. PCem uses the DOSBox dbopl emulator. +Adlib Gold | OPL3 with YM318Z 12-bit digital section. Possibly some bugs (not a lot of software to test). The surround module is now emulated. +Sound Blaster [[1]](#sound-note-1) | See linked note for more details. +Gravis Ultrasound | 32 voice sample playback. Port address is fixed to 240, IRQ and DMA can be changed from the drivers. Emulation is improved significantly over previous versions. +Windows Sound System | 16-bit digital + OPL3. Note that this only emulates WSS itself, and should not be used with drivers from compatible boards with additional components (eg Turtle Beach Monte Carlo) +Aztech Sound Galaxy Pro 16 AB (Washington) | SB compatible + WSS compatible +Innovation SSI-2001 | SID6581. Emulated using resid-fp. Board is fixed to port 280. +Ensoniq AudioPCI (ES1371)
Sound Blaster PCI 128
| Basic PCI sound card. Emulates Sound Blaster in software. + +### Additional Notes +`[1]` Sound Blaster: Several Sound Blasters are emulated. +* SB v1.0 - The original. Limited to 22khz, and no auto-init DMA (can cause crackles sometimes). +* SB v1.5 - Adds auto-init DMA +* SB v2.0 - Upped to 41khz +* SB Pro v1.0 - Stereo with twin OPL2 chips. +* SB Pro v2.0 - Stereo with OPL 3 chip +* SB 16 - 16 bit stereo +* SB AWE32 - SB 16 + wavetable MIDI. This requires a ROM dump from a real AWE32. + +All cards are set to Address 220, IRQ 7 and DMA 1 (and High DMA 5). IRQ and DMA can be changed for the SB16 & AWE32 in the drivers. The relevant SET line for autoexec.bat is `SET BLASTER = A220 I7 D1 Tx` - where Tx is T1 for SB v1.0, T3 for SB v2.0, T4 for SB Pro, and T6 for SB16. + +AWE32 requires a ROM dump called `awe32.raw`. AWE-DUMP is a utility which can get a dump from a real card. Most EMU8000 functionality should work, however filters are not correct and reverb/chorus effects are not currently emulated. + +
+ +## HDD Controller Cards + +Int. | Hardware | Notes | ROM file needed
(within ./roms/ folder) +:-: | --- | --- | ---- +MFM | Fixed Disk Adapter (Xebec) | MFM controller originally included in the IBM XT. This controller only supports HD types 0, 2, 13, and 16. | ibm_xebec_62x0822_1985.bin +MFM | DTC 5150X | 8-bit MFM controller.
To configure drive types, run `DEBUG.EXE` and enter `g=c800:5`. | dtc_cxd21a.bin +MFM | AT Fixed Disk Adapter | MFM controller originally included in the IBM AT. Supported by all AT-compatible BIOSes. | (none) +ESDI | Western Digital WD1007V-SE1 | 16-bit ESDI controller | 62-000279-061.bin +ESDI | IBM ESDI Fixed Disk Controller | MCA ESDI controller. Only supported on PS/2 models. | 90x8969.bin
90x8970.bin +IDE | Standard IDE | Standard IDE controller. Supported by all AT-compatible BIOSes. Use this if in any doubt! | (none) +IDE | XTIDE | 8-bit IDE controller. The BIOS is available [here](http://code.google.com/p/xtideuniversalbios/).
v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues. | ide_xt.bin +IDE | XTIDE (AT) | 16-bit IDE controller. | ide_at.bin +IDE | XTIDE (PS/1) | IDE controller for the PS/1 model 2033. For this machine you will need BIOS version v1.1.5. The PS/1 is a bit fussy with XTIDE, and I've found that it works best when the XTIDE configuration has 'Full Operating Mode' disabled. | ide_at_1_1_5.bin +SCSI | Longshine LCS-6821N | 8-bit SCSI controller. | Longshine LCS-6821N - BIOS version 1.04.bin +SCSI | Rancho RT1000B | 8-bit SCSI controller. | Rancho_RT1000_RTBios_version_8.10R.bin +SCSI | Trantor T130B | 8-bit SCSI controller. | trantor_t130b_bios_v2.14.bin +SCSI | IBM SCSI Adapter with Cache | MCA SCSI controller. Only supported on PS/2 models. | 92F2244.U68
92F2245.U69 +SCSI | Adaptec AHA-1542C | 16-bit SCSI controller. | adaptec_aha1542c_bios_534201-00.bin +SCSI | BusLogic BT-545S | 16-bit SCSI controller. | BusLogic_BT-545S_U15_27128_5002026-4.50.bin + +
+ +## Misc Cards + +Hardware | Note +--- | --- +Serial mouse | A Microsoft compatible serial mouse on COM1. Compatible drivers are all over the place for this. +M24 mouse | I haven't seen a DOS mouse driver for this yet but the regular scancode mode works as does the Windows 1.x driver. +PC1512 mouse | The PC1512's perculiar quadrature mouse. You need Amstrad's actual driver for this one. +PS/2 mouse | A standard 2 button PS/2 mouse. As with serial, compatible drivers are common. +Microsoft PS/2 Intellimouse | A PS/2 mouse with mouse wheel. +ATAPI CD-ROM | Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've tried. From e8e0cf453c455df47dd17ca7a59cfb6f543d3434 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 26 Nov 2020 18:26:23 +0000 Subject: [PATCH 0996/1050] Add TESTED.md --- TESTED.md | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 346 insertions(+) create mode 100644 TESTED.md diff --git a/TESTED.md b/TESTED.md new file mode 100644 index 0000000..44d452e --- /dev/null +++ b/TESTED.md @@ -0,0 +1,346 @@ +## Software tested (v16): + +### DOS +- PC-DOS 1.0 +- PC-DOS 2.10 +- PC-DOS 3.30 +- MS-DOS 3.30 +- MS-DOS 3.31 +- PC-DOS 4.0 +- MS-DOS 4.01 +- PC-DOS 5.02 +- MS-DOS 6.22 + +### Windows +- Windows 1.03 +- Windows 2.03 +- Windows/286 2.11 +- Windows/386 2.11 +- Windows 3.0 +- Windows 3.1 +- Windows for Workgroups 3.11 +- Windows 95 +- Windows 95 OSR2 +- Windows 98SE +- Windows ME + +### Windows NT +- Windows NT 3.1 +- Windows NT 3.51 +- Windows NT 4 Workstation (SP6a) +- Windows 2000 +- Windows XP + +### OS/2 +- OS/2 v1.0 +- OS/2 v1.1 +- OS/2 v1.2 +- OS/2 v1.3 +- OS/2 v2.1 +- OS/2 Warp 3 +- OS/2 Warp 4 + +### Linux +- Corel Linux 1.2 +- Red Hat Linux 7.1 (Seawolf) +- SuSE Linux 6.3 +- Ubuntu 6.06.1 + +### BeOS +- BeOS 5.0 Personal Edition +- BeOS 5.0 Professional Edition + +### Applications +- CorelDRAW! v2.5 for OS/2 +- Cubasis +- Fasttracker 2.08 +- Lotus SmartSuite 97 +- Microsoft Office 95 +- Microsoft Word 1.1 for OS/2 +- Microsoft Word 1.1 for Windows +- Microsoft Word 2.0 +- Microsoft Word 6.1 +- Microsoft Works for Windows 3.0 +- Mozilla Firefox 1.5.0.5 +- Visual Basic 4.0 +- Winzip 6.2 + +### Games +- 3-Demon +- Abuse +- Abuse (demo) +- Actua Soccer +- Age of Empires +- Aladdin +- Aladdin (demo) +- Alien Breed : Tower Assault (demo) +- Alien Carnage (shareware) +- Alien vs Predator +- All New World of Lemmings +- American McGee's Alice +- Apache (demo) +- Atomic Bomberman +- Backtrack (demo) +- Balls of Steel (demo) +- Battlezone +- Battlezone (1998) +- Battlezone II +- Big Red Racing +- Bio Menace (shareware) +- Blackthorne (demo) +- Blake Stone (shareware) +- Blast Doors +- Blood (demo) +- Blood 2 +- Breakneck +- Brix (shareware) +- Bust-a-Move 2 : Arcade Edition +- Cannon Fodder 2 +- Caesar III +- Captain Claw +- Carmageddon +- Carnivores 2 +- Catacomb Abyss (demo) +- Carmageddon (demo) +- CD-MAN +- Charlie the Duck (demo) +- Clusterball +- Colin McRae Rally +- Colonization +- Command and Conquer (demo) +- Command and Conquer : Red Alert +- Commander Keen : Goodbye Galaxy +- Commander Keen : Invasion of the Vorticons +- Corridor 7 +- Counter-Strike 2D +- Curse of Monkey Island +- Cyril Cyberpunk (demo) +- Dark Forces (demo) +- Dark Forces +- Dawn Patrol +- Death Rally +- Descent (v1.4) +- Descent (demo) +- Desert Strike +- Destruction Derby +- Destruction Derby (demo) +- Deus Ex +- Diablo +- Digger +- Discworld II +- Dogz +- Doom (v1.2) +- Doom (shareware) +- Doom II (v1.666) +- Doom II for Windows 95 +- Dune +- Dune II +- Duke Nukem (shareware) +- Duke Nukem 3D (shareware) +- DX-Ball 2 +- Earthworm Jim (demo) +- Ecstatica +- Epic Pinball +- Epic Pinball (shareware) +- Eradicator +- Expendable +- Expendable (demo) +- Extreme Assault +- Final Fantasy VII +- Flashback (demo) +- Frogger +- Frogger (1998) +- Frontier : First Encounters +- Full Throttle (demo) +- G-Police +- Galactix +- GLQuake (v0.93) +- Gods (demo) +- Grand Theft Auto +- Grand Theft Auto 2 +- Grim Fandango +- Half-Life (1.0.0.9) +- Heartlight (shareware) +- Heretic +- Heretic (demo) +- Hexen +- Hexen (demo) +- Hexen95 +- Hocus Pocus (shareware) +- House of the Dead 2 +- Hover! +- Incoming +- Indiana Jones and the Fate of Atlantis (demo) +- Indy Car Racing 2 (demo) +- Interstate 76 Nitro Riders +- Interstate 82 +- Jazz Jackrabbit (shareware) +- Jazz Jackrabbit 2 +- Jedi Knight +- Jumpman +- Kings Quest +- Kings Quest II +- Lamborghini American Challenge (demo) +- LBA 2 +- Lemmings +- Lemmings (demo) +- Lemmings 2 : The Tribes +- Lemmings Paintball +- Lotus III +- Mageslayer +- Magic Carpet +- MDK +- MegaMan X (demo) +- Metal Gear Solid +- Microsoft Arcade +- Monster Bash (shareware) +- Mortal Kombat +- Mortal Kombat II +- Mortal Kombat Trilogy +- Moto Racer +- NASCAR Heat +- NBA Hangtime +- Need for Speed (demo) +- Need for Speed II SE +- Need for Speed III +- Nerf Arena Blast +- Network Q RAC Rally +- No One Lives Forever +- No One Lives Forever (tech demo) +- Oddworld : Abe's Oddysee +- Out of this World (demo) +- Panzer Dragoon +- Pinball Fantasies +- Pinball Illusions +- Populous : The Beginning +- Prince of Persia (demo) +- Prince of Persia 2 (demo) +- Pro Pinball : Big Race USA +- Pro Pinball : Timeshock! +- Pro Pinball : The Web +- Project X (demo) +- Psycho Pinball +- Quake (v1.01) +- Quake (shareware) +- Quake II +- Quake III Arena (1.27g) +- Quake III Arena (1.30) +- Radix (demo) +- Railroad Tycoon II (demo) +- Raptor (shareware) +- Rayman +- Realms of Chaos (shareware) +- Red Faction +- Resident Evil 2 +- Return to Castle Wolfenstein (v1.32) +- Rise of the Triad (shareware) +- Road Rash +- Rogue Spear (demo) +- Rollcage (demo) +- Rollercoaster Tycoon +- Sam and Max Hit the Road (demo) +- Screamer +- Screamer 2 (demo) +- Screamer Rally (NOT 3DFX) +- Secret of Monkey Island (demo) +- Serious Sam +- Shadow Warrior (demo) +- Simcity 2000 +- Simcity 2000 (demo) +- Simcity 2000 for OS/2 Warp +- SimCity 3000 +- Simcopter +- Sonic 3 & Knuckles +- Speed Haste (demo) +- Star Trek Voyager : Elite Force +- Stargunner +- Street Racer (demo) +- Streets of Simcity +- Striker 95 +- Super Angelo (demo) +- Superkarts +- Super Street Fighter 2 (demo) +- Syndicate +- Syndicate (demo) +- System Shock +- Tennis Elbow (demo) +- Terminal velocity +- Terminal Velocity (shareware) +- The Adventures of Captain Comic +- The Chaos Engine +- The Chaos Engine (demo) +- The Humans +- The Incredible Machine (demo) +- The Lion King +- The Lion King (demo) +- Thief II +- Theme Hospital +- Theme Hospital (demo) +- Theme Park +- Threat (demo) +- Tie Fighter (demo) +- Tomb Raider +- Tomb Raider (demo) +- Tomb Raider II +- Tomb Raider III +- Tony Hawk's Pro Skater 2 +- Transport Tycoon +- Transport Tycoon Deluxe +- Turok (demo) +- Tyrian +- Tyrian (shareware) +- UFO : Enemy Unknown +- Ultimate Doom (v1.9) +- Unreal +- Unreal Gold +- Unreal Tournament +- Unreal Tournament (v436 GOTY) +- Virtual Pool (demo) +- Wacky Wheels +- Warcraft (demo) +- Warcraft II (demo) +- Wing Commander +- Wolfenstein 3D (v1.4) +- Wolfenstein 3D (shareware) +- World Cup 98 +- Worms +- Worms (demo) +- Worms 2 +- Worms World Party +- X-Com : Terror From The Deep +- X-Wing +- Z (demo) +- Z.A.R. (demo) +- Zone 66 +- Zone 66 (shareware) + +### Demos +- Cascada - Cronologia +- Complex - Cyboman 2 +- EMF - Verses +- Exceed - Heaven 7 +- Future Crew - Second Reality +- Gazebo - Cyboman! +- KFMF - Dance, Move, Shake +- KFMF - Trip +- Logic Design - Fashion +- Orange - x14 +- Renaissance - Amnesia +- Skull - Putre Faction +- Tran - Ambience +- Tran - Luminati +- Tran - Timeless +- Triton - Crystal Dream II +- Triton - Crystal Dream +- Ultraforce - Coldcut +- Ultraforce - Vector Demo + +### Emulators +- BeebInC v0.99f +- Fellow v0.3.3 +- KGen98 v0.4 +- PaCifiST v0.45 +- SNES9x v0.96 +- UltraHLE v1.0.0 +- vMac v0.1.9.1 +- ZSNES v0.800c \ No newline at end of file From 97dd2aa4bfa00debf25d8ae63a4ab0e89a2d7a4a Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 26 Nov 2020 20:52:50 +0000 Subject: [PATCH 0997/1050] Implement Banshee/V3 line stippling, including previously missing registers. Fixes Lotus Smartsuite 97 installation. --- src/vid_voodoo_banshee_blitter.c | 93 ++++++++++++++++++++++++++------ src/vid_voodoo_common.h | 7 ++- 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index ab33e76..6bec5b7 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -35,6 +35,7 @@ #define COMMAND_INITIATE (1 << 8) #define COMMAND_INC_X_START (1 << 10) #define COMMAND_INC_Y_START (1 << 11) +#define COMMAND_STIPPLE_LINE (1 << 12) #define COMMAND_PATTERN_MONO (1 << 13) #define COMMAND_DX (1 << 14) #define COMMAND_DY (1 << 15) @@ -220,6 +221,49 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } } +static void PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey) +{ + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) + { + case DST_FORMAT_COL_8_BPP: + { + uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = voodoo->vram[addr]; + + voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t addr = get_addr(voodoo, x*2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; + + *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t addr = get_addr(voodoo, x*3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + + *(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t addr = get_addr(voodoo, x*4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + + *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + } +} + static void update_src_stride(voodoo_t *voodoo) { int bpp; @@ -832,14 +876,23 @@ static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, u } } +static void step_line(voodoo_t *voodoo) +{ + if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt) + { + voodoo->banshee_blt.line_pix_pos = 0; + if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size) + voodoo->banshee_blt.line_bit_pos = 0; + else + voodoo->banshee_blt.line_bit_pos++; + } + else + voodoo->banshee_blt.line_pix_pos++; +} + static void banshee_do_line(voodoo_t *voodoo) { clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.srcY); - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.srcX; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); uint8_t rop = voodoo->banshee_blt.command >> 24; int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); @@ -848,27 +901,28 @@ static void banshee_do_line(voodoo_t *voodoo) int x = voodoo->banshee_blt.srcX; int y = voodoo->banshee_blt.srcY; int error; + uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? + voodoo->banshee_blt.lineStipple : ~0; if (dx > dy) /*X major*/ { error = dx/2; while (x != voodoo->banshee_blt.dstX) { - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); error -= dy; if (error < 0) { error += dx; y += y_inc; - pat_y += y_inc; } x += x_inc; - pat_x += x_inc; + step_line(voodoo); } } else /*Y major*/ @@ -876,21 +930,20 @@ static void banshee_do_line(voodoo_t *voodoo) error = dy/2; while (y != voodoo->banshee_blt.dstY) { - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); error -= dx; if (error < 0) { error += dy; x += x_inc; - pat_x += x_inc; } y += y_inc; - pat_y += y_inc; + step_line(voodoo); } } @@ -1115,6 +1168,16 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) case 0x38: voodoo->banshee_blt.commandExtra = val; // pclog("commandExtra=%08x\n", val); + break; + case 0x3c: + voodoo->banshee_blt.lineStipple = val; + break; + case 0x40: + voodoo->banshee_blt.lineStyle = val; + voodoo->banshee_blt.line_rep_cnt = val & 0xff; + voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f; + voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff; + voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f; break; case 0x44: voodoo->banshee_blt.colorPattern[0] = val; diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index d8ca533..df261af 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -372,6 +372,8 @@ typedef struct voodoo_t uint32_t dstFormat; uint32_t dstSize; uint32_t dstXY; + uint32_t lineStipple; + uint32_t lineStyle; uint32_t rop; uint32_t srcBaseAddr; uint32_t srcFormat; @@ -417,8 +419,11 @@ typedef struct voodoo_t int host_data_count; int host_data_size_src, host_data_size_dest; int src_stride_src, src_stride_dest; - + int src_bpp; + + int line_pix_pos, line_bit_pos; + int line_rep_cnt, line_bit_mask_size; } banshee_blt; struct From 1dbb94e9897af5de8254f1000f433662bb7cdbf9 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 27 Nov 2020 16:27:54 +0000 Subject: [PATCH 0998/1050] Implement true 128k VGA mappings on ET4000 and TVGA cards (the only cards I believe that support them). Fixes Majic 12 - Wish. --- src/vid_et4000.c | 15 +++++++++++++++ src/vid_et4000w32.c | 2 +- src/vid_tvga.c | 9 +++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/vid_et4000.c b/src/vid_et4000.c index 25cb60d..6f2fdf2 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -71,6 +71,21 @@ void et4000_out(uint16_t addr, uint8_t val, void *p) et4000->banking = val; // pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val); return; + + case 0x3cf: + if ((svga->gdcaddr & 15) == 6) + { + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) + { + /*override mask - ET4000 supports linear 128k at A0000*/ + svga->banked_mask = 0x1ffff; + } + return; + } + break; + case 0x3D4: svga->crtcreg = val & 0x3f; return; diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index e8a8e8f..ae748ef 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -337,7 +337,7 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000) case 0x0: case 0x4: case 0x8: case 0xC: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0xffff; + svga->banked_mask = 0x1ffff; break; case 0x1: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); diff --git a/src/vid_tvga.c b/src/vid_tvga.c index 59e11e3..6a42ac4 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -109,6 +109,15 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) case 0x3CF: switch (svga->gdcaddr & 15) { + case 0x6: + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) + { + /*override mask - TVGA supports linear 128k at A0000*/ + svga->banked_mask = 0x1ffff; + } + return; case 0xE: svga->gdcreg[0xe] = val ^ 2; tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf; From fe96629cedb911c1084f18aa77671a1e84a66a2c Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 30 Nov 2020 22:29:03 +0000 Subject: [PATCH 0999/1050] SMI : Fix 'NOTFLAT' status when leaving SMI, set oldcpl on enter/leave. --- src/x86seg.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/x86seg.c b/src/x86seg.c index 6703f8f..c44e807 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -3150,6 +3150,8 @@ void x86_smi_enter(void) stack32 = 0; } + oldcpl = 0; + // pclog("x86_smi_enter\n"); } @@ -3240,14 +3242,16 @@ void x86_smi_leave(void) } } } - if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) + if (!(cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff)) cpu_cur_status |= CPU_STATUS_NOTFLATDS; - if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) + if (!(cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff)) cpu_cur_status |= CPU_STATUS_NOTFLATSS; if (smram_disable) smram_disable(); flushmmucache(); + oldcpl = CPL; + // pclog("x86_smi_leave\n"); } From cd7b41f73a3b4a6f25855f4497b3f4f52aab9dab Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 30 Nov 2020 22:29:51 +0000 Subject: [PATCH 1000/1050] Correct Banshee subsystem ID. --- src/vid_voodoo_banshee.c | 44 +++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 76733ca..18530d9 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -2330,11 +2330,11 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x1a: ret = 0x00; break; case 0x1b: ret = 0x00; break; - /*Undocumented, but Voodoo 3 BIOS checks this*/ - case 0x2c: ret = 0x1a; break; - case 0x2d: ret = 0x12; break; - case 0x2e: ret = (banshee->type == TYPE_V3_3000) ? 0x3a : 0x30; break; - case 0x2f: ret = 0x00; break; + /*Subsystem vendor ID*/ + case 0x2c: ret = banshee->pci_regs[0x2c]; break; + case 0x2d: ret = banshee->pci_regs[0x2d]; break; + case 0x2e: ret = banshee->pci_regs[0x2e]; break; + case 0x2f: ret = banshee->pci_regs[0x2f]; break; case 0x30: ret = banshee->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ case 0x31: ret = 0x00; break; @@ -2639,6 +2639,40 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t ddc_init(); + switch (type) + { + case TYPE_BANSHEE: + if (has_sgram) + { + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x04; + banshee->pci_regs[0x2f] = 0x00; + } + else + { + banshee->pci_regs[0x2c] = 0x02; + banshee->pci_regs[0x2d] = 0x11; + banshee->pci_regs[0x2e] = 0x17; + banshee->pci_regs[0x2f] = 0x10; + } + break; + + case TYPE_V3_2000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x30; + banshee->pci_regs[0x2f] = 0x00; + break; + + case TYPE_V3_3000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x3a; + banshee->pci_regs[0x2f] = 0x00; + break; + } + return banshee; } From 3a7336913d313bf2ec126f56b2d7c161cd0f4e30 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 30 Nov 2020 22:30:12 +0000 Subject: [PATCH 1001/1050] Add some keyboard controller behaviour on Intel Advanced/EV and ZP that fixes SMI hangs on Windows 95 OSR2. --- src/keyboard_at.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index f86cb21..44cb3ec 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -590,6 +590,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.want60 = 1; break; + case 0xba: + if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA) + keyboard_at_adddata(0); + break; + /* T3100e commands not implemented: * 0xB7: Emulate PS/2 keyboard * 0xB8: Emulate AT keyboard */ @@ -620,7 +625,11 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) if (romset == ROM_T3100E) keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; - keyboard_at_adddata(keyboard_at.input_port | 4); + if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA) + keyboard_at_adddata(keyboard_at.input_port | 4 | 0x40); + else + keyboard_at_adddata(keyboard_at.input_port | 4); + keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); break; From 8635bc5184f7f0400036bd1cbeeb805d7494fa4f Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Dec 2020 15:20:49 +0000 Subject: [PATCH 1002/1050] Update README.md with new machines + video cards for v17 --- README.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 74a693b..4b92aa0 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,7 @@ Release | Machine | ROM file needed
(within ./roms/ folder) ### 8086 based Release | Machine | ROM file needed
(within ./roms/ folder) :-: | --- | --- +1984 | Compaq Deskpro
8086 at 8 MHz
128KB - 640KB RAM | deskpro/Compaq - BIOS - Revision J - 106265-002.bin 1984 | Olivetti M24 [[5]](#system-note-5)
8086 at 8 MHz
128KB - 640KB RAM
Built-in enhanced CGA (supports 640x400x2) | olivetti_m24/olivetti_m24_version_1.43_low.bin
olivetti_m24/olivetti_m24_version_1.43_high.bin 1986 | Amstrad PC1512 [[5]](#system-note-5)
8086 at 8 MHz
512KB - 640KB RAM
Enhanced CGA (supports 640x200x16)
Custom mouse port | pc1512/40043.v1
pc1512/40044.v2
pc1512/40078.ic127 1987 | Amstrad PC1640 [[5]](#system-note-5)
8086 at 8 MHz
640KB RAM
Built-in Paradise EGA
Custom mouse port | pc1640/40043.v3
pc1640/40044.v3
pc1640/40100 @@ -109,6 +110,7 @@ Release | Machine | ROM file needed
(within ./roms/ folder) 1989 | Amstrad PC2086 [[5]](#system-note-5)
8086 at 8 MHz
640KB RAM
Built-in VGA | pc2086/40179.ic129
pc2086/40180.ic132
pc2086/40186.ic171 1989 | Tandy 1000SL/2 [[5]](#system-note-5)
8086 at 9.54 MHz
512KB - 768KB RAM
Built-in 16 colour graphics
4 voice sound | tandy1000sl2/8079047.hu1
tandy1000sl2/8079048.hu2 1990 | Amstrad PC3086 [[5]](#system-note-5)
8086 at 8 MHz
640KB RAM
Built-in VGA | pc3086/fc00.bin
pc3086/c000.bin +1991 | Amstrad PC5086
8086 at 8 MHz
640KB RAM | pc5086/sys_rom.bin ### 286 based Release | Machine | ROM file needed
(within ./roms/ folder) @@ -125,7 +127,7 @@ Release | Machine | ROM file needed
(within ./roms/ folder) 1989 | Epson PC AX2e
286 at 12 MHz
256KB - 16MB RAM | epson_pcax2e/EVAX
epson_pcax2e/ODAX 1990 | AMI 286 clone
286 at 8+ MHz
512KB - 16MB RAM | ami286/amic206.bin 1990 | Award 286 clone
286 at 8+ MHz
512KB - 16MB RAM | award286/award.bin -1990? | Dell System 200
286 at 12 MHz
640KB - 16MB RAM | dells200/dell0.bin
dells200/dell1.bin +1990 | Dell System 200
286 at 12 MHz
640KB - 16MB RAM | dells200/dell0.bin
dells200/dell1.bin 1990 | IBM PS/1 Model 2011 [[5]](#system-note-5)
286 at 10 MHz
512KB - 16MB RAM
Built-in VGA
DOS 4.01 + GUI menu system in ROM | ibmps1/f80000.bin ? | Goldstar GDC-212M
286 at 12 MHz
512KB - 4MB RAM | gdc212m/gdc212m_72h.bin ? | GW-286CT GEAR
286 at 8+ MHz
512KB - 16MB RAM | gw286ct/2ctc001.bin @@ -146,10 +148,12 @@ Release | Machine | ROM file needed
(within ./roms/ folder) 1989 | IBM PS/2 Model 55SX
386SX at 16 MHz
1MB - 8MB RAM
Built-in VGA
MCA bus | i8555081/33f8146.zm41
i8555081/33f8145.zm40 1990 | DTK 386SX clone
386SX
512KB - 16MB RAM | dtk386/3cto001.bin 1990 | IBM PS/1 Model 2121 [[5]](#system-note-5)
386SX at 20 MHz
1MB - 16MB RAM
Built-in VGA | ibmps1_2121/fc0000.bin -1992? | Acermate 386SX/25N [[5]](#system-note-5)
386SX at 25 MHz
2MB - 16MB RAM
Built-in Oak SVGA | acer386/acer386.bin
acer386/oti067.bin +1990 | Samsung SPC-6000A
386DX
1MB - 32 MB RAM | spc6000a/3c80.u27
spc6000a/9f80.u26 +1992 | Acermate 386SX/25N [[5]](#system-note-5)
386SX at 25 MHz
2MB - 16MB RAM
Built-in Oak SVGA | acer386/acer386.bin
acer386/oti067.bin 1992 | Amstrad MegaPC [[2]](#system-note-2) [[5]](#system-note-5)
386SX at 25 MHz
1MB - 16MB RAM
Built-in VGA
| megapc/41651-bios lo.u18
megapc/211253-bios hi.u19 1992 | Commodore SL386SX-25 [[5]](#system-note-5)
386SX at 25 MHz
1MB - 16MB RAM
Built-in AVGA2 | cbm_sl386sx25/f000.bin
cbm_sl386sx25/c000.bin 1992 | Packard Bell Legend 300SX
386SX at 16 MHz
1MB - 16MB RAM | pb_l300sx/pb_l300sx.bin +1992 | Samsung SPC-6033P
386SX at 33 MHz
2MB - 12 MB RAM | spc6033p/phoenix.bin
spc6033p/svb6120a_font.rom 1994 | AMI 386DX clone
386DX at 40 MHz
1MB - 32MB RAM | ami386dx/opt495sx.ami 1994 | AMI 386SX clone
386SX at 25 MHz
1MB - 16MB RAM | ami386/ami386.bin 1994 | MR 386DX clone
This is a generic 386DX clone with an MR BIOS | mr386dx/opt495sx.mr @@ -185,6 +189,16 @@ Release | Machine
(+ addl. hardware) | CPU(s) Supported | ROM file needed
FIC VA-503+
1MB - 512MB RAM | AMD K6 at 166-300 MHz
AMD K6-2 at 233-550 MHz
AMD K6-2+ at 450-550 MHz
AMD K6-III at 400-450 MHz
AMD K6-III+ at 400-500 MHz
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT WinChip2 at 200-250 MHz
IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz) | fic_va503p/je4333.bin +### Socket 8 based +Release | Machine
(+ addl. hardware) | CPU(s) Supported | ROM file needed
(within ./roms/ folder) +:-: | --- | --- | --- +1996 | Intel VS440FX
8MB - 256 MB RAM | Pentium Pro at 150-200 MHz
Pentium II Overdrive at 300-333 MHz | vs440fx/1018CS1_.BI1
vs440fx/1018CS1_.BI2
vs440fx/1018CS1_.BI3
vs440fx/1018CS1_.BIO
vs440fx/1018CS1_.RCV + +### Slot 1 based +Release | Machine
(+ addl. hardware) | CPU(s) Supported | ROM file needed
(within ./roms/ folder) +:-: | --- | --- | --- +1998 | Gigabyte GA-686BX
8MB - 512MB RAM | Pentium II at 233-450 MHz
Celeron at 266-533 MHz
Cyrix IIIat 500 MHz | ga686bx/6BX.F2a + #### Additional Notes `[1]` Toshiba Button Mapping: PCem maps [Fn] to `right-Ctrl` and `right-Alt`. The following functions are supported: @@ -255,11 +269,14 @@ Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) ATI VGA Charger | ATI-28800 based
512KB VRAM
Supports up to 8-bit colour | bios.bin AVGA2 | Also known as Cirrus Logic GD5402
256KB - 512KB VRAM
Supports up to 8-bit colour | avga2vram.vbi IBM VGA (1987) | 256KB VRAM
Text up to 80x50
Graphics up to 320x200 in 256 colours or 640x480 in 16 colours | ibm_vga.bin +Kasan Hangulmadang-16 | ET4000AX based
1MB VRAM
Supports up to 8-bit colour
Korean font support | et4000_kasan16.bin
kasan_ksc5601.rom OAK OTI-037C | 256KB VRAM
Supports up to 8-bit colour | oti037/bios.bin OAK OTI-067 | 256KB - 512KB VRAM
Supports up to 8-bit colour | oti067/bios.bin Olivetti GO481 (Paradise PVGA1A) | 256KB VRAM
Supports up to 8-bit colour | oli_go481_lo.bin
oli_go481_hi.bin Trident 8900D SVGA | 256KB - 1MB VRAM
Supports up to 24-bit colour | trident.bin +Trident 9000B SVGA | 512KB VRAM
Supports up to 8-bit colour | tvga9000b/BIOS.BIN Trident TGUI9400CXi | 1MB - 2MB VRAM
Supports up to 24-bit colour | 9440.vbi +Trigem Korean VGA | ET4000AX based
1MB VRAM
Supports up to 8-bit colour
Korean font support | tgkorvga.bin
tg_ksc5601.rom Tseng ET4000AX SVGA | 1MB VRAM
Supports up to 8-bit colour | et4000.bin ### 2D Accelerated SVGA cards @@ -282,6 +299,10 @@ Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) ### 3D Accelerated SVGA cards Hardware | Addl. Info | ROM file needed
(within ./roms/ folder) --- | --- | --- +3DFX Voodoo Banshee (reference) | Voodoo Banshee based
8MB - 16MB VRAM | pci_sg.rom +3DFX Voodoo 3 2000 | Voodoo 3 based
16MB VRAM | voodoo3_2000/2k11sd.rom +3DFX Voodoo 3 3000 | Voodoo 3 based
16MB VRAM | voodoo3_3000/3k12sd.rom +Creative Labs 3D Blaster Banshee | Voodoo Banshee based
16MB VRAM | blasterpci.rom Diamond Stealth 3D 2000 [[2]](#graphics-note-2)| S3 ViRGE/325 based
2MB - 4MB VRAM | s3virge.bin S3 ViRGE/DX [[3]](#graphics-note-3)| S3 ViRGE/DX based
2MB - 4MB VRAM | 86c375_1.bin From 4adb34078d32fd8c827b2532e6097f9e5561b494 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Dec 2020 15:21:44 +0000 Subject: [PATCH 1003/1050] Implement non-poly lines in Banshee/V3 blitter. --- src/vid_voodoo_banshee_blitter.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index 6bec5b7..ac35fbb 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -890,7 +890,7 @@ static void step_line(voodoo_t *voodoo) voodoo->banshee_blt.line_pix_pos++; } -static void banshee_do_line(voodoo_t *voodoo) +static void banshee_do_line(voodoo_t *voodoo, int draw_last_pixel) { clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; uint8_t rop = voodoo->banshee_blt.command >> 24; @@ -947,6 +947,15 @@ static void banshee_do_line(voodoo_t *voodoo) } } + if (draw_last_pixel) + { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + } + voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16); voodoo->banshee_blt.srcX = x; voodoo->banshee_blt.srcY = y; @@ -1084,8 +1093,12 @@ static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) banshee_do_rectfill(voodoo); break; + case COMMAND_CMD_LINE: + banshee_do_line(voodoo, 1); + break; + case COMMAND_CMD_POLYLINE: - banshee_do_line(voodoo); + banshee_do_line(voodoo, 0); break; default: @@ -1358,18 +1371,18 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) banshee_do_rectfill(voodoo); break; -/* case COMMAND_CMD_LINE: + case COMMAND_CMD_LINE: voodoo->banshee_blt.dstXY = val; voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_line(voodoo); - break;*/ + banshee_do_line(voodoo, 1); + break; case COMMAND_CMD_POLYLINE: voodoo->banshee_blt.dstXY = val; voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_line(voodoo); + banshee_do_line(voodoo, 0); break; case COMMAND_CMD_POLYFILL: From e27e37179f41d689860081d992c02d0e3793ecf1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Dec 2020 16:04:19 +0000 Subject: [PATCH 1004/1050] Guard fatal()s in Banshee/V3 code in !RELEASE_BUILD --- src/vid_voodoo_banshee.c | 12 ++++++++---- src/vid_voodoo_banshee_blitter.c | 9 ++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 18530d9..2ac803e 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -408,8 +408,11 @@ static void banshee_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; svga->bpp = 32; break; + +#ifndef RELEASE_BUILD default: fatal("Unknown pixel format %08x\n", banshee->vgaInit0); +#endif } svga->rowcount = 0; if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) @@ -967,9 +970,11 @@ static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) case 0x108: break; - + +#ifndef RELEASE_BUILD default: fatal("Unknown banshee_cmd_read %08x\n", addr); +#endif } return ret; @@ -1239,7 +1244,9 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_userIntrCMD: +#ifndef RELEASE_BUILD fatal("userIntrCMD write %08x\n", val); +#endif break; case SST_swapbufferCMD: @@ -1805,9 +1812,6 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) else \ DECODE_RGB565(buf); \ break; \ - \ - default: \ - fatal("Unknown overlay pix fmt %i\n", banshee->overlay_pix_fmt); \ } \ } while (0) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index ac35fbb..f6f0d03 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -563,9 +563,10 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x src_data = *(uint32_t *)&src_p[src_x_real]; break; } - +#ifndef RELEASE_BUILD default: fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); +#endif } if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && @@ -1101,8 +1102,10 @@ static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) banshee_do_line(voodoo, 0); break; +#ifndef RELEASE_BUILD default: fatal("banshee_do_2d_blit: unknown command=%08x\n", voodoo->banshee_blt.command); +#endif } } @@ -1389,8 +1392,10 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) banshee_polyfill_continue(voodoo, val); break; +#ifndef RELEASE_BUILD default: fatal("launch area write, command=%08x\n", voodoo->banshee_blt.command); +#endif } break; @@ -1437,7 +1442,9 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) // pclog("colorPattern%02x=%08x\n", (addr >> 2) & 63, val); break; +#ifndef RELEASE_BUILD default: fatal("Unknown 2D reg write %03x %08x\n", addr & 0x1fc, val); +#endif } } From df1d53c75c21b81ad576cef7e6be2348c9c06a52 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Dec 2020 17:26:41 +0000 Subject: [PATCH 1005/1050] Add missing break in switch in et4000_kasan_out(). Patch from Greatpsycho. --- src/vid_et4000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vid_et4000.c b/src/vid_et4000.c index 6f2fdf2..ee30098 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -209,6 +209,7 @@ void et4000_kasan_out(uint16_t addr, uint8_t val, void *p) case 5: et4000->kasan_cfg_regs[5] = val; et4000->svga.ksc5601_english_font_type = 0x100 | val; + break; case 6: case 7: et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; From ad6b1406e814e61e9f1e198025bc951e11dd93a0 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Dec 2020 19:47:00 +0000 Subject: [PATCH 1006/1050] Update version number to v17. --- configure.ac | 2 +- src/pc.c | 2 +- src/pc.xrc | 2 +- src/wx-resources.cpp | 2 +- src/wx-sdl2-display-win.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index baf37d8..407b057 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # AC_PREREQ([2.61]) -AC_INIT(PCem, v16, Sarah Walker , pcem) +AC_INIT(PCem, v17, Sarah Walker , pcem) AC_CANONICAL_HOST diff --git a/src/pc.c b/src/pc.c index 49c43af..6ed0be9 100644 --- a/src/pc.c +++ b/src/pc.c @@ -584,7 +584,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v16 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem v17 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); set_window_title(s); } done++; diff --git a/src/pc.xrc b/src/pc.xrc index 400842d..88e234c 100644 --- a/src/pc.xrc +++ b/src/pc.xrc @@ -3683,7 +3683,7 @@ wxALL 5 - + -1
diff --git a/src/wx-resources.cpp b/src/wx-resources.cpp index 6d1fa79..68deac3 100644 --- a/src/wx-resources.cpp +++ b/src/wx-resources.cpp @@ -8010,7 +8010,7 @@ static unsigned char xml_res_file_26[] = { 47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, 106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, 84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, -101,108,62,80,67,101,109,32,118,49,52,92,110,104,116,116,112,115,58,47, +101,108,62,80,67,101,109,32,118,49,55,92,110,104,116,116,112,115,58,47, 47,112,99,101,109,45,101,109,117,108,97,116,111,114,46,99,111,46,117,107, 47,92,110,92,110,84,104,105,115,32,112,114,111,103,114,97,109,32,105,115, 32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116,104,101, diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 5ac647a..ba2bdb6 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -595,7 +595,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v16", /* Title Text */ + "PCem v17", /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From 13f53a25687be71ee3ee8482b1a90b1b0aa64fb6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 1 Dec 2020 19:49:05 +0000 Subject: [PATCH 1007/1050] Update documentation for v17. --- README.md | 13 +- Readme-BSD.txt | 31 - Readme-LINUX.txt | 31 - TESTED.md | 410 ++++++------ readme.html | 1467 +++++++++++++++++++++++++++++++++++++++++ readme.txt | 1636 ---------------------------------------------- tested.html | 493 ++++++++++++++ 7 files changed, 2164 insertions(+), 1917 deletions(-) delete mode 100644 Readme-BSD.txt delete mode 100644 Readme-LINUX.txt create mode 100644 readme.html delete mode 100644 readme.txt create mode 100644 tested.html diff --git a/README.md b/README.md index 4b92aa0..134a542 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # [PCem](https://pcem-emulator.co.uk/) -## Download: [Windows](https://pcem-emulator.co.uk/files/PCemV16Win.zip)/[Linux](https://pcem-emulator.co.uk/files/PCemV16Linux.tar.gz) +## Download: [Windows](https://pcem-emulator.co.uk/files/PCemV17Win.zip)/[Linux](https://pcem-emulator.co.uk/files/PCemV17Linux.tar.gz) -Latest version: v16 [Changelog](https://pcem-emulator.co.uk/index.html) +Latest version: v17 [Changelog](https://pcem-emulator.co.uk/index.html) PCem is licensed under GPL v2.0, see [COPYING](COPYING) for more details. -You can submit patches on our [forum](https://pcem-emulator.co.uk/phpBB3/viewforum.php?f=4). Before you do, please note the [guidelines](https://pcem-emulator.co.uk/phpBB3/viewtopic.php?f=3&t=5) for submitting patches. +You can submit patches on our [forum](https://pcem-emulator.co.uk/phpBB3). Before you do, please note the [guidelines](https://pcem-emulator.co.uk/phpBB3/viewtopic.php?f=3&t=5) for submitting patches. :exclamation: Note: NO COPYRIGHTED ROM FILES ARE INCLUDED NOR WILL THEY BE. PLEASE DO NOT ASK FOR THEM. -## BSD and Linux supplement (v16) +## BSD and Linux supplement (v17) You will need the following libraries (and their dependencies): - SDL2 @@ -47,7 +47,7 @@ CD-ROM support currently only accesses `/dev/cdrom`. It has not been heavily tes ## Links -### PCem emulates the following hardware (as of v16): +### PCem emulates the following hardware (as of v17): Hardware | Links --- | --- @@ -218,7 +218,8 @@ Fn + SysRQ | Toggle window `[4]` Intel Advanced/EV (Endeavor) (Pentium): The real board has a Sound Blaster 16 onboard and optionally an S3 Trio64V+. Neither are emulated as onboard devices. `[5]` Some systems have fixed graphics adapters:
-** = Can use external video card. +** = Can use external video card.
+ System | Graphics | Addl. Info | ** --- | --- | --- | :-: Amstrad MegaPC | Paradise 90C11 | A development of the PVGA1 with 512KB VRAM | ✔ diff --git a/Readme-BSD.txt b/Readme-BSD.txt deleted file mode 100644 index e100c85..0000000 --- a/Readme-BSD.txt +++ /dev/null @@ -1,31 +0,0 @@ -PCem v16 BSD supplement - - -You will need the following libraries : - -SDL2 -wxWidgets 3.x -OpenAL - -and their dependencies. - -Open a terminal window, navigate to the PCem directory then enter - -./configure --enable-release-build -gmake - -then ./pcem to run. - -The BSD version stores BIOS ROM images, configuration files, and other data in ~/.pcem - -configure options are : - --enable-release-build : Generate release build. Recommended for regular use. - --enable-debug : Compile with debugging enabled. - --enable-networking : Build with networking support. - --enable-alsa : Build with support for MIDI output through ALSA. Requires libasound. - - -The menu is a pop-up menu in the BSD port. Right-click on the main window when mouse is not -captured. - -CD-ROM support currently only accesses /dev/cdrom. It has not been heavily tested. diff --git a/Readme-LINUX.txt b/Readme-LINUX.txt deleted file mode 100644 index 766db70..0000000 --- a/Readme-LINUX.txt +++ /dev/null @@ -1,31 +0,0 @@ -PCem v16 Linux supplement - - -You will need the following libraries : - -SDL2 -wxWidgets 3.x -OpenAL - -and their dependencies. - -Open a terminal window, navigate to the PCem directory then enter - -./configure --enable-release -make - -then ./pcem to run. - -The Linux version stores BIOS ROM images, configuration files, and other data in ~/.pcem - -configure options are : - --enable-release-build : Generate release build. Recommended for regular use. - --enable-debug : Compile with debugging enabled. - --enable-networking : Build with networking support. - --enable-alsa : Build with support for MIDI output through ALSA. Requires libasound. - - -The menu is a pop-up menu in the Linux port. Right-click on the main window when mouse is not -captured. - -CD-ROM support currently only accesses /dev/cdrom. It has not been heavily tested. diff --git a/TESTED.md b/TESTED.md index 44d452e..d7ae6e5 100644 --- a/TESTED.md +++ b/TESTED.md @@ -1,19 +1,16 @@ -## Software tested (v16): +## Software tested (v17): ### DOS - PC-DOS 1.0 -- PC-DOS 2.10 -- PC-DOS 3.30 +- MS-DOS 2.11 - MS-DOS 3.30 -- MS-DOS 3.31 -- PC-DOS 4.0 - MS-DOS 4.01 -- PC-DOS 5.02 +- MS-DOS 5.0 +- MS-DOS 6.0 - MS-DOS 6.22 ### Windows -- Windows 1.03 -- Windows 2.03 +- Windows 1.04 - Windows/286 2.11 - Windows/386 2.11 - Windows 3.0 @@ -42,305 +39,292 @@ ### Linux - Corel Linux 1.2 +- Mandriva LE 2005 - Red Hat Linux 7.1 (Seawolf) -- SuSE Linux 6.3 -- Ubuntu 6.06.1 ### BeOS -- BeOS 5.0 Personal Edition - BeOS 5.0 Professional Edition ### Applications -- CorelDRAW! v2.5 for OS/2 +- 3DMark 2000 +- 3DMark 2001SE +- After Dark 3.06 +- Cinemania 1994 +- Creative Writer - Cubasis -- Fasttracker 2.08 -- Lotus SmartSuite 97 -- Microsoft Office 95 -- Microsoft Word 1.1 for OS/2 -- Microsoft Word 1.1 for Windows -- Microsoft Word 2.0 -- Microsoft Word 6.1 -- Microsoft Works for Windows 3.0 -- Mozilla Firefox 1.5.0.5 -- Visual Basic 4.0 +- Encarta 1994 +- Fasttracker v2.08 +- PageMaker 5.0 +- PC Paintbrush 1.05 +- Photoshop 3.0 +- Smartsuite 97 +- Visual Basic 3.0 +- Visual C++ 6.0 +- Word for Windows 2.0 - Winzip 6.2 ### Games -- 3-Demon -- Abuse -- Abuse (demo) +- 1602 AD (demo) +- 3D Ultra Pinball Thrillride +- A-10 Tank Killer - Actua Soccer -- Age of Empires +- Adventure Pinball Forgotten Island (demo) - Aladdin -- Aladdin (demo) -- Alien Breed : Tower Assault (demo) -- Alien Carnage (shareware) - Alien vs Predator +- Alien vs Predator 2 (demo) - All New World of Lemmings -- American McGee's Alice -- Apache (demo) -- Atomic Bomberman -- Backtrack (demo) -- Balls of Steel (demo) +- Alone in the Dark +- Alone in the Dark : The New Nightmare (demo) +- Anachronox +- Arkanoid +- Armoured Fist 3 (demo) +- Asteroids (1998) +- B-17 Flying Fortress +- Battle Chess - Battlezone -- Battlezone (1998) - Battlezone II +- Bejeweled +- Beyond Castle Wolfenstein - Big Red Racing -- Bio Menace (shareware) -- Blackthorne (demo) -- Blake Stone (shareware) -- Blast Doors -- Blood (demo) -- Blood 2 -- Breakneck -- Brix (shareware) -- Bust-a-Move 2 : Arcade Edition +- Bio Menace +- Black & White +- Brix +- Bugs Bunny Lost In Time (demo) - Cannon Fodder 2 -- Caesar III -- Captain Claw -- Carmageddon - Carnivores 2 -- Catacomb Abyss (demo) -- Carmageddon (demo) -- CD-MAN -- Charlie the Duck (demo) -- Clusterball -- Colin McRae Rally -- Colonization -- Command and Conquer (demo) -- Command and Conquer : Red Alert -- Commander Keen : Goodbye Galaxy -- Commander Keen : Invasion of the Vorticons +- Civilization +- Civilization for Windows +- Claw +- Clive Barker's Undying (demo) +- Clockwiser +- Command & Conquer : Red Alert +- Command & Conquer : Red Alert 2 +- Command & Conquer : Tiberian Sun (demo) +- Command & Conquer Renegade +- Conquest - Corridor 7 - Counter-Strike 2D +- Crimson Skies (demo) +- Croc - Curse of Monkey Island -- Cyril Cyberpunk (demo) -- Dark Forces (demo) -- Dark Forces +- Cutthroats (demo) +- Daikatana - Dawn Patrol -- Death Rally -- Descent (v1.4) -- Descent (demo) +- Day of the Tentacle +- Dance Dance Revolution +- Dead Reckoning (demo) +- Death Drome - Desert Strike -- Destruction Derby -- Destruction Derby (demo) -- Deus Ex -- Diablo - Digger +- Dirt Track Racing (demo) +- Disciples (demo) - Discworld II -- Dogz - Doom (v1.2) -- Doom (shareware) - Doom II (v1.666) -- Doom II for Windows 95 +- Double Dragon +- Drakan (demo) +- Duke Nukem 3D (v1.3D) - Dune -- Dune II -- Duke Nukem (shareware) -- Duke Nukem 3D (shareware) - DX-Ball 2 -- Earthworm Jim (demo) +- Echelon - Ecstatica - Epic Pinball -- Epic Pinball (shareware) -- Eradicator +- Every Extend +- Evolva (demo) - Expendable -- Expendable (demo) -- Extreme Assault -- Final Fantasy VII -- Flashback (demo) +- Eye of the Beholder +- Fallout Tactics (demo) +- Final Fantasy VIII (demo) +- Flashback +- Flight Simulator 5 - Frogger -- Frogger (1998) - Frontier : First Encounters -- Full Throttle (demo) -- G-Police -- Galactix -- GLQuake (v0.93) -- Gods (demo) -- Grand Theft Auto +- Gabriel Knight 3 (demo) +- Giants : Citizen Kabuto +- GLQuake - Grand Theft Auto 2 -- Grim Fandango -- Half-Life (1.0.0.9) -- Heartlight (shareware) -- Heretic -- Heretic (demo) +- Half-Life +- Halloween Harry +- Heartlight +- Hellbender - Hexen -- Hexen (demo) -- Hexen95 -- Hocus Pocus (shareware) -- House of the Dead 2 -- Hover! +- High Heat Baseball 2002 (demo) +- Hitch Hiker's Guide to the Galaxy +- Hocus Pocus +- Homeworld Cataclysm (demo) - Incoming -- Indiana Jones and the Fate of Atlantis (demo) -- Indy Car Racing 2 (demo) -- Interstate 76 Nitro Riders -- Interstate 82 -- Jazz Jackrabbit (shareware) +- James Pond 2 : Robocod +- Jazz Jackrabbit - Jazz Jackrabbit 2 -- Jedi Knight -- Jumpman -- Kings Quest -- Kings Quest II -- Lamborghini American Challenge (demo) -- LBA 2 +- Jill of the Jungle +- King's Quest +- King's Quest II +- King's Quest III - Lemmings -- Lemmings (demo) - Lemmings 2 : The Tribes -- Lemmings Paintball +- Lode Runner : The Legend Continues - Lotus III -- Mageslayer -- Magic Carpet -- MDK -- MegaMan X (demo) +- Madden 2002 (demo) +- Majesty (demo) +- Maniac Mansion (enhanced) +- Max Payne +- MDK (Direct3D, USA release) +- MechCommander 2 +- Mechwarrior 2 +- Mechwarrior 3 +- Megaman Legends - Metal Gear Solid - Microsoft Arcade -- Monster Bash (shareware) +- Microsoft Golf 99 (demo) +- Midtown Madness 2 (demo) +- Monaco Grand Prix (demo) +- Monkey Island 2 +- Monster Bash +- Monster Truck Madness - Mortal Kombat -- Mortal Kombat II -- Mortal Kombat Trilogy -- Moto Racer -- NASCAR Heat -- NBA Hangtime -- Need for Speed (demo) +- Mortal Kombat 2 +- Mortal Kombat 3 +- Motorcross Madness (demo) +- Mystic Towers +- Nascar Heat - Need for Speed II SE - Need for Speed III -- Nerf Arena Blast -- Network Q RAC Rally +- Need for Speed : High Stakes +- NHL 2001 (demo) - No One Lives Forever -- No One Lives Forever (tech demo) -- Oddworld : Abe's Oddysee -- Out of this World (demo) -- Panzer Dragoon +- Oddworld : Abe's Exoddus +- One Must Fall 2097 +- Oni +- Outlaws +- Pacific Strike +- Pacman Adventures in Time (demo) +- Pharoah (demo) - Pinball Fantasies - Pinball Illusions -- Populous : The Beginning -- Prince of Persia (demo) -- Prince of Persia 2 (demo) -- Pro Pinball : Big Race USA -- Pro Pinball : Timeshock! +- Police Quest +- Police Quest 2 +- Porrasturvat +- Power Drive +- Prince of Persia +- Prince of Persia 3D (demo) - Pro Pinball : The Web -- Project X (demo) - Psycho Pinball -- Quake (v1.01) -- Quake (shareware) +- Quake - Quake II -- Quake III Arena (1.27g) -- Quake III Arena (1.30) -- Radix (demo) -- Railroad Tycoon II (demo) -- Raptor (shareware) -- Rayman -- Realms of Chaos (shareware) +- Quake III Arena +- Rayman 2 (demo) - Red Faction -- Resident Evil 2 -- Return to Castle Wolfenstein (v1.32) -- Rise of the Triad (shareware) -- Road Rash -- Rogue Spear (demo) -- Rollcage (demo) -- Rollercoaster Tycoon -- Sam and Max Hit the Road (demo) +- Redline Racer +- Rise of the Triad (v1.2) - Screamer -- Screamer 2 (demo) -- Screamer Rally (NOT 3DFX) -- Secret of Monkey Island (demo) -- Serious Sam -- Shadow Warrior (demo) -- Simcity 2000 -- Simcity 2000 (demo) -- Simcity 2000 for OS/2 Warp -- SimCity 3000 -- Simcopter -- Sonic 3 & Knuckles -- Speed Haste (demo) -- Star Trek Voyager : Elite Force +- Sega Rally 2 (demo) +- Sensible World of Soccer +- Settlers 3 (demo) +- Severance : Blade of Darkness (demo) +- Shadow Company (demo) +- Shadow Warrior +- Shadowman (demo) +- Sid Meier's Alien Crossfire (demo) +- SimCity 2000 +- SimCity Classic +- SimTower +- Sink or Swim +- Soldat (1.0.5) +- Sonic CD +- Space Simulator +- Space Strike +- Spider-Man (demo) +- Springy Madness +- Star Trek Hidden Evil (demo) +- Star Trek Voyager Elite Force +- Star Wars Jedi Academy +- Starfleet Command 2 (demo) - Stargunner -- Street Racer (demo) -- Streets of Simcity -- Striker 95 -- Super Angelo (demo) -- Superkarts -- Super Street Fighter 2 (demo) +- Starlancer (demo) +- Steel Beasts (demo) +- Stunt Island +- SWAT 3 Elite Edition (demo) - Syndicate -- Syndicate (demo) - System Shock -- Tennis Elbow (demo) -- Terminal velocity -- Terminal Velocity (shareware) -- The Adventures of Captain Comic -- The Chaos Engine -- The Chaos Engine (demo) +- Tanktics (demo) +- Terminal Velocity +- The Dig - The Humans -- The Incredible Machine (demo) -- The Lion King -- The Lion King (demo) -- Thief II +- The Labyrinth (RealArcade version) +- The Lost Vikings +- The Ultimate Doom (v1.9) - Theme Hospital -- Theme Hospital (demo) - Theme Park -- Threat (demo) -- Tie Fighter (demo) - Tomb Raider -- Tomb Raider (demo) - Tomb Raider II -- Tomb Raider III +- Tomb Raider The Last Revelation (demo) - Tony Hawk's Pro Skater 2 - Transport Tycoon - Transport Tycoon Deluxe -- Turok (demo) -- Tyrian -- Tyrian (shareware) +- Tropico (demo) +- Turrican 2 - UFO : Enemy Unknown -- Ultimate Doom (v1.9) +- Ultimate Ride (demo) - Unreal -- Unreal Gold - Unreal Tournament -- Unreal Tournament (v436 GOTY) -- Virtual Pool (demo) +- Unreal Tournament 2004 (Direct3D) - Wacky Wheels -- Warcraft (demo) -- Warcraft II (demo) +- Warlords Battlecry (demo) +- Wheel of Time (demo) - Wing Commander -- Wolfenstein 3D (v1.4) -- Wolfenstein 3D (shareware) -- World Cup 98 +- Wing Commander : Privateer +- Wizkid +- Wolfenstein 3D +- World War III : Black Gold (demo) - Worms -- Worms (demo) -- Worms 2 -- Worms World Party +- Worms Armageddon - X-Com : Terror From The Deep -- X-Wing -- Z (demo) -- Z.A.R. (demo) +- Xargon +- Z : Steel Soldiers (demo) +- Zak McKracken - Zone 66 -- Zone 66 (shareware) ### Demos - Cascada - Cronologia +- Coma - Paimen - Complex - Cyboman 2 +- Complex - Dope - EMF - Verses - Exceed - Heaven 7 - Future Crew - Second Reality -- Gazebo - Cyboman! +- Gazebo - Cyboman +- Halcyon - Lifeforms +- Iguana - Heartquake +- Impact Studios - Legend +- Impact Studios - Project Angel - KFMF - Dance, Move, Shake - KFMF - Trip - Logic Design - Fashion +- Majic 12 - Show +- Majic 12 - Wish +- Megabusters - Hellraiser - Orange - x14 - Renaissance - Amnesia - Skull - Putre Faction -- Tran - Ambience -- Tran - Luminati +- Tran - Ambience (flickery) +- Tran - Luminati (flickery) - Tran - Timeless -- Triton - Crystal Dream II - Triton - Crystal Dream +- Triton - Crystal Dream 2 - Ultraforce - Coldcut - Ultraforce - Vector Demo +- Valhalla - Solstice +- Witan - Witan House ### Emulators +- Beebem v1.02 - BeebInC v0.99f -- Fellow v0.3.3 -- KGen98 v0.4 -- PaCifiST v0.45 +- CPE v5.2i +- DOSBox 0.74-3 +- Fellow 0.33 +- KGen98 v0.4b +- PaCifiST v0.48 - SNES9x v0.96 - UltraHLE v1.0.0 - vMac v0.1.9.1 -- ZSNES v0.800c \ No newline at end of file +- ZSNES v0.800c diff --git a/readme.html b/readme.html new file mode 100644 index 0000000..8694110 --- /dev/null +++ b/readme.html @@ -0,0 +1,1467 @@ + + + + + + + readme + + + + +

PCem

+

Download: Windows/Linux

+

Latest version: v17 Changelog

+

PCem is licensed under GPL v2.0, see COPYING for more details.

+

You can submit patches on our forum. Before you do, please note the guidelines for submitting patches.

+

â— Note: NO COPYRIGHTED ROM FILES ARE INCLUDED NOR WILL THEY BE. PLEASE DO NOT ASK FOR THEM.

+

BSD and Linux supplement (v17)

+

You will need the following libraries (and their dependencies):

+
    +
  • SDL2
  • +
  • wxWidgets 3.x
  • +
  • OpenAL
  • +
+

Open a terminal window, navigate to the PCem directory then enter:

+

Linux

+
./configure --enable-release
+make
+

BSD

+
./configure --enable-release-build
+gmake
+

then ./pcem to run.

+

The Linux/BSD versions store BIOS ROM images, configuration files, and other data in ~/.pcem

+

configure options are :

+
  --enable-release-build : Generate release build. Recommended for regular use.
+  --enable-debug         : Compile with debugging enabled.
+  --enable-networking    : Build with networking support.
+  --enable-alsa          : Build with support for MIDI output through ALSA. Requires libasound.
+

The menu is a pop-up menu in the Linux/BSD port. Right-click on the main window when mouse is not captured.

+

CD-ROM support currently only accesses /dev/cdrom. It has not been heavily tested.

+ +

PCem emulates the following hardware (as of v17):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareLinks
Systems8088
8086
286
386
486
Pentium
Super Socket 7
GraphicsBasic
Unaccelerated (S)VGA cards
2D accelerated SVGA cards
3D accelerated SVGA cards
3D only cards
SoundCards
HDD ControllerCards
MiscCards
+

Software Tested (list)

+ +
+ +

Systems

+

8088 based

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReleaseMachineROM file needed
(within ./roms/ folder)
1981IBM PC
8088 at 4.77 MHz
16KB - 640KB RAM (min. 64KB)
ibmpc/pc102782.bin
ibmpc/basicc11.f6
ibmpc/basicc11.f8
ibmpc/basicc11.fa
ibmpc/basicc11.fc
1983Compaq Portable Plus
8088 at 4.77 MHz
128KB - 640KB RAM
compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin
1983IBM XT
8088 at 4.77 MHz
64KB - 640KB RAM
ibmxt/5000027.u19
ibmxt/1501512.u18
1983Leading Edge Model M
8088 at 7.16 MHz
128KB - 704KB RAM
leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin
1984IBM PCjr [5]
8088 at 4.77 MHz
64KB - 640KB RAM (min. 128KB)
Built-in 16 colour graphics
3 voice sound
Not generally PC compatible.
ibmpcjr/bios.rom
1984Tandy 1000 [5]
8088 at 4.77 MHz
128KB - 640KB RAM
Built-in 16 colour graphics
3 voice sound
tandy/tandy1t1.020
1985NCR PC4i
8088 at 4.77 MHz
256KB - 640KB RAM
ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN
1986DTK Clone XT
8088 at 8/10 MHz
64KB - 640KB RAM
dtk/dtk_erso_2.42_2764.bin
1986Phoenix XT clone
8088 at 8/10 MHz
64KB - 640KB RAM
pxxt/000p001.bin
1987Tandy 1000HX
8088 at 7.16 MHz
256KB - 640KB RAM
Built-in 16 colour graphics
3 voice sound
Has DOS 2.11 in ROM
tandy1000hx/v020000.u12
1987Thomson TO16 PC
8088 at 9.54 MHz
512KB - 640KB RAM
to16_pc/TO16_103.bin
1987Toshiba T1000 [1] [5]
8088 at 4.77 MHz
512KB - 1024KB RAM
CGA on built-in LCD
t1000/t1000.rom
t1000/t1000font.rom
1987VTech Laser Turbo XT
8088 at 10 MHz
640KB RAM
ltxt/27c64.bin
1987Zenith Data SupersPort
8088 at 8 MHz
128KB - 640KB RAM
Built-in LCD video is not currently emulated
zdsupers/z184m v3.1d.10d
1988?©Anonymous Generic Turbo XT BIOS
8088 at 8+ MHz
64KB - 640KB RAM
genxt/pcxt.rom
1988Atari PC3
8088 at 8 MHz
640KB RAM
ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN
1988Juko XT clonejukopc/000o001.bin
1988Schneider Euro PC
8088 at 9.54 MHz
512KB - 640KB RAM
europc/50145
europc/50146
1989AMI XT clone
8088 at 8+ MHz
64KB - 640KB RAM
amixt/ami_8088_bios_31jan89.bin
2015Xi8088
8088 at 4.77-13.33 MHz
640KB RAM
xi8088/bios-xi8088.bin
+

8086 based

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReleaseMachineROM file needed
(within ./roms/ folder)
1984Compaq Deskpro
8086 at 8 MHz
128KB - 640KB RAM
deskpro/Compaq - BIOS - Revision J - 106265-002.bin
1984Olivetti M24 [5]
8086 at 8 MHz
128KB - 640KB RAM
Built-in enhanced CGA (supports 640x400x2)
olivetti_m24/olivetti_m24_version_1.43_low.bin
olivetti_m24/olivetti_m24_version_1.43_high.bin
1986Amstrad PC1512 [5]
8086 at 8 MHz
512KB - 640KB RAM
Enhanced CGA (supports 640x200x16)
Custom mouse port
pc1512/40043.v1
pc1512/40044.v2
pc1512/40078.ic127
1987Amstrad PC1640 [5]
8086 at 8 MHz
640KB RAM
Built-in Paradise EGA
Custom mouse port
pc1640/40043.v3
pc1640/40044.v3
pc1640/40100
1987Toshiba T1200 [1] [5]
8086 at 9.54 MHz
1MB - 2MB RAM
CGA on built-in LCD
t1200/t1200_019e.ic15.bin
t1200/t1000font.rom
1988Amstrad PPC512/640 [5]
8086 at 8 MHz
512KB - 640KB RAM
Built-in CGA w/ plasma display
ppc512/40107.v2
ppc512/40108.v2
ppc512/40109.bin
1988Sinclair PC200/Amstrad PC20 [5]
8086 at 8 MHz
512KB - 640KB RAM
Built-in CGA (supports TV-out 50hz PAL)
pc200/pc20v2.0
pc200/pc20v2.1
pc200/40109.bin
1988VTech Laser XT3
8086 at 10 MHz
512KB - 1152KB RAM
lxt3/27c64d.bin
1989Amstrad PC2086 [5]
8086 at 8 MHz
640KB RAM
Built-in VGA
pc2086/40179.ic129
pc2086/40180.ic132
pc2086/40186.ic171
1989Tandy 1000SL/2 [5]
8086 at 9.54 MHz
512KB - 768KB RAM
Built-in 16 colour graphics
4 voice sound
tandy1000sl2/8079047.hu1
tandy1000sl2/8079048.hu2
1990Amstrad PC3086 [5]
8086 at 8 MHz
640KB RAM
Built-in VGA
pc3086/fc00.bin
pc3086/c000.bin
1991Amstrad PC5086
8086 at 8 MHz
640KB RAM
pc5086/sys_rom.bin
+

286 based

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReleaseMachineROM file needed
(within ./roms/ folder)
1984IBM AT
286 at 6 or 8 MHz
256KB - 16MB RAM
ibmat/at111585.0
ibmat/at111585.1
1986Compaq Portable II
286 at 8 MHz
256KB - 15MB RAM
compaq_pii/109739-001.rom
compaq_pii/109740-001.rom
1986IBM XT Model 286
286 at 6 MHz
256KB - 16MB RAM
ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN
ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.BIN
1986Toshiba T3100e [1] [5]
286 at 12 MHz
1MB - 5MB RAM
CGA on gas-plasma display
t3100e/t3100e_font.bin
t3100e/t3100e.rom
1987IBM PS/2 Model 50 [5]
286 at 10 MHz
1MB - 16MB RAM
Built-in VGA
MCA bus
i8550021/90x7420.zm13
i8550021/90x7423.zm14
i8550021/90x7426.zm16
i8550021/90x7429.zm18
1988Bull Micral 45
286 at 12 MHz
1MB - 6MB RAM
bull_micral_45/even.fil
bull_micral_45/odd.fil
1988Commodore PC30-III
286 at 12 MHz
512KB - 16MB RAM
cmdpc30/commodore pc 30 iii even.bin
cmdpc30/commodore pc 30 iii odd.bin
1988IBM PS/2 Model 30-286
286 at 10 MHz
1MB - 16MB RAM
Built-in VGA
MCA bus
ibmps2_m30_286/33f5381a.bin
1989Epson PC AX
286
256KB - 16MB RAM
epson_pcax/EVAX
epson_pcax/ODAX
1989Epson PC AX2e
286 at 12 MHz
256KB - 16MB RAM
epson_pcax2e/EVAX
epson_pcax2e/ODAX
1990AMI 286 clone
286 at 8+ MHz
512KB - 16MB RAM
ami286/amic206.bin
1990Award 286 clone
286 at 8+ MHz
512KB - 16MB RAM
award286/award.bin
1990Dell System 200
286 at 12 MHz
640KB - 16MB RAM
dells200/dell0.bin
dells200/dell1.bin
1990IBM PS/1 Model 2011 [5]
286 at 10 MHz
512KB - 16MB RAM
Built-in VGA
DOS 4.01 + GUI menu system in ROM
ibmps1/f80000.bin
?Goldstar GDC-212M
286 at 12 MHz
512KB - 4MB RAM
gdc212m/gdc212m_72h.bin
?GW-286CT GEAR
286 at 8+ MHz
512KB - 16MB RAM
gw286ct/2ctc001.bin
?Hyundai Super-286TR
286 at 12 MHz
1MB - 4MB RAM
super286tr/award.bin
?Samsung SPC-4200P
286 at 12 MHz
512KB - 2MB RAM
spc4200p/u8.01
?Samsung SPC-4216P
286 at 12 MHz
1MB - 5MB RAM
spc4216p/phoenix.bin
   or
spc4216p/7101.u8
spc4216p/ac64.u10
?Samsung SPC-4620P
286 at 12 MHz
1MB - 5MB RAM
Built-in Korean ATI-28800
spc4620p/31005h.u8
spc4620p/31005h.u10
spc4620p/svb6120a_font.rom
spc4620p/31005h.u8
spc4620p/31005h.u10
?Tulip AT Compact
286
640KB - 16MB RAM
tulip_tc7/tc7be.bin
tulip_tc7/tc7bo.bin
+

386 based

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReleaseMachineROM file needed
(within ./roms/ folder)
1987IBM PS/2 Model 80 [5]
386DX at 20 MHz
1MB - 12MB RAM
Built-in VGA
MCA bus
i8580111/15f6637.bin
i8580111/15f6639.bin
1988ECS 386/32
386DX at 20 MHz
1MB - 16MB RAM
ecs386_32/386_32_even.bin
ecs386_32/386_32_odd.bin
1989IBM PS/2 Model 70 (type 3) [5]
386DX at 25 MHz
2MB - 16MB RAM
Built-in VGA
MCA bus
ibmps2_m70_type3/70-a_even.bin
ibmps2_m70_type3/70-a_odd.bin
1989Compaq Deskpro 386
386DX at 20 MHz
1MB - 15MB RAM
deskpro386/109592-005.u11.bin
deskpro386/109591-005.u13.bin
1989Epson PC AX3
386SX at 16 MHz
256KB - 16MB RAM
epson_pcax3/EVAX3
epson_pcax3/ODAX3
1989IBM PS/2 Model 55SX
386SX at 16 MHz
1MB - 8MB RAM
Built-in VGA
MCA bus
i8555081/33f8146.zm41
i8555081/33f8145.zm40
1990DTK 386SX clone
386SX
512KB - 16MB RAM
dtk386/3cto001.bin
1990IBM PS/1 Model 2121 [5]
386SX at 20 MHz
1MB - 16MB RAM
Built-in VGA
ibmps1_2121/fc0000.bin
1990Samsung SPC-6000A
386DX
1MB - 32 MB RAM
spc6000a/3c80.u27
spc6000a/9f80.u26
1992Acermate 386SX/25N [5]
386SX at 25 MHz
2MB - 16MB RAM
Built-in Oak SVGA
acer386/acer386.bin
acer386/oti067.bin
1992Amstrad MegaPC [2] [5]
386SX at 25 MHz
1MB - 16MB RAM
Built-in VGA
megapc/41651-bios lo.u18
megapc/211253-bios hi.u19
1992Commodore SL386SX-25 [5]
386SX at 25 MHz
1MB - 16MB RAM
Built-in AVGA2
cbm_sl386sx25/f000.bin
cbm_sl386sx25/c000.bin
1992Packard Bell Legend 300SX
386SX at 16 MHz
1MB - 16MB RAM
pb_l300sx/pb_l300sx.bin
1992Samsung SPC-6033P
386SX at 33 MHz
2MB - 12 MB RAM
spc6033p/phoenix.bin
spc6033p/svb6120a_font.rom
1994AMI 386DX clone
386DX at 40 MHz
1MB - 32MB RAM
ami386dx/opt495sx.ami
1994AMI 386SX clone
386SX at 25 MHz
1MB - 16MB RAM
ami386/ami386.bin
1994MR 386DX clone
This is a generic 386DX clone with an MR BIOS
mr386dx/opt495sx.mr
?KMX-C-02
386SX
512KB - 16MB RAM
kmxc02/3ctm005.bin
+

486 based

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReleaseMachine
(+ addl. hardware)
CPU(s) SupportedROM file needed
(within ./roms/ folder)
1990IBM PS/2 Model 70 (type 4) [3]
2MB - 16MB RAM
Built-in VGA
MCA bus
486DX at 25 MHzibmps2_m70_type3/70-a_even.bin
ibmps2_m70_type3/70-a_odd.bin
1993AMI 486 clone
1MB - 32MB RAM
486 at 16-66 MHzami486/ami486.bin
1993Elonex PC-425X [5]
1MB - 256MB RAM
Built-in Trident TGUI9440CXi
486SX at 25 MHzelx_pc425x/elx_pc425x.bin
   or
elx_pc425x/elx_pc425x_bios.bin
elx_pc425x/elx_pc425x_vbios.bin
1993IBM PS/1 Model 2133 (EMEA 451)
2MB - 64MB RAM
Built-in Cirrus Logic GD5426
486SX at 25 MHzibmps1_2133/PS1_2133_52G2974_ROM.bin
1993Packard Bell PB410A [5]
1MB - 64MB RAM
Built-in HT-216 video
486 at 25-120 MHz
Am5x86 at 133-160 MHz
Cx5x86 at 100-133 MHz
Pentium Overdrive at 63-83 MHz
pb410a/PB410A.080337.4ABF.U25.bin
1994AMI WinBIOS 486 clone
1MB - 32MB RAM
486 at 16-66 MHzwin486/ali1429g.amw
1995Award SiS 496/497
1MB - 64MB RAM
486 at 16-120 MHz
Am5x86 at 133-160 MHz
Cx5x86 at 100-133 MHz
Pentium Overdrive at 63-83 MHz
sis496/sis496-1.awa
+

Pentium based

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReleaseMachine
(+ addl. hardware)
CPU(s) SupportedROM file needed
(within ./roms/ folder)
1994Intel Premiere/PCI (Batman's Revenge)
1MB - 128MB RAM
Pentium at 60-66 MHz
Pentium Overdrive at 120-133 MHz
revenge/1009af2_.bi0
revenge/1009af2_.bi1
1995Intel Advanced/EV (Endeavor) [4]
1MB - 128MB RAM
Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz
endeavor/1006cb0_.bi0
endeavor/1006cb0_.bi1
1995Intel Advanced/ZP (Zappa)
1MB - 128MB RAM
Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz
zappa/1006bs0_.bio
zappa/1006bs0_.bi1
1995Packard Bell PB520R (Robin LC) [5]
1MB - 128MB RAM
Built-in Cirrus Logic GD-5434
Pentium at 60-66 MHz
Pentium Overdrive at 120-133 MHz
pb520r/1009bc0r.bio
pb520r/1009bc0r.bi1
pb520r/gd5434.bin
1995Packard Bell PB570 (Hillary) [5]
1MB - 128MB RAM
Built-in Cirrus Logic GD-5430
Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz
pb570/1007by0r.bio
pb570/1007by0r.bi1
pb570/gd5430.bin
1996ASUS P/I-P55TVP4
1MB - 128MB RAM
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz
p55tvp4/tv5i0204.awd
1996ASUS P/I-P55T2P4
1MB - 512MB RAM
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz
p55t2p4/0207_j2.bin
1996Award 430VX PCI
1MB - 128MB RAM
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz
430vx/55xwuq0e.bin
1996Itautec Infoway Multimidia
8MB - 128MB RAM
Pentium at 75-133 MHz
Pentium Overdrive at 125-200 MHz
infowaym/1006bs0_.bio
infowaym/1006bs0_.bi1
1997Epox P55-VA
1MB - 128MB RAM
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT Winchip 2 at 200-240 MHz
IDT Winchip 2A at 200-233 MHz
AMD K6 at 166-300 MHz
AMD K6-2 (AFR-66) at 233-300 MHz
p55va/va021297.bin
+

Super Socket 7 based

+ + + + + + + + + + + + + + + + + +
ReleaseMachine
(+ addl. hardware)
CPU(s) SupportedROM file needed
(within ./roms/ folder)
1998FIC VA-503+
1MB - 512MB RAM
AMD K6 at 166-300 MHz
AMD K6-2 at 233-550 MHz
AMD K6-2+ at 450-550 MHz
AMD K6-III at 400-450 MHz
AMD K6-III+ at 400-500 MHz
Pentium at 75-200 MHz
Pentium MMX at 166-233 MHz
Mobile Pentium MMX at 120-300 MHz
Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz)
Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz)
IDT WinChip at 75-240 MHz
IDT WinChip2 at 200-250 MHz
IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz)
fic_va503p/je4333.bin
+

Socket 8 based

+ + + + + + + + + + + + + + + + + +
ReleaseMachine
(+ addl. hardware)
CPU(s) SupportedROM file needed
(within ./roms/ folder)
1996Intel VS440FX
8MB - 256 MB RAM
Pentium Pro at 150-200 MHz
Pentium II Overdrive at 300-333 MHz
vs440fx/1018CS1_.BI1
vs440fx/1018CS1_.BI2
vs440fx/1018CS1_.BI3
vs440fx/1018CS1_.BIO
vs440fx/1018CS1_.RCV
+

Slot 1 based

+ + + + + + + + + + + + + + + + + +
ReleaseMachine
(+ addl. hardware)
CPU(s) SupportedROM file needed
(within ./roms/ folder)
1998Gigabyte GA-686BX
8MB - 512MB RAM
Pentium II at 233-450 MHz
Celeron at 266-533 MHz
Cyrix IIIat 500 MHz
ga686bx/6BX.F2a
+

Additional Notes

+

[1] Toshiba Button Mapping: PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported: Key Combo | Function ---|--- Fn + Num Lock | toggle numpad Fn + Home | Internal LCD display Fn + Page Down | Turbo on Fn + Right | Toggle LCD font Fn + End | External CRT display Fn + SysRQ | Toggle window

+

[2] Amstrad MegaPC (386SX): The original machine had a built-in Sega MegaDrive. This is not emulated in PCem.

+

[3] IBM PS/2 Model 70 (type 4) (486DX): PCem's FPU emulation is not bit accurate and can not pass IBM's floating point tests. As a result, this machine will always print 12903 and 162 errors on bootup. These can be ignored - F1 will boot the machine.

+

[4] Intel Advanced/EV (Endeavor) (Pentium): The real board has a Sound Blaster 16 onboard and optionally an S3 Trio64V+. Neither are emulated as onboard devices.

+

[5] Some systems have fixed graphics adapters:
** = Can use external video card.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SystemGraphicsAddl. Info**
Amstrad MegaPCParadise 90C11A development of the PVGA1 with 512KB VRAM✔
Acer 386SX/25NOak OTI-067Another 512KB SVGA clone✔
Amstrad PC1512CGAHas a new mode (640x200x16)X
Amstrad PC1640Paradise EGA ✔
Amstrad PC2086/PC3086Paradise PVGA1An early SVGA clone with 256KB VRAM✔
Amstrad PPC512/640CGA/MDAOutputs to 640x200 plasma display✔
Commodore SL386SX-25AVGA2256KB - 512KB VRAMX
Elonex PC-425XTrident TGUI9400CXi512KB VRAMX
IBM PCjrCGAHas various new modes:
160x200 x 16
320x200 x 16
640x200 x 4
X
IBM PS/1 Model 2011Stock VGA256KB VRAMX
IBM PS/1 Model 2121Basic (and unknown) SVGA256KB VRAMX
IBM PS/2 machinesStock VGA256KB VRAMX
Olivetti M24 [6]CGAHas double-res text modes + 640x400 modeX
Packard Bell PB410AHeadland HT-216 ✔
Packard Bell PB520RCirrus Logic GD-5434 ✔
Packard Bell PB570Cirrus Logic GD-5430 ✔
Sinclair PC200CGACan output to TV @ 50hz (UK)✔
Tandy 1000Clone of PCjr videoWidely supported in 80s gamesX
Tandy 1000 SL/2Improved Tandy 1000Has support for 640x200x16X
Toshiba T-seriesCGAOutputs to built-in LCD or plasma displayX
+

[6] Olivetti M24 (display): I haven't seen a dump of the font ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd as it is 14-line instead of 16-line.

+
+ +

Graphics Cards

+

Basic cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareAddl. InfoROM file needed
(within ./roms/ folder)
MDA (1981)80x25 monochrome text(none)
CGA (1981)40x25 and 80x25 text
320x200 in 4 colours
620x200 in 2 colours
Supports composite output for ~16 colours.
(none)
Hercules (1982)80x25 monochrome text
720x348 in monochrome
(none)
Plantronics ColorPlusAn enhanced CGA board with support for 320x200x16 and 640x200x4(none)
Wyse WY-700A CGA-compatible board with support for a 1280x800 mode(none)
MDSI GeniusMono portrait board with support for a 728x1008 mode8x12.bin
IBM EGA (1984)Text up to 80x43
Graphics up to 640x350 in 16 colours
ibm_6277356_ega_card_u44_27128.bin
ATI EGA Wonder 800+An enhanced EGA-compatible board with support for up to 800x600 in 16 coloursATI EGA Wonder 800+ N1.00.BIN
Hercules InColorAn enhanced Hercules with a custom 720x350 16 colour mode(none)
+

Unaccelerated (S)VGA cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareAddl. InfoROM file needed
(within ./roms/ folder)
ATI Korean VGAATI-28800 based.
512KB VRAM
Supports up to 8-bit colour
Korean font support
atikorvga.bin
ati_ksc5601.rom
ATI VGA Edge-16ATI-18800 based
512KB VRAM
Supports up to 8-bit colour
vgaedge16.vbi
ATI VGA ChargerATI-28800 based
512KB VRAM
Supports up to 8-bit colour
bios.bin
AVGA2Also known as Cirrus Logic GD5402
256KB - 512KB VRAM
Supports up to 8-bit colour
avga2vram.vbi
IBM VGA (1987)256KB VRAM
Text up to 80x50
Graphics up to 320x200 in 256 colours or 640x480 in 16 colours
ibm_vga.bin
Kasan Hangulmadang-16ET4000AX based
1MB VRAM
Supports up to 8-bit colour
Korean font support
et4000_kasan16.bin
kasan_ksc5601.rom
OAK OTI-037C256KB VRAM
Supports up to 8-bit colour
oti037/bios.bin
OAK OTI-067256KB - 512KB VRAM
Supports up to 8-bit colour
oti067/bios.bin
Olivetti GO481 (Paradise PVGA1A)256KB VRAM
Supports up to 8-bit colour
oli_go481_lo.bin
oli_go481_hi.bin
Trident 8900D SVGA256KB - 1MB VRAM
Supports up to 24-bit colour
trident.bin
Trident 9000B SVGA512KB VRAM
Supports up to 8-bit colour
tvga9000b/BIOS.BIN
Trident TGUI9400CXi1MB - 2MB VRAM
Supports up to 24-bit colour
9440.vbi
Trigem Korean VGAET4000AX based
1MB VRAM
Supports up to 8-bit colour
Korean font support
tgkorvga.bin
tg_ksc5601.rom
Tseng ET4000AX SVGA1MB VRAM
Supports up to 8-bit colour
et4000.bin
+

2D Accelerated SVGA cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareAddl. InfoROM file needed
(within ./roms/ folder)
ATI Graphics Pro TurboMach64GX based
1MB - 4MB VRAM
mach64gx/bios.bin
ATI Video XpressionMach64VT2 based
2MB - 4MB VRAM
Has video acceleration
atimach64vt2pci.bin
Cirrus Logic GD-54281MB - 2MB VRAMMachspeed_VGA_GUI_2100_VLB.vbi
Cirrus Logic GD-54291MB - 2MB VRAM5429.vbi
Cirrus Logic GD-54301MB - 2MB VRAMgd5430/pci.bin
Cirrus Logic GD-5434 [1]2MB - 4MB VRAMgd5434.bin
Diamond Stealth 32 SVGAET4000/W32p based
1MB - 2MB VRAM
et4000w32.bin
IBM 1MB SVGA Adapter/ACirrus Logic GD5428 based
1 MB VRAM
Only supported on PS/2 models
SVGA141.ROM
Number Nine 9FXS3 Trio64 based
1MB - 2MB VRAM
s3_764.bin
Paradise Bahamas 64S3 Vision864 based
1MB - 4MB VRAM
bahamas64.bin
Phoenix S3 Trio32S3 Trio32 based
512KB - 2MB VRAM
86c732p.bin
Phoenix S3 Trio64S3 Trio64 based
1MB - 4MB VRAM
86c764x1.bin
Trident TGUI94401MB - 2MB VRAM9440.vbi
+

3D Accelerated SVGA cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareAddl. InfoROM file needed
(within ./roms/ folder)
3DFX Voodoo Banshee (reference)Voodoo Banshee based
8MB - 16MB VRAM
pci_sg.rom
3DFX Voodoo 3 2000Voodoo 3 based
16MB VRAM
voodoo3_2000/2k11sd.rom
3DFX Voodoo 3 3000Voodoo 3 based
16MB VRAM
voodoo3_3000/3k12sd.rom
Creative Labs 3D Blaster BansheeVoodoo Banshee based
16MB VRAM
blasterpci.rom
Diamond Stealth 3D 2000 [2]S3 ViRGE/325 based
2MB - 4MB VRAM
s3virge.bin
S3 ViRGE/DX [3]S3 ViRGE/DX based
2MB - 4MB VRAM
86c375_1.bin
+

3D only cards

+ + + + + + + + + + + + + + + + + + + + + +
HardwareAddl. Info
3DFX Voodoo Graphics [4]3D accelerator. Widely supported in late 90s games.
Obsidian SB50 [5]Voodoo with 2 TMUs
3DFX Voodoo 2 [6]Improved Voodoo Graphics
Higher clocks
2 TMUs
Triangle setup, etc.
+

Additional Notes

+

[1] Cirrus Logic GD-5434: Real chip also supports 1MB configurations, however this is not currently supported in PCem.

+

[2] Diamond Stealth 3D 2000: PCem emulates the ViRGE S3D engine in software. This works with most games I tried, but there may be some issues. The Direct3D drivers for the /325 are fairly poor (often showing as missing triangles), so use of the /DX instead is recommended.

+

[3] S3 ViRGE/DX: The drivers that come with Windows are similar to those for the /325, however better ones do exist (try the 8-21-1997 version). With the correct drivers, many early Direct3D games work okay (if slowly).

+

[4] 3DFX Voodoo Graphics: PCem emulates this in software. The emulation is a lot faster than in v10 (thanks to a new dynamic recompiler) and should be capable of hitting Voodoo 1 performance on most machines when two render threads are used. As before, the emulated CPU is the bottleneck for most games.

PCem can emulate 6 and 8 MB configurations, but defaults to 4 MB for compatibility. It can also emulate the screen filter present on the original card, though this does at present have a noticeable performance hit.

Almost everything I've tried works okay, with a very few exceptions - Screamer 2 and Rally have serious issues.

+

[5] Obsidian SB50: Drivers for this are a bit limited - the official drivers don't support 2 TMUs in Direct3D.

+

[6] 3DFX Voodoo 2: PCem can emulate both 8 and 12 MB configurations. It can also emulate 6 and 10 MB configurations (with 2MB framebuffer memory), which were never sold into the PC market but do exist for arcade systems.

+
+ +

Sound Cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareNotes
PC speakerThe standard beeper on all PCs. Supports samples/RealSound.
Tandy PSGThe Texas Instruments chip in the PCjr and Tandy 1000. Supports 3 voices plus noise. I reused the emulator in B-em for this (slightly modified). PCem emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 (currently assigned to the Tandy 1000HX). Maniac Mansion and Zak McKraken will only sound correct on the latter.
Tandy PSSJUsed on the Tandy 1000SL/2, this clones the NCR8496, adding an addition frequency divider (did any software actually use this?) and an 8-bit DAC.
PS/1 audio cardAn SN76496 clone plus an 8-bit DAC. The SN76496 isn't at the same address as PCjr/Tandy, so most software doesn't support it.
GameblasterThe Creative Labs Gameblaster/Creative Music System, Creative's first sound card introduced in 1987. Has two Philips SAA1099, giving 12 voices of square waves plus 4 noise voices. In stereo!
AdlibHas a Yamaha YM3812, giving 9 voices of 2 op FM, or 6 voices plus a rhythm section. PCem uses the DOSBox dbopl emulator.
Adlib GoldOPL3 with YM318Z 12-bit digital section. Possibly some bugs (not a lot of software to test). The surround module is now emulated.
Sound Blaster [1]See linked note for more details.
Gravis Ultrasound32 voice sample playback. Port address is fixed to 240, IRQ and DMA can be changed from the drivers. Emulation is improved significantly over previous versions.
Windows Sound System16-bit digital + OPL3. Note that this only emulates WSS itself, and should not be used with drivers from compatible boards with additional components (eg Turtle Beach Monte Carlo)
Aztech Sound Galaxy Pro 16 AB (Washington)SB compatible + WSS compatible
Innovation SSI-2001SID6581. Emulated using resid-fp. Board is fixed to port 280.
Ensoniq AudioPCI (ES1371)
Sound Blaster PCI 128
Basic PCI sound card. Emulates Sound Blaster in software.
+

Additional Notes

+

[1] Sound Blaster: Several Sound Blasters are emulated.

+
    +
  • SB v1.0 - The original. Limited to 22khz, and no auto-init DMA (can cause crackles sometimes).
  • +
  • SB v1.5 - Adds auto-init DMA
  • +
  • SB v2.0 - Upped to 41khz
  • +
  • SB Pro v1.0 - Stereo with twin OPL2 chips.
  • +
  • SB Pro v2.0 - Stereo with OPL 3 chip
  • +
  • SB 16 - 16 bit stereo
  • +
  • SB AWE32 - SB 16 + wavetable MIDI. This requires a ROM dump from a real AWE32.
  • +
+

All cards are set to Address 220, IRQ 7 and DMA 1 (and High DMA 5). IRQ and DMA can be changed for the SB16 & AWE32 in the drivers. The relevant SET line for autoexec.bat is SET BLASTER = A220 I7 D1 Tx - where Tx is T1 for SB v1.0, T3 for SB v2.0, T4 for SB Pro, and T6 for SB16.

+

AWE32 requires a ROM dump called awe32.raw. AWE-DUMP is a utility which can get a dump from a real card. Most EMU8000 functionality should work, however filters are not correct and reverb/chorus effects are not currently emulated.

+
+ +

HDD Controller Cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Int.HardwareNotesROM file needed
(within ./roms/ folder)
MFMFixed Disk Adapter (Xebec)MFM controller originally included in the IBM XT. This controller only supports HD types 0, 2, 13, and 16.ibm_xebec_62x0822_1985.bin
MFMDTC 5150X8-bit MFM controller.
To configure drive types, run DEBUG.EXE and enter g=c800:5.
dtc_cxd21a.bin
MFMAT Fixed Disk AdapterMFM controller originally included in the IBM AT. Supported by all AT-compatible BIOSes.(none)
ESDIWestern Digital WD1007V-SE116-bit ESDI controller62-000279-061.bin
ESDIIBM ESDI Fixed Disk ControllerMCA ESDI controller. Only supported on PS/2 models.90x8969.bin
90x8970.bin
IDEStandard IDEStandard IDE controller. Supported by all AT-compatible BIOSes. Use this if in any doubt!(none)
IDEXTIDE8-bit IDE controller. The BIOS is available here.
v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues.
ide_xt.bin
IDEXTIDE (AT)16-bit IDE controller.ide_at.bin
IDEXTIDE (PS/1)IDE controller for the PS/1 model 2033. For this machine you will need BIOS version v1.1.5. The PS/1 is a bit fussy with XTIDE, and I've found that it works best when the XTIDE configuration has 'Full Operating Mode' disabled.ide_at_1_1_5.bin
SCSILongshine LCS-6821N8-bit SCSI controller.Longshine LCS-6821N - BIOS version 1.04.bin
SCSIRancho RT1000B8-bit SCSI controller.Rancho_RT1000_RTBios_version_8.10R.bin
SCSITrantor T130B8-bit SCSI controller.trantor_t130b_bios_v2.14.bin
SCSIIBM SCSI Adapter with CacheMCA SCSI controller. Only supported on PS/2 models.92F2244.U68
92F2245.U69
SCSIAdaptec AHA-1542C16-bit SCSI controller.adaptec_aha1542c_bios_534201-00.bin
SCSIBusLogic BT-545S16-bit SCSI controller.BusLogic_BT-545S_U15_27128_5002026-4.50.bin
+
+ +

Misc Cards

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
HardwareNote
Serial mouseA Microsoft compatible serial mouse on COM1. Compatible drivers are all over the place for this.
M24 mouseI haven't seen a DOS mouse driver for this yet but the regular scancode mode works as does the Windows 1.x driver.
PC1512 mouseThe PC1512's perculiar quadrature mouse. You need Amstrad's actual driver for this one.
PS/2 mouseA standard 2 button PS/2 mouse. As with serial, compatible drivers are common.
Microsoft PS/2 IntellimouseA PS/2 mouse with mouse wheel.
ATAPI CD-ROMWorks with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've tried.
+ + diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 3a4b244..0000000 --- a/readme.txt +++ /dev/null @@ -1,1636 +0,0 @@ -PCem v16 - -PCem is licensed under the GPL, see COPYING for more details. - -Changes since v15 -- New machines added - Commodore SL386SX-25, ECS 386/32, Goldstar GDC-212M, - Hyundai Super-286TR, IBM PS/1 Model 2133 (EMEA 451), Itautec Infoway Multimidia, - Samsung SPC-4620P, Leading Edge Model M -- New graphics cards added - ATI EGA Wonder 800+, AVGA2, Cirrus Logic GD5428, - IBM 1MB SVGA Adapter/A -- New sound card added - Aztech Sound Galaxy Pro 16 AB (Washington) -- New SCSI card added - IBM SCSI Adapter with Cache -- Support FPU emulation on pre-486 machines -- Numerous bug fixes - -Thanks to EluanCM, Greatpsycho, John Elliott, and leilei for contributions towards this release. - - -PCem emulates the following machines: - -8088 based : - - AMI XT clone (1989) - 8088 at 8+ MHz, 64-640kb RAM. - - ROM files needed: - amixt\ami_8088_bios_31jan89.bin - - - Atari PC3 (19xx) - 8088 at 8 MHz, 640kb RAM. - - ROM files needed: - ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN - - - Compaq Portable Plus (1983) - 8088 at 4.77 MHz, 128-640kb RAM. - - ROM files needed: - compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin - - - DTK Clone XT (1986) - 8088 at 8/10 MHz, 64kb-640kb RAM. - - ROM files needed: - dtk/dtk_erso_2.42_2764.bin - - - (c)Anonymous Generic Turbo XT BIOS (1988?) - 8088 at 8+ MHz, 64-640kb RAM. - - ROM files needed: - genxt\pcxt.rom - - - IBM PC (1981) - 8088 at 4.77 MHz, 16-640kb RAM (PCem emulates minimum 64kb) - - ROM files needed: - ibmpc\pc102782.bin - ibmpc\basicc11.f6 - ibmpc\basicc11.f8 - ibmpc\basicc11.fa - ibmpc\basicc11.fc - - - IBM PCjr (1984) - 8088 at 4.77 MHz, 64-640kb RAM (PCem emulates minimum 128kb), built-in 16 colour graphics, 3 voice sound. - Not generally PC compatible. - - ROM files needed: - ibmpcjr\bios.rom - - - IBM XT (1983) - 8088 at 4.77 MHz, 64-640kb RAM - - ROM files needed: - ibmxt\5000027.u19 - ibmxt\1501512.u18 - - - Juko XT clone (1988) - - ROM files needed: - jukopc\000o001.bin - - - Leading Edge Model M (1983) - 8088 at 7.16 MHz, 128-704kB RAM - - ROM files needed: - leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin - - - NCR PC4i (1985) - 8088 at 4.77 MHz, 256-640kb RAM - - ROM files needed: - ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN - - - Phoenix XT clone (1986) - 8088 at 8/10 MHz, 64kb-640kb RAM. - - ROM files needed: - pxxt\000p001.bin - - - Schneider Euro PC (1988) - 8088 at 9.54 MHz, 512-640kb RAM. - - ROM files needed: - europc\50145 - europc\50146 - - - Tandy 1000 (1984) - 8088 at 4.77 MHz, 128kb-640kb RAM, built-in 16 colour graphics + 3 voice sound - - ROM files needed: - tandy\tandy1t1.020 - - - Tandy 1000HX (1987) - 8088 at 7.16 MHz, 256-640kb RAM, built-in 16 colour graphics + 3 voice sound. - Has DOS 2.11 in ROM. - - ROM files needed: - tandy1000hx\v020000.u12 - - - Thomson TO16 PC (1987) - 8088 at 9.54 MHz, 512-640kb RAM. - - ROM files needed: - to16_pc/TO16_103.bin - - - Toshiba T1000 (1987) - 8088 at 4.77 MHz, 512-1024 kb RAM, CGA on built-in LCD. - - PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : - Fn + Num Lock - toggle numpad - Fn + Home - Internal LCD display - Fn + Page Down - Turbo on - Fn + Right - Toggle LCD font - Fn + End - External CRT display - Fn + SysRQ - Toggle window - - ROM files needed: - t1000/t1000.rom - t1000/t1000font.rom - - - VTech Laser Turbo XT (1987) - 8088 at 10 MHz, 640kb RAM - - ROM files needed: - ltxt\27c64.bin - - - Zenith Data SupersPort (1987) - 8088 at 8 MHz, 128-640kb RAM. Built-in LCD video is not currently emulated - - ROM files needed: - zdsupers/z184m v3.1d.10d - - - Xi8088 (2015) - 8088 at 4.77 - 13.33 MHz, 640kb RAM - - ROM files needed: - xi8088/bios-xi8088.bin - - -8086 based : - - Amstrad PC1512 (1986) - 8086 at 8 MHz, 512kb-640kb RAM, enhanced CGA (supports 640x200x16), custom mouse port. - - ROM files needed: - pc1512\40043.v1 - pc1512\40044.v2 - pc1512\40078.ic127 - - - Amstrad PC1640 (1987) - 8086 at 8 MHz, 640kb RAM, built-in Paradise EGA, custom mouse port. - - ROM files needed: - pc1640\40043.v3 - pc1640\40044.v3 - pc1640\40100 - - - Amstrad PC2086 (1989) - 8086 at 8 MHz, 640kb, built-in VGA. - - ROM files needed: - pc2086\40179.ic129 - pc2086\40180.ic132 - pc2086\40186.ic171 - - - Amstrad PC3086 (1990) - 8086 at 8 MHz, 640kb, built-in VGA. - - ROM files needed: - pc3086\fc00.bin - pc3086\c000.bin - - - Amstrad PPC512/640 (1988) - 8086 at 8 MHz, 512-640kb RAM, built-in CGA driving plasma display. - - ROM files needed: - ppc512/40107.v2 - ppc512/40108.v2 - ppc512/40109.bin - - - Olivetti M24 (1984) - 8086 at 8 MHz, 128kb-640kb RAM, built-in enhanced CGA (supports 640x400x2). - - ROM files needed: - olivetti_m24\olivetti_m24_version_1.43_low.bin - olivetti_m24\olivetti_m24_version_1.43_high.bin - - - Sinclair PC200/Amstrad PC20 (1988) - 8086 at 8 MHz, 512-640kb RAM, built-in CGA. Video supports TV out (50 HZ PAL). - - ROM files needed: - pc200\pc20v2.0 - pc200\pc20v2.1 - pc200\40109.bin - - - Tandy 1000SL/2 (1989) - 8086 at 9.54 MHz, 512-768kb RAM, built-in 16 colour graphics + 4 voice sound. - - ROM files needed: - tandy1000sl2\8079047.hu1 - tandy1000sl2\8079048.hu2 - - - Toshiba T1200 (1987) - 8086 at 9.54 MHz, 1-2 MB RAM, CGA on built-in LCD. - - PCem maps [Fn] to right-Ctrl and right-Alt. The following functions are supported : - Fn + Num Lock - toggle numpad - Fn + Home - Internal LCD display - Fn + Page Down - Turbo on - Fn + Right - Toggle LCD font - Fn + End - External CRT display - Fn + SysRQ - Toggle window - - ROM files needed: - t1200/t1200_019e.ic15.bin - t1200/t1000font.rom - - - VTech Laser XT3 (1988) - 8086 at 10 MHz, 512-1152kb RAM. - - ROM files needed: - lxt3\27c64d.bin - - - -286 based : - - AMI 286 clone (1990) - 286 at 8+ MHz, 512kb - 16MB RAM. - - ROM files needed: - ami286\amic206.bin - - - Award 286 clone (1990) - 286 at 8+ MHz, 512kb - 16MB RAM. - - ROM files needed: - award286\award.bin - - - Bull Micral 45 (1988) - 286 at 12 MHz, 1-6MB RAM. - - ROM files needed: - bull_micral_45/even.fil - bull_micral_45/odd.fil - - - Commodore PC30-III (1988) - 286 at 12 MHz, 512kb - 16MB RAM. - - ROM files needed: - cmdpc30\commodore pc 30 iii even.bin - cmdpc30\commodore pc 30 iii odd.bin - - - Compaq Portable II (1986) - 286 at 8 MHz, 256kb-15MB RAM. - - ROM files needed: - compaq_pii/109739-001.rom - compaq_pii/109740-001.rom - - - Dell System 200 (1990?) - 286 at 12 MHz, 640kb-16MB RAM. - - ROM files needed: - dells200\dell0.bin - dells200\dell1.bin - - - Epson PC AX (1989) - 286, 256kb - 16MB RAM. - - ROM files needed : - epson_pcax\EVAX - epson_pcax\ODAX - - - Epson PC AX2e (1989) - 286 at 12 MHz, 256kb - 16MB RAM. - - ROM files needed : - epson_pcax2e\EVAX - epson_pcax2e\ODAX - - - Goldstar GDC-212M - 286 at 12 MHz, 512kb - 4MB RAM. - - ROM files needed : - gdc212m/gdc212m_72h.bin - - - GW-286CT GEAR - 286 at 8+ MHz, 512kb - 16MB RAM. - - ROM files needed: - gw286ct/2ctc001.bin - - - Hyundai Super-286TR (19xx) - 286 at 12 MHz, 1-4MB RAM - - ROM files needed: - super286tr/award.bin - - - IBM AT (1984) - 286 at 6 or 8 MHz, 256kb-16mb RAM - - ROM files needed: - ibmat\at111585.0 - ibmat\at111585.1 - - - IBM PS/1 Model 2011 (1990) - 286 at 10 MHz, 512kb-16MB RAM, built-in VGA, DOS 4.01 + GUI menu system in ROM. - - ROM files needed : - ibmps1\f80000.bin - - - IBM PS/2 Model 30-286 (1988) - 286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. - - ROM files needed : - ibmps2_m30_286\33f5381a.bin - - - IBM PS/2 Model 50 (1987) - 286 at 10 MHz, 1MB-16MB RAM, built-in VGA, MCA bus. - - ROM files needed : - i8550021\90x7420.zm13 - i8550021\90x7423.zm14 - i8550021\90x7426.zm16 - i8550021\90x7429.zm18 - - - IBM XT Model 286 (1986) - 286 at 6 MHz, 256kb-16mb RAM - - ROM files needed : - ibmxt286\BIOS_5162_21APR86_U34_78X7460_27256.BIN - ibmxt286\BIOS_5162_21APR86_U35_78X7461_27256.BIN - - - Samsung SPC-4200P - 286 at 12 MHz, 512kb - 2MB RAM - - ROM files needed : - spc4200p\u8.01 - - - Samsung SPC-4216P - 286 at 12 MHz, 1MB - 5MB RAM - - ROM files needed : - spc4216p\phoenix.bin - or - spc4216p\7101.u8 - spc4216p\ac64.u10 - - - Samsung SPC-4620P - 286 at 12 MHz, 1MB - 5MB RAM. Built-in Korean ATI-28800. - - ROM files needed : - spc4620p/31005h.u8 - spc4620p/31005h.u10 - spc4620p/svb6120a_font.rom - spc4620p/31005h.u8 - spc4620p/31005h.u10 - - - Toshiba T3100e (1986) - 286 at 12 MHz, 1MB - 5MB RAM, CGA on gas-plasma display - - PCem maps [Fn] to right-Ctrl and right-Alt. - - ROM files needed : - t3100e\t3100e_font.bin - t3100e\t3100e.rom - - - Tulip AT Compact (198x) - 286 at MHz, 640kb - 16 MB RAM - - ROM files needed : - tulip_tc7/tc7be.bin - tulip_tc7/tc7bo.bin - - - -386SX based : - - Acermate 386SX/25N (1992?) - 386SX at 25 MHz, 2-16MB RAM, built-in Oak SVGA. - - ROM files needed : - acer386\acer386.bin - acer386\oti067.bin - - - AMI 386SX clone (1994) - 386SX at 25 MHz, 1-16MB RAM. - - ROM files needed : - ami386\ami386.bin - - - Amstrad MegaPC (1992) - 386SX at 25 MHz, 1-16MB RAM, built-in VGA. - - The original machine had a built-in Sega MegaDrive. This is not emulated in PCem. - - ROM files needed : - megapc\41651-bios lo.u18 - megapc\211253-bios hi.u19 - - - Commodore SL386SX-25 (1992) - 386SX at 25 MHz, 1-16MB RAM, built-in AVGA2. - - ROM files needed : - cbm_sl386sx25/f000.bin - cbm_sl386sx25/c000.bin - - - DTK 386SX clone (1990) - 386SX, 512kb - 16MB RAM. - - ROM files needed : - dtk386\3cto001.bin - - - Epson PC AX3 (1989) - 386SX at 16 MHz, 256kb-16MB RAM. - - ROM files needed : - epson_pcax3\EVAX3 - epson_pcax3\ODAX3 - - - IBM PS/1 Model 2121 (1990) - 386SX at 20 MHz, 1MB-16MB RAM, built-in VGA. - - ROM files needed: - ibmps1_2121\fc0000.bin - - - IBM PS/2 Model 55SX (1989) - 386SX at 16 MHz, 1MB-8MB RAM, built-in VGA, MCA bus. - - ROM files needed : - i8555081\33f8146.zm41 - i8555081\33f8145.zm40 - - - KMX-C-02 - 386SX, 512kb-16MB RAM. - - ROM files needed : - kmxc02\3ctm005.bin - - - Packard Bell Legend 300SX (1992) - 386 SX at 16 MHz, 1-16MB RAM - - ROM files needed : - pb_l300sx/pb_l300sx.bin - - - -386DX based : - - AMI 386DX clone (1994) - 386DX at 40 MHz, 1-32MB RAM. - - ROM files needed: - ami386dx\opt495sx.ami - - - Compaq Deskpro 386 (1989) - 386DX at 20 MHz, 1MB-15MB RAM. - - ROM files needed: - deskpro386\109592-005.u11.bin - deskpro386\109591-005.u13.bin - - - ECS 386/32 (1988) - 386DX at 20 MHz, 1-16MB RAM. - - ROM files needed: - ecs386_32/386_32_even.bin - ecs386_32/386_32_odd.bin - - - IBM PS/2 Model 70 (type 3) (1989) - 386DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. - - ROM files needed : - ibmps2_m70_type3/70-a_even.bin - ibmps2_m70_type3/70-a_odd.bin - - - IBM PS/2 Model 80 (1987) - 386DX at 20 MHz, 1MB-12MB RAM, built-in VGA, MCA bus. - - ROM files needed : - i8580111\15f6637.bin - i8580111\15f6639.bin - - - MR 386DX clone (1994) - This is a generic 386DX clone with an MR BIOS. - - ROM files needed: - mr386dx\opt495sx.mr - - -486 based : - - AMI 486 clone (1993) - 486 at 16-66 MHz, 1-32MB RAM. - - ROM files needed: - ami486\ami486.bin - - - AMI WinBIOS 486 clone (1994) - 486 at 16-66 MHz, 1-32MB RAM. - - ROM files needed: - win486\ali1429g.amw - - - Award SiS 496/497 (1995) - 486 at 16-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive - at 63-83 MHz. 1-64MB RAM. - - ROM files needed: - sis496\sis496-1.awa - - - Elonex PC-425X (1993) - 486SX at 25 MHz, 1-256MB RAM, built-in Trident TGUI9440CXi - - ROM files needed: - elx_pc425x/elx_pc425x.bin - or - elx_pc425x/elx_pc425x_bios.bin - elx_pc425x/elx_pc425x_vbios.bin - - - IBM PS/1 Model 2133 (EMEA 451) (1993) - 486SX at 25 MHz, 2-64MB RAM, built-in Cirrus Logic GD5426 - - ROM files needed: - ibmps1_2133/PS1_2133_52G2974_ROM.bin - - - IBM PS/2 Model 70 (type 4) (1990) - 486DX at 25 MHz, 2-16MB RAM, built-in VGA, MCA bus. - - PCem's FPU emulation is not bit accurate and can not pass IBM's floating point tests. As a result, - this machine will always print 12903 and 162 errors on bootup. These can be ignored - F1 will boot - the machine. - - ROM files needed : - ibmps2_m70_type3/70-a_even.bin - ibmps2_m70_type3/70-a_odd.bin - - - Packard Bell PB410A (1993) - 486 at 25-120 MHz, Am5x86 at 133-160 MHz, Cx5x86 at 100-133 MHz, Pentium Overdrive - at 63-83 MHz. 1-64MB RAM. Built-in HT-216 video. - - ROM files needed: - pb410a/PB410A.080337.4ABF.U25.bin - - -Pentium based : - - ASUS P/I-P55TVP4 (1996) - Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, - Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- - PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip - 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB - RAM. - - ROM files needed: - p55tvp4/tv5i0204.awd - - - ASUS P/I-P55T2P4 (1996) - Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, - Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- - PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip - 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-512MB - RAM. - - ROM files needed: - p55t2p4/0207_j2.bin - - - Award 430VX PCI (1996) - Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, - Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- - PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip - 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB - RAM. - - ROM files needed: - 430vx\55xwuq0e.bin - - - Epox P55-VA (1997) - Pentium at 75-200 MHz, Pentium MMX at 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, - Cyrix 6x86 at PR90(80 MHz)-PR200(200 MHz), Cyrix 6x86MX/MII at PR166(133 MHz)- - PR400(285 MHz), IDT WinChip at 75-240 MHz, IDT Winchip 2 at 200-240 MHz, IDT Winchip - 2A at 200-233 MHz, AMD K6 at 166-300 MHz, AMD K6-2 at 233 to 300 (AFR-66) MHz. 1-128MB - RAM. - - ROM files needed: - p55va/va021297.bin - - - Intel Advanced/EV (Endeavor) (1995) - Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. - - The real board has a Sound Blaster 16 onboard, and optionally an S3 Trio64V+. Neither - are emulated as onboard devices. - - ROM files needed: - endeavor\1006cb0_.bi0 - endeavor\1006cb0_.bi1 - - - Intel Advanced/ZP (Zappa) (1995) - Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM. - - ROM files needed: - zappa/1006bs0_.bio - zappa/1006bs0_.bi1 - - - Intel Premiere/PCI (Batman's Revenge) (1994) - Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz. - - ROM files needed: - revenge\1009af2_.bi0 - revenge\1009af2_.bi1 - - - Itautec Infoway Multimidia (1996) - Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 8-128MB RAM. - - ROM files needed: - infowaym/1006bs0_.bio - infowaym/1006bs0_.bi1 - - - Packard Bell PB520R (Robin LC) (1995) - Pentium at 60-66 MHz, Pentium OverDrive at 120-133 MHz, 1-128MB RAM, built-in Cirrus - Logic GD-5434. - - ROM files needed: - pb520r/1009bc0r.bio - pb520r/1009bc0r.bi1 - pb520r/gd5434.bin - - - Packard Bell PB570 (Hillary) (1995) - Pentium at 75-133 MHz, Pentium Overdrive at 125-200 MHz, 1-128MB RAM, built-in Cirrus - Logic GD-5430. - - ROM files needed: - pb570/1007by0r.bio - pb570/1007by0r.bi1 - pb570/gd5430.bin - - -Super Socket 7 : - - FIC VA-503+ (1998) - AMD K6 at 166-300 MHz, AMD K6-2 at 233-550 MHz, AMD K6-III at 400-450 MHz, AMD K6-2+ - at 450-550 MHz, AMD K6-III+ at 400-500 MHz, Pentium at 75-200 MHz, Pentium MMX at - 166-233 MHz, Mobile Pentium MMX at 120-300 MHz, Cyrix 6x86 at PR90(80 MHz)-PR200(200 - MHz), Cyrix 6x86MX/MII at PR166(133 MHz)-PR400(285 MHz), IDT WinChip at 75-240 MHz, - IDT WinChip2 at 200-250 MHz, IDT Winchip 2A at PR200(200 MHz)-PR300(250 MHz). 1-512MB - RAM. - - ROM files needed: - fic_va503p/je4333.bin - - - -PCem emulates the following graphics adapters : - - MDA (1981) - 80x25 monochrome text. - - - CGA (1981) - 40x25 and 80x25 text, 320x200 in 4 colours, 620x200 in 2 colours. Supports composite - output for ~16 colours. - - - Hercules (1982) - 80x25 monochrome text, 720x348 in monochrome. - - - Plantronics ColorPlus - An enhanced CGA board, with support for 320x200x16 and 640x200x4. - - - Wyse WY-700 - A CGA-compatible board, with support for a 1280x800 mode - - - MDSI Genius - Mono portrait board, with support for a 728x1008 mode. - - ROM files needed: - 8x12.bin - - - IBM EGA (1984) - Text up to 80x43, graphics up to 640x350 in 16 colours. - - ROM files needed: - ibm_6277356_ega_card_u44_27128.bin - - - ATI EGA Wonder 800+ - An enhanced EGA-compatible board, with support for up to 800x600 in 16 colours - - ROM files needed: - ATI EGA Wonder 800+ N1.00.BIN - - - Hercules InColor - An enhanced Hercules with a custom 720x350 16 colour mode. - - -Unaccelerated (S)VGA cards : - - ATI Korean VGA - ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. Korean font support. - - ROM files needed: - atikorvga.bin - ati_ksc5601.rom - - - ATI VGA Edge-16 - ATI-18800 based. 512kb VRAM, supports up to 8-bit colour. - - ROM files needed: - vgaedge16.vbi - - - ATI VGA Charger - ATI-28800 based. 512kb VRAM, supports up to 8-bit colour. - - ROM files needed: - bios.bin - - - AVGA2 - Also known as Cirrus Logic GD5402. 256-512kb VRAM, supports up to 8-bit colour. - - ROM files needed: - avga2vram.vbi - - - IBM VGA (1987) - 256kb VRAM, Text up to 80x50, graphics up to 320x200 in 256 colours or 640x480 in 16 colours. - - ROM files needed: - ibm_vga.bin - - - OAK OTI-037C - 256kb VRAM, supports up to 8-bit colour. - - ROM files needed: - oti037\bios.bin - - - OAK OTI-067 - 256kb-512kb VRAM, supports up to 8-bit colour. - - ROM files needed: - oti067\bios.bin - - - Olivetti GO481 (Paradise PVGA1A) - 256kb VRAM, supports up to 8-bit colour. - - ROM files needed : - oli_go481_lo.bin - oli_go481_hi.bin - - - Trident 8900D SVGA - 256kb-1MB VRAM, supports up to 24-bit colour. - - ROM files needed: - trident.bin - - - Trident TGUI9400CXi - 1-2MB VRAM, supports up to 24-bit colour. - - ROM files needed: - 9440.vbi - - - Tseng ET4000AX SVGA - 1MB VRAM, supports up to 8-bit colour. - - ROM files needed: - et4000.bin - - -2D accelerated SVGA cards : - - ATI Graphics Pro Turbo - Mach64GX based. 1-4MB VRAM. - - ROM files needed: - mach64gx\bios.bin - - - ATI Video Xpression - Mach64VT2 based. 2-4MB VRAM. Has video acceleration. - - ROM files needed : - atimach64vt2pci.bin - - - Cirrus Logic GD-5428 - 1-2MB VRAM. - - ROM files needed: - Machspeed_VGA_GUI_2100_VLB.vbi - - - Cirrus Logic GD-5429 - 1-2MB VRAM. - - ROM files needed: - 5429.vbi - - - Cirrus Logic GD-5430 - 1-2MB VRAM. - - ROM files needed: - gd5430/pci.bin - - - Cirrus Logic GD-5434 - 2-4MB VRAM. Real chip also supports 1MB configurations, however this is not currently - supported in PCem. - - ROM files needed: - gd5434.bin - - - Diamond Stealth 32 SVGA - ET4000/W32p based. 1-2MB VRAM. - - ROM files needed: - et4000w32.bin - - - IBM 1MB SVGA Adapter/A - Cirrus Logic GD5428 based. 1 MB VRAM. Only supported on PS/2 models. - - ROM files needed: - SVGA141.ROM - - Number Nine 9FX - S3 Trio64 based. 1-2MB VRAM. - - ROM files needed: - s3_764.bin - - - Paradise Bahamas 64 - S3 Vision864 based. 1-4MB VRAM. - - ROM files needed: - bahamas64.bin - - - Phoenix S3 Trio32 - S3 Trio32 based. 512kb-2MB VRAM. - - ROM files needed: - 86c732p.bin - - - Phoenix S3 Trio64 - S3 Trio64 based. 1MB-4MB VRAM. - - ROM files needed: - 86c764x1.bin - - - Trident TGUI9440 - Trident TGUI9440 based. 1-2MB VRAM. - - ROM files needed: - 9440.vbi - - -3D accelerated SVGA cards : - - Diamond Stealth 3D 2000 - S3 ViRGE/325 based. 2-4MB VRAM. - - PCem emulates the ViRGE S3D engine in software. This works with most games I tried, but - there may be some issues. The Direct3D drivers for the /325 are fairly poor (often showing - as missing triangles), so use of the /DX instead is recommended. - - The streams processor (video overlay) is also emulated, however many features are missing. - - ROM files needed: - s3virge.bin - - - S3 ViRGE/DX - S3 ViRGE/DX based. 2-4MB VRAM. - - The drivers that come with Windows are similar to those for the /325, however better ones - do exist (try the 8-21-1997 version). With the correct drivers, many early Direct3D games - work okay (if slowly). - - ROM files needed: - 86c375_1.bin - - -3D only cards : - - 3DFX Voodoo Graphics - 3D accelerator. Widely supported in late 90s games. - - PCem emulates this in software. The emulation is a lot faster than in v10 (thanks to a new - dynamic recompiler) and should be capable of hitting Voodoo 1 performance on most machines - when two render threads are used. As before, the emulated CPU is the bottleneck for most games. - - PCem can emulate 6 and 8 MB configurations, but defaults to 4 MB for compatibility. It can also - emulate the screen filter present on the original card, though this does at present have a - noticeable performance hit. - - Almost everything I've tried works okay, with a very few exceptions - Screamer 2 and Rally have - serious issues. - - - Obsidian SB50 - Voodoo Graphics with 2 TMUs. Drivers for this are a bit limited - the official drivers don't - support 2 TMUs in Direct3D. - - - Voodoo 2 - Improved Voodoo Graphics - higher clocks, 2 TMUs, triangle setup etc. - - PCem can emulate both 8 and 12 MB configurations. It can also emulate 6 and 10 MB configurations - (with 2MB framebuffer memory), which were never sold into the PC market but do exist for arcade - systems. - - -Some models have fixed graphics adapters : - - Amstrad MegaPC - Paradise 90C11. A development of the PVGA1, with 512kb VRAM. Can use external video card. - - Acer 386SX/25N - Oak OTI-067. Another 512kb SVGA clone. Can use external video card. - - Amstrad PC1512 - CGA with a new mode (640x200x16). - - Amstrad PC1640 - Paradise EGA. Can use external video card. - - Amstrad PC2086/PC3086 - Paradise PVGA1. An early SVGA clone with 256kb VRAM. Can use external video card. - - Amstrad PPC512/640 - CGA/MDA outputting to 640x200 plasma display. Can use external video card. - - Commodore SL386SX-25 - AVGA2 with 256-512kb VRAM. - - Elonex PC-425X - Trident TGUI9400CXi with 512kb VRAM. - - IBM PCjr - CGA with various new modes - 160x200x16, 320x200x16, 640x200x4. - - IBM PS/1 Model 2011 - Stock VGA with 256kb VRAM. - - IBM PS/1 Model 2121 - Basic (and unknown) SVGA with 256kb VRAM. - - IBM PS/2 machines - Stock VGA with 256kb VRAM. - - Olivetti M24 - CGA with double-res text modes and a 640x400 mode. I haven't seen a dump of the font - ROM for this yet, so if one is not provided the MDA font will be used - which looks slightly odd - as it is 14-line instead of 16-line. - - Packard Bell PB410A - Headland HT-216. Can use external video card. - - Packard Bell PB520R - Cirrus Logic GD-5434. Can use external video card. - - Packard Bell PB570 - Cirrus Logic GD-5430. Can use external video card. - - Sinclair PC200 - CGA. Can use external video card. Internal video can output to a TV, as this is a UK machine - this runs at 50 Hz. - - Tandy 1000 - Clone of PCjr video. Widely supported in 80s games. - - Tandy 1000 SL/2 - Improvement of Tandy 1000, with support for 640x200x16. - - Toshiba T-series - CGA on built-in LCD or plasma display. - - - -PCem emulates the following sound devices : - - PC speaker - The standard beeper on all PCs. Supports samples/RealSound. - - Tandy PSG - The Texas Instruments chip in the PCjr and Tandy 1000. Supports 3 voices plus - noise. I reused the emulator in B-em for this (slightly modified). - PCem emulates the differences between the SN76496 (PCjr and Tandy 1000), and the NCR8496 - (currently assigned to the Tandy 1000HX). Maniac Mansion and Zak McKraken will only sound - correct on the latter. - - Tandy PSSJ - Used on the Tandy 1000SL/2, this clones the NCR8496, adding an addition frequency divider (did any - software actually use this?) and an 8-bit DAC. - - PS/1 audio card - An SN76496 clone plus an 8-bit DAC. The SN76496 isn't at the same address as PCjr/Tandy, so most - software doesn't support it. - - Gameblaster - The Creative Labs Gameblaster/Creative Music System, Creative's first sound card - introduced in 1987. Has two Philips SAA1099, giving 12 voices of square waves plus 4 noise - voices. In stereo! - - Adlib - Has a Yamaha YM3812, giving 9 voices of 2 op FM, or 6 voices plus a rhythm section. PCem - uses the DOSBox dbopl emulator. - - Adlib Gold - OPL3 with YM318Z 12-bit digital section. Possibly some bugs (not a lot of software to test). - The surround module is now emulated. - - Sound Blaster - Several Sound Blasters are emulated : - SB v1.0 - The original. Limited to 22khz, and no auto-init DMA (can cause crackles sometimes). - SB v1.5 - Adds auto-init DMA - SB v2.0 - Upped to 41khz - SB Pro v1.0 - Stereo, with twin OPL2 chips. - SB Pro v2.0 - Stereo, with OPL 3 chip - SB 16 - 16 bit stereo - SB AWE32 - SB 16 + wavetable MIDI. This requires a ROM dump from a real AWE32. - All are set to Address 220, IRQ 7 and DMA 1 (and High DMA 5). IRQ and DMA can be changed for the - SB16 & AWE32 in the drivers. - The relevant SET line for autoexec.bat is - SET BLASTER = A220 I7 D1 Tx - where Tx is T1 for SB v1.0, T3 for SB v2.0, T4 for SB Pro, - and T6 for SB16. - - AWE32 requires a ROM dump called awe32.raw. AWE-DUMP is a utility which can get a dump from a real - card. Most EMU8000 functionality should work, however filters are not correct and reverb/chorus - effects are not currently emulated. - - Gravis Ultrasound - 32 voice sample playback. Port address is fixed to 240, IRQ and DMA can be changed from the drivers. - Emulation is improved significantly over previous versions. - - Windows Sound System - 16-bit digital + OPL3. Note that this only emulates WSS itself, and should not be used with drivers - from compatible boards with additional components (eg Turtle Beach Monte Carlo) - - Aztech Sound Galaxy Pro 16 AB (Washington) - SB compatible + WSS compatible - - Innovation SSI-2001 - SID6581. Emulated using resid-fp. Board is fixed to port 280. - - Ensoniq AudioPCI (ES1371) / Sound Blaster PCI 128 - Basic PCI sound card. Emulates Sound Blaster in software. - - -PCem emulates the following hard drive controllers : - - [MFM] Fixed Disk Adapter (Xebec) - MFM controller originally included in the IBM XT. This controller only supports HD types 0, 2, 13 - and 16. - - ROM files needed : - ibm_xebec_62x0822_1985.bin - - - [MFM] DTC 5150X - 8-bit MFM controller. To configure drive types, run DEBUG.EXE and enter 'g=c800:5'. - - ROM files needed : - dtc_cxd21a.bin - - - [MFM] AT Fixed Disk Adapter - MFM controller originally included in the IBM AT. Supported by all AT-compatible BIOSes. - - - [ESDI] Western Digital WD1007V-SE1 - 16-bit ESDI controller. - - ROM files needed : - 62-000279-061.bin - - - [ESDI] IBM ESDI Fixed Disk Controller - MCA ESDI controller. Only supported on PS/2 models. - - ROM files needed : - 90x8969.bin - 90x8970.bin - - - [IDE] Standard IDE - Standard IDE controller. Supported by all AT-compatible BIOSes. Use this if in any doubt! - - - [IDE] XTIDE - 8-bit IDE controller. The BIOS is available at : - - http://code.google.com/p/xtideuniversalbios/ - - v2.0.0 beta 1 is the version I've mostly tested. v2.0.0 beta 3 is known to have some issues. - - ROM files needed : - ide_xt.bin - - - [IDE] XTIDE (AT) - 16-bit IDE controller. - - ROM files needed : - ide_at.bin - - - [IDE] XTIDE (PS/1) - IDE controller for the PS/1 model 2033. For this machine you will need BIOS version v1.1.5. The - PS/1 is a bit fussy with XTIDE, and I've found that it works best when the XTIDE configuration - has 'Full Operating Mode' disabled. - - ROM files needed : - ide_at_1_1_5.bin - - - [SCSI] Longshine LCS-6821N - 8-bit SCSI controller. - - ROM files needed : - Longshine LCS-6821N - BIOS version 1.04.bin - - - [SCSI] Rancho RT1000B - 8-bit SCSI controller. - - ROM files needed : - Rancho_RT1000_RTBios_version_8.10R.bin - - - [SCSI] Trantor T130B - 8-bit SCSI controller. - - ROM files needed : - trantor_t130b_bios_v2.14.bin - - - [SCSI] IBM SCSI Adapter with Cache - MCA SCSI controller. Only supported on PS/2 models. - - ROM files needed : - 92F2244.U68 - 92F2245.U69 - - - [SCSI] Adaptec AHA-1542C - 16-bit SCSI controller. - - ROM files needed : - adaptec_aha1542c_bios_534201-00.bin - - - [SCSI] BusLogic BT-545S - 16-bit SCSI controller. - - ROM files needed : - BusLogic_BT-545S_U15_27128_5002026-4.50.bin - - -Other stuff emulated : - -Serial mouse - A Microsoft compatible serial mouse on COM1. Compatible drivers are all over the place for this. - -M24 mouse - I haven't seen a DOS mouse driver for this yet, but the regular scancode mode works, as does the - Windows 1.x driver. - -PC1512 mouse - The PC1512's perculiar quadrature mouse. You need Amstrad's actual driver for this one. - -PS/2 mouse - A standard 2 button PS/2 mouse. As with serial, compatible drivers are common. - -Microsoft PS/2 Intellimouse - A PS/2 mouse with mouse wheel. - -ATAPI CD-ROM - Works with OAKCDROM.SYS, VDD-IDE.SYS, and the internal drivers of every OS I've tried. - - - - - -Software tested: - -PC-DOS 1.0 -PC-DOS 2.10 -PC-DOS 3.30 -MS-DOS 3.30 -MS-DOS 3.31 -PC-DOS 4.0 -MS-DOS 4.01 -PC-DOS 5.02 -MS-DOS 6.22 - -Windows 1.03 -Windows 2.03 -Windows/286 2.11 -Windows/386 2.11 -Windows 3.0 -Windows 3.1 -Windows for Workgroups 3.11 -Windows 95 -Windows 95 OSR2 -Windows 98SE -Windows ME - -Windows NT 3.1 -Windows NT 3.51 -Windows NT 4 Workstation (SP6a) -Windows 2000 -Windows XP - -OS/2 v1.0 -OS/2 v1.1 -OS/2 v1.2 -OS/2 v1.3 -OS/2 v2.1 -OS/2 Warp 3 -OS/2 Warp 4 - -Corel Linux 1.2 -Red Hat Linux 7.1 (Seawolf) -SuSE Linux 6.3 -Ubuntu 6.06.1 - -BeOS 5.0 Personal Edition -BeOS 5.0 Professional Edition - -CorelDRAW! v2.5 for OS/2 -Cubasis -Fasttracker 2.08 -Lotus SmartSuite 97 -Microsoft Office 95 -Microsoft Word 1.1 for OS/2 -Microsoft Word 1.1 for Windows -Microsoft Word 2.0 -Microsoft Word 6.1 -Microsoft Works for Windows 3.0 -Mozilla Firefox 1.5.0.5 -Visual Basic 4.0 -Winzip 6.2 - -3-Demon -Abuse -Abuse (demo) -Actua Soccer -Age of Empires -Aladdin -Aladdin (demo) -Alien Breed : Tower Assault (demo) -Alien Carnage (shareware) -Alien vs Predator -All New World of Lemmings -American McGee's Alice -Apache (demo) -Atomic Bomberman -Backtrack (demo) -Balls of Steel (demo) -Battlezone -Battlezone (1998) -Battlezone II -Big Red Racing -Bio Menace (shareware) -Blackthorne (demo) -Blake Stone (shareware) -Blast Doors -Blood (demo) -Blood 2 -Breakneck -Brix (shareware) -Bust-a-Move 2 : Arcade Edition -Cannon Fodder 2 -Caesar III -Captain Claw -Carmageddon -Carnivores 2 -Catacomb Abyss (demo) -Carmageddon (demo) -CD-MAN -Charlie the Duck (demo) -Clusterball -Colin McRae Rally -Colonization -Command and Conquer (demo) -Command and Conquer : Red Alert -Commander Keen : Goodbye Galaxy -Commander Keen : Invasion of the Vorticons -Corridor 7 -Counter-Strike 2D -Curse of Monkey Island -Cyril Cyberpunk (demo) -Dark Forces (demo) -Dark Forces -Dawn Patrol -Death Rally -Descent (v1.4) -Descent (demo) -Desert Strike -Destruction Derby -Destruction Derby (demo) -Deus Ex -Diablo -Digger -Discworld II -Dogz -Doom (v1.2) -Doom (shareware) -Doom II (v1.666) -Doom II for Windows 95 -Dune -Dune II -Duke Nukem (shareware) -Duke Nukem 3D (shareware) -DX-Ball 2 -Earthworm Jim (demo) -Ecstatica -Epic Pinball -Epic Pinball (shareware) -Eradicator -Expendable -Expendable (demo) -Extreme Assault -Final Fantasy VII -Flashback (demo) -Frogger -Frogger (1998) -Frontier : First Encounters -Full Throttle (demo) -G-Police -Galactix -GLQuake (v0.93) -Gods (demo) -Grand Theft Auto -Grand Theft Auto 2 -Grim Fandango -Half-Life (1.0.0.9) -Heartlight (shareware) -Heretic -Heretic (demo) -Hexen -Hexen (demo) -Hexen95 -Hocus Pocus (shareware) -House of the Dead 2 -Hover! -Incoming -Indiana Jones and the Fate of Atlantis (demo) -Indy Car Racing 2 (demo) -Interstate 76 Nitro Riders -Interstate 82 -Jazz Jackrabbit (shareware) -Jazz Jackrabbit 2 -Jedi Knight -Jumpman -Kings Quest -Kings Quest II -Lamborghini American Challenge (demo) -LBA 2 -Lemmings -Lemmings (demo) -Lemmings 2 : The Tribes -Lemmings Paintball -Lotus III -Mageslayer -Magic Carpet -MDK -MegaMan X (demo) -Metal Gear Solid -Microsoft Arcade -Monster Bash (shareware) -Mortal Kombat -Mortal Kombat II -Mortal Kombat Trilogy -Moto Racer -NASCAR Heat -NBA Hangtime -Need for Speed (demo) -Need for Speed II SE -Need for Speed III -Nerf Arena Blast -Network Q RAC Rally -No One Lives Forever -No One Lives Forever (tech demo) -Oddworld : Abe's Oddysee -Out of this World (demo) -Panzer Dragoon -Pinball Fantasies -Pinball Illusions -Populous : The Beginning -Prince of Persia (demo) -Prince of Persia 2 (demo) -Pro Pinball : Big Race USA -Pro Pinball : Timeshock! -Pro Pinball : The Web -Project X (demo) -Psycho Pinball -Quake (v1.01) -Quake (shareware) -Quake II -Quake III Arena (1.27g) -Quake III Arena (1.30) -Radix (demo) -Railroad Tycoon II (demo) -Raptor (shareware) -Rayman -Realms of Chaos (shareware) -Red Faction -Resident Evil 2 -Return to Castle Wolfenstein (v1.32) -Rise of the Triad (shareware) -Road Rash -Rogue Spear (demo) -Rollcage (demo) -Rollercoaster Tycoon -Sam and Max Hit the Road (demo) -Screamer -Screamer 2 (demo) -Screamer Rally (NOT 3DFX) -Secret of Monkey Island (demo) -Serious Sam -Shadow Warrior (demo) -Simcity 2000 -Simcity 2000 (demo) -Simcity 2000 for OS/2 Warp -SimCity 3000 -Simcopter -Sonic 3 & Knuckles -Speed Haste (demo) -Star Trek Voyager : Elite Force -Stargunner -Street Racer (demo) -Streets of Simcity -Striker 95 -Super Angelo (demo) -Superkarts -Super Street Fighter 2 (demo) -Syndicate -Syndicate (demo) -System Shock -Tennis Elbow (demo) -Terminal velocity -Terminal Velocity (shareware) -The Adventures of Captain Comic -The Chaos Engine -The Chaos Engine (demo) -The Humans -The Incredible Machine (demo) -The Lion King -The Lion King (demo) -Thief II -Theme Hospital -Theme Hospital (demo) -Theme Park -Threat (demo) -Tie Fighter (demo) -Tomb Raider -Tomb Raider (demo) -Tomb Raider II -Tomb Raider III -Tony Hawk's Pro Skater 2 -Transport Tycoon -Transport Tycoon Deluxe -Turok (demo) -Tyrian -Tyrian (shareware) -UFO : Enemy Unknown -Ultimate Doom (v1.9) -Unreal -Unreal Gold -Unreal Tournament -Unreal Tournament (v436 GOTY) -Virtual Pool (demo) -Wacky Wheels -Warcraft (demo) -Warcraft II (demo) -Wing Commander -Wolfenstein 3D (v1.4) -Wolfenstein 3D (shareware) -World Cup 98 -Worms -Worms (demo) -Worms 2 -Worms World Party -X-Com : Terror From The Deep -X-Wing -Z (demo) -Z.A.R. (demo) -Zone 66 -Zone 66 (shareware) - -Cascada - Cronologia -Complex - Cyboman 2 -EMF - Verses -Exceed - Heaven 7 -Future Crew - Second Reality -Gazebo - Cyboman! -KFMF - Dance, Move, Shake -KFMF - Trip -Logic Design - Fashion -Orange - x14 -Renaissance - Amnesia -Skull - Putre Faction -Tran - Ambience -Tran - Luminati -Tran - Timeless -Triton - Crystal Dream II -Triton - Crystal Dream -Ultraforce - Coldcut -Ultraforce - Vector Demo - -BeebInC v0.99f -Fellow v0.3.3 -KGen98 v0.4 -PaCifiST v0.45 -SNES9x v0.96 -UltraHLE v1.0.0 -vMac v0.1.9.1 -ZSNES v0.800c diff --git a/tested.html b/tested.html new file mode 100644 index 0000000..0480f1d --- /dev/null +++ b/tested.html @@ -0,0 +1,493 @@ + + + + + + + tested + + + + +

Software tested (v17):

+

DOS

+
    +
  • PC-DOS 1.0
  • +
  • MS-DOS 2.11
  • +
  • MS-DOS 3.30
  • +
  • MS-DOS 4.01
  • +
  • MS-DOS 5.0
  • +
  • MS-DOS 6.0
  • +
  • MS-DOS 6.22
  • +
+

Windows

+
    +
  • Windows 1.04
  • +
  • Windows/286 2.11
  • +
  • Windows/386 2.11
  • +
  • Windows 3.0
  • +
  • Windows 3.1
  • +
  • Windows for Workgroups 3.11
  • +
  • Windows 95
  • +
  • Windows 95 OSR2
  • +
  • Windows 98SE
  • +
  • Windows ME
  • +
+

Windows NT

+
    +
  • Windows NT 3.1
  • +
  • Windows NT 3.51
  • +
  • Windows NT 4 Workstation (SP6a)
  • +
  • Windows 2000
  • +
  • Windows XP
  • +
+

OS/2

+
    +
  • OS/2 v1.0
  • +
  • OS/2 v1.1
  • +
  • OS/2 v1.2
  • +
  • OS/2 v1.3
  • +
  • OS/2 v2.1
  • +
  • OS/2 Warp 3
  • +
  • OS/2 Warp 4
  • +
+

Linux

+
    +
  • Corel Linux 1.2
  • +
  • Mandriva LE 2005
  • +
  • Red Hat Linux 7.1 (Seawolf)
  • +
+

BeOS

+
    +
  • BeOS 5.0 Professional Edition
  • +
+

Applications

+
    +
  • 3DMark 2000
  • +
  • 3DMark 2001SE
  • +
  • After Dark 3.06
  • +
  • Cinemania 1994
  • +
  • Creative Writer
  • +
  • Cubasis
  • +
  • Encarta 1994
  • +
  • Fasttracker v2.08
  • +
  • PageMaker 5.0
  • +
  • PC Paintbrush 1.05
  • +
  • Photoshop 3.0
  • +
  • Smartsuite 97
  • +
  • Visual Basic 3.0
  • +
  • Visual C++ 6.0
  • +
  • Word for Windows 2.0
  • +
  • Winzip 6.2
  • +
+

Games

+
    +
  • 1602 AD (demo)
  • +
  • 3D Ultra Pinball Thrillride
  • +
  • A-10 Tank Killer
  • +
  • Actua Soccer
  • +
  • Adventure Pinball Forgotten Island (demo)
  • +
  • Aladdin
  • +
  • Alien vs Predator
  • +
  • Alien vs Predator 2 (demo)
  • +
  • All New World of Lemmings
  • +
  • Alone in the Dark
  • +
  • Alone in the Dark : The New Nightmare (demo)
  • +
  • Anachronox
  • +
  • Arkanoid
  • +
  • Armoured Fist 3 (demo)
  • +
  • Asteroids (1998)
  • +
  • B-17 Flying Fortress
  • +
  • Battle Chess
  • +
  • Battlezone
  • +
  • Battlezone II
  • +
  • Bejeweled
  • +
  • Beyond Castle Wolfenstein
  • +
  • Big Red Racing
  • +
  • Bio Menace
  • +
  • Black & White
  • +
  • Brix
  • +
  • Bugs Bunny Lost In Time (demo)
  • +
  • Cannon Fodder 2
  • +
  • Carnivores 2
  • +
  • Civilization
  • +
  • Civilization for Windows
  • +
  • Claw
  • +
  • Clive Barker's Undying (demo)
  • +
  • Clockwiser
  • +
  • Command & Conquer : Red Alert
  • +
  • Command & Conquer : Red Alert 2
  • +
  • Command & Conquer : Tiberian Sun (demo)
  • +
  • Command & Conquer Renegade
  • +
  • Conquest
  • +
  • Corridor 7
  • +
  • Counter-Strike 2D
  • +
  • Crimson Skies (demo)
  • +
  • Croc
  • +
  • Curse of Monkey Island
  • +
  • Cutthroats (demo)
  • +
  • Daikatana
  • +
  • Dawn Patrol
  • +
  • Day of the Tentacle
  • +
  • Dance Dance Revolution
  • +
  • Dead Reckoning (demo)
  • +
  • Death Drome
  • +
  • Desert Strike
  • +
  • Digger
  • +
  • Dirt Track Racing (demo)
  • +
  • Disciples (demo)
  • +
  • Discworld II
  • +
  • Doom (v1.2)
  • +
  • Doom II (v1.666)
  • +
  • Double Dragon
  • +
  • Drakan (demo)
  • +
  • Duke Nukem 3D (v1.3D)
  • +
  • Dune
  • +
  • DX-Ball 2
  • +
  • Echelon
  • +
  • Ecstatica
  • +
  • Epic Pinball
  • +
  • Every Extend
  • +
  • Evolva (demo)
  • +
  • Expendable
  • +
  • Eye of the Beholder
  • +
  • Fallout Tactics (demo)
  • +
  • Final Fantasy VIII (demo)
  • +
  • Flashback
  • +
  • Flight Simulator 5
  • +
  • Frogger
  • +
  • Frontier : First Encounters
  • +
  • Gabriel Knight 3 (demo)
  • +
  • Giants : Citizen Kabuto
  • +
  • GLQuake
  • +
  • Grand Theft Auto 2
  • +
  • Half-Life
  • +
  • Halloween Harry
  • +
  • Heartlight
  • +
  • Hellbender
  • +
  • Hexen
  • +
  • High Heat Baseball 2002 (demo)
  • +
  • Hitch Hiker's Guide to the Galaxy
  • +
  • Hocus Pocus
  • +
  • Homeworld Cataclysm (demo)
  • +
  • Incoming
  • +
  • James Pond 2 : Robocod
  • +
  • Jazz Jackrabbit
  • +
  • Jazz Jackrabbit 2
  • +
  • Jill of the Jungle
  • +
  • King's Quest
  • +
  • King's Quest II
  • +
  • King's Quest III
  • +
  • Lemmings
  • +
  • Lemmings 2 : The Tribes
  • +
  • Lode Runner : The Legend Continues
  • +
  • Lotus III
  • +
  • Madden 2002 (demo)
  • +
  • Majesty (demo)
  • +
  • Maniac Mansion (enhanced)
  • +
  • Max Payne
  • +
  • MDK (Direct3D, USA release)
  • +
  • MechCommander 2
  • +
  • Mechwarrior 2
  • +
  • Mechwarrior 3
  • +
  • Megaman Legends
  • +
  • Metal Gear Solid
  • +
  • Microsoft Arcade
  • +
  • Microsoft Golf 99 (demo)
  • +
  • Midtown Madness 2 (demo)
  • +
  • Monaco Grand Prix (demo)
  • +
  • Monkey Island 2
  • +
  • Monster Bash
  • +
  • Monster Truck Madness
  • +
  • Mortal Kombat
  • +
  • Mortal Kombat 2
  • +
  • Mortal Kombat 3
  • +
  • Motorcross Madness (demo)
  • +
  • Mystic Towers
  • +
  • Nascar Heat
  • +
  • Need for Speed II SE
  • +
  • Need for Speed III
  • +
  • Need for Speed : High Stakes
  • +
  • NHL 2001 (demo)
  • +
  • No One Lives Forever
  • +
  • Oddworld : Abe's Exoddus
  • +
  • One Must Fall 2097
  • +
  • Oni
  • +
  • Outlaws
  • +
  • Pacific Strike
  • +
  • Pacman Adventures in Time (demo)
  • +
  • Pharoah (demo)
  • +
  • Pinball Fantasies
  • +
  • Pinball Illusions
  • +
  • Police Quest
  • +
  • Police Quest 2
  • +
  • Porrasturvat
  • +
  • Power Drive
  • +
  • Prince of Persia
  • +
  • Prince of Persia 3D (demo)
  • +
  • Pro Pinball : The Web
  • +
  • Psycho Pinball
  • +
  • Quake
  • +
  • Quake II
  • +
  • Quake III Arena
  • +
  • Rayman 2 (demo)
  • +
  • Red Faction
  • +
  • Redline Racer
  • +
  • Rise of the Triad (v1.2)
  • +
  • Screamer
  • +
  • Sega Rally 2 (demo)
  • +
  • Sensible World of Soccer
  • +
  • Settlers 3 (demo)
  • +
  • Severance : Blade of Darkness (demo)
  • +
  • Shadow Company (demo)
  • +
  • Shadow Warrior
  • +
  • Shadowman (demo)
  • +
  • Sid Meier's Alien Crossfire (demo)
  • +
  • SimCity 2000
  • +
  • SimCity Classic
  • +
  • SimTower
  • +
  • Sink or Swim
  • +
  • Soldat (1.0.5)
  • +
  • Sonic CD
  • +
  • Space Simulator
  • +
  • Space Strike
  • +
  • Spider-Man (demo)
  • +
  • Springy Madness
  • +
  • Star Trek Hidden Evil (demo)
  • +
  • Star Trek Voyager Elite Force
  • +
  • Star Wars Jedi Academy
  • +
  • Starfleet Command 2 (demo)
  • +
  • Stargunner
  • +
  • Starlancer (demo)
  • +
  • Steel Beasts (demo)
  • +
  • Stunt Island
  • +
  • SWAT 3 Elite Edition (demo)
  • +
  • Syndicate
  • +
  • System Shock
  • +
  • Tanktics (demo)
  • +
  • Terminal Velocity
  • +
  • The Dig
  • +
  • The Humans
  • +
  • The Labyrinth (RealArcade version)
  • +
  • The Lost Vikings
  • +
  • The Ultimate Doom (v1.9)
  • +
  • Theme Hospital
  • +
  • Theme Park
  • +
  • Tomb Raider
  • +
  • Tomb Raider II
  • +
  • Tomb Raider The Last Revelation (demo)
  • +
  • Tony Hawk's Pro Skater 2
  • +
  • Transport Tycoon
  • +
  • Transport Tycoon Deluxe
  • +
  • Tropico (demo)
  • +
  • Turrican 2
  • +
  • UFO : Enemy Unknown
  • +
  • Ultimate Ride (demo)
  • +
  • Unreal
  • +
  • Unreal Tournament
  • +
  • Unreal Tournament 2004 (Direct3D)
  • +
  • Wacky Wheels
  • +
  • Warlords Battlecry (demo)
  • +
  • Wheel of Time (demo)
  • +
  • Wing Commander
  • +
  • Wing Commander : Privateer
  • +
  • Wizkid
  • +
  • Wolfenstein 3D
  • +
  • World War III : Black Gold (demo)
  • +
  • Worms
  • +
  • Worms Armageddon
  • +
  • X-Com : Terror From The Deep
  • +
  • Xargon
  • +
  • Z : Steel Soldiers (demo)
  • +
  • Zak McKracken
  • +
  • Zone 66
  • +
+

Demos

+
    +
  • Cascada - Cronologia
  • +
  • Coma - Paimen
  • +
  • Complex - Cyboman 2
  • +
  • Complex - Dope
  • +
  • EMF - Verses
  • +
  • Exceed - Heaven 7
  • +
  • Future Crew - Second Reality
  • +
  • Gazebo - Cyboman
  • +
  • Halcyon - Lifeforms
  • +
  • Iguana - Heartquake
  • +
  • Impact Studios - Legend
  • +
  • Impact Studios - Project Angel
  • +
  • KFMF - Dance, Move, Shake
  • +
  • KFMF - Trip
  • +
  • Logic Design - Fashion
  • +
  • Majic 12 - Show
  • +
  • Majic 12 - Wish
  • +
  • Megabusters - Hellraiser
  • +
  • Orange - x14
  • +
  • Renaissance - Amnesia
  • +
  • Skull - Putre Faction
  • +
  • Tran - Ambience (flickery)
  • +
  • Tran - Luminati (flickery)
  • +
  • Tran - Timeless
  • +
  • Triton - Crystal Dream
  • +
  • Triton - Crystal Dream 2
  • +
  • Ultraforce - Coldcut
  • +
  • Ultraforce - Vector Demo
  • +
  • Valhalla - Solstice
  • +
  • Witan - Witan House
  • +
+

Emulators

+
    +
  • Beebem v1.02
  • +
  • BeebInC v0.99f
  • +
  • CPE v5.2i
  • +
  • DOSBox 0.74-3
  • +
  • Fellow 0.33
  • +
  • KGen98 v0.4b
  • +
  • PaCifiST v0.48
  • +
  • SNES9x v0.96
  • +
  • UltraHLE v1.0.0
  • +
  • vMac v0.1.9.1
  • +
  • ZSNES v0.800c
  • +
+ + From 54ae48c1742e3a46a4669cbfaf17ea7f05b2227c Mon Sep 17 00:00:00 2001 From: Jeremy Andrews Date: Sat, 16 Jan 2021 10:17:33 -0500 Subject: [PATCH 1008/1050] typo in linux build command missing "-build" from "--enable-release-build" option of "./configure" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 134a542..e2dba29 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ You will need the following libraries (and their dependencies): Open a terminal window, navigate to the PCem directory then enter: ### Linux ``` -./configure --enable-release +./configure --enable-release-build make ``` ### BSD From 9687a85943ad6b462afff10381629960ae23a87f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Feb 2021 19:59:08 +0000 Subject: [PATCH 1009/1050] Add keyboard controller SMI fix to Itautec Infoway. Patch from EluanCM. --- src/keyboard_at.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 44cb3ec..055c784 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -591,7 +591,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) break; case 0xba: - if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA) + if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM) keyboard_at_adddata(0); break; @@ -625,7 +625,7 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) if (romset == ROM_T3100E) keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; - if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA) + if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM) keyboard_at_adddata(keyboard_at.input_port | 4 | 0x40); else keyboard_at_adddata(keyboard_at.input_port | 4); From 55e84c338bb040603b512a8a4e5502c577b9b13f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 8 Feb 2021 20:21:52 +0000 Subject: [PATCH 1010/1050] Back out display and cursor skew changes from commit ed30e171. Fixes offset display on some SVGA cards. --- src/vid_svga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vid_svga.c b/src/vid_svga.c index a8c978e..369173d 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -322,7 +322,7 @@ void svga_recalctimings(svga_t *svga) if (svga->crtc[9] & 0x20) svga->vblankstart |= 0x200; svga->vblankstart++; - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp = svga->crtc[1]; svga->hdisp++; svga->htotal = svga->crtc[0]; @@ -660,9 +660,9 @@ void svga_poll(void *p) changeframecount = svga->interlace ? 3 : 2; svga->vslines = 0; - if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); - else svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); - svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; + if (svga->interlace && svga->oddeven) svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); + else svga->ma = svga->maback = svga->ma_latch; + svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + svga->ca_adj; svga->ma <<= 2; svga->maback <<= 2; From 40a48a4c7c43f7bb9b78c6f0bc0b8572f7e69d2b Mon Sep 17 00:00:00 2001 From: sarah-walker-pcem <67199234+sarah-walker-pcem@users.noreply.github.com> Date: Sun, 16 May 2021 09:06:00 +0100 Subject: [PATCH 1011/1050] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..8c05fbd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Emulator configuration** + - Machine: [e.g. IBM AT, AMI 486 clone etc] + - CPU: + - Graphics/sound cards: + - Installed OS + +**Host machine** + - OS: [e.g. Windows 10, Ubuntu 18.04 etc] + - Emulator version + - Any other relevant information + +**Additional context** +Add any other context about the problem here. From f63b06f5f68c5efc26b46a5e8f25a6dc83e65766 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 15:23:17 -0600 Subject: [PATCH 1012/1050] MacOS lacks 64-bit-specific offset bits for file functions: Use plain off_t-based functions if HAS_OFF64T is false. --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 8197093..734be0e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -137,7 +137,7 @@ pcem_LDADD += wx.res endif if !HAS_OFF64T -#pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell +pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello endif if RELEASE_BUILD From 33da24d0e25f36a08bc2907d4a997f9bc666700f Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 15:42:50 -0600 Subject: [PATCH 1013/1050] macOS: Add support for Apple Silicon and usage of the MAP_JIT flag. --- src/386_dynarec.c | 9 +++++++++ src/codegen_allocator.c | 4 ++++ src/pc.c | 9 +++++++++ 3 files changed, 22 insertions(+) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 9dedf44..5b7e8f4 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1,6 +1,9 @@ #include #include #include +#if defined __APPLE__ && defined __aarch64__ +#include +#endif #include "ibm.h" #include "x86.h" #include "x86_ops.h" @@ -410,6 +413,9 @@ static inline void exec_recompiler(void) cpu_new_blocks++; +#if defined __APPLE__ && defined __aarch64__ + pthread_jit_write_protect_np(0); +#endif codegen_block_start_recompile(block); codegen_in_recompile = 1; @@ -481,6 +487,9 @@ static inline void exec_recompiler(void) codegen_reset(); codegen_in_recompile = 0; +#if defined __APPLE__ && defined __aarch64__ + pthread_jit_write_protect_np(1); +#endif } else if (!cpu_state.abrt) { diff --git a/src/codegen_allocator.c b/src/codegen_allocator.c index 5807b5d..a5301d1 100644 --- a/src/codegen_allocator.c +++ b/src/codegen_allocator.c @@ -30,6 +30,10 @@ void codegen_allocator_init() #if defined WIN32 || defined _WIN32 || defined _WIN32 mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + /* TODO: check deployment target: older Intel-based versions of macOS don't play + nice with MAP_JIT. */ +#elif defined(__APPLE__) && defined(MAP_JIT) + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_JIT, 0, 0); #else mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); #endif diff --git a/src/pc.c b/src/pc.c index 6ed0be9..f362378 100644 --- a/src/pc.c +++ b/src/pc.c @@ -1,6 +1,9 @@ #include #include #include +#if defined(__APPLE__) && defined(__aarch64__) +#include +#endif #include "ibm.h" #include "device.h" @@ -307,7 +310,13 @@ void initpc(int argc, char *argv[]) loadbios(); mem_add_bios(); +#if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(0); +#endif codegen_init(); +#if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(1); +#endif timer_reset(); sound_reset(); From 20d7014e4af328709af021e88a14036846ad12cb Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 15:49:03 -0600 Subject: [PATCH 1014/1050] macOS: Rename the window only on the main thread: macOS doesn't like non-main threads modifying the UI. --- src/pc.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/pc.c b/src/pc.c index f362378..7b1b4c0 100644 --- a/src/pc.c +++ b/src/pc.c @@ -1,9 +1,13 @@ #include #include #include -#if defined(__APPLE__) && defined(__aarch64__) +#ifdef __APPLE__ +#include +#include +#ifdef __aarch64__ #include #endif +#endif #include "ibm.h" #include "device.h" @@ -519,6 +523,14 @@ int serial_fifo_read, serial_fifo_write; int emu_fps = 0; +#ifdef __APPLE__ +static void _set_window_title(void *s) +{ + set_window_title((const char *)s); + free(s); +} +#endif + void runpc() { char s[200]; @@ -594,7 +606,12 @@ void runpc() { win_title_update=0; sprintf(s, "PCem v17 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); +#ifdef __APPLE__ + // Needed due to modifying the UI on the non-main thread is a big no-no. + dispatch_async_f(dispatch_get_main_queue(), strdup(s), _set_window_title); +#else set_window_title(s); +#endif } done++; } From 1eb1cc5e5b4c1fc7266c90347325ebbbadd34b50 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 16:07:40 -0600 Subject: [PATCH 1015/1050] Include SDL2 CFlags in with the general CFlags: this fixes SDL2 build failures on macOS. Regenerate auto-conf/etc. Fix the SDL2 includes. --- Makefile.in | 35 +- aclocal.m4 | 324 ++- configure | 3656 ++++++++++++++++++++++------------ configure.ac | 1 + src/Makefile.in | 2532 ++++++++++++++++++----- src/wx-main.cc | 2 +- src/wx-sdl2-display-win.c | 2 +- src/wx-sdl2-display.c | 2 +- src/wx-sdl2-joystick.c | 2 +- src/wx-sdl2-mouse.c | 2 +- src/wx-sdl2-status.c | 2 +- src/wx-sdl2-video-gl3.c | 6 +- src/wx-sdl2-video-renderer.c | 2 +- src/wx-sdl2-video.c | 2 +- src/wx-sdl2.c | 2 +- src/wx-thread.c | 4 + 16 files changed, 4592 insertions(+), 1984 deletions(-) diff --git a/Makefile.in b/Makefile.in index 903d123..fa42541 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -133,7 +133,7 @@ am__recursive_targets = \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck + cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -196,6 +196,8 @@ am__relativize = \ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -342,8 +344,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -461,7 +463,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -526,7 +531,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -541,6 +546,10 @@ dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -552,7 +561,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -570,7 +579,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -580,9 +589,11 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -598,7 +609,7 @@ distcheck: dist $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ @@ -759,7 +770,7 @@ uninstall-am: am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-generic distclean-tags \ + dist-zstd distcheck distclean distclean-generic distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ diff --git a/aclocal.m4 b/aclocal.m4 index 925cb54..5b27abd 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.16.3 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,15 +14,15 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, +[m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29) -dnl +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl @@ -63,7 +63,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29]) +[m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -164,7 +164,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -174,11 +174,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -195,7 +195,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -372,7 +372,7 @@ AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework]) done fi - if test -d $sdl_framework; then + if test x"$sdl_framework" != x && test -d "$sdl_framework"; then AC_MSG_RESULT($sdl_framework) sdl_framework_dir=`dirname $sdl_framework` SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include" @@ -675,7 +675,8 @@ AC_DEFUN([_WX_PRIVATE_CHECK_VERSION], dnl --------------------------------------------------------------------------- dnl WX_CONFIG_CHECK(VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND -dnl [, WX-LIBS [, ADDITIONAL-WX-CONFIG-FLAGS]]]]) +dnl [, WX-LIBS [, ADDITIONAL-WX-CONFIG-FLAGS +dnl [, WX-OPTIONAL-LIBS]]]]]) dnl dnl Test for wxWidgets, and define WX_C*FLAGS, WX_LIBS and WX_LIBS_STATIC dnl (the latter is for static linking against wxWidgets). Set WX_CONFIG_NAME @@ -692,6 +693,10 @@ dnl Optional ADDITIONAL-WX-CONFIG-FLAGS argument is appended to wx-config dnl invocation command in present. It can be used to fine-tune lookup of dnl best wxWidgets build available. dnl +dnl Optional WX-OPTIONAL-LIBS argument contains comma- or space-separated list +dnl of wxWidgets libraries to link against if they are available. +dnl WX-OPTIONAL-LIBS is supported on version 2.9.0 and later. +dnl dnl Example use: dnl WX_CONFIG_CHECK([2.6.0], [wxWin=1], [wxWin=0], [html,core,net] dnl [--unicode --debug]) @@ -743,8 +748,8 @@ AC_DEFUN([WX_CONFIG_CHECK], AC_MSG_CHECKING([for wxWidgets version >= $min_wx_version ($5)]) fi - dnl don't add the libraries ($4) to this variable as this would result in - dnl an error when it's used with --version below + dnl don't add the libraries (4th argument) to this variable as this would + dnl result in an error when it's used with --version below WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args $5" WX_VERSION=`$WX_CONFIG_WITH_ARGS --version 2>/dev/null` @@ -768,14 +773,20 @@ AC_DEFUN([WX_CONFIG_CHECK], if test -n "$wx_ver_ok"; then AC_MSG_RESULT(yes (version $WX_VERSION)) - WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs $4` + + wx_optional_libs="" + _WX_PRIVATE_CHECK_VERSION(2,9,0) + if test -n "$wx_ver_ok" -a -n "$6"; then + wx_optional_libs="--optional-libs $6" + fi + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs $4 $wx_optional_libs` dnl is this even still appropriate? --static is a real option now dnl and WX_CONFIG_WITH_ARGS is likely to contain it if that is dnl what the user actually wants, making this redundant at best. dnl For now keep it in case anyone actually used it in the past. AC_MSG_CHECKING([for wxWidgets static library]) - WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs $4 2>/dev/null` + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs $4 $wx_optional_libs 2>/dev/null` if test "x$WX_LIBS_STATIC" = "x"; then AC_MSG_RESULT(no) else @@ -1052,7 +1063,7 @@ AC_DEFUN([WX_ARG_ENABLE_YESNOAUTO], $2=0 elif test "$enableval" = "auto" ; then AC_MSG_RESULT([will be automatically detected]) - $2="auto" + $2="" else AC_MSG_ERROR([ Unrecognized option value (allowed values: yes, no, auto) @@ -1078,7 +1089,7 @@ AC_DEFUN([WX_ARG_WITH_YESNOAUTO], $2=0 elif test "$withval" = "auto" ; then AC_MSG_RESULT([will be automatically detected]) - $2="auto" + $2="" else AC_MSG_ERROR([ Unrecognized option value (allowed values: yes, auto) @@ -1130,17 +1141,17 @@ AC_DEFUN([WX_STANDARD_OPTIONS], AC_MSG_CHECKING([for the --with-toolkit option]) if test "$withval" = "auto" ; then AC_MSG_RESULT([will be automatically detected]) - TOOLKIT="auto" + TOOLKIT="" else TOOLKIT="$withval" dnl PORT must be one of the allowed values - if test "$TOOLKIT" != "gtk1" -a "$TOOLKIT" != "gtk2" -a \ + if test "$TOOLKIT" != "gtk1" -a "$TOOLKIT" != "gtk2" -a "$TOOLKIT" != "gtk3" -a \ "$TOOLKIT" != "msw" -a "$TOOLKIT" != "motif" -a \ "$TOOLKIT" != "osx_carbon" -a "$TOOLKIT" != "osx_cocoa" -a \ - "$TOOLKIT" != "dfb" -a "$TOOLKIT" != "x11"; then + "$TOOLKIT" != "dfb" -a "$TOOLKIT" != "x11" -a "$TOOLKIT" != "base"; then AC_MSG_ERROR([ - Unrecognized option value (allowed values: auto, gtk1, gtk2, msw, motif, osx_carbon, osx_cocoa, dfb, x11) + Unrecognized option value (allowed values: auto, gtk1, gtk2, gtk3, msw, motif, osx_carbon, osx_cocoa, dfb, x11, base) ]) fi @@ -1204,7 +1215,7 @@ AC_DEFUN([WX_STANDARD_OPTIONS], AC_MSG_CHECKING([for the --with-wxversion option]) if test "$withval" = "auto" ; then AC_MSG_RESULT([will be automatically detected]) - WX_RELEASE="auto" + WX_RELEASE="" else wx_requested_major_version=`echo $withval | \ @@ -1239,7 +1250,7 @@ dnl --------------------------------------------------------------------------- dnl WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS dnl dnl Sets the WXCONFIG_FLAGS string using the SHARED,DEBUG,UNICODE variable values -dnl which are different from "auto". +dnl which were specified. dnl Thus this macro needs to be called only once all options have been set. dnl --------------------------------------------------------------------------- AC_DEFUN([WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS], @@ -1263,11 +1274,11 @@ AC_DEFUN([WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS], WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--unicode=no " fi - if test "$TOOLKIT" != "auto" ; then + if test -n "$TOOLKIT" ; then WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--toolkit=$TOOLKIT " fi - if test "$WX_RELEASE" != "auto" ; then + if test -n "$WX_RELEASE" ; then WXCONFIG_FLAGS="$WXCONFIG_FLAGS""--version=$WX_RELEASE " fi @@ -1281,16 +1292,16 @@ AC_DEFUN([WX_CONVERT_STANDARD_OPTIONS_TO_WXCONFIG_FLAGS], dnl --------------------------------------------------------------------------- -dnl _WX_SELECTEDCONFIG_CHECKFOR([RESULTVAR], [STRING], [MSG] -dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +dnl _WX_SELECTEDCONFIG_CHECKFOR([RESULTVAR], [STRING], [MSG]) dnl -dnl Outputs the given MSG. Then searches the given STRING in the wxWidgets -dnl additional CPP flags and put the result of the search in WX_$RESULTVAR -dnl also adding the "yes" or "no" message result to MSG. +dnl Sets WX_$RESULTVAR to the value of $RESULTVAR if it's defined. Otherwise, +dnl auto-detect the value by checking for the presence of STRING in +dnl $WX_SELECTEDCONFIG (which is supposed to be set by caller) and set +dnl WX_$RESULTVAR to either 0 or 1, also outputting "yes" or "no" after MSG. dnl --------------------------------------------------------------------------- AC_DEFUN([_WX_SELECTEDCONFIG_CHECKFOR], [ - if test "$$1" = "auto" ; then + if test -z "$$1" ; then dnl The user does not have particular preferences for this option; dnl so we will detect the wxWidgets relative build setting and use it @@ -1305,11 +1316,9 @@ AC_DEFUN([_WX_SELECTEDCONFIG_CHECKFOR], if test "$WX_$1" != "0"; then WX_$1=1 AC_MSG_RESULT([yes]) - ifelse([$4], , :, [$4]) else WX_$1=0 AC_MSG_RESULT([no]) - ifelse([$5], , :, [$5]) fi else @@ -1356,19 +1365,16 @@ AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], echo "[[dbg]] WX_SELECTEDCONFIG: $WX_SELECTEDCONFIG" fi - dnl we could test directly for WX_SHARED with a line like: dnl _WX_SELECTEDCONFIG_CHECKFOR([SHARED], [shared], dnl [if wxWidgets was built in SHARED mode]) dnl but wx-config --selected-config DOES NOT outputs the 'shared' dnl word when wx was built in shared mode; it rather outputs the dnl 'static' word when built in static mode. - if test $WX_SHARED = "1"; then + if test "$WX_SHARED" = "1"; then STATIC=0 - elif test $WX_SHARED = "0"; then + elif test "$WX_SHARED" = "0"; then STATIC=1 - elif test $WX_SHARED = "auto"; then - STATIC="auto" fi dnl Now set the WX_UNICODE, WX_DEBUG, WX_STATIC variables @@ -1391,7 +1397,7 @@ AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], AC_SUBST(WX_SHARED) dnl detect the WX_PORT to use - if test "$TOOLKIT" = "auto" ; then + if test -z "$TOOLKIT" ; then dnl The user does not have particular preferences for this option; dnl so we will detect the wxWidgets relative build setting and use it @@ -1399,22 +1405,26 @@ AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], WX_GTKPORT1=$(expr "$WX_SELECTEDCONFIG" : ".*gtk1.*") WX_GTKPORT2=$(expr "$WX_SELECTEDCONFIG" : ".*gtk2.*") + WX_GTKPORT3=$(expr "$WX_SELECTEDCONFIG" : ".*gtk3.*") WX_MSWPORT=$(expr "$WX_SELECTEDCONFIG" : ".*msw.*") WX_MOTIFPORT=$(expr "$WX_SELECTEDCONFIG" : ".*motif.*") WX_OSXCOCOAPORT=$(expr "$WX_SELECTEDCONFIG" : ".*osx_cocoa.*") WX_OSXCARBONPORT=$(expr "$WX_SELECTEDCONFIG" : ".*osx_carbon.*") WX_X11PORT=$(expr "$WX_SELECTEDCONFIG" : ".*x11.*") WX_DFBPORT=$(expr "$WX_SELECTEDCONFIG" : ".*dfb.*") + WX_BASEPORT=$(expr "$WX_SELECTEDCONFIG" : ".*base.*") WX_PORT="unknown" if test "$WX_GTKPORT1" != "0"; then WX_PORT="gtk1"; fi if test "$WX_GTKPORT2" != "0"; then WX_PORT="gtk2"; fi + if test "$WX_GTKPORT3" != "0"; then WX_PORT="gtk3"; fi if test "$WX_MSWPORT" != "0"; then WX_PORT="msw"; fi if test "$WX_MOTIFPORT" != "0"; then WX_PORT="motif"; fi if test "$WX_OSXCOCOAPORT" != "0"; then WX_PORT="osx_cocoa"; fi if test "$WX_OSXCARBONPORT" != "0"; then WX_PORT="osx_carbon"; fi if test "$WX_X11PORT" != "0"; then WX_PORT="x11"; fi if test "$WX_DFBPORT" != "0"; then WX_PORT="dfb"; fi + if test "$WX_BASEPORT" != "0"; then WX_PORT="base"; fi dnl NOTE: backward-compatible check for wx2.8; in wx2.9 the mac dnl ports are called 'osx_cocoa' and 'osx_carbon' (see above) @@ -1432,14 +1442,8 @@ AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], AC_MSG_RESULT([$WX_PORT]) else - dnl Use the setting given by the user - if test -z "$TOOLKIT" ; then - WX_PORT=$TOOLKIT - else - dnl try with PORT - WX_PORT=$PORT - fi + WX_PORT=$TOOLKIT fi AC_SUBST(WX_PORT) @@ -1470,35 +1474,29 @@ AC_DEFUN([WX_DETECT_STANDARD_OPTION_VALUES], ]) fi - dnl now we can finally update the DEBUG,UNICODE,SHARED options - dnl to their final values if they were set to 'auto' - if test "$DEBUG" = "auto"; then - DEBUG=$WX_DEBUG - fi - if test "$UNICODE" = "auto"; then + dnl now we can finally update the options to their final values if they + dnl were not already set + if test -z "$UNICODE" ; then UNICODE=$WX_UNICODE fi - if test "$SHARED" = "auto"; then + if test -z "$SHARED" ; then SHARED=$WX_SHARED fi - if test "$TOOLKIT" = "auto"; then + if test -z "$TOOLKIT" ; then TOOLKIT=$WX_PORT fi - dnl in case the user needs a BUILD=debug/release var... - if test "$DEBUG" = "1"; then - BUILD="debug" - elif test "$DEBUG" = "0" -o "$DEBUG" = ""; then - BUILD="release" - fi - - dnl respect the DEBUG variable adding the optimize/debug flags + dnl respect the DEBUG variable adding the optimize/debug flags and also + dnl define a BUILD variable in case the user wants to use it + dnl dnl NOTE: the CXXFLAGS are merged together with the CPPFLAGS so we dnl don't need to set them, too if test "$DEBUG" = "1"; then + BUILD="debug" CXXFLAGS="$CXXFLAGS -g -O0" CFLAGS="$CFLAGS -g -O0" - else + elif test "$DEBUG" = "0"; then + BUILD="release" CXXFLAGS="$CXXFLAGS -O2" CFLAGS="$CFLAGS -O2" fi @@ -1591,7 +1589,7 @@ AC_DEFUN([AM_PATH_WXCONFIG], [ ]) AC_DEFUN([AM_PATH_WXRC], [WXRC_CHECK([$1],[$2])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1603,10 +1601,10 @@ AC_DEFUN([AM_PATH_WXRC], [WXRC_CHECK([$1],[$2])]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.16.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -1622,14 +1620,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.16.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1681,7 +1679,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1712,7 +1710,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1903,13 +1901,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file 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. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -1917,49 +1914,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -1968,18 +1959,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2066,8 +2056,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -2134,7 +2124,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -2176,7 +2166,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2197,7 +2187,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2218,7 +2208,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2226,49 +2216,42 @@ AC_SUBST([am__leading_dot])]) # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2289,12 +2272,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -2307,7 +2285,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2336,7 +2314,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2383,7 +2361,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2402,7 +2380,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2483,7 +2461,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2543,7 +2521,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2571,7 +2549,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -2590,7 +2568,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index 7b59503..dfcded4 100755 --- a/configure +++ b/configure @@ -1,11 +1,12 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PCem v14. +# Generated by GNU Autoconf 2.71 for PCem v17. # # Report bugs to >. # # -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. # # # This configure script is free software; the Free Software Foundation @@ -16,14 +17,16 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -33,46 +36,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -81,13 +84,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -96,8 +92,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -109,30 +109,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. @@ -154,20 +134,22 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else +else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( @@ -187,41 +169,52 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : -else +else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" - if (eval "$as_required") 2>/dev/null; then : + if (eval "$as_required") 2>/dev/null +then : as_have_required=yes -else +else $as_nop as_have_required=no fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : -else +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base + as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : break 2 fi fi @@ -229,14 +222,21 @@ fi esac as_found=false done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi - if test "x$CONFIG_SHELL" != x; then : + if test "x$CONFIG_SHELL" != x +then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also @@ -254,18 +254,19 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and Sarah Walker + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and Sarah Walker $0: about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script @@ -293,6 +294,7 @@ as_fn_unset () } as_unset=as_fn_unset + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -310,6 +312,14 @@ as_fn_exit () as_fn_set_status $1 exit $1 } # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_mkdir_p # ------------- @@ -324,7 +334,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -333,7 +343,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -372,12 +382,13 @@ as_fn_executable_p () # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -389,18 +400,27 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- @@ -412,9 +432,9 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -441,7 +461,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -485,7 +505,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall @@ -499,6 +519,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits exit } + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -512,6 +536,13 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -579,8 +610,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCem' PACKAGE_TARNAME='pcem' -PACKAGE_VERSION='v14' -PACKAGE_STRING='PCem v14' +PACKAGE_VERSION='v17' +PACKAGE_STRING='PCem v17' PACKAGE_BUGREPORT='Sarah Walker ' PACKAGE_URL='' @@ -647,7 +678,6 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR OBJEXT @@ -730,7 +760,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -834,8 +865,6 @@ do *) ac_optarg=yes ;; esac - # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; @@ -876,9 +905,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -902,9 +931,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -1115,9 +1144,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1131,9 +1160,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1177,9 +1206,9 @@ Try \`$0 --help' for more information" *) # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; @@ -1195,7 +1224,7 @@ if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1259,7 +1288,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | +printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -1316,7 +1345,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PCem v14 to adapt to many kinds of systems. +\`configure' configures PCem v17 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1387,7 +1416,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCem v14:";; + short | recursive ) echo "Configuration of PCem v17:";; esac cat <<\_ACEOF @@ -1458,9 +1487,9 @@ if test "$ac_init_help" = "recursive"; then case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -1488,7 +1517,8 @@ esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive @@ -1496,7 +1526,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix echo && $SHELL "$ac_srcdir/configure" --help=recursive else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done @@ -1505,10 +1535,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCem configure v14 -generated by GNU Autoconf 2.69 +PCem configure v17 +generated by GNU Autoconf 2.71 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1525,14 +1555,14 @@ fi ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext + rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -1540,14 +1570,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest.$ac_objext; then : + } && test -s conftest.$ac_objext +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -1563,14 +1594,14 @@ fi ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext + rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -1578,14 +1609,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err - } && test -s conftest.$ac_objext; then : + } && test -s conftest.$ac_objext +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -1601,14 +1633,14 @@ fi ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -1616,17 +1648,18 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext - }; then : + } +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -1643,8 +1676,8 @@ fi # ac_fn_c_try_run LINENO # ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack @@ -1654,25 +1687,26 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status @@ -1682,14 +1716,34 @@ fi as_fn_set_status $ac_retval } # ac_fn_c_try_run +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PCem $as_me v14, which was -generated by GNU Autoconf 2.69. Invocation command line was +It was created by PCem $as_me v17, which was +generated by GNU Autoconf 2.71. Invocation command line was - $ $0 $@ + $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log @@ -1722,8 +1776,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS @@ -1758,7 +1816,7 @@ do | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; @@ -1793,11 +1851,13 @@ done # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo - $as_echo "## ---------------- ## + printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo @@ -1808,8 +1868,8 @@ trap 'exit_status=$? case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -1833,7 +1893,7 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - $as_echo "## ----------------- ## + printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo @@ -1841,14 +1901,14 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo @@ -1856,15 +1916,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then - $as_echo "## ----------- ## + printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo @@ -1872,8 +1932,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; echo fi test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && @@ -1887,63 +1947,48 @@ ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h -$as_echo "/* confdefs.h */" > confdefs.h +printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" + +for ac_site_file in $ac_site_files do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi @@ -1953,19 +1998,641 @@ if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +# Test code for whether the C++ compiler supports C++98 (global declarations) +ac_cxx_conftest_cxx98_globals=' +// Does the compiler advertise C++98 conformance? +#if !defined __cplusplus || __cplusplus < 199711L +# error "Compiler does not advertise C++98 conformance" +#endif + +// These inclusions are to reject old compilers that +// lack the unsuffixed header files. +#include +#include + +// and are *not* freestanding headers in C++98. +extern void assert (int); +namespace std { + extern int strcmp (const char *, const char *); +} + +// Namespaces, exceptions, and templates were all added after "C++ 2.0". +using std::exception; +using std::strcmp; + +namespace { + +void test_exception_syntax() +{ + try { + throw "test"; + } catch (const char *s) { + // Extra parentheses suppress a warning when building autoconf itself, + // due to lint rules shared with more typical C programs. + assert (!(strcmp) (s, "test")); + } +} + +template struct test_template +{ + T const val; + explicit test_template(T t) : val(t) {} + template T add(U u) { return static_cast(u) + val; } +}; + +} // anonymous namespace +' + +# Test code for whether the C++ compiler supports C++98 (body of main) +ac_cxx_conftest_cxx98_main=' + assert (argc); + assert (! argv[0]); +{ + test_exception_syntax (); + test_template tt (2.0); + assert (tt.add (4) == 6.0); + assert (true && !false); +} +' + +# Test code for whether the C++ compiler supports C++11 (global declarations) +ac_cxx_conftest_cxx11_globals=' +// Does the compiler advertise C++ 2011 conformance? +#if !defined __cplusplus || __cplusplus < 201103L +# error "Compiler does not advertise C++11 conformance" +#endif + +namespace cxx11test +{ + constexpr int get_val() { return 20; } + + struct testinit + { + int i; + double d; + }; + + class delegate + { + public: + delegate(int n) : n(n) {} + delegate(): delegate(2354) {} + + virtual int getval() { return this->n; }; + protected: + int n; + }; + + class overridden : public delegate + { + public: + overridden(int n): delegate(n) {} + virtual int getval() override final { return this->n * 2; } + }; + + class nocopy + { + public: + nocopy(int i): i(i) {} + nocopy() = default; + nocopy(const nocopy&) = delete; + nocopy & operator=(const nocopy&) = delete; + private: + int i; + }; + + // for testing lambda expressions + template Ret eval(Fn f, Ret v) + { + return f(v); + } + + // for testing variadic templates and trailing return types + template auto sum(V first) -> V + { + return first; + } + template auto sum(V first, Args... rest) -> V + { + return first + sum(rest...); + } +} +' + +# Test code for whether the C++ compiler supports C++11 (body of main) +ac_cxx_conftest_cxx11_main=' +{ + // Test auto and decltype + auto a1 = 6538; + auto a2 = 48573953.4; + auto a3 = "String literal"; + + int total = 0; + for (auto i = a3; *i; ++i) { total += *i; } + + decltype(a2) a4 = 34895.034; +} +{ + // Test constexpr + short sa[cxx11test::get_val()] = { 0 }; +} +{ + // Test initializer lists + cxx11test::testinit il = { 4323, 435234.23544 }; +} +{ + // Test range-based for + int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, + 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + for (auto &x : array) { x += 23; } +} +{ + // Test lambda expressions + using cxx11test::eval; + assert (eval ([](int x) { return x*2; }, 21) == 42); + double d = 2.0; + assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); + assert (d == 5.0); + assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); + assert (d == 5.0); +} +{ + // Test use of variadic templates + using cxx11test::sum; + auto a = sum(1); + auto b = sum(1, 2); + auto c = sum(1.0, 2.0, 3.0); +} +{ + // Test constructor delegation + cxx11test::delegate d1; + cxx11test::delegate d2(); + cxx11test::delegate d3(45); +} +{ + // Test override and final + cxx11test::overridden o1(55464); +} +{ + // Test nullptr + char *c = nullptr; +} +{ + // Test template brackets + test_template<::test_template> v(test_template(12)); +} +{ + // Unicode literals + char const *utf8 = u8"UTF-8 string \u2500"; + char16_t const *utf16 = u"UTF-8 string \u2500"; + char32_t const *utf32 = U"UTF-32 string \u2500"; +} +' + +# Test code for whether the C compiler supports C++11 (complete). +ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} +${ac_cxx_conftest_cxx11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + ${ac_cxx_conftest_cxx11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C++98 (complete). +ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + return ok; +} +" + + +# Auxiliary files required by this configure script. +ac_aux_files="compile missing install-sh config.guess config.sub" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false @@ -1976,12 +2643,12 @@ for ac_var in $ac_precious_vars; do eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) @@ -1990,24 +2657,24 @@ $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in @@ -2017,11 +2684,12 @@ $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi done if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2035,55 +2703,30 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; @@ -2102,21 +2745,22 @@ IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; @@ -2136,9 +2780,10 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac -am__api_version='1.15' +am__api_version='1.16' -# Find a good install program. We prefer a C program (faster), + + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install @@ -2152,20 +2797,25 @@ am__api_version='1.15' # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; @@ -2175,13 +2825,13 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else @@ -2189,12 +2839,12 @@ case $as_dir/ in #(( echo one > conftest.one echo two > conftest.two mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi @@ -2210,7 +2860,7 @@ IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi - if test "${ac_cv_path_install+set}" = set; then + if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a @@ -2220,8 +2870,8 @@ fi INSTALL=$ac_install_sh fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. @@ -2231,8 +2881,8 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -2286,8 +2936,8 @@ else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= @@ -2306,26 +2956,23 @@ test "$program_suffix" != NONE && # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` +program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` + # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + + if test x"${MISSING+set}" != xset; then + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then @@ -2345,11 +2992,12 @@ if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else @@ -2357,11 +3005,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2372,11 +3024,11 @@ fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -2385,11 +3037,12 @@ if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else @@ -2397,11 +3050,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2412,11 +3069,11 @@ fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then @@ -2424,8 +3081,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP @@ -2437,25 +3094,31 @@ fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${ac_cv_path_mkdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done @@ -2466,7 +3129,7 @@ IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then + if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a @@ -2476,18 +3139,19 @@ fi MKDIR_P="$ac_install_sh -d" fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else @@ -2495,11 +3159,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2510,24 +3178,25 @@ fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval test \${ac_cv_prog_make_${ac_make}_set+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @@ -2543,12 +3212,12 @@ esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } SET_MAKE= else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi @@ -2562,7 +3231,8 @@ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : +if test ${enable_silent_rules+y} +then : enableval=$enable_silent_rules; fi @@ -2572,12 +3242,13 @@ case $enable_silent_rules in # ((( *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +printf %s "checking whether $am_make supports nested variables... " >&6; } +if test ${am_cv_make_support_nested_variables+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 @@ -2589,8 +3260,8 @@ else am_cv_make_support_nested_variables=no fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' @@ -2622,17 +3293,13 @@ fi # Define the identity of the package. PACKAGE='pcem' - VERSION='v14' + VERSION='v17' -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF +printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF +printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. @@ -2652,8 +3319,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -2704,7 +3371,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -2715,6 +3382,15 @@ END fi fi + + + + + + + + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2723,11 +3399,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -2735,11 +3412,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2750,11 +3431,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -2763,11 +3444,12 @@ if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -2775,11 +3457,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2790,11 +3476,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then @@ -2802,8 +3488,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -2816,11 +3502,12 @@ if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -2828,11 +3515,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2843,11 +3534,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -2856,11 +3547,12 @@ fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -2869,15 +3561,19 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2893,18 +3589,18 @@ if test $ac_prog_rejected = yes; then # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -2915,11 +3611,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -2927,11 +3624,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2942,11 +3643,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -2959,11 +3660,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -2971,11 +3673,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -2986,11 +3692,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3002,8 +3708,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -3011,25 +3717,129 @@ esac fi fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 -for ac_option in --version -v -V -qversion; do +for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -3039,7 +3849,7 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -3047,7 +3857,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -3059,9 +3869,9 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" @@ -3082,11 +3892,12 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, @@ -3103,7 +3914,7 @@ do # certainly right. break;; *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi @@ -3119,44 +3930,46 @@ do done test "$ac_cv_exeext" = no && ac_cv_exeext= -else +else $as_nop ac_file='' fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -3170,15 +3983,15 @@ for ac_file in conftest.exe conftest conftest.*; do * ) break;; esac done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext @@ -3187,7 +4000,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; @@ -3199,8 +4012,8 @@ _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in @@ -3208,10 +4021,10 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in @@ -3219,39 +4032,40 @@ $as_echo "$ac_try_echo"; } >&5 *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -3265,11 +4079,12 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in @@ -3278,31 +4093,32 @@ $as_echo "$ac_try_echo"; } >&5 break;; esac done -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -3312,29 +4128,33 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_compiler_gnu=yes -else +else $as_nop ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi -ac_test_CFLAGS=${CFLAGS+set} +ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no @@ -3343,57 +4163,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes -else +else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -else +else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then @@ -3408,94 +4231,144 @@ else CFLAGS= fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} +$ac_c_conftest_c89_program _ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : + if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_c89=$ac_arg fi -rm -f core conftest.err conftest.$ac_objext +rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC - fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi fi ac_ext=c @@ -3504,21 +4377,23 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_ext=c + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +printf %s "checking whether $CC understands -c and -o together... " >&6; } +if test ${am_cv_prog_cc_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -3546,8 +4421,8 @@ _ACEOF rm -f core conftest* unset am_i fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. @@ -3566,48 +4441,49 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : +if test ${enable_dependency_tracking+y} +then : enableval=$enable_dependency_tracking; fi @@ -3628,11 +4504,12 @@ fi depcc="$CC" am_compiler_list= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CC_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For @@ -3739,8 +4616,8 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if @@ -3754,6 +4631,12 @@ else fi + + + + + + ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3764,15 +4647,16 @@ if test -z "$CXX"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else @@ -3780,11 +4664,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3795,11 +4683,11 @@ fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3808,15 +4696,16 @@ fi fi if test -z "$CXX"; then ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else @@ -3824,11 +4713,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3839,11 +4732,11 @@ fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3855,8 +4748,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX @@ -3866,7 +4759,7 @@ fi fi fi # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do @@ -3876,7 +4769,7 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -3886,20 +4779,21 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 +printf %s "checking whether the compiler supports GNU C++... " >&6; } +if test ${ac_cv_cxx_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -3909,29 +4803,33 @@ main () return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : ac_compiler_gnu=yes -else +else $as_nop ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi -ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +printf %s "checking whether $CXX accepts -g... " >&6; } +if test ${ac_cv_prog_cxx_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no @@ -3940,57 +4838,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : ac_cv_prog_cxx_g=yes -else +else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : -else +else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : ac_cv_prog_cxx_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } +if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then @@ -4005,6 +4906,100 @@ else CXXFLAGS= fi fi +ac_prog_cxx_stdcxx=no +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 +printf %s "checking for $CXX option to enable C++11 features... " >&6; } +if test ${ac_cv_prog_cxx_11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_11=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx11_program +_ACEOF +for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx11" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx11" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_prog_cxx_stdcxx=cxx11 +fi +fi +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 +printf %s "checking for $CXX option to enable C++98 features... " >&6; } +if test ${ac_cv_prog_cxx_98+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_98=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx98_program +_ACEOF +for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx98=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx98" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx98" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx98" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx98" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 + ac_prog_cxx_stdcxx=cxx98 +fi +fi + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4013,11 +5008,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CXX_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +printf %s "checking dependency style of $depcc... " >&6; } +if test ${am_cv_CXX_dependencies_compiler_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For @@ -4124,8 +5120,8 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if @@ -4143,19 +5139,20 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build for release" >&5 -$as_echo_n "checking whether to build for release... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build for release" >&5 +printf %s "checking whether to build for release... " >&6; } # Check whether --enable-release_build was given. -if test "${enable_release_build+set}" = set; then : +if test ${enable_release_build+y} +then : enableval=$enable_release_build; fi if test "$enable_release_build" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "$enable_release_build" = "yes"; then RELEASE_BUILD_TRUE= @@ -4166,77 +5163,80 @@ else fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 -$as_echo_n "checking whether to enable debugging... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 +printf %s "checking whether to enable debugging... " >&6; } # Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : +if test ${enable_debug+y} +then : enableval=$enable_debug; fi if test "$enable_debug" = "yes"; then - CFLAGS="-Wall -O0 -g -D_DEBUG" - CXXFLAGS="-Wall -O0 -g -D_DEBUG" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + CFLAGS="-Wall -O0 -g -D_DEBUG -fcommon" + CXXFLAGS="-Wall -O0 -g -D_DEBUG -fcommon" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - CFLAGS="-O3" - CXXFLAGS="-O3" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + CFLAGS="-O3 -fcommon" + CXXFLAGS="-O3 -fcommon" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable networking" >&5 -$as_echo_n "checking whether to enable networking... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable networking" >&5 +printf %s "checking whether to enable networking... " >&6; } # Check whether --enable-networking was given. -if test "${enable_networking+set}" = set; then : +if test ${enable_networking+y} +then : enableval=$enable_networking; fi if test "$enable_networking" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use ALSA for MIDI output" >&5 -$as_echo_n "checking whether to use ALSA for MIDI output... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use ALSA for MIDI output" >&5 +printf %s "checking whether to use ALSA for MIDI output... " >&6; } # Check whether --enable-alsa was given. -if test "${enable_alsa+set}" = set; then : +if test ${enable_alsa+y} +then : enableval=$enable_alsa; fi if test "$enable_alsa" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cpu" >&5 -$as_echo_n "checking for cpu... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for cpu" >&5 +printf %s "checking for cpu... " >&6; } case "${host_cpu}" in i?86) CPU=i386 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 -$as_echo "${host_cpu}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 +printf "%s\n" "${host_cpu}" >&6; } ;; x86_64) CPU=x86_64 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 -$as_echo "${host_cpu}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 +printf "%s\n" "${host_cpu}" >&6; } ;; armv7l) CPU=arm - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 -$as_echo "${host_cpu}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 +printf "%s\n" "${host_cpu}" >&6; } ;; aarch64) CPU=arm64 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 -$as_echo "${host_cpu}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5 +printf "%s\n" "${host_cpu}" >&6; } ;; *) as_fn_error $? "Unsupported CPU. ${host_cpu}" "$LINENO" 5 @@ -4276,34 +5276,35 @@ else fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t $CPU" >&5 -$as_echo_n "checking for off64_t $CPU... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for off64_t $CPU" >&5 +printf %s "checking for off64_t $CPU... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { off64_t n=0; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : has_lfs="yes" -else +else $as_nop has_lfs="no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext case "$host" in *-*-freebsd*) # has off64_t but no fopen64/etc. has_lfs="no" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_lfs" >&5 -$as_echo "$has_lfs" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $has_lfs" >&5 +printf "%s\n" "$has_lfs" >&6; } #AC_MSG_CHECKING([for libz]) #AX_CHECK_ZLIB @@ -4354,11 +5355,12 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. @@ -4368,11 +5370,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4384,11 +5390,11 @@ esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4397,11 +5403,12 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. @@ -4411,11 +5418,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4427,11 +5438,11 @@ esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then @@ -4439,8 +5450,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG @@ -4452,44 +5463,48 @@ fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi # Check whether --with-sdl-prefix was given. -if test "${with_sdl_prefix+set}" = set; then : +if test ${with_sdl_prefix+y} +then : withval=$with_sdl_prefix; sdl_prefix="$withval" -else +else $as_nop sdl_prefix="" fi # Check whether --with-sdl-exec-prefix was given. -if test "${with_sdl_exec_prefix+set}" = set; then : +if test ${with_sdl_exec_prefix+y} +then : withval=$with_sdl_exec_prefix; sdl_exec_prefix="$withval" -else +else $as_nop sdl_exec_prefix="" fi # Check whether --enable-sdltest was given. -if test "${enable_sdltest+set}" = set; then : +if test ${enable_sdltest+y} +then : enableval=$enable_sdltest; -else +else $as_nop enable_sdltest=yes fi # Check whether --enable-sdlframework was given. -if test "${enable_sdlframework+set}" = set; then : +if test ${enable_sdlframework+y} +then : enableval=$enable_sdlframework; -else +else $as_nop search_sdl_framework=yes fi @@ -4501,17 +5516,17 @@ fi if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 -$as_echo_n "checking for SDL... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 +printf %s "checking for sdl2 >= $min_sdl_version... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 ($PKG_CONFIG --exists --print-errors "sdl2 >= $min_sdl_version") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2 >= $min_sdl_version" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -4525,10 +5540,10 @@ if test -n "$SDL_LIBS"; then pkg_cv_SDL_LIBS="$SDL_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 ($PKG_CONFIG --exists --print-errors "sdl2 >= $min_sdl_version") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2 >= $min_sdl_version" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -4542,8 +5557,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -4560,14 +5575,14 @@ fi sdl_pc=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } sdl_pc=no else SDL_CFLAGS=$pkg_cv_SDL_CFLAGS SDL_LIBS=$pkg_cv_SDL_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } sdl_pc=yes fi else @@ -4596,11 +5611,12 @@ fi fi # Extract the first word of "sdl2-config", so it can be a program name with args. set dummy sdl2-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SDL2_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_SDL2_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $SDL2_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_SDL2_CONFIG="$SDL2_CONFIG" # Let the user override the test with a path. @@ -4610,11 +5626,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_SDL2_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_SDL2_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4627,11 +5647,11 @@ esac fi SDL2_CONFIG=$ac_cv_path_SDL2_CONFIG if test -n "$SDL2_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDL2_CONFIG" >&5 -$as_echo "$SDL2_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SDL2_CONFIG" >&5 +printf "%s\n" "$SDL2_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4639,8 +5659,8 @@ fi no_sdl="" if test "$SDL2_CONFIG" = "no" -a "x$search_sdl_framework" = "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL2.framework" >&5 -$as_echo_n "checking for SDL2.framework... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SDL2.framework" >&5 +printf %s "checking for SDL2.framework... " >&6; } if test "x$SDL2_FRAMEWORK" != x; then sdl_framework=$SDL2_FRAMEWORK else @@ -4651,9 +5671,9 @@ $as_echo_n "checking for SDL2.framework... " >&6; } done fi - if test -d $sdl_framework; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sdl_framework" >&5 -$as_echo "$sdl_framework" >&6; } + if test x"$sdl_framework" != x && test -d "$sdl_framework"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $sdl_framework" >&5 +printf "%s\n" "$sdl_framework" >&6; } sdl_framework_dir=`dirname $sdl_framework` SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include" SDL_LIBS="-F$sdl_framework_dir -Wl,-framework,SDL2" @@ -4664,8 +5684,8 @@ $as_echo "$sdl_framework" >&6; } if test "$SDL2_CONFIG" != "no"; then if test "x$sdl_pc" = "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 -$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 +printf %s "checking for SDL - version >= $min_sdl_version... " >&6; } SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` fi @@ -4684,9 +5704,10 @@ $as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" rm -f conf.sdltest - if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes +then : echo $ac_n "cross compiling; assumed OK... $ac_c" -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4748,9 +5769,10 @@ int main (int argc, char *argv[]) _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : -else +else $as_nop no_sdl=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -4764,11 +5786,11 @@ fi fi if test "x$sdl_pc" = "xno"; then if test "x$no_sdl" = "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi fi fi @@ -4801,14 +5823,15 @@ int main(int argc, char *argv[]) #define main K_and_R_C_main int -main () +main (void) { return 0; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding SDL or finding the wrong" echo "*** version of SDL. If it is not finding SDL, you'll need to set your" @@ -4818,13 +5841,13 @@ if ac_fn_c_try_link "$LINENO"; then : echo "***" echo "*** If you have an old version installed, it is best to remove it, although" echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" -else +else $as_nop echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occured. This usually means SDL was incorrectly installed" echo "*** or that you have moved SDL since it was installed. In the latter case, you" echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" @@ -4844,30 +5867,34 @@ rm -f core conftest.err conftest.$ac_objext \ # Check whether --with-wxdir was given. -if test "${with_wxdir+set}" = set; then : +if test ${with_wxdir+y} +then : withval=$with_wxdir; wx_config_name="$withval/wx-config" wx_config_args="--inplace" fi # Check whether --with-wx-config was given. -if test "${with_wx_config+set}" = set; then : +if test ${with_wx_config+y} +then : withval=$with_wx_config; wx_config_name="$withval" fi # Check whether --with-wx-prefix was given. -if test "${with_wx_prefix+set}" = set; then : +if test ${with_wx_prefix+y} +then : withval=$with_wx_prefix; wx_config_prefix="$withval" -else +else $as_nop wx_config_prefix="" fi # Check whether --with-wx-exec-prefix was given. -if test "${with_wx_exec_prefix+set}" = set; then : +if test ${with_wx_exec_prefix+y} +then : withval=$with_wx_exec_prefix; wx_config_exec_prefix="$withval" -else +else $as_nop wx_config_exec_prefix="" fi @@ -4896,19 +5923,20 @@ reqwx=3.0.0 fi if test -x "$WX_CONFIG_NAME" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wx-config" >&5 -$as_echo_n "checking for wx-config... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wx-config" >&5 +printf %s "checking for wx-config... " >&6; } WX_CONFIG_PATH="$WX_CONFIG_NAME" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 -$as_echo "$WX_CONFIG_PATH" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +printf "%s\n" "$WX_CONFIG_PATH" >&6; } else # Extract the first word of "$WX_CONFIG_NAME", so it can be a program name with args. set dummy $WX_CONFIG_NAME; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_WX_CONFIG_PATH+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_WX_CONFIG_PATH+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $WX_CONFIG_PATH in [\\/]* | ?:[\\/]*) ac_cv_path_WX_CONFIG_PATH="$WX_CONFIG_PATH" # Let the user override the test with a path. @@ -4919,11 +5947,15 @@ as_dummy=""$WX_LOOKUP_PATH:$PATH"" for as_dir in $as_dummy do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_WX_CONFIG_PATH="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_WX_CONFIG_PATH="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4936,11 +5968,11 @@ esac fi WX_CONFIG_PATH=$ac_cv_path_WX_CONFIG_PATH if test -n "$WX_CONFIG_PATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 -$as_echo "$WX_CONFIG_PATH" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $WX_CONFIG_PATH" >&5 +printf "%s\n" "$WX_CONFIG_PATH" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4951,11 +5983,11 @@ fi min_wx_version=$reqwx if test -z "" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version" >&5 -$as_echo_n "checking for wxWidgets version >= $min_wx_version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version" >&5 +printf %s "checking for wxWidgets version >= $min_wx_version... " >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version ()" >&5 -$as_echo_n "checking for wxWidgets version >= $min_wx_version ()... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxWidgets version >= $min_wx_version ()" >&5 +printf %s "checking for wxWidgets version >= $min_wx_version ()... " >&6; } fi WX_CONFIG_WITH_ARGS="$WX_CONFIG_PATH $wx_config_args " @@ -4997,19 +6029,44 @@ $as_echo_n "checking for wxWidgets version >= $min_wx_version ()... " >&6; } if test -n "$wx_ver_ok"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $WX_VERSION)" >&5 -$as_echo "yes (version $WX_VERSION)" >&6; } - WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs ` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes (version $WX_VERSION)" >&5 +printf "%s\n" "yes (version $WX_VERSION)" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wxWidgets static library" >&5 -$as_echo_n "checking for wxWidgets static library... " >&6; } - WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs 2>/dev/null` - if test "x$WX_LIBS_STATIC" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + wx_optional_libs="" + + wx_ver_ok="" + if test "x$WX_VERSION" != x ; then + if test $wx_config_major_version -gt 2; then + wx_ver_ok=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + if test $wx_config_major_version -eq 2; then + if test $wx_config_minor_version -gt 9; then + wx_ver_ok=yes + else + if test $wx_config_minor_version -eq 9; then + if test $wx_config_micro_version -ge 0; then + wx_ver_ok=yes + fi + fi + fi + fi + fi + fi + + if test -n "$wx_ver_ok" -a -n ""; then + wx_optional_libs="--optional-libs " + fi + WX_LIBS=`$WX_CONFIG_WITH_ARGS --libs $wx_optional_libs` + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wxWidgets static library" >&5 +printf %s "checking for wxWidgets static library... " >&6; } + WX_LIBS_STATIC=`$WX_CONFIG_WITH_ARGS --static --libs $wx_optional_libs 2>/dev/null` + if test "x$WX_LIBS_STATIC" = "x"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi wx_has_cppflags="" @@ -5066,11 +6123,11 @@ $as_echo "yes" >&6; } else if test "x$WX_VERSION" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (version $WX_VERSION is not new enough)" >&5 -$as_echo "no (version $WX_VERSION is not new enough)" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (version $WX_VERSION is not new enough)" >&5 +printf "%s\n" "no (version $WX_VERSION is not new enough)" >&6; } fi WX_CFLAGS="" @@ -5151,11 +6208,12 @@ if test "$wxWin" != 1; then fi if test "$enable_alsa" == "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for snd_pcm_open in -lasound" >&5 -$as_echo_n "checking for snd_pcm_open in -lasound... " >&6; } -if ${ac_cv_lib_asound_snd_pcm_open+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for snd_pcm_open in -lasound" >&5 +printf %s "checking for snd_pcm_open in -lasound... " >&6; } +if test ${ac_cv_lib_asound_snd_pcm_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lasound $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5164,48 +6222,46 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char snd_pcm_open (); int -main () +main (void) { return snd_pcm_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_asound_snd_pcm_open=yes -else +else $as_nop ac_cv_lib_asound_snd_pcm_open=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_pcm_open" >&5 -$as_echo "$ac_cv_lib_asound_snd_pcm_open" >&6; } -if test "x$ac_cv_lib_asound_snd_pcm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBASOUND 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_pcm_open" >&5 +printf "%s\n" "$ac_cv_lib_asound_snd_pcm_open" >&6; } +if test "x$ac_cv_lib_asound_snd_pcm_open" = xyes +then : + printf "%s\n" "#define HAVE_LIBASOUND 1" >>confdefs.h LIBS="-lasound $LIBS" -else +else $as_nop echo "You need to install the ALSA library." exit -1 fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } -if ${ac_cv_lib_pthread_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +printf %s "checking for pthread_create in -lpthread... " >&6; } +if test ${ac_cv_lib_pthread_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5214,33 +6270,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pthread_create (); int -main () +main (void) { return pthread_create (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_pthread_pthread_create=yes -else +else $as_nop ac_cv_lib_pthread_pthread_create=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } -if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPTHREAD 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes +then : + printf "%s\n" "#define HAVE_LIBPTHREAD 1" >>confdefs.h LIBS="-lpthread $LIBS" @@ -5259,11 +6312,12 @@ case "$host" in build_macosx="yes" ;; *-*-cygwin* | *-*-mingw32*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 -$as_echo_n "checking for main in -lopengl32... " >&6; } -if ${ac_cv_lib_opengl32_main+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 +printf %s "checking for main in -lopengl32... " >&6; } +if test ${ac_cv_lib_opengl32_main+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lopengl32 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5271,42 +6325,43 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext int -main () +main (void) { return main (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_opengl32_main=yes -else +else $as_nop ac_cv_lib_opengl32_main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 -$as_echo "$ac_cv_lib_opengl32_main" >&6; } -if test "x$ac_cv_lib_opengl32_main" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBOPENGL32 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_opengl32_main" >&5 +printf "%s\n" "$ac_cv_lib_opengl32_main" >&6; } +if test "x$ac_cv_lib_opengl32_main" = xyes +then : + printf "%s\n" "#define HAVE_LIBOPENGL32 1" >>confdefs.h LIBS="-lopengl32 $LIBS" -else +else $as_nop \ echo "You need to install the OpenGL library." exit -1 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 -$as_echo_n "checking for alGetError in -lopenal... " >&6; } -if ${ac_cv_lib_openal_alGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +printf %s "checking for alGetError in -lopenal... " >&6; } +if test ${ac_cv_lib_openal_alGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lopenal $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5315,37 +6370,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char alGetError (); int -main () +main (void) { return alGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_openal_alGetError=yes -else +else $as_nop ac_cv_lib_openal_alGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 -$as_echo "$ac_cv_lib_openal_alGetError" >&6; } -if test "x$ac_cv_lib_openal_alGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBOPENAL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +printf "%s\n" "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBOPENAL 1" >>confdefs.h LIBS="-lopenal $LIBS" -else +else $as_nop \ echo "You need to install the OpenAL library." exit -1 @@ -5356,11 +6408,12 @@ fi ;; *-*-linux*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 -$as_echo_n "checking for glGetError in -lGL... " >&6; } -if ${ac_cv_lib_GL_glGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +printf %s "checking for glGetError in -lGL... " >&6; } +if test ${ac_cv_lib_GL_glGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lGL $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5369,47 +6422,45 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char glGetError (); int -main () +main (void) { return glGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_GL_glGetError=yes -else +else $as_nop ac_cv_lib_GL_glGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 -$as_echo "$ac_cv_lib_GL_glGetError" >&6; } -if test "x$ac_cv_lib_GL_glGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +printf "%s\n" "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBGL 1" >>confdefs.h LIBS="-lGL $LIBS" -else +else $as_nop \ echo "You need to install the OpenGL library." exit -1 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 -$as_echo_n "checking for alGetError in -lopenal... " >&6; } -if ${ac_cv_lib_openal_alGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +printf %s "checking for alGetError in -lopenal... " >&6; } +if test ${ac_cv_lib_openal_alGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lopenal $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5418,37 +6469,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char alGetError (); int -main () +main (void) { return alGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_openal_alGetError=yes -else +else $as_nop ac_cv_lib_openal_alGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 -$as_echo "$ac_cv_lib_openal_alGetError" >&6; } -if test "x$ac_cv_lib_openal_alGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBOPENAL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +printf "%s\n" "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBOPENAL 1" >>confdefs.h LIBS="-lopenal $LIBS" -else +else $as_nop \ echo "You need to install the OpenAL library." exit -1 @@ -5460,11 +6508,12 @@ fi CFLAGS="$CFLAGS -I/usr/local/include" CXXFLAGS="$CXXFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 -$as_echo_n "checking for glGetError in -lGL... " >&6; } -if ${ac_cv_lib_GL_glGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +printf %s "checking for glGetError in -lGL... " >&6; } +if test ${ac_cv_lib_GL_glGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lGL $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5473,47 +6522,45 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char glGetError (); int -main () +main (void) { return glGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_GL_glGetError=yes -else +else $as_nop ac_cv_lib_GL_glGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 -$as_echo "$ac_cv_lib_GL_glGetError" >&6; } -if test "x$ac_cv_lib_GL_glGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +printf "%s\n" "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBGL 1" >>confdefs.h LIBS="-lGL $LIBS" -else +else $as_nop \ echo "You need to install the OpenGL library." exit -1 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 -$as_echo_n "checking for alGetError in -lopenal... " >&6; } -if ${ac_cv_lib_openal_alGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +printf %s "checking for alGetError in -lopenal... " >&6; } +if test ${ac_cv_lib_openal_alGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lopenal $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5522,37 +6569,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char alGetError (); int -main () +main (void) { return alGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_openal_alGetError=yes -else +else $as_nop ac_cv_lib_openal_alGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 -$as_echo "$ac_cv_lib_openal_alGetError" >&6; } -if test "x$ac_cv_lib_openal_alGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBOPENAL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +printf "%s\n" "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBOPENAL 1" >>confdefs.h LIBS="-lopenal $LIBS" -else +else $as_nop \ echo "You need to install the OpenAL library." exit -1 @@ -5561,11 +6605,12 @@ fi build_other="yes" ;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 -$as_echo_n "checking for glGetError in -lGL... " >&6; } -if ${ac_cv_lib_GL_glGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5 +printf %s "checking for glGetError in -lGL... " >&6; } +if test ${ac_cv_lib_GL_glGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lGL $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5574,47 +6619,45 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char glGetError (); int -main () +main (void) { return glGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_GL_glGetError=yes -else +else $as_nop ac_cv_lib_GL_glGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 -$as_echo "$ac_cv_lib_GL_glGetError" >&6; } -if test "x$ac_cv_lib_GL_glGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5 +printf "%s\n" "$ac_cv_lib_GL_glGetError" >&6; } +if test "x$ac_cv_lib_GL_glGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBGL 1" >>confdefs.h LIBS="-lGL $LIBS" -else +else $as_nop \ echo "You need to install the OpenGL library." exit -1 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 -$as_echo_n "checking for alGetError in -lopenal... " >&6; } -if ${ac_cv_lib_openal_alGetError+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5 +printf %s "checking for alGetError in -lopenal... " >&6; } +if test ${ac_cv_lib_openal_alGetError+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lopenal $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5623,37 +6666,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char alGetError (); int -main () +main (void) { return alGetError (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_openal_alGetError=yes -else +else $as_nop ac_cv_lib_openal_alGetError=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 -$as_echo "$ac_cv_lib_openal_alGetError" >&6; } -if test "x$ac_cv_lib_openal_alGetError" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBOPENAL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5 +printf "%s\n" "$ac_cv_lib_openal_alGetError" >&6; } +if test "x$ac_cv_lib_openal_alGetError" = xyes +then : + printf "%s\n" "#define HAVE_LIBOPENAL 1" >>confdefs.h LIBS="-lopenal $LIBS" -else +else $as_nop \ echo "You need to install the OpenAL library." exit -1 @@ -5663,6 +6703,7 @@ fi ;; esac +CFLAGS="$CFLAGS $SDL_CFLAGS" LIBS="$LIBS $WX_LIBS $SDL_LIBS" if test "$build_linux" = "yes"; then @@ -5727,8 +6768,8 @@ _ACEOF case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -5758,15 +6799,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; /^ac_cv_env_/b end t clear :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else @@ -5780,8 +6821,8 @@ $as_echo "$as_me: updating cache $cache_file" >&6;} fi fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -5834,7 +6875,7 @@ U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" @@ -5845,14 +6886,14 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 +printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -5930,8 +6971,8 @@ fi ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL @@ -5954,14 +6995,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -5971,46 +7014,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -6019,13 +7062,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -6034,8 +7070,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -6047,30 +7087,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] @@ -6083,13 +7103,14 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -6116,18 +7137,20 @@ as_fn_unset () { eval $1=; unset $1;} } as_unset=as_fn_unset + # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -6139,12 +7162,13 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` @@ -6175,7 +7199,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -6197,6 +7221,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -6210,6 +7238,12 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -6251,7 +7285,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -6260,7 +7294,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -6322,8 +7356,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PCem $as_me v14, which was -generated by GNU Autoconf 2.69. Invocation command line was +This file was extended by PCem $as_me v17, which was +generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -6376,14 +7410,16 @@ $config_commands Report bugs to >." _ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -PCem config.status v14 -configured by $0, generated by GNU Autoconf 2.69, +PCem config.status v17 +configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -6423,21 +7459,21 @@ do -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; + printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; + printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; + printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; @@ -6465,7 +7501,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" @@ -6479,7 +7515,7 @@ exec 5>>config.log sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX - $as_echo "$ac_log" + printf "%s\n" "$ac_log" } >&5 _ACEOF @@ -6487,7 +7523,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" _ACEOF @@ -6511,8 +7547,8 @@ done # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree @@ -6740,7 +7776,7 @@ do esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done @@ -6748,17 +7784,17 @@ do # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | + ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac @@ -6775,7 +7811,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | +printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -6799,9 +7835,9 @@ $as_echo X"$ac_file" | case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -6863,8 +7899,8 @@ ac_sed_dataroot=' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' @@ -6908,9 +7944,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" @@ -6922,8 +7958,8 @@ which seems to be undefined. Please make sure it is defined" >&2;} ;; - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} + :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac @@ -6933,29 +7969,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -6973,53 +8015,50 @@ $as_echo X"$mf" | q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)[^/].*/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; @@ -7056,7 +8095,8 @@ if test "$no_create" != yes; then $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + diff --git a/configure.ac b/configure.ac index 407b057..20a6d09 100644 --- a/configure.ac +++ b/configure.ac @@ -183,6 +183,7 @@ case "$host" in ;; esac +CFLAGS="$CFLAGS $SDL_CFLAGS" LIBS="$LIBS $WX_LIBS $SDL_LIBS" AM_CONDITIONAL(OS_LINUX, [test "$build_linux" = "yes"]) diff --git a/src/Makefile.in b/src/Makefile.in index 9bcb781..7d7cc5c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -124,10 +124,9 @@ bin_PROGRAMS = pcem$(EXEEXT) DEFAULT_INCLUDES = -I.@am__isrc@ @OS_WINDOWS_TRUE@am__append_20 = cdrom-ioctl.c wx-sdl2-display-win.c @OS_WINDOWS_TRUE@am__append_21 = wx.res - -#pcem_CFLAGS += -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseek -Dftello64=ftell -@RELEASE_BUILD_TRUE@am__append_22 = -DRELEASE_BUILD +@HAS_OFF64T_FALSE@am__append_22 = -Doff64_t=off_t -Dfopen64=fopen -Dfseeko64=fseeko -Dftello64=ftello @RELEASE_BUILD_TRUE@am__append_23 = -DRELEASE_BUILD +@RELEASE_BUILD_TRUE@am__append_24 = -DRELEASE_BUILD subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac @@ -155,77 +154,88 @@ am__pcem_SOURCES_DIST = 386.c 386_common.c 386_dynarec.c \ codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c \ codegen_ops_stack.c codegen_reg.c codegen_timing_486.c \ codegen_timing_686.c codegen_timing_common.c \ - codegen_timing_k6.c codegen_timing_pentium.c \ + codegen_timing_cyrixiii.c codegen_timing_k6.c \ + codegen_timing_p6.c codegen_timing_pentium.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c \ - config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ - disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c \ - fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c \ - hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430hx.c \ - i430vx.c ide.c ide_atapi.c ide_sff8038i.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 \ + config.c cpu.c cpu_tables.c cs8230.c dells200.c device.c \ + disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c \ + f82c710_upc.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c \ + gameport.c hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c \ + i430fx.c i430hx.c i430vx.c i440fx.c i440bx.c ide.c ide_atapi.c \ + ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ mvp3.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c \ - pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ - ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c \ - rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c \ - scsi_cd.c scsi_hd.c scsi_zip.c serial.c sio.c sis496.c \ - sl82c460.c sound.c sound_ad1848.c sound_adlib.c \ - sound_adlibgold.c sound_audiopci.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 sst39sf010.c tandy_eeprom.c \ + pc.c pc87306.c pc87307.c pci.c pic.c piix.c piix_pm.c pit.c \ + ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c \ + rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c \ + scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_ibm.c scsi_zip.c \ + serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ + sound_adlib.c sound_adlibgold.c sound_audiopci.c \ + sound_azt2316a.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 sst39sf010.c superxt.c tandy_eeprom.c \ tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c \ - vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c \ - vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c \ - vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c \ - vid_paradise.c vid_pc200.c vid_pc1512.c vid_pc1640.c \ - vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c \ - vid_sdac_ramdac.c vid_sigma.c vid_stg_ramdac.c vid_svga.c \ - vid_svga_render.c vid_t1000.c vid_t3100e.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 \ - vid_wy700.c vt82c586b.c w83877tf.c x86seg.c x87.c xi8088.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ - wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ - wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ - wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ - wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ - midi_alsa.c wx-sdl2-midi.c codegen_backend_x86.c \ - codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c \ - codegen_backend_x86_ops_sse.c codegen_backend_x86_uops.c \ - codegen_backend_x86-64.c codegen_backend_x86-64_ops.c \ - codegen_backend_x86-64_ops_sse.c codegen_backend_x86-64_uops.c \ - codegen_backend_arm.c codegen_backend_arm_ops.c \ - codegen_backend_arm_uops.c codegen_backend_arm64.c \ - codegen_backend_arm64_imm.c codegen_backend_arm64_ops.c \ - codegen_backend_arm64_uops.c ne2000.c nethandler.c \ - wx-hostconfig.c slirp/bootp.c slirp/cksum.c slirp/debug.c \ - slirp/if.c slirp/ip_icmp.c slirp/ip_input.c slirp/ip_output.c \ - slirp/mbuf.c slirp/misc.c slirp/queue.c slirp/sbuf.c \ - slirp/slirp.c slirp/socket.c slirp/tcp_input.c \ - slirp/tcp_output.c slirp/tcp_subr.c slirp/tcp_timer.c \ - slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c wx-sdl2-display.c \ - cdrom-ioctl-dummy.c cdrom-ioctl-osx.c cdrom-ioctl.c \ - wx-sdl2-display-win.c + vid_colorplus.c vid_compaq_cga.c vid_ddc.c vid_ega.c \ + vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ + vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c \ + vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c \ + vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \ + vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c \ + vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ + vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c \ + vid_t3100e.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 vid_voodoo_banshee.c vid_voodoo_banshee_blitter.c \ + vid_voodoo_blitter.c vid_voodoo_display.c vid_voodoo_fb.c \ + vid_voodoo_fifo.c vid_voodoo_reg.c vid_voodoo_render.c \ + vid_voodoo_setup.c vid_voodoo_texture.c video.c wd76c10.c \ + vid_wy700.c vt82c586b.c vl82c480.c w83877tf.c w83977tf.c \ + x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 minivhd/cwalk.c \ + minivhd/libxml2_encoding.c minivhd/minivhd_convert.c \ + minivhd/minivhd_create.c minivhd/minivhd_io.c \ + minivhd/minivhd_manage.c minivhd/minivhd_struct_rw.c \ + minivhd/minivhd_util.c wx-main.cc wx-config_sel.c \ + wx-dialogbox.cc wx-utils.cc wx-app.cc wx-sdl2-joystick.c \ + wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c \ + wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ + wx-thread.c wx-common.c wx-sdl2-video-renderer.c \ + wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ + wx-shaderconfig.cc wx-joystickconfig.cc wx-createdisc.cc \ + wx-resources.cpp midi_alsa.c wx-sdl2-midi.c \ + codegen_backend_x86.c codegen_backend_x86_ops.c \ + codegen_backend_x86_ops_fpu.c codegen_backend_x86_ops_sse.c \ + codegen_backend_x86_uops.c codegen_backend_x86-64.c \ + codegen_backend_x86-64_ops.c codegen_backend_x86-64_ops_sse.c \ + codegen_backend_x86-64_uops.c codegen_backend_arm.c \ + codegen_backend_arm_ops.c codegen_backend_arm_uops.c \ + codegen_backend_arm64.c codegen_backend_arm64_imm.c \ + codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c \ + ne2000.c nethandler.c wx-hostconfig.c slirp/bootp.c \ + slirp/cksum.c slirp/debug.c slirp/if.c slirp/ip_icmp.c \ + slirp/ip_input.c slirp/ip_output.c slirp/mbuf.c slirp/misc.c \ + slirp/queue.c slirp/sbuf.c slirp/slirp.c slirp/socket.c \ + slirp/tcp_input.c slirp/tcp_output.c slirp/tcp_subr.c \ + slirp/tcp_timer.c slirp/tftp.c slirp/udp.c cdrom-ioctl-linux.c \ + wx-sdl2-display.c cdrom-ioctl-dummy.c cdrom-ioctl-osx.c \ + cdrom-ioctl.c wx-sdl2-display-win.c am__dirstamp = $(am__leading_dot)dirstamp @USE_ALSA_TRUE@am__objects_1 = pcem-midi_alsa.$(OBJEXT) @USE_ALSA_FALSE@am__objects_2 = pcem-wx-sdl2-midi.$(OBJEXT) @@ -310,23 +320,27 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ pcem-codegen_timing_486.$(OBJEXT) \ pcem-codegen_timing_686.$(OBJEXT) \ pcem-codegen_timing_common.$(OBJEXT) \ + pcem-codegen_timing_cyrixiii.$(OBJEXT) \ pcem-codegen_timing_k6.$(OBJEXT) \ + pcem-codegen_timing_p6.$(OBJEXT) \ pcem-codegen_timing_pentium.$(OBJEXT) \ pcem-codegen_timing_winchip.$(OBJEXT) \ pcem-codegen_timing_winchip2.$(OBJEXT) pcem-compaq.$(OBJEXT) \ pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) \ - pcem-cpu_tables.$(OBJEXT) pcem-dells200.$(OBJEXT) \ - pcem-device.$(OBJEXT) pcem-disc.$(OBJEXT) \ - pcem-disc_fdi.$(OBJEXT) pcem-disc_img.$(OBJEXT) \ - pcem-disc_sector.$(OBJEXT) pcem-dma.$(OBJEXT) \ - pcem-esdi_at.$(OBJEXT) pcem-fdc.$(OBJEXT) \ + pcem-cpu_tables.$(OBJEXT) pcem-cs8230.$(OBJEXT) \ + pcem-dells200.$(OBJEXT) pcem-device.$(OBJEXT) \ + pcem-disc.$(OBJEXT) pcem-disc_fdi.$(OBJEXT) \ + pcem-disc_img.$(OBJEXT) pcem-disc_sector.$(OBJEXT) \ + pcem-dma.$(OBJEXT) pcem-esdi_at.$(OBJEXT) \ + pcem-f82c710_upc.$(OBJEXT) pcem-fdc.$(OBJEXT) \ pcem-fdc37c665.$(OBJEXT) pcem-fdc37c93x.$(OBJEXT) \ pcem-fdd.$(OBJEXT) pcem-fdi2raw.$(OBJEXT) \ pcem-gameport.$(OBJEXT) pcem-hdd.$(OBJEXT) \ pcem-hdd_esdi.$(OBJEXT) pcem-hdd_file.$(OBJEXT) \ pcem-headland.$(OBJEXT) pcem-i430lx.$(OBJEXT) \ pcem-i430fx.$(OBJEXT) pcem-i430hx.$(OBJEXT) \ - pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ + pcem-i430vx.$(OBJEXT) pcem-i440fx.$(OBJEXT) \ + pcem-i440bx.$(OBJEXT) pcem-ide.$(OBJEXT) \ pcem-ide_atapi.$(OBJEXT) pcem-ide_sff8038i.$(OBJEXT) \ pcem-intel.$(OBJEXT) pcem-intel_flash.$(OBJEXT) \ pcem-io.$(OBJEXT) pcem-jim.$(OBJEXT) \ @@ -346,28 +360,31 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ pcem-mvp3.$(OBJEXT) pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) \ pcem-nvr.$(OBJEXT) pcem-olivetti_m24.$(OBJEXT) \ pcem-opti495.$(OBJEXT) pcem-paths.$(OBJEXT) pcem-pc.$(OBJEXT) \ - pcem-pc87306.$(OBJEXT) pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) \ - pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) \ + pcem-pc87306.$(OBJEXT) pcem-pc87307.$(OBJEXT) \ + pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) pcem-piix.$(OBJEXT) \ + pcem-piix_pm.$(OBJEXT) pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) \ pcem-ps1.$(OBJEXT) pcem-ps2.$(OBJEXT) pcem-ps2_mca.$(OBJEXT) \ pcem-ps2_nvr.$(OBJEXT) pcem-nvr_tc8521.$(OBJEXT) \ pcem-pzx.$(OBJEXT) pcem-rom.$(OBJEXT) pcem-rtc.$(OBJEXT) \ - pcem-rtc_tc8521.$(OBJEXT) pcem-scat.$(OBJEXT) \ - pcem-scsi.$(OBJEXT) pcem-scsi_53c400.$(OBJEXT) \ - pcem-scsi_aha1540.$(OBJEXT) pcem-scsi_cd.$(OBJEXT) \ - pcem-scsi_hd.$(OBJEXT) pcem-scsi_zip.$(OBJEXT) \ + pcem-rtc_tc8521.$(OBJEXT) pcem-scamp.$(OBJEXT) \ + pcem-scat.$(OBJEXT) pcem-scsi.$(OBJEXT) \ + pcem-scsi_53c400.$(OBJEXT) pcem-scsi_aha1540.$(OBJEXT) \ + pcem-scsi_cd.$(OBJEXT) pcem-scsi_hd.$(OBJEXT) \ + pcem-scsi_ibm.$(OBJEXT) pcem-scsi_zip.$(OBJEXT) \ pcem-serial.$(OBJEXT) pcem-sio.$(OBJEXT) pcem-sis496.$(OBJEXT) \ pcem-sl82c460.$(OBJEXT) pcem-sound.$(OBJEXT) \ pcem-sound_ad1848.$(OBJEXT) pcem-sound_adlib.$(OBJEXT) \ pcem-sound_adlibgold.$(OBJEXT) pcem-sound_audiopci.$(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_ps1.$(OBJEXT) pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ - pcem-sst39sf010.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ + pcem-sound_azt2316a.$(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_ps1.$(OBJEXT) \ + pcem-sound_pssj.$(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-sound_ym7128.$(OBJEXT) \ + pcem-soundopenal.$(OBJEXT) pcem-sst39sf010.$(OBJEXT) \ + pcem-superxt.$(OBJEXT) pcem-tandy_eeprom.$(OBJEXT) \ pcem-tandy_rom.$(OBJEXT) pcem-t1000.$(OBJEXT) \ pcem-t3100e.$(OBJEXT) pcem-timer.$(OBJEXT) \ pcem-um8669f.$(OBJEXT) pcem-um8881f.$(OBJEXT) \ @@ -375,12 +392,13 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ pcem-vid_ati18800.$(OBJEXT) pcem-vid_ati28800.$(OBJEXT) \ pcem-vid_ati68860_ramdac.$(OBJEXT) pcem-vid_cga.$(OBJEXT) \ pcem-vid_cl5429.$(OBJEXT) pcem-vid_colorplus.$(OBJEXT) \ - pcem-vid_compaq_cga.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ - pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ - pcem-vid_genius.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ - pcem-vid_ht216.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ - pcem-vid_ics2595.$(OBJEXT) pcem-vid_im1024.$(OBJEXT) \ - pcem-vid_incolor.$(OBJEXT) pcem-vid_mda.$(OBJEXT) \ + pcem-vid_compaq_cga.$(OBJEXT) pcem-vid_ddc.$(OBJEXT) \ + pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ + pcem-vid_et4000w32.$(OBJEXT) pcem-vid_genius.$(OBJEXT) \ + pcem-vid_hercules.$(OBJEXT) pcem-vid_ht216.$(OBJEXT) \ + pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ + pcem-vid_im1024.$(OBJEXT) pcem-vid_incolor.$(OBJEXT) \ + pcem-vid_mda.$(OBJEXT) pcem-vid_mga.$(OBJEXT) \ pcem-vid_olivetti_m24.$(OBJEXT) pcem-vid_oti037.$(OBJEXT) \ pcem-vid_oti067.$(OBJEXT) pcem-vid_paradise.$(OBJEXT) \ pcem-vid_pc200.$(OBJEXT) pcem-vid_pc1512.$(OBJEXT) \ @@ -394,10 +412,19 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ pcem-vid_tandysl.$(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-vid_voodoo.$(OBJEXT) pcem-vid_voodoo_banshee.$(OBJEXT) \ + pcem-vid_voodoo_banshee_blitter.$(OBJEXT) \ + pcem-vid_voodoo_blitter.$(OBJEXT) \ + pcem-vid_voodoo_display.$(OBJEXT) pcem-vid_voodoo_fb.$(OBJEXT) \ + pcem-vid_voodoo_fifo.$(OBJEXT) pcem-vid_voodoo_reg.$(OBJEXT) \ + pcem-vid_voodoo_render.$(OBJEXT) \ + pcem-vid_voodoo_setup.$(OBJEXT) \ + pcem-vid_voodoo_texture.$(OBJEXT) pcem-video.$(OBJEXT) \ pcem-wd76c10.$(OBJEXT) pcem-vid_wy700.$(OBJEXT) \ - pcem-vt82c586b.$(OBJEXT) pcem-w83877tf.$(OBJEXT) \ - pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xi8088.$(OBJEXT) \ + pcem-vt82c586b.$(OBJEXT) pcem-vl82c480.$(OBJEXT) \ + pcem-w83877tf.$(OBJEXT) pcem-w83977tf.$(OBJEXT) \ + pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) \ + pcem-x87_timings.$(OBJEXT) pcem-xi8088.$(OBJEXT) \ pcem-xtide.$(OBJEXT) pcem-sound_dbopl.$(OBJEXT) \ pcem-sound_resid.$(OBJEXT) dosbox/pcem-cdrom_image.$(OBJEXT) \ dosbox/pcem-dbopl.$(OBJEXT) dosbox/pcem-nukedopl.$(OBJEXT) \ @@ -416,7 +443,14 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_common.$(OBJEXT) \ resid-fp/pcem-wave8580_PST.$(OBJEXT) \ resid-fp/pcem-wave8580_P_T.$(OBJEXT) \ resid-fp/pcem-wave8580__ST.$(OBJEXT) \ - resid-fp/pcem-wave.$(OBJEXT) pcem-wx-main.$(OBJEXT) \ + resid-fp/pcem-wave.$(OBJEXT) minivhd/pcem-cwalk.$(OBJEXT) \ + minivhd/pcem-libxml2_encoding.$(OBJEXT) \ + minivhd/pcem-minivhd_convert.$(OBJEXT) \ + minivhd/pcem-minivhd_create.$(OBJEXT) \ + minivhd/pcem-minivhd_io.$(OBJEXT) \ + minivhd/pcem-minivhd_manage.$(OBJEXT) \ + minivhd/pcem-minivhd_struct_rw.$(OBJEXT) \ + minivhd/pcem-minivhd_util.$(OBJEXT) pcem-wx-main.$(OBJEXT) \ pcem-wx-config_sel.$(OBJEXT) pcem-wx-dialogbox.$(OBJEXT) \ pcem-wx-utils.$(OBJEXT) pcem-wx-app.$(OBJEXT) \ pcem-wx-sdl2-joystick.$(OBJEXT) pcem-wx-sdl2-mouse.$(OBJEXT) \ @@ -453,7 +487,264 @@ am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/pcem-386.Po \ + ./$(DEPDIR)/pcem-386_common.Po ./$(DEPDIR)/pcem-386_dynarec.Po \ + ./$(DEPDIR)/pcem-386_dynarec_ops.Po ./$(DEPDIR)/pcem-808x.Po \ + ./$(DEPDIR)/pcem-82091aa.Po ./$(DEPDIR)/pcem-acc2036.Po \ + ./$(DEPDIR)/pcem-acc2168.Po ./$(DEPDIR)/pcem-acc3221.Po \ + ./$(DEPDIR)/pcem-acer386sx.Po ./$(DEPDIR)/pcem-ali1429.Po \ + ./$(DEPDIR)/pcem-amstrad.Po ./$(DEPDIR)/pcem-cassette.Po \ + ./$(DEPDIR)/pcem-cbm_io.Po ./$(DEPDIR)/pcem-cdrom-image.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po \ + ./$(DEPDIR)/pcem-cdrom-ioctl.Po ./$(DEPDIR)/pcem-cdrom-null.Po \ + ./$(DEPDIR)/pcem-cmd640.Po ./$(DEPDIR)/pcem-codegen.Po \ + ./$(DEPDIR)/pcem-codegen_accumulate.Po \ + ./$(DEPDIR)/pcem-codegen_allocator.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm64.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm64_imm.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm64_ops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm_ops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86_ops.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po \ + ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po \ + ./$(DEPDIR)/pcem-codegen_block.Po \ + ./$(DEPDIR)/pcem-codegen_ir.Po ./$(DEPDIR)/pcem-codegen_ops.Po \ + ./$(DEPDIR)/pcem-codegen_ops_3dnow.Po \ + ./$(DEPDIR)/pcem-codegen_ops_arith.Po \ + ./$(DEPDIR)/pcem-codegen_ops_branch.Po \ + ./$(DEPDIR)/pcem-codegen_ops_fpu_arith.Po \ + ./$(DEPDIR)/pcem-codegen_ops_fpu_constant.Po \ + ./$(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po \ + ./$(DEPDIR)/pcem-codegen_ops_fpu_misc.Po \ + ./$(DEPDIR)/pcem-codegen_ops_helpers.Po \ + ./$(DEPDIR)/pcem-codegen_ops_jump.Po \ + ./$(DEPDIR)/pcem-codegen_ops_logic.Po \ + ./$(DEPDIR)/pcem-codegen_ops_misc.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mmx_arith.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mmx_logic.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mmx_pack.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mmx_shift.Po \ + ./$(DEPDIR)/pcem-codegen_ops_mov.Po \ + ./$(DEPDIR)/pcem-codegen_ops_shift.Po \ + ./$(DEPDIR)/pcem-codegen_ops_stack.Po \ + ./$(DEPDIR)/pcem-codegen_reg.Po \ + ./$(DEPDIR)/pcem-codegen_timing_486.Po \ + ./$(DEPDIR)/pcem-codegen_timing_686.Po \ + ./$(DEPDIR)/pcem-codegen_timing_common.Po \ + ./$(DEPDIR)/pcem-codegen_timing_cyrixiii.Po \ + ./$(DEPDIR)/pcem-codegen_timing_k6.Po \ + ./$(DEPDIR)/pcem-codegen_timing_p6.Po \ + ./$(DEPDIR)/pcem-codegen_timing_pentium.Po \ + ./$(DEPDIR)/pcem-codegen_timing_winchip.Po \ + ./$(DEPDIR)/pcem-codegen_timing_winchip2.Po \ + ./$(DEPDIR)/pcem-compaq.Po ./$(DEPDIR)/pcem-config.Po \ + ./$(DEPDIR)/pcem-cpu.Po ./$(DEPDIR)/pcem-cpu_tables.Po \ + ./$(DEPDIR)/pcem-cs8230.Po ./$(DEPDIR)/pcem-dells200.Po \ + ./$(DEPDIR)/pcem-device.Po ./$(DEPDIR)/pcem-disc.Po \ + ./$(DEPDIR)/pcem-disc_fdi.Po ./$(DEPDIR)/pcem-disc_img.Po \ + ./$(DEPDIR)/pcem-disc_sector.Po ./$(DEPDIR)/pcem-dma.Po \ + ./$(DEPDIR)/pcem-esdi_at.Po ./$(DEPDIR)/pcem-f82c710_upc.Po \ + ./$(DEPDIR)/pcem-fdc.Po ./$(DEPDIR)/pcem-fdc37c665.Po \ + ./$(DEPDIR)/pcem-fdc37c93x.Po ./$(DEPDIR)/pcem-fdd.Po \ + ./$(DEPDIR)/pcem-fdi2raw.Po ./$(DEPDIR)/pcem-gameport.Po \ + ./$(DEPDIR)/pcem-hdd.Po ./$(DEPDIR)/pcem-hdd_esdi.Po \ + ./$(DEPDIR)/pcem-hdd_file.Po ./$(DEPDIR)/pcem-headland.Po \ + ./$(DEPDIR)/pcem-i430fx.Po ./$(DEPDIR)/pcem-i430hx.Po \ + ./$(DEPDIR)/pcem-i430lx.Po ./$(DEPDIR)/pcem-i430vx.Po \ + ./$(DEPDIR)/pcem-i440bx.Po ./$(DEPDIR)/pcem-i440fx.Po \ + ./$(DEPDIR)/pcem-ide.Po ./$(DEPDIR)/pcem-ide_atapi.Po \ + ./$(DEPDIR)/pcem-ide_sff8038i.Po ./$(DEPDIR)/pcem-intel.Po \ + ./$(DEPDIR)/pcem-intel_flash.Po ./$(DEPDIR)/pcem-io.Po \ + ./$(DEPDIR)/pcem-jim.Po \ + ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po \ + ./$(DEPDIR)/pcem-joystick_standard.Po \ + ./$(DEPDIR)/pcem-joystick_sw_pad.Po \ + ./$(DEPDIR)/pcem-joystick_tm_fcs.Po \ + ./$(DEPDIR)/pcem-keyboard.Po \ + ./$(DEPDIR)/pcem-keyboard_amstrad.Po \ + ./$(DEPDIR)/pcem-keyboard_at.Po \ + ./$(DEPDIR)/pcem-keyboard_olim24.Po \ + ./$(DEPDIR)/pcem-keyboard_pcjr.Po \ + ./$(DEPDIR)/pcem-keyboard_xt.Po ./$(DEPDIR)/pcem-laserxt.Po \ + ./$(DEPDIR)/pcem-lpt.Po ./$(DEPDIR)/pcem-lpt_dac.Po \ + ./$(DEPDIR)/pcem-lpt_dss.Po ./$(DEPDIR)/pcem-mca.Po \ + ./$(DEPDIR)/pcem-mcr.Po ./$(DEPDIR)/pcem-mem.Po \ + ./$(DEPDIR)/pcem-mem_bios.Po ./$(DEPDIR)/pcem-mfm_at.Po \ + ./$(DEPDIR)/pcem-mfm_xebec.Po ./$(DEPDIR)/pcem-midi_alsa.Po \ + ./$(DEPDIR)/pcem-model.Po ./$(DEPDIR)/pcem-mouse.Po \ + ./$(DEPDIR)/pcem-mouse_msystems.Po \ + ./$(DEPDIR)/pcem-mouse_ps2.Po ./$(DEPDIR)/pcem-mouse_serial.Po \ + ./$(DEPDIR)/pcem-mvp3.Po ./$(DEPDIR)/pcem-ne2000.Po \ + ./$(DEPDIR)/pcem-neat.Po ./$(DEPDIR)/pcem-nethandler.Po \ + ./$(DEPDIR)/pcem-nmi.Po ./$(DEPDIR)/pcem-nvr.Po \ + ./$(DEPDIR)/pcem-nvr_tc8521.Po \ + ./$(DEPDIR)/pcem-olivetti_m24.Po ./$(DEPDIR)/pcem-opti495.Po \ + ./$(DEPDIR)/pcem-paths.Po ./$(DEPDIR)/pcem-pc.Po \ + ./$(DEPDIR)/pcem-pc87306.Po ./$(DEPDIR)/pcem-pc87307.Po \ + ./$(DEPDIR)/pcem-pci.Po ./$(DEPDIR)/pcem-pic.Po \ + ./$(DEPDIR)/pcem-piix.Po ./$(DEPDIR)/pcem-piix_pm.Po \ + ./$(DEPDIR)/pcem-pit.Po ./$(DEPDIR)/pcem-ppi.Po \ + ./$(DEPDIR)/pcem-ps1.Po ./$(DEPDIR)/pcem-ps2.Po \ + ./$(DEPDIR)/pcem-ps2_mca.Po ./$(DEPDIR)/pcem-ps2_nvr.Po \ + ./$(DEPDIR)/pcem-pzx.Po ./$(DEPDIR)/pcem-rom.Po \ + ./$(DEPDIR)/pcem-rtc.Po ./$(DEPDIR)/pcem-rtc_tc8521.Po \ + ./$(DEPDIR)/pcem-scamp.Po ./$(DEPDIR)/pcem-scat.Po \ + ./$(DEPDIR)/pcem-scsi.Po ./$(DEPDIR)/pcem-scsi_53c400.Po \ + ./$(DEPDIR)/pcem-scsi_aha1540.Po ./$(DEPDIR)/pcem-scsi_cd.Po \ + ./$(DEPDIR)/pcem-scsi_hd.Po ./$(DEPDIR)/pcem-scsi_ibm.Po \ + ./$(DEPDIR)/pcem-scsi_zip.Po ./$(DEPDIR)/pcem-serial.Po \ + ./$(DEPDIR)/pcem-sio.Po ./$(DEPDIR)/pcem-sis496.Po \ + ./$(DEPDIR)/pcem-sl82c460.Po ./$(DEPDIR)/pcem-sound.Po \ + ./$(DEPDIR)/pcem-sound_ad1848.Po \ + ./$(DEPDIR)/pcem-sound_adlib.Po \ + ./$(DEPDIR)/pcem-sound_adlibgold.Po \ + ./$(DEPDIR)/pcem-sound_audiopci.Po \ + ./$(DEPDIR)/pcem-sound_azt2316a.Po \ + ./$(DEPDIR)/pcem-sound_cms.Po ./$(DEPDIR)/pcem-sound_dbopl.Po \ + ./$(DEPDIR)/pcem-sound_emu8k.Po ./$(DEPDIR)/pcem-sound_gus.Po \ + ./$(DEPDIR)/pcem-sound_mpu401_uart.Po \ + ./$(DEPDIR)/pcem-sound_opl.Po ./$(DEPDIR)/pcem-sound_pas16.Po \ + ./$(DEPDIR)/pcem-sound_ps1.Po ./$(DEPDIR)/pcem-sound_pssj.Po \ + ./$(DEPDIR)/pcem-sound_resid.Po ./$(DEPDIR)/pcem-sound_sb.Po \ + ./$(DEPDIR)/pcem-sound_sb_dsp.Po \ + ./$(DEPDIR)/pcem-sound_sn76489.Po \ + ./$(DEPDIR)/pcem-sound_speaker.Po \ + ./$(DEPDIR)/pcem-sound_ssi2001.Po \ + ./$(DEPDIR)/pcem-sound_wss.Po ./$(DEPDIR)/pcem-sound_ym7128.Po \ + ./$(DEPDIR)/pcem-soundopenal.Po ./$(DEPDIR)/pcem-sst39sf010.Po \ + ./$(DEPDIR)/pcem-superxt.Po ./$(DEPDIR)/pcem-t1000.Po \ + ./$(DEPDIR)/pcem-t3100e.Po ./$(DEPDIR)/pcem-tandy_eeprom.Po \ + ./$(DEPDIR)/pcem-tandy_rom.Po ./$(DEPDIR)/pcem-timer.Po \ + ./$(DEPDIR)/pcem-um8669f.Po ./$(DEPDIR)/pcem-um8881f.Po \ + ./$(DEPDIR)/pcem-vid_ati18800.Po \ + ./$(DEPDIR)/pcem-vid_ati28800.Po \ + ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_ati_eeprom.Po \ + ./$(DEPDIR)/pcem-vid_ati_mach64.Po ./$(DEPDIR)/pcem-vid_cga.Po \ + ./$(DEPDIR)/pcem-vid_cl5429.Po \ + ./$(DEPDIR)/pcem-vid_colorplus.Po \ + ./$(DEPDIR)/pcem-vid_compaq_cga.Po ./$(DEPDIR)/pcem-vid_ddc.Po \ + ./$(DEPDIR)/pcem-vid_ega.Po ./$(DEPDIR)/pcem-vid_et4000.Po \ + ./$(DEPDIR)/pcem-vid_et4000w32.Po \ + ./$(DEPDIR)/pcem-vid_genius.Po \ + ./$(DEPDIR)/pcem-vid_hercules.Po ./$(DEPDIR)/pcem-vid_ht216.Po \ + ./$(DEPDIR)/pcem-vid_icd2061.Po \ + ./$(DEPDIR)/pcem-vid_ics2595.Po ./$(DEPDIR)/pcem-vid_im1024.Po \ + ./$(DEPDIR)/pcem-vid_incolor.Po ./$(DEPDIR)/pcem-vid_mda.Po \ + ./$(DEPDIR)/pcem-vid_mga.Po \ + ./$(DEPDIR)/pcem-vid_olivetti_m24.Po \ + ./$(DEPDIR)/pcem-vid_oti037.Po ./$(DEPDIR)/pcem-vid_oti067.Po \ + ./$(DEPDIR)/pcem-vid_paradise.Po \ + ./$(DEPDIR)/pcem-vid_pc1512.Po ./$(DEPDIR)/pcem-vid_pc1640.Po \ + ./$(DEPDIR)/pcem-vid_pc200.Po ./$(DEPDIR)/pcem-vid_pcjr.Po \ + ./$(DEPDIR)/pcem-vid_pgc.Po ./$(DEPDIR)/pcem-vid_ps1_svga.Po \ + ./$(DEPDIR)/pcem-vid_s3.Po ./$(DEPDIR)/pcem-vid_s3_virge.Po \ + ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_sigma.Po \ + ./$(DEPDIR)/pcem-vid_stg_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_svga.Po \ + ./$(DEPDIR)/pcem-vid_svga_render.Po \ + ./$(DEPDIR)/pcem-vid_t1000.Po ./$(DEPDIR)/pcem-vid_t3100e.Po \ + ./$(DEPDIR)/pcem-vid_tandy.Po ./$(DEPDIR)/pcem-vid_tandysl.Po \ + ./$(DEPDIR)/pcem-vid_tgui9440.Po \ + ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po \ + ./$(DEPDIR)/pcem-vid_tvga.Po \ + ./$(DEPDIR)/pcem-vid_unk_ramdac.Po ./$(DEPDIR)/pcem-vid_vga.Po \ + ./$(DEPDIR)/pcem-vid_voodoo.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_banshee.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_blitter.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_display.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_fb.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_fifo.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_reg.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_render.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_setup.Po \ + ./$(DEPDIR)/pcem-vid_voodoo_texture.Po \ + ./$(DEPDIR)/pcem-vid_wy700.Po ./$(DEPDIR)/pcem-video.Po \ + ./$(DEPDIR)/pcem-vl82c480.Po ./$(DEPDIR)/pcem-vt82c586b.Po \ + ./$(DEPDIR)/pcem-w83877tf.Po ./$(DEPDIR)/pcem-w83977tf.Po \ + ./$(DEPDIR)/pcem-wd76c10.Po ./$(DEPDIR)/pcem-wx-app.Po \ + ./$(DEPDIR)/pcem-wx-common.Po ./$(DEPDIR)/pcem-wx-config.Po \ + ./$(DEPDIR)/pcem-wx-config_sel.Po \ + ./$(DEPDIR)/pcem-wx-createdisc.Po \ + ./$(DEPDIR)/pcem-wx-deviceconfig.Po \ + ./$(DEPDIR)/pcem-wx-dialogbox.Po \ + ./$(DEPDIR)/pcem-wx-glslp-parser.Po \ + ./$(DEPDIR)/pcem-wx-hostconfig.Po \ + ./$(DEPDIR)/pcem-wx-joystickconfig.Po \ + ./$(DEPDIR)/pcem-wx-main.Po ./$(DEPDIR)/pcem-wx-resources.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-display.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-midi.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-status.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po \ + ./$(DEPDIR)/pcem-wx-sdl2-video.Po ./$(DEPDIR)/pcem-wx-sdl2.Po \ + ./$(DEPDIR)/pcem-wx-shader_man.Po \ + ./$(DEPDIR)/pcem-wx-shaderconfig.Po \ + ./$(DEPDIR)/pcem-wx-status.Po ./$(DEPDIR)/pcem-wx-thread.Po \ + ./$(DEPDIR)/pcem-wx-utils.Po ./$(DEPDIR)/pcem-x86seg.Po \ + ./$(DEPDIR)/pcem-x87.Po ./$(DEPDIR)/pcem-x87_timings.Po \ + ./$(DEPDIR)/pcem-xi8088.Po ./$(DEPDIR)/pcem-xtide.Po \ + dosbox/$(DEPDIR)/pcem-cdrom_image.Po \ + dosbox/$(DEPDIR)/pcem-dbopl.Po \ + dosbox/$(DEPDIR)/pcem-nukedopl.Po \ + dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po \ + minivhd/$(DEPDIR)/pcem-cwalk.Po \ + minivhd/$(DEPDIR)/pcem-libxml2_encoding.Po \ + minivhd/$(DEPDIR)/pcem-minivhd_convert.Po \ + minivhd/$(DEPDIR)/pcem-minivhd_create.Po \ + minivhd/$(DEPDIR)/pcem-minivhd_io.Po \ + minivhd/$(DEPDIR)/pcem-minivhd_manage.Po \ + minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Po \ + minivhd/$(DEPDIR)/pcem-minivhd_util.Po \ + resid-fp/$(DEPDIR)/pcem-convolve-sse.Po \ + resid-fp/$(DEPDIR)/pcem-convolve.Po \ + resid-fp/$(DEPDIR)/pcem-envelope.Po \ + resid-fp/$(DEPDIR)/pcem-extfilt.Po \ + resid-fp/$(DEPDIR)/pcem-filter.Po \ + resid-fp/$(DEPDIR)/pcem-pot.Po resid-fp/$(DEPDIR)/pcem-sid.Po \ + resid-fp/$(DEPDIR)/pcem-voice.Po \ + resid-fp/$(DEPDIR)/pcem-wave.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po \ + resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po \ + resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po \ + slirp/$(DEPDIR)/pcem-bootp.Po slirp/$(DEPDIR)/pcem-cksum.Po \ + slirp/$(DEPDIR)/pcem-debug.Po slirp/$(DEPDIR)/pcem-if.Po \ + slirp/$(DEPDIR)/pcem-ip_icmp.Po \ + slirp/$(DEPDIR)/pcem-ip_input.Po \ + slirp/$(DEPDIR)/pcem-ip_output.Po slirp/$(DEPDIR)/pcem-mbuf.Po \ + slirp/$(DEPDIR)/pcem-misc.Po slirp/$(DEPDIR)/pcem-queue.Po \ + slirp/$(DEPDIR)/pcem-sbuf.Po slirp/$(DEPDIR)/pcem-slirp.Po \ + slirp/$(DEPDIR)/pcem-socket.Po \ + slirp/$(DEPDIR)/pcem-tcp_input.Po \ + slirp/$(DEPDIR)/pcem-tcp_output.Po \ + slirp/$(DEPDIR)/pcem-tcp_subr.Po \ + slirp/$(DEPDIR)/pcem-tcp_timer.Po slirp/$(DEPDIR)/pcem-tftp.Po \ + slirp/$(DEPDIR)/pcem-udp.Po am__mv = mv -f AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -641,6 +932,8 @@ WINDRES = $(shell $(WX_CONFIG_PATH) --rescomp) # DOSBox # resid-fp + +#MiniVHD pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c \ 808x.c 82091aa.c acc2036.c acc2168.c acc3221.c acer386sx.c \ ali1429.c amstrad.c cassette.c cbm_io.c cdrom-image.cc \ @@ -656,70 +949,82 @@ pcem_SOURCES = 386.c 386_common.c 386_dynarec.c 386_dynarec_ops.c \ codegen_ops_shift.c codegen_ops_misc.c codegen_ops_mov.c \ codegen_ops_stack.c codegen_reg.c codegen_timing_486.c \ codegen_timing_686.c codegen_timing_common.c \ - codegen_timing_k6.c codegen_timing_pentium.c \ + codegen_timing_cyrixiii.c codegen_timing_k6.c \ + codegen_timing_p6.c codegen_timing_pentium.c \ codegen_timing_winchip.c codegen_timing_winchip2.c compaq.c \ - config.c cpu.c cpu_tables.c dells200.c device.c disc.c \ - disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c \ - fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c gameport.c hdd.c \ - hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430hx.c \ - i430vx.c ide.c ide_atapi.c ide_sff8038i.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 \ + config.c cpu.c cpu_tables.c cs8230.c dells200.c device.c \ + disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c \ + f82c710_upc.c fdc.c fdc37c665.c fdc37c93x.c fdd.c fdi2raw.c \ + gameport.c hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c \ + i430fx.c i430hx.c i430vx.c i440fx.c i440bx.c ide.c ide_atapi.c \ + ide_sff8038i.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 laserxt.c lpt.c lpt_dac.c \ lpt_dss.c mca.c mcr.c mem.c mem_bios.c mfm_at.c mfm_xebec.c \ model.c mouse.c mouse_msystems.c mouse_ps2.c mouse_serial.c \ mvp3.c neat.c nmi.c nvr.c olivetti_m24.c opti495.c paths.c \ - pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c \ - ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c rtc.c \ - rtc_tc8521.c scat.c scsi.c scsi_53c400.c scsi_aha1540.c \ - scsi_cd.c scsi_hd.c scsi_zip.c serial.c sio.c sis496.c \ - sl82c460.c sound.c sound_ad1848.c sound_adlib.c \ - sound_adlibgold.c sound_audiopci.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 sst39sf010.c tandy_eeprom.c \ + pc.c pc87306.c pc87307.c pci.c pic.c piix.c piix_pm.c pit.c \ + ppi.c ps1.c ps2.c ps2_mca.c ps2_nvr.c nvr_tc8521.c pzx.c rom.c \ + rtc.c rtc_tc8521.c scamp.c scat.c scsi.c scsi_53c400.c \ + scsi_aha1540.c scsi_cd.c scsi_hd.c scsi_ibm.c scsi_zip.c \ + serial.c sio.c sis496.c sl82c460.c sound.c sound_ad1848.c \ + sound_adlib.c sound_adlibgold.c sound_audiopci.c \ + sound_azt2316a.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 sst39sf010.c superxt.c tandy_eeprom.c \ tandy_rom.c t1000.c t3100e.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_colorplus.c vid_compaq_cga.c vid_ega.c vid_et4000.c \ - vid_et4000w32.c vid_genius.c vid_hercules.c vid_ht216.c \ - vid_icd2061.c vid_ics2595.c vid_im1024.c vid_incolor.c \ - vid_mda.c vid_olivetti_m24.c vid_oti037.c vid_oti067.c \ - vid_paradise.c vid_pc200.c vid_pc1512.c vid_pc1640.c \ - vid_pcjr.c vid_pgc.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c \ - vid_sdac_ramdac.c vid_sigma.c vid_stg_ramdac.c vid_svga.c \ - vid_svga_render.c vid_t1000.c vid_t3100e.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 \ - vid_wy700.c vt82c586b.c w83877tf.c x86seg.c x87.c xi8088.c \ - xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp \ - dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 wx-main.cc wx-config_sel.c wx-dialogbox.cc \ - wx-utils.cc wx-app.cc wx-sdl2-joystick.c wx-sdl2-mouse.c \ - wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c wx-config.c \ - wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c wx-thread.c \ - wx-common.c wx-sdl2-video-renderer.c wx-sdl2-video-gl3.c \ - wx-glslp-parser.c wx-shader_man.c wx-shaderconfig.cc \ - wx-joystickconfig.cc wx-createdisc.cc wx-resources.cpp \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_8) $(am__append_9) $(am__append_10) \ - $(am__append_13) $(am__append_15) $(am__append_16) \ - $(am__append_17) $(am__append_20) + vid_colorplus.c vid_compaq_cga.c vid_ddc.c vid_ega.c \ + vid_et4000.c vid_et4000w32.c vid_genius.c vid_hercules.c \ + vid_ht216.c vid_icd2061.c vid_ics2595.c vid_im1024.c \ + vid_incolor.c vid_mda.c vid_mga.c vid_olivetti_m24.c \ + vid_oti037.c vid_oti067.c vid_paradise.c vid_pc200.c \ + vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_pgc.c vid_ps1_svga.c \ + vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_sigma.c \ + vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c \ + vid_t3100e.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 vid_voodoo_banshee.c vid_voodoo_banshee_blitter.c \ + vid_voodoo_blitter.c vid_voodoo_display.c vid_voodoo_fb.c \ + vid_voodoo_fifo.c vid_voodoo_reg.c vid_voodoo_render.c \ + vid_voodoo_setup.c vid_voodoo_texture.c video.c wd76c10.c \ + vid_wy700.c vt82c586b.c vl82c480.c w83877tf.c w83977tf.c \ + x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc \ + sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ + dosbox/nukedopl.cpp dosbox/vid_cga_comp.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_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 minivhd/cwalk.c \ + minivhd/libxml2_encoding.c minivhd/minivhd_convert.c \ + minivhd/minivhd_create.c minivhd/minivhd_io.c \ + minivhd/minivhd_manage.c minivhd/minivhd_struct_rw.c \ + minivhd/minivhd_util.c wx-main.cc wx-config_sel.c \ + wx-dialogbox.cc wx-utils.cc wx-app.cc wx-sdl2-joystick.c \ + wx-sdl2-mouse.c wx-sdl2-keyboard.c wx-sdl2-video.c wx-sdl2.c \ + wx-config.c wx-deviceconfig.cc wx-status.cc wx-sdl2-status.c \ + wx-thread.c wx-common.c wx-sdl2-video-renderer.c \ + wx-sdl2-video-gl3.c wx-glslp-parser.c wx-shader_man.c \ + wx-shaderconfig.cc wx-joystickconfig.cc wx-createdisc.cc \ + wx-resources.cpp $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_8) $(am__append_9) \ + $(am__append_10) $(am__append_13) $(am__append_15) \ + $(am__append_16) $(am__append_17) $(am__append_20) pcem_CFLAGS = $(subst -fpermissive,,$(shell $(WX_CONFIG_PATH) \ --cxxflags) $(shell sdl2-config --cflags)) $(am__append_7) \ - $(am__append_11) $(am__append_18) $(am__append_22) + $(am__append_11) $(am__append_18) $(am__append_22) \ + $(am__append_23) pcem_CXXFLAGS = $(shell $(WX_CONFIG_PATH) --cxxflags) $(shell \ sdl2-config --cflags) $(am__append_12) $(am__append_19) \ - $(am__append_23) + $(am__append_24) pcem_LDADD = @LIBS@ $(am__append_3) $(am__append_14) $(am__append_21) @OS_WINDOWS_TRUE@DEFAULT_INCLUDES = -iquote . all: all-am @@ -743,8 +1048,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *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);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -851,6 +1156,28 @@ resid-fp/pcem-wave8580__ST.$(OBJEXT): resid-fp/$(am__dirstamp) \ resid-fp/$(DEPDIR)/$(am__dirstamp) resid-fp/pcem-wave.$(OBJEXT): resid-fp/$(am__dirstamp) \ resid-fp/$(DEPDIR)/$(am__dirstamp) +minivhd/$(am__dirstamp): + @$(MKDIR_P) minivhd + @: > minivhd/$(am__dirstamp) +minivhd/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) minivhd/$(DEPDIR) + @: > minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-cwalk.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-libxml2_encoding.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-minivhd_convert.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-minivhd_create.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-minivhd_io.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-minivhd_manage.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-minivhd_struct_rw.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) +minivhd/pcem-minivhd_util.$(OBJEXT): minivhd/$(am__dirstamp) \ + minivhd/$(DEPDIR)/$(am__dirstamp) slirp/$(am__dirstamp): @$(MKDIR_P) slirp @: > slirp/$(am__dirstamp) @@ -903,333 +1230,375 @@ pcem$(EXEEXT): $(pcem_OBJECTS) $(pcem_DEPENDENCIES) $(EXTRA_pcem_DEPENDENCIES) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f dosbox/*.$(OBJEXT) + -rm -f minivhd/*.$(OBJEXT) -rm -f resid-fp/*.$(OBJEXT) -rm -f slirp/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_common.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-82091aa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2036.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2168.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc3221.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-amstrad.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cassette.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-dummy.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-ioctl-osx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_accumulate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_allocator.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_imm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_block.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ir.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_ops_3dnow.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_arith.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_branch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_arith.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_constant.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_helpers.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_jump.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_logic.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_arith.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_logic.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_pack.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_shift.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mov.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_shift.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_stack.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_reg.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_686.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_k6.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_timing_winchip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_winchip2.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-cpu_tables.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.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-disc_sector.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.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-fdc37c93x.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdd.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-hdd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.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-i430hx.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-ide_atapi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide_sff8038i.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-joystick_ch_flightstick_pro.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_standard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_sw_pad.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_tm_fcs.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-laserxt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.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-mem_bios.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_at.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.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_msystems.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-mvp3.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ne2000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.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-nvr_tc8521.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.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-ps2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_mca.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pzx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.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_audiopci.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_dbopl.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_ps1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.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-sound_ym7128.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sst39sf010.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.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_colorplus.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.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_genius.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_ht216.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_im1024.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.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_oti037.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_pgc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ps1_svga.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_sigma.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_t1000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.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_tandysl.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-vid_wy700.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vt82c586b.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-w83877tf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.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-xi8088.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-808x.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-82091aa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2036.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc2168.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acc3221.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acer386sx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ali1429.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-amstrad.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cassette.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cbm_io.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-image.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cmd640.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_accumulate.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_allocator.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_imm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_block.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ir.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_3dnow.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_arith.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_branch.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_arith.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_constant.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_fpu_misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_helpers.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_jump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_logic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_arith.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_logic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_pack.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mmx_shift.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_mov.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_shift.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops_stack.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_reg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_486.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_686.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_cyrixiii.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_k6.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_p6.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_pentium.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_winchip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_winchip2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-compaq.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-config.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu_tables.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cs8230.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dells200.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-device.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_fdi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_img.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_sector.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-esdi_at.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-f82c710_upc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc37c665.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc37c93x.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdi2raw.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_esdi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-hdd_file.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-headland.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430fx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430hx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430lx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430vx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i440bx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i440fx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide_atapi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide_sff8038i.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel_flash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-io.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-jim.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_standard.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_sw_pad.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-joystick_tm_fcs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_amstrad.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_at.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_olim24.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_pcjr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_xt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-laserxt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt_dss.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mcr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem_bios.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_at.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mfm_xebec.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-midi_alsa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-model.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_msystems.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_ps2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_serial.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mvp3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ne2000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nethandler.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nmi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr_tc8521.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti495.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-paths.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87306.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc87307.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pci.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pic.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-piix.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-piix_pm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pit.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ppi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_mca.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps2_nvr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pzx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rtc_tc8521.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scamp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scat.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_53c400.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_aha1540.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_cd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_hd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_ibm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-scsi_zip.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sio.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sl82c460.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ad1848.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlib.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlibgold.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_audiopci.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_azt2316a.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_cms.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_dbopl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_emu8k.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_gus.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_mpu401_uart.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_opl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pas16.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ps1.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pssj.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_resid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb_dsp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sn76489.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_speaker.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ssi2001.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_wss.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ym7128.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sst39sf010.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-superxt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t1000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-t3100e.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_eeprom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-tandy_rom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-timer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8669f.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8881f.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati18800.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati28800.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_eeprom.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_mach64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cl5429.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_colorplus.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_compaq_cga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ddc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ega.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000w32.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_genius.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_hercules.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ht216.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_icd2061.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ics2595.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_im1024.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_mda.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_mga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_olivetti_m24.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti037.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti067.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_paradise.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1512.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1640.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc200.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pcjr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pgc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ps1_svga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3_virge.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_sdac_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_sigma.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_stg_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga_render.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t1000.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_t3100e.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandy.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandysl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tgui9440.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tvga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_unk_ramdac.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_vga.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_banshee.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_blitter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_display.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_fb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_fifo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_reg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_render.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_setup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo_texture.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_wy700.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vl82c480.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vt82c586b.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-w83877tf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-w83977tf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-app.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-config_sel.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-createdisc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-deviceconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-dialogbox.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-glslp-parser.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-hostconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-joystickconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-resources.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display-win.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-display.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-joystick.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-midi.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-mouse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-status.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2-video.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-sdl2.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shader_man.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-shaderconfig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-status.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-thread.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wx-utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x86seg.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x87.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x87_timings.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xi8088.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-cdrom_image.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-dbopl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-nukedopl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-cwalk.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-libxml2_encoding.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-minivhd_convert.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-minivhd_create.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-minivhd_io.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-minivhd_manage.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@minivhd/$(DEPDIR)/pcem-minivhd_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve-sse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-convolve.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-envelope.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-extfilt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-filter.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-pot.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-sid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-voice.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-bootp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-cksum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-debug.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-if.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_icmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_input.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-ip_output.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-mbuf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-queue.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-sbuf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-slirp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-socket.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_input.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_output.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_subr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tcp_timer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-tftp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@slirp/$(DEPDIR)/pcem-udp.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -1891,6 +2260,20 @@ pcem-codegen_timing_common.obj: codegen_timing_common.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_common.obj `if test -f 'codegen_timing_common.c'; then $(CYGPATH_W) 'codegen_timing_common.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_common.c'; fi` +pcem-codegen_timing_cyrixiii.o: codegen_timing_cyrixiii.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_cyrixiii.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_cyrixiii.Tpo -c -o pcem-codegen_timing_cyrixiii.o `test -f 'codegen_timing_cyrixiii.c' || echo '$(srcdir)/'`codegen_timing_cyrixiii.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_cyrixiii.Tpo $(DEPDIR)/pcem-codegen_timing_cyrixiii.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_cyrixiii.c' object='pcem-codegen_timing_cyrixiii.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_cyrixiii.o `test -f 'codegen_timing_cyrixiii.c' || echo '$(srcdir)/'`codegen_timing_cyrixiii.c + +pcem-codegen_timing_cyrixiii.obj: codegen_timing_cyrixiii.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_cyrixiii.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_cyrixiii.Tpo -c -o pcem-codegen_timing_cyrixiii.obj `if test -f 'codegen_timing_cyrixiii.c'; then $(CYGPATH_W) 'codegen_timing_cyrixiii.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_cyrixiii.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_cyrixiii.Tpo $(DEPDIR)/pcem-codegen_timing_cyrixiii.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_cyrixiii.c' object='pcem-codegen_timing_cyrixiii.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_cyrixiii.obj `if test -f 'codegen_timing_cyrixiii.c'; then $(CYGPATH_W) 'codegen_timing_cyrixiii.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_cyrixiii.c'; fi` + pcem-codegen_timing_k6.o: codegen_timing_k6.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_k6.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_k6.Tpo -c -o pcem-codegen_timing_k6.o `test -f 'codegen_timing_k6.c' || echo '$(srcdir)/'`codegen_timing_k6.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_k6.Tpo $(DEPDIR)/pcem-codegen_timing_k6.Po @@ -1905,6 +2288,20 @@ pcem-codegen_timing_k6.obj: codegen_timing_k6.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_k6.obj `if test -f 'codegen_timing_k6.c'; then $(CYGPATH_W) 'codegen_timing_k6.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_k6.c'; fi` +pcem-codegen_timing_p6.o: codegen_timing_p6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_p6.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_p6.Tpo -c -o pcem-codegen_timing_p6.o `test -f 'codegen_timing_p6.c' || echo '$(srcdir)/'`codegen_timing_p6.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_p6.Tpo $(DEPDIR)/pcem-codegen_timing_p6.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_p6.c' object='pcem-codegen_timing_p6.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_p6.o `test -f 'codegen_timing_p6.c' || echo '$(srcdir)/'`codegen_timing_p6.c + +pcem-codegen_timing_p6.obj: codegen_timing_p6.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_p6.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_p6.Tpo -c -o pcem-codegen_timing_p6.obj `if test -f 'codegen_timing_p6.c'; then $(CYGPATH_W) 'codegen_timing_p6.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_p6.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_p6.Tpo $(DEPDIR)/pcem-codegen_timing_p6.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='codegen_timing_p6.c' object='pcem-codegen_timing_p6.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_p6.obj `if test -f 'codegen_timing_p6.c'; then $(CYGPATH_W) 'codegen_timing_p6.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_p6.c'; fi` + pcem-codegen_timing_pentium.o: codegen_timing_pentium.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-codegen_timing_pentium.Tpo $(DEPDIR)/pcem-codegen_timing_pentium.Po @@ -2003,6 +2400,20 @@ pcem-cpu_tables.obj: cpu_tables.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cpu_tables.obj `if test -f 'cpu_tables.c'; then $(CYGPATH_W) 'cpu_tables.c'; else $(CYGPATH_W) '$(srcdir)/cpu_tables.c'; fi` +pcem-cs8230.o: cs8230.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cs8230.o -MD -MP -MF $(DEPDIR)/pcem-cs8230.Tpo -c -o pcem-cs8230.o `test -f 'cs8230.c' || echo '$(srcdir)/'`cs8230.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cs8230.Tpo $(DEPDIR)/pcem-cs8230.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cs8230.c' object='pcem-cs8230.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cs8230.o `test -f 'cs8230.c' || echo '$(srcdir)/'`cs8230.c + +pcem-cs8230.obj: cs8230.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cs8230.obj -MD -MP -MF $(DEPDIR)/pcem-cs8230.Tpo -c -o pcem-cs8230.obj `if test -f 'cs8230.c'; then $(CYGPATH_W) 'cs8230.c'; else $(CYGPATH_W) '$(srcdir)/cs8230.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-cs8230.Tpo $(DEPDIR)/pcem-cs8230.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cs8230.c' object='pcem-cs8230.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cs8230.obj `if test -f 'cs8230.c'; then $(CYGPATH_W) 'cs8230.c'; else $(CYGPATH_W) '$(srcdir)/cs8230.c'; fi` + pcem-dells200.o: dells200.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dells200.o -MD -MP -MF $(DEPDIR)/pcem-dells200.Tpo -c -o pcem-dells200.o `test -f 'dells200.c' || echo '$(srcdir)/'`dells200.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-dells200.Tpo $(DEPDIR)/pcem-dells200.Po @@ -2115,6 +2526,20 @@ pcem-esdi_at.obj: esdi_at.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-esdi_at.obj `if test -f 'esdi_at.c'; then $(CYGPATH_W) 'esdi_at.c'; else $(CYGPATH_W) '$(srcdir)/esdi_at.c'; fi` +pcem-f82c710_upc.o: f82c710_upc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-f82c710_upc.o -MD -MP -MF $(DEPDIR)/pcem-f82c710_upc.Tpo -c -o pcem-f82c710_upc.o `test -f 'f82c710_upc.c' || echo '$(srcdir)/'`f82c710_upc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-f82c710_upc.Tpo $(DEPDIR)/pcem-f82c710_upc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='f82c710_upc.c' object='pcem-f82c710_upc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-f82c710_upc.o `test -f 'f82c710_upc.c' || echo '$(srcdir)/'`f82c710_upc.c + +pcem-f82c710_upc.obj: f82c710_upc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-f82c710_upc.obj -MD -MP -MF $(DEPDIR)/pcem-f82c710_upc.Tpo -c -o pcem-f82c710_upc.obj `if test -f 'f82c710_upc.c'; then $(CYGPATH_W) 'f82c710_upc.c'; else $(CYGPATH_W) '$(srcdir)/f82c710_upc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-f82c710_upc.Tpo $(DEPDIR)/pcem-f82c710_upc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='f82c710_upc.c' object='pcem-f82c710_upc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-f82c710_upc.obj `if test -f 'f82c710_upc.c'; then $(CYGPATH_W) 'f82c710_upc.c'; else $(CYGPATH_W) '$(srcdir)/f82c710_upc.c'; fi` + pcem-fdc.o: fdc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-fdc.Tpo $(DEPDIR)/pcem-fdc.Po @@ -2311,6 +2736,34 @@ pcem-i430vx.obj: i430vx.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-i440fx.o: i440fx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i440fx.o -MD -MP -MF $(DEPDIR)/pcem-i440fx.Tpo -c -o pcem-i440fx.o `test -f 'i440fx.c' || echo '$(srcdir)/'`i440fx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-i440fx.Tpo $(DEPDIR)/pcem-i440fx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='i440fx.c' object='pcem-i440fx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i440fx.o `test -f 'i440fx.c' || echo '$(srcdir)/'`i440fx.c + +pcem-i440fx.obj: i440fx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i440fx.obj -MD -MP -MF $(DEPDIR)/pcem-i440fx.Tpo -c -o pcem-i440fx.obj `if test -f 'i440fx.c'; then $(CYGPATH_W) 'i440fx.c'; else $(CYGPATH_W) '$(srcdir)/i440fx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-i440fx.Tpo $(DEPDIR)/pcem-i440fx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='i440fx.c' object='pcem-i440fx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i440fx.obj `if test -f 'i440fx.c'; then $(CYGPATH_W) 'i440fx.c'; else $(CYGPATH_W) '$(srcdir)/i440fx.c'; fi` + +pcem-i440bx.o: i440bx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i440bx.o -MD -MP -MF $(DEPDIR)/pcem-i440bx.Tpo -c -o pcem-i440bx.o `test -f 'i440bx.c' || echo '$(srcdir)/'`i440bx.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-i440bx.Tpo $(DEPDIR)/pcem-i440bx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='i440bx.c' object='pcem-i440bx.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i440bx.o `test -f 'i440bx.c' || echo '$(srcdir)/'`i440bx.c + +pcem-i440bx.obj: i440bx.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i440bx.obj -MD -MP -MF $(DEPDIR)/pcem-i440bx.Tpo -c -o pcem-i440bx.obj `if test -f 'i440bx.c'; then $(CYGPATH_W) 'i440bx.c'; else $(CYGPATH_W) '$(srcdir)/i440bx.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-i440bx.Tpo $(DEPDIR)/pcem-i440bx.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='i440bx.c' object='pcem-i440bx.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i440bx.obj `if test -f 'i440bx.c'; then $(CYGPATH_W) 'i440bx.c'; else $(CYGPATH_W) '$(srcdir)/i440bx.c'; fi` + pcem-ide.o: ide.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-ide.Tpo $(DEPDIR)/pcem-ide.Po @@ -2885,6 +3338,20 @@ pcem-pc87306.obj: pc87306.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc87306.obj `if test -f 'pc87306.c'; then $(CYGPATH_W) 'pc87306.c'; else $(CYGPATH_W) '$(srcdir)/pc87306.c'; fi` +pcem-pc87307.o: pc87307.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pc87307.o -MD -MP -MF $(DEPDIR)/pcem-pc87307.Tpo -c -o pcem-pc87307.o `test -f 'pc87307.c' || echo '$(srcdir)/'`pc87307.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pc87307.Tpo $(DEPDIR)/pcem-pc87307.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pc87307.c' object='pcem-pc87307.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc87307.o `test -f 'pc87307.c' || echo '$(srcdir)/'`pc87307.c + +pcem-pc87307.obj: pc87307.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pc87307.obj -MD -MP -MF $(DEPDIR)/pcem-pc87307.Tpo -c -o pcem-pc87307.obj `if test -f 'pc87307.c'; then $(CYGPATH_W) 'pc87307.c'; else $(CYGPATH_W) '$(srcdir)/pc87307.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-pc87307.Tpo $(DEPDIR)/pcem-pc87307.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pc87307.c' object='pcem-pc87307.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc87307.obj `if test -f 'pc87307.c'; then $(CYGPATH_W) 'pc87307.c'; else $(CYGPATH_W) '$(srcdir)/pc87307.c'; fi` + pcem-pci.o: pci.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-pci.Tpo $(DEPDIR)/pcem-pci.Po @@ -2927,6 +3394,20 @@ pcem-piix.obj: piix.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-piix_pm.o: piix_pm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-piix_pm.o -MD -MP -MF $(DEPDIR)/pcem-piix_pm.Tpo -c -o pcem-piix_pm.o `test -f 'piix_pm.c' || echo '$(srcdir)/'`piix_pm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-piix_pm.Tpo $(DEPDIR)/pcem-piix_pm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='piix_pm.c' object='pcem-piix_pm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-piix_pm.o `test -f 'piix_pm.c' || echo '$(srcdir)/'`piix_pm.c + +pcem-piix_pm.obj: piix_pm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-piix_pm.obj -MD -MP -MF $(DEPDIR)/pcem-piix_pm.Tpo -c -o pcem-piix_pm.obj `if test -f 'piix_pm.c'; then $(CYGPATH_W) 'piix_pm.c'; else $(CYGPATH_W) '$(srcdir)/piix_pm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-piix_pm.Tpo $(DEPDIR)/pcem-piix_pm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='piix_pm.c' object='pcem-piix_pm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-piix_pm.obj `if test -f 'piix_pm.c'; then $(CYGPATH_W) 'piix_pm.c'; else $(CYGPATH_W) '$(srcdir)/piix_pm.c'; fi` + pcem-pit.o: pit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-pit.Tpo $(DEPDIR)/pcem-pit.Po @@ -3081,6 +3562,20 @@ pcem-rtc_tc8521.obj: rtc_tc8521.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-rtc_tc8521.obj `if test -f 'rtc_tc8521.c'; then $(CYGPATH_W) 'rtc_tc8521.c'; else $(CYGPATH_W) '$(srcdir)/rtc_tc8521.c'; fi` +pcem-scamp.o: scamp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scamp.o -MD -MP -MF $(DEPDIR)/pcem-scamp.Tpo -c -o pcem-scamp.o `test -f 'scamp.c' || echo '$(srcdir)/'`scamp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scamp.Tpo $(DEPDIR)/pcem-scamp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scamp.c' object='pcem-scamp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scamp.o `test -f 'scamp.c' || echo '$(srcdir)/'`scamp.c + +pcem-scamp.obj: scamp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scamp.obj -MD -MP -MF $(DEPDIR)/pcem-scamp.Tpo -c -o pcem-scamp.obj `if test -f 'scamp.c'; then $(CYGPATH_W) 'scamp.c'; else $(CYGPATH_W) '$(srcdir)/scamp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scamp.Tpo $(DEPDIR)/pcem-scamp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scamp.c' object='pcem-scamp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scamp.obj `if test -f 'scamp.c'; then $(CYGPATH_W) 'scamp.c'; else $(CYGPATH_W) '$(srcdir)/scamp.c'; fi` + pcem-scat.o: scat.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scat.o -MD -MP -MF $(DEPDIR)/pcem-scat.Tpo -c -o pcem-scat.o `test -f 'scat.c' || echo '$(srcdir)/'`scat.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scat.Tpo $(DEPDIR)/pcem-scat.Po @@ -3165,6 +3660,20 @@ pcem-scsi_hd.obj: scsi_hd.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_hd.obj `if test -f 'scsi_hd.c'; then $(CYGPATH_W) 'scsi_hd.c'; else $(CYGPATH_W) '$(srcdir)/scsi_hd.c'; fi` +pcem-scsi_ibm.o: scsi_ibm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_ibm.o -MD -MP -MF $(DEPDIR)/pcem-scsi_ibm.Tpo -c -o pcem-scsi_ibm.o `test -f 'scsi_ibm.c' || echo '$(srcdir)/'`scsi_ibm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_ibm.Tpo $(DEPDIR)/pcem-scsi_ibm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_ibm.c' object='pcem-scsi_ibm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_ibm.o `test -f 'scsi_ibm.c' || echo '$(srcdir)/'`scsi_ibm.c + +pcem-scsi_ibm.obj: scsi_ibm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_ibm.obj -MD -MP -MF $(DEPDIR)/pcem-scsi_ibm.Tpo -c -o pcem-scsi_ibm.obj `if test -f 'scsi_ibm.c'; then $(CYGPATH_W) 'scsi_ibm.c'; else $(CYGPATH_W) '$(srcdir)/scsi_ibm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_ibm.Tpo $(DEPDIR)/pcem-scsi_ibm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scsi_ibm.c' object='pcem-scsi_ibm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-scsi_ibm.obj `if test -f 'scsi_ibm.c'; then $(CYGPATH_W) 'scsi_ibm.c'; else $(CYGPATH_W) '$(srcdir)/scsi_ibm.c'; fi` + pcem-scsi_zip.o: scsi_zip.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-scsi_zip.o -MD -MP -MF $(DEPDIR)/pcem-scsi_zip.Tpo -c -o pcem-scsi_zip.o `test -f 'scsi_zip.c' || echo '$(srcdir)/'`scsi_zip.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-scsi_zip.Tpo $(DEPDIR)/pcem-scsi_zip.Po @@ -3305,6 +3814,20 @@ pcem-sound_audiopci.obj: sound_audiopci.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_audiopci.obj `if test -f 'sound_audiopci.c'; then $(CYGPATH_W) 'sound_audiopci.c'; else $(CYGPATH_W) '$(srcdir)/sound_audiopci.c'; fi` +pcem-sound_azt2316a.o: sound_azt2316a.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_azt2316a.o -MD -MP -MF $(DEPDIR)/pcem-sound_azt2316a.Tpo -c -o pcem-sound_azt2316a.o `test -f 'sound_azt2316a.c' || echo '$(srcdir)/'`sound_azt2316a.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_azt2316a.Tpo $(DEPDIR)/pcem-sound_azt2316a.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sound_azt2316a.c' object='pcem-sound_azt2316a.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_azt2316a.o `test -f 'sound_azt2316a.c' || echo '$(srcdir)/'`sound_azt2316a.c + +pcem-sound_azt2316a.obj: sound_azt2316a.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_azt2316a.obj -MD -MP -MF $(DEPDIR)/pcem-sound_azt2316a.Tpo -c -o pcem-sound_azt2316a.obj `if test -f 'sound_azt2316a.c'; then $(CYGPATH_W) 'sound_azt2316a.c'; else $(CYGPATH_W) '$(srcdir)/sound_azt2316a.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-sound_azt2316a.Tpo $(DEPDIR)/pcem-sound_azt2316a.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sound_azt2316a.c' object='pcem-sound_azt2316a.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_azt2316a.obj `if test -f 'sound_azt2316a.c'; then $(CYGPATH_W) 'sound_azt2316a.c'; else $(CYGPATH_W) '$(srcdir)/sound_azt2316a.c'; fi` + pcem-sound_cms.o: sound_cms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-sound_cms.Tpo $(DEPDIR)/pcem-sound_cms.Po @@ -3543,6 +4066,20 @@ pcem-sst39sf010.obj: sst39sf010.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sst39sf010.obj `if test -f 'sst39sf010.c'; then $(CYGPATH_W) 'sst39sf010.c'; else $(CYGPATH_W) '$(srcdir)/sst39sf010.c'; fi` +pcem-superxt.o: superxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-superxt.o -MD -MP -MF $(DEPDIR)/pcem-superxt.Tpo -c -o pcem-superxt.o `test -f 'superxt.c' || echo '$(srcdir)/'`superxt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-superxt.Tpo $(DEPDIR)/pcem-superxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='superxt.c' object='pcem-superxt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-superxt.o `test -f 'superxt.c' || echo '$(srcdir)/'`superxt.c + +pcem-superxt.obj: superxt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-superxt.obj -MD -MP -MF $(DEPDIR)/pcem-superxt.Tpo -c -o pcem-superxt.obj `if test -f 'superxt.c'; then $(CYGPATH_W) 'superxt.c'; else $(CYGPATH_W) '$(srcdir)/superxt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-superxt.Tpo $(DEPDIR)/pcem-superxt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='superxt.c' object='pcem-superxt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-superxt.obj `if test -f 'superxt.c'; then $(CYGPATH_W) 'superxt.c'; else $(CYGPATH_W) '$(srcdir)/superxt.c'; fi` + pcem-tandy_eeprom.o: tandy_eeprom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-tandy_eeprom.o -MD -MP -MF $(DEPDIR)/pcem-tandy_eeprom.Tpo -c -o pcem-tandy_eeprom.o `test -f 'tandy_eeprom.c' || echo '$(srcdir)/'`tandy_eeprom.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-tandy_eeprom.Tpo $(DEPDIR)/pcem-tandy_eeprom.Po @@ -3767,6 +4304,20 @@ pcem-vid_compaq_cga.obj: vid_compaq_cga.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_compaq_cga.obj `if test -f 'vid_compaq_cga.c'; then $(CYGPATH_W) 'vid_compaq_cga.c'; else $(CYGPATH_W) '$(srcdir)/vid_compaq_cga.c'; fi` +pcem-vid_ddc.o: vid_ddc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ddc.o -MD -MP -MF $(DEPDIR)/pcem-vid_ddc.Tpo -c -o pcem-vid_ddc.o `test -f 'vid_ddc.c' || echo '$(srcdir)/'`vid_ddc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ddc.Tpo $(DEPDIR)/pcem-vid_ddc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_ddc.c' object='pcem-vid_ddc.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ddc.o `test -f 'vid_ddc.c' || echo '$(srcdir)/'`vid_ddc.c + +pcem-vid_ddc.obj: vid_ddc.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ddc.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ddc.Tpo -c -o pcem-vid_ddc.obj `if test -f 'vid_ddc.c'; then $(CYGPATH_W) 'vid_ddc.c'; else $(CYGPATH_W) '$(srcdir)/vid_ddc.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ddc.Tpo $(DEPDIR)/pcem-vid_ddc.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_ddc.c' object='pcem-vid_ddc.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ddc.obj `if test -f 'vid_ddc.c'; then $(CYGPATH_W) 'vid_ddc.c'; else $(CYGPATH_W) '$(srcdir)/vid_ddc.c'; fi` + pcem-vid_ega.o: vid_ega.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_ega.Tpo $(DEPDIR)/pcem-vid_ega.Po @@ -3921,6 +4472,20 @@ pcem-vid_mda.obj: vid_mda.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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_mga.o: vid_mga.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_mga.o -MD -MP -MF $(DEPDIR)/pcem-vid_mga.Tpo -c -o pcem-vid_mga.o `test -f 'vid_mga.c' || echo '$(srcdir)/'`vid_mga.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_mga.Tpo $(DEPDIR)/pcem-vid_mga.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_mga.c' object='pcem-vid_mga.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_mga.o `test -f 'vid_mga.c' || echo '$(srcdir)/'`vid_mga.c + +pcem-vid_mga.obj: vid_mga.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_mga.obj -MD -MP -MF $(DEPDIR)/pcem-vid_mga.Tpo -c -o pcem-vid_mga.obj `if test -f 'vid_mga.c'; then $(CYGPATH_W) 'vid_mga.c'; else $(CYGPATH_W) '$(srcdir)/vid_mga.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_mga.Tpo $(DEPDIR)/pcem-vid_mga.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_mga.c' object='pcem-vid_mga.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_mga.obj `if test -f 'vid_mga.c'; then $(CYGPATH_W) 'vid_mga.c'; else $(CYGPATH_W) '$(srcdir)/vid_mga.c'; fi` + pcem-vid_olivetti_m24.o: vid_olivetti_m24.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-vid_olivetti_m24.Tpo $(DEPDIR)/pcem-vid_olivetti_m24.Po @@ -4299,6 +4864,146 @@ pcem-vid_voodoo.obj: vid_voodoo.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-vid_voodoo_banshee.o: vid_voodoo_banshee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_banshee.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_banshee.Tpo -c -o pcem-vid_voodoo_banshee.o `test -f 'vid_voodoo_banshee.c' || echo '$(srcdir)/'`vid_voodoo_banshee.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_banshee.Tpo $(DEPDIR)/pcem-vid_voodoo_banshee.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_banshee.c' object='pcem-vid_voodoo_banshee.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_banshee.o `test -f 'vid_voodoo_banshee.c' || echo '$(srcdir)/'`vid_voodoo_banshee.c + +pcem-vid_voodoo_banshee.obj: vid_voodoo_banshee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_banshee.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_banshee.Tpo -c -o pcem-vid_voodoo_banshee.obj `if test -f 'vid_voodoo_banshee.c'; then $(CYGPATH_W) 'vid_voodoo_banshee.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_banshee.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_banshee.Tpo $(DEPDIR)/pcem-vid_voodoo_banshee.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_banshee.c' object='pcem-vid_voodoo_banshee.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_banshee.obj `if test -f 'vid_voodoo_banshee.c'; then $(CYGPATH_W) 'vid_voodoo_banshee.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_banshee.c'; fi` + +pcem-vid_voodoo_banshee_blitter.o: vid_voodoo_banshee_blitter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_banshee_blitter.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Tpo -c -o pcem-vid_voodoo_banshee_blitter.o `test -f 'vid_voodoo_banshee_blitter.c' || echo '$(srcdir)/'`vid_voodoo_banshee_blitter.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Tpo $(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_banshee_blitter.c' object='pcem-vid_voodoo_banshee_blitter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_banshee_blitter.o `test -f 'vid_voodoo_banshee_blitter.c' || echo '$(srcdir)/'`vid_voodoo_banshee_blitter.c + +pcem-vid_voodoo_banshee_blitter.obj: vid_voodoo_banshee_blitter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_banshee_blitter.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Tpo -c -o pcem-vid_voodoo_banshee_blitter.obj `if test -f 'vid_voodoo_banshee_blitter.c'; then $(CYGPATH_W) 'vid_voodoo_banshee_blitter.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_banshee_blitter.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Tpo $(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_banshee_blitter.c' object='pcem-vid_voodoo_banshee_blitter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_banshee_blitter.obj `if test -f 'vid_voodoo_banshee_blitter.c'; then $(CYGPATH_W) 'vid_voodoo_banshee_blitter.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_banshee_blitter.c'; fi` + +pcem-vid_voodoo_blitter.o: vid_voodoo_blitter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_blitter.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_blitter.Tpo -c -o pcem-vid_voodoo_blitter.o `test -f 'vid_voodoo_blitter.c' || echo '$(srcdir)/'`vid_voodoo_blitter.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_blitter.Tpo $(DEPDIR)/pcem-vid_voodoo_blitter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_blitter.c' object='pcem-vid_voodoo_blitter.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_blitter.o `test -f 'vid_voodoo_blitter.c' || echo '$(srcdir)/'`vid_voodoo_blitter.c + +pcem-vid_voodoo_blitter.obj: vid_voodoo_blitter.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_blitter.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_blitter.Tpo -c -o pcem-vid_voodoo_blitter.obj `if test -f 'vid_voodoo_blitter.c'; then $(CYGPATH_W) 'vid_voodoo_blitter.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_blitter.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_blitter.Tpo $(DEPDIR)/pcem-vid_voodoo_blitter.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_blitter.c' object='pcem-vid_voodoo_blitter.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_blitter.obj `if test -f 'vid_voodoo_blitter.c'; then $(CYGPATH_W) 'vid_voodoo_blitter.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_blitter.c'; fi` + +pcem-vid_voodoo_display.o: vid_voodoo_display.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_display.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_display.Tpo -c -o pcem-vid_voodoo_display.o `test -f 'vid_voodoo_display.c' || echo '$(srcdir)/'`vid_voodoo_display.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_display.Tpo $(DEPDIR)/pcem-vid_voodoo_display.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_display.c' object='pcem-vid_voodoo_display.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_display.o `test -f 'vid_voodoo_display.c' || echo '$(srcdir)/'`vid_voodoo_display.c + +pcem-vid_voodoo_display.obj: vid_voodoo_display.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_display.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_display.Tpo -c -o pcem-vid_voodoo_display.obj `if test -f 'vid_voodoo_display.c'; then $(CYGPATH_W) 'vid_voodoo_display.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_display.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_display.Tpo $(DEPDIR)/pcem-vid_voodoo_display.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_display.c' object='pcem-vid_voodoo_display.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_display.obj `if test -f 'vid_voodoo_display.c'; then $(CYGPATH_W) 'vid_voodoo_display.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_display.c'; fi` + +pcem-vid_voodoo_fb.o: vid_voodoo_fb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_fb.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_fb.Tpo -c -o pcem-vid_voodoo_fb.o `test -f 'vid_voodoo_fb.c' || echo '$(srcdir)/'`vid_voodoo_fb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_fb.Tpo $(DEPDIR)/pcem-vid_voodoo_fb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_fb.c' object='pcem-vid_voodoo_fb.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_fb.o `test -f 'vid_voodoo_fb.c' || echo '$(srcdir)/'`vid_voodoo_fb.c + +pcem-vid_voodoo_fb.obj: vid_voodoo_fb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_fb.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_fb.Tpo -c -o pcem-vid_voodoo_fb.obj `if test -f 'vid_voodoo_fb.c'; then $(CYGPATH_W) 'vid_voodoo_fb.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_fb.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_fb.Tpo $(DEPDIR)/pcem-vid_voodoo_fb.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_fb.c' object='pcem-vid_voodoo_fb.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_fb.obj `if test -f 'vid_voodoo_fb.c'; then $(CYGPATH_W) 'vid_voodoo_fb.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_fb.c'; fi` + +pcem-vid_voodoo_fifo.o: vid_voodoo_fifo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_fifo.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_fifo.Tpo -c -o pcem-vid_voodoo_fifo.o `test -f 'vid_voodoo_fifo.c' || echo '$(srcdir)/'`vid_voodoo_fifo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_fifo.Tpo $(DEPDIR)/pcem-vid_voodoo_fifo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_fifo.c' object='pcem-vid_voodoo_fifo.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_fifo.o `test -f 'vid_voodoo_fifo.c' || echo '$(srcdir)/'`vid_voodoo_fifo.c + +pcem-vid_voodoo_fifo.obj: vid_voodoo_fifo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_fifo.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_fifo.Tpo -c -o pcem-vid_voodoo_fifo.obj `if test -f 'vid_voodoo_fifo.c'; then $(CYGPATH_W) 'vid_voodoo_fifo.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_fifo.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_fifo.Tpo $(DEPDIR)/pcem-vid_voodoo_fifo.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_fifo.c' object='pcem-vid_voodoo_fifo.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_fifo.obj `if test -f 'vid_voodoo_fifo.c'; then $(CYGPATH_W) 'vid_voodoo_fifo.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_fifo.c'; fi` + +pcem-vid_voodoo_reg.o: vid_voodoo_reg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_reg.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_reg.Tpo -c -o pcem-vid_voodoo_reg.o `test -f 'vid_voodoo_reg.c' || echo '$(srcdir)/'`vid_voodoo_reg.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_reg.Tpo $(DEPDIR)/pcem-vid_voodoo_reg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_reg.c' object='pcem-vid_voodoo_reg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_reg.o `test -f 'vid_voodoo_reg.c' || echo '$(srcdir)/'`vid_voodoo_reg.c + +pcem-vid_voodoo_reg.obj: vid_voodoo_reg.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_reg.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_reg.Tpo -c -o pcem-vid_voodoo_reg.obj `if test -f 'vid_voodoo_reg.c'; then $(CYGPATH_W) 'vid_voodoo_reg.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_reg.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_reg.Tpo $(DEPDIR)/pcem-vid_voodoo_reg.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_reg.c' object='pcem-vid_voodoo_reg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_reg.obj `if test -f 'vid_voodoo_reg.c'; then $(CYGPATH_W) 'vid_voodoo_reg.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_reg.c'; fi` + +pcem-vid_voodoo_render.o: vid_voodoo_render.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_render.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_render.Tpo -c -o pcem-vid_voodoo_render.o `test -f 'vid_voodoo_render.c' || echo '$(srcdir)/'`vid_voodoo_render.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_render.Tpo $(DEPDIR)/pcem-vid_voodoo_render.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_render.c' object='pcem-vid_voodoo_render.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_render.o `test -f 'vid_voodoo_render.c' || echo '$(srcdir)/'`vid_voodoo_render.c + +pcem-vid_voodoo_render.obj: vid_voodoo_render.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_render.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_render.Tpo -c -o pcem-vid_voodoo_render.obj `if test -f 'vid_voodoo_render.c'; then $(CYGPATH_W) 'vid_voodoo_render.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_render.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_render.Tpo $(DEPDIR)/pcem-vid_voodoo_render.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_render.c' object='pcem-vid_voodoo_render.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_render.obj `if test -f 'vid_voodoo_render.c'; then $(CYGPATH_W) 'vid_voodoo_render.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_render.c'; fi` + +pcem-vid_voodoo_setup.o: vid_voodoo_setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_setup.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_setup.Tpo -c -o pcem-vid_voodoo_setup.o `test -f 'vid_voodoo_setup.c' || echo '$(srcdir)/'`vid_voodoo_setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_setup.Tpo $(DEPDIR)/pcem-vid_voodoo_setup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_setup.c' object='pcem-vid_voodoo_setup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_setup.o `test -f 'vid_voodoo_setup.c' || echo '$(srcdir)/'`vid_voodoo_setup.c + +pcem-vid_voodoo_setup.obj: vid_voodoo_setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_setup.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_setup.Tpo -c -o pcem-vid_voodoo_setup.obj `if test -f 'vid_voodoo_setup.c'; then $(CYGPATH_W) 'vid_voodoo_setup.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_setup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_setup.Tpo $(DEPDIR)/pcem-vid_voodoo_setup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_setup.c' object='pcem-vid_voodoo_setup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_setup.obj `if test -f 'vid_voodoo_setup.c'; then $(CYGPATH_W) 'vid_voodoo_setup.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_setup.c'; fi` + +pcem-vid_voodoo_texture.o: vid_voodoo_texture.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_texture.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_texture.Tpo -c -o pcem-vid_voodoo_texture.o `test -f 'vid_voodoo_texture.c' || echo '$(srcdir)/'`vid_voodoo_texture.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_texture.Tpo $(DEPDIR)/pcem-vid_voodoo_texture.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_texture.c' object='pcem-vid_voodoo_texture.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_texture.o `test -f 'vid_voodoo_texture.c' || echo '$(srcdir)/'`vid_voodoo_texture.c + +pcem-vid_voodoo_texture.obj: vid_voodoo_texture.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo_texture.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo_texture.Tpo -c -o pcem-vid_voodoo_texture.obj `if test -f 'vid_voodoo_texture.c'; then $(CYGPATH_W) 'vid_voodoo_texture.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_texture.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vid_voodoo_texture.Tpo $(DEPDIR)/pcem-vid_voodoo_texture.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vid_voodoo_texture.c' object='pcem-vid_voodoo_texture.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo_texture.obj `if test -f 'vid_voodoo_texture.c'; then $(CYGPATH_W) 'vid_voodoo_texture.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo_texture.c'; fi` + pcem-video.o: video.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-video.Tpo $(DEPDIR)/pcem-video.Po @@ -4355,6 +5060,20 @@ pcem-vt82c586b.obj: vt82c586b.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vt82c586b.obj `if test -f 'vt82c586b.c'; then $(CYGPATH_W) 'vt82c586b.c'; else $(CYGPATH_W) '$(srcdir)/vt82c586b.c'; fi` +pcem-vl82c480.o: vl82c480.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vl82c480.o -MD -MP -MF $(DEPDIR)/pcem-vl82c480.Tpo -c -o pcem-vl82c480.o `test -f 'vl82c480.c' || echo '$(srcdir)/'`vl82c480.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vl82c480.Tpo $(DEPDIR)/pcem-vl82c480.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vl82c480.c' object='pcem-vl82c480.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vl82c480.o `test -f 'vl82c480.c' || echo '$(srcdir)/'`vl82c480.c + +pcem-vl82c480.obj: vl82c480.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vl82c480.obj -MD -MP -MF $(DEPDIR)/pcem-vl82c480.Tpo -c -o pcem-vl82c480.obj `if test -f 'vl82c480.c'; then $(CYGPATH_W) 'vl82c480.c'; else $(CYGPATH_W) '$(srcdir)/vl82c480.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-vl82c480.Tpo $(DEPDIR)/pcem-vl82c480.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vl82c480.c' object='pcem-vl82c480.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vl82c480.obj `if test -f 'vl82c480.c'; then $(CYGPATH_W) 'vl82c480.c'; else $(CYGPATH_W) '$(srcdir)/vl82c480.c'; fi` + pcem-w83877tf.o: w83877tf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-w83877tf.o -MD -MP -MF $(DEPDIR)/pcem-w83877tf.Tpo -c -o pcem-w83877tf.o `test -f 'w83877tf.c' || echo '$(srcdir)/'`w83877tf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-w83877tf.Tpo $(DEPDIR)/pcem-w83877tf.Po @@ -4369,6 +5088,20 @@ pcem-w83877tf.obj: w83877tf.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-w83877tf.obj `if test -f 'w83877tf.c'; then $(CYGPATH_W) 'w83877tf.c'; else $(CYGPATH_W) '$(srcdir)/w83877tf.c'; fi` +pcem-w83977tf.o: w83977tf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-w83977tf.o -MD -MP -MF $(DEPDIR)/pcem-w83977tf.Tpo -c -o pcem-w83977tf.o `test -f 'w83977tf.c' || echo '$(srcdir)/'`w83977tf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-w83977tf.Tpo $(DEPDIR)/pcem-w83977tf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='w83977tf.c' object='pcem-w83977tf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-w83977tf.o `test -f 'w83977tf.c' || echo '$(srcdir)/'`w83977tf.c + +pcem-w83977tf.obj: w83977tf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-w83977tf.obj -MD -MP -MF $(DEPDIR)/pcem-w83977tf.Tpo -c -o pcem-w83977tf.obj `if test -f 'w83977tf.c'; then $(CYGPATH_W) 'w83977tf.c'; else $(CYGPATH_W) '$(srcdir)/w83977tf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-w83977tf.Tpo $(DEPDIR)/pcem-w83977tf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='w83977tf.c' object='pcem-w83977tf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-w83977tf.obj `if test -f 'w83977tf.c'; then $(CYGPATH_W) 'w83977tf.c'; else $(CYGPATH_W) '$(srcdir)/w83977tf.c'; fi` + pcem-x86seg.o: x86seg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(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_V_at)$(am__mv) $(DEPDIR)/pcem-x86seg.Tpo $(DEPDIR)/pcem-x86seg.Po @@ -4397,6 +5130,20 @@ pcem-x87.obj: x87.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-x87_timings.o: x87_timings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-x87_timings.o -MD -MP -MF $(DEPDIR)/pcem-x87_timings.Tpo -c -o pcem-x87_timings.o `test -f 'x87_timings.c' || echo '$(srcdir)/'`x87_timings.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-x87_timings.Tpo $(DEPDIR)/pcem-x87_timings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x87_timings.c' object='pcem-x87_timings.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-x87_timings.o `test -f 'x87_timings.c' || echo '$(srcdir)/'`x87_timings.c + +pcem-x87_timings.obj: x87_timings.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-x87_timings.obj -MD -MP -MF $(DEPDIR)/pcem-x87_timings.Tpo -c -o pcem-x87_timings.obj `if test -f 'x87_timings.c'; then $(CYGPATH_W) 'x87_timings.c'; else $(CYGPATH_W) '$(srcdir)/x87_timings.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-x87_timings.Tpo $(DEPDIR)/pcem-x87_timings.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='x87_timings.c' object='pcem-x87_timings.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-x87_timings.obj `if test -f 'x87_timings.c'; then $(CYGPATH_W) 'x87_timings.c'; else $(CYGPATH_W) '$(srcdir)/x87_timings.c'; fi` + pcem-xi8088.o: xi8088.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-xi8088.o -MD -MP -MF $(DEPDIR)/pcem-xi8088.Tpo -c -o pcem-xi8088.o `test -f 'xi8088.c' || echo '$(srcdir)/'`xi8088.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-xi8088.Tpo $(DEPDIR)/pcem-xi8088.Po @@ -4439,6 +5186,118 @@ dosbox/pcem-vid_cga_comp.obj: dosbox/vid_cga_comp.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o dosbox/pcem-vid_cga_comp.obj `if test -f 'dosbox/vid_cga_comp.c'; then $(CYGPATH_W) 'dosbox/vid_cga_comp.c'; else $(CYGPATH_W) '$(srcdir)/dosbox/vid_cga_comp.c'; fi` +minivhd/pcem-cwalk.o: minivhd/cwalk.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-cwalk.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-cwalk.Tpo -c -o minivhd/pcem-cwalk.o `test -f 'minivhd/cwalk.c' || echo '$(srcdir)/'`minivhd/cwalk.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-cwalk.Tpo minivhd/$(DEPDIR)/pcem-cwalk.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/cwalk.c' object='minivhd/pcem-cwalk.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-cwalk.o `test -f 'minivhd/cwalk.c' || echo '$(srcdir)/'`minivhd/cwalk.c + +minivhd/pcem-cwalk.obj: minivhd/cwalk.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-cwalk.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-cwalk.Tpo -c -o minivhd/pcem-cwalk.obj `if test -f 'minivhd/cwalk.c'; then $(CYGPATH_W) 'minivhd/cwalk.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/cwalk.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-cwalk.Tpo minivhd/$(DEPDIR)/pcem-cwalk.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/cwalk.c' object='minivhd/pcem-cwalk.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-cwalk.obj `if test -f 'minivhd/cwalk.c'; then $(CYGPATH_W) 'minivhd/cwalk.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/cwalk.c'; fi` + +minivhd/pcem-libxml2_encoding.o: minivhd/libxml2_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-libxml2_encoding.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-libxml2_encoding.Tpo -c -o minivhd/pcem-libxml2_encoding.o `test -f 'minivhd/libxml2_encoding.c' || echo '$(srcdir)/'`minivhd/libxml2_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-libxml2_encoding.Tpo minivhd/$(DEPDIR)/pcem-libxml2_encoding.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/libxml2_encoding.c' object='minivhd/pcem-libxml2_encoding.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-libxml2_encoding.o `test -f 'minivhd/libxml2_encoding.c' || echo '$(srcdir)/'`minivhd/libxml2_encoding.c + +minivhd/pcem-libxml2_encoding.obj: minivhd/libxml2_encoding.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-libxml2_encoding.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-libxml2_encoding.Tpo -c -o minivhd/pcem-libxml2_encoding.obj `if test -f 'minivhd/libxml2_encoding.c'; then $(CYGPATH_W) 'minivhd/libxml2_encoding.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/libxml2_encoding.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-libxml2_encoding.Tpo minivhd/$(DEPDIR)/pcem-libxml2_encoding.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/libxml2_encoding.c' object='minivhd/pcem-libxml2_encoding.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-libxml2_encoding.obj `if test -f 'minivhd/libxml2_encoding.c'; then $(CYGPATH_W) 'minivhd/libxml2_encoding.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/libxml2_encoding.c'; fi` + +minivhd/pcem-minivhd_convert.o: minivhd/minivhd_convert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_convert.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_convert.Tpo -c -o minivhd/pcem-minivhd_convert.o `test -f 'minivhd/minivhd_convert.c' || echo '$(srcdir)/'`minivhd/minivhd_convert.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_convert.Tpo minivhd/$(DEPDIR)/pcem-minivhd_convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_convert.c' object='minivhd/pcem-minivhd_convert.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_convert.o `test -f 'minivhd/minivhd_convert.c' || echo '$(srcdir)/'`minivhd/minivhd_convert.c + +minivhd/pcem-minivhd_convert.obj: minivhd/minivhd_convert.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_convert.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_convert.Tpo -c -o minivhd/pcem-minivhd_convert.obj `if test -f 'minivhd/minivhd_convert.c'; then $(CYGPATH_W) 'minivhd/minivhd_convert.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_convert.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_convert.Tpo minivhd/$(DEPDIR)/pcem-minivhd_convert.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_convert.c' object='minivhd/pcem-minivhd_convert.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_convert.obj `if test -f 'minivhd/minivhd_convert.c'; then $(CYGPATH_W) 'minivhd/minivhd_convert.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_convert.c'; fi` + +minivhd/pcem-minivhd_create.o: minivhd/minivhd_create.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_create.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_create.Tpo -c -o minivhd/pcem-minivhd_create.o `test -f 'minivhd/minivhd_create.c' || echo '$(srcdir)/'`minivhd/minivhd_create.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_create.Tpo minivhd/$(DEPDIR)/pcem-minivhd_create.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_create.c' object='minivhd/pcem-minivhd_create.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_create.o `test -f 'minivhd/minivhd_create.c' || echo '$(srcdir)/'`minivhd/minivhd_create.c + +minivhd/pcem-minivhd_create.obj: minivhd/minivhd_create.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_create.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_create.Tpo -c -o minivhd/pcem-minivhd_create.obj `if test -f 'minivhd/minivhd_create.c'; then $(CYGPATH_W) 'minivhd/minivhd_create.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_create.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_create.Tpo minivhd/$(DEPDIR)/pcem-minivhd_create.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_create.c' object='minivhd/pcem-minivhd_create.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_create.obj `if test -f 'minivhd/minivhd_create.c'; then $(CYGPATH_W) 'minivhd/minivhd_create.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_create.c'; fi` + +minivhd/pcem-minivhd_io.o: minivhd/minivhd_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_io.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_io.Tpo -c -o minivhd/pcem-minivhd_io.o `test -f 'minivhd/minivhd_io.c' || echo '$(srcdir)/'`minivhd/minivhd_io.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_io.Tpo minivhd/$(DEPDIR)/pcem-minivhd_io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_io.c' object='minivhd/pcem-minivhd_io.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_io.o `test -f 'minivhd/minivhd_io.c' || echo '$(srcdir)/'`minivhd/minivhd_io.c + +minivhd/pcem-minivhd_io.obj: minivhd/minivhd_io.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_io.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_io.Tpo -c -o minivhd/pcem-minivhd_io.obj `if test -f 'minivhd/minivhd_io.c'; then $(CYGPATH_W) 'minivhd/minivhd_io.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_io.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_io.Tpo minivhd/$(DEPDIR)/pcem-minivhd_io.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_io.c' object='minivhd/pcem-minivhd_io.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_io.obj `if test -f 'minivhd/minivhd_io.c'; then $(CYGPATH_W) 'minivhd/minivhd_io.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_io.c'; fi` + +minivhd/pcem-minivhd_manage.o: minivhd/minivhd_manage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_manage.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_manage.Tpo -c -o minivhd/pcem-minivhd_manage.o `test -f 'minivhd/minivhd_manage.c' || echo '$(srcdir)/'`minivhd/minivhd_manage.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_manage.Tpo minivhd/$(DEPDIR)/pcem-minivhd_manage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_manage.c' object='minivhd/pcem-minivhd_manage.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_manage.o `test -f 'minivhd/minivhd_manage.c' || echo '$(srcdir)/'`minivhd/minivhd_manage.c + +minivhd/pcem-minivhd_manage.obj: minivhd/minivhd_manage.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_manage.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_manage.Tpo -c -o minivhd/pcem-minivhd_manage.obj `if test -f 'minivhd/minivhd_manage.c'; then $(CYGPATH_W) 'minivhd/minivhd_manage.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_manage.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_manage.Tpo minivhd/$(DEPDIR)/pcem-minivhd_manage.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_manage.c' object='minivhd/pcem-minivhd_manage.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_manage.obj `if test -f 'minivhd/minivhd_manage.c'; then $(CYGPATH_W) 'minivhd/minivhd_manage.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_manage.c'; fi` + +minivhd/pcem-minivhd_struct_rw.o: minivhd/minivhd_struct_rw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_struct_rw.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Tpo -c -o minivhd/pcem-minivhd_struct_rw.o `test -f 'minivhd/minivhd_struct_rw.c' || echo '$(srcdir)/'`minivhd/minivhd_struct_rw.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Tpo minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_struct_rw.c' object='minivhd/pcem-minivhd_struct_rw.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_struct_rw.o `test -f 'minivhd/minivhd_struct_rw.c' || echo '$(srcdir)/'`minivhd/minivhd_struct_rw.c + +minivhd/pcem-minivhd_struct_rw.obj: minivhd/minivhd_struct_rw.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_struct_rw.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Tpo -c -o minivhd/pcem-minivhd_struct_rw.obj `if test -f 'minivhd/minivhd_struct_rw.c'; then $(CYGPATH_W) 'minivhd/minivhd_struct_rw.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_struct_rw.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Tpo minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_struct_rw.c' object='minivhd/pcem-minivhd_struct_rw.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_struct_rw.obj `if test -f 'minivhd/minivhd_struct_rw.c'; then $(CYGPATH_W) 'minivhd/minivhd_struct_rw.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_struct_rw.c'; fi` + +minivhd/pcem-minivhd_util.o: minivhd/minivhd_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_util.o -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_util.Tpo -c -o minivhd/pcem-minivhd_util.o `test -f 'minivhd/minivhd_util.c' || echo '$(srcdir)/'`minivhd/minivhd_util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_util.Tpo minivhd/$(DEPDIR)/pcem-minivhd_util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_util.c' object='minivhd/pcem-minivhd_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_util.o `test -f 'minivhd/minivhd_util.c' || echo '$(srcdir)/'`minivhd/minivhd_util.c + +minivhd/pcem-minivhd_util.obj: minivhd/minivhd_util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT minivhd/pcem-minivhd_util.obj -MD -MP -MF minivhd/$(DEPDIR)/pcem-minivhd_util.Tpo -c -o minivhd/pcem-minivhd_util.obj `if test -f 'minivhd/minivhd_util.c'; then $(CYGPATH_W) 'minivhd/minivhd_util.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) minivhd/$(DEPDIR)/pcem-minivhd_util.Tpo minivhd/$(DEPDIR)/pcem-minivhd_util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='minivhd/minivhd_util.c' object='minivhd/pcem-minivhd_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o minivhd/pcem-minivhd_util.obj `if test -f 'minivhd/minivhd_util.c'; then $(CYGPATH_W) 'minivhd/minivhd_util.c'; else $(CYGPATH_W) '$(srcdir)/minivhd/minivhd_util.c'; fi` + pcem-wx-config_sel.o: wx-config_sel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wx-config_sel.o -MD -MP -MF $(DEPDIR)/pcem-wx-config_sel.Tpo -c -o pcem-wx-config_sel.o `test -f 'wx-config_sel.c' || echo '$(srcdir)/'`wx-config_sel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pcem-wx-config_sel.Tpo $(DEPDIR)/pcem-wx-config_sel.Po @@ -5825,7 +6684,10 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -5891,6 +6753,8 @@ distclean-generic: -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f dosbox/$(DEPDIR)/$(am__dirstamp) -rm -f dosbox/$(am__dirstamp) + -rm -f minivhd/$(DEPDIR)/$(am__dirstamp) + -rm -f minivhd/$(am__dirstamp) -rm -f resid-fp/$(DEPDIR)/$(am__dirstamp) -rm -f resid-fp/$(am__dirstamp) -rm -f slirp/$(DEPDIR)/$(am__dirstamp) @@ -5904,7 +6768,362 @@ clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) + -rm -f ./$(DEPDIR)/pcem-386.Po + -rm -f ./$(DEPDIR)/pcem-386_common.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec_ops.Po + -rm -f ./$(DEPDIR)/pcem-808x.Po + -rm -f ./$(DEPDIR)/pcem-82091aa.Po + -rm -f ./$(DEPDIR)/pcem-acc2036.Po + -rm -f ./$(DEPDIR)/pcem-acc2168.Po + -rm -f ./$(DEPDIR)/pcem-acc3221.Po + -rm -f ./$(DEPDIR)/pcem-acer386sx.Po + -rm -f ./$(DEPDIR)/pcem-ali1429.Po + -rm -f ./$(DEPDIR)/pcem-amstrad.Po + -rm -f ./$(DEPDIR)/pcem-cassette.Po + -rm -f ./$(DEPDIR)/pcem-cbm_io.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-image.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-null.Po + -rm -f ./$(DEPDIR)/pcem-cmd640.Po + -rm -f ./$(DEPDIR)/pcem-codegen.Po + -rm -f ./$(DEPDIR)/pcem-codegen_accumulate.Po + -rm -f ./$(DEPDIR)/pcem-codegen_allocator.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_imm.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_block.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ir.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_3dnow.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_arith.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_branch.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_arith.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_constant.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_misc.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_helpers.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_jump.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_logic.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_misc.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_arith.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_logic.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_pack.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_shift.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mov.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_shift.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_stack.Po + -rm -f ./$(DEPDIR)/pcem-codegen_reg.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_486.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_686.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_common.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_cyrixiii.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_k6.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_p6.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_pentium.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip2.Po + -rm -f ./$(DEPDIR)/pcem-compaq.Po + -rm -f ./$(DEPDIR)/pcem-config.Po + -rm -f ./$(DEPDIR)/pcem-cpu.Po + -rm -f ./$(DEPDIR)/pcem-cpu_tables.Po + -rm -f ./$(DEPDIR)/pcem-cs8230.Po + -rm -f ./$(DEPDIR)/pcem-dells200.Po + -rm -f ./$(DEPDIR)/pcem-device.Po + -rm -f ./$(DEPDIR)/pcem-disc.Po + -rm -f ./$(DEPDIR)/pcem-disc_fdi.Po + -rm -f ./$(DEPDIR)/pcem-disc_img.Po + -rm -f ./$(DEPDIR)/pcem-disc_sector.Po + -rm -f ./$(DEPDIR)/pcem-dma.Po + -rm -f ./$(DEPDIR)/pcem-esdi_at.Po + -rm -f ./$(DEPDIR)/pcem-f82c710_upc.Po + -rm -f ./$(DEPDIR)/pcem-fdc.Po + -rm -f ./$(DEPDIR)/pcem-fdc37c665.Po + -rm -f ./$(DEPDIR)/pcem-fdc37c93x.Po + -rm -f ./$(DEPDIR)/pcem-fdd.Po + -rm -f ./$(DEPDIR)/pcem-fdi2raw.Po + -rm -f ./$(DEPDIR)/pcem-gameport.Po + -rm -f ./$(DEPDIR)/pcem-hdd.Po + -rm -f ./$(DEPDIR)/pcem-hdd_esdi.Po + -rm -f ./$(DEPDIR)/pcem-hdd_file.Po + -rm -f ./$(DEPDIR)/pcem-headland.Po + -rm -f ./$(DEPDIR)/pcem-i430fx.Po + -rm -f ./$(DEPDIR)/pcem-i430hx.Po + -rm -f ./$(DEPDIR)/pcem-i430lx.Po + -rm -f ./$(DEPDIR)/pcem-i430vx.Po + -rm -f ./$(DEPDIR)/pcem-i440bx.Po + -rm -f ./$(DEPDIR)/pcem-i440fx.Po + -rm -f ./$(DEPDIR)/pcem-ide.Po + -rm -f ./$(DEPDIR)/pcem-ide_atapi.Po + -rm -f ./$(DEPDIR)/pcem-ide_sff8038i.Po + -rm -f ./$(DEPDIR)/pcem-intel.Po + -rm -f ./$(DEPDIR)/pcem-intel_flash.Po + -rm -f ./$(DEPDIR)/pcem-io.Po + -rm -f ./$(DEPDIR)/pcem-jim.Po + -rm -f ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po + -rm -f ./$(DEPDIR)/pcem-joystick_standard.Po + -rm -f ./$(DEPDIR)/pcem-joystick_sw_pad.Po + -rm -f ./$(DEPDIR)/pcem-joystick_tm_fcs.Po + -rm -f ./$(DEPDIR)/pcem-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_amstrad.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_at.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_olim24.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_xt.Po + -rm -f ./$(DEPDIR)/pcem-laserxt.Po + -rm -f ./$(DEPDIR)/pcem-lpt.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dac.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dss.Po + -rm -f ./$(DEPDIR)/pcem-mca.Po + -rm -f ./$(DEPDIR)/pcem-mcr.Po + -rm -f ./$(DEPDIR)/pcem-mem.Po + -rm -f ./$(DEPDIR)/pcem-mem_bios.Po + -rm -f ./$(DEPDIR)/pcem-mfm_at.Po + -rm -f ./$(DEPDIR)/pcem-mfm_xebec.Po + -rm -f ./$(DEPDIR)/pcem-midi_alsa.Po + -rm -f ./$(DEPDIR)/pcem-model.Po + -rm -f ./$(DEPDIR)/pcem-mouse.Po + -rm -f ./$(DEPDIR)/pcem-mouse_msystems.Po + -rm -f ./$(DEPDIR)/pcem-mouse_ps2.Po + -rm -f ./$(DEPDIR)/pcem-mouse_serial.Po + -rm -f ./$(DEPDIR)/pcem-mvp3.Po + -rm -f ./$(DEPDIR)/pcem-ne2000.Po + -rm -f ./$(DEPDIR)/pcem-neat.Po + -rm -f ./$(DEPDIR)/pcem-nethandler.Po + -rm -f ./$(DEPDIR)/pcem-nmi.Po + -rm -f ./$(DEPDIR)/pcem-nvr.Po + -rm -f ./$(DEPDIR)/pcem-nvr_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-opti495.Po + -rm -f ./$(DEPDIR)/pcem-paths.Po + -rm -f ./$(DEPDIR)/pcem-pc.Po + -rm -f ./$(DEPDIR)/pcem-pc87306.Po + -rm -f ./$(DEPDIR)/pcem-pc87307.Po + -rm -f ./$(DEPDIR)/pcem-pci.Po + -rm -f ./$(DEPDIR)/pcem-pic.Po + -rm -f ./$(DEPDIR)/pcem-piix.Po + -rm -f ./$(DEPDIR)/pcem-piix_pm.Po + -rm -f ./$(DEPDIR)/pcem-pit.Po + -rm -f ./$(DEPDIR)/pcem-ppi.Po + -rm -f ./$(DEPDIR)/pcem-ps1.Po + -rm -f ./$(DEPDIR)/pcem-ps2.Po + -rm -f ./$(DEPDIR)/pcem-ps2_mca.Po + -rm -f ./$(DEPDIR)/pcem-ps2_nvr.Po + -rm -f ./$(DEPDIR)/pcem-pzx.Po + -rm -f ./$(DEPDIR)/pcem-rom.Po + -rm -f ./$(DEPDIR)/pcem-rtc.Po + -rm -f ./$(DEPDIR)/pcem-rtc_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-scamp.Po + -rm -f ./$(DEPDIR)/pcem-scat.Po + -rm -f ./$(DEPDIR)/pcem-scsi.Po + -rm -f ./$(DEPDIR)/pcem-scsi_53c400.Po + -rm -f ./$(DEPDIR)/pcem-scsi_aha1540.Po + -rm -f ./$(DEPDIR)/pcem-scsi_cd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_hd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_ibm.Po + -rm -f ./$(DEPDIR)/pcem-scsi_zip.Po + -rm -f ./$(DEPDIR)/pcem-serial.Po + -rm -f ./$(DEPDIR)/pcem-sio.Po + -rm -f ./$(DEPDIR)/pcem-sis496.Po + -rm -f ./$(DEPDIR)/pcem-sl82c460.Po + -rm -f ./$(DEPDIR)/pcem-sound.Po + -rm -f ./$(DEPDIR)/pcem-sound_ad1848.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlib.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlibgold.Po + -rm -f ./$(DEPDIR)/pcem-sound_audiopci.Po + -rm -f ./$(DEPDIR)/pcem-sound_azt2316a.Po + -rm -f ./$(DEPDIR)/pcem-sound_cms.Po + -rm -f ./$(DEPDIR)/pcem-sound_dbopl.Po + -rm -f ./$(DEPDIR)/pcem-sound_emu8k.Po + -rm -f ./$(DEPDIR)/pcem-sound_gus.Po + -rm -f ./$(DEPDIR)/pcem-sound_mpu401_uart.Po + -rm -f ./$(DEPDIR)/pcem-sound_opl.Po + -rm -f ./$(DEPDIR)/pcem-sound_pas16.Po + -rm -f ./$(DEPDIR)/pcem-sound_ps1.Po + -rm -f ./$(DEPDIR)/pcem-sound_pssj.Po + -rm -f ./$(DEPDIR)/pcem-sound_resid.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb_dsp.Po + -rm -f ./$(DEPDIR)/pcem-sound_sn76489.Po + -rm -f ./$(DEPDIR)/pcem-sound_speaker.Po + -rm -f ./$(DEPDIR)/pcem-sound_ssi2001.Po + -rm -f ./$(DEPDIR)/pcem-sound_wss.Po + -rm -f ./$(DEPDIR)/pcem-sound_ym7128.Po + -rm -f ./$(DEPDIR)/pcem-soundopenal.Po + -rm -f ./$(DEPDIR)/pcem-sst39sf010.Po + -rm -f ./$(DEPDIR)/pcem-superxt.Po + -rm -f ./$(DEPDIR)/pcem-t1000.Po + -rm -f ./$(DEPDIR)/pcem-t3100e.Po + -rm -f ./$(DEPDIR)/pcem-tandy_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-tandy_rom.Po + -rm -f ./$(DEPDIR)/pcem-timer.Po + -rm -f ./$(DEPDIR)/pcem-um8669f.Po + -rm -f ./$(DEPDIR)/pcem-um8881f.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati18800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati28800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_mach64.Po + -rm -f ./$(DEPDIR)/pcem-vid_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_cl5429.Po + -rm -f ./$(DEPDIR)/pcem-vid_colorplus.Po + -rm -f ./$(DEPDIR)/pcem-vid_compaq_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_ddc.Po + -rm -f ./$(DEPDIR)/pcem-vid_ega.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000w32.Po + -rm -f ./$(DEPDIR)/pcem-vid_genius.Po + -rm -f ./$(DEPDIR)/pcem-vid_hercules.Po + -rm -f ./$(DEPDIR)/pcem-vid_ht216.Po + -rm -f ./$(DEPDIR)/pcem-vid_icd2061.Po + -rm -f ./$(DEPDIR)/pcem-vid_ics2595.Po + -rm -f ./$(DEPDIR)/pcem-vid_im1024.Po + -rm -f ./$(DEPDIR)/pcem-vid_incolor.Po + -rm -f ./$(DEPDIR)/pcem-vid_mda.Po + -rm -f ./$(DEPDIR)/pcem-vid_mga.Po + -rm -f ./$(DEPDIR)/pcem-vid_olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti037.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti067.Po + -rm -f ./$(DEPDIR)/pcem-vid_paradise.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1512.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1640.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc200.Po + -rm -f ./$(DEPDIR)/pcem-vid_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-vid_pgc.Po + -rm -f ./$(DEPDIR)/pcem-vid_ps1_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3_virge.Po + -rm -f ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_sigma.Po + -rm -f ./$(DEPDIR)/pcem-vid_stg_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga_render.Po + -rm -f ./$(DEPDIR)/pcem-vid_t1000.Po + -rm -f ./$(DEPDIR)/pcem-vid_t3100e.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandy.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandysl.Po + -rm -f ./$(DEPDIR)/pcem-vid_tgui9440.Po + -rm -f ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_tvga.Po + -rm -f ./$(DEPDIR)/pcem-vid_unk_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_vga.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_banshee.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_blitter.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_display.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_fb.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_fifo.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_reg.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_render.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_setup.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_texture.Po + -rm -f ./$(DEPDIR)/pcem-vid_wy700.Po + -rm -f ./$(DEPDIR)/pcem-video.Po + -rm -f ./$(DEPDIR)/pcem-vl82c480.Po + -rm -f ./$(DEPDIR)/pcem-vt82c586b.Po + -rm -f ./$(DEPDIR)/pcem-w83877tf.Po + -rm -f ./$(DEPDIR)/pcem-w83977tf.Po + -rm -f ./$(DEPDIR)/pcem-wd76c10.Po + -rm -f ./$(DEPDIR)/pcem-wx-app.Po + -rm -f ./$(DEPDIR)/pcem-wx-common.Po + -rm -f ./$(DEPDIR)/pcem-wx-config.Po + -rm -f ./$(DEPDIR)/pcem-wx-config_sel.Po + -rm -f ./$(DEPDIR)/pcem-wx-createdisc.Po + -rm -f ./$(DEPDIR)/pcem-wx-deviceconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-dialogbox.Po + -rm -f ./$(DEPDIR)/pcem-wx-glslp-parser.Po + -rm -f ./$(DEPDIR)/pcem-wx-hostconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-joystickconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-main.Po + -rm -f ./$(DEPDIR)/pcem-wx-resources.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-midi.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2.Po + -rm -f ./$(DEPDIR)/pcem-wx-shader_man.Po + -rm -f ./$(DEPDIR)/pcem-wx-shaderconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-thread.Po + -rm -f ./$(DEPDIR)/pcem-wx-utils.Po + -rm -f ./$(DEPDIR)/pcem-x86seg.Po + -rm -f ./$(DEPDIR)/pcem-x87.Po + -rm -f ./$(DEPDIR)/pcem-x87_timings.Po + -rm -f ./$(DEPDIR)/pcem-xi8088.Po + -rm -f ./$(DEPDIR)/pcem-xtide.Po + -rm -f dosbox/$(DEPDIR)/pcem-cdrom_image.Po + -rm -f dosbox/$(DEPDIR)/pcem-dbopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-nukedopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po + -rm -f minivhd/$(DEPDIR)/pcem-cwalk.Po + -rm -f minivhd/$(DEPDIR)/pcem-libxml2_encoding.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_convert.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_create.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_io.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_manage.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_util.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve-sse.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve.Po + -rm -f resid-fp/$(DEPDIR)/pcem-envelope.Po + -rm -f resid-fp/$(DEPDIR)/pcem-extfilt.Po + -rm -f resid-fp/$(DEPDIR)/pcem-filter.Po + -rm -f resid-fp/$(DEPDIR)/pcem-pot.Po + -rm -f resid-fp/$(DEPDIR)/pcem-sid.Po + -rm -f resid-fp/$(DEPDIR)/pcem-voice.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po + -rm -f slirp/$(DEPDIR)/pcem-bootp.Po + -rm -f slirp/$(DEPDIR)/pcem-cksum.Po + -rm -f slirp/$(DEPDIR)/pcem-debug.Po + -rm -f slirp/$(DEPDIR)/pcem-if.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_icmp.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_input.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_output.Po + -rm -f slirp/$(DEPDIR)/pcem-mbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-misc.Po + -rm -f slirp/$(DEPDIR)/pcem-queue.Po + -rm -f slirp/$(DEPDIR)/pcem-sbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-slirp.Po + -rm -f slirp/$(DEPDIR)/pcem-socket.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_input.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_output.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_subr.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_timer.Po + -rm -f slirp/$(DEPDIR)/pcem-tftp.Po + -rm -f slirp/$(DEPDIR)/pcem-udp.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -5950,7 +7169,362 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) dosbox/$(DEPDIR) resid-fp/$(DEPDIR) slirp/$(DEPDIR) + -rm -f ./$(DEPDIR)/pcem-386.Po + -rm -f ./$(DEPDIR)/pcem-386_common.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec.Po + -rm -f ./$(DEPDIR)/pcem-386_dynarec_ops.Po + -rm -f ./$(DEPDIR)/pcem-808x.Po + -rm -f ./$(DEPDIR)/pcem-82091aa.Po + -rm -f ./$(DEPDIR)/pcem-acc2036.Po + -rm -f ./$(DEPDIR)/pcem-acc2168.Po + -rm -f ./$(DEPDIR)/pcem-acc3221.Po + -rm -f ./$(DEPDIR)/pcem-acer386sx.Po + -rm -f ./$(DEPDIR)/pcem-ali1429.Po + -rm -f ./$(DEPDIR)/pcem-amstrad.Po + -rm -f ./$(DEPDIR)/pcem-cassette.Po + -rm -f ./$(DEPDIR)/pcem-cbm_io.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-image.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-dummy.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl-osx.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-ioctl.Po + -rm -f ./$(DEPDIR)/pcem-cdrom-null.Po + -rm -f ./$(DEPDIR)/pcem-cmd640.Po + -rm -f ./$(DEPDIR)/pcem-codegen.Po + -rm -f ./$(DEPDIR)/pcem-codegen_accumulate.Po + -rm -f ./$(DEPDIR)/pcem-codegen_allocator.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_imm.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_arm_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_ops_sse.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86-64_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_ops_fpu.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_ops_sse.Po + -rm -f ./$(DEPDIR)/pcem-codegen_backend_x86_uops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_block.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ir.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_3dnow.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_arith.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_branch.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_arith.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_constant.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_loadstore.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_fpu_misc.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_helpers.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_jump.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_logic.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_misc.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_arith.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_cmp.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_loadstore.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_logic.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_pack.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mmx_shift.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_mov.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_shift.Po + -rm -f ./$(DEPDIR)/pcem-codegen_ops_stack.Po + -rm -f ./$(DEPDIR)/pcem-codegen_reg.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_486.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_686.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_common.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_cyrixiii.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_k6.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_p6.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_pentium.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip.Po + -rm -f ./$(DEPDIR)/pcem-codegen_timing_winchip2.Po + -rm -f ./$(DEPDIR)/pcem-compaq.Po + -rm -f ./$(DEPDIR)/pcem-config.Po + -rm -f ./$(DEPDIR)/pcem-cpu.Po + -rm -f ./$(DEPDIR)/pcem-cpu_tables.Po + -rm -f ./$(DEPDIR)/pcem-cs8230.Po + -rm -f ./$(DEPDIR)/pcem-dells200.Po + -rm -f ./$(DEPDIR)/pcem-device.Po + -rm -f ./$(DEPDIR)/pcem-disc.Po + -rm -f ./$(DEPDIR)/pcem-disc_fdi.Po + -rm -f ./$(DEPDIR)/pcem-disc_img.Po + -rm -f ./$(DEPDIR)/pcem-disc_sector.Po + -rm -f ./$(DEPDIR)/pcem-dma.Po + -rm -f ./$(DEPDIR)/pcem-esdi_at.Po + -rm -f ./$(DEPDIR)/pcem-f82c710_upc.Po + -rm -f ./$(DEPDIR)/pcem-fdc.Po + -rm -f ./$(DEPDIR)/pcem-fdc37c665.Po + -rm -f ./$(DEPDIR)/pcem-fdc37c93x.Po + -rm -f ./$(DEPDIR)/pcem-fdd.Po + -rm -f ./$(DEPDIR)/pcem-fdi2raw.Po + -rm -f ./$(DEPDIR)/pcem-gameport.Po + -rm -f ./$(DEPDIR)/pcem-hdd.Po + -rm -f ./$(DEPDIR)/pcem-hdd_esdi.Po + -rm -f ./$(DEPDIR)/pcem-hdd_file.Po + -rm -f ./$(DEPDIR)/pcem-headland.Po + -rm -f ./$(DEPDIR)/pcem-i430fx.Po + -rm -f ./$(DEPDIR)/pcem-i430hx.Po + -rm -f ./$(DEPDIR)/pcem-i430lx.Po + -rm -f ./$(DEPDIR)/pcem-i430vx.Po + -rm -f ./$(DEPDIR)/pcem-i440bx.Po + -rm -f ./$(DEPDIR)/pcem-i440fx.Po + -rm -f ./$(DEPDIR)/pcem-ide.Po + -rm -f ./$(DEPDIR)/pcem-ide_atapi.Po + -rm -f ./$(DEPDIR)/pcem-ide_sff8038i.Po + -rm -f ./$(DEPDIR)/pcem-intel.Po + -rm -f ./$(DEPDIR)/pcem-intel_flash.Po + -rm -f ./$(DEPDIR)/pcem-io.Po + -rm -f ./$(DEPDIR)/pcem-jim.Po + -rm -f ./$(DEPDIR)/pcem-joystick_ch_flightstick_pro.Po + -rm -f ./$(DEPDIR)/pcem-joystick_standard.Po + -rm -f ./$(DEPDIR)/pcem-joystick_sw_pad.Po + -rm -f ./$(DEPDIR)/pcem-joystick_tm_fcs.Po + -rm -f ./$(DEPDIR)/pcem-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_amstrad.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_at.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_olim24.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-keyboard_xt.Po + -rm -f ./$(DEPDIR)/pcem-laserxt.Po + -rm -f ./$(DEPDIR)/pcem-lpt.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dac.Po + -rm -f ./$(DEPDIR)/pcem-lpt_dss.Po + -rm -f ./$(DEPDIR)/pcem-mca.Po + -rm -f ./$(DEPDIR)/pcem-mcr.Po + -rm -f ./$(DEPDIR)/pcem-mem.Po + -rm -f ./$(DEPDIR)/pcem-mem_bios.Po + -rm -f ./$(DEPDIR)/pcem-mfm_at.Po + -rm -f ./$(DEPDIR)/pcem-mfm_xebec.Po + -rm -f ./$(DEPDIR)/pcem-midi_alsa.Po + -rm -f ./$(DEPDIR)/pcem-model.Po + -rm -f ./$(DEPDIR)/pcem-mouse.Po + -rm -f ./$(DEPDIR)/pcem-mouse_msystems.Po + -rm -f ./$(DEPDIR)/pcem-mouse_ps2.Po + -rm -f ./$(DEPDIR)/pcem-mouse_serial.Po + -rm -f ./$(DEPDIR)/pcem-mvp3.Po + -rm -f ./$(DEPDIR)/pcem-ne2000.Po + -rm -f ./$(DEPDIR)/pcem-neat.Po + -rm -f ./$(DEPDIR)/pcem-nethandler.Po + -rm -f ./$(DEPDIR)/pcem-nmi.Po + -rm -f ./$(DEPDIR)/pcem-nvr.Po + -rm -f ./$(DEPDIR)/pcem-nvr_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-opti495.Po + -rm -f ./$(DEPDIR)/pcem-paths.Po + -rm -f ./$(DEPDIR)/pcem-pc.Po + -rm -f ./$(DEPDIR)/pcem-pc87306.Po + -rm -f ./$(DEPDIR)/pcem-pc87307.Po + -rm -f ./$(DEPDIR)/pcem-pci.Po + -rm -f ./$(DEPDIR)/pcem-pic.Po + -rm -f ./$(DEPDIR)/pcem-piix.Po + -rm -f ./$(DEPDIR)/pcem-piix_pm.Po + -rm -f ./$(DEPDIR)/pcem-pit.Po + -rm -f ./$(DEPDIR)/pcem-ppi.Po + -rm -f ./$(DEPDIR)/pcem-ps1.Po + -rm -f ./$(DEPDIR)/pcem-ps2.Po + -rm -f ./$(DEPDIR)/pcem-ps2_mca.Po + -rm -f ./$(DEPDIR)/pcem-ps2_nvr.Po + -rm -f ./$(DEPDIR)/pcem-pzx.Po + -rm -f ./$(DEPDIR)/pcem-rom.Po + -rm -f ./$(DEPDIR)/pcem-rtc.Po + -rm -f ./$(DEPDIR)/pcem-rtc_tc8521.Po + -rm -f ./$(DEPDIR)/pcem-scamp.Po + -rm -f ./$(DEPDIR)/pcem-scat.Po + -rm -f ./$(DEPDIR)/pcem-scsi.Po + -rm -f ./$(DEPDIR)/pcem-scsi_53c400.Po + -rm -f ./$(DEPDIR)/pcem-scsi_aha1540.Po + -rm -f ./$(DEPDIR)/pcem-scsi_cd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_hd.Po + -rm -f ./$(DEPDIR)/pcem-scsi_ibm.Po + -rm -f ./$(DEPDIR)/pcem-scsi_zip.Po + -rm -f ./$(DEPDIR)/pcem-serial.Po + -rm -f ./$(DEPDIR)/pcem-sio.Po + -rm -f ./$(DEPDIR)/pcem-sis496.Po + -rm -f ./$(DEPDIR)/pcem-sl82c460.Po + -rm -f ./$(DEPDIR)/pcem-sound.Po + -rm -f ./$(DEPDIR)/pcem-sound_ad1848.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlib.Po + -rm -f ./$(DEPDIR)/pcem-sound_adlibgold.Po + -rm -f ./$(DEPDIR)/pcem-sound_audiopci.Po + -rm -f ./$(DEPDIR)/pcem-sound_azt2316a.Po + -rm -f ./$(DEPDIR)/pcem-sound_cms.Po + -rm -f ./$(DEPDIR)/pcem-sound_dbopl.Po + -rm -f ./$(DEPDIR)/pcem-sound_emu8k.Po + -rm -f ./$(DEPDIR)/pcem-sound_gus.Po + -rm -f ./$(DEPDIR)/pcem-sound_mpu401_uart.Po + -rm -f ./$(DEPDIR)/pcem-sound_opl.Po + -rm -f ./$(DEPDIR)/pcem-sound_pas16.Po + -rm -f ./$(DEPDIR)/pcem-sound_ps1.Po + -rm -f ./$(DEPDIR)/pcem-sound_pssj.Po + -rm -f ./$(DEPDIR)/pcem-sound_resid.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb.Po + -rm -f ./$(DEPDIR)/pcem-sound_sb_dsp.Po + -rm -f ./$(DEPDIR)/pcem-sound_sn76489.Po + -rm -f ./$(DEPDIR)/pcem-sound_speaker.Po + -rm -f ./$(DEPDIR)/pcem-sound_ssi2001.Po + -rm -f ./$(DEPDIR)/pcem-sound_wss.Po + -rm -f ./$(DEPDIR)/pcem-sound_ym7128.Po + -rm -f ./$(DEPDIR)/pcem-soundopenal.Po + -rm -f ./$(DEPDIR)/pcem-sst39sf010.Po + -rm -f ./$(DEPDIR)/pcem-superxt.Po + -rm -f ./$(DEPDIR)/pcem-t1000.Po + -rm -f ./$(DEPDIR)/pcem-t3100e.Po + -rm -f ./$(DEPDIR)/pcem-tandy_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-tandy_rom.Po + -rm -f ./$(DEPDIR)/pcem-timer.Po + -rm -f ./$(DEPDIR)/pcem-um8669f.Po + -rm -f ./$(DEPDIR)/pcem-um8881f.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati18800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati28800.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_eeprom.Po + -rm -f ./$(DEPDIR)/pcem-vid_ati_mach64.Po + -rm -f ./$(DEPDIR)/pcem-vid_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_cl5429.Po + -rm -f ./$(DEPDIR)/pcem-vid_colorplus.Po + -rm -f ./$(DEPDIR)/pcem-vid_compaq_cga.Po + -rm -f ./$(DEPDIR)/pcem-vid_ddc.Po + -rm -f ./$(DEPDIR)/pcem-vid_ega.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000.Po + -rm -f ./$(DEPDIR)/pcem-vid_et4000w32.Po + -rm -f ./$(DEPDIR)/pcem-vid_genius.Po + -rm -f ./$(DEPDIR)/pcem-vid_hercules.Po + -rm -f ./$(DEPDIR)/pcem-vid_ht216.Po + -rm -f ./$(DEPDIR)/pcem-vid_icd2061.Po + -rm -f ./$(DEPDIR)/pcem-vid_ics2595.Po + -rm -f ./$(DEPDIR)/pcem-vid_im1024.Po + -rm -f ./$(DEPDIR)/pcem-vid_incolor.Po + -rm -f ./$(DEPDIR)/pcem-vid_mda.Po + -rm -f ./$(DEPDIR)/pcem-vid_mga.Po + -rm -f ./$(DEPDIR)/pcem-vid_olivetti_m24.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti037.Po + -rm -f ./$(DEPDIR)/pcem-vid_oti067.Po + -rm -f ./$(DEPDIR)/pcem-vid_paradise.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1512.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc1640.Po + -rm -f ./$(DEPDIR)/pcem-vid_pc200.Po + -rm -f ./$(DEPDIR)/pcem-vid_pcjr.Po + -rm -f ./$(DEPDIR)/pcem-vid_pgc.Po + -rm -f ./$(DEPDIR)/pcem-vid_ps1_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3.Po + -rm -f ./$(DEPDIR)/pcem-vid_s3_virge.Po + -rm -f ./$(DEPDIR)/pcem-vid_sdac_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_sigma.Po + -rm -f ./$(DEPDIR)/pcem-vid_stg_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga.Po + -rm -f ./$(DEPDIR)/pcem-vid_svga_render.Po + -rm -f ./$(DEPDIR)/pcem-vid_t1000.Po + -rm -f ./$(DEPDIR)/pcem-vid_t3100e.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandy.Po + -rm -f ./$(DEPDIR)/pcem-vid_tandysl.Po + -rm -f ./$(DEPDIR)/pcem-vid_tgui9440.Po + -rm -f ./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_tvga.Po + -rm -f ./$(DEPDIR)/pcem-vid_unk_ramdac.Po + -rm -f ./$(DEPDIR)/pcem-vid_vga.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_banshee.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_banshee_blitter.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_blitter.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_display.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_fb.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_fifo.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_reg.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_render.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_setup.Po + -rm -f ./$(DEPDIR)/pcem-vid_voodoo_texture.Po + -rm -f ./$(DEPDIR)/pcem-vid_wy700.Po + -rm -f ./$(DEPDIR)/pcem-video.Po + -rm -f ./$(DEPDIR)/pcem-vl82c480.Po + -rm -f ./$(DEPDIR)/pcem-vt82c586b.Po + -rm -f ./$(DEPDIR)/pcem-w83877tf.Po + -rm -f ./$(DEPDIR)/pcem-w83977tf.Po + -rm -f ./$(DEPDIR)/pcem-wd76c10.Po + -rm -f ./$(DEPDIR)/pcem-wx-app.Po + -rm -f ./$(DEPDIR)/pcem-wx-common.Po + -rm -f ./$(DEPDIR)/pcem-wx-config.Po + -rm -f ./$(DEPDIR)/pcem-wx-config_sel.Po + -rm -f ./$(DEPDIR)/pcem-wx-createdisc.Po + -rm -f ./$(DEPDIR)/pcem-wx-deviceconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-dialogbox.Po + -rm -f ./$(DEPDIR)/pcem-wx-glslp-parser.Po + -rm -f ./$(DEPDIR)/pcem-wx-hostconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-joystickconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-main.Po + -rm -f ./$(DEPDIR)/pcem-wx-resources.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display-win.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-display.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-joystick.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-keyboard.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-midi.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-mouse.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-gl3.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video-renderer.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2-video.Po + -rm -f ./$(DEPDIR)/pcem-wx-sdl2.Po + -rm -f ./$(DEPDIR)/pcem-wx-shader_man.Po + -rm -f ./$(DEPDIR)/pcem-wx-shaderconfig.Po + -rm -f ./$(DEPDIR)/pcem-wx-status.Po + -rm -f ./$(DEPDIR)/pcem-wx-thread.Po + -rm -f ./$(DEPDIR)/pcem-wx-utils.Po + -rm -f ./$(DEPDIR)/pcem-x86seg.Po + -rm -f ./$(DEPDIR)/pcem-x87.Po + -rm -f ./$(DEPDIR)/pcem-x87_timings.Po + -rm -f ./$(DEPDIR)/pcem-xi8088.Po + -rm -f ./$(DEPDIR)/pcem-xtide.Po + -rm -f dosbox/$(DEPDIR)/pcem-cdrom_image.Po + -rm -f dosbox/$(DEPDIR)/pcem-dbopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-nukedopl.Po + -rm -f dosbox/$(DEPDIR)/pcem-vid_cga_comp.Po + -rm -f minivhd/$(DEPDIR)/pcem-cwalk.Po + -rm -f minivhd/$(DEPDIR)/pcem-libxml2_encoding.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_convert.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_create.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_io.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_manage.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_struct_rw.Po + -rm -f minivhd/$(DEPDIR)/pcem-minivhd_util.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve-sse.Po + -rm -f resid-fp/$(DEPDIR)/pcem-convolve.Po + -rm -f resid-fp/$(DEPDIR)/pcem-envelope.Po + -rm -f resid-fp/$(DEPDIR)/pcem-extfilt.Po + -rm -f resid-fp/$(DEPDIR)/pcem-filter.Po + -rm -f resid-fp/$(DEPDIR)/pcem-pot.Po + -rm -f resid-fp/$(DEPDIR)/pcem-sid.Po + -rm -f resid-fp/$(DEPDIR)/pcem-voice.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave6581__ST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PST.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_PS_.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580_P_T.Po + -rm -f resid-fp/$(DEPDIR)/pcem-wave8580__ST.Po + -rm -f slirp/$(DEPDIR)/pcem-bootp.Po + -rm -f slirp/$(DEPDIR)/pcem-cksum.Po + -rm -f slirp/$(DEPDIR)/pcem-debug.Po + -rm -f slirp/$(DEPDIR)/pcem-if.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_icmp.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_input.Po + -rm -f slirp/$(DEPDIR)/pcem-ip_output.Po + -rm -f slirp/$(DEPDIR)/pcem-mbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-misc.Po + -rm -f slirp/$(DEPDIR)/pcem-queue.Po + -rm -f slirp/$(DEPDIR)/pcem-sbuf.Po + -rm -f slirp/$(DEPDIR)/pcem-slirp.Po + -rm -f slirp/$(DEPDIR)/pcem-socket.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_input.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_output.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_subr.Po + -rm -f slirp/$(DEPDIR)/pcem-tcp_timer.Po + -rm -f slirp/$(DEPDIR)/pcem-tftp.Po + -rm -f slirp/$(DEPDIR)/pcem-udp.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -5970,7 +7544,7 @@ uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir dvi dvi-am html html-am info info-am install \ diff --git a/src/wx-main.cc b/src/wx-main.cc index 53a9371..2f17e28 100644 --- a/src/wx-main.cc +++ b/src/wx-main.cc @@ -1,5 +1,5 @@ #include "wx-app.h" -#include +#include extern "C" { diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index ba2bdb6..9d56517 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -1,5 +1,5 @@ #define _WIN32_WINNT 0x0501 -#include +#include #include "video.h" #include "wx-sdl2-video.h" #include "wx-utils.h" diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index ac8c23e..1bc458a 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -1,4 +1,4 @@ -#include +#include #include "video.h" #include "wx-sdl2-video.h" #include "wx-utils.h" diff --git a/src/wx-sdl2-joystick.c b/src/wx-sdl2-joystick.c index 8aa487b..f6bef48 100644 --- a/src/wx-sdl2-joystick.c +++ b/src/wx-sdl2-joystick.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "ibm.h" #include "device.h" #include "gameport.h" diff --git a/src/wx-sdl2-mouse.c b/src/wx-sdl2-mouse.c index a9326cf..4fbc3c3 100644 --- a/src/wx-sdl2-mouse.c +++ b/src/wx-sdl2-mouse.c @@ -1,4 +1,4 @@ -#include +#include #include #include "plat-mouse.h" diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 71c01ac..2feea96 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -1,4 +1,4 @@ -#include +#include #include "video.h" #include "wx-sdl2.h" #include "wx-sdl2-video.h" diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index 3ce76e1..248432d 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -1,8 +1,8 @@ -#include +#include #define BITMAP WINDOWS_BITMAP -#include +#include #if SDL_VERSION_ATLEAST(2, 0, 4) -#include +#include #endif #undef BITMAP #include "wx-sdl2-glw.h" diff --git a/src/wx-sdl2-video-renderer.c b/src/wx-sdl2-video-renderer.c index c06d64c..acbfbf8 100644 --- a/src/wx-sdl2-video-renderer.c +++ b/src/wx-sdl2-video-renderer.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/wx-sdl2-video.c b/src/wx-sdl2-video.c index f6551b0..f229202 100644 --- a/src/wx-sdl2-video.c +++ b/src/wx-sdl2-video.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 9411d5b..1c5f96d 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -1,6 +1,6 @@ #include "wx-sdl2.h" -#include +#include #include #ifdef __WINDOWS__ diff --git a/src/wx-thread.c b/src/wx-thread.c index b5958ad..fec52fb 100644 --- a/src/wx-thread.c +++ b/src/wx-thread.c @@ -1,6 +1,10 @@ #include #include #include +#ifdef __APPLE__ +#include +#endif +#include #include "thread.h" #if defined WIN32 || defined _WIN32 || defined _WIN32 #include From e2f01a7e8a739955192c35e04f30d1ade740d5d6 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 16:13:08 -0600 Subject: [PATCH 1016/1050] How did that sneak in? --- src/wx-thread.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wx-thread.c b/src/wx-thread.c index fec52fb..c3797f6 100644 --- a/src/wx-thread.c +++ b/src/wx-thread.c @@ -4,7 +4,6 @@ #ifdef __APPLE__ #include #endif -#include #include "thread.h" #if defined WIN32 || defined _WIN32 || defined _WIN32 #include From 04e4a14edcc5032949b19c338157ea956a52830b Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 16:19:31 -0600 Subject: [PATCH 1017/1050] Define HAVE_UNISTD_H on Darwin/macOS: Fixes a compiler failure due to missing function prototype. --- configure | 1 + configure.ac | 1 + src/slirp/slirp.h | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/configure b/configure index dfcded4..9075b97 100755 --- a/configure +++ b/configure @@ -6310,6 +6310,7 @@ case "$host" in LIBS="$LIBS -framework OpenGL" LIBS="$LIBS -framework OpenAL" build_macosx="yes" + CFLAGS="$CFLAGS -DHAVE_UNISTD_H" ;; *-*-cygwin* | *-*-mingw32*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lopengl32" >&5 diff --git a/configure.ac b/configure.ac index 20a6d09..3a89aff 100644 --- a/configure.ac +++ b/configure.ac @@ -140,6 +140,7 @@ case "$host" in LIBS="$LIBS -framework OpenGL" LIBS="$LIBS -framework OpenAL" build_macosx="yes" + CFLAGS="$CFLAGS -DHAVE_UNISTD_H" ;; *-*-cygwin* | *-*-mingw32*) AC_CHECK_LIB([opengl32], [main], [], \ diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index 416b402..6e15943 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -80,6 +80,10 @@ typedef char *SLIRPcaddr_t; # include #endif +#ifdef HAVE_UNISTD_H +# include +#endif + #ifndef _MSC_VER #include #else From ea0867860fb769d90464528d8c72d72642f55af1 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Wed, 19 May 2021 16:37:42 -0600 Subject: [PATCH 1018/1050] Configure: pick up flags from the command line Allow configure to pick up CFLAGS and CXXFLAGS from the command line. Note: configure will need to be regenerated. --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 407b057..6a308d2 100644 --- a/configure.ac +++ b/configure.ac @@ -27,12 +27,12 @@ AC_MSG_CHECKING([whether to enable debugging]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [build debug executable])) if test "$enable_debug" = "yes"; then - CFLAGS="-Wall -O0 -g -D_DEBUG -fcommon" - CXXFLAGS="-Wall -O0 -g -D_DEBUG -fcommon" + CFLAGS="$CFLAGS -Wall -O0 -g -D_DEBUG -fcommon" + CXXFLAGS="$CXXFLAGS -Wall -O0 -g -D_DEBUG -fcommon" AC_MSG_RESULT([yes]) else - CFLAGS="-O3 -fcommon" - CXXFLAGS="-O3 -fcommon" + CFLAGS="$CFLAGS -O3 -fcommon" + CXXFLAGS="$CXXFLAGS -O3 -fcommon" AC_MSG_RESULT([no]) fi From 0d46e719eba15d522775773ce259e39e6587ccb1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 20 May 2021 22:03:28 +0100 Subject: [PATCH 1019/1050] FDC commands 8d and cd appear to be synonyms for "format track" (officially documented as 0d and 4d). Fixes formatting on AMI BIOSes. --- src/fdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index e818c93..eb70169 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -482,7 +482,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.stat=0x90; fdc.pos=0; break; - case 0x0d: case 0x4d: /*Format track*/ + case 0x0d: case 0x4d: case 0x8d: case 0xcd: /*Format track*/ fdc.pnum=0; fdc.ptot=5; fdc.stat=0x90; @@ -640,7 +640,7 @@ bad_command: timer_set_delay_u64(&fdc.timer, time); break; - case 0x0d: case 0x4d: /*Format*/ + case 0x0d: case 0x4d: case 0x8d: case 0xcd: /*Format*/ fdc_rate(fdc.drive); fdc.head = (fdc.params[0] & 4) ? 1 : 0; fdc.format_state = 1; From 3dd4fda614ce0916f8a8b7330abb64c6b2808973 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Fri, 21 May 2021 01:11:56 -0600 Subject: [PATCH 1020/1050] Minor style changes. --- src/386_dynarec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 5b7e8f4..ec56e57 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1,7 +1,7 @@ #include #include #include -#if defined __APPLE__ && defined __aarch64__ +#if defined(__APPLE__) && defined(__aarch64__) #include #endif #include "ibm.h" @@ -413,7 +413,7 @@ static inline void exec_recompiler(void) cpu_new_blocks++; -#if defined __APPLE__ && defined __aarch64__ +#if defined(__APPLE__) && defined(__aarch64__) pthread_jit_write_protect_np(0); #endif codegen_block_start_recompile(block); @@ -487,7 +487,7 @@ static inline void exec_recompiler(void) codegen_reset(); codegen_in_recompile = 0; -#if defined __APPLE__ && defined __aarch64__ +#if defined(__APPLE__) && defined(__aarch64__) pthread_jit_write_protect_np(1); #endif } From c82cd208c1717cb2e07d3011f52fc8b0aca58504 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 21 May 2021 22:15:21 +0100 Subject: [PATCH 1021/1050] CGA-class cards mirror CRTC between ports 3d0 and 3d7. Fixes scrolling in Prohibition. --- src/vid_cga.c | 4 ++-- src/vid_pc1512.c | 4 ++-- src/vid_tandy.c | 4 ++-- src/vid_tandysl.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vid_cga.c b/src/vid_cga.c index 7a21b2f..a74f497 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -28,10 +28,10 @@ void cga_out(uint16_t addr, uint8_t val, void *p) // pclog("CGA_OUT %04X %02X\n", addr, val); switch (addr) { - case 0x3D4: + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: cga->crtcreg = val & 31; return; - case 0x3D5: + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: old = cga->crtc[cga->crtcreg]; cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; if (old != val) diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 3c962d0..35ffa20 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -58,10 +58,10 @@ static void pc1512_out(uint16_t addr, uint8_t val, void *p) // pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr) { - case 0x3d4: + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: pc1512->crtcreg = val & 31; return; - case 0x3d5: + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: old = pc1512->crtc[pc1512->crtcreg]; pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg]; if (old != val) diff --git a/src/vid_tandy.c b/src/vid_tandy.c index d2cd49a..1b07f27 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -60,10 +60,10 @@ void tandy_out(uint16_t addr, uint8_t val, void *p) // pclog("Tandy OUT %04X %02X\n",addr,val); switch (addr) { - case 0x3d4: + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: tandy->crtcreg = val & 0x1f; return; - case 0x3d5: + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: old = tandy->crtc[tandy->crtcreg]; tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; if (old != val) diff --git a/src/vid_tandysl.c b/src/vid_tandysl.c index 2a521b0..1119f14 100644 --- a/src/vid_tandysl.c +++ b/src/vid_tandysl.c @@ -60,10 +60,10 @@ static void tandysl_out(uint16_t addr, uint8_t val, void *p) // pclog("TandySL OUT %04X %02X\n",addr,val); switch (addr) { - case 0x3d4: + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: tandy->crtcreg = val & 0x1f; return; - case 0x3d5: + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: // pclog("Write CRTC R%02x %02x ",tandy->crtcreg, val); old = tandy->crtc[tandy->crtcreg]; tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; From 366529ca35accd6a89d12605616575b2162d11d0 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Sat, 22 May 2021 11:35:59 -0600 Subject: [PATCH 1022/1050] macOS: Fix OpenGL 3 support. --- src/wx-sdl2-video-gl3.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index 248432d..14907cb 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -769,6 +769,12 @@ int gl3_init(SDL_Window* window, sdl_render_driver requested_render_driver, SDL_ strcpy(current_render_driver_name, requested_render_driver.name); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +#ifdef __APPLE__ + // without an explicit request for the core profile 3.0 macOS falls back to default ancient 2.1 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); +#endif context = SDL_GL_CreateContext(window); @@ -1637,12 +1643,21 @@ int gl3_renderer_available(struct sdl_render_driver* driver) if (available < 0) { available = 0; + + // GL SetAttribute should be done *before* window creation for the attributes to apply on + // context creation (seems to depend on OpenGL impl. but it souldn't hurt other platforms + // to do it here (earlier than before) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + +#ifdef __APPLE__ + // without an explicit request for the core profile 3.0 macOS falls back to default ancient 2.1 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); +#endif + SDL_Window* window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); if (window) { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GLContext context = SDL_GL_CreateContext(window); if (context) { From 4ebf9ec4278aefd9f98ddf42b4e5dd8050c9ed84 Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Sat, 22 May 2021 11:43:49 -0600 Subject: [PATCH 1023/1050] macOS: Have the support directory be in Application support. --- src/wx-sdl2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 1c5f96d..084a527 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -50,6 +50,8 @@ #include #include #undef pause +#include +#include #endif extern void creatediscimage_open(void *hwnd); @@ -241,6 +243,20 @@ void get_pcem_path(char *s, int size) #ifdef __linux wx_get_home_directory(s); strcat(s, ".pcem/"); +#elif defined(__APPLE__) + /*TODO: Use CoreFoundation functions to get proper directory, in case + the Application Support directory is different (I.E., with signing)*/ + wx_get_home_directory(s); + strcat(s, "Library/Application Support/PCem/"); + + struct stat st = {0}; + + // create ~/Library/Application Support/PCem/ + // if it doesn't exist + if (stat(s, &st) == -1) + { + mkdir(s, 0700); + } #else char* path = SDL_GetBasePath(); strcpy(s, path); From 14d199b0041ae294bcc706ac39b1542be5e4e13f Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Mon, 24 May 2021 16:20:36 -0600 Subject: [PATCH 1024/1050] Partially revert 1eb1cc5e5b4c1fc7266c90347325ebbbadd34b50: it broke the Windows build. Go back to using SDL2 in front of SDL2 header includes. --- src/wx-main.cc | 2 +- src/wx-sdl2-display-win.c | 2 +- src/wx-sdl2-display.c | 2 +- src/wx-sdl2-joystick.c | 2 +- src/wx-sdl2-mouse.c | 2 +- src/wx-sdl2-status.c | 2 +- src/wx-sdl2-video-gl3.c | 6 +++--- src/wx-sdl2-video-renderer.c | 2 +- src/wx-sdl2-video.c | 2 +- src/wx-sdl2.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/wx-main.cc b/src/wx-main.cc index 2f17e28..53a9371 100644 --- a/src/wx-main.cc +++ b/src/wx-main.cc @@ -1,5 +1,5 @@ #include "wx-app.h" -#include +#include extern "C" { diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index 9d56517..ba2bdb6 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -1,5 +1,5 @@ #define _WIN32_WINNT 0x0501 -#include +#include #include "video.h" #include "wx-sdl2-video.h" #include "wx-utils.h" diff --git a/src/wx-sdl2-display.c b/src/wx-sdl2-display.c index 1bc458a..ac8c23e 100644 --- a/src/wx-sdl2-display.c +++ b/src/wx-sdl2-display.c @@ -1,4 +1,4 @@ -#include +#include #include "video.h" #include "wx-sdl2-video.h" #include "wx-utils.h" diff --git a/src/wx-sdl2-joystick.c b/src/wx-sdl2-joystick.c index f6bef48..8aa487b 100644 --- a/src/wx-sdl2-joystick.c +++ b/src/wx-sdl2-joystick.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "ibm.h" #include "device.h" #include "gameport.h" diff --git a/src/wx-sdl2-mouse.c b/src/wx-sdl2-mouse.c index 4fbc3c3..a9326cf 100644 --- a/src/wx-sdl2-mouse.c +++ b/src/wx-sdl2-mouse.c @@ -1,4 +1,4 @@ -#include +#include #include #include "plat-mouse.h" diff --git a/src/wx-sdl2-status.c b/src/wx-sdl2-status.c index 2feea96..71c01ac 100644 --- a/src/wx-sdl2-status.c +++ b/src/wx-sdl2-status.c @@ -1,4 +1,4 @@ -#include +#include #include "video.h" #include "wx-sdl2.h" #include "wx-sdl2-video.h" diff --git a/src/wx-sdl2-video-gl3.c b/src/wx-sdl2-video-gl3.c index 14907cb..3e4330c 100644 --- a/src/wx-sdl2-video-gl3.c +++ b/src/wx-sdl2-video-gl3.c @@ -1,8 +1,8 @@ -#include +#include #define BITMAP WINDOWS_BITMAP -#include +#include #if SDL_VERSION_ATLEAST(2, 0, 4) -#include +#include #endif #undef BITMAP #include "wx-sdl2-glw.h" diff --git a/src/wx-sdl2-video-renderer.c b/src/wx-sdl2-video-renderer.c index acbfbf8..c06d64c 100644 --- a/src/wx-sdl2-video-renderer.c +++ b/src/wx-sdl2-video-renderer.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/wx-sdl2-video.c b/src/wx-sdl2-video.c index f229202..f6551b0 100644 --- a/src/wx-sdl2-video.c +++ b/src/wx-sdl2-video.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 084a527..172a50e 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -1,6 +1,6 @@ #include "wx-sdl2.h" -#include +#include #include #ifdef __WINDOWS__ From 6c063e3fcc5275e2e7e7bda0ce7f48814b492b38 Mon Sep 17 00:00:00 2001 From: JosepMaJAZ Date: Wed, 26 May 2021 03:22:19 +0200 Subject: [PATCH 1025/1050] First attempt at multi-os build --- .github/workflows/c-cpp.yml | 201 ++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 0000000..aac413b --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,201 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu 64bit (gcc) + os: ubuntu-latest + args: --enable-networking --enable-release-build + artifacts_name: PCem-Ubuntu-${{ github.head_ref }}-${{ github.run_number }} + artifacts_path: PCem.tar + installdeps: >- + libsdl2-dev + libopenal-dev + libwxgtk3.0-gtk3-dev + libncap-dev + - name: Windows 32bits (MSYS2) + os: windows-latest + compiler: MINGW32 + args: --enable-networking --enable-release-build + artifacts_name: PCem-Windows-MINGW32-${{ github.head_ref }}-${{ github.run_number }} + artifacts_path: PCem.zip + installdeps: >- + base-devel + zip + unzip + mingw-w64-i686-ntldd-git + mingw-w64-i686-toolchain + mingw-w64-i686-SDL2 + mingw-w64-i686-openal + mingw-w64-i686-wxWidgets + - name: Windows 64bits (MSYS2) + os: windows-latest + compiler: MINGW64 + args: --enable-networking --enable-release-build + artifacts_name: PCem-Windows-MINGW64-${{ github.head_ref }}-${{ github.run_number }} + artifacts_path: PCem.zip + installdeps: >- + base-devel + zip + unzip + mingw-w64-x86_64-ntldd-git + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-SDL2 + mingw-w64-x86_64-openal + mingw-w64-x86_64-wxWidgets + + runs-on: ${{ matrix.os }} + name: ${{ matrix.name }} + + steps: + - uses: actions/checkout@v2 + with: + path: temp + fetch-depth: 0 + + - name: Setup MSYS2 (Windows) + if: runner.os == 'Windows' + # You may pin to the exact commit or the version. + # uses: msys2/setup-msys2@a43b8403533fffe0c157dd8498f021ddec66bff7 + uses: msys2/setup-msys2@v2 + with: + # Variant of the environment to set by default: MSYS, MINGW32, MINGW64, UCRT64 or CLANG64 + msystem: ${{ matrix.compiler }} + # Retrieve and extract base installation from upstream GitHub Releases + release: false # optional, default is true + # Update MSYS2 installation through pacman + update: false + # Install packages after installation through pacman + install: ${{ matrix.installdeps }} + - name: npcap download (Windows) + if: runner.os == 'Windows' + shell: msys2 {0} + run: | + wget https://nmap.org/npcap/dist/npcap-sdk-1.05.zip + unzip -d npcap-sdk-1.05/ npcap-sdk-1.05.zip + cd npcap-sdk-1.05 + cp -r Include/* /mingw32/include/ + cp -r Include/* /mingw64/include/ + cp -r Lib/* /mingw32/lib/ + cp -r Lib/* /mingw64/lib/ + - name: Setup ubuntu dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install ${{ matrix.installdeps }} + + # Copy all the sources to the dist folder, before we start generating intermediate files. + - name: prepare-package (Windows32) + if: runner.os == 'Windows' && matrix.compiler == 'MINGW32' + shell: msys2 {0} + run: | + mkdir dist + cp -R ./temp/* dist + rm -Rf ./dist/.git + cp /mingw32/bin/libdeflate.dll dist + cp /mingw32/bin/libexpat-1.dll dist + cp /mingw32/bin/libgcc_s_dw2-1.dll dist + cp /mingw32/bin/libjpeg-8.dll dist + cp /mingw32/bin/liblzma-5.dll dist + cp /mingw32/bin/libopenal-1.dll dist + cp /mingw32/bin/libpng16-16.dll dist + cp /mingw32/bin/libstdc++-6.dll dist + cp /mingw32/bin/libtiff-5.dll dist + cp /mingw32/bin/libwebp-7.dll dist + cp /mingw32/bin/libwinpthread-1.dll dist + cp /mingw32/bin/libzstd.dll dist + cp /mingw32/bin/SDL2.dll dist + cp /mingw32/bin/wxbase30u_gcc_custom.dll dist + cp /mingw32/bin/wxbase30u_xml_gcc_custom.dll dist + cp /mingw32/bin/wxmsw30u_adv_gcc_custom.dll dist + cp /mingw32/bin/wxmsw30u_core_gcc_custom.dll dist + cp /mingw32/bin/wxmsw30u_html_gcc_custom.dll dist + cp /mingw32/bin/wxmsw30u_xrc_gcc_custom.dll dist + cp /mingw32/bin/zlib1.dll dist + - name: prepare-package (Windows64) + if: runner.os == 'Windows' && matrix.compiler == 'MINGW64' + shell: msys2 {0} + run: | + mkdir dist + cp -R ./temp/* dist + rm -Rf ./dist/.git + cp /mingw64/bin/libdeflate.dll dist + cp /mingw64/bin/libexpat-1.dll dist + cp /mingw64/bin/libgcc_s_seh-1.dll dist + cp /mingw64/bin/libjpeg-8.dll dist + cp /mingw64/bin/liblzma-5.dll dist + cp /mingw64/bin/libopenal-1.dll dist + cp /mingw64/bin/libpng16-16.dll dist + cp /mingw64/bin/libstdc++-6.dll dist + cp /mingw64/bin/libtiff-5.dll dist + cp /mingw64/bin/libwebp-7.dll dist + cp /mingw64/bin/libwinpthread-1.dll dist + cp /mingw64/bin/libzstd.dll dist + cp /mingw64/bin/SDL2.dll dist + cp /mingw64/bin/wxbase30u_gcc_custom.dll dist + cp /mingw64/bin/wxbase30u_xml_gcc_custom.dll dist + cp /mingw64/bin/wxmsw30u_adv_gcc_custom.dll dist + cp /mingw64/bin/wxmsw30u_core_gcc_custom.dll dist + cp /mingw64/bin/wxmsw30u_html_gcc_custom.dll dist + cp /mingw64/bin/wxmsw30u_xrc_gcc_custom.dll dist + cp /mingw64/bin/zlib1.dll dist + - name: configure (Windows) + if: runner.os == 'Windows' + shell: msys2 {0} + run: | + cd temp + autoreconf -i + ./configure ${{ matrix.args }} + - name: make (Windows) + if: runner.os == 'Windows' + shell: msys2 {0} + run: | + cd temp + make -j + - name: package (Windows) + if: runner.os == 'Windows' + shell: msys2 {0} + run: | + cp ./temp/src/pcem.exe dist + cd dist + zip ${{ matrix.artifacts_path }} * + + - name: prepare-package (Linux) + if: runner.os == 'Linux' + run: | + mkdir dist + cp -R ./temp/* dist + rm -Rf ./dist/.git + - name: configure (Linux) + if: runner.os == 'Linux' + run: | + cd temp + autoreconf -i + ./configure ${{ matrix.args }} + - name: make (Linux) + if: runner.os == 'Linux' + run: | + cd temp + make -j + - name: package (Linux) + if: runner.os == 'Linux' + run: | + cp ./temp/src/pcem dist + cd dist + tar -czf ${{ matrix.artifacts_path }} * + + - name: "Upload GitHub Actions artifacts" + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.artifacts_name }} + path: ./dist/${{ matrix.artifacts_path }} + From 3ea00897c8d5be298d65aac9d4076ac7c03c97ff Mon Sep 17 00:00:00 2001 From: JosepMaJAZ Date: Wed, 26 May 2021 03:39:17 +0200 Subject: [PATCH 1026/1050] Compression retouches --- .github/workflows/c-cpp.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index aac413b..317fb08 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -16,7 +16,7 @@ jobs: os: ubuntu-latest args: --enable-networking --enable-release-build artifacts_name: PCem-Ubuntu-${{ github.head_ref }}-${{ github.run_number }} - artifacts_path: PCem.tar + artifacts_path: PCem.tar.bz2 installdeps: >- libsdl2-dev libopenal-dev @@ -167,7 +167,7 @@ jobs: run: | cp ./temp/src/pcem.exe dist cd dist - zip ${{ matrix.artifacts_path }} * + zip -9 ${{ matrix.artifacts_path }} * - name: prepare-package (Linux) if: runner.os == 'Linux' @@ -191,7 +191,7 @@ jobs: run: | cp ./temp/src/pcem dist cd dist - tar -czf ${{ matrix.artifacts_path }} * + tar -cjf ${{ matrix.artifacts_path }} * - name: "Upload GitHub Actions artifacts" uses: actions/upload-artifact@v2 From d2f399ac5f14d79cdaf7b6f0eb1d7c42556f53a9 Mon Sep 17 00:00:00 2001 From: JosepMaJAZ Date: Wed, 26 May 2021 04:35:05 +0200 Subject: [PATCH 1027/1050] fixed incorrect 64bits npcap lib. fixed missing source subdirs content --- .github/workflows/c-cpp.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 317fb08..fef134e 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -85,8 +85,8 @@ jobs: cd npcap-sdk-1.05 cp -r Include/* /mingw32/include/ cp -r Include/* /mingw64/include/ - cp -r Lib/* /mingw32/lib/ - cp -r Lib/* /mingw64/lib/ + cp -r Lib/*.lib /mingw32/lib/ + cp -r Lib/x64/*.lib /mingw64/lib/ - name: Setup ubuntu dependencies if: runner.os == 'Linux' run: | @@ -167,7 +167,7 @@ jobs: run: | cp ./temp/src/pcem.exe dist cd dist - zip -9 ${{ matrix.artifacts_path }} * + zip -r -9 ${{ matrix.artifacts_path }} * - name: prepare-package (Linux) if: runner.os == 'Linux' From f9cdcfa6b64e3ac4cc968813f4dd39b92f68cdc6 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 28 May 2021 21:33:22 +0100 Subject: [PATCH 1028/1050] Add preprocessor variable to override version number on title bar. Modify github workflow to set version number to current git SHA, and append to artifact name. --- .github/workflows/c-cpp.yml | 12 ++++++------ src/ibm.h | 9 +++++++++ src/pc.c | 2 +- src/wx-sdl2-display-win.c | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index fef134e..80c06f5 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -14,9 +14,9 @@ jobs: include: - name: Ubuntu 64bit (gcc) os: ubuntu-latest - args: --enable-networking --enable-release-build + args: --enable-networking --enable-release-build CFLAGS="-DPCEM_BUILD_VERSION=${GITHUB_SHA::8}" artifacts_name: PCem-Ubuntu-${{ github.head_ref }}-${{ github.run_number }} - artifacts_path: PCem.tar.bz2 + artifacts_path: PCem-${{ github.sha }}.tar.bz2 installdeps: >- libsdl2-dev libopenal-dev @@ -25,9 +25,9 @@ jobs: - name: Windows 32bits (MSYS2) os: windows-latest compiler: MINGW32 - args: --enable-networking --enable-release-build + args: --enable-networking --enable-release-build CFLAGS="-DPCEM_BUILD_VERSION=${GITHUB_SHA::8}" artifacts_name: PCem-Windows-MINGW32-${{ github.head_ref }}-${{ github.run_number }} - artifacts_path: PCem.zip + artifacts_path: PCem-${{ github.sha }}.zip installdeps: >- base-devel zip @@ -40,9 +40,9 @@ jobs: - name: Windows 64bits (MSYS2) os: windows-latest compiler: MINGW64 - args: --enable-networking --enable-release-build + args: --enable-networking --enable-release-build CFLAGS="-DPCEM_BUILD_VERSION=${GITHUB_SHA::8}" artifacts_name: PCem-Windows-MINGW64-${{ github.head_ref }}-${{ github.run_number }} - artifacts_path: PCem.zip + artifacts_path: PCem-${{ github.sha }}.zip installdeps: >- base-devel zip diff --git a/src/ibm.h b/src/ibm.h index 75d476b..c1b6581 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -4,6 +4,15 @@ #include "timer.h" + +#ifdef PCEM_BUILD_VERSION +#define STRINGISE2(string) #string +#define STRINGISE(string) STRINGISE2(string) +#define PCEM_VERSION_STRING "build " STRINGISE(PCEM_BUILD_VERSION) +#else +#define PCEM_VERSION_STRING "v17" +#endif + #ifdef ABS #undef ABS #endif diff --git a/src/pc.c b/src/pc.c index 7b1b4c0..8e59278 100644 --- a/src/pc.c +++ b/src/pc.c @@ -605,7 +605,7 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "PCem v17 - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + sprintf(s, "PCem " PCEM_VERSION_STRING " - %i%% - %s - %s - %s", 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 CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); #ifdef __APPLE__ // Needed due to modifying the UI on the non-main thread is a big no-no. dispatch_async_f(dispatch_get_main_queue(), strdup(s), _set_window_title); diff --git a/src/wx-sdl2-display-win.c b/src/wx-sdl2-display-win.c index ba2bdb6..461ba16 100644 --- a/src/wx-sdl2-display-win.c +++ b/src/wx-sdl2-display-win.c @@ -595,7 +595,7 @@ int window_create() hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ - "PCem v17", /* Title Text */ + "PCem " PCEM_VERSION_STRING, /* Title Text */ WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ From 092be3e9d440022f2ce331049c746cbad47d1731 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 May 2021 09:08:34 +0100 Subject: [PATCH 1029/1050] Rework (S)VGA memory addressing. Support correct chain-4 mapping, as well as MA13/14 remapping for non-CGA modes. Fixes corruption on Windows 3.x when using Paradise drivers, also fixes corruption in Titan. --- src/vid_cl5429.c | 17 +- src/vid_et4000.c | 6 + src/vid_et4000w32.c | 2 + src/vid_ht216.c | 44 ++- src/vid_s3.c | 51 ++- src/vid_s3_virge.c | 6 + src/vid_svga.c | 39 ++- src/vid_svga.h | 10 + src/vid_svga_render.c | 602 +++++++++++++++++++++++++----------- src/vid_svga_render.h | 2 + src/vid_svga_render_remap.h | 129 ++++++++ src/vid_tgui9440.c | 73 +++-- 12 files changed, 741 insertions(+), 240 deletions(-) create mode 100644 src/vid_svga_render_remap.h diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 153723d..852406e 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -1,4 +1,5 @@ /*Cirrus Logic CL-GD5429 emulation*/ +//SR7.0 = "true packed-pixel memory addressing" #include #include "ibm.h" #include "cpu.h" @@ -178,6 +179,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p) case 0x07: svga->set_reset_disabled = svga->seqregs[7] & 1; + svga->packed_chain4 = svga->seqregs[7] & 1; + svga_recalctimings(svga); case 0x17: if (gd5429->type >= CL_TYPE_GD5429) gd5429_recalc_mapping(gd5429); @@ -844,11 +847,16 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) svga->fullchange = 2; if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; - else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) + else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { writemask2 = 1 << (addr & 3); addr &= ~3; } + else if (svga->chain4) + { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -1193,13 +1201,18 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; - else if (svga->chain4 || svga->fb_only) + else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; return svga->vram[addr & svga->vram_mask]; } + else if (svga->chain4) + { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); diff --git a/src/vid_et4000.c b/src/vid_et4000.c index ee30098..7f366b3 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -495,6 +495,8 @@ void *et4000_init() et4000_in, et4000_out, NULL, NULL); + + et4000->svga.packed_chain4 = 1; return et4000; } @@ -527,6 +529,8 @@ void *et4000k_init() et4000->svga.ksc5601_swap_mode = 0; et4000->svga.ksc5601_english_font_type = 0; + et4000->svga.packed_chain4 = 1; + return et4000; } @@ -571,6 +575,8 @@ void *et4000_kasan_init() et4000->svga.ksc5601_swap_mode = 0; et4000->svga.ksc5601_english_font_type = 0x1FF; + et4000->svga.packed_chain4 = 1; + return et4000; } diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index ae748ef..b84cdbd 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -1207,6 +1207,8 @@ void *et4000w32p_init() et4000->fifo_not_full_event = thread_create_event(); et4000->fifo_thread = thread_create(fifo_thread, et4000); + et4000->svga.packed_chain4 = 1; + return et4000; } diff --git a/src/vid_ht216.c b/src/vid_ht216.c index ab2e021..aa717e4 100644 --- a/src/vid_ht216.c +++ b/src/vid_ht216.c @@ -154,6 +154,9 @@ void ht216_out(uint16_t addr, uint8_t val, void *p) ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); break; + case 0xfc: + svga->packed_chain4 = val & 0x20; + break; case 0xff: svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2; //pclog("cursor_addr = %05x\n", svga->hwcursor.addr); @@ -421,6 +424,14 @@ static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b) return val; } +/*Remap address for chain-4/doubleword style layout*/ +static inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) +{ + if (svga->packed_chain4) + return in_addr; + return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); +} + static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded) { svga_t *svga = &ht216->svga; @@ -430,10 +441,10 @@ static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8 if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (svga->chain4 || svga->fb_only) + if (svga->chain4) { - writemask2=1<<(addr&3); - addr&=~3; + writemask2 = 1 << (addr & 3); + addr = dword_remap(svga, addr) & ~3; } else if (svga->chain2_write) { @@ -666,9 +677,10 @@ static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat uint8_t input_a = 0, input_b = 0; uint8_t fg, bg; uint8_t output; + uint32_t remapped_addr = dword_remap(svga, addr); if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/ - input_b = svga->vram[addr]; + input_b = svga->vram[remapped_addr]; else input_b = ht216->bg_latch[addr & 7]; @@ -695,9 +707,9 @@ static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); // svga->vram[addr] output = (fg & rop_select) | (bg & ~rop_select); - svga->vram[addr] = (svga->vram[addr] & ~bit_mask) | (output & bit_mask); + svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask); // pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr); - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[remapped_addr >> 12] = changeframecount; } static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) @@ -909,7 +921,7 @@ static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) egareads++; - if (svga->chain4 || svga->fb_only) + if (svga->chain4) { // if (ht216->ht_regs[0xcd]) // pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max); @@ -920,20 +932,20 @@ static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) latch_addr = (addr & svga->vram_mask) & ~7; if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) latch_addr += (svga->gdcreg[3] & 7); - ht216->bg_latch[0] = svga->vram[latch_addr]; - ht216->bg_latch[1] = svga->vram[latch_addr + 1]; - ht216->bg_latch[2] = svga->vram[latch_addr + 2]; - ht216->bg_latch[3] = svga->vram[latch_addr + 3]; - ht216->bg_latch[4] = svga->vram[latch_addr + 4]; - ht216->bg_latch[5] = svga->vram[latch_addr + 5]; - ht216->bg_latch[6] = svga->vram[latch_addr + 6]; - ht216->bg_latch[7] = svga->vram[latch_addr + 7]; + ht216->bg_latch[0] = svga->vram[dword_remap(svga, latch_addr)]; + ht216->bg_latch[1] = svga->vram[dword_remap(svga, latch_addr + 1)]; + ht216->bg_latch[2] = svga->vram[dword_remap(svga, latch_addr + 2)]; + ht216->bg_latch[3] = svga->vram[dword_remap(svga, latch_addr + 3)]; + ht216->bg_latch[4] = svga->vram[dword_remap(svga, latch_addr + 4)]; + ht216->bg_latch[5] = svga->vram[dword_remap(svga, latch_addr + 5)]; + ht216->bg_latch[6] = svga->vram[dword_remap(svga, latch_addr + 6)]; + ht216->bg_latch[7] = svga->vram[dword_remap(svga, latch_addr + 7)]; /*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr, ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ - return svga->vram[addr & svga->vram_mask]; + return svga->vram[dword_remap(svga, addr) & svga->vram_mask]; } else if (svga->chain2_read) { diff --git a/src/vid_s3.c b/src/vid_s3.c index f56ae34..65adde4 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1010,6 +1010,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + svga->force_dword_mode = val & 0x08; break; case 0x32: svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; @@ -1662,15 +1663,35 @@ static void polygon_setup(s3_t *s3) } } -#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \ +/*Remap address for chain-4/doubleword style layout*/ +static inline uint32_t dword_remap(uint32_t in_addr) +{ + return ((in_addr << 2) & 0x3fff0) | + ((in_addr >> 14) & 0xc) | + (in_addr & ~0x3fffc); +} +static inline uint32_t dword_remap_w(uint32_t in_addr) +{ + return ((in_addr << 2) & 0x1fff8) | + ((in_addr >> 14) & 0x6) | + (in_addr & ~0x1fffe); +} +static inline uint32_t dword_remap_l(uint32_t in_addr) +{ + return ((in_addr << 2) & 0xfffc) | + ((in_addr >> 14) & 0x3) | + (in_addr & ~0xffff); +} + +#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \ + else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; \ if (vram_mask) \ dat = ((dat & rd_mask) == rd_mask); -#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; +#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \ + else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; #define MIX { \ uint32_t old_dest_dat = dest_dat; \ @@ -1699,18 +1720,18 @@ static void polygon_setup(s3_t *s3) #define WRITE(addr) if (s3->bpp == 0) \ { \ - svga->vram[(addr) & s3->vram_mask] = dest_dat; \ - svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \ + svga->vram[dword_remap(addr) & s3->vram_mask] = dest_dat; \ + svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \ } \ else if (s3->bpp == 1) \ { \ - vram_w[(addr) & (s3->vram_mask >> 1)] = dest_dat; \ - svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ + vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dest_dat; \ + svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ } \ else \ { \ - vram_l[(addr) & (s3->vram_mask >> 2)] = dest_dat; \ - svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ + vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dest_dat; \ + svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) @@ -2520,8 +2541,10 @@ void s3_hwcursor_draw(svga_t *svga, int displine) // 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]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr); + + dat[0] = (svga->vram[remapped_addr] << 8) | svga->vram[remapped_addr + 1]; + dat[1] = (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; for (xx = 0; xx < 16; xx++) { if (offset >= svga->hwcursor_latch.x) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 562842d..428669b 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3945,6 +3945,9 @@ static void *s3_virge_init() ddc_init(); + //TODO ViRGE does not use packed chain4 + virge->svga.packed_chain4 = 1; + return virge; } @@ -4044,6 +4047,9 @@ static void *s3_virge_375_init() ddc_init(); + //TODO ViRGE does not use packed chain4 + virge->svga.packed_chain4 = 1; + return virge; } diff --git a/src/vid_svga.c b/src/vid_svga.c index 369173d..c41528c 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -116,7 +116,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 4: svga->chain2_write = !(val & 4); svga->chain4 = val & 8; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only); break; } break; @@ -201,7 +202,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 7: svga->colournocare=val; break; } svga->gdcreg[svga->gdcaddr & 15] = val; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only); if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) svga_recalctimings(svga); break; @@ -444,6 +446,8 @@ void svga_recalctimings(svga_t *svga) svga->dispontime = TIMER_USEC; if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; + + svga_recalc_remap_func(svga); /* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); @@ -816,11 +820,17 @@ void svga_write(uint32_t addr, uint8_t val, void *p) addr += svga->write_bank; if (!(svga->gdcreg[6] & 1)) svga->fullchange=2; - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { writemask2=1<<(addr&3); addr&=~3; } + else if (svga->chain4) + { + writemask2 = 1 << (addr & 3); + addr &= ~3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -1007,7 +1017,7 @@ uint8_t svga_read(uint32_t addr, void *p) // 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) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -1019,6 +1029,11 @@ uint8_t svga_read(uint32_t addr, void *p) svga->ld = svga->vram[latch_addr | 0x3]; return svga->vram[addr & svga->vram_mask]; } + else if (svga->chain4) + { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); @@ -1082,11 +1097,16 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) if (svga_output) pclog("Write LFB %08X %02X ", addr, val); if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { writemask2=1<<(addr&3); addr&=~3; } + else if (svga->chain4) + { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { writemask2 &= ~0xa; @@ -1262,13 +1282,18 @@ uint8_t svga_read_linear(uint32_t addr, void *p) egareads++; - if (svga->chain4 || svga->fb_only) + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; return svga->vram[addr & svga->vram_mask]; } + else if (svga->chain4) + { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); @@ -1276,7 +1301,9 @@ uint8_t svga_read_linear(uint32_t addr, void *p) addr <<= 2; } else + { addr<<=2; + } addr &= svga->decode_mask; diff --git a/src/vid_svga.h b/src/vid_svga.h index 9e49bfd..f8fb48b 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -148,6 +148,16 @@ typedef struct svga_t /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ int hsync_divisor; + + /*Tseng-style chain4 mode - CRTC dword mode is the same as byte mode, chain4 + addresses are shifted to match*/ + int packed_chain4; + + /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ + int force_dword_mode; + + int remap_required; + uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr); } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize, diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index eac363f..f07892b 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -3,6 +3,7 @@ #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" +#include "vid_svga_render_remap.h" void svga_render_null(svga_t *svga) { @@ -58,9 +59,12 @@ void svga_render_text_40(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -122,9 +126,12 @@ void svga_render_text_80(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; + if (attr & 8) charaddr = svga->charsetb + (chr * 128); else charaddr = svga->charseta + (chr * 128); @@ -186,10 +193,12 @@ void svga_render_text_80_ksc5601(svga_t *svga) for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + nextchr = svga->vram[addr + 8]; + attr = svga->vram[addr + 1]; if (drawcursor) { @@ -304,11 +313,9 @@ void svga_render_text_80_ksc5601(svga_t *svga) void svga_render_2bpp_lowres(svga_t *svga) { - int changed_offset; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = ((8 - svga->scrollcache) << 1) + 16; @@ -320,10 +327,11 @@ void svga_render_2bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 16) { + uint32_t addr = svga->remap_func(svga, svga->ma); uint8_t dat[2]; - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr + 1]; svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -343,11 +351,9 @@ void svga_render_2bpp_lowres(svga_t *svga) void svga_render_2bpp_highres(svga_t *svga) { - int changed_offset; - - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - svga->scrollcache) + 24; @@ -359,30 +365,31 @@ void svga_render_2bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t addr = svga->remap_func(svga, svga->ma); uint8_t dat[2]; - dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]; - dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1]; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr + 1]; svga->ma += 4; svga->ma &= svga->vram_display_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - - p += 8; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + *p++ = svga->pallook[svga->egapal[dat[0] & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + *p++ = svga->pallook[svga->egapal[dat[1] & 3]]; } } } void svga_render_4bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = ((8 - svga->scrollcache) << 1) + 16; @@ -396,8 +403,9 @@ void svga_render_4bpp_lowres(svga_t *svga) { uint8_t edat[4]; uint8_t dat; + uint32_t addr = svga->remap_func(svga, svga->ma); - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -421,11 +429,9 @@ void svga_render_4bpp_lowres(svga_t *svga) void svga_render_4bpp_highres(svga_t *svga) { - int changed_offset; - - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - svga->scrollcache) + 24; @@ -439,32 +445,33 @@ void svga_render_4bpp_highres(svga_t *svga) { uint8_t edat[4]; uint8_t dat; + uint32_t addr = svga->remap_func(svga, svga->ma); - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]); + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); svga->ma += 4; svga->ma &= svga->vram_display_mask; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - - p += 8; + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; } } } void svga_render_8bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -474,17 +481,36 @@ void svga_render_8bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - - p[0] = p[1] = svga->pallook[dat & 0xff]; - p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; - - svga->ma += 4; - p += 8; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 8; + } } svga->ma &= svga->vram_display_mask; } @@ -492,41 +518,62 @@ void svga_render_8bpp_lowres(svga_t *svga) void svga_render_8bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat; - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->pallook[dat & 0xff]; - p[1] = svga->pallook[(dat >> 8) & 0xff]; - p[2] = svga->pallook[(dat >> 16) & 0xff]; - p[3] = svga->pallook[(dat >> 24) & 0xff]; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga->pallook[dat & 0xff]; - p[5] = svga->pallook[(dat >> 8) & 0xff]; - p[6] = svga->pallook[(dat >> 16) & 0xff]; - p[7] = svga->pallook[(dat >> 24) & 0xff]; - - svga->ma += 8; - p += 8; + dat = *(uint32_t *)(&svga->vram[(svga->ma+4) & svga->vram_display_mask]); + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; + + svga->ma += 8; + } } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + svga->ma += 4; + + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; + } + } + svga->ma &= svga->vram_display_mask; } } void svga_render_15bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -536,26 +583,44 @@ void svga_render_15bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + } + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_15bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -565,32 +630,51 @@ void svga_render_15bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + + svga->ma += x << 1; + } + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_16bpp_lowres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; @@ -600,26 +684,45 @@ void svga_render_16bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + svga->ma += x << 1; } - svga->ma += x << 1; + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + svga->ma += 4; + } + } + svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_16bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -629,55 +732,106 @@ void svga_render_16bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + for (x = 0; x <= svga->hdisp; x += 8) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + + svga->ma += x << 1; + } + else + { + for (x = 0; x <= svga->hdisp; x += 2) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } void svga_render_24bpp_lowres(svga_t *svga) { - int x, offset; - uint32_t fg; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 3; - svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; + + svga->ma += 12; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat0, dat1, dat2; + uint32_t addr; + + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; + + svga->ma += 12; + } } } } void svga_render_24bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -687,21 +841,43 @@ void svga_render_24bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; - - svga->ma += 12; + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + + svga->ma += 12; + } + } + else + { + for (x = 0; x <= svga->hdisp; x += 4) + { + uint32_t dat0, dat1, dat2; + uint32_t addr; + + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + + svga->ma += 12; + } } svga->ma &= svga->vram_display_mask; } @@ -709,24 +885,40 @@ void svga_render_24bpp_highres(svga_t *svga) void svga_render_32bpp_lowres(svga_t *svga) { - int x, offset; - uint32_t fg; - - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - offset = (8 - (svga->scrollcache & 6)) + 24; - - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += x*4; } + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } @@ -734,7 +926,9 @@ void svga_render_32bpp_lowres(svga_t *svga) 91%*/ void svga_render_32bpp_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; @@ -744,56 +938,102 @@ void svga_render_32bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } + svga->ma += x*4; } - svga->ma += 4; + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } void svga_render_ABGR8888_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - - if (svga->firstline_draw == 2000) + + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } + svga->ma += x*4; } - svga->ma += 4; + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } void svga_render_RGBA8888_highres(svga_t *svga) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) + uint32_t changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - - if (svga->firstline_draw == 2000) + + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) + if (!svga->remap_required) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat >> 8; + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat >> 8; + } + svga->ma += x*4; } - svga->ma += 4; + else + { + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat >> 8; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } diff --git a/src/vid_svga_render.h b/src/vid_svga_render.h index 625ba6b..bb3b3c1 100644 --- a/src/vid_svga_render.h +++ b/src/vid_svga_render.h @@ -9,6 +9,8 @@ extern int scrollcache; extern uint8_t edatlookup[4][4]; +void svga_recalc_remap_func(svga_t *svga); + void svga_render_null(svga_t *svga); void svga_render_blank(svga_t *svga); void svga_render_text_40(svga_t *svga); diff --git a/src/vid_svga_render_remap.h b/src/vid_svga_render_remap.h new file mode 100644 index 0000000..189f846 --- /dev/null +++ b/src/vid_svga_render_remap.h @@ -0,0 +1,129 @@ +/*Variables : + byte/word/doubleword mode + word has MA13/MA15->MA0 + ET4000 treats doubleword as byte + row 0 -> MA13 + row 1 -> MA14 +*/ + +//S3 - enhanced mode mappings CR31.3 can force doubleword mode +//Cirrus Logic handles SVGA writes seperately +//S3, CL, TGUI blitters need checking + +//CL, S3, Mach64, ET4000, Banshee, TGUI all okay +//Still to check - ViRGE, HT216 +#define VAR_BYTE_MODE (0 << 0) +#define VAR_WORD_MODE_MA13 (1 << 0) +#define VAR_WORD_MODE_MA15 (2 << 0) +#define VAR_DWORD_MODE (3 << 0) +#define VAR_MODE_MASK (3 << 0) +#define VAR_ROW0_MA13 (1 << 2) +#define VAR_ROW1_MA14 (1 << 3) + +#define ADDRESS_REMAP_FUNC(nr) \ + static uint32_t address_remap_func_ ## nr(svga_t *svga, uint32_t in_addr) \ + { \ + uint32_t out_addr; \ + \ + switch (nr & VAR_MODE_MASK) \ + { \ + case VAR_BYTE_MODE: \ + out_addr = in_addr; \ + break; \ + \ + case VAR_WORD_MODE_MA13: \ + out_addr = ((in_addr << 1) & 0x1fff8) | \ + ((in_addr >> 13) & 0x4) | \ + (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_WORD_MODE_MA15: \ + out_addr = ((in_addr << 1) & 0x1fff8) | \ + ((in_addr >> 15) & 0x4) | \ + (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_DWORD_MODE: \ + out_addr = ((in_addr << 2) & 0x3fff0) | \ + ((in_addr >> 14) & 0xc) | \ + (in_addr & ~0x3ffff); \ + break; \ + } \ + \ + if (nr & VAR_ROW0_MA13) \ + out_addr = (out_addr & ~(1 << (13+2))) | \ + ((svga->sc & 1) ? (1 << (13+2)) : 0); \ + if (nr & VAR_ROW1_MA14) \ + out_addr = (out_addr & ~(1 << (14+2))) | \ + ((svga->sc & 2) ? (1 << (14+2)) : 0); \ + \ + return out_addr; \ + } + +ADDRESS_REMAP_FUNC(0) +ADDRESS_REMAP_FUNC(1) +ADDRESS_REMAP_FUNC(2) +ADDRESS_REMAP_FUNC(3) +ADDRESS_REMAP_FUNC(4) +ADDRESS_REMAP_FUNC(5) +ADDRESS_REMAP_FUNC(6) +ADDRESS_REMAP_FUNC(7) +ADDRESS_REMAP_FUNC(8) +ADDRESS_REMAP_FUNC(9) +ADDRESS_REMAP_FUNC(10) +ADDRESS_REMAP_FUNC(11) +ADDRESS_REMAP_FUNC(12) +ADDRESS_REMAP_FUNC(13) +ADDRESS_REMAP_FUNC(14) +ADDRESS_REMAP_FUNC(15) + +static uint32_t (*address_remap_funcs[16])(svga_t *svga, uint32_t in_addr) = +{ + address_remap_func_0, + address_remap_func_1, + address_remap_func_2, + address_remap_func_3, + address_remap_func_4, + address_remap_func_5, + address_remap_func_6, + address_remap_func_7, + address_remap_func_8, + address_remap_func_9, + address_remap_func_10, + address_remap_func_11, + address_remap_func_12, + address_remap_func_13, + address_remap_func_14, + address_remap_func_15 +}; + +void svga_recalc_remap_func(svga_t *svga) +{ + int func_nr; + + if (svga->fb_only) + func_nr = 0; + else + { + if (svga->force_dword_mode) + func_nr = VAR_DWORD_MODE; + else if (svga->crtc[0x14] & (1 << 6)) + func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE; + else if (svga->crtc[0x17] & (1 << 6)) + func_nr = VAR_BYTE_MODE; + else if (svga->crtc[0x17] & (1 << 5)) + func_nr = VAR_WORD_MODE_MA15; + else + func_nr = VAR_WORD_MODE_MA13; + + if (!(svga->crtc[0x17] & (1 << 0))) + func_nr |= VAR_ROW0_MA13; + if (!(svga->crtc[0x17] & (1 << 1))) + func_nr |= VAR_ROW1_MA14; + } + +// pclog("svga_recalc_remap_func: fb_only=%i chain4=%i packed_chain4=%i crtc[14]=%02x crtc[17]=%02x func_nr=%i\n", +// svga->fb_only, svga->chain4, svga->packed_chain4, svga->crtc[0x14], svga->crtc[0x17], func_nr); + svga->remap_required = (func_nr != 0); + svga->remap_func = address_remap_funcs[func_nr]; +} diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index 2edf8c7..a42f7e9 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -631,17 +631,34 @@ void tgui_recalcmapping(tgui_t *tgui) } } +/*Remap address for chain-4/doubleword style layout*/ +static inline uint32_t dword_remap(uint32_t in_addr) +{ + return ((in_addr << 2) & 0x3fff0) | + ((in_addr >> 14) & 0xc) | + (in_addr & ~0x3fffc); +} +static inline uint32_t dword_remap_w(uint32_t in_addr) +{ + return ((in_addr << 2) & 0x1fff8) | + ((in_addr >> 14) & 0x6) | + (in_addr & ~0x1fffe); +} + void tgui_hwcursor_draw(svga_t *svga, int displine) { uint32_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t remapped_addr; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 8; - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; + remapped_addr = dword_remap(svga->hwcursor_latch.addr); + dat[0] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; + remapped_addr = dword_remap(svga->hwcursor_latch.addr+4); + dat[1] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; for (xx = 0; xx < 32; xx++) { if (offset >= svga->hwcursor_latch.x) @@ -840,8 +857,13 @@ static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) return 0xff; addr &= ~0xf; + addr = dword_remap(addr); + for (c = 0; c < 16; c++) - tgui->copy_latch[c] = svga->vram[addr+c]; + { + tgui->copy_latch[c] = svga->vram[addr]; + addr += ((c & 3) == 3) ? 13 : 1; + } return svga->vram[addr & svga->vram_mask]; } @@ -871,7 +893,9 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - addr &= ~0x7; + addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; + + addr = dword_remap(addr); svga->changedvram[addr >> 12] = changeframecount; switch (tgui->ext_gdc_regs[0] & 0xf) @@ -882,7 +906,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr++; + addr += (c == 4) ? 13 : 1; } break; @@ -892,7 +916,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr++; + addr += (c == 4) ? 13 : 1; } break; @@ -902,7 +926,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[0]; - addr++; + addr += (c == 4) ? 13 : 1; } break; @@ -912,15 +936,17 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr++; + addr += (c == 4) ? 13 : 1; } break; case 0x8: case 0x9: case 0xa: case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: - addr &= ~0xf; for (c = 0; c < 16; c++) - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; + { + *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } break; } } @@ -942,6 +968,8 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) return; addr &= svga->vram_mask; addr &= ~0xf; + + addr = dword_remap(addr); svga->changedvram[addr >> 12] = changeframecount; val = (val >> 8) | (val << 8); @@ -954,7 +982,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr++; + addr += (c & 3) ? 1 : 13; } break; @@ -964,7 +992,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if (mask & (1 << c)) *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr++; + addr += (c & 3) ? 1 : 13; } break; @@ -974,7 +1002,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[0]; - addr++; + addr += (c & 3) ? 1 : 13; } break; @@ -984,14 +1012,17 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { if ((val & mask) & (1 << c)) *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr++; + addr += (c & 3) ? 1 : 13; } break; case 0x8: case 0x9: case 0xa: case 0xb: case 0xc: case 0xd: case 0xe: case 0xf: for (c = 0; c < 16; c++) - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; + { + *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } break; } } @@ -1044,8 +1075,8 @@ enum TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ }; -#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \ - else dat = vram_w[addr & 0xfffff]; +#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[dword_remap(addr) & 0x1fffff]; \ + else dat = vram_w[dword_remap_w(addr) & 0xfffff]; #define MIX() do \ { \ @@ -1061,13 +1092,13 @@ enum #define WRITE(addr, dat) if (tgui->accel.bpp == 0) \ { \ - svga->vram[addr & 0x1fffff] = dat; \ - svga->changedvram[((addr) & 0x1fffff) >> 12] = changeframecount; \ + svga->vram[dword_remap(addr) & 0x1fffff] = dat; \ + svga->changedvram[(dword_remap(addr) & 0x1fffff) >> 12] = changeframecount; \ } \ else \ { \ - vram_w[addr & 0xfffff] = dat; \ - svga->changedvram[((addr) & 0xfffff) >> 11] = changeframecount; \ + vram_w[dword_remap_w(addr) & 0xfffff] = dat; \ + svga->changedvram[(dword_remap_w(addr) & 0xfffff) >> 11] = changeframecount; \ } void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) From 231d235d8f92d9bffbf5f64dc429c778fc4ad180 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 May 2021 09:18:04 +0100 Subject: [PATCH 1030/1050] Fix bugs in Paradise banking. Fixes further Windows 3.x corruption. --- src/vid_paradise.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 3aabd3a..369fb34 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -101,9 +101,9 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) paradise_remap(paradise); return; } - if (svga->gdcaddr == 0xe) + if (svga->gdcaddr == 0xb) { - svga->gdcreg[0xe] = val; + svga->gdcreg[0xb] = val; paradise_remap(paradise); return; } @@ -211,11 +211,11 @@ void paradise_remap(paradise_t *paradise) paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } - else if (svga->gdcreg[0xe] & 0x08) + else if (svga->gdcreg[0xb] & 0x08) { if (svga->gdcreg[0x6] & 0xc) { -// pclog("Remap 2\n"); +// 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); @@ -238,7 +238,10 @@ void paradise_remap(paradise_t *paradise) 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]); + paradise->read_bank[1] &= 0x7ffff; + paradise->write_bank[1] &= 0x7ffff; + +// pclog("Remap - %04X %04X %04x %04x\n", paradise->read_bank[0], paradise->write_bank[0], paradise->read_bank[1], paradise->write_bank[1]); } void paradise_recalctimings(svga_t *svga) From 6b80e58487de186faea190638fe5a63881bad30e Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 May 2021 09:31:21 +0100 Subject: [PATCH 1031/1050] Fix BY16 addressing on Cirrus Logic cards. --- src/vid_cl5429.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/vid_cl5429.c b/src/vid_cl5429.c index 852406e..51584cd 100644 --- a/src/vid_cl5429.c +++ b/src/vid_cl5429.c @@ -96,9 +96,10 @@ typedef struct gd5429_t int vidsys_ena; } gd5429_t; -#define GRB_X8_ADDRESSING (1 << 1) -#define GRB_WRITEMODE_EXT (1 << 2) -#define GRB_8B_LATCHES (1 << 3) +#define GRB_X8_ADDRESSING (1 << 1) +#define GRB_WRITEMODE_EXT (1 << 2) +#define GRB_8B_LATCHES (1 << 3) +#define GRB_ENHANCED_16BIT (1 << 4) static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p); @@ -845,7 +846,9 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) // if (svga_output) pclog("Write LFB %08X %02X ", addr, val); if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) + addr <<= 4; + else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { @@ -879,10 +882,9 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) switch (svga->writemode) { case 4: - if (svga->gdcreg[0xb] & 0x10) + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) { // pclog("Writemode 4 : %X ", addr); - addr <<= 2; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); if (val & svga->seqregs[2] & 0x80) @@ -951,10 +953,9 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) break; case 5: - if (svga->gdcreg[0xb] & 0x10) + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) { // pclog("Writemode 5 : %X ", addr); - addr <<= 2; svga->changedvram[addr >> 12] = changeframecount; // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); if (svga->seqregs[2] & 0x80) @@ -1194,12 +1195,16 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p) egareads++; - if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) + latch_addr = (addr << 4) & svga->decode_mask; + else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) latch_addr = (addr << 3) & svga->decode_mask; else latch_addr = (addr << 2) & svga->decode_mask; - if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) + addr <<= 4; + else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) addr <<= 3; else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { From e8d6266df64e3e0c0f4afe3f10f1c104633a6a29 Mon Sep 17 00:00:00 2001 From: SarahW Date: Sat, 29 May 2021 21:50:44 +0100 Subject: [PATCH 1032/1050] GUS should set DMA TC IRQ flag even when IRQ disabled. Fixes sound in CNCD - Inside when DMA sample transfer enabled. Also cleaned up GUS IRQ handling a bit. --- src/sound_gus.c | 133 ++++++++++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 54 deletions(-) diff --git a/src/sound_gus.c b/src/sound_gus.c index 20df0c3..d1d54e5 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -85,40 +85,6 @@ int gusfreqs[]= double vol16bit[4096]; -void pollgusirqs(gus_t *gus) -{ - int c; - - gus->irqstatus&=~0x60; - for (c=0;c<32;c++) - { - 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); -} - enum { MIDI_INT_RECEIVE = 0x01, @@ -144,6 +110,73 @@ enum GUS_TIMER_CTRL_AUTO = 0x01 }; +void gus_update_int_status(gus_t *gus) +{ + int c; + int irq_pending = 0; + int midi_irq_pending = 0; + + gus->irqstatus&=~0x60; + gus->irqstatus2=0xE0; + for (c=0;c<32;c++) + { + 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); + irq_pending = 1; + break; + } + 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); + irq_pending = 1; + break; + } + } + if ((gus->tctrl & 4) && (gus->irqstatus & 0x04)) + irq_pending = 1; /*Timer 1 interrupt pending*/ + if ((gus->tctrl & 8) && (gus->irqstatus & 0x08)) + irq_pending = 1; /*Timer 2 interrupt pending*/ + if ((gus->irqstatus & 0x80) && (gus->dmactrl & 0x20)) + irq_pending = 1; /*DMA TC interrupt pending*/ + + midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; + +// pclog("gus_update_int_status: tctrl=%02x irqstatus=%02x irq_pending=%i midi_irq_pending=%i gus->irq=%i gus->irq_midi=%i\n", +// gus->tctrl, gus->irqstatus, irq_pending, midi_irq_pending, gus->irq, gus->irq_midi); + if (gus->irq == gus->irq_midi && gus->irq != -1) + { + if (irq_pending || midi_irq_pending) + picintlevel(1 << gus->irq); + else + picintc(1 << gus->irq); + } + else + { + if (gus->irq != -1) + { + if (irq_pending) + picintlevel(1 << gus->irq); + else + picintc(1 << gus->irq); + } + if (gus->irq_midi != -1) + { + if (midi_irq_pending) + picintlevel(1 << gus->irq_midi); + else + picintc(1 << gus->irq_midi); + } + } +} + void gus_midi_update_int_status(gus_t *gus) { gus->midi_status &= ~MIDI_INT_MASTER; @@ -163,11 +196,7 @@ void gus_midi_update_int_status(gus_t *gus) else gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE; - if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != -1)) - { -// pclog("Take MIDI IRQ\n"); - picint(1 << gus->irq_midi); - } + gus_update_int_status(gus); } void writegus(uint16_t addr, uint8_t val, void *p) @@ -271,6 +300,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); case 0x45: /*Timer control*/ // printf("Timer control %02X\n",val); gus->tctrl=val; + gus_update_int_status(gus); break; } break; @@ -291,7 +321,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); old = gus->waveirqs[gus->voice]; gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; if (gus->waveirqs[gus->voice] != old) - pollgusirqs(gus); + gus_update_int_status(gus); break; case 1: /*Frequency control*/ gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF)|(val<<8); @@ -355,7 +385,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); gus->rctrl[gus->voice] = val & 0x7F; gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; if (gus->rampirqs[gus->voice] != old) - pollgusirqs(gus); + gus_update_int_status(gus); // printf("Ramp control %02i %02X %02X %i\n",gus->voice,val,gus->rampirqs[gus->voice],ins); break; @@ -408,7 +438,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); } // printf("GUS->MEM Transferred %i bytes\n",c); gus->dmactrl=val&~0x40; - if (val&0x20) gus->irqnext=1; + gus->irqnext = 1; } else { @@ -440,7 +470,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); } // printf("MEM->GUS Transferred %i bytes\n",c); gus->dmactrl=val&~0x40; - if (val&0x20) gus->irqnext=1; + gus->irqnext = 1; } // exit(-1); } @@ -477,6 +507,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); }*/ gus->tctrl=val; gus->sb_ctrl = val; + gus_update_int_status(gus); break; case 0x46: /*Timer 1*/ gus->t1 = gus->t1l = val; @@ -674,7 +705,7 @@ uint8_t readgus(uint16_t addr, void *p) // pclog("Read IRQ status - %02X\n",val); gus->rampirqs[gus->irqstatus2&0x1F]=0; gus->waveirqs[gus->irqstatus2&0x1F]=0; - pollgusirqs(gus); + gus_update_int_status(gus); return val; case 0x00: case 0x01: case 0x02: case 0x03: @@ -722,7 +753,7 @@ uint8_t readgus(uint16_t addr, void *p) val=gus->irqstatus2; gus->rampirqs[gus->irqstatus2&0x1F]=0; gus->waveirqs[gus->irqstatus2&0x1F]=0; - pollgusirqs(gus); + gus_update_int_status(gus); // pclog("Read IRQ status - %02X %i %i\n",val, gus->waveirqs[gus->irqstatus2&0x1F], gus->rampirqs[gus->irqstatus2&0x1F]); return val; @@ -837,8 +868,6 @@ void gus_poll_timer_1(void *p) gus->ad_status |= 0x40; if (gus->tctrl&4) { - if (gus->irq != -1) - picint(1 << gus->irq); gus->ad_status |= 0x04; gus->irqstatus |= 0x04; // pclog("GUS T1 IRQ!\n"); @@ -850,10 +879,9 @@ void gus_poll_timer_1(void *p) // pclog("Take IRQ\n"); gus->irqnext=0; gus->irqstatus|=0x80; - if (gus->irq != -1) - picint(1 << gus->irq); } gus_midi_update_int_status(gus); + gus_update_int_status(gus); } void gus_poll_timer_2(void *p) @@ -872,8 +900,6 @@ void gus_poll_timer_2(void *p) gus->ad_status |= 0x20; if (gus->tctrl&8) { - if (gus->irq != -1) - picint(1 << gus->irq); gus->ad_status |= 0x02; gus->irqstatus |= 0x08; // pclog("GUS T2 IRQ!\n"); @@ -885,9 +911,8 @@ void gus_poll_timer_2(void *p) // pclog("Take IRQ\n"); gus->irqnext=0; gus->irqstatus|=0x80; - if (gus->irq != -1) - picint(1 << gus->irq); } + gus_update_int_status(gus); } static void gus_update(gus_t *gus) @@ -1075,7 +1100,7 @@ void gus_poll_wave(void *p) } if (update_irqs) - pollgusirqs(gus); + gus_update_int_status(gus); } static void gus_get_buffer(int32_t *buffer, int len, void *p) From 51516c0bb146919fe5409ed130c78a65c766b1bf Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 30 May 2021 15:23:11 +0100 Subject: [PATCH 1033/1050] Correct top-of-stack value stored by FSTENV. Fixes rendering in CNCD - Inside --- src/x87_ops_misc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index b2f7d32..bde89c7 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -781,6 +781,8 @@ static int FSTENV() { FP_ENTER(); if (fplog) pclog("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { case 0x000: /*16-bit real mode*/ From be74288b5e6f9dac2eff28685148ff5429c36161 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 31 May 2021 08:17:37 +0100 Subject: [PATCH 1034/1050] Stricter logic when adding/removing IO handlers. Fixes crashes with GA686BX when triggering power events when using older BIOSes (tested with 02/10/1999 BIOS). --- src/io.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/io.c b/src/io.c index 3c6cfd9..ea94c67 100644 --- a/src/io.c +++ b/src/io.c @@ -87,36 +87,28 @@ void io_removehandler(uint16_t base, int size, int c; for (c = 0; c < size; c++) { - if (port_priv[base + c][0] == priv) + if (port_priv[base + c][0] == priv && + port_inb[base + c][0] == inb && port_inw[base + c][0] == inw && port_inl[base + c][0] == inl && + port_outb[base + c][0] == outb && port_outw[base + c][0] == outw && port_outl[base + c][0] == outl) { - if (port_inb[ base + c][0] == inb) - port_inb[ base + c][0] = NULL; - if (port_inw[ base + c][0] == inw) - port_inw[ base + c][0] = NULL; - if (port_inl[ base + c][0] == inl) - port_inl[ base + c][0] = NULL; - if (port_outb[ base + c][0] == outb) - port_outb[ base + c][0] = NULL; - if (port_outw[ base + c][0] == outw) - port_outw[ base + c][0] = NULL; - if (port_outl[ base + c][0] == outl) - port_outl[ base + c][0] = NULL; + port_inb[ base + c][0] = NULL; + port_inw[ base + c][0] = NULL; + port_inl[ base + c][0] = NULL; + port_outb[ base + c][0] = NULL; + port_outw[ base + c][0] = NULL; + port_outl[ base + c][0] = NULL; port_priv[base + c][0] = NULL; } - if (port_priv[base + c][1] == priv) + if (port_priv[base + c][1] == priv && + port_inb[base + c][1] == inb && port_inw[base + c][1] == inw && port_inl[base + c][1] == inl && + port_outb[base + c][1] == outb && port_outw[base + c][1] == outw && port_outl[base + c][1] == outl) { - if (port_inb[ base + c][1] == inb) - port_inb[ base + c][1] = NULL; - if (port_inw[ base + c][1] == inw) - port_inw[ base + c][1] = NULL; - if (port_inl[ base + c][1] == inl) - port_inl[ base + c][1] = NULL; - if (port_outb[ base + c][1] == outb) - port_outb[ base + c][1] = NULL; - if (port_outw[ base + c][1] == outw) - port_outw[ base + c][1] = NULL; - if (port_outl[ base + c][1] == outl) - port_outl[ base + c][1] = NULL; + port_inb[ base + c][1] = NULL; + port_inw[ base + c][1] = NULL; + port_inl[ base + c][1] = NULL; + port_outb[base + c][1] = NULL; + port_outw[base + c][1] = NULL; + port_outl[base + c][1] = NULL; port_priv[base + c][1] = NULL; } } From 0ad51dd73be0fea3da7400ef998ff386100d2c87 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 31 May 2021 09:31:50 +0100 Subject: [PATCH 1035/1050] Add status window text for GUS --- src/sound_gus.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sound_gus.c b/src/sound_gus.c index d1d54e5..05700c2 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -1181,6 +1181,16 @@ void gus_speed_changed(void *p) gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); } +static void gus_add_status_info(char *s, int max_len, void *p) +{ + gus_t *gus = (gus_t *)p; + char temps[256]; + + sprintf(temps, "GUS max voices : %i\nGUS playback frequency : %iHz\n\n", + gus->voices, gusfreqs[gus->voices-14]); + strncat(s, temps, max_len); +} + device_t gus_device = { "Gravis UltraSound", @@ -1190,5 +1200,5 @@ device_t gus_device = NULL, gus_speed_changed, NULL, - NULL + gus_add_status_info }; From 2e037b50760c4ee35b86104e5102bbc1cb1881a5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 2 Jun 2021 21:13:39 +0100 Subject: [PATCH 1036/1050] FSCALE should always return 0.0 if ST(0) input is 0.0, regardless of value of ST(1); this might otherwise return infinity or NaN if not trapped. Fixes fade-in on MDK2. --- src/x87_ops_misc.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index bde89c7..8abb544 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -673,7 +673,8 @@ static int opFSCALE(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FSCALE\n"); temp64 = (int64_t)ST(1); - ST(0) = ST(0) * pow(2.0, (double)temp64); + if (ST(0) != 0.0) + ST(0) = ST(0) * pow(2.0, (double)temp64); cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(x87_timings.fscale); return 0; From 5f772fdf70bfb49cac3c57c552ce1f10d1ea55a5 Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 3 Jun 2021 20:36:30 +0100 Subject: [PATCH 1037/1050] Correct path to default NVR files on Linux --- src/nvr.c | 6 +----- src/paths.c | 12 ++++++++++++ src/paths.h | 2 ++ src/wx-sdl2.c | 6 ++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/nvr.c b/src/nvr.c index 7a96db5..edbd35b 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -48,11 +48,7 @@ FILE *nvrfopen(char *fn, char *mode) if (mode[0] == 'r') { - strcpy(s, nvr_path); - put_backslash(s); - strcat(s, "default"); - put_backslash(s); - strcat(s, fn); + snprintf(s, 512, "%s%s", nvr_default_path, fn); return fopen(s, mode); } else diff --git a/src/paths.c b/src/paths.c index e3265b8..15d9963 100644 --- a/src/paths.c +++ b/src/paths.c @@ -25,6 +25,8 @@ char logs_path[512]; /* this is where screenshots as stored */ char screenshots_path[512]; +char nvr_default_path[512]; + char get_path_separator() { #ifdef _WIN32 @@ -129,6 +131,11 @@ void set_default_nvr_path(char *s) set_nvr_path(s); } +static void set_default_nvr_default_path(char *s) +{ + safe_strncpy(nvr_default_path, s, 512); +} + /* set the default logs path, this makes it permanent */ void set_default_logs_path(char *s) { @@ -203,6 +210,7 @@ void paths_onconfigloaded() void paths_init() { char s[512]; + char base_path[512]; char *p; get_pcem_path(pcem_path, 512); @@ -221,6 +229,10 @@ void paths_init() set_screenshots_path(s); set_logs_path(pcem_path); + get_pcem_base_path(base_path, 512); + append_filename(s, base_path, "nvr/default/", 512); + set_default_nvr_default_path(s); + add_config_callback(paths_loadconfig, paths_saveconfig, paths_onconfigloaded); } diff --git a/src/paths.h b/src/paths.h index ba54344..bf18630 100644 --- a/src/paths.h +++ b/src/paths.h @@ -4,8 +4,10 @@ extern char configs_path[512]; extern char nvr_path[512]; extern char logs_path[512]; extern char screenshots_path[512]; +extern char nvr_default_path[512]; void get_pcem_path(char *s, int size); +void get_pcem_base_path(char *s, int size); char get_path_separator(); void paths_init(); int dir_exists(char* path); diff --git a/src/wx-sdl2.c b/src/wx-sdl2.c index 172a50e..984d731 100644 --- a/src/wx-sdl2.c +++ b/src/wx-sdl2.c @@ -263,6 +263,12 @@ void get_pcem_path(char *s, int size) #endif } +void get_pcem_base_path(char *s, int size) +{ + char* path = SDL_GetBasePath(); + strcpy(s, path); +} + void set_window_title(const char *s) { sdl_set_window_title(s); From e069ec73386b3e4c8e6f1fe9d3e2463fa4650891 Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 4 Jun 2021 08:13:35 +0100 Subject: [PATCH 1038/1050] Banshee: disable SVGA video processing (set svga->fb_only) when video processor is enabled. Fixes corrupt desktop introduced by recent SVGA mapping changes. --- src/vid_voodoo_banshee.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 2ac803e..a549270 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -147,6 +147,7 @@ enum #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) +#define VIDPROCCFG_VIDPROC_ENABLE (1 << 0) #define VIDPROCCFG_CURSOR_MODE (1 << 1) #define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) @@ -476,6 +477,8 @@ static void banshee_recalctimings(svga_t *svga) svga->video_res_override = 0; } + svga->fb_only = (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE); + if (((svga->miscout >> 2) & 3) == 3) { int k = banshee->pllCtrl0 & 3; From 84b9af3e05bb29f23afbcf900d2d3b8cb5b675ca Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 7 Jun 2021 19:51:30 +0100 Subject: [PATCH 1039/1050] Use correct value for Y swap origin on Voodoo Banshee/3. Fixes issues sometimes seen when running in low resolutions, ie below 640x480. --- src/vid_voodoo_banshee.c | 4 ++++ src/vid_voodoo_blitter.c | 6 ++++-- src/vid_voodoo_common.h | 2 ++ src/vid_voodoo_render.c | 5 +++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index a549270..34eaffd 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -205,6 +205,9 @@ enum #define VIDSERIAL_I2C_SCK_R (1 << 26) #define VIDSERIAL_I2C_SDA_R (1 << 27) +#define MISCINIT0_Y_ORIGIN_SWAP_SHIFT (18) +#define MISCINIT0_Y_ORIGIN_SWAP_MASK (0xfff << MISCINIT0_Y_ORIGIN_SWAP_SHIFT) + static uint32_t banshee_status(banshee_t *banshee); static void banshee_out(uint16_t addr, uint8_t val, void *p) @@ -550,6 +553,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Init_miscInit0: banshee->miscInit0 = val; + voodoo->y_origin_swap = (val & MISCINIT0_Y_ORIGIN_SWAP_MASK) >> MISCINIT0_Y_ORIGIN_SWAP_SHIFT; break; case Init_miscInit1: banshee->miscInit1 = val; diff --git a/src/vid_voodoo_blitter.c b/src/vid_voodoo_blitter.c index 01048f9..af7e204 100644 --- a/src/vid_voodoo_blitter.c +++ b/src/vid_voodoo_blitter.c @@ -409,8 +409,10 @@ void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) if (params->fbzMode & (1 << 17)) { - high_y = voodoo->v_disp - params->clipLowY; - low_y = voodoo->v_disp - params->clipHighY; + int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap+1) : voodoo->v_disp; + + high_y = y_origin - params->clipLowY; + low_y = y_origin - params->clipHighY; } else { diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index df261af..dd760ae 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -456,6 +456,8 @@ typedef struct voodoo_t uint32_t tile_base, tile_stride; int tile_stride_shift, tile_x, tile_x_real; + int y_origin_swap; + int read_time, write_time, burst_time; pc_timer_t wake_timer; diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index 2116180..503829d 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -682,6 +682,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); #endif int y_diff = SLI_ENABLED ? 2 : 1; + int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? voodoo->y_origin_swap : (voodoo->v_disp-1); if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) @@ -746,7 +747,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood int test_y; if (params->fbzMode & (1 << 17)) - test_y = (voodoo->v_disp-1) - state->y; + test_y = y_origin - state->y; else test_y = state->y; @@ -811,7 +812,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); if (params->fbzMode & (1 << 17)) - real_y = (voodoo->v_disp-1) - (real_y >> 4); + real_y = y_origin - (real_y >> 4); else real_y >>= 4; From b62acab9aedc0bd0b022c882f42354d3c166211b Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Tue, 8 Jun 2021 15:08:20 -0600 Subject: [PATCH 1040/1050] Update x86seg.c Evaluates the bitwise operator first. Fixes a warning in Clang: "logical not is only applied to the left hand side of this bitwise operator [-Wlogical-not-parentheses]" --- src/x86seg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x86seg.c b/src/x86seg.c index c44e807..f2d465f 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -3058,7 +3058,7 @@ void x86_smi_enter(void) { uint32_t base; - if (!cyrix.smhr & SMHR_VALID) + if (!(cyrix.smhr & SMHR_VALID)) cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; base = cyrix.smhr & SMHR_ADDR_MASK; From bfa73972b1774fd843a473821a6372f43a16893a Mon Sep 17 00:00:00 2001 From: "C.W. Betts" Date: Tue, 8 Jun 2021 15:24:21 -0600 Subject: [PATCH 1041/1050] Declare HAVE_UNISTD_H for FreeBSD and Linux This should quiet warnings about undefined functions in the slirp source files. --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index 94516ae..408ac13 100644 --- a/configure.ac +++ b/configure.ac @@ -160,6 +160,7 @@ case "$host" in [echo "You need to install the OpenAL library." exit -1]) build_linux="yes" + CFLAGS="$CFLAGS -DHAVE_UNISTD_H" ;; *-*-freebsd*) CFLAGS="$CFLAGS -I/usr/local/include" @@ -172,6 +173,7 @@ case "$host" in [echo "You need to install the OpenAL library." exit -1]) build_other="yes" + CFLAGS="$CFLAGS -DHAVE_UNISTD_H" ;; *) AC_CHECK_LIB([GL], [glGetError], [], \ From e781f6b4a22f10df68701551be3aff01e1974d26 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 9 Jun 2021 20:04:17 +0100 Subject: [PATCH 1042/1050] midi_alsa: Increase maximum sysex message to 65536 bytes, and cap regular messages at 3 bytes. Fixes out-of-bounds corruption and crashes. --- src/midi_alsa.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/midi_alsa.c b/src/midi_alsa.c index f513c23..5b8a2cc 100644 --- a/src/midi_alsa.c +++ b/src/midi_alsa.c @@ -124,7 +124,7 @@ static int midi_pos, midi_len; static uint8_t midi_command[4]; 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 uint8_t midi_sysex_data[65536]; void midi_write(uint8_t val) { @@ -143,7 +143,7 @@ void midi_write(uint8_t val) { midi_sysex_data[midi_pos++] = val; - if (val == 0xf7 || midi_pos >= 1024+2) + if (val == 0xf7 || midi_pos >= 65536) { /* pclog("MIDI send sysex %i: ", midi_pos); for (int i = 0; i < midi_pos; i++) @@ -157,15 +157,18 @@ void midi_write(uint8_t val) } if (midi_len) - { - midi_command[midi_pos] = val; - - midi_pos++; - - if (midi_pos == midi_len) + { + if (midi_pos < 3) { -// pclog("MIDI send %i: %02x %02x %02x %02x\n", midi_len, midi_command[0], midi_command[1], midi_command[2], midi_command[3]); - snd_rawmidi_write(midiout, midi_command, midi_len); + midi_command[midi_pos] = val; + + midi_pos++; + + if (midi_pos == midi_len) + { +// pclog("MIDI send %i: %02x %02x %02x %02x\n", midi_len, midi_command[0], midi_command[1], midi_command[2], midi_command[3]); + snd_rawmidi_write(midiout, midi_command, midi_len); + } } } } From b22cc53122c0aae5574a8a3d6bbf0d77e12dc71b Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 10 Jun 2021 08:08:17 +0100 Subject: [PATCH 1043/1050] config: If configure dialog opened with an unavailable model selected (eg ROMs not present), force an available model instead. Fixes new model creation when only one ROM set available. --- src/wx-config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wx-config.c b/src/wx-config.c index 5ff7679..9bc5c8d 100644 --- a/src/wx-config.c +++ b/src/wx-config.c @@ -737,6 +737,8 @@ int config_dlgproc(void* hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) c++; } wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); + model = listtomodel[modeltolist[model]]; + romset = model_getromset(); prev_model = model; recalc_vid_list(hdlg, romstomodel[romset], 0); From 0322c0f936602edc904617f8b350c8c8ff84e638 Mon Sep 17 00:00:00 2001 From: leilei- Date: Tue, 15 Jun 2021 01:12:53 -0400 Subject: [PATCH 1044/1050] Voodoo: Emulation of dither subtraction (interpreter only) --- src/vid_voodoo.c | 9 + src/vid_voodoo_banshee.c | 12 + src/vid_voodoo_common.h | 1 + src/vid_voodoo_dither.h | 5144 ++++++++++++++++++++++++++++++++++++++ src/vid_voodoo_regs.h | 3 + src/vid_voodoo_render.c | 14 + 6 files changed, 5183 insertions(+) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 132ced4..4164908 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -952,6 +952,7 @@ void *voodoo_card_init() memset(voodoo, 0, sizeof(voodoo_t)); voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->dithersub_enabled = device_get_config_int("dithersub"); voodoo->scrfilter = device_get_config_int("dacfilter"); voodoo->texture_size = device_get_config_int("texture_memory"); voodoo->texture_mask = (voodoo->texture_size << 20) - 1; @@ -1098,8 +1099,10 @@ void *voodoo_2d3d_card_init(int type) memset(voodoo, 0, sizeof(voodoo_t)); voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->dithersub_enabled = device_get_config_int("dithersub"); voodoo->scrfilter = device_get_config_int("dacfilter"); voodoo->render_threads = device_get_config_int("render_threads"); + voodoo->odd_even_mask = voodoo->render_threads - 1; #ifndef NO_CODEGEN voodoo->use_recompiler = device_get_config_int("recompiler"); @@ -1407,6 +1410,12 @@ static device_config_t voodoo_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, { .name = "dacfilter", .description = "Screen Filter", diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 34eaffd..cf676a0 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -2474,6 +2474,12 @@ static device_config_t banshee_sgram_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, { .name = "dacfilter", .description = "Screen Filter", @@ -2525,6 +2531,12 @@ static device_config_t banshee_sdram_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_int = 1 + }, { .name = "dacfilter", .description = "Screen Filter", diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index dd760ae..bfd0f7f 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -283,6 +283,7 @@ typedef struct voodoo_t int swap_pending; int bilinear_enabled; + int dithersub_enabled; int fb_size; uint32_t fb_mask; diff --git a/src/vid_voodoo_dither.h b/src/vid_voodoo_dither.h index daf26d5..c1109c9 100644 --- a/src/vid_voodoo_dither.h +++ b/src/vid_voodoo_dither.h @@ -5134,3 +5134,5147 @@ static const uint8_t dither_g2x2[256][2][2] = }, }; + + +/* Dither subtraction */ + +static const uint8_t dithersub_rb[256][4][4] = +{ + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {9, 5, 8, 4}, + {3, 7, 2, 6}, + {7, 3, 8, 4}, + {1, 5, 2, 6}, + }, + { + {10, 6, 9, 5}, + {4, 8, 3, 7}, + {8, 4, 9, 5}, + {2, 6, 3, 7}, + }, + { + {11, 7, 10, 6}, + {5, 9, 4, 8}, + {9, 5, 10, 6}, + {3, 7, 4, 8}, + }, + { + {12, 8, 11, 7}, + {6, 10, 5, 9}, + {10, 6, 11, 7}, + {4, 8, 5, 9}, + }, + { + {13, 9, 12, 8}, + {7, 11, 6, 10}, + {11, 7, 12, 8}, + {5, 9, 6, 10}, + }, + { + {14, 10, 13, 9}, + {8, 12, 7, 11}, + {12, 8, 13, 9}, + {6, 10, 7, 11}, + }, + { + {15, 11, 14, 10}, + {9, 13, 8, 12}, + {13, 9, 14, 10}, + {7, 11, 8, 12}, + }, + { + {16, 12, 15, 11}, + {10, 14, 9, 13}, + {14, 10, 15, 11}, + {8, 12, 9, 13}, + }, + { + {17, 13, 16, 12}, + {11, 15, 10, 14}, + {15, 11, 16, 12}, + {9, 13, 10, 14}, + }, + { + {18, 14, 17, 13}, + {12, 16, 11, 15}, + {16, 12, 17, 13}, + {10, 14, 11, 15}, + }, + { + {19, 15, 18, 14}, + {13, 17, 12, 16}, + {17, 13, 18, 14}, + {11, 15, 12, 16}, + }, + { + {20, 16, 19, 15}, + {14, 18, 13, 17}, + {18, 14, 19, 15}, + {12, 16, 13, 17}, + }, + { + {21, 17, 20, 16}, + {15, 19, 14, 18}, + {19, 15, 20, 16}, + {13, 17, 14, 18}, + }, + { + {22, 18, 21, 17}, + {16, 20, 15, 19}, + {20, 16, 21, 17}, + {14, 18, 15, 19}, + }, + { + {23, 19, 22, 18}, + {17, 21, 16, 20}, + {21, 17, 22, 18}, + {15, 19, 16, 20}, + }, + { + {24, 20, 23, 19}, + {18, 22, 17, 21}, + {22, 18, 23, 19}, + {16, 20, 17, 21}, + }, + { + {25, 21, 24, 20}, + {19, 23, 18, 22}, + {23, 19, 24, 20}, + {17, 21, 18, 22}, + }, + { + {26, 22, 25, 21}, + {20, 24, 19, 23}, + {24, 20, 25, 21}, + {18, 22, 19, 23}, + }, + { + {27, 23, 26, 22}, + {21, 25, 20, 24}, + {25, 21, 26, 22}, + {19, 23, 20, 24}, + }, + { + {28, 24, 27, 23}, + {22, 26, 21, 25}, + {26, 22, 27, 23}, + {20, 24, 21, 25}, + }, + { + {29, 25, 28, 24}, + {23, 27, 22, 26}, + {27, 23, 28, 24}, + {21, 25, 22, 26}, + }, + { + {30, 26, 29, 25}, + {24, 28, 23, 27}, + {28, 24, 29, 25}, + {22, 26, 23, 27}, + }, + { + {31, 27, 30, 26}, + {25, 29, 24, 28}, + {29, 25, 30, 26}, + {23, 27, 24, 28}, + }, + { + {32, 28, 31, 27}, + {26, 30, 25, 29}, + {30, 26, 31, 27}, + {24, 28, 25, 29}, + }, + { + {33, 29, 32, 28}, + {27, 31, 26, 30}, + {31, 27, 32, 28}, + {25, 29, 26, 30}, + }, + { + {34, 30, 33, 29}, + {28, 32, 27, 31}, + {32, 28, 33, 29}, + {26, 30, 27, 31}, + }, + { + {35, 31, 34, 30}, + {29, 33, 28, 32}, + {33, 29, 34, 30}, + {27, 31, 28, 32}, + }, + { + {36, 32, 35, 31}, + {30, 34, 29, 33}, + {34, 30, 35, 31}, + {28, 32, 29, 33}, + }, + { + {37, 33, 36, 32}, + {31, 35, 30, 34}, + {35, 31, 36, 32}, + {29, 33, 30, 34}, + }, + { + {38, 34, 37, 33}, + {32, 36, 31, 35}, + {36, 32, 37, 33}, + {30, 34, 31, 35}, + }, + { + {39, 35, 38, 34}, + {33, 37, 32, 36}, + {37, 33, 38, 34}, + {31, 35, 32, 36}, + }, + { + {40, 36, 39, 35}, + {34, 38, 33, 37}, + {38, 34, 39, 35}, + {32, 36, 33, 37}, + }, + { + {41, 37, 40, 36}, + {35, 39, 34, 38}, + {39, 35, 40, 36}, + {33, 37, 34, 38}, + }, + { + {42, 38, 41, 37}, + {36, 40, 35, 39}, + {40, 36, 41, 37}, + {34, 38, 35, 39}, + }, + { + {43, 39, 42, 38}, + {37, 41, 36, 40}, + {41, 37, 42, 38}, + {35, 39, 36, 40}, + }, + { + {44, 40, 43, 39}, + {38, 42, 37, 41}, + {42, 38, 43, 39}, + {36, 40, 37, 41}, + }, + { + {45, 41, 44, 40}, + {39, 43, 38, 42}, + {43, 39, 44, 40}, + {37, 41, 38, 42}, + }, + { + {46, 42, 45, 41}, + {40, 44, 39, 43}, + {44, 40, 45, 41}, + {38, 42, 39, 43}, + }, + { + {47, 43, 46, 42}, + {41, 45, 40, 44}, + {45, 41, 46, 42}, + {39, 43, 40, 44}, + }, + { + {48, 44, 47, 43}, + {42, 46, 41, 45}, + {46, 42, 47, 43}, + {40, 44, 41, 45}, + }, + { + {49, 45, 48, 44}, + {43, 47, 42, 46}, + {47, 43, 48, 44}, + {41, 45, 42, 46}, + }, + { + {50, 46, 49, 45}, + {44, 48, 43, 47}, + {48, 44, 49, 45}, + {42, 46, 43, 47}, + }, + { + {51, 47, 50, 46}, + {45, 49, 44, 48}, + {49, 45, 50, 46}, + {43, 47, 44, 48}, + }, + { + {52, 48, 51, 47}, + {46, 50, 45, 49}, + {50, 46, 51, 47}, + {44, 48, 45, 49}, + }, + { + {53, 49, 52, 48}, + {47, 51, 46, 50}, + {51, 47, 52, 48}, + {45, 49, 46, 50}, + }, + { + {54, 50, 53, 49}, + {48, 52, 47, 51}, + {52, 48, 53, 49}, + {46, 50, 47, 51}, + }, + { + {55, 51, 54, 50}, + {49, 53, 48, 52}, + {53, 49, 54, 50}, + {47, 51, 48, 52}, + }, + { + {56, 52, 55, 51}, + {50, 54, 49, 53}, + {54, 50, 55, 51}, + {48, 52, 49, 53}, + }, + { + {57, 53, 56, 52}, + {51, 55, 50, 54}, + {55, 51, 56, 52}, + {49, 53, 50, 54}, + }, + { + {58, 54, 57, 53}, + {52, 56, 51, 55}, + {56, 52, 57, 53}, + {50, 54, 51, 55}, + }, + { + {59, 55, 58, 54}, + {53, 57, 52, 56}, + {57, 53, 58, 54}, + {51, 55, 52, 56}, + }, + { + {60, 56, 59, 55}, + {54, 58, 53, 57}, + {58, 54, 59, 55}, + {52, 56, 53, 57}, + }, + { + {61, 57, 60, 56}, + {55, 59, 54, 58}, + {59, 55, 60, 56}, + {53, 57, 54, 58}, + }, + { + {62, 58, 61, 57}, + {56, 60, 55, 59}, + {60, 56, 61, 57}, + {54, 58, 55, 59}, + }, + { + {63, 59, 62, 58}, + {57, 61, 56, 60}, + {61, 57, 62, 58}, + {55, 59, 56, 60}, + }, + { + {64, 60, 63, 59}, + {58, 62, 57, 61}, + {62, 58, 63, 59}, + {56, 60, 57, 61}, + }, + { + {65, 61, 64, 60}, + {59, 63, 58, 62}, + {63, 59, 64, 60}, + {57, 61, 58, 62}, + }, + { + {66, 62, 65, 61}, + {60, 64, 59, 63}, + {64, 60, 65, 61}, + {58, 62, 59, 63}, + }, + { + {67, 63, 66, 62}, + {61, 65, 60, 64}, + {65, 61, 66, 62}, + {59, 63, 60, 64}, + }, + { + {68, 64, 67, 63}, + {62, 66, 61, 65}, + {66, 62, 67, 63}, + {60, 64, 61, 65}, + }, + { + {69, 65, 68, 64}, + {63, 67, 62, 66}, + {67, 63, 68, 64}, + {61, 65, 62, 66}, + }, + { + {70, 66, 69, 65}, + {64, 68, 63, 67}, + {68, 64, 69, 65}, + {62, 66, 63, 67}, + }, + { + {71, 67, 70, 66}, + {65, 69, 64, 68}, + {69, 65, 70, 66}, + {63, 67, 64, 68}, + }, + { + {72, 68, 71, 67}, + {66, 70, 65, 69}, + {70, 66, 71, 67}, + {64, 68, 65, 69}, + }, + { + {73, 69, 72, 68}, + {67, 71, 66, 70}, + {71, 67, 72, 68}, + {65, 69, 66, 70}, + }, + { + {74, 70, 73, 69}, + {68, 72, 67, 71}, + {72, 68, 73, 69}, + {66, 70, 67, 71}, + }, + { + {75, 71, 74, 70}, + {69, 73, 68, 72}, + {73, 69, 74, 70}, + {67, 71, 68, 72}, + }, + { + {76, 72, 75, 71}, + {70, 74, 69, 73}, + {74, 70, 75, 71}, + {68, 72, 69, 73}, + }, + { + {77, 73, 76, 72}, + {71, 75, 70, 74}, + {75, 71, 76, 72}, + {69, 73, 70, 74}, + }, + { + {78, 74, 77, 73}, + {72, 76, 71, 75}, + {76, 72, 77, 73}, + {70, 74, 71, 75}, + }, + { + {79, 75, 78, 74}, + {73, 77, 72, 76}, + {77, 73, 78, 74}, + {71, 75, 72, 76}, + }, + { + {80, 76, 79, 75}, + {74, 78, 73, 77}, + {78, 74, 79, 75}, + {72, 76, 73, 77}, + }, + { + {81, 77, 80, 76}, + {75, 79, 74, 78}, + {79, 75, 80, 76}, + {73, 77, 74, 78}, + }, + { + {82, 78, 81, 77}, + {76, 80, 75, 79}, + {80, 76, 81, 77}, + {74, 78, 75, 79}, + }, + { + {83, 79, 82, 78}, + {77, 81, 76, 80}, + {81, 77, 82, 78}, + {75, 79, 76, 80}, + }, + { + {84, 80, 83, 79}, + {78, 82, 77, 81}, + {82, 78, 83, 79}, + {76, 80, 77, 81}, + }, + { + {85, 81, 84, 80}, + {79, 83, 78, 82}, + {83, 79, 84, 80}, + {77, 81, 78, 82}, + }, + { + {86, 82, 85, 81}, + {80, 84, 79, 83}, + {84, 80, 85, 81}, + {78, 82, 79, 83}, + }, + { + {87, 83, 86, 82}, + {81, 85, 80, 84}, + {85, 81, 86, 82}, + {79, 83, 80, 84}, + }, + { + {88, 84, 87, 83}, + {82, 86, 81, 85}, + {86, 82, 87, 83}, + {80, 84, 81, 85}, + }, + { + {89, 85, 88, 84}, + {83, 87, 82, 86}, + {87, 83, 88, 84}, + {81, 85, 82, 86}, + }, + { + {90, 86, 89, 85}, + {84, 88, 83, 87}, + {88, 84, 89, 85}, + {82, 86, 83, 87}, + }, + { + {91, 87, 90, 86}, + {85, 89, 84, 88}, + {89, 85, 90, 86}, + {83, 87, 84, 88}, + }, + { + {92, 88, 91, 87}, + {86, 90, 85, 89}, + {90, 86, 91, 87}, + {84, 88, 85, 89}, + }, + { + {93, 89, 92, 88}, + {87, 91, 86, 90}, + {91, 87, 92, 88}, + {85, 89, 86, 90}, + }, + { + {94, 90, 93, 89}, + {88, 92, 87, 91}, + {92, 88, 93, 89}, + {86, 90, 87, 91}, + }, + { + {95, 91, 94, 90}, + {89, 93, 88, 92}, + {93, 89, 94, 90}, + {87, 91, 88, 92}, + }, + { + {96, 92, 95, 91}, + {90, 94, 89, 93}, + {94, 90, 95, 91}, + {88, 92, 89, 93}, + }, + { + {97, 93, 96, 92}, + {91, 95, 90, 94}, + {95, 91, 96, 92}, + {89, 93, 90, 94}, + }, + { + {98, 94, 97, 93}, + {92, 96, 91, 95}, + {96, 92, 97, 93}, + {90, 94, 91, 95}, + }, + { + {99, 95, 98, 94}, + {93, 97, 92, 96}, + {97, 93, 98, 94}, + {91, 95, 92, 96}, + }, + { + {100, 96, 99, 95}, + {94, 98, 93, 97}, + {98, 94, 99, 95}, + {92, 96, 93, 97}, + }, + { + {101, 97, 100, 96}, + {95, 99, 94, 98}, + {99, 95, 100, 96}, + {93, 97, 94, 98}, + }, + { + {102, 98, 101, 97}, + {96, 100, 95, 99}, + {100, 96, 101, 97}, + {94, 98, 95, 99}, + }, + { + {103, 99, 102, 98}, + {97, 101, 96, 100}, + {101, 97, 102, 98}, + {95, 99, 96, 100}, + }, + { + {104, 100, 103, 99}, + {98, 102, 97, 101}, + {102, 98, 103, 99}, + {96, 100, 97, 101}, + }, + { + {105, 101, 104, 100}, + {99, 103, 98, 102}, + {103, 99, 104, 100}, + {97, 101, 98, 102}, + }, + { + {106, 102, 105, 101}, + {100, 104, 99, 103}, + {104, 100, 105, 101}, + {98, 102, 99, 103}, + }, + { + {107, 103, 106, 102}, + {101, 105, 100, 104}, + {105, 101, 106, 102}, + {99, 103, 100, 104}, + }, + { + {108, 104, 107, 103}, + {102, 106, 101, 105}, + {106, 102, 107, 103}, + {100, 104, 101, 105}, + }, + { + {109, 105, 108, 104}, + {103, 107, 102, 106}, + {107, 103, 108, 104}, + {101, 105, 102, 106}, + }, + { + {110, 106, 109, 105}, + {104, 108, 103, 107}, + {108, 104, 109, 105}, + {102, 106, 103, 107}, + }, + { + {111, 107, 110, 106}, + {105, 109, 104, 108}, + {109, 105, 110, 106}, + {103, 107, 104, 108}, + }, + { + {112, 108, 111, 107}, + {106, 110, 105, 109}, + {110, 106, 111, 107}, + {104, 108, 105, 109}, + }, + { + {113, 109, 112, 108}, + {107, 111, 106, 110}, + {111, 107, 112, 108}, + {105, 109, 106, 110}, + }, + { + {114, 110, 113, 109}, + {108, 112, 107, 111}, + {112, 108, 113, 109}, + {106, 110, 107, 111}, + }, + { + {115, 111, 114, 110}, + {109, 113, 108, 112}, + {113, 109, 114, 110}, + {107, 111, 108, 112}, + }, + { + {116, 112, 115, 111}, + {110, 114, 109, 113}, + {114, 110, 115, 111}, + {108, 112, 109, 113}, + }, + { + {117, 113, 116, 112}, + {111, 115, 110, 114}, + {115, 111, 116, 112}, + {109, 113, 110, 114}, + }, + { + {118, 114, 117, 113}, + {112, 116, 111, 115}, + {116, 112, 117, 113}, + {110, 114, 111, 115}, + }, + { + {119, 115, 118, 114}, + {113, 117, 112, 116}, + {117, 113, 118, 114}, + {111, 115, 112, 116}, + }, + { + {120, 116, 119, 115}, + {114, 118, 113, 117}, + {118, 114, 119, 115}, + {112, 116, 113, 117}, + }, + { + {121, 117, 120, 116}, + {115, 119, 114, 118}, + {119, 115, 120, 116}, + {113, 117, 114, 118}, + }, + { + {122, 118, 121, 117}, + {116, 120, 115, 119}, + {120, 116, 121, 117}, + {114, 118, 115, 119}, + }, + { + {123, 119, 122, 118}, + {117, 121, 116, 120}, + {121, 117, 122, 118}, + {115, 119, 116, 120}, + }, + { + {124, 120, 123, 119}, + {118, 122, 117, 121}, + {122, 118, 123, 119}, + {116, 120, 117, 121}, + }, + { + {125, 121, 124, 120}, + {119, 123, 118, 122}, + {123, 119, 124, 120}, + {117, 121, 118, 122}, + }, + { + {126, 122, 125, 121}, + {120, 124, 119, 123}, + {124, 120, 125, 121}, + {118, 122, 119, 123}, + }, + { + {127, 123, 126, 122}, + {121, 125, 120, 124}, + {125, 121, 126, 122}, + {119, 123, 120, 124}, + }, + { + {128, 124, 127, 123}, + {122, 126, 121, 125}, + {126, 122, 127, 123}, + {120, 124, 121, 125}, + }, + { + {129, 125, 128, 124}, + {123, 127, 122, 126}, + {127, 123, 128, 124}, + {121, 125, 122, 126}, + }, + { + {130, 126, 129, 125}, + {124, 128, 123, 127}, + {128, 124, 129, 125}, + {122, 126, 123, 127}, + }, + { + {131, 127, 130, 126}, + {125, 129, 124, 128}, + {129, 125, 130, 126}, + {123, 127, 124, 128}, + }, + { + {132, 128, 131, 127}, + {126, 130, 125, 129}, + {130, 126, 131, 127}, + {124, 128, 125, 129}, + }, + { + {133, 129, 132, 128}, + {127, 131, 126, 130}, + {131, 127, 132, 128}, + {125, 129, 126, 130}, + }, + { + {134, 130, 133, 129}, + {128, 132, 127, 131}, + {132, 128, 133, 129}, + {126, 130, 127, 131}, + }, + { + {135, 131, 134, 130}, + {129, 133, 128, 132}, + {133, 129, 134, 130}, + {127, 131, 128, 132}, + }, + { + {136, 132, 135, 131}, + {130, 134, 129, 133}, + {134, 130, 135, 131}, + {128, 132, 129, 133}, + }, + { + {137, 133, 136, 132}, + {131, 135, 130, 134}, + {135, 131, 136, 132}, + {129, 133, 130, 134}, + }, + { + {138, 134, 137, 133}, + {132, 136, 131, 135}, + {136, 132, 137, 133}, + {130, 134, 131, 135}, + }, + { + {139, 135, 138, 134}, + {133, 137, 132, 136}, + {137, 133, 138, 134}, + {131, 135, 132, 136}, + }, + { + {140, 136, 139, 135}, + {134, 138, 133, 137}, + {138, 134, 139, 135}, + {132, 136, 133, 137}, + }, + { + {141, 137, 140, 136}, + {135, 139, 134, 138}, + {139, 135, 140, 136}, + {133, 137, 134, 138}, + }, + { + {142, 138, 141, 137}, + {136, 140, 135, 139}, + {140, 136, 141, 137}, + {134, 138, 135, 139}, + }, + { + {143, 139, 142, 138}, + {137, 141, 136, 140}, + {141, 137, 142, 138}, + {135, 139, 136, 140}, + }, + { + {144, 140, 143, 139}, + {138, 142, 137, 141}, + {142, 138, 143, 139}, + {136, 140, 137, 141}, + }, + { + {145, 141, 144, 140}, + {139, 143, 138, 142}, + {143, 139, 144, 140}, + {137, 141, 138, 142}, + }, + { + {146, 142, 145, 141}, + {140, 144, 139, 143}, + {144, 140, 145, 141}, + {138, 142, 139, 143}, + }, + { + {147, 143, 146, 142}, + {141, 145, 140, 144}, + {145, 141, 146, 142}, + {139, 143, 140, 144}, + }, + { + {148, 144, 147, 143}, + {142, 146, 141, 145}, + {146, 142, 147, 143}, + {140, 144, 141, 145}, + }, + { + {149, 145, 148, 144}, + {143, 147, 142, 146}, + {147, 143, 148, 144}, + {141, 145, 142, 146}, + }, + { + {150, 146, 149, 145}, + {144, 148, 143, 147}, + {148, 144, 149, 145}, + {142, 146, 143, 147}, + }, + { + {151, 147, 150, 146}, + {145, 149, 144, 148}, + {149, 145, 150, 146}, + {143, 147, 144, 148}, + }, + { + {152, 148, 151, 147}, + {146, 150, 145, 149}, + {150, 146, 151, 147}, + {144, 148, 145, 149}, + }, + { + {153, 149, 152, 148}, + {147, 151, 146, 150}, + {151, 147, 152, 148}, + {145, 149, 146, 150}, + }, + { + {154, 150, 153, 149}, + {148, 152, 147, 151}, + {152, 148, 153, 149}, + {146, 150, 147, 151}, + }, + { + {155, 151, 154, 150}, + {149, 153, 148, 152}, + {153, 149, 154, 150}, + {147, 151, 148, 152}, + }, + { + {156, 152, 155, 151}, + {150, 154, 149, 153}, + {154, 150, 155, 151}, + {148, 152, 149, 153}, + }, + { + {157, 153, 156, 152}, + {151, 155, 150, 154}, + {155, 151, 156, 152}, + {149, 153, 150, 154}, + }, + { + {158, 154, 157, 153}, + {152, 156, 151, 155}, + {156, 152, 157, 153}, + {150, 154, 151, 155}, + }, + { + {159, 155, 158, 154}, + {153, 157, 152, 156}, + {157, 153, 158, 154}, + {151, 155, 152, 156}, + }, + { + {160, 156, 159, 155}, + {154, 158, 153, 157}, + {158, 154, 159, 155}, + {152, 156, 153, 157}, + }, + { + {161, 157, 160, 156}, + {155, 159, 154, 158}, + {159, 155, 160, 156}, + {153, 157, 154, 158}, + }, + { + {162, 158, 161, 157}, + {156, 160, 155, 159}, + {160, 156, 161, 157}, + {154, 158, 155, 159}, + }, + { + {163, 159, 162, 158}, + {157, 161, 156, 160}, + {161, 157, 162, 158}, + {155, 159, 156, 160}, + }, + { + {164, 160, 163, 159}, + {158, 162, 157, 161}, + {162, 158, 163, 159}, + {156, 160, 157, 161}, + }, + { + {165, 161, 164, 160}, + {159, 163, 158, 162}, + {163, 159, 164, 160}, + {157, 161, 158, 162}, + }, + { + {166, 162, 165, 161}, + {160, 164, 159, 163}, + {164, 160, 165, 161}, + {158, 162, 159, 163}, + }, + { + {167, 163, 166, 162}, + {161, 165, 160, 164}, + {165, 161, 166, 162}, + {159, 163, 160, 164}, + }, + { + {168, 164, 167, 163}, + {162, 166, 161, 165}, + {166, 162, 167, 163}, + {160, 164, 161, 165}, + }, + { + {169, 165, 168, 164}, + {163, 167, 162, 166}, + {167, 163, 168, 164}, + {161, 165, 162, 166}, + }, + { + {170, 166, 169, 165}, + {164, 168, 163, 167}, + {168, 164, 169, 165}, + {162, 166, 163, 167}, + }, + { + {171, 167, 170, 166}, + {165, 169, 164, 168}, + {169, 165, 170, 166}, + {163, 167, 164, 168}, + }, + { + {172, 168, 171, 167}, + {166, 170, 165, 169}, + {170, 166, 171, 167}, + {164, 168, 165, 169}, + }, + { + {173, 169, 172, 168}, + {167, 171, 166, 170}, + {171, 167, 172, 168}, + {165, 169, 166, 170}, + }, + { + {174, 170, 173, 169}, + {168, 172, 167, 171}, + {172, 168, 173, 169}, + {166, 170, 167, 171}, + }, + { + {175, 171, 174, 170}, + {169, 173, 168, 172}, + {173, 169, 174, 170}, + {167, 171, 168, 172}, + }, + { + {176, 172, 175, 171}, + {170, 174, 169, 173}, + {174, 170, 175, 171}, + {168, 172, 169, 173}, + }, + { + {177, 173, 176, 172}, + {171, 175, 170, 174}, + {175, 171, 176, 172}, + {169, 173, 170, 174}, + }, + { + {178, 174, 177, 173}, + {172, 176, 171, 175}, + {176, 172, 177, 173}, + {170, 174, 171, 175}, + }, + { + {179, 175, 178, 174}, + {173, 177, 172, 176}, + {177, 173, 178, 174}, + {171, 175, 172, 176}, + }, + { + {180, 176, 179, 175}, + {174, 178, 173, 177}, + {178, 174, 179, 175}, + {172, 176, 173, 177}, + }, + { + {181, 177, 180, 176}, + {175, 179, 174, 178}, + {179, 175, 180, 176}, + {173, 177, 174, 178}, + }, + { + {182, 178, 181, 177}, + {176, 180, 175, 179}, + {180, 176, 181, 177}, + {174, 178, 175, 179}, + }, + { + {183, 179, 182, 178}, + {177, 181, 176, 180}, + {181, 177, 182, 178}, + {175, 179, 176, 180}, + }, + { + {184, 180, 183, 179}, + {178, 182, 177, 181}, + {182, 178, 183, 179}, + {176, 180, 177, 181}, + }, + { + {185, 181, 184, 180}, + {179, 183, 178, 182}, + {183, 179, 184, 180}, + {177, 181, 178, 182}, + }, + { + {186, 182, 185, 181}, + {180, 184, 179, 183}, + {184, 180, 185, 181}, + {178, 182, 179, 183}, + }, + { + {187, 183, 186, 182}, + {181, 185, 180, 184}, + {185, 181, 186, 182}, + {179, 183, 180, 184}, + }, + { + {188, 184, 187, 183}, + {182, 186, 181, 185}, + {186, 182, 187, 183}, + {180, 184, 181, 185}, + }, + { + {189, 185, 188, 184}, + {183, 187, 182, 186}, + {187, 183, 188, 184}, + {181, 185, 182, 186}, + }, + { + {190, 186, 189, 185}, + {184, 188, 183, 187}, + {188, 184, 189, 185}, + {182, 186, 183, 187}, + }, + { + {191, 187, 190, 186}, + {185, 189, 184, 188}, + {189, 185, 190, 186}, + {183, 187, 184, 188}, + }, + { + {192, 188, 191, 187}, + {186, 190, 185, 189}, + {190, 186, 191, 187}, + {184, 188, 185, 189}, + }, + { + {193, 189, 192, 188}, + {187, 191, 186, 190}, + {191, 187, 192, 188}, + {185, 189, 186, 190}, + }, + { + {194, 190, 193, 189}, + {188, 192, 187, 191}, + {192, 188, 193, 189}, + {186, 190, 187, 191}, + }, + { + {195, 191, 194, 190}, + {189, 193, 188, 192}, + {193, 189, 194, 190}, + {187, 191, 188, 192}, + }, + { + {196, 192, 195, 191}, + {190, 194, 189, 193}, + {194, 190, 195, 191}, + {188, 192, 189, 193}, + }, + { + {197, 193, 196, 192}, + {191, 195, 190, 194}, + {195, 191, 196, 192}, + {189, 193, 190, 194}, + }, + { + {198, 194, 197, 193}, + {192, 196, 191, 195}, + {196, 192, 197, 193}, + {190, 194, 191, 195}, + }, + { + {199, 195, 198, 194}, + {193, 197, 192, 196}, + {197, 193, 198, 194}, + {191, 195, 192, 196}, + }, + { + {200, 196, 199, 195}, + {194, 198, 193, 197}, + {198, 194, 199, 195}, + {192, 196, 193, 197}, + }, + { + {201, 197, 200, 196}, + {195, 199, 194, 198}, + {199, 195, 200, 196}, + {193, 197, 194, 198}, + }, + { + {202, 198, 201, 197}, + {196, 200, 195, 199}, + {200, 196, 201, 197}, + {194, 198, 195, 199}, + }, + { + {203, 199, 202, 198}, + {197, 201, 196, 200}, + {201, 197, 202, 198}, + {195, 199, 196, 200}, + }, + { + {204, 200, 203, 199}, + {198, 202, 197, 201}, + {202, 198, 203, 199}, + {196, 200, 197, 201}, + }, + { + {205, 201, 204, 200}, + {199, 203, 198, 202}, + {203, 199, 204, 200}, + {197, 201, 198, 202}, + }, + { + {206, 202, 205, 201}, + {200, 204, 199, 203}, + {204, 200, 205, 201}, + {198, 202, 199, 203}, + }, + { + {207, 203, 206, 202}, + {201, 205, 200, 204}, + {205, 201, 206, 202}, + {199, 203, 200, 204}, + }, + { + {208, 204, 207, 203}, + {202, 206, 201, 205}, + {206, 202, 207, 203}, + {200, 204, 201, 205}, + }, + { + {209, 205, 208, 204}, + {203, 207, 202, 206}, + {207, 203, 208, 204}, + {201, 205, 202, 206}, + }, + { + {210, 206, 209, 205}, + {204, 208, 203, 207}, + {208, 204, 209, 205}, + {202, 206, 203, 207}, + }, + { + {211, 207, 210, 206}, + {205, 209, 204, 208}, + {209, 205, 210, 206}, + {203, 207, 204, 208}, + }, + { + {212, 208, 211, 207}, + {206, 210, 205, 209}, + {210, 206, 211, 207}, + {204, 208, 205, 209}, + }, + { + {213, 209, 212, 208}, + {207, 211, 206, 210}, + {211, 207, 212, 208}, + {205, 209, 206, 210}, + }, + { + {214, 210, 213, 209}, + {208, 212, 207, 211}, + {212, 208, 213, 209}, + {206, 210, 207, 211}, + }, + { + {215, 211, 214, 210}, + {209, 213, 208, 212}, + {213, 209, 214, 210}, + {207, 211, 208, 212}, + }, + { + {216, 212, 215, 211}, + {210, 214, 209, 213}, + {214, 210, 215, 211}, + {208, 212, 209, 213}, + }, + { + {217, 213, 216, 212}, + {211, 215, 210, 214}, + {215, 211, 216, 212}, + {209, 213, 210, 214}, + }, + { + {218, 214, 217, 213}, + {212, 216, 211, 215}, + {216, 212, 217, 213}, + {210, 214, 211, 215}, + }, + { + {219, 215, 218, 214}, + {213, 217, 212, 216}, + {217, 213, 218, 214}, + {211, 215, 212, 216}, + }, + { + {220, 216, 219, 215}, + {214, 218, 213, 217}, + {218, 214, 219, 215}, + {212, 216, 213, 217}, + }, + { + {221, 217, 220, 216}, + {215, 219, 214, 218}, + {219, 215, 220, 216}, + {213, 217, 214, 218}, + }, + { + {222, 218, 221, 217}, + {216, 220, 215, 219}, + {220, 216, 221, 217}, + {214, 218, 215, 219}, + }, + { + {223, 219, 222, 218}, + {217, 221, 216, 220}, + {221, 217, 222, 218}, + {215, 219, 216, 220}, + }, + { + {224, 220, 223, 219}, + {218, 222, 217, 221}, + {222, 218, 223, 219}, + {216, 220, 217, 221}, + }, + { + {225, 221, 224, 220}, + {219, 223, 218, 222}, + {223, 219, 224, 220}, + {217, 221, 218, 222}, + }, + { + {226, 222, 225, 221}, + {220, 224, 219, 223}, + {224, 220, 225, 221}, + {218, 222, 219, 223}, + }, + { + {227, 223, 226, 222}, + {221, 225, 220, 224}, + {225, 221, 226, 222}, + {219, 223, 220, 224}, + }, + { + {228, 224, 227, 223}, + {222, 226, 221, 225}, + {226, 222, 227, 223}, + {220, 224, 221, 225}, + }, + { + {229, 225, 228, 224}, + {223, 227, 222, 226}, + {227, 223, 228, 224}, + {221, 225, 222, 226}, + }, + { + {230, 226, 229, 225}, + {224, 228, 223, 227}, + {228, 224, 229, 225}, + {222, 226, 223, 227}, + }, + { + {231, 227, 230, 226}, + {225, 229, 224, 228}, + {229, 225, 230, 226}, + {223, 227, 224, 228}, + }, + { + {232, 228, 231, 227}, + {226, 230, 225, 229}, + {230, 226, 231, 227}, + {224, 228, 225, 229}, + }, + { + {233, 229, 232, 228}, + {227, 231, 226, 230}, + {231, 227, 232, 228}, + {225, 229, 226, 230}, + }, + { + {234, 230, 233, 229}, + {228, 232, 227, 231}, + {232, 228, 233, 229}, + {226, 230, 227, 231}, + }, + { + {235, 231, 234, 230}, + {229, 233, 228, 232}, + {233, 229, 234, 230}, + {227, 231, 228, 232}, + }, + { + {236, 232, 235, 231}, + {230, 234, 229, 233}, + {234, 230, 235, 231}, + {228, 232, 229, 233}, + }, + { + {237, 233, 236, 232}, + {231, 235, 230, 234}, + {235, 231, 236, 232}, + {229, 233, 230, 234}, + }, + { + {238, 234, 237, 233}, + {232, 236, 231, 235}, + {236, 232, 237, 233}, + {230, 234, 231, 235}, + }, + { + {239, 235, 238, 234}, + {233, 237, 232, 236}, + {237, 233, 238, 234}, + {231, 235, 232, 236}, + }, + { + {240, 236, 239, 235}, + {234, 238, 233, 237}, + {238, 234, 239, 235}, + {232, 236, 233, 237}, + }, + { + {241, 237, 240, 236}, + {235, 239, 234, 238}, + {239, 235, 240, 236}, + {233, 237, 234, 238}, + }, + { + {242, 238, 241, 237}, + {236, 240, 235, 239}, + {240, 236, 241, 237}, + {234, 238, 235, 239}, + }, + { + {243, 239, 242, 238}, + {237, 241, 236, 240}, + {241, 237, 242, 238}, + {235, 239, 236, 240}, + }, + { + {244, 240, 243, 239}, + {238, 242, 237, 241}, + {242, 238, 243, 239}, + {236, 240, 237, 241}, + }, + { + {245, 241, 244, 240}, + {239, 243, 238, 242}, + {243, 239, 244, 240}, + {237, 241, 238, 242}, + }, + { + {246, 242, 245, 241}, + {240, 244, 239, 243}, + {244, 240, 245, 241}, + {238, 242, 239, 243}, + }, + { + {247, 243, 246, 242}, + {241, 245, 240, 244}, + {245, 241, 246, 242}, + {239, 243, 240, 244}, + }, + { + {248, 244, 247, 243}, + {242, 246, 241, 245}, + {246, 242, 247, 243}, + {240, 244, 241, 245}, + }, + { + {249, 245, 248, 244}, + {243, 247, 242, 246}, + {247, 243, 248, 244}, + {241, 245, 242, 246}, + }, + { + {250, 246, 249, 245}, + {244, 248, 243, 247}, + {248, 244, 249, 245}, + {242, 246, 243, 247}, + }, + { + {251, 247, 250, 246}, + {245, 249, 244, 248}, + {249, 245, 250, 246}, + {243, 247, 244, 248}, + }, + { + {252, 248, 251, 247}, + {246, 250, 245, 249}, + {250, 246, 251, 247}, + {244, 248, 245, 249}, + }, + { + {253, 249, 252, 248}, + {247, 251, 246, 250}, + {251, 247, 252, 248}, + {245, 249, 246, 250}, + }, + { + {254, 250, 253, 249}, + {248, 252, 247, 251}, + {252, 248, 253, 249}, + {246, 250, 247, 251}, + }, + { + {255, 251, 254, 250}, + {249, 253, 248, 252}, + {253, 249, 254, 250}, + {247, 251, 248, 252}, + }, + { + {255, 252, 255, 251}, + {250, 254, 249, 253}, + {254, 250, 255, 251}, + {248, 252, 249, 253}, + }, + { + {255, 253, 255, 252}, + {251, 255, 250, 254}, + {255, 251, 255, 252}, + {249, 253, 250, 254}, + }, + { + {255, 254, 255, 253}, + {252, 255, 251, 255}, + {255, 252, 255, 253}, + {250, 254, 251, 255}, + }, + { + {255, 255, 255, 254}, + {253, 255, 252, 255}, + {255, 253, 255, 254}, + {251, 255, 252, 255}, + }, + { + {255, 255, 255, 255}, + {254, 255, 253, 255}, + {255, 254, 255, 255}, + {252, 255, 253, 255}, + }, +}; + +static const uint8_t dithersub_g[256][4][4] = +{ + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {5, 3, 4, 2}, + {2, 4, 1, 3}, + {4, 2, 4, 2}, + {1, 3, 1, 3}, + }, + { + {6, 4, 5, 3}, + {3, 5, 2, 4}, + {5, 3, 5, 3}, + {2, 4, 2, 4}, + }, + { + {7, 5, 6, 4}, + {4, 6, 3, 5}, + {6, 4, 6, 4}, + {3, 5, 3, 5}, + }, + { + {8, 6, 7, 5}, + {5, 7, 4, 6}, + {7, 5, 7, 5}, + {4, 6, 4, 6}, + }, + { + {9, 7, 8, 6}, + {6, 8, 5, 7}, + {8, 6, 8, 6}, + {5, 7, 5, 7}, + }, + { + {10, 8, 9, 7}, + {7, 9, 6, 8}, + {9, 7, 9, 7}, + {6, 8, 6, 8}, + }, + { + {11, 9, 10, 8}, + {8, 10, 7, 9}, + {10, 8, 10, 8}, + {7, 9, 7, 9}, + }, + { + {12, 10, 11, 9}, + {9, 11, 8, 10}, + {11, 9, 11, 9}, + {8, 10, 8, 10}, + }, + { + {13, 11, 12, 10}, + {10, 12, 9, 11}, + {12, 10, 12, 10}, + {9, 11, 9, 11}, + }, + { + {14, 12, 13, 11}, + {11, 13, 10, 12}, + {13, 11, 13, 11}, + {10, 12, 10, 12}, + }, + { + {15, 13, 14, 12}, + {12, 14, 11, 13}, + {14, 12, 14, 12}, + {11, 13, 11, 13}, + }, + { + {16, 14, 15, 13}, + {13, 15, 12, 14}, + {15, 13, 15, 13}, + {12, 14, 12, 14}, + }, + { + {17, 15, 16, 14}, + {14, 16, 13, 15}, + {16, 14, 16, 14}, + {13, 15, 13, 15}, + }, + { + {18, 16, 17, 15}, + {15, 17, 14, 16}, + {17, 15, 17, 15}, + {14, 16, 14, 16}, + }, + { + {19, 17, 18, 16}, + {16, 18, 15, 17}, + {18, 16, 18, 16}, + {15, 17, 15, 17}, + }, + { + {20, 18, 19, 17}, + {17, 19, 16, 18}, + {19, 17, 19, 17}, + {16, 18, 16, 18}, + }, + { + {21, 19, 20, 18}, + {18, 20, 17, 19}, + {20, 18, 20, 18}, + {17, 19, 17, 19}, + }, + { + {22, 20, 21, 19}, + {19, 21, 18, 20}, + {21, 19, 21, 19}, + {18, 20, 18, 20}, + }, + { + {23, 21, 22, 20}, + {20, 22, 19, 21}, + {22, 20, 22, 20}, + {19, 21, 19, 21}, + }, + { + {24, 22, 23, 21}, + {21, 23, 20, 22}, + {23, 21, 23, 21}, + {20, 22, 20, 22}, + }, + { + {25, 23, 24, 22}, + {22, 24, 21, 23}, + {24, 22, 24, 22}, + {21, 23, 21, 23}, + }, + { + {26, 24, 25, 23}, + {23, 25, 22, 24}, + {25, 23, 25, 23}, + {22, 24, 22, 24}, + }, + { + {27, 25, 26, 24}, + {24, 26, 23, 25}, + {26, 24, 26, 24}, + {23, 25, 23, 25}, + }, + { + {28, 26, 27, 25}, + {25, 27, 24, 26}, + {27, 25, 27, 25}, + {24, 26, 24, 26}, + }, + { + {29, 27, 28, 26}, + {26, 28, 25, 27}, + {28, 26, 28, 26}, + {25, 27, 25, 27}, + }, + { + {30, 28, 29, 27}, + {27, 29, 26, 28}, + {29, 27, 29, 27}, + {26, 28, 26, 28}, + }, + { + {31, 29, 30, 28}, + {28, 30, 27, 29}, + {30, 28, 30, 28}, + {27, 29, 27, 29}, + }, + { + {32, 30, 31, 29}, + {29, 31, 28, 30}, + {31, 29, 31, 29}, + {28, 30, 28, 30}, + }, + { + {33, 31, 32, 30}, + {30, 32, 29, 31}, + {32, 30, 32, 30}, + {29, 31, 29, 31}, + }, + { + {34, 32, 33, 31}, + {31, 33, 30, 32}, + {33, 31, 33, 31}, + {30, 32, 30, 32}, + }, + { + {35, 33, 34, 32}, + {32, 34, 31, 33}, + {34, 32, 34, 32}, + {31, 33, 31, 33}, + }, + { + {36, 34, 35, 33}, + {33, 35, 32, 34}, + {35, 33, 35, 33}, + {32, 34, 32, 34}, + }, + { + {37, 35, 36, 34}, + {34, 36, 33, 35}, + {36, 34, 36, 34}, + {33, 35, 33, 35}, + }, + { + {38, 36, 37, 35}, + {35, 37, 34, 36}, + {37, 35, 37, 35}, + {34, 36, 34, 36}, + }, + { + {39, 37, 38, 36}, + {36, 38, 35, 37}, + {38, 36, 38, 36}, + {35, 37, 35, 37}, + }, + { + {40, 38, 39, 37}, + {37, 39, 36, 38}, + {39, 37, 39, 37}, + {36, 38, 36, 38}, + }, + { + {41, 39, 40, 38}, + {38, 40, 37, 39}, + {40, 38, 40, 38}, + {37, 39, 37, 39}, + }, + { + {42, 40, 41, 39}, + {39, 41, 38, 40}, + {41, 39, 41, 39}, + {38, 40, 38, 40}, + }, + { + {43, 41, 42, 40}, + {40, 42, 39, 41}, + {42, 40, 42, 40}, + {39, 41, 39, 41}, + }, + { + {44, 42, 43, 41}, + {41, 43, 40, 42}, + {43, 41, 43, 41}, + {40, 42, 40, 42}, + }, + { + {45, 43, 44, 42}, + {42, 44, 41, 43}, + {44, 42, 44, 42}, + {41, 43, 41, 43}, + }, + { + {46, 44, 45, 43}, + {43, 45, 42, 44}, + {45, 43, 45, 43}, + {42, 44, 42, 44}, + }, + { + {47, 45, 46, 44}, + {44, 46, 43, 45}, + {46, 44, 46, 44}, + {43, 45, 43, 45}, + }, + { + {48, 46, 47, 45}, + {45, 47, 44, 46}, + {47, 45, 47, 45}, + {44, 46, 44, 46}, + }, + { + {49, 47, 48, 46}, + {46, 48, 45, 47}, + {48, 46, 48, 46}, + {45, 47, 45, 47}, + }, + { + {50, 48, 49, 47}, + {47, 49, 46, 48}, + {49, 47, 49, 47}, + {46, 48, 46, 48}, + }, + { + {51, 49, 50, 48}, + {48, 50, 47, 49}, + {50, 48, 50, 48}, + {47, 49, 47, 49}, + }, + { + {52, 50, 51, 49}, + {49, 51, 48, 50}, + {51, 49, 51, 49}, + {48, 50, 48, 50}, + }, + { + {53, 51, 52, 50}, + {50, 52, 49, 51}, + {52, 50, 52, 50}, + {49, 51, 49, 51}, + }, + { + {54, 52, 53, 51}, + {51, 53, 50, 52}, + {53, 51, 53, 51}, + {50, 52, 50, 52}, + }, + { + {55, 53, 54, 52}, + {52, 54, 51, 53}, + {54, 52, 54, 52}, + {51, 53, 51, 53}, + }, + { + {56, 54, 55, 53}, + {53, 55, 52, 54}, + {55, 53, 55, 53}, + {52, 54, 52, 54}, + }, + { + {57, 55, 56, 54}, + {54, 56, 53, 55}, + {56, 54, 56, 54}, + {53, 55, 53, 55}, + }, + { + {58, 56, 57, 55}, + {55, 57, 54, 56}, + {57, 55, 57, 55}, + {54, 56, 54, 56}, + }, + { + {59, 57, 58, 56}, + {56, 58, 55, 57}, + {58, 56, 58, 56}, + {55, 57, 55, 57}, + }, + { + {60, 58, 59, 57}, + {57, 59, 56, 58}, + {59, 57, 59, 57}, + {56, 58, 56, 58}, + }, + { + {61, 59, 60, 58}, + {58, 60, 57, 59}, + {60, 58, 60, 58}, + {57, 59, 57, 59}, + }, + { + {62, 60, 61, 59}, + {59, 61, 58, 60}, + {61, 59, 61, 59}, + {58, 60, 58, 60}, + }, + { + {63, 61, 62, 60}, + {60, 62, 59, 61}, + {62, 60, 62, 60}, + {59, 61, 59, 61}, + }, + { + {64, 62, 63, 61}, + {61, 63, 60, 62}, + {63, 61, 63, 61}, + {60, 62, 60, 62}, + }, + { + {65, 63, 64, 62}, + {62, 64, 61, 63}, + {64, 62, 64, 62}, + {61, 63, 61, 63}, + }, + { + {66, 64, 65, 63}, + {63, 65, 62, 64}, + {65, 63, 65, 63}, + {62, 64, 62, 64}, + }, + { + {67, 65, 66, 64}, + {64, 66, 63, 65}, + {66, 64, 66, 64}, + {63, 65, 63, 65}, + }, + { + {68, 66, 67, 65}, + {65, 67, 64, 66}, + {67, 65, 67, 65}, + {64, 66, 64, 66}, + }, + { + {69, 67, 68, 66}, + {66, 68, 65, 67}, + {68, 66, 68, 66}, + {65, 67, 65, 67}, + }, + { + {70, 68, 69, 67}, + {67, 69, 66, 68}, + {69, 67, 69, 67}, + {66, 68, 66, 68}, + }, + { + {71, 69, 70, 68}, + {68, 70, 67, 69}, + {70, 68, 70, 68}, + {67, 69, 67, 69}, + }, + { + {72, 70, 71, 69}, + {69, 71, 68, 70}, + {71, 69, 71, 69}, + {68, 70, 68, 70}, + }, + { + {73, 71, 72, 70}, + {70, 72, 69, 71}, + {72, 70, 72, 70}, + {69, 71, 69, 71}, + }, + { + {74, 72, 73, 71}, + {71, 73, 70, 72}, + {73, 71, 73, 71}, + {70, 72, 70, 72}, + }, + { + {75, 73, 74, 72}, + {72, 74, 71, 73}, + {74, 72, 74, 72}, + {71, 73, 71, 73}, + }, + { + {76, 74, 75, 73}, + {73, 75, 72, 74}, + {75, 73, 75, 73}, + {72, 74, 72, 74}, + }, + { + {77, 75, 76, 74}, + {74, 76, 73, 75}, + {76, 74, 76, 74}, + {73, 75, 73, 75}, + }, + { + {78, 76, 77, 75}, + {75, 77, 74, 76}, + {77, 75, 77, 75}, + {74, 76, 74, 76}, + }, + { + {79, 77, 78, 76}, + {76, 78, 75, 77}, + {78, 76, 78, 76}, + {75, 77, 75, 77}, + }, + { + {80, 78, 79, 77}, + {77, 79, 76, 78}, + {79, 77, 79, 77}, + {76, 78, 76, 78}, + }, + { + {81, 79, 80, 78}, + {78, 80, 77, 79}, + {80, 78, 80, 78}, + {77, 79, 77, 79}, + }, + { + {82, 80, 81, 79}, + {79, 81, 78, 80}, + {81, 79, 81, 79}, + {78, 80, 78, 80}, + }, + { + {83, 81, 82, 80}, + {80, 82, 79, 81}, + {82, 80, 82, 80}, + {79, 81, 79, 81}, + }, + { + {84, 82, 83, 81}, + {81, 83, 80, 82}, + {83, 81, 83, 81}, + {80, 82, 80, 82}, + }, + { + {85, 83, 84, 82}, + {82, 84, 81, 83}, + {84, 82, 84, 82}, + {81, 83, 81, 83}, + }, + { + {86, 84, 85, 83}, + {83, 85, 82, 84}, + {85, 83, 85, 83}, + {82, 84, 82, 84}, + }, + { + {87, 85, 86, 84}, + {84, 86, 83, 85}, + {86, 84, 86, 84}, + {83, 85, 83, 85}, + }, + { + {88, 86, 87, 85}, + {85, 87, 84, 86}, + {87, 85, 87, 85}, + {84, 86, 84, 86}, + }, + { + {89, 87, 88, 86}, + {86, 88, 85, 87}, + {88, 86, 88, 86}, + {85, 87, 85, 87}, + }, + { + {90, 88, 89, 87}, + {87, 89, 86, 88}, + {89, 87, 89, 87}, + {86, 88, 86, 88}, + }, + { + {91, 89, 90, 88}, + {88, 90, 87, 89}, + {90, 88, 90, 88}, + {87, 89, 87, 89}, + }, + { + {92, 90, 91, 89}, + {89, 91, 88, 90}, + {91, 89, 91, 89}, + {88, 90, 88, 90}, + }, + { + {93, 91, 92, 90}, + {90, 92, 89, 91}, + {92, 90, 92, 90}, + {89, 91, 89, 91}, + }, + { + {94, 92, 93, 91}, + {91, 93, 90, 92}, + {93, 91, 93, 91}, + {90, 92, 90, 92}, + }, + { + {95, 93, 94, 92}, + {92, 94, 91, 93}, + {94, 92, 94, 92}, + {91, 93, 91, 93}, + }, + { + {96, 94, 95, 93}, + {93, 95, 92, 94}, + {95, 93, 95, 93}, + {92, 94, 92, 94}, + }, + { + {97, 95, 96, 94}, + {94, 96, 93, 95}, + {96, 94, 96, 94}, + {93, 95, 93, 95}, + }, + { + {98, 96, 97, 95}, + {95, 97, 94, 96}, + {97, 95, 97, 95}, + {94, 96, 94, 96}, + }, + { + {99, 97, 98, 96}, + {96, 98, 95, 97}, + {98, 96, 98, 96}, + {95, 97, 95, 97}, + }, + { + {100, 98, 99, 97}, + {97, 99, 96, 98}, + {99, 97, 99, 97}, + {96, 98, 96, 98}, + }, + { + {101, 99, 100, 98}, + {98, 100, 97, 99}, + {100, 98, 100, 98}, + {97, 99, 97, 99}, + }, + { + {102, 100, 101, 99}, + {99, 101, 98, 100}, + {101, 99, 101, 99}, + {98, 100, 98, 100}, + }, + { + {103, 101, 102, 100}, + {100, 102, 99, 101}, + {102, 100, 102, 100}, + {99, 101, 99, 101}, + }, + { + {104, 102, 103, 101}, + {101, 103, 100, 102}, + {103, 101, 103, 101}, + {100, 102, 100, 102}, + }, + { + {105, 103, 104, 102}, + {102, 104, 101, 103}, + {104, 102, 104, 102}, + {101, 103, 101, 103}, + }, + { + {106, 104, 105, 103}, + {103, 105, 102, 104}, + {105, 103, 105, 103}, + {102, 104, 102, 104}, + }, + { + {107, 105, 106, 104}, + {104, 106, 103, 105}, + {106, 104, 106, 104}, + {103, 105, 103, 105}, + }, + { + {108, 106, 107, 105}, + {105, 107, 104, 106}, + {107, 105, 107, 105}, + {104, 106, 104, 106}, + }, + { + {109, 107, 108, 106}, + {106, 108, 105, 107}, + {108, 106, 108, 106}, + {105, 107, 105, 107}, + }, + { + {110, 108, 109, 107}, + {107, 109, 106, 108}, + {109, 107, 109, 107}, + {106, 108, 106, 108}, + }, + { + {111, 109, 110, 108}, + {108, 110, 107, 109}, + {110, 108, 110, 108}, + {107, 109, 107, 109}, + }, + { + {112, 110, 111, 109}, + {109, 111, 108, 110}, + {111, 109, 111, 109}, + {108, 110, 108, 110}, + }, + { + {113, 111, 112, 110}, + {110, 112, 109, 111}, + {112, 110, 112, 110}, + {109, 111, 109, 111}, + }, + { + {114, 112, 113, 111}, + {111, 113, 110, 112}, + {113, 111, 113, 111}, + {110, 112, 110, 112}, + }, + { + {115, 113, 114, 112}, + {112, 114, 111, 113}, + {114, 112, 114, 112}, + {111, 113, 111, 113}, + }, + { + {116, 114, 115, 113}, + {113, 115, 112, 114}, + {115, 113, 115, 113}, + {112, 114, 112, 114}, + }, + { + {117, 115, 116, 114}, + {114, 116, 113, 115}, + {116, 114, 116, 114}, + {113, 115, 113, 115}, + }, + { + {118, 116, 117, 115}, + {115, 117, 114, 116}, + {117, 115, 117, 115}, + {114, 116, 114, 116}, + }, + { + {119, 117, 118, 116}, + {116, 118, 115, 117}, + {118, 116, 118, 116}, + {115, 117, 115, 117}, + }, + { + {120, 118, 119, 117}, + {117, 119, 116, 118}, + {119, 117, 119, 117}, + {116, 118, 116, 118}, + }, + { + {121, 119, 120, 118}, + {118, 120, 117, 119}, + {120, 118, 120, 118}, + {117, 119, 117, 119}, + }, + { + {122, 120, 121, 119}, + {119, 121, 118, 120}, + {121, 119, 121, 119}, + {118, 120, 118, 120}, + }, + { + {123, 121, 122, 120}, + {120, 122, 119, 121}, + {122, 120, 122, 120}, + {119, 121, 119, 121}, + }, + { + {124, 122, 123, 121}, + {121, 123, 120, 122}, + {123, 121, 123, 121}, + {120, 122, 120, 122}, + }, + { + {125, 123, 124, 122}, + {122, 124, 121, 123}, + {124, 122, 124, 122}, + {121, 123, 121, 123}, + }, + { + {126, 124, 125, 123}, + {123, 125, 122, 124}, + {125, 123, 125, 123}, + {122, 124, 122, 124}, + }, + { + {127, 125, 126, 124}, + {124, 126, 123, 125}, + {126, 124, 126, 124}, + {123, 125, 123, 125}, + }, + { + {128, 126, 127, 125}, + {125, 127, 124, 126}, + {127, 125, 127, 125}, + {124, 126, 124, 126}, + }, + { + {129, 127, 128, 126}, + {126, 128, 125, 127}, + {128, 126, 128, 126}, + {125, 127, 125, 127}, + }, + { + {130, 128, 129, 127}, + {127, 129, 126, 128}, + {129, 127, 129, 127}, + {126, 128, 126, 128}, + }, + { + {131, 129, 130, 128}, + {128, 130, 127, 129}, + {130, 128, 130, 128}, + {127, 129, 127, 129}, + }, + { + {132, 130, 131, 129}, + {129, 131, 128, 130}, + {131, 129, 131, 129}, + {128, 130, 128, 130}, + }, + { + {133, 131, 132, 130}, + {130, 132, 129, 131}, + {132, 130, 132, 130}, + {129, 131, 129, 131}, + }, + { + {134, 132, 133, 131}, + {131, 133, 130, 132}, + {133, 131, 133, 131}, + {130, 132, 130, 132}, + }, + { + {135, 133, 134, 132}, + {132, 134, 131, 133}, + {134, 132, 134, 132}, + {131, 133, 131, 133}, + }, + { + {136, 134, 135, 133}, + {133, 135, 132, 134}, + {135, 133, 135, 133}, + {132, 134, 132, 134}, + }, + { + {137, 135, 136, 134}, + {134, 136, 133, 135}, + {136, 134, 136, 134}, + {133, 135, 133, 135}, + }, + { + {138, 136, 137, 135}, + {135, 137, 134, 136}, + {137, 135, 137, 135}, + {134, 136, 134, 136}, + }, + { + {139, 137, 138, 136}, + {136, 138, 135, 137}, + {138, 136, 138, 136}, + {135, 137, 135, 137}, + }, + { + {140, 138, 139, 137}, + {137, 139, 136, 138}, + {139, 137, 139, 137}, + {136, 138, 136, 138}, + }, + { + {141, 139, 140, 138}, + {138, 140, 137, 139}, + {140, 138, 140, 138}, + {137, 139, 137, 139}, + }, + { + {142, 140, 141, 139}, + {139, 141, 138, 140}, + {141, 139, 141, 139}, + {138, 140, 138, 140}, + }, + { + {143, 141, 142, 140}, + {140, 142, 139, 141}, + {142, 140, 142, 140}, + {139, 141, 139, 141}, + }, + { + {144, 142, 143, 141}, + {141, 143, 140, 142}, + {143, 141, 143, 141}, + {140, 142, 140, 142}, + }, + { + {145, 143, 144, 142}, + {142, 144, 141, 143}, + {144, 142, 144, 142}, + {141, 143, 141, 143}, + }, + { + {146, 144, 145, 143}, + {143, 145, 142, 144}, + {145, 143, 145, 143}, + {142, 144, 142, 144}, + }, + { + {147, 145, 146, 144}, + {144, 146, 143, 145}, + {146, 144, 146, 144}, + {143, 145, 143, 145}, + }, + { + {148, 146, 147, 145}, + {145, 147, 144, 146}, + {147, 145, 147, 145}, + {144, 146, 144, 146}, + }, + { + {149, 147, 148, 146}, + {146, 148, 145, 147}, + {148, 146, 148, 146}, + {145, 147, 145, 147}, + }, + { + {150, 148, 149, 147}, + {147, 149, 146, 148}, + {149, 147, 149, 147}, + {146, 148, 146, 148}, + }, + { + {151, 149, 150, 148}, + {148, 150, 147, 149}, + {150, 148, 150, 148}, + {147, 149, 147, 149}, + }, + { + {152, 150, 151, 149}, + {149, 151, 148, 150}, + {151, 149, 151, 149}, + {148, 150, 148, 150}, + }, + { + {153, 151, 152, 150}, + {150, 152, 149, 151}, + {152, 150, 152, 150}, + {149, 151, 149, 151}, + }, + { + {154, 152, 153, 151}, + {151, 153, 150, 152}, + {153, 151, 153, 151}, + {150, 152, 150, 152}, + }, + { + {155, 153, 154, 152}, + {152, 154, 151, 153}, + {154, 152, 154, 152}, + {151, 153, 151, 153}, + }, + { + {156, 154, 155, 153}, + {153, 155, 152, 154}, + {155, 153, 155, 153}, + {152, 154, 152, 154}, + }, + { + {157, 155, 156, 154}, + {154, 156, 153, 155}, + {156, 154, 156, 154}, + {153, 155, 153, 155}, + }, + { + {158, 156, 157, 155}, + {155, 157, 154, 156}, + {157, 155, 157, 155}, + {154, 156, 154, 156}, + }, + { + {159, 157, 158, 156}, + {156, 158, 155, 157}, + {158, 156, 158, 156}, + {155, 157, 155, 157}, + }, + { + {160, 158, 159, 157}, + {157, 159, 156, 158}, + {159, 157, 159, 157}, + {156, 158, 156, 158}, + }, + { + {161, 159, 160, 158}, + {158, 160, 157, 159}, + {160, 158, 160, 158}, + {157, 159, 157, 159}, + }, + { + {162, 160, 161, 159}, + {159, 161, 158, 160}, + {161, 159, 161, 159}, + {158, 160, 158, 160}, + }, + { + {163, 161, 162, 160}, + {160, 162, 159, 161}, + {162, 160, 162, 160}, + {159, 161, 159, 161}, + }, + { + {164, 162, 163, 161}, + {161, 163, 160, 162}, + {163, 161, 163, 161}, + {160, 162, 160, 162}, + }, + { + {165, 163, 164, 162}, + {162, 164, 161, 163}, + {164, 162, 164, 162}, + {161, 163, 161, 163}, + }, + { + {166, 164, 165, 163}, + {163, 165, 162, 164}, + {165, 163, 165, 163}, + {162, 164, 162, 164}, + }, + { + {167, 165, 166, 164}, + {164, 166, 163, 165}, + {166, 164, 166, 164}, + {163, 165, 163, 165}, + }, + { + {168, 166, 167, 165}, + {165, 167, 164, 166}, + {167, 165, 167, 165}, + {164, 166, 164, 166}, + }, + { + {169, 167, 168, 166}, + {166, 168, 165, 167}, + {168, 166, 168, 166}, + {165, 167, 165, 167}, + }, + { + {170, 168, 169, 167}, + {167, 169, 166, 168}, + {169, 167, 169, 167}, + {166, 168, 166, 168}, + }, + { + {171, 169, 170, 168}, + {168, 170, 167, 169}, + {170, 168, 170, 168}, + {167, 169, 167, 169}, + }, + { + {172, 170, 171, 169}, + {169, 171, 168, 170}, + {171, 169, 171, 169}, + {168, 170, 168, 170}, + }, + { + {173, 171, 172, 170}, + {170, 172, 169, 171}, + {172, 170, 172, 170}, + {169, 171, 169, 171}, + }, + { + {174, 172, 173, 171}, + {171, 173, 170, 172}, + {173, 171, 173, 171}, + {170, 172, 170, 172}, + }, + { + {175, 173, 174, 172}, + {172, 174, 171, 173}, + {174, 172, 174, 172}, + {171, 173, 171, 173}, + }, + { + {176, 174, 175, 173}, + {173, 175, 172, 174}, + {175, 173, 175, 173}, + {172, 174, 172, 174}, + }, + { + {177, 175, 176, 174}, + {174, 176, 173, 175}, + {176, 174, 176, 174}, + {173, 175, 173, 175}, + }, + { + {178, 176, 177, 175}, + {175, 177, 174, 176}, + {177, 175, 177, 175}, + {174, 176, 174, 176}, + }, + { + {179, 177, 178, 176}, + {176, 178, 175, 177}, + {178, 176, 178, 176}, + {175, 177, 175, 177}, + }, + { + {180, 178, 179, 177}, + {177, 179, 176, 178}, + {179, 177, 179, 177}, + {176, 178, 176, 178}, + }, + { + {181, 179, 180, 178}, + {178, 180, 177, 179}, + {180, 178, 180, 178}, + {177, 179, 177, 179}, + }, + { + {182, 180, 181, 179}, + {179, 181, 178, 180}, + {181, 179, 181, 179}, + {178, 180, 178, 180}, + }, + { + {183, 181, 182, 180}, + {180, 182, 179, 181}, + {182, 180, 182, 180}, + {179, 181, 179, 181}, + }, + { + {184, 182, 183, 181}, + {181, 183, 180, 182}, + {183, 181, 183, 181}, + {180, 182, 180, 182}, + }, + { + {185, 183, 184, 182}, + {182, 184, 181, 183}, + {184, 182, 184, 182}, + {181, 183, 181, 183}, + }, + { + {186, 184, 185, 183}, + {183, 185, 182, 184}, + {185, 183, 185, 183}, + {182, 184, 182, 184}, + }, + { + {187, 185, 186, 184}, + {184, 186, 183, 185}, + {186, 184, 186, 184}, + {183, 185, 183, 185}, + }, + { + {188, 186, 187, 185}, + {185, 187, 184, 186}, + {187, 185, 187, 185}, + {184, 186, 184, 186}, + }, + { + {189, 187, 188, 186}, + {186, 188, 185, 187}, + {188, 186, 188, 186}, + {185, 187, 185, 187}, + }, + { + {190, 188, 189, 187}, + {187, 189, 186, 188}, + {189, 187, 189, 187}, + {186, 188, 186, 188}, + }, + { + {191, 189, 190, 188}, + {188, 190, 187, 189}, + {190, 188, 190, 188}, + {187, 189, 187, 189}, + }, + { + {192, 190, 191, 189}, + {189, 191, 188, 190}, + {191, 189, 191, 189}, + {188, 190, 188, 190}, + }, + { + {193, 191, 192, 190}, + {190, 192, 189, 191}, + {192, 190, 192, 190}, + {189, 191, 189, 191}, + }, + { + {194, 192, 193, 191}, + {191, 193, 190, 192}, + {193, 191, 193, 191}, + {190, 192, 190, 192}, + }, + { + {195, 193, 194, 192}, + {192, 194, 191, 193}, + {194, 192, 194, 192}, + {191, 193, 191, 193}, + }, + { + {196, 194, 195, 193}, + {193, 195, 192, 194}, + {195, 193, 195, 193}, + {192, 194, 192, 194}, + }, + { + {197, 195, 196, 194}, + {194, 196, 193, 195}, + {196, 194, 196, 194}, + {193, 195, 193, 195}, + }, + { + {198, 196, 197, 195}, + {195, 197, 194, 196}, + {197, 195, 197, 195}, + {194, 196, 194, 196}, + }, + { + {199, 197, 198, 196}, + {196, 198, 195, 197}, + {198, 196, 198, 196}, + {195, 197, 195, 197}, + }, + { + {200, 198, 199, 197}, + {197, 199, 196, 198}, + {199, 197, 199, 197}, + {196, 198, 196, 198}, + }, + { + {201, 199, 200, 198}, + {198, 200, 197, 199}, + {200, 198, 200, 198}, + {197, 199, 197, 199}, + }, + { + {202, 200, 201, 199}, + {199, 201, 198, 200}, + {201, 199, 201, 199}, + {198, 200, 198, 200}, + }, + { + {203, 201, 202, 200}, + {200, 202, 199, 201}, + {202, 200, 202, 200}, + {199, 201, 199, 201}, + }, + { + {204, 202, 203, 201}, + {201, 203, 200, 202}, + {203, 201, 203, 201}, + {200, 202, 200, 202}, + }, + { + {205, 203, 204, 202}, + {202, 204, 201, 203}, + {204, 202, 204, 202}, + {201, 203, 201, 203}, + }, + { + {206, 204, 205, 203}, + {203, 205, 202, 204}, + {205, 203, 205, 203}, + {202, 204, 202, 204}, + }, + { + {207, 205, 206, 204}, + {204, 206, 203, 205}, + {206, 204, 206, 204}, + {203, 205, 203, 205}, + }, + { + {208, 206, 207, 205}, + {205, 207, 204, 206}, + {207, 205, 207, 205}, + {204, 206, 204, 206}, + }, + { + {209, 207, 208, 206}, + {206, 208, 205, 207}, + {208, 206, 208, 206}, + {205, 207, 205, 207}, + }, + { + {210, 208, 209, 207}, + {207, 209, 206, 208}, + {209, 207, 209, 207}, + {206, 208, 206, 208}, + }, + { + {211, 209, 210, 208}, + {208, 210, 207, 209}, + {210, 208, 210, 208}, + {207, 209, 207, 209}, + }, + { + {212, 210, 211, 209}, + {209, 211, 208, 210}, + {211, 209, 211, 209}, + {208, 210, 208, 210}, + }, + { + {213, 211, 212, 210}, + {210, 212, 209, 211}, + {212, 210, 212, 210}, + {209, 211, 209, 211}, + }, + { + {214, 212, 213, 211}, + {211, 213, 210, 212}, + {213, 211, 213, 211}, + {210, 212, 210, 212}, + }, + { + {215, 213, 214, 212}, + {212, 214, 211, 213}, + {214, 212, 214, 212}, + {211, 213, 211, 213}, + }, + { + {216, 214, 215, 213}, + {213, 215, 212, 214}, + {215, 213, 215, 213}, + {212, 214, 212, 214}, + }, + { + {217, 215, 216, 214}, + {214, 216, 213, 215}, + {216, 214, 216, 214}, + {213, 215, 213, 215}, + }, + { + {218, 216, 217, 215}, + {215, 217, 214, 216}, + {217, 215, 217, 215}, + {214, 216, 214, 216}, + }, + { + {219, 217, 218, 216}, + {216, 218, 215, 217}, + {218, 216, 218, 216}, + {215, 217, 215, 217}, + }, + { + {220, 218, 219, 217}, + {217, 219, 216, 218}, + {219, 217, 219, 217}, + {216, 218, 216, 218}, + }, + { + {221, 219, 220, 218}, + {218, 220, 217, 219}, + {220, 218, 220, 218}, + {217, 219, 217, 219}, + }, + { + {222, 220, 221, 219}, + {219, 221, 218, 220}, + {221, 219, 221, 219}, + {218, 220, 218, 220}, + }, + { + {223, 221, 222, 220}, + {220, 222, 219, 221}, + {222, 220, 222, 220}, + {219, 221, 219, 221}, + }, + { + {224, 222, 223, 221}, + {221, 223, 220, 222}, + {223, 221, 223, 221}, + {220, 222, 220, 222}, + }, + { + {225, 223, 224, 222}, + {222, 224, 221, 223}, + {224, 222, 224, 222}, + {221, 223, 221, 223}, + }, + { + {226, 224, 225, 223}, + {223, 225, 222, 224}, + {225, 223, 225, 223}, + {222, 224, 222, 224}, + }, + { + {227, 225, 226, 224}, + {224, 226, 223, 225}, + {226, 224, 226, 224}, + {223, 225, 223, 225}, + }, + { + {228, 226, 227, 225}, + {225, 227, 224, 226}, + {227, 225, 227, 225}, + {224, 226, 224, 226}, + }, + { + {229, 227, 228, 226}, + {226, 228, 225, 227}, + {228, 226, 228, 226}, + {225, 227, 225, 227}, + }, + { + {230, 228, 229, 227}, + {227, 229, 226, 228}, + {229, 227, 229, 227}, + {226, 228, 226, 228}, + }, + { + {231, 229, 230, 228}, + {228, 230, 227, 229}, + {230, 228, 230, 228}, + {227, 229, 227, 229}, + }, + { + {232, 230, 231, 229}, + {229, 231, 228, 230}, + {231, 229, 231, 229}, + {228, 230, 228, 230}, + }, + { + {233, 231, 232, 230}, + {230, 232, 229, 231}, + {232, 230, 232, 230}, + {229, 231, 229, 231}, + }, + { + {234, 232, 233, 231}, + {231, 233, 230, 232}, + {233, 231, 233, 231}, + {230, 232, 230, 232}, + }, + { + {235, 233, 234, 232}, + {232, 234, 231, 233}, + {234, 232, 234, 232}, + {231, 233, 231, 233}, + }, + { + {236, 234, 235, 233}, + {233, 235, 232, 234}, + {235, 233, 235, 233}, + {232, 234, 232, 234}, + }, + { + {237, 235, 236, 234}, + {234, 236, 233, 235}, + {236, 234, 236, 234}, + {233, 235, 233, 235}, + }, + { + {238, 236, 237, 235}, + {235, 237, 234, 236}, + {237, 235, 237, 235}, + {234, 236, 234, 236}, + }, + { + {239, 237, 238, 236}, + {236, 238, 235, 237}, + {238, 236, 238, 236}, + {235, 237, 235, 237}, + }, + { + {240, 238, 239, 237}, + {237, 239, 236, 238}, + {239, 237, 239, 237}, + {236, 238, 236, 238}, + }, + { + {241, 239, 240, 238}, + {238, 240, 237, 239}, + {240, 238, 240, 238}, + {237, 239, 237, 239}, + }, + { + {242, 240, 241, 239}, + {239, 241, 238, 240}, + {241, 239, 241, 239}, + {238, 240, 238, 240}, + }, + { + {243, 241, 242, 240}, + {240, 242, 239, 241}, + {242, 240, 242, 240}, + {239, 241, 239, 241}, + }, + { + {244, 242, 243, 241}, + {241, 243, 240, 242}, + {243, 241, 243, 241}, + {240, 242, 240, 242}, + }, + { + {245, 243, 244, 242}, + {242, 244, 241, 243}, + {244, 242, 244, 242}, + {241, 243, 241, 243}, + }, + { + {246, 244, 245, 243}, + {243, 245, 242, 244}, + {245, 243, 245, 243}, + {242, 244, 242, 244}, + }, + { + {247, 245, 246, 244}, + {244, 246, 243, 245}, + {246, 244, 246, 244}, + {243, 245, 243, 245}, + }, + { + {248, 246, 247, 245}, + {245, 247, 244, 246}, + {247, 245, 247, 245}, + {244, 246, 244, 246}, + }, + { + {249, 247, 248, 246}, + {246, 248, 245, 247}, + {248, 246, 248, 246}, + {245, 247, 245, 247}, + }, + { + {250, 248, 249, 247}, + {247, 249, 246, 248}, + {249, 247, 249, 247}, + {246, 248, 246, 248}, + }, + { + {251, 249, 250, 248}, + {248, 250, 247, 249}, + {250, 248, 250, 248}, + {247, 249, 247, 249}, + }, + { + {252, 250, 251, 249}, + {249, 251, 248, 250}, + {251, 249, 251, 249}, + {248, 250, 248, 250}, + }, + { + {253, 251, 252, 250}, + {250, 252, 249, 251}, + {252, 250, 252, 250}, + {249, 251, 249, 251}, + }, + { + {254, 252, 253, 251}, + {251, 253, 250, 252}, + {253, 251, 253, 251}, + {250, 252, 250, 252}, + }, + { + {255, 253, 254, 252}, + {252, 254, 251, 253}, + {254, 252, 254, 252}, + {251, 253, 251, 253}, + }, + { + {255, 254, 255, 253}, + {253, 255, 252, 254}, + {255, 253, 255, 253}, + {252, 254, 252, 254}, + }, + { + {255, 255, 255, 254}, + {254, 255, 253, 255}, + {255, 254, 255, 254}, + {253, 255, 253, 255}, + }, + { + {255, 255, 255, 255}, + {255, 255, 254, 255}, + {255, 255, 255, 255}, + {254, 255, 254, 255}, + }, +}; + + + + +static const uint8_t dithersub_g2x2[256][2][2] = +{ + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {4, 2}, + {1, 3}, + }, + { + {5, 3}, + {2, 4}, + }, + { + {6, 4}, + {3, 5}, + }, + { + {7, 5}, + {4, 6}, + }, + { + {8, 6}, + {5, 7}, + }, + { + {9, 7}, + {6, 8}, + }, + { + {10, 8}, + {7, 9}, + }, + { + {11, 9}, + {8, 10}, + }, + { + {12, 10}, + {9, 11}, + }, + { + {13, 11}, + {10, 12}, + }, + { + {14, 12}, + {11, 13}, + }, + { + {15, 13}, + {12, 14}, + }, + { + {16, 14}, + {13, 15}, + }, + { + {17, 15}, + {14, 16}, + }, + { + {18, 16}, + {15, 17}, + }, + { + {19, 17}, + {16, 18}, + }, + { + {20, 18}, + {17, 19}, + }, + { + {21, 19}, + {18, 20}, + }, + { + {22, 20}, + {19, 21}, + }, + { + {23, 21}, + {20, 22}, + }, + { + {24, 22}, + {21, 23}, + }, + { + {25, 23}, + {22, 24}, + }, + { + {26, 24}, + {23, 25}, + }, + { + {27, 25}, + {24, 26}, + }, + { + {28, 26}, + {25, 27}, + }, + { + {29, 27}, + {26, 28}, + }, + { + {30, 28}, + {27, 29}, + }, + { + {31, 29}, + {28, 30}, + }, + { + {32, 30}, + {29, 31}, + }, + { + {33, 31}, + {30, 32}, + }, + { + {34, 32}, + {31, 33}, + }, + { + {35, 33}, + {32, 34}, + }, + { + {36, 34}, + {33, 35}, + }, + { + {37, 35}, + {34, 36}, + }, + { + {38, 36}, + {35, 37}, + }, + { + {39, 37}, + {36, 38}, + }, + { + {40, 38}, + {37, 39}, + }, + { + {41, 39}, + {38, 40}, + }, + { + {42, 40}, + {39, 41}, + }, + { + {43, 41}, + {40, 42}, + }, + { + {44, 42}, + {41, 43}, + }, + { + {45, 43}, + {42, 44}, + }, + { + {46, 44}, + {43, 45}, + }, + { + {47, 45}, + {44, 46}, + }, + { + {48, 46}, + {45, 47}, + }, + { + {49, 47}, + {46, 48}, + }, + { + {50, 48}, + {47, 49}, + }, + { + {51, 49}, + {48, 50}, + }, + { + {52, 50}, + {49, 51}, + }, + { + {53, 51}, + {50, 52}, + }, + { + {54, 52}, + {51, 53}, + }, + { + {55, 53}, + {52, 54}, + }, + { + {56, 54}, + {53, 55}, + }, + { + {57, 55}, + {54, 56}, + }, + { + {58, 56}, + {55, 57}, + }, + { + {59, 57}, + {56, 58}, + }, + { + {60, 58}, + {57, 59}, + }, + { + {61, 59}, + {58, 60}, + }, + { + {62, 60}, + {59, 61}, + }, + { + {63, 61}, + {60, 62}, + }, + { + {64, 62}, + {61, 63}, + }, + { + {65, 63}, + {62, 64}, + }, + { + {66, 64}, + {63, 65}, + }, + { + {67, 65}, + {64, 66}, + }, + { + {68, 66}, + {65, 67}, + }, + { + {69, 67}, + {66, 68}, + }, + { + {70, 68}, + {67, 69}, + }, + { + {71, 69}, + {68, 70}, + }, + { + {72, 70}, + {69, 71}, + }, + { + {73, 71}, + {70, 72}, + }, + { + {74, 72}, + {71, 73}, + }, + { + {75, 73}, + {72, 74}, + }, + { + {76, 74}, + {73, 75}, + }, + { + {77, 75}, + {74, 76}, + }, + { + {78, 76}, + {75, 77}, + }, + { + {79, 77}, + {76, 78}, + }, + { + {80, 78}, + {77, 79}, + }, + { + {81, 79}, + {78, 80}, + }, + { + {82, 80}, + {79, 81}, + }, + { + {83, 81}, + {80, 82}, + }, + { + {84, 82}, + {81, 83}, + }, + { + {85, 83}, + {82, 84}, + }, + { + {86, 84}, + {83, 85}, + }, + { + {87, 85}, + {84, 86}, + }, + { + {88, 86}, + {85, 87}, + }, + { + {89, 87}, + {86, 88}, + }, + { + {90, 88}, + {87, 89}, + }, + { + {91, 89}, + {88, 90}, + }, + { + {92, 90}, + {89, 91}, + }, + { + {93, 91}, + {90, 92}, + }, + { + {94, 92}, + {91, 93}, + }, + { + {95, 93}, + {92, 94}, + }, + { + {96, 94}, + {93, 95}, + }, + { + {97, 95}, + {94, 96}, + }, + { + {98, 96}, + {95, 97}, + }, + { + {99, 97}, + {96, 98}, + }, + { + {100, 98}, + {97, 99}, + }, + { + {101, 99}, + {98, 100}, + }, + { + {102, 100}, + {99, 101}, + }, + { + {103, 101}, + {100, 102}, + }, + { + {104, 102}, + {101, 103}, + }, + { + {105, 103}, + {102, 104}, + }, + { + {106, 104}, + {103, 105}, + }, + { + {107, 105}, + {104, 106}, + }, + { + {108, 106}, + {105, 107}, + }, + { + {109, 107}, + {106, 108}, + }, + { + {110, 108}, + {107, 109}, + }, + { + {111, 109}, + {108, 110}, + }, + { + {112, 110}, + {109, 111}, + }, + { + {113, 111}, + {110, 112}, + }, + { + {114, 112}, + {111, 113}, + }, + { + {115, 113}, + {112, 114}, + }, + { + {116, 114}, + {113, 115}, + }, + { + {117, 115}, + {114, 116}, + }, + { + {118, 116}, + {115, 117}, + }, + { + {119, 117}, + {116, 118}, + }, + { + {120, 118}, + {117, 119}, + }, + { + {121, 119}, + {118, 120}, + }, + { + {122, 120}, + {119, 121}, + }, + { + {123, 121}, + {120, 122}, + }, + { + {124, 122}, + {121, 123}, + }, + { + {125, 123}, + {122, 124}, + }, + { + {126, 124}, + {123, 125}, + }, + { + {127, 125}, + {124, 126}, + }, + { + {128, 126}, + {125, 127}, + }, + { + {129, 127}, + {126, 128}, + }, + { + {130, 128}, + {127, 129}, + }, + { + {131, 129}, + {128, 130}, + }, + { + {132, 130}, + {129, 131}, + }, + { + {133, 131}, + {130, 132}, + }, + { + {134, 132}, + {131, 133}, + }, + { + {135, 133}, + {132, 134}, + }, + { + {136, 134}, + {133, 135}, + }, + { + {137, 135}, + {134, 136}, + }, + { + {138, 136}, + {135, 137}, + }, + { + {139, 137}, + {136, 138}, + }, + { + {140, 138}, + {137, 139}, + }, + { + {141, 139}, + {138, 140}, + }, + { + {142, 140}, + {139, 141}, + }, + { + {143, 141}, + {140, 142}, + }, + { + {144, 142}, + {141, 143}, + }, + { + {145, 143}, + {142, 144}, + }, + { + {146, 144}, + {143, 145}, + }, + { + {147, 145}, + {144, 146}, + }, + { + {148, 146}, + {145, 147}, + }, + { + {149, 147}, + {146, 148}, + }, + { + {150, 148}, + {147, 149}, + }, + { + {151, 149}, + {148, 150}, + }, + { + {152, 150}, + {149, 151}, + }, + { + {153, 151}, + {150, 152}, + }, + { + {154, 152}, + {151, 153}, + }, + { + {155, 153}, + {152, 154}, + }, + { + {156, 154}, + {153, 155}, + }, + { + {157, 155}, + {154, 156}, + }, + { + {158, 156}, + {155, 157}, + }, + { + {159, 157}, + {156, 158}, + }, + { + {160, 158}, + {157, 159}, + }, + { + {161, 159}, + {158, 160}, + }, + { + {162, 160}, + {159, 161}, + }, + { + {163, 161}, + {160, 162}, + }, + { + {164, 162}, + {161, 163}, + }, + { + {165, 163}, + {162, 164}, + }, + { + {166, 164}, + {163, 165}, + }, + { + {167, 165}, + {164, 166}, + }, + { + {168, 166}, + {165, 167}, + }, + { + {169, 167}, + {166, 168}, + }, + { + {170, 168}, + {167, 169}, + }, + { + {171, 169}, + {168, 170}, + }, + { + {172, 170}, + {169, 171}, + }, + { + {173, 171}, + {170, 172}, + }, + { + {174, 172}, + {171, 173}, + }, + { + {175, 173}, + {172, 174}, + }, + { + {176, 174}, + {173, 175}, + }, + { + {177, 175}, + {174, 176}, + }, + { + {178, 176}, + {175, 177}, + }, + { + {179, 177}, + {176, 178}, + }, + { + {180, 178}, + {177, 179}, + }, + { + {181, 179}, + {178, 180}, + }, + { + {182, 180}, + {179, 181}, + }, + { + {183, 181}, + {180, 182}, + }, + { + {184, 182}, + {181, 183}, + }, + { + {185, 183}, + {182, 184}, + }, + { + {186, 184}, + {183, 185}, + }, + { + {187, 185}, + {184, 186}, + }, + { + {188, 186}, + {185, 187}, + }, + { + {189, 187}, + {186, 188}, + }, + { + {190, 188}, + {187, 189}, + }, + { + {191, 189}, + {188, 190}, + }, + { + {192, 190}, + {189, 191}, + }, + { + {193, 191}, + {190, 192}, + }, + { + {194, 192}, + {191, 193}, + }, + { + {195, 193}, + {192, 194}, + }, + { + {196, 194}, + {193, 195}, + }, + { + {197, 195}, + {194, 196}, + }, + { + {198, 196}, + {195, 197}, + }, + { + {199, 197}, + {196, 198}, + }, + { + {200, 198}, + {197, 199}, + }, + { + {201, 199}, + {198, 200}, + }, + { + {202, 200}, + {199, 201}, + }, + { + {203, 201}, + {200, 202}, + }, + { + {204, 202}, + {201, 203}, + }, + { + {205, 203}, + {202, 204}, + }, + { + {206, 204}, + {203, 205}, + }, + { + {207, 205}, + {204, 206}, + }, + { + {208, 206}, + {205, 207}, + }, + { + {209, 207}, + {206, 208}, + }, + { + {210, 208}, + {207, 209}, + }, + { + {211, 209}, + {208, 210}, + }, + { + {212, 210}, + {209, 211}, + }, + { + {213, 211}, + {210, 212}, + }, + { + {214, 212}, + {211, 213}, + }, + { + {215, 213}, + {212, 214}, + }, + { + {216, 214}, + {213, 215}, + }, + { + {217, 215}, + {214, 216}, + }, + { + {218, 216}, + {215, 217}, + }, + { + {219, 217}, + {216, 218}, + }, + { + {220, 218}, + {217, 219}, + }, + { + {221, 219}, + {218, 220}, + }, + { + {222, 220}, + {219, 221}, + }, + { + {223, 221}, + {220, 222}, + }, + { + {224, 222}, + {221, 223}, + }, + { + {225, 223}, + {222, 224}, + }, + { + {226, 224}, + {223, 225}, + }, + { + {227, 225}, + {224, 226}, + }, + { + {228, 226}, + {225, 227}, + }, + { + {229, 227}, + {226, 228}, + }, + { + {230, 228}, + {227, 229}, + }, + { + {231, 229}, + {228, 230}, + }, + { + {232, 230}, + {229, 231}, + }, + { + {233, 231}, + {230, 232}, + }, + { + {234, 232}, + {231, 233}, + }, + { + {235, 233}, + {232, 234}, + }, + { + {236, 234}, + {233, 235}, + }, + { + {237, 235}, + {234, 236}, + }, + { + {238, 236}, + {235, 237}, + }, + { + {239, 237}, + {236, 238}, + }, + { + {240, 238}, + {237, 239}, + }, + { + {241, 239}, + {238, 240}, + }, + { + {242, 240}, + {239, 241}, + }, + { + {243, 241}, + {240, 242}, + }, + { + {244, 242}, + {241, 243}, + }, + { + {245, 243}, + {242, 244}, + }, + { + {246, 244}, + {243, 245}, + }, + { + {247, 245}, + {244, 246}, + }, + { + {248, 246}, + {245, 247}, + }, + { + {249, 247}, + {246, 248}, + }, + { + {250, 248}, + {247, 249}, + }, + { + {251, 249}, + {248, 250}, + }, + { + {252, 250}, + {249, 251}, + }, + { + {253, 251}, + {250, 252}, + }, + { + {254, 252}, + {251, 253}, + }, + { + {255, 253}, + {252, 254}, + }, + { + {255, 254}, + {253, 255}, + }, + { + {255, 255}, + {254, 255}, + }, +}; + + +static const uint8_t dithersub_rb2x2[256][2][2] = +{ + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {8, 4}, + {2, 6}, + }, + { + {9, 5}, + {3, 7}, + }, + { + {10, 6}, + {4, 8}, + }, + { + {11, 7}, + {5, 9}, + }, + { + {12, 8}, + {6, 10}, + }, + { + {13, 9}, + {7, 11}, + }, + { + {14, 10}, + {8, 12}, + }, + { + {15, 11}, + {9, 13}, + }, + { + {16, 12}, + {10, 14}, + }, + { + {17, 13}, + {11, 15}, + }, + { + {18, 14}, + {12, 16}, + }, + { + {19, 15}, + {13, 17}, + }, + { + {20, 16}, + {14, 18}, + }, + { + {21, 17}, + {15, 19}, + }, + { + {22, 18}, + {16, 20}, + }, + { + {23, 19}, + {17, 21}, + }, + { + {24, 20}, + {18, 22}, + }, + { + {25, 21}, + {19, 23}, + }, + { + {26, 22}, + {20, 24}, + }, + { + {27, 23}, + {21, 25}, + }, + { + {28, 24}, + {22, 26}, + }, + { + {29, 25}, + {23, 27}, + }, + { + {30, 26}, + {24, 28}, + }, + { + {31, 27}, + {25, 29}, + }, + { + {32, 28}, + {26, 30}, + }, + { + {33, 29}, + {27, 31}, + }, + { + {34, 30}, + {28, 32}, + }, + { + {35, 31}, + {29, 33}, + }, + { + {36, 32}, + {30, 34}, + }, + { + {37, 33}, + {31, 35}, + }, + { + {38, 34}, + {32, 36}, + }, + { + {39, 35}, + {33, 37}, + }, + { + {40, 36}, + {34, 38}, + }, + { + {41, 37}, + {35, 39}, + }, + { + {42, 38}, + {36, 40}, + }, + { + {43, 39}, + {37, 41}, + }, + { + {44, 40}, + {38, 42}, + }, + { + {45, 41}, + {39, 43}, + }, + { + {46, 42}, + {40, 44}, + }, + { + {47, 43}, + {41, 45}, + }, + { + {48, 44}, + {42, 46}, + }, + { + {49, 45}, + {43, 47}, + }, + { + {50, 46}, + {44, 48}, + }, + { + {51, 47}, + {45, 49}, + }, + { + {52, 48}, + {46, 50}, + }, + { + {53, 49}, + {47, 51}, + }, + { + {54, 50}, + {48, 52}, + }, + { + {55, 51}, + {49, 53}, + }, + { + {56, 52}, + {50, 54}, + }, + { + {57, 53}, + {51, 55}, + }, + { + {58, 54}, + {52, 56}, + }, + { + {59, 55}, + {53, 57}, + }, + { + {60, 56}, + {54, 58}, + }, + { + {61, 57}, + {55, 59}, + }, + { + {62, 58}, + {56, 60}, + }, + { + {63, 59}, + {57, 61}, + }, + { + {64, 60}, + {58, 62}, + }, + { + {65, 61}, + {59, 63}, + }, + { + {66, 62}, + {60, 64}, + }, + { + {67, 63}, + {61, 65}, + }, + { + {68, 64}, + {62, 66}, + }, + { + {69, 65}, + {63, 67}, + }, + { + {70, 66}, + {64, 68}, + }, + { + {71, 67}, + {65, 69}, + }, + { + {72, 68}, + {66, 70}, + }, + { + {73, 69}, + {67, 71}, + }, + { + {74, 70}, + {68, 72}, + }, + { + {75, 71}, + {69, 73}, + }, + { + {76, 72}, + {70, 74}, + }, + { + {77, 73}, + {71, 75}, + }, + { + {78, 74}, + {72, 76}, + }, + { + {79, 75}, + {73, 77}, + }, + { + {80, 76}, + {74, 78}, + }, + { + {81, 77}, + {75, 79}, + }, + { + {82, 78}, + {76, 80}, + }, + { + {83, 79}, + {77, 81}, + }, + { + {84, 80}, + {78, 82}, + }, + { + {85, 81}, + {79, 83}, + }, + { + {86, 82}, + {80, 84}, + }, + { + {87, 83}, + {81, 85}, + }, + { + {88, 84}, + {82, 86}, + }, + { + {89, 85}, + {83, 87}, + }, + { + {90, 86}, + {84, 88}, + }, + { + {91, 87}, + {85, 89}, + }, + { + {92, 88}, + {86, 90}, + }, + { + {93, 89}, + {87, 91}, + }, + { + {94, 90}, + {88, 92}, + }, + { + {95, 91}, + {89, 93}, + }, + { + {96, 92}, + {90, 94}, + }, + { + {97, 93}, + {91, 95}, + }, + { + {98, 94}, + {92, 96}, + }, + { + {99, 95}, + {93, 97}, + }, + { + {100, 96}, + {94, 98}, + }, + { + {101, 97}, + {95, 99}, + }, + { + {102, 98}, + {96, 100}, + }, + { + {103, 99}, + {97, 101}, + }, + { + {104, 100}, + {98, 102}, + }, + { + {105, 101}, + {99, 103}, + }, + { + {106, 102}, + {100, 104}, + }, + { + {107, 103}, + {101, 105}, + }, + { + {108, 104}, + {102, 106}, + }, + { + {109, 105}, + {103, 107}, + }, + { + {110, 106}, + {104, 108}, + }, + { + {111, 107}, + {105, 109}, + }, + { + {112, 108}, + {106, 110}, + }, + { + {113, 109}, + {107, 111}, + }, + { + {114, 110}, + {108, 112}, + }, + { + {115, 111}, + {109, 113}, + }, + { + {116, 112}, + {110, 114}, + }, + { + {117, 113}, + {111, 115}, + }, + { + {118, 114}, + {112, 116}, + }, + { + {119, 115}, + {113, 117}, + }, + { + {120, 116}, + {114, 118}, + }, + { + {121, 117}, + {115, 119}, + }, + { + {122, 118}, + {116, 120}, + }, + { + {123, 119}, + {117, 121}, + }, + { + {124, 120}, + {118, 122}, + }, + { + {125, 121}, + {119, 123}, + }, + { + {126, 122}, + {120, 124}, + }, + { + {127, 123}, + {121, 125}, + }, + { + {128, 124}, + {122, 126}, + }, + { + {129, 125}, + {123, 127}, + }, + { + {130, 126}, + {124, 128}, + }, + { + {131, 127}, + {125, 129}, + }, + { + {132, 128}, + {126, 130}, + }, + { + {133, 129}, + {127, 131}, + }, + { + {134, 130}, + {128, 132}, + }, + { + {135, 131}, + {129, 133}, + }, + { + {136, 132}, + {130, 134}, + }, + { + {137, 133}, + {131, 135}, + }, + { + {138, 134}, + {132, 136}, + }, + { + {139, 135}, + {133, 137}, + }, + { + {140, 136}, + {134, 138}, + }, + { + {141, 137}, + {135, 139}, + }, + { + {142, 138}, + {136, 140}, + }, + { + {143, 139}, + {137, 141}, + }, + { + {144, 140}, + {138, 142}, + }, + { + {145, 141}, + {139, 143}, + }, + { + {146, 142}, + {140, 144}, + }, + { + {147, 143}, + {141, 145}, + }, + { + {148, 144}, + {142, 146}, + }, + { + {149, 145}, + {143, 147}, + }, + { + {150, 146}, + {144, 148}, + }, + { + {151, 147}, + {145, 149}, + }, + { + {152, 148}, + {146, 150}, + }, + { + {153, 149}, + {147, 151}, + }, + { + {154, 150}, + {148, 152}, + }, + { + {155, 151}, + {149, 153}, + }, + { + {156, 152}, + {150, 154}, + }, + { + {157, 153}, + {151, 155}, + }, + { + {158, 154}, + {152, 156}, + }, + { + {159, 155}, + {153, 157}, + }, + { + {160, 156}, + {154, 158}, + }, + { + {161, 157}, + {155, 159}, + }, + { + {162, 158}, + {156, 160}, + }, + { + {163, 159}, + {157, 161}, + }, + { + {164, 160}, + {158, 162}, + }, + { + {165, 161}, + {159, 163}, + }, + { + {166, 162}, + {160, 164}, + }, + { + {167, 163}, + {161, 165}, + }, + { + {168, 164}, + {162, 166}, + }, + { + {169, 165}, + {163, 167}, + }, + { + {170, 166}, + {164, 168}, + }, + { + {171, 167}, + {165, 169}, + }, + { + {172, 168}, + {166, 170}, + }, + { + {173, 169}, + {167, 171}, + }, + { + {174, 170}, + {168, 172}, + }, + { + {175, 171}, + {169, 173}, + }, + { + {176, 172}, + {170, 174}, + }, + { + {177, 173}, + {171, 175}, + }, + { + {178, 174}, + {172, 176}, + }, + { + {179, 175}, + {173, 177}, + }, + { + {180, 176}, + {174, 178}, + }, + { + {181, 177}, + {175, 179}, + }, + { + {182, 178}, + {176, 180}, + }, + { + {183, 179}, + {177, 181}, + }, + { + {184, 180}, + {178, 182}, + }, + { + {185, 181}, + {179, 183}, + }, + { + {186, 182}, + {180, 184}, + }, + { + {187, 183}, + {181, 185}, + }, + { + {188, 184}, + {182, 186}, + }, + { + {189, 185}, + {183, 187}, + }, + { + {190, 186}, + {184, 188}, + }, + { + {191, 187}, + {185, 189}, + }, + { + {192, 188}, + {186, 190}, + }, + { + {193, 189}, + {187, 191}, + }, + { + {194, 190}, + {188, 192}, + }, + { + {195, 191}, + {189, 193}, + }, + { + {196, 192}, + {190, 194}, + }, + { + {197, 193}, + {191, 195}, + }, + { + {198, 194}, + {192, 196}, + }, + { + {199, 195}, + {193, 197}, + }, + { + {200, 196}, + {194, 198}, + }, + { + {201, 197}, + {195, 199}, + }, + { + {202, 198}, + {196, 200}, + }, + { + {203, 199}, + {197, 201}, + }, + { + {204, 200}, + {198, 202}, + }, + { + {205, 201}, + {199, 203}, + }, + { + {206, 202}, + {200, 204}, + }, + { + {207, 203}, + {201, 205}, + }, + { + {208, 204}, + {202, 206}, + }, + { + {209, 205}, + {203, 207}, + }, + { + {210, 206}, + {204, 208}, + }, + { + {211, 207}, + {205, 209}, + }, + { + {212, 208}, + {206, 210}, + }, + { + {213, 209}, + {207, 211}, + }, + { + {214, 210}, + {208, 212}, + }, + { + {215, 211}, + {209, 213}, + }, + { + {216, 212}, + {210, 214}, + }, + { + {217, 213}, + {211, 215}, + }, + { + {218, 214}, + {212, 216}, + }, + { + {219, 215}, + {213, 217}, + }, + { + {220, 216}, + {214, 218}, + }, + { + {221, 217}, + {215, 219}, + }, + { + {222, 218}, + {216, 220}, + }, + { + {223, 219}, + {217, 221}, + }, + { + {224, 220}, + {218, 222}, + }, + { + {225, 221}, + {219, 223}, + }, + { + {226, 222}, + {220, 224}, + }, + { + {227, 223}, + {221, 225}, + }, + { + {228, 224}, + {222, 226}, + }, + { + {229, 225}, + {223, 227}, + }, + { + {230, 226}, + {224, 228}, + }, + { + {231, 227}, + {225, 229}, + }, + { + {232, 228}, + {226, 230}, + }, + { + {233, 229}, + {227, 231}, + }, + { + {234, 230}, + {228, 232}, + }, + { + {235, 231}, + {229, 233}, + }, + { + {236, 232}, + {230, 234}, + }, + { + {237, 233}, + {231, 235}, + }, + { + {238, 234}, + {232, 236}, + }, + { + {239, 235}, + {233, 237}, + }, + { + {240, 236}, + {234, 238}, + }, + { + {241, 237}, + {235, 239}, + }, + { + {242, 238}, + {236, 240}, + }, + { + {243, 239}, + {237, 241}, + }, + { + {244, 240}, + {238, 242}, + }, + { + {245, 241}, + {239, 243}, + }, + { + {246, 242}, + {240, 244}, + }, + { + {247, 243}, + {241, 245}, + }, + { + {248, 244}, + {242, 246}, + }, + { + {249, 245}, + {243, 247}, + }, + { + {250, 246}, + {244, 248}, + }, + { + {251, 247}, + {245, 249}, + }, + { + {252, 248}, + {246, 250}, + }, + { + {253, 249}, + {247, 251}, + }, + { + {254, 250}, + {248, 252}, + }, + { + {255, 251}, + {249, 253}, + }, + { + {255, 252}, + {250, 254}, + }, + { + {255, 253}, + {251, 255}, + }, + { + {255, 254}, + {252, 255}, + }, + { + {255, 255}, + {253, 255}, + }, +}; + diff --git a/src/vid_voodoo_regs.h b/src/vid_voodoo_regs.h index f7ab208..e99241f 100644 --- a/src/vid_voodoo_regs.h +++ b/src/vid_voodoo_regs.h @@ -370,6 +370,7 @@ enum FBZ_DEPTH_BIAS = (1 << 16), + FBZ_DITHER_SUB = (1 << 19), FBZ_DEPTH_SOURCE = (1 << 20), FBZ_PARAM_ADJUST = (1 << 26) @@ -689,3 +690,5 @@ enum #define depth_op ( (params->fbzMode >> 5) & 7) #define dither ( params->fbzMode & FBZ_DITHER) #define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) +#define dithersub (params->fbzMode & FBZ_DITHER_SUB) + diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index 503829d..420e396 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -1281,7 +1281,21 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood ALPHA_TEST(src_a); if (params->alphaMode & (1 << 4)) + { + if (dithersub && !dither2x2 && voodoo->dithersub_enabled) + { + dest_r = dithersub_rb[dest_r][real_y & 3][x & 3]; + dest_g = dithersub_g [dest_g][real_y & 3][x & 3]; + dest_b = dithersub_rb[dest_b][real_y & 3][x & 3]; + } + if (dithersub && dither2x2 && voodoo->dithersub_enabled) + { + dest_r = dithersub_rb2x2[dest_r][real_y & 1][x & 1]; + dest_g = dithersub_g2x2 [dest_g][real_y & 1][x & 1]; + dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1]; + } ALPHA_BLEND(src_r, src_g, src_b, src_a); + } if (update) { From f99dc0dd714ba93d232d1a8ce2713802b4441172 Mon Sep 17 00:00:00 2001 From: greatpsycho Date: Sun, 20 Jun 2021 13:02:24 +0900 Subject: [PATCH 1045/1050] Update wx-createdisc.cc Add 1.2MB floppy image format. --- src/wx-createdisc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wx-createdisc.cc b/src/wx-createdisc.cc index d9d1a66..f0eb8fc 100644 --- a/src/wx-createdisc.cc +++ b/src/wx-createdisc.cc @@ -29,6 +29,7 @@ static struct {"320 kB", 2*40*8}, {"360 kB", 2*40*9}, {"720 kB", 2*80*9}, + {"1.2 MB", 2*80*15}, {"1.44 MB", 2*80*18}, {"2.88 MB", 2*80*36}, {"100 MB (Zip)", 2048*96}, From 351b23ed9559c8142338fae1864fbc839e6ecfd9 Mon Sep 17 00:00:00 2001 From: greatpsycho Date: Sun, 20 Jun 2021 13:12:08 +0900 Subject: [PATCH 1046/1050] Update Makefile Add missed Zenith Data SupersPort source. --- src/Makefile.am | 2 +- src/Makefile.mingw-wx-sdl2 | 2 +- src/Makefile.mingw-wx-sdl2-network | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 734be0e..65ab6a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -51,7 +51,7 @@ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_t1000.c vid_t3100e.c vid_tandy vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c vid_voodoo_banshee.c vid_voodoo_banshee_blitter.c \ vid_voodoo_blitter.c vid_voodoo_display.c vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c \ vid_voodoo_render.c vid_voodoo_setup.c vid_voodoo_texture.c video.c wd76c10.c vid_wy700.c vt82c586b.c \ -vl82c480.c w83877tf.c w83977tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c sound_dbopl.cc sound_resid.cc +vl82c480.c w83877tf.c w83977tf.c x86seg.c x87.c x87_timings.c xi8088.c xtide.c zenith.c sound_dbopl.cc sound_resid.cc # DOSBox pcem_SOURCES += dosbox/cdrom_image.cpp dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c diff --git a/src/Makefile.mingw-wx-sdl2 b/src/Makefile.mingw-wx-sdl2 index 4d16048..cc37a09 100644 --- a/src/Makefile.mingw-wx-sdl2 +++ b/src/Makefile.mingw-wx-sdl2 @@ -39,7 +39,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \ vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \ vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \ - vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ + vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o zenith.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ diff --git a/src/Makefile.mingw-wx-sdl2-network b/src/Makefile.mingw-wx-sdl2-network index d181926..c1d7771 100644 --- a/src/Makefile.mingw-wx-sdl2-network +++ b/src/Makefile.mingw-wx-sdl2-network @@ -39,7 +39,7 @@ OBJ = 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o 808x.o 82091aa.o acc203 vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_voodoo_banshee.o vid_voodoo_banshee_blitter.o \ vid_voodoo_blitter.o vid_voodoo_display.o vid_voodoo_fb.o vid_voodoo_fifo.o vid_voodoo_reg.o \ vid_voodoo_render.o vid_voodoo_setup.o vid_voodoo_texture.o vid_wy700.o video.o vl82c480.o \ - vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o win-midi.o wx-main.o \ + vt82c586b.o w83877tf.o w83977tf.o wd76c10.o x86seg.o x87.o x87_timings.o xi8088.c xtide.o zenith.o win-midi.o wx-main.o \ wx-config_sel.o wx-dialogbox.o wx-hostconfig.o wx-utils.o wx-app.o wx-sdl2-joystick.o wx-sdl2-mouse.o \ wx-sdl2-keyboard.o wx-sdl2-video.o wx-sdl2.o wx-config.o wx-deviceconfig.o wx-status.o \ wx-sdl2-status.o wx-resources.o wx-thread.o wx-common.o wx-sdl2-display-win.o \ From 974f663d9226d78e54baf0572582751b3a0c09d1 Mon Sep 17 00:00:00 2001 From: pcem-maintainer Date: Sun, 20 Jun 2021 17:50:34 -0300 Subject: [PATCH 1047/1050] Remove AWARD 286 BIOS turbo hack CPU clock control is now implemented in the C&T SCAT chipset. --- src/keyboard_at.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 055c784..312326a 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -675,17 +675,14 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at_adddata(0x00); break; - case 0xe8: /* Super-286TR: turbo ON */ - // TODO: 0xe8 is always followed by 0xba - // TODO: I don't know where to call cpu_set_turbo(1) to avoid slow POST after ctrl-alt-del when on low speed (if this is the real behavior!) - if (romset == ROM_HYUNDAI_SUPER286TR) - cpu_set_turbo(1); // 12 MHz - break; - - case 0xe9: /* Super-286TR: turbo OFF */ - if (romset == ROM_HYUNDAI_SUPER286TR) - cpu_set_turbo(0); // 8 MHz - break; + // AWARD BIOS: called after turbo ON/OFF in the + // Hyundai Super-286TR and probably other AWARD 286 + // bioses. Related to the Turbo LEDs. Exact function + // can't be confirmed because the system in question + // has no such leds. + //case 0xe8: /* Turbo ON, always followed by 0xba */ + //case 0xe9: /* Turbo OFF */ + //break; case 0xef: /*??? - sent by AMI486*/ break; From 169d6908341bc32f558187ba16174c6da99c5c9c Mon Sep 17 00:00:00 2001 From: pcem-maintainer Date: Sun, 4 Jul 2021 13:35:05 -0300 Subject: [PATCH 1048/1050] Remove some debug messages from release builds. Closes #42 --- src/pc.c | 2 +- src/wx-utils.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pc.c b/src/pc.c index 8e59278..2e20851 100644 --- a/src/pc.c +++ b/src/pc.c @@ -621,7 +621,7 @@ void fullspeed() cpuspeed2=cpuspeed; if (!atfullspeed) { - printf("Set fullspeed - %i %i %i\n",is386,AT,cpuspeed2); + pclog("Set fullspeed - %i %i %i\n",is386,AT,cpuspeed2); if (AT) setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); else diff --git a/src/wx-utils.cc b/src/wx-utils.cc index f62a8ec..2facbea 100644 --- a/src/wx-utils.cc +++ b/src/wx-utils.cc @@ -115,8 +115,10 @@ void wx_checkmenuitem(void* menu, int id, int checked) if (item) item->Check(checked); +#ifndef RELEASE_BUILD else std::cout << "Menu item not found: " << id << std::endl; +#endif } void wx_enablemenuitem(void* menu, int id, int enable) @@ -129,8 +131,10 @@ void wx_enablemenuitem(void* menu, int id, int enable) if (item) item->Enable(enable); +#ifndef RELEASE_BUILD else std::cout << "Menu item not found: " << id << std::endl; +#endif } void* wx_getsubmenu(void* menu, int id) From 0ac4af52a38c4e39e704c55e9b946b9d401e78bf Mon Sep 17 00:00:00 2001 From: pcem-maintainer Date: Sun, 4 Jul 2021 13:45:47 -0300 Subject: [PATCH 1049/1050] Add .gitignore file to make repository management easier --- .gitignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b4c77b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.o +*.swp +/Makefile +/src/Makefile +autom4te.cache +config.log +config.status +.deps +.dirstamp +/pcem +/src/pcem From 78d06183633c6c3ea042e533ca36081e113e2420 Mon Sep 17 00:00:00 2001 From: pcem-maintainer Date: Sun, 4 Jul 2021 18:32:57 -0300 Subject: [PATCH 1050/1050] Xi 8088: add the UMB dip switch and allow the programming of the BIOS flash memory --- src/mem.c | 21 +++++++++++++--- src/model.c | 2 +- src/pc.c | 4 ++- src/sst39sf010.c | 64 +++++++++++++++++++++++++++++++++++++++++------- src/xi8088.c | 47 ++++++++++++++++++++++++++++++----- 5 files changed, 118 insertions(+), 20 deletions(-) diff --git a/src/mem.c b/src/mem.c index 98dc738..15dc5ee 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1468,7 +1468,22 @@ void mem_alloc() memset(_mem_state, 0, sizeof(_mem_state)); mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (romset == ROM_XI8088) + { + // Xi 8088 UMBs are selected by DIP Switches + mem_set_mem_state(0x0a0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x0c0000, 0x08000, model_get_config_int("umb_c0000h_c7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0c8000, 0x08000, model_get_config_int("umb_c8000h_cffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0d0000, 0x08000, model_get_config_int("umb_d0000h_d7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0d8000, 0x08000, model_get_config_int("umb_d8000h_dffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0e0000, 0x08000, model_get_config_int("umb_e0000h_e7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0e8000, 0x08000, model_get_config_int("umb_e8000h_effff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + else + { + mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } 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) @@ -1484,8 +1499,8 @@ void mem_alloc() mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); } } - if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + if (mem_size > 768) // 640k - 768k is graphics RAM + mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, 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); diff --git a/src/model.c b/src/model.c index 672b110..6b9f71f 100644 --- a/src/model.c +++ b/src/model.c @@ -468,7 +468,6 @@ void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */ void xt_xi8088_init() { - /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ common_init(); mem_add_bios(); keyboard_at_init(); @@ -477,6 +476,7 @@ void xt_xi8088_init() device_add(&nvr_device); pic2_init(); device_add(&gameport_device); + device_add(&sst_39sf010_device); } void at_init() diff --git a/src/pc.c b/src/pc.c index 2e20851..dbe1633 100644 --- a/src/pc.c +++ b/src/pc.c @@ -312,7 +312,9 @@ void initpc(int argc, char *argv[]) initvideo(); mem_init(); loadbios(); - mem_add_bios(); + + // this is now done per-model + //mem_add_bios(); #if defined(__APPLE__) && defined(__aarch64__) pthread_jit_write_protect_np(0); diff --git a/src/sst39sf010.c b/src/sst39sf010.c index 8acb664..b2283f1 100644 --- a/src/sst39sf010.c +++ b/src/sst39sf010.c @@ -3,6 +3,7 @@ #include "device.h" #include "mem.h" #include "sst39sf010.h" +#include "xi8088.h" typedef struct sst_t { @@ -25,6 +26,18 @@ typedef struct sst_t static void set_id_mode(sst_t *sst); static void clear_id_mode(sst_t *sst); +static uint32_t sst_masked_rom_addr(uint32_t addr) +{ + // The flipped MSB of the Xi 8088 is only present in the on-disk files, + // in ram the mapping is as the software sees. This does not cause + // problems with the programming commands because they only use the + // lower 2 bytes. + if (romset == ROM_XI8088 && !xi8088_bios_128kb()) + return addr & 0xffff; + else + return addr & 0x1ffff; +} + static void sst_new_command(sst_t *sst, uint8_t val) { switch (val) @@ -69,11 +82,11 @@ static void sst_new_command(sst_t *sst, uint8_t val) } } -static void sst_sector_erase(sst_t *sst, uint32_t addr) +static void sst_sector_erase(sst_t *sst, uint32_t sst_addr) { -// pclog("SST sector erase %08x\n", addr); - memset(&rom[addr & 0x1f000], 0xff, 4096); - memset(&sst->data[addr & 0x1f000], 0xff, 4096); +// pclog("SST sector erase sst_addr %08x\n", sst_addr); + memset(&rom[sst_addr & 0x1f000], 0xff, 4096); + memset(&sst->data[sst_addr & 0x1f000], 0xff, 4096); sst->dirty = 1; } @@ -117,7 +130,7 @@ static void sst_write(uint32_t addr, uint8_t val, void *p) sst_new_command(sst, val); else if (val == SST_SECTOR_ERASE && sst->erase) { - sst_sector_erase(sst, addr); + sst_sector_erase(sst, sst_masked_rom_addr(addr)); sst->command_state = 0; } else @@ -125,8 +138,8 @@ static void sst_write(uint32_t addr, uint8_t val, void *p) break; case 3: // pclog("Byte program %08x %02x\n", addr, val); - rom[addr & 0x1ffff] = val; - sst->data[addr & 0x1ffff] = val; + rom[sst_masked_rom_addr(addr)] = val; + sst->data[sst_masked_rom_addr(addr)] = val; sst->command_state = 0; sst->dirty = 1; break; @@ -177,9 +190,14 @@ static void *sst_39sf010_init() switch(romset) { + case ROM_XI8088: + strcpy(sst->flash_path, "xi8088/"); + break; + case ROM_FIC_VA503P: strcpy(sst->flash_path, "fic_va503p/"); break; + default: fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); } @@ -187,7 +205,21 @@ static void *sst_39sf010_init() f = romfopen(sst->flash_path, "rb"); if (f) { - fread(rom, 0x20000, 1, f); + switch(romset) + { + case ROM_XI8088: + if (xi8088_bios_128kb()) + fread(rom + 0x10000, 0x10000, 1, f); + fread(rom, 0x10000, 1, f); + break; + + case ROM_FIC_VA503P: + fread(rom, 0x20000, 1, f); + break; + + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } fclose(f); } memcpy(sst->data, rom, 0x20000); @@ -204,7 +236,21 @@ static void sst_39sf010_close(void *p) if (sst->dirty) { FILE *f = romfopen(sst->flash_path, "wb"); - fwrite(sst->data, 0x20000, 1, f); + switch(romset) + { + case ROM_XI8088: + if (xi8088_bios_128kb()) + fwrite(sst->data + 0x10000, 0x10000, 1, f); + fwrite(sst->data, 0x10000, 1, f); + break; + + case ROM_FIC_VA503P: + fwrite(sst->data, 0x20000, 1, f); + break; + + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } fclose(f); } diff --git a/src/xi8088.c b/src/xi8088.c index 6ea95e6..1c5a135 100644 --- a/src/xi8088.c +++ b/src/xi8088.c @@ -28,12 +28,12 @@ void xi8088_turbo_set(uint8_t value) xi8088.turbo = value; if (!value) { - pclog("Xi8088 turbo off\n"); +// pclog("Xi8088 turbo off\n"); cpu_set_turbo(0); } else { - pclog("Xi8088 turbo on\n"); +// pclog("Xi8088 turbo on\n"); cpu_set_turbo(1); } } @@ -45,7 +45,6 @@ int xi8088_bios_128kb() static void *xi8088_init() { - /* even though the bios by default turns the turbo off when controlling by hotkeys, pcem always starts at full speed */ xi8088.turbo = 1; xi8088.turbo_setting = device_get_config_int("turbo_setting"); xi8088.bios_128kb = device_get_config_int("bios_128kb"); @@ -66,7 +65,7 @@ static device_config_t xi8088_config[] = .value = 0 }, { - .description = "Hotkeys (starts off)", + .description = "BIOS setting + Hotkeys (off during POST)", .value = 1 } }, @@ -79,16 +78,52 @@ static device_config_t xi8088_config[] = .selection = { { - .description = "64KB", + .description = "64KB starting from 0xF0000", .value = 0 }, { - .description = "128KB", + .description = "128KB starting from 0xE0000 (address MSB inverted, last 64KB first)", .value = 1 } }, .default_int = 1 }, + { + .name = "umb_c0000h_c7fff", + .description = "Map 0xc0000-0xc7fff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_c8000h_cffff", + .description = "Map 0xc8000-0xcffff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_d0000h_d7fff", + .description = "Map 0xd0000-0xd7fff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_d8000h_dffff", + .description = "Map 0xd8000-0xdffff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_e0000h_e7fff", + .description = "Map 0xe0000-0xe7fff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_e8000h_effff", + .description = "Map 0xe8000-0xeffff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, { .type = -1 }